#!/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'); }