@synergenius/flow-weaver-pack-weaver 0.8.3 → 0.9.3

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 (265) hide show
  1. package/dist/bot/ai-client.d.ts +22 -2
  2. package/dist/bot/ai-client.d.ts.map +1 -1
  3. package/dist/bot/ai-client.js +168 -20
  4. package/dist/bot/ai-client.js.map +1 -1
  5. package/dist/bot/assistant-core.d.ts +25 -0
  6. package/dist/bot/assistant-core.d.ts.map +1 -0
  7. package/dist/bot/assistant-core.js +265 -0
  8. package/dist/bot/assistant-core.js.map +1 -0
  9. package/dist/bot/assistant-tools.d.ts +9 -0
  10. package/dist/bot/assistant-tools.d.ts.map +1 -0
  11. package/dist/bot/assistant-tools.js +602 -0
  12. package/dist/bot/assistant-tools.js.map +1 -0
  13. package/dist/bot/audit-logger.d.ts.map +1 -1
  14. package/dist/bot/audit-logger.js +9 -5
  15. package/dist/bot/audit-logger.js.map +1 -1
  16. package/dist/bot/audit-store.d.ts.map +1 -1
  17. package/dist/bot/audit-store.js +3 -11
  18. package/dist/bot/audit-store.js.map +1 -1
  19. package/dist/bot/bot-manager.d.ts +49 -0
  20. package/dist/bot/bot-manager.d.ts.map +1 -0
  21. package/dist/bot/bot-manager.js +279 -0
  22. package/dist/bot/bot-manager.js.map +1 -0
  23. package/dist/bot/child-process-tracker.d.ts +6 -0
  24. package/dist/bot/child-process-tracker.d.ts.map +1 -0
  25. package/dist/bot/child-process-tracker.js +35 -0
  26. package/dist/bot/child-process-tracker.js.map +1 -0
  27. package/dist/bot/cli-provider.d.ts.map +1 -1
  28. package/dist/bot/cli-provider.js +13 -8
  29. package/dist/bot/cli-provider.js.map +1 -1
  30. package/dist/bot/conversation-store.d.ts +40 -0
  31. package/dist/bot/conversation-store.d.ts.map +1 -0
  32. package/dist/bot/conversation-store.js +182 -0
  33. package/dist/bot/conversation-store.js.map +1 -0
  34. package/dist/bot/cost-store.d.ts.map +1 -1
  35. package/dist/bot/cost-store.js +10 -14
  36. package/dist/bot/cost-store.js.map +1 -1
  37. package/dist/bot/error-guide.d.ts +10 -0
  38. package/dist/bot/error-guide.d.ts.map +1 -0
  39. package/dist/bot/error-guide.js +34 -0
  40. package/dist/bot/error-guide.js.map +1 -0
  41. package/dist/bot/genesis-store.d.ts.map +1 -1
  42. package/dist/bot/genesis-store.js +11 -20
  43. package/dist/bot/genesis-store.js.map +1 -1
  44. package/dist/bot/index.d.ts +3 -0
  45. package/dist/bot/index.d.ts.map +1 -1
  46. package/dist/bot/index.js +3 -0
  47. package/dist/bot/index.js.map +1 -1
  48. package/dist/bot/knowledge-store.d.ts +17 -0
  49. package/dist/bot/knowledge-store.d.ts.map +1 -0
  50. package/dist/bot/knowledge-store.js +53 -0
  51. package/dist/bot/knowledge-store.js.map +1 -0
  52. package/dist/bot/pipeline-runner.d.ts.map +1 -1
  53. package/dist/bot/pipeline-runner.js +8 -1
  54. package/dist/bot/pipeline-runner.js.map +1 -1
  55. package/dist/bot/retry-utils.d.ts +19 -0
  56. package/dist/bot/retry-utils.d.ts.map +1 -0
  57. package/dist/bot/retry-utils.js +64 -0
  58. package/dist/bot/retry-utils.js.map +1 -0
  59. package/dist/bot/run-store.d.ts.map +1 -1
  60. package/dist/bot/run-store.js +2 -10
  61. package/dist/bot/run-store.js.map +1 -1
  62. package/dist/bot/runner.d.ts.map +1 -1
  63. package/dist/bot/runner.js +24 -3
  64. package/dist/bot/runner.js.map +1 -1
  65. package/dist/bot/safe-json.d.ts +32 -0
  66. package/dist/bot/safe-json.d.ts.map +1 -0
  67. package/dist/bot/safe-json.js +56 -0
  68. package/dist/bot/safe-json.js.map +1 -0
  69. package/dist/bot/safe-path.d.ts +18 -0
  70. package/dist/bot/safe-path.d.ts.map +1 -0
  71. package/dist/bot/safe-path.js +40 -0
  72. package/dist/bot/safe-path.js.map +1 -0
  73. package/dist/bot/session-state.d.ts.map +1 -1
  74. package/dist/bot/session-state.js +3 -1
  75. package/dist/bot/session-state.js.map +1 -1
  76. package/dist/bot/steering.js +1 -1
  77. package/dist/bot/steering.js.map +1 -1
  78. package/dist/bot/step-executor.d.ts +10 -5
  79. package/dist/bot/step-executor.d.ts.map +1 -1
  80. package/dist/bot/step-executor.js +252 -3
  81. package/dist/bot/step-executor.js.map +1 -1
  82. package/dist/bot/system-prompt.d.ts +1 -1
  83. package/dist/bot/system-prompt.d.ts.map +1 -1
  84. package/dist/bot/system-prompt.js +69 -43
  85. package/dist/bot/system-prompt.js.map +1 -1
  86. package/dist/bot/task-decomposer.d.ts +24 -0
  87. package/dist/bot/task-decomposer.d.ts.map +1 -0
  88. package/dist/bot/task-decomposer.js +75 -0
  89. package/dist/bot/task-decomposer.js.map +1 -0
  90. package/dist/bot/task-queue.d.ts +17 -4
  91. package/dist/bot/task-queue.d.ts.map +1 -1
  92. package/dist/bot/task-queue.js +102 -14
  93. package/dist/bot/task-queue.js.map +1 -1
  94. package/dist/bot/terminal-renderer.d.ts +60 -0
  95. package/dist/bot/terminal-renderer.d.ts.map +1 -0
  96. package/dist/bot/terminal-renderer.js +205 -0
  97. package/dist/bot/terminal-renderer.js.map +1 -0
  98. package/dist/bot/types.d.ts +7 -0
  99. package/dist/bot/types.d.ts.map +1 -1
  100. package/dist/bot/weaver-tools.d.ts +18 -0
  101. package/dist/bot/weaver-tools.d.ts.map +1 -0
  102. package/dist/bot/weaver-tools.js +215 -0
  103. package/dist/bot/weaver-tools.js.map +1 -0
  104. package/dist/cli-bridge.d.ts.map +1 -1
  105. package/dist/cli-bridge.js +10 -3
  106. package/dist/cli-bridge.js.map +1 -1
  107. package/dist/cli-handlers.d.ts +15 -1
  108. package/dist/cli-handlers.d.ts.map +1 -1
  109. package/dist/cli-handlers.js +742 -28
  110. package/dist/cli-handlers.js.map +1 -1
  111. package/dist/handlers/on-bot-completed.d.ts +21 -0
  112. package/dist/handlers/on-bot-completed.d.ts.map +1 -0
  113. package/dist/handlers/on-bot-completed.js +28 -0
  114. package/dist/handlers/on-bot-completed.js.map +1 -0
  115. package/dist/handlers/on-execution-failure.d.ts +23 -0
  116. package/dist/handlers/on-execution-failure.d.ts.map +1 -0
  117. package/dist/handlers/on-execution-failure.js +28 -0
  118. package/dist/handlers/on-execution-failure.js.map +1 -0
  119. package/dist/handlers/scheduled-run.d.ts +24 -0
  120. package/dist/handlers/scheduled-run.d.ts.map +1 -0
  121. package/dist/handlers/scheduled-run.js +25 -0
  122. package/dist/handlers/scheduled-run.js.map +1 -0
  123. package/dist/index.d.ts +3 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +4 -0
  126. package/dist/index.js.map +1 -1
  127. package/dist/mcp-tools.js +2 -2
  128. package/dist/mcp-tools.js.map +1 -1
  129. package/dist/node-types/abort-task.d.ts.map +1 -1
  130. package/dist/node-types/abort-task.js +4 -3
  131. package/dist/node-types/abort-task.js.map +1 -1
  132. package/dist/node-types/agent-execute.d.ts +38 -0
  133. package/dist/node-types/agent-execute.d.ts.map +1 -0
  134. package/dist/node-types/agent-execute.js +256 -0
  135. package/dist/node-types/agent-execute.js.map +1 -0
  136. package/dist/node-types/bot-report.d.ts +5 -3
  137. package/dist/node-types/bot-report.d.ts.map +1 -1
  138. package/dist/node-types/bot-report.js +39 -7
  139. package/dist/node-types/bot-report.js.map +1 -1
  140. package/dist/node-types/build-context.d.ts +3 -3
  141. package/dist/node-types/build-context.d.ts.map +1 -1
  142. package/dist/node-types/build-context.js +108 -24
  143. package/dist/node-types/build-context.js.map +1 -1
  144. package/dist/node-types/detect-provider.d.ts +2 -2
  145. package/dist/node-types/detect-provider.d.ts.map +1 -1
  146. package/dist/node-types/detect-provider.js +3 -1
  147. package/dist/node-types/detect-provider.js.map +1 -1
  148. package/dist/node-types/exec-validate-retry.d.ts.map +1 -1
  149. package/dist/node-types/exec-validate-retry.js +43 -6
  150. package/dist/node-types/exec-validate-retry.js.map +1 -1
  151. package/dist/node-types/execute-plan.d.ts.map +1 -1
  152. package/dist/node-types/execute-plan.js +31 -8
  153. package/dist/node-types/execute-plan.js.map +1 -1
  154. package/dist/node-types/execute-target.d.ts.map +1 -1
  155. package/dist/node-types/execute-target.js +3 -1
  156. package/dist/node-types/execute-target.js.map +1 -1
  157. package/dist/node-types/fix-errors.d.ts.map +1 -1
  158. package/dist/node-types/fix-errors.js +21 -5
  159. package/dist/node-types/fix-errors.js.map +1 -1
  160. package/dist/node-types/genesis-observe.d.ts.map +1 -1
  161. package/dist/node-types/genesis-observe.js +3 -1
  162. package/dist/node-types/genesis-observe.js.map +1 -1
  163. package/dist/node-types/genesis-report.js +4 -1
  164. package/dist/node-types/genesis-report.js.map +1 -1
  165. package/dist/node-types/git-ops.d.ts.map +1 -1
  166. package/dist/node-types/git-ops.js +98 -4
  167. package/dist/node-types/git-ops.js.map +1 -1
  168. package/dist/node-types/index.d.ts +2 -0
  169. package/dist/node-types/index.d.ts.map +1 -1
  170. package/dist/node-types/index.js +2 -0
  171. package/dist/node-types/index.js.map +1 -1
  172. package/dist/node-types/load-config.d.ts +2 -2
  173. package/dist/node-types/load-config.d.ts.map +1 -1
  174. package/dist/node-types/load-config.js.map +1 -1
  175. package/dist/node-types/plan-task.d.ts.map +1 -1
  176. package/dist/node-types/plan-task.js +14 -2
  177. package/dist/node-types/plan-task.js.map +1 -1
  178. package/dist/node-types/read-workflow.js +8 -2
  179. package/dist/node-types/read-workflow.js.map +1 -1
  180. package/dist/node-types/receive-task.d.ts.map +1 -1
  181. package/dist/node-types/receive-task.js +35 -26
  182. package/dist/node-types/receive-task.js.map +1 -1
  183. package/dist/node-types/send-notify.js +2 -1
  184. package/dist/node-types/send-notify.js.map +1 -1
  185. package/dist/node-types/validate-gate.d.ts +18 -0
  186. package/dist/node-types/validate-gate.d.ts.map +1 -0
  187. package/dist/node-types/validate-gate.js +96 -0
  188. package/dist/node-types/validate-gate.js.map +1 -0
  189. package/dist/workflows/genesis-task.d.ts +20 -12
  190. package/dist/workflows/genesis-task.d.ts.map +1 -1
  191. package/dist/workflows/genesis-task.js +20 -12
  192. package/dist/workflows/genesis-task.js.map +1 -1
  193. package/dist/workflows/weaver-agent.d.ts +35 -0
  194. package/dist/workflows/weaver-agent.d.ts.map +1 -0
  195. package/dist/workflows/weaver-agent.js +777 -0
  196. package/dist/workflows/weaver-agent.js.map +1 -0
  197. package/dist/workflows/weaver-bot-batch.d.ts +19 -26
  198. package/dist/workflows/weaver-bot-batch.d.ts.map +1 -1
  199. package/dist/workflows/weaver-bot-batch.js +1043 -27
  200. package/dist/workflows/weaver-bot-batch.js.map +1 -1
  201. package/dist/workflows/weaver-bot.d.ts +21 -35
  202. package/dist/workflows/weaver-bot.d.ts.map +1 -1
  203. package/dist/workflows/weaver-bot.js +1119 -36
  204. package/dist/workflows/weaver-bot.js.map +1 -1
  205. package/flowweaver.manifest.json +113 -2
  206. package/package.json +5 -2
  207. package/src/bot/ai-client.ts +180 -19
  208. package/src/bot/assistant-core.ts +306 -0
  209. package/src/bot/assistant-tools.ts +605 -0
  210. package/src/bot/audit-logger.ts +6 -5
  211. package/src/bot/audit-store.ts +3 -12
  212. package/src/bot/bot-manager.ts +293 -0
  213. package/src/bot/child-process-tracker.ts +40 -0
  214. package/src/bot/cli-provider.ts +13 -8
  215. package/src/bot/conversation-store.ts +222 -0
  216. package/src/bot/cost-store.ts +11 -12
  217. package/src/bot/error-guide.ts +34 -0
  218. package/src/bot/genesis-store.ts +11 -17
  219. package/src/bot/index.ts +5 -0
  220. package/src/bot/knowledge-store.ts +59 -0
  221. package/src/bot/pipeline-runner.ts +7 -1
  222. package/src/bot/retry-utils.ts +76 -0
  223. package/src/bot/run-store.ts +2 -11
  224. package/src/bot/runner.ts +26 -3
  225. package/src/bot/safe-json.ts +76 -0
  226. package/src/bot/safe-path.ts +44 -0
  227. package/src/bot/session-state.ts +2 -1
  228. package/src/bot/steering.ts +1 -1
  229. package/src/bot/step-executor.ts +313 -5
  230. package/src/bot/system-prompt.ts +70 -47
  231. package/src/bot/task-decomposer.ts +100 -0
  232. package/src/bot/task-queue.ts +119 -15
  233. package/src/bot/terminal-renderer.ts +241 -0
  234. package/src/bot/types.ts +8 -0
  235. package/src/bot/weaver-tools.ts +225 -0
  236. package/src/cli-bridge.ts +14 -3
  237. package/src/cli-handlers.ts +760 -29
  238. package/src/handlers/on-bot-completed.ts +48 -0
  239. package/src/handlers/on-execution-failure.ts +42 -0
  240. package/src/handlers/scheduled-run.ts +42 -0
  241. package/src/index.ts +5 -0
  242. package/src/mcp-tools.ts +2 -2
  243. package/src/node-types/abort-task.ts +5 -4
  244. package/src/node-types/agent-execute.ts +306 -0
  245. package/src/node-types/bot-report.ts +40 -9
  246. package/src/node-types/build-context.ts +112 -25
  247. package/src/node-types/detect-provider.ts +4 -3
  248. package/src/node-types/exec-validate-retry.ts +47 -8
  249. package/src/node-types/execute-plan.ts +32 -8
  250. package/src/node-types/execute-target.ts +2 -1
  251. package/src/node-types/fix-errors.ts +20 -5
  252. package/src/node-types/genesis-observe.ts +2 -1
  253. package/src/node-types/genesis-report.ts +1 -1
  254. package/src/node-types/git-ops.ts +93 -4
  255. package/src/node-types/index.ts +2 -0
  256. package/src/node-types/load-config.ts +3 -3
  257. package/src/node-types/plan-task.ts +15 -3
  258. package/src/node-types/read-workflow.ts +2 -2
  259. package/src/node-types/receive-task.ts +31 -26
  260. package/src/node-types/send-notify.ts +1 -1
  261. package/src/node-types/validate-gate.ts +112 -0
  262. package/src/workflows/genesis-task.ts +20 -12
  263. package/src/workflows/weaver-agent.ts +799 -0
  264. package/src/workflows/weaver-bot-batch.ts +1049 -27
  265. package/src/workflows/weaver-bot.ts +1123 -36
@@ -29,7 +29,12 @@ export async function weaverPlanTask(
29
29
  }
30
30
 
31
31
  const { providerInfo: pInfo } = env;
32
- const task = JSON.parse(context.taskJson!);
32
+
33
+ if (!context.taskJson) {
34
+ context.planJson = JSON.stringify({ steps: [], summary: 'Planning failed: missing taskJson' });
35
+ return { onSuccess: false, onFailure: true, ctx: JSON.stringify(context) };
36
+ }
37
+ const task = JSON.parse(context.taskJson);
33
38
 
34
39
  let systemPrompt: string;
35
40
  try {
@@ -42,11 +47,18 @@ export async function weaverPlanTask(
42
47
  } catch { /* older flow-weaver version */ }
43
48
  const botPrompt = mod.buildBotSystemPrompt(context.contextBundle!, cliCommands);
44
49
  systemPrompt = basePrompt + '\n\n' + botPrompt;
45
- } catch {
50
+ } catch (err) {
51
+ if (process.env.WEAVER_VERBOSE) console.error('[plan-task] system prompt build failed:', err);
46
52
  systemPrompt = 'You are Weaver, an AI workflow bot. Return ONLY valid JSON with a plan.';
47
53
  }
48
54
 
49
- const userPrompt = `Task: ${task.instruction}\nMode: ${task.mode ?? 'create'}\n${task.targets ? 'Targets: ' + task.targets.join(', ') : ''}\n\nPlan this task. Return a JSON plan with steps and summary.`;
55
+ const userPrompt = `Task: ${task.instruction}\nMode: ${task.mode ?? 'create'}\n${task.targets ? 'Targets: ' + task.targets.join(', ') : ''}
56
+
57
+ Plan this task. IMPORTANT rules:
58
+ 1. Every step MUST have complete, concrete args — no empty patches, no placeholders.
59
+ 2. If you need to discover file contents or errors before fixing, plan ONLY the discovery steps (run-shell, read-file, list-files) in this first plan. The system will automatically provide a second planning round with actual errors if validation fails.
60
+ 3. Do NOT plan patch-file steps unless you already know the exact find/replace strings.
61
+ 4. Prefer run-shell with "npx flow-weaver validate <file> --json" to discover errors, then read-file to see the file, then patch-file with exact strings.`;
50
62
 
51
63
  try {
52
64
  const text = await callAI(pInfo, systemPrompt, userPrompt, 8192);
@@ -47,7 +47,7 @@ export function weaverReadWorkflow(ctx: string): { ctx: string } {
47
47
  timeout: 30_000,
48
48
  cwd: projectDir,
49
49
  }).trim();
50
- } catch { /* diagram generation failed, continue without it */ }
50
+ } catch (err) { if (process.env.WEAVER_VERBOSE) console.error('[read-workflow] diagram failed:', err); }
51
51
 
52
52
  try {
53
53
  description = execFileSync('flow-weaver', ['describe', filePath], {
@@ -56,7 +56,7 @@ export function weaverReadWorkflow(ctx: string): { ctx: string } {
56
56
  timeout: 30_000,
57
57
  cwd: projectDir,
58
58
  }).trim();
59
- } catch { /* description failed, continue without it */ }
59
+ } catch (err) { if (process.env.WEAVER_VERBOSE) console.error('[read-workflow] describe failed:', err); }
60
60
 
61
61
  results.push({ file: target, source, diagram, description });
62
62
  console.log(`\x1b[36m→ Read: ${target}\x1b[0m`);
@@ -2,6 +2,7 @@ import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import * as os from 'node:os';
4
4
  import type { WeaverEnv, WeaverContext } from '../bot/types.js';
5
+ import { withFileLock } from '../bot/file-lock.js';
5
6
 
6
7
  interface QueuedTask {
7
8
  id: string;
@@ -54,38 +55,42 @@ export async function weaverReceiveTask(
54
55
  } catch { /* fall through to queue check */ }
55
56
  }
56
57
 
57
- // Check task queue
58
+ // Check task queue (with file locking to prevent race conditions)
58
59
  const queuePath = path.join(os.homedir(), '.weaver', 'task-queue.ndjson');
59
60
  try {
60
- if (fs.existsSync(queuePath)) {
61
+ const claimed = await withFileLock(queuePath, () => {
62
+ if (!fs.existsSync(queuePath)) return null;
61
63
  const content = fs.readFileSync(queuePath, 'utf-8').trim();
62
- if (content) {
63
- const tasks: QueuedTask[] = content.split('\n').map(l => JSON.parse(l));
64
- const pending = tasks
65
- .filter(t => t.status === 'pending')
66
- .sort((a, b) => b.priority - a.priority || a.addedAt - b.addedAt);
64
+ if (!content) return null;
67
65
 
68
- if (pending.length > 0) {
69
- const task = pending[0]!;
70
- // Mark as running
71
- const updated = tasks.map(t => t.id === task.id ? { ...t, status: 'running' } : t);
72
- fs.writeFileSync(queuePath, updated.map(t => JSON.stringify(t)).join('\n') + '\n', 'utf-8');
66
+ const tasks: QueuedTask[] = content.split('\n').filter(Boolean).map(l => JSON.parse(l));
67
+ const pending = tasks
68
+ .filter(t => t.status === 'pending')
69
+ .sort((a, b) => b.priority - a.priority || a.addedAt - b.addedAt);
73
70
 
74
- const botTask = {
75
- instruction: task.instruction,
76
- mode: task.mode ?? 'create',
77
- targets: task.targets,
78
- options: task.options,
79
- queueId: task.id,
80
- };
81
- console.log(`\x1b[36m→ Task from queue [${task.id}]: ${task.instruction.slice(0, 80)}\x1b[0m`);
82
- context.taskJson = JSON.stringify(botTask);
83
- context.hasTask = true;
84
- return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
85
- }
86
- }
71
+ if (pending.length === 0) return null;
72
+
73
+ const task = pending[0]!;
74
+ // Atomically mark as running inside the lock
75
+ const updated = tasks.map(t => t.id === task.id ? { ...t, status: 'running' } : t);
76
+ fs.writeFileSync(queuePath, updated.map(t => JSON.stringify(t)).join('\n') + '\n', 'utf-8');
77
+ return task;
78
+ });
79
+
80
+ if (claimed) {
81
+ const botTask = {
82
+ instruction: claimed.instruction,
83
+ mode: claimed.mode ?? 'create',
84
+ targets: claimed.targets,
85
+ options: claimed.options,
86
+ queueId: claimed.id,
87
+ };
88
+ console.log(`\x1b[36m→ Task from queue [${claimed.id}]: ${claimed.instruction.slice(0, 80)}\x1b[0m`);
89
+ context.taskJson = JSON.stringify(botTask);
90
+ context.hasTask = true;
91
+ return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
87
92
  }
88
- } catch { /* ignore queue errors */ }
93
+ } catch (err) { if (process.env.WEAVER_VERBOSE) console.error('[receive-task] queue error:', err); }
89
94
 
90
95
  console.log('\x1b[33m→ No task found\x1b[0m');
91
96
  return { onSuccess: false, onFailure: true, ctx: JSON.stringify(context) };
@@ -40,7 +40,7 @@ function sendWebhook(
40
40
  headers,
41
41
  body,
42
42
  signal: AbortSignal.timeout(10_000),
43
- }).catch(() => {});
43
+ }).catch((err) => { if (process.env.WEAVER_VERBOSE) console.error('[send-notify] webhook failed:', err); });
44
44
  }
45
45
 
46
46
  /**
@@ -0,0 +1,112 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import * as path from 'node:path';
3
+ import type { WeaverContext } from '../bot/types.js';
4
+
5
+ /**
6
+ * Post-agent validation gate. Runs `flow-weaver validate` on all modified files
7
+ * and fails the task if any have errors. Don't trust the AI's self-assessment.
8
+ *
9
+ * @flowWeaver nodeType
10
+ * @expression
11
+ * @label Validate Gate
12
+ * @input ctx [order:0] - Weaver context (JSON)
13
+ * @output ctx [order:0] - Weaver context with validation result (JSON)
14
+ * @output onSuccess [order:-2] - All files valid
15
+ * @output onFailure [order:-1] [hidden] - Validation failed
16
+ */
17
+ export function weaverValidateGate(ctx: string): {
18
+ ctx: string;
19
+ onSuccess: boolean;
20
+ onFailure: boolean;
21
+ } {
22
+ const context = JSON.parse(ctx) as WeaverContext;
23
+ const { projectDir } = context.env;
24
+ const files: string[] = context.filesModified ? JSON.parse(context.filesModified) : [];
25
+
26
+ if (files.length === 0) {
27
+ context.validationResultJson = JSON.stringify({ skipped: true, reason: 'no files modified' });
28
+ return { ctx: JSON.stringify(context), onSuccess: true, onFailure: false };
29
+ }
30
+
31
+ // Only validate .ts files that look like workflows or node types
32
+ const toValidate = files.filter(f => f.endsWith('.ts'));
33
+ if (toValidate.length === 0) {
34
+ context.validationResultJson = JSON.stringify({ skipped: true, reason: 'no .ts files' });
35
+ return { ctx: JSON.stringify(context), onSuccess: true, onFailure: false };
36
+ }
37
+
38
+ const errors: Array<{ file: string; errorCount: number; errors: string[] }> = [];
39
+ let allValid = true;
40
+
41
+ for (const file of toValidate) {
42
+ const absPath = path.isAbsolute(file) ? file : path.resolve(projectDir, file);
43
+ try {
44
+ const output = execFileSync(
45
+ 'npx',
46
+ ['flow-weaver', 'validate', absPath, '--json'],
47
+ { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 30_000, cwd: projectDir },
48
+ ).trim();
49
+
50
+ // Parse JSON output — look for errors (not warnings)
51
+ let result: { errors?: Array<{ message: string }>; errorCount?: number };
52
+ try {
53
+ result = JSON.parse(output);
54
+ } catch {
55
+ // Non-JSON output — try to detect errors from text
56
+ const hasErrors = output.includes('error') && !output.includes('0 error');
57
+ if (hasErrors) {
58
+ errors.push({ file, errorCount: 1, errors: [output.slice(0, 200)] });
59
+ allValid = false;
60
+ }
61
+ continue;
62
+ }
63
+
64
+ const errorCount = result.errorCount ?? result.errors?.length ?? 0;
65
+ if (errorCount > 0) {
66
+ allValid = false;
67
+ errors.push({
68
+ file,
69
+ errorCount,
70
+ errors: (result.errors ?? []).map(e => e.message).slice(0, 5),
71
+ });
72
+ }
73
+ } catch (err: unknown) {
74
+ // validate command failed — could be a parse error, treat as validation failure
75
+ const msg = err instanceof Error ? err.message : String(err);
76
+ // But don't fail on "not a workflow" — only on actual errors
77
+ if (!msg.includes('No @flowWeaver annotation') && !msg.includes('not a workflow')) {
78
+ errors.push({ file, errorCount: 1, errors: [msg.slice(0, 200)] });
79
+ allValid = false;
80
+ }
81
+ }
82
+ }
83
+
84
+ // Also run tsc --noEmit if any .ts files were modified (catches type errors FW validate misses)
85
+ if (allValid && toValidate.length > 0) {
86
+ try {
87
+ execFileSync('npx', ['tsc', '--noEmit', '--pretty'], {
88
+ cwd: projectDir, encoding: 'utf-8', timeout: 60_000, stdio: ['pipe', 'pipe', 'pipe'],
89
+ });
90
+ } catch (err: unknown) {
91
+ const tscOutput = (err as { stdout?: string }).stdout ?? (err instanceof Error ? err.message : '');
92
+ if (tscOutput.includes('error TS')) {
93
+ allValid = false;
94
+ errors.push({ file: '(tsc)', errorCount: 1, errors: [tscOutput.slice(0, 500)] });
95
+ }
96
+ }
97
+ }
98
+
99
+ context.validationResultJson = JSON.stringify({ errors, allValid });
100
+ context.allValid = allValid;
101
+
102
+ if (!allValid && process.env.WEAVER_VERBOSE) {
103
+ for (const e of errors) {
104
+ process.stderr.write(`\x1b[31m ✗ ${e.file}: ${e.errorCount} error(s)\x1b[0m\n`);
105
+ for (const msg of e.errors) {
106
+ process.stderr.write(`\x1b[31m ${msg}\x1b[0m\n`);
107
+ }
108
+ }
109
+ }
110
+
111
+ return { ctx: JSON.stringify(context), onSuccess: allValid, onFailure: !allValid };
112
+ }
@@ -33,40 +33,48 @@ import { genesisEscrowGrace } from '../node-types/genesis-escrow-grace.js';
33
33
  * @flowWeaver workflow
34
34
  *
35
35
  * @node cfg weaverLoadConfig [color: "teal"] [icon: "settings"] [position: 200 200]
36
- * @node detect weaverDetectProvider [color: "cyan"] [icon: "search"] [position: 400 200]
36
+ * @node detect weaverDetectProvider [color: "cyan"] [icon: "search"] [position: 400 200] [suppress: "OBJECT_TYPE_MISMATCH", "ANNOTATION_SIGNATURE_TYPE_MISMATCH"]
37
37
  * @node gCfg genesisLoadConfig [color: "purple"] [icon: "settings"] [position: 600 200]
38
- * @node escRecover genesisEscrowRecover [color: "yellow"] [icon: "healing"] [position: 750 200]
38
+ * @node escRecover genesisEscrowRecover [color: "yellow"] [icon: "healthAndSafety"] [position: 750 200]
39
39
  * @node observe genesisObserve [color: "blue"] [icon: "visibility"] [position: 900 200]
40
- * @node diffFp genesisDiffFingerprint [color: "cyan"] [icon: "compare"] [position: 1100 200]
40
+ * @node diffFp genesisDiffFingerprint [color: "cyan"] [icon: "assessment"] [position: 1100 200]
41
41
  * @node stabilize genesisCheckStabilize [color: "orange"] [icon: "lock"] [position: 1300 200]
42
42
  * @node propose genesisPropose [color: "blue"] [icon: "psychology"] [position: 1500 200]
43
- * @node validate genesisValidateProposal [color: "teal"] [icon: "check"] [position: 1700 200]
43
+ * @node validate genesisValidateProposal [color: "teal"] [icon: "checkCircle"] [position: 1700 200]
44
44
  * @node snapshot genesisSnapshot [color: "cyan"] [icon: "backup"] [position: 1900 200]
45
- * @node applyRetry genesisApplyRetry [color: "purple"] [icon: "replay"] [position: 2100 200] [size: 300 200]
46
- * @node tryApply genesisTryApply applyRetry.attempt [position: 2150 230]
47
- * @node diffWf genesisDiffWorkflow [color: "cyan"] [icon: "compare"] [position: 2440 200]
45
+ * @node applyRetry genesisApplyRetry [color: "purple"] [icon: "repeat"] [position: 2100 200] [size: 300 200] [suppress: "DESIGN_UNBOUNDED_RETRY"]
46
+ * @node tryApply genesisTryApply applyRetry.attempt [position: 2150 230] [suppress: "DESIGN_PULL_CANDIDATE"]
47
+ * @node diffWf genesisDiffWorkflow [color: "cyan"] [icon: "altRoute"] [position: 2440 200]
48
48
  * @node threshold genesisCheckThreshold [color: "orange"] [icon: "tune"] [position: 2640 200]
49
49
  * @node approve genesisApprove [color: "orange"] [icon: "send"] [position: 2840 200]
50
50
  * @node commit genesisCommit [color: "green"] [icon: "save"] [position: 3040 200]
51
- * @node escStage genesisEscrowStage [color: "yellow"] [icon: "archive"] [position: 3240 400]
51
+ * @node escStage genesisEscrowStage [color: "yellow"] [icon: "storage"] [position: 3240 400]
52
52
  * @node escVal genesisEscrowValidate [color: "yellow"] [icon: "verified"] [position: 3440 400]
53
- * @node escMig genesisEscrowMigrate [color: "yellow"] [icon: "swap_horiz"] [position: 3640 400]
54
- * @node history genesisUpdateHistory [color: "teal"] [icon: "history"] [position: 3840 200]
53
+ * @node escMig genesisEscrowMigrate [color: "yellow"] [icon: "sync"] [position: 3640 400]
54
+ * @node history genesisUpdateHistory [color: "teal"] [icon: "receipt"] [position: 3840 200]
55
55
  * @node escGrace genesisEscrowGrace [color: "yellow"] [icon: "timer"] [position: 4040 200]
56
56
  * @node report genesisReport [color: "green"] [icon: "description"] [position: 4240 200]
57
57
  *
58
58
  * @path Start -> cfg -> detect -> gCfg -> escRecover -> observe -> diffFp -> stabilize -> propose -> validate -> snapshot -> applyRetry -> diffWf -> threshold -> approve -> commit -> escStage -> escVal -> escMig -> history -> escGrace -> report -> Exit
59
59
  *
60
60
  * @path applyRetry:fail -> report
61
+ * @path observe:fail -> report
62
+ * @path propose:fail -> report
63
+ * @path approve:fail -> report
64
+ * @path commit:fail -> report
61
65
  * @path escStage:fail -> report
62
66
  * @path escVal:fail -> report
63
67
  * @path escMig:fail -> report
64
68
  *
65
69
  * @connect applyRetry.attemptCtx:attempt -> tryApply.ctx
66
70
  * @connect tryApply.ctx -> applyRetry.attemptCtx:attempt
71
+ * @connect tryApply.onSuccess -> applyRetry.success:attempt
72
+ * @connect tryApply.onFailure -> applyRetry.failure:attempt
67
73
  *
68
- * @connect history.ctx -> report.successCtx
74
+ * @connect escGrace.ctx -> report.successCtx
69
75
  * @connect applyRetry.ctx -> report.failCtx
76
+ * @connect propose.ctx -> report.proposeFailCtx
77
+ * @connect commit.ctx -> report.commitFailCtx
70
78
  *
71
79
  * @connect report.summary -> Exit.summary
72
80
  *
@@ -74,7 +82,7 @@ import { genesisEscrowGrace } from '../node-types/genesis-escrow-grace.js';
74
82
  * @position Exit 4440 200
75
83
  *
76
84
  * @param execute [order:-1] - Execute
77
- * @param projectDir [order:0] [optional] - Project directory
85
+ * @param [projectDir] [order:0] - Project directory
78
86
  * @returns onSuccess [order:-2] - On Success
79
87
  * @returns onFailure [order:-1] [hidden] - On Failure
80
88
  * @returns summary [order:0] - Summary text