codeam-cli 1.4.37 → 1.4.38
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/dist/index.js +48 -45
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -116,7 +116,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
116
116
|
// package.json
|
|
117
117
|
var package_default = {
|
|
118
118
|
name: "codeam-cli",
|
|
119
|
-
version: "1.4.
|
|
119
|
+
version: "1.4.38",
|
|
120
120
|
description: "Remote control Claude Code from your mobile device",
|
|
121
121
|
main: "dist/index.js",
|
|
122
122
|
bin: {
|
|
@@ -1116,7 +1116,8 @@ function filterChrome(lines) {
|
|
|
1116
1116
|
if (/^\?\s.*shortcut/i.test(t)) continue;
|
|
1117
1117
|
if (/spending limit|usage limit/i.test(t) && t.length < 80) continue;
|
|
1118
1118
|
if (/↑\s*\/?\s*↓\s*to\s*navigate/i.test(t)) continue;
|
|
1119
|
-
|
|
1119
|
+
const stripped = t.replace(/^[│╭╰╮╯┌└┐┘├┤┬┴┼]\s?/, "");
|
|
1120
|
+
if (/^[❯>]\s+\S/.test(stripped) && !/^[❯>]\s*\d+\./.test(stripped)) {
|
|
1120
1121
|
skipEchoContinuation = true;
|
|
1121
1122
|
continue;
|
|
1122
1123
|
}
|
|
@@ -1148,7 +1149,15 @@ var OutputService = class _OutputService {
|
|
|
1148
1149
|
static IDLE_MS = 3e3;
|
|
1149
1150
|
/** Shorter idle threshold for selector detection (UI is ready immediately). */
|
|
1150
1151
|
static SELECTOR_IDLE_MS = 1500;
|
|
1151
|
-
|
|
1152
|
+
/**
|
|
1153
|
+
* Grace period before the first tick processes output.
|
|
1154
|
+
* Prevents the raw PTY input echo from being captured before Claude Code
|
|
1155
|
+
* clears and re-renders its TUI (which happens within ~100-200 ms of
|
|
1156
|
+
* receiving the input, but we give a 1.5 s margin for loaded machines).
|
|
1157
|
+
*/
|
|
1158
|
+
static WARMUP_MS = 1500;
|
|
1159
|
+
/** Max idle with no visible content (spinner only) before finalizing. */
|
|
1160
|
+
static EMPTY_TIMEOUT_MS = 6e4;
|
|
1152
1161
|
static MAX_MS = 12e4;
|
|
1153
1162
|
newTurn() {
|
|
1154
1163
|
this.stopPoll();
|
|
@@ -1222,6 +1231,7 @@ var OutputService = class _OutputService {
|
|
|
1222
1231
|
this.finalize();
|
|
1223
1232
|
return;
|
|
1224
1233
|
}
|
|
1234
|
+
if (elapsed < _OutputService.WARMUP_MS) return;
|
|
1225
1235
|
const lines = renderToLines(this.rawBuffer);
|
|
1226
1236
|
const selector = detectSelector(lines) ?? detectListSelector(lines);
|
|
1227
1237
|
if (selector) {
|
|
@@ -1559,61 +1569,54 @@ var HistoryService = class {
|
|
|
1559
1569
|
return { used: inputTokens, total, percent, model: lastModel, outputTokens, cacheReadTokens: lastUsage["cache_read_input_tokens"] ?? 0 };
|
|
1560
1570
|
}
|
|
1561
1571
|
/**
|
|
1562
|
-
* Estimate the
|
|
1563
|
-
* Scans
|
|
1572
|
+
* Estimate the API cost for the current month in the current project directory.
|
|
1573
|
+
* Scans only the JSONL files for this project (cwd), so the value reflects
|
|
1574
|
+
* usage from the active Claude Code session rather than the entire machine.
|
|
1564
1575
|
*/
|
|
1565
1576
|
getMonthlyEstimatedCost() {
|
|
1566
|
-
const
|
|
1567
|
-
let projectDirs;
|
|
1568
|
-
try {
|
|
1569
|
-
projectDirs = fs4.readdirSync(claudeDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path4.join(claudeDir, e.name));
|
|
1570
|
-
} catch {
|
|
1571
|
-
return 0;
|
|
1572
|
-
}
|
|
1577
|
+
const projectDir = this.projectDir;
|
|
1573
1578
|
const now = /* @__PURE__ */ new Date();
|
|
1574
1579
|
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
1575
1580
|
const monthStartIso = monthStart.toISOString();
|
|
1576
1581
|
const monthStartMs = monthStart.getTime();
|
|
1577
1582
|
let totalCost = 0;
|
|
1578
|
-
|
|
1579
|
-
|
|
1583
|
+
let files;
|
|
1584
|
+
try {
|
|
1585
|
+
files = fs4.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
1586
|
+
try {
|
|
1587
|
+
return fs4.statSync(path4.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
1588
|
+
} catch {
|
|
1589
|
+
return false;
|
|
1590
|
+
}
|
|
1591
|
+
});
|
|
1592
|
+
} catch {
|
|
1593
|
+
return 0;
|
|
1594
|
+
}
|
|
1595
|
+
for (const file of files) {
|
|
1596
|
+
let raw;
|
|
1580
1597
|
try {
|
|
1581
|
-
|
|
1582
|
-
try {
|
|
1583
|
-
return fs4.statSync(path4.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
1584
|
-
} catch {
|
|
1585
|
-
return false;
|
|
1586
|
-
}
|
|
1587
|
-
});
|
|
1598
|
+
raw = fs4.readFileSync(path4.join(projectDir, file), "utf8");
|
|
1588
1599
|
} catch {
|
|
1589
1600
|
continue;
|
|
1590
1601
|
}
|
|
1591
|
-
for (const
|
|
1592
|
-
let raw;
|
|
1602
|
+
for (const line of raw.split("\n").filter(Boolean)) {
|
|
1593
1603
|
try {
|
|
1594
|
-
|
|
1604
|
+
const record = JSON.parse(line);
|
|
1605
|
+
if (record["type"] !== "assistant") continue;
|
|
1606
|
+
const timestamp = record["timestamp"];
|
|
1607
|
+
if (timestamp && timestamp < monthStartIso) continue;
|
|
1608
|
+
const msg = record["message"];
|
|
1609
|
+
if (!msg || msg["model"] === "<synthetic>") continue;
|
|
1610
|
+
const model = msg["model"] || "";
|
|
1611
|
+
const usage = msg["usage"];
|
|
1612
|
+
if (!usage) continue;
|
|
1613
|
+
const pricing = getPricing(model);
|
|
1614
|
+
const input = usage["input_tokens"] ?? 0;
|
|
1615
|
+
const output = usage["output_tokens"] ?? 0;
|
|
1616
|
+
const cacheRead = usage["cache_read_input_tokens"] ?? 0;
|
|
1617
|
+
const cacheWrite = usage["cache_creation_input_tokens"] ?? 0;
|
|
1618
|
+
totalCost += input / 1e6 * pricing.input + output / 1e6 * pricing.output + cacheRead / 1e6 * pricing.cacheRead + cacheWrite / 1e6 * pricing.cacheWrite;
|
|
1595
1619
|
} catch {
|
|
1596
|
-
continue;
|
|
1597
|
-
}
|
|
1598
|
-
for (const line of raw.split("\n").filter(Boolean)) {
|
|
1599
|
-
try {
|
|
1600
|
-
const record = JSON.parse(line);
|
|
1601
|
-
if (record["type"] !== "assistant") continue;
|
|
1602
|
-
const timestamp = record["timestamp"];
|
|
1603
|
-
if (timestamp && timestamp < monthStartIso) continue;
|
|
1604
|
-
const msg = record["message"];
|
|
1605
|
-
if (!msg || msg["model"] === "<synthetic>") continue;
|
|
1606
|
-
const model = msg["model"] || "";
|
|
1607
|
-
const usage = msg["usage"];
|
|
1608
|
-
if (!usage) continue;
|
|
1609
|
-
const pricing = getPricing(model);
|
|
1610
|
-
const input = usage["input_tokens"] ?? 0;
|
|
1611
|
-
const output = usage["output_tokens"] ?? 0;
|
|
1612
|
-
const cacheRead = usage["cache_read_input_tokens"] ?? 0;
|
|
1613
|
-
const cacheWrite = usage["cache_creation_input_tokens"] ?? 0;
|
|
1614
|
-
totalCost += input / 1e6 * pricing.input + output / 1e6 * pricing.output + cacheRead / 1e6 * pricing.cacheRead + cacheWrite / 1e6 * pricing.cacheWrite;
|
|
1615
|
-
} catch {
|
|
1616
|
-
}
|
|
1617
1620
|
}
|
|
1618
1621
|
}
|
|
1619
1622
|
}
|