tickmarkr 1.90.6 → 1.90.7
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/dist/cli/commands/doctor.js +25 -3
- package/dist/cli/commands/fleet.d.ts +18 -0
- package/dist/cli/commands/fleet.js +88 -56
- package/dist/cli/commands/init.d.ts +6 -1
- package/dist/cli/commands/init.js +73 -47
- package/dist/cli/commands/run.js +3 -2
- package/dist/cli/commands/verify.d.ts +1 -0
- package/dist/cli/commands/verify.js +12 -2
- package/dist/config/fleet-overlay.d.ts +4 -0
- package/dist/config/fleet-overlay.js +4 -0
- package/dist/gates/baseline.d.ts +15 -0
- package/dist/gates/baseline.js +77 -4
- package/dist/run/daemon.js +25 -0
- package/dist/tui/ink/components.d.ts +3 -1
- package/dist/tui/ink/components.js +2 -2
- package/dist/tui/ink/fleet-app.d.ts +15 -2
- package/dist/tui/ink/fleet-app.js +169 -41
- package/dist/tui/ink/init-app.d.ts +34 -0
- package/dist/tui/ink/init-app.js +272 -0
- package/package.json +1 -1
|
@@ -102,9 +102,15 @@ export function formatDoctorAge(ageMs) {
|
|
|
102
102
|
return `${mins}m old`;
|
|
103
103
|
return `${Math.floor(mins / 60)}h old`;
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
// judge seats travel the editor as the same "adapter:model" strings the pickers list; the model
|
|
106
|
+
// half may itself contain ":" so only the first separator is structural.
|
|
107
|
+
function splitSeat(seat) {
|
|
108
|
+
const at = seat.indexOf(":");
|
|
109
|
+
return { adapter: seat.slice(0, at), model: seat.slice(at + 1) };
|
|
110
|
+
}
|
|
111
|
+
export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels, modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewOverlay, reloadGuard, entry = "probe", initialJudge = "", judgeSeats = [], }) {
|
|
106
112
|
const { exit } = useApp();
|
|
107
|
-
const [screen, setScreen] = useState("probe");
|
|
113
|
+
const [screen, setScreen] = useState(entry === "presets" ? "modes" : "probe");
|
|
108
114
|
const screenRef = useRef(screen);
|
|
109
115
|
const [cursor, setCursor] = useState(0);
|
|
110
116
|
const cursorRef = useRef(cursor);
|
|
@@ -159,9 +165,19 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
159
165
|
const steeringPickerCursorRef = useRef(0);
|
|
160
166
|
const [steeringPickerCursor, setSteeringPickerCursor] = useState(0);
|
|
161
167
|
const [, setSteeringPickerRevision] = useState(0);
|
|
168
|
+
const judgeCursorRef = useRef(0);
|
|
169
|
+
const [judgeCursor, setJudgeCursor] = useState(0);
|
|
170
|
+
const judgeSeatRef = useRef(null);
|
|
171
|
+
const [judgeSeat, setJudgeSeat] = useState(null);
|
|
162
172
|
const reviewRef = useRef(null);
|
|
163
173
|
const [review, setReview] = useState(null);
|
|
164
174
|
const doneRef = useRef(false);
|
|
175
|
+
// entry === "presets": the first modes visit is the preset pick (mode → review, custom → the
|
|
176
|
+
// full walk). Once custom is chosen this flips off and modes behaves exactly as in probe entry.
|
|
177
|
+
const presetPickRef = useRef(entry === "presets");
|
|
178
|
+
// type-to-search on the long lists — reset on every screen change (per-screen-visit filter)
|
|
179
|
+
const filterRef = useRef("");
|
|
180
|
+
const [filter, setFilter] = useState("");
|
|
165
181
|
const enabledModelGroups = () => modelGroups.filter((group) => !denyRef.current?.has(group.adapter));
|
|
166
182
|
const stagedMap = () => mapRef.current;
|
|
167
183
|
const currentModelRows = () => {
|
|
@@ -180,6 +196,31 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
180
196
|
}
|
|
181
197
|
return rows;
|
|
182
198
|
};
|
|
199
|
+
// type-to-search over the long lists: plain case-insensitive substring on the row's visible
|
|
200
|
+
// label. Each filterable screen derives its rows through these so input and render agree.
|
|
201
|
+
const matches = (label, f = filterRef.current) => f === "" || label.toLowerCase().includes(f.toLowerCase());
|
|
202
|
+
const filteredModelRows = (f = filterRef.current) => currentModelRows().filter((row) => matches(row.model, f));
|
|
203
|
+
const filteredCandidates = (f = filterRef.current) => candidatesRef.current.filter((candidate) => matches(candidate.label, f));
|
|
204
|
+
const filteredSteeringRows = (f = filterRef.current) => steeringRowsRef.current.filter((option) => matches(option, f));
|
|
205
|
+
const judgeKeepRow = initialJudge ? `(keep default) ${initialJudge}` : "(keep default)";
|
|
206
|
+
const filteredJudgeRows = (f = filterRef.current) => [judgeKeepRow, ...judgeSeats].filter((row) => matches(row, f));
|
|
207
|
+
// Shared filter-edit tail for the filterable screens: hotkeys run first in each screen block,
|
|
208
|
+
// whatever printable input is left appends here (space stays a toggle key, never a filter char).
|
|
209
|
+
const filterInput = (countFor, cursorRef, setCursorState, input, key) => {
|
|
210
|
+
// printable chars only: "\r" reaches here when an emptied list makes key.return a no-op
|
|
211
|
+
const printable = input > " " && !key.ctrl && !key.meta;
|
|
212
|
+
const next = key.backspace || key.delete
|
|
213
|
+
? filterRef.current.slice(0, -1)
|
|
214
|
+
: (printable ? filterRef.current + input : null);
|
|
215
|
+
if (next === null)
|
|
216
|
+
return false;
|
|
217
|
+
filterRef.current = next;
|
|
218
|
+
setFilter(next);
|
|
219
|
+
const clamped = Math.min(cursorRef.current, Math.max(countFor(next) - 1, 0));
|
|
220
|
+
cursorRef.current = clamped;
|
|
221
|
+
setCursorState(clamped);
|
|
222
|
+
return true;
|
|
223
|
+
};
|
|
183
224
|
const editorState = () => ({
|
|
184
225
|
denyAdapters: [...(denyRef.current ?? [])].sort(),
|
|
185
226
|
denyModels: [...(denyModelsRef.current ?? [])].sort(),
|
|
@@ -194,6 +235,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
194
235
|
: classification),
|
|
195
236
|
selectedMode: selectedModeRef.current,
|
|
196
237
|
map: stagedMap(),
|
|
238
|
+
...(judgeSeatRef.current ? { judgeSeat: splitSeat(judgeSeatRef.current) } : {}),
|
|
197
239
|
steering: structuredClone(steeringRef.current),
|
|
198
240
|
});
|
|
199
241
|
const finish = (result) => {
|
|
@@ -206,9 +248,24 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
206
248
|
showScreen("steering");
|
|
207
249
|
};
|
|
208
250
|
const showScreen = (next) => {
|
|
251
|
+
filterRef.current = "";
|
|
252
|
+
setFilter("");
|
|
209
253
|
screenRef.current = next;
|
|
210
254
|
setScreen(next);
|
|
211
255
|
};
|
|
256
|
+
// The one review funnel: an empty staged overlay finishes as no-changes, a real diff shows the
|
|
257
|
+
// confirm screen. Reached from the steering enter and, in preset entry, from a mode pick.
|
|
258
|
+
const goReview = () => {
|
|
259
|
+
const nextReview = reviewOverlay(editorState());
|
|
260
|
+
if (nextReview.kind === "empty") {
|
|
261
|
+
finish({ kind: "no-changes" });
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
reviewRef.current = nextReview;
|
|
265
|
+
setReview(reviewRef.current);
|
|
266
|
+
setNotice("");
|
|
267
|
+
showScreen("review");
|
|
268
|
+
};
|
|
212
269
|
const beginClassification = (group, model) => {
|
|
213
270
|
tierCursorRef.current = 0;
|
|
214
271
|
setTierCursor(0);
|
|
@@ -248,7 +305,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
248
305
|
showScreen("shapes");
|
|
249
306
|
return;
|
|
250
307
|
}
|
|
251
|
-
if (key.escape && screenRef.current === "steering-prefer") {
|
|
308
|
+
if (key.escape && (screenRef.current === "steering-prefer" || screenRef.current === "judge-pick")) {
|
|
252
309
|
showScreen("steering");
|
|
253
310
|
return;
|
|
254
311
|
}
|
|
@@ -304,7 +361,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
304
361
|
return;
|
|
305
362
|
}
|
|
306
363
|
if (screenRef.current === "models") {
|
|
307
|
-
const rows =
|
|
364
|
+
const rows = filteredModelRows();
|
|
308
365
|
if (key.downArrow || input === "j") {
|
|
309
366
|
const next = Math.min(modelCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
310
367
|
modelCursorRef.current = next;
|
|
@@ -354,10 +411,16 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
354
411
|
setModelGroup(next);
|
|
355
412
|
modelCursorRef.current = 0;
|
|
356
413
|
setModelCursor(0);
|
|
414
|
+
filterRef.current = "";
|
|
415
|
+
setFilter("");
|
|
357
416
|
}
|
|
358
417
|
else {
|
|
359
418
|
showScreen("modes");
|
|
360
419
|
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (filterInput((f) => filteredModelRows(f).length, modelCursorRef, setModelCursor, input, key)) {
|
|
423
|
+
setNotice("");
|
|
361
424
|
}
|
|
362
425
|
return;
|
|
363
426
|
}
|
|
@@ -464,9 +527,11 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
464
527
|
}
|
|
465
528
|
}
|
|
466
529
|
if (screenRef.current === "modes") {
|
|
530
|
+
// preset entry adds one final `custom` row after the modes — the full-walk escape hatch
|
|
531
|
+
const rowCount = modeOptions.length + (presetPickRef.current ? 1 : 0);
|
|
467
532
|
const currentModeCursor = modeCursorRef.current ?? 0;
|
|
468
533
|
if (key.downArrow || input === "j") {
|
|
469
|
-
const next = Math.min(currentModeCursor + 1, Math.max(
|
|
534
|
+
const next = Math.min(currentModeCursor + 1, Math.max(rowCount - 1, 0));
|
|
470
535
|
modeCursorRef.current = next;
|
|
471
536
|
setModeCursor(next);
|
|
472
537
|
return;
|
|
@@ -477,8 +542,20 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
477
542
|
setModeCursor(next);
|
|
478
543
|
return;
|
|
479
544
|
}
|
|
480
|
-
if (key.return
|
|
545
|
+
if (key.return) {
|
|
546
|
+
if (presetPickRef.current && currentModeCursor === modeOptions.length) {
|
|
547
|
+
presetPickRef.current = false;
|
|
548
|
+
showScreen("agents");
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (!modeOptions[currentModeCursor])
|
|
552
|
+
return;
|
|
481
553
|
selectedModeRef.current = modeOptions[currentModeCursor].id;
|
|
554
|
+
if (presetPickRef.current) {
|
|
555
|
+
// entry context: a preset pick goes straight to the diff confirm
|
|
556
|
+
goReview();
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
482
559
|
showScreen("shapes");
|
|
483
560
|
}
|
|
484
561
|
return;
|
|
@@ -527,8 +604,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
527
604
|
return;
|
|
528
605
|
}
|
|
529
606
|
if (screenRef.current === "candidates") {
|
|
607
|
+
const rows = filteredCandidates();
|
|
530
608
|
if (key.downArrow || input === "j") {
|
|
531
|
-
const next = Math.min(candidateCursorRef.current + 1, Math.max(
|
|
609
|
+
const next = Math.min(candidateCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
532
610
|
candidateCursorRef.current = next;
|
|
533
611
|
setCandidateCursor(next);
|
|
534
612
|
return;
|
|
@@ -539,16 +617,18 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
539
617
|
setCandidateCursor(next);
|
|
540
618
|
return;
|
|
541
619
|
}
|
|
542
|
-
if (key.return &&
|
|
620
|
+
if (key.return && rows[candidateCursorRef.current]) {
|
|
543
621
|
const shape = shapeRows(selectedModeRef.current, stagedMap())[shapeCursorRef.current]?.id;
|
|
544
622
|
if (shape) {
|
|
545
|
-
const picked =
|
|
623
|
+
const picked = rows[candidateCursorRef.current];
|
|
546
624
|
const nextMap = { ...stagedMap(), [shape]: { pin: picked.pin } };
|
|
547
625
|
mapRef.current = nextMap;
|
|
548
626
|
setMap(nextMap);
|
|
549
627
|
}
|
|
550
628
|
showScreen("shapes");
|
|
629
|
+
return;
|
|
551
630
|
}
|
|
631
|
+
filterInput((f) => filteredCandidates(f).length, candidateCursorRef, setCandidateCursor, input, key);
|
|
552
632
|
return;
|
|
553
633
|
}
|
|
554
634
|
if (screenRef.current === "shape-prefer") {
|
|
@@ -591,8 +671,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
591
671
|
return;
|
|
592
672
|
}
|
|
593
673
|
if (screenRef.current === "steering") {
|
|
674
|
+
// review.prefer + consult.prefer rows plus the single judge seat as the final row
|
|
594
675
|
if (key.downArrow || input === "j") {
|
|
595
|
-
const next = Math.min(steeringCursorRef.current + 1, STEERING_KEYS.length
|
|
676
|
+
const next = Math.min(steeringCursorRef.current + 1, STEERING_KEYS.length);
|
|
596
677
|
steeringCursorRef.current = next;
|
|
597
678
|
setSteeringCursor(next);
|
|
598
679
|
return;
|
|
@@ -604,6 +685,13 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
604
685
|
return;
|
|
605
686
|
}
|
|
606
687
|
if (input === "f") {
|
|
688
|
+
if (steeringCursorRef.current === STEERING_KEYS.length) {
|
|
689
|
+
judgeCursorRef.current = 0;
|
|
690
|
+
setJudgeCursor(0);
|
|
691
|
+
setNotice("");
|
|
692
|
+
showScreen("judge-pick");
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
607
695
|
const which = STEERING_KEYS[steeringCursorRef.current];
|
|
608
696
|
const current = steeringRef.current?.[which] ?? [];
|
|
609
697
|
steeringPickerRef.current = which;
|
|
@@ -615,22 +703,40 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
615
703
|
showScreen("steering-prefer");
|
|
616
704
|
return;
|
|
617
705
|
}
|
|
618
|
-
if (key.return)
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
706
|
+
if (key.return)
|
|
707
|
+
goReview();
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (screenRef.current === "judge-pick") {
|
|
711
|
+
const rows = filteredJudgeRows();
|
|
712
|
+
if (key.downArrow || input === "j") {
|
|
713
|
+
const next = Math.min(judgeCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
714
|
+
judgeCursorRef.current = next;
|
|
715
|
+
setJudgeCursor(next);
|
|
716
|
+
return;
|
|
628
717
|
}
|
|
718
|
+
if (key.upArrow || input === "k") {
|
|
719
|
+
const next = Math.max(judgeCursorRef.current - 1, 0);
|
|
720
|
+
judgeCursorRef.current = next;
|
|
721
|
+
setJudgeCursor(next);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
if (key.return && rows[judgeCursorRef.current]) {
|
|
725
|
+
// single-select: one seat or back to the config default — never a chain
|
|
726
|
+
const picked = rows[judgeCursorRef.current];
|
|
727
|
+
const seat = picked === judgeKeepRow ? null : picked;
|
|
728
|
+
judgeSeatRef.current = seat;
|
|
729
|
+
setJudgeSeat(seat);
|
|
730
|
+
showScreen("steering");
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
filterInput((f) => filteredJudgeRows(f).length, judgeCursorRef, setJudgeCursor, input, key);
|
|
629
734
|
return;
|
|
630
735
|
}
|
|
631
736
|
if (screenRef.current === "steering-prefer") {
|
|
737
|
+
const rows = filteredSteeringRows();
|
|
632
738
|
if (key.downArrow || input === "j") {
|
|
633
|
-
const next = Math.min(steeringPickerCursorRef.current + 1, Math.max(
|
|
739
|
+
const next = Math.min(steeringPickerCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
634
740
|
steeringPickerCursorRef.current = next;
|
|
635
741
|
setSteeringPickerCursor(next);
|
|
636
742
|
return;
|
|
@@ -641,8 +747,8 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
641
747
|
setSteeringPickerCursor(next);
|
|
642
748
|
return;
|
|
643
749
|
}
|
|
644
|
-
if (input === " " &&
|
|
645
|
-
const option =
|
|
750
|
+
if (input === " " && rows[steeringPickerCursorRef.current]) {
|
|
751
|
+
const option = rows[steeringPickerCursorRef.current];
|
|
646
752
|
const at = steeringChainRef.current.indexOf(option);
|
|
647
753
|
if (at === -1)
|
|
648
754
|
steeringChainRef.current.push(option);
|
|
@@ -661,7 +767,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
661
767
|
setSteering(next);
|
|
662
768
|
setNotice("");
|
|
663
769
|
showScreen("steering");
|
|
770
|
+
return;
|
|
664
771
|
}
|
|
772
|
+
filterInput((f) => filteredSteeringRows(f).length, steeringPickerCursorRef, setSteeringPickerCursor, input, key);
|
|
665
773
|
return;
|
|
666
774
|
}
|
|
667
775
|
if (screenRef.current === "review") {
|
|
@@ -675,7 +783,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
675
783
|
setNotice(`fleet: config loader rejects the proposed overlay — ${loadError}`);
|
|
676
784
|
reviewRef.current = null;
|
|
677
785
|
setReview(null);
|
|
678
|
-
showScreen("steering");
|
|
786
|
+
showScreen(presetPickRef.current ? "modes" : "steering");
|
|
679
787
|
return;
|
|
680
788
|
}
|
|
681
789
|
finish({ kind: "write", review: reviewRef.current });
|
|
@@ -699,16 +807,15 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
699
807
|
return (_jsx(FleetListScreen, { title: "step 2/6 \u00B7 agent CLIs", legend: "\u2191\u2193/jk move \u00B7 space toggle \u00B7 enter next \u00B7 esc/q quit", rows: rows, cursor: cursor }));
|
|
700
808
|
}
|
|
701
809
|
const group = enabledModelGroups()[modelGroup];
|
|
702
|
-
const modelRows = currentModelRows();
|
|
703
810
|
if (screen === "models") {
|
|
704
|
-
const rows =
|
|
811
|
+
const rows = filteredModelRows().map((row) => {
|
|
705
812
|
const denied = group ? denyModels.has(`${group.adapter}:${row.model}`) : false;
|
|
706
813
|
return {
|
|
707
814
|
id: row.model,
|
|
708
815
|
content: row.tier ? (_jsxs(_Fragment, { children: [_jsx(ToggleMark, { active: !denied }), _jsx(Text, { children: ` ${row.model} ${row.tier} ${denied ? "denied" : "allowed"}` })] })) : _jsx(Text, { children: `( ) ${row.model} ??? unclassified${row.detectedAt ? ` (${row.detectedAt})` : ""}` }),
|
|
709
816
|
};
|
|
710
817
|
});
|
|
711
|
-
return (_jsx(FleetListScreen, { title: `step 3/6 · models · ${group?.adapter ?? ""}`, legend: "\u2191\u2193
|
|
818
|
+
return (_jsx(FleetListScreen, { title: `step 3/6 · models · ${group?.adapter ?? ""}`, legend: "\u2191\u2193 to move \u00B7 Space to toggle \u00B7 t to classify tier \u00B7 n to add model \u00B7 Enter for next \u00B7 Type to search \u00B7 Esc to quit", rows: rows, cursor: modelCursor, details: notice ? [notice] : [], filter: filter }));
|
|
712
819
|
}
|
|
713
820
|
if (screen === "add-model")
|
|
714
821
|
return (_jsx(FleetListScreen, { title: `add model · ${group?.adapter ?? ""}`, legend: "type model id \u00B7 enter classify \u00B7 esc cancel", rows: [{ id: "model", content: _jsx(Text, { children: modelId || "model id (required):" }) }], cursor: 0, details: notice ? [notice] : [] }));
|
|
@@ -720,10 +827,18 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
720
827
|
if (screen === "provenance")
|
|
721
828
|
return (_jsx(FleetListScreen, { title: `benchmark provenance · ${pendingClassificationRef.current?.adapter}:${pendingClassificationRef.current?.model}`, legend: "type note \u00B7 enter apply \u00B7 esc cancel", rows: [{ id: "note", content: _jsx(Text, { children: note || "benchmark provenance note (required):" }) }], cursor: 0, details: notice ? [notice] : [] }));
|
|
722
829
|
if (screen === "modes") {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
})
|
|
830
|
+
const presetPick = presetPickRef.current;
|
|
831
|
+
const rows = modeOptions.map((option) => ({
|
|
832
|
+
id: option.id,
|
|
833
|
+
content: (_jsxs(_Fragment, { children: [option.id === initialMode ? _jsx(ToggleMark, { active: true }) : _jsx(Text, { children: " " }), _jsx(Text, { children: ` ${option.id.padEnd(11)} ${option.gloss}` })] })),
|
|
834
|
+
}));
|
|
835
|
+
if (presetPick) {
|
|
836
|
+
rows.push({
|
|
837
|
+
id: "custom",
|
|
838
|
+
content: (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { children: ` ${"custom".padEnd(11)} walk the full editor (agents → models → shapes → seats)` })] })),
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
return (_jsx(FleetListScreen, { title: presetPick ? "fleet · routing presets" : "step 4/6 · routing mode", legend: presetPick ? "↑↓ to move · Enter to apply preset · Esc to close" : "↑↓/jk move · enter select · esc/q quit", rows: rows, cursor: modeCursor, details: modeOptions[modeCursor] ? modePreview(modeOptions[modeCursor].id, map) : [] }));
|
|
727
842
|
}
|
|
728
843
|
const renderedShapes = shapeRows(selectedModeRef.current, map);
|
|
729
844
|
if (screen === "shapes") {
|
|
@@ -731,10 +846,10 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
731
846
|
}
|
|
732
847
|
const shape = renderedShapes[shapeCursor]?.id;
|
|
733
848
|
if (screen === "candidates") {
|
|
734
|
-
return (_jsx(FleetListScreen, { title: `pick · ${shape}`, legend: "\u2191\u2193
|
|
849
|
+
return (_jsx(FleetListScreen, { title: `pick · ${shape}`, legend: "\u2191\u2193 to move \u00B7 Enter to pin \u00B7 Type to search \u00B7 Esc to cancel \u00B7 q to quit", rows: filteredCandidates().map((candidate) => ({
|
|
735
850
|
id: candidate.id,
|
|
736
851
|
content: _jsx(Text, { children: candidate.label }),
|
|
737
|
-
})), cursor: candidateCursor }));
|
|
852
|
+
})), cursor: candidateCursor, filter: filter }));
|
|
738
853
|
}
|
|
739
854
|
if (screen === "shape-prefer")
|
|
740
855
|
return (_jsx(FleetListScreen, { title: `pick · ${shape}.prefer`, legend: "\u2191\u2193/jk move \u00B7 space add/drop \u00B7 enter apply (empty clears) \u00B7 esc cancel \u00B7 q quit", rows: preferRowsRef.current.map((option) => {
|
|
@@ -742,21 +857,34 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
742
857
|
return { id: option, content: _jsx(Text, { children: `${at === -1 ? "·" : String(at + 1)} ${option}` }) };
|
|
743
858
|
}), cursor: preferCursor }));
|
|
744
859
|
if (screen === "steering") {
|
|
745
|
-
return (_jsx(FleetListScreen, { title: "step 6/6 \u00B7 steering", legend: "\u2191\u2193
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
860
|
+
return (_jsx(FleetListScreen, { title: "step 6/6 \u00B7 steering", legend: "\u2191\u2193 to move \u00B7 f to edit \u00B7 Enter to review \u00B7 Esc/q to quit", rows: [
|
|
861
|
+
...STEERING_KEYS.map((key) => ({
|
|
862
|
+
id: key,
|
|
863
|
+
content: _jsx(Text, { children: `${key}.prefer → ${steering[key]?.join(", ") ?? "(none)"}` }),
|
|
864
|
+
})),
|
|
865
|
+
{
|
|
866
|
+
id: "judge",
|
|
867
|
+
content: _jsx(Text, { children: `judge → ${judgeSeat ?? (initialJudge ? `${initialJudge} (default)` : "(default)")}` }),
|
|
868
|
+
},
|
|
869
|
+
], cursor: steeringCursor, details: notice ? [notice] : [] }));
|
|
870
|
+
}
|
|
871
|
+
if (screen === "judge-pick") {
|
|
872
|
+
const selected = judgeSeat ?? judgeKeepRow;
|
|
873
|
+
return (_jsx(FleetListScreen, { title: "pick \u00B7 judge", legend: "\u2191\u2193 to move \u00B7 Enter to select \u00B7 Type to search \u00B7 Esc to cancel \u00B7 q to quit", rows: filteredJudgeRows().map((label) => ({
|
|
874
|
+
id: label,
|
|
875
|
+
content: (_jsxs(_Fragment, { children: [label === selected ? _jsx(ToggleMark, { active: true }) : _jsx(Text, { children: " " }), _jsx(Text, { children: ` ${label}` })] })),
|
|
876
|
+
})), cursor: judgeCursor, filter: filter }));
|
|
749
877
|
}
|
|
750
878
|
if (screen === "steering-prefer") {
|
|
751
879
|
const which = steeringPickerRef.current;
|
|
752
|
-
return (_jsx(FleetListScreen, { title: `pick · ${which}.prefer`, legend: "\u2191\u2193
|
|
880
|
+
return (_jsx(FleetListScreen, { title: `pick · ${which}.prefer`, legend: "\u2191\u2193 to move \u00B7 Space to add/drop \u00B7 Enter to apply (empty clears) \u00B7 Type to search \u00B7 Esc to cancel \u00B7 q to quit", rows: filteredSteeringRows().map((option) => {
|
|
753
881
|
const at = steeringChainRef.current.indexOf(option);
|
|
754
882
|
return { id: option, content: _jsx(Text, { children: `${at === -1 ? "·" : String(at + 1)} ${option}` }) };
|
|
755
|
-
}), cursor: steeringPickerCursor }));
|
|
883
|
+
}), cursor: steeringPickerCursor, filter: filter }));
|
|
756
884
|
}
|
|
757
885
|
return (_jsx(FleetReviewScreen, { title: "review \u00B7 overlay diff", legend: "y write \u00B7 n discard \u00B7 esc/q quit", diff: review?.diff ?? "" }));
|
|
758
886
|
}
|
|
759
|
-
export async function runFleetInkEditor({ ageMs, adapters, health, initialDenyAdapters, initialDenyModels, modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewOverlay, reloadGuard, initialInput = [], input, output, debug = false, }) {
|
|
887
|
+
export async function runFleetInkEditor({ ageMs, adapters, health, initialDenyAdapters, initialDenyModels, modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewOverlay, reloadGuard, entry = "probe", initialJudge = "", judgeSeats = [], initialInput = [], input, output, debug = false, }) {
|
|
760
888
|
const agents = adapters.flatMap((adapter) => {
|
|
761
889
|
const state = health[adapter.id];
|
|
762
890
|
if (!state?.installed)
|
|
@@ -774,7 +902,7 @@ export async function runFleetInkEditor({ ageMs, adapters, health, initialDenyAd
|
|
|
774
902
|
}));
|
|
775
903
|
const bridgedInput = inkInput(input, initialInput);
|
|
776
904
|
const legacyOutput = typeof output.on !== "function" || typeof output.off !== "function";
|
|
777
|
-
const app = render(_jsx(FleetApp, { ageMs: ageMs, agents: agents, initialDenyAdapters: initialDenyAdapters, initialDenyModels: initialDenyModels, modelGroups: declaredModelGroups, initialMode: initialMode, modeOptions: modeOptions, initialMap: initialMap, modePreview: modePreview, shapeRows: shapeRows, candidatesForShape: candidatesForShape, preferOptionsForShape: preferOptionsForShape, initialSteering: initialSteering, steeringOptionsFor: steeringOptionsFor, reviewOverlay: reviewOverlay, reloadGuard: reloadGuard }), {
|
|
905
|
+
const app = render(_jsx(FleetApp, { ageMs: ageMs, agents: agents, initialDenyAdapters: initialDenyAdapters, initialDenyModels: initialDenyModels, modelGroups: declaredModelGroups, initialMode: initialMode, modeOptions: modeOptions, initialMap: initialMap, modePreview: modePreview, shapeRows: shapeRows, candidatesForShape: candidatesForShape, preferOptionsForShape: preferOptionsForShape, initialSteering: initialSteering, steeringOptionsFor: steeringOptionsFor, reviewOverlay: reviewOverlay, reloadGuard: reloadGuard, entry: entry, initialJudge: initialJudge, judgeSeats: judgeSeats }), {
|
|
778
906
|
// FleetIO's injected stream predates Ink and did not require ref/unref.
|
|
779
907
|
// Real terminal streams pass through unchanged; the compatibility facade
|
|
780
908
|
// adds only those lifecycle methods and leaves input decoding to Ink.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InitConfigOverlay } from "../../config/config.js";
|
|
2
|
+
type Driver = NonNullable<InitConfigOverlay["driver"]>;
|
|
3
|
+
type VisibilityLlm = NonNullable<NonNullable<InitConfigOverlay["visibility"]>["llm"]>;
|
|
4
|
+
export type InitWizardFields = {
|
|
5
|
+
driver: Driver;
|
|
6
|
+
concurrency: number;
|
|
7
|
+
visibilityLlm: VisibilityLlm;
|
|
8
|
+
offerSkills: boolean;
|
|
9
|
+
skillsDefault: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type InitWizardResult = {
|
|
12
|
+
kind: "continue";
|
|
13
|
+
overlay: {
|
|
14
|
+
driver: Driver;
|
|
15
|
+
concurrency: number;
|
|
16
|
+
visibility: {
|
|
17
|
+
llm: VisibilityLlm;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
installSkills: boolean;
|
|
21
|
+
installDocs: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "quit";
|
|
24
|
+
};
|
|
25
|
+
export declare function InitWizardApp({ fields }: {
|
|
26
|
+
fields: InitWizardFields;
|
|
27
|
+
}): import("react").JSX.Element;
|
|
28
|
+
export declare function runInitWizardApp(opts: {
|
|
29
|
+
fields: InitWizardFields;
|
|
30
|
+
input: NodeJS.ReadStream;
|
|
31
|
+
output: NodeJS.WriteStream;
|
|
32
|
+
initialInput?: string[];
|
|
33
|
+
}): Promise<InitWizardResult>;
|
|
34
|
+
export {};
|