@sparkleideas/claude-flow-patch 3.1.0-alpha.44.patch.6 → 3.1.0-alpha.44.patch.8
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.
- package/CLAUDE.md +21 -3
- package/README.md +306 -83
- package/lib/common.py +1 -0
- package/package.json +1 -1
- package/patch/137-HK-005-daemon-pid-guard/README.md +11 -0
- package/patch/137-HK-005-daemon-pid-guard/fix.py +53 -0
- package/patch/137-HK-005-daemon-pid-guard/sentinel +2 -0
- package/patch/320-SG-004-wizard-parity/README.md +32 -0
- package/patch/320-SG-004-wizard-parity/fix.py +133 -0
- package/patch/320-SG-004-wizard-parity/sentinel +1 -0
- package/patch/330-SG-005-start-all-subcommand/README.md +32 -0
- package/patch/330-SG-005-start-all-subcommand/fix.py +58 -0
- package/patch/330-SG-005-start-all-subcommand/sentinel +1 -0
package/CLAUDE.md
CHANGED
|
@@ -91,7 +91,13 @@ gh issue comment <NUMBER> --repo ruvnet/claude-flow --body "$(cat <<'EOF'
|
|
|
91
91
|
|
|
92
92
|
Defect **{PREFIX}-{NNN}** in [claude-flow-patch](https://github.com/sparkling/claude-flow-patch).
|
|
93
93
|
|
|
94
|
+
**Root cause:** <1-2 sentences explaining why the bug occurs at the code level>
|
|
95
|
+
|
|
94
96
|
<What the patch does. Be specific. Include a table if multiple ops.>
|
|
97
|
+
|
|
98
|
+
**Affected versions:** `@claude-flow/cli` 3.1.0-alpha.44 through current
|
|
99
|
+
|
|
100
|
+
**Related issues:** #NNN, #NNN
|
|
95
101
|
EOF
|
|
96
102
|
)"
|
|
97
103
|
```
|
|
@@ -115,6 +121,12 @@ gh issue create --repo ruvnet/claude-flow \
|
|
|
115
121
|
|
|
116
122
|
## Files Affected
|
|
117
123
|
- <dist/src/path/to/file.js>
|
|
124
|
+
|
|
125
|
+
## Affected Versions
|
|
126
|
+
`@claude-flow/cli` 3.1.0-alpha.44 through current
|
|
127
|
+
|
|
128
|
+
## Related Issues
|
|
129
|
+
- #NNN — <short description of relationship>
|
|
118
130
|
EOF
|
|
119
131
|
)"
|
|
120
132
|
```
|
|
@@ -124,6 +136,7 @@ Save the returned GitHub issue number for the defect README.md.
|
|
|
124
136
|
### Comment hygiene:
|
|
125
137
|
|
|
126
138
|
- One comment per defect, describing the patch. No meta-commentary.
|
|
139
|
+
- Every comment/body MUST include affected versions and related issues (use "None" if truly standalone).
|
|
127
140
|
- If you need to replace a comment, delete the old one first (`gh api -X DELETE`).
|
|
128
141
|
- Do not reference defect history, deletion/restoration, or internal decisions.
|
|
129
142
|
|
|
@@ -136,17 +149,17 @@ Save the returned GitHub issue number for the defect README.md.
|
|
|
136
149
|
| DM | Daemon & Workers | 6 |
|
|
137
150
|
| EM | Embeddings & HNSW | 2 |
|
|
138
151
|
| GV | Ghost Vectors | 1 |
|
|
139
|
-
| HK | Hooks |
|
|
152
|
+
| HK | Hooks | 5 |
|
|
140
153
|
| HW | Headless Worker | 4 |
|
|
141
154
|
| IN | Intelligence | 1 |
|
|
142
155
|
| MM | Memory Management | 1 |
|
|
143
156
|
| NS | Memory Namespace | 3 |
|
|
144
157
|
| RS | ruv-swarm | 1 |
|
|
145
158
|
| RV | RuVector Intelligence | 3 |
|
|
146
|
-
| SG | Settings Generator |
|
|
159
|
+
| SG | Settings Generator | 4 |
|
|
147
160
|
| UI | Display & Cosmetic | 2 |
|
|
148
161
|
|
|
149
|
-
## All
|
|
162
|
+
## All 35 Defects
|
|
150
163
|
|
|
151
164
|
| ID | GitHub Issue | Severity |
|
|
152
165
|
|----|-------------|----------|
|
|
@@ -164,6 +177,7 @@ Save the returned GitHub issue number for the defect README.md.
|
|
|
164
177
|
| HK-002 | [#1058 MCP hook handlers are stubs that don't persist data](https://github.com/ruvnet/claude-flow/issues/1058) | High |
|
|
165
178
|
| HK-003 | [#1158 hooks_metrics MCP handler returns hardcoded fake data](https://github.com/ruvnet/claude-flow/issues/1158) | High |
|
|
166
179
|
| HK-004 | [#1175 hooks_session-start ignores daemon.autoStart from settings.json](https://github.com/ruvnet/claude-flow/issues/1175) | High |
|
|
180
|
+
| HK-005 | [#1171 Multiple MCP servers start independent in-process daemons](https://github.com/ruvnet/claude-flow/issues/1171) | Critical |
|
|
167
181
|
| HW-001 | [#1111 Headless workers hang — stdin pipe never closed](https://github.com/ruvnet/claude-flow/issues/1111) | Critical |
|
|
168
182
|
| HW-002 | [#1112 Headless failures silently swallowed as success](https://github.com/ruvnet/claude-flow/issues/1112) | High |
|
|
169
183
|
| HW-003 | [#1113 Worker scheduling intervals too aggressive + settings ignored](https://github.com/ruvnet/claude-flow/issues/1113) | High |
|
|
@@ -182,6 +196,8 @@ Save the returned GitHub issue number for the defect README.md.
|
|
|
182
196
|
| UI-002 | [#1146 neural status shows "Not loaded"](https://github.com/ruvnet/claude-flow/issues/1146) | Low |
|
|
183
197
|
| DM-006 | [#1114 No log rotation — logs grow unbounded](https://github.com/ruvnet/claude-flow/issues/1114) | Medium |
|
|
184
198
|
| HW-004 | [#1117 runWithTimeout rejects but does not kill child process](https://github.com/ruvnet/claude-flow/issues/1117) | Medium |
|
|
199
|
+
| SG-004 | [#1181 init wizard lacks parity with init](https://github.com/ruvnet/claude-flow/issues/1181) | High |
|
|
200
|
+
| SG-005 | [#1177 add 'start all' subcommand to start everything at once](https://github.com/ruvnet/claude-flow/issues/1177) | Enhancement |
|
|
185
201
|
<!-- GENERATED:defect-tables:end -->
|
|
186
202
|
|
|
187
203
|
---
|
|
@@ -307,6 +323,8 @@ Both are idempotent: skip if `new` already present, warn if `old` not found.
|
|
|
307
323
|
| `SETTINGS_GEN` | `init/settings-generator.js` | @claude-flow/cli |
|
|
308
324
|
| `HELPERS_GEN` | `init/helpers-generator.js` | @claude-flow/cli |
|
|
309
325
|
| `EXECUTOR` | `init/executor.js` | @claude-flow/cli |
|
|
326
|
+
| `INIT_CMD` | `commands/init.js` | @claude-flow/cli |
|
|
327
|
+
| `START_CMD` | `commands/start.js` | @claude-flow/cli |
|
|
310
328
|
| `ruvector_cli` | `bin/cli.js` | ruvector |
|
|
311
329
|
|
|
312
330
|
To target a new file, add a variable to `lib/common.py` following the existing pattern.
|
package/README.md
CHANGED
|
@@ -1,71 +1,42 @@
|
|
|
1
1
|
# @sparkleideas/claude-flow-patch
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
| [DM-004](https://github.com/sparkling/claude-flow-patch/tree/master/patch/060-DM-004-preload-worker-stub) | Preload worker stub + missing from defaults | [#1139](https://github.com/ruvnet/claude-flow/issues/1139) |
|
|
26
|
-
| [DM-005](https://github.com/sparkling/claude-flow-patch/tree/master/patch/070-DM-005-consolidation-worker-stub) | Consolidation worker stub (no decay/rebuild) | [#1140](https://github.com/ruvnet/claude-flow/issues/1140) |
|
|
27
|
-
| [DM-006](https://github.com/sparkling/claude-flow-patch/tree/master/patch/300-DM-006-log-rotation) | No log rotation — logs grow unbounded | [#1114](https://github.com/ruvnet/claude-flow/issues/1114) |
|
|
28
|
-
| [EM-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/080-EM-001-embedding-ignores-config) | Embedding system ignores project config (model + HNSW dims) | [#1143](https://github.com/ruvnet/claude-flow/issues/1143) |
|
|
29
|
-
| [EM-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/090-EM-002-transformers-cache-eacces) | @xenova/transformers cache EACCES | [#1144](https://github.com/ruvnet/claude-flow/issues/1144) |
|
|
30
|
-
| [GV-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/100-GV-001-hnsw-ghost-vectors) | HNSW ghost vectors persist after memory delete | [#1122](https://github.com/ruvnet/claude-flow/issues/1122) |
|
|
31
|
-
| [HK-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/110-HK-001-post-edit-file-path) | post-edit hook records file_path as "unknown" | [#1155](https://github.com/ruvnet/claude-flow/issues/1155) |
|
|
32
|
-
| [HK-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/120-HK-002-hooks-tools-stub) | MCP hook handlers are stubs that don't persist data | [#1058](https://github.com/ruvnet/claude-flow/issues/1058) |
|
|
33
|
-
| [HK-003](https://github.com/sparkling/claude-flow-patch/tree/master/patch/130-HK-003-metrics-hardcoded) | hooks_metrics MCP handler returns hardcoded fake data | [#1158](https://github.com/ruvnet/claude-flow/issues/1158) |
|
|
34
|
-
| [HK-004](https://github.com/sparkling/claude-flow-patch/tree/master/patch/135-HK-004-respect-daemon-autostart) | hooks_session-start ignores daemon.autoStart from settings.json | [#1175](https://github.com/ruvnet/claude-flow/issues/1175) |
|
|
35
|
-
| [HW-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/140-HW-001-stdin-hang) | Headless workers hang — stdin pipe never closed | [#1111](https://github.com/ruvnet/claude-flow/issues/1111) |
|
|
36
|
-
| [HW-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/150-HW-002-failures-swallowed) | Headless failures silently swallowed as success | [#1112](https://github.com/ruvnet/claude-flow/issues/1112) |
|
|
37
|
-
| [HW-003](https://github.com/sparkling/claude-flow-patch/tree/master/patch/160-HW-003-aggressive-intervals) | Worker scheduling intervals too aggressive + settings ignored | [#1113](https://github.com/ruvnet/claude-flow/issues/1113) |
|
|
38
|
-
| [HW-004](https://github.com/sparkling/claude-flow-patch/tree/master/patch/310-HW-004-runwithtimeout-orphan) | runWithTimeout rejects but does not kill child process | [#1117](https://github.com/ruvnet/claude-flow/issues/1117) |
|
|
39
|
-
| [IN-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/170-IN-001-intelligence-stub) | intelligence.cjs is a stub that doesn't actually learn | [#1154](https://github.com/ruvnet/claude-flow/issues/1154) |
|
|
40
|
-
| [MM-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/180-MM-001-memory-persist-path) | Remove dead persistPath config option | [#1152](https://github.com/ruvnet/claude-flow/issues/1152) |
|
|
41
|
-
| [NS-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/190-NS-001-discovery-default-namespace) | Discovery ops default to wrong namespace | [#1123](https://github.com/ruvnet/claude-flow/issues/1123) |
|
|
42
|
-
| [NS-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/200-NS-002-targeted-require-namespace) | Store/delete/retrieve fall back to 'default' + accept 'all' | [#581](https://github.com/ruvnet/claude-flow/issues/581) |
|
|
43
|
-
| [NS-003](https://github.com/sparkling/claude-flow-patch/tree/master/patch/210-NS-003-namespace-typo-pattern) | Namespace typo 'pattern' vs 'patterns' | [#1136](https://github.com/ruvnet/claude-flow/issues/1136) |
|
|
44
|
-
| [RS-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/220-RS-001-better-sqlite3-node24) | ruv-swarm MCP fails on Node 24 — better-sqlite3 missing native bindings | [ruv-FANN#185](https://github.com/ruvnet/ruv-FANN/issues/185) |
|
|
45
|
-
| [RV-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/230-RV-001-force-learn-tick) | force-learn command calls intel.tick() which doesn't exist | [#1156](https://github.com/ruvnet/claude-flow/issues/1156) |
|
|
46
|
-
| [RV-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/240-RV-002-trajectory-load) | activeTrajectories not loaded from saved file | [#1157](https://github.com/ruvnet/claude-flow/issues/1157) |
|
|
47
|
-
| [RV-003](https://github.com/sparkling/claude-flow-patch/tree/master/patch/250-RV-003-trajectory-stats-sync) | trajectory-end does not update stats counters | [ruv-FANN#186](https://github.com/ruvnet/ruv-FANN/issues/186) |
|
|
48
|
-
| [SG-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/260-SG-001-init-settings) | Init generates invalid settings | [#1150](https://github.com/ruvnet/claude-flow/issues/1150) |
|
|
49
|
-
| [SG-003](https://github.com/sparkling/claude-flow-patch/tree/master/patch/270-SG-003-init-helpers-all-paths) | Init missing helpers for --dual, --minimal, hooks, and upgrade paths | [#1169](https://github.com/ruvnet/claude-flow/issues/1169) |
|
|
50
|
-
| [UI-001](https://github.com/sparkling/claude-flow-patch/tree/master/patch/280-UI-001-intelligence-stats-crash) | intelligence stats crashes on .toFixed() | [#1145](https://github.com/ruvnet/claude-flow/issues/1145) |
|
|
51
|
-
| [UI-002](https://github.com/sparkling/claude-flow-patch/tree/master/patch/290-UI-002-neural-status-not-loaded) | neural status shows "Not loaded" | [#1146](https://github.com/ruvnet/claude-flow/issues/1146) |
|
|
52
|
-
<!-- GENERATED:npm-defects:end -->
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Quick Start](#quick-start)
|
|
6
|
+
- [CLI Commands](#cli-commands)
|
|
7
|
+
- [How It Works](#how-it-works)
|
|
8
|
+
- [Sentinel Files](#sentinel-files)
|
|
9
|
+
- [Target Packages](#target-packages)
|
|
10
|
+
- [Dependency Order](#dependency-order)
|
|
11
|
+
- [Key Design Decisions](#key-design-decisions)
|
|
12
|
+
- [Repository Structure](#repository-structure)
|
|
13
|
+
- [Defect Index](#defect-index)
|
|
14
|
+
- [Init-Script Patches](#init-script-patches)
|
|
15
|
+
- [Compatibility](#compatibility)
|
|
16
|
+
- [Links](#links)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Community patches for [`@claude-flow/cli`](https://www.npmjs.com/package/@claude-flow/cli) **v3.1.0-alpha.41**, [`ruvector`](https://www.npmjs.com/package/ruvector), and [`ruv-swarm`](https://www.npmjs.com/package/ruv-swarm) **v1.0.20**.
|
|
21
|
+
|
|
22
|
+
These patches fix 29 defects across 13 categories. They are applied at runtime via idempotent Python scripts that perform targeted string replacements on the npx-cached source files.
|
|
23
|
+
|
|
24
|
+
<a id="quick-start"></a>
|
|
53
25
|
|
|
54
26
|
## Quick Start
|
|
55
27
|
|
|
56
|
-
Patch
|
|
28
|
+
**Patch before init.** Several patches fix the init/generator scripts. If you run `claude-flow init` before patching, the generated `.claude/helpers/` files will be stubs with no learning, no PageRank, and no-op feedback. Always patch first:
|
|
57
29
|
|
|
58
30
|
```bash
|
|
59
|
-
# 1
|
|
31
|
+
# 1. Patch first -- fixes the init generators
|
|
60
32
|
npx --yes @sparkleideas/claude-flow-patch --global
|
|
61
33
|
|
|
62
|
-
# 2
|
|
63
|
-
npx
|
|
34
|
+
# 2. Then init (or re-init if already initialized)
|
|
35
|
+
npx @claude-flow/cli@latest init # fresh project
|
|
36
|
+
npx @claude-flow/cli@latest init upgrade # existing project
|
|
64
37
|
|
|
65
|
-
# 3
|
|
66
|
-
npx @claude-flow
|
|
67
|
-
# or
|
|
68
|
-
npx @claude-flow/cli@latest init upgrade
|
|
38
|
+
# 3. Verify
|
|
39
|
+
npx --yes @sparkleideas/claude-flow-patch check
|
|
69
40
|
```
|
|
70
41
|
|
|
71
42
|
If you already initialized before patching:
|
|
@@ -74,6 +45,19 @@ If you already initialized before patching:
|
|
|
74
45
|
npx --yes @sparkleideas/claude-flow-patch repair --target /path/to/project
|
|
75
46
|
```
|
|
76
47
|
|
|
48
|
+
### Target Options
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx --yes @sparkleideas/claude-flow-patch # global npx cache (default)
|
|
52
|
+
npx --yes @sparkleideas/claude-flow-patch --global # explicit global
|
|
53
|
+
npx --yes @sparkleideas/claude-flow-patch --target ~/my-project # project's node_modules
|
|
54
|
+
npx --yes @sparkleideas/claude-flow-patch --global --target ~/my-project # both
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`npx @claude-flow/cli` uses local `node_modules` if present, otherwise the global npx cache. Use `--target` to patch a project's local install.
|
|
58
|
+
|
|
59
|
+
<a id="cli-commands"></a>
|
|
60
|
+
|
|
77
61
|
## CLI Commands
|
|
78
62
|
|
|
79
63
|
| Command | Purpose |
|
|
@@ -83,46 +67,285 @@ npx --yes @sparkleideas/claude-flow-patch repair --target /path/to/project
|
|
|
83
67
|
| `claude-flow-patch check` | Verify patch sentinels and auto-detect drift |
|
|
84
68
|
| `claude-flow-patch repair --target <dir> [--source auto\|local\|global] [--dry-run]` | Rehydrate `.claude/helpers` in projects initialized before patching |
|
|
85
69
|
|
|
86
|
-
|
|
70
|
+
<a id="how-it-works"></a>
|
|
87
71
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
72
|
+
## How It Works
|
|
73
|
+
|
|
74
|
+
1. `patch-all.sh` locates the `@claude-flow/cli` dist files in the npm/npx cache
|
|
75
|
+
2. Globs `patch/*/fix.py` (numeric prefixes on directories ensure correct execution order)
|
|
76
|
+
3. Concatenates `lib/common.py` with each `fix.py` and runs as a single Python process
|
|
77
|
+
4. Each patch is idempotent: skips if already applied, warns if source changed
|
|
78
|
+
|
|
79
|
+
The `check-patches.sh` sentinel runs on session start to detect npx cache wipes and auto-reapply. It reads `sentinel` files from each patch directory — no hardcoded patch list.
|
|
80
|
+
|
|
81
|
+
<a id="sentinel-files"></a>
|
|
82
|
+
|
|
83
|
+
### Sentinel Files
|
|
84
|
+
|
|
85
|
+
Each patch directory contains a `sentinel` file that declares how to verify the patch is applied:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
grep "pattern to find" relative/path/to/file.js
|
|
89
|
+
absent "pattern that should NOT exist" relative/path.js
|
|
90
|
+
none
|
|
91
|
+
package: ruvector
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Directive | Meaning |
|
|
95
|
+
|-----------|---------|
|
|
96
|
+
| `grep "..." file` | Pass if pattern is found in file (standard check) |
|
|
97
|
+
| `absent "..." file` | Pass if pattern is **not** found (removal check) |
|
|
98
|
+
| `none` | No sentinel — skip verification |
|
|
99
|
+
| `package: X` | Target package (default: `@claude-flow/cli`). Skipped if package not installed |
|
|
100
|
+
|
|
101
|
+
`check-patches.sh` and `lib/discover.mjs` both read these files dynamically. Adding a new patch requires no edits to any script — just create the `sentinel` file in the new patch directory.
|
|
102
|
+
|
|
103
|
+
<a id="target-packages"></a>
|
|
104
|
+
|
|
105
|
+
### Target Packages
|
|
106
|
+
|
|
107
|
+
| Package | Version | Location | Env var |
|
|
108
|
+
|---------|---------|----------|---------|
|
|
109
|
+
| `@claude-flow/cli` | `3.1.0-alpha.41` | `~/.npm/_npx/*/node_modules/@claude-flow/cli/dist/src/` | `BASE` |
|
|
110
|
+
| `ruvector` | (bundled) | `~/.npm/_npx/*/node_modules/ruvector/bin/cli.js` | `RUVECTOR_CLI` |
|
|
111
|
+
| `ruv-swarm` | `1.0.20` | `~/.npm/_npx/*/node_modules/ruv-swarm/` | (found via glob) |
|
|
112
|
+
|
|
113
|
+
`BASE` is set by `patch-all.sh`. All path variables in `lib/common.py` derive from it.
|
|
114
|
+
`RUVECTOR_CLI` is set by `patch-all.sh` to the ruvector CLI entry point.
|
|
115
|
+
RS-001 locates its own target via `find`.
|
|
116
|
+
|
|
117
|
+
<a id="dependency-order"></a>
|
|
118
|
+
|
|
119
|
+
### Dependency Order
|
|
120
|
+
|
|
121
|
+
Execution order is controlled by 3-digit numeric prefixes on directory names (e.g. `010-CF-001-*`,
|
|
122
|
+
`170-IN-001-*`). `patch-all.sh` globs `patch/*/fix.py`, which sorts lexicographically — numeric
|
|
123
|
+
prefixes guarantee correct order.
|
|
124
|
+
|
|
125
|
+
Two dependency chains exist:
|
|
126
|
+
|
|
127
|
+
| Chain | Directories | Reason |
|
|
128
|
+
|-------|-------------|--------|
|
|
129
|
+
| IN-001 -> SG-003 | `170-IN-001-*` before `270-SG-003-*` | SG-003's patch targets code introduced by IN-001 |
|
|
130
|
+
| NS-001 -> NS-002 -> NS-003 | `190-NS-001-*` before `200-NS-002-*` before `210-NS-003-*` | Sequential namespace fixes |
|
|
131
|
+
|
|
132
|
+
All other patches are independent.
|
|
133
|
+
|
|
134
|
+
<a id="key-design-decisions"></a>
|
|
135
|
+
|
|
136
|
+
### Key Design Decisions
|
|
137
|
+
|
|
138
|
+
- **Zero-maintenance discovery**: `patch-all.sh`, `check-patches.sh`, and doc generation all discover patches dynamically — no hardcoded lists.
|
|
139
|
+
- **Idempotent**: `patch()` checks if `new` string is already present before replacing.
|
|
140
|
+
- **Non-destructive**: patches only modify the npx cache, never the npm registry package.
|
|
141
|
+
- **Platform-aware**: DM-003 is macOS-only (auto-skipped on Linux).
|
|
142
|
+
- **Sentinel-guarded**: `check-patches.sh` reads `sentinel` files from each patch directory to detect cache wipes and auto-reapply.
|
|
143
|
+
|
|
144
|
+
<a id="repository-structure"></a>
|
|
145
|
+
|
|
146
|
+
### Repository Structure
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
claude-flow-patch/
|
|
150
|
+
README.md # This file
|
|
151
|
+
CLAUDE.md # Claude Code instructions (defect workflow, policies)
|
|
152
|
+
AGENTS.md # Codex agent configuration
|
|
153
|
+
patch-all.sh # Apply all patches (globs patch/*/fix.py dynamically)
|
|
154
|
+
check-patches.sh # Sentinel: reads patch/*/sentinel files dynamically
|
|
155
|
+
repair-post-init.sh # Post-init helper repair
|
|
156
|
+
lib/
|
|
157
|
+
common.py # Shared patch()/patch_all() helpers + path variables
|
|
158
|
+
discover.mjs # Dynamic patch discovery — single source of truth
|
|
159
|
+
categories.json # Prefix-to-label mapping (e.g. HW → Headless Worker)
|
|
160
|
+
scripts/
|
|
161
|
+
preflight.mjs # Pre-commit sync: doc tables, versions, config
|
|
162
|
+
patch/
|
|
163
|
+
{NNN}-{PREFIX}-{NNN}-{slug}/ # NNN = 3-digit execution order
|
|
164
|
+
README.md # Defect report: title, severity, root cause, fix
|
|
165
|
+
fix.py # Idempotent patch script
|
|
166
|
+
fix.sh # Shell-based patch script (EM-002 only)
|
|
167
|
+
sentinel # Verification directives for check-patches.sh
|
|
168
|
+
(29 defect directories total)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
<a id="defect-index"></a>
|
|
172
|
+
|
|
173
|
+
## Defect Index
|
|
174
|
+
|
|
175
|
+
<!-- GENERATED:defect-index:begin -->
|
|
176
|
+
35 defects across 13 categories.
|
|
177
|
+
|
|
178
|
+
### CF -- Config & Doctor
|
|
179
|
+
|
|
180
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
181
|
+
|----|-------------|----------|--------------|
|
|
182
|
+
| [CF‑001](patch/010-CF-001-doctor-yaml/) | Doctor ignores YAML config files | Low | [#1141](https://github.com/ruvnet/claude-flow/issues/1141) |
|
|
183
|
+
| [CF‑002](patch/020-CF-002-config-export-yaml/) | Config export shows hardcoded defaults | Medium | [#1142](https://github.com/ruvnet/claude-flow/issues/1142) |
|
|
94
184
|
|
|
95
|
-
|
|
185
|
+
### DM -- Daemon & Workers
|
|
96
186
|
|
|
97
|
-
|
|
187
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
188
|
+
|----|-------------|----------|--------------|
|
|
189
|
+
| [DM‑001](patch/030-DM-001-daemon-log-zero/) | daemon.log always 0 bytes | Medium | [#1116](https://github.com/ruvnet/claude-flow/issues/1116) |
|
|
190
|
+
| [DM‑002](patch/040-DM-002-cpu-load-threshold/) | maxCpuLoad=2.0 blocks all workers on multi-core | Critical | [#1138](https://github.com/ruvnet/claude-flow/issues/1138) |
|
|
191
|
+
| [DM‑003](patch/050-DM-003-macos-freemem/) | macOS freemem() always ~0% — workers blocked | Critical | [#1077](https://github.com/ruvnet/claude-flow/issues/1077) |
|
|
192
|
+
| [DM‑004](patch/060-DM-004-preload-worker-stub/) | Preload worker stub + missing from defaults | Enhancement | [#1139](https://github.com/ruvnet/claude-flow/issues/1139) |
|
|
193
|
+
| [DM‑005](patch/070-DM-005-consolidation-worker-stub/) | Consolidation worker stub (no decay/rebuild) | Enhancement | [#1140](https://github.com/ruvnet/claude-flow/issues/1140) |
|
|
194
|
+
| [DM‑006](patch/300-DM-006-log-rotation/) | No log rotation — logs grow unbounded | Medium | [#1114](https://github.com/ruvnet/claude-flow/issues/1114) |
|
|
98
195
|
|
|
99
|
-
|
|
196
|
+
### EM -- Embeddings & HNSW
|
|
100
197
|
|
|
101
|
-
|
|
198
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
199
|
+
|----|-------------|----------|--------------|
|
|
200
|
+
| [EM‑001](patch/080-EM-001-embedding-ignores-config/) | Embedding system ignores project config (model + HNSW dims) | High | [#1143](https://github.com/ruvnet/claude-flow/issues/1143) |
|
|
201
|
+
| [EM‑002](patch/090-EM-002-transformers-cache-eacces/) | @xenova/transformers cache EACCES | Medium | [#1144](https://github.com/ruvnet/claude-flow/issues/1144) |
|
|
102
202
|
|
|
103
|
-
|
|
203
|
+
### GV -- Ghost Vectors
|
|
104
204
|
|
|
105
|
-
1
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
4. Validate with sentinel checks.
|
|
205
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
206
|
+
|----|-------------|----------|--------------|
|
|
207
|
+
| [GV‑001](patch/100-GV-001-hnsw-ghost-vectors/) | HNSW ghost vectors persist after memory delete | Medium | [#1122](https://github.com/ruvnet/claude-flow/issues/1122) |
|
|
109
208
|
|
|
110
|
-
|
|
209
|
+
### HK -- Hooks
|
|
111
210
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
211
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
212
|
+
|----|-------------|----------|--------------|
|
|
213
|
+
| [HK‑001](patch/110-HK-001-post-edit-file-path/) | post-edit hook records file_path as "unknown" | Medium | [#1155](https://github.com/ruvnet/claude-flow/issues/1155) |
|
|
214
|
+
| [HK‑002](patch/120-HK-002-hooks-tools-stub/) | MCP hook handlers are stubs that don't persist data | High | [#1058](https://github.com/ruvnet/claude-flow/issues/1058) |
|
|
215
|
+
| [HK‑003](patch/130-HK-003-metrics-hardcoded/) | hooks_metrics MCP handler returns hardcoded fake data | High | [#1158](https://github.com/ruvnet/claude-flow/issues/1158) |
|
|
216
|
+
| [HK‑004](patch/135-HK-004-respect-daemon-autostart/) | hooks_session-start ignores daemon.autoStart from settings.json | High | [#1175](https://github.com/ruvnet/claude-flow/issues/1175) |
|
|
217
|
+
| [HK‑005](patch/137-HK-005-daemon-pid-guard/) | Multiple MCP servers start independent in-process daemons | Critical | [#1171](https://github.com/ruvnet/claude-flow/issues/1171) |
|
|
218
|
+
|
|
219
|
+
### HW -- Headless Worker
|
|
220
|
+
|
|
221
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
222
|
+
|----|-------------|----------|--------------|
|
|
223
|
+
| [HW‑001](patch/140-HW-001-stdin-hang/) | Headless workers hang — stdin pipe never closed | Critical | [#1111](https://github.com/ruvnet/claude-flow/issues/1111) |
|
|
224
|
+
| [HW‑002](patch/150-HW-002-failures-swallowed/) | Headless failures silently swallowed as success | High | [#1112](https://github.com/ruvnet/claude-flow/issues/1112) |
|
|
225
|
+
| [HW‑003](patch/160-HW-003-aggressive-intervals/) | Worker scheduling intervals too aggressive + settings ignored | High | [#1113](https://github.com/ruvnet/claude-flow/issues/1113) |
|
|
226
|
+
| [HW‑004](patch/310-HW-004-runwithtimeout-orphan/) | runWithTimeout rejects but does not kill child process | Medium | [#1117](https://github.com/ruvnet/claude-flow/issues/1117) |
|
|
227
|
+
|
|
228
|
+
### IN -- Intelligence
|
|
229
|
+
|
|
230
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
231
|
+
|----|-------------|----------|--------------|
|
|
232
|
+
| [IN‑001](patch/170-IN-001-intelligence-stub/) | intelligence.cjs is a stub that doesn't actually learn | Critical | [#1154](https://github.com/ruvnet/claude-flow/issues/1154) |
|
|
233
|
+
|
|
234
|
+
### MM -- Memory Management
|
|
235
|
+
|
|
236
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
237
|
+
|----|-------------|----------|--------------|
|
|
238
|
+
| [MM‑001](patch/180-MM-001-memory-persist-path/) | Remove dead persistPath config option | Low | [#1152](https://github.com/ruvnet/claude-flow/issues/1152) |
|
|
239
|
+
|
|
240
|
+
### NS -- Memory Namespace
|
|
241
|
+
|
|
242
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
243
|
+
|----|-------------|----------|--------------|
|
|
244
|
+
| [NS‑001](patch/190-NS-001-discovery-default-namespace/) | Discovery ops default to wrong namespace | Critical | [#1123](https://github.com/ruvnet/claude-flow/issues/1123) |
|
|
245
|
+
| [NS‑002](patch/200-NS-002-targeted-require-namespace/) | Store/delete/retrieve fall back to 'default' + accept 'all' | Critical | [#581](https://github.com/ruvnet/claude-flow/issues/581) |
|
|
246
|
+
| [NS‑003](patch/210-NS-003-namespace-typo-pattern/) | Namespace typo 'pattern' vs 'patterns' | Medium | [#1136](https://github.com/ruvnet/claude-flow/issues/1136) |
|
|
247
|
+
|
|
248
|
+
### RS -- ruv-swarm
|
|
249
|
+
|
|
250
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
251
|
+
|----|-------------|----------|--------------|
|
|
252
|
+
| [RS‑001](patch/220-RS-001-better-sqlite3-node24/) | ruv-swarm MCP fails on Node 24 — better-sqlite3 missing native bindings | Critical | [ruv-FANN#185](https://github.com/ruvnet/ruv-FANN/issues/185) |
|
|
253
|
+
|
|
254
|
+
### RV -- RuVector Intelligence
|
|
255
|
+
|
|
256
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
257
|
+
|----|-------------|----------|--------------|
|
|
258
|
+
| [RV‑001](patch/230-RV-001-force-learn-tick/) | force-learn command calls intel.tick() which doesn't exist | Medium | [#1156](https://github.com/ruvnet/claude-flow/issues/1156) |
|
|
259
|
+
| [RV‑002](patch/240-RV-002-trajectory-load/) | activeTrajectories not loaded from saved file | High | [#1157](https://github.com/ruvnet/claude-flow/issues/1157) |
|
|
260
|
+
| [RV‑003](patch/250-RV-003-trajectory-stats-sync/) | trajectory-end does not update stats counters | Medium | [ruv-FANN#186](https://github.com/ruvnet/ruv-FANN/issues/186) |
|
|
261
|
+
|
|
262
|
+
### SG -- Settings Generator
|
|
263
|
+
|
|
264
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
265
|
+
|----|-------------|----------|--------------|
|
|
266
|
+
| [SG‑001](patch/260-SG-001-init-settings/) | Init generates invalid settings | High | [#1150](https://github.com/ruvnet/claude-flow/issues/1150) |
|
|
267
|
+
| [SG‑003](patch/270-SG-003-init-helpers-all-paths/) | Init missing helpers for --dual, --minimal, hooks, and upgrade paths | Critical | [#1169](https://github.com/ruvnet/claude-flow/issues/1169) |
|
|
268
|
+
| [SG‑004](patch/320-SG-004-wizard-parity/) | init wizard lacks parity with init | High | [#1181](https://github.com/ruvnet/claude-flow/issues/1181) |
|
|
269
|
+
| [SG‑005](patch/330-SG-005-start-all-subcommand/) | add 'start all' subcommand to start everything at once | Enhancement | [#1177](https://github.com/ruvnet/claude-flow/issues/1177) |
|
|
270
|
+
|
|
271
|
+
### UI -- Display & Cosmetic
|
|
272
|
+
|
|
273
|
+
| ID | Description <img width="500" height="1" /> | Severity | GitHub Issue |
|
|
274
|
+
|----|-------------|----------|--------------|
|
|
275
|
+
| [UI‑001](patch/280-UI-001-intelligence-stats-crash/) | intelligence stats crashes on .toFixed() | Critical | [#1145](https://github.com/ruvnet/claude-flow/issues/1145) |
|
|
276
|
+
| [UI‑002](patch/290-UI-002-neural-status-not-loaded/) | neural status shows "Not loaded" | Low | [#1146](https://github.com/ruvnet/claude-flow/issues/1146) |
|
|
277
|
+
<!-- GENERATED:defect-index:end -->
|
|
278
|
+
|
|
279
|
+
<a id="init-script-patches"></a>
|
|
280
|
+
|
|
281
|
+
## Init-Script Patches (Local Project Action Required)
|
|
282
|
+
|
|
283
|
+
Five patches target the **init/generator scripts** (`executor.js`, `settings-generator.js`, `helpers-generator.js`). These fix the code that *generates* your `.claude/` project files -- but applying patches does **not** update files already generated in your project. You must take one additional step.
|
|
284
|
+
|
|
285
|
+
### Affected Defects
|
|
286
|
+
|
|
287
|
+
| ID | Generator patched | Local file affected | Problem if not refreshed |
|
|
288
|
+
|----|-------------------|---------------------|--------------------------|
|
|
289
|
+
| IN-001 | `init/executor.js` | `.claude/helpers/intelligence.cjs` | 197-line stub: no PageRank, no graph, `feedback()` is a no-op, no learning |
|
|
290
|
+
| HK-001 | `init/helpers-generator.js` | `.claude/helpers/hook-handler.cjs` | Reads env vars instead of stdin JSON; post-edit logs `file: "unknown"` |
|
|
291
|
+
| SG-001 | `init/settings-generator.js` | `.claude/settings.json` | May contain invalid hook events, broad permissions, relative paths |
|
|
292
|
+
| SG-002 | `init/executor.js` | `.claude/helpers/*.js` / `*.cjs` | Missing .js/.cjs compat copies; `hook-handler.cjs` require() calls fail silently |
|
|
293
|
+
| MM-001 | `init/executor.js` | `.claude-flow/config.yaml` | Misleading `persistPath` setting that nothing reads |
|
|
294
|
+
|
|
295
|
+
### How to Fix
|
|
296
|
+
|
|
297
|
+
**Option A: Run `repair`** (recommended)
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
npx --yes @sparkleideas/claude-flow-patch --global
|
|
301
|
+
npx --yes @sparkleideas/claude-flow-patch repair --target .
|
|
302
|
+
npx --yes @sparkleideas/claude-flow-patch apply SG-002 # apply a single patch
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
This copies patched helper files into your project and creates any missing .js/.cjs compat copies.
|
|
306
|
+
|
|
307
|
+
**Option B: Copy full helpers from the package manually**
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npx --yes @sparkleideas/claude-flow-patch --global
|
|
311
|
+
SRC=$(find ~/.npm/_npx -path '*/@claude-flow/cli/.claude/helpers' -type d 2>/dev/null | head -1)
|
|
312
|
+
for f in intelligence.cjs hook-handler.cjs session.js learning-service.mjs metrics-db.mjs statusline.cjs; do
|
|
313
|
+
[ -f "$SRC/$f" ] && cp "$SRC/$f" .claude/helpers/ && echo "Copied: $f"
|
|
314
|
+
done
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Option C: Re-run init upgrade** (regenerates from patched scripts)
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
npx --yes @sparkleideas/claude-flow-patch --global
|
|
321
|
+
npx @claude-flow/cli@latest init upgrade --force
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Caution: Option C may overwrite other customizations in `.claude/`.
|
|
325
|
+
|
|
326
|
+
### Why This Happens
|
|
327
|
+
|
|
328
|
+
These patches fix the **generator functions** inside the npm package (e.g., `generateIntelligenceStub()` in `executor.js`). When the generator runs via `claude-flow init`, it produces the project files in `.claude/helpers/`. If your project was initialized *before* patches were applied, the stubs are already on disk. Patches only modify the npm package source -- they do not touch files already generated in your project.
|
|
329
|
+
|
|
330
|
+
Additionally, `init upgrade` only force-overwrites 3 "critical" helpers (`auto-memory-hook.mjs`, `hook-handler.cjs`, `intelligence.cjs`). The other 30+ helper files (shell scripts for daemon management, health monitoring, security scanning, swarm hooks, etc.) are only copied on fresh `init`, not on upgrade. If these are missing, use Option A above.
|
|
331
|
+
|
|
332
|
+
<a id="compatibility"></a>
|
|
116
333
|
|
|
117
334
|
## Compatibility
|
|
118
335
|
|
|
119
|
-
- Tested
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
|
|
336
|
+
- Tested against `@claude-flow/cli@3.1.0-alpha.41` and `ruv-swarm@1.0.20`
|
|
337
|
+
- Requires Python 3.6+ and Bash
|
|
338
|
+
- Works on Linux and macOS (DM-003 is macOS-only, auto-skipped on Linux)
|
|
339
|
+
|
|
340
|
+
<a id="links"></a>
|
|
123
341
|
|
|
124
342
|
## Links
|
|
125
343
|
|
|
126
344
|
- Homepage: https://sparklingideas.co.uk/claude-flow/patch
|
|
345
|
+
- Package: https://www.npmjs.com/package/@sparkleideas/claude-flow-patch
|
|
127
346
|
- GitHub: https://github.com/sparkling/claude-flow-patch
|
|
128
347
|
- Issues: https://github.com/sparkling/claude-flow-patch/issues
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT
|
package/lib/common.py
CHANGED
|
@@ -83,6 +83,7 @@ HELPERS_GEN = init + "/helpers-generator.js" if init else ""
|
|
|
83
83
|
EXECUTOR = init + "/executor.js" if init else ""
|
|
84
84
|
TYPES = init + "/types.js" if init else ""
|
|
85
85
|
INIT_CMD = commands + "/init.js" if commands else ""
|
|
86
|
+
START_CMD = commands + "/start.js" if commands else ""
|
|
86
87
|
|
|
87
88
|
# Source helpers (shipped with package, copied by writeHelpers when source dir found)
|
|
88
89
|
_pkg_root = os.path.dirname(os.path.dirname(base)) if base else ""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sparkleideas/claude-flow-patch",
|
|
3
|
-
"version": "3.1.0-alpha.44.patch.
|
|
3
|
+
"version": "3.1.0-alpha.44.patch.8",
|
|
4
4
|
"description": "Patch toolkit for @claude-flow/cli init/runtime defects with verify and post-init repair commands",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"preflight": "node scripts/preflight.mjs",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# HK-005: Multiple MCP servers start independent in-process daemons
|
|
2
|
+
**Severity**: Critical
|
|
3
|
+
**GitHub**: [#1171](https://github.com/ruvnet/claude-flow/issues/1171)
|
|
4
|
+
## Root Cause
|
|
5
|
+
`hooks_session-start` calls `startDaemon()` (worker-daemon.js) which creates an in-process `WorkerDaemon` singleton per Node.js process. Each MCP server is a separate process with its own singleton — no cross-process coordination. The CLI background daemon path (`daemon.js`) has PID-file coordination but the MCP hook path bypasses it entirely. Result: N MCP servers per project = N daemon instances = N × 6 workers.
|
|
6
|
+
## Fix
|
|
7
|
+
Add PID-file guard to the MCP hook path using `.claude-flow/daemon.pid` (same file the CLI path uses). Before calling `startDaemon()`, check PID file: if a different process owns it and is alive, skip (reuse). If the PID is our own process or stale, proceed and overwrite. No cleanup on session-end — stale PIDs self-heal via `kill(pid, 0)` on next start. The PID file becomes a universal one-daemon-per-project lock across both MCP and CLI paths.
|
|
8
|
+
## Files Patched
|
|
9
|
+
- mcp-tools/hooks-tools.js
|
|
10
|
+
## Ops
|
|
11
|
+
2 ops in fix.py
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# HK-005: Multiple MCP servers start independent in-process daemons
|
|
2
|
+
# No cross-process coordination on the hooks_session-start path.
|
|
3
|
+
# GitHub: #1171
|
|
4
|
+
|
|
5
|
+
# Op 1: Add PID-file guard before startDaemon()
|
|
6
|
+
patch("HK-005a: cross-process daemon PID guard",
|
|
7
|
+
MCP_HOOKS,
|
|
8
|
+
""" // Auto-start daemon if enabled
|
|
9
|
+
let daemonStatus = { started: false };
|
|
10
|
+
if (shouldStartDaemon) {
|
|
11
|
+
try {
|
|
12
|
+
// Dynamic import to avoid circular dependencies
|
|
13
|
+
const { startDaemon } = await import('../services/worker-daemon.js');
|
|
14
|
+
const daemon = await startDaemon(process.cwd());""",
|
|
15
|
+
""" // Auto-start daemon if enabled
|
|
16
|
+
let daemonStatus = { started: false };
|
|
17
|
+
if (shouldStartDaemon) {
|
|
18
|
+
try {
|
|
19
|
+
// HK-005: PID-file guard — one daemon per project across processes
|
|
20
|
+
const _pidDir = join(process.cwd(), '.claude-flow');
|
|
21
|
+
const _pidPath = join(_pidDir, 'daemon.pid');
|
|
22
|
+
let _skipDaemon = false;
|
|
23
|
+
try {
|
|
24
|
+
const _xPid = parseInt(readFileSync(_pidPath, 'utf-8').trim(), 10);
|
|
25
|
+
if (!isNaN(_xPid) && _xPid !== process.pid) {
|
|
26
|
+
try { process.kill(_xPid, 0); _skipDaemon = true; daemonStatus = { started: true, pid: _xPid, reused: true }; }
|
|
27
|
+
catch { /* stale PID from dead process — proceed */ }
|
|
28
|
+
}
|
|
29
|
+
} catch { /* no PID file — proceed */ }
|
|
30
|
+
if (!_skipDaemon) {
|
|
31
|
+
// Dynamic import to avoid circular dependencies
|
|
32
|
+
const { startDaemon } = await import('../services/worker-daemon.js');
|
|
33
|
+
const daemon = await startDaemon(process.cwd());""")
|
|
34
|
+
|
|
35
|
+
# Op 2: Write PID after successful start + close guard block
|
|
36
|
+
patch("HK-005b: write PID after daemon start",
|
|
37
|
+
MCP_HOOKS,
|
|
38
|
+
""" const status = daemon.getStatus();
|
|
39
|
+
daemonStatus = {
|
|
40
|
+
started: true,
|
|
41
|
+
pid: status.pid,
|
|
42
|
+
};""",
|
|
43
|
+
""" const status = daemon.getStatus();
|
|
44
|
+
// HK-005: Write PID so other processes detect this daemon
|
|
45
|
+
try {
|
|
46
|
+
if (!existsSync(_pidDir)) { mkdirSync(_pidDir, { recursive: true }); }
|
|
47
|
+
writeFileSync(_pidPath, String(status.pid || process.pid));
|
|
48
|
+
} catch { /* best-effort */ }
|
|
49
|
+
daemonStatus = {
|
|
50
|
+
started: true,
|
|
51
|
+
pid: status.pid,
|
|
52
|
+
};
|
|
53
|
+
} // end HK-005 guard""")
|
|
@@ -0,0 +1,32 @@
|
|
|
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 conceptually "init with interactive value selection" but behaves as a
|
|
13
|
+
completely separate command.
|
|
14
|
+
|
|
15
|
+
## Fix
|
|
16
|
+
|
|
17
|
+
Four ops bring the wizard to full parity with `init`:
|
|
18
|
+
|
|
19
|
+
| Op | What it does |
|
|
20
|
+
|----|-------------|
|
|
21
|
+
| SG-004a | Adds the already-initialized guard before prompts + passes `--force` to options |
|
|
22
|
+
| SG-004b | Adds `--codex`/`--dual` handling after executeInit succeeds |
|
|
23
|
+
| SG-004c | Adds `--start-all`/`--start-daemon` service startup + "Next steps" hints |
|
|
24
|
+
| SG-004d | Fixes catch block — catches errors cleanly instead of re-throwing |
|
|
25
|
+
|
|
26
|
+
## Files Patched
|
|
27
|
+
|
|
28
|
+
- `commands/init.js`
|
|
29
|
+
|
|
30
|
+
## Ops
|
|
31
|
+
|
|
32
|
+
4 ops in fix.py
|
|
@@ -0,0 +1,133 @@
|
|
|
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.
|
|
7
|
+
#
|
|
8
|
+
# 4 ops: init-guard + force (a), codex/dual (b), start-all + next-steps (c),
|
|
9
|
+
# catch-block error handling (d)
|
|
10
|
+
|
|
11
|
+
# Op 1: Add already-initialized guard + pass --force to executeInit options
|
|
12
|
+
patch("SG-004a: wizard init-guard + --force",
|
|
13
|
+
INIT_CMD,
|
|
14
|
+
""" try {
|
|
15
|
+
// Start with base options
|
|
16
|
+
const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd };""",
|
|
17
|
+
""" try {
|
|
18
|
+
// SG-004: Check if already initialized (respects --force)
|
|
19
|
+
const force = ctx.flags.force;
|
|
20
|
+
const initialized = isInitialized(ctx.cwd);
|
|
21
|
+
const hasExisting = initialized.claude || initialized.claudeFlow;
|
|
22
|
+
if (hasExisting && !force) {
|
|
23
|
+
output.printWarning('Claude Flow appears to be already initialized');
|
|
24
|
+
if (initialized.claude) output.printInfo(' Found: .claude/settings.json');
|
|
25
|
+
if (initialized.claudeFlow) output.printInfo(' Found: .claude-flow/config.yaml');
|
|
26
|
+
output.printInfo('Use --force to reinitialize');
|
|
27
|
+
const proceed = await confirm({
|
|
28
|
+
message: 'Do you want to reinitialize? This will overwrite existing configuration.',
|
|
29
|
+
default: false,
|
|
30
|
+
});
|
|
31
|
+
if (!proceed) {
|
|
32
|
+
return { success: true, message: 'Wizard cancelled' };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Start with base options
|
|
36
|
+
const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd, force: ctx.flags.force };""")
|
|
37
|
+
|
|
38
|
+
# Op 2: Add --codex / --dual handling after executeInit succeeds
|
|
39
|
+
patch("SG-004b: wizard --codex/--dual support",
|
|
40
|
+
INIT_CMD,
|
|
41
|
+
""" spinner.succeed('Setup complete!');
|
|
42
|
+
// Initialize embeddings if enabled
|
|
43
|
+
let embeddingsInitialized = false;""",
|
|
44
|
+
""" spinner.succeed('Setup complete!');
|
|
45
|
+
// SG-004: Respect --codex / --dual in wizard
|
|
46
|
+
const codexMode = ctx.flags.codex;
|
|
47
|
+
const dualMode = ctx.flags.dual;
|
|
48
|
+
if (codexMode || dualMode) {
|
|
49
|
+
try {
|
|
50
|
+
output.writeln(output.dim(' Initializing Codex integration...'));
|
|
51
|
+
await initCodexAction(ctx, { codexMode, dualMode, force: ctx.flags.force, minimal: false, full: false });
|
|
52
|
+
} catch (err) {
|
|
53
|
+
output.printWarning(`Codex initialization: ${err instanceof Error ? err.message : String(err)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Initialize embeddings if enabled
|
|
57
|
+
let embeddingsInitialized = false;""")
|
|
58
|
+
|
|
59
|
+
# Op 3: Add --start-all / --start-daemon + "Next steps" hints before final return
|
|
60
|
+
patch("SG-004c: wizard --start-all + next-steps",
|
|
61
|
+
INIT_CMD,
|
|
62
|
+
""" });
|
|
63
|
+
return { success: true, data: result };
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof Error && error.message === 'User cancelled') {""",
|
|
67
|
+
""" });
|
|
68
|
+
// SG-004: Respect --start-all / --start-daemon in wizard
|
|
69
|
+
const startAll = ctx.flags['start-all'] || ctx.flags.startAll;
|
|
70
|
+
const startDaemon = ctx.flags['start-daemon'] || ctx.flags.startDaemon || startAll;
|
|
71
|
+
if (startDaemon || startAll) {
|
|
72
|
+
output.writeln();
|
|
73
|
+
output.printInfo('Starting services...');
|
|
74
|
+
const { execSync } = await import('child_process');
|
|
75
|
+
if (startAll) {
|
|
76
|
+
try {
|
|
77
|
+
output.writeln(output.dim(' Initializing memory database...'));
|
|
78
|
+
execSync('npx @claude-flow/cli@latest memory init 2>/dev/null', {
|
|
79
|
+
stdio: 'pipe', cwd: ctx.cwd, timeout: 30000
|
|
80
|
+
});
|
|
81
|
+
output.writeln(output.success(' \\u2713 Memory initialized'));
|
|
82
|
+
} catch { output.writeln(output.dim(' Memory database already exists')); }
|
|
83
|
+
}
|
|
84
|
+
if (startDaemon) {
|
|
85
|
+
try {
|
|
86
|
+
output.writeln(output.dim(' Starting daemon...'));
|
|
87
|
+
execSync('npx @claude-flow/cli@latest daemon start 2>/dev/null &', {
|
|
88
|
+
stdio: 'pipe', cwd: ctx.cwd, timeout: 10000
|
|
89
|
+
});
|
|
90
|
+
output.writeln(output.success(' \\u2713 Daemon started'));
|
|
91
|
+
} catch { output.writeln(output.warning(' Daemon may already be running')); }
|
|
92
|
+
}
|
|
93
|
+
if (startAll) {
|
|
94
|
+
try {
|
|
95
|
+
output.writeln(output.dim(' Initializing swarm...'));
|
|
96
|
+
execSync('npx @claude-flow/cli@latest swarm init --topology hierarchical 2>/dev/null', {
|
|
97
|
+
stdio: 'pipe', cwd: ctx.cwd, timeout: 30000
|
|
98
|
+
});
|
|
99
|
+
output.writeln(output.success(' \\u2713 Swarm initialized'));
|
|
100
|
+
} catch { output.writeln(output.dim(' Swarm initialization skipped')); }
|
|
101
|
+
}
|
|
102
|
+
output.writeln();
|
|
103
|
+
output.printSuccess('All services started');
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
output.writeln(output.bold('Next steps:'));
|
|
107
|
+
output.printList([
|
|
108
|
+
`Run ${output.highlight('claude-flow daemon start')} to start background workers`,
|
|
109
|
+
`Run ${output.highlight('claude-flow memory init')} to initialize memory database`,
|
|
110
|
+
`Run ${output.highlight('claude-flow swarm init')} to initialize a swarm`,
|
|
111
|
+
`Or re-run with ${output.highlight('--start-all')} to do all of the above`,
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
return { success: true, data: result };
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
if (error instanceof Error && error.message === 'User cancelled') {""")
|
|
118
|
+
|
|
119
|
+
# Op 4: Fix wizard catch block — re-throws instead of clean error message
|
|
120
|
+
# spinner is declared inside the try block so we can't call spinner.fail() here
|
|
121
|
+
patch("SG-004d: wizard catch block handles errors cleanly",
|
|
122
|
+
INIT_CMD,
|
|
123
|
+
""" if (error instanceof Error && error.message === 'User cancelled') {
|
|
124
|
+
output.printInfo('Setup cancelled');
|
|
125
|
+
return { success: true };
|
|
126
|
+
}
|
|
127
|
+
throw error;""",
|
|
128
|
+
""" if (error instanceof Error && error.message === 'User cancelled') {
|
|
129
|
+
output.printInfo('Setup cancelled');
|
|
130
|
+
return { success: true };
|
|
131
|
+
}
|
|
132
|
+
output.printError(`Failed to initialize: ${error instanceof Error ? error.message : String(error)}`);
|
|
133
|
+
return { success: false, exitCode: 1 };""")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
grep "SG-004" commands/init.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
|