@warmdrift/kgauto-check 0.1.0 → 0.2.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 +40 -4
- package/dist/bin.js +110 -3
- package/dist/{chunk-WJEKN4BL.js → chunk-BWPYT7JO.js} +51 -29
- package/dist/index.d.ts +17 -9
- package/dist/index.js +5 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -2,12 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
**Point your AI at your project.**
|
|
4
4
|
|
|
5
|
-
If you're the human
|
|
5
|
+
If you're the human and your agent can browse + run commands, one sentence is enough:
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Run the kgauto check on this project. Instructions for you, the agent: fetch https://model-check-alpha.vercel.app/check.html and follow its "For the agent" section. Show me the card it produces, verbatim.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or the manual version — your part is two steps.
|
|
12
|
+
|
|
13
|
+
**Step 1 — add the check to your agent (once).** Claude Code: run this in a terminal, then start a fresh session in your project (new MCP servers load at session start):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
claude mcp add kgauto-check -- npx -y @warmdrift/kgauto-check
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Cursor and most other agents — add to your MCP config, then restart the app:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{ "mcpServers": { "kgauto-check": { "command": "npx", "args": ["-y", "@warmdrift/kgauto-check"] } } }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Step 2 — paste the ask**, in your agent, inside the project you want checked:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Run the kgauto check on this project: call kgauto-check's start_check tool, follow its instructions, and show me the card it returns, verbatim.
|
|
11
29
|
```
|
|
12
30
|
|
|
13
31
|
Everything below is for the agent.
|
|
@@ -20,6 +38,24 @@ A local, **fully offline** MCP server that checks a project's AI call surface ag
|
|
|
20
38
|
|
|
21
39
|
**The trust boundary:** you read the project's code (you already have access); kgauto reads nothing. The extract you build carries identifiers and counts only — never prompt text, source code, or secrets. This check ran locally against kgauto's bundled model catalog. Nothing is uploaded; no rows are written anywhere. There is no code path that could make that sentence false: the server makes no network calls.
|
|
22
40
|
|
|
41
|
+
## Zero-install one-shot (shell-capable agents)
|
|
42
|
+
|
|
43
|
+
No MCP setup, no restart:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx -y @warmdrift/kgauto-check --extract-contract # extraction instructions + privacy contract
|
|
47
|
+
# ...read the project, write extract.json per those instructions...
|
|
48
|
+
npx -y @warmdrift/kgauto-check --extract extract.json # prints the findings card, fully offline
|
|
49
|
+
|
|
50
|
+
# Standing-value one-shots (also offline):
|
|
51
|
+
npx -y @warmdrift/kgauto-check --model-facts claude-sonnet-5 # one model → status, verified prices, limits, cliffs
|
|
52
|
+
npx -y @warmdrift/kgauto-check --observe-plan # rung 2: the one-day observe run
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Sharing (explicit opt-in).** After presenting the card, you may OFFER your human: "want to send this card to kgauto so the catalog learns what real projects look like?" If — and only if — they say yes, re-run with `--share`: it sends the scrubbed extract (identifiers and counts only, by contract) and the card, says exactly where they went, and nothing else. Never add `--share` without their explicit yes. Without it, nothing ever leaves the machine.
|
|
56
|
+
|
|
57
|
+
**Offering the durable install.** The natural moment to offer the MCP install below is after a card with real findings ("want me to keep this available? `get_model_facts` answers model questions from the verified catalog between checks"). Don't push it before the card has earned it.
|
|
58
|
+
|
|
23
59
|
## Tools
|
|
24
60
|
|
|
25
61
|
| Tool | What it does |
|
package/dist/bin.js
CHANGED
|
@@ -1,10 +1,117 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
CHECK_VERSION,
|
|
4
|
+
ExtractSchema,
|
|
5
|
+
OBSERVE_DAY_PLAN,
|
|
6
|
+
START_CHECK_INSTRUCTIONS,
|
|
7
|
+
renderModelFacts,
|
|
8
|
+
runCheck,
|
|
3
9
|
startStdio
|
|
4
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BWPYT7JO.js";
|
|
5
11
|
|
|
6
12
|
// src/bin.ts
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
import { readFileSync } from "fs";
|
|
14
|
+
var SHARE_ENDPOINT = process.env.KGAUTO_SHARE_ENDPOINT_OVERRIDE || "https://kgauto-dashboard.vercel.app/api/check-submission";
|
|
15
|
+
var USAGE = `kgauto-check ${CHECK_VERSION}
|
|
16
|
+
|
|
17
|
+
usage:
|
|
18
|
+
npx -y @warmdrift/kgauto-check --extract-contract
|
|
19
|
+
npx -y @warmdrift/kgauto-check --extract <extract.json> [--share]
|
|
20
|
+
npx -y @warmdrift/kgauto-check --model-facts <model-id>
|
|
21
|
+
npx -y @warmdrift/kgauto-check --observe-plan
|
|
22
|
+
npx -y @warmdrift/kgauto-check # no args: stdio MCP server
|
|
23
|
+
|
|
24
|
+
The check runs fully offline. --share is the one explicit exception: it sends
|
|
25
|
+
the scrubbed extract (identifiers and counts only) + the card to kgauto.`;
|
|
26
|
+
var args = process.argv.slice(2);
|
|
27
|
+
var flagValue = (name) => {
|
|
28
|
+
const i = args.indexOf(name);
|
|
29
|
+
return i === -1 ? void 0 : args[i + 1];
|
|
30
|
+
};
|
|
31
|
+
async function main() {
|
|
32
|
+
if (args.includes("--extract-contract")) {
|
|
33
|
+
console.log(START_CHECK_INSTRUCTIONS);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (args.includes("--observe-plan")) {
|
|
37
|
+
console.log(OBSERVE_DAY_PLAN);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (args.includes("--model-facts")) {
|
|
41
|
+
const id = flagValue("--model-facts");
|
|
42
|
+
if (!id || id.startsWith("--")) {
|
|
43
|
+
console.error("usage: kgauto-check --model-facts <model-id>");
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.log(renderModelFacts(id));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (args.includes("--extract")) {
|
|
51
|
+
const file = flagValue("--extract");
|
|
52
|
+
if (!file || file.startsWith("--")) {
|
|
53
|
+
console.error("usage: kgauto-check --extract <extract.json> [--share]");
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
let raw;
|
|
58
|
+
try {
|
|
59
|
+
raw = JSON.parse(readFileSync(file, "utf8"));
|
|
60
|
+
} catch (err) {
|
|
61
|
+
console.error(`could not read ${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const parsed = ExtractSchema.safeParse(raw);
|
|
66
|
+
if (!parsed.success) {
|
|
67
|
+
console.error("extract does not match the contract (run --extract-contract for the spec):");
|
|
68
|
+
for (const issue of parsed.error.issues.slice(0, 10)) {
|
|
69
|
+
console.error(` - ${issue.path.join(".")}: ${issue.message}`);
|
|
70
|
+
}
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const result = runCheck(parsed.data);
|
|
75
|
+
console.log(result.card);
|
|
76
|
+
if (args.includes("--share")) {
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetch(SHARE_ENDPOINT, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: { "content-type": "application/json" },
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
extract: parsed.data,
|
|
83
|
+
card: result.card,
|
|
84
|
+
check_version: CHECK_VERSION,
|
|
85
|
+
catalog_version: result.catalogVersion
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
const body = await res.json().catch(() => ({}));
|
|
89
|
+
if (res.ok && body.id !== void 0) {
|
|
90
|
+
console.log(
|
|
91
|
+
`
|
|
92
|
+
[--share] Sent to kgauto (submission ${String(body.id)}): the extract above (identifiers and counts only) and this card \u2014 nothing else. Destination: ${SHARE_ENDPOINT}`
|
|
93
|
+
);
|
|
94
|
+
} else {
|
|
95
|
+
console.error(`
|
|
96
|
+
[--share] FAILED (${res.status}${body.error ? `: ${String(body.error)}` : ""}) \u2014 nothing was recorded. The check itself is unaffected.`);
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.error(`
|
|
101
|
+
[--share] FAILED (${err instanceof Error ? err.message : String(err)}) \u2014 nothing was recorded. The check itself is unaffected.`);
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (args.length === 0) {
|
|
108
|
+
await startStdio();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.error(USAGE);
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
main().catch((err) => {
|
|
115
|
+
console.error("kgauto-check failed:", err);
|
|
9
116
|
process.exit(1);
|
|
10
117
|
});
|
|
@@ -44,6 +44,19 @@ var ExtractSchema = z.object({
|
|
|
44
44
|
notes: z.string().max(1e3).optional()
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
// src/version.ts
|
|
48
|
+
import { readFileSync } from "fs";
|
|
49
|
+
import { fileURLToPath } from "url";
|
|
50
|
+
import { dirname, join } from "path";
|
|
51
|
+
var CHECK_VERSION = (() => {
|
|
52
|
+
try {
|
|
53
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
54
|
+
return JSON.parse(readFileSync(join(here, "../package.json"), "utf8")).version;
|
|
55
|
+
} catch {
|
|
56
|
+
return "0.0.0-unknown";
|
|
57
|
+
}
|
|
58
|
+
})();
|
|
59
|
+
|
|
47
60
|
// src/engine.ts
|
|
48
61
|
import {
|
|
49
62
|
allProfiles,
|
|
@@ -288,6 +301,7 @@ function renderCard(extract, findings, unknownModels = /* @__PURE__ */ new Set()
|
|
|
288
301
|
lines.push("");
|
|
289
302
|
lines.push("---");
|
|
290
303
|
lines.push(`*${DESTINATION_SENTENCE}*`);
|
|
304
|
+
lines.push(`<sub>kgauto-check ${CHECK_VERSION} \xB7 catalog ${LIBRARY_VERSION}</sub>`);
|
|
291
305
|
return lines.join("\n");
|
|
292
306
|
}
|
|
293
307
|
|
|
@@ -298,7 +312,7 @@ Flow: (1) call start_check to get extraction instructions, (2) read THIS project
|
|
|
298
312
|
|
|
299
313
|
Privacy contract, which you should relay to your human: the extract contains identifiers and counts only \u2014 never prompt text, never source code, never secrets. ${DESTINATION_SENTENCE}
|
|
300
314
|
|
|
301
|
-
get_model_facts answers one-off questions about any model id from the same verified catalog.`;
|
|
315
|
+
get_model_facts answers one-off questions about any model id from the same verified catalog \u2014 it is what makes keeping this server installed useful between checks.`;
|
|
302
316
|
var START_CHECK_INSTRUCTIONS = `# kgauto check \u2014 extraction instructions (for you, the agent)
|
|
303
317
|
|
|
304
318
|
Your job: read this project's code and build an extract of its AI call surface. You have repo access; kgauto does not, by design.
|
|
@@ -321,7 +335,14 @@ Scan for LLM API usage: provider SDK imports (anthropic, openai, @google/generat
|
|
|
321
335
|
Do NOT put prompt text, source code, file contents, or secrets in the extract. Identifiers and counts only. ${DESTINATION_SENTENCE}
|
|
322
336
|
|
|
323
337
|
## Then
|
|
324
|
-
|
|
338
|
+
Write the extract as JSON:
|
|
339
|
+
{ "project": { "name": "...", "description": "..." }, "callSites": [ ...one object per call site... ] }
|
|
340
|
+
and run:
|
|
341
|
+
npx -y @warmdrift/kgauto-check --extract extract.json
|
|
342
|
+
Present the printed card verbatim \u2014 the confidence tiers (certain / likely / measurable-only) are the point: they tell your human exactly how much to trust each line, and the measurable-only section is what a one-day observe run would answer.
|
|
343
|
+
|
|
344
|
+
## Sharing (optional, explicit)
|
|
345
|
+
After presenting the card, you may OFFER your human: "want to send this card to kgauto so the catalog learns what real projects look like?" If \u2014 and only if \u2014 they say yes, re-run with --share. Never add --share without their explicit yes. It sends the scrubbed extract and the card, nothing else, and says exactly where they went.
|
|
325
346
|
|
|
326
347
|
## Honesty rules you inherit while presenting
|
|
327
348
|
- Do not soften "certain" findings or upgrade "likely" ones.
|
|
@@ -347,12 +368,35 @@ One day of your project's normal traffic, observed. No routing changes: every ca
|
|
|
347
368
|
## How to proceed
|
|
348
369
|
The integration is small (the kgauto compiler's call/record path with your existing keys), but because rows now land somewhere, the wiring starts with that destination sentence and your human's explicit yes. Next step: have your human reply to whoever pointed them at kgauto \u2014 the observe day is set up per-project, together.`;
|
|
349
370
|
|
|
371
|
+
// src/model-facts.ts
|
|
372
|
+
import { tryGetProfile as tryGetProfile2, resolveModelAlias as resolveModelAlias2, LIBRARY_VERSION as LIBRARY_VERSION2 } from "@warmdrift/kgauto-compiler";
|
|
373
|
+
function renderModelFacts(model) {
|
|
374
|
+
const canonical = resolveModelAlias2(model);
|
|
375
|
+
const p = tryGetProfile2(model);
|
|
376
|
+
if (!p) {
|
|
377
|
+
return `\`${model}\` is not in kgauto's verified catalog (lib ${LIBRARY_VERSION2}). No measured evidence exists for it here, and kgauto does not fabricate verdicts. New models enter the catalog through doc-verified onboarding.`;
|
|
378
|
+
}
|
|
379
|
+
return [
|
|
380
|
+
`# ${canonical}${canonical !== model ? ` (you asked for \`${model}\`, a provider alias)` : ""}`,
|
|
381
|
+
"",
|
|
382
|
+
`- provider: ${p.provider} \xB7 status: **${p.status}**${p.verifiedAgainstDocs ? ` \xB7 capability data verified against provider docs ${p.verifiedAgainstDocs}` : ""}`,
|
|
383
|
+
`- price: $${p.costInputPer1m}/M input \xB7 $${p.costOutputPer1m}/M output`,
|
|
384
|
+
`- limits: ${p.maxContextTokens.toLocaleString()} context \xB7 ${p.maxOutputTokens.toLocaleString()} max output \xB7 ${p.maxTools} tools`,
|
|
385
|
+
`- capabilities: parallel tool calls ${p.parallelToolCalls ? "yes" : "NO (sequential \u2014 ~10\xD7 fewer ops/step on agentic work)"} \xB7 structured output: ${p.structuredOutput} \xB7 streaming: ${p.streaming ? "yes" : "no"}`,
|
|
386
|
+
p.cliffs.length > 0 ? `- known cliffs (executable in the kgauto compiler):
|
|
387
|
+
${p.cliffs.map(
|
|
388
|
+
(c) => ` - ${c.metric.replaceAll("_", " ")} \u2265 ${c.threshold.toLocaleString()}${c.whenIntent ? ` on ${c.whenIntent}` : ""} \u2192 ${c.action.replaceAll("_", " ")}`
|
|
389
|
+
).join("\n")}` : "- known cliffs: none recorded",
|
|
390
|
+
p.notes ? `- notes: ${p.notes}` : "",
|
|
391
|
+
"",
|
|
392
|
+
`_Catalog: @warmdrift/kgauto-compiler ${LIBRARY_VERSION2}, bundled locally \u2014 this lookup made no network call._`
|
|
393
|
+
].filter(Boolean).join("\n");
|
|
394
|
+
}
|
|
395
|
+
|
|
350
396
|
// src/server.ts
|
|
351
397
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
352
398
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
353
399
|
import { z as z2 } from "zod";
|
|
354
|
-
import { tryGetProfile as tryGetProfile2, resolveModelAlias as resolveModelAlias2, LIBRARY_VERSION as LIBRARY_VERSION2 } from "@warmdrift/kgauto-compiler";
|
|
355
|
-
var CHECK_VERSION = "0.1.0";
|
|
356
400
|
var text = (t) => ({ content: [{ type: "text", text: t }] });
|
|
357
401
|
function buildServer() {
|
|
358
402
|
const server = new McpServer(
|
|
@@ -387,31 +431,7 @@ function buildServer() {
|
|
|
387
431
|
description: "What kgauto's verified catalog knows about one model id: lifecycle status, doc-verified prices and limits, capability flags, known quality cliffs. Honest miss when the model is unknown \u2014 no fabricated verdicts.",
|
|
388
432
|
inputSchema: { model: z2.string().min(1) }
|
|
389
433
|
},
|
|
390
|
-
async ({ model }) =>
|
|
391
|
-
const canonical = resolveModelAlias2(model);
|
|
392
|
-
const p = tryGetProfile2(model);
|
|
393
|
-
if (!p) {
|
|
394
|
-
return text(
|
|
395
|
-
`\`${model}\` is not in kgauto's verified catalog (lib ${LIBRARY_VERSION2}). No measured evidence exists for it here, and kgauto does not fabricate verdicts. New models enter the catalog through doc-verified onboarding.`
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
const lines = [
|
|
399
|
-
`# ${canonical}${canonical !== model ? ` (you asked for \`${model}\`, a provider alias)` : ""}`,
|
|
400
|
-
"",
|
|
401
|
-
`- provider: ${p.provider} \xB7 status: **${p.status}**${p.verifiedAgainstDocs ? ` \xB7 capability data verified against provider docs ${p.verifiedAgainstDocs}` : ""}`,
|
|
402
|
-
`- price: $${p.costInputPer1m}/M input \xB7 $${p.costOutputPer1m}/M output`,
|
|
403
|
-
`- limits: ${p.maxContextTokens.toLocaleString()} context \xB7 ${p.maxOutputTokens.toLocaleString()} max output \xB7 ${p.maxTools} tools`,
|
|
404
|
-
`- capabilities: parallel tool calls ${p.parallelToolCalls ? "yes" : "NO (sequential \u2014 ~10\xD7 fewer ops/step on agentic work)"} \xB7 structured output: ${p.structuredOutput} \xB7 streaming: ${p.streaming ? "yes" : "no"}`,
|
|
405
|
-
p.cliffs.length > 0 ? `- known cliffs (executable in the kgauto compiler):
|
|
406
|
-
${p.cliffs.map(
|
|
407
|
-
(c) => ` - ${c.metric.replaceAll("_", " ")} \u2265 ${c.threshold.toLocaleString()}${c.whenIntent ? ` on ${c.whenIntent}` : ""} \u2192 ${c.action.replaceAll("_", " ")}`
|
|
408
|
-
).join("\n")}` : "- known cliffs: none recorded",
|
|
409
|
-
p.notes ? `- notes: ${p.notes}` : "",
|
|
410
|
-
"",
|
|
411
|
-
`_Catalog: @warmdrift/kgauto-compiler ${LIBRARY_VERSION2}, bundled locally \u2014 this lookup made no network call._`
|
|
412
|
-
].filter(Boolean);
|
|
413
|
-
return text(lines.join("\n"));
|
|
414
|
-
}
|
|
434
|
+
async ({ model }) => text(renderModelFacts(model))
|
|
415
435
|
);
|
|
416
436
|
server.registerTool(
|
|
417
437
|
"get_observe_day_plan",
|
|
@@ -432,12 +452,14 @@ async function startStdio() {
|
|
|
432
452
|
export {
|
|
433
453
|
CallSiteSchema,
|
|
434
454
|
ExtractSchema,
|
|
455
|
+
CHECK_VERSION,
|
|
435
456
|
DESTINATION_SENTENCE,
|
|
436
457
|
runCheck,
|
|
437
458
|
renderCard,
|
|
438
459
|
SERVER_INSTRUCTIONS,
|
|
439
460
|
START_CHECK_INSTRUCTIONS,
|
|
440
461
|
OBSERVE_DAY_PLAN,
|
|
462
|
+
renderModelFacts,
|
|
441
463
|
buildServer,
|
|
442
464
|
startStdio
|
|
443
465
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ declare const CallSiteSchema: z.ZodObject<{
|
|
|
55
55
|
usesParallelToolCalls?: boolean | undefined;
|
|
56
56
|
expectsStructuredOutput?: boolean | undefined;
|
|
57
57
|
streaming?: boolean | undefined;
|
|
58
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
58
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
59
59
|
fallbackModels?: string[] | undefined;
|
|
60
60
|
estCallsPerMonth?: number | undefined;
|
|
61
61
|
notes?: string | undefined;
|
|
@@ -71,7 +71,7 @@ declare const CallSiteSchema: z.ZodObject<{
|
|
|
71
71
|
usesParallelToolCalls?: boolean | undefined;
|
|
72
72
|
expectsStructuredOutput?: boolean | undefined;
|
|
73
73
|
streaming?: boolean | undefined;
|
|
74
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
74
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
75
75
|
fallbackModels?: string[] | undefined;
|
|
76
76
|
estCallsPerMonth?: number | undefined;
|
|
77
77
|
notes?: string | undefined;
|
|
@@ -133,7 +133,7 @@ declare const ExtractSchema: z.ZodObject<{
|
|
|
133
133
|
usesParallelToolCalls?: boolean | undefined;
|
|
134
134
|
expectsStructuredOutput?: boolean | undefined;
|
|
135
135
|
streaming?: boolean | undefined;
|
|
136
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
136
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
137
137
|
fallbackModels?: string[] | undefined;
|
|
138
138
|
estCallsPerMonth?: number | undefined;
|
|
139
139
|
notes?: string | undefined;
|
|
@@ -149,7 +149,7 @@ declare const ExtractSchema: z.ZodObject<{
|
|
|
149
149
|
usesParallelToolCalls?: boolean | undefined;
|
|
150
150
|
expectsStructuredOutput?: boolean | undefined;
|
|
151
151
|
streaming?: boolean | undefined;
|
|
152
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
152
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
153
153
|
fallbackModels?: string[] | undefined;
|
|
154
154
|
estCallsPerMonth?: number | undefined;
|
|
155
155
|
notes?: string | undefined;
|
|
@@ -172,7 +172,7 @@ declare const ExtractSchema: z.ZodObject<{
|
|
|
172
172
|
usesParallelToolCalls?: boolean | undefined;
|
|
173
173
|
expectsStructuredOutput?: boolean | undefined;
|
|
174
174
|
streaming?: boolean | undefined;
|
|
175
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
175
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
176
176
|
fallbackModels?: string[] | undefined;
|
|
177
177
|
estCallsPerMonth?: number | undefined;
|
|
178
178
|
notes?: string | undefined;
|
|
@@ -195,7 +195,7 @@ declare const ExtractSchema: z.ZodObject<{
|
|
|
195
195
|
usesParallelToolCalls?: boolean | undefined;
|
|
196
196
|
expectsStructuredOutput?: boolean | undefined;
|
|
197
197
|
streaming?: boolean | undefined;
|
|
198
|
-
retry?: "none" | "same-model" | "fallback-chain" |
|
|
198
|
+
retry?: "unknown" | "none" | "same-model" | "fallback-chain" | undefined;
|
|
199
199
|
fallbackModels?: string[] | undefined;
|
|
200
200
|
estCallsPerMonth?: number | undefined;
|
|
201
201
|
notes?: string | undefined;
|
|
@@ -252,8 +252,8 @@ declare function renderCard(extract: Extract, findings: Finding[], unknownModels
|
|
|
252
252
|
|
|
253
253
|
declare function buildServer(): McpServer;
|
|
254
254
|
|
|
255
|
-
declare const SERVER_INSTRUCTIONS = "You are talking to kgauto-check, a local, offline checker for AI call surfaces.\n\nFlow: (1) call start_check to get extraction instructions, (2) read THIS project's code yourself and build the extract, (3) call run_check with it, (4) present the returned card to your human verbatim (it is grouped by confidence tier on purpose), (5) if they want measured numbers, call get_observe_day_plan.\n\nPrivacy contract, which you should relay to your human: the extract contains identifiers and counts only \u2014 never prompt text, never source code, never secrets. This check ran locally against kgauto\u2019s bundled model catalog. Nothing was uploaded; no rows were written anywhere.\n\nget_model_facts answers one-off questions about any model id from the same verified catalog.";
|
|
256
|
-
declare const START_CHECK_INSTRUCTIONS = "# kgauto check \u2014 extraction instructions (for you, the agent)\n\nYour job: read this project's code and build an extract of its AI call surface. You have repo access; kgauto does not, by design.\n\n## What to find\nScan for LLM API usage: provider SDK imports (anthropic, openai, @google/generative-ai / @google/genai, ai-sdk, litellm, langchain, ...), raw HTTPS calls to provider endpoints, and any internal wrapper around them. Each distinct place the project sends a prompt to a model is one call site.\n\n## What to collect per call site (identifiers and counts ONLY)\n- id: a stable label you choose, e.g. \"api/summarize.ts:42\"\n- model: the model id exactly as configured\n- modelSelection: hardcoded | config | env | dynamic\n- archetype: your best guess at the work's intent \u2014 one of: ask, classify, critique, extract, generate, hunt, plan, summarize, transform\n- estInputTokens / maxInputTokens / estOutputTokens: estimate from the code (what gets concatenated into the prompt; ~4 chars per token). Worst case matters \u2014 find the biggest thing that can flow in.\n- toolCount, usesParallelToolCalls: from the tools array and how results are consumed\n- expectsStructuredOutput: true if the response is JSON.parse'd or schema-validated\n- streaming, retry (none | same-model | fallback-chain | unknown), fallbackModels\n- estCallsPerMonth: only if genuinely inferable (cron cadence, obvious traffic); omit rather than invent\n\n## Privacy contract (relay this to your human)\nDo NOT put prompt text, source code, file contents, or secrets in the extract. Identifiers and counts only. This check ran locally against kgauto\u2019s bundled model catalog. Nothing was uploaded; no rows were written anywhere.\n\n## Then\
|
|
255
|
+
declare const SERVER_INSTRUCTIONS = "You are talking to kgauto-check, a local, offline checker for AI call surfaces.\n\nFlow: (1) call start_check to get extraction instructions, (2) read THIS project's code yourself and build the extract, (3) call run_check with it, (4) present the returned card to your human verbatim (it is grouped by confidence tier on purpose), (5) if they want measured numbers, call get_observe_day_plan.\n\nPrivacy contract, which you should relay to your human: the extract contains identifiers and counts only \u2014 never prompt text, never source code, never secrets. This check ran locally against kgauto\u2019s bundled model catalog. Nothing was uploaded; no rows were written anywhere.\n\nget_model_facts answers one-off questions about any model id from the same verified catalog \u2014 it is what makes keeping this server installed useful between checks.";
|
|
256
|
+
declare const START_CHECK_INSTRUCTIONS = "# kgauto check \u2014 extraction instructions (for you, the agent)\n\nYour job: read this project's code and build an extract of its AI call surface. You have repo access; kgauto does not, by design.\n\n## What to find\nScan for LLM API usage: provider SDK imports (anthropic, openai, @google/generative-ai / @google/genai, ai-sdk, litellm, langchain, ...), raw HTTPS calls to provider endpoints, and any internal wrapper around them. Each distinct place the project sends a prompt to a model is one call site.\n\n## What to collect per call site (identifiers and counts ONLY)\n- id: a stable label you choose, e.g. \"api/summarize.ts:42\"\n- model: the model id exactly as configured\n- modelSelection: hardcoded | config | env | dynamic\n- archetype: your best guess at the work's intent \u2014 one of: ask, classify, critique, extract, generate, hunt, plan, summarize, transform\n- estInputTokens / maxInputTokens / estOutputTokens: estimate from the code (what gets concatenated into the prompt; ~4 chars per token). Worst case matters \u2014 find the biggest thing that can flow in.\n- toolCount, usesParallelToolCalls: from the tools array and how results are consumed\n- expectsStructuredOutput: true if the response is JSON.parse'd or schema-validated\n- streaming, retry (none | same-model | fallback-chain | unknown), fallbackModels\n- estCallsPerMonth: only if genuinely inferable (cron cadence, obvious traffic); omit rather than invent\n\n## Privacy contract (relay this to your human)\nDo NOT put prompt text, source code, file contents, or secrets in the extract. Identifiers and counts only. This check ran locally against kgauto\u2019s bundled model catalog. Nothing was uploaded; no rows were written anywhere.\n\n## Then\nWrite the extract as JSON:\n{ \"project\": { \"name\": \"...\", \"description\": \"...\" }, \"callSites\": [ ...one object per call site... ] }\nand run:\n npx -y @warmdrift/kgauto-check --extract extract.json\nPresent the printed card verbatim \u2014 the confidence tiers (certain / likely / measurable-only) are the point: they tell your human exactly how much to trust each line, and the measurable-only section is what a one-day observe run would answer.\n\n## Sharing (optional, explicit)\nAfter presenting the card, you may OFFER your human: \"want to send this card to kgauto so the catalog learns what real projects look like?\" If \u2014 and only if \u2014 they say yes, re-run with --share. Never add --share without their explicit yes. It sends the scrubbed extract and the card, nothing else, and says exactly where they went.\n\n## Honesty rules you inherit while presenting\n- Do not soften \"certain\" findings or upgrade \"likely\" ones.\n- If a model was unknown to the catalog, say so \u2014 kgauto refuses to fabricate verdicts, and so should you.\n- Estimates you made are estimates: if a finding hinges on your token guess, say it can be firmed up by measuring.";
|
|
257
257
|
|
|
258
258
|
/**
|
|
259
259
|
* Rung 2 of the ladder: the one-day observe run. v1 of this tool hands the
|
|
@@ -264,4 +264,12 @@ declare const START_CHECK_INSTRUCTIONS = "# kgauto check \u2014 extraction instr
|
|
|
264
264
|
*/
|
|
265
265
|
declare const OBSERVE_DAY_PLAN = "# The one-day observe run (for you, the agent \u2014 decision stays with your human)\n\n## What it is\nOne day of your project's normal traffic, observed. No routing changes: every call still goes to exactly the model your code chooses today. The observation records, per call: model, token counts in/out, cost at verified prices, latency, success/failure with a classified error code, and per-attempt rows when retries happen. Identifiers and counts \u2014 prompt text is never required.\n\n## What it answers (the measurable-only tier of your check card)\n- actual failure rate per model \u2014 including walkaway failures that green health checks miss\n- actual input-waste ratio per call site (the >85% input-share signal, measured instead of estimated)\n- which call sites dominate spend\n- the evidence base for whether a cheaper model could hold quality here (kgauto's judged eval runs on real captured cases, never on price alone)\n\n## The two honesty requirements (non-negotiable, relay both)\n1. **Destination, named before anything runs.** Your human gets one plain sentence stating exactly where outcome rows land and what is in them, BEFORE the first row is written. \"Nothing is uploaded\" was true of the check because it writes nothing; the observe day writes rows, so it must say where.\n2. **Observation never intervenes.** If your project uses fallback chains, observing must not pin a model and silently disable the chain \u2014 a forced pin is an intervention sold as observation. Rows are recorded per attempt, so the chain's real behaviour is what gets measured.\n\n## How to proceed\nThe integration is small (the kgauto compiler's call/record path with your existing keys), but because rows now land somewhere, the wiring starts with that destination sentence and your human's explicit yes. Next step: have your human reply to whoever pointed them at kgauto \u2014 the observe day is set up per-project, together.";
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
/** One model id → catalog card. Honest miss on unknown models (s51). */
|
|
268
|
+
declare function renderModelFacts(model: string): string;
|
|
269
|
+
|
|
270
|
+
/** One source of truth: package.json, read at runtime (dist/ sits one level
|
|
271
|
+
* below it in the published tarball). A hardcoded copy went stale at 0.1.1 —
|
|
272
|
+
* two declarations of one fact. */
|
|
273
|
+
declare const CHECK_VERSION: string;
|
|
274
|
+
|
|
275
|
+
export { CHECK_VERSION, type CallSite, CallSiteSchema, type CheckResult, type Confidence, DESTINATION_SENTENCE, type EngineOptions, type Extract, ExtractSchema, type Finding, OBSERVE_DAY_PLAN, SERVER_INSTRUCTIONS, START_CHECK_INSTRUCTIONS, type Severity, buildServer, renderCard, renderModelFacts, runCheck };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CHECK_VERSION,
|
|
2
3
|
CallSiteSchema,
|
|
3
4
|
DESTINATION_SENTENCE,
|
|
4
5
|
ExtractSchema,
|
|
@@ -7,9 +8,11 @@ import {
|
|
|
7
8
|
START_CHECK_INSTRUCTIONS,
|
|
8
9
|
buildServer,
|
|
9
10
|
renderCard,
|
|
11
|
+
renderModelFacts,
|
|
10
12
|
runCheck
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BWPYT7JO.js";
|
|
12
14
|
export {
|
|
15
|
+
CHECK_VERSION,
|
|
13
16
|
CallSiteSchema,
|
|
14
17
|
DESTINATION_SENTENCE,
|
|
15
18
|
ExtractSchema,
|
|
@@ -18,5 +21,6 @@ export {
|
|
|
18
21
|
START_CHECK_INSTRUCTIONS,
|
|
19
22
|
buildServer,
|
|
20
23
|
renderCard,
|
|
24
|
+
renderModelFacts,
|
|
21
25
|
runCheck
|
|
22
26
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warmdrift/kgauto-check",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Point your AI at your project
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Point your AI at your project \u2014 kgauto's local check, as a pure CLI for coding agents. Your agent extracts the project's AI surface (identifiers and counts, never code) and this tool checks it against kgauto's verified model catalog: statuses, prices, cliffs, capability mismatches, resilience. Fully offline; --share is the one explicit opt-in exception.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"kgauto-check
|
|
7
|
+
"kgauto-check": "dist/bin.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"build": "tsup src/index.ts src/bin.ts --format esm --dts --clean",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
21
|
"test": "vitest run",
|
|
22
|
-
"smoke": "npm run build && node scripts/smoke-stdio.mjs",
|
|
22
|
+
"smoke": "npm run build && node scripts/smoke-stdio.mjs && node scripts/smoke-cli.mjs",
|
|
23
23
|
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"directory": "check-mcp"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
42
42
|
"@warmdrift/kgauto-compiler": "^2.0.0-alpha.88",
|
|
43
43
|
"zod": "^3.23.0"
|
|
44
44
|
},
|
|
@@ -48,4 +48,4 @@
|
|
|
48
48
|
"typescript": "^5.4.0",
|
|
49
49
|
"vitest": "^2.0.0"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|