codeam-cli 1.4.22 → 1.4.24

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 +49 -3
  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.22",
118
+ version: "1.4.24",
119
119
  description: "Remote control Claude Code from your mobile device",
120
120
  main: "dist/index.js",
121
121
  bin: {
@@ -1125,11 +1125,12 @@ function filterChrome(lines) {
1125
1125
  return result;
1126
1126
  }
1127
1127
  var OutputService = class _OutputService {
1128
- constructor(sessionId, pluginId, onSessionIdDetected, onRateLimitDetected) {
1128
+ constructor(sessionId, pluginId, onSessionIdDetected, onRateLimitDetected, onTurnComplete) {
1129
1129
  this.sessionId = sessionId;
1130
1130
  this.pluginId = pluginId;
1131
1131
  this.onSessionIdDetected = onSessionIdDetected;
1132
1132
  this.onRateLimitDetected = onRateLimitDetected;
1133
+ this.onTurnComplete = onTurnComplete;
1133
1134
  }
1134
1135
  sessionId;
1135
1136
  pluginId;
@@ -1141,6 +1142,7 @@ var OutputService = class _OutputService {
1141
1142
  lastPushTime = 0;
1142
1143
  onSessionIdDetected;
1143
1144
  onRateLimitDetected;
1145
+ onTurnComplete;
1144
1146
  static POLL_MS = 1e3;
1145
1147
  static IDLE_MS = 3e3;
1146
1148
  /** Shorter idle threshold for selector detection (UI is ready immediately). */
@@ -1259,6 +1261,7 @@ var OutputService = class _OutputService {
1259
1261
  const content = filterChrome(lines).join("\n").replace(/\n{3,}/g, "\n\n").trim();
1260
1262
  this.postChunk({ type: "text", content, done: true }).catch(() => {
1261
1263
  });
1264
+ this.onTurnComplete?.();
1262
1265
  }
1263
1266
  }
1264
1267
  stopPoll() {
@@ -1430,6 +1433,7 @@ var HistoryService = class {
1430
1433
  cwd;
1431
1434
  currentConversationId = null;
1432
1435
  _rateLimitReset = null;
1436
+ _quotaPercent = null;
1433
1437
  /** Store rate limit reset info detected from Claude Code output */
1434
1438
  setRateLimitReset(reset) {
1435
1439
  this._rateLimitReset = reset;
@@ -1437,6 +1441,13 @@ var HistoryService = class {
1437
1441
  getRateLimitReset() {
1438
1442
  return this._rateLimitReset;
1439
1443
  }
1444
+ /** Store weekly quota usage percentage parsed from /usage output */
1445
+ setQuotaPercent(percent) {
1446
+ this._quotaPercent = percent;
1447
+ }
1448
+ getQuotaPercent() {
1449
+ return this._quotaPercent;
1450
+ }
1440
1451
  get projectDir() {
1441
1452
  return path4.join(os4.homedir(), ".claude", "projects", encodeCwd(this.cwd));
1442
1453
  }
@@ -1686,10 +1697,40 @@ async function start() {
1686
1697
  const cwd = process.cwd();
1687
1698
  const ws = new WebSocketService(session.id, pluginId);
1688
1699
  const historySvc = new HistoryService(pluginId, cwd);
1700
+ let capturingQuota = false;
1701
+ let quotaBuffer = "";
1702
+ let turnCount = 0;
1703
+ const USAGE_FETCH_INTERVAL = 5;
1704
+ function fetchQuotaUsage() {
1705
+ capturingQuota = true;
1706
+ quotaBuffer = "";
1707
+ claude.sendCommand("/usage");
1708
+ setTimeout(() => {
1709
+ const clean = quotaBuffer.replace(/\x1B\[[^@-~]*[@-~]/g, "").replace(/[\x00-\x1F\x7F]/g, "");
1710
+ const weekMatch = clean.match(/current\s+week[^]*?(\d+)%\s*used/i);
1711
+ if (weekMatch) {
1712
+ historySvc.setQuotaPercent(parseInt(weekMatch[1], 10));
1713
+ }
1714
+ const resetMatch = clean.match(/resets\s+(.+?)(?:\s*\(|$)/im);
1715
+ if (resetMatch) {
1716
+ historySvc.setRateLimitReset(resetMatch[1].trim());
1717
+ }
1718
+ claude.sendEscape();
1719
+ setTimeout(() => {
1720
+ capturingQuota = false;
1721
+ quotaBuffer = "";
1722
+ }, 500);
1723
+ }, 2e3);
1724
+ }
1689
1725
  const outputSvc = new OutputService(session.id, pluginId, (conversationId) => {
1690
1726
  historySvc.setCurrentConversationId(conversationId);
1691
1727
  }, (reset) => {
1692
1728
  historySvc.setRateLimitReset(reset);
1729
+ }, () => {
1730
+ turnCount++;
1731
+ if (turnCount % USAGE_FETCH_INTERVAL === 1) {
1732
+ fetchQuotaUsage();
1733
+ }
1693
1734
  });
1694
1735
  function sendPrompt(prompt) {
1695
1736
  outputSvc.newTurn();
@@ -1742,8 +1783,9 @@ async function start() {
1742
1783
  const usage = historySvc.getCurrentUsage();
1743
1784
  const monthlyCost = historySvc.getMonthlyEstimatedCost();
1744
1785
  const rateLimitReset = historySvc.getRateLimitReset();
1786
+ const quotaPercent = historySvc.getQuotaPercent();
1745
1787
  const base = usage ? { ...usage, monthlyCost } : { used: 0, total: 2e5, percent: 0, model: null, outputTokens: 0, cacheReadTokens: 0, monthlyCost, error: "No usage data found" };
1746
- const result = rateLimitReset ? { ...base, rateLimitReset } : base;
1788
+ const result = { ...base, ...rateLimitReset ? { rateLimitReset } : {}, ...quotaPercent !== null ? { quotaPercent } : {} };
1747
1789
  await relay.sendResult(cmd.id, "completed", result);
1748
1790
  break;
1749
1791
  }
@@ -1818,6 +1860,10 @@ async function start() {
1818
1860
  const claude = new ClaudeService({
1819
1861
  cwd: process.cwd(),
1820
1862
  onData(raw) {
1863
+ if (capturingQuota) {
1864
+ quotaBuffer += raw;
1865
+ return;
1866
+ }
1821
1867
  outputSvc.push(raw);
1822
1868
  },
1823
1869
  onExit(code) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "1.4.22",
3
+ "version": "1.4.24",
4
4
  "description": "Remote control Claude Code from your mobile device",
5
5
  "main": "dist/index.js",
6
6
  "bin": {