@riotprompt/riotdoc 1.0.0 → 1.0.3-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +36 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +30 -57
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/{loader-B7ZeTPQg.js → loader-Jj2cSi3H.js} +36 -7
- package/dist/{loader-B7ZeTPQg.js.map → loader-Jj2cSi3H.js.map} +1 -1
- package/package.json +10 -9
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import chalk from "chalk";
|
|
|
3
3
|
import inquirer from "inquirer";
|
|
4
4
|
import { resolve, join } from "node:path";
|
|
5
5
|
import { stat, readFile } from "node:fs/promises";
|
|
6
|
-
import { c as createWorkspace, R as RIOTDOC_STRUCTURE, e as parse, b as loadVoice } from "./loader-
|
|
6
|
+
import { c as createWorkspace, R as RIOTDOC_STRUCTURE, e as parse, b as loadVoice } from "./loader-Jj2cSi3H.js";
|
|
7
7
|
const DOCUMENT_TYPES = [
|
|
8
8
|
{ name: "Blog Post", value: "blog-post" },
|
|
9
9
|
{ name: "Podcast Script", value: "podcast-script" },
|
|
@@ -182,9 +182,24 @@ function parseObjectivesMarkdown(content) {
|
|
|
182
182
|
if (goalMatch) {
|
|
183
183
|
objectives.primaryGoal = goalMatch[1].trim().replace(/^_|_$/g, "");
|
|
184
184
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
const lines = content.split("\n");
|
|
186
|
+
const secondaryLines = [];
|
|
187
|
+
let inSecondary = false;
|
|
188
|
+
for (const line of lines) {
|
|
189
|
+
if (/^##\s*Secondary\s+Goals$/i.test(line)) {
|
|
190
|
+
inSecondary = true;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (inSecondary && /^##/.test(line)) {
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (inSecondary) {
|
|
197
|
+
secondaryLines.push(line);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (secondaryLines.length > 0) {
|
|
201
|
+
const sectionContent = secondaryLines.join("\n");
|
|
202
|
+
const goals = sectionContent.matchAll(/^[-*]\s+(.+)$/gm);
|
|
188
203
|
for (const goal of goals) {
|
|
189
204
|
const text = goal[1].trim().replace(/^_|_$/g, "");
|
|
190
205
|
if (text && !text.startsWith("Add")) {
|
|
@@ -192,9 +207,23 @@ function parseObjectivesMarkdown(content) {
|
|
|
192
207
|
}
|
|
193
208
|
}
|
|
194
209
|
}
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
210
|
+
const takeawayLines = [];
|
|
211
|
+
let inTakeaways = false;
|
|
212
|
+
for (const line of lines) {
|
|
213
|
+
if (/^##\s*Key\s+Takeaways$/i.test(line)) {
|
|
214
|
+
inTakeaways = true;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (inTakeaways && /^##/.test(line)) {
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
if (inTakeaways) {
|
|
221
|
+
takeawayLines.push(line);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (takeawayLines.length > 0) {
|
|
225
|
+
const sectionContent = takeawayLines.join("\n");
|
|
226
|
+
const takeaways = sectionContent.matchAll(/^\d+\.\s+(.+)$/gm);
|
|
198
227
|
for (const takeaway of takeaways) {
|
|
199
228
|
const text = takeaway[1].trim().replace(/^_|_$/g, "");
|
|
200
229
|
if (text && !text.startsWith("Define")) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/cli/commands/create.ts","../src/outline/generator.ts","../src/workspace/loader.ts","../src/objectives/loader.ts","../src/cli/commands/outline.ts","../src/cli/commands/draft.ts","../src/cli/commands/revise.ts","../src/cli/commands/cleanup.ts","../src/cli/commands/spellcheck.ts","../src/cli/commands/export.ts","../src/cli/commands/status.ts","../src/cli/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport { join, resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\nimport { createWorkspace } from \"../../workspace/creator.js\";\nimport type { DocumentConfig } from \"../../types.js\";\n\nexport interface CreateOptions {\n type?: DocumentConfig[\"type\"];\n title?: string;\n path?: string;\n}\n\nconst DOCUMENT_TYPES = [\n { name: \"Blog Post\", value: \"blog-post\" },\n { name: \"Podcast Script\", value: \"podcast-script\" },\n { name: \"Technical Documentation\", value: \"technical-doc\" },\n { name: \"Newsletter\", value: \"newsletter\" },\n { name: \"Custom\", value: \"custom\" },\n];\n\n/**\n * Prompt for document type\n */\nasync function promptForType(): Promise<DocumentConfig[\"type\"]> {\n const { type } = await inquirer.prompt([{\n type: \"list\",\n name: \"type\",\n message: \"Document type:\",\n choices: DOCUMENT_TYPES,\n }]);\n return type;\n}\n\n/**\n * Prompt for document title\n */\nasync function promptForTitle(name: string): Promise<string> {\n const defaultTitle = name\n .split(\"-\")\n .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \");\n \n const { title } = await inquirer.prompt([{\n type: \"input\",\n name: \"title\",\n message: \"Document title:\",\n default: defaultTitle,\n }]);\n return title;\n}\n\n/**\n * Prompt for primary goal\n */\nasync function promptForGoal(): Promise<string> {\n const { goal } = await inquirer.prompt([{\n type: \"input\",\n name: \"goal\",\n message: \"What is the primary goal of this document?\",\n }]);\n return goal;\n}\n\n/**\n * Prompt for target audience\n */\nasync function promptForAudience(): Promise<string> {\n const { audience } = await inquirer.prompt([{\n type: \"input\",\n name: \"audience\",\n message: \"Who is the target audience?\",\n }]);\n return audience;\n}\n\n/**\n * Check if path already exists\n */\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Register the create command\n */\nexport function registerCreateCommand(program: Command): void {\n program\n .command(\"create <name>\")\n .description(\"Create a new document workspace\")\n .option(\"-t, --type <type>\", \"Document type (blog-post, podcast-script, technical-doc, newsletter, custom)\")\n .option(\"-T, --title <title>\", \"Document title\")\n .option(\"-p, --path <path>\", \"Base path (default: current directory)\")\n .action(async (name: string, options: CreateOptions) => {\n try {\n const basePath = options.path || process.cwd();\n const workspacePath = resolve(join(basePath, name));\n \n // Check if already exists\n if (await pathExists(workspacePath)) {\n console.error(chalk.red(`Directory already exists: ${workspacePath}`));\n process.exit(1);\n }\n \n console.log(chalk.cyan(\"\\n📝 Creating new document workspace\\n\"));\n \n // Get document type\n const type = options.type as DocumentConfig[\"type\"] || await promptForType();\n \n // Get title\n const title = options.title || await promptForTitle(name);\n \n // Get initial objectives\n const goal = await promptForGoal();\n const audience = await promptForAudience();\n \n // Create workspace\n console.log(chalk.gray(\"\\nCreating workspace...\"));\n \n await createWorkspace({\n path: workspacePath,\n id: name,\n title,\n type,\n objectives: {\n primaryGoal: goal,\n secondaryGoals: [],\n keyTakeaways: [],\n },\n });\n \n // Note: audience is collected but not yet stored in config\n // This will be added when we implement config management\n if (audience) {\n // Future: store audience in config\n }\n \n console.log(chalk.green(`\\n✅ Document workspace created: ${workspacePath}`));\n \n // Show next steps\n console.log(chalk.cyan(\"\\n📋 Next steps:\\n\"));\n console.log(chalk.gray(` 1. Edit voice/tone.md to define your writing voice`));\n console.log(chalk.gray(` 2. Edit OBJECTIVES.md to refine your goals`));\n console.log(chalk.gray(` 3. Run: riotdoc outline ${name}`));\n console.log(chalk.gray(` 4. Run: riotdoc draft ${name}`));\n \n console.log(chalk.cyan(`\\n📁 Workspace structure:`));\n console.log(chalk.gray(` ${name}/`));\n console.log(chalk.gray(` ├── riotdoc.yaml # Configuration`));\n console.log(chalk.gray(` ├── OBJECTIVES.md # Goals and objectives`));\n console.log(chalk.gray(` ├── OUTLINE.md # Document outline`));\n console.log(chalk.gray(` ├── voice/ # Voice and style`));\n console.log(chalk.gray(` ├── evidence/ # Research and references`));\n console.log(chalk.gray(` ├── drafts/ # Draft iterations`));\n console.log(chalk.gray(` └── export/ # Final output`));\n \n } catch (error) {\n console.error(chalk.red(\"Failed to create workspace:\"), error);\n process.exit(1);\n }\n });\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { DocumentObjectives, VoiceConfig } from \"../types.js\";\n\nexport interface OutlineSection {\n title: string;\n points: string[];\n subsections?: OutlineSection[];\n}\n\nexport interface Outline {\n title: string;\n hook: string;\n sections: OutlineSection[];\n conclusion: string;\n}\n\n/**\n * Load outline from workspace\n */\nexport async function loadOutline(workspacePath: string): Promise<string> {\n const outlinePath = join(workspacePath, RIOTDOC_STRUCTURE.outlineFile);\n return await readFile(outlinePath, \"utf-8\");\n}\n\n/**\n * Save outline to workspace\n */\nexport async function saveOutline(workspacePath: string, content: string): Promise<void> {\n const outlinePath = join(workspacePath, RIOTDOC_STRUCTURE.outlineFile);\n await writeFile(outlinePath, content, \"utf-8\");\n}\n\n/**\n * Build prompt for outline generation\n */\nexport function buildOutlinePrompt(\n objectives: DocumentObjectives,\n voice: VoiceConfig,\n documentType: string\n): string {\n return `Generate an outline for a ${documentType}.\n\n## Objectives\n\nPrimary Goal: ${objectives.primaryGoal}\n\nSecondary Goals:\n${objectives.secondaryGoals.map(g => `- ${g}`).join(\"\\n\")}\n\nKey Takeaways:\n${objectives.keyTakeaways.map(t => `- ${t}`).join(\"\\n\")}\n\n${objectives.emotionalArc ? `Emotional Arc: ${objectives.emotionalArc}` : \"\"}\n\n## Voice & Tone\n\nTone: ${voice.tone}\nPoint of View: ${voice.pointOfView}\n\n## Output Format\n\nCreate a markdown outline with:\n1. A compelling hook/introduction\n2. 3-5 main sections with bullet points\n3. A conclusion with call to action\n\nUse ## for main sections, ### for subsections, and - for bullet points.\n`;\n}\n\n/**\n * Parse outline markdown into structure\n */\nexport function parseOutline(content: string): Outline {\n const lines = content.split(\"\\n\");\n const outline: Outline = {\n title: \"\",\n hook: \"\",\n sections: [],\n conclusion: \"\",\n };\n \n let currentSection: OutlineSection | null = null;\n let inIntro = false;\n let inConclusion = false;\n \n for (const line of lines) {\n // Title\n if (line.startsWith(\"# \")) {\n outline.title = line.slice(2).trim();\n continue;\n }\n \n // Main section\n if (line.startsWith(\"## \")) {\n const title = line.slice(3).trim().toLowerCase();\n if (title.includes(\"intro\") || title.includes(\"hook\")) {\n inIntro = true;\n inConclusion = false;\n currentSection = null;\n } else if (title.includes(\"conclusion\")) {\n inIntro = false;\n inConclusion = true;\n currentSection = null;\n } else {\n inIntro = false;\n inConclusion = false;\n currentSection = { title: line.slice(3).trim(), points: [] };\n outline.sections.push(currentSection);\n }\n continue;\n }\n \n // Bullet point\n if (line.match(/^[-*]\\s+/)) {\n const point = line.replace(/^[-*]\\s+/, \"\").trim();\n if (inIntro) {\n outline.hook += (outline.hook ? \"\\n\" : \"\") + point;\n } else if (inConclusion) {\n outline.conclusion += (outline.conclusion ? \"\\n\" : \"\") + point;\n } else if (currentSection) {\n currentSection.points.push(point);\n }\n }\n }\n \n return outline;\n}\n\n/**\n * Format outline structure as markdown\n */\nexport function formatOutline(outline: Outline): string {\n const parts: string[] = [];\n \n parts.push(`# ${outline.title}\\n`);\n \n if (outline.hook) {\n parts.push(`## Introduction\\n`);\n parts.push(outline.hook.split(\"\\n\").map(p => `- ${p}`).join(\"\\n\"));\n parts.push(\"\");\n }\n \n for (const section of outline.sections) {\n parts.push(`## ${section.title}\\n`);\n parts.push(section.points.map(p => `- ${p}`).join(\"\\n\"));\n parts.push(\"\");\n }\n \n if (outline.conclusion) {\n parts.push(`## Conclusion\\n`);\n parts.push(outline.conclusion.split(\"\\n\").map(p => `- ${p}`).join(\"\\n\"));\n }\n \n return parts.join(\"\\n\");\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { RiotDoc, DocumentConfig } from \"../types.js\";\n\n/**\n * Load document from workspace\n */\nexport async function loadDocument(workspacePath: string): Promise<RiotDoc | null> {\n try {\n const configPath = join(workspacePath, RIOTDOC_STRUCTURE.configFile);\n const content = await readFile(configPath, \"utf-8\");\n const config = parse(content) as DocumentConfig;\n \n // Convert date strings to Date objects\n config.createdAt = new Date(config.createdAt);\n config.updatedAt = new Date(config.updatedAt);\n \n return {\n config,\n voice: { tone: \"\", pointOfView: \"first\", styleNotes: [], avoid: [] },\n objectives: { primaryGoal: \"\", secondaryGoals: [], keyTakeaways: [] },\n evidence: [],\n drafts: [],\n revisions: [],\n workspacePath,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Check if path is a RiotDoc workspace\n */\nexport async function isRiotDocWorkspace(path: string): Promise<boolean> {\n try {\n const configPath = join(path, RIOTDOC_STRUCTURE.configFile);\n await stat(configPath);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { DocumentObjectives } from \"../types.js\";\n\n/**\n * Load objectives from workspace\n */\nexport async function loadObjectives(workspacePath: string): Promise<DocumentObjectives> {\n const objectivesPath = join(workspacePath, RIOTDOC_STRUCTURE.objectivesFile);\n \n try {\n const content = await readFile(objectivesPath, \"utf-8\");\n return parseObjectivesMarkdown(content);\n } catch {\n return {\n primaryGoal: \"\",\n secondaryGoals: [],\n keyTakeaways: [],\n };\n }\n}\n\n/**\n * Parse objectives markdown\n */\nfunction parseObjectivesMarkdown(content: string): DocumentObjectives {\n const objectives: DocumentObjectives = {\n primaryGoal: \"\",\n secondaryGoals: [],\n keyTakeaways: [],\n };\n \n // Extract primary goal\n const goalMatch = content.match(/##\\s*Primary\\s+Goal\\s*\\n+([^\\n#]+)/i);\n if (goalMatch) {\n objectives.primaryGoal = goalMatch[1].trim().replace(/^_|_$/g, \"\");\n }\n \n // Extract secondary goals\n const secondaryMatch = content.match(/##\\s*Secondary\\s+Goals\\s*\\n([\\s\\S]*?)(?=\\n##|$)/i);\n if (secondaryMatch) {\n const goals = secondaryMatch[1].matchAll(/^[-*]\\s+(.+)$/gm);\n for (const goal of goals) {\n const text = goal[1].trim().replace(/^_|_$/g, \"\");\n if (text && !text.startsWith(\"Add\")) {\n objectives.secondaryGoals.push(text);\n }\n }\n }\n \n // Extract key takeaways\n const takeawaysMatch = content.match(/##\\s*Key\\s+Takeaways\\s*\\n([\\s\\S]*?)(?=\\n##|$)/i);\n if (takeawaysMatch) {\n const takeaways = takeawaysMatch[1].matchAll(/^\\d+\\.\\s+(.+)$/gm);\n for (const takeaway of takeaways) {\n const text = takeaway[1].trim().replace(/^_|_$/g, \"\");\n if (text && !text.startsWith(\"Define\")) {\n objectives.keyTakeaways.push(text);\n }\n }\n }\n \n // Extract call to action\n const ctaMatch = content.match(/##\\s*Call\\s+to\\s+Action\\s*\\n+([^\\n#]+)/i);\n if (ctaMatch) {\n const cta = ctaMatch[1].trim().replace(/^_|_$/g, \"\");\n if (cta && !cta.startsWith(\"What\")) {\n objectives.callToAction = cta;\n }\n }\n \n // Extract emotional arc\n const arcMatch = content.match(/##\\s*Emotional\\s+Arc\\s*\\n+([^\\n#]+)/i);\n if (arcMatch) {\n const arc = arcMatch[1].trim().replace(/^_|_$/g, \"\");\n if (arc && !arc.startsWith(\"Describe\")) {\n objectives.emotionalArc = arc;\n }\n }\n \n return objectives;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { resolve } from \"node:path\";\nimport { loadOutline, buildOutlinePrompt } from \"../../outline/generator.js\";\nimport { loadDocument } from \"../../workspace/loader.js\";\nimport { loadVoice } from \"../../voice/loader.js\";\nimport { loadObjectives } from \"../../objectives/loader.js\";\n\nexport interface OutlineOptions {\n generate?: boolean;\n edit?: boolean;\n}\n\nexport function registerOutlineCommand(program: Command): void {\n program\n .command(\"outline [path]\")\n .description(\"Generate or edit document outline\")\n .option(\"-g, --generate\", \"Generate outline with AI\")\n .option(\"-e, --edit\", \"Open outline for editing\")\n .action(async (pathArg: string | undefined, options: OutlineOptions) => {\n try {\n const workspacePath = resolve(pathArg || process.cwd());\n \n // Load document state\n const doc = await loadDocument(workspacePath);\n if (!doc) {\n console.error(chalk.red(\"Not a RiotDoc workspace\"));\n process.exit(1);\n }\n \n if (options.generate) {\n // Generate outline with AI\n console.log(chalk.cyan(\"Generating outline...\"));\n \n const voice = await loadVoice(workspacePath);\n const objectives = await loadObjectives(workspacePath);\n \n const prompt = buildOutlinePrompt(objectives, voice, doc.config.type);\n \n // TODO: Call AI provider\n console.log(chalk.yellow(\"\\nOutline generation prompt:\"));\n console.log(chalk.gray(prompt));\n console.log(chalk.yellow(\"\\n(AI integration pending - edit OUTLINE.md manually)\"));\n \n } else if (options.edit) {\n // Open in editor\n const { spawn } = await import(\"node:child_process\");\n const editor = process.env.EDITOR || \"vim\";\n const outlinePath = `${workspacePath}/OUTLINE.md`;\n \n spawn(editor, [outlinePath], { stdio: \"inherit\" });\n \n } else {\n // Show current outline\n const outline = await loadOutline(workspacePath);\n console.log(chalk.cyan(\"\\n📋 Current Outline:\\n\"));\n console.log(outline);\n \n console.log(chalk.gray(\"\\nOptions:\"));\n console.log(chalk.gray(\" --generate Generate outline with AI\"));\n console.log(chalk.gray(\" --edit Open outline in editor\"));\n }\n \n } catch (error) {\n console.error(chalk.red(\"Failed:\"), error);\n process.exit(1);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface DraftOptions {\n level?: string;\n from?: string;\n}\n\nexport function registerDraftCommand(program: Command): void {\n program\n .command(\"draft [path]\")\n .description(\"Create a new draft\")\n .option(\"-l, --level <level>\", \"AI assistance level (generate, expand, revise)\", \"expand\")\n .option(\"-f, --from <draft>\", \"Base on existing draft\")\n .action(async (_path: string | undefined, _options: DraftOptions) => {\n console.log(chalk.yellow(\"Draft command - AI integration pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load outline and objectives\"));\n console.log(chalk.gray(\" 2. Apply voice and style rules\"));\n console.log(chalk.gray(\" 3. Generate draft with specified assistance level\"));\n console.log(chalk.gray(\" 4. Save to drafts/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface ReviseOptions {\n draft?: string;\n message?: string;\n}\n\nexport function registerReviseCommand(program: Command): void {\n program\n .command(\"revise [path]\")\n .description(\"Add revision feedback\")\n .option(\"-d, --draft <number>\", \"Target draft number\")\n .option(\"-m, --message <message>\", \"Revision feedback\")\n .action(async (_path: string | undefined, _options: ReviseOptions) => {\n console.log(chalk.yellow(\"Revise command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load specified draft\"));\n console.log(chalk.gray(\" 2. Collect revision feedback\"));\n console.log(chalk.gray(\" 3. Save to revisions/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface CleanupOptions {\n draft?: string;\n}\n\nexport function registerCleanupCommand(program: Command): void {\n program\n .command(\"cleanup [path]\")\n .description(\"Light editing pass (grammar, clarity)\")\n .option(\"-d, --draft <number>\", \"Target draft\")\n .action(async (_path: string | undefined, _options: CleanupOptions) => {\n console.log(chalk.yellow(\"Cleanup command - AI integration pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load draft\"));\n console.log(chalk.gray(\" 2. Apply light editing for grammar and clarity\"));\n console.log(chalk.gray(\" 3. Save cleaned version\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface SpellcheckOptions {\n draft?: string;\n}\n\nexport function registerSpellcheckCommand(program: Command): void {\n program\n .command(\"spellcheck [path]\")\n .description(\"Fix spelling and grammar only\")\n .option(\"-d, --draft <number>\", \"Target draft\")\n .action(async (_path: string | undefined, _options: SpellcheckOptions) => {\n console.log(chalk.yellow(\"Spellcheck command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load draft\"));\n console.log(chalk.gray(\" 2. Check spelling and basic grammar\"));\n console.log(chalk.gray(\" 3. Report or fix issues\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface ExportOptions {\n draft?: string;\n output?: string;\n}\n\nexport function registerExportCommand(program: Command): void {\n program\n .command(\"export [path]\")\n .description(\"Export publication-ready document\")\n .option(\"-d, --draft <number>\", \"Source draft\")\n .option(\"-o, --output <file>\", \"Output file name\")\n .action(async (_path: string | undefined, _options: ExportOptions) => {\n console.log(chalk.yellow(\"Export command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load specified draft\"));\n console.log(chalk.gray(\" 2. Apply final formatting\"));\n console.log(chalk.gray(\" 3. Export to export/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { resolve } from \"node:path\";\nimport { loadDocument } from \"../../workspace/loader.js\";\n\nexport function registerStatusCommand(program: Command): void {\n program\n .command(\"status [path]\")\n .description(\"Show document status\")\n .action(async (pathArg: string | undefined) => {\n try {\n const workspacePath = resolve(pathArg || process.cwd());\n \n const doc = await loadDocument(workspacePath);\n if (!doc) {\n console.error(chalk.red(\"Not a RiotDoc workspace\"));\n process.exit(1);\n }\n \n console.log(chalk.cyan(\"\\n📊 Document Status\\n\"));\n console.log(chalk.gray(`Title: ${doc.config.title}`));\n console.log(chalk.gray(`Type: ${doc.config.type}`));\n console.log(chalk.gray(`Status: ${doc.config.status}`));\n console.log(chalk.gray(`Created: ${doc.config.createdAt.toLocaleDateString()}`));\n console.log(chalk.gray(`Updated: ${doc.config.updatedAt.toLocaleDateString()}`));\n \n if (doc.config.targetWordCount) {\n console.log(chalk.gray(`Target: ${doc.config.targetWordCount} words`));\n }\n \n console.log(chalk.cyan(\"\\n📁 Workspace: \") + chalk.gray(workspacePath));\n \n } catch (error) {\n console.error(chalk.red(\"Failed:\"), error);\n process.exit(1);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { registerCreateCommand } from \"./commands/create.js\";\nimport { registerOutlineCommand } from \"./commands/outline.js\";\nimport { registerDraftCommand } from \"./commands/draft.js\";\nimport { registerReviseCommand } from \"./commands/revise.js\";\nimport { registerCleanupCommand } from \"./commands/cleanup.js\";\nimport { registerSpellcheckCommand } from \"./commands/spellcheck.js\";\nimport { registerExportCommand } from \"./commands/export.js\";\nimport { registerStatusCommand } from \"./commands/status.js\";\n\nconst VERSION = \"1.0.0-dev.0\";\n\n/**\n * Create the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n \n program\n .name(\"riotdoc\")\n .description(\"Structured document creation with AI assistance\")\n .version(VERSION)\n .configureHelp({\n sortSubcommands: true,\n });\n \n // Register commands (implemented in subsequent steps)\n registerCreateCommand(program);\n registerOutlineCommand(program);\n registerDraftCommand(program);\n registerReviseCommand(program);\n registerCleanupCommand(program);\n registerSpellcheckCommand(program);\n registerExportCommand(program);\n registerStatusCommand(program);\n \n // Global options\n program\n .option(\"-v, --verbose\", \"Verbose output\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--no-color\", \"Disable colored output\");\n \n // Handle unknown commands\n program.on(\"command:*\", () => {\n console.error(chalk.red(`Unknown command: ${program.args.join(\" \")}`));\n console.log(`Run ${chalk.cyan(\"riotdoc --help\")} for usage.`);\n process.exit(1);\n });\n \n return program;\n}\n\n// All commands are now imported from separate files\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/cli/commands/create.ts","../src/outline/generator.ts","../src/workspace/loader.ts","../src/objectives/loader.ts","../src/cli/commands/outline.ts","../src/cli/commands/draft.ts","../src/cli/commands/revise.ts","../src/cli/commands/cleanup.ts","../src/cli/commands/spellcheck.ts","../src/cli/commands/export.ts","../src/cli/commands/status.ts","../src/cli/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport { join, resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\nimport { createWorkspace } from \"../../workspace/creator.js\";\nimport type { DocumentConfig } from \"../../types.js\";\n\nexport interface CreateOptions {\n type?: DocumentConfig[\"type\"];\n title?: string;\n path?: string;\n}\n\nconst DOCUMENT_TYPES = [\n { name: \"Blog Post\", value: \"blog-post\" },\n { name: \"Podcast Script\", value: \"podcast-script\" },\n { name: \"Technical Documentation\", value: \"technical-doc\" },\n { name: \"Newsletter\", value: \"newsletter\" },\n { name: \"Custom\", value: \"custom\" },\n];\n\n/**\n * Prompt for document type\n */\nasync function promptForType(): Promise<DocumentConfig[\"type\"]> {\n const { type } = await inquirer.prompt([{\n type: \"list\",\n name: \"type\",\n message: \"Document type:\",\n choices: DOCUMENT_TYPES,\n }]);\n return type;\n}\n\n/**\n * Prompt for document title\n */\nasync function promptForTitle(name: string): Promise<string> {\n const defaultTitle = name\n .split(\"-\")\n .map(w => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \");\n \n const { title } = await inquirer.prompt([{\n type: \"input\",\n name: \"title\",\n message: \"Document title:\",\n default: defaultTitle,\n }]);\n return title;\n}\n\n/**\n * Prompt for primary goal\n */\nasync function promptForGoal(): Promise<string> {\n const { goal } = await inquirer.prompt([{\n type: \"input\",\n name: \"goal\",\n message: \"What is the primary goal of this document?\",\n }]);\n return goal;\n}\n\n/**\n * Prompt for target audience\n */\nasync function promptForAudience(): Promise<string> {\n const { audience } = await inquirer.prompt([{\n type: \"input\",\n name: \"audience\",\n message: \"Who is the target audience?\",\n }]);\n return audience;\n}\n\n/**\n * Check if path already exists\n */\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Register the create command\n */\nexport function registerCreateCommand(program: Command): void {\n program\n .command(\"create <name>\")\n .description(\"Create a new document workspace\")\n .option(\"-t, --type <type>\", \"Document type (blog-post, podcast-script, technical-doc, newsletter, custom)\")\n .option(\"-T, --title <title>\", \"Document title\")\n .option(\"-p, --path <path>\", \"Base path (default: current directory)\")\n .action(async (name: string, options: CreateOptions) => {\n try {\n const basePath = options.path || process.cwd();\n const workspacePath = resolve(join(basePath, name));\n \n // Check if already exists\n if (await pathExists(workspacePath)) {\n console.error(chalk.red(`Directory already exists: ${workspacePath}`));\n process.exit(1);\n }\n \n console.log(chalk.cyan(\"\\n📝 Creating new document workspace\\n\"));\n \n // Get document type\n const type = options.type as DocumentConfig[\"type\"] || await promptForType();\n \n // Get title\n const title = options.title || await promptForTitle(name);\n \n // Get initial objectives\n const goal = await promptForGoal();\n const audience = await promptForAudience();\n \n // Create workspace\n console.log(chalk.gray(\"\\nCreating workspace...\"));\n \n await createWorkspace({\n path: workspacePath,\n id: name,\n title,\n type,\n objectives: {\n primaryGoal: goal,\n secondaryGoals: [],\n keyTakeaways: [],\n },\n });\n \n // Note: audience is collected but not yet stored in config\n // This will be added when we implement config management\n if (audience) {\n // Future: store audience in config\n }\n \n console.log(chalk.green(`\\n✅ Document workspace created: ${workspacePath}`));\n \n // Show next steps\n console.log(chalk.cyan(\"\\n📋 Next steps:\\n\"));\n console.log(chalk.gray(` 1. Edit voice/tone.md to define your writing voice`));\n console.log(chalk.gray(` 2. Edit OBJECTIVES.md to refine your goals`));\n console.log(chalk.gray(` 3. Run: riotdoc outline ${name}`));\n console.log(chalk.gray(` 4. Run: riotdoc draft ${name}`));\n \n console.log(chalk.cyan(`\\n📁 Workspace structure:`));\n console.log(chalk.gray(` ${name}/`));\n console.log(chalk.gray(` ├── riotdoc.yaml # Configuration`));\n console.log(chalk.gray(` ├── OBJECTIVES.md # Goals and objectives`));\n console.log(chalk.gray(` ├── OUTLINE.md # Document outline`));\n console.log(chalk.gray(` ├── voice/ # Voice and style`));\n console.log(chalk.gray(` ├── evidence/ # Research and references`));\n console.log(chalk.gray(` ├── drafts/ # Draft iterations`));\n console.log(chalk.gray(` └── export/ # Final output`));\n \n } catch (error) {\n console.error(chalk.red(\"Failed to create workspace:\"), error);\n process.exit(1);\n }\n });\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { DocumentObjectives, VoiceConfig } from \"../types.js\";\n\nexport interface OutlineSection {\n title: string;\n points: string[];\n subsections?: OutlineSection[];\n}\n\nexport interface Outline {\n title: string;\n hook: string;\n sections: OutlineSection[];\n conclusion: string;\n}\n\n/**\n * Load outline from workspace\n */\nexport async function loadOutline(workspacePath: string): Promise<string> {\n const outlinePath = join(workspacePath, RIOTDOC_STRUCTURE.outlineFile);\n return await readFile(outlinePath, \"utf-8\");\n}\n\n/**\n * Save outline to workspace\n */\nexport async function saveOutline(workspacePath: string, content: string): Promise<void> {\n const outlinePath = join(workspacePath, RIOTDOC_STRUCTURE.outlineFile);\n await writeFile(outlinePath, content, \"utf-8\");\n}\n\n/**\n * Build prompt for outline generation\n */\nexport function buildOutlinePrompt(\n objectives: DocumentObjectives,\n voice: VoiceConfig,\n documentType: string\n): string {\n return `Generate an outline for a ${documentType}.\n\n## Objectives\n\nPrimary Goal: ${objectives.primaryGoal}\n\nSecondary Goals:\n${objectives.secondaryGoals.map(g => `- ${g}`).join(\"\\n\")}\n\nKey Takeaways:\n${objectives.keyTakeaways.map(t => `- ${t}`).join(\"\\n\")}\n\n${objectives.emotionalArc ? `Emotional Arc: ${objectives.emotionalArc}` : \"\"}\n\n## Voice & Tone\n\nTone: ${voice.tone}\nPoint of View: ${voice.pointOfView}\n\n## Output Format\n\nCreate a markdown outline with:\n1. A compelling hook/introduction\n2. 3-5 main sections with bullet points\n3. A conclusion with call to action\n\nUse ## for main sections, ### for subsections, and - for bullet points.\n`;\n}\n\n/**\n * Parse outline markdown into structure\n */\nexport function parseOutline(content: string): Outline {\n const lines = content.split(\"\\n\");\n const outline: Outline = {\n title: \"\",\n hook: \"\",\n sections: [],\n conclusion: \"\",\n };\n \n let currentSection: OutlineSection | null = null;\n let inIntro = false;\n let inConclusion = false;\n \n for (const line of lines) {\n // Title\n if (line.startsWith(\"# \")) {\n outline.title = line.slice(2).trim();\n continue;\n }\n \n // Main section\n if (line.startsWith(\"## \")) {\n const title = line.slice(3).trim().toLowerCase();\n if (title.includes(\"intro\") || title.includes(\"hook\")) {\n inIntro = true;\n inConclusion = false;\n currentSection = null;\n } else if (title.includes(\"conclusion\")) {\n inIntro = false;\n inConclusion = true;\n currentSection = null;\n } else {\n inIntro = false;\n inConclusion = false;\n currentSection = { title: line.slice(3).trim(), points: [] };\n outline.sections.push(currentSection);\n }\n continue;\n }\n \n // Bullet point\n if (line.match(/^[-*]\\s+/)) {\n const point = line.replace(/^[-*]\\s+/, \"\").trim();\n if (inIntro) {\n outline.hook += (outline.hook ? \"\\n\" : \"\") + point;\n } else if (inConclusion) {\n outline.conclusion += (outline.conclusion ? \"\\n\" : \"\") + point;\n } else if (currentSection) {\n currentSection.points.push(point);\n }\n }\n }\n \n return outline;\n}\n\n/**\n * Format outline structure as markdown\n */\nexport function formatOutline(outline: Outline): string {\n const parts: string[] = [];\n \n parts.push(`# ${outline.title}\\n`);\n \n if (outline.hook) {\n parts.push(`## Introduction\\n`);\n parts.push(outline.hook.split(\"\\n\").map(p => `- ${p}`).join(\"\\n\"));\n parts.push(\"\");\n }\n \n for (const section of outline.sections) {\n parts.push(`## ${section.title}\\n`);\n parts.push(section.points.map(p => `- ${p}`).join(\"\\n\"));\n parts.push(\"\");\n }\n \n if (outline.conclusion) {\n parts.push(`## Conclusion\\n`);\n parts.push(outline.conclusion.split(\"\\n\").map(p => `- ${p}`).join(\"\\n\"));\n }\n \n return parts.join(\"\\n\");\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { RiotDoc, DocumentConfig } from \"../types.js\";\n\n/**\n * Load document from workspace\n */\nexport async function loadDocument(workspacePath: string): Promise<RiotDoc | null> {\n try {\n const configPath = join(workspacePath, RIOTDOC_STRUCTURE.configFile);\n const content = await readFile(configPath, \"utf-8\");\n const config = parse(content) as DocumentConfig;\n \n // Convert date strings to Date objects\n config.createdAt = new Date(config.createdAt);\n config.updatedAt = new Date(config.updatedAt);\n \n return {\n config,\n voice: { tone: \"\", pointOfView: \"first\", styleNotes: [], avoid: [] },\n objectives: { primaryGoal: \"\", secondaryGoals: [], keyTakeaways: [] },\n evidence: [],\n drafts: [],\n revisions: [],\n workspacePath,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Check if path is a RiotDoc workspace\n */\nexport async function isRiotDocWorkspace(path: string): Promise<boolean> {\n try {\n const configPath = join(path, RIOTDOC_STRUCTURE.configFile);\n await stat(configPath);\n return true;\n } catch {\n return false;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { RIOTDOC_STRUCTURE } from \"../constants.js\";\nimport type { DocumentObjectives } from \"../types.js\";\n\n/**\n * Load objectives from workspace\n */\nexport async function loadObjectives(workspacePath: string): Promise<DocumentObjectives> {\n const objectivesPath = join(workspacePath, RIOTDOC_STRUCTURE.objectivesFile);\n \n try {\n const content = await readFile(objectivesPath, \"utf-8\");\n return parseObjectivesMarkdown(content);\n } catch {\n return {\n primaryGoal: \"\",\n secondaryGoals: [],\n keyTakeaways: [],\n };\n }\n}\n\n/**\n * Parse objectives markdown\n */\nfunction parseObjectivesMarkdown(content: string): DocumentObjectives {\n const objectives: DocumentObjectives = {\n primaryGoal: \"\",\n secondaryGoals: [],\n keyTakeaways: [],\n };\n \n // Extract primary goal\n const goalMatch = content.match(/##\\s*Primary\\s+Goal\\s*\\n+([^\\n#]+)/i);\n if (goalMatch) {\n objectives.primaryGoal = goalMatch[1].trim().replace(/^_|_$/g, \"\");\n }\n \n // Extract secondary goals\n // Use line-by-line parsing to avoid polynomial regex\n const lines = content.split('\\n');\n const secondaryLines: string[] = [];\n let inSecondary = false;\n \n for (const line of lines) {\n if (/^##\\s*Secondary\\s+Goals$/i.test(line)) {\n inSecondary = true;\n continue;\n }\n if (inSecondary && /^##/.test(line)) {\n break;\n }\n if (inSecondary) {\n secondaryLines.push(line);\n }\n }\n \n if (secondaryLines.length > 0) {\n const sectionContent = secondaryLines.join('\\n');\n const goals = sectionContent.matchAll(/^[-*]\\s+(.+)$/gm);\n for (const goal of goals) {\n const text = goal[1].trim().replace(/^_|_$/g, \"\");\n if (text && !text.startsWith(\"Add\")) {\n objectives.secondaryGoals.push(text);\n }\n }\n }\n \n // Extract key takeaways\n // Use line-by-line parsing to avoid polynomial regex\n const takeawayLines: string[] = [];\n let inTakeaways = false;\n \n for (const line of lines) {\n if (/^##\\s*Key\\s+Takeaways$/i.test(line)) {\n inTakeaways = true;\n continue;\n }\n if (inTakeaways && /^##/.test(line)) {\n break;\n }\n if (inTakeaways) {\n takeawayLines.push(line);\n }\n }\n \n if (takeawayLines.length > 0) {\n const sectionContent = takeawayLines.join('\\n');\n const takeaways = sectionContent.matchAll(/^\\d+\\.\\s+(.+)$/gm);\n for (const takeaway of takeaways) {\n const text = takeaway[1].trim().replace(/^_|_$/g, \"\");\n if (text && !text.startsWith(\"Define\")) {\n objectives.keyTakeaways.push(text);\n }\n }\n }\n \n // Extract call to action\n const ctaMatch = content.match(/##\\s*Call\\s+to\\s+Action\\s*\\n+([^\\n#]+)/i);\n if (ctaMatch) {\n const cta = ctaMatch[1].trim().replace(/^_|_$/g, \"\");\n if (cta && !cta.startsWith(\"What\")) {\n objectives.callToAction = cta;\n }\n }\n \n // Extract emotional arc\n const arcMatch = content.match(/##\\s*Emotional\\s+Arc\\s*\\n+([^\\n#]+)/i);\n if (arcMatch) {\n const arc = arcMatch[1].trim().replace(/^_|_$/g, \"\");\n if (arc && !arc.startsWith(\"Describe\")) {\n objectives.emotionalArc = arc;\n }\n }\n \n return objectives;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { resolve } from \"node:path\";\nimport { loadOutline, buildOutlinePrompt } from \"../../outline/generator.js\";\nimport { loadDocument } from \"../../workspace/loader.js\";\nimport { loadVoice } from \"../../voice/loader.js\";\nimport { loadObjectives } from \"../../objectives/loader.js\";\n\nexport interface OutlineOptions {\n generate?: boolean;\n edit?: boolean;\n}\n\nexport function registerOutlineCommand(program: Command): void {\n program\n .command(\"outline [path]\")\n .description(\"Generate or edit document outline\")\n .option(\"-g, --generate\", \"Generate outline with AI\")\n .option(\"-e, --edit\", \"Open outline for editing\")\n .action(async (pathArg: string | undefined, options: OutlineOptions) => {\n try {\n const workspacePath = resolve(pathArg || process.cwd());\n \n // Load document state\n const doc = await loadDocument(workspacePath);\n if (!doc) {\n console.error(chalk.red(\"Not a RiotDoc workspace\"));\n process.exit(1);\n }\n \n if (options.generate) {\n // Generate outline with AI\n console.log(chalk.cyan(\"Generating outline...\"));\n \n const voice = await loadVoice(workspacePath);\n const objectives = await loadObjectives(workspacePath);\n \n const prompt = buildOutlinePrompt(objectives, voice, doc.config.type);\n \n // TODO: Call AI provider\n console.log(chalk.yellow(\"\\nOutline generation prompt:\"));\n console.log(chalk.gray(prompt));\n console.log(chalk.yellow(\"\\n(AI integration pending - edit OUTLINE.md manually)\"));\n \n } else if (options.edit) {\n // Open in editor\n const { spawn } = await import(\"node:child_process\");\n const editor = process.env.EDITOR || \"vim\";\n const outlinePath = `${workspacePath}/OUTLINE.md`;\n \n spawn(editor, [outlinePath], { stdio: \"inherit\" });\n \n } else {\n // Show current outline\n const outline = await loadOutline(workspacePath);\n console.log(chalk.cyan(\"\\n📋 Current Outline:\\n\"));\n console.log(outline);\n \n console.log(chalk.gray(\"\\nOptions:\"));\n console.log(chalk.gray(\" --generate Generate outline with AI\"));\n console.log(chalk.gray(\" --edit Open outline in editor\"));\n }\n \n } catch (error) {\n console.error(chalk.red(\"Failed:\"), error);\n process.exit(1);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface DraftOptions {\n level?: string;\n from?: string;\n}\n\nexport function registerDraftCommand(program: Command): void {\n program\n .command(\"draft [path]\")\n .description(\"Create a new draft\")\n .option(\"-l, --level <level>\", \"AI assistance level (generate, expand, revise)\", \"expand\")\n .option(\"-f, --from <draft>\", \"Base on existing draft\")\n .action(async (_path: string | undefined, _options: DraftOptions) => {\n console.log(chalk.yellow(\"Draft command - AI integration pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load outline and objectives\"));\n console.log(chalk.gray(\" 2. Apply voice and style rules\"));\n console.log(chalk.gray(\" 3. Generate draft with specified assistance level\"));\n console.log(chalk.gray(\" 4. Save to drafts/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface ReviseOptions {\n draft?: string;\n message?: string;\n}\n\nexport function registerReviseCommand(program: Command): void {\n program\n .command(\"revise [path]\")\n .description(\"Add revision feedback\")\n .option(\"-d, --draft <number>\", \"Target draft number\")\n .option(\"-m, --message <message>\", \"Revision feedback\")\n .action(async (_path: string | undefined, _options: ReviseOptions) => {\n console.log(chalk.yellow(\"Revise command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load specified draft\"));\n console.log(chalk.gray(\" 2. Collect revision feedback\"));\n console.log(chalk.gray(\" 3. Save to revisions/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface CleanupOptions {\n draft?: string;\n}\n\nexport function registerCleanupCommand(program: Command): void {\n program\n .command(\"cleanup [path]\")\n .description(\"Light editing pass (grammar, clarity)\")\n .option(\"-d, --draft <number>\", \"Target draft\")\n .action(async (_path: string | undefined, _options: CleanupOptions) => {\n console.log(chalk.yellow(\"Cleanup command - AI integration pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load draft\"));\n console.log(chalk.gray(\" 2. Apply light editing for grammar and clarity\"));\n console.log(chalk.gray(\" 3. Save cleaned version\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface SpellcheckOptions {\n draft?: string;\n}\n\nexport function registerSpellcheckCommand(program: Command): void {\n program\n .command(\"spellcheck [path]\")\n .description(\"Fix spelling and grammar only\")\n .option(\"-d, --draft <number>\", \"Target draft\")\n .action(async (_path: string | undefined, _options: SpellcheckOptions) => {\n console.log(chalk.yellow(\"Spellcheck command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load draft\"));\n console.log(chalk.gray(\" 2. Check spelling and basic grammar\"));\n console.log(chalk.gray(\" 3. Report or fix issues\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nexport interface ExportOptions {\n draft?: string;\n output?: string;\n}\n\nexport function registerExportCommand(program: Command): void {\n program\n .command(\"export [path]\")\n .description(\"Export publication-ready document\")\n .option(\"-d, --draft <number>\", \"Source draft\")\n .option(\"-o, --output <file>\", \"Output file name\")\n .action(async (_path: string | undefined, _options: ExportOptions) => {\n console.log(chalk.yellow(\"Export command - implementation pending\"));\n console.log(chalk.gray(\"\\nThis command will:\"));\n console.log(chalk.gray(\" 1. Load specified draft\"));\n console.log(chalk.gray(\" 2. Apply final formatting\"));\n console.log(chalk.gray(\" 3. Export to export/ directory\"));\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { resolve } from \"node:path\";\nimport { loadDocument } from \"../../workspace/loader.js\";\n\nexport function registerStatusCommand(program: Command): void {\n program\n .command(\"status [path]\")\n .description(\"Show document status\")\n .action(async (pathArg: string | undefined) => {\n try {\n const workspacePath = resolve(pathArg || process.cwd());\n \n const doc = await loadDocument(workspacePath);\n if (!doc) {\n console.error(chalk.red(\"Not a RiotDoc workspace\"));\n process.exit(1);\n }\n \n console.log(chalk.cyan(\"\\n📊 Document Status\\n\"));\n console.log(chalk.gray(`Title: ${doc.config.title}`));\n console.log(chalk.gray(`Type: ${doc.config.type}`));\n console.log(chalk.gray(`Status: ${doc.config.status}`));\n console.log(chalk.gray(`Created: ${doc.config.createdAt.toLocaleDateString()}`));\n console.log(chalk.gray(`Updated: ${doc.config.updatedAt.toLocaleDateString()}`));\n \n if (doc.config.targetWordCount) {\n console.log(chalk.gray(`Target: ${doc.config.targetWordCount} words`));\n }\n \n console.log(chalk.cyan(\"\\n📁 Workspace: \") + chalk.gray(workspacePath));\n \n } catch (error) {\n console.error(chalk.red(\"Failed:\"), error);\n process.exit(1);\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { registerCreateCommand } from \"./commands/create.js\";\nimport { registerOutlineCommand } from \"./commands/outline.js\";\nimport { registerDraftCommand } from \"./commands/draft.js\";\nimport { registerReviseCommand } from \"./commands/revise.js\";\nimport { registerCleanupCommand } from \"./commands/cleanup.js\";\nimport { registerSpellcheckCommand } from \"./commands/spellcheck.js\";\nimport { registerExportCommand } from \"./commands/export.js\";\nimport { registerStatusCommand } from \"./commands/status.js\";\n\nconst VERSION = \"1.0.0-dev.0\";\n\n/**\n * Create the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n \n program\n .name(\"riotdoc\")\n .description(\"Structured document creation with AI assistance\")\n .version(VERSION)\n .configureHelp({\n sortSubcommands: true,\n });\n \n // Register commands (implemented in subsequent steps)\n registerCreateCommand(program);\n registerOutlineCommand(program);\n registerDraftCommand(program);\n registerReviseCommand(program);\n registerCleanupCommand(program);\n registerSpellcheckCommand(program);\n registerExportCommand(program);\n registerStatusCommand(program);\n \n // Global options\n program\n .option(\"-v, --verbose\", \"Verbose output\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--no-color\", \"Disable colored output\");\n \n // Handle unknown commands\n program.on(\"command:*\", () => {\n console.error(chalk.red(`Unknown command: ${program.args.join(\" \")}`));\n console.log(`Run ${chalk.cyan(\"riotdoc --help\")} for usage.`);\n process.exit(1);\n });\n \n return program;\n}\n\n// All commands are now imported from separate files\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -76,34 +76,27 @@ export declare interface DocumentConfig {
|
|
|
76
76
|
export declare const DocumentConfigSchema: z.ZodObject<{
|
|
77
77
|
id: z.ZodString;
|
|
78
78
|
title: z.ZodString;
|
|
79
|
-
type: z.ZodEnum<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
type: z.ZodEnum<{
|
|
80
|
+
"blog-post": "blog-post";
|
|
81
|
+
"podcast-script": "podcast-script";
|
|
82
|
+
"technical-doc": "technical-doc";
|
|
83
|
+
newsletter: "newsletter";
|
|
84
|
+
custom: "custom";
|
|
85
|
+
}>;
|
|
86
|
+
status: z.ZodEnum<{
|
|
87
|
+
idea: "idea";
|
|
88
|
+
outlined: "outlined";
|
|
89
|
+
drafting: "drafting";
|
|
90
|
+
revising: "revising";
|
|
91
|
+
final: "final";
|
|
92
|
+
exported: "exported";
|
|
93
|
+
}>;
|
|
94
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
95
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
83
96
|
targetWordCount: z.ZodOptional<z.ZodNumber>;
|
|
84
97
|
audience: z.ZodOptional<z.ZodString>;
|
|
85
98
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
86
|
-
},
|
|
87
|
-
id: string;
|
|
88
|
-
title: string;
|
|
89
|
-
type: "blog-post" | "podcast-script" | "technical-doc" | "newsletter" | "custom";
|
|
90
|
-
status: "idea" | "outlined" | "drafting" | "revising" | "final" | "exported";
|
|
91
|
-
createdAt: Date;
|
|
92
|
-
updatedAt: Date;
|
|
93
|
-
targetWordCount?: number | undefined;
|
|
94
|
-
audience?: string | undefined;
|
|
95
|
-
metadata?: Record<string, unknown> | undefined;
|
|
96
|
-
}, {
|
|
97
|
-
id: string;
|
|
98
|
-
title: string;
|
|
99
|
-
type: "blog-post" | "podcast-script" | "technical-doc" | "newsletter" | "custom";
|
|
100
|
-
status: "idea" | "outlined" | "drafting" | "revising" | "final" | "exported";
|
|
101
|
-
createdAt: Date;
|
|
102
|
-
updatedAt: Date;
|
|
103
|
-
targetWordCount?: number | undefined;
|
|
104
|
-
audience?: string | undefined;
|
|
105
|
-
metadata?: Record<string, unknown> | undefined;
|
|
106
|
-
}>;
|
|
99
|
+
}, z.core.$strip>;
|
|
107
100
|
|
|
108
101
|
/**
|
|
109
102
|
* Document objectives
|
|
@@ -123,23 +116,11 @@ export declare interface DocumentObjectives {
|
|
|
123
116
|
|
|
124
117
|
export declare const DocumentObjectivesSchema: z.ZodObject<{
|
|
125
118
|
primaryGoal: z.ZodString;
|
|
126
|
-
secondaryGoals: z.ZodArray<z.ZodString
|
|
119
|
+
secondaryGoals: z.ZodArray<z.ZodString>;
|
|
127
120
|
callToAction: z.ZodOptional<z.ZodString>;
|
|
128
|
-
keyTakeaways: z.ZodArray<z.ZodString
|
|
121
|
+
keyTakeaways: z.ZodArray<z.ZodString>;
|
|
129
122
|
emotionalArc: z.ZodOptional<z.ZodString>;
|
|
130
|
-
},
|
|
131
|
-
primaryGoal: string;
|
|
132
|
-
secondaryGoals: string[];
|
|
133
|
-
keyTakeaways: string[];
|
|
134
|
-
callToAction?: string | undefined;
|
|
135
|
-
emotionalArc?: string | undefined;
|
|
136
|
-
}, {
|
|
137
|
-
primaryGoal: string;
|
|
138
|
-
secondaryGoals: string[];
|
|
139
|
-
keyTakeaways: string[];
|
|
140
|
-
callToAction?: string | undefined;
|
|
141
|
-
emotionalArc?: string | undefined;
|
|
142
|
-
}>;
|
|
123
|
+
}, z.core.$strip>;
|
|
143
124
|
|
|
144
125
|
export declare interface DocumentStats {
|
|
145
126
|
wordCount: number;
|
|
@@ -340,22 +321,14 @@ export declare interface VoiceConfig {
|
|
|
340
321
|
|
|
341
322
|
export declare const VoiceConfigSchema: z.ZodObject<{
|
|
342
323
|
tone: z.ZodString;
|
|
343
|
-
pointOfView: z.ZodEnum<
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
examplePhrases?: string[] | undefined;
|
|
353
|
-
}, {
|
|
354
|
-
tone: string;
|
|
355
|
-
pointOfView: "first" | "second" | "third";
|
|
356
|
-
styleNotes: string[];
|
|
357
|
-
avoid: string[];
|
|
358
|
-
examplePhrases?: string[] | undefined;
|
|
359
|
-
}>;
|
|
324
|
+
pointOfView: z.ZodEnum<{
|
|
325
|
+
first: "first";
|
|
326
|
+
second: "second";
|
|
327
|
+
third: "third";
|
|
328
|
+
}>;
|
|
329
|
+
styleNotes: z.ZodArray<z.ZodString>;
|
|
330
|
+
avoid: z.ZodArray<z.ZodString>;
|
|
331
|
+
examplePhrases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
332
|
+
}, z.core.$strip>;
|
|
360
333
|
|
|
361
334
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { D, a, R, c, h, l, b, p, d } from "./loader-
|
|
2
|
+
import { D, a, R, c, h, l, b, p, d } from "./loader-Jj2cSi3H.js";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
const DocumentConfigSchema = z.object({
|
|
5
5
|
id: z.string(),
|
|
@@ -10,7 +10,7 @@ const DocumentConfigSchema = z.object({
|
|
|
10
10
|
updatedAt: z.coerce.date(),
|
|
11
11
|
targetWordCount: z.number().optional(),
|
|
12
12
|
audience: z.string().optional(),
|
|
13
|
-
metadata: z.record(z.unknown()).optional()
|
|
13
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
14
14
|
});
|
|
15
15
|
const VoiceConfigSchema = z.object({
|
|
16
16
|
tone: z.string(),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/schema.ts","../src/voice/prompt-builder.ts","../src/style/validator.ts","../src/style/reporter.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const DocumentConfigSchema = z.object({\n id: z.string(),\n title: z.string(),\n type: z.enum([\"blog-post\", \"podcast-script\", \"technical-doc\", \"newsletter\", \"custom\"]),\n status: z.enum([\"idea\", \"outlined\", \"drafting\", \"revising\", \"final\", \"exported\"]),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n targetWordCount: z.number().optional(),\n audience: z.string().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const VoiceConfigSchema = z.object({\n tone: z.string(),\n pointOfView: z.enum([\"first\", \"second\", \"third\"]),\n styleNotes: z.array(z.string()),\n avoid: z.array(z.string()),\n examplePhrases: z.array(z.string()).optional(),\n});\n\nexport const DocumentObjectivesSchema = z.object({\n primaryGoal: z.string(),\n secondaryGoals: z.array(z.string()),\n callToAction: z.string().optional(),\n keyTakeaways: z.array(z.string()),\n emotionalArc: z.string().optional(),\n});\n","import type { VoiceConfig } from \"../types.js\";\n\n/**\n * Build a prompt section describing the voice/tone\n */\nexport function buildVoicePrompt(voice: VoiceConfig): string {\n const sections: string[] = [];\n \n sections.push(`## Writing Voice\\n`);\n sections.push(`Tone: ${voice.tone}`);\n sections.push(`Point of view: ${formatPointOfView(voice.pointOfView)}`);\n \n if (voice.styleNotes.length > 0) {\n sections.push(`\\n### Style Guidelines\\n`);\n sections.push(`Do:\\n${voice.styleNotes.map(n => `- ${n}`).join(\"\\n\")}`);\n }\n \n if (voice.avoid.length > 0) {\n sections.push(`\\nAvoid:\\n${voice.avoid.map(a => `- ${a}`).join(\"\\n\")}`);\n }\n \n if (voice.examplePhrases && voice.examplePhrases.length > 0) {\n sections.push(`\\n### Example Phrases\\n`);\n sections.push(voice.examplePhrases.map(p => `\"${p}\"`).join(\"\\n\"));\n }\n \n return sections.join(\"\\n\");\n}\n\nfunction formatPointOfView(pov: \"first\" | \"second\" | \"third\"): string {\n switch (pov) {\n case \"first\": return \"First person (I, we)\";\n case \"second\": return \"Second person (you)\";\n case \"third\": return \"Third person (they, it)\";\n }\n}\n","export interface StyleViolation {\n rule: string;\n message: string;\n line?: number;\n severity: \"error\" | \"warning\" | \"info\";\n}\n\nexport interface StyleValidationResult {\n valid: boolean;\n violations: StyleViolation[];\n stats: DocumentStats;\n}\n\nexport interface DocumentStats {\n wordCount: number;\n sentenceCount: number;\n paragraphCount: number;\n avgWordsPerSentence: number;\n avgSentencesPerParagraph: number;\n}\n\n/**\n * Validate document content against style rules\n */\nexport function validateStyle(\n content: string,\n rules: StyleRules\n): StyleValidationResult {\n const violations: StyleViolation[] = [];\n const stats = calculateStats(content);\n \n // Check word count\n if (rules.maxWordCount && stats.wordCount > rules.maxWordCount) {\n violations.push({\n rule: \"max-word-count\",\n message: `Document has ${stats.wordCount} words, exceeds max of ${rules.maxWordCount}`,\n severity: \"warning\",\n });\n }\n \n if (rules.minWordCount && stats.wordCount < rules.minWordCount) {\n violations.push({\n rule: \"min-word-count\",\n message: `Document has ${stats.wordCount} words, below min of ${rules.minWordCount}`,\n severity: \"warning\",\n });\n }\n \n // Check sentence length\n if (rules.maxSentenceLength) {\n const longSentences = findLongSentences(content, rules.maxSentenceLength);\n for (const sentence of longSentences) {\n violations.push({\n rule: \"sentence-length\",\n message: `Sentence has ${sentence.wordCount} words: \"${sentence.preview}...\"`,\n line: sentence.line,\n severity: \"info\",\n });\n }\n }\n \n // Check passive voice\n if (rules.checkPassiveVoice) {\n const passiveInstances = findPassiveVoice(content);\n for (const instance of passiveInstances) {\n violations.push({\n rule: \"passive-voice\",\n message: `Possible passive voice: \"${instance.text}\"`,\n line: instance.line,\n severity: \"info\",\n });\n }\n }\n \n // Check for avoid patterns\n if (rules.avoidPatterns) {\n for (const pattern of rules.avoidPatterns) {\n const regex = new RegExp(pattern, \"gi\");\n const matches = content.matchAll(regex);\n for (const match of matches) {\n violations.push({\n rule: \"avoid-pattern\",\n message: `Found \"${match[0]}\" which should be avoided`,\n severity: \"warning\",\n });\n }\n }\n }\n \n return {\n valid: violations.filter(v => v.severity === \"error\").length === 0,\n violations,\n stats,\n };\n}\n\nexport interface StyleRules {\n maxWordCount?: number;\n minWordCount?: number;\n maxSentenceLength?: number;\n checkPassiveVoice?: boolean;\n avoidPatterns?: string[];\n}\n\n/**\n * Calculate document statistics\n */\nfunction calculateStats(content: string): DocumentStats {\n const words = content.split(/\\s+/).filter(w => w.length > 0);\n const sentences = content.split(/[.!?]+/).filter(s => s.trim().length > 0);\n const paragraphs = content.split(/\\n\\n+/).filter(p => p.trim().length > 0);\n \n return {\n wordCount: words.length,\n sentenceCount: sentences.length,\n paragraphCount: paragraphs.length,\n avgWordsPerSentence: sentences.length > 0 \n ? Math.round(words.length / sentences.length) \n : 0,\n avgSentencesPerParagraph: paragraphs.length > 0 \n ? Math.round(sentences.length / paragraphs.length) \n : 0,\n };\n}\n\n/**\n * Find sentences exceeding word limit\n */\nfunction findLongSentences(\n content: string, \n maxWords: number\n): Array<{ wordCount: number; preview: string; line: number }> {\n const results: Array<{ wordCount: number; preview: string; line: number }> = [];\n const lines = content.split(\"\\n\");\n \n let lineNum = 0;\n for (const line of lines) {\n lineNum++;\n const sentences = line.split(/[.!?]+/);\n for (const sentence of sentences) {\n const words = sentence.trim().split(/\\s+/).filter(w => w.length > 0);\n if (words.length > maxWords) {\n results.push({\n wordCount: words.length,\n preview: sentence.trim().slice(0, 50),\n line: lineNum,\n });\n }\n }\n }\n \n return results;\n}\n\n/**\n * Simple passive voice detection\n */\nfunction findPassiveVoice(content: string): Array<{ text: string; line: number }> {\n const results: Array<{ text: string; line: number }> = [];\n const lines = content.split(\"\\n\");\n \n // Common passive voice patterns\n const passivePatterns = [\n /\\b(was|were|been|being|is|are|am)\\s+\\w+ed\\b/gi,\n /\\b(was|were|been|being|is|are|am)\\s+\\w+en\\b/gi,\n ];\n \n let lineNum = 0;\n for (const line of lines) {\n lineNum++;\n for (const pattern of passivePatterns) {\n const matches = line.matchAll(pattern);\n for (const match of matches) {\n results.push({\n text: match[0],\n line: lineNum,\n });\n }\n }\n }\n \n return results;\n}\n","import chalk from \"chalk\";\nimport type { StyleValidationResult, StyleViolation } from \"./validator.js\";\n\n/**\n * Format style validation result for terminal\n */\nexport function formatStyleReport(result: StyleValidationResult): string {\n const lines: string[] = [];\n \n lines.push(chalk.cyan(\"\\n📊 Document Statistics\"));\n lines.push(chalk.gray(` Words: ${result.stats.wordCount}`));\n lines.push(chalk.gray(` Sentences: ${result.stats.sentenceCount}`));\n lines.push(chalk.gray(` Paragraphs: ${result.stats.paragraphCount}`));\n lines.push(chalk.gray(` Avg words/sentence: ${result.stats.avgWordsPerSentence}`));\n \n if (result.violations.length === 0) {\n lines.push(chalk.green(\"\\n✅ No style violations found.\"));\n return lines.join(\"\\n\");\n }\n \n lines.push(chalk.yellow(`\\n⚠️ Style Issues (${result.violations.length}):`));\n \n const grouped = groupViolations(result.violations);\n \n for (const [severity, violations] of Object.entries(grouped)) {\n if (violations.length === 0) continue;\n \n const icon = severity === \"error\" ? \"❌\" : severity === \"warning\" ? \"⚠️\" : \"ℹ️\";\n const color = severity === \"error\" ? chalk.red : severity === \"warning\" ? chalk.yellow : chalk.gray;\n \n lines.push(color(`\\n${icon} ${severity.toUpperCase()} (${violations.length}):`));\n for (const v of violations.slice(0, 5)) {\n const lineInfo = v.line ? ` (line ${v.line})` : \"\";\n lines.push(color(` - ${v.message}${lineInfo}`));\n }\n if (violations.length > 5) {\n lines.push(color(` ... and ${violations.length - 5} more`));\n }\n }\n \n return lines.join(\"\\n\");\n}\n\nfunction groupViolations(violations: StyleViolation[]): Record<string, StyleViolation[]> {\n return {\n error: violations.filter(v => v.severity === \"error\"),\n warning: violations.filter(v => v.severity === \"warning\"),\n info: violations.filter(v => v.severity === \"info\"),\n };\n}\n"],"names":["a","p"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/schema.ts","../src/voice/prompt-builder.ts","../src/style/validator.ts","../src/style/reporter.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const DocumentConfigSchema = z.object({\n id: z.string(),\n title: z.string(),\n type: z.enum([\"blog-post\", \"podcast-script\", \"technical-doc\", \"newsletter\", \"custom\"]),\n status: z.enum([\"idea\", \"outlined\", \"drafting\", \"revising\", \"final\", \"exported\"]),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n targetWordCount: z.number().optional(),\n audience: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const VoiceConfigSchema = z.object({\n tone: z.string(),\n pointOfView: z.enum([\"first\", \"second\", \"third\"]),\n styleNotes: z.array(z.string()),\n avoid: z.array(z.string()),\n examplePhrases: z.array(z.string()).optional(),\n});\n\nexport const DocumentObjectivesSchema = z.object({\n primaryGoal: z.string(),\n secondaryGoals: z.array(z.string()),\n callToAction: z.string().optional(),\n keyTakeaways: z.array(z.string()),\n emotionalArc: z.string().optional(),\n});\n","import type { VoiceConfig } from \"../types.js\";\n\n/**\n * Build a prompt section describing the voice/tone\n */\nexport function buildVoicePrompt(voice: VoiceConfig): string {\n const sections: string[] = [];\n \n sections.push(`## Writing Voice\\n`);\n sections.push(`Tone: ${voice.tone}`);\n sections.push(`Point of view: ${formatPointOfView(voice.pointOfView)}`);\n \n if (voice.styleNotes.length > 0) {\n sections.push(`\\n### Style Guidelines\\n`);\n sections.push(`Do:\\n${voice.styleNotes.map(n => `- ${n}`).join(\"\\n\")}`);\n }\n \n if (voice.avoid.length > 0) {\n sections.push(`\\nAvoid:\\n${voice.avoid.map(a => `- ${a}`).join(\"\\n\")}`);\n }\n \n if (voice.examplePhrases && voice.examplePhrases.length > 0) {\n sections.push(`\\n### Example Phrases\\n`);\n sections.push(voice.examplePhrases.map(p => `\"${p}\"`).join(\"\\n\"));\n }\n \n return sections.join(\"\\n\");\n}\n\nfunction formatPointOfView(pov: \"first\" | \"second\" | \"third\"): string {\n switch (pov) {\n case \"first\": return \"First person (I, we)\";\n case \"second\": return \"Second person (you)\";\n case \"third\": return \"Third person (they, it)\";\n }\n}\n","export interface StyleViolation {\n rule: string;\n message: string;\n line?: number;\n severity: \"error\" | \"warning\" | \"info\";\n}\n\nexport interface StyleValidationResult {\n valid: boolean;\n violations: StyleViolation[];\n stats: DocumentStats;\n}\n\nexport interface DocumentStats {\n wordCount: number;\n sentenceCount: number;\n paragraphCount: number;\n avgWordsPerSentence: number;\n avgSentencesPerParagraph: number;\n}\n\n/**\n * Validate document content against style rules\n */\nexport function validateStyle(\n content: string,\n rules: StyleRules\n): StyleValidationResult {\n const violations: StyleViolation[] = [];\n const stats = calculateStats(content);\n \n // Check word count\n if (rules.maxWordCount && stats.wordCount > rules.maxWordCount) {\n violations.push({\n rule: \"max-word-count\",\n message: `Document has ${stats.wordCount} words, exceeds max of ${rules.maxWordCount}`,\n severity: \"warning\",\n });\n }\n \n if (rules.minWordCount && stats.wordCount < rules.minWordCount) {\n violations.push({\n rule: \"min-word-count\",\n message: `Document has ${stats.wordCount} words, below min of ${rules.minWordCount}`,\n severity: \"warning\",\n });\n }\n \n // Check sentence length\n if (rules.maxSentenceLength) {\n const longSentences = findLongSentences(content, rules.maxSentenceLength);\n for (const sentence of longSentences) {\n violations.push({\n rule: \"sentence-length\",\n message: `Sentence has ${sentence.wordCount} words: \"${sentence.preview}...\"`,\n line: sentence.line,\n severity: \"info\",\n });\n }\n }\n \n // Check passive voice\n if (rules.checkPassiveVoice) {\n const passiveInstances = findPassiveVoice(content);\n for (const instance of passiveInstances) {\n violations.push({\n rule: \"passive-voice\",\n message: `Possible passive voice: \"${instance.text}\"`,\n line: instance.line,\n severity: \"info\",\n });\n }\n }\n \n // Check for avoid patterns\n if (rules.avoidPatterns) {\n for (const pattern of rules.avoidPatterns) {\n const regex = new RegExp(pattern, \"gi\");\n const matches = content.matchAll(regex);\n for (const match of matches) {\n violations.push({\n rule: \"avoid-pattern\",\n message: `Found \"${match[0]}\" which should be avoided`,\n severity: \"warning\",\n });\n }\n }\n }\n \n return {\n valid: violations.filter(v => v.severity === \"error\").length === 0,\n violations,\n stats,\n };\n}\n\nexport interface StyleRules {\n maxWordCount?: number;\n minWordCount?: number;\n maxSentenceLength?: number;\n checkPassiveVoice?: boolean;\n avoidPatterns?: string[];\n}\n\n/**\n * Calculate document statistics\n */\nfunction calculateStats(content: string): DocumentStats {\n const words = content.split(/\\s+/).filter(w => w.length > 0);\n const sentences = content.split(/[.!?]+/).filter(s => s.trim().length > 0);\n const paragraphs = content.split(/\\n\\n+/).filter(p => p.trim().length > 0);\n \n return {\n wordCount: words.length,\n sentenceCount: sentences.length,\n paragraphCount: paragraphs.length,\n avgWordsPerSentence: sentences.length > 0 \n ? Math.round(words.length / sentences.length) \n : 0,\n avgSentencesPerParagraph: paragraphs.length > 0 \n ? Math.round(sentences.length / paragraphs.length) \n : 0,\n };\n}\n\n/**\n * Find sentences exceeding word limit\n */\nfunction findLongSentences(\n content: string, \n maxWords: number\n): Array<{ wordCount: number; preview: string; line: number }> {\n const results: Array<{ wordCount: number; preview: string; line: number }> = [];\n const lines = content.split(\"\\n\");\n \n let lineNum = 0;\n for (const line of lines) {\n lineNum++;\n const sentences = line.split(/[.!?]+/);\n for (const sentence of sentences) {\n const words = sentence.trim().split(/\\s+/).filter(w => w.length > 0);\n if (words.length > maxWords) {\n results.push({\n wordCount: words.length,\n preview: sentence.trim().slice(0, 50),\n line: lineNum,\n });\n }\n }\n }\n \n return results;\n}\n\n/**\n * Simple passive voice detection\n */\nfunction findPassiveVoice(content: string): Array<{ text: string; line: number }> {\n const results: Array<{ text: string; line: number }> = [];\n const lines = content.split(\"\\n\");\n \n // Common passive voice patterns\n const passivePatterns = [\n /\\b(was|were|been|being|is|are|am)\\s+\\w+ed\\b/gi,\n /\\b(was|were|been|being|is|are|am)\\s+\\w+en\\b/gi,\n ];\n \n let lineNum = 0;\n for (const line of lines) {\n lineNum++;\n for (const pattern of passivePatterns) {\n const matches = line.matchAll(pattern);\n for (const match of matches) {\n results.push({\n text: match[0],\n line: lineNum,\n });\n }\n }\n }\n \n return results;\n}\n","import chalk from \"chalk\";\nimport type { StyleValidationResult, StyleViolation } from \"./validator.js\";\n\n/**\n * Format style validation result for terminal\n */\nexport function formatStyleReport(result: StyleValidationResult): string {\n const lines: string[] = [];\n \n lines.push(chalk.cyan(\"\\n📊 Document Statistics\"));\n lines.push(chalk.gray(` Words: ${result.stats.wordCount}`));\n lines.push(chalk.gray(` Sentences: ${result.stats.sentenceCount}`));\n lines.push(chalk.gray(` Paragraphs: ${result.stats.paragraphCount}`));\n lines.push(chalk.gray(` Avg words/sentence: ${result.stats.avgWordsPerSentence}`));\n \n if (result.violations.length === 0) {\n lines.push(chalk.green(\"\\n✅ No style violations found.\"));\n return lines.join(\"\\n\");\n }\n \n lines.push(chalk.yellow(`\\n⚠️ Style Issues (${result.violations.length}):`));\n \n const grouped = groupViolations(result.violations);\n \n for (const [severity, violations] of Object.entries(grouped)) {\n if (violations.length === 0) continue;\n \n const icon = severity === \"error\" ? \"❌\" : severity === \"warning\" ? \"⚠️\" : \"ℹ️\";\n const color = severity === \"error\" ? chalk.red : severity === \"warning\" ? chalk.yellow : chalk.gray;\n \n lines.push(color(`\\n${icon} ${severity.toUpperCase()} (${violations.length}):`));\n for (const v of violations.slice(0, 5)) {\n const lineInfo = v.line ? ` (line ${v.line})` : \"\";\n lines.push(color(` - ${v.message}${lineInfo}`));\n }\n if (violations.length > 5) {\n lines.push(color(` ... and ${violations.length - 5} more`));\n }\n }\n \n return lines.join(\"\\n\");\n}\n\nfunction groupViolations(violations: StyleViolation[]): Record<string, StyleViolation[]> {\n return {\n error: violations.filter(v => v.severity === \"error\"),\n warning: violations.filter(v => v.severity === \"warning\"),\n info: violations.filter(v => v.severity === \"info\"),\n };\n}\n"],"names":["a","p"],"mappings":"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"}
|
|
@@ -6293,16 +6293,45 @@ async function loadStyleRulesFile(voiceDir) {
|
|
|
6293
6293
|
function parseStyleRulesMarkdown(content) {
|
|
6294
6294
|
const doItems = [];
|
|
6295
6295
|
const dontItems = [];
|
|
6296
|
-
const
|
|
6297
|
-
|
|
6298
|
-
|
|
6296
|
+
const lines = content.split("\n");
|
|
6297
|
+
const doLines = [];
|
|
6298
|
+
let inDo = false;
|
|
6299
|
+
for (const line of lines) {
|
|
6300
|
+
if (/^##\s*Do$/i.test(line)) {
|
|
6301
|
+
inDo = true;
|
|
6302
|
+
continue;
|
|
6303
|
+
}
|
|
6304
|
+
if (inDo && /^##/.test(line)) {
|
|
6305
|
+
break;
|
|
6306
|
+
}
|
|
6307
|
+
if (inDo) {
|
|
6308
|
+
doLines.push(line);
|
|
6309
|
+
}
|
|
6310
|
+
}
|
|
6311
|
+
if (doLines.length > 0) {
|
|
6312
|
+
const sectionContent = doLines.join("\n");
|
|
6313
|
+
const items = sectionContent.matchAll(/^[-*]\s+(.+)$/gm);
|
|
6299
6314
|
for (const item of items) {
|
|
6300
6315
|
doItems.push(item[1].trim());
|
|
6301
6316
|
}
|
|
6302
6317
|
}
|
|
6303
|
-
const
|
|
6304
|
-
|
|
6305
|
-
|
|
6318
|
+
const dontLines = [];
|
|
6319
|
+
let inDont = false;
|
|
6320
|
+
for (const line of lines) {
|
|
6321
|
+
if (/^##\s*Don'?t$/i.test(line)) {
|
|
6322
|
+
inDont = true;
|
|
6323
|
+
continue;
|
|
6324
|
+
}
|
|
6325
|
+
if (inDont && /^##/.test(line)) {
|
|
6326
|
+
break;
|
|
6327
|
+
}
|
|
6328
|
+
if (inDont) {
|
|
6329
|
+
dontLines.push(line);
|
|
6330
|
+
}
|
|
6331
|
+
}
|
|
6332
|
+
if (dontLines.length > 0) {
|
|
6333
|
+
const sectionContent = dontLines.join("\n");
|
|
6334
|
+
const items = sectionContent.matchAll(/^[-*]\s+(.+)$/gm);
|
|
6306
6335
|
for (const item of items) {
|
|
6307
6336
|
dontItems.push(item[1].trim());
|
|
6308
6337
|
}
|
|
@@ -6355,4 +6384,4 @@ export {
|
|
|
6355
6384
|
loadGlossary as l,
|
|
6356
6385
|
parseStyleRulesMarkdown as p
|
|
6357
6386
|
};
|
|
6358
|
-
//# sourceMappingURL=loader-
|
|
6387
|
+
//# sourceMappingURL=loader-Jj2cSi3H.js.map
|