codeam-cli 2.60.18 → 2.60.20
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 +20 -0
- package/dist/index.js +191 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ 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.19] — 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Baton — pre-mint Cursor session id via `create-chat`
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
|
|
15
|
+
- **cli:** De-flake adapter module-graph gate — crash synchronously in settling fixture
|
|
16
|
+
|
|
17
|
+
## [2.60.18] — 2026-07-09
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **cli:** Auto-install Kimi on local pair when the binary is missing
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **cli:** Baton — discover Kimi's self-minted session id after spawn
|
|
26
|
+
|
|
7
27
|
## [2.60.17] — 2026-07-09
|
|
8
28
|
|
|
9
29
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5680,7 +5680,7 @@ function readAnonId() {
|
|
|
5680
5680
|
}
|
|
5681
5681
|
function superProperties() {
|
|
5682
5682
|
return {
|
|
5683
|
-
cliVersion: true ? "2.60.
|
|
5683
|
+
cliVersion: true ? "2.60.20" : "0.0.0-dev",
|
|
5684
5684
|
nodeVersion: process.version,
|
|
5685
5685
|
platform: process.platform,
|
|
5686
5686
|
arch: process.arch,
|
|
@@ -5861,7 +5861,7 @@ var os4 = __toESM(require("os"));
|
|
|
5861
5861
|
// package.json
|
|
5862
5862
|
var package_default = {
|
|
5863
5863
|
name: "codeam-cli",
|
|
5864
|
-
version: "2.60.
|
|
5864
|
+
version: "2.60.20",
|
|
5865
5865
|
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.",
|
|
5866
5866
|
type: "commonjs",
|
|
5867
5867
|
main: "dist/index.js",
|
|
@@ -6932,7 +6932,7 @@ var CommandRelayService = class {
|
|
|
6932
6932
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6933
6933
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6934
6934
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6935
|
-
..."2.60.
|
|
6935
|
+
..."2.60.20" ? { ideVersion: "2.60.20" } : {}
|
|
6936
6936
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6937
6937
|
}
|
|
6938
6938
|
/**
|
|
@@ -9089,7 +9089,7 @@ function findGitRoot2(startDir) {
|
|
|
9089
9089
|
}
|
|
9090
9090
|
|
|
9091
9091
|
// src/commands/link.ts
|
|
9092
|
-
var
|
|
9092
|
+
var import_node_crypto8 = require("crypto");
|
|
9093
9093
|
var fs30 = __toESM(require("fs"));
|
|
9094
9094
|
var path34 = __toESM(require("path"));
|
|
9095
9095
|
var import_chokidar = __toESM(require("chokidar"));
|
|
@@ -13444,7 +13444,70 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13444
13444
|
var fs23 = __toESM(require("fs"));
|
|
13445
13445
|
var os21 = __toESM(require("os"));
|
|
13446
13446
|
var path27 = __toESM(require("path"));
|
|
13447
|
+
var import_node_crypto5 = require("crypto");
|
|
13447
13448
|
var HISTORY_ROOT = path27.join(os21.homedir(), ".cursor", "projects");
|
|
13449
|
+
var CURSOR_HOME = path27.join(os21.homedir(), ".cursor");
|
|
13450
|
+
var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
|
|
13451
|
+
function acpSessionDir(sessionId) {
|
|
13452
|
+
return path27.join(CURSOR_HOME, "acp-sessions", sessionId);
|
|
13453
|
+
}
|
|
13454
|
+
function nativeStoreDir(cwd, sessionId) {
|
|
13455
|
+
const chatsRoot = path27.join(CURSOR_HOME, "chats");
|
|
13456
|
+
let buckets = [];
|
|
13457
|
+
try {
|
|
13458
|
+
buckets = fs23.readdirSync(chatsRoot);
|
|
13459
|
+
} catch {
|
|
13460
|
+
}
|
|
13461
|
+
for (const b of buckets) {
|
|
13462
|
+
const candidate = path27.join(chatsRoot, b, sessionId);
|
|
13463
|
+
if (fs23.existsSync(path27.join(candidate, "store.db"))) return candidate;
|
|
13464
|
+
}
|
|
13465
|
+
const computed = path27.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
13466
|
+
return fs23.existsSync(computed) ? computed : null;
|
|
13467
|
+
}
|
|
13468
|
+
function copyStoreFiles(srcDir, dstDir) {
|
|
13469
|
+
fs23.mkdirSync(dstDir, { recursive: true });
|
|
13470
|
+
for (const f of STORE_FILES) {
|
|
13471
|
+
const dst = path27.join(dstDir, f);
|
|
13472
|
+
if (fs23.existsSync(dst)) fs23.rmSync(dst, { force: true });
|
|
13473
|
+
}
|
|
13474
|
+
for (const f of STORE_FILES) {
|
|
13475
|
+
const src = path27.join(srcDir, f);
|
|
13476
|
+
if (fs23.existsSync(src)) fs23.copyFileSync(src, path27.join(dstDir, f));
|
|
13477
|
+
}
|
|
13478
|
+
}
|
|
13479
|
+
function bridgeNativeToAcp(cwd, sessionId) {
|
|
13480
|
+
try {
|
|
13481
|
+
const src = nativeStoreDir(cwd, sessionId);
|
|
13482
|
+
if (!src) {
|
|
13483
|
+
log.warn("cursor", `baton bridge: no native store for ${sessionId.slice(0, 8)} \u2014 skip`);
|
|
13484
|
+
return;
|
|
13485
|
+
}
|
|
13486
|
+
const dst = acpSessionDir(sessionId);
|
|
13487
|
+
copyStoreFiles(src, dst);
|
|
13488
|
+
fs23.writeFileSync(
|
|
13489
|
+
path27.join(dst, "meta.json"),
|
|
13490
|
+
JSON.stringify({ schemaVersion: 1, cwd })
|
|
13491
|
+
);
|
|
13492
|
+
log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
|
|
13493
|
+
} catch (err) {
|
|
13494
|
+
log.warn("cursor", `baton bridge native\u2192acp failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13495
|
+
}
|
|
13496
|
+
}
|
|
13497
|
+
function bridgeAcpToNative(cwd, sessionId) {
|
|
13498
|
+
try {
|
|
13499
|
+
const src = acpSessionDir(sessionId);
|
|
13500
|
+
if (!fs23.existsSync(path27.join(src, "store.db"))) {
|
|
13501
|
+
log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
|
|
13502
|
+
return;
|
|
13503
|
+
}
|
|
13504
|
+
const dst = nativeStoreDir(cwd, sessionId) ?? path27.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
13505
|
+
copyStoreFiles(src, dst);
|
|
13506
|
+
log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
|
|
13507
|
+
} catch (err) {
|
|
13508
|
+
log.warn("cursor", `baton bridge acp\u2192native failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13509
|
+
}
|
|
13510
|
+
}
|
|
13448
13511
|
function encodeCursorCwd(cwd) {
|
|
13449
13512
|
return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
|
|
13450
13513
|
}
|
|
@@ -13601,6 +13664,8 @@ function detectCursorSelector(lines) {
|
|
|
13601
13664
|
}
|
|
13602
13665
|
|
|
13603
13666
|
// src/agents/cursor/runtime.ts
|
|
13667
|
+
var import_node_child_process10 = require("child_process");
|
|
13668
|
+
var UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
13604
13669
|
var CURSOR_CONTEXT_WINDOW = 2e5;
|
|
13605
13670
|
var CURSOR_MODELS = [
|
|
13606
13671
|
{ id: "cursor-default", label: "Cursor (auto)", contextWindow: CURSOR_CONTEXT_WINDOW },
|
|
@@ -13622,12 +13687,54 @@ var CursorRuntimeStrategy = class {
|
|
|
13622
13687
|
'Cursor Agent CLI ("cursor-agent") is not on PATH.\n Install Cursor (https://cursor.com/), enable its CLI plugin,\n then run `codeam pair` again.'
|
|
13623
13688
|
);
|
|
13624
13689
|
}
|
|
13625
|
-
|
|
13690
|
+
const sessionId = this.mintChatId(binary);
|
|
13691
|
+
if (sessionId) {
|
|
13692
|
+
const launch2 = this.os.buildLaunch(binary, ["--resume", sessionId]);
|
|
13693
|
+
return { cmd: launch2.cmd, args: launch2.args, sessionId };
|
|
13694
|
+
}
|
|
13695
|
+
const launch = this.os.buildLaunch(binary);
|
|
13696
|
+
return { cmd: launch.cmd, args: launch.args };
|
|
13697
|
+
}
|
|
13698
|
+
/**
|
|
13699
|
+
* Pre-create an empty, resumable Cursor chat and return its id, or null on any
|
|
13700
|
+
* failure. `cursor-agent create-chat` prints a bare UUID and exits 0 (verified
|
|
13701
|
+
* on cursor-agent 2026.06.24). Synchronous + bounded so prepareLaunch stays a
|
|
13702
|
+
* single deterministic step; a timeout/parse failure just disables pre-mint.
|
|
13703
|
+
*/
|
|
13704
|
+
mintChatId(binary) {
|
|
13705
|
+
try {
|
|
13706
|
+
const r = (0, import_node_child_process10.spawnSync)(binary, ["create-chat"], {
|
|
13707
|
+
encoding: "utf8",
|
|
13708
|
+
timeout: 2e4,
|
|
13709
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
13710
|
+
});
|
|
13711
|
+
if (r.status !== 0 || r.error) {
|
|
13712
|
+
log.warn("cursor", `create-chat failed (status=${r.status}) \u2014 baton id pre-mint skipped`);
|
|
13713
|
+
return null;
|
|
13714
|
+
}
|
|
13715
|
+
const id = (r.stdout ?? "").match(UUID_RE)?.[0] ?? null;
|
|
13716
|
+
if (!id) log.warn("cursor", "create-chat produced no chat id \u2014 baton id pre-mint skipped");
|
|
13717
|
+
return id;
|
|
13718
|
+
} catch (err) {
|
|
13719
|
+
log.warn("cursor", `create-chat threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
13720
|
+
return null;
|
|
13721
|
+
}
|
|
13626
13722
|
}
|
|
13627
13723
|
/** Cursor mirrors Claude's `--resume <id>` flag for session resume. */
|
|
13628
13724
|
resumeLaunchArgs(sessionId, _opts) {
|
|
13629
13725
|
return ["--resume", sessionId];
|
|
13630
13726
|
}
|
|
13727
|
+
/**
|
|
13728
|
+
* Resume as a COMPLETE relaunch (mirrors Claude). The initial spawn already
|
|
13729
|
+
* carries `--resume <preMintedId>` from {@link prepareLaunch}, so appending
|
|
13730
|
+
* `resumeLaunchArgs` onto `initialLaunch.args` would emit a duplicate
|
|
13731
|
+
* `--resume … --resume …`. Rebuild a clean `--resume <id>` launch instead.
|
|
13732
|
+
*/
|
|
13733
|
+
prepareResumeLaunch(sessionId, opts) {
|
|
13734
|
+
const binary = this.os.findInPath("cursor-agent") ?? this.meta.binaryName;
|
|
13735
|
+
const launch = this.os.buildLaunch(binary, this.resumeLaunchArgs(sessionId, opts));
|
|
13736
|
+
return { cmd: launch.cmd, args: launch.args };
|
|
13737
|
+
}
|
|
13631
13738
|
resolveHistoryDir(cwd) {
|
|
13632
13739
|
return resolveHistoryDir3(cwd);
|
|
13633
13740
|
}
|
|
@@ -13641,6 +13748,25 @@ var CursorRuntimeStrategy = class {
|
|
|
13641
13748
|
parseHistoryFile(filePath) {
|
|
13642
13749
|
return parseHistoryFile3(filePath);
|
|
13643
13750
|
}
|
|
13751
|
+
/**
|
|
13752
|
+
* Baton Take Control (native TUI → mobile ACP). Cursor keeps native-TUI
|
|
13753
|
+
* conversations in `~/.cursor/chats/<md5(cwd)>/<id>` but ACP `session/load`
|
|
13754
|
+
* only reads `~/.cursor/acp-sessions/<id>` — so without this, loading the
|
|
13755
|
+
* native session id fails "not found". Bridge the native store into the ACP
|
|
13756
|
+
* store just before the load. Best-effort; verified live (identical
|
|
13757
|
+
* `blobs`+`meta` SQLite schema, raw file copy replays the conversation).
|
|
13758
|
+
*/
|
|
13759
|
+
async syncTranscriptForAcpResume(cwd, sessionId) {
|
|
13760
|
+
bridgeNativeToAcp(cwd, sessionId);
|
|
13761
|
+
}
|
|
13762
|
+
/**
|
|
13763
|
+
* Baton hand-back (mobile ACP → native TUI). Copy the ACP conversation store
|
|
13764
|
+
* back into the native `~/.cursor/chats` store so `cursor-agent --resume <id>`
|
|
13765
|
+
* in the terminal picks up whatever mobile did. Best-effort.
|
|
13766
|
+
*/
|
|
13767
|
+
async syncTranscriptForNativeResume(cwd, sessionId) {
|
|
13768
|
+
bridgeAcpToNative(cwd, sessionId);
|
|
13769
|
+
}
|
|
13644
13770
|
getCurrentUsage(historyDir) {
|
|
13645
13771
|
return getCurrentUsage3(historyDir);
|
|
13646
13772
|
}
|
|
@@ -13714,7 +13840,7 @@ function getCurrentUsage4(_historyDir) {
|
|
|
13714
13840
|
}
|
|
13715
13841
|
|
|
13716
13842
|
// src/agents/aider/link.ts
|
|
13717
|
-
var
|
|
13843
|
+
var import_node_child_process11 = require("child_process");
|
|
13718
13844
|
|
|
13719
13845
|
// src/agents/aider/local-token.ts
|
|
13720
13846
|
var fs26 = __toESM(require("fs"));
|
|
@@ -13772,7 +13898,7 @@ function aiderLoginLauncher(os49) {
|
|
|
13772
13898
|
console.error(
|
|
13773
13899
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
13774
13900
|
);
|
|
13775
|
-
return (0,
|
|
13901
|
+
return (0, import_node_child_process11.spawn)(os49.id === "win32" ? "cmd.exe" : "sh", os49.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
13776
13902
|
stdio: "ignore"
|
|
13777
13903
|
});
|
|
13778
13904
|
}
|
|
@@ -13913,10 +14039,10 @@ var AiderRuntimeStrategy = class {
|
|
|
13913
14039
|
};
|
|
13914
14040
|
|
|
13915
14041
|
// src/agents/gemini/runtime.ts
|
|
13916
|
-
var
|
|
14042
|
+
var import_node_crypto6 = require("crypto");
|
|
13917
14043
|
|
|
13918
14044
|
// src/agents/gemini/link.ts
|
|
13919
|
-
var
|
|
14045
|
+
var import_node_child_process12 = require("child_process");
|
|
13920
14046
|
|
|
13921
14047
|
// src/agents/gemini/local-token.ts
|
|
13922
14048
|
var fs27 = __toESM(require("fs"));
|
|
@@ -13981,7 +14107,7 @@ function geminiLoginLauncher() {
|
|
|
13981
14107
|
return os49.findInPath("gemini") !== null;
|
|
13982
14108
|
},
|
|
13983
14109
|
launch() {
|
|
13984
|
-
return (0,
|
|
14110
|
+
return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
13985
14111
|
}
|
|
13986
14112
|
};
|
|
13987
14113
|
}
|
|
@@ -14178,7 +14304,7 @@ var GeminiRuntimeStrategy = class {
|
|
|
14178
14304
|
"Gemini CLI is not on PATH. Install it with:\n npm install -g @google/gemini-cli\n Then run `codeam pair` again."
|
|
14179
14305
|
);
|
|
14180
14306
|
}
|
|
14181
|
-
const sessionId = (0,
|
|
14307
|
+
const sessionId = (0, import_node_crypto6.randomUUID)();
|
|
14182
14308
|
const launch = this.os.buildLaunch(binary, ["--session-id", sessionId]);
|
|
14183
14309
|
log.info(
|
|
14184
14310
|
"gemini",
|
|
@@ -14277,7 +14403,7 @@ var GeminiRuntimeStrategy = class {
|
|
|
14277
14403
|
};
|
|
14278
14404
|
|
|
14279
14405
|
// src/agents/kimi/runtime.ts
|
|
14280
|
-
var
|
|
14406
|
+
var import_node_child_process13 = require("child_process");
|
|
14281
14407
|
var import_node_os3 = require("os");
|
|
14282
14408
|
var import_node_path4 = require("path");
|
|
14283
14409
|
|
|
@@ -14285,12 +14411,12 @@ var import_node_path4 = require("path");
|
|
|
14285
14411
|
var fs29 = __toESM(require("fs"));
|
|
14286
14412
|
var os26 = __toESM(require("os"));
|
|
14287
14413
|
var path33 = __toESM(require("path"));
|
|
14288
|
-
var
|
|
14414
|
+
var import_node_crypto7 = require("crypto");
|
|
14289
14415
|
function kimiHome() {
|
|
14290
14416
|
return process.env.KIMI_CODE_HOME || path33.join(os26.homedir(), ".kimi-code");
|
|
14291
14417
|
}
|
|
14292
14418
|
function workDirKey(cwd) {
|
|
14293
|
-
const hash = (0,
|
|
14419
|
+
const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
|
|
14294
14420
|
return `wd_${path33.basename(cwd)}_${hash}`;
|
|
14295
14421
|
}
|
|
14296
14422
|
function resolveHistoryDir6(cwd) {
|
|
@@ -14567,7 +14693,7 @@ var KimiRuntimeStrategy = class {
|
|
|
14567
14693
|
return createOsStrategy().findInPath("kimi") !== null;
|
|
14568
14694
|
},
|
|
14569
14695
|
launch() {
|
|
14570
|
-
return (0,
|
|
14696
|
+
return (0, import_node_child_process13.spawn)("kimi", [], { stdio: "inherit" });
|
|
14571
14697
|
}
|
|
14572
14698
|
};
|
|
14573
14699
|
}
|
|
@@ -14683,9 +14809,9 @@ async function link(args2 = []) {
|
|
|
14683
14809
|
await linkDryRunPreflight(ctx);
|
|
14684
14810
|
return;
|
|
14685
14811
|
}
|
|
14686
|
-
const pluginId = (0,
|
|
14687
|
-
const pollSecret = (0,
|
|
14688
|
-
const pluginSecretHash = (0,
|
|
14812
|
+
const pluginId = (0, import_node_crypto8.randomUUID)();
|
|
14813
|
+
const pollSecret = (0, import_node_crypto8.randomBytes)(32).toString("base64url");
|
|
14814
|
+
const pluginSecretHash = (0, import_node_crypto8.createHash)("sha256").update(pollSecret).digest("hex");
|
|
14689
14815
|
const spin = dist_exports.spinner();
|
|
14690
14816
|
spin.start("Requesting pairing code...");
|
|
14691
14817
|
const pairing = await requestCode(pluginId, pluginSecretHash);
|
|
@@ -15000,7 +15126,7 @@ async function linkDryRunPreflight(ctx) {
|
|
|
15000
15126
|
}
|
|
15001
15127
|
|
|
15002
15128
|
// src/commands/host-agent.ts
|
|
15003
|
-
var
|
|
15129
|
+
var import_node_child_process21 = require("child_process");
|
|
15004
15130
|
var os34 = __toESM(require("os"));
|
|
15005
15131
|
var fs40 = __toESM(require("fs"));
|
|
15006
15132
|
var path42 = __toESM(require("path"));
|
|
@@ -15013,7 +15139,7 @@ var path35 = __toESM(require("path"));
|
|
|
15013
15139
|
// src/lib/restrict-to-owner.ts
|
|
15014
15140
|
var import_node_fs5 = __toESM(require("fs"));
|
|
15015
15141
|
var import_node_os4 = __toESM(require("os"));
|
|
15016
|
-
var
|
|
15142
|
+
var import_node_child_process14 = require("child_process");
|
|
15017
15143
|
var BROAD_WINDOWS_SIDS = [
|
|
15018
15144
|
"*S-1-1-0",
|
|
15019
15145
|
"*S-1-5-11",
|
|
@@ -15025,7 +15151,7 @@ function restrictToOwner(filePath) {
|
|
|
15025
15151
|
try {
|
|
15026
15152
|
if (process.platform === "win32") {
|
|
15027
15153
|
const username = import_node_os4.default.userInfo().username;
|
|
15028
|
-
(0,
|
|
15154
|
+
(0, import_node_child_process14.execFileSync)(
|
|
15029
15155
|
"icacls",
|
|
15030
15156
|
[
|
|
15031
15157
|
filePath,
|
|
@@ -15287,9 +15413,9 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
15287
15413
|
var fs33 = __toESM(require("fs"));
|
|
15288
15414
|
var os29 = __toESM(require("os"));
|
|
15289
15415
|
var path36 = __toESM(require("path"));
|
|
15290
|
-
var
|
|
15416
|
+
var import_node_child_process15 = require("child_process");
|
|
15291
15417
|
var import_node_util4 = require("util");
|
|
15292
|
-
var execFileP4 = (0, import_node_util4.promisify)(
|
|
15418
|
+
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process15.execFile);
|
|
15293
15419
|
function isAbsolutePathTarget(target) {
|
|
15294
15420
|
return path36.isAbsolute(target);
|
|
15295
15421
|
}
|
|
@@ -15559,7 +15685,7 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
|
|
|
15559
15685
|
}
|
|
15560
15686
|
|
|
15561
15687
|
// src/commands/host/git-tooling.ts
|
|
15562
|
-
var
|
|
15688
|
+
var import_node_child_process16 = require("child_process");
|
|
15563
15689
|
var fs35 = __toESM(require("fs"));
|
|
15564
15690
|
var os31 = __toESM(require("os"));
|
|
15565
15691
|
var path38 = __toESM(require("path"));
|
|
@@ -15673,7 +15799,7 @@ var defaultGitToolingRunner = {
|
|
|
15673
15799
|
which(cmd) {
|
|
15674
15800
|
try {
|
|
15675
15801
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
15676
|
-
(0,
|
|
15802
|
+
(0, import_node_child_process16.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
15677
15803
|
return true;
|
|
15678
15804
|
} catch {
|
|
15679
15805
|
return false;
|
|
@@ -15681,7 +15807,7 @@ var defaultGitToolingRunner = {
|
|
|
15681
15807
|
},
|
|
15682
15808
|
run(cmd, args2, opts = {}) {
|
|
15683
15809
|
return new Promise((resolve7) => {
|
|
15684
|
-
const child = (0,
|
|
15810
|
+
const child = (0, import_node_child_process16.spawn)(cmd, args2, {
|
|
15685
15811
|
stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
|
|
15686
15812
|
});
|
|
15687
15813
|
let stderr = "";
|
|
@@ -15835,12 +15961,12 @@ var HeadroomStatsReporter = class {
|
|
|
15835
15961
|
};
|
|
15836
15962
|
|
|
15837
15963
|
// src/commands/host/os-packages.ts
|
|
15838
|
-
var
|
|
15964
|
+
var import_node_child_process17 = require("child_process");
|
|
15839
15965
|
var PM_INSTALL_TIMEOUT_MS = 18e4;
|
|
15840
15966
|
var defaultHeadroomRunner = {
|
|
15841
15967
|
which(cmd) {
|
|
15842
15968
|
try {
|
|
15843
|
-
(0,
|
|
15969
|
+
(0, import_node_child_process17.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
15844
15970
|
return true;
|
|
15845
15971
|
} catch {
|
|
15846
15972
|
return false;
|
|
@@ -15849,7 +15975,7 @@ var defaultHeadroomRunner = {
|
|
|
15849
15975
|
run(cmd, args2, opts = {}) {
|
|
15850
15976
|
return new Promise((resolve7) => {
|
|
15851
15977
|
const spawnEnv = opts.env ?? process.env;
|
|
15852
|
-
const child = (0,
|
|
15978
|
+
const child = (0, import_node_child_process17.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
|
|
15853
15979
|
let stderrBuf = "";
|
|
15854
15980
|
let stdoutBuf = "";
|
|
15855
15981
|
let settled = false;
|
|
@@ -16356,14 +16482,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
16356
16482
|
}
|
|
16357
16483
|
|
|
16358
16484
|
// src/commands/host/self-update.ts
|
|
16359
|
-
var
|
|
16485
|
+
var import_node_child_process19 = require("child_process");
|
|
16360
16486
|
|
|
16361
16487
|
// src/lib/updateNotifier.ts
|
|
16362
16488
|
var fs38 = __toESM(require("fs"));
|
|
16363
16489
|
var os33 = __toESM(require("os"));
|
|
16364
16490
|
var path41 = __toESM(require("path"));
|
|
16365
16491
|
var https6 = __toESM(require("https"));
|
|
16366
|
-
var
|
|
16492
|
+
var import_node_child_process18 = require("child_process");
|
|
16367
16493
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
16368
16494
|
var PKG_NAME = "codeam-cli";
|
|
16369
16495
|
var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
@@ -16457,7 +16583,7 @@ function notifyIfStale(currentVersion, latest) {
|
|
|
16457
16583
|
}
|
|
16458
16584
|
function isLinkedInstall() {
|
|
16459
16585
|
try {
|
|
16460
|
-
const root = (0,
|
|
16586
|
+
const root = (0, import_node_child_process18.execSync)("npm root -g", {
|
|
16461
16587
|
encoding: "utf8",
|
|
16462
16588
|
stdio: ["ignore", "pipe", "ignore"],
|
|
16463
16589
|
timeout: 2e3
|
|
@@ -16485,7 +16611,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16485
16611
|
|
|
16486
16612
|
`
|
|
16487
16613
|
);
|
|
16488
|
-
const install = (0,
|
|
16614
|
+
const install = (0, import_node_child_process18.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
|
|
16489
16615
|
stdio: "inherit",
|
|
16490
16616
|
env: process.env
|
|
16491
16617
|
});
|
|
@@ -16506,7 +16632,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
16506
16632
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
16507
16633
|
|
|
16508
16634
|
`);
|
|
16509
|
-
const child = (0,
|
|
16635
|
+
const child = (0, import_node_child_process18.spawnSync)("codeam", process.argv.slice(2), {
|
|
16510
16636
|
stdio: "inherit",
|
|
16511
16637
|
env: process.env
|
|
16512
16638
|
});
|
|
@@ -16516,7 +16642,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
16516
16642
|
if (process.env.NODE_ENV === "test") return;
|
|
16517
16643
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16518
16644
|
if (process.env.CI) return;
|
|
16519
|
-
const current = true ? "2.60.
|
|
16645
|
+
const current = true ? "2.60.20" : null;
|
|
16520
16646
|
if (!current) return;
|
|
16521
16647
|
const cache = readCache();
|
|
16522
16648
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16533,7 +16659,7 @@ function checkForUpdates() {
|
|
|
16533
16659
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
16534
16660
|
if (process.env.CI) return;
|
|
16535
16661
|
if (!process.stdout.isTTY) return;
|
|
16536
|
-
const current = true ? "2.60.
|
|
16662
|
+
const current = true ? "2.60.20" : null;
|
|
16537
16663
|
if (!current) return;
|
|
16538
16664
|
const cache = readCache();
|
|
16539
16665
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -16553,11 +16679,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
16553
16679
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
16554
16680
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
16555
16681
|
function currentCliVersion() {
|
|
16556
|
-
return true ? "2.60.
|
|
16682
|
+
return true ? "2.60.20" : null;
|
|
16557
16683
|
}
|
|
16558
16684
|
function runCmd(cmd, args2, timeoutMs) {
|
|
16559
16685
|
return new Promise((resolve7) => {
|
|
16560
|
-
(0,
|
|
16686
|
+
(0, import_node_child_process19.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
16561
16687
|
const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
|
|
16562
16688
|
resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
16563
16689
|
});
|
|
@@ -16619,11 +16745,11 @@ async function runSelfUpdate() {
|
|
|
16619
16745
|
}
|
|
16620
16746
|
|
|
16621
16747
|
// src/commands/host/teardown.ts
|
|
16622
|
-
var
|
|
16748
|
+
var import_node_child_process20 = require("child_process");
|
|
16623
16749
|
var fs39 = __toESM(require("fs"));
|
|
16624
16750
|
var defaultDisableService = () => {
|
|
16625
16751
|
try {
|
|
16626
|
-
(0,
|
|
16752
|
+
(0, import_node_child_process20.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
16627
16753
|
} catch {
|
|
16628
16754
|
}
|
|
16629
16755
|
};
|
|
@@ -16631,7 +16757,7 @@ var defaultTeardownHeadroom = () => {
|
|
|
16631
16757
|
try {
|
|
16632
16758
|
const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
16633
16759
|
if (kind) {
|
|
16634
|
-
(0,
|
|
16760
|
+
(0, import_node_child_process20.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
16635
16761
|
}
|
|
16636
16762
|
} catch {
|
|
16637
16763
|
}
|
|
@@ -16789,7 +16915,7 @@ var CONTROL_AGENT_META = {
|
|
|
16789
16915
|
headroomWrappable: false,
|
|
16790
16916
|
acp: false
|
|
16791
16917
|
};
|
|
16792
|
-
var defaultSpawner = (env, cwd, args2 = []) => (0,
|
|
16918
|
+
var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process21.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
|
|
16793
16919
|
cwd,
|
|
16794
16920
|
env: { ...process.env, ...env },
|
|
16795
16921
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -17269,7 +17395,7 @@ var HostAgentSupervisor = class {
|
|
|
17269
17395
|
runAgentInstall(script) {
|
|
17270
17396
|
return new Promise((resolve7) => {
|
|
17271
17397
|
const home = process.env.HOME || os34.homedir();
|
|
17272
|
-
const child = (0,
|
|
17398
|
+
const child = (0, import_node_child_process21.spawn)("sh", ["-c", script], {
|
|
17273
17399
|
env: { ...process.env, HOME: home },
|
|
17274
17400
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17275
17401
|
});
|
|
@@ -21675,7 +21801,7 @@ async function pairAuto(args2) {
|
|
|
21675
21801
|
}
|
|
21676
21802
|
|
|
21677
21803
|
// src/services/headroom/wrap-launch.ts
|
|
21678
|
-
var
|
|
21804
|
+
var import_node_child_process22 = require("child_process");
|
|
21679
21805
|
function wrapWithHeadroom(launch, opts) {
|
|
21680
21806
|
if (!opts.enabled || !opts.headroomPresent) return launch;
|
|
21681
21807
|
return {
|
|
@@ -21688,7 +21814,7 @@ var _present;
|
|
|
21688
21814
|
function headroomPresent() {
|
|
21689
21815
|
if (_present !== void 0) return Promise.resolve(_present);
|
|
21690
21816
|
return new Promise((resolve7) => {
|
|
21691
|
-
(0,
|
|
21817
|
+
(0, import_node_child_process22.execFile)("headroom", ["--version"], (err) => {
|
|
21692
21818
|
_present = !err;
|
|
21693
21819
|
resolve7(_present);
|
|
21694
21820
|
});
|
|
@@ -22212,7 +22338,7 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
22212
22338
|
}
|
|
22213
22339
|
|
|
22214
22340
|
// src/agents/kimi/installer.ts
|
|
22215
|
-
var
|
|
22341
|
+
var import_node_child_process23 = require("child_process");
|
|
22216
22342
|
var import_node_os6 = require("os");
|
|
22217
22343
|
var import_node_path6 = require("path");
|
|
22218
22344
|
var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
|
|
@@ -22220,7 +22346,7 @@ function kimiBinDir() {
|
|
|
22220
22346
|
return (0, import_node_path6.join)(process.env.KIMI_CODE_HOME || (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".kimi-code"), "bin");
|
|
22221
22347
|
}
|
|
22222
22348
|
function kimiRuns() {
|
|
22223
|
-
const r = (0,
|
|
22349
|
+
const r = (0, import_node_child_process23.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
|
|
22224
22350
|
return !r.error && r.status === 0;
|
|
22225
22351
|
}
|
|
22226
22352
|
function augmentPath2() {
|
|
@@ -22230,7 +22356,7 @@ function augmentPath2() {
|
|
|
22230
22356
|
}
|
|
22231
22357
|
async function runInstaller2() {
|
|
22232
22358
|
return new Promise((resolve7) => {
|
|
22233
|
-
const proc = (0,
|
|
22359
|
+
const proc = (0, import_node_child_process23.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
|
|
22234
22360
|
proc.on("close", (code) => resolve7(code === 0));
|
|
22235
22361
|
proc.on("error", () => resolve7(false));
|
|
22236
22362
|
});
|
|
@@ -22387,7 +22513,7 @@ function requiresAcp(agent) {
|
|
|
22387
22513
|
}
|
|
22388
22514
|
|
|
22389
22515
|
// src/agents/acp/runner.ts
|
|
22390
|
-
var
|
|
22516
|
+
var import_node_crypto10 = require("crypto");
|
|
22391
22517
|
|
|
22392
22518
|
// src/services/history.service.ts
|
|
22393
22519
|
var fs55 = __toESM(require("fs"));
|
|
@@ -22967,7 +23093,7 @@ var HistoryService = class _HistoryService {
|
|
|
22967
23093
|
};
|
|
22968
23094
|
|
|
22969
23095
|
// src/agents/acp/client.ts
|
|
22970
|
-
var
|
|
23096
|
+
var import_node_child_process24 = require("child_process");
|
|
22971
23097
|
var fs56 = __toESM(require("fs/promises"));
|
|
22972
23098
|
var fsSync = __toESM(require("fs"));
|
|
22973
23099
|
var os45 = __toESM(require("os"));
|
|
@@ -25571,7 +25697,7 @@ var AcpClient = class {
|
|
|
25571
25697
|
"acpClient",
|
|
25572
25698
|
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
25573
25699
|
);
|
|
25574
|
-
const child = (0,
|
|
25700
|
+
const child = (0, import_node_child_process24.spawn)(adapter.command, adapter.args, {
|
|
25575
25701
|
cwd,
|
|
25576
25702
|
// extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
|
|
25577
25703
|
// re-spawn) layers over process.env; PATH stays last so the augmented
|
|
@@ -26588,7 +26714,7 @@ async function runOnboardingTurn(opts) {
|
|
|
26588
26714
|
}
|
|
26589
26715
|
|
|
26590
26716
|
// src/agents/acp/mappers.ts
|
|
26591
|
-
var
|
|
26717
|
+
var import_node_crypto9 = require("crypto");
|
|
26592
26718
|
function mapSessionUpdate(notification) {
|
|
26593
26719
|
const update = notification.update;
|
|
26594
26720
|
switch (update.sessionUpdate) {
|
|
@@ -26651,7 +26777,7 @@ function mapPermissionRequest(request) {
|
|
|
26651
26777
|
}
|
|
26652
26778
|
return {
|
|
26653
26779
|
event: {
|
|
26654
|
-
questionId: (0,
|
|
26780
|
+
questionId: (0, import_node_crypto9.randomUUID)(),
|
|
26655
26781
|
prompt,
|
|
26656
26782
|
options: labels.length > 0 ? labels : void 0
|
|
26657
26783
|
},
|
|
@@ -26661,7 +26787,7 @@ function mapPermissionRequest(request) {
|
|
|
26661
26787
|
}
|
|
26662
26788
|
function messageChunkId(messageId) {
|
|
26663
26789
|
if (typeof messageId === "string" && messageId.length > 0) return messageId;
|
|
26664
|
-
return (0,
|
|
26790
|
+
return (0, import_node_crypto9.randomUUID)();
|
|
26665
26791
|
}
|
|
26666
26792
|
function extractText4(content) {
|
|
26667
26793
|
if (!content || typeof content !== "object") return null;
|
|
@@ -28474,7 +28600,7 @@ var AcpHistory = class {
|
|
|
28474
28600
|
this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
|
|
28475
28601
|
}
|
|
28476
28602
|
this.messages.push({
|
|
28477
|
-
id: (0,
|
|
28603
|
+
id: (0, import_node_crypto10.randomUUID)(),
|
|
28478
28604
|
role: "user",
|
|
28479
28605
|
text,
|
|
28480
28606
|
timestamp: Date.now()
|
|
@@ -28483,7 +28609,7 @@ var AcpHistory = class {
|
|
|
28483
28609
|
appendAgentReply(text) {
|
|
28484
28610
|
if (text.length === 0) return;
|
|
28485
28611
|
this.messages.push({
|
|
28486
|
-
id: (0,
|
|
28612
|
+
id: (0, import_node_crypto10.randomUUID)(),
|
|
28487
28613
|
role: "agent",
|
|
28488
28614
|
text,
|
|
28489
28615
|
timestamp: Date.now()
|
|
@@ -28689,7 +28815,7 @@ async function runAcpSession(opts) {
|
|
|
28689
28815
|
currentIndex: 0,
|
|
28690
28816
|
done: true
|
|
28691
28817
|
}),
|
|
28692
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
28818
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto10.randomUUID)(), prompt, options }),
|
|
28693
28819
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
28694
28820
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
28695
28821
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -29997,6 +30123,7 @@ var NativeTuiDriver = class {
|
|
|
29997
30123
|
keepAliveCtx;
|
|
29998
30124
|
async start(resumeId) {
|
|
29999
30125
|
if (resumeId !== void 0) {
|
|
30126
|
+
await this.deps.runtime.syncTranscriptForNativeResume?.(this.deps.opts.cwd, resumeId);
|
|
30000
30127
|
await this.agent.restart(resumeId, false);
|
|
30001
30128
|
return resumeId;
|
|
30002
30129
|
}
|
|
@@ -30055,7 +30182,7 @@ var NativeTuiDriver = class {
|
|
|
30055
30182
|
};
|
|
30056
30183
|
|
|
30057
30184
|
// src/baton/acp-driver.ts
|
|
30058
|
-
var
|
|
30185
|
+
var import_node_crypto11 = require("crypto");
|
|
30059
30186
|
var AcpDriver = class {
|
|
30060
30187
|
constructor(deps) {
|
|
30061
30188
|
this.deps = deps;
|
|
@@ -30077,6 +30204,7 @@ var AcpDriver = class {
|
|
|
30077
30204
|
try {
|
|
30078
30205
|
started = await this.deps.client.start();
|
|
30079
30206
|
if (resumeId !== void 0) {
|
|
30207
|
+
await this.deps.runtime.syncTranscriptForAcpResume?.(this.deps.opts.cwd, resumeId);
|
|
30080
30208
|
this.deps.streaming.beginLoadReplay();
|
|
30081
30209
|
try {
|
|
30082
30210
|
await this.deps.client.loadSession(resumeId);
|
|
@@ -30148,7 +30276,7 @@ var AcpDriver = class {
|
|
|
30148
30276
|
currentIndex: 0,
|
|
30149
30277
|
done: true
|
|
30150
30278
|
}),
|
|
30151
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
30279
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto11.randomUUID)(), prompt, options }),
|
|
30152
30280
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
30153
30281
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
30154
30282
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -33243,7 +33371,7 @@ async function invite() {
|
|
|
33243
33371
|
// src/commands/doctor.ts
|
|
33244
33372
|
var import_node_dns = require("dns");
|
|
33245
33373
|
var import_node_util5 = require("util");
|
|
33246
|
-
var
|
|
33374
|
+
var import_node_crypto12 = require("crypto");
|
|
33247
33375
|
var fs62 = __toESM(require("fs"));
|
|
33248
33376
|
var path69 = __toESM(require("path"));
|
|
33249
33377
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
@@ -33413,9 +33541,9 @@ function checkChokidar() {
|
|
|
33413
33541
|
}
|
|
33414
33542
|
async function doctor(args2 = []) {
|
|
33415
33543
|
const json = args2.includes("--json");
|
|
33416
|
-
const cliVersion = true ? "2.60.
|
|
33544
|
+
const cliVersion = true ? "2.60.20" : "0.0.0-dev";
|
|
33417
33545
|
const apiBase2 = resolveApiBaseUrl();
|
|
33418
|
-
const diagnosticId = (0,
|
|
33546
|
+
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
33419
33547
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
33420
33548
|
const [dns, health] = await Promise.all([
|
|
33421
33549
|
checkDns(apiBase2),
|
|
@@ -33612,7 +33740,7 @@ async function completion(args2) {
|
|
|
33612
33740
|
// src/commands/version.ts
|
|
33613
33741
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
33614
33742
|
function version2() {
|
|
33615
|
-
const v = true ? "2.60.
|
|
33743
|
+
const v = true ? "2.60.20" : "unknown";
|
|
33616
33744
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
33617
33745
|
}
|
|
33618
33746
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.20",
|
|
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",
|