greprag 0.6.1 → 0.7.0

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.
@@ -44,6 +44,7 @@ var __importStar = (this && this.__importStar) || (function () {
44
44
  };
45
45
  })();
46
46
  Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.computeGitDerivedProjectId = computeGitDerivedProjectId;
47
48
  exports.readAnchor = readAnchor;
48
49
  exports.ensureGlobalAnchor = ensureGlobalAnchor;
49
50
  exports.ensureAnchor = ensureAnchor;
@@ -51,6 +52,7 @@ const path = __importStar(require("path"));
51
52
  const fs = __importStar(require("fs"));
52
53
  const crypto = __importStar(require("crypto"));
53
54
  const os = __importStar(require("os"));
55
+ const child_process_1 = require("child_process");
54
56
  const ANCHOR_DIR = '.claude';
55
57
  const ANCHOR_FILE = 'project.json';
56
58
  /** Walk up from cwd looking for an existing .claude/project.json.
@@ -91,6 +93,41 @@ function isEphemeralCwd(cwd) {
91
93
  return true; // macOS
92
94
  return false;
93
95
  }
96
+ /** Derive a stable project_id from the git repository's root commit SHA.
97
+ * Returns null when the cwd isn't inside a git repo or the repo has no
98
+ * commits yet (newly `git init`-ed, no first commit).
99
+ *
100
+ * The root commit is *permanently stable* per project — it doesn't change
101
+ * across clones, worktrees, machines, or directory renames, and it survives
102
+ * anchor-file deletion. Disjoint histories (unrelated-histories merge) are
103
+ * handled by sorting all root SHAs alphabetically and concatenating before
104
+ * hashing — same algorithm everywhere produces the same UUID. */
105
+ function computeGitDerivedProjectId(workingDir) {
106
+ try {
107
+ // Multiple root commits possible (history merged from disjoint roots).
108
+ // We sort alphabetically for determinism across machines.
109
+ const out = (0, child_process_1.execSync)('git rev-list --max-parents=0 HEAD', {
110
+ cwd: workingDir,
111
+ encoding: 'utf-8',
112
+ stdio: ['pipe', 'pipe', 'pipe'],
113
+ });
114
+ const roots = out.trim().split(/\s+/).filter(Boolean).sort();
115
+ if (roots.length === 0)
116
+ return null;
117
+ const hash = crypto.createHash('sha256').update(roots.join('\n')).digest('hex');
118
+ // UUID v4-shape, deterministic (matches the deterministicProjectId format).
119
+ return [
120
+ hash.slice(0, 8),
121
+ hash.slice(8, 12),
122
+ '4' + hash.slice(13, 16), // version 4 nibble
123
+ '8' + hash.slice(17, 20), // variant nibble
124
+ hash.slice(20, 32),
125
+ ].join('-');
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
94
131
  /** Hash a working directory into a stable UUID. Used when no anchor file
95
132
  * exists yet — keeps turns flowing without forcing init first. */
96
133
  function deterministicProjectId(workingDir) {
@@ -105,78 +142,113 @@ function deterministicProjectId(workingDir) {
105
142
  hash.slice(20, 32),
106
143
  ].join('-');
107
144
  }
108
- /** Try to read a JSON anchor file at a specific path. Returns null if absent or invalid.
109
- * Flags default to true if absent. The agent can flip them per-project. */
110
- function tryReadAnchorFile(filePath) {
145
+ /** Read a `.claude/project.json` and return its parsed contents. Returns null
146
+ * if the file is missing, unreadable, or invalid JSON. Identity fields stay
147
+ * optional; settings always come back with their defaults applied. */
148
+ function tryReadAnchorFileContents(filePath) {
111
149
  try {
112
150
  const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
113
- if (raw.project_id && raw.project_name) {
114
- const notifyRaw = raw.inbox_notify;
115
- const inboxNotify = notifyRaw === 'off' || notifyRaw === 'session_start_only'
116
- ? notifyRaw
117
- : 'every_turn';
118
- return {
119
- projectId: raw.project_id,
120
- projectName: raw.project_name,
121
- initialized: true,
122
- anchorPath: filePath,
123
- created: raw.created,
124
- memoryCapture: raw.memory_capture !== false, // default true
125
- sessionStartRecap: raw.session_start_recap !== false, // default true
126
- inboxNotify,
127
- };
128
- }
151
+ const notifyRaw = raw.inbox_notify;
152
+ const inboxNotify = notifyRaw === 'off' || notifyRaw === 'session_start_only'
153
+ ? notifyRaw
154
+ : 'every_turn';
155
+ return {
156
+ projectId: raw.project_id,
157
+ projectName: raw.project_name,
158
+ created: raw.created,
159
+ memoryCapture: raw.memory_capture !== false,
160
+ sessionStartRecap: raw.session_start_recap !== false,
161
+ inboxNotify,
162
+ };
129
163
  }
130
164
  catch {
131
- // Fall through.
165
+ return null;
132
166
  }
133
- return null;
134
167
  }
135
168
  /** Read the project anchor for a given cwd. Read-only.
136
169
  *
137
- * Priority:
138
- * (1) walk-up finds a repo-level .claude/project.json → use it.
139
- * (2) cwd is an ephemeral session path (Cowork) AND ~/.claude/project.json
140
- * exists use the global anchor (so memory accumulates across sessions
141
- * whose cwd would otherwise hash differently each time).
142
- * (3) Deterministic per-path UUID fallback stable for any consistent cwd.
170
+ * 4-level cascade (v0.7+):
171
+ * (1) `.claude/project.json` with explicit `project_id` file-based identity
172
+ * (legacy / explicit override). Settings come from the file too.
173
+ * (2) Git repo with at least one commit derive UUID from the root commit
174
+ * SHA. Stable across clones, worktrees, machines, file deletions. If a
175
+ * settings-only file exists nearby, layer its settings on top.
176
+ * (3) Ephemeral cwd (Cowork session paths, /tmp/, etc.) + ~/.claude/project.json
177
+ * exists → use the global anchor.
178
+ * (4) Deterministic path-hash fallback. The only source that returns
179
+ * `initialized: false` — the hook emits a setup warning so the user
180
+ * knows to `git init` or `greprag init`.
143
181
  *
144
- * Crucial: a normal project living under the home dir (e.g. C:/tm-book or
145
- * /home/user/projects/foo) without its own .claude/project.json gets the
146
- * deterministic hash. The global anchor must NEVER capture it.
182
+ * Settings (memoryCapture, sessionStartRecap, inboxNotify) come from a
183
+ * repo-level `.claude/project.json` when one exists, regardless of which
184
+ * identity level resolved. A file with no `project_id` carries settings
185
+ * only — identity flows through git derivation.
147
186
  *
148
187
  * // adr: adr/project-anchor.md
149
188
  */
150
189
  function readAnchor(cwd) {
151
- // 1. Walk up from cwd looking for a repo-level .claude/project.json
152
- // (findExistingAnchor skips the home global anchor).
153
- const existing = findExistingAnchor(cwd);
154
- if (existing) {
155
- const anchor = tryReadAnchorFile(existing);
156
- if (anchor)
157
- return anchor;
190
+ const existingPath = findExistingAnchor(cwd);
191
+ const fileContents = existingPath ? tryReadAnchorFileContents(existingPath) : null;
192
+ // 1. File with explicit project_id → legacy/override identity.
193
+ if (existingPath && fileContents && fileContents.projectId && fileContents.projectName) {
194
+ return {
195
+ projectId: fileContents.projectId,
196
+ projectName: fileContents.projectName,
197
+ initialized: true,
198
+ source: 'file',
199
+ anchorPath: existingPath,
200
+ created: fileContents.created,
201
+ memoryCapture: fileContents.memoryCapture,
202
+ sessionStartRecap: fileContents.sessionStartRecap,
203
+ inboxNotify: fileContents.inboxNotify,
204
+ };
158
205
  }
159
- // 2. Ephemeral session path Cowork and friends. The global anchor exists
160
- // specifically to give these a stable bucket since their cwd changes
161
- // every session.
206
+ // 2. Git-derived identitystable per-project, no file needed.
207
+ const gitId = computeGitDerivedProjectId(cwd);
208
+ if (gitId) {
209
+ const root = path.resolve(cwd);
210
+ return {
211
+ projectId: gitId,
212
+ projectName: fileContents?.projectName || path.basename(root).toLowerCase(),
213
+ initialized: true,
214
+ source: 'git',
215
+ anchorPath: existingPath || path.join(root, ANCHOR_DIR, ANCHOR_FILE),
216
+ created: fileContents?.created,
217
+ memoryCapture: fileContents?.memoryCapture ?? true,
218
+ sessionStartRecap: fileContents?.sessionStartRecap ?? true,
219
+ inboxNotify: fileContents?.inboxNotify ?? 'every_turn',
220
+ };
221
+ }
222
+ // 3. Ephemeral cwd + global anchor — Cowork and similar agent runners.
162
223
  if (isEphemeralCwd(cwd)) {
163
224
  const globalAnchorPath = path.join(os.homedir(), ANCHOR_DIR, ANCHOR_FILE);
164
- if (fs.existsSync(globalAnchorPath)) {
165
- const anchor = tryReadAnchorFile(globalAnchorPath);
166
- if (anchor)
167
- return { ...anchor, anchorPath: globalAnchorPath };
225
+ const globalContents = tryReadAnchorFileContents(globalAnchorPath);
226
+ if (globalContents && globalContents.projectId && globalContents.projectName) {
227
+ return {
228
+ projectId: globalContents.projectId,
229
+ projectName: globalContents.projectName,
230
+ initialized: true,
231
+ source: 'global',
232
+ anchorPath: globalAnchorPath,
233
+ created: globalContents.created,
234
+ memoryCapture: globalContents.memoryCapture,
235
+ sessionStartRecap: globalContents.sessionStartRecap,
236
+ inboxNotify: globalContents.inboxNotify,
237
+ };
168
238
  }
169
239
  }
170
- // 3. Fallback: deterministic per-path UUID + basename as name.
240
+ // 4. Path-hash fallback only source that flags `initialized: false`.
171
241
  const root = path.resolve(cwd);
172
242
  return {
173
243
  projectId: deterministicProjectId(root),
174
- projectName: path.basename(root).toLowerCase(),
244
+ projectName: fileContents?.projectName || path.basename(root).toLowerCase(),
175
245
  initialized: false,
176
- anchorPath: path.join(root, ANCHOR_DIR, ANCHOR_FILE),
177
- memoryCapture: true,
178
- sessionStartRecap: true,
179
- inboxNotify: 'every_turn',
246
+ source: 'hash',
247
+ anchorPath: existingPath || path.join(root, ANCHOR_DIR, ANCHOR_FILE),
248
+ created: fileContents?.created,
249
+ memoryCapture: fileContents?.memoryCapture ?? true,
250
+ sessionStartRecap: fileContents?.sessionStartRecap ?? true,
251
+ inboxNotify: fileContents?.inboxNotify ?? 'every_turn',
180
252
  };
181
253
  }
182
254
  /** Create (or return existing) ~/.claude/project.json.
@@ -184,11 +256,21 @@ function readAnchor(cwd) {
184
256
  function ensureGlobalAnchor(projectName) {
185
257
  const globalAnchorDir = path.join(os.homedir(), ANCHOR_DIR);
186
258
  const globalAnchorPath = path.join(globalAnchorDir, ANCHOR_FILE);
187
- // Return existing if valid.
188
259
  if (fs.existsSync(globalAnchorPath)) {
189
- const anchor = tryReadAnchorFile(globalAnchorPath);
190
- if (anchor)
191
- return anchor;
260
+ const contents = tryReadAnchorFileContents(globalAnchorPath);
261
+ if (contents && contents.projectId && contents.projectName) {
262
+ return {
263
+ projectId: contents.projectId,
264
+ projectName: contents.projectName,
265
+ initialized: true,
266
+ source: 'global',
267
+ anchorPath: globalAnchorPath,
268
+ created: contents.created,
269
+ memoryCapture: contents.memoryCapture,
270
+ sessionStartRecap: contents.sessionStartRecap,
271
+ inboxNotify: contents.inboxNotify,
272
+ };
273
+ }
192
274
  }
193
275
  if (!fs.existsSync(globalAnchorDir)) {
194
276
  fs.mkdirSync(globalAnchorDir, { recursive: true });
@@ -203,6 +285,7 @@ function ensureGlobalAnchor(projectName) {
203
285
  projectId: newAnchor.project_id,
204
286
  projectName: newAnchor.project_name,
205
287
  initialized: true,
288
+ source: 'global',
206
289
  anchorPath: globalAnchorPath,
207
290
  created: newAnchor.created,
208
291
  memoryCapture: true,
@@ -210,37 +293,75 @@ function ensureGlobalAnchor(projectName) {
210
293
  inboxNotify: 'every_turn',
211
294
  };
212
295
  }
213
- /** Ensure an anchor exists at <cwd>/.claude/project.json. Generates UUID + writes
214
- * the file if absent. Returns the resolved anchor (initialized=true on return).
215
- * Called by `greprag init`.
296
+ /** Ensure an anchor exists at <cwd>/.claude/project.json. Behavior depends on
297
+ * whether the cwd is inside a git repo with commits:
216
298
  *
217
- * Does NOT treat the global anchor (~/.claude/project.json) as an existing repo
218
- * anchor init should always create a proper per-repo file. */
299
+ * - Git repo with commits: writes settings only (no `project_id` field).
300
+ * Identity flows through git derivation no random UUID stored, so the
301
+ * file can be deleted without orphaning history. Returns the resolved
302
+ * anchor (source='git').
303
+ *
304
+ * - No git or no commits: writes a random `project_id` to the file (legacy
305
+ * behavior). User gets a stable per-path identity until they `git init`
306
+ * + commit, at which point they can run `greprag doctor` to migrate.
307
+ *
308
+ * Called by `greprag init`. Idempotent — if a repo-level anchor already
309
+ * exists, returns it unchanged.
310
+ *
311
+ * Never treats the global anchor as an existing repo anchor. */
219
312
  function ensureAnchor(cwd, projectName) {
220
313
  const globalAnchorPath = path.join(os.homedir(), ANCHOR_DIR, ANCHOR_FILE);
221
314
  const existing = findExistingAnchor(cwd);
222
- // Short-circuit only for a real repo anchor, not the global catch-all.
223
315
  if (existing && existing !== globalAnchorPath) {
224
316
  return readAnchor(cwd);
225
317
  }
226
318
  const root = path.resolve(cwd);
227
319
  const anchorDir = path.join(root, ANCHOR_DIR);
228
320
  const anchorPath = path.join(anchorDir, ANCHOR_FILE);
321
+ const resolvedName = (projectName || path.basename(root)).toLowerCase();
322
+ const created = new Date().toISOString();
229
323
  if (!fs.existsSync(anchorDir)) {
230
324
  fs.mkdirSync(anchorDir, { recursive: true });
231
325
  }
326
+ const gitId = computeGitDerivedProjectId(cwd);
327
+ if (gitId) {
328
+ // Git repo with commits — write settings-only file, identity from git.
329
+ const fileBody = {
330
+ project_name: resolvedName,
331
+ created,
332
+ memory_capture: true,
333
+ session_start_recap: true,
334
+ inbox_notify: 'every_turn',
335
+ };
336
+ fs.writeFileSync(anchorPath, JSON.stringify(fileBody, null, 2) + '\n');
337
+ return {
338
+ projectId: gitId,
339
+ projectName: resolvedName,
340
+ initialized: true,
341
+ source: 'git',
342
+ anchorPath,
343
+ created,
344
+ memoryCapture: true,
345
+ sessionStartRecap: true,
346
+ inboxNotify: 'every_turn',
347
+ };
348
+ }
349
+ // No git or no commits — write a random project_id (legacy path). The
350
+ // hook's drift detector will surface a migration prompt once the project
351
+ // does get a first commit (doctor consolidates old random UUID → git UUID).
232
352
  const newAnchor = {
233
353
  project_id: crypto.randomUUID(),
234
- project_name: (projectName || path.basename(root)).toLowerCase(),
235
- created: new Date().toISOString(),
354
+ project_name: resolvedName,
355
+ created,
236
356
  };
237
357
  fs.writeFileSync(anchorPath, JSON.stringify(newAnchor, null, 2) + '\n');
238
358
  return {
239
359
  projectId: newAnchor.project_id,
240
360
  projectName: newAnchor.project_name,
241
361
  initialized: true,
362
+ source: 'file',
242
363
  anchorPath,
243
- created: newAnchor.created,
364
+ created,
244
365
  memoryCapture: true,
245
366
  sessionStartRecap: true,
246
367
  inboxNotify: 'every_turn',
@@ -1 +1 @@
1
- {"version":3,"file":"project-anchor.js","sourceRoot":"","sources":["../src/project-anchor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4HH,gCA+BC;AAID,gDAgCC;AAQD,oCAkCC;AAvOD,2CAA6B;AAC7B,uCAAyB;AACzB,+CAAiC;AACjC,uCAAyB;AAkBzB,MAAM,UAAU,GAAG,SAAS,CAAC;AAC7B,MAAM,WAAW,GAAG,cAAc,CAAC;AAEnC;;;;;gFAKgF;AAChF,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IACpE,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAC1D,IAAI,SAAS,KAAK,UAAU,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,eAAe;QAChD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;uEAEuE;AACvE,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,4CAA4C;IAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAAE,OAAO,IAAI,CAAC;IACrF,IAAI,IAAI,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QAAE,OAAO,IAAI,CAAC;IACnF,+DAA+D;IAC/D,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,QAAQ;IAC3D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;mEACmE;AACnE,SAAS,sBAAsB,CAAC,UAAkB;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1E,2EAA2E;IAC3E,OAAO;QACL,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAChB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACjB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAU,mBAAmB;QACrD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAU,iBAAiB;QACnD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;KACnB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED;4EAC4E;AAC5E,SAAS,iBAAiB,CAAC,QAAgB;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAOxD,CAAC;QACF,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC;YACnC,MAAM,WAAW,GACf,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,oBAAoB;gBACvD,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,YAAY,CAAC;YACnB,OAAO;gBACL,SAAS,EAAE,GAAG,CAAC,UAAU;gBACzB,WAAW,EAAE,GAAG,CAAC,YAAY;gBAC7B,WAAW,EAAE,IAAI;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,aAAa,EAAE,GAAG,CAAC,cAAc,KAAK,KAAK,EAAU,eAAe;gBACpE,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,KAAK,KAAK,EAAE,eAAe;gBACrE,WAAW;aACZ,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,UAAU,CAAC,GAAW;IACpC,oEAAoE;IACpE,wDAAwD;IACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,2EAA2E;IAC3E,wEAAwE;IACxE,oBAAoB;IACpB,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAC1E,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;YACnD,IAAI,MAAM;gBAAE,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC;QACjE,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO;QACL,SAAS,EAAE,sBAAsB,CAAC,IAAI,CAAC;QACvC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;QAC9C,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC;QACpD,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,YAAY;KAC1B,CAAC;AACJ,CAAC;AAED;qDACqD;AACrD,SAAgB,kBAAkB,CAAC,WAAoB;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IAEjE,4BAA4B;IAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;QAC/B,YAAY,EAAE,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC,WAAW,EAAE;QACrD,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAClC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE9E,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,UAAU;QAC/B,WAAW,EAAE,SAAS,CAAC,YAAY;QACnC,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,gBAAgB;QAC5B,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,YAAY;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;iEAKiE;AACjE,SAAgB,YAAY,CAAC,GAAW,EAAE,WAAoB;IAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACzC,uEAAuE;IACvE,IAAI,QAAQ,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QAC9C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAErD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;QAC/B,YAAY,EAAE,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;QAChE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAClC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAExE,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,UAAU;QAC/B,WAAW,EAAE,SAAS,CAAC,YAAY;QACnC,WAAW,EAAE,IAAI;QACjB,UAAU;QACV,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,YAAY;KAC1B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"project-anchor.js","sourceRoot":"","sources":["../src/project-anchor.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greprag",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "GrepRAG — agent memory for Claude Code. 2-command setup.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -182,6 +182,29 @@ Address formats (all valid):
182
182
 
183
183
  Auto-read semantics: any message returned by `greprag inbox` (without `--all`) is marked read in the same call. Once read, it stops appearing in notifications. TTL deletes read messages after 14 days. Use `keep` to extend before expiry.
184
184
 
185
+ ## Step 5c — Health & repair (when memory looks wrong)
186
+
187
+ Triggers: user says "memory looks empty", "I'm missing my history", "fix greprag here", "are there orphans", "consolidate my project IDs"; or `greprag status` reports identity drift; or the session-start recap printed a "[GrepRAG memory: identity drift detected ...]" line.
188
+
189
+ ```bash
190
+ greprag doctor
191
+ ```
192
+
193
+ What it does:
194
+ 1. Reads the current project's identity (project_id + which cascade level resolved it — file / git-derived / global / path-hash)
195
+ 2. Computes what the git-derived UUID *would* be (if in a git repo with commits)
196
+ 3. Queries the API for sibling project_ids under the same profile name (these are the orphans — usually from old anchor files lost to gitignore or a hash-fallback period before init)
197
+ 4. Presents the findings and offers actions:
198
+ - **Migrate to git-derived UUID** (recommended when there's drift) — moves current + orphan rows onto the git-derived ID and strips `project_id` from `.claude/project.json` so identity flows from git history going forward
199
+ - **Consolidate orphans into current UUID** — keeps the current identity but pulls orphan rows in
200
+ - **Dry-run** — runs the recommended action through the API with `dry_run: true` so the user sees exactly what would change before committing
201
+
202
+ Flags:
203
+ - `--inspect` — diagnose only, no prompts (good for "tell me what's wrong here")
204
+ - `--yes` / `-y` — non-interactive; picks the recommended action and runs it
205
+
206
+ Repair is fully tenant-scoped via the API — `greprag doctor` only ever touches rows under the caller's tenant, and the merge runs in a transaction so a partial failure rolls back cleanly.
207
+
185
208
  ## Step 6 — Briefing (when everything is configured)
186
209
 
187
210
  ```bash