codeam-cli 2.75.10 → 2.75.11

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,12 @@ 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.75.10] — 2026-09-23
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Guardrails judge a write by its target; pack stage shows a mid-turn permission as awaiting
12
+
7
13
  ## [2.75.9] — 2026-09-23
8
14
 
9
15
  ### Added
package/dist/index.js CHANGED
@@ -10509,7 +10509,7 @@ function readAnonId() {
10509
10509
  }
10510
10510
  function superProperties() {
10511
10511
  return {
10512
- cliVersion: true ? "2.75.10" : "0.0.0-dev",
10512
+ cliVersion: true ? "2.75.11" : "0.0.0-dev",
10513
10513
  nodeVersion: process.version,
10514
10514
  platform: process.platform,
10515
10515
  arch: process.arch,
@@ -10751,7 +10751,7 @@ var http = __toESM(require("http"));
10751
10751
  // package.json
10752
10752
  var package_default = {
10753
10753
  name: "codeam-cli",
10754
- version: "2.75.10",
10754
+ version: "2.75.11",
10755
10755
  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.",
10756
10756
  type: "commonjs",
10757
10757
  main: "dist/index.js",
@@ -12081,7 +12081,7 @@ var CommandRelayService = class _CommandRelayService {
12081
12081
  // fresh + clear the "CLI update available" banner after a self-update
12082
12082
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
12083
12083
  // pair/reconnect). Older backends ignore the extra field.
12084
- ..."2.75.10" ? { ideVersion: "2.75.10" } : {}
12084
+ ..."2.75.11" ? { ideVersion: "2.75.11" } : {}
12085
12085
  };
12086
12086
  try {
12087
12087
  const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
@@ -35576,6 +35576,18 @@ function _get(url2, headers) {
35576
35576
  }
35577
35577
 
35578
35578
  // src/agents/acp/publisher.ts
35579
+ var STREAMING_CHUNK_SNAPSHOT_MAX_CHARS = 56 * 1024;
35580
+ var STREAMING_CHUNK_COALESCE_MIN_CHARS = 8 * 1024;
35581
+ var STREAMING_CHUNK_COALESCE_WINDOW_MS = 300;
35582
+ function boundStreamingChunkContent(content, max = STREAMING_CHUNK_SNAPSHOT_MAX_CHARS) {
35583
+ if (content.length <= max) return { content, truncated: false };
35584
+ const dropped = content.length - max;
35585
+ return {
35586
+ content: `${content.slice(0, max)}
35587
+ \u2026 [output truncated: ${dropped} more characters \u2014 the full text is in the conversation transcript]`,
35588
+ truncated: true
35589
+ };
35590
+ }
35579
35591
  var AcpPublisher = class {
35580
35592
  constructor(opts) {
35581
35593
  this.opts = opts;
@@ -35585,6 +35597,11 @@ var AcpPublisher = class {
35585
35597
  opts;
35586
35598
  apiBase;
35587
35599
  token;
35600
+ /** chunkIds whose truncated snapshot already went out — nothing new to show
35601
+ * until the terminal frame. */
35602
+ truncatedChunks = /* @__PURE__ */ new Set();
35603
+ lastChunkPostAt = /* @__PURE__ */ new Map();
35604
+ pendingChunkPosts = /* @__PURE__ */ new Map();
35588
35605
  /** Latched on an unrecoverable 401/403 — every surface stops posting
35589
35606
  * (2026-06-28 incident: a dead-token publisher spammed 401 ×34 while
35590
35607
  * the agent's replies silently never reached the phone). */
@@ -35613,7 +35630,10 @@ var AcpPublisher = class {
35613
35630
  const fresh = await this.opts.refreshAuthToken();
35614
35631
  if (fresh) {
35615
35632
  this.token = fresh;
35616
- log.info("acpPublisher", `plugin-auth token refreshed after ${first.statusCode}; retrying POST`);
35633
+ log.info(
35634
+ "acpPublisher",
35635
+ `plugin-auth token refreshed after ${first.statusCode}; retrying POST`
35636
+ );
35617
35637
  const second = await _transport4.post(url2, this.authHeaders(), payload);
35618
35638
  if (second.statusCode !== 401 && second.statusCode !== 403) return second;
35619
35639
  this.markPairingInvalid(second.statusCode);
@@ -35722,17 +35742,51 @@ var AcpPublisher = class {
35722
35742
  * richer SessionDetail surface.
35723
35743
  */
35724
35744
  async publishStreamingChunk(event) {
35745
+ const { chunkId, isFinal } = event;
35746
+ const pending = this.pendingChunkPosts.get(chunkId);
35747
+ if (pending) {
35748
+ clearTimeout(pending.timer);
35749
+ this.pendingChunkPosts.delete(chunkId);
35750
+ }
35751
+ const bounded = boundStreamingChunkContent(event.content);
35752
+ if (bounded.truncated) {
35753
+ if (!isFinal && this.truncatedChunks.has(chunkId)) return;
35754
+ if (!this.truncatedChunks.has(chunkId)) {
35755
+ log.warn(
35756
+ "acpPublisher",
35757
+ `streaming-chunk ${chunkId.slice(0, 12)} (${event.kind}) exceeds ${STREAMING_CHUNK_SNAPSHOT_MAX_CHARS} chars \u2014 sending a truncated snapshot once`
35758
+ );
35759
+ }
35760
+ this.truncatedChunks.add(chunkId);
35761
+ }
35762
+ if (isFinal) {
35763
+ this.truncatedChunks.delete(chunkId);
35764
+ this.lastChunkPostAt.delete(chunkId);
35765
+ } else if (!bounded.truncated && bounded.content.length >= STREAMING_CHUNK_COALESCE_MIN_CHARS) {
35766
+ const last = this.lastChunkPostAt.get(chunkId) ?? 0;
35767
+ const wait = STREAMING_CHUNK_COALESCE_WINDOW_MS - (Date.now() - last);
35768
+ if (wait > 0) {
35769
+ const timer = setTimeout(() => {
35770
+ const latest = this.pendingChunkPosts.get(chunkId);
35771
+ this.pendingChunkPosts.delete(chunkId);
35772
+ if (latest) void this.postStreamingChunk(latest.event);
35773
+ }, wait);
35774
+ this.pendingChunkPosts.set(chunkId, { timer, event });
35775
+ return;
35776
+ }
35777
+ }
35778
+ await this.postStreamingChunk({ ...event, content: bounded.content });
35779
+ }
35780
+ async postStreamingChunk(event) {
35725
35781
  const url2 = `${this.apiBase}/api/sessions/${encodeURIComponent(this.opts.sessionId)}/streaming-chunk`;
35782
+ if (!event.isFinal) this.lastChunkPostAt.set(event.chunkId, Date.now());
35726
35783
  try {
35727
35784
  const { statusCode, body } = await this.postWithReauth(
35728
35785
  url2,
35729
35786
  this.envelope(event)
35730
35787
  );
35731
35788
  if (statusCode < 200 || statusCode >= 300) {
35732
- log.warn(
35733
- "acpPublisher",
35734
- `streaming-chunk status=${statusCode} body=${body.slice(0, 200)}`
35735
- );
35789
+ log.warn("acpPublisher", `streaming-chunk status=${statusCode} body=${body.slice(0, 200)}`);
35736
35790
  }
35737
35791
  } catch (err) {
35738
35792
  log.trace("acpPublisher", "streaming-chunk post failed", err);
@@ -47060,7 +47114,7 @@ async function autoUpgradeBeforeCriticalCommand() {
47060
47114
  if (process.env.NODE_ENV === "test") return;
47061
47115
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
47062
47116
  if (process.env.CI) return;
47063
- const current2 = true ? "2.75.10" : null;
47117
+ const current2 = true ? "2.75.11" : null;
47064
47118
  if (!current2) return;
47065
47119
  const cache = readCache();
47066
47120
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -47077,7 +47131,7 @@ function checkForUpdates() {
47077
47131
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
47078
47132
  if (process.env.CI) return;
47079
47133
  if (!process.stdout.isTTY) return;
47080
- const current2 = true ? "2.75.10" : null;
47134
+ const current2 = true ? "2.75.11" : null;
47081
47135
  if (!current2) return;
47082
47136
  const cache = readCache();
47083
47137
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -47100,7 +47154,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
47100
47154
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
47101
47155
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
47102
47156
  function currentCliVersion() {
47103
- return true ? "2.75.10" : null;
47157
+ return true ? "2.75.11" : null;
47104
47158
  }
47105
47159
  async function installedVersion(deps) {
47106
47160
  const ls = await deps.run(
@@ -48840,7 +48894,7 @@ function checkChokidar() {
48840
48894
  }
48841
48895
  async function doctor(args2 = []) {
48842
48896
  const json = args2.includes("--json");
48843
- const cliVersion = true ? "2.75.10" : "0.0.0-dev";
48897
+ const cliVersion = true ? "2.75.11" : "0.0.0-dev";
48844
48898
  const apiBase2 = resolveApiBaseUrl();
48845
48899
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
48846
48900
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -49364,7 +49418,7 @@ async function mcpWarm(argv = [], opts = {}) {
49364
49418
  // src/commands/version.ts
49365
49419
  var import_picocolors15 = __toESM(require("picocolors"));
49366
49420
  function version2() {
49367
- const v = true ? "2.75.10" : "unknown";
49421
+ const v = true ? "2.75.11" : "unknown";
49368
49422
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
49369
49423
  }
49370
49424
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.75.10",
3
+ "version": "2.75.11",
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",