@relayburn/mcp 1.4.0 → 1.6.0

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 CHANGED
@@ -4,6 +4,12 @@ All notable changes to `@relayburn/mcp`.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.5.0] - 2026-05-02
8
+
9
+ ### Removed
10
+
11
+ - Removed the `burn__currentBlock` quota forecast tool; MCP now exposes session cost lookup only.
12
+
7
13
  ## [1.2.1] - 2026-04-30
8
14
 
9
15
  ### Changed
package/dist/index.d.ts CHANGED
@@ -5,6 +5,4 @@ export type { StartStdioServerOptions, RunningServer } from './server.js';
5
5
  export type { ToolDefinition, ToolHandler, ToolInputSchema } from './types.js';
6
6
  export { createSessionCostTool } from './tools/session-cost.js';
7
7
  export type { SessionCostDeps, SessionCostInput, SessionCostResult } from './tools/session-cost.js';
8
- export { createCurrentBlockTool } from './tools/current-block.js';
9
- export type { CurrentBlockAdvice, CurrentBlockDeps, CurrentBlockResult, } from './tools/current-block.js';
10
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACpG,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export { buildMcpConfig } from './config.js';
2
2
  export { startStdioServer } from './server.js';
3
3
  export { createSessionCostTool } from './tools/session-cost.js';
4
- export { createCurrentBlockTool } from './tools/current-block.js';
5
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -4,11 +4,10 @@ import { tmpdir } from 'node:os';
4
4
  import * as path from 'node:path';
5
5
  import { after, before, beforeEach, describe, it } from 'node:test';
6
6
  import { __resetIndexCacheForTesting, appendTurns, archivePath, buildArchive, } from '@relayburn/ledger';
7
- import { createCurrentBlockTool } from './current-block.js';
8
7
  import { createSessionCostTool } from './session-cost.js';
9
8
  // Verifies the archive-backed default `queryTurns` path that issue #97 wires
10
- // onto both MCP tool handlers — including the transparent fallback to
11
- // `queryAll` when the archive cannot be opened or queried.
9
+ // onto MCP tool handlers — including the transparent fallback to `queryAll`
10
+ // when the archive cannot be opened or queried.
12
11
  function fakeTurn(overrides = {}) {
13
12
  return {
14
13
  v: 1,
@@ -148,73 +147,5 @@ describe('MCP tool handlers backed by archive (issue #97)', () => {
148
147
  assert.ok(logs.some((m) => /sessionCost: archive query failed/.test(m)), `expected an archive-fallback log line, got: ${JSON.stringify(logs)}`);
149
148
  });
150
149
  });
151
- describe('burn__currentBlock', () => {
152
- it('reads ledger-derived burn rate from the materialized archive on the hot path', async () => {
153
- // 60k input tokens, treated as having accrued in the 2h elapsed of a
154
- // 5h window starting at 10:00. This mirrors the existing unit test for
155
- // the same calculation but exercises the real archive-backed code
156
- // path instead of an injected `queryTurns`.
157
- await appendTurns([
158
- fakeTurn({
159
- sessionId: 's-block',
160
- messageId: 'mb-1',
161
- ts: '2026-04-24T10:30:00.000Z',
162
- usage: {
163
- input: 60_000,
164
- output: 0,
165
- reasoning: 0,
166
- cacheRead: 0,
167
- cacheCreate5m: 0,
168
- cacheCreate1h: 0,
169
- },
170
- }),
171
- ]);
172
- await buildArchive();
173
- const NOW = new Date('2026-04-24T12:00:00.000Z');
174
- const RESET_AT = '2026-04-24T15:00:00.000Z';
175
- const tool = createCurrentBlockTool({
176
- now: () => NOW,
177
- loadOauthToken: async () => 'tok',
178
- fetchUsage: async () => ({ five_hour: { percent_used: 20, reset_at: RESET_AT } }),
179
- });
180
- const result = (await tool.handler({}));
181
- assert.equal(result.percentUsed, 20);
182
- // 60k tokens / 120 minutes = 500 tok/min.
183
- assert.equal(result.burnRateTokensPerMin, 500);
184
- assert.equal(result.projectedBlockTotal, 150_000);
185
- });
186
- it('falls back to queryAll and logs when the archive query throws', async () => {
187
- await appendTurns([
188
- fakeTurn({
189
- sessionId: 's-block',
190
- messageId: 'mb-1',
191
- ts: '2026-04-24T10:30:00.000Z',
192
- usage: {
193
- input: 60_000,
194
- output: 0,
195
- reasoning: 0,
196
- cacheRead: 0,
197
- cacheCreate5m: 0,
198
- cacheCreate1h: 0,
199
- },
200
- }),
201
- ]);
202
- // Corrupt archive file → openArchive throws; tool should fall through
203
- // to queryAll and still produce the same forecast.
204
- await writeFile(archivePath(), 'not a sqlite db', 'utf8');
205
- const NOW = new Date('2026-04-24T12:00:00.000Z');
206
- const RESET_AT = '2026-04-24T15:00:00.000Z';
207
- const logs = [];
208
- const tool = createCurrentBlockTool({
209
- now: () => NOW,
210
- loadOauthToken: async () => 'tok',
211
- fetchUsage: async () => ({ five_hour: { percent_used: 20, reset_at: RESET_AT } }),
212
- onLog: (m) => logs.push(m),
213
- });
214
- const result = (await tool.handler({}));
215
- assert.equal(result.burnRateTokensPerMin, 500);
216
- assert.ok(logs.some((m) => /currentBlock: archive query failed/.test(m)), `expected an archive-fallback log line, got: ${JSON.stringify(logs)}`);
217
- });
218
- });
219
150
  });
220
151
  //# sourceMappingURL=archive-backed.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"archive-backed.test.js","sourceRoot":"","sources":["../../src/tools/archive-backed.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"archive-backed.test.js","sourceRoot":"","sources":["../../src/tools/archive-backed.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EACL,2BAA2B,EAC3B,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAA0B,MAAM,mBAAmB,CAAC;AAElF,6EAA6E;AAC7E,4EAA4E;AAC5E,gDAAgD;AAEhD,SAAS,QAAQ,CAAC,YAAiC,EAAE;IACnD,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,CAAC;QACZ,EAAE,EAAE,0BAA0B;QAC9B,KAAK,EAAE,mBAAmB;QAC1B,KAAK,EAAE;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,CAAC;YAChB,aAAa,EAAE,CAAC;SACjB;QACD,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,cAAc;QACvB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;IAClC,mBAAmB,EAAE;QACnB,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,GAAG;QACd,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,gBAAyB;KACzC;CACF,CAAC,CAAC;AAEH,QAAQ,CAAC,iDAAiD,EAAE,GAAG,EAAE;IAC/D,IAAI,MAAc,CAAC;IACnB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAEnD,MAAM,CAAC,KAAK,IAAI,EAAE;QAChB,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC;QACvC,2BAA2B,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,mEAAmE;YACnE,gEAAgE;YAChE,MAAM,WAAW,CAAC;gBAChB,QAAQ,EAAE;gBACV,QAAQ,CAAC;oBACP,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,CAAC;oBACZ,KAAK,EAAE;wBACL,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,SAAS;wBACjB,SAAS,EAAE,CAAC;wBACZ,SAAS,EAAE,CAAC;wBACZ,aAAa,EAAE,CAAC;wBAChB,aAAa,EAAE,CAAC;qBACjB;iBACF,CAAC;aACH,CAAC,CAAC;YACH,MAAM,YAAY,EAAE,CAAC;YAErB,MAAM,IAAI,GAAG,qBAAqB,CAAC;gBACjC,gBAAgB,EAAE,QAAQ;gBAC1B,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAsB,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC5C,6CAA6C;YAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC9E,wEAAwE;YACxE,iEAAiE;YACjE,oEAAoE;YACpE,2DAA2D;YAC3D,MAAM,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAChC,MAAM,YAAY,EAAE,CAAC;YAErB,uEAAuE;YACvE,4DAA4D;YAC5D,MAAM,WAAW,CAAC;gBAChB,QAAQ,CAAC;oBACP,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,CAAC;oBACZ,EAAE,EAAE,0BAA0B;oBAC9B,KAAK,EAAE;wBACL,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,SAAS;wBACjB,SAAS,EAAE,CAAC;wBACZ,SAAS,EAAE,CAAC;wBACZ,aAAa,EAAE,CAAC;wBAChB,aAAa,EAAE,CAAC;qBACjB;iBACF,CAAC;aACH,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,qBAAqB,CAAC;gBACjC,gBAAgB,EAAE,QAAQ;gBAC1B,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAsB,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC5C,6CAA6C;YAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAChC,4DAA4D;YAC5D,oEAAoE;YACpE,qEAAqE;YACrE,oBAAoB;YACpB,MAAM,SAAS,CAAC,WAAW,EAAE,EAAE,+BAA+B,EAAE,MAAM,CAAC,CAAC;YAExE,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,qBAAqB,CAAC;gBACjC,gBAAgB,EAAE,QAAQ;gBAC1B,WAAW,EAAE,cAAc;gBAC3B,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;aAC3B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAsB,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC5C,wBAAwB;YACxB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,EAAE,CACP,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAC7D,+CAA+C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relayburn/mcp",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "MCP (Model Context Protocol) server exposing read-only relayburn ledger queries for in-session self-query",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,9 +19,9 @@
19
19
  "node": ">=22"
20
20
  },
21
21
  "dependencies": {
22
- "@relayburn/reader": "1.4.0",
23
- "@relayburn/ledger": "1.4.0",
24
- "@relayburn/analyze": "1.4.0"
22
+ "@relayburn/reader": "1.6.0",
23
+ "@relayburn/ledger": "1.6.0",
24
+ "@relayburn/analyze": "1.6.0"
25
25
  },
26
26
  "repository": {
27
27
  "type": "git",
@@ -1,34 +0,0 @@
1
- import type { EnrichedTurn } from '@relayburn/ledger';
2
- import type { ToolDefinition } from '../types.js';
3
- interface UsageWindow {
4
- percent_used: number;
5
- reset_at: string;
6
- }
7
- interface UsageResponse {
8
- five_hour?: UsageWindow;
9
- }
10
- export type CurrentBlockAdvice = 'on-track' | 'at-risk' | 'over-budget' | 'unknown';
11
- export interface CurrentBlockResult {
12
- percentUsed: number | null;
13
- burnRateTokensPerMin: number | null;
14
- projectedBlockTotal: number | null;
15
- minutesToReset: number | null;
16
- advice: CurrentBlockAdvice;
17
- note?: string;
18
- }
19
- export interface CurrentBlockDeps {
20
- loadOauthToken?: () => Promise<string | null>;
21
- fetchUsage?: (token: string) => Promise<UsageResponse>;
22
- queryTurns?: (windowStartMs: number) => Promise<EnrichedTurn[]>;
23
- now?: () => Date;
24
- /**
25
- * Called when the default archive-backed `queryTurns` falls through to the
26
- * ledger-walking `queryAll` because the archive open / query threw. Defaults
27
- * to no-op; the CLI server wires this to stderr so failures are visible.
28
- */
29
- onLog?: (msg: string) => void;
30
- }
31
- export declare function createCurrentBlockTool(deps?: CurrentBlockDeps): ToolDefinition;
32
- export declare function loadOauthToken(): Promise<string | null>;
33
- export {};
34
- //# sourceMappingURL=current-block.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"current-block.d.ts","sourceRoot":"","sources":["../../src/tools/current-block.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAMlD,UAAU,WAAW;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAChE,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,gBAAqB,GAAG,cAAc,CAsFlF;AAoED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY7D"}
@@ -1,243 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { readFile } from 'node:fs/promises';
3
- import { homedir } from 'node:os';
4
- import * as path from 'node:path';
5
- import { buildArchive, queryAll, queryTurnsFromArchive } from '@relayburn/ledger';
6
- const USAGE_ENDPOINT = 'https://api.anthropic.com/api/oauth/usage';
7
- const ANTHROPIC_OAUTH_BETA = 'oauth-2025-04-20';
8
- const SESSION_DURATION_MS = 5 * 60 * 60 * 1000;
9
- export function createCurrentBlockTool(deps = {}) {
10
- const loadToken = deps.loadOauthToken ?? loadOauthToken;
11
- const fetchUsage = deps.fetchUsage ?? fetchUsageFromApi;
12
- const log = deps.onLog ?? (() => { });
13
- const queryTurns = deps.queryTurns ??
14
- (async (start) => {
15
- const since = new Date(start).toISOString();
16
- // Hooks append new turns to the JSONL ledger throughout the session,
17
- // but the archive is only materialized when something explicitly calls
18
- // `buildArchive`. Run an incremental build before each query so the
19
- // tool reflects fresh data. The build is
20
- // idempotent + cursor-driven, so it's a no-op when nothing has changed
21
- // since the last call.
22
- try {
23
- await buildArchive();
24
- return await queryTurnsFromArchive({ since, source: 'claude-code' });
25
- }
26
- catch (err) {
27
- const msg = err instanceof Error ? err.message : String(err);
28
- log(`currentBlock: archive query failed, falling back to ledger walk: ${msg}`);
29
- return queryAll({ since, source: 'claude-code' });
30
- }
31
- });
32
- const now = deps.now ?? (() => new Date());
33
- return {
34
- name: 'burn__currentBlock',
35
- description: "Return the Claude 5-hour quota window's current percent-used and a " +
36
- 'locally-forecast burn rate + projection. Combines the OAuth-reported ' +
37
- 'window state with ledger-derived token totals so an agent can decide ' +
38
- 'whether to downgrade models mid-session. Read-only.',
39
- inputSchema: {
40
- type: 'object',
41
- properties: {
42
- sessionId: {
43
- type: 'string',
44
- description: 'Accepted but not used — current-block is account-wide, not per-session.',
45
- },
46
- },
47
- required: [],
48
- additionalProperties: false,
49
- },
50
- handler: async () => {
51
- const nowDate = now();
52
- const nowMs = nowDate.getTime();
53
- const token = await loadToken();
54
- let usage = null;
55
- let usageError = null;
56
- if (token) {
57
- try {
58
- usage = await fetchUsage(token);
59
- }
60
- catch (err) {
61
- usageError = err instanceof Error ? err.message : String(err);
62
- }
63
- }
64
- else {
65
- usageError = 'no Claude OAuth token found';
66
- }
67
- const windowStartMs = forecastWindowStartMs(usage?.five_hour, nowMs);
68
- const turns = await queryTurns(windowStartMs);
69
- const tokensSoFar = sumTokens(turns);
70
- const elapsedMs = Math.max(0, nowMs - windowStartMs);
71
- const remainingMs = Math.max(0, windowStartMs + SESSION_DURATION_MS - nowMs);
72
- const burnRate = elapsedMs > 0 ? tokensSoFar / (elapsedMs / 60_000) : null;
73
- const projectedBlockTotal = burnRate !== null ? Math.round(burnRate * (SESSION_DURATION_MS / 60_000)) : null;
74
- const minutesToReset = Math.round(remainingMs / 60_000);
75
- const pct = normalizePercent(usage?.five_hour?.percent_used);
76
- const projectedPct = projectPercentAtReset(pct, elapsedMs, remainingMs);
77
- const advice = deriveAdvice(pct, projectedPct);
78
- const result = {
79
- percentUsed: pct,
80
- burnRateTokensPerMin: burnRate !== null ? Math.round(burnRate) : null,
81
- projectedBlockTotal,
82
- minutesToReset,
83
- advice,
84
- };
85
- if (usageError)
86
- result.note = `oauth usage unavailable: ${usageError}`;
87
- return result;
88
- },
89
- };
90
- }
91
- function sumTokens(turns) {
92
- let total = 0;
93
- for (const t of turns) {
94
- const u = t.usage;
95
- total +=
96
- (u.input ?? 0) +
97
- (u.output ?? 0) +
98
- (u.reasoning ?? 0) +
99
- (u.cacheRead ?? 0) +
100
- (u.cacheCreate5m ?? 0) +
101
- (u.cacheCreate1h ?? 0);
102
- }
103
- return total;
104
- }
105
- function normalizePercent(raw) {
106
- if (raw === undefined || !Number.isFinite(raw))
107
- return null;
108
- // Anthropic's OAuth usage endpoint documents and returns the 0..100 scale
109
- // (e.g. percent_used: 34 means 34%). Pass it through unchanged. An earlier
110
- // version tried to auto-detect 0..1 vs 0..100 with a > 1.5 threshold, but
111
- // that misclassifies legitimately-low values like 1% as 0..1 scale and
112
- // inflates them 100x — turning "1% used" into "100% used → over-budget"
113
- // and causing false alarms early in a quota window.
114
- return raw;
115
- }
116
- function projectPercentAtReset(currentPercent, elapsedMs, remainingMs) {
117
- if (currentPercent === null)
118
- return null;
119
- if (elapsedMs <= 0)
120
- return null;
121
- const totalMs = elapsedMs + remainingMs;
122
- if (totalMs <= 0)
123
- return null;
124
- const elapsedFraction = elapsedMs / totalMs;
125
- if (elapsedFraction <= 0)
126
- return null;
127
- return Math.min(100, currentPercent / elapsedFraction);
128
- }
129
- function deriveAdvice(current, projected) {
130
- if (current === null && projected === null)
131
- return 'unknown';
132
- if (current !== null && current >= 100)
133
- return 'over-budget';
134
- if (projected !== null && projected >= 100)
135
- return 'over-budget';
136
- if (projected !== null && projected >= 80)
137
- return 'at-risk';
138
- if (current !== null && current >= 80)
139
- return 'at-risk';
140
- return 'on-track';
141
- }
142
- function forecastWindowStartMs(fiveHour, nowMs) {
143
- if (fiveHour) {
144
- const reset = Date.parse(fiveHour.reset_at);
145
- if (Number.isFinite(reset))
146
- return reset - SESSION_DURATION_MS;
147
- }
148
- return nowMs - SESSION_DURATION_MS;
149
- }
150
- // --------------------------------------------------------------------------
151
- // OAuth token loading. Copied verbatim from packages/cli/src/commands/budget.ts
152
- // (extracting to a shared location would pull token I/O into @relayburn/ledger,
153
- // which has no transport deps today — punting that refactor to a follow-up).
154
- // --------------------------------------------------------------------------
155
- export async function loadOauthToken() {
156
- const env = process.env['CLAUDE_CODE_OAUTH_TOKEN'];
157
- if (env && env.length > 0)
158
- return env;
159
- const fromFile = await readCredentialsFile();
160
- if (fromFile)
161
- return fromFile;
162
- if (process.platform === 'darwin') {
163
- const fromKeychain = await readMacOsKeychain();
164
- if (fromKeychain)
165
- return fromKeychain;
166
- }
167
- return null;
168
- }
169
- async function readCredentialsFile() {
170
- const candidates = [
171
- path.join(homedir(), '.claude', '.credentials.json'),
172
- path.join(homedir(), '.claude', 'credentials.json'),
173
- ];
174
- for (const p of candidates) {
175
- try {
176
- const raw = await readFile(p, 'utf8');
177
- const parsed = JSON.parse(raw);
178
- const token = extractTokenFromCredentials(parsed);
179
- if (token)
180
- return token;
181
- }
182
- catch {
183
- // fall through to next candidate
184
- }
185
- }
186
- return null;
187
- }
188
- function extractTokenFromCredentials(parsed) {
189
- if (!parsed || typeof parsed !== 'object')
190
- return null;
191
- const obj = parsed;
192
- const oauth = obj['claudeAiOauth'];
193
- if (oauth && typeof oauth === 'object') {
194
- const access = oauth['accessToken'];
195
- if (typeof access === 'string' && access.length > 0)
196
- return access;
197
- }
198
- const direct = obj['accessToken'];
199
- if (typeof direct === 'string' && direct.length > 0)
200
- return direct;
201
- return null;
202
- }
203
- function readMacOsKeychain() {
204
- return new Promise((resolve) => {
205
- const child = spawn('security', ['find-generic-password', '-s', 'Claude Code-credentials', '-w'], { stdio: ['ignore', 'pipe', 'ignore'] });
206
- let out = '';
207
- child.stdout.on('data', (chunk) => {
208
- out += chunk.toString('utf8');
209
- });
210
- child.on('error', () => resolve(null));
211
- child.on('exit', (code) => {
212
- if (code !== 0)
213
- return resolve(null);
214
- const trimmed = out.trim();
215
- if (!trimmed)
216
- return resolve(null);
217
- try {
218
- const parsed = JSON.parse(trimmed);
219
- const fromJson = extractTokenFromCredentials(parsed);
220
- if (fromJson)
221
- return resolve(fromJson);
222
- }
223
- catch {
224
- // keychain entry is the bare token, not JSON
225
- }
226
- resolve(trimmed);
227
- });
228
- });
229
- }
230
- async function fetchUsageFromApi(token) {
231
- const res = await fetch(USAGE_ENDPOINT, {
232
- headers: {
233
- Authorization: `Bearer ${token}`,
234
- 'anthropic-beta': ANTHROPIC_OAUTH_BETA,
235
- Accept: 'application/json',
236
- },
237
- });
238
- if (!res.ok) {
239
- throw new Error(`usage endpoint ${res.status}`);
240
- }
241
- return (await res.json());
242
- }
243
- //# sourceMappingURL=current-block.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"current-block.js","sourceRoot":"","sources":["../../src/tools/current-block.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=current-block.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"current-block.test.d.ts","sourceRoot":"","sources":["../../src/tools/current-block.test.ts"],"names":[],"mappings":""}
@@ -1,119 +0,0 @@
1
- import { strict as assert } from 'node:assert';
2
- import { describe, it } from 'node:test';
3
- import { createCurrentBlockTool } from './current-block.js';
4
- function turn(usage = {}, ts = '2026-04-24T10:00:00.000Z') {
5
- return {
6
- v: 1,
7
- source: 'claude-code',
8
- sessionId: 's1',
9
- messageId: 'm1',
10
- turnIndex: 0,
11
- ts,
12
- model: 'claude-sonnet-4-5',
13
- usage: {
14
- input: 0,
15
- output: 0,
16
- reasoning: 0,
17
- cacheRead: 0,
18
- cacheCreate5m: 0,
19
- cacheCreate1h: 0,
20
- ...usage,
21
- },
22
- toolCalls: [],
23
- enrichment: {},
24
- };
25
- }
26
- describe('createCurrentBlockTool', () => {
27
- // 2026-04-24 12:00 UTC = midpoint of a 5h window starting at 10:00 with reset at 15:00
28
- const NOW = new Date('2026-04-24T12:00:00.000Z');
29
- const RESET_AT = '2026-04-24T15:00:00.000Z'; // 3 hours away
30
- it('combines OAuth percent_used with locally-derived burn rate', async () => {
31
- // 60k tokens consumed in 2h elapsed → 500 tok/min → 5h projection = 150_000.
32
- // OAuth says 20% used at the 2h mark of a 5h window, projecting to 50% at
33
- // reset → on-track on both axes.
34
- const tool = createCurrentBlockTool({
35
- now: () => NOW,
36
- loadOauthToken: async () => 'tok',
37
- fetchUsage: async () => ({ five_hour: { percent_used: 20, reset_at: RESET_AT } }),
38
- queryTurns: async () => [turn({ input: 60_000 })],
39
- });
40
- const result = (await tool.handler({}));
41
- assert.equal(result.percentUsed, 20);
42
- assert.equal(result.burnRateTokensPerMin, 500);
43
- assert.equal(result.projectedBlockTotal, 150_000);
44
- assert.equal(result.minutesToReset, 180);
45
- assert.equal(result.advice, 'on-track');
46
- });
47
- it('flags at-risk when projected reaches 80%+ at reset', async () => {
48
- // 40% used at 1h elapsed of a 5h window → projects to 200% at reset.
49
- const now = new Date('2026-04-24T11:00:00.000Z');
50
- const tool = createCurrentBlockTool({
51
- now: () => now,
52
- loadOauthToken: async () => 'tok',
53
- fetchUsage: async () => ({ five_hour: { percent_used: 40, reset_at: RESET_AT } }),
54
- queryTurns: async () => [],
55
- });
56
- const result = (await tool.handler({}));
57
- assert.equal(result.advice, 'over-budget');
58
- });
59
- it('flags over-budget when current percent already >= 100', async () => {
60
- const tool = createCurrentBlockTool({
61
- now: () => NOW,
62
- loadOauthToken: async () => 'tok',
63
- fetchUsage: async () => ({ five_hour: { percent_used: 100, reset_at: RESET_AT } }),
64
- queryTurns: async () => [],
65
- });
66
- const result = (await tool.handler({}));
67
- assert.equal(result.advice, 'over-budget');
68
- });
69
- it('returns null percentUsed and a note when no OAuth token is available', async () => {
70
- const tool = createCurrentBlockTool({
71
- now: () => NOW,
72
- loadOauthToken: async () => null,
73
- fetchUsage: async () => {
74
- throw new Error('should not be called');
75
- },
76
- queryTurns: async () => [turn({ input: 30_000 })],
77
- });
78
- const result = (await tool.handler({}));
79
- assert.equal(result.percentUsed, null);
80
- assert.match(result.note ?? '', /no Claude OAuth token/);
81
- // Local forecast still flows even without OAuth — that's the entire
82
- // point of the dual-source design.
83
- assert.ok(result.burnRateTokensPerMin !== null);
84
- });
85
- it('keeps a local forecast when the OAuth fetch errors', async () => {
86
- const tool = createCurrentBlockTool({
87
- now: () => NOW,
88
- loadOauthToken: async () => 'tok',
89
- fetchUsage: async () => {
90
- throw new Error('502');
91
- },
92
- queryTurns: async () => [turn({ input: 30_000 })],
93
- });
94
- const result = (await tool.handler({}));
95
- assert.equal(result.percentUsed, null);
96
- assert.match(result.note ?? '', /oauth usage unavailable/);
97
- assert.notEqual(result.burnRateTokensPerMin, null);
98
- });
99
- it('preserves low percent_used values as-is on the 0..100 scale (regression: Devin review on #67)', async () => {
100
- // 1% used early in the window must stay 1%, not get inflated to 100%
101
- // by an over-eager 0..1 normalization heuristic.
102
- const tool = createCurrentBlockTool({
103
- now: () => NOW,
104
- loadOauthToken: async () => 'tok',
105
- fetchUsage: async () => ({ five_hour: { percent_used: 1, reset_at: RESET_AT } }),
106
- queryTurns: async () => [],
107
- });
108
- const result = (await tool.handler({}));
109
- assert.equal(result.percentUsed, 1);
110
- assert.equal(result.advice, 'on-track');
111
- });
112
- it('declares its tool surface (name, description, schema)', () => {
113
- const tool = createCurrentBlockTool({});
114
- assert.equal(tool.name, 'burn__currentBlock');
115
- assert.ok(tool.description.length > 0);
116
- assert.equal(tool.inputSchema.type, 'object');
117
- });
118
- });
119
- //# sourceMappingURL=current-block.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"current-block.test.js","sourceRoot":"","sources":["../../src/tools/current-block.test.ts"],"names":[],"mappings":"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"}