@sdsrs/code-graph 0.45.2 → 0.45.4

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.45.2",
7
+ "version": "0.45.4",
8
8
  "keywords": [
9
9
  "code-graph",
10
10
  "ast",
@@ -367,6 +367,19 @@ async function downloadAndInstall(latest) {
367
367
 
368
368
  // ── Main Entry ─────────────────────────────────────────────
369
369
 
370
+ /**
371
+ * Self-heal the cached native binary when the plugin shell is already at latest
372
+ * but the binary lags (missing OR a different version). This is the orchestration
373
+ * glue that broke twice in the field (v0.45.1, v0.45.2): the decision predicate
374
+ * was correct, but nothing guaranteed checkForUpdate actually invoked the download
375
+ * on the shell-matches-latest path. Extracted + injectable so the wiring itself is
376
+ * regression-tested, not just the predicate. Returns true iff a download promoted.
377
+ */
378
+ async function selfHealStaleBinary(latest, { needsUpdate = cachedBinaryNeedsUpdate, download = downloadBinary } = {}) {
379
+ if (!needsUpdate(latest)) return false;
380
+ return await download(latest);
381
+ }
382
+
370
383
  async function checkForUpdate({ installMissing = false } = {}) {
371
384
  try {
372
385
  // Skip in dev mode — unless the launcher explicitly requested a missing-
@@ -431,14 +444,10 @@ async function checkForUpdate({ installMissing = false } = {}) {
431
444
  }
432
445
 
433
446
  // No plugin-shell update — but self-heal the native binary if it is missing
434
- // OR stale. The shell version (manifest.version) can match latest while the
435
- // cached binary lags (a previous download failed silently, the cache was
436
- // wiped, an `npm install -g` optionalDependency dropped the platform package,
437
- // or the marketplace bumped the shell without re-fetching the binary).
438
- let selfHealedBinary = false;
439
- if (cachedBinaryNeedsUpdate(latest)) {
440
- selfHealedBinary = await downloadBinary(latest);
441
- }
447
+ // OR stale (see selfHealStaleBinary). The shell version (manifest.version)
448
+ // can match latest while the cached binary lags this is exactly the wild
449
+ // failure observed in the field (shell at v0.45, binary pinned at v0.16.6).
450
+ const selfHealedBinary = await selfHealStaleBinary(latest);
442
451
 
443
452
  saveState({
444
453
  ...state,
@@ -464,6 +473,7 @@ module.exports = {
464
473
  isSilentMode, isInstallMissingMode,
465
474
  requestJson, parseLatestRelease, fetchLatestRelease,
466
475
  downloadBinary, cachedBinaryPath, cachedBinaryNeedsUpdate, cachedBinaryStaleVsState,
476
+ selfHealStaleBinary,
467
477
  };
468
478
 
469
479
  // CLI: node auto-update.js [check|status] [--silent] [--install-missing]
@@ -16,6 +16,7 @@ const {
16
16
  cachedBinaryNeedsUpdate,
17
17
  cachedBinaryStaleVsState,
18
18
  downloadBinary,
19
+ selfHealStaleBinary,
19
20
  isInstallMissingMode,
20
21
  isSilentMode,
21
22
  } = require('./auto-update');
@@ -143,6 +144,35 @@ test('cachedBinaryStaleVsState bypasses throttle only for a present-but-stale bi
143
144
  assert.equal(cachedBinaryStaleVsState({ latestVersion: '0.45.1' }, { binaryPath }), false);
144
145
  });
145
146
 
147
+ test('selfHealStaleBinary wires the stale-binary check to a download (the v0.45.x glue)', async () => {
148
+ const latest = { version: '0.45.2', binaryUrl: 'https://example/bin' };
149
+
150
+ // Field failure mode: shell already at latest, binary pinned stale → MUST download.
151
+ let downloaded = false;
152
+ const healed = await selfHealStaleBinary(latest, {
153
+ needsUpdate: () => true,
154
+ download: async () => { downloaded = true; return true; },
155
+ });
156
+ assert.equal(downloaded, true, 'stale binary must trigger a download');
157
+ assert.equal(healed, true);
158
+
159
+ // Binary current → no download, no-op.
160
+ let touched = false;
161
+ const noop = await selfHealStaleBinary(latest, {
162
+ needsUpdate: () => false,
163
+ download: async () => { touched = true; return true; },
164
+ });
165
+ assert.equal(touched, false, 'current binary must not download');
166
+ assert.equal(noop, false);
167
+
168
+ // Download fails (no curl / network) → returns false so the next session retries.
169
+ const failed = await selfHealStaleBinary(latest, {
170
+ needsUpdate: () => true,
171
+ download: async () => false,
172
+ });
173
+ assert.equal(failed, false);
174
+ });
175
+
146
176
  test('parseLatestRelease selects the matching platform asset', () => {
147
177
  const latest = parseLatestRelease({
148
178
  tag_name: 'v1.2.3',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdsrs/code-graph",
3
- "version": "0.45.2",
3
+ "version": "0.45.4",
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.45.2",
39
- "@sdsrs/code-graph-linux-arm64": "0.45.2",
40
- "@sdsrs/code-graph-darwin-x64": "0.45.2",
41
- "@sdsrs/code-graph-darwin-arm64": "0.45.2",
42
- "@sdsrs/code-graph-win32-x64": "0.45.2"
38
+ "@sdsrs/code-graph-linux-x64": "0.45.4",
39
+ "@sdsrs/code-graph-linux-arm64": "0.45.4",
40
+ "@sdsrs/code-graph-darwin-x64": "0.45.4",
41
+ "@sdsrs/code-graph-darwin-arm64": "0.45.4",
42
+ "@sdsrs/code-graph-win32-x64": "0.45.4"
43
43
  }
44
44
  }