reeval 0.0.1
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/LICENSE +202 -0
- package/THIRD_PARTY_NOTICES.md +2160 -0
- package/assets/package.json +9 -0
- package/assets/pnpm-lock.yaml +1336 -0
- package/dist/agent-DVHkx8aT.js +532 -0
- package/dist/agent-DVHkx8aT.js.map +1 -0
- package/dist/analysis-CxSCt1YY.js +16 -0
- package/dist/analysis-CxSCt1YY.js.map +1 -0
- package/dist/assemble-B-nmz8oH.js +695 -0
- package/dist/assemble-B-nmz8oH.js.map +1 -0
- package/dist/assemble-CmRVDZ2Q.js +2 -0
- package/dist/attempt-BdRQ9jKX.js +176 -0
- package/dist/attempt-BdRQ9jKX.js.map +1 -0
- package/dist/bridge/index.mjs +1911 -0
- package/dist/bridge/package.json +13 -0
- package/dist/bridge/pnpm-lock.yaml +1041 -0
- package/dist/bridge/pnpm-workspace.yaml +2 -0
- package/dist/budget-DBUrH4jX.js +8 -0
- package/dist/budget-DBUrH4jX.js.map +1 -0
- package/dist/cli--CQ3Iy9q.js +1865 -0
- package/dist/cli--CQ3Iy9q.js.map +1 -0
- package/dist/cli-spec-DKAu09Gi.js +478 -0
- package/dist/cli-spec-DKAu09Gi.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors-QV9dFVhN.js +34 -0
- package/dist/colors-QV9dFVhN.js.map +1 -0
- package/dist/command-BSJzHMtP.js +280 -0
- package/dist/command-BSJzHMtP.js.map +1 -0
- package/dist/command-CEm8PZ1N.js +1043 -0
- package/dist/command-CEm8PZ1N.js.map +1 -0
- package/dist/command-D-jnQWVG.js +673 -0
- package/dist/command-D-jnQWVG.js.map +1 -0
- package/dist/command-DQAvbG7d.js +432 -0
- package/dist/command-DQAvbG7d.js.map +1 -0
- package/dist/commands-A4udfyKZ.js +2 -0
- package/dist/commands-CF8mOfiu.js +207 -0
- package/dist/commands-CF8mOfiu.js.map +1 -0
- package/dist/config-Cuj0kVYj.js +415 -0
- package/dist/config-Cuj0kVYj.js.map +1 -0
- package/dist/context-loi9OCZv.js +106 -0
- package/dist/context-loi9OCZv.js.map +1 -0
- package/dist/core-tLN-z1Be.js +96 -0
- package/dist/core-tLN-z1Be.js.map +1 -0
- package/dist/db-Cjj2ZsfQ.js +2 -0
- package/dist/db-DxDzMhtB.js +827 -0
- package/dist/db-DxDzMhtB.js.map +1 -0
- package/dist/debug-D24NOQH1.js +89 -0
- package/dist/debug-D24NOQH1.js.map +1 -0
- package/dist/debug-SEmW4w8f.js +2 -0
- package/dist/dist-BZXYHN2X.js +1673 -0
- package/dist/dist-BZXYHN2X.js.map +1 -0
- package/dist/docker-DQDZWXF9.js +20 -0
- package/dist/docker-DQDZWXF9.js.map +1 -0
- package/dist/docker-DnWAVdEm.js +2 -0
- package/dist/docker-oSbCExHL.js +153 -0
- package/dist/docker-oSbCExHL.js.map +1 -0
- package/dist/doctor-CxlH1pDM.js +525 -0
- package/dist/doctor-CxlH1pDM.js.map +1 -0
- package/dist/egress-73SQfKdx.js +619 -0
- package/dist/egress-73SQfKdx.js.map +1 -0
- package/dist/env-BQqj93gu.js +21 -0
- package/dist/env-BQqj93gu.js.map +1 -0
- package/dist/environment-Mz7wvrtD.js +552 -0
- package/dist/environment-Mz7wvrtD.js.map +1 -0
- package/dist/errors-C9w_ud7g.js +160 -0
- package/dist/errors-C9w_ud7g.js.map +1 -0
- package/dist/errors-CSxfJ4qu.js +11 -0
- package/dist/errors-CSxfJ4qu.js.map +1 -0
- package/dist/files--6CEUXm7.js +2 -0
- package/dist/files-BLlrhU4-.js +62 -0
- package/dist/files-BLlrhU4-.js.map +1 -0
- package/dist/files-Bd25OAQH.js +2 -0
- package/dist/files-BvHCFWgD.js +2 -0
- package/dist/files-D2-qn_Dl.js +275 -0
- package/dist/files-D2-qn_Dl.js.map +1 -0
- package/dist/files-bF2fPuT9.js +99 -0
- package/dist/files-bF2fPuT9.js.map +1 -0
- package/dist/git-D6hMeieS.js +44 -0
- package/dist/git-D6hMeieS.js.map +1 -0
- package/dist/harness-ls5aX1UO.js +131 -0
- package/dist/harness-ls5aX1UO.js.map +1 -0
- package/dist/harness.d.ts +74 -0
- package/dist/harness.js +2 -0
- package/dist/header-DzFDoMCI.js +78 -0
- package/dist/header-DzFDoMCI.js.map +1 -0
- package/dist/ids-Bp6ut7ZD.js +49 -0
- package/dist/ids-Bp6ut7ZD.js.map +1 -0
- package/dist/images-Cc1-coFc.js +286 -0
- package/dist/images-Cc1-coFc.js.map +1 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +1959 -0
- package/dist/index.js.map +1 -0
- package/dist/init-CFljS8BJ.js +344 -0
- package/dist/init-CFljS8BJ.js.map +1 -0
- package/dist/init-z2ZPn9Tj.js +2 -0
- package/dist/invocations-rXktgSAn.js +157 -0
- package/dist/invocations-rXktgSAn.js.map +1 -0
- package/dist/jiti-BOLXpKyG.js +46 -0
- package/dist/jiti-BOLXpKyG.js.map +1 -0
- package/dist/judge-D8Uf4dA9.js +146 -0
- package/dist/judge-D8Uf4dA9.js.map +1 -0
- package/dist/judge.d.ts +21 -0
- package/dist/judge.js +19 -0
- package/dist/judge.js.map +1 -0
- package/dist/live-Bs3LReMV.js +98 -0
- package/dist/live-Bs3LReMV.js.map +1 -0
- package/dist/matchers-DyLvm7EG.js +374 -0
- package/dist/matchers-DyLvm7EG.js.map +1 -0
- package/dist/model-BdO79gWz.js +44 -0
- package/dist/model-BdO79gWz.js.map +1 -0
- package/dist/model-CDL98xue.js +725 -0
- package/dist/model-CDL98xue.js.map +1 -0
- package/dist/model-v-0_Ik7S.js +2 -0
- package/dist/node-kG64XxdE.js +506 -0
- package/dist/node-kG64XxdE.js.map +1 -0
- package/dist/opencode-providers-DZuD_oYt.js +3149 -0
- package/dist/opencode-providers-DZuD_oYt.js.map +1 -0
- package/dist/options-CAQhu--C.js +452 -0
- package/dist/options-CAQhu--C.js.map +1 -0
- package/dist/patch-BkKje4cp.js +69 -0
- package/dist/patch-BkKje4cp.js.map +1 -0
- package/dist/paths-CBvm6pap.js +72 -0
- package/dist/paths-CBvm6pap.js.map +1 -0
- package/dist/plan-gwk6dJ8c.js +237 -0
- package/dist/plan-gwk6dJ8c.js.map +1 -0
- package/dist/preflight-BtubXKQ8.js +2 -0
- package/dist/preflight-BypZMNBG.js +185 -0
- package/dist/preflight-BypZMNBG.js.map +1 -0
- package/dist/prepare-Cwv0bHs_.js +3 -0
- package/dist/prepare-D6Uzcubb.js +213 -0
- package/dist/prepare-D6Uzcubb.js.map +1 -0
- package/dist/provenance-Dfb8YY5Y.js +129 -0
- package/dist/provenance-Dfb8YY5Y.js.map +1 -0
- package/dist/provider-BDbNOQhQ.js +2 -0
- package/dist/provider-CmAYTQQs.js +14 -0
- package/dist/provider-CmAYTQQs.js.map +1 -0
- package/dist/providers-2p3ylMHI.js +107 -0
- package/dist/providers-2p3ylMHI.js.map +1 -0
- package/dist/providers-BUOxitcT.js +2 -0
- package/dist/query-CFATHZmV.js +91 -0
- package/dist/query-CFATHZmV.js.map +1 -0
- package/dist/query-DR4m6CXf.js +2 -0
- package/dist/record-DQ8wzyco.js +99 -0
- package/dist/record-DQ8wzyco.js.map +1 -0
- package/dist/redact-C4fL_bZP.js +167 -0
- package/dist/redact-C4fL_bZP.js.map +1 -0
- package/dist/results-CeXb8Wde.js +37 -0
- package/dist/results-CeXb8Wde.js.map +1 -0
- package/dist/root-CFDjpWuc.js +110 -0
- package/dist/root-CFDjpWuc.js.map +1 -0
- package/dist/sandbox-By2gkdkC.js +133 -0
- package/dist/sandbox-By2gkdkC.js.map +1 -0
- package/dist/sandbox.d.ts +41 -0
- package/dist/sandbox.js +2 -0
- package/dist/server-Bi61uiY0.js +350 -0
- package/dist/server-Bi61uiY0.js.map +1 -0
- package/dist/server-CsSBL8NC.js +2 -0
- package/dist/source-BXzrmof5.js +2 -0
- package/dist/source-Bsfa3LZH.js +40 -0
- package/dist/source-Bsfa3LZH.js.map +1 -0
- package/dist/src-55j1zNHH.js +3 -0
- package/dist/src-AEwxd1UP.js +602 -0
- package/dist/src-AEwxd1UP.js.map +1 -0
- package/dist/src-BDwSuyIo.js +3 -0
- package/dist/src-BQyMiWri.js +490 -0
- package/dist/src-BQyMiWri.js.map +1 -0
- package/dist/src-C-LHyTSV.js +3 -0
- package/dist/src-Cmp-7YrD.js +1136 -0
- package/dist/src-Cmp-7YrD.js.map +1 -0
- package/dist/src-D0RdqpNb.js +252 -0
- package/dist/src-D0RdqpNb.js.map +1 -0
- package/dist/src-D8KYzxBX.js +793 -0
- package/dist/src-D8KYzxBX.js.map +1 -0
- package/dist/src-DEgff9Z7.js +4 -0
- package/dist/src-DXx_29pq.js +567 -0
- package/dist/src-DXx_29pq.js.map +1 -0
- package/dist/src-DwwiVLqv.js +2937 -0
- package/dist/src-DwwiVLqv.js.map +1 -0
- package/dist/src-N7E_mfcZ.js +2 -0
- package/dist/src-W9g-y5X5.js +3 -0
- package/dist/src-daS0wKH2.js +3 -0
- package/dist/state-Cyw3QTsN.js +2 -0
- package/dist/state-DZ7eqb1F.js +167 -0
- package/dist/state-DZ7eqb1F.js.map +1 -0
- package/dist/stats-BNAHlNMD.js +114 -0
- package/dist/stats-BNAHlNMD.js.map +1 -0
- package/dist/studio-app/assets/index-D6XyfFSH.js +58 -0
- package/dist/studio-app/assets/index-xwzWdcE_.css +2 -0
- package/dist/studio-app/favicon.svg +1 -0
- package/dist/studio-app/index.html +15 -0
- package/dist/summary-D7Ttky0z.js +166 -0
- package/dist/summary-D7Ttky0z.js.map +1 -0
- package/dist/text-gEcKjAyp.js +29 -0
- package/dist/text-gEcKjAyp.js.map +1 -0
- package/dist/types-C5vI3g1C.js +9 -0
- package/dist/types-C5vI3g1C.js.map +1 -0
- package/dist/types-DLec-6Cx.d.ts +1535 -0
- package/dist/usage-DsYUqIUM.js +24 -0
- package/dist/usage-DsYUqIUM.js.map +1 -0
- package/dist/view/index.d.ts +645 -0
- package/dist/view/index.js +8 -0
- package/dist/views-BrHOv6wg.js +220 -0
- package/dist/views-BrHOv6wg.js.map +1 -0
- package/dist/views-CwCWLWqo.js +3 -0
- package/dist/worker-entry-DnYkANPG.js +506 -0
- package/dist/worker-entry-DnYkANPG.js.map +1 -0
- package/dist/workspace-C2S0Z6gl.js +327 -0
- package/dist/workspace-C2S0Z6gl.js.map +1 -0
- package/dist/workspace-CyoXG6CY.js +2 -0
- package/docker/Dockerfile +19 -0
- package/package.json +79 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { c as relativeFile } from "./ids-Bp6ut7ZD.js";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { sep } from "node:path";
|
|
4
|
+
import { inspect, stripVTControlCharacters } from "node:util";
|
|
5
|
+
import { truncateString } from "@vitest/utils/display";
|
|
6
|
+
import { lineSplitRE, positionToOffset } from "@vitest/utils/offset";
|
|
7
|
+
import { parseErrorStacktrace } from "@vitest/utils/source-map";
|
|
8
|
+
//#region src/engine/errors.ts
|
|
9
|
+
// @vitest/utils (`serializeError`); this runs in the main process.
|
|
10
|
+
const paint = (open, close = 39) => (text) => `\x1b[${open}m${text}\x1b[${close}m`;
|
|
11
|
+
const red = paint(31);
|
|
12
|
+
const yellow = paint(33);
|
|
13
|
+
const cyan = paint(36);
|
|
14
|
+
const gray = paint(90);
|
|
15
|
+
const bold = paint(1, 22);
|
|
16
|
+
const dim = paint(2, 22);
|
|
17
|
+
const POINTER = "❯";
|
|
18
|
+
/** reeval's own directories; their frames are noise in an eval's stack. */
|
|
19
|
+
const esFrames = (packageDir) => [`${packageDir}${packageDir.endsWith(sep) ? "" : sep}src${sep}`, `${packageDir}${packageDir.endsWith(sep) ? "" : sep}dist${sep}`];
|
|
20
|
+
/** A path as frames are compared: forward slashes (parsed frames say C:/… on Windows), any case there. */
|
|
21
|
+
const comparable = (path, windows = process.platform === "win32") => {
|
|
22
|
+
const slashed = path.replaceAll("\\", "/");
|
|
23
|
+
return windows ? slashed.toLowerCase() : slashed;
|
|
24
|
+
};
|
|
25
|
+
/** Loaders and assertion libraries reeval runs eval files through; never the eval's own frames. */
|
|
26
|
+
const HIDDEN = [
|
|
27
|
+
"/node_modules/jiti/",
|
|
28
|
+
"/node_modules/@vitest/",
|
|
29
|
+
"/node_modules/chai/"
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* The error as the terminal shows it, with ANSI colours (renderers strip them when colour is
|
|
33
|
+
* off): `Name: message`, the diff, then each stack frame with a code frame at the first one in
|
|
34
|
+
* the project's own files, and any cause.
|
|
35
|
+
*/
|
|
36
|
+
function formatError(error, options) {
|
|
37
|
+
const lines = [];
|
|
38
|
+
printError(error, options, lines, true);
|
|
39
|
+
return lines.join("\n");
|
|
40
|
+
}
|
|
41
|
+
function printError(error, options, out, showCodeFrame) {
|
|
42
|
+
let e = error;
|
|
43
|
+
if (e === null || typeof e !== "object" && typeof e !== "function") e = {
|
|
44
|
+
message: String(error).split(/\n/g)[0],
|
|
45
|
+
stack: String(error)
|
|
46
|
+
};
|
|
47
|
+
const hide = options.hide.map((dir) => comparable(dir));
|
|
48
|
+
const stacks = parseErrorStacktrace(e, { frameFilter: (_error, frame) => !hide.some((dir) => comparable(frame.file).startsWith(dir)) && !HIDDEN.some((dir) => comparable(frame.file).includes(dir)) });
|
|
49
|
+
const nearest = stacks.find((frame) => !comparable(frame.file).includes("/node_modules/") && existsSync(frame.file));
|
|
50
|
+
const name = e.name || "Unknown Error";
|
|
51
|
+
if (!e.message) out.push(inspect(e));
|
|
52
|
+
else if (e.message.length > 5e3) out.push(`${red(bold(name))}: ${e.message}`);
|
|
53
|
+
else out.push(red(`${bold(name)}: ${e.message}`));
|
|
54
|
+
if (e.codeFrame) out.push(`${e.codeFrame}\n`);
|
|
55
|
+
if (e.diff) out.push(`\n${e.diff}\n`);
|
|
56
|
+
if (e.frame) out.push(yellow(e.frame));
|
|
57
|
+
else {
|
|
58
|
+
for (const frame of stacks) {
|
|
59
|
+
const color = frame === nearest ? cyan : gray;
|
|
60
|
+
const path = relativeFile(options.root, frame.file);
|
|
61
|
+
out.push(color(` ${dim(POINTER)} ${[frame.method, `${path}:${dim(`${frame.line}:${frame.column}`)}`].filter(Boolean).join(" ")}`));
|
|
62
|
+
if (showCodeFrame && frame === nearest) {
|
|
63
|
+
const source = readFileSync(frame.file, "utf8");
|
|
64
|
+
out.push(codeFrame(source, 4, frame, options.columns ?? 80));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (stacks.length) out.push("");
|
|
68
|
+
const properties = errorProperties(e);
|
|
69
|
+
if (Object.keys(properties).length) {
|
|
70
|
+
out.push(red(dim("⎯".repeat(options.columns ?? 80))));
|
|
71
|
+
out.push(`${red(bold("Serialized Error:"))} ${gray(inspect(properties))}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (e.cause != null) {
|
|
75
|
+
let cause = e.cause;
|
|
76
|
+
if (typeof cause !== "object") {
|
|
77
|
+
const text = String(cause);
|
|
78
|
+
cause = {
|
|
79
|
+
name: "Caused by",
|
|
80
|
+
message: text,
|
|
81
|
+
stack: text
|
|
82
|
+
};
|
|
83
|
+
} else if (!("name" in cause)) cause = {
|
|
84
|
+
...cause,
|
|
85
|
+
name: "Caused by"
|
|
86
|
+
};
|
|
87
|
+
else cause = {
|
|
88
|
+
...cause,
|
|
89
|
+
name: `Caused by: ${cause.name}`
|
|
90
|
+
};
|
|
91
|
+
printError(cause, options, out, false);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const SKIPPED = /* @__PURE__ */ new Set([
|
|
95
|
+
"cause",
|
|
96
|
+
"stacks",
|
|
97
|
+
"type",
|
|
98
|
+
"showDiff",
|
|
99
|
+
"ok",
|
|
100
|
+
"operator",
|
|
101
|
+
"diff",
|
|
102
|
+
"codeFrame",
|
|
103
|
+
"actual",
|
|
104
|
+
"expected",
|
|
105
|
+
"diffOptions",
|
|
106
|
+
"runnerError",
|
|
107
|
+
"sourceURL",
|
|
108
|
+
"column",
|
|
109
|
+
"line",
|
|
110
|
+
"fileName",
|
|
111
|
+
"lineNumber",
|
|
112
|
+
"columnNumber",
|
|
113
|
+
"VITEST_TEST_NAME",
|
|
114
|
+
"VITEST_TEST_PATH",
|
|
115
|
+
"__vitest_rollup_error__",
|
|
116
|
+
"__vitest_error_context__",
|
|
117
|
+
"__vitest_test_syntax_error__",
|
|
118
|
+
...Object.getOwnPropertyNames(Error.prototype),
|
|
119
|
+
...Object.getOwnPropertyNames(Object.prototype)
|
|
120
|
+
]);
|
|
121
|
+
/** What else the error carries (a `code`, a response…), printed below the stack. */
|
|
122
|
+
function errorProperties(e) {
|
|
123
|
+
const properties = Object.create(null);
|
|
124
|
+
if (e.name === "AssertionError") return properties;
|
|
125
|
+
for (const key of Object.getOwnPropertyNames(e)) if (key === "stack") {
|
|
126
|
+
if (e.stack != null && typeof e.stack !== "string") properties.stack = e.stack;
|
|
127
|
+
} else if (!SKIPPED.has(key)) properties[key] = e[key];
|
|
128
|
+
return properties;
|
|
129
|
+
}
|
|
130
|
+
const lineNo = (no = "") => gray(`${String(no).padStart(3, " ")}|`);
|
|
131
|
+
/** Two lines either side of `loc`, with a caret under it. */
|
|
132
|
+
function codeFrame(source, indent, loc, columns, range = 2) {
|
|
133
|
+
const start = positionToOffset(source, loc.line, loc.column);
|
|
134
|
+
const lines = source.split(lineSplitRE);
|
|
135
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
|
136
|
+
let count = 0;
|
|
137
|
+
const res = [];
|
|
138
|
+
for (let i = 0; i < lines.length; i++) {
|
|
139
|
+
count += lines[i].length + nl;
|
|
140
|
+
if (count < start) continue;
|
|
141
|
+
for (let j = Math.max(0, i - range); j <= i + range && j < lines.length; j++) {
|
|
142
|
+
const line = lines[j];
|
|
143
|
+
const stripped = stripVTControlCharacters(line);
|
|
144
|
+
if (stripped.startsWith("//# sourceMappingURL")) continue;
|
|
145
|
+
if (stripped.length > 200) return "";
|
|
146
|
+
const truncated = truncateString(line.replace(/\t/g, " "), columns - 5 - indent).trimEnd();
|
|
147
|
+
res.push(lineNo(j + 1) + (truncated ? ` ${truncated}` : truncated));
|
|
148
|
+
if (j === i) {
|
|
149
|
+
const pad = start - (count - line.length) + (nl - 1);
|
|
150
|
+
res.push(lineNo() + " ".repeat(pad + 1) + red("^"));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
return res.map((line) => " ".repeat(indent) + line).join("\n");
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
export { esFrames as n, formatError as r, codeFrame as t };
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=errors-C9w_ud7g.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-C9w_ud7g.js","names":[],"sources":["../src/engine/errors.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/** The engine's, the harness's and the attempt's own timeout messages all say "timed out". */
|
|
3
|
+
const isTimeout = (message) => /timed out/i.test(message);
|
|
4
|
+
/** A mistake in the config, an eval's options or the command line. Exits 2. */
|
|
5
|
+
var UsageError = class extends Error {
|
|
6
|
+
name = "UsageError";
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { isTimeout as n, UsageError as t };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=errors-CSxfJ4qu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-CSxfJ4qu.js","names":[],"sources":["../src/errors.ts"],"mappings":";;AACA,MAAa,aAAa,YAAoB,aAAa,KAAK,OAAO;;AAGvE,IAAa,aAAb,cAAgC,MAAM;CACpC,OAAgB;AAClB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { t as RUN_ID } from "./paths-CBvm6pap.js";
|
|
2
|
+
import { i as evalSlug } from "./ids-Bp6ut7ZD.js";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { readdir, rm, stat } from "node:fs/promises";
|
|
5
|
+
//#region src/debug/files.ts
|
|
6
|
+
/** Local debug data, one directory per run. Gitignored with `.reeval/`, never recorded. */
|
|
7
|
+
const debugRoot = (root) => join(root, ".reeval", "debug");
|
|
8
|
+
/** Where one attempt's debug data goes: the same layout as its artifacts in the run. */
|
|
9
|
+
const attemptDebugDir = (root, runId, evalId, cellKey, n) => join(debugRoot(root), runId, evalSlug(evalId), evalSlug(cellKey), String(n));
|
|
10
|
+
/** `<eval> # <cell>#<n>`, the attempt key in a record, back into its parts. */
|
|
11
|
+
function parseAttemptKey(key) {
|
|
12
|
+
const split = key.lastIndexOf(" # ");
|
|
13
|
+
if (split < 0) return null;
|
|
14
|
+
const attempt = key.slice(split + 3);
|
|
15
|
+
const hash = attempt.lastIndexOf("#");
|
|
16
|
+
const n = Number(attempt.slice(hash + 1));
|
|
17
|
+
if (hash < 0 || !Number.isInteger(n) || n < 1) return null;
|
|
18
|
+
return {
|
|
19
|
+
evalId: key.slice(0, split),
|
|
20
|
+
cell: attempt.slice(0, hash),
|
|
21
|
+
n
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Runs with debug data, oldest first. */
|
|
25
|
+
async function debugRuns(root) {
|
|
26
|
+
try {
|
|
27
|
+
return (await readdir(debugRoot(root))).filter((name) => RUN_ID.test(name)).sort();
|
|
28
|
+
} catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function size(path) {
|
|
33
|
+
const info = await stat(path).catch(() => null);
|
|
34
|
+
if (!info) return 0;
|
|
35
|
+
if (!info.isDirectory()) return info.size;
|
|
36
|
+
const entries = await readdir(path).catch(() => []);
|
|
37
|
+
let total = 0;
|
|
38
|
+
for (const name of entries) total += await size(join(path, name));
|
|
39
|
+
return total;
|
|
40
|
+
}
|
|
41
|
+
/** Removes every run's debug data but the newest `keep`; returns what it removed. */
|
|
42
|
+
async function pruneDebug(root, keep) {
|
|
43
|
+
const runs = await debugRuns(root);
|
|
44
|
+
const removed = runs.slice(0, Math.max(0, runs.length - keep));
|
|
45
|
+
let bytes = 0;
|
|
46
|
+
for (const runId of removed) {
|
|
47
|
+
const dir = join(debugRoot(root), runId);
|
|
48
|
+
bytes += await size(dir);
|
|
49
|
+
await rm(dir, {
|
|
50
|
+
recursive: true,
|
|
51
|
+
force: true
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
runs: removed,
|
|
56
|
+
bytes
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { pruneDebug as a, parseAttemptKey as i, debugRoot as n, debugRuns as r, attemptDebugDir as t };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=files-BLlrhU4-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-BLlrhU4-.js","names":[],"sources":["../src/debug/files.ts"],"mappings":";;;;;;AAKA,MAAa,aAAa,SAAiB,KAAK,MAAM,WAAW,OAAO;;AAGxE,MAAa,mBACX,MACA,OACA,QACA,SACA,MACG,KAAK,UAAU,IAAI,GAAG,OAAO,SAAS,MAAM,GAAG,SAAS,OAAO,GAAG,OAAO,CAAC,CAAC;;AAGhF,SAAgB,gBAAgB,KAAiE;CAC/F,MAAM,QAAQ,IAAI,YAAY,KAAK;CACnC,IAAI,QAAQ,GAAG,OAAO;CACtB,MAAM,UAAU,IAAI,MAAM,QAAQ,CAAC;CACnC,MAAM,OAAO,QAAQ,YAAY,GAAG;CACpC,MAAM,IAAI,OAAO,QAAQ,MAAM,OAAO,CAAC,CAAC;CACxC,IAAI,OAAO,KAAK,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GAAG,OAAO;CACtD,OAAO;EAAE,QAAQ,IAAI,MAAM,GAAG,KAAK;EAAG,MAAM,QAAQ,MAAM,GAAG,IAAI;EAAG;CAAE;AACxE;;AAGA,eAAsB,UAAU,MAAiC;CAC/D,IAAI;EACF,QAAQ,MAAM,QAAQ,UAAU,IAAI,CAAC,EAAA,CAAG,QAAQ,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK;CACnF,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,eAAe,KAAK,MAA+B;CACjD,MAAM,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,YAAY,IAAI;CAC9C,IAAI,CAAC,MAAM,OAAO;CAClB,IAAI,CAAC,KAAK,YAAY,GAAG,OAAO,KAAK;CACrC,MAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC;CAClD,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,SAAS,SAAS,MAAM,KAAK,KAAK,MAAM,IAAI,CAAC;CAChE,OAAO;AACT;;AAGA,eAAsB,WACpB,MACA,MAC4C;CAC5C,MAAM,OAAO,MAAM,UAAU,IAAI;CACjC,MAAM,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC;CAC7D,IAAI,QAAQ;CACZ,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;EACvC,SAAS,MAAM,KAAK,GAAG;EACvB,MAAM,GAAG,KAAK;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;CAChD;CACA,OAAO;EAAE,MAAM;EAAS;CAAM;AAChC"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { r as countSecrets } from "./redact-C4fL_bZP.js";
|
|
2
|
+
import { t as BUILD_ID } from "./root-CFDjpWuc.js";
|
|
3
|
+
import { t as RUN_ID } from "./paths-CBvm6pap.js";
|
|
4
|
+
import { a as fromCwd, c as relativeFile, l as sha256 } from "./ids-Bp6ut7ZD.js";
|
|
5
|
+
import { t as runHeader } from "./header-DzFDoMCI.js";
|
|
6
|
+
import { o as readableRecord, t as NewerSchemaError } from "./record-DQ8wzyco.js";
|
|
7
|
+
import { a as renderSummary } from "./summary-D7Ttky0z.js";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { randomBytes } from "node:crypto";
|
|
10
|
+
import { link, mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
11
|
+
//#region src/history/files.ts
|
|
12
|
+
var HistoryError = class extends Error {
|
|
13
|
+
name = "HistoryError";
|
|
14
|
+
};
|
|
15
|
+
/** A record from a newer reeval: skipped with a warning to upgrade, never "restore or delete it". */
|
|
16
|
+
var NewerRecordError = class extends HistoryError {
|
|
17
|
+
reason;
|
|
18
|
+
constructor(error) {
|
|
19
|
+
super(error.message);
|
|
20
|
+
this.reason = error.reason;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/** Where `reeval run` writes runs before they're recorded. Gitignored. */
|
|
24
|
+
const scratchDir = (root) => join(root, ".reeval", "runs");
|
|
25
|
+
const cacheFile = (root) => join(root, ".reeval", "history-cache.json");
|
|
26
|
+
const TEXT_FILE = /\.(json|jsonl|md|patch|log|txt)$/;
|
|
27
|
+
const isMissing = (error) => error.code === "ENOENT";
|
|
28
|
+
/**
|
|
29
|
+
* A file another process is writing, renaming or removing right now: Windows refuses to open or
|
|
30
|
+
* replace one that's open elsewhere (EPERM, EBUSY). It reads fine on a later try.
|
|
31
|
+
*/
|
|
32
|
+
const inFlux = (error) => [
|
|
33
|
+
"ENOENT",
|
|
34
|
+
"EPERM",
|
|
35
|
+
"EBUSY"
|
|
36
|
+
].includes(error.code ?? "");
|
|
37
|
+
const tmpName = () => `${process.pid}-${randomBytes(6).toString("hex")}`;
|
|
38
|
+
const encodeRecord = (record) => Buffer.from(`${JSON.stringify(record, null, 2)}\n`);
|
|
39
|
+
function parseRecord(bytes, where) {
|
|
40
|
+
const value = JSON.parse(Buffer.from(bytes).toString("utf8"));
|
|
41
|
+
if (value?.kind !== "es-run") throw new HistoryError(`${where} is not a reeval run record`);
|
|
42
|
+
try {
|
|
43
|
+
return readableRecord(value, where);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (error instanceof NewerSchemaError) throw new NewerRecordError(error);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function readRecord(path) {
|
|
50
|
+
return parseRecord(await readFile(path), path);
|
|
51
|
+
}
|
|
52
|
+
const warnedUnreadable = /* @__PURE__ */ new Set();
|
|
53
|
+
/**
|
|
54
|
+
* Says once per process that a run-named file isn't a readable record, so a run lost to a bad
|
|
55
|
+
* merge or a cut-short copy doesn't silently drop out of history, compare's base and queries.
|
|
56
|
+
*/
|
|
57
|
+
function warnUnreadable(path, error) {
|
|
58
|
+
if (warnedUnreadable.has(path)) return;
|
|
59
|
+
warnedUnreadable.add(path);
|
|
60
|
+
if (error instanceof NewerRecordError) {
|
|
61
|
+
process.stderr.write(`warning: skipped ${fromCwd(path)}: ${error.reason}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const why = error instanceof Error ? error.message : String(error);
|
|
65
|
+
process.stderr.write(`warning: skipped ${fromCwd(path)}: not a readable reeval run record (${why}). Restore it from git, or delete it.\n`);
|
|
66
|
+
}
|
|
67
|
+
/** A run's record file in a history or scratch folder. */
|
|
68
|
+
const recordFile = (dir, runId) => join(dir, `${runId}.json`);
|
|
69
|
+
/** A run's artifact directory in a history or scratch folder. */
|
|
70
|
+
const runDir = (dir, runId) => join(dir, runId);
|
|
71
|
+
/** The top-level `.json` names in `dir` (records land last and whole), sorted; null if it's missing. */
|
|
72
|
+
async function recordNames(dir) {
|
|
73
|
+
try {
|
|
74
|
+
return (await readdir(dir)).filter((n) => n.endsWith(".json") && !n.startsWith(".")).sort();
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (isMissing(error)) return null;
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The newest `limit` records across `dirs`, by file name (= start time), oldest first. Files that
|
|
82
|
+
* aren't readable records are skipped: these feed estimates, not results.
|
|
83
|
+
*/
|
|
84
|
+
async function recentRecords(dirs, limit) {
|
|
85
|
+
const paths = [];
|
|
86
|
+
for (const dir of dirs) {
|
|
87
|
+
const names = await recordNames(dir).catch(() => null) ?? [];
|
|
88
|
+
paths.push(...names.map((n) => join(dir, n)));
|
|
89
|
+
}
|
|
90
|
+
const recent = paths.sort((a, b) => (a.split("/").at(-1) ?? "").localeCompare(b.split("/").at(-1) ?? "")).slice(-limit);
|
|
91
|
+
const records = [];
|
|
92
|
+
for (const path of recent) try {
|
|
93
|
+
records.push(await readRecord(path));
|
|
94
|
+
} catch {}
|
|
95
|
+
return records;
|
|
96
|
+
}
|
|
97
|
+
const BUILD = BUILD_ID;
|
|
98
|
+
async function readCache(root) {
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(await readFile(cacheFile(root), "utf8"));
|
|
101
|
+
if (parsed.build === BUILD && parsed.files) return parsed;
|
|
102
|
+
} catch {}
|
|
103
|
+
return {
|
|
104
|
+
build: BUILD,
|
|
105
|
+
files: {}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Every run in `dir`, sorted by file name (= start time). Derived from the folder listing on
|
|
110
|
+
* every read; parsed records are cached in `.reeval/` by size and mtime, and never committed.
|
|
111
|
+
*/
|
|
112
|
+
async function listRuns(root, dir, recorded) {
|
|
113
|
+
const names = (await recordNames(dir) ?? []).filter((n) => RUN_ID.test(n.slice(0, -5)));
|
|
114
|
+
if (names.length === 0) return [];
|
|
115
|
+
const cache = await readCache(root);
|
|
116
|
+
let changed = false;
|
|
117
|
+
const entries = [];
|
|
118
|
+
for (const name of names) {
|
|
119
|
+
const path = join(dir, name);
|
|
120
|
+
const key = relativeFile(root, path);
|
|
121
|
+
try {
|
|
122
|
+
const info = await stat(path);
|
|
123
|
+
const hit = cache.files[key];
|
|
124
|
+
if (hit && hit.size === info.size && hit.mtimeMs === info.mtimeMs) {
|
|
125
|
+
entries.push(hit.entry);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const entry = runHeader(await readRecord(path), recorded);
|
|
129
|
+
cache.files[key] = {
|
|
130
|
+
size: info.size,
|
|
131
|
+
mtimeMs: info.mtimeMs,
|
|
132
|
+
entry
|
|
133
|
+
};
|
|
134
|
+
entries.push(entry);
|
|
135
|
+
changed = true;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (inFlux(error)) continue;
|
|
138
|
+
if (!(error instanceof HistoryError) && !(error instanceof SyntaxError)) throw error;
|
|
139
|
+
warnUnreadable(path, error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (changed) await writeCache(root, cache);
|
|
143
|
+
return entries;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Best-effort: another reader (a studio serving parallel requests, a second `es`) may be
|
|
147
|
+
* replacing the same file, which Windows refuses. The cache is only a speed-up.
|
|
148
|
+
*/
|
|
149
|
+
async function writeCache(root, cache) {
|
|
150
|
+
const tmp = `${cacheFile(root)}.${tmpName()}`;
|
|
151
|
+
try {
|
|
152
|
+
await mkdir(dirname(cacheFile(root)), { recursive: true });
|
|
153
|
+
await writeFile(tmp, JSON.stringify(cache));
|
|
154
|
+
await rename(tmp, cacheFile(root));
|
|
155
|
+
} catch {
|
|
156
|
+
await rm(tmp, { force: true }).catch(() => {});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Writes `<dir>/<runId>/` (artifacts), then `<dir>/<runId>.json` (the record). The record lands
|
|
161
|
+
* last and create-only, so a reader never sees a half-written run, and a run is never rewritten.
|
|
162
|
+
*/
|
|
163
|
+
async function writeRun(dir, record, artifacts) {
|
|
164
|
+
const recordPath = join(dir, `${record.runId}.json`);
|
|
165
|
+
const artifactDir = artifacts.size > 0 ? join(dir, record.runId) : null;
|
|
166
|
+
const bytes = encodeRecord(record);
|
|
167
|
+
let existing = null;
|
|
168
|
+
try {
|
|
169
|
+
existing = await readFile(recordPath);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (!isMissing(error)) throw error;
|
|
172
|
+
}
|
|
173
|
+
if (existing) {
|
|
174
|
+
if (existing.equals(bytes)) return {
|
|
175
|
+
recordPath,
|
|
176
|
+
artifactDir,
|
|
177
|
+
created: false
|
|
178
|
+
};
|
|
179
|
+
throw new HistoryError(`${record.runId} is already recorded with different content (another --artifacts level?). Recorded runs are never rewritten.`);
|
|
180
|
+
}
|
|
181
|
+
await mkdir(dir, { recursive: true });
|
|
182
|
+
await rm(join(dir, record.runId), {
|
|
183
|
+
recursive: true,
|
|
184
|
+
force: true
|
|
185
|
+
});
|
|
186
|
+
if (artifactDir) {
|
|
187
|
+
const staging = join(dir, `.tmp-${tmpName()}`);
|
|
188
|
+
try {
|
|
189
|
+
for (const [path, content] of artifacts) {
|
|
190
|
+
const file = join(staging, ...path.split("/"));
|
|
191
|
+
await mkdir(dirname(file), { recursive: true });
|
|
192
|
+
await writeFile(file, content);
|
|
193
|
+
}
|
|
194
|
+
await rename(staging, artifactDir);
|
|
195
|
+
} finally {
|
|
196
|
+
await rm(staging, {
|
|
197
|
+
recursive: true,
|
|
198
|
+
force: true
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const tmp = join(dir, `.tmp-${tmpName()}.json`);
|
|
203
|
+
await writeFile(tmp, bytes);
|
|
204
|
+
try {
|
|
205
|
+
await link(tmp, recordPath);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (error.code === "EEXIST") throw new HistoryError(`${recordPath} was written by another process meanwhile`);
|
|
208
|
+
throw error;
|
|
209
|
+
} finally {
|
|
210
|
+
await unlink(tmp).catch(() => {});
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
recordPath,
|
|
214
|
+
artifactDir,
|
|
215
|
+
created: true
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const keeps = (e, level) => level === "all" || level === "failures" && (e.outcome === "fail" || e.outcome === "infra_error");
|
|
219
|
+
const refsOf = (e) => e.attempts.flatMap((a) => [...Object.values(a.files), ...a.checks.flatMap((c) => c.log ? [c.log] : [])]);
|
|
220
|
+
/** Promotes a scratch run into the committed history folder. reeval never commits it. */
|
|
221
|
+
async function recordRun(options) {
|
|
222
|
+
const { runId, artifacts: level } = options;
|
|
223
|
+
const source = scratchDir(options.root);
|
|
224
|
+
let scratch;
|
|
225
|
+
try {
|
|
226
|
+
scratch = await readRecord(join(source, `${runId}.json`));
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (isMissing(error)) throw new HistoryError(`No run ${runId} in .reeval/runs`);
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
if (scratch.status !== "complete" && !options.allowIncomplete) throw new HistoryError(`Run ${runId} was ${scratch.status}; pass --allow-incomplete to record it`);
|
|
232
|
+
const record = structuredClone(scratch);
|
|
233
|
+
record.artifacts = level;
|
|
234
|
+
const files = /* @__PURE__ */ new Map();
|
|
235
|
+
for (const e of record.evals) {
|
|
236
|
+
if (level !== "none" && keeps(e, level)) {
|
|
237
|
+
for (const ref of refsOf(e)) {
|
|
238
|
+
const bytes = await readFile(join(source, runId, ...ref.path.split("/")));
|
|
239
|
+
if (sha256(bytes) !== ref.sha256) throw new HistoryError(`${runId}/${ref.path} changed since the run wrote it`);
|
|
240
|
+
files.set(ref.path, bytes);
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
for (const a of e.attempts) {
|
|
245
|
+
a.files = {};
|
|
246
|
+
for (const c of a.checks) delete c.log;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const patch = record.git?.worktreePatch;
|
|
250
|
+
if (patch && level !== "none") {
|
|
251
|
+
const bytes = await readFile(join(source, runId, patch.path));
|
|
252
|
+
if (sha256(bytes) !== patch.sha256) throw new HistoryError(`${runId}/${patch.path} changed since the run wrote it`);
|
|
253
|
+
files.set(patch.path, bytes);
|
|
254
|
+
} else if (patch && record.git) {
|
|
255
|
+
record.git.worktreePatch = null;
|
|
256
|
+
record.git.worktreePatchNote = "not kept: recorded with artifacts 'none'";
|
|
257
|
+
}
|
|
258
|
+
if (level !== "none") files.set("summary.md", Buffer.from(renderSummary(record)));
|
|
259
|
+
if (!options.skipSecretScan) {
|
|
260
|
+
const flagged = [...files].filter(([path, bytes]) => TEXT_FILE.test(path) && countSecrets(Buffer.from(bytes).toString()) > 0).map(([path]) => `${runId}/${path}`);
|
|
261
|
+
if (countSecrets(encodeRecord(record).toString()) > 0) flagged.unshift(`${runId}.json`);
|
|
262
|
+
if (flagged.length > 0) throw new HistoryError(`Refusing to record ${runId}: ${flagged.length} file(s) look like they contain a secret:\n${flagged.map((p) => ` ${p}`).join("\n")}\nCheck them, then pass --skip-secret-scan if these are false positives.`);
|
|
263
|
+
}
|
|
264
|
+
const written = await writeRun(options.historyDir, record, files);
|
|
265
|
+
const bytes = [...files.values()].reduce((n, b) => n + b.length, encodeRecord(record).length);
|
|
266
|
+
return {
|
|
267
|
+
...written,
|
|
268
|
+
files: files.size,
|
|
269
|
+
bytes
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
273
|
+
export { parseRecord as a, recordFile as c, runDir as d, scratchDir as f, listRuns as i, recordNames as l, writeRun as m, NewerRecordError as n, readRecord as o, warnUnreadable as p, encodeRecord as r, recentRecords as s, HistoryError as t, recordRun as u };
|
|
274
|
+
|
|
275
|
+
//# sourceMappingURL=files-D2-qn_Dl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-D2-qn_Dl.js","names":[],"sources":["../src/history/files.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { r as countSecrets } from "./redact-C4fL_bZP.js";
|
|
2
|
+
import { a as fromCwd } from "./ids-Bp6ut7ZD.js";
|
|
3
|
+
import { r as readableAnalysis, t as NewerSchemaError } from "./record-DQ8wzyco.js";
|
|
4
|
+
import { d as runDir, t as HistoryError } from "./files-D2-qn_Dl.js";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { mkdir, readFile, readdir, rename, writeFile } from "node:fs/promises";
|
|
7
|
+
//#region src/analysis/files.ts
|
|
8
|
+
const analysisCacheDir = (root) => join(root, ".reeval", "analysis");
|
|
9
|
+
const savedAnalysisDir = (historyDir, runId) => join(runDir(historyDir, runId), "analysis");
|
|
10
|
+
const warned = /* @__PURE__ */ new Set();
|
|
11
|
+
/** An analysis file as this reeval reads it; null if it isn't one, or (with a warning) is newer. */
|
|
12
|
+
const parse = (text, file) => {
|
|
13
|
+
try {
|
|
14
|
+
const doc = JSON.parse(text);
|
|
15
|
+
return doc?.kind === "es-analysis" ? readableAnalysis(doc, file) : null;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
if (error instanceof NewerSchemaError && !warned.has(file)) {
|
|
18
|
+
warned.add(file);
|
|
19
|
+
process.stderr.write(`warning: skipped ${fromCwd(file)}: ${error.reason}\n`);
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
async function readCached(root, key) {
|
|
25
|
+
const file = join(analysisCacheDir(root), `${key}.json`);
|
|
26
|
+
const text = await readFile(file, "utf8").catch(() => null);
|
|
27
|
+
return text === null ? null : parse(text, file);
|
|
28
|
+
}
|
|
29
|
+
async function writeCached(root, key, doc) {
|
|
30
|
+
const dir = analysisCacheDir(root);
|
|
31
|
+
await mkdir(dir, { recursive: true });
|
|
32
|
+
const path = join(dir, `${key}.json`);
|
|
33
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
34
|
+
await writeFile(tmp, `${JSON.stringify(doc, null, 2)}\n`);
|
|
35
|
+
await rename(tmp, path);
|
|
36
|
+
return path;
|
|
37
|
+
}
|
|
38
|
+
const slug = (s) => s.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "unknown";
|
|
39
|
+
/** `20260926T104633Z`: the UTC second the analysis was made. */
|
|
40
|
+
const stamp = (iso) => iso.replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z");
|
|
41
|
+
/**
|
|
42
|
+
* Writes the saved pair under the run's `analysis/` folder, create-only. Refuses (and writes
|
|
43
|
+
* nothing) when either file exists or when the text looks like it holds a secret.
|
|
44
|
+
*/
|
|
45
|
+
async function saveAnalysis(historyDir, doc, key, markdown) {
|
|
46
|
+
const json = `${JSON.stringify(doc, null, 2)}\n`;
|
|
47
|
+
if (countSecrets(json) > 0 || countSecrets(markdown) > 0) throw new HistoryError("Refusing to save the analysis: it looks like it contains a secret. Check it with reeval analyze --json.");
|
|
48
|
+
const dir = savedAnalysisDir(historyDir, doc.anchor);
|
|
49
|
+
await mkdir(dir, { recursive: true });
|
|
50
|
+
const name = `${stamp(doc.createdAt)}_${slug(doc.author)}_${key.slice(0, 8)}`;
|
|
51
|
+
const paths = [join(dir, `${name}.json`), join(dir, `${name}.md`)];
|
|
52
|
+
const written = [];
|
|
53
|
+
try {
|
|
54
|
+
await writeFile(paths[0], json, { flag: "wx" });
|
|
55
|
+
written.push(paths[0]);
|
|
56
|
+
await writeFile(paths[1], markdown, { flag: "wx" });
|
|
57
|
+
written.push(paths[1]);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error.code === "EEXIST") throw new HistoryError(`${name} is already saved for ${doc.anchor}. Saved analyses are never rewritten.`);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
return written;
|
|
63
|
+
}
|
|
64
|
+
/** Saved analyses of a run (newest first by name), and cached ones anchored on it when asked. */
|
|
65
|
+
async function listAnalyses(root, historyDirs, runId, withCache) {
|
|
66
|
+
const entries = [];
|
|
67
|
+
for (const dir of historyDirs) {
|
|
68
|
+
const folder = savedAnalysisDir(dir, runId);
|
|
69
|
+
const names = (await readdir(folder).catch(() => [])).filter((n) => n.endsWith(".json"));
|
|
70
|
+
for (const name of names.sort().reverse()) {
|
|
71
|
+
const file = join(folder, name);
|
|
72
|
+
const doc = parse(await readFile(file, "utf8").catch(() => ""), file);
|
|
73
|
+
if (doc) entries.push({
|
|
74
|
+
file: `analysis/${name}`,
|
|
75
|
+
source: "saved",
|
|
76
|
+
doc
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (entries.length) break;
|
|
80
|
+
}
|
|
81
|
+
if (withCache) {
|
|
82
|
+
const cache = analysisCacheDir(root);
|
|
83
|
+
for (const name of await readdir(cache).catch(() => [])) {
|
|
84
|
+
if (!name.endsWith(".json")) continue;
|
|
85
|
+
const file = join(cache, name);
|
|
86
|
+
const doc = parse(await readFile(file, "utf8").catch(() => ""), file);
|
|
87
|
+
if (doc?.anchor === runId) entries.push({
|
|
88
|
+
file: `.reeval/analysis/${name}`,
|
|
89
|
+
source: "cached",
|
|
90
|
+
doc
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return entries;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { savedAnalysisDir as a, saveAnalysis as i, listAnalyses as n, writeCached as o, readCached as r, analysisCacheDir as t };
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=files-bF2fPuT9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-bF2fPuT9.js","names":[],"sources":["../src/analysis/files.ts"],"mappings":"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"}
|