codeam-cli 1.4.6 → 1.4.8
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 +58 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ function makeConfig(baseDir) {
|
|
|
71
71
|
const c = load();
|
|
72
72
|
c.sessions = c.sessions.filter((s) => s.id !== session.id);
|
|
73
73
|
c.sessions.unshift(session);
|
|
74
|
-
|
|
74
|
+
c.activeSessionId = session.id;
|
|
75
75
|
save(c);
|
|
76
76
|
}
|
|
77
77
|
function removeSession2(sessionId) {
|
|
@@ -115,7 +115,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
115
115
|
// package.json
|
|
116
116
|
var package_default = {
|
|
117
117
|
name: "codeam-cli",
|
|
118
|
-
version: "1.4.
|
|
118
|
+
version: "1.4.8",
|
|
119
119
|
description: "Remote control Claude Code from your mobile device",
|
|
120
120
|
main: "dist/index.js",
|
|
121
121
|
bin: {
|
|
@@ -1369,6 +1369,56 @@ var HistoryService = class {
|
|
|
1369
1369
|
get projectDir() {
|
|
1370
1370
|
return path4.join(os4.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
1371
1371
|
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Read the most recently modified JSONL session file and extract the
|
|
1374
|
+
* context window usage from the last assistant message's usage field.
|
|
1375
|
+
*
|
|
1376
|
+
* Claude Code records token counts per-response:
|
|
1377
|
+
* input_tokens + cache_read_input_tokens + cache_creation_input_tokens
|
|
1378
|
+
* = total context tokens consumed in that request.
|
|
1379
|
+
*/
|
|
1380
|
+
getCurrentUsage() {
|
|
1381
|
+
const dir = this.projectDir;
|
|
1382
|
+
let entries;
|
|
1383
|
+
try {
|
|
1384
|
+
entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
1385
|
+
} catch {
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
1389
|
+
try {
|
|
1390
|
+
return { name: e.name, mtime: fs4.statSync(path4.join(dir, e.name)).mtimeMs };
|
|
1391
|
+
} catch {
|
|
1392
|
+
return { name: e.name, mtime: 0 };
|
|
1393
|
+
}
|
|
1394
|
+
}).sort((a, b) => b.mtime - a.mtime);
|
|
1395
|
+
if (files.length === 0) return null;
|
|
1396
|
+
let raw;
|
|
1397
|
+
try {
|
|
1398
|
+
raw = fs4.readFileSync(path4.join(dir, files[0].name), "utf8");
|
|
1399
|
+
} catch {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
let lastUsage = null;
|
|
1403
|
+
let lastModel = null;
|
|
1404
|
+
for (const line of raw.split("\n").filter(Boolean)) {
|
|
1405
|
+
try {
|
|
1406
|
+
const record = JSON.parse(line);
|
|
1407
|
+
if (record["type"] === "assistant") {
|
|
1408
|
+
const msg = record["message"];
|
|
1409
|
+
if (msg?.["usage"]) lastUsage = msg["usage"];
|
|
1410
|
+
if (msg?.["model"]) lastModel = msg["model"];
|
|
1411
|
+
}
|
|
1412
|
+
} catch {
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
if (!lastUsage) return null;
|
|
1416
|
+
const inputTokens = (lastUsage["input_tokens"] ?? 0) + (lastUsage["cache_read_input_tokens"] ?? 0) + (lastUsage["cache_creation_input_tokens"] ?? 0);
|
|
1417
|
+
const outputTokens = lastUsage["output_tokens"] ?? 0;
|
|
1418
|
+
const total = 2e5;
|
|
1419
|
+
const percent = Math.min(100, Math.round(inputTokens / total * 100));
|
|
1420
|
+
return { used: inputTokens, total, percent, model: lastModel, outputTokens, cacheReadTokens: lastUsage["cache_read_input_tokens"] ?? 0 };
|
|
1421
|
+
}
|
|
1372
1422
|
/**
|
|
1373
1423
|
* Read session list from disk and POST it to the API.
|
|
1374
1424
|
* Called once ~2 s after Claude spawns (non-blocking).
|
|
@@ -1455,6 +1505,7 @@ async function start() {
|
|
|
1455
1505
|
showInfo("Launching Claude Code...\n");
|
|
1456
1506
|
const ws = new WebSocketService(session.id, pluginId);
|
|
1457
1507
|
const outputSvc = new OutputService(session.id, pluginId);
|
|
1508
|
+
const historySvc = new HistoryService(pluginId, process.cwd());
|
|
1458
1509
|
function sendPrompt(prompt) {
|
|
1459
1510
|
outputSvc.newTurn();
|
|
1460
1511
|
claude.sendCommand(prompt);
|
|
@@ -1502,6 +1553,11 @@ async function start() {
|
|
|
1502
1553
|
case "stop_task":
|
|
1503
1554
|
claude.interrupt();
|
|
1504
1555
|
break;
|
|
1556
|
+
case "get_context": {
|
|
1557
|
+
const usage = historySvc.getCurrentUsage();
|
|
1558
|
+
await relay.sendResult(cmd.id, "completed", usage ?? { error: "No usage data found" });
|
|
1559
|
+
break;
|
|
1560
|
+
}
|
|
1505
1561
|
case "resume_session": {
|
|
1506
1562
|
const id = cmd.payload.id;
|
|
1507
1563
|
const auto = cmd.payload.auto ?? false;
|
|
@@ -1591,7 +1647,6 @@ async function start() {
|
|
|
1591
1647
|
}
|
|
1592
1648
|
process.once("SIGINT", sigintHandler);
|
|
1593
1649
|
claude.spawn();
|
|
1594
|
-
const historySvc = new HistoryService(pluginId, process.cwd());
|
|
1595
1650
|
setTimeout(() => {
|
|
1596
1651
|
historySvc.load().catch(() => {
|
|
1597
1652
|
});
|