codeam-cli 2.9.2 → 2.9.4
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 +19 -0
- package/dist/index.js +56 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ 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.3] — 2026-05-10
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Surface Anthropic API errors as status chunks
|
|
12
|
+
|
|
13
|
+
## [2.9.2] — 2026-05-09
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **jetbrains-plugin:** Heuristic table detection for AI Assistant Compose chat
|
|
18
|
+
- **jetbrains-plugin:** Broaden Compose-table heuristic + diagnostic log
|
|
19
|
+
|
|
20
|
+
## [2.9.1] — 2026-05-09
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **jetbrains-plugin:** Heuristic table detection for AI Assistant Compose chat
|
|
25
|
+
|
|
7
26
|
## [2.9.0] — 2026-05-09
|
|
8
27
|
|
|
9
28
|
### Added
|
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.
|
|
1480
|
+
version: "2.9.4",
|
|
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,6 +5285,13 @@ 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;
|
|
5288
5295
|
onSessionIdDetected;
|
|
5289
5296
|
onRateLimitDetected;
|
|
5290
5297
|
onTurnComplete;
|
|
@@ -5375,6 +5382,7 @@ var OutputService = class _OutputService {
|
|
|
5375
5382
|
);
|
|
5376
5383
|
this.tryExtractSessionId(raw);
|
|
5377
5384
|
this.tryDetectRateLimit(raw);
|
|
5385
|
+
this.tryDetectApiError(this.pty.content);
|
|
5378
5386
|
}
|
|
5379
5387
|
dispose() {
|
|
5380
5388
|
this.stopPoll();
|
|
@@ -5386,6 +5394,7 @@ var OutputService = class _OutputService {
|
|
|
5386
5394
|
this.pty.activate();
|
|
5387
5395
|
this.steps.reset();
|
|
5388
5396
|
this.lastSentContent = "";
|
|
5397
|
+
this.apiErrorEmittedThisTurn = false;
|
|
5389
5398
|
this.startTime = Date.now();
|
|
5390
5399
|
this.pollTimer = setInterval(() => this.tick(), _OutputService.POLL_MS);
|
|
5391
5400
|
}
|
|
@@ -5526,7 +5535,51 @@ var OutputService = class _OutputService {
|
|
|
5526
5535
|
this.onRateLimitDetected(match[1].trim());
|
|
5527
5536
|
}
|
|
5528
5537
|
}
|
|
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-\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
|
+
}
|
|
5529
5563
|
};
|
|
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
|
+
}
|
|
5530
5583
|
|
|
5531
5584
|
// src/services/history.service.ts
|
|
5532
5585
|
var fs5 = __toESM(require("fs"));
|
|
@@ -9318,7 +9371,7 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
9318
9371
|
// src/commands/version.ts
|
|
9319
9372
|
var import_picocolors11 = __toESM(require("picocolors"));
|
|
9320
9373
|
function version() {
|
|
9321
|
-
const v = true ? "2.9.
|
|
9374
|
+
const v = true ? "2.9.4" : "unknown";
|
|
9322
9375
|
console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
|
|
9323
9376
|
}
|
|
9324
9377
|
|
|
@@ -9453,7 +9506,7 @@ function checkForUpdates() {
|
|
|
9453
9506
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
9454
9507
|
if (process.env.CI) return;
|
|
9455
9508
|
if (!process.stdout.isTTY) return;
|
|
9456
|
-
const current = true ? "2.9.
|
|
9509
|
+
const current = true ? "2.9.4" : null;
|
|
9457
9510
|
if (!current) return;
|
|
9458
9511
|
const cache = readCache();
|
|
9459
9512
|
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.
|
|
3
|
+
"version": "2.9.4",
|
|
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",
|