codeam-cli 2.4.37 → 2.4.39

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.4.37] — 2026-05-06
8
+
9
+ ### Fixed
10
+
11
+ - **shared:** Filter multi-column TUI box chrome (welcome banner)
12
+
7
13
  ## [2.4.36] — 2026-05-06
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -1482,7 +1482,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
1482
1482
  // package.json
1483
1483
  var package_default = {
1484
1484
  name: "codeam-cli",
1485
- version: "2.4.37",
1485
+ version: "2.4.39",
1486
1486
  description: "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands \u2014 from anywhere.",
1487
1487
  type: "commonjs",
1488
1488
  main: "dist/index.js",
@@ -4959,7 +4959,6 @@ function filterChrome(lines) {
4959
4959
  continue;
4960
4960
  }
4961
4961
  if (/^[●⏺]\s/.test(t2)) skipEchoContinuation = false;
4962
- if (/^│/.test(t2) && (t2.match(/│/g)?.length ?? 0) >= 2) continue;
4963
4962
  if (/^[✳✢✶✻✽✴✷✸✹⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏◐◑◒◓▁▂▃▄▅▆▇█]\s/.test(t2)) continue;
4964
4963
  if (/esc.{0,5}to.{0,5}interrupt/i.test(t2)) continue;
4965
4964
  if (/high\s*[·•]\s*\/effort/i.test(t2)) continue;
@@ -5202,12 +5201,6 @@ var OutputService = class _OutputService {
5202
5201
  "outputSvc",
5203
5202
  `tick empty content (raw=${this.rawBuffer.length}B lines=${lines.length} elapsed=${elapsed}ms)`
5204
5203
  );
5205
- if (lines.length > 0 && this.rawBuffer.length > 200) {
5206
- const dump = lines.map((l, i) => `${i}: ${JSON.stringify(l)}`).join("\n");
5207
- const preview = dump.length > 1500 ? dump.slice(0, 1500) + "\u2026(truncated)" : dump;
5208
- log.trace("outputSvc", `lines dump:
5209
- ${preview}`);
5210
- }
5211
5204
  if (elapsed >= _OutputService.EMPTY_TIMEOUT_MS) this.finalize();
5212
5205
  return;
5213
5206
  }
@@ -5506,6 +5499,14 @@ var HistoryService = class {
5506
5499
  _rateLimitReset = null;
5507
5500
  _quotaPercent = null;
5508
5501
  _quotaFetchedAt = 0;
5502
+ /**
5503
+ * Per-conversation marker of the last message uuid we successfully
5504
+ * uploaded to the backend. `uploadDelta()` reads the JSONL,
5505
+ * filters out everything up to and including this uuid, and
5506
+ * uploads only the tail. Resets per conversation so a session
5507
+ * resume re-uploads the full transcript on first call.
5508
+ */
5509
+ lastUploadedUuid = /* @__PURE__ */ new Map();
5509
5510
  /** Store rate limit reset info detected from Claude Code output */
5510
5511
  setRateLimitReset(reset) {
5511
5512
  this._rateLimitReset = reset;
@@ -5782,6 +5783,54 @@ var HistoryService = class {
5782
5783
  throw new Error(`Failed to upload conversation batch ${i + 1}/${totalBatches} after all retries`);
5783
5784
  }
5784
5785
  }
5786
+ const last = messages[messages.length - 1];
5787
+ if (last) this.lastUploadedUuid.set(sessionId, last.id);
5788
+ }
5789
+ /**
5790
+ * Incremental upload — ships only the messages added since the last
5791
+ * `loadConversation` / `uploadDelta` call for this conversation.
5792
+ * Used by `onTurnComplete` after every turn so the backend's
5793
+ * conversation table stays fresh enough for the SSE consumers
5794
+ * (mobile + web dashboard) to fetch the canonical markdown via
5795
+ * `?last=N` and replace the streaming-from-PTY approximation —
5796
+ * which lacks the markdown ``` fences the parser needs to surface
5797
+ * the rich CodeBlock / DiffBlock / etc. components.
5798
+ *
5799
+ * Posts under `mode: 'append'` so the server merges by uuid
5800
+ * instead of replacing the full conversation. Idempotent — if
5801
+ * called twice in a row the second call sees zero new messages
5802
+ * and is a no-op.
5803
+ *
5804
+ * Returns the number of messages uploaded (0 means nothing new).
5805
+ */
5806
+ async uploadDelta() {
5807
+ if (!this.currentConversationId) return 0;
5808
+ const sessionId = this.currentConversationId;
5809
+ const filePath = path8.join(this.projectDir, `${sessionId}.jsonl`);
5810
+ const messages = parseJsonl(filePath);
5811
+ if (messages.length === 0) return 0;
5812
+ const marker = this.lastUploadedUuid.get(sessionId);
5813
+ let newMessages = messages;
5814
+ if (marker) {
5815
+ const idx = messages.findIndex((m) => m.id === marker);
5816
+ if (idx >= 0) {
5817
+ newMessages = messages.slice(idx + 1);
5818
+ }
5819
+ }
5820
+ if (newMessages.length === 0) return 0;
5821
+ const body = {
5822
+ pluginId: this.pluginId,
5823
+ sessionId,
5824
+ messages: newMessages,
5825
+ mode: "append"
5826
+ };
5827
+ const ok = await post("/api/sessions/claude-conversation", body);
5828
+ if (ok) {
5829
+ const last = newMessages[newMessages.length - 1];
5830
+ this.lastUploadedUuid.set(sessionId, last.id);
5831
+ return newMessages.length;
5832
+ }
5833
+ return 0;
5785
5834
  }
5786
5835
  };
5787
5836
 
@@ -6351,6 +6400,10 @@ except Exception:sys.exit(0)
6351
6400
  if (historySvc.isQuotaStale()) {
6352
6401
  fetchQuotaUsage();
6353
6402
  }
6403
+ setTimeout(() => {
6404
+ historySvc.uploadDelta().catch(() => {
6405
+ });
6406
+ }, 400);
6354
6407
  }, () => {
6355
6408
  const prevCount = historySvc.getCurrentMessageCount();
6356
6409
  historySvc.waitForNewUserMessage(prevCount).then((userText) => outputSvc.startTerminalTurn(userText ?? void 0)).catch(() => outputSvc.startTerminalTurn(void 0));
@@ -9048,7 +9101,7 @@ async function stopWorkspaceFromLocal(target) {
9048
9101
  // src/commands/version.ts
9049
9102
  var import_picocolors11 = __toESM(require("picocolors"));
9050
9103
  function version() {
9051
- const v = true ? "2.4.37" : "unknown";
9104
+ const v = true ? "2.4.39" : "unknown";
9052
9105
  console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
9053
9106
  }
9054
9107
 
@@ -9183,7 +9236,7 @@ function checkForUpdates() {
9183
9236
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
9184
9237
  if (process.env.CI) return;
9185
9238
  if (!process.stdout.isTTY) return;
9186
- const current = true ? "2.4.37" : null;
9239
+ const current = true ? "2.4.39" : null;
9187
9240
  if (!current) return;
9188
9241
  const cache = readCache();
9189
9242
  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.4.37",
3
+ "version": "2.4.39",
4
4
  "description": "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands — from anywhere.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",