coaian 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +523 -0
- package/dist/generated-llm-guidance.d.ts +2 -0
- package/dist/generated-llm-guidance.js +498 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1879 -0
- package/dist/validation.d.ts +28 -0
- package/dist/validation.js +145 -0
- package/package.json +62 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1879 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { promises as fs } from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { LLM_GUIDANCE } from "./generated-llm-guidance.js";
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import minimist from 'minimist';
|
|
10
|
+
import { isAbsolute } from 'path';
|
|
11
|
+
import { validate, ValidationSchemas } from './validation.js';
|
|
12
|
+
// Parse args and handle paths safely
|
|
13
|
+
const argv = minimist(process.argv.slice(2));
|
|
14
|
+
// Handle help command
|
|
15
|
+
if (argv.help || argv.h) {
|
|
16
|
+
console.log(`
|
|
17
|
+
š§ COAIA Memory - Creative-Oriented AI Assistant Memory System v2.1.0
|
|
18
|
+
Based on Robert Fritz's Structural Tension methodology
|
|
19
|
+
|
|
20
|
+
DESCRIPTION:
|
|
21
|
+
MCP server that extends knowledge graphs with structural tension charts for
|
|
22
|
+
creative-oriented memory management. Supports advancing patterns, telescoping
|
|
23
|
+
charts, and natural language interaction for AI assistants.
|
|
24
|
+
|
|
25
|
+
USAGE:
|
|
26
|
+
coaia-memory [OPTIONS]
|
|
27
|
+
npx coaia-memory [OPTIONS]
|
|
28
|
+
|
|
29
|
+
OPTIONS:
|
|
30
|
+
--memory-path PATH Custom path for memory storage (default: ./memory.jsonl)
|
|
31
|
+
--help, -h Show this help message
|
|
32
|
+
|
|
33
|
+
ENVIRONMENT VARIABLES:
|
|
34
|
+
COAIA_TOOLS Comma or space separated list of tool groups and/or individual tools to enable
|
|
35
|
+
(default: "STC_TOOLS,init_llm_guidance")
|
|
36
|
+
|
|
37
|
+
COAIA_DISABLED_TOOLS Comma or space separated list of tools to disable
|
|
38
|
+
(useful for selectively removing tools from a group)
|
|
39
|
+
|
|
40
|
+
TOOL GROUPS:
|
|
41
|
+
STC_TOOLS All structural tension chart tools (11 tools) - recommended for creative work
|
|
42
|
+
KG_TOOLS All knowledge graph tools (9 tools) - for traditional entity/relation work
|
|
43
|
+
CORE_TOOLS Essential tools only (4 tools) - minimal viable set
|
|
44
|
+
|
|
45
|
+
EXAMPLES:
|
|
46
|
+
# Use only STC tools (default)
|
|
47
|
+
coaia-memory --memory-path ./memory.jsonl
|
|
48
|
+
|
|
49
|
+
# Enable both STC and KG tools
|
|
50
|
+
COAIA_TOOLS="STC_TOOLS KG_TOOLS" coaia-memory --memory-path ./memory.jsonl
|
|
51
|
+
|
|
52
|
+
# Use only core tools
|
|
53
|
+
COAIA_TOOLS="CORE_TOOLS" coaia-memory --memory-path ./memory.jsonl
|
|
54
|
+
|
|
55
|
+
# Enable STC tools but disable specific tools
|
|
56
|
+
COAIA_TOOLS="STC_TOOLS" COAIA_DISABLED_TOOLS="delete_entities,delete_relations" coaia-memory
|
|
57
|
+
|
|
58
|
+
# Enable specific individual tools
|
|
59
|
+
COAIA_TOOLS="create_structural_tension_chart add_action_step list_active_charts" coaia-memory
|
|
60
|
+
|
|
61
|
+
CORE FEATURES:
|
|
62
|
+
|
|
63
|
+
š Structural Tension Charts
|
|
64
|
+
⢠Create charts with desired outcomes, current reality, and action steps
|
|
65
|
+
⢠Automatic due date distribution for strategic timing
|
|
66
|
+
⢠Progress tracking and completion monitoring
|
|
67
|
+
|
|
68
|
+
š Telescoping Support
|
|
69
|
+
⢠Break down action steps into detailed sub-charts
|
|
70
|
+
⢠Proper due date inheritance from parent steps
|
|
71
|
+
⢠Navigate between overview and details seamlessly
|
|
72
|
+
|
|
73
|
+
š Advancing Patterns
|
|
74
|
+
⢠Completed actions flow into current reality automatically
|
|
75
|
+
⢠Success builds momentum for continued advancement
|
|
76
|
+
⢠Prevents oscillating patterns through structural awareness
|
|
77
|
+
|
|
78
|
+
MCP TOOLS AVAILABLE:
|
|
79
|
+
|
|
80
|
+
Chart Management (Common Workflow):
|
|
81
|
+
⢠list_active_charts - START HERE: See all charts and their progress
|
|
82
|
+
⢠add_action_step - Add strategic actions to existing charts
|
|
83
|
+
⢠telescope_action_step - Break down action steps into detailed sub-charts
|
|
84
|
+
⢠update_action_progress - Track progress without completing actions
|
|
85
|
+
⢠mark_action_complete - Complete actions & update reality
|
|
86
|
+
⢠update_current_reality - Add observations directly to current reality
|
|
87
|
+
⢠create_structural_tension_chart - Create new chart with outcome & reality
|
|
88
|
+
|
|
89
|
+
Chart Analysis (Advanced):
|
|
90
|
+
⢠get_chart_progress - Detailed progress (redundant after list_active_charts)
|
|
91
|
+
⢠open_nodes - Inspect specific chart components by exact name
|
|
92
|
+
⢠read_graph - Dump all data (rarely needed)
|
|
93
|
+
|
|
94
|
+
Knowledge Graph (Traditional):
|
|
95
|
+
⢠create_entities - Add entities (people, concepts, events)
|
|
96
|
+
⢠create_relations - Connect entities with relationships
|
|
97
|
+
⢠add_observations - Record information about entities
|
|
98
|
+
⢠search_nodes - Search across all stored information
|
|
99
|
+
⢠read_graph - Export complete graph structure
|
|
100
|
+
|
|
101
|
+
EXAMPLE USAGE:
|
|
102
|
+
|
|
103
|
+
# Start with custom memory path
|
|
104
|
+
coaia-memory --memory-path /path/to/my-charts.jsonl
|
|
105
|
+
|
|
106
|
+
# Use in Claude Desktop (add to claude_desktop_config.json):
|
|
107
|
+
{
|
|
108
|
+
"mcpServers": {
|
|
109
|
+
"coaia-memory": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["-y", "coaia-memory", "--memory-path", "./charts.jsonl"]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
NATURAL LANGUAGE PATTERNS:
|
|
117
|
+
|
|
118
|
+
Creating Charts:
|
|
119
|
+
"I want to create a mobile app in 3 months"
|
|
120
|
+
"My desired outcome is to establish a morning routine"
|
|
121
|
+
|
|
122
|
+
Progress Tracking:
|
|
123
|
+
"I completed the research phase yesterday"
|
|
124
|
+
"Show me progress on my Python learning goal"
|
|
125
|
+
|
|
126
|
+
Telescoping:
|
|
127
|
+
"Break down the Django tutorial step further"
|
|
128
|
+
"I need more detail on the deployment action"
|
|
129
|
+
|
|
130
|
+
CREATIVE ORIENTATION PRINCIPLES:
|
|
131
|
+
|
|
132
|
+
ā
Focus on Creation (not problem-solving):
|
|
133
|
+
⢠"I want to create..." vs "I need to fix..."
|
|
134
|
+
⢠"My desired outcome..." vs "The problem is..."
|
|
135
|
+
|
|
136
|
+
ā
Structural Tension Awareness:
|
|
137
|
+
⢠Always pair desired outcomes with current reality
|
|
138
|
+
⢠Honest assessment creates productive tension
|
|
139
|
+
⢠Action steps are strategic secondary action we choose todo to achive the primary goal
|
|
140
|
+
|
|
141
|
+
ā
Advancing Patterns:
|
|
142
|
+
⢠Success builds on success
|
|
143
|
+
⢠Completed actions become part of current reality
|
|
144
|
+
⢠Momentum creates natural progression toward goals
|
|
145
|
+
|
|
146
|
+
PHILOSOPHY:
|
|
147
|
+
COAIA Memory recognizes that structure determines behavior. By organizing
|
|
148
|
+
memory around structural tension rather than problem-solving patterns, it
|
|
149
|
+
naturally forms a structure that advances and helps build, not just the life you want, but the technologies to supports it's manifestation (hopefully!).
|
|
150
|
+
|
|
151
|
+
CREDITS:
|
|
152
|
+
⢠Author: J.Guillaume D.-Isabelle <jgi@jgwill.com>
|
|
153
|
+
⢠Methodology: Robert Fritz - https://robertfritz.com
|
|
154
|
+
⢠Foundation: Shane Holloman (original mcp-knowledge-graph)
|
|
155
|
+
⢠License: MIT
|
|
156
|
+
|
|
157
|
+
For more information, see: CLAUDE.md in the package directory
|
|
158
|
+
`);
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
let memoryPath = argv['memory-path'];
|
|
162
|
+
// If a custom path is provided, ensure it's absolute
|
|
163
|
+
if (memoryPath && !isAbsolute(memoryPath)) {
|
|
164
|
+
memoryPath = path.resolve(process.cwd(), memoryPath);
|
|
165
|
+
}
|
|
166
|
+
// Tool filtering configuration
|
|
167
|
+
const TOOL_GROUPS = {
|
|
168
|
+
STC_TOOLS: [
|
|
169
|
+
'create_structural_tension_chart',
|
|
170
|
+
'telescope_action_step',
|
|
171
|
+
'add_action_step',
|
|
172
|
+
'remove_action_step',
|
|
173
|
+
'mark_action_complete',
|
|
174
|
+
'get_chart_progress',
|
|
175
|
+
'list_active_charts',
|
|
176
|
+
'update_action_progress',
|
|
177
|
+
'update_current_reality',
|
|
178
|
+
'update_desired_outcome',
|
|
179
|
+
'creator_moment_of_truth'
|
|
180
|
+
],
|
|
181
|
+
NARRATIVE_TOOLS: [
|
|
182
|
+
'create_narrative_beat',
|
|
183
|
+
'telescope_narrative_beat',
|
|
184
|
+
'list_narrative_beats'
|
|
185
|
+
],
|
|
186
|
+
KG_TOOLS: [
|
|
187
|
+
'create_entities',
|
|
188
|
+
'create_relations',
|
|
189
|
+
'add_observations',
|
|
190
|
+
'delete_entities',
|
|
191
|
+
'delete_observations',
|
|
192
|
+
'delete_relations',
|
|
193
|
+
'search_nodes',
|
|
194
|
+
'open_nodes',
|
|
195
|
+
'read_graph'
|
|
196
|
+
],
|
|
197
|
+
CORE_TOOLS: [
|
|
198
|
+
'list_active_charts',
|
|
199
|
+
'create_structural_tension_chart',
|
|
200
|
+
'add_action_step',
|
|
201
|
+
'mark_action_complete'
|
|
202
|
+
]
|
|
203
|
+
};
|
|
204
|
+
function getEnabledTools() {
|
|
205
|
+
const enabledTools = new Set();
|
|
206
|
+
// Check for COAIA_DISABLED_TOOLS env var (comma or space separated)
|
|
207
|
+
const disabledStr = process.env.COAIA_DISABLED_TOOLS || '';
|
|
208
|
+
const disabledTools = new Set(disabledStr.split(/[,\s]+/).filter(t => t.trim()));
|
|
209
|
+
// Determine which tools to enable
|
|
210
|
+
const enabledGroupsStr = process.env.COAIA_TOOLS || 'STC_TOOLS,NARRATIVE_TOOLS,init_llm_guidance';
|
|
211
|
+
const enabledGroups = enabledGroupsStr.split(/[,\s]+/).filter(t => t.trim());
|
|
212
|
+
enabledGroups.forEach(group => {
|
|
213
|
+
const groupTools = TOOL_GROUPS[group];
|
|
214
|
+
if (groupTools) {
|
|
215
|
+
groupTools.forEach(tool => enabledTools.add(tool));
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// Assume it's an individual tool name
|
|
219
|
+
enabledTools.add(group);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
// Remove disabled tools
|
|
223
|
+
disabledTools.forEach(tool => enabledTools.delete(tool));
|
|
224
|
+
return enabledTools;
|
|
225
|
+
}
|
|
226
|
+
// Define the path to the JSONL file
|
|
227
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
228
|
+
// Use the custom path or default to the installation directory
|
|
229
|
+
const MEMORY_FILE_PATH = memoryPath || path.join(__dirname, 'memory.jsonl');
|
|
230
|
+
// The KnowledgeGraphManager class contains all operations to interact with the knowledge graph
|
|
231
|
+
class KnowledgeGraphManager {
|
|
232
|
+
async loadGraph() {
|
|
233
|
+
try {
|
|
234
|
+
const data = await fs.readFile(MEMORY_FILE_PATH, "utf-8");
|
|
235
|
+
const lines = data.split("\n").filter(line => line.trim() !== "");
|
|
236
|
+
return lines.reduce((graph, line) => {
|
|
237
|
+
const item = JSON.parse(line);
|
|
238
|
+
if (item.type === "entity")
|
|
239
|
+
graph.entities.push(item);
|
|
240
|
+
if (item.type === "relation")
|
|
241
|
+
graph.relations.push(item);
|
|
242
|
+
// Support narrative_beat entities (convert to entity format)
|
|
243
|
+
if (item.type === "narrative_beat") {
|
|
244
|
+
const narrativeBeat = {
|
|
245
|
+
name: item.name,
|
|
246
|
+
entityType: 'narrative_beat',
|
|
247
|
+
observations: item.observations || [],
|
|
248
|
+
metadata: {
|
|
249
|
+
...item.metadata,
|
|
250
|
+
narrative: item.narrative,
|
|
251
|
+
relationalAlignment: item.relational_alignment,
|
|
252
|
+
fourDirections: item.four_directions
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
graph.entities.push(narrativeBeat);
|
|
256
|
+
}
|
|
257
|
+
return graph;
|
|
258
|
+
}, { entities: [], relations: [] });
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
if (error instanceof Error && 'code' in error && error.code === "ENOENT") {
|
|
262
|
+
return { entities: [], relations: [] };
|
|
263
|
+
}
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Helper function to extract current reality from user context
|
|
268
|
+
// Maintains structural tension by requiring explicit assessment
|
|
269
|
+
extractCurrentRealityFromContext(userInput, actionStepTitle) {
|
|
270
|
+
// Common patterns that indicate current reality assessment
|
|
271
|
+
const realityPatterns = [
|
|
272
|
+
/(?:currently|right now|at present|today)\s+(.{10,})/i,
|
|
273
|
+
/(?:i am|we are|the situation is)\s+(.{10,})/i,
|
|
274
|
+
/(?:i have|we have|there is|there are)\s+(.{10,})/i,
|
|
275
|
+
/(?:my current|our current|the current)\s+(.{10,})/i
|
|
276
|
+
];
|
|
277
|
+
for (const pattern of realityPatterns) {
|
|
278
|
+
const match = userInput.match(pattern);
|
|
279
|
+
if (match && match[1]) {
|
|
280
|
+
return match[1].trim();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// If no explicit current reality found, require assessment
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
async saveGraph(graph) {
|
|
287
|
+
const lines = [
|
|
288
|
+
...graph.entities.map(e => JSON.stringify({ type: "entity", ...e })),
|
|
289
|
+
...graph.relations.map(r => JSON.stringify({ type: "relation", ...r })),
|
|
290
|
+
];
|
|
291
|
+
await fs.writeFile(MEMORY_FILE_PATH, lines.join("\n"));
|
|
292
|
+
}
|
|
293
|
+
async createEntities(entities) {
|
|
294
|
+
const graph = await this.loadGraph();
|
|
295
|
+
const newEntities = entities.filter(e => !graph.entities.some(existingEntity => existingEntity.name === e.name));
|
|
296
|
+
graph.entities.push(...newEntities);
|
|
297
|
+
await this.saveGraph(graph);
|
|
298
|
+
return newEntities;
|
|
299
|
+
}
|
|
300
|
+
async createRelations(relations) {
|
|
301
|
+
const graph = await this.loadGraph();
|
|
302
|
+
const newRelations = relations.filter(r => !graph.relations.some(existingRelation => existingRelation.from === r.from &&
|
|
303
|
+
existingRelation.to === r.to &&
|
|
304
|
+
existingRelation.relationType === r.relationType));
|
|
305
|
+
graph.relations.push(...newRelations);
|
|
306
|
+
await this.saveGraph(graph);
|
|
307
|
+
return newRelations;
|
|
308
|
+
}
|
|
309
|
+
async addObservations(observations) {
|
|
310
|
+
const graph = await this.loadGraph();
|
|
311
|
+
const results = observations.map(o => {
|
|
312
|
+
const entity = graph.entities.find(e => e.name === o.entityName);
|
|
313
|
+
if (!entity) {
|
|
314
|
+
throw new Error(`Entity with name ${o.entityName} not found`);
|
|
315
|
+
}
|
|
316
|
+
const newObservations = o.contents.filter(content => !entity.observations.includes(content));
|
|
317
|
+
entity.observations.push(...newObservations);
|
|
318
|
+
return { entityName: o.entityName, addedObservations: newObservations };
|
|
319
|
+
});
|
|
320
|
+
await this.saveGraph(graph);
|
|
321
|
+
return results;
|
|
322
|
+
}
|
|
323
|
+
async deleteEntities(entityNames) {
|
|
324
|
+
const graph = await this.loadGraph();
|
|
325
|
+
graph.entities = graph.entities.filter(e => !entityNames.includes(e.name));
|
|
326
|
+
graph.relations = graph.relations.filter(r => !entityNames.includes(r.from) && !entityNames.includes(r.to));
|
|
327
|
+
await this.saveGraph(graph);
|
|
328
|
+
}
|
|
329
|
+
async deleteObservations(deletions) {
|
|
330
|
+
const graph = await this.loadGraph();
|
|
331
|
+
deletions.forEach(d => {
|
|
332
|
+
const entity = graph.entities.find(e => e.name === d.entityName);
|
|
333
|
+
if (entity) {
|
|
334
|
+
entity.observations = entity.observations.filter(o => !d.observations.includes(o));
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
await this.saveGraph(graph);
|
|
338
|
+
}
|
|
339
|
+
async deleteRelations(relations) {
|
|
340
|
+
const graph = await this.loadGraph();
|
|
341
|
+
graph.relations = graph.relations.filter(r => !relations.some(delRelation => r.from === delRelation.from &&
|
|
342
|
+
r.to === delRelation.to &&
|
|
343
|
+
r.relationType === delRelation.relationType));
|
|
344
|
+
await this.saveGraph(graph);
|
|
345
|
+
}
|
|
346
|
+
async readGraph() {
|
|
347
|
+
return this.loadGraph();
|
|
348
|
+
}
|
|
349
|
+
// Very basic search function
|
|
350
|
+
async searchNodes(query) {
|
|
351
|
+
const graph = await this.loadGraph();
|
|
352
|
+
// Filter entities
|
|
353
|
+
const filteredEntities = graph.entities.filter(e => e.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
354
|
+
e.entityType.toLowerCase().includes(query.toLowerCase()) ||
|
|
355
|
+
e.observations.some(o => o.toLowerCase().includes(query.toLowerCase())));
|
|
356
|
+
// Create a Set of filtered entity names for quick lookup
|
|
357
|
+
const filteredEntityNames = new Set(filteredEntities.map(e => e.name));
|
|
358
|
+
// Filter relations to only include those between filtered entities
|
|
359
|
+
const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
|
|
360
|
+
const filteredGraph = {
|
|
361
|
+
entities: filteredEntities,
|
|
362
|
+
relations: filteredRelations,
|
|
363
|
+
};
|
|
364
|
+
return filteredGraph;
|
|
365
|
+
}
|
|
366
|
+
async openNodes(names) {
|
|
367
|
+
const graph = await this.loadGraph();
|
|
368
|
+
// Filter entities
|
|
369
|
+
const filteredEntities = graph.entities.filter(e => names.includes(e.name));
|
|
370
|
+
// Create a Set of filtered entity names for quick lookup
|
|
371
|
+
const filteredEntityNames = new Set(filteredEntities.map(e => e.name));
|
|
372
|
+
// Filter relations to only include those between filtered entities
|
|
373
|
+
const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
|
|
374
|
+
const filteredGraph = {
|
|
375
|
+
entities: filteredEntities,
|
|
376
|
+
relations: filteredRelations,
|
|
377
|
+
};
|
|
378
|
+
return filteredGraph;
|
|
379
|
+
}
|
|
380
|
+
// COAIA-specific methods for structural tension charts and creative processes
|
|
381
|
+
async createStructuralTensionChart(desiredOutcome, currentReality, dueDate, actionSteps) {
|
|
382
|
+
// Educational validation for creative orientation
|
|
383
|
+
const problemSolvingWords = ['fix', 'solve', 'eliminate', 'prevent', 'stop', 'avoid', 'reduce', 'remove'];
|
|
384
|
+
const detectedProblemWords = problemSolvingWords.filter(word => desiredOutcome.toLowerCase().includes(word));
|
|
385
|
+
if (detectedProblemWords.length > 0) {
|
|
386
|
+
throw new Error(`š CREATIVE ORIENTATION REQUIRED
|
|
387
|
+
|
|
388
|
+
Desired Outcome: "${desiredOutcome}"
|
|
389
|
+
|
|
390
|
+
ā **Problem**: Contains problem-solving language: "${detectedProblemWords.join(', ')}"
|
|
391
|
+
š **Principle**: Structural Tension Charts use creative orientation - focus on what you want to CREATE, not what you want to eliminate.
|
|
392
|
+
|
|
393
|
+
šÆ **Reframe Your Outcome**:
|
|
394
|
+
Instead of elimination ā Creation focus
|
|
395
|
+
|
|
396
|
+
ā
**Examples**:
|
|
397
|
+
- Instead of: "Fix communication problems"
|
|
398
|
+
- Use: "Establish clear, effective communication practices"
|
|
399
|
+
|
|
400
|
+
- Instead of: "Reduce website loading time"
|
|
401
|
+
- Use: "Achieve fast, responsive website performance"
|
|
402
|
+
|
|
403
|
+
**Why This Matters**: Problem-solving creates oscillating patterns. Creative orientation creates advancing patterns toward desired outcomes.
|
|
404
|
+
|
|
405
|
+
š” **Tip**: Run 'init_llm_guidance' for complete methodology overview.`);
|
|
406
|
+
}
|
|
407
|
+
// Educational validation for current reality
|
|
408
|
+
const readinessWords = ['ready to', 'prepared to', 'all set', 'ready for', 'set to'];
|
|
409
|
+
const detectedReadinessWords = readinessWords.filter(phrase => currentReality.toLowerCase().includes(phrase));
|
|
410
|
+
if (detectedReadinessWords.length > 0) {
|
|
411
|
+
throw new Error(`š DELAYED RESOLUTION PRINCIPLE VIOLATION
|
|
412
|
+
|
|
413
|
+
Current Reality: "${currentReality}"
|
|
414
|
+
|
|
415
|
+
ā **Problem**: Contains readiness assumptions: "${detectedReadinessWords.join(', ')}"
|
|
416
|
+
š **Principle**: "Tolerate discrepancy, tension, and delayed resolution" - Robert Fritz
|
|
417
|
+
|
|
418
|
+
šÆ **What's Needed**: Factual assessment of your actual current state (not readiness or preparation).
|
|
419
|
+
|
|
420
|
+
ā
**Examples**:
|
|
421
|
+
- Instead of: "Ready to learn Python"
|
|
422
|
+
- Use: "Never programmed before, interested in web development"
|
|
423
|
+
|
|
424
|
+
- Instead of: "Prepared to start the project"
|
|
425
|
+
- Use: "Have project requirements, no code written yet"
|
|
426
|
+
|
|
427
|
+
**Why This Matters**: Readiness assumptions prematurely resolve the structural tension needed for creative advancement.
|
|
428
|
+
|
|
429
|
+
š” **Tip**: Run 'init_llm_guidance' for complete methodology overview.`);
|
|
430
|
+
}
|
|
431
|
+
const chartId = `chart_${Date.now()}`;
|
|
432
|
+
const timestamp = new Date().toISOString();
|
|
433
|
+
// Create chart, desired outcome, and current reality entities
|
|
434
|
+
const entities = [
|
|
435
|
+
{
|
|
436
|
+
name: `${chartId}_chart`,
|
|
437
|
+
entityType: 'structural_tension_chart',
|
|
438
|
+
observations: [`Chart created on ${timestamp}`],
|
|
439
|
+
metadata: {
|
|
440
|
+
chartId,
|
|
441
|
+
dueDate,
|
|
442
|
+
level: 0,
|
|
443
|
+
createdAt: timestamp,
|
|
444
|
+
updatedAt: timestamp
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: `${chartId}_desired_outcome`,
|
|
449
|
+
entityType: 'desired_outcome',
|
|
450
|
+
observations: [desiredOutcome],
|
|
451
|
+
metadata: {
|
|
452
|
+
chartId,
|
|
453
|
+
dueDate,
|
|
454
|
+
createdAt: timestamp,
|
|
455
|
+
updatedAt: timestamp
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
name: `${chartId}_current_reality`,
|
|
460
|
+
entityType: 'current_reality',
|
|
461
|
+
observations: [currentReality],
|
|
462
|
+
metadata: {
|
|
463
|
+
chartId,
|
|
464
|
+
createdAt: timestamp,
|
|
465
|
+
updatedAt: timestamp
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
];
|
|
469
|
+
// Add action steps if provided
|
|
470
|
+
if (actionSteps && actionSteps.length > 0) {
|
|
471
|
+
const stepDueDates = this.distributeActionStepDates(new Date(), new Date(dueDate), actionSteps.length);
|
|
472
|
+
actionSteps.forEach((step, index) => {
|
|
473
|
+
entities.push({
|
|
474
|
+
name: `${chartId}_action_${index + 1}`,
|
|
475
|
+
entityType: 'action_step',
|
|
476
|
+
observations: [step],
|
|
477
|
+
metadata: {
|
|
478
|
+
chartId,
|
|
479
|
+
dueDate: stepDueDates[index].toISOString(),
|
|
480
|
+
completionStatus: false,
|
|
481
|
+
createdAt: timestamp,
|
|
482
|
+
updatedAt: timestamp
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
// Create relations
|
|
488
|
+
const relations = [
|
|
489
|
+
{
|
|
490
|
+
from: `${chartId}_chart`,
|
|
491
|
+
to: `${chartId}_desired_outcome`,
|
|
492
|
+
relationType: 'contains',
|
|
493
|
+
metadata: { createdAt: timestamp }
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
from: `${chartId}_chart`,
|
|
497
|
+
to: `${chartId}_current_reality`,
|
|
498
|
+
relationType: 'contains',
|
|
499
|
+
metadata: { createdAt: timestamp }
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
from: `${chartId}_current_reality`,
|
|
503
|
+
to: `${chartId}_desired_outcome`,
|
|
504
|
+
relationType: 'creates_tension_with',
|
|
505
|
+
metadata: { createdAt: timestamp }
|
|
506
|
+
}
|
|
507
|
+
];
|
|
508
|
+
// Add action step relations
|
|
509
|
+
if (actionSteps && actionSteps.length > 0) {
|
|
510
|
+
actionSteps.forEach((_, index) => {
|
|
511
|
+
const actionName = `${chartId}_action_${index + 1}`;
|
|
512
|
+
relations.push({
|
|
513
|
+
from: `${chartId}_chart`,
|
|
514
|
+
to: actionName,
|
|
515
|
+
relationType: 'contains',
|
|
516
|
+
metadata: { createdAt: timestamp }
|
|
517
|
+
}, {
|
|
518
|
+
from: actionName,
|
|
519
|
+
to: `${chartId}_desired_outcome`,
|
|
520
|
+
relationType: 'advances_toward',
|
|
521
|
+
metadata: { createdAt: timestamp }
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
// Save to graph
|
|
526
|
+
await this.createEntities(entities);
|
|
527
|
+
await this.createRelations(relations);
|
|
528
|
+
return { chartId, entities, relations };
|
|
529
|
+
}
|
|
530
|
+
async telescopeActionStep(actionStepName, newCurrentReality, initialActionSteps) {
|
|
531
|
+
const graph = await this.loadGraph();
|
|
532
|
+
const actionStep = graph.entities.find(e => e.name === actionStepName && e.entityType === 'action_step');
|
|
533
|
+
if (!actionStep || !actionStep.metadata?.chartId) {
|
|
534
|
+
throw new Error(`Action step ${actionStepName} not found or not properly configured`);
|
|
535
|
+
}
|
|
536
|
+
const parentChartId = actionStep.metadata.chartId;
|
|
537
|
+
const inheritedDueDate = actionStep.metadata.dueDate || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
538
|
+
const desiredOutcome = actionStep.observations[0]; // Use the action step description as the new desired outcome
|
|
539
|
+
const result = await this.createStructuralTensionChart(desiredOutcome, newCurrentReality, inheritedDueDate, initialActionSteps);
|
|
540
|
+
// Update the new chart's metadata to reflect telescoping relationship
|
|
541
|
+
const newChart = await this.loadGraph();
|
|
542
|
+
const chartEntity = newChart.entities.find(e => e.name === `${result.chartId}_chart`);
|
|
543
|
+
if (chartEntity && chartEntity.metadata) {
|
|
544
|
+
chartEntity.metadata.parentChart = parentChartId;
|
|
545
|
+
chartEntity.metadata.parentActionStep = actionStepName;
|
|
546
|
+
chartEntity.metadata.level = (actionStep.metadata.level || 0) + 1;
|
|
547
|
+
chartEntity.metadata.updatedAt = new Date().toISOString();
|
|
548
|
+
}
|
|
549
|
+
await this.saveGraph(newChart);
|
|
550
|
+
return { chartId: result.chartId, parentChart: parentChartId };
|
|
551
|
+
}
|
|
552
|
+
async markActionStepComplete(actionStepName) {
|
|
553
|
+
const graph = await this.loadGraph();
|
|
554
|
+
// An "action step" can be a 'desired_outcome' of a sub-chart, or a simple 'action_step' entity.
|
|
555
|
+
const actionStep = graph.entities.find(e => e.name === actionStepName && (e.entityType === 'action_step' || e.entityType === 'desired_outcome'));
|
|
556
|
+
if (!actionStep) {
|
|
557
|
+
throw new Error(`Action step ${actionStepName} not found`);
|
|
558
|
+
}
|
|
559
|
+
const chartId = actionStep.metadata?.chartId;
|
|
560
|
+
if (!chartId) {
|
|
561
|
+
throw new Error(`Chart ID not found for action step ${actionStepName}`);
|
|
562
|
+
}
|
|
563
|
+
// Mark the action step itself as complete
|
|
564
|
+
if (actionStep.metadata) {
|
|
565
|
+
actionStep.metadata.completionStatus = true;
|
|
566
|
+
actionStep.metadata.updatedAt = new Date().toISOString();
|
|
567
|
+
}
|
|
568
|
+
// Also mark the parent chart entity as complete
|
|
569
|
+
const chartEntity = graph.entities.find(e => e.name === `${chartId}_chart`);
|
|
570
|
+
if (chartEntity && chartEntity.metadata) {
|
|
571
|
+
chartEntity.metadata.completionStatus = true;
|
|
572
|
+
chartEntity.metadata.updatedAt = new Date().toISOString();
|
|
573
|
+
}
|
|
574
|
+
// Structural tension principle: completed action steps flow into the CURRENT REALITY
|
|
575
|
+
// of the PARENT chart, advancing the overall structure.
|
|
576
|
+
const parentChartId = chartEntity?.metadata?.parentChart;
|
|
577
|
+
if (parentChartId) {
|
|
578
|
+
const parentCurrentReality = graph.entities.find(e => e.name === `${parentChartId}_current_reality` &&
|
|
579
|
+
e.entityType === 'current_reality');
|
|
580
|
+
if (parentCurrentReality) {
|
|
581
|
+
const completionMessage = `Completed: ${actionStep.observations[0]}`;
|
|
582
|
+
if (!parentCurrentReality.observations.includes(completionMessage)) {
|
|
583
|
+
parentCurrentReality.observations.push(completionMessage);
|
|
584
|
+
if (parentCurrentReality.metadata) {
|
|
585
|
+
parentCurrentReality.metadata.updatedAt = new Date().toISOString();
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
await this.saveGraph(graph);
|
|
591
|
+
}
|
|
592
|
+
async getChartProgress(chartId) {
|
|
593
|
+
const graph = await this.loadGraph();
|
|
594
|
+
const actionSteps = graph.entities.filter(e => e.entityType === 'action_step' &&
|
|
595
|
+
e.metadata?.chartId === chartId);
|
|
596
|
+
const completedActions = actionSteps.filter(e => e.metadata?.completionStatus === true).length;
|
|
597
|
+
const totalActions = actionSteps.length;
|
|
598
|
+
const progress = totalActions > 0 ? completedActions / totalActions : 0;
|
|
599
|
+
// Find next incomplete action step with earliest due date
|
|
600
|
+
const incompleteActions = actionSteps
|
|
601
|
+
.filter(e => e.metadata?.completionStatus !== true)
|
|
602
|
+
.sort((a, b) => {
|
|
603
|
+
const dateA = new Date(a.metadata?.dueDate || '').getTime();
|
|
604
|
+
const dateB = new Date(b.metadata?.dueDate || '').getTime();
|
|
605
|
+
return dateA - dateB;
|
|
606
|
+
});
|
|
607
|
+
const chart = graph.entities.find(e => e.name === `${chartId}_chart`);
|
|
608
|
+
return {
|
|
609
|
+
chartId,
|
|
610
|
+
progress,
|
|
611
|
+
completedActions,
|
|
612
|
+
totalActions,
|
|
613
|
+
nextAction: incompleteActions[0]?.name,
|
|
614
|
+
dueDate: chart?.metadata?.dueDate
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
distributeActionStepDates(startDate, endDate, stepCount) {
|
|
618
|
+
const totalTime = endDate.getTime() - startDate.getTime();
|
|
619
|
+
const stepInterval = totalTime / (stepCount + 1); // +1 to leave space before final due date
|
|
620
|
+
const dates = [];
|
|
621
|
+
for (let i = 1; i <= stepCount; i++) {
|
|
622
|
+
dates.push(new Date(startDate.getTime() + (stepInterval * i)));
|
|
623
|
+
}
|
|
624
|
+
return dates;
|
|
625
|
+
}
|
|
626
|
+
async listActiveCharts() {
|
|
627
|
+
const graph = await this.loadGraph();
|
|
628
|
+
const charts = graph.entities.filter(e => e.entityType === 'structural_tension_chart');
|
|
629
|
+
const chartSummaries = await Promise.all(charts.map(async (chart) => {
|
|
630
|
+
const chartId = chart.metadata?.chartId || chart.name.replace('_chart', '');
|
|
631
|
+
const progress = await this.getChartProgress(chartId);
|
|
632
|
+
// Get desired outcome
|
|
633
|
+
const desiredOutcome = graph.entities.find(e => e.name === `${chartId}_desired_outcome` && e.entityType === 'desired_outcome');
|
|
634
|
+
return {
|
|
635
|
+
chartId,
|
|
636
|
+
desiredOutcome: desiredOutcome?.observations[0] || 'Unknown outcome',
|
|
637
|
+
dueDate: chart.metadata?.dueDate,
|
|
638
|
+
progress: progress.progress,
|
|
639
|
+
completedActions: progress.completedActions,
|
|
640
|
+
totalActions: progress.totalActions,
|
|
641
|
+
level: chart.metadata?.level || 0,
|
|
642
|
+
parentChart: chart.metadata?.parentChart
|
|
643
|
+
};
|
|
644
|
+
}));
|
|
645
|
+
return chartSummaries.sort((a, b) => {
|
|
646
|
+
// Sort by level first (master charts first), then by due date
|
|
647
|
+
if (a.level !== b.level)
|
|
648
|
+
return a.level - b.level;
|
|
649
|
+
const dateA = new Date(a.dueDate || '').getTime();
|
|
650
|
+
const dateB = new Date(b.dueDate || '').getTime();
|
|
651
|
+
return dateA - dateB;
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
async updateActionProgress(actionStepName, progressObservation, updateCurrentReality) {
|
|
655
|
+
const graph = await this.loadGraph();
|
|
656
|
+
const actionStep = graph.entities.find(e => e.name === actionStepName && (e.entityType === 'action_step' || e.entityType === 'desired_outcome'));
|
|
657
|
+
if (!actionStep) {
|
|
658
|
+
throw new Error(`Action step ${actionStepName} not found`);
|
|
659
|
+
}
|
|
660
|
+
// Add progress observation to action step
|
|
661
|
+
actionStep.observations.push(progressObservation);
|
|
662
|
+
if (actionStep.metadata) {
|
|
663
|
+
actionStep.metadata.updatedAt = new Date().toISOString();
|
|
664
|
+
}
|
|
665
|
+
// Optionally update current reality with progress
|
|
666
|
+
if (updateCurrentReality && actionStep.metadata?.chartId) {
|
|
667
|
+
const chartEntity = graph.entities.find(e => e.name === `${actionStep.metadata.chartId}_chart`);
|
|
668
|
+
const parentChartId = chartEntity?.metadata?.parentChart;
|
|
669
|
+
const targetChartId = parentChartId || actionStep.metadata.chartId;
|
|
670
|
+
const currentReality = graph.entities.find(e => e.name === `${targetChartId}_current_reality` &&
|
|
671
|
+
e.entityType === 'current_reality');
|
|
672
|
+
if (currentReality) {
|
|
673
|
+
// Progress observations flow into current reality, changing the structural dynamic
|
|
674
|
+
const progressMessage = `Progress on ${actionStep.observations[0]}: ${progressObservation}`;
|
|
675
|
+
if (!currentReality.observations.includes(progressMessage)) {
|
|
676
|
+
currentReality.observations.push(progressMessage);
|
|
677
|
+
if (currentReality.metadata) {
|
|
678
|
+
currentReality.metadata.updatedAt = new Date().toISOString();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
await this.saveGraph(graph);
|
|
684
|
+
}
|
|
685
|
+
async updateCurrentReality(chartId, newObservations) {
|
|
686
|
+
const graph = await this.loadGraph();
|
|
687
|
+
const currentReality = graph.entities.find(e => e.name === `${chartId}_current_reality` &&
|
|
688
|
+
e.entityType === 'current_reality');
|
|
689
|
+
if (!currentReality) {
|
|
690
|
+
throw new Error(`Chart ${chartId} not found or missing current reality`);
|
|
691
|
+
}
|
|
692
|
+
// Add new observations to current reality
|
|
693
|
+
const uniqueObservations = newObservations.filter(obs => !currentReality.observations.includes(obs));
|
|
694
|
+
currentReality.observations.push(...uniqueObservations);
|
|
695
|
+
if (currentReality.metadata) {
|
|
696
|
+
currentReality.metadata.updatedAt = new Date().toISOString();
|
|
697
|
+
}
|
|
698
|
+
await this.saveGraph(graph);
|
|
699
|
+
}
|
|
700
|
+
async updateDesiredOutcome(chartId, newDesiredOutcome) {
|
|
701
|
+
const graph = await this.loadGraph();
|
|
702
|
+
const desiredOutcomeEntity = graph.entities.find(e => e.name === `${chartId}_desired_outcome` && e.entityType === 'desired_outcome');
|
|
703
|
+
if (!desiredOutcomeEntity) {
|
|
704
|
+
throw new Error(`Chart ${chartId} desired outcome not found`);
|
|
705
|
+
}
|
|
706
|
+
// Replace the first observation (which is the desired outcome text)
|
|
707
|
+
desiredOutcomeEntity.observations[0] = newDesiredOutcome;
|
|
708
|
+
if (desiredOutcomeEntity.metadata) {
|
|
709
|
+
desiredOutcomeEntity.metadata.updatedAt = new Date().toISOString();
|
|
710
|
+
}
|
|
711
|
+
await this.saveGraph(graph);
|
|
712
|
+
}
|
|
713
|
+
// Narrative beat creation functionality
|
|
714
|
+
async createNarrativeBeat(parentChartId, title, act, type_dramatic, universes, description, prose, lessons, assessRelationalAlignment = false, initiateFourDirectionsInquiry = false, filePath) {
|
|
715
|
+
const timestamp = Date.now();
|
|
716
|
+
const beatName = `${parentChartId}_beat_${timestamp}`;
|
|
717
|
+
// Create narrative beat entity
|
|
718
|
+
const entity = {
|
|
719
|
+
name: beatName,
|
|
720
|
+
entityType: 'narrative_beat',
|
|
721
|
+
observations: [
|
|
722
|
+
`Act ${act} ${type_dramatic}`,
|
|
723
|
+
`Timestamp: ${new Date().toISOString()}`,
|
|
724
|
+
`Universe: ${universes.join(', ')}`
|
|
725
|
+
],
|
|
726
|
+
metadata: {
|
|
727
|
+
chartId: parentChartId,
|
|
728
|
+
act,
|
|
729
|
+
type_dramatic,
|
|
730
|
+
universes,
|
|
731
|
+
timestamp: new Date().toISOString(),
|
|
732
|
+
createdAt: new Date().toISOString(),
|
|
733
|
+
narrative: {
|
|
734
|
+
description,
|
|
735
|
+
prose,
|
|
736
|
+
lessons
|
|
737
|
+
},
|
|
738
|
+
relationalAlignment: {
|
|
739
|
+
assessed: false,
|
|
740
|
+
score: null,
|
|
741
|
+
principles: []
|
|
742
|
+
},
|
|
743
|
+
fourDirections: {
|
|
744
|
+
north_vision: null,
|
|
745
|
+
east_intention: null,
|
|
746
|
+
south_emotion: null,
|
|
747
|
+
west_introspection: null
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
// Add to graph
|
|
752
|
+
await this.createEntities([entity]);
|
|
753
|
+
// Create relation to parent chart if it exists
|
|
754
|
+
const graph = await this.loadGraph();
|
|
755
|
+
const parentChart = graph.entities.find(e => e.entityType === 'structural_tension_chart' && e.metadata?.chartId === parentChartId);
|
|
756
|
+
if (parentChart) {
|
|
757
|
+
await this.createRelations([{
|
|
758
|
+
from: beatName,
|
|
759
|
+
to: `${parentChartId}_chart`,
|
|
760
|
+
relationType: 'documents',
|
|
761
|
+
metadata: {
|
|
762
|
+
createdAt: new Date().toISOString(),
|
|
763
|
+
description: 'Narrative beat documents chart progress'
|
|
764
|
+
}
|
|
765
|
+
}]);
|
|
766
|
+
}
|
|
767
|
+
// TODO: IAIP integration would go here
|
|
768
|
+
if (assessRelationalAlignment) {
|
|
769
|
+
console.log('š® Relational alignment assessment requested (iaip-mcp integration pending)');
|
|
770
|
+
}
|
|
771
|
+
if (initiateFourDirectionsInquiry) {
|
|
772
|
+
console.log('š§ Four Directions inquiry requested (iaip-mcp integration pending)');
|
|
773
|
+
}
|
|
774
|
+
return { entity, beatName };
|
|
775
|
+
}
|
|
776
|
+
async telescopeNarrativeBeat(parentBeatName, newCurrentReality, initialSubBeats) {
|
|
777
|
+
const graph = await this.loadGraph();
|
|
778
|
+
const parentBeat = graph.entities.find(e => e.name === parentBeatName && e.entityType === 'narrative_beat');
|
|
779
|
+
if (!parentBeat) {
|
|
780
|
+
throw new Error(`Parent narrative beat not found: ${parentBeatName}`);
|
|
781
|
+
}
|
|
782
|
+
// Update parent beat's current reality (add to observations)
|
|
783
|
+
parentBeat.observations.push(`Telescoped: ${newCurrentReality}`);
|
|
784
|
+
if (parentBeat.metadata) {
|
|
785
|
+
parentBeat.metadata.updatedAt = new Date().toISOString();
|
|
786
|
+
}
|
|
787
|
+
const subBeats = [];
|
|
788
|
+
// Create sub-beats if provided
|
|
789
|
+
if (initialSubBeats && initialSubBeats.length > 0) {
|
|
790
|
+
for (let i = 0; i < initialSubBeats.length; i++) {
|
|
791
|
+
const subBeat = initialSubBeats[i];
|
|
792
|
+
const result = await this.createNarrativeBeat(parentBeatName, // Use parent beat as chart ID
|
|
793
|
+
subBeat.title, i + 1, // Sequential act numbers
|
|
794
|
+
subBeat.type_dramatic, parentBeat.metadata?.universes || ['engineer-world'], subBeat.description, subBeat.prose, subBeat.lessons);
|
|
795
|
+
subBeats.push(result.entity);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
await this.saveGraph(graph);
|
|
799
|
+
return { parentBeat, subBeats };
|
|
800
|
+
}
|
|
801
|
+
async listNarrativeBeats(parentChartId) {
|
|
802
|
+
const graph = await this.loadGraph();
|
|
803
|
+
const beats = graph.entities.filter(e => e.entityType === 'narrative_beat');
|
|
804
|
+
if (parentChartId) {
|
|
805
|
+
return beats.filter(beat => beat.metadata?.chartId === parentChartId);
|
|
806
|
+
}
|
|
807
|
+
return beats;
|
|
808
|
+
}
|
|
809
|
+
async addActionStep(parentChartId, actionStepTitle, dueDate, currentReality) {
|
|
810
|
+
const graph = await this.loadGraph();
|
|
811
|
+
const parentChart = graph.entities.find(e => e.entityType === 'structural_tension_chart' && e.metadata?.chartId === parentChartId);
|
|
812
|
+
if (!parentChart) {
|
|
813
|
+
throw new Error(`Parent chart ${parentChartId} not found`);
|
|
814
|
+
}
|
|
815
|
+
// Get parent chart's due date for auto-distribution
|
|
816
|
+
const parentDueDate = parentChart.metadata?.dueDate;
|
|
817
|
+
if (!parentDueDate) {
|
|
818
|
+
throw new Error(`Parent chart ${parentChartId} has no due date`);
|
|
819
|
+
}
|
|
820
|
+
// Calculate due date for action step if not provided
|
|
821
|
+
let actionStepDueDate = dueDate;
|
|
822
|
+
if (!actionStepDueDate) {
|
|
823
|
+
// Distribute between now and parent due date (simple midpoint for now)
|
|
824
|
+
const now = new Date();
|
|
825
|
+
const parentEnd = new Date(parentDueDate);
|
|
826
|
+
const midpoint = new Date(now.getTime() + (parentEnd.getTime() - now.getTime()) / 2);
|
|
827
|
+
actionStepDueDate = midpoint.toISOString();
|
|
828
|
+
}
|
|
829
|
+
// Require current reality assessment - no defaults that prematurely resolve tension
|
|
830
|
+
if (!currentReality) {
|
|
831
|
+
throw new Error(`š DELAYED RESOLUTION PRINCIPLE VIOLATION
|
|
832
|
+
|
|
833
|
+
Action step: "${actionStepTitle}"
|
|
834
|
+
|
|
835
|
+
ā **Problem**: Current reality assessment missing
|
|
836
|
+
š **Principle**: "Tolerate discrepancy, tension, and delayed resolution" - Robert Fritz
|
|
837
|
+
|
|
838
|
+
šÆ **What's Needed**: Honest assessment of your actual current state relative to this action step.
|
|
839
|
+
|
|
840
|
+
ā
**Examples**:
|
|
841
|
+
- "Never used Django, completed Python basics"
|
|
842
|
+
- "Built one API, struggling with authentication"
|
|
843
|
+
- "Read 3 chapters, concepts still unclear"
|
|
844
|
+
|
|
845
|
+
ā **Avoid**: "Ready to begin", "Prepared to start", "All set to..."
|
|
846
|
+
|
|
847
|
+
**Why This Matters**: Premature resolution destroys the structural tension that generates creative advancement. The system NEEDS honest current reality to create productive tension.
|
|
848
|
+
|
|
849
|
+
š” **Tip**: Run 'init_llm_guidance' for complete methodology overview.`);
|
|
850
|
+
}
|
|
851
|
+
const actionCurrentReality = currentReality;
|
|
852
|
+
// Create telescoped structural tension chart
|
|
853
|
+
const telescopedChart = await this.createStructuralTensionChart(actionStepTitle, actionCurrentReality, actionStepDueDate);
|
|
854
|
+
// Update the telescoped chart's metadata to show parent relationship
|
|
855
|
+
const updatedGraph = await this.loadGraph();
|
|
856
|
+
const telescopedChartEntity = updatedGraph.entities.find(e => e.name === `${telescopedChart.chartId}_chart`);
|
|
857
|
+
if (telescopedChartEntity && telescopedChartEntity.metadata) {
|
|
858
|
+
telescopedChartEntity.metadata.parentChart = parentChartId;
|
|
859
|
+
telescopedChartEntity.metadata.level = (parentChart.metadata?.level || 0) + 1;
|
|
860
|
+
telescopedChartEntity.metadata.updatedAt = new Date().toISOString();
|
|
861
|
+
}
|
|
862
|
+
// Create relationship: telescoped chart advances toward parent's desired outcome
|
|
863
|
+
const parentDesiredOutcome = updatedGraph.entities.find(e => e.name === `${parentChartId}_desired_outcome` && e.entityType === 'desired_outcome');
|
|
864
|
+
if (parentDesiredOutcome) {
|
|
865
|
+
const timestamp = new Date().toISOString();
|
|
866
|
+
await this.createRelations([{
|
|
867
|
+
from: `${telescopedChart.chartId}_desired_outcome`,
|
|
868
|
+
to: parentDesiredOutcome.name,
|
|
869
|
+
relationType: 'advances_toward',
|
|
870
|
+
metadata: { createdAt: timestamp }
|
|
871
|
+
}]);
|
|
872
|
+
}
|
|
873
|
+
await this.saveGraph(updatedGraph);
|
|
874
|
+
return {
|
|
875
|
+
chartId: telescopedChart.chartId,
|
|
876
|
+
actionStepName: `${telescopedChart.chartId}_desired_outcome`
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
// Enhanced method for LLMs to telescope with intelligent current reality extraction
|
|
880
|
+
async telescopeActionStepWithContext(parentChartId, actionStepTitle, userContext, currentReality, dueDate) {
|
|
881
|
+
// If current reality not provided, try to extract from context
|
|
882
|
+
let finalCurrentReality = currentReality;
|
|
883
|
+
if (!finalCurrentReality) {
|
|
884
|
+
finalCurrentReality = this.extractCurrentRealityFromContext(userContext, actionStepTitle) ?? undefined;
|
|
885
|
+
}
|
|
886
|
+
// If still no current reality, provide guidance while maintaining tension
|
|
887
|
+
if (!finalCurrentReality) {
|
|
888
|
+
throw new Error(`Current reality assessment needed for "${actionStepTitle}". ` +
|
|
889
|
+
`Please assess your actual current state relative to this action step. ` +
|
|
890
|
+
`Example: "I have never used Django before" or "I completed the basics but haven't built a real project" ` +
|
|
891
|
+
`rather than assuming readiness. Structural tension requires honest current reality assessment.`);
|
|
892
|
+
}
|
|
893
|
+
// Proceed with telescoping using the assessed current reality
|
|
894
|
+
return this.addActionStep(parentChartId, actionStepTitle, dueDate, finalCurrentReality);
|
|
895
|
+
}
|
|
896
|
+
// Unified interface for managing action steps - handles both creation and expansion
|
|
897
|
+
async manageActionStep(parentReference, actionDescription, currentReality, initialActionSteps, dueDate) {
|
|
898
|
+
const graph = await this.loadGraph();
|
|
899
|
+
// Pattern detection: Determine if parentReference is entity name or chart ID
|
|
900
|
+
const actionStepPattern = /^chart_\d+_action_\d+$/;
|
|
901
|
+
const desiredOutcomePattern = /^chart_\d+_desired_outcome$/;
|
|
902
|
+
const chartIdPattern = /^chart_\d+$/;
|
|
903
|
+
const isActionStepEntity = actionStepPattern.test(parentReference);
|
|
904
|
+
const isDesiredOutcomeEntity = desiredOutcomePattern.test(parentReference);
|
|
905
|
+
const isChartId = chartIdPattern.test(parentReference);
|
|
906
|
+
// Route 1: Expanding existing action_step entity (legacy pattern)
|
|
907
|
+
if (isActionStepEntity) {
|
|
908
|
+
const actionStep = graph.entities.find(e => e.name === parentReference && e.entityType === 'action_step');
|
|
909
|
+
if (!actionStep) {
|
|
910
|
+
// Provide helpful error with available actions
|
|
911
|
+
const allActionSteps = graph.entities
|
|
912
|
+
.filter(e => e.entityType === 'action_step')
|
|
913
|
+
.map(e => `- ${e.name}: "${e.observations[0]}"`);
|
|
914
|
+
throw new Error(`š ACTION STEP ENTITY NOT FOUND
|
|
915
|
+
|
|
916
|
+
Received: "${parentReference}"
|
|
917
|
+
Expected: Valid action_step entity name (e.g., "chart_123_action_1")
|
|
918
|
+
|
|
919
|
+
Available action steps in memory:
|
|
920
|
+
${allActionSteps.length > 0 ? allActionSteps.join('\n') : '(none found)'}
|
|
921
|
+
|
|
922
|
+
Tip: If creating a new action step, use the parent chart ID instead.`);
|
|
923
|
+
}
|
|
924
|
+
// Use telescoping logic for legacy action_step entities
|
|
925
|
+
const currentRealityToUse = currentReality || "Expanding action step into detailed sub-chart";
|
|
926
|
+
const telescopedResult = await this.telescopeActionStep(parentReference, currentRealityToUse, initialActionSteps);
|
|
927
|
+
// Transform result to include actionStepName
|
|
928
|
+
return {
|
|
929
|
+
chartId: telescopedResult.chartId,
|
|
930
|
+
actionStepName: `${telescopedResult.chartId}_desired_outcome`
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
// Route 2: Expanding existing desired_outcome entity (modern pattern)
|
|
934
|
+
if (isDesiredOutcomeEntity) {
|
|
935
|
+
const desiredOutcome = graph.entities.find(e => e.name === parentReference && e.entityType === 'desired_outcome');
|
|
936
|
+
if (!desiredOutcome || !desiredOutcome.metadata?.chartId) {
|
|
937
|
+
throw new Error(`š DESIRED OUTCOME ENTITY NOT FOUND
|
|
938
|
+
|
|
939
|
+
Received: "${parentReference}"
|
|
940
|
+
Expected: Valid desired_outcome entity name (e.g., "chart_123_desired_outcome")
|
|
941
|
+
|
|
942
|
+
Tip: If creating a new action step, use the parent chart ID instead.`);
|
|
943
|
+
}
|
|
944
|
+
// Use telescoping logic for desired_outcome entities
|
|
945
|
+
const currentRealityToUse = currentReality || "Expanding desired outcome into detailed sub-chart";
|
|
946
|
+
const telescopedResult = await this.telescopeActionStep(parentReference, currentRealityToUse, initialActionSteps);
|
|
947
|
+
// Transform result to include actionStepName
|
|
948
|
+
return {
|
|
949
|
+
chartId: telescopedResult.chartId,
|
|
950
|
+
actionStepName: `${telescopedResult.chartId}_desired_outcome`
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
// Route 3: Creating new action step under parent chart (modern pattern)
|
|
954
|
+
if (isChartId) {
|
|
955
|
+
// Validate parent chart exists
|
|
956
|
+
const parentChart = graph.entities.find(e => e.entityType === 'structural_tension_chart' &&
|
|
957
|
+
e.metadata?.chartId === parentReference);
|
|
958
|
+
if (!parentChart) {
|
|
959
|
+
// Provide helpful error with available charts
|
|
960
|
+
const allCharts = graph.entities
|
|
961
|
+
.filter(e => e.entityType === 'structural_tension_chart')
|
|
962
|
+
.map(e => {
|
|
963
|
+
const outcome = graph.entities.find(o => o.name === `${e.metadata?.chartId}_desired_outcome`);
|
|
964
|
+
return `- ${e.metadata?.chartId}: "${outcome?.observations[0] || 'Unknown'}"`;
|
|
965
|
+
});
|
|
966
|
+
throw new Error(`š PARENT CHART NOT FOUND
|
|
967
|
+
|
|
968
|
+
Received: "${parentReference}"
|
|
969
|
+
Expected: Valid chart ID (e.g., "chart_123")
|
|
970
|
+
|
|
971
|
+
Available charts in memory:
|
|
972
|
+
${allCharts.length > 0 ? allCharts.join('\n') : '(none found)'}
|
|
973
|
+
|
|
974
|
+
Tip: Use 'list_active_charts' to see all available charts.`);
|
|
975
|
+
}
|
|
976
|
+
// Enforce delayed resolution principle for new action creation
|
|
977
|
+
if (!currentReality) {
|
|
978
|
+
throw new Error(`š DELAYED RESOLUTION PRINCIPLE VIOLATION
|
|
979
|
+
|
|
980
|
+
Action step: "${actionDescription}"
|
|
981
|
+
Parent chart: "${parentReference}"
|
|
982
|
+
|
|
983
|
+
ā **Problem**: Current reality assessment missing
|
|
984
|
+
š **Principle**: "Tolerate discrepancy, tension, and delayed resolution" - Robert Fritz
|
|
985
|
+
|
|
986
|
+
šÆ **What's Needed**: Honest assessment of actual current state relative to this action step.
|
|
987
|
+
|
|
988
|
+
ā
**Examples**:
|
|
989
|
+
- "Never used Django, completed Python basics"
|
|
990
|
+
- "Built one API, struggling with authentication"
|
|
991
|
+
- "Read 3 chapters, concepts still unclear"
|
|
992
|
+
|
|
993
|
+
ā **Avoid**: "Ready to begin", "Prepared to start", "All set to..."
|
|
994
|
+
|
|
995
|
+
**Why This Matters**: Premature resolution destroys structural tension essential for creative advancement.
|
|
996
|
+
|
|
997
|
+
š” **Tip**: Run 'init_llm_guidance' for complete methodology overview.`);
|
|
998
|
+
}
|
|
999
|
+
// Create new action step as telescoped chart
|
|
1000
|
+
return await this.addActionStep(parentReference, actionDescription, dueDate, currentReality);
|
|
1001
|
+
}
|
|
1002
|
+
// Route 4: Invalid format - provide comprehensive guidance
|
|
1003
|
+
throw new Error(`šØ INVALID PARENT REFERENCE FORMAT
|
|
1004
|
+
|
|
1005
|
+
Received: "${parentReference}"
|
|
1006
|
+
|
|
1007
|
+
Valid formats:
|
|
1008
|
+
1. Chart ID: "chart_123" ā Creates new action step
|
|
1009
|
+
2. Action entity: "chart_123_action_1" ā Expands existing legacy action step
|
|
1010
|
+
3. Desired outcome: "chart_123_desired_outcome" ā Expands existing modern action step
|
|
1011
|
+
|
|
1012
|
+
Examples:
|
|
1013
|
+
- Create new action: manageActionStep("chart_123", "Complete tutorial", "Never used Django")
|
|
1014
|
+
- Expand existing: manageActionStep("chart_123_action_1", "Complete tutorial", undefined, ["Step 1", "Step 2"])
|
|
1015
|
+
|
|
1016
|
+
š” **Tip**: Use 'list_active_charts' to see available charts and their IDs.`);
|
|
1017
|
+
}
|
|
1018
|
+
async removeActionStep(parentChartId, actionStepName) {
|
|
1019
|
+
const graph = await this.loadGraph();
|
|
1020
|
+
// Find the action step (which is actually a telescoped chart's desired outcome)
|
|
1021
|
+
const actionStepEntity = graph.entities.find(e => e.name === actionStepName);
|
|
1022
|
+
if (!actionStepEntity || !actionStepEntity.metadata?.chartId) {
|
|
1023
|
+
throw new Error(`Action step ${actionStepName} not found`);
|
|
1024
|
+
}
|
|
1025
|
+
const telescopedChartId = actionStepEntity.metadata.chartId;
|
|
1026
|
+
// Verify it belongs to the parent chart
|
|
1027
|
+
const telescopedChart = graph.entities.find(e => e.entityType === 'structural_tension_chart' &&
|
|
1028
|
+
e.metadata?.chartId === telescopedChartId &&
|
|
1029
|
+
e.metadata?.parentChart === parentChartId);
|
|
1030
|
+
if (!telescopedChart) {
|
|
1031
|
+
throw new Error(`Action step ${actionStepName} does not belong to chart ${parentChartId}`);
|
|
1032
|
+
}
|
|
1033
|
+
// Remove all entities belonging to the telescoped chart
|
|
1034
|
+
const entitiesToRemove = graph.entities
|
|
1035
|
+
.filter(e => e.metadata?.chartId === telescopedChartId)
|
|
1036
|
+
.map(e => e.name);
|
|
1037
|
+
await this.deleteEntities(entitiesToRemove);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
const knowledgeGraphManager = new KnowledgeGraphManager();
|
|
1041
|
+
// The server instance and tools exposed to AI models
|
|
1042
|
+
const server = new Server({
|
|
1043
|
+
name: "coaia-narrative",
|
|
1044
|
+
version: "0.1.0",
|
|
1045
|
+
description: "COAIA Narrative - Structural Tension Charts with Narrative Beat Extension for multi-universe story capture. Extends coaia-memory with relational and ceremonial integration. šØ NEW LLM? Run 'init_llm_guidance' first."
|
|
1046
|
+
}, {
|
|
1047
|
+
capabilities: {
|
|
1048
|
+
tools: {},
|
|
1049
|
+
},
|
|
1050
|
+
});
|
|
1051
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1052
|
+
const enabledTools = getEnabledTools();
|
|
1053
|
+
const allTools = [
|
|
1054
|
+
{
|
|
1055
|
+
name: "create_entities",
|
|
1056
|
+
description: "ADVANCED: Create traditional knowledge graph entities. For structural tension charts, use create_structural_tension_chart or add_action_step instead.",
|
|
1057
|
+
inputSchema: {
|
|
1058
|
+
type: "object",
|
|
1059
|
+
properties: {
|
|
1060
|
+
entities: {
|
|
1061
|
+
type: "array",
|
|
1062
|
+
items: {
|
|
1063
|
+
type: "object",
|
|
1064
|
+
properties: {
|
|
1065
|
+
name: { type: "string", description: "The name of the entity" },
|
|
1066
|
+
entityType: { type: "string", description: "The type of the entity" },
|
|
1067
|
+
observations: {
|
|
1068
|
+
type: "array",
|
|
1069
|
+
items: { type: "string" },
|
|
1070
|
+
description: "An array of observation contents associated with the entity"
|
|
1071
|
+
},
|
|
1072
|
+
},
|
|
1073
|
+
required: ["name", "entityType", "observations"],
|
|
1074
|
+
},
|
|
1075
|
+
},
|
|
1076
|
+
},
|
|
1077
|
+
required: ["entities"],
|
|
1078
|
+
},
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
name: "create_relations",
|
|
1082
|
+
description: "Create multiple new relations between entities in the knowledge graph. Relations should be in active voice",
|
|
1083
|
+
inputSchema: {
|
|
1084
|
+
type: "object",
|
|
1085
|
+
properties: {
|
|
1086
|
+
relations: {
|
|
1087
|
+
type: "array",
|
|
1088
|
+
items: {
|
|
1089
|
+
type: "object",
|
|
1090
|
+
properties: {
|
|
1091
|
+
from: { type: "string", description: "The name of the entity where the relation starts" },
|
|
1092
|
+
to: { type: "string", description: "The name of the entity where the relation ends" },
|
|
1093
|
+
relationType: { type: "string", description: "The type of the relation" },
|
|
1094
|
+
},
|
|
1095
|
+
required: ["from", "to", "relationType"],
|
|
1096
|
+
},
|
|
1097
|
+
},
|
|
1098
|
+
},
|
|
1099
|
+
required: ["relations"],
|
|
1100
|
+
},
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
name: "add_observations",
|
|
1104
|
+
description: "ADVANCED: Add observations to traditional knowledge graph entities. For structural tension charts, use update_current_reality instead.",
|
|
1105
|
+
inputSchema: {
|
|
1106
|
+
type: "object",
|
|
1107
|
+
properties: {
|
|
1108
|
+
observations: {
|
|
1109
|
+
type: "array",
|
|
1110
|
+
items: {
|
|
1111
|
+
type: "object",
|
|
1112
|
+
properties: {
|
|
1113
|
+
entityName: { type: "string", description: "The name of the entity to add the observations to" },
|
|
1114
|
+
contents: {
|
|
1115
|
+
type: "array",
|
|
1116
|
+
items: { type: "string" },
|
|
1117
|
+
description: "An array of observation contents to add"
|
|
1118
|
+
},
|
|
1119
|
+
},
|
|
1120
|
+
required: ["entityName", "contents"],
|
|
1121
|
+
},
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
required: ["observations"],
|
|
1125
|
+
},
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
name: "delete_entities",
|
|
1129
|
+
description: "Delete multiple entities and their associated relations from the knowledge graph",
|
|
1130
|
+
inputSchema: {
|
|
1131
|
+
type: "object",
|
|
1132
|
+
properties: {
|
|
1133
|
+
entityNames: {
|
|
1134
|
+
type: "array",
|
|
1135
|
+
items: { type: "string" },
|
|
1136
|
+
description: "An array of entity names to delete"
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
required: ["entityNames"],
|
|
1140
|
+
},
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: "delete_observations",
|
|
1144
|
+
description: "Delete specific observations from entities in the knowledge graph",
|
|
1145
|
+
inputSchema: {
|
|
1146
|
+
type: "object",
|
|
1147
|
+
properties: {
|
|
1148
|
+
deletions: {
|
|
1149
|
+
type: "array",
|
|
1150
|
+
items: {
|
|
1151
|
+
type: "object",
|
|
1152
|
+
properties: {
|
|
1153
|
+
entityName: { type: "string", description: "The name of the entity containing the observations" },
|
|
1154
|
+
observations: {
|
|
1155
|
+
type: "array",
|
|
1156
|
+
items: { type: "string" },
|
|
1157
|
+
description: "An array of observations to delete"
|
|
1158
|
+
},
|
|
1159
|
+
},
|
|
1160
|
+
required: ["entityName", "observations"],
|
|
1161
|
+
},
|
|
1162
|
+
},
|
|
1163
|
+
},
|
|
1164
|
+
required: ["deletions"],
|
|
1165
|
+
},
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
name: "delete_relations",
|
|
1169
|
+
description: "Delete multiple relations from the knowledge graph",
|
|
1170
|
+
inputSchema: {
|
|
1171
|
+
type: "object",
|
|
1172
|
+
properties: {
|
|
1173
|
+
relations: {
|
|
1174
|
+
type: "array",
|
|
1175
|
+
items: {
|
|
1176
|
+
type: "object",
|
|
1177
|
+
properties: {
|
|
1178
|
+
from: { type: "string", description: "The name of the entity where the relation starts" },
|
|
1179
|
+
to: { type: "string", description: "The name of the entity where the relation ends" },
|
|
1180
|
+
relationType: { type: "string", description: "The type of the relation" },
|
|
1181
|
+
},
|
|
1182
|
+
required: ["from", "to", "relationType"],
|
|
1183
|
+
},
|
|
1184
|
+
description: "An array of relations to delete"
|
|
1185
|
+
},
|
|
1186
|
+
},
|
|
1187
|
+
required: ["relations"],
|
|
1188
|
+
},
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
name: "read_graph",
|
|
1192
|
+
description: "RARELY USED: Dumps entire knowledge graph (all entities and relations). Only use for debugging or when you need to see ALL data. For chart work, use list_active_charts instead.",
|
|
1193
|
+
inputSchema: {
|
|
1194
|
+
type: "object",
|
|
1195
|
+
properties: {},
|
|
1196
|
+
},
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
name: "search_nodes",
|
|
1200
|
+
description: "Search for nodes in the knowledge graph based on a query",
|
|
1201
|
+
inputSchema: {
|
|
1202
|
+
type: "object",
|
|
1203
|
+
properties: {
|
|
1204
|
+
query: { type: "string", description: "The search query to match against entity names, types, and observation content" },
|
|
1205
|
+
},
|
|
1206
|
+
required: ["query"],
|
|
1207
|
+
},
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
name: "open_nodes",
|
|
1211
|
+
description: "ADVANCED: Open specific entity nodes by exact name (e.g. 'chart_123_current_reality'). Only use if you need to inspect specific chart components. NOT for general chart viewing - use list_active_charts instead.",
|
|
1212
|
+
inputSchema: {
|
|
1213
|
+
type: "object",
|
|
1214
|
+
properties: {
|
|
1215
|
+
names: {
|
|
1216
|
+
type: "array",
|
|
1217
|
+
items: { type: "string" },
|
|
1218
|
+
description: "An array of exact entity names to retrieve (e.g. 'chart_123_desired_outcome')",
|
|
1219
|
+
},
|
|
1220
|
+
},
|
|
1221
|
+
required: ["names"],
|
|
1222
|
+
},
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
name: "create_structural_tension_chart",
|
|
1226
|
+
description: "Create a new structural tension chart with desired outcome, current reality, and optional action steps. CRITICAL: Use creative orientation (what you want to CREATE) not problem-solving (what you want to fix/solve). Current reality must be factual assessment, never 'ready to begin'.",
|
|
1227
|
+
inputSchema: {
|
|
1228
|
+
type: "object",
|
|
1229
|
+
properties: {
|
|
1230
|
+
desiredOutcome: { type: "string", description: "What you want to CREATE (not solve/fix). Focus on positive outcomes, not problems to eliminate." },
|
|
1231
|
+
currentReality: { type: "string", description: "Your current situation - factual assessment only. NEVER use 'ready to begin' or similar readiness statements." },
|
|
1232
|
+
dueDate: { type: "string", description: "When you want to achieve this outcome (ISO date string)" },
|
|
1233
|
+
actionSteps: {
|
|
1234
|
+
type: "array",
|
|
1235
|
+
items: { type: "string" },
|
|
1236
|
+
description: "Optional list of action steps needed to achieve the outcome"
|
|
1237
|
+
}
|
|
1238
|
+
},
|
|
1239
|
+
required: ["desiredOutcome", "currentReality", "dueDate"]
|
|
1240
|
+
}
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
name: "telescope_action_step",
|
|
1244
|
+
description: "ā ļø DEPRECATED: Use 'manage_action_step' instead for unified interface. Break down an action step into a detailed structural tension chart. CRITICAL: Current reality must be an honest assessment of actual current state relative to this specific action step, NOT readiness or preparation statements. This maintains structural tension essential for creative advancement.",
|
|
1245
|
+
inputSchema: {
|
|
1246
|
+
type: "object",
|
|
1247
|
+
properties: {
|
|
1248
|
+
actionStepName: { type: "string", description: "Name of the action step to telescope" },
|
|
1249
|
+
newCurrentReality: {
|
|
1250
|
+
type: "string",
|
|
1251
|
+
description: "REQUIRED: Honest assessment of actual current state relative to this action step. Examples: 'Never used Django before', 'Completed models section, struggling with views'. AVOID: 'Ready to begin', 'Prepared to start'."
|
|
1252
|
+
},
|
|
1253
|
+
initialActionSteps: {
|
|
1254
|
+
type: "array",
|
|
1255
|
+
items: { type: "string" },
|
|
1256
|
+
description: "Optional list of initial action steps for the telescoped chart"
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
required: ["actionStepName", "newCurrentReality"]
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
name: "mark_action_complete",
|
|
1264
|
+
description: "Mark an action step as completed and update current reality",
|
|
1265
|
+
inputSchema: {
|
|
1266
|
+
type: "object",
|
|
1267
|
+
properties: {
|
|
1268
|
+
actionStepName: { type: "string", description: "Name of the completed action step" }
|
|
1269
|
+
},
|
|
1270
|
+
required: ["actionStepName"]
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
name: "get_chart_progress",
|
|
1275
|
+
description: "Get detailed progress for a specific chart (redundant if you just used list_active_charts which shows progress). Only use if you need the nextAction details.",
|
|
1276
|
+
inputSchema: {
|
|
1277
|
+
type: "object",
|
|
1278
|
+
properties: {
|
|
1279
|
+
chartId: { type: "string", description: "ID of the chart to check progress for" }
|
|
1280
|
+
},
|
|
1281
|
+
required: ["chartId"]
|
|
1282
|
+
}
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
name: "list_active_charts",
|
|
1286
|
+
description: "List all active structural tension charts with their progress. Use this FIRST to see all charts and their IDs. This shows chart overview with progress - you don't need other tools after this for basic chart information.",
|
|
1287
|
+
inputSchema: {
|
|
1288
|
+
type: "object",
|
|
1289
|
+
properties: {}
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
name: "update_action_progress",
|
|
1294
|
+
description: "Update progress on an action step without marking it complete, optionally updating current reality",
|
|
1295
|
+
inputSchema: {
|
|
1296
|
+
type: "object",
|
|
1297
|
+
properties: {
|
|
1298
|
+
actionStepName: { type: "string", description: "Name of the action step to update progress for" },
|
|
1299
|
+
progressObservation: { type: "string", description: "Description of progress made on this action step" },
|
|
1300
|
+
updateCurrentReality: {
|
|
1301
|
+
type: "boolean",
|
|
1302
|
+
description: "Whether to also add this progress to current reality (optional, defaults to false)"
|
|
1303
|
+
}
|
|
1304
|
+
},
|
|
1305
|
+
required: ["actionStepName", "progressObservation"]
|
|
1306
|
+
}
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
name: "update_current_reality",
|
|
1310
|
+
description: "FOR STRUCTURAL TENSION CHARTS: Add observations to current reality. DO NOT use add_observations or create_entities for chart work - use this instead.",
|
|
1311
|
+
inputSchema: {
|
|
1312
|
+
type: "object",
|
|
1313
|
+
properties: {
|
|
1314
|
+
chartId: { type: "string", description: "ID of the chart to update current reality for" },
|
|
1315
|
+
newObservations: {
|
|
1316
|
+
type: "array",
|
|
1317
|
+
items: { type: "string" },
|
|
1318
|
+
description: "Array of new observations to add to current reality"
|
|
1319
|
+
}
|
|
1320
|
+
},
|
|
1321
|
+
required: ["chartId", "newObservations"]
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
name: "manage_action_step",
|
|
1326
|
+
description: "⨠RECOMMENDED: Unified interface for managing action steps - handles both creation and expansion. Automatically detects whether you're creating a new action step (chart ID) or expanding an existing one (entity name). Provides clear error messages when parameters are invalid.",
|
|
1327
|
+
inputSchema: {
|
|
1328
|
+
type: "object",
|
|
1329
|
+
properties: {
|
|
1330
|
+
parentReference: {
|
|
1331
|
+
type: "string",
|
|
1332
|
+
description: "Chart ID (e.g., 'chart_123') to create new action step, OR action step entity name (e.g., 'chart_123_action_1' or 'chart_123_desired_outcome') to expand existing action step"
|
|
1333
|
+
},
|
|
1334
|
+
actionDescription: {
|
|
1335
|
+
type: "string",
|
|
1336
|
+
description: "Title/description of the action step"
|
|
1337
|
+
},
|
|
1338
|
+
currentReality: {
|
|
1339
|
+
type: "string",
|
|
1340
|
+
description: "REQUIRED for new action creation. Honest assessment of actual current state relative to this action step. Examples: 'Never used Django', 'Completed models, struggling with views'. AVOID: 'Ready to begin'. Optional when expanding existing actions."
|
|
1341
|
+
},
|
|
1342
|
+
initialActionSteps: {
|
|
1343
|
+
type: "array",
|
|
1344
|
+
items: { type: "string" },
|
|
1345
|
+
description: "Optional list of sub-actions for the action step"
|
|
1346
|
+
},
|
|
1347
|
+
dueDate: {
|
|
1348
|
+
type: "string",
|
|
1349
|
+
description: "Optional due date (ISO string). Auto-distributed if not provided."
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
required: ["parentReference", "actionDescription"]
|
|
1353
|
+
}
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
name: "add_action_step",
|
|
1357
|
+
description: "ā ļø DEPRECATED: Use 'manage_action_step' instead for unified interface. Add a strategic action step to an existing structural tension chart (creates telescoped chart). WARNING: Requires honest current reality assessment - avoid 'ready to begin' language. Action steps become full structural tension charts.",
|
|
1358
|
+
inputSchema: {
|
|
1359
|
+
type: "object",
|
|
1360
|
+
properties: {
|
|
1361
|
+
parentChartId: { type: "string", description: "ID of the parent chart to add the action step to" },
|
|
1362
|
+
actionStepTitle: { type: "string", description: "Title of the action step (becomes desired outcome of telescoped chart)" },
|
|
1363
|
+
dueDate: {
|
|
1364
|
+
type: "string",
|
|
1365
|
+
description: "Optional due date for the action step (ISO string). If not provided, auto-distributed between now and parent due date"
|
|
1366
|
+
},
|
|
1367
|
+
currentReality: {
|
|
1368
|
+
type: "string",
|
|
1369
|
+
description: "Current reality specific to this action step. Required to maintain structural tension - assess the actual current state relative to this action step, not readiness to begin."
|
|
1370
|
+
}
|
|
1371
|
+
},
|
|
1372
|
+
required: ["parentChartId", "actionStepTitle", "currentReality"]
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
name: "remove_action_step",
|
|
1377
|
+
description: "Remove an action step from a structural tension chart (deletes telescoped chart)",
|
|
1378
|
+
inputSchema: {
|
|
1379
|
+
type: "object",
|
|
1380
|
+
properties: {
|
|
1381
|
+
parentChartId: { type: "string", description: "ID of the parent chart containing the action step" },
|
|
1382
|
+
actionStepName: { type: "string", description: "Name of the action step to remove (telescoped chart's desired outcome name)" }
|
|
1383
|
+
},
|
|
1384
|
+
required: ["parentChartId", "actionStepName"]
|
|
1385
|
+
}
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
name: "update_desired_outcome",
|
|
1389
|
+
description: "Update a chart's desired outcome (goal). Works for BOTH master charts AND action steps (which are telescoped charts). Provide the chart ID of the chart you want to update - whether it's a master chart or an action step chart.",
|
|
1390
|
+
inputSchema: {
|
|
1391
|
+
type: "object",
|
|
1392
|
+
properties: {
|
|
1393
|
+
chartId: { type: "string", description: "ID of the chart to update (works for master charts like 'chart_123' or action step charts like 'chart_456')" },
|
|
1394
|
+
newDesiredOutcome: { type: "string", description: "New desired outcome text" }
|
|
1395
|
+
},
|
|
1396
|
+
required: ["chartId", "newDesiredOutcome"]
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
name: "creator_moment_of_truth",
|
|
1401
|
+
description: "Guide through the Creator Moment of Truth - a four-step review process for assessing chart progress. Transforms discrepancies between expected and delivered into learning opportunities. Use when reviewing progress or when action steps aren't going as planned.",
|
|
1402
|
+
inputSchema: {
|
|
1403
|
+
type: "object",
|
|
1404
|
+
properties: {
|
|
1405
|
+
chartId: { type: "string", description: "ID of the chart to review" },
|
|
1406
|
+
step: {
|
|
1407
|
+
type: "string",
|
|
1408
|
+
enum: ["full_review", "acknowledge", "analyze", "plan", "feedback"],
|
|
1409
|
+
default: "full_review",
|
|
1410
|
+
description: "Which step to guide through: 'full_review' for complete process, or individual steps"
|
|
1411
|
+
},
|
|
1412
|
+
userInput: {
|
|
1413
|
+
type: "string",
|
|
1414
|
+
description: "Optional: User's observations or responses for the current step"
|
|
1415
|
+
}
|
|
1416
|
+
},
|
|
1417
|
+
required: ["chartId"]
|
|
1418
|
+
}
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
name: "init_llm_guidance",
|
|
1422
|
+
description: "šØ NEW LLM? Essential guidance for understanding COAIA Memory's structural tension methodology, delayed resolution principle, and proper tool usage. Run this FIRST to avoid common mistakes.",
|
|
1423
|
+
inputSchema: {
|
|
1424
|
+
type: "object",
|
|
1425
|
+
properties: {
|
|
1426
|
+
format: {
|
|
1427
|
+
type: "string",
|
|
1428
|
+
enum: ["full", "quick", "save_directive"],
|
|
1429
|
+
default: "full",
|
|
1430
|
+
description: "Level of detail: 'full' for complete guidance, 'quick' for essentials only, 'save_directive' for session memory instructions"
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
},
|
|
1435
|
+
{
|
|
1436
|
+
name: "create_narrative_beat",
|
|
1437
|
+
description: "Create a new narrative beat with multi-universe perspective and optional IAIP integration. Documents story progression across three archetypal universes (engineer-world, ceremony-world, story-engine-world).",
|
|
1438
|
+
inputSchema: {
|
|
1439
|
+
type: "object",
|
|
1440
|
+
properties: {
|
|
1441
|
+
parentChartId: { type: "string", description: "ID of the parent structural tension chart" },
|
|
1442
|
+
title: { type: "string", description: "Title of the narrative beat" },
|
|
1443
|
+
act: { type: "number", description: "Act number in the narrative sequence" },
|
|
1444
|
+
type_dramatic: { type: "string", description: "Dramatic type (e.g. 'Crisis/Antagonist Force', 'Setup', 'Turning Point')" },
|
|
1445
|
+
universes: {
|
|
1446
|
+
type: "array",
|
|
1447
|
+
items: { type: "string" },
|
|
1448
|
+
description: "Universe perspectives (engineer-world, ceremony-world, story-engine-world)"
|
|
1449
|
+
},
|
|
1450
|
+
description: { type: "string", description: "Detailed description of the narrative beat" },
|
|
1451
|
+
prose: { type: "string", description: "Prose narrative of the beat" },
|
|
1452
|
+
lessons: {
|
|
1453
|
+
type: "array",
|
|
1454
|
+
items: { type: "string" },
|
|
1455
|
+
description: "Key lessons or insights from this beat"
|
|
1456
|
+
},
|
|
1457
|
+
assessRelationalAlignment: { type: "boolean", description: "Whether to call iaip-mcp assess_relational_alignment" },
|
|
1458
|
+
initiateFourDirectionsInquiry: { type: "boolean", description: "Whether to call iaip-mcp get_direction_guidance" },
|
|
1459
|
+
filePath: { type: "string", description: "Path to narrative JSONL file (optional)" }
|
|
1460
|
+
},
|
|
1461
|
+
required: ["parentChartId", "title", "act", "type_dramatic", "universes", "description", "prose", "lessons"]
|
|
1462
|
+
}
|
|
1463
|
+
},
|
|
1464
|
+
{
|
|
1465
|
+
name: "telescope_narrative_beat",
|
|
1466
|
+
description: "Telescope a narrative beat into sub-beats for detailed exploration. Creates detailed sub-narrative structure from a parent beat.",
|
|
1467
|
+
inputSchema: {
|
|
1468
|
+
type: "object",
|
|
1469
|
+
properties: {
|
|
1470
|
+
parentBeatName: { type: "string", description: "Name of the parent narrative beat to telescope" },
|
|
1471
|
+
newCurrentReality: { type: "string", description: "Updated current reality for the telescoped beat" },
|
|
1472
|
+
initialSubBeats: {
|
|
1473
|
+
type: "array",
|
|
1474
|
+
items: {
|
|
1475
|
+
type: "object",
|
|
1476
|
+
properties: {
|
|
1477
|
+
title: { type: "string" },
|
|
1478
|
+
type_dramatic: { type: "string" },
|
|
1479
|
+
description: { type: "string" },
|
|
1480
|
+
prose: { type: "string" },
|
|
1481
|
+
lessons: { type: "array", items: { type: "string" } }
|
|
1482
|
+
},
|
|
1483
|
+
required: ["title", "type_dramatic", "description", "prose", "lessons"]
|
|
1484
|
+
},
|
|
1485
|
+
description: "Optional initial sub-beats to create"
|
|
1486
|
+
}
|
|
1487
|
+
},
|
|
1488
|
+
required: ["parentBeatName", "newCurrentReality"]
|
|
1489
|
+
}
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
name: "list_narrative_beats",
|
|
1493
|
+
description: "List all narrative beats, optionally filtered by parent chart ID. Shows multi-universe story progression.",
|
|
1494
|
+
inputSchema: {
|
|
1495
|
+
type: "object",
|
|
1496
|
+
properties: {
|
|
1497
|
+
parentChartId: { type: "string", description: "Optional: Filter by parent chart ID" }
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
];
|
|
1502
|
+
// Filter tools based on enabled tools set
|
|
1503
|
+
const filteredTools = allTools.filter(tool => enabledTools.has(tool.name));
|
|
1504
|
+
return {
|
|
1505
|
+
tools: filteredTools,
|
|
1506
|
+
};
|
|
1507
|
+
});
|
|
1508
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1509
|
+
try {
|
|
1510
|
+
const { name, arguments: args } = request.params;
|
|
1511
|
+
// Strict validation: name must exist
|
|
1512
|
+
if (!name || typeof name !== 'string') {
|
|
1513
|
+
return {
|
|
1514
|
+
content: [{ type: "text", text: `Error: Invalid tool name: ${name}` }],
|
|
1515
|
+
isError: true
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
// Strict validation: args must be object or undefined
|
|
1519
|
+
if (args !== undefined && (typeof args !== 'object' || args === null || Array.isArray(args))) {
|
|
1520
|
+
return {
|
|
1521
|
+
content: [{ type: "text", text: `Error: Tool arguments must be an object, received: ${typeof args}` }],
|
|
1522
|
+
isError: true
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
const toolArgs = args || {};
|
|
1526
|
+
switch (name) {
|
|
1527
|
+
case "create_entities": {
|
|
1528
|
+
const valResult = validate(toolArgs, { entities: ValidationSchemas.entityArray() });
|
|
1529
|
+
if (!valResult.valid)
|
|
1530
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1531
|
+
const result = await knowledgeGraphManager.createEntities(toolArgs.entities);
|
|
1532
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1533
|
+
}
|
|
1534
|
+
case "create_relations": {
|
|
1535
|
+
const valResult = validate(toolArgs, { relations: ValidationSchemas.relationArray() });
|
|
1536
|
+
if (!valResult.valid)
|
|
1537
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1538
|
+
const result = await knowledgeGraphManager.createRelations(toolArgs.relations);
|
|
1539
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1540
|
+
}
|
|
1541
|
+
case "add_observations": {
|
|
1542
|
+
const valResult = validate(toolArgs, {
|
|
1543
|
+
observations: {
|
|
1544
|
+
type: 'array',
|
|
1545
|
+
required: true,
|
|
1546
|
+
items: {
|
|
1547
|
+
type: 'object',
|
|
1548
|
+
properties: {
|
|
1549
|
+
entityName: { type: 'string', required: true },
|
|
1550
|
+
contents: { type: 'array', required: true, items: { type: 'string' } }
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
if (!valResult.valid)
|
|
1556
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1557
|
+
const result = await knowledgeGraphManager.addObservations(toolArgs.observations);
|
|
1558
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1559
|
+
}
|
|
1560
|
+
case "delete_entities": {
|
|
1561
|
+
const valResult = validate(toolArgs, { entityNames: ValidationSchemas.stringArray() });
|
|
1562
|
+
if (!valResult.valid)
|
|
1563
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1564
|
+
await knowledgeGraphManager.deleteEntities(toolArgs.entityNames);
|
|
1565
|
+
return { content: [{ type: "text", text: "Entities deleted successfully" }] };
|
|
1566
|
+
}
|
|
1567
|
+
case "delete_observations": {
|
|
1568
|
+
const valResult = validate(toolArgs, {
|
|
1569
|
+
deletions: {
|
|
1570
|
+
type: 'array',
|
|
1571
|
+
required: true,
|
|
1572
|
+
items: {
|
|
1573
|
+
type: 'object',
|
|
1574
|
+
properties: {
|
|
1575
|
+
entityName: { type: 'string', required: true },
|
|
1576
|
+
observations: { type: 'array', required: true, items: { type: 'string' } }
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
if (!valResult.valid)
|
|
1582
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1583
|
+
await knowledgeGraphManager.deleteObservations(toolArgs.deletions);
|
|
1584
|
+
return { content: [{ type: "text", text: "Observations deleted successfully" }] };
|
|
1585
|
+
}
|
|
1586
|
+
case "delete_relations": {
|
|
1587
|
+
const valResult = validate(toolArgs, { relations: ValidationSchemas.relationArray() });
|
|
1588
|
+
if (!valResult.valid)
|
|
1589
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1590
|
+
await knowledgeGraphManager.deleteRelations(toolArgs.relations);
|
|
1591
|
+
return { content: [{ type: "text", text: "Relations deleted successfully" }] };
|
|
1592
|
+
}
|
|
1593
|
+
case "read_graph": {
|
|
1594
|
+
const result = await knowledgeGraphManager.readGraph();
|
|
1595
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1596
|
+
}
|
|
1597
|
+
case "search_nodes": {
|
|
1598
|
+
const valResult = validate(toolArgs, { query: ValidationSchemas.nonEmptyString() });
|
|
1599
|
+
if (!valResult.valid)
|
|
1600
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1601
|
+
const result = await knowledgeGraphManager.searchNodes(toolArgs.query);
|
|
1602
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1603
|
+
}
|
|
1604
|
+
case "open_nodes": {
|
|
1605
|
+
const valResult = validate(toolArgs, { names: { type: 'array', required: true, minLength: 1, items: { type: 'string' } } });
|
|
1606
|
+
if (!valResult.valid)
|
|
1607
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1608
|
+
const result = await knowledgeGraphManager.openNodes(toolArgs.names);
|
|
1609
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1610
|
+
}
|
|
1611
|
+
case "create_structural_tension_chart": {
|
|
1612
|
+
const valResult = validate(toolArgs, {
|
|
1613
|
+
desiredOutcome: ValidationSchemas.nonEmptyString(),
|
|
1614
|
+
currentReality: ValidationSchemas.nonEmptyString(),
|
|
1615
|
+
dueDate: ValidationSchemas.isoDate(),
|
|
1616
|
+
actionSteps: { type: 'array', items: { type: 'string' } }
|
|
1617
|
+
});
|
|
1618
|
+
if (!valResult.valid)
|
|
1619
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1620
|
+
const chartResult = await knowledgeGraphManager.createStructuralTensionChart(toolArgs.desiredOutcome, toolArgs.currentReality, toolArgs.dueDate, (Array.isArray(toolArgs.actionSteps) ? toolArgs.actionSteps : []));
|
|
1621
|
+
return { content: [{ type: "text", text: JSON.stringify(chartResult, null, 2) }] };
|
|
1622
|
+
}
|
|
1623
|
+
case "telescope_action_step": {
|
|
1624
|
+
const valResult = validate(toolArgs, {
|
|
1625
|
+
actionStepName: ValidationSchemas.nonEmptyString(),
|
|
1626
|
+
newCurrentReality: ValidationSchemas.nonEmptyString(),
|
|
1627
|
+
initialActionSteps: { type: 'array', items: { type: 'string' } }
|
|
1628
|
+
});
|
|
1629
|
+
if (!valResult.valid)
|
|
1630
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1631
|
+
const telescopeResult = await knowledgeGraphManager.telescopeActionStep(toolArgs.actionStepName, toolArgs.newCurrentReality, (Array.isArray(toolArgs.initialActionSteps) ? toolArgs.initialActionSteps : []));
|
|
1632
|
+
return { content: [{ type: "text", text: JSON.stringify(telescopeResult, null, 2) }] };
|
|
1633
|
+
}
|
|
1634
|
+
case "mark_action_complete": {
|
|
1635
|
+
const valResult = validate(toolArgs, { actionStepName: ValidationSchemas.nonEmptyString() });
|
|
1636
|
+
if (!valResult.valid)
|
|
1637
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1638
|
+
await knowledgeGraphManager.markActionStepComplete(toolArgs.actionStepName);
|
|
1639
|
+
return { content: [{ type: "text", text: `Action step '${toolArgs.actionStepName}' marked as complete and current reality updated` }] };
|
|
1640
|
+
}
|
|
1641
|
+
case "get_chart_progress": {
|
|
1642
|
+
const valResult = validate(toolArgs, { chartId: ValidationSchemas.nonEmptyString() });
|
|
1643
|
+
if (!valResult.valid)
|
|
1644
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1645
|
+
const progressResult = await knowledgeGraphManager.getChartProgress(toolArgs.chartId);
|
|
1646
|
+
return { content: [{ type: "text", text: JSON.stringify(progressResult, null, 2) }] };
|
|
1647
|
+
}
|
|
1648
|
+
case "list_active_charts": {
|
|
1649
|
+
const chartsResult = await knowledgeGraphManager.listActiveCharts();
|
|
1650
|
+
let hierarchyText = "## Structural Tension Charts Hierarchy\n\n";
|
|
1651
|
+
const masterCharts = chartsResult.filter(c => c.level === 0);
|
|
1652
|
+
const actionCharts = chartsResult.filter(c => c.level > 0);
|
|
1653
|
+
masterCharts.forEach(master => {
|
|
1654
|
+
const progress = master.progress > 0 ? ` (${Math.round(master.progress * 100)}% complete)` : "";
|
|
1655
|
+
const dueDate = master.dueDate ? ` [Due: ${new Date(master.dueDate).toLocaleDateString()}]` : "";
|
|
1656
|
+
hierarchyText += `š **${master.desiredOutcome}** (Master Chart)${progress}${dueDate}\n`;
|
|
1657
|
+
hierarchyText += ` ID: ${master.chartId}\n`;
|
|
1658
|
+
const actions = actionCharts.filter(a => a.parentChart === master.chartId);
|
|
1659
|
+
if (actions.length > 0) {
|
|
1660
|
+
actions.forEach((action, index) => {
|
|
1661
|
+
const isLast = index === actions.length - 1;
|
|
1662
|
+
const connector = isLast ? "āāā " : "āāā ";
|
|
1663
|
+
const actionProgress = action.progress > 0 ? ` (${Math.round(action.progress * 100)}%)` : "";
|
|
1664
|
+
const actionDue = action.dueDate ? ` [${new Date(action.dueDate).toLocaleDateString()}]` : "";
|
|
1665
|
+
hierarchyText += ` ${connector}šÆ ${action.desiredOutcome} (Action Step)${actionProgress}${actionDue}\n`;
|
|
1666
|
+
hierarchyText += ` ID: ${action.chartId}\n`;
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
else {
|
|
1670
|
+
hierarchyText += ` āāā (No action steps yet)\n`;
|
|
1671
|
+
}
|
|
1672
|
+
hierarchyText += "\n";
|
|
1673
|
+
});
|
|
1674
|
+
if (masterCharts.length === 0) {
|
|
1675
|
+
hierarchyText += "No active structural tension charts found.\n\n";
|
|
1676
|
+
hierarchyText += "š” Create your first chart with: create_structural_tension_chart\n";
|
|
1677
|
+
}
|
|
1678
|
+
return { content: [{ type: "text", text: hierarchyText }] };
|
|
1679
|
+
}
|
|
1680
|
+
case "update_action_progress": {
|
|
1681
|
+
const valResult = validate(toolArgs, {
|
|
1682
|
+
actionStepName: ValidationSchemas.nonEmptyString(),
|
|
1683
|
+
progressObservation: ValidationSchemas.nonEmptyString(),
|
|
1684
|
+
updateCurrentReality: { type: 'boolean' }
|
|
1685
|
+
});
|
|
1686
|
+
if (!valResult.valid)
|
|
1687
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1688
|
+
await knowledgeGraphManager.updateActionProgress(toolArgs.actionStepName, toolArgs.progressObservation, toolArgs.updateCurrentReality === true);
|
|
1689
|
+
return { content: [{ type: "text", text: `Action step '${toolArgs.actionStepName}' progress updated` }] };
|
|
1690
|
+
}
|
|
1691
|
+
case "update_current_reality": {
|
|
1692
|
+
const valResult = validate(toolArgs, {
|
|
1693
|
+
chartId: ValidationSchemas.nonEmptyString(),
|
|
1694
|
+
newObservations: { type: 'array', required: true, minLength: 1, items: { type: 'string' } }
|
|
1695
|
+
});
|
|
1696
|
+
if (!valResult.valid)
|
|
1697
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1698
|
+
await knowledgeGraphManager.updateCurrentReality(toolArgs.chartId, toolArgs.newObservations);
|
|
1699
|
+
return { content: [{ type: "text", text: `Current reality updated for chart '${toolArgs.chartId}'` }] };
|
|
1700
|
+
}
|
|
1701
|
+
case "manage_action_step": {
|
|
1702
|
+
const valResult = validate(toolArgs, {
|
|
1703
|
+
parentReference: ValidationSchemas.nonEmptyString(),
|
|
1704
|
+
actionDescription: ValidationSchemas.nonEmptyString(),
|
|
1705
|
+
currentReality: { type: 'string' },
|
|
1706
|
+
initialActionSteps: { type: 'array', items: { type: 'string' } },
|
|
1707
|
+
dueDate: { type: 'date' }
|
|
1708
|
+
});
|
|
1709
|
+
if (!valResult.valid)
|
|
1710
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1711
|
+
const manageActionResult = await knowledgeGraphManager.manageActionStep(toolArgs.parentReference, toolArgs.actionDescription, toolArgs.currentReality, toolArgs.initialActionSteps, toolArgs.dueDate);
|
|
1712
|
+
return { content: [{ type: "text", text: `Action step '${toolArgs.actionDescription}' managed for parent '${toolArgs.parentReference}'. Result: ${JSON.stringify(manageActionResult, null, 2)}` }] };
|
|
1713
|
+
}
|
|
1714
|
+
case "add_action_step": {
|
|
1715
|
+
const valResult = validate(toolArgs, {
|
|
1716
|
+
parentChartId: ValidationSchemas.nonEmptyString(),
|
|
1717
|
+
actionStepTitle: ValidationSchemas.nonEmptyString(),
|
|
1718
|
+
currentReality: ValidationSchemas.nonEmptyString(),
|
|
1719
|
+
dueDate: { type: 'date' }
|
|
1720
|
+
});
|
|
1721
|
+
if (!valResult.valid)
|
|
1722
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1723
|
+
const addActionResult = await knowledgeGraphManager.addActionStep(toolArgs.parentChartId, toolArgs.actionStepTitle, toolArgs.dueDate, toolArgs.currentReality);
|
|
1724
|
+
return { content: [{ type: "text", text: `Action step '${toolArgs.actionStepTitle}' added to chart '${toolArgs.parentChartId}' as telescoped chart '${addActionResult.chartId}'` }] };
|
|
1725
|
+
}
|
|
1726
|
+
case "remove_action_step": {
|
|
1727
|
+
const valResult = validate(toolArgs, {
|
|
1728
|
+
parentChartId: ValidationSchemas.nonEmptyString(),
|
|
1729
|
+
actionStepName: ValidationSchemas.nonEmptyString()
|
|
1730
|
+
});
|
|
1731
|
+
if (!valResult.valid)
|
|
1732
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1733
|
+
await knowledgeGraphManager.removeActionStep(toolArgs.parentChartId, toolArgs.actionStepName);
|
|
1734
|
+
return { content: [{ type: "text", text: `Action step '${toolArgs.actionStepName}' removed from chart '${toolArgs.parentChartId}'` }] };
|
|
1735
|
+
}
|
|
1736
|
+
case "update_desired_outcome": {
|
|
1737
|
+
const valResult = validate(toolArgs, {
|
|
1738
|
+
chartId: ValidationSchemas.nonEmptyString(),
|
|
1739
|
+
newDesiredOutcome: ValidationSchemas.nonEmptyString()
|
|
1740
|
+
});
|
|
1741
|
+
if (!valResult.valid)
|
|
1742
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1743
|
+
await knowledgeGraphManager.updateDesiredOutcome(toolArgs.chartId, toolArgs.newDesiredOutcome);
|
|
1744
|
+
return { content: [{ type: "text", text: `Desired outcome updated for chart '${toolArgs.chartId}'` }] };
|
|
1745
|
+
}
|
|
1746
|
+
case "creator_moment_of_truth": {
|
|
1747
|
+
const valResult = validate(toolArgs, {
|
|
1748
|
+
chartId: ValidationSchemas.nonEmptyString(),
|
|
1749
|
+
step: { type: 'enum', enumValues: ['full_review', 'acknowledge', 'analyze', 'plan', 'feedback'] },
|
|
1750
|
+
userInput: { type: 'string' }
|
|
1751
|
+
});
|
|
1752
|
+
if (!valResult.valid)
|
|
1753
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1754
|
+
const cmotStep = toolArgs.step || "full_review";
|
|
1755
|
+
const cmotUserInput = toolArgs.userInput;
|
|
1756
|
+
const cmotProgress = await knowledgeGraphManager.getChartProgress(toolArgs.chartId);
|
|
1757
|
+
const cmotGraph = await knowledgeGraphManager.readGraph();
|
|
1758
|
+
const cmotDesiredOutcome = cmotGraph.entities.find(e => e.name === `${toolArgs.chartId}_desired_outcome`);
|
|
1759
|
+
const cmotCurrentReality = cmotGraph.entities.find(e => e.name === `${toolArgs.chartId}_current_reality`);
|
|
1760
|
+
const cmotGuidance = {
|
|
1761
|
+
full_review: `## Creator Moment of Truth - Chart Review\n\n**Chart**: ${toolArgs.chartId}\n**Desired Outcome**: ${cmotDesiredOutcome?.observations[0] || 'Unknown'}\n**Current Reality**: ${cmotCurrentReality?.observations.join('; ') || 'Unknown'}\n**Progress**: ${Math.round(cmotProgress.progress * 100)}% (${cmotProgress.completedActions}/${cmotProgress.totalActions} action steps)\n\n---\n\n### The Four-Step Review Process\n\nGuide the user through each step to transform discrepancies into learning:\n\n**Step 1: ACKNOWLEDGE THE TRUTH**\nWhat difference exists between what was expected and what was delivered?\n- Report facts only, no excuses\n- "We expected X, we delivered Y"\n- Ask: "Looking at this chart, what expected progress didn't happen? What did happen instead?"\n\n**Step 2: ANALYZE HOW IT HAPPENED**\nHow did this come to pass?\n- Step-by-step tracking (not blame)\n- What assumptions were made?\n- How was it approached?\n- Ask: "Walk me through what happened. What did you tell yourself? What assumptions turned out to be wrong?"\n\n**Step 3: CREATE A PLAN FOR NEXT TIME**\nGiven what you discovered, how will you change your approach?\n- What patterns need to change?\n- What specific actions will be different?\n- Ask: "Based on what you learned, what will you do differently? What new action steps should we add?"\n\n**Step 4: SET UP A FEEDBACK SYSTEM**\nHow will you track whether you're actually making the changes?\n- Simple self-management system\n- How to notice old patterns returning\n- Ask: "How will you know if you're falling back to old patterns? What will remind you of the new approach?"\n\n---\n\n**After completing the review**: Update current reality with new observations, adjust action steps as needed.\n\n**Remember**: The goal is not perfection but effectiveness. Discrepancies are learning opportunities, not failures.`,
|
|
1762
|
+
acknowledge: `## Step 1: ACKNOWLEDGE THE TRUTH\n\n**Chart Progress**: ${Math.round(cmotProgress.progress * 100)}%\n**Desired Outcome**: ${cmotDesiredOutcome?.observations[0] || 'Unknown'}\n\n**Question**: What difference exists between what was expected and what was delivered?\n\nGuidelines:\n- Simply report the facts\n- No excuses, no blame\n- "We expected X, we delivered Y"\n- Focus on seeing reality clearly\n\n${cmotUserInput ? `\n**User's Observation**: ${cmotUserInput}\n\nNext: Proceed to Step 2 (analyze) to explore how this came to pass.` : 'Please share what you expected vs. what actually happened.'}`,
|
|
1763
|
+
analyze: `## Step 2: ANALYZE HOW IT HAPPENED\n\n**Question**: How did this come to pass?\n\nGuidelines:\n- Step-by-step tracking (this is co-exploration, not blame)\n- What assumptions were made?\n- What did you tell yourself?\n- How did you approach it?\n\n${cmotUserInput ? `\n**User's Analysis**: ${cmotUserInput}\n\nNext: Proceed to Step 3 (plan) to create adjustments based on these insights.` : 'Walk through the sequence of events. What assumptions turned out not to be true?'}`,
|
|
1764
|
+
plan: `## Step 3: CREATE A PLAN FOR NEXT TIME\n\n**Question**: Given what you discovered, how will you change your approach?\n\nGuidelines:\n- What assumptions turned out not to be true?\n- What patterns need to change?\n- What specific actions will you take differently?\n\n${cmotUserInput ? `\n**User's Plan**: ${cmotUserInput}\n\nNext: Use add_action_step or update_current_reality to record these changes, then proceed to Step 4 (feedback).` : 'What concrete adjustments will you make? Should we add new action steps or update the chart?'}`,
|
|
1765
|
+
feedback: `## Step 4: SET UP A FEEDBACK SYSTEM\n\n**Question**: How will you track whether you're actually making the changes?\n\nGuidelines:\n- Simple system for self-management\n- How will you notice if you're falling back to old patterns?\n- What will remind you of the new approach?\n\n${cmotUserInput ? `\n**User's Feedback System**: ${cmotUserInput}\n\nā
**Review Complete**. Use update_current_reality to record key learnings from this review.` : 'What simple tracking will help you stay on the new course?'}`
|
|
1766
|
+
};
|
|
1767
|
+
return { content: [{ type: "text", text: cmotGuidance[cmotStep] || cmotGuidance.full_review }] };
|
|
1768
|
+
}
|
|
1769
|
+
case "create_narrative_beat": {
|
|
1770
|
+
const valResult = validate(toolArgs, {
|
|
1771
|
+
parentChartId: ValidationSchemas.nonEmptyString(),
|
|
1772
|
+
title: ValidationSchemas.nonEmptyString(),
|
|
1773
|
+
act: { type: 'number', required: true, minValue: 1 },
|
|
1774
|
+
type_dramatic: ValidationSchemas.nonEmptyString(),
|
|
1775
|
+
universes: { type: 'array', required: true, minLength: 1, items: { type: 'string' } },
|
|
1776
|
+
description: ValidationSchemas.nonEmptyString(),
|
|
1777
|
+
prose: ValidationSchemas.nonEmptyString(),
|
|
1778
|
+
lessons: { type: 'array', required: true, items: { type: 'string' } },
|
|
1779
|
+
assessRelationalAlignment: { type: 'boolean' },
|
|
1780
|
+
initiateFourDirectionsInquiry: { type: 'boolean' },
|
|
1781
|
+
filePath: { type: 'string' }
|
|
1782
|
+
});
|
|
1783
|
+
if (!valResult.valid)
|
|
1784
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1785
|
+
const beatResult = await knowledgeGraphManager.createNarrativeBeat(toolArgs.parentChartId, toolArgs.title, toolArgs.act, toolArgs.type_dramatic, toolArgs.universes, toolArgs.description, toolArgs.prose, toolArgs.lessons, toolArgs.assessRelationalAlignment || false, toolArgs.initiateFourDirectionsInquiry || false, toolArgs.filePath);
|
|
1786
|
+
return { content: [{ type: "text", text: JSON.stringify(beatResult, null, 2) }] };
|
|
1787
|
+
}
|
|
1788
|
+
case "telescope_narrative_beat": {
|
|
1789
|
+
const valResult = validate(toolArgs, {
|
|
1790
|
+
parentBeatName: ValidationSchemas.nonEmptyString(),
|
|
1791
|
+
newCurrentReality: ValidationSchemas.nonEmptyString(),
|
|
1792
|
+
initialSubBeats: {
|
|
1793
|
+
type: 'array',
|
|
1794
|
+
items: {
|
|
1795
|
+
type: 'object',
|
|
1796
|
+
properties: {
|
|
1797
|
+
title: { type: 'string', required: true },
|
|
1798
|
+
type_dramatic: { type: 'string', required: true },
|
|
1799
|
+
description: { type: 'string', required: true },
|
|
1800
|
+
prose: { type: 'string', required: true },
|
|
1801
|
+
lessons: { type: 'array', required: true, items: { type: 'string' } }
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
});
|
|
1806
|
+
if (!valResult.valid)
|
|
1807
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1808
|
+
const telescopeResult = await knowledgeGraphManager.telescopeNarrativeBeat(toolArgs.parentBeatName, toolArgs.newCurrentReality, (Array.isArray(toolArgs.initialSubBeats) ? toolArgs.initialSubBeats : []));
|
|
1809
|
+
return { content: [{ type: "text", text: JSON.stringify(telescopeResult, null, 2) }] };
|
|
1810
|
+
}
|
|
1811
|
+
case "list_narrative_beats": {
|
|
1812
|
+
const valResult = validate(toolArgs, {
|
|
1813
|
+
parentChartId: { type: 'string' }
|
|
1814
|
+
});
|
|
1815
|
+
if (!valResult.valid)
|
|
1816
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1817
|
+
const parentChartId = toolArgs.parentChartId;
|
|
1818
|
+
const beatsResult = await knowledgeGraphManager.listNarrativeBeats(parentChartId);
|
|
1819
|
+
if (beatsResult.length === 0) {
|
|
1820
|
+
return { content: [{ type: "text", text: "No narrative beats found." }] };
|
|
1821
|
+
}
|
|
1822
|
+
let beatsText = "## š Narrative Beats\n\n";
|
|
1823
|
+
beatsResult.forEach((beat) => {
|
|
1824
|
+
const act = beat.metadata?.act || '?';
|
|
1825
|
+
const type = beat.metadata?.type_dramatic || 'Unknown';
|
|
1826
|
+
const universes = beat.metadata?.universes?.join(', ') || 'Unknown';
|
|
1827
|
+
const lessons = beat.metadata?.narrative?.lessons || [];
|
|
1828
|
+
beatsText += `### Act ${act}: ${type}\n`;
|
|
1829
|
+
beatsText += `**Name**: ${beat.name}\n`;
|
|
1830
|
+
beatsText += `**Universes**: ${universes}\n`;
|
|
1831
|
+
beatsText += `**Description**: ${beat.metadata?.narrative?.description || 'N/A'}\n`;
|
|
1832
|
+
if (lessons.length > 0) {
|
|
1833
|
+
beatsText += `**Lessons**: ${lessons.join(', ')}\n`;
|
|
1834
|
+
}
|
|
1835
|
+
beatsText += "\n";
|
|
1836
|
+
});
|
|
1837
|
+
return { content: [{ type: "text", text: beatsText }] };
|
|
1838
|
+
}
|
|
1839
|
+
case "init_llm_guidance": {
|
|
1840
|
+
const valResult = validate(toolArgs, {
|
|
1841
|
+
format: { type: 'enum', enumValues: ['full', 'quick', 'save_directive'] }
|
|
1842
|
+
});
|
|
1843
|
+
if (!valResult.valid)
|
|
1844
|
+
return { content: [{ type: "text", text: `Error: ${valResult.error}` }], isError: true };
|
|
1845
|
+
const format = toolArgs.format || "full";
|
|
1846
|
+
if (format === "save_directive") {
|
|
1847
|
+
return { content: [{ type: "text", text: `## š” RECOMMENDED: Save This Guidance\n\n**Claude Code**: Add this guidance to CLAUDE.md in your project directory\n**Gemini**: Save as GEMINI.md in your workspace \n**Other Agents**: Create AGENTS.md or similar session memory file\n\nThis ensures you remember COAIA Memory's structural tension principles across our entire conversation.\n\n**Quick Command**: Use format="full" to get the complete guidance content to save.` }] };
|
|
1848
|
+
}
|
|
1849
|
+
if (format === "quick") {
|
|
1850
|
+
return { content: [{ type: "text", text: `## šØ COAIA Memory Quick Reference\n\n**CRITICAL**: "Ready to begin" = WRONG. Current reality must be factual assessment.\n\n**Core Tools**:\n1. \`list_active_charts\` ā Start here, see all charts\n2. \`create_structural_tension_chart\` ā New chart (outcome + reality + actions)\n3. \`add_action_step\` ā Add strategic actions (creates telescoped chart)\n4. \`telescope_action_step\` ā Break down actions into detailed sub-charts\n\n**Common Mistakes**:\nā "Ready to begin Django tutorial" \nā
"Never used Django, completed Python basics"\n\nUse format="full" for complete guidance.` }] };
|
|
1851
|
+
}
|
|
1852
|
+
// Default: full guidance
|
|
1853
|
+
return { content: [{ type: "text", text: LLM_GUIDANCE }] };
|
|
1854
|
+
}
|
|
1855
|
+
default: {
|
|
1856
|
+
return {
|
|
1857
|
+
content: [{ type: "text", text: `Error: Unknown tool: ${name}` }],
|
|
1858
|
+
isError: true
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
catch (error) {
|
|
1864
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1865
|
+
return {
|
|
1866
|
+
content: [{ type: "text", text: `Error executing tool: ${errorMessage}` }],
|
|
1867
|
+
isError: true
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
async function main() {
|
|
1872
|
+
const transport = new StdioServerTransport();
|
|
1873
|
+
await server.connect(transport);
|
|
1874
|
+
console.error("COAIA Narrative - Creative Oriented AI Assistant Memory Server - Narrative Beat Extension running on stdio");
|
|
1875
|
+
}
|
|
1876
|
+
main().catch((error) => {
|
|
1877
|
+
console.error("Fatal error in main():", error);
|
|
1878
|
+
process.exit(1);
|
|
1879
|
+
});
|