tickmarkr 2.6.2 → 2.6.4
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 +12 -2
- package/dist/adapters/codex.d.ts +2 -1
- package/dist/adapters/codex.js +26 -5
- package/dist/adapters/model-lints.d.ts +1 -0
- package/dist/adapters/model-lints.js +48 -1
- package/dist/adapters/model-windows.d.ts +2 -1
- package/dist/adapters/model-windows.js +18 -7
- package/dist/adapters/types.d.ts +6 -0
- package/dist/cli/commands/approve.d.ts +6 -3
- package/dist/cli/commands/approve.js +43 -6
- package/dist/cli/commands/doctor.d.ts +8 -2
- package/dist/cli/commands/doctor.js +6 -1
- package/dist/cli/commands/fleet.js +264 -59
- package/dist/cli/commands/init.js +5 -3
- package/dist/cli/commands/plan.js +13 -8
- package/dist/cli/commands/report.d.ts +40 -2
- package/dist/cli/commands/report.js +278 -11
- package/dist/cli/commands/resume.js +2 -4
- package/dist/cli/commands/run.d.ts +11 -0
- package/dist/cli/commands/run.js +33 -5
- package/dist/cli/commands/status.js +49 -4
- package/dist/cli/commands/verify.js +332 -121
- package/dist/compile/native.js +137 -0
- package/dist/config/config.d.ts +40 -9
- package/dist/config/config.js +133 -15
- package/dist/config/fleet-overlay.d.ts +13 -3
- package/dist/config/fleet-overlay.js +12 -8
- package/dist/drivers/herdr.d.ts +12 -0
- package/dist/drivers/herdr.js +51 -0
- package/dist/drivers/orca.d.ts +9 -1
- package/dist/drivers/orca.js +29 -7
- package/dist/drivers/types.d.ts +2 -0
- package/dist/drivers/types.js +2 -2
- package/dist/gates/acceptance.d.ts +7 -0
- package/dist/gates/acceptance.js +27 -5
- package/dist/gates/baseline.d.ts +20 -1
- package/dist/gates/baseline.js +100 -20
- package/dist/gates/cache.d.ts +8 -0
- package/dist/gates/cache.js +12 -2
- package/dist/gates/llm.d.ts +6 -0
- package/dist/gates/llm.js +27 -8
- package/dist/gates/review.d.ts +6 -1
- package/dist/gates/review.js +122 -32
- package/dist/gates/run-gates.d.ts +54 -3
- package/dist/gates/run-gates.js +331 -45
- package/dist/gates/test-manifest.d.ts +42 -0
- package/dist/gates/test-manifest.js +69 -10
- package/dist/route/router.d.ts +23 -1
- package/dist/route/router.js +54 -16
- package/dist/run/consult.d.ts +3 -1
- package/dist/run/consult.js +4 -2
- package/dist/run/daemon.d.ts +2 -1
- package/dist/run/daemon.js +349 -79
- package/dist/run/interactive-seed.d.ts +4 -0
- package/dist/run/interactive-seed.js +35 -9
- package/dist/run/journal.d.ts +123 -1
- package/dist/run/journal.js +480 -17
- package/dist/run/lease.d.ts +13 -0
- package/dist/run/lease.js +45 -0
- package/dist/run/protocol.d.ts +15 -0
- package/dist/run/protocol.js +11 -1
- package/dist/run/receipt-resolver.d.ts +22 -0
- package/dist/run/receipt-resolver.js +40 -1
- package/dist/run/repair-selection.d.ts +11 -1
- package/dist/run/repair-selection.js +17 -9
- package/dist/run/wall-budget.d.ts +48 -0
- package/dist/run/wall-budget.js +280 -0
- package/dist/tui/cockpit/live-store.d.ts +6 -0
- package/dist/tui/cockpit/live-store.js +36 -11
- package/dist/tui/cockpit/run-cockpit.js +2 -2
- package/dist/tui/cockpit/run-view.d.ts +2 -1
- package/dist/tui/cockpit/run-view.js +13 -9
- package/dist/tui/cockpit/setup-cockpit.d.ts +2 -0
- package/dist/tui/cockpit/setup-cockpit.js +4 -0
- package/package.json +2 -1
- package/schema/config.schema.json +8 -1
- package/skills/tickmarkr-auto/SKILL.md +2 -2
- package/skills/tickmarkr-loop/SKILL.md +17 -5
- package/skills/tickmarkr-overseer/scripts/classify-vitest-log.sh +4 -1
|
@@ -12,11 +12,13 @@ import { authorsNote, doneAuthors } from "../../run/operator-state.js";
|
|
|
12
12
|
import { projectOperatorSummary } from "../../run/operator-summary.js";
|
|
13
13
|
import { trackJournalRows } from "../../run/protocol.js";
|
|
14
14
|
import { newestPark, permittedDecisionVerbs } from "./approve.js";
|
|
15
|
+
import { currentOwed, endToEndFirstPass, firstPassText, leadLines, leadRows, needsYouText, wallText } from "./report.js";
|
|
15
16
|
import { Journal, bindingToken, effectiveEvents, formatJournalNarration, parseJournalText, physicalLine, engagementComparable, isQualityFailureParkKind, parseRunId, preservedRefsByTask, recordedTaskFailureKind, runHasEnded, upheldFeedbackByTask, } from "../../run/journal.js";
|
|
16
17
|
import { isPidLive, runLockRunId, runStatusLine } from "../../run/lock.js";
|
|
17
18
|
import { normalizeGateOutcome } from "../../run/outcome.js";
|
|
18
19
|
import { desiredPanes } from "../../run/reconcile.js";
|
|
19
20
|
import { normalizeStallSnapshot } from "../../run/stall.js";
|
|
21
|
+
import { formatSpan, wallBudget, wallBudgetFacts } from "../../run/wall-budget.js";
|
|
20
22
|
import { armWatchSupervision, observeNamedRun, WATCH_OWNER_ENV, readSupervision, supervisionText } from "../../run/supervision.js";
|
|
21
23
|
import { deriveRunCockpitData, } from "../../tui/cockpit/derive.js";
|
|
22
24
|
import { cellWidth, fitCells, wrapCells } from "../../tui/cockpit/width.js";
|
|
@@ -447,6 +449,8 @@ export const shortGoal = (goal, max) => {
|
|
|
447
449
|
};
|
|
448
450
|
/** Columns the machine row always spends on the task title, however long its machinery segment runs. */
|
|
449
451
|
const MACHINE_TITLE_FLOOR = 24;
|
|
452
|
+
/** The plain print's own width when none is configured: its machine rows are laid out, and parsed whole, at it. */
|
|
453
|
+
const MACHINE_COLUMNS = 120;
|
|
450
454
|
// The approved task board derives an area from files[] rather than adding another graph field.
|
|
451
455
|
// Known tickmarkr domains keep their reviewed names; other repositories fall back to their first
|
|
452
456
|
// meaningful path segment so the shipped surface never turns a foreign project into UNMAPPED rows.
|
|
@@ -1036,7 +1040,7 @@ binaryVersion, now = Date.now(), animationFrame = 0, workerLiveness = new Map(),
|
|
|
1036
1040
|
// SUP-01: derived by stat() alone, from THIS frame's clock. status stays a reader — nothing here
|
|
1037
1041
|
// creates, touches or reaps a beat file, so an absent supervision dir stays absent.
|
|
1038
1042
|
const supervision = readSupervision(cwd, now);
|
|
1039
|
-
const width = process.stdout.columns ??
|
|
1043
|
+
const width = process.stdout.columns ?? MACHINE_COLUMNS;
|
|
1040
1044
|
const done = journalRowsOnly
|
|
1041
1045
|
? recordedDone(renderedTasks, taskRows)
|
|
1042
1046
|
: effective.tasks.filter((task) => task.status === "done").length;
|
|
@@ -1054,6 +1058,16 @@ binaryVersion, now = Date.now(), animationFrame = 0, workerLiveness = new Map(),
|
|
|
1054
1058
|
if (!taskIds.has(taskId))
|
|
1055
1059
|
phases.delete(taskId);
|
|
1056
1060
|
const hotPhase = [...phases.values()].sort((a, b) => a.order - b.order).at(-1);
|
|
1061
|
+
// CG1: the three lead lines — finished, wall, needs you from the CURRENT owed-check fold — open
|
|
1062
|
+
// every frame, plain and terminal; the header below keeps every comparability, supersession and verify fact.
|
|
1063
|
+
const lead = runId
|
|
1064
|
+
? leadLines(events, currentOwed(events, cwd), {
|
|
1065
|
+
// The header's own rule: while the tip is unverified the tally never reads as a finished run.
|
|
1066
|
+
tally: comparable ? tipPhase ? `${done}/${total} tasks done` : `${done}/${total} done` : NOT_COMPARABLE_CLAIM,
|
|
1067
|
+
tip: verify ? `tip ${verify}` : "tip verify pending",
|
|
1068
|
+
notes: supersededBy ? [`superseded by ${supersededBy}`] : [],
|
|
1069
|
+
}).map(sanitizeTaskText)
|
|
1070
|
+
: [];
|
|
1057
1071
|
// OBS-738: recovery facts stay on the journal's two established reducers. The prefix fold keeps an
|
|
1058
1072
|
// older journal equally readable by asking upheldFeedbackByTask what was active at that exact
|
|
1059
1073
|
// restore boundary; current resume-restore rows additionally carry the same task for narration.
|
|
@@ -1150,11 +1164,20 @@ binaryVersion, now = Date.now(), animationFrame = 0, workerLiveness = new Map(),
|
|
|
1150
1164
|
? `tickmarkr status${divider}${runLine ?? `run ${runId}`}${zone}${supersededBy ? `${divider}superseded by ${supersededBy}` : ""}${!comparable ? `${divider}${NOT_COMPARABLE_NOTICE}` : ""}${divider}${liveness(events, daemon, now).replaceAll(" · ", divider)}${verify ? `${divider}${verify}` : ""}${divider}${tipPhase ? `${done}/${total} tasks done${divider}run not verified` : `${done}/${total} done`}`
|
|
1151
1165
|
: `tickmarkr status${zone}${divider}no runs yet${divider}${done}/${total} done`;
|
|
1152
1166
|
const legendLine = ` gates: ${GATE_NAMES.map((gate) => `${GATE_KEYS[gate]} ${gate}`).join(divider)}`;
|
|
1167
|
+
// At its machine width and wider the plain print keeps each machine row whole — one row per task and
|
|
1168
|
+
// its evidence line after it, which consumers parse. A configured width narrower than that holds for
|
|
1169
|
+
// EVERY row: one that overflows wraps beneath its own indent, its identity kept on the first.
|
|
1170
|
+
const body = [header, legendLine, ` ${supervisionText(supervision, divider)}`, ...rows];
|
|
1171
|
+
const wrapRow = (line) => wrapCells(line, width, { continuationPrefix: `${/^ */u.exec(line)[0]} ` });
|
|
1153
1172
|
return {
|
|
1154
|
-
content: [
|
|
1173
|
+
content: [
|
|
1174
|
+
...leadRows(lead, width),
|
|
1175
|
+
...(width >= MACHINE_COLUMNS ? body : body.flatMap(wrapRow)),
|
|
1176
|
+
].join("\n"),
|
|
1155
1177
|
...(hotPhase ? { hotPhase } : {}),
|
|
1156
1178
|
...(runId ? { runId } : {}),
|
|
1157
1179
|
workerPhases: [...phases.values()].filter((phase) => phase.phase === "worker"),
|
|
1180
|
+
events,
|
|
1158
1181
|
};
|
|
1159
1182
|
}
|
|
1160
1183
|
// TTY: the operator-approved task table. The daemon gives this surface a ~110-column pane first;
|
|
@@ -1347,6 +1370,7 @@ binaryVersion, now = Date.now(), animationFrame = 0, workerLiveness = new Map(),
|
|
|
1347
1370
|
const effort = effortPanel(g.tasks, record && !comparable ? undefined : events, boardColumns);
|
|
1348
1371
|
return {
|
|
1349
1372
|
content: boardRows([
|
|
1373
|
+
...leadRows(lead, boardColumns),
|
|
1350
1374
|
...headerRows,
|
|
1351
1375
|
...nowLine,
|
|
1352
1376
|
supervisionLegend,
|
|
@@ -1364,8 +1388,22 @@ binaryVersion, now = Date.now(), animationFrame = 0, workerLiveness = new Map(),
|
|
|
1364
1388
|
...(hotPhase ? { hotPhase } : {}),
|
|
1365
1389
|
...(runId ? { runId } : {}),
|
|
1366
1390
|
workerPhases: [...phases.values()].filter((phase) => phase.phase === "worker"),
|
|
1391
|
+
events,
|
|
1367
1392
|
};
|
|
1368
1393
|
};
|
|
1394
|
+
// OBS-1201: the one-shot print closes with where the run's wall went (src/run/wall-budget.ts). A
|
|
1395
|
+
// window of zero length measured nothing, so it prints nothing; watch frames are untouched. Rows wrap
|
|
1396
|
+
// to the board width, so narrowing costs rows, never columns.
|
|
1397
|
+
const wallBudgetLines = (events) => {
|
|
1398
|
+
const budget = wallBudget(events);
|
|
1399
|
+
if (!budget || budget.wallMs <= 0)
|
|
1400
|
+
return [];
|
|
1401
|
+
const columns = Math.max(40, process.stdout.columns ?? 120);
|
|
1402
|
+
return [
|
|
1403
|
+
` wall budget ${formatSpan(budget.wallMs)} · each instant once, by priority`,
|
|
1404
|
+
...wallBudgetFacts(budget).map(([label, fact]) => ` ${label} ${fact}`),
|
|
1405
|
+
].flatMap((line) => wrapCells(line, columns, { continuationPrefix: " " }));
|
|
1406
|
+
};
|
|
1369
1407
|
/**
|
|
1370
1408
|
* The compact form a statusline calls, so journal interpretation happens ONCE, inside the product.
|
|
1371
1409
|
* (An operator-local bash reimplementation counted `tip-verify` events instead of reading the
|
|
@@ -1388,7 +1426,12 @@ const oneLine = (cwd, namedRunId) => {
|
|
|
1388
1426
|
`verify ${recordedVerify(record.events)}`,
|
|
1389
1427
|
]
|
|
1390
1428
|
: [NOT_COMPARABLE_CLAIM, "verify unavailable"];
|
|
1391
|
-
|
|
1429
|
+
// CG1: the lead's facts in one line — lineage first pass, the wall window, and what needs you from
|
|
1430
|
+
// the CURRENT fold, so a discharge after run-end moves this line too.
|
|
1431
|
+
const { events } = record;
|
|
1432
|
+
return sanitizeTaskText([
|
|
1433
|
+
record.runId, ...claims, firstPassText(endToEndFirstPass(events)), wallText(events), needsYouText(events, currentOwed(events, cwd)),
|
|
1434
|
+
].join(" · "));
|
|
1392
1435
|
};
|
|
1393
1436
|
export async function status(argv, cwd = process.cwd(), opts = {}) {
|
|
1394
1437
|
if (argv.some((arg) => arg === "--help" || arg === "-h"))
|
|
@@ -1401,7 +1444,9 @@ export async function status(argv, cwd = process.cwd(), opts = {}) {
|
|
|
1401
1444
|
// The task-table frame owns its own two-row brand lockup; the four-row global banner would
|
|
1402
1445
|
// create the second header the approved replacement removes.
|
|
1403
1446
|
if (!argv.includes("--watch")) {
|
|
1404
|
-
|
|
1447
|
+
const frame = renderFrame(cwd, binaryVersion, opts.now?.() ?? Date.now(), 0, undefined, false, namedRunId);
|
|
1448
|
+
const wall = wallBudgetLines(frame.events);
|
|
1449
|
+
return wall.length ? [frame.content, "", ...wall].join("\n") : frame.content;
|
|
1405
1450
|
}
|
|
1406
1451
|
const eventStream = argv.some((arg) => arg === "--events" || arg === "--jsonl" || arg === "--decision-events");
|
|
1407
1452
|
const webhookUrl = opts.webhookUrl
|