@letterstory/cli 0.123.0 → 0.124.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 CHANGED
@@ -61,13 +61,15 @@ import {
61
61
  } from "./commands.mjs";
62
62
 
63
63
  // Keep in sync with cli/package.json.
64
- export const VERSION = "0.123.0";
64
+ export const VERSION = "0.124.0";
65
65
 
66
66
  // Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
67
67
  // can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
68
68
  // `negate` spelling) in a command's ARGS map must be listed; boolean-flags.test.ts enforces it.
69
69
  export const BOOLEAN_FLAGS = new Set([
70
70
  "json",
71
+ // admin models runs: only the starred ones.
72
+ "starred",
71
73
  // shredder file / arena file: save the version as a candidate beside live.
72
74
  "candidate",
73
75
  // site tree: include children a fold-by-default family would hide; items over the whole subtree.
@@ -843,6 +845,8 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
843
845
  session (a trial per arm), linked to its
844
846
  ledger entry. Written by \`npm run lab --
845
847
  publish\` in the kernels repo.
848
+ admin models runs [--model M] [--starred] | run <id> | star|unstar <id> | scoreboard --model M
849
+ The model hub's saved runs and blind arena (models.letter.dev)
846
850
  admin spend summary [--range day|week|month|year | --from D --to D] [--grain day|week|month]
847
851
  | reconcile [--from D --to D] | pnl [--range day|week|month|year | --from D --to D]
848
852
  | reference add --vendor V [--key K] --metric billed_usd --value N --from D [--to D] --ref "…"
@@ -19,6 +19,7 @@
19
19
  // admin brand-detection <org-id> (fleet:read)
20
20
  // admin brand-detection <org-id> [--term t]... [--exact t]... [--exclude p]... [--note "…"] | --clear [--note "…"] (fleet:instrument)
21
21
  // admin recipes list|show|vocab|export|import|save|delete … (recipes:read / recipes:write)
22
+ // admin models runs|run|star|unstar|scoreboard … (models:read / models:write)
22
23
  // admin replays [--org <id>] [--target <id>] [--status …] [--limit n] (fleet:read)
23
24
  // admin replay --org <id> [<response-id> | --target <id>] [--surface …] (fleet:replay)
24
25
  // admin create-org --domain acme.com [--name "Acme"] [--test] [--no-key] [--key-name N]
@@ -3962,6 +3963,83 @@ function spendEntryFromFlags(flags) {
3962
3963
  });
3963
3964
  }
3964
3965
 
3966
+ const MODELS = "/api/superadmin/models";
3967
+ const MODELS_USAGE =
3968
+ "Usage: admin models runs [--model ballpoint-1] [--starred] [--limit N] | run <id> | star <id> | unstar <id> | scoreboard --model ballpoint-1";
3969
+
3970
+ /** The model hub's saved runs and blind arena (models.letter.dev), same functions as its pages. */
3971
+ async function cmdAdminModels(ctx) {
3972
+ const { flags, positionals, io } = ctx;
3973
+ const sub = positionals[0];
3974
+ switch (sub) {
3975
+ case "runs": {
3976
+ const params = new URLSearchParams(
3977
+ compact({
3978
+ model: flagStr(flags.model),
3979
+ starred: flagBool(flags.starred) ? "true" : undefined,
3980
+ limit: flagNum(flags.limit)?.toString(),
3981
+ })
3982
+ );
3983
+ const result = await staffRequest(ctx, "GET", `${MODELS}/runs${params.size ? `?${params}` : ""}`);
3984
+ printResult(io, flags, result, (r) =>
3985
+ (r.runs ?? [])
3986
+ .map(
3987
+ (x) =>
3988
+ `${x.created_at.slice(0, 16)} ${x.starred ? "★" : " "} ${x.model.padEnd(14)} ${String(x.outputs).padStart(3)} outputs ${String(x.votes).padStart(3)} votes ${x.contenders.join(", ")} ${x.id}`
3989
+ )
3990
+ .join("\n")
3991
+ );
3992
+ return 0;
3993
+ }
3994
+ case "run": {
3995
+ const id = positionals[1];
3996
+ if (!id) throw new CliError("Usage: admin models run <id>");
3997
+ const result = await staffRequest(ctx, "GET", `${MODELS}/runs/${id}`);
3998
+ printResult(io, flags, result, (r) =>
3999
+ [
4000
+ `${r.model} · ${r.created_at} · ${JSON.stringify(r.input)}`,
4001
+ ...(r.outputs ?? []).map(
4002
+ (o) =>
4003
+ ` [${o.slot}] ${o.contender}${o.ours ? " (ours)" : ""}: ${o.error ? `error: ${o.error}` : Object.values(o.output).join(" — ")}`
4004
+ ),
4005
+ ].join("\n")
4006
+ );
4007
+ return 0;
4008
+ }
4009
+ case "star":
4010
+ case "unstar": {
4011
+ const id = positionals[1];
4012
+ if (!id) throw new CliError(`Usage: admin models ${sub} <id>`);
4013
+ const result = await staffRequest(ctx, "PATCH", `${MODELS}/runs/${id}`, { starred: sub === "star" });
4014
+ ok(ctx, `${sub === "star" ? "Starred" : "Unstarred"} ${result.id}`);
4015
+ printResult(io, flags, result, () => "");
4016
+ return 0;
4017
+ }
4018
+ case "scoreboard": {
4019
+ const model = flagStr(flags.model);
4020
+ if (!model) throw new CliError("Usage: admin models scoreboard --model ballpoint-1");
4021
+ const result = await staffRequest(
4022
+ ctx,
4023
+ "GET",
4024
+ `${MODELS}/arena/scoreboard?model=${encodeURIComponent(model)}`
4025
+ );
4026
+ printResult(io, flags, result, (r) =>
4027
+ (r.opponents ?? []).length
4028
+ ? r.opponents
4029
+ .map(
4030
+ (o) =>
4031
+ `${r.model} vs ${o.opponent}: ${o.wins}-${o.losses} (${o.ties} ties, ${o.both_bad} both bad) · ${o.win_rate == null ? "—" : `${Math.round(o.win_rate * 100)}% [${Math.round(o.low * 100)}–${Math.round(o.high * 100)}]`} · ${o.voters} voters`
4032
+ )
4033
+ .join("\n")
4034
+ : `No votes on ${r.model} yet.`
4035
+ );
4036
+ return 0;
4037
+ }
4038
+ default:
4039
+ throw new CliError(MODELS_USAGE);
4040
+ }
4041
+ }
4042
+
3965
4043
  async function cmdAdminSpend(ctx) {
3966
4044
  const { flags, positionals, io } = ctx;
3967
4045
  const sub = positionals[0];
@@ -4767,6 +4845,7 @@ export async function cmdAdmin(ctx) {
4767
4845
  return cmdAdminReplays({ ...ctx, positionals: ctx.positionals.slice(1) }, sub);
4768
4846
  if (sub === "crm") return cmdAdminCrm({ ...ctx, positionals: ctx.positionals.slice(1) });
4769
4847
  if (sub === "spend") return cmdAdminSpend({ ...ctx, positionals: ctx.positionals.slice(1) });
4848
+ if (sub === "models") return cmdAdminModels({ ...ctx, positionals: ctx.positionals.slice(1) });
4770
4849
  if (sub === "create-org") return cmdAdminCreateOrg({ ...ctx, positionals: ctx.positionals.slice(1) });
4771
4850
  if (sub === "ask") return cmdAdminAsk({ ...ctx, positionals: ctx.positionals.slice(1) });
4772
4851
  if (sub === "patterns") return cmdAdminPatterns({ ...ctx, positionals: ctx.positionals.slice(1) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.123.0",
3
+ "version": "0.124.0",
4
4
  "description": "Spin up and manage Letterstory phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",