tickmarkr 1.85.0 → 1.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/adapters/catalog-remote.d.ts +64 -0
- package/dist/adapters/catalog-remote.js +287 -0
- package/dist/adapters/catalog.d.ts +96 -0
- package/dist/adapters/catalog.js +176 -0
- package/dist/adapters/claude-code.js +5 -3
- package/dist/adapters/fake.js +33 -4
- package/dist/adapters/model-lints.d.ts +25 -5
- package/dist/adapters/model-lints.js +184 -50
- package/dist/adapters/model-windows.d.ts +31 -0
- package/dist/adapters/model-windows.js +69 -0
- package/dist/adapters/prompt.d.ts +5 -1
- package/dist/adapters/prompt.js +13 -4
- package/dist/adapters/registry.d.ts +25 -26
- package/dist/adapters/registry.js +173 -110
- package/dist/adapters/types.js +15 -3
- package/dist/brand.d.ts +5 -1
- package/dist/brand.js +18 -2
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +43 -21
- package/dist/cli/commands/fleet.d.ts +7 -0
- package/dist/cli/commands/fleet.js +94 -74
- package/dist/cli/commands/init.js +118 -5
- package/dist/cli/commands/status.js +44 -18
- package/dist/compile/gsd.d.ts +2 -1
- package/dist/compile/gsd.js +68 -2
- package/dist/compile/native.d.ts +14 -0
- package/dist/compile/native.js +161 -12
- package/dist/config/config.d.ts +20 -5
- package/dist/config/config.js +96 -64
- package/dist/config/fleet-overlay.d.ts +25 -20
- package/dist/config/fleet-overlay.js +195 -77
- package/dist/config/fleet-why.d.ts +23 -0
- package/dist/config/fleet-why.js +42 -0
- package/dist/drivers/herdr.d.ts +1 -0
- package/dist/drivers/herdr.js +70 -19
- package/dist/gates/acceptance.js +7 -2
- package/dist/gates/llm.d.ts +0 -1
- package/dist/gates/llm.js +5 -30
- package/dist/gates/review.d.ts +2 -1
- package/dist/gates/review.js +9 -7
- package/dist/gates/verdict-cause.d.ts +4 -0
- package/dist/gates/verdict-cause.js +63 -0
- package/dist/graph/schema.d.ts +6 -0
- package/dist/graph/schema.js +8 -5
- package/dist/route/router.d.ts +0 -5
- package/dist/route/router.js +16 -20
- package/dist/run/consult.d.ts +6 -0
- package/dist/run/consult.js +35 -25
- package/dist/run/daemon.js +71 -15
- package/dist/run/journal.js +87 -7
- package/dist/tui/cockpit/capture.d.ts +12 -0
- package/dist/tui/cockpit/capture.js +37 -1
- package/dist/tui/cockpit/components.js +8 -8
- package/dist/tui/cockpit/theme.d.ts +32 -26
- package/dist/tui/cockpit/theme.js +11 -5
- package/dist/tui/ink/components.d.ts +0 -15
- package/dist/tui/ink/components.js +0 -17
- package/dist/tui/ink/fleet-app.d.ts +4 -1
- package/dist/tui/ink/fleet-app.js +134 -13
- package/fixtures/sample.native.md +1 -1
- package/package.json +1 -1
- package/skills/tickmarkr-overseer/SKILL.md +354 -34
- package/skills/tickmarkr-overseer/scripts/watch-artifacts.sh +70 -0
- package/skills/tickmarkr-overseer/scripts/watch-panes.sh +1 -1
- package/dist/tui/ink/studio-app.d.ts +0 -59
- package/dist/tui/ink/studio-app.js +0 -320
- package/dist/tui/save.d.ts +0 -38
- package/dist/tui/save.js +0 -96
- package/dist/tui/staging.d.ts +0 -29
- package/dist/tui/staging.js +0 -78
|
@@ -3,10 +3,13 @@ import { emitKeypressEvents } from "node:readline";
|
|
|
3
3
|
import { PassThrough } from "node:stream";
|
|
4
4
|
import { render, Text, useApp, useInput } from "ink";
|
|
5
5
|
import { useRef, useState } from "react";
|
|
6
|
+
import { MODEL_ID_RE } from "../../adapters/types.js";
|
|
7
|
+
import { fleetFirstTouchProvenance } from "../../config/fleet-overlay.js";
|
|
6
8
|
import { TIERS } from "../../graph/schema.js";
|
|
7
9
|
import { FleetListScreen, FleetReviewScreen, ToggleMark } from "./components.js";
|
|
8
10
|
const STEERING_KEYS = ["review", "consult"];
|
|
9
11
|
const escape = String.fromCharCode(27);
|
|
12
|
+
const CHANNELS = ["sub", "api"];
|
|
10
13
|
const inkBookkeepingWrites = new Set(["", `${escape}[?25l`, `${escape}[?25h`, `${escape}[?2026h`, `${escape}[?2026l`]);
|
|
11
14
|
function inkOutput(output) {
|
|
12
15
|
if (typeof output.on === "function" && typeof output.off === "function")
|
|
@@ -117,6 +120,11 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
117
120
|
const [modelGroup, setModelGroup] = useState(0);
|
|
118
121
|
const modelCursorRef = useRef(0);
|
|
119
122
|
const [modelCursor, setModelCursor] = useState(0);
|
|
123
|
+
const modelIdRef = useRef("");
|
|
124
|
+
const [modelId, setModelId] = useState("");
|
|
125
|
+
const channelCursorRef = useRef(0);
|
|
126
|
+
const [channelCursor, setChannelCursor] = useState(0);
|
|
127
|
+
const channelByAdapterRef = useRef({});
|
|
120
128
|
const tierCursorRef = useRef(0);
|
|
121
129
|
const [tierCursor, setTierCursor] = useState(0);
|
|
122
130
|
const pendingClassificationRef = useRef(null);
|
|
@@ -160,15 +168,30 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
160
168
|
const group = enabledModelGroups()[modelGroupRef.current];
|
|
161
169
|
if (!group)
|
|
162
170
|
return [];
|
|
163
|
-
|
|
171
|
+
const rows = group.rows.map((row) => {
|
|
164
172
|
const staged = classificationsRef.current.find((classification) => classification.adapter === group.adapter && classification.model === row.model);
|
|
165
173
|
return staged ? { ...row, tier: staged.tier } : row;
|
|
166
174
|
});
|
|
175
|
+
const known = new Set(rows.map((row) => row.model));
|
|
176
|
+
for (const staged of classificationsRef.current) {
|
|
177
|
+
if (staged.adapter === group.adapter && !known.has(staged.model)) {
|
|
178
|
+
rows.push({ model: staged.model, tier: staged.tier });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return rows;
|
|
167
182
|
};
|
|
168
183
|
const editorState = () => ({
|
|
169
184
|
denyAdapters: [...(denyRef.current ?? [])].sort(),
|
|
170
185
|
denyModels: [...(denyModelsRef.current ?? [])].sort(),
|
|
171
|
-
classifications: classificationsRef.current
|
|
186
|
+
classifications: classificationsRef.current.map((classification) => classification.vendor && classification.channel
|
|
187
|
+
? {
|
|
188
|
+
...classification,
|
|
189
|
+
note: fleetFirstTouchProvenance(classification.note, {
|
|
190
|
+
vendor: classification.vendor,
|
|
191
|
+
channel: classification.channel,
|
|
192
|
+
}),
|
|
193
|
+
}
|
|
194
|
+
: classification),
|
|
172
195
|
selectedMode: selectedModeRef.current,
|
|
173
196
|
map: stagedMap(),
|
|
174
197
|
steering: structuredClone(steeringRef.current),
|
|
@@ -186,6 +209,38 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
186
209
|
screenRef.current = next;
|
|
187
210
|
setScreen(next);
|
|
188
211
|
};
|
|
212
|
+
const beginClassification = (group, model) => {
|
|
213
|
+
tierCursorRef.current = 0;
|
|
214
|
+
setTierCursor(0);
|
|
215
|
+
const firstTouch = !group.rows.some((row) => row.tier !== undefined);
|
|
216
|
+
const pending = {
|
|
217
|
+
adapter: group.adapter,
|
|
218
|
+
model,
|
|
219
|
+
tier: TIERS[0],
|
|
220
|
+
};
|
|
221
|
+
if (!firstTouch) {
|
|
222
|
+
pendingClassificationRef.current = pending;
|
|
223
|
+
showScreen("tiers");
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (!group.vendor) {
|
|
227
|
+
setNotice(`fleet: ${group.adapter} has no vendor declaration — classification cannot be saved`);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
pending.vendor = group.vendor;
|
|
231
|
+
const answered = channelByAdapterRef.current[group.adapter];
|
|
232
|
+
if (answered) {
|
|
233
|
+
pending.channel = answered;
|
|
234
|
+
pendingClassificationRef.current = pending;
|
|
235
|
+
showScreen("tiers");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
pendingClassificationRef.current = pending;
|
|
239
|
+
channelCursorRef.current = 0;
|
|
240
|
+
setChannelCursor(0);
|
|
241
|
+
setNotice("");
|
|
242
|
+
showScreen("channel");
|
|
243
|
+
};
|
|
189
244
|
useInput((input, key) => {
|
|
190
245
|
if (doneRef.current)
|
|
191
246
|
return;
|
|
@@ -197,7 +252,13 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
197
252
|
showScreen("steering");
|
|
198
253
|
return;
|
|
199
254
|
}
|
|
200
|
-
if (key.escape
|
|
255
|
+
if (key.escape && screenRef.current === "add-model") {
|
|
256
|
+
setNotice("");
|
|
257
|
+
showScreen("models");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const typing = screenRef.current === "provenance" || screenRef.current === "add-model";
|
|
261
|
+
if (key.escape || (!typing && input === "q") || (key.ctrl && input === "c")) {
|
|
201
262
|
finish({ kind: "quit" });
|
|
202
263
|
return;
|
|
203
264
|
}
|
|
@@ -276,14 +337,14 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
276
337
|
setNotice("fleet: tier reassignment on classified models is not supported in v1 — edit config directly");
|
|
277
338
|
return;
|
|
278
339
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
showScreen("
|
|
340
|
+
beginClassification(group, row.model);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
if (input === "n" && group) {
|
|
344
|
+
modelIdRef.current = "";
|
|
345
|
+
setModelId("");
|
|
346
|
+
setNotice("");
|
|
347
|
+
showScreen("add-model");
|
|
287
348
|
return;
|
|
288
349
|
}
|
|
289
350
|
if (key.return) {
|
|
@@ -300,6 +361,57 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
300
361
|
}
|
|
301
362
|
return;
|
|
302
363
|
}
|
|
364
|
+
if (screenRef.current === "add-model") {
|
|
365
|
+
if (key.return) {
|
|
366
|
+
const group = enabledModelGroups()[modelGroupRef.current];
|
|
367
|
+
const candidate = modelIdRef.current;
|
|
368
|
+
if (!MODEL_ID_RE.test(candidate)) {
|
|
369
|
+
setNotice(`fleet: model id must match ${MODEL_ID_RE.source}`);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (currentModelRows().some((row) => row.model === candidate)) {
|
|
373
|
+
setNotice(`fleet: ${candidate} is already listed for ${group?.adapter ?? "this adapter"}`);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (group)
|
|
377
|
+
beginClassification(group, candidate);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (key.backspace || key.delete) {
|
|
381
|
+
const next = modelIdRef.current.slice(0, -1);
|
|
382
|
+
modelIdRef.current = next;
|
|
383
|
+
setModelId(next);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (input && !key.ctrl && !key.meta) {
|
|
387
|
+
const next = modelIdRef.current + input;
|
|
388
|
+
modelIdRef.current = next;
|
|
389
|
+
setModelId(next);
|
|
390
|
+
setNotice("");
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (screenRef.current === "channel") {
|
|
395
|
+
if (key.downArrow || input === "j") {
|
|
396
|
+
const next = Math.min(channelCursorRef.current + 1, CHANNELS.length - 1);
|
|
397
|
+
channelCursorRef.current = next;
|
|
398
|
+
setChannelCursor(next);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (key.upArrow || input === "k") {
|
|
402
|
+
const next = Math.max(channelCursorRef.current - 1, 0);
|
|
403
|
+
channelCursorRef.current = next;
|
|
404
|
+
setChannelCursor(next);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (key.return && pendingClassificationRef.current) {
|
|
408
|
+
const channel = CHANNELS[channelCursorRef.current];
|
|
409
|
+
channelByAdapterRef.current[pendingClassificationRef.current.adapter] = channel;
|
|
410
|
+
pendingClassificationRef.current.channel = channel;
|
|
411
|
+
showScreen("tiers");
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
303
415
|
if (screenRef.current === "tiers") {
|
|
304
416
|
if (key.downArrow || input === "j") {
|
|
305
417
|
const next = Math.min(tierCursorRef.current + 1, TIERS.length - 1);
|
|
@@ -596,8 +708,12 @@ export function FleetApp({ ageMs, agents, initialDenyAdapters, initialDenyModels
|
|
|
596
708
|
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})` : ""}` }),
|
|
597
709
|
};
|
|
598
710
|
});
|
|
599
|
-
return (_jsx(FleetListScreen, { title: `step 3/6 · models · ${group?.adapter ?? ""}`, legend: "\u2191\u2193/jk move \u00B7 space toggle \u00B7 t tier \u00B7 enter next \u00B7 esc/q quit", rows: rows, cursor: modelCursor, details: notice ? [notice] : [] }));
|
|
711
|
+
return (_jsx(FleetListScreen, { title: `step 3/6 · models · ${group?.adapter ?? ""}`, legend: "\u2191\u2193/jk move \u00B7 space toggle \u00B7 t tier \u00B7 n add model \u00B7 enter next \u00B7 esc/q quit", rows: rows, cursor: modelCursor, details: notice ? [notice] : [] }));
|
|
600
712
|
}
|
|
713
|
+
if (screen === "add-model")
|
|
714
|
+
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] : [] }));
|
|
715
|
+
if (screen === "channel")
|
|
716
|
+
return (_jsx(FleetListScreen, { title: `channel · ${pendingClassificationRef.current?.adapter ?? ""}`, legend: "\u2191\u2193/jk move \u00B7 enter select \u00B7 esc/q quit", rows: CHANNELS.map((channel) => ({ id: channel, content: _jsx(Text, { children: channel }) })), cursor: channelCursor }));
|
|
601
717
|
if (screen === "tiers") {
|
|
602
718
|
return (_jsx(FleetListScreen, { title: `pick · tier · ${pendingClassificationRef.current?.adapter}:${pendingClassificationRef.current?.model}`, legend: "\u2191\u2193/jk move \u00B7 enter select \u00B7 esc/q quit", rows: TIERS.map((tier) => ({ id: tier, content: _jsx(Text, { children: tier }) })), cursor: tierCursor }));
|
|
603
719
|
}
|
|
@@ -651,9 +767,14 @@ export async function runFleetInkEditor({ ageMs, adapters, health, initialDenyAd
|
|
|
651
767
|
authed: state.authed,
|
|
652
768
|
}];
|
|
653
769
|
});
|
|
770
|
+
const vendors = new Map(adapters.map((adapter) => [adapter.id, adapter.vendor]));
|
|
771
|
+
const declaredModelGroups = modelGroups.map((group) => ({
|
|
772
|
+
...group,
|
|
773
|
+
vendor: group.vendor ?? vendors.get(group.adapter),
|
|
774
|
+
}));
|
|
654
775
|
const bridgedInput = inkInput(input, initialInput);
|
|
655
776
|
const legacyOutput = typeof output.on !== "function" || typeof output.off !== "function";
|
|
656
|
-
const app = render(_jsx(FleetApp, { ageMs: ageMs, agents: agents, initialDenyAdapters: initialDenyAdapters, initialDenyModels: initialDenyModels, modelGroups:
|
|
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 }), {
|
|
657
778
|
// FleetIO's injected stream predates Ink and did not require ref/unref.
|
|
658
779
|
// Real terminal streams pass through unchanged; the compatibility facade
|
|
659
780
|
// adds only those lifecycle methods and leaves input decoding to Ink.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
- shape: implement
|
|
7
7
|
- deps: none
|
|
8
8
|
- files: src/compile/native.ts, src/compile/index.ts
|
|
9
|
-
- context: docs/
|
|
9
|
+
- context: docs/codebase/ARCHITECTURE.md, src/graph/schema.ts
|
|
10
10
|
- complexity: 8
|
|
11
11
|
- humanGate: true
|
|
12
12
|
- pin: claude-code opus
|