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 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 (default: all)
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 === 'project' || scope === 'all') {
140
- // Walk up looking for the CLOSEST .claude dir containing a settings file
141
- // (matches Claude Code's own resolution). We don't scan ancestors beyond
142
- // the first match those belong to other projects.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-recall",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Persistent memory for Claude Code and Pi with native Skills integration, automatic capture, failure learning, and project scoping",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -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 that reference a defunct claude-recall install
122
- // (common when node/nvm versions change, or when the package was reinstalled
123
- // into a different location). The --auto --scope user flags mean:
124
- // only user-global settings are touched (no project files)
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 user`, {
136
+ execSync(`node "${cliPath}" repair --auto --scope all`, {
134
137
  stdio: 'inherit',
135
- timeout: 15000
138
+ timeout: 60000
136
139
  });
137
140
  }
138
141
  } catch (repairError) {