synabun 2026.4.20-beta.4 → 2026.4.20-beta.6
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.
|
@@ -9818,6 +9818,57 @@ function buildUpdateCommand(toolKey, installSource) {
|
|
|
9818
9818
|
return `npm install -g ${npmPkg}@latest`;
|
|
9819
9819
|
}
|
|
9820
9820
|
|
|
9821
|
+
// Resolve SynaBun's own install roots so we can reject any tool binary that
|
|
9822
|
+
// lives inside our bundled node_modules — bulletproof guard for the recurring
|
|
9823
|
+
// phantom-version bug (e.g. stale @anthropic-ai/claude-code left over from
|
|
9824
|
+
// prior SynaBun installs that shipped it as a dependency, which `npm install`
|
|
9825
|
+
// does not auto-prune when removed from package.json).
|
|
9826
|
+
const SYNABUN_ROOTS = (() => {
|
|
9827
|
+
const roots = new Set();
|
|
9828
|
+
try { roots.add(realpathSync(__dirname).replace(/\\/g, '/').toLowerCase()); } catch {}
|
|
9829
|
+
try { roots.add(realpathSync(resolve(__dirname, '..')).replace(/\\/g, '/').toLowerCase()); } catch {}
|
|
9830
|
+
return [...roots];
|
|
9831
|
+
})();
|
|
9832
|
+
|
|
9833
|
+
function isInsideSynabun(binPath) {
|
|
9834
|
+
if (!binPath) return false;
|
|
9835
|
+
try {
|
|
9836
|
+
const resolved = realpathSync(binPath).replace(/\\/g, '/').toLowerCase();
|
|
9837
|
+
return SYNABUN_ROOTS.some(root => resolved.startsWith(root + '/'));
|
|
9838
|
+
} catch {
|
|
9839
|
+
const norm = binPath.replace(/\\/g, '/').toLowerCase();
|
|
9840
|
+
return SYNABUN_ROOTS.some(root => norm.startsWith(root + '/'));
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
|
|
9844
|
+
// Aggressively delete any stale bundled CLI tool packages left over in our
|
|
9845
|
+
// own node_modules. Idempotent — runs on every startup. Belt-and-suspenders
|
|
9846
|
+
// against `npm install` not auto-pruning packages removed from package.json.
|
|
9847
|
+
function pruneBundledCliTools() {
|
|
9848
|
+
const stalePkgs = ['@anthropic-ai/claude-code', '@openai/codex', 'opencode-ai', '@google/gemini-cli'];
|
|
9849
|
+
const moduleRoots = [
|
|
9850
|
+
join(__dirname, 'node_modules'),
|
|
9851
|
+
join(__dirname, '..', 'node_modules'),
|
|
9852
|
+
];
|
|
9853
|
+
for (const root of moduleRoots) {
|
|
9854
|
+
for (const pkg of stalePkgs) {
|
|
9855
|
+
const target = join(root, pkg);
|
|
9856
|
+
try {
|
|
9857
|
+
if (existsSync(target)) {
|
|
9858
|
+
rmSync(target, { recursive: true, force: true });
|
|
9859
|
+
console.log(` Pruned stale bundled CLI: ${target}`);
|
|
9860
|
+
}
|
|
9861
|
+
} catch { /* permission or in-use — ignore */ }
|
|
9862
|
+
// Also remove .bin shims that point at the deleted package
|
|
9863
|
+
const binBase = pkg.split('/').pop().replace(/-cli$|-ai$/, '');
|
|
9864
|
+
for (const ext of ['', '.cmd', '.ps1', '.exe']) {
|
|
9865
|
+
const shim = join(root, '.bin', binBase + ext);
|
|
9866
|
+
try { if (existsSync(shim)) rmSync(shim, { force: true }); } catch {}
|
|
9867
|
+
}
|
|
9868
|
+
}
|
|
9869
|
+
}
|
|
9870
|
+
}
|
|
9871
|
+
|
|
9821
9872
|
async function checkToolVersions() {
|
|
9822
9873
|
// Strip node_modules/.bin entries so the version check reflects the user's
|
|
9823
9874
|
// global install rather than any copy bundled with SynaBun itself.
|
|
@@ -9831,11 +9882,20 @@ async function checkToolVersions() {
|
|
|
9831
9882
|
const results = {};
|
|
9832
9883
|
|
|
9833
9884
|
for (const tool of TOOL_DEFS) {
|
|
9885
|
+
// Resolve binary path FIRST. If it lives inside SynaBun's own install
|
|
9886
|
+
// dir (stale bundled copy), treat the tool as not installed — do NOT
|
|
9887
|
+
// run --version against it, since that would report the bundled
|
|
9888
|
+
// version and trigger a false-positive update badge.
|
|
9889
|
+
const probedBinPath = resolveBinPath(tool.cmd, cleanEnv);
|
|
9890
|
+
const isStaleBundle = isInsideSynabun(probedBinPath);
|
|
9891
|
+
|
|
9834
9892
|
let installed = null;
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9893
|
+
if (!isStaleBundle) {
|
|
9894
|
+
try {
|
|
9895
|
+
const raw = execSync(`${tool.cmd} ${tool.versionArg}`, execOpts).trim();
|
|
9896
|
+
installed = parseVersion(raw);
|
|
9897
|
+
} catch { /* not installed or errored */ }
|
|
9898
|
+
}
|
|
9839
9899
|
|
|
9840
9900
|
let latest = null;
|
|
9841
9901
|
try {
|
|
@@ -9852,7 +9912,7 @@ async function checkToolVersions() {
|
|
|
9852
9912
|
}
|
|
9853
9913
|
} catch { /* network error */ }
|
|
9854
9914
|
|
|
9855
|
-
const binPath = installed ?
|
|
9915
|
+
const binPath = installed ? probedBinPath : null;
|
|
9856
9916
|
const installSource = detectInstallSource(binPath);
|
|
9857
9917
|
const updateCommand = installed ? buildUpdateCommand(tool.key, installSource) : null;
|
|
9858
9918
|
|
|
@@ -21082,6 +21142,12 @@ const httpServer = app.listen(PORT, async () => {
|
|
|
21082
21142
|
// Check for npm updates
|
|
21083
21143
|
try { await checkNpmUpdate(); } catch {}
|
|
21084
21144
|
|
|
21145
|
+
// Aggressively prune any stale bundled CLI tools left in our node_modules
|
|
21146
|
+
// before the version check runs — defends against `npm install` not auto-
|
|
21147
|
+
// pruning packages that were removed from package.json (recurring source of
|
|
21148
|
+
// phantom-version badges, e.g. v2.1.89 from a stale @anthropic-ai/claude-code).
|
|
21149
|
+
try { pruneBundledCliTools(); } catch {}
|
|
21150
|
+
|
|
21085
21151
|
// Check for CLI tool updates
|
|
21086
21152
|
try { await checkToolVersions(); } catch {}
|
|
21087
21153
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synabun",
|
|
3
|
-
"version": "2026.4.20-beta.
|
|
3
|
+
"version": "2026.4.20-beta.6",
|
|
4
4
|
"description": "Persistent vector memory for AI assistants",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "The SynaBun Authors",
|
|
@@ -59,8 +59,5 @@
|
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": ">=22.0.0"
|
|
62
|
-
},
|
|
63
|
-
"dependencies": {
|
|
64
|
-
"@anthropic-ai/claude-code": "^2.1.91"
|
|
65
62
|
}
|
|
66
63
|
}
|