@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.
- 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 +18 -11
- package/build/core/dispatch.js +43 -33
- package/build/core/dispatch.js.map +1 -1
- package/build/core/issues.d.ts +37 -0
- package/build/core/issues.js +100 -0
- package/build/core/issues.js.map +1 -0
- 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 +36 -3
- package/build/core/registry.js +63 -5
- package/build/core/registry.js.map +1 -1
- package/build/core/reviews.d.ts +13 -13
- package/build/core/reviews.js +31 -32
- 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 +29 -22
- package/build/core/state.js +49 -81
- package/build/core/state.js.map +1 -1
- package/build/core/steps.d.ts +15 -15
- package/build/core/steps.js +32 -33
- 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 +417 -117
- 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 +28 -25
- 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 -103
- package/build/setup/templates.js.map +1 -1
- package/build/tools/artifact-approve.d.ts +8 -0
- package/build/tools/artifact-approve.js +94 -0
- 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/dispatch-report.js +261 -0
- 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 +308 -246
- 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/issue-tools.d.ts +10 -0
- package/build/tools/issue-tools.js +169 -0
- package/build/tools/issue-tools.js.map +1 -0
- package/build/tools/iteration-start.d.ts +7 -4
- package/build/tools/iteration-start.js +51 -20
- 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 +16 -0
- package/build/tools/patch-start.js +122 -0
- package/build/tools/patch-start.js.map +1 -0
- package/build/tools/project-init.d.ts +5 -5
- package/build/tools/project-init.js +47 -18
- 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 +40 -0
- package/build/tools/utils.js +97 -0
- package/build/tools/utils.js.map +1 -0
- 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 -32
- package/build/core/docs.js +0 -91
- 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 +0 -108
- 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 -277
- 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 -389
- 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 +0 -194
- 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 -107
- 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 -159
- 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
package/build/tools/doc-tools.js
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tools: doc_write / doc_read / doc_list
|
|
3
|
-
* Read and write project documents under <data_dir>/<project_name>/docs/
|
|
4
|
-
*
|
|
5
|
-
* doc_write validates content against document schemas and checks review
|
|
6
|
-
* configuration. If validation fails, the write is rejected with specific
|
|
7
|
-
* error details. If review is required, the document is submitted for
|
|
8
|
-
* user approval.
|
|
9
|
-
*
|
|
10
|
-
* Sequential mode (P3): When a document has `steps` defined in workflow.json
|
|
11
|
-
* and the project scale is >= medium, doc_write requires a `step` parameter.
|
|
12
|
-
* Each step is validated independently, and the final step automatically
|
|
13
|
-
* writes the formal document and triggers the review flow.
|
|
14
|
-
*/
|
|
15
|
-
import { z } from 'zod';
|
|
16
|
-
import { writeDoc, readDoc, listDocs, writeStepArtifact } from '../core/docs.js';
|
|
17
|
-
import { readState } from '../core/state.js';
|
|
18
|
-
import { loadWorkflow } from '../core/workflow.js';
|
|
19
|
-
import { getMergedOverrides, resolveDocReview } from '../core/overrides.js';
|
|
20
|
-
import { submitForReview } from '../core/reviews.js';
|
|
21
|
-
import { loadDocSchema, validateDoc, formatValidationErrors } from '../core/schema.js';
|
|
22
|
-
import { getDocStepState, getCompletedStepIds, recordStepCompletion, markFinalized } from '../core/steps.js';
|
|
23
|
-
import { getProject } from '../core/registry.js';
|
|
24
|
-
/** Scales that activate sequential mode (medium and above) */
|
|
25
|
-
const SEQUENTIAL_SCALES = new Set(['medium', 'large']);
|
|
26
|
-
/**
|
|
27
|
-
* Check if sequential mode is active for a given doc definition and scale.
|
|
28
|
-
* Returns false when scale is null (not yet set).
|
|
29
|
-
*/
|
|
30
|
-
function isSequentialActive(docDef, scale) {
|
|
31
|
-
return scale !== null && !!docDef.steps?.length && SEQUENTIAL_SCALES.has(scale);
|
|
32
|
-
}
|
|
33
|
-
export function registerDocTools(server, builtinDir, customDir) {
|
|
34
|
-
server.tool('doc_write', 'Write or update a project document. For documents with sequential steps (PRD, tech-design, task-breakdown) at medium/large scale, you MUST specify the step parameter. Automatically checks review configuration — if review is required, the document is submitted for user approval.', {
|
|
35
|
-
project_name: z.string().describe('Project name'),
|
|
36
|
-
doc_id: z
|
|
37
|
-
.string()
|
|
38
|
-
.describe('Document ID (e.g. prd, user-stories, fsd, prototype, tech-design, task-breakdown, etc.)'),
|
|
39
|
-
content: z.string().describe('Document content (markdown, HTML, or JSON depending on doc type and step)'),
|
|
40
|
-
step: z
|
|
41
|
-
.string()
|
|
42
|
-
.optional()
|
|
43
|
-
.describe('Sequential step ID (required for docs with steps at medium/large scale). Use project_status to see available steps.'),
|
|
44
|
-
}, async ({ project_name, doc_id, content, step }) => {
|
|
45
|
-
// Resolve current iteration
|
|
46
|
-
const entry = await getProject(project_name);
|
|
47
|
-
if (!entry || entry.currentIteration === 0) {
|
|
48
|
-
return {
|
|
49
|
-
content: [
|
|
50
|
-
{
|
|
51
|
-
type: 'text',
|
|
52
|
-
text: `项目 "${project_name}" 未找到或尚未开始迭代。请先调用 iteration_start。`,
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
isError: true,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const iteration = entry.currentIteration;
|
|
59
|
-
// Load workflow to get doc definition (format, review defaults)
|
|
60
|
-
const state = await readState(project_name, iteration);
|
|
61
|
-
const wf = await loadWorkflow(builtinDir, customDir, state.workflow);
|
|
62
|
-
const docDef = wf.definition.docs[doc_id];
|
|
63
|
-
const isHtml = docDef?.format === 'html';
|
|
64
|
-
// Guard: doc_id must be defined in workflow
|
|
65
|
-
if (!docDef) {
|
|
66
|
-
const validIds = Object.keys(wf.definition.docs)
|
|
67
|
-
.filter((id) => !wf.definition.docs[id].external)
|
|
68
|
-
.join(', ');
|
|
69
|
-
return {
|
|
70
|
-
content: [
|
|
71
|
-
{
|
|
72
|
-
type: 'text',
|
|
73
|
-
text: `文档类型 "${doc_id}" 未在工作流中定义。可用的文档类型: ${validIds}`,
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
isError: true,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
// Guard: reject external doc types (should be produced outside doc_write)
|
|
80
|
-
if (docDef.external) {
|
|
81
|
-
return {
|
|
82
|
-
content: [
|
|
83
|
-
{
|
|
84
|
-
type: 'text',
|
|
85
|
-
text: `文档 "${doc_id}" 是外部产出类型,不应通过 doc_write 写入。`,
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
isError: true,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
// Guard: empty content
|
|
92
|
-
if (!content.trim()) {
|
|
93
|
-
return {
|
|
94
|
-
content: [
|
|
95
|
-
{
|
|
96
|
-
type: 'text',
|
|
97
|
-
text: '文档内容为空,请提供实际内容后重新提交。',
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
isError: true,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
// ─── Sequential Mode ───
|
|
104
|
-
if (isSequentialActive(docDef, state.scale)) {
|
|
105
|
-
return handleSequentialWrite(builtinDir, customDir, state.workflow, project_name, iteration, doc_id, content, step, docDef, state.scale);
|
|
106
|
-
}
|
|
107
|
-
// ─── Normal Mode (no steps or small scale) ───
|
|
108
|
-
// If step was passed but sequential is not active, warn but proceed
|
|
109
|
-
if (step) {
|
|
110
|
-
// Ignore step parameter for non-sequential docs
|
|
111
|
-
}
|
|
112
|
-
// Schema validation — reject write if content doesn't meet requirements
|
|
113
|
-
const schema = await loadDocSchema(builtinDir, customDir, state.workflow, doc_id);
|
|
114
|
-
if (schema) {
|
|
115
|
-
const result = validateDoc(content, schema, state.scale, isHtml);
|
|
116
|
-
if (!result.valid) {
|
|
117
|
-
return {
|
|
118
|
-
content: [
|
|
119
|
-
{
|
|
120
|
-
type: 'text',
|
|
121
|
-
text: formatValidationErrors(result.errors),
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
isError: true,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Write the document with correct extension
|
|
129
|
-
const filePath = await writeDoc(project_name, iteration, doc_id, content, docDef);
|
|
130
|
-
// Check if review is required
|
|
131
|
-
const overrides = await getMergedOverrides(project_name);
|
|
132
|
-
const needsReview = docDef ? resolveDocReview(doc_id, docDef, overrides) : false;
|
|
133
|
-
if (needsReview) {
|
|
134
|
-
await submitForReview(project_name, iteration, doc_id);
|
|
135
|
-
const docName = docDef?.name ?? doc_id;
|
|
136
|
-
return {
|
|
137
|
-
content: [
|
|
138
|
-
{
|
|
139
|
-
type: 'text',
|
|
140
|
-
text: [
|
|
141
|
-
`Document "${doc_id}" (${docName}) written to ${filePath}`,
|
|
142
|
-
``,
|
|
143
|
-
`** REVIEW REQUIRED **`,
|
|
144
|
-
`This document requires user approval before the workflow can proceed.`,
|
|
145
|
-
`Please present the document content to the user and ask for their confirmation.`,
|
|
146
|
-
`After user approval, call doc_approve with project_name="${project_name}" and doc_id="${doc_id}".`,
|
|
147
|
-
`If the user requests changes, revise the document and call doc_write again.`,
|
|
148
|
-
].join('\n'),
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
content: [
|
|
155
|
-
{
|
|
156
|
-
type: 'text',
|
|
157
|
-
text: `Document "${doc_id}" written to ${filePath}`,
|
|
158
|
-
},
|
|
159
|
-
],
|
|
160
|
-
};
|
|
161
|
-
});
|
|
162
|
-
server.tool('doc_read', 'Read a project document from the project docs directory.', {
|
|
163
|
-
project_name: z.string().describe('Project name'),
|
|
164
|
-
doc_id: z.string().describe('Document ID to read'),
|
|
165
|
-
}, async ({ project_name, doc_id }) => {
|
|
166
|
-
try {
|
|
167
|
-
// Resolve current iteration
|
|
168
|
-
const entry = await getProject(project_name);
|
|
169
|
-
if (!entry || entry.currentIteration === 0) {
|
|
170
|
-
return {
|
|
171
|
-
content: [
|
|
172
|
-
{
|
|
173
|
-
type: 'text',
|
|
174
|
-
text: `项目 "${project_name}" 未找到或尚未开始迭代。请先调用 iteration_start。`,
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
isError: true,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
const iteration = entry.currentIteration;
|
|
181
|
-
const docContent = await readDoc(project_name, iteration, doc_id);
|
|
182
|
-
return {
|
|
183
|
-
content: [
|
|
184
|
-
{
|
|
185
|
-
type: 'text',
|
|
186
|
-
text: docContent,
|
|
187
|
-
},
|
|
188
|
-
],
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
return {
|
|
193
|
-
content: [
|
|
194
|
-
{
|
|
195
|
-
type: 'text',
|
|
196
|
-
text: `Document "${doc_id}" not found. Use doc_list to see available documents.`,
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
isError: true,
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
server.tool('doc_list', 'List all project documents in the project docs directory.', {
|
|
204
|
-
project_name: z.string().describe('Project name'),
|
|
205
|
-
}, async ({ project_name }) => {
|
|
206
|
-
// Resolve current iteration
|
|
207
|
-
const entry = await getProject(project_name);
|
|
208
|
-
if (!entry || entry.currentIteration === 0) {
|
|
209
|
-
return {
|
|
210
|
-
content: [
|
|
211
|
-
{
|
|
212
|
-
type: 'text',
|
|
213
|
-
text: `项目 "${project_name}" 未找到或尚未开始迭代。请先调用 iteration_start。`,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
isError: true,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
const iteration = entry.currentIteration;
|
|
220
|
-
const docs = await listDocs(project_name, iteration);
|
|
221
|
-
return {
|
|
222
|
-
content: [
|
|
223
|
-
{
|
|
224
|
-
type: 'text',
|
|
225
|
-
text: docs.length > 0
|
|
226
|
-
? `Documents:\n${docs.map((d) => `- ${d}`).join('\n')}`
|
|
227
|
-
: 'No documents found for this iteration.',
|
|
228
|
-
},
|
|
229
|
-
],
|
|
230
|
-
};
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
async function handleSequentialWrite(builtinDir, customDir, workflowName, projectName, iteration, docId, content, step, docDef, scale) {
|
|
234
|
-
const steps = docDef.steps;
|
|
235
|
-
const stepIds = steps.map((s) => s.id);
|
|
236
|
-
const stepNames = steps.map((s) => `${s.id} (${s.name})`).join(', ');
|
|
237
|
-
// Guard: step parameter is required in sequential mode
|
|
238
|
-
if (!step) {
|
|
239
|
-
return {
|
|
240
|
-
content: [
|
|
241
|
-
{
|
|
242
|
-
type: 'text',
|
|
243
|
-
text: [
|
|
244
|
-
`文档 "${docId}" 在 ${scale} 规模项目中需要分步写入。`,
|
|
245
|
-
`请指定 step 参数。可用的步骤: ${stepNames}`,
|
|
246
|
-
``,
|
|
247
|
-
`步骤说明:`,
|
|
248
|
-
...steps.map((s, i) => ` ${i + 1}. ${s.id} — ${s.description}`),
|
|
249
|
-
].join('\n'),
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
isError: true,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
// Guard: step must be valid
|
|
256
|
-
const stepDef = steps.find((s) => s.id === step);
|
|
257
|
-
if (!stepDef) {
|
|
258
|
-
return {
|
|
259
|
-
content: [
|
|
260
|
-
{
|
|
261
|
-
type: 'text',
|
|
262
|
-
text: `未知的步骤 "${step}"。可用的步骤: ${stepNames}`,
|
|
263
|
-
},
|
|
264
|
-
],
|
|
265
|
-
isError: true,
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
const stepIndex = stepIds.indexOf(step);
|
|
269
|
-
const stepState = await getDocStepState(projectName, iteration, docId);
|
|
270
|
-
const completedIds = getCompletedStepIds(stepState);
|
|
271
|
-
// Guard: prerequisite steps must be completed (hard enforcement)
|
|
272
|
-
for (let i = 0; i < stepIndex; i++) {
|
|
273
|
-
if (!completedIds.has(stepIds[i])) {
|
|
274
|
-
const missingStep = steps[i];
|
|
275
|
-
return {
|
|
276
|
-
content: [
|
|
277
|
-
{
|
|
278
|
-
type: 'text',
|
|
279
|
-
text: `无法写入步骤 "${step}":前置步骤 "${missingStep.id}" (${missingStep.name}) 尚未完成。请先完成该步骤。`,
|
|
280
|
-
},
|
|
281
|
-
],
|
|
282
|
-
isError: true,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
// Step schema validation
|
|
287
|
-
const isJson = stepDef.format === 'json';
|
|
288
|
-
const stepSchemaId = `${docId}.${step}`;
|
|
289
|
-
const stepSchema = await loadDocSchema(builtinDir, customDir, workflowName, stepSchemaId);
|
|
290
|
-
if (stepSchema) {
|
|
291
|
-
const result = validateDoc(content, stepSchema, scale, false, isJson);
|
|
292
|
-
if (!result.valid) {
|
|
293
|
-
return {
|
|
294
|
-
content: [
|
|
295
|
-
{
|
|
296
|
-
type: 'text',
|
|
297
|
-
text: formatValidationErrors(result.errors),
|
|
298
|
-
},
|
|
299
|
-
],
|
|
300
|
-
isError: true,
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
// Write the step artifact
|
|
305
|
-
const artifactPath = await writeStepArtifact(projectName, iteration, docId, step, content, stepDef.format);
|
|
306
|
-
// Record step completion (handles rollback if overwriting)
|
|
307
|
-
await recordStepCompletion(projectName, iteration, docId, step, artifactPath, stepIds);
|
|
308
|
-
const isLastStep = stepIndex === steps.length - 1;
|
|
309
|
-
if (isLastStep) {
|
|
310
|
-
// Auto-merge: validate against final doc schema, write formal doc, trigger review
|
|
311
|
-
return handleFinalStep(builtinDir, customDir, workflowName, projectName, iteration, docId, content, docDef, scale, stepDef);
|
|
312
|
-
}
|
|
313
|
-
// Not the last step — return progress info
|
|
314
|
-
const nextStep = steps[stepIndex + 1];
|
|
315
|
-
return {
|
|
316
|
-
content: [
|
|
317
|
-
{
|
|
318
|
-
type: 'text',
|
|
319
|
-
text: [
|
|
320
|
-
`步骤 "${step}" (${stepDef.name}) 完成,产物已写入 ${artifactPath}`,
|
|
321
|
-
``,
|
|
322
|
-
`下一步: ${nextStep.id} — ${nextStep.description}`,
|
|
323
|
-
`请调用 doc_write(project_name="${projectName}", doc_id="${docId}", step="${nextStep.id}", content=...)`,
|
|
324
|
-
].join('\n'),
|
|
325
|
-
},
|
|
326
|
-
],
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
async function handleFinalStep(builtinDir, customDir, workflowName, projectName, iteration, docId, content, docDef, scale, stepDef) {
|
|
330
|
-
const isHtml = docDef.format === 'html';
|
|
331
|
-
// Validate against the final document schema (e.g. prd.json)
|
|
332
|
-
const finalSchema = await loadDocSchema(builtinDir, customDir, workflowName, docId);
|
|
333
|
-
if (finalSchema) {
|
|
334
|
-
const isJson = stepDef.format === 'json';
|
|
335
|
-
const result = validateDoc(content, finalSchema, scale, isHtml, isJson);
|
|
336
|
-
if (!result.valid) {
|
|
337
|
-
return {
|
|
338
|
-
content: [
|
|
339
|
-
{
|
|
340
|
-
type: 'text',
|
|
341
|
-
text: [
|
|
342
|
-
'最终文档校验失败:',
|
|
343
|
-
formatValidationErrors(result.errors),
|
|
344
|
-
'',
|
|
345
|
-
`请修正后重新提交步骤 "${stepDef.id}"。`,
|
|
346
|
-
].join('\n'),
|
|
347
|
-
},
|
|
348
|
-
],
|
|
349
|
-
isError: true,
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// Write the formal document
|
|
354
|
-
const filePath = await writeDoc(projectName, iteration, docId, content, docDef);
|
|
355
|
-
// Mark as finalized
|
|
356
|
-
await markFinalized(projectName, iteration, docId);
|
|
357
|
-
// Check if review is required
|
|
358
|
-
const overrides = await getMergedOverrides(projectName);
|
|
359
|
-
const needsReview = resolveDocReview(docId, docDef, overrides);
|
|
360
|
-
if (needsReview) {
|
|
361
|
-
await submitForReview(projectName, iteration, docId);
|
|
362
|
-
const docName = docDef.name ?? docId;
|
|
363
|
-
return {
|
|
364
|
-
content: [
|
|
365
|
-
{
|
|
366
|
-
type: 'text',
|
|
367
|
-
text: [
|
|
368
|
-
`所有步骤完成!文档 "${docId}" (${docName}) 已写入 ${filePath}`,
|
|
369
|
-
``,
|
|
370
|
-
`** REVIEW REQUIRED **`,
|
|
371
|
-
`This document requires user approval before the workflow can proceed.`,
|
|
372
|
-
`Please present the document content to the user and ask for their confirmation.`,
|
|
373
|
-
`After user approval, call doc_approve with project_name="${projectName}" and doc_id="${docId}".`,
|
|
374
|
-
`If the user requests changes, revise the document and call doc_write again with the appropriate step.`,
|
|
375
|
-
].join('\n'),
|
|
376
|
-
},
|
|
377
|
-
],
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
return {
|
|
381
|
-
content: [
|
|
382
|
-
{
|
|
383
|
-
type: 'text',
|
|
384
|
-
text: `所有步骤完成!文档 "${docId}" 已写入 ${filePath}`,
|
|
385
|
-
},
|
|
386
|
-
],
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
//# sourceMappingURL=doc-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doc-tools.js","sourceRoot":"","sources":["../../src/tools/doc-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tools: guard_set / review_set_rule / guard_get
|
|
3
|
-
* Manage capability overrides and review settings.
|
|
4
|
-
*/
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
import { setCapabilityOverride, setReviewOverride, getMergedOverrides, readGlobalOverrides, readProjectOverrides, } from '../core/overrides.js';
|
|
7
|
-
export function registerOverrideTools(server) {
|
|
8
|
-
server.tool('guard_set', 'Configure a role capability to use an external skill or MCP tool instead of the built-in behavior. Settings are saved to the override config file.', {
|
|
9
|
-
scope: z.enum(['global', 'project']).describe('Override scope: global (all projects) or project-specific'),
|
|
10
|
-
project_name: z.string().optional().describe("Project name (required when scope is 'project')"),
|
|
11
|
-
role_id: z.string().describe('Role ID (e.g. pm, architect, developer, tester)'),
|
|
12
|
-
capability_id: z.string().describe('Capability ID (e.g. write-prd, write-tech-design)'),
|
|
13
|
-
type: z.enum(['skill', 'mcp']).describe('Tool source type'),
|
|
14
|
-
tool: z.string().describe('Tool name'),
|
|
15
|
-
server_name: z.string().optional().describe("MCP server name (required when type is 'mcp')"),
|
|
16
|
-
params: z
|
|
17
|
-
.record(z.string(), z.unknown())
|
|
18
|
-
.optional()
|
|
19
|
-
.describe('Static parameters to always pass when calling the tool'),
|
|
20
|
-
notes: z.string().optional().describe('Additional notes for prompt generation (rarely needed)'),
|
|
21
|
-
}, async ({ scope, project_name, role_id, capability_id, type, tool, server_name, params, notes }) => {
|
|
22
|
-
if (scope === 'project' && !project_name) {
|
|
23
|
-
return {
|
|
24
|
-
content: [
|
|
25
|
-
{
|
|
26
|
-
type: 'text',
|
|
27
|
-
text: "Error: project_name is required when scope is 'project'.",
|
|
28
|
-
},
|
|
29
|
-
],
|
|
30
|
-
isError: true,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
const override = { type, tool };
|
|
34
|
-
if (server_name)
|
|
35
|
-
override.server = server_name;
|
|
36
|
-
if (params)
|
|
37
|
-
override.params = params;
|
|
38
|
-
if (notes)
|
|
39
|
-
override.notes = notes;
|
|
40
|
-
await setCapabilityOverride(scope, project_name ?? null, role_id, capability_id, override);
|
|
41
|
-
return {
|
|
42
|
-
content: [
|
|
43
|
-
{
|
|
44
|
-
type: 'text',
|
|
45
|
-
text: `Override set: ${role_id}.${capability_id} → ${type === 'mcp' ? `${server_name}/${tool}` : tool} (${scope})`,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
server.tool('review_set_rule', 'Enable or disable review requirement for a specific document type.', {
|
|
51
|
-
scope: z.enum(['global', 'project']).describe('Override scope: global or project-specific'),
|
|
52
|
-
project_name: z.string().optional().describe("Project name (required when scope is 'project')"),
|
|
53
|
-
doc_id: z.string().describe('Document ID (e.g. prd, prototype)'),
|
|
54
|
-
enabled: z.boolean().describe('true = require review, false = skip review'),
|
|
55
|
-
}, async ({ scope, project_name, doc_id, enabled }) => {
|
|
56
|
-
if (scope === 'project' && !project_name) {
|
|
57
|
-
return {
|
|
58
|
-
content: [
|
|
59
|
-
{
|
|
60
|
-
type: 'text',
|
|
61
|
-
text: "Error: project_name is required when scope is 'project'.",
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
isError: true,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
await setReviewOverride(scope, project_name ?? null, doc_id, enabled);
|
|
68
|
-
return {
|
|
69
|
-
content: [
|
|
70
|
-
{
|
|
71
|
-
type: 'text',
|
|
72
|
-
text: `Review override set: ${doc_id} → ${enabled ? 'required' : 'skipped'} (${scope})`,
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
};
|
|
76
|
-
});
|
|
77
|
-
server.tool('guard_get', 'Get the current override configuration. Shows the merged result (project + global) or a specific scope.', {
|
|
78
|
-
project_name: z
|
|
79
|
-
.string()
|
|
80
|
-
.optional()
|
|
81
|
-
.describe('Project name — if provided, shows merged config for this project'),
|
|
82
|
-
scope: z
|
|
83
|
-
.enum(['merged', 'global', 'project'])
|
|
84
|
-
.default('merged')
|
|
85
|
-
.describe('Which config to show: merged (default), global only, or project only'),
|
|
86
|
-
}, async ({ project_name, scope }) => {
|
|
87
|
-
let config;
|
|
88
|
-
let label;
|
|
89
|
-
if (scope === 'global') {
|
|
90
|
-
config = await readGlobalOverrides();
|
|
91
|
-
label = 'Global overrides';
|
|
92
|
-
}
|
|
93
|
-
else if (scope === 'project') {
|
|
94
|
-
if (!project_name) {
|
|
95
|
-
return {
|
|
96
|
-
content: [
|
|
97
|
-
{
|
|
98
|
-
type: 'text',
|
|
99
|
-
text: "Error: project_name is required when scope is 'project'.",
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
isError: true,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
config = await readProjectOverrides(project_name);
|
|
106
|
-
label = `Project overrides for "${project_name}"`;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
if (!project_name) {
|
|
110
|
-
config = await readGlobalOverrides();
|
|
111
|
-
label = 'Global overrides (no project specified)';
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
config = await getMergedOverrides(project_name);
|
|
115
|
-
label = `Merged overrides for "${project_name}"`;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const isEmpty = !config.review && (!config.roles || Object.keys(config.roles).length === 0);
|
|
119
|
-
return {
|
|
120
|
-
content: [
|
|
121
|
-
{
|
|
122
|
-
type: 'text',
|
|
123
|
-
text: isEmpty ? `${label}: (none configured)` : `${label}:\n${JSON.stringify(config, null, 2)}`,
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
//# sourceMappingURL=override-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"override-tools.js","sourceRoot":"","sources":["../../src/tools/override-tools.ts"],"names":[],"mappings":"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"}
|