@claude-flow/cli 3.1.0-alpha.5 → 3.1.0-alpha.51

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 (60) hide show
  1. package/.claude/helpers/auto-memory-hook.mjs +350 -0
  2. package/.claude/helpers/hook-handler.cjs +232 -0
  3. package/.claude/helpers/intelligence.cjs +916 -0
  4. package/.claude/helpers/session.js +8 -0
  5. package/.claude/helpers/statusline.cjs +96 -28
  6. package/.claude/settings.json +86 -141
  7. package/README.md +830 -353
  8. package/bin/cli.js +28 -0
  9. package/bin/mcp-server.js +28 -0
  10. package/bin/preinstall.cjs +111 -0
  11. package/dist/src/commands/hooks.d.ts.map +1 -1
  12. package/dist/src/commands/hooks.js +263 -62
  13. package/dist/src/commands/hooks.js.map +1 -1
  14. package/dist/src/commands/init.d.ts.map +1 -1
  15. package/dist/src/commands/init.js +191 -4
  16. package/dist/src/commands/init.js.map +1 -1
  17. package/dist/src/commands/memory.d.ts.map +1 -1
  18. package/dist/src/commands/memory.js +12 -2
  19. package/dist/src/commands/memory.js.map +1 -1
  20. package/dist/src/index.js +2 -2
  21. package/dist/src/index.js.map +1 -1
  22. package/dist/src/init/executor.d.ts +8 -2
  23. package/dist/src/init/executor.d.ts.map +1 -1
  24. package/dist/src/init/executor.js +310 -41
  25. package/dist/src/init/executor.js.map +1 -1
  26. package/dist/src/init/helpers-generator.d.ts +18 -0
  27. package/dist/src/init/helpers-generator.d.ts.map +1 -1
  28. package/dist/src/init/helpers-generator.js +498 -0
  29. package/dist/src/init/helpers-generator.js.map +1 -1
  30. package/dist/src/init/mcp-generator.d.ts +6 -0
  31. package/dist/src/init/mcp-generator.d.ts.map +1 -1
  32. package/dist/src/init/mcp-generator.js +52 -16
  33. package/dist/src/init/mcp-generator.js.map +1 -1
  34. package/dist/src/init/settings-generator.d.ts.map +1 -1
  35. package/dist/src/init/settings-generator.js +134 -91
  36. package/dist/src/init/settings-generator.js.map +1 -1
  37. package/dist/src/init/statusline-generator.d.ts +16 -8
  38. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  39. package/dist/src/init/statusline-generator.js +424 -931
  40. package/dist/src/init/statusline-generator.js.map +1 -1
  41. package/dist/src/init/types.d.ts +12 -0
  42. package/dist/src/init/types.d.ts.map +1 -1
  43. package/dist/src/init/types.js +12 -0
  44. package/dist/src/init/types.js.map +1 -1
  45. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  46. package/dist/src/mcp-tools/memory-tools.js +4 -1
  47. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  48. package/dist/src/memory/intelligence.d.ts.map +1 -1
  49. package/dist/src/memory/intelligence.js +34 -6
  50. package/dist/src/memory/intelligence.js.map +1 -1
  51. package/dist/src/memory/memory-bridge.d.ts +203 -0
  52. package/dist/src/memory/memory-bridge.d.ts.map +1 -0
  53. package/dist/src/memory/memory-bridge.js +693 -0
  54. package/dist/src/memory/memory-bridge.js.map +1 -0
  55. package/dist/src/memory/memory-initializer.d.ts +4 -0
  56. package/dist/src/memory/memory-initializer.d.ts.map +1 -1
  57. package/dist/src/memory/memory-initializer.js +119 -9
  58. package/dist/src/memory/memory-initializer.js.map +1 -1
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +5 -2
package/bin/cli.js CHANGED
@@ -6,8 +6,36 @@
6
6
  *
7
7
  * Auto-detects MCP mode when stdin is piped and no args provided.
8
8
  * This allows: echo '{"jsonrpc":"2.0",...}' | npx @claude-flow/cli
9
+ *
10
+ * Includes pre-flight npx cache repair to prevent ENOTEMPTY errors
11
+ * in remote/CI environments (known npm 10.x bug).
9
12
  */
10
13
 
14
+ // Pre-flight: repair stale npx cache to prevent ENOTEMPTY on next run
15
+ import { existsSync, readdirSync, rmSync, statSync } from 'node:fs';
16
+ import { join } from 'node:path';
17
+ import { homedir } from 'node:os';
18
+
19
+ try {
20
+ const npxRoot = join(homedir(), '.npm', '_npx');
21
+ if (existsSync(npxRoot)) {
22
+ for (const dir of readdirSync(npxRoot)) {
23
+ const nm = join(npxRoot, dir, 'node_modules');
24
+ if (!existsSync(nm)) continue;
25
+ try {
26
+ for (const entry of readdirSync(nm)) {
27
+ if (entry.startsWith('.') && entry.includes('-') && /[A-Za-z]{8}$/.test(entry)) {
28
+ try {
29
+ const p = join(nm, entry);
30
+ if (statSync(p).isDirectory()) rmSync(p, { recursive: true, force: true });
31
+ } catch {}
32
+ }
33
+ }
34
+ } catch {}
35
+ }
36
+ }
37
+ } catch {}
38
+
11
39
  import { randomUUID } from 'crypto';
12
40
 
13
41
  // Check if we should run in MCP server mode
package/bin/mcp-server.js CHANGED
@@ -5,8 +5,36 @@
5
5
  * Direct stdio MCP server for Claude Code integration.
6
6
  * This entry point handles stdin/stdout directly for MCP protocol
7
7
  * without any CLI formatting output that would corrupt the protocol.
8
+ *
9
+ * Includes pre-flight npx cache repair to prevent ENOTEMPTY errors
10
+ * in remote/CI environments (known npm 10.x bug).
8
11
  */
9
12
 
13
+ // Pre-flight: repair stale npx cache to prevent ENOTEMPTY on next run
14
+ import { existsSync, readdirSync, rmSync, statSync } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { homedir } from 'node:os';
17
+
18
+ try {
19
+ const npxRoot = join(homedir(), '.npm', '_npx');
20
+ if (existsSync(npxRoot)) {
21
+ for (const dir of readdirSync(npxRoot)) {
22
+ const nm = join(npxRoot, dir, 'node_modules');
23
+ if (!existsSync(nm)) continue;
24
+ try {
25
+ for (const entry of readdirSync(nm)) {
26
+ if (entry.startsWith('.') && entry.includes('-') && /[A-Za-z]{8}$/.test(entry)) {
27
+ try {
28
+ const p = join(nm, entry);
29
+ if (statSync(p).isDirectory()) rmSync(p, { recursive: true, force: true });
30
+ } catch {}
31
+ }
32
+ }
33
+ } catch {}
34
+ }
35
+ }
36
+ } catch {}
37
+
10
38
  import { randomUUID } from 'crypto';
11
39
  import { listMCPTools, callMCPTool, hasTool } from '../dist/src/mcp-client.js';
12
40
 
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Preinstall hook: repairs npm/npx cache to prevent ENOTEMPTY and ECOMPROMISED.
4
+ *
5
+ * Handles two common npm bugs in remote/CI/Codespaces environments:
6
+ * - ENOTEMPTY: leftover .package-XxXxXxXx dirs from interrupted atomic renames
7
+ * - ECOMPROMISED: corrupted integrity manifests in _cacache
8
+ *
9
+ * Works on Windows, macOS, and Linux. Uses only Node.js built-ins (CJS).
10
+ * Intentionally uses var/ES5 for maximum Node.js compatibility (14+).
11
+ */
12
+ var fs = require('fs');
13
+ var path = require('path');
14
+ var os = require('os');
15
+
16
+ var npmDir = path.join(os.homedir(), '.npm');
17
+
18
+ // 1. Clean stale rename artifacts from npx cache (fixes ENOTEMPTY)
19
+ try {
20
+ var npxRoot = path.join(npmDir, '_npx');
21
+ if (fs.existsSync(npxRoot)) {
22
+ var dirs = fs.readdirSync(npxRoot);
23
+ for (var i = 0; i < dirs.length; i++) {
24
+ var nm = path.join(npxRoot, dirs[i], 'node_modules');
25
+ if (fs.existsSync(nm) === false) continue;
26
+
27
+ try {
28
+ var entries = fs.readdirSync(nm);
29
+ for (var k = 0; k < entries.length; k++) {
30
+ var entry = entries[k];
31
+ // Stale rename targets: .package-name-XxXxXxXx (dot prefix, dash, 8+ alpha suffix)
32
+ if (entry.charAt(0) === '.' && entry.indexOf('-') > 0 && /[A-Za-z]{8}$/.test(entry)) {
33
+ try {
34
+ var p = path.join(nm, entry);
35
+ var stat = fs.statSync(p);
36
+ if (stat.isDirectory()) {
37
+ fs.rmSync(p, { recursive: true, force: true });
38
+ }
39
+ } catch (e) { /* ignore individual failures */ }
40
+ }
41
+ }
42
+ } catch (e) { /* can't read dir, skip */ }
43
+ }
44
+ }
45
+ } catch (e) { /* non-fatal */ }
46
+
47
+ // 2. Remove corrupted integrity entries from _cacache (fixes ECOMPROMISED)
48
+ // Scans index-v5 hash buckets for entries referencing claude-flow or ruflo
49
+ // packages and removes them so npm re-fetches with correct integrity.
50
+ try {
51
+ var cacheIndex = path.join(npmDir, '_cacache', 'index-v5');
52
+ if (fs.existsSync(cacheIndex)) {
53
+ // Walk the two-level hash bucket structure: index-v5/XX/YY/...
54
+ var buckets = fs.readdirSync(cacheIndex);
55
+ for (var bi = 0; bi < buckets.length; bi++) {
56
+ var bucketPath = path.join(cacheIndex, buckets[bi]);
57
+ try {
58
+ var stat = fs.statSync(bucketPath);
59
+ if (!stat.isDirectory()) continue;
60
+ var subBuckets = fs.readdirSync(bucketPath);
61
+ for (var si = 0; si < subBuckets.length; si++) {
62
+ var subPath = path.join(bucketPath, subBuckets[si]);
63
+ try {
64
+ var subStat = fs.statSync(subPath);
65
+ if (subStat.isDirectory()) {
66
+ // Third level
67
+ var files = fs.readdirSync(subPath);
68
+ for (var fi = 0; fi < files.length; fi++) {
69
+ var filePath = path.join(subPath, files[fi]);
70
+ try {
71
+ var content = fs.readFileSync(filePath, 'utf-8');
72
+ if (content.indexOf('claude-flow') !== -1 || content.indexOf('ruflo') !== -1) {
73
+ fs.unlinkSync(filePath);
74
+ }
75
+ } catch (e2) { /* skip unreadable */ }
76
+ }
77
+ } else {
78
+ // File at second level
79
+ try {
80
+ var content2 = fs.readFileSync(subPath, 'utf-8');
81
+ if (content2.indexOf('claude-flow') !== -1 || content2.indexOf('ruflo') !== -1) {
82
+ fs.unlinkSync(subPath);
83
+ }
84
+ } catch (e2) { /* skip unreadable */ }
85
+ }
86
+ } catch (e2) { /* skip */ }
87
+ }
88
+ } catch (e2) { /* skip unreadable bucket */ }
89
+ }
90
+ }
91
+ } catch (e) { /* non-fatal */ }
92
+
93
+ // 3. Remove stale package-lock.json files from npx cache entries
94
+ try {
95
+ if (fs.existsSync(npxRoot)) {
96
+ var cDirs = fs.readdirSync(npxRoot);
97
+ for (var j = 0; j < cDirs.length; j++) {
98
+ var lockFile = path.join(npxRoot, cDirs[j], 'package-lock.json');
99
+ try {
100
+ if (fs.existsSync(lockFile)) {
101
+ var lockStat = fs.statSync(lockFile);
102
+ // Remove lock files older than 1 hour (likely stale)
103
+ var ageMs = Date.now() - lockStat.mtimeMs;
104
+ if (ageMs > 3600000) {
105
+ fs.unlinkSync(lockFile);
106
+ }
107
+ }
108
+ } catch (e) { /* ignore */ }
109
+ }
110
+ }
111
+ } catch (e) { /* non-fatal */ }
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAiC,MAAM,aAAa,CAAC;AA4lI1E,eAAO,MAAM,YAAY,EAAE,OAiG1B,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAiC,MAAM,aAAa,CAAC;AAyzI1E,eAAO,MAAM,YAAY,EAAE,OAyG1B,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -32,7 +32,7 @@ const preEditCommand = {
32
32
  short: 'f',
33
33
  description: 'File path to edit',
34
34
  type: 'string',
35
- required: true
35
+ required: false
36
36
  },
37
37
  {
38
38
  name: 'operation',
@@ -53,12 +53,9 @@ const preEditCommand = {
53
53
  { command: 'claude-flow hooks pre-edit -f src/api.ts -o refactor', description: 'Pre-edit with operation type' }
54
54
  ],
55
55
  action: async (ctx) => {
56
- const filePath = ctx.args[0] || ctx.flags.file;
56
+ // Default file to 'unknown' for backward compatibility (env var may be empty)
57
+ const filePath = ctx.args[0] || ctx.flags.file || 'unknown';
57
58
  const operation = ctx.flags.operation || 'update';
58
- if (!filePath) {
59
- output.printError('File path is required. Use --file or -f flag.');
60
- return { success: false, exitCode: 1 };
61
- }
62
59
  output.printInfo(`Analyzing context for: ${output.highlight(filePath)}`);
63
60
  try {
64
61
  // Call MCP tool for pre-edit hook
@@ -134,14 +131,14 @@ const postEditCommand = {
134
131
  short: 'f',
135
132
  description: 'File path that was edited',
136
133
  type: 'string',
137
- required: true
134
+ required: false
138
135
  },
139
136
  {
140
137
  name: 'success',
141
138
  short: 's',
142
139
  description: 'Whether the edit was successful',
143
140
  type: 'boolean',
144
- required: true
141
+ required: false
145
142
  },
146
143
  {
147
144
  name: 'outcome',
@@ -161,16 +158,10 @@ const postEditCommand = {
161
158
  { command: 'claude-flow hooks post-edit -f src/api.ts --success false -o "Type error"', description: 'Record failed edit' }
162
159
  ],
163
160
  action: async (ctx) => {
164
- const filePath = ctx.args[0] || ctx.flags.file;
165
- const success = ctx.flags.success;
166
- if (!filePath) {
167
- output.printError('File path is required. Use --file or -f flag.');
168
- return { success: false, exitCode: 1 };
169
- }
170
- if (success === undefined) {
171
- output.printError('Success flag is required. Use --success true/false.');
172
- return { success: false, exitCode: 1 };
173
- }
161
+ // Default file to 'unknown' for backward compatibility (env var may be empty)
162
+ const filePath = ctx.args[0] || ctx.flags.file || 'unknown';
163
+ // Default success to true for backward compatibility (PostToolUse = success, PostToolUseFailure = failure)
164
+ const success = ctx.flags.success !== undefined ? ctx.flags.success : true;
174
165
  output.printInfo(`Recording outcome for: ${output.highlight(filePath)}`);
175
166
  try {
176
167
  // Parse metrics if provided
@@ -339,7 +330,7 @@ const postCommandCommand = {
339
330
  short: 's',
340
331
  description: 'Whether the command succeeded',
341
332
  type: 'boolean',
342
- required: true
333
+ required: false
343
334
  },
344
335
  {
345
336
  name: 'exit-code',
@@ -361,15 +352,12 @@ const postCommandCommand = {
361
352
  ],
362
353
  action: async (ctx) => {
363
354
  const command = ctx.args[0] || ctx.flags.command;
364
- const success = ctx.flags.success;
355
+ // Default success to true for backward compatibility
356
+ const success = ctx.flags.success !== undefined ? ctx.flags.success : true;
365
357
  if (!command) {
366
358
  output.printError('Command is required. Use --command or -c flag.');
367
359
  return { success: false, exitCode: 1 };
368
360
  }
369
- if (success === undefined) {
370
- output.printError('Success flag is required. Use --success true/false.');
371
- return { success: false, exitCode: 1 };
372
- }
373
361
  output.printInfo(`Recording command outcome: ${output.highlight(command)}`);
374
362
  try {
375
363
  // Call MCP tool for post-command hook
@@ -1305,7 +1293,7 @@ const postTaskCommand = {
1305
1293
  short: 's',
1306
1294
  description: 'Whether the task succeeded',
1307
1295
  type: 'boolean',
1308
- required: true
1296
+ required: false
1309
1297
  },
1310
1298
  {
1311
1299
  name: 'quality',
@@ -1327,11 +1315,8 @@ const postTaskCommand = {
1327
1315
  action: async (ctx) => {
1328
1316
  // Auto-generate task ID if not provided
1329
1317
  const taskId = ctx.flags.taskId || `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
1330
- const success = ctx.flags.success;
1331
- if (success === undefined) {
1332
- output.printError('Success flag is required. Use --success true/false.');
1333
- return { success: false, exitCode: 1 };
1334
- }
1318
+ // Default success to true for backward compatibility
1319
+ const success = ctx.flags.success !== undefined ? ctx.flags.success : true;
1335
1320
  output.printInfo(`Recording outcome for task: ${output.highlight(taskId)}`);
1336
1321
  try {
1337
1322
  const result = await callMCPTool('hooks_post-task', {
@@ -1649,19 +1634,20 @@ const intelligenceCommand = {
1649
1634
  // SONA Component
1650
1635
  output.writeln();
1651
1636
  output.writeln(output.bold('🧠 SONA (Sub-0.05ms Learning)'));
1652
- if (result.components.sona.enabled) {
1637
+ const sona = result.components?.sona;
1638
+ if (sona?.enabled) {
1653
1639
  output.printTable({
1654
1640
  columns: [
1655
1641
  { key: 'metric', header: 'Metric', width: 25 },
1656
1642
  { key: 'value', header: 'Value', width: 20, align: 'right' }
1657
1643
  ],
1658
1644
  data: [
1659
- { metric: 'Status', value: formatIntelligenceStatus(result.components.sona.status) },
1660
- { metric: 'Learning Time', value: `${result.components.sona.learningTimeMs.toFixed(3)}ms` },
1661
- { metric: 'Adaptation Time', value: `${result.components.sona.adaptationTimeMs.toFixed(3)}ms` },
1662
- { metric: 'Trajectories', value: result.components.sona.trajectoriesRecorded },
1663
- { metric: 'Patterns Learned', value: result.components.sona.patternsLearned },
1664
- { metric: 'Avg Quality', value: `${(result.components.sona.avgQuality * 100).toFixed(1)}%` }
1645
+ { metric: 'Status', value: formatIntelligenceStatus(sona.status) },
1646
+ { metric: 'Learning Time', value: `${(sona.learningTimeMs ?? 0).toFixed(3)}ms` },
1647
+ { metric: 'Adaptation Time', value: `${(sona.adaptationTimeMs ?? 0).toFixed(3)}ms` },
1648
+ { metric: 'Trajectories', value: sona.trajectoriesRecorded ?? 0 },
1649
+ { metric: 'Patterns Learned', value: sona.patternsLearned ?? 0 },
1650
+ { metric: 'Avg Quality', value: `${((sona.avgQuality ?? 0) * 100).toFixed(1)}%` }
1665
1651
  ]
1666
1652
  });
1667
1653
  }
@@ -1671,17 +1657,18 @@ const intelligenceCommand = {
1671
1657
  // MoE Component
1672
1658
  output.writeln();
1673
1659
  output.writeln(output.bold('🔀 Mixture of Experts (MoE)'));
1674
- if (result.components.moe.enabled) {
1660
+ const moe = result.components?.moe;
1661
+ if (moe?.enabled) {
1675
1662
  output.printTable({
1676
1663
  columns: [
1677
1664
  { key: 'metric', header: 'Metric', width: 25 },
1678
1665
  { key: 'value', header: 'Value', width: 20, align: 'right' }
1679
1666
  ],
1680
1667
  data: [
1681
- { metric: 'Status', value: formatIntelligenceStatus(result.components.moe.status) },
1682
- { metric: 'Active Experts', value: result.components.moe.expertsActive },
1683
- { metric: 'Routing Accuracy', value: `${(result.components.moe.routingAccuracy * 100).toFixed(1)}%` },
1684
- { metric: 'Load Balance', value: `${(result.components.moe.loadBalance * 100).toFixed(1)}%` }
1668
+ { metric: 'Status', value: formatIntelligenceStatus(moe.status) },
1669
+ { metric: 'Active Experts', value: moe.expertsActive ?? 0 },
1670
+ { metric: 'Routing Accuracy', value: `${((moe.routingAccuracy ?? 0) * 100).toFixed(1)}%` },
1671
+ { metric: 'Load Balance', value: `${((moe.loadBalance ?? 0) * 100).toFixed(1)}%` }
1685
1672
  ]
1686
1673
  });
1687
1674
  }
@@ -1691,18 +1678,19 @@ const intelligenceCommand = {
1691
1678
  // HNSW Component
1692
1679
  output.writeln();
1693
1680
  output.writeln(output.bold('🔍 HNSW (150x Faster Search)'));
1694
- if (result.components.hnsw.enabled) {
1681
+ const hnsw = result.components?.hnsw;
1682
+ if (hnsw?.enabled) {
1695
1683
  output.printTable({
1696
1684
  columns: [
1697
1685
  { key: 'metric', header: 'Metric', width: 25 },
1698
1686
  { key: 'value', header: 'Value', width: 20, align: 'right' }
1699
1687
  ],
1700
1688
  data: [
1701
- { metric: 'Status', value: formatIntelligenceStatus(result.components.hnsw.status) },
1702
- { metric: 'Index Size', value: result.components.hnsw.indexSize.toLocaleString() },
1703
- { metric: 'Search Speedup', value: output.success(result.components.hnsw.searchSpeedup) },
1704
- { metric: 'Memory Usage', value: result.components.hnsw.memoryUsage },
1705
- { metric: 'Dimension', value: result.components.hnsw.dimension }
1689
+ { metric: 'Status', value: formatIntelligenceStatus(hnsw.status) },
1690
+ { metric: 'Index Size', value: (hnsw.indexSize ?? 0).toLocaleString() },
1691
+ { metric: 'Search Speedup', value: output.success(hnsw.searchSpeedup ?? 'N/A') },
1692
+ { metric: 'Memory Usage', value: hnsw.memoryUsage ?? 'N/A' },
1693
+ { metric: 'Dimension', value: hnsw.dimension ?? 384 }
1706
1694
  ]
1707
1695
  });
1708
1696
  }
@@ -1712,18 +1700,24 @@ const intelligenceCommand = {
1712
1700
  // Embeddings
1713
1701
  output.writeln();
1714
1702
  output.writeln(output.bold('📦 Embeddings (ONNX)'));
1715
- output.printTable({
1716
- columns: [
1717
- { key: 'metric', header: 'Metric', width: 25 },
1718
- { key: 'value', header: 'Value', width: 20, align: 'right' }
1719
- ],
1720
- data: [
1721
- { metric: 'Provider', value: result.components.embeddings.provider },
1722
- { metric: 'Model', value: result.components.embeddings.model },
1723
- { metric: 'Dimension', value: result.components.embeddings.dimension },
1724
- { metric: 'Cache Hit Rate', value: `${(result.components.embeddings.cacheHitRate * 100).toFixed(1)}%` }
1725
- ]
1726
- });
1703
+ const emb = result.components?.embeddings;
1704
+ if (emb) {
1705
+ output.printTable({
1706
+ columns: [
1707
+ { key: 'metric', header: 'Metric', width: 25 },
1708
+ { key: 'value', header: 'Value', width: 20, align: 'right' }
1709
+ ],
1710
+ data: [
1711
+ { metric: 'Provider', value: emb.provider ?? 'N/A' },
1712
+ { metric: 'Model', value: emb.model ?? 'N/A' },
1713
+ { metric: 'Dimension', value: emb.dimension ?? 384 },
1714
+ { metric: 'Cache Hit Rate', value: `${((emb.cacheHitRate ?? 0) * 100).toFixed(1)}%` }
1715
+ ]
1716
+ });
1717
+ }
1718
+ else {
1719
+ output.writeln(output.dim(' Not initialized'));
1720
+ }
1727
1721
  // V3 Performance
1728
1722
  output.writeln();
1729
1723
  output.writeln(output.bold('🚀 V3 Performance Gains'));
@@ -3447,6 +3441,205 @@ const modelStatsCommand = {
3447
3441
  }
3448
3442
  }
3449
3443
  };
3444
+ // Teammate Idle command - Agent Teams integration
3445
+ const teammateIdleCommand = {
3446
+ name: 'teammate-idle',
3447
+ description: 'Handle idle teammate in Agent Teams - auto-assign tasks or notify lead',
3448
+ options: [
3449
+ {
3450
+ name: 'auto-assign',
3451
+ short: 'a',
3452
+ description: 'Automatically assign pending tasks to idle teammate',
3453
+ type: 'boolean',
3454
+ default: true
3455
+ },
3456
+ {
3457
+ name: 'check-task-list',
3458
+ short: 'c',
3459
+ description: 'Check shared task list for available work',
3460
+ type: 'boolean',
3461
+ default: true
3462
+ },
3463
+ {
3464
+ name: 'teammate-id',
3465
+ short: 't',
3466
+ description: 'ID of the idle teammate',
3467
+ type: 'string'
3468
+ },
3469
+ {
3470
+ name: 'team-name',
3471
+ description: 'Team name for context',
3472
+ type: 'string'
3473
+ }
3474
+ ],
3475
+ examples: [
3476
+ { command: 'claude-flow hooks teammate-idle --auto-assign true', description: 'Auto-assign tasks to idle teammate' },
3477
+ { command: 'claude-flow hooks teammate-idle -t worker-1 --check-task-list', description: 'Check tasks for specific teammate' }
3478
+ ],
3479
+ action: async (ctx) => {
3480
+ const autoAssign = ctx.flags.autoAssign !== false;
3481
+ const checkTaskList = ctx.flags.checkTaskList !== false;
3482
+ const teammateId = ctx.flags.teammateId;
3483
+ const teamName = ctx.flags.teamName;
3484
+ if (ctx.flags.format !== 'json') {
3485
+ output.printInfo(`Teammate idle hook triggered${teammateId ? ` for: ${output.highlight(teammateId)}` : ''}`);
3486
+ }
3487
+ try {
3488
+ const result = await callMCPTool('hooks_teammate-idle', {
3489
+ autoAssign,
3490
+ checkTaskList,
3491
+ teammateId,
3492
+ teamName,
3493
+ timestamp: Date.now(),
3494
+ });
3495
+ if (ctx.flags.format === 'json') {
3496
+ output.printJson(result);
3497
+ return { success: true, data: result };
3498
+ }
3499
+ output.writeln();
3500
+ if (result.action === 'assigned' && result.taskAssigned) {
3501
+ output.printSuccess(`Task assigned: ${result.taskAssigned.subject}`);
3502
+ output.printList([
3503
+ `Task ID: ${result.taskAssigned.taskId}`,
3504
+ `Priority: ${result.taskAssigned.priority}`,
3505
+ `Pending tasks remaining: ${result.pendingTasks}`
3506
+ ]);
3507
+ }
3508
+ else if (result.action === 'waiting') {
3509
+ output.printInfo('No pending tasks available - teammate waiting for work');
3510
+ }
3511
+ else {
3512
+ output.printInfo(`Team lead notified: ${result.message}`);
3513
+ }
3514
+ return { success: true, data: result };
3515
+ }
3516
+ catch (error) {
3517
+ // Graceful fallback - don't fail hard, just report
3518
+ if (ctx.flags.format === 'json') {
3519
+ output.printJson({ success: true, action: 'waiting', message: 'Teammate idle - no MCP server' });
3520
+ }
3521
+ else {
3522
+ output.printInfo('Teammate idle - awaiting task assignment');
3523
+ }
3524
+ return { success: true };
3525
+ }
3526
+ }
3527
+ };
3528
+ // Task Completed command - Agent Teams integration
3529
+ const taskCompletedCommand = {
3530
+ name: 'task-completed',
3531
+ description: 'Handle task completion in Agent Teams - train patterns and notify lead',
3532
+ options: [
3533
+ {
3534
+ name: 'task-id',
3535
+ short: 'i',
3536
+ description: 'ID of the completed task',
3537
+ type: 'string',
3538
+ required: true
3539
+ },
3540
+ {
3541
+ name: 'train-patterns',
3542
+ short: 'p',
3543
+ description: 'Train neural patterns from successful task',
3544
+ type: 'boolean',
3545
+ default: true
3546
+ },
3547
+ {
3548
+ name: 'notify-lead',
3549
+ short: 'n',
3550
+ description: 'Notify team lead of task completion',
3551
+ type: 'boolean',
3552
+ default: true
3553
+ },
3554
+ {
3555
+ name: 'success',
3556
+ short: 's',
3557
+ description: 'Whether the task succeeded',
3558
+ type: 'boolean',
3559
+ default: true
3560
+ },
3561
+ {
3562
+ name: 'quality',
3563
+ short: 'q',
3564
+ description: 'Quality score (0-1)',
3565
+ type: 'number'
3566
+ },
3567
+ {
3568
+ name: 'teammate-id',
3569
+ short: 't',
3570
+ description: 'ID of the teammate that completed the task',
3571
+ type: 'string'
3572
+ }
3573
+ ],
3574
+ examples: [
3575
+ { command: 'claude-flow hooks task-completed -i task-123 --train-patterns', description: 'Complete task and train patterns' },
3576
+ { command: 'claude-flow hooks task-completed -i task-456 --notify-lead --quality 0.95', description: 'Complete with quality score' }
3577
+ ],
3578
+ action: async (ctx) => {
3579
+ const taskId = ctx.args[0] || ctx.flags.taskId;
3580
+ const trainPatterns = ctx.flags.trainPatterns !== false;
3581
+ const notifyLead = ctx.flags.notifyLead !== false;
3582
+ const success = ctx.flags.success !== false;
3583
+ const quality = ctx.flags.quality;
3584
+ const teammateId = ctx.flags.teammateId;
3585
+ if (!taskId) {
3586
+ output.printError('Task ID is required. Use --task-id or -i flag.');
3587
+ return { success: false, exitCode: 1 };
3588
+ }
3589
+ if (ctx.flags.format !== 'json') {
3590
+ output.printInfo(`Task completed: ${output.highlight(taskId)}`);
3591
+ }
3592
+ try {
3593
+ const result = await callMCPTool('hooks_task-completed', {
3594
+ taskId,
3595
+ trainPatterns,
3596
+ notifyLead,
3597
+ success,
3598
+ quality,
3599
+ teammateId,
3600
+ timestamp: Date.now(),
3601
+ });
3602
+ if (ctx.flags.format === 'json') {
3603
+ output.printJson(result);
3604
+ return { success: true, data: result };
3605
+ }
3606
+ output.writeln();
3607
+ output.printSuccess(`Task ${taskId} marked complete`);
3608
+ output.writeln();
3609
+ output.writeln(output.bold('Completion Metrics'));
3610
+ output.printTable({
3611
+ columns: [
3612
+ { key: 'metric', header: 'Metric', width: 25 },
3613
+ { key: 'value', header: 'Value', width: 20, align: 'right' }
3614
+ ],
3615
+ data: [
3616
+ { metric: 'Patterns Learned', value: result.patternsLearned },
3617
+ { metric: 'Quality Score', value: quality ? `${(quality * 100).toFixed(0)}%` : 'N/A' },
3618
+ { metric: 'Lead Notified', value: result.leadNotified ? 'Yes' : 'No' },
3619
+ { metric: 'Learning Updates', value: result.metrics?.learningUpdates || 0 }
3620
+ ]
3621
+ });
3622
+ if (result.nextTask) {
3623
+ output.writeln();
3624
+ output.printInfo(`Next available task: ${result.nextTask.subject}`);
3625
+ }
3626
+ return { success: true, data: result };
3627
+ }
3628
+ catch (error) {
3629
+ // Graceful fallback
3630
+ if (ctx.flags.format === 'json') {
3631
+ output.printJson({ success: true, taskId, message: 'Task completed - patterns pending' });
3632
+ }
3633
+ else {
3634
+ output.printSuccess(`Task ${taskId} completed`);
3635
+ if (trainPatterns) {
3636
+ output.printInfo('Pattern training queued for next sync');
3637
+ }
3638
+ }
3639
+ return { success: true };
3640
+ }
3641
+ }
3642
+ };
3450
3643
  // Main hooks command
3451
3644
  export const hooksCommand = {
3452
3645
  name: 'hooks',
@@ -3486,6 +3679,9 @@ export const hooksCommand = {
3486
3679
  sessionStartCommand,
3487
3680
  preBashCommand,
3488
3681
  postBashCommand,
3682
+ // Agent Teams integration
3683
+ teammateIdleCommand,
3684
+ taskCompletedCommand,
3489
3685
  ],
3490
3686
  options: [],
3491
3687
  examples: [
@@ -3528,7 +3724,11 @@ export const hooksCommand = {
3528
3724
  `${output.highlight('token-optimize')} - Token optimization (30-50% savings)`,
3529
3725
  `${output.highlight('model-route')} - Route to optimal model (haiku/sonnet/opus)`,
3530
3726
  `${output.highlight('model-outcome')} - Record model routing outcome`,
3531
- `${output.highlight('model-stats')} - View model routing statistics`
3727
+ `${output.highlight('model-stats')} - View model routing statistics`,
3728
+ '',
3729
+ output.bold('Agent Teams:'),
3730
+ `${output.highlight('teammate-idle')} - Handle idle teammate (auto-assign tasks)`,
3731
+ `${output.highlight('task-completed')} - Handle task completion (train patterns)`
3532
3732
  ]);
3533
3733
  output.writeln();
3534
3734
  output.writeln('Run "claude-flow hooks <subcommand> --help" for subcommand help');
@@ -3540,7 +3740,8 @@ export const hooksCommand = {
3540
3740
  '🔍 AgentDB integration (150x faster search)',
3541
3741
  '📊 84.8% SWE-Bench solve rate',
3542
3742
  '🎯 32.3% token reduction',
3543
- '🚀 2.8-4.4x speed improvement'
3743
+ '🚀 2.8-4.4x speed improvement',
3744
+ '👥 Agent Teams integration (auto task assignment)'
3544
3745
  ]);
3545
3746
  return { success: true };
3546
3747
  }