ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/scripts/queue-manager.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

125 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
// Queue management library for linkedin-thought-leadership plugin
// Import: import { queueRead, queueToday, ... } from './queue-manager.mjs';
// Replaces python3 dependency with native Node.js JSON/Date operations
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const PLUGIN_ROOT = process.env.PLUGIN_ROOT || join(__dirname, '..', '..');
const QUEUE_FILE = join(PLUGIN_ROOT, 'assets', 'drafts', 'queue.json');
function ensureQueue() {
if (!existsSync(QUEUE_FILE)) {
mkdirSync(dirname(QUEUE_FILE), { recursive: true });
writeFileSync(QUEUE_FILE, JSON.stringify({ version: 1, queue: [] }, null, 2));
}
}
function readQueue() {
ensureQueue();
try {
const data = JSON.parse(readFileSync(QUEUE_FILE, 'utf-8'));
return data.queue || [];
} catch {
return [];
}
}
function writeQueue(queue) {
ensureQueue();
const data = JSON.parse(readFileSync(QUEUE_FILE, 'utf-8'));
data.queue = queue;
writeFileSync(QUEUE_FILE, JSON.stringify(data, null, 2));
}
function todayISO() {
return new Date().toISOString().slice(0, 10);
}
// Read all queue entries
export function queueRead() {
return readQueue();
}
// Get entries scheduled for today (status=scheduled only)
export function queueToday() {
const today = todayISO();
return readQueue().filter(e => e.scheduled_date === today && e.status === 'scheduled');
}
// Get entries for next N days (status=scheduled only)
export function queueUpcoming(days = 7) {
const today = todayISO();
const end = new Date();
end.setDate(end.getDate() + days);
const endStr = end.toISOString().slice(0, 10);
return readQueue()
.filter(e => e.status === 'scheduled' && e.scheduled_date >= today && e.scheduled_date <= endStr)
.sort((a, b) => (a.scheduled_date + (a.scheduled_time || '')).localeCompare(b.scheduled_date + (b.scheduled_time || '')));
}
// Add entry to queue
export function queueAdd(id, draftPath, schedDate, schedTime, pillar, format, hookPreview, charCount) {
const queue = readQueue().filter(e => e.id !== id);
queue.push({
id,
draft_path: draftPath,
scheduled_date: schedDate,
scheduled_time: schedTime,
pillar,
format,
hook_preview: hookPreview,
character_count: charCount,
status: 'scheduled',
created_at: todayISO()
});
writeQueue(queue);
return `Added: ${id}`;
}
// Update status of a queue entry
export function queueUpdateStatus(id, newStatus) {
const queue = readQueue();
const entry = queue.find(e => e.id === id);
if (entry) {
entry.status = newStatus;
writeQueue(queue);
return `Updated: ${id} -> ${newStatus}`;
}
return `Not found: ${id}`;
}
// Get overdue entries (past scheduled_date, still "scheduled")
export function queueOverdue() {
const today = todayISO();
return readQueue()
.filter(e => e.status === 'scheduled' && (e.scheduled_date || '9999') < today)
.sort((a, b) => (a.scheduled_date || '').localeCompare(b.scheduled_date || ''));
}
// Count entries by status
export function queueCount() {
const counts = {};
for (const e of readQueue()) {
const s = e.status || 'unknown';
counts[s] = (counts[s] || 0) + 1;
}
return counts;
}
// Format queue entries as readable summary
export function queueFormatSummary(entries) {
if (!entries || entries.length === 0) return '(none)';
return entries.map(e => {
const d = e.scheduled_date || '?';
const t = e.scheduled_time || '?';
const hook = (e.hook_preview || '').slice(0, 50);
const pillar = e.pillar || '?';
const fmt = e.format || '?';
const status = e.status || '?';
return ` ${d} ${t} | ${hook}... | ${pillar} (${fmt}) [${status}]`;
}).join('\n');
}