codeam-cli 2.9.5 → 2.9.7

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.9.5] — 2026-05-10
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Preserve newlines when scanning PTY for API errors
12
+
7
13
  ## [2.9.4] — 2026-05-10
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -1477,7 +1477,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
1477
1477
  // package.json
1478
1478
  var package_default = {
1479
1479
  name: "codeam-cli",
1480
- version: "2.9.5",
1480
+ version: "2.9.7",
1481
1481
  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.",
1482
1482
  type: "commonjs",
1483
1483
  main: "dist/index.js",
@@ -5285,13 +5285,6 @@ var OutputService = class _OutputService {
5285
5285
  pollTimer = null;
5286
5286
  startTime = 0;
5287
5287
  terminalTurnPending = false;
5288
- /**
5289
- * Tracks whether we already emitted an api-error status chunk for
5290
- * the current turn. The error pattern usually appears in multiple
5291
- * consecutive PTY frames as Claude redraws — without this flag the
5292
- * mobile/web client would see the same banner several times in a row.
5293
- */
5294
- apiErrorEmittedThisTurn = false;
5295
5288
  onSessionIdDetected;
5296
5289
  onRateLimitDetected;
5297
5290
  onTurnComplete;
@@ -5382,7 +5375,6 @@ var OutputService = class _OutputService {
5382
5375
  );
5383
5376
  this.tryExtractSessionId(raw);
5384
5377
  this.tryDetectRateLimit(raw);
5385
- this.tryDetectApiError(this.pty.content);
5386
5378
  }
5387
5379
  dispose() {
5388
5380
  this.stopPoll();
@@ -5394,7 +5386,6 @@ var OutputService = class _OutputService {
5394
5386
  this.pty.activate();
5395
5387
  this.steps.reset();
5396
5388
  this.lastSentContent = "";
5397
- this.apiErrorEmittedThisTurn = false;
5398
5389
  this.startTime = Date.now();
5399
5390
  this.pollTimer = setInterval(() => this.tick(), _OutputService.POLL_MS);
5400
5391
  }
@@ -5535,51 +5526,7 @@ var OutputService = class _OutputService {
5535
5526
  this.onRateLimitDetected(match[1].trim());
5536
5527
  }
5537
5528
  }
5538
- /**
5539
- * Detect provider-side API errors that block the turn (out of
5540
- * credits, quota exceeded, auth invalid). These appear in Claude's
5541
- * TUI as `└ Credit balance too low …` / `└ API Error: …` and would
5542
- * otherwise be filtered by `filterChrome` as box-drawing chrome —
5543
- * leaving the mobile chat looking frozen when the user actually
5544
- * just needs to add funds or wait.
5545
- *
5546
- * Side-channel: emits a `status` chunk so the UI can render a
5547
- * banner above the (empty) reply. Does NOT modify the chrome
5548
- * filter — that's tuned for Windows ConPTY quirks and stays as-is.
5549
- *
5550
- * Once-per-turn guard: Claude redraws the same error in multiple
5551
- * frames. Without the guard the user sees the same banner several
5552
- * times in a row.
5553
- */
5554
- tryDetectApiError(text) {
5555
- if (this.apiErrorEmittedThisTurn) return;
5556
- const printable = text.replace(/\x1B\[[^@-~]*[@-~]/g, "").replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/g, "");
5557
- const message = extractApiErrorMessage(printable);
5558
- if (!message) return;
5559
- this.apiErrorEmittedThisTurn = true;
5560
- this.send({ type: "status", content: message }, { critical: true }).catch(() => {
5561
- });
5562
- }
5563
5529
  };
5564
- function extractApiErrorMessage(text) {
5565
- const credit = text.match(/Credit balance too low[^\n]*/i);
5566
- if (credit) {
5567
- return credit[0].trim().replace(/\s+/g, " ");
5568
- }
5569
- const apiError = text.match(/API Error[:\s]+([^\n]{3,200})/i);
5570
- if (apiError) {
5571
- return `API Error: ${apiError[1].trim()}`;
5572
- }
5573
- if (/(?:\bquota\b.*\b(?:exceeded|exhausted)\b|\binsufficient[\s_-]+(?:credits?|funds?|quota)\b)/i.test(text)) {
5574
- const m = text.match(/(?:\bquota\b[^\n]{0,200}|insufficient[^\n]{0,200})/i);
5575
- return m ? m[0].trim().replace(/\s+/g, " ") : "API quota exceeded";
5576
- }
5577
- const auth = text.match(/(?:authentication failed|invalid api key|unauthorized)[^\n]{0,200}/i);
5578
- if (auth) {
5579
- return auth[0].trim().replace(/\s+/g, " ");
5580
- }
5581
- return null;
5582
- }
5583
5530
 
5584
5531
  // src/services/history.service.ts
5585
5532
  var fs5 = __toESM(require("fs"));
@@ -6021,7 +5968,10 @@ var HistoryService = class {
6021
5968
  * Returns the number of messages uploaded (0 means nothing new).
6022
5969
  */
6023
5970
  async uploadDelta() {
6024
- if (!this.currentConversationId) return 0;
5971
+ if (!this.currentConversationId) {
5972
+ this.detectCurrentConversation();
5973
+ if (!this.currentConversationId) return 0;
5974
+ }
6025
5975
  const sessionId = this.currentConversationId;
6026
5976
  const filePath = path8.join(this.projectDir, `${sessionId}.jsonl`);
6027
5977
  const messages = parseJsonl(filePath);
@@ -9371,7 +9321,7 @@ async function stopWorkspaceFromLocal(target) {
9371
9321
  // src/commands/version.ts
9372
9322
  var import_picocolors11 = __toESM(require("picocolors"));
9373
9323
  function version() {
9374
- const v = true ? "2.9.5" : "unknown";
9324
+ const v = true ? "2.9.7" : "unknown";
9375
9325
  console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
9376
9326
  }
9377
9327
 
@@ -9506,7 +9456,7 @@ function checkForUpdates() {
9506
9456
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
9507
9457
  if (process.env.CI) return;
9508
9458
  if (!process.stdout.isTTY) return;
9509
- const current = true ? "2.9.5" : null;
9459
+ const current = true ? "2.9.7" : null;
9510
9460
  if (!current) return;
9511
9461
  const cache = readCache();
9512
9462
  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.9.5",
3
+ "version": "2.9.7",
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",