codeam-cli 2.61.95 → 2.61.97
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 +126 -30
- 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.61.96] — 2026-08-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **packs:** A review-only stage that approves clean is DONE, not a stall (#606)
|
|
12
|
+
|
|
13
|
+
## [2.61.95] — 2026-08-08
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Re-assert full-auto mode on Agent Packs fresh conversations (#605)
|
|
18
|
+
|
|
7
19
|
## [2.61.94] — 2026-08-08
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -90,11 +90,11 @@ var require_src = __commonJS({
|
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
// src/integrations/stdio-proxy.ts
|
|
93
|
-
var
|
|
93
|
+
var import_node_child_process33, import_node_readline3, RESTART_CHECK_INTERVAL_MS, SIGKILL_ESCALATION_MS, TOOL_CALL_TIMEOUT_MS, REPLAY_INIT_ID, RestartableStdioProxy;
|
|
94
94
|
var init_stdio_proxy = __esm({
|
|
95
95
|
"src/integrations/stdio-proxy.ts"() {
|
|
96
96
|
"use strict";
|
|
97
|
-
|
|
97
|
+
import_node_child_process33 = require("child_process");
|
|
98
98
|
import_node_readline3 = __toESM(require("readline"));
|
|
99
99
|
RESTART_CHECK_INTERVAL_MS = 3e4;
|
|
100
100
|
SIGKILL_ESCALATION_MS = 2e3;
|
|
@@ -271,8 +271,8 @@ var init_stdio_proxy = __esm({
|
|
|
271
271
|
}
|
|
272
272
|
async spawnChild(stdout, preResolved) {
|
|
273
273
|
const spec = preResolved ?? await this.opts.spawnSpec();
|
|
274
|
-
const
|
|
275
|
-
const child =
|
|
274
|
+
const spawn45 = this.opts.spawnImpl ?? import_node_child_process33.spawn;
|
|
275
|
+
const child = spawn45(spec.command, spec.args, {
|
|
276
276
|
env: { ...process.env, ...spec.env },
|
|
277
277
|
// env only — never argv
|
|
278
278
|
stdio: ["pipe", "pipe", "inherit"]
|
|
@@ -2711,7 +2711,9 @@ var PACK_REGISTRY = {
|
|
|
2711
2711
|
name: "Reviewer",
|
|
2712
2712
|
description: "Skeptical review in a fresh context \u2014 finds and fixes what the coder missed.",
|
|
2713
2713
|
skillIds: ["code-review", "code-naming"],
|
|
2714
|
-
prompt: REVIEWER_PROMPT
|
|
2714
|
+
prompt: REVIEWER_PROMPT,
|
|
2715
|
+
// Review-only: approving clean with no change is success, not a stall.
|
|
2716
|
+
requiresCommit: false
|
|
2715
2717
|
}
|
|
2716
2718
|
]
|
|
2717
2719
|
},
|
|
@@ -2740,7 +2742,9 @@ var PACK_REGISTRY = {
|
|
|
2740
2742
|
name: "Reviewer",
|
|
2741
2743
|
description: "Audits correctness, scope, design, and conventions with fresh eyes.",
|
|
2742
2744
|
skillIds: ["code-review", "code-naming"],
|
|
2743
|
-
prompt: REVIEWER_PROMPT
|
|
2745
|
+
prompt: REVIEWER_PROMPT,
|
|
2746
|
+
// Review-only: approving clean with no change is success, not a stall.
|
|
2747
|
+
requiresCommit: false
|
|
2744
2748
|
},
|
|
2745
2749
|
{
|
|
2746
2750
|
role: "qa",
|
|
@@ -8017,7 +8021,7 @@ function readAnonId() {
|
|
|
8017
8021
|
}
|
|
8018
8022
|
function superProperties() {
|
|
8019
8023
|
return {
|
|
8020
|
-
cliVersion: true ? "2.61.
|
|
8024
|
+
cliVersion: true ? "2.61.97" : "0.0.0-dev",
|
|
8021
8025
|
nodeVersion: process.version,
|
|
8022
8026
|
platform: process.platform,
|
|
8023
8027
|
arch: process.arch,
|
|
@@ -8198,7 +8202,7 @@ var os4 = __toESM(require("os"));
|
|
|
8198
8202
|
// package.json
|
|
8199
8203
|
var package_default = {
|
|
8200
8204
|
name: "codeam-cli",
|
|
8201
|
-
version: "2.61.
|
|
8205
|
+
version: "2.61.97",
|
|
8202
8206
|
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.",
|
|
8203
8207
|
type: "commonjs",
|
|
8204
8208
|
main: "dist/index.js",
|
|
@@ -9515,7 +9519,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9515
9519
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
9516
9520
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
9517
9521
|
// pair/reconnect). Older backends ignore the extra field.
|
|
9518
|
-
..."2.61.
|
|
9522
|
+
..."2.61.97" ? { ideVersion: "2.61.97" } : {}
|
|
9519
9523
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
9520
9524
|
}
|
|
9521
9525
|
/**
|
|
@@ -14061,9 +14065,26 @@ var PosixOsStrategy = class {
|
|
|
14061
14065
|
};
|
|
14062
14066
|
var DarwinOsStrategy = class extends PosixOsStrategy {
|
|
14063
14067
|
id = "darwin";
|
|
14068
|
+
keepAwakeCommand(pid) {
|
|
14069
|
+
return { cmd: "caffeinate", args: ["-i", "-s", "-w", String(pid)] };
|
|
14070
|
+
}
|
|
14064
14071
|
};
|
|
14065
14072
|
var LinuxOsStrategy = class extends PosixOsStrategy {
|
|
14066
14073
|
id = "linux";
|
|
14074
|
+
keepAwakeCommand(pid) {
|
|
14075
|
+
return {
|
|
14076
|
+
cmd: "systemd-inhibit",
|
|
14077
|
+
args: [
|
|
14078
|
+
"--what=sleep:idle",
|
|
14079
|
+
"--why=CodeAgent local session active",
|
|
14080
|
+
"--mode=block",
|
|
14081
|
+
"tail",
|
|
14082
|
+
`--pid=${pid}`,
|
|
14083
|
+
"-f",
|
|
14084
|
+
"/dev/null"
|
|
14085
|
+
]
|
|
14086
|
+
};
|
|
14087
|
+
}
|
|
14067
14088
|
};
|
|
14068
14089
|
|
|
14069
14090
|
// src/os/win32.ts
|
|
@@ -14347,6 +14368,19 @@ var Win32OsStrategy = class {
|
|
|
14347
14368
|
list.push(new WindowsPtyStrategy(opts));
|
|
14348
14369
|
return list;
|
|
14349
14370
|
}
|
|
14371
|
+
keepAwakeCommand(pid) {
|
|
14372
|
+
const script = [
|
|
14373
|
+
"$s=Add-Type -Name P -Namespace W -PassThru -MemberDefinition",
|
|
14374
|
+
`'[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint e);';`,
|
|
14375
|
+
"$s::SetThreadExecutionState(2147483649) | Out-Null;",
|
|
14376
|
+
`try { (Get-Process -Id ${pid} -ErrorAction Stop).WaitForExit() } catch {};`,
|
|
14377
|
+
"$s::SetThreadExecutionState(2147483648) | Out-Null;"
|
|
14378
|
+
].join(" ");
|
|
14379
|
+
return {
|
|
14380
|
+
cmd: "powershell",
|
|
14381
|
+
args: ["-NoProfile", "-NonInteractive", "-Command", script]
|
|
14382
|
+
};
|
|
14383
|
+
}
|
|
14350
14384
|
};
|
|
14351
14385
|
|
|
14352
14386
|
// src/os/registry.ts
|
|
@@ -20688,7 +20722,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
20688
20722
|
if (process.env.NODE_ENV === "test") return;
|
|
20689
20723
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
20690
20724
|
if (process.env.CI) return;
|
|
20691
|
-
const current2 = true ? "2.61.
|
|
20725
|
+
const current2 = true ? "2.61.97" : null;
|
|
20692
20726
|
if (!current2) return;
|
|
20693
20727
|
const cache = readCache();
|
|
20694
20728
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -20705,7 +20739,7 @@ function checkForUpdates() {
|
|
|
20705
20739
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
20706
20740
|
if (process.env.CI) return;
|
|
20707
20741
|
if (!process.stdout.isTTY) return;
|
|
20708
|
-
const current2 = true ? "2.61.
|
|
20742
|
+
const current2 = true ? "2.61.97" : null;
|
|
20709
20743
|
if (!current2) return;
|
|
20710
20744
|
const cache = readCache();
|
|
20711
20745
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -20725,7 +20759,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
20725
20759
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
20726
20760
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
20727
20761
|
function currentCliVersion() {
|
|
20728
|
-
return true ? "2.61.
|
|
20762
|
+
return true ? "2.61.97" : null;
|
|
20729
20763
|
}
|
|
20730
20764
|
function runCmd(cmd, args2, timeoutMs) {
|
|
20731
20765
|
return new Promise((resolve9) => {
|
|
@@ -33771,12 +33805,12 @@ function buildRelaunchProxyEnv(baseEnv) {
|
|
|
33771
33805
|
return env;
|
|
33772
33806
|
}
|
|
33773
33807
|
var relaunchProxyWithoutBudget = async () => {
|
|
33774
|
-
const { spawn:
|
|
33808
|
+
const { spawn: spawn45 } = await import("child_process");
|
|
33775
33809
|
killHeadroomProxy();
|
|
33776
33810
|
await new Promise((r) => setTimeout(r, 500));
|
|
33777
33811
|
const proxyEnv = buildRelaunchProxyEnv(process.env);
|
|
33778
33812
|
try {
|
|
33779
|
-
const proxy =
|
|
33813
|
+
const proxy = spawn45(
|
|
33780
33814
|
"headroom",
|
|
33781
33815
|
["proxy", "--port", "8787"],
|
|
33782
33816
|
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
@@ -35742,11 +35776,31 @@ var PackRunner = class _PackRunner {
|
|
|
35742
35776
|
await this.settle("aborted");
|
|
35743
35777
|
return false;
|
|
35744
35778
|
}
|
|
35779
|
+
const commitOptional = stageDef.requiresCommit === false;
|
|
35745
35780
|
let endSha = await this.deps.gates.head();
|
|
35746
35781
|
if (!endSha || endSha === startSha) {
|
|
35782
|
+
if (commitOptional && reply.trim().length > 0) {
|
|
35783
|
+
const reviewedCommit = startSha ? await this.deps.gates.canonicalCommit(startSha) : null;
|
|
35784
|
+
const handoff2 = {
|
|
35785
|
+
commit: reviewedCommit ?? "(no changes)",
|
|
35786
|
+
summary: reply.trim().slice(-SUMMARY_MAX_CHARS),
|
|
35787
|
+
diffStat: "reviewed \u2014 no changes needed",
|
|
35788
|
+
durationMs: Date.now() - startedMs
|
|
35789
|
+
};
|
|
35790
|
+
return this.recordHandoff(index, stageDef.role, handoff2);
|
|
35791
|
+
}
|
|
35747
35792
|
reply = await this.deps.driver.runTurn(NUDGE_PROMPT, "\u25B6 Waiting for the stage commit\u2026");
|
|
35748
35793
|
endSha = await this.deps.gates.head();
|
|
35749
35794
|
if (!endSha || endSha === startSha) {
|
|
35795
|
+
if (commitOptional && reply.trim().length > 0) {
|
|
35796
|
+
const reviewedCommit = startSha ? await this.deps.gates.canonicalCommit(startSha) : null;
|
|
35797
|
+
return this.recordHandoff(index, stageDef.role, {
|
|
35798
|
+
commit: reviewedCommit ?? "(no changes)",
|
|
35799
|
+
summary: reply.trim().slice(-SUMMARY_MAX_CHARS),
|
|
35800
|
+
diffStat: "reviewed \u2014 no changes needed",
|
|
35801
|
+
durationMs: Date.now() - startedMs
|
|
35802
|
+
});
|
|
35803
|
+
}
|
|
35750
35804
|
return this.stall(index, "stage produced no commit", reply);
|
|
35751
35805
|
}
|
|
35752
35806
|
}
|
|
@@ -35759,16 +35813,7 @@ var PackRunner = class _PackRunner {
|
|
|
35759
35813
|
checks: await this.deps.gates.runChecks() ?? void 0,
|
|
35760
35814
|
durationMs: Date.now() - startedMs
|
|
35761
35815
|
};
|
|
35762
|
-
|
|
35763
|
-
stages[index] = { ...stages[index], status: "done", handoff };
|
|
35764
|
-
this.state = { ...this.state, stages, currentStage: index + 1 };
|
|
35765
|
-
try {
|
|
35766
|
-
this.deps.ledger.saveStageHandoff(this.state.runId, index, stageDef.role, handoff);
|
|
35767
|
-
} catch (err) {
|
|
35768
|
-
this.deps.log(`pack handoff save failed: ${err.message}`);
|
|
35769
|
-
}
|
|
35770
|
-
await this.publish();
|
|
35771
|
-
return true;
|
|
35816
|
+
return this.recordHandoff(index, stageDef.role, handoff);
|
|
35772
35817
|
} catch (err) {
|
|
35773
35818
|
if (this.control === "abort") {
|
|
35774
35819
|
await this.settle("aborted");
|
|
@@ -35777,6 +35822,19 @@ var PackRunner = class _PackRunner {
|
|
|
35777
35822
|
return this.stall(index, err.message);
|
|
35778
35823
|
}
|
|
35779
35824
|
}
|
|
35825
|
+
/** Mark a stage `done` with its handoff, persist, and advance. */
|
|
35826
|
+
async recordHandoff(index, role, handoff) {
|
|
35827
|
+
const stages = this.state.stages.slice();
|
|
35828
|
+
stages[index] = { ...stages[index], status: "done", handoff };
|
|
35829
|
+
this.state = { ...this.state, stages, currentStage: index + 1 };
|
|
35830
|
+
try {
|
|
35831
|
+
this.deps.ledger.saveStageHandoff(this.state.runId, index, role, handoff);
|
|
35832
|
+
} catch (err) {
|
|
35833
|
+
this.deps.log(`pack handoff save failed: ${err.message}`);
|
|
35834
|
+
}
|
|
35835
|
+
await this.publish();
|
|
35836
|
+
return true;
|
|
35837
|
+
}
|
|
35780
35838
|
async stall(index, reason, lastReply) {
|
|
35781
35839
|
const stages = this.state.stages.slice();
|
|
35782
35840
|
stages[index] = { ...stages[index], status: "failed", error: reason };
|
|
@@ -39522,6 +39580,42 @@ function toEpochMs(ts) {
|
|
|
39522
39580
|
return Number.isFinite(parsed) ? parsed : Date.now();
|
|
39523
39581
|
}
|
|
39524
39582
|
|
|
39583
|
+
// src/services/keep-awake.ts
|
|
39584
|
+
var import_node_child_process32 = require("child_process");
|
|
39585
|
+
function keepDeviceAwake(deps = {}) {
|
|
39586
|
+
const env = deps.env ?? process.env;
|
|
39587
|
+
const isLocal = deps.isLocal ?? isLocalSession(env);
|
|
39588
|
+
const noop = () => {
|
|
39589
|
+
};
|
|
39590
|
+
if (!isLocal) return noop;
|
|
39591
|
+
if (env.CODEAM_NO_KEEP_AWAKE === "1") return noop;
|
|
39592
|
+
const command2 = deps.command !== void 0 ? deps.command : createOsStrategy().keepAwakeCommand(deps.pid ?? process.pid);
|
|
39593
|
+
if (!command2) return noop;
|
|
39594
|
+
const spawnFn = deps.spawnFn ?? import_node_child_process32.spawn;
|
|
39595
|
+
let child = null;
|
|
39596
|
+
try {
|
|
39597
|
+
child = spawnFn(command2.cmd, command2.args, { stdio: "ignore", detached: true });
|
|
39598
|
+
child.once("error", () => {
|
|
39599
|
+
});
|
|
39600
|
+
child.unref();
|
|
39601
|
+
log.info("keep-awake", `holding a power assertion for this local session (${command2.cmd})`);
|
|
39602
|
+
} catch {
|
|
39603
|
+
child = null;
|
|
39604
|
+
}
|
|
39605
|
+
let released = false;
|
|
39606
|
+
return () => {
|
|
39607
|
+
if (released) return;
|
|
39608
|
+
released = true;
|
|
39609
|
+
if (child && child.pid && !child.killed) {
|
|
39610
|
+
try {
|
|
39611
|
+
child.kill("SIGTERM");
|
|
39612
|
+
} catch {
|
|
39613
|
+
}
|
|
39614
|
+
}
|
|
39615
|
+
child = null;
|
|
39616
|
+
};
|
|
39617
|
+
}
|
|
39618
|
+
|
|
39525
39619
|
// src/agents/claude/onboarding.ts
|
|
39526
39620
|
var fs77 = __toESM(require("fs"));
|
|
39527
39621
|
var os60 = __toESM(require("os"));
|
|
@@ -39706,6 +39800,8 @@ async function start(requestedAgent, presetSession) {
|
|
|
39706
39800
|
`agent-spawn gate released (beads ungated, ${beads ? "already ready" : "still provisioning in background"}); project deps provisioned`
|
|
39707
39801
|
);
|
|
39708
39802
|
}
|
|
39803
|
+
const releaseKeepAwake = keepDeviceAwake();
|
|
39804
|
+
process.once("exit", releaseKeepAwake);
|
|
39709
39805
|
if (isLocalSession() && requiresAcp(session.agent)) {
|
|
39710
39806
|
const adapter = await resolveAcpAdapterWithRetry(session.agent);
|
|
39711
39807
|
const batonCapable = runtimeSupportsBaton(createRuntimeStrategy(session.agent));
|
|
@@ -42502,7 +42598,7 @@ function checkChokidar() {
|
|
|
42502
42598
|
}
|
|
42503
42599
|
async function doctor(args2 = []) {
|
|
42504
42600
|
const json = args2.includes("--json");
|
|
42505
|
-
const cliVersion = true ? "2.61.
|
|
42601
|
+
const cliVersion = true ? "2.61.97" : "0.0.0-dev";
|
|
42506
42602
|
const apiBase2 = resolveApiBaseUrl();
|
|
42507
42603
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
42508
42604
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -42699,7 +42795,7 @@ async function completion(args2) {
|
|
|
42699
42795
|
}
|
|
42700
42796
|
|
|
42701
42797
|
// src/integrations/mcp-run.ts
|
|
42702
|
-
var
|
|
42798
|
+
var import_node_child_process34 = require("child_process");
|
|
42703
42799
|
var import_node_fs12 = require("fs");
|
|
42704
42800
|
var import_node_os14 = __toESM(require("os"));
|
|
42705
42801
|
var import_node_path12 = __toESM(require("path"));
|
|
@@ -42774,7 +42870,7 @@ function resolveDelivery(id) {
|
|
|
42774
42870
|
function commandExists(command2) {
|
|
42775
42871
|
try {
|
|
42776
42872
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
42777
|
-
(0,
|
|
42873
|
+
(0, import_node_child_process34.execFileSync)(probe, [command2], { stdio: "ignore" });
|
|
42778
42874
|
return true;
|
|
42779
42875
|
} catch {
|
|
42780
42876
|
return false;
|
|
@@ -42807,7 +42903,7 @@ function ensureCommand(command2) {
|
|
|
42807
42903
|
}
|
|
42808
42904
|
if (command2 === "uvx") {
|
|
42809
42905
|
try {
|
|
42810
|
-
(0,
|
|
42906
|
+
(0, import_node_child_process34.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
|
|
42811
42907
|
stdio: ["ignore", process.stderr, process.stderr],
|
|
42812
42908
|
timeout: 18e4,
|
|
42813
42909
|
env: { ...process.env, UV_NO_MODIFY_PATH: "1" }
|
|
@@ -42816,7 +42912,7 @@ function ensureCommand(command2) {
|
|
|
42816
42912
|
}
|
|
42817
42913
|
if (resolveLauncherPath(command2) !== command2) return;
|
|
42818
42914
|
try {
|
|
42819
|
-
(0,
|
|
42915
|
+
(0, import_node_child_process34.execSync)("python3 -m pip install --user --quiet uv", {
|
|
42820
42916
|
stdio: ["ignore", process.stderr, process.stderr],
|
|
42821
42917
|
timeout: 18e4
|
|
42822
42918
|
});
|
|
@@ -42893,7 +42989,7 @@ async function mcpRun(args2) {
|
|
|
42893
42989
|
// src/commands/version.ts
|
|
42894
42990
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
42895
42991
|
function version2() {
|
|
42896
|
-
const v = true ? "2.61.
|
|
42992
|
+
const v = true ? "2.61.97" : "unknown";
|
|
42897
42993
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
42898
42994
|
}
|
|
42899
42995
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.61.
|
|
3
|
+
"version": "2.61.97",
|
|
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",
|