@letterstory/cli 0.72.2 → 0.73.1
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 +2 -0
- package/lib/cli.mjs +4 -3
- package/lib/commands/admin.mjs +129 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -368,6 +368,8 @@ letterstory admin tuning bank-judge <eval-id> --prompt-file judge.md --mode scor
|
|
|
368
368
|
letterstory admin tuning bank-score <eval-id> --version 2 # score it over the pool; prints agreement on held-out labels
|
|
369
369
|
letterstory admin tuning bank-try <eval-id> --version 2 # the judge as a trial rule in candidates, and a comparison against live
|
|
370
370
|
letterstory admin tuning invite --email editor@example.com # invite an editor (Pick and Eval bank only); `people`, `revoke <id>`
|
|
371
|
+
letterstory admin tuning assign --pick <comparison-id> --instructions "Read for the opening" # a task for every editor (--to <email> for one)
|
|
372
|
+
letterstory admin tuning assign --label bank-draft-x-not-y --target 50 # editors cut or keep 50 of this eval's sentences
|
|
371
373
|
letterstory admin tuning side-by-side <id>,<id>,<id> [--cell <key>] # several writers as one board: each one's measures against live; with --cell, every writer's text on that input
|
|
372
374
|
letterstory admin tuning candidates --kernels all --patch '{"writer":"echo/echo"}' --note "Echo" # the same change as a candidate of each kernel
|
|
373
375
|
letterstory admin tuning session-new --title "Echo round 1" --kernel Hazel --input-file brief.md --kind outline [--version 22] [--versions 23,29] # --versions: saved candidates, a trial each
|
package/lib/cli.mjs
CHANGED
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
} from "./commands.mjs";
|
|
57
57
|
|
|
58
58
|
// Keep in sync with cli/package.json.
|
|
59
|
-
export const VERSION = "0.
|
|
59
|
+
export const VERSION = "0.73.1";
|
|
60
60
|
|
|
61
61
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
62
62
|
// can't accidentally swallow the id as --json's value.
|
|
@@ -639,8 +639,9 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
639
639
|
candidate, compare, comparisons, picks, pick,
|
|
640
640
|
ledger, reading-list, finalists,
|
|
641
641
|
finalists-queue, pair, side-by-side,
|
|
642
|
-
|
|
643
|
-
|
|
642
|
+
checklist, checklist-add, checklist-set,
|
|
643
|
+
checklist-labels, feedback, feedback-add,
|
|
644
|
+
feedback-file, feedback-reject, promote,
|
|
644
645
|
sessions, session-new, propose, trial-add,
|
|
645
646
|
trial-run, trial-save, the Write input bank
|
|
646
647
|
(inputs, input, inputs-harvest, input-save),
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
// admin tuning-context [--q "<question>"] (tuning:experiment)
|
|
9
9
|
// admin tuning-import <brief-results.json> [--experiment <id>] (tuning:experiment)
|
|
10
10
|
// admin tuning kernels|kernel|candidate|compare|comparisons|comparison|picks|pick|criteria|promote … (tuning:experiment)
|
|
11
|
-
// admin tuning
|
|
12
|
-
// (
|
|
11
|
+
// admin tuning checklist|checklist-add|checklist-set|checklist-labels|feedback|feedback-add|feedback-file|feedback-reject … (tuning:experiment)
|
|
12
|
+
// (feedback-add --fix "…" files the reader's rewrite; the diff is classified and a disposition suggested.
|
|
13
|
+
// The old names — evals, eval-add, eval-set, proposals, propose-eval, capture-eval, reject-eval — still work.)
|
|
13
14
|
// admin evals scoreboard|cases|runs|run|triage|guard|retire … (fleet:read / tuning:experiment)
|
|
14
15
|
// admin crm import|capture|signals|record|signal|accounts|account|score|slack-channels|link-slack|white-glove|set-white-glove|churn|record-churn|undo-churn|onboard|onboarding|retry-onboarding|onboard-plan|payment-link … (crm:read / crm:write)
|
|
15
16
|
// admin replays [--org <id>] [--target <id>] [--status …] [--limit n] (fleet:read)
|
|
@@ -449,15 +450,19 @@ async function cmdAdminTuningContext(ctx) {
|
|
|
449
450
|
* admin tuning criteria the Eye Test's criteria: id, label and the question each asks of a pair
|
|
450
451
|
* admin tuning loop where the loop stands: what waits at each station, and where to go next
|
|
451
452
|
* admin tuning ledger <comparison-id> the defect ledger: per arm, what the diagnosis read named, the floor and the ceiling, the candidate's next arm; then the reader edits per arm by lever, and the schema gaps
|
|
452
|
-
* admin tuning
|
|
453
|
-
* admin tuning
|
|
454
|
-
* admin tuning
|
|
455
|
-
* admin tuning
|
|
456
|
-
* admin tuning
|
|
457
|
-
* admin tuning
|
|
458
|
-
* admin tuning
|
|
459
|
-
* admin tuning
|
|
460
|
-
* admin tuning
|
|
453
|
+
* admin tuning checklist the checklist: every defect category with its status, the picks' agreement (n, agreement, suggestion) and its labels (+/−) (alias: evals)
|
|
454
|
+
* admin tuning checklist-add --id … --label … --how … --layer … --lever … --locality local|structural --axis … [--example "span"] add a category (starts unvetted) (alias: eval-add)
|
|
455
|
+
* admin tuning checklist-set <id> [--status confirmed|rejected|unvetted] [--example "span" [--fix "…"]] confirm / reject (a person's call), or add an example (alias: eval-set)
|
|
456
|
+
* admin tuning checklist-labels <id> the labelled set of one category: positives (examples + feedback filed into it), negatives (rejected feedback suggested for it), grid overrules
|
|
457
|
+
* admin tuning feedback [--status proposed|captured|rejected] the feedback: spans readers marked in a pair's text with their words, each with its disposition (alias: proposals)
|
|
458
|
+
* admin tuning feedback-add --span "…" --comment "…" [--fix "…"] [--comparison <id> --cell <key> --side control|candidate] [--kind narrow|wide] add feedback (no --side from a blind read); --fix is the reader's rewrite, classified and a disposition suggested (alias: propose-eval)
|
|
459
|
+
* admin tuning feedback-file <id> --as checklist --id … --label … --how … --layer … --lever … --locality local|structural --axis … file it on the checklist, the span (and its fix) as the category's example (appends when the id exists) (alias: capture-eval; --as category)
|
|
460
|
+
* admin tuning feedback-file <id> --as rule file it as a rule; the rule itself is written in the kernels rule lab
|
|
461
|
+
* admin tuning feedback-file <id> --as config [--note "…"] file it as a lever this candidate should pull
|
|
462
|
+
* admin tuning feedback-file <id> --as implementation [--note "…"] file it as a schema gap no setting can express, for the kernels repo (--as lever still works)
|
|
463
|
+
* admin tuning feedback-file <id> --as material [--note "…"] file it as the material's: the input never carried it
|
|
464
|
+
* admin tuning feedback-file <id> --as note keep it; no action
|
|
465
|
+
* admin tuning feedback-reject <id> feedback that was not worth keeping after all (alias: reject-eval)
|
|
461
466
|
* admin tuning reading-list <comparison-id> [--n 10] your next blind pairs as links, to read off the screen
|
|
462
467
|
* admin tuning finalists [--limit 10] the finalists feed: done, gates clean, no craft loss, not yet decided by the picks; ranked by the objective's order
|
|
463
468
|
* admin tuning finalists-queue [--n 10] your next blind pairs round-robin across the finalists (a key reads the queue of the person who owns it; recording a pick still needs a person)
|
|
@@ -473,6 +478,8 @@ async function cmdAdminTuningContext(ctx) {
|
|
|
473
478
|
* admin tuning bank-score <eval-id> --version N score a judge version over the pool (call again for more than 600)
|
|
474
479
|
* admin tuning bank-try <eval-id> --version N [--kernels Hazel,Aspen] the judge as a trial rule in candidates, and a comparison against live
|
|
475
480
|
* admin tuning people | invite --email e [--note "…"] | revoke <id> who an admin invited into the console as an editor
|
|
481
|
+
* admin tuning assignments | assign --pick <comparison-id>|--label <eval-id> [--to e] [--instructions "…"] [--target N] | unassign <id> what editors are asked to do
|
|
482
|
+
* admin tuning tasks your own open tasks, with progress
|
|
476
483
|
* admin tuning side-by-side <id>,<id>[,…] [--cell <key>] several comparisons as one board: each writer's measures against live, and one input's texts
|
|
477
484
|
* admin tuning candidates --kernels Hazel,Aspen|all --patch '{…}' [--base N] [--note "…"] the same changes as a candidate of each kernel
|
|
478
485
|
* admin tuning promote <experiment-id> --versions <service-kernel-id>:<version>,… promote from a "ship" decision
|
|
@@ -505,8 +512,8 @@ async function cmdAdminTuningContext(ctx) {
|
|
|
505
512
|
* admin tuning screens | screen <id> list / one screen: per candidate, each measure against the Base, with its noise
|
|
506
513
|
* admin tuning screen-advance <id> queue what the caps allow now (the cron does it every minute)
|
|
507
514
|
*
|
|
508
|
-
* The bake-off: a screen's versions graded item by item against the checklist
|
|
509
|
-
*
|
|
515
|
+
* The bake-off: a screen's versions graded item by item against the checklist's confirmed and
|
|
516
|
+
* unvetted categories and the craft axes commitment / economy / movement, the winner
|
|
510
517
|
* per item tallied across the inputs, and a merge that composes the best of each into one candidate.
|
|
511
518
|
* Deterministic; a person overrides a grade and confirms the merge, which is a hypothesis until the
|
|
512
519
|
* eye test confirms it.
|
|
@@ -791,6 +798,7 @@ async function cmdAdminTuning(ctx) {
|
|
|
791
798
|
})
|
|
792
799
|
);
|
|
793
800
|
}
|
|
801
|
+
case "checklist":
|
|
794
802
|
case "evals": {
|
|
795
803
|
const r = await staffRequest(ctx, "GET", `${T}/evals`);
|
|
796
804
|
if (json) return printResult(io, flags, r);
|
|
@@ -798,16 +806,29 @@ async function cmdAdminTuning(ctx) {
|
|
|
798
806
|
if (!rows.length) return io.log("(no categories)");
|
|
799
807
|
const cell = (v, w) => String(v ?? "—").padEnd(w);
|
|
800
808
|
io.log(
|
|
801
|
-
`${cell("id", 24)} ${cell("status", 10)} ${cell("layer", 10)} ${cell("lever", 30)} ${"n".padStart(4)} ${"agree".padStart(6)} ${cell("suggest", 10)} ${"
|
|
809
|
+
`${cell("id", 24)} ${cell("status", 10)} ${cell("layer", 10)} ${cell("lever", 30)} ${"n".padStart(4)} ${"agree".padStart(6)} ${cell("suggest", 10)} ${"+".padStart(3)} ${"−".padStart(3)}`
|
|
802
810
|
);
|
|
803
811
|
for (const c of rows) {
|
|
804
812
|
const v = c.vetting ?? {};
|
|
813
|
+
const l = c.labels ?? { positives: (c.examples ?? []).length, negatives: 0 };
|
|
805
814
|
io.log(
|
|
806
|
-
`${cell(c.id, 24)} ${cell(c.status, 10)} ${cell(c.layer, 10)} ${cell(c.lever || "—", 30)} ${String(v.n ?? 0).padStart(4)} ${String(v.agreement ?? "—").padStart(6)} ${cell(v.suggestion, 10)} ${String(
|
|
815
|
+
`${cell(c.id, 24)} ${cell(c.status, 10)} ${cell(c.layer, 10)} ${cell(c.lever || "—", 30)} ${String(v.n ?? 0).padStart(4)} ${String(v.agreement ?? "—").padStart(6)} ${cell(v.suggestion, 10)} ${String(l.positives).padStart(3)} ${String(l.negatives).padStart(3)}`
|
|
807
816
|
);
|
|
808
817
|
}
|
|
809
818
|
return;
|
|
810
819
|
}
|
|
820
|
+
case "checklist-labels": {
|
|
821
|
+
if (!id) throw new CliError("Usage: admin tuning checklist-labels <category-id>");
|
|
822
|
+
const r = await staffRequest(ctx, "GET", `${T}/evals/${encodeURIComponent(id)}/labels`);
|
|
823
|
+
if (json) return printResult(io, flags, r);
|
|
824
|
+
io.log(
|
|
825
|
+
`${r.category_id}: ${r.counts.positives} positive, ${r.counts.negatives} negative (${r.grid_overrules} grid overrule${r.grid_overrules === 1 ? "" : "s"})`
|
|
826
|
+
);
|
|
827
|
+
for (const x of r.positives ?? []) io.log(` + [${x.source}] "${x.span}"${x.fix ? ` → "${x.fix}"` : ""}`);
|
|
828
|
+
for (const x of r.negatives ?? []) io.log(` − [${x.source}] "${x.span}"${x.fix ? ` → "${x.fix}"` : ""}`);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
case "checklist-add":
|
|
811
832
|
case "eval-add": {
|
|
812
833
|
const body = {
|
|
813
834
|
id: flagStr(flags.id),
|
|
@@ -828,25 +849,26 @@ async function cmdAdminTuning(ctx) {
|
|
|
828
849
|
!["local", "structural"].includes(body.locality ?? "")
|
|
829
850
|
)
|
|
830
851
|
throw new CliError(
|
|
831
|
-
'Usage: admin tuning
|
|
852
|
+
'Usage: admin tuning checklist-add --id … --label … --how … --layer … --lever … --locality local|structural --axis … [--example "span"]'
|
|
832
853
|
);
|
|
833
854
|
if (example) body.examples = [{ span: example, ...(flags.fix ? { fix: flagStr(flags.fix) } : {}) }];
|
|
834
855
|
const r = await staffRequest(ctx, "POST", `${T}/evals`, body);
|
|
835
856
|
return json ? printResult(io, flags, r) : io.log(`added ${r.category.id} (${r.category.status})`);
|
|
836
857
|
}
|
|
858
|
+
case "checklist-set":
|
|
837
859
|
case "eval-set": {
|
|
838
860
|
const status = flagStr(flags.status);
|
|
839
861
|
const example = flagStr(flags.example);
|
|
840
862
|
if (!id || (!status && !example) || (status && !["confirmed", "rejected", "unvetted"].includes(status)))
|
|
841
863
|
throw new CliError(
|
|
842
|
-
'Usage: admin tuning
|
|
864
|
+
'Usage: admin tuning checklist-set <id> [--status confirmed|rejected|unvetted] [--example "span" [--fix "…"]]'
|
|
843
865
|
);
|
|
844
866
|
const patch = {};
|
|
845
867
|
if (status) patch.status = status;
|
|
846
868
|
if (example) {
|
|
847
869
|
// The PATCH replaces the whole list: read what is stored and append.
|
|
848
870
|
const current = (await staffRequest(ctx, "GET", `${T}/evals`)).categories?.find((c) => c.id === id);
|
|
849
|
-
if (!current) throw new CliError(`No category ${id}
|
|
871
|
+
if (!current) throw new CliError(`No category ${id} on the checklist`);
|
|
850
872
|
const fix = flagStr(flags.fix);
|
|
851
873
|
patch.examples = [...(current.examples ?? []), { span: example, ...(fix ? { fix } : {}) }];
|
|
852
874
|
}
|
|
@@ -855,27 +877,32 @@ async function cmdAdminTuning(ctx) {
|
|
|
855
877
|
? printResult(io, flags, r)
|
|
856
878
|
: io.log(`${r.category.id}: ${r.category.status}, ${(r.category.examples ?? []).length} examples`);
|
|
857
879
|
}
|
|
880
|
+
case "feedback":
|
|
858
881
|
case "proposals": {
|
|
859
882
|
const status = flagStr(flags.status);
|
|
860
883
|
if (status && !["proposed", "captured", "rejected"].includes(status))
|
|
861
|
-
throw new CliError("Usage: admin tuning
|
|
884
|
+
throw new CliError("Usage: admin tuning feedback [--status proposed|captured|rejected]");
|
|
862
885
|
const qs = status ? `?${new URLSearchParams({ status })}` : "";
|
|
863
886
|
const r = await staffRequest(ctx, "GET", `${T}/proposals${qs}`);
|
|
864
887
|
if (json) return printResult(io, flags, r);
|
|
865
888
|
const rows = r.proposals ?? [];
|
|
866
|
-
if (!rows.length) return io.log("(no
|
|
889
|
+
if (!rows.length) return io.log("(no feedback)");
|
|
867
890
|
for (const p of rows) {
|
|
868
891
|
const where = [p.cell_key, p.side].filter(Boolean).join(" / ") || "—";
|
|
892
|
+
const suggested = p.suggested_disposition
|
|
893
|
+
? `; suggested ${p.suggested_disposition}${p.suggested_category ? ` (${p.suggested_category})` : ""}`
|
|
894
|
+
: "";
|
|
869
895
|
const edit =
|
|
870
896
|
p.fix != null
|
|
871
|
-
? `\n → "${p.fix}" [${p.edit_class ?? "?"} → ${p.lever ?? "no lever: schema gap"}]`
|
|
897
|
+
? `\n → "${p.fix}" [${p.edit_class ?? "?"} → ${p.lever ?? "no lever: schema gap"}${suggested}]`
|
|
872
898
|
: "";
|
|
873
899
|
io.log(
|
|
874
|
-
`${p.id} ${p.status.padEnd(9)} ${p.kind.padEnd(
|
|
900
|
+
`${p.id} ${p.status.padEnd(9)} ${(p.disposition ?? p.kind).padEnd(14)} ${where}${p.category_id ? ` → ${p.category_id}` : ""}\n "${p.span}"${edit}${p.comment ? `\n ${p.comment}` : ""}`
|
|
875
901
|
);
|
|
876
902
|
}
|
|
877
903
|
return;
|
|
878
904
|
}
|
|
905
|
+
case "feedback-add":
|
|
879
906
|
case "propose-eval": {
|
|
880
907
|
const span = flagStr(flags.span);
|
|
881
908
|
const side = flagStr(flags.side);
|
|
@@ -886,7 +913,7 @@ async function cmdAdminTuning(ctx) {
|
|
|
886
913
|
(kind && !["narrow", "wide"].includes(kind))
|
|
887
914
|
)
|
|
888
915
|
throw new CliError(
|
|
889
|
-
'Usage: admin tuning
|
|
916
|
+
'Usage: admin tuning feedback-add --span "…" --comment "…" [--fix "…"] [--comparison <id> --cell <key> --side control|candidate] [--kind narrow|wide]'
|
|
890
917
|
);
|
|
891
918
|
const r = await staffRequest(
|
|
892
919
|
ctx,
|
|
@@ -904,17 +931,27 @@ async function cmdAdminTuning(ctx) {
|
|
|
904
931
|
);
|
|
905
932
|
if (json) return printResult(io, flags, r);
|
|
906
933
|
const p = r.proposal;
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
934
|
+
const suggested = p.suggested_disposition
|
|
935
|
+
? `; suggested ${p.suggested_disposition}${p.suggested_category ? ` (${p.suggested_category})` : ""}`
|
|
936
|
+
: "";
|
|
937
|
+
const edit =
|
|
938
|
+
p.fix != null ? ` — ${p.edit_class}: ${p.lever ?? "no lever maps: a schema gap"}${suggested}` : "";
|
|
939
|
+
return io.log(`added feedback ${p.id} (${p.disposition ?? p.kind})${edit}`);
|
|
940
|
+
}
|
|
941
|
+
case "feedback-file":
|
|
910
942
|
case "capture-eval": {
|
|
911
|
-
|
|
943
|
+
// The first names of checklist and implementation, still accepted.
|
|
944
|
+
const AS_ALIAS = { category: "checklist", lever: "implementation" };
|
|
945
|
+
const asGiven = flagStr(flags.as);
|
|
946
|
+
const as = AS_ALIAS[asGiven] ?? asGiven;
|
|
912
947
|
const usage =
|
|
913
|
-
'Usage: admin tuning
|
|
914
|
-
if (!id || !["
|
|
948
|
+
'Usage: admin tuning feedback-file <id> --as checklist --id … --label … --how … --layer … --lever … --locality local|structural --axis … | --as rule | --as config|implementation|material [--note "…"] | --as note';
|
|
949
|
+
if (!id || !["checklist", "rule", "config", "implementation", "material", "note"].includes(as ?? ""))
|
|
950
|
+
throw new CliError(usage);
|
|
915
951
|
let body = { as };
|
|
916
|
-
if (as === "
|
|
917
|
-
|
|
952
|
+
if (as === "config" || as === "implementation" || as === "material")
|
|
953
|
+
body = compact({ as, note: flagStr(flags.note) });
|
|
954
|
+
if (as === "checklist") {
|
|
918
955
|
const category = {
|
|
919
956
|
id: flagStr(flags.id),
|
|
920
957
|
label: flagStr(flags.label),
|
|
@@ -936,14 +973,22 @@ async function cmdAdminTuning(ctx) {
|
|
|
936
973
|
body = { as, category };
|
|
937
974
|
}
|
|
938
975
|
const r = await staffRequest(ctx, "POST", `${T}/proposals/${id}/capture`, body);
|
|
939
|
-
return
|
|
940
|
-
|
|
941
|
-
:
|
|
942
|
-
|
|
943
|
-
|
|
976
|
+
if (json) return printResult(io, flags, r);
|
|
977
|
+
const FILED = {
|
|
978
|
+
rule: "; write the rule in the kernels rule lab",
|
|
979
|
+
implementation: "; a schema gap, filed for the kernels repo",
|
|
980
|
+
config: "; a lever for this candidate",
|
|
981
|
+
material: "; the input never carried it",
|
|
982
|
+
note: "; kept, no action",
|
|
983
|
+
};
|
|
984
|
+
const d = r.proposal.disposition ?? as;
|
|
985
|
+
return io.log(
|
|
986
|
+
`filed ${r.proposal.id} as ${d}${r.category ? ` → ${r.category.id} (${(r.category.examples ?? []).length} examples)` : (FILED[d] ?? "")}`
|
|
987
|
+
);
|
|
944
988
|
}
|
|
989
|
+
case "feedback-reject":
|
|
945
990
|
case "reject-eval": {
|
|
946
|
-
if (!id) throw new CliError("Usage: admin tuning reject
|
|
991
|
+
if (!id) throw new CliError("Usage: admin tuning feedback-reject <id>");
|
|
947
992
|
const r = await staffRequest(ctx, "POST", `${T}/proposals/${id}/reject`, {});
|
|
948
993
|
return json ? printResult(io, flags, r) : io.log(`rejected ${r.proposal.id}`);
|
|
949
994
|
}
|
|
@@ -956,11 +1001,13 @@ async function cmdAdminTuning(ctx) {
|
|
|
956
1001
|
case "loop": {
|
|
957
1002
|
const r = await staffRequest(ctx, "GET", `${T}/loop`);
|
|
958
1003
|
if (json) return printResult(io, flags, r);
|
|
959
|
-
|
|
1004
|
+
const week = r.propose.candidates_week ?? "?";
|
|
1005
|
+
const progs = r.propose.programmes_running ?? "?";
|
|
1006
|
+
io.log(`propose ${r.propose.running} running, ${week} candidates this week, ${progs} programmes running`);
|
|
960
1007
|
io.log(`read ${r.read.settled_unread} settled, unread`);
|
|
961
1008
|
io.log(`eye test ${r.eye_test.finalists} finalists, ${r.eye_test.pairs_to_read} pairs to read`);
|
|
962
1009
|
io.log(
|
|
963
|
-
`
|
|
1010
|
+
`checklist ${r.evals.proposals_waiting} feedback waiting, ${r.evals.unvetted} unvetted, ${r.evals.suggested} with a suggestion${r.evals.reachable ? "" : " (the checklist could not be read)"}`
|
|
964
1011
|
);
|
|
965
1012
|
io.log(`promote ${r.promote.promotable} won their picks`);
|
|
966
1013
|
io.log(`\nnext: ${r.next}`);
|
|
@@ -1187,6 +1234,48 @@ async function cmdAdminTuning(ctx) {
|
|
|
1187
1234
|
`${ctx.client.url}/superadmin/tuning?${new URLSearchParams({ tab: "compare", comparison: r.comparison_id })}`
|
|
1188
1235
|
);
|
|
1189
1236
|
}
|
|
1237
|
+
case "assignments": {
|
|
1238
|
+
const r = await staffRequest(ctx, "GET", `${T}/assignments${flagBool(flags.closed) ? "?closed=1" : ""}`);
|
|
1239
|
+
if (json) return printResult(io, flags, r);
|
|
1240
|
+
for (const a of r.assignments)
|
|
1241
|
+
io.log(
|
|
1242
|
+
`${a.id} ${a.kind} "${a.title}" → ${a.assignee_email ?? "every editor"}${a.target ? `, ${a.target} asked` : ""}${a.closed_at ? " (closed)" : ""}`
|
|
1243
|
+
);
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
case "assign": {
|
|
1247
|
+
const pick = flagStr(flags.pick);
|
|
1248
|
+
const label = flagStr(flags.label);
|
|
1249
|
+
if (!pick === !label)
|
|
1250
|
+
throw new CliError(
|
|
1251
|
+
'Usage: admin tuning assign --pick <comparison-id> | --label <eval-id> [--to email] [--instructions "…"] [--title "…"] [--target N]'
|
|
1252
|
+
);
|
|
1253
|
+
const body = compact({
|
|
1254
|
+
...(pick ? { kind: "pick", comparison_id: pick } : { kind: "label", eval_id: label }),
|
|
1255
|
+
assignee_email: flagStr(flags.to),
|
|
1256
|
+
instructions: flagStr(flags.instructions),
|
|
1257
|
+
title: flagStr(flags.title),
|
|
1258
|
+
target: flagNum(flags.target),
|
|
1259
|
+
});
|
|
1260
|
+
const r = await staffRequest(ctx, "POST", `${T}/assignments`, body);
|
|
1261
|
+
if (json) return printResult(io, flags, r);
|
|
1262
|
+
return io.log(
|
|
1263
|
+
`assigned ${r.assignment.kind} task "${r.assignment.title}" to ${r.assignment.assignee_email ?? "every editor"} (${r.assignment.id})`
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
case "unassign": {
|
|
1267
|
+
if (!id) throw new CliError("Usage: admin tuning unassign <assignment-id>");
|
|
1268
|
+
return printResult(io, flags, await staffRequest(ctx, "DELETE", `${T}/assignments/${id}`));
|
|
1269
|
+
}
|
|
1270
|
+
case "tasks": {
|
|
1271
|
+
const r = await staffRequest(ctx, "GET", `${T}/editor/tasks`);
|
|
1272
|
+
if (json) return printResult(io, flags, r);
|
|
1273
|
+
for (const t of r.tasks)
|
|
1274
|
+
io.log(
|
|
1275
|
+
`${t.id} ${t.kind} "${t.title}": ${t.done} done, ${t.remaining} left${t.complete ? " (complete)" : ""}`
|
|
1276
|
+
);
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1190
1279
|
case "people": {
|
|
1191
1280
|
const r = await staffRequest(ctx, "GET", `${T}/people`);
|
|
1192
1281
|
if (json) return printResult(io, flags, r);
|
|
@@ -2144,7 +2233,7 @@ async function cmdAdminTuning(ctx) {
|
|
|
2144
2233
|
}
|
|
2145
2234
|
default:
|
|
2146
2235
|
throw new CliError(
|
|
2147
|
-
"Usage: admin tuning kernels|kernel|candidate|compare|comparisons|comparison|picks|pick|loop|ledger|
|
|
2236
|
+
"Usage: admin tuning kernels|kernel|candidate|compare|comparisons|comparison|picks|pick|loop|ledger|checklist|checklist-add|checklist-set|checklist-labels|feedback|feedback-add|feedback-file|feedback-reject|reading-list|finalists|finalists-queue|pair|bank|bank-eval|bank-draft|bank-shape|bank-pool|bank-judge|bank-score|bank-try|people|invite|revoke|assignments|assign|unassign|tasks|side-by-side|candidates|base-kernels|base-versions|sessions|session|session-new|propose|trial-add|trial-run|trial-save|promote|arenas|arena|arena-candidate|arena-dials|comparison-extend|research-compare|research-inputs|research-split|research-standing|promote-arena|shred-compare|shred-inputs|shred-split|shred-standing|shredders|shredder|shredder-candidate|promote-shredder|enhance-compare|enhance-inputs|enhance-split|enhance-standing|enhancers|enhancer|enhancer-candidate|promote-enhancer (see --help)"
|
|
2148
2237
|
);
|
|
2149
2238
|
}
|
|
2150
2239
|
}
|