@redaksjon/protokoll 0.0.8 → 0.0.10

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.
Files changed (112) hide show
  1. package/.cursor/rules/definition-of-done.md +89 -0
  2. package/.cursor/rules/no-emoticons.md +43 -0
  3. package/LICENSE +1 -1
  4. package/README.md +928 -35
  5. package/dist/agentic/executor.js +315 -0
  6. package/dist/agentic/executor.js.map +1 -0
  7. package/dist/agentic/index.js +19 -0
  8. package/dist/agentic/index.js.map +1 -0
  9. package/dist/agentic/registry.js +41 -0
  10. package/dist/agentic/registry.js.map +1 -0
  11. package/dist/agentic/tools/lookup-person.js +66 -0
  12. package/dist/agentic/tools/lookup-person.js.map +1 -0
  13. package/dist/agentic/tools/lookup-project.js +93 -0
  14. package/dist/agentic/tools/lookup-project.js.map +1 -0
  15. package/dist/agentic/tools/route-note.js +45 -0
  16. package/dist/agentic/tools/route-note.js.map +1 -0
  17. package/dist/agentic/tools/store-context.js +51 -0
  18. package/dist/agentic/tools/store-context.js.map +1 -0
  19. package/dist/agentic/tools/verify-spelling.js +57 -0
  20. package/dist/agentic/tools/verify-spelling.js.map +1 -0
  21. package/dist/arguments.js +23 -6
  22. package/dist/arguments.js.map +1 -1
  23. package/dist/constants.js +13 -11
  24. package/dist/constants.js.map +1 -1
  25. package/dist/context/discovery.js +114 -0
  26. package/dist/context/discovery.js.map +1 -0
  27. package/dist/context/index.js +58 -0
  28. package/dist/context/index.js.map +1 -0
  29. package/dist/context/storage.js +131 -0
  30. package/dist/context/storage.js.map +1 -0
  31. package/dist/interactive/handler.js +223 -0
  32. package/dist/interactive/handler.js.map +1 -0
  33. package/dist/interactive/index.js +18 -0
  34. package/dist/interactive/index.js.map +1 -0
  35. package/dist/interactive/onboarding.js +28 -0
  36. package/dist/interactive/onboarding.js.map +1 -0
  37. package/dist/main.js +0 -0
  38. package/dist/output/index.js +8 -0
  39. package/dist/output/index.js.map +1 -0
  40. package/dist/output/manager.js +105 -0
  41. package/dist/output/manager.js.map +1 -0
  42. package/dist/phases/complete.js +107 -0
  43. package/dist/phases/complete.js.map +1 -0
  44. package/dist/phases/locate.js +14 -5
  45. package/dist/phases/locate.js.map +1 -1
  46. package/dist/pipeline/index.js +8 -0
  47. package/dist/pipeline/index.js.map +1 -0
  48. package/dist/pipeline/orchestrator.js +281 -0
  49. package/dist/pipeline/orchestrator.js.map +1 -0
  50. package/dist/prompt/instructions/transcribe.md +6 -6
  51. package/dist/prompt/personas/transcriber.md +5 -5
  52. package/dist/protokoll.js +38 -5
  53. package/dist/protokoll.js.map +1 -1
  54. package/dist/reasoning/client.js +150 -0
  55. package/dist/reasoning/client.js.map +1 -0
  56. package/dist/reasoning/index.js +36 -0
  57. package/dist/reasoning/index.js.map +1 -0
  58. package/dist/reasoning/strategy.js +60 -0
  59. package/dist/reasoning/strategy.js.map +1 -0
  60. package/dist/reflection/collector.js +124 -0
  61. package/dist/reflection/collector.js.map +1 -0
  62. package/dist/reflection/index.js +16 -0
  63. package/dist/reflection/index.js.map +1 -0
  64. package/dist/reflection/reporter.js +238 -0
  65. package/dist/reflection/reporter.js.map +1 -0
  66. package/dist/routing/classifier.js +201 -0
  67. package/dist/routing/classifier.js.map +1 -0
  68. package/dist/routing/index.js +27 -0
  69. package/dist/routing/index.js.map +1 -0
  70. package/dist/routing/router.js +153 -0
  71. package/dist/routing/router.js.map +1 -0
  72. package/dist/transcription/index.js +41 -0
  73. package/dist/transcription/index.js.map +1 -0
  74. package/dist/transcription/service.js +64 -0
  75. package/dist/transcription/service.js.map +1 -0
  76. package/dist/transcription/types.js +31 -0
  77. package/dist/transcription/types.js.map +1 -0
  78. package/dist/util/media.js +4 -4
  79. package/dist/util/media.js.map +1 -1
  80. package/dist/util/metadata.js +95 -0
  81. package/dist/util/metadata.js.map +1 -0
  82. package/dist/util/storage.js +2 -2
  83. package/dist/util/storage.js.map +1 -1
  84. package/docs/examples.md +224 -0
  85. package/docs/index.html +5 -3
  86. package/docs/package-lock.json +639 -332
  87. package/docs/package.json +5 -4
  88. package/docs/troubleshooting.md +257 -0
  89. package/docs/vite.config.js +9 -3
  90. package/eslint.config.mjs +1 -0
  91. package/guide/architecture.md +217 -0
  92. package/guide/configuration.md +199 -0
  93. package/guide/context-system.md +215 -0
  94. package/guide/development.md +273 -0
  95. package/guide/index.md +91 -0
  96. package/guide/interactive.md +199 -0
  97. package/guide/quickstart.md +138 -0
  98. package/guide/reasoning.md +193 -0
  99. package/guide/routing.md +222 -0
  100. package/package.json +10 -7
  101. package/tsconfig.tsbuildinfo +1 -1
  102. package/vitest.config.ts +27 -5
  103. package/dist/phases/transcribe.js +0 -149
  104. package/dist/phases/transcribe.js.map +0 -1
  105. package/dist/processor.js +0 -35
  106. package/dist/processor.js.map +0 -1
  107. package/dist/prompt/transcribe.js +0 -41
  108. package/dist/prompt/transcribe.js.map +0 -1
  109. package/dist/util/general.js +0 -39
  110. package/dist/util/general.js.map +0 -1
  111. package/dist/util/openai.js +0 -92
  112. package/dist/util/openai.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/context/index.ts"],"sourcesContent":["/**\n * Context System\n * \n * Main entry point for the context system. Provides a factory function\n * to create context instances that can discover, load, and manage\n * entity data from hierarchical .protokoll directories.\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 { \n Entity, \n Person, \n Project, \n Company, \n Term, \n ContextDiscoveryOptions,\n DiscoveredContextDir,\n HierarchicalContextResult \n} from './types';\nimport * as Storage from './storage';\nimport * as Discovery from './discovery';\n\nexport interface ContextInstance {\n // Initialization\n load(): Promise<void>;\n reload(): Promise<void>;\n \n // Discovery info\n getDiscoveredDirs(): DiscoveredContextDir[];\n getConfig(): Record<string, unknown>;\n \n // Entity access\n getPerson(id: string): Person | undefined;\n getProject(id: string): Project | undefined;\n getCompany(id: string): Company | undefined;\n getTerm(id: string): Term | undefined;\n \n getAllPeople(): Person[];\n getAllProjects(): Project[];\n getAllCompanies(): Company[];\n getAllTerms(): Term[];\n \n // Search\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n \n // Modification (for self-update mode)\n saveEntity(entity: Entity): Promise<void>;\n \n // Check if context is available\n hasContext(): boolean;\n}\n\nexport interface CreateOptions {\n startingDir?: string;\n configDirName?: string;\n configFileName?: string;\n}\n\n/**\n * Create a new context instance\n */\nexport const create = async (options: CreateOptions = {}): Promise<ContextInstance> => {\n const discoveryOptions: ContextDiscoveryOptions = {\n configDirName: options.configDirName ?? '.protokoll',\n configFileName: options.configFileName ?? 'config.yaml',\n startingDir: options.startingDir,\n };\n\n const storage = Storage.create();\n let discoveryResult: HierarchicalContextResult = {\n config: {},\n discoveredDirs: [],\n contextDirs: [],\n };\n\n const loadContext = async (): Promise<void> => {\n discoveryResult = await Discovery.loadHierarchicalConfig(discoveryOptions);\n storage.clear();\n await storage.load(discoveryResult.contextDirs);\n };\n\n // Initial load\n await loadContext();\n\n return {\n load: loadContext,\n \n reload: async () => {\n storage.clear();\n await storage.load(discoveryResult.contextDirs);\n },\n \n getDiscoveredDirs: () => discoveryResult.discoveredDirs,\n getConfig: () => discoveryResult.config,\n \n getPerson: (id) => storage.get<Person>('person', id),\n getProject: (id) => storage.get<Project>('project', id),\n getCompany: (id) => storage.get<Company>('company', id),\n getTerm: (id) => storage.get<Term>('term', id),\n \n getAllPeople: () => storage.getAll<Person>('person'),\n getAllProjects: () => storage.getAll<Project>('project'),\n getAllCompanies: () => storage.getAll<Company>('company'),\n getAllTerms: () => storage.getAll<Term>('term'),\n \n search: (query) => storage.search(query),\n findBySoundsLike: (phonetic) => storage.findBySoundsLike(phonetic),\n \n saveEntity: async (entity) => {\n // Save to the closest .protokoll directory\n const closestDir = discoveryResult.discoveredDirs\n .sort((a, b) => a.level - b.level)[0];\n \n if (!closestDir) {\n throw new Error('No .protokoll directory found. Run with --setup to create one.');\n }\n \n await storage.save(entity, closestDir.path);\n },\n \n hasContext: () => discoveryResult.discoveredDirs.length > 0,\n };\n};\n\n// Re-export types\nexport * from './types';\n\n// Re-export discovery utilities for direct use if needed\nexport { discoverConfigDirectories, loadHierarchicalConfig, deepMerge } from './discovery';\n\n"],"names":["create","options","discoveryOptions","configDirName","configFileName","startingDir","storage","Storage","discoveryResult","config","discoveredDirs","contextDirs","loadContext","Discovery","clear","load","reload","getDiscoveredDirs","getConfig","getPerson","id","get","getProject","getCompany","getTerm","getAllPeople","getAll","getAllProjects","getAllCompanies","getAllTerms","search","query","findBySoundsLike","phonetic","saveEntity","entity","closestDir","sort","a","b","level","Error","save","path","hasContext","length"],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ import * as yaml from 'js-yaml';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+
5
+ const DIRECTORY_TO_TYPE = {
6
+ 'people': 'person',
7
+ 'projects': 'project',
8
+ 'companies': 'company',
9
+ 'terms': 'term'
10
+ };
11
+ const TYPE_TO_DIRECTORY = {
12
+ 'person': 'people',
13
+ 'project': 'projects',
14
+ 'company': 'companies',
15
+ 'term': 'terms'
16
+ };
17
+ const create = ()=>{
18
+ const entities = new Map([
19
+ [
20
+ 'person',
21
+ new Map()
22
+ ],
23
+ [
24
+ 'project',
25
+ new Map()
26
+ ],
27
+ [
28
+ 'company',
29
+ new Map()
30
+ ],
31
+ [
32
+ 'term',
33
+ new Map()
34
+ ]
35
+ ]);
36
+ const load = async (contextDirs)=>{
37
+ // Load from all context directories (later directories override)
38
+ for (const contextDir of contextDirs){
39
+ for (const dirName of Object.keys(DIRECTORY_TO_TYPE)){
40
+ const typeDir = path.join(contextDir, dirName);
41
+ const entityType = DIRECTORY_TO_TYPE[dirName];
42
+ try {
43
+ const files = await fs.readdir(typeDir);
44
+ for (const file of files){
45
+ if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;
46
+ const content = await fs.readFile(path.join(typeDir, file), 'utf-8');
47
+ const parsed = yaml.load(content);
48
+ if (parsed && parsed.id) {
49
+ var _entities_get;
50
+ (_entities_get = entities.get(entityType)) === null || _entities_get === void 0 ? void 0 : _entities_get.set(parsed.id, {
51
+ ...parsed,
52
+ type: entityType
53
+ });
54
+ }
55
+ }
56
+ } catch {
57
+ // Directory doesn't exist, skip
58
+ }
59
+ }
60
+ }
61
+ };
62
+ const save = async (entity, targetDir)=>{
63
+ var _entities_get;
64
+ const dirName = TYPE_TO_DIRECTORY[entity.type];
65
+ const dirPath = path.join(targetDir, 'context', dirName);
66
+ await fs.mkdir(dirPath, {
67
+ recursive: true
68
+ });
69
+ const filePath = path.join(dirPath, `${entity.id}.yaml`);
70
+ // Remove type from saved YAML (it's inferred from directory)
71
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
72
+ const { type: _entityType, ...entityWithoutType } = entity;
73
+ const content = yaml.dump(entityWithoutType, {
74
+ lineWidth: -1
75
+ });
76
+ await fs.writeFile(filePath, content, 'utf-8');
77
+ (_entities_get = entities.get(entity.type)) === null || _entities_get === void 0 ? void 0 : _entities_get.set(entity.id, entity);
78
+ };
79
+ const get = (type, id)=>{
80
+ var _entities_get;
81
+ return (_entities_get = entities.get(type)) === null || _entities_get === void 0 ? void 0 : _entities_get.get(id);
82
+ };
83
+ const getAll = (type)=>{
84
+ var _ref;
85
+ var _entities_get;
86
+ return Array.from((_ref = (_entities_get = entities.get(type)) === null || _entities_get === void 0 ? void 0 : _entities_get.values()) !== null && _ref !== void 0 ? _ref : []);
87
+ };
88
+ const search = (query)=>{
89
+ const normalizedQuery = query.toLowerCase();
90
+ const results = [];
91
+ for (const entityMap of entities.values()){
92
+ for (const entity of entityMap.values()){
93
+ if (entity.name.toLowerCase().includes(normalizedQuery)) {
94
+ results.push(entity);
95
+ }
96
+ }
97
+ }
98
+ return results;
99
+ };
100
+ const findBySoundsLike = (phonetic)=>{
101
+ const normalized = phonetic.toLowerCase().trim();
102
+ for (const entityMap of entities.values()){
103
+ for (const entity of entityMap.values()){
104
+ // Check sounds_like field on entities that have it
105
+ const entityWithSoundsLike = entity;
106
+ const variants = entityWithSoundsLike.sounds_like;
107
+ if (variants === null || variants === void 0 ? void 0 : variants.some((v)=>v.toLowerCase() === normalized)) {
108
+ return entity;
109
+ }
110
+ }
111
+ }
112
+ return undefined;
113
+ };
114
+ const clear = ()=>{
115
+ for (const entityMap of entities.values()){
116
+ entityMap.clear();
117
+ }
118
+ };
119
+ return {
120
+ load,
121
+ save,
122
+ get,
123
+ getAll,
124
+ search,
125
+ findBySoundsLike,
126
+ clear
127
+ };
128
+ };
129
+
130
+ export { create };
131
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sources":["../../src/context/storage.ts"],"sourcesContent":["/**\n * Context Storage\n * \n * Handles loading and saving entity YAML files from context directories.\n * Supports hierarchical loading where later directories override earlier ones.\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 yaml from 'js-yaml';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { Entity, EntityType } from './types';\n\nexport interface StorageInstance {\n load(contextDirs: string[]): Promise<void>;\n save(entity: Entity, targetDir: string): Promise<void>;\n get<T extends Entity>(type: EntityType, id: string): T | undefined;\n getAll<T extends Entity>(type: EntityType): T[];\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n clear(): void;\n}\n\ntype DirectoryName = 'people' | 'projects' | 'companies' | 'terms';\n\nconst DIRECTORY_TO_TYPE: Record<DirectoryName, EntityType> = {\n 'people': 'person',\n 'projects': 'project',\n 'companies': 'company',\n 'terms': 'term',\n};\n\nconst TYPE_TO_DIRECTORY: Record<EntityType, DirectoryName> = {\n 'person': 'people',\n 'project': 'projects',\n 'company': 'companies',\n 'term': 'terms',\n};\n\nexport const create = (): StorageInstance => {\n const entities: Map<EntityType, Map<string, Entity>> = new Map([\n ['person', new Map()],\n ['project', new Map()],\n ['company', new Map()],\n ['term', new Map()],\n ]);\n\n const load = async (contextDirs: string[]): Promise<void> => {\n // Load from all context directories (later directories override)\n for (const contextDir of contextDirs) {\n for (const dirName of Object.keys(DIRECTORY_TO_TYPE) as DirectoryName[]) {\n const typeDir = path.join(contextDir, dirName);\n const entityType = DIRECTORY_TO_TYPE[dirName];\n \n try {\n const files = await fs.readdir(typeDir);\n for (const file of files) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n \n const content = await fs.readFile(path.join(typeDir, file), 'utf-8');\n const parsed = yaml.load(content) as Partial<Entity>;\n \n if (parsed && parsed.id) {\n entities.get(entityType)?.set(parsed.id, {\n ...parsed,\n type: entityType,\n } as Entity);\n }\n }\n } catch {\n // Directory doesn't exist, skip\n }\n }\n }\n };\n\n const save = async (entity: Entity, targetDir: string): Promise<void> => {\n const dirName = TYPE_TO_DIRECTORY[entity.type];\n const dirPath = path.join(targetDir, 'context', dirName);\n await fs.mkdir(dirPath, { recursive: true });\n \n const filePath = path.join(dirPath, `${entity.id}.yaml`);\n \n // Remove type from saved YAML (it's inferred from directory)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type: _entityType, ...entityWithoutType } = entity;\n const content = yaml.dump(entityWithoutType, { lineWidth: -1 });\n await fs.writeFile(filePath, content, 'utf-8');\n \n entities.get(entity.type)?.set(entity.id, entity);\n };\n\n const get = <T extends Entity>(type: EntityType, id: string): T | undefined => {\n return entities.get(type)?.get(id) as T | undefined;\n };\n\n const getAll = <T extends Entity>(type: EntityType): T[] => {\n return Array.from(entities.get(type)?.values() ?? []) as T[];\n };\n\n const search = (query: string): Entity[] => {\n const normalizedQuery = query.toLowerCase();\n const results: Entity[] = [];\n \n for (const entityMap of entities.values()) {\n for (const entity of entityMap.values()) {\n if (entity.name.toLowerCase().includes(normalizedQuery)) {\n results.push(entity);\n }\n }\n }\n \n return results;\n };\n\n const findBySoundsLike = (phonetic: string): Entity | undefined => {\n const normalized = phonetic.toLowerCase().trim();\n \n for (const entityMap of entities.values()) {\n for (const entity of entityMap.values()) {\n // Check sounds_like field on entities that have it\n const entityWithSoundsLike = entity as Entity & { sounds_like?: string[] };\n const variants = entityWithSoundsLike.sounds_like;\n if (variants?.some(v => v.toLowerCase() === normalized)) {\n return entity;\n }\n }\n }\n \n return undefined;\n };\n\n const clear = (): void => {\n for (const entityMap of entities.values()) {\n entityMap.clear();\n }\n };\n\n return { load, save, get, getAll, search, findBySoundsLike, clear };\n};\n\n"],"names":["DIRECTORY_TO_TYPE","TYPE_TO_DIRECTORY","create","entities","Map","load","contextDirs","contextDir","dirName","Object","keys","typeDir","path","join","entityType","files","fs","readdir","file","endsWith","content","readFile","parsed","yaml","id","get","set","type","save","entity","targetDir","dirPath","mkdir","recursive","filePath","_entityType","entityWithoutType","dump","lineWidth","writeFile","getAll","Array","from","values","search","query","normalizedQuery","toLowerCase","results","entityMap","name","includes","push","findBySoundsLike","phonetic","normalized","trim","entityWithSoundsLike","variants","sounds_like","some","v","undefined","clear"],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ import * as readline from 'readline';
2
+ import { getLogger } from '../logging.js';
3
+
4
+ const createReadlineInterface = ()=>{
5
+ return readline.createInterface({
6
+ input: process.stdin,
7
+ output: process.stdout
8
+ });
9
+ };
10
+ const askQuestion = (rl, question)=>{
11
+ return new Promise((resolve)=>{
12
+ rl.question(question, (answer)=>{
13
+ resolve(answer.trim());
14
+ });
15
+ });
16
+ };
17
+ const formatClarificationPrompt = (request)=>{
18
+ const lines = [];
19
+ lines.push('');
20
+ lines.push('─'.repeat(60));
21
+ switch(request.type){
22
+ case 'name_spelling':
23
+ lines.push(`[Name Spelling Clarification]`);
24
+ lines.push(`Context: ${request.context}`);
25
+ lines.push(`Heard: "${request.term}"`);
26
+ if (request.suggestion) {
27
+ lines.push(`Suggested correction: "${request.suggestion}"`);
28
+ }
29
+ lines.push('');
30
+ lines.push('Enter correct spelling (or press Enter to accept suggestion):');
31
+ break;
32
+ case 'new_person':
33
+ lines.push(`[New Person Detected]`);
34
+ lines.push(`Context: ${request.context}`);
35
+ lines.push(`Name heard: "${request.term}"`);
36
+ lines.push('');
37
+ lines.push('Who is this person? (brief description, or press Enter to skip):');
38
+ break;
39
+ case 'new_project':
40
+ lines.push(`[New Project Detected]`);
41
+ lines.push(`Context: ${request.context}`);
42
+ lines.push(`Project name: "${request.term}"`);
43
+ lines.push('');
44
+ lines.push('What is this project? (brief description, or press Enter to skip):');
45
+ break;
46
+ case 'new_company':
47
+ lines.push(`[New Company Detected]`);
48
+ lines.push(`Context: ${request.context}`);
49
+ lines.push(`Company name: "${request.term}"`);
50
+ lines.push('');
51
+ lines.push('Any notes about this company? (or press Enter to skip):');
52
+ break;
53
+ case 'new_term':
54
+ lines.push(`[New Term Found]`);
55
+ lines.push(`Context: ${request.context}`);
56
+ lines.push(`Term: "${request.term}"`);
57
+ lines.push('');
58
+ lines.push('What does this term mean? (brief description, or press Enter to skip):');
59
+ break;
60
+ case 'routing_decision':
61
+ lines.push(`[Routing Decision Required]`);
62
+ lines.push(`Context: ${request.context}`);
63
+ if (request.options && request.options.length > 0) {
64
+ lines.push('Available destinations:');
65
+ request.options.forEach((opt, i)=>{
66
+ lines.push(` ${i + 1}. ${opt}`);
67
+ });
68
+ lines.push('');
69
+ lines.push('Enter number or destination path:');
70
+ } else {
71
+ lines.push('');
72
+ lines.push('Where should this note be filed?');
73
+ }
74
+ break;
75
+ case 'low_confidence_routing':
76
+ lines.push(`[Confirm Note Routing]`);
77
+ lines.push(`Confidence: ${request.term}`);
78
+ lines.push(`${request.context}`);
79
+ lines.push('');
80
+ lines.push('Is this correct? (Y/Enter to accept, or enter different path):');
81
+ break;
82
+ case 'first_run_onboarding':
83
+ lines.push(`[First Run Setup]`);
84
+ lines.push(`${request.context}`);
85
+ lines.push('');
86
+ if (request.options && request.options.length > 0) {
87
+ request.options.forEach((opt, i)=>{
88
+ lines.push(` ${i + 1}. ${opt}`);
89
+ });
90
+ lines.push('');
91
+ lines.push('Enter your choice:');
92
+ } else {
93
+ lines.push('Enter your response:');
94
+ }
95
+ break;
96
+ case 'general':
97
+ default:
98
+ lines.push(`[Clarification Needed]`);
99
+ lines.push(`${request.context}`);
100
+ if (request.term) {
101
+ lines.push(`Term: "${request.term}"`);
102
+ }
103
+ if (request.suggestion) {
104
+ lines.push(`Suggested spelling: "${request.suggestion}"`);
105
+ lines.push('');
106
+ lines.push('Press Enter or Y to accept suggestion, or type alternative:');
107
+ } else {
108
+ lines.push('');
109
+ lines.push('Your response:');
110
+ }
111
+ break;
112
+ }
113
+ lines.push('─'.repeat(60));
114
+ return lines.join('\n') + '\n> ';
115
+ };
116
+ const create = (config)=>{
117
+ const logger = getLogger();
118
+ let session = null;
119
+ let rl = null;
120
+ const startSession = ()=>{
121
+ session = {
122
+ requests: [],
123
+ responses: [],
124
+ startedAt: new Date()
125
+ };
126
+ if (config.enabled) {
127
+ rl = createReadlineInterface();
128
+ logger.info('Interactive session started - will prompt for clarifications');
129
+ } else {
130
+ logger.debug('Interactive session started (non-interactive mode)');
131
+ }
132
+ };
133
+ const endSession = ()=>{
134
+ if (!session) {
135
+ throw new Error('No active session');
136
+ }
137
+ if (rl) {
138
+ rl.close();
139
+ rl = null;
140
+ }
141
+ session.completedAt = new Date();
142
+ const completed = session;
143
+ session = null;
144
+ logger.info('Interactive session ended', {
145
+ requests: completed.requests.length,
146
+ responses: completed.responses.length
147
+ });
148
+ return completed;
149
+ };
150
+ const handleClarification = async (request)=>{
151
+ if (session) {
152
+ session.requests.push(request);
153
+ }
154
+ // In non-interactive mode, return the suggestion or the original term
155
+ if (!config.enabled || !rl) {
156
+ const response = {
157
+ type: request.type,
158
+ term: request.term,
159
+ response: request.suggestion ? request.suggestion : request.term,
160
+ shouldRemember: false
161
+ };
162
+ if (session) {
163
+ session.responses.push(response);
164
+ }
165
+ logger.debug('Clarification auto-resolved (non-interactive)', {
166
+ type: request.type,
167
+ term: request.term,
168
+ response: response.response
169
+ });
170
+ return response;
171
+ }
172
+ // Interactive mode - actually prompt the user
173
+ const prompt = formatClarificationPrompt(request);
174
+ const userInput = await askQuestion(rl, prompt);
175
+ // Process the user's response
176
+ let finalResponse;
177
+ let shouldRemember = false;
178
+ if (userInput === '' || userInput.toLowerCase() === 'y') {
179
+ // User pressed Enter or typed Y - use suggestion or original
180
+ finalResponse = request.suggestion || request.term;
181
+ } else if (request.options && /^\d+$/.test(userInput)) {
182
+ // User entered a number - select from options
183
+ const index = parseInt(userInput, 10) - 1;
184
+ if (index >= 0 && index < request.options.length) {
185
+ finalResponse = request.options[index];
186
+ } else {
187
+ finalResponse = userInput;
188
+ }
189
+ } else {
190
+ finalResponse = userInput;
191
+ // If user provided a custom answer, they might want to remember it
192
+ shouldRemember = true;
193
+ }
194
+ const response = {
195
+ type: request.type,
196
+ term: request.term,
197
+ response: finalResponse,
198
+ shouldRemember
199
+ };
200
+ if (session) {
201
+ session.responses.push(response);
202
+ }
203
+ logger.debug('Clarification resolved via user input', {
204
+ type: request.type,
205
+ term: request.term,
206
+ response: response.response,
207
+ shouldRemember
208
+ });
209
+ return response;
210
+ };
211
+ const isEnabled = ()=>config.enabled;
212
+ const getSession = ()=>session;
213
+ return {
214
+ startSession,
215
+ endSession,
216
+ handleClarification,
217
+ isEnabled,
218
+ getSession
219
+ };
220
+ };
221
+
222
+ export { create };
223
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sources":["../../src/interactive/handler.ts"],"sourcesContent":["/**\n * Interactive Handler\n * \n * Manages interactive sessions and clarification requests.\n * Uses readline for actual user prompting.\n */\n\nimport * as readline from 'readline';\nimport { \n InteractiveConfig, \n InteractiveSession, \n ClarificationRequest, \n ClarificationResponse \n} from './types';\nimport * as Logging from '../logging';\n\nexport interface HandlerInstance {\n startSession(): void;\n endSession(): InteractiveSession;\n handleClarification(request: ClarificationRequest): Promise<ClarificationResponse>;\n isEnabled(): boolean;\n getSession(): InteractiveSession | null;\n}\n\nconst createReadlineInterface = () => {\n return readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n};\n\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 formatClarificationPrompt = (request: ClarificationRequest): string => {\n const lines: string[] = [];\n \n lines.push('');\n lines.push('─'.repeat(60));\n \n switch (request.type) {\n case 'name_spelling':\n lines.push(`[Name Spelling Clarification]`);\n lines.push(`Context: ${request.context}`);\n lines.push(`Heard: \"${request.term}\"`);\n if (request.suggestion) {\n lines.push(`Suggested correction: \"${request.suggestion}\"`);\n }\n lines.push('');\n lines.push('Enter correct spelling (or press Enter to accept suggestion):');\n break;\n \n case 'new_person':\n lines.push(`[New Person Detected]`);\n lines.push(`Context: ${request.context}`);\n lines.push(`Name heard: \"${request.term}\"`);\n lines.push('');\n lines.push('Who is this person? (brief description, or press Enter to skip):');\n break;\n \n case 'new_project':\n lines.push(`[New Project Detected]`);\n lines.push(`Context: ${request.context}`);\n lines.push(`Project name: \"${request.term}\"`);\n lines.push('');\n lines.push('What is this project? (brief description, or press Enter to skip):');\n break;\n \n case 'new_company':\n lines.push(`[New Company Detected]`);\n lines.push(`Context: ${request.context}`);\n lines.push(`Company name: \"${request.term}\"`);\n lines.push('');\n lines.push('Any notes about this company? (or press Enter to skip):');\n break;\n \n case 'new_term':\n lines.push(`[New Term Found]`);\n lines.push(`Context: ${request.context}`);\n lines.push(`Term: \"${request.term}\"`);\n lines.push('');\n lines.push('What does this term mean? (brief description, or press Enter to skip):');\n break;\n \n case 'routing_decision':\n lines.push(`[Routing Decision Required]`);\n lines.push(`Context: ${request.context}`);\n if (request.options && request.options.length > 0) {\n lines.push('Available destinations:');\n request.options.forEach((opt, i) => {\n lines.push(` ${i + 1}. ${opt}`);\n });\n lines.push('');\n lines.push('Enter number or destination path:');\n } else {\n lines.push('');\n lines.push('Where should this note be filed?');\n }\n break;\n \n case 'low_confidence_routing':\n lines.push(`[Confirm Note Routing]`);\n lines.push(`Confidence: ${request.term}`);\n lines.push(`${request.context}`);\n lines.push('');\n lines.push('Is this correct? (Y/Enter to accept, or enter different path):');\n break;\n \n case 'first_run_onboarding':\n lines.push(`[First Run Setup]`);\n lines.push(`${request.context}`);\n lines.push('');\n if (request.options && request.options.length > 0) {\n request.options.forEach((opt, i) => {\n lines.push(` ${i + 1}. ${opt}`);\n });\n lines.push('');\n lines.push('Enter your choice:');\n } else {\n lines.push('Enter your response:');\n }\n break;\n \n case 'general':\n default:\n lines.push(`[Clarification Needed]`);\n lines.push(`${request.context}`);\n if (request.term) {\n lines.push(`Term: \"${request.term}\"`);\n }\n if (request.suggestion) {\n lines.push(`Suggested spelling: \"${request.suggestion}\"`);\n lines.push('');\n lines.push('Press Enter or Y to accept suggestion, or type alternative:');\n } else {\n lines.push('');\n lines.push('Your response:');\n }\n break;\n }\n \n lines.push('─'.repeat(60));\n \n return lines.join('\\n') + '\\n> ';\n};\n\nexport const create = (config: InteractiveConfig): HandlerInstance => {\n const logger = Logging.getLogger();\n \n let session: InteractiveSession | null = null;\n let rl: readline.Interface | null = null;\n \n const startSession = () => {\n session = {\n requests: [],\n responses: [],\n startedAt: new Date(),\n };\n \n if (config.enabled) {\n rl = createReadlineInterface();\n logger.info('Interactive session started - will prompt for clarifications');\n } else {\n logger.debug('Interactive session started (non-interactive mode)');\n }\n };\n \n const endSession = (): InteractiveSession => {\n if (!session) {\n throw new Error('No active session');\n }\n \n if (rl) {\n rl.close();\n rl = null;\n }\n \n session.completedAt = new Date();\n const completed = session;\n session = null;\n \n logger.info('Interactive session ended', { \n requests: completed.requests.length,\n responses: completed.responses.length,\n });\n \n return completed;\n };\n \n const handleClarification = async (\n request: ClarificationRequest\n ): Promise<ClarificationResponse> => {\n if (session) {\n session.requests.push(request);\n }\n \n // In non-interactive mode, return the suggestion or the original term\n if (!config.enabled || !rl) {\n const response: ClarificationResponse = {\n type: request.type,\n term: request.term,\n response: config.defaultToSuggestion && request.suggestion \n ? request.suggestion \n : request.term,\n shouldRemember: false,\n };\n \n if (session) {\n session.responses.push(response);\n }\n \n logger.debug('Clarification auto-resolved (non-interactive)', { \n type: request.type, \n term: request.term,\n response: response.response,\n });\n \n return response;\n }\n \n // Interactive mode - actually prompt the user\n const prompt = formatClarificationPrompt(request);\n const userInput = await askQuestion(rl, prompt);\n \n // Process the user's response\n let finalResponse: string;\n let shouldRemember = false;\n \n if (userInput === '' || userInput.toLowerCase() === 'y') {\n // User pressed Enter or typed Y - use suggestion or original\n finalResponse = request.suggestion || request.term;\n } else if (request.options && /^\\d+$/.test(userInput)) {\n // User entered a number - select from options\n const index = parseInt(userInput, 10) - 1;\n if (index >= 0 && index < request.options.length) {\n finalResponse = request.options[index];\n } else {\n finalResponse = userInput;\n }\n } else {\n finalResponse = userInput;\n // If user provided a custom answer, they might want to remember it\n shouldRemember = true;\n }\n \n const response: ClarificationResponse = {\n type: request.type,\n term: request.term,\n response: finalResponse,\n shouldRemember,\n };\n \n if (session) {\n session.responses.push(response);\n }\n \n logger.debug('Clarification resolved via user input', { \n type: request.type, \n term: request.term,\n response: response.response,\n shouldRemember,\n });\n \n return response;\n };\n \n const isEnabled = () => config.enabled;\n \n const getSession = () => session;\n \n return {\n startSession,\n endSession,\n handleClarification,\n isEnabled,\n getSession,\n };\n};\n"],"names":["createReadlineInterface","readline","createInterface","input","process","stdin","output","stdout","askQuestion","rl","question","Promise","resolve","answer","trim","formatClarificationPrompt","request","lines","push","repeat","type","context","term","suggestion","options","length","forEach","opt","i","join","create","config","logger","Logging","session","startSession","requests","responses","startedAt","Date","enabled","info","debug","endSession","Error","close","completedAt","completed","handleClarification","response","shouldRemember","prompt","userInput","finalResponse","toLowerCase","test","index","parseInt","isEnabled","getSession"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { create as create$2 } from './handler.js';
2
+ import { create as create$1 } from './onboarding.js';
3
+
4
+ const create = (config, context)=>{
5
+ const handler = create$2(config);
6
+ const onboarding = create$1(context);
7
+ return {
8
+ startSession: handler.startSession,
9
+ endSession: handler.endSession,
10
+ getSession: handler.getSession,
11
+ handleClarification: handler.handleClarification,
12
+ isEnabled: handler.isEnabled,
13
+ checkNeedsOnboarding: onboarding.checkNeedsOnboarding
14
+ };
15
+ };
16
+
17
+ export { create };
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/interactive/index.ts"],"sourcesContent":["/**\n * Interactive Mode System\n * \n * Main entry point for the interactive mode system. Provides session management,\n * clarification handling, and onboarding detection.\n */\n\nimport { \n InteractiveConfig, \n InteractiveSession, \n ClarificationRequest, \n ClarificationResponse,\n OnboardingState \n} from './types';\nimport * as Handler from './handler';\nimport * as Onboarding from './onboarding';\nimport * as Context from '../context';\n\nexport interface InteractiveInstance {\n // Session management\n startSession(): void;\n endSession(): InteractiveSession;\n getSession(): InteractiveSession | null;\n \n // Clarification handling\n handleClarification(request: ClarificationRequest): Promise<ClarificationResponse>;\n \n // State\n isEnabled(): boolean;\n \n // Onboarding\n checkNeedsOnboarding(): OnboardingState;\n}\n\nexport const create = (\n config: InteractiveConfig,\n context: Context.ContextInstance\n): InteractiveInstance => {\n const handler = Handler.create(config);\n const onboarding = Onboarding.create(context);\n \n return {\n startSession: handler.startSession,\n endSession: handler.endSession,\n getSession: handler.getSession,\n handleClarification: handler.handleClarification,\n isEnabled: handler.isEnabled,\n checkNeedsOnboarding: onboarding.checkNeedsOnboarding,\n };\n};\n\n// Re-export types\nexport * from './types';\n\n// Re-export utilities\nexport { createDefaultOnboardingResult } from './onboarding';\n\n"],"names":["create","config","context","handler","Handler","onboarding","Onboarding","startSession","endSession","getSession","handleClarification","isEnabled","checkNeedsOnboarding"],"mappings":";;;AAkCO,MAAMA,MAAAA,GAAS,CAClBC,MAAAA,EACAC,OAAAA,GAAAA;IAEA,MAAMC,OAAAA,GAAUC,QAAc,CAACH,MAAAA,CAAAA;IAC/B,MAAMI,UAAAA,GAAaC,QAAiB,CAACJ,OAAAA,CAAAA;IAErC,OAAO;AACHK,QAAAA,YAAAA,EAAcJ,QAAQI,YAAY;AAClCC,QAAAA,UAAAA,EAAYL,QAAQK,UAAU;AAC9BC,QAAAA,UAAAA,EAAYN,QAAQM,UAAU;AAC9BC,QAAAA,mBAAAA,EAAqBP,QAAQO,mBAAmB;AAChDC,QAAAA,SAAAA,EAAWR,QAAQQ,SAAS;AAC5BC,QAAAA,oBAAAA,EAAsBP,WAAWO;AACrC,KAAA;AACJ;;;;"}
@@ -0,0 +1,28 @@
1
+ import { getLogger } from '../logging.js';
2
+
3
+ const create = (context)=>{
4
+ const logger = getLogger();
5
+ const checkNeedsOnboarding = ()=>{
6
+ var _configWithRouting_routing_default, _configWithRouting_routing;
7
+ const projects = context.getAllProjects();
8
+ const config = context.getConfig();
9
+ const hasProjects = projects.length > 0;
10
+ const configWithRouting = config;
11
+ const hasDefaultDestination = !!(configWithRouting === null || configWithRouting === void 0 ? void 0 : (_configWithRouting_routing = configWithRouting.routing) === null || _configWithRouting_routing === void 0 ? void 0 : (_configWithRouting_routing_default = _configWithRouting_routing.default) === null || _configWithRouting_routing_default === void 0 ? void 0 : _configWithRouting_routing_default.path);
12
+ const hasAnyContext = context.hasContext();
13
+ const state = {
14
+ hasProjects,
15
+ hasDefaultDestination,
16
+ hasAnyContext,
17
+ needsOnboarding: !hasAnyContext
18
+ };
19
+ logger.debug('Onboarding state checked', state);
20
+ return state;
21
+ };
22
+ return {
23
+ checkNeedsOnboarding
24
+ };
25
+ };
26
+
27
+ export { create };
28
+ //# sourceMappingURL=onboarding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.js","sources":["../../src/interactive/onboarding.ts"],"sourcesContent":["/**\n * Onboarding\n * \n * Handles first-run detection and bootstrap onboarding flow.\n */\n\nimport { OnboardingState, OnboardingResult } from './types';\nimport * as Context from '../context';\nimport * as Logging from '../logging';\n\nexport interface OnboardingInstance {\n checkNeedsOnboarding(): OnboardingState;\n // Note: Full interactive onboarding requires inquirer\n // This provides the state detection and result structure\n}\n\nexport const create = (context: Context.ContextInstance): OnboardingInstance => {\n const logger = Logging.getLogger();\n \n const checkNeedsOnboarding = (): OnboardingState => {\n const projects = context.getAllProjects();\n const config = context.getConfig();\n \n const hasProjects = projects.length > 0;\n const configWithRouting = config as { routing?: { default?: { path?: string } } };\n const hasDefaultDestination = !!configWithRouting?.routing?.default?.path;\n const hasAnyContext = context.hasContext();\n \n const state: OnboardingState = {\n hasProjects,\n hasDefaultDestination,\n hasAnyContext,\n needsOnboarding: !hasAnyContext,\n };\n \n logger.debug('Onboarding state checked', state);\n \n return state;\n };\n \n return { checkNeedsOnboarding };\n};\n\n/**\n * Create a default onboarding result for non-interactive mode\n */\nexport const createDefaultOnboardingResult = (): OnboardingResult => ({\n defaultDestination: '~/notes',\n defaultStructure: 'month',\n projects: [],\n completed: false,\n});\n\n"],"names":["create","context","logger","Logging","checkNeedsOnboarding","configWithRouting","projects","getAllProjects","config","getConfig","hasProjects","length","hasDefaultDestination","routing","default","path","hasAnyContext","hasContext","state","needsOnboarding","debug"],"mappings":";;AAgBO,MAAMA,SAAS,CAACC,OAAAA,GAAAA;IACnB,MAAMC,MAAAA,GAASC,SAAiB,EAAA;AAEhC,IAAA,MAAMC,oBAAAA,GAAuB,IAAA;YAMOC,kCAAAA,EAAAA,0BAAAA;QALhC,MAAMC,QAAAA,GAAWL,QAAQM,cAAc,EAAA;QACvC,MAAMC,MAAAA,GAASP,QAAQQ,SAAS,EAAA;QAEhC,MAAMC,WAAAA,GAAcJ,QAAAA,CAASK,MAAM,GAAG,CAAA;AACtC,QAAA,MAAMN,iBAAAA,GAAoBG,MAAAA;AAC1B,QAAA,MAAMI,wBAAwB,CAAC,EAACP,iBAAAA,KAAAA,IAAAA,IAAAA,iBAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,CAAAA,6BAAAA,iBAAAA,CAAmBQ,OAAO,MAAA,IAAA,IAA1BR,0BAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,CAAAA,qCAAAA,0BAAAA,CAA4BS,OAAO,MAAA,IAAA,IAAnCT,kCAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,mCAAqCU,IAAI,CAAA;QACzE,MAAMC,aAAAA,GAAgBf,QAAQgB,UAAU,EAAA;AAExC,QAAA,MAAMC,KAAAA,GAAyB;AAC3BR,YAAAA,WAAAA;AACAE,YAAAA,qBAAAA;AACAI,YAAAA,aAAAA;AACAG,YAAAA,eAAAA,EAAiB,CAACH;AACtB,SAAA;QAEAd,MAAAA,CAAOkB,KAAK,CAAC,0BAAA,EAA4BF,KAAAA,CAAAA;QAEzC,OAAOA,KAAAA;AACX,IAAA,CAAA;IAEA,OAAO;AAAEd,QAAAA;AAAqB,KAAA;AAClC;;;;"}
package/dist/main.js CHANGED
File without changes
@@ -0,0 +1,8 @@
1
+ import { create as create$1 } from './manager.js';
2
+
3
+ const create = (config)=>{
4
+ return create$1(config);
5
+ };
6
+
7
+ export { create };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/output/index.ts"],"sourcesContent":["/**\n * Output Management System\n *\n * Main entry point for the output management system. Handles intermediate\n * files and final output destinations.\n */\n\nimport { OutputConfig, OutputPaths, IntermediateFiles } from './types';\nimport * as Manager from './manager';\nimport * as Metadata from '../util/metadata';\n\nexport interface OutputInstance {\n createOutputPaths(\n audioFile: string,\n routedDestination: string,\n hash: string,\n date: Date\n ): OutputPaths;\n ensureDirectories(paths: OutputPaths): Promise<void>;\n writeIntermediate(\n paths: OutputPaths,\n type: keyof IntermediateFiles,\n content: unknown\n ): Promise<string>;\n writeTranscript(paths: OutputPaths, content: string, metadata?: Metadata.TranscriptMetadata): Promise<string>;\n cleanIntermediates(paths: OutputPaths): Promise<void>;\n}\n\nexport const create = (config: OutputConfig): OutputInstance => {\n return Manager.create(config);\n};\n\nexport const DEFAULT_OUTPUT_CONFIG: OutputConfig = {\n intermediateDir: './output/protokoll',\n keepIntermediates: true,\n timestampFormat: 'YYMMDD-HHmm',\n};\n\n// Re-export types\nexport * from './types';\n\n"],"names":["create","config","Manager"],"mappings":";;AA4BO,MAAMA,SAAS,CAACC,MAAAA,GAAAA;IACnB,OAAOC,QAAc,CAACD,MAAAA,CAAAA;AAC1B;;;;"}
@@ -0,0 +1,105 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs/promises';
3
+ import { getLogger } from '../logging.js';
4
+ import { formatMetadataMarkdown } from '../util/metadata.js';
5
+
6
+ const create = (config)=>{
7
+ const logger = getLogger();
8
+ const formatTimestamp = (date)=>{
9
+ // Format: YYYY-MM-DD-HHmm (full year, dashes for separation)
10
+ const pad = (n)=>n.toString().padStart(2, '0');
11
+ const year = date.getFullYear().toString();
12
+ const month = pad(date.getMonth() + 1);
13
+ const day = pad(date.getDate());
14
+ const hours = pad(date.getHours());
15
+ const minutes = pad(date.getMinutes());
16
+ return `${year}-${month}-${day}-${hours}${minutes}`;
17
+ };
18
+ const createOutputPaths = (_audioFile, routedDestination, hash, date)=>{
19
+ const timestamp = formatTimestamp(date);
20
+ const shortHash = hash.slice(0, 6);
21
+ // Hash at the end for easier filename correlation
22
+ const buildFilename = (type, ext)=>`${timestamp}-${type}-${shortHash}${ext}`;
23
+ const intermediateDir = config.intermediateDir;
24
+ return {
25
+ final: routedDestination,
26
+ intermediate: {
27
+ transcript: path.join(intermediateDir, buildFilename('transcript', '.json')),
28
+ context: path.join(intermediateDir, buildFilename('context', '.json')),
29
+ request: path.join(intermediateDir, buildFilename('request', '.json')),
30
+ response: path.join(intermediateDir, buildFilename('response', '.json')),
31
+ reflection: path.join(intermediateDir, buildFilename('reflection', '.md')),
32
+ session: path.join(intermediateDir, buildFilename('session', '.json'))
33
+ }
34
+ };
35
+ };
36
+ const ensureDirectories = async (paths)=>{
37
+ // Ensure intermediate directory
38
+ await fs.mkdir(path.dirname(paths.intermediate.transcript), {
39
+ recursive: true
40
+ });
41
+ // Ensure final directory
42
+ await fs.mkdir(path.dirname(paths.final), {
43
+ recursive: true
44
+ });
45
+ logger.debug('Ensured output directories', {
46
+ intermediate: path.dirname(paths.intermediate.transcript),
47
+ final: path.dirname(paths.final)
48
+ });
49
+ };
50
+ const writeIntermediate = async (paths, type, content)=>{
51
+ const filePath = paths.intermediate[type];
52
+ if (!filePath) {
53
+ throw new Error(`Invalid intermediate type: ${type}`);
54
+ }
55
+ const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
56
+ await fs.writeFile(filePath, contentStr, 'utf-8');
57
+ logger.debug('Wrote intermediate file', {
58
+ type,
59
+ path: filePath
60
+ });
61
+ return filePath;
62
+ };
63
+ const writeTranscript = async (paths, content, metadata)=>{
64
+ // Prepend metadata if provided
65
+ let finalContent = content;
66
+ if (metadata) {
67
+ const metadataSection = formatMetadataMarkdown(metadata);
68
+ finalContent = metadataSection + content;
69
+ }
70
+ await fs.writeFile(paths.final, finalContent, 'utf-8');
71
+ logger.info('Wrote final transcript', {
72
+ path: paths.final
73
+ });
74
+ return paths.final;
75
+ };
76
+ const cleanIntermediates = async (paths)=>{
77
+ if (config.keepIntermediates) {
78
+ logger.debug('Keeping intermediate files');
79
+ return;
80
+ }
81
+ for (const [type, filePath] of Object.entries(paths.intermediate)){
82
+ if (filePath) {
83
+ try {
84
+ await fs.unlink(filePath);
85
+ logger.debug('Removed intermediate file', {
86
+ type,
87
+ path: filePath
88
+ });
89
+ } catch {
90
+ // File might not exist, that's OK
91
+ }
92
+ }
93
+ }
94
+ };
95
+ return {
96
+ createOutputPaths,
97
+ ensureDirectories,
98
+ writeIntermediate,
99
+ writeTranscript,
100
+ cleanIntermediates
101
+ };
102
+ };
103
+
104
+ export { create };
105
+ //# sourceMappingURL=manager.js.map