@letterstory/cli 0.60.1 → 0.61.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/lib/cli.mjs +12 -1
- package/lib/commands/admin.mjs +46 -5
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
} from "./commands.mjs";
|
|
56
56
|
|
|
57
57
|
// Keep in sync with cli/package.json.
|
|
58
|
-
export const VERSION = "0.
|
|
58
|
+
export const VERSION = "0.61.0";
|
|
59
59
|
|
|
60
60
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
61
61
|
// can't accidentally swallow the id as --json's value.
|
|
@@ -604,6 +604,7 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
604
604
|
| cases [--org <uuid>] [--status s] [--stage s] | runs [--limit N] [--mode record|full]
|
|
605
605
|
| run [--mode record|full] [--keys a,b] [--org <uuid>] [--baseline latest|<id>]
|
|
606
606
|
| triage [--owner research|kernel|links|mentions|accuracy|pipeline] [--overdue]
|
|
607
|
+
[--eval <key> [--org <id>|fleet] --assign <owner> | --dismiss "…"] patterns (measure × org)
|
|
607
608
|
| guard <case-key> [--sha <commit>] [--fix-pr #N] | retire <case-key> --reason "…"
|
|
608
609
|
The fleet-wide eval surface: scoreboard,
|
|
609
610
|
every org's cases and suite runs, the
|
|
@@ -613,6 +614,16 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
613
614
|
admin tuning-context [--q "<question>"] The experiment agent's context pack (JSON):
|
|
614
615
|
the pipeline as deployed, levers, measures,
|
|
615
616
|
goals, related history.
|
|
617
|
+
admin tuning desk What waits on a person: comparisons to read
|
|
618
|
+
blind, questions to decide, versions to
|
|
619
|
+
promote, open corpus flags, overdue patterns.
|
|
620
|
+
admin tuning <sub> … The console's loop over a staff key: kernels,
|
|
621
|
+
candidate, compare, comparisons, picks, pick,
|
|
622
|
+
reading-list, pair, side-by-side, promote,
|
|
623
|
+
sessions, session-new, propose, trial-add,
|
|
624
|
+
trial-run, trial-save, and the arena, shredder
|
|
625
|
+
and enhancer twins (every flag is listed in
|
|
626
|
+
cli/lib/commands/admin.mjs).
|
|
616
627
|
admin create-org --domain <bare-domain> [--name "Acme"] [--test] [--no-key]
|
|
617
628
|
[--key-name N] [--capabilities a,b] [--onboard] [--watch] [+ the onboard domain flags]
|
|
618
629
|
The key exchange: create the client org from
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -420,6 +420,7 @@ async function cmdAdminTuningContext(ctx) {
|
|
|
420
420
|
* and promotion from the ledger (docs/architecture/tuning-foundation.md): the headless half of the
|
|
421
421
|
* tuning console's Write › Kernels and Compare tabs. Needs `tuning:experiment` on the key.
|
|
422
422
|
*
|
|
423
|
+
* admin tuning desk what waits on a person: comparisons to read blind, questions to decide, versions to promote, open flags, overdue findings
|
|
423
424
|
* admin tuning kernels every catalog kernel, live version, writer, candidates
|
|
424
425
|
* admin tuning kernel <service-kernel-id> [--version N|live] one version's file (JSON)
|
|
425
426
|
* admin tuning candidate <service-kernel-id> --file f.json [--note "…"] save a file as a candidate version
|
|
@@ -529,6 +530,20 @@ async function cmdAdminTuning(ctx) {
|
|
|
529
530
|
const json = flagBool(flags.json);
|
|
530
531
|
const T = "/api/superadmin/tuning";
|
|
531
532
|
switch (sub) {
|
|
533
|
+
case "desk": {
|
|
534
|
+
const d = await staffRequest(ctx, "GET", `${T}/desk`);
|
|
535
|
+
if (json) return printResult(io, flags, d);
|
|
536
|
+
const lines = [];
|
|
537
|
+
for (const c of d.to_read)
|
|
538
|
+
lines.push(`read blind ${c.read}/${c.target} ${c.primitive.padEnd(8)} ${c.title} ${c.id}`);
|
|
539
|
+
for (const e of d.to_decide) lines.push(`decide ${e.status.padEnd(9)} ${e.question} ${e.id}`);
|
|
540
|
+
for (const e of d.to_promote) lines.push(`promote ship ${e.question} ${e.id}`);
|
|
541
|
+
if (d.flags_open) lines.push(`flags ${d.flags_open} corpus flags open`);
|
|
542
|
+
if (d.findings_overdue)
|
|
543
|
+
lines.push(`triage ${d.findings_overdue} shipped patterns past their due date`);
|
|
544
|
+
for (const err of d.errors ?? []) lines.push(`(could not read: ${err})`);
|
|
545
|
+
return io.log(lines.join("\n") || "Nothing waits on a person.");
|
|
546
|
+
}
|
|
532
547
|
case "kernels": {
|
|
533
548
|
const r = await staffRequest(ctx, "GET", `${T}/kernel-files`);
|
|
534
549
|
if (json) return printResult(io, flags, r);
|
|
@@ -1801,14 +1816,40 @@ async function cmdAdminEvals(ctx) {
|
|
|
1801
1816
|
return r.run?.verdict === "fail" ? 1 : 0;
|
|
1802
1817
|
}
|
|
1803
1818
|
case "triage": {
|
|
1804
|
-
|
|
1819
|
+
// A decision names its pattern: --eval <key> and --org <id> (omitted = the fleet-wide one).
|
|
1820
|
+
const assign = flagStr(flags.assign);
|
|
1821
|
+
const dismiss = flagStr(flags.dismiss);
|
|
1822
|
+
if (assign || dismiss) {
|
|
1823
|
+
const evalKey = flagStr(flags.eval);
|
|
1824
|
+
if (!evalKey)
|
|
1825
|
+
throw new CliError(
|
|
1826
|
+
'Usage: admin evals triage --eval <key> [--org <id>] --assign <owner> | --dismiss "…"'
|
|
1827
|
+
);
|
|
1828
|
+
if (assign && dismiss) throw new CliError("Send --assign or --dismiss, not both.");
|
|
1829
|
+
const orgFlag = flagStr(flags.org);
|
|
1830
|
+
const body = {
|
|
1831
|
+
eval_key: evalKey,
|
|
1832
|
+
org_id: orgFlag && orgFlag !== "fleet" ? orgFlag : null,
|
|
1833
|
+
...(assign ? { owner: assign } : { reason: dismiss }),
|
|
1834
|
+
};
|
|
1835
|
+
return out(
|
|
1836
|
+
await staffRequest(ctx, "PATCH", `${EVALS}/triage`, body),
|
|
1837
|
+
(r) =>
|
|
1838
|
+
`${r.affected ?? 0} finding(s) ${r.action === "assign" ? `handed to ${assign}` : "dismissed"} in ${evalKey} × ${body.org_id ?? "fleet"}`
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
const q = query({
|
|
1842
|
+
owner: flagStr(flags.owner),
|
|
1843
|
+
overdue: flagBool(flags.overdue) ? "true" : undefined,
|
|
1844
|
+
limit: flagStr(flags.limit),
|
|
1845
|
+
});
|
|
1805
1846
|
return out(await staffRequest(ctx, "GET", `${EVALS}/triage${q}`), (r) =>
|
|
1806
1847
|
[
|
|
1807
|
-
...(r.
|
|
1808
|
-
(
|
|
1809
|
-
`${
|
|
1848
|
+
...(r.patterns ?? []).map(
|
|
1849
|
+
(p) =>
|
|
1850
|
+
`${p.eval_key.padEnd(36)} ${(p.org_name ?? p.org_id ?? "fleet").padEnd(24)} ${(p.owner ?? "unassigned").padEnd(10)} ${String(p.count).padStart(5)} ${p.overdue ? "OVERDUE " : "due "}${p.sla_due_at ? p.sla_due_at.slice(0, 10) : "—"}`
|
|
1810
1851
|
),
|
|
1811
|
-
`${r.total ?? 0}
|
|
1852
|
+
`${r.total ?? 0} patterns (${r.findings ?? 0} findings), ${r.overdue ?? 0} overdue`,
|
|
1812
1853
|
].join("\n")
|
|
1813
1854
|
);
|
|
1814
1855
|
}
|