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.
- package/README.md +5 -0
- package/dist/artifacts.js +6 -1
- package/dist/doctor/checks/cwd-context.js +4 -3
- package/dist/doctor/checks/env-diagnostics.js +168 -71
- package/dist/doctor/checks/flow-readiness.js +210 -198
- package/dist/doctor/index.js +1 -1
- package/dist/doctor/orchestrator.js +18 -7
- package/dist/doctor/runner.js +9 -8
- package/dist/doctor/types.js +12 -0
- package/dist/index.js +113 -29
- package/dist/pipeline/flow-catalog.js +4 -0
- package/dist/pipeline/flow-specs/design-review.json +239 -0
- package/dist/pipeline/flow-specs/implement.json +13 -1
- package/dist/pipeline/flow-specs/plan-revise.json +261 -0
- package/dist/pipeline/flow-specs/task-describe.json +60 -2
- package/dist/pipeline/node-registry.js +8 -0
- package/dist/pipeline/nodes/ensure-summary-json-node.js +59 -0
- package/dist/pipeline/prompt-registry.js +3 -1
- package/dist/pipeline/spec-types.js +2 -0
- package/dist/pipeline/value-resolver.js +11 -1
- package/dist/prompts.js +49 -2
- package/dist/runtime/design-review-input-contract.js +112 -0
- package/dist/runtime/plan-revise-input-contract.js +144 -0
- package/dist/runtime/ready-to-merge.js +10 -0
- package/dist/scope.js +11 -2
- package/dist/structured-artifact-schema-registry.js +1 -0
- package/dist/structured-artifact-schemas.json +117 -0
- package/dist/structured-artifacts.js +6 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import {
|
|
6
|
+
import { bugAnalyzeArtifacts, bugAnalyzeJsonFile, bugFixDesignJsonFile, bugFixPlanJsonFile, designReviewFile, designReviewJsonFile, designJsonFile, gitlabDiffFile, gitlabDiffJsonFile, ensureScopeWorkspaceDir, gitlabReviewFile, gitlabReviewJsonFile, latestArtifactIteration, nextArtifactIteration, planJsonFile, planArtifacts, qaJsonFile, readyToMergeFile, requireArtifacts, reviewAssessmentFile, reviewAssessmentJsonFile, reviewFile, reviewFixSelectionJsonFile, reviewJsonFile, scopeWorkspaceDir, flowStateFile, taskSummaryFile, } from "./artifacts.js";
|
|
7
7
|
import { FlowInterruptedError, TaskRunnerError } from "./errors.js";
|
|
8
8
|
import { createFlowRunState, hasResumableFlowState, loadFlowRunState, prepareFlowStateForResume, resetFlowRunState, rewindFlowRunStateToPhase, saveFlowRunState, stripExecutionStatePayload, } from "./flow-state.js";
|
|
9
9
|
import { requireJiraTaskFile } from "./jira.js";
|
|
@@ -20,11 +20,14 @@ import { resolveCmd } from "./runtime/command-resolution.js";
|
|
|
20
20
|
import { loadTieredEnv } from "./runtime/env-loader.js";
|
|
21
21
|
import { agentweaverHome } from "./runtime/agentweaver-home.js";
|
|
22
22
|
import { runCommand } from "./runtime/process-runner.js";
|
|
23
|
+
import { resolveDesignReviewInputContract } from "./runtime/design-review-input-contract.js";
|
|
24
|
+
import { resolvePlanReviseInputContract } from "./runtime/plan-revise-input-contract.js";
|
|
25
|
+
import { clearReadyToMergeFile } from "./runtime/ready-to-merge.js";
|
|
23
26
|
import { InteractiveUi } from "./interactive-ui.js";
|
|
24
27
|
import { bye, printError, printInfo, printPanel, printSummary, setFlowExecutionState, stripAnsi, } from "./tui.js";
|
|
25
28
|
import { requestUserInputInTerminal } from "./user-input.js";
|
|
26
29
|
import { runDoctorCommand } from "./doctor/index.js";
|
|
27
|
-
import {
|
|
30
|
+
import { detectGitBranchName, requestJiraContext, resolveProjectScope, } from "./scope.js";
|
|
28
31
|
const COMMANDS = [
|
|
29
32
|
"auto-golang",
|
|
30
33
|
"auto-common",
|
|
@@ -32,12 +35,14 @@ const COMMANDS = [
|
|
|
32
35
|
"auto-reset",
|
|
33
36
|
"bug-analyze",
|
|
34
37
|
"bug-fix",
|
|
38
|
+
"design-review",
|
|
35
39
|
"doctor",
|
|
36
40
|
"git-commit",
|
|
37
41
|
"gitlab-diff-review",
|
|
38
42
|
"gitlab-review",
|
|
39
43
|
"mr-description",
|
|
40
44
|
"plan",
|
|
45
|
+
"plan-revise",
|
|
41
46
|
"task-describe",
|
|
42
47
|
"implement",
|
|
43
48
|
"review",
|
|
@@ -99,9 +104,11 @@ function usage() {
|
|
|
99
104
|
agentweaver gitlab-review [--dry] [--verbose] [--prompt <text>] [--scope <name>]
|
|
100
105
|
agentweaver bug-analyze [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
101
106
|
agentweaver bug-fix [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
107
|
+
agentweaver design-review [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
102
108
|
agentweaver doctor [<category>|<check-id>] [--json]
|
|
103
109
|
agentweaver mr-description [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
104
110
|
agentweaver plan [--dry] [--verbose] [--prompt <text>] [--md-lang <en|ru>] [<jira-browse-url|jira-issue-key>]
|
|
111
|
+
agentweaver plan-revise [--dry] [--verbose] [--prompt <text>] <jira-browse-url|jira-issue-key>
|
|
105
112
|
agentweaver task-describe [--dry] [--verbose] [--prompt <text>] [<jira-browse-url|jira-issue-key>]
|
|
106
113
|
agentweaver implement [--dry] [--verbose] [--prompt <text>] [--scope <name>] [<jira-browse-url|jira-issue-key>]
|
|
107
114
|
agentweaver review [--dry] [--verbose] [--prompt <text>] [--scope <name>] [<jira-browse-url|jira-issue-key>]
|
|
@@ -364,17 +371,19 @@ function scopeWithRestoredJiraContext(scope, state) {
|
|
|
364
371
|
if (scope.jiraRef || !state?.jiraRef?.trim()) {
|
|
365
372
|
return scope;
|
|
366
373
|
}
|
|
367
|
-
return
|
|
374
|
+
return resolveProjectScope(null, state.jiraRef);
|
|
375
|
+
}
|
|
376
|
+
function buildInteractiveBaseConfig(flowId, scope) {
|
|
377
|
+
return buildBaseConfig(flowId, {
|
|
378
|
+
...(scope.jiraRef ? { jiraRef: scope.jiraRef } : {}),
|
|
379
|
+
});
|
|
368
380
|
}
|
|
369
381
|
function lookupInteractiveFlowResume(flowEntry, currentScope) {
|
|
370
382
|
const directState = loadFlowRunState(currentScope.scopeKey, flowEntry.id);
|
|
371
383
|
if (directState && hasResumableFlowState(directState)) {
|
|
372
384
|
try {
|
|
373
385
|
const effectiveScope = scopeWithRestoredJiraContext(currentScope, directState);
|
|
374
|
-
const baseConfig =
|
|
375
|
-
...(effectiveScope.jiraRef ? { jiraRef: effectiveScope.jiraRef } : {}),
|
|
376
|
-
scopeName: effectiveScope.scopeKey,
|
|
377
|
-
});
|
|
386
|
+
const baseConfig = buildInteractiveBaseConfig(flowEntry.id, effectiveScope);
|
|
378
387
|
const config = buildRuntimeConfig(baseConfig, effectiveScope);
|
|
379
388
|
validateDeclarativeFlowResumeState(flowEntry, config, directState, directState.launchProfile);
|
|
380
389
|
return {
|
|
@@ -410,21 +419,10 @@ function printAutoCommonPhasesHelp() {
|
|
|
410
419
|
printPanel("Auto-Common Phases", phaseLines.join("\n"), "magenta");
|
|
411
420
|
}
|
|
412
421
|
function nextReviewIterationForTask(taskKey) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
for (const entry of readdirSync(workspaceDir, { withFileTypes: true })) {
|
|
419
|
-
if (!entry.isFile()) {
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
const match = REVIEW_FILE_RE.exec(entry.name);
|
|
423
|
-
if (match && match[1] === taskKey) {
|
|
424
|
-
maxIndex = Math.max(maxIndex, Number.parseInt(match[2] ?? "0", 10));
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
return maxIndex + 1;
|
|
422
|
+
return nextArtifactIteration(taskKey, "review");
|
|
423
|
+
}
|
|
424
|
+
function nextDesignReviewIterationForTask(taskKey) {
|
|
425
|
+
return nextArtifactIteration(taskKey, "design-review");
|
|
428
426
|
}
|
|
429
427
|
function buildBaseConfig(command, options = {}) {
|
|
430
428
|
return {
|
|
@@ -442,8 +440,10 @@ function buildBaseConfig(command, options = {}) {
|
|
|
442
440
|
}
|
|
443
441
|
function commandRequiresTask(command) {
|
|
444
442
|
return (command === "plan" ||
|
|
443
|
+
command === "plan-revise" ||
|
|
445
444
|
command === "bug-analyze" ||
|
|
446
445
|
command === "bug-fix" ||
|
|
446
|
+
command === "design-review" ||
|
|
447
447
|
command === "mr-description" ||
|
|
448
448
|
command === "auto-golang" ||
|
|
449
449
|
command === "auto-common" ||
|
|
@@ -865,6 +865,90 @@ async function executeCommand(baseConfig, runFollowupVerify = true, requestUserI
|
|
|
865
865
|
}, launchProfile ? { launchProfile } : {}, requestUserInput, setSummary, launchMode, runtime);
|
|
866
866
|
return false;
|
|
867
867
|
}
|
|
868
|
+
if (config.command === "design-review") {
|
|
869
|
+
const iteration = nextDesignReviewIterationForTask(config.taskKey);
|
|
870
|
+
const inputContract = resolveDesignReviewInputContract(config.taskKey);
|
|
871
|
+
if (!config.dryRun) {
|
|
872
|
+
clearReadyToMergeFile(config.taskKey);
|
|
873
|
+
}
|
|
874
|
+
await runDeclarativeFlowBySpecFile("design-review.json", config, {
|
|
875
|
+
taskKey: config.taskKey,
|
|
876
|
+
iteration,
|
|
877
|
+
planningIteration: inputContract.planningIteration,
|
|
878
|
+
designFile: inputContract.designFile,
|
|
879
|
+
designJsonFile: inputContract.designJsonFile,
|
|
880
|
+
planFile: inputContract.planFile,
|
|
881
|
+
planJsonFile: inputContract.planJsonFile,
|
|
882
|
+
hasQaArtifacts: inputContract.hasQaArtifacts,
|
|
883
|
+
qaFilePath: inputContract.qaFilePath,
|
|
884
|
+
qaJsonFilePath: inputContract.qaJsonFilePath,
|
|
885
|
+
qaFile: inputContract.qaFile,
|
|
886
|
+
qaJsonFile: inputContract.qaJsonFile,
|
|
887
|
+
hasJiraTaskFile: inputContract.hasJiraTaskFile,
|
|
888
|
+
jiraTaskFilePath: inputContract.jiraTaskFilePath,
|
|
889
|
+
jiraTaskFile: inputContract.jiraTaskFile,
|
|
890
|
+
hasJiraAttachmentsManifestFile: inputContract.hasJiraAttachmentsManifestFile,
|
|
891
|
+
jiraAttachmentsManifestFilePath: inputContract.jiraAttachmentsManifestFilePath,
|
|
892
|
+
jiraAttachmentsManifestFile: inputContract.jiraAttachmentsManifestFile,
|
|
893
|
+
hasJiraAttachmentsContextFile: inputContract.hasJiraAttachmentsContextFile,
|
|
894
|
+
jiraAttachmentsContextFilePath: inputContract.jiraAttachmentsContextFilePath,
|
|
895
|
+
jiraAttachmentsContextFile: inputContract.jiraAttachmentsContextFile,
|
|
896
|
+
hasPlanningAnswersJsonFile: inputContract.hasPlanningAnswersJsonFile,
|
|
897
|
+
planningAnswersJsonFilePath: inputContract.planningAnswersJsonFilePath,
|
|
898
|
+
planningAnswersJsonFile: inputContract.planningAnswersJsonFile,
|
|
899
|
+
extraPrompt: config.extraPrompt,
|
|
900
|
+
}, launchProfile ? { launchProfile } : {}, requestUserInput, undefined, launchMode, runtime);
|
|
901
|
+
if (!config.dryRun) {
|
|
902
|
+
printSummary("Design Review", `Artifacts:\n${designReviewFile(config.taskKey, iteration)}\n${designReviewJsonFile(config.taskKey, iteration)}`);
|
|
903
|
+
}
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (config.command === "plan-revise") {
|
|
907
|
+
const inputContract = resolvePlanReviseInputContract(config.taskKey);
|
|
908
|
+
if (!config.dryRun) {
|
|
909
|
+
clearReadyToMergeFile(config.taskKey);
|
|
910
|
+
}
|
|
911
|
+
await runDeclarativeFlowBySpecFile("plan-revise.json", config, {
|
|
912
|
+
taskKey: config.taskKey,
|
|
913
|
+
reviewIteration: inputContract.reviewIteration,
|
|
914
|
+
reviewFile: inputContract.reviewFile,
|
|
915
|
+
reviewJsonFile: inputContract.reviewJsonFile,
|
|
916
|
+
sourcePlanningIteration: inputContract.sourcePlanningIteration,
|
|
917
|
+
outputIteration: inputContract.outputIteration,
|
|
918
|
+
designFile: inputContract.designFile,
|
|
919
|
+
designJsonFile: inputContract.designJsonFile,
|
|
920
|
+
planFile: inputContract.planFile,
|
|
921
|
+
planJsonFile: inputContract.planJsonFile,
|
|
922
|
+
hasQaArtifacts: inputContract.hasQaArtifacts,
|
|
923
|
+
qaFilePath: inputContract.qaFilePath,
|
|
924
|
+
qaJsonFilePath: inputContract.qaJsonFilePath,
|
|
925
|
+
qaFile: inputContract.qaFile,
|
|
926
|
+
qaJsonFile: inputContract.qaJsonFile,
|
|
927
|
+
revisedDesignFile: inputContract.revisedDesignFile,
|
|
928
|
+
revisedDesignJsonFile: inputContract.revisedDesignJsonFile,
|
|
929
|
+
revisedPlanFile: inputContract.revisedPlanFile,
|
|
930
|
+
revisedPlanJsonFile: inputContract.revisedPlanJsonFile,
|
|
931
|
+
revisedQaFile: inputContract.revisedQaFile,
|
|
932
|
+
revisedQaJsonFile: inputContract.revisedQaJsonFile,
|
|
933
|
+
hasJiraTaskFile: inputContract.hasJiraTaskFile,
|
|
934
|
+
jiraTaskFilePath: inputContract.jiraTaskFilePath,
|
|
935
|
+
jiraTaskFile: inputContract.jiraTaskFile,
|
|
936
|
+
hasJiraAttachmentsManifestFile: inputContract.hasJiraAttachmentsManifestFile,
|
|
937
|
+
jiraAttachmentsManifestFilePath: inputContract.jiraAttachmentsManifestFilePath,
|
|
938
|
+
jiraAttachmentsManifestFile: inputContract.jiraAttachmentsManifestFile,
|
|
939
|
+
hasJiraAttachmentsContextFile: inputContract.hasJiraAttachmentsContextFile,
|
|
940
|
+
jiraAttachmentsContextFilePath: inputContract.jiraAttachmentsContextFilePath,
|
|
941
|
+
jiraAttachmentsContextFile: inputContract.jiraAttachmentsContextFile,
|
|
942
|
+
hasPlanningAnswersJsonFile: inputContract.hasPlanningAnswersJsonFile,
|
|
943
|
+
planningAnswersJsonFilePath: inputContract.planningAnswersJsonFilePath,
|
|
944
|
+
planningAnswersJsonFile: inputContract.planningAnswersJsonFile,
|
|
945
|
+
extraPrompt: config.extraPrompt,
|
|
946
|
+
}, launchProfile ? { launchProfile } : {}, requestUserInput, undefined, launchMode, runtime);
|
|
947
|
+
if (!config.dryRun) {
|
|
948
|
+
printSummary("Plan Revise", `Artifacts:\n${inputContract.revisedDesignFile}\n${inputContract.revisedDesignJsonFile}\n${inputContract.revisedPlanFile}\n${inputContract.revisedPlanJsonFile}\n${inputContract.revisedQaFile}\n${inputContract.revisedQaJsonFile}`);
|
|
949
|
+
}
|
|
950
|
+
return false;
|
|
951
|
+
}
|
|
868
952
|
if (config.command === "gitlab-review") {
|
|
869
953
|
const iteration = nextReviewIterationForTask(config.taskKey);
|
|
870
954
|
const gitlabReviewIteration = nextArtifactIteration(config.taskKey, "gitlab-review");
|
|
@@ -1182,17 +1266,14 @@ async function runInteractive(jiraRef, forceRefresh = false, scopeName) {
|
|
|
1182
1266
|
throw new TaskRunnerError("Resume is impossible because launch profile was not saved. Use restart.");
|
|
1183
1267
|
}
|
|
1184
1268
|
const previousScopeKey = currentScope.scopeKey;
|
|
1185
|
-
const baseConfig =
|
|
1186
|
-
...(currentScope.jiraRef ? { jiraRef: currentScope.jiraRef } : {}),
|
|
1187
|
-
scopeName: currentScope.scopeKey,
|
|
1188
|
-
});
|
|
1269
|
+
const baseConfig = buildInteractiveBaseConfig(flowId, currentScope);
|
|
1189
1270
|
if (flowEntry.source === "built-in" && isBuiltInCommandFlowId(flowId)) {
|
|
1190
1271
|
const nextScope = await resolveScopeForCommand(baseConfig, (form) => ui.requestUserInput(form));
|
|
1191
1272
|
currentScope = nextScope;
|
|
1192
1273
|
}
|
|
1193
1274
|
else if (flowRequiresTaskScope(flowEntry) && !currentScope.jiraRef) {
|
|
1194
1275
|
const jiraContext = await requestJiraContext((form) => ui.requestUserInput(form));
|
|
1195
|
-
currentScope =
|
|
1276
|
+
currentScope = resolveProjectScope(null, jiraContext.jiraRef);
|
|
1196
1277
|
}
|
|
1197
1278
|
ui.setScope(currentScope.scopeKey, currentScope.jiraIssueKey ?? null);
|
|
1198
1279
|
if (previousScopeKey !== currentScope.scopeKey || currentScope.jiraIssueKey) {
|
|
@@ -1283,7 +1364,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
1283
1364
|
return await runInteractive(args[0] ?? "", forceRefresh);
|
|
1284
1365
|
}
|
|
1285
1366
|
const parsedArgs = parseCliArgs(args);
|
|
1286
|
-
await executeCommand(buildConfigFromArgs(parsedArgs));
|
|
1367
|
+
const commandCompleted = await executeCommand(buildConfigFromArgs(parsedArgs));
|
|
1368
|
+
if (parsedArgs.command === "doctor") {
|
|
1369
|
+
return commandCompleted ? 0 : 1;
|
|
1370
|
+
}
|
|
1287
1371
|
return 0;
|
|
1288
1372
|
}
|
|
1289
1373
|
catch (error) {
|
|
@@ -8,11 +8,13 @@ export const BUILT_IN_COMMAND_FLOW_IDS = [
|
|
|
8
8
|
"auto-common",
|
|
9
9
|
"bug-analyze",
|
|
10
10
|
"bug-fix",
|
|
11
|
+
"design-review",
|
|
11
12
|
"git-commit",
|
|
12
13
|
"gitlab-diff-review",
|
|
13
14
|
"gitlab-review",
|
|
14
15
|
"mr-description",
|
|
15
16
|
"plan",
|
|
17
|
+
"plan-revise",
|
|
16
18
|
"task-describe",
|
|
17
19
|
"implement",
|
|
18
20
|
"review",
|
|
@@ -26,11 +28,13 @@ const BUILT_IN_COMMAND_FLOW_FILES = {
|
|
|
26
28
|
"auto-common": "auto-common.json",
|
|
27
29
|
"bug-analyze": "bugz/bug-analyze.json",
|
|
28
30
|
"bug-fix": "bugz/bug-fix.json",
|
|
31
|
+
"design-review": "design-review.json",
|
|
29
32
|
"git-commit": "git-commit.json",
|
|
30
33
|
"gitlab-diff-review": "gitlab/gitlab-diff-review.json",
|
|
31
34
|
"gitlab-review": "gitlab/gitlab-review.json",
|
|
32
35
|
"mr-description": "gitlab/mr-description.json",
|
|
33
36
|
plan: "plan.json",
|
|
37
|
+
"plan-revise": "plan-revise.json",
|
|
34
38
|
"task-describe": "task-describe.json",
|
|
35
39
|
implement: "implement.json",
|
|
36
40
|
review: "review/review.json",
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "design-review-flow",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"description": "Performs a structured planning critique of the latest completed planning artifacts against the task context available in the scope. Produces a verdict-oriented design review artifact and treats approved_with_warnings as ready to proceed.",
|
|
5
|
+
"phases": [
|
|
6
|
+
{
|
|
7
|
+
"id": "phase_1_load_contract",
|
|
8
|
+
"steps": [
|
|
9
|
+
{
|
|
10
|
+
"id": "validate_design_markdown_artifact",
|
|
11
|
+
"node": "file-check",
|
|
12
|
+
"params": {
|
|
13
|
+
"path": { "ref": "params.designFile" },
|
|
14
|
+
"panelTitle": { "const": "Design Markdown Artifact" },
|
|
15
|
+
"foundMessage": { "const": "Design markdown artifact found for the resolved planning iteration." },
|
|
16
|
+
"tone": { "const": "cyan" }
|
|
17
|
+
},
|
|
18
|
+
"expect": [
|
|
19
|
+
{
|
|
20
|
+
"kind": "require-file",
|
|
21
|
+
"path": { "ref": "params.designFile" },
|
|
22
|
+
"message": "Design-review contract is missing the required design markdown artifact."
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "validate_design_json_artifact",
|
|
28
|
+
"node": "file-check",
|
|
29
|
+
"params": {
|
|
30
|
+
"path": { "ref": "params.designJsonFile" },
|
|
31
|
+
"panelTitle": { "const": "Design Structured Artifact" },
|
|
32
|
+
"foundMessage": { "const": "Design structured artifact found for the resolved planning iteration." },
|
|
33
|
+
"tone": { "const": "cyan" }
|
|
34
|
+
},
|
|
35
|
+
"expect": [
|
|
36
|
+
{
|
|
37
|
+
"kind": "require-file",
|
|
38
|
+
"path": { "ref": "params.designJsonFile" },
|
|
39
|
+
"message": "Design-review contract is missing the required design structured artifact."
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "validate_plan_markdown_artifact",
|
|
45
|
+
"node": "file-check",
|
|
46
|
+
"params": {
|
|
47
|
+
"path": { "ref": "params.planFile" },
|
|
48
|
+
"panelTitle": { "const": "Plan Markdown Artifact" },
|
|
49
|
+
"foundMessage": { "const": "Implementation plan markdown artifact found for the resolved planning iteration." },
|
|
50
|
+
"tone": { "const": "cyan" }
|
|
51
|
+
},
|
|
52
|
+
"expect": [
|
|
53
|
+
{
|
|
54
|
+
"kind": "require-file",
|
|
55
|
+
"path": { "ref": "params.planFile" },
|
|
56
|
+
"message": "Design-review contract is missing the required implementation plan markdown artifact."
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "validate_plan_json_artifact",
|
|
62
|
+
"node": "file-check",
|
|
63
|
+
"params": {
|
|
64
|
+
"path": { "ref": "params.planJsonFile" },
|
|
65
|
+
"panelTitle": { "const": "Plan Structured Artifact" },
|
|
66
|
+
"foundMessage": { "const": "Implementation plan structured artifact found for the resolved planning iteration." },
|
|
67
|
+
"tone": { "const": "cyan" }
|
|
68
|
+
},
|
|
69
|
+
"expect": [
|
|
70
|
+
{
|
|
71
|
+
"kind": "require-file",
|
|
72
|
+
"path": { "ref": "params.planJsonFile" },
|
|
73
|
+
"message": "Design-review contract is missing the required implementation plan structured artifact."
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "validate_qa_markdown_artifact",
|
|
79
|
+
"when": { "ref": "params.hasQaArtifacts" },
|
|
80
|
+
"node": "file-check",
|
|
81
|
+
"params": {
|
|
82
|
+
"path": { "ref": "params.qaFilePath" },
|
|
83
|
+
"panelTitle": { "const": "QA Markdown Artifact" },
|
|
84
|
+
"foundMessage": { "const": "QA markdown artifact found and will be included in the critique." },
|
|
85
|
+
"tone": { "const": "cyan" }
|
|
86
|
+
},
|
|
87
|
+
"expect": [
|
|
88
|
+
{
|
|
89
|
+
"kind": "require-file",
|
|
90
|
+
"path": { "ref": "params.qaFilePath" },
|
|
91
|
+
"message": "Design-review contract expected a QA markdown artifact, but the file is missing."
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "validate_qa_json_artifact",
|
|
97
|
+
"when": { "ref": "params.hasQaArtifacts" },
|
|
98
|
+
"node": "file-check",
|
|
99
|
+
"params": {
|
|
100
|
+
"path": { "ref": "params.qaJsonFilePath" },
|
|
101
|
+
"panelTitle": { "const": "QA Structured Artifact" },
|
|
102
|
+
"foundMessage": { "const": "QA structured artifact found and will be included in the critique." },
|
|
103
|
+
"tone": { "const": "cyan" }
|
|
104
|
+
},
|
|
105
|
+
"expect": [
|
|
106
|
+
{
|
|
107
|
+
"kind": "require-file",
|
|
108
|
+
"path": { "ref": "params.qaJsonFilePath" },
|
|
109
|
+
"message": "Design-review contract expected a QA structured artifact, but the file is missing."
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "phase_2_review",
|
|
117
|
+
"steps": [
|
|
118
|
+
{
|
|
119
|
+
"id": "run_design_review",
|
|
120
|
+
"node": "llm-prompt",
|
|
121
|
+
"prompt": {
|
|
122
|
+
"templateRef": "design-review",
|
|
123
|
+
"vars": {
|
|
124
|
+
"jira_task_file": { "ref": "params.jiraTaskFile" },
|
|
125
|
+
"jira_attachments_manifest_file": { "ref": "params.jiraAttachmentsManifestFile" },
|
|
126
|
+
"jira_attachments_context_file": { "ref": "params.jiraAttachmentsContextFile" },
|
|
127
|
+
"planning_answers_json_file": { "ref": "params.planningAnswersJsonFile" },
|
|
128
|
+
"design_file": { "ref": "params.designFile" },
|
|
129
|
+
"design_json_file": { "ref": "params.designJsonFile" },
|
|
130
|
+
"plan_file": { "ref": "params.planFile" },
|
|
131
|
+
"plan_json_file": { "ref": "params.planJsonFile" },
|
|
132
|
+
"qa_file": { "ref": "params.qaFile" },
|
|
133
|
+
"qa_json_file": { "ref": "params.qaJsonFile" },
|
|
134
|
+
"review_file": {
|
|
135
|
+
"artifact": {
|
|
136
|
+
"kind": "design-review-file",
|
|
137
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
138
|
+
"iteration": { "ref": "params.iteration" }
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"review_json_file": {
|
|
142
|
+
"artifact": {
|
|
143
|
+
"kind": "design-review-json-file",
|
|
144
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
145
|
+
"iteration": { "ref": "params.iteration" }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"extraPrompt": { "ref": "params.extraPrompt" },
|
|
150
|
+
"format": "task-prompt"
|
|
151
|
+
},
|
|
152
|
+
"params": {
|
|
153
|
+
"labelText": {
|
|
154
|
+
"template": "Running design review (iteration {iteration})",
|
|
155
|
+
"vars": {
|
|
156
|
+
"iteration": { "ref": "params.iteration" }
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"model": { "ref": "params.llmModel" },
|
|
160
|
+
"executor": { "ref": "params.llmExecutor" },
|
|
161
|
+
"requiredArtifacts": {
|
|
162
|
+
"list": [
|
|
163
|
+
{
|
|
164
|
+
"artifact": {
|
|
165
|
+
"kind": "design-review-file",
|
|
166
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
167
|
+
"iteration": { "ref": "params.iteration" }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"expect": [
|
|
174
|
+
{
|
|
175
|
+
"kind": "require-artifacts",
|
|
176
|
+
"when": { "not": { "ref": "context.dryRun" } },
|
|
177
|
+
"paths": {
|
|
178
|
+
"list": [
|
|
179
|
+
{
|
|
180
|
+
"artifact": {
|
|
181
|
+
"kind": "design-review-file",
|
|
182
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
183
|
+
"iteration": { "ref": "params.iteration" }
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
"message": "Design review did not produce the required review artifact."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"kind": "require-structured-artifacts",
|
|
192
|
+
"when": { "not": { "ref": "context.dryRun" } },
|
|
193
|
+
"items": [
|
|
194
|
+
{
|
|
195
|
+
"path": {
|
|
196
|
+
"artifact": {
|
|
197
|
+
"kind": "design-review-json-file",
|
|
198
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
199
|
+
"iteration": { "ref": "params.iteration" }
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
"schemaId": "design-review/v1"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"message": "Design review produced invalid structured artifacts."
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"id": "phase_3_finalize",
|
|
213
|
+
"steps": [
|
|
214
|
+
{
|
|
215
|
+
"id": "check_ready_to_merge",
|
|
216
|
+
"node": "file-check",
|
|
217
|
+
"params": {
|
|
218
|
+
"path": {
|
|
219
|
+
"artifact": {
|
|
220
|
+
"kind": "ready-to-merge-file",
|
|
221
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"panelTitle": { "const": "Ready To Merge" },
|
|
225
|
+
"foundMessage": { "const": "Design review is ready to proceed. File ready-to-merge.md has been created." },
|
|
226
|
+
"tone": { "const": "green" }
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"id": "notify_review_complete",
|
|
231
|
+
"node": "telegram-notify",
|
|
232
|
+
"params": {
|
|
233
|
+
"message": { "const": "Design review phase complete" }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"kind": "implement-flow",
|
|
3
3
|
"version": 1,
|
|
4
|
-
"description": "Runs LLM-backed implementation based on previously approved design and
|
|
4
|
+
"description": "Runs LLM-backed implementation based on previously approved design, plan, and QA artifacts. Executes code changes locally in the project working directory.",
|
|
5
5
|
"phases": [
|
|
6
6
|
{
|
|
7
7
|
"id": "implement",
|
|
@@ -35,6 +35,18 @@
|
|
|
35
35
|
"kind": "plan-json-file",
|
|
36
36
|
"taskKey": { "ref": "params.taskKey" }
|
|
37
37
|
}
|
|
38
|
+
},
|
|
39
|
+
"qa_file": {
|
|
40
|
+
"artifact": {
|
|
41
|
+
"kind": "qa-file",
|
|
42
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"qa_json_file": {
|
|
46
|
+
"artifact": {
|
|
47
|
+
"kind": "qa-json-file",
|
|
48
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
},
|
|
40
52
|
"extraPrompt": { "ref": "params.extraPrompt" },
|