codeam-cli 2.60.20 → 2.60.22
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/CHANGELOG.md +13 -0
- package/dist/index.js +150 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.60.21] — 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Baton — discover Codex's self-minted session id (first-turn aware)
|
|
12
|
+
|
|
13
|
+
## [2.60.20] — 2026-07-09
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Baton — pre-mint Cursor session id via `create-chat`
|
|
18
|
+
- **cli:** Baton Take Control for Cursor — bridge native↔ACP session stores
|
|
19
|
+
|
|
7
20
|
## [2.60.19] — 2026-07-09
|
|
8
21
|
|
|
9
22
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -5680,7 +5680,7 @@ function readAnonId() {
|
|
|
5680
5680
|
}
|
|
5681
5681
|
function superProperties() {
|
|
5682
5682
|
return {
|
|
5683
|
-
cliVersion: true ? "2.60.
|
|
5683
|
+
cliVersion: true ? "2.60.22" : "0.0.0-dev",
|
|
5684
5684
|
nodeVersion: process.version,
|
|
5685
5685
|
platform: process.platform,
|
|
5686
5686
|
arch: process.arch,
|
|
@@ -5861,7 +5861,7 @@ var os4 = __toESM(require("os"));
|
|
|
5861
5861
|
// package.json
|
|
5862
5862
|
var package_default = {
|
|
5863
5863
|
name: "codeam-cli",
|
|
5864
|
-
version: "2.60.
|
|
5864
|
+
version: "2.60.22",
|
|
5865
5865
|
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.",
|
|
5866
5866
|
type: "commonjs",
|
|
5867
5867
|
main: "dist/index.js",
|
|
@@ -6932,7 +6932,7 @@ var CommandRelayService = class {
|
|
|
6932
6932
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6933
6933
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6934
6934
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6935
|
-
..."2.60.
|
|
6935
|
+
..."2.60.22" ? { ideVersion: "2.60.22" } : {}
|
|
6936
6936
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6937
6937
|
}
|
|
6938
6938
|
/**
|
|
@@ -12931,6 +12931,87 @@ function resolveHistoryFile2(cwd, sessionId, homeOverride) {
|
|
|
12931
12931
|
}
|
|
12932
12932
|
return null;
|
|
12933
12933
|
}
|
|
12934
|
+
async function discoverSessionId(cwd, opts, homeOverride) {
|
|
12935
|
+
const home = homeOverride ?? import_node_os.default.homedir();
|
|
12936
|
+
const sessionsRoot = import_node_path2.default.join(home, ".codex", "sessions");
|
|
12937
|
+
const floor = opts.sinceMs - 2e3;
|
|
12938
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 24e4);
|
|
12939
|
+
let resolvedCurrent;
|
|
12940
|
+
try {
|
|
12941
|
+
resolvedCurrent = import_node_fs3.default.realpathSync(cwd);
|
|
12942
|
+
} catch {
|
|
12943
|
+
resolvedCurrent = import_node_path2.default.resolve(cwd);
|
|
12944
|
+
}
|
|
12945
|
+
for (; ; ) {
|
|
12946
|
+
const id = newestRolloutIdSince(sessionsRoot, resolvedCurrent, floor);
|
|
12947
|
+
if (id) return id;
|
|
12948
|
+
if (Date.now() >= deadline) return null;
|
|
12949
|
+
await sleep2(500);
|
|
12950
|
+
}
|
|
12951
|
+
}
|
|
12952
|
+
function newestRolloutIdSince(sessionsRoot, resolvedCwd, floorMs) {
|
|
12953
|
+
if (!import_node_fs3.default.existsSync(sessionsRoot)) return null;
|
|
12954
|
+
const now = /* @__PURE__ */ new Date();
|
|
12955
|
+
let bestId = null;
|
|
12956
|
+
let bestMtime = -1;
|
|
12957
|
+
for (let dayOffset = 0; dayOffset < 2; dayOffset += 1) {
|
|
12958
|
+
const d3 = new Date(now.getTime() - dayOffset * 24 * 60 * 60 * 1e3);
|
|
12959
|
+
const yyyy = String(d3.getUTCFullYear());
|
|
12960
|
+
const mm = String(d3.getUTCMonth() + 1).padStart(2, "0");
|
|
12961
|
+
const dd = String(d3.getUTCDate()).padStart(2, "0");
|
|
12962
|
+
const dayDir = import_node_path2.default.join(sessionsRoot, yyyy, mm, dd);
|
|
12963
|
+
let dayFiles;
|
|
12964
|
+
try {
|
|
12965
|
+
dayFiles = import_node_fs3.default.readdirSync(dayDir, { withFileTypes: true });
|
|
12966
|
+
} catch {
|
|
12967
|
+
continue;
|
|
12968
|
+
}
|
|
12969
|
+
for (const entry of dayFiles) {
|
|
12970
|
+
if (!entry.isFile()) continue;
|
|
12971
|
+
if (!entry.name.startsWith("rollout-") || !entry.name.endsWith(".jsonl")) continue;
|
|
12972
|
+
const filePath = import_node_path2.default.join(dayDir, entry.name);
|
|
12973
|
+
let mtime;
|
|
12974
|
+
try {
|
|
12975
|
+
mtime = import_node_fs3.default.statSync(filePath).mtimeMs;
|
|
12976
|
+
} catch {
|
|
12977
|
+
continue;
|
|
12978
|
+
}
|
|
12979
|
+
if (mtime < floorMs || mtime <= bestMtime) continue;
|
|
12980
|
+
let metaCwd;
|
|
12981
|
+
let metaId;
|
|
12982
|
+
try {
|
|
12983
|
+
const raw = import_node_fs3.default.readFileSync(filePath, "utf8");
|
|
12984
|
+
for (const line of raw.split("\n")) {
|
|
12985
|
+
if (!line.trim()) continue;
|
|
12986
|
+
const rec = parseLine(line);
|
|
12987
|
+
if (!rec) continue;
|
|
12988
|
+
if (rec.type === "session_meta") {
|
|
12989
|
+
const meta = rec.payload;
|
|
12990
|
+
metaCwd = typeof meta?.cwd === "string" ? meta.cwd : void 0;
|
|
12991
|
+
metaId = typeof meta?.id === "string" ? meta.id : void 0;
|
|
12992
|
+
}
|
|
12993
|
+
break;
|
|
12994
|
+
}
|
|
12995
|
+
} catch {
|
|
12996
|
+
continue;
|
|
12997
|
+
}
|
|
12998
|
+
if (!metaId || !metaCwd) continue;
|
|
12999
|
+
let resolvedMeta;
|
|
13000
|
+
try {
|
|
13001
|
+
resolvedMeta = import_node_fs3.default.realpathSync(metaCwd);
|
|
13002
|
+
} catch {
|
|
13003
|
+
resolvedMeta = import_node_path2.default.resolve(metaCwd);
|
|
13004
|
+
}
|
|
13005
|
+
if (resolvedMeta !== resolvedCwd) continue;
|
|
13006
|
+
bestMtime = mtime;
|
|
13007
|
+
bestId = metaId;
|
|
13008
|
+
}
|
|
13009
|
+
}
|
|
13010
|
+
return bestId;
|
|
13011
|
+
}
|
|
13012
|
+
function sleep2(ms) {
|
|
13013
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
13014
|
+
}
|
|
12934
13015
|
function getCurrentUsage2(historyDir) {
|
|
12935
13016
|
if (!import_node_fs3.default.existsSync(historyDir)) return null;
|
|
12936
13017
|
const files = import_node_fs3.default.readdirSync(historyDir).filter((f) => f.startsWith("rollout-") && f.endsWith(".jsonl")).map((f) => ({ name: f, full: import_node_path2.default.join(historyDir, f) })).map((e) => ({ ...e, mtime: import_node_fs3.default.statSync(e.full).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
@@ -13098,6 +13179,16 @@ var CodexRuntimeStrategy = class {
|
|
|
13098
13179
|
resolveHistoryFile(cwd, sessionId) {
|
|
13099
13180
|
return resolveHistoryFile2(cwd, sessionId);
|
|
13100
13181
|
}
|
|
13182
|
+
/**
|
|
13183
|
+
* Codex mints its own session id (into a `rollout-*.jsonl` at TUI boot) and
|
|
13184
|
+
* neither accepts a pre-set one nor prints it — so, like Kimi, the baton's
|
|
13185
|
+
* NativeTuiDriver discovers it post-spawn. Codex shares that rollout store with
|
|
13186
|
+
* its ACP adapter, so discovery alone is enough (no cross-store bridge). The
|
|
13187
|
+
* TUI boots slowly, hence the generous poll budget inside.
|
|
13188
|
+
*/
|
|
13189
|
+
discoverSessionId(cwd, opts) {
|
|
13190
|
+
return discoverSessionId(cwd, opts);
|
|
13191
|
+
}
|
|
13101
13192
|
getCurrentUsage(historyDir) {
|
|
13102
13193
|
return getCurrentUsage2(historyDir);
|
|
13103
13194
|
}
|
|
@@ -14473,7 +14564,7 @@ function scanBucketsForSession(sessionId) {
|
|
|
14473
14564
|
}
|
|
14474
14565
|
return null;
|
|
14475
14566
|
}
|
|
14476
|
-
async function
|
|
14567
|
+
async function discoverSessionId2(cwd, opts) {
|
|
14477
14568
|
const bucket = path33.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
14478
14569
|
const floor = opts.sinceMs - 2e3;
|
|
14479
14570
|
const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
|
|
@@ -14481,7 +14572,7 @@ async function discoverSessionId(cwd, opts) {
|
|
|
14481
14572
|
const id = newestSessionSince(bucket, floor);
|
|
14482
14573
|
if (id) return id;
|
|
14483
14574
|
if (Date.now() >= deadline) return null;
|
|
14484
|
-
await
|
|
14575
|
+
await sleep3(250);
|
|
14485
14576
|
}
|
|
14486
14577
|
}
|
|
14487
14578
|
function newestSessionSince(bucket, floorMs) {
|
|
@@ -14508,7 +14599,7 @@ function newestSessionSince(bucket, floorMs) {
|
|
|
14508
14599
|
}
|
|
14509
14600
|
return bestId;
|
|
14510
14601
|
}
|
|
14511
|
-
function
|
|
14602
|
+
function sleep3(ms) {
|
|
14512
14603
|
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
14513
14604
|
}
|
|
14514
14605
|
function joinTextParts(parts) {
|
|
@@ -14631,7 +14722,7 @@ var KimiRuntimeStrategy = class {
|
|
|
14631
14722
|
* have no baton), so the driver's optional call is inert for them.
|
|
14632
14723
|
*/
|
|
14633
14724
|
discoverSessionId(cwd, opts) {
|
|
14634
|
-
return
|
|
14725
|
+
return discoverSessionId2(cwd, opts);
|
|
14635
14726
|
}
|
|
14636
14727
|
getCurrentUsage(historyDir) {
|
|
14637
14728
|
return getCurrentUsage5(historyDir);
|
|
@@ -16642,7 +16733,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16642
16733
|
if (process.env.NODE_ENV === "test") return;
|
|
16643
16734
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16644
16735
|
if (process.env.CI) return;
|
|
16645
|
-
const current = true ? "2.60.
|
|
16736
|
+
const current = true ? "2.60.22" : null;
|
|
16646
16737
|
if (!current) return;
|
|
16647
16738
|
const cache = readCache();
|
|
16648
16739
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16659,7 +16750,7 @@ function checkForUpdates() {
|
|
|
16659
16750
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16660
16751
|
if (process.env.CI) return;
|
|
16661
16752
|
if (!process.stdout.isTTY) return;
|
|
16662
|
-
const current = true ? "2.60.
|
|
16753
|
+
const current = true ? "2.60.22" : null;
|
|
16663
16754
|
if (!current) return;
|
|
16664
16755
|
const cache = readCache();
|
|
16665
16756
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16679,7 +16770,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16679
16770
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16680
16771
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16681
16772
|
function currentCliVersion() {
|
|
16682
|
-
return true ? "2.60.
|
|
16773
|
+
return true ? "2.60.22" : null;
|
|
16683
16774
|
}
|
|
16684
16775
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16685
16776
|
return new Promise((resolve7) => {
|
|
@@ -22211,7 +22302,7 @@ async function waitForClaudeNativeBinary(opts = {}) {
|
|
|
22211
22302
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22212
22303
|
const pollMs = opts.pollMs ?? 500;
|
|
22213
22304
|
const now = opts.now ?? Date.now;
|
|
22214
|
-
const
|
|
22305
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
22215
22306
|
const deps = {
|
|
22216
22307
|
sdkDir: opts.sdkDir,
|
|
22217
22308
|
platformKey: opts.platformKey,
|
|
@@ -22221,7 +22312,7 @@ async function waitForClaudeNativeBinary(opts = {}) {
|
|
|
22221
22312
|
let found = resolveClaudeNativeBinary(deps);
|
|
22222
22313
|
if (found) return found;
|
|
22223
22314
|
while (now() < deadline) {
|
|
22224
|
-
await
|
|
22315
|
+
await sleep5(pollMs);
|
|
22225
22316
|
found = resolveClaudeNativeBinary(deps);
|
|
22226
22317
|
if (found) return found;
|
|
22227
22318
|
}
|
|
@@ -22243,13 +22334,13 @@ async function waitForCommandOnPath(cmd, opts = {}) {
|
|
|
22243
22334
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22244
22335
|
const pollMs = opts.pollMs ?? 500;
|
|
22245
22336
|
const now = opts.now ?? Date.now;
|
|
22246
|
-
const
|
|
22337
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
22247
22338
|
const probe = opts.probe;
|
|
22248
22339
|
const check = () => isCommandOnPath(cmd, probe);
|
|
22249
22340
|
const deadline = now() + timeoutMs;
|
|
22250
22341
|
if (check()) return true;
|
|
22251
22342
|
while (now() < deadline) {
|
|
22252
|
-
await
|
|
22343
|
+
await sleep5(pollMs);
|
|
22253
22344
|
if (check()) return true;
|
|
22254
22345
|
}
|
|
22255
22346
|
return check();
|
|
@@ -22272,12 +22363,12 @@ async function waitForCursorAgent(opts = {}) {
|
|
|
22272
22363
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22273
22364
|
const pollMs = opts.pollMs ?? 500;
|
|
22274
22365
|
const now = opts.now ?? Date.now;
|
|
22275
|
-
const
|
|
22366
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
22276
22367
|
const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
|
|
22277
22368
|
const deadline = now() + timeoutMs;
|
|
22278
22369
|
if (check()) return true;
|
|
22279
22370
|
while (now() < deadline) {
|
|
22280
|
-
await
|
|
22371
|
+
await sleep5(pollMs);
|
|
22281
22372
|
if (check()) return true;
|
|
22282
22373
|
}
|
|
22283
22374
|
return check();
|
|
@@ -22326,12 +22417,12 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
22326
22417
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
22327
22418
|
const pollMs = opts.pollMs ?? 500;
|
|
22328
22419
|
const now = opts.now ?? Date.now;
|
|
22329
|
-
const
|
|
22420
|
+
const sleep5 = opts.sleep ?? realSleep;
|
|
22330
22421
|
const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
|
|
22331
22422
|
const deadline = now() + timeoutMs;
|
|
22332
22423
|
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
22333
22424
|
while (now() < deadline) {
|
|
22334
|
-
await
|
|
22425
|
+
await sleep5(pollMs);
|
|
22335
22426
|
if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
|
|
22336
22427
|
}
|
|
22337
22428
|
return false;
|
|
@@ -29939,12 +30030,12 @@ var StreamingEmitterService = class {
|
|
|
29939
30030
|
log.warn("streamingEmitter", `post error url=${url} attempt=${attempt + 1}`, err);
|
|
29940
30031
|
}
|
|
29941
30032
|
if (attempt < MAX_RETRIES2) {
|
|
29942
|
-
await
|
|
30033
|
+
await sleep4(RETRY_BACKOFF_MS3 * (attempt + 1));
|
|
29943
30034
|
}
|
|
29944
30035
|
}
|
|
29945
30036
|
}
|
|
29946
30037
|
};
|
|
29947
|
-
function
|
|
30038
|
+
function sleep4(ms) {
|
|
29948
30039
|
return new Promise((r) => setTimeout(r, ms));
|
|
29949
30040
|
}
|
|
29950
30041
|
var TREE_CONTINUATION_RE = /^\s*└/;
|
|
@@ -30027,6 +30118,20 @@ var BatonController = class {
|
|
|
30027
30118
|
this._active = "local_tui";
|
|
30028
30119
|
this.setState("LOCAL_DRIVE");
|
|
30029
30120
|
}
|
|
30121
|
+
/**
|
|
30122
|
+
* Late-bind the conversation id for an agent (Codex) that minted it only on the
|
|
30123
|
+
* user's first turn, so `begin()` returned null. Fires from the native driver's
|
|
30124
|
+
* background discovery. Idempotent + guarded: only binds while we're still in
|
|
30125
|
+
* the INITIAL, id-less LOCAL_DRIVE — if the user already took control (which
|
|
30126
|
+
* started its own session) or an id is already set, it's a no-op, so a stray
|
|
30127
|
+
* native id can never clobber the live conversation. Re-publishes LOCAL_DRIVE so
|
|
30128
|
+
* the read-only mirror arms on the now-known id.
|
|
30129
|
+
*/
|
|
30130
|
+
rebindConversation(conversationId) {
|
|
30131
|
+
if (this._conversationId !== null || this._state !== "LOCAL_DRIVE") return;
|
|
30132
|
+
this._conversationId = conversationId;
|
|
30133
|
+
this.setState("LOCAL_DRIVE");
|
|
30134
|
+
}
|
|
30030
30135
|
async takeControl() {
|
|
30031
30136
|
await this.switchDriver(
|
|
30032
30137
|
"LOCAL_DRIVE",
|
|
@@ -30088,7 +30193,7 @@ function parkTerminalForReadonly(term = {}) {
|
|
|
30088
30193
|
}
|
|
30089
30194
|
|
|
30090
30195
|
// src/baton/native-tui-driver.ts
|
|
30091
|
-
var NativeTuiDriver = class {
|
|
30196
|
+
var NativeTuiDriver = class _NativeTuiDriver {
|
|
30092
30197
|
constructor(deps) {
|
|
30093
30198
|
this.deps = deps;
|
|
30094
30199
|
this.agent = deps.agent;
|
|
@@ -30117,6 +30222,9 @@ var NativeTuiDriver = class {
|
|
|
30117
30222
|
idleMs;
|
|
30118
30223
|
now;
|
|
30119
30224
|
lastOutput;
|
|
30225
|
+
/** How long `start()` waits for a boot-time session store (Kimi) before
|
|
30226
|
+
* falling back to background/late-bind discovery (Codex, first-turn store). */
|
|
30227
|
+
static QUICK_DISCOVER_MS = 8e3;
|
|
30120
30228
|
outputSvc;
|
|
30121
30229
|
historySvc;
|
|
30122
30230
|
setKeepAlive;
|
|
@@ -30131,11 +30239,20 @@ var NativeTuiDriver = class {
|
|
|
30131
30239
|
await this.agent.spawn();
|
|
30132
30240
|
const preMinted = this.agent.spawnedSessionId;
|
|
30133
30241
|
if (preMinted) return preMinted;
|
|
30134
|
-
const
|
|
30135
|
-
|
|
30242
|
+
const discover = this.deps.runtime.discoverSessionId;
|
|
30243
|
+
if (!discover) {
|
|
30244
|
+
throw new Error("NativeTuiDriver: agent did not expose a session id after spawn");
|
|
30245
|
+
}
|
|
30246
|
+
const quick = await discover(this.deps.opts.cwd, {
|
|
30247
|
+
sinceMs: spawnedAt,
|
|
30248
|
+
timeoutMs: _NativeTuiDriver.QUICK_DISCOVER_MS
|
|
30136
30249
|
});
|
|
30137
|
-
if (
|
|
30138
|
-
|
|
30250
|
+
if (quick) return quick;
|
|
30251
|
+
void discover(this.deps.opts.cwd, { sinceMs: spawnedAt }).then((id) => {
|
|
30252
|
+
if (id) this.deps.onLateBind?.(id);
|
|
30253
|
+
}).catch(() => {
|
|
30254
|
+
});
|
|
30255
|
+
return null;
|
|
30139
30256
|
}
|
|
30140
30257
|
async stop() {
|
|
30141
30258
|
this.agent.kill();
|
|
@@ -30549,7 +30666,12 @@ async function runBatonSession(opts) {
|
|
|
30549
30666
|
cwd: opts.cwd
|
|
30550
30667
|
},
|
|
30551
30668
|
getRelay: () => relay,
|
|
30552
|
-
getBeads: opts.getBeads ?? (() => null)
|
|
30669
|
+
getBeads: opts.getBeads ?? (() => null),
|
|
30670
|
+
// Late-bind for first-turn-minted ids (Codex): the background discovery
|
|
30671
|
+
// calls this once the user's first terminal turn creates the transcript.
|
|
30672
|
+
// Safe forward-ref — `controller` is initialised long before `begin()` runs,
|
|
30673
|
+
// and onLateBind only fires from inside `begin()`'s spawn.
|
|
30674
|
+
onLateBind: (id) => controller.rebindConversation(id)
|
|
30553
30675
|
});
|
|
30554
30676
|
let mirror = null;
|
|
30555
30677
|
let firstLocalDrive = true;
|
|
@@ -33541,7 +33663,7 @@ function checkChokidar() {
|
|
|
33541
33663
|
}
|
|
33542
33664
|
async function doctor(args2 = []) {
|
|
33543
33665
|
const json = args2.includes("--json");
|
|
33544
|
-
const cliVersion = true ? "2.60.
|
|
33666
|
+
const cliVersion = true ? "2.60.22" : "0.0.0-dev";
|
|
33545
33667
|
const apiBase2 = resolveApiBaseUrl();
|
|
33546
33668
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
33547
33669
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -33740,7 +33862,7 @@ async function completion(args2) {
|
|
|
33740
33862
|
// src/commands/version.ts
|
|
33741
33863
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33742
33864
|
function version2() {
|
|
33743
|
-
const v = true ? "2.60.
|
|
33865
|
+
const v = true ? "2.60.22" : "unknown";
|
|
33744
33866
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33745
33867
|
}
|
|
33746
33868
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.22",
|
|
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",
|