@sdsrs/code-graph 0.120.0 → 0.121.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.
|
@@ -808,7 +808,17 @@ function unadopt({ cwd, home } = {}) {
|
|
|
808
808
|
// Also sweep any legacy memory-dir remnants (uninstall before auto-migration ran).
|
|
809
809
|
const migrated = migrateLegacyMemoryDir({ cwd, home });
|
|
810
810
|
|
|
811
|
-
|
|
811
|
+
// Deregister ONLY what we actually cleaned. The registry is the sole record
|
|
812
|
+
// of which repos carry a managed block — `uninstall --unadopt-all` and the
|
|
813
|
+
// uninstall-time sweep are both driven by it — so dropping the entry for a
|
|
814
|
+
// project whose CLAUDE.md we could not rewrite (root-owned file, read-only
|
|
815
|
+
// mount, EPERM dir) strands that block with nothing left pointing at it.
|
|
816
|
+
// Harmless while the caller only ever passed the current cwd; load-bearing
|
|
817
|
+
// since the uninstall sweep walks the whole list, because an unconditional
|
|
818
|
+
// deregister empties the file and removeCacheResidue() only preserves a
|
|
819
|
+
// NON-EMPTY registry — so the failed project's record died with the cache.
|
|
820
|
+
const cleanupFailed = claudeMdUnwritable || claudeMdUnreadable;
|
|
821
|
+
const registryUpdated = cleanupFailed ? false : removeAdopted(effectiveCwd, home);
|
|
812
822
|
return {
|
|
813
823
|
ok: true, fileRemoved, blockPruned, claudeMdRemoved,
|
|
814
824
|
claudeMdUnreadable, claudeMdUnwritable, registryUpdated,
|
|
@@ -889,7 +899,7 @@ if (require.main === module) {
|
|
|
889
899
|
|
|
890
900
|
module.exports = {
|
|
891
901
|
adopt, unadopt, memoryDir, formatResult, stripSentinelBlock,
|
|
892
|
-
readAdoptedProjects, recordAdopted, removeAdopted, adoptedRegistryFile,
|
|
902
|
+
readAdoptedProjects, readAdoptedResult, recordAdopted, removeAdopted, adoptedRegistryFile,
|
|
893
903
|
isAdopted, isPluginModeInstall, maybeAutoAdopt, needsRefresh, isProjectRoot,
|
|
894
904
|
detectProjectType, buildBlock, buildTriggerRows, migrateLegacyMemoryDir,
|
|
895
905
|
claudeMdPath, detailDir, detailPath,
|
|
@@ -601,12 +601,13 @@ function cleanupDisabledStatusline() {
|
|
|
601
601
|
// our composite from settings.json, so Claude Code stops invoking us.
|
|
602
602
|
let cacheRemoved = false;
|
|
603
603
|
let unadopted = [];
|
|
604
|
+
let registryUnusable = false;
|
|
604
605
|
if (uninstalled) {
|
|
605
|
-
unadopted = unadoptRegisteredProjects();
|
|
606
|
+
({ unadopted, registryUnusable } = unadoptRegisteredProjects());
|
|
606
607
|
cacheRemoved = removeCacheResidue();
|
|
607
608
|
}
|
|
608
609
|
|
|
609
|
-
return { cleaned: true, settingsChanged, cacheRemoved, unadopted };
|
|
610
|
+
return { cleaned: true, settingsChanged, cacheRemoved, unadopted, registryUnusable };
|
|
610
611
|
}
|
|
611
612
|
|
|
612
613
|
/**
|
|
@@ -622,12 +623,20 @@ function cleanupDisabledStatusline() {
|
|
|
622
623
|
*/
|
|
623
624
|
function unadoptRegisteredProjects() {
|
|
624
625
|
const out = [];
|
|
625
|
-
let
|
|
626
|
-
try { ({
|
|
627
|
-
catch { return out; } // POSIX-only helper unavailable — teardown continues
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
626
|
+
let readAdoptedResult, unadopt;
|
|
627
|
+
try { ({ readAdoptedResult, unadopt } = require('./adopt')); }
|
|
628
|
+
catch { return { unadopted: out, registryUnusable: false }; } // POSIX-only helper unavailable — teardown continues
|
|
629
|
+
// readAdoptedResult, NOT the lenient readAdoptedProjects(): that wrapper
|
|
630
|
+
// collapses "unreadable / truncated / wrong shape" into `[]`, which here is
|
|
631
|
+
// indistinguishable from "no projects to clean" — so a corrupt registry would
|
|
632
|
+
// silently sweep nothing AND still be deleted by removeCacheResidue() below,
|
|
633
|
+
// taking the only record of which repos carry a managed block with it. adopt.js
|
|
634
|
+
// documents the same bit for the same reason: only a genuinely ABSENT file may
|
|
635
|
+
// be read as empty.
|
|
636
|
+
let res;
|
|
637
|
+
try { res = readAdoptedResult(); } catch { return { unadopted: out, registryUnusable: true }; }
|
|
638
|
+
if (res && res.unusable) return { unadopted: out, registryUnusable: true };
|
|
639
|
+
for (const project of (res && res.list) || []) {
|
|
631
640
|
try {
|
|
632
641
|
const r = unadopt({ cwd: project });
|
|
633
642
|
out.push({ project, cleaned: !!(r && (r.blockPruned || r.fileRemoved || r.claudeMdRemoved)) });
|
|
@@ -635,7 +644,36 @@ function unadoptRegisteredProjects() {
|
|
|
635
644
|
out.push({ project, cleaned: false, error: (e && e.message) || String(e) });
|
|
636
645
|
}
|
|
637
646
|
}
|
|
638
|
-
|
|
647
|
+
reportUnadoptSweep(out);
|
|
648
|
+
return { unadopted: out, registryUnusable: false };
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Tell the user their repos were just edited. Everything else about this
|
|
653
|
+
* teardown is invisible by construction: it runs inside a statusline render,
|
|
654
|
+
* both callers `process.exit(0)` on `cleaned` and discard the return value, and
|
|
655
|
+
* Claude Code fires no uninstall hook — so without this line the first signal is
|
|
656
|
+
* unexplained `CLAUDE.md` diffs in `git status` across several repositories.
|
|
657
|
+
* stderr, because a statusline's stdout IS the status line.
|
|
658
|
+
*/
|
|
659
|
+
function reportUnadoptSweep(entries) {
|
|
660
|
+
try {
|
|
661
|
+
const cleaned = entries.filter((e) => e && e.cleaned).map((e) => e.project);
|
|
662
|
+
const failed = entries.filter((e) => e && !e.cleaned).map((e) => e.project);
|
|
663
|
+
if (!cleaned.length && !failed.length) return;
|
|
664
|
+
const lines = [];
|
|
665
|
+
if (cleaned.length) {
|
|
666
|
+
lines.push(`[code-graph] Plugin uninstalled — removed the managed CLAUDE.md block from ${cleaned.length} project(s):`);
|
|
667
|
+
for (const p of cleaned.slice(0, 10)) lines.push(` ${p}`);
|
|
668
|
+
if (cleaned.length > 10) lines.push(` …and ${cleaned.length - 10} more`);
|
|
669
|
+
lines.push(' Your own text outside the block was kept; .code-graph/ index dirs are untouched.');
|
|
670
|
+
}
|
|
671
|
+
if (failed.length) {
|
|
672
|
+
lines.push(`[code-graph] Could NOT clean ${failed.length} project(s) — remove the block by hand or run \`code-graph-mcp unadopt\` there:`);
|
|
673
|
+
for (const p of failed.slice(0, 10)) lines.push(` ${p}`);
|
|
674
|
+
}
|
|
675
|
+
process.stderr.write(lines.join('\n') + '\n');
|
|
676
|
+
} catch { /* a notice must never be able to fail a teardown */ }
|
|
639
677
|
}
|
|
640
678
|
|
|
641
679
|
// --- Scope Conflict Detection ---
|
|
@@ -1716,9 +1754,20 @@ function removeCacheResidue() {
|
|
|
1716
1754
|
try {
|
|
1717
1755
|
registryPath = require('./adopt').adoptedRegistryFile();
|
|
1718
1756
|
const raw = fs.existsSync(registryPath) ? fs.readFileSync(registryPath) : null;
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1757
|
+
if (raw) {
|
|
1758
|
+
let parsed = null;
|
|
1759
|
+
let usable = true;
|
|
1760
|
+
try { parsed = JSON.parse(raw.toString('utf8')); } catch { usable = false; }
|
|
1761
|
+
// Preserve a NON-EMPTY list (projects still carry a block) and anything we
|
|
1762
|
+
// could not READ as a list. The unusable case used to fall into the same
|
|
1763
|
+
// "nothing to preserve" catch as a missing file — the strictly worse
|
|
1764
|
+
// outcome, since a registry we cannot parse is the one whose contents we
|
|
1765
|
+
// are least able to reconstruct, and the sweep above deliberately skips it
|
|
1766
|
+
// rather than guessing. Only a genuinely EMPTY array strands nothing and
|
|
1767
|
+
// is allowed to go with the cache dir.
|
|
1768
|
+
if (!usable || !Array.isArray(parsed) || parsed.length) registry = raw;
|
|
1769
|
+
}
|
|
1770
|
+
} catch { /* POSIX-only helper or an unreadable path — nothing to preserve */ }
|
|
1722
1771
|
try {
|
|
1723
1772
|
fs.rmSync(CACHE_DIR, { recursive: true, force: true });
|
|
1724
1773
|
} catch { return false; }
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
node-version: '20'
|
|
36
36
|
- name: Build snapshot
|
|
37
37
|
run: |
|
|
38
|
-
npx -y -p @sdsrs/code-graph@0.
|
|
38
|
+
npx -y -p @sdsrs/code-graph@0.121.0 code-graph-mcp snapshot create --out snapshot.db
|
|
39
39
|
zstd -9 snapshot.db -o snapshot.db.zst
|
|
40
40
|
mv snapshot.db.zst "code-graph-snapshot-${GITHUB_SHA:0:7}.db.zst"
|
|
41
41
|
- name: Upload to release
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdsrs/code-graph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.121.0",
|
|
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.
|
|
39
|
-
"@sdsrs/code-graph-linux-arm64": "0.
|
|
40
|
-
"@sdsrs/code-graph-darwin-x64": "0.
|
|
41
|
-
"@sdsrs/code-graph-darwin-arm64": "0.
|
|
42
|
-
"@sdsrs/code-graph-win32-x64": "0.
|
|
38
|
+
"@sdsrs/code-graph-linux-x64": "0.121.0",
|
|
39
|
+
"@sdsrs/code-graph-linux-arm64": "0.121.0",
|
|
40
|
+
"@sdsrs/code-graph-darwin-x64": "0.121.0",
|
|
41
|
+
"@sdsrs/code-graph-darwin-arm64": "0.121.0",
|
|
42
|
+
"@sdsrs/code-graph-win32-x64": "0.121.0"
|
|
43
43
|
}
|
|
44
44
|
}
|