codeam-cli 2.60.9 → 2.60.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/CHANGELOG.md +12 -0
- package/dist/index.js +72 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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.10] — 2026-07-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Detailed observability for the gemini baton paths
|
|
12
|
+
|
|
13
|
+
## [2.60.9] — 2026-07-08
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Baton support for gemini (native-TUI mirror + resume)
|
|
18
|
+
|
|
7
19
|
## [2.60.8] — 2026-07-08
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -220,15 +220,18 @@ var MODEL_PRICING = {
|
|
|
220
220
|
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
221
221
|
"claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 },
|
|
222
222
|
// ── Codex / OpenAI ────────────────────────────────────────
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
"gpt-5.
|
|
230
|
-
"gpt-5.
|
|
231
|
-
"
|
|
223
|
+
// GPT-5.x rows are derived from OpenAI's published GPT-5 family rates
|
|
224
|
+
// (standard tier: $1.25/1M in, $10/1M out, cached input at ~10% of input;
|
|
225
|
+
// mini tier: $0.25/1M in, $2/1M out). OpenAI has no separate cache-WRITE
|
|
226
|
+
// premium, so cacheWrite mirrors the input rate. Replace with the exact
|
|
227
|
+
// per-version numbers from developers.openai.com/pricing when published —
|
|
228
|
+
// these were the ZERO placeholders that rendered Codex sessions as $0.
|
|
229
|
+
"gpt-5.5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
|
|
230
|
+
"gpt-5.4": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
|
|
231
|
+
"gpt-5.4-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0.25 },
|
|
232
|
+
"gpt-5.3-codex": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
|
|
233
|
+
"gpt-5.2": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
|
|
234
|
+
"codex-auto-review": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 }
|
|
232
235
|
};
|
|
233
236
|
var MODEL_CONTEXT_WINDOW = {
|
|
234
237
|
// ── Anthropic / Claude ────────────────────────────────────
|
|
@@ -261,8 +264,14 @@ function longestPrefixMatch(table, model) {
|
|
|
261
264
|
}
|
|
262
265
|
return best;
|
|
263
266
|
}
|
|
267
|
+
var UNKNOWN_MODEL_PRICING = {
|
|
268
|
+
input: 0,
|
|
269
|
+
output: 0,
|
|
270
|
+
cacheRead: 0,
|
|
271
|
+
cacheWrite: 0
|
|
272
|
+
};
|
|
264
273
|
function getPricing(model) {
|
|
265
|
-
return longestPrefixMatch(MODEL_PRICING, model) ??
|
|
274
|
+
return longestPrefixMatch(MODEL_PRICING, model) ?? UNKNOWN_MODEL_PRICING;
|
|
266
275
|
}
|
|
267
276
|
function getContextWindow(model) {
|
|
268
277
|
if (!model) return DEFAULT_CONTEXT_WINDOW;
|
|
@@ -5653,7 +5662,7 @@ function readAnonId() {
|
|
|
5653
5662
|
}
|
|
5654
5663
|
function superProperties() {
|
|
5655
5664
|
return {
|
|
5656
|
-
cliVersion: true ? "2.60.
|
|
5665
|
+
cliVersion: true ? "2.60.11" : "0.0.0-dev",
|
|
5657
5666
|
nodeVersion: process.version,
|
|
5658
5667
|
platform: process.platform,
|
|
5659
5668
|
arch: process.arch,
|
|
@@ -5834,7 +5843,7 @@ var os4 = __toESM(require("os"));
|
|
|
5834
5843
|
// package.json
|
|
5835
5844
|
var package_default = {
|
|
5836
5845
|
name: "codeam-cli",
|
|
5837
|
-
version: "2.60.
|
|
5846
|
+
version: "2.60.11",
|
|
5838
5847
|
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
5848
|
type: "commonjs",
|
|
5840
5849
|
main: "dist/index.js",
|
|
@@ -6905,7 +6914,7 @@ var CommandRelayService = class {
|
|
|
6905
6914
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6906
6915
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6907
6916
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6908
|
-
..."2.60.
|
|
6917
|
+
..."2.60.11" ? { ideVersion: "2.60.11" } : {}
|
|
6909
6918
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6910
6919
|
}
|
|
6911
6920
|
/**
|
|
@@ -13978,36 +13987,56 @@ function projectNameForCwd(cwd, root) {
|
|
|
13978
13987
|
} catch {
|
|
13979
13988
|
}
|
|
13980
13989
|
}
|
|
13981
|
-
|
|
13990
|
+
log.debug("gemini", `projects.json has no entry for cwd=${cwd} \u2014 using basename fallback`);
|
|
13991
|
+
} catch (err) {
|
|
13992
|
+
log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
|
|
13982
13993
|
}
|
|
13983
13994
|
return path32.basename(cwd) || null;
|
|
13984
13995
|
}
|
|
13985
13996
|
function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
13986
13997
|
const name = projectNameForCwd(cwd, root);
|
|
13987
|
-
if (!name)
|
|
13998
|
+
if (!name) {
|
|
13999
|
+
log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
|
|
14000
|
+
return null;
|
|
14001
|
+
}
|
|
13988
14002
|
const dir = path32.join(root, "tmp", name, "chats");
|
|
13989
|
-
|
|
14003
|
+
if (!fs28.existsSync(dir)) {
|
|
14004
|
+
log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
|
|
14005
|
+
return null;
|
|
14006
|
+
}
|
|
14007
|
+
return dir;
|
|
13990
14008
|
}
|
|
13991
14009
|
function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
14010
|
+
const id8 = sessionId.slice(0, 8);
|
|
13992
14011
|
const dir = resolveHistoryDir5(cwd, root);
|
|
13993
14012
|
if (!dir) return null;
|
|
13994
14013
|
let files;
|
|
13995
14014
|
try {
|
|
13996
14015
|
files = fs28.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
13997
|
-
} catch {
|
|
14016
|
+
} catch (err) {
|
|
14017
|
+
log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
|
|
14018
|
+
return null;
|
|
14019
|
+
}
|
|
14020
|
+
if (files.length === 0) {
|
|
14021
|
+
log.debug("gemini", `resolveHistoryFile \u2014 no session-*.jsonl yet in ${dir} (id8=${id8})`);
|
|
13998
14022
|
return null;
|
|
13999
14023
|
}
|
|
14000
|
-
if (files.length === 0) return null;
|
|
14001
|
-
const id8 = sessionId.slice(0, 8);
|
|
14002
14024
|
const byName = files.find((f) => id8.length > 0 && f.includes(id8));
|
|
14003
|
-
if (byName)
|
|
14025
|
+
if (byName) {
|
|
14026
|
+
log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
|
|
14027
|
+
return path32.join(dir, byName);
|
|
14028
|
+
}
|
|
14004
14029
|
for (const f of files) {
|
|
14005
14030
|
const full = path32.join(dir, f);
|
|
14006
14031
|
try {
|
|
14007
14032
|
const firstLine = fs28.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
|
|
14008
14033
|
const hdr = JSON.parse(firstLine);
|
|
14009
|
-
if (hdr.sessionId === sessionId)
|
|
14010
|
-
|
|
14034
|
+
if (hdr.sessionId === sessionId) {
|
|
14035
|
+
log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
|
|
14036
|
+
return full;
|
|
14037
|
+
}
|
|
14038
|
+
} catch (err) {
|
|
14039
|
+
log.debug("gemini", `resolveHistoryFile \u2014 unreadable/non-JSON header in ${f}`, err);
|
|
14011
14040
|
}
|
|
14012
14041
|
}
|
|
14013
14042
|
let newest = null;
|
|
@@ -14018,6 +14047,10 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
14018
14047
|
} catch {
|
|
14019
14048
|
}
|
|
14020
14049
|
}
|
|
14050
|
+
log.warn(
|
|
14051
|
+
"gemini",
|
|
14052
|
+
`resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
|
|
14053
|
+
);
|
|
14021
14054
|
return newest ? path32.join(dir, newest.file) : null;
|
|
14022
14055
|
}
|
|
14023
14056
|
function extractGeminiText(content) {
|
|
@@ -14047,12 +14080,14 @@ function parseHistoryFile5(filePath) {
|
|
|
14047
14080
|
let raw;
|
|
14048
14081
|
try {
|
|
14049
14082
|
raw = fs28.readFileSync(filePath, "utf8");
|
|
14050
|
-
} catch {
|
|
14083
|
+
} catch (err) {
|
|
14084
|
+
log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
|
|
14051
14085
|
return [];
|
|
14052
14086
|
}
|
|
14053
14087
|
const out2 = [];
|
|
14054
14088
|
const seen = /* @__PURE__ */ new Set();
|
|
14055
14089
|
let idx = 0;
|
|
14090
|
+
let malformed = 0;
|
|
14056
14091
|
const consider = (m) => {
|
|
14057
14092
|
if (m.type !== "user" && m.type !== "gemini") return;
|
|
14058
14093
|
const id = typeof m.id === "string" ? m.id : `pos-${idx}`;
|
|
@@ -14074,6 +14109,7 @@ function parseHistoryFile5(filePath) {
|
|
|
14074
14109
|
try {
|
|
14075
14110
|
rec = JSON.parse(line);
|
|
14076
14111
|
} catch {
|
|
14112
|
+
malformed += 1;
|
|
14077
14113
|
continue;
|
|
14078
14114
|
}
|
|
14079
14115
|
if (rec.$set && Array.isArray(rec.$set.messages)) {
|
|
@@ -14082,6 +14118,10 @@ function parseHistoryFile5(filePath) {
|
|
|
14082
14118
|
consider(rec);
|
|
14083
14119
|
}
|
|
14084
14120
|
}
|
|
14121
|
+
log.trace(
|
|
14122
|
+
"gemini",
|
|
14123
|
+
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${path32.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
|
|
14124
|
+
);
|
|
14085
14125
|
return out2;
|
|
14086
14126
|
}
|
|
14087
14127
|
|
|
@@ -14122,6 +14162,10 @@ var GeminiRuntimeStrategy = class {
|
|
|
14122
14162
|
}
|
|
14123
14163
|
const sessionId = (0, import_node_crypto5.randomUUID)();
|
|
14124
14164
|
const launch = this.os.buildLaunch(binary, ["--session-id", sessionId]);
|
|
14165
|
+
log.info(
|
|
14166
|
+
"gemini",
|
|
14167
|
+
`prepareLaunch \u2014 native TUI, binary=${binary} sessionId=${sessionId} (id8=${sessionId.slice(0, 8)})`
|
|
14168
|
+
);
|
|
14125
14169
|
return { cmd: launch.cmd, args: launch.args, sessionId };
|
|
14126
14170
|
}
|
|
14127
14171
|
// Re-attach the same conversation on hand-back (baton) by passing the same
|
|
@@ -16140,7 +16184,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16140
16184
|
if (process.env.NODE_ENV === "test") return;
|
|
16141
16185
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16142
16186
|
if (process.env.CI) return;
|
|
16143
|
-
const current = true ? "2.60.
|
|
16187
|
+
const current = true ? "2.60.11" : null;
|
|
16144
16188
|
if (!current) return;
|
|
16145
16189
|
const cache = readCache();
|
|
16146
16190
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16157,7 +16201,7 @@ function checkForUpdates() {
|
|
|
16157
16201
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16158
16202
|
if (process.env.CI) return;
|
|
16159
16203
|
if (!process.stdout.isTTY) return;
|
|
16160
|
-
const current = true ? "2.60.
|
|
16204
|
+
const current = true ? "2.60.11" : null;
|
|
16161
16205
|
if (!current) return;
|
|
16162
16206
|
const cache = readCache();
|
|
16163
16207
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16177,7 +16221,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16177
16221
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16178
16222
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16179
16223
|
function currentCliVersion() {
|
|
16180
|
-
return true ? "2.60.
|
|
16224
|
+
return true ? "2.60.11" : null;
|
|
16181
16225
|
}
|
|
16182
16226
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16183
16227
|
return new Promise((resolve7) => {
|
|
@@ -32956,7 +33000,7 @@ function checkChokidar() {
|
|
|
32956
33000
|
}
|
|
32957
33001
|
async function doctor(args2 = []) {
|
|
32958
33002
|
const json = args2.includes("--json");
|
|
32959
|
-
const cliVersion = true ? "2.60.
|
|
33003
|
+
const cliVersion = true ? "2.60.11" : "0.0.0-dev";
|
|
32960
33004
|
const apiBase2 = resolveApiBaseUrl();
|
|
32961
33005
|
const diagnosticId = (0, import_node_crypto10.randomUUID)();
|
|
32962
33006
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -33155,7 +33199,7 @@ async function completion(args2) {
|
|
|
33155
33199
|
// src/commands/version.ts
|
|
33156
33200
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33157
33201
|
function version2() {
|
|
33158
|
-
const v = true ? "2.60.
|
|
33202
|
+
const v = true ? "2.60.11" : "unknown";
|
|
33159
33203
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33160
33204
|
}
|
|
33161
33205
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.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",
|