@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.
- package/README.md +140 -392
- package/build/cli/setup.d.ts +4 -2
- package/build/cli/setup.js +44 -18
- package/build/cli/setup.js.map +1 -1
- package/build/core/action-registry.d.ts +36 -0
- package/build/core/action-registry.js +53 -0
- package/build/core/action-registry.js.map +1 -0
- package/build/core/artifacts.d.ts +66 -0
- package/build/core/artifacts.js +178 -0
- package/build/core/artifacts.js.map +1 -0
- package/build/core/dispatch.d.ts +6 -2
- package/build/core/dispatch.js +12 -7
- package/build/core/dispatch.js.map +1 -1
- package/build/core/overrides.d.ts +19 -26
- package/build/core/overrides.js +32 -98
- package/build/core/overrides.js.map +1 -1
- package/build/core/plugin.d.ts +86 -0
- package/build/core/plugin.js +332 -0
- package/build/core/plugin.js.map +1 -0
- package/build/core/registry.d.ts +4 -5
- package/build/core/registry.js +8 -9
- package/build/core/registry.js.map +1 -1
- package/build/core/reviews.d.ts +11 -12
- package/build/core/reviews.js +18 -21
- package/build/core/reviews.js.map +1 -1
- package/build/core/schema.d.ts +43 -15
- package/build/core/schema.js +124 -20
- package/build/core/schema.js.map +1 -1
- package/build/core/state.d.ts +26 -27
- package/build/core/state.js +36 -90
- package/build/core/state.js.map +1 -1
- package/build/core/steps.d.ts +13 -14
- package/build/core/steps.js +26 -29
- package/build/core/steps.js.map +1 -1
- package/build/core/tree-utils.d.ts +52 -0
- package/build/core/tree-utils.js +226 -0
- package/build/core/tree-utils.js.map +1 -0
- package/build/core/types.d.ts +389 -118
- package/build/core/types.js +15 -1
- package/build/core/types.js.map +1 -1
- package/build/core/workflow-engine.d.ts +68 -0
- package/build/core/workflow-engine.js +821 -0
- package/build/core/workflow-engine.js.map +1 -0
- package/build/core/workflow-validator.d.ts +22 -0
- package/build/core/workflow-validator.js +489 -0
- package/build/core/workflow-validator.js.map +1 -0
- package/build/index.js +25 -26
- package/build/index.js.map +1 -1
- package/build/setup/inject.d.ts +4 -4
- package/build/setup/inject.js +6 -6
- package/build/setup/inject.js.map +1 -1
- package/build/setup/templates.d.ts +9 -7
- package/build/setup/templates.js +68 -172
- package/build/setup/templates.js.map +1 -1
- package/build/tools/artifact-approve.d.ts +8 -0
- package/build/tools/{approve-doc.js → artifact-approve.js} +24 -16
- package/build/tools/artifact-approve.js.map +1 -0
- package/build/tools/artifact-schema.d.ts +12 -0
- package/build/tools/artifact-schema.js +148 -0
- package/build/tools/artifact-schema.js.map +1 -0
- package/build/tools/artifact-tools.d.ts +18 -0
- package/build/tools/artifact-tools.js +465 -0
- package/build/tools/artifact-tools.js.map +1 -0
- package/build/tools/{report-dispatch.d.ts → dispatch-report.d.ts} +7 -3
- package/build/tools/{report-dispatch.js → dispatch-report.js} +106 -28
- package/build/tools/dispatch-report.js.map +1 -0
- package/build/tools/engine-helpers.d.ts +41 -0
- package/build/tools/engine-helpers.js +182 -0
- package/build/tools/engine-helpers.js.map +1 -0
- package/build/tools/get-project-status.d.ts +6 -4
- package/build/tools/get-project-status.js +265 -248
- package/build/tools/get-project-status.js.map +1 -1
- package/build/tools/get-role-prompt.d.ts +1 -1
- package/build/tools/get-role-prompt.js +7 -41
- package/build/tools/get-role-prompt.js.map +1 -1
- package/build/tools/iteration-start.d.ts +7 -4
- package/build/tools/iteration-start.js +45 -19
- package/build/tools/iteration-start.js.map +1 -1
- package/build/tools/loop-done.d.ts +11 -0
- package/build/tools/loop-done.js +109 -0
- package/build/tools/loop-done.js.map +1 -0
- package/build/tools/patch-start.d.ts +4 -2
- package/build/tools/patch-start.js +36 -11
- package/build/tools/patch-start.js.map +1 -1
- package/build/tools/project-init.d.ts +5 -5
- package/build/tools/project-init.js +41 -10
- package/build/tools/project-init.js.map +1 -1
- package/build/tools/role-dispatch.d.ts +55 -0
- package/build/tools/role-dispatch.js +508 -0
- package/build/tools/role-dispatch.js.map +1 -0
- package/build/tools/utils.d.ts +6 -0
- package/build/tools/utils.js +36 -0
- package/build/tools/utils.js.map +1 -1
- package/package.json +1 -1
- package/{build/hooks/claude-code.js → workflows/dev/hooks/claude.js} +34 -23
- package/{build → workflows/dev}/hooks/content.js +27 -18
- package/workflows/dev/hooks/index.js +52 -0
- package/{build → workflows/dev}/hooks/openclaw.js +31 -20
- package/{build → workflows/dev}/hooks/opencode.js +31 -20
- package/workflows/dev/roles/architect.md +68 -28
- package/workflows/dev/roles/coordinator.md +103 -0
- package/workflows/dev/roles/developer.md +5 -5
- package/workflows/dev/roles/tester.md +19 -19
- package/workflows/dev/schemas/api-contract.json +42 -0
- package/workflows/dev/schemas/api-design.json +30 -13
- package/workflows/dev/schemas/data-model.json +20 -7
- package/workflows/dev/schemas/prd.completeness-check.json +6 -5
- package/workflows/dev/schemas/prd.draft.json +13 -5
- package/workflows/dev/schemas/prd.final.json +34 -11
- package/workflows/dev/schemas/prd.json +29 -11
- package/workflows/dev/schemas/prd.requirements.json +6 -5
- package/workflows/dev/schemas/prototype.json +6 -2
- package/workflows/dev/schemas/task-breakdown.coarse.json +4 -3
- package/workflows/dev/schemas/task-breakdown.dependencies.json +5 -4
- package/workflows/dev/schemas/task-breakdown.detailed.json +8 -3
- package/workflows/dev/schemas/task-breakdown.final.json +8 -3
- package/workflows/dev/schemas/task-breakdown.json +8 -3
- package/workflows/dev/schemas/tech-design.analysis.json +6 -5
- package/workflows/dev/schemas/tech-design.draft.json +14 -5
- package/workflows/dev/schemas/tech-design.final.json +39 -13
- package/workflows/dev/schemas/tech-design.json +34 -13
- package/workflows/dev/schemas/tech-design.research.json +21 -0
- package/workflows/dev/schemas/test-plan.json +17 -7
- package/workflows/dev/schemas/test-report.json +26 -9
- package/workflows/dev/schemas/user-stories.json +7 -3
- package/workflows/dev/tools/index.js +23 -0
- package/workflows/dev/workflow.json +234 -101
- package/build/core/docs.d.ts +0 -36
- package/build/core/docs.js +0 -96
- package/build/core/docs.js.map +0 -1
- package/build/core/workflow.d.ts +0 -33
- package/build/core/workflow.js +0 -140
- package/build/core/workflow.js.map +0 -1
- package/build/hooks/claude-code.d.ts +0 -20
- package/build/hooks/claude-code.js.map +0 -1
- package/build/hooks/content.d.ts +0 -43
- package/build/hooks/content.js.map +0 -1
- package/build/hooks/install.d.ts +0 -40
- package/build/hooks/install.js +0 -63
- package/build/hooks/install.js.map +0 -1
- package/build/hooks/openclaw.d.ts +0 -24
- package/build/hooks/openclaw.js.map +0 -1
- package/build/hooks/opencode.d.ts +0 -29
- package/build/hooks/opencode.js.map +0 -1
- package/build/tools/approve-doc.d.ts +0 -6
- package/build/tools/approve-doc.js.map +0 -1
- package/build/tools/dispatch-role.d.ts +0 -16
- package/build/tools/dispatch-role.js +0 -266
- package/build/tools/dispatch-role.js.map +0 -1
- package/build/tools/doc-tools.d.ts +0 -16
- package/build/tools/doc-tools.js +0 -425
- package/build/tools/doc-tools.js.map +0 -1
- package/build/tools/override-tools.d.ts +0 -6
- package/build/tools/override-tools.js +0 -129
- package/build/tools/override-tools.js.map +0 -1
- package/build/tools/report-dispatch.js.map +0 -1
- package/build/tools/set-scale.d.ts +0 -6
- package/build/tools/set-scale.js +0 -95
- package/build/tools/set-scale.js.map +0 -1
- package/build/tools/setup-project.d.ts +0 -8
- package/build/tools/setup-project.js +0 -116
- package/build/tools/setup-project.js.map +0 -1
- package/build/tools/update-phase.d.ts +0 -12
- package/build/tools/update-phase.js +0 -148
- package/build/tools/update-phase.js.map +0 -1
- package/workflows/dev/roles/pm.md +0 -99
- package/workflows/dev/schemas/deploy.json +0 -20
- package/workflows/dev/schemas/fsd.json +0 -25
- package/workflows/dev/schemas/project-plan.json +0 -20
- package/workflows/dev/schemas/retrospective.json +0 -20
- package/workflows/dev/schemas/risk-assessment.json +0 -15
- 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
|
-
*
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
? `
|
|
61
|
-
: `
|
|
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
|
|
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":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAU/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAWzD;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,GAAY,EAAE,IAAY;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3E,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,OAAO,GAAI,OAAmC,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CACrB,WAAmB,EACnB,SAAiB,EACjB,UAAkB,EAClB,iBAA8B,EAC9B,OAA2C,EAC3C,aAAmC;IAEnC,OAAO;QACH,cAAc,EAAE,CAAC,UAAkB,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;QACzE,gBAAgB,EAAE,CAAC,UAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,UAAU;QACpF,aAAa,EAAE,CAAC,UAAkB,EAAE,KAAa,EAAE,EAAE;YACjD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,OAAO,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC5C,OAAO,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,kBAAkB,CAC7B,WAAmB,EACnB,SAAiB,EACjB,UAAkB,EAClB,EAAkB,EAClB,KAAwB;IAExB,yDAAyD;IACzD,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEtE,mEAAmE;IACnE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAmB,CAAC;IACjD,KAAK,MAAM,UAAU,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACvD,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YACnE,sDAAsD;YACtD,IAAI,CAAC;gBACD,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACL,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC3C,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,wCAAwC;QAC5C,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAEhH,OAAO;QACH,IAAI,EAAE,OAAO;QACb,aAAa,EAAE,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE;YAC5C,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,IAAI,oBAAoB,CAAC;QAChE,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAkB,EAAE,MAAc;IAC3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACpD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,uBAAuB;IACvB,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;AACvE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,YAAoB,EACpB,WAAmB,EACnB,GAAoB,EACpB,KAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAsB;QAC7B,UAAU,EAAE,GAAG,CAAC,GAAG;QACnB,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG;QACzB,YAAY,EAAE,GAAG,CAAC,aAAa;KAClC,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAExF,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAEzE,iFAAiF;IACjF,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAChC,MAAM,YAAY,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,MAAM,CAAC,UAAU;KAChC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,YAAoB,EACpB,WAAmB,EACnB,GAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAsB;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,UAAU;YACX,IAAI,UAAU,CAAC,gBAAgB,IAAI,UAAU,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxE,KAAK,CAAC,IAAI,CAAC,sCAAsC,UAAU,CAAC,gBAAgB,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAC7F,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAE,CAAC;oBAC1C,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC9D,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,IAAI,CAAC,kCAAkC,UAAU,CAAC,IAAI,eAAe,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;YACrG,CAAC;YACD,IAAI,UAAU,CAAC,YAAY;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM;QACV,KAAK,gBAAgB;YACjB,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC7C,IAAI,UAAU,CAAC,YAAY;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM;QACV,KAAK,kBAAkB;YACnB,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;YAC/C,IAAI,UAAU,CAAC,YAAY;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM;QACV,KAAK,MAAM;YACP,KAAK,CAAC,IAAI,CAAC,mBAAmB,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;YACzD,MAAM;QACV,KAAK,WAAW;YACZ,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YAClD,MAAM;QACV,KAAK,QAAQ;YACT,KAAK,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;YAC7D,MAAM;QACV,KAAK,eAAe;YAChB,KAAK,CAAC,IAAI,CAAC,kCAAkC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;YACnE,IAAI,UAAU,CAAC,YAAY;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM;QACV,KAAK,MAAM;YACP,0BAA0B;YAC1B,MAAM;IACd,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tool: project_status
|
|
3
|
-
* Read the current project status with rich context for
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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,
|
|
12
|
+
export declare function registerGetProjectStatus(server: McpServer, workflowsDir: string): void;
|