@synergenius/flow-weaver-pack-weaver 0.9.152 → 0.9.154

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 (104) hide show
  1. package/dist/ai-chat-provider.js +4 -4
  2. package/dist/ai-chat-provider.js.map +1 -1
  3. package/dist/bot/ai-client.d.ts +30 -0
  4. package/dist/bot/ai-client.d.ts.map +1 -1
  5. package/dist/bot/ai-client.js +37 -0
  6. package/dist/bot/ai-client.js.map +1 -1
  7. package/dist/bot/behavior-defaults.d.ts.map +1 -1
  8. package/dist/bot/behavior-defaults.js +7 -2
  9. package/dist/bot/behavior-defaults.js.map +1 -1
  10. package/dist/bot/capability-registry.d.ts.map +1 -1
  11. package/dist/bot/capability-registry.js +46 -33
  12. package/dist/bot/capability-registry.js.map +1 -1
  13. package/dist/bot/file-validator.d.ts +7 -0
  14. package/dist/bot/file-validator.d.ts.map +1 -1
  15. package/dist/bot/file-validator.js +76 -0
  16. package/dist/bot/file-validator.js.map +1 -1
  17. package/dist/bot/instance-manager.d.ts +22 -7
  18. package/dist/bot/instance-manager.d.ts.map +1 -1
  19. package/dist/bot/instance-manager.js +69 -7
  20. package/dist/bot/instance-manager.js.map +1 -1
  21. package/dist/bot/orchestrator.d.ts +11 -9
  22. package/dist/bot/orchestrator.d.ts.map +1 -1
  23. package/dist/bot/orchestrator.js +56 -107
  24. package/dist/bot/orchestrator.js.map +1 -1
  25. package/dist/bot/runner.d.ts +29 -0
  26. package/dist/bot/runner.d.ts.map +1 -1
  27. package/dist/bot/runner.js +114 -73
  28. package/dist/bot/runner.js.map +1 -1
  29. package/dist/bot/step-executor.d.ts.map +1 -1
  30. package/dist/bot/step-executor.js +28 -9
  31. package/dist/bot/step-executor.js.map +1 -1
  32. package/dist/bot/swarm-controller.d.ts +7 -6
  33. package/dist/bot/swarm-controller.d.ts.map +1 -1
  34. package/dist/bot/swarm-controller.js +64 -74
  35. package/dist/bot/swarm-controller.js.map +1 -1
  36. package/dist/bot/system-prompt.d.ts.map +1 -1
  37. package/dist/bot/system-prompt.js +2 -0
  38. package/dist/bot/system-prompt.js.map +1 -1
  39. package/dist/bot/task-types.d.ts +1 -0
  40. package/dist/bot/task-types.d.ts.map +1 -1
  41. package/dist/bot/weaver-tools.d.ts +1 -1
  42. package/dist/bot/weaver-tools.d.ts.map +1 -1
  43. package/dist/bot/weaver-tools.js +12 -1
  44. package/dist/bot/weaver-tools.js.map +1 -1
  45. package/dist/node-types/agent-execute.js +2 -2
  46. package/dist/node-types/agent-execute.js.map +1 -1
  47. package/dist/node-types/bot-report.d.ts.map +1 -1
  48. package/dist/node-types/bot-report.js +5 -2
  49. package/dist/node-types/bot-report.js.map +1 -1
  50. package/dist/node-types/build-context.d.ts.map +1 -1
  51. package/dist/node-types/build-context.js +13 -1
  52. package/dist/node-types/build-context.js.map +1 -1
  53. package/dist/node-types/exec-validate-retry.d.ts +3 -3
  54. package/dist/node-types/exec-validate-retry.d.ts.map +1 -1
  55. package/dist/node-types/exec-validate-retry.js +13 -184
  56. package/dist/node-types/exec-validate-retry.js.map +1 -1
  57. package/dist/node-types/load-config.d.ts +1 -0
  58. package/dist/node-types/load-config.d.ts.map +1 -1
  59. package/dist/node-types/load-config.js +1 -0
  60. package/dist/node-types/load-config.js.map +1 -1
  61. package/dist/node-types/plan-task.d.ts +7 -5
  62. package/dist/node-types/plan-task.d.ts.map +1 -1
  63. package/dist/node-types/plan-task.js +282 -83
  64. package/dist/node-types/plan-task.js.map +1 -1
  65. package/dist/ui/bot-panel.js +1 -1
  66. package/dist/ui/capability-editor.js +46 -33
  67. package/dist/ui/chat-task-result.js +7 -7
  68. package/dist/ui/profile-editor.js +44 -31
  69. package/dist/ui/swarm-dashboard.js +80 -47
  70. package/dist/ui/task-detail-view.js +31 -11
  71. package/dist/ui/task-editor.js +1 -1
  72. package/dist/ui/task-pool-list.js +1 -1
  73. package/dist/workflows/weaver-bot.d.ts +5 -4
  74. package/dist/workflows/weaver-bot.d.ts.map +1 -1
  75. package/dist/workflows/weaver-bot.js +8 -7
  76. package/dist/workflows/weaver-bot.js.map +1 -1
  77. package/flowweaver.manifest.json +1 -1
  78. package/package.json +1 -1
  79. package/src/ai-chat-provider.ts +4 -4
  80. package/src/bot/ai-client.ts +65 -0
  81. package/src/bot/behavior-defaults.ts +5 -2
  82. package/src/bot/capability-registry.ts +46 -33
  83. package/src/bot/file-validator.ts +97 -0
  84. package/src/bot/instance-manager.ts +77 -7
  85. package/src/bot/orchestrator.ts +63 -126
  86. package/src/bot/runner.ts +124 -70
  87. package/src/bot/step-executor.ts +30 -9
  88. package/src/bot/swarm-controller.ts +65 -76
  89. package/src/bot/system-prompt.ts +2 -0
  90. package/src/bot/task-types.ts +1 -0
  91. package/src/bot/weaver-tools.ts +14 -1
  92. package/src/node-types/agent-execute.ts +2 -2
  93. package/src/node-types/bot-report.ts +5 -2
  94. package/src/node-types/build-context.ts +13 -1
  95. package/src/node-types/exec-validate-retry.ts +14 -203
  96. package/src/node-types/load-config.ts +1 -0
  97. package/src/node-types/plan-task.ts +313 -88
  98. package/src/ui/bot-panel.tsx +1 -1
  99. package/src/ui/chat-task-result.tsx +10 -8
  100. package/src/ui/swarm-dashboard.tsx +4 -4
  101. package/src/ui/task-detail-view.tsx +35 -12
  102. package/src/ui/task-editor.tsx +2 -2
  103. package/src/ui/task-pool-list.tsx +2 -2
  104. package/src/workflows/weaver-bot.ts +8 -7
@@ -18,6 +18,7 @@ function parseResult(result) {
18
18
  }
19
19
  function statusToIcon(status) {
20
20
  switch (status) {
21
+ case "open":
21
22
  case "pending":
22
23
  case "blocked":
23
24
  return "pending";
@@ -25,7 +26,6 @@ function statusToIcon(status) {
25
26
  return "running";
26
27
  case "done":
27
28
  return "completed";
28
- case "failed":
29
29
  case "cancelled":
30
30
  return "failed";
31
31
  default:
@@ -34,16 +34,16 @@ function statusToIcon(status) {
34
34
  }
35
35
  function statusLabel(status) {
36
36
  switch (status) {
37
+ case "open":
38
+ return "Open";
37
39
  case "pending":
38
- return "Pending";
40
+ return "Queued";
39
41
  case "in-progress":
40
- return "In Progress";
42
+ return "Running";
41
43
  case "blocked":
42
44
  return "Blocked";
43
45
  case "done":
44
46
  return "Done";
45
- case "failed":
46
- return "Failed";
47
47
  case "cancelled":
48
48
  return "Cancelled";
49
49
  default:
@@ -51,7 +51,7 @@ function statusLabel(status) {
51
51
  }
52
52
  }
53
53
  function isTerminal(status) {
54
- return status === "done" || status === "failed" || status === "cancelled";
54
+ return status === "done" || status === "cancelled";
55
55
  }
56
56
  function ChatTaskResult(props) {
57
57
  const { result = null, args = {}, callTool, openWorkspace } = props ?? {};
@@ -152,7 +152,7 @@ function ChatTaskResult(props) {
152
152
  // Status label
153
153
  React.createElement(Typography, {
154
154
  variant: "smallCaption-regular",
155
- color: task.status === "done" ? "color-text-positive" : task.status === "failed" ? "color-text-negative" : task.status === "in-progress" ? "color-text-info" : "color-text-medium"
155
+ color: task.status === "done" ? "color-text-positive" : task.status === "cancelled" ? "color-text-negative" : task.status === "in-progress" ? "color-text-info" : "color-text-medium"
156
156
  }, statusLabel(task.status)),
157
157
  // Subtask progress
158
158
  hasSubtasks && React.createElement(Typography, {
@@ -247,35 +247,28 @@ var CAP_ROLE_ORCHESTRATOR = {
247
247
  You DECOMPOSE and ASSIGN. You never write code or create files directly.
248
248
 
249
249
  Your job:
250
- 1. Analyze the objective and understand the project scope
251
- 2. Create a PROJECT BRIEF (a concise description of what we're building, how pieces connect, conventions to follow)
252
- 3. Break the objective into focused subtasks using task_create. The prompt contains "Task ID: <id>" \u2014 use that exact ID value as parentId in every task_create call so subtasks appear as children.
253
- 4. ALWAYS set assignedProfile on every subtask to one of these three:
254
- - "developer" \u2192 code writing, file creation, implementation
255
- - "reviewer" \u2192 code review, quality checks, security audit
256
- - "ops" \u2192 project setup, dependencies, config, infrastructure
257
- NEVER set assignedProfile to "orchestrator". You are the orchestrator \u2014 assigning to yourself creates an infinite loop. Only "developer", "reviewer", or "ops".
258
- 5. Set dependencies so tasks execute in the right order
259
- Use the EXACT title of a previous subtask as the dependsOn value. The system resolves titles to real task IDs at execution time. Example: dependsOn: ["Setup: Initialize project structure"]
260
- 6. Include the project brief in every subtask's description
250
+ 1. Analyze the objective
251
+ 2. Break it into focused subtasks via task_create. Set parentId to "@self" on every subtask.
252
+ 3. ALWAYS set assignedProfile: "developer", "reviewer", or "ops".
253
+ NEVER set assignedProfile to "orchestrator" \u2014 assigning to yourself creates an infinite loop.
254
+ 4. Use the EXACT title of a previous subtask as dependsOn. The system resolves titles to real task IDs.
255
+ 5. Include a project brief in every subtask: "PROJECT: [what]. FILES: [exact paths from workspace root]. CONVENTIONS: [patterns]."
261
256
 
262
- CRITICAL: You do NOT have write_file, patch_file, or run_shell. You cannot execute code \u2014 only plan and delegate to developer/reviewer/ops.
257
+ CRITICAL: You do NOT have write_file, patch_file, or run_shell. Only plan and delegate.
263
258
 
264
- ### Project Brief Format
265
- Include this at the TOP of every subtask description:
266
- "PROJECT: [what we're building]. STRUCTURE: [file layout]. CONVENTIONS: [naming, patterns, exports]."
259
+ ### Design Phase (MANDATORY)
260
+ Your FIRST subtask MUST be a design task assigned to ops that creates a .design.md file in the project root. This is the single source of truth. It must contain:
261
+ - Module map, TypeScript interfaces (copy-paste ready), export contracts (function signatures)
262
+ - Dependency graph, conventions (naming, error handling, patterns)
263
+ Every subsequent developer task MUST read .design.md before writing code.
267
264
 
268
265
  ### Subtask Quality
269
- Each subtask must be:
270
- - Focused (one file or one concern)
271
- - Self-contained (has enough context to execute independently)
272
- - Properly routed (assignedProfile is set)
273
- - Ordered (dependsOn reflects real dependencies)
266
+ Each subtask: focused (one concern), self-contained, properly routed, ordered by dependsOn.
274
267
 
275
268
  ### Example
276
- For a task with Task ID "abc123":
277
- { operation: "task_create", args: { title: "Setup project", parentId: "abc123", assignedProfile: "ops", dependsOn: [] } }
278
- { operation: "task_create", args: { title: "Write code", parentId: "abc123", assignedProfile: "developer", dependsOn: ["Setup project"] } }`
269
+ { operation: "task_create", args: { title: "Design: Create project contract", parentId: "@self", assignedProfile: "ops", complexity: "complex", description: "Create todo-app/.design.md with module map, TypeScript interfaces, export contracts.", dependsOn: [] } }
270
+ { operation: "task_create", args: { title: "Setup project", parentId: "@self", assignedProfile: "ops", dependsOn: ["Design: Create project contract"] } }
271
+ { operation: "task_create", args: { title: "Write code", parentId: "@self", assignedProfile: "developer", dependsOn: ["Setup project"] } }`
279
272
  };
280
273
  var CAP_ROLE_DEVELOPER = {
281
274
  name: "role-developer",
@@ -284,17 +277,28 @@ var CAP_ROLE_DEVELOPER = {
284
277
  You WRITE CODE. Execute the task directly using write_file, patch_file, and run_shell.
285
278
 
286
279
  Your job:
287
- 1. Read the task description (including the project brief)
288
- 2. Create a plan with CONCRETE file operations (write_file, patch_file, run_shell)
289
- 3. Execute every step \u2014 produce actual files on disk
290
- 4. Verify your work compiles and is correct
280
+ 1. Read .design.md in the project root to understand interfaces and contracts
281
+ 2. Read files created by previous tasks (your dependencies are done \u2014 their files are on disk)
282
+ 3. Write code that MATCHES the contracts in .design.md exactly \u2014 same types, same function signatures, same exports
283
+ 4. Verify your imports resolve to real exports in existing files
291
284
 
292
285
  You do NOT have task_create. You cannot create subtasks or delegate.
293
286
  If the task seems too large, do your best \u2014 the orchestrator already decomposed it for you.
294
287
 
288
+ ### File Paths
289
+ All paths in write_file/patch_file are RELATIVE TO THE WORKSPACE ROOT. If the task says "inside todo-app/", your paths MUST start with todo-app/ (e.g., todo-app/src/cli.ts, NOT src/cli.ts).
290
+
291
+ ### Code Quality
292
+ - Write COMPLETE, WORKING code. No TODOs, no placeholders, no empty function bodies, no "// implement later".
293
+ - Every function must be fully implemented with real logic.
294
+ - Use proper TypeScript types. Use strict mode patterns.
295
+ - Export everything that other files will import.
296
+ - Handle edge cases (empty input, file not found, invalid args).
297
+ - Use ESM-compatible patterns: import.meta.url instead of __dirname, import.meta.filename instead of __filename. Use fileURLToPath(import.meta.url) for path resolution.
298
+
295
299
  ### Output Requirements
296
300
  Your plan MUST include at least one write_file, patch_file, or run_shell step.
297
- A plan with only "respond" steps is a FAILURE \u2014 you must produce artifacts.`
301
+ A plan with only read_file, list_files, or respond steps is a FAILURE \u2014 you must produce artifacts.`
298
302
  };
299
303
  var CAP_ROLE_REVIEWER = {
300
304
  name: "role-reviewer",
@@ -318,10 +322,19 @@ var CAP_ROLE_OPS = {
318
322
  You SET UP infrastructure \u2014 package.json, tsconfig.json, directory structure, dependencies.
319
323
 
320
324
  Your job:
321
- 1. Initialize project structure (create config files, directories)
322
- 2. Install dependencies with run_shell
323
- 3. Ensure the project builds and tests can run
325
+ 1. Create the project directory first: run_shell with mkdir -p <project>/src
326
+ 2. Write config files (package.json, tsconfig.json) using write_file
327
+ 3. Install dependencies with run_shell (npm install)
328
+ 4. Ensure the project structure is ready for developers
329
+
330
+ ### File Paths
331
+ All paths are RELATIVE TO THE WORKSPACE ROOT. If the project is in a subfolder (e.g., todo-app/), ALL your paths must include that prefix: todo-app/package.json, todo-app/tsconfig.json, todo-app/src/.
324
332
 
333
+ ### Design Tasks
334
+ When the task is a Design task, create a .design.md file with detailed TypeScript interfaces, module exports, and dependency graph. This file must contain copy-paste ready interface definitions that developers will implement exactly.
335
+
336
+ ### Output Requirements
337
+ Your plan MUST include write_file and/or run_shell steps that create real files.
325
338
  You do NOT have task_create. You execute infrastructure tasks directly.`
326
339
  };
327
340
  var CAP_FILE_OPS = {
@@ -403,10 +403,10 @@ var React4 = require("react");
403
403
  var { useState: useState2 } = React4;
404
404
  var { Flex: Flex4, Typography: Typography4, Icon: Icon2, StatusIcon: StatusIcon2, Chip, ScrollArea, Badge, EmptyState } = require("@fw/plugin-ui-kit");
405
405
  var statusToIcon = {
406
+ "open": "pending",
406
407
  "pending": "pending",
407
408
  "in-progress": "running",
408
409
  "done": "completed",
409
- "failed": "failed",
410
410
  "blocked": "pending",
411
411
  "cancelled": "failed"
412
412
  };
@@ -854,18 +854,18 @@ var {
854
854
  useEventStream
855
855
  } = require("@fw/plugin-ui-kit");
856
856
  var statusToIcon2 = {
857
+ "open": "pending",
857
858
  "pending": "pending",
858
859
  "in-progress": "running",
859
860
  "done": "completed",
860
- "failed": "failed",
861
861
  "blocked": "pending",
862
862
  "cancelled": "failed"
863
863
  };
864
864
  var statusToLabel2 = {
865
- "pending": "Pending",
866
- "in-progress": "In Progress",
865
+ "open": "Open",
866
+ "pending": "Queued",
867
+ "in-progress": "Running",
867
868
  "done": "Done",
868
- "failed": "Failed",
869
869
  "blocked": "Blocked",
870
870
  "cancelled": "Cancelled"
871
871
  };
@@ -943,6 +943,25 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
943
943
  if (!data) return;
944
944
  const t = data.task ?? data;
945
945
  setTask(t);
946
+ const rs = t.context;
947
+ const summaries = rs?.runSummaries;
948
+ if (summaries?.length) {
949
+ setHistory((prev) => {
950
+ if (prev.length > 0) return prev;
951
+ return summaries.map((s) => ({
952
+ id: s.runId,
953
+ runId: s.runId,
954
+ outcome: s.outcome,
955
+ summary: s.summary,
956
+ report: s.report,
957
+ filesModified: s.filesModified,
958
+ durationMs: s.durationMs,
959
+ cost: s.cost,
960
+ tokensUsed: s.tokensUsed,
961
+ error: s.error
962
+ }));
963
+ });
964
+ }
946
965
  if (data.subtasks && Array.isArray(data.subtasks)) {
947
966
  setSubtasks(data.subtasks);
948
967
  } else if (t.isParent) {
@@ -959,13 +978,14 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
959
978
  try {
960
979
  const raw = await callTool("fw_weaver_history", { taskId });
961
980
  const data = typeof raw === "string" ? JSON.parse(raw) : raw;
962
- if (Array.isArray(data)) {
981
+ if (Array.isArray(data) && data.length > 0) {
963
982
  setHistory(
964
983
  data.map((r) => {
965
984
  const costObj = r.cost && typeof r.cost === "object" ? r.cost : void 0;
966
985
  return { ...r, costDetail: costObj, cost: costObj?.totalCost };
967
986
  })
968
987
  );
988
+ return;
969
989
  }
970
990
  } catch {
971
991
  }
@@ -1252,9 +1272,9 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
1252
1272
  Flex5,
1253
1273
  { variant: "row-center-start-wrap-6" },
1254
1274
  React6.createElement(Chip2, {
1255
- label: statusToLabel2[task.status] || task.status || "pending",
1275
+ label: statusToLabel2[task.status] || task.status || "open",
1256
1276
  size: "small",
1257
- color: task.status === "done" ? "color-status-positive" : task.status === "failed" ? "color-status-negative" : task.status === "in-progress" ? "color-status-info" : task.status === "blocked" ? "color-status-caution" : "color-brand-alt"
1277
+ color: task.status === "done" ? "color-status-positive" : task.status === "cancelled" ? "color-status-negative" : task.status === "in-progress" ? "color-status-info" : task.status === "blocked" ? "color-status-caution" : "color-brand-alt"
1258
1278
  }),
1259
1279
  task.assignedProfile && React6.createElement(Chip2, { key: `profile-${task.assignedProfile}`, label: task.assignedProfile, size: "small", color: "color-status-info" }),
1260
1280
  task.priority > 0 && React6.createElement(Chip2, {
@@ -1262,10 +1282,10 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
1262
1282
  size: "small",
1263
1283
  color: task.priority >= 3 ? "color-status-caution" : "color-status-info"
1264
1284
  }),
1265
- task.attempt != null && task.maxAttempts != null && React6.createElement(Typography5, {
1285
+ task.maxAttempts != null && task.maxAttempts > 1 && React6.createElement(Typography5, {
1266
1286
  variant: "smallCaption-regular",
1267
1287
  color: "color-text-subtle"
1268
- }, `Attempt ${task.attempt}/${task.maxAttempts}`)
1288
+ }, `${task.runs?.length ?? 0}/${task.maxAttempts} runs`)
1269
1289
  ),
1270
1290
  // Description
1271
1291
  task.description && React6.createElement(Typography5, {
@@ -1380,7 +1400,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
1380
1400
  React6.createElement(
1381
1401
  Flex5,
1382
1402
  { variant: "row-center-start-nowrap-6" },
1383
- task.status === "failed" && React6.createElement(Button2, {
1403
+ task.status === "open" && (task.attempt ?? 0) > 0 && React6.createElement(Button2, {
1384
1404
  size: "xs",
1385
1405
  variant: "fill",
1386
1406
  color: "primary",
@@ -1388,7 +1408,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
1388
1408
  loading: actionLoading === "retry",
1389
1409
  disabled: !!actionLoading
1390
1410
  }, "Retry Task"),
1391
- (task.status === "pending" || task.status === "in-progress" || task.status === "blocked") && React6.createElement(Button2, {
1411
+ (task.status === "open" || task.status === "pending" || task.status === "in-progress" || task.status === "blocked") && React6.createElement(Button2, {
1392
1412
  size: "xs",
1393
1413
  variant: "outlined",
1394
1414
  color: "danger",
@@ -1643,11 +1663,11 @@ var COMPLEXITY_OPTIONS = [
1643
1663
  { id: "complex", label: "Complex" }
1644
1664
  ];
1645
1665
  var STATUS_COLOR = {
1666
+ "open": "color-brand-alt",
1646
1667
  "pending": "color-brand-alt",
1647
1668
  "in-progress": "color-status-info",
1648
1669
  "blocked": "color-status-caution",
1649
1670
  "done": "color-status-positive",
1650
- "failed": "color-status-negative",
1651
1671
  "cancelled": "color-status-negative"
1652
1672
  };
1653
1673
  function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
@@ -2738,35 +2758,28 @@ var CAP_ROLE_ORCHESTRATOR = {
2738
2758
  You DECOMPOSE and ASSIGN. You never write code or create files directly.
2739
2759
 
2740
2760
  Your job:
2741
- 1. Analyze the objective and understand the project scope
2742
- 2. Create a PROJECT BRIEF (a concise description of what we're building, how pieces connect, conventions to follow)
2743
- 3. Break the objective into focused subtasks using task_create. The prompt contains "Task ID: <id>" \u2014 use that exact ID value as parentId in every task_create call so subtasks appear as children.
2744
- 4. ALWAYS set assignedProfile on every subtask to one of these three:
2745
- - "developer" \u2192 code writing, file creation, implementation
2746
- - "reviewer" \u2192 code review, quality checks, security audit
2747
- - "ops" \u2192 project setup, dependencies, config, infrastructure
2748
- NEVER set assignedProfile to "orchestrator". You are the orchestrator \u2014 assigning to yourself creates an infinite loop. Only "developer", "reviewer", or "ops".
2749
- 5. Set dependencies so tasks execute in the right order
2750
- Use the EXACT title of a previous subtask as the dependsOn value. The system resolves titles to real task IDs at execution time. Example: dependsOn: ["Setup: Initialize project structure"]
2751
- 6. Include the project brief in every subtask's description
2761
+ 1. Analyze the objective
2762
+ 2. Break it into focused subtasks via task_create. Set parentId to "@self" on every subtask.
2763
+ 3. ALWAYS set assignedProfile: "developer", "reviewer", or "ops".
2764
+ NEVER set assignedProfile to "orchestrator" \u2014 assigning to yourself creates an infinite loop.
2765
+ 4. Use the EXACT title of a previous subtask as dependsOn. The system resolves titles to real task IDs.
2766
+ 5. Include a project brief in every subtask: "PROJECT: [what]. FILES: [exact paths from workspace root]. CONVENTIONS: [patterns]."
2752
2767
 
2753
- CRITICAL: You do NOT have write_file, patch_file, or run_shell. You cannot execute code \u2014 only plan and delegate to developer/reviewer/ops.
2768
+ CRITICAL: You do NOT have write_file, patch_file, or run_shell. Only plan and delegate.
2754
2769
 
2755
- ### Project Brief Format
2756
- Include this at the TOP of every subtask description:
2757
- "PROJECT: [what we're building]. STRUCTURE: [file layout]. CONVENTIONS: [naming, patterns, exports]."
2770
+ ### Design Phase (MANDATORY)
2771
+ Your FIRST subtask MUST be a design task assigned to ops that creates a .design.md file in the project root. This is the single source of truth. It must contain:
2772
+ - Module map, TypeScript interfaces (copy-paste ready), export contracts (function signatures)
2773
+ - Dependency graph, conventions (naming, error handling, patterns)
2774
+ Every subsequent developer task MUST read .design.md before writing code.
2758
2775
 
2759
2776
  ### Subtask Quality
2760
- Each subtask must be:
2761
- - Focused (one file or one concern)
2762
- - Self-contained (has enough context to execute independently)
2763
- - Properly routed (assignedProfile is set)
2764
- - Ordered (dependsOn reflects real dependencies)
2777
+ Each subtask: focused (one concern), self-contained, properly routed, ordered by dependsOn.
2765
2778
 
2766
2779
  ### Example
2767
- For a task with Task ID "abc123":
2768
- { operation: "task_create", args: { title: "Setup project", parentId: "abc123", assignedProfile: "ops", dependsOn: [] } }
2769
- { operation: "task_create", args: { title: "Write code", parentId: "abc123", assignedProfile: "developer", dependsOn: ["Setup project"] } }`
2780
+ { operation: "task_create", args: { title: "Design: Create project contract", parentId: "@self", assignedProfile: "ops", complexity: "complex", description: "Create todo-app/.design.md with module map, TypeScript interfaces, export contracts.", dependsOn: [] } }
2781
+ { operation: "task_create", args: { title: "Setup project", parentId: "@self", assignedProfile: "ops", dependsOn: ["Design: Create project contract"] } }
2782
+ { operation: "task_create", args: { title: "Write code", parentId: "@self", assignedProfile: "developer", dependsOn: ["Setup project"] } }`
2770
2783
  };
2771
2784
  var CAP_ROLE_DEVELOPER = {
2772
2785
  name: "role-developer",
@@ -2775,17 +2788,28 @@ var CAP_ROLE_DEVELOPER = {
2775
2788
  You WRITE CODE. Execute the task directly using write_file, patch_file, and run_shell.
2776
2789
 
2777
2790
  Your job:
2778
- 1. Read the task description (including the project brief)
2779
- 2. Create a plan with CONCRETE file operations (write_file, patch_file, run_shell)
2780
- 3. Execute every step \u2014 produce actual files on disk
2781
- 4. Verify your work compiles and is correct
2791
+ 1. Read .design.md in the project root to understand interfaces and contracts
2792
+ 2. Read files created by previous tasks (your dependencies are done \u2014 their files are on disk)
2793
+ 3. Write code that MATCHES the contracts in .design.md exactly \u2014 same types, same function signatures, same exports
2794
+ 4. Verify your imports resolve to real exports in existing files
2782
2795
 
2783
2796
  You do NOT have task_create. You cannot create subtasks or delegate.
2784
2797
  If the task seems too large, do your best \u2014 the orchestrator already decomposed it for you.
2785
2798
 
2799
+ ### File Paths
2800
+ All paths in write_file/patch_file are RELATIVE TO THE WORKSPACE ROOT. If the task says "inside todo-app/", your paths MUST start with todo-app/ (e.g., todo-app/src/cli.ts, NOT src/cli.ts).
2801
+
2802
+ ### Code Quality
2803
+ - Write COMPLETE, WORKING code. No TODOs, no placeholders, no empty function bodies, no "// implement later".
2804
+ - Every function must be fully implemented with real logic.
2805
+ - Use proper TypeScript types. Use strict mode patterns.
2806
+ - Export everything that other files will import.
2807
+ - Handle edge cases (empty input, file not found, invalid args).
2808
+ - Use ESM-compatible patterns: import.meta.url instead of __dirname, import.meta.filename instead of __filename. Use fileURLToPath(import.meta.url) for path resolution.
2809
+
2786
2810
  ### Output Requirements
2787
2811
  Your plan MUST include at least one write_file, patch_file, or run_shell step.
2788
- A plan with only "respond" steps is a FAILURE \u2014 you must produce artifacts.`
2812
+ A plan with only read_file, list_files, or respond steps is a FAILURE \u2014 you must produce artifacts.`
2789
2813
  };
2790
2814
  var CAP_ROLE_REVIEWER = {
2791
2815
  name: "role-reviewer",
@@ -2809,10 +2833,19 @@ var CAP_ROLE_OPS = {
2809
2833
  You SET UP infrastructure \u2014 package.json, tsconfig.json, directory structure, dependencies.
2810
2834
 
2811
2835
  Your job:
2812
- 1. Initialize project structure (create config files, directories)
2813
- 2. Install dependencies with run_shell
2814
- 3. Ensure the project builds and tests can run
2836
+ 1. Create the project directory first: run_shell with mkdir -p <project>/src
2837
+ 2. Write config files (package.json, tsconfig.json) using write_file
2838
+ 3. Install dependencies with run_shell (npm install)
2839
+ 4. Ensure the project structure is ready for developers
2840
+
2841
+ ### File Paths
2842
+ All paths are RELATIVE TO THE WORKSPACE ROOT. If the project is in a subfolder (e.g., todo-app/), ALL your paths must include that prefix: todo-app/package.json, todo-app/tsconfig.json, todo-app/src/.
2815
2843
 
2844
+ ### Design Tasks
2845
+ When the task is a Design task, create a .design.md file with detailed TypeScript interfaces, module exports, and dependency graph. This file must contain copy-paste ready interface definitions that developers will implement exactly.
2846
+
2847
+ ### Output Requirements
2848
+ Your plan MUST include write_file and/or run_shell steps that create real files.
2816
2849
  You do NOT have task_create. You execute infrastructure tasks directly.`
2817
2850
  };
2818
2851
  var CAP_FILE_OPS = {
@@ -4349,7 +4382,7 @@ function SwarmDashboard() {
4349
4382
  React11.createElement(Tabs2, {
4350
4383
  tabs: [
4351
4384
  { id: "tasks", title: `Tasks (${tasks.length})` },
4352
- { id: "bots", title: hasSwarmInstances ? `Instances (${swarmInstanceEntries.length})` : `Bots (${registeredBots.length})` },
4385
+ { id: "bots", title: hasSwarmInstances ? `Workers (${swarmInstanceEntries.length})` : `Bots (${registeredBots.length})` },
4353
4386
  { id: "profiles", title: `Profiles (${profiles.length})` },
4354
4387
  { id: "config", title: "Config" }
4355
4388
  ],
@@ -4490,7 +4523,7 @@ function SwarmDashboard() {
4490
4523
  variant: "smallCaption-regular",
4491
4524
  color: "color-text-subtle",
4492
4525
  style: { width: "120px", flexShrink: 0 }
4493
- }, "Instance"),
4526
+ }, "Worker"),
4494
4527
  React11.createElement(Typography10, {
4495
4528
  variant: "smallCaption-regular",
4496
4529
  color: "color-text-subtle",
@@ -4530,7 +4563,7 @@ function SwarmDashboard() {
4530
4563
  key: inst.instanceId,
4531
4564
  bot: {
4532
4565
  botId: inst.instanceId,
4533
- botName: `${inst.profileId} #${inst.index}`,
4566
+ botName: inst.profileId ? `${inst.instanceId} (${inst.profileId})` : inst.instanceId,
4534
4567
  status: inst.status,
4535
4568
  currentTaskId: inst.currentTaskId,
4536
4569
  currentRunId: inst.currentRunId,
@@ -348,18 +348,18 @@ var {
348
348
  useEventStream
349
349
  } = require("@fw/plugin-ui-kit");
350
350
  var statusToIcon = {
351
+ "open": "pending",
351
352
  "pending": "pending",
352
353
  "in-progress": "running",
353
354
  "done": "completed",
354
- "failed": "failed",
355
355
  "blocked": "pending",
356
356
  "cancelled": "failed"
357
357
  };
358
358
  var statusToLabel = {
359
- "pending": "Pending",
360
- "in-progress": "In Progress",
359
+ "open": "Open",
360
+ "pending": "Queued",
361
+ "in-progress": "Running",
361
362
  "done": "Done",
362
- "failed": "Failed",
363
363
  "blocked": "Blocked",
364
364
  "cancelled": "Cancelled"
365
365
  };
@@ -437,6 +437,25 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
437
437
  if (!data) return;
438
438
  const t = data.task ?? data;
439
439
  setTask(t);
440
+ const rs = t.context;
441
+ const summaries = rs?.runSummaries;
442
+ if (summaries?.length) {
443
+ setHistory((prev) => {
444
+ if (prev.length > 0) return prev;
445
+ return summaries.map((s) => ({
446
+ id: s.runId,
447
+ runId: s.runId,
448
+ outcome: s.outcome,
449
+ summary: s.summary,
450
+ report: s.report,
451
+ filesModified: s.filesModified,
452
+ durationMs: s.durationMs,
453
+ cost: s.cost,
454
+ tokensUsed: s.tokensUsed,
455
+ error: s.error
456
+ }));
457
+ });
458
+ }
440
459
  if (data.subtasks && Array.isArray(data.subtasks)) {
441
460
  setSubtasks(data.subtasks);
442
461
  } else if (t.isParent) {
@@ -453,13 +472,14 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
453
472
  try {
454
473
  const raw = await callTool("fw_weaver_history", { taskId });
455
474
  const data = typeof raw === "string" ? JSON.parse(raw) : raw;
456
- if (Array.isArray(data)) {
475
+ if (Array.isArray(data) && data.length > 0) {
457
476
  setHistory(
458
477
  data.map((r) => {
459
478
  const costObj = r.cost && typeof r.cost === "object" ? r.cost : void 0;
460
479
  return { ...r, costDetail: costObj, cost: costObj?.totalCost };
461
480
  })
462
481
  );
482
+ return;
463
483
  }
464
484
  } catch {
465
485
  }
@@ -746,9 +766,9 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
746
766
  Flex,
747
767
  { variant: "row-center-start-wrap-6" },
748
768
  React2.createElement(Chip, {
749
- label: statusToLabel[task.status] || task.status || "pending",
769
+ label: statusToLabel[task.status] || task.status || "open",
750
770
  size: "small",
751
- color: task.status === "done" ? "color-status-positive" : task.status === "failed" ? "color-status-negative" : task.status === "in-progress" ? "color-status-info" : task.status === "blocked" ? "color-status-caution" : "color-brand-alt"
771
+ color: task.status === "done" ? "color-status-positive" : task.status === "cancelled" ? "color-status-negative" : task.status === "in-progress" ? "color-status-info" : task.status === "blocked" ? "color-status-caution" : "color-brand-alt"
752
772
  }),
753
773
  task.assignedProfile && React2.createElement(Chip, { key: `profile-${task.assignedProfile}`, label: task.assignedProfile, size: "small", color: "color-status-info" }),
754
774
  task.priority > 0 && React2.createElement(Chip, {
@@ -756,10 +776,10 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
756
776
  size: "small",
757
777
  color: task.priority >= 3 ? "color-status-caution" : "color-status-info"
758
778
  }),
759
- task.attempt != null && task.maxAttempts != null && React2.createElement(Typography, {
779
+ task.maxAttempts != null && task.maxAttempts > 1 && React2.createElement(Typography, {
760
780
  variant: "smallCaption-regular",
761
781
  color: "color-text-subtle"
762
- }, `Attempt ${task.attempt}/${task.maxAttempts}`)
782
+ }, `${task.runs?.length ?? 0}/${task.maxAttempts} runs`)
763
783
  ),
764
784
  // Description
765
785
  task.description && React2.createElement(Typography, {
@@ -874,7 +894,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
874
894
  React2.createElement(
875
895
  Flex,
876
896
  { variant: "row-center-start-nowrap-6" },
877
- task.status === "failed" && React2.createElement(Button, {
897
+ task.status === "open" && (task.attempt ?? 0) > 0 && React2.createElement(Button, {
878
898
  size: "xs",
879
899
  variant: "fill",
880
900
  color: "primary",
@@ -882,7 +902,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
882
902
  loading: actionLoading === "retry",
883
903
  disabled: !!actionLoading
884
904
  }, "Retry Task"),
885
- (task.status === "pending" || task.status === "in-progress" || task.status === "blocked") && React2.createElement(Button, {
905
+ (task.status === "open" || task.status === "pending" || task.status === "in-progress" || task.status === "blocked") && React2.createElement(Button, {
886
906
  size: "xs",
887
907
  variant: "outlined",
888
908
  color: "danger",
@@ -51,11 +51,11 @@ var COMPLEXITY_OPTIONS = [
51
51
  { id: "complex", label: "Complex" }
52
52
  ];
53
53
  var STATUS_COLOR = {
54
+ "open": "color-brand-alt",
54
55
  "pending": "color-brand-alt",
55
56
  "in-progress": "color-status-info",
56
57
  "blocked": "color-status-caution",
57
58
  "done": "color-status-positive",
58
- "failed": "color-status-negative",
59
59
  "cancelled": "color-status-negative"
60
60
  };
61
61
  function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
@@ -28,10 +28,10 @@ var React = require("react");
28
28
  var { useState } = React;
29
29
  var { Flex, Typography, Icon, StatusIcon, Chip, ScrollArea, Badge, EmptyState } = require("@fw/plugin-ui-kit");
30
30
  var statusToIcon = {
31
+ "open": "pending",
31
32
  "pending": "pending",
32
33
  "in-progress": "running",
33
34
  "done": "completed",
34
- "failed": "failed",
35
35
  "blocked": "pending",
36
36
  "cancelled": "failed"
37
37
  };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @flowWeaver workflow
3
- * @node cfg weaverLoadConfig [color: "teal"] [icon: "settings"] [position: 200 200]
3
+ * @node cfg weaverLoadConfig [color: "teal"] [icon: "settings"] [suppress: "AGENT_UNGUARDED_TOOL_EXECUTOR"] [position: 200 200]
4
4
  * @node detect weaverDetectProvider [color: "cyan"] [icon: "search"] [suppress: "OBJECT_TYPE_MISMATCH", "ANNOTATION_SIGNATURE_TYPE_MISMATCH"] [position: 400 200]
5
5
  * @node receive weaverReceiveTask [color: "blue"] [icon: "send"] [position: 600 200]
6
6
  * @node route weaverRouteTask [color: "purple"] [icon: "flow"] [position: 800 200]
@@ -18,7 +18,7 @@
18
18
  * @node resolveReviewModel weaverResolveModel [label: "Review Model"] [expr: phaseName="'review'"] [minimized] [color: "green"] [icon: "tune"] [position: 1900 50]
19
19
  * @node review weaverReviewResult [color: "green"] [icon: "spellcheck"] [position: 1950 100]
20
20
  * @node mergeReview weaverCtxMerge [label: "Merge Review"] [minimized] [color: "teal"] [icon: "callMerge"] [position: 2050 200]
21
- * @node gitOps weaverGitOps [color: "green"] [icon: "code"] [position: 2150 100]
21
+ * @node gitOps weaverGitOps [color: "green"] [icon: "code"] [suppress: "UNUSED_OUTPUT_PORT"] [position: 2150 100]
22
22
  * @node notify weaverSendNotify [color: "yellow"] [icon: "send"] [suppress: "UNUSED_OUTPUT_PORT"] [position: 2050 400]
23
23
  * @node report weaverBotReport [color: "green"] [icon: "description"] [suppress: "UNUSED_OUTPUT_PORT", "DESIGN_ASYNC_NO_ERROR_PATH"] [position: 2350 200]
24
24
  * @path Start -> cfg -> detect -> receive -> route -> context -> gatePlan -> resolvePlanModel -> plan -> mergePlan -> approve -> resolveExecModel -> execRetry -> gateReview -> resolveReviewModel -> review -> mergeReview -> gitOps -> report -> Exit
@@ -42,11 +42,12 @@
42
42
  * @connect readWf.onSuccess -> report.execute
43
43
  * @connect abort.onSuccess -> report.execute
44
44
  * @connect notify.onSuccess -> report.execute
45
- * @connect gitOps.ctx -> report.mainCtx
45
+ * @connect mergePlan.ctx -> report.mainCtx
46
46
  * @connect readWf.ctx -> report.readCtx
47
47
  * @connect abort.ctx -> report.abortCtx
48
- * @connect execRetry.ctx -> report.failCtx
48
+ * @connect plan.ctx -> report.failCtx
49
49
  * @connect report.summary -> Exit.summary
50
+ * @connect review.onFailure -> report.execute
50
51
  * @param execute [order:-1] - Execute
51
52
  * @param taskJson [order:0] - TaskJson
52
53
  * @param projectDir [order:1] - ProjectDir
@@ -1 +1 @@
1
- {"version":3,"file":"weaver-bot.d.ts","sourceRoot":"","sources":["../../src/workflows/weaver-bot.ts"],"names":[],"mappings":"AAuaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACzE,eAAe,CAAC,EAAE,WAAW,GAC5B,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAwqD7E"}
1
+ {"version":3,"file":"weaver-bot.d.ts","sourceRoot":"","sources":["../../src/workflows/weaver-bot.ts"],"names":[],"mappings":"AAuaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACzE,eAAe,CAAC,EAAE,WAAW,GAC5B,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAwqD7E"}