@ai-dossier/cli 0.51.0 → 0.54.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/README.md +73 -6
- package/dist/batch-suite-runner.d.ts +30 -6
- package/dist/batch-suite-runner.d.ts.map +1 -1
- package/dist/batch-suite-runner.js +86 -25
- package/dist/batch-suite-runner.js.map +1 -1
- package/dist/capability.d.ts +8 -0
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +16 -1
- package/dist/capability.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/classify.d.ts.map +1 -1
- package/dist/commands/classify.js +8 -2
- package/dist/commands/classify.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +10 -1
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/sched.d.ts.map +1 -1
- package/dist/commands/sched.js +35 -0
- package/dist/commands/sched.js.map +1 -1
- package/dist/commands/usage.d.ts +84 -0
- package/dist/commands/usage.d.ts.map +1 -0
- package/dist/commands/usage.js +395 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/prescreen.d.ts +48 -5
- package/dist/prescreen.d.ts.map +1 -1
- package/dist/prescreen.js +195 -6
- package/dist/prescreen.js.map +1 -1
- package/dist/usage/collect-claude.d.ts +47 -0
- package/dist/usage/collect-claude.d.ts.map +1 -0
- package/dist/usage/collect-claude.js +237 -0
- package/dist/usage/collect-claude.js.map +1 -0
- package/dist/usage/collect-dispatch.d.ts +73 -0
- package/dist/usage/collect-dispatch.d.ts.map +1 -0
- package/dist/usage/collect-dispatch.js +297 -0
- package/dist/usage/collect-dispatch.js.map +1 -0
- package/dist/usage/collect-opencode.d.ts +74 -0
- package/dist/usage/collect-opencode.d.ts.map +1 -0
- package/dist/usage/collect-opencode.js +198 -0
- package/dist/usage/collect-opencode.js.map +1 -0
- package/dist/usage/host-session.d.ts +63 -0
- package/dist/usage/host-session.d.ts.map +1 -0
- package/dist/usage/host-session.js +325 -0
- package/dist/usage/host-session.js.map +1 -0
- package/dist/usage/ledger.d.ts +87 -0
- package/dist/usage/ledger.d.ts.map +1 -0
- package/dist/usage/ledger.js +268 -0
- package/dist/usage/ledger.js.map +1 -0
- package/dist/usage/types.d.ts +80 -0
- package/dist/usage/types.d.ts.map +1 -0
- package/dist/usage/types.js +11 -0
- package/dist/usage/types.js.map +1 -0
- package/dist/usage/util.d.ts +36 -0
- package/dist/usage/util.d.ts.map +1 -0
- package/dist/usage/util.js +158 -0
- package/dist/usage/util.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/commands/usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `ai-dossier usage` — cross-provider token ledger + quota-window RCA (#769).
|
|
4
|
+
*
|
|
5
|
+
* ai-dossier usage window [--last 5h] [--provider anthropic] what ate my window?
|
|
6
|
+
* ai-dossier usage --batch <id> | --issue <n> real model per member
|
|
7
|
+
* ai-dossier usage watch [--last 1h] [--interval 30s] live re-render
|
|
8
|
+
*
|
|
9
|
+
* Every view reads the source stores on demand (Claude Code transcripts,
|
|
10
|
+
* opencode.db, sched dispatch logs/events, runs.jsonl) — read-only and
|
|
11
|
+
* idempotent; nothing is written anywhere.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.parseDurationSpec = parseDurationSpec;
|
|
48
|
+
exports.parseSince = parseSince;
|
|
49
|
+
exports.formatTokens = formatTokens;
|
|
50
|
+
exports.buildWindowReport = buildWindowReport;
|
|
51
|
+
exports.renderWindowReport = renderWindowReport;
|
|
52
|
+
exports.buildScopeReport = buildScopeReport;
|
|
53
|
+
exports.renderScopeReport = renderScopeReport;
|
|
54
|
+
exports.registerUsageCommand = registerUsageCommand;
|
|
55
|
+
const os = __importStar(require("node:os"));
|
|
56
|
+
const cost_format_1 = require("../cost-format");
|
|
57
|
+
const helpers_1 = require("../helpers");
|
|
58
|
+
const table_1 = require("../table");
|
|
59
|
+
const ledger_1 = require("../usage/ledger");
|
|
60
|
+
const MS = {
|
|
61
|
+
s: 1000,
|
|
62
|
+
m: 60_000,
|
|
63
|
+
h: 3_600_000,
|
|
64
|
+
d: 86_400_000,
|
|
65
|
+
w: 7 * 86_400_000,
|
|
66
|
+
};
|
|
67
|
+
/** `90s` / `30m` / `5h` / `7d` / `2w` → milliseconds, or null when malformed. */
|
|
68
|
+
function parseDurationSpec(spec) {
|
|
69
|
+
const match = spec.trim().match(/^(\d+(?:\.\d+)?)\s*([smhdw])$/i);
|
|
70
|
+
if (!match)
|
|
71
|
+
return null;
|
|
72
|
+
const ms = Number.parseFloat(match[1]) * MS[match[2].toLowerCase()];
|
|
73
|
+
return ms > 0 ? ms : null;
|
|
74
|
+
}
|
|
75
|
+
/** `--since` accepts a duration back from now (`30d`) or an absolute ISO date/time. */
|
|
76
|
+
function parseSince(spec, nowMs) {
|
|
77
|
+
const duration = parseDurationSpec(spec);
|
|
78
|
+
if (duration !== null)
|
|
79
|
+
return nowMs - duration;
|
|
80
|
+
const abs = Date.parse(spec);
|
|
81
|
+
return Number.isNaN(abs) ? null : abs;
|
|
82
|
+
}
|
|
83
|
+
/** Compact token count: 950 · 12.3k · 4.5M · 1.2B. */
|
|
84
|
+
function formatTokens(n) {
|
|
85
|
+
if (n < 1000)
|
|
86
|
+
return String(n);
|
|
87
|
+
if (n < 1e6)
|
|
88
|
+
return `${(n / 1e3).toFixed(1)}k`;
|
|
89
|
+
if (n < 1e9)
|
|
90
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
91
|
+
return `${(n / 1e9).toFixed(2)}B`;
|
|
92
|
+
}
|
|
93
|
+
function pct(part, whole) {
|
|
94
|
+
return whole === 0 ? '-' : `${((part / whole) * 100).toFixed(1)}%`;
|
|
95
|
+
}
|
|
96
|
+
function shortSession(id) {
|
|
97
|
+
// Claude subagent ids are `<uuid>/<agentId>` — keep both halves recognisable.
|
|
98
|
+
const [head, sub] = id.split('/');
|
|
99
|
+
const h = head.length > 12 ? head.slice(0, 12) : head;
|
|
100
|
+
return sub ? `${h}…/${sub.slice(0, 10)}` : h;
|
|
101
|
+
}
|
|
102
|
+
function clip(text, max) {
|
|
103
|
+
if (!text)
|
|
104
|
+
return '-';
|
|
105
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
106
|
+
}
|
|
107
|
+
function filterRows(rows, f) {
|
|
108
|
+
const provider = f.provider?.toLowerCase();
|
|
109
|
+
const sources = f.source
|
|
110
|
+
?.split(',')
|
|
111
|
+
.map((s) => s.trim())
|
|
112
|
+
.filter(Boolean);
|
|
113
|
+
return rows.filter((r) => (!provider || r.provider.toLowerCase() === provider) &&
|
|
114
|
+
(!sources || sources.length === 0 || sources.includes(r.source)));
|
|
115
|
+
}
|
|
116
|
+
function tokenCells(t) {
|
|
117
|
+
return [
|
|
118
|
+
String(t.messages),
|
|
119
|
+
formatTokens(t.input),
|
|
120
|
+
formatTokens(t.output),
|
|
121
|
+
formatTokens(t.reasoning),
|
|
122
|
+
formatTokens(t.cache_read),
|
|
123
|
+
formatTokens(t.cache_write),
|
|
124
|
+
formatTokens(t.total),
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
const TOKEN_HEADERS = ['Msgs', 'In', 'Out', 'Reason', 'Cache-R', 'Cache-W', 'Total'];
|
|
128
|
+
const TOKEN_ALIGN = Array(TOKEN_HEADERS.length).fill('right');
|
|
129
|
+
/** Build the quota-window RCA report (pure over the collected ledger). */
|
|
130
|
+
function buildWindowReport(opts, deps = {}) {
|
|
131
|
+
const nowMs = deps.nowMs ?? Date.now();
|
|
132
|
+
const lastMs = parseDurationSpec(opts.last ?? '5h');
|
|
133
|
+
if (lastMs === null)
|
|
134
|
+
(0, helpers_1.fail)([`--last must be a duration like 5h, 30m, 7d (got '${opts.last}')`]);
|
|
135
|
+
const untilMs = opts.until ? Date.parse(opts.until) : nowMs;
|
|
136
|
+
if (Number.isNaN(untilMs))
|
|
137
|
+
(0, helpers_1.fail)([`--until must be an ISO date/time (got '${opts.until}')`]);
|
|
138
|
+
const sinceMs = untilMs - lastMs;
|
|
139
|
+
const limitWindowMs = parseDurationSpec(opts.limitWindow ?? '5h');
|
|
140
|
+
if (limitWindowMs === null)
|
|
141
|
+
(0, helpers_1.fail)([`--limit-window must be a duration (got '${opts.limitWindow}')`]);
|
|
142
|
+
const top = Number.parseInt(opts.top ?? '10', 10);
|
|
143
|
+
// Collect back far enough that a limit hit early in the window still has
|
|
144
|
+
// its full preceding window of consumers.
|
|
145
|
+
const ledger = (0, ledger_1.collectLedger)({
|
|
146
|
+
sinceMs: sinceMs - limitWindowMs,
|
|
147
|
+
untilMs,
|
|
148
|
+
paths: deps.paths ?? (0, ledger_1.defaultLedgerPaths)(),
|
|
149
|
+
host: deps.host,
|
|
150
|
+
openOpenCode: deps.openOpenCode,
|
|
151
|
+
});
|
|
152
|
+
const allRows = filterRows(ledger.rows, opts);
|
|
153
|
+
const rows = allRows.filter((r) => Date.parse(r.ts) >= sinceMs);
|
|
154
|
+
const limits = (0, ledger_1.collapseLimitEvents)(ledger.limits.filter((l) => {
|
|
155
|
+
const t = Date.parse(l.ts);
|
|
156
|
+
if (t < sinceMs || t >= untilMs)
|
|
157
|
+
return false;
|
|
158
|
+
return !opts.provider || l.provider === null || l.provider === opts.provider.toLowerCase();
|
|
159
|
+
}));
|
|
160
|
+
const byModel = (0, ledger_1.groupRows)(rows, (r) => `${r.provider}\u0000${r.model ?? ''}\u0000${r.source}`).map((g) => {
|
|
161
|
+
const [provider, model, source] = g.key.split('\u0000');
|
|
162
|
+
return { ...g, provider, model: model || null, source };
|
|
163
|
+
});
|
|
164
|
+
const sessions = (0, ledger_1.summarizeSessions)(rows)
|
|
165
|
+
.slice(0, top)
|
|
166
|
+
.map((s) => ({ ...s, dossier_runs: ledger.dossierRuns.get(s.session_id) ?? 0 }));
|
|
167
|
+
const totals = (0, ledger_1.totalsOf)(rows);
|
|
168
|
+
return {
|
|
169
|
+
since: new Date(sinceMs).toISOString(),
|
|
170
|
+
until: new Date(untilMs).toISOString(),
|
|
171
|
+
host: deps.host ?? os.hostname(),
|
|
172
|
+
collectors: ledger.collectors,
|
|
173
|
+
model_coverage: (0, ledger_1.modelCoverage)(rows),
|
|
174
|
+
totals,
|
|
175
|
+
by_model: byModel,
|
|
176
|
+
by_project_issue: (0, ledger_1.groupRows)(rows, (r) => `${r.project ?? '-'} ${r.issue !== null ? `#${r.issue}` : '(no issue)'}`),
|
|
177
|
+
top_sessions: sessions,
|
|
178
|
+
hourly: (0, ledger_1.hourlyBurn)(rows, sinceMs, untilMs),
|
|
179
|
+
burn_per_hour: totals.total / (lastMs / MS.h),
|
|
180
|
+
limits: (0, ledger_1.limitContexts)(limits, allRows, limitWindowMs),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function renderWindowReport(report) {
|
|
184
|
+
const out = [];
|
|
185
|
+
const t = report.totals;
|
|
186
|
+
out.push(`Usage window ${report.since} → ${report.until} [host ${report.host}]`);
|
|
187
|
+
out.push(`Collectors: ${report.collectors.map((c) => `${c.source}=${c.status === 'ok' ? c.rows : c.status}`).join(' ')}`);
|
|
188
|
+
for (const c of report.collectors) {
|
|
189
|
+
if (c.status !== 'ok')
|
|
190
|
+
out.push(` ⚠ ${c.source}: ${c.status}${c.detail ? ` — ${c.detail}` : ''}`);
|
|
191
|
+
}
|
|
192
|
+
out.push(`Total: ${formatTokens(t.total)} tokens in ${t.messages} messages · ${formatTokens(Math.round(report.burn_per_hour))}/h · model attributed: ${pct(report.model_coverage, 1)}${t.cost_usd ? ` · recorded cost ${(0, cost_format_1.formatCost)(t.cost_usd)}` : ''}`);
|
|
193
|
+
if (t.messages === 0) {
|
|
194
|
+
out.push('\nNo usage recorded in this window.');
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
out.push('\nBy model × source:');
|
|
198
|
+
out.push((0, table_1.renderTable)(['Provider', 'Model', 'Source', ...TOKEN_HEADERS, 'Share'], report.by_model.map((g) => [
|
|
199
|
+
g.provider,
|
|
200
|
+
g.model ?? '(unknown)',
|
|
201
|
+
g.source,
|
|
202
|
+
...tokenCells(g),
|
|
203
|
+
pct(g.total, t.total),
|
|
204
|
+
]), { align: ['left', 'left', 'left', ...TOKEN_ALIGN, 'right'], separator: true }));
|
|
205
|
+
out.push('\nBy project × issue:');
|
|
206
|
+
out.push((0, table_1.renderTable)(['Project / issue', 'Msgs', 'Total', 'Share'], report.by_project_issue.map((g) => [
|
|
207
|
+
g.key,
|
|
208
|
+
String(g.messages),
|
|
209
|
+
formatTokens(g.total),
|
|
210
|
+
pct(g.total, t.total),
|
|
211
|
+
]), { align: ['left', 'right', 'right', 'right'], separator: true }));
|
|
212
|
+
out.push('\nTop sessions:');
|
|
213
|
+
out.push(renderSessionTable(report.top_sessions, t.total));
|
|
214
|
+
out.push('\nBurn by hour:');
|
|
215
|
+
out.push((0, table_1.renderTable)(['Hour (UTC)', 'Msgs', 'Total'], report.hourly.map((h) => [
|
|
216
|
+
`${h.hour.slice(0, 13).replace('T', ' ')}h`,
|
|
217
|
+
String(h.messages),
|
|
218
|
+
formatTokens(h.total),
|
|
219
|
+
]), { align: ['left', 'right', 'right'], separator: true }));
|
|
220
|
+
}
|
|
221
|
+
if (report.limits.length > 0) {
|
|
222
|
+
out.push('\nLimit events:');
|
|
223
|
+
for (const ctx of report.limits) {
|
|
224
|
+
const e = ctx.event;
|
|
225
|
+
out.push(` ⛔ ${e.ts} ${e.source}${e.provider ? `/${e.provider}` : ''}${e.status !== null ? ` ${e.status}` : ''}${e.unit ? ` ${e.unit}` : ''} — ${e.detail}${(e.count ?? 1) > 1 ? ` (×${e.count}, last ${e.last_ts})` : ''}`);
|
|
226
|
+
if (ctx.top.length === 0) {
|
|
227
|
+
out.push(' (no recorded consumers in the preceding window)');
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
out.push(` top consumers in the preceding ${Math.round(ctx.window_ms / MS.h)}h:`);
|
|
231
|
+
for (const s of ctx.top) {
|
|
232
|
+
out.push(` ${formatTokens(s.total).padStart(7)} ${shortSession(s.session_id)} ${s.source} ${s.models.join(',') || '(unknown)'} ${s.project ?? '-'}${s.issue !== null ? ` #${s.issue}` : ''}${s.title ? ` "${clip(s.title, 50)}"` : ''}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
out.push('\nLimit events: none recorded in this window.');
|
|
239
|
+
}
|
|
240
|
+
return out.join('\n');
|
|
241
|
+
}
|
|
242
|
+
function renderSessionTable(sessions, whole) {
|
|
243
|
+
return (0, table_1.renderTable)([
|
|
244
|
+
'Session',
|
|
245
|
+
'Source',
|
|
246
|
+
'Model',
|
|
247
|
+
'Project',
|
|
248
|
+
'Issue',
|
|
249
|
+
'Unit',
|
|
250
|
+
'Title',
|
|
251
|
+
...TOKEN_HEADERS,
|
|
252
|
+
'Share',
|
|
253
|
+
'Runs',
|
|
254
|
+
], sessions.map((s) => [
|
|
255
|
+
shortSession(s.session_id),
|
|
256
|
+
s.source,
|
|
257
|
+
s.models.join(',') || '(unknown)',
|
|
258
|
+
s.project ?? '-',
|
|
259
|
+
s.issue !== null ? `#${s.issue}` : '-',
|
|
260
|
+
s.unit ?? '-',
|
|
261
|
+
clip(s.title, 40),
|
|
262
|
+
...tokenCells(s),
|
|
263
|
+
pct(s.total, whole),
|
|
264
|
+
String(s.dossier_runs ?? 0),
|
|
265
|
+
]), {
|
|
266
|
+
align: [
|
|
267
|
+
'left',
|
|
268
|
+
'left',
|
|
269
|
+
'left',
|
|
270
|
+
'left',
|
|
271
|
+
'right',
|
|
272
|
+
'left',
|
|
273
|
+
'left',
|
|
274
|
+
...TOKEN_ALIGN,
|
|
275
|
+
'right',
|
|
276
|
+
'right',
|
|
277
|
+
],
|
|
278
|
+
separator: true,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function buildScopeReport(opts, deps = {}) {
|
|
282
|
+
const nowMs = deps.nowMs ?? Date.now();
|
|
283
|
+
const sinceMs = parseSince(opts.since ?? '30d', nowMs);
|
|
284
|
+
if (sinceMs === null)
|
|
285
|
+
(0, helpers_1.fail)([`--since must be a duration (30d) or ISO date (got '${opts.since}')`]);
|
|
286
|
+
const issue = opts.issue !== undefined ? Number.parseInt(opts.issue, 10) : null;
|
|
287
|
+
if (opts.issue !== undefined && (issue === null || Number.isNaN(issue))) {
|
|
288
|
+
(0, helpers_1.fail)([`--issue must be an issue number (got '${opts.issue}')`]);
|
|
289
|
+
}
|
|
290
|
+
const ledger = (0, ledger_1.collectLedger)({
|
|
291
|
+
sinceMs,
|
|
292
|
+
untilMs: nowMs,
|
|
293
|
+
paths: deps.paths ?? (0, ledger_1.defaultLedgerPaths)(),
|
|
294
|
+
host: deps.host,
|
|
295
|
+
openOpenCode: deps.openOpenCode,
|
|
296
|
+
});
|
|
297
|
+
const rows = filterRows(ledger.rows, opts).filter((r) => (!opts.batch || r.batch === opts.batch) && (issue === null || r.issue === issue));
|
|
298
|
+
return {
|
|
299
|
+
scope: { batch: opts.batch ?? null, issue },
|
|
300
|
+
since: new Date(sinceMs).toISOString(),
|
|
301
|
+
until: new Date(nowMs).toISOString(),
|
|
302
|
+
collectors: ledger.collectors,
|
|
303
|
+
model_coverage: (0, ledger_1.modelCoverage)(rows),
|
|
304
|
+
totals: (0, ledger_1.totalsOf)(rows),
|
|
305
|
+
by_model: (0, ledger_1.groupRows)(rows, (r) => r.model ?? '(unknown)'),
|
|
306
|
+
sessions: (0, ledger_1.summarizeSessions)(rows),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function renderScopeReport(report) {
|
|
310
|
+
const label = report.scope.batch
|
|
311
|
+
? `batch ${report.scope.batch}${report.scope.issue !== null ? ` issue #${report.scope.issue}` : ''}`
|
|
312
|
+
: `issue #${report.scope.issue}`;
|
|
313
|
+
const out = [`Usage for ${label} (${report.since} → ${report.until})`];
|
|
314
|
+
for (const c of report.collectors) {
|
|
315
|
+
if (c.status !== 'ok')
|
|
316
|
+
out.push(` ⚠ ${c.source}: ${c.status}${c.detail ? ` — ${c.detail}` : ''}`);
|
|
317
|
+
}
|
|
318
|
+
if (report.sessions.length === 0) {
|
|
319
|
+
out.push('No sessions attributed to it. Batch/dispatch attribution comes from sched dispatch logs; interactive sessions are matched by branch/worktree name.');
|
|
320
|
+
return out.join('\n');
|
|
321
|
+
}
|
|
322
|
+
const t = report.totals;
|
|
323
|
+
out.push(`Total: ${formatTokens(t.total)} tokens · model attributed: ${pct(report.model_coverage, 1)}${t.cost_usd ? ` · recorded cost ${(0, cost_format_1.formatCost)(t.cost_usd)}` : ''}`);
|
|
324
|
+
out.push('\nSessions:');
|
|
325
|
+
out.push(renderSessionTable(report.sessions, t.total));
|
|
326
|
+
out.push('\nBy model:');
|
|
327
|
+
out.push((0, table_1.renderTable)(['Model', ...TOKEN_HEADERS, 'Share'], report.by_model.map((g) => [g.key, ...tokenCells(g), pct(g.total, t.total)]), { align: ['left', ...TOKEN_ALIGN, 'right'], separator: true }));
|
|
328
|
+
return out.join('\n');
|
|
329
|
+
}
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
// registration
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
function registerUsageCommand(program) {
|
|
334
|
+
const cmd = program
|
|
335
|
+
.command('usage')
|
|
336
|
+
.description('Cross-provider token ledger (Claude Code, opencode, sched dispatches): quota-window RCA, per-batch/issue model attribution')
|
|
337
|
+
.option('--batch <id>', "Show a sched batch's sessions with the real model per member")
|
|
338
|
+
.option('--issue <n>', 'Show every session attributed to an issue')
|
|
339
|
+
.option('--since <when>', 'How far back --batch/--issue look: a duration (30d) or ISO date', '30d')
|
|
340
|
+
.option('--provider <name>', 'Only this provider (anthropic, openai, zai, …)')
|
|
341
|
+
.option('--source <list>', 'Only these sources: claude-code,opencode')
|
|
342
|
+
.option('--json', 'Output JSON')
|
|
343
|
+
.action((opts) => {
|
|
344
|
+
if (!opts.batch && opts.issue === undefined) {
|
|
345
|
+
cmd.outputHelp();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const report = buildScopeReport(opts);
|
|
349
|
+
console.log(opts.json ? JSON.stringify(report, null, 2) : renderScopeReport(report));
|
|
350
|
+
});
|
|
351
|
+
cmd
|
|
352
|
+
.command('window')
|
|
353
|
+
.description('Quota-window RCA: tokens by model × source × project × issue, top sessions, burn rate, limit events')
|
|
354
|
+
.option('--last <duration>', 'Window length ending now (or at --until)', '5h')
|
|
355
|
+
.option('--until <iso>', 'Window end (default: now)')
|
|
356
|
+
.option('--provider <name>', 'Only this provider (anthropic, openai, zai, …)')
|
|
357
|
+
.option('--source <list>', 'Only these sources: claude-code,opencode')
|
|
358
|
+
.option('--top <n>', 'How many top sessions to list', '10')
|
|
359
|
+
.option('--limit-window <duration>', 'Look-back used to explain each limit event', '5h')
|
|
360
|
+
.option('--json', 'Output JSON')
|
|
361
|
+
.action((_opts, command) => {
|
|
362
|
+
// optsWithGlobals: without positional options on the root program,
|
|
363
|
+
// Commander hands `--json`/`--provider`/`--source` given after `window`
|
|
364
|
+
// to the parent `usage` command (which defines the same flags).
|
|
365
|
+
const opts = command.optsWithGlobals();
|
|
366
|
+
const report = buildWindowReport(opts);
|
|
367
|
+
console.log(opts.json ? JSON.stringify(report, null, 2) : renderWindowReport(report));
|
|
368
|
+
});
|
|
369
|
+
cmd
|
|
370
|
+
.command('watch')
|
|
371
|
+
.description('Live view: re-render the window report on an interval (Ctrl-C to stop)')
|
|
372
|
+
.option('--last <duration>', 'Window length', '1h')
|
|
373
|
+
.option('--provider <name>', 'Only this provider')
|
|
374
|
+
.option('--source <list>', 'Only these sources: claude-code,opencode')
|
|
375
|
+
.option('--top <n>', 'How many top sessions to list', '10')
|
|
376
|
+
.option('--interval <duration>', 'Refresh interval', '30s')
|
|
377
|
+
.option('--iterations <n>', 'Stop after this many renders (default: until interrupted)')
|
|
378
|
+
.action(async (_opts, command) => {
|
|
379
|
+
const opts = command.optsWithGlobals();
|
|
380
|
+
const intervalMs = parseDurationSpec(opts.interval ?? '30s');
|
|
381
|
+
if (intervalMs === null)
|
|
382
|
+
(0, helpers_1.fail)([`--interval must be a duration (got '${opts.interval}')`]);
|
|
383
|
+
const max = opts.iterations ? Number.parseInt(opts.iterations, 10) : Number.POSITIVE_INFINITY;
|
|
384
|
+
for (let i = 0; i < max; i++) {
|
|
385
|
+
const report = buildWindowReport(opts);
|
|
386
|
+
if (process.stdout.isTTY)
|
|
387
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
388
|
+
console.log(renderWindowReport(report));
|
|
389
|
+
console.log(`\n(refreshing every ${opts.interval ?? '30s'} — Ctrl-C to stop)`);
|
|
390
|
+
if (i + 1 < max)
|
|
391
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/commands/usage.ts"],"names":[],"mappings":"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"}
|
package/dist/prescreen.d.ts
CHANGED
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
* a plan artifact, rule 10 confidence) falls through to the classifier's own bounded
|
|
13
13
|
* mechanical-tier pass, which is the intended safety net — not a gap this module needs to close.
|
|
14
14
|
*
|
|
15
|
+
* v2 (#772, `PRESCREEN_SCHEMA`): two outputs. `verdict: full` only for the EXCLUDING checks
|
|
16
|
+
* (hard-block label, open dependency, plan:v1 path floor, >8 predicted files); any finding —
|
|
17
|
+
* a text-floor keyword hit included — sets `review: full`. A text-floor hit alone is a batchable
|
|
18
|
+
* `candidate` reviewed at full depth (#770 Option A), and the text floor scans the change
|
|
19
|
+
* surface only (`floorScanText`: reference sections/lines and provenance clauses removed).
|
|
20
|
+
*
|
|
15
21
|
* Pure and dependency-free (no `gh`, network, or fs), same discipline as `plan-artifact.ts` and
|
|
16
22
|
* `runstate.ts` — unit-testable directly. Subprocess access (fetching the issue, resolving
|
|
17
23
|
* dependency state, filtering by submitted set) lives in the command layer (`commands/classify.ts`).
|
|
@@ -20,7 +26,7 @@
|
|
|
20
26
|
export interface TextFloorPattern {
|
|
21
27
|
/** Reported in the reason; also the RFC-0001 E.2 rule it approximates. */
|
|
22
28
|
name: string;
|
|
23
|
-
/** Matched case-insensitively against title + body + label names
|
|
29
|
+
/** Matched case-insensitively against {@link floorScanText} (title + reference-stripped body + label names). Returns the matched keyword, or null. */
|
|
24
30
|
match: (text: string) => string | null;
|
|
25
31
|
}
|
|
26
32
|
export declare const TEXT_FLOOR_PATTERNS: readonly TextFloorPattern[];
|
|
@@ -39,7 +45,10 @@ export declare const TEXT_FLOOR_PATTERNS: readonly TextFloorPattern[];
|
|
|
39
45
|
* issues are rejected by text-floor alone, including genuine risk-floor cases
|
|
40
46
|
* (#3403 `terraform`, #3901 `authorization`). That change would have gutted the
|
|
41
47
|
* deterministic rejection rate the pre-screen exists to provide, and #538's
|
|
42
|
-
* cost saving with it.
|
|
48
|
+
* cost saving with it. (#772 later made that move deliberately — but not as
|
|
49
|
+
* "advisory": a text-floor hit still costs no model call and now carries
|
|
50
|
+
* `review: full`, so the genuine risk-floor cases are reviewed at full depth
|
|
51
|
+
* inside a batch instead of being excluded from one. See `PRESCREEN_SCHEMA`.)
|
|
43
52
|
*
|
|
44
53
|
* Stripping quoted spans, by contrast, leaves all 15 fixture verdicts
|
|
45
54
|
* unchanged — the true positives name their risk surface in prose, not in
|
|
@@ -51,6 +60,22 @@ export declare const TEXT_FLOOR_PATTERNS: readonly TextFloorPattern[];
|
|
|
51
60
|
* the same line, so a lone `"` blanks nothing.
|
|
52
61
|
*/
|
|
53
62
|
export declare function stripQuotedSpans(text: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* #772: the issue body with reference material removed — the part a text-floor keyword may
|
|
65
|
+
* legitimately fire on. Removes: sections under an {@link IGNORED_SECTION_HEADING_RE} heading
|
|
66
|
+
* (fence-aware — a `#` comment inside a code block is never a heading), reference lines
|
|
67
|
+
* ({@link REFERENCE_LINE_RE}), link-only lines, and sentence-opening provenance clauses
|
|
68
|
+
* ({@link PROVENANCE_CLAUSE_RE}). Quoted spans are handled separately by {@link stripQuotedSpans}
|
|
69
|
+
* (#627). Pure; line count is preserved (dropped lines become empty) so `stripQuotedSpans`'s
|
|
70
|
+
* same-line bound behaves exactly as before.
|
|
71
|
+
*/
|
|
72
|
+
export declare function stripReferenceMaterial(body: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* The exact text the text floor scans (#772): title + section/provenance-filtered body + label
|
|
75
|
+
* names, with quoted spans blanked (#627). Exported so measurement tooling
|
|
76
|
+
* (`scripts/prescreen-backlog-measure.mjs`) and tests see precisely what the rule sees.
|
|
77
|
+
*/
|
|
78
|
+
export declare function floorScanText(title: string, body: string, labels: readonly string[]): string;
|
|
54
79
|
/** `Depends on #N` references resolved per issue; each costs a `gh` call downstream (command layer), same rationale as `MAX_ISSUE_SELECTION` (`issue-selection.ts`). */
|
|
55
80
|
export declare const MAX_DEPENDENCY_REFS = 32;
|
|
56
81
|
/**
|
|
@@ -78,15 +103,33 @@ export interface PrescreenInput {
|
|
|
78
103
|
*/
|
|
79
104
|
openDependencies?: readonly number[];
|
|
80
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Version of the `classify prescreen` JSON contract (#772). v1 (implicit, pre-#772): any finding,
|
|
108
|
+
* text-floor included, meant `verdict: full`. v2: a text-floor hit is `verdict: candidate` +
|
|
109
|
+
* `review: full`; `verdict: full` is reserved for the checks that genuinely exclude an issue from
|
|
110
|
+
* a batch (hard-block label, open dependency, plan:v1 path floor, >8 predicted files).
|
|
111
|
+
*/
|
|
112
|
+
export declare const PRESCREEN_SCHEMA = "prescreen:v2";
|
|
81
113
|
export interface PrescreenVerdict {
|
|
82
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* `full` = an excluding floor hit (hard-block label, open dependency, plan:v1 path floor,
|
|
116
|
+
* >8 predicted files) — reject before any model call. `candidate` = proceed to the bounded
|
|
117
|
+
* mechanical-tier classify pass; read `review` for how deeply it must be reviewed.
|
|
118
|
+
*/
|
|
83
119
|
verdict: 'full' | 'candidate';
|
|
120
|
+
/**
|
|
121
|
+
* Review depth the issue needs, vocabulary shared with the scheduler's per-member `review`
|
|
122
|
+
* (#771): `full` when ANY floor finding exists — a text-floor keyword hit on a `candidate`
|
|
123
|
+
* means "batchable, but reviewed at full depth" (#770 Option A), not exclusion. `light` when
|
|
124
|
+
* no check found anything.
|
|
125
|
+
*/
|
|
126
|
+
review: 'light' | 'full';
|
|
84
127
|
/** Every check's finding, in evaluation order — not just the one that decided `verdict`. */
|
|
85
128
|
reasons: PrescreenReason[];
|
|
86
129
|
}
|
|
87
130
|
/**
|
|
88
|
-
* Run every deterministic check, in order, and record every hit —
|
|
89
|
-
*
|
|
131
|
+
* Run every deterministic check, in order, and record every hit — an excluding hit decides
|
|
132
|
+
* `verdict`, any hit decides `review`, and the caller (and the rationale a consumer posts) gets the full list, matching the existing
|
|
90
133
|
* "a verdict may hit several" precedent in `issue-cycle-classifier.ds.md`.
|
|
91
134
|
*/
|
|
92
135
|
export declare function prescreenIssue(input: PrescreenInput): PrescreenVerdict;
|
package/dist/prescreen.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prescreen.d.ts","sourceRoot":"","sources":["../src/prescreen.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"prescreen.d.ts","sourceRoot":"","sources":["../src/prescreen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,6FAA6F;AAC7F,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,sJAAsJ;IACtJ,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxC;AAwBD,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EAmD1D,CAAC;AASF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AAuHD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyC3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE5F;AAED,wKAAwK;AACxK,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAKtC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAY5D;AAED,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,uGAAuG;IACvG,KAAK,EAAE,kBAAkB,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,CAAC;IAC3F,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,oGAAoG;IACpG,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAU/C,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B;;;;;OAKG;IACH,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,4FAA4F;IAC5F,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AA6BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,gBAAgB,CAgDtE"}
|