baychat 0.25.0 → 0.25.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.
- package/dist/commands.js +4 -3
- package/dist/main.js +2 -1
- package/dist/self-upgrade.js +232 -0
- package/dist/update-command.js +54 -29
- package/package.json +1 -1
package/dist/commands.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.realConfigIo = exports.CATCHUP_UNTRUSTED_REMINDER = void 0;
|
|
6
|
+
exports.realConfigIo = exports.WINDOWS_UNSAFE = exports.CATCHUP_UNTRUSTED_REMINDER = void 0;
|
|
7
7
|
exports.requireCredentials = requireCredentials;
|
|
8
8
|
exports.cmdPair = cmdPair;
|
|
9
9
|
exports.cmdWhoami = cmdWhoami;
|
|
@@ -18,6 +18,7 @@ exports.resetSessionState = resetSessionState;
|
|
|
18
18
|
exports.cmdCheck = cmdCheck;
|
|
19
19
|
exports.cmdWatch = cmdWatch;
|
|
20
20
|
exports.cmdLink = cmdLink;
|
|
21
|
+
exports.quoteForCmd = quoteForCmd;
|
|
21
22
|
exports.claudeMcpAddSpawn = claudeMcpAddSpawn;
|
|
22
23
|
exports.registerWithClaude = registerWithClaude;
|
|
23
24
|
exports.cmdLogin = cmdLogin;
|
|
@@ -583,7 +584,7 @@ function quoteForCmd(arg) {
|
|
|
583
584
|
* quoted, and `!` only expands under delayed expansion, which `cmd /d /s /c` —
|
|
584
585
|
* what Node's `shell: true` invokes — does not enable.
|
|
585
586
|
*/
|
|
586
|
-
|
|
587
|
+
exports.WINDOWS_UNSAFE = /["%\u0000-\u001f\u007f]/;
|
|
587
588
|
/**
|
|
588
589
|
* The spawn recipe for `claude mcp add`, or null when it cannot be run safely.
|
|
589
590
|
*
|
|
@@ -620,7 +621,7 @@ function claudeMcpAddSpawn(platform, baseUrl, token) {
|
|
|
620
621
|
];
|
|
621
622
|
if (platform !== "win32")
|
|
622
623
|
return { command: "claude", args, shell: false };
|
|
623
|
-
if (args.some((a) => WINDOWS_UNSAFE.test(a)))
|
|
624
|
+
if (args.some((a) => exports.WINDOWS_UNSAFE.test(a)))
|
|
624
625
|
return null;
|
|
625
626
|
return { command: "claude", args: args.map(quoteForCmd), shell: true };
|
|
626
627
|
}
|
package/dist/main.js
CHANGED
|
@@ -217,7 +217,8 @@ async function main() {
|
|
|
217
217
|
case "start":
|
|
218
218
|
return (0, start_command_1.cmdStart)(args);
|
|
219
219
|
case "update":
|
|
220
|
-
|
|
220
|
+
// `--quiet` is how an old version hands a `start`-driven update to the new one.
|
|
221
|
+
return (0, update_command_1.cmdUpdate)({ quiet: args.includes("--quiet") });
|
|
221
222
|
case "skill": {
|
|
222
223
|
const runtime = args[1];
|
|
223
224
|
if (args.length !== 2 ||
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolveEntry = resolveEntry;
|
|
37
|
+
exports.currentEntry = currentEntry;
|
|
38
|
+
exports.classifyInstall = classifyInstall;
|
|
39
|
+
exports.compareVersions = compareVersions;
|
|
40
|
+
exports.upgradePackage = upgradePackage;
|
|
41
|
+
exports.describeOutcome = describeOutcome;
|
|
42
|
+
exports.realNpm = realNpm;
|
|
43
|
+
exports.readPackageVersion = readPackageVersion;
|
|
44
|
+
exports.packageEntry = packageEntry;
|
|
45
|
+
exports.ownVersion = ownVersion;
|
|
46
|
+
const child_process_1 = require("child_process");
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const commands_1 = require("./commands");
|
|
50
|
+
/** A path as the filesystem sees it: every symlink on the way resolved. */
|
|
51
|
+
function resolveEntry(file) {
|
|
52
|
+
try {
|
|
53
|
+
return fs.realpathSync(file);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Unresolvable (deleted under us, a permission on a parent). The path as given is still
|
|
57
|
+
// the best evidence there is, and classifying it honestly beats throwing mid-update.
|
|
58
|
+
return file;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The entry file of THIS running CLI. `__dirname` rather than argv: it is where the executing
|
|
63
|
+
* code actually lives, and Node has already resolved symlinks to get it (resolved again here
|
|
64
|
+
* for `--preserve-symlinks`).
|
|
65
|
+
*/
|
|
66
|
+
function currentEntry() {
|
|
67
|
+
return resolveEntry(path.join(__dirname, "index.js"));
|
|
68
|
+
}
|
|
69
|
+
function classifyInstall(entry, platform = process.platform) {
|
|
70
|
+
const p = platform === "win32" ? path.win32 : path.posix;
|
|
71
|
+
const parts = entry.split(/[\\/]+/);
|
|
72
|
+
if (parts.includes("_npx"))
|
|
73
|
+
return { kind: "npx", entry };
|
|
74
|
+
const at = parts.lastIndexOf("node_modules");
|
|
75
|
+
if (at < 0 || parts[at + 1] !== "baychat")
|
|
76
|
+
return { kind: "source", entry };
|
|
77
|
+
const modules = parts.slice(0, at + 1).join(p.sep);
|
|
78
|
+
const packageRoot = p.join(modules, "baychat");
|
|
79
|
+
if (platform === "win32") {
|
|
80
|
+
return { kind: "global", entry, packageRoot, prefix: p.dirname(modules) };
|
|
81
|
+
}
|
|
82
|
+
const lib = p.dirname(modules);
|
|
83
|
+
if (p.basename(lib) === "lib")
|
|
84
|
+
return { kind: "global", entry, packageRoot, prefix: p.dirname(lib) };
|
|
85
|
+
return { kind: "local", entry, packageRoot };
|
|
86
|
+
}
|
|
87
|
+
/** -1, 0, 1 for dotted numeric versions; undefined when either will not parse. */
|
|
88
|
+
function compareVersions(a, b) {
|
|
89
|
+
const parse = (v) => (/^\d+(\.\d+)*$/.test(v) ? v.split(".").map(Number) : undefined);
|
|
90
|
+
const x = parse(a);
|
|
91
|
+
const y = parse(b);
|
|
92
|
+
if (!x || !y)
|
|
93
|
+
return undefined;
|
|
94
|
+
for (let i = 0; i < Math.max(x.length, y.length); i++) {
|
|
95
|
+
const d = (x[i] ?? 0) - (y[i] ?? 0);
|
|
96
|
+
if (d !== 0)
|
|
97
|
+
return d < 0 ? -1 : 1;
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
const VIEW_TIMEOUT_MS = 30_000;
|
|
102
|
+
const INSTALL_TIMEOUT_MS = 180_000;
|
|
103
|
+
/** Upgrade the running package where it can be upgraded, and say exactly what happened. */
|
|
104
|
+
function upgradePackage(deps) {
|
|
105
|
+
const { install, current } = deps;
|
|
106
|
+
if (install.kind === "npx")
|
|
107
|
+
return { outcome: "npx", current };
|
|
108
|
+
if (install.kind === "local")
|
|
109
|
+
return { outcome: "local", current, packageRoot: install.packageRoot };
|
|
110
|
+
if (install.kind === "source")
|
|
111
|
+
return { outcome: "source", current, entry: install.entry };
|
|
112
|
+
// Ask first, install only when there is something newer. Besides saving a slow npm run a
|
|
113
|
+
// day, this is what lets a machine whose global folder needs sudo finish `baychat update`
|
|
114
|
+
// after the one `sudo npm i -g` — otherwise every run would retry the write and fail.
|
|
115
|
+
const view = deps.npm(["view", "baychat", "version"], VIEW_TIMEOUT_MS);
|
|
116
|
+
const latest = view.stdout.trim();
|
|
117
|
+
if (view.error || view.status !== 0 || !/^\d+\.\d+\.\d+$/.test(latest)) {
|
|
118
|
+
return { outcome: "unchecked", current, reason: npmFailure(view) };
|
|
119
|
+
}
|
|
120
|
+
const order = compareVersions(current, latest);
|
|
121
|
+
if (order === 0 || order === 1)
|
|
122
|
+
return { outcome: "current", current };
|
|
123
|
+
// `--prefer-online`: `npm view` above always revalidates, but `install` trusts a cached
|
|
124
|
+
// packument for its max-age (~5 minutes). Straight after a publish — exactly when people run
|
|
125
|
+
// `update` — that cache can predate the version view just named, and install dies ETARGET.
|
|
126
|
+
const result = deps.npm(["install", "--global", "--prefer-online", "--prefix", install.prefix, `baychat@${latest}`], INSTALL_TIMEOUT_MS);
|
|
127
|
+
if (result.error || result.status !== 0) {
|
|
128
|
+
const denied = /\b(EACCES|EPERM)\b/.test(`${result.stderr}\n${result.error?.message ?? ""}`);
|
|
129
|
+
const reason = denied
|
|
130
|
+
? `npm is not allowed to write to ${install.prefix}. Run \`${sudoHint(deps, install.prefix)}\` ` +
|
|
131
|
+
"(or give npm a folder you own: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally), " +
|
|
132
|
+
"then `baychat update` again."
|
|
133
|
+
: npmFailure(result);
|
|
134
|
+
return { outcome: "failed", current, reason };
|
|
135
|
+
}
|
|
136
|
+
// npm said yes. Believe the file on disk, not the exit code: this is the very step that
|
|
137
|
+
// used to report success over an unchanged install.
|
|
138
|
+
const onDisk = deps.readVersion(install.packageRoot);
|
|
139
|
+
if (onDisk !== latest) {
|
|
140
|
+
return {
|
|
141
|
+
outcome: "failed",
|
|
142
|
+
current,
|
|
143
|
+
reason: `npm reported success, but ${install.packageRoot} holds ${onDisk ?? "no readable package.json"}, not ${latest}.`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return { outcome: "upgraded", from: current, to: onDisk, packageRoot: install.packageRoot };
|
|
147
|
+
}
|
|
148
|
+
/** What a person reads for each outcome. `ok: false` means: do not claim this machine is updated. */
|
|
149
|
+
function describeOutcome(o) {
|
|
150
|
+
switch (o.outcome) {
|
|
151
|
+
case "npx":
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
note: `This is an npx copy of baychat ${o.current}, and npx can keep running a cached older one. Use \`npx baychat@latest\` (or install it once with \`npm i -g baychat\`) so updates land.`,
|
|
155
|
+
};
|
|
156
|
+
case "local":
|
|
157
|
+
return {
|
|
158
|
+
ok: true,
|
|
159
|
+
note: `baychat ${o.current} is installed inside a project (${o.packageRoot}), so update it there with \`npm i baychat@latest\`. The package was left alone.`,
|
|
160
|
+
};
|
|
161
|
+
case "source":
|
|
162
|
+
return {
|
|
163
|
+
ok: true,
|
|
164
|
+
note: `baychat ${o.current} is running from ${o.entry}, not from an npm install, so the package was left alone. Rebuild that checkout to update it.`,
|
|
165
|
+
};
|
|
166
|
+
case "unchecked":
|
|
167
|
+
return { ok: true, note: `Could not ask npm for the latest baychat (${o.reason}). The package stays at ${o.current}.` };
|
|
168
|
+
case "current":
|
|
169
|
+
return { ok: true, done: `baychat ${o.current} is the latest` };
|
|
170
|
+
case "upgraded":
|
|
171
|
+
return { ok: true, done: `upgraded baychat ${o.from} → ${o.to}` };
|
|
172
|
+
case "failed":
|
|
173
|
+
return {
|
|
174
|
+
ok: false,
|
|
175
|
+
note: `Could not upgrade baychat ${o.current}: ${o.reason}\nNothing else was changed, and the relay was NOT upgraded: it is still running ${o.current}.`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function sudoHint(deps, prefix) {
|
|
180
|
+
// Plain `sudo npm i -g` is only right when npm's own global prefix IS this install's.
|
|
181
|
+
const own = deps.npm(["prefix", "--global"], VIEW_TIMEOUT_MS);
|
|
182
|
+
const ownPrefix = !own.error && own.status === 0 ? own.stdout.trim() : "";
|
|
183
|
+
return ownPrefix && resolveEntry(ownPrefix) === resolveEntry(prefix)
|
|
184
|
+
? "sudo npm i -g baychat@latest"
|
|
185
|
+
: `sudo npm i -g --prefix ${prefix} baychat@latest`;
|
|
186
|
+
}
|
|
187
|
+
function npmFailure(r) {
|
|
188
|
+
if (r.error) {
|
|
189
|
+
return r.error.code === "ENOENT" ? "npm was not found on PATH" : r.error.message;
|
|
190
|
+
}
|
|
191
|
+
const lines = r.stderr.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
192
|
+
return lines.slice(-3).join(" ") || `npm exited with ${r.status}`;
|
|
193
|
+
}
|
|
194
|
+
/** Run npm for real. Windows' npm is a `.cmd` shim, which Node will only start through a shell. */
|
|
195
|
+
function realNpm(args, timeoutMs) {
|
|
196
|
+
const windows = process.platform === "win32";
|
|
197
|
+
if (windows && args.some((a) => commands_1.WINDOWS_UNSAFE.test(a))) {
|
|
198
|
+
return { status: null, stdout: "", stderr: "", error: new Error("a path npm needs cannot be passed safely through cmd.exe") };
|
|
199
|
+
}
|
|
200
|
+
const r = (0, child_process_1.spawnSync)("npm", windows ? args.map(commands_1.quoteForCmd) : args, {
|
|
201
|
+
encoding: "utf8",
|
|
202
|
+
timeout: timeoutMs,
|
|
203
|
+
shell: windows,
|
|
204
|
+
});
|
|
205
|
+
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "", error: r.error };
|
|
206
|
+
}
|
|
207
|
+
function readPackageVersion(packageRoot) {
|
|
208
|
+
try {
|
|
209
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
210
|
+
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** The CLI entry a package root declares, for handing the rest of `update` to the new code. */
|
|
217
|
+
function packageEntry(packageRoot) {
|
|
218
|
+
try {
|
|
219
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
220
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.baychat;
|
|
221
|
+
if (typeof bin === "string")
|
|
222
|
+
return path.join(packageRoot, bin);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Fall through to the layout every published version has had.
|
|
226
|
+
}
|
|
227
|
+
return path.join(packageRoot, "dist", "index.js");
|
|
228
|
+
}
|
|
229
|
+
/** The version of the code that is executing right now. */
|
|
230
|
+
function ownVersion() {
|
|
231
|
+
return require("../package.json").version;
|
|
232
|
+
}
|
package/dist/update-command.js
CHANGED
|
@@ -43,6 +43,7 @@ const credential_refresh_1 = require("./credential-refresh");
|
|
|
43
43
|
const commands_1 = require("./commands");
|
|
44
44
|
const client_paths_1 = require("./client-paths");
|
|
45
45
|
const commands_2 = require("./relay/commands");
|
|
46
|
+
const self_upgrade_1 = require("./self-upgrade");
|
|
46
47
|
/**
|
|
47
48
|
* `baychat update` — bring this whole machine onto the current version, in one word.
|
|
48
49
|
*
|
|
@@ -85,11 +86,42 @@ async function cmdUpdate(opts = {}) {
|
|
|
85
86
|
return 1;
|
|
86
87
|
}
|
|
87
88
|
const done = [];
|
|
88
|
-
// 1. THE PACKAGE
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
done.push(
|
|
89
|
+
// 1. THE PACKAGE, and it goes first because everything after it should run on the NEW code.
|
|
90
|
+
const upgradedFrom = takeUpgradedFrom();
|
|
91
|
+
if (upgradedFrom) {
|
|
92
|
+
// We are the new version, started by the old one straight after it installed us.
|
|
93
|
+
done.push(`upgraded baychat ${upgradedFrom} → ${(0, self_upgrade_1.ownVersion)()}`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const outcome = (0, self_upgrade_1.upgradePackage)({
|
|
97
|
+
install: (0, self_upgrade_1.classifyInstall)((0, self_upgrade_1.currentEntry)()),
|
|
98
|
+
current: (0, self_upgrade_1.ownVersion)(),
|
|
99
|
+
npm: self_upgrade_1.realNpm,
|
|
100
|
+
readVersion: self_upgrade_1.readPackageVersion,
|
|
101
|
+
});
|
|
102
|
+
const told = (0, self_upgrade_1.describeOutcome)(outcome);
|
|
103
|
+
if (!told.ok) {
|
|
104
|
+
// Never "Updated this machine" over a package that did not move. Stop before the relay
|
|
105
|
+
// restart too: restarting it would only relaunch the same old code and look like progress.
|
|
106
|
+
console.error(told.note);
|
|
107
|
+
writeStamp(); // a daily retry from `start`, not one on every start
|
|
108
|
+
return 1;
|
|
109
|
+
}
|
|
110
|
+
if (told.note)
|
|
111
|
+
say(told.note);
|
|
112
|
+
if (outcome.outcome === "upgraded") {
|
|
113
|
+
// THIS process is still the old code, loaded before npm replaced the files. Hand the
|
|
114
|
+
// rest of the update — client configs, Claude registration, the relay unit and restart
|
|
115
|
+
// — to the version just installed, so each is written by the code that will run it.
|
|
116
|
+
const handedOff = runOnNewCode(outcome.packageRoot, outcome.from, !!opts.quiet);
|
|
117
|
+
if (handedOff !== undefined)
|
|
118
|
+
return handedOff;
|
|
119
|
+
// Could not start it. The relay is still restarted below from the same path, which
|
|
120
|
+
// now holds the new files, so the upgrade itself still lands.
|
|
121
|
+
}
|
|
122
|
+
if (told.done)
|
|
123
|
+
done.push(told.done);
|
|
124
|
+
}
|
|
93
125
|
// 2. EVERY CONNECTED CLIENT's copy of the credential and endpoint.
|
|
94
126
|
try {
|
|
95
127
|
const updated = (0, credential_refresh_1.refreshExistingClientConfigs)({ url: `${device.baseUrl}/api/mcp`, token: device.token }, commands_1.realConfigIo, (0, client_paths_1.currentPathEnv)());
|
|
@@ -163,34 +195,27 @@ function writeStamp() {
|
|
|
163
195
|
}
|
|
164
196
|
}
|
|
165
197
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* npx resolves from its own cache, so `npx baychat` can keep running a version from weeks
|
|
170
|
-
* ago while reporting success at every step. The honest output there is the one flag that
|
|
171
|
-
* fixes it.
|
|
198
|
+
* Set by the OLD version when it hands the rest of `update` to the version it just installed:
|
|
199
|
+
* the version it upgraded from, for the report. Read once and cleared, so nothing this process
|
|
200
|
+
* starts afterwards inherits it.
|
|
172
201
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
202
|
+
const UPGRADED_FROM_ENV = "BAYCHAT_UPGRADED_FROM";
|
|
203
|
+
function takeUpgradedFrom() {
|
|
204
|
+
const value = process.env[UPGRADED_FROM_ENV];
|
|
205
|
+
delete process.env[UPGRADED_FROM_ENV];
|
|
206
|
+
return value && /^\d+\.\d+\.\d+$/.test(value) ? value : undefined;
|
|
207
|
+
}
|
|
208
|
+
/** Finish `update` in the newly installed version. Its exit status, or undefined if it never ran. */
|
|
209
|
+
function runOnNewCode(packageRoot, from, quiet) {
|
|
210
|
+
const child = (0, child_process_1.spawnSync)(process.execPath, [(0, self_upgrade_1.packageEntry)(packageRoot), "update", ...(quiet ? ["--quiet"] : [])], {
|
|
211
|
+
stdio: "inherit",
|
|
212
|
+
env: { ...process.env, [UPGRADED_FROM_ENV]: from },
|
|
182
213
|
});
|
|
183
|
-
if (
|
|
184
|
-
console.log(` Could not
|
|
214
|
+
if (child.error) {
|
|
215
|
+
console.log(` Could not start the new version (${errText(child.error)}); finishing the update from this one.`);
|
|
185
216
|
return undefined;
|
|
186
217
|
}
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
/** Is this process running from a global npm install, rather than an npx cache? */
|
|
190
|
-
function isGlobalInstall() {
|
|
191
|
-
const self = process.argv[1] ?? "";
|
|
192
|
-
// npx unpacks into `_npx` inside the npm cache; a global install never does.
|
|
193
|
-
return self.includes("node_modules") && !self.includes("_npx");
|
|
218
|
+
return child.status ?? 1;
|
|
194
219
|
}
|
|
195
220
|
function hasBinary(name) {
|
|
196
221
|
const probe = (0, child_process_1.spawnSync)(name, ["--version"], { stdio: "ignore", timeout: 15_000 });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baychat",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.2",
|
|
4
4
|
"description": "BayChat connector CLI — pair an agent session (Claude Code, Codex, Cursor) with BayChat, or have the relay run DeepSeek or the Cursor CLI for you",
|
|
5
5
|
"bin": {
|
|
6
6
|
"baychat": "dist/index.js"
|