claude-recall 0.25.0 → 0.25.1
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/README.md +1 -1
- package/dist/cli/commands/repair.js +95 -4
- package/package.json +1 -1
- package/scripts/postinstall.js +9 -6
package/README.md
CHANGED
|
@@ -310,7 +310,7 @@ claude-recall status # Installation and system status
|
|
|
310
310
|
claude-recall repair # Fix broken claude-recall hook paths (conservative: preserves user customizations)
|
|
311
311
|
claude-recall repair --auto # Non-interactive; apply safe fixes without prompting (used by postinstall)
|
|
312
312
|
claude-recall repair --dry-run # Report what would change without writing
|
|
313
|
-
claude-recall repair --scope user|project|all # Scope the scan (
|
|
313
|
+
claude-recall repair --scope user|project|all # Scope the scan: user (~/.claude), project (closest .claude walking up from cwd), all (user + every nested project under ~). Default: all
|
|
314
314
|
claude-recall repair --reinstall-hooks # Opinionated: rewrite entire hook block from current template
|
|
315
315
|
claude-recall hooks check # Verify hook files exist and are valid
|
|
316
316
|
claude-recall hooks test-enforcement # Test if search enforcer hook works
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.resolveOnPath = resolveOnPath;
|
|
37
37
|
exports.classifyHook = classifyHook;
|
|
38
|
+
exports.findHomeProjectSettings = findHomeProjectSettings;
|
|
38
39
|
exports.findSettingsFiles = findSettingsFiles;
|
|
39
40
|
exports.scanFile = scanFile;
|
|
40
41
|
exports.applyFixes = applyFixes;
|
|
@@ -127,6 +128,87 @@ function pickSiblings(settingsPath) {
|
|
|
127
128
|
}
|
|
128
129
|
return out;
|
|
129
130
|
}
|
|
131
|
+
// Directory names that are guaranteed not to contain a project's `.claude/`
|
|
132
|
+
// dir but tend to be huge. Pruning them keeps the home walk fast even on
|
|
133
|
+
// machines with sprawling node_modules/cache trees.
|
|
134
|
+
const HOME_WALK_PRUNE = new Set([
|
|
135
|
+
'node_modules',
|
|
136
|
+
'.git',
|
|
137
|
+
'.npm',
|
|
138
|
+
'.nvm',
|
|
139
|
+
'.cache',
|
|
140
|
+
'.pnpm-store',
|
|
141
|
+
'.yarn',
|
|
142
|
+
'.docker',
|
|
143
|
+
'.local',
|
|
144
|
+
'.cargo',
|
|
145
|
+
'.rustup',
|
|
146
|
+
'.gradle',
|
|
147
|
+
'.m2',
|
|
148
|
+
'.vscode-server',
|
|
149
|
+
'.cursor-server',
|
|
150
|
+
'Library',
|
|
151
|
+
'AppData',
|
|
152
|
+
'dist',
|
|
153
|
+
'build',
|
|
154
|
+
'target',
|
|
155
|
+
'__pycache__',
|
|
156
|
+
'.venv',
|
|
157
|
+
'venv',
|
|
158
|
+
'.tox',
|
|
159
|
+
'.mypy_cache',
|
|
160
|
+
'.pytest_cache',
|
|
161
|
+
'.next',
|
|
162
|
+
'.turbo',
|
|
163
|
+
]);
|
|
164
|
+
const HOME_WALK_MAX_DEPTH = 8;
|
|
165
|
+
/**
|
|
166
|
+
* Walk $HOME (excluding the user-global ~/.claude/ itself) for every nested
|
|
167
|
+
* `.claude/settings.json` and `.claude/settings.local.json`. Conservative on
|
|
168
|
+
* descent — never follows symlinks, prunes well-known bloat dirs, depth-limited.
|
|
169
|
+
* Used by --scope all to find every project under home that may have stale
|
|
170
|
+
* claude-recall hook paths after an install moves.
|
|
171
|
+
*/
|
|
172
|
+
function findHomeProjectSettings(home) {
|
|
173
|
+
const results = [];
|
|
174
|
+
const userClaudeDir = path.join(home, '.claude');
|
|
175
|
+
function walk(dir, depth) {
|
|
176
|
+
if (depth > HOME_WALK_MAX_DEPTH)
|
|
177
|
+
return;
|
|
178
|
+
let entries;
|
|
179
|
+
try {
|
|
180
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return; // permission denied, gone, etc. — silently skip
|
|
184
|
+
}
|
|
185
|
+
for (const entry of entries) {
|
|
186
|
+
// Don't follow symlinks (loop avoidance, also unlikely to host the
|
|
187
|
+
// canonical project root we want to scan).
|
|
188
|
+
if (entry.isSymbolicLink())
|
|
189
|
+
continue;
|
|
190
|
+
if (entry.isDirectory()) {
|
|
191
|
+
if (HOME_WALK_PRUNE.has(entry.name))
|
|
192
|
+
continue;
|
|
193
|
+
const child = path.join(dir, entry.name);
|
|
194
|
+
if (entry.name === '.claude') {
|
|
195
|
+
// Skip the user-global ~/.claude/ — that's covered by --scope user.
|
|
196
|
+
if (child === userClaudeDir)
|
|
197
|
+
continue;
|
|
198
|
+
for (const f of pickSiblings(path.join(child, 'settings.json'))) {
|
|
199
|
+
if (!results.includes(f))
|
|
200
|
+
results.push(f);
|
|
201
|
+
}
|
|
202
|
+
// Don't descend into .claude/ — settings files live at its root.
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
walk(child, depth + 1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
walk(home, 0);
|
|
210
|
+
return results;
|
|
211
|
+
}
|
|
130
212
|
function findSettingsFiles(cwd, home, scope) {
|
|
131
213
|
const results = [];
|
|
132
214
|
if (scope === 'user' || scope === 'all') {
|
|
@@ -136,10 +218,19 @@ function findSettingsFiles(cwd, home, scope) {
|
|
|
136
218
|
results.push(p);
|
|
137
219
|
}
|
|
138
220
|
}
|
|
139
|
-
if (scope === '
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
// the
|
|
221
|
+
if (scope === 'all') {
|
|
222
|
+
// For --scope all we walk the entire home tree to catch every project's
|
|
223
|
+
// .claude/settings.json — important for postinstall, where stale hook paths
|
|
224
|
+
// in ANY project on the machine break Claude Code in that project.
|
|
225
|
+
for (const p of findHomeProjectSettings(home)) {
|
|
226
|
+
if (!results.includes(p))
|
|
227
|
+
results.push(p);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else if (scope === 'project') {
|
|
231
|
+
// For --scope project we only walk up from cwd looking for the CLOSEST
|
|
232
|
+
// .claude dir (matches Claude Code's own resolution). We don't scan
|
|
233
|
+
// ancestors beyond the first match — those belong to other projects.
|
|
143
234
|
let dir = cwd;
|
|
144
235
|
while (dir !== path.dirname(dir)) {
|
|
145
236
|
const claudeDir = path.join(dir, '.claude');
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -118,21 +118,24 @@ try {
|
|
|
118
118
|
// produces a diff the user can see.
|
|
119
119
|
|
|
120
120
|
// Conservative repair on upgrade: fix broken absolute hook paths in
|
|
121
|
-
// ~/.claude/settings.json
|
|
122
|
-
//
|
|
123
|
-
// into a different location
|
|
124
|
-
//
|
|
121
|
+
// ~/.claude/settings.json AND every project's .claude/settings.json under
|
|
122
|
+
// the user's home. Common when node/nvm versions change, or when the package
|
|
123
|
+
// was reinstalled into a different location (e.g. moving from a root-owned
|
|
124
|
+
// global prefix to ~/.npm-global). The --auto --scope all flags mean:
|
|
125
|
+
// • user-global settings AND every nested project settings file are scanned
|
|
125
126
|
// • only commands pointing at MISSING absolute scripts get rewritten
|
|
126
127
|
// • user customizations (timeouts, matchers, sibling hooks) preserved
|
|
127
128
|
// • writes a .bak.<timestamp> before any change
|
|
128
129
|
// • never installs hooks where none exist — satisfies the "don't clobber"
|
|
129
130
|
// rule above
|
|
131
|
+
// Timeout raised because the home walk can touch many directories on
|
|
132
|
+
// larger machines.
|
|
130
133
|
try {
|
|
131
134
|
const cliPath = path.join(__dirname, '..', 'dist', 'cli', 'claude-recall-cli.js');
|
|
132
135
|
if (fs.existsSync(cliPath)) {
|
|
133
|
-
execSync(`node "${cliPath}" repair --auto --scope
|
|
136
|
+
execSync(`node "${cliPath}" repair --auto --scope all`, {
|
|
134
137
|
stdio: 'inherit',
|
|
135
|
-
timeout:
|
|
138
|
+
timeout: 60000
|
|
136
139
|
});
|
|
137
140
|
}
|
|
138
141
|
} catch (repairError) {
|