codeam-cli 2.76.30 → 2.76.31
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 +15 -0
- package/dist/index.js +72 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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.76.30] — 2026-10-14
|
|
8
|
+
|
|
9
|
+
### CI
|
|
10
|
+
|
|
11
|
+
- **release:** Build the Box image only after npm serves the version
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- **release:** Describe the next → canary → latest release gate in the README
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **cli:** Preview prewarm skips an empty scratch project
|
|
20
|
+
- **cli:** Identify with the current plan from /reconnect, not the pair-time one
|
|
21
|
+
|
|
7
22
|
## [2.76.29] — 2026-10-13
|
|
8
23
|
|
|
9
24
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -10627,7 +10627,7 @@ function readAnonId() {
|
|
|
10627
10627
|
}
|
|
10628
10628
|
function superProperties() {
|
|
10629
10629
|
return {
|
|
10630
|
-
cliVersion: true ? "2.76.
|
|
10630
|
+
cliVersion: true ? "2.76.31" : "0.0.0-dev",
|
|
10631
10631
|
nodeVersion: process.version,
|
|
10632
10632
|
platform: process.platform,
|
|
10633
10633
|
arch: process.arch,
|
|
@@ -10876,7 +10876,7 @@ var http = __toESM(require("http"));
|
|
|
10876
10876
|
// package.json
|
|
10877
10877
|
var package_default = {
|
|
10878
10878
|
name: "codeam-cli",
|
|
10879
|
-
version: "2.76.
|
|
10879
|
+
version: "2.76.31",
|
|
10880
10880
|
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.",
|
|
10881
10881
|
type: "commonjs",
|
|
10882
10882
|
main: "dist/index.js",
|
|
@@ -12241,7 +12241,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12241
12241
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12242
12242
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12243
12243
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12244
|
-
..."2.76.
|
|
12244
|
+
..."2.76.31" ? { ideVersion: "2.76.31" } : {}
|
|
12245
12245
|
};
|
|
12246
12246
|
try {
|
|
12247
12247
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body, this.pollSecretHeader());
|
|
@@ -19489,7 +19489,7 @@ var CodexRuntimeStrategy = class {
|
|
|
19489
19489
|
async generateOneShot(prompt, opts) {
|
|
19490
19490
|
const binary = this.os.findInPath("codex");
|
|
19491
19491
|
if (!binary) return null;
|
|
19492
|
-
const launch = this.os.buildLaunch(binary, ["exec", prompt]);
|
|
19492
|
+
const launch = this.os.buildLaunch(binary, ["exec", "--skip-git-repo-check", prompt]);
|
|
19493
19493
|
const runOnce = () => {
|
|
19494
19494
|
let stderr = "";
|
|
19495
19495
|
return spawnAndCapture(launch.cmd, launch.args, {
|
|
@@ -27280,7 +27280,12 @@ async function startDevServer(ctx, extraEnv = {}) {
|
|
|
27280
27280
|
emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
|
|
27281
27281
|
const devServer = (0, import_child_process20.spawn)(spawnable.command, spawnable.args, {
|
|
27282
27282
|
cwd,
|
|
27283
|
-
|
|
27283
|
+
// PYTHONUNBUFFERED: Python block-buffers stdout into a pipe, so a
|
|
27284
|
+
// `python3 -m http.server` (what the detector picks for a plain HTML site)
|
|
27285
|
+
// never shows its "Serving HTTP on … (http://0.0.0.0:8000/)" line while it
|
|
27286
|
+
// already serves — every such preview ended in a 120 s ready_timeout
|
|
27287
|
+
// (codeagent-nczt.9). First, so the project's own env can still override it.
|
|
27288
|
+
env: { PYTHONUNBUFFERED: "1", ...process.env, ...spawnable.env ?? {}, ...extraEnv },
|
|
27284
27289
|
stdio: ["ignore", "pipe", "pipe"],
|
|
27285
27290
|
// POSIX: lead a new process group so teardown can SIGTERM the whole
|
|
27286
27291
|
// tree. Dev servers fork worker children that bind the port; killing
|
|
@@ -38906,6 +38911,26 @@ function boundStreamingChunkContent(content, max = STREAMING_CHUNK_SNAPSHOT_MAX_
|
|
|
38906
38911
|
truncated: true
|
|
38907
38912
|
};
|
|
38908
38913
|
}
|
|
38914
|
+
var CHAT_TEXT_MAX_BYTES = 192 * 1024;
|
|
38915
|
+
var CHAT_TEXT_FALLBACK_MAX_BYTES = 32 * 1024;
|
|
38916
|
+
function boundChatText(content, maxBytes = CHAT_TEXT_MAX_BYTES) {
|
|
38917
|
+
const bytes = Buffer.from(content, "utf8");
|
|
38918
|
+
if (bytes.length <= maxBytes) return { content, truncated: false };
|
|
38919
|
+
const budget = Math.max(0, maxBytes - 256);
|
|
38920
|
+
const headBytes = Math.floor(budget * 0.4);
|
|
38921
|
+
const tailBytes = budget - headBytes;
|
|
38922
|
+
const head = bytes.subarray(0, headBytes).toString("utf8").replace(/\uFFFD+$/, "");
|
|
38923
|
+
const tail = bytes.subarray(bytes.length - tailBytes).toString("utf8").replace(/^\uFFFD+/, "");
|
|
38924
|
+
const omittedKb = Math.max(1, Math.round((bytes.length - headBytes - tailBytes) / 1024));
|
|
38925
|
+
return {
|
|
38926
|
+
content: `${head}
|
|
38927
|
+
|
|
38928
|
+
\u2026 [${omittedKb} KB of this reply left out \u2014 too long to show in full] \u2026
|
|
38929
|
+
|
|
38930
|
+
${tail}`,
|
|
38931
|
+
truncated: true
|
|
38932
|
+
};
|
|
38933
|
+
}
|
|
38909
38934
|
var AcpPublisher = class {
|
|
38910
38935
|
constructor(opts) {
|
|
38911
38936
|
this.opts = opts;
|
|
@@ -38924,6 +38949,10 @@ var AcpPublisher = class {
|
|
|
38924
38949
|
* (2026-06-28 incident: a dead-token publisher spammed 401 ×34 while
|
|
38925
38950
|
* the agent's replies silently never reached the phone). */
|
|
38926
38951
|
pairingInvalid = false;
|
|
38952
|
+
/** Set when the server refused a streaming `text` frame with 413: further
|
|
38953
|
+
* partial frames of the turn would be refused too, so they are dropped
|
|
38954
|
+
* until the next `new_turn` / `clear`. The terminal frame still goes. */
|
|
38955
|
+
oversizeTextTurn = false;
|
|
38927
38956
|
authHeaders() {
|
|
38928
38957
|
return {
|
|
38929
38958
|
"Content-Type": "application/json",
|
|
@@ -39005,8 +39034,29 @@ var AcpPublisher = class {
|
|
|
39005
39034
|
*/
|
|
39006
39035
|
async publishOutput(body) {
|
|
39007
39036
|
const url2 = `${this.apiBase}/api/commands/output`;
|
|
39008
|
-
|
|
39009
|
-
|
|
39037
|
+
const isText = body.type === "text" && typeof body.content === "string";
|
|
39038
|
+
const isFinal = body.done === true;
|
|
39039
|
+
if (body.type === "new_turn" || body.type === "clear") this.oversizeTextTurn = false;
|
|
39040
|
+
if (isText && !isFinal && this.oversizeTextTurn) return;
|
|
39041
|
+
if (isText) {
|
|
39042
|
+
const bounded = boundChatText(body.content);
|
|
39043
|
+
if (bounded.truncated) body = { ...body, content: bounded.content };
|
|
39044
|
+
}
|
|
39045
|
+
try {
|
|
39046
|
+
let { statusCode, body: resBody } = await this.postWithReauth(url2, this.envelope(body));
|
|
39047
|
+
if (statusCode === 413 && isText) {
|
|
39048
|
+
if (!isFinal) {
|
|
39049
|
+
this.oversizeTextTurn = true;
|
|
39050
|
+
log.warn("acpPublisher", "output text frame refused 413 \u2014 dropping partial frames until the turn ends");
|
|
39051
|
+
return;
|
|
39052
|
+
}
|
|
39053
|
+
const fallback = boundChatText(body.content, CHAT_TEXT_FALLBACK_MAX_BYTES);
|
|
39054
|
+
log.warn("acpPublisher", "output done:true refused 413 \u2014 retrying once with a shortened reply");
|
|
39055
|
+
({ statusCode, body: resBody } = await this.postWithReauth(
|
|
39056
|
+
url2,
|
|
39057
|
+
this.envelope({ ...body, content: fallback.content })
|
|
39058
|
+
));
|
|
39059
|
+
}
|
|
39010
39060
|
if (statusCode < 200 || statusCode >= 300) {
|
|
39011
39061
|
log.warn(
|
|
39012
39062
|
"acpPublisher",
|
|
@@ -42061,7 +42111,11 @@ function describeResult(raw) {
|
|
|
42061
42111
|
return {
|
|
42062
42112
|
// The agent once answered a failed spawn with "the preview is open, here
|
|
42063
42113
|
// is the link" (2026-10-05). Say plainly that nothing is serving.
|
|
42064
|
-
text: `Preview failed at ${String(r.stage)}: ${String(r.message)}. The preview is NOT running \u2014 do not give the user a preview link
|
|
42114
|
+
text: `Preview failed at ${String(r.stage)}: ${String(r.message).replace(/\.+$/, "")}. The preview is NOT running \u2014 do not give the user a preview link.` + (r.output ? ` The dev server's last output:
|
|
42115
|
+
\`\`\`
|
|
42116
|
+
${String(r.output)}
|
|
42117
|
+
\`\`\`
|
|
42118
|
+
If it shows a mistake in the command (a wrong flag, a missing file), call start_preview again with the fixed command; otherwise tell the user what failed.` : " Tell the user what failed."),
|
|
42065
42119
|
isError: true
|
|
42066
42120
|
};
|
|
42067
42121
|
default:
|
|
@@ -42394,6 +42448,7 @@ var MAX_AGENT_RESTARTS = 3;
|
|
|
42394
42448
|
var AGENT_RESTART_WINDOW_MS = 10 * 6e4;
|
|
42395
42449
|
var MAX_SELECTOR = 500;
|
|
42396
42450
|
var MAX_LABEL = 80;
|
|
42451
|
+
var AGENT_OUTPUT_TAIL = 2e3;
|
|
42397
42452
|
var AgentPreviewBridge = class {
|
|
42398
42453
|
server = null;
|
|
42399
42454
|
listening = null;
|
|
@@ -42599,9 +42654,11 @@ var AgentPreviewBridge = class {
|
|
|
42599
42654
|
origin: "agent",
|
|
42600
42655
|
onEvent: (type, payload) => {
|
|
42601
42656
|
if (type === USER_EVENTS.PREVIEW_ERROR) {
|
|
42657
|
+
const output = String(payload.stderrTail ?? "").trim().slice(-AGENT_OUTPUT_TAIL);
|
|
42602
42658
|
failure = {
|
|
42603
42659
|
stage: String(payload.stage ?? "spawn"),
|
|
42604
|
-
message: String(payload.message ?? "The preview failed to start.")
|
|
42660
|
+
message: String(payload.message ?? "The preview failed to start."),
|
|
42661
|
+
...output ? { output } : {}
|
|
42605
42662
|
};
|
|
42606
42663
|
}
|
|
42607
42664
|
}
|
|
@@ -51421,7 +51478,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
51421
51478
|
if (process.env.NODE_ENV === "test") return;
|
|
51422
51479
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51423
51480
|
if (process.env.CI) return;
|
|
51424
|
-
const current2 = true ? "2.76.
|
|
51481
|
+
const current2 = true ? "2.76.31" : null;
|
|
51425
51482
|
if (!current2) return;
|
|
51426
51483
|
const cache = readCache();
|
|
51427
51484
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51438,7 +51495,7 @@ function checkForUpdates() {
|
|
|
51438
51495
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51439
51496
|
if (process.env.CI) return;
|
|
51440
51497
|
if (!process.stdout.isTTY) return;
|
|
51441
|
-
const current2 = true ? "2.76.
|
|
51498
|
+
const current2 = true ? "2.76.31" : null;
|
|
51442
51499
|
if (!current2) return;
|
|
51443
51500
|
const cache = readCache();
|
|
51444
51501
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51721,7 +51778,7 @@ var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
|
51721
51778
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
51722
51779
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
51723
51780
|
function currentCliVersion() {
|
|
51724
|
-
return true ? "2.76.
|
|
51781
|
+
return true ? "2.76.31" : null;
|
|
51725
51782
|
}
|
|
51726
51783
|
async function installedVersion(deps) {
|
|
51727
51784
|
const ls = await deps.run(
|
|
@@ -51932,7 +51989,7 @@ function signalHostReady(send = process.send?.bind(process)) {
|
|
|
51932
51989
|
}
|
|
51933
51990
|
function defaultDeps() {
|
|
51934
51991
|
return {
|
|
51935
|
-
ownVersion: true ? "2.76.
|
|
51992
|
+
ownVersion: true ? "2.76.31" : null,
|
|
51936
51993
|
root: cliVersionsRoot(),
|
|
51937
51994
|
args: process.argv.slice(3),
|
|
51938
51995
|
execPath: process.execPath,
|
|
@@ -54470,7 +54527,7 @@ function checkChokidar() {
|
|
|
54470
54527
|
}
|
|
54471
54528
|
async function doctor(args2 = []) {
|
|
54472
54529
|
const json = args2.includes("--json");
|
|
54473
|
-
const cliVersion = true ? "2.76.
|
|
54530
|
+
const cliVersion = true ? "2.76.31" : "0.0.0-dev";
|
|
54474
54531
|
const apiBase2 = resolveApiBaseUrl();
|
|
54475
54532
|
const diagnosticId = (0, import_node_crypto17.randomUUID)();
|
|
54476
54533
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -55006,7 +55063,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
55006
55063
|
// src/commands/version.ts
|
|
55007
55064
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
55008
55065
|
function version2() {
|
|
55009
|
-
const v = true ? "2.76.
|
|
55066
|
+
const v = true ? "2.76.31" : "unknown";
|
|
55010
55067
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
55011
55068
|
}
|
|
55012
55069
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.76.
|
|
3
|
+
"version": "2.76.31",
|
|
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",
|