tickmarkr 2.6.1 → 2.6.2
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 +14 -3
- package/dist/adapters/catalog-remote.js +89 -47
- package/dist/adapters/claude-code.js +9 -6
- package/dist/adapters/codex.js +7 -4
- package/dist/adapters/prompt.d.ts +1 -0
- package/dist/adapters/prompt.js +14 -6
- package/dist/adapters/registry.js +3 -3
- package/dist/adapters/types.d.ts +12 -4
- package/dist/adapters/types.js +6 -0
- package/dist/cli/commands/approve.d.ts +5 -1
- package/dist/cli/commands/approve.js +66 -23
- package/dist/cli/commands/compile.js +13 -3
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +11 -3
- package/dist/cli/commands/fleet.js +45 -7
- package/dist/cli/commands/report.js +18 -2
- package/dist/cli/commands/resume.js +4 -2
- package/dist/cli/commands/status.js +24 -19
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.js +9 -2
- package/dist/config/config.d.ts +20 -0
- package/dist/config/config.js +47 -8
- package/dist/config/fleet-overlay.d.ts +1 -0
- package/dist/config/fleet-overlay.js +56 -0
- package/dist/drivers/orca.d.ts +26 -1
- package/dist/drivers/orca.js +193 -60
- package/dist/eval/canary.d.ts +2 -1
- package/dist/eval/canary.js +2 -2
- package/dist/eval/dispatch.js +1 -0
- package/dist/gates/acceptance.d.ts +2 -1
- package/dist/gates/acceptance.js +7 -2
- package/dist/gates/baseline.d.ts +12 -1
- package/dist/gates/baseline.js +11 -4
- package/dist/gates/llm.d.ts +5 -4
- package/dist/gates/llm.js +13 -13
- package/dist/gates/review.d.ts +8 -0
- package/dist/gates/review.js +40 -4
- package/dist/gates/run-gates.d.ts +2 -1
- package/dist/gates/run-gates.js +27 -13
- package/dist/gates/test-manifest.d.ts +3 -1
- package/dist/gates/test-manifest.js +9 -2
- package/dist/graph/schema.d.ts +2 -0
- package/dist/graph/schema.js +2 -0
- package/dist/plan/scope.js +2 -2
- package/dist/route/preference.d.ts +20 -2
- package/dist/route/preference.js +48 -13
- package/dist/route/router.js +30 -15
- package/dist/run/consult.d.ts +13 -1
- package/dist/run/consult.js +14 -5
- package/dist/run/daemon.d.ts +37 -2
- package/dist/run/daemon.js +579 -141
- package/dist/run/git.d.ts +8 -0
- package/dist/run/git.js +14 -0
- package/dist/run/journal.d.ts +126 -3
- package/dist/run/journal.js +410 -37
- package/dist/run/merge.d.ts +3 -1
- package/dist/run/merge.js +3 -2
- package/dist/run/operator-summary.d.ts +3 -0
- package/dist/run/operator-summary.js +3 -1
- package/dist/run/protocol.d.ts +31 -1
- package/dist/run/protocol.js +3 -1
- package/dist/run/supervision.d.ts +7 -1
- package/dist/run/supervision.js +5 -2
- package/dist/tui/cockpit/board.js +3 -3
- package/dist/tui/cockpit/decision-actions.d.ts +8 -5
- package/dist/tui/cockpit/decision-actions.js +55 -32
- package/dist/tui/cockpit/derive.js +13 -2
- package/dist/tui/cockpit/live-runtime.d.ts +10 -0
- package/dist/tui/cockpit/live-runtime.js +50 -3
- package/dist/tui/cockpit/run-cockpit.d.ts +3 -0
- package/dist/tui/cockpit/run-cockpit.js +26 -1
- package/dist/tui/cockpit/run-view.d.ts +9 -3
- package/dist/tui/cockpit/run-view.js +60 -7
- package/dist/tui/cockpit/setup-cockpit.d.ts +4 -0
- package/dist/tui/cockpit/setup-cockpit.js +6 -3
- package/dist/tui/ink/fleet-app.d.ts +15 -3
- package/dist/tui/ink/fleet-app.js +91 -22
- package/package.json +2 -1
- package/schema/config.schema.json +818 -0
- package/skills/tickmarkr-loop/SKILL.md +8 -2
- package/skills/tickmarkr-overseer/SKILL.md +42 -0
- package/skills/tickmarkr-overseer/scripts/classify-vitest-log.sh +88 -0
- package/skills/tickmarkr-overseer/scripts/context-statusline.sh +81 -0
- package/skills/tickmarkr-overseer/scripts/grade-ci.sh +36 -34
- package/skills/tickmarkr-overseer/scripts/watch-journal.sh +6 -4
|
@@ -3,12 +3,13 @@ import { Box, render, Text, useApp, useInput } from "ink";
|
|
|
3
3
|
import { useRef, useState } from "react";
|
|
4
4
|
import { MODEL_ID_RE } from "../../adapters/types.js";
|
|
5
5
|
import { retiredModelReason } from "../../adapters/model-lints.js";
|
|
6
|
-
import { DENY_SCOPES, denyBlockFrom, denyEntriesAt, initialDenyPropOf, stagedDenyKeyOf } from "../../config/config.js";
|
|
6
|
+
import { DENY_SCOPES, EFFORT_ADAPTERS, denyBlockFrom, denyEntriesAt, initialDenyPropOf, stagedDenyKeyOf } from "../../config/config.js";
|
|
7
7
|
import { fleetFirstTouchProvenance } from "../../config/fleet-overlay.js";
|
|
8
8
|
import { exclusionReason } from "../../config/fleet-why.js";
|
|
9
9
|
import { entryMatchesChannel, exclusionCollector } from "../../route/preference.js";
|
|
10
|
-
import { TIERS } from "../../graph/schema.js";
|
|
10
|
+
import { EFFORTS, TIERS } from "../../graph/schema.js";
|
|
11
11
|
import { windowRows } from "./components.js";
|
|
12
|
+
import { wrapCells } from "../cockpit/width.js";
|
|
12
13
|
import { clip, clipPathTail, ElisionMark, enterAltScreen, fmtCtx, fmtMs, fmtUsdPair, Glyph, INK, inkInput, inkOutput, KeyBar, OverlayPanel, padCell, padCellStart, Pointer, SearchRow, } from "./frame.js";
|
|
13
14
|
const STEERING_KEYS = ["review", "consult"];
|
|
14
15
|
/** every scope's staged list, empty — the "every policy scope open" probe the picker lifts against */
|
|
@@ -31,12 +32,18 @@ function splitSeat(seat) {
|
|
|
31
32
|
const at = seat.indexOf(":");
|
|
32
33
|
return { adapter: seat.slice(0, at), model: seat.slice(at + 1) };
|
|
33
34
|
}
|
|
35
|
+
// a picker ledger row is labelled "adapter/model — …" (fleet.ts channelLedger); this is its seat id
|
|
36
|
+
function ledgerChannelId(line) {
|
|
37
|
+
const head = line.split(" — ")[0];
|
|
38
|
+
const slash = head.indexOf("/");
|
|
39
|
+
return slash === -1 ? undefined : `${head.slice(0, slash)}:${head.slice(slash + 1)}`;
|
|
40
|
+
}
|
|
34
41
|
const REACH_CHOICES = [
|
|
35
42
|
{ id: "in", label: "in", gloss: "every seat may route here" },
|
|
36
43
|
{ id: "out-workers", label: "out · workers", gloss: "workers skip it; judge/review/consult unaffected" },
|
|
37
44
|
{ id: "out-all", label: "out · all seats", gloss: "no seat routes here" },
|
|
38
45
|
];
|
|
39
|
-
export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewOverlay, reloadGuard, stagedRouting, entry = "probe", initialJudge = "", judgeSeats = [], viewRows = Number.POSITIVE_INFINITY, frameColumns = 100, frameRows, ...initialDenyProps }) {
|
|
46
|
+
export function FleetApp({ ageMs, agents, initialAllowOut = [], initialEfforts = {}, modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewAdvisories = [], reviewOverlay, reloadGuard, stagedRouting, entry = "probe", initialJudge = "", judgeSeats = [], viewRows = Number.POSITIVE_INFINITY, frameColumns = 100, frameRows, ...initialDenyProps }) {
|
|
40
47
|
const { exit } = useApp();
|
|
41
48
|
const [, setRevision] = useState(0);
|
|
42
49
|
// the props are the fleet command's contract, one per schema-enumerated scope (initialDeny…),
|
|
@@ -60,6 +67,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
60
67
|
allowOut: new Set(initialAllowOut),
|
|
61
68
|
...Object.fromEntries(DENY_SCOPES.map((scope) => [scope.key, new Set(initialDeny[scope.key])])),
|
|
62
69
|
classifications: [],
|
|
70
|
+
efforts: structuredClone(initialEfforts),
|
|
63
71
|
selectedMode: initialMode,
|
|
64
72
|
map: structuredClone(initialMap),
|
|
65
73
|
steering: structuredClone(initialSteering),
|
|
@@ -100,6 +108,12 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
100
108
|
if (JSON.stringify(ui.steering[key]) !== JSON.stringify(initialSteering[key]))
|
|
101
109
|
n += 1;
|
|
102
110
|
}
|
|
111
|
+
for (const adapter of new Set([...Object.keys(initialEfforts), ...Object.keys(ui.efforts)])) {
|
|
112
|
+
for (const model of new Set([...Object.keys(initialEfforts[adapter] ?? {}), ...Object.keys(ui.efforts[adapter] ?? {})])) {
|
|
113
|
+
if (initialEfforts[adapter]?.[model] !== ui.efforts[adapter]?.[model])
|
|
114
|
+
n += 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
103
117
|
return n;
|
|
104
118
|
};
|
|
105
119
|
// ── derived data ───────────────────────────────────────────────────────────
|
|
@@ -367,6 +381,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
367
381
|
}),
|
|
368
382
|
}
|
|
369
383
|
: classification),
|
|
384
|
+
efforts: structuredClone(ui.efforts),
|
|
370
385
|
selectedMode: ui.selectedMode,
|
|
371
386
|
map: ui.map,
|
|
372
387
|
...(ui.judgeSeat ? { judgeSeat: splitSeat(ui.judgeSeat) } : {}),
|
|
@@ -704,10 +719,9 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
704
719
|
// same picker reopens over the recomputed policy — a shared or adapter-wide entry is refused by
|
|
705
720
|
// name and the row stays greyed
|
|
706
721
|
const liftFromPicker = (overlay, line) => {
|
|
707
|
-
const
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
: displayedChannels().find((channel) => channel.adapter === head.slice(0, slash) && channel.model === head.slice(slash + 1));
|
|
722
|
+
const lineId = ledgerChannelId(line);
|
|
723
|
+
const self = lineId === undefined ? undefined
|
|
724
|
+
: displayedChannels().find((channel) => `${channel.adapter}:${channel.model}` === lineId);
|
|
711
725
|
if (!self) {
|
|
712
726
|
ui.notice = `nothing to lift on this row — ${line}`;
|
|
713
727
|
bump();
|
|
@@ -747,7 +761,12 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
747
761
|
bump();
|
|
748
762
|
};
|
|
749
763
|
const reviewWindow = (overlay) => {
|
|
750
|
-
|
|
764
|
+
// OBS-1144: notes are pre-wrapped to the diff's width and lead the SAME scrolled buffer, so a
|
|
765
|
+
// note never sits past the terminal's last row, unreachable, while y still saves.
|
|
766
|
+
const notes = (overlay.review.notes ?? [])
|
|
767
|
+
.flatMap((note) => wrapCells(`! ${note}`, bodyW - 6, { continuationPrefix: " " }))
|
|
768
|
+
.map((text) => ({ text, note: true }));
|
|
769
|
+
const lines = [...notes, ...overlay.review.diff.split("\n").map((text) => ({ text, note: false }))];
|
|
751
770
|
const cap = reviewCapacity();
|
|
752
771
|
const maxScroll = Math.max(lines.length - cap, 0);
|
|
753
772
|
const scroll = Math.min(Math.max(overlay.scroll, 0), maxScroll);
|
|
@@ -1059,16 +1078,39 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1059
1078
|
bump();
|
|
1060
1079
|
return;
|
|
1061
1080
|
}
|
|
1062
|
-
if (input === " "
|
|
1063
|
-
const
|
|
1081
|
+
if (input === " ") {
|
|
1082
|
+
const offered = rows[overlay.at];
|
|
1083
|
+
const greyed = offered ? undefined : ledger[overlay.at - rows.length];
|
|
1084
|
+
const id = offered?.id ?? (greyed === undefined ? undefined : ledgerChannelId(greyed));
|
|
1085
|
+
if (id === undefined)
|
|
1086
|
+
return;
|
|
1064
1087
|
const at = overlay.chain.indexOf(id);
|
|
1065
|
-
|
|
1088
|
+
// OBS-1145 add.1: Space drops ANY carried member, admitted or not, and leaves its deny
|
|
1089
|
+
// alone; only an offered row joins — a greyed one still enters through its reach (Enter)
|
|
1090
|
+
if (at !== -1)
|
|
1091
|
+
overlay.chain.splice(at, 1);
|
|
1092
|
+
else if (offered)
|
|
1066
1093
|
overlay.chain.push(id);
|
|
1067
1094
|
else
|
|
1068
|
-
|
|
1095
|
+
ui.notice = `${id} is not offered — Enter lifts it first; Space pools offered rows only`;
|
|
1069
1096
|
bump();
|
|
1070
1097
|
return;
|
|
1071
1098
|
}
|
|
1099
|
+
// a selection is a POOL, and its mode is a decision, not a default — the tiny
|
|
1100
|
+
// poolmode overlay asks it; Esc there restores this picker with the chain intact
|
|
1101
|
+
// OBS-525: an existing pool's mode seeds the cursor so a round-trip keeps it
|
|
1102
|
+
const askPoolMode = () => setOverlay({ kind: "poolmode", picker: overlay, at: ui.map[overlay.shape]?.pool?.mode === "ordered" ? 1 : 0 });
|
|
1103
|
+
// OBS-1145 add.1: Tab applies the chain from ANY row — in an all-greyed picker every row is
|
|
1104
|
+
// ✗ and Enter lifts it, so a Space drop there had no commit path; Tab lifts no deny
|
|
1105
|
+
if (key.tab) {
|
|
1106
|
+
if (overlay.chain.length)
|
|
1107
|
+
askPoolMode();
|
|
1108
|
+
else {
|
|
1109
|
+
ui.notice = `the ${overlay.shape} pool is empty — Esc keeps it; a on the shape reverts it to auto`;
|
|
1110
|
+
bump();
|
|
1111
|
+
}
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1072
1114
|
if (key.return) {
|
|
1073
1115
|
const greyed = ledger[overlay.at - rows.length];
|
|
1074
1116
|
if (!rows[overlay.at] && greyed !== undefined) {
|
|
@@ -1076,10 +1118,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1076
1118
|
return;
|
|
1077
1119
|
}
|
|
1078
1120
|
if (overlay.chain.length) {
|
|
1079
|
-
|
|
1080
|
-
// poolmode overlay asks it; Esc there restores this picker with the chain intact
|
|
1081
|
-
// OBS-525: an existing pool's mode seeds the cursor so a round-trip keeps it
|
|
1082
|
-
setOverlay({ kind: "poolmode", picker: overlay, at: ui.map[overlay.shape]?.pool?.mode === "ordered" ? 1 : 0 });
|
|
1121
|
+
askPoolMode();
|
|
1083
1122
|
return;
|
|
1084
1123
|
}
|
|
1085
1124
|
if (rows[overlay.at]) {
|
|
@@ -1448,6 +1487,29 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1448
1487
|
setOverlay({ kind: "lift", id: `${row.adapter}:${row.model}`, covering: row.covering });
|
|
1449
1488
|
return;
|
|
1450
1489
|
}
|
|
1490
|
+
if (hotkey === "e" && row) {
|
|
1491
|
+
// OBS-1182: e cycles launch effort default → low → medium → high → default; the seat's
|
|
1492
|
+
// identity (adapter:model) never changes, only tiers.<adapter>.modelOverrides.<model>.effort
|
|
1493
|
+
if (!EFFORT_ADAPTERS.includes(row.adapter)) {
|
|
1494
|
+
ui.notice = `${row.adapter} takes no effort level — effort is launch metadata only ${EFFORT_ADAPTERS.join(" and ")} accept`;
|
|
1495
|
+
}
|
|
1496
|
+
else if (!row.tier) {
|
|
1497
|
+
ui.notice = `${row.adapter}:${row.model} is unclassified — classify it before setting its effort`;
|
|
1498
|
+
}
|
|
1499
|
+
else {
|
|
1500
|
+
const current = ui.efforts[row.adapter]?.[row.model];
|
|
1501
|
+
const next = EFFORTS[current === undefined ? 0 : EFFORTS.indexOf(current) + 1];
|
|
1502
|
+
const models = { ...ui.efforts[row.adapter] };
|
|
1503
|
+
if (next === undefined)
|
|
1504
|
+
delete models[row.model];
|
|
1505
|
+
else
|
|
1506
|
+
models[row.model] = next;
|
|
1507
|
+
ui.efforts = { ...ui.efforts, [row.adapter]: models };
|
|
1508
|
+
ui.notice = `${row.adapter}:${row.model} effort → ${next ?? "CLI default"} — w writes tiers.${row.adapter}.modelOverrides.${row.model}.effort`;
|
|
1509
|
+
}
|
|
1510
|
+
bump();
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1451
1513
|
if (hotkey === "t" && row) {
|
|
1452
1514
|
if (row.tier) {
|
|
1453
1515
|
ui.notice = "tier reassignment on classified models is not supported in v1 — edit config directly";
|
|
@@ -1657,6 +1719,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1657
1719
|
const parts = [
|
|
1658
1720
|
`${row.adapter}:${row.model}`,
|
|
1659
1721
|
row.tier ?? "unclassified",
|
|
1722
|
+
ui.efforts[row.adapter]?.[row.model] ? `effort ${ui.efforts[row.adapter][row.model]}` : "",
|
|
1660
1723
|
ui.lastEdit?.id === `${row.adapter}:${row.model}` ? ui.lastEdit.text : "",
|
|
1661
1724
|
identityDetail(row),
|
|
1662
1725
|
row.tier ? reachDetail(row) : "",
|
|
@@ -1734,7 +1797,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1734
1797
|
if (overlay.kind === "review") {
|
|
1735
1798
|
const { visible, scroll, cap, lines } = reviewWindow(overlay);
|
|
1736
1799
|
const below = lines.length - scroll - visible.length;
|
|
1737
|
-
return (_jsxs(OverlayPanel, { title: `review · ${overlay.review.path}`, width: bodyW, children: [_jsx(Text, { dimColor: true, wrap: "truncate", children: clip("everything staged lands in this one diff — y writes, n discards, ↑↓ scroll, Esc keeps editing", bodyW - 4) }), scroll > 0 && _jsx(ElisionMark, { count: scroll, side: "above" }), visible.map((line, index) => (_jsx(Text, { wrap: "truncate", color: line.startsWith("+") ? INK.brand : line.startsWith("-") ? INK.fail : undefined, dimColor: line.startsWith("@") || line.startsWith("---") || line.startsWith("+++"), children: clip(line, bodyW - 6) || " " }, `${scroll + index}:${line}`))), below > 0 && _jsx(ElisionMark, { count: below, side: "below", hint: `↓ scrolls · PgDn jumps ${cap} lines` })] }));
|
|
1800
|
+
return (_jsxs(OverlayPanel, { title: clipPathTail(`review · ${overlay.review.path}`, bodyW - 4), width: bodyW, children: [_jsx(Text, { dimColor: true, wrap: "truncate", children: clip("everything staged lands in this one diff — y writes, n discards, ↑↓ scroll, Esc keeps editing", bodyW - 4) }), scroll > 0 && _jsx(ElisionMark, { count: scroll, side: "above" }), visible.map(({ text: line, note }, index) => (_jsx(Text, { wrap: "truncate", color: note ? INK.warn : line.startsWith("+") ? INK.brand : line.startsWith("-") ? INK.fail : undefined, dimColor: !note && (line.startsWith("@") || line.startsWith("---") || line.startsWith("+++")), children: clip(line, bodyW - 6) || " " }, `${scroll + index}:${line}`))), below > 0 && _jsx(ElisionMark, { count: below, side: "below", hint: `↓ scrolls · PgDn jumps ${cap} lines` })] }));
|
|
1738
1801
|
}
|
|
1739
1802
|
if (overlay.kind === "classify") {
|
|
1740
1803
|
const subject = overlay.bulk
|
|
@@ -1767,10 +1830,13 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1767
1830
|
];
|
|
1768
1831
|
const { visible, start, above, below } = windowRows(items, overlay.at, Math.max(1, capacity - noteLines.length + 1));
|
|
1769
1832
|
const chained = overlay.chain.length > 0;
|
|
1770
|
-
return (_jsxs(OverlayPanel, { title: chained ? `pool · ${overlay.shape}` : `pin · ${overlay.shape}`, width: bodyW, children: [_jsx(Text, { dimColor: true, wrap: "truncate", children: clip("Enter pins one channel · Space
|
|
1833
|
+
return (_jsxs(OverlayPanel, { title: chained ? `pool · ${overlay.shape}` : `pin · ${overlay.shape}`, width: bodyW, children: [_jsx(Text, { dimColor: true, wrap: "truncate", children: clip("Enter pins one channel · Space pools in order · Tab applies the pool from any row — Enter on an offered row too (pool replaces pin)", bodyW - 4) }), _jsx(SearchRow, { filter: ui.filter, active: true }), noteLines.map((line, index) => _jsx(Text, { dimColor: true, wrap: "truncate", children: clip(line, bodyW - 4) }, `excluded-${index}`)), above > 0 && _jsx(ElisionMark, { count: above, side: "above" }), visible.map(({ candidate, line }, index) => {
|
|
1771
1834
|
const selected = start + index === overlay.at;
|
|
1772
1835
|
if (candidate === undefined) {
|
|
1773
|
-
|
|
1836
|
+
// OBS-1145 add.1: a carried chain member the picker cannot offer keeps its ordinal
|
|
1837
|
+
const id = ledgerChannelId(line);
|
|
1838
|
+
const at = id === undefined ? -1 : overlay.chain.indexOf(id);
|
|
1839
|
+
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Pointer, { on: selected }), at !== -1 && _jsx(Text, { color: INK.brand, children: `${at + 1} ` }), _jsx(Text, { dimColor: true, children: "✗ " }), _jsx(Text, { bold: selected, dimColor: !selected, children: clip(line, bodyW - (at === -1 ? 10 : 12)) })] }, `ledger-${start + index}`));
|
|
1774
1840
|
}
|
|
1775
1841
|
const at = overlay.chain.indexOf(candidate.id);
|
|
1776
1842
|
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Pointer, { on: selected }), at === -1 ? _jsx(Text, { dimColor: true, children: "· " }) : _jsx(Text, { color: INK.brand, children: `${at + 1} ` }), _jsx(Text, { bold: selected, children: clip(candidate.label, bodyW - 10) })] }, candidate.id));
|
|
@@ -1840,7 +1906,8 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1840
1906
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Shapes" }), _jsx(Text, { dimColor: true, children: ` routed under ${ui.selectedMode}` })] }), _jsx(Text, { children: " " }), rows.map((row, index) => renderShapeRow(row, ui.focus === "list" && index === ui.listAt))] }));
|
|
1841
1907
|
}
|
|
1842
1908
|
const rows = steeringList();
|
|
1843
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Steering" }), _jsx(Text, { dimColor: true, children: " review · consult · judge" })] }), _jsx(Text, { children: " " }), rows.map((row, index) => renderPlainRow(row.id, row.label, ui.focus === "list" && index === ui.listAt))
|
|
1909
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Steering" }), _jsx(Text, { dimColor: true, children: " review · consult · judge" })] }), _jsx(Text, { children: " " }), rows.map((row, index) => renderPlainRow(row.id, row.label, ui.focus === "list" && index === ui.listAt)), reviewAdvisories.length ? _jsx(Text, { children: " " }) : null, reviewAdvisories.flatMap((line) => wrapCells(`! ${line}`, bodyW - 4, { continuationPrefix: " " }))
|
|
1910
|
+
.map((text, index) => _jsx(Text, { color: INK.warn, children: text }, `advisory-${index}`))] }));
|
|
1844
1911
|
})();
|
|
1845
1912
|
// ── footer ─────────────────────────────────────────────────────────────────
|
|
1846
1913
|
const detailLines = () => {
|
|
@@ -1911,6 +1978,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1911
1978
|
if (overlay.kind === "candidates") {
|
|
1912
1979
|
return [
|
|
1913
1980
|
{ key: "Enter", label: overlay.chain.length ? "apply pool" : "pin · lift greyed" },
|
|
1981
|
+
...(overlay.chain.length ? [{ key: "Tab", label: "apply from any row" }] : []),
|
|
1914
1982
|
{ key: "Space", label: "pool in order" },
|
|
1915
1983
|
{ key: "type", label: "search" },
|
|
1916
1984
|
{ key: "Esc", label: "cancel" },
|
|
@@ -1955,6 +2023,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1955
2023
|
{ key: "Enter", label: "assign/classify" },
|
|
1956
2024
|
{ key: "Space", label: "reach picker" },
|
|
1957
2025
|
{ key: "l", label: "lift entry" },
|
|
2026
|
+
{ key: "e", label: "effort" },
|
|
1958
2027
|
{ key: "m", label: "presets" },
|
|
1959
2028
|
{ key: "w", label: "review + write" },
|
|
1960
2029
|
{ key: "←", label: "rail" },
|
|
@@ -1985,7 +2054,7 @@ export function FleetApp({ ageMs, agents, initialAllowOut = [], modelGroups, ini
|
|
|
1985
2054
|
? _jsx(Text, { color: INK.warn, children: ` ! ${clip(ui.notice, width - 4)}` })
|
|
1986
2055
|
: details.map((line) => _jsx(Text, { dimColor: true, children: ` ${clip(line, width - 2)}` }, line)), _jsx(KeyBar, { binds: keyBinds() })] }));
|
|
1987
2056
|
}
|
|
1988
|
-
export async function runFleetInkEditor({ ageMs, adapters, health, initialAllowOut = [], modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewOverlay, reloadGuard, stagedRouting, entry = "probe", initialJudge = "", judgeSeats = [], initialInput = [], input, output, debug = false, ...initialDenyProps }) {
|
|
2057
|
+
export async function runFleetInkEditor({ ageMs, adapters, health, initialAllowOut = [], initialEfforts, modelGroups, initialMode, modeOptions, initialMap, modePreview, shapeRows, candidatesForShape, preferOptionsForShape, initialSteering, steeringOptionsFor, reviewAdvisories = [], reviewOverlay, reloadGuard, stagedRouting, entry = "probe", initialJudge = "", judgeSeats = [], initialInput = [], input, output, debug = false, ...initialDenyProps }) {
|
|
1989
2058
|
const agents = adapters.flatMap((adapter) => {
|
|
1990
2059
|
const state = health[adapter.id];
|
|
1991
2060
|
if (!state?.installed)
|
|
@@ -2009,7 +2078,7 @@ export async function runFleetInkEditor({ ageMs, adapters, health, initialAllowO
|
|
|
2009
2078
|
// rebuilt from output.columns/rows so a pane resize re-renders at the new size. Same root
|
|
2010
2079
|
// element type on every rerender ⇒ React keeps the component instance, so staged edits,
|
|
2011
2080
|
// cursor, and overlays all survive the resize.
|
|
2012
|
-
const editorElement = () => (_jsx(FleetApp, { ageMs: ageMs, agents: agents, ...initialDenyProps, initialAllowOut: initialAllowOut, modelGroups: declaredModelGroups, initialMode: initialMode, modeOptions: modeOptions, initialMap: initialMap, modePreview: modePreview, shapeRows: shapeRows, candidatesForShape: candidatesForShape, preferOptionsForShape: preferOptionsForShape, initialSteering: initialSteering, steeringOptionsFor: steeringOptionsFor, reviewOverlay: reviewOverlay, reloadGuard: reloadGuard, stagedRouting: stagedRouting, entry: entry, initialJudge: initialJudge, judgeSeats: judgeSeats,
|
|
2081
|
+
const editorElement = () => (_jsx(FleetApp, { ageMs: ageMs, agents: agents, ...initialDenyProps, initialAllowOut: initialAllowOut, initialEfforts: initialEfforts, modelGroups: declaredModelGroups, initialMode: initialMode, modeOptions: modeOptions, initialMap: initialMap, modePreview: modePreview, shapeRows: shapeRows, candidatesForShape: candidatesForShape, preferOptionsForShape: preferOptionsForShape, initialSteering: initialSteering, steeringOptionsFor: steeringOptionsFor, reviewAdvisories: reviewAdvisories, reviewOverlay: reviewOverlay, reloadGuard: reloadGuard, stagedRouting: stagedRouting, entry: entry, initialJudge: initialJudge, judgeSeats: judgeSeats,
|
|
2013
2082
|
// v1.90.9: cap every list to the terminal minus chrome so the cursor and header can
|
|
2014
2083
|
// never scroll off-screen (omp's 218-model list did exactly that pre-cap).
|
|
2015
2084
|
// OBS-523: chrome is ≤12 rows worst case (header, borders, padding, scope+search,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tickmarkr",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"description": "Spec in, verified work out.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"scripts/assert-test-file-count.sh",
|
|
81
81
|
"scripts/emit-schema.ts",
|
|
82
82
|
"scripts/probe-rig.mjs",
|
|
83
|
+
"scripts/run-ci-vitest.sh",
|
|
83
84
|
"specs/export-selftest.spec.md"
|
|
84
85
|
],
|
|
85
86
|
"prefixes": [
|