agentweaver 0.1.18 → 0.1.20
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 +54 -6
- package/dist/artifacts.js +9 -0
- package/dist/executors/git-commit-executor.js +24 -6
- package/dist/flow-state.js +3 -8
- package/dist/git/git-diff-parser.js +223 -0
- package/dist/git/git-service.js +562 -0
- package/dist/git/git-stage-selection.js +24 -0
- package/dist/git/git-status-parser.js +171 -0
- package/dist/git/git-types.js +1 -0
- package/dist/index.js +454 -108
- package/dist/interactive/auto-flow.js +644 -0
- package/dist/interactive/controller.js +489 -7
- package/dist/interactive/progress.js +194 -1
- package/dist/interactive/state.js +34 -0
- package/dist/interactive/web/index.js +237 -5
- package/dist/interactive/web/protocol.js +222 -1
- package/dist/interactive/web/server.js +497 -3
- package/dist/interactive/web/static/app.js +2462 -37
- package/dist/interactive/web/static/index.html +113 -11
- package/dist/interactive/web/static/styles.css +1 -1
- package/dist/interactive/web/static/styles.input.css +1383 -149
- package/dist/pipeline/auto-flow-blocks.js +307 -0
- package/dist/pipeline/auto-flow-config.js +273 -0
- package/dist/pipeline/auto-flow-identity.js +49 -0
- package/dist/pipeline/auto-flow-presets.js +52 -0
- package/dist/pipeline/auto-flow-resolver.js +830 -0
- package/dist/pipeline/auto-flow-types.js +17 -0
- package/dist/pipeline/context.js +1 -0
- package/dist/pipeline/declarative-flows.js +27 -1
- package/dist/pipeline/flow-specs/auto-common-guided.json +11 -0
- package/dist/pipeline/flow-specs/auto-golang.json +12 -1
- package/dist/pipeline/flow-specs/bugz/bug-analyze.json +54 -1
- package/dist/pipeline/flow-specs/gitlab/gitlab-diff-review.json +19 -1
- package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +33 -1
- package/dist/pipeline/flow-specs/review/review-project.json +19 -1
- package/dist/pipeline/flow-specs/task-source/manual-jira-input.json +70 -0
- package/dist/pipeline/node-registry.js +9 -0
- package/dist/pipeline/nodes/codex-prompt-node.js +8 -1
- package/dist/pipeline/nodes/flow-run-node.js +5 -3
- package/dist/pipeline/nodes/git-status-node.js +2 -168
- package/dist/pipeline/nodes/manual-jira-task-input-node.js +146 -0
- package/dist/pipeline/nodes/opencode-prompt-node.js +8 -1
- package/dist/pipeline/nodes/plan-codex-node.js +8 -1
- package/dist/pipeline/spec-loader.js +14 -4
- package/dist/runtime/artifact-catalog.js +403 -0
- package/dist/runtime/settings.js +114 -0
- package/dist/scope.js +14 -4
- package/package.json +1 -1
- package/dist/pipeline/flow-specs/auto-common.json +0 -179
- package/dist/pipeline/flow-specs/auto-simple.json +0 -141
|
@@ -12,6 +12,27 @@ const ACTION_TYPES = new Set([
|
|
|
12
12
|
"interrupt.openConfirm",
|
|
13
13
|
"flow.interrupt",
|
|
14
14
|
"log.clear",
|
|
15
|
+
"artifactExplorer.open",
|
|
16
|
+
"artifactExplorer.close",
|
|
17
|
+
"autoFlow.selectPreset",
|
|
18
|
+
"autoFlow.loadConfig",
|
|
19
|
+
"autoFlow.save",
|
|
20
|
+
"autoFlow.reset",
|
|
21
|
+
"autoFlow.toggleBlock",
|
|
22
|
+
"autoFlow.updateParam",
|
|
23
|
+
"autoFlow.insertBlock",
|
|
24
|
+
"autoFlow.removeBlock",
|
|
25
|
+
"git.refresh",
|
|
26
|
+
"git.createBranch",
|
|
27
|
+
"git.checkout",
|
|
28
|
+
"git.fetch",
|
|
29
|
+
"git.pullFfOnly",
|
|
30
|
+
"git.stage",
|
|
31
|
+
"git.unstage",
|
|
32
|
+
"git.updateCommitMessage",
|
|
33
|
+
"git.commit",
|
|
34
|
+
"git.push",
|
|
35
|
+
"settings.update",
|
|
15
36
|
"help.toggle",
|
|
16
37
|
"scroll",
|
|
17
38
|
]);
|
|
@@ -51,6 +72,62 @@ function optionalInteger(value, fieldName) {
|
|
|
51
72
|
}
|
|
52
73
|
return field;
|
|
53
74
|
}
|
|
75
|
+
function optionalBoolean(value, fieldName) {
|
|
76
|
+
if (value[fieldName] === undefined) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const field = value[fieldName];
|
|
80
|
+
if (typeof field !== "boolean") {
|
|
81
|
+
throw new Error(`${fieldName} must be a boolean.`);
|
|
82
|
+
}
|
|
83
|
+
return field;
|
|
84
|
+
}
|
|
85
|
+
function requireSettingsPatch(value) {
|
|
86
|
+
const settings = value.settings;
|
|
87
|
+
if (!isRecord(settings)) {
|
|
88
|
+
throw new Error("settings must be an object.");
|
|
89
|
+
}
|
|
90
|
+
const allowed = new Set(["theme", "autoFlowHeight", "workspaceSplit", "logAutoscroll"]);
|
|
91
|
+
for (const key of Object.keys(settings)) {
|
|
92
|
+
if (!allowed.has(key)) {
|
|
93
|
+
throw new Error(`Unsupported settings key: ${key}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const patch = {};
|
|
97
|
+
if ("theme" in settings) {
|
|
98
|
+
const theme = settings.theme;
|
|
99
|
+
if (theme !== "dark" && theme !== "light") {
|
|
100
|
+
throw new Error("settings.theme must be light or dark.");
|
|
101
|
+
}
|
|
102
|
+
patch.theme = theme;
|
|
103
|
+
}
|
|
104
|
+
if ("autoFlowHeight" in settings) {
|
|
105
|
+
const autoFlowHeight = settings.autoFlowHeight;
|
|
106
|
+
if (autoFlowHeight !== null
|
|
107
|
+
&& (typeof autoFlowHeight !== "number" || !Number.isFinite(autoFlowHeight))) {
|
|
108
|
+
throw new Error("settings.autoFlowHeight must be a finite number or null.");
|
|
109
|
+
}
|
|
110
|
+
patch.autoFlowHeight = autoFlowHeight;
|
|
111
|
+
}
|
|
112
|
+
if ("workspaceSplit" in settings) {
|
|
113
|
+
const workspaceSplit = settings.workspaceSplit;
|
|
114
|
+
if (typeof workspaceSplit !== "number" || !Number.isFinite(workspaceSplit)) {
|
|
115
|
+
throw new Error("settings.workspaceSplit must be a finite number.");
|
|
116
|
+
}
|
|
117
|
+
patch.workspaceSplit = workspaceSplit;
|
|
118
|
+
}
|
|
119
|
+
if ("logAutoscroll" in settings) {
|
|
120
|
+
const logAutoscroll = settings.logAutoscroll;
|
|
121
|
+
if (typeof logAutoscroll !== "boolean") {
|
|
122
|
+
throw new Error("settings.logAutoscroll must be a boolean.");
|
|
123
|
+
}
|
|
124
|
+
patch.logAutoscroll = logAutoscroll;
|
|
125
|
+
}
|
|
126
|
+
if (Object.keys(patch).length === 0) {
|
|
127
|
+
throw new Error("settings.update requires at least one setting.");
|
|
128
|
+
}
|
|
129
|
+
return patch;
|
|
130
|
+
}
|
|
54
131
|
function requireValues(value, fieldName = "values") {
|
|
55
132
|
const values = value[fieldName];
|
|
56
133
|
if (!isRecord(values)) {
|
|
@@ -58,6 +135,26 @@ function requireValues(value, fieldName = "values") {
|
|
|
58
135
|
}
|
|
59
136
|
return values;
|
|
60
137
|
}
|
|
138
|
+
function requireStringArray(value, fieldName) {
|
|
139
|
+
const field = value[fieldName];
|
|
140
|
+
if (!Array.isArray(field) || field.some((item) => typeof item !== "string" || item.length === 0)) {
|
|
141
|
+
throw new Error(`${fieldName} must be an array of non-empty strings.`);
|
|
142
|
+
}
|
|
143
|
+
return field;
|
|
144
|
+
}
|
|
145
|
+
function optionalStringArray(value, fieldName) {
|
|
146
|
+
if (value[fieldName] === undefined) {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
return requireStringArray(value, fieldName);
|
|
150
|
+
}
|
|
151
|
+
function requireCommitMessage(value) {
|
|
152
|
+
const message = value.message;
|
|
153
|
+
if (typeof message !== "string" || message.trim().length === 0) {
|
|
154
|
+
throw new Error("message must be a non-empty string.");
|
|
155
|
+
}
|
|
156
|
+
return message;
|
|
157
|
+
}
|
|
61
158
|
export function parseClientAction(raw) {
|
|
62
159
|
let parsed;
|
|
63
160
|
try {
|
|
@@ -96,7 +193,15 @@ export function parseClientAction(raw) {
|
|
|
96
193
|
const action = optionalNonEmptyString(parsed, "action");
|
|
97
194
|
return { type: "confirm.accept", ...(action ? { action } : {}), ...(actionId ? { actionId } : {}) };
|
|
98
195
|
}
|
|
99
|
-
if (parsed.type === "confirm.cancel"
|
|
196
|
+
if (parsed.type === "confirm.cancel"
|
|
197
|
+
|| parsed.type === "form.cancel"
|
|
198
|
+
|| parsed.type === "log.clear"
|
|
199
|
+
|| parsed.type === "artifactExplorer.open"
|
|
200
|
+
|| parsed.type === "artifactExplorer.close"
|
|
201
|
+
|| parsed.type === "git.refresh"
|
|
202
|
+
|| parsed.type === "git.fetch"
|
|
203
|
+
|| parsed.type === "git.pullFfOnly"
|
|
204
|
+
|| parsed.type === "git.push") {
|
|
100
205
|
return { type: parsed.type, ...(actionId ? { actionId } : {}) };
|
|
101
206
|
}
|
|
102
207
|
if (parsed.type === "form.update") {
|
|
@@ -129,12 +234,128 @@ export function parseClientAction(raw) {
|
|
|
129
234
|
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
130
235
|
return { type: "flow.interrupt", ...(flowId ? { flowId } : {}), ...(actionId ? { actionId } : {}) };
|
|
131
236
|
}
|
|
237
|
+
if (parsed.type === "autoFlow.selectPreset") {
|
|
238
|
+
const preset = requireNonEmptyString(parsed, "preset");
|
|
239
|
+
if (preset !== "simple" && preset !== "standard") {
|
|
240
|
+
throw new Error("preset must be simple or standard.");
|
|
241
|
+
}
|
|
242
|
+
return { type: "autoFlow.selectPreset", preset, ...(actionId ? { actionId } : {}) };
|
|
243
|
+
}
|
|
244
|
+
if (parsed.type === "autoFlow.loadConfig") {
|
|
245
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
246
|
+
return {
|
|
247
|
+
type: "autoFlow.loadConfig",
|
|
248
|
+
name: requireNonEmptyString(parsed, "name"),
|
|
249
|
+
...(flowId ? { flowId } : {}),
|
|
250
|
+
...(actionId ? { actionId } : {}),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
if (parsed.type === "autoFlow.save") {
|
|
254
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
255
|
+
const name = optionalNonEmptyString(parsed, "name");
|
|
256
|
+
const location = optionalNonEmptyString(parsed, "location");
|
|
257
|
+
if (location !== undefined && location !== "project" && location !== "user") {
|
|
258
|
+
throw new Error("location must be project or user.");
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
type: "autoFlow.save",
|
|
262
|
+
...(flowId ? { flowId } : {}),
|
|
263
|
+
...(name ? { name } : {}),
|
|
264
|
+
...(location ? { location } : {}),
|
|
265
|
+
...(actionId ? { actionId } : {}),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (parsed.type === "autoFlow.reset") {
|
|
269
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
270
|
+
return { type: "autoFlow.reset", ...(flowId ? { flowId } : {}), ...(actionId ? { actionId } : {}) };
|
|
271
|
+
}
|
|
272
|
+
if (parsed.type === "autoFlow.toggleBlock") {
|
|
273
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
274
|
+
const slotId = optionalNonEmptyString(parsed, "slotId");
|
|
275
|
+
const enabled = optionalBoolean(parsed, "enabled");
|
|
276
|
+
return {
|
|
277
|
+
type: "autoFlow.toggleBlock",
|
|
278
|
+
...(flowId ? { flowId } : {}),
|
|
279
|
+
...(slotId ? { slotId } : {}),
|
|
280
|
+
blockId: requireNonEmptyString(parsed, "blockId"),
|
|
281
|
+
...(enabled !== undefined ? { enabled } : {}),
|
|
282
|
+
...(actionId ? { actionId } : {}),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (parsed.type === "autoFlow.updateParam") {
|
|
286
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
287
|
+
const slotId = optionalNonEmptyString(parsed, "slotId");
|
|
288
|
+
return {
|
|
289
|
+
type: "autoFlow.updateParam",
|
|
290
|
+
...(flowId ? { flowId } : {}),
|
|
291
|
+
...(slotId ? { slotId } : {}),
|
|
292
|
+
blockId: requireNonEmptyString(parsed, "blockId"),
|
|
293
|
+
paramName: requireNonEmptyString(parsed, "paramName"),
|
|
294
|
+
value: optionalInteger(parsed, "value") ?? (() => {
|
|
295
|
+
throw new Error("value must be an integer.");
|
|
296
|
+
})(),
|
|
297
|
+
...(actionId ? { actionId } : {}),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
if (parsed.type === "autoFlow.insertBlock") {
|
|
301
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
302
|
+
return {
|
|
303
|
+
type: "autoFlow.insertBlock",
|
|
304
|
+
...(flowId ? { flowId } : {}),
|
|
305
|
+
slotId: requireNonEmptyString(parsed, "slotId"),
|
|
306
|
+
blockId: requireNonEmptyString(parsed, "blockId"),
|
|
307
|
+
...(actionId ? { actionId } : {}),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
if (parsed.type === "autoFlow.removeBlock") {
|
|
311
|
+
const flowId = optionalNonEmptyString(parsed, "flowId");
|
|
312
|
+
return {
|
|
313
|
+
type: "autoFlow.removeBlock",
|
|
314
|
+
...(flowId ? { flowId } : {}),
|
|
315
|
+
slotId: requireNonEmptyString(parsed, "slotId"),
|
|
316
|
+
blockId: requireNonEmptyString(parsed, "blockId"),
|
|
317
|
+
...(actionId ? { actionId } : {}),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
132
320
|
if (parsed.type === "help.toggle") {
|
|
133
321
|
if (parsed.visible !== undefined && typeof parsed.visible !== "boolean") {
|
|
134
322
|
throw new Error("visible must be a boolean when provided.");
|
|
135
323
|
}
|
|
136
324
|
return { type: "help.toggle", ...(parsed.visible !== undefined ? { visible: parsed.visible } : {}), ...(actionId ? { actionId } : {}) };
|
|
137
325
|
}
|
|
326
|
+
if (parsed.type === "git.createBranch") {
|
|
327
|
+
if ("selectedBase" in parsed || "base" in parsed || "baseBranch" in parsed) {
|
|
328
|
+
throw new Error("git.createBranch does not accept a selected base in the MVP.");
|
|
329
|
+
}
|
|
330
|
+
return { type: "git.createBranch", branchName: requireNonEmptyString(parsed, "branchName"), ...(actionId ? { actionId } : {}) };
|
|
331
|
+
}
|
|
332
|
+
if (parsed.type === "git.checkout") {
|
|
333
|
+
return { type: "git.checkout", branchName: requireNonEmptyString(parsed, "branchName"), ...(actionId ? { actionId } : {}) };
|
|
334
|
+
}
|
|
335
|
+
if (parsed.type === "git.stage") {
|
|
336
|
+
return { type: "git.stage", paths: requireStringArray(parsed, "paths"), ...(actionId ? { actionId } : {}) };
|
|
337
|
+
}
|
|
338
|
+
if (parsed.type === "git.unstage") {
|
|
339
|
+
return { type: "git.unstage", paths: requireStringArray(parsed, "paths"), ...(actionId ? { actionId } : {}) };
|
|
340
|
+
}
|
|
341
|
+
if (parsed.type === "git.updateCommitMessage") {
|
|
342
|
+
if (typeof parsed.message !== "string") {
|
|
343
|
+
throw new Error("message must be a string.");
|
|
344
|
+
}
|
|
345
|
+
return { type: "git.updateCommitMessage", message: parsed.message, ...(actionId ? { actionId } : {}) };
|
|
346
|
+
}
|
|
347
|
+
if (parsed.type === "git.commit") {
|
|
348
|
+
const paths = optionalStringArray(parsed, "paths");
|
|
349
|
+
return {
|
|
350
|
+
type: "git.commit",
|
|
351
|
+
message: requireCommitMessage(parsed),
|
|
352
|
+
...(paths !== undefined ? { paths } : {}),
|
|
353
|
+
...(actionId ? { actionId } : {}),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
if (parsed.type === "settings.update") {
|
|
357
|
+
return { type: "settings.update", settings: requireSettingsPatch(parsed), ...(actionId ? { actionId } : {}) };
|
|
358
|
+
}
|
|
138
359
|
const pane = requireNonEmptyString(parsed, "pane");
|
|
139
360
|
if (!SCROLL_PANES.has(pane)) {
|
|
140
361
|
throw new Error("scroll pane must be one of flows, progress, summary, log, or help.");
|