codeam-cli 2.60.0 → 2.60.1
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 +32 -0
- package/dist/index.js +53 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ 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.0] — 2026-07-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** Baton local-session gate + feature flag
|
|
12
|
+
- **cli:** BatonController turn-safe single-driver state machine
|
|
13
|
+
- **cli:** TranscriptMirror emits JSONL deltas for the read-only view
|
|
14
|
+
- **cli:** NativeTuiDriver over AgentService with idle turn-boundary
|
|
15
|
+
- **cli:** AcpDriver over AcpClient (spawn + loadSession resume)
|
|
16
|
+
- **cli:** PostBatonEvent publisher driver-state
|
|
17
|
+
- **cli:** Take_control/handback relay handlers
|
|
18
|
+
- **cli:** Wire local baton branch before the ACP fork (flag-gated)
|
|
19
|
+
- **cli:** Make the session baton drivable after a hand-off
|
|
20
|
+
- **cli:** Enable the session baton by default for local sessions (CODEAM_BATON=0 kill switch)
|
|
21
|
+
- **shared:** Add baton_state to USER_EVENTS (session baton wire type)
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **cli:** Extract shared ACP command-context assembler + proxy-relaunch helper
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **cli:** Mark SessionDriver.kind readonly (contract)
|
|
30
|
+
- **cli:** Baton switch-failure recovery + ack-on-failure; test cleanups
|
|
31
|
+
- **cli:** EncodeCwd underscore-collapse + ClaudeRuntimeStrategy.resolveHistoryFile (baton mirror)
|
|
32
|
+
- **cli:** AcpClient.start cleans up on handshake failure (baton take-control recovery)
|
|
33
|
+
|
|
34
|
+
### Tests
|
|
35
|
+
|
|
36
|
+
- **cli:** Prove noteOutput resets the idle window + cover throw/undefined branches
|
|
37
|
+
- **cli:** Gated cross-mode-resume integration test (real claude)
|
|
38
|
+
|
|
7
39
|
## [2.59.0] — 2026-07-08
|
|
8
40
|
|
|
9
41
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5653,7 +5653,7 @@ function readAnonId() {
|
|
|
5653
5653
|
}
|
|
5654
5654
|
function superProperties() {
|
|
5655
5655
|
return {
|
|
5656
|
-
cliVersion: true ? "2.60.
|
|
5656
|
+
cliVersion: true ? "2.60.1" : "0.0.0-dev",
|
|
5657
5657
|
nodeVersion: process.version,
|
|
5658
5658
|
platform: process.platform,
|
|
5659
5659
|
arch: process.arch,
|
|
@@ -5834,7 +5834,7 @@ var os4 = __toESM(require("os"));
|
|
|
5834
5834
|
// package.json
|
|
5835
5835
|
var package_default = {
|
|
5836
5836
|
name: "codeam-cli",
|
|
5837
|
-
version: "2.60.
|
|
5837
|
+
version: "2.60.1",
|
|
5838
5838
|
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
5839
|
type: "commonjs",
|
|
5840
5840
|
main: "dist/index.js",
|
|
@@ -6905,7 +6905,7 @@ var CommandRelayService = class {
|
|
|
6905
6905
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6906
6906
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6907
6907
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6908
|
-
..."2.60.
|
|
6908
|
+
..."2.60.1" ? { ideVersion: "2.60.1" } : {}
|
|
6909
6909
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6910
6910
|
}
|
|
6911
6911
|
/**
|
|
@@ -15921,7 +15921,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
15921
15921
|
if (process.env.NODE_ENV === "test") return;
|
|
15922
15922
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
15923
15923
|
if (process.env.CI) return;
|
|
15924
|
-
const current = true ? "2.60.
|
|
15924
|
+
const current = true ? "2.60.1" : null;
|
|
15925
15925
|
if (!current) return;
|
|
15926
15926
|
const cache = readCache();
|
|
15927
15927
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15938,7 +15938,7 @@ function checkForUpdates() {
|
|
|
15938
15938
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
15939
15939
|
if (process.env.CI) return;
|
|
15940
15940
|
if (!process.stdout.isTTY) return;
|
|
15941
|
-
const current = true ? "2.60.
|
|
15941
|
+
const current = true ? "2.60.1" : null;
|
|
15942
15942
|
if (!current) return;
|
|
15943
15943
|
const cache = readCache();
|
|
15944
15944
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15958,7 +15958,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
15958
15958
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
15959
15959
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
15960
15960
|
function currentCliVersion() {
|
|
15961
|
-
return true ? "2.60.
|
|
15961
|
+
return true ? "2.60.1" : null;
|
|
15962
15962
|
}
|
|
15963
15963
|
function runCmd(cmd, args2, timeoutMs) {
|
|
15964
15964
|
return new Promise((resolve7) => {
|
|
@@ -29110,11 +29110,6 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
29110
29110
|
function isLocalSession(env = process.env) {
|
|
29111
29111
|
return env.CODESPACES !== "true" && env.CODEAM_AUTO_APPROVE !== "1" && env.HEADROOM_ENABLED !== "1" && !env.CODEAM_AUTO_TOKEN && !env.CODEAM_ENROLL_TOKEN;
|
|
29112
29112
|
}
|
|
29113
|
-
function batonEnabled(env = process.env) {
|
|
29114
|
-
const v = env.CODEAM_BATON;
|
|
29115
|
-
if (v === void 0 || v === "") return true;
|
|
29116
|
-
return v !== "0" && v.toLowerCase() !== "false";
|
|
29117
|
-
}
|
|
29118
29113
|
|
|
29119
29114
|
// src/baton/baton-controller.ts
|
|
29120
29115
|
var BatonController = class {
|
|
@@ -29480,6 +29475,45 @@ function makeOnCommand(deps) {
|
|
|
29480
29475
|
await deps.dispatchActive(cmd);
|
|
29481
29476
|
};
|
|
29482
29477
|
}
|
|
29478
|
+
async function publishMirroredTurnsLive(publisher, messages) {
|
|
29479
|
+
for (const m of messages) {
|
|
29480
|
+
if (m.role === "user") {
|
|
29481
|
+
await publisher.publishOutput({ type: "clear" });
|
|
29482
|
+
await publisher.publishOutput({ type: "user_message", content: m.text, done: true });
|
|
29483
|
+
await publisher.publishOutput({ type: "new_turn", done: false });
|
|
29484
|
+
} else {
|
|
29485
|
+
await publisher.publishOutput({ type: "text", content: m.text, done: true });
|
|
29486
|
+
}
|
|
29487
|
+
}
|
|
29488
|
+
}
|
|
29489
|
+
function makeMirrorOnNewMessages(deps) {
|
|
29490
|
+
let isFirstEmit = true;
|
|
29491
|
+
let publishChain = Promise.resolve();
|
|
29492
|
+
return (messages) => {
|
|
29493
|
+
const relevant = messages.filter((m) => m.role !== "system");
|
|
29494
|
+
if (relevant.length === 0) return;
|
|
29495
|
+
const mapped = relevant.map((m) => ({
|
|
29496
|
+
id: m.id,
|
|
29497
|
+
role: m.role === "user" ? "user" : "agent",
|
|
29498
|
+
text: m.text,
|
|
29499
|
+
timestamp: toEpochMs(m.timestamp)
|
|
29500
|
+
}));
|
|
29501
|
+
void deps.publisher.pushConversation({
|
|
29502
|
+
agentId: deps.agentId,
|
|
29503
|
+
sessionId: deps.conversationId,
|
|
29504
|
+
messages: mapped
|
|
29505
|
+
});
|
|
29506
|
+
if (!isFirstEmit) {
|
|
29507
|
+
publishChain = publishChain.then(() => publishMirroredTurnsLive(deps.publisher, relevant)).catch((err) => {
|
|
29508
|
+
log.warn(
|
|
29509
|
+
"wireBaton",
|
|
29510
|
+
`mirror live-publish failed: ${err instanceof Error ? err.message : String(err)}`
|
|
29511
|
+
);
|
|
29512
|
+
});
|
|
29513
|
+
}
|
|
29514
|
+
isFirstEmit = false;
|
|
29515
|
+
};
|
|
29516
|
+
}
|
|
29483
29517
|
async function runBatonSession(opts) {
|
|
29484
29518
|
const publisher = new AcpPublisher({
|
|
29485
29519
|
sessionId: opts.sessionId,
|
|
@@ -29565,20 +29599,11 @@ async function runBatonSession(opts) {
|
|
|
29565
29599
|
runtime,
|
|
29566
29600
|
cwd: opts.cwd,
|
|
29567
29601
|
conversationId,
|
|
29568
|
-
onNewMessages: (
|
|
29569
|
-
|
|
29570
|
-
|
|
29571
|
-
|
|
29572
|
-
|
|
29573
|
-
timestamp: toEpochMs(m.timestamp)
|
|
29574
|
-
}));
|
|
29575
|
-
if (mapped.length === 0) return;
|
|
29576
|
-
void publisher.pushConversation({
|
|
29577
|
-
agentId: opts.agent,
|
|
29578
|
-
sessionId: conversationId,
|
|
29579
|
-
messages: mapped
|
|
29580
|
-
});
|
|
29581
|
-
}
|
|
29602
|
+
onNewMessages: makeMirrorOnNewMessages({
|
|
29603
|
+
publisher,
|
|
29604
|
+
agentId: opts.agent,
|
|
29605
|
+
conversationId
|
|
29606
|
+
})
|
|
29582
29607
|
});
|
|
29583
29608
|
mirror.start();
|
|
29584
29609
|
};
|
|
@@ -29786,7 +29811,7 @@ async function start(requestedAgent) {
|
|
|
29786
29811
|
`agent-spawn gate released \u2014 beads ${beads ? "ready" : "pending"}; project deps provisioned`
|
|
29787
29812
|
);
|
|
29788
29813
|
}
|
|
29789
|
-
if (isLocalSession() &&
|
|
29814
|
+
if (isLocalSession() && requiresAcp(session.agent)) {
|
|
29790
29815
|
const adapter = getAcpAdapter(session.agent);
|
|
29791
29816
|
if (adapter && session.pluginAuthToken) {
|
|
29792
29817
|
await runBatonSession({
|
|
@@ -32549,7 +32574,7 @@ function checkChokidar() {
|
|
|
32549
32574
|
}
|
|
32550
32575
|
async function doctor(args2 = []) {
|
|
32551
32576
|
const json = args2.includes("--json");
|
|
32552
|
-
const cliVersion = true ? "2.60.
|
|
32577
|
+
const cliVersion = true ? "2.60.1" : "0.0.0-dev";
|
|
32553
32578
|
const apiBase2 = resolveApiBaseUrl();
|
|
32554
32579
|
const diagnosticId = (0, import_node_crypto9.randomUUID)();
|
|
32555
32580
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -32748,7 +32773,7 @@ async function completion(args2) {
|
|
|
32748
32773
|
// src/commands/version.ts
|
|
32749
32774
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
32750
32775
|
function version2() {
|
|
32751
|
-
const v = true ? "2.60.
|
|
32776
|
+
const v = true ? "2.60.1" : "unknown";
|
|
32752
32777
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
32753
32778
|
}
|
|
32754
32779
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.1",
|
|
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",
|