codeam-cli 2.60.9 → 2.60.10
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 +6 -0
- package/dist/index.js +53 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.9] — 2026-07-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Baton support for gemini (native-TUI mirror + resume)
|
|
12
|
+
|
|
7
13
|
## [2.60.8] — 2026-07-08
|
|
8
14
|
|
|
9
15
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -5653,7 +5653,7 @@ function readAnonId() {
|
|
|
5653
5653
|
}
|
|
5654
5654
|
function superProperties() {
|
|
5655
5655
|
return {
|
|
5656
|
-
cliVersion: true ? "2.60.
|
|
5656
|
+
cliVersion: true ? "2.60.10" : "0.0.0-dev",
|
|
5657
5657
|
nodeVersion: process.version,
|
|
5658
5658
|
platform: process.platform,
|
|
5659
5659
|
arch: process.arch,
|
|
@@ -5834,7 +5834,7 @@ var os4 = __toESM(require("os"));
|
|
|
5834
5834
|
// package.json
|
|
5835
5835
|
var package_default = {
|
|
5836
5836
|
name: "codeam-cli",
|
|
5837
|
-
version: "2.60.
|
|
5837
|
+
version: "2.60.10",
|
|
5838
5838
|
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.",
|
|
5839
5839
|
type: "commonjs",
|
|
5840
5840
|
main: "dist/index.js",
|
|
@@ -6905,7 +6905,7 @@ var CommandRelayService = class {
|
|
|
6905
6905
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6906
6906
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6907
6907
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6908
|
-
..."2.60.
|
|
6908
|
+
..."2.60.10" ? { ideVersion: "2.60.10" } : {}
|
|
6909
6909
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6910
6910
|
}
|
|
6911
6911
|
/**
|
|
@@ -13978,36 +13978,56 @@ function projectNameForCwd(cwd, root) {
|
|
|
13978
13978
|
} catch {
|
|
13979
13979
|
}
|
|
13980
13980
|
}
|
|
13981
|
-
|
|
13981
|
+
log.debug("gemini", `projects.json has no entry for cwd=${cwd} \u2014 using basename fallback`);
|
|
13982
|
+
} catch (err) {
|
|
13983
|
+
log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
|
|
13982
13984
|
}
|
|
13983
13985
|
return path32.basename(cwd) || null;
|
|
13984
13986
|
}
|
|
13985
13987
|
function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
13986
13988
|
const name = projectNameForCwd(cwd, root);
|
|
13987
|
-
if (!name)
|
|
13989
|
+
if (!name) {
|
|
13990
|
+
log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
|
|
13991
|
+
return null;
|
|
13992
|
+
}
|
|
13988
13993
|
const dir = path32.join(root, "tmp", name, "chats");
|
|
13989
|
-
|
|
13994
|
+
if (!fs28.existsSync(dir)) {
|
|
13995
|
+
log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
|
|
13996
|
+
return null;
|
|
13997
|
+
}
|
|
13998
|
+
return dir;
|
|
13990
13999
|
}
|
|
13991
14000
|
function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
14001
|
+
const id8 = sessionId.slice(0, 8);
|
|
13992
14002
|
const dir = resolveHistoryDir5(cwd, root);
|
|
13993
14003
|
if (!dir) return null;
|
|
13994
14004
|
let files;
|
|
13995
14005
|
try {
|
|
13996
14006
|
files = fs28.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
13997
|
-
} catch {
|
|
14007
|
+
} catch (err) {
|
|
14008
|
+
log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
|
|
14009
|
+
return null;
|
|
14010
|
+
}
|
|
14011
|
+
if (files.length === 0) {
|
|
14012
|
+
log.debug("gemini", `resolveHistoryFile \u2014 no session-*.jsonl yet in ${dir} (id8=${id8})`);
|
|
13998
14013
|
return null;
|
|
13999
14014
|
}
|
|
14000
|
-
if (files.length === 0) return null;
|
|
14001
|
-
const id8 = sessionId.slice(0, 8);
|
|
14002
14015
|
const byName = files.find((f) => id8.length > 0 && f.includes(id8));
|
|
14003
|
-
if (byName)
|
|
14016
|
+
if (byName) {
|
|
14017
|
+
log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
|
|
14018
|
+
return path32.join(dir, byName);
|
|
14019
|
+
}
|
|
14004
14020
|
for (const f of files) {
|
|
14005
14021
|
const full = path32.join(dir, f);
|
|
14006
14022
|
try {
|
|
14007
14023
|
const firstLine = fs28.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
|
|
14008
14024
|
const hdr = JSON.parse(firstLine);
|
|
14009
|
-
if (hdr.sessionId === sessionId)
|
|
14010
|
-
|
|
14025
|
+
if (hdr.sessionId === sessionId) {
|
|
14026
|
+
log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
|
|
14027
|
+
return full;
|
|
14028
|
+
}
|
|
14029
|
+
} catch (err) {
|
|
14030
|
+
log.debug("gemini", `resolveHistoryFile \u2014 unreadable/non-JSON header in ${f}`, err);
|
|
14011
14031
|
}
|
|
14012
14032
|
}
|
|
14013
14033
|
let newest = null;
|
|
@@ -14018,6 +14038,10 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
14018
14038
|
} catch {
|
|
14019
14039
|
}
|
|
14020
14040
|
}
|
|
14041
|
+
log.warn(
|
|
14042
|
+
"gemini",
|
|
14043
|
+
`resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
|
|
14044
|
+
);
|
|
14021
14045
|
return newest ? path32.join(dir, newest.file) : null;
|
|
14022
14046
|
}
|
|
14023
14047
|
function extractGeminiText(content) {
|
|
@@ -14047,12 +14071,14 @@ function parseHistoryFile5(filePath) {
|
|
|
14047
14071
|
let raw;
|
|
14048
14072
|
try {
|
|
14049
14073
|
raw = fs28.readFileSync(filePath, "utf8");
|
|
14050
|
-
} catch {
|
|
14074
|
+
} catch (err) {
|
|
14075
|
+
log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
|
|
14051
14076
|
return [];
|
|
14052
14077
|
}
|
|
14053
14078
|
const out2 = [];
|
|
14054
14079
|
const seen = /* @__PURE__ */ new Set();
|
|
14055
14080
|
let idx = 0;
|
|
14081
|
+
let malformed = 0;
|
|
14056
14082
|
const consider = (m) => {
|
|
14057
14083
|
if (m.type !== "user" && m.type !== "gemini") return;
|
|
14058
14084
|
const id = typeof m.id === "string" ? m.id : `pos-${idx}`;
|
|
@@ -14074,6 +14100,7 @@ function parseHistoryFile5(filePath) {
|
|
|
14074
14100
|
try {
|
|
14075
14101
|
rec = JSON.parse(line);
|
|
14076
14102
|
} catch {
|
|
14103
|
+
malformed += 1;
|
|
14077
14104
|
continue;
|
|
14078
14105
|
}
|
|
14079
14106
|
if (rec.$set && Array.isArray(rec.$set.messages)) {
|
|
@@ -14082,6 +14109,10 @@ function parseHistoryFile5(filePath) {
|
|
|
14082
14109
|
consider(rec);
|
|
14083
14110
|
}
|
|
14084
14111
|
}
|
|
14112
|
+
log.trace(
|
|
14113
|
+
"gemini",
|
|
14114
|
+
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${path32.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
|
|
14115
|
+
);
|
|
14085
14116
|
return out2;
|
|
14086
14117
|
}
|
|
14087
14118
|
|
|
@@ -14122,6 +14153,10 @@ var GeminiRuntimeStrategy = class {
|
|
|
14122
14153
|
}
|
|
14123
14154
|
const sessionId = (0, import_node_crypto5.randomUUID)();
|
|
14124
14155
|
const launch = this.os.buildLaunch(binary, ["--session-id", sessionId]);
|
|
14156
|
+
log.info(
|
|
14157
|
+
"gemini",
|
|
14158
|
+
`prepareLaunch \u2014 native TUI, binary=${binary} sessionId=${sessionId} (id8=${sessionId.slice(0, 8)})`
|
|
14159
|
+
);
|
|
14125
14160
|
return { cmd: launch.cmd, args: launch.args, sessionId };
|
|
14126
14161
|
}
|
|
14127
14162
|
// Re-attach the same conversation on hand-back (baton) by passing the same
|
|
@@ -16140,7 +16175,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16140
16175
|
if (process.env.NODE_ENV === "test") return;
|
|
16141
16176
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16142
16177
|
if (process.env.CI) return;
|
|
16143
|
-
const current = true ? "2.60.
|
|
16178
|
+
const current = true ? "2.60.10" : null;
|
|
16144
16179
|
if (!current) return;
|
|
16145
16180
|
const cache = readCache();
|
|
16146
16181
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16157,7 +16192,7 @@ function checkForUpdates() {
|
|
|
16157
16192
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16158
16193
|
if (process.env.CI) return;
|
|
16159
16194
|
if (!process.stdout.isTTY) return;
|
|
16160
|
-
const current = true ? "2.60.
|
|
16195
|
+
const current = true ? "2.60.10" : null;
|
|
16161
16196
|
if (!current) return;
|
|
16162
16197
|
const cache = readCache();
|
|
16163
16198
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16177,7 +16212,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16177
16212
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16178
16213
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16179
16214
|
function currentCliVersion() {
|
|
16180
|
-
return true ? "2.60.
|
|
16215
|
+
return true ? "2.60.10" : null;
|
|
16181
16216
|
}
|
|
16182
16217
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16183
16218
|
return new Promise((resolve7) => {
|
|
@@ -32956,7 +32991,7 @@ function checkChokidar() {
|
|
|
32956
32991
|
}
|
|
32957
32992
|
async function doctor(args2 = []) {
|
|
32958
32993
|
const json = args2.includes("--json");
|
|
32959
|
-
const cliVersion = true ? "2.60.
|
|
32994
|
+
const cliVersion = true ? "2.60.10" : "0.0.0-dev";
|
|
32960
32995
|
const apiBase2 = resolveApiBaseUrl();
|
|
32961
32996
|
const diagnosticId = (0, import_node_crypto10.randomUUID)();
|
|
32962
32997
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -33155,7 +33190,7 @@ async function completion(args2) {
|
|
|
33155
33190
|
// src/commands/version.ts
|
|
33156
33191
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33157
33192
|
function version2() {
|
|
33158
|
-
const v = true ? "2.60.
|
|
33193
|
+
const v = true ? "2.60.10" : "unknown";
|
|
33159
33194
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33160
33195
|
}
|
|
33161
33196
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.10",
|
|
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",
|