codeam-cli 1.4.7 → 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.
Files changed (2) hide show
  1. package/dist/index.js +57 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -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.7",
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "1.4.7",
3
+ "version": "1.4.8",
4
4
  "description": "Remote control Claude Code from your mobile device",
5
5
  "main": "dist/index.js",
6
6
  "bin": {