@s_s/harmonia 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +140 -392
  2. package/build/cli/setup.d.ts +4 -2
  3. package/build/cli/setup.js +44 -18
  4. package/build/cli/setup.js.map +1 -1
  5. package/build/core/action-registry.d.ts +36 -0
  6. package/build/core/action-registry.js +53 -0
  7. package/build/core/action-registry.js.map +1 -0
  8. package/build/core/artifacts.d.ts +66 -0
  9. package/build/core/artifacts.js +178 -0
  10. package/build/core/artifacts.js.map +1 -0
  11. package/build/core/dispatch.d.ts +18 -11
  12. package/build/core/dispatch.js +43 -33
  13. package/build/core/dispatch.js.map +1 -1
  14. package/build/core/issues.d.ts +37 -0
  15. package/build/core/issues.js +100 -0
  16. package/build/core/issues.js.map +1 -0
  17. package/build/core/overrides.d.ts +19 -26
  18. package/build/core/overrides.js +32 -98
  19. package/build/core/overrides.js.map +1 -1
  20. package/build/core/plugin.d.ts +86 -0
  21. package/build/core/plugin.js +332 -0
  22. package/build/core/plugin.js.map +1 -0
  23. package/build/core/registry.d.ts +36 -3
  24. package/build/core/registry.js +63 -5
  25. package/build/core/registry.js.map +1 -1
  26. package/build/core/reviews.d.ts +13 -13
  27. package/build/core/reviews.js +31 -32
  28. package/build/core/reviews.js.map +1 -1
  29. package/build/core/schema.d.ts +43 -15
  30. package/build/core/schema.js +124 -20
  31. package/build/core/schema.js.map +1 -1
  32. package/build/core/state.d.ts +29 -22
  33. package/build/core/state.js +49 -81
  34. package/build/core/state.js.map +1 -1
  35. package/build/core/steps.d.ts +15 -15
  36. package/build/core/steps.js +32 -33
  37. package/build/core/steps.js.map +1 -1
  38. package/build/core/tree-utils.d.ts +52 -0
  39. package/build/core/tree-utils.js +226 -0
  40. package/build/core/tree-utils.js.map +1 -0
  41. package/build/core/types.d.ts +417 -117
  42. package/build/core/types.js +15 -1
  43. package/build/core/types.js.map +1 -1
  44. package/build/core/workflow-engine.d.ts +68 -0
  45. package/build/core/workflow-engine.js +821 -0
  46. package/build/core/workflow-engine.js.map +1 -0
  47. package/build/core/workflow-validator.d.ts +22 -0
  48. package/build/core/workflow-validator.js +489 -0
  49. package/build/core/workflow-validator.js.map +1 -0
  50. package/build/index.js +28 -25
  51. package/build/index.js.map +1 -1
  52. package/build/setup/inject.d.ts +4 -4
  53. package/build/setup/inject.js +6 -6
  54. package/build/setup/inject.js.map +1 -1
  55. package/build/setup/templates.d.ts +9 -7
  56. package/build/setup/templates.js +68 -103
  57. package/build/setup/templates.js.map +1 -1
  58. package/build/tools/artifact-approve.d.ts +8 -0
  59. package/build/tools/artifact-approve.js +94 -0
  60. package/build/tools/artifact-approve.js.map +1 -0
  61. package/build/tools/artifact-schema.d.ts +12 -0
  62. package/build/tools/artifact-schema.js +148 -0
  63. package/build/tools/artifact-schema.js.map +1 -0
  64. package/build/tools/artifact-tools.d.ts +18 -0
  65. package/build/tools/artifact-tools.js +465 -0
  66. package/build/tools/artifact-tools.js.map +1 -0
  67. package/build/tools/{report-dispatch.d.ts → dispatch-report.d.ts} +7 -3
  68. package/build/tools/dispatch-report.js +261 -0
  69. package/build/tools/dispatch-report.js.map +1 -0
  70. package/build/tools/engine-helpers.d.ts +41 -0
  71. package/build/tools/engine-helpers.js +182 -0
  72. package/build/tools/engine-helpers.js.map +1 -0
  73. package/build/tools/get-project-status.d.ts +6 -4
  74. package/build/tools/get-project-status.js +308 -246
  75. package/build/tools/get-project-status.js.map +1 -1
  76. package/build/tools/get-role-prompt.d.ts +1 -1
  77. package/build/tools/get-role-prompt.js +7 -41
  78. package/build/tools/get-role-prompt.js.map +1 -1
  79. package/build/tools/issue-tools.d.ts +10 -0
  80. package/build/tools/issue-tools.js +169 -0
  81. package/build/tools/issue-tools.js.map +1 -0
  82. package/build/tools/iteration-start.d.ts +7 -4
  83. package/build/tools/iteration-start.js +51 -20
  84. package/build/tools/iteration-start.js.map +1 -1
  85. package/build/tools/loop-done.d.ts +11 -0
  86. package/build/tools/loop-done.js +109 -0
  87. package/build/tools/loop-done.js.map +1 -0
  88. package/build/tools/patch-start.d.ts +16 -0
  89. package/build/tools/patch-start.js +122 -0
  90. package/build/tools/patch-start.js.map +1 -0
  91. package/build/tools/project-init.d.ts +5 -5
  92. package/build/tools/project-init.js +47 -18
  93. package/build/tools/project-init.js.map +1 -1
  94. package/build/tools/role-dispatch.d.ts +55 -0
  95. package/build/tools/role-dispatch.js +508 -0
  96. package/build/tools/role-dispatch.js.map +1 -0
  97. package/build/tools/utils.d.ts +40 -0
  98. package/build/tools/utils.js +97 -0
  99. package/build/tools/utils.js.map +1 -0
  100. package/package.json +1 -1
  101. package/{build/hooks/claude-code.js → workflows/dev/hooks/claude.js} +34 -23
  102. package/{build → workflows/dev}/hooks/content.js +27 -18
  103. package/workflows/dev/hooks/index.js +52 -0
  104. package/{build → workflows/dev}/hooks/openclaw.js +31 -20
  105. package/{build → workflows/dev}/hooks/opencode.js +31 -20
  106. package/workflows/dev/roles/architect.md +68 -28
  107. package/workflows/dev/roles/coordinator.md +103 -0
  108. package/workflows/dev/roles/developer.md +5 -5
  109. package/workflows/dev/roles/tester.md +19 -19
  110. package/workflows/dev/schemas/api-contract.json +42 -0
  111. package/workflows/dev/schemas/api-design.json +30 -13
  112. package/workflows/dev/schemas/data-model.json +20 -7
  113. package/workflows/dev/schemas/prd.completeness-check.json +6 -5
  114. package/workflows/dev/schemas/prd.draft.json +13 -5
  115. package/workflows/dev/schemas/prd.final.json +34 -11
  116. package/workflows/dev/schemas/prd.json +29 -11
  117. package/workflows/dev/schemas/prd.requirements.json +6 -5
  118. package/workflows/dev/schemas/prototype.json +6 -2
  119. package/workflows/dev/schemas/task-breakdown.coarse.json +4 -3
  120. package/workflows/dev/schemas/task-breakdown.dependencies.json +5 -4
  121. package/workflows/dev/schemas/task-breakdown.detailed.json +8 -3
  122. package/workflows/dev/schemas/task-breakdown.final.json +8 -3
  123. package/workflows/dev/schemas/task-breakdown.json +8 -3
  124. package/workflows/dev/schemas/tech-design.analysis.json +6 -5
  125. package/workflows/dev/schemas/tech-design.draft.json +14 -5
  126. package/workflows/dev/schemas/tech-design.final.json +39 -13
  127. package/workflows/dev/schemas/tech-design.json +34 -13
  128. package/workflows/dev/schemas/tech-design.research.json +21 -0
  129. package/workflows/dev/schemas/test-plan.json +17 -7
  130. package/workflows/dev/schemas/test-report.json +26 -9
  131. package/workflows/dev/schemas/user-stories.json +7 -3
  132. package/workflows/dev/tools/index.js +23 -0
  133. package/workflows/dev/workflow.json +234 -101
  134. package/build/core/docs.d.ts +0 -32
  135. package/build/core/docs.js +0 -91
  136. package/build/core/docs.js.map +0 -1
  137. package/build/core/workflow.d.ts +0 -33
  138. package/build/core/workflow.js +0 -140
  139. package/build/core/workflow.js.map +0 -1
  140. package/build/hooks/claude-code.d.ts +0 -20
  141. package/build/hooks/claude-code.js.map +0 -1
  142. package/build/hooks/content.d.ts +0 -43
  143. package/build/hooks/content.js.map +0 -1
  144. package/build/hooks/install.d.ts +0 -40
  145. package/build/hooks/install.js +0 -63
  146. package/build/hooks/install.js.map +0 -1
  147. package/build/hooks/openclaw.d.ts +0 -24
  148. package/build/hooks/openclaw.js.map +0 -1
  149. package/build/hooks/opencode.d.ts +0 -29
  150. package/build/hooks/opencode.js.map +0 -1
  151. package/build/tools/approve-doc.d.ts +0 -6
  152. package/build/tools/approve-doc.js +0 -108
  153. package/build/tools/approve-doc.js.map +0 -1
  154. package/build/tools/dispatch-role.d.ts +0 -16
  155. package/build/tools/dispatch-role.js +0 -277
  156. package/build/tools/dispatch-role.js.map +0 -1
  157. package/build/tools/doc-tools.d.ts +0 -16
  158. package/build/tools/doc-tools.js +0 -389
  159. package/build/tools/doc-tools.js.map +0 -1
  160. package/build/tools/override-tools.d.ts +0 -6
  161. package/build/tools/override-tools.js +0 -129
  162. package/build/tools/override-tools.js.map +0 -1
  163. package/build/tools/report-dispatch.js +0 -194
  164. package/build/tools/report-dispatch.js.map +0 -1
  165. package/build/tools/set-scale.d.ts +0 -6
  166. package/build/tools/set-scale.js +0 -107
  167. package/build/tools/set-scale.js.map +0 -1
  168. package/build/tools/setup-project.d.ts +0 -8
  169. package/build/tools/setup-project.js +0 -116
  170. package/build/tools/setup-project.js.map +0 -1
  171. package/build/tools/update-phase.d.ts +0 -12
  172. package/build/tools/update-phase.js +0 -159
  173. package/build/tools/update-phase.js.map +0 -1
  174. package/workflows/dev/roles/pm.md +0 -99
  175. package/workflows/dev/schemas/deploy.json +0 -20
  176. package/workflows/dev/schemas/fsd.json +0 -25
  177. package/workflows/dev/schemas/project-plan.json +0 -20
  178. package/workflows/dev/schemas/retrospective.json +0 -20
  179. package/workflows/dev/schemas/risk-assessment.json +0 -15
  180. package/workflows/dev/schemas/tech-design.api-contract.json +0 -20
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * MCP Tool: dispatch_report
3
3
  *
4
- * PM calls this tool to report dispatch status changes:
4
+ * Coordinator calls this tool to report dispatch status changes:
5
5
  * 1. After launching an agent: provide agent_session_id → creates/reuses session, marks dispatch running
6
6
  * 2. After agent finishes: provide status=completed/failed → updates dispatch, session goes idle/closed
7
7
  *
8
+ * Node-based architecture changes:
9
+ * - On completed: triggers `node_completed` engine event → computes nextAction
10
+ * - On failed: triggers `node_failed` engine event → engine checks onFailed → computes nextAction
11
+ * - Returns nextAction in response so coordinator knows what to do next
12
+ *
8
13
  * Guards:
9
14
  * - State machine: terminal states (completed/failed/cancelled) are irreversible
10
15
  * - Valid transitions: dispatched→running/cancelled, running→completed/failed/cancelled
11
- * - Completion check: warns if expectedOutputs docs are missing
12
16
  */
13
17
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
14
- export declare function registerReportDispatch(server: McpServer, builtinDir: string, customDir: string): void;
18
+ export declare function registerReportDispatch(server: McpServer, workflowsDir: string): void;
@@ -0,0 +1,261 @@
1
+ /**
2
+ * MCP Tool: dispatch_report
3
+ *
4
+ * Coordinator calls this tool to report dispatch status changes:
5
+ * 1. After launching an agent: provide agent_session_id → creates/reuses session, marks dispatch running
6
+ * 2. After agent finishes: provide status=completed/failed → updates dispatch, session goes idle/closed
7
+ *
8
+ * Node-based architecture changes:
9
+ * - On completed: triggers `node_completed` engine event → computes nextAction
10
+ * - On failed: triggers `node_failed` engine event → engine checks onFailed → computes nextAction
11
+ * - Returns nextAction in response so coordinator knows what to do next
12
+ *
13
+ * Guards:
14
+ * - State machine: terminal states (completed/failed/cancelled) are irreversible
15
+ * - Valid transitions: dispatched→running/cancelled, running→completed/failed/cancelled
16
+ */
17
+ import { z } from 'zod';
18
+ import { getDispatch, updateDispatch, createSession, updateSession, findSessionByAgentId, readSessions, isValidTransition, isTerminalStatus, } from '../core/dispatch.js';
19
+ import { resolveActive, isError } from './utils.js';
20
+ import { loadWorkflowForContext, processWorkflowEvent, formatNextAction, findTaskNode } from './engine-helpers.js';
21
+ import { readArtifact, listArtifacts } from '../core/artifacts.js';
22
+ import { findAncestorLoopId } from '../core/tree-utils.js';
23
+ export function registerReportDispatch(server, workflowsDir) {
24
+ server.tool('dispatch_report', 'Report dispatch status after launching or completing a team member agent. Call with agent_session_id after launching to register the session. Call with status="completed" or "failed" when the agent finishes. Returns nextAction indicating what the coordinator should do next.', {
25
+ project_name: z.string().describe('Project name'),
26
+ dispatch_id: z.string().describe('Dispatch ID returned by role_dispatch'),
27
+ status: z
28
+ .enum(['running', 'completed', 'failed', 'cancelled'])
29
+ .optional()
30
+ .describe('New dispatch status. Omit when only registering agent_session_id (defaults to "running").'),
31
+ agent_session_id: z
32
+ .string()
33
+ .optional()
34
+ .describe('The actual session ID from the host agent (e.g. OpenCode session ID). Provide on first report after launching.'),
35
+ agent_type: z
36
+ .enum(['opencode', 'openclaw', 'claude-code', 'codex'])
37
+ .optional()
38
+ .describe('Agent type used for this dispatch'),
39
+ label: z.string().optional().describe('Optional label for the session (e.g. "dev-auth-module")'),
40
+ note: z.string().optional().describe('Optional note (e.g. failure reason)'),
41
+ }, async ({ project_name, dispatch_id, status, agent_session_id, agent_type, label, note }) => {
42
+ try {
43
+ const ctx = await resolveActive(project_name);
44
+ if (isError(ctx))
45
+ return ctx;
46
+ // Load the dispatch record
47
+ const dispatch = await getDispatch(project_name, ctx.number, dispatch_id, ctx.dir);
48
+ if (!dispatch) {
49
+ return {
50
+ content: [
51
+ {
52
+ type: 'text',
53
+ text: `Dispatch "${dispatch_id}" not found in project "${project_name}".`,
54
+ },
55
+ ],
56
+ isError: true,
57
+ };
58
+ }
59
+ const effectiveStatus = status ?? 'running';
60
+ const results = [];
61
+ // Guard: state machine — reject invalid transitions
62
+ if (!isValidTransition(dispatch.status, effectiveStatus)) {
63
+ const reason = isTerminalStatus(dispatch.status)
64
+ ? `Dispatch "${dispatch_id}" is in terminal status "${dispatch.status}" — cannot transition to "${effectiveStatus}".`
65
+ : `Dispatch "${dispatch_id}" current status "${dispatch.status}" does not allow transition to "${effectiveStatus}".`;
66
+ return {
67
+ content: [
68
+ {
69
+ type: 'text',
70
+ text: reason,
71
+ },
72
+ ],
73
+ isError: true,
74
+ };
75
+ }
76
+ // Handle session registration (when agent_session_id is provided)
77
+ let session = null;
78
+ if (agent_session_id) {
79
+ session = await resolveOrCreateSession(project_name, ctx.number, dispatch, agent_session_id, agent_type, label, ctx.dir);
80
+ results.push(`Session: ${session.id} (agent: ${agent_session_id}, status: ${session.status})`);
81
+ }
82
+ // Handle status transitions
83
+ let nextActionText = '';
84
+ if (effectiveStatus === 'completed' ||
85
+ effectiveStatus === 'failed' ||
86
+ effectiveStatus === 'cancelled') {
87
+ // Terminal states: update dispatch and transition session
88
+ await updateDispatch(project_name, ctx.number, dispatch_id, {
89
+ status: effectiveStatus,
90
+ ...(session ? { sessionId: session.id } : {}),
91
+ ...(note ? { note } : {}),
92
+ }, ctx.dir);
93
+ // Transition session: completed → idle, failed/cancelled → lost
94
+ const sessionId = session?.id ?? dispatch.sessionId;
95
+ if (sessionId) {
96
+ const newSessionStatus = effectiveStatus === 'completed' ? 'idle' : 'lost';
97
+ await updateSession(project_name, ctx.number, sessionId, { status: newSessionStatus }, ctx.dir);
98
+ results.push(`Session ${sessionId} → ${newSessionStatus}`);
99
+ }
100
+ results.push(`Dispatch ${dispatch_id} → ${effectiveStatus}`);
101
+ // Trigger engine events for completed/failed/cancelled
102
+ if (dispatch.nodeId) {
103
+ if (effectiveStatus === 'completed') {
104
+ const engineResult = await processWorkflowEvent(workflowsDir, project_name, ctx, {
105
+ type: 'node_completed',
106
+ nodeId: dispatch.nodeId,
107
+ });
108
+ nextActionText = formatNextAction(engineResult.nextAction);
109
+ // Execute afterComplete hooks
110
+ try {
111
+ const { wf, state: currentState } = await loadWorkflowForContext(workflowsDir, project_name, ctx);
112
+ const targetNode = findTaskNode(wf, dispatch.nodeId);
113
+ if (targetNode?.afterComplete) {
114
+ const hookInjections = [];
115
+ if (targetNode.afterComplete.inject) {
116
+ hookInjections.push(...targetNode.afterComplete.inject);
117
+ }
118
+ if (targetNode.afterComplete.actions && wf.actions) {
119
+ const reportIoCtx = {
120
+ contextDir: ctx.dir,
121
+ projectDir: ctx.entry.dir,
122
+ contextLabel: ctx.activeContext,
123
+ };
124
+ const nodeState = currentState.nodes[dispatch.nodeId];
125
+ // Resolve loopIteration: find ancestor loop node and read its current iteration
126
+ let loopIteration;
127
+ const ancestorLoopId = findAncestorLoopId(wf.definition.root, dispatch.nodeId);
128
+ if (ancestorLoopId) {
129
+ const loopState = currentState.nodes[ancestorLoopId];
130
+ if (loopState) {
131
+ loopIteration = loopState.currentIteration;
132
+ }
133
+ }
134
+ const actionCtx = {
135
+ nodeId: dispatch.nodeId,
136
+ role: dispatch.role,
137
+ retryCount: nodeState?.retryCount ?? 0,
138
+ projectName: project_name,
139
+ pluginConfig: wf.config,
140
+ workflowState: currentState,
141
+ artifacts: {
142
+ read: (artifactId) => readArtifact(artifactId, reportIoCtx, wf.artifactDefinitions[artifactId]),
143
+ list: () => listArtifacts(reportIoCtx, wf.artifactDefinitions),
144
+ },
145
+ loopIteration,
146
+ };
147
+ for (const actionName of targetNode.afterComplete.actions) {
148
+ const handler = wf.actions[actionName];
149
+ if (handler) {
150
+ try {
151
+ const actionResult = await handler(actionCtx);
152
+ if (actionResult.inject) {
153
+ hookInjections.push(...actionResult.inject);
154
+ }
155
+ }
156
+ catch (err) {
157
+ console.warn(`[harmonia] afterComplete action "${actionName}" failed:`, err);
158
+ }
159
+ }
160
+ }
161
+ }
162
+ if (hookInjections.length > 0) {
163
+ results.push('', '## After-Complete Hook Output', ...hookInjections);
164
+ }
165
+ }
166
+ }
167
+ catch (err) {
168
+ console.warn('[harmonia] afterComplete hook processing failed:', err);
169
+ }
170
+ }
171
+ else if (effectiveStatus === 'failed') {
172
+ const engineResult = await processWorkflowEvent(workflowsDir, project_name, ctx, {
173
+ type: 'node_failed',
174
+ nodeId: dispatch.nodeId,
175
+ error: note ?? 'Unknown failure',
176
+ });
177
+ nextActionText = formatNextAction(engineResult.nextAction);
178
+ }
179
+ else if (effectiveStatus === 'cancelled') {
180
+ // Cancelled dispatches should also update node state via engine
181
+ // so the node doesn't stay stuck in 'active' forever
182
+ const engineResult = await processWorkflowEvent(workflowsDir, project_name, ctx, {
183
+ type: 'node_failed',
184
+ nodeId: dispatch.nodeId,
185
+ error: note ?? 'Dispatch cancelled',
186
+ });
187
+ nextActionText = formatNextAction(engineResult.nextAction);
188
+ }
189
+ }
190
+ }
191
+ else {
192
+ // Running: update dispatch status + associate session
193
+ await updateDispatch(project_name, ctx.number, dispatch_id, {
194
+ status: 'running',
195
+ ...(session ? { sessionId: session.id } : {}),
196
+ ...(note ? { note } : {}),
197
+ }, ctx.dir);
198
+ // Mark session as active
199
+ const sessionId = session?.id ?? dispatch.sessionId;
200
+ if (sessionId) {
201
+ await updateSession(project_name, ctx.number, sessionId, { status: 'active' }, ctx.dir);
202
+ }
203
+ results.push(`Dispatch ${dispatch_id} → running`);
204
+ }
205
+ // Build response
206
+ const nextStepHint = effectiveStatus === 'running'
207
+ ? `\nNext: When the agent finishes, call dispatch_report with dispatch_id="${dispatch_id}" and status="completed" (or "failed").`
208
+ : `\nNext: Call project_status to check overall progress and determine next steps.`;
209
+ return {
210
+ content: [
211
+ {
212
+ type: 'text',
213
+ text: `# Report Dispatch: ${dispatch_id}\n\n${results.join('\n')}${nextStepHint}${nextActionText}`,
214
+ },
215
+ ],
216
+ };
217
+ }
218
+ catch (err) {
219
+ return {
220
+ content: [
221
+ {
222
+ type: 'text',
223
+ text: `Error: ${err instanceof Error ? err.message : String(err)}`,
224
+ },
225
+ ],
226
+ isError: true,
227
+ };
228
+ }
229
+ });
230
+ }
231
+ /**
232
+ * Resolve an existing session by agent session ID, or create a new one.
233
+ */
234
+ async function resolveOrCreateSession(projectName, iteration, dispatch, agentSessionId, agentType, label, contextDir) {
235
+ // If the dispatch already has a session, update it with the agent session ID
236
+ if (dispatch.sessionId) {
237
+ const sessions = await readSessions(projectName, iteration, contextDir);
238
+ const existing = sessions.find((s) => s.id === dispatch.sessionId);
239
+ if (existing) {
240
+ return await updateSession(projectName, iteration, existing.id, {
241
+ agentSessionId,
242
+ ...(agentType ? { agentType } : {}),
243
+ ...(label ? { label } : {}),
244
+ status: 'active',
245
+ }, contextDir);
246
+ }
247
+ }
248
+ // Check if a session with this agent session ID already exists for this role
249
+ const existingByAgent = await findSessionByAgentId(projectName, iteration, dispatch.role, agentSessionId, contextDir);
250
+ if (existingByAgent) {
251
+ return await updateSession(projectName, iteration, existingByAgent.id, {
252
+ status: 'active',
253
+ ...(agentType ? { agentType } : {}),
254
+ ...(label ? { label } : {}),
255
+ }, contextDir);
256
+ }
257
+ // Create a new session
258
+ const session = await createSession(projectName, iteration, dispatch.role, agentType, label, contextDir);
259
+ return await updateSession(projectName, iteration, session.id, { agentSessionId }, contextDir);
260
+ }
261
+ //# sourceMappingURL=dispatch-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-report.js","sourceRoot":"","sources":["../../src/tools/dispatch-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared engine helpers for tool handlers.
3
+ *
4
+ * Provides a workflow engine integration layer so that individual tools
5
+ * can trigger engine events (artifact_written, artifact_approved, etc.)
6
+ * and receive the computed nextAction.
7
+ */
8
+ import type { WorkflowState, WorkflowEvent, NextAction, WorkflowPlugin, TaskNode } from '../core/types.js';
9
+ import type { ResolvedContext } from './utils.js';
10
+ /** Result of processing a workflow event through the engine */
11
+ export interface EngineResult {
12
+ /** Updated workflow state (already persisted) */
13
+ state: WorkflowState;
14
+ /** What the coordinator should do next */
15
+ nextAction: NextAction;
16
+ }
17
+ /**
18
+ * Find a task node by ID in the workflow definition (including floating nodes).
19
+ */
20
+ export declare function findTaskNode(wf: WorkflowPlugin, nodeId: string): TaskNode | undefined;
21
+ /**
22
+ * Process a workflow event through the engine.
23
+ *
24
+ * 1. Loads current state + workflow plugin
25
+ * 2. Builds engine context (gate evaluation, role prompts)
26
+ * 3. Calls computeNextAction
27
+ * 4. Persists updated state
28
+ * 5. Returns the nextAction
29
+ */
30
+ export declare function processWorkflowEvent(workflowsDir: string, projectName: string, ctx: ResolvedContext, event: WorkflowEvent): Promise<EngineResult>;
31
+ /**
32
+ * Load the workflow plugin for a resolved context.
33
+ */
34
+ export declare function loadWorkflowForContext(workflowsDir: string, projectName: string, ctx: ResolvedContext): Promise<{
35
+ wf: WorkflowPlugin;
36
+ state: WorkflowState;
37
+ }>;
38
+ /**
39
+ * Format a nextAction into a human-readable message for the tool response.
40
+ */
41
+ export declare function formatNextAction(nextAction: NextAction): string;
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Shared engine helpers for tool handlers.
3
+ *
4
+ * Provides a workflow engine integration layer so that individual tools
5
+ * can trigger engine events (artifact_written, artifact_approved, etc.)
6
+ * and receive the computed nextAction.
7
+ */
8
+ import { readState, persistState } from '../core/state.js';
9
+ import { loadWorkflow } from '../core/plugin.js';
10
+ import { listArtifacts, readArtifact } from '../core/artifacts.js';
11
+ import { readReviews } from '../core/reviews.js';
12
+ import { computeNextAction } from '../core/workflow-engine.js';
13
+ import { collectTaskNodes } from '../core/tree-utils.js';
14
+ /**
15
+ * Resolve a dot-separated field path on a JSON object.
16
+ * e.g. "result" on { result: "pass" } → "pass"
17
+ * e.g. "stats.total" on { stats: { total: 10 } } → 10
18
+ */
19
+ function resolveFieldPath(obj, path) {
20
+ const parts = path.split('.');
21
+ let current = obj;
22
+ for (const part of parts) {
23
+ if (current === null || current === undefined || typeof current !== 'object') {
24
+ return undefined;
25
+ }
26
+ current = current[part];
27
+ }
28
+ return current;
29
+ }
30
+ /**
31
+ * Build a GateContext from the current project state.
32
+ * This provides the artifact existence/approval/field checks
33
+ * that the engine needs for gate evaluation.
34
+ *
35
+ * For artifact_field conditions, pre-loads and caches all existing
36
+ * JSON artifact contents so field access can be synchronous.
37
+ */
38
+ function buildGateContext(projectName, iteration, contextDir, existingArtifacts, reviews, artifactCache) {
39
+ return {
40
+ artifactExists: (artifactId) => existingArtifacts.has(artifactId),
41
+ artifactApproved: (artifactId) => reviews[artifactId]?.status === 'approved',
42
+ artifactField: (artifactId, field) => {
43
+ const content = artifactCache.get(artifactId);
44
+ if (content === undefined)
45
+ return undefined;
46
+ return resolveFieldPath(content, field);
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * Build the full EngineContext needed for engine operations.
52
+ * Pre-loads artifact content for field-based gate evaluation.
53
+ */
54
+ async function buildEngineContext(projectName, iteration, contextDir, wf, ioCtx) {
55
+ // Load current artifacts and reviews for gate evaluation
56
+ const artifactList = await listArtifacts(ioCtx, wf.artifactDefinitions);
57
+ const existingArtifacts = new Set(artifactList);
58
+ const reviews = await readReviews(projectName, iteration, contextDir);
59
+ // Pre-load artifact content for field access (JSON artifacts only)
60
+ const artifactCache = new Map();
61
+ for (const artifactId of artifactList) {
62
+ const artifactDef = wf.artifactDefinitions[artifactId];
63
+ try {
64
+ const content = await readArtifact(artifactId, ioCtx, artifactDef);
65
+ // Try to parse as JSON; if it fails, store raw string
66
+ try {
67
+ artifactCache.set(artifactId, JSON.parse(content));
68
+ }
69
+ catch {
70
+ artifactCache.set(artifactId, content);
71
+ }
72
+ }
73
+ catch {
74
+ // Artifact listed but unreadable — skip
75
+ }
76
+ }
77
+ const gateCtx = buildGateContext(projectName, iteration, contextDir, existingArtifacts, reviews, artifactCache);
78
+ return {
79
+ gate: gateCtx,
80
+ getRolePrompt: (role, nodeId) => {
81
+ const roleDef = wf.roles[role];
82
+ return roleDef?.prompt ?? `Role "${role}" prompt not found`;
83
+ },
84
+ };
85
+ }
86
+ /**
87
+ * Find a task node by ID in the workflow definition (including floating nodes).
88
+ */
89
+ export function findTaskNode(wf, nodeId) {
90
+ const allTasks = collectTaskNodes(wf.definition.root);
91
+ const found = allTasks.find((t) => t.id === nodeId);
92
+ if (found)
93
+ return found;
94
+ // Check floating nodes
95
+ return wf.definition.floatingNodes?.find((fn) => fn.id === nodeId);
96
+ }
97
+ /**
98
+ * Process a workflow event through the engine.
99
+ *
100
+ * 1. Loads current state + workflow plugin
101
+ * 2. Builds engine context (gate evaluation, role prompts)
102
+ * 3. Calls computeNextAction
103
+ * 4. Persists updated state
104
+ * 5. Returns the nextAction
105
+ */
106
+ export async function processWorkflowEvent(workflowsDir, projectName, ctx, event) {
107
+ const state = await readState(projectName, ctx.number, ctx.dir);
108
+ const wf = await loadWorkflow(workflowsDir, state.workflow);
109
+ const ioCtx = {
110
+ contextDir: ctx.dir,
111
+ projectDir: ctx.entry.dir,
112
+ contextLabel: ctx.activeContext,
113
+ };
114
+ const engineCtx = await buildEngineContext(projectName, ctx.number, ctx.dir, wf, ioCtx);
115
+ const result = computeNextAction(wf.definition, state, event, engineCtx);
116
+ // Skip persisting state for read-only events (query_status doesn't modify state)
117
+ if (event.type !== 'query_status') {
118
+ await persistState(projectName, ctx.number, result.state, ctx.dir);
119
+ }
120
+ return {
121
+ state: result.state,
122
+ nextAction: result.nextAction,
123
+ };
124
+ }
125
+ /**
126
+ * Load the workflow plugin for a resolved context.
127
+ */
128
+ export async function loadWorkflowForContext(workflowsDir, projectName, ctx) {
129
+ const state = await readState(projectName, ctx.number, ctx.dir);
130
+ const wf = await loadWorkflow(workflowsDir, state.workflow);
131
+ return { wf, state };
132
+ }
133
+ /**
134
+ * Format a nextAction into a human-readable message for the tool response.
135
+ */
136
+ export function formatNextAction(nextAction) {
137
+ const lines = [];
138
+ switch (nextAction.type) {
139
+ case 'dispatch':
140
+ if (nextAction.parallelDispatch && nextAction.parallelDispatch.length > 1) {
141
+ lines.push(`\n[Next Action] Parallel dispatch: ${nextAction.parallelDispatch.length} tasks`);
142
+ for (const d of nextAction.parallelDispatch) {
143
+ lines.push(` - role "${d.role}" for node "${d.nodeId}"`);
144
+ }
145
+ }
146
+ else {
147
+ lines.push(`\n[Next Action] Dispatch role "${nextAction.role}" for node "${nextAction.nodeId}"`);
148
+ }
149
+ if (nextAction.instructions)
150
+ lines.push(nextAction.instructions);
151
+ break;
152
+ case 'write_artifact':
153
+ lines.push(`\n[Next Action] Write artifact`);
154
+ if (nextAction.instructions)
155
+ lines.push(nextAction.instructions);
156
+ break;
157
+ case 'approve_artifact':
158
+ lines.push(`\n[Next Action] Approve artifact`);
159
+ if (nextAction.instructions)
160
+ lines.push(nextAction.instructions);
161
+ break;
162
+ case 'wait':
163
+ lines.push(`\n[Next Action] ${nextAction.instructions}`);
164
+ break;
165
+ case 'completed':
166
+ lines.push(`\n[Next Action] Workflow completed!`);
167
+ break;
168
+ case 'failed':
169
+ lines.push(`\n[Workflow Failed] ${nextAction.instructions}`);
170
+ break;
171
+ case 'evaluate_gate':
172
+ lines.push(`\n[Next Action] Evaluate gate "${nextAction.nodeId}"`);
173
+ if (nextAction.instructions)
174
+ lines.push(nextAction.instructions);
175
+ break;
176
+ case 'none':
177
+ // No specific next action
178
+ break;
179
+ }
180
+ return lines.join('\n');
181
+ }
182
+ //# sourceMappingURL=engine-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-helpers.js","sourceRoot":"","sources":["../../src/tools/engine-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * MCP Tool: project_status
3
- * Read the current project status with rich context for PM decision-making.
4
- * Includes phase progress, documents, pending reviews, dispatch records,
5
- * active sessions, and intelligent next-step suggestions.
3
+ * Read the current project status with rich context for coordinator decision-making.
4
+ *
5
+ * Node-based architecture: displays workflow tree with node states instead of phases.
6
+ * Includes artifacts, pending reviews, dispatch records, active sessions,
7
+ * workflow engine nextAction, and intelligent next-step suggestions.
6
8
  *
7
9
  * When called without project_name, returns a summary list of all projects.
8
10
  */
9
11
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
- export declare function registerGetProjectStatus(server: McpServer, builtinDir: string, customDir: string): void;
12
+ export declare function registerGetProjectStatus(server: McpServer, workflowsDir: string): void;