ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/scripts/content-gatekeeper.mjs
Kjell Tore Guttormsen 39f8b275a6 feat(linkedin-thought-leadership): v1.0.0 — initial open-source import
Build LinkedIn thought leadership with algorithmic understanding,
strategic consistency, and AI-assisted content creation. Updated for
the January 2026 360Brew algorithm change.

16 agents, 25 commands, 6 skills, 9 hooks, 24 reference docs.

Personal data sanitized: voice samples generalized to template,
high-engagement posts cleared, region-specific references replaced
with placeholders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 22:09:03 +02:00

70 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
// content-gatekeeper.mjs
// Unified PreToolUse/PostToolUse gatekeeper for linkedin-thought-leadership plugin
//
// Replaces 4 nearly identical bash scripts:
// pre-content-quality-gate.sh, pre-voice-guardian.sh,
// pre-topic-rotation-gate.sh, post-creation-check.sh
//
// Usage:
// node content-gatekeeper.mjs <prompt-filename> [--no-session-marker]
//
// Arguments:
// prompt-filename - Prompt file in hooks/prompts/ (e.g. content-quality-gate.md)
// --no-session-marker - Skip creating session-active marker (for PostToolUse)
//
// Exit codes:
// 0 - Always allow (injects systemMessage or passes through)
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { isLinkedInContent } from './linkedin-content-filter.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const pluginRoot = join(__dirname, '..', '..');
const promptFile = process.argv[2];
const noSessionMarker = process.argv.includes('--no-session-marker');
if (!promptFile) {
process.stdout.write('{}');
process.exit(0);
}
// Read and parse stdin JSON
let input;
try {
input = JSON.parse(readFileSync(0, 'utf-8'));
} catch {
process.stdout.write('{}');
process.exit(0);
}
// Extract file_path from tool_input
const toolInput = input.tool_input ?? {};
const filePath = toolInput.file_path ?? toolInput.filePath ?? '';
// Check if this is LinkedIn content
if (!isLinkedInContent(filePath)) {
process.stdout.write('{}');
process.exit(0);
}
// Mark session as having LinkedIn content activity
if (!noSessionMarker) {
const sessionDir = '/tmp/linkedin-hooks';
mkdirSync(sessionDir, { recursive: true });
writeFileSync(join(sessionDir, 'session-active'), '');
}
// Load and return prompt
const promptPath = join(pluginRoot, 'hooks', 'prompts', promptFile);
if (!existsSync(promptPath)) {
process.stdout.write('{}');
process.exit(0);
}
const promptContent = readFileSync(promptPath, 'utf-8');
process.stdout.write(JSON.stringify({ systemMessage: promptContent }));
process.exit(0);