codeam-cli 2.23.23 → 2.23.25

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 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.23.24] — 2026-05-30
8
+
9
+ ### Added
10
+
11
+ - **cli:** Pre-assign Claude session id via --session-id, drop birthtime guesswork
12
+
13
+ ## [2.23.23] — 2026-05-30
14
+
15
+ ### Fixed
16
+
17
+ - **cli:** Get_conversation handler runs lazy detect when needed
18
+
7
19
  ## [2.23.22] — 2026-05-30
8
20
 
9
21
  ### Fixed
package/dist/index.js CHANGED
@@ -441,7 +441,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
441
441
  // package.json
442
442
  var package_default = {
443
443
  name: "codeam-cli",
444
- version: "2.23.23",
444
+ version: "2.23.25",
445
445
  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.",
446
446
  type: "commonjs",
447
447
  main: "dist/index.js",
@@ -5774,7 +5774,7 @@ function readAnonId() {
5774
5774
  }
5775
5775
  function superProperties() {
5776
5776
  return {
5777
- cliVersion: true ? "2.23.23" : "0.0.0-dev",
5777
+ cliVersion: true ? "2.23.25" : "0.0.0-dev",
5778
5778
  nodeVersion: process.version,
5779
5779
  platform: process.platform,
5780
5780
  arch: process.arch,
@@ -6266,6 +6266,16 @@ var AgentService = class _AgentService {
6266
6266
  * the SAME binary with new resume args.
6267
6267
  */
6268
6268
  initialLaunch = null;
6269
+ /**
6270
+ * Pre-assigned session id from `prepareLaunch` (Claude:
6271
+ * `--session-id <uuid>`). When the runtime supports it, the CLI
6272
+ * binds the conversation id at spawn time instead of inferring
6273
+ * it from filesystem state. Null for runtimes that don't accept
6274
+ * a pre-assigned id (Codex, Aider, ...).
6275
+ */
6276
+ get spawnedSessionId() {
6277
+ return this.initialLaunch?.sessionId ?? null;
6278
+ }
6269
6279
  /**
6270
6280
  * Debounced "agent went idle" check. Re-arms itself as long as
6271
6281
  * fresh PTY output keeps arriving. When the gap since the last
@@ -7091,6 +7101,9 @@ function buildForPlatform(platform2) {
7091
7101
  }
7092
7102
  }
7093
7103
 
7104
+ // src/agents/claude/runtime.ts
7105
+ var import_node_crypto4 = require("crypto");
7106
+
7094
7107
  // src/agents/claude/resolver.ts
7095
7108
  function buildClaudeLaunch(extraArgs = [], os26 = createOsStrategy()) {
7096
7109
  const found = os26.findInPath("claude") ?? os26.findInPath("claude-code");
@@ -9797,10 +9810,12 @@ var ClaudeRuntimeStrategy = class {
9797
9810
  this.os = os26;
9798
9811
  }
9799
9812
  async prepareLaunch() {
9800
- let launch = buildClaudeLaunch([], this.os);
9813
+ const sessionId = (0, import_node_crypto4.randomUUID)();
9814
+ const sessionArgs = ["--session-id", sessionId];
9815
+ let launch = buildClaudeLaunch(sessionArgs, this.os);
9801
9816
  if (!launch) {
9802
9817
  const installed = await ensureClaudeInstalled();
9803
- if (installed) launch = buildClaudeLaunch([], this.os);
9818
+ if (installed) launch = buildClaudeLaunch(sessionArgs, this.os);
9804
9819
  }
9805
9820
  if (!launch) {
9806
9821
  const cmd = this.os.id === "win32" ? "irm https://claude.ai/install.ps1 | iex" : "curl -fsSL https://claude.ai/install.sh | bash";
@@ -9810,7 +9825,7 @@ var ClaudeRuntimeStrategy = class {
9810
9825
  Then restart your terminal and run \`codeam pair\` again.`
9811
9826
  );
9812
9827
  }
9813
- return { cmd: launch.cmd, args: launch.args };
9828
+ return { cmd: launch.cmd, args: launch.args, sessionId };
9814
9829
  }
9815
9830
  resumeLaunchArgs(sessionId, opts) {
9816
9831
  const args2 = ["--resume", sessionId];
@@ -12123,8 +12138,40 @@ var OutputService = class _OutputService {
12123
12138
  ).catch(() => {
12124
12139
  });
12125
12140
  this.onTurnComplete?.();
12141
+ this.scheduleSuggestionPoll();
12126
12142
  }
12127
12143
  }
12144
+ /**
12145
+ * Poll for an `input_suggestion` chunk a few times after a
12146
+ * turn finalises. The TUI takes a beat to render the ghost
12147
+ * completion, so a single check at finalize-time would miss
12148
+ * it. Three checks at 400/800/1500 ms cover the window
12149
+ * without burning CPU when there's no suggestion (each tick
12150
+ * is cheap — a regex over the rendered lines).
12151
+ */
12152
+ scheduleSuggestionPoll() {
12153
+ if (!this.runtime.detectInputSuggestion) return;
12154
+ const tryDetect = () => {
12155
+ if (!this.runtime.detectInputSuggestion) return;
12156
+ const rendered = this.runtime.renderToLines?.(this.pty.content) ?? renderLines(this.pty.content);
12157
+ const suggestion = this.runtime.detectInputSuggestion(rendered);
12158
+ if (suggestion !== this.lastSentSuggestion) {
12159
+ this.lastSentSuggestion = suggestion;
12160
+ this.send(
12161
+ {
12162
+ type: "input_suggestion",
12163
+ content: suggestion ?? "",
12164
+ done: true
12165
+ },
12166
+ { critical: false }
12167
+ ).catch(() => {
12168
+ });
12169
+ }
12170
+ };
12171
+ setTimeout(tryDetect, 400);
12172
+ setTimeout(tryDetect, 800);
12173
+ setTimeout(tryDetect, 1500);
12174
+ }
12128
12175
  // ─── Side-channel observation (session id + rate limit) ──────────
12129
12176
  tryExtractSessionId(text) {
12130
12177
  if (!this.onSessionIdDetected) return;
@@ -15125,7 +15172,7 @@ function findGitRoot2(startDir) {
15125
15172
  }
15126
15173
 
15127
15174
  // src/commands/link.ts
15128
- var import_node_crypto4 = require("crypto");
15175
+ var import_node_crypto5 = require("crypto");
15129
15176
  var fs26 = __toESM(require("fs"));
15130
15177
  var path32 = __toESM(require("path"));
15131
15178
  var import_chokidar = __toESM(require("chokidar"));
@@ -15214,7 +15261,7 @@ async function link(args2 = []) {
15214
15261
  await linkDryRunPreflight(ctx);
15215
15262
  return;
15216
15263
  }
15217
- const pluginId = (0, import_node_crypto4.randomUUID)();
15264
+ const pluginId = (0, import_node_crypto5.randomUUID)();
15218
15265
  const spin = dist_exports.spinner();
15219
15266
  spin.start("Requesting pairing code...");
15220
15267
  const pairing = await requestCode(pluginId);
@@ -16112,6 +16159,10 @@ async function start(requestedAgent) {
16112
16159
  process.once("SIGTERM", sigintHandler);
16113
16160
  process.once("SIGHUP", sigintHandler);
16114
16161
  await agent.spawn();
16162
+ const spawnedSessionId = agent.spawnedSessionId;
16163
+ if (spawnedSessionId) {
16164
+ historySvc.setCurrentConversationId(spawnedSessionId);
16165
+ }
16115
16166
  await outputSvc.startTerminalTurn();
16116
16167
  relay.start();
16117
16168
  if (fileWatcher) {
@@ -18687,7 +18738,7 @@ async function stopWorkspaceFromLocal(target) {
18687
18738
  // src/commands/doctor.ts
18688
18739
  var import_node_dns = require("dns");
18689
18740
  var import_node_util4 = require("util");
18690
- var import_node_crypto5 = require("crypto");
18741
+ var import_node_crypto6 = require("crypto");
18691
18742
  var fs29 = __toESM(require("fs"));
18692
18743
  var path38 = __toESM(require("path"));
18693
18744
  var import_picocolors12 = __toESM(require("picocolors"));
@@ -18857,9 +18908,9 @@ function checkChokidar() {
18857
18908
  }
18858
18909
  async function doctor(args2 = []) {
18859
18910
  const json = args2.includes("--json");
18860
- const cliVersion = true ? "2.23.23" : "0.0.0-dev";
18911
+ const cliVersion = true ? "2.23.25" : "0.0.0-dev";
18861
18912
  const apiBase = resolveApiBaseUrl();
18862
- const diagnosticId = (0, import_node_crypto5.randomUUID)();
18913
+ const diagnosticId = (0, import_node_crypto6.randomUUID)();
18863
18914
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
18864
18915
  const [dns, health] = await Promise.all([
18865
18916
  checkDns(apiBase),
@@ -19056,7 +19107,7 @@ async function completion(args2) {
19056
19107
  // src/commands/version.ts
19057
19108
  var import_picocolors13 = __toESM(require("picocolors"));
19058
19109
  function version2() {
19059
- const v = true ? "2.23.23" : "unknown";
19110
+ const v = true ? "2.23.25" : "unknown";
19060
19111
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
19061
19112
  }
19062
19113
 
@@ -19284,7 +19335,7 @@ function checkForUpdates() {
19284
19335
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
19285
19336
  if (process.env.CI) return;
19286
19337
  if (!process.stdout.isTTY) return;
19287
- const current = true ? "2.23.23" : null;
19338
+ const current = true ? "2.23.25" : null;
19288
19339
  if (!current) return;
19289
19340
  const cache = readCache();
19290
19341
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.23.23",
3
+ "version": "2.23.25",
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",