codeam-cli 2.65.6 → 2.65.7
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 +79 -26
- 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.65.6] — 2026-08-15
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Accumulated stream keeps post-cut deltas + unclosed trailing fence tolerated
|
|
12
|
+
|
|
7
13
|
## [2.65.4] — 2026-08-14
|
|
8
14
|
|
|
9
15
|
### Fixed
|
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.7" : "0.0.0-dev",
|
|
8083
8083
|
nodeVersion: process.version,
|
|
8084
8084
|
platform: process.platform,
|
|
8085
8085
|
arch: process.arch,
|
|
@@ -8260,7 +8260,7 @@ var os4 = __toESM(require("os"));
|
|
|
8260
8260
|
// package.json
|
|
8261
8261
|
var package_default = {
|
|
8262
8262
|
name: "codeam-cli",
|
|
8263
|
-
version: "2.65.
|
|
8263
|
+
version: "2.65.7",
|
|
8264
8264
|
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.",
|
|
8265
8265
|
type: "commonjs",
|
|
8266
8266
|
main: "dist/index.js",
|
|
@@ -8632,7 +8632,19 @@ async function postHeadroomEvent(input) {
|
|
|
8632
8632
|
};
|
|
8633
8633
|
}
|
|
8634
8634
|
}
|
|
8635
|
-
|
|
8635
|
+
function parseBackendErrorBody(body) {
|
|
8636
|
+
if (!body) return null;
|
|
8637
|
+
try {
|
|
8638
|
+
const parsed = JSON.parse(body);
|
|
8639
|
+
const nested = parsed.error;
|
|
8640
|
+
const code = typeof nested?.code === "string" ? nested.code : typeof parsed.code === "string" ? parsed.code : void 0;
|
|
8641
|
+
const message = typeof nested?.message === "string" ? nested.message : typeof parsed.message === "string" ? parsed.message : void 0;
|
|
8642
|
+
return code || message ? { code, message } : null;
|
|
8643
|
+
} catch {
|
|
8644
|
+
return null;
|
|
8645
|
+
}
|
|
8646
|
+
}
|
|
8647
|
+
async function fetchProvisionCredentialDetailed(input) {
|
|
8636
8648
|
try {
|
|
8637
8649
|
const res = await _transport.postJsonAuthed(
|
|
8638
8650
|
`${API_BASE}/api/plugin/agents/${input.agentId}/provision-credential`,
|
|
@@ -8646,16 +8658,29 @@ async function fetchProvisionCredential(input) {
|
|
|
8646
8658
|
const data = res?.data;
|
|
8647
8659
|
if (data && (data.method === "api_key" || data.method === "oauth") && typeof data.credential === "string" && data.credential.length > 0) {
|
|
8648
8660
|
return {
|
|
8661
|
+
ok: true,
|
|
8649
8662
|
method: data.method,
|
|
8650
8663
|
credential: data.credential,
|
|
8651
8664
|
...typeof data.installScript === "string" && data.installScript.length > 0 ? { installScript: data.installScript } : {}
|
|
8652
8665
|
};
|
|
8653
8666
|
}
|
|
8654
|
-
return
|
|
8655
|
-
} catch {
|
|
8656
|
-
|
|
8667
|
+
return { ok: false, status: 0 };
|
|
8668
|
+
} catch (err) {
|
|
8669
|
+
const e = err;
|
|
8670
|
+
const status2 = typeof e.statusCode === "number" ? e.statusCode : 0;
|
|
8671
|
+
const parsed = parseBackendErrorBody(e.body);
|
|
8672
|
+
return { ok: false, status: status2, code: parsed?.code, message: parsed?.message };
|
|
8657
8673
|
}
|
|
8658
8674
|
}
|
|
8675
|
+
async function fetchProvisionCredential(input) {
|
|
8676
|
+
const res = await fetchProvisionCredentialDetailed(input);
|
|
8677
|
+
if (!res.ok) return null;
|
|
8678
|
+
return {
|
|
8679
|
+
method: res.method,
|
|
8680
|
+
credential: res.credential,
|
|
8681
|
+
...res.installScript ? { installScript: res.installScript } : {}
|
|
8682
|
+
};
|
|
8683
|
+
}
|
|
8659
8684
|
async function fetchSquadRoster(input) {
|
|
8660
8685
|
try {
|
|
8661
8686
|
const res = await _transport.postJsonAuthed(
|
|
@@ -8860,6 +8885,7 @@ function makeHttpError(statusCode, retryAfterHeader, responseBody) {
|
|
|
8860
8885
|
);
|
|
8861
8886
|
err.statusCode = statusCode;
|
|
8862
8887
|
if (typeof retryAfterSeconds === "number") err.retryAfterSeconds = retryAfterSeconds;
|
|
8888
|
+
if (responseBody) err.body = responseBody;
|
|
8863
8889
|
return err;
|
|
8864
8890
|
}
|
|
8865
8891
|
async function _postJson(url2, body, extraHeaders) {
|
|
@@ -9712,7 +9738,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9712
9738
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
9713
9739
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
9714
9740
|
// pair/reconnect). Older backends ignore the extra field.
|
|
9715
|
-
..."2.65.
|
|
9741
|
+
..."2.65.7" ? { ideVersion: "2.65.7" } : {}
|
|
9716
9742
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
9717
9743
|
}
|
|
9718
9744
|
/**
|
|
@@ -21641,7 +21667,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
21641
21667
|
if (process.env.NODE_ENV === "test") return;
|
|
21642
21668
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21643
21669
|
if (process.env.CI) return;
|
|
21644
|
-
const current2 = true ? "2.65.
|
|
21670
|
+
const current2 = true ? "2.65.7" : null;
|
|
21645
21671
|
if (!current2) return;
|
|
21646
21672
|
const cache = readCache();
|
|
21647
21673
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21658,7 +21684,7 @@ function checkForUpdates() {
|
|
|
21658
21684
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21659
21685
|
if (process.env.CI) return;
|
|
21660
21686
|
if (!process.stdout.isTTY) return;
|
|
21661
|
-
const current2 = true ? "2.65.
|
|
21687
|
+
const current2 = true ? "2.65.7" : null;
|
|
21662
21688
|
if (!current2) return;
|
|
21663
21689
|
const cache = readCache();
|
|
21664
21690
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21678,7 +21704,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
21678
21704
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
21679
21705
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
21680
21706
|
function currentCliVersion() {
|
|
21681
|
-
return true ? "2.65.
|
|
21707
|
+
return true ? "2.65.7" : null;
|
|
21682
21708
|
}
|
|
21683
21709
|
function runCmd(cmd, args2, timeoutMs) {
|
|
21684
21710
|
return new Promise((resolve9) => {
|
|
@@ -34738,6 +34764,10 @@ var NON_SWITCHABLE = /* @__PURE__ */ new Set([
|
|
|
34738
34764
|
function displayName(id) {
|
|
34739
34765
|
return isKnownAgentId(id) ? AGENT_REGISTRY[id]?.displayName ?? id : id;
|
|
34740
34766
|
}
|
|
34767
|
+
function credentialFailureMessage(agentId, failure) {
|
|
34768
|
+
if (failure.message) return failure.message;
|
|
34769
|
+
return `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`;
|
|
34770
|
+
}
|
|
34741
34771
|
function resolveSwitchTarget(raw, currentAgent) {
|
|
34742
34772
|
if (typeof raw !== "string" || raw.length === 0) {
|
|
34743
34773
|
return { ok: false, error: "switch_agent: missing agentId" };
|
|
@@ -34854,10 +34884,8 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
|
|
|
34854
34884
|
if (!fastPath.skipProvision) {
|
|
34855
34885
|
void emitStep("credential");
|
|
34856
34886
|
const cred = await deps.fetchCredential(agentId);
|
|
34857
|
-
if (!cred) {
|
|
34858
|
-
return fail2(
|
|
34859
|
-
`No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`
|
|
34860
|
-
);
|
|
34887
|
+
if (!cred.ok) {
|
|
34888
|
+
return fail2(credentialFailureMessage(agentId, cred));
|
|
34861
34889
|
}
|
|
34862
34890
|
try {
|
|
34863
34891
|
deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
|
|
@@ -35574,6 +35602,15 @@ function handoffFenceStartMasked(text) {
|
|
|
35574
35602
|
}
|
|
35575
35603
|
return -1;
|
|
35576
35604
|
}
|
|
35605
|
+
function withholdTrailingPartialFenceMarker(text) {
|
|
35606
|
+
const maxLen = Math.min(text.length, FENCE_OPEN.length - 1);
|
|
35607
|
+
for (let len = maxLen; len > 0; len--) {
|
|
35608
|
+
if (FENCE_OPEN.startsWith(text.slice(text.length - len))) {
|
|
35609
|
+
return text.slice(0, text.length - len);
|
|
35610
|
+
}
|
|
35611
|
+
}
|
|
35612
|
+
return text;
|
|
35613
|
+
}
|
|
35577
35614
|
|
|
35578
35615
|
// src/agents/acp/onboarding.ts
|
|
35579
35616
|
var import_child_process28 = require("child_process");
|
|
@@ -36608,6 +36645,11 @@ var AUTH_FAILURE_MESSAGE = "\u{1F512} **Authentication failed \u2014 your agent
|
|
|
36608
36645
|
var CURSOR_UPGRADE_MESSAGE = "\u26A1 **Cursor needs a paid plan to run the agent.**\n\nThe headless Cursor Agent requires Cursor **Pro** \u2014 your Free plan\u2019s included usage does NOT cover Agent runs, even with quota left. This is your Cursor account (not CodeAgent). Upgrade, then send your message again:\n\n[Upgrade to Cursor Pro \u2192](https://cursor.com/dashboard)";
|
|
36609
36646
|
var ONE_M_CREDITS_MESSAGE = "\u{1F504} **Reconnect your Claude subscription to continue.**\n\nClaude requested 1M-context but your account doesn\u2019t have the usage credits for it on this credential. Reconnecting refreshes your subscription so the agent can keep going \u2014 disabling 1M context won\u2019t fix a credits gate.\n\nTap [Reconnect this agent](codeam://reauth) to reconnect your Claude subscription in Profile \u203A Agents, then send your message again.";
|
|
36610
36647
|
var TURN_FAILURE_MESSAGE = "\u26A0\uFE0F **The agent hit an error and couldn\u2019t finish this turn.** Please send your message again.";
|
|
36648
|
+
function emptyReplyMessage(agent) {
|
|
36649
|
+
const label = isKnownAgentId(agent) ? AGENT_REGISTRY[agent].displayName : agent;
|
|
36650
|
+
const binary = isKnownAgentId(agent) ? AGENT_REGISTRY[agent].binaryName : agent;
|
|
36651
|
+
return `\u26A0\uFE0F **${label} returned an empty reply.** Its provider may be having issues \u2014 check the agent's login/subscription on this machine (e.g. run \`${binary} -p "test"\` there).`;
|
|
36652
|
+
}
|
|
36611
36653
|
var PROVIDER_OUTAGE_RE = /overloaded_error|\boverloaded\b|service[ _]unavailable|temporarily[ _]unavailable|(?:api error|http|status)[:\s]+(?:529|503|502|504)\b|\b(?:529|503|502|504)\b[^\n]{0,40}(?:overload|unavailable|gateway|upstream|server error)|bad gateway|gateway time-?out|upstream (?:error|connect|timeout)/i;
|
|
36612
36654
|
function looksLikeProviderOutage(text) {
|
|
36613
36655
|
return PROVIDER_OUTAGE_RE.test(text);
|
|
@@ -36643,12 +36685,10 @@ ${recentStderr}`;
|
|
|
36643
36685
|
if (looksLikeAuthFailure(haystack2)) return AUTH_FAILURE_MESSAGE;
|
|
36644
36686
|
if (looksLikeProviderOutage(haystack2)) return providerOutageMessage(agent);
|
|
36645
36687
|
const tail = recentStderr.split("\n").filter(Boolean).slice(-3).join("\n");
|
|
36646
|
-
return [
|
|
36647
|
-
|
|
36648
|
-
""
|
|
36649
|
-
|
|
36650
|
-
${tail}` : detail
|
|
36651
|
-
].join("\n");
|
|
36688
|
+
return [`\u26A0\uFE0F The ${agent} agent failed to start.`, "", tail ? `Details:
|
|
36689
|
+
${tail}` : detail].join(
|
|
36690
|
+
"\n"
|
|
36691
|
+
);
|
|
36652
36692
|
}
|
|
36653
36693
|
function budgetBubbleMessage(agent, period) {
|
|
36654
36694
|
return `\u{1F4B8} **Headroom budget reached for the ${period} period.**
|
|
@@ -38064,6 +38104,18 @@ async function startTaskH(ctx) {
|
|
|
38064
38104
|
error: "agent reply reported 1M-context usage-credits gate"
|
|
38065
38105
|
});
|
|
38066
38106
|
return;
|
|
38107
|
+
} else if (reply.stopReason === "end_turn" && finalText.trim().length === 0 && !streaming.hasVisibleProgress()) {
|
|
38108
|
+
const bubble = emptyReplyMessage(opts.agent);
|
|
38109
|
+
await streaming.closeWithBubble(bubble);
|
|
38110
|
+
turnClosed = true;
|
|
38111
|
+
history.appendAgentReply(bubble);
|
|
38112
|
+
void history.flush();
|
|
38113
|
+
turnFiles.flushTurn().catch((err) => {
|
|
38114
|
+
log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
|
|
38115
|
+
});
|
|
38116
|
+
log.info("acpRunner", `start_task \u2190 empty-reply id=${cmd.id.slice(0, 8)}`);
|
|
38117
|
+
await relay.sendResult(cmd.id, "failed", { error: "agent turn ended with an empty reply" });
|
|
38118
|
+
return;
|
|
38067
38119
|
} else {
|
|
38068
38120
|
await streaming.closeTurnWithInteractiveDetection();
|
|
38069
38121
|
turnClosed = true;
|
|
@@ -38956,13 +39008,14 @@ var StreamingState = class {
|
|
|
38956
39008
|
const cumulativeContent = reconcileCumulative(existing?.content ?? "", delta.delta);
|
|
38957
39009
|
this.streamingChunks.set(chunkId, { kind: delta.kind, content: cumulativeContent });
|
|
38958
39010
|
let fenceCut = -1;
|
|
39011
|
+
let textVisible = null;
|
|
38959
39012
|
if (delta.kind === "text") {
|
|
38960
39013
|
this.recomputeText();
|
|
38961
39014
|
fenceCut = handoffFenceStartMasked(this.text);
|
|
38962
|
-
|
|
38963
|
-
void this.publisher.publishOutput({ type: "text", content:
|
|
39015
|
+
textVisible = fenceCut === -1 ? withholdTrailingPartialFenceMarker(this.text) : this.text.slice(0, fenceCut).trimEnd();
|
|
39016
|
+
void this.publisher.publishOutput({ type: "text", content: textVisible, done: false });
|
|
38964
39017
|
}
|
|
38965
|
-
const visibleChunkContent = delta.kind === "text"
|
|
39018
|
+
const visibleChunkContent = delta.kind === "text" ? textVisible : cumulativeContent;
|
|
38966
39019
|
void this.publisher.publishStreamingChunk({
|
|
38967
39020
|
chunkId,
|
|
38968
39021
|
kind: delta.kind,
|
|
@@ -39697,7 +39750,7 @@ async function runAcpSession(opts) {
|
|
|
39697
39750
|
const switchDeps = {
|
|
39698
39751
|
currentAgent: () => opts.agent,
|
|
39699
39752
|
postEvent: emitSwitchEvent,
|
|
39700
|
-
fetchCredential: (agentId) =>
|
|
39753
|
+
fetchCredential: (agentId) => fetchProvisionCredentialDetailed({
|
|
39701
39754
|
agentId,
|
|
39702
39755
|
sessionId: opts.sessionId,
|
|
39703
39756
|
pluginId: opts.pluginId,
|
|
@@ -44625,7 +44678,7 @@ function checkChokidar() {
|
|
|
44625
44678
|
}
|
|
44626
44679
|
async function doctor(args2 = []) {
|
|
44627
44680
|
const json = args2.includes("--json");
|
|
44628
|
-
const cliVersion = true ? "2.65.
|
|
44681
|
+
const cliVersion = true ? "2.65.7" : "0.0.0-dev";
|
|
44629
44682
|
const apiBase2 = resolveApiBaseUrl();
|
|
44630
44683
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
44631
44684
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -45016,7 +45069,7 @@ async function mcpRun(args2) {
|
|
|
45016
45069
|
// src/commands/version.ts
|
|
45017
45070
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
45018
45071
|
function version2() {
|
|
45019
|
-
const v = true ? "2.65.
|
|
45072
|
+
const v = true ? "2.65.7" : "unknown";
|
|
45020
45073
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
45021
45074
|
}
|
|
45022
45075
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.65.
|
|
3
|
+
"version": "2.65.7",
|
|
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",
|