Rename design r2, "Selector scopes and parser matrix". packages/business/src/selector.mjs and scripts/selector.sh carry one rule set: in a parser's scope each spelling appears once, and a second spelling must carry exactly the same value; a repeated spelling, a missing or flag-shaped value, an invalid id and unequal values refuse. The file family (--business-file/--org-file) compares paths as given. Every CLI parser that took --business now takes --org through orgSelector, and the old global --org rewrite in main() is gone, so a value another option consumes is never read as a selector. The id is checked while parsing (OrgError org-invalid, exit 3), so grants admin set no longer reads the token and proxy init no longer prompts for the key before an invalid id refuses. access gains the same local id check.
28 lines
1.5 KiB
JavaScript
28 lines
1.5 KiB
JavaScript
import { CliError } from './errors.mjs';
|
|
import { orgSelector } from './org-selector.mjs';
|
|
export const USAGE_USAGE = 'mosaic usage [--business ID] [--json] [--tester]';
|
|
export async function usageCommand(args, io, callFor) {
|
|
const parsed = { flags: new Set(), values: {} };
|
|
// --org and --business are one selector in this parser's scope (rename design r2).
|
|
const selector = orgSelector(() => new CliError(USAGE_USAGE, 4));
|
|
for (let i = 0; i < args.length; i++) {
|
|
const arg = args[i];
|
|
if ((arg === '--json' || arg === '--tester') && !parsed.flags.has(arg)) parsed.flags.add(arg);
|
|
else if (selector.owns(arg)) { selector.take(arg, args[i + 1]); i++; }
|
|
else throw new CliError(USAGE_USAGE, 4);
|
|
}
|
|
if (selector.given) parsed.values['--business'] = selector.value;
|
|
const result = await callFor(parsed)('usage', {});
|
|
if (parsed.flags.has('--json')) { io.stdout.write(JSON.stringify(result, null, 2) + '\n'); return; }
|
|
const counts = row => `input=${row.input} output=${row.output} cacheWrite=${row.cacheWrite} cacheRead=${row.cacheRead} unknown=${row.unknownTurns}`;
|
|
const lines = [`Total: ${counts(result.total)}`];
|
|
for (const group of ['byRun', 'byInstance', 'byModel', 'byProvider', 'byAccount']) {
|
|
for (const row of result[group]) {
|
|
const name = ['run', 'instance', 'provider', 'model', 'account'].filter(key => key in row)
|
|
.map(key => row[key] ?? '(unassigned)').join(' / ');
|
|
lines.push(`${group} ${name}: ${counts(row)}`);
|
|
}
|
|
}
|
|
io.stdout.write(lines.join('\n') + '\n');
|
|
}
|