coaiajs 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/KINSHIP.md +1 -1
  2. package/README.md +191 -75
  3. package/dist/mcp/config.d.ts.map +1 -0
  4. package/dist/mcp/config.js +0 -2
  5. package/dist/mcp/config.js.map +1 -0
  6. package/dist/mcp/prompts.d.ts.map +1 -0
  7. package/dist/mcp/prompts.js.map +1 -0
  8. package/dist/mcp/resources.d.ts.map +1 -0
  9. package/dist/mcp/resources.js.map +1 -0
  10. package/dist/mcp/server.d.ts.map +1 -0
  11. package/dist/mcp/server.js +1 -1
  12. package/dist/mcp/server.js.map +1 -0
  13. package/dist/mcp/tools/coaiapy-tools.d.ts.map +1 -0
  14. package/dist/mcp/tools/coaiapy-tools.js.map +1 -0
  15. package/dist/mcp/tools/index.d.ts.map +1 -0
  16. package/dist/mcp/tools/index.js.map +1 -0
  17. package/dist/src/audio.d.ts.map +1 -0
  18. package/dist/src/audio.js.map +1 -0
  19. package/dist/src/cli-helpers.d.ts.map +1 -0
  20. package/dist/src/cli-helpers.js.map +1 -0
  21. package/dist/src/cli.d.ts.map +1 -0
  22. package/dist/src/cli.js.map +1 -0
  23. package/dist/src/config.d.ts.map +1 -0
  24. package/dist/src/config.js.map +1 -0
  25. package/dist/src/environment.d.ts.map +1 -0
  26. package/dist/src/environment.js.map +1 -0
  27. package/dist/src/github.d.ts.map +1 -0
  28. package/dist/src/github.js.map +1 -0
  29. package/dist/src/index.d.ts +1 -0
  30. package/dist/src/index.d.ts.map +1 -0
  31. package/dist/src/index.js +1 -0
  32. package/dist/src/index.js.map +1 -0
  33. package/dist/src/langfuse/client.d.ts.map +1 -0
  34. package/dist/src/langfuse/client.js.map +1 -0
  35. package/dist/src/langfuse/comments.d.ts.map +1 -0
  36. package/dist/src/langfuse/comments.js.map +1 -0
  37. package/dist/src/langfuse/datasets.d.ts.map +1 -0
  38. package/dist/src/langfuse/datasets.js.map +1 -0
  39. package/dist/src/langfuse/index.d.ts.map +1 -0
  40. package/dist/src/langfuse/index.js.map +1 -0
  41. package/dist/src/langfuse/media.d.ts.map +1 -0
  42. package/dist/src/langfuse/media.js.map +1 -0
  43. package/dist/src/langfuse/observations.d.ts.map +1 -0
  44. package/dist/src/langfuse/observations.js.map +1 -0
  45. package/dist/src/langfuse/prompts.d.ts.map +1 -0
  46. package/dist/src/langfuse/prompts.js.map +1 -0
  47. package/dist/src/langfuse/scores.d.ts.map +1 -0
  48. package/dist/src/langfuse/scores.js.map +1 -0
  49. package/dist/src/langfuse/traces.d.ts.map +1 -0
  50. package/dist/src/langfuse/traces.js.map +1 -0
  51. package/dist/src/llm.d.ts.map +1 -0
  52. package/dist/src/llm.js.map +1 -0
  53. package/dist/src/narrative/graph-manager.d.ts.map +1 -0
  54. package/dist/src/narrative/graph-manager.js.map +1 -0
  55. package/dist/src/narrative/index.d.ts.map +1 -0
  56. package/dist/src/narrative/index.js.map +1 -0
  57. package/dist/src/narrative/markdown-export.d.ts.map +1 -0
  58. package/dist/src/narrative/markdown-export.js.map +1 -0
  59. package/dist/src/narrative/tool-definitions.d.ts.map +1 -0
  60. package/dist/src/narrative/tool-definitions.js.map +1 -0
  61. package/dist/src/narrative/tool-handlers.d.ts.map +1 -0
  62. package/dist/src/narrative/tool-handlers.js.map +1 -0
  63. package/dist/src/narrative/types.d.ts.map +1 -0
  64. package/dist/src/narrative/types.js.map +1 -0
  65. package/dist/src/narrative/validation.d.ts.map +1 -0
  66. package/dist/src/narrative/validation.js.map +1 -0
  67. package/dist/src/pde/index.d.ts.map +1 -0
  68. package/dist/src/pde/index.js.map +1 -0
  69. package/dist/src/pde/mcp-handlers.d.ts.map +1 -0
  70. package/dist/src/pde/mcp-handlers.js.map +1 -0
  71. package/dist/src/pde/mcp-tools.d.ts.map +1 -0
  72. package/dist/src/pde/mcp-tools.js.map +1 -0
  73. package/dist/src/pde/session-manager.d.ts.map +1 -0
  74. package/dist/src/pde/session-manager.js.map +1 -0
  75. package/dist/src/pde/stc-mapper.d.ts.map +1 -0
  76. package/dist/src/pde/stc-mapper.js.map +1 -0
  77. package/dist/src/pipeline/index.d.ts.map +1 -0
  78. package/dist/src/pipeline/index.js.map +1 -0
  79. package/dist/src/pipeline/template-engine.d.ts.map +1 -0
  80. package/dist/src/pipeline/template-engine.js.map +1 -0
  81. package/dist/src/planning/index.d.ts.map +1 -0
  82. package/dist/src/planning/index.js.map +1 -0
  83. package/dist/src/planning/mcp-handlers.d.ts.map +1 -0
  84. package/dist/src/planning/mcp-handlers.js.map +1 -0
  85. package/dist/src/planning/mcp-tools.d.ts.map +1 -0
  86. package/dist/src/planning/mcp-tools.js.map +1 -0
  87. package/dist/src/planning/plan-parser.d.ts.map +1 -0
  88. package/dist/src/planning/plan-parser.js.map +1 -0
  89. package/dist/src/redis.d.ts.map +1 -0
  90. package/dist/src/redis.js.map +1 -0
  91. package/dist/src/types.d.ts.map +1 -0
  92. package/dist/src/types.js.map +1 -0
  93. package/dist/src/version.d.ts.map +1 -0
  94. package/dist/src/version.js.map +1 -0
  95. package/llms-full.txt +361 -0
  96. package/llms.txt +43 -0
  97. package/package.json +79 -12
  98. package/.claude/settings.local.json +0 -17
  99. package/.claude-plugin/marketplace.json +0 -26
  100. package/articles/academic/NOTES.md +0 -1
  101. package/articles/academic/README.md +0 -1
  102. package/articles/academic/creative-orientation-vs-problem-solving.md +0 -177
  103. package/articles/academic/jsonl-knowledge-graphs-agent-memory.md +0 -142
  104. package/articles/academic/langfuse-observability-llm-pipelines.md +0 -144
  105. package/articles/academic/medicine-wheel-software-architecture.md +0 -163
  106. package/articles/academic/mmot-autonomous-agents.md +0 -156
  107. package/articles/academic/model-context-protocol-interagent.md +0 -161
  108. package/articles/academic/pde-prompt-decomposition.md +0 -186
  109. package/articles/academic/structural-tension-in-ai-agents.md +0 -134
  110. package/articles/reviews/mcp-protocol-design-review.md +0 -170
  111. package/articles/reviews/observability-ai-systems-review.md +0 -176
  112. package/articles/reviews/prompt-engineering-decomposition-review.md +0 -184
  113. package/articles/surveys/agent-orchestration-survey.md +0 -186
  114. package/articles/surveys/knowledge-graph-storage-survey.md +0 -204
  115. package/articles/surveys/structural-tension-methodology-survey.md +0 -154
  116. package/articles/technical/aws-sdk-v3-polly.md +0 -270
  117. package/articles/technical/commander-cli-framework.md +0 -262
  118. package/articles/technical/dotenv-config-patterns.md +0 -360
  119. package/articles/technical/ioredis-vs-redis.md +0 -142
  120. package/articles/technical/langfuse-js-sdk-vs-rest.md +0 -191
  121. package/articles/technical/mcp-sdk-typescript.md +0 -291
  122. package/articles/technical/octokit-github-api.md +0 -293
  123. package/articles/technical/openai-sdk-modern.md +0 -231
  124. package/articles/technical/yaml-parsing-node.md +0 -266
  125. package/articles/technical/zod-runtime-validation.md +0 -212
  126. package/coaiajs-langfuse-claude-plugin/.claude-plugin/marketplace.json +0 -16
  127. package/coaiajs-langfuse-claude-plugin/.claude-plugin/plugin.json +0 -10
  128. package/coaiajs-langfuse-claude-plugin/.mcp.json +0 -8
  129. package/coaiajs-langfuse-claude-plugin/README.md +0 -60
  130. package/mcp/config.ts +0 -225
  131. package/mcp/prompts.ts +0 -131
  132. package/mcp/resources.ts +0 -84
  133. package/mcp/server.ts +0 -519
  134. package/mcp/tools/coaiapy-tools.ts +0 -366
  135. package/mcp/tools/index.ts +0 -4
  136. package/src/audio.ts +0 -76
  137. package/src/cli-helpers.ts +0 -86
  138. package/src/cli.ts +0 -1261
  139. package/src/config.ts +0 -207
  140. package/src/environment.ts +0 -171
  141. package/src/github.ts +0 -143
  142. package/src/index.ts +0 -82
  143. package/src/langfuse/client.ts +0 -105
  144. package/src/langfuse/comments.ts +0 -52
  145. package/src/langfuse/datasets.ts +0 -178
  146. package/src/langfuse/index.ts +0 -37
  147. package/src/langfuse/media.ts +0 -193
  148. package/src/langfuse/observations.ts +0 -155
  149. package/src/langfuse/prompts.ts +0 -157
  150. package/src/langfuse/scores.ts +0 -456
  151. package/src/langfuse/traces.ts +0 -353
  152. package/src/llm.ts +0 -106
  153. package/src/narrative/graph-manager.ts +0 -1358
  154. package/src/narrative/index.ts +0 -188
  155. package/src/narrative/markdown-export.ts +0 -535
  156. package/src/narrative/tool-definitions.ts +0 -635
  157. package/src/narrative/tool-handlers.ts +0 -528
  158. package/src/narrative/types.ts +0 -9
  159. package/src/narrative/validation.ts +0 -179
  160. package/src/pde/index.ts +0 -34
  161. package/src/pde/mcp-handlers.ts +0 -359
  162. package/src/pde/mcp-tools.ts +0 -201
  163. package/src/pde/session-manager.ts +0 -248
  164. package/src/pde/stc-mapper.ts +0 -298
  165. package/src/pipeline/index.ts +0 -7
  166. package/src/pipeline/template-engine.ts +0 -398
  167. package/src/planning/index.ts +0 -32
  168. package/src/planning/mcp-handlers.ts +0 -369
  169. package/src/planning/mcp-tools.ts +0 -155
  170. package/src/planning/plan-parser.ts +0 -587
  171. package/src/redis.ts +0 -111
  172. package/src/types.ts +0 -281
  173. package/src/version.ts +0 -39
  174. package/test/config.test.mjs +0 -93
  175. package/tsconfig.json +0 -26
@@ -1,179 +0,0 @@
1
- // Strict input validation for multi-LLM compatibility (no zod dependency)
2
- type ValidationType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'enum';
3
-
4
- interface ValidationRule {
5
- type: ValidationType;
6
- required?: boolean;
7
- minLength?: number;
8
- maxLength?: number;
9
- pattern?: RegExp;
10
- minValue?: number;
11
- maxValue?: number;
12
- enumValues?: (string | number)[];
13
- items?: ValidationRule;
14
- properties?: Record<string, ValidationRule>;
15
- }
16
-
17
- interface ValidationSchema {
18
- [key: string]: ValidationRule;
19
- }
20
-
21
- export function validate(args: unknown, schema: ValidationSchema): { valid: boolean; error?: string } {
22
- if (typeof args !== 'object' || args === null) {
23
- return { valid: false, error: 'Arguments must be an object' };
24
- }
25
-
26
- const record = args as Record<string, unknown>;
27
-
28
- for (const [key, rule] of Object.entries(schema)) {
29
- const value = record[key];
30
-
31
- if (rule.required && (value === undefined || value === null)) {
32
- return { valid: false, error: `Missing required field: ${key}` };
33
- }
34
-
35
- if (value === undefined || value === null) continue;
36
-
37
- const result = validateValue(value, rule, key);
38
- if (!result.valid) return result;
39
- }
40
-
41
- return { valid: true };
42
- }
43
-
44
- function validateValue(value: unknown, rule: ValidationRule, path: string): { valid: boolean; error?: string } {
45
- switch (rule.type) {
46
- case 'string':
47
- if (typeof value !== 'string') {
48
- return { valid: false, error: `${path} must be a string, got ${typeof value}` };
49
- }
50
- if (rule.minLength && value.length < rule.minLength) {
51
- return { valid: false, error: `${path} must be at least ${rule.minLength} characters` };
52
- }
53
- if (rule.maxLength && value.length > rule.maxLength) {
54
- return { valid: false, error: `${path} must be at most ${rule.maxLength} characters` };
55
- }
56
- if (rule.pattern && !rule.pattern.test(value)) {
57
- return { valid: false, error: `${path} format is invalid` };
58
- }
59
- if (rule.enumValues && !rule.enumValues.includes(value)) {
60
- return { valid: false, error: `${path} must be one of: ${rule.enumValues.join(', ')}` };
61
- }
62
- break;
63
-
64
- case 'number':
65
- if (typeof value !== 'number' || isNaN(value)) {
66
- return { valid: false, error: `${path} must be a number` };
67
- }
68
- if (rule.minValue !== undefined && value < rule.minValue) {
69
- return { valid: false, error: `${path} must be at least ${rule.minValue}` };
70
- }
71
- if (rule.maxValue !== undefined && value > rule.maxValue) {
72
- return { valid: false, error: `${path} must be at most ${rule.maxValue}` };
73
- }
74
- if (rule.enumValues && !rule.enumValues.includes(value)) {
75
- return { valid: false, error: `${path} must be one of: ${rule.enumValues.join(', ')}` };
76
- }
77
- break;
78
-
79
- case 'boolean':
80
- if (typeof value !== 'boolean') {
81
- return { valid: false, error: `${path} must be a boolean` };
82
- }
83
- break;
84
-
85
- case 'date':
86
- if (typeof value !== 'string') {
87
- return { valid: false, error: `${path} must be an ISO date string` };
88
- }
89
- if (isNaN(Date.parse(value))) {
90
- return { valid: false, error: `${path} must be a valid ISO date string` };
91
- }
92
- break;
93
-
94
- case 'array':
95
- if (!Array.isArray(value)) {
96
- return { valid: false, error: `${path} must be an array` };
97
- }
98
- if (rule.minLength && value.length < rule.minLength) {
99
- return { valid: false, error: `${path} must have at least ${rule.minLength} items` };
100
- }
101
- if (rule.maxLength && value.length > rule.maxLength) {
102
- return { valid: false, error: `${path} must have at most ${rule.maxLength} items` };
103
- }
104
- if (rule.items) {
105
- for (let i = 0; i < value.length; i++) {
106
- const itemResult = validateValue(value[i], rule.items, `${path}[${i}]`);
107
- if (!itemResult.valid) return itemResult;
108
- }
109
- }
110
- break;
111
-
112
- case 'object':
113
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
114
- return { valid: false, error: `${path} must be an object` };
115
- }
116
- if (rule.properties) {
117
- const nestedResult = validate(value, rule.properties);
118
- if (!nestedResult.valid) {
119
- return { valid: false, error: `${path}: ${nestedResult.error}` };
120
- }
121
- }
122
- break;
123
-
124
- case 'enum':
125
- if (!rule.enumValues?.includes(value as string | number)) {
126
- return { valid: false, error: `${path} must be one of: ${rule.enumValues?.join(', ')}` };
127
- }
128
- break;
129
- }
130
-
131
- return { valid: true };
132
- }
133
-
134
- // Pre-built schemas for common tool patterns
135
- export const ValidationSchemas = {
136
- stringArray: (minLength = 0): ValidationRule => ({
137
- type: 'array',
138
- required: true,
139
- minLength,
140
- items: { type: 'string' },
141
- }),
142
-
143
- entityArray: (): ValidationRule => ({
144
- type: 'array',
145
- required: true,
146
- items: {
147
- type: 'object',
148
- properties: {
149
- name: { type: 'string', required: true },
150
- entityType: { type: 'string', required: true },
151
- observations: { type: 'array', required: true, items: { type: 'string' } },
152
- },
153
- },
154
- }),
155
-
156
- relationArray: (): ValidationRule => ({
157
- type: 'array',
158
- required: true,
159
- items: {
160
- type: 'object',
161
- properties: {
162
- from: { type: 'string', required: true },
163
- to: { type: 'string', required: true },
164
- relationType: { type: 'string', required: true },
165
- },
166
- },
167
- }),
168
-
169
- isoDate: (): ValidationRule => ({
170
- type: 'date',
171
- required: true,
172
- }),
173
-
174
- nonEmptyString: (): ValidationRule => ({
175
- type: 'string',
176
- required: true,
177
- minLength: 1,
178
- }),
179
- };
package/src/pde/index.ts DELETED
@@ -1,34 +0,0 @@
1
- /**
2
- * PDE module — Prompt Decomposition Engine → Structural Tension Chart transformation
3
- */
4
-
5
- export { StcMapper, stcMapper } from './stc-mapper.js';
6
- export { SessionManager, sessionManager } from './session-manager.js';
7
- export { PDE_MCP_TOOLS } from './mcp-tools.js';
8
- export { handlePdeTool } from './mcp-handlers.js';
9
-
10
- import { handlePdeTool } from './mcp-handlers.js';
11
- import type { McpToolResult } from '../types.js';
12
-
13
- function firstText(result: McpToolResult): string {
14
- return result.content[0]?.text ?? '';
15
- }
16
-
17
- export async function importDecomposition(pdeId: string, workdir?: string): Promise<string> {
18
- return firstText(await handlePdeTool('import_pde_decomposition', {
19
- pde_id: pdeId,
20
- workdir,
21
- }));
22
- }
23
-
24
- export async function listDecompositions(workdir?: string): Promise<string> {
25
- return firstText(await handlePdeTool('list_pde_decompositions', { workdir }));
26
- }
27
-
28
- export async function listSessions(status = 'all'): Promise<string> {
29
- return firstText(await handlePdeTool('list_sessions', { status }));
30
- }
31
-
32
- export async function showSession(sessionId: string): Promise<string> {
33
- return firstText(await handlePdeTool('get_session', { session_id: sessionId }));
34
- }
@@ -1,359 +0,0 @@
1
- /**
2
- * PDE MCP tool dispatch — handles each tool by calling stcMapper + sessionManager
3
- * Ported from coaia-pde/src/mcp-server.ts handler logic
4
- */
5
-
6
- import type { DecompositionResult, McpToolResult } from '../types.js';
7
- import { stcMapper } from './stc-mapper.js';
8
- import { sessionManager } from './session-manager.js';
9
-
10
- export async function handlePdeTool(
11
- name: string,
12
- args: Record<string, unknown>
13
- ): Promise<McpToolResult> {
14
- try {
15
- switch (name) {
16
- case 'import_pde_decomposition': {
17
- const pdeId = args.pde_id as string;
18
- const workdir = args.workdir as string | undefined;
19
-
20
- const stored = await sessionManager.loadPdeDecomposition(pdeId, workdir);
21
- if (!stored) {
22
- throw new Error(`PDE decomposition ${pdeId} not found in .pde/ directory`);
23
- }
24
-
25
- const { entities, relations, chartId } = stcMapper.mapDecompositionToChart(
26
- stored.result,
27
- stored.prompt,
28
- { pdeId: stored.id }
29
- );
30
-
31
- const session = await sessionManager.initSession(stored.prompt, chartId, stored.id);
32
- for (const entity of entities) {
33
- await sessionManager.appendEntity(session.sessionId, entity);
34
- }
35
- for (const relation of relations) {
36
- await sessionManager.appendRelation(session.sessionId, relation);
37
- }
38
-
39
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome')?.observations[0];
40
- const currentReality = entities.find(e => e.entityType === 'current_reality')?.observations;
41
- const actionSteps = entities
42
- .filter(e => e.entityType === 'action_step')
43
- .map(e => ({ name: e.name, description: e.observations[0] }));
44
-
45
- return {
46
- content: [{
47
- type: 'text',
48
- text: JSON.stringify({
49
- success: true,
50
- sessionId: session.sessionId,
51
- chartId,
52
- pdeDecompositionId: stored.id,
53
- filePath: await sessionManager.getSessionFilePath(session.sessionId),
54
- chart: { desiredOutcome, currentReality, actionSteps },
55
- }, null, 2)
56
- }]
57
- };
58
- }
59
-
60
- case 'create_stc_from_pde': {
61
- const resultJson = args.decomposition_result as DecompositionResult;
62
- const originalPrompt = args.original_prompt as string;
63
-
64
- const { entities, relations, chartId } = stcMapper.mapDecompositionToChart(
65
- resultJson,
66
- originalPrompt
67
- );
68
-
69
- const session = await sessionManager.initSession(originalPrompt, chartId);
70
- for (const entity of entities) {
71
- await sessionManager.appendEntity(session.sessionId, entity);
72
- }
73
- for (const relation of relations) {
74
- await sessionManager.appendRelation(session.sessionId, relation);
75
- }
76
-
77
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome')?.observations[0];
78
- const currentReality = entities.find(e => e.entityType === 'current_reality')?.observations;
79
- const actionSteps = entities
80
- .filter(e => e.entityType === 'action_step')
81
- .map(e => ({ name: e.name, description: e.observations[0] }));
82
-
83
- return {
84
- content: [{
85
- type: 'text',
86
- text: JSON.stringify({
87
- success: true,
88
- sessionId: session.sessionId,
89
- chartId,
90
- filePath: await sessionManager.getSessionFilePath(session.sessionId),
91
- chart: { desiredOutcome, currentReality, actionSteps },
92
- }, null, 2)
93
- }]
94
- };
95
- }
96
-
97
- case 'list_pde_decompositions': {
98
- const workdir = args.workdir as string | undefined;
99
- const decompositions = await sessionManager.listPdeDecompositions(workdir);
100
-
101
- return {
102
- content: [{
103
- type: 'text',
104
- text: JSON.stringify({
105
- count: decompositions.length,
106
- decompositions: decompositions.map(d => ({
107
- id: d.id,
108
- timestamp: d.timestamp,
109
- prompt: d.prompt.substring(0, 100) + (d.prompt.length > 100 ? '...' : '')
110
- }))
111
- }, null, 2)
112
- }]
113
- };
114
- }
115
-
116
- case 'get_session': {
117
- const sessionId = args.session_id as string;
118
- const { session, entities } = await sessionManager.loadSession(sessionId);
119
-
120
- const chart = entities.find(e => e.entityType === 'structural_tension_chart');
121
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome');
122
- const currentReality = entities.find(e => e.entityType === 'current_reality');
123
- const actionSteps = entities.filter(e => e.entityType === 'action_step');
124
-
125
- const completedCount = actionSteps.filter(a => a.metadata?.completionStatus).length;
126
- const progress = actionSteps.length > 0 ? completedCount / actionSteps.length : 0;
127
-
128
- return {
129
- content: [{
130
- type: 'text',
131
- text: JSON.stringify({
132
- session,
133
- chart: {
134
- chartId: chart?.metadata?.chartId,
135
- desiredOutcome: desiredOutcome?.observations[0],
136
- currentReality: currentReality?.observations,
137
- dueDate: chart?.metadata?.dueDate,
138
- progress: Math.round(progress * 100) + '%',
139
- completedActions: completedCount,
140
- totalActions: actionSteps.length
141
- },
142
- actionSteps: actionSteps.map(a => ({
143
- name: a.name,
144
- description: a.observations[0],
145
- completed: a.metadata?.completionStatus || false,
146
- dueDate: a.metadata?.dueDate,
147
- progress: a.observations.slice(1)
148
- }))
149
- }, null, 2)
150
- }]
151
- };
152
- }
153
-
154
- case 'list_sessions': {
155
- const status = args.status as string | undefined;
156
- let sessions = await sessionManager.listSessions();
157
-
158
- if (status && status !== 'all') {
159
- sessions = sessions.filter(s => s.status === status);
160
- }
161
-
162
- return {
163
- content: [{
164
- type: 'text',
165
- text: JSON.stringify({
166
- count: sessions.length,
167
- sessions: sessions.map(s => ({
168
- sessionId: s.sessionId,
169
- status: s.status,
170
- createdAt: s.createdAt,
171
- pdeDecompositionId: s.pdeDecompositionId,
172
- prompt: s.originalPrompt.substring(0, 100) + (s.originalPrompt.length > 100 ? '...' : '')
173
- }))
174
- }, null, 2)
175
- }]
176
- };
177
- }
178
-
179
- case 'update_action_progress': {
180
- const sessionId = args.session_id as string;
181
- const actionName = args.action_name as string;
182
- const observation = args.observation as string;
183
- const updateCR = args.update_current_reality as boolean | undefined;
184
-
185
- const { entities } = await sessionManager.loadSession(sessionId);
186
- const action = entities.find(e => e.name === actionName);
187
-
188
- if (!action) {
189
- throw new Error(`Action step ${actionName} not found`);
190
- }
191
-
192
- action.observations.push(observation);
193
- await sessionManager.updateEntity(sessionId, actionName, { observations: action.observations });
194
-
195
- if (updateCR) {
196
- const chartId = action.metadata?.chartId;
197
- const realityName = `${chartId}_current_reality`;
198
- const reality = entities.find(e => e.name === realityName);
199
- if (reality) {
200
- reality.observations.push(`Progress: ${observation}`);
201
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
202
- }
203
- }
204
-
205
- return {
206
- content: [{
207
- type: 'text',
208
- text: JSON.stringify({ success: true, actionName, observation })
209
- }]
210
- };
211
- }
212
-
213
- case 'mark_action_complete': {
214
- const sessionId = args.session_id as string;
215
- const actionName = args.action_name as string;
216
- const completionNote = args.completion_note as string | undefined;
217
-
218
- const { entities } = await sessionManager.loadSession(sessionId);
219
- const action = entities.find(e => e.name === actionName);
220
-
221
- if (!action) {
222
- throw new Error(`Action step ${actionName} not found`);
223
- }
224
-
225
- if (!action.metadata) action.metadata = {};
226
- action.metadata.completionStatus = true;
227
- action.metadata.updatedAt = new Date().toISOString();
228
-
229
- if (completionNote) {
230
- action.observations.push(`Completed: ${completionNote}`);
231
- }
232
-
233
- await sessionManager.updateEntity(sessionId, actionName, {
234
- observations: action.observations,
235
- metadata: action.metadata
236
- });
237
-
238
- const chartId = action.metadata?.chartId;
239
- const realityName = `${chartId}_current_reality`;
240
- const reality = entities.find(e => e.name === realityName);
241
- if (reality) {
242
- reality.observations.push(`Completed: ${action.observations[0]}`);
243
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
244
- }
245
-
246
- return {
247
- content: [{
248
- type: 'text',
249
- text: JSON.stringify({ success: true, actionName, completed: true })
250
- }]
251
- };
252
- }
253
-
254
- case 'add_action_step': {
255
- const sessionId = args.session_id as string;
256
- const description = args.action_description as string;
257
- const currentReality = args.current_reality as string | undefined;
258
-
259
- const { session, entities } = await sessionManager.loadSession(sessionId);
260
- const chart = entities.find(e => e.entityType === 'structural_tension_chart');
261
- const chartId = (chart?.metadata?.chartId as string) || session.masterChartId;
262
-
263
- const existingActions = entities.filter(e => e.entityType === 'action_step');
264
- const actionNum = existingActions.length + 1;
265
- const actionName = `${chartId}_action_${actionNum}`;
266
- const now = new Date().toISOString();
267
-
268
- const newAction = {
269
- name: actionName,
270
- entityType: 'action_step',
271
- observations: currentReality ? [description, `Current: ${currentReality}`] : [description],
272
- metadata: {
273
- chartId,
274
- completionStatus: false,
275
- level: 1,
276
- parentChart: chartId,
277
- createdAt: now,
278
- updatedAt: now,
279
- }
280
- };
281
-
282
- await sessionManager.appendEntity(sessionId, newAction);
283
- await sessionManager.appendRelation(sessionId, {
284
- from: `${chartId}_chart`,
285
- to: actionName,
286
- relationType: 'has_action_step',
287
- metadata: { createdAt: now }
288
- });
289
-
290
- return {
291
- content: [{
292
- type: 'text',
293
- text: JSON.stringify({ success: true, actionName, description })
294
- }]
295
- };
296
- }
297
-
298
- case 'update_current_reality': {
299
- const sessionId = args.session_id as string;
300
- const observations = args.observations as string[];
301
-
302
- const { session, entities } = await sessionManager.loadSession(sessionId);
303
- const chartId = session.masterChartId;
304
- const realityName = `${chartId}_current_reality`;
305
- const reality = entities.find(e => e.name === realityName);
306
-
307
- if (!reality) {
308
- throw new Error(`Current reality not found for chart ${chartId}`);
309
- }
310
-
311
- reality.observations.push(...observations);
312
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
313
-
314
- return {
315
- content: [{
316
- type: 'text',
317
- text: JSON.stringify({ success: true, added: observations.length, totalObservations: reality.observations.length })
318
- }]
319
- };
320
- }
321
-
322
- case 'complete_session': {
323
- const sessionId = args.session_id as string;
324
- const finalNote = args.final_note as string | undefined;
325
-
326
- await sessionManager.updateSession(sessionId, { status: 'completed' });
327
-
328
- if (finalNote) {
329
- const { session, entities } = await sessionManager.loadSession(sessionId);
330
- const realityName = `${session.masterChartId}_current_reality`;
331
- const reality = entities.find(e => e.name === realityName);
332
- if (reality) {
333
- reality.observations.push(`Final: ${finalNote}`);
334
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
335
- }
336
- }
337
-
338
- return {
339
- content: [{
340
- type: 'text',
341
- text: JSON.stringify({ success: true, sessionId, status: 'completed' })
342
- }]
343
- };
344
- }
345
-
346
- default:
347
- throw new Error(`Unknown PDE tool: ${name}`);
348
- }
349
- } catch (error: unknown) {
350
- const message = error instanceof Error ? error.message : String(error);
351
- return {
352
- content: [{
353
- type: 'text',
354
- text: `Error: ${message}`,
355
- }],
356
- isError: true
357
- };
358
- }
359
- }