katt 0.0.9 → 0.0.11

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/dist/index.js CHANGED
@@ -1,393 +1,488 @@
1
- import { r as N, c as I, a as j, p as z, b as C, l as h, d as T, g as D, e as B, f as $, h as H, s as A, i as W, j as L, k as G, m as X, n as Y, o as q, q as K, t as J } from "./runCli-j5xhVCdB.js";
2
- import { u as jt } from "./runCli-j5xhVCdB.js";
3
- import { CopilotClient as Q } from "@github/copilot-sdk";
4
- import { mkdtemp as V, rm as Z, readFile as R } from "node:fs/promises";
5
- import { join as S, dirname as v, isAbsolute as tt, resolve as et, basename as nt } from "node:path";
6
- import { spawn as ot } from "node:child_process";
7
- import { tmpdir as rt } from "node:os";
8
- import { readFileSync as st, writeFileSync as M, mkdirSync as it } from "node:fs";
9
- function Pt(t, e) {
10
- N(() => {
11
- j(), z(t);
12
- const n = D(), o = Date.now(), i = () => D() === n, s = () => Date.now() - o;
13
- try {
14
- const r = e();
15
- if (r && typeof r.then == "function") {
16
- C(
17
- r.then(() => {
18
- h(!0, s());
19
- }).catch((a) => {
20
- throw h(!1, s()), a;
21
- }).finally(() => {
22
- T();
23
- })
24
- );
25
- return;
26
- }
27
- } catch (r) {
28
- throw h(!1, s()), T(), r;
29
- }
30
- h(i(), s()), T();
31
- }, I());
32
- }
33
- function Nt(t, e) {
34
- N(() => {
35
- B(t);
36
- try {
37
- const n = e();
38
- if (n && typeof n.then == "function") {
39
- C(
40
- n.finally(() => {
41
- $();
42
- })
43
- );
44
- return;
45
- }
46
- } catch (n) {
47
- throw $(), n;
48
- }
49
- $();
50
- }, I());
51
- }
52
- const at = "katt-codex-", ct = "last-message.txt";
53
- function ut(t, e) {
54
- return typeof t == "object" && t !== null && "code" in t && t.code === e;
55
- }
56
- function m(t) {
57
- return typeof t == "string" && t.length > 0;
58
- }
59
- function dt(t) {
60
- return m(t) ? [t] : Array.isArray(t) ? t.filter(m) : [];
61
- }
62
- function lt(t, e) {
63
- const n = e ?? {}, o = [
64
- "exec",
65
- "--color",
66
- "never",
67
- "--output-last-message",
68
- t
69
- ];
70
- m(n.model) && o.push("--model", n.model), m(n.profile) && o.push("--profile", n.profile), m(n.sandbox) && o.push("--sandbox", n.sandbox), n.fullAuto === !0 && o.push("--full-auto"), n.skipGitRepoCheck === !0 && o.push("--skip-git-repo-check"), n.dangerouslyBypassApprovalsAndSandbox === !0 && o.push("--dangerously-bypass-approvals-and-sandbox");
71
- for (const i of dt(n.config))
72
- o.push("--config", i);
73
- return o.push("-"), o;
74
- }
75
- function ft(t, e, n, o) {
76
- return new Promise((i, s) => {
77
- const r = ot("codex", e, {
78
- cwd: o,
79
- stdio: ["pipe", "pipe", "pipe"]
80
- });
81
- let a = "", c = "", p = !1;
82
- r.stdout.setEncoding("utf8"), r.stderr.setEncoding("utf8"), r.stdout.on("data", (u) => {
83
- a += u;
84
- }), r.stderr.on("data", (u) => {
85
- c += u;
86
- }), r.stdin.on("error", () => {
87
- });
88
- const g = setTimeout(() => {
89
- p = !0, r.kill("SIGTERM");
90
- }, n);
91
- r.once("error", (u) => {
92
- clearTimeout(g), s(
93
- new Error(
94
- `Failed to start Codex CLI. Ensure codex is installed and available on PATH. ${String(
95
- u
96
- )}`
97
- )
98
- );
99
- }), r.once("close", (u, x) => {
100
- clearTimeout(g), i({
101
- exitCode: u,
102
- signal: x,
103
- stdout: a.trim(),
104
- stderr: c.trim(),
105
- timedOut: p
106
- });
107
- }), r.stdin.end(t);
108
- });
109
- }
110
- async function pt(t, e) {
111
- try {
112
- return await R(t, "utf8");
113
- } catch (n) {
114
- if (!ut(n, "ENOENT"))
115
- throw n;
116
- return e;
117
- }
118
- }
119
- function ht(t) {
120
- if (t.timedOut)
121
- return "Codex timed out before returning a response.";
122
- if (t.exitCode === null)
123
- return `Codex exited due to signal ${t.signal ?? "unknown"}.`;
124
- const e = t.stderr.length > 0 ? ` ${t.stderr}` : "";
125
- return `Codex exited with code ${t.exitCode}.${e}`;
126
- }
127
- async function mt(t, e, n) {
128
- const o = n ?? {}, i = m(o.workingDirectory) ? o.workingDirectory : process.cwd(), s = await V(S(rt(), at)), r = S(s, ct);
129
- try {
130
- const a = lt(r, n), c = await ft(
131
- t,
132
- a,
133
- e,
134
- i
135
- );
136
- if (c.timedOut)
137
- throw new Error(`Codex timed out after ${e}ms.`);
138
- if (c.exitCode !== 0)
139
- throw new Error(ht(c));
140
- const p = await pt(r, c.stdout);
141
- if (p.length === 0)
142
- throw new Error("Codex did not return a response.");
143
- return p;
144
- } finally {
145
- await Z(s, { recursive: !0, force: !0 });
146
- }
147
- }
148
- const gt = 6e5;
149
- function U(t) {
150
- return typeof t == "string" && t.length > 0 ? t : void 0;
151
- }
152
- function E(t) {
153
- if (!t)
154
- return;
155
- const e = { ...t };
156
- if (e.model !== void 0) {
157
- const n = U(
158
- typeof e.model == "string" ? e.model : void 0
159
- );
160
- n ? e.model = n : delete e.model;
161
- }
162
- return Object.keys(e).length > 0 ? e : void 0;
163
- }
164
- function O(t) {
165
- if (!(typeof t != "number" || !Number.isFinite(t)) && !(t <= 0))
166
- return Math.floor(t);
167
- }
168
- function y(t) {
169
- return !Number.isFinite(t) || (t ?? 0) <= 0 ? 0 : Math.floor(t ?? 0);
170
- }
171
- function xt(t) {
172
- return y(t.inputTokens) + y(t.outputTokens) + y(t.cacheReadTokens) + y(t.cacheWriteTokens);
173
- }
174
- async function F(t, e = {}) {
175
- const { timeoutMs: n, ...o } = e, i = await H(), s = E(i.agentOptions), r = E(
176
- o
177
- ), a = E({
178
- ...s ?? {},
179
- ...r ?? {}
180
- }), c = O(i.promptTimeoutMs), g = O(n) ?? c ?? gt, u = U(
181
- typeof a?.model == "string" ? a.model : void 0
182
- );
183
- if (i.agent === "codex") {
184
- const d = await mt(t, g, a);
185
- return u && A(u), d;
186
- }
187
- const x = new Q({ useLoggedInUser: !0 });
188
- let w, k, b = 0;
189
- try {
190
- await x.start(), w = await x.createSession(a), k = w.on("assistant.usage", (f) => {
191
- b += xt(f.data);
192
- });
193
- const d = await w.sendAndWait({ prompt: t }, g);
194
- if (!d?.data?.content)
195
- throw new Error("Copilot did not return a response.");
196
- return u && A(u), d.data.content;
197
- } finally {
198
- const d = [];
199
- if (k?.(), b > 0 && W(b), w)
200
- try {
201
- await w.destroy();
202
- } catch (f) {
203
- d.push(f);
204
- }
205
- try {
206
- const f = await x.stop();
207
- d.push(...f);
208
- } catch (f) {
209
- d.push(f);
210
- }
211
- d.length > 0 && console.error(
212
- `Copilot cleanup encountered ${d.length} error(s).`
213
- );
214
- }
215
- }
216
- async function It(t, e = {}) {
217
- const n = L.getStore(), o = n?.evalFile ? v(n.evalFile) : process.cwd(), i = tt(t) ? t : et(o, t), s = await R(i, "utf8");
218
- return F(s, e);
219
- }
220
- function l(t) {
221
- G({
222
- describePath: Y(),
223
- itPath: X(),
224
- message: t
225
- });
226
- }
227
- async function wt(t, e) {
228
- const n = Date.now(), o = `expected '${t}' to satisfy '${e}'`, i = F(`Evaluate if the expectation is fulfiled in by the input.
229
- Expectation: "${e}".
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g, v as _, y as v } from "./runCli-CJ7_lGMV.js";
2
+ import { access as y, constants as b, mkdir as x, mkdtemp as S, readFile as C, rm as w, writeFile as ee } from "node:fs/promises";
3
+ import { basename as T, dirname as E, isAbsolute as te, join as D, resolve as O } from "node:path";
4
+ import { mkdirSync as k, readFileSync as A, writeFileSync as j } from "node:fs";
5
+ import { CopilotClient as ne, approveAll as re } from "@github/copilot-sdk";
6
+ import { spawn as ie } from "node:child_process";
7
+ import { tmpdir as ae } from "node:os";
8
+ //#region src/lib/describe/describe.ts
9
+ function oe(t, n) {
10
+ _(() => {
11
+ o(t);
12
+ try {
13
+ let t = n();
14
+ if (t && typeof t.then == "function") {
15
+ e(t.finally(() => {
16
+ l();
17
+ }));
18
+ return;
19
+ }
20
+ } catch (e) {
21
+ throw l(), e;
22
+ }
23
+ l();
24
+ }, c());
25
+ }
26
+ //#endregion
27
+ //#region src/lib/prompt/codex.ts
28
+ var se = "katt-codex-", ce = "last-message.txt";
29
+ function le(e, t) {
30
+ return typeof e == "object" && !!e && "code" in e && e.code === t;
31
+ }
32
+ function M(e) {
33
+ return typeof e == "string" && e.length > 0;
34
+ }
35
+ function ue(e) {
36
+ return M(e) ? [e] : Array.isArray(e) ? e.filter(M) : [];
37
+ }
38
+ function de(e, t, n = !1) {
39
+ let r = t ?? {}, i = [
40
+ "exec",
41
+ "--color",
42
+ "never",
43
+ ...n ? ["--json"] : [],
44
+ "--output-last-message",
45
+ e
46
+ ];
47
+ M(r.model) && i.push("--model", r.model), M(r.profile) && i.push("--profile", r.profile), M(r.sandbox) && i.push("--sandbox", r.sandbox), r.fullAuto === !0 && i.push("--full-auto"), r.skipGitRepoCheck === !0 && i.push("--skip-git-repo-check"), r.dangerouslyBypassApprovalsAndSandbox === !0 && i.push("--dangerously-bypass-approvals-and-sandbox");
48
+ for (let e of ue(r.config)) i.push("--config", e);
49
+ return i.push("-"), i;
50
+ }
51
+ function N(e, t, n, r) {
52
+ return new Promise((i, a) => {
53
+ let o = ie("codex", t, {
54
+ cwd: r,
55
+ stdio: [
56
+ "pipe",
57
+ "pipe",
58
+ "pipe"
59
+ ]
60
+ }), s = "", c = "", l = !1;
61
+ o.stdout.setEncoding("utf8"), o.stderr.setEncoding("utf8"), o.stdout.on("data", (e) => {
62
+ s += e;
63
+ }), o.stderr.on("data", (e) => {
64
+ c += e;
65
+ }), o.stdin.on("error", () => {});
66
+ let u = setTimeout(() => {
67
+ l = !0, o.kill("SIGTERM");
68
+ }, n);
69
+ o.once("error", (e) => {
70
+ clearTimeout(u), a(/* @__PURE__ */ Error(`Failed to start Codex CLI. Ensure codex is installed and available on PATH. ${String(e)}`));
71
+ }), o.once("close", (e, t) => {
72
+ clearTimeout(u), i({
73
+ exitCode: e,
74
+ signal: t,
75
+ stdout: s.trim(),
76
+ stderr: c.trim(),
77
+ timedOut: l
78
+ });
79
+ }), o.stdin.end(e);
80
+ });
81
+ }
82
+ async function P(e, t) {
83
+ try {
84
+ return await C(e, "utf8");
85
+ } catch (e) {
86
+ if (!le(e, "ENOENT")) throw e;
87
+ return t;
88
+ }
89
+ }
90
+ function F(e) {
91
+ if (e.timedOut) return "Codex timed out before returning a response.";
92
+ if (e.exitCode === null) return `Codex exited due to signal ${e.signal ?? "unknown"}.`;
93
+ let t = e.stderr.length > 0 ? ` ${e.stderr}` : "";
94
+ return `Codex exited with code ${e.exitCode}.${t}`;
95
+ }
96
+ function I(e) {
97
+ return typeof e == "object" && !!e;
98
+ }
99
+ function L(e) {
100
+ return typeof e == "string" && e.trim().length > 0 ? e.trim() : void 0;
101
+ }
102
+ function R(e, t, n = 0) {
103
+ if (n > 6) return;
104
+ let r = L(e);
105
+ if (r) {
106
+ t.push(r);
107
+ return;
108
+ }
109
+ if (Array.isArray(e)) {
110
+ for (let r of e) R(r, t, n + 1);
111
+ return;
112
+ }
113
+ if (I(e)) for (let r of [
114
+ "reasoning",
115
+ "reasoningText",
116
+ "reasoning_text",
117
+ "content",
118
+ "summary",
119
+ "deltaContent",
120
+ "delta",
121
+ "text",
122
+ "intent",
123
+ "analysis",
124
+ "thought",
125
+ "plan",
126
+ "message"
127
+ ]) r in e && R(e[r], t, n + 1);
128
+ }
129
+ function z(e) {
130
+ if (e.trim().length === 0) return [];
131
+ try {
132
+ let t = JSON.parse(e);
133
+ if (!I(t)) return [];
134
+ let n = [], r = L(t.type);
135
+ if (r && /reason|intent|plan|analysis|thought|think/i.test(r) && R(t, n), "msg" in t && I(t.msg)) {
136
+ let e = L(t.msg.type);
137
+ e && /reason|intent|plan|analysis|thought|think/i.test(e) && R(t.msg, n);
138
+ }
139
+ return n;
140
+ } catch {
141
+ return [];
142
+ }
143
+ }
144
+ function B(e) {
145
+ let t = e.split(/\r?\n/), n = [], r = /* @__PURE__ */ new Set();
146
+ for (let e of t) {
147
+ let t = z(e);
148
+ for (let e of t) r.has(e) || (r.add(e), n.push(e));
149
+ }
150
+ return n.join("\n\n");
151
+ }
152
+ function V(e) {
153
+ let t = e.split(/\r?\n/), n = "";
154
+ for (let e of t) if (e.trim().length !== 0) try {
155
+ let t = JSON.parse(e);
156
+ if (!I(t)) continue;
157
+ if (I(t.msg) && L(t.msg.type) === "agent_message") {
158
+ let e = L(t.msg.message);
159
+ e && (n = e);
160
+ }
161
+ } catch {}
162
+ return n;
163
+ }
164
+ async function H(e, t, n, r) {
165
+ let i = n ?? {}, a = M(i.workingDirectory) ? i.workingDirectory : process.cwd(), o = await S(D(ae(), se)), s = D(o, ce);
166
+ try {
167
+ let i = await N(e, de(s, n, r), t, a);
168
+ if (i.timedOut) throw Error(`Codex timed out after ${t}ms.`);
169
+ if (i.exitCode !== 0) throw Error(F(i));
170
+ let o = await P(s, r ? V(i.stdout) : i.stdout);
171
+ if (o.length === 0) throw Error("Codex did not return a response.");
172
+ return {
173
+ response: o,
174
+ reasoning: r ? B(i.stdout) : ""
175
+ };
176
+ } finally {
177
+ await w(o, {
178
+ recursive: !0,
179
+ force: !0
180
+ });
181
+ }
182
+ }
183
+ async function fe(e, t, n) {
184
+ return (await H(e, t, n, !1)).response;
185
+ }
186
+ async function pe(e, t, n) {
187
+ return H(e, t, n, !0);
188
+ }
189
+ //#endregion
190
+ //#region src/lib/prompt/reasoningWriter.ts
191
+ var me = "No reasoning was emitted by the runtime for this prompt.", he = "No final output was returned by the runtime for this prompt.", ge = new Set([
192
+ "<",
193
+ ">",
194
+ ":",
195
+ "\"",
196
+ "/",
197
+ "\\",
198
+ "|",
199
+ "?",
200
+ "*"
201
+ ]);
202
+ function U(e) {
203
+ let t = e.trim().split("").map((e) => e.charCodeAt(0) <= 31 || ge.has(e) ? "_" : e).join("").replace(/\s+/g, "_");
204
+ return t.length > 0 ? t : "unnamed";
205
+ }
206
+ function _e() {
207
+ let e = g().map((e) => U(e.description)), t = i().map((e) => U(e.description)), n = [...e, ...t];
208
+ return n.length === 0 ? "root" : n.join("__");
209
+ }
210
+ function ve(e) {
211
+ return `${String(e.getUTCFullYear())}${String(e.getUTCMonth() + 1).padStart(2, "0")}${String(e.getUTCDate()).padStart(2, "0")}T${String(e.getUTCHours()).padStart(2, "0")}${String(e.getUTCMinutes()).padStart(2, "0")}${String(e.getUTCSeconds()).padStart(2, "0")}`;
212
+ }
213
+ async function ye(e) {
214
+ try {
215
+ return await y(e, b.F_OK), !0;
216
+ } catch {
217
+ return !1;
218
+ }
219
+ }
220
+ function be(e, t, n) {
221
+ let r = t.trim().length > 0 ? t : me, i = n.trim().length > 0 ? n : he;
222
+ return [
223
+ "# Reasoning",
224
+ "",
225
+ `Runtime: ${e}`,
226
+ "",
227
+ "## Reasoning Trace",
228
+ "",
229
+ r,
230
+ "",
231
+ "## Final Output",
232
+ "",
233
+ i,
234
+ ""
235
+ ].join("\n");
236
+ }
237
+ function xe(e) {
238
+ let t = T(e).replace(/\.eval\.[^./\\]+$/, ""), n = _e();
239
+ return D(E(e), "__reasoning__", `${t}__${n}.reasoning.md`);
240
+ }
241
+ function Se(e) {
242
+ let t = ve(/* @__PURE__ */ new Date());
243
+ return `${e.replace(/\.reasoning\.md$/, "")}__${t}.reasoning.md`;
244
+ }
245
+ async function W(e, n, r) {
246
+ let i = t.getStore()?.evalFile;
247
+ if (!i) return;
248
+ let a = xe(i);
249
+ await x(E(a), { recursive: !0 });
250
+ let o = await ye(a) ? Se(a) : a;
251
+ return await ee(o, be(e, n, r), "utf8"), o;
252
+ }
253
+ function G(e) {
254
+ return typeof e == "string" && e.length > 0 ? e : void 0;
255
+ }
256
+ function K(e) {
257
+ if (!e) return;
258
+ let t = { ...e };
259
+ if (t.model !== void 0) {
260
+ let e = G(typeof t.model == "string" ? t.model : void 0);
261
+ e ? t.model = e : delete t.model;
262
+ }
263
+ return Object.keys(t).length > 0 ? t : void 0;
264
+ }
265
+ function q(e) {
266
+ if (!(typeof e != "number" || !Number.isFinite(e)) && !(e <= 0)) return Math.floor(e);
267
+ }
268
+ function J(e) {
269
+ return !Number.isFinite(e) || (e ?? 0) <= 0 ? 0 : Math.floor(e ?? 0);
270
+ }
271
+ function Ce(e) {
272
+ return J(e.inputTokens) + J(e.outputTokens) + J(e.cacheReadTokens) + J(e.cacheWriteTokens);
273
+ }
274
+ async function Y(e, t = {}) {
275
+ let { timeoutMs: r, onPermissionRequest: i, ...a } = t, o = await u(), s = K(o.agentOptions), c = K(a), l = K({
276
+ ...s ?? {},
277
+ ...c ?? {}
278
+ }), d = q(o.promptTimeoutMs), f = q(r) ?? d ?? 6e5, m = G(typeof l?.model == "string" ? l.model : void 0), h = p();
279
+ if (o.agent === "codex") {
280
+ if (h) {
281
+ let t = await pe(e, f, l);
282
+ return m && v(m), await W("codex", t.reasoning, t.response), t.response;
283
+ }
284
+ let t = await fe(e, f, l);
285
+ return m && v(m), t;
286
+ }
287
+ let g = new ne({ useLoggedInUser: !0 }), _, y, b, x, S = 0, C = [], w = [];
288
+ try {
289
+ await g.start(), _ = await g.createSession({
290
+ ...l,
291
+ onPermissionRequest: i ?? re
292
+ }), y = _.on("assistant.usage", (e) => {
293
+ S += Ce(e.data);
294
+ }), b = _.on("assistant.reasoning", (e) => {
295
+ typeof e.data.content == "string" && e.data.content.length > 0 && C.push(e.data.content);
296
+ }), x = _.on("assistant.intent", (e) => {
297
+ typeof e.data.intent == "string" && e.data.intent.length > 0 && w.push(e.data.intent);
298
+ });
299
+ let t = await _.sendAndWait({ prompt: e }, f);
300
+ if (!t?.data?.content) throw Error("Copilot did not return a response.");
301
+ if (h) {
302
+ let e = [];
303
+ for (let t of w) e.push(`Intent: ${t}`);
304
+ e.push(...C), typeof t.data.reasoningText == "string" && t.data.reasoningText.length > 0 && e.push(t.data.reasoningText), await W("gh-copilot", e.join("\n\n"), t.data.content);
305
+ }
306
+ return m && v(m), t.data.content;
307
+ } finally {
308
+ let e = [];
309
+ if (y?.(), b?.(), x?.(), S > 0 && n(S), _) try {
310
+ await _.destroy();
311
+ } catch (t) {
312
+ e.push(t);
313
+ }
314
+ try {
315
+ let t = await g.stop();
316
+ e.push(...t);
317
+ } catch (t) {
318
+ e.push(t);
319
+ }
320
+ e.length > 0 && console.error(`Copilot cleanup encountered ${e.length} error(s).`);
321
+ }
322
+ }
323
+ async function we(e, n = {}) {
324
+ let r = t.getStore(), i = r?.evalFile ? E(r.evalFile) : process.cwd();
325
+ return Y(await C(te(e) ? e : O(i, e), "utf8"), n);
326
+ }
327
+ //#endregion
328
+ //#region src/lib/expect/matcherUtils.ts
329
+ function X(e) {
330
+ a({
331
+ describePath: r(),
332
+ itPath: f(),
333
+ message: e
334
+ });
335
+ }
336
+ //#endregion
337
+ //#region src/lib/expect/promptCheck.ts
338
+ async function Te(t, n) {
339
+ let r = Date.now(), i = `expected '${t}' to satisfy '${n}'`, a = Y(`Evaluate if the expectation is fulfiled in by the input.
340
+ Expectation: "${n}".
230
341
  Input:
231
342
  ---
232
343
  ${t}
233
344
  ---
234
345
  Important: Answer with "Yes" or "No" only, without any additional text.
235
- `).then((s) => {
236
- s.includes("Yes") ? h(!0, Date.now() - n, "promptCheck") : s.includes("No") ? l(o) : l(`failed to evaluate expectation '${e}'`);
237
- });
238
- return C(i), i;
239
- }
240
- const yt = 3;
241
- function Ct(t) {
242
- const e = t.match(/\b([1-5])\b/);
243
- return !e || !e[1] ? null : Number(e[1]);
244
- }
245
- async function bt(t, e, n) {
246
- const o = Date.now(), i = n?.threshold ?? yt, s = F(
247
- `Classify the input by how "${e}" it is on a scale of 1 to 5.
248
- 1 means "not ${e}" and 5 means "very ${e}".
346
+ `).then((e) => {
347
+ e.includes("Yes") ? m(Date.now() - r, "promptCheck") : e.includes("No") ? X(i) : X(`failed to evaluate expectation '${n}'`);
348
+ });
349
+ return e(a), a;
350
+ }
351
+ //#endregion
352
+ //#region src/lib/expect/toBeClassifiedAs.ts
353
+ var Ee = 3;
354
+ function De(e) {
355
+ let t = e.match(/\b([1-5])\b/);
356
+ return t?.[1] ? Number(t[1]) : null;
357
+ }
358
+ async function Oe(t, n, r) {
359
+ let i = Date.now(), a = r?.threshold ?? Ee, o = Y(`Classify the input by how "${n}" it is on a scale of 1 to 5.
360
+ 1 means "not ${n}" and 5 means "very ${n}".
249
361
  Return only a single number: 1, 2, 3, 4, or 5.
250
362
 
251
363
  Input:
252
364
  ---
253
365
  ${t}
254
- ---`,
255
- n?.model ? { model: n.model } : void 0
256
- ).then((r) => {
257
- const a = Ct(r);
258
- if (a === null) {
259
- l(
260
- `failed to classify as '${e}'. Evaluator returned '${r}'`
261
- );
262
- return;
263
- }
264
- const c = `expected response to be classified as '${e}' with score >= ${i}, got ${a}`;
265
- if (a < i) {
266
- l(c);
267
- return;
268
- }
269
- h(
270
- !0,
271
- Date.now() - o,
272
- "toBeClassifiedAs"
273
- );
274
- });
275
- return C(s), s;
276
- }
277
- function Tt(t, e) {
278
- const n = `expected '${t}' to include '${e}'`;
279
- t.includes(e) || l(n);
280
- }
281
- function _(t) {
282
- const e = t.trim().replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").replace(/\s+/g, "_");
283
- return e.length > 0 ? e : "unnamed";
284
- }
285
- function $t() {
286
- const t = K().map(
287
- (o) => _(o.description)
288
- ), e = J().map(
289
- (o) => _(o.description)
290
- ), n = [...t, ...e];
291
- return n.length === 0 ? "root" : n.join("__");
292
- }
293
- function Et(t) {
294
- const n = nt(t).replace(/\.eval\.[^./\\]+$/, ""), o = $t();
295
- return S(
296
- v(t),
297
- "__snapshots__",
298
- `${n}__${o}.snap.md`
299
- );
300
- }
301
- function P(t) {
302
- return t.split(/\r?\n/);
303
- }
304
- function St(t, e) {
305
- if (t === e)
306
- return " (no diff)";
307
- const n = P(t), o = P(e), i = Math.max(n.length, o.length), s = [];
308
- for (let r = 0; r < i; r += 1) {
309
- const a = n[r], c = o[r];
310
- if (a !== c) {
311
- if (a === void 0 && c !== void 0) {
312
- s.push(`+ ${c}`);
313
- continue;
314
- }
315
- if (a !== void 0 && c === void 0) {
316
- s.push(`- ${a}`);
317
- continue;
318
- }
319
- s.push(`- ${a ?? ""}`), s.push(`+ ${c ?? ""}`);
320
- }
321
- }
322
- return s.join(`
323
- `);
324
- }
325
- function vt(t) {
326
- const e = L.getStore()?.evalFile;
327
- if (!e) {
328
- l(
329
- "toMatchSnapshot can only be used while running an eval file."
330
- );
331
- return;
332
- }
333
- const n = Et(e);
334
- try {
335
- const o = st(n, "utf8");
336
- if (o === t)
337
- return;
338
- if (q()) {
339
- M(n, t, "utf8");
340
- return;
341
- }
342
- const i = St(o, t);
343
- l(
344
- [
345
- `Snapshot mismatch at ${n}`,
346
- "",
347
- "Diff:",
348
- i,
349
- "",
350
- "Run 'npx katt --update-snapshots' (or -u) to accept this change."
351
- ].join(`
352
- `)
353
- );
354
- } catch (o) {
355
- if (o.code !== "ENOENT") {
356
- l(
357
- `Failed to read snapshot at ${n}: ${String(o)}`
358
- );
359
- return;
360
- }
361
- try {
362
- it(v(n), { recursive: !0 }), M(n, t, "utf8");
363
- } catch (s) {
364
- l(
365
- `Failed to write snapshot at ${n}: ${String(s)}`
366
- );
367
- }
368
- }
369
- }
370
- function Lt(t) {
371
- return {
372
- toContain: (e) => {
373
- Tt(t, e);
374
- },
375
- toMatchSnapshot: () => {
376
- vt(t);
377
- },
378
- promptCheck: async (e) => {
379
- await wt(t, e);
380
- },
381
- toBeClassifiedAs: async (e, n) => {
382
- await bt(t, e, n);
383
- }
384
- };
385
- }
386
- export {
387
- Nt as describe,
388
- Lt as expect,
389
- Pt as it,
390
- F as prompt,
391
- It as promptFile,
392
- jt as runCli
393
- };
366
+ ---`, r?.model ? { model: r.model } : void 0).then((e) => {
367
+ let t = De(e);
368
+ if (t === null) {
369
+ X(`failed to classify as '${n}'. Evaluator returned '${e}'`);
370
+ return;
371
+ }
372
+ let r = `expected response to be classified as '${n}' with score >= ${a}, got ${t}`;
373
+ if (t < a) {
374
+ X(r);
375
+ return;
376
+ }
377
+ m(Date.now() - i, "toBeClassifiedAs");
378
+ });
379
+ return e(o), o;
380
+ }
381
+ //#endregion
382
+ //#region src/lib/expect/toContain.ts
383
+ function ke(e, t) {
384
+ let n = `expected '${e}' to include '${t}'`;
385
+ e.includes(t) || X(n);
386
+ }
387
+ //#endregion
388
+ //#region src/lib/expect/toMatchSnapshot.ts
389
+ var Z = new Set([
390
+ "<",
391
+ ">",
392
+ ":",
393
+ "\"",
394
+ "/",
395
+ "\\",
396
+ "|",
397
+ "?",
398
+ "*"
399
+ ]);
400
+ function Q(e) {
401
+ let t = e.trim().split("").map((e) => e.charCodeAt(0) <= 31 || Z.has(e) ? "_" : e).join("").replace(/\s+/g, "_");
402
+ return t.length > 0 ? t : "unnamed";
403
+ }
404
+ function Ae() {
405
+ let e = g().map((e) => Q(e.description)), t = i().map((e) => Q(e.description)), n = [...e, ...t];
406
+ return n.length === 0 ? "root" : n.join("__");
407
+ }
408
+ function je(e) {
409
+ let t = T(e).replace(/\.eval\.[^./\\]+$/, ""), n = Ae();
410
+ return D(E(e), "__snapshots__", `${t}__${n}.snap.md`);
411
+ }
412
+ function $(e) {
413
+ return e.split(/\r?\n/);
414
+ }
415
+ function Me(e, t) {
416
+ if (e === t) return " (no diff)";
417
+ let n = $(e), r = $(t), i = Math.max(n.length, r.length), a = [];
418
+ for (let e = 0; e < i; e += 1) {
419
+ let t = n[e], i = r[e];
420
+ if (t !== i) {
421
+ if (t === void 0 && i !== void 0) {
422
+ a.push(`+ ${i}`);
423
+ continue;
424
+ }
425
+ if (t !== void 0 && i === void 0) {
426
+ a.push(`- ${t}`);
427
+ continue;
428
+ }
429
+ a.push(`- ${t ?? ""}`), a.push(`+ ${i ?? ""}`);
430
+ }
431
+ }
432
+ return a.join("\n");
433
+ }
434
+ function Ne(e) {
435
+ let n = t.getStore()?.evalFile;
436
+ if (!n) {
437
+ X("toMatchSnapshot can only be used while running an eval file.");
438
+ return;
439
+ }
440
+ let r = je(n);
441
+ try {
442
+ let t = A(r, "utf8");
443
+ if (t === e) return;
444
+ if (s()) {
445
+ j(r, e, "utf8");
446
+ return;
447
+ }
448
+ let n = Me(t, e);
449
+ X([
450
+ `Snapshot mismatch at ${r}`,
451
+ "",
452
+ "Diff:",
453
+ n,
454
+ "",
455
+ "Run 'npx katt --update-snapshots' (or -u) to accept this change."
456
+ ].join("\n"));
457
+ } catch (t) {
458
+ if (t.code !== "ENOENT") {
459
+ X(`Failed to read snapshot at ${r}: ${String(t)}`);
460
+ return;
461
+ }
462
+ try {
463
+ k(E(r), { recursive: !0 }), j(r, e, "utf8");
464
+ } catch (e) {
465
+ X(`Failed to write snapshot at ${r}: ${String(e)}`);
466
+ }
467
+ }
468
+ }
469
+ //#endregion
470
+ //#region src/lib/expect/expect.ts
471
+ function Pe(e) {
472
+ return {
473
+ toContain: (t) => {
474
+ ke(e, t);
475
+ },
476
+ toMatchSnapshot: () => {
477
+ Ne(e);
478
+ },
479
+ promptCheck: async (t) => {
480
+ await Te(e, t);
481
+ },
482
+ toBeClassifiedAs: async (t, n) => {
483
+ await Oe(e, t, n);
484
+ }
485
+ };
486
+ }
487
+ //#endregion
488
+ export { oe as describe, Pe as expect, d as it, Y as prompt, we as promptFile, h as runCli };