loki-mode 11.3.5 → 11.3.6
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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/FAILURE-CLASSES.md +18 -0
- package/docs/v10/GUARDS.md +7 -0
- package/loki-ts/dist/loki.js +667 -667
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +241 -179
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-CtMDQ7tq.js → AdminPage-DQmOVG7S.js} +1 -1
- package/web-app/dist/assets/{Avatar-BunEd-95.js → Avatar-CgA1W2hU.js} +1 -1
- package/web-app/dist/assets/{Badge-BrAChY_L.js → Badge-BHu-Aw77.js} +1 -1
- package/web-app/dist/assets/{Button-CUGJz-QD.js → Button-Dd5PTsTA.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-mS3B6nCY.js → CockpitPage-BqZAu2dx.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DOpjq2wB.js → ComparePage-BoLiFsH-.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-BPVaV2s1.js → ErrorBoundary-D5LPwwqH.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-B1o2RKnU.js → EvidenceReceiptPanel-_Cnzqiz3.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-07-Gi_tj.js → GitHubIssuesPanel-DP7RgZIj.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-DwpdHdD0.js → GitHubPRsPanel-B7G7f1ME.js} +1 -1
- package/web-app/dist/assets/{HomePage-5SYxWllM.js → HomePage-BtTxigAS.js} +2 -2
- package/web-app/dist/assets/{LoginPage-DxKw4woS.js → LoginPage-BN8rKw8b.js} +1 -1
- package/web-app/dist/assets/{MagicPage-Cs1wKf5C.js → MagicPage-CZHgAX_d.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DViQGz-y.js → MetricsPage-BGeztBOD.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-DZ1rQcEH.js → NotFoundPage-llhb5dZD.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-qjTYnrCe.js → ProjectPage-8eDk19Hz.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-CrJzeJzg.js → ProjectsPage-CGYuJP1i.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-DfWrefQZ.js → SettingsPage-UT4j3Hi8.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-DBPrEBK-.js → ShowcasePage-BYj3La6L.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-CN-27Yul.js → SystemSettingsPage-Dp5zvB-G.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-vXKC7Ctc.js → TeamsPage-DUK-Q4wW.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-BvC4ftFD.js → TemplatesPage-CB-bJpPc.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-pst4yhsm.js → TerminalOutput-BQs_SwaV.js} +1 -1
- package/web-app/dist/assets/{activity-B9Qo_kJN.js → activity-BgC_Ois0.js} +1 -1
- package/web-app/dist/assets/{bell-yXv87YzA.js → bell-CQM4oxzr.js} +1 -1
- package/web-app/dist/assets/{bot-UQlOwPgx.js → bot-BbnmKWvH.js} +1 -1
- package/web-app/dist/assets/{check-DYle8PJT.js → check-C7rK0fPm.js} +1 -1
- package/web-app/dist/assets/{chevron-left-BKGmCkxA.js → chevron-left-BcfKpSjM.js} +1 -1
- package/web-app/dist/assets/{circle-alert-Dc1XUGH3.js → circle-alert-Bz0gNsvI.js} +1 -1
- package/web-app/dist/assets/{clock-B0jfhwc2.js → clock-D62JPqIM.js} +1 -1
- package/web-app/dist/assets/{cloud-IkyAY6Dw.js → cloud-DqUjmEip.js} +1 -1
- package/web-app/dist/assets/{code-xml-CPdTgKr9.js → code-xml-BOfhXcsB.js} +1 -1
- package/web-app/dist/assets/{database-E6L0Lwuc.js → database-BtUHezwg.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-alo3vpLg.js → dollar-sign-YuKPD0TX.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DcstcagN.js → file-code-corner-lM78R7wx.js} +1 -1
- package/web-app/dist/assets/{file-plus-DYrxUtNS.js → file-plus-k9jtMlVw.js} +1 -1
- package/web-app/dist/assets/{globe-D0ceSi6L.js → globe-BotkF9Lb.js} +1 -1
- package/web-app/dist/assets/{hammer-Bix0hGg_.js → hammer-BbctxPnE.js} +1 -1
- package/web-app/dist/assets/{index-Bq0IXorg.js → index-CQ_LSpnv.js} +3 -3
- package/web-app/dist/assets/{layers-ClEOJz-A.js → layers-DHh4VJfQ.js} +1 -1
- package/web-app/dist/assets/{loader-circle-aPR8MCfq.js → loader-circle-BAb1cEw6.js} +1 -1
- package/web-app/dist/assets/{lock-qWtNggvV.js → lock-DrdR04VZ.js} +1 -1
- package/web-app/dist/assets/{package-Cf9OA6-r.js → package-BoJAHt7a.js} +1 -1
- package/web-app/dist/assets/{plus-BFwUepQN.js → plus-CI6B0_tm.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DzmKZ3CW.js → refresh-cw-BqmrZLg2.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-DZMAdo4p.js → rotate-ccw-DUZOTZYh.js} +1 -1
- package/web-app/dist/assets/{scroll-text-CLK1QhL-.js → scroll-text-CNtbRU1G.js} +1 -1
- package/web-app/dist/assets/{server-D2hE3MdR.js → server-DyPZO72X.js} +1 -1
- package/web-app/dist/assets/{shield-alert-aK0eddg8.js → shield-alert-DrhFa6cZ.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-B_jbqHDP.js → thumbs-up-DNgUkbHP.js} +1 -1
- package/web-app/dist/assets/{trash-2-Dgo9A169.js → trash-2-DGTZpPKg.js} +1 -1
- package/web-app/dist/assets/{trending-down-DeRHmNFR.js → trending-down-5zMgMOQa.js} +1 -1
- package/web-app/dist/assets/{trending-up-BxPu0OUd.js → trending-up-Dk5fQQzd.js} +1 -1
- package/web-app/dist/assets/{upload-DaaWxRxF.js → upload-BxVLazyr.js} +1 -1
- package/web-app/dist/assets/{usePolling-QplcA_Qc.js → usePolling-B6ukuagG.js} +1 -1
- package/web-app/dist/assets/{user-B9a_CFg0.js → user-BAuQUINc.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -7608,12 +7608,73 @@ var init_pr_body = __esm(() => {
|
|
|
7608
7608
|
init_seal_group();
|
|
7609
7609
|
});
|
|
7610
7610
|
|
|
7611
|
+
// ../../loki-ts/src/util/credential_env.ts
|
|
7612
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, statSync as statSync12, lstatSync as lstatSync4 } from "fs";
|
|
7613
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
7614
|
+
import { join as join28 } from "path";
|
|
7615
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
7616
|
+
function withheldSentinel(fresh = false) {
|
|
7617
|
+
if (fresh)
|
|
7618
|
+
sentinel = null;
|
|
7619
|
+
return sentinel ??= `${SENTINEL_PREFIX}${process.pid}${randomBytes2(8).toString("hex")}INVALID`;
|
|
7620
|
+
}
|
|
7621
|
+
function emptyGhConfigDir(env = process.env) {
|
|
7622
|
+
if (configDir && isDir(configDir))
|
|
7623
|
+
return configDir;
|
|
7624
|
+
const runTmp = env["LOKI_RUN_TMP"] ?? "";
|
|
7625
|
+
const root = runTmp !== "" && isDir(runTmp) ? runTmp : tmpdir3();
|
|
7626
|
+
try {
|
|
7627
|
+
configDir = mkdtempSync2(join28(root, "loki-gh-config-"));
|
|
7628
|
+
} catch {
|
|
7629
|
+
return null;
|
|
7630
|
+
}
|
|
7631
|
+
if (!exitHooked) {
|
|
7632
|
+
exitHooked = true;
|
|
7633
|
+
process.once("exit", () => {
|
|
7634
|
+
if (configDir)
|
|
7635
|
+
try {
|
|
7636
|
+
rmSync4(configDir, { recursive: true, force: true });
|
|
7637
|
+
} catch {}
|
|
7638
|
+
});
|
|
7639
|
+
}
|
|
7640
|
+
return configDir;
|
|
7641
|
+
}
|
|
7642
|
+
function hardenCredentialEnv(env, fresh = false) {
|
|
7643
|
+
const s = withheldSentinel(fresh);
|
|
7644
|
+
for (const v of GITHUB_TOKEN_VARS)
|
|
7645
|
+
env[v] = s;
|
|
7646
|
+
const dir = emptyGhConfigDir(env);
|
|
7647
|
+
if (dir)
|
|
7648
|
+
env["GH_CONFIG_DIR"] = dir;
|
|
7649
|
+
const existing = Number(env["GIT_CONFIG_COUNT"]);
|
|
7650
|
+
const n2 = Number.isInteger(existing) && existing >= 0 ? existing : 0;
|
|
7651
|
+
const alreadyLast = n2 > 0 && env[`GIT_CONFIG_KEY_${n2 - 1}`] === "credential.helper" && env[`GIT_CONFIG_VALUE_${n2 - 1}`] === "";
|
|
7652
|
+
if (!alreadyLast) {
|
|
7653
|
+
env[`GIT_CONFIG_KEY_${n2}`] = "credential.helper";
|
|
7654
|
+
env[`GIT_CONFIG_VALUE_${n2}`] = "";
|
|
7655
|
+
env["GIT_CONFIG_COUNT"] = String(n2 + 1);
|
|
7656
|
+
}
|
|
7657
|
+
env["GIT_TERMINAL_PROMPT"] = "0";
|
|
7658
|
+
env["GCM_INTERACTIVE"] = "never";
|
|
7659
|
+
}
|
|
7660
|
+
var GITHUB_TOKEN_VARS, SENTINEL_PREFIX = "ghp_LOKIWITHHELDsentinel", sentinel = null, configDir = null, exitHooked = false, isDir = (p) => {
|
|
7661
|
+
try {
|
|
7662
|
+
return !lstatSync4(p).isSymbolicLink() && statSync12(p).isDirectory();
|
|
7663
|
+
} catch {
|
|
7664
|
+
return false;
|
|
7665
|
+
}
|
|
7666
|
+
};
|
|
7667
|
+
var init_credential_env = __esm(() => {
|
|
7668
|
+
GITHUB_TOKEN_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN"];
|
|
7669
|
+
});
|
|
7670
|
+
|
|
7611
7671
|
// ../../loki-ts/src/util/safe_git.ts
|
|
7612
7672
|
import { execFileSync as execFileSync4, spawnSync } from "child_process";
|
|
7613
7673
|
function tokenFreeEnv(env = process.env) {
|
|
7614
7674
|
const out2 = { ...env };
|
|
7615
7675
|
for (const k of SECRET_VARS)
|
|
7616
7676
|
delete out2[k];
|
|
7677
|
+
hardenCredentialEnv(out2);
|
|
7617
7678
|
return out2;
|
|
7618
7679
|
}
|
|
7619
7680
|
function driverKeys(repoDir) {
|
|
@@ -7703,6 +7764,7 @@ var SAFE_GIT_CONFIG, CREDENTIAL_CONFIG, DRIVER_CONFIG, ATTRS_OFF = "core.attribu
|
|
|
7703
7764
|
return env;
|
|
7704
7765
|
};
|
|
7705
7766
|
var init_safe_git = __esm(() => {
|
|
7767
|
+
init_credential_env();
|
|
7706
7768
|
SAFE_GIT_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "core.sshCommand=", "-c", "protocol.ext.allow=never", "-c", "credential.helper="];
|
|
7707
7769
|
CREDENTIAL_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "protocol.ext.allow=never"];
|
|
7708
7770
|
DRIVER_CONFIG = ["-c", "diff.external=", "-c", "commit.gpgSign=false", "-c", "core.attributesFile=/dev/null"];
|
|
@@ -7719,9 +7781,9 @@ var init_run_cap = __esm(() => {
|
|
|
7719
7781
|
});
|
|
7720
7782
|
|
|
7721
7783
|
// ../../loki-ts/src/util/mutation_proof.ts
|
|
7722
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync5, mkdtempSync as
|
|
7723
|
-
import { tmpdir as
|
|
7724
|
-
import { basename as basename8, dirname as dirname8, isAbsolute as isAbsolute2, join as
|
|
7784
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync3, readFileSync as readFileSync19, rmSync as rmSync5, symlinkSync, writeFileSync as writeFileSync8 } from "fs";
|
|
7785
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
7786
|
+
import { basename as basename8, dirname as dirname8, isAbsolute as isAbsolute2, join as join29, relative as relative2 } from "path";
|
|
7725
7787
|
function mutationProof(i) {
|
|
7726
7788
|
const rels = i.wallFiles.map((f) => isAbsolute2(f.path) ? relative2(i.repoDir, f.path) : f.path);
|
|
7727
7789
|
if (rels.length === 0)
|
|
@@ -7739,25 +7801,25 @@ function mutationProof(i) {
|
|
|
7739
7801
|
const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
|
|
7740
7802
|
let parent = null, wt = null, added = false;
|
|
7741
7803
|
try {
|
|
7742
|
-
parent =
|
|
7743
|
-
wt =
|
|
7804
|
+
parent = mkdtempSync3(join29(tmpdir4(), "loki-mutproof-"));
|
|
7805
|
+
wt = join29(parent, "wt");
|
|
7744
7806
|
const add2 = git(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
|
|
7745
7807
|
added = existsSync16(wt) || add2.status === 0;
|
|
7746
7808
|
if (add2.status !== 0)
|
|
7747
7809
|
return np("could not create the base worktree");
|
|
7748
7810
|
for (const rel of rels) {
|
|
7749
|
-
const sealed =
|
|
7811
|
+
const sealed = join29(i.runDir, "wall", basename8(rel)), src = existsSync16(sealed) ? sealed : join29(i.repoDir, rel);
|
|
7750
7812
|
if (!existsSync16(src))
|
|
7751
7813
|
return np(`Wall file missing: ${rel}`);
|
|
7752
|
-
mkdirSync5(dirname8(
|
|
7753
|
-
writeFileSync8(
|
|
7814
|
+
mkdirSync5(dirname8(join29(wt, rel)), { recursive: true });
|
|
7815
|
+
writeFileSync8(join29(wt, rel), readFileSync19(src));
|
|
7754
7816
|
}
|
|
7755
7817
|
for (const rel of rels) {
|
|
7756
7818
|
const parts = rel.split("/").slice(0, -1);
|
|
7757
7819
|
for (let n2 = 0;n2 <= parts.length; n2++) {
|
|
7758
7820
|
const anc = parts.slice(0, n2).join("/");
|
|
7759
7821
|
for (const d of DEP_DIRS) {
|
|
7760
|
-
const src =
|
|
7822
|
+
const src = join29(i.repoDir, anc, d), dst = join29(wt, anc, d);
|
|
7761
7823
|
if (existsSync16(src) && !existsSync16(dst)) {
|
|
7762
7824
|
try {
|
|
7763
7825
|
symlinkSync(src, dst);
|
|
@@ -7788,7 +7850,7 @@ function mutationProof(i) {
|
|
|
7788
7850
|
if (wt && added)
|
|
7789
7851
|
git(i.repoDir, ["worktree", "remove", "--force", wt]);
|
|
7790
7852
|
if (parent)
|
|
7791
|
-
|
|
7853
|
+
rmSync5(parent, { recursive: true, force: true });
|
|
7792
7854
|
}
|
|
7793
7855
|
}
|
|
7794
7856
|
var mutationStrict = (env = process.env) => (env["LOKI_MUTATION_STRICT"] ?? "").trim() === "1", mutationEnabled = (env = process.env) => (env["LOKI_MUTATION_PROOF"] ?? "").trim() !== "0", LABEL = "test fails without the fix: ", np = (reason) => ({ outcome: "inconclusive", line: `${LABEL}inconclusive (${reason})` }), MAX_TOTAL_S = 40, DEP_DIRS, git = (cwd, args, timeout = 30000) => {
|
|
@@ -7816,8 +7878,8 @@ var init_lean_prefix = __esm(() => {
|
|
|
7816
7878
|
|
|
7817
7879
|
// ../../loki-ts/src/features/wall_manifest.ts
|
|
7818
7880
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7819
|
-
import { accessSync, constants, statSync as
|
|
7820
|
-
import { tmpdir as
|
|
7881
|
+
import { accessSync, constants, statSync as statSync13 } from "fs";
|
|
7882
|
+
import { tmpdir as tmpdir5 } from "os";
|
|
7821
7883
|
function templateEnd(s, i) {
|
|
7822
7884
|
for (let j = i + 1;j < s.length; ) {
|
|
7823
7885
|
const c = s[j];
|
|
@@ -8550,7 +8612,7 @@ function resolvePython3() {
|
|
|
8550
8612
|
const cand = `${dir}/python3`;
|
|
8551
8613
|
try {
|
|
8552
8614
|
accessSync(cand, constants.X_OK);
|
|
8553
|
-
if (
|
|
8615
|
+
if (statSync13(cand).isFile())
|
|
8554
8616
|
return cand;
|
|
8555
8617
|
} catch {}
|
|
8556
8618
|
}
|
|
@@ -8563,7 +8625,7 @@ function pySignatures(src) {
|
|
|
8563
8625
|
return [];
|
|
8564
8626
|
const r = spawnSync2(py, ["-I", "-S", "-c", PY_SCRIPT], {
|
|
8565
8627
|
input: norm2(src),
|
|
8566
|
-
cwd:
|
|
8628
|
+
cwd: tmpdir5(),
|
|
8567
8629
|
timeout: PY_TIMEOUT_MS,
|
|
8568
8630
|
encoding: "utf8",
|
|
8569
8631
|
env: { PATH: process.env.PATH ?? "/usr/bin:/bin" },
|
|
@@ -9056,7 +9118,7 @@ var init_hooks = __esm(() => {
|
|
|
9056
9118
|
|
|
9057
9119
|
// ../../loki-ts/src/engine10/cost.ts
|
|
9058
9120
|
import { mkdirSync as mkdirSync7, readdirSync as readdirSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync10 } from "fs";
|
|
9059
|
-
import { join as
|
|
9121
|
+
import { join as join30 } from "path";
|
|
9060
9122
|
function routerTelemetryOn(env = process.env) {
|
|
9061
9123
|
return routerEnabled(env);
|
|
9062
9124
|
}
|
|
@@ -9064,7 +9126,7 @@ function num4(v) {
|
|
|
9064
9126
|
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
9065
9127
|
}
|
|
9066
9128
|
function resultCostPath(lokiRoot, iteration) {
|
|
9067
|
-
return
|
|
9129
|
+
return join30(lokiRoot, "metrics", `result-cost-${iteration}.json`);
|
|
9068
9130
|
}
|
|
9069
9131
|
function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
9070
9132
|
const out2 = {
|
|
@@ -9201,7 +9263,7 @@ var init_cost = __esm(() => {
|
|
|
9201
9263
|
|
|
9202
9264
|
// ../../loki-ts/src/runner/budget.ts
|
|
9203
9265
|
import { existsSync as existsSync18, mkdirSync as mkdirSync8, readdirSync as readdirSync11, readFileSync as readFileSync23, renameSync as renameSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
9204
|
-
import { dirname as dirname10, join as
|
|
9266
|
+
import { dirname as dirname10, join as join31, resolve as resolve10 } from "path";
|
|
9205
9267
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9206
9268
|
function _loadPricing() {
|
|
9207
9269
|
try {
|
|
@@ -9358,8 +9420,8 @@ var init_sizing = __esm(() => {
|
|
|
9358
9420
|
});
|
|
9359
9421
|
|
|
9360
9422
|
// ../../loki-ts/src/project_model/schema.ts
|
|
9361
|
-
import { existsSync as existsSync20, lstatSync as
|
|
9362
|
-
import { isAbsolute as isAbsolute3, join as
|
|
9423
|
+
import { existsSync as existsSync20, lstatSync as lstatSync5, realpathSync as realpathSync14, statSync as statSync14 } from "fs";
|
|
9424
|
+
import { isAbsolute as isAbsolute3, join as join33, normalize, sep as sep9 } from "path";
|
|
9363
9425
|
function safeRel(p) {
|
|
9364
9426
|
const n2 = normalize(p.trim()).split(sep9).join("/").replace(/\/$/, "");
|
|
9365
9427
|
if (n2 === "" || isAbsolute3(n2) || n2 === ".." || n2.startsWith("../"))
|
|
@@ -9368,7 +9430,7 @@ function safeRel(p) {
|
|
|
9368
9430
|
}
|
|
9369
9431
|
function insideRepo(repoDir, rel) {
|
|
9370
9432
|
try {
|
|
9371
|
-
const real2 = realpathSync14(
|
|
9433
|
+
const real2 = realpathSync14(join33(repoDir, rel));
|
|
9372
9434
|
const base = realpathSync14(repoDir);
|
|
9373
9435
|
return real2 === base || real2.startsWith(base + sep9);
|
|
9374
9436
|
} catch {
|
|
@@ -9381,8 +9443,8 @@ function checkCitation(repoDir, raw2) {
|
|
|
9381
9443
|
const rel = safeRel(raw2.replace(/:\d+(?:-\d+)?$/, ""));
|
|
9382
9444
|
if (rel === null)
|
|
9383
9445
|
return `citation "${raw2}" is not a repo-relative path`;
|
|
9384
|
-
const abs =
|
|
9385
|
-
if (!existsSync20(abs) || !
|
|
9446
|
+
const abs = join33(repoDir, rel);
|
|
9447
|
+
if (!existsSync20(abs) || !statSync14(abs).isFile() || !insideRepo(repoDir, rel))
|
|
9386
9448
|
return `citation "${raw2}" names a file that does not exist`;
|
|
9387
9449
|
return null;
|
|
9388
9450
|
}
|
|
@@ -9393,7 +9455,7 @@ function checkFingerprint(repoDir, raw2) {
|
|
|
9393
9455
|
if (rel === null)
|
|
9394
9456
|
return `fingerprint "${raw2}" is not a repo-relative path`;
|
|
9395
9457
|
try {
|
|
9396
|
-
if (!
|
|
9458
|
+
if (!lstatSync5(join33(repoDir, rel)).isFile() || !insideRepo(repoDir, rel))
|
|
9397
9459
|
return `fingerprint "${raw2}" is not a regular file inside the repo`;
|
|
9398
9460
|
} catch {
|
|
9399
9461
|
return `fingerprint "${raw2}" names a file that does not exist`;
|
|
@@ -9421,8 +9483,8 @@ function checkDir(repoDir, v, where, errs) {
|
|
|
9421
9483
|
errs.push(`${where}: must be a repo-relative directory ("." for the repo root)`);
|
|
9422
9484
|
return ".";
|
|
9423
9485
|
}
|
|
9424
|
-
const abs =
|
|
9425
|
-
if (!existsSync20(abs) || !
|
|
9486
|
+
const abs = join33(repoDir, rel);
|
|
9487
|
+
if (!existsSync20(abs) || !statSync14(abs).isDirectory() || !insideRepo(repoDir, rel))
|
|
9426
9488
|
errs.push(`${where}: directory "${rel}" does not exist`);
|
|
9427
9489
|
return rel;
|
|
9428
9490
|
}
|
|
@@ -9525,8 +9587,8 @@ var init_schema = __esm(() => {
|
|
|
9525
9587
|
|
|
9526
9588
|
// ../../loki-ts/src/project_model/gather.ts
|
|
9527
9589
|
import { createHash as createHash9 } from "crypto";
|
|
9528
|
-
import { closeSync as closeSync5, lstatSync as
|
|
9529
|
-
import { dirname as dirname11, join as
|
|
9590
|
+
import { closeSync as closeSync5, lstatSync as lstatSync6, openSync as openSync5, readFileSync as readFileSync25, readSync as readSync4 } from "fs";
|
|
9591
|
+
import { dirname as dirname11, join as join34 } from "path";
|
|
9530
9592
|
function listShallow(repoDir) {
|
|
9531
9593
|
try {
|
|
9532
9594
|
const out2 = safeGit(repoDir, ["ls-files", "-z"], { maxBuffer: 256 * 1024 * 1024 });
|
|
@@ -9552,8 +9614,8 @@ function computeKey(repoDir, fingerprintFiles, dirs, committedHash = null) {
|
|
|
9552
9614
|
if (checkFingerprint(repoDir, f) !== null)
|
|
9553
9615
|
h.update("invalid");
|
|
9554
9616
|
else {
|
|
9555
|
-
const abs =
|
|
9556
|
-
const size =
|
|
9617
|
+
const abs = join34(repoDir, f);
|
|
9618
|
+
const size = lstatSync6(abs).size;
|
|
9557
9619
|
h.update(size <= GATHER_CAPS.maxHashBytes ? readFileSync25(abs) : `too-large:${size}`);
|
|
9558
9620
|
}
|
|
9559
9621
|
} catch {
|
|
@@ -9597,14 +9659,14 @@ var init_gather = __esm(() => {
|
|
|
9597
9659
|
});
|
|
9598
9660
|
|
|
9599
9661
|
// ../../loki-ts/src/project_model/discover.ts
|
|
9600
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync26, rmSync as
|
|
9601
|
-
import { join as
|
|
9662
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync26, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
9663
|
+
import { join as join35 } from "path";
|
|
9602
9664
|
function projectModelEnabled(env = process.env) {
|
|
9603
9665
|
return env["LOKI_E10_PROJECT_MODEL"] !== "0";
|
|
9604
9666
|
}
|
|
9605
9667
|
function loadCached(repoDir, now2 = Date.now()) {
|
|
9606
9668
|
try {
|
|
9607
|
-
return parseCached(repoDir, JSON.parse(readFileSync26(
|
|
9669
|
+
return parseCached(repoDir, JSON.parse(readFileSync26(join35(repoDir, PROJECT_FILE), "utf8")), now2);
|
|
9608
9670
|
} catch {
|
|
9609
9671
|
return null;
|
|
9610
9672
|
}
|
|
@@ -9619,7 +9681,7 @@ function loadCommitted(repoDir) {
|
|
|
9619
9681
|
};
|
|
9620
9682
|
let raw2;
|
|
9621
9683
|
try {
|
|
9622
|
-
raw2 = JSON.parse(readFileSync26(
|
|
9684
|
+
raw2 = JSON.parse(readFileSync26(join35(repoDir, PROJECT_FILE), "utf8"));
|
|
9623
9685
|
} catch (e) {
|
|
9624
9686
|
return ignore(`unreadable JSON (${e instanceof Error ? e.message : String(e)})`);
|
|
9625
9687
|
}
|
|
@@ -9692,7 +9754,7 @@ var clean2 = (p) => typeof p === "string" ? posix.normalize(p.replace(/\\/g, "/"
|
|
|
9692
9754
|
var init_api = () => {};
|
|
9693
9755
|
|
|
9694
9756
|
// ../../loki-ts/src/project_model/resolve.ts
|
|
9695
|
-
import { join as
|
|
9757
|
+
import { join as join36 } from "path";
|
|
9696
9758
|
function loadProjectApi(repoDir, env = process.env) {
|
|
9697
9759
|
if (!projectModelEnabled(env))
|
|
9698
9760
|
return null;
|
|
@@ -9714,7 +9776,7 @@ function siteFor(api, repoDir, file) {
|
|
|
9714
9776
|
const rel = api.relativeToRoot(file);
|
|
9715
9777
|
if (!pkg || pkg.root === "." || rel === null)
|
|
9716
9778
|
return null;
|
|
9717
|
-
return { pkg, root: pkg.root, cwd:
|
|
9779
|
+
return { pkg, root: pkg.root, cwd: join36(repoDir, pkg.root), file: rel };
|
|
9718
9780
|
}
|
|
9719
9781
|
function groupByPackage(api, repoDir, files) {
|
|
9720
9782
|
const out2 = new Map;
|
|
@@ -9747,9 +9809,9 @@ var init_scope = __esm(() => {
|
|
|
9747
9809
|
|
|
9748
9810
|
// ../../loki-ts/src/e10ext/assert_delta.ts
|
|
9749
9811
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
9750
|
-
import { mkdtempSync as
|
|
9751
|
-
import { tmpdir as
|
|
9752
|
-
import { join as
|
|
9812
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync27, rmSync as rmSync7 } from "fs";
|
|
9813
|
+
import { tmpdir as tmpdir6 } from "os";
|
|
9814
|
+
import { join as join37 } from "path";
|
|
9753
9815
|
import { basename as basename11 } from "path";
|
|
9754
9816
|
function classifyAssertDelta(inp) {
|
|
9755
9817
|
const f = basename11(inp.path);
|
|
@@ -9759,7 +9821,7 @@ function classifyAssertDelta(inp) {
|
|
|
9759
9821
|
return WEAKENED;
|
|
9760
9822
|
let cwd = "";
|
|
9761
9823
|
try {
|
|
9762
|
-
cwd =
|
|
9824
|
+
cwd = mkdtempSync4(join37(tmpdir6(), "loki-ad-"));
|
|
9763
9825
|
const raw2 = execFileSync5("python3", ["-I", "-c", PY], {
|
|
9764
9826
|
input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
|
|
9765
9827
|
cwd,
|
|
@@ -9782,7 +9844,7 @@ function classifyAssertDelta(inp) {
|
|
|
9782
9844
|
return WEAKENED;
|
|
9783
9845
|
} finally {
|
|
9784
9846
|
if (cwd)
|
|
9785
|
-
|
|
9847
|
+
rmSync7(cwd, { recursive: true, force: true });
|
|
9786
9848
|
}
|
|
9787
9849
|
}
|
|
9788
9850
|
function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, headCounts) {
|
|
@@ -9790,7 +9852,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
|
|
|
9790
9852
|
return null;
|
|
9791
9853
|
try {
|
|
9792
9854
|
const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
|
|
9793
|
-
const head = headRef ? show(headRef) : readFileSync27(
|
|
9855
|
+
const head = headRef ? show(headRef) : readFileSync27(join37(repoDir, path), "utf8");
|
|
9794
9856
|
const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
|
|
9795
9857
|
return r[0]?.kind === "literal-only" ? r.map((e) => `assertion value changed (not shown to be required by the task): ${e.file}:${e.line} ${e.old} -> ${e.new}`) : null;
|
|
9796
9858
|
} catch {
|
|
@@ -10225,12 +10287,12 @@ var init_check_result = __esm(() => {
|
|
|
10225
10287
|
|
|
10226
10288
|
// ../../loki-ts/src/runner/load_owner.ts
|
|
10227
10289
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10228
|
-
import { mkdtempSync as
|
|
10229
|
-
import { tmpdir as
|
|
10230
|
-
import { basename as basename13, extname, join as
|
|
10290
|
+
import { mkdtempSync as mkdtempSync5, realpathSync as realpathSync15, rmSync as rmSync8 } from "fs";
|
|
10291
|
+
import { tmpdir as tmpdir7 } from "os";
|
|
10292
|
+
import { basename as basename13, extname, join as join38 } from "path";
|
|
10231
10293
|
function changedFilesNamed(out2, repoDir, changed) {
|
|
10232
10294
|
return changed.filter((f) => {
|
|
10233
|
-
if (out2.includes(f) || out2.includes(
|
|
10295
|
+
if (out2.includes(f) || out2.includes(join38(repoDir, f)))
|
|
10234
10296
|
return true;
|
|
10235
10297
|
const segs = f.split("/");
|
|
10236
10298
|
if (suffixes(segs, 2).some((x) => x !== f && bounded(out2, x, "(?![\\w-])")))
|
|
@@ -10341,7 +10403,7 @@ async function loadErrorIsHarnessOwned(i) {
|
|
|
10341
10403
|
return false;
|
|
10342
10404
|
if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
|
|
10343
10405
|
return false;
|
|
10344
|
-
const dir =
|
|
10406
|
+
const dir = mkdtempSync5(join38(tmpdir7(), "e10-loadown-"));
|
|
10345
10407
|
const git3 = (args) => {
|
|
10346
10408
|
safeGit(i.repoDir, args, { stdio: "ignore" });
|
|
10347
10409
|
};
|
|
@@ -10355,7 +10417,7 @@ async function loadErrorIsHarnessOwned(i) {
|
|
|
10355
10417
|
try {
|
|
10356
10418
|
git3(["worktree", "remove", "--force", dir]);
|
|
10357
10419
|
} catch {}
|
|
10358
|
-
|
|
10420
|
+
rmSync8(dir, { recursive: true, force: true });
|
|
10359
10421
|
try {
|
|
10360
10422
|
git3(["worktree", "prune"]);
|
|
10361
10423
|
} catch {}
|
|
@@ -10373,7 +10435,7 @@ var init_load_owner = __esm(() => {
|
|
|
10373
10435
|
});
|
|
10374
10436
|
|
|
10375
10437
|
// ../../loki-ts/src/engine10/testmap.ts
|
|
10376
|
-
import { basename as basename14, extname as extname2, join as
|
|
10438
|
+
import { basename as basename14, extname as extname2, join as join39, relative as relative3, sep as sep10 } from "path";
|
|
10377
10439
|
function isTestFile(rel) {
|
|
10378
10440
|
const name = basename14(rel);
|
|
10379
10441
|
return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
|
|
@@ -10403,7 +10465,7 @@ var init_testmap = __esm(() => {
|
|
|
10403
10465
|
});
|
|
10404
10466
|
|
|
10405
10467
|
// ../../loki-ts/src/util/wall_owned.ts
|
|
10406
|
-
import { isAbsolute as isAbsolute4, join as
|
|
10468
|
+
import { isAbsolute as isAbsolute4, join as join40, relative as relative4 } from "path";
|
|
10407
10469
|
function failingLocations(raw2, cwd, repoDir) {
|
|
10408
10470
|
const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
|
|
10409
10471
|
`), files = new Set;
|
|
@@ -10435,7 +10497,7 @@ function failingLocations(raw2, cwd, repoDir) {
|
|
|
10435
10497
|
}
|
|
10436
10498
|
if (errors2 === 0 || located !== errors2)
|
|
10437
10499
|
return null;
|
|
10438
|
-
return [...files].map((f) => relative4(repoDir, isAbsolute4(f) ? f :
|
|
10500
|
+
return [...files].map((f) => relative4(repoDir, isAbsolute4(f) ? f : join40(cwd, f)));
|
|
10439
10501
|
}
|
|
10440
10502
|
function wallOwnedFailure(raw2, cwd, repoDir, wall) {
|
|
10441
10503
|
const locs = failingLocations(raw2, cwd, repoDir);
|
|
@@ -10447,9 +10509,9 @@ var init_wall_owned = __esm(() => {
|
|
|
10447
10509
|
});
|
|
10448
10510
|
|
|
10449
10511
|
// ../../loki-ts/src/engine10/stages/verify.ts
|
|
10450
|
-
import { existsSync as existsSync22, mkdtempSync as
|
|
10451
|
-
import { tmpdir as
|
|
10452
|
-
import { dirname as dirname12, isAbsolute as isAbsolute5, join as
|
|
10512
|
+
import { existsSync as existsSync22, mkdtempSync as mkdtempSync6, realpathSync as realpathSync16, rmSync as rmSync9 } from "fs";
|
|
10513
|
+
import { tmpdir as tmpdir8 } from "os";
|
|
10514
|
+
import { dirname as dirname12, isAbsolute as isAbsolute5, join as join41, relative as relative5 } from "path";
|
|
10453
10515
|
function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
10454
10516
|
const inRepo = (p) => {
|
|
10455
10517
|
try {
|
|
@@ -10460,7 +10522,7 @@ function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
|
10460
10522
|
}
|
|
10461
10523
|
};
|
|
10462
10524
|
const venvEnv = process.env["VIRTUAL_ENV"];
|
|
10463
|
-
const project = [
|
|
10525
|
+
const project = [join41(repoDir, ".venv", "bin", bin), join41(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join41(venvEnv, "bin", bin)] : []].find(existsSync22);
|
|
10464
10526
|
return project ? [project, "project"] : [Bun.which(fallback) ? fallback : lastResort, "system"];
|
|
10465
10527
|
}
|
|
10466
10528
|
function runnerCmd(t, repoDir) {
|
|
@@ -10585,7 +10647,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
10585
10647
|
const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
|
|
10586
10648
|
if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length) || signal.aborted)
|
|
10587
10649
|
return out2;
|
|
10588
|
-
const dir =
|
|
10650
|
+
const dir = mkdtempSync6(join41(tmpdir8(), "e10-base-"));
|
|
10589
10651
|
const git3 = (args) => {
|
|
10590
10652
|
safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
|
|
10591
10653
|
};
|
|
@@ -10612,7 +10674,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
10612
10674
|
try {
|
|
10613
10675
|
git3(["worktree", "remove", "--force", dir]);
|
|
10614
10676
|
} catch {}
|
|
10615
|
-
|
|
10677
|
+
rmSync9(dir, { recursive: true, force: true });
|
|
10616
10678
|
try {
|
|
10617
10679
|
git3(["worktree", "prune"]);
|
|
10618
10680
|
} catch {}
|
|
@@ -10620,7 +10682,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
10620
10682
|
return out2;
|
|
10621
10683
|
}
|
|
10622
10684
|
function isLokiModeRepo(repoDir) {
|
|
10623
|
-
return existsSync22(
|
|
10685
|
+
return existsSync22(join41(repoDir, "scripts", "select-tests.sh"));
|
|
10624
10686
|
}
|
|
10625
10687
|
async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
10626
10688
|
const { api, ...runOpts } = opts;
|
|
@@ -10637,9 +10699,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
10637
10699
|
}
|
|
10638
10700
|
for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
|
|
10639
10701
|
const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
|
|
10640
|
-
if (existsSync22(
|
|
10702
|
+
if (existsSync22(join41(g.cwd, "tsconfig.json")))
|
|
10641
10703
|
await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
|
|
10642
|
-
if (ESLINT_CONFIGS.some((f) => existsSync22(
|
|
10704
|
+
if (ESLINT_CONFIGS.some((f) => existsSync22(join41(g.cwd, f))))
|
|
10643
10705
|
await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
|
|
10644
10706
|
}
|
|
10645
10707
|
}
|
|
@@ -10741,7 +10803,7 @@ var init_verify = __esm(() => {
|
|
|
10741
10803
|
|
|
10742
10804
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
10743
10805
|
import { existsSync as existsSync23, readdirSync as readdirSync12, readFileSync as readFileSync28 } from "fs";
|
|
10744
|
-
import { dirname as dirname13, join as
|
|
10806
|
+
import { dirname as dirname13, join as join42 } from "path";
|
|
10745
10807
|
function parseJsonc(text3) {
|
|
10746
10808
|
let out2 = "", i = 0;
|
|
10747
10809
|
while (i < text3.length) {
|
|
@@ -10776,7 +10838,7 @@ function moduleOf(file, depth = 0) {
|
|
|
10776
10838
|
const ext = typeof j.extends === "string" ? j.extends : null;
|
|
10777
10839
|
if (!ext || !ext.startsWith("."))
|
|
10778
10840
|
return null;
|
|
10779
|
-
const next =
|
|
10841
|
+
const next = join42(dirname13(file), ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
10780
10842
|
return existsSync23(next) ? moduleOf(next, depth + 1) : null;
|
|
10781
10843
|
}
|
|
10782
10844
|
function readPackageConventions(pkgDir, runner = null) {
|
|
@@ -10788,13 +10850,13 @@ function readPackageConventions(pkgDir, runner = null) {
|
|
|
10788
10850
|
}
|
|
10789
10851
|
let packageType = null, tsModule = null;
|
|
10790
10852
|
for (const n2 of names) {
|
|
10791
|
-
const j = readJson5(
|
|
10853
|
+
const j = readJson5(join42(pkgDir, n2));
|
|
10792
10854
|
if (!j)
|
|
10793
10855
|
continue;
|
|
10794
10856
|
if (packageType === null && typeof j.type === "string" && typeof j.name === "string")
|
|
10795
10857
|
packageType = j.type;
|
|
10796
10858
|
if (tsModule === null && j.compilerOptions !== undefined)
|
|
10797
|
-
tsModule = moduleOf(
|
|
10859
|
+
tsModule = moduleOf(join42(pkgDir, n2));
|
|
10798
10860
|
}
|
|
10799
10861
|
if (packageType === null && tsModule === null)
|
|
10800
10862
|
return null;
|
|
@@ -10826,15 +10888,15 @@ var init_conventions = () => {};
|
|
|
10826
10888
|
|
|
10827
10889
|
// ../../loki-ts/src/engine10/stages/wall.ts
|
|
10828
10890
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
10829
|
-
import { existsSync as existsSync24, mkdirSync as mkdirSync10, mkdtempSync as
|
|
10830
|
-
import { tmpdir as
|
|
10831
|
-
import { dirname as dirname14, isAbsolute as isAbsolute6, join as
|
|
10891
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync7, readFileSync as readFileSync29, readdirSync as readdirSync13, realpathSync as realpathSync17, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "fs";
|
|
10892
|
+
import { tmpdir as tmpdir9 } from "os";
|
|
10893
|
+
import { dirname as dirname14, isAbsolute as isAbsolute6, join as join43, relative as relative6 } from "path";
|
|
10832
10894
|
function pytestCollectionIsRed(output, repoDir) {
|
|
10833
10895
|
if (/ModuleNotFoundError/.test(output))
|
|
10834
10896
|
return false;
|
|
10835
10897
|
const real2 = (p) => {
|
|
10836
10898
|
try {
|
|
10837
|
-
return realpathSync17(isAbsolute6(p) ? p :
|
|
10899
|
+
return realpathSync17(isAbsolute6(p) ? p : join43(repoDir, p));
|
|
10838
10900
|
} catch {
|
|
10839
10901
|
return null;
|
|
10840
10902
|
}
|
|
@@ -10871,7 +10933,7 @@ function pytestCollectionIsRed(output, repoDir) {
|
|
|
10871
10933
|
}
|
|
10872
10934
|
function moduleUnderRepo(repoDir, name) {
|
|
10873
10935
|
const rel = name.replace(/\./g, "/");
|
|
10874
|
-
return existsSync24(
|
|
10936
|
+
return existsSync24(join43(repoDir, `${rel}.py`)) || existsSync24(join43(repoDir, rel, "__init__.py"));
|
|
10875
10937
|
}
|
|
10876
10938
|
function pytestExit1IsRed(output) {
|
|
10877
10939
|
if (/^!+ _pytest\.outcomes\.Exit\b/m.test(output))
|
|
@@ -10966,7 +11028,7 @@ ${repomapText}`] : [],
|
|
|
10966
11028
|
function loadTaskText(ctx, fromPrior) {
|
|
10967
11029
|
if (fromPrior)
|
|
10968
11030
|
return fromPrior;
|
|
10969
|
-
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ??
|
|
11031
|
+
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join43(ctx.runDir, "issue.json");
|
|
10970
11032
|
if (existsSync24(issueJsonPath)) {
|
|
10971
11033
|
try {
|
|
10972
11034
|
const issue = JSON.parse(readFileSync29(issueJsonPath, "utf8"));
|
|
@@ -10981,7 +11043,7 @@ function loadTaskText(ctx, fromPrior) {
|
|
|
10981
11043
|
}
|
|
10982
11044
|
function wallTargetDir(repoDir, existingTests) {
|
|
10983
11045
|
const first = existingTests[0];
|
|
10984
|
-
return first ?
|
|
11046
|
+
return first ? join43(repoDir, dirname14(first.path)) : join43(repoDir, "tests");
|
|
10985
11047
|
}
|
|
10986
11048
|
function guessRunner(fileName, runners) {
|
|
10987
11049
|
if (fileName.endsWith(".py"))
|
|
@@ -11012,11 +11074,11 @@ async function wallAuthor(ctx, signal) {
|
|
|
11012
11074
|
const tree = prior.intake?.tree;
|
|
11013
11075
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
11014
11076
|
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative6(ctx.repoDir, targetDir)}/x`);
|
|
11015
|
-
const conv2 = readPackageConventions(
|
|
11016
|
-
const cwd =
|
|
11077
|
+
const conv2 = readPackageConventions(join43(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
11078
|
+
const cwd = mkdtempSync7(join43(tmpdir9(), "loki-e15-wall-"));
|
|
11017
11079
|
const wm = wallManifestFor(ctx.repoDir, tree, task);
|
|
11018
11080
|
for (const [n2, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm ? [["wall_manifest.txt", wm.text]] : []])
|
|
11019
|
-
writeFileSync13(
|
|
11081
|
+
writeFileSync13(join43(cwd, n2), c, "utf8");
|
|
11020
11082
|
const session = await ctx.sessions.run({
|
|
11021
11083
|
stage: "wall",
|
|
11022
11084
|
brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2)),
|
|
@@ -11028,24 +11090,24 @@ async function wallAuthor(ctx, signal) {
|
|
|
11028
11090
|
cwd
|
|
11029
11091
|
});
|
|
11030
11092
|
if (session.killed || session.exit === null) {
|
|
11031
|
-
|
|
11093
|
+
rmSync10(cwd, { recursive: true, force: true });
|
|
11032
11094
|
return done({ status: "failed", data: {}, reason: "wall session aborted, killed, or timed out", killed: true });
|
|
11033
11095
|
}
|
|
11034
11096
|
const generated = readdirSync13(cwd).filter((f) => f.startsWith(WALL_PREFIX));
|
|
11035
|
-
const sealedDir =
|
|
11097
|
+
const sealedDir = join43(ctx.runDir, "wall");
|
|
11036
11098
|
if (generated.length > 0)
|
|
11037
11099
|
mkdirSync10(sealedDir, { recursive: true });
|
|
11038
11100
|
const contents = new Map;
|
|
11039
11101
|
const discarded = [];
|
|
11040
11102
|
for (const name of generated) {
|
|
11041
|
-
const content = readFileSync29(
|
|
11042
|
-
writeFileSync13(
|
|
11103
|
+
const content = readFileSync29(join43(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
|
|
11104
|
+
writeFileSync13(join43(sealedDir, name), content, "utf8");
|
|
11043
11105
|
if (bad)
|
|
11044
11106
|
discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
|
|
11045
11107
|
else
|
|
11046
11108
|
contents.set(name, content);
|
|
11047
11109
|
}
|
|
11048
|
-
|
|
11110
|
+
rmSync10(cwd, { recursive: true, force: true });
|
|
11049
11111
|
return { kind: "authored", task, sizeName: sz.size, runners, targetDir, generated, contents, discarded, ...wm ? { manifestSha256: wm.sha256 } : {} };
|
|
11050
11112
|
}
|
|
11051
11113
|
function installWall(ctx, a, baseDir, opts = {}) {
|
|
@@ -11059,7 +11121,7 @@ function installWall(ctx, a, baseDir, opts = {}) {
|
|
|
11059
11121
|
const content = contents.get(name);
|
|
11060
11122
|
if (content === undefined)
|
|
11061
11123
|
continue;
|
|
11062
|
-
const dest =
|
|
11124
|
+
const dest = join43(targetDir, name), runner = guessRunner(name, runners);
|
|
11063
11125
|
writeFileSync13(dest, content, "utf8");
|
|
11064
11126
|
sealedFiles.push({ path: dest, sha256: sha2562(content) });
|
|
11065
11127
|
readOnlyFiles.push({ path: dest, content });
|
|
@@ -11069,13 +11131,13 @@ function installWall(ctx, a, baseDir, opts = {}) {
|
|
|
11069
11131
|
ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
|
|
11070
11132
|
const baseRunner = opts.baseRunner ?? new RealBaseTestRunner, baseRun = { pass: 0, fail: 0, not_run: discarded.length }, notRunFiles = [];
|
|
11071
11133
|
for (const t of wallTests) {
|
|
11072
|
-
const r = baseRunner.run(baseDir, [t]), abs =
|
|
11134
|
+
const r = baseRunner.run(baseDir, [t]), abs = join43(ctx.repoDir, t.path);
|
|
11073
11135
|
baseRun.pass += r.pass;
|
|
11074
11136
|
baseRun.fail += r.fail;
|
|
11075
11137
|
baseRun.not_run += r.not_run ?? 0;
|
|
11076
11138
|
notRunFiles.push(...baseRunner.lastNotRunFiles ?? []);
|
|
11077
11139
|
if (r.pass + r.fail === 0) {
|
|
11078
|
-
|
|
11140
|
+
rmSync10(abs, { force: true });
|
|
11079
11141
|
for (const l of [sealedFiles, readOnlyFiles])
|
|
11080
11142
|
l.splice(0, l.length, ...l.filter((f) => f.path !== abs));
|
|
11081
11143
|
}
|
|
@@ -11120,18 +11182,18 @@ var init_wall = __esm(() => {
|
|
|
11120
11182
|
});
|
|
11121
11183
|
|
|
11122
11184
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
11123
|
-
import { chmodSync as chmodSync4, closeSync as closeSync6, lstatSync as
|
|
11124
|
-
import { dirname as dirname15, join as
|
|
11185
|
+
import { chmodSync as chmodSync4, closeSync as closeSync6, lstatSync as lstatSync7, mkdirSync as mkdirSync11, openSync as openSync6, readFileSync as readFileSync30, realpathSync as realpathSync18, rmdirSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync14 } from "fs";
|
|
11186
|
+
import { dirname as dirname15, join as join44, relative as relative7, sep as sep11 } from "path";
|
|
11125
11187
|
function safeRestore(repoDir, f, want, mode) {
|
|
11126
|
-
const root = realpathSync18(repoDir), fp =
|
|
11188
|
+
const root = realpathSync18(repoDir), fp = join44(root, f), rel = relative7(root, dirname15(fp));
|
|
11127
11189
|
if (rel.startsWith(".."))
|
|
11128
11190
|
throw new Error("outside repo");
|
|
11129
11191
|
let cur = root;
|
|
11130
11192
|
for (const part of rel === "" ? [] : rel.split(sep11)) {
|
|
11131
|
-
cur =
|
|
11193
|
+
cur = join44(cur, part);
|
|
11132
11194
|
let st2;
|
|
11133
11195
|
try {
|
|
11134
|
-
st2 =
|
|
11196
|
+
st2 = lstatSync7(cur);
|
|
11135
11197
|
} catch {
|
|
11136
11198
|
mkdirSync11(cur);
|
|
11137
11199
|
continue;
|
|
@@ -11141,7 +11203,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
11141
11203
|
}
|
|
11142
11204
|
let st;
|
|
11143
11205
|
try {
|
|
11144
|
-
st =
|
|
11206
|
+
st = lstatSync7(fp);
|
|
11145
11207
|
} catch {
|
|
11146
11208
|
st = null;
|
|
11147
11209
|
}
|
|
@@ -11183,10 +11245,10 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
11183
11245
|
return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
|
|
11184
11246
|
const notProven = [];
|
|
11185
11247
|
for (const [f, v] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
|
|
11186
|
-
const fp =
|
|
11248
|
+
const fp = join44(repoDir, f);
|
|
11187
11249
|
try {
|
|
11188
11250
|
if (v.startsWith("!")) {
|
|
11189
|
-
const st =
|
|
11251
|
+
const st = lstatSync7(fp);
|
|
11190
11252
|
if (`!${st.size}:${st.mtimeMs}:${st.ctimeMs}` !== v)
|
|
11191
11253
|
throw new Error("changed, not snapshotted");
|
|
11192
11254
|
continue;
|
|
@@ -11202,7 +11264,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
11202
11264
|
try {
|
|
11203
11265
|
let m = 420;
|
|
11204
11266
|
try {
|
|
11205
|
-
const l =
|
|
11267
|
+
const l = lstatSync7(join44(repoDir, f));
|
|
11206
11268
|
if (l.isFile())
|
|
11207
11269
|
m = l.mode & 511;
|
|
11208
11270
|
} catch {}
|
|
@@ -11246,9 +11308,9 @@ var init_commit_filter = __esm(() => {
|
|
|
11246
11308
|
});
|
|
11247
11309
|
|
|
11248
11310
|
// ../../loki-ts/src/features/speed/unit_mode.ts
|
|
11249
|
-
import { closeSync as closeSync7, constants as constants2, fstatSync as fstatSync4, lstatSync as
|
|
11311
|
+
import { closeSync as closeSync7, constants as constants2, fstatSync as fstatSync4, lstatSync as lstatSync8, openSync as openSync7, readSync as readSync5, realpathSync as realpathSync19 } from "fs";
|
|
11250
11312
|
function readBounded(path) {
|
|
11251
|
-
const l =
|
|
11313
|
+
const l = lstatSync8(path);
|
|
11252
11314
|
if (l.isSymbolicLink() || !l.isFile() || l.size > MAX_SPEC_BYTES)
|
|
11253
11315
|
return null;
|
|
11254
11316
|
const fd = openSync7(path, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
|
|
@@ -11348,13 +11410,13 @@ import {
|
|
|
11348
11410
|
closeSync as closeSync8,
|
|
11349
11411
|
fstatSync as fstatSync5,
|
|
11350
11412
|
fsyncSync as fsyncSync2,
|
|
11351
|
-
lstatSync as
|
|
11413
|
+
lstatSync as lstatSync9,
|
|
11352
11414
|
mkdirSync as mkdirSync12,
|
|
11353
11415
|
openSync as openSync8,
|
|
11354
11416
|
readSync as readSync6,
|
|
11355
11417
|
renameSync as renameSync5,
|
|
11356
|
-
rmSync as
|
|
11357
|
-
statSync as
|
|
11418
|
+
rmSync as rmSync11,
|
|
11419
|
+
statSync as statSync15,
|
|
11358
11420
|
unlinkSync as unlinkSync4,
|
|
11359
11421
|
writeSync as writeSync3
|
|
11360
11422
|
} from "fs";
|
|
@@ -11396,7 +11458,7 @@ var init_atomic = __esm(() => {
|
|
|
11396
11458
|
|
|
11397
11459
|
// ../../loki-ts/src/util/pr_lessons.ts
|
|
11398
11460
|
import { existsSync as existsSync25, mkdirSync as mkdirSync13, readFileSync as readFileSync31 } from "fs";
|
|
11399
|
-
import { dirname as dirname19, join as
|
|
11461
|
+
import { dirname as dirname19, join as join45 } from "path";
|
|
11400
11462
|
function loadLessons(repoDir) {
|
|
11401
11463
|
const p = lessonsPath(repoDir);
|
|
11402
11464
|
if (!existsSync25(p))
|
|
@@ -11425,17 +11487,17 @@ function recordRunVerdict(repoDir, runId, verdict) {
|
|
|
11425
11487
|
if (dirty)
|
|
11426
11488
|
save(repoDir, lessons);
|
|
11427
11489
|
}
|
|
11428
|
-
var lessonsPath = (repoDir) =>
|
|
11490
|
+
var lessonsPath = (repoDir) => join45(repoDir, ".loki", "memory", "semantic", "pr-lessons.json");
|
|
11429
11491
|
var init_pr_lessons = __esm(() => {
|
|
11430
11492
|
init_atomic();
|
|
11431
11493
|
});
|
|
11432
11494
|
|
|
11433
11495
|
// ../../loki-ts/src/features/visual_evidence.ts
|
|
11434
11496
|
import { spawn as spawn7 } from "child_process";
|
|
11435
|
-
import { createHash as createHash10, randomBytes as
|
|
11436
|
-
import { existsSync as existsSync26, lstatSync as
|
|
11497
|
+
import { createHash as createHash10, randomBytes as randomBytes3 } from "crypto";
|
|
11498
|
+
import { existsSync as existsSync26, lstatSync as lstatSync10, mkdirSync as mkdirSync14, readdirSync as readdirSync14, readFileSync as readFileSync32, writeFileSync as writeFileSync15 } from "fs";
|
|
11437
11499
|
import { createServer } from "net";
|
|
11438
|
-
import { dirname as dirname20, isAbsolute as isAbsolute7, join as
|
|
11500
|
+
import { dirname as dirname20, isAbsolute as isAbsolute7, join as join46, normalize as normalize2, relative as relative8, sep as sep12 } from "path";
|
|
11439
11501
|
function routeFor(file) {
|
|
11440
11502
|
let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
|
|
11441
11503
|
r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
|
|
@@ -11445,7 +11507,7 @@ function hashScreens(runDir, rels) {
|
|
|
11445
11507
|
const out2 = [];
|
|
11446
11508
|
for (const rel of rels) {
|
|
11447
11509
|
try {
|
|
11448
|
-
out2.push({ path: rel, sha256: sha256File(
|
|
11510
|
+
out2.push({ path: rel, sha256: sha256File(join46(runDir, rel)) });
|
|
11449
11511
|
} catch {}
|
|
11450
11512
|
}
|
|
11451
11513
|
return out2;
|
|
@@ -11458,10 +11520,10 @@ function checkScreens(runDir, screens) {
|
|
|
11458
11520
|
return "evidence_screens entry is malformed";
|
|
11459
11521
|
if (isAbsolute7(s.path) || normalize2(s.path).startsWith(".."))
|
|
11460
11522
|
return `evidence screenshot path escapes the evidence dir: ${s.path}`;
|
|
11461
|
-
const file =
|
|
11523
|
+
const file = join46(runDir, s.path);
|
|
11462
11524
|
let cur = runDir;
|
|
11463
11525
|
for (const seg of normalize2(s.path).split(sep12)) {
|
|
11464
|
-
cur =
|
|
11526
|
+
cur = join46(cur, seg);
|
|
11465
11527
|
if (isSymlink(cur))
|
|
11466
11528
|
return `evidence screenshot path is a symlink: ${s.path}`;
|
|
11467
11529
|
}
|
|
@@ -11508,7 +11570,7 @@ async function waitUp(url, ms, signal) {
|
|
|
11508
11570
|
}
|
|
11509
11571
|
function openapiPaths(repoDir) {
|
|
11510
11572
|
for (const f of ["openapi.json", "openapi.yaml", "openapi.yml", "swagger.json"]) {
|
|
11511
|
-
const p =
|
|
11573
|
+
const p = join46(repoDir, f);
|
|
11512
11574
|
if (!existsSync26(p))
|
|
11513
11575
|
continue;
|
|
11514
11576
|
try {
|
|
@@ -11526,24 +11588,24 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
|
|
|
11526
11588
|
if (!pw || !pkg)
|
|
11527
11589
|
return { rels: [], skipped: "playwright e2e video and trace skipped: @playwright/test is not installed in the repo" };
|
|
11528
11590
|
try {
|
|
11529
|
-
const dir =
|
|
11591
|
+
const dir = join46(runDir, relDir, "e2e");
|
|
11530
11592
|
mkdirSync14(dir, { recursive: true });
|
|
11531
|
-
writeFileSync15(
|
|
11532
|
-
writeFileSync15(
|
|
11593
|
+
writeFileSync15(join46(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
|
|
11594
|
+
writeFileSync15(join46(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
|
|
11533
11595
|
`);
|
|
11534
|
-
if (!await shoot(pw, ["test", "--config",
|
|
11596
|
+
if (!await shoot(pw, ["test", "--config", join46(dir, "playwright.config.cjs")], repoDir, ms, signal))
|
|
11535
11597
|
return { rels: [], skipped: "playwright e2e video and trace skipped: the run failed or timed out" };
|
|
11536
11598
|
const rels = [];
|
|
11537
11599
|
const walk = (d) => {
|
|
11538
11600
|
for (const e of readdirSync14(d, { withFileTypes: true })) {
|
|
11539
|
-
const full =
|
|
11601
|
+
const full = join46(d, e.name);
|
|
11540
11602
|
if (e.isDirectory())
|
|
11541
11603
|
walk(full);
|
|
11542
11604
|
else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
|
|
11543
|
-
rels.push(
|
|
11605
|
+
rels.push(join46(relDir, "e2e", relative8(dir, full)));
|
|
11544
11606
|
}
|
|
11545
11607
|
};
|
|
11546
|
-
walk(
|
|
11608
|
+
walk(join46(dir, "out"));
|
|
11547
11609
|
return rels.length > 0 ? { rels, skipped: null } : { rels, skipped: "playwright e2e video and trace skipped: no video or trace was produced" };
|
|
11548
11610
|
} catch (e) {
|
|
11549
11611
|
return { rels: [], skipped: `playwright e2e video and trace skipped: ${String(e?.message ?? e).slice(0, 120)}` };
|
|
@@ -11612,8 +11674,8 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
11612
11674
|
if (!visualEvidenceEnabled(opts.env))
|
|
11613
11675
|
return skip("LOKI_VISUAL_EVIDENCE is 0");
|
|
11614
11676
|
const api = loadProjectApi(repoDir), boot = isMultiRoot(api) ? api.uiBoot() : null;
|
|
11615
|
-
const appDir = boot ?
|
|
11616
|
-
const pkgPath =
|
|
11677
|
+
const appDir = boot ? join46(repoDir, boot.boot.cwd) : repoDir;
|
|
11678
|
+
const pkgPath = join46(appDir, "package.json");
|
|
11617
11679
|
let script = null;
|
|
11618
11680
|
if (!boot) {
|
|
11619
11681
|
if (!existsSync26(pkgPath))
|
|
@@ -11645,20 +11707,20 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
11645
11707
|
}
|
|
11646
11708
|
if (!await waitUp(base, left(), signal))
|
|
11647
11709
|
return skip(aborted() ? "aborted" : `${script} server did not answer within ${Math.round(budget / 1000)}s`);
|
|
11648
|
-
const evRoot =
|
|
11710
|
+
const evRoot = join46(runDir, "evidence");
|
|
11649
11711
|
if (isSymlink(evRoot))
|
|
11650
11712
|
return skip("evidence dir is a symlink");
|
|
11651
11713
|
mkdirSync14(evRoot, { recursive: true });
|
|
11652
11714
|
if (pages.length > 0) {
|
|
11653
|
-
const rel0 =
|
|
11654
|
-
mkdirSync14(
|
|
11715
|
+
const rel0 = join46("evidence", randomBytes3(6).toString("hex"));
|
|
11716
|
+
mkdirSync14(join46(runDir, rel0));
|
|
11655
11717
|
const rels = [];
|
|
11656
11718
|
for (const route of [...new Set(pages.map(routeFor))].slice(0, opts.maxRoutes ?? MAX_ROUTES)) {
|
|
11657
11719
|
if (aborted() || left() <= 0)
|
|
11658
11720
|
break;
|
|
11659
|
-
const rel =
|
|
11660
|
-
const ok = await shoot(pw, ["screenshot", `${base}${route}`,
|
|
11661
|
-
if (ok && !aborted() && !isSymlink(
|
|
11721
|
+
const rel = join46(rel0, `${screenName(route)}.png`);
|
|
11722
|
+
const ok = await shoot(pw, ["screenshot", `${base}${route}`, join46(runDir, rel)], appDir, left(), signal);
|
|
11723
|
+
if (ok && !aborted() && !isSymlink(join46(runDir, rel)) && existsSync26(join46(runDir, rel)))
|
|
11662
11724
|
rels.push(rel);
|
|
11663
11725
|
}
|
|
11664
11726
|
if (aborted())
|
|
@@ -11683,9 +11745,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
11683
11745
|
}
|
|
11684
11746
|
if (aborted())
|
|
11685
11747
|
return skip("aborted");
|
|
11686
|
-
const hdir =
|
|
11748
|
+
const hdir = join46(evRoot, randomBytes3(6).toString("hex"));
|
|
11687
11749
|
mkdirSync14(hdir);
|
|
11688
|
-
writeFileSync15(
|
|
11750
|
+
writeFileSync15(join46(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
|
|
11689
11751
|
`);
|
|
11690
11752
|
return { screens: [], http: true, skipped: null };
|
|
11691
11753
|
} catch (e) {
|
|
@@ -11711,24 +11773,24 @@ function receiptScreensProblem(receiptPath, receipt) {
|
|
|
11711
11773
|
return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname20(receiptPath), receipt["evidence_screens"]);
|
|
11712
11774
|
}
|
|
11713
11775
|
var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash10("sha256").update(readFileSync32(p)).digest("hex"), playwrightBin = (repoDir) => {
|
|
11714
|
-
const bin =
|
|
11776
|
+
const bin = join46(repoDir, "node_modules", ".bin", "playwright");
|
|
11715
11777
|
return existsSync26(bin) ? bin : null;
|
|
11716
11778
|
}, playwrightTestPkg = (repoDir) => {
|
|
11717
|
-
const d =
|
|
11718
|
-
return existsSync26(
|
|
11779
|
+
const d = join46(repoDir, "node_modules", "@playwright", "test");
|
|
11780
|
+
return existsSync26(join46(d, "package.json")) ? d : null;
|
|
11719
11781
|
}, e2eSpecSource = (pkgDir, base, routes) => `const { test } = require(${JSON.stringify(pkgDir)});
|
|
11720
11782
|
test("loki e2e walkthrough", async ({ page }) => {
|
|
11721
11783
|
for (const r of ${JSON.stringify(routes)}) { await page.goto(${JSON.stringify(base)} + r); await page.waitForLoadState("load"); }
|
|
11722
11784
|
});
|
|
11723
11785
|
`, DEFAULT_BUDGET_MS = 25000, MAX_ROUTES = 5, isSymlink = (p) => {
|
|
11724
11786
|
try {
|
|
11725
|
-
return
|
|
11787
|
+
return lstatSync10(p).isSymbolicLink();
|
|
11726
11788
|
} catch {
|
|
11727
11789
|
return false;
|
|
11728
11790
|
}
|
|
11729
11791
|
}, isRegularFile = (p) => {
|
|
11730
11792
|
try {
|
|
11731
|
-
return
|
|
11793
|
+
return lstatSync10(p).isFile();
|
|
11732
11794
|
} catch {
|
|
11733
11795
|
return false;
|
|
11734
11796
|
}
|
|
@@ -11818,7 +11880,7 @@ var init_shell = __esm(() => {
|
|
|
11818
11880
|
|
|
11819
11881
|
// ../../loki-ts/src/engine10/stages/xreview.ts
|
|
11820
11882
|
import { existsSync as existsSync27, readFileSync as readFileSync33 } from "fs";
|
|
11821
|
-
import { join as
|
|
11883
|
+
import { join as join47 } from "path";
|
|
11822
11884
|
function minVerdict(verdict, review) {
|
|
11823
11885
|
const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
|
|
11824
11886
|
return RANK2[ceiling] < RANK2[verdict] ? ceiling : verdict;
|
|
@@ -11831,7 +11893,7 @@ function explicitReview(repoDir, env) {
|
|
|
11831
11893
|
if (flag && isOff(ev))
|
|
11832
11894
|
return "off";
|
|
11833
11895
|
for (const f of ["loki.yaml", "loki.yml"]) {
|
|
11834
|
-
const p =
|
|
11896
|
+
const p = join47(repoDir, f);
|
|
11835
11897
|
if (!existsSync27(p))
|
|
11836
11898
|
continue;
|
|
11837
11899
|
try {
|
|
@@ -11916,12 +11978,12 @@ var init_xreview = __esm(() => {
|
|
|
11916
11978
|
});
|
|
11917
11979
|
|
|
11918
11980
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
11919
|
-
import { existsSync as existsSync28, lstatSync as
|
|
11920
|
-
import { join as
|
|
11981
|
+
import { existsSync as existsSync28, lstatSync as lstatSync11, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync16 } from "fs";
|
|
11982
|
+
import { join as join48 } from "path";
|
|
11921
11983
|
function loadRouteRecord(runDir) {
|
|
11922
11984
|
try {
|
|
11923
|
-
const p =
|
|
11924
|
-
if (!existsSync28(p) || !
|
|
11985
|
+
const p = join48(runDir, ROUTE_RECORD_FILE);
|
|
11986
|
+
if (!existsSync28(p) || !lstatSync11(p).isFile())
|
|
11925
11987
|
return;
|
|
11926
11988
|
const v = JSON.parse(readFileSync34(p, "utf8"));
|
|
11927
11989
|
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
|
|
@@ -11933,7 +11995,7 @@ var ROUTE_RECORD_FILE = "route.json";
|
|
|
11933
11995
|
var init_route_record = () => {};
|
|
11934
11996
|
|
|
11935
11997
|
// ../../loki-ts/src/runner/router/history_store.ts
|
|
11936
|
-
import { existsSync as existsSync29, mkdirSync as mkdirSync16, readFileSync as readFileSync35, renameSync as renameSync6, rmSync as
|
|
11998
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync16, readFileSync as readFileSync35, renameSync as renameSync6, rmSync as rmSync12, writeFileSync as writeFileSync17 } from "fs";
|
|
11937
11999
|
import { resolve as resolve11 } from "path";
|
|
11938
12000
|
function validRun(v) {
|
|
11939
12001
|
if (typeof v !== "object" || v === null)
|
|
@@ -11966,7 +12028,7 @@ function appendRunOutcome(key, outcome, cacheRoot) {
|
|
|
11966
12028
|
writeFileSync17(tmp, JSON.stringify({ runs: runs2 }));
|
|
11967
12029
|
renameSync6(tmp, target);
|
|
11968
12030
|
} catch (e) {
|
|
11969
|
-
|
|
12031
|
+
rmSync12(tmp, { force: true, recursive: false });
|
|
11970
12032
|
throw e;
|
|
11971
12033
|
}
|
|
11972
12034
|
return true;
|
|
@@ -11983,7 +12045,7 @@ var init_history_store = __esm(() => {
|
|
|
11983
12045
|
});
|
|
11984
12046
|
|
|
11985
12047
|
// ../../loki-ts/src/runner/router/history.ts
|
|
11986
|
-
import { dirname as dirname21, join as
|
|
12048
|
+
import { dirname as dirname21, join as join49, resolve as resolve12 } from "path";
|
|
11987
12049
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11988
12050
|
function shapeKey(model) {
|
|
11989
12051
|
if (!model || model.status !== "ok")
|
|
@@ -12061,8 +12123,8 @@ var init_cost_preview = __esm(() => {
|
|
|
12061
12123
|
});
|
|
12062
12124
|
|
|
12063
12125
|
// ../../loki-ts/src/features/contract.ts
|
|
12064
|
-
import { existsSync as existsSync30, lstatSync as
|
|
12065
|
-
import { dirname as dirname22, join as
|
|
12126
|
+
import { existsSync as existsSync30, lstatSync as lstatSync12, mkdirSync as mkdirSync17, readFileSync as readFileSync36, writeFileSync as writeFileSync18 } from "fs";
|
|
12127
|
+
import { dirname as dirname22, join as join50 } from "path";
|
|
12066
12128
|
import { createHash as createHash11 } from "crypto";
|
|
12067
12129
|
function contractEnabled(env = process.env) {
|
|
12068
12130
|
return env["LOKI_CONTRACT"] !== "0";
|
|
@@ -12094,13 +12156,13 @@ function untracedLines(trace) {
|
|
|
12094
12156
|
return trace.criteria.filter((c) => c.status === "no_match").map((c) => `contract ${sanitizeCriterion(c.id)} untraced (no keyword match in changed files): ${sanitizeCriterion(c.text)}`);
|
|
12095
12157
|
}
|
|
12096
12158
|
function contractPath(repoDir) {
|
|
12097
|
-
return
|
|
12159
|
+
return join50(repoDir, ".loki", "contract.json");
|
|
12098
12160
|
}
|
|
12099
12161
|
function readContract(repoDir) {
|
|
12100
12162
|
const p = contractPath(repoDir);
|
|
12101
12163
|
let st;
|
|
12102
12164
|
try {
|
|
12103
|
-
st =
|
|
12165
|
+
st = lstatSync12(p);
|
|
12104
12166
|
} catch {
|
|
12105
12167
|
return { contract: null, notes: [], sha256: null };
|
|
12106
12168
|
}
|
|
@@ -12145,7 +12207,7 @@ function sealContract(repoDir, body, rawDiff, checks, env = process.env, snap) {
|
|
|
12145
12207
|
const live2 = readContract(repoDir);
|
|
12146
12208
|
let exists2 = true;
|
|
12147
12209
|
try {
|
|
12148
|
-
|
|
12210
|
+
lstatSync12(contractPath(repoDir));
|
|
12149
12211
|
} catch {
|
|
12150
12212
|
exists2 = false;
|
|
12151
12213
|
}
|
|
@@ -12179,8 +12241,8 @@ var init_contract = __esm(() => {
|
|
|
12179
12241
|
});
|
|
12180
12242
|
|
|
12181
12243
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
12182
|
-
import { existsSync as existsSync31, readFileSync as readFileSync37, statSync as
|
|
12183
|
-
import { basename as basename17, join as
|
|
12244
|
+
import { existsSync as existsSync31, readFileSync as readFileSync37, statSync as statSync16 } from "fs";
|
|
12245
|
+
import { basename as basename17, join as join51 } from "path";
|
|
12184
12246
|
function supplyEnabled(env) {
|
|
12185
12247
|
return env["LOKI_SUPPLY_GUARD"] !== "0";
|
|
12186
12248
|
}
|
|
@@ -12195,11 +12257,11 @@ function isManifestPath(path) {
|
|
|
12195
12257
|
return MANIFESTS.test(basename17(path));
|
|
12196
12258
|
}
|
|
12197
12259
|
function readDeclared(repoDir) {
|
|
12198
|
-
const p =
|
|
12260
|
+
const p = join51(repoDir, ".loki", DECLARED_FILE);
|
|
12199
12261
|
if (!existsSync31(p))
|
|
12200
12262
|
return { deps: [], problem: null };
|
|
12201
12263
|
try {
|
|
12202
|
-
if (
|
|
12264
|
+
if (statSync16(p).size > MAX_FILE_BYTES)
|
|
12203
12265
|
return { deps: [], problem: "declaration file too large" };
|
|
12204
12266
|
const j = JSON.parse(readFileSync37(p, "utf8"));
|
|
12205
12267
|
if (!Array.isArray(j))
|
|
@@ -12221,7 +12283,7 @@ function readDeclared(repoDir) {
|
|
|
12221
12283
|
}
|
|
12222
12284
|
}
|
|
12223
12285
|
function readAllowlist(repoDir) {
|
|
12224
|
-
const p =
|
|
12286
|
+
const p = join51(repoDir, ".loki", "supply-allowlist");
|
|
12225
12287
|
if (!existsSync31(p))
|
|
12226
12288
|
return new Set;
|
|
12227
12289
|
try {
|
|
@@ -12266,7 +12328,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
12266
12328
|
if (eco === "npm") {
|
|
12267
12329
|
if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
|
|
12268
12330
|
return true;
|
|
12269
|
-
return files(
|
|
12331
|
+
return files(join51(repoDir, ".npmrc"), home ? join51(home, ".npmrc") : "").some((t) => t.split(`
|
|
12270
12332
|
`).some((l) => {
|
|
12271
12333
|
const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
|
|
12272
12334
|
return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
|
|
@@ -12275,7 +12337,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
12275
12337
|
if (eco === "pypi") {
|
|
12276
12338
|
if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
|
|
12277
12339
|
return true;
|
|
12278
|
-
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ?
|
|
12340
|
+
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join51(home, ".config", "pip", "pip.conf") : "", home ? join51(home, ".pip", "pip.conf") : "", join51(repoDir, "pip.conf")];
|
|
12279
12341
|
return files(...cfg).some((t) => t.split(`
|
|
12280
12342
|
`).some((l) => {
|
|
12281
12343
|
const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
|
|
@@ -12285,7 +12347,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
12285
12347
|
if (eco === "cargo") {
|
|
12286
12348
|
if (Object.keys(env).some((k) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k) || /^CARGO_SOURCE_/.test(k)))
|
|
12287
12349
|
return true;
|
|
12288
|
-
return files(
|
|
12350
|
+
return files(join51(repoDir, ".cargo", "config.toml"), join51(repoDir, ".cargo", "config"), home ? join51(home, ".cargo", "config.toml") : "", home ? join51(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
|
|
12289
12351
|
}
|
|
12290
12352
|
if (eco === "go") {
|
|
12291
12353
|
const gp = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
|
|
@@ -12408,7 +12470,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
|
|
|
12408
12470
|
}
|
|
12409
12471
|
}, PUBLIC_HOSTS, hostOf = (u) => u.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//, "").replace(/^www\./, "").split(/[/?#\s]/)[0].replace(/^[^@]*@/, "").replace(/:\d+$/, ""), privateUrl = (u) => /[a-z0-9]/i.test(u) && !PUBLIC_HOSTS.has(hostOf(u)), readSmall = (p) => {
|
|
12410
12472
|
try {
|
|
12411
|
-
return
|
|
12473
|
+
return statSync16(p).size <= MAX_FILE_BYTES ? readFileSync37(p, "utf8") : "";
|
|
12412
12474
|
} catch {
|
|
12413
12475
|
return "";
|
|
12414
12476
|
}
|
|
@@ -12423,10 +12485,10 @@ var init_supply_guard = __esm(() => {
|
|
|
12423
12485
|
});
|
|
12424
12486
|
|
|
12425
12487
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
12426
|
-
import { createHash as createHash12, randomBytes as
|
|
12427
|
-
import { chmodSync as chmodSync5, existsSync as existsSync32, readdirSync as readdirSync15, linkSync, mkdirSync as mkdirSync18, readFileSync as readFileSync38, statSync as
|
|
12488
|
+
import { createHash as createHash12, randomBytes as randomBytes4, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, sign } from "crypto";
|
|
12489
|
+
import { chmodSync as chmodSync5, existsSync as existsSync32, readdirSync as readdirSync15, linkSync, mkdirSync as mkdirSync18, readFileSync as readFileSync38, statSync as statSync17, unlinkSync as unlinkSync5, writeFileSync as writeFileSync19 } from "fs";
|
|
12428
12490
|
import { homedir as homedir8 } from "os";
|
|
12429
|
-
import { basename as basename18, dirname as dirname23, isAbsolute as isAbsolute8, join as
|
|
12491
|
+
import { basename as basename18, dirname as dirname23, isAbsolute as isAbsolute8, join as join52, relative as relative9 } from "path";
|
|
12430
12492
|
function sanitizeReason(s) {
|
|
12431
12493
|
const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
|
|
12432
12494
|
const capped = collapsed.length > 500 ? `${collapsed.slice(0, 500)}...` : collapsed;
|
|
@@ -12454,12 +12516,12 @@ function loadSigningKey(generate = true) {
|
|
|
12454
12516
|
let pem = inline ?? "";
|
|
12455
12517
|
if (!inline) {
|
|
12456
12518
|
const given = process.env["LOKI_RECEIPT_SIGNING_KEY_FILE"]?.trim();
|
|
12457
|
-
const file = given ||
|
|
12519
|
+
const file = given || join52(process.env["HOME"] || homedir8(), ".loki", "keys", RECEIPT_SIGNER_BASENAME);
|
|
12458
12520
|
try {
|
|
12459
12521
|
pem = readFileSync38(file);
|
|
12460
12522
|
if (!given) {
|
|
12461
12523
|
for (const [f, m] of [[file, 384], [dirname23(file), 448]])
|
|
12462
|
-
if (
|
|
12524
|
+
if (statSync17(f).mode & 63)
|
|
12463
12525
|
chmodSync5(f, m);
|
|
12464
12526
|
}
|
|
12465
12527
|
} catch (e) {
|
|
@@ -12467,7 +12529,7 @@ function loadSigningKey(generate = true) {
|
|
|
12467
12529
|
return null;
|
|
12468
12530
|
mkdirSync18(dirname23(dirname23(file)), { recursive: true, mode: 448 });
|
|
12469
12531
|
mkdirSync18(dirname23(file), { recursive: true, mode: 448 });
|
|
12470
|
-
const tmp = `${file}.${
|
|
12532
|
+
const tmp = `${file}.${randomBytes4(6).toString("hex")}.tmp`;
|
|
12471
12533
|
writeFileSync19(tmp, generateKeyPairSync("ed25519").privateKey.export({ type: "pkcs8", format: "pem" }), { flag: "wx", mode: 384 });
|
|
12472
12534
|
try {
|
|
12473
12535
|
linkSync(tmp, file);
|
|
@@ -12559,7 +12621,7 @@ function renderReceiptMd(r) {
|
|
|
12559
12621
|
`);
|
|
12560
12622
|
}
|
|
12561
12623
|
var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash12("sha256").update(s).digest("hex"), str3 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], b64u = (b) => Buffer.from(b).toString("base64url"), kidOf2 = (pub) => b64u(createHash12("sha256").update(`{"crv":"Ed25519","kty":"OKP","x":"${pub.export({ format: "jwk" }).x}"}`).digest()), receiptRel = (ctx) => {
|
|
12562
|
-
const r = relative9(ctx.repoDir,
|
|
12624
|
+
const r = relative9(ctx.repoDir, join52(ctx.runDir, "receipt.json"));
|
|
12563
12625
|
return r.startsWith("..") || isAbsolute8(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
12564
12626
|
}, commitStage, sealStage;
|
|
12565
12627
|
var init_seal = __esm(() => {
|
|
@@ -12662,7 +12724,7 @@ var init_seal = __esm(() => {
|
|
|
12662
12724
|
if (wallNotRun > 0) {
|
|
12663
12725
|
try {
|
|
12664
12726
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename18(String(f.path))));
|
|
12665
|
-
for (const n2 of readdirSync15(
|
|
12727
|
+
for (const n2 of readdirSync15(join52(ctx.runDir, "wall")).sort())
|
|
12666
12728
|
if (!kept.has(n2))
|
|
12667
12729
|
notProven.add(`wall test discarded: ${n2} (not_run)`);
|
|
12668
12730
|
} catch {}
|
|
@@ -12721,19 +12783,19 @@ var init_seal = __esm(() => {
|
|
|
12721
12783
|
for (const [s, d] of Object.entries(o))
|
|
12722
12784
|
if (typeof d?.duration_s === "number")
|
|
12723
12785
|
stages[s] = d.duration_s;
|
|
12724
|
-
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(
|
|
12786
|
+
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join52(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
|
|
12725
12787
|
const iterIds = Object.values(o).flatMap((d) => [...strs2(d?.iteration_ids), ...strs2([d?.iteration_id])]);
|
|
12726
12788
|
if (iterIds.length === 0)
|
|
12727
12789
|
notProven.add("cost not measured (no iteration ids recorded)");
|
|
12728
12790
|
const cost = ctx.cost.read(ctx.repoDir, iterIds);
|
|
12729
12791
|
if (cost.unmetered)
|
|
12730
12792
|
notProven.add("cost unmetered (CLI invoker; recorded as 0)");
|
|
12731
|
-
const eventsPath =
|
|
12793
|
+
const eventsPath = join52(ctx.runDir, "events.jsonl");
|
|
12732
12794
|
const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
|
|
12733
12795
|
const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
|
|
12734
12796
|
if (wallFiles.length > 0 && wallPassed === null)
|
|
12735
12797
|
notProven.add("wall result not recorded by verify");
|
|
12736
|
-
const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(
|
|
12798
|
+
const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(join52(ctx.repoDir, ".loki"), iterIds).router : undefined), ctx.model);
|
|
12737
12799
|
if (routeBlock)
|
|
12738
12800
|
for (const l of routeNotProven(routeBlock))
|
|
12739
12801
|
notProven.add(l);
|
|
@@ -12796,10 +12858,10 @@ var init_seal = __esm(() => {
|
|
|
12796
12858
|
}
|
|
12797
12859
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
12798
12860
|
mkdirSync18(ctx.runDir, { recursive: true });
|
|
12799
|
-
const path =
|
|
12861
|
+
const path = join52(ctx.runDir, "receipt.json");
|
|
12800
12862
|
writeFileSync19(path, JSON.stringify(receipt, null, 2) + `
|
|
12801
12863
|
`);
|
|
12802
|
-
writeFileSync19(
|
|
12864
|
+
writeFileSync19(join52(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
12803
12865
|
recordRun(process.env, ctx.repoDir, ctx.model, verdict, cost.usd, cost.unmetered === true, totalS);
|
|
12804
12866
|
const signed = sig.jwt !== null;
|
|
12805
12867
|
const data = { receipt_path: path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven, ...mp ? { mutation_line: mp.line } : {}, ...routeBlock ? { route_line: routePrLine(routeBlock) } : {} };
|
|
@@ -12905,8 +12967,8 @@ var init_keys_cmd = __esm(() => {
|
|
|
12905
12967
|
});
|
|
12906
12968
|
|
|
12907
12969
|
// ../../loki-ts/src/engine10/verify_cmd.ts
|
|
12908
|
-
import { existsSync as existsSync33, readdirSync as readdirSync16, readFileSync as readFileSync40, statSync as
|
|
12909
|
-
import { dirname as dirname24, join as
|
|
12970
|
+
import { existsSync as existsSync33, readdirSync as readdirSync16, readFileSync as readFileSync40, statSync as statSync18 } from "fs";
|
|
12971
|
+
import { dirname as dirname24, join as join53 } from "path";
|
|
12910
12972
|
import { createHash as createHash13, createPublicKey as createPublicKey4, verify as verify3 } from "crypto";
|
|
12911
12973
|
function pubFor(kid, given) {
|
|
12912
12974
|
if (given)
|
|
@@ -12946,7 +13008,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
12946
13008
|
const bound = receipt["events_sha256"];
|
|
12947
13009
|
if (typeof bound !== "string" || bound === createHash13("sha256").digest("hex"))
|
|
12948
13010
|
return null;
|
|
12949
|
-
const path =
|
|
13011
|
+
const path = join53(dirname24(receiptPath), "events.jsonl");
|
|
12950
13012
|
if (!existsSync33(path))
|
|
12951
13013
|
return "events.jsonl is missing";
|
|
12952
13014
|
const raw2 = readFileSync40(path, "utf8"), events2 = readEvents(path), lines = raw2.split(`
|
|
@@ -12965,7 +13027,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
12965
13027
|
return h.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
|
|
12966
13028
|
}
|
|
12967
13029
|
function checkLogSeal(receiptPath, hash, kid, given) {
|
|
12968
|
-
const path =
|
|
13030
|
+
const path = join53(dirname24(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
|
|
12969
13031
|
if (!events2.some((e) => e.type === "receipt.sealed" && e.data["receipt_sha256"] === hash))
|
|
12970
13032
|
return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
|
|
12971
13033
|
if (done < 0)
|
|
@@ -13042,8 +13104,8 @@ var init_verify_cmd = __esm(() => {
|
|
|
13042
13104
|
});
|
|
13043
13105
|
|
|
13044
13106
|
// src/server/app.ts
|
|
13045
|
-
import { existsSync as existsSync35, readFileSync as readFileSync43, statSync as
|
|
13046
|
-
import { join as
|
|
13107
|
+
import { existsSync as existsSync35, readFileSync as readFileSync43, statSync as statSync19 } from "fs";
|
|
13108
|
+
import { join as join56, resolve as resolve13, sep as sep14 } from "path";
|
|
13047
13109
|
|
|
13048
13110
|
// node_modules/hono/dist/request/constants.js
|
|
13049
13111
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -23292,7 +23354,7 @@ function mount20(ctx) {
|
|
|
23292
23354
|
// src/server/routes/verify.ts
|
|
23293
23355
|
import { readFileSync as readFileSync41, realpathSync as realpathSync20 } from "fs";
|
|
23294
23356
|
import { createPublicKey as createPublicKey5 } from "crypto";
|
|
23295
|
-
import { join as
|
|
23357
|
+
import { join as join54, sep as sep13 } from "path";
|
|
23296
23358
|
init_verify_cmd();
|
|
23297
23359
|
init_seal();
|
|
23298
23360
|
init_receipt_dsse();
|
|
@@ -23319,11 +23381,11 @@ function mount21(ctx) {
|
|
|
23319
23381
|
return done(404, "receipt not available", "not_found");
|
|
23320
23382
|
let runDir, file;
|
|
23321
23383
|
try {
|
|
23322
|
-
const root = realpathSync20(
|
|
23323
|
-
runDir = realpathSync20(
|
|
23324
|
-
if (runDir !==
|
|
23384
|
+
const root = realpathSync20(join54(repo.p, ".loki", "runs"));
|
|
23385
|
+
runDir = realpathSync20(join54(root, run2));
|
|
23386
|
+
if (runDir !== join54(root, run2))
|
|
23325
23387
|
return done(404, "receipt not found", "not_found");
|
|
23326
|
-
file = realpathSync20(
|
|
23388
|
+
file = realpathSync20(join54(runDir, "receipt.json"));
|
|
23327
23389
|
} catch {
|
|
23328
23390
|
return done(404, "receipt not found", "not_found");
|
|
23329
23391
|
}
|
|
@@ -23405,7 +23467,7 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
|
|
|
23405
23467
|
|
|
23406
23468
|
// src/server/legacy/shim.ts
|
|
23407
23469
|
import { existsSync as existsSync34, readFileSync as readFileSync42 } from "fs";
|
|
23408
|
-
import { join as
|
|
23470
|
+
import { join as join55 } from "path";
|
|
23409
23471
|
|
|
23410
23472
|
// src/server/legacy/routes.ts
|
|
23411
23473
|
var LEGACY_ROUTES = [
|
|
@@ -23777,7 +23839,7 @@ var logged = new Set;
|
|
|
23777
23839
|
var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
|
|
23778
23840
|
var NOT_SUPPORTED = "not yet supported by the Control Plane";
|
|
23779
23841
|
var repoVersion = () => {
|
|
23780
|
-
for (const f of [
|
|
23842
|
+
for (const f of [join55(import.meta.dir, "../../../../../VERSION")]) {
|
|
23781
23843
|
try {
|
|
23782
23844
|
if (existsSync34(f))
|
|
23783
23845
|
return readFileSync42(f, "utf8").trim();
|
|
@@ -23962,7 +24024,7 @@ function legacyShim(opts) {
|
|
|
23962
24024
|
|
|
23963
24025
|
// src/server/app.ts
|
|
23964
24026
|
var MAX_BODY2 = 1e6;
|
|
23965
|
-
var defaultUiDir = () => [
|
|
24027
|
+
var defaultUiDir = () => [join56(import.meta.dir, "../../ui/dist"), join56(import.meta.dir, "../ui/dist")].find((d) => existsSync35(join56(d, "index.html")));
|
|
23966
24028
|
function createApp(opts) {
|
|
23967
24029
|
const uiDir = opts.uiDir ?? defaultUiDir();
|
|
23968
24030
|
const { db, sqlite } = openDb(opts.dbPath);
|
|
@@ -23991,7 +24053,7 @@ function createApp(opts) {
|
|
|
23991
24053
|
await next();
|
|
23992
24054
|
});
|
|
23993
24055
|
const readInstalled = () => {
|
|
23994
|
-
for (const f of [process.env.LOKI_VERSION_FILE,
|
|
24056
|
+
for (const f of [process.env.LOKI_VERSION_FILE, join56(import.meta.dir, "../../../../VERSION")]) {
|
|
23995
24057
|
try {
|
|
23996
24058
|
if (f)
|
|
23997
24059
|
return readFileSync43(f, "utf8").trim() || "unknown";
|
|
@@ -24105,11 +24167,11 @@ function createApp(opts) {
|
|
|
24105
24167
|
return c.json({ error: "not found" }, 404);
|
|
24106
24168
|
const root = resolve13(uiDir);
|
|
24107
24169
|
const f = resolve13(root, `.${p}`);
|
|
24108
|
-
if (f.startsWith(root + sep14) && existsSync35(f) &&
|
|
24170
|
+
if (f.startsWith(root + sep14) && existsSync35(f) && statSync19(f).isFile())
|
|
24109
24171
|
return new Response(Bun.file(f));
|
|
24110
24172
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
24111
24173
|
return c.json({ error: "not found" }, 404);
|
|
24112
|
-
return new Response(Bun.file(
|
|
24174
|
+
return new Response(Bun.file(join56(root, "index.html")));
|
|
24113
24175
|
});
|
|
24114
24176
|
return { app, db, close: () => {
|
|
24115
24177
|
clearInterval(reconciler);
|