@sdsrs/code-graph 0.76.1 → 0.76.2
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.
|
@@ -393,30 +393,35 @@ async function downloadAndInstall(latest, {
|
|
|
393
393
|
pluginUpdated = true;
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
//
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
installed.plugins[PLUGIN_ID][0].installPath = pluginDst;
|
|
402
|
-
installed.plugins[PLUGIN_ID][0].version = latest.version;
|
|
403
|
-
installed.plugins[PLUGIN_ID][0].lastUpdated = new Date().toISOString();
|
|
404
|
-
writeJsonAtomic(installedPath, installed);
|
|
405
|
-
}
|
|
406
|
-
} catch { /* not fatal */ }
|
|
407
|
-
|
|
408
|
-
// Update install manifest
|
|
409
|
-
try {
|
|
410
|
-
const manifest = readManifest();
|
|
411
|
-
manifest.version = latest.version;
|
|
412
|
-
manifest.updatedAt = new Date().toISOString();
|
|
413
|
-
writeJsonAtomic(path.join(CACHE_DIR, 'install-manifest.json'), manifest);
|
|
414
|
-
} catch { /* not fatal */ }
|
|
415
|
-
|
|
416
|
-
// Run the NEW lifecycle.js to update settings.json hooks with new paths.
|
|
417
|
-
// Without this, settings.json hooks still point to the old version directory
|
|
418
|
-
// until the next session's self-heal corrects them.
|
|
396
|
+
// Repoint state at the new version ONLY if the plugin copy actually landed.
|
|
397
|
+
// Guarding on pluginUpdated: when the copy above was skipped (pluginSrc absent, or
|
|
398
|
+
// its plugin.json version drifted from the tag — the project's version sync is known
|
|
399
|
+
// fragile), pluginDst was never created. Advancing installPath/manifest to it anyway
|
|
400
|
+
// pointed Claude Code at a nonexistent install dir while state read "up to date".
|
|
419
401
|
if (pluginUpdated) {
|
|
402
|
+
// Update installed_plugins.json to point to new version
|
|
403
|
+
const installedPath = installedPluginsPath();
|
|
404
|
+
try {
|
|
405
|
+
const installed = readJson(installedPath);
|
|
406
|
+
if (installed && installed.plugins && installed.plugins[PLUGIN_ID]) {
|
|
407
|
+
installed.plugins[PLUGIN_ID][0].installPath = pluginDst;
|
|
408
|
+
installed.plugins[PLUGIN_ID][0].version = latest.version;
|
|
409
|
+
installed.plugins[PLUGIN_ID][0].lastUpdated = new Date().toISOString();
|
|
410
|
+
writeJsonAtomic(installedPath, installed);
|
|
411
|
+
}
|
|
412
|
+
} catch { /* not fatal */ }
|
|
413
|
+
|
|
414
|
+
// Update install manifest
|
|
415
|
+
try {
|
|
416
|
+
const manifest = readManifest();
|
|
417
|
+
manifest.version = latest.version;
|
|
418
|
+
manifest.updatedAt = new Date().toISOString();
|
|
419
|
+
writeJsonAtomic(path.join(CACHE_DIR, 'install-manifest.json'), manifest);
|
|
420
|
+
} catch { /* not fatal */ }
|
|
421
|
+
|
|
422
|
+
// Run the NEW lifecycle.js to update settings.json hooks with new paths.
|
|
423
|
+
// Without this, settings.json hooks still point to the old version directory
|
|
424
|
+
// until the next session's self-heal corrects them.
|
|
420
425
|
try {
|
|
421
426
|
const newLifecycle = path.join(pluginDst, 'scripts', 'lifecycle.js');
|
|
422
427
|
if (fs.existsSync(newLifecycle)) {
|
|
@@ -376,3 +376,57 @@ test('downloadAndInstall wires the marketplace refresh + binary download (orches
|
|
|
376
376
|
'code-graph-mcp', 'code-graph-mcp', '9.9.9', '.claude-plugin', 'plugin.json');
|
|
377
377
|
assert.equal(fs.existsSync(dst), true, 'plugin copied into sandbox plugins cache');
|
|
378
378
|
});
|
|
379
|
+
|
|
380
|
+
test('downloadAndInstall does NOT repoint install state when the plugin copy is skipped (version drift)', async (t) => {
|
|
381
|
+
// Guard for a silent-breakage bug: when the extracted tarball's plugin.json version
|
|
382
|
+
// doesn't match latest.version, the copy is skipped and pluginDst is never created.
|
|
383
|
+
// installed_plugins.json must NOT be advanced to that nonexistent dir, or Claude Code
|
|
384
|
+
// ends up pointed at a missing install while state reads "up to date".
|
|
385
|
+
const sandboxHome = mkDir(t, 'code-graph-dai-skip-');
|
|
386
|
+
const installedDir = path.join(sandboxHome, '.claude', 'plugins');
|
|
387
|
+
fs.mkdirSync(installedDir, { recursive: true });
|
|
388
|
+
const installedPath = path.join(installedDir, 'installed_plugins.json');
|
|
389
|
+
fs.writeFileSync(installedPath, JSON.stringify({
|
|
390
|
+
plugins: { 'code-graph-mcp@code-graph-mcp': [
|
|
391
|
+
{ installPath: '/old/install/path', version: '0.0.1', lastUpdated: 'seed' },
|
|
392
|
+
] },
|
|
393
|
+
}));
|
|
394
|
+
|
|
395
|
+
const script = `
|
|
396
|
+
const fs = require('fs');
|
|
397
|
+
const path = require('path');
|
|
398
|
+
const { downloadAndInstall } = require(${JSON.stringify(path.join(__dirname, 'auto-update.js'))});
|
|
399
|
+
const latest = { version: '9.9.9', tarballUrl: 'https://example/tar', binaryUrl: null };
|
|
400
|
+
const exec = (cmd, args) => {
|
|
401
|
+
if (cmd === 'tar') {
|
|
402
|
+
// Extract a claude-plugin/ whose version DRIFTS from latest → copy is skipped.
|
|
403
|
+
const tmpDir = args[args.indexOf('-C') + 1];
|
|
404
|
+
const mDir = path.join(tmpDir, 'claude-plugin', '.claude-plugin');
|
|
405
|
+
fs.mkdirSync(mDir, { recursive: true });
|
|
406
|
+
fs.writeFileSync(path.join(mDir, 'plugin.json'), JSON.stringify({ version: '0.0.0' }));
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
(async () => {
|
|
410
|
+
const result = await downloadAndInstall(latest, {
|
|
411
|
+
exec,
|
|
412
|
+
refreshMarketplace: () => true,
|
|
413
|
+
downloadBin: async () => true,
|
|
414
|
+
});
|
|
415
|
+
console.log(JSON.stringify({ result }));
|
|
416
|
+
})();
|
|
417
|
+
`;
|
|
418
|
+
const out = execGit(process.execPath, ['-e', script], {
|
|
419
|
+
env: { ...process.env, HOME: sandboxHome },
|
|
420
|
+
encoding: 'utf8',
|
|
421
|
+
});
|
|
422
|
+
const { result } = JSON.parse(out.trim().split('\n').pop());
|
|
423
|
+
assert.equal(result.pluginUpdated, false, 'version drift must skip the plugin copy');
|
|
424
|
+
|
|
425
|
+
// The pre-seeded record must be UNTOUCHED — not repointed to the 9.9.9 dir.
|
|
426
|
+
const rec = JSON.parse(fs.readFileSync(installedPath, 'utf8'))
|
|
427
|
+
.plugins['code-graph-mcp@code-graph-mcp'][0];
|
|
428
|
+
assert.equal(rec.installPath, '/old/install/path',
|
|
429
|
+
'installPath must not be repointed when the copy was skipped');
|
|
430
|
+
assert.equal(rec.version, '0.0.1',
|
|
431
|
+
'version must not be advanced when the copy was skipped');
|
|
432
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdsrs/code-graph",
|
|
3
|
-
"version": "0.76.
|
|
3
|
+
"version": "0.76.2",
|
|
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.76.
|
|
39
|
-
"@sdsrs/code-graph-linux-arm64": "0.76.
|
|
40
|
-
"@sdsrs/code-graph-darwin-x64": "0.76.
|
|
41
|
-
"@sdsrs/code-graph-darwin-arm64": "0.76.
|
|
42
|
-
"@sdsrs/code-graph-win32-x64": "0.76.
|
|
38
|
+
"@sdsrs/code-graph-linux-x64": "0.76.2",
|
|
39
|
+
"@sdsrs/code-graph-linux-arm64": "0.76.2",
|
|
40
|
+
"@sdsrs/code-graph-darwin-x64": "0.76.2",
|
|
41
|
+
"@sdsrs/code-graph-darwin-arm64": "0.76.2",
|
|
42
|
+
"@sdsrs/code-graph-win32-x64": "0.76.2"
|
|
43
43
|
}
|
|
44
44
|
}
|