@redaksjon/protokoll 0.0.11 → 0.0.13
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/.cursor/rules/definition-of-done.md +1 -0
- package/.cursor/rules/no-emoticons.md +26 -12
- package/README.md +483 -69
- package/dist/agentic/executor.js +473 -41
- package/dist/agentic/executor.js.map +1 -1
- package/dist/agentic/index.js.map +1 -1
- package/dist/agentic/tools/lookup-person.js +123 -4
- package/dist/agentic/tools/lookup-person.js.map +1 -1
- package/dist/agentic/tools/lookup-project.js +139 -22
- package/dist/agentic/tools/lookup-project.js.map +1 -1
- package/dist/agentic/tools/route-note.js +5 -1
- package/dist/agentic/tools/route-note.js.map +1 -1
- package/dist/arguments.js +6 -3
- package/dist/arguments.js.map +1 -1
- package/dist/cli/action.js +704 -0
- package/dist/cli/action.js.map +1 -0
- package/dist/cli/config.js +482 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/context.js +466 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/feedback.js +858 -0
- package/dist/cli/feedback.js.map +1 -0
- package/dist/cli/index.js +103 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/install.js +572 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/transcript.js +199 -0
- package/dist/cli/transcript.js.map +1 -0
- package/dist/constants.js +12 -5
- package/dist/constants.js.map +1 -1
- package/dist/context/discovery.js +1 -1
- package/dist/context/discovery.js.map +1 -1
- package/dist/context/index.js +25 -1
- package/dist/context/index.js.map +1 -1
- package/dist/context/storage.js +57 -4
- package/dist/context/storage.js.map +1 -1
- package/dist/interactive/handler.js +310 -9
- package/dist/interactive/handler.js.map +1 -1
- package/dist/main.js +11 -1
- package/dist/main.js.map +1 -1
- package/dist/output/index.js.map +1 -1
- package/dist/output/manager.js +47 -2
- package/dist/output/manager.js.map +1 -1
- package/dist/phases/complete.js +38 -3
- package/dist/phases/complete.js.map +1 -1
- package/dist/phases/locate.js +1 -1
- package/dist/phases/locate.js.map +1 -1
- package/dist/pipeline/orchestrator.js +104 -31
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/protokoll.js +68 -2
- package/dist/protokoll.js.map +1 -1
- package/dist/reasoning/client.js +83 -0
- package/dist/reasoning/client.js.map +1 -1
- package/dist/reasoning/index.js +1 -0
- package/dist/reasoning/index.js.map +1 -1
- package/dist/routing/router.js +2 -2
- package/dist/routing/router.js.map +1 -1
- package/dist/util/media.js +1 -1
- package/dist/util/media.js.map +1 -1
- package/dist/util/metadata.js.map +1 -1
- package/dist/util/sound.js +116 -0
- package/dist/util/sound.js.map +1 -0
- package/dist/util/storage.js +3 -3
- package/dist/util/storage.js.map +1 -1
- package/docs/duplicate-question-prevention.md +117 -0
- package/docs/examples.md +152 -0
- package/docs/interactive-context-example.md +92 -0
- package/docs/package-lock.json +6 -0
- package/docs/package.json +3 -1
- package/eslint.config.mjs +1 -1
- package/guide/action.md +375 -0
- package/guide/config.md +207 -0
- package/guide/configuration.md +82 -67
- package/guide/context-commands.md +574 -0
- package/guide/context-system.md +20 -7
- package/guide/development.md +106 -4
- package/guide/feedback.md +335 -0
- package/guide/index.md +100 -4
- package/guide/interactive.md +15 -14
- package/guide/quickstart.md +21 -7
- package/guide/reasoning.md +18 -4
- package/guide/routing.md +192 -97
- package/package.json +2 -3
- package/scripts/copy-assets.mjs +47 -0
- package/scripts/coverage-priority.mjs +323 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +6 -13
- package/vitest.config.ts +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sources":["../../src/cli/install.ts"],"sourcesContent":["/**\n * Install Command\n * \n * Interactive setup wizard for first-time Protokoll configuration.\n * Guides users through model selection, directory setup, and project creation.\n */\n\nimport { Command } from 'commander';\nimport * as readline from 'readline';\nimport * as yaml from 'js-yaml';\nimport * as fs from 'fs/promises';\nimport * as path from 'node:path';\nimport { VERSION, DEFAULT_MODEL, DEFAULT_TRANSCRIPTION_MODEL } from '../constants';\n\n// Helper to print to stdout\nconst print = (text: string) => process.stdout.write(text + '\\n');\n\n// ANSI color codes for pretty output\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n magenta: '\\x1b[35m',\n};\n\nconst bold = (text: string) => `${colors.bold}${text}${colors.reset}`;\nconst dim = (text: string) => `${colors.dim}${text}${colors.reset}`;\nconst green = (text: string) => `${colors.green}${text}${colors.reset}`;\nconst yellow = (text: string) => `${colors.yellow}${text}${colors.reset}`;\nconst blue = (text: string) => `${colors.blue}${text}${colors.reset}`;\nconst cyan = (text: string) => `${colors.cyan}${text}${colors.reset}`;\nconst magenta = (text: string) => `${colors.magenta}${text}${colors.reset}`;\n\n// Helper for interactive prompts\nconst askQuestion = (rl: readline.Interface, question: string): Promise<string> => {\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n resolve(answer.trim());\n });\n });\n};\n\nconst createReadline = () => readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n});\n\n// Model information for guidance\nconst MODEL_INFO = {\n reasoning: [\n { name: 'gpt-5.2', provider: 'OpenAI', notes: 'Default - High reasoning, best quality', recommended: true },\n { name: 'gpt-5.1', provider: 'OpenAI', notes: 'High reasoning, balanced' },\n { name: 'gpt-5', provider: 'OpenAI', notes: 'Fast and capable' },\n { name: 'gpt-4o', provider: 'OpenAI', notes: 'Previous gen, still capable' },\n { name: 'gpt-4o-mini', provider: 'OpenAI', notes: 'Fast, lower cost' },\n { name: 'o1', provider: 'OpenAI', notes: 'Reasoning-focused' },\n { name: 'o1-mini', provider: 'OpenAI', notes: 'Faster reasoning' },\n { name: 'claude-3-5-sonnet', provider: 'Anthropic', notes: 'Recommended for quality' },\n { name: 'claude-3-opus', provider: 'Anthropic', notes: 'Highest capability' },\n ],\n transcription: [\n { name: 'whisper-1', notes: 'Default, reliable', recommended: true },\n { name: 'gpt-4o-transcribe', notes: 'Newer, supports prompting' },\n ],\n};\n\ninterface InstallConfig {\n model: string;\n transcriptionModel: string;\n inputDirectory: string;\n outputDirectory: string;\n processedDirectory?: string;\n useProjects: boolean;\n projects: ProjectSetup[];\n}\n\ninterface ProjectSetup {\n name: string;\n id: string;\n description?: string;\n destination?: string;\n contextType: 'work' | 'personal' | 'mixed';\n structure: 'none' | 'year' | 'month' | 'day';\n triggerPhrases: string[];\n}\n\n/**\n * Print the welcome banner\n */\nconst printWelcome = () => {\n print('');\n print('═'.repeat(60));\n print(bold(cyan(` ╔═╗┬─┐┌─┐┌┬┐┌─┐┬┌─┌─┐┬ ┬ `)));\n print(bold(cyan(` ╠═╝├┬┘│ │ │ │ │├┴┐│ ││ │ `)));\n print(bold(cyan(` ╩ ┴└─└─┘ ┴ └─┘┴ ┴└─┘┴─┘┴─┘`)));\n print('');\n print(dim(` Intelligent Audio Transcription`));\n print(dim(` Version ${VERSION}`));\n print('═'.repeat(60));\n print('');\n print(`Welcome to ${bold('Protokoll')}! This wizard will help you set up your`);\n print(`configuration for intelligent audio transcription.`);\n print('');\n};\n\n/**\n * Print the models table\n */\nconst printModelsTable = (type: 'reasoning' | 'transcription') => {\n const models = MODEL_INFO[type];\n print('');\n print(bold(`Available ${type === 'reasoning' ? 'Reasoning' : 'Transcription'} Models:`));\n print('');\n print(` ${dim('Model'.padEnd(20))} ${dim('Provider'.padEnd(12))} ${dim('Notes')}`);\n print(' ' + '─'.repeat(56));\n \n for (const model of models) {\n const marker = model.recommended ? green('★ ') : ' ';\n const provider = 'provider' in model ? (model as { provider: string }).provider : 'OpenAI';\n print(` ${marker}${model.name.padEnd(18)} ${provider.padEnd(12)} ${model.notes}`);\n }\n print('');\n if (models.some(m => m.recommended)) {\n print(` ${green('★')} = Recommended`);\n print('');\n }\n};\n\n/**\n * Ask for model selection\n */\nconst askModel = async (rl: readline.Interface): Promise<{ model: string; transcriptionModel: string }> => {\n print(bold(yellow('─── Step 1: Model Selection ───')));\n print('');\n print(`Protokoll uses two AI models:`);\n print(` 1. ${bold('Reasoning Model')}: Enhances transcripts, corrects names, routes notes`);\n print(` 2. ${bold('Transcription Model')}: Converts audio to text (Whisper)`);\n print('');\n\n // Reasoning model\n printModelsTable('reasoning');\n print(`You can use any OpenAI or Anthropic model. The default (${DEFAULT_MODEL}) provides`);\n print(`the best balance of quality and capability.`);\n print('');\n \n const modelInput = await askQuestion(rl, `Reasoning model [${DEFAULT_MODEL}]: `);\n const model = modelInput || DEFAULT_MODEL;\n print(green(` ✓ Using reasoning model: ${model}`));\n print('');\n\n // Transcription model\n printModelsTable('transcription');\n const transInput = await askQuestion(rl, `Transcription model [${DEFAULT_TRANSCRIPTION_MODEL}]: `);\n const transcriptionModel = transInput || DEFAULT_TRANSCRIPTION_MODEL;\n print(green(` ✓ Using transcription model: ${transcriptionModel}`));\n print('');\n\n return { model, transcriptionModel };\n};\n\n/**\n * Ask for directory configuration\n */\nconst askDirectories = async (rl: readline.Interface): Promise<{ inputDirectory: string; outputDirectory: string; processedDirectory?: string }> => {\n print(bold(yellow('─── Step 2: Directory Configuration ───')));\n print('');\n print(`Protokoll needs to know where your audio files are and where`);\n print(`transcripts should be saved.`);\n print('');\n\n // Input directory\n print(bold('Audio Input Directory'));\n print(dim(` Where do your audio recordings live? This is where Protokoll`));\n print(dim(` will look for files to transcribe.`));\n print('');\n const inputDir = await askQuestion(rl, `Audio input directory [./recordings]: `);\n const inputDirectory = inputDir || './recordings';\n print(green(` ✓ Will look for audio files in: ${inputDirectory}`));\n print('');\n\n // Output directory\n print(bold('Transcript Output Directory'));\n print(dim(` Where should transcribed notes be saved? This is your default`));\n print(dim(` destination (projects can override this).`));\n print('');\n const outputDir = await askQuestion(rl, `Transcript output directory [~/notes]: `);\n const outputDirectory = outputDir || '~/notes';\n print(green(` ✓ Will save transcripts to: ${outputDirectory}`));\n print('');\n\n // Processed directory\n print(bold('Processed Audio Directory'));\n print(dim(` After transcription, should audio files be moved somewhere?`));\n print(dim(` Leave blank to keep them in place, or specify a directory.`));\n print('');\n const processedDir = await askQuestion(rl, `Move processed audio to (Enter to skip): `);\n const processedDirectory = processedDir || undefined;\n if (processedDirectory) {\n print(green(` ✓ Will move processed audio to: ${processedDirectory}`));\n } else {\n print(dim(` ○ Audio files will remain in place after processing`));\n }\n print('');\n\n return { inputDirectory, outputDirectory, processedDirectory };\n};\n\n/**\n * Ask about projects/contexts\n */\nconst askAboutProjects = async (rl: readline.Interface): Promise<boolean> => {\n print(bold(yellow('─── Step 3: Projects & Contexts ───')));\n print('');\n print(`Protokoll can route transcripts to different destinations based`);\n print(`on content. This is done through ${bold('Projects')}.`);\n print('');\n\n print(bold(`What's a Project?`));\n print(` • A named context that triggers specific routing`);\n print(` • Examples: \"Work Notes\", \"Personal Journal\", \"Client Alpha\"`);\n print(` • Each project has trigger phrases that identify it`);\n print(` • Projects route notes to specific folders automatically`);\n print('');\n\n print(bold(`What's a Context?`));\n print(` • The broader category a project belongs to`);\n print(` • Three types: ${cyan('work')}, ${magenta('personal')}, or ${yellow('mixed')}`);\n print(` • Helps Protokoll understand note categorization`);\n print('');\n\n print(bold(`Examples:`));\n print(dim(` • \"Meeting with Sarah about Project Alpha\" → routes to ~/work/alpha/`));\n print(dim(` • \"Reminder to pick up groceries\" → routes to ~/personal/`));\n print(dim(` • \"Skiing trip planning\" → routes to ~/personal/trips/`));\n print('');\n\n const answer = await askQuestion(rl, `Do you want to set up projects? (Y/n): `);\n const useProjects = answer.toLowerCase() !== 'n';\n \n if (useProjects) {\n print(green(` ✓ Let's set up some projects!`));\n } else {\n print(dim(` ○ Skipping project setup (you can add them later)`));\n }\n print('');\n\n return useProjects;\n};\n\n/**\n * Interactive project creation\n */\nconst createProject = async (rl: readline.Interface, existingIds: Set<string>): Promise<ProjectSetup | null> => {\n print('');\n print(bold(blue('─── New Project ───')));\n print('');\n\n const name = await askQuestion(rl, `Project name (or Enter to finish): `);\n if (!name) {\n return null;\n }\n\n // Generate ID\n const suggestedId = name.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n let finalId = suggestedId;\n \n // Check for conflicts\n if (existingIds.has(suggestedId)) {\n const customId = await askQuestion(rl, `ID \"${suggestedId}\" exists. Enter new ID: `);\n finalId = customId.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n } else {\n const idInput = await askQuestion(rl, `ID [${suggestedId}]: `);\n if (idInput) {\n finalId = idInput.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n }\n }\n\n // Description\n const description = await askQuestion(rl, `Description (Enter to skip): `);\n\n // Context type\n print(`Context type: ${cyan('work')} | ${magenta('personal')} | ${yellow('mixed')}`);\n const ctxInput = await askQuestion(rl, `Context type [work]: `);\n const contextType = (['work', 'personal', 'mixed'].includes(ctxInput) ? ctxInput : 'work') as 'work' | 'personal' | 'mixed';\n\n // Destination\n print(dim(` Leave blank to use global default output directory`));\n const destination = await askQuestion(rl, `Output destination (Enter for default): `);\n\n // Structure\n print(`Directory structure: ${dim('none')} | ${dim('year')} | ${bold('month')} | ${dim('day')}`);\n print(dim(` none: output/transcript.md`));\n print(dim(` year: output/2026/transcript.md`));\n print(dim(` month: output/2026/01/transcript.md`));\n print(dim(` day: output/2026/01/15/transcript.md`));\n const structInput = await askQuestion(rl, `Structure [month]: `);\n const structure = (['none', 'year', 'month', 'day'].includes(structInput) ? structInput : 'month') as 'none' | 'year' | 'month' | 'day';\n\n // Trigger phrases\n print(`Trigger phrases - words/phrases that identify this project`);\n print(dim(` Examples: \"work note\", \"project alpha\", \"client meeting\"`));\n const phrasesInput = await askQuestion(rl, `Trigger phrases (comma-separated): `);\n const triggerPhrases = phrasesInput ? phrasesInput.split(',').map(s => s.trim()).filter(Boolean) : [];\n\n const project: ProjectSetup = {\n name,\n id: finalId,\n ...(description && { description }),\n ...(destination && { destination }),\n contextType,\n structure,\n triggerPhrases,\n };\n\n print('');\n print(green(` ✓ Project \"${name}\" created`));\n \n return project;\n};\n\n/**\n * Create multiple projects\n */\nconst createProjects = async (rl: readline.Interface): Promise<ProjectSetup[]> => {\n const projects: ProjectSetup[] = [];\n const existingIds = new Set<string>();\n\n print('');\n print(`Let's create your first project. You can add more after.`);\n print(dim(`Press Enter without a name when you're done adding projects.`));\n\n while (true) {\n const project = await createProject(rl, existingIds);\n if (!project) {\n break;\n }\n projects.push(project);\n existingIds.add(project.id);\n \n print('');\n print(dim(`Added ${projects.length} project(s). Add another or press Enter to continue.`));\n }\n\n return projects;\n};\n\n/**\n * Write the configuration files\n */\nconst writeConfiguration = async (config: InstallConfig): Promise<string> => {\n const configDir = '.protokoll';\n const configPath = path.join(process.cwd(), configDir);\n \n // Create directory structure\n await fs.mkdir(configPath, { recursive: true });\n await fs.mkdir(path.join(configPath, 'context', 'projects'), { recursive: true });\n await fs.mkdir(path.join(configPath, 'context', 'people'), { recursive: true });\n await fs.mkdir(path.join(configPath, 'context', 'terms'), { recursive: true });\n await fs.mkdir(path.join(configPath, 'context', 'companies'), { recursive: true });\n await fs.mkdir(path.join(configPath, 'context', 'ignored'), { recursive: true });\n\n // Build config.yaml content\n const configContent: Record<string, unknown> = {\n model: config.model,\n transcriptionModel: config.transcriptionModel,\n inputDirectory: config.inputDirectory,\n outputDirectory: config.outputDirectory,\n };\n\n if (config.processedDirectory) {\n configContent.processedDirectory = config.processedDirectory;\n }\n\n // Write config.yaml\n const configYaml = yaml.dump(configContent, { lineWidth: -1 });\n await fs.writeFile(path.join(configPath, 'config.yaml'), configYaml, 'utf-8');\n\n // Write project files\n for (const project of config.projects) {\n const projectData: Record<string, unknown> = {\n id: project.id,\n name: project.name,\n ...(project.description && { description: project.description }),\n classification: {\n context_type: project.contextType,\n explicit_phrases: project.triggerPhrases,\n },\n routing: {\n ...(project.destination && { destination: project.destination }),\n structure: project.structure,\n filename_options: ['date', 'time', 'subject'],\n },\n active: true,\n };\n\n const projectYaml = yaml.dump(projectData, { lineWidth: -1 });\n await fs.writeFile(\n path.join(configPath, 'context', 'projects', `${project.id}.yaml`),\n projectYaml,\n 'utf-8'\n );\n }\n\n return configPath;\n};\n\n/**\n * Print configuration summary\n */\nconst printSummary = (config: InstallConfig, configPath: string) => {\n print('');\n print('═'.repeat(60));\n print(bold(green(' ✓ Installation Complete!')));\n print('═'.repeat(60));\n print('');\n\n print(bold('Configuration Summary'));\n print('─'.repeat(40));\n print('');\n\n print(bold('Models:'));\n print(` Reasoning: ${cyan(config.model)}`);\n print(` Transcription: ${cyan(config.transcriptionModel)}`);\n print('');\n\n print(bold('Directories:'));\n print(` Audio Input: ${config.inputDirectory}`);\n print(` Output: ${config.outputDirectory}`);\n if (config.processedDirectory) {\n print(` Processed: ${config.processedDirectory}`);\n }\n print('');\n\n if (config.projects.length > 0) {\n print(bold(`Projects (${config.projects.length}):`));\n for (const project of config.projects) {\n print(` ${green('●')} ${project.name} (${project.id})`);\n if (project.destination) {\n print(` → ${project.destination}`);\n }\n if (project.triggerPhrases.length > 0) {\n print(` Triggers: ${dim(project.triggerPhrases.join(', '))}`);\n }\n }\n print('');\n }\n\n print(bold('Configuration saved to:'));\n print(` ${configPath}/config.yaml`);\n print('');\n};\n\n/**\n * Print getting started guide\n */\nconst printGettingStarted = (config: InstallConfig) => {\n print('═'.repeat(60));\n print(bold(' Getting Started'));\n print('═'.repeat(60));\n print('');\n\n print(bold('1. Set your API key:'));\n print(` ${dim('export OPENAI_API_KEY=\"sk-your-key\"')}`);\n print('');\n\n print(bold('2. Start transcribing:'));\n print(` ${cyan(`protokoll --input-directory ${config.inputDirectory}`)}`);\n print('');\n\n print(bold('3. Add context over time:'));\n print(` ${dim('protokoll person add')} # Add people you mention`);\n print(` ${dim('protokoll project add')} # Add new projects`);\n print(` ${dim('protokoll term add')} # Add technical terms`);\n print('');\n\n print(bold('4. Provide feedback:'));\n print(` ${dim('protokoll feedback <transcript>')} # Improve routing`);\n print('');\n\n print('═'.repeat(60));\n print(bold(' Documentation & Help'));\n print('═'.repeat(60));\n print('');\n\n print(bold('Documentation:'));\n print(` ${blue('https://github.com/redaksjon/protokoll')}`);\n print('');\n\n print(bold('Quick Guide:'));\n print(` ${dim('protokoll --help')} # All command options`);\n print(` ${dim('protokoll context status')} # View context system`);\n print(` ${dim('protokoll project list')} # List all projects`);\n print('');\n\n print(bold('Useful Commands:'));\n print(` ${dim('protokoll --batch')} # Non-interactive (for cron)`);\n print(` ${dim('protokoll --verbose')} # Detailed output`);\n print(` ${dim('protokoll --dry-run')} # Preview without saving`);\n print('');\n\n print('═'.repeat(60));\n print(`${green('Ready to go!')} Run ${cyan('protokoll --help')} for more options.`);\n print('═'.repeat(60));\n print('');\n};\n\n/**\n * Check if configuration already exists\n */\nconst checkExistingConfig = async (): Promise<boolean> => {\n const configPath = path.join(process.cwd(), '.protokoll', 'config.yaml');\n try {\n await fs.access(configPath);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Run the install wizard\n */\nconst runInstallWizard = async (): Promise<void> => {\n const rl = createReadline();\n\n try {\n // Check for existing config\n const hasExisting = await checkExistingConfig();\n \n printWelcome();\n\n if (hasExisting) {\n print(yellow('⚠ Configuration already exists at .protokoll/config.yaml'));\n print('');\n const overwrite = await askQuestion(rl, `Overwrite existing configuration? (y/N): `);\n if (overwrite.toLowerCase() !== 'y') {\n print('');\n print('Installation cancelled. Your existing configuration is unchanged.');\n print(`Run ${cyan('protokoll context status')} to view your current setup.`);\n print('');\n return;\n }\n print('');\n }\n\n // Step 1: Model selection\n const { model, transcriptionModel } = await askModel(rl);\n\n // Step 2: Directory configuration\n const { inputDirectory, outputDirectory, processedDirectory } = await askDirectories(rl);\n\n // Step 3: Projects\n const useProjects = await askAboutProjects(rl);\n \n let projects: ProjectSetup[] = [];\n if (useProjects) {\n projects = await createProjects(rl);\n }\n\n // Write configuration\n print('');\n print(dim('Writing configuration...'));\n \n const config: InstallConfig = {\n model,\n transcriptionModel,\n inputDirectory,\n outputDirectory,\n processedDirectory,\n useProjects,\n projects,\n };\n\n const configPath = await writeConfiguration(config);\n\n // Print summary and getting started guide\n printSummary(config, configPath);\n printGettingStarted(config);\n\n } finally {\n rl.close();\n }\n};\n\n/**\n * Register the install command\n */\nexport const registerInstallCommand = (program: Command): void => {\n program\n .command('install')\n .description('Interactive setup wizard for first-time configuration')\n .action(async () => {\n await runInstallWizard();\n });\n};\n\n/**\n * Check if this is an install command\n */\nexport const isInstallCommand = (): boolean => {\n const args = process.argv.slice(2);\n return args.length > 0 && args[0] === 'install';\n};\n\n/**\n * Run the install command directly\n */\nexport const runInstallCLI = async (): Promise<void> => {\n await runInstallWizard();\n};\n"],"names":["print","text","process","stdout","write","colors","reset","bold","dim","green","yellow","blue","cyan","magenta","askQuestion","rl","question","Promise","resolve","answer","trim","createReadline","readline","createInterface","input","stdin","output","MODEL_INFO","reasoning","name","provider","notes","recommended","transcription","printWelcome","repeat","VERSION","printModelsTable","type","models","padEnd","model","marker","some","m","askModel","DEFAULT_MODEL","modelInput","transInput","DEFAULT_TRANSCRIPTION_MODEL","transcriptionModel","askDirectories","inputDir","inputDirectory","outputDir","outputDirectory","processedDir","processedDirectory","undefined","askAboutProjects","useProjects","toLowerCase","createProject","existingIds","suggestedId","replace","finalId","has","customId","idInput","description","ctxInput","contextType","includes","destination","structInput","structure","phrasesInput","triggerPhrases","split","map","s","filter","Boolean","project","id","createProjects","projects","Set","push","add","length","writeConfiguration","config","configDir","configPath","path","join","cwd","fs","mkdir","recursive","configContent","configYaml","yaml","dump","lineWidth","writeFile","projectData","classification","context_type","explicit_phrases","routing","filename_options","active","projectYaml","printSummary","printGettingStarted","checkExistingConfig","access","runInstallWizard","hasExisting","overwrite","close","registerInstallCommand","program","command","action","isInstallCommand","args","argv","slice","runInstallCLI"],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the raw transcript path for a given final transcript path
|
|
6
|
+
*/ const getRawTranscriptPath = (finalPath)=>{
|
|
7
|
+
const dir = path.dirname(finalPath);
|
|
8
|
+
const basename = path.basename(finalPath, path.extname(finalPath));
|
|
9
|
+
return path.join(dir, '.transcript', `${basename}.json`);
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Read raw transcript data from the .transcript/ directory
|
|
13
|
+
*/ const readRawTranscript = async (finalPath)=>{
|
|
14
|
+
const rawPath = getRawTranscriptPath(finalPath);
|
|
15
|
+
try {
|
|
16
|
+
const content = await fs.readFile(rawPath, 'utf-8');
|
|
17
|
+
return JSON.parse(content);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Read final transcript content
|
|
27
|
+
*/ const readFinalTranscript = async (finalPath)=>{
|
|
28
|
+
try {
|
|
29
|
+
return await fs.readFile(finalPath, 'utf-8');
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Format a side-by-side comparison of raw and enhanced transcripts
|
|
39
|
+
*/ const formatComparison = (raw, enhanced, width = 80)=>{
|
|
40
|
+
const halfWidth = Math.floor(width / 2) - 2;
|
|
41
|
+
const lines = [];
|
|
42
|
+
// Header
|
|
43
|
+
lines.push('╔' + '═'.repeat(halfWidth) + '╦' + '═'.repeat(halfWidth) + '╗');
|
|
44
|
+
lines.push('║' + ' RAW WHISPER OUTPUT'.padEnd(halfWidth) + '║' + ' ENHANCED TRANSCRIPT'.padEnd(halfWidth) + '║');
|
|
45
|
+
lines.push('╠' + '═'.repeat(halfWidth) + '╬' + '═'.repeat(halfWidth) + '╣');
|
|
46
|
+
// Split into paragraphs and display
|
|
47
|
+
const rawParagraphs = raw.split('\n\n');
|
|
48
|
+
const enhancedParagraphs = enhanced.split('\n\n');
|
|
49
|
+
const maxParagraphs = Math.max(rawParagraphs.length, enhancedParagraphs.length);
|
|
50
|
+
for(let i = 0; i < maxParagraphs; i++){
|
|
51
|
+
const rawPara = rawParagraphs[i] || '';
|
|
52
|
+
const enhancedPara = enhancedParagraphs[i] || '';
|
|
53
|
+
// Word wrap each paragraph
|
|
54
|
+
const rawLines = wrapText(rawPara, halfWidth - 1);
|
|
55
|
+
const enhancedLines = wrapText(enhancedPara, halfWidth - 1);
|
|
56
|
+
const maxLines = Math.max(rawLines.length, enhancedLines.length);
|
|
57
|
+
for(let j = 0; j < maxLines; j++){
|
|
58
|
+
const rawLine = (rawLines[j] || '').padEnd(halfWidth);
|
|
59
|
+
const enhancedLine = (enhancedLines[j] || '').padEnd(halfWidth);
|
|
60
|
+
lines.push('║' + rawLine + '║' + enhancedLine + '║');
|
|
61
|
+
}
|
|
62
|
+
// Add separator between paragraphs
|
|
63
|
+
if (i < maxParagraphs - 1) {
|
|
64
|
+
lines.push('║' + '─'.repeat(halfWidth) + '║' + '─'.repeat(halfWidth) + '║');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
lines.push('╚' + '═'.repeat(halfWidth) + '╩' + '═'.repeat(halfWidth) + '╝');
|
|
68
|
+
return lines.join('\n');
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Word wrap text to a maximum width
|
|
72
|
+
*/ const wrapText = (text, maxWidth)=>{
|
|
73
|
+
const words = text.replace(/\n/g, ' ').split(' ');
|
|
74
|
+
const lines = [];
|
|
75
|
+
let currentLine = '';
|
|
76
|
+
for (const word of words){
|
|
77
|
+
if (!word) continue;
|
|
78
|
+
if (currentLine.length + word.length + 1 <= maxWidth) {
|
|
79
|
+
currentLine += (currentLine ? ' ' : '') + word;
|
|
80
|
+
} else {
|
|
81
|
+
if (currentLine) lines.push(currentLine);
|
|
82
|
+
currentLine = word.length > maxWidth ? word.slice(0, maxWidth) : word;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (currentLine) lines.push(currentLine);
|
|
86
|
+
return lines.length > 0 ? lines : [
|
|
87
|
+
''
|
|
88
|
+
];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Compare command - show raw vs enhanced side-by-side
|
|
92
|
+
*/ const compareCommand = async (transcriptPath, options)=>{
|
|
93
|
+
// Resolve the path
|
|
94
|
+
const absolutePath = path.isAbsolute(transcriptPath) ? transcriptPath : path.resolve(process.cwd(), transcriptPath);
|
|
95
|
+
// Read both transcripts
|
|
96
|
+
const rawData = await readRawTranscript(absolutePath);
|
|
97
|
+
const finalContent = await readFinalTranscript(absolutePath);
|
|
98
|
+
if (!rawData) {
|
|
99
|
+
console.error(`No raw transcript found for: ${transcriptPath}`);
|
|
100
|
+
console.error(`Expected at: ${getRawTranscriptPath(absolutePath)}`);
|
|
101
|
+
console.error('\nThe raw transcript may not have been saved during transcription.');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (!finalContent) {
|
|
106
|
+
console.error(`Final transcript not found: ${transcriptPath}`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// Show metadata about the raw transcript
|
|
111
|
+
console.log('\n📋 Raw Transcript Info:');
|
|
112
|
+
console.log(` Model: ${rawData.model}`);
|
|
113
|
+
console.log(` Duration: ${(rawData.duration / 1000).toFixed(1)}s`);
|
|
114
|
+
console.log(` Audio: ${rawData.audioFile}`);
|
|
115
|
+
console.log(` Transcribed: ${new Date(rawData.transcribedAt).toLocaleString()}`);
|
|
116
|
+
console.log(` Characters: ${rawData.text.length} (raw) → ${finalContent.length} (enhanced)`);
|
|
117
|
+
console.log('');
|
|
118
|
+
if (options.raw) {
|
|
119
|
+
// Show only raw transcript
|
|
120
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
121
|
+
console.log('RAW WHISPER OUTPUT');
|
|
122
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
123
|
+
console.log(rawData.text);
|
|
124
|
+
} else if (options.enhanced) {
|
|
125
|
+
// Show only enhanced transcript
|
|
126
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
127
|
+
console.log('ENHANCED TRANSCRIPT');
|
|
128
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
129
|
+
console.log(finalContent);
|
|
130
|
+
} else {
|
|
131
|
+
// Show side-by-side comparison
|
|
132
|
+
const termWidth = process.stdout.columns || 160;
|
|
133
|
+
const comparison = formatComparison(rawData.text, finalContent, Math.min(termWidth, 160));
|
|
134
|
+
console.log(comparison);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Info command - show info about raw transcript
|
|
139
|
+
*/ const infoCommand = async (transcriptPath)=>{
|
|
140
|
+
const absolutePath = path.isAbsolute(transcriptPath) ? transcriptPath : path.resolve(process.cwd(), transcriptPath);
|
|
141
|
+
const rawData = await readRawTranscript(absolutePath);
|
|
142
|
+
if (!rawData) {
|
|
143
|
+
console.error(`No raw transcript found for: ${transcriptPath}`);
|
|
144
|
+
console.error(`Expected at: ${getRawTranscriptPath(absolutePath)}`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
console.log('\n📋 Raw Transcript Information:');
|
|
149
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
150
|
+
console.log(` 📁 Final transcript: ${absolutePath}`);
|
|
151
|
+
console.log(` 📁 Raw transcript: ${getRawTranscriptPath(absolutePath)}`);
|
|
152
|
+
console.log('');
|
|
153
|
+
console.log(` 🎤 Audio file: ${rawData.audioFile}`);
|
|
154
|
+
console.log(` 🔑 Audio hash: ${rawData.audioHash}`);
|
|
155
|
+
console.log(` 🤖 Model: ${rawData.model}`);
|
|
156
|
+
console.log(` ⏱️ Duration: ${(rawData.duration / 1000).toFixed(1)} seconds`);
|
|
157
|
+
console.log(` 📅 Transcribed: ${new Date(rawData.transcribedAt).toLocaleString()}`);
|
|
158
|
+
console.log('');
|
|
159
|
+
console.log(` 📝 Raw text length: ${rawData.text.length} characters`);
|
|
160
|
+
console.log(` 📝 Raw word count: ~${rawData.text.split(/\s+/).length} words`);
|
|
161
|
+
console.log('═══════════════════════════════════════════════════════════════\n');
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* List command - list all transcripts with raw transcripts in a directory
|
|
165
|
+
*/ const listCommand = async (directory)=>{
|
|
166
|
+
const absoluteDir = path.isAbsolute(directory) ? directory : path.resolve(process.cwd(), directory);
|
|
167
|
+
// Find all .md files in the directory
|
|
168
|
+
const files = await fs.readdir(absoluteDir);
|
|
169
|
+
const mdFiles = files.filter((f)=>f.endsWith('.md'));
|
|
170
|
+
console.log(`\n📂 Transcripts in: ${absoluteDir}\n`);
|
|
171
|
+
let foundCount = 0;
|
|
172
|
+
let missingCount = 0;
|
|
173
|
+
for (const file of mdFiles){
|
|
174
|
+
const fullPath = path.join(absoluteDir, file);
|
|
175
|
+
const rawData = await readRawTranscript(fullPath);
|
|
176
|
+
if (rawData) {
|
|
177
|
+
foundCount++;
|
|
178
|
+
console.log(` ✅ ${file}`);
|
|
179
|
+
console.log(` Model: ${rawData.model}, Transcribed: ${new Date(rawData.transcribedAt).toLocaleDateString()}`);
|
|
180
|
+
} else {
|
|
181
|
+
missingCount++;
|
|
182
|
+
console.log(` ❌ ${file} (no raw transcript)`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log(`Found ${foundCount} with raw transcripts, ${missingCount} without.`);
|
|
187
|
+
console.log('');
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Register transcript commands with the CLI
|
|
191
|
+
*/ const registerTranscriptCommands = (program)=>{
|
|
192
|
+
const transcript = program.command('transcript').description('Work with transcripts and raw Whisper output');
|
|
193
|
+
transcript.command('compare <file>').description('Compare enhanced transcript with raw Whisper output').option('--raw', 'Show only the raw Whisper output').option('--enhanced', 'Show only the enhanced transcript').option('--diff', 'Show a unified diff (requires diff command)').action(compareCommand);
|
|
194
|
+
transcript.command('info <file>').description('Show information about a transcript\'s raw source').action(infoCommand);
|
|
195
|
+
transcript.command('list <directory>').description('List transcripts and their raw transcript status').action(listCommand);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export { compareCommand, formatComparison, getRawTranscriptPath, infoCommand, listCommand, readFinalTranscript, readRawTranscript, registerTranscriptCommands, wrapText };
|
|
199
|
+
//# sourceMappingURL=transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.js","sources":["../../src/cli/transcript.ts"],"sourcesContent":["/**\n * Transcript CLI Commands\n * \n * Commands for working with transcripts, including comparing against\n * raw Whisper output and reanalyzing.\n */\n\n/* eslint-disable no-console */\nimport { Command } from 'commander';\nimport * as fs from 'fs/promises';\nimport * as path from 'node:path';\nimport { RawTranscriptData } from '../output/types';\n\n/**\n * Get the raw transcript path for a given final transcript path\n */\nexport const getRawTranscriptPath = (finalPath: string): string => {\n const dir = path.dirname(finalPath);\n const basename = path.basename(finalPath, path.extname(finalPath));\n return path.join(dir, '.transcript', `${basename}.json`);\n};\n\n/**\n * Read raw transcript data from the .transcript/ directory\n */\nexport const readRawTranscript = async (finalPath: string): Promise<RawTranscriptData | null> => {\n const rawPath = getRawTranscriptPath(finalPath);\n try {\n const content = await fs.readFile(rawPath, 'utf-8');\n return JSON.parse(content) as RawTranscriptData;\n } catch (error: unknown) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n};\n\n/**\n * Read final transcript content\n */\nexport const readFinalTranscript = async (finalPath: string): Promise<string | null> => {\n try {\n return await fs.readFile(finalPath, 'utf-8');\n } catch (error: unknown) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n};\n\n/**\n * Format a side-by-side comparison of raw and enhanced transcripts\n */\nexport const formatComparison = (raw: string, enhanced: string, width: number = 80): string => {\n const halfWidth = Math.floor(width / 2) - 2;\n const lines: string[] = [];\n \n // Header\n lines.push('╔' + '═'.repeat(halfWidth) + '╦' + '═'.repeat(halfWidth) + '╗');\n lines.push('║' + ' RAW WHISPER OUTPUT'.padEnd(halfWidth) + '║' + ' ENHANCED TRANSCRIPT'.padEnd(halfWidth) + '║');\n lines.push('╠' + '═'.repeat(halfWidth) + '╬' + '═'.repeat(halfWidth) + '╣');\n \n // Split into paragraphs and display\n const rawParagraphs = raw.split('\\n\\n');\n const enhancedParagraphs = enhanced.split('\\n\\n');\n const maxParagraphs = Math.max(rawParagraphs.length, enhancedParagraphs.length);\n \n for (let i = 0; i < maxParagraphs; i++) {\n const rawPara = rawParagraphs[i] || '';\n const enhancedPara = enhancedParagraphs[i] || '';\n \n // Word wrap each paragraph\n const rawLines = wrapText(rawPara, halfWidth - 1);\n const enhancedLines = wrapText(enhancedPara, halfWidth - 1);\n const maxLines = Math.max(rawLines.length, enhancedLines.length);\n \n for (let j = 0; j < maxLines; j++) {\n const rawLine = (rawLines[j] || '').padEnd(halfWidth);\n const enhancedLine = (enhancedLines[j] || '').padEnd(halfWidth);\n lines.push('║' + rawLine + '║' + enhancedLine + '║');\n }\n \n // Add separator between paragraphs\n if (i < maxParagraphs - 1) {\n lines.push('║' + '─'.repeat(halfWidth) + '║' + '─'.repeat(halfWidth) + '║');\n }\n }\n \n lines.push('╚' + '═'.repeat(halfWidth) + '╩' + '═'.repeat(halfWidth) + '╝');\n \n return lines.join('\\n');\n};\n\n/**\n * Word wrap text to a maximum width\n */\nexport const wrapText = (text: string, maxWidth: number): string[] => {\n const words = text.replace(/\\n/g, ' ').split(' ');\n const lines: string[] = [];\n let currentLine = '';\n \n for (const word of words) {\n if (!word) continue;\n if (currentLine.length + word.length + 1 <= maxWidth) {\n currentLine += (currentLine ? ' ' : '') + word;\n } else {\n if (currentLine) lines.push(currentLine);\n currentLine = word.length > maxWidth ? word.slice(0, maxWidth) : word;\n }\n }\n if (currentLine) lines.push(currentLine);\n \n return lines.length > 0 ? lines : [''];\n};\n\n/**\n * Compare command - show raw vs enhanced side-by-side\n */\nexport const compareCommand = async (transcriptPath: string, options: { raw?: boolean; enhanced?: boolean; diff?: boolean }): Promise<void> => {\n // Resolve the path\n const absolutePath = path.isAbsolute(transcriptPath) \n ? transcriptPath \n : path.resolve(process.cwd(), transcriptPath);\n \n // Read both transcripts\n const rawData = await readRawTranscript(absolutePath);\n const finalContent = await readFinalTranscript(absolutePath);\n \n if (!rawData) {\n console.error(`No raw transcript found for: ${transcriptPath}`);\n console.error(`Expected at: ${getRawTranscriptPath(absolutePath)}`);\n console.error('\\nThe raw transcript may not have been saved during transcription.');\n process.exit(1);\n return;\n }\n \n if (!finalContent) {\n console.error(`Final transcript not found: ${transcriptPath}`);\n process.exit(1);\n return;\n }\n \n // Show metadata about the raw transcript\n console.log('\\n📋 Raw Transcript Info:');\n console.log(` Model: ${rawData.model}`);\n console.log(` Duration: ${(rawData.duration / 1000).toFixed(1)}s`);\n console.log(` Audio: ${rawData.audioFile}`);\n console.log(` Transcribed: ${new Date(rawData.transcribedAt).toLocaleString()}`);\n console.log(` Characters: ${rawData.text.length} (raw) → ${finalContent.length} (enhanced)`);\n console.log('');\n \n if (options.raw) {\n // Show only raw transcript\n console.log('═══════════════════════════════════════════════════════════════');\n console.log('RAW WHISPER OUTPUT');\n console.log('═══════════════════════════════════════════════════════════════');\n console.log(rawData.text);\n } else if (options.enhanced) {\n // Show only enhanced transcript \n console.log('═══════════════════════════════════════════════════════════════');\n console.log('ENHANCED TRANSCRIPT');\n console.log('═══════════════════════════════════════════════════════════════');\n console.log(finalContent);\n } else {\n // Show side-by-side comparison\n const termWidth = process.stdout.columns || 160;\n const comparison = formatComparison(rawData.text, finalContent, Math.min(termWidth, 160));\n console.log(comparison);\n }\n};\n\n/**\n * Info command - show info about raw transcript\n */\nexport const infoCommand = async (transcriptPath: string): Promise<void> => {\n const absolutePath = path.isAbsolute(transcriptPath) \n ? transcriptPath \n : path.resolve(process.cwd(), transcriptPath);\n \n const rawData = await readRawTranscript(absolutePath);\n \n if (!rawData) {\n console.error(`No raw transcript found for: ${transcriptPath}`);\n console.error(`Expected at: ${getRawTranscriptPath(absolutePath)}`);\n process.exit(1);\n return;\n }\n \n console.log('\\n📋 Raw Transcript Information:');\n console.log('═══════════════════════════════════════════════════════════════');\n console.log(` 📁 Final transcript: ${absolutePath}`);\n console.log(` 📁 Raw transcript: ${getRawTranscriptPath(absolutePath)}`);\n console.log('');\n console.log(` 🎤 Audio file: ${rawData.audioFile}`);\n console.log(` 🔑 Audio hash: ${rawData.audioHash}`);\n console.log(` 🤖 Model: ${rawData.model}`);\n console.log(` ⏱️ Duration: ${(rawData.duration / 1000).toFixed(1)} seconds`);\n console.log(` 📅 Transcribed: ${new Date(rawData.transcribedAt).toLocaleString()}`);\n console.log('');\n console.log(` 📝 Raw text length: ${rawData.text.length} characters`);\n console.log(` 📝 Raw word count: ~${rawData.text.split(/\\s+/).length} words`);\n console.log('═══════════════════════════════════════════════════════════════\\n');\n};\n\n/**\n * List command - list all transcripts with raw transcripts in a directory\n */\nexport const listCommand = async (directory: string): Promise<void> => {\n const absoluteDir = path.isAbsolute(directory) \n ? directory \n : path.resolve(process.cwd(), directory);\n \n // Find all .md files in the directory\n const files = await fs.readdir(absoluteDir);\n const mdFiles = files.filter(f => f.endsWith('.md'));\n \n console.log(`\\n📂 Transcripts in: ${absoluteDir}\\n`);\n \n let foundCount = 0;\n let missingCount = 0;\n \n for (const file of mdFiles) {\n const fullPath = path.join(absoluteDir, file);\n const rawData = await readRawTranscript(fullPath);\n \n if (rawData) {\n foundCount++;\n console.log(` ✅ ${file}`);\n console.log(` Model: ${rawData.model}, Transcribed: ${new Date(rawData.transcribedAt).toLocaleDateString()}`);\n } else {\n missingCount++;\n console.log(` ❌ ${file} (no raw transcript)`);\n }\n }\n \n console.log('');\n console.log(`Found ${foundCount} with raw transcripts, ${missingCount} without.`);\n console.log('');\n};\n\n/**\n * Register transcript commands with the CLI\n */\nexport const registerTranscriptCommands = (program: Command): void => {\n const transcript = program\n .command('transcript')\n .description('Work with transcripts and raw Whisper output');\n \n transcript\n .command('compare <file>')\n .description('Compare enhanced transcript with raw Whisper output')\n .option('--raw', 'Show only the raw Whisper output')\n .option('--enhanced', 'Show only the enhanced transcript')\n .option('--diff', 'Show a unified diff (requires diff command)')\n .action(compareCommand);\n \n transcript\n .command('info <file>')\n .description('Show information about a transcript\\'s raw source')\n .action(infoCommand);\n \n transcript\n .command('list <directory>')\n .description('List transcripts and their raw transcript status')\n .action(listCommand);\n};\n"],"names":["getRawTranscriptPath","finalPath","dir","path","dirname","basename","extname","join","readRawTranscript","rawPath","content","fs","readFile","JSON","parse","error","code","readFinalTranscript","formatComparison","raw","enhanced","width","halfWidth","Math","floor","lines","push","repeat","padEnd","rawParagraphs","split","enhancedParagraphs","maxParagraphs","max","length","i","rawPara","enhancedPara","rawLines","wrapText","enhancedLines","maxLines","j","rawLine","enhancedLine","text","maxWidth","words","replace","currentLine","word","slice","compareCommand","transcriptPath","options","absolutePath","isAbsolute","resolve","process","cwd","rawData","finalContent","console","exit","log","model","duration","toFixed","audioFile","Date","transcribedAt","toLocaleString","termWidth","stdout","columns","comparison","min","infoCommand","audioHash","listCommand","directory","absoluteDir","files","readdir","mdFiles","filter","f","endsWith","foundCount","missingCount","file","fullPath","toLocaleDateString","registerTranscriptCommands","program","transcript","command","description","option","action"],"mappings":"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"}
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import os__default from 'os';
|
|
1
|
+
import os__default from 'node:os';
|
|
2
2
|
|
|
3
|
-
const VERSION = '0.0.
|
|
3
|
+
const VERSION = '0.0.13 (HEAD/aaf168e T:v0.0.13 2026-01-16 04:58:42 -0800) linux x64 v24.12.0';
|
|
4
4
|
const PROGRAM_NAME = 'protokoll';
|
|
5
5
|
const DEFAULT_DIFF = true;
|
|
6
6
|
const DEFAULT_LOG = false;
|
|
@@ -50,16 +50,21 @@ const ALLOWED_OUTPUT_FILENAME_OPTIONS = [
|
|
|
50
50
|
'subject'
|
|
51
51
|
];
|
|
52
52
|
const DEFAULT_CONFIG_DIR = `./.${PROGRAM_NAME}`;
|
|
53
|
+
// Context System Constants
|
|
54
|
+
const DEFAULT_CONTEXT_DIR_NAME = '.protokoll';
|
|
55
|
+
const DEFAULT_CONTEXT_CONFIG_FILE_NAME = 'config.yaml';
|
|
53
56
|
// Note: We no longer maintain a static allowlist of models
|
|
54
57
|
// This allows for dynamic model discovery and future model additions
|
|
55
58
|
// Users can specify any model supported by their OpenAI API
|
|
56
59
|
const DEFAULT_TRANSCRIPTION_MODEL = 'whisper-1';
|
|
57
60
|
const DEFAULT_MODEL = 'gpt-5.2';
|
|
61
|
+
const DEFAULT_REASONING_LEVEL = 'medium';
|
|
58
62
|
const DEFAULT_OVERRIDES = false;
|
|
59
63
|
const DEFAULT_MAX_AUDIO_SIZE = 26214400; // 25MB in bytes
|
|
60
64
|
const DEFAULT_TEMP_DIRECTORY = os__default.tmpdir(); // Use OS default temp directory
|
|
61
|
-
const DEFAULT_INTERACTIVE =
|
|
65
|
+
const DEFAULT_INTERACTIVE = true; // Interactive prompts enabled by default
|
|
62
66
|
const DEFAULT_SELF_REFLECTION = true;
|
|
67
|
+
const DEFAULT_SILENT = false; // Sound notifications enabled by default
|
|
63
68
|
// Output Management Constants
|
|
64
69
|
const DEFAULT_INTERMEDIATE_DIRECTORY = './output/protokoll';
|
|
65
70
|
// Define Protokoll-specific defaults
|
|
@@ -71,14 +76,16 @@ const PROTOKOLL_DEFAULTS = {
|
|
|
71
76
|
log: DEFAULT_LOG,
|
|
72
77
|
transcriptionModel: DEFAULT_TRANSCRIPTION_MODEL,
|
|
73
78
|
model: DEFAULT_MODEL,
|
|
79
|
+
reasoningLevel: DEFAULT_REASONING_LEVEL,
|
|
74
80
|
contentTypes: DEFAULT_CONTENT_TYPES,
|
|
75
81
|
overrides: DEFAULT_OVERRIDES,
|
|
76
82
|
maxAudioSize: DEFAULT_MAX_AUDIO_SIZE,
|
|
77
83
|
tempDirectory: DEFAULT_TEMP_DIRECTORY || os__default.tmpdir(),
|
|
78
84
|
configDirectory: DEFAULT_CONFIG_DIR,
|
|
79
85
|
interactive: DEFAULT_INTERACTIVE,
|
|
80
|
-
selfReflection: DEFAULT_SELF_REFLECTION
|
|
86
|
+
selfReflection: DEFAULT_SELF_REFLECTION,
|
|
87
|
+
silent: DEFAULT_SILENT
|
|
81
88
|
};
|
|
82
89
|
|
|
83
|
-
export { ALLOWED_AUDIO_EXTENSIONS, ALLOWED_OUTPUT_FILENAME_OPTIONS, ALLOWED_OUTPUT_STRUCTURES, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS, DEFAULT_AUDIO_EXTENSIONS, DEFAULT_CONFIG_DIR, DEFAULT_CONTENT_TYPES, DEFAULT_DEBUG, DEFAULT_DIFF, DEFAULT_DRY_RUN, DEFAULT_INPUT_DIRECTORY, DEFAULT_INTERACTIVE, DEFAULT_INTERMEDIATE_DIRECTORY, DEFAULT_LOG, DEFAULT_MAX_AUDIO_SIZE, DEFAULT_MODEL, DEFAULT_OUTPUT_DIRECTORY, DEFAULT_OUTPUT_FILENAME_OPTIONS, DEFAULT_OUTPUT_STRUCTURE, DEFAULT_OVERRIDES, DEFAULT_SELF_REFLECTION, DEFAULT_TEMP_DIRECTORY, DEFAULT_TIMEZONE, DEFAULT_TRANSCRIPTION_MODEL, DEFAULT_VERBOSE, PROGRAM_NAME, PROTOKOLL_DEFAULTS, VERSION };
|
|
90
|
+
export { ALLOWED_AUDIO_EXTENSIONS, ALLOWED_OUTPUT_FILENAME_OPTIONS, ALLOWED_OUTPUT_STRUCTURES, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS, DEFAULT_AUDIO_EXTENSIONS, DEFAULT_CONFIG_DIR, DEFAULT_CONTENT_TYPES, DEFAULT_CONTEXT_CONFIG_FILE_NAME, DEFAULT_CONTEXT_DIR_NAME, DEFAULT_DEBUG, DEFAULT_DIFF, DEFAULT_DRY_RUN, DEFAULT_INPUT_DIRECTORY, DEFAULT_INTERACTIVE, DEFAULT_INTERMEDIATE_DIRECTORY, DEFAULT_LOG, DEFAULT_MAX_AUDIO_SIZE, DEFAULT_MODEL, DEFAULT_OUTPUT_DIRECTORY, DEFAULT_OUTPUT_FILENAME_OPTIONS, DEFAULT_OUTPUT_STRUCTURE, DEFAULT_OVERRIDES, DEFAULT_REASONING_LEVEL, DEFAULT_SELF_REFLECTION, DEFAULT_SILENT, DEFAULT_TEMP_DIRECTORY, DEFAULT_TIMEZONE, DEFAULT_TRANSCRIPTION_MODEL, DEFAULT_VERBOSE, PROGRAM_NAME, PROTOKOLL_DEFAULTS, VERSION };
|
|
84
91
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import os from 'os';\nimport { FilenameOption } from '@theunwalked/dreadcabinet';\nimport { FilesystemStructure } from '@theunwalked/dreadcabinet';\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'protokoll';\nexport const DEFAULT_CHARACTER_ENCODING = 'utf-8';\nexport const DEFAULT_BINARY_TO_TEXT_ENCODING = 'base64';\nexport const DEFAULT_DIFF = true;\nexport const DEFAULT_LOG = false;\nexport const DEFAULT_TIMEZONE = 'Etc/UTC';\nexport const DATE_FORMAT_MONTH_DAY = 'M-D';\nexport const DATE_FORMAT_YEAR = 'YYYY';\nexport const DATE_FORMAT_YEAR_MONTH = 'YYYY-M';\nexport const DATE_FORMAT_YEAR_MONTH_DAY = 'YYYY-M-D';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_SLASH = 'YYYY/M/D';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES = 'YYYY-M-D-HHmm';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS = 'YYYY-M-D-HHmmss';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS = 'YYYY-M-D-HHmmss.SSS';\nexport const DATE_FORMAT_MONTH = 'M';\nexport const DATE_FORMAT_DAY = 'D';\nexport const DATE_FORMAT_HOURS = 'HHmm';\nexport const DATE_FORMAT_MINUTES = 'mm';\nexport const DATE_FORMAT_SECONDS = 'ss';\nexport const DATE_FORMAT_MILLISECONDS = 'SSS';\nexport const DEFAULT_VERBOSE = false;\nexport const DEFAULT_DRY_RUN = false;\nexport const DEFAULT_DEBUG = false;\nexport const DEFAULT_CONTENT_TYPES = ['diff'];\nexport const DEFAULT_RECURSIVE = false;\nexport const DEFAULT_INPUT_DIRECTORY = './';\nexport const DEFAULT_OUTPUT_DIRECTORY = './';\n\nexport const DEFAULT_AUDIO_EXTENSIONS = ['mp3', 'mp4', 'mpeg', 'mpga', 'm4a', 'wav', 'webm'];\n\nexport const ALLOWED_CONTENT_TYPES = ['log', 'diff'];\nexport const ALLOWED_AUDIO_EXTENSIONS = ['mp3', 'mp4', 'mpeg', 'mpga', 'm4a', 'wav', 'webm'];\n\nexport const DEFAULT_OUTPUT_STRUCTURE = 'month' as FilesystemStructure;\nexport const DEFAULT_OUTPUT_FILENAME_OPTIONS = ['date', 'time', 'subject'] as FilenameOption[];\n\nexport const ALLOWED_OUTPUT_STRUCTURES = ['none', 'year', 'month', 'day'] as FilesystemStructure[];\nexport const ALLOWED_OUTPUT_FILENAME_OPTIONS = ['date', 'time', 'subject'] as FilenameOption[];\n\nexport const DEFAULT_CONFIG_DIR = `./.${PROGRAM_NAME}`;\nexport const DEFAULT_PROCESSED_DIR = './processed';\n\n// Context System Constants\nexport const DEFAULT_CONTEXT_DIR_NAME = '.protokoll';\nexport const DEFAULT_CONTEXT_CONFIG_FILE_NAME = 'config.yaml';\nexport const DEFAULT_MAX_DISCOVERY_LEVELS = 10;\n\nexport const CONTEXT_SUBDIRECTORIES = {\n people: 'people',\n projects: 'projects',\n companies: 'companies',\n terms: 'terms',\n} as const;\n\nexport const DEFAULT_PERSONAS_DIR = `/personas`;\n\nexport const DEFAULT_PERSONA_TRANSCRIBER_FILE = `${DEFAULT_PERSONAS_DIR}/transcriber.md`;\n\nexport const DEFAULT_INSTRUCTIONS_DIR = `/instructions`;\n\nexport const DEFAULT_INSTRUCTIONS_TRANSCRIBE_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/transcribe.md`;\n\n// Note: We no longer maintain a static allowlist of models\n// This allows for dynamic model discovery and future model additions\n// Users can specify any model supported by their OpenAI API\n\nexport const DEFAULT_TRANSCRIPTION_MODEL = 'whisper-1';\nexport const DEFAULT_MODEL = 'gpt-5.2';\nexport const DEFAULT_REASONING_LEVEL = 'medium';\n\nexport const DEFAULT_OVERRIDES = false;\nexport const DEFAULT_MAX_AUDIO_SIZE = 26214400; // 25MB in bytes\nexport const DEFAULT_TEMP_DIRECTORY = os.tmpdir(); // Use OS default temp directory\nexport const DEFAULT_INTERACTIVE =
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import os from 'node:os';\nimport { FilenameOption } from '@theunwalked/dreadcabinet';\nimport { FilesystemStructure } from '@theunwalked/dreadcabinet';\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'protokoll';\nexport const DEFAULT_CHARACTER_ENCODING = 'utf-8';\nexport const DEFAULT_BINARY_TO_TEXT_ENCODING = 'base64';\nexport const DEFAULT_DIFF = true;\nexport const DEFAULT_LOG = false;\nexport const DEFAULT_TIMEZONE = 'Etc/UTC';\nexport const DATE_FORMAT_MONTH_DAY = 'M-D';\nexport const DATE_FORMAT_YEAR = 'YYYY';\nexport const DATE_FORMAT_YEAR_MONTH = 'YYYY-M';\nexport const DATE_FORMAT_YEAR_MONTH_DAY = 'YYYY-M-D';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_SLASH = 'YYYY/M/D';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES = 'YYYY-M-D-HHmm';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS = 'YYYY-M-D-HHmmss';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS = 'YYYY-M-D-HHmmss.SSS';\nexport const DATE_FORMAT_MONTH = 'M';\nexport const DATE_FORMAT_DAY = 'D';\nexport const DATE_FORMAT_HOURS = 'HHmm';\nexport const DATE_FORMAT_MINUTES = 'mm';\nexport const DATE_FORMAT_SECONDS = 'ss';\nexport const DATE_FORMAT_MILLISECONDS = 'SSS';\nexport const DEFAULT_VERBOSE = false;\nexport const DEFAULT_DRY_RUN = false;\nexport const DEFAULT_DEBUG = false;\nexport const DEFAULT_CONTENT_TYPES = ['diff'];\nexport const DEFAULT_RECURSIVE = false;\nexport const DEFAULT_INPUT_DIRECTORY = './';\nexport const DEFAULT_OUTPUT_DIRECTORY = './';\n\nexport const DEFAULT_AUDIO_EXTENSIONS = ['mp3', 'mp4', 'mpeg', 'mpga', 'm4a', 'wav', 'webm'];\n\nexport const ALLOWED_CONTENT_TYPES = ['log', 'diff'];\nexport const ALLOWED_AUDIO_EXTENSIONS = ['mp3', 'mp4', 'mpeg', 'mpga', 'm4a', 'wav', 'webm'];\n\nexport const DEFAULT_OUTPUT_STRUCTURE = 'month' as FilesystemStructure;\nexport const DEFAULT_OUTPUT_FILENAME_OPTIONS = ['date', 'time', 'subject'] as FilenameOption[];\n\nexport const ALLOWED_OUTPUT_STRUCTURES = ['none', 'year', 'month', 'day'] as FilesystemStructure[];\nexport const ALLOWED_OUTPUT_FILENAME_OPTIONS = ['date', 'time', 'subject'] as FilenameOption[];\n\nexport const DEFAULT_CONFIG_DIR = `./.${PROGRAM_NAME}`;\nexport const DEFAULT_PROCESSED_DIR = './processed';\n\n// Context System Constants\nexport const DEFAULT_CONTEXT_DIR_NAME = '.protokoll';\nexport const DEFAULT_CONTEXT_CONFIG_FILE_NAME = 'config.yaml';\nexport const DEFAULT_MAX_DISCOVERY_LEVELS = 10;\n\nexport const CONTEXT_SUBDIRECTORIES = {\n people: 'people',\n projects: 'projects',\n companies: 'companies',\n terms: 'terms',\n} as const;\n\nexport const DEFAULT_PERSONAS_DIR = `/personas`;\n\nexport const DEFAULT_PERSONA_TRANSCRIBER_FILE = `${DEFAULT_PERSONAS_DIR}/transcriber.md`;\n\nexport const DEFAULT_INSTRUCTIONS_DIR = `/instructions`;\n\nexport const DEFAULT_INSTRUCTIONS_TRANSCRIBE_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/transcribe.md`;\n\n// Note: We no longer maintain a static allowlist of models\n// This allows for dynamic model discovery and future model additions\n// Users can specify any model supported by their OpenAI API\n\nexport const DEFAULT_TRANSCRIPTION_MODEL = 'whisper-1';\nexport const DEFAULT_MODEL = 'gpt-5.2';\nexport const DEFAULT_REASONING_LEVEL = 'medium';\n\nexport const DEFAULT_OVERRIDES = false;\nexport const DEFAULT_MAX_AUDIO_SIZE = 26214400; // 25MB in bytes\nexport const DEFAULT_TEMP_DIRECTORY = os.tmpdir(); // Use OS default temp directory\nexport const DEFAULT_INTERACTIVE = true; // Interactive prompts enabled by default\nexport const DEFAULT_SELF_REFLECTION = true;\nexport const DEFAULT_SILENT = false; // Sound notifications enabled by default\n\n// Output Management Constants\nexport const DEFAULT_INTERMEDIATE_DIRECTORY = './output/protokoll';\nexport const DEFAULT_KEEP_INTERMEDIATES = true;\nexport const OUTPUT_FILE_TYPES = [\n 'transcript',\n 'context',\n 'request',\n 'response',\n 'reflection',\n 'session',\n] as const;\n\n// Define Protokoll-specific defaults\nexport const PROTOKOLL_DEFAULTS = {\n dryRun: DEFAULT_DRY_RUN,\n verbose: DEFAULT_VERBOSE,\n debug: DEFAULT_DEBUG,\n diff: DEFAULT_DIFF,\n log: DEFAULT_LOG,\n transcriptionModel: DEFAULT_TRANSCRIPTION_MODEL,\n model: DEFAULT_MODEL,\n reasoningLevel: DEFAULT_REASONING_LEVEL,\n contentTypes: DEFAULT_CONTENT_TYPES,\n overrides: DEFAULT_OVERRIDES,\n maxAudioSize: DEFAULT_MAX_AUDIO_SIZE,\n tempDirectory: DEFAULT_TEMP_DIRECTORY || os.tmpdir(),\n configDirectory: DEFAULT_CONFIG_DIR,\n interactive: DEFAULT_INTERACTIVE,\n selfReflection: DEFAULT_SELF_REFLECTION,\n silent: DEFAULT_SILENT,\n};\n"],"names":["VERSION","PROGRAM_NAME","DEFAULT_DIFF","DEFAULT_LOG","DEFAULT_TIMEZONE","DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS","DEFAULT_VERBOSE","DEFAULT_DRY_RUN","DEFAULT_DEBUG","DEFAULT_CONTENT_TYPES","DEFAULT_INPUT_DIRECTORY","DEFAULT_OUTPUT_DIRECTORY","DEFAULT_AUDIO_EXTENSIONS","ALLOWED_AUDIO_EXTENSIONS","DEFAULT_OUTPUT_STRUCTURE","DEFAULT_OUTPUT_FILENAME_OPTIONS","ALLOWED_OUTPUT_STRUCTURES","ALLOWED_OUTPUT_FILENAME_OPTIONS","DEFAULT_CONFIG_DIR","DEFAULT_CONTEXT_DIR_NAME","DEFAULT_CONTEXT_CONFIG_FILE_NAME","DEFAULT_TRANSCRIPTION_MODEL","DEFAULT_MODEL","DEFAULT_REASONING_LEVEL","DEFAULT_OVERRIDES","DEFAULT_MAX_AUDIO_SIZE","DEFAULT_TEMP_DIRECTORY","os","tmpdir","DEFAULT_INTERACTIVE","DEFAULT_SELF_REFLECTION","DEFAULT_SILENT","DEFAULT_INTERMEDIATE_DIRECTORY","PROTOKOLL_DEFAULTS","dryRun","verbose","debug","diff","log","transcriptionModel","model","reasoningLevel","contentTypes","overrides","maxAudioSize","tempDirectory","configDirectory","interactive","selfReflection","silent"],"mappings":";;AAIO,MAAMA,UAAU;AAChB,MAAMC,eAAe;AAGrB,MAAMC,eAAe;AACrB,MAAMC,cAAc;AACpB,MAAMC,mBAAmB;AAOzB,MAAMC,mDAAmD;AAQzD,MAAMC,kBAAkB;AACxB,MAAMC,kBAAkB;AACxB,MAAMC,gBAAgB;MAChBC,qBAAAA,GAAwB;AAAC,IAAA;;AAE/B,MAAMC,0BAA0B;AAChC,MAAMC,2BAA2B;MAE3BC,wBAAAA,GAA2B;AAAC,IAAA,KAAA;AAAO,IAAA,KAAA;AAAO,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,KAAA;AAAO,IAAA;;MAGxEC,wBAAAA,GAA2B;AAAC,IAAA,KAAA;AAAO,IAAA,KAAA;AAAO,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,KAAA;AAAO,IAAA;;AAE9E,MAAMC,2BAA2B;MAC3BC,+BAAAA,GAAkC;AAAC,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA;;MAEnDC,yBAAAA,GAA4B;AAAC,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA;;MACtDC,+BAAAA,GAAkC;AAAC,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA;;MAEnDC,kBAAAA,GAAqB,CAAC,GAAG,EAAEjB;AAGxC;AACO,MAAMkB,2BAA2B;AACjC,MAAMC,mCAAmC;AAkBhD;AACA;AACA;AAEO,MAAMC,8BAA8B;AACpC,MAAMC,gBAAgB;AACtB,MAAMC,0BAA0B;AAEhC,MAAMC,oBAAoB;AAC1B,MAAMC,sBAAAA,GAAyB,SAAS;MAClCC,sBAAAA,GAAyBC,WAAAA,CAAGC,MAAM,GAAG;AAC3C,MAAMC,mBAAAA,GAAsB,KAAK;AACjC,MAAMC,0BAA0B;AAChC,MAAMC,cAAAA,GAAiB,MAAM;AAEpC;AACO,MAAMC,iCAAiC;AAW9C;MACaC,kBAAAA,GAAqB;IAC9BC,MAAAA,EAAQ3B,eAAAA;IACR4B,OAAAA,EAAS7B,eAAAA;IACT8B,KAAAA,EAAO5B,aAAAA;IACP6B,IAAAA,EAAMnC,YAAAA;IACNoC,GAAAA,EAAKnC,WAAAA;IACLoC,kBAAAA,EAAoBlB,2BAAAA;IACpBmB,KAAAA,EAAOlB,aAAAA;IACPmB,cAAAA,EAAgBlB,uBAAAA;IAChBmB,YAAAA,EAAcjC,qBAAAA;IACdkC,SAAAA,EAAWnB,iBAAAA;IACXoB,YAAAA,EAAcnB,sBAAAA;IACdoB,aAAAA,EAAenB,sBAAAA,IAA0BC,YAAGC,MAAM,EAAA;IAClDkB,eAAAA,EAAiB5B,kBAAAA;IACjB6B,WAAAA,EAAalB,mBAAAA;IACbmB,cAAAA,EAAgBlB,uBAAAA;IAChBmB,MAAAA,EAAQlB;AACZ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sources":["../../src/context/discovery.ts"],"sourcesContent":["/**\n * Hierarchical Configuration Discovery\n * \n * Follows Cardigantime pattern: walks up directory tree finding .protokoll/\n * directories. Merges config with local taking precedence.\n * \n * Example:\n * /home/user/projects/work/projectA/ <- CWD\n * └── .protokoll/config.yaml <- Highest precedence\n * /home/user/projects/work/\n * └── .protokoll/config.yaml <- Work context\n * /home/user/\n * └── .protokoll/config.yaml <- User defaults\n * \n * Design Note: This module is designed to be self-contained and may be\n * extracted for use in other tools (kronologi, observasjon) in the future.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport * as yaml from 'js-yaml';\nimport { ContextDiscoveryOptions, DiscoveredContextDir, HierarchicalContextResult } from './types';\n\n/**\n * Discover configuration directories by walking up the directory tree\n */\nexport const discoverConfigDirectories = async (\n options: ContextDiscoveryOptions\n): Promise<DiscoveredContextDir[]> => {\n const {\n configDirName,\n maxLevels = 10,\n startingDir = process.cwd(),\n } = options;\n\n const discovered: DiscoveredContextDir[] = [];\n let currentDir = path.resolve(startingDir);\n let level = 0;\n const visited = new Set<string>();\n\n while (level < maxLevels) {\n const realPath = path.resolve(currentDir);\n if (visited.has(realPath)) break;\n visited.add(realPath);\n\n const configDirPath = path.join(currentDir, configDirName);\n \n try {\n const stat = await fs.stat(configDirPath);\n if (stat.isDirectory()) {\n discovered.push({ path: configDirPath, level });\n }\n } catch {\n // Directory doesn't exist, continue searching\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n \n currentDir = parentDir;\n level++;\n }\n\n return discovered;\n};\n\n/**\n * Load and merge hierarchical configuration\n */\nexport const loadHierarchicalConfig = async (\n options: ContextDiscoveryOptions\n): Promise<HierarchicalContextResult> => {\n const discoveredDirs = await discoverConfigDirectories(options);\n \n if (discoveredDirs.length === 0) {\n return {\n config: {},\n discoveredDirs: [],\n contextDirs: [],\n };\n }\n\n // Sort by level descending (lowest precedence first)\n const sortedDirs = [...discoveredDirs].sort((a, b) => b.level - a.level);\n \n const configs: Record<string, unknown>[] = [];\n const contextDirs: string[] = [];\n \n for (const dir of sortedDirs) {\n const configPath = path.join(dir.path, options.configFileName);\n \n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const parsed = yaml.load(content);\n if (parsed && typeof parsed === 'object') {\n configs.push(parsed as Record<string, unknown>);\n }\n } catch {\n // No config file in this directory\n }\n \n // Add context directory\n const contextDir = path.join(dir.path, 'context');\n try {\n const stat = await fs.stat(contextDir);\n if (stat.isDirectory()) {\n contextDirs.push(contextDir);\n }\n } catch {\n // No context subdirectory\n }\n }\n\n // Merge configs (later entries override earlier)\n const mergedConfig = configs.reduce(\n (acc, curr) => deepMerge(acc, curr), \n {} as Record<string, unknown>\n );\n\n return {\n config: mergedConfig,\n discoveredDirs,\n contextDirs,\n };\n};\n\n/**\n * Deep merge utility (similar to Cardigantime's implementation)\n */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, source: T): T {\n if (source === null || source === undefined) return target;\n if (target === null || target === undefined) return source;\n \n if (typeof source !== 'object' || typeof target !== 'object') {\n return source;\n }\n \n if (Array.isArray(source)) {\n return [...source] as unknown as T;\n }\n \n const result = { ...target } as Record<string, unknown>;\n \n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const targetVal = result[key];\n const sourceVal = source[key];\n \n if (\n typeof targetVal === 'object' && \n typeof sourceVal === 'object' &&\n targetVal !== null &&\n sourceVal !== null &&\n !Array.isArray(targetVal) && \n !Array.isArray(sourceVal)\n ) {\n result[key] = deepMerge(\n targetVal as Record<string, unknown>, \n sourceVal as Record<string, unknown>\n );\n } else {\n result[key] = sourceVal;\n }\n }\n }\n \n return result as T;\n}\n\n"],"names":["discoverConfigDirectories","options","configDirName","maxLevels","startingDir","process","cwd","discovered","currentDir","path","resolve","level","visited","Set","realPath","has","add","configDirPath","join","stat","fs","isDirectory","push","parentDir","dirname","loadHierarchicalConfig","discoveredDirs","length","config","contextDirs","sortedDirs","sort","a","b","configs","dir","configPath","configFileName","content","readFile","parsed","yaml","load","contextDir","mergedConfig","reduce","acc","curr","deepMerge","target","source","undefined","Array","isArray","result","key","Object","prototype","hasOwnProperty","call","targetVal","sourceVal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"discovery.js","sources":["../../src/context/discovery.ts"],"sourcesContent":["/**\n * Hierarchical Configuration Discovery\n * \n * Follows Cardigantime pattern: walks up directory tree finding .protokoll/\n * directories. Merges config with local taking precedence.\n * \n * Example:\n * /home/user/projects/work/projectA/ <- CWD\n * └── .protokoll/config.yaml <- Highest precedence\n * /home/user/projects/work/\n * └── .protokoll/config.yaml <- Work context\n * /home/user/\n * └── .protokoll/config.yaml <- User defaults\n * \n * Design Note: This module is designed to be self-contained and may be\n * extracted for use in other tools (kronologi, observasjon) in the future.\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'fs/promises';\nimport * as yaml from 'js-yaml';\nimport { ContextDiscoveryOptions, DiscoveredContextDir, HierarchicalContextResult } from './types';\n\n/**\n * Discover configuration directories by walking up the directory tree\n */\nexport const discoverConfigDirectories = async (\n options: ContextDiscoveryOptions\n): Promise<DiscoveredContextDir[]> => {\n const {\n configDirName,\n maxLevels = 10,\n startingDir = process.cwd(),\n } = options;\n\n const discovered: DiscoveredContextDir[] = [];\n let currentDir = path.resolve(startingDir);\n let level = 0;\n const visited = new Set<string>();\n\n while (level < maxLevels) {\n const realPath = path.resolve(currentDir);\n if (visited.has(realPath)) break;\n visited.add(realPath);\n\n const configDirPath = path.join(currentDir, configDirName);\n \n try {\n const stat = await fs.stat(configDirPath);\n if (stat.isDirectory()) {\n discovered.push({ path: configDirPath, level });\n }\n } catch {\n // Directory doesn't exist, continue searching\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n \n currentDir = parentDir;\n level++;\n }\n\n return discovered;\n};\n\n/**\n * Load and merge hierarchical configuration\n */\nexport const loadHierarchicalConfig = async (\n options: ContextDiscoveryOptions\n): Promise<HierarchicalContextResult> => {\n const discoveredDirs = await discoverConfigDirectories(options);\n \n if (discoveredDirs.length === 0) {\n return {\n config: {},\n discoveredDirs: [],\n contextDirs: [],\n };\n }\n\n // Sort by level descending (lowest precedence first)\n const sortedDirs = [...discoveredDirs].sort((a, b) => b.level - a.level);\n \n const configs: Record<string, unknown>[] = [];\n const contextDirs: string[] = [];\n \n for (const dir of sortedDirs) {\n const configPath = path.join(dir.path, options.configFileName);\n \n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const parsed = yaml.load(content);\n if (parsed && typeof parsed === 'object') {\n configs.push(parsed as Record<string, unknown>);\n }\n } catch {\n // No config file in this directory\n }\n \n // Add context directory\n const contextDir = path.join(dir.path, 'context');\n try {\n const stat = await fs.stat(contextDir);\n if (stat.isDirectory()) {\n contextDirs.push(contextDir);\n }\n } catch {\n // No context subdirectory\n }\n }\n\n // Merge configs (later entries override earlier)\n const mergedConfig = configs.reduce(\n (acc, curr) => deepMerge(acc, curr), \n {} as Record<string, unknown>\n );\n\n return {\n config: mergedConfig,\n discoveredDirs,\n contextDirs,\n };\n};\n\n/**\n * Deep merge utility (similar to Cardigantime's implementation)\n */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, source: T): T {\n if (source === null || source === undefined) return target;\n if (target === null || target === undefined) return source;\n \n if (typeof source !== 'object' || typeof target !== 'object') {\n return source;\n }\n \n if (Array.isArray(source)) {\n return [...source] as unknown as T;\n }\n \n const result = { ...target } as Record<string, unknown>;\n \n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const targetVal = result[key];\n const sourceVal = source[key];\n \n if (\n typeof targetVal === 'object' && \n typeof sourceVal === 'object' &&\n targetVal !== null &&\n sourceVal !== null &&\n !Array.isArray(targetVal) && \n !Array.isArray(sourceVal)\n ) {\n result[key] = deepMerge(\n targetVal as Record<string, unknown>, \n sourceVal as Record<string, unknown>\n );\n } else {\n result[key] = sourceVal;\n }\n }\n }\n \n return result as T;\n}\n\n"],"names":["discoverConfigDirectories","options","configDirName","maxLevels","startingDir","process","cwd","discovered","currentDir","path","resolve","level","visited","Set","realPath","has","add","configDirPath","join","stat","fs","isDirectory","push","parentDir","dirname","loadHierarchicalConfig","discoveredDirs","length","config","contextDirs","sortedDirs","sort","a","b","configs","dir","configPath","configFileName","content","readFile","parsed","yaml","load","contextDir","mergedConfig","reduce","acc","curr","deepMerge","target","source","undefined","Array","isArray","result","key","Object","prototype","hasOwnProperty","call","targetVal","sourceVal"],"mappings":";;;;AAuBA;;IAGO,MAAMA,yBAAAA,GAA4B,OACrCC,OAAAA,GAAAA;IAEA,MAAM,EACFC,aAAa,EACbC,SAAAA,GAAY,EAAE,EACdC,WAAAA,GAAcC,OAAAA,CAAQC,GAAG,EAAE,EAC9B,GAAGL,OAAAA;AAEJ,IAAA,MAAMM,aAAqC,EAAE;IAC7C,IAAIC,UAAAA,GAAaC,IAAAA,CAAKC,OAAO,CAACN,WAAAA,CAAAA;AAC9B,IAAA,IAAIO,KAAAA,GAAQ,CAAA;AACZ,IAAA,MAAMC,UAAU,IAAIC,GAAAA,EAAAA;AAEpB,IAAA,MAAOF,QAAQR,SAAAA,CAAW;QACtB,MAAMW,QAAAA,GAAWL,IAAAA,CAAKC,OAAO,CAACF,UAAAA,CAAAA;QAC9B,IAAII,OAAAA,CAAQG,GAAG,CAACD,QAAAA,CAAAA,EAAW;AAC3BF,QAAAA,OAAAA,CAAQI,GAAG,CAACF,QAAAA,CAAAA;AAEZ,QAAA,MAAMG,aAAAA,GAAgBR,IAAAA,CAAKS,IAAI,CAACV,UAAAA,EAAYN,aAAAA,CAAAA;QAE5C,IAAI;AACA,YAAA,MAAMiB,IAAAA,GAAO,MAAMC,EAAAA,CAAGD,IAAI,CAACF,aAAAA,CAAAA;YAC3B,IAAIE,IAAAA,CAAKE,WAAW,EAAA,EAAI;AACpBd,gBAAAA,UAAAA,CAAWe,IAAI,CAAC;oBAAEb,IAAAA,EAAMQ,aAAAA;AAAeN,oBAAAA;AAAM,iBAAA,CAAA;AACjD,YAAA;AACJ,QAAA,CAAA,CAAE,OAAM;;AAER,QAAA;QAEA,MAAMY,SAAAA,GAAYd,IAAAA,CAAKe,OAAO,CAAChB,UAAAA,CAAAA;QAC/B,IAAIe,SAAAA,KAAcf,UAAAA,EAAY,MAAA;QAE9BA,UAAAA,GAAae,SAAAA;AACbZ,QAAAA,KAAAA,EAAAA;AACJ,IAAA;IAEA,OAAOJ,UAAAA;AACX;AAEA;;IAGO,MAAMkB,sBAAAA,GAAyB,OAClCxB,OAAAA,GAAAA;IAEA,MAAMyB,cAAAA,GAAiB,MAAM1B,yBAAAA,CAA0BC,OAAAA,CAAAA;IAEvD,IAAIyB,cAAAA,CAAeC,MAAM,KAAK,CAAA,EAAG;QAC7B,OAAO;AACHC,YAAAA,MAAAA,EAAQ,EAAC;AACTF,YAAAA,cAAAA,EAAgB,EAAE;AAClBG,YAAAA,WAAAA,EAAa;AACjB,SAAA;AACJ,IAAA;;AAGA,IAAA,MAAMC,UAAAA,GAAa;AAAIJ,QAAAA,GAAAA;KAAe,CAACK,IAAI,CAAC,CAACC,CAAAA,EAAGC,IAAMA,CAAAA,CAAEtB,KAAK,GAAGqB,CAAAA,CAAErB,KAAK,CAAA;AAEvE,IAAA,MAAMuB,UAAqC,EAAE;AAC7C,IAAA,MAAML,cAAwB,EAAE;IAEhC,KAAK,MAAMM,OAAOL,UAAAA,CAAY;QAC1B,MAAMM,UAAAA,GAAa3B,KAAKS,IAAI,CAACiB,IAAI1B,IAAI,EAAER,QAAQoC,cAAc,CAAA;QAE7D,IAAI;AACA,YAAA,MAAMC,OAAAA,GAAU,MAAMlB,EAAAA,CAAGmB,QAAQ,CAACH,UAAAA,EAAY,OAAA,CAAA;YAC9C,MAAMI,MAAAA,GAASC,IAAAA,CAAKC,IAAI,CAACJ,OAAAA,CAAAA;YACzB,IAAIE,MAAAA,IAAU,OAAOA,MAAAA,KAAW,QAAA,EAAU;AACtCN,gBAAAA,OAAAA,CAAQZ,IAAI,CAACkB,MAAAA,CAAAA;AACjB,YAAA;AACJ,QAAA,CAAA,CAAE,OAAM;;AAER,QAAA;;AAGA,QAAA,MAAMG,aAAalC,IAAAA,CAAKS,IAAI,CAACiB,GAAAA,CAAI1B,IAAI,EAAE,SAAA,CAAA;QACvC,IAAI;AACA,YAAA,MAAMU,IAAAA,GAAO,MAAMC,EAAAA,CAAGD,IAAI,CAACwB,UAAAA,CAAAA;YAC3B,IAAIxB,IAAAA,CAAKE,WAAW,EAAA,EAAI;AACpBQ,gBAAAA,WAAAA,CAAYP,IAAI,CAACqB,UAAAA,CAAAA;AACrB,YAAA;AACJ,QAAA,CAAA,CAAE,OAAM;;AAER,QAAA;AACJ,IAAA;;IAGA,MAAMC,YAAAA,GAAeV,OAAAA,CAAQW,MAAM,CAC/B,CAACC,KAAKC,IAAAA,GAASC,SAAAA,CAAUF,GAAAA,EAAKC,IAAAA,CAAAA,EAClC,EAAC,CAAA;IAGD,OAAO;QACHnB,MAAAA,EAAQgB,YAAAA;AACRlB,QAAAA,cAAAA;AACAG,QAAAA;AACJ,KAAA;AACJ;AAEA;;AAEC,IACM,SAASmB,SAAAA,CAA6CC,MAAS,EAAEC,MAAS,EAAA;AAC7E,IAAA,IAAIA,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAWC,SAAAA,EAAW,OAAOF,MAAAA;AACpD,IAAA,IAAIA,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAWE,SAAAA,EAAW,OAAOD,MAAAA;AAEpD,IAAA,IAAI,OAAOA,MAAAA,KAAW,QAAA,IAAY,OAAOD,WAAW,QAAA,EAAU;QAC1D,OAAOC,MAAAA;AACX,IAAA;IAEA,IAAIE,KAAAA,CAAMC,OAAO,CAACH,MAAAA,CAAAA,EAAS;QACvB,OAAO;AAAIA,YAAAA,GAAAA;AAAO,SAAA;AACtB,IAAA;AAEA,IAAA,MAAMI,MAAAA,GAAS;AAAE,QAAA,GAAGL;AAAO,KAAA;IAE3B,IAAK,MAAMM,OAAOL,MAAAA,CAAQ;QACtB,IAAIM,MAAAA,CAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACT,QAAQK,GAAAA,CAAAA,EAAM;YACnD,MAAMK,SAAAA,GAAYN,MAAM,CAACC,GAAAA,CAAI;YAC7B,MAAMM,SAAAA,GAAYX,MAAM,CAACK,GAAAA,CAAI;AAE7B,YAAA,IACI,OAAOK,SAAAA,KAAc,QAAA,IAC7B,OAAOC,SAAAA,KAAc,QAAA,IACrBD,cAAc,IAAA,IACdC,SAAAA,KAAc,QACd,CAACT,KAAAA,CAAMC,OAAO,CAACO,SAAAA,CAAAA,IACf,CAACR,KAAAA,CAAMC,OAAO,CAACQ,SAAAA,CAAAA,EACT;AACEP,gBAAAA,MAAM,CAACC,GAAAA,CAAI,GAAGP,SAAAA,CACpBY,SAAAA,EACAC,SAAAA,CAAAA;YAEE,CAAA,MAAO;gBACHP,MAAM,CAACC,IAAI,GAAGM,SAAAA;AAClB,YAAA;AACJ,QAAA;AACJ,IAAA;IAEA,OAAOP,MAAAA;AACX;;;;"}
|
package/dist/context/index.js
CHANGED
|
@@ -32,24 +32,48 @@ export { deepMerge, discoverConfigDirectories } from './discovery.js';
|
|
|
32
32
|
},
|
|
33
33
|
getDiscoveredDirs: ()=>discoveryResult.discoveredDirs,
|
|
34
34
|
getConfig: ()=>discoveryResult.config,
|
|
35
|
+
getContextDirs: ()=>discoveryResult.contextDirs,
|
|
35
36
|
getPerson: (id)=>storage.get('person', id),
|
|
36
37
|
getProject: (id)=>storage.get('project', id),
|
|
37
38
|
getCompany: (id)=>storage.get('company', id),
|
|
38
39
|
getTerm: (id)=>storage.get('term', id),
|
|
40
|
+
getIgnored: (id)=>storage.get('ignored', id),
|
|
39
41
|
getAllPeople: ()=>storage.getAll('person'),
|
|
40
42
|
getAllProjects: ()=>storage.getAll('project'),
|
|
41
43
|
getAllCompanies: ()=>storage.getAll('company'),
|
|
42
44
|
getAllTerms: ()=>storage.getAll('term'),
|
|
45
|
+
getAllIgnored: ()=>storage.getAll('ignored'),
|
|
46
|
+
isIgnored: (term)=>{
|
|
47
|
+
const normalizedTerm = term.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
48
|
+
const ignoredTerms = storage.getAll('ignored');
|
|
49
|
+
return ignoredTerms.some((ignored)=>ignored.id === normalizedTerm || ignored.name.toLowerCase() === term.toLowerCase());
|
|
50
|
+
},
|
|
43
51
|
search: (query)=>storage.search(query),
|
|
44
52
|
findBySoundsLike: (phonetic)=>storage.findBySoundsLike(phonetic),
|
|
45
53
|
saveEntity: async (entity)=>{
|
|
46
54
|
// Save to the closest .protokoll directory
|
|
47
55
|
const closestDir = discoveryResult.discoveredDirs.sort((a, b)=>a.level - b.level)[0];
|
|
48
56
|
if (!closestDir) {
|
|
49
|
-
throw new Error('No .protokoll directory found. Run with --
|
|
57
|
+
throw new Error('No .protokoll directory found. Run with --init-config to create one.');
|
|
50
58
|
}
|
|
51
59
|
await storage.save(entity, closestDir.path);
|
|
52
60
|
},
|
|
61
|
+
deleteEntity: async (entity)=>{
|
|
62
|
+
// Delete from the closest .protokoll directory that contains it
|
|
63
|
+
const filePath = storage.getEntityFilePath(entity.type, entity.id, discoveryResult.contextDirs);
|
|
64
|
+
if (!filePath) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// Extract the context directory from the file path
|
|
68
|
+
const contextDir = discoveryResult.contextDirs.find((dir)=>filePath.startsWith(dir));
|
|
69
|
+
if (!contextDir) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return storage.delete(entity.type, entity.id, contextDir);
|
|
73
|
+
},
|
|
74
|
+
getEntityFilePath: (entity)=>{
|
|
75
|
+
return storage.getEntityFilePath(entity.type, entity.id, discoveryResult.contextDirs);
|
|
76
|
+
},
|
|
53
77
|
hasContext: ()=>discoveryResult.discoveredDirs.length > 0
|
|
54
78
|
};
|
|
55
79
|
};
|