coaiajs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CLAUDE.md +56 -0
  2. package/KINSHIP.md +63 -0
  3. package/README.md +148 -0
  4. package/articles/academic/creative-orientation-vs-problem-solving.md +177 -0
  5. package/articles/academic/jsonl-knowledge-graphs-agent-memory.md +142 -0
  6. package/articles/academic/langfuse-observability-llm-pipelines.md +144 -0
  7. package/articles/academic/medicine-wheel-software-architecture.md +163 -0
  8. package/articles/academic/mmot-autonomous-agents.md +156 -0
  9. package/articles/academic/model-context-protocol-interagent.md +161 -0
  10. package/articles/academic/pde-prompt-decomposition.md +186 -0
  11. package/articles/academic/structural-tension-in-ai-agents.md +134 -0
  12. package/articles/reviews/mcp-protocol-design-review.md +170 -0
  13. package/articles/reviews/observability-ai-systems-review.md +176 -0
  14. package/articles/reviews/prompt-engineering-decomposition-review.md +184 -0
  15. package/articles/surveys/agent-orchestration-survey.md +186 -0
  16. package/articles/surveys/knowledge-graph-storage-survey.md +204 -0
  17. package/articles/surveys/structural-tension-methodology-survey.md +154 -0
  18. package/articles/technical/aws-sdk-v3-polly.md +270 -0
  19. package/articles/technical/commander-cli-framework.md +262 -0
  20. package/articles/technical/dotenv-config-patterns.md +360 -0
  21. package/articles/technical/ioredis-vs-redis.md +142 -0
  22. package/articles/technical/langfuse-js-sdk-vs-rest.md +191 -0
  23. package/articles/technical/mcp-sdk-typescript.md +291 -0
  24. package/articles/technical/octokit-github-api.md +293 -0
  25. package/articles/technical/openai-sdk-modern.md +231 -0
  26. package/articles/technical/yaml-parsing-node.md +266 -0
  27. package/articles/technical/zod-runtime-validation.md +212 -0
  28. package/dist/mcp/config.d.ts +14 -0
  29. package/dist/mcp/config.js +185 -0
  30. package/dist/mcp/server.d.ts +3 -0
  31. package/dist/mcp/server.js +324 -0
  32. package/dist/mcp/tools/coaiapy-tools.d.ts +8 -0
  33. package/dist/mcp/tools/coaiapy-tools.js +326 -0
  34. package/dist/mcp/tools/index.d.ts +3 -0
  35. package/dist/mcp/tools/index.js +3 -0
  36. package/dist/src/audio.d.ts +12 -0
  37. package/dist/src/audio.js +57 -0
  38. package/dist/src/cli-helpers.d.ts +9 -0
  39. package/dist/src/cli-helpers.js +78 -0
  40. package/dist/src/cli.d.ts +3 -0
  41. package/dist/src/cli.js +1086 -0
  42. package/dist/src/config.d.ts +15 -0
  43. package/dist/src/config.js +145 -0
  44. package/dist/src/environment.d.ts +44 -0
  45. package/dist/src/environment.js +146 -0
  46. package/dist/src/github.d.ts +47 -0
  47. package/dist/src/github.js +79 -0
  48. package/dist/src/langfuse/client.d.ts +30 -0
  49. package/dist/src/langfuse/client.js +75 -0
  50. package/dist/src/langfuse/comments.d.ts +16 -0
  51. package/dist/src/langfuse/comments.js +36 -0
  52. package/dist/src/langfuse/datasets.d.ts +19 -0
  53. package/dist/src/langfuse/datasets.js +140 -0
  54. package/dist/src/langfuse/index.d.ts +13 -0
  55. package/dist/src/langfuse/index.js +10 -0
  56. package/dist/src/langfuse/media.d.ts +11 -0
  57. package/dist/src/langfuse/media.js +167 -0
  58. package/dist/src/langfuse/observations.d.ts +18 -0
  59. package/dist/src/langfuse/observations.js +113 -0
  60. package/dist/src/langfuse/prompts.d.ts +14 -0
  61. package/dist/src/langfuse/prompts.js +127 -0
  62. package/dist/src/langfuse/scores.d.ts +54 -0
  63. package/dist/src/langfuse/scores.js +366 -0
  64. package/dist/src/langfuse/traces.d.ts +29 -0
  65. package/dist/src/langfuse/traces.js +225 -0
  66. package/dist/src/llm.d.ts +23 -0
  67. package/dist/src/llm.js +76 -0
  68. package/dist/src/narrative/graph-manager.d.ts +106 -0
  69. package/dist/src/narrative/graph-manager.js +915 -0
  70. package/dist/src/narrative/index.d.ts +9 -0
  71. package/dist/src/narrative/index.js +7 -0
  72. package/dist/src/narrative/markdown-export.d.ts +21 -0
  73. package/dist/src/narrative/markdown-export.js +383 -0
  74. package/dist/src/narrative/tool-definitions.d.ts +21 -0
  75. package/dist/src/narrative/tool-definitions.js +588 -0
  76. package/dist/src/narrative/tool-handlers.d.ts +11 -0
  77. package/dist/src/narrative/tool-handlers.js +462 -0
  78. package/dist/src/narrative/types.d.ts +2 -0
  79. package/dist/src/narrative/types.js +2 -0
  80. package/dist/src/narrative/validation.d.ts +29 -0
  81. package/dist/src/narrative/validation.js +144 -0
  82. package/dist/src/pde/index.d.ts +8 -0
  83. package/dist/src/pde/index.js +8 -0
  84. package/dist/src/pde/mcp-handlers.d.ts +7 -0
  85. package/dist/src/pde/mcp-handlers.js +300 -0
  86. package/dist/src/pde/mcp-tools.d.ts +15 -0
  87. package/dist/src/pde/mcp-tools.js +191 -0
  88. package/dist/src/pde/session-manager.d.ts +32 -0
  89. package/dist/src/pde/session-manager.js +205 -0
  90. package/dist/src/pde/stc-mapper.d.ts +26 -0
  91. package/dist/src/pde/stc-mapper.js +234 -0
  92. package/dist/src/pipeline/index.d.ts +2 -0
  93. package/dist/src/pipeline/index.js +3 -0
  94. package/dist/src/pipeline/template-engine.d.ts +20 -0
  95. package/dist/src/pipeline/template-engine.js +361 -0
  96. package/dist/src/planning/index.d.ts +7 -0
  97. package/dist/src/planning/index.js +7 -0
  98. package/dist/src/planning/mcp-handlers.d.ts +7 -0
  99. package/dist/src/planning/mcp-handlers.js +310 -0
  100. package/dist/src/planning/mcp-tools.d.ts +15 -0
  101. package/dist/src/planning/mcp-tools.js +145 -0
  102. package/dist/src/planning/plan-parser.d.ts +35 -0
  103. package/dist/src/planning/plan-parser.js +506 -0
  104. package/dist/src/redis.d.ts +21 -0
  105. package/dist/src/redis.js +78 -0
  106. package/dist/src/types.d.ts +244 -0
  107. package/dist/src/types.js +8 -0
  108. package/mcp/config.ts +196 -0
  109. package/mcp/server.ts +402 -0
  110. package/mcp/tools/coaiapy-tools.ts +364 -0
  111. package/mcp/tools/index.ts +4 -0
  112. package/package.json +52 -0
  113. package/rispecs/00-coaiajs-platform.spec.md +102 -0
  114. package/rispecs/01-core-config.spec.md +89 -0
  115. package/rispecs/02-redis-module.spec.md +62 -0
  116. package/rispecs/03-langfuse-module.spec.md +101 -0
  117. package/rispecs/04-narrative-engine.spec.md +185 -0
  118. package/rispecs/05-pde-engine.spec.md +112 -0
  119. package/rispecs/06-planning-engine.spec.md +128 -0
  120. package/rispecs/07-pipeline-templates.spec.md +97 -0
  121. package/rispecs/08-cli-interface.spec.md +134 -0
  122. package/rispecs/09-mcp-server.spec.md +140 -0
  123. package/rispecs/10-audio-module.spec.md +63 -0
  124. package/rispecs/KINSHIP.md +56 -0
  125. package/rispecs/README.md +100 -0
  126. package/src/audio.ts +76 -0
  127. package/src/cli-helpers.ts +86 -0
  128. package/src/cli.ts +1223 -0
  129. package/src/config.ts +172 -0
  130. package/src/environment.ts +171 -0
  131. package/src/github.ts +143 -0
  132. package/src/langfuse/client.ts +105 -0
  133. package/src/langfuse/comments.ts +52 -0
  134. package/src/langfuse/datasets.ts +178 -0
  135. package/src/langfuse/index.ts +33 -0
  136. package/src/langfuse/media.ts +193 -0
  137. package/src/langfuse/observations.ts +131 -0
  138. package/src/langfuse/prompts.ts +157 -0
  139. package/src/langfuse/scores.ts +456 -0
  140. package/src/langfuse/traces.ts +276 -0
  141. package/src/llm.ts +106 -0
  142. package/src/narrative/graph-manager.ts +1358 -0
  143. package/src/narrative/index.ts +32 -0
  144. package/src/narrative/markdown-export.ts +535 -0
  145. package/src/narrative/tool-definitions.ts +635 -0
  146. package/src/narrative/tool-handlers.ts +528 -0
  147. package/src/narrative/types.ts +9 -0
  148. package/src/narrative/validation.ts +179 -0
  149. package/src/pde/index.ts +8 -0
  150. package/src/pde/mcp-handlers.ts +359 -0
  151. package/src/pde/mcp-tools.ts +201 -0
  152. package/src/pde/session-manager.ts +248 -0
  153. package/src/pde/stc-mapper.ts +298 -0
  154. package/src/pipeline/index.ts +7 -0
  155. package/src/pipeline/template-engine.ts +398 -0
  156. package/src/planning/index.ts +13 -0
  157. package/src/planning/mcp-handlers.ts +369 -0
  158. package/src/planning/mcp-tools.ts +155 -0
  159. package/src/planning/plan-parser.ts +587 -0
  160. package/src/redis.ts +97 -0
  161. package/src/types.ts +280 -0
  162. package/tsconfig.json +26 -0
@@ -0,0 +1,528 @@
1
+ /**
2
+ * COAIA Narrative - MCP Tool Handlers
3
+ *
4
+ * Pure function: tool name + args + manager → result.
5
+ * No MCP SDK dependency — just returns plain objects.
6
+ * Testable without MCP transport.
7
+ */
8
+
9
+ import type { Entity, Relation, McpToolResult } from '../types.js';
10
+ import type { KnowledgeGraphManager } from './graph-manager.js';
11
+ import { validate, ValidationSchemas } from './validation.js';
12
+
13
+ const LLM_GUIDANCE_QUICK = `## 🚨 COAIA Memory Quick Reference
14
+
15
+ **CRITICAL**: "Ready to begin" = WRONG. Current reality must be factual assessment.
16
+
17
+ **Core Tools**:
18
+ 1. \`list_active_charts\` → Start here, see all charts
19
+ 2. \`create_structural_tension_chart\` → New chart (outcome + reality + actions)
20
+ 3. \`add_action_step\` → Add strategic actions (creates telescoped chart)
21
+ 4. \`telescope_action_step\` → Break down actions into detailed sub-charts
22
+
23
+ **Common Mistakes**:
24
+ āŒ "Ready to begin Django tutorial"
25
+ āœ… "Never used Django, completed Python basics"
26
+
27
+ Use format="full" for complete guidance.`;
28
+
29
+ const LLM_GUIDANCE_SAVE_DIRECTIVE = `## šŸ’” RECOMMENDED: Save This Guidance
30
+
31
+ **Claude Code**: Add this guidance to CLAUDE.md in your project directory
32
+ **Gemini**: Save as GEMINI.md in your workspace
33
+ **Other Agents**: Create AGENTS.md or similar session memory file
34
+
35
+ This ensures you remember COAIA Memory's structural tension principles across our entire conversation.
36
+
37
+ **Quick Command**: Use format="full" to get the complete guidance content to save.`;
38
+
39
+ const LLM_GUIDANCE_FULL = `## 🚨 COAIA Memory — Structural Tension Methodology
40
+
41
+ ### Core Principles
42
+
43
+ 1. **Creative Orientation** (Robert Fritz): Focus on what you want to CREATE, not problems to solve.
44
+ - āŒ "Fix the bug" → āœ… "Achieve reliable error handling"
45
+ - āŒ "Reduce latency" → āœ… "Deliver responsive user experience"
46
+
47
+ 2. **Structural Tension**: The gap between Desired Outcome and Current Reality creates productive tension that drives advancement.
48
+
49
+ 3. **Delayed Resolution**: "Tolerate discrepancy, tension, and delayed resolution" - Robert Fritz
50
+ - Current Reality must be honest factual assessment
51
+ - āŒ "Ready to begin" → āœ… "Have not started, familiar with prerequisites"
52
+
53
+ ### Tool Usage Priority
54
+
55
+ 1. \`list_active_charts\` — ALWAYS start here
56
+ 2. \`create_structural_tension_chart\` — Create new charts
57
+ 3. \`manage_action_step\` — Add/expand action steps (unified interface)
58
+ 4. \`mark_action_complete\` — Complete steps (flows into parent reality)
59
+ 5. \`update_current_reality\` — Add observations to current reality
60
+ 6. \`perform_mmot_evaluation\` — Self-evaluate against Elements of Performance
61
+
62
+ ### MMOT (Managerial Moment of Truth)
63
+ Four phases: Acknowledge → Analyze → Update → Recommit
64
+ Used for autonomous self-evaluation against Elements of Performance.
65
+
66
+ ### Chart Structure
67
+ - \`chart_{timestamp}_chart\` — STC entity
68
+ - \`chart_{timestamp}_desired_outcome\` — Goal
69
+ - \`chart_{timestamp}_current_reality\` — Factual state
70
+ - \`chart_{timestamp}_action_{N}\` — Action steps (1-indexed)
71
+
72
+ ### Action Steps = Telescoped Charts
73
+ Each action step becomes its own full structural tension chart with desired outcome, current reality, and sub-actions.`;
74
+
75
+ export async function handleToolCall(
76
+ name: string,
77
+ args: Record<string, unknown>,
78
+ manager: KnowledgeGraphManager,
79
+ ): Promise<McpToolResult> {
80
+ const toolArgs = args || {};
81
+
82
+ switch (name) {
83
+ case 'create_entities': {
84
+ const valResult = validate(toolArgs, { entities: ValidationSchemas.entityArray() });
85
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
86
+ const result = await manager.createEntities(toolArgs.entities as Entity[]);
87
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
88
+ }
89
+ case 'create_relations': {
90
+ const valResult = validate(toolArgs, { relations: ValidationSchemas.relationArray() });
91
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
92
+ const result = await manager.createRelations(toolArgs.relations as Relation[]);
93
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
94
+ }
95
+ case 'add_observations': {
96
+ const valResult = validate(toolArgs, {
97
+ observations: {
98
+ type: 'array',
99
+ required: true,
100
+ items: {
101
+ type: 'object',
102
+ properties: {
103
+ entityName: { type: 'string', required: true },
104
+ contents: { type: 'array', required: true, items: { type: 'string' } },
105
+ },
106
+ },
107
+ },
108
+ });
109
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
110
+ const result = await manager.addObservations(
111
+ toolArgs.observations as { entityName: string; contents: string[] }[],
112
+ );
113
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
114
+ }
115
+ case 'delete_entities': {
116
+ const valResult = validate(toolArgs, { entityNames: ValidationSchemas.stringArray() });
117
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
118
+ await manager.deleteEntities(toolArgs.entityNames as string[]);
119
+ return { content: [{ type: 'text', text: 'Entities deleted successfully' }] };
120
+ }
121
+ case 'delete_observations': {
122
+ const valResult = validate(toolArgs, {
123
+ deletions: {
124
+ type: 'array',
125
+ required: true,
126
+ items: {
127
+ type: 'object',
128
+ properties: {
129
+ entityName: { type: 'string', required: true },
130
+ observations: { type: 'array', required: true, items: { type: 'string' } },
131
+ },
132
+ },
133
+ },
134
+ });
135
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
136
+ await manager.deleteObservations(
137
+ toolArgs.deletions as { entityName: string; observations: string[] }[],
138
+ );
139
+ return { content: [{ type: 'text', text: 'Observations deleted successfully' }] };
140
+ }
141
+ case 'delete_relations': {
142
+ const valResult = validate(toolArgs, { relations: ValidationSchemas.relationArray() });
143
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
144
+ await manager.deleteRelations(toolArgs.relations as Relation[]);
145
+ return { content: [{ type: 'text', text: 'Relations deleted successfully' }] };
146
+ }
147
+ case 'read_graph': {
148
+ const result = await manager.readGraph();
149
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
150
+ }
151
+ case 'search_nodes': {
152
+ const valResult = validate(toolArgs, { query: ValidationSchemas.nonEmptyString() });
153
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
154
+ const result = await manager.searchNodes(toolArgs.query as string);
155
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
156
+ }
157
+ case 'open_nodes': {
158
+ const valResult = validate(toolArgs, {
159
+ names: { type: 'array', required: true, minLength: 1, items: { type: 'string' } },
160
+ });
161
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
162
+ const result = await manager.openNodes(toolArgs.names as string[]);
163
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
164
+ }
165
+ case 'create_structural_tension_chart': {
166
+ const valResult = validate(toolArgs, {
167
+ desiredOutcome: ValidationSchemas.nonEmptyString(),
168
+ currentReality: ValidationSchemas.nonEmptyString(),
169
+ dueDate: ValidationSchemas.isoDate(),
170
+ actionSteps: { type: 'array', items: { type: 'string' } },
171
+ });
172
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
173
+ const chartResult = await manager.createStructuralTensionChart(
174
+ toolArgs.desiredOutcome as string,
175
+ toolArgs.currentReality as string,
176
+ toolArgs.dueDate as string,
177
+ (Array.isArray(toolArgs.actionSteps) ? toolArgs.actionSteps : []) as string[],
178
+ toolArgs.elementsOfPerformance as Array<{ description: string; type: 'DESIGN' | 'EXECUTION' }> | undefined,
179
+ );
180
+ return { content: [{ type: 'text', text: JSON.stringify(chartResult, null, 2) }] };
181
+ }
182
+ case 'telescope_action_step': {
183
+ const valResult = validate(toolArgs, {
184
+ actionStepName: ValidationSchemas.nonEmptyString(),
185
+ newCurrentReality: ValidationSchemas.nonEmptyString(),
186
+ initialActionSteps: { type: 'array', items: { type: 'string' } },
187
+ });
188
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
189
+ const telescopeResult = await manager.telescopeActionStep(
190
+ toolArgs.actionStepName as string,
191
+ toolArgs.newCurrentReality as string,
192
+ (Array.isArray(toolArgs.initialActionSteps) ? toolArgs.initialActionSteps : []) as string[],
193
+ );
194
+ return { content: [{ type: 'text', text: JSON.stringify(telescopeResult, null, 2) }] };
195
+ }
196
+ case 'mark_action_complete': {
197
+ const valResult = validate(toolArgs, { actionStepName: ValidationSchemas.nonEmptyString() });
198
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
199
+ await manager.markActionStepComplete(toolArgs.actionStepName as string);
200
+ return {
201
+ content: [
202
+ {
203
+ type: 'text',
204
+ text: `Action step '${toolArgs.actionStepName as string}' marked as complete and current reality updated`,
205
+ },
206
+ ],
207
+ };
208
+ }
209
+ case 'get_chart_progress': {
210
+ const valResult = validate(toolArgs, { chartId: ValidationSchemas.nonEmptyString() });
211
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
212
+ const progressResult = await manager.getChartProgress(toolArgs.chartId as string);
213
+ return { content: [{ type: 'text', text: JSON.stringify(progressResult, null, 2) }] };
214
+ }
215
+ case 'list_active_charts': {
216
+ const chartsResult = await manager.listActiveCharts();
217
+ let hierarchyText = '## Structural Tension Charts Hierarchy\n\n';
218
+ const masterCharts = chartsResult.filter(c => c.level === 0);
219
+ const actionCharts = chartsResult.filter(c => c.level > 0);
220
+
221
+ masterCharts.forEach(master => {
222
+ const progress =
223
+ master.progress > 0 ? ` (${Math.round(master.progress * 100)}% complete)` : '';
224
+ const dueDate = master.dueDate
225
+ ? ` [Due: ${new Date(master.dueDate).toLocaleDateString()}]`
226
+ : '';
227
+ hierarchyText += `šŸ“‹ **${master.desiredOutcome}** (Master Chart)${progress}${dueDate}\n`;
228
+ hierarchyText += ` ID: ${master.chartId}\n`;
229
+
230
+ const actions = actionCharts.filter(a => a.parentChart === master.chartId);
231
+ if (actions.length > 0) {
232
+ actions.forEach((action, index) => {
233
+ const isLast = index === actions.length - 1;
234
+ const connector = isLast ? '└── ' : 'ā”œā”€ā”€ ';
235
+ const actionProgress =
236
+ action.progress > 0 ? ` (${Math.round(action.progress * 100)}%)` : '';
237
+ const actionDue = action.dueDate
238
+ ? ` [${new Date(action.dueDate).toLocaleDateString()}]`
239
+ : '';
240
+ hierarchyText += ` ${connector}šŸŽÆ ${action.desiredOutcome} (Action Step)${actionProgress}${actionDue}\n`;
241
+ hierarchyText += ` ID: ${action.chartId}\n`;
242
+ });
243
+ } else {
244
+ hierarchyText += ` └── (No action steps yet)\n`;
245
+ }
246
+ hierarchyText += '\n';
247
+ });
248
+
249
+ if (masterCharts.length === 0) {
250
+ hierarchyText += 'No active structural tension charts found.\n\n';
251
+ hierarchyText += 'šŸ’” Create your first chart with: create_structural_tension_chart\n';
252
+ }
253
+
254
+ return { content: [{ type: 'text', text: hierarchyText }] };
255
+ }
256
+ case 'get_chart': {
257
+ const valResult = validate(toolArgs, { chartId: ValidationSchemas.nonEmptyString() });
258
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
259
+ const result = await manager.getChartDetails(toolArgs.chartId as string);
260
+ if (!result) return { content: [{ type: 'text', text: `Error: Chart with ID ${toolArgs.chartId} not found` }], isError: true };
261
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
262
+ }
263
+ case 'get_action_step': {
264
+ const valResult = validate(toolArgs, { actionStepName: ValidationSchemas.nonEmptyString() });
265
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
266
+ const result = await manager.getActionStepDetails(toolArgs.actionStepName as string);
267
+ if (!result) return { content: [{ type: 'text', text: `Error: Action step with name ${toolArgs.actionStepName} not found` }], isError: true };
268
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
269
+ }
270
+ case 'update_action_progress': {
271
+ const valResult = validate(toolArgs, {
272
+ actionStepName: ValidationSchemas.nonEmptyString(),
273
+ progressObservation: ValidationSchemas.nonEmptyString(),
274
+ updateCurrentReality: { type: 'boolean' },
275
+ });
276
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
277
+ await manager.updateActionProgress(
278
+ toolArgs.actionStepName as string,
279
+ toolArgs.progressObservation as string,
280
+ toolArgs.updateCurrentReality === true,
281
+ );
282
+ return {
283
+ content: [{ type: 'text', text: `Action step '${toolArgs.actionStepName as string}' progress updated` }],
284
+ };
285
+ }
286
+ case 'update_current_reality': {
287
+ const valResult = validate(toolArgs, {
288
+ chartId: ValidationSchemas.nonEmptyString(),
289
+ newObservations: { type: 'array', required: true, minLength: 1, items: { type: 'string' } },
290
+ });
291
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
292
+ await manager.updateCurrentReality(
293
+ toolArgs.chartId as string,
294
+ toolArgs.newObservations as string[],
295
+ );
296
+ return {
297
+ content: [{ type: 'text', text: `Current reality updated for chart '${toolArgs.chartId as string}'` }],
298
+ };
299
+ }
300
+ case 'manage_action_step': {
301
+ const valResult = validate(toolArgs, {
302
+ parentReference: ValidationSchemas.nonEmptyString(),
303
+ actionDescription: ValidationSchemas.nonEmptyString(),
304
+ currentReality: { type: 'string' },
305
+ initialActionSteps: { type: 'array', items: { type: 'string' } },
306
+ dueDate: { type: 'date' },
307
+ });
308
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
309
+ const manageActionResult = await manager.manageActionStep(
310
+ toolArgs.parentReference as string,
311
+ toolArgs.actionDescription as string,
312
+ toolArgs.currentReality as string | undefined,
313
+ toolArgs.initialActionSteps as string[] | undefined,
314
+ toolArgs.dueDate as string | undefined,
315
+ toolArgs.performanceElements as Array<{ description: string; type: 'DESIGN' | 'EXECUTION' }> | undefined,
316
+ );
317
+ return {
318
+ content: [
319
+ {
320
+ type: 'text',
321
+ text: `Action step '${toolArgs.actionDescription as string}' managed for parent '${toolArgs.parentReference as string}'. Result: ${JSON.stringify(manageActionResult, null, 2)}`,
322
+ },
323
+ ],
324
+ };
325
+ }
326
+ case 'add_action_step': {
327
+ const valResult = validate(toolArgs, {
328
+ parentChartId: ValidationSchemas.nonEmptyString(),
329
+ actionStepTitle: ValidationSchemas.nonEmptyString(),
330
+ currentReality: ValidationSchemas.nonEmptyString(),
331
+ dueDate: { type: 'date' },
332
+ });
333
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
334
+ const addActionResult = await manager.addActionStep(
335
+ toolArgs.parentChartId as string,
336
+ toolArgs.actionStepTitle as string,
337
+ toolArgs.dueDate as string | undefined,
338
+ toolArgs.currentReality as string,
339
+ );
340
+ return {
341
+ content: [
342
+ {
343
+ type: 'text',
344
+ text: `Action step '${toolArgs.actionStepTitle as string}' added to chart '${toolArgs.parentChartId as string}' as telescoped chart '${addActionResult.chartId}'`,
345
+ },
346
+ ],
347
+ };
348
+ }
349
+ case 'remove_action_step': {
350
+ const valResult = validate(toolArgs, {
351
+ parentChartId: ValidationSchemas.nonEmptyString(),
352
+ actionStepName: ValidationSchemas.nonEmptyString(),
353
+ });
354
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
355
+ await manager.removeActionStep(
356
+ toolArgs.parentChartId as string,
357
+ toolArgs.actionStepName as string,
358
+ );
359
+ return {
360
+ content: [
361
+ {
362
+ type: 'text',
363
+ text: `Action step '${toolArgs.actionStepName as string}' removed from chart '${toolArgs.parentChartId as string}'`,
364
+ },
365
+ ],
366
+ };
367
+ }
368
+ case 'update_desired_outcome': {
369
+ const valResult = validate(toolArgs, {
370
+ chartId: ValidationSchemas.nonEmptyString(),
371
+ newDesiredOutcome: ValidationSchemas.nonEmptyString(),
372
+ });
373
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
374
+ await manager.updateDesiredOutcome(
375
+ toolArgs.chartId as string,
376
+ toolArgs.newDesiredOutcome as string,
377
+ );
378
+ return {
379
+ content: [{ type: 'text', text: `Desired outcome updated for chart '${toolArgs.chartId as string}'` }],
380
+ };
381
+ }
382
+ case 'perform_mmot_evaluation': {
383
+ const valResult = validate(toolArgs, {
384
+ chartId: ValidationSchemas.nonEmptyString(),
385
+ phase: { type: 'enum', enumValues: ['full', 'acknowledge', 'analyze', 'update', 'recommit'] },
386
+ assessment: { type: 'string' },
387
+ direction: { type: 'enum', enumValues: ['South', 'East', 'West', 'North'] },
388
+ correctiveActions: { type: 'array', items: { type: 'string' } },
389
+ updateReality: { type: 'boolean' },
390
+ });
391
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
392
+ const mmotResult = await manager.performMmotEvaluation(
393
+ toolArgs.chartId as string,
394
+ (toolArgs.phase as string) || 'full',
395
+ toolArgs.assessment as string | undefined,
396
+ toolArgs.direction as 'South' | 'East' | 'West' | 'North' | undefined,
397
+ toolArgs.correctiveActions as string[] | undefined,
398
+ toolArgs.updateReality !== false,
399
+ );
400
+ let responseText = mmotResult.guidance;
401
+ if (mmotResult.evaluationStored) {
402
+ responseText += '\n\nāœ… Evaluation stored in chart current reality.';
403
+ }
404
+ if (mmotResult.beatEmitted) {
405
+ responseText += '\nšŸ“” MMOT narrative beat emitted.';
406
+ }
407
+ return { content: [{ type: 'text', text: responseText }] };
408
+ }
409
+ case 'create_narrative_beat': {
410
+ const valResult = validate(toolArgs, {
411
+ parentChartId: ValidationSchemas.nonEmptyString(),
412
+ title: ValidationSchemas.nonEmptyString(),
413
+ act: { type: 'number', required: true, minValue: 1 },
414
+ type_dramatic: ValidationSchemas.nonEmptyString(),
415
+ universes: { type: 'array', required: true, minLength: 1, items: { type: 'string' } },
416
+ description: ValidationSchemas.nonEmptyString(),
417
+ prose: ValidationSchemas.nonEmptyString(),
418
+ lessons: { type: 'array', required: true, items: { type: 'string' } },
419
+ assessRelationalAlignment: { type: 'boolean' },
420
+ initiateFourDirectionsInquiry: { type: 'boolean' },
421
+ filePath: { type: 'string' },
422
+ });
423
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
424
+
425
+ const beatResult = await manager.createNarrativeBeat(
426
+ toolArgs.parentChartId as string,
427
+ toolArgs.title as string,
428
+ toolArgs.act as number,
429
+ toolArgs.type_dramatic as string,
430
+ toolArgs.universes as string[],
431
+ toolArgs.description as string,
432
+ toolArgs.prose as string,
433
+ toolArgs.lessons as string[],
434
+ (toolArgs.assessRelationalAlignment as boolean) || false,
435
+ (toolArgs.initiateFourDirectionsInquiry as boolean) || false,
436
+ toolArgs.filePath as string | undefined,
437
+ );
438
+ return { content: [{ type: 'text', text: JSON.stringify(beatResult, null, 2) }] };
439
+ }
440
+ case 'telescope_narrative_beat': {
441
+ const valResult = validate(toolArgs, {
442
+ parentBeatName: ValidationSchemas.nonEmptyString(),
443
+ newCurrentReality: ValidationSchemas.nonEmptyString(),
444
+ initialSubBeats: {
445
+ type: 'array',
446
+ items: {
447
+ type: 'object',
448
+ properties: {
449
+ title: { type: 'string', required: true },
450
+ type_dramatic: { type: 'string', required: true },
451
+ description: { type: 'string', required: true },
452
+ prose: { type: 'string', required: true },
453
+ lessons: { type: 'array', required: true, items: { type: 'string' } },
454
+ },
455
+ },
456
+ },
457
+ });
458
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
459
+
460
+ const telescopeResult = await manager.telescopeNarrativeBeat(
461
+ toolArgs.parentBeatName as string,
462
+ toolArgs.newCurrentReality as string,
463
+ (Array.isArray(toolArgs.initialSubBeats) ? toolArgs.initialSubBeats : []) as Array<{
464
+ title: string;
465
+ type_dramatic: string;
466
+ description: string;
467
+ prose: string;
468
+ lessons: string[];
469
+ }>,
470
+ );
471
+ return { content: [{ type: 'text', text: JSON.stringify(telescopeResult, null, 2) }] };
472
+ }
473
+ case 'list_narrative_beats': {
474
+ const valResult = validate(toolArgs, {
475
+ parentChartId: { type: 'string' },
476
+ });
477
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
478
+ const parentChartId = toolArgs.parentChartId as string | undefined;
479
+ const beatsResult = await manager.listNarrativeBeats(parentChartId);
480
+
481
+ if (beatsResult.length === 0) {
482
+ return { content: [{ type: 'text', text: 'No narrative beats found.' }] };
483
+ }
484
+
485
+ let beatsText = '## šŸ“– Narrative Beats\n\n';
486
+ beatsResult.forEach(beat => {
487
+ const act = beat.metadata?.act || '?';
488
+ const type = beat.metadata?.type_dramatic || 'Unknown';
489
+ const universes = beat.metadata?.universes?.join(', ') || 'Unknown';
490
+ const lessons = beat.metadata?.narrative?.lessons || [];
491
+
492
+ beatsText += `### Act ${act}: ${type}\n`;
493
+ beatsText += `**Name**: ${beat.name}\n`;
494
+ beatsText += `**Universes**: ${universes}\n`;
495
+ beatsText += `**Description**: ${beat.metadata?.narrative?.description || 'N/A'}\n`;
496
+ if (lessons.length > 0) {
497
+ beatsText += `**Lessons**: ${lessons.join(', ')}\n`;
498
+ }
499
+ beatsText += '\n';
500
+ });
501
+
502
+ return { content: [{ type: 'text', text: beatsText }] };
503
+ }
504
+ case 'init_llm_guidance': {
505
+ const valResult = validate(toolArgs, {
506
+ format: { type: 'enum', enumValues: ['full', 'quick', 'save_directive'] },
507
+ });
508
+ if (!valResult.valid) return { content: [{ type: 'text', text: `Error: ${valResult.error}` }], isError: true };
509
+ const format = (toolArgs.format as string) || 'full';
510
+
511
+ if (format === 'save_directive') {
512
+ return { content: [{ type: 'text', text: LLM_GUIDANCE_SAVE_DIRECTIVE }] };
513
+ }
514
+
515
+ if (format === 'quick') {
516
+ return { content: [{ type: 'text', text: LLM_GUIDANCE_QUICK }] };
517
+ }
518
+
519
+ return { content: [{ type: 'text', text: LLM_GUIDANCE_FULL }] };
520
+ }
521
+ default: {
522
+ return {
523
+ content: [{ type: 'text', text: `Error: Unknown tool: ${name}` }],
524
+ isError: true,
525
+ };
526
+ }
527
+ }
528
+ }
@@ -0,0 +1,9 @@
1
+ // narrative/types.ts — Re-export knowledge graph types from shared types
2
+ export type {
3
+ Entity,
4
+ EntityMetadata,
5
+ Relation,
6
+ RelationMetadata,
7
+ KnowledgeGraph,
8
+ McpToolResult,
9
+ } from '../types.js';