// pi-wiki: Append-and-Review - quick notes pipeline import * as fs from "fs"; import * as path from "path"; const WIKI_DIR = process.env.PI_WIKI_DIR || path.join(process.env.HOME || "", "pi-wiki"); const DRAFTS_DIR = path.join(WIKI_DIR, "_drafts"); const LOG_FILE = path.join(WIKI_DIR, "log.md"); function ensureDirs() { if (!fs.existsSync(DRAFTS_DIR)) fs.mkdirSync(DRAFTS_DIR, { recursive: true }); } function logEntry(type: string, desc: string) { const date = new Date().toISOString().split("T")[0]; const entry = `\n## [${date}] ${type} | ${desc}\n`; fs.appendFileSync(LOG_FILE, entry); } interface AppendNote { id: string; content: string; created: string; reviewed: boolean; } function loadAppendNotes(): AppendNote[] { const file = path.join(DRAFTS_DIR, "append-notes.md"); if (!fs.existsSync(file)) return []; const content = fs.readFileSync(file, "utf8"); const notes: AppendNote[] = []; // Parse notes from markdown const regex = /## Note (\w+)\n(\d{4}-\d{2}-\d{2})\n([\s\S]*?)(?=## Note |$)/g; let match; while ((match = regex.exec(content)) !== null) { notes.push({ id: match[1], created: match[2], content: match[3].trim(), reviewed: false, }); } return notes; } function saveAppendNotes(notes: AppendNote[]) { const file = path.join(DRAFTS_DIR, "append-notes.md"); const content = notes.map(n => `## Note ${n.id}\n${n.created}\n${n.content}` ).join("\n\n"); fs.writeFileSync(file, content); } export async function appendNote(text: string): Promise { ensureDirs(); const id = Date.now().toString(36); const note: AppendNote = { id, created: new Date().toISOString().split("T")[0], content: text, reviewed: false, }; const notes = loadAppendNotes(); notes.push(note); saveAppendNotes(notes); logEntry("append", text.slice(0, 50)); return `✅ Note saved to drafts. Will be reviewed during /wiki-lint\n\nNote ID: ${id}`; } export async function reviewNotes(): Promise { ensureDirs(); const notes = loadAppendNotes(); if (notes.length === 0) { return "📭 No append notes to review. Use /wiki-append to add notes."; } const lines = ["## 📝 Append Notes Review\n"]; lines.push(`**${notes.length} notes pending review**\n`); for (const note of notes) { lines.push(`### ${note.id} (${note.created})`); lines.push(note.content); lines.push(`\n_Promote: /wiki-promote ${note.id}_\n`); } return lines.join("\n"); } export async function promoteNote(noteId: string, title: string, tags: string[]): Promise { const notes = loadAppendNotes(); const note = notes.find(n => n.id === noteId); if (!note) { return `❌ Note not found: ${noteId}`; } // Create wiki page const WIKI_DIR = process.env.PI_WIKI_DIR || path.join(process.env.HOME || "", "pi-wiki"); const PAGES_DIR = path.join(WIKI_DIR, "wiki"); if (!fs.existsSync(PAGES_DIR)) fs.mkdirSync(PAGES_DIR, { recursive: true }); const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-"); const page = `--- title: ${title} type: concept tags: [${tags.join(", ")}] sources: [] created: ${new Date().toISOString().split("T")[0]} provenance: ^[appended] --- # ${title} ${note.content} ## See Also - [[Index]] `; fs.writeFileSync(path.join(PAGES_DIR, slug + ".md"), page); // Remove from drafts const remaining = notes.filter(n => n.id !== noteId); saveAppendNotes(remaining); logEntry("promote", `${noteId} → ${title}`); return `✅ Note promoted to [[${title}]]`; } export async function discardNote(noteId: string): Promise { const notes = loadAppendNotes(); const remaining = notes.filter(n => n.id !== noteId); saveAppendNotes(remaining); logEntry("discard", noteId); return `🗑️ Note discarded: ${noteId}`; }