@s_s/harmonia 1.3.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 (172) 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 +6 -2
  12. package/build/core/dispatch.js +12 -7
  13. package/build/core/dispatch.js.map +1 -1
  14. package/build/core/overrides.d.ts +19 -26
  15. package/build/core/overrides.js +32 -98
  16. package/build/core/overrides.js.map +1 -1
  17. package/build/core/plugin.d.ts +86 -0
  18. package/build/core/plugin.js +332 -0
  19. package/build/core/plugin.js.map +1 -0
  20. package/build/core/registry.d.ts +4 -5
  21. package/build/core/registry.js +8 -9
  22. package/build/core/registry.js.map +1 -1
  23. package/build/core/reviews.d.ts +11 -12
  24. package/build/core/reviews.js +18 -21
  25. package/build/core/reviews.js.map +1 -1
  26. package/build/core/schema.d.ts +43 -15
  27. package/build/core/schema.js +124 -20
  28. package/build/core/schema.js.map +1 -1
  29. package/build/core/state.d.ts +26 -27
  30. package/build/core/state.js +36 -90
  31. package/build/core/state.js.map +1 -1
  32. package/build/core/steps.d.ts +13 -14
  33. package/build/core/steps.js +26 -29
  34. package/build/core/steps.js.map +1 -1
  35. package/build/core/tree-utils.d.ts +52 -0
  36. package/build/core/tree-utils.js +226 -0
  37. package/build/core/tree-utils.js.map +1 -0
  38. package/build/core/types.d.ts +389 -118
  39. package/build/core/types.js +15 -1
  40. package/build/core/types.js.map +1 -1
  41. package/build/core/workflow-engine.d.ts +68 -0
  42. package/build/core/workflow-engine.js +821 -0
  43. package/build/core/workflow-engine.js.map +1 -0
  44. package/build/core/workflow-validator.d.ts +22 -0
  45. package/build/core/workflow-validator.js +489 -0
  46. package/build/core/workflow-validator.js.map +1 -0
  47. package/build/index.js +25 -26
  48. package/build/index.js.map +1 -1
  49. package/build/setup/inject.d.ts +4 -4
  50. package/build/setup/inject.js +6 -6
  51. package/build/setup/inject.js.map +1 -1
  52. package/build/setup/templates.d.ts +9 -7
  53. package/build/setup/templates.js +68 -172
  54. package/build/setup/templates.js.map +1 -1
  55. package/build/tools/artifact-approve.d.ts +8 -0
  56. package/build/tools/{approve-doc.js → artifact-approve.js} +24 -16
  57. package/build/tools/artifact-approve.js.map +1 -0
  58. package/build/tools/artifact-schema.d.ts +12 -0
  59. package/build/tools/artifact-schema.js +148 -0
  60. package/build/tools/artifact-schema.js.map +1 -0
  61. package/build/tools/artifact-tools.d.ts +18 -0
  62. package/build/tools/artifact-tools.js +465 -0
  63. package/build/tools/artifact-tools.js.map +1 -0
  64. package/build/tools/{report-dispatch.d.ts → dispatch-report.d.ts} +7 -3
  65. package/build/tools/{report-dispatch.js → dispatch-report.js} +106 -28
  66. package/build/tools/dispatch-report.js.map +1 -0
  67. package/build/tools/engine-helpers.d.ts +41 -0
  68. package/build/tools/engine-helpers.js +182 -0
  69. package/build/tools/engine-helpers.js.map +1 -0
  70. package/build/tools/get-project-status.d.ts +6 -4
  71. package/build/tools/get-project-status.js +265 -248
  72. package/build/tools/get-project-status.js.map +1 -1
  73. package/build/tools/get-role-prompt.d.ts +1 -1
  74. package/build/tools/get-role-prompt.js +7 -41
  75. package/build/tools/get-role-prompt.js.map +1 -1
  76. package/build/tools/iteration-start.d.ts +7 -4
  77. package/build/tools/iteration-start.js +45 -19
  78. package/build/tools/iteration-start.js.map +1 -1
  79. package/build/tools/loop-done.d.ts +11 -0
  80. package/build/tools/loop-done.js +109 -0
  81. package/build/tools/loop-done.js.map +1 -0
  82. package/build/tools/patch-start.d.ts +4 -2
  83. package/build/tools/patch-start.js +36 -11
  84. package/build/tools/patch-start.js.map +1 -1
  85. package/build/tools/project-init.d.ts +5 -5
  86. package/build/tools/project-init.js +41 -10
  87. package/build/tools/project-init.js.map +1 -1
  88. package/build/tools/role-dispatch.d.ts +55 -0
  89. package/build/tools/role-dispatch.js +508 -0
  90. package/build/tools/role-dispatch.js.map +1 -0
  91. package/build/tools/utils.d.ts +6 -0
  92. package/build/tools/utils.js +36 -0
  93. package/build/tools/utils.js.map +1 -1
  94. package/package.json +1 -1
  95. package/{build/hooks/claude-code.js → workflows/dev/hooks/claude.js} +34 -23
  96. package/{build → workflows/dev}/hooks/content.js +27 -18
  97. package/workflows/dev/hooks/index.js +52 -0
  98. package/{build → workflows/dev}/hooks/openclaw.js +31 -20
  99. package/{build → workflows/dev}/hooks/opencode.js +31 -20
  100. package/workflows/dev/roles/architect.md +68 -28
  101. package/workflows/dev/roles/coordinator.md +103 -0
  102. package/workflows/dev/roles/developer.md +5 -5
  103. package/workflows/dev/roles/tester.md +19 -19
  104. package/workflows/dev/schemas/api-contract.json +42 -0
  105. package/workflows/dev/schemas/api-design.json +30 -13
  106. package/workflows/dev/schemas/data-model.json +20 -7
  107. package/workflows/dev/schemas/prd.completeness-check.json +6 -5
  108. package/workflows/dev/schemas/prd.draft.json +13 -5
  109. package/workflows/dev/schemas/prd.final.json +34 -11
  110. package/workflows/dev/schemas/prd.json +29 -11
  111. package/workflows/dev/schemas/prd.requirements.json +6 -5
  112. package/workflows/dev/schemas/prototype.json +6 -2
  113. package/workflows/dev/schemas/task-breakdown.coarse.json +4 -3
  114. package/workflows/dev/schemas/task-breakdown.dependencies.json +5 -4
  115. package/workflows/dev/schemas/task-breakdown.detailed.json +8 -3
  116. package/workflows/dev/schemas/task-breakdown.final.json +8 -3
  117. package/workflows/dev/schemas/task-breakdown.json +8 -3
  118. package/workflows/dev/schemas/tech-design.analysis.json +6 -5
  119. package/workflows/dev/schemas/tech-design.draft.json +14 -5
  120. package/workflows/dev/schemas/tech-design.final.json +39 -13
  121. package/workflows/dev/schemas/tech-design.json +34 -13
  122. package/workflows/dev/schemas/tech-design.research.json +21 -0
  123. package/workflows/dev/schemas/test-plan.json +17 -7
  124. package/workflows/dev/schemas/test-report.json +26 -9
  125. package/workflows/dev/schemas/user-stories.json +7 -3
  126. package/workflows/dev/tools/index.js +23 -0
  127. package/workflows/dev/workflow.json +234 -101
  128. package/build/core/docs.d.ts +0 -36
  129. package/build/core/docs.js +0 -96
  130. package/build/core/docs.js.map +0 -1
  131. package/build/core/workflow.d.ts +0 -33
  132. package/build/core/workflow.js +0 -140
  133. package/build/core/workflow.js.map +0 -1
  134. package/build/hooks/claude-code.d.ts +0 -20
  135. package/build/hooks/claude-code.js.map +0 -1
  136. package/build/hooks/content.d.ts +0 -43
  137. package/build/hooks/content.js.map +0 -1
  138. package/build/hooks/install.d.ts +0 -40
  139. package/build/hooks/install.js +0 -63
  140. package/build/hooks/install.js.map +0 -1
  141. package/build/hooks/openclaw.d.ts +0 -24
  142. package/build/hooks/openclaw.js.map +0 -1
  143. package/build/hooks/opencode.d.ts +0 -29
  144. package/build/hooks/opencode.js.map +0 -1
  145. package/build/tools/approve-doc.d.ts +0 -6
  146. package/build/tools/approve-doc.js.map +0 -1
  147. package/build/tools/dispatch-role.d.ts +0 -16
  148. package/build/tools/dispatch-role.js +0 -266
  149. package/build/tools/dispatch-role.js.map +0 -1
  150. package/build/tools/doc-tools.d.ts +0 -16
  151. package/build/tools/doc-tools.js +0 -425
  152. package/build/tools/doc-tools.js.map +0 -1
  153. package/build/tools/override-tools.d.ts +0 -6
  154. package/build/tools/override-tools.js +0 -129
  155. package/build/tools/override-tools.js.map +0 -1
  156. package/build/tools/report-dispatch.js.map +0 -1
  157. package/build/tools/set-scale.d.ts +0 -6
  158. package/build/tools/set-scale.js +0 -95
  159. package/build/tools/set-scale.js.map +0 -1
  160. package/build/tools/setup-project.d.ts +0 -8
  161. package/build/tools/setup-project.js +0 -116
  162. package/build/tools/setup-project.js.map +0 -1
  163. package/build/tools/update-phase.d.ts +0 -12
  164. package/build/tools/update-phase.js +0 -148
  165. package/build/tools/update-phase.js.map +0 -1
  166. package/workflows/dev/roles/pm.md +0 -99
  167. package/workflows/dev/schemas/deploy.json +0 -20
  168. package/workflows/dev/schemas/fsd.json +0 -25
  169. package/workflows/dev/schemas/project-plan.json +0 -20
  170. package/workflows/dev/schemas/retrospective.json +0 -20
  171. package/workflows/dev/schemas/risk-assessment.json +0 -15
  172. package/workflows/dev/schemas/tech-design.api-contract.json +0 -20
@@ -1,23 +1,27 @@
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 { z } from 'zod';
14
18
  import { getDispatch, updateDispatch, createSession, updateSession, findSessionByAgentId, readSessions, isValidTransition, isTerminalStatus, } from '../core/dispatch.js';
15
- import { listDocs } from '../core/docs.js';
16
- import { readState } from '../core/state.js';
17
- import { loadWorkflow } from '../core/workflow.js';
18
19
  import { resolveActive, isError } from './utils.js';
19
- export function registerReportDispatch(server, builtinDir, customDir) {
20
- 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.', {
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.', {
21
25
  project_name: z.string().describe('Project name'),
22
26
  dispatch_id: z.string().describe('Dispatch ID returned by role_dispatch'),
23
27
  status: z
@@ -57,8 +61,8 @@ export function registerReportDispatch(server, builtinDir, customDir) {
57
61
  // Guard: state machine — reject invalid transitions
58
62
  if (!isValidTransition(dispatch.status, effectiveStatus)) {
59
63
  const reason = isTerminalStatus(dispatch.status)
60
- ? `dispatch "${dispatch_id}" 已处于终态 "${dispatch.status}",无法转换到 "${effectiveStatus}"`
61
- : `dispatch "${dispatch_id}" 当前状态 "${dispatch.status}" 不允许转换到 "${effectiveStatus}"`;
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}".`;
62
66
  return {
63
67
  content: [
64
68
  {
@@ -76,6 +80,7 @@ export function registerReportDispatch(server, builtinDir, customDir) {
76
80
  results.push(`Session: ${session.id} (agent: ${agent_session_id}, status: ${session.status})`);
77
81
  }
78
82
  // Handle status transitions
83
+ let nextActionText = '';
79
84
  if (effectiveStatus === 'completed' ||
80
85
  effectiveStatus === 'failed' ||
81
86
  effectiveStatus === 'cancelled') {
@@ -85,7 +90,7 @@ export function registerReportDispatch(server, builtinDir, customDir) {
85
90
  ...(session ? { sessionId: session.id } : {}),
86
91
  ...(note ? { note } : {}),
87
92
  }, ctx.dir);
88
- // Transition session: completed → idle, failed → lost
93
+ // Transition session: completed → idle, failed/cancelled → lost
89
94
  const sessionId = session?.id ?? dispatch.sessionId;
90
95
  if (sessionId) {
91
96
  const newSessionStatus = effectiveStatus === 'completed' ? 'idle' : 'lost';
@@ -93,6 +98,95 @@ export function registerReportDispatch(server, builtinDir, customDir) {
93
98
  results.push(`Session ${sessionId} → ${newSessionStatus}`);
94
99
  }
95
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
+ }
96
190
  }
97
191
  else {
98
192
  // Running: update dispatch status + associate session
@@ -108,22 +202,6 @@ export function registerReportDispatch(server, builtinDir, customDir) {
108
202
  }
109
203
  results.push(`Dispatch ${dispatch_id} → running`);
110
204
  }
111
- // Completion check: warn if expectedOutputs are missing
112
- if (effectiveStatus === 'completed' && dispatch.expectedOutputs.length > 0) {
113
- const existingDocs = await listDocs(project_name, ctx.number, ctx.dir);
114
- const state = await readState(project_name, ctx.number, ctx.dir);
115
- const wf = await loadWorkflow(builtinDir, customDir, state.workflow);
116
- const missingOutputs = dispatch.expectedOutputs.filter((docId) => {
117
- const docDef = wf.definition.docs[docId];
118
- if (docDef?.external)
119
- return false; // external docs not tracked
120
- return !existingDocs.includes(docId);
121
- });
122
- if (missingOutputs.length > 0) {
123
- results.push(`\n⚠ 预期产出文档缺失: ${missingOutputs.join(', ')}`);
124
- results.push('请确认角色是否已通过 doc_write 提交了所有产出。');
125
- }
126
- }
127
205
  // Build response
128
206
  const nextStepHint = effectiveStatus === 'running'
129
207
  ? `\nNext: When the agent finishes, call dispatch_report with dispatch_id="${dispatch_id}" and status="completed" (or "failed").`
@@ -132,7 +210,7 @@ export function registerReportDispatch(server, builtinDir, customDir) {
132
210
  content: [
133
211
  {
134
212
  type: 'text',
135
- text: `# Report Dispatch: ${dispatch_id}\n\n${results.join('\n')}${nextStepHint}`,
213
+ text: `# Report Dispatch: ${dispatch_id}\n\n${results.join('\n')}${nextStepHint}${nextActionText}`,
136
214
  },
137
215
  ],
138
216
  };
@@ -180,4 +258,4 @@ async function resolveOrCreateSession(projectName, iteration, dispatch, agentSes
180
258
  const session = await createSession(projectName, iteration, dispatch.role, agentType, label, contextDir);
181
259
  return await updateSession(projectName, iteration, session.id, { agentSessionId }, contextDir);
182
260
  }
183
- //# sourceMappingURL=report-dispatch.js.map
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;