Rocko's round 2 candidate e09313aba4d155a1c5af7bfb227ec397e96c0d57444782cd0b48593102bcc684
(38 paths, base 23533625d), approved by Dewey in #1618 comment 28923 (queue rev 1757).
Packet: agents/rocko/work/queue-124/r2/.
- Schema 3g to 3h: packages/bus/src/migrations/3g-3h.sql adds an append-only
usage_records table; nothing earlier changes. usage_records is in timedTables.
- The transcript usage-source module reads token counts from Pi and Claude
Code session transcripts and follows no symlink.
- `mosaic usage` in the CLI and a read-only usage section in the Console's
Settings (one GET route; 400 on a query string).
Decision 123 go: Mos, mos-0737. Activation (3g to 3h) is a migrating run
with Jason present, in Mos's combined re-pin; landing changes nothing live.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
31 lines
2.1 KiB
JavaScript
31 lines
2.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { main } from '../src/cli.mjs';
|
|
import { fixture, io, tmp } from './helpers.mjs';
|
|
const count = { input: 11, output: 3, cacheWrite: 5, cacheRead: 7, unknownTurns: 2 };
|
|
const view = { total: count, byRun: [{ run: 'run1', ...count }], byInstance: [{ instance: 'coder', ...count }],
|
|
byModel: [{ provider: 'anthropic', model: 'fixture-model', ...count }], byProvider: [{ provider: 'anthropic', ...count }],
|
|
byAccount: [{ account: null, ...count }] };
|
|
test('REQ-LIMIT-4 mosaic usage shows each token kind and unknown turns beside every total', async t => {
|
|
const f = fixture(tmp(t), 'acme'), calls = [];
|
|
const deps = { transport: business => async (verb, args) => { calls.push({ business, verb, args }); return view; } };
|
|
const text = io(f.env); await main(['usage', '--business', 'acme'], text, deps);
|
|
for (const expected of ['input=11', 'output=3', 'cacheWrite=5', 'cacheRead=7', 'unknown=2', 'run1', 'coder', 'fixture-model', 'anthropic', '(unassigned)']) assert.ok(text.out.text.includes(expected), expected);
|
|
assert.equal((text.out.text.match(/unknown=2/g) ?? []).length, 6);
|
|
const json = io(f.env); await main(['usage', '--business', 'acme', '--json'], json, deps);
|
|
assert.deepEqual(JSON.parse(json.out.text), view);
|
|
assert.deepEqual(calls[0], { business: 'acme', verb: 'usage', args: {} });
|
|
await assert.rejects(main(['usage', '--bad'], io(f.env), deps), { exitCode: 4 });
|
|
});
|
|
|
|
test('usage is dispatched by scripts/mosaic and the shared read adapter', async () => {
|
|
const { spawnSync } = await import('node:child_process');
|
|
const { views } = await import('../../bus/src/views.mjs');
|
|
const calls = [];
|
|
const result = await views({ call: (...args) => { calls.push(args); return view; } }).usage();
|
|
assert.deepEqual(result, view); assert.deepEqual(calls, [['usage']]);
|
|
const script = new URL('../../../scripts/mosaic', import.meta.url).pathname;
|
|
const command = spawnSync(script, ['usage', '--bad'], { encoding: 'utf8', env: { PATH: process.env.PATH } });
|
|
assert.equal(command.status, 4); assert.match(command.stderr, /mosaic usage/);
|
|
});
|