@synergenius/flow-weaver-pack-weaver 0.9.7 → 0.9.9

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 (224) hide show
  1. package/dist/bot/agent-loop.d.ts +20 -0
  2. package/dist/bot/agent-loop.d.ts.map +1 -0
  3. package/dist/bot/agent-loop.js +331 -0
  4. package/dist/bot/agent-loop.js.map +1 -0
  5. package/dist/bot/agent-provider.d.ts.map +1 -1
  6. package/dist/bot/agent-provider.js +3 -2
  7. package/dist/bot/agent-provider.js.map +1 -1
  8. package/dist/bot/approvals.js +17 -8
  9. package/dist/bot/approvals.js.map +1 -1
  10. package/dist/bot/assistant-core.d.ts +17 -0
  11. package/dist/bot/assistant-core.d.ts.map +1 -1
  12. package/dist/bot/assistant-core.js +418 -60
  13. package/dist/bot/assistant-core.js.map +1 -1
  14. package/dist/bot/assistant-tools.d.ts +1 -1
  15. package/dist/bot/assistant-tools.d.ts.map +1 -1
  16. package/dist/bot/assistant-tools.js +283 -9
  17. package/dist/bot/assistant-tools.js.map +1 -1
  18. package/dist/bot/bot-agent-channel.d.ts.map +1 -1
  19. package/dist/bot/bot-agent-channel.js +2 -0
  20. package/dist/bot/bot-agent-channel.js.map +1 -1
  21. package/dist/bot/bot-manager.d.ts +4 -0
  22. package/dist/bot/bot-manager.d.ts.map +1 -1
  23. package/dist/bot/bot-manager.js +72 -27
  24. package/dist/bot/bot-manager.js.map +1 -1
  25. package/dist/bot/conversation-store.d.ts +6 -5
  26. package/dist/bot/conversation-store.d.ts.map +1 -1
  27. package/dist/bot/conversation-store.js +98 -42
  28. package/dist/bot/conversation-store.js.map +1 -1
  29. package/dist/bot/cost-store.d.ts +3 -0
  30. package/dist/bot/cost-store.d.ts.map +1 -1
  31. package/dist/bot/cost-store.js +21 -10
  32. package/dist/bot/cost-store.js.map +1 -1
  33. package/dist/bot/cost-tracker.d.ts.map +1 -1
  34. package/dist/bot/cost-tracker.js +14 -1
  35. package/dist/bot/cost-tracker.js.map +1 -1
  36. package/dist/bot/cron-parser.d.ts.map +1 -1
  37. package/dist/bot/cron-parser.js +2 -0
  38. package/dist/bot/cron-parser.js.map +1 -1
  39. package/dist/bot/cron-scheduler.d.ts.map +1 -1
  40. package/dist/bot/cron-scheduler.js +1 -0
  41. package/dist/bot/cron-scheduler.js.map +1 -1
  42. package/dist/bot/device-connection.d.ts +13 -0
  43. package/dist/bot/device-connection.d.ts.map +1 -0
  44. package/dist/bot/device-connection.js +102 -0
  45. package/dist/bot/device-connection.js.map +1 -0
  46. package/dist/bot/error-classifier.d.ts.map +1 -1
  47. package/dist/bot/error-classifier.js +5 -0
  48. package/dist/bot/error-classifier.js.map +1 -1
  49. package/dist/bot/file-lock.d.ts.map +1 -1
  50. package/dist/bot/file-lock.js +13 -3
  51. package/dist/bot/file-lock.js.map +1 -1
  52. package/dist/bot/file-watcher.d.ts.map +1 -1
  53. package/dist/bot/file-watcher.js +1 -0
  54. package/dist/bot/file-watcher.js.map +1 -1
  55. package/dist/bot/genesis-prompt-context.d.ts +5 -0
  56. package/dist/bot/genesis-prompt-context.d.ts.map +1 -1
  57. package/dist/bot/genesis-prompt-context.js +55 -0
  58. package/dist/bot/genesis-prompt-context.js.map +1 -1
  59. package/dist/bot/genesis-store.d.ts +4 -0
  60. package/dist/bot/genesis-store.d.ts.map +1 -1
  61. package/dist/bot/genesis-store.js +79 -12
  62. package/dist/bot/genesis-store.js.map +1 -1
  63. package/dist/bot/improve-loop.d.ts +46 -0
  64. package/dist/bot/improve-loop.d.ts.map +1 -0
  65. package/dist/bot/improve-loop.js +592 -0
  66. package/dist/bot/improve-loop.js.map +1 -0
  67. package/dist/bot/insight-engine.d.ts +12 -0
  68. package/dist/bot/insight-engine.d.ts.map +1 -0
  69. package/dist/bot/insight-engine.js +256 -0
  70. package/dist/bot/insight-engine.js.map +1 -0
  71. package/dist/bot/knowledge-store.d.ts.map +1 -1
  72. package/dist/bot/knowledge-store.js +4 -1
  73. package/dist/bot/knowledge-store.js.map +1 -1
  74. package/dist/bot/pipeline-runner.d.ts.map +1 -1
  75. package/dist/bot/pipeline-runner.js +12 -4
  76. package/dist/bot/pipeline-runner.js.map +1 -1
  77. package/dist/bot/project-model.d.ts +25 -0
  78. package/dist/bot/project-model.d.ts.map +1 -0
  79. package/dist/bot/project-model.js +372 -0
  80. package/dist/bot/project-model.js.map +1 -0
  81. package/dist/bot/response-formatter.js +2 -3
  82. package/dist/bot/response-formatter.js.map +1 -1
  83. package/dist/bot/run-store.d.ts.map +1 -1
  84. package/dist/bot/run-store.js +10 -2
  85. package/dist/bot/run-store.js.map +1 -1
  86. package/dist/bot/safe-path.d.ts +1 -1
  87. package/dist/bot/safe-path.d.ts.map +1 -1
  88. package/dist/bot/safe-path.js +20 -1
  89. package/dist/bot/safe-path.js.map +1 -1
  90. package/dist/bot/safety.d.ts +10 -2
  91. package/dist/bot/safety.d.ts.map +1 -1
  92. package/dist/bot/safety.js +45 -2
  93. package/dist/bot/safety.js.map +1 -1
  94. package/dist/bot/session-state.d.ts +4 -0
  95. package/dist/bot/session-state.d.ts.map +1 -1
  96. package/dist/bot/session-state.js +52 -9
  97. package/dist/bot/session-state.js.map +1 -1
  98. package/dist/bot/slash-commands.d.ts.map +1 -1
  99. package/dist/bot/slash-commands.js +109 -3
  100. package/dist/bot/slash-commands.js.map +1 -1
  101. package/dist/bot/steering-engine.d.ts +67 -0
  102. package/dist/bot/steering-engine.d.ts.map +1 -0
  103. package/dist/bot/steering-engine.js +198 -0
  104. package/dist/bot/steering-engine.js.map +1 -0
  105. package/dist/bot/step-executor.d.ts.map +1 -1
  106. package/dist/bot/step-executor.js +62 -25
  107. package/dist/bot/step-executor.js.map +1 -1
  108. package/dist/bot/system-prompt.d.ts.map +1 -1
  109. package/dist/bot/system-prompt.js +5 -2
  110. package/dist/bot/system-prompt.js.map +1 -1
  111. package/dist/bot/task-queue.d.ts +6 -1
  112. package/dist/bot/task-queue.d.ts.map +1 -1
  113. package/dist/bot/task-queue.js +43 -4
  114. package/dist/bot/task-queue.js.map +1 -1
  115. package/dist/bot/tool-registry.d.ts +1 -1
  116. package/dist/bot/tool-registry.d.ts.map +1 -1
  117. package/dist/bot/tool-registry.js +65 -4
  118. package/dist/bot/tool-registry.js.map +1 -1
  119. package/dist/bot/trust-calculator.d.ts +34 -0
  120. package/dist/bot/trust-calculator.d.ts.map +1 -0
  121. package/dist/bot/trust-calculator.js +67 -0
  122. package/dist/bot/trust-calculator.js.map +1 -0
  123. package/dist/bot/types.d.ts +97 -0
  124. package/dist/bot/types.d.ts.map +1 -1
  125. package/dist/bot/update-checker.d.ts +21 -0
  126. package/dist/bot/update-checker.d.ts.map +1 -0
  127. package/dist/bot/update-checker.js +129 -0
  128. package/dist/bot/update-checker.js.map +1 -0
  129. package/dist/bot/weaver-tools.d.ts.map +1 -1
  130. package/dist/bot/weaver-tools.js +11 -4
  131. package/dist/bot/weaver-tools.js.map +1 -1
  132. package/dist/cli-bridge.d.ts +2 -0
  133. package/dist/cli-bridge.d.ts.map +1 -1
  134. package/dist/cli-bridge.js +3 -1
  135. package/dist/cli-bridge.js.map +1 -1
  136. package/dist/cli-handlers.d.ts +10 -1
  137. package/dist/cli-handlers.d.ts.map +1 -1
  138. package/dist/cli-handlers.js +141 -24
  139. package/dist/cli-handlers.js.map +1 -1
  140. package/dist/cli.d.ts +3 -0
  141. package/dist/cli.d.ts.map +1 -0
  142. package/dist/cli.js +749 -0
  143. package/dist/cli.js.map +1 -0
  144. package/dist/docs/weaver-config.md +15 -9
  145. package/dist/handlers/on-execution-completed.d.ts +11 -0
  146. package/dist/handlers/on-execution-completed.d.ts.map +1 -0
  147. package/dist/handlers/on-execution-completed.js +25 -0
  148. package/dist/handlers/on-execution-completed.js.map +1 -0
  149. package/dist/mcp-tools.d.ts.map +1 -1
  150. package/dist/mcp-tools.js +33 -0
  151. package/dist/mcp-tools.js.map +1 -1
  152. package/dist/node-types/genesis-approve.d.ts.map +1 -1
  153. package/dist/node-types/genesis-approve.js +28 -3
  154. package/dist/node-types/genesis-approve.js.map +1 -1
  155. package/dist/node-types/genesis-observe.d.ts.map +1 -1
  156. package/dist/node-types/genesis-observe.js +23 -13
  157. package/dist/node-types/genesis-observe.js.map +1 -1
  158. package/dist/node-types/genesis-propose.d.ts.map +1 -1
  159. package/dist/node-types/genesis-propose.js +8 -0
  160. package/dist/node-types/genesis-propose.js.map +1 -1
  161. package/dist/node-types/genesis-update-history.d.ts.map +1 -1
  162. package/dist/node-types/genesis-update-history.js +13 -0
  163. package/dist/node-types/genesis-update-history.js.map +1 -1
  164. package/dist/templates/weaver-template.d.ts +11 -0
  165. package/dist/templates/weaver-template.d.ts.map +1 -0
  166. package/dist/templates/weaver-template.js +53 -0
  167. package/dist/templates/weaver-template.js.map +1 -0
  168. package/dist/workflows/weaver-bot-session.d.ts +65 -0
  169. package/dist/workflows/weaver-bot-session.d.ts.map +1 -0
  170. package/dist/workflows/weaver-bot-session.js +68 -0
  171. package/dist/workflows/weaver-bot-session.js.map +1 -0
  172. package/dist/workflows/weaver.d.ts +24 -0
  173. package/dist/workflows/weaver.d.ts.map +1 -0
  174. package/dist/workflows/weaver.js +28 -0
  175. package/dist/workflows/weaver.js.map +1 -0
  176. package/flowweaver.manifest.json +28 -1
  177. package/package.json +6 -3
  178. package/src/bot/agent-provider.ts +3 -2
  179. package/src/bot/approvals.ts +16 -8
  180. package/src/bot/assistant-core.ts +420 -63
  181. package/src/bot/assistant-tools.ts +291 -9
  182. package/src/bot/bot-agent-channel.ts +2 -0
  183. package/src/bot/bot-manager.ts +70 -29
  184. package/src/bot/conversation-store.ts +87 -42
  185. package/src/bot/cost-store.ts +20 -9
  186. package/src/bot/cost-tracker.ts +13 -1
  187. package/src/bot/cron-parser.ts +1 -0
  188. package/src/bot/cron-scheduler.ts +1 -0
  189. package/src/bot/device-connection.ts +102 -0
  190. package/src/bot/error-classifier.ts +5 -0
  191. package/src/bot/file-lock.ts +12 -2
  192. package/src/bot/file-watcher.ts +1 -0
  193. package/src/bot/genesis-prompt-context.ts +61 -0
  194. package/src/bot/genesis-store.ts +68 -16
  195. package/src/bot/improve-loop.ts +651 -0
  196. package/src/bot/insight-engine.ts +273 -0
  197. package/src/bot/knowledge-store.ts +4 -1
  198. package/src/bot/pipeline-runner.ts +11 -6
  199. package/src/bot/project-model.ts +404 -0
  200. package/src/bot/response-formatter.ts +2 -3
  201. package/src/bot/run-store.ts +5 -2
  202. package/src/bot/safe-path.ts +20 -1
  203. package/src/bot/safety.ts +57 -3
  204. package/src/bot/session-state.ts +47 -7
  205. package/src/bot/slash-commands.ts +111 -3
  206. package/src/bot/steering-engine.ts +233 -0
  207. package/src/bot/step-executor.ts +66 -26
  208. package/src/bot/system-prompt.ts +5 -2
  209. package/src/bot/task-queue.ts +40 -4
  210. package/src/bot/tool-registry.ts +67 -5
  211. package/src/bot/trust-calculator.ts +87 -0
  212. package/src/bot/types.ts +104 -0
  213. package/src/bot/update-checker.ts +138 -0
  214. package/src/bot/weaver-tools.ts +10 -4
  215. package/src/cli-bridge.ts +4 -1
  216. package/src/cli-handlers.ts +150 -29
  217. package/src/handlers/on-execution-completed.ts +30 -0
  218. package/src/mcp-tools.ts +38 -0
  219. package/src/node-types/genesis-approve.ts +28 -3
  220. package/src/node-types/genesis-observe.ts +23 -12
  221. package/src/node-types/genesis-propose.ts +8 -0
  222. package/src/node-types/genesis-update-history.ts +12 -0
  223. package/src/ui/evolution-panel.tsx +96 -0
  224. package/src/ui/insights-widget.tsx +77 -0
@@ -8,7 +8,7 @@ import type { ToolDefinition } from '@synergenius/flow-weaver/agent';
8
8
 
9
9
  export interface WeaverTool extends ToolDefinition {
10
10
  verboseOutput?: boolean;
11
- category: 'bot-management' | 'queue' | 'flow-weaver' | 'project' | 'knowledge' | 'conversation' | 'ci' | 'web';
11
+ category: 'bot-management' | 'queue' | 'flow-weaver' | 'project' | 'knowledge' | 'conversation' | 'ci' | 'web' | 'overseer';
12
12
  contexts: Array<'bot' | 'assistant'>;
13
13
  }
14
14
 
@@ -290,7 +290,7 @@ export const ALL_TOOLS: WeaverTool[] = [
290
290
  required: ['file', 'patches'],
291
291
  },
292
292
  category: 'project',
293
- contexts: ['bot'],
293
+ contexts: ['bot', 'assistant'],
294
294
  },
295
295
  {
296
296
  name: 'write_file',
@@ -304,7 +304,7 @@ export const ALL_TOOLS: WeaverTool[] = [
304
304
  required: ['file', 'content'],
305
305
  },
306
306
  category: 'project',
307
- contexts: ['bot'],
307
+ contexts: ['bot', 'assistant'],
308
308
  },
309
309
  {
310
310
  name: 'tsc_check',
@@ -312,7 +312,7 @@ export const ALL_TOOLS: WeaverTool[] = [
312
312
  inputSchema: { type: 'object', properties: {}, required: [] },
313
313
  verboseOutput: true,
314
314
  category: 'project',
315
- contexts: ['bot'],
315
+ contexts: ['bot', 'assistant'],
316
316
  },
317
317
  {
318
318
  name: 'run_tests',
@@ -320,7 +320,7 @@ export const ALL_TOOLS: WeaverTool[] = [
320
320
  inputSchema: { type: 'object', properties: { pattern: { type: 'string', description: 'Test file pattern (optional)' } }, required: [] },
321
321
  verboseOutput: true,
322
322
  category: 'project',
323
- contexts: ['bot'],
323
+ contexts: ['bot', 'assistant'],
324
324
  },
325
325
  {
326
326
  name: 'project_list',
@@ -434,6 +434,68 @@ export const ALL_TOOLS: WeaverTool[] = [
434
434
  contexts: ['bot', 'assistant'],
435
435
  },
436
436
 
437
+ // ── Overseer tools (assistant only) ─────────────────────────────
438
+ {
439
+ name: 'project_health',
440
+ description: 'Get project health: workflow scores, bot performance, failure patterns, cost trends, trust level.',
441
+ inputSchema: { type: 'object', properties: {}, required: [] },
442
+ category: 'overseer',
443
+ contexts: ['assistant'],
444
+ },
445
+ {
446
+ name: 'project_insights',
447
+ description: 'Get actionable insights: recurring failures, degrading workflows, cost optimizations, evolution opportunities.',
448
+ inputSchema: {
449
+ type: 'object',
450
+ properties: { limit: { type: 'number', description: 'Max insights (default 5)' } },
451
+ required: [],
452
+ },
453
+ category: 'overseer',
454
+ contexts: ['assistant'],
455
+ },
456
+ {
457
+ name: 'evolution_status',
458
+ description: 'Get genesis evolution history: cycle outcomes, operation effectiveness, recent proposals.',
459
+ inputSchema: { type: 'object', properties: {}, required: [] },
460
+ category: 'overseer',
461
+ contexts: ['assistant'],
462
+ },
463
+ {
464
+ name: 'genesis_propose',
465
+ description: 'Generate a Genesis evolution proposal for a bot workflow based on project insights. Auto-ejects bot if needed.',
466
+ inputSchema: {
467
+ type: 'object',
468
+ properties: {
469
+ bot: { type: 'string', description: 'Bot name (default: weaver-bot)' },
470
+ focus: { type: 'string', description: 'Optional focus area for the proposal' },
471
+ budget: { type: 'number', description: 'Cost unit budget (default: from config)' },
472
+ },
473
+ required: [],
474
+ },
475
+ category: 'overseer',
476
+ contexts: ['assistant'],
477
+ },
478
+ {
479
+ name: 'improve_status',
480
+ description: 'Get status of the current or most recent weaver improve run — cycles, commits, successes, failures.',
481
+ inputSchema: { type: 'object', properties: {}, required: [] },
482
+ category: 'overseer',
483
+ contexts: ['assistant'],
484
+ },
485
+ {
486
+ name: 'genesis_apply',
487
+ description: 'Apply an approved Genesis proposal to the bot workflow.',
488
+ inputSchema: {
489
+ type: 'object',
490
+ properties: {
491
+ proposal_id: { type: 'string', description: 'Proposal ID from genesis_propose' },
492
+ },
493
+ required: ['proposal_id'],
494
+ },
495
+ category: 'overseer',
496
+ contexts: ['assistant'],
497
+ },
498
+
437
499
  // ── Bot-only interactive ─────────────────────────────────────────
438
500
  {
439
501
  name: 'ask_user',
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Trust Calculator — pure function that derives a trust level from the project model.
3
+ *
4
+ * Trust phases:
5
+ * Phase 1: Insights + suggestions (default)
6
+ * Phase 2: Proposals with explanation
7
+ * Phase 3: Proposals with visual diff
8
+ * Phase 4: Auto-apply COSMETIC changes
9
+ */
10
+
11
+ import type { TrustLevel } from './types.js';
12
+
13
+ interface TrustInput {
14
+ health: { workflows: Array<{ lastRun: string | null }> };
15
+ userPreferences: { approvalHistory: Array<{ approved: boolean; impactLevel: string }> };
16
+ evolution: { totalCycles: number; successRate: number };
17
+ cost: { last7Days: number };
18
+ _conversationCount?: number;
19
+ }
20
+
21
+ export function computeTrustLevel(model: TrustInput): TrustLevel {
22
+ const conversationCount = model._conversationCount ?? 0;
23
+ const approvalHistory = model.userPreferences.approvalHistory;
24
+ const approvalCount = approvalHistory.length;
25
+ const approvalRate = approvalCount > 0
26
+ ? approvalHistory.filter(a => a.approved).length / approvalCount
27
+ : 0;
28
+ const genesisSuccessRate = model.evolution.totalCycles > 0 ? model.evolution.successRate : 0;
29
+
30
+ // Estimate days since first use from earliest workflow run
31
+ const timestamps: number[] = [];
32
+ for (const w of model.health.workflows) {
33
+ if (w.lastRun) timestamps.push(new Date(w.lastRun).getTime());
34
+ }
35
+ const earliest = timestamps.length > 0 ? Math.min(...timestamps) : Date.now();
36
+ const daysSinceFirstUse = Math.max(0, Math.round((Date.now() - earliest) / 86_400_000));
37
+
38
+ // COSMETIC-specific approval rate
39
+ const cosmeticApprovals = approvalHistory.filter(a => a.impactLevel === 'COSMETIC');
40
+ const cosmeticApprovalRate = cosmeticApprovals.length > 0
41
+ ? cosmeticApprovals.filter(a => a.approved).length / cosmeticApprovals.length
42
+ : 0;
43
+
44
+ // Weighted score (0-100)
45
+ const score = Math.round(
46
+ Math.min(conversationCount / 30, 1) * 25 +
47
+ approvalRate * 25 +
48
+ genesisSuccessRate * 25 +
49
+ Math.min(daysSinceFirstUse / 30, 1) * 25,
50
+ );
51
+
52
+ // Phase thresholds
53
+ let phase: 1 | 2 | 3 | 4 = 1;
54
+ if (
55
+ conversationCount >= 30 &&
56
+ cosmeticApprovalRate >= 0.85 &&
57
+ cosmeticApprovals.length >= 3 &&
58
+ daysSinceFirstUse >= 7
59
+ ) {
60
+ phase = 4;
61
+ } else if (
62
+ conversationCount >= 15 &&
63
+ approvalRate >= 0.7 &&
64
+ approvalCount >= 5 &&
65
+ model.evolution.totalCycles >= 3 &&
66
+ genesisSuccessRate >= 0.5
67
+ ) {
68
+ phase = 3;
69
+ } else if (
70
+ conversationCount >= 5 &&
71
+ approvalCount >= 3 &&
72
+ approvalRate >= 0.6
73
+ ) {
74
+ phase = 2;
75
+ }
76
+
77
+ return {
78
+ score,
79
+ phase,
80
+ factors: {
81
+ conversationCount,
82
+ approvalConsistency: approvalRate,
83
+ genesisSuccessRate,
84
+ daysSinceFirstUse,
85
+ },
86
+ };
87
+ }
package/src/bot/types.ts CHANGED
@@ -471,6 +471,108 @@ export interface GenesisFingerprint {
471
471
  existingWorkflows: string[];
472
472
  }
473
473
 
474
+ // --- Project Model (Overseer) ---
475
+
476
+ export interface WorkflowHealth {
477
+ file: string;
478
+ score: number;
479
+ totalRuns: number;
480
+ successRate: number;
481
+ avgDurationMs: number;
482
+ lastRun: string | null;
483
+ trend: 'improving' | 'stable' | 'degrading';
484
+ }
485
+
486
+ export interface FailurePattern {
487
+ pattern: string;
488
+ category: string;
489
+ occurrences: number;
490
+ lastSeen: string;
491
+ workflows: string[];
492
+ transient: boolean;
493
+ }
494
+
495
+ export interface ApprovalDecision {
496
+ timestamp: string;
497
+ proposalSummary: string;
498
+ impactLevel: string;
499
+ approved: boolean;
500
+ reason?: string;
501
+ }
502
+
503
+ export interface OperationEffectiveness {
504
+ proposed: number;
505
+ applied: number;
506
+ rolledBack: number;
507
+ effectiveness: number;
508
+ }
509
+
510
+ export interface TrustLevel {
511
+ score: number;
512
+ phase: 1 | 2 | 3 | 4;
513
+ factors: {
514
+ conversationCount: number;
515
+ approvalConsistency: number;
516
+ genesisSuccessRate: number;
517
+ daysSinceFirstUse: number;
518
+ };
519
+ }
520
+
521
+ export interface BotProfile {
522
+ name: string;
523
+ workflowFile: string;
524
+ ejected: boolean;
525
+ totalTasksRun: number;
526
+ successRate: number;
527
+ avgTaskDurationMs: number;
528
+ topFailurePatterns: FailurePattern[];
529
+ }
530
+
531
+ export interface ProjectModel {
532
+ projectDir: string;
533
+ builtAt: number;
534
+ health: {
535
+ overall: number;
536
+ workflows: WorkflowHealth[];
537
+ };
538
+ bots: BotProfile[];
539
+ failurePatterns: FailurePattern[];
540
+ userPreferences: {
541
+ approvalHistory: ApprovalDecision[];
542
+ autoApprovePatterns: string[];
543
+ neverApprovePatterns: string[];
544
+ };
545
+ evolution: {
546
+ totalCycles: number;
547
+ successRate: number;
548
+ byOperationType: Record<string, OperationEffectiveness>;
549
+ recentCycles: GenesisCycleRecord[];
550
+ };
551
+ cost: {
552
+ totalSpent: number;
553
+ last7Days: number;
554
+ last30Days: number;
555
+ trend: 'increasing' | 'stable' | 'decreasing';
556
+ costPerSuccessfulRun: number;
557
+ highCostWorkflows: Array<{ workflow: string; avgCost: number }>;
558
+ };
559
+ trust: TrustLevel;
560
+ }
561
+
562
+ export interface Insight {
563
+ id: string;
564
+ type: 'failure-pattern' | 'health-trend' | 'cost-optimization' | 'evolution-opportunity' | 'unused-workflow' | 'bot-performance' | 'update-available';
565
+ confidence: number;
566
+ severity: 'info' | 'warning' | 'critical';
567
+ title: string;
568
+ description: string;
569
+ evidence: string[];
570
+ suggestion?: string;
571
+ genesisCandidate: boolean;
572
+ targetBot?: string;
573
+ operationHint?: string;
574
+ }
575
+
474
576
  export interface GenesisCycleRecord {
475
577
  id: string;
476
578
  timestamp: string;
@@ -483,6 +585,7 @@ export interface GenesisCycleRecord {
483
585
  approved: boolean | null;
484
586
  error: string | null;
485
587
  snapshotFile: string | null;
588
+ rejectionReason?: string;
486
589
  }
487
590
 
488
591
  export interface GenesisHistory {
@@ -519,6 +622,7 @@ export interface GenesisContext {
519
622
  workflowDiffJson?: string;
520
623
  approvalRequired?: boolean;
521
624
  approved?: boolean;
625
+ rejectionReason?: string;
522
626
  commitResultJson?: string;
523
627
  cycleRecordJson?: string;
524
628
  workflowDescription?: string;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Update Checker — checks npm registry for newer versions of installed packs.
3
+ * Results are cached for 24 hours to avoid spamming the registry.
4
+ */
5
+
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ import * as os from 'node:os';
9
+ import { safeJsonParse } from './safe-json.js';
10
+
11
+ export interface UpdateInfo {
12
+ packageName: string;
13
+ currentVersion: string;
14
+ latestVersion: string;
15
+ updateAvailable: boolean;
16
+ }
17
+
18
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
19
+ const CACHE_DIR = path.join(os.homedir(), '.weaver');
20
+ const CACHE_FILE = path.join(CACHE_DIR, 'update-cache.json');
21
+
22
+ interface CacheEntry {
23
+ checkedAt: number;
24
+ updates: UpdateInfo[];
25
+ }
26
+
27
+ function readCache(): CacheEntry | null {
28
+ try {
29
+ if (!fs.existsSync(CACHE_FILE)) return null;
30
+ const text = fs.readFileSync(CACHE_FILE, 'utf-8');
31
+ const parsed = safeJsonParse<CacheEntry>(text, 'update-cache');
32
+ if (!parsed.ok) {
33
+ console.error(`[weaver] ${parsed.error}`);
34
+ return null;
35
+ }
36
+ if (Date.now() - parsed.value.checkedAt < CACHE_TTL_MS) return parsed.value;
37
+ return null; // stale
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+
43
+ function writeCache(entry: CacheEntry): void {
44
+ try {
45
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
46
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(entry, null, 2), 'utf-8');
47
+ } catch { /* non-fatal */ }
48
+ }
49
+
50
+ export function compareVersions(a: string, b: string): number {
51
+ const pa = a.replace(/^v/, '').split('.').map(s => parseInt(s, 10) || 0);
52
+ const pb = b.replace(/^v/, '').split('.').map(s => parseInt(s, 10) || 0);
53
+ for (let i = 0; i < 3; i++) {
54
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
55
+ if (diff !== 0) return diff;
56
+ }
57
+ return 0;
58
+ }
59
+
60
+ async function fetchLatestVersion(packageName: string): Promise<string | null> {
61
+ try {
62
+ const encoded = packageName.replace('/', '%2f');
63
+ const resp = await fetch(`https://registry.npmjs.org/${encoded}/latest`, {
64
+ signal: AbortSignal.timeout(5000),
65
+ });
66
+ if (!resp.ok) return null;
67
+ const data = await resp.json() as { version?: string };
68
+ return data.version ?? null;
69
+ } catch {
70
+ return null; // network error, timeout, etc.
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Check for updates on installed packs. Returns cached result if fresh.
76
+ * Checks: the weaver pack itself, and any flow-weaver-pack-* in node_modules.
77
+ */
78
+ export async function checkForUpdates(projectDir: string): Promise<UpdateInfo[]> {
79
+ // Return cached if fresh
80
+ const cached = readCache();
81
+ if (cached) return cached.updates;
82
+
83
+ const updates: UpdateInfo[] = [];
84
+
85
+ // Check the weaver pack itself
86
+ try {
87
+ const packPkgPath = path.resolve(projectDir, 'node_modules', '@synergenius', 'flow-weaver-pack-weaver', 'package.json');
88
+ if (fs.existsSync(packPkgPath)) {
89
+ const text = fs.readFileSync(packPkgPath, 'utf-8');
90
+ const parsed = safeJsonParse<{ name: string; version: string }>(text, 'pack-weaver package.json');
91
+ if (!parsed.ok) {
92
+ console.error(`[weaver] ${parsed.error}`);
93
+ } else {
94
+ const pkg = parsed.value;
95
+ const current = pkg.version;
96
+ const latest = await fetchLatestVersion(pkg.name);
97
+ if (latest && compareVersions(latest, current) > 0) {
98
+ updates.push({ packageName: pkg.name, currentVersion: current, latestVersion: latest, updateAvailable: true });
99
+ } else if (latest) {
100
+ updates.push({ packageName: pkg.name, currentVersion: current, latestVersion: latest, updateAvailable: false });
101
+ }
102
+ }
103
+ }
104
+ } catch { /* not installed or unreadable */ }
105
+
106
+ // Check flow-weaver core
107
+ try {
108
+ const corePkgPath = path.resolve(projectDir, 'node_modules', '@synergenius', 'flow-weaver', 'package.json');
109
+ if (fs.existsSync(corePkgPath)) {
110
+ const text = fs.readFileSync(corePkgPath, 'utf-8');
111
+ const parsed = safeJsonParse<{ name: string; version: string }>(text, 'flow-weaver package.json');
112
+ if (!parsed.ok) {
113
+ console.error(`[weaver] ${parsed.error}`);
114
+ } else {
115
+ const pkg = parsed.value;
116
+ const current = pkg.version;
117
+ const latest = await fetchLatestVersion(pkg.name);
118
+ if (latest && compareVersions(latest, current) > 0) {
119
+ updates.push({ packageName: pkg.name, currentVersion: current, latestVersion: latest, updateAvailable: true });
120
+ }
121
+ }
122
+ }
123
+ } catch { /* not installed */ }
124
+
125
+ // Cache result
126
+ writeCache({ checkedAt: Date.now(), updates });
127
+ return updates;
128
+ }
129
+
130
+ /**
131
+ * Format update info as a brief notification string.
132
+ */
133
+ export function formatUpdateNotification(updates: UpdateInfo[]): string | null {
134
+ const available = updates.filter(u => u.updateAvailable);
135
+ if (available.length === 0) return null;
136
+ const lines = available.map(u => `${u.packageName}: ${u.currentVersion} → ${u.latestVersion}`);
137
+ return `Updates available:\n${lines.join('\n')}\nRun: npm update`;
138
+ }
@@ -41,9 +41,14 @@ export function createWeaverExecutor(projectDir: string) {
41
41
  if (isBlockedUrl(url)) {
42
42
  return { result: 'Blocked: cannot fetch internal/localhost URLs.', isError: true };
43
43
  }
44
- const resp = await fetch(url, { method: (args.method as string) ?? 'GET', signal: AbortSignal.timeout(15_000) });
45
- const text = await resp.text();
46
- return { result: text.slice(0, 10_000), isError: !resp.ok };
44
+ try {
45
+ const resp = await fetch(url, { method: (args.method as string) ?? 'GET', signal: AbortSignal.timeout(15_000) });
46
+ const text = await resp.text();
47
+ return { result: text.slice(0, 10_000), isError: !resp.ok };
48
+ } catch (err: unknown) {
49
+ const msg = err instanceof Error ? err.message : String(err);
50
+ return { result: `Fetch error: ${msg}`, isError: true };
51
+ }
47
52
  }
48
53
 
49
54
  case 'tsc_check': {
@@ -68,7 +73,8 @@ export function createWeaverExecutor(projectDir: string) {
68
73
  const failures = (json.testResults ?? []).filter((t: any) => t.status === 'failed').map((t: any) => t.name).slice(0, 10);
69
74
  return { result: JSON.stringify({ passed, failed, total: passed + failed, failures }), isError: failed > 0 };
70
75
  } catch {
71
- return { result: output.slice(0, 5000), isError: false };
76
+ // JSON parse failed — output is not structured, flag as error
77
+ return { result: output.slice(0, 5000), isError: true };
72
78
  }
73
79
  } catch (err: any) {
74
80
  return { result: (err.stdout ?? err.stderr ?? err.message ?? '').slice(0, 5000), isError: true };
package/src/cli-bridge.ts CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  handleCron, handlePipeline, handleDashboard, handleProviders,
5
5
  handleEject, handleBot, handleSession, handleSteer, handleQueue,
6
6
  handleStatus, handleGenesis, handleAudit, handleInit, handleAssistant,
7
- handleExamples, handleDoctor,
7
+ handleExamples, handleDoctor, handleImprove,
8
8
  printHelp,
9
9
  } from './cli-handlers.js';
10
10
 
@@ -29,8 +29,11 @@ const handlers: Record<string, (opts: ParsedArgs) => Promise<void>> = {
29
29
  assistant: handleAssistant,
30
30
  examples: handleExamples,
31
31
  doctor: handleDoctor,
32
+ improve: handleImprove,
32
33
  };
33
34
 
35
+ export { printHelp };
36
+
34
37
  export async function handleCommand(
35
38
  name: string,
36
39
  args: string[],