tickmarkr 1.90.3 → 1.90.5
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.
|
@@ -89,12 +89,20 @@ function providerModels(modelsDev, preferred) {
|
|
|
89
89
|
: [];
|
|
90
90
|
// Price is provider-specific. A provider-qualified query must never borrow an identically named
|
|
91
91
|
// model from another provider, where subscription and metered costs can differ materially.
|
|
92
|
-
|
|
92
|
+
// D-OBS-11 follow-up: that rule presumes the hinted provider EXISTS in the catalog. A hint that
|
|
93
|
+
// matches nothing (kimi's "moonshot" vs the catalog's "moonshotai"/"kimi-for-coding"; cursor has
|
|
94
|
+
// no provider at all) used to ZERO the search space and blanket-uncover the whole adapter.
|
|
95
|
+
// Fail open to the full scan instead — advisory evidence with a visible models.dev id beats none.
|
|
96
|
+
const selected = preferred && preferredEntries.length > 0 ? preferredEntries : entries;
|
|
93
97
|
return selected
|
|
94
98
|
.map(([, provider]) => record(record(provider)?.models))
|
|
95
99
|
.filter((models) => models !== undefined);
|
|
96
100
|
}
|
|
97
101
|
function findModelsDevModel(catalog, provider, modelId) {
|
|
102
|
+
// CLI namespaces prefix their catalog ids (kimi-code/k3 vs catalog key k3; omp's openai/gpt-4):
|
|
103
|
+
// after exact key/id misses, retry with the bare segment after the last "/". Deterministic
|
|
104
|
+
// provider order; first hit wins — acceptable for advisory evidence, never routing.
|
|
105
|
+
const bare = modelId.includes("/") ? modelId.slice(modelId.lastIndexOf("/") + 1) : undefined;
|
|
98
106
|
for (const models of providerModels(catalog.modelsDev, provider)) {
|
|
99
107
|
const direct = record(models[modelId]);
|
|
100
108
|
if (direct)
|
|
@@ -103,6 +111,13 @@ function findModelsDevModel(catalog, provider, modelId) {
|
|
|
103
111
|
if (byId)
|
|
104
112
|
return byId;
|
|
105
113
|
}
|
|
114
|
+
if (bare) {
|
|
115
|
+
for (const models of providerModels(catalog.modelsDev, provider)) {
|
|
116
|
+
const direct = record(models[bare]);
|
|
117
|
+
if (direct)
|
|
118
|
+
return direct;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
106
121
|
return undefined;
|
|
107
122
|
}
|
|
108
123
|
function artificialAnalysisRows(value) {
|
|
@@ -11,8 +11,9 @@ export const MODEL_STALE_DAYS = 30;
|
|
|
11
11
|
const DAY_MS = 86400000;
|
|
12
12
|
// cursor-agent 2026.07.08 reports 193 mostly-parameterized ids (e.g. gpt-5.3-codex-high-fast); filter the `auto`
|
|
13
13
|
// pseudo-model + effort/speed variant suffixes from the unconfigured-lint aggregation ONLY — doctor.json keeps the
|
|
14
|
-
// raw list (verified 2026-07-10). Data stays raw; lints stay signal.
|
|
15
|
-
|
|
14
|
+
// raw list (verified 2026-07-10). Data stays raw; lints stay signal. -max/-none/-thinking joined the suffix set
|
|
15
|
+
// 2026-08-12 (D-OBS-11: cursor's residual lint list was still mostly effort variants of configured bases).
|
|
16
|
+
const LINT_VARIANT_RE = /^auto$|-(fast|minimal|none|low|medium|high|xhigh|max|thinking)$/;
|
|
16
17
|
const LINT_CAP = 5;
|
|
17
18
|
const TTY_LINT_CAP = 3;
|
|
18
19
|
const DEFAULT_STATE_DIR = ".tickmarkr";
|
|
@@ -40,4 +40,19 @@ export declare function packageManagerFinding(cwd: string, probe?: (pm: string)
|
|
|
40
40
|
verdict: "pass" | "fail";
|
|
41
41
|
detail: string;
|
|
42
42
|
} | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Q142s: tickmarkr guarded every binary except its own. Exhibit (operator machine,
|
|
45
|
+
* 2026-08-12): an orphaned npm-prefix root at ~/.local held tickmarkr AND tkr at
|
|
46
|
+
* 1.85.0 beside the live 1.90.3 — two seats disagreed about the tool's version and
|
|
47
|
+
* were BOTH right about their own PATH order (a consultant reported "no verify
|
|
48
|
+
* command" — verify shipped in 1.90.0 — while the overseer saw it present). Checks
|
|
49
|
+
* EVERY bin name the package declares: the first sweep of that machine missed `tkr`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function selfShadowFinding(ownVersion: string, cwd?: string, resolve?: (bin: string, cwd: string) => {
|
|
52
|
+
resolved?: string;
|
|
53
|
+
all: string[];
|
|
54
|
+
}, versionOf?: (path: string) => string | undefined): {
|
|
55
|
+
verdict: "pass" | "fail";
|
|
56
|
+
detail: string;
|
|
57
|
+
} | undefined;
|
|
43
58
|
export declare function doctor(_argv: string[], cwd?: string, adapters?: WorkerAdapter[], opts?: DoctorOpts): Promise<string>;
|
|
@@ -3,7 +3,8 @@ import { spawnSync } from "node:child_process";
|
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { detectPackageManager } from "../../gates/baseline.js";
|
|
6
|
-
import {
|
|
6
|
+
import { version } from "./version.js";
|
|
7
|
+
import { allAdapters, binaryShadowWarnings, detectCandidateClis, flagDriftWarnings, modelAliasExclusions, modelAliasLine, probeAll, probeModels, resolveShellBinary, servableExclusions, servabilityLine, writeDoctor } from "../../adapters/registry.js";
|
|
7
8
|
import { CLAUDE_ALIAS_IDENTITY_STAMPS, claudeCode, resolveClaudeAliasIdentity } from "../../adapters/claude-code.js";
|
|
8
9
|
import { BANNER, dim, fail, kvRow, legend, ok, rule, statusRow, title } from "../../brand.js";
|
|
9
10
|
import { tickmarkrDir, stateDirName } from "../../graph/graph.js";
|
|
@@ -170,6 +171,40 @@ export function packageManagerFinding(cwd, probe = (pm) => spawnSync(pm, ["--ver
|
|
|
170
171
|
detail: `repo uses ${pm} but the binary does not resolve in this environment — every auto-detected gate command will die before running any suite (fix: corepack enable, or install ${pm} on the daemon's PATH)`,
|
|
171
172
|
};
|
|
172
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Q142s: tickmarkr guarded every binary except its own. Exhibit (operator machine,
|
|
176
|
+
* 2026-08-12): an orphaned npm-prefix root at ~/.local held tickmarkr AND tkr at
|
|
177
|
+
* 1.85.0 beside the live 1.90.3 — two seats disagreed about the tool's version and
|
|
178
|
+
* were BOTH right about their own PATH order (a consultant reported "no verify
|
|
179
|
+
* command" — verify shipped in 1.90.0 — while the overseer saw it present). Checks
|
|
180
|
+
* EVERY bin name the package declares: the first sweep of that machine missed `tkr`.
|
|
181
|
+
*/
|
|
182
|
+
export function selfShadowFinding(ownVersion, cwd = process.cwd(), resolve = resolveShellBinary, versionOf = (p) => {
|
|
183
|
+
const r = spawnSync(p, ["version"], { encoding: "utf8", timeout: 5_000, shell: false });
|
|
184
|
+
return r.status === 0 ? r.stdout.trim().split("\n")[0] : undefined;
|
|
185
|
+
}) {
|
|
186
|
+
const hits = new Map(); // path -> version
|
|
187
|
+
for (const bin of ["tickmarkr", "tkr"]) {
|
|
188
|
+
for (const p of resolve(bin, cwd).all) {
|
|
189
|
+
if (!hits.has(p))
|
|
190
|
+
hits.set(p, versionOf(p) ?? "?");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (hits.size === 0)
|
|
194
|
+
return undefined; // no install on PATH (repo checkout) — nothing to shadow
|
|
195
|
+
const stale = [...hits].filter(([, v]) => v !== ownVersion);
|
|
196
|
+
if (stale.length === 0) {
|
|
197
|
+
return { verdict: "pass", detail: `single install root at ${ownVersion} (${[...hits.keys()].join(", ")})` };
|
|
198
|
+
}
|
|
199
|
+
const listing = stale.map(([p, v]) => `${p} → ${v}`).join(", ");
|
|
200
|
+
// One mismatched hit and it's the one running? Impossible — it would report ownVersion.
|
|
201
|
+
// Mismatch therefore means a SECOND root: a shell or daemon with a different PATH
|
|
202
|
+
// order runs a different tickmarkr than this one, silently.
|
|
203
|
+
return {
|
|
204
|
+
verdict: "fail",
|
|
205
|
+
detail: `stale tickmarkr/tkr binaries on PATH: ${listing} (running ${ownVersion}) — a seat with different PATH order silently runs the old binary; remove the stale install root`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
173
208
|
export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(), opts = {}) {
|
|
174
209
|
if (_argv.length === 1 && _argv[0] === "--refresh-catalog") {
|
|
175
210
|
const refreshed = await refreshCatalogCommand({ repoRoot: cwd, now: opts.catalogNow });
|
|
@@ -265,6 +300,10 @@ export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(
|
|
|
265
300
|
const pmRow = packageManagerFinding(cwd);
|
|
266
301
|
if (pmRow)
|
|
267
302
|
rows.push(alignedStatusRow(pmRow.verdict, "package-manager", pmRow.detail));
|
|
303
|
+
// Q142s: tickmarkr's own binary gets the shadow check every adapter binary already had.
|
|
304
|
+
const shadowRow = selfShadowFinding(await version(), cwd);
|
|
305
|
+
if (shadowRow)
|
|
306
|
+
rows.push(alignedStatusRow(shadowRow.verdict, "tickmarkr-binary", shadowRow.detail));
|
|
268
307
|
// v1.22 T5: workspace-trust pre-flight — per installed adapter: trusted | seeded | action-required | n/a.
|
|
269
308
|
// action-required names the exact one-time command (or dialog) the operator must run once.
|
|
270
309
|
rows.push(legend("workspace trust:"));
|