tickmarkr 1.90.6 → 1.90.8
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.d.ts +3 -0
- package/dist/cli/commands/doctor.js +30 -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 -45
- 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 +178 -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
|
}
|
|
@@ -257,6 +314,15 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
257
314
|
showScreen("models");
|
|
258
315
|
return;
|
|
259
316
|
}
|
|
317
|
+
// v1.90.8 (operator field report): inside the init journey, one Esc must never discard the
|
|
318
|
+
// whole walk — from any walk screen it returns HOME to the presets screen; Esc there (or
|
|
319
|
+
// `q`/ctrl+c anywhere) remains the real quit. Sub-screen Escs above keep their tighter backs.
|
|
320
|
+
if (key.escape && entry === "presets" && screenRef.current !== "modes") {
|
|
321
|
+
setReview(null);
|
|
322
|
+
presetPickRef.current = true;
|
|
323
|
+
showScreen("modes");
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
260
326
|
const typing = screenRef.current === "provenance" || screenRef.current === "add-model";
|
|
261
327
|
if (key.escape || (!typing && input === "q") || (key.ctrl && input === "c")) {
|
|
262
328
|
finish({ kind: "quit" });
|
|
@@ -304,7 +370,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
304
370
|
return;
|
|
305
371
|
}
|
|
306
372
|
if (screenRef.current === "models") {
|
|
307
|
-
const rows =
|
|
373
|
+
const rows = filteredModelRows();
|
|
308
374
|
if (key.downArrow || input === "j") {
|
|
309
375
|
const next = Math.min(modelCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
310
376
|
modelCursorRef.current = next;
|
|
@@ -354,10 +420,16 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
354
420
|
setModelGroup(next);
|
|
355
421
|
modelCursorRef.current = 0;
|
|
356
422
|
setModelCursor(0);
|
|
423
|
+
filterRef.current = "";
|
|
424
|
+
setFilter("");
|
|
357
425
|
}
|
|
358
426
|
else {
|
|
359
427
|
showScreen("modes");
|
|
360
428
|
}
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
if (filterInput((f) => filteredModelRows(f).length, modelCursorRef, setModelCursor, input, key)) {
|
|
432
|
+
setNotice("");
|
|
361
433
|
}
|
|
362
434
|
return;
|
|
363
435
|
}
|
|
@@ -464,9 +536,11 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
464
536
|
}
|
|
465
537
|
}
|
|
466
538
|
if (screenRef.current === "modes") {
|
|
539
|
+
// preset entry adds one final `custom` row after the modes — the full-walk escape hatch
|
|
540
|
+
const rowCount = modeOptions.length + (presetPickRef.current ? 1 : 0);
|
|
467
541
|
const currentModeCursor = modeCursorRef.current ?? 0;
|
|
468
542
|
if (key.downArrow || input === "j") {
|
|
469
|
-
const next = Math.min(currentModeCursor + 1, Math.max(
|
|
543
|
+
const next = Math.min(currentModeCursor + 1, Math.max(rowCount - 1, 0));
|
|
470
544
|
modeCursorRef.current = next;
|
|
471
545
|
setModeCursor(next);
|
|
472
546
|
return;
|
|
@@ -477,8 +551,20 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
477
551
|
setModeCursor(next);
|
|
478
552
|
return;
|
|
479
553
|
}
|
|
480
|
-
if (key.return
|
|
554
|
+
if (key.return) {
|
|
555
|
+
if (presetPickRef.current && currentModeCursor === modeOptions.length) {
|
|
556
|
+
presetPickRef.current = false;
|
|
557
|
+
showScreen("agents");
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
if (!modeOptions[currentModeCursor])
|
|
561
|
+
return;
|
|
481
562
|
selectedModeRef.current = modeOptions[currentModeCursor].id;
|
|
563
|
+
if (presetPickRef.current) {
|
|
564
|
+
// entry context: a preset pick goes straight to the diff confirm
|
|
565
|
+
goReview();
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
482
568
|
showScreen("shapes");
|
|
483
569
|
}
|
|
484
570
|
return;
|
|
@@ -527,8 +613,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
527
613
|
return;
|
|
528
614
|
}
|
|
529
615
|
if (screenRef.current === "candidates") {
|
|
616
|
+
const rows = filteredCandidates();
|
|
530
617
|
if (key.downArrow || input === "j") {
|
|
531
|
-
const next = Math.min(candidateCursorRef.current + 1, Math.max(
|
|
618
|
+
const next = Math.min(candidateCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
532
619
|
candidateCursorRef.current = next;
|
|
533
620
|
setCandidateCursor(next);
|
|
534
621
|
return;
|
|
@@ -539,16 +626,18 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
539
626
|
setCandidateCursor(next);
|
|
540
627
|
return;
|
|
541
628
|
}
|
|
542
|
-
if (key.return &&
|
|
629
|
+
if (key.return && rows[candidateCursorRef.current]) {
|
|
543
630
|
const shape = shapeRows(selectedModeRef.current, stagedMap())[shapeCursorRef.current]?.id;
|
|
544
631
|
if (shape) {
|
|
545
|
-
const picked =
|
|
632
|
+
const picked = rows[candidateCursorRef.current];
|
|
546
633
|
const nextMap = { ...stagedMap(), [shape]: { pin: picked.pin } };
|
|
547
634
|
mapRef.current = nextMap;
|
|
548
635
|
setMap(nextMap);
|
|
549
636
|
}
|
|
550
637
|
showScreen("shapes");
|
|
638
|
+
return;
|
|
551
639
|
}
|
|
640
|
+
filterInput((f) => filteredCandidates(f).length, candidateCursorRef, setCandidateCursor, input, key);
|
|
552
641
|
return;
|
|
553
642
|
}
|
|
554
643
|
if (screenRef.current === "shape-prefer") {
|
|
@@ -591,8 +680,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
591
680
|
return;
|
|
592
681
|
}
|
|
593
682
|
if (screenRef.current === "steering") {
|
|
683
|
+
// review.prefer + consult.prefer rows plus the single judge seat as the final row
|
|
594
684
|
if (key.downArrow || input === "j") {
|
|
595
|
-
const next = Math.min(steeringCursorRef.current + 1, STEERING_KEYS.length
|
|
685
|
+
const next = Math.min(steeringCursorRef.current + 1, STEERING_KEYS.length);
|
|
596
686
|
steeringCursorRef.current = next;
|
|
597
687
|
setSteeringCursor(next);
|
|
598
688
|
return;
|
|
@@ -604,6 +694,13 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
604
694
|
return;
|
|
605
695
|
}
|
|
606
696
|
if (input === "f") {
|
|
697
|
+
if (steeringCursorRef.current === STEERING_KEYS.length) {
|
|
698
|
+
judgeCursorRef.current = 0;
|
|
699
|
+
setJudgeCursor(0);
|
|
700
|
+
setNotice("");
|
|
701
|
+
showScreen("judge-pick");
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
607
704
|
const which = STEERING_KEYS[steeringCursorRef.current];
|
|
608
705
|
const current = steeringRef.current?.[which] ?? [];
|
|
609
706
|
steeringPickerRef.current = which;
|
|
@@ -615,22 +712,40 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
615
712
|
showScreen("steering-prefer");
|
|
616
713
|
return;
|
|
617
714
|
}
|
|
618
|
-
if (key.return)
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
715
|
+
if (key.return)
|
|
716
|
+
goReview();
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
if (screenRef.current === "judge-pick") {
|
|
720
|
+
const rows = filteredJudgeRows();
|
|
721
|
+
if (key.downArrow || input === "j") {
|
|
722
|
+
const next = Math.min(judgeCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
723
|
+
judgeCursorRef.current = next;
|
|
724
|
+
setJudgeCursor(next);
|
|
725
|
+
return;
|
|
628
726
|
}
|
|
727
|
+
if (key.upArrow || input === "k") {
|
|
728
|
+
const next = Math.max(judgeCursorRef.current - 1, 0);
|
|
729
|
+
judgeCursorRef.current = next;
|
|
730
|
+
setJudgeCursor(next);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
if (key.return && rows[judgeCursorRef.current]) {
|
|
734
|
+
// single-select: one seat or back to the config default — never a chain
|
|
735
|
+
const picked = rows[judgeCursorRef.current];
|
|
736
|
+
const seat = picked === judgeKeepRow ? null : picked;
|
|
737
|
+
judgeSeatRef.current = seat;
|
|
738
|
+
setJudgeSeat(seat);
|
|
739
|
+
showScreen("steering");
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
filterInput((f) => filteredJudgeRows(f).length, judgeCursorRef, setJudgeCursor, input, key);
|
|
629
743
|
return;
|
|
630
744
|
}
|
|
631
745
|
if (screenRef.current === "steering-prefer") {
|
|
746
|
+
const rows = filteredSteeringRows();
|
|
632
747
|
if (key.downArrow || input === "j") {
|
|
633
|
-
const next = Math.min(steeringPickerCursorRef.current + 1, Math.max(
|
|
748
|
+
const next = Math.min(steeringPickerCursorRef.current + 1, Math.max(rows.length - 1, 0));
|
|
634
749
|
steeringPickerCursorRef.current = next;
|
|
635
750
|
setSteeringPickerCursor(next);
|
|
636
751
|
return;
|
|
@@ -641,8 +756,8 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
641
756
|
setSteeringPickerCursor(next);
|
|
642
757
|
return;
|
|
643
758
|
}
|
|
644
|
-
if (input === " " &&
|
|
645
|
-
const option =
|
|
759
|
+
if (input === " " && rows[steeringPickerCursorRef.current]) {
|
|
760
|
+
const option = rows[steeringPickerCursorRef.current];
|
|
646
761
|
const at = steeringChainRef.current.indexOf(option);
|
|
647
762
|
if (at === -1)
|
|
648
763
|
steeringChainRef.current.push(option);
|
|
@@ -661,7 +776,9 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
661
776
|
setSteering(next);
|
|
662
777
|
setNotice("");
|
|
663
778
|
showScreen("steering");
|
|
779
|
+
return;
|
|
664
780
|
}
|
|
781
|
+
filterInput((f) => filteredSteeringRows(f).length, steeringPickerCursorRef, setSteeringPickerCursor, input, key);
|
|
665
782
|
return;
|
|
666
783
|
}
|
|
667
784
|
if (screenRef.current === "review") {
|
|
@@ -675,7 +792,7 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
675
792
|
setNotice(`fleet: config loader rejects the proposed overlay — ${loadError}`);
|
|
676
793
|
reviewRef.current = null;
|
|
677
794
|
setReview(null);
|
|
678
|
-
showScreen("steering");
|
|
795
|
+
showScreen(presetPickRef.current ? "modes" : "steering");
|
|
679
796
|
return;
|
|
680
797
|
}
|
|
681
798
|
finish({ kind: "write", review: reviewRef.current });
|
|
@@ -699,16 +816,15 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
699
816
|
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
817
|
}
|
|
701
818
|
const group = enabledModelGroups()[modelGroup];
|
|
702
|
-
const modelRows = currentModelRows();
|
|
703
819
|
if (screen === "models") {
|
|
704
|
-
const rows =
|
|
820
|
+
const rows = filteredModelRows().map((row) => {
|
|
705
821
|
const denied = group ? denyModels.has(`${group.adapter}:${row.model}`) : false;
|
|
706
822
|
return {
|
|
707
823
|
id: row.model,
|
|
708
824
|
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
825
|
};
|
|
710
826
|
});
|
|
711
|
-
return (_jsx(FleetListScreen, { title: `step 3/6 · models · ${group?.adapter ?? ""}`, legend: "\u2191\u2193
|
|
827
|
+
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
828
|
}
|
|
713
829
|
if (screen === "add-model")
|
|
714
830
|
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 +836,18 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
720
836
|
if (screen === "provenance")
|
|
721
837
|
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
838
|
if (screen === "modes") {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
})
|
|
839
|
+
const presetPick = presetPickRef.current;
|
|
840
|
+
const rows = modeOptions.map((option) => ({
|
|
841
|
+
id: option.id,
|
|
842
|
+
content: (_jsxs(_Fragment, { children: [option.id === initialMode ? _jsx(ToggleMark, { active: true }) : _jsx(Text, { children: " " }), _jsx(Text, { children: ` ${option.id.padEnd(11)} ${option.gloss}` })] })),
|
|
843
|
+
}));
|
|
844
|
+
if (presetPick) {
|
|
845
|
+
rows.push({
|
|
846
|
+
id: "custom",
|
|
847
|
+
content: (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { children: ` ${"custom".padEnd(11)} walk the full editor (agents → models → shapes → seats)` })] })),
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
return (_jsx(FleetListScreen, { title: presetPick ? "tickmarkr init · act 3 of 3 — fleet · routing presets" : "step 4/6 · routing mode", legend: presetPick ? "↑↓ to move · Enter to apply preset · Enter on custom to walk the editor · Esc inside the walk returns here · Esc here closes" : "↑↓/jk move · enter select · esc/q quit", rows: rows, cursor: modeCursor, details: modeOptions[modeCursor] ? modePreview(modeOptions[modeCursor].id, map) : [] }));
|
|
727
851
|
}
|
|
728
852
|
const renderedShapes = shapeRows(selectedModeRef.current, map);
|
|
729
853
|
if (screen === "shapes") {
|
|
@@ -731,10 +855,10 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
731
855
|
}
|
|
732
856
|
const shape = renderedShapes[shapeCursor]?.id;
|
|
733
857
|
if (screen === "candidates") {
|
|
734
|
-
return (_jsx(FleetListScreen, { title: `pick · ${shape}`, legend: "\u2191\u2193
|
|
858
|
+
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
859
|
id: candidate.id,
|
|
736
860
|
content: _jsx(Text, { children: candidate.label }),
|
|
737
|
-
})), cursor: candidateCursor }));
|
|
861
|
+
})), cursor: candidateCursor, filter: filter }));
|
|
738
862
|
}
|
|
739
863
|
if (screen === "shape-prefer")
|
|
740
864
|
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 +866,34 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
742
866
|
return { id: option, content: _jsx(Text, { children: `${at === -1 ? "·" : String(at + 1)} ${option}` }) };
|
|
743
867
|
}), cursor: preferCursor }));
|
|
744
868
|
if (screen === "steering") {
|
|
745
|
-
return (_jsx(FleetListScreen, { title: "step 6/6 \u00B7 steering", legend: "\u2191\u2193
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
869
|
+
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: [
|
|
870
|
+
...STEERING_KEYS.map((key) => ({
|
|
871
|
+
id: key,
|
|
872
|
+
content: _jsx(Text, { children: `${key}.prefer → ${steering[key]?.join(", ") ?? "(none)"}` }),
|
|
873
|
+
})),
|
|
874
|
+
{
|
|
875
|
+
id: "judge",
|
|
876
|
+
content: _jsx(Text, { children: `judge → ${judgeSeat ?? (initialJudge ? `${initialJudge} (default)` : "(default)")}` }),
|
|
877
|
+
},
|
|
878
|
+
], cursor: steeringCursor, details: notice ? [notice] : [] }));
|
|
879
|
+
}
|
|
880
|
+
if (screen === "judge-pick") {
|
|
881
|
+
const selected = judgeSeat ?? judgeKeepRow;
|
|
882
|
+
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) => ({
|
|
883
|
+
id: label,
|
|
884
|
+
content: (_jsxs(_Fragment, { children: [label === selected ? _jsx(ToggleMark, { active: true }) : _jsx(Text, { children: " " }), _jsx(Text, { children: ` ${label}` })] })),
|
|
885
|
+
})), cursor: judgeCursor, filter: filter }));
|
|
749
886
|
}
|
|
750
887
|
if (screen === "steering-prefer") {
|
|
751
888
|
const which = steeringPickerRef.current;
|
|
752
|
-
return (_jsx(FleetListScreen, { title: `pick · ${which}.prefer`, legend: "\u2191\u2193
|
|
889
|
+
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
890
|
const at = steeringChainRef.current.indexOf(option);
|
|
754
891
|
return { id: option, content: _jsx(Text, { children: `${at === -1 ? "·" : String(at + 1)} ${option}` }) };
|
|
755
|
-
}), cursor: steeringPickerCursor }));
|
|
892
|
+
}), cursor: steeringPickerCursor, filter: filter }));
|
|
756
893
|
}
|
|
757
894
|
return (_jsx(FleetReviewScreen, { title: "review \u00B7 overlay diff", legend: "y write \u00B7 n discard \u00B7 esc/q quit", diff: review?.diff ?? "" }));
|
|
758
895
|
}
|
|
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, }) {
|
|
896
|
+
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
897
|
const agents = adapters.flatMap((adapter) => {
|
|
761
898
|
const state = health[adapter.id];
|
|
762
899
|
if (!state?.installed)
|
|
@@ -774,7 +911,7 @@ export async function runFleetInkEditor({ ageMs, adapters, health, initialDenyAd
|
|
|
774
911
|
}));
|
|
775
912
|
const bridgedInput = inkInput(input, initialInput);
|
|
776
913
|
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 }), {
|
|
914
|
+
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
915
|
// FleetIO's injected stream predates Ink and did not require ref/unref.
|
|
779
916
|
// Real terminal streams pass through unchanged; the compatibility facade
|
|
780
917
|
// 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 {};
|