@sparkleideas/claude-flow-patch 3.1.0-alpha.44.patch.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 (120) hide show
  1. package/AGENTS.md +162 -0
  2. package/CLAUDE.md +506 -0
  3. package/README.md +351 -0
  4. package/bin/claude-flow-patch.mjs +148 -0
  5. package/check-patches.sh +195 -0
  6. package/lib/categories.json +15 -0
  7. package/lib/common.py +97 -0
  8. package/lib/discover.mjs +181 -0
  9. package/lib/discover.sh +160 -0
  10. package/package.json +86 -0
  11. package/patch/010-CF-001-doctor-yaml/README.md +11 -0
  12. package/patch/010-CF-001-doctor-yaml/fix.py +20 -0
  13. package/patch/010-CF-001-doctor-yaml/sentinel +1 -0
  14. package/patch/020-CF-002-config-export-yaml/README.md +11 -0
  15. package/patch/020-CF-002-config-export-yaml/fix.py +130 -0
  16. package/patch/020-CF-002-config-export-yaml/sentinel +1 -0
  17. package/patch/030-DM-001-daemon-log-zero/README.md +12 -0
  18. package/patch/030-DM-001-daemon-log-zero/fix.py +37 -0
  19. package/patch/030-DM-001-daemon-log-zero/sentinel +1 -0
  20. package/patch/040-DM-002-cpu-load-threshold/README.md +11 -0
  21. package/patch/040-DM-002-cpu-load-threshold/fix.py +6 -0
  22. package/patch/040-DM-002-cpu-load-threshold/sentinel +1 -0
  23. package/patch/050-DM-003-macos-freemem/README.md +11 -0
  24. package/patch/050-DM-003-macos-freemem/fix.py +7 -0
  25. package/patch/050-DM-003-macos-freemem/sentinel +1 -0
  26. package/patch/060-DM-004-preload-worker-stub/README.md +11 -0
  27. package/patch/060-DM-004-preload-worker-stub/fix.py +34 -0
  28. package/patch/060-DM-004-preload-worker-stub/sentinel +1 -0
  29. package/patch/070-DM-005-consolidation-worker-stub/README.md +11 -0
  30. package/patch/070-DM-005-consolidation-worker-stub/fix.py +46 -0
  31. package/patch/070-DM-005-consolidation-worker-stub/sentinel +1 -0
  32. package/patch/080-EM-001-embedding-ignores-config/README.md +11 -0
  33. package/patch/080-EM-001-embedding-ignores-config/fix.py +111 -0
  34. package/patch/080-EM-001-embedding-ignores-config/sentinel +1 -0
  35. package/patch/090-EM-002-transformers-cache-eacces/README.md +11 -0
  36. package/patch/090-EM-002-transformers-cache-eacces/fix.sh +12 -0
  37. package/patch/090-EM-002-transformers-cache-eacces/sentinel +1 -0
  38. package/patch/100-GV-001-hnsw-ghost-vectors/README.md +11 -0
  39. package/patch/100-GV-001-hnsw-ghost-vectors/fix.py +34 -0
  40. package/patch/100-GV-001-hnsw-ghost-vectors/sentinel +1 -0
  41. package/patch/110-HK-001-post-edit-file-path/README.md +44 -0
  42. package/patch/110-HK-001-post-edit-file-path/fix.py +23 -0
  43. package/patch/110-HK-001-post-edit-file-path/sentinel +1 -0
  44. package/patch/120-HK-002-hooks-tools-stub/README.md +36 -0
  45. package/patch/120-HK-002-hooks-tools-stub/fix.py +155 -0
  46. package/patch/120-HK-002-hooks-tools-stub/sentinel +1 -0
  47. package/patch/130-HK-003-metrics-hardcoded/README.md +30 -0
  48. package/patch/130-HK-003-metrics-hardcoded/fix.py +82 -0
  49. package/patch/130-HK-003-metrics-hardcoded/sentinel +1 -0
  50. package/patch/135-HK-004-respect-daemon-autostart/README.md +11 -0
  51. package/patch/135-HK-004-respect-daemon-autostart/fix.py +14 -0
  52. package/patch/135-HK-004-respect-daemon-autostart/sentinel +1 -0
  53. package/patch/137-HK-005-daemon-pid-guard/README.md +11 -0
  54. package/patch/137-HK-005-daemon-pid-guard/fix.py +53 -0
  55. package/patch/137-HK-005-daemon-pid-guard/sentinel +2 -0
  56. package/patch/140-HW-001-stdin-hang/README.md +11 -0
  57. package/patch/140-HW-001-stdin-hang/fix.py +6 -0
  58. package/patch/140-HW-001-stdin-hang/sentinel +1 -0
  59. package/patch/150-HW-002-failures-swallowed/README.md +11 -0
  60. package/patch/150-HW-002-failures-swallowed/fix.py +42 -0
  61. package/patch/150-HW-002-failures-swallowed/sentinel +1 -0
  62. package/patch/160-HW-003-aggressive-intervals/README.md +11 -0
  63. package/patch/160-HW-003-aggressive-intervals/fix.py +52 -0
  64. package/patch/160-HW-003-aggressive-intervals/sentinel +3 -0
  65. package/patch/170-IN-001-intelligence-stub/README.md +64 -0
  66. package/patch/170-IN-001-intelligence-stub/fix.py +63 -0
  67. package/patch/170-IN-001-intelligence-stub/sentinel +1 -0
  68. package/patch/180-MM-001-memory-persist-path/README.md +27 -0
  69. package/patch/180-MM-001-memory-persist-path/fix.py +54 -0
  70. package/patch/180-MM-001-memory-persist-path/sentinel +1 -0
  71. package/patch/190-NS-001-discovery-default-namespace/README.md +16 -0
  72. package/patch/190-NS-001-discovery-default-namespace/fix.py +68 -0
  73. package/patch/190-NS-001-discovery-default-namespace/sentinel +2 -0
  74. package/patch/200-NS-002-targeted-require-namespace/README.md +19 -0
  75. package/patch/200-NS-002-targeted-require-namespace/fix.py +158 -0
  76. package/patch/200-NS-002-targeted-require-namespace/sentinel +2 -0
  77. package/patch/210-NS-003-namespace-typo-pattern/README.md +15 -0
  78. package/patch/210-NS-003-namespace-typo-pattern/fix.py +23 -0
  79. package/patch/210-NS-003-namespace-typo-pattern/sentinel +1 -0
  80. package/patch/220-RS-001-better-sqlite3-node24/README.md +54 -0
  81. package/patch/220-RS-001-better-sqlite3-node24/fix.py +27 -0
  82. package/patch/220-RS-001-better-sqlite3-node24/rebuild.sh +31 -0
  83. package/patch/220-RS-001-better-sqlite3-node24/sentinel +2 -0
  84. package/patch/230-RV-001-force-learn-tick/README.md +31 -0
  85. package/patch/230-RV-001-force-learn-tick/fix.py +14 -0
  86. package/patch/230-RV-001-force-learn-tick/sentinel +2 -0
  87. package/patch/240-RV-002-trajectory-load/README.md +28 -0
  88. package/patch/240-RV-002-trajectory-load/fix.py +14 -0
  89. package/patch/240-RV-002-trajectory-load/sentinel +2 -0
  90. package/patch/250-RV-003-trajectory-stats-sync/README.md +31 -0
  91. package/patch/250-RV-003-trajectory-stats-sync/fix.py +18 -0
  92. package/patch/250-RV-003-trajectory-stats-sync/sentinel +2 -0
  93. package/patch/260-SG-001-init-settings/README.md +29 -0
  94. package/patch/260-SG-001-init-settings/fix.py +143 -0
  95. package/patch/260-SG-001-init-settings/sentinel +4 -0
  96. package/patch/270-SG-003-init-helpers-all-paths/README.md +60 -0
  97. package/patch/270-SG-003-init-helpers-all-paths/fix.py +165 -0
  98. package/patch/270-SG-003-init-helpers-all-paths/sentinel +3 -0
  99. package/patch/280-UI-001-intelligence-stats-crash/README.md +11 -0
  100. package/patch/280-UI-001-intelligence-stats-crash/fix.py +57 -0
  101. package/patch/280-UI-001-intelligence-stats-crash/sentinel +1 -0
  102. package/patch/290-UI-002-neural-status-not-loaded/README.md +11 -0
  103. package/patch/290-UI-002-neural-status-not-loaded/fix.py +19 -0
  104. package/patch/290-UI-002-neural-status-not-loaded/sentinel +1 -0
  105. package/patch/300-DM-006-log-rotation/README.md +12 -0
  106. package/patch/300-DM-006-log-rotation/fix.py +72 -0
  107. package/patch/300-DM-006-log-rotation/sentinel +2 -0
  108. package/patch/310-HW-004-runwithtimeout-orphan/README.md +11 -0
  109. package/patch/310-HW-004-runwithtimeout-orphan/fix.py +10 -0
  110. package/patch/310-HW-004-runwithtimeout-orphan/sentinel +1 -0
  111. package/patch/320-SG-004-wizard-parity/README.md +40 -0
  112. package/patch/320-SG-004-wizard-parity/fix.py +208 -0
  113. package/patch/320-SG-004-wizard-parity/sentinel +3 -0
  114. package/patch/330-SG-005-start-all-subcommand/README.md +32 -0
  115. package/patch/330-SG-005-start-all-subcommand/fix.py +58 -0
  116. package/patch/330-SG-005-start-all-subcommand/sentinel +1 -0
  117. package/patch-all.sh +199 -0
  118. package/repair-post-init.sh +263 -0
  119. package/scripts/preflight.mjs +249 -0
  120. package/scripts/upstream-log.mjs +257 -0
@@ -0,0 +1,57 @@
1
+ # UI-001: intelligence stats crashes on .toFixed() of undefined
2
+ # Absorbed from old patch-17. Applied via sed to npx cache.
3
+
4
+ # SONA component null checks
5
+ patch("17a: SONA learningTimeMs null check",
6
+ HOOKS_CMD,
7
+ "{ metric: 'Learning Time', value: `${result.components.sona.learningTimeMs.toFixed(3)}ms` }",
8
+ "{ metric: 'Learning Time', value: result.components.sona.learningTimeMs != null ? `${result.components.sona.learningTimeMs.toFixed(3)}ms` : 'N/A' }")
9
+
10
+ patch("17b: SONA adaptationTimeMs null check",
11
+ HOOKS_CMD,
12
+ "{ metric: 'Adaptation Time', value: `${result.components.sona.adaptationTimeMs.toFixed(3)}ms` }",
13
+ "{ metric: 'Adaptation Time', value: result.components.sona.adaptationTimeMs != null ? `${result.components.sona.adaptationTimeMs.toFixed(3)}ms` : 'N/A' }")
14
+
15
+ patch("17c: SONA avgQuality null check",
16
+ HOOKS_CMD,
17
+ "{ metric: 'Avg Quality', value: `${(result.components.sona.avgQuality * 100).toFixed(1)}%` }",
18
+ "{ metric: 'Avg Quality', value: result.components.sona.avgQuality != null ? `${(result.components.sona.avgQuality * 100).toFixed(1)}%` : 'N/A' }")
19
+
20
+ # MoE component null checks
21
+ patch("17d: MoE routingAccuracy null check",
22
+ HOOKS_CMD,
23
+ "{ metric: 'Routing Accuracy', value: `${(result.components.moe.routingAccuracy * 100).toFixed(1)}%` }",
24
+ "{ metric: 'Routing Accuracy', value: result.components.moe.routingAccuracy != null ? `${(result.components.moe.routingAccuracy * 100).toFixed(1)}%` : 'N/A' }")
25
+
26
+ patch("17e: MoE loadBalance null check",
27
+ HOOKS_CMD,
28
+ "{ metric: 'Load Balance', value: `${(result.components.moe.loadBalance * 100).toFixed(1)}%` }",
29
+ "{ metric: 'Load Balance', value: result.components.moe.loadBalance != null ? `${(result.components.moe.loadBalance * 100).toFixed(1)}%` : 'N/A' }")
30
+
31
+ # Embeddings null check
32
+ patch("17f: embeddings cacheHitRate null check",
33
+ HOOKS_CMD,
34
+ "{ metric: 'Cache Hit Rate', value: `${(result.components.embeddings.cacheHitRate * 100).toFixed(1)}%` }",
35
+ "{ metric: 'Cache Hit Rate', value: result.components.embeddings.cacheHitRate != null ? `${(result.components.embeddings.cacheHitRate * 100).toFixed(1)}%` : 'N/A' }")
36
+
37
+ # Performance section null guard
38
+ patch("17g: performance section null guard",
39
+ HOOKS_CMD,
40
+ """ output.printList([
41
+ `Flash Attention: ${output.success(result.performance.flashAttention)}`,
42
+ `Memory Reduction: ${output.success(result.performance.memoryReduction)}`,
43
+ `Search Improvement: ${output.success(result.performance.searchImprovement)}`,
44
+ `Token Reduction: ${output.success(result.performance.tokenReduction)}`,
45
+ `SWE-Bench Score: ${output.success(result.performance.sweBenchScore)}`
46
+ ]);""",
47
+ """ if (result.performance) {
48
+ output.printList([
49
+ `Flash Attention: ${output.success(result.performance.flashAttention || 'N/A')}`,
50
+ `Memory Reduction: ${output.success(result.performance.memoryReduction || 'N/A')}`,
51
+ `Search Improvement: ${output.success(result.performance.searchImprovement || 'N/A')}`,
52
+ `Token Reduction: ${output.success(result.performance.tokenReduction || 'N/A')}`,
53
+ `SWE-Bench Score: ${output.success(result.performance.sweBenchScore || 'N/A')}`
54
+ ]);
55
+ } else {
56
+ output.writeln(output.dim(' No performance data available'));
57
+ }""")
@@ -0,0 +1 @@
1
+ grep "learningTimeMs != null" commands/hooks.js
@@ -0,0 +1,11 @@
1
+ # UI-002: neural status shows "Not loaded"
2
+ **Severity**: Low (cosmetic)
3
+ **GitHub**: [#1146](https://github.com/ruvnet/claude-flow/issues/1146)
4
+ ## Root Cause
5
+ `neural status` reads module-level flags (`initialized`, `sonaAvailable`, `hnswIndex`) without calling their init functions. RuVector WASM, SONA Engine, and HNSW Index always show "Not loaded" even when packages are installed and working.
6
+ ## Fix
7
+ Add `initializeTraining()` and `getHNSWIndex()` calls before reading status. Update import to include `getHNSWIndex`.
8
+ ## Files Patched
9
+ - commands/neural.js
10
+ ## Ops
11
+ 2 ops in fix.py
@@ -0,0 +1,19 @@
1
+ # UI-002: neural status shows "Not loaded" for installed components
2
+ # Absorbed from old patch-18. Applied manually to npx cache.
3
+
4
+ # Update import to include getHNSWIndex
5
+ patch("18a: neural.js import getHNSWIndex",
6
+ NEURAL,
7
+ "const { getHNSWStatus, loadEmbeddingModel } = await import('../memory/memory-initializer.js');",
8
+ "const { getHNSWIndex, getHNSWStatus, loadEmbeddingModel } = await import('../memory/memory-initializer.js');")
9
+
10
+ # Add initialization calls before status reads
11
+ patch("18b: neural.js init before status",
12
+ NEURAL,
13
+ " const ruvectorStats = ruvector.getTrainingStats();",
14
+ """ // Patch 18: Initialize RuVector WASM + SONA + HNSW so status reflects reality
15
+ if (!ruvector.getTrainingStats().initialized) {
16
+ await ruvector.initializeTraining({ useSona: true }).catch(() => {});
17
+ }
18
+ await getHNSWIndex().catch(() => null);
19
+ const ruvectorStats = ruvector.getTrainingStats();""")
@@ -0,0 +1 @@
1
+ grep "getHNSWIndex" commands/neural.js
@@ -0,0 +1,12 @@
1
+ # DM-006: No log rotation — logs grow unbounded
2
+ **Severity**: Medium
3
+ **GitHub**: [#1114](https://github.com/ruvnet/claude-flow/issues/1114)
4
+ ## Root Cause
5
+ (Headless) `logExecution()` in `headless-worker-executor.js` creates 2-3 log files per worker run (~75 KB each) but has zero cleanup. No rotation, no max file count, no TTL. At current daemon intervals this accumulates ~23 MB/day, ~702 MB/month. (Main) `startBackgroundDaemon()` in `daemon.js` opens `daemon.log` in append mode and never truncates. A single long-running daemon can grow daemon.log to 100+ GB.
6
+ ## Fix
7
+ (A) Add `unlinkSync` and `statSync` to the headless executor ESM import. (B) Call `cleanupOldLogs()` from `ensureLogDir()` so cleanup runs on each headless execution cycle. (C) Add `cleanupOldLogs()` method: removes `.log` files older than 7 days or beyond a 500-file cap, keeping newest files. (D) In `daemon.js`, before opening `daemon.log` for append, check its size with `fs.statSync()` and rotate to `daemon.log.1` if > 50MB.
8
+ ## Files Patched
9
+ - services/headless-worker-executor.js
10
+ - commands/daemon.js
11
+ ## Ops
12
+ 4 ops in fix.py
@@ -0,0 +1,72 @@
1
+ # DM-006: No log rotation — headless execution logs grow unbounded
2
+ # GitHub: #1114
3
+
4
+ # A: Add unlinkSync and statSync to ESM import
5
+ patch("DM-006a: add unlinkSync/statSync to fs import",
6
+ HWE,
7
+ "import { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync } from 'fs';",
8
+ "import { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync, unlinkSync, statSync } from 'fs';")
9
+
10
+ # B: Call cleanupOldLogs() from ensureLogDir()
11
+ patch("DM-006b: call cleanup from ensureLogDir",
12
+ HWE,
13
+ """ ensureLogDir() {
14
+ try {
15
+ if (!existsSync(this.config.logDir)) {
16
+ mkdirSync(this.config.logDir, { recursive: true });
17
+ }
18
+ }
19
+ catch (error) {
20
+ this.emit('warning', { message: 'Failed to create log directory', error });
21
+ }
22
+ }""",
23
+ """ ensureLogDir() {
24
+ try {
25
+ if (!existsSync(this.config.logDir)) {
26
+ mkdirSync(this.config.logDir, { recursive: true });
27
+ }
28
+ this.cleanupOldLogs();
29
+ }
30
+ catch (error) {
31
+ this.emit('warning', { message: 'Failed to create log directory', error });
32
+ }
33
+ }""")
34
+
35
+ # C: Add cleanupOldLogs() method before logExecution()
36
+ patch("DM-006c: add cleanupOldLogs method",
37
+ HWE,
38
+ """ logExecution(executionId, type, content) {""",
39
+ """ cleanupOldLogs(maxAgeDays = 7, maxFiles = 500) {
40
+ try {
41
+ const files = readdirSync(this.config.logDir)
42
+ .filter(f => f.endsWith('.log'))
43
+ .map(f => {
44
+ try { return { name: f, mtime: statSync(join(this.config.logDir, f)).mtimeMs }; }
45
+ catch { return null; }
46
+ })
47
+ .filter(Boolean)
48
+ .sort((a, b) => b.mtime - a.mtime);
49
+ const cutoff = Date.now() - maxAgeDays * 86400000;
50
+ for (let i = 0; i < files.length; i++) {
51
+ if (files[i].mtime < cutoff || i >= maxFiles) {
52
+ try { unlinkSync(join(this.config.logDir, files[i].name)); } catch {}
53
+ }
54
+ }
55
+ }
56
+ catch { /* ignore cleanup errors */ }
57
+ }
58
+ logExecution(executionId, type, content) {""")
59
+
60
+ # DM-006 extension: Main daemon.log rotation in daemon.js
61
+ # Before opening daemon.log for append, check size and rotate if > 50MB
62
+ patch("DM-006d: main daemon.log rotation",
63
+ DJ,
64
+ " const logFile = join(logsDir, 'daemon.log');",
65
+ """ const logFile = join(logsDir, 'daemon.log');
66
+ // Rotate main daemon.log if > 50MB
67
+ try {
68
+ const logStat = fs.statSync(logFile);
69
+ if (logStat.size > 50 * 1024 * 1024) {
70
+ fs.renameSync(logFile, logFile + '.1');
71
+ }
72
+ } catch { /* file doesn't exist yet or stat failed — ignore */ }""")
@@ -0,0 +1,2 @@
1
+ grep "cleanupOldLogs" services/headless-worker-executor.js
2
+ grep "Rotate main daemon.log" commands/daemon.js
@@ -0,0 +1,11 @@
1
+ # HW-004: runWithTimeout rejects but does not kill child process
2
+ **Severity**: Medium
3
+ **GitHub**: [#1117](https://github.com/ruvnet/claude-flow/issues/1117)
4
+ ## Root Cause
5
+ `runWithTimeout()` in `worker-daemon.js` has `DEFAULT_WORKER_TIMEOUT_MS = 5 * 60 * 1000` (5 min), but the headless executor's per-worker timeouts range from 5-15 minutes. When the daemon timeout fires first, the promise rejects but the underlying `claude --print` child process keeps running as an orphan until the executor's own timeout fires minutes later.
6
+ ## Fix
7
+ Raise `DEFAULT_WORKER_TIMEOUT_MS` from 5 minutes to 16 minutes so the daemon timeout never fires before the executor's own per-worker timeout (max 15 min for audit/refactor workers). The executor handles its own child process cleanup on timeout.
8
+ ## Files Patched
9
+ - services/worker-daemon.js
10
+ ## Ops
11
+ 1 op in fix.py
@@ -0,0 +1,10 @@
1
+ # HW-004: runWithTimeout rejects but does not kill child process
2
+ # GitHub: #1117
3
+
4
+ # A: Raise daemon worker timeout above max headless timeout (15 min)
5
+ patch("HW-004a: raise worker timeout to 16 min",
6
+ WD,
7
+ """// Worker timeout (5 minutes max per worker)
8
+ const DEFAULT_WORKER_TIMEOUT_MS = 5 * 60 * 1000;""",
9
+ """// Worker timeout — must exceed max headless timeout (15 min for audit/refactor)
10
+ const DEFAULT_WORKER_TIMEOUT_MS = 16 * 60 * 1000;""")
@@ -0,0 +1 @@
1
+ grep "16 \* 60 \* 1000" services/worker-daemon.js
@@ -0,0 +1,40 @@
1
+ # SG-004: init wizard lacks parity with init
2
+
3
+ **Severity**: High
4
+ **GitHub**: [#1181](https://github.com/ruvnet/claude-flow/issues/1181)
5
+
6
+ ## Root Cause
7
+
8
+ The `wizardCommand.action` in `commands/init.js` was implemented as a
9
+ standalone code path that diverges from the parent `initAction`. It skips the
10
+ already-initialized guard, ignores `--force`, `--start-all`, `--start-daemon`,
11
+ `--codex`, and `--dual` flags, and never shows "Next steps" hints. The wizard
12
+ is also only reachable as a subcommand of `init` with no `options` array, so
13
+ the parser cannot validate flags for the wizard context.
14
+
15
+ ## Fix
16
+
17
+ Ten ops bring the wizard to full parity with `init` and promote it to a
18
+ top-level command (`claude-flow wizard`):
19
+
20
+ | Op | What it does |
21
+ |----|-------------|
22
+ | SG-004a | Adds the already-initialized guard before prompts + passes `--force` to options |
23
+ | SG-004b | Adds `--codex`/`--dual` handling after executeInit succeeds |
24
+ | SG-004c | Adds `--start-all`/`--start-daemon` service startup + "Next steps" hints |
25
+ | SG-004d | Fixes catch block — catches errors cleanly instead of re-throwing |
26
+ | SG-004e | Exports `wizardCommand` from init.js, adds `options` + `examples` arrays |
27
+ | SG-004f | Imports `wizardCommand` in the command registry (`commands/index.js`) |
28
+ | SG-004g | Adds wizard to `commandLoaders` for lazy-loading |
29
+ | SG-004h | Pre-populates wizard in the loaded commands cache |
30
+ | SG-004i | Adds `wizardCommand` to the `commands` array (parser registration) |
31
+ | SG-004j | Adds `wizardCommand` to `commandsByCategory.primary` for help display |
32
+
33
+ ## Files Patched
34
+
35
+ - `commands/init.js`
36
+ - `commands/index.js`
37
+
38
+ ## Ops
39
+
40
+ 10 ops in fix.py
@@ -0,0 +1,208 @@
1
+ # SG-004: init wizard lacks parity with init
2
+ # GitHub: #1181
3
+ #
4
+ # The wizard was implemented as a standalone code path that ignores
5
+ # --force, --start-all, --start-daemon, --codex, --dual, and skips
6
+ # the already-initialized guard and "Next steps" hints. It is also only
7
+ # reachable as a subcommand of `init` with no options array, so the parser
8
+ # cannot validate flags for the wizard context.
9
+ #
10
+ # 10 ops: init-guard + force (a), codex/dual (b), start-all + next-steps (c),
11
+ # catch-block error handling (d), export + options (e),
12
+ # import in registry (f), loaders (g), cache (h),
13
+ # commands array (i), category (j)
14
+
15
+ # Op 1: Add already-initialized guard + pass --force to executeInit options
16
+ patch("SG-004a: wizard init-guard + --force",
17
+ INIT_CMD,
18
+ """ try {
19
+ // Start with base options
20
+ const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd };""",
21
+ """ try {
22
+ // SG-004: Check if already initialized (respects --force)
23
+ const force = ctx.flags.force;
24
+ const initialized = isInitialized(ctx.cwd);
25
+ const hasExisting = initialized.claude || initialized.claudeFlow;
26
+ if (hasExisting && !force) {
27
+ output.printWarning('Claude Flow appears to be already initialized');
28
+ if (initialized.claude) output.printInfo(' Found: .claude/settings.json');
29
+ if (initialized.claudeFlow) output.printInfo(' Found: .claude-flow/config.yaml');
30
+ output.printInfo('Use --force to reinitialize');
31
+ const proceed = await confirm({
32
+ message: 'Do you want to reinitialize? This will overwrite existing configuration.',
33
+ default: false,
34
+ });
35
+ if (!proceed) {
36
+ return { success: true, message: 'Wizard cancelled' };
37
+ }
38
+ }
39
+ // Start with base options
40
+ const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd, force: ctx.flags.force };""")
41
+
42
+ # Op 2: Add --codex / --dual handling after executeInit succeeds
43
+ patch("SG-004b: wizard --codex/--dual support",
44
+ INIT_CMD,
45
+ """ spinner.succeed('Setup complete!');
46
+ // Initialize embeddings if enabled
47
+ let embeddingsInitialized = false;""",
48
+ """ spinner.succeed('Setup complete!');
49
+ // SG-004: Respect --codex / --dual in wizard
50
+ const codexMode = ctx.flags.codex;
51
+ const dualMode = ctx.flags.dual;
52
+ if (codexMode || dualMode) {
53
+ try {
54
+ output.writeln(output.dim(' Initializing Codex integration...'));
55
+ await initCodexAction(ctx, { codexMode, dualMode, force: ctx.flags.force, minimal: false, full: false });
56
+ } catch (err) {
57
+ output.printWarning(`Codex initialization: ${err instanceof Error ? err.message : String(err)}`);
58
+ }
59
+ }
60
+ // Initialize embeddings if enabled
61
+ let embeddingsInitialized = false;""")
62
+
63
+ # Op 3: Add --start-all / --start-daemon + "Next steps" hints before final return
64
+ patch("SG-004c: wizard --start-all + next-steps",
65
+ INIT_CMD,
66
+ """ });
67
+ return { success: true, data: result };
68
+ }
69
+ catch (error) {
70
+ if (error instanceof Error && error.message === 'User cancelled') {""",
71
+ """ });
72
+ // SG-004: Respect --start-all / --start-daemon in wizard
73
+ const startAll = ctx.flags['start-all'] || ctx.flags.startAll;
74
+ const startDaemon = ctx.flags['start-daemon'] || ctx.flags.startDaemon || startAll;
75
+ if (startDaemon || startAll) {
76
+ output.writeln();
77
+ output.printInfo('Starting services...');
78
+ const { execSync } = await import('child_process');
79
+ if (startAll) {
80
+ try {
81
+ output.writeln(output.dim(' Initializing memory database...'));
82
+ execSync('npx @claude-flow/cli@latest memory init 2>/dev/null', {
83
+ stdio: 'pipe', cwd: ctx.cwd, timeout: 30000
84
+ });
85
+ output.writeln(output.success(' \\u2713 Memory initialized'));
86
+ } catch { output.writeln(output.dim(' Memory database already exists')); }
87
+ }
88
+ if (startDaemon) {
89
+ try {
90
+ output.writeln(output.dim(' Starting daemon...'));
91
+ execSync('npx @claude-flow/cli@latest daemon start 2>/dev/null &', {
92
+ stdio: 'pipe', cwd: ctx.cwd, timeout: 10000
93
+ });
94
+ output.writeln(output.success(' \\u2713 Daemon started'));
95
+ } catch { output.writeln(output.warning(' Daemon may already be running')); }
96
+ }
97
+ if (startAll) {
98
+ try {
99
+ output.writeln(output.dim(' Initializing swarm...'));
100
+ execSync('npx @claude-flow/cli@latest swarm init --topology hierarchical 2>/dev/null', {
101
+ stdio: 'pipe', cwd: ctx.cwd, timeout: 30000
102
+ });
103
+ output.writeln(output.success(' \\u2713 Swarm initialized'));
104
+ } catch { output.writeln(output.dim(' Swarm initialization skipped')); }
105
+ }
106
+ output.writeln();
107
+ output.printSuccess('All services started');
108
+ }
109
+ else {
110
+ output.writeln(output.bold('Next steps:'));
111
+ output.printList([
112
+ `Run ${output.highlight('claude-flow daemon start')} to start background workers`,
113
+ `Run ${output.highlight('claude-flow memory init')} to initialize memory database`,
114
+ `Run ${output.highlight('claude-flow swarm init')} to initialize a swarm`,
115
+ `Or re-run with ${output.highlight('--start-all')} to do all of the above`,
116
+ ]);
117
+ }
118
+ return { success: true, data: result };
119
+ }
120
+ catch (error) {
121
+ if (error instanceof Error && error.message === 'User cancelled') {""")
122
+
123
+ # Op 4: Fix wizard catch block — re-throws instead of clean error message
124
+ # spinner is declared inside the try block so we can't call spinner.fail() here
125
+ patch("SG-004d: wizard catch block handles errors cleanly",
126
+ INIT_CMD,
127
+ """ if (error instanceof Error && error.message === 'User cancelled') {
128
+ output.printInfo('Setup cancelled');
129
+ return { success: true };
130
+ }
131
+ throw error;""",
132
+ """ if (error instanceof Error && error.message === 'User cancelled') {
133
+ output.printInfo('Setup cancelled');
134
+ return { success: true };
135
+ }
136
+ output.printError(`Failed to initialize: ${error instanceof Error ? error.message : String(error)}`);
137
+ return { success: false, exitCode: 1 };""")
138
+
139
+ # ── Promote wizard to top-level command ──
140
+ # Ops e–j: export wizardCommand with options, register in command registry
141
+
142
+ # Op 5: Export wizardCommand + add options/examples arrays
143
+ patch("SG-004e: export wizardCommand with options",
144
+ INIT_CMD,
145
+ """// Wizard subcommand for interactive setup
146
+ const wizardCommand = {
147
+ name: 'wizard',
148
+ description: 'Interactive setup wizard for comprehensive configuration',
149
+ action: async (ctx) => {""",
150
+ """// Wizard — top-level command + init subcommand — SG-004
151
+ export const wizardCommand = {
152
+ name: 'wizard',
153
+ aliases: ['wiz'],
154
+ description: 'Interactive setup wizard for comprehensive configuration',
155
+ options: [
156
+ { name: 'force', short: 'f', description: 'Overwrite existing configuration', type: 'boolean', default: false },
157
+ { name: 'start-all', description: 'Auto-start daemon, memory, and swarm after init', type: 'boolean', default: false },
158
+ { name: 'start-daemon', description: 'Auto-start daemon after init', type: 'boolean', default: false },
159
+ { name: 'codex', description: 'Initialize for OpenAI Codex CLI', type: 'boolean', default: false },
160
+ { name: 'dual', description: 'Initialize for both Claude Code and Codex', type: 'boolean', default: false },
161
+ { name: 'with-embeddings', description: 'Initialize ONNX embedding subsystem', type: 'boolean', default: false },
162
+ { name: 'embedding-model', description: 'ONNX embedding model', type: 'string', default: 'all-MiniLM-L6-v2', choices: ['all-MiniLM-L6-v2', 'all-mpnet-base-v2'] },
163
+ ],
164
+ examples: [
165
+ { command: 'claude-flow wizard', description: 'Run interactive setup wizard' },
166
+ { command: 'claude-flow wizard --start-all', description: 'Wizard then start all services' },
167
+ { command: 'claude-flow wizard --force', description: 'Reinitialize with wizard' },
168
+ { command: 'claude-flow wizard --codex', description: 'Wizard with Codex integration' },
169
+ ],
170
+ action: async (ctx) => {""")
171
+
172
+ # Op 6: Import wizardCommand in command registry
173
+ patch("SG-004f: import wizardCommand in command registry",
174
+ CMDS_INDEX,
175
+ """import { initCommand } from './init.js';""",
176
+ """import { initCommand, wizardCommand } from './init.js';""")
177
+
178
+ # Op 7: Add wizard to commandLoaders for lazy loading
179
+ patch("SG-004g: add wizard to commandLoaders",
180
+ CMDS_INDEX,
181
+ """ init: () => import('./init.js'),""",
182
+ """ init: () => import('./init.js'),
183
+ wizard: () => import('./init.js'),""")
184
+
185
+ # Op 8: Pre-populate wizard in loadedCommands cache
186
+ patch("SG-004h: cache wizard command",
187
+ CMDS_INDEX,
188
+ """loadedCommands.set('init', initCommand);""",
189
+ """loadedCommands.set('init', initCommand);
190
+ loadedCommands.set('wizard', wizardCommand);""")
191
+
192
+ # Op 9: Add wizardCommand to commands array (triggers parser registration)
193
+ patch("SG-004i: register wizard in commands array",
194
+ CMDS_INDEX,
195
+ """ initCommand,
196
+ startCommand,""",
197
+ """ initCommand,
198
+ wizardCommand,
199
+ startCommand,""")
200
+
201
+ # Op 10: Add wizardCommand to commandsByCategory.primary for help display
202
+ patch("SG-004j: add wizard to primary category",
203
+ CMDS_INDEX,
204
+ """ primary: [
205
+ initCommand,""",
206
+ """ primary: [
207
+ initCommand,
208
+ wizardCommand,""")
@@ -0,0 +1,3 @@
1
+ grep "SG-004" commands/init.js
2
+ grep "export const wizardCommand" commands/init.js
3
+ grep "wizardCommand" commands/index.js
@@ -0,0 +1,32 @@
1
+ # SG-005: add 'start all' subcommand to start everything at once
2
+
3
+ **Severity**: Enhancement
4
+ **GitHub**: [#1177](https://github.com/ruvnet/claude-flow/issues/1177)
5
+
6
+ ## Root Cause
7
+
8
+ There is no single command to start the full Claude Flow stack (memory +
9
+ daemon + swarm + MCP) on an already-initialized project. `claude-flow start`
10
+ only initializes the swarm and MCP server. Users must run `memory init`,
11
+ `daemon start`, and `start` separately, or re-run `init --start-all` which
12
+ also re-creates project files.
13
+
14
+ ## Fix
15
+
16
+ Add an `allCommand` subcommand to the `start` command so that
17
+ `claude-flow start all` initializes memory, starts the daemon, then runs the
18
+ normal `startAction` (swarm + MCP + health checks).
19
+
20
+ | Op | What it does |
21
+ |----|-------------|
22
+ | SG-005a | Adds `allCommand` subcommand definition before `quickCommand` |
23
+ | SG-005b | Registers `allCommand` in the `subcommands` array |
24
+ | SG-005c | Adds `start all` to the examples array for `--help` output |
25
+
26
+ ## Files Patched
27
+
28
+ - `commands/start.js`
29
+
30
+ ## Ops
31
+
32
+ 3 ops in fix.py
@@ -0,0 +1,58 @@
1
+ # SG-005: add 'start all' subcommand to start everything at once
2
+ # GitHub: #1177
3
+
4
+ patch("SG-005a: add allCommand subcommand definition",
5
+ START_CMD,
6
+ """// Quick start subcommand
7
+ const quickCommand = {""",
8
+ """// Start-all subcommand — SG-005
9
+ const allCommand = {
10
+ name: 'all',
11
+ aliases: ['everything'],
12
+ description: 'Start memory, daemon, swarm, and MCP server',
13
+ action: async (ctx) => {
14
+ // Check initialization
15
+ if (!isInitialized(ctx.cwd)) {
16
+ output.printError('Claude Flow is not initialized in this directory');
17
+ output.printInfo('Run "claude-flow init" first, or use "claude-flow start quick"');
18
+ return { success: false, exitCode: 1 };
19
+ }
20
+ output.writeln();
21
+ output.writeln(output.bold('Starting all Claude Flow services'));
22
+ output.writeln();
23
+ const { execSync } = await import('child_process');
24
+ // Step 1: Initialize memory
25
+ try {
26
+ output.writeln(output.dim(' Initializing memory database...'));
27
+ execSync('npx @claude-flow/cli@latest memory init 2>/dev/null', {
28
+ stdio: 'pipe', cwd: ctx.cwd, timeout: 30000
29
+ });
30
+ output.writeln(' \\u2713 Memory initialized');
31
+ } catch { output.writeln(' Memory database already exists'); }
32
+ // Step 2: Start daemon
33
+ try {
34
+ output.writeln(output.dim(' Starting daemon...'));
35
+ execSync('npx @claude-flow/cli@latest daemon start 2>/dev/null &', {
36
+ stdio: 'pipe', cwd: ctx.cwd, timeout: 10000
37
+ });
38
+ output.writeln(' \\u2713 Daemon started');
39
+ } catch { output.writeln(' Daemon may already be running'); }
40
+ // Step 3: Start swarm + MCP via normal startAction
41
+ return startAction(ctx);
42
+ }
43
+ };
44
+ // Quick start subcommand
45
+ const quickCommand = {""")
46
+
47
+ patch("SG-005b: register allCommand in subcommands array",
48
+ START_CMD,
49
+ """ subcommands: [stopCommand, restartCommand, quickCommand],""",
50
+ """ subcommands: [stopCommand, restartCommand, quickCommand, allCommand],""")
51
+
52
+ patch("SG-005c: add 'start all' to examples array",
53
+ START_CMD,
54
+ """ { command: 'claude-flow start stop', description: 'Stop the running system' }
55
+ ],""",
56
+ """ { command: 'claude-flow start stop', description: 'Stop the running system' },
57
+ { command: 'claude-flow start all', description: 'Start memory, daemon, swarm, and MCP' }
58
+ ],""")
@@ -0,0 +1 @@
1
+ grep "allCommand" commands/start.js