@synergenius/flow-weaver-pack-weaver 0.9.8 → 0.9.10

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 (228) 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 +366 -45
  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/index.d.ts +1 -0
  68. package/dist/bot/index.d.ts.map +1 -1
  69. package/dist/bot/index.js +2 -0
  70. package/dist/bot/index.js.map +1 -1
  71. package/dist/bot/insight-engine.d.ts +12 -0
  72. package/dist/bot/insight-engine.d.ts.map +1 -0
  73. package/dist/bot/insight-engine.js +256 -0
  74. package/dist/bot/insight-engine.js.map +1 -0
  75. package/dist/bot/knowledge-store.d.ts.map +1 -1
  76. package/dist/bot/knowledge-store.js +4 -1
  77. package/dist/bot/knowledge-store.js.map +1 -1
  78. package/dist/bot/pipeline-runner.d.ts.map +1 -1
  79. package/dist/bot/pipeline-runner.js +12 -4
  80. package/dist/bot/pipeline-runner.js.map +1 -1
  81. package/dist/bot/project-model.d.ts +25 -0
  82. package/dist/bot/project-model.d.ts.map +1 -0
  83. package/dist/bot/project-model.js +372 -0
  84. package/dist/bot/project-model.js.map +1 -0
  85. package/dist/bot/response-formatter.js +2 -3
  86. package/dist/bot/response-formatter.js.map +1 -1
  87. package/dist/bot/run-store.d.ts.map +1 -1
  88. package/dist/bot/run-store.js +10 -2
  89. package/dist/bot/run-store.js.map +1 -1
  90. package/dist/bot/safe-path.d.ts +1 -1
  91. package/dist/bot/safe-path.d.ts.map +1 -1
  92. package/dist/bot/safe-path.js +20 -1
  93. package/dist/bot/safe-path.js.map +1 -1
  94. package/dist/bot/safety.d.ts +10 -2
  95. package/dist/bot/safety.d.ts.map +1 -1
  96. package/dist/bot/safety.js +45 -2
  97. package/dist/bot/safety.js.map +1 -1
  98. package/dist/bot/session-state.d.ts +4 -0
  99. package/dist/bot/session-state.d.ts.map +1 -1
  100. package/dist/bot/session-state.js +52 -9
  101. package/dist/bot/session-state.js.map +1 -1
  102. package/dist/bot/slash-commands.d.ts.map +1 -1
  103. package/dist/bot/slash-commands.js +100 -5
  104. package/dist/bot/slash-commands.js.map +1 -1
  105. package/dist/bot/steering-engine.d.ts +67 -0
  106. package/dist/bot/steering-engine.d.ts.map +1 -0
  107. package/dist/bot/steering-engine.js +198 -0
  108. package/dist/bot/steering-engine.js.map +1 -0
  109. package/dist/bot/step-executor.d.ts.map +1 -1
  110. package/dist/bot/step-executor.js +62 -25
  111. package/dist/bot/step-executor.js.map +1 -1
  112. package/dist/bot/system-prompt.d.ts.map +1 -1
  113. package/dist/bot/system-prompt.js +5 -2
  114. package/dist/bot/system-prompt.js.map +1 -1
  115. package/dist/bot/task-queue.d.ts +6 -1
  116. package/dist/bot/task-queue.d.ts.map +1 -1
  117. package/dist/bot/task-queue.js +43 -4
  118. package/dist/bot/task-queue.js.map +1 -1
  119. package/dist/bot/tool-registry.d.ts +1 -1
  120. package/dist/bot/tool-registry.d.ts.map +1 -1
  121. package/dist/bot/tool-registry.js +65 -4
  122. package/dist/bot/tool-registry.js.map +1 -1
  123. package/dist/bot/trust-calculator.d.ts +34 -0
  124. package/dist/bot/trust-calculator.d.ts.map +1 -0
  125. package/dist/bot/trust-calculator.js +67 -0
  126. package/dist/bot/trust-calculator.js.map +1 -0
  127. package/dist/bot/types.d.ts +97 -0
  128. package/dist/bot/types.d.ts.map +1 -1
  129. package/dist/bot/update-checker.d.ts +21 -0
  130. package/dist/bot/update-checker.d.ts.map +1 -0
  131. package/dist/bot/update-checker.js +129 -0
  132. package/dist/bot/update-checker.js.map +1 -0
  133. package/dist/bot/weaver-tools.d.ts.map +1 -1
  134. package/dist/bot/weaver-tools.js +11 -4
  135. package/dist/bot/weaver-tools.js.map +1 -1
  136. package/dist/cli-bridge.d.ts.map +1 -1
  137. package/dist/cli-bridge.js +2 -1
  138. package/dist/cli-bridge.js.map +1 -1
  139. package/dist/cli-handlers.d.ts +9 -1
  140. package/dist/cli-handlers.d.ts.map +1 -1
  141. package/dist/cli-handlers.js +77 -8
  142. package/dist/cli-handlers.js.map +1 -1
  143. package/dist/cli.d.ts +3 -0
  144. package/dist/cli.d.ts.map +1 -0
  145. package/dist/cli.js +749 -0
  146. package/dist/cli.js.map +1 -0
  147. package/dist/docs/weaver-config.md +15 -9
  148. package/dist/handlers/on-execution-completed.d.ts +11 -0
  149. package/dist/handlers/on-execution-completed.d.ts.map +1 -0
  150. package/dist/handlers/on-execution-completed.js +25 -0
  151. package/dist/handlers/on-execution-completed.js.map +1 -0
  152. package/dist/mcp-tools.d.ts.map +1 -1
  153. package/dist/mcp-tools.js +33 -0
  154. package/dist/mcp-tools.js.map +1 -1
  155. package/dist/node-types/genesis-approve.d.ts.map +1 -1
  156. package/dist/node-types/genesis-approve.js +28 -3
  157. package/dist/node-types/genesis-approve.js.map +1 -1
  158. package/dist/node-types/genesis-observe.d.ts.map +1 -1
  159. package/dist/node-types/genesis-observe.js +23 -13
  160. package/dist/node-types/genesis-observe.js.map +1 -1
  161. package/dist/node-types/genesis-propose.d.ts.map +1 -1
  162. package/dist/node-types/genesis-propose.js +8 -0
  163. package/dist/node-types/genesis-propose.js.map +1 -1
  164. package/dist/node-types/genesis-update-history.d.ts.map +1 -1
  165. package/dist/node-types/genesis-update-history.js +13 -0
  166. package/dist/node-types/genesis-update-history.js.map +1 -1
  167. package/dist/templates/weaver-template.d.ts +11 -0
  168. package/dist/templates/weaver-template.d.ts.map +1 -0
  169. package/dist/templates/weaver-template.js +53 -0
  170. package/dist/templates/weaver-template.js.map +1 -0
  171. package/dist/workflows/weaver-bot-session.d.ts +65 -0
  172. package/dist/workflows/weaver-bot-session.d.ts.map +1 -0
  173. package/dist/workflows/weaver-bot-session.js +68 -0
  174. package/dist/workflows/weaver-bot-session.js.map +1 -0
  175. package/dist/workflows/weaver.d.ts +24 -0
  176. package/dist/workflows/weaver.d.ts.map +1 -0
  177. package/dist/workflows/weaver.js +28 -0
  178. package/dist/workflows/weaver.js.map +1 -0
  179. package/flowweaver.manifest.json +27 -0
  180. package/package.json +5 -2
  181. package/src/bot/agent-provider.ts +3 -2
  182. package/src/bot/approvals.ts +16 -8
  183. package/src/bot/assistant-core.ts +366 -44
  184. package/src/bot/assistant-tools.ts +291 -9
  185. package/src/bot/bot-agent-channel.ts +2 -0
  186. package/src/bot/bot-manager.ts +70 -29
  187. package/src/bot/conversation-store.ts +87 -42
  188. package/src/bot/cost-store.ts +20 -9
  189. package/src/bot/cost-tracker.ts +13 -1
  190. package/src/bot/cron-parser.ts +1 -0
  191. package/src/bot/cron-scheduler.ts +1 -0
  192. package/src/bot/device-connection.ts +102 -0
  193. package/src/bot/error-classifier.ts +5 -0
  194. package/src/bot/file-lock.ts +12 -2
  195. package/src/bot/file-watcher.ts +1 -0
  196. package/src/bot/genesis-prompt-context.ts +61 -0
  197. package/src/bot/genesis-store.ts +68 -16
  198. package/src/bot/improve-loop.ts +651 -0
  199. package/src/bot/index.ts +3 -0
  200. package/src/bot/insight-engine.ts +273 -0
  201. package/src/bot/knowledge-store.ts +4 -1
  202. package/src/bot/pipeline-runner.ts +11 -6
  203. package/src/bot/project-model.ts +404 -0
  204. package/src/bot/response-formatter.ts +2 -3
  205. package/src/bot/run-store.ts +5 -2
  206. package/src/bot/safe-path.ts +20 -1
  207. package/src/bot/safety.ts +57 -3
  208. package/src/bot/session-state.ts +47 -7
  209. package/src/bot/slash-commands.ts +103 -5
  210. package/src/bot/steering-engine.ts +233 -0
  211. package/src/bot/step-executor.ts +66 -26
  212. package/src/bot/system-prompt.ts +5 -2
  213. package/src/bot/task-queue.ts +40 -4
  214. package/src/bot/tool-registry.ts +67 -5
  215. package/src/bot/trust-calculator.ts +87 -0
  216. package/src/bot/types.ts +104 -0
  217. package/src/bot/update-checker.ts +138 -0
  218. package/src/bot/weaver-tools.ts +10 -4
  219. package/src/cli-bridge.ts +2 -1
  220. package/src/cli-handlers.ts +84 -9
  221. package/src/handlers/on-execution-completed.ts +30 -0
  222. package/src/mcp-tools.ts +38 -0
  223. package/src/node-types/genesis-approve.ts +28 -3
  224. package/src/node-types/genesis-observe.ts +23 -12
  225. package/src/node-types/genesis-propose.ts +8 -0
  226. package/src/node-types/genesis-update-history.ts +12 -0
  227. package/src/ui/evolution-panel.tsx +96 -0
  228. package/src/ui/insights-widget.tsx +77 -0
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Platform event handler: invalidates project model cache when executions complete.
3
+ * Registered in flowweaver.manifest.json as an event subscription.
4
+ */
5
+
6
+ import * as crypto from 'node:crypto';
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import * as os from 'node:os';
10
+
11
+ export async function onExecutionCompleted(event: {
12
+ deploymentId?: string;
13
+ wsPath?: string;
14
+ status?: string;
15
+ executionTimeMs?: number;
16
+ }): Promise<void> {
17
+ const projectDir = event.wsPath;
18
+ if (!projectDir) return;
19
+
20
+ // Invalidate project model cache directly (same logic as ProjectModelStore.invalidate)
21
+ try {
22
+ const hash8 = crypto.createHash('sha256').update(projectDir).digest('hex').slice(0, 8);
23
+ const modelPath = path.join(os.homedir(), '.weaver', 'projects', hash8, 'model.json');
24
+ if (fs.existsSync(modelPath)) {
25
+ fs.unlinkSync(modelPath);
26
+ }
27
+ } catch {
28
+ // Non-fatal — cache will be rebuilt on next access
29
+ }
30
+ }
package/src/mcp-tools.ts CHANGED
@@ -271,4 +271,42 @@ export async function registerMcpTools(mcp: McpServer): Promise<void> {
271
271
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
272
272
  },
273
273
  );
274
+
275
+ mcp.tool(
276
+ 'fw_weaver_insights',
277
+ 'Get project health, insights, trust level, and cost summary. Returns structured JSON with actionable recommendations.',
278
+ {
279
+ projectDir: z.string().describe('Project directory path'),
280
+ },
281
+ async (args) => {
282
+ try {
283
+ const { ProjectModelStore } = await import('./bot/project-model.js');
284
+ const { InsightEngine } = await import('./bot/insight-engine.js');
285
+ const pms = new ProjectModelStore(args.projectDir as string);
286
+ const model = await pms.getOrBuild();
287
+ const engine = new InsightEngine();
288
+ const insights = engine.analyze(model);
289
+ return {
290
+ content: [{
291
+ type: 'text',
292
+ text: JSON.stringify({
293
+ health: model.health,
294
+ bots: model.bots,
295
+ insights: insights.slice(0, 10),
296
+ trust: model.trust,
297
+ cost: model.cost,
298
+ evolution: {
299
+ totalCycles: model.evolution.totalCycles,
300
+ successRate: model.evolution.successRate,
301
+ },
302
+ }, null, 2),
303
+ }],
304
+ };
305
+ } catch (err: unknown) {
306
+ return {
307
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
308
+ };
309
+ }
310
+ },
311
+ );
274
312
  }
@@ -66,8 +66,33 @@ export async function genesisApprove(
66
66
  return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
67
67
  }
68
68
 
69
- // Non-auto modes reject in non-interactive context
70
- console.log('\x1b[33m→ Rejected (approval required, non-auto mode)\x1b[0m');
71
- context.approved = false;
69
+ // Non-auto modes: try interactive approval, fall back to reject
70
+ let approved = false;
71
+ let rejectionReason = 'Non-interactive environment';
72
+
73
+ if (approvalMode === 'prompt') {
74
+ try {
75
+ const readline = await import('node:readline');
76
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
77
+ const answer = await new Promise<string>(resolve => {
78
+ rl.question('\x1b[33m? Approve this proposal? (y/N/reason): \x1b[0m', resolve);
79
+ });
80
+ rl.close();
81
+ const trimmed = answer.trim().toLowerCase();
82
+ if (trimmed === 'y' || trimmed === 'yes') {
83
+ approved = true;
84
+ } else {
85
+ rejectionReason = trimmed && trimmed !== 'n' && trimmed !== 'no' ? answer.trim() : 'User rejected';
86
+ }
87
+ } catch {
88
+ // Non-interactive — fall through to reject
89
+ }
90
+ }
91
+
92
+ context.approved = approved;
93
+ context.rejectionReason = approved ? undefined : rejectionReason;
94
+ console.log(approved
95
+ ? '\x1b[32m→ Approved by user\x1b[0m'
96
+ : `\x1b[33m→ Rejected: ${rejectionReason}\x1b[0m`);
72
97
  return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
73
98
  }
@@ -46,22 +46,28 @@ export async function genesisObserve(
46
46
 
47
47
  try {
48
48
  const files: Record<string, string> = {};
49
- const dirsToScan = [projectDir];
50
- const srcDir = path.join(projectDir, 'src');
51
- if (fs.existsSync(srcDir) && fs.statSync(srcDir).isDirectory()) dirsToScan.push(srcDir);
49
+ const fileContents: Record<string, string> = {};
50
+ const SKIP_DIRS = new Set(['node_modules', 'dist', '.git', 'coverage', '.next', '.turbo']);
52
51
 
53
- for (const dir of dirsToScan) {
52
+ function walkDir(dir: string): void {
54
53
  const entries = fs.readdirSync(dir, { withFileTypes: true });
55
54
  for (const entry of entries) {
56
- if (entry.isFile() && entry.name.endsWith('.ts')) {
55
+ if (entry.isDirectory()) {
56
+ if (!SKIP_DIRS.has(entry.name)) {
57
+ walkDir(path.join(dir, entry.name));
58
+ }
59
+ } else if (entry.isFile() && entry.name.endsWith('.ts')) {
57
60
  const filePath = path.join(dir, entry.name);
58
61
  const relPath = path.relative(projectDir, filePath);
59
62
  const content = fs.readFileSync(filePath, 'utf-8');
63
+ fileContents[relPath] = content;
60
64
  files[relPath] = crypto.createHash('sha256').update(content).digest('hex');
61
65
  }
62
66
  }
63
67
  }
64
68
 
69
+ walkDir(projectDir);
70
+
65
71
  let packageJson: Record<string, unknown> | null = null;
66
72
  const pkgPath = path.join(projectDir, 'package.json');
67
73
  if (fs.existsSync(pkgPath)) {
@@ -83,17 +89,20 @@ export async function genesisObserve(
83
89
  }
84
90
 
85
91
  const existingWorkflows: string[] = [];
86
- for (const [relPath, _hash] of Object.entries(files)) {
87
- const filePath = path.join(projectDir, relPath);
88
- const content = fs.readFileSync(filePath, 'utf-8');
92
+ for (const [relPath, content] of Object.entries(fileContents)) {
89
93
  if (content.includes('@flowWeaver workflow')) {
90
94
  existingWorkflows.push(relPath);
91
95
  }
92
96
  }
93
97
 
94
- const targetPath = path.resolve(projectDir, config.targetWorkflow);
95
- const targetContent = fs.readFileSync(targetPath, 'utf-8');
96
- const workflowHash = crypto.createHash('sha256').update(targetContent).digest('hex');
98
+ let workflowHash = '';
99
+ let targetPath = '';
100
+ if (config.targetWorkflow) {
101
+ targetPath = path.resolve(projectDir, config.targetWorkflow);
102
+ const targetRelPath = path.relative(projectDir, targetPath);
103
+ const targetContent = fileContents[targetRelPath] ?? fs.readFileSync(targetPath, 'utf-8');
104
+ workflowHash = crypto.createHash('sha256').update(targetContent).digest('hex');
105
+ }
97
106
 
98
107
  const fingerprint: GenesisFingerprint = {
99
108
  timestamp: new Date().toISOString(),
@@ -108,7 +117,9 @@ export async function genesisObserve(
108
117
  console.log(`\x1b[36m→ Fingerprint: ${Object.keys(files).length} files, ${existingWorkflows.length} workflows\x1b[0m`);
109
118
 
110
119
  context.fingerprintJson = JSON.stringify(fingerprint);
111
- context.workflowDescription = await getWorkflowDescription(targetPath);
120
+ if (targetPath) {
121
+ context.workflowDescription = await getWorkflowDescription(targetPath);
122
+ }
112
123
 
113
124
  return { onSuccess: true, onFailure: false, ctx: JSON.stringify(context) };
114
125
  } catch (err: unknown) {
@@ -40,10 +40,18 @@ export async function genesisPropose(
40
40
  graceRemaining: context.escrowGraceRemaining ?? 0,
41
41
  });
42
42
 
43
+ // Inject project intelligence
44
+ let insightContext = '';
45
+ try {
46
+ const { getGenesisInsightContext } = await import('../bot/genesis-prompt-context.js');
47
+ insightContext = await getGenesisInsightContext(env.projectDir);
48
+ } catch { /* insights not available */ }
49
+
43
50
  const userPrompt = [
44
51
  '## Current Workflow Structure',
45
52
  context.workflowDescription || '(no description available)',
46
53
  '',
54
+ ...(insightContext ? [insightContext, ''] : []),
47
55
  '## Project Diff Since Last Cycle',
48
56
  JSON.stringify(diff, null, 2),
49
57
  '',
@@ -60,6 +60,18 @@ export function genesisUpdateHistory(ctx: string): { ctx: string } {
60
60
  if (fingerprint) {
61
61
  store.saveFingerprint(fingerprint);
62
62
  }
63
+
64
+ // Invalidate project model cache so next access rebuilds with fresh data
65
+ try {
66
+ // Use sync require-like approach: delete the cached model.json directly
67
+ const crypto = require('node:crypto') as typeof import('node:crypto');
68
+ const fsMod = require('node:fs') as typeof import('node:fs');
69
+ const pathMod = require('node:path') as typeof import('node:path');
70
+ const osMod = require('node:os') as typeof import('node:os');
71
+ const hash8 = crypto.createHash('sha256').update(env.projectDir).digest('hex').slice(0, 8);
72
+ const modelPath = pathMod.join(osMod.homedir(), '.weaver', 'projects', hash8, 'model.json');
73
+ if (fsMod.existsSync(modelPath)) fsMod.unlinkSync(modelPath);
74
+ } catch { /* project model not available */ }
63
75
  } catch (err: unknown) {
64
76
  const msg = err instanceof Error ? err.message : String(err);
65
77
  console.error(`\x1b[31m→ Failed to save history: ${msg}\x1b[0m`);
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Weaver Evolution Panel — shows Genesis cycle history and operation effectiveness.
3
+ * Loaded dynamically by the platform's pack UI contributions loader.
4
+ */
5
+
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ interface EvolutionData {
9
+ evolution: {
10
+ totalCycles: number;
11
+ successRate: number;
12
+ byOperationType: Record<string, { proposed: number; applied: number; effectiveness: number }>;
13
+ recentCycles: Array<{ id: string; outcome: string; proposal?: { summary: string; impactLevel: string } }>;
14
+ };
15
+ trust: { phase: number; score: number };
16
+ }
17
+
18
+ export function WeaverEvolutionPanel({ projectDir }: { projectDir?: string }) {
19
+ const [data, setData] = useState<EvolutionData | null>(null);
20
+ const [error, setError] = useState<string | null>(null);
21
+
22
+ useEffect(() => {
23
+ if (!projectDir) return;
24
+ fetch(`/api/mcp/fw_weaver_insights?projectDir=${encodeURIComponent(projectDir)}`)
25
+ .then(r => r.json())
26
+ .then(setData)
27
+ .catch(e => setError(e.message));
28
+ }, [projectDir]);
29
+
30
+ if (error) return <div style={{ padding: 16, color: '#ef4444' }}>Error: {error}</div>;
31
+ if (!data) return <div style={{ padding: 16, opacity: 0.5 }}>Loading evolution data...</div>;
32
+
33
+ const { evolution, trust } = data;
34
+ const outcomeColor: Record<string, string> = {
35
+ applied: '#22c55e',
36
+ 'rolled-back': '#ef4444',
37
+ rejected: '#f59e0b',
38
+ 'no-change': '#6b7280',
39
+ error: '#ef4444',
40
+ };
41
+
42
+ return (
43
+ <div style={{ padding: 16, fontFamily: 'system-ui, sans-serif', fontSize: 13 }}>
44
+ <div style={{ marginBottom: 16 }}>
45
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>Trust Level</div>
46
+ <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
47
+ <span style={{ fontSize: 20, fontWeight: 700 }}>Phase {trust.phase}</span>
48
+ <span style={{ opacity: 0.5 }}>Score: {trust.score}/100</span>
49
+ </div>
50
+ </div>
51
+
52
+ <div style={{ marginBottom: 16 }}>
53
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>
54
+ Genesis Cycles: {evolution.totalCycles} ({evolution.totalCycles > 0 ? Math.round(evolution.successRate * 100) : 0}% success)
55
+ </div>
56
+ </div>
57
+
58
+ {Object.keys(evolution.byOperationType).length > 0 && (
59
+ <div style={{ marginBottom: 16 }}>
60
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>Operation Effectiveness</div>
61
+ {Object.entries(evolution.byOperationType).map(([op, stats]) => (
62
+ <div key={op} style={{ padding: '2px 0', display: 'flex', justifyContent: 'space-between' }}>
63
+ <span>{op}</span>
64
+ <span style={{ opacity: 0.7 }}>{Math.round(stats.effectiveness * 100)}% ({stats.applied}/{stats.proposed})</span>
65
+ </div>
66
+ ))}
67
+ </div>
68
+ )}
69
+
70
+ {evolution.recentCycles.length > 0 && (
71
+ <div>
72
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>Recent Cycles</div>
73
+ {evolution.recentCycles.slice(-5).reverse().map((cycle) => (
74
+ <div key={cycle.id} style={{ padding: '4px 0', borderBottom: '1px solid rgba(128,128,128,0.1)' }}>
75
+ <span style={{ color: outcomeColor[cycle.outcome] ?? '#6b7280', fontWeight: 600, marginRight: 8 }}>
76
+ {cycle.outcome}
77
+ </span>
78
+ <span style={{ opacity: 0.7 }}>{cycle.id}</span>
79
+ {cycle.proposal && (
80
+ <div style={{ opacity: 0.6, paddingLeft: 8 }}>{cycle.proposal.summary}</div>
81
+ )}
82
+ </div>
83
+ ))}
84
+ </div>
85
+ )}
86
+
87
+ {evolution.totalCycles === 0 && (
88
+ <div style={{ opacity: 0.5, textAlign: 'center', padding: 20 }}>
89
+ No genesis cycles yet. Use /genesis in the assistant to start evolving bot workflows.
90
+ </div>
91
+ )}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ export default WeaverEvolutionPanel;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Weaver Insights Dashboard Widget — shows project health, insights, and cost summary.
3
+ * Loaded dynamically by the platform's pack UI contributions loader.
4
+ */
5
+
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ interface InsightsData {
9
+ health: { overall: number; workflows: Array<{ file: string; score: number; trend: string }> };
10
+ bots: Array<{ name: string; ejected: boolean; successRate: number; totalTasksRun: number }>;
11
+ insights: Array<{ severity: string; title: string; description: string; confidence: number }>;
12
+ cost: { last7Days: number; trend: string };
13
+ trust: { phase: number; score: number };
14
+ }
15
+
16
+ export function WeaverInsightsWidget({ projectDir }: { projectDir?: string }) {
17
+ const [data, setData] = useState<InsightsData | null>(null);
18
+ const [error, setError] = useState<string | null>(null);
19
+
20
+ useEffect(() => {
21
+ if (!projectDir) return;
22
+ fetch(`/api/mcp/fw_weaver_insights?projectDir=${encodeURIComponent(projectDir)}`)
23
+ .then(r => r.json())
24
+ .then(setData)
25
+ .catch(e => setError(e.message));
26
+ }, [projectDir]);
27
+
28
+ if (error) return <div style={{ padding: 16, color: '#ef4444' }}>Error: {error}</div>;
29
+ if (!data) return <div style={{ padding: 16, opacity: 0.5 }}>Loading insights...</div>;
30
+
31
+ const severityColor: Record<string, string> = {
32
+ critical: '#ef4444',
33
+ warning: '#f59e0b',
34
+ info: '#6b7280',
35
+ };
36
+
37
+ return (
38
+ <div style={{ padding: 16, fontFamily: 'system-ui, sans-serif', fontSize: 13 }}>
39
+ <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginBottom: 12 }}>
40
+ <span style={{ fontSize: 28, fontWeight: 700 }}>{data.health.overall}</span>
41
+ <span style={{ opacity: 0.6 }}>/100 health</span>
42
+ <span style={{ marginLeft: 'auto', opacity: 0.5 }}>
43
+ Phase {data.trust.phase} · ${data.cost.last7Days.toFixed(2)}/7d ({data.cost.trend})
44
+ </span>
45
+ </div>
46
+
47
+ {data.insights.length > 0 && (
48
+ <div style={{ marginBottom: 12 }}>
49
+ <div style={{ fontWeight: 600, marginBottom: 6 }}>Insights</div>
50
+ {data.insights.slice(0, 3).map((insight, i) => (
51
+ <div key={i} style={{ padding: '4px 0', borderBottom: '1px solid rgba(128,128,128,0.1)' }}>
52
+ <span style={{ color: severityColor[insight.severity] ?? '#6b7280', fontWeight: 600, marginRight: 8 }}>
53
+ {insight.severity.toUpperCase()}
54
+ </span>
55
+ <span>{insight.title}</span>
56
+ <span style={{ opacity: 0.5, marginLeft: 8 }}>{Math.round(insight.confidence * 100)}%</span>
57
+ </div>
58
+ ))}
59
+ </div>
60
+ )}
61
+
62
+ {data.bots.length > 0 && (
63
+ <div>
64
+ <div style={{ fontWeight: 600, marginBottom: 6 }}>Bots</div>
65
+ {data.bots.map((bot, i) => (
66
+ <div key={i} style={{ padding: '2px 0' }}>
67
+ {bot.name}: {Math.round(bot.successRate * 100)}% success ({bot.totalTasksRun} tasks)
68
+ {bot.ejected && <span style={{ opacity: 0.5 }}> · ejected</span>}
69
+ </div>
70
+ ))}
71
+ </div>
72
+ )}
73
+ </div>
74
+ );
75
+ }
76
+
77
+ export default WeaverInsightsWidget;