@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
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: artifact_schema
|
|
3
|
+
*
|
|
4
|
+
* Query artifact structure requirements and writing guidance before writing.
|
|
5
|
+
* Returns human-readable schema guidance including required sections/fields,
|
|
6
|
+
* content boundaries, format requirements, and step-by-step constraints.
|
|
7
|
+
*
|
|
8
|
+
* Primarily used by coordinator (who is not dispatched and thus doesn't receive
|
|
9
|
+
* Artifact Requirements automatically via role_dispatch).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { loadArtifactSchema, formatSchemaGuidance } from '../core/schema.js';
|
|
13
|
+
import { loadWorkflowForContext } from './engine-helpers.js';
|
|
14
|
+
import { resolveActive, isError } from './utils.js';
|
|
15
|
+
export function registerArtifactSchema(server, workflowsDir) {
|
|
16
|
+
server.tool('artifact_schema', 'Query artifact structure requirements and writing guidance. Call this before writing an artifact to understand required sections, content boundaries, and format constraints.', {
|
|
17
|
+
project_name: z.string().describe('Project name'),
|
|
18
|
+
artifact_id: z
|
|
19
|
+
.string()
|
|
20
|
+
.describe('Artifact ID (e.g. prd, user-stories, fsd, prototype, tech-design, task-breakdown, etc.)'),
|
|
21
|
+
step: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Step ID (e.g. requirements, draft, final). If specified, returns only that step's schema. If omitted, returns the full artifact schema including all steps."),
|
|
25
|
+
}, async ({ project_name, artifact_id, step }) => {
|
|
26
|
+
try {
|
|
27
|
+
const ctx = await resolveActive(project_name);
|
|
28
|
+
if (isError(ctx))
|
|
29
|
+
return ctx;
|
|
30
|
+
const { wf, state } = await loadWorkflowForContext(workflowsDir, project_name, ctx);
|
|
31
|
+
// Validate artifact_id exists in workflow
|
|
32
|
+
const artifactDef = wf.artifactDefinitions[artifact_id];
|
|
33
|
+
if (!artifactDef) {
|
|
34
|
+
const available = Object.keys(wf.artifactDefinitions).join(', ');
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: `Artifact "${artifact_id}" not found in workflow. Available: ${available}`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// If a specific step is requested, return only that step's schema
|
|
46
|
+
if (step) {
|
|
47
|
+
// Validate step exists in artifact definition
|
|
48
|
+
if (!artifactDef.steps || !artifactDef.steps.find((s) => s.id === step)) {
|
|
49
|
+
const availableSteps = artifactDef.steps?.map((s) => s.id).join(', ') ?? '(无分步)';
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: `Step "${step}" not found for artifact "${artifact_id}". Available steps: ${availableSteps}`,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
isError: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const stepSchema = await loadArtifactSchema(workflowsDir, state.workflow, `${artifact_id}.${step}`);
|
|
61
|
+
const stepDefFound = artifactDef.steps.find((s) => s.id === step);
|
|
62
|
+
const lines = [];
|
|
63
|
+
lines.push(`## Step 要求: ${artifact_id}.${step}(${stepDefFound.name})`);
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push(`格式: ${stepDefFound.format === 'json' ? 'JSON' : 'Markdown'}`);
|
|
66
|
+
lines.push(`描述: ${stepDefFound.description}`);
|
|
67
|
+
if (stepSchema) {
|
|
68
|
+
if (stepSchema.guidance) {
|
|
69
|
+
lines.push(`内容指引: ${stepSchema.guidance}`);
|
|
70
|
+
}
|
|
71
|
+
if (stepSchema.minLength) {
|
|
72
|
+
lines.push(`最小长度: ${stepSchema.minLength} 字符`);
|
|
73
|
+
}
|
|
74
|
+
if (stepSchema.jsonFields) {
|
|
75
|
+
const reqFields = stepSchema.jsonFields.filter((f) => f.required);
|
|
76
|
+
if (reqFields.length > 0) {
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('### 必需 JSON 字段');
|
|
79
|
+
for (const field of reqFields) {
|
|
80
|
+
let desc = `- ${field.field}`;
|
|
81
|
+
if (field.type)
|
|
82
|
+
desc += ` (${field.type})`;
|
|
83
|
+
if (field.minItems)
|
|
84
|
+
desc += `, ≥${field.minItems} 项`;
|
|
85
|
+
lines.push(desc);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (stepSchema.sections) {
|
|
90
|
+
const reqSections = stepSchema.sections.filter((s) => s.required);
|
|
91
|
+
if (reqSections.length > 0) {
|
|
92
|
+
lines.push('');
|
|
93
|
+
lines.push('### 必需章节');
|
|
94
|
+
for (const section of reqSections) {
|
|
95
|
+
const heading = section.heading.replace(/^#+\s*/, '');
|
|
96
|
+
lines.push(`- ${heading}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push('(此 step 无 schema 约束)');
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Full artifact schema
|
|
110
|
+
const schema = await loadArtifactSchema(workflowsDir, state.workflow, artifact_id);
|
|
111
|
+
// Load step schemas if artifact has steps
|
|
112
|
+
let stepSchemas;
|
|
113
|
+
if (artifactDef.steps && artifactDef.steps.length > 0) {
|
|
114
|
+
stepSchemas = [];
|
|
115
|
+
for (const s of artifactDef.steps) {
|
|
116
|
+
const stepSchema = await loadArtifactSchema(workflowsDir, state.workflow, `${artifact_id}.${s.id}`);
|
|
117
|
+
stepSchemas.push({ step: s, schema: stepSchema });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (!schema && (!stepSchemas || stepSchemas.every((s) => !s.schema))) {
|
|
121
|
+
return {
|
|
122
|
+
content: [
|
|
123
|
+
{
|
|
124
|
+
type: 'text',
|
|
125
|
+
text: `Artifact "${artifact_id}" 无 schema 定义。`,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const guidance = formatSchemaGuidance(artifact_id, artifactDef, schema, stepSchemas);
|
|
131
|
+
return {
|
|
132
|
+
content: [{ type: 'text', text: guidance }],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
return {
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
isError: true,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=artifact-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-schema.js","sourceRoot":"","sources":["../../src/tools/artifact-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools: artifact_write / artifact_read / artifact_list
|
|
3
|
+
* Read and write project artifacts. Output paths are resolved per artifact
|
|
4
|
+
*
|
|
5
|
+
* artifact_write validates content against artifact schemas and checks review
|
|
6
|
+
* configuration. If validation fails, the write is rejected with specific
|
|
7
|
+
* error details. If review is required, the artifact is submitted for
|
|
8
|
+
* user approval.
|
|
9
|
+
*
|
|
10
|
+
* Sequential mode: When an artifact has `steps` defined in workflow.json,
|
|
11
|
+
* artifact_write requires a `step` parameter. Each step is validated
|
|
12
|
+
* independently, and the final step automatically writes the formal
|
|
13
|
+
* artifact and triggers the review flow.
|
|
14
|
+
*
|
|
15
|
+
* After writing, triggers engine event `artifact_written` to evaluate gates.
|
|
16
|
+
*/
|
|
17
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
18
|
+
export declare function registerArtifactTools(server: McpServer, workflowsDir: string): void;
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools: artifact_write / artifact_read / artifact_list
|
|
3
|
+
* Read and write project artifacts. Output paths are resolved per artifact
|
|
4
|
+
*
|
|
5
|
+
* artifact_write validates content against artifact schemas and checks review
|
|
6
|
+
* configuration. If validation fails, the write is rejected with specific
|
|
7
|
+
* error details. If review is required, the artifact is submitted for
|
|
8
|
+
* user approval.
|
|
9
|
+
*
|
|
10
|
+
* Sequential mode: When an artifact has `steps` defined in workflow.json,
|
|
11
|
+
* artifact_write requires a `step` parameter. Each step is validated
|
|
12
|
+
* independently, and the final step automatically writes the formal
|
|
13
|
+
* artifact and triggers the review flow.
|
|
14
|
+
*
|
|
15
|
+
* After writing, triggers engine event `artifact_written` to evaluate gates.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { writeArtifact, readArtifact, listArtifacts, writeStepArtifact } from '../core/artifacts.js';
|
|
19
|
+
import { readState } from '../core/state.js';
|
|
20
|
+
import { loadWorkflow } from '../core/plugin.js';
|
|
21
|
+
import { getMergedOverrides, resolveArtifactReview } from '../core/overrides.js';
|
|
22
|
+
import { submitForReview } from '../core/reviews.js';
|
|
23
|
+
import { loadArtifactSchema, validateArtifact, formatValidationErrors } from '../core/schema.js';
|
|
24
|
+
import { getArtifactStepState, getCompletedStepIds, recordStepCompletion, markFinalized } from '../core/steps.js';
|
|
25
|
+
import { resolveActive, isError } from './utils.js';
|
|
26
|
+
import { processWorkflowEvent, loadWorkflowForContext, formatNextAction } from './engine-helpers.js';
|
|
27
|
+
import { getProject, resolveContextDir } from '../core/registry.js';
|
|
28
|
+
/**
|
|
29
|
+
* Check if sequential mode is active for a given artifact definition.
|
|
30
|
+
* Sequential mode is active whenever the artifact has steps defined.
|
|
31
|
+
*/
|
|
32
|
+
function isSequentialActive(artifactDef) {
|
|
33
|
+
return !!artifactDef.steps?.length;
|
|
34
|
+
}
|
|
35
|
+
export function registerArtifactTools(server, workflowsDir) {
|
|
36
|
+
server.tool('artifact_write', 'Write or update a project artifact. For artifacts with sequential steps (PRD, tech-design, task-breakdown), you MUST specify the step parameter. Automatically checks review configuration — if review is required, the artifact is submitted for user approval.', {
|
|
37
|
+
project_name: z.string().describe('Project name'),
|
|
38
|
+
artifact_id: z
|
|
39
|
+
.string()
|
|
40
|
+
.describe('Artifact ID (e.g. prd, user-stories, fsd, prototype, tech-design, task-breakdown, etc.)'),
|
|
41
|
+
content: z
|
|
42
|
+
.string()
|
|
43
|
+
.describe('Artifact content (markdown, HTML, or JSON depending on artifact type and step)'),
|
|
44
|
+
step: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Sequential step ID (required for artifacts with steps). Use project_status to see available steps.'),
|
|
48
|
+
}, async ({ project_name, artifact_id, content, step }) => {
|
|
49
|
+
const ctx = await resolveActive(project_name);
|
|
50
|
+
if (isError(ctx))
|
|
51
|
+
return ctx;
|
|
52
|
+
// Load workflow to get artifact definition (format, review defaults)
|
|
53
|
+
const { wf, state } = await loadWorkflowForContext(workflowsDir, project_name, ctx);
|
|
54
|
+
const artifactDef = wf.artifactDefinitions[artifact_id];
|
|
55
|
+
const isHtml = artifactDef?.format === 'html';
|
|
56
|
+
// Guard: artifact_id must be defined in workflow
|
|
57
|
+
if (!artifactDef) {
|
|
58
|
+
const validIds = Object.keys(wf.artifactDefinitions)
|
|
59
|
+
.filter((id) => !wf.artifactDefinitions[id].unmanaged)
|
|
60
|
+
.join(', ');
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{
|
|
64
|
+
type: 'text',
|
|
65
|
+
text: `Artifact "${artifact_id}" 未在工作流中定义。可用的 artifact 类型: ${validIds}`,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
isError: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Guard: reject unmanaged artifact types (should be produced outside artifact_write)
|
|
72
|
+
if (artifactDef.unmanaged) {
|
|
73
|
+
return {
|
|
74
|
+
content: [
|
|
75
|
+
{
|
|
76
|
+
type: 'text',
|
|
77
|
+
text: `Artifact "${artifact_id}" 是非托管(unmanaged)产出类型,不应通过 artifact_write 写入。`,
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
isError: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Guard: empty content
|
|
84
|
+
if (!content.trim()) {
|
|
85
|
+
return {
|
|
86
|
+
content: [
|
|
87
|
+
{
|
|
88
|
+
type: 'text',
|
|
89
|
+
text: 'Artifact 内容为空,请提供实际内容后重新提交。',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
isError: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// ─── Sequential Mode ───
|
|
96
|
+
if (isSequentialActive(artifactDef)) {
|
|
97
|
+
return handleSequentialWrite(workflowsDir, state.workflow, project_name, ctx, artifact_id, content, step, artifactDef);
|
|
98
|
+
}
|
|
99
|
+
// ─── Normal Mode (no steps) ───
|
|
100
|
+
// Schema validation — reject write if content doesn't meet requirements
|
|
101
|
+
const schema = await loadArtifactSchema(workflowsDir, state.workflow, artifact_id);
|
|
102
|
+
if (schema) {
|
|
103
|
+
const result = validateArtifact(content, schema, isHtml);
|
|
104
|
+
if (!result.valid) {
|
|
105
|
+
return {
|
|
106
|
+
content: [
|
|
107
|
+
{
|
|
108
|
+
type: 'text',
|
|
109
|
+
text: formatValidationErrors(result.errors),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
isError: true,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Write the artifact with correct extension
|
|
117
|
+
const writeIoCtx = {
|
|
118
|
+
contextDir: ctx.dir,
|
|
119
|
+
projectDir: ctx.entry.dir,
|
|
120
|
+
contextLabel: ctx.activeContext,
|
|
121
|
+
};
|
|
122
|
+
const filePath = await writeArtifact(artifact_id, content, writeIoCtx, artifactDef);
|
|
123
|
+
// Trigger engine event: artifact_written
|
|
124
|
+
const engineResult = await processWorkflowEvent(workflowsDir, project_name, ctx, {
|
|
125
|
+
type: 'artifact_written',
|
|
126
|
+
artifactId: artifact_id,
|
|
127
|
+
});
|
|
128
|
+
// Check if review is required
|
|
129
|
+
const overrides = await getMergedOverrides(project_name);
|
|
130
|
+
const needsReview = resolveArtifactReview(artifact_id, artifactDef, overrides);
|
|
131
|
+
if (needsReview) {
|
|
132
|
+
await submitForReview(project_name, ctx.number, artifact_id, ctx.dir);
|
|
133
|
+
const artifactName = artifactDef.name ?? artifact_id;
|
|
134
|
+
return {
|
|
135
|
+
content: [
|
|
136
|
+
{
|
|
137
|
+
type: 'text',
|
|
138
|
+
text: [
|
|
139
|
+
`Artifact "${artifact_id}" (${artifactName}) written to ${filePath}`,
|
|
140
|
+
``,
|
|
141
|
+
`** REVIEW REQUIRED **`,
|
|
142
|
+
`This artifact requires user approval before the workflow can proceed.`,
|
|
143
|
+
`Please present the artifact content to the user and ask for their confirmation.`,
|
|
144
|
+
`After user approval, call artifact_approve with project_name="${project_name}" and artifact_id="${artifact_id}".`,
|
|
145
|
+
`If the user requests changes, revise the artifact and call artifact_write again.`,
|
|
146
|
+
formatNextAction(engineResult.nextAction),
|
|
147
|
+
].join('\n'),
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
content: [
|
|
154
|
+
{
|
|
155
|
+
type: 'text',
|
|
156
|
+
text: `Artifact "${artifact_id}" written to ${filePath}` +
|
|
157
|
+
formatNextAction(engineResult.nextAction),
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
server.tool('artifact_read', 'Read a project artifact. By default reads from the active context. Use the optional `context` parameter (e.g. "iter-1", "patch-2") to read from a different context.', {
|
|
163
|
+
project_name: z.string().describe('Project name'),
|
|
164
|
+
artifact_id: z.string().describe('Artifact ID to read'),
|
|
165
|
+
context: z
|
|
166
|
+
.string()
|
|
167
|
+
.optional()
|
|
168
|
+
.describe('Context to read from (e.g. "iter-1", "patch-2"). Defaults to active context.'),
|
|
169
|
+
}, async ({ project_name, artifact_id, context }) => {
|
|
170
|
+
try {
|
|
171
|
+
let contextNumber;
|
|
172
|
+
let contextDir;
|
|
173
|
+
let contextLabel;
|
|
174
|
+
let projectDir;
|
|
175
|
+
if (context) {
|
|
176
|
+
// Cross-context read: resolve the specified context
|
|
177
|
+
const entry = await getProject(project_name);
|
|
178
|
+
if (!entry) {
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: 'text', text: `项目 "${project_name}" 未注册。` }],
|
|
181
|
+
isError: true,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const resolved = resolveContextDir(project_name, context);
|
|
185
|
+
if (!resolved) {
|
|
186
|
+
return {
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
189
|
+
type: 'text',
|
|
190
|
+
text: `无法解析上下文 "${context}"。格式示例: iter-1, patch-2`,
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
isError: true,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
contextNumber = resolved.number;
|
|
197
|
+
contextDir = resolved.dir;
|
|
198
|
+
contextLabel = context;
|
|
199
|
+
projectDir = entry.dir;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// Default: active context
|
|
203
|
+
const ctx = await resolveActive(project_name);
|
|
204
|
+
if (isError(ctx))
|
|
205
|
+
return ctx;
|
|
206
|
+
contextNumber = ctx.number;
|
|
207
|
+
contextDir = ctx.dir;
|
|
208
|
+
contextLabel = ctx.activeContext;
|
|
209
|
+
projectDir = ctx.entry.dir;
|
|
210
|
+
}
|
|
211
|
+
// Load workflow to get artifact definition for output path resolution
|
|
212
|
+
const state = await readState(project_name, contextNumber, contextDir);
|
|
213
|
+
const wf = await loadWorkflow(workflowsDir, state.workflow);
|
|
214
|
+
const artifactDef = wf.artifactDefinitions[artifact_id];
|
|
215
|
+
const ioCtx = { contextDir, projectDir, contextLabel };
|
|
216
|
+
const artifactContent = await readArtifact(artifact_id, ioCtx, artifactDef);
|
|
217
|
+
return {
|
|
218
|
+
content: [
|
|
219
|
+
{
|
|
220
|
+
type: 'text',
|
|
221
|
+
text: artifactContent,
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return {
|
|
228
|
+
content: [
|
|
229
|
+
{
|
|
230
|
+
type: 'text',
|
|
231
|
+
text: `Artifact "${artifact_id}" not found. Use artifact_list to see available artifacts.`,
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
isError: true,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
server.tool('artifact_list', 'List all project artifacts. By default lists from the active context. Use the optional `context` parameter (e.g. "iter-1", "patch-2") to list from a different context.', {
|
|
239
|
+
project_name: z.string().describe('Project name'),
|
|
240
|
+
context: z
|
|
241
|
+
.string()
|
|
242
|
+
.optional()
|
|
243
|
+
.describe('Context to list from (e.g. "iter-1", "patch-2"). Defaults to active context.'),
|
|
244
|
+
}, async ({ project_name, context }) => {
|
|
245
|
+
let contextNumber;
|
|
246
|
+
let contextDir;
|
|
247
|
+
let contextLabel;
|
|
248
|
+
let projectDir;
|
|
249
|
+
if (context) {
|
|
250
|
+
const entry = await getProject(project_name);
|
|
251
|
+
if (!entry) {
|
|
252
|
+
return {
|
|
253
|
+
content: [{ type: 'text', text: `项目 "${project_name}" 未注册。` }],
|
|
254
|
+
isError: true,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const resolved = resolveContextDir(project_name, context);
|
|
258
|
+
if (!resolved) {
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{ type: 'text', text: `无法解析上下文 "${context}"。格式示例: iter-1, patch-2` },
|
|
262
|
+
],
|
|
263
|
+
isError: true,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
contextNumber = resolved.number;
|
|
267
|
+
contextDir = resolved.dir;
|
|
268
|
+
contextLabel = context;
|
|
269
|
+
projectDir = entry.dir;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const ctx = await resolveActive(project_name);
|
|
273
|
+
if (isError(ctx))
|
|
274
|
+
return ctx;
|
|
275
|
+
contextNumber = ctx.number;
|
|
276
|
+
contextDir = ctx.dir;
|
|
277
|
+
contextLabel = ctx.activeContext;
|
|
278
|
+
projectDir = ctx.entry.dir;
|
|
279
|
+
}
|
|
280
|
+
// Load workflow for artifact definitions and output path resolution
|
|
281
|
+
const state = await readState(project_name, contextNumber, contextDir);
|
|
282
|
+
const wf = await loadWorkflow(workflowsDir, state.workflow);
|
|
283
|
+
const ioCtx = { contextDir, projectDir, contextLabel };
|
|
284
|
+
const artifacts = await listArtifacts(ioCtx, wf.artifactDefinitions);
|
|
285
|
+
return {
|
|
286
|
+
content: [
|
|
287
|
+
{
|
|
288
|
+
type: 'text',
|
|
289
|
+
text: artifacts.length > 0
|
|
290
|
+
? `Artifacts (${contextLabel}):\n${artifacts.map((d) => `- ${d}`).join('\n')}`
|
|
291
|
+
: `No artifacts found for ${contextLabel}.`,
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
async function handleSequentialWrite(workflowsDir, workflowName, projectName, ctx, artifactId, content, step, artifactDef) {
|
|
298
|
+
const steps = artifactDef.steps;
|
|
299
|
+
const stepIds = steps.map((s) => s.id);
|
|
300
|
+
const stepNames = steps.map((s) => `${s.id} (${s.name})`).join(', ');
|
|
301
|
+
// Guard: step parameter is required in sequential mode
|
|
302
|
+
if (!step) {
|
|
303
|
+
return {
|
|
304
|
+
content: [
|
|
305
|
+
{
|
|
306
|
+
type: 'text',
|
|
307
|
+
text: [
|
|
308
|
+
`Artifact "${artifactId}" 需要分步写入。`,
|
|
309
|
+
`请指定 step 参数。可用的步骤: ${stepNames}`,
|
|
310
|
+
``,
|
|
311
|
+
`步骤说明:`,
|
|
312
|
+
...steps.map((s, i) => ` ${i + 1}. ${s.id} — ${s.description}`),
|
|
313
|
+
].join('\n'),
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
isError: true,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// Guard: step must be valid
|
|
320
|
+
const stepDef = steps.find((s) => s.id === step);
|
|
321
|
+
if (!stepDef) {
|
|
322
|
+
return {
|
|
323
|
+
content: [
|
|
324
|
+
{
|
|
325
|
+
type: 'text',
|
|
326
|
+
text: `未知的步骤 "${step}"。可用的步骤: ${stepNames}`,
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
isError: true,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
const stepIndex = stepIds.indexOf(step);
|
|
333
|
+
const stepState = await getArtifactStepState(projectName, ctx.number, artifactId, ctx.dir);
|
|
334
|
+
const completedIds = getCompletedStepIds(stepState);
|
|
335
|
+
// Guard: prerequisite steps must be completed (hard enforcement)
|
|
336
|
+
for (let i = 0; i < stepIndex; i++) {
|
|
337
|
+
if (!completedIds.has(stepIds[i])) {
|
|
338
|
+
const missingStep = steps[i];
|
|
339
|
+
return {
|
|
340
|
+
content: [
|
|
341
|
+
{
|
|
342
|
+
type: 'text',
|
|
343
|
+
text: `无法写入步骤 "${step}":前置步骤 "${missingStep.id}" (${missingStep.name}) 尚未完成。请先完成该步骤。`,
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
isError: true,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Step schema validation
|
|
351
|
+
const isJson = stepDef.format === 'json';
|
|
352
|
+
const stepSchemaId = `${artifactId}.${step}`;
|
|
353
|
+
const stepSchema = await loadArtifactSchema(workflowsDir, workflowName, stepSchemaId);
|
|
354
|
+
if (stepSchema) {
|
|
355
|
+
const result = validateArtifact(content, stepSchema, false, isJson);
|
|
356
|
+
if (!result.valid) {
|
|
357
|
+
return {
|
|
358
|
+
content: [
|
|
359
|
+
{
|
|
360
|
+
type: 'text',
|
|
361
|
+
text: formatValidationErrors(result.errors),
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
isError: true,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Write the step artifact
|
|
369
|
+
const ioCtx = {
|
|
370
|
+
contextDir: ctx.dir,
|
|
371
|
+
projectDir: ctx.entry.dir,
|
|
372
|
+
contextLabel: ctx.activeContext,
|
|
373
|
+
};
|
|
374
|
+
const artifactPath = await writeStepArtifact(artifactId, step, content, stepDef.format, ioCtx, artifactDef);
|
|
375
|
+
// Record step completion (handles rollback if overwriting)
|
|
376
|
+
await recordStepCompletion(projectName, ctx.number, artifactId, step, artifactPath, stepIds, ctx.dir);
|
|
377
|
+
const isLastStep = stepIndex === steps.length - 1;
|
|
378
|
+
if (isLastStep) {
|
|
379
|
+
// Auto-merge: validate against final artifact schema, write formal artifact, trigger review
|
|
380
|
+
return handleFinalStep(workflowsDir, workflowName, projectName, ctx, artifactId, content, artifactDef, stepDef, ioCtx);
|
|
381
|
+
}
|
|
382
|
+
// Not the last step — return progress info
|
|
383
|
+
const nextStep = steps[stepIndex + 1];
|
|
384
|
+
return {
|
|
385
|
+
content: [
|
|
386
|
+
{
|
|
387
|
+
type: 'text',
|
|
388
|
+
text: [
|
|
389
|
+
`步骤 "${step}" (${stepDef.name}) 完成,产物已写入 ${artifactPath}`,
|
|
390
|
+
``,
|
|
391
|
+
`下一步: ${nextStep.id} — ${nextStep.description}`,
|
|
392
|
+
`请调用 artifact_write(project_name="${projectName}", artifact_id="${artifactId}", step="${nextStep.id}", content=...)`,
|
|
393
|
+
].join('\n'),
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
async function handleFinalStep(workflowsDir, workflowName, projectName, ctx, artifactId, content, artifactDef, stepDef, ioCtx) {
|
|
399
|
+
const isHtml = artifactDef.format === 'html';
|
|
400
|
+
// Validate against the final artifact schema (e.g. prd.json)
|
|
401
|
+
const finalSchema = await loadArtifactSchema(workflowsDir, workflowName, artifactId);
|
|
402
|
+
if (finalSchema) {
|
|
403
|
+
const isJson = artifactDef.format === 'json';
|
|
404
|
+
const result = validateArtifact(content, finalSchema, isHtml, isJson);
|
|
405
|
+
if (!result.valid) {
|
|
406
|
+
return {
|
|
407
|
+
content: [
|
|
408
|
+
{
|
|
409
|
+
type: 'text',
|
|
410
|
+
text: [
|
|
411
|
+
'最终 artifact 校验失败:',
|
|
412
|
+
formatValidationErrors(result.errors),
|
|
413
|
+
'',
|
|
414
|
+
`请修正后重新提交步骤 "${stepDef.id}"。`,
|
|
415
|
+
].join('\n'),
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
isError: true,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
// Write the formal artifact
|
|
423
|
+
const filePath = await writeArtifact(artifactId, content, ioCtx, artifactDef);
|
|
424
|
+
// Mark as finalized
|
|
425
|
+
await markFinalized(projectName, ctx.number, artifactId, ctx.dir);
|
|
426
|
+
// Trigger engine event: artifact_written
|
|
427
|
+
const engineResult = await processWorkflowEvent(workflowsDir, projectName, ctx, {
|
|
428
|
+
type: 'artifact_written',
|
|
429
|
+
artifactId,
|
|
430
|
+
});
|
|
431
|
+
// Check if review is required
|
|
432
|
+
const overrides = await getMergedOverrides(projectName);
|
|
433
|
+
const needsReview = resolveArtifactReview(artifactId, artifactDef, overrides);
|
|
434
|
+
if (needsReview) {
|
|
435
|
+
await submitForReview(projectName, ctx.number, artifactId, ctx.dir);
|
|
436
|
+
const artifactName = artifactDef.name ?? artifactId;
|
|
437
|
+
return {
|
|
438
|
+
content: [
|
|
439
|
+
{
|
|
440
|
+
type: 'text',
|
|
441
|
+
text: [
|
|
442
|
+
`所有步骤完成!Artifact "${artifactId}" (${artifactName}) 已写入 ${filePath}`,
|
|
443
|
+
``,
|
|
444
|
+
`** REVIEW REQUIRED **`,
|
|
445
|
+
`This artifact requires user approval before the workflow can proceed.`,
|
|
446
|
+
`Please present the artifact content to the user and ask for their confirmation.`,
|
|
447
|
+
`After user approval, call artifact_approve with project_name="${projectName}" and artifact_id="${artifactId}".`,
|
|
448
|
+
`If the user requests changes, revise the artifact and call artifact_write again with the appropriate step.`,
|
|
449
|
+
formatNextAction(engineResult.nextAction),
|
|
450
|
+
].join('\n'),
|
|
451
|
+
},
|
|
452
|
+
],
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
content: [
|
|
457
|
+
{
|
|
458
|
+
type: 'text',
|
|
459
|
+
text: `所有步骤完成!Artifact "${artifactId}" 已写入 ${filePath}` +
|
|
460
|
+
formatNextAction(engineResult.nextAction),
|
|
461
|
+
},
|
|
462
|
+
],
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
//# sourceMappingURL=artifact-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-tools.js","sourceRoot":"","sources":["../../src/tools/artifact-tools.ts"],"names":[],"mappings":"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"}
|