codeam-cli 2.65.10 → 2.65.11
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/index.js +190 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8079,7 +8079,7 @@ function readAnonId() {
|
|
|
8079
8079
|
}
|
|
8080
8080
|
function superProperties() {
|
|
8081
8081
|
return {
|
|
8082
|
-
cliVersion: true ? "2.65.
|
|
8082
|
+
cliVersion: true ? "2.65.11" : "0.0.0-dev",
|
|
8083
8083
|
nodeVersion: process.version,
|
|
8084
8084
|
platform: process.platform,
|
|
8085
8085
|
arch: process.arch,
|
|
@@ -8321,7 +8321,7 @@ var http = __toESM(require("http"));
|
|
|
8321
8321
|
// package.json
|
|
8322
8322
|
var package_default = {
|
|
8323
8323
|
name: "codeam-cli",
|
|
8324
|
-
version: "2.65.
|
|
8324
|
+
version: "2.65.11",
|
|
8325
8325
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
8326
8326
|
type: "commonjs",
|
|
8327
8327
|
main: "dist/index.js",
|
|
@@ -9542,12 +9542,30 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9542
9542
|
this.connectSSE();
|
|
9543
9543
|
}
|
|
9544
9544
|
}
|
|
9545
|
+
/**
|
|
9546
|
+
* Stop the relay. Kept SYNCHRONOUS for the many callers that just tear down
|
|
9547
|
+
* — the goodbye heartbeat is fired but NOT awaited here.
|
|
9548
|
+
*
|
|
9549
|
+
* ⚠️ On a shutdown path that calls `process.exit()` right after, use
|
|
9550
|
+
* {@link stopAndFlush} (or {@link stopRelayWithGoodbye}) instead: the process
|
|
9551
|
+
* dies before the fire-and-forget POST hits the wire, so the backend never
|
|
9552
|
+
* learns the CLI went away and mobile keeps showing the session ONLINE until
|
|
9553
|
+
* the 30 s Redis heartbeat key expires — silently, since nothing publishes on
|
|
9554
|
+
* expiry (the 2026-08-18 "closing Claude Code leaves mobile online" report).
|
|
9555
|
+
*/
|
|
9545
9556
|
stop() {
|
|
9557
|
+
void this.stopAndFlush();
|
|
9558
|
+
}
|
|
9559
|
+
/**
|
|
9560
|
+
* Same teardown as {@link stop}, but resolves only once the `online:false`
|
|
9561
|
+
* heartbeat POST has settled — so a caller can `await` it before exiting.
|
|
9562
|
+
* Never rejects (`sendHeartbeat` swallows its own transport errors).
|
|
9563
|
+
*/
|
|
9564
|
+
async stopAndFlush() {
|
|
9546
9565
|
if (!this._running) return;
|
|
9547
9566
|
this._running = false;
|
|
9548
9567
|
this.cleanup();
|
|
9549
|
-
this.sendHeartbeat(false)
|
|
9550
|
-
});
|
|
9568
|
+
await this.sendHeartbeat(false);
|
|
9551
9569
|
}
|
|
9552
9570
|
async sendResult(commandId, status2, result) {
|
|
9553
9571
|
if (this.pairingInvalid) return;
|
|
@@ -9824,7 +9842,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9824
9842
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
9825
9843
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
9826
9844
|
// pair/reconnect). Older backends ignore the extra field.
|
|
9827
|
-
..."2.65.
|
|
9845
|
+
..."2.65.11" ? { ideVersion: "2.65.11" } : {}
|
|
9828
9846
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
9829
9847
|
}
|
|
9830
9848
|
/**
|
|
@@ -9905,6 +9923,21 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9905
9923
|
}
|
|
9906
9924
|
}
|
|
9907
9925
|
};
|
|
9926
|
+
var RELAY_GOODBYE_TIMEOUT_MS = 1500;
|
|
9927
|
+
async function stopRelayWithGoodbye(relay, timeoutMs = RELAY_GOODBYE_TIMEOUT_MS) {
|
|
9928
|
+
let timer;
|
|
9929
|
+
try {
|
|
9930
|
+
await Promise.race([
|
|
9931
|
+
relay.stopAndFlush(),
|
|
9932
|
+
new Promise((resolve10) => {
|
|
9933
|
+
timer = setTimeout(resolve10, timeoutMs);
|
|
9934
|
+
})
|
|
9935
|
+
]);
|
|
9936
|
+
} catch {
|
|
9937
|
+
} finally {
|
|
9938
|
+
if (timer) clearTimeout(timer);
|
|
9939
|
+
}
|
|
9940
|
+
}
|
|
9908
9941
|
|
|
9909
9942
|
// src/services/file-watcher.service.ts
|
|
9910
9943
|
var import_child_process4 = require("child_process");
|
|
@@ -21753,7 +21786,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
21753
21786
|
if (process.env.NODE_ENV === "test") return;
|
|
21754
21787
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21755
21788
|
if (process.env.CI) return;
|
|
21756
|
-
const current2 = true ? "2.65.
|
|
21789
|
+
const current2 = true ? "2.65.11" : null;
|
|
21757
21790
|
if (!current2) return;
|
|
21758
21791
|
const cache = readCache();
|
|
21759
21792
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21770,7 +21803,7 @@ function checkForUpdates() {
|
|
|
21770
21803
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21771
21804
|
if (process.env.CI) return;
|
|
21772
21805
|
if (!process.stdout.isTTY) return;
|
|
21773
|
-
const current2 = true ? "2.65.
|
|
21806
|
+
const current2 = true ? "2.65.11" : null;
|
|
21774
21807
|
if (!current2) return;
|
|
21775
21808
|
const cache = readCache();
|
|
21776
21809
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21790,7 +21823,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
21790
21823
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
21791
21824
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
21792
21825
|
function currentCliVersion() {
|
|
21793
|
-
return true ? "2.65.
|
|
21826
|
+
return true ? "2.65.11" : null;
|
|
21794
21827
|
}
|
|
21795
21828
|
function runCmd(cmd, args2, timeoutMs) {
|
|
21796
21829
|
return new Promise((resolve10) => {
|
|
@@ -26585,7 +26618,7 @@ var sessionTerminated = async (ctx, cmd) => {
|
|
|
26585
26618
|
} catch {
|
|
26586
26619
|
}
|
|
26587
26620
|
ctx.outputSvc.dispose();
|
|
26588
|
-
ctx.relay
|
|
26621
|
+
await stopRelayWithGoodbye(ctx.relay);
|
|
26589
26622
|
process.exit(0);
|
|
26590
26623
|
};
|
|
26591
26624
|
var shutdownSession = async (ctx, cmd) => {
|
|
@@ -26614,7 +26647,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
26614
26647
|
} catch {
|
|
26615
26648
|
}
|
|
26616
26649
|
ctx.outputSvc.dispose();
|
|
26617
|
-
ctx.relay
|
|
26650
|
+
await stopRelayWithGoodbye(ctx.relay);
|
|
26618
26651
|
process.exit(0);
|
|
26619
26652
|
};
|
|
26620
26653
|
var showInstallCommand = async (ctx, cmd, parsed) => {
|
|
@@ -33869,6 +33902,7 @@ var _acpStartSeam = {
|
|
|
33869
33902
|
var PROTOCOL_VERSION3 = 1;
|
|
33870
33903
|
var FATAL_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
|
|
33871
33904
|
var NEWSESSION_TIMEOUT_MS = 12e4;
|
|
33905
|
+
var LOADSESSION_TIMEOUT_MS = 6e4;
|
|
33872
33906
|
var PROMPT_IDLE_TIMEOUT_MS = 9e4;
|
|
33873
33907
|
var PROMPT_ACTIVE_IDLE_TIMEOUT_MS = 6e5;
|
|
33874
33908
|
var CLIENT_CAPABILITIES = {
|
|
@@ -34383,13 +34417,30 @@ var AcpClient = class {
|
|
|
34383
34417
|
log.info("acpClient", `loadSession \u2192 sessionId=${sessionId.slice(0, 8)}`);
|
|
34384
34418
|
this.opts.beginLoadReplay?.();
|
|
34385
34419
|
let loaded;
|
|
34420
|
+
let loadTimer;
|
|
34386
34421
|
try {
|
|
34387
|
-
loaded = await
|
|
34388
|
-
|
|
34389
|
-
|
|
34390
|
-
|
|
34391
|
-
|
|
34422
|
+
loaded = await Promise.race([
|
|
34423
|
+
this.connection.loadSession({
|
|
34424
|
+
sessionId,
|
|
34425
|
+
cwd: this.opts.cwd,
|
|
34426
|
+
mcpServers: this.opts.mcpServers ?? []
|
|
34427
|
+
}),
|
|
34428
|
+
new Promise((_2, reject) => {
|
|
34429
|
+
loadTimer = setTimeout(() => {
|
|
34430
|
+
const tail = this.recentStderr.slice(-4).join(" | ");
|
|
34431
|
+
reject(
|
|
34432
|
+
new Error(
|
|
34433
|
+
`ACP_LOAD_SESSION_TIMEOUT: ${this.opts.adapter.requiresAgentBinary} did not answer session/load for ${sessionId.slice(
|
|
34434
|
+
0,
|
|
34435
|
+
8
|
|
34436
|
+
)} within ${Math.round(LOADSESSION_TIMEOUT_MS / 1e3)}s${tail ? ` \u2014 last output: ${tail}` : ""}`
|
|
34437
|
+
)
|
|
34438
|
+
);
|
|
34439
|
+
}, LOADSESSION_TIMEOUT_MS);
|
|
34440
|
+
})
|
|
34441
|
+
]);
|
|
34392
34442
|
} finally {
|
|
34443
|
+
if (loadTimer) clearTimeout(loadTimer);
|
|
34393
34444
|
this.opts.endLoadReplay?.();
|
|
34394
34445
|
}
|
|
34395
34446
|
this.sessionId = sessionId;
|
|
@@ -38676,7 +38727,7 @@ async function sessionShutdownH(ctx) {
|
|
|
38676
38727
|
} catch {
|
|
38677
38728
|
}
|
|
38678
38729
|
}
|
|
38679
|
-
relay
|
|
38730
|
+
await stopRelayWithGoodbye(relay);
|
|
38680
38731
|
closeAllTerminals();
|
|
38681
38732
|
await client3.stop();
|
|
38682
38733
|
process.exit(0);
|
|
@@ -39975,7 +40026,7 @@ async function runAcpSession(opts) {
|
|
|
39975
40026
|
const shutdown = async (signal) => {
|
|
39976
40027
|
showInfo(`Shutting down ACP session (${signal})\u2026`);
|
|
39977
40028
|
clearTimeout(prewarmTimer);
|
|
39978
|
-
relay
|
|
40029
|
+
await stopRelayWithGoodbye(relay);
|
|
39979
40030
|
void fileWatcher.stop();
|
|
39980
40031
|
turnFiles.stop();
|
|
39981
40032
|
closeAllTerminals();
|
|
@@ -40444,7 +40495,27 @@ var OutputService = class _OutputService {
|
|
|
40444
40495
|
...lines.slice(banner.endIdx + 1)
|
|
40445
40496
|
];
|
|
40446
40497
|
}
|
|
40498
|
+
/**
|
|
40499
|
+
* Mute/unmute the CHAT-output publish path. Every frame this service would
|
|
40500
|
+
* emit (clear / user_message / new_turn / text / chrome_steps / selectors /
|
|
40501
|
+
* banner / input_suggestion) is dropped while muted; `push()` and the tick
|
|
40502
|
+
* still run, so the detection side-effects (session id, rate limit,
|
|
40503
|
+
* terminal-turn gate) are untouched.
|
|
40504
|
+
*
|
|
40505
|
+
* ⚠️ The one caller is the baton's {@link NativeTuiDriver}: while LOCAL_DRIVE
|
|
40506
|
+
* holds the baton, the mobile view is the read-only TRANSCRIPT mirror, never
|
|
40507
|
+
* a screen-scrape — piping the native TUI's PTY bytes through here published
|
|
40508
|
+
* raw Claude Code chrome (box-drawing rules, `❯`, "auto mode on (shift+tab to
|
|
40509
|
+
* cycle) · esc to interrupt") into the chat as if it were agent output.
|
|
40510
|
+
* Terminal-panel frames (`sendTerminalChunk`/`sendTerminalExit`) go straight
|
|
40511
|
+
* to the emitter and are deliberately NOT affected.
|
|
40512
|
+
*/
|
|
40513
|
+
setPublishSuppressed(suppressed) {
|
|
40514
|
+
this.publishSuppressed = suppressed;
|
|
40515
|
+
}
|
|
40516
|
+
publishSuppressed = false;
|
|
40447
40517
|
async send(body, opts = {}) {
|
|
40518
|
+
if (this.publishSuppressed) return;
|
|
40448
40519
|
const outcome = await this.emitter.send(body, opts);
|
|
40449
40520
|
if (outcome.dead && this.pty.isActive) {
|
|
40450
40521
|
this.dispose();
|
|
@@ -41135,11 +41206,18 @@ function provisionSkillsForStart(home = import_node_os13.default.homedir()) {
|
|
|
41135
41206
|
}
|
|
41136
41207
|
|
|
41137
41208
|
// src/baton/baton-controller.ts
|
|
41138
|
-
var BatonController = class {
|
|
41209
|
+
var BatonController = class _BatonController {
|
|
41139
41210
|
constructor(deps) {
|
|
41140
41211
|
this.deps = deps;
|
|
41141
41212
|
}
|
|
41142
41213
|
deps;
|
|
41214
|
+
/**
|
|
41215
|
+
* Default upper bound on a whole hand-off. A cold `newSession` on claude is
|
|
41216
|
+
* ~20 s, so 45 s leaves generous headroom for a healthy switch while still
|
|
41217
|
+
* failing FAST enough that the user gets an honest error instead of a
|
|
41218
|
+
* permanent "Switching…".
|
|
41219
|
+
*/
|
|
41220
|
+
static DEFAULT_SWITCH_TIMEOUT_MS = 45e3;
|
|
41143
41221
|
_state = "LOCAL_DRIVE";
|
|
41144
41222
|
_active = "local_tui";
|
|
41145
41223
|
_conversationId = null;
|
|
@@ -41216,24 +41294,79 @@ var BatonController = class {
|
|
|
41216
41294
|
this.setState("SWITCHING");
|
|
41217
41295
|
const priorActive = this._active;
|
|
41218
41296
|
const priorConversationId = this._conversationId;
|
|
41219
|
-
|
|
41297
|
+
const timeoutMs = this.deps.switchTimeoutMs ?? _BatonController.DEFAULT_SWITCH_TIMEOUT_MS;
|
|
41298
|
+
let stoppedCurrent = false;
|
|
41299
|
+
const handoff = (async () => {
|
|
41220
41300
|
await current2.whenSafeToYield();
|
|
41221
41301
|
await current2.stop();
|
|
41222
|
-
|
|
41302
|
+
stoppedCurrent = true;
|
|
41303
|
+
return next.start(priorConversationId ?? void 0);
|
|
41304
|
+
})();
|
|
41305
|
+
handoff.catch(() => void 0);
|
|
41306
|
+
try {
|
|
41307
|
+
const conversationId = await withDeadline(
|
|
41308
|
+
handoff,
|
|
41309
|
+
timeoutMs,
|
|
41310
|
+
`BATON_SWITCH_TIMEOUT: ${from} \u2192 ${to} hand-off did not complete within ${Math.round(
|
|
41311
|
+
timeoutMs / 1e3
|
|
41312
|
+
)}s`
|
|
41313
|
+
);
|
|
41314
|
+
this._conversationId = conversationId;
|
|
41223
41315
|
this._active = nextKind;
|
|
41224
41316
|
this.setState(to);
|
|
41225
41317
|
} catch (err) {
|
|
41318
|
+
await this.recoverFromFailedSwitch(
|
|
41319
|
+
current2,
|
|
41320
|
+
next,
|
|
41321
|
+
stoppedCurrent,
|
|
41322
|
+
priorConversationId,
|
|
41323
|
+
timeoutMs
|
|
41324
|
+
);
|
|
41226
41325
|
this._active = priorActive;
|
|
41227
|
-
this._conversationId = priorConversationId;
|
|
41228
41326
|
this.setState(from);
|
|
41229
41327
|
throw err;
|
|
41230
41328
|
}
|
|
41231
41329
|
}
|
|
41330
|
+
/**
|
|
41331
|
+
* Undo a half-done hand-off. The `next` driver may still be starting behind
|
|
41332
|
+
* the deadline — stop it so a second adapter/PTY can't race the revived one.
|
|
41333
|
+
* And when `current` was ALREADY stopped before the failure, reverting only
|
|
41334
|
+
* the STATE would leave the user staring at a dead terminal (or mobile at a
|
|
41335
|
+
* dead adapter), so bring it back on the same conversation. Both best-effort
|
|
41336
|
+
* and bounded: recovery must never itself hang the controller.
|
|
41337
|
+
*/
|
|
41338
|
+
async recoverFromFailedSwitch(current2, next, stoppedCurrent, priorConversationId, timeoutMs) {
|
|
41339
|
+
this._conversationId = priorConversationId;
|
|
41340
|
+
await withDeadline(next.stop(), timeoutMs, "BATON_RECOVERY_STOP_TIMEOUT").catch(
|
|
41341
|
+
() => void 0
|
|
41342
|
+
);
|
|
41343
|
+
if (!stoppedCurrent) return;
|
|
41344
|
+
try {
|
|
41345
|
+
const revived = await withDeadline(
|
|
41346
|
+
current2.start(priorConversationId ?? void 0),
|
|
41347
|
+
timeoutMs,
|
|
41348
|
+
"BATON_RECOVERY_START_TIMEOUT"
|
|
41349
|
+
);
|
|
41350
|
+
if (revived) this._conversationId = revived;
|
|
41351
|
+
} catch {
|
|
41352
|
+
}
|
|
41353
|
+
}
|
|
41232
41354
|
setState(state) {
|
|
41233
41355
|
this._state = state;
|
|
41234
41356
|
this.deps.publishState(state, this._active, this._conversationId);
|
|
41235
41357
|
}
|
|
41236
41358
|
};
|
|
41359
|
+
function withDeadline(promise, ms, message) {
|
|
41360
|
+
let timer;
|
|
41361
|
+
return Promise.race([
|
|
41362
|
+
promise,
|
|
41363
|
+
new Promise((_2, reject) => {
|
|
41364
|
+
timer = setTimeout(() => reject(new Error(message)), ms);
|
|
41365
|
+
})
|
|
41366
|
+
]).finally(() => {
|
|
41367
|
+
if (timer) clearTimeout(timer);
|
|
41368
|
+
});
|
|
41369
|
+
}
|
|
41237
41370
|
|
|
41238
41371
|
// src/baton/terminal.ts
|
|
41239
41372
|
var TUI_MODE_RESET = "\x1B[?1004l\x1B[?2004l\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?25h";
|
|
@@ -41271,6 +41404,7 @@ var NativeTuiDriver = class _NativeTuiDriver {
|
|
|
41271
41404
|
deps.opts.pluginAuthToken,
|
|
41272
41405
|
deps.runtime
|
|
41273
41406
|
);
|
|
41407
|
+
this.outputSvc.setPublishSuppressed(true);
|
|
41274
41408
|
this.keepAliveCtx = { inCodespace: false, codespaceName: void 0 };
|
|
41275
41409
|
this.setKeepAlive = buildKeepAlive(this.keepAliveCtx).apply;
|
|
41276
41410
|
}
|
|
@@ -41375,10 +41509,17 @@ var AcpDriver = class {
|
|
|
41375
41509
|
session = null;
|
|
41376
41510
|
budgetReachedPosted = false;
|
|
41377
41511
|
async start(resumeId) {
|
|
41512
|
+
const resumable = resumeId !== void 0 && this.hasTranscript(resumeId);
|
|
41513
|
+
if (resumeId !== void 0 && !resumable) {
|
|
41514
|
+
log.info(
|
|
41515
|
+
"batonAcp",
|
|
41516
|
+
`resume id ${resumeId.slice(0, 8)} has no transcript on disk (zero turns yet) \u2014 starting a fresh ACP session instead of session/load`
|
|
41517
|
+
);
|
|
41518
|
+
}
|
|
41378
41519
|
let started;
|
|
41379
41520
|
try {
|
|
41380
41521
|
started = await this.deps.client.start();
|
|
41381
|
-
if (resumeId !== void 0) {
|
|
41522
|
+
if (resumable && resumeId !== void 0) {
|
|
41382
41523
|
await this.deps.runtime.syncTranscriptForAcpResume?.(this.deps.opts.cwd, resumeId);
|
|
41383
41524
|
this.deps.streaming.beginLoadReplay();
|
|
41384
41525
|
try {
|
|
@@ -41391,13 +41532,30 @@ var AcpDriver = class {
|
|
|
41391
41532
|
await this.deps.client.stop().catch(() => void 0);
|
|
41392
41533
|
throw err;
|
|
41393
41534
|
}
|
|
41394
|
-
const conversationId = resumeId !== void 0 ? resumeId : started.sessionId;
|
|
41535
|
+
const conversationId = resumable && resumeId !== void 0 ? resumeId : started.sessionId;
|
|
41395
41536
|
this.acpSessionId = conversationId;
|
|
41396
41537
|
this.agentCaps = started.initialize.agentCapabilities;
|
|
41397
41538
|
this.session = null;
|
|
41398
41539
|
this.budgetReachedPosted = false;
|
|
41399
41540
|
return conversationId;
|
|
41400
41541
|
}
|
|
41542
|
+
/**
|
|
41543
|
+
* Does the agent's own on-disk transcript for `conversationId` exist yet?
|
|
41544
|
+
* `resolveHistoryFile` returns null when the file isn't there (every baton
|
|
41545
|
+
* runtime `existsSync`-checks), which is exactly "the native TUI has run zero
|
|
41546
|
+
* turns on this id" — the only case where `session/load` has nothing to load.
|
|
41547
|
+
* A runtime without the hook can't be a baton runtime (see `gate.ts`), but if
|
|
41548
|
+
* one ever is, assume resumable so behaviour is unchanged.
|
|
41549
|
+
*/
|
|
41550
|
+
hasTranscript(conversationId) {
|
|
41551
|
+
const resolve10 = this.deps.runtime.resolveHistoryFile;
|
|
41552
|
+
if (typeof resolve10 !== "function") return true;
|
|
41553
|
+
try {
|
|
41554
|
+
return resolve10.call(this.deps.runtime, this.deps.opts.cwd, conversationId) !== null;
|
|
41555
|
+
} catch {
|
|
41556
|
+
return true;
|
|
41557
|
+
}
|
|
41558
|
+
}
|
|
41401
41559
|
async stop() {
|
|
41402
41560
|
await this.deps.client.stop();
|
|
41403
41561
|
this.acpSessionId = null;
|
|
@@ -41732,8 +41890,7 @@ async function runBatonSession(opts) {
|
|
|
41732
41890
|
nativeDriver.handlePtyData(raw);
|
|
41733
41891
|
},
|
|
41734
41892
|
onExit(code) {
|
|
41735
|
-
teardown();
|
|
41736
|
-
process.exit(code);
|
|
41893
|
+
void teardown().finally(() => process.exit(code));
|
|
41737
41894
|
}
|
|
41738
41895
|
});
|
|
41739
41896
|
nativeDriver = new NativeTuiDriver({
|
|
@@ -41813,19 +41970,18 @@ async function runBatonSession(opts) {
|
|
|
41813
41970
|
publish: publishBatonState
|
|
41814
41971
|
})
|
|
41815
41972
|
);
|
|
41816
|
-
function teardown() {
|
|
41973
|
+
async function teardown() {
|
|
41817
41974
|
if (torn) return;
|
|
41818
41975
|
torn = true;
|
|
41819
41976
|
process.removeListener("SIGINT", onSignal);
|
|
41820
41977
|
process.removeListener("SIGTERM", onSignal);
|
|
41821
41978
|
process.removeListener("SIGHUP", onSignal);
|
|
41822
41979
|
mirror?.stop();
|
|
41823
|
-
relay.stop();
|
|
41824
41980
|
void controller.shutdown();
|
|
41981
|
+
await stopRelayWithGoodbye(relay);
|
|
41825
41982
|
}
|
|
41826
41983
|
const onSignal = () => {
|
|
41827
|
-
teardown();
|
|
41828
|
-
process.exit(0);
|
|
41984
|
+
void teardown().finally(() => process.exit(0));
|
|
41829
41985
|
};
|
|
41830
41986
|
process.once("SIGINT", onSignal);
|
|
41831
41987
|
process.once("SIGTERM", onSignal);
|
|
@@ -42212,12 +42368,12 @@ async function start(requestedAgent, presetSession) {
|
|
|
42212
42368
|
outputSvc.push(raw);
|
|
42213
42369
|
streamingEmitter?.push(raw);
|
|
42214
42370
|
},
|
|
42215
|
-
onExit(code) {
|
|
42371
|
+
async onExit(code) {
|
|
42216
42372
|
process.removeListener("SIGINT", sigintHandler);
|
|
42217
42373
|
process.removeListener("SIGTERM", sigintHandler);
|
|
42218
42374
|
process.removeListener("SIGHUP", sigintHandler);
|
|
42219
42375
|
outputSvc.dispose();
|
|
42220
|
-
relay
|
|
42376
|
+
await stopRelayWithGoodbye(relay);
|
|
42221
42377
|
void fileWatcher?.stop();
|
|
42222
42378
|
turnFiles?.stop();
|
|
42223
42379
|
void beads?.watcher.stop();
|
|
@@ -42272,7 +42428,7 @@ async function start(requestedAgent, presetSession) {
|
|
|
42272
42428
|
shuttingDown = true;
|
|
42273
42429
|
agent.kill();
|
|
42274
42430
|
outputSvc.dispose();
|
|
42275
|
-
relay
|
|
42431
|
+
await stopRelayWithGoodbye(relay);
|
|
42276
42432
|
void fileWatcher?.stop();
|
|
42277
42433
|
void beads?.watcher.stop();
|
|
42278
42434
|
void streamingEmitter?.stop();
|
|
@@ -44868,7 +45024,7 @@ function checkChokidar() {
|
|
|
44868
45024
|
}
|
|
44869
45025
|
async function doctor(args2 = []) {
|
|
44870
45026
|
const json = args2.includes("--json");
|
|
44871
|
-
const cliVersion = true ? "2.65.
|
|
45027
|
+
const cliVersion = true ? "2.65.11" : "0.0.0-dev";
|
|
44872
45028
|
const apiBase2 = resolveApiBaseUrl();
|
|
44873
45029
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
44874
45030
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -45259,7 +45415,7 @@ async function mcpRun(args2) {
|
|
|
45259
45415
|
// src/commands/version.ts
|
|
45260
45416
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
45261
45417
|
function version2() {
|
|
45262
|
-
const v = true ? "2.65.
|
|
45418
|
+
const v = true ? "2.65.11" : "unknown";
|
|
45263
45419
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
45264
45420
|
}
|
|
45265
45421
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.65.
|
|
3
|
+
"version": "2.65.11",
|
|
4
4
|
"description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|