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.
Files changed (3) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/index.js +191 -63
  3. 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.18" : "0.0.0-dev",
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.18",
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.18" ? { ideVersion: "2.60.18" } : {}
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 import_node_crypto7 = require("crypto");
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
- return this.os.buildLaunch(binary);
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 import_node_child_process10 = require("child_process");
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, import_node_child_process10.spawn)(os49.id === "win32" ? "cmd.exe" : "sh", os49.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 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 import_node_crypto5 = require("crypto");
14042
+ var import_node_crypto6 = require("crypto");
13917
14043
 
13918
14044
  // src/agents/gemini/link.ts
13919
- var import_node_child_process11 = require("child_process");
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, import_node_child_process11.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
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, import_node_crypto5.randomUUID)();
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 import_node_child_process12 = require("child_process");
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 import_node_crypto6 = require("crypto");
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, import_node_crypto6.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
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, import_node_child_process12.spawn)("kimi", [], { stdio: "inherit" });
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, import_node_crypto7.randomUUID)();
14687
- const pollSecret = (0, import_node_crypto7.randomBytes)(32).toString("base64url");
14688
- const pluginSecretHash = (0, import_node_crypto7.createHash)("sha256").update(pollSecret).digest("hex");
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 import_node_child_process20 = require("child_process");
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 import_node_child_process13 = require("child_process");
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, import_node_child_process13.execFileSync)(
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 import_node_child_process14 = require("child_process");
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)(import_node_child_process14.execFile);
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 import_node_child_process15 = require("child_process");
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, import_node_child_process15.execFileSync)(probe, [cmd], { stdio: "ignore" });
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, import_node_child_process15.spawn)(cmd, args2, {
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 import_node_child_process16 = require("child_process");
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, import_node_child_process16.execFileSync)("which", [cmd], { stdio: "ignore" });
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, import_node_child_process16.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
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 import_node_child_process18 = require("child_process");
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 import_node_child_process17 = require("child_process");
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, import_node_child_process17.execSync)("npm root -g", {
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, import_node_child_process17.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
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, import_node_child_process17.spawnSync)("codeam", process.argv.slice(2), {
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.18" : null;
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.18" : null;
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.18" : null;
16682
+ return true ? "2.60.20" : null;
16557
16683
  }
16558
16684
  function runCmd(cmd, args2, timeoutMs) {
16559
16685
  return new Promise((resolve7) => {
16560
- (0, import_node_child_process18.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
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 import_node_child_process19 = require("child_process");
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, import_node_child_process19.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
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, import_node_child_process19.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
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, import_node_child_process20.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
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, import_node_child_process20.spawn)("sh", ["-c", script], {
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 import_node_child_process21 = require("child_process");
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, import_node_child_process21.execFile)("headroom", ["--version"], (err) => {
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 import_node_child_process22 = require("child_process");
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, import_node_child_process22.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
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, import_node_child_process22.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
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 import_node_crypto9 = require("crypto");
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 import_node_child_process23 = require("child_process");
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, import_node_child_process23.spawn)(adapter.command, adapter.args, {
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 import_node_crypto8 = require("crypto");
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, import_node_crypto8.randomUUID)(),
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, import_node_crypto8.randomUUID)();
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, import_node_crypto9.randomUUID)(),
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, import_node_crypto9.randomUUID)(),
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, import_node_crypto9.randomUUID)(), prompt, options }),
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 import_node_crypto10 = require("crypto");
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, import_node_crypto10.randomUUID)(), prompt, options }),
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 import_node_crypto11 = require("crypto");
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.18" : "0.0.0-dev";
33544
+ const cliVersion = true ? "2.60.20" : "0.0.0-dev";
33417
33545
  const apiBase2 = resolveApiBaseUrl();
33418
- const diagnosticId = (0, import_node_crypto11.randomUUID)();
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.18" : "unknown";
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.18",
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",