tickmarkr 1.84.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.d.ts +1 -0
- package/dist/adapters/claude-code.js +59 -1
- package/dist/adapters/fake.js +42 -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.d.ts +3 -0
- package/dist/adapters/types.js +36 -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 +202 -46
- package/dist/compile/collateral.d.ts +86 -2
- package/dist/compile/collateral.js +294 -3
- 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 +82 -5
- package/dist/config/config.js +253 -66
- 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 +21 -3
- package/dist/drivers/herdr.js +344 -110
- package/dist/gates/acceptance.js +7 -2
- package/dist/gates/baseline.d.ts +1 -0
- package/dist/gates/baseline.js +91 -13
- package/dist/gates/llm.d.ts +0 -1
- package/dist/gates/llm.js +5 -30
- package/dist/gates/review.d.ts +9 -1
- package/dist/gates/review.js +105 -10
- package/dist/gates/run-gates.d.ts +9 -0
- package/dist/gates/run-gates.js +285 -41
- 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.d.ts +48 -2
- package/dist/run/daemon.js +1488 -330
- package/dist/run/journal.d.ts +56 -3
- package/dist/run/journal.js +358 -4
- package/dist/run/stall.d.ts +35 -1
- package/dist/run/stall.js +118 -8
- package/dist/tui/cockpit/capture.d.ts +12 -0
- package/dist/tui/cockpit/capture.js +37 -1
- package/dist/tui/cockpit/components.d.ts +2 -0
- package/dist/tui/cockpit/components.js +8 -8
- package/dist/tui/cockpit/derive.d.ts +29 -2
- package/dist/tui/cockpit/derive.js +219 -23
- package/dist/tui/cockpit/run-cockpit.js +128 -27
- 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
package/dist/run/consult.js
CHANGED
|
@@ -2,7 +2,8 @@ import { mkdirSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { getAdapter } from "../adapters/registry.js";
|
|
4
4
|
import { bannerShell, paneDispatchCommand } from "../brand.js";
|
|
5
|
-
import {
|
|
5
|
+
import { extractVerdictJson, gateExitTrailer, gatePaneName, generateVerdictNonce, verdictNonceLine } from "../gates/llm.js";
|
|
6
|
+
import { classifyVerdictCause } from "../gates/verdict-cause.js";
|
|
6
7
|
import { sh } from "./git.js";
|
|
7
8
|
import { redactSecrets } from "./redact.js";
|
|
8
9
|
import { filterLlmTranscript } from "./stall.js";
|
|
@@ -57,6 +58,33 @@ export function augmentRetryBrief(feedback, opts) {
|
|
|
57
58
|
return parts.join("\n\n");
|
|
58
59
|
}
|
|
59
60
|
const ACTIONS = ["retry", "reroute", "decompose", "human"];
|
|
61
|
+
export function parseConsultVerdict(out, nonce) {
|
|
62
|
+
const v = extractVerdictJson(out, nonce);
|
|
63
|
+
if (!v)
|
|
64
|
+
return { verdict: null, cause: classifyVerdictCause(out, nonce, "action") };
|
|
65
|
+
// A parsed object with an unknown action is a content rejection, not silence. It keeps the existing
|
|
66
|
+
// null result without manufacturing a classifier cause for a state the classifier never saw.
|
|
67
|
+
if (!ACTIONS.includes(v.action))
|
|
68
|
+
return { verdict: null };
|
|
69
|
+
// fail-closed exclusion: only a non-empty string survives. Malformed values (number/array/object/
|
|
70
|
+
// empty) are dropped — the verdict stays a normal channel-level reroute/retry/…, never a crash
|
|
71
|
+
// and never silently forced to human. Unknown adapter ids pass through; the daemon treats a
|
|
72
|
+
// zero-match expansion as channel-level reroute.
|
|
73
|
+
const raw = v.excludeAdapter;
|
|
74
|
+
const excludeAdapter = typeof raw === "string" && raw.length > 0 ? raw : undefined;
|
|
75
|
+
const reason = typeof v.reason === "string" ? v.reason : undefined;
|
|
76
|
+
const guidance = typeof v.guidance === "string" ? v.guidance : undefined;
|
|
77
|
+
const notes = String(v.notes ?? guidance ?? reason ?? "");
|
|
78
|
+
return {
|
|
79
|
+
verdict: {
|
|
80
|
+
action: v.action,
|
|
81
|
+
notes,
|
|
82
|
+
...(reason ? { reason } : {}),
|
|
83
|
+
...(guidance ? { guidance } : {}),
|
|
84
|
+
...(excludeAdapter ? { excludeAdapter } : {}),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
60
88
|
// v1.65 T2: transcript noise (spinner repaints, CR churn, pass-run spam) is squashed at build time —
|
|
61
89
|
// the filtered form is what persists to the consults/ artifact AND what the model reads; fail-open.
|
|
62
90
|
export function buildDossierPrompt(d, nonce) {
|
|
@@ -108,7 +136,8 @@ opts = {}) {
|
|
|
108
136
|
// consult model reads) is masked at this seam; the in-memory Dossier stays untouched.
|
|
109
137
|
writeFileSync(promptFile, redactSecrets(buildDossierPrompt(d, nonce)));
|
|
110
138
|
// One seat = the WHOLE invoke-and-parse unit, both visibility branches (OBS-69 class: a headless-only
|
|
111
|
-
// failover would leave the production pane path hard-failing on seat one). null
|
|
139
|
+
// failover would leave the production pane path hard-failing on seat one). A null verdict retains
|
|
140
|
+
// the classifier's cause when extraction failed; parsed content rejections deliberately have none.
|
|
112
141
|
const invokeSeat = async (seatAdapter, seatModel, seatIdx) => {
|
|
113
142
|
const adapter = getAdapter(seatAdapter, adapters);
|
|
114
143
|
let out;
|
|
@@ -143,26 +172,7 @@ opts = {}) {
|
|
|
143
172
|
await driver.close(slot);
|
|
144
173
|
}
|
|
145
174
|
}
|
|
146
|
-
|
|
147
|
-
const v = extractVerdictJson(out, nonce);
|
|
148
|
-
if (!v || !ACTIONS.includes(v.action))
|
|
149
|
-
return null;
|
|
150
|
-
// fail-closed exclusion: only a non-empty string survives. Malformed values (number/array/object/
|
|
151
|
-
// empty) are dropped — the verdict stays a normal channel-level reroute/retry/…, never a crash
|
|
152
|
-
// and never silently forced to human. Unknown adapter ids pass through; the daemon treats a
|
|
153
|
-
// zero-match expansion as channel-level reroute.
|
|
154
|
-
const raw = v.excludeAdapter;
|
|
155
|
-
const excludeAdapter = typeof raw === "string" && raw.length > 0 ? raw : undefined;
|
|
156
|
-
const reason = typeof v.reason === "string" ? v.reason : undefined;
|
|
157
|
-
const guidance = typeof v.guidance === "string" ? v.guidance : undefined;
|
|
158
|
-
const notes = String(v.notes ?? guidance ?? reason ?? "");
|
|
159
|
-
return {
|
|
160
|
-
action: v.action,
|
|
161
|
-
notes,
|
|
162
|
-
...(reason ? { reason } : {}),
|
|
163
|
-
...(guidance ? { guidance } : {}),
|
|
164
|
-
...(excludeAdapter ? { excludeAdapter } : {}),
|
|
165
|
-
};
|
|
175
|
+
return parseConsultVerdict(out, nonce);
|
|
166
176
|
};
|
|
167
177
|
// v1.54 T1: ranked seat failover. Walk consult.prefer (adapter:model entries) to the first entry
|
|
168
178
|
// whose adapter is in the live channel set; a failed seat or unparseable verdict falls to the next;
|
|
@@ -176,9 +186,9 @@ opts = {}) {
|
|
|
176
186
|
seats.push({ adapter: cfg.consult.adapter, model: cfg.consult.model });
|
|
177
187
|
for (const [i, seat] of seats.entries()) {
|
|
178
188
|
try {
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
return
|
|
189
|
+
const parsed = await invokeSeat(seat.adapter, seat.model, i);
|
|
190
|
+
if (parsed.verdict)
|
|
191
|
+
return parsed.verdict;
|
|
182
192
|
}
|
|
183
193
|
catch {
|
|
184
194
|
// failed seat (unknown adapter, dead driver/pane, shell error) — fall to the next entry
|
package/dist/run/daemon.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type WorkerAdapter } from "../adapters/types.js";
|
|
2
2
|
import { type ModeResolution, type RoutingMode, type TickmarkrConfig } from "../config/config.js";
|
|
3
3
|
import { type ExecutorDriver } from "../drivers/types.js";
|
|
4
|
-
import { type JournalEvent } from "./journal.js";
|
|
4
|
+
import { Journal, type JournalEvent } from "./journal.js";
|
|
5
5
|
export interface RunOptions {
|
|
6
6
|
runId?: string;
|
|
7
7
|
resume?: boolean;
|
|
@@ -42,13 +42,59 @@ export interface RunSummary {
|
|
|
42
42
|
lastMergedTask?: string;
|
|
43
43
|
}
|
|
44
44
|
export declare function formatSummary(s: RunSummary): string;
|
|
45
|
+
/**
|
|
46
|
+
* T4 (OBS-265): the journal with the review objections a round did NOT hinge on removed. Judge and
|
|
47
|
+
* review are now launched together, so a round can journal a failed review that the serial walk would
|
|
48
|
+
* never have asked for — it returned at the judge. Those verdicts stay on the record (they are real,
|
|
49
|
+
* and the retry brief carries them), but they must not spend the OPERATOR-facing review round budget:
|
|
50
|
+
* otherwise concurrency alone parks a task rounds early for objections the old pipeline never bought.
|
|
51
|
+
* A round is the gate-result span opened by each `gates` phase-start, per task.
|
|
52
|
+
*/
|
|
53
|
+
export declare function decisiveReviewRounds(events: JournalEvent[]): JournalEvent[];
|
|
45
54
|
export declare const EARLY_LAUNCH_LIVENESS_MS = 60000;
|
|
46
55
|
/** Test seam — lowers the empty-pane liveness window without sleeping 60s per case. */
|
|
47
56
|
export declare function setEarlyLaunchLivenessMsForTests(ms: number): void;
|
|
48
57
|
export declare function resetEarlyLaunchLivenessMsForTests(): void;
|
|
49
|
-
export
|
|
58
|
+
export { NUDGEABLE_ADAPTERS } from "./stall.js";
|
|
50
59
|
export declare const WORKER_NUDGE_MESSAGE = "tickmarkr liveness check: if the task is complete, print your TICKMARKR_RESULT completion trailer exactly as specified in your prompt now. If not, state your next concrete action and continue working.";
|
|
51
60
|
/** Test seam — shrink the nudge gate and grace without minute-long sleeps. */
|
|
52
61
|
export declare function setNudgeTimingForTests(silentMs: number, graceMs: number): void;
|
|
53
62
|
export declare function resetNudgeTimingForTests(): void;
|
|
63
|
+
/** Test seam — shrink the quota-banner silence gate without minute-long sleeps. */
|
|
64
|
+
export declare function setQuotaBannerSilentMsForTests(ms: number): void;
|
|
65
|
+
export declare function resetQuotaBannerSilentMsForTests(): void;
|
|
66
|
+
/** Test seam — shrink the repeat-page cadence without minute-long sleeps. */
|
|
67
|
+
export declare function setPageRepeatMsForTests(ms: number): void;
|
|
68
|
+
export declare function resetPageRepeatMsForTests(): void;
|
|
69
|
+
/** Test seam — shrink the fast-kill window without minute-long sleeps. */
|
|
70
|
+
export declare function setDeadChannelFastKillMsForTests(ms: number): void;
|
|
71
|
+
export declare function resetDeadChannelFastKillMsForTests(): void;
|
|
72
|
+
/** Test seam — shrink the harvest silence gate without minute-long sleeps. */
|
|
73
|
+
export declare function setHarvestSilentMsForTests(ms: number): void;
|
|
74
|
+
export declare function resetHarvestSilentMsForTests(): void;
|
|
75
|
+
export declare function harvestCpuFlatWindowMs(resolutionMs: number): number;
|
|
76
|
+
/** Test seam — pin the flat window so a probe case need not sit through a real one. */
|
|
77
|
+
export declare function setHarvestCpuFlatMsForTests(ms: number): void;
|
|
78
|
+
export declare function resetHarvestCpuFlatMsForTests(): void;
|
|
79
|
+
export declare const HARVESTED_RESULT_SUMMARY = "harvested: the worktree carries committed work; the worker emitted no TICKMARKR_RESULT trailer";
|
|
80
|
+
/** T4 (OBS-266): identity of the command SET a tip verify ran — a changed command is a different verify. */
|
|
81
|
+
export declare function commandsHash(commands: Record<string, string>): string;
|
|
82
|
+
/**
|
|
83
|
+
* OBS-34's strict tip verify, but it stops re-paying for an unmoved tip (~334m corpus-wide; 69.5m in
|
|
84
|
+
* one park-heavy run whose 18 resume cycles merged nothing new). The verify journals the SHA it
|
|
85
|
+
* verified and the hash of the command set, so a later run-end can recognize the same verified state:
|
|
86
|
+
* head equals the LAST green verified SHA, commands unchanged, tree clean → journal
|
|
87
|
+
* `tip-verify-cached` and skip. ANY doubt — moved head, changed commands, dirty tree, a gate missing
|
|
88
|
+
* from that cycle's green set, a failure recorded in it, a cycle older than the last one — runs the
|
|
89
|
+
* full verify. The tip-verify-before-green law is untouched: a cached green is a verified green OF
|
|
90
|
+
* THAT EXACT COMMIT, established by the most recent real run of the same commands.
|
|
91
|
+
* Returns whether the tip is failing.
|
|
92
|
+
*/
|
|
93
|
+
export declare function verifyIntegrationTipCached(intWt: string, commands: Record<string, string>, journal: Journal, opts?: {
|
|
94
|
+
lastMergedTask?: string;
|
|
95
|
+
}): Promise<boolean>;
|
|
96
|
+
export declare function workerTreeCpuMs(marker: string, cwd: string): Promise<{
|
|
97
|
+
ms: number;
|
|
98
|
+
resolutionMs: number;
|
|
99
|
+
} | undefined>;
|
|
54
100
|
export declare function runDaemon(repoRoot: string, opts?: RunOptions): Promise<RunSummary>;
|