agentweaver 0.1.14 → 0.1.15

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.
@@ -0,0 +1,261 @@
1
+ {
2
+ "kind": "plan-revise-flow",
3
+ "version": 1,
4
+ "description": "Consumes a design-review verdict artifact and the latest planning artifacts, then produces revised design, implementation plan, and QA artifacts at the next iteration number without modifying originals.",
5
+ "phases": [
6
+ {
7
+ "id": "phase_1_load_contract",
8
+ "steps": [
9
+ {
10
+ "id": "validate_review_markdown",
11
+ "node": "file-check",
12
+ "params": {
13
+ "path": { "ref": "params.reviewFile" },
14
+ "panelTitle": { "const": "Design Review Verdict Markdown" },
15
+ "foundMessage": { "const": "Design review verdict markdown found." },
16
+ "tone": { "const": "cyan" }
17
+ },
18
+ "expect": [
19
+ {
20
+ "kind": "require-file",
21
+ "path": { "ref": "params.reviewFile" },
22
+ "message": "Plan-revise contract is missing the required design-review verdict markdown."
23
+ }
24
+ ]
25
+ },
26
+ {
27
+ "id": "validate_review_json",
28
+ "node": "file-check",
29
+ "params": {
30
+ "path": { "ref": "params.reviewJsonFile" },
31
+ "panelTitle": { "const": "Design Review Verdict JSON" },
32
+ "foundMessage": { "const": "Design review verdict JSON found." },
33
+ "tone": { "const": "cyan" }
34
+ },
35
+ "expect": [
36
+ {
37
+ "kind": "require-file",
38
+ "path": { "ref": "params.reviewJsonFile" },
39
+ "message": "Plan-revise contract is missing the required design-review verdict JSON."
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ "id": "validate_source_design_markdown",
45
+ "node": "file-check",
46
+ "params": {
47
+ "path": { "ref": "params.designFile" },
48
+ "panelTitle": { "const": "Source Design Markdown" },
49
+ "foundMessage": { "const": "Source design markdown artifact found." },
50
+ "tone": { "const": "cyan" }
51
+ },
52
+ "expect": [
53
+ {
54
+ "kind": "require-file",
55
+ "path": { "ref": "params.designFile" },
56
+ "message": "Plan-revise contract is missing the required source design markdown."
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ "id": "validate_source_design_json",
62
+ "node": "file-check",
63
+ "params": {
64
+ "path": { "ref": "params.designJsonFile" },
65
+ "panelTitle": { "const": "Source Design JSON" },
66
+ "foundMessage": { "const": "Source design structured artifact found." },
67
+ "tone": { "const": "cyan" }
68
+ },
69
+ "expect": [
70
+ {
71
+ "kind": "require-file",
72
+ "path": { "ref": "params.designJsonFile" },
73
+ "message": "Plan-revise contract is missing the required source design JSON."
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "id": "validate_source_plan_markdown",
79
+ "node": "file-check",
80
+ "params": {
81
+ "path": { "ref": "params.planFile" },
82
+ "panelTitle": { "const": "Source Plan Markdown" },
83
+ "foundMessage": { "const": "Source implementation plan markdown found." },
84
+ "tone": { "const": "cyan" }
85
+ },
86
+ "expect": [
87
+ {
88
+ "kind": "require-file",
89
+ "path": { "ref": "params.planFile" },
90
+ "message": "Plan-revise contract is missing the required source plan markdown."
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "id": "validate_source_plan_json",
96
+ "node": "file-check",
97
+ "params": {
98
+ "path": { "ref": "params.planJsonFile" },
99
+ "panelTitle": { "const": "Source Plan JSON" },
100
+ "foundMessage": { "const": "Source implementation plan structured artifact found." },
101
+ "tone": { "const": "cyan" }
102
+ },
103
+ "expect": [
104
+ {
105
+ "kind": "require-file",
106
+ "path": { "ref": "params.planJsonFile" },
107
+ "message": "Plan-revise contract is missing the required source plan JSON."
108
+ }
109
+ ]
110
+ },
111
+ {
112
+ "id": "validate_source_qa_markdown",
113
+ "when": { "ref": "params.hasQaArtifacts" },
114
+ "node": "file-check",
115
+ "params": {
116
+ "path": { "ref": "params.qaFilePath" },
117
+ "panelTitle": { "const": "Source QA Markdown" },
118
+ "foundMessage": { "const": "Source QA markdown artifact found." },
119
+ "tone": { "const": "cyan" }
120
+ },
121
+ "expect": [
122
+ {
123
+ "kind": "require-file",
124
+ "path": { "ref": "params.qaFilePath" },
125
+ "message": "Plan-revise contract expected a source QA markdown artifact, but the file is missing."
126
+ }
127
+ ]
128
+ },
129
+ {
130
+ "id": "validate_source_qa_json",
131
+ "when": { "ref": "params.hasQaArtifacts" },
132
+ "node": "file-check",
133
+ "params": {
134
+ "path": { "ref": "params.qaJsonFilePath" },
135
+ "panelTitle": { "const": "Source QA JSON" },
136
+ "foundMessage": { "const": "Source QA structured artifact found." },
137
+ "tone": { "const": "cyan" }
138
+ },
139
+ "expect": [
140
+ {
141
+ "kind": "require-file",
142
+ "path": { "ref": "params.qaJsonFilePath" },
143
+ "message": "Plan-revise contract expected a source QA JSON artifact, but the file is missing."
144
+ }
145
+ ]
146
+ }
147
+ ]
148
+ },
149
+ {
150
+ "id": "phase_2_revise",
151
+ "steps": [
152
+ {
153
+ "id": "run_plan_revise",
154
+ "node": "llm-prompt",
155
+ "prompt": {
156
+ "templateRef": "plan-revise",
157
+ "vars": {
158
+ "review_file": { "ref": "params.reviewFile" },
159
+ "review_json_file": { "ref": "params.reviewJsonFile" },
160
+ "design_file": { "ref": "params.designFile" },
161
+ "design_json_file": { "ref": "params.designJsonFile" },
162
+ "plan_file": { "ref": "params.planFile" },
163
+ "plan_json_file": { "ref": "params.planJsonFile" },
164
+ "qa_file": { "ref": "params.qaFile" },
165
+ "qa_json_file": { "ref": "params.qaJsonFile" },
166
+ "jira_task_file": { "ref": "params.jiraTaskFile" },
167
+ "jira_attachments_manifest_file": { "ref": "params.jiraAttachmentsManifestFile" },
168
+ "jira_attachments_context_file": { "ref": "params.jiraAttachmentsContextFile" },
169
+ "planning_answers_json_file": { "ref": "params.planningAnswersJsonFile" },
170
+ "revised_design_file": { "ref": "params.revisedDesignFile" },
171
+ "revised_design_json_file": { "ref": "params.revisedDesignJsonFile" },
172
+ "revised_plan_file": { "ref": "params.revisedPlanFile" },
173
+ "revised_plan_json_file": { "ref": "params.revisedPlanJsonFile" },
174
+ "revised_qa_file": { "ref": "params.revisedQaFile" },
175
+ "revised_qa_json_file": { "ref": "params.revisedQaJsonFile" }
176
+ },
177
+ "extraPrompt": { "ref": "params.extraPrompt" },
178
+ "format": "task-prompt"
179
+ },
180
+ "params": {
181
+ "labelText": {
182
+ "template": "Revising planning artifacts (iteration {outputIteration})",
183
+ "vars": {
184
+ "outputIteration": { "ref": "params.outputIteration" }
185
+ }
186
+ },
187
+ "model": { "ref": "params.llmModel" },
188
+ "executor": { "ref": "params.llmExecutor" },
189
+ "requiredArtifacts": {
190
+ "list": [
191
+ { "ref": "params.revisedDesignFile" },
192
+ { "ref": "params.revisedPlanFile" },
193
+ { "ref": "params.revisedQaFile" }
194
+ ]
195
+ }
196
+ },
197
+ "expect": [
198
+ {
199
+ "kind": "require-artifacts",
200
+ "when": { "not": { "ref": "context.dryRun" } },
201
+ "paths": {
202
+ "list": [
203
+ { "ref": "params.revisedDesignFile" },
204
+ { "ref": "params.revisedPlanFile" },
205
+ { "ref": "params.revisedQaFile" }
206
+ ]
207
+ },
208
+ "message": "Plan-revise did not produce the required revised markdown artifacts."
209
+ },
210
+ {
211
+ "kind": "require-structured-artifacts",
212
+ "when": { "not": { "ref": "context.dryRun" } },
213
+ "items": [
214
+ {
215
+ "path": { "ref": "params.revisedDesignJsonFile" },
216
+ "schemaId": "implementation-design/v1"
217
+ },
218
+ {
219
+ "path": { "ref": "params.revisedPlanJsonFile" },
220
+ "schemaId": "implementation-plan/v1"
221
+ },
222
+ {
223
+ "path": { "ref": "params.revisedQaJsonFile" },
224
+ "schemaId": "qa-plan/v1"
225
+ }
226
+ ],
227
+ "message": "Plan-revise produced invalid structured artifacts."
228
+ }
229
+ ]
230
+ }
231
+ ]
232
+ },
233
+ {
234
+ "id": "phase_3_finalize",
235
+ "steps": [
236
+ {
237
+ "id": "check_ready_to_merge",
238
+ "node": "file-check",
239
+ "params": {
240
+ "path": {
241
+ "artifact": {
242
+ "kind": "ready-to-merge-file",
243
+ "taskKey": { "ref": "params.taskKey" }
244
+ }
245
+ },
246
+ "panelTitle": { "const": "Ready To Merge" },
247
+ "foundMessage": { "const": "Plan-revise completed and all blocking findings addressed. File ready-to-merge.md has been created." },
248
+ "tone": { "const": "green" }
249
+ }
250
+ },
251
+ {
252
+ "id": "notify_revise_complete",
253
+ "node": "telegram-notify",
254
+ "params": {
255
+ "message": { "const": "Plan-revise phase complete" }
256
+ }
257
+ }
258
+ ]
259
+ }
260
+ ]
261
+ }
@@ -235,10 +235,37 @@
235
235
  }
236
236
  },
237
237
  "message": "Task describe mode did not produce the Jira description artifact."
238
+ }
239
+ ]
240
+ },
241
+ {
242
+ "id": "ensure_task_describe_json_from_jira_markdown",
243
+ "node": "ensure-summary-json",
244
+ "when": {
245
+ "all": [
246
+ { "ref": "steps.task_describe.collect_task_source.value.values.jira_ref" },
247
+ { "not": { "ref": "context.dryRun" } }
248
+ ]
249
+ },
250
+ "params": {
251
+ "markdownFile": {
252
+ "artifact": {
253
+ "kind": "jira-description-file",
254
+ "taskKey": { "ref": "params.taskKey" },
255
+ "iteration": { "ref": "params.iteration" }
256
+ }
238
257
  },
258
+ "outputFile": {
259
+ "artifact": {
260
+ "kind": "jira-description-json-file",
261
+ "taskKey": { "ref": "params.taskKey" },
262
+ "iteration": { "ref": "params.iteration" }
263
+ }
264
+ }
265
+ },
266
+ "expect": [
239
267
  {
240
268
  "kind": "require-structured-artifacts",
241
- "when": { "not": { "ref": "context.dryRun" } },
242
269
  "items": [
243
270
  {
244
271
  "path": {
@@ -330,10 +357,41 @@
330
357
  }
331
358
  },
332
359
  "message": "Task describe mode did not produce the Jira description artifact."
360
+ }
361
+ ]
362
+ },
363
+ {
364
+ "id": "ensure_task_describe_json_from_input_markdown",
365
+ "node": "ensure-summary-json",
366
+ "when": {
367
+ "all": [
368
+ {
369
+ "not": {
370
+ "ref": "steps.task_describe.collect_task_source.value.values.jira_ref"
371
+ }
372
+ },
373
+ { "not": { "ref": "context.dryRun" } }
374
+ ]
375
+ },
376
+ "params": {
377
+ "markdownFile": {
378
+ "artifact": {
379
+ "kind": "jira-description-file",
380
+ "taskKey": { "ref": "params.taskKey" },
381
+ "iteration": { "ref": "params.iteration" }
382
+ }
333
383
  },
384
+ "outputFile": {
385
+ "artifact": {
386
+ "kind": "jira-description-json-file",
387
+ "taskKey": { "ref": "params.taskKey" },
388
+ "iteration": { "ref": "params.iteration" }
389
+ }
390
+ }
391
+ },
392
+ "expect": [
334
393
  {
335
394
  "kind": "require-structured-artifacts",
336
- "when": { "not": { "ref": "context.dryRun" } },
337
395
  "items": [
338
396
  {
339
397
  "path": {
@@ -3,6 +3,7 @@ import { buildReviewFixPromptNode } from "./nodes/build-review-fix-prompt-node.j
3
3
  import { codexPromptNode } from "./nodes/codex-prompt-node.js";
4
4
  import { commandCheckNode } from "./nodes/command-check-node.js";
5
5
  import { commitMessageFormNode } from "./nodes/commit-message-form-node.js";
6
+ import { ensureSummaryJsonNode } from "./nodes/ensure-summary-json-node.js";
6
7
  import { fetchGitLabDiffNode } from "./nodes/fetch-gitlab-diff-node.js";
7
8
  import { fetchGitLabReviewNode } from "./nodes/fetch-gitlab-review-node.js";
8
9
  import { fileCheckNode } from "./nodes/file-check-node.js";
@@ -32,6 +33,7 @@ const builtInNodes = {
32
33
  "codex-prompt": codexPromptNode,
33
34
  "command-check": commandCheckNode,
34
35
  "commit-message-form": commitMessageFormNode,
36
+ "ensure-summary-json": ensureSummaryJsonNode,
35
37
  "fetch-gitlab-diff": fetchGitLabDiffNode,
36
38
  "fetch-gitlab-review": fetchGitLabReviewNode,
37
39
  "file-check": fileCheckNode,
@@ -90,6 +92,12 @@ const builtInNodeMetadata = {
90
92
  prompt: "forbidden",
91
93
  requiredParams: ["commitMessageFile", "formId", "title", "outputFile"],
92
94
  },
95
+ "ensure-summary-json": {
96
+ kind: "ensure-summary-json",
97
+ version: 1,
98
+ prompt: "forbidden",
99
+ requiredParams: ["markdownFile", "outputFile"],
100
+ },
93
101
  "fetch-gitlab-diff": {
94
102
  kind: "fetch-gitlab-diff",
95
103
  version: 1,
@@ -0,0 +1,59 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { TaskRunnerError } from "../../errors.js";
4
+ function toSummaryText(markdown) {
5
+ return markdown
6
+ .replace(/\r\n/g, "\n")
7
+ .replace(/^#{1,6}\s+/gm, "")
8
+ .replace(/^\s*[-*+]\s+/gm, "- ")
9
+ .replace(/`([^`]*)`/g, "$1")
10
+ .replace(/\*\*(.*?)\*\*/g, "$1")
11
+ .replace(/__(.*?)__/g, "$1")
12
+ .replace(/\n{3,}/g, "\n\n")
13
+ .trim();
14
+ }
15
+ function hasValidSummaryArtifact(outputFile) {
16
+ if (!existsSync(outputFile)) {
17
+ return false;
18
+ }
19
+ try {
20
+ const parsed = JSON.parse(readFileSync(outputFile, "utf8"));
21
+ return typeof parsed.summary === "string" && parsed.summary.trim().length > 0;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ export const ensureSummaryJsonNode = {
28
+ kind: "ensure-summary-json",
29
+ version: 1,
30
+ async run(_context, params) {
31
+ if (hasValidSummaryArtifact(params.outputFile)) {
32
+ return {
33
+ value: {
34
+ outputFile: params.outputFile,
35
+ created: false,
36
+ repaired: false,
37
+ },
38
+ };
39
+ }
40
+ if (!existsSync(params.markdownFile)) {
41
+ throw new TaskRunnerError(`Cannot create summary JSON ${params.outputFile}: markdown source ${params.markdownFile} was not found.`);
42
+ }
43
+ const summary = toSummaryText(readFileSync(params.markdownFile, "utf8"));
44
+ if (!summary) {
45
+ throw new TaskRunnerError(`Cannot create summary JSON ${params.outputFile}: markdown source ${params.markdownFile} is empty.`);
46
+ }
47
+ mkdirSync(path.dirname(params.outputFile), { recursive: true });
48
+ const repaired = existsSync(params.outputFile);
49
+ writeFileSync(params.outputFile, `${JSON.stringify({ summary }, null, 2)}\n`, "utf8");
50
+ return {
51
+ value: {
52
+ outputFile: params.outputFile,
53
+ created: !repaired,
54
+ repaired,
55
+ },
56
+ outputs: [{ kind: "artifact", path: params.outputFile, required: true }],
57
+ };
58
+ },
59
+ };
@@ -1,8 +1,9 @@
1
- import { BUG_ANALYZE_PROMPT_TEMPLATE, COMMIT_MESSAGE_PROMPT_TEMPLATE, GITLAB_DIFF_REVIEW_PROMPT_TEMPLATE, GITLAB_REVIEW_PROMPT_TEMPLATE, BUG_FIX_PROMPT_TEMPLATE, IMPLEMENT_PROMPT_TEMPLATE, JIRA_DESCRIPTION_PROMPT_TEMPLATE, MR_DESCRIPTION_PROMPT_TEMPLATE, PLAN_QUESTIONS_PROMPT_TEMPLATE, PLAN_PROMPT_TEMPLATE, REVIEW_FIX_PROMPT_TEMPLATE, REVIEW_PROJECT_PROMPT_TEMPLATE, REVIEW_PROMPT_TEMPLATE, REVIEW_SUMMARY_PROMPT_TEMPLATE, RUN_GO_LINTER_LOOP_FIX_PROMPT_TEMPLATE, RUN_GO_TESTS_LOOP_FIX_PROMPT_TEMPLATE, TASK_SUMMARY_PROMPT_TEMPLATE, } from "../prompts.js";
1
+ import { BUG_ANALYZE_PROMPT_TEMPLATE, COMMIT_MESSAGE_PROMPT_TEMPLATE, DESIGN_REVIEW_PROMPT_TEMPLATE, GITLAB_DIFF_REVIEW_PROMPT_TEMPLATE, GITLAB_REVIEW_PROMPT_TEMPLATE, BUG_FIX_PROMPT_TEMPLATE, IMPLEMENT_PROMPT_TEMPLATE, JIRA_DESCRIPTION_PROMPT_TEMPLATE, MR_DESCRIPTION_PROMPT_TEMPLATE, PLAN_PROMPT_TEMPLATE, PLAN_QUESTIONS_PROMPT_TEMPLATE, PLAN_REVISE_PROMPT_TEMPLATE, REVIEW_FIX_PROMPT_TEMPLATE, REVIEW_PROJECT_PROMPT_TEMPLATE, REVIEW_PROMPT_TEMPLATE, REVIEW_SUMMARY_PROMPT_TEMPLATE, RUN_GO_LINTER_LOOP_FIX_PROMPT_TEMPLATE, RUN_GO_TESTS_LOOP_FIX_PROMPT_TEMPLATE, TASK_SUMMARY_PROMPT_TEMPLATE, } from "../prompts.js";
2
2
  const promptTemplates = {
3
3
  "bug-analyze": BUG_ANALYZE_PROMPT_TEMPLATE,
4
4
  "bug-fix": BUG_FIX_PROMPT_TEMPLATE,
5
5
  "commit-message": COMMIT_MESSAGE_PROMPT_TEMPLATE,
6
+ "design-review": DESIGN_REVIEW_PROMPT_TEMPLATE,
6
7
  "gitlab-diff-review": GITLAB_DIFF_REVIEW_PROMPT_TEMPLATE,
7
8
  "gitlab-review": GITLAB_REVIEW_PROMPT_TEMPLATE,
8
9
  implement: IMPLEMENT_PROMPT_TEMPLATE,
@@ -10,6 +11,7 @@ const promptTemplates = {
10
11
  "mr-description": MR_DESCRIPTION_PROMPT_TEMPLATE,
11
12
  "plan-questions": PLAN_QUESTIONS_PROMPT_TEMPLATE,
12
13
  plan: PLAN_PROMPT_TEMPLATE,
14
+ "plan-revise": PLAN_REVISE_PROMPT_TEMPLATE,
13
15
  review: REVIEW_PROMPT_TEMPLATE,
14
16
  "review-project": REVIEW_PROJECT_PROMPT_TEMPLATE,
15
17
  "review-fix": REVIEW_FIX_PROMPT_TEMPLATE,
@@ -7,6 +7,8 @@ export const ARTIFACT_REF_KINDS = [
7
7
  "bug-fix-plan-json-file",
8
8
  "design-file",
9
9
  "design-json-file",
10
+ "design-review-file",
11
+ "design-review-json-file",
10
12
  "gitlab-diff-file",
11
13
  "gitlab-diff-json-file",
12
14
  "gitlab-diff-review-input-json-file",
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from "node:fs";
2
- import { artifactFile, bugAnalyzeArtifacts, bugAnalyzeFile, bugAnalyzeJsonFile, bugFixDesignFile, bugFixDesignJsonFile, bugFixPlanFile, bugFixPlanJsonFile, designFile, designJsonFile, gitlabDiffFile, gitlabDiffJsonFile, gitlabDiffReviewInputJsonFile, gitlabReviewFile, gitlabReviewInputJsonFile, gitlabReviewJsonFile, jiraAttachmentsContextFile, jiraAttachmentsManifestFile, jiraDescriptionFile, jiraDescriptionJsonFile, jiraTaskFile, mrDescriptionFile, mrDescriptionJsonFile, planningAnswersJsonFile, planningQuestionsJsonFile, planArtifacts, planFile, planJsonFile, qaFile, qaJsonFile, readyToMergeFile, reviewAssessmentFile, reviewAssessmentJsonFile, reviewFile, reviewFixFile, reviewFixJsonFile, reviewJsonFile, runGoLinterResultJsonFile, runGoTestsResultJsonFile, taskSummaryFile, taskDescribeInputJsonFile, taskSummaryJsonFile, gitStatusJsonFile, gitCommitMessageJsonFile, gitCommitInputJsonFile, selectFilesOutputJsonFile, commitMessageOutputJsonFile, gitDiffFile as gitDiffFileHelper, } from "../artifacts.js";
2
+ import { artifactFile, bugAnalyzeArtifacts, bugAnalyzeFile, bugAnalyzeJsonFile, bugFixDesignFile, bugFixDesignJsonFile, bugFixPlanFile, bugFixPlanJsonFile, designFile, designJsonFile, designReviewFile, designReviewJsonFile, gitlabDiffFile, gitlabDiffJsonFile, gitlabDiffReviewInputJsonFile, gitlabReviewFile, gitlabReviewInputJsonFile, gitlabReviewJsonFile, jiraAttachmentsContextFile, jiraAttachmentsManifestFile, jiraDescriptionFile, jiraDescriptionJsonFile, jiraTaskFile, mrDescriptionFile, mrDescriptionJsonFile, planningAnswersJsonFile, planningQuestionsJsonFile, planArtifacts, planFile, planJsonFile, qaFile, qaJsonFile, readyToMergeFile, reviewAssessmentFile, reviewAssessmentJsonFile, reviewFile, reviewFixFile, reviewFixJsonFile, reviewJsonFile, runGoLinterResultJsonFile, runGoTestsResultJsonFile, taskSummaryFile, taskDescribeInputJsonFile, taskSummaryJsonFile, gitStatusJsonFile, gitCommitMessageJsonFile, gitCommitInputJsonFile, selectFilesOutputJsonFile, commitMessageOutputJsonFile, gitDiffFile as gitDiffFileHelper, } from "../artifacts.js";
3
3
  import { TaskRunnerError } from "../errors.js";
4
4
  import { formatTemplate } from "../prompts.js";
5
5
  function readStepRef(segments, context, originalPath) {
@@ -88,6 +88,16 @@ function resolveArtifact(spec, context) {
88
88
  return designFile(taskKey, iteration);
89
89
  case "design-json-file":
90
90
  return designJsonFile(taskKey, iteration);
91
+ case "design-review-file":
92
+ if (iteration === undefined) {
93
+ throw new TaskRunnerError("design-review-file requires iteration");
94
+ }
95
+ return designReviewFile(taskKey, iteration);
96
+ case "design-review-json-file":
97
+ if (iteration === undefined) {
98
+ throw new TaskRunnerError("design-review-json-file requires iteration");
99
+ }
100
+ return designReviewJsonFile(taskKey, iteration);
91
101
  case "gitlab-diff-file":
92
102
  return gitlabDiffFile(taskKey, iteration);
93
103
  case "gitlab-diff-json-file":
package/dist/prompts.js CHANGED
@@ -52,13 +52,32 @@ export const MR_DESCRIPTION_PROMPT_TEMPLATE = "Review the task in {jira_task_fil
52
52
  "Prepare a very brief intent description for the merge request without implementation details, file lists, or technical details. " +
53
53
  `First write the source-of-truth JSON to {mr_description_json_file}. ${strictSchemaInstruction("{mr_description_json_file}", "mr-description/v1")}Then write the derivative markdown version to {mr_description_file}. `;
54
54
  export const IMPLEMENT_PROMPT_TEMPLATE = "Use only structured artifacts as source of truth. " +
55
- "Analyze the system design {design_json_file}, implementation plan {plan_json_file}, and proceed with implementation according to the plan. " +
56
- "Markdown artifacts are intended only for human reading and should not define the implementation. ";
55
+ "Analyze the system design {design_json_file}, implementation plan {plan_json_file}, and QA plan {qa_json_file}, then proceed with implementation according to those artifacts. " +
56
+ "Treat the QA plan as the source of truth for the minimum required test scenarios, edge cases, regression checks, and validation behavior that the implementation must satisfy. " +
57
+ "When the repository contains automated tests, add or update tests for the key scenarios from the QA plan whenever it is practical in the current codebase. " +
58
+ "If some QA scenarios cannot be automated in the current change, still implement the code so those scenarios are satisfied and keep them explicit in your reasoning while editing. " +
59
+ "Markdown artifacts such as {design_file}, {plan_file}, and {qa_file} are intended only for human reading and should not define the implementation. ";
57
60
  export const REVIEW_PROMPT_TEMPLATE = "Conduct a code review of the current changes. " +
58
61
  "Use only structured artifacts as source of truth: the task in {jira_task_file}, design in {design_json_file}, and plan in {plan_json_file}. " +
59
62
  `First write the structured result to {review_json_file}. ${strictSchemaInstruction("{review_json_file}", "review-findings/v1")}` +
60
63
  "Then write the derivative markdown version to {review_file}. " +
61
64
  "If ready_to_merge=true and there are no blockers preventing merge - create the ready-to-merge.md file.";
65
+ export const DESIGN_REVIEW_PROMPT_TEMPLATE = "Conduct a structured planning critique as a specification critic, not as an implementer. " +
66
+ "Use structured JSON artifacts as the source of truth for semantics. " +
67
+ "Required planning inputs: design markdown {design_file}, design JSON {design_json_file}, implementation plan markdown {plan_file}, implementation plan JSON {plan_json_file}. " +
68
+ "Review the markdown files as derivative human-readable renderings of the same planning run, but do not let markdown override the structured JSON. " +
69
+ "Optional supplemental context is provided through these variables and may contain the literal value 'not provided' when absent: QA markdown {qa_file}, QA JSON {qa_json_file}, Jira task JSON {jira_task_file}, Jira attachments manifest {jira_attachments_manifest_file}, Jira attachments context {jira_attachments_context_file}, planning answers JSON {planning_answers_json_file}. " +
70
+ "When an optional variable is 'not provided', treat that source as unavailable and do not invent details from it. " +
71
+ "Evaluate completeness, consistency, implementation readiness, risk coverage, QA coverage, and scope discipline across the available planning artifacts and optional context. " +
72
+ "Identify blocking findings, major non-blocking findings, warnings, missing information, consistency check results, QA coverage gaps, and concise recommended actions. " +
73
+ "Use exactly one status value: approved, approved_with_warnings, or needs_revision. " +
74
+ "Set status to needs_revision when any blocking finding exists or when required information is missing in a way that blocks safe implementation start. " +
75
+ "Set status to approved_with_warnings when there are no blocking findings, but there are major findings, warnings, non-blocking missing information items, QA coverage gaps, or non-blocking consistency issues. " +
76
+ "Set status to approved only when there are no unresolved blocking findings, major findings, warnings, missing information items, or QA coverage gaps. " +
77
+ `First write the structured design review to {review_json_file}. ${strictSchemaInstruction("{review_json_file}", "design-review/v1")}` +
78
+ "Then write the derivative markdown version to {review_file}. " +
79
+ "Create ready-to-merge.md only when status is approved or approved_with_warnings. " +
80
+ "Do not create ready-to-merge.md when status is needs_revision.";
62
81
  export const REVIEW_PROJECT_PROMPT_TEMPLATE = "Conduct a code review of current changes in the project without Jira context. " +
63
82
  "Evaluate the quality of changes based on current code, tests, regression risks, and overall engineering quality. " +
64
83
  `First write the structured result to {review_json_file}. ${strictSchemaInstruction("{review_json_file}", "review-findings/v1")}` +
@@ -116,6 +135,34 @@ export const COMMIT_MESSAGE_PROMPT_TEMPLATE = "Generate a commit message for the
116
135
  "3) Include task key from Jira task. " +
117
136
  "4) Commit message language: English. " +
118
137
  "5) Write JSON to {commit_message_json_file}: {\"subject\": \"...\"}.";
138
+ export const PLAN_REVISE_PROMPT_TEMPLATE = "Revise the planning artifacts based on the design-review verdict. " +
139
+ "Use structured JSON artifacts as the source of truth for semantics. " +
140
+ "First revise the structured JSON artifacts; only after the JSON is complete and schema-valid should you write the derivative markdown files. " +
141
+ "Markdown must not influence JSON structure or types. " +
142
+ "The design-review verdict JSON {review_json_file} is the primary source of revision instructions — treat its blocking findings, major findings, and recommended actions as mandatory revision targets. " +
143
+ "The design-review markdown {review_file} is a derivative rendering only and must not override the structured verdict. " +
144
+ "Required source planning inputs: design JSON {design_json_file}, design markdown {design_file}, plan JSON {plan_json_file}, plan markdown {plan_file}. " +
145
+ "Optional source QA inputs (may be 'not provided'): QA JSON {qa_json_file}, QA markdown {qa_file}. " +
146
+ "When QA inputs are 'not provided', synthesize a new QA plan from the revised design and plan. " +
147
+ "Optional supplemental context (may be 'not provided'): Jira task JSON {jira_task_file}, Jira attachments manifest {jira_attachments_manifest_file}, Jira attachments context {jira_attachments_context_file}, planning answers JSON {planning_answers_json_file}. " +
148
+ "When an optional variable is 'not provided', treat that source as unavailable and do not invent details from it. " +
149
+ "For every blocking finding and major finding in the verdict, address it directly in the revised artifacts. " +
150
+ "Preserve all content from the original artifacts that is not directly addressed by findings in the verdict — do not drop details, sections, or decisions that remain valid. " +
151
+ "Preserve semantics, not source formatting conventions from the verdict: do not copy verdict-style nested objects into fields whose schemas require plain strings. " +
152
+ "For implementation-design/v1 specifically, goals, non_goals, components, current_state, target_state, business_rules, migration_strategy, database_changes, api_changes, risks, acceptance_criteria, and open_questions must remain arrays of non-empty strings. " +
153
+ "Only affected_code and decisions may contain nested objects in implementation-design/v1. " +
154
+ "If you need to preserve extra detail such as mitigation, resolution, or answer text for a string-array field, fold that detail into a single English sentence string instead of creating an object. " +
155
+ "Produce the following revised outputs: " +
156
+ `revised design JSON to {revised_design_json_file}. ${strictSchemaInstruction("{revised_design_json_file}", "implementation-design/v1")}` +
157
+ "Revised design markdown to {revised_design_file}. " +
158
+ `revised plan JSON to {revised_plan_json_file}. ${strictSchemaInstruction("{revised_plan_json_file}", "implementation-plan/v1")}` +
159
+ "Revised plan markdown to {revised_plan_file}. " +
160
+ `revised QA JSON to {revised_qa_json_file}. ${strictSchemaInstruction("{revised_qa_json_file}", "qa-plan/v1")}` +
161
+ "Revised QA markdown to {revised_qa_file}. " +
162
+ "Create ready-to-merge.md only when all blocking findings from the verdict have been addressed in the revised artifacts. " +
163
+ "Do not create ready-to-merge.md if any blocking finding remains unresolved. " +
164
+ "JSON files must be valid and contain only JSON without markdown wrapping. " +
165
+ "Markdown files must be comprehensive derivative representations of the corresponding JSON artifacts.";
119
166
  export const AUTO_REVIEW_FIX_EXTRA_PROMPT = "Fix only blockers, criticals, and important issues";
120
167
  export function formatTemplate(template, values) {
121
168
  let result = template;