@post-print/agent-harness 0.1.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.
Files changed (50) hide show
  1. package/README.md +18 -0
  2. package/dist/adapters/index.d.ts +15 -0
  3. package/dist/adapters/index.d.ts.map +1 -0
  4. package/dist/adapters/index.js +65 -0
  5. package/dist/adapters/index.js.map +1 -0
  6. package/dist/adapters/replay.d.ts +7 -0
  7. package/dist/adapters/replay.d.ts.map +1 -0
  8. package/dist/adapters/replay.js +61 -0
  9. package/dist/adapters/replay.js.map +1 -0
  10. package/dist/capture.d.ts +69 -0
  11. package/dist/capture.d.ts.map +1 -0
  12. package/dist/capture.js +352 -0
  13. package/dist/capture.js.map +1 -0
  14. package/dist/context.d.ts +11 -0
  15. package/dist/context.d.ts.map +1 -0
  16. package/dist/context.js +93 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/cursor-run.d.ts +44 -0
  19. package/dist/cursor-run.d.ts.map +1 -0
  20. package/dist/cursor-run.js +159 -0
  21. package/dist/cursor-run.js.map +1 -0
  22. package/dist/index.d.ts +20 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +18 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/judge.d.ts +35 -0
  27. package/dist/judge.d.ts.map +1 -0
  28. package/dist/judge.js +222 -0
  29. package/dist/judge.js.map +1 -0
  30. package/dist/routing-contract.d.ts +4 -0
  31. package/dist/routing-contract.d.ts.map +1 -0
  32. package/dist/routing-contract.js +22 -0
  33. package/dist/routing-contract.js.map +1 -0
  34. package/dist/skills-context.d.ts +25 -0
  35. package/dist/skills-context.d.ts.map +1 -0
  36. package/dist/skills-context.js +120 -0
  37. package/dist/skills-context.js.map +1 -0
  38. package/dist/types.d.ts +72 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +2 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/working-tree-guard.d.ts +6 -0
  43. package/dist/working-tree-guard.d.ts.map +1 -0
  44. package/dist/working-tree-guard.js +20 -0
  45. package/dist/working-tree-guard.js.map +1 -0
  46. package/dist/worktree.d.ts +10 -0
  47. package/dist/worktree.d.ts.map +1 -0
  48. package/dist/worktree.js +58 -0
  49. package/dist/worktree.js.map +1 -0
  50. package/package.json +49 -0
@@ -0,0 +1,93 @@
1
+ import { access, readdir, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { loadSkillContext } from "./skills-context";
4
+ const SHARED_SOURCES = ["AGENTS.md", ".claude/skills/README.md"];
5
+ const CLAUDE_SOURCES = ["CLAUDE.md", "AGENTS.md"];
6
+ const CURSOR_RULES_DIR = ".cursor/rules";
7
+ async function fileExists(path) {
8
+ try {
9
+ await access(path);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ async function readIfExists(cwd, rel) {
17
+ const path = join(cwd, rel);
18
+ if (!(await fileExists(path))) {
19
+ return null;
20
+ }
21
+ return readFile(path, "utf8");
22
+ }
23
+ async function loadCursorRules(cwd) {
24
+ const rulesDir = join(cwd, CURSOR_RULES_DIR);
25
+ if (!(await fileExists(rulesDir))) {
26
+ return [];
27
+ }
28
+ const entries = (await readdir(rulesDir)).filter((name) => name.endsWith(".mdc")).sort();
29
+ const loaded = [];
30
+ for (const name of entries) {
31
+ const rel = `${CURSOR_RULES_DIR}/${name}`;
32
+ const text = await readIfExists(cwd, rel);
33
+ if (text !== null) {
34
+ loaded.push({ rel, text });
35
+ }
36
+ }
37
+ return loaded;
38
+ }
39
+ function sourcesForProfile(profile) {
40
+ switch (profile) {
41
+ case "claude":
42
+ return [...SHARED_SOURCES, ...CLAUDE_SOURCES];
43
+ default:
44
+ return SHARED_SOURCES;
45
+ }
46
+ }
47
+ /** Load canonical agent context files from the repo. */
48
+ export async function loadContext(options) {
49
+ const profile = options.profile ?? "shared";
50
+ const seen = new Set();
51
+ const parts = [];
52
+ const loaded = [];
53
+ for (const rel of sourcesForProfile(profile)) {
54
+ if (seen.has(rel)) {
55
+ continue;
56
+ }
57
+ seen.add(rel);
58
+ const text = await readIfExists(options.cwd, rel);
59
+ if (text === null) {
60
+ continue;
61
+ }
62
+ loaded.push(rel);
63
+ parts.push(`<!-- ${rel} -->\n${text}`);
64
+ }
65
+ if (profile === "cursor") {
66
+ for (const rule of await loadCursorRules(options.cwd)) {
67
+ if (seen.has(rule.rel)) {
68
+ continue;
69
+ }
70
+ seen.add(rule.rel);
71
+ loaded.push(rule.rel);
72
+ parts.push(`<!-- ${rule.rel} -->\n${rule.text}`);
73
+ }
74
+ }
75
+ const skillContext = await loadSkillContext(options.cwd, options.skills);
76
+ if (skillContext.preamble) {
77
+ for (const rel of skillContext.sources) {
78
+ if (!seen.has(rel)) {
79
+ seen.add(rel);
80
+ loaded.push(rel);
81
+ }
82
+ }
83
+ parts.push(skillContext.preamble);
84
+ }
85
+ return {
86
+ profile,
87
+ cwd: options.cwd,
88
+ sources: loaded,
89
+ preamble: parts.join("\n\n---\n\n"),
90
+ skillsMode: skillContext.mode,
91
+ };
92
+ }
93
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type SdkMessage } from "./capture";
2
+ import type { AgentTrace } from "./types";
3
+ export interface CursorRunOptions {
4
+ cwd: string;
5
+ prompt: string;
6
+ apiKey?: string;
7
+ model?: {
8
+ id: string;
9
+ params?: Array<{
10
+ id: string;
11
+ value: string;
12
+ }>;
13
+ };
14
+ }
15
+ export interface JudgeClassifierOptions {
16
+ cwd: string;
17
+ prompt: string;
18
+ apiKey?: string;
19
+ model?: {
20
+ id: string;
21
+ params?: Array<{
22
+ id: string;
23
+ value: string;
24
+ }>;
25
+ };
26
+ }
27
+ export interface JudgeClassifierResult {
28
+ status: string;
29
+ text: string;
30
+ }
31
+ export interface CursorRunResult {
32
+ status: string;
33
+ trace: AgentTrace;
34
+ }
35
+ /** Map Cursor SDK terminal status to harness run status. */
36
+ export declare function normalizeSdkRunStatus(status: string): "completed" | "failed";
37
+ /** Shared Cursor SDK path — Agent.create + send + wait (runs and judge use the same surface). */
38
+ export declare function runCursorAgent(options: CursorRunOptions): Promise<CursorRunResult>;
39
+ /** Classifier-only judge path — one-shot Agent.prompt, JSON reply, temperature 0 when supported. */
40
+ export declare function runJudgeClassifier(options: JudgeClassifierOptions): Promise<JudgeClassifierResult>;
41
+ /** Assistant prose from a Cursor SDK message stream (last assistant block wins for short replies). */
42
+ export declare function assistantTextFromSdkMessages(messages: SdkMessage[]): string;
43
+ export declare function textBlocksFromSdkMessage(event: SdkMessage): string;
44
+ //# sourceMappingURL=cursor-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-run.d.ts","sourceRoot":"","sources":["../src/cursor-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,UAAU,EACf,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA0B1C,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACtE;AAED,MAAM,WAAW,sBAAsB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACtE;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;CAClB;AAED,4DAA4D;AAC5D,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAE5E;AAED,iGAAiG;AACjG,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwBxF;AAED,oGAAoG;AACpG,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,qBAAqB,CAAC,CAoBhC;AAED,sGAAsG;AACtG,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAS3E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAqBlE"}
@@ -0,0 +1,159 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import { accumulateSdkEvent, createTraceAccumulator, finalizeTraceAccumulator, } from "./capture";
54
+ /** Default local agent model; override with CURSOR_AGENT_MODEL or options.model. */
55
+ const DEFAULT_CURSOR_MODEL = "auto";
56
+ function judgeModelSelection(override) {
57
+ const id = override?.id ??
58
+ process.env.CURSOR_JUDGE_MODEL ??
59
+ process.env.CURSOR_AGENT_MODEL ??
60
+ DEFAULT_CURSOR_MODEL;
61
+ const params = override?.params ?? judgeModelParamsFromEnv();
62
+ return params ? { id, params } : { id };
63
+ }
64
+ function judgeModelParamsFromEnv() {
65
+ const raw = process.env.CURSOR_JUDGE_TEMPERATURE ?? "0";
66
+ if (!raw.trim()) {
67
+ return undefined;
68
+ }
69
+ return [{ id: "temperature", value: raw.trim() }];
70
+ }
71
+ /** Map Cursor SDK terminal status to harness run status. */
72
+ export function normalizeSdkRunStatus(status) {
73
+ return status === "finished" || status === "completed" ? "completed" : "failed";
74
+ }
75
+ /** Shared Cursor SDK path — Agent.create + send + wait (runs and judge use the same surface). */
76
+ export async function runCursorAgent(options) {
77
+ const env_1 = { stack: [], error: void 0, hasError: false };
78
+ try {
79
+ const apiKey = options.apiKey ?? process.env.CURSOR_API_KEY;
80
+ if (!apiKey) {
81
+ throw new Error("CURSOR_API_KEY not set");
82
+ }
83
+ const sdkModule = await import("@cursor/sdk");
84
+ const modelId = options.model?.id ?? process.env.CURSOR_AGENT_MODEL ?? DEFAULT_CURSOR_MODEL;
85
+ const agent = __addDisposableResource(env_1, await sdkModule.Agent.create({
86
+ apiKey,
87
+ model: { id: modelId },
88
+ local: { cwd: options.cwd },
89
+ }), true);
90
+ const run = await agent.send(options.prompt);
91
+ const acc = createTraceAccumulator();
92
+ for await (const event of run.stream()) {
93
+ accumulateSdkEvent(acc, event);
94
+ }
95
+ const result = await run.wait();
96
+ return {
97
+ status: normalizeSdkRunStatus(result.status),
98
+ trace: finalizeTraceAccumulator(acc),
99
+ };
100
+ }
101
+ catch (e_1) {
102
+ env_1.error = e_1;
103
+ env_1.hasError = true;
104
+ }
105
+ finally {
106
+ const result_1 = __disposeResources(env_1);
107
+ if (result_1)
108
+ await result_1;
109
+ }
110
+ }
111
+ /** Classifier-only judge path — one-shot Agent.prompt, JSON reply, temperature 0 when supported. */
112
+ export async function runJudgeClassifier(options) {
113
+ const apiKey = options.apiKey ?? process.env.CURSOR_API_KEY;
114
+ if (!apiKey) {
115
+ throw new Error("CURSOR_API_KEY not set");
116
+ }
117
+ const sdkModule = await import("@cursor/sdk");
118
+ const result = await sdkModule.Agent.prompt(options.prompt, {
119
+ apiKey,
120
+ model: judgeModelSelection(options.model),
121
+ name: "agent-spec-judge",
122
+ local: { cwd: options.cwd },
123
+ });
124
+ const text = result.result?.trim() ?? "";
125
+ const status = result.status === "finished" ? "completed" : result.status;
126
+ return {
127
+ status: normalizeSdkRunStatus(status),
128
+ text,
129
+ };
130
+ }
131
+ /** Assistant prose from a Cursor SDK message stream (last assistant block wins for short replies). */
132
+ export function assistantTextFromSdkMessages(messages) {
133
+ const chunks = [];
134
+ for (const event of messages) {
135
+ const text = textBlocksFromSdkMessage(event);
136
+ if (text.length > 0 && (event.type === "assistant" || event.message?.role === "assistant")) {
137
+ chunks.push(text);
138
+ }
139
+ }
140
+ return chunks.join("\n").trim();
141
+ }
142
+ export function textBlocksFromSdkMessage(event) {
143
+ const parts = [];
144
+ if (event.message?.content) {
145
+ for (const block of event.message.content) {
146
+ if (block.text) {
147
+ parts.push(block.text);
148
+ }
149
+ }
150
+ }
151
+ if (event.tool?.input !== undefined) {
152
+ parts.push(typeof event.tool.input === "string" ? event.tool.input : JSON.stringify(event.tool.input));
153
+ }
154
+ if (event.tool?.output) {
155
+ parts.push(event.tool.output);
156
+ }
157
+ return parts.join("\n");
158
+ }
159
+ //# sourceMappingURL=cursor-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-run.js","sourceRoot":"","sources":["../src/cursor-run.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GAExB,MAAM,WAAW,CAAC;AAGnB,oFAAoF;AACpF,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAEpC,SAAS,mBAAmB,CAAC,QAA0C;IAItE,MAAM,EAAE,GACP,QAAQ,EAAE,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,oBAAoB,CAAC;IACtB,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,uBAAuB,EAAE,CAAC;IAC7D,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;AACzC,CAAC;AAED,SAAS,uBAAuB;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,GAAG,CAAC;IACxD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC;AA0BD,4DAA4D;AAC5D,MAAM,UAAU,qBAAqB,CAAC,MAAc;IACnD,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;AACjF,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAyB;;;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,oBAAoB,CAAC;QAC5F,MAAY,KAAK,kCAAG,MAAM,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;YAChD,MAAM;YACN,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;YACtB,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;SAC3B,CAAC,OAAA,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,sBAAsB,EAAE,CAAC;QACrC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO;YACN,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5C,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC;SACpC,CAAC;;;;;;;;;;;CACF;AAED,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,OAA+B;IAE/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE;QAC3D,MAAM;QACN,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC;QACzC,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;KAC3B,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1E,OAAO;QACN,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC;QACrC,IAAI;KACJ,CAAC;AACH,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,4BAA4B,CAAC,QAAsB;IAClE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;YAC5F,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAiB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CACT,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAC1F,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type LoadContextOptions, loadContext } from "./context";
2
+ import type { AgentSession, ContextProfile, RunAgentOptions } from "./types";
3
+ export type { SdkMessage } from "./capture";
4
+ export type { AgentHost, AgentMessage, AgentSession, AgentToolCall, AgentTrace, ContextProfile, HostAdapter, LoadedContext, RoutingContract, RunAgentOptions, RunStatus, SkillContextMode, SkillContextOptions, SkillContextSetting, } from "./types";
5
+ export { loadContext, type LoadContextOptions };
6
+ export { ClaudeAdapter, CursorAdapter, createAdapter, ReplayAdapter, } from "./adapters";
7
+ export { assistantPrefixBeforeTools, buildTraceFromSdkMessages, captureGitDiff, collapseTraceWhitespace, enrichTrace, extractShellCommands, extractShellCommandsFromToolCalls, extractSkillsAppliedFromText, extractSkillsInvokedFromText, extractSkillsInvokedFromToolCalls, handsOnTierBeforeTools, inferReviewDepthFromText, inferRoutingFromText, mergeSkillsInvoked, routingBlockBeforeTools, } from "./capture";
8
+ export { assistantTextFromSdkMessages, type CursorRunOptions, type CursorRunResult, type JudgeClassifierOptions, type JudgeClassifierResult, runCursorAgent, runJudgeClassifier, textBlocksFromSdkMessage, } from "./cursor-run";
9
+ export { type JudgeCriterion, type JudgeTraceOptions, type JudgeTraceResult, type JudgeVerdict, judgeTrace, type ParsedJudgeJson, parseJudgeJsonResponse, parseJudgeLegacyResponse, parseJudgeResponse, } from "./judge";
10
+ export { buildRoutingContract } from "./routing-contract";
11
+ export { loadSkillContext, normalizeSkillContext, type SkillCatalogEntry } from "./skills-context";
12
+ export { captureWorkingTreeStatus, findWorkingTreeLeak, formatWorkingTreeLeak, } from "./working-tree-guard";
13
+ export { cleanupStaleScenarioWorktrees, createScenarioWorktree, SCENARIO_WORKTREE_DIR_PREFIX, type ScenarioWorktree, } from "./worktree";
14
+ export interface RunAgentInput extends Omit<RunAgentOptions, "context"> {
15
+ context?: RunAgentOptions["context"];
16
+ profile?: ContextProfile;
17
+ }
18
+ /** Run an agent session via the selected host adapter. */
19
+ export declare function runAgent(input: RunAgentInput): Promise<AgentSession>;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE7E,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EACX,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,eAAe,EACf,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,CAAC;AAChD,OAAO,EACN,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,0BAA0B,EAC1B,yBAAyB,EACzB,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,4BAA4B,EAC5B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,cAAc,EACd,kBAAkB,EAClB,wBAAwB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,UAAU,EACV,KAAK,eAAe,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EACN,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC5B,KAAK,gBAAgB,GACrB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC;IACtE,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,0DAA0D;AAC1D,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAK1E"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ import { createAdapter } from "./adapters";
2
+ import { loadContext } from "./context";
3
+ export { loadContext };
4
+ export { ClaudeAdapter, CursorAdapter, createAdapter, ReplayAdapter, } from "./adapters";
5
+ export { assistantPrefixBeforeTools, buildTraceFromSdkMessages, captureGitDiff, collapseTraceWhitespace, enrichTrace, extractShellCommands, extractShellCommandsFromToolCalls, extractSkillsAppliedFromText, extractSkillsInvokedFromText, extractSkillsInvokedFromToolCalls, handsOnTierBeforeTools, inferReviewDepthFromText, inferRoutingFromText, mergeSkillsInvoked, routingBlockBeforeTools, } from "./capture";
6
+ export { assistantTextFromSdkMessages, runCursorAgent, runJudgeClassifier, textBlocksFromSdkMessage, } from "./cursor-run";
7
+ export { judgeTrace, parseJudgeJsonResponse, parseJudgeLegacyResponse, parseJudgeResponse, } from "./judge";
8
+ export { buildRoutingContract } from "./routing-contract";
9
+ export { loadSkillContext, normalizeSkillContext } from "./skills-context";
10
+ export { captureWorkingTreeStatus, findWorkingTreeLeak, formatWorkingTreeLeak, } from "./working-tree-guard";
11
+ export { cleanupStaleScenarioWorktrees, createScenarioWorktree, SCENARIO_WORKTREE_DIR_PREFIX, } from "./worktree";
12
+ /** Run an agent session via the selected host adapter. */
13
+ export async function runAgent(input) {
14
+ const context = input.context ?? (await loadContext({ cwd: input.cwd, profile: input.profile ?? "shared" }));
15
+ const adapter = createAdapter(input.host);
16
+ return adapter.run({ ...input, context });
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAA2B,WAAW,EAAE,MAAM,WAAW,CAAC;AAqBjE,OAAO,EAAE,WAAW,EAA2B,CAAC;AAChD,OAAO,EACN,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,0BAA0B,EAC1B,yBAAyB,EACzB,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,4BAA4B,EAK5B,cAAc,EACd,kBAAkB,EAClB,wBAAwB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAKN,UAAU,EAEV,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAA0B,MAAM,kBAAkB,CAAC;AACnG,OAAO,EACN,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,GAE5B,MAAM,YAAY,CAAC;AAOpB,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAoB;IAClD,MAAM,OAAO,GACZ,KAAK,CAAC,OAAO,IAAI,CAAC,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AgentTrace } from "./types";
2
+ export interface JudgeCriterion {
3
+ id: string;
4
+ question: string;
5
+ }
6
+ export interface JudgeVerdict {
7
+ id: string;
8
+ pass: boolean;
9
+ rationale: string;
10
+ evidence?: string[];
11
+ }
12
+ export interface JudgeTraceOptions {
13
+ cwd: string;
14
+ apiKey?: string;
15
+ }
16
+ export interface JudgeTraceResult {
17
+ verdicts: JudgeVerdict[];
18
+ skipped: boolean;
19
+ error?: string;
20
+ }
21
+ export interface ParsedJudgeJson {
22
+ pass: boolean;
23
+ rationale: string;
24
+ evidence: string[];
25
+ valid: boolean;
26
+ }
27
+ /** Parse structured judge JSON (`verdict`, `evidence`, `rationale`). */
28
+ export declare function parseJudgeJsonResponse(text: string): ParsedJudgeJson;
29
+ /** Fallback when model ignores JSON contract — parse YES/NO prose. */
30
+ export declare function parseJudgeLegacyResponse(text: string): ParsedJudgeJson;
31
+ /** Parse structured JSON first, then legacy YES/NO prose. */
32
+ export declare function parseJudgeResponse(text: string): ParsedJudgeJson;
33
+ /** Score fuzzy rubric criteria with a structured JSON judge (live runs only). */
34
+ export declare function judgeTrace(trace: AgentTrace, criteria: JudgeCriterion[], options: JudgeTraceOptions): Promise<JudgeTraceResult>;
35
+ //# sourceMappingURL=judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAK1C,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CACf;AAuBD,wEAAwE;AACxE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAuCpE;AA+BD,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CA4CtE;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAMhE;AA6DD,iFAAiF;AACjF,wBAAsB,UAAU,CAC/B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,EAAE,iBAAiB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAgC3B"}
package/dist/judge.js ADDED
@@ -0,0 +1,222 @@
1
+ import { runJudgeClassifier } from "./cursor-run";
2
+ const JSON_FENCE_PATTERN = /```(?:json)?\s*([\s\S]*?)```/i;
3
+ const JSON_OBJECT_PATTERN = /\{[\s\S]*\}/;
4
+ function transcriptForJudge(trace) {
5
+ return [
6
+ ...trace.messages.map((m) => m.content),
7
+ trace.prBody ?? "",
8
+ trace.gitDiff ? `Git diff:\n${trace.gitDiff}` : "",
9
+ trace.shellCommands.length > 0 ? `Shell commands:\n${trace.shellCommands.join("\n")}` : "",
10
+ ]
11
+ .filter(Boolean)
12
+ .join("\n\n---\n\n");
13
+ }
14
+ function normalizeVerdict(value) {
15
+ const verdict = String(value ?? "")
16
+ .trim()
17
+ .toLowerCase();
18
+ if (verdict === "yes" || verdict === "no") {
19
+ return verdict;
20
+ }
21
+ return undefined;
22
+ }
23
+ /** Parse structured judge JSON (`verdict`, `evidence`, `rationale`). */
24
+ export function parseJudgeJsonResponse(text) {
25
+ const trimmed = text.trim();
26
+ const candidates = [trimmed];
27
+ const fenced = trimmed.match(JSON_FENCE_PATTERN);
28
+ if (fenced?.[1]) {
29
+ candidates.unshift(fenced[1].trim());
30
+ }
31
+ const objectMatch = trimmed.match(JSON_OBJECT_PATTERN);
32
+ if (objectMatch?.[0]) {
33
+ candidates.push(objectMatch[0]);
34
+ }
35
+ for (const candidate of candidates) {
36
+ try {
37
+ const parsed = JSON.parse(candidate);
38
+ const verdict = normalizeVerdict(parsed.verdict);
39
+ if (verdict !== undefined) {
40
+ return {
41
+ pass: verdict === "yes",
42
+ rationale: String(parsed.rationale ?? "").trim() || "no rationale",
43
+ evidence: Array.isArray(parsed.evidence)
44
+ ? parsed.evidence.map((item) => String(item)).filter(Boolean)
45
+ : [],
46
+ valid: true,
47
+ };
48
+ }
49
+ }
50
+ catch {
51
+ // try next candidate
52
+ }
53
+ }
54
+ return {
55
+ pass: false,
56
+ rationale: "judge returned invalid JSON (expected { verdict, evidence, rationale })",
57
+ evidence: [],
58
+ valid: false,
59
+ };
60
+ }
61
+ const JUDGE_MARKDOWN_TRIM_PATTERN = /^\*+\s*|\s*\*+$/g;
62
+ const JUDGE_VERDICT_PREFIX_PATTERN = /^(?:answer|verdict|line\s*1)\s*:\s*/i;
63
+ const JUDGE_TRAILING_PUNCT_PATTERN = /[.:!]+$/g;
64
+ const JUDGE_TAIL_VERDICT_PATTERN = /\b(YES|NO)\.?\s*$/i;
65
+ const JUDGE_INLINE_VERDICT_PATTERN = /\b(YES|NO)\b/i;
66
+ function extractLegacyVerdict(line) {
67
+ const stripped = line
68
+ .replace(JUDGE_MARKDOWN_TRIM_PATTERN, "")
69
+ .replace(JUDGE_VERDICT_PREFIX_PATTERN, "")
70
+ .trim();
71
+ const head = stripped.replace(JUDGE_TRAILING_PUNCT_PATTERN, "").toUpperCase();
72
+ if (head === "YES" || head.startsWith("YES ")) {
73
+ return "yes";
74
+ }
75
+ if (head === "NO" || head.startsWith("NO ")) {
76
+ return "no";
77
+ }
78
+ const tailMatch = stripped.match(JUDGE_TAIL_VERDICT_PATTERN);
79
+ if (tailMatch?.[1]) {
80
+ return tailMatch[1].toLowerCase();
81
+ }
82
+ const inlineMatch = stripped.match(JUDGE_INLINE_VERDICT_PATTERN);
83
+ if (inlineMatch?.[1]) {
84
+ return inlineMatch[1].toLowerCase();
85
+ }
86
+ return undefined;
87
+ }
88
+ /** Fallback when model ignores JSON contract — parse YES/NO prose. */
89
+ export function parseJudgeLegacyResponse(text) {
90
+ const lines = text
91
+ .trim()
92
+ .split("\n")
93
+ .map((line) => line.trim())
94
+ .filter(Boolean);
95
+ for (let index = 0; index < Math.min(lines.length, 3); index++) {
96
+ const line = lines[index];
97
+ if (!line) {
98
+ continue;
99
+ }
100
+ const verdict = extractLegacyVerdict(line);
101
+ if (verdict !== undefined) {
102
+ const rationale = lines
103
+ .filter((_, i) => i !== index)
104
+ .join(" ")
105
+ .trim() || line.replace(JUDGE_TAIL_VERDICT_PATTERN, "").trim();
106
+ return {
107
+ pass: verdict === "yes",
108
+ rationale: rationale || line,
109
+ evidence: [],
110
+ valid: true,
111
+ };
112
+ }
113
+ }
114
+ const fallback = extractLegacyVerdict(lines[0] ?? text.trim());
115
+ if (fallback !== undefined) {
116
+ return {
117
+ pass: fallback === "yes",
118
+ rationale: lines.slice(1).join(" ").trim() || lines[0] || text,
119
+ evidence: [],
120
+ valid: true,
121
+ };
122
+ }
123
+ return {
124
+ pass: false,
125
+ rationale: "judge returned invalid JSON (expected { verdict, evidence, rationale })",
126
+ evidence: [],
127
+ valid: false,
128
+ };
129
+ }
130
+ /** Parse structured JSON first, then legacy YES/NO prose. */
131
+ export function parseJudgeResponse(text) {
132
+ const json = parseJudgeJsonResponse(text);
133
+ if (json.valid) {
134
+ return json;
135
+ }
136
+ return parseJudgeLegacyResponse(text);
137
+ }
138
+ function buildJudgePrompt(transcript, question) {
139
+ return [
140
+ "You are a test harness classifier. Do not use tools. Do not edit files.",
141
+ "Decide whether the transcript satisfies the criterion using only transcript evidence.",
142
+ "Reply with one JSON object only — no markdown fences, no text before or after:",
143
+ '{"verdict":"yes"|"no","evidence":["verbatim quote from transcript"],"rationale":"one sentence"}',
144
+ 'Use verdict "yes" only when evidence clearly supports the criterion.',
145
+ "",
146
+ "Transcript:",
147
+ transcript,
148
+ "",
149
+ `Criterion: ${question}`,
150
+ ].join("\n");
151
+ }
152
+ async function runJudgePrompt(prompt, options) {
153
+ const apiKey = options.apiKey ?? process.env.CURSOR_API_KEY;
154
+ if (!apiKey) {
155
+ return {
156
+ pass: false,
157
+ rationale: "CURSOR_API_KEY not set",
158
+ evidence: [],
159
+ error: "missing api key",
160
+ };
161
+ }
162
+ try {
163
+ const result = await runJudgeClassifier({
164
+ cwd: options.cwd,
165
+ prompt,
166
+ apiKey,
167
+ });
168
+ if (result.status !== "completed") {
169
+ return {
170
+ pass: false,
171
+ rationale: `judge run status: ${result.status}`,
172
+ evidence: [],
173
+ error: `judge run status: ${result.status}`,
174
+ };
175
+ }
176
+ const parsed = parseJudgeResponse(result.text);
177
+ if (!parsed.valid) {
178
+ return {
179
+ pass: false,
180
+ rationale: `${parsed.rationale} (raw: ${result.text.slice(0, 160) || "empty"})`,
181
+ evidence: [],
182
+ error: parsed.rationale,
183
+ };
184
+ }
185
+ return { pass: parsed.pass, rationale: parsed.rationale, evidence: parsed.evidence };
186
+ }
187
+ catch (error) {
188
+ const message = error instanceof Error ? error.message : "judge prompt failed";
189
+ return { pass: false, rationale: message, evidence: [], error: message };
190
+ }
191
+ }
192
+ /** Score fuzzy rubric criteria with a structured JSON judge (live runs only). */
193
+ export async function judgeTrace(trace, criteria, options) {
194
+ if (criteria.length === 0) {
195
+ return { verdicts: [], skipped: true };
196
+ }
197
+ const apiKey = options.apiKey ?? process.env.CURSOR_API_KEY;
198
+ if (!apiKey) {
199
+ return {
200
+ verdicts: [],
201
+ skipped: true,
202
+ error: "CURSOR_API_KEY not set — judge criteria skipped",
203
+ };
204
+ }
205
+ const transcript = transcriptForJudge(trace);
206
+ const verdicts = [];
207
+ for (const criterion of criteria) {
208
+ const prompt = buildJudgePrompt(transcript, criterion.question);
209
+ const parsed = await runJudgePrompt(prompt, { ...options, apiKey });
210
+ verdicts.push({
211
+ id: criterion.id,
212
+ pass: parsed.pass,
213
+ rationale: parsed.rationale,
214
+ evidence: parsed.evidence,
215
+ });
216
+ if (parsed.error) {
217
+ return { verdicts, skipped: false, error: parsed.error };
218
+ }
219
+ }
220
+ return { verdicts, skipped: false };
221
+ }
222
+ //# sourceMappingURL=judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type RoutingContract = "hands-on" | "hands-off";
2
+ /** Live dogfood output contract derived from agent-routing.md (not scenario answer keys). */
3
+ export declare function buildRoutingContract(mode: RoutingContract): string;
4
+ //# sourceMappingURL=routing-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-contract.d.ts","sourceRoot":"","sources":["../src/routing-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvD,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAoBlE"}