agentweaver 0.1.15 → 0.1.17
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 +76 -19
- package/dist/artifact-manifest.js +219 -0
- package/dist/artifacts.js +88 -3
- package/dist/doctor/checks/env-diagnostics.js +25 -0
- package/dist/doctor/checks/executors.js +2 -2
- package/dist/doctor/checks/flow-readiness.js +15 -18
- package/dist/flow-state.js +212 -15
- package/dist/index.js +539 -209
- package/dist/interactive/blessed-session.js +361 -0
- package/dist/interactive/controller.js +1326 -0
- package/dist/interactive/create-interactive-session.js +5 -0
- package/dist/interactive/ink/index.js +597 -0
- package/dist/interactive/progress.js +245 -0
- package/dist/interactive/selectors.js +14 -0
- package/dist/interactive/session.js +1 -0
- package/dist/interactive/state.js +34 -0
- package/dist/interactive/tree.js +155 -0
- package/dist/interactive/types.js +1 -0
- package/dist/interactive/view-model.js +1 -0
- package/dist/interactive-ui.js +159 -194
- package/dist/pipeline/auto-flow.js +9 -6
- package/dist/pipeline/context.js +7 -5
- package/dist/pipeline/declarative-flow-runner.js +212 -6
- package/dist/pipeline/declarative-flows.js +63 -17
- package/dist/pipeline/execution-routing-config.js +15 -0
- package/dist/pipeline/flow-catalog.js +50 -12
- package/dist/pipeline/flow-run-resume.js +29 -0
- package/dist/pipeline/flow-specs/auto-common.json +90 -360
- package/dist/pipeline/flow-specs/auto-golang.json +81 -360
- package/dist/pipeline/flow-specs/auto-simple.json +141 -0
- package/dist/pipeline/flow-specs/bugz/bug-analyze.json +2 -0
- package/dist/pipeline/flow-specs/bugz/bug-fix.json +1 -0
- package/dist/pipeline/flow-specs/design-review/design-review-loop.json +316 -0
- package/dist/pipeline/flow-specs/design-review.json +10 -0
- package/dist/pipeline/flow-specs/gitlab/gitlab-diff-review.json +11 -0
- package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +2 -0
- package/dist/pipeline/flow-specs/gitlab/mr-description.json +1 -0
- package/dist/pipeline/flow-specs/go/run-go-linter-loop.json +2 -0
- package/dist/pipeline/flow-specs/go/run-go-tests-loop.json +2 -0
- package/dist/pipeline/flow-specs/implement.json +13 -6
- package/dist/pipeline/flow-specs/instant-task.json +177 -0
- package/dist/pipeline/flow-specs/normalize-task-source.json +311 -0
- package/dist/pipeline/flow-specs/plan-revise.json +7 -1
- package/dist/pipeline/flow-specs/plan.json +51 -71
- package/dist/pipeline/flow-specs/review/review-fix.json +24 -4
- package/dist/pipeline/flow-specs/review/review-loop.json +351 -45
- package/dist/pipeline/flow-specs/review/review-project-loop.json +590 -0
- package/dist/pipeline/flow-specs/review/review-project.json +12 -0
- package/dist/pipeline/flow-specs/review/review.json +37 -31
- package/dist/pipeline/flow-specs/task-describe.json +2 -0
- package/dist/pipeline/flow-specs/task-source/jira-fetch.json +70 -0
- package/dist/pipeline/flow-specs/task-source/manual-input.json +216 -0
- package/dist/pipeline/launch-profile-config.js +30 -18
- package/dist/pipeline/node-contract.js +1 -0
- package/dist/pipeline/node-registry.js +115 -6
- package/dist/pipeline/node-runner.js +3 -2
- package/dist/pipeline/nodes/build-review-fix-prompt-node.js +5 -1
- package/dist/pipeline/nodes/clear-ready-to-merge-node.js +11 -0
- package/dist/pipeline/nodes/commit-message-form-node.js +8 -0
- package/dist/pipeline/nodes/design-review-verdict-node.js +36 -0
- package/dist/pipeline/nodes/ensure-summary-json-node.js +13 -2
- package/dist/pipeline/nodes/fetch-gitlab-diff-node.js +19 -2
- package/dist/pipeline/nodes/fetch-gitlab-review-node.js +19 -2
- package/dist/pipeline/nodes/flow-run-node.js +242 -8
- package/dist/pipeline/nodes/git-commit-form-node.js +8 -0
- package/dist/pipeline/nodes/gitlab-review-artifacts-node.js +19 -2
- package/dist/pipeline/nodes/jira-fetch-node.js +50 -4
- package/dist/pipeline/nodes/llm-prompt-node.js +38 -36
- package/dist/pipeline/nodes/planning-bundle-node.js +10 -0
- package/dist/pipeline/nodes/review-verdict-node.js +86 -0
- package/dist/pipeline/nodes/select-files-form-node.js +8 -0
- package/dist/pipeline/nodes/structured-summary-node.js +24 -0
- package/dist/pipeline/nodes/user-input-node.js +38 -3
- package/dist/pipeline/nodes/write-selection-file-node.js +20 -4
- package/dist/pipeline/plugin-loader.js +389 -0
- package/dist/pipeline/plugin-types.js +1 -0
- package/dist/pipeline/prompt-registry.js +3 -1
- package/dist/pipeline/prompt-runtime.js +4 -1
- package/dist/pipeline/registry.js +71 -4
- package/dist/pipeline/review-iteration.js +26 -0
- package/dist/pipeline/spec-compiler.js +3 -0
- package/dist/pipeline/spec-loader.js +14 -0
- package/dist/pipeline/spec-types.js +3 -0
- package/dist/pipeline/spec-validator.js +20 -0
- package/dist/pipeline/value-resolver.js +76 -2
- package/dist/plugin-sdk.js +1 -0
- package/dist/prompts.js +36 -14
- package/dist/review-severity.js +45 -0
- package/dist/runtime/artifact-registry.js +405 -0
- package/dist/runtime/design-review-input-contract.js +17 -16
- package/dist/runtime/env-loader.js +3 -0
- package/dist/runtime/execution-routing-store.js +134 -0
- package/dist/runtime/execution-routing.js +233 -0
- package/dist/runtime/interactive-execution-routing.js +471 -0
- package/dist/runtime/plan-revise-input-contract.js +35 -32
- package/dist/runtime/planning-bundle.js +123 -0
- package/dist/runtime/ready-to-merge.js +22 -1
- package/dist/runtime/review-input-contract.js +100 -0
- package/dist/structured-artifact-schema-registry.js +9 -0
- package/dist/structured-artifact-schemas.json +140 -1
- package/dist/structured-artifacts.js +77 -6
- package/dist/user-input.js +70 -3
- package/docs/example/.flows/examples/claude-example.json +50 -0
- package/docs/example/.plugins/claude-example-plugin/index.js +149 -0
- package/docs/example/.plugins/claude-example-plugin/plugin.json +8 -0
- package/docs/examples/.flows/claude-example.json +50 -0
- package/docs/examples/.plugins/claude-example-plugin/index.js +149 -0
- package/docs/examples/.plugins/claude-example-plugin/plugin.json +8 -0
- package/docs/plugin-sdk.md +731 -0
- package/package.json +11 -4
|
@@ -9,39 +9,17 @@
|
|
|
9
9
|
{
|
|
10
10
|
"id": "run_review",
|
|
11
11
|
"node": "llm-prompt",
|
|
12
|
+
"routingGroup": "review",
|
|
12
13
|
"prompt": {
|
|
13
14
|
"templateRef": "review",
|
|
14
15
|
"vars": {
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
"
|
|
22
|
-
"artifact": {
|
|
23
|
-
"kind": "design-file",
|
|
24
|
-
"taskKey": { "ref": "params.taskKey" }
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
"design_json_file": {
|
|
28
|
-
"artifact": {
|
|
29
|
-
"kind": "design-json-file",
|
|
30
|
-
"taskKey": { "ref": "params.taskKey" }
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"plan_file": {
|
|
34
|
-
"artifact": {
|
|
35
|
-
"kind": "plan-file",
|
|
36
|
-
"taskKey": { "ref": "params.taskKey" }
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"plan_json_file": {
|
|
40
|
-
"artifact": {
|
|
41
|
-
"kind": "plan-json-file",
|
|
42
|
-
"taskKey": { "ref": "params.taskKey" }
|
|
43
|
-
}
|
|
44
|
-
},
|
|
16
|
+
"task_context_json_file": { "ref": "params.taskContextJsonFile" },
|
|
17
|
+
"jira_task_file": { "ref": "params.jiraTaskFile" },
|
|
18
|
+
"task_input_json_file": { "ref": "params.taskInputJsonFile" },
|
|
19
|
+
"design_file": { "ref": "params.designFile" },
|
|
20
|
+
"design_json_file": { "ref": "params.designJsonFile" },
|
|
21
|
+
"plan_file": { "ref": "params.planFile" },
|
|
22
|
+
"plan_json_file": { "ref": "params.planJsonFile" },
|
|
45
23
|
"review_file": {
|
|
46
24
|
"artifact": {
|
|
47
25
|
"kind": "review-file",
|
|
@@ -68,7 +46,25 @@
|
|
|
68
46
|
}
|
|
69
47
|
},
|
|
70
48
|
"model": { "ref": "params.llmModel" },
|
|
71
|
-
"executor": { "ref": "params.llmExecutor" }
|
|
49
|
+
"executor": { "ref": "params.llmExecutor" },
|
|
50
|
+
"requiredArtifacts": {
|
|
51
|
+
"list": [
|
|
52
|
+
{
|
|
53
|
+
"artifact": {
|
|
54
|
+
"kind": "review-file",
|
|
55
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
56
|
+
"iteration": { "ref": "params.iteration" }
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"artifact": {
|
|
61
|
+
"kind": "review-json-file",
|
|
62
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
63
|
+
"iteration": { "ref": "params.iteration" }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
72
68
|
},
|
|
73
69
|
"expect": [
|
|
74
70
|
{
|
|
@@ -106,6 +102,16 @@
|
|
|
106
102
|
}
|
|
107
103
|
]
|
|
108
104
|
},
|
|
105
|
+
{
|
|
106
|
+
"id": "review_verdict",
|
|
107
|
+
"node": "review-verdict",
|
|
108
|
+
"when": { "not": { "ref": "context.dryRun" } },
|
|
109
|
+
"params": {
|
|
110
|
+
"taskKey": { "ref": "params.taskKey" },
|
|
111
|
+
"iteration": { "ref": "params.iteration" },
|
|
112
|
+
"blockingSeverities": { "ref": "params.reviewBlockingSeverities" }
|
|
113
|
+
}
|
|
114
|
+
},
|
|
109
115
|
{
|
|
110
116
|
"id": "check_ready_to_merge",
|
|
111
117
|
"node": "file-check",
|
|
@@ -153,6 +153,7 @@
|
|
|
153
153
|
{
|
|
154
154
|
"id": "run_task_describe_from_jira",
|
|
155
155
|
"node": "llm-prompt",
|
|
156
|
+
"routingGroup": "planning",
|
|
156
157
|
"when": {
|
|
157
158
|
"ref": "steps.task_describe.collect_task_source.value.values.jira_ref"
|
|
158
159
|
},
|
|
@@ -285,6 +286,7 @@
|
|
|
285
286
|
{
|
|
286
287
|
"id": "run_task_describe_from_input",
|
|
287
288
|
"node": "llm-prompt",
|
|
289
|
+
"routingGroup": "planning",
|
|
288
290
|
"when": {
|
|
289
291
|
"not": {
|
|
290
292
|
"ref": "steps.task_describe.collect_task_source.value.values.jira_ref"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "task-source-jira-flow",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"description": "Fetches raw Jira task context and attachments into scope artifacts for subsequent normalization.",
|
|
5
|
+
"catalogVisibility": "hidden",
|
|
6
|
+
"phases": [
|
|
7
|
+
{
|
|
8
|
+
"id": "source",
|
|
9
|
+
"steps": [
|
|
10
|
+
{
|
|
11
|
+
"id": "fetch_jira",
|
|
12
|
+
"node": "jira-fetch",
|
|
13
|
+
"params": {
|
|
14
|
+
"jiraApiUrl": { "ref": "params.jiraApiUrl" },
|
|
15
|
+
"outputFile": {
|
|
16
|
+
"artifact": {
|
|
17
|
+
"kind": "jira-task-file",
|
|
18
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"attachmentsManifestFile": {
|
|
22
|
+
"artifact": {
|
|
23
|
+
"kind": "jira-attachments-manifest-file",
|
|
24
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"attachmentsContextFile": {
|
|
28
|
+
"artifact": {
|
|
29
|
+
"kind": "jira-attachments-context-file",
|
|
30
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"expect": [
|
|
35
|
+
{
|
|
36
|
+
"kind": "require-file",
|
|
37
|
+
"path": {
|
|
38
|
+
"artifact": {
|
|
39
|
+
"kind": "jira-task-file",
|
|
40
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"message": "Jira fetch node did not produce the Jira task file."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"kind": "require-file",
|
|
47
|
+
"path": {
|
|
48
|
+
"artifact": {
|
|
49
|
+
"kind": "jira-attachments-manifest-file",
|
|
50
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"message": "Jira fetch node did not produce the Jira attachments manifest file."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"kind": "require-file",
|
|
57
|
+
"path": {
|
|
58
|
+
"artifact": {
|
|
59
|
+
"kind": "jira-attachments-context-file",
|
|
60
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"message": "Jira fetch node did not produce the Jira attachments context file."
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "task-source-manual-flow",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"description": "Collects manual task input in the current project scope for subsequent normalization and planning. Stored input is reused on reruns and can be edited on interactive restart.",
|
|
5
|
+
"catalogVisibility": "hidden",
|
|
6
|
+
"phases": [
|
|
7
|
+
{
|
|
8
|
+
"id": "source",
|
|
9
|
+
"steps": [
|
|
10
|
+
{
|
|
11
|
+
"id": "edit_task_source",
|
|
12
|
+
"when": {
|
|
13
|
+
"all": [
|
|
14
|
+
{
|
|
15
|
+
"ref": "params.repromptInstantTaskInput"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"exists": {
|
|
19
|
+
"artifact": {
|
|
20
|
+
"kind": "instant-task-input-json-file",
|
|
21
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"node": "user-input",
|
|
28
|
+
"params": {
|
|
29
|
+
"formId": { "const": "instant-task-input" },
|
|
30
|
+
"title": { "const": "Instant Task Input" },
|
|
31
|
+
"description": {
|
|
32
|
+
"const": "Review and edit the saved instant-task request for this branch-derived lineage before restarting planning."
|
|
33
|
+
},
|
|
34
|
+
"submitLabel": { "const": "Restart planning" },
|
|
35
|
+
"fields": {
|
|
36
|
+
"list": [
|
|
37
|
+
{
|
|
38
|
+
"const": {
|
|
39
|
+
"id": "task_description",
|
|
40
|
+
"type": "text",
|
|
41
|
+
"label": "Task description",
|
|
42
|
+
"help": "Update the requested work for this restart. Leave the field empty to keep the current value.",
|
|
43
|
+
"required": true,
|
|
44
|
+
"multiline": true,
|
|
45
|
+
"rows": 5,
|
|
46
|
+
"placeholder": "e.g. add an instant-task command that runs planning, implementation, and review without Jira"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"const": {
|
|
51
|
+
"id": "additional_instructions",
|
|
52
|
+
"type": "text",
|
|
53
|
+
"label": "Additional instructions",
|
|
54
|
+
"help": "Update optional constraints, references, or implementation notes for this restart.",
|
|
55
|
+
"required": false,
|
|
56
|
+
"multiline": true,
|
|
57
|
+
"rows": 4,
|
|
58
|
+
"placeholder": "e.g. keep the existing Jira-backed flows unchanged, add tests for review routing"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"initialValues": { "ref": "params.prefilledInstantTaskInputValues" },
|
|
64
|
+
"outputFile": {
|
|
65
|
+
"artifact": {
|
|
66
|
+
"kind": "instant-task-input-json-file",
|
|
67
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"expect": [
|
|
72
|
+
{
|
|
73
|
+
"kind": "require-structured-artifacts",
|
|
74
|
+
"items": [
|
|
75
|
+
{
|
|
76
|
+
"path": {
|
|
77
|
+
"artifact": {
|
|
78
|
+
"kind": "instant-task-input-json-file",
|
|
79
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"schemaId": "user-input/v1"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"message": "Instant-task source input is missing or invalid."
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "collect_task_source",
|
|
91
|
+
"when": {
|
|
92
|
+
"not": {
|
|
93
|
+
"exists": {
|
|
94
|
+
"artifact": {
|
|
95
|
+
"kind": "instant-task-input-json-file",
|
|
96
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"node": "user-input",
|
|
102
|
+
"params": {
|
|
103
|
+
"formId": { "const": "instant-task-input" },
|
|
104
|
+
"title": { "const": "Instant Task Input" },
|
|
105
|
+
"description": {
|
|
106
|
+
"const": "Describe the task for this branch-derived lineage. The saved task input will be reused on reruns unless you choose interactive restart and edit it."
|
|
107
|
+
},
|
|
108
|
+
"submitLabel": { "const": "Start planning" },
|
|
109
|
+
"fields": {
|
|
110
|
+
"list": [
|
|
111
|
+
{
|
|
112
|
+
"const": {
|
|
113
|
+
"id": "task_description",
|
|
114
|
+
"type": "text",
|
|
115
|
+
"label": "Task description",
|
|
116
|
+
"help": "Describe the requested work. This text becomes the source-of-truth input for the instant-task lineage.",
|
|
117
|
+
"required": true,
|
|
118
|
+
"multiline": true,
|
|
119
|
+
"rows": 5,
|
|
120
|
+
"placeholder": "e.g. add an instant-task command that runs planning, implementation, and review without Jira"
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"const": {
|
|
125
|
+
"id": "additional_instructions",
|
|
126
|
+
"type": "text",
|
|
127
|
+
"label": "Additional instructions",
|
|
128
|
+
"help": "Optional extra constraints, references, or implementation notes for the same task lineage.",
|
|
129
|
+
"required": false,
|
|
130
|
+
"multiline": true,
|
|
131
|
+
"rows": 4,
|
|
132
|
+
"placeholder": "e.g. keep the existing Jira-backed flows unchanged, add tests for review routing"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
"outputFile": {
|
|
138
|
+
"artifact": {
|
|
139
|
+
"kind": "instant-task-input-json-file",
|
|
140
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"expect": [
|
|
145
|
+
{
|
|
146
|
+
"kind": "require-structured-artifacts",
|
|
147
|
+
"items": [
|
|
148
|
+
{
|
|
149
|
+
"path": {
|
|
150
|
+
"artifact": {
|
|
151
|
+
"kind": "instant-task-input-json-file",
|
|
152
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"schemaId": "user-input/v1"
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"message": "Instant-task source input is missing or invalid."
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": "validate_task_source_artifact",
|
|
164
|
+
"when": {
|
|
165
|
+
"all": [
|
|
166
|
+
{
|
|
167
|
+
"not": {
|
|
168
|
+
"ref": "params.repromptInstantTaskInput"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"exists": {
|
|
173
|
+
"artifact": {
|
|
174
|
+
"kind": "instant-task-input-json-file",
|
|
175
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"node": "file-check",
|
|
182
|
+
"params": {
|
|
183
|
+
"path": {
|
|
184
|
+
"artifact": {
|
|
185
|
+
"kind": "instant-task-input-json-file",
|
|
186
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"panelTitle": { "const": "Instant Task Source Artifact" },
|
|
190
|
+
"foundMessage": {
|
|
191
|
+
"const": "Validated the saved instant-task source artifact before continuing planning."
|
|
192
|
+
},
|
|
193
|
+
"tone": { "const": "cyan" }
|
|
194
|
+
},
|
|
195
|
+
"expect": [
|
|
196
|
+
{
|
|
197
|
+
"kind": "require-structured-artifacts",
|
|
198
|
+
"items": [
|
|
199
|
+
{
|
|
200
|
+
"path": {
|
|
201
|
+
"artifact": {
|
|
202
|
+
"kind": "instant-task-input-json-file",
|
|
203
|
+
"taskKey": { "ref": "params.taskKey" }
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"schemaId": "user-input/v1"
|
|
207
|
+
}
|
|
208
|
+
],
|
|
209
|
+
"message": "Instant-task source input is missing or invalid."
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
@@ -1,32 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
codex: ["gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex"],
|
|
4
|
-
opencode: ["opencode/minimax-m2.5-free", "minimax-coding-plan/MiniMax-M2.7", "zhipuai-coding-plan/glm-5.1", "zhipuai-coding-plan/glm-4.7"],
|
|
5
|
-
};
|
|
1
|
+
import { createExecutorRegistry } from "./registry.js";
|
|
2
|
+
const BUILT_IN_EXECUTOR_REGISTRY = createExecutorRegistry();
|
|
6
3
|
export const DEFAULT_EXECUTOR = "opencode";
|
|
7
|
-
export const DEFAULT_MODEL_BY_EXECUTOR = {
|
|
8
|
-
codex: "gpt-5.4",
|
|
9
|
-
opencode: "minimax-coding-plan/MiniMax-M2.7",
|
|
10
|
-
};
|
|
11
4
|
export const DEFAULT_LAUNCH_PROFILE = {
|
|
12
5
|
executor: DEFAULT_EXECUTOR,
|
|
13
|
-
model:
|
|
6
|
+
model: "minimax-coding-plan/MiniMax-M2.7",
|
|
14
7
|
};
|
|
15
|
-
|
|
16
|
-
return
|
|
8
|
+
function registryOrBuiltIn(executors) {
|
|
9
|
+
return executors ?? BUILT_IN_EXECUTOR_REGISTRY;
|
|
10
|
+
}
|
|
11
|
+
export function llmExecutorIds(executors) {
|
|
12
|
+
return registryOrBuiltIn(executors).llmExecutors().map((entry) => entry.id);
|
|
13
|
+
}
|
|
14
|
+
export function defaultModelForExecutor(executor, executors) {
|
|
15
|
+
const routing = registryOrBuiltIn(executors).getRouting(executor);
|
|
16
|
+
if (!routing || routing.kind !== "llm") {
|
|
17
|
+
throw new Error(`Unsupported llm executor '${executor}'.`);
|
|
18
|
+
}
|
|
19
|
+
return routing.defaultModel;
|
|
20
|
+
}
|
|
21
|
+
export function isLlmExecutorId(value, executors) {
|
|
22
|
+
const routing = registryOrBuiltIn(executors).getRouting(value);
|
|
23
|
+
return routing?.kind === "llm";
|
|
17
24
|
}
|
|
18
|
-
export function
|
|
19
|
-
|
|
25
|
+
export function isAllowedModelForExecutor(executor, model, executors) {
|
|
26
|
+
const routing = registryOrBuiltIn(executors).getRouting(executor);
|
|
27
|
+
return routing?.kind === "llm" ? routing.models.includes(model) : false;
|
|
20
28
|
}
|
|
21
|
-
export function
|
|
22
|
-
|
|
29
|
+
export function allowedModelsForExecutor(executor, executors) {
|
|
30
|
+
const routing = registryOrBuiltIn(executors).getRouting(executor);
|
|
31
|
+
if (!routing || routing.kind !== "llm") {
|
|
32
|
+
throw new Error(`Unsupported llm executor '${executor}'.`);
|
|
33
|
+
}
|
|
34
|
+
return [...routing.models];
|
|
23
35
|
}
|
|
24
|
-
export function resolveLaunchProfile(selection, fallback = DEFAULT_LAUNCH_PROFILE) {
|
|
36
|
+
export function resolveLaunchProfile(selection, fallback = DEFAULT_LAUNCH_PROFILE, executors) {
|
|
25
37
|
const executor = selection.executor === "default" ? fallback.executor : selection.executor;
|
|
26
38
|
const model = selection.model === "default"
|
|
27
39
|
? selection.executor === "default"
|
|
28
40
|
? fallback.model
|
|
29
|
-
: defaultModelForExecutor(executor)
|
|
41
|
+
: defaultModelForExecutor(executor, executors)
|
|
30
42
|
: selection.model;
|
|
31
43
|
return {
|
|
32
44
|
executor,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { buildFailureSummaryNode } from "./nodes/build-failure-summary-node.js";
|
|
2
2
|
import { buildReviewFixPromptNode } from "./nodes/build-review-fix-prompt-node.js";
|
|
3
|
+
import { clearReadyToMergeNode } from "./nodes/clear-ready-to-merge-node.js";
|
|
3
4
|
import { codexPromptNode } from "./nodes/codex-prompt-node.js";
|
|
4
5
|
import { commandCheckNode } from "./nodes/command-check-node.js";
|
|
5
6
|
import { commitMessageFormNode } from "./nodes/commit-message-form-node.js";
|
|
7
|
+
import { designReviewVerdictNode } from "./nodes/design-review-verdict-node.js";
|
|
6
8
|
import { ensureSummaryJsonNode } from "./nodes/ensure-summary-json-node.js";
|
|
7
9
|
import { fetchGitLabDiffNode } from "./nodes/fetch-gitlab-diff-node.js";
|
|
8
10
|
import { fetchGitLabReviewNode } from "./nodes/fetch-gitlab-review-node.js";
|
|
@@ -19,20 +21,62 @@ import { localScriptCheckNode } from "./nodes/local-script-check-node.js";
|
|
|
19
21
|
import { llmPromptNode } from "./nodes/llm-prompt-node.js";
|
|
20
22
|
import { opencodePromptNode } from "./nodes/opencode-prompt-node.js";
|
|
21
23
|
import { planCodexNode } from "./nodes/plan-codex-node.js";
|
|
24
|
+
import { planningBundleNode } from "./nodes/planning-bundle-node.js";
|
|
22
25
|
import { planningQuestionsFormNode } from "./nodes/planning-questions-form-node.js";
|
|
23
26
|
import { readFileNode } from "./nodes/read-file-node.js";
|
|
24
27
|
import { reviewFindingsFormNode } from "./nodes/review-findings-form-node.js";
|
|
28
|
+
import { reviewVerdictNode } from "./nodes/review-verdict-node.js";
|
|
25
29
|
import { selectFilesFormNode } from "./nodes/select-files-form-node.js";
|
|
30
|
+
import { structuredSummaryNode } from "./nodes/structured-summary-node.js";
|
|
26
31
|
import { summaryFileLoadNode } from "./nodes/summary-file-load-node.js";
|
|
27
32
|
import { telegramNotifierNode } from "./nodes/telegram-notifier-node.js";
|
|
28
33
|
import { userInputNode } from "./nodes/user-input-node.js";
|
|
29
34
|
import { writeSelectionFileNode } from "./nodes/write-selection-file-node.js";
|
|
35
|
+
import { TaskRunnerError } from "../errors.js";
|
|
36
|
+
export const BUILT_IN_NODE_KINDS = [
|
|
37
|
+
"build-failure-summary",
|
|
38
|
+
"build-review-fix-prompt",
|
|
39
|
+
"clear-ready-to-merge",
|
|
40
|
+
"codex-prompt",
|
|
41
|
+
"command-check",
|
|
42
|
+
"commit-message-form",
|
|
43
|
+
"design-review-verdict",
|
|
44
|
+
"ensure-summary-json",
|
|
45
|
+
"fetch-gitlab-diff",
|
|
46
|
+
"fetch-gitlab-review",
|
|
47
|
+
"file-check",
|
|
48
|
+
"flow-run",
|
|
49
|
+
"git-commit",
|
|
50
|
+
"git-commit-form",
|
|
51
|
+
"git-status",
|
|
52
|
+
"gitlab-review-artifacts",
|
|
53
|
+
"jira-context",
|
|
54
|
+
"jira-fetch",
|
|
55
|
+
"jira-issue-check",
|
|
56
|
+
"local-script-check",
|
|
57
|
+
"llm-prompt",
|
|
58
|
+
"opencode-prompt",
|
|
59
|
+
"plan-codex",
|
|
60
|
+
"planning-bundle",
|
|
61
|
+
"planning-questions-form",
|
|
62
|
+
"read-file",
|
|
63
|
+
"review-findings-form",
|
|
64
|
+
"review-verdict",
|
|
65
|
+
"select-files-form",
|
|
66
|
+
"structured-summary",
|
|
67
|
+
"summary-file-load",
|
|
68
|
+
"telegram-notify",
|
|
69
|
+
"user-input",
|
|
70
|
+
"write-selection-file",
|
|
71
|
+
];
|
|
30
72
|
const builtInNodes = {
|
|
31
73
|
"build-failure-summary": buildFailureSummaryNode,
|
|
32
74
|
"build-review-fix-prompt": buildReviewFixPromptNode,
|
|
75
|
+
"clear-ready-to-merge": clearReadyToMergeNode,
|
|
33
76
|
"codex-prompt": codexPromptNode,
|
|
34
77
|
"command-check": commandCheckNode,
|
|
35
78
|
"commit-message-form": commitMessageFormNode,
|
|
79
|
+
"design-review-verdict": designReviewVerdictNode,
|
|
36
80
|
"ensure-summary-json": ensureSummaryJsonNode,
|
|
37
81
|
"fetch-gitlab-diff": fetchGitLabDiffNode,
|
|
38
82
|
"fetch-gitlab-review": fetchGitLabReviewNode,
|
|
@@ -49,10 +93,13 @@ const builtInNodes = {
|
|
|
49
93
|
"llm-prompt": llmPromptNode,
|
|
50
94
|
"opencode-prompt": opencodePromptNode,
|
|
51
95
|
"plan-codex": planCodexNode,
|
|
96
|
+
"planning-bundle": planningBundleNode,
|
|
52
97
|
"planning-questions-form": planningQuestionsFormNode,
|
|
53
98
|
"read-file": readFileNode,
|
|
54
99
|
"review-findings-form": reviewFindingsFormNode,
|
|
100
|
+
"review-verdict": reviewVerdictNode,
|
|
55
101
|
"select-files-form": selectFilesFormNode,
|
|
102
|
+
"structured-summary": structuredSummaryNode,
|
|
56
103
|
"summary-file-load": summaryFileLoadNode,
|
|
57
104
|
"telegram-notify": telegramNotifierNode,
|
|
58
105
|
"user-input": userInputNode,
|
|
@@ -72,6 +119,12 @@ const builtInNodeMetadata = {
|
|
|
72
119
|
prompt: "forbidden",
|
|
73
120
|
requiredParams: ["selectionFile", "autoMode"],
|
|
74
121
|
},
|
|
122
|
+
"clear-ready-to-merge": {
|
|
123
|
+
kind: "clear-ready-to-merge",
|
|
124
|
+
version: 1,
|
|
125
|
+
prompt: "forbidden",
|
|
126
|
+
requiredParams: ["taskKey"],
|
|
127
|
+
},
|
|
75
128
|
"codex-prompt": {
|
|
76
129
|
kind: "codex-prompt",
|
|
77
130
|
version: 1,
|
|
@@ -92,6 +145,12 @@ const builtInNodeMetadata = {
|
|
|
92
145
|
prompt: "forbidden",
|
|
93
146
|
requiredParams: ["commitMessageFile", "formId", "title", "outputFile"],
|
|
94
147
|
},
|
|
148
|
+
"design-review-verdict": {
|
|
149
|
+
kind: "design-review-verdict",
|
|
150
|
+
version: 1,
|
|
151
|
+
prompt: "forbidden",
|
|
152
|
+
requiredParams: ["taskKey"],
|
|
153
|
+
},
|
|
95
154
|
"ensure-summary-json": {
|
|
96
155
|
kind: "ensure-summary-json",
|
|
97
156
|
version: 1,
|
|
@@ -158,7 +217,7 @@ const builtInNodeMetadata = {
|
|
|
158
217
|
kind: "llm-prompt",
|
|
159
218
|
version: 1,
|
|
160
219
|
prompt: "required",
|
|
161
|
-
requiredParams: ["labelText"
|
|
220
|
+
requiredParams: ["labelText"],
|
|
162
221
|
executors: ["codex", "opencode"],
|
|
163
222
|
},
|
|
164
223
|
"opencode-prompt": { kind: "opencode-prompt", version: 1, prompt: "required", requiredParams: ["labelText"] },
|
|
@@ -169,6 +228,12 @@ const builtInNodeMetadata = {
|
|
|
169
228
|
requiredParams: ["prompt", "requiredArtifacts"],
|
|
170
229
|
executors: ["codex"],
|
|
171
230
|
},
|
|
231
|
+
"planning-bundle": {
|
|
232
|
+
kind: "planning-bundle",
|
|
233
|
+
version: 1,
|
|
234
|
+
prompt: "forbidden",
|
|
235
|
+
requiredParams: ["taskKey"],
|
|
236
|
+
},
|
|
172
237
|
"planning-questions-form": {
|
|
173
238
|
kind: "planning-questions-form",
|
|
174
239
|
version: 1,
|
|
@@ -182,12 +247,24 @@ const builtInNodeMetadata = {
|
|
|
182
247
|
prompt: "forbidden",
|
|
183
248
|
requiredParams: ["reviewFindingsJsonFile", "formId", "title"],
|
|
184
249
|
},
|
|
250
|
+
"review-verdict": {
|
|
251
|
+
kind: "review-verdict",
|
|
252
|
+
version: 1,
|
|
253
|
+
prompt: "forbidden",
|
|
254
|
+
requiredParams: ["taskKey"],
|
|
255
|
+
},
|
|
185
256
|
"select-files-form": {
|
|
186
257
|
kind: "select-files-form",
|
|
187
258
|
version: 1,
|
|
188
259
|
prompt: "forbidden",
|
|
189
260
|
requiredParams: ["gitStatusJsonFile", "formId", "title", "outputFile"],
|
|
190
261
|
},
|
|
262
|
+
"structured-summary": {
|
|
263
|
+
kind: "structured-summary",
|
|
264
|
+
version: 1,
|
|
265
|
+
prompt: "forbidden",
|
|
266
|
+
requiredParams: ["path"],
|
|
267
|
+
},
|
|
191
268
|
"summary-file-load": { kind: "summary-file-load", version: 1, prompt: "forbidden", requiredParams: ["path"] },
|
|
192
269
|
"telegram-notify": {
|
|
193
270
|
kind: "telegram-notify",
|
|
@@ -209,19 +286,51 @@ const builtInNodeMetadata = {
|
|
|
209
286
|
requiredParams: ["outputFile", "reviewFindingsJsonFile", "selectionMode"],
|
|
210
287
|
},
|
|
211
288
|
};
|
|
212
|
-
|
|
289
|
+
function coreOwner(id) {
|
|
290
|
+
return {
|
|
291
|
+
kind: "core",
|
|
292
|
+
id: `core:${id}`,
|
|
293
|
+
manifestPath: "built-in node registry",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
export function createNodeRegistry(pluginNodes = []) {
|
|
297
|
+
const definitions = new Map(Object.entries(builtInNodes));
|
|
298
|
+
const metadata = new Map(Object.entries(builtInNodeMetadata));
|
|
299
|
+
const owners = new Map(Object.keys(builtInNodes).map((id) => [id, coreOwner(id)]));
|
|
300
|
+
for (const registration of pluginNodes) {
|
|
301
|
+
const existingOwner = owners.get(registration.id);
|
|
302
|
+
if (existingOwner) {
|
|
303
|
+
throw new TaskRunnerError(`Duplicate node id '${registration.id}' conflicts between ${existingOwner.id} (${existingOwner.manifestPath}) and plugin '${registration.pluginId}' (${registration.manifestPath}).`);
|
|
304
|
+
}
|
|
305
|
+
definitions.set(registration.id, registration.definition);
|
|
306
|
+
metadata.set(registration.id, registration.metadata);
|
|
307
|
+
owners.set(registration.id, {
|
|
308
|
+
kind: "plugin",
|
|
309
|
+
id: registration.pluginId,
|
|
310
|
+
manifestPath: registration.manifestPath,
|
|
311
|
+
entrypointPath: registration.entrypointPath,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
213
314
|
return {
|
|
214
315
|
get(kind) {
|
|
215
|
-
|
|
316
|
+
const definition = definitions.get(kind);
|
|
317
|
+
if (!definition) {
|
|
318
|
+
throw new TaskRunnerError(`Unknown node kind '${kind}'.`);
|
|
319
|
+
}
|
|
320
|
+
return definition;
|
|
216
321
|
},
|
|
217
322
|
getMeta(kind) {
|
|
218
|
-
|
|
323
|
+
const definition = metadata.get(kind);
|
|
324
|
+
if (!definition) {
|
|
325
|
+
throw new TaskRunnerError(`Unknown node metadata '${kind}'.`);
|
|
326
|
+
}
|
|
327
|
+
return definition;
|
|
219
328
|
},
|
|
220
329
|
has(kind) {
|
|
221
|
-
return kind
|
|
330
|
+
return definitions.has(kind);
|
|
222
331
|
},
|
|
223
332
|
kinds() {
|
|
224
|
-
return
|
|
333
|
+
return [...definitions.keys()];
|
|
225
334
|
},
|
|
226
335
|
};
|
|
227
336
|
}
|