@sdsrs/code-graph 0.75.1 → 0.75.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.
@@ -4,7 +4,7 @@
4
4
  "author": {
5
5
  "name": "sdsrs"
6
6
  },
7
- "version": "0.75.1",
7
+ "version": "0.75.3",
8
8
  "keywords": [
9
9
  "code-graph",
10
10
  "ast",
@@ -1391,6 +1391,31 @@ test('resolveProjectRoot: a nested index with its OWN .git (submodule) still win
1391
1391
  } finally { fsE2e.rmSync(base, { recursive: true, force: true }); }
1392
1392
  });
1393
1393
 
1394
+ test('resolveProjectRoot: start with its OWN .git but no index → null (boundary, no escape)', () => {
1395
+ const base = fsE2e.mkdtempSync(pathE2e.join(osE2e.tmpdir(), 'cg-root-'));
1396
+ try {
1397
+ const proj = pathE2e.join(base, 'proj'); // indexed parent
1398
+ fsE2e.mkdirSync(pathE2e.join(proj, '.code-graph'), { recursive: true });
1399
+ fsE2e.writeFileSync(pathE2e.join(proj, '.code-graph', 'index.db'), '');
1400
+ const sub = pathE2e.join(proj, 'sub'); // own .git, no index
1401
+ fsE2e.mkdirSync(pathE2e.join(sub, '.git'), { recursive: true });
1402
+ assert.equal(resolveProjectRoot(sub, { home: base }), null);
1403
+ } finally { fsE2e.rmSync(base, { recursive: true, force: true }); }
1404
+ });
1405
+
1406
+ test('resolveProjectRoot: non-git monorepo — stray subdir index resolves to indexed ancestor', () => {
1407
+ const base = fsE2e.mkdtempSync(pathE2e.join(osE2e.tmpdir(), 'cg-root-'));
1408
+ try {
1409
+ const root = pathE2e.join(base, 'mono'); // indexed, NO .git
1410
+ fsE2e.mkdirSync(pathE2e.join(root, '.code-graph'), { recursive: true });
1411
+ fsE2e.writeFileSync(pathE2e.join(root, '.code-graph', 'index.db'), '');
1412
+ const sub = pathE2e.join(root, 'backend'); // stray index, no .git
1413
+ fsE2e.mkdirSync(pathE2e.join(sub, '.code-graph'), { recursive: true });
1414
+ fsE2e.writeFileSync(pathE2e.join(sub, '.code-graph', 'index.db'), '');
1415
+ assert.equal(resolveProjectRoot(sub, { home: base }), root);
1416
+ } finally { fsE2e.rmSync(base, { recursive: true, force: true }); }
1417
+ });
1418
+
1394
1419
  test('rebaseRelativePaths: daagu shape — bare `app` from backend/ cwd', () => {
1395
1420
  const exists = (p) => p.endsWith(pathE2e.join('backend', 'app'));
1396
1421
  const cmd = 'grep -rn "rr_source\\|max_retries" app --include=*.py';
@@ -31,6 +31,12 @@ function resolveProjectRoot(startDir, opts = {}) {
31
31
  const hasGit = (d) => exists(path.join(d, '.git'));
32
32
  const start = path.resolve(startDir || '.');
33
33
 
34
+ // start's own `.git` is a hard project boundary (a real submodule / distinct
35
+ // repo): use its index if present, else `null` — never escape to an ancestor's
36
+ // index. Mirrors the Rust resolver's rule 1 (which returns cwd even without an
37
+ // index because it CREATES one; the JS reader has nothing to read → null).
38
+ if (hasGit(start)) return hasIndex(start) ? start : null;
39
+
34
40
  // Detect whether `start` is a STRAY nested index: walk STRICT ancestors up to
35
41
  // the nearest `.git` root (project boundary), bounded at home. An indexed
36
42
  // ancestor within that boundary means start's own index is a monorepo-subdir
@@ -50,9 +56,9 @@ function resolveProjectRoot(startDir, opts = {}) {
50
56
  if (hasGit(dir)) { if (hasIndex(dir)) gitRootIndexed = dir; break; }
51
57
  }
52
58
 
53
- // start's own index wins unless it is stray (indexed ancestor within the git
54
- // boundary) and start is not itself a boundary (`.git`, a real submodule).
55
- if (hasIndex(start) && (!ancestorIndexed || hasGit(start))) return start;
59
+ // start's own index wins unless it is stray (an indexed ancestor within the
60
+ // git boundary). start's own `.git` was already handled above.
61
+ if (hasIndex(start) && !ancestorIndexed) return start;
56
62
  if (gitRootIndexed) return gitRootIndexed;
57
63
  // Otherwise the nearest indexed ancestor (skipping a stray start), bounded at
58
64
  // home; null if nothing on the chain is indexed. Mirrors the original walk.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdsrs/code-graph",
3
- "version": "0.75.1",
3
+ "version": "0.75.3",
4
4
  "description": "MCP server that indexes codebases into an AST knowledge graph with semantic search, call graph traversal, and HTTP route tracing",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,10 +35,10 @@
35
35
  "node": ">=16"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@sdsrs/code-graph-linux-x64": "0.75.1",
39
- "@sdsrs/code-graph-linux-arm64": "0.75.1",
40
- "@sdsrs/code-graph-darwin-x64": "0.75.1",
41
- "@sdsrs/code-graph-darwin-arm64": "0.75.1",
42
- "@sdsrs/code-graph-win32-x64": "0.75.1"
38
+ "@sdsrs/code-graph-linux-x64": "0.75.3",
39
+ "@sdsrs/code-graph-linux-arm64": "0.75.3",
40
+ "@sdsrs/code-graph-darwin-x64": "0.75.3",
41
+ "@sdsrs/code-graph-darwin-arm64": "0.75.3",
42
+ "@sdsrs/code-graph-win32-x64": "0.75.3"
43
43
  }
44
44
  }