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.
Files changed (50) hide show
  1. package/README.md +54 -6
  2. package/dist/artifacts.js +9 -0
  3. package/dist/executors/git-commit-executor.js +24 -6
  4. package/dist/flow-state.js +3 -8
  5. package/dist/git/git-diff-parser.js +223 -0
  6. package/dist/git/git-service.js +562 -0
  7. package/dist/git/git-stage-selection.js +24 -0
  8. package/dist/git/git-status-parser.js +171 -0
  9. package/dist/git/git-types.js +1 -0
  10. package/dist/index.js +454 -108
  11. package/dist/interactive/auto-flow.js +644 -0
  12. package/dist/interactive/controller.js +489 -7
  13. package/dist/interactive/progress.js +194 -1
  14. package/dist/interactive/state.js +34 -0
  15. package/dist/interactive/web/index.js +237 -5
  16. package/dist/interactive/web/protocol.js +222 -1
  17. package/dist/interactive/web/server.js +497 -3
  18. package/dist/interactive/web/static/app.js +2462 -37
  19. package/dist/interactive/web/static/index.html +113 -11
  20. package/dist/interactive/web/static/styles.css +1 -1
  21. package/dist/interactive/web/static/styles.input.css +1383 -149
  22. package/dist/pipeline/auto-flow-blocks.js +307 -0
  23. package/dist/pipeline/auto-flow-config.js +273 -0
  24. package/dist/pipeline/auto-flow-identity.js +49 -0
  25. package/dist/pipeline/auto-flow-presets.js +52 -0
  26. package/dist/pipeline/auto-flow-resolver.js +830 -0
  27. package/dist/pipeline/auto-flow-types.js +17 -0
  28. package/dist/pipeline/context.js +1 -0
  29. package/dist/pipeline/declarative-flows.js +27 -1
  30. package/dist/pipeline/flow-specs/auto-common-guided.json +11 -0
  31. package/dist/pipeline/flow-specs/auto-golang.json +12 -1
  32. package/dist/pipeline/flow-specs/bugz/bug-analyze.json +54 -1
  33. package/dist/pipeline/flow-specs/gitlab/gitlab-diff-review.json +19 -1
  34. package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +33 -1
  35. package/dist/pipeline/flow-specs/review/review-project.json +19 -1
  36. package/dist/pipeline/flow-specs/task-source/manual-jira-input.json +70 -0
  37. package/dist/pipeline/node-registry.js +9 -0
  38. package/dist/pipeline/nodes/codex-prompt-node.js +8 -1
  39. package/dist/pipeline/nodes/flow-run-node.js +5 -3
  40. package/dist/pipeline/nodes/git-status-node.js +2 -168
  41. package/dist/pipeline/nodes/manual-jira-task-input-node.js +146 -0
  42. package/dist/pipeline/nodes/opencode-prompt-node.js +8 -1
  43. package/dist/pipeline/nodes/plan-codex-node.js +8 -1
  44. package/dist/pipeline/spec-loader.js +14 -4
  45. package/dist/runtime/artifact-catalog.js +403 -0
  46. package/dist/runtime/settings.js +114 -0
  47. package/dist/scope.js +14 -4
  48. package/package.json +1 -1
  49. package/dist/pipeline/flow-specs/auto-common.json +0 -179
  50. 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" || parsed.type === "form.cancel" || parsed.type === "log.clear") {
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.");