@sparkleideas/claude-flow-patch 3.1.0-alpha.44.patch.3

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 (107) hide show
  1. package/AGENTS.md +162 -0
  2. package/CLAUDE.md +458 -0
  3. package/README.md +306 -0
  4. package/bin/claude-flow-patch.mjs +148 -0
  5. package/check-patches.sh +176 -0
  6. package/lib/categories.json +15 -0
  7. package/lib/common.py +92 -0
  8. package/lib/discover.mjs +181 -0
  9. package/package.json +85 -0
  10. package/patch/010-CF-001-doctor-yaml/README.md +11 -0
  11. package/patch/010-CF-001-doctor-yaml/fix.py +20 -0
  12. package/patch/010-CF-001-doctor-yaml/sentinel +1 -0
  13. package/patch/020-CF-002-config-export-yaml/README.md +11 -0
  14. package/patch/020-CF-002-config-export-yaml/fix.py +130 -0
  15. package/patch/020-CF-002-config-export-yaml/sentinel +1 -0
  16. package/patch/030-DM-001-daemon-log-zero/README.md +12 -0
  17. package/patch/030-DM-001-daemon-log-zero/fix.py +37 -0
  18. package/patch/030-DM-001-daemon-log-zero/sentinel +1 -0
  19. package/patch/040-DM-002-cpu-load-threshold/README.md +11 -0
  20. package/patch/040-DM-002-cpu-load-threshold/fix.py +6 -0
  21. package/patch/040-DM-002-cpu-load-threshold/sentinel +1 -0
  22. package/patch/050-DM-003-macos-freemem/README.md +11 -0
  23. package/patch/050-DM-003-macos-freemem/fix.py +7 -0
  24. package/patch/050-DM-003-macos-freemem/sentinel +1 -0
  25. package/patch/060-DM-004-preload-worker-stub/README.md +11 -0
  26. package/patch/060-DM-004-preload-worker-stub/fix.py +34 -0
  27. package/patch/060-DM-004-preload-worker-stub/sentinel +1 -0
  28. package/patch/070-DM-005-consolidation-worker-stub/README.md +11 -0
  29. package/patch/070-DM-005-consolidation-worker-stub/fix.py +46 -0
  30. package/patch/070-DM-005-consolidation-worker-stub/sentinel +1 -0
  31. package/patch/080-EM-001-embedding-ignores-config/README.md +11 -0
  32. package/patch/080-EM-001-embedding-ignores-config/fix.py +111 -0
  33. package/patch/080-EM-001-embedding-ignores-config/sentinel +1 -0
  34. package/patch/090-EM-002-transformers-cache-eacces/README.md +11 -0
  35. package/patch/090-EM-002-transformers-cache-eacces/fix.sh +12 -0
  36. package/patch/090-EM-002-transformers-cache-eacces/sentinel +1 -0
  37. package/patch/100-GV-001-hnsw-ghost-vectors/README.md +11 -0
  38. package/patch/100-GV-001-hnsw-ghost-vectors/fix.py +34 -0
  39. package/patch/100-GV-001-hnsw-ghost-vectors/sentinel +1 -0
  40. package/patch/110-HK-001-post-edit-file-path/README.md +44 -0
  41. package/patch/110-HK-001-post-edit-file-path/fix.py +23 -0
  42. package/patch/110-HK-001-post-edit-file-path/sentinel +1 -0
  43. package/patch/120-HK-002-hooks-tools-stub/README.md +36 -0
  44. package/patch/120-HK-002-hooks-tools-stub/fix.py +155 -0
  45. package/patch/120-HK-002-hooks-tools-stub/sentinel +1 -0
  46. package/patch/130-HK-003-metrics-hardcoded/README.md +30 -0
  47. package/patch/130-HK-003-metrics-hardcoded/fix.py +82 -0
  48. package/patch/130-HK-003-metrics-hardcoded/sentinel +1 -0
  49. package/patch/140-HW-001-stdin-hang/README.md +11 -0
  50. package/patch/140-HW-001-stdin-hang/fix.py +6 -0
  51. package/patch/140-HW-001-stdin-hang/sentinel +1 -0
  52. package/patch/150-HW-002-failures-swallowed/README.md +11 -0
  53. package/patch/150-HW-002-failures-swallowed/fix.py +42 -0
  54. package/patch/150-HW-002-failures-swallowed/sentinel +1 -0
  55. package/patch/160-HW-003-aggressive-intervals/README.md +11 -0
  56. package/patch/160-HW-003-aggressive-intervals/fix.py +16 -0
  57. package/patch/160-HW-003-aggressive-intervals/sentinel +1 -0
  58. package/patch/170-IN-001-intelligence-stub/README.md +64 -0
  59. package/patch/170-IN-001-intelligence-stub/fix.py +70 -0
  60. package/patch/170-IN-001-intelligence-stub/sentinel +1 -0
  61. package/patch/180-MM-001-memory-persist-path/README.md +27 -0
  62. package/patch/180-MM-001-memory-persist-path/fix.py +54 -0
  63. package/patch/180-MM-001-memory-persist-path/sentinel +1 -0
  64. package/patch/190-NS-001-discovery-default-namespace/README.md +16 -0
  65. package/patch/190-NS-001-discovery-default-namespace/fix.py +68 -0
  66. package/patch/190-NS-001-discovery-default-namespace/sentinel +2 -0
  67. package/patch/200-NS-002-targeted-require-namespace/README.md +19 -0
  68. package/patch/200-NS-002-targeted-require-namespace/fix.py +158 -0
  69. package/patch/200-NS-002-targeted-require-namespace/sentinel +2 -0
  70. package/patch/210-NS-003-namespace-typo-pattern/README.md +15 -0
  71. package/patch/210-NS-003-namespace-typo-pattern/fix.py +23 -0
  72. package/patch/210-NS-003-namespace-typo-pattern/sentinel +1 -0
  73. package/patch/220-RS-001-better-sqlite3-node24/README.md +54 -0
  74. package/patch/220-RS-001-better-sqlite3-node24/fix.py +22 -0
  75. package/patch/220-RS-001-better-sqlite3-node24/rebuild.sh +31 -0
  76. package/patch/220-RS-001-better-sqlite3-node24/sentinel +2 -0
  77. package/patch/230-RV-001-force-learn-tick/README.md +31 -0
  78. package/patch/230-RV-001-force-learn-tick/fix.py +14 -0
  79. package/patch/230-RV-001-force-learn-tick/sentinel +2 -0
  80. package/patch/240-RV-002-trajectory-load/README.md +28 -0
  81. package/patch/240-RV-002-trajectory-load/fix.py +14 -0
  82. package/patch/240-RV-002-trajectory-load/sentinel +2 -0
  83. package/patch/250-RV-003-trajectory-stats-sync/README.md +31 -0
  84. package/patch/250-RV-003-trajectory-stats-sync/fix.py +18 -0
  85. package/patch/250-RV-003-trajectory-stats-sync/sentinel +2 -0
  86. package/patch/260-SG-001-init-settings/README.md +29 -0
  87. package/patch/260-SG-001-init-settings/fix.py +143 -0
  88. package/patch/260-SG-001-init-settings/sentinel +4 -0
  89. package/patch/270-SG-003-init-helpers-all-paths/README.md +60 -0
  90. package/patch/270-SG-003-init-helpers-all-paths/fix.py +164 -0
  91. package/patch/270-SG-003-init-helpers-all-paths/sentinel +3 -0
  92. package/patch/280-UI-001-intelligence-stats-crash/README.md +11 -0
  93. package/patch/280-UI-001-intelligence-stats-crash/fix.py +57 -0
  94. package/patch/280-UI-001-intelligence-stats-crash/sentinel +1 -0
  95. package/patch/290-UI-002-neural-status-not-loaded/README.md +11 -0
  96. package/patch/290-UI-002-neural-status-not-loaded/fix.py +19 -0
  97. package/patch/290-UI-002-neural-status-not-loaded/sentinel +1 -0
  98. package/patch/300-DM-006-log-rotation/README.md +11 -0
  99. package/patch/300-DM-006-log-rotation/fix.py +58 -0
  100. package/patch/300-DM-006-log-rotation/sentinel +1 -0
  101. package/patch/310-HW-004-runwithtimeout-orphan/README.md +11 -0
  102. package/patch/310-HW-004-runwithtimeout-orphan/fix.py +10 -0
  103. package/patch/310-HW-004-runwithtimeout-orphan/sentinel +1 -0
  104. package/patch-all.sh +203 -0
  105. package/repair-post-init.sh +245 -0
  106. package/scripts/update-docs.mjs +208 -0
  107. package/scripts/upstream-log.mjs +257 -0
package/README.md ADDED
@@ -0,0 +1,306 @@
1
+ # @sparkleideas/claude-flow-patch
2
+
3
+ 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**.
4
+
5
+ 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.
6
+
7
+ ## Quick Start
8
+
9
+ **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:
10
+
11
+ ```bash
12
+ # 1. Patch first -- fixes the init generators
13
+ npx --yes @sparkleideas/claude-flow-patch --global
14
+
15
+ # 2. Then init (or re-init if already initialized)
16
+ npx @claude-flow/cli@latest init # fresh project
17
+ npx @claude-flow/cli@latest init upgrade # existing project
18
+
19
+ # 3. Verify
20
+ npx --yes @sparkleideas/claude-flow-patch check
21
+ ```
22
+
23
+ If you already initialized before patching:
24
+
25
+ ```bash
26
+ npx --yes @sparkleideas/claude-flow-patch repair --target /path/to/project
27
+ ```
28
+
29
+ ### Target Options
30
+
31
+ ```bash
32
+ npx --yes @sparkleideas/claude-flow-patch # global npx cache (default)
33
+ npx --yes @sparkleideas/claude-flow-patch --global # explicit global
34
+ npx --yes @sparkleideas/claude-flow-patch --target ~/my-project # project's node_modules
35
+ npx --yes @sparkleideas/claude-flow-patch --global --target ~/my-project # both
36
+ ```
37
+
38
+ `npx @claude-flow/cli` uses local `node_modules` if present, otherwise the global npx cache. Use `--target` to patch a project's local install.
39
+
40
+ ## CLI Commands
41
+
42
+ | Command | Purpose |
43
+ |---|---|
44
+ | `claude-flow-patch [--global] [--target <dir>]` | Apply all patches (default: `--global`) |
45
+ | `claude-flow-patch apply <ID>` | Apply a single patch by defect ID (e.g. `SG-002`) |
46
+ | `claude-flow-patch check` | Verify patch sentinels and auto-detect drift |
47
+ | `claude-flow-patch repair --target <dir> [--source auto\|local\|global] [--dry-run]` | Rehydrate `.claude/helpers` in projects initialized before patching |
48
+
49
+ ## How It Works
50
+
51
+ 1. `patch-all.sh` locates the `@claude-flow/cli` dist files in the npm/npx cache
52
+ 2. Globs `patch/*/fix.py` (numeric prefixes on directories ensure correct execution order)
53
+ 3. Concatenates `lib/common.py` with each `fix.py` and runs as a single Python process
54
+ 4. Each patch is idempotent: skips if already applied, warns if source changed
55
+
56
+ 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.
57
+
58
+ ### Sentinel Files
59
+
60
+ Each patch directory contains a `sentinel` file that declares how to verify the patch is applied:
61
+
62
+ ```
63
+ grep "pattern to find" relative/path/to/file.js
64
+ absent "pattern that should NOT exist" relative/path.js
65
+ none
66
+ package: ruvector
67
+ ```
68
+
69
+ | Directive | Meaning |
70
+ |-----------|---------|
71
+ | `grep "..." file` | Pass if pattern is found in file (standard check) |
72
+ | `absent "..." file` | Pass if pattern is **not** found (removal check) |
73
+ | `none` | No sentinel — skip verification |
74
+ | `package: X` | Target package (default: `@claude-flow/cli`). Skipped if package not installed |
75
+
76
+ `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.
77
+
78
+ ### Target Packages
79
+
80
+ | Package | Version | Location | Env var |
81
+ |---------|---------|----------|---------|
82
+ | `@claude-flow/cli` | `3.1.0-alpha.41` | `~/.npm/_npx/*/node_modules/@claude-flow/cli/dist/src/` | `BASE` |
83
+ | `ruvector` | (bundled) | `~/.npm/_npx/*/node_modules/ruvector/bin/cli.js` | `RUVECTOR_CLI` |
84
+ | `ruv-swarm` | `1.0.20` | `~/.npm/_npx/*/node_modules/ruv-swarm/` | (found via glob) |
85
+
86
+ `BASE` is set by `patch-all.sh`. All path variables in `lib/common.py` derive from it.
87
+ `RUVECTOR_CLI` is set by `patch-all.sh` to the ruvector CLI entry point.
88
+ RS-001 locates its own target via `find`.
89
+
90
+ ### Dependency Order
91
+
92
+ Execution order is controlled by 3-digit numeric prefixes on directory names (e.g. `010-CF-001-*`,
93
+ `170-IN-001-*`). `patch-all.sh` globs `patch/*/fix.py`, which sorts lexicographically — numeric
94
+ prefixes guarantee correct order.
95
+
96
+ Two dependency chains exist:
97
+
98
+ | Chain | Directories | Reason |
99
+ |-------|-------------|--------|
100
+ | IN-001 -> SG-003 | `170-IN-001-*` before `270-SG-003-*` | SG-003's patch targets code introduced by IN-001 |
101
+ | NS-001 -> NS-002 -> NS-003 | `190-NS-001-*` before `200-NS-002-*` before `210-NS-003-*` | Sequential namespace fixes |
102
+
103
+ All other patches are independent.
104
+
105
+ ### Key Design Decisions
106
+
107
+ - **Zero-maintenance discovery**: `patch-all.sh`, `check-patches.sh`, and doc generation all discover patches dynamically — no hardcoded lists.
108
+ - **Idempotent**: `patch()` checks if `new` string is already present before replacing.
109
+ - **Non-destructive**: patches only modify the npx cache, never the npm registry package.
110
+ - **Platform-aware**: DM-003 is macOS-only (auto-skipped on Linux).
111
+ - **Sentinel-guarded**: `check-patches.sh` reads `sentinel` files from each patch directory to detect cache wipes and auto-reapply.
112
+
113
+ ### Repository Structure
114
+
115
+ ```
116
+ claude-flow-patch/
117
+ README.md # This file
118
+ CLAUDE.md # Claude Code instructions (defect workflow, policies)
119
+ AGENTS.md # Codex agent configuration
120
+ patch-all.sh # Apply all patches (globs patch/*/fix.py dynamically)
121
+ check-patches.sh # Sentinel: reads patch/*/sentinel files dynamically
122
+ repair-post-init.sh # Post-init helper repair
123
+ lib/
124
+ common.py # Shared patch()/patch_all() helpers + path variables
125
+ discover.mjs # Dynamic patch discovery — single source of truth
126
+ categories.json # Prefix-to-label mapping (e.g. HW → Headless Worker)
127
+ scripts/
128
+ update-docs.mjs # Regenerate doc tables from discover() output
129
+ patch/
130
+ {NNN}-{PREFIX}-{NNN}-{slug}/ # NNN = 3-digit execution order
131
+ README.md # Defect report: title, severity, root cause, fix
132
+ fix.py # Idempotent patch script
133
+ fix.sh # Shell-based patch script (EM-002 only)
134
+ sentinel # Verification directives for check-patches.sh
135
+ (29 defect directories total)
136
+ ```
137
+
138
+ ## Defect Index
139
+
140
+ <!-- GENERATED:defect-index:begin -->
141
+ 31 defects across 13 categories.
142
+
143
+ ### CF -- Config & Doctor
144
+
145
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
146
+ |----|-------------|----------|--------------|
147
+ | [CF&#8209;001](patch/010-CF-001-doctor-yaml/) | Doctor ignores YAML config files | Low | [#1141](https://github.com/ruvnet/claude-flow/issues/1141) |
148
+ | [CF&#8209;002](patch/020-CF-002-config-export-yaml/) | Config export shows hardcoded defaults | Medium | [#1142](https://github.com/ruvnet/claude-flow/issues/1142) |
149
+
150
+ ### DM -- Daemon & Workers
151
+
152
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
153
+ |----|-------------|----------|--------------|
154
+ | [DM&#8209;001](patch/030-DM-001-daemon-log-zero/) | daemon.log always 0 bytes | Medium | [#1116](https://github.com/ruvnet/claude-flow/issues/1116) |
155
+ | [DM&#8209;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) |
156
+ | [DM&#8209;003](patch/050-DM-003-macos-freemem/) | macOS freemem() always ~0% — workers blocked | Critical | [#1077](https://github.com/ruvnet/claude-flow/issues/1077) |
157
+ | [DM&#8209;004](patch/060-DM-004-preload-worker-stub/) | Preload worker stub + missing from defaults | Enhancement | [#1139](https://github.com/ruvnet/claude-flow/issues/1139) |
158
+ | [DM&#8209;005](patch/070-DM-005-consolidation-worker-stub/) | Consolidation worker stub (no decay/rebuild) | Enhancement | [#1140](https://github.com/ruvnet/claude-flow/issues/1140) |
159
+ | [DM&#8209;006](patch/300-DM-006-log-rotation/) | No log rotation — headless execution logs grow unbounded | Medium | [#1114](https://github.com/ruvnet/claude-flow/issues/1114) |
160
+
161
+ ### EM -- Embeddings & HNSW
162
+
163
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
164
+ |----|-------------|----------|--------------|
165
+ | [EM&#8209;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) |
166
+ | [EM&#8209;002](patch/090-EM-002-transformers-cache-eacces/) | @xenova/transformers cache EACCES | Medium | [#1144](https://github.com/ruvnet/claude-flow/issues/1144) |
167
+
168
+ ### GV -- Ghost Vectors
169
+
170
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
171
+ |----|-------------|----------|--------------|
172
+ | [GV&#8209;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) |
173
+
174
+ ### HK -- Hooks
175
+
176
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
177
+ |----|-------------|----------|--------------|
178
+ | [HK&#8209;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) |
179
+ | [HK&#8209;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) |
180
+ | [HK&#8209;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) |
181
+
182
+ ### HW -- Headless Worker
183
+
184
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
185
+ |----|-------------|----------|--------------|
186
+ | [HW&#8209;001](patch/140-HW-001-stdin-hang/) | Headless workers hang — stdin pipe never closed | Critical | [#1111](https://github.com/ruvnet/claude-flow/issues/1111) |
187
+ | [HW&#8209;002](patch/150-HW-002-failures-swallowed/) | Headless failures silently swallowed as success | High | [#1112](https://github.com/ruvnet/claude-flow/issues/1112) |
188
+ | [HW&#8209;003](patch/160-HW-003-aggressive-intervals/) | Worker scheduling intervals too aggressive | High | [#1113](https://github.com/ruvnet/claude-flow/issues/1113) |
189
+ | [HW&#8209;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) |
190
+
191
+ ### IN -- Intelligence
192
+
193
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
194
+ |----|-------------|----------|--------------|
195
+ | [IN&#8209;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) |
196
+
197
+ ### MM -- Memory Management
198
+
199
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
200
+ |----|-------------|----------|--------------|
201
+ | [MM&#8209;001](patch/180-MM-001-memory-persist-path/) | Remove dead persistPath config option | Low | [#1152](https://github.com/ruvnet/claude-flow/issues/1152) |
202
+
203
+ ### NS -- Memory Namespace
204
+
205
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
206
+ |----|-------------|----------|--------------|
207
+ | [NS&#8209;001](patch/190-NS-001-discovery-default-namespace/) | Discovery ops default to wrong namespace | Critical | [#1123](https://github.com/ruvnet/claude-flow/issues/1123) |
208
+ | [NS&#8209;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) |
209
+ | [NS&#8209;003](patch/210-NS-003-namespace-typo-pattern/) | Namespace typo 'pattern' vs 'patterns' | Medium | [#1136](https://github.com/ruvnet/claude-flow/issues/1136) |
210
+
211
+ ### RS -- ruv-swarm
212
+
213
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
214
+ |----|-------------|----------|--------------|
215
+ | [RS&#8209;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) |
216
+
217
+ ### RV -- RuVector Intelligence
218
+
219
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
220
+ |----|-------------|----------|--------------|
221
+ | [RV&#8209;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) |
222
+ | [RV&#8209;002](patch/240-RV-002-trajectory-load/) | activeTrajectories not loaded from saved file | High | [#1157](https://github.com/ruvnet/claude-flow/issues/1157) |
223
+ | [RV&#8209;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) |
224
+
225
+ ### SG -- Settings Generator
226
+
227
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
228
+ |----|-------------|----------|--------------|
229
+ | [SG&#8209;001](patch/260-SG-001-init-settings/) | Init generates invalid settings | High | [#1150](https://github.com/ruvnet/claude-flow/issues/1150) |
230
+ | [SG&#8209;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) |
231
+
232
+ ### UI -- Display & Cosmetic
233
+
234
+ | ID | Description <img width="500" height="1" /> | Severity | GitHub&nbsp;Issue |
235
+ |----|-------------|----------|--------------|
236
+ | [UI&#8209;001](patch/280-UI-001-intelligence-stats-crash/) | intelligence stats crashes on .toFixed() | Critical | [#1145](https://github.com/ruvnet/claude-flow/issues/1145) |
237
+ | [UI&#8209;002](patch/290-UI-002-neural-status-not-loaded/) | neural status shows "Not loaded" | Low | [#1146](https://github.com/ruvnet/claude-flow/issues/1146) |
238
+ <!-- GENERATED:defect-index:end -->
239
+
240
+ ## Init-Script Patches (Local Project Action Required)
241
+
242
+ 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.
243
+
244
+ ### Affected Defects
245
+
246
+ | ID | Generator patched | Local file affected | Problem if not refreshed |
247
+ |----|-------------------|---------------------|--------------------------|
248
+ | IN-001 | `init/executor.js` | `.claude/helpers/intelligence.cjs` | 197-line stub: no PageRank, no graph, `feedback()` is a no-op, no learning |
249
+ | HK-001 | `init/helpers-generator.js` | `.claude/helpers/hook-handler.cjs` | Reads env vars instead of stdin JSON; post-edit logs `file: "unknown"` |
250
+ | SG-001 | `init/settings-generator.js` | `.claude/settings.json` | May contain invalid hook events, broad permissions, relative paths |
251
+ | SG-002 | `init/executor.js` | `.claude/helpers/*.js` / `*.cjs` | Missing .js/.cjs compat copies; `hook-handler.cjs` require() calls fail silently |
252
+ | MM-001 | `init/executor.js` | `.claude-flow/config.yaml` | Misleading `persistPath` setting that nothing reads |
253
+
254
+ ### How to Fix
255
+
256
+ **Option A: Run `repair`** (recommended)
257
+
258
+ ```bash
259
+ npx --yes @sparkleideas/claude-flow-patch --global
260
+ npx --yes @sparkleideas/claude-flow-patch repair --target .
261
+ npx --yes @sparkleideas/claude-flow-patch apply SG-002 # apply a single patch
262
+ ```
263
+
264
+ This copies patched helper files into your project and creates any missing .js/.cjs compat copies.
265
+
266
+ **Option B: Copy full helpers from the package manually**
267
+
268
+ ```bash
269
+ npx --yes @sparkleideas/claude-flow-patch --global
270
+ SRC=$(find ~/.npm/_npx -path '*/@claude-flow/cli/.claude/helpers' -type d 2>/dev/null | head -1)
271
+ for f in intelligence.cjs hook-handler.cjs session.js learning-service.mjs metrics-db.mjs statusline.cjs; do
272
+ [ -f "$SRC/$f" ] && cp "$SRC/$f" .claude/helpers/ && echo "Copied: $f"
273
+ done
274
+ ```
275
+
276
+ **Option C: Re-run init upgrade** (regenerates from patched scripts)
277
+
278
+ ```bash
279
+ npx --yes @sparkleideas/claude-flow-patch --global
280
+ npx @claude-flow/cli@latest init upgrade --force
281
+ ```
282
+
283
+ Caution: Option C may overwrite other customizations in `.claude/`.
284
+
285
+ ### Why This Happens
286
+
287
+ 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.
288
+
289
+ 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.
290
+
291
+ ## Compatibility
292
+
293
+ - Tested against `@claude-flow/cli@3.1.0-alpha.41` and `ruv-swarm@1.0.20`
294
+ - Requires Python 3.6+ and Bash
295
+ - Works on Linux and macOS (DM-003 is macOS-only, auto-skipped on Linux)
296
+
297
+ ## Links
298
+
299
+ - Homepage: https://sparklingideas.co.uk/claude-flow/patch
300
+ - Package: https://www.npmjs.com/package/@sparkleideas/claude-flow-patch
301
+ - GitHub: https://github.com/sparkling/claude-flow-patch
302
+ - Issues: https://github.com/sparkling/claude-flow-patch/issues
303
+
304
+ ## License
305
+
306
+ MIT
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { readdirSync } from 'node:fs';
4
+ import { dirname, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const rootDir = resolve(__dirname, '..');
9
+ const patchDir = resolve(rootDir, 'patch');
10
+
11
+ const COMMAND_MAP = new Map([
12
+ ['check', 'check-patches.sh'],
13
+ ['repair', 'repair-post-init.sh'],
14
+ ]);
15
+
16
+ function findPatch(id) {
17
+ try {
18
+ const dirs = readdirSync(patchDir, { withFileTypes: true });
19
+ const escaped = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
20
+ const re = new RegExp(`^(\\d+-)?${escaped}-`);
21
+ const match = dirs.find(d => d.isDirectory() && re.test(d.name));
22
+ return match ? resolve(patchDir, match.name, 'fix.py') : null;
23
+ } catch { return null; }
24
+ }
25
+
26
+ function listPatchIds() {
27
+ try {
28
+ return readdirSync(patchDir, { withFileTypes: true })
29
+ .filter(d => d.isDirectory())
30
+ .map(d => {
31
+ const name = d.name.replace(/^\d+-/, '');
32
+ const i = name.indexOf('-', name.indexOf('-') + 1);
33
+ return i > 0 ? name.slice(0, i) : name;
34
+ })
35
+ .sort();
36
+ } catch { return []; }
37
+ }
38
+
39
+ function usage() {
40
+ console.log(`Usage:
41
+ claude-flow-patch Apply all patches (default: --global)
42
+ claude-flow-patch apply <ID> Apply a single patch by defect ID (e.g. SG-002)
43
+ claude-flow-patch check Verify patch sentinels are present
44
+ claude-flow-patch repair [options] Post-init repair
45
+
46
+ Options for default (all patches) and check:
47
+ --global Patch the npx cache (~/.npm/_npx/*)
48
+ --target <dir> Patch node_modules inside <dir>
49
+ --include <regex> Only patches matching regex (against dir name)
50
+ --exclude <regex> Skip patches matching regex (against dir name)
51
+
52
+ If neither --global nor --target is given, --global is assumed.
53
+
54
+ Examples:
55
+ claude-flow-patch --global --target ~/my-project Patch both locations
56
+ claude-flow-patch --target ~/my-project Patch only project node_modules
57
+ claude-flow-patch --include "^DM-" Only daemon patches
58
+ claude-flow-patch --exclude "^RV-" Skip ruvector patches
59
+
60
+ Options for repair:
61
+ --target <dir> Target directory
62
+ --source auto|local|global Source scope
63
+ --dry-run Show what would happen
64
+ `);
65
+ }
66
+
67
+ function run(cmd, args, opts = {}) {
68
+ const result = spawnSync(cmd, args, { stdio: 'inherit', cwd: process.cwd(), env: process.env, ...opts });
69
+ if (result.error) { console.error(result.error.message); process.exit(1); }
70
+ process.exit(result.status ?? 1);
71
+ }
72
+
73
+ // ── Parse options from anywhere in argv ──
74
+
75
+ function extractOpt(argv, name) {
76
+ const idx = argv.indexOf(name);
77
+ if (idx < 0 || idx + 1 >= argv.length) return null;
78
+ const val = argv[idx + 1];
79
+ argv.splice(idx, 2);
80
+ return val;
81
+ }
82
+
83
+ function extractFlag(argv, name) {
84
+ const idx = argv.indexOf(name);
85
+ if (idx < 0) return false;
86
+ argv.splice(idx, 1);
87
+ return true;
88
+ }
89
+
90
+ const rawArgs = process.argv.slice(2);
91
+ const includeRe = extractOpt(rawArgs, '--include');
92
+ const excludeRe = extractOpt(rawArgs, '--exclude');
93
+ const globalFlag = extractFlag(rawArgs, '--global');
94
+ const targetDir = extractOpt(rawArgs, '--target');
95
+
96
+ const [subcommand, ...args] = rawArgs;
97
+
98
+ // Pass filter regexes to patch-all.sh / check-patches.sh via env
99
+ function filterEnv() {
100
+ const env = { ...process.env };
101
+ if (includeRe) env.PATCH_INCLUDE = includeRe;
102
+ if (excludeRe) env.PATCH_EXCLUDE = excludeRe;
103
+ return env;
104
+ }
105
+
106
+ // Build --global / --target args to pass to shell scripts
107
+ function scopeArgs() {
108
+ const a = [];
109
+ if (globalFlag) a.push('--global');
110
+ if (targetDir) a.push('--target', targetDir);
111
+ return a;
112
+ }
113
+
114
+ // No args → apply all patches (most common use case)
115
+ if (!subcommand) {
116
+ run('bash', [resolve(rootDir, 'patch-all.sh'), ...scopeArgs()], { env: filterEnv() });
117
+ }
118
+
119
+ if (subcommand === '--help' || subcommand === '-h') {
120
+ usage();
121
+ process.exit(0);
122
+ }
123
+
124
+ // apply <ID> — run a single patch
125
+ if (subcommand === 'apply') {
126
+ const patchId = args[0];
127
+ if (!patchId) {
128
+ console.error('Error: apply requires a patch ID (e.g. claude-flow-patch apply SG-002)');
129
+ process.exit(1);
130
+ }
131
+ const fixPath = findPatch(patchId);
132
+ if (!fixPath) {
133
+ console.error(`Error: no patch found for ID "${patchId}"`);
134
+ console.error(`Available patches: ${listPatchIds().join(', ')}`);
135
+ process.exit(1);
136
+ }
137
+ run('python3', [fixPath, ...args.slice(1)]);
138
+ }
139
+
140
+ // Named subcommands: check, repair
141
+ const scriptName = COMMAND_MAP.get(subcommand);
142
+ if (!scriptName) {
143
+ console.error(`Unknown command: ${subcommand}`);
144
+ usage();
145
+ process.exit(1);
146
+ }
147
+
148
+ run('bash', [resolve(rootDir, scriptName), ...scopeArgs(), ...args], { env: filterEnv() });
@@ -0,0 +1,176 @@
1
+ #!/bin/bash
2
+ # check-patches.sh — Dynamic sentinel checker
3
+ # Reads patch/*/sentinel files to verify patches are still applied.
4
+ # On session start: detects wipes, auto-reapplies, warns user.
5
+ #
6
+ # Usage:
7
+ # bash check-patches.sh [--global] [--target <dir>]
8
+ #
9
+ # If neither flag is given, --global is assumed.
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+
13
+ # ── Parse arguments ──
14
+ DO_GLOBAL=0
15
+ TARGET_DIR=""
16
+ while [[ $# -gt 0 ]]; do
17
+ case $1 in
18
+ --global) DO_GLOBAL=1; shift ;;
19
+ --target) TARGET_DIR="${2:-}"; shift 2 ;;
20
+ *) shift ;; # ignore unknown (e.g. filter env handled by caller)
21
+ esac
22
+ done
23
+
24
+ if [[ $DO_GLOBAL -eq 0 && -z "$TARGET_DIR" ]]; then
25
+ DO_GLOBAL=1
26
+ fi
27
+
28
+ # ── Locate packages ──
29
+
30
+ find_base_in_global() {
31
+ local mem=$(find ~/.npm/_npx -name "memory-initializer.js" -path "*/memory/*" 2>/dev/null | head -1)
32
+ if [ -n "$mem" ]; then
33
+ echo "$(cd "$(dirname "$mem")/.." && pwd)"
34
+ fi
35
+ }
36
+
37
+ find_base_in_target() {
38
+ local dir="$1"
39
+ local cf="$dir/node_modules/@claude-flow/cli/dist/src"
40
+ if [ -d "$cf" ]; then
41
+ echo "$(cd "$cf" && pwd)"
42
+ fi
43
+ }
44
+
45
+ BASE=""
46
+ VERSION=""
47
+ if [[ $DO_GLOBAL -eq 1 ]]; then
48
+ BASE=$(find_base_in_global)
49
+ fi
50
+ if [[ -z "$BASE" && -n "$TARGET_DIR" ]]; then
51
+ BASE=$(find_base_in_target "$TARGET_DIR")
52
+ fi
53
+
54
+ if [ -z "$BASE" ]; then
55
+ echo "[PATCHES] WARN: Cannot find claude-flow CLI files"
56
+ exit 0
57
+ fi
58
+
59
+ VERSION=$(grep -o '"version": *"[^"]*"' "$BASE/../../package.json" 2>/dev/null | head -1 | cut -d'"' -f4)
60
+
61
+ # External packages (optional) — search same tree as BASE
62
+ PKG_ROOT=$(cd "$BASE/../.." && pwd)
63
+ SEARCH_ROOT=$(dirname "$PKG_ROOT")
64
+
65
+ RV_CLI=$(find "$SEARCH_ROOT" -name "cli.js" -path "*/ruvector/bin/*" 2>/dev/null | head -1)
66
+ RV_BASE=""
67
+ if [ -n "$RV_CLI" ]; then
68
+ RV_BASE=$(cd "$(dirname "$RV_CLI")/.." && pwd)
69
+ fi
70
+
71
+ RS_PKG=$(find "$SEARCH_ROOT" -path "*/ruv-swarm/package.json" 2>/dev/null | head -1)
72
+ RS_BASE=""
73
+ if [ -n "$RS_PKG" ]; then
74
+ RS_BASE=$(dirname "$RS_PKG")
75
+ fi
76
+
77
+ # ── Path resolver ──
78
+
79
+ resolve_path() {
80
+ local pkg="$1"
81
+ local relpath="$2"
82
+ case "$pkg" in
83
+ ruvector) echo "$RV_BASE/$relpath" ;;
84
+ ruv-swarm) echo "$RS_BASE/$relpath" ;;
85
+ *) echo "$BASE/$relpath" ;;
86
+ esac
87
+ }
88
+
89
+ # ── Dynamic sentinel checks ──
90
+ # Reads each patch/*/sentinel file for verification directives.
91
+
92
+ all_ok=true
93
+
94
+ for sentinel_file in "$SCRIPT_DIR"/patch/*/sentinel; do
95
+ [ -f "$sentinel_file" ] || continue
96
+
97
+ # PATCH_INCLUDE / PATCH_EXCLUDE env vars filter by directory name regex
98
+ dirname=$(basename "$(dirname "$sentinel_file")")
99
+ matchname="${dirname#[0-9][0-9][0-9]-}" # strip NNN- prefix for pattern matching
100
+ if [ -n "${PATCH_INCLUDE:-}" ] && ! echo "$matchname" | grep -qE "$PATCH_INCLUDE"; then
101
+ continue
102
+ fi
103
+ if [ -n "${PATCH_EXCLUDE:-}" ] && echo "$matchname" | grep -qE "$PATCH_EXCLUDE"; then
104
+ continue
105
+ fi
106
+
107
+ # Read package line (default: claude-flow)
108
+ pkg="claude-flow"
109
+ pkg_line=$(grep -m1 '^package:' "$sentinel_file" 2>/dev/null || true)
110
+ if [ -n "$pkg_line" ]; then
111
+ pkg="${pkg_line#package:}"
112
+ pkg="${pkg#"${pkg%%[![:space:]]*}"}" # trim leading whitespace
113
+ pkg="${pkg%%[[:space:]]*}" # trim trailing whitespace
114
+ fi
115
+
116
+ # Skip if required package not installed
117
+ case "$pkg" in
118
+ ruvector) [ -z "$RV_CLI" ] && continue ;;
119
+ ruv-swarm) [ -z "$RS_PKG" ] && continue ;;
120
+ esac
121
+
122
+ # Process each line
123
+ while IFS= read -r line; do
124
+ line="${line#"${line%%[![:space:]]*}"}" # trim leading whitespace
125
+ [[ -z "$line" ]] && continue
126
+ [[ "$line" == package:* ]] && continue
127
+
128
+ if [[ "$line" == "none" ]]; then
129
+ continue
130
+
131
+ elif [[ "$line" =~ ^absent\ \"(.+)\"\ (.+)$ ]]; then
132
+ pattern="${BASH_REMATCH[1]}"
133
+ filepath=$(resolve_path "$pkg" "${BASH_REMATCH[2]}")
134
+ if grep -q "$pattern" "$filepath" 2>/dev/null; then
135
+ all_ok=false
136
+ fi
137
+
138
+ elif [[ "$line" =~ ^grep\ \"(.+)\"\ (.+)$ ]]; then
139
+ pattern="${BASH_REMATCH[1]}"
140
+ filepath=$(resolve_path "$pkg" "${BASH_REMATCH[2]}")
141
+ if ! grep -q "$pattern" "$filepath" 2>/dev/null; then
142
+ all_ok=false
143
+ fi
144
+ fi
145
+ done < "$sentinel_file"
146
+ done
147
+
148
+ if $all_ok; then
149
+ echo "[PATCHES] OK: All patches verified (v$VERSION)"
150
+ exit 0
151
+ fi
152
+
153
+ # ── Patches wiped — auto-reapply and warn ──
154
+
155
+ echo ""
156
+ echo "============================================"
157
+ echo " WARNING: claude-flow patches were wiped!"
158
+ echo " Likely cause: npx cache update (v$VERSION)"
159
+ echo "============================================"
160
+ echo ""
161
+
162
+ if [ -x "$SCRIPT_DIR/patch-all.sh" ]; then
163
+ REAPPLY_ARGS=()
164
+ if [[ $DO_GLOBAL -eq 1 ]]; then REAPPLY_ARGS+=(--global); fi
165
+ if [[ -n "$TARGET_DIR" ]]; then REAPPLY_ARGS+=(--target "$TARGET_DIR"); fi
166
+ bash "$SCRIPT_DIR/patch-all.sh" "${REAPPLY_ARGS[@]}"
167
+ echo ""
168
+ echo "[PATCHES] Auto-reapplied. Restarting daemon..."
169
+ npx @claude-flow/cli@latest daemon stop 2>/dev/null
170
+ npx @claude-flow/cli@latest daemon start 2>/dev/null
171
+ echo "[PATCHES] Daemon restarted with patched code."
172
+ echo ""
173
+ else
174
+ echo "[PATCHES] ERROR: patch-all.sh not found at $SCRIPT_DIR"
175
+ echo "[PATCHES] Run manually: bash ~/src/claude-flow-patch/patch-all.sh"
176
+ fi
@@ -0,0 +1,15 @@
1
+ {
2
+ "HW": "Headless Worker",
3
+ "DM": "Daemon & Workers",
4
+ "CF": "Config & Doctor",
5
+ "EM": "Embeddings & HNSW",
6
+ "UI": "Display & Cosmetic",
7
+ "NS": "Memory Namespace",
8
+ "GV": "Ghost Vectors",
9
+ "IN": "Intelligence",
10
+ "SG": "Settings Generator",
11
+ "MM": "Memory Management",
12
+ "HK": "Hooks",
13
+ "RV": "RuVector Intelligence",
14
+ "RS": "ruv-swarm"
15
+ }