UNPKG

story-weaver-ai

Version:

A narrative development system for AI-driven storytelling with Jungian psychology

239 lines (215 loc) 8.68 kB
#!/usr/bin/env node /** * Story Weaver CLI * * @author Sean Pavlak * @github https://github.com/seanpavlak/cursor-story-master * * A story writing management system with Jungian psychology influences. */ import { program } from 'commander'; import { registerStoryCommands } from '../scripts/commands.js'; import { fileURLToPath } from 'url'; import { dirname, resolve } from 'path'; import { spawn } from 'child_process'; import { createRequire } from 'module'; import chalk from 'chalk'; // Get the directory path for the module const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const require = createRequire(import.meta.url); // Get package info const packageJson = require('../package.json'); // Welcome message console.log(chalk.blue(` ┌─────────────────────────────────────────────┐ │ │ │ 🧠 Story Weaver v${packageJson.version.padEnd(5)} │ │ │ │ Narrative Analysis & Refinement System │ │ With Jungian Psychology Influences │ │ │ └─────────────────────────────────────────────┘ `)); // Initialize the CLI program .name('story-weaver') .description('Story Weaver - A story writing system with Jungian psychology influences') .version(packageJson.version); // Register story analysis and refinement commands registerStoryCommands(program); // Parse concept document program .command('parse-concept') .description('Parse a story concept document to generate story elements') .requiredOption('-i, --input <file>', 'Path to the concept document') .option('-o, --output <file>', 'Output file for story elements', 'elements/elements.json') .option('-a, --archetypes', 'Focus on archetypal analysis') .option('-s, --symbols', 'Include symbolic analysis') .option('-d, --dependencies', 'Generate element dependencies') .option('-m, --model <model>', 'Claude model to use') .action(async (options) => { try { console.log(chalk.blue(`Parsing concept document: ${options.input}`)); const conceptParser = await import('../scripts/modules/concept-parser.js'); await conceptParser.parseConceptDocument(options); console.log(chalk.green(`Successfully parsed concept document and generated elements at ${options.output}`)); } catch (error) { console.error(chalk.red(`Failed to parse concept document: ${error.message}`)); process.exit(1); } }); // List elements program .command('list') .description('List all story elements') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .option('-s, --status <status>', 'Filter by status') .option('-a, --archetype <archetype>', 'Filter by archetype') .option('-t, --theme <theme>', 'Filter by theme') .action(async (options) => { try { const elementManager = await import('../scripts/modules/element-manager.js'); await elementManager.listElements(options); } catch (error) { console.error(chalk.red(`Failed to list elements: ${error.message}`)); process.exit(1); } }); // Add element program .command('add-element') .description('Add a new story element') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .requiredOption('-t, --title <title>', 'Element title') .option('-d, --description <description>', 'Element description') .option('-a, --archetypes <archetypes...>', 'Associated archetypes') .option('-T, --themes <themes...>', 'Associated themes') .option('-p, --priority <priority>', 'Element priority (high, medium, low)', 'medium') .option('-D, --dependencies <dependencies...>', 'Element dependencies (IDs)') .option('--details <details>', 'Detailed element description') .action(async (options) => { try { const elementManager = await import('../scripts/modules/element-manager.js'); await elementManager.addElement(options); console.log(chalk.green('New element added successfully')); } catch (error) { console.error(chalk.red(`Failed to add element: ${error.message}`)); process.exit(1); } }); // Set element status program .command('set-status') .description('Set the status of a story element') .requiredOption('--id <id>', 'Element ID') .requiredOption('--status <status>', 'New status value') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .action(async (options) => { try { const elementManager = await import('../scripts/modules/element-manager.js'); await elementManager.setElementStatus(options.id, options.status, options.file); console.log(chalk.green(`Element ${options.id} status set to "${options.status}"`)); } catch (error) { console.error(chalk.red(`Failed to set element status: ${error.message}`)); process.exit(1); } }); // Analyze dependencies program .command('analyze-dependencies') .description('Analyze and validate element dependencies') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .option('--fix', 'Automatically fix invalid dependencies') .action(async (options) => { try { const dependencyManager = await import('../scripts/modules/dependency-manager.js'); await dependencyManager.analyzeDependencies(options); } catch (error) { console.error(chalk.red(`Failed to analyze dependencies: ${error.message}`)); process.exit(1); } }); // Next element program .command('next') .description('Show the next element to work on') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .action(async (options) => { try { const elementManager = await import('../scripts/modules/element-manager.js'); await elementManager.showNextElement(options.file); } catch (error) { console.error(chalk.red(`Failed to determine next element: ${error.message}`)); process.exit(1); } }); // Show element program .command('show') .description('Show details of a specific element') .argument('<id>', 'Element ID') .option('-f, --file <file>', 'Elements file path', 'elements/elements.json') .action(async (id, options) => { try { const elementManager = await import('../scripts/modules/element-manager.js'); await elementManager.showElement(id, options.file); } catch (error) { console.error(chalk.red(`Failed to show element: ${error.message}`)); process.exit(1); } }); // Initialize a new story project program .command('init') .description('Initialize a new story project') .option('-n, --name <name>', 'Project name') .option('-y, --yes', 'Skip prompts and use defaults') .action(() => { const initScript = resolve(__dirname, 'story-weaver-init.js'); // Pass arguments to the init script const args = process.argv.slice(process.argv.indexOf('init') + 1); const child = spawn('node', [initScript, ...args], { stdio: 'inherit', cwd: process.cwd() }); child.on('close', (code) => { process.exit(code); }); }); // Psychological archetypes reference program .command('archetypes') .description('Display information about Jungian archetypes') .option('--details', 'Show detailed descriptions') .option('--examples', 'Include literary examples') .action(async (options) => { try { const { displayArchetypes } = await import('../scripts/modules/jungian-references.js'); await displayArchetypes(options); } catch (error) { console.error(chalk.red(`Failed to display archetypes: ${error.message}`)); process.exit(1); } }); // Psychological symbols reference program .command('symbols') .description('Display information about symbolic psychology') .option('--details', 'Show detailed descriptions') .option('--category <category>', 'Filter by category') .action(async (options) => { try { const { displaySymbols } = await import('../scripts/modules/jungian-references.js'); await displaySymbols(options); } catch (error) { console.error(chalk.red(`Failed to display symbols: ${error.message}`)); process.exit(1); } }); // If no arguments are supplied, show help if (process.argv.length === 2) { program.help(); } // Parse the arguments program.parse(process.argv);