codeam-cli 2.20.0 → 2.20.1
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 +6 -0
- package/dist/index.js +70 -10
- package/package.json +1 -1
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.20.0] — 2026-05-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** CODEAM_TEST_MODE env var to route clients at dev preview (#176)
|
|
12
|
+
|
|
7
13
|
## [2.19.0] — 2026-05-24
|
|
8
14
|
|
|
9
15
|
### Added
|
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.20.
|
|
444
|
+
version: "2.20.1",
|
|
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",
|
|
@@ -5740,7 +5740,7 @@ function readAnonId() {
|
|
|
5740
5740
|
}
|
|
5741
5741
|
function superProperties() {
|
|
5742
5742
|
return {
|
|
5743
|
-
cliVersion: true ? "2.20.
|
|
5743
|
+
cliVersion: true ? "2.20.1" : "0.0.0-dev",
|
|
5744
5744
|
nodeVersion: process.version,
|
|
5745
5745
|
platform: process.platform,
|
|
5746
5746
|
arch: process.arch,
|
|
@@ -9531,6 +9531,9 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9531
9531
|
detectInteractivePrompt(lines) {
|
|
9532
9532
|
return detectSelector(lines) ?? detectListSelector(lines);
|
|
9533
9533
|
}
|
|
9534
|
+
detectReadyPrompt(lines) {
|
|
9535
|
+
return lines.some((l) => /^\?\s.*shortcut/i.test(l.trim()));
|
|
9536
|
+
}
|
|
9534
9537
|
credentialLocator() {
|
|
9535
9538
|
return claudeCredentialLocator();
|
|
9536
9539
|
}
|
|
@@ -10411,6 +10414,9 @@ var CodexRuntimeStrategy = class {
|
|
|
10411
10414
|
detectInteractivePrompt(lines) {
|
|
10412
10415
|
return detectCodexSelector(lines);
|
|
10413
10416
|
}
|
|
10417
|
+
detectReadyPrompt(lines) {
|
|
10418
|
+
return lines.some((l) => /[│┃]\s*›/u.test(l));
|
|
10419
|
+
}
|
|
10414
10420
|
credentialLocator() {
|
|
10415
10421
|
return codexCredentialLocator();
|
|
10416
10422
|
}
|
|
@@ -10858,6 +10864,9 @@ var CursorRuntimeStrategy = class {
|
|
|
10858
10864
|
detectInteractivePrompt(lines) {
|
|
10859
10865
|
return detectCursorSelector(lines);
|
|
10860
10866
|
}
|
|
10867
|
+
detectReadyPrompt(lines) {
|
|
10868
|
+
return lines.some((l) => /[│┃]\s*[›>]\s/u.test(l));
|
|
10869
|
+
}
|
|
10861
10870
|
credentialLocator() {
|
|
10862
10871
|
return cursorCredentialLocator();
|
|
10863
10872
|
}
|
|
@@ -11065,6 +11074,12 @@ var AiderRuntimeStrategy = class {
|
|
|
11065
11074
|
detectInteractivePrompt(lines) {
|
|
11066
11075
|
return detectAiderSelector(lines);
|
|
11067
11076
|
}
|
|
11077
|
+
detectReadyPrompt(lines) {
|
|
11078
|
+
return lines.some((l) => {
|
|
11079
|
+
const t2 = l.replace(/\x1B\[[^@-~]*[@-~]/g, "").trim();
|
|
11080
|
+
return t2 === ">" || /^>\s*$/.test(t2) || /^\.\.\.\s*>\s*$/.test(t2);
|
|
11081
|
+
});
|
|
11082
|
+
}
|
|
11068
11083
|
credentialLocator() {
|
|
11069
11084
|
return aiderCredentialLocator();
|
|
11070
11085
|
}
|
|
@@ -11362,6 +11377,20 @@ var OutputService = class _OutputService {
|
|
|
11362
11377
|
emitter;
|
|
11363
11378
|
runtime;
|
|
11364
11379
|
lastSentContent = "";
|
|
11380
|
+
/**
|
|
11381
|
+
* Wall-clock of the most recent tick where the rendered + filtered
|
|
11382
|
+
* content actually changed. Most agent TUIs keep redrawing a
|
|
11383
|
+
* spinner + input prompt after the response is settled (Claude:
|
|
11384
|
+
* `? for shortcuts`; Codex: ratatui input bar), which keeps
|
|
11385
|
+
* `pty.lastPushTime` moving and prevents the PTY-idle heuristic
|
|
11386
|
+
* from ever crossing the IDLE_MS threshold — so the turn never
|
|
11387
|
+
* finalises and `done: true` never reaches the webapp's
|
|
11388
|
+
* canonical-refresh path. Tracking content-stability separately
|
|
11389
|
+
* closes that hole: PTY can churn all it wants, but once the
|
|
11390
|
+
* filtered TUI output stops changing for a beat we know the
|
|
11391
|
+
* agent is done.
|
|
11392
|
+
*/
|
|
11393
|
+
lastContentChangeAt = 0;
|
|
11365
11394
|
pollTimer = null;
|
|
11366
11395
|
startTime = 0;
|
|
11367
11396
|
terminalTurnPending = false;
|
|
@@ -11375,6 +11404,22 @@ var OutputService = class _OutputService {
|
|
|
11375
11404
|
static IDLE_MS = 3e3;
|
|
11376
11405
|
/** Same threshold but tighter for selectors (UI is ready to interact immediately). */
|
|
11377
11406
|
static SELECTOR_IDLE_MS = 1500;
|
|
11407
|
+
/**
|
|
11408
|
+
* Content-stable threshold. When the rendered + filtered content
|
|
11409
|
+
* hasn't changed for this long AND we can see Claude's "? for
|
|
11410
|
+
* shortcuts" prompt re-drawn at the bottom (= back to input
|
|
11411
|
+
* state), we know the response is settled even though the PTY
|
|
11412
|
+
* itself is still pushing spinner / status redraws. Tighter than
|
|
11413
|
+
* IDLE_MS because the ready-prompt is a strong signal on its own.
|
|
11414
|
+
*/
|
|
11415
|
+
static READY_STABLE_MS = 800;
|
|
11416
|
+
/**
|
|
11417
|
+
* Hard content-stable fallback. If the filtered content has been
|
|
11418
|
+
* unchanged for this long, finalize regardless of the ready
|
|
11419
|
+
* prompt — covers cases where Claude's TUI doesn't redraw the
|
|
11420
|
+
* shortcuts line (older versions, headless runs).
|
|
11421
|
+
*/
|
|
11422
|
+
static CONTENT_STABLE_MS = 8e3;
|
|
11378
11423
|
/**
|
|
11379
11424
|
* Grace period before tick processes anything — Claude needs ~100-
|
|
11380
11425
|
* 200 ms after `\r` to clear the input echo and re-render the TUI.
|
|
@@ -11496,6 +11541,7 @@ var OutputService = class _OutputService {
|
|
|
11496
11541
|
this.pty.activate();
|
|
11497
11542
|
this.steps.reset();
|
|
11498
11543
|
this.lastSentContent = "";
|
|
11544
|
+
this.lastContentChangeAt = 0;
|
|
11499
11545
|
this.startTime = Date.now();
|
|
11500
11546
|
this.pollTimer = setInterval(() => this.tick(), _OutputService.POLL_MS);
|
|
11501
11547
|
}
|
|
@@ -11588,18 +11634,32 @@ var OutputService = class _OutputService {
|
|
|
11588
11634
|
return;
|
|
11589
11635
|
}
|
|
11590
11636
|
const idleMs = this.pty.lastPushTime > 0 ? now - this.pty.lastPushTime : elapsed;
|
|
11637
|
+
if (content !== this.lastSentContent) {
|
|
11638
|
+
this.lastContentChangeAt = now;
|
|
11639
|
+
this.lastSentContent = content;
|
|
11640
|
+
this.send({ type: "text", content, done: false }).catch(() => {
|
|
11641
|
+
});
|
|
11642
|
+
}
|
|
11643
|
+
const contentStableMs = this.lastContentChangeAt > 0 ? now - this.lastContentChangeAt : 0;
|
|
11644
|
+
const readyPrompt = this.runtime.detectReadyPrompt?.(lines) ?? false;
|
|
11591
11645
|
log.trace(
|
|
11592
11646
|
"outputSvc",
|
|
11593
|
-
`tick content (raw=${this.pty.size}B lines=${lines.length} content=${content.length} idleMs=${idleMs})`
|
|
11647
|
+
`tick content (raw=${this.pty.size}B lines=${lines.length} content=${content.length} idleMs=${idleMs} stableMs=${contentStableMs} ready=${readyPrompt})`
|
|
11594
11648
|
);
|
|
11595
11649
|
if (idleMs >= _OutputService.IDLE_MS) {
|
|
11650
|
+
log.trace("outputSvc", `finalize: idleMs=${idleMs}`);
|
|
11596
11651
|
this.finalize();
|
|
11597
11652
|
return;
|
|
11598
11653
|
}
|
|
11599
|
-
if (
|
|
11600
|
-
|
|
11601
|
-
this.
|
|
11602
|
-
|
|
11654
|
+
if (readyPrompt && contentStableMs >= _OutputService.READY_STABLE_MS) {
|
|
11655
|
+
log.trace("outputSvc", `finalize: readyPrompt + stableMs=${contentStableMs}`);
|
|
11656
|
+
this.finalize();
|
|
11657
|
+
return;
|
|
11658
|
+
}
|
|
11659
|
+
if (contentStableMs >= _OutputService.CONTENT_STABLE_MS) {
|
|
11660
|
+
log.trace("outputSvc", `finalize: stableMs=${contentStableMs} (fallback)`);
|
|
11661
|
+
this.finalize();
|
|
11662
|
+
return;
|
|
11603
11663
|
}
|
|
11604
11664
|
}
|
|
11605
11665
|
finalize() {
|
|
@@ -17330,7 +17390,7 @@ function checkChokidar() {
|
|
|
17330
17390
|
}
|
|
17331
17391
|
async function doctor(args2 = []) {
|
|
17332
17392
|
const json = args2.includes("--json");
|
|
17333
|
-
const cliVersion = true ? "2.20.
|
|
17393
|
+
const cliVersion = true ? "2.20.1" : "0.0.0-dev";
|
|
17334
17394
|
const apiBase = resolveApiBaseUrl();
|
|
17335
17395
|
const diagnosticId = (0, import_node_crypto5.randomUUID)();
|
|
17336
17396
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -17529,7 +17589,7 @@ async function completion(args2) {
|
|
|
17529
17589
|
// src/commands/version.ts
|
|
17530
17590
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
17531
17591
|
function version2() {
|
|
17532
|
-
const v = true ? "2.20.
|
|
17592
|
+
const v = true ? "2.20.1" : "unknown";
|
|
17533
17593
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
17534
17594
|
}
|
|
17535
17595
|
|
|
@@ -17757,7 +17817,7 @@ function checkForUpdates() {
|
|
|
17757
17817
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17758
17818
|
if (process.env.CI) return;
|
|
17759
17819
|
if (!process.stdout.isTTY) return;
|
|
17760
|
-
const current = true ? "2.20.
|
|
17820
|
+
const current = true ? "2.20.1" : null;
|
|
17761
17821
|
if (!current) return;
|
|
17762
17822
|
const cache = readCache();
|
|
17763
17823
|
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.20.
|
|
3
|
+
"version": "2.20.1",
|
|
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",
|