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 +6 -0
- package/dist/index.js +63 -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.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.
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|