codeam-cli 2.42.0 → 2.43.0
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 +11 -0
- package/dist/index.js +126 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ 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.42.0] — 2026-06-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Confirm provider outage via status page on turn stall/failure (catch-all)
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **cli:** Make agent-failure messaging honest — outage only on real provider error, re-auth on auth-notice replies
|
|
16
|
+
- **cli:** Keep the heartbeat punctual by detecting the git branch off the hot path
|
|
17
|
+
|
|
7
18
|
## [2.41.0] — 2026-06-24
|
|
8
19
|
|
|
9
20
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -476,6 +476,13 @@ function makeConfig(baseDir) {
|
|
|
476
476
|
matches.sort((a, b) => b.pairedAt - a.pairedAt);
|
|
477
477
|
return matches[0];
|
|
478
478
|
}
|
|
479
|
+
function setDisable1mContext2(pluginId, value) {
|
|
480
|
+
const c2 = load();
|
|
481
|
+
const s = c2.sessions.find((x) => x.pluginId === pluginId);
|
|
482
|
+
if (!s) return;
|
|
483
|
+
s.disable1mContext = value;
|
|
484
|
+
save(c2);
|
|
485
|
+
}
|
|
479
486
|
function clearAll2() {
|
|
480
487
|
try {
|
|
481
488
|
fs.unlinkSync(file);
|
|
@@ -488,7 +495,7 @@ function makeConfig(baseDir) {
|
|
|
488
495
|
function loadCliConfig2() {
|
|
489
496
|
return load();
|
|
490
497
|
}
|
|
491
|
-
return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, getActiveSessionForAgent: getActiveSessionForAgent2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
|
|
498
|
+
return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, getActiveSessionForAgent: getActiveSessionForAgent2, setDisable1mContext: setDisable1mContext2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
|
|
492
499
|
}
|
|
493
500
|
var CODESPACE_ENV_KEYS = [
|
|
494
501
|
"PREVIEW_TUNNEL_TOKEN",
|
|
@@ -512,7 +519,7 @@ function loadCodespaceEnv() {
|
|
|
512
519
|
}
|
|
513
520
|
}
|
|
514
521
|
var _default = makeConfig();
|
|
515
|
-
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
522
|
+
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
516
523
|
|
|
517
524
|
// src/commands/pair-auto.ts
|
|
518
525
|
var fs41 = __toESM(require("fs"));
|
|
@@ -5390,7 +5397,7 @@ function readAnonId() {
|
|
|
5390
5397
|
}
|
|
5391
5398
|
function superProperties() {
|
|
5392
5399
|
return {
|
|
5393
|
-
cliVersion: true ? "2.
|
|
5400
|
+
cliVersion: true ? "2.43.0" : "0.0.0-dev",
|
|
5394
5401
|
nodeVersion: process.version,
|
|
5395
5402
|
platform: process.platform,
|
|
5396
5403
|
arch: process.arch,
|
|
@@ -5571,7 +5578,7 @@ var os4 = __toESM(require("os"));
|
|
|
5571
5578
|
// package.json
|
|
5572
5579
|
var package_default = {
|
|
5573
5580
|
name: "codeam-cli",
|
|
5574
|
-
version: "2.
|
|
5581
|
+
version: "2.43.0",
|
|
5575
5582
|
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.",
|
|
5576
5583
|
type: "commonjs",
|
|
5577
5584
|
main: "dist/index.js",
|
|
@@ -17804,7 +17811,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17804
17811
|
if (process.env.NODE_ENV === "test") return;
|
|
17805
17812
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17806
17813
|
if (process.env.CI) return;
|
|
17807
|
-
const current = true ? "2.
|
|
17814
|
+
const current = true ? "2.43.0" : null;
|
|
17808
17815
|
if (!current) return;
|
|
17809
17816
|
const cache = readCache();
|
|
17810
17817
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17821,7 +17828,7 @@ function checkForUpdates() {
|
|
|
17821
17828
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17822
17829
|
if (process.env.CI) return;
|
|
17823
17830
|
if (!process.stdout.isTTY) return;
|
|
17824
|
-
const current = true ? "2.
|
|
17831
|
+
const current = true ? "2.43.0" : null;
|
|
17825
17832
|
if (!current) return;
|
|
17826
17833
|
const cache = readCache();
|
|
17827
17834
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18259,7 +18266,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.s
|
|
|
18259
18266
|
detached: false
|
|
18260
18267
|
});
|
|
18261
18268
|
function currentCliVersion() {
|
|
18262
|
-
return true ? "2.
|
|
18269
|
+
return true ? "2.43.0" : null;
|
|
18263
18270
|
}
|
|
18264
18271
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18265
18272
|
return new Promise((resolve7) => {
|
|
@@ -22737,7 +22744,10 @@ var AcpClient = class {
|
|
|
22737
22744
|
);
|
|
22738
22745
|
const child = (0, import_node_child_process16.spawn)(adapter.command, adapter.args, {
|
|
22739
22746
|
cwd,
|
|
22740
|
-
|
|
22747
|
+
// extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
|
|
22748
|
+
// re-spawn) layers over process.env; PATH stays last so the augmented
|
|
22749
|
+
// PATH always wins.
|
|
22750
|
+
env: { ...process.env, ...this.opts.extraEnv ?? {}, PATH: augmentedPath },
|
|
22741
22751
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22742
22752
|
});
|
|
22743
22753
|
this.child = child;
|
|
@@ -23431,6 +23441,66 @@ function buildAcpPromptBlocks(payload) {
|
|
|
23431
23441
|
return blocks;
|
|
23432
23442
|
}
|
|
23433
23443
|
|
|
23444
|
+
// src/agents/acp/oneMContextRecovery.ts
|
|
23445
|
+
var ONE_M_CONTEXT_CREDITS_RE = /usage credits required for 1m context/i;
|
|
23446
|
+
function looksLike1mContextCreditsError(text) {
|
|
23447
|
+
return ONE_M_CONTEXT_CREDITS_RE.test(text);
|
|
23448
|
+
}
|
|
23449
|
+
var ONE_M_DISABLE_OPTION = "Disable 1M context and continue";
|
|
23450
|
+
function shouldOfferOneMRecovery(opts) {
|
|
23451
|
+
return looksLike1mContextCreditsError(opts.detail) || looksLike1mContextCreditsError(opts.recentStderr) || looksLike1mContextCreditsError(opts.finalText);
|
|
23452
|
+
}
|
|
23453
|
+
function oneMRecoverySelectPrompt() {
|
|
23454
|
+
return {
|
|
23455
|
+
question: "\u26A0\uFE0F This agent's Anthropic account needs usage credits for 1M context. You can disable 1M context (uses standard 200K context) and continue.",
|
|
23456
|
+
options: [ONE_M_DISABLE_OPTION]
|
|
23457
|
+
};
|
|
23458
|
+
}
|
|
23459
|
+
function createOneMRecovery(deps) {
|
|
23460
|
+
let pending = null;
|
|
23461
|
+
const sp = oneMRecoverySelectPrompt();
|
|
23462
|
+
return {
|
|
23463
|
+
offer: async (commandId, blocks) => {
|
|
23464
|
+
pending = { blocks };
|
|
23465
|
+
await deps.publishText(sp.question);
|
|
23466
|
+
await deps.publishSelectPrompt(sp.question, sp.options);
|
|
23467
|
+
deps.appendAgentReply(sp.question);
|
|
23468
|
+
deps.flushHistory();
|
|
23469
|
+
deps.log?.(`1M-context credits gate \u2014 recovery offered id=${commandId.slice(0, 8)}`);
|
|
23470
|
+
await deps.sendResult(commandId, "failed", {
|
|
23471
|
+
error: "1M context requires usage credits \u2014 recovery offered"
|
|
23472
|
+
});
|
|
23473
|
+
},
|
|
23474
|
+
tryRecover: async (commandId) => {
|
|
23475
|
+
if (!pending) return false;
|
|
23476
|
+
const blocks = pending.blocks;
|
|
23477
|
+
pending = null;
|
|
23478
|
+
deps.log?.("1M-context recovery \u2192 disable + reconnect + rerun");
|
|
23479
|
+
await deps.reconnectWith1mDisabled();
|
|
23480
|
+
await deps.beginTurn();
|
|
23481
|
+
try {
|
|
23482
|
+
const reply = await deps.promptAgent(blocks);
|
|
23483
|
+
const finalText = deps.getCurrentText();
|
|
23484
|
+
await deps.closeTurn();
|
|
23485
|
+
deps.appendAgentReply(finalText);
|
|
23486
|
+
deps.flushHistory();
|
|
23487
|
+
await deps.sendResult(commandId, "completed", { stopReason: reply.stopReason });
|
|
23488
|
+
} catch (err) {
|
|
23489
|
+
await deps.recoverFromFailedTurn();
|
|
23490
|
+
const d3 = deps.describeError(err);
|
|
23491
|
+
const b = deps.failureBubbleFor(d3);
|
|
23492
|
+
if (b) {
|
|
23493
|
+
await deps.publishText(b);
|
|
23494
|
+
deps.appendAgentReply(b);
|
|
23495
|
+
deps.flushHistory();
|
|
23496
|
+
}
|
|
23497
|
+
await deps.sendResult(commandId, "failed", { error: d3 });
|
|
23498
|
+
}
|
|
23499
|
+
return true;
|
|
23500
|
+
}
|
|
23501
|
+
};
|
|
23502
|
+
}
|
|
23503
|
+
|
|
23434
23504
|
// src/agents/acp/reconcileDelta.ts
|
|
23435
23505
|
function reconcileCumulative(existing, incoming) {
|
|
23436
23506
|
if (incoming.length === 0) return existing;
|
|
@@ -24793,9 +24863,11 @@ async function runAcpSession(opts) {
|
|
|
24793
24863
|
}
|
|
24794
24864
|
});
|
|
24795
24865
|
let updateCount = 0;
|
|
24796
|
-
const
|
|
24866
|
+
const disable1mContext = loadCliConfig().sessions.find((s) => s.pluginId === opts.pluginId)?.disable1mContext === true;
|
|
24867
|
+
const clientOptions = {
|
|
24797
24868
|
adapter: opts.adapter,
|
|
24798
24869
|
cwd: opts.cwd,
|
|
24870
|
+
extraEnv: disable1mContext ? { CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" } : {},
|
|
24799
24871
|
onSessionUpdate: (notification) => {
|
|
24800
24872
|
updateCount += 1;
|
|
24801
24873
|
const variant = notification.update?.sessionUpdate ?? "unknown";
|
|
@@ -24860,6 +24932,39 @@ async function runAcpSession(opts) {
|
|
|
24860
24932
|
process.exit(1);
|
|
24861
24933
|
})();
|
|
24862
24934
|
}
|
|
24935
|
+
};
|
|
24936
|
+
let client2 = new AcpClient(clientOptions);
|
|
24937
|
+
const reconnectWith1mDisabled = async () => {
|
|
24938
|
+
setDisable1mContext(opts.pluginId, true);
|
|
24939
|
+
try {
|
|
24940
|
+
await client2.stop();
|
|
24941
|
+
} catch {
|
|
24942
|
+
}
|
|
24943
|
+
client2 = new AcpClient({ ...clientOptions, extraEnv: { CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" } });
|
|
24944
|
+
await client2.start();
|
|
24945
|
+
};
|
|
24946
|
+
const oneMRecovery = createOneMRecovery({
|
|
24947
|
+
publishText: (text) => publisher.publishOutput({ type: "text", content: text, done: true }),
|
|
24948
|
+
publishSelectPrompt: (question, options) => publisher.publishOutput({
|
|
24949
|
+
type: "select_prompt",
|
|
24950
|
+
content: question,
|
|
24951
|
+
options,
|
|
24952
|
+
optionDescriptions: options.map(() => ""),
|
|
24953
|
+
currentIndex: 0,
|
|
24954
|
+
done: true
|
|
24955
|
+
}),
|
|
24956
|
+
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
24957
|
+
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
24958
|
+
flushHistory: () => void history.flush(),
|
|
24959
|
+
beginTurn: () => streaming.beginTurn(),
|
|
24960
|
+
getCurrentText: () => streaming.getCurrentText(),
|
|
24961
|
+
closeTurn: () => streaming.closeTurnWithInteractiveDetection(),
|
|
24962
|
+
recoverFromFailedTurn: () => recoverFromFailedTurn(client2, streaming),
|
|
24963
|
+
reconnectWith1mDisabled,
|
|
24964
|
+
promptAgent: (blocks) => client2.prompt(blocks),
|
|
24965
|
+
failureBubbleFor: (detail) => failureBubble({ detail, recentStderr: recentStderr.join("\n"), hadText: false, agent: opts.agent }),
|
|
24966
|
+
describeError,
|
|
24967
|
+
log: (msg) => log.info("acpRunner", msg)
|
|
24863
24968
|
});
|
|
24864
24969
|
showInfo(`Starting ${opts.agent} via ACP adapter (${opts.adapter.requiresAgentBinary})\u2026`);
|
|
24865
24970
|
const {
|
|
@@ -24954,7 +25059,8 @@ async function runAcpSession(opts) {
|
|
|
24954
25059
|
turnFiles,
|
|
24955
25060
|
getBeads,
|
|
24956
25061
|
publisher,
|
|
24957
|
-
recentStderr
|
|
25062
|
+
recentStderr,
|
|
25063
|
+
oneMRecovery
|
|
24958
25064
|
);
|
|
24959
25065
|
},
|
|
24960
25066
|
{ id: opts.agent, name: opts.agent, displayName: opts.agent }
|
|
@@ -24978,7 +25084,7 @@ async function runAcpSession(opts) {
|
|
|
24978
25084
|
await new Promise(() => {
|
|
24979
25085
|
});
|
|
24980
25086
|
}
|
|
24981
|
-
async function handleCommand(cmd, client2, relay, acpSessionId, models, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr) {
|
|
25087
|
+
async function handleCommand(cmd, client2, relay, acpSessionId, models, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr, oneMRecovery) {
|
|
24982
25088
|
switch (cmd.type) {
|
|
24983
25089
|
case "beads_action": {
|
|
24984
25090
|
const beads = getBeads();
|
|
@@ -25029,6 +25135,8 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
|
|
|
25029
25135
|
void reportCredentialInvalid(opts);
|
|
25030
25136
|
log.info("acpRunner", `start_task \u2190 auth-failure-in-reply id=${cmd.id.slice(0, 8)}`);
|
|
25031
25137
|
await relay.sendResult(cmd.id, "failed", { error: "agent reply reported auth failure" });
|
|
25138
|
+
} else if (shouldOfferOneMRecovery({ detail: "", recentStderr: recentStderr.join("\n"), finalText })) {
|
|
25139
|
+
await oneMRecovery.offer(cmd.id, blocks);
|
|
25032
25140
|
} else {
|
|
25033
25141
|
await streaming.closeTurnWithInteractiveDetection();
|
|
25034
25142
|
const replyLine = formatAgentReplyLine(finalText);
|
|
@@ -25048,6 +25156,10 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
|
|
|
25048
25156
|
await recoverFromFailedTurn(client2, streaming);
|
|
25049
25157
|
const detail = describeError(err);
|
|
25050
25158
|
log.warn("acpRunner", `prompt failed: ${detail}`);
|
|
25159
|
+
if (shouldOfferOneMRecovery({ detail, recentStderr: recentStderr.join("\n"), finalText: "" })) {
|
|
25160
|
+
await oneMRecovery.offer(cmd.id, blocks);
|
|
25161
|
+
return;
|
|
25162
|
+
}
|
|
25051
25163
|
const bubble = failureBubble({
|
|
25052
25164
|
detail,
|
|
25053
25165
|
recentStderr: recentStderr.join("\n"),
|
|
@@ -25142,6 +25254,7 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
|
|
|
25142
25254
|
return;
|
|
25143
25255
|
}
|
|
25144
25256
|
case "select_option": {
|
|
25257
|
+
if (await oneMRecovery.tryRecover(cmd.id)) return;
|
|
25145
25258
|
const payload = cmd.payload;
|
|
25146
25259
|
const index = typeof payload?.index === "number" ? payload.index : 0;
|
|
25147
25260
|
const offset = typeof payload?.from === "number" ? payload.from : 0;
|
|
@@ -29211,7 +29324,7 @@ function checkChokidar() {
|
|
|
29211
29324
|
}
|
|
29212
29325
|
async function doctor(args2 = []) {
|
|
29213
29326
|
const json = args2.includes("--json");
|
|
29214
|
-
const cliVersion = true ? "2.
|
|
29327
|
+
const cliVersion = true ? "2.43.0" : "0.0.0-dev";
|
|
29215
29328
|
const apiBase2 = resolveApiBaseUrl();
|
|
29216
29329
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
29217
29330
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -29410,7 +29523,7 @@ async function completion(args2) {
|
|
|
29410
29523
|
// src/commands/version.ts
|
|
29411
29524
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
29412
29525
|
function version2() {
|
|
29413
|
-
const v = true ? "2.
|
|
29526
|
+
const v = true ? "2.43.0" : "unknown";
|
|
29414
29527
|
console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
|
|
29415
29528
|
}
|
|
29416
29529
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.43.0",
|
|
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",
|