katt 0.0.8 → 0.0.10
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/CODE_OF_CONDUCT.MD +92 -0
- package/README.md +46 -26
- package/SECURITY.md +10 -0
- package/build-tests/check1.eval.js +0 -9
- package/build-tests/check2.eval.js +0 -7
- package/dist/index.js +286 -357
- package/dist/katt.js +6 -4
- package/dist/runCli-DkkiL_uk.js +388 -0
- package/package.json +7 -7
- package/build-tests/__snapshots__/check1.snap.md +0 -1
- package/build-tests/__snapshots__/check1__Hello_World__should_return_the_date_in_a_json_format.snap.md +0 -1
- package/build-tests/__snapshots__/check1__root.snap.md +0 -1
- package/dist/runCli-425rgVp8.js +0 -424
package/dist/index.js
CHANGED
|
@@ -1,393 +1,322 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { spawn as
|
|
7
|
-
import { tmpdir as
|
|
8
|
-
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
} catch (r) {
|
|
28
|
-
throw h(!1, s()), T(), r;
|
|
29
|
-
}
|
|
30
|
-
h(i(), s()), T();
|
|
31
|
-
}, I());
|
|
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 _ } from "./runCli-DkkiL_uk.js";
|
|
2
|
+
import { mkdtemp as v, readFile as y, rm as b } from "node:fs/promises";
|
|
3
|
+
import { basename as x, dirname as S, isAbsolute as C, join as w, resolve as T } from "node:path";
|
|
4
|
+
import { mkdirSync as E, readFileSync as D, writeFileSync as O } from "node:fs";
|
|
5
|
+
import { CopilotClient as ee, approveAll as te } from "@github/copilot-sdk";
|
|
6
|
+
import { spawn as ne } from "node:child_process";
|
|
7
|
+
import { tmpdir as k } from "node:os";
|
|
8
|
+
//#region src/lib/describe/describe.ts
|
|
9
|
+
function A(t, r) {
|
|
10
|
+
e(() => {
|
|
11
|
+
l(t);
|
|
12
|
+
try {
|
|
13
|
+
let e = r();
|
|
14
|
+
if (e && typeof e.then == "function") {
|
|
15
|
+
a(e.finally(() => {
|
|
16
|
+
f();
|
|
17
|
+
}));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
} catch (e) {
|
|
21
|
+
throw f(), e;
|
|
22
|
+
}
|
|
23
|
+
f();
|
|
24
|
+
}, n());
|
|
32
25
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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());
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/lib/prompt/codex.ts
|
|
28
|
+
var j = "katt-codex-", M = "last-message.txt";
|
|
29
|
+
function N(e, t) {
|
|
30
|
+
return typeof e == "object" && !!e && "code" in e && e.code === t;
|
|
51
31
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return typeof t == "object" && t !== null && "code" in t && t.code === e;
|
|
32
|
+
function P(e) {
|
|
33
|
+
return typeof e == "string" && e.length > 0;
|
|
55
34
|
}
|
|
56
|
-
function
|
|
57
|
-
|
|
35
|
+
function F(e) {
|
|
36
|
+
return P(e) ? [e] : Array.isArray(e) ? e.filter(P) : [];
|
|
58
37
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
38
|
+
function I(e, t) {
|
|
39
|
+
let n = t ?? {}, r = [
|
|
40
|
+
"exec",
|
|
41
|
+
"--color",
|
|
42
|
+
"never",
|
|
43
|
+
"--output-last-message",
|
|
44
|
+
e
|
|
45
|
+
];
|
|
46
|
+
P(n.model) && r.push("--model", n.model), P(n.profile) && r.push("--profile", n.profile), P(n.sandbox) && r.push("--sandbox", n.sandbox), n.fullAuto === !0 && r.push("--full-auto"), n.skipGitRepoCheck === !0 && r.push("--skip-git-repo-check"), n.dangerouslyBypassApprovalsAndSandbox === !0 && r.push("--dangerously-bypass-approvals-and-sandbox");
|
|
47
|
+
for (let e of F(n.config)) r.push("--config", e);
|
|
48
|
+
return r.push("-"), r;
|
|
61
49
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
50
|
+
function L(e, t, n, r) {
|
|
51
|
+
return new Promise((i, a) => {
|
|
52
|
+
let o = ne("codex", t, {
|
|
53
|
+
cwd: r,
|
|
54
|
+
stdio: [
|
|
55
|
+
"pipe",
|
|
56
|
+
"pipe",
|
|
57
|
+
"pipe"
|
|
58
|
+
]
|
|
59
|
+
}), s = "", c = "", l = !1;
|
|
60
|
+
o.stdout.setEncoding("utf8"), o.stderr.setEncoding("utf8"), o.stdout.on("data", (e) => {
|
|
61
|
+
s += e;
|
|
62
|
+
}), o.stderr.on("data", (e) => {
|
|
63
|
+
c += e;
|
|
64
|
+
}), o.stdin.on("error", () => {});
|
|
65
|
+
let u = setTimeout(() => {
|
|
66
|
+
l = !0, o.kill("SIGTERM");
|
|
67
|
+
}, n);
|
|
68
|
+
o.once("error", (e) => {
|
|
69
|
+
clearTimeout(u), a(/* @__PURE__ */ Error(`Failed to start Codex CLI. Ensure codex is installed and available on PATH. ${String(e)}`));
|
|
70
|
+
}), o.once("close", (e, t) => {
|
|
71
|
+
clearTimeout(u), i({
|
|
72
|
+
exitCode: e,
|
|
73
|
+
signal: t,
|
|
74
|
+
stdout: s.trim(),
|
|
75
|
+
stderr: c.trim(),
|
|
76
|
+
timedOut: l
|
|
77
|
+
});
|
|
78
|
+
}), o.stdin.end(e);
|
|
79
|
+
});
|
|
74
80
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
});
|
|
81
|
+
async function R(e, t) {
|
|
82
|
+
try {
|
|
83
|
+
return await y(e, "utf8");
|
|
84
|
+
} catch (e) {
|
|
85
|
+
if (!N(e, "ENOENT")) throw e;
|
|
86
|
+
return t;
|
|
87
|
+
}
|
|
109
88
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
throw n;
|
|
116
|
-
return e;
|
|
117
|
-
}
|
|
89
|
+
function z(e) {
|
|
90
|
+
if (e.timedOut) return "Codex timed out before returning a response.";
|
|
91
|
+
if (e.exitCode === null) return `Codex exited due to signal ${e.signal ?? "unknown"}.`;
|
|
92
|
+
let t = e.stderr.length > 0 ? ` ${e.stderr}` : "";
|
|
93
|
+
return `Codex exited with code ${e.exitCode}.${t}`;
|
|
118
94
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
95
|
+
async function B(e, t, n) {
|
|
96
|
+
let r = n ?? {}, i = P(r.workingDirectory) ? r.workingDirectory : process.cwd(), a = await v(w(k(), j)), o = w(a, M);
|
|
97
|
+
try {
|
|
98
|
+
let r = await L(e, I(o, n), t, i);
|
|
99
|
+
if (r.timedOut) throw Error(`Codex timed out after ${t}ms.`);
|
|
100
|
+
if (r.exitCode !== 0) throw Error(z(r));
|
|
101
|
+
let a = await R(o, r.stdout);
|
|
102
|
+
if (a.length === 0) throw Error("Codex did not return a response.");
|
|
103
|
+
return a;
|
|
104
|
+
} finally {
|
|
105
|
+
await b(a, {
|
|
106
|
+
recursive: !0,
|
|
107
|
+
force: !0
|
|
108
|
+
});
|
|
109
|
+
}
|
|
126
110
|
}
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
}
|
|
111
|
+
function V(e) {
|
|
112
|
+
return typeof e == "string" && e.length > 0 ? e : void 0;
|
|
147
113
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
114
|
+
function H(e) {
|
|
115
|
+
if (!e) return;
|
|
116
|
+
let t = { ...e };
|
|
117
|
+
if (t.model !== void 0) {
|
|
118
|
+
let e = V(typeof t.model == "string" ? t.model : void 0);
|
|
119
|
+
e ? t.model = e : delete t.model;
|
|
120
|
+
}
|
|
121
|
+
return Object.keys(t).length > 0 ? t : void 0;
|
|
151
122
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
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;
|
|
123
|
+
function U(e) {
|
|
124
|
+
if (!(typeof e != "number" || !Number.isFinite(e)) && !(e <= 0)) return Math.floor(e);
|
|
163
125
|
}
|
|
164
|
-
function
|
|
165
|
-
|
|
166
|
-
return Math.floor(t);
|
|
126
|
+
function W(e) {
|
|
127
|
+
return !Number.isFinite(e) || (e ?? 0) <= 0 ? 0 : Math.floor(e ?? 0);
|
|
167
128
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
129
|
+
function G(e) {
|
|
130
|
+
return W(e.inputTokens) + W(e.outputTokens) + W(e.cacheReadTokens) + W(e.cacheWriteTokens);
|
|
170
131
|
}
|
|
171
|
-
function
|
|
172
|
-
|
|
132
|
+
async function K(e, t = {}) {
|
|
133
|
+
let { timeoutMs: n, onPermissionRequest: r, ...i } = t, a = await u(), o = H(a.agentOptions), s = H(i), c = H({
|
|
134
|
+
...o ?? {},
|
|
135
|
+
...s ?? {}
|
|
136
|
+
}), l = U(a.promptTimeoutMs), d = U(n) ?? l ?? 6e5, f = V(typeof c?.model == "string" ? c.model : void 0);
|
|
137
|
+
if (a.agent === "codex") {
|
|
138
|
+
let t = await B(e, d, c);
|
|
139
|
+
return f && _(f), t;
|
|
140
|
+
}
|
|
141
|
+
let p = new ee({ useLoggedInUser: !0 }), h, g, v = 0;
|
|
142
|
+
try {
|
|
143
|
+
await p.start(), h = await p.createSession({
|
|
144
|
+
...c,
|
|
145
|
+
onPermissionRequest: r ?? te
|
|
146
|
+
}), g = h.on("assistant.usage", (e) => {
|
|
147
|
+
v += G(e.data);
|
|
148
|
+
});
|
|
149
|
+
let t = await h.sendAndWait({ prompt: e }, d);
|
|
150
|
+
if (!t?.data?.content) throw Error("Copilot did not return a response.");
|
|
151
|
+
return f && _(f), t.data.content;
|
|
152
|
+
} finally {
|
|
153
|
+
let e = [];
|
|
154
|
+
if (g?.(), v > 0 && m(v), h) try {
|
|
155
|
+
await h.destroy();
|
|
156
|
+
} catch (t) {
|
|
157
|
+
e.push(t);
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
let t = await p.stop();
|
|
161
|
+
e.push(...t);
|
|
162
|
+
} catch (t) {
|
|
163
|
+
e.push(t);
|
|
164
|
+
}
|
|
165
|
+
e.length > 0 && console.error(`Copilot cleanup encountered ${e.length} error(s).`);
|
|
166
|
+
}
|
|
173
167
|
}
|
|
174
|
-
async function
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
}
|
|
168
|
+
async function q(e, t = {}) {
|
|
169
|
+
let n = s.getStore(), r = n?.evalFile ? S(n.evalFile) : process.cwd();
|
|
170
|
+
return K(await y(C(e) ? e : T(r, e), "utf8"), t);
|
|
215
171
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/lib/expect/matcherUtils.ts
|
|
174
|
+
function J(e) {
|
|
175
|
+
o({
|
|
176
|
+
describePath: g(),
|
|
177
|
+
itPath: i(),
|
|
178
|
+
message: e
|
|
179
|
+
});
|
|
219
180
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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}".
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/lib/expect/promptCheck.ts
|
|
183
|
+
async function Y(e, t) {
|
|
184
|
+
let n = Date.now(), r = `expected '${e}' to satisfy '${t}'`, i = K(`Evaluate if the expectation is fulfiled in by the input.
|
|
185
|
+
Expectation: "${t}".
|
|
230
186
|
Input:
|
|
231
187
|
---
|
|
232
|
-
${
|
|
188
|
+
${e}
|
|
233
189
|
---
|
|
234
190
|
Important: Answer with "Yes" or "No" only, without any additional text.
|
|
235
|
-
`).then((
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
191
|
+
`).then((e) => {
|
|
192
|
+
e.includes("Yes") ? d(Date.now() - n, "promptCheck") : e.includes("No") ? J(r) : J(`failed to evaluate expectation '${t}'`);
|
|
193
|
+
});
|
|
194
|
+
return a(i), i;
|
|
239
195
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/lib/expect/toBeClassifiedAs.ts
|
|
198
|
+
var X = 3;
|
|
199
|
+
function re(e) {
|
|
200
|
+
let t = e.match(/\b([1-5])\b/);
|
|
201
|
+
return !t || !t[1] ? null : Number(t[1]);
|
|
244
202
|
}
|
|
245
|
-
async function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
1 means "not ${e}" and 5 means "very ${e}".
|
|
203
|
+
async function ie(e, t, n) {
|
|
204
|
+
let r = Date.now(), i = n?.threshold ?? X, o = K(`Classify the input by how "${t}" it is on a scale of 1 to 5.
|
|
205
|
+
1 means "not ${t}" and 5 means "very ${t}".
|
|
249
206
|
Return only a single number: 1, 2, 3, 4, or 5.
|
|
250
207
|
|
|
251
208
|
Input:
|
|
252
209
|
---
|
|
253
|
-
${
|
|
254
|
-
---`,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
h(
|
|
270
|
-
!0,
|
|
271
|
-
Date.now() - o,
|
|
272
|
-
"toBeClassifiedAs"
|
|
273
|
-
);
|
|
274
|
-
});
|
|
275
|
-
return C(s), s;
|
|
210
|
+
${e}
|
|
211
|
+
---`, n?.model ? { model: n.model } : void 0).then((e) => {
|
|
212
|
+
let n = re(e);
|
|
213
|
+
if (n === null) {
|
|
214
|
+
J(`failed to classify as '${t}'. Evaluator returned '${e}'`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
let a = `expected response to be classified as '${t}' with score >= ${i}, got ${n}`;
|
|
218
|
+
if (n < i) {
|
|
219
|
+
J(a);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
d(Date.now() - r, "toBeClassifiedAs");
|
|
223
|
+
});
|
|
224
|
+
return a(o), o;
|
|
276
225
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/lib/expect/toContain.ts
|
|
228
|
+
function ae(e, t) {
|
|
229
|
+
let n = `expected '${e}' to include '${t}'`;
|
|
230
|
+
e.includes(t) || J(n);
|
|
280
231
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/lib/expect/toMatchSnapshot.ts
|
|
234
|
+
function Z(e) {
|
|
235
|
+
let t = e.trim().replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").replace(/\s+/g, "_");
|
|
236
|
+
return t.length > 0 ? t : "unnamed";
|
|
284
237
|
}
|
|
285
|
-
function
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
), e = J().map(
|
|
289
|
-
(o) => _(o.description)
|
|
290
|
-
), n = [...t, ...e];
|
|
291
|
-
return n.length === 0 ? "root" : n.join("__");
|
|
238
|
+
function oe() {
|
|
239
|
+
let e = c().map((e) => Z(e.description)), t = r().map((e) => Z(e.description)), n = [...e, ...t];
|
|
240
|
+
return n.length === 0 ? "root" : n.join("__");
|
|
292
241
|
}
|
|
293
|
-
function
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
v(t),
|
|
297
|
-
"__snapshots__",
|
|
298
|
-
`${n}__${o}.snap.md`
|
|
299
|
-
);
|
|
242
|
+
function se(e) {
|
|
243
|
+
let t = x(e).replace(/\.eval\.[^./\\]+$/, ""), n = oe();
|
|
244
|
+
return w(S(e), "__snapshots__", `${t}__${n}.snap.md`);
|
|
300
245
|
}
|
|
301
|
-
function
|
|
302
|
-
|
|
246
|
+
function Q(e) {
|
|
247
|
+
return e.split(/\r?\n/);
|
|
303
248
|
}
|
|
304
|
-
function
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return s.join(`
|
|
323
|
-
`);
|
|
249
|
+
function ce(e, t) {
|
|
250
|
+
if (e === t) return " (no diff)";
|
|
251
|
+
let n = Q(e), r = Q(t), i = Math.max(n.length, r.length), a = [];
|
|
252
|
+
for (let e = 0; e < i; e += 1) {
|
|
253
|
+
let t = n[e], i = r[e];
|
|
254
|
+
if (t !== i) {
|
|
255
|
+
if (t === void 0 && i !== void 0) {
|
|
256
|
+
a.push(`+ ${i}`);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (t !== void 0 && i === void 0) {
|
|
260
|
+
a.push(`- ${t}`);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
a.push(`- ${t ?? ""}`), a.push(`+ ${i ?? ""}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return a.join("\n");
|
|
324
267
|
}
|
|
325
|
-
function
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
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
|
-
}
|
|
268
|
+
function le(e) {
|
|
269
|
+
let t = s.getStore()?.evalFile;
|
|
270
|
+
if (!t) {
|
|
271
|
+
J("toMatchSnapshot can only be used while running an eval file.");
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
let n = se(t);
|
|
275
|
+
try {
|
|
276
|
+
let t = D(n, "utf8");
|
|
277
|
+
if (t === e) return;
|
|
278
|
+
if (p()) {
|
|
279
|
+
O(n, e, "utf8");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
let r = ce(t, e);
|
|
283
|
+
J([
|
|
284
|
+
`Snapshot mismatch at ${n}`,
|
|
285
|
+
"",
|
|
286
|
+
"Diff:",
|
|
287
|
+
r,
|
|
288
|
+
"",
|
|
289
|
+
"Run 'npx katt --update-snapshots' (or -u) to accept this change."
|
|
290
|
+
].join("\n"));
|
|
291
|
+
} catch (t) {
|
|
292
|
+
if (t.code !== "ENOENT") {
|
|
293
|
+
J(`Failed to read snapshot at ${n}: ${String(t)}`);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
E(S(n), { recursive: !0 }), O(n, e, "utf8");
|
|
298
|
+
} catch (e) {
|
|
299
|
+
J(`Failed to write snapshot at ${n}: ${String(e)}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
369
302
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region src/lib/expect/expect.ts
|
|
305
|
+
function $(e) {
|
|
306
|
+
return {
|
|
307
|
+
toContain: (t) => {
|
|
308
|
+
ae(e, t);
|
|
309
|
+
},
|
|
310
|
+
toMatchSnapshot: () => {
|
|
311
|
+
le(e);
|
|
312
|
+
},
|
|
313
|
+
promptCheck: async (t) => {
|
|
314
|
+
await Y(e, t);
|
|
315
|
+
},
|
|
316
|
+
toBeClassifiedAs: async (t, n) => {
|
|
317
|
+
await ie(e, t, n);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
385
320
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
Lt as expect,
|
|
389
|
-
Pt as it,
|
|
390
|
-
F as prompt,
|
|
391
|
-
It as promptFile,
|
|
392
|
-
jt as runCli
|
|
393
|
-
};
|
|
321
|
+
//#endregion
|
|
322
|
+
export { A as describe, $ as expect, t as it, K as prompt, q as promptFile, h as runCli };
|