loki-mode 11.17.6 → 11.17.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/cost-summary.py +5 -2
  4. package/autonomy/lib/efficiency_cost.py +21 -1
  5. package/autonomy/lib/proof-generator.py +5 -0
  6. package/autonomy/lib/proof-template.html +21 -6
  7. package/autonomy/lib/trust_trajectory.py +11 -1
  8. package/autonomy/loki +42 -28
  9. package/completions/_loki +1 -0
  10. package/completions/loki.bash +1 -1
  11. package/dashboard/__init__.py +1 -1
  12. package/docs/CLI-REFERENCE.md +1 -1
  13. package/docs/INSTALLATION.md +1 -1
  14. package/docs/v10/BOARD.md +108 -4
  15. package/docs/v10/FAILURE-CLASSES.md +106 -2
  16. package/docs/v10/MODERNIZE.md +7 -1
  17. package/docs/v10/PROGRESS.md +10 -0
  18. package/loki-ts/dist/loki.js +1014 -999
  19. package/mcp/__init__.py +1 -1
  20. package/package.json +2 -2
  21. package/packages/control-plane/dist/ask-tools-server.js +218 -12
  22. package/packages/control-plane/dist/server.js +719 -593
  23. package/packages/control-plane/src/server/diffstat.ts +2 -2
  24. package/packages/control-plane/src/server/routes/checkpoints.ts +2 -2
  25. package/packages/control-plane/src/server/routes/integrations.ts +1 -1
  26. package/packages/control-plane/src/shipper/discover.ts +2 -2
  27. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  28. package/web-app/dist/assets/{AdminPage-CCedYmn3.js → AdminPage-CwtSZac4.js} +1 -1
  29. package/web-app/dist/assets/{Avatar-DMrDsuGe.js → Avatar-BfguNHDC.js} +1 -1
  30. package/web-app/dist/assets/{Badge-K4Ui2tJz.js → Badge-DQGEOIqb.js} +1 -1
  31. package/web-app/dist/assets/{Button-Bhjts5QZ.js → Button-CRb-wJga.js} +1 -1
  32. package/web-app/dist/assets/{CockpitPage-Be7sEVqh.js → CockpitPage-DnA9wewN.js} +1 -1
  33. package/web-app/dist/assets/{ComparePage-D4ty3jiF.js → ComparePage-DX6F_G0l.js} +1 -1
  34. package/web-app/dist/assets/{ErrorBoundary-Cmt2x_mL.js → ErrorBoundary-VVIdgfkb.js} +1 -1
  35. package/web-app/dist/assets/{EvidenceReceiptPanel-D2IXLnp9.js → EvidenceReceiptPanel-FxknNXxU.js} +1 -1
  36. package/web-app/dist/assets/{GitHubIssuesPanel-CyXitr6h.js → GitHubIssuesPanel-DqiraoJP.js} +1 -1
  37. package/web-app/dist/assets/{GitHubPRsPanel-RRM3H-xd.js → GitHubPRsPanel-BYkTsRfQ.js} +1 -1
  38. package/web-app/dist/assets/{HomePage-CMtrrgfs.js → HomePage-BjpWZdl4.js} +2 -2
  39. package/web-app/dist/assets/{LoginPage-BrzNhnMJ.js → LoginPage-DdBnFY4Y.js} +1 -1
  40. package/web-app/dist/assets/{MagicPage-D7VynOKM.js → MagicPage-ihQmO1wm.js} +1 -1
  41. package/web-app/dist/assets/{MetricsPage-DJ-gDbfP.js → MetricsPage-Dq5YARm1.js} +1 -1
  42. package/web-app/dist/assets/{NotFoundPage-BJh0XVTj.js → NotFoundPage-CLzwsmxk.js} +1 -1
  43. package/web-app/dist/assets/{ProjectPage-CAodVUpE.js → ProjectPage-Dm8X4ntm.js} +3 -3
  44. package/web-app/dist/assets/{ProjectsPage-m3siS0Rf.js → ProjectsPage-DI3PhBwa.js} +1 -1
  45. package/web-app/dist/assets/{SettingsPage-CFGgjOvy.js → SettingsPage-D3bL3Ll-.js} +1 -1
  46. package/web-app/dist/assets/{ShowcasePage-Dd9tpSKJ.js → ShowcasePage-ypNyQAKe.js} +1 -1
  47. package/web-app/dist/assets/{SystemSettingsPage-DXd0PtTI.js → SystemSettingsPage-a9KPi49-.js} +1 -1
  48. package/web-app/dist/assets/{TeamsPage-C5KaLIGW.js → TeamsPage-B2KmQjeS.js} +1 -1
  49. package/web-app/dist/assets/{TemplatesPage-CDbzE0ZZ.js → TemplatesPage-BnK5NB62.js} +1 -1
  50. package/web-app/dist/assets/{TerminalOutput-CKG79r_-.js → TerminalOutput-CYbPu51X.js} +1 -1
  51. package/web-app/dist/assets/{activity-BaQQRhDp.js → activity-DBIfCcER.js} +1 -1
  52. package/web-app/dist/assets/{bell-OeFqvU4e.js → bell-B9HN4QkY.js} +1 -1
  53. package/web-app/dist/assets/{bot-CSxaA0KU.js → bot-DamtEiBN.js} +1 -1
  54. package/web-app/dist/assets/{check-DJml2Xdn.js → check-DXifl-uv.js} +1 -1
  55. package/web-app/dist/assets/{chevron-left-DGnt-DtK.js → chevron-left-BrlJBb8m.js} +1 -1
  56. package/web-app/dist/assets/{circle-alert-BV5rVL7K.js → circle-alert-CVKCTAb9.js} +1 -1
  57. package/web-app/dist/assets/{clock-CZ7SvULz.js → clock-HQ6E5gSp.js} +1 -1
  58. package/web-app/dist/assets/{cloud-lkIzrZps.js → cloud-B15Ysqug.js} +1 -1
  59. package/web-app/dist/assets/{code-xml-DzA2wL8F.js → code-xml-hqFIp0_h.js} +1 -1
  60. package/web-app/dist/assets/{database-CLFG5upC.js → database-CcSm0M_K.js} +1 -1
  61. package/web-app/dist/assets/{dollar-sign-DgWePGsv.js → dollar-sign-acxpddMc.js} +1 -1
  62. package/web-app/dist/assets/{file-code-corner-DGQX2bmv.js → file-code-corner-B5IIv12W.js} +1 -1
  63. package/web-app/dist/assets/{file-plus-LkaXeYd6.js → file-plus-CkbMFWJb.js} +1 -1
  64. package/web-app/dist/assets/{globe-rSsEzPYv.js → globe-CWmZ3xTF.js} +1 -1
  65. package/web-app/dist/assets/{hammer-CPogONt9.js → hammer-BSaCsCAo.js} +1 -1
  66. package/web-app/dist/assets/{index-DpBLuMuz.js → index-BCf0fCNu.js} +3 -3
  67. package/web-app/dist/assets/{layers-CwFaqidn.js → layers-CL82nJ3b.js} +1 -1
  68. package/web-app/dist/assets/{loader-circle-C43izEm5.js → loader-circle-DBhm8R7M.js} +1 -1
  69. package/web-app/dist/assets/{lock-Bc_Uqxpp.js → lock-wWcqImfq.js} +1 -1
  70. package/web-app/dist/assets/{package-BM25lcR-.js → package-BaZa22IO.js} +1 -1
  71. package/web-app/dist/assets/{plus-D0xoiY6N.js → plus-TFOQPEeK.js} +1 -1
  72. package/web-app/dist/assets/{refresh-cw-COI1R5Oo.js → refresh-cw-BOKfYIta.js} +1 -1
  73. package/web-app/dist/assets/{rotate-ccw-BoNZx4xe.js → rotate-ccw-DrH5oGwW.js} +1 -1
  74. package/web-app/dist/assets/{scroll-text-Cakp8XHd.js → scroll-text-aY8_wIJd.js} +1 -1
  75. package/web-app/dist/assets/{server-CjfIlPmE.js → server-C6FQ01rB.js} +1 -1
  76. package/web-app/dist/assets/{shield-alert-BilhziJF.js → shield-alert-DurYyWUo.js} +1 -1
  77. package/web-app/dist/assets/{thumbs-up-CglMrtrt.js → thumbs-up-wUuSs67Q.js} +1 -1
  78. package/web-app/dist/assets/{trash-2-B6zVvnoG.js → trash-2-DAob0LKZ.js} +1 -1
  79. package/web-app/dist/assets/{trending-down-BVhwD9bt.js → trending-down-yKL9mp2O.js} +1 -1
  80. package/web-app/dist/assets/{trending-up-CVJ1ox6c.js → trending-up-BD55eCE3.js} +1 -1
  81. package/web-app/dist/assets/{upload-DmuR09WL.js → upload-0IJxnT31.js} +1 -1
  82. package/web-app/dist/assets/{usePolling-BTALfO91.js → usePolling-DuBiboP5.js} +1 -1
  83. package/web-app/dist/assets/{user-CRdHMZNH.js → user-BDw_rGaY.js} +1 -1
  84. package/web-app/dist/index.html +1 -1
@@ -150,11 +150,251 @@ var init_redact = __esm(() => {
150
150
  ];
151
151
  });
152
152
 
153
+ // ../../loki-ts/src/util/credential_env.ts
154
+ import { mkdtempSync, rmSync, statSync, lstatSync } from "fs";
155
+ import { tmpdir as tmpdir2 } from "os";
156
+ import { join as join4 } from "path";
157
+ import { randomBytes } from "crypto";
158
+ function withheldSentinel(fresh = false) {
159
+ if (fresh)
160
+ sentinel = null;
161
+ return sentinel ??= `${SENTINEL_PREFIX}${process.pid}${randomBytes(8).toString("hex")}INVALID`;
162
+ }
163
+ function removeConfigDir() {
164
+ if (configDir)
165
+ try {
166
+ rmSync(configDir, { recursive: true, force: true });
167
+ } catch {}
168
+ }
169
+ function emptyGhConfigDir(env = process.env) {
170
+ if (configDir && isDir(configDir))
171
+ return configDir;
172
+ const runTmp = env["LOKI_RUN_TMP"] ?? "";
173
+ const root = runTmp !== "" && isDir(runTmp) ? runTmp : tmpdir2();
174
+ try {
175
+ configDir = mkdtempSync(join4(root, "loki-gh-config-"));
176
+ } catch {
177
+ return null;
178
+ }
179
+ if (!exitHooked) {
180
+ exitHooked = true;
181
+ process.once("exit", removeConfigDir);
182
+ }
183
+ if (!sigtermHooked) {
184
+ sigtermHooked = true;
185
+ process.prependListener("SIGTERM", () => {
186
+ removeConfigDir();
187
+ if (process.listenerCount("SIGTERM") === 1)
188
+ process.exit(143);
189
+ });
190
+ }
191
+ return configDir;
192
+ }
193
+ function hardenCredentialEnv(env, fresh = false) {
194
+ const s = withheldSentinel(fresh);
195
+ for (const v of GITHUB_TOKEN_VARS)
196
+ env[v] = s;
197
+ const dir = emptyGhConfigDir(env);
198
+ if (dir)
199
+ env["GH_CONFIG_DIR"] = dir;
200
+ const existing = Number(env["GIT_CONFIG_COUNT"]);
201
+ const n2 = Number.isInteger(existing) && existing >= 0 ? existing : 0;
202
+ const alreadyLast = n2 > 0 && env[`GIT_CONFIG_KEY_${n2 - 1}`] === "credential.helper" && env[`GIT_CONFIG_VALUE_${n2 - 1}`] === "";
203
+ if (!alreadyLast) {
204
+ env[`GIT_CONFIG_KEY_${n2}`] = "credential.helper";
205
+ env[`GIT_CONFIG_VALUE_${n2}`] = "";
206
+ env["GIT_CONFIG_COUNT"] = String(n2 + 1);
207
+ }
208
+ const params = env["GIT_CONFIG_PARAMETERS"];
209
+ if (params && !params.trimEnd().endsWith("'credential.helper'=''"))
210
+ env["GIT_CONFIG_PARAMETERS"] = `${params} 'credential.helper'=''`;
211
+ env["GIT_TERMINAL_PROMPT"] = "0";
212
+ env["GCM_INTERACTIVE"] = "never";
213
+ }
214
+ var GITHUB_TOKEN_VARS, SENTINEL_PREFIX = "ghp_LOKIWITHHELDsentinel", sentinel = null, configDir = null, exitHooked = false, sigtermHooked = false, isDir = (p) => {
215
+ try {
216
+ return !lstatSync(p).isSymbolicLink() && statSync(p).isDirectory();
217
+ } catch {
218
+ return false;
219
+ }
220
+ };
221
+ var init_credential_env = __esm(() => {
222
+ GITHUB_TOKEN_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN"];
223
+ });
224
+
225
+ // ../../loki-ts/src/util/safe_git.ts
226
+ import { execFileSync, spawnSync } from "child_process";
227
+ function tokenFreeEnv(env = process.env) {
228
+ const out = { ...env };
229
+ for (const k of SECRET_VARS)
230
+ delete out[k];
231
+ hardenCredentialEnv(out);
232
+ return out;
233
+ }
234
+ function driverKeys(repoDir) {
235
+ const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", DRIVER_KEY_RE], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
236
+ if (r.error)
237
+ throw r.error;
238
+ if (r.status === 1)
239
+ return [];
240
+ if (r.status !== 0)
241
+ throw new Error(`safeGit: cannot enumerate git config drivers (status ${r.status})`);
242
+ const t = r.stdout.split("\x00"), keys = [];
243
+ for (let i = 0;i + 1 < t.length; i += 2) {
244
+ const k = t[i + 1].split(`
245
+ `)[0];
246
+ if (REPO_SCOPES.has(t[i]) && k)
247
+ keys.push(k);
248
+ }
249
+ return [...new Set(keys)];
250
+ }
251
+ function netCommandOverrides(repoDir, env) {
252
+ const r = spawnSync("git", [...CREDENTIAL_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", NET_CMD_KEY_RE], { cwd: repoDir, env: safeGitEnv(env, true), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
253
+ if (r.error)
254
+ throw r.error;
255
+ if (r.status === 1)
256
+ return { cfg: [], opts: [] };
257
+ if (r.status !== 0)
258
+ throw new Error(`safeGit: cannot enumerate git network config (status ${r.status})`);
259
+ const t = r.stdout.split("\x00"), all = [];
260
+ for (let i = 0;i + 1 < t.length; i += 2) {
261
+ const nl = t[i + 1].indexOf(`
262
+ `), k = nl < 0 ? t[i + 1] : t[i + 1].slice(0, nl), v = nl < 0 ? "" : t[i + 1].slice(nl + 1);
263
+ if (k)
264
+ all.push({ k, scope: t[i], value: v });
265
+ }
266
+ const tainted = new Set(all.filter((e) => LOCAL_SCOPES.has(e.scope)).map((e) => e.k));
267
+ const cfg = [], opts = [], packs = new Map;
268
+ const isCred = (k) => /^credential(\..*)?\.helper$/.test(k);
269
+ for (const k of tainted) {
270
+ const pack = PACK_OPTS.find((o) => o.re.test(k));
271
+ if (pack) {
272
+ if (!packs.has(pack.flag))
273
+ packs.set(pack.flag, all.find((e) => e.k === k && !LOCAL_SCOPES.has(e.scope) && e.value !== "")?.value ?? pack.dflt);
274
+ continue;
275
+ }
276
+ cfg.push("-c", `${k}=`);
277
+ if (!isCred(k)) {
278
+ for (const e of all)
279
+ if (e.k === k && !LOCAL_SCOPES.has(e.scope) && e.value !== "")
280
+ cfg.push("-c", `${k}=${e.value}`);
281
+ }
282
+ }
283
+ if ([...tainted].some(isCred)) {
284
+ for (const e of all)
285
+ if (isCred(e.k) && !LOCAL_SCOPES.has(e.scope) && e.value !== "")
286
+ cfg.push("-c", `${e.k}=${e.value}`);
287
+ }
288
+ for (const o of PACK_OPTS)
289
+ if (packs.has(o.flag))
290
+ opts.push({ flag: `${o.flag}${packs.get(o.flag)}`, cmds: o.cmds });
291
+ return { cfg, opts };
292
+ }
293
+ function cmdIndex(args) {
294
+ let i = 0;
295
+ while (i < args.length && args[i].startsWith("-"))
296
+ i += OPT_WITH_VALUE.has(args[i]) ? 2 : 1;
297
+ return i;
298
+ }
299
+ function injectPackOpts(args, opts) {
300
+ if (opts.length === 0)
301
+ return args;
302
+ const i = cmdIndex(args), cmd = args[i];
303
+ const extra = opts.filter((o) => cmd !== undefined && o.cmds.has(cmd)).map((o) => o.flag);
304
+ if (cmd !== undefined && !TRANSPORT_OR_LOCAL.has(cmd))
305
+ throw new Error(`safeGit: ${cmd} with allowToken is refused: the repo sets remote uploadpack/receivepack and the option cannot be pinned`);
306
+ return [...args.slice(0, i + 1), ...extra, ...args.slice(i + 1)];
307
+ }
308
+ function safeGitArgs(args, allowToken = false, repoDir, keep = {}, env = process.env) {
309
+ if (keep.userHooks && allowToken)
310
+ throw new Error("safeGit: userHooks with allowToken is refused (a hook would run holding the credential)");
311
+ const off = new Set([...keep.repoDrivers ? [ATTRS_OFF] : [], ...keep.userHooks ? [HOOKS_OFF, SIGN_OFF] : []]);
312
+ const cfg = [...allowToken ? CREDENTIAL_CONFIG : SAFE_GIT_CONFIG, ...DRIVER_CONFIG];
313
+ const flags = cfg.flatMap((v, i) => i % 2 === 1 && !off.has(v) ? [cfg[i - 1], v] : []);
314
+ const net = allowToken && repoDir ? netCommandOverrides(repoDir, env) : { cfg: [], opts: [] };
315
+ return [...flags, ...net.cfg, ...repoDir && !keep.repoDrivers ? driverKeys(repoDir).flatMap((k) => ["-c", `${k}=`]) : [], ...injectPackOpts(noExtDiff(args), net.opts)];
316
+ }
317
+ function noExtDiff(args) {
318
+ const i = cmdIndex(args), cmd = args[i];
319
+ if (cmd === undefined || !PATCH_CMDS.has(cmd))
320
+ return [...args];
321
+ const rest = args.slice(i + 1);
322
+ const end = rest.indexOf("--");
323
+ const opts = (end < 0 ? rest : rest.slice(0, end)).filter((a) => a !== "--ext-diff" && a !== "--textconv" && a !== "--no-ext-diff" && a !== "--no-textconv");
324
+ return [...args.slice(0, i + 1), "--no-ext-diff", "--no-textconv", ...opts, ...end < 0 ? [] : rest.slice(end)];
325
+ }
326
+ function safeGit(repoDir, args, opts = {}) {
327
+ const { env, allowToken, repoDrivers, userHooks, ...rest } = opts;
328
+ const out = execFileSync("git", safeGitArgs(args, allowToken, repoDir, { repoDrivers, userHooks }, env ?? process.env), { stdio: ["ignore", "pipe", "ignore"], ...rest, cwd: repoDir, env: safeGitEnv(env ?? process.env, allowToken), encoding: "utf8" });
329
+ return typeof out === "string" ? out : "";
330
+ }
331
+ function safeGitSpawn(repoDir, args, opts = {}) {
332
+ const { env, allowToken, repoDrivers, userHooks, ...rest } = opts;
333
+ let argv;
334
+ try {
335
+ argv = safeGitArgs(args, allowToken, repoDir, { repoDrivers, userHooks }, env ?? process.env);
336
+ } catch (e) {
337
+ return { pid: 0, output: [], stdout: "", stderr: "", status: null, signal: null, error: e };
338
+ }
339
+ return spawnSync("git", argv, { ...rest, cwd: repoDir, env: safeGitEnv(env ?? process.env, allowToken) });
340
+ }
341
+ async function safeGitRun(repoDir, args, opts = {}) {
342
+ let argv;
343
+ try {
344
+ argv = safeGitArgs(args, opts.allowToken, repoDir, { repoDrivers: opts.repoDrivers, userHooks: opts.userHooks }, opts.env ?? process.env);
345
+ } catch (e) {
346
+ return { stdout: "", stderr: String(e), exitCode: 128 };
347
+ }
348
+ let proc;
349
+ try {
350
+ proc = Bun.spawn({ cmd: ["git", ...argv], cwd: repoDir, env: safeGitEnv(opts.env ?? process.env, opts.allowToken), stdin: "ignore", stdout: "pipe", stderr: "pipe", signal: opts.signal });
351
+ } catch (e) {
352
+ return { stdout: "", stderr: String(e), exitCode: 127 };
353
+ }
354
+ let timer;
355
+ if (opts.timeoutMs && opts.timeoutMs > 0)
356
+ timer = setTimeout(() => {
357
+ try {
358
+ proc.kill("SIGKILL");
359
+ } catch {}
360
+ }, opts.timeoutMs);
361
+ try {
362
+ const [stdout, stderr, exitCode] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited]);
363
+ return { stdout, stderr, exitCode };
364
+ } finally {
365
+ if (timer)
366
+ clearTimeout(timer);
367
+ }
368
+ }
369
+ var SAFE_GIT_CONFIG, CREDENTIAL_CONFIG, DRIVER_CONFIG, ATTRS_OFF = "core.attributesFile=/dev/null", HOOKS_OFF = "core.hooksPath=/dev/null", SIGN_OFF = "commit.gpgSign=false", REPO_SCOPES, DRIVER_KEY_RE = "^(filter\\..*\\.(clean|smudge|process)|diff\\..*\\.(textconv|command))$", PATCH_CMDS, OPT_WITH_VALUE, SECRET_VARS, safeGitEnv = (base = process.env, allowToken = false) => {
370
+ const env = { ...allowToken ? base : tokenFreeEnv(base), GIT_CONFIG_NOSYSTEM: "1" };
371
+ delete env.GIT_ATTR_SOURCE;
372
+ delete env.GIT_EXTERNAL_DIFF;
373
+ return env;
374
+ }, NET_CMD_KEY_RE = "^(core\\.(sshcommand|gitproxy)|remote\\..*\\.(uploadpack|receivepack)|credential(\\..*)?\\.helper)$", LOCAL_SCOPES, PUSH_CMD, PACK_OPTS, TRANSPORT_OR_LOCAL;
375
+ var init_safe_git = __esm(() => {
376
+ init_credential_env();
377
+ SAFE_GIT_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "core.sshCommand=", "-c", "protocol.ext.allow=never", "-c", "credential.helper="];
378
+ CREDENTIAL_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "protocol.ext.allow=never"];
379
+ DRIVER_CONFIG = ["-c", "diff.external=", "-c", "commit.gpgSign=false", "-c", "core.attributesFile=/dev/null"];
380
+ REPO_SCOPES = new Set(["local", "worktree", "command"]);
381
+ PATCH_CMDS = new Set(["diff", "show", "log", "whatchanged"]);
382
+ OPT_WITH_VALUE = new Set(["-C", "-c", "--git-dir", "--work-tree", "--namespace", "--exec-path", "--config-env", "--attr-source"]);
383
+ SECRET_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "SSH_AUTH_SOCK"];
384
+ LOCAL_SCOPES = new Set(["local", "worktree"]);
385
+ PUSH_CMD = ["pu", "sh"].join("");
386
+ PACK_OPTS = [
387
+ { re: /\.uploadpack$/, dflt: "git-upload-pack", flag: "--upload-pack=", cmds: new Set(["fetch", "pull", "ls-remote", "clone"]) },
388
+ { re: /\.receivepack$/, dflt: "git-receive-pack", flag: "--receive-pack=", cmds: new Set([PUSH_CMD]) }
389
+ ];
390
+ TRANSPORT_OR_LOCAL = new Set(["fetch", "pull", "ls-remote", "clone", PUSH_CMD, "config", "rev-parse", "rev-list", "log", "show", "status", "diff", "for-each-ref", "cat-file", "symbolic-ref", "branch", "merge-base", "ls-files", "credential"]);
391
+ });
392
+
153
393
  // src/shipper/ship.ts
154
394
  import { createHash as createHash4 } from "crypto";
155
395
  import { existsSync as existsSync4, readFileSync as readFileSync3, realpathSync as realpathSync3, renameSync, writeFileSync as writeFileSync2 } from "fs";
156
396
  import { hostname } from "os";
157
- import { join as join6 } from "path";
397
+ import { join as join7 } from "path";
158
398
  function sourceId(repoDir) {
159
399
  let real2 = repoDir;
160
400
  try {
@@ -164,24 +404,24 @@ function sourceId(repoDir) {
164
404
  }
165
405
  function readShip(runDir, url) {
166
406
  try {
167
- const s = JSON.parse(readFileSync3(join6(runDir, "ship.json"), "utf8"));
407
+ const s = JSON.parse(readFileSync3(join7(runDir, "ship.json"), "utf8"));
168
408
  if (s.url === url && Number.isInteger(s.acked_seq))
169
409
  return { acked_seq: s.acked_seq, url };
170
410
  } catch {}
171
411
  return { acked_seq: -1, url };
172
412
  }
173
413
  function writeShip(runDir, s) {
174
- const tmp = join6(runDir, `ship.json.${process.pid}.tmp`);
414
+ const tmp = join7(runDir, `ship.json.${process.pid}.tmp`);
175
415
  writeFileSync2(tmp, JSON.stringify(s) + `
176
416
  `);
177
- renameSync(tmp, join6(runDir, "ship.json"));
417
+ renameSync(tmp, join7(runDir, "ship.json"));
178
418
  }
179
419
  async function shipRun(o) {
180
420
  const st = readShip(o.runDir, o.url);
181
- const all = readEvents(join6(o.runDir, "events.jsonl"));
421
+ const all = readEvents(join7(o.runDir, "events.jsonl"));
182
422
  let lines = 0;
183
423
  try {
184
- lines = readFileSync3(join6(o.runDir, "events.jsonl"), "utf8").split(`
424
+ lines = readFileSync3(join7(o.runDir, "events.jsonl"), "utf8").split(`
185
425
  `).filter((l) => l.trim() !== "").length;
186
426
  } catch {}
187
427
  const skipped = lines - all.length;
@@ -223,7 +463,7 @@ async function shipRun(o) {
223
463
  }
224
464
  return { ok: true, sent, acked_seq: st.acked_seq, pending: 0 };
225
465
  }
226
- var BATCH = 200, MAX_BYTES = 800000, redactDeep = (x) => typeof x === "string" ? redactSecrets(x) : Array.isArray(x) ? x.map(redactDeep) : x && typeof x === "object" ? Object.fromEntries(Object.entries(x).map(([k, v]) => [k, redactDeep(v)])) : x, redactEvent = (e) => ({ ...e, data: redactDeep(e.data) }), backoffMs = (failures, rnd = Math.random) => Math.min(60000, 1000 * 2 ** Math.max(0, failures - 1)) * (1 + 0.25 * rnd()), shipEnabled = (env) => env.LOKI_CONTROL_URL || null, hasSpool = (runDir) => existsSync4(join6(runDir, "events.jsonl"));
466
+ var BATCH = 200, MAX_BYTES = 800000, redactDeep = (x) => typeof x === "string" ? redactSecrets(x) : Array.isArray(x) ? x.map(redactDeep) : x && typeof x === "object" ? Object.fromEntries(Object.entries(x).map(([k, v]) => [k, redactDeep(v)])) : x, redactEvent = (e) => ({ ...e, data: redactDeep(e.data) }), backoffMs = (failures, rnd = Math.random) => Math.min(60000, 1000 * 2 ** Math.max(0, failures - 1)) * (1 + 0.25 * rnd()), shipEnabled = (env) => env.LOKI_CONTROL_URL || null, hasSpool = (runDir) => existsSync4(join7(runDir, "events.jsonl"));
227
467
  var init_ship = __esm(() => {
228
468
  init_events();
229
469
  init_redact();
@@ -231,7 +471,7 @@ var init_ship = __esm(() => {
231
471
 
232
472
  // src/shipper/backfill.ts
233
473
  import { readdirSync } from "fs";
234
- import { join as join7 } from "path";
474
+ import { join as join8 } from "path";
235
475
  async function backfill(o) {
236
476
  const env = o.env ?? process.env;
237
477
  const url = shipEnabled(env);
@@ -239,7 +479,7 @@ async function backfill(o) {
239
479
  return { runs: 0, sent: 0, failed: [] };
240
480
  const sleep = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
241
481
  const attempts = o.attempts ?? 3;
242
- const root = join7(o.repoDir, ".loki", "runs");
482
+ const root = join8(o.repoDir, ".loki", "runs");
243
483
  let ids = [];
244
484
  try {
245
485
  ids = readdirSync(root).sort();
@@ -250,7 +490,7 @@ async function backfill(o) {
250
490
  let runs2 = 0, sent = 0;
251
491
  const failed2 = [];
252
492
  for (const id of ids) {
253
- const runDir = join7(root, id);
493
+ const runDir = join8(root, id);
254
494
  if (!hasSpool(runDir))
255
495
  continue;
256
496
  runs2++;
@@ -274,8 +514,8 @@ var init_backfill = __esm(() => {
274
514
 
275
515
  // ../../loki-ts/src/util/run_pid.ts
276
516
  import { execFileSync as execFileSync2 } from "child_process";
277
- import { chmodSync as chmodSync2, readFileSync as readFileSync4, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync3 } from "fs";
278
- import { join as join8 } from "path";
517
+ import { chmodSync as chmodSync2, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
518
+ import { join as join9 } from "path";
279
519
  function processStartTime(pid) {
280
520
  if (!Number.isInteger(pid) || pid <= 1)
281
521
  return null;
@@ -311,18 +551,18 @@ function verifyRunPid(runDir, runId, startOf = processStartTime) {
311
551
  return { ok: false, reason: "the pid now belongs to a different process (start time differs)" };
312
552
  return { ok: true, pid: rec.pid };
313
553
  }
314
- var runPidPath = (runDir) => join8(runDir, "run.pid"), liveSessions;
554
+ var runPidPath = (runDir) => join9(runDir, "run.pid"), liveSessions;
315
555
  var init_run_pid = __esm(() => {
316
556
  liveSessions = new Set;
317
557
  });
318
558
 
319
559
  // src/shipper/watch.ts
320
- import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync } from "fs";
560
+ import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
321
561
  import { homedir as homedir4 } from "os";
322
- import { join as join10 } from "path";
562
+ import { join as join11 } from "path";
323
563
  function registryRepos(env) {
324
564
  try {
325
- const reg = JSON.parse(readFileSync5(join10(env.HOME || homedir4(), ".loki", "dashboard", "projects.json"), "utf8"));
565
+ const reg = JSON.parse(readFileSync5(join11(env.HOME || homedir4(), ".loki", "dashboard", "projects.json"), "utf8"));
326
566
  return Object.values(reg.projects ?? {}).map((p) => p.path).filter((p) => typeof p === "string" && p.startsWith("/"));
327
567
  } catch {
328
568
  return [];
@@ -335,14 +575,14 @@ var init_watch = __esm(() => {
335
575
  });
336
576
 
337
577
  // src/shipper/discover.ts
338
- import { readFileSync as readFileSync6, realpathSync as realpathSync5, statSync as statSync2 } from "fs";
339
- import { basename, dirname, join as join11, resolve as resolve2 } from "path";
578
+ import { readFileSync as readFileSync6, realpathSync as realpathSync5, statSync as statSync3 } from "fs";
579
+ import { basename, dirname, join as join12, resolve as resolve2 } from "path";
340
580
  function discoverLocalRepos(repoDir, env = process.env) {
341
581
  const out = new Map;
342
582
  for (const dir of [repoDir, ...registryRepos(env)]) {
343
583
  try {
344
584
  const real2 = realpathSync5(dir);
345
- if (!statSync2(real2).isDirectory())
585
+ if (!statSync3(real2).isDirectory())
346
586
  continue;
347
587
  const id = sourceId(real2);
348
588
  if (!out.has(id))
@@ -352,6 +592,7 @@ function discoverLocalRepos(repoDir, env = process.env) {
352
592
  return [...out.values()];
353
593
  }
354
594
  var init_discover = __esm(() => {
595
+ init_safe_git();
355
596
  init_ship();
356
597
  init_watch();
357
598
  });
@@ -7326,10 +7567,10 @@ var init_paths = __esm(() => {
7326
7567
  });
7327
7568
 
7328
7569
  // ../../loki-ts/src/util/receipt_signer.ts
7329
- import { createHash as createHash6, randomBytes as randomBytes2, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, sign, verify as verify2 } from "crypto";
7330
- import { chmodSync as chmodSync4, linkSync, mkdirSync as mkdirSync5, readdirSync as readdirSync9, readFileSync as readFileSync18, renameSync as renameSync4, statSync as statSync11, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "fs";
7570
+ import { createHash as createHash6, randomBytes as randomBytes3, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, sign, verify as verify2 } from "crypto";
7571
+ import { chmodSync as chmodSync4, linkSync, mkdirSync as mkdirSync5, readdirSync as readdirSync9, readFileSync as readFileSync18, renameSync as renameSync4, statSync as statSync12, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "fs";
7331
7572
  import { homedir as homedir8 } from "os";
7332
- import { dirname as dirname7, join as join26 } from "path";
7573
+ import { dirname as dirname7, join as join27 } from "path";
7333
7574
  function canonicalJson(x) {
7334
7575
  const walk = (v) => {
7335
7576
  if (Array.isArray(v))
@@ -7348,12 +7589,12 @@ function loadSigningKey(generate = true) {
7348
7589
  let pem = inline ?? "";
7349
7590
  if (!inline) {
7350
7591
  const given = process.env["LOKI_RECEIPT_SIGNING_KEY_FILE"]?.trim();
7351
- const file = given || join26(process.env["HOME"] || homedir8(), ".loki", "keys", RECEIPT_SIGNER_BASENAME);
7592
+ const file = given || join27(process.env["HOME"] || homedir8(), ".loki", "keys", RECEIPT_SIGNER_BASENAME);
7352
7593
  try {
7353
7594
  pem = readFileSync18(file);
7354
7595
  if (!given) {
7355
7596
  for (const [f, m] of [[file, 384], [dirname7(file), 448]])
7356
- if (statSync11(f).mode & 63)
7597
+ if (statSync12(f).mode & 63)
7357
7598
  chmodSync4(f, m);
7358
7599
  }
7359
7600
  } catch (e) {
@@ -7361,7 +7602,7 @@ function loadSigningKey(generate = true) {
7361
7602
  return null;
7362
7603
  mkdirSync5(dirname7(dirname7(file)), { recursive: true, mode: 448 });
7363
7604
  mkdirSync5(dirname7(file), { recursive: true, mode: 448 });
7364
- const tmp = `${file}.${randomBytes2(6).toString("hex")}.tmp`;
7605
+ const tmp = `${file}.${randomBytes3(6).toString("hex")}.tmp`;
7365
7606
  writeFileSync8(tmp, generateKeyPairSync("ed25519").privateKey.export({ type: "pkcs8", format: "pem" }), { flag: "wx", mode: 384 });
7366
7607
  try {
7367
7608
  linkSync(tmp, file);
@@ -7394,10 +7635,43 @@ var init_receipt_signer = () => {};
7394
7635
  // ../../loki-ts/src/engine10/registry.ts
7395
7636
  var init_registry = () => {};
7396
7637
 
7638
+ // ../../loki-ts/src/engine10/types.ts
7639
+ function pushArgv(a) {
7640
+ switch (a.cmd) {
7641
+ case "push-pr":
7642
+ return ["push-pr", a.repoDir, a.branch, a.title, a.bodyFile, a.draft ? "1" : "0"];
7643
+ case "comment":
7644
+ return ["comment", a.runId, a.prUrl, a.file];
7645
+ case "status":
7646
+ return ["status", a.sha, a.state, a.description];
7647
+ case "issue-comment":
7648
+ return a.update ? ["issue-comment", "--update", a.issueRef, a.bodyFile] : ["issue-comment", a.issueRef, a.bodyFile];
7649
+ }
7650
+ }
7651
+ function taskBlock(task) {
7652
+ return ["Task (untrusted, quoted verbatim):", "<<<TASK", task, "TASK"];
7653
+ }
7654
+ var STAGE_BUDGETS;
7655
+ var init_types = __esm(() => {
7656
+ STAGE_BUDGETS = {
7657
+ intake: { targetS: 15, limitS: 60 },
7658
+ plan: { targetS: 45, limitS: 90 },
7659
+ wall: { targetS: 45, limitS: 90 },
7660
+ implement: { targetS: 180, limitS: 480 },
7661
+ verify: { targetS: 60, limitS: 120 },
7662
+ fix: { targetS: 90, limitS: 180 },
7663
+ commit: { targetS: 5, limitS: 30 },
7664
+ seal: { targetS: 15, limitS: 60 },
7665
+ pr: { targetS: 15, limitS: 60 },
7666
+ deep: { targetS: null, limitS: 2700 }
7667
+ };
7668
+ });
7669
+
7397
7670
  // ../../loki-ts/src/engine10/output.ts
7398
7671
  var init_output = __esm(() => {
7399
7672
  init_registry();
7400
7673
  init_redact();
7674
+ init_types();
7401
7675
  });
7402
7676
 
7403
7677
  // ../../loki-ts/src/util/atomic.ts
@@ -7405,13 +7679,13 @@ import {
7405
7679
  closeSync as closeSync5,
7406
7680
  fstatSync as fstatSync4,
7407
7681
  fsyncSync as fsyncSync2,
7408
- lstatSync as lstatSync4,
7682
+ lstatSync as lstatSync5,
7409
7683
  mkdirSync as mkdirSync6,
7410
7684
  openSync as openSync5,
7411
7685
  readSync as readSync4,
7412
7686
  renameSync as renameSync5,
7413
- rmSync as rmSync4,
7414
- statSync as statSync12,
7687
+ rmSync as rmSync5,
7688
+ statSync as statSync13,
7415
7689
  unlinkSync as unlinkSync4,
7416
7690
  writeFileSync as writeFileSync9,
7417
7691
  writeSync as writeSync3
@@ -7455,184 +7729,6 @@ var init_atomic = __esm(() => {
7455
7729
  _appendChains = new Map;
7456
7730
  });
7457
7731
 
7458
- // ../../loki-ts/src/util/credential_env.ts
7459
- import { mkdtempSync as mkdtempSync2, rmSync as rmSync5, statSync as statSync13, lstatSync as lstatSync5 } from "fs";
7460
- import { tmpdir as tmpdir3 } from "os";
7461
- import { join as join27 } from "path";
7462
- import { randomBytes as randomBytes3 } from "crypto";
7463
- function withheldSentinel(fresh = false) {
7464
- if (fresh)
7465
- sentinel = null;
7466
- return sentinel ??= `${SENTINEL_PREFIX}${process.pid}${randomBytes3(8).toString("hex")}INVALID`;
7467
- }
7468
- function removeConfigDir() {
7469
- if (configDir)
7470
- try {
7471
- rmSync5(configDir, { recursive: true, force: true });
7472
- } catch {}
7473
- }
7474
- function emptyGhConfigDir(env = process.env) {
7475
- if (configDir && isDir(configDir))
7476
- return configDir;
7477
- const runTmp = env["LOKI_RUN_TMP"] ?? "";
7478
- const root = runTmp !== "" && isDir(runTmp) ? runTmp : tmpdir3();
7479
- try {
7480
- configDir = mkdtempSync2(join27(root, "loki-gh-config-"));
7481
- } catch {
7482
- return null;
7483
- }
7484
- if (!exitHooked) {
7485
- exitHooked = true;
7486
- process.once("exit", removeConfigDir);
7487
- }
7488
- if (!sigtermHooked) {
7489
- sigtermHooked = true;
7490
- process.prependListener("SIGTERM", () => {
7491
- removeConfigDir();
7492
- if (process.listenerCount("SIGTERM") === 1)
7493
- process.exit(143);
7494
- });
7495
- }
7496
- return configDir;
7497
- }
7498
- function hardenCredentialEnv(env, fresh = false) {
7499
- const s = withheldSentinel(fresh);
7500
- for (const v of GITHUB_TOKEN_VARS)
7501
- env[v] = s;
7502
- const dir = emptyGhConfigDir(env);
7503
- if (dir)
7504
- env["GH_CONFIG_DIR"] = dir;
7505
- const existing = Number(env["GIT_CONFIG_COUNT"]);
7506
- const n2 = Number.isInteger(existing) && existing >= 0 ? existing : 0;
7507
- const alreadyLast = n2 > 0 && env[`GIT_CONFIG_KEY_${n2 - 1}`] === "credential.helper" && env[`GIT_CONFIG_VALUE_${n2 - 1}`] === "";
7508
- if (!alreadyLast) {
7509
- env[`GIT_CONFIG_KEY_${n2}`] = "credential.helper";
7510
- env[`GIT_CONFIG_VALUE_${n2}`] = "";
7511
- env["GIT_CONFIG_COUNT"] = String(n2 + 1);
7512
- }
7513
- const params = env["GIT_CONFIG_PARAMETERS"];
7514
- if (params && !params.trimEnd().endsWith("'credential.helper'=''"))
7515
- env["GIT_CONFIG_PARAMETERS"] = `${params} 'credential.helper'=''`;
7516
- env["GIT_TERMINAL_PROMPT"] = "0";
7517
- env["GCM_INTERACTIVE"] = "never";
7518
- }
7519
- var GITHUB_TOKEN_VARS, SENTINEL_PREFIX = "ghp_LOKIWITHHELDsentinel", sentinel = null, configDir = null, exitHooked = false, sigtermHooked = false, isDir = (p) => {
7520
- try {
7521
- return !lstatSync5(p).isSymbolicLink() && statSync13(p).isDirectory();
7522
- } catch {
7523
- return false;
7524
- }
7525
- };
7526
- var init_credential_env = __esm(() => {
7527
- GITHUB_TOKEN_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN"];
7528
- });
7529
-
7530
- // ../../loki-ts/src/util/safe_git.ts
7531
- import { execFileSync as execFileSync4, spawnSync } from "child_process";
7532
- function tokenFreeEnv(env = process.env) {
7533
- const out2 = { ...env };
7534
- for (const k of SECRET_VARS)
7535
- delete out2[k];
7536
- hardenCredentialEnv(out2);
7537
- return out2;
7538
- }
7539
- function driverKeys(repoDir) {
7540
- const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", DRIVER_KEY_RE], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
7541
- if (r.error)
7542
- throw r.error;
7543
- if (r.status === 1)
7544
- return [];
7545
- if (r.status !== 0)
7546
- throw new Error(`safeGit: cannot enumerate git config drivers (status ${r.status})`);
7547
- const t = r.stdout.split("\x00"), keys = [];
7548
- for (let i = 0;i + 1 < t.length; i += 2) {
7549
- const k = t[i + 1].split(`
7550
- `)[0];
7551
- if (REPO_SCOPES.has(t[i]) && k)
7552
- keys.push(k);
7553
- }
7554
- return [...new Set(keys)];
7555
- }
7556
- function safeGitArgs(args, allowToken = false, repoDir, keep = {}) {
7557
- if (keep.userHooks && allowToken)
7558
- throw new Error("safeGit: userHooks with allowToken is refused (a hook would run holding the credential)");
7559
- const off = new Set([...keep.repoDrivers ? [ATTRS_OFF] : [], ...keep.userHooks ? [HOOKS_OFF, SIGN_OFF] : []]);
7560
- const cfg = [...allowToken ? CREDENTIAL_CONFIG : SAFE_GIT_CONFIG, ...DRIVER_CONFIG];
7561
- const flags = cfg.flatMap((v, i) => i % 2 === 1 && !off.has(v) ? [cfg[i - 1], v] : []);
7562
- return [...flags, ...repoDir && !keep.repoDrivers ? driverKeys(repoDir).flatMap((k) => ["-c", `${k}=`]) : [], ...noExtDiff(args)];
7563
- }
7564
- function noExtDiff(args) {
7565
- let i = 0;
7566
- while (i < args.length && args[i].startsWith("-"))
7567
- i += OPT_WITH_VALUE.has(args[i]) ? 2 : 1;
7568
- const cmd = args[i];
7569
- if (cmd === undefined || !PATCH_CMDS.has(cmd))
7570
- return [...args];
7571
- const rest = args.slice(i + 1);
7572
- const end = rest.indexOf("--");
7573
- const opts = (end < 0 ? rest : rest.slice(0, end)).filter((a) => a !== "--ext-diff" && a !== "--textconv" && a !== "--no-ext-diff" && a !== "--no-textconv");
7574
- return [...args.slice(0, i + 1), "--no-ext-diff", "--no-textconv", ...opts, ...end < 0 ? [] : rest.slice(end)];
7575
- }
7576
- function safeGit(repoDir, args, opts = {}) {
7577
- const { env, allowToken, repoDrivers, userHooks, ...rest } = opts;
7578
- const out2 = execFileSync4("git", safeGitArgs(args, allowToken, repoDir, { repoDrivers, userHooks }), { stdio: ["ignore", "pipe", "ignore"], ...rest, cwd: repoDir, env: safeGitEnv(env ?? process.env, allowToken), encoding: "utf8" });
7579
- return typeof out2 === "string" ? out2 : "";
7580
- }
7581
- function safeGitSpawn(repoDir, args, opts = {}) {
7582
- const { env, allowToken, repoDrivers, userHooks, ...rest } = opts;
7583
- let argv;
7584
- try {
7585
- argv = safeGitArgs(args, allowToken, repoDir, { repoDrivers, userHooks });
7586
- } catch (e) {
7587
- return { pid: 0, output: [], stdout: "", stderr: "", status: null, signal: null, error: e };
7588
- }
7589
- return spawnSync("git", argv, { ...rest, cwd: repoDir, env: safeGitEnv(env ?? process.env, allowToken) });
7590
- }
7591
- async function safeGitRun(repoDir, args, opts = {}) {
7592
- let argv;
7593
- try {
7594
- argv = safeGitArgs(args, opts.allowToken, repoDir, { repoDrivers: opts.repoDrivers, userHooks: opts.userHooks });
7595
- } catch (e) {
7596
- return { stdout: "", stderr: String(e), exitCode: 128 };
7597
- }
7598
- let proc;
7599
- try {
7600
- proc = Bun.spawn({ cmd: ["git", ...argv], cwd: repoDir, env: safeGitEnv(opts.env ?? process.env, opts.allowToken), stdin: "ignore", stdout: "pipe", stderr: "pipe", signal: opts.signal });
7601
- } catch (e) {
7602
- return { stdout: "", stderr: String(e), exitCode: 127 };
7603
- }
7604
- let timer;
7605
- if (opts.timeoutMs && opts.timeoutMs > 0)
7606
- timer = setTimeout(() => {
7607
- try {
7608
- proc.kill("SIGKILL");
7609
- } catch {}
7610
- }, opts.timeoutMs);
7611
- try {
7612
- const [stdout, stderr, exitCode] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited]);
7613
- return { stdout, stderr, exitCode };
7614
- } finally {
7615
- if (timer)
7616
- clearTimeout(timer);
7617
- }
7618
- }
7619
- var SAFE_GIT_CONFIG, CREDENTIAL_CONFIG, DRIVER_CONFIG, ATTRS_OFF = "core.attributesFile=/dev/null", HOOKS_OFF = "core.hooksPath=/dev/null", SIGN_OFF = "commit.gpgSign=false", REPO_SCOPES, DRIVER_KEY_RE = "^(filter\\..*\\.(clean|smudge|process)|diff\\..*\\.(textconv|command))$", PATCH_CMDS, OPT_WITH_VALUE, SECRET_VARS, safeGitEnv = (base = process.env, allowToken = false) => {
7620
- const env = { ...allowToken ? base : tokenFreeEnv(base), GIT_CONFIG_NOSYSTEM: "1" };
7621
- delete env.GIT_ATTR_SOURCE;
7622
- delete env.GIT_EXTERNAL_DIFF;
7623
- return env;
7624
- };
7625
- var init_safe_git = __esm(() => {
7626
- init_credential_env();
7627
- SAFE_GIT_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "core.sshCommand=", "-c", "protocol.ext.allow=never", "-c", "credential.helper="];
7628
- CREDENTIAL_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "protocol.ext.allow=never"];
7629
- DRIVER_CONFIG = ["-c", "diff.external=", "-c", "commit.gpgSign=false", "-c", "core.attributesFile=/dev/null"];
7630
- REPO_SCOPES = new Set(["local", "worktree", "command"]);
7631
- PATCH_CMDS = new Set(["diff", "show", "log", "whatchanged"]);
7632
- OPT_WITH_VALUE = new Set(["-C", "-c", "--git-dir", "--work-tree", "--namespace", "--exec-path", "--config-env", "--attr-source"]);
7633
- SECRET_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "SSH_AUTH_SOCK"];
7634
- });
7635
-
7636
7732
  // ../../loki-ts/src/util/engine_origin.ts
7637
7733
  function readOriginUrl(repoDir) {
7638
7734
  try {
@@ -8060,38 +8156,6 @@ var init_budget = __esm(() => {
8060
8156
  PRICING = Object.freeze(_loadPricing());
8061
8157
  });
8062
8158
 
8063
- // ../../loki-ts/src/engine10/types.ts
8064
- function pushArgv(a) {
8065
- switch (a.cmd) {
8066
- case "push-pr":
8067
- return ["push-pr", a.repoDir, a.branch, a.title, a.bodyFile, a.draft ? "1" : "0"];
8068
- case "comment":
8069
- return ["comment", a.runId, a.prUrl, a.file];
8070
- case "status":
8071
- return ["status", a.sha, a.state, a.description];
8072
- case "issue-comment":
8073
- return a.update ? ["issue-comment", "--update", a.issueRef, a.bodyFile] : ["issue-comment", a.issueRef, a.bodyFile];
8074
- }
8075
- }
8076
- function taskBlock(task) {
8077
- return ["Task (untrusted, quoted verbatim):", "<<<TASK", task, "TASK"];
8078
- }
8079
- var STAGE_BUDGETS;
8080
- var init_types = __esm(() => {
8081
- STAGE_BUDGETS = {
8082
- intake: { targetS: 15, limitS: 60 },
8083
- plan: { targetS: 45, limitS: 90 },
8084
- wall: { targetS: 45, limitS: 90 },
8085
- implement: { targetS: 180, limitS: 480 },
8086
- verify: { targetS: 60, limitS: 120 },
8087
- fix: { targetS: 90, limitS: 180 },
8088
- commit: { targetS: 5, limitS: 30 },
8089
- seal: { targetS: 15, limitS: 60 },
8090
- pr: { targetS: 15, limitS: 60 },
8091
- deep: { targetS: null, limitS: 2700 }
8092
- };
8093
- });
8094
-
8095
8159
  // ../../loki-ts/src/runner/router/decision.ts
8096
8160
  var init_decision = () => {};
8097
8161
 
@@ -8801,16 +8865,25 @@ var init_scope = __esm(() => {
8801
8865
  dropped = new WeakMap;
8802
8866
  });
8803
8867
 
8804
- // ../../loki-ts/src/engine10/testmap.ts
8805
- import { basename as basename9, extname, join as join37, relative, sep as sep10 } from "path";
8868
+ // ../../loki-ts/src/util/test_file_text.ts
8869
+ import { basename as basename9 } from "path";
8806
8870
  function isTestFile(rel) {
8807
8871
  const name = basename9(rel);
8808
8872
  return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
8809
8873
  }
8810
- var SKIP_DIRS, JS_TEST_RE, PY_TEST_RE, GO_TEST_RE;
8874
+ var JS_TEST_RE, PY_TEST_RE, GO_TEST_RE;
8875
+ var init_test_file_text = __esm(() => {
8876
+ JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
8877
+ PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
8878
+ GO_TEST_RE = /_test\.go$/;
8879
+ });
8880
+
8881
+ // ../../loki-ts/src/engine10/testmap.ts
8882
+ var SKIP_DIRS;
8811
8883
  var init_testmap = __esm(() => {
8812
8884
  init_resolve();
8813
8885
  init_scope();
8886
+ init_test_file_text();
8814
8887
  SKIP_DIRS = new Set([
8815
8888
  ".git",
8816
8889
  "node_modules",
@@ -8826,14 +8899,11 @@ var init_testmap = __esm(() => {
8826
8899
  ".loki",
8827
8900
  ".next"
8828
8901
  ]);
8829
- JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
8830
- PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
8831
- GO_TEST_RE = /_test\.go$/;
8832
8902
  });
8833
8903
 
8834
8904
  // ../../loki-ts/src/util/check_result.ts
8835
8905
  import { mkdirSync as mkdirSync13, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as writeFileSync16 } from "fs";
8836
- import { basename as basename10, join as join38 } from "path";
8906
+ import { basename as basename10, join as join37 } from "path";
8837
8907
  function plainTestEnv(base = process.env) {
8838
8908
  const e = {};
8839
8909
  for (const [k, v] of Object.entries(tokenFreeEnv(base)))
@@ -9128,7 +9198,7 @@ function diffFiles(repoDir, baseSha) {
9128
9198
  return f;
9129
9199
  let n2 = 0;
9130
9200
  try {
9131
- n2 = readFileSync28(join38(repoDir, path), "utf8").split(`
9201
+ n2 = readFileSync28(join37(repoDir, path), "utf8").split(`
9132
9202
  `).length;
9133
9203
  } catch {}
9134
9204
  return { path, added: n2, deleted: 0, status: "added" };
@@ -9136,7 +9206,7 @@ function diffFiles(repoDir, baseSha) {
9136
9206
  }
9137
9207
  function recordRisk(repoDir, a) {
9138
9208
  try {
9139
- const dir = join38(repoDir, ".loki", "state"), p = join38(dir, "risk-tier.json");
9209
+ const dir = join37(repoDir, ".loki", "state"), p = join37(dir, "risk-tier.json");
9140
9210
  mkdirSync13(dir, { recursive: true });
9141
9211
  writeFileSync16(`${p}.tmp`, JSON.stringify(a, null, 2) + `
9142
9212
  `);
@@ -9196,7 +9266,7 @@ var init_state = __esm(() => {
9196
9266
 
9197
9267
  // ../../loki-ts/src/runner/repo_profile.ts
9198
9268
  import { existsSync as existsSync22, readFileSync as readFileSync29, mkdirSync as mkdirSync14, readdirSync as readdirSync13, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
9199
- import { basename as basename11, join as join39, resolve as resolve13, isAbsolute as isAbsolute2 } from "path";
9269
+ import { basename as basename11, join as join38, resolve as resolve13, isAbsolute as isAbsolute2 } from "path";
9200
9270
  function loadProfile(repoDir) {
9201
9271
  try {
9202
9272
  const p = JSON.parse(readFileSync29(commandProfilePath(repoDir), "utf8"));
@@ -9230,7 +9300,7 @@ function attributeFullSuite(repoDir, baseSha, full, blocked, changed) {
9230
9300
  const block = new Set(blocked);
9231
9301
  return attribute(repoDir, baseSha, bad.map((c) => ({ name: c.name, ...c.ids ? { ids: c.ids } : {}, eligible: (c.ids ?? []).every((i) => !block.has(i) && !changed.some((f) => i.includes(f))) })));
9232
9302
  }
9233
- var commandProfilePath = (repoDir) => join39(repoDir, ".loki", "state", "repo-profile.json");
9303
+ var commandProfilePath = (repoDir) => join38(repoDir, ".loki", "state", "repo-profile.json");
9234
9304
  var init_repo_profile = __esm(() => {
9235
9305
  init_failures();
9236
9306
  init_check_result();
@@ -9266,12 +9336,12 @@ var init_context = __esm(() => {
9266
9336
  // ../../loki-ts/src/util/steer.ts
9267
9337
  import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync14, lstatSync as lstatSync9, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync30, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync23 } from "fs";
9268
9338
  import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
9269
- import { basename as basename12, join as join40 } from "path";
9339
+ import { basename as basename12, join as join39 } from "path";
9270
9340
  function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
9271
9341
  for (let i = 0;; i++) {
9272
9342
  const name = i === 0 ? `${prefix}.md` : `${prefix}-${i}.md`;
9273
9343
  try {
9274
- link(src, join40(logs, name));
9344
+ link(src, join39(logs, name));
9275
9345
  } catch (e) {
9276
9346
  const code = e.code;
9277
9347
  if (code === "EEXIST")
@@ -9279,7 +9349,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
9279
9349
  if (code !== "EPERM" && code !== "ENOTSUP" && code !== "EXDEV" && code !== "EMLINK")
9280
9350
  throw e;
9281
9351
  const name2 = `${prefix}-${randomBytes4(4).toString("hex")}.md`;
9282
- renameSync10(src, join40(logs, name2));
9352
+ renameSync10(src, join39(logs, name2));
9283
9353
  onLinked?.(name2);
9284
9354
  return name2;
9285
9355
  }
@@ -9298,7 +9368,7 @@ function orphanAlreadyArchived(logs, claim) {
9298
9368
  if (!/^human-input-.*\.md$/.test(a))
9299
9369
  continue;
9300
9370
  try {
9301
- const s = statSync15(join40(logs, a));
9371
+ const s = statSync15(join39(logs, a));
9302
9372
  if (s.ino !== c.ino || s.dev !== c.dev)
9303
9373
  continue;
9304
9374
  if (/^human-input-(ORPHAN|REJECTED)-/.test(a) || existsSync23(appliedMarker(logs, a)))
@@ -9318,7 +9388,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
9318
9388
  for (const n2 of names)
9319
9389
  if (n2.startsWith(".applied-") && !present.has(n2.slice(".applied-".length))) {
9320
9390
  try {
9321
- unlinkSync5(join40(logs, n2));
9391
+ unlinkSync5(join39(logs, n2));
9322
9392
  } catch {}
9323
9393
  }
9324
9394
  for (const n2 of names) {
@@ -9335,7 +9405,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
9335
9405
  if (alive) {
9336
9406
  let ageMs = 0;
9337
9407
  try {
9338
- ageMs = nowMs - statSync15(join40(logs, n2)).mtimeMs;
9408
+ ageMs = nowMs - statSync15(join39(logs, n2)).mtimeMs;
9339
9409
  } catch {
9340
9410
  continue;
9341
9411
  }
@@ -9343,11 +9413,11 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
9343
9413
  continue;
9344
9414
  }
9345
9415
  try {
9346
- if (orphanAlreadyArchived(logs, join40(logs, n2))) {
9347
- unlinkSync5(join40(logs, n2));
9416
+ if (orphanAlreadyArchived(logs, join39(logs, n2))) {
9417
+ unlinkSync5(join39(logs, n2));
9348
9418
  continue;
9349
9419
  }
9350
- archiveTo(logs, `human-input-ORPHAN-${stamp2}`, join40(logs, n2), link);
9420
+ archiveTo(logs, `human-input-ORPHAN-${stamp2}`, join39(logs, n2), link);
9351
9421
  unapplied("orphaned claim");
9352
9422
  } catch (e) {
9353
9423
  if (e.code === "ENOENT")
@@ -9359,17 +9429,17 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
9359
9429
  function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, hooks2) {
9360
9430
  if (/^(0|false)$/i.test(env.LOKI_PROMPT_INJECTION ?? ""))
9361
9431
  return null;
9362
- const f = join40(repoDir, ".loki", "HUMAN_INPUT.md");
9432
+ const f = join39(repoDir, ".loki", "HUMAN_INPUT.md");
9363
9433
  const unapplied = (reason) => {
9364
9434
  sink?.push({ rev: 0, source: null, actor: null, sha: "", at: now2().getTime(), unapplied: true, reason });
9365
9435
  };
9366
9436
  let fd = -1, claimed = "";
9367
9437
  try {
9368
- const logs = join40(repoDir, ".loki", "logs");
9438
+ const logs = join39(repoDir, ".loki", "logs");
9369
9439
  mkdirSync15(logs, { recursive: true });
9370
9440
  const stamp2 = now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "");
9371
9441
  sweepOrphans(logs, stamp2, unapplied, hooks2?.link, now2().getTime());
9372
- claimed = join40(logs, `.claim-${process.pid}-${randomBytes4(6).toString("hex")}`);
9442
+ claimed = join39(logs, `.claim-${process.pid}-${randomBytes4(6).toString("hex")}`);
9373
9443
  try {
9374
9444
  renameSync10(f, claimed);
9375
9445
  } catch (e) {
@@ -9460,7 +9530,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
9460
9530
  } catch {
9461
9531
  if (claimed) {
9462
9532
  try {
9463
- archiveTo(join40(repoDir, ".loki", "logs"), `human-input-${now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "")}`, claimed, hooks2?.link);
9533
+ archiveTo(join39(repoDir, ".loki", "logs"), `human-input-${now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "")}`, claimed, hooks2?.link);
9464
9534
  unapplied("logs dir unwritable or file unreadable");
9465
9535
  } catch {
9466
9536
  unapplied(`steer stranded at .loki/logs/${basename12(claimed)}`);
@@ -9479,7 +9549,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
9479
9549
  }
9480
9550
  }
9481
9551
  function recordRevisions(repoDir, text2, archived, at) {
9482
- const file = join40(repoDir, ".loki", "intent-revisions.jsonl");
9552
+ const file = join39(repoDir, ".loki", "intent-revisions.jsonl");
9483
9553
  let last = 0;
9484
9554
  try {
9485
9555
  for (const l of readFileSync30(file, "utf8").split(`
@@ -9536,7 +9606,7 @@ function staleAtSeal(repoDir, ctx) {
9536
9606
  const frozen = ctx.outputs === undefined || ctx.outputs().wall !== undefined || ctx.wallSealed === true;
9537
9607
  return [...new Set([...staleWallRevisions(ctx.intentRevisions, frozen ? ctx.timeline : []), ...late])];
9538
9608
  }
9539
- var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) => join40(logs, `.applied-${archive}`), REV_HDR, STEER_REMEDY;
9609
+ var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) => join39(logs, `.applied-${archive}`), REV_HDR, STEER_REMEDY;
9540
9610
  var init_steer = __esm(() => {
9541
9611
  init_context();
9542
9612
  STEER_MAX_BYTES = 1024 * 1024;
@@ -9599,18 +9669,18 @@ var init_seal_drift = __esm(() => {
9599
9669
  });
9600
9670
 
9601
9671
  // ../../loki-ts/src/util/spec_file.ts
9602
- import { isAbsolute as isAbsolute3, join as join41, relative as relative2 } from "path";
9672
+ import { isAbsolute as isAbsolute3, join as join40, relative } from "path";
9603
9673
  function specReceiptBlock(env) {
9604
9674
  const { LOKI_E10_SPEC_PATH: p, LOKI_E10_SPEC_SHA256: sha2 } = env;
9605
9675
  if (!p || !sha2)
9606
9676
  return {};
9607
- const rel = isAbsolute3(p) && env.LOKI_E10_REPO_DIR ? relative2(env.LOKI_E10_REPO_DIR, p) : p;
9677
+ const rel = isAbsolute3(p) && env.LOKI_E10_REPO_DIR ? relative(env.LOKI_E10_REPO_DIR, p) : p;
9608
9678
  return { spec: { path: rel, sha256: sha2 } };
9609
9679
  }
9610
9680
  var SPEC_DIR;
9611
9681
  var init_spec_file = __esm(() => {
9612
9682
  init_types();
9613
- SPEC_DIR = join41(".loki", "specs");
9683
+ SPEC_DIR = join40(".loki", "specs");
9614
9684
  });
9615
9685
 
9616
9686
  // ../../loki-ts/src/engine10/pr_body.ts
@@ -9632,9 +9702,9 @@ var init_run_cap = __esm(() => {
9632
9702
  // ../../loki-ts/src/util/mutation_proof.ts
9633
9703
  import { existsSync as existsSync24, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync31, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
9634
9704
  import { tmpdir as tmpdir4 } from "os";
9635
- import { basename as basename13, dirname as dirname13, isAbsolute as isAbsolute4, join as join42, relative as relative3 } from "path";
9705
+ import { basename as basename13, dirname as dirname13, isAbsolute as isAbsolute4, join as join41, relative as relative2 } from "path";
9636
9706
  function mutationProof(i) {
9637
- const rels = i.wallFiles.map((f) => isAbsolute4(f.path) ? relative3(i.repoDir, f.path) : f.path);
9707
+ const rels = i.wallFiles.map((f) => isAbsolute4(f.path) ? relative2(i.repoDir, f.path) : f.path);
9638
9708
  if (rels.length === 0)
9639
9709
  return np("no Wall tests");
9640
9710
  const tests = rels.flatMap((rel) => {
@@ -9650,25 +9720,25 @@ function mutationProof(i) {
9650
9720
  const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
9651
9721
  let parent = null, wt = null, added = false;
9652
9722
  try {
9653
- parent = mkdtempSync3(join42(tmpdir4(), "loki-mutproof-"));
9654
- wt = join42(parent, "wt");
9723
+ parent = mkdtempSync3(join41(tmpdir4(), "loki-mutproof-"));
9724
+ wt = join41(parent, "wt");
9655
9725
  const add3 = git(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
9656
9726
  added = existsSync24(wt) || add3.status === 0;
9657
9727
  if (add3.status !== 0)
9658
9728
  return np("could not create the base worktree");
9659
9729
  for (const rel of rels) {
9660
- const sealed = join42(i.runDir, "wall", basename13(rel)), src = existsSync24(sealed) ? sealed : join42(i.repoDir, rel);
9730
+ const sealed = join41(i.runDir, "wall", basename13(rel)), src = existsSync24(sealed) ? sealed : join41(i.repoDir, rel);
9661
9731
  if (!existsSync24(src))
9662
9732
  return np(`Wall file missing: ${rel}`);
9663
- mkdirSync16(dirname13(join42(wt, rel)), { recursive: true });
9664
- writeFileSync19(join42(wt, rel), readFileSync31(src));
9733
+ mkdirSync16(dirname13(join41(wt, rel)), { recursive: true });
9734
+ writeFileSync19(join41(wt, rel), readFileSync31(src));
9665
9735
  }
9666
9736
  for (const rel of rels) {
9667
9737
  const parts = rel.split("/").slice(0, -1);
9668
9738
  for (let n2 = 0;n2 <= parts.length; n2++) {
9669
9739
  const anc = parts.slice(0, n2).join("/");
9670
9740
  for (const d of DEP_DIRS) {
9671
- const src = join42(i.repoDir, anc, d), dst = join42(wt, anc, d);
9741
+ const src = join41(i.repoDir, anc, d), dst = join41(wt, anc, d);
9672
9742
  if (existsSync24(src) && !existsSync24(dst)) {
9673
9743
  try {
9674
9744
  symlinkSync(src, dst);
@@ -10965,7 +11035,7 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
10965
11035
  import { createHash as createHash12 } from "crypto";
10966
11036
  import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync26, mkdirSync as mkdirSync17, readFileSync as readFileSync33, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
10967
11037
  import { tmpdir as tmpdir6 } from "os";
10968
- import { basename as basename15, join as join43, relative as relative4 } from "path";
11038
+ import { basename as basename15, join as join42, relative as relative3 } from "path";
10969
11039
  function wallHoldoutRatio(env = process.env) {
10970
11040
  if (env["LOKI_WALL_HOLDOUT"]?.trim() === "0")
10971
11041
  return 0;
@@ -10993,32 +11063,32 @@ function stashHoldout(o) {
10993
11063
  rmSync12(dir, { recursive: true, force: true });
10994
11064
  mkdirSync17(dir, { recursive: true, mode: 448 });
10995
11065
  const files = held.map((name) => {
10996
- copyFileSync2(join43(o.srcDir, name), join43(dir, name));
10997
- rmSync12(join43(o.srcDir, name), { force: true });
10998
- return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync33(join43(dir, name), "utf8")) };
11066
+ copyFileSync2(join42(o.srcDir, name), join42(dir, name));
11067
+ rmSync12(join42(o.srcDir, name), { force: true });
11068
+ return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync33(join42(dir, name), "utf8")) };
10999
11069
  });
11000
- writeFileSync20(join43(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
11070
+ writeFileSync20(join42(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
11001
11071
  return { dir, names: new Set(held) };
11002
11072
  }
11003
11073
  function stageHoldout(dir, repoDir) {
11004
11074
  const put = [], tests = [], missing = [];
11005
11075
  let man = null;
11006
11076
  try {
11007
- man = JSON.parse(readFileSync33(join43(dir, MANIFEST), "utf8"));
11077
+ man = JSON.parse(readFileSync33(join42(dir, MANIFEST), "utf8"));
11008
11078
  } catch {}
11009
11079
  if (!man)
11010
11080
  return { tests, missing: [`holdout store unreadable: ${basename15(dir)}`], cleanup: () => {} };
11011
11081
  mkdirSync17(man.targetDir, { recursive: true });
11012
11082
  man.files.forEach((f, i) => {
11013
- const src = join43(dir, f.name);
11083
+ const src = join42(dir, f.name);
11014
11084
  if (!existsSync26(src) || sha2(readFileSync33(src, "utf8")) !== f.sha256) {
11015
11085
  missing.push(`holdout ${i + 1} missing or altered`);
11016
11086
  return;
11017
11087
  }
11018
- const dest = join43(man.targetDir, `loki_wall_holdout_${i + 1}${f.name.slice(f.name.indexOf("."))}`);
11088
+ const dest = join42(man.targetDir, `loki_wall_holdout_${i + 1}${f.name.slice(f.name.indexOf("."))}`);
11019
11089
  copyFileSync2(src, dest);
11020
11090
  put.push(dest);
11021
- tests.push({ runner: f.runner, path: relative4(repoDir, dest) });
11091
+ tests.push({ runner: f.runner, path: relative3(repoDir, dest) });
11022
11092
  });
11023
11093
  return { tests, missing, cleanup: () => {
11024
11094
  for (const p of put)
@@ -11028,16 +11098,16 @@ function stageHoldout(dir, repoDir) {
11028
11098
  function recordHoldoutTriage(runDir, entry) {
11029
11099
  try {
11030
11100
  mkdirSync17(runDir, { recursive: true });
11031
- appendFileSync3(join43(runDir, HOLDOUT_TRIAGE_FILE), JSON.stringify(entry) + `
11101
+ appendFileSync3(join42(runDir, HOLDOUT_TRIAGE_FILE), JSON.stringify(entry) + `
11032
11102
  `, { mode: 384 });
11033
11103
  } catch {}
11034
11104
  }
11035
- var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join43(tmpdir6(), `loki-e10-holdout-${sha2(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
11105
+ var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join42(tmpdir6(), `loki-e10-holdout-${sha2(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
11036
11106
  var init_holdout = () => {};
11037
11107
 
11038
11108
  // ../../loki-ts/src/features/runner_config.ts
11039
11109
  import { readFileSync as readFileSync34 } from "fs";
11040
- import { dirname as dirname15, join as join44, normalize as normalize2 } from "path";
11110
+ import { dirname as dirname15, join as join43, normalize as normalize2 } from "path";
11041
11111
  function tomlKey2(s, i = 0, eq2 = true) {
11042
11112
  const parts = [], ws = () => {
11043
11113
  while (/\s/.test(s[i] ?? "x"))
@@ -11257,6 +11327,53 @@ function testConfigChanged(repoDir, baseSha, changed) {
11257
11327
  }
11258
11328
  });
11259
11329
  }
11330
+ function patchedTargets(cfg, text2) {
11331
+ const out2 = [], unq = (v) => v.replace(/^["']|["']$/g, "");
11332
+ if (/package\.json$/i.test(cfg)) {
11333
+ try {
11334
+ const j = JSON.parse(text2);
11335
+ for (const m of [j.patchedDependencies, j.pnpm?.patchedDependencies])
11336
+ if (m && typeof m === "object") {
11337
+ for (const v of Object.values(m))
11338
+ if (typeof v === "string")
11339
+ out2.push(v);
11340
+ }
11341
+ } catch {}
11342
+ } else if (/pnpm-workspace\.yaml$/i.test(cfg)) {
11343
+ let on = false, flow = 0;
11344
+ const pairs = (t) => {
11345
+ for (const m of t.matchAll(/:\s*("[^"]*"|'[^']*'|[^\s,}#]+)/g))
11346
+ out2.push(unq(m[1]));
11347
+ }, depth = (t) => (t.match(/{/g) ?? []).length - (t.match(/}/g) ?? []).length;
11348
+ for (const l of text2.split(/\r?\n/)) {
11349
+ if (flow) {
11350
+ const c = l.replace(/#.*$/, "");
11351
+ pairs(c);
11352
+ flow = Math.max(0, flow + depth(c));
11353
+ continue;
11354
+ }
11355
+ const h = /^patchedDependencies\s*:(.*)$/.exec(l);
11356
+ if (h) {
11357
+ const rest = h[1].trim(), c = rest.replace(/#.*$/, "");
11358
+ on = !rest || rest.startsWith("#");
11359
+ pairs(c);
11360
+ if (c.startsWith("{"))
11361
+ flow = Math.max(0, depth(c));
11362
+ continue;
11363
+ }
11364
+ if (!on)
11365
+ continue;
11366
+ if (/^\S/.test(l)) {
11367
+ on = false;
11368
+ continue;
11369
+ }
11370
+ const m = /^\s+(?:"[^"]*"|'[^']*'|[^\s:'"][^:]*?)\s*:\s*("[^"]*"|'[^']*'|[^\s#]+)/.exec(l);
11371
+ if (m)
11372
+ out2.push(unq(m[1]));
11373
+ }
11374
+ }
11375
+ return out2.filter((t) => t && !t.startsWith("/"));
11376
+ }
11260
11377
  function referenced(cfg, text2) {
11261
11378
  const raw2 = [...text2.matchAll(REFS)].flatMap((m) => [...m[1].matchAll(QUOTED)].map((q) => q[1]));
11262
11379
  for (const m of text2.matchAll(MAPPER))
@@ -11267,8 +11384,8 @@ function referenced(cfg, text2) {
11267
11384
  }
11268
11385
  const dir = dirname15(cfg), explicit = ROOT_DIR.exec(text2), roots = [dir];
11269
11386
  if (explicit)
11270
- roots.push("", ...explicit[1] ? [join44(dir, explicit[1])] : []);
11271
- return raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(join44(root, r.replace(/^<rootDir>\/?/, "")))));
11387
+ roots.push("", ...explicit[1] ? [join43(dir, explicit[1])] : []);
11388
+ return [...raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(join43(root, r.replace(/^<rootDir>\/?/, ""))))), ...patchedTargets(cfg, text2).map((t) => normalize2(join43(dir, t)))];
11272
11389
  }
11273
11390
  function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
11274
11391
  const notes = new Set, ch = new Set(changed.map((c) => normalize2(c)));
@@ -11303,7 +11420,7 @@ function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
11303
11420
  if (spec.shared && t)
11304
11421
  try {
11305
11422
  relevant(spec.shared, t);
11306
- } catch {
11423
+ } catch (x) {
11307
11424
  bad = true;
11308
11425
  }
11309
11426
  for (const c of referenced(cfg, t))
@@ -11311,7 +11428,7 @@ function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
11311
11428
  }
11312
11429
  const e = typeof spec.shared === "string" && spec.shared !== "tsconfig" ? "" : "{}";
11313
11430
  if (!bad && !same)
11314
- changedHere = !spec.shared || /conftest\.py$/.test(cfg) || relevant(spec.shared, texts[0] || e) !== relevant(spec.shared, texts[1] || e);
11431
+ changedHere = !spec.shared || /conftest\.py$/i.test(cfg) || relevant(spec.shared, texts[0] || e) !== relevant(spec.shared, texts[1] || e);
11315
11432
  } catch {
11316
11433
  bad = true;
11317
11434
  }
@@ -11328,7 +11445,7 @@ function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
11328
11445
  }
11329
11446
  return [...notes];
11330
11447
  }
11331
- var PKG_KEYS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, depGuard = (j) => DEP_MAPS.map((m) => Object.entries(j[m] ?? {}).filter(([k, v]) => RUNNER_DEP.test(k) || LOCAL_SPEC.test(String(v)))), KW, lines = (t) => t.split(`
11448
+ var PKG_KEYS, RAW_CONFIGS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, depGuard = (j) => DEP_MAPS.map((m) => Object.entries(j[m] ?? {}).filter(([k, v]) => RUNNER_DEP.test(k) || LOCAL_SPEC.test(String(v)))), KW, lines = (t) => t.split(`
11332
11449
  `).map((l) => l.trim()).filter((l) => l && !l.startsWith("#")), ESC, unesc = (s) => s.replace(/\\(?:u([0-9a-fA-F]{4})|U([0-9a-fA-F]{8})|([\s\S]))/g, (_m, u, U2, c) => {
11333
11450
  if (c !== undefined) {
11334
11451
  const e = ESC[c];
@@ -11348,26 +11465,29 @@ var PKG_KEYS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, depGuard = (j) =
11348
11465
  }
11349
11466
  }, headText = (dir, f) => {
11350
11467
  try {
11351
- return readFileSync34(join44(dir, f), "utf8");
11468
+ return readFileSync34(join43(dir, f), "utf8");
11352
11469
  } catch {
11353
11470
  return "";
11354
11471
  }
11355
11472
  }, REFS, MAPPER, ROOT_DIR, QUOTED, EXT, gitOut = (dir, args, signal) => safeGit(dir, args, { timeout: 20000, maxBuffer: 64 << 20, ...signal ? { signal } : {} }), NON_SOURCE;
11356
11473
  var init_runner_config = __esm(() => {
11357
11474
  init_safe_git();
11358
- PKG_KEYS = ["scripts", "jest", "overrides", "resolutions", "imports", "pnpm", "mocha", "vitest", "ava", "c8", "nyc", "babel", "bun"];
11359
- RUNNER_CONFIGS = [
11475
+ PKG_KEYS = ["scripts", "jest", "overrides", "resolutions", "imports", "pnpm", "mocha", "vitest", "ava", "c8", "nyc", "babel", "bun", "patchedDependencies"];
11476
+ RAW_CONFIGS = [
11360
11477
  { re: /(^|\/)(conftest\.py|tox\.ini|bunfig\.toml|\.?pytest\.(ini|toml)|\.mocharc[\w.]*)$/ },
11361
11478
  { re: /(^|\/)(vitest|vite|jest)\.(config|workspace)\.[\w.]+$/ },
11362
11479
  { re: /(^|\/)\.cargo\/config(\.toml)?$/ },
11363
11480
  { re: /(^|\/)(babel\.config\.[\w.]+|\.babelrc(\.[\w]+)?|\.pnpmfile\.(cjs|mjs))$/ },
11364
11481
  { re: /(^|\/)package\.json$/, shared: PKG_KEYS },
11482
+ { re: /(^|\/)(pnpm-workspace\.yaml|\.yarnrc\.yml|\.npmrc)$/ },
11483
+ { re: /(^|\/)patches\/|\.patch$/ },
11365
11484
  { re: /(^|\/)pyproject\.toml$/, shared: /^\[tool\.pytest/ },
11366
11485
  { re: /(^|\/)setup\.cfg$/, shared: /^\[tool:pytest\]/ },
11367
11486
  { re: /(^|\/)go\.(mod|work)$/, shared: "go" },
11368
11487
  { re: /(^|\/)Cargo\.toml$/, shared: "cargo" },
11369
11488
  { re: /(^|\/)[jt]sconfig(\.[\w-]+)?\.json$/, shared: "tsconfig" }
11370
11489
  ];
11490
+ RUNNER_CONFIGS = RAW_CONFIGS.map((s) => ({ ...s, re: new RegExp(s.re.source, "i") }));
11371
11491
  DEP_MAPS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
11372
11492
  RUNNER_DEP = /^(jest|vitest|mocha|ava|c8|nyc|pytest[\w-]*|@jest\/.*|ts-jest|babel-jest)$/;
11373
11493
  LOCAL_SPEC = /^(file|link|npm|workspace):/;
@@ -11384,10 +11504,10 @@ var init_runner_config = __esm(() => {
11384
11504
  });
11385
11505
 
11386
11506
  // ../../loki-ts/src/e10ext/assert_delta.ts
11387
- import { execFileSync as execFileSync5 } from "child_process";
11507
+ import { execFileSync as execFileSync3 } from "child_process";
11388
11508
  import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync35, rmSync as rmSync13 } from "fs";
11389
11509
  import { tmpdir as tmpdir7 } from "os";
11390
- import { join as join45 } from "path";
11510
+ import { join as join44 } from "path";
11391
11511
  import { basename as basename16 } from "path";
11392
11512
  function classifyAssertDelta(inp) {
11393
11513
  const f = basename16(inp.path);
@@ -11397,8 +11517,8 @@ function classifyAssertDelta(inp) {
11397
11517
  return WEAKENED;
11398
11518
  let cwd = "";
11399
11519
  try {
11400
- cwd = mkdtempSync5(join45(tmpdir7(), "loki-ad-"));
11401
- const raw2 = execFileSync5("python3", ["-I", "-c", PY], {
11520
+ cwd = mkdtempSync5(join44(tmpdir7(), "loki-ad-"));
11521
+ const raw2 = execFileSync3("python3", ["-I", "-c", PY], {
11402
11522
  input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
11403
11523
  cwd,
11404
11524
  env: process.env,
@@ -11428,7 +11548,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
11428
11548
  return null;
11429
11549
  try {
11430
11550
  const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
11431
- const head = headRef ? show(headRef) : readFileSync35(join45(repoDir, path), "utf8");
11551
+ const head = headRef ? show(headRef) : readFileSync35(join44(repoDir, path), "utf8");
11432
11552
  const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
11433
11553
  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;
11434
11554
  } catch {
@@ -11637,17 +11757,17 @@ var init_runner_errors = __esm(() => {
11637
11757
  import { spawnSync as spawnSync3 } from "child_process";
11638
11758
  import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync17, rmSync as rmSync14 } from "fs";
11639
11759
  import { tmpdir as tmpdir8 } from "os";
11640
- import { basename as basename17, extname as extname2, join as join46 } from "path";
11760
+ import { basename as basename17, extname, join as join45 } from "path";
11641
11761
  function changedFilesNamed(out2, repoDir, changed) {
11642
11762
  return changed.filter((f) => {
11643
- if (out2.includes(f) || out2.includes(join46(repoDir, f)))
11763
+ if (out2.includes(f) || out2.includes(join45(repoDir, f)))
11644
11764
  return true;
11645
11765
  const segs = f.split("/");
11646
11766
  if (suffixes(segs, 2).some((x) => x !== f && bounded(out2, x, "(?![\\w-])")))
11647
11767
  return true;
11648
- if (extname2(f) === ".go" && segs.length > 1 && suffixes(segs.slice(0, -1), 1).some((d) => new RegExp(`(?<=[\\w-])/${esc(d)}(?![\\w./-])`).test(out2)))
11768
+ if (extname(f) === ".go" && segs.length > 1 && suffixes(segs.slice(0, -1), 1).some((d) => new RegExp(`(?<=[\\w-])/${esc(d)}(?![\\w./-])`).test(out2)))
11649
11769
  return true;
11650
- const stem = basename17(f, extname2(f));
11770
+ const stem = basename17(f, extname(f));
11651
11771
  if (stem.length < 2 || stem === "index" || stem === "__init__")
11652
11772
  return false;
11653
11773
  return new RegExp(`(?<![\\w-])${esc(stem)}(?![\\w-])`).test(out2);
@@ -11751,7 +11871,7 @@ async function loadErrorIsHarnessOwned(i) {
11751
11871
  return false;
11752
11872
  if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
11753
11873
  return false;
11754
- const dir = mkdtempSync6(join46(tmpdir8(), "e10-loadown-"));
11874
+ const dir = mkdtempSync6(join45(tmpdir8(), "e10-loadown-"));
11755
11875
  const git3 = (args) => {
11756
11876
  safeGit(i.repoDir, args, { stdio: "ignore" });
11757
11877
  };
@@ -11783,7 +11903,7 @@ var init_load_owner = __esm(() => {
11783
11903
  });
11784
11904
 
11785
11905
  // ../../loki-ts/src/util/wall_owned.ts
11786
- import { isAbsolute as isAbsolute5, join as join47, relative as relative5 } from "path";
11906
+ import { isAbsolute as isAbsolute5, join as join46, relative as relative4 } from "path";
11787
11907
  function failingLocations(raw2, cwd, repoDir) {
11788
11908
  const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
11789
11909
  `), files = new Set;
@@ -11815,7 +11935,7 @@ function failingLocations(raw2, cwd, repoDir) {
11815
11935
  }
11816
11936
  if (errors2 === 0 || located !== errors2)
11817
11937
  return null;
11818
- return [...files].map((f) => relative5(repoDir, isAbsolute5(f) ? f : join47(cwd, f)));
11938
+ return [...files].map((f) => relative4(repoDir, isAbsolute5(f) ? f : join46(cwd, f)));
11819
11939
  }
11820
11940
  function wallOwnedFailure(raw2, cwd, repoDir, wall) {
11821
11941
  const locs = failingLocations(raw2, cwd, repoDir);
@@ -11836,7 +11956,7 @@ import {
11836
11956
  writeFileSync as writeFileSync21,
11837
11957
  mkdirSync as mkdirSync18
11838
11958
  } from "fs";
11839
- import { basename as basename18, dirname as dirname16, join as join48, resolve as resolve14 } from "path";
11959
+ import { basename as basename18, dirname as dirname16, join as join47, resolve as resolve14 } from "path";
11840
11960
  function readManifest(path) {
11841
11961
  if (!existsSync27(path)) {
11842
11962
  return null;
@@ -11895,7 +12015,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
11895
12015
  for (const child of children) {
11896
12016
  if (!matchPattern(name, child))
11897
12017
  continue;
11898
- const full = join48(rootDir, child);
12018
+ const full = join47(rootDir, child);
11899
12019
  if (seen.has(full))
11900
12020
  continue;
11901
12021
  let st;
@@ -11912,7 +12032,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
11912
12032
  }
11913
12033
  if (declared.length === 0) {
11914
12034
  for (const child of children) {
11915
- const full = join48(rootDir, child);
12035
+ const full = join47(rootDir, child);
11916
12036
  if (seen.has(full))
11917
12037
  continue;
11918
12038
  let st;
@@ -11923,7 +12043,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
11923
12043
  }
11924
12044
  if (!st.isDirectory())
11925
12045
  continue;
11926
- if (!existsSync27(join48(full, ".loki", "app.json")))
12046
+ if (!existsSync27(join47(full, ".loki", "app.json")))
11927
12047
  continue;
11928
12048
  seen.add(full);
11929
12049
  out2.push(full);
@@ -11944,17 +12064,17 @@ function cacheKey(manifestPaths) {
11944
12064
  }
11945
12065
  function writeCache(targetDir, key, result) {
11946
12066
  try {
11947
- const cacheDir = join48(targetDir, ".loki", "state");
12067
+ const cacheDir = join47(targetDir, ".loki", "state");
11948
12068
  mkdirSync18(cacheDir, { recursive: true });
11949
- const cachePath = join48(cacheDir, "project-graph.json");
12069
+ const cachePath = join47(cacheDir, "project-graph.json");
11950
12070
  writeFileSync21(cachePath, JSON.stringify({ key, result }, null, 2), "utf8");
11951
12071
  } catch {}
11952
12072
  }
11953
12073
  function discoverProjectGraph(targetDir) {
11954
12074
  const absTarget = resolve14(targetDir);
11955
- const targetManifest = join48(absTarget, ".loki", "app.json");
12075
+ const targetManifest = join47(absTarget, ".loki", "app.json");
11956
12076
  const parentDir = dirname16(absTarget);
11957
- const parentManifest = join48(parentDir, ".loki", "app.json");
12077
+ const parentManifest = join47(parentDir, ".loki", "app.json");
11958
12078
  const examined = [];
11959
12079
  let chosenManifest = null;
11960
12080
  let chosenRoot = "";
@@ -11974,7 +12094,7 @@ function discoverProjectGraph(targetDir) {
11974
12094
  const members = resolveMembers(chosenRoot, declared, basename18(absTarget));
11975
12095
  const filtered = [];
11976
12096
  for (const m of members) {
11977
- const sibManifestPath = join48(m, ".loki", "app.json");
12097
+ const sibManifestPath = join47(m, ".loki", "app.json");
11978
12098
  if (existsSync27(sibManifestPath)) {
11979
12099
  examined.push(sibManifestPath);
11980
12100
  const sibManifest = readManifest(sibManifestPath);
@@ -12105,7 +12225,7 @@ import { spawn as spawn7 } from "child_process";
12105
12225
  import { createHash as createHash14, randomBytes as randomBytes5 } from "crypto";
12106
12226
  import { existsSync as existsSync28, lstatSync as lstatSync10, mkdirSync as mkdirSync19, readdirSync as readdirSync16, readFileSync as readFileSync37, writeFileSync as writeFileSync22 } from "fs";
12107
12227
  import { createServer } from "net";
12108
- import { dirname as dirname17, isAbsolute as isAbsolute6, join as join49, normalize as normalize3, relative as relative6, sep as sep11 } from "path";
12228
+ import { dirname as dirname17, isAbsolute as isAbsolute6, join as join48, normalize as normalize3, relative as relative5, sep as sep10 } from "path";
12109
12229
  function routeFor(file) {
12110
12230
  let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
12111
12231
  r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
@@ -12115,7 +12235,7 @@ function hashScreens(runDir, rels) {
12115
12235
  const out2 = [];
12116
12236
  for (const rel of rels) {
12117
12237
  try {
12118
- out2.push({ path: rel, sha256: sha256File(join49(runDir, rel)) });
12238
+ out2.push({ path: rel, sha256: sha256File(join48(runDir, rel)) });
12119
12239
  } catch {}
12120
12240
  }
12121
12241
  return out2;
@@ -12128,10 +12248,10 @@ function checkScreens(runDir, screens) {
12128
12248
  return "evidence_screens entry is malformed";
12129
12249
  if (isAbsolute6(s.path) || normalize3(s.path).startsWith(".."))
12130
12250
  return `evidence screenshot path escapes the evidence dir: ${s.path}`;
12131
- const file = join49(runDir, s.path);
12251
+ const file = join48(runDir, s.path);
12132
12252
  let cur = runDir;
12133
- for (const seg of normalize3(s.path).split(sep11)) {
12134
- cur = join49(cur, seg);
12253
+ for (const seg of normalize3(s.path).split(sep10)) {
12254
+ cur = join48(cur, seg);
12135
12255
  if (isSymlink(cur))
12136
12256
  return `evidence screenshot path is a symlink: ${s.path}`;
12137
12257
  }
@@ -12178,7 +12298,7 @@ async function waitUp(url, ms, signal) {
12178
12298
  }
12179
12299
  function openapiPaths(repoDir) {
12180
12300
  for (const f of ["openapi.json", "openapi.yaml", "openapi.yml", "swagger.json"]) {
12181
- const p = join49(repoDir, f);
12301
+ const p = join48(repoDir, f);
12182
12302
  if (!existsSync28(p))
12183
12303
  continue;
12184
12304
  try {
@@ -12196,24 +12316,24 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
12196
12316
  if (!pw || !pkg)
12197
12317
  return { rels: [], skipped: "playwright e2e video and trace skipped: @playwright/test is not installed in the repo" };
12198
12318
  try {
12199
- const dir = join49(runDir, relDir, "e2e");
12319
+ const dir = join48(runDir, relDir, "e2e");
12200
12320
  mkdirSync19(dir, { recursive: true });
12201
- writeFileSync22(join49(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
12202
- writeFileSync22(join49(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
12321
+ writeFileSync22(join48(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
12322
+ writeFileSync22(join48(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
12203
12323
  `);
12204
- if (!await shoot(pw, ["test", "--config", join49(dir, "playwright.config.cjs")], repoDir, ms, signal))
12324
+ if (!await shoot(pw, ["test", "--config", join48(dir, "playwright.config.cjs")], repoDir, ms, signal))
12205
12325
  return { rels: [], skipped: "playwright e2e video and trace skipped: the run failed or timed out" };
12206
12326
  const rels = [];
12207
12327
  const walk = (d) => {
12208
12328
  for (const e of readdirSync16(d, { withFileTypes: true })) {
12209
- const full = join49(d, e.name);
12329
+ const full = join48(d, e.name);
12210
12330
  if (e.isDirectory())
12211
12331
  walk(full);
12212
12332
  else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
12213
- rels.push(join49(relDir, "e2e", relative6(dir, full)));
12333
+ rels.push(join48(relDir, "e2e", relative5(dir, full)));
12214
12334
  }
12215
12335
  };
12216
- walk(join49(dir, "out"));
12336
+ walk(join48(dir, "out"));
12217
12337
  return rels.length > 0 ? { rels, skipped: null } : { rels, skipped: "playwright e2e video and trace skipped: no video or trace was produced" };
12218
12338
  } catch (e) {
12219
12339
  return { rels: [], skipped: `playwright e2e video and trace skipped: ${String(e?.message ?? e).slice(0, 120)}` };
@@ -12292,15 +12412,15 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12292
12412
  if (!visualEvidenceEnabled(opts.env))
12293
12413
  return skip("LOKI_VISUAL_EVIDENCE is 0");
12294
12414
  const api = loadProjectApi(repoDir), boot = isMultiRoot(api) ? api.uiBoot() : null;
12295
- const appDir = boot ? join49(repoDir, boot.boot.cwd) : repoDir;
12296
- const pkgPath = join49(appDir, "package.json");
12415
+ const appDir = boot ? join48(repoDir, boot.boot.cwd) : repoDir;
12416
+ const pkgPath = join48(appDir, "package.json");
12297
12417
  let script = null;
12298
12418
  if (!boot) {
12299
12419
  if (!existsSync28(pkgPath)) {
12300
- const subs = ["backend", "frontend"].filter((d) => existsSync28(join49(repoDir, d, "package.json")));
12420
+ const subs = ["backend", "frontend"].filter((d) => existsSync28(join48(repoDir, d, "package.json")));
12301
12421
  const has = (d) => {
12302
12422
  try {
12303
- return pickScript(JSON.parse(readFileSync37(join49(repoDir, d, "package.json"), "utf8"))) !== null;
12423
+ return pickScript(JSON.parse(readFileSync37(join48(repoDir, d, "package.json"), "utf8"))) !== null;
12304
12424
  } catch {
12305
12425
  return false;
12306
12426
  }
@@ -12334,20 +12454,20 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12334
12454
  }
12335
12455
  if (!await waitUp(base, left(), signal))
12336
12456
  return skip(aborted() ? "aborted" : `${script} server did not answer within ${Math.round(budget / 1000)}s`);
12337
- const evRoot = join49(runDir, "evidence");
12457
+ const evRoot = join48(runDir, "evidence");
12338
12458
  if (isSymlink(evRoot))
12339
12459
  return skip("evidence dir is a symlink");
12340
12460
  mkdirSync19(evRoot, { recursive: true });
12341
12461
  if (pages.length > 0) {
12342
- const rel0 = join49("evidence", randomBytes5(6).toString("hex"));
12343
- mkdirSync19(join49(runDir, rel0));
12462
+ const rel0 = join48("evidence", randomBytes5(6).toString("hex"));
12463
+ mkdirSync19(join48(runDir, rel0));
12344
12464
  const rels = [];
12345
12465
  for (const route of [...new Set(pages.map(routeFor))].slice(0, opts.maxRoutes ?? MAX_ROUTES)) {
12346
12466
  if (aborted() || left() <= 0)
12347
12467
  break;
12348
- const rel = join49(rel0, `${screenName(route)}.png`);
12349
- const ok = await shoot(pw, ["screenshot", `${base}${route}`, join49(runDir, rel)], appDir, left(), signal);
12350
- if (ok && !aborted() && !isSymlink(join49(runDir, rel)) && existsSync28(join49(runDir, rel)))
12468
+ const rel = join48(rel0, `${screenName(route)}.png`);
12469
+ const ok = await shoot(pw, ["screenshot", `${base}${route}`, join48(runDir, rel)], appDir, left(), signal);
12470
+ if (ok && !aborted() && !isSymlink(join48(runDir, rel)) && existsSync28(join48(runDir, rel)))
12351
12471
  rels.push(rel);
12352
12472
  }
12353
12473
  if (aborted())
@@ -12372,9 +12492,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12372
12492
  }
12373
12493
  if (aborted())
12374
12494
  return skip("aborted");
12375
- const hdir = join49(evRoot, randomBytes5(6).toString("hex"));
12495
+ const hdir = join48(evRoot, randomBytes5(6).toString("hex"));
12376
12496
  mkdirSync19(hdir);
12377
- writeFileSync22(join49(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
12497
+ writeFileSync22(join48(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
12378
12498
  `);
12379
12499
  return { screens: [], http: true, skipped: null };
12380
12500
  } catch (e) {
@@ -12404,11 +12524,11 @@ function receiptScreensProblem(receiptPath, receipt) {
12404
12524
  return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname17(receiptPath), receipt["evidence_screens"]);
12405
12525
  }
12406
12526
  var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash14("sha256").update(readFileSync37(p)).digest("hex"), playwrightBin = (repoDir) => {
12407
- const bin = join49(repoDir, "node_modules", ".bin", "playwright");
12527
+ const bin = join48(repoDir, "node_modules", ".bin", "playwright");
12408
12528
  return existsSync28(bin) ? bin : null;
12409
12529
  }, playwrightTestPkg = (repoDir) => {
12410
- const d = join49(repoDir, "node_modules", "@playwright", "test");
12411
- return existsSync28(join49(d, "package.json")) ? d : null;
12530
+ const d = join48(repoDir, "node_modules", "@playwright", "test");
12531
+ return existsSync28(join48(d, "package.json")) ? d : null;
12412
12532
  }, e2eSpecSource = (pkgDir, base, routes) => `const { test } = require(${JSON.stringify(pkgDir)});
12413
12533
  test("loki e2e walkthrough", async ({ page }) => {
12414
12534
  for (const r of ${JSON.stringify(routes)}) { await page.goto(${JSON.stringify(base)} + r); await page.waitForLoadState("load"); }
@@ -12451,7 +12571,7 @@ var init_outbox = __esm(() => {
12451
12571
  });
12452
12572
 
12453
12573
  // ../../loki-ts/src/engine10/stages/pr.ts
12454
- import { join as join50 } from "path";
12574
+ import { join as join49 } from "path";
12455
12575
  var DEFAULT_PUSH_SH;
12456
12576
  var init_pr = __esm(() => {
12457
12577
  init_types();
@@ -12468,12 +12588,12 @@ var init_pr = __esm(() => {
12468
12588
  init_run_outputs();
12469
12589
  init_yaml_key();
12470
12590
  init_outbox();
12471
- DEFAULT_PUSH_SH = join50(REPO_ROOT, "autonomy/lib/engine10-push.sh");
12591
+ DEFAULT_PUSH_SH = join49(REPO_ROOT, "autonomy/lib/engine10-push.sh");
12472
12592
  });
12473
12593
 
12474
12594
  // ../../loki-ts/src/util/pr_lessons.ts
12475
12595
  import { existsSync as existsSync29, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync7, readFileSync as readFileSync38, rmSync as rmSync15, writeFileSync as writeFileSync23 } from "fs";
12476
- import { dirname as dirname18, join as join51 } from "path";
12596
+ import { dirname as dirname18, join as join50 } from "path";
12477
12597
  import { createHash as createHash15 } from "crypto";
12478
12598
  function loadLessons(repoDir) {
12479
12599
  const p = lessonsPath(repoDir);
@@ -12522,7 +12642,7 @@ function recordRunVerdict(repoDir, runId, verdict) {
12522
12642
  if (dirty)
12523
12643
  save(repoDir, lessons);
12524
12644
  }
12525
- var lessonsPath = (repoDir) => join51(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), KINDS;
12645
+ var lessonsPath = (repoDir) => join50(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), KINDS;
12526
12646
  var init_pr_lessons = __esm(() => {
12527
12647
  init_atomic();
12528
12648
  init_safe_git();
@@ -12657,10 +12777,10 @@ var init_providers = __esm(() => {
12657
12777
 
12658
12778
  // ../../loki-ts/src/runner/router/route_record.ts
12659
12779
  import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readFileSync as readFileSync40, writeFileSync as writeFileSync24 } from "fs";
12660
- import { join as join52 } from "path";
12780
+ import { join as join51 } from "path";
12661
12781
  function loadRouteRecord(runDir) {
12662
12782
  try {
12663
- const p = join52(runDir, ROUTE_RECORD_FILE);
12783
+ const p = join51(runDir, ROUTE_RECORD_FILE);
12664
12784
  if (!existsSync31(p) || !lstatSync11(p).isFile())
12665
12785
  return;
12666
12786
  const v = JSON.parse(readFileSync40(p, "utf8"));
@@ -12789,7 +12909,7 @@ var init_worker = __esm(() => {
12789
12909
  });
12790
12910
 
12791
12911
  // ../../loki-ts/src/project_model/package_suite.ts
12792
- import { join as join53 } from "path";
12912
+ import { join as join52 } from "path";
12793
12913
  async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
12794
12914
  const api = loadProjectApi(repoDir);
12795
12915
  if (!isMultiRoot(api))
@@ -12800,7 +12920,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
12800
12920
  for (const pkg of withTests) {
12801
12921
  const tc = pkg.commands.test, name = `full suite: ${pkg.name}`, cmd = `(cd ${tc.cwd} && ${tc.cmd})`;
12802
12922
  const started = Date.now();
12803
- const r = await run(["bash", "-c", tc.cmd], { cwd: join53(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
12923
+ const r = await run(["bash", "-c", tc.cmd], { cwd: join52(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
12804
12924
  const duration_s = (Date.now() - started) / 1000;
12805
12925
  if (signal.aborted) {
12806
12926
  checks.push({ name, cmd, result: "not_run", duration_s });
@@ -12809,7 +12929,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
12809
12929
  }
12810
12930
  const out2 = `${r.stdout}
12811
12931
  ${r.stderr}`;
12812
- const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join53(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
12932
+ const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join52(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
12813
12933
  if (lr) {
12814
12934
  checks.push({ name, cmd, result: "not_run", duration_s });
12815
12935
  notProven.add(`${lr} (${name}; harness-owned)`);
@@ -12843,7 +12963,7 @@ __export(exports_deep, {
12843
12963
  DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
12844
12964
  });
12845
12965
  import { existsSync as existsSync32, mkdirSync as mkdirSync22, writeFileSync as writeFileSync25 } from "fs";
12846
- import { join as join54 } from "path";
12966
+ import { join as join53 } from "path";
12847
12967
  async function runFullSuite(ctx, signal, opts, checks, notProven) {
12848
12968
  if (await runPackageSuites(ctx.repoDir, signal, { path: opts.path, timeoutMs: opts.fullSuiteTimeoutMs ?? FULL_SUITE_TIMEOUT_MS, baseSha: ctx.baseSha }, checks, notProven))
12849
12969
  return;
@@ -12940,7 +13060,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
12940
13060
  }
12941
13061
  const inline = 'script="$1"; shift; . "$script" || exit 3; hit=0; for f in "$@"; do if _commit_scan_secret_file "$f" || _commit_path_looks_secret "$f"; then printf "%s\\n" "$f"; hit=1; fi; done; exit "$hit"';
12942
13062
  const started = Date.now();
12943
- const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join54(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
13063
+ const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join53(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
12944
13064
  const durationS = (Date.now() - started) / 1000;
12945
13065
  if (r.exitCode === 3) {
12946
13066
  checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: durationS });
@@ -12981,7 +13101,7 @@ async function postResults(ctx, opts, checks, notProven, statusState) {
12981
13101
  const prNumber = prUrl ? PR_NUMBER_RE.exec(prUrl)?.[1] : undefined;
12982
13102
  if (prNumber) {
12983
13103
  mkdirSync22(ctx.runDir, { recursive: true });
12984
- const bodyFile = join54(ctx.runDir, "deep-comment.md");
13104
+ const bodyFile = join53(ctx.runDir, "deep-comment.md");
12985
13105
  writeFileSync25(bodyFile, buildCommentBody(checks, notProven, statusState), "utf8");
12986
13106
  const commentResult = await run(["bash", scriptPath, ...commentArgv(prNumber, bodyFile)], { cwd: ctx.repoDir, env, timeoutMs: 30000 });
12987
13107
  if (commentResult.exitCode !== 0)
@@ -13035,7 +13155,7 @@ async function runDeep(ctx, signal, opts = {}) {
13035
13155
  const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
13036
13156
  const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
13037
13157
  mkdirSync22(ctx.runDir, { recursive: true });
13038
- writeFileSync25(join54(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
13158
+ writeFileSync25(join53(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
13039
13159
  `);
13040
13160
  const pushNotProven = await postResults(ctx, opts, checks, notProvenList, statusState);
13041
13161
  const allNotProven = [...notProvenList, ...pushNotProven];
@@ -13080,18 +13200,18 @@ var init_deep = __esm(() => {
13080
13200
  // ../../loki-ts/src/engine10/stages/verify.ts
13081
13201
  import { existsSync as existsSync33, mkdtempSync as mkdtempSync8, realpathSync as realpathSync18, rmSync as rmSync16 } from "fs";
13082
13202
  import { tmpdir as tmpdir9 } from "os";
13083
- import { dirname as dirname20, isAbsolute as isAbsolute7, join as join55, relative as relative7 } from "path";
13203
+ import { dirname as dirname20, isAbsolute as isAbsolute7, join as join54, relative as relative6 } from "path";
13084
13204
  function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
13085
13205
  const inRepo = (p) => {
13086
13206
  try {
13087
- const r = relative7(realpathSync18(repoDir), realpathSync18(p));
13207
+ const r = relative6(realpathSync18(repoDir), realpathSync18(p));
13088
13208
  return r !== "" && !r.startsWith("..") && !isAbsolute7(r);
13089
13209
  } catch {
13090
13210
  return false;
13091
13211
  }
13092
13212
  };
13093
13213
  const venvEnv = process.env["VIRTUAL_ENV"];
13094
- const project = [join55(repoDir, ".venv", "bin", bin), join55(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join55(venvEnv, "bin", bin)] : []].find(existsSync33);
13214
+ const project = [join54(repoDir, ".venv", "bin", bin), join54(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join54(venvEnv, "bin", bin)] : []].find(existsSync33);
13095
13215
  return project ? [project, "project"] : [Bun.which(fallback) ? fallback : lastResort, "system"];
13096
13216
  }
13097
13217
  function runnerCmd(t, repoDir) {
@@ -13204,7 +13324,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
13204
13324
  const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
13205
13325
  if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length) || signal.aborted)
13206
13326
  return out2;
13207
- const dir = mkdtempSync8(join55(tmpdir9(), "e10-base-"));
13327
+ const dir = mkdtempSync8(join54(tmpdir9(), "e10-base-"));
13208
13328
  const git3 = (args) => {
13209
13329
  safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
13210
13330
  };
@@ -13242,7 +13362,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
13242
13362
  return out2;
13243
13363
  }
13244
13364
  function isLokiModeRepo(repoDir) {
13245
- return existsSync33(join55(repoDir, "scripts", "select-tests.sh"));
13365
+ return existsSync33(join54(repoDir, "scripts", "select-tests.sh"));
13246
13366
  }
13247
13367
  async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
13248
13368
  const { api, ...runOpts } = opts;
@@ -13259,9 +13379,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
13259
13379
  }
13260
13380
  for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
13261
13381
  const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
13262
- if (existsSync33(join55(g.cwd, "tsconfig.json")))
13382
+ if (existsSync33(join54(g.cwd, "tsconfig.json")))
13263
13383
  await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
13264
- if (ESLINT_CONFIGS.some((f) => existsSync33(join55(g.cwd, f))))
13384
+ if (ESLINT_CONFIGS.some((f) => existsSync33(join54(g.cwd, f))))
13265
13385
  await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
13266
13386
  }
13267
13387
  }
@@ -13319,7 +13439,7 @@ var init_verify = __esm(() => {
13319
13439
  const impacted = ctx.tests.impacted(map, changed);
13320
13440
  const changedTestFiles = map.tests.filter((t) => changed.includes(t.path));
13321
13441
  const wall = ctx.outputs().wall ?? {};
13322
- const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute7(f.path) ? relative7(ctx.repoDir, f.path) : f.path));
13442
+ const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute7(f.path) ? relative6(ctx.repoDir, f.path) : f.path));
13323
13443
  const wallTests = map.tests.filter((t) => wallPaths.has(t.path));
13324
13444
  const intake = ctx.outputs().intake, relevant2 = ctx.tests.impacted(map, namedFiles(intake?.task ?? "", loadRepoMap(intake?.repomap_ref)));
13325
13445
  const tests = dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]);
@@ -13417,7 +13537,7 @@ var init_verify = __esm(() => {
13417
13537
 
13418
13538
  // ../../loki-ts/src/project_model/conventions.ts
13419
13539
  import { existsSync as existsSync34, readdirSync as readdirSync17, readFileSync as readFileSync41 } from "fs";
13420
- import { dirname as dirname21, join as join56 } from "path";
13540
+ import { dirname as dirname21, join as join55 } from "path";
13421
13541
  function parseJsonc(text2) {
13422
13542
  let out2 = "", i = 0;
13423
13543
  while (i < text2.length) {
@@ -13452,7 +13572,7 @@ function moduleOf(file, depth = 0) {
13452
13572
  const ext = typeof j.extends === "string" ? j.extends : null;
13453
13573
  if (!ext || !ext.startsWith("."))
13454
13574
  return null;
13455
- const next = join56(dirname21(file), ext.endsWith(".json") ? ext : `${ext}.json`);
13575
+ const next = join55(dirname21(file), ext.endsWith(".json") ? ext : `${ext}.json`);
13456
13576
  return existsSync34(next) ? moduleOf(next, depth + 1) : null;
13457
13577
  }
13458
13578
  function readPackageConventions(pkgDir, runner = null) {
@@ -13464,13 +13584,13 @@ function readPackageConventions(pkgDir, runner = null) {
13464
13584
  }
13465
13585
  let packageType = null, tsModule = null;
13466
13586
  for (const n2 of names) {
13467
- const j = readJson4(join56(pkgDir, n2));
13587
+ const j = readJson4(join55(pkgDir, n2));
13468
13588
  if (!j)
13469
13589
  continue;
13470
13590
  if (packageType === null && typeof j.type === "string" && typeof j.name === "string")
13471
13591
  packageType = j.type;
13472
13592
  if (tsModule === null && j.compilerOptions !== undefined)
13473
- tsModule = moduleOf(join56(pkgDir, n2));
13593
+ tsModule = moduleOf(join55(pkgDir, n2));
13474
13594
  }
13475
13595
  if (packageType === null && tsModule === null)
13476
13596
  return null;
@@ -13504,13 +13624,13 @@ var init_conventions = () => {};
13504
13624
  import { spawnSync as spawnSync4 } from "child_process";
13505
13625
  import { existsSync as existsSync35, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync9, readFileSync as readFileSync42, readdirSync as readdirSync18, realpathSync as realpathSync19, rmSync as rmSync17, writeFileSync as writeFileSync26 } from "fs";
13506
13626
  import { tmpdir as tmpdir10 } from "os";
13507
- import { dirname as dirname22, isAbsolute as isAbsolute8, join as join57, relative as relative8 } from "path";
13627
+ import { dirname as dirname22, isAbsolute as isAbsolute8, join as join56, relative as relative7 } from "path";
13508
13628
  function pytestCollectionIsRed(output, repoDir) {
13509
13629
  if (/ModuleNotFoundError/.test(output))
13510
13630
  return false;
13511
13631
  const real2 = (p) => {
13512
13632
  try {
13513
- return realpathSync19(isAbsolute8(p) ? p : join57(repoDir, p));
13633
+ return realpathSync19(isAbsolute8(p) ? p : join56(repoDir, p));
13514
13634
  } catch {
13515
13635
  return null;
13516
13636
  }
@@ -13547,7 +13667,7 @@ function pytestCollectionIsRed(output, repoDir) {
13547
13667
  }
13548
13668
  function moduleUnderRepo(repoDir, name) {
13549
13669
  const rel = name.replace(/\./g, "/");
13550
- return existsSync35(join57(repoDir, `${rel}.py`)) || existsSync35(join57(repoDir, rel, "__init__.py"));
13670
+ return existsSync35(join56(repoDir, `${rel}.py`)) || existsSync35(join56(repoDir, rel, "__init__.py"));
13551
13671
  }
13552
13672
  function pytestExit1IsRed(output) {
13553
13673
  if (/^!+ _pytest\.outcomes\.Exit\b/m.test(output))
@@ -13645,7 +13765,7 @@ ${acceptance.map((a) => `Acceptance: ${a}`).join(`
13645
13765
  function loadTaskText(ctx, fromPrior) {
13646
13766
  if (fromPrior)
13647
13767
  return fromPrior;
13648
- const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join57(ctx.runDir, "issue.json");
13768
+ const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join56(ctx.runDir, "issue.json");
13649
13769
  if (existsSync35(issueJsonPath)) {
13650
13770
  try {
13651
13771
  const issue = JSON.parse(readFileSync42(issueJsonPath, "utf8"));
@@ -13660,7 +13780,7 @@ function loadTaskText(ctx, fromPrior) {
13660
13780
  }
13661
13781
  function wallTargetDir(repoDir, existingTests) {
13662
13782
  const first = existingTests[0];
13663
- return first ? join57(repoDir, dirname22(first.path)) : join57(repoDir, "tests");
13783
+ return first ? join56(repoDir, dirname22(first.path)) : join56(repoDir, "tests");
13664
13784
  }
13665
13785
  function guessRunner(fileName, runners) {
13666
13786
  if (fileName.endsWith(".py"))
@@ -13690,12 +13810,12 @@ async function wallAuthor(ctx, signal) {
13690
13810
  return done({ status: "skipped", data: { size: sz.size, files: [], no_runner: true }, reason: "no runnable test command detected: the Wall cannot write a runnable check" });
13691
13811
  const tree = prior.intake?.tree;
13692
13812
  const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
13693
- const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative8(ctx.repoDir, targetDir)}/x`);
13694
- const conv2 = readPackageConventions(join57(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
13695
- const cwd = mkdtempSync9(join57(tmpdir10(), "loki-e15-wall-"));
13813
+ const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative7(ctx.repoDir, targetDir)}/x`);
13814
+ const conv2 = readPackageConventions(join56(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
13815
+ const cwd = mkdtempSync9(join56(tmpdir10(), "loki-e15-wall-"));
13696
13816
  const wm = wallManifestFor(ctx.repoDir, tree, task);
13697
13817
  for (const [n2, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm ? [["wall_manifest.txt", wm.text]] : []])
13698
- writeFileSync26(join57(cwd, n2), c, "utf8");
13818
+ writeFileSync26(join56(cwd, n2), c, "utf8");
13699
13819
  const session = await ctx.sessions.run({
13700
13820
  stage: "wall",
13701
13821
  brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2), unitSpec()?.acceptance ?? []),
@@ -13710,15 +13830,15 @@ async function wallAuthor(ctx, signal) {
13710
13830
  rmSync17(cwd, { recursive: true, force: true });
13711
13831
  return done({ status: "failed", data: {}, reason: "wall session aborted, killed, or timed out", killed: true });
13712
13832
  }
13713
- const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync42(join57(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
13714
- const sealedDir = join57(ctx.runDir, "wall");
13833
+ const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync42(join56(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
13834
+ const sealedDir = join56(ctx.runDir, "wall");
13715
13835
  if (generated.length > 0)
13716
13836
  mkdirSync23(sealedDir, { recursive: true });
13717
13837
  const contents = new Map;
13718
13838
  const discarded = [];
13719
13839
  for (const name of generated) {
13720
- const content = readFileSync42(join57(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
13721
- writeFileSync26(join57(sealedDir, name), content, "utf8");
13840
+ const content = readFileSync42(join56(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
13841
+ writeFileSync26(join56(sealedDir, name), content, "utf8");
13722
13842
  if (bad)
13723
13843
  discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
13724
13844
  else
@@ -13738,18 +13858,18 @@ function installWall(ctx, a, baseDir, opts = {}) {
13738
13858
  const content = contents.get(name);
13739
13859
  if (content === undefined)
13740
13860
  continue;
13741
- const dest = join57(targetDir, name), runner = guessRunner(name, runners);
13861
+ const dest = join56(targetDir, name), runner = guessRunner(name, runners);
13742
13862
  writeFileSync26(dest, content, "utf8");
13743
13863
  sealedFiles.push({ path: dest, sha256: sha2562(content) });
13744
13864
  readOnlyFiles.push({ path: dest, content });
13745
13865
  if (runner)
13746
- wallTests.push({ runner, path: relative8(ctx.repoDir, dest) });
13866
+ wallTests.push({ runner, path: relative7(ctx.repoDir, dest) });
13747
13867
  }
13748
13868
  ctx.wallSealed = true;
13749
13869
  ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
13750
13870
  const baseRunner = opts.baseRunner ?? new RealBaseTestRunner, baseRun = { pass: 0, fail: 0, not_run: discarded.length }, notRunFiles = [];
13751
13871
  for (const t of wallTests) {
13752
- const r = baseRunner.run(baseDir, [t]), abs = join57(ctx.repoDir, t.path);
13872
+ const r = baseRunner.run(baseDir, [t]), abs = join56(ctx.repoDir, t.path);
13753
13873
  baseRun.pass += r.pass;
13754
13874
  baseRun.fail += r.fail;
13755
13875
  baseRun.not_run += r.not_run ?? 0;
@@ -13804,14 +13924,14 @@ var init_wall = __esm(() => {
13804
13924
 
13805
13925
  // ../../loki-ts/src/e10ext/discard.ts
13806
13926
  import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync12, mkdirSync as mkdirSync24, openSync as openSync9, readFileSync as readFileSync43, realpathSync as realpathSync20, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "fs";
13807
- import { dirname as dirname23, join as join58, relative as relative9, sep as sep12 } from "path";
13927
+ import { dirname as dirname23, join as join57, relative as relative8, sep as sep11 } from "path";
13808
13928
  function safeRestore(repoDir, f, want, mode) {
13809
- const root = realpathSync20(repoDir), fp = join58(root, f), rel = relative9(root, dirname23(fp));
13929
+ const root = realpathSync20(repoDir), fp = join57(root, f), rel = relative8(root, dirname23(fp));
13810
13930
  if (rel.startsWith(".."))
13811
13931
  throw new Error("outside repo");
13812
13932
  let cur = root;
13813
- for (const part of rel === "" ? [] : rel.split(sep12)) {
13814
- cur = join58(cur, part);
13933
+ for (const part of rel === "" ? [] : rel.split(sep11)) {
13934
+ cur = join57(cur, part);
13815
13935
  let st2;
13816
13936
  try {
13817
13937
  st2 = lstatSync12(cur);
@@ -13866,7 +13986,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
13866
13986
  return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
13867
13987
  const notProven = [];
13868
13988
  for (const [f, v] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
13869
- const fp = join58(repoDir, f);
13989
+ const fp = join57(repoDir, f);
13870
13990
  try {
13871
13991
  if (v.startsWith("!")) {
13872
13992
  const st = lstatSync12(fp);
@@ -13885,7 +14005,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
13885
14005
  try {
13886
14006
  let m = 420;
13887
14007
  try {
13888
- const l = lstatSync12(join58(repoDir, f));
14008
+ const l = lstatSync12(join57(repoDir, f));
13889
14009
  if (l.isFile())
13890
14010
  m = l.mode & 511;
13891
14011
  } catch {}
@@ -13961,9 +14081,9 @@ var init_scope2 = __esm(() => {
13961
14081
  // ../../loki-ts/src/council/role_agents.ts
13962
14082
  import { existsSync as existsSync36, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "fs";
13963
14083
  import { homedir as homedir9 } from "os";
13964
- import { join as join59 } from "path";
14084
+ import { join as join58 } from "path";
13965
14085
  function agentDirs(repoDir, env = process.env) {
13966
- return [env["LOKI_AGENTS_PROJECT_DIR"] || join59(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join59(env["XDG_CONFIG_HOME"] || join59(homedir9(), ".config"), "loki", "agents")];
14086
+ return [env["LOKI_AGENTS_PROJECT_DIR"] || join58(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join58(env["XDG_CONFIG_HOME"] || join58(homedir9(), ".config"), "loki", "agents")];
13967
14087
  }
13968
14088
  function parseAgent(file, stem2) {
13969
14089
  const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync44(file, "utf8"));
@@ -13991,7 +14111,7 @@ function loadRoleAgent(repoDir, role, env = process.env) {
13991
14111
  const ordered = [...names.filter((n2) => n2 === `${role}.md`), ...names.filter((n2) => n2 !== `${role}.md`)];
13992
14112
  for (const n2 of ordered) {
13993
14113
  try {
13994
- const a = parseAgent(join59(d, n2), n2.slice(0, -3));
14114
+ const a = parseAgent(join58(d, n2), n2.slice(0, -3));
13995
14115
  if (a && a.role === role)
13996
14116
  return a;
13997
14117
  } catch {}
@@ -14009,10 +14129,10 @@ var init_role_agents = __esm(() => {
14009
14129
 
14010
14130
  // ../../loki-ts/src/util/run_summary.ts
14011
14131
  import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as readFileSync45, renameSync as renameSync11, statSync as statSync18, writeFileSync as writeFileSync28 } from "fs";
14012
- import { join as join60 } from "path";
14132
+ import { join as join59 } from "path";
14013
14133
  function readRiskRecord(repoDir, sinceMs = 0) {
14014
14134
  try {
14015
- const p = join60(repoDir, ".loki", "state", "risk-tier.json");
14135
+ const p = join59(repoDir, ".loki", "state", "risk-tier.json");
14016
14136
  if (statSync18(p).mtimeMs < sinceMs)
14017
14137
  return null;
14018
14138
  const r = JSON.parse(readFileSync45(p, "utf8"));
@@ -14030,7 +14150,7 @@ var init_run_summary = __esm(() => {
14030
14150
 
14031
14151
  // ../../loki-ts/src/engine10/stages/xreview.ts
14032
14152
  import { existsSync as existsSync38, readFileSync as readFileSync46 } from "fs";
14033
- import { join as join61 } from "path";
14153
+ import { join as join60 } from "path";
14034
14154
  function minVerdict(verdict, review) {
14035
14155
  const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
14036
14156
  return RANK3[ceiling] < RANK3[verdict] ? ceiling : verdict;
@@ -14043,7 +14163,7 @@ function explicitReview(repoDir, env) {
14043
14163
  if (flag && isOff(ev))
14044
14164
  return "off";
14045
14165
  for (const f of ["loki.yaml", "loki.yml"]) {
14046
- const p = join61(repoDir, f);
14166
+ const p = join60(repoDir, f);
14047
14167
  if (!existsSync38(p))
14048
14168
  continue;
14049
14169
  try {
@@ -14212,7 +14332,7 @@ See also: loki cost --detail (what a run ALREADY spent)
14212
14332
 
14213
14333
  // ../../loki-ts/src/features/contract.ts
14214
14334
  import { existsSync as existsSync39, lstatSync as lstatSync13, mkdirSync as mkdirSync26, readFileSync as readFileSync47, rmSync as rmSync18, writeFileSync as writeFileSync29 } from "fs";
14215
- import { dirname as dirname26, join as join62 } from "path";
14335
+ import { dirname as dirname26, join as join61 } from "path";
14216
14336
  import { createHash as createHash16 } from "crypto";
14217
14337
  function contractEnabled(env = process.env) {
14218
14338
  return env["LOKI_CONTRACT"] !== "0";
@@ -14244,7 +14364,7 @@ function untracedLines(trace) {
14244
14364
  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)}`);
14245
14365
  }
14246
14366
  function contractPath(repoDir) {
14247
- return join62(repoDir, ".loki", "contract.json");
14367
+ return join61(repoDir, ".loki", "contract.json");
14248
14368
  }
14249
14369
  function readContract(repoDir) {
14250
14370
  const p = contractPath(repoDir);
@@ -14329,16 +14449,16 @@ var init_contract = __esm(() => {
14329
14449
  init_safe_git();
14330
14450
  STOP2 = new Set(["the", "and", "for", "with", "that", "this", "must", "should", "shall", "when", "then", "are", "was", "all", "any", "can", "not", "has", "have", "from", "into", "each", "user", "users"]);
14331
14451
  MAX_CONTRACT_BYTES = 1024 * 1024;
14332
- REQ_MAP_REL = join62(".loki", "state", "requirements-map.json");
14452
+ REQ_MAP_REL = join61(".loki", "state", "requirements-map.json");
14333
14453
  REQ_STOP = new Set(["with", "that", "this", "from", "have", "will", "should", "must", "when", "then", "into", "each", "every", "user", "users", "page", "able", "allow", "support", "ensure", "using", "their", "there", "which", "shall"]);
14334
14454
  });
14335
14455
 
14336
14456
  // ../../loki-ts/src/features/speed/seal_group.ts
14337
14457
  import { createHash as createHash17 } from "crypto";
14338
14458
  import { existsSync as existsSync40, mkdirSync as mkdirSync27, readdirSync as readdirSync20, readFileSync as readFileSync48, renameSync as renameSync12, statSync as statSync19, writeFileSync as writeFileSync30 } from "fs";
14339
- import { dirname as dirname27, join as join63 } from "path";
14459
+ import { dirname as dirname27, join as join62 } from "path";
14340
14460
  function sealGroup(runDir, rh) {
14341
- const manifestPath = join63(runDir, "group", "manifest.json");
14461
+ const manifestPath = join62(runDir, "group", "manifest.json");
14342
14462
  if (!existsSync40(manifestPath))
14343
14463
  return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
14344
14464
  const notProven = [];
@@ -14363,7 +14483,7 @@ function sealGroup(runDir, rh) {
14363
14483
  return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
14364
14484
  seen.add(id);
14365
14485
  seenLower.add(id.toLowerCase());
14366
- const dir = join63(unitsDir(runDir), id), rp = join63(dir, "receipt.json"), ep = join63(dir, "events.jsonl");
14486
+ const dir = join62(unitsDir(runDir), id), rp = join62(dir, "receipt.json"), ep = join62(dir, "events.jsonl");
14367
14487
  let bytes;
14368
14488
  try {
14369
14489
  bytes = readFileSync48(rp);
@@ -14408,7 +14528,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
14408
14528
  const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
14409
14529
  const g = receipt["group"];
14410
14530
  if (g === undefined)
14411
- return existsSync40(join63(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
14531
+ return existsSync40(join62(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
14412
14532
  if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
14413
14533
  return bad("group section malformed");
14414
14534
  const entries = g["units"];
@@ -14420,7 +14540,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
14420
14540
  return bad("unit directories do not match the receipt (missing or extra unit)");
14421
14541
  let unchecked = null;
14422
14542
  for (let i = 0;i < entries.length; i++) {
14423
- const e = entries[i], id = ids[i], dir = join63(unitsDir(runDir), id), rp = join63(dir, "receipt.json"), ep = join63(dir, "events.jsonl");
14543
+ const e = entries[i], id = ids[i], dir = join62(unitsDir(runDir), id), rp = join62(dir, "receipt.json"), ep = join62(dir, "events.jsonl");
14424
14544
  if (e["index"] !== i)
14425
14545
  return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
14426
14546
  let bytes;
@@ -14456,7 +14576,7 @@ function compositeVerdict(childVerdicts) {
14456
14576
  const failed2 = childVerdicts.filter((v) => v === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v)).length;
14457
14577
  return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v) => PASSING.has(v)) });
14458
14578
  }
14459
- var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join63(runDir, "group", "units"), readJson5 = (p) => {
14579
+ var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join62(runDir, "group", "units"), readJson5 = (p) => {
14460
14580
  try {
14461
14581
  return JSON.parse(readFileSync48(p, "utf8"));
14462
14582
  } catch {
@@ -14477,7 +14597,7 @@ var init_seal_group = __esm(() => {
14477
14597
 
14478
14598
  // ../../loki-ts/src/supply/supply_guard.ts
14479
14599
  import { existsSync as existsSync41, readFileSync as readFileSync49, statSync as statSync20 } from "fs";
14480
- import { basename as basename21, join as join64 } from "path";
14600
+ import { basename as basename21, join as join63 } from "path";
14481
14601
  function supplyEnabled(env) {
14482
14602
  return env["LOKI_SUPPLY_GUARD"] !== "0";
14483
14603
  }
@@ -14492,7 +14612,7 @@ function isManifestPath(path) {
14492
14612
  return MANIFESTS.test(basename21(path));
14493
14613
  }
14494
14614
  function readDeclared(repoDir) {
14495
- const p = join64(repoDir, ".loki", DECLARED_FILE);
14615
+ const p = join63(repoDir, ".loki", DECLARED_FILE);
14496
14616
  if (!existsSync41(p))
14497
14617
  return { deps: [], problem: null };
14498
14618
  try {
@@ -14518,7 +14638,7 @@ function readDeclared(repoDir) {
14518
14638
  }
14519
14639
  }
14520
14640
  function readAllowlist(repoDir) {
14521
- const p = join64(repoDir, ".loki", "supply-allowlist");
14641
+ const p = join63(repoDir, ".loki", "supply-allowlist");
14522
14642
  if (!existsSync41(p))
14523
14643
  return new Set;
14524
14644
  try {
@@ -14563,7 +14683,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14563
14683
  if (eco === "npm") {
14564
14684
  if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
14565
14685
  return true;
14566
- return files(join64(repoDir, ".npmrc"), home ? join64(home, ".npmrc") : "").some((t) => t.split(`
14686
+ return files(join63(repoDir, ".npmrc"), home ? join63(home, ".npmrc") : "").some((t) => t.split(`
14567
14687
  `).some((l) => {
14568
14688
  const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
14569
14689
  return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
@@ -14572,7 +14692,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14572
14692
  if (eco === "pypi") {
14573
14693
  if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
14574
14694
  return true;
14575
- const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join64(home, ".config", "pip", "pip.conf") : "", home ? join64(home, ".pip", "pip.conf") : "", join64(repoDir, "pip.conf")];
14695
+ const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join63(home, ".config", "pip", "pip.conf") : "", home ? join63(home, ".pip", "pip.conf") : "", join63(repoDir, "pip.conf")];
14576
14696
  return files(...cfg).some((t) => t.split(`
14577
14697
  `).some((l) => {
14578
14698
  const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
@@ -14582,7 +14702,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14582
14702
  if (eco === "cargo") {
14583
14703
  if (Object.keys(env).some((k) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k) || /^CARGO_SOURCE_/.test(k)))
14584
14704
  return true;
14585
- return files(join64(repoDir, ".cargo", "config.toml"), join64(repoDir, ".cargo", "config"), home ? join64(home, ".cargo", "config.toml") : "", home ? join64(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
14705
+ return files(join63(repoDir, ".cargo", "config.toml"), join63(repoDir, ".cargo", "config"), home ? join63(home, ".cargo", "config.toml") : "", home ? join63(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
14586
14706
  }
14587
14707
  if (eco === "go") {
14588
14708
  const gp = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
@@ -14722,7 +14842,7 @@ var init_supply_guard = __esm(() => {
14722
14842
  // ../../loki-ts/src/engine10/stages/seal.ts
14723
14843
  import { createHash as createHash18 } from "crypto";
14724
14844
  import { existsSync as existsSync42, readdirSync as readdirSync21, mkdirSync as mkdirSync28, readFileSync as readFileSync50, writeFileSync as writeFileSync31 } from "fs";
14725
- import { basename as basename22, isAbsolute as isAbsolute9, join as join65, relative as relative10 } from "path";
14845
+ import { basename as basename22, isAbsolute as isAbsolute9, join as join64, relative as relative9 } from "path";
14726
14846
  function sanitizeReason(s) {
14727
14847
  const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
14728
14848
  const capped = collapsed.length > 500 ? `${collapsed.slice(0, 500)}...` : collapsed;
@@ -14797,7 +14917,7 @@ function renderReceiptMd(r) {
14797
14917
  `);
14798
14918
  }
14799
14919
  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) => createHash18("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 !== "") : [], receiptRel = (ctx) => {
14800
- const r = relative10(ctx.repoDir, join65(ctx.runDir, "receipt.json"));
14920
+ const r = relative9(ctx.repoDir, join64(ctx.runDir, "receipt.json"));
14801
14921
  return r.startsWith("..") || isAbsolute9(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
14802
14922
  }, commitStage, sealStage;
14803
14923
  var init_seal = __esm(() => {
@@ -14906,7 +15026,7 @@ var init_seal = __esm(() => {
14906
15026
  if (wallNotRun > 0) {
14907
15027
  try {
14908
15028
  const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename22(String(f.path))));
14909
- for (const n2 of readdirSync21(join65(ctx.runDir, "wall")).sort())
15029
+ for (const n2 of readdirSync21(join64(ctx.runDir, "wall")).sort())
14910
15030
  if (!kept.has(n2))
14911
15031
  notProven.add(`wall test discarded: ${n2} (not_run)`);
14912
15032
  } catch {}
@@ -14969,19 +15089,19 @@ var init_seal = __esm(() => {
14969
15089
  for (const [s, d] of Object.entries(o))
14970
15090
  if (typeof d?.duration_s === "number")
14971
15091
  stages[s] = d.duration_s;
14972
- const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join65(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
15092
+ const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join64(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
14973
15093
  const iterIds = Object.values(o).flatMap((d) => [...strs2(d?.iteration_ids), ...strs2([d?.iteration_id])]);
14974
15094
  if (iterIds.length === 0)
14975
15095
  notProven.add("cost not measured (no iteration ids recorded)");
14976
15096
  const cost = ctx.cost.read(ctx.repoDir, iterIds);
14977
15097
  if (cost.unmetered)
14978
15098
  notProven.add("cost unmetered (CLI invoker; recorded as 0)");
14979
- const eventsPath = join65(ctx.runDir, "events.jsonl");
15099
+ const eventsPath = join64(ctx.runDir, "events.jsonl");
14980
15100
  const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
14981
15101
  const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
14982
15102
  if (wallFiles.length > 0 && wallPassed === null)
14983
15103
  notProven.add("wall result not recorded by verify");
14984
- 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(join65(ctx.repoDir, ".loki"), liveArchivedCosts(join65(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
15104
+ 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(join64(ctx.repoDir, ".loki"), liveArchivedCosts(join64(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
14985
15105
  if (routeBlock)
14986
15106
  for (const l of routeNotProven(routeBlock))
14987
15107
  notProven.add(l);
@@ -15045,11 +15165,17 @@ var init_seal = __esm(() => {
15045
15165
  }
15046
15166
  const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
15047
15167
  mkdirSync28(ctx.runDir, { recursive: true });
15048
- const path = join65(ctx.runDir, "receipt.json");
15168
+ const path = join64(ctx.runDir, "receipt.json");
15049
15169
  writeFileSync31(path, JSON.stringify(receipt, null, 2) + `
15050
15170
  `);
15051
- writeFileSync31(join65(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
15171
+ writeFileSync31(join64(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
15052
15172
  recordRun(process.env, ctx.repoDir, ranModel(o.implement, ctx.model, o.fix), verdict, cost.usd, cost.unmetered === true, totalS);
15173
+ try {
15174
+ hooks.sealed?.(ctx.runDir, JSON.parse(JSON.stringify(receipt), (_k, v) => v && typeof v === "object" ? Object.freeze(v) : v));
15175
+ } catch (e) {
15176
+ process.stderr.write(`ai-bom skipped: ${e.message}
15177
+ `);
15178
+ }
15053
15179
  const signed = sig.jwt !== null;
15054
15180
  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) } : {} };
15055
15181
  try {
@@ -15155,13 +15281,13 @@ var init_receipt_dsse = () => {};
15155
15281
 
15156
15282
  // ../../loki-ts/src/util/composite_seal.ts
15157
15283
  import { existsSync as existsSync43, readFileSync as readFileSync52 } from "fs";
15158
- import { basename as basename23, dirname as dirname29, join as join66 } from "path";
15284
+ import { basename as basename23, dirname as dirname29, join as join65 } from "path";
15159
15285
  function logProblem(runDir, integ) {
15160
15286
  if (typeof integ["log_sha256"] !== "string")
15161
15287
  return null;
15162
15288
  let b;
15163
15289
  try {
15164
- b = readFileSync52(join66(runDir, "integration.log"));
15290
+ b = readFileSync52(join65(runDir, "integration.log"));
15165
15291
  } catch {
15166
15292
  return "integration.log is missing but integration.json records its hash";
15167
15293
  }
@@ -15184,13 +15310,13 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
15184
15310
  return bad("body malformed");
15185
15311
  let ibytes;
15186
15312
  try {
15187
- ibytes = readFileSync52(join66(runDir, "integration.json"));
15313
+ ibytes = readFileSync52(join65(runDir, "integration.json"));
15188
15314
  } catch {
15189
15315
  return bad("integration.json missing");
15190
15316
  }
15191
15317
  if (sha3(ibytes) !== receipt["integration_sha256"])
15192
15318
  return bad("integration.json does not match its recorded hash");
15193
- const integ = readJson5(join66(runDir, "integration.json"));
15319
+ const integ = readJson5(join65(runDir, "integration.json"));
15194
15320
  if (!isObj10(integ) || !isObj10(integ["outcomes"]))
15195
15321
  return bad("integration.json has no outcomes");
15196
15322
  const iprob = integrationProblem(integ);
@@ -15220,7 +15346,7 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
15220
15346
  return bad(`child ${text2(repo, 80) || "?"} has an invalid receipt path`);
15221
15347
  if (outcomes[repo] !== "ok")
15222
15348
  return bad(`child ${text2(repo, 80)} did not finish ok in integration.json`);
15223
- const rp = join66(runDir, rel);
15349
+ const rp = join65(runDir, rel);
15224
15350
  let bytes;
15225
15351
  try {
15226
15352
  bytes = readFileSync52(rp);
@@ -15273,7 +15399,7 @@ var init_keys_cmd = __esm(() => {
15273
15399
 
15274
15400
  // ../../loki-ts/src/engine10/verify_cmd.ts
15275
15401
  import { existsSync as existsSync44, readFileSync as readFileSync53, renameSync as renameSync13, statSync as statSync22, writeFileSync as writeFileSync32 } from "fs";
15276
- import { basename as basename24, dirname as dirname30, join as join67 } from "path";
15402
+ import { basename as basename24, dirname as dirname30, join as join66 } from "path";
15277
15403
  import { createHash as createHash19, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
15278
15404
  function pubFor(kid, given) {
15279
15405
  if (given)
@@ -15325,7 +15451,7 @@ function checkEventLog(receiptPath, receipt) {
15325
15451
  const claims = st !== null && typeof st === "object" && Object.keys(st).length > 0;
15326
15452
  return claims ? "the receipt records stages but binds the empty-log hash, so no events.jsonl can back it (missing, empty or non-empty); the receipt is forged or was sealed without a log. Re-run the task to produce a fresh receipt" : null;
15327
15453
  }
15328
- const path = join67(dirname30(receiptPath), "events.jsonl");
15454
+ const path = join66(dirname30(receiptPath), "events.jsonl");
15329
15455
  if (!existsSync44(path))
15330
15456
  return "events.jsonl is missing";
15331
15457
  const raw2 = readFileSync53(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
@@ -15344,7 +15470,7 @@ function checkEventLog(receiptPath, receipt) {
15344
15470
  return h.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
15345
15471
  }
15346
15472
  function checkLogSeal(receiptPath, hash, kid, given) {
15347
- const path = join67(dirname30(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
15473
+ const path = join66(dirname30(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
15348
15474
  if (!events2.some((e) => e.type === "receipt.sealed" && e.data["receipt_sha256"] === hash))
15349
15475
  return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
15350
15476
  if (done < 0)
@@ -15455,7 +15581,7 @@ var init_verify_cmd = __esm(() => {
15455
15581
 
15456
15582
  // src/server/app.ts
15457
15583
  import { existsSync as existsSync46, readFileSync as readFileSync56, statSync as statSync23 } from "fs";
15458
- import { join as join70, resolve as resolve15, sep as sep14 } from "path";
15584
+ import { join as join69, resolve as resolve15, sep as sep13 } from "path";
15459
15585
 
15460
15586
  // node_modules/hono/dist/request/constants.js
15461
15587
  var GET_MATCH_RESULT = Symbol();
@@ -21219,9 +21345,9 @@ function writeAnswer(dir, source, run, answer) {
21219
21345
  }
21220
21346
 
21221
21347
  // src/server/diffstat.ts
21222
- import { execFileSync } from "child_process";
21348
+ init_safe_git();
21223
21349
  import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2, realpathSync as realpathSync2 } from "fs";
21224
- import { join as join4, sep as sep2 } from "path";
21350
+ import { join as join5, sep as sep2 } from "path";
21225
21351
  var ID2 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
21226
21352
  var SHA = /^[0-9a-f]{40,64}$/;
21227
21353
  var MAX_RECEIPT_BYTES = 1024 * 1024;
@@ -21245,7 +21371,7 @@ function parseNumstat(out) {
21245
21371
  function readReceipt(runDir) {
21246
21372
  let fd;
21247
21373
  try {
21248
- fd = openSync2(join4(runDir, "receipt.json"), "r");
21374
+ fd = openSync2(join5(runDir, "receipt.json"), "r");
21249
21375
  } catch {
21250
21376
  return null;
21251
21377
  }
@@ -21276,12 +21402,12 @@ function diffStatFor(db, source, run) {
21276
21402
  let repoReal, runsRoot, runDir;
21277
21403
  try {
21278
21404
  repoReal = realpathSync2(repo.p);
21279
- runsRoot = realpathSync2(join4(repoReal, ".loki", "runs"));
21280
- runDir = realpathSync2(join4(runsRoot, run));
21405
+ runsRoot = realpathSync2(join5(repoReal, ".loki", "runs"));
21406
+ runDir = realpathSync2(join5(runsRoot, run));
21281
21407
  } catch {
21282
21408
  return null;
21283
21409
  }
21284
- if (runDir !== join4(runsRoot, run) || !runDir.startsWith(runsRoot + sep2))
21410
+ if (runDir !== join5(runsRoot, run) || !runDir.startsWith(runsRoot + sep2))
21285
21411
  return null;
21286
21412
  const r = readReceipt(runDir);
21287
21413
  const base = typeof r?.base_sha === "string" ? r.base_sha : "", head = typeof r?.head_sha === "string" ? r.head_sha : "";
@@ -21293,7 +21419,7 @@ function diffStatFor(db, source, run) {
21293
21419
  return null;
21294
21420
  try {
21295
21421
  diffStatGitRuns.n++;
21296
- const out = execFileSync("git", ["-C", repoReal, "-c", "core.quotePath=false", "diff", "--numstat", "--no-renames", `${base}..${head}`, "--"], { env: gitEnv(), timeout: GIT_TIMEOUT_MS, maxBuffer: 8 * 1024 * 1024, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
21422
+ const out = safeGit(repoReal, ["-c", "core.quotePath=false", "diff", "--numstat", "--no-renames", `${base}..${head}`, "--"], { env: gitEnv(), timeout: GIT_TIMEOUT_MS, maxBuffer: 8 * 1024 * 1024 });
21297
21423
  const files = parseNumstat(out);
21298
21424
  const stat = { base, head, files, added: files.reduce((n2, f) => n2 + (f.added ?? 0), 0), removed: files.reduce((n2, f) => n2 + (f.removed ?? 0), 0), source: "git" };
21299
21425
  cache.set(key, stat);
@@ -21308,7 +21434,7 @@ function diffStatFor(db, source, run) {
21308
21434
  import { createHash, createPublicKey, verify } from "crypto";
21309
21435
  import { readFileSync as readFileSync2 } from "fs";
21310
21436
  import { homedir as homedir3 } from "os";
21311
- import { join as join5 } from "path";
21437
+ import { join as join6 } from "path";
21312
21438
  var SHA2 = /^[0-9a-f]{64}$/;
21313
21439
  var SEAL_LINE = "log.sealed";
21314
21440
  var REDACTED = /\[REDACTED(?::[A-Z_]+)?\]/;
@@ -21326,7 +21452,7 @@ function localKeyInfo(env = process.env) {
21326
21452
  if (inline)
21327
21453
  pub = createPublicKey(inline);
21328
21454
  else {
21329
- const file = given || join5(env["HOME"] || homedir3(), ".loki", "keys", "receipt-ed25519.pem");
21455
+ const file = given || join6(env["HOME"] || homedir3(), ".loki", "keys", "receipt-ed25519.pem");
21330
21456
  try {
21331
21457
  pub = createPublicKey(readFileSync2(file));
21332
21458
  } catch (e) {
@@ -21820,7 +21946,7 @@ init_backfill();
21820
21946
 
21821
21947
  // src/server/reconcile.ts
21822
21948
  import { realpathSync as realpathSync4 } from "fs";
21823
- import { join as join9, resolve, sep as sep3 } from "path";
21949
+ import { join as join10, resolve, sep as sep3 } from "path";
21824
21950
  init_run_pid();
21825
21951
  var STOPPED_VERDICT = "STOPPED";
21826
21952
  var STALE_GRACE_MS = 120000;
@@ -21840,7 +21966,7 @@ function reconcileDeadRuns(db, o = {}) {
21840
21966
  } catch {
21841
21967
  continue;
21842
21968
  }
21843
- const root = join9(repo, ".loki", "runs"), dir = resolve(root, r.runId);
21969
+ const root = join10(repo, ".loki", "runs"), dir = resolve(root, r.runId);
21844
21970
  if (!dir.startsWith(root + sep3))
21845
21971
  continue;
21846
21972
  if (verify2(dir, r.runId).ok)
@@ -21907,7 +22033,7 @@ function mountRepos(act, db, peerIsLoopback2, repoDir, gh = defaultGh) {
21907
22033
 
21908
22034
  // src/server/routes/artifacts.ts
21909
22035
  import { closeSync as closeSync3, fstatSync as fstatSync3, openSync as openSync3, readSync as readSync3, realpathSync as realpathSync6 } from "fs";
21910
- import { join as join12, sep as sep4 } from "path";
22036
+ import { join as join13, sep as sep4 } from "path";
21911
22037
  var MAX_ARTIFACT_BYTES = 5 * 1024 * 1024;
21912
22038
  var EVENTS_DEFAULT = 500;
21913
22039
  var EVENTS_MAX = 1000;
@@ -21988,15 +22114,15 @@ function mount(ctx) {
21988
22114
  return c.json({ error: "artifact not available" }, 404);
21989
22115
  let runsRoot, runDir, file;
21990
22116
  try {
21991
- runsRoot = realpathSync6(join12(repo.p, ".loki", "runs"));
21992
- runDir = realpathSync6(join12(runsRoot, run));
22117
+ runsRoot = realpathSync6(join13(repo.p, ".loki", "runs"));
22118
+ runDir = realpathSync6(join13(runsRoot, run));
21993
22119
  } catch {
21994
22120
  return c.json({ error: "artifact not found" }, 404);
21995
22121
  }
21996
- if (runDir !== join12(runsRoot, run))
22122
+ if (runDir !== join13(runsRoot, run))
21997
22123
  return c.json({ error: "artifact not found" }, 404);
21998
22124
  try {
21999
- file = realpathSync6(join12(runDir, name));
22125
+ file = realpathSync6(join13(runDir, name));
22000
22126
  } catch {
22001
22127
  return c.json({ error: "artifact not found" }, 404);
22002
22128
  }
@@ -22025,9 +22151,9 @@ function mount(ctx) {
22025
22151
  import { basename as basename4 } from "path";
22026
22152
 
22027
22153
  // src/ask/policy.ts
22028
- import { chmodSync as chmodSync3, existsSync as existsSync5, lstatSync, mkdtempSync, readFileSync as readFileSync7, realpathSync as realpathSync7, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
22029
- import { tmpdir as tmpdir2 } from "os";
22030
- import { dirname as dirname2, join as join13, parse } from "path";
22154
+ import { chmodSync as chmodSync3, existsSync as existsSync5, lstatSync as lstatSync2, mkdtempSync as mkdtempSync2, readFileSync as readFileSync7, realpathSync as realpathSync7, rmSync as rmSync3, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
22155
+ import { tmpdir as tmpdir3 } from "os";
22156
+ import { dirname as dirname2, join as join14, parse } from "path";
22031
22157
  var MCP_SERVER_NAME = "loki-ask";
22032
22158
  var MCP_SERVER_SCRIPT = "packages/control-plane/src/ask/tools_server.ts";
22033
22159
  var MCP_SERVER_BUNDLE = "ask-tools-server.js";
@@ -22038,8 +22164,8 @@ function resolveToolsServer(startDir) {
22038
22164
  if (d === parse(d).root)
22039
22165
  break;
22040
22166
  }
22041
- const bundles = dirs.flatMap((d) => [join13(d, MCP_SERVER_BUNDLE), join13(d, "dist", MCP_SERVER_BUNDLE), join13(d, "packages/control-plane/dist", MCP_SERVER_BUNDLE)]);
22042
- const sources2 = dirs.flatMap((d) => [join13(d, "src/ask/tools_server.ts"), join13(d, MCP_SERVER_SCRIPT)]);
22167
+ const bundles = dirs.flatMap((d) => [join14(d, MCP_SERVER_BUNDLE), join14(d, "dist", MCP_SERVER_BUNDLE), join14(d, "packages/control-plane/dist", MCP_SERVER_BUNDLE)]);
22168
+ const sources2 = dirs.flatMap((d) => [join14(d, "src/ask/tools_server.ts"), join14(d, MCP_SERVER_SCRIPT)]);
22043
22169
  return [...bundles, ...sources2].find((f) => existsSync5(f)) ?? null;
22044
22170
  }
22045
22171
  var ALLOWED_TOOLS = `mcp__${MCP_SERVER_NAME}__*`;
@@ -22072,38 +22198,38 @@ function buildMcpConfig(serverScript, dbPath) {
22072
22198
  var PREFIX = "loki-ask.";
22073
22199
  var MARKER = ".loki-ask-owned";
22074
22200
  function createJobDir() {
22075
- const root = realpathSync7(tmpdir2());
22201
+ const root = realpathSync7(tmpdir3());
22076
22202
  for (let d = root;; d = dirname2(d)) {
22077
- if (existsSync5(join13(d, ".git")))
22203
+ if (existsSync5(join14(d, ".git")))
22078
22204
  throw new Error(`temp root is inside a repo: ${d}`);
22079
22205
  if (d === dirname2(d))
22080
22206
  break;
22081
22207
  }
22082
- const dir = mkdtempSync(join13(root, PREFIX));
22208
+ const dir = mkdtempSync2(join14(root, PREFIX));
22083
22209
  chmodSync3(dir, 448);
22084
- writeFileSync4(join13(dir, MARKER), dir, { mode: 384 });
22210
+ writeFileSync4(join14(dir, MARKER), dir, { mode: 384 });
22085
22211
  return dir;
22086
22212
  }
22087
22213
  function removeJobDir(dir) {
22088
- const root = realpathSync7(tmpdir2());
22214
+ const root = realpathSync7(tmpdir3());
22089
22215
  const refuse = (why) => {
22090
22216
  throw new Error(`refusing to remove ${dir}: ${why}`);
22091
22217
  };
22092
22218
  if (dirname2(dir) !== root || !dir.slice(root.length + 1).startsWith(PREFIX))
22093
22219
  refuse("not a scratch dir name");
22094
- const st = lstatSync(dir);
22220
+ const st = lstatSync2(dir);
22095
22221
  if (!st.isDirectory() || st.isSymbolicLink())
22096
22222
  refuse("not a plain directory");
22097
22223
  if (st.uid !== process.getuid())
22098
22224
  refuse("not owned by this user");
22099
22225
  if ((st.mode & 511) !== 448)
22100
22226
  refuse("mode is not 0700");
22101
- const marker = join13(dir, MARKER);
22227
+ const marker = join14(dir, MARKER);
22102
22228
  if (!existsSync5(marker) || readFileSync7(marker, "utf8") !== dir)
22103
22229
  refuse("marker missing or wrong");
22104
- if (!statSync3(marker).isFile())
22230
+ if (!statSync4(marker).isFile())
22105
22231
  refuse("marker is not a file");
22106
- rmSync2(dir, { recursive: true, force: true });
22232
+ rmSync3(dir, { recursive: true, force: true });
22107
22233
  }
22108
22234
 
22109
22235
  // src/ask/invoke.ts
@@ -22222,13 +22348,13 @@ function pidAlive(pid) {
22222
22348
  // src/ask/worker.ts
22223
22349
  import { spawn as spawn2 } from "child_process";
22224
22350
  import { writeFileSync as writeFileSync5 } from "fs";
22225
- import { join as join15 } from "path";
22351
+ import { join as join16 } from "path";
22226
22352
 
22227
22353
  // src/server/spawn.ts
22228
22354
  import { spawn } from "child_process";
22229
- import { existsSync as existsSync6, readFileSync as readFileSync8, realpathSync as realpathSync8, statSync as statSync4 } from "fs";
22355
+ import { existsSync as existsSync6, readFileSync as readFileSync8, realpathSync as realpathSync8, statSync as statSync5 } from "fs";
22230
22356
  import { homedir as homedir5 } from "os";
22231
- import { basename as basename3, dirname as dirname3, join as join14, resolve as resolve4 } from "path";
22357
+ import { basename as basename3, dirname as dirname3, join as join15, resolve as resolve4 } from "path";
22232
22358
  var ISSUE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}\/[A-Za-z0-9._-]{1,100}#[1-9][0-9]{0,8}$/;
22233
22359
  var TASK = /^[A-Za-z0-9][A-Za-z0-9 .,_/#@+=-]{0,499}$/;
22234
22360
  var hasDotDot = (t) => t.split(/[\\/ ]/).some((seg) => seg.startsWith(".."));
@@ -22257,14 +22383,14 @@ function repoRefusal(cwd, env = process.env) {
22257
22383
  if (dir === home)
22258
22384
  return "refusing to start a run in your home directory; pick a project repository (a folder with its own .git)";
22259
22385
  for (let d = dir;d !== "/" && d !== home && d !== dirname3(d); d = dirname3(d))
22260
- if (existsSync6(join14(d, ".git")))
22386
+ if (existsSync6(join15(d, ".git")))
22261
22387
  return null;
22262
22388
  return `${cwd} is not a git repository; pick a registered project repository`;
22263
22389
  }
22264
22390
  function registryRepos2(env = process.env) {
22265
22391
  try {
22266
- const j = JSON.parse(readFileSync8(join14(env.HOME || homedir5(), ".loki", "dashboard", "projects.json"), "utf8"));
22267
- return Object.values(j.projects ?? {}).map((p) => typeof p?.path === "string" ? p.path : "").filter((p) => p && existsSync6(p) && statSync4(p).isDirectory());
22392
+ const j = JSON.parse(readFileSync8(join15(env.HOME || homedir5(), ".loki", "dashboard", "projects.json"), "utf8"));
22393
+ return Object.values(j.projects ?? {}).map((p) => typeof p?.path === "string" ? p.path : "").filter((p) => p && existsSync6(p) && statSync5(p).isDirectory());
22268
22394
  } catch {
22269
22395
  return [];
22270
22396
  }
@@ -22519,7 +22645,7 @@ async function runAskJob(db, messageId, o) {
22519
22645
  if (!toolsServer)
22520
22646
  return fail("Ask tools server not found (expected ask-tools-server.js in dist/ or src/ask/tools_server.ts); rebuild with bun run build:server");
22521
22647
  jobDir = createJobDir();
22522
- const mcpConfigPath = join15(jobDir, "mcp.json");
22648
+ const mcpConfigPath = join16(jobDir, "mcp.json");
22523
22649
  writeFileSync5(mcpConfigPath, JSON.stringify(buildMcpConfig(toolsServer, o.dbPath)), { mode: 384 });
22524
22650
  const inv = buildInvocation({
22525
22651
  provider: thread.provider,
@@ -22982,13 +23108,13 @@ function mount4(ctx) {
22982
23108
  }
22983
23109
 
22984
23110
  // src/server/routes/checkpoints.ts
22985
- import { execFileSync as execFileSync3 } from "child_process";
22986
- import { appendFileSync, copyFileSync, cpSync, existsSync as existsSync8, lstatSync as lstatSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync10, realpathSync as realpathSync9, rmSync as rmSync3, statSync as statSync6, writeFileSync as writeFileSync6 } from "fs";
22987
- import { join as join17, sep as sep5 } from "path";
23111
+ init_safe_git();
23112
+ import { appendFileSync, copyFileSync, cpSync, existsSync as existsSync8, lstatSync as lstatSync3, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync10, realpathSync as realpathSync9, rmSync as rmSync4, statSync as statSync7, writeFileSync as writeFileSync6 } from "fs";
23113
+ import { join as join18, sep as sep5 } from "path";
22988
23114
 
22989
23115
  // src/server/routes/cost_ledger.ts
22990
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync5 } from "fs";
22991
- import { join as join16 } from "path";
23116
+ import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
23117
+ import { join as join17 } from "path";
22992
23118
  var isNum = (v) => typeof v === "number" && Number.isFinite(v);
22993
23119
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
22994
23120
  var r6 = (n2) => Math.round(n2 * 1e6) / 1e6;
@@ -23019,7 +23145,7 @@ var DEFAULT_PRICING = {
23019
23145
  "gpt-5.6-luna": { input: 0.5, output: 4 }
23020
23146
  };
23021
23147
  function pricing(lokiDir) {
23022
- const d = readJson(join16(lokiDir, "pricing.json"));
23148
+ const d = readJson(join17(lokiDir, "pricing.json"));
23023
23149
  const models = isObj3(d) && isObj3(d.models) ? d.models : {};
23024
23150
  return { ...DEFAULT_PRICING, ...models };
23025
23151
  }
@@ -23032,7 +23158,7 @@ function modelCost(table, model, inp, out, cr = 0, cw = 0) {
23032
23158
  return r6((inp * ir + out * or2 + cr * crr + cw * cwr) / 1e6);
23033
23159
  }
23034
23160
  function iterationRecords(lokiDir) {
23035
- const dir = join16(lokiDir, "metrics", "efficiency");
23161
+ const dir = join17(lokiDir, "metrics", "efficiency");
23036
23162
  let names = [];
23037
23163
  try {
23038
23164
  names = readdirSync3(dir).filter((n2) => /^iteration-.*\.json$/.test(n2)).sort();
@@ -23041,7 +23167,7 @@ function iterationRecords(lokiDir) {
23041
23167
  }
23042
23168
  const out = [];
23043
23169
  for (const n2 of names) {
23044
- const d = readJson(join16(dir, n2));
23170
+ const d = readJson(join17(dir, n2));
23045
23171
  if (isObj3(d))
23046
23172
  out.push(d);
23047
23173
  }
@@ -23078,7 +23204,7 @@ function costSnapshot(lokiDir) {
23078
23204
  }
23079
23205
  }
23080
23206
  if (tIn === 0 && tOut === 0) {
23081
- const ctx = readJson(join16(lokiDir, "context", "tracking.json"));
23207
+ const ctx = readJson(join17(lokiDir, "context", "tracking.json"));
23082
23208
  const totals = isObj3(ctx) && isObj3(ctx.totals) ? ctx.totals : {};
23083
23209
  tIn = num0(totals.total_input);
23084
23210
  tOut = num0(totals.total_output);
@@ -23104,7 +23230,7 @@ function costSnapshot(lokiDir) {
23104
23230
  }
23105
23231
  }
23106
23232
  let limit = null, used = null, remaining = null;
23107
- const bd = readJson(join16(lokiDir, "metrics", "budget.json"));
23233
+ const bd = readJson(join17(lokiDir, "metrics", "budget.json"));
23108
23234
  if (isObj3(bd) && isNum(bd.limit)) {
23109
23235
  limit = bd.limit;
23110
23236
  if (recorded && !unknownUsd) {
@@ -23155,7 +23281,7 @@ function budgetSnapshot(lokiDir) {
23155
23281
  total += priced(table, d);
23156
23282
  }
23157
23283
  let limit = null;
23158
- const bd = readJson(join16(lokiDir, "metrics", "budget.json"));
23284
+ const bd = readJson(join17(lokiDir, "metrics", "budget.json"));
23159
23285
  if (isObj3(bd)) {
23160
23286
  const l = bd.limit || bd.budget_limit;
23161
23287
  limit = isNum(l) ? l : null;
@@ -23206,19 +23332,19 @@ function costTimeline(lokiDir) {
23206
23332
  }
23207
23333
  const runs2 = [];
23208
23334
  let projectTotal = 0, runsMeasured = 0;
23209
- const proofs = join16(lokiDir, "proofs");
23335
+ const proofs = join17(lokiDir, "proofs");
23210
23336
  let entries = [];
23211
23337
  try {
23212
23338
  entries = readdirSync3(proofs).sort();
23213
23339
  } catch {}
23214
23340
  for (const e of entries) {
23215
23341
  try {
23216
- if (!statSync5(join16(proofs, e)).isDirectory())
23342
+ if (!statSync6(join17(proofs, e)).isDirectory())
23217
23343
  continue;
23218
23344
  } catch {
23219
23345
  continue;
23220
23346
  }
23221
- const p = readJson(join16(proofs, e, "proof.json"));
23347
+ const p = readJson(join17(proofs, e, "proof.json"));
23222
23348
  if (!isObj3(p))
23223
23349
  continue;
23224
23350
  const cost = isObj3(p.cost) ? p.cost : {};
@@ -23248,7 +23374,7 @@ function costTimeline(lokiDir) {
23248
23374
  ...recorded || runsMeasured ? {} : { not_measured: NOT_MEASURED }
23249
23375
  };
23250
23376
  }
23251
- var lokiDirOf = (repoDir) => join16(repoDir, ".loki");
23377
+ var lokiDirOf = (repoDir) => join17(repoDir, ".loki");
23252
23378
  var lokiDirExists = (repoDir) => existsSync7(lokiDirOf(repoDir));
23253
23379
  function mount5(ctx) {
23254
23380
  const deny = { error: "loopback only without a token" };
@@ -23263,8 +23389,8 @@ var SAFE_ID = /^[A-Za-z0-9_-]{1,128}$/;
23263
23389
  var MAX_CHECKPOINTS = 50;
23264
23390
  var ROLLBACK_ALLOW = new Set(["session.json", "dashboard-state.json", "CONTINUITY.md", "autonomy-state.json", "state", "queue"]);
23265
23391
  var validCheckpointId = (id) => SAFE_ID.test(id);
23266
- var storeOf = (repoDir) => join17(repoDir, ".loki", "state", "checkpoints");
23267
- var lokiOf = (repoDir) => join17(repoDir, ".loki");
23392
+ var storeOf = (repoDir) => join18(repoDir, ".loki", "state", "checkpoints");
23393
+ var lokiOf = (repoDir) => join18(repoDir, ".loki");
23268
23394
  var readObj = (f) => {
23269
23395
  try {
23270
23396
  const d = JSON.parse(readFileSync10(f, "utf8"));
@@ -23278,7 +23404,7 @@ function listCheckpoints(repoDir, limit = 20) {
23278
23404
  const store = storeOf(repoDir);
23279
23405
  let lines = [];
23280
23406
  try {
23281
- lines = readFileSync10(join17(store, "index.jsonl"), "utf8").split(`
23407
+ lines = readFileSync10(join18(store, "index.jsonl"), "utf8").split(`
23282
23408
  `);
23283
23409
  } catch {
23284
23410
  return [];
@@ -23306,7 +23432,7 @@ function listCheckpoints(repoDir, limit = 20) {
23306
23432
  message: str2(raw2.task) ?? str2(raw2.message) ?? str2(raw2.task_description),
23307
23433
  iteration: Number.isInteger(it) ? it : null
23308
23434
  };
23309
- const meta = readObj(join17(store, id, "metadata.json"));
23435
+ const meta = readObj(join18(store, id, "metadata.json"));
23310
23436
  if (meta) {
23311
23437
  cp.git_branch = str2(meta.git_branch);
23312
23438
  cp.provider = str2(meta.provider);
@@ -23314,7 +23440,7 @@ function listCheckpoints(repoDir, limit = 20) {
23314
23440
  cp.message ??= str2(meta.task_description);
23315
23441
  cp.git_sha ??= str2(meta.git_sha);
23316
23442
  cp.created_at ??= str2(meta.timestamp);
23317
- cp.files_count = countFiles(join17(store, id));
23443
+ cp.files_count = countFiles(join18(store, id));
23318
23444
  }
23319
23445
  out.push(cp);
23320
23446
  }
@@ -23325,7 +23451,7 @@ function countFiles(dir) {
23325
23451
  const walk = (d, top) => {
23326
23452
  for (const e of readdirSync4(d, { withFileTypes: true })) {
23327
23453
  if (e.isDirectory())
23328
- walk(join17(d, e.name), false);
23454
+ walk(join18(d, e.name), false);
23329
23455
  else if (e.isFile() && !(top && e.name === "metadata.json"))
23330
23456
  n2++;
23331
23457
  }
@@ -23336,11 +23462,11 @@ function countFiles(dir) {
23336
23462
  return n2;
23337
23463
  }
23338
23464
  function getCheckpoint(repoDir, id) {
23339
- return validCheckpointId(id) ? readObj(join17(storeOf(repoDir), id, "metadata.json")) : null;
23465
+ return validCheckpointId(id) ? readObj(join18(storeOf(repoDir), id, "metadata.json")) : null;
23340
23466
  }
23341
23467
  var gitHead = (repoDir) => {
23342
23468
  try {
23343
- return execFileSync3("git", ["rev-parse", "HEAD"], { cwd: repoDir, timeout: 5000, stdio: ["ignore", "pipe", "ignore"] }).toString().trim() || null;
23469
+ return safeGit(repoDir, ["rev-parse", "HEAD"], { timeout: 5000 }).trim() || null;
23344
23470
  } catch {
23345
23471
  return null;
23346
23472
  }
@@ -23348,60 +23474,60 @@ var gitHead = (repoDir) => {
23348
23474
  function createCheckpoint(repoDir, message, now2 = new Date) {
23349
23475
  const store = storeOf(repoDir), loki = lokiOf(repoDir);
23350
23476
  mkdirSync3(store, { recursive: true });
23351
- const id = `chk-${stamp(now2)}`, dir = join17(store, id);
23477
+ const id = `chk-${stamp(now2)}`, dir = join18(store, id);
23352
23478
  mkdirSync3(dir, { recursive: true });
23353
23479
  for (const f of ["dashboard-state.json", "session.json"]) {
23354
23480
  try {
23355
- if (existsSync8(join17(loki, f)))
23356
- copyFileSync(join17(loki, f), join17(dir, f));
23481
+ if (existsSync8(join18(loki, f)))
23482
+ copyFileSync(join18(loki, f), join18(dir, f));
23357
23483
  } catch {}
23358
23484
  }
23359
23485
  try {
23360
- if (existsSync8(join17(loki, "queue")))
23361
- cpSync(join17(loki, "queue"), join17(dir, "queue"), { recursive: true });
23486
+ if (existsSync8(join18(loki, "queue")))
23487
+ cpSync(join18(loki, "queue"), join18(dir, "queue"), { recursive: true });
23362
23488
  } catch {}
23363
23489
  const meta = { id, created_at: now2.toISOString(), git_sha: gitHead(repoDir), message: message || null, files: readdirSync4(dir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name) };
23364
- writeFileSync6(join17(dir, "metadata.json"), JSON.stringify(meta, null, 2));
23365
- appendFileSync(join17(store, "index.jsonl"), `${JSON.stringify(meta)}
23490
+ writeFileSync6(join18(dir, "metadata.json"), JSON.stringify(meta, null, 2));
23491
+ appendFileSync(join18(store, "index.jsonl"), `${JSON.stringify(meta)}
23366
23492
  `);
23367
23493
  const mine = readdirSync4(store, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("chk-")).map((e) => e.name).sort();
23368
23494
  while (mine.length > MAX_CHECKPOINTS)
23369
- rmSync3(join17(store, mine.shift()), { recursive: true, force: true });
23495
+ rmSync4(join18(store, mine.shift()), { recursive: true, force: true });
23370
23496
  return meta;
23371
23497
  }
23372
23498
  function rollbackCheckpoint(repoDir, id, now2 = new Date) {
23373
23499
  const store = storeOf(repoDir), loki = lokiOf(repoDir);
23374
23500
  let real2 = "", realStore = "";
23375
23501
  try {
23376
- real2 = realpathSync9(join17(store, id));
23502
+ real2 = realpathSync9(join18(store, id));
23377
23503
  realStore = realpathSync9(store);
23378
23504
  } catch {
23379
23505
  return null;
23380
23506
  }
23381
- if (!real2.startsWith(`${realStore}${sep5}`) || !statSync6(real2).isDirectory())
23507
+ if (!real2.startsWith(`${realStore}${sep5}`) || !statSync7(real2).isDirectory())
23382
23508
  return null;
23383
- const preId = `rb-pre-${stamp(now2)}`, pre = join17(store, preId);
23509
+ const preId = `rb-pre-${stamp(now2)}`, pre = join18(store, preId);
23384
23510
  mkdirSync3(pre, { recursive: true });
23385
23511
  const notStore = (src) => src !== store;
23386
23512
  for (const n2 of ["session.json", "dashboard-state.json", "CONTINUITY.md", "autonomy-state.json"]) {
23387
23513
  try {
23388
- if (existsSync8(join17(loki, n2)))
23389
- copyFileSync(join17(loki, n2), join17(pre, n2));
23514
+ if (existsSync8(join18(loki, n2)))
23515
+ copyFileSync(join18(loki, n2), join18(pre, n2));
23390
23516
  } catch {}
23391
23517
  }
23392
23518
  for (const d of ["state", "queue"]) {
23393
23519
  try {
23394
- if (existsSync8(join17(loki, d)))
23395
- cpSync(join17(loki, d), join17(pre, d), { recursive: true, filter: notStore });
23520
+ if (existsSync8(join18(loki, d)))
23521
+ cpSync(join18(loki, d), join18(pre, d), { recursive: true, filter: notStore });
23396
23522
  } catch {}
23397
23523
  }
23398
23524
  const preMeta = { id: preId, created_at: now2.toISOString(), message: `pre-rollback snapshot (before restoring ${id})`, created_by: "control plane rollback" };
23399
- writeFileSync6(join17(pre, "metadata.json"), JSON.stringify(preMeta, null, 2));
23400
- appendFileSync(join17(store, "index.jsonl"), `${JSON.stringify(preMeta)}
23525
+ writeFileSync6(join18(pre, "metadata.json"), JSON.stringify(preMeta, null, 2));
23526
+ appendFileSync(join18(store, "index.jsonl"), `${JSON.stringify(preMeta)}
23401
23527
  `);
23402
23528
  let restored = 0;
23403
23529
  const errors = [];
23404
- const skipped = (src) => src === join17(real2, "state", "checkpoints");
23530
+ const skipped = (src) => src === join18(real2, "state", "checkpoints");
23405
23531
  for (const e of readdirSync4(real2, { withFileTypes: true })) {
23406
23532
  if (e.name === "metadata.json" || e.name === "worktree-snapshot.txt")
23407
23533
  continue;
@@ -23409,20 +23535,20 @@ function rollbackCheckpoint(repoDir, id, now2 = new Date) {
23409
23535
  errors.push(`${e.name}: not in the rollback allowlist, skipped`);
23410
23536
  continue;
23411
23537
  }
23412
- const src = join17(real2, e.name), dst = join17(loki, e.name);
23538
+ const src = join18(real2, e.name), dst = join18(loki, e.name);
23413
23539
  try {
23414
- if (lstatSync2(src).isSymbolicLink()) {
23540
+ if (lstatSync3(src).isSymbolicLink()) {
23415
23541
  errors.push(`${e.name}: symlink skipped`);
23416
23542
  continue;
23417
23543
  }
23418
- if (existsSync8(dst) && lstatSync2(dst).isSymbolicLink()) {
23544
+ if (existsSync8(dst) && lstatSync3(dst).isSymbolicLink()) {
23419
23545
  errors.push(`${e.name}: destination is a symlink, skipped`);
23420
23546
  continue;
23421
23547
  }
23422
23548
  cpSync(src, dst, { recursive: true, filter: (s) => {
23423
23549
  if (skipped(s))
23424
23550
  return false;
23425
- if (lstatSync2(s).isSymbolicLink()) {
23551
+ if (lstatSync3(s).isSymbolicLink()) {
23426
23552
  errors.push(`${s.slice(real2.length + 1)}: nested symlink skipped`);
23427
23553
  return false;
23428
23554
  }
@@ -23509,9 +23635,9 @@ function mount6(ctx) {
23509
23635
  }
23510
23636
 
23511
23637
  // src/server/routes/config.ts
23512
- import { createHash as createHash5, randomBytes } from "crypto";
23513
- import { closeSync as closeSync4, fchmodSync, fsyncSync, lstatSync as lstatSync3, openSync as openSync4, readFileSync as readFileSync11, realpathSync as realpathSync10, renameSync as renameSync3, statSync as statSync7, unlinkSync, writeSync as writeSync2 } from "fs";
23514
- import { basename as basename5, dirname as dirname4, join as join18, sep as sep6 } from "path";
23638
+ import { createHash as createHash5, randomBytes as randomBytes2 } from "crypto";
23639
+ import { closeSync as closeSync4, fchmodSync, fsyncSync, lstatSync as lstatSync4, openSync as openSync4, readFileSync as readFileSync11, realpathSync as realpathSync10, renameSync as renameSync3, statSync as statSync8, unlinkSync, writeSync as writeSync2 } from "fs";
23640
+ import { basename as basename5, dirname as dirname4, join as join19, sep as sep6 } from "path";
23515
23641
 
23516
23642
  // node_modules/yaml/dist/index.js
23517
23643
  var composer = require_composer();
@@ -23950,10 +24076,10 @@ function resolveConfigFile(repoDir) {
23950
24076
  } catch {
23951
24077
  return { ok: false, status: 400, error: "repo directory not found" };
23952
24078
  }
23953
- const p = join18(root, "loki.yaml");
24079
+ const p = join19(root, "loki.yaml");
23954
24080
  let st;
23955
24081
  try {
23956
- st = lstatSync3(p);
24082
+ st = lstatSync4(p);
23957
24083
  } catch {
23958
24084
  return { ok: true, file: p, exists: false };
23959
24085
  }
@@ -23966,7 +24092,7 @@ function resolveConfigFile(repoDir) {
23966
24092
  }
23967
24093
  if (!real2.startsWith(root + sep6))
23968
24094
  return { ok: false, status: 400, error: "loki.yaml is a symlink that resolves outside the repo" };
23969
- if (!statSync7(real2).isFile())
24095
+ if (!statSync8(real2).isFile())
23970
24096
  return { ok: false, status: 422, error: "loki.yaml is not a regular file" };
23971
24097
  return { ok: true, file: real2, exists: true };
23972
24098
  }
@@ -23975,7 +24101,7 @@ function resolveConfigFile(repoDir) {
23975
24101
  return { ok: true, file: p, exists: true };
23976
24102
  }
23977
24103
  function atomicWrite(file, text2, mode) {
23978
- const tmp = join18(dirname4(file), `.${basename5(file)}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`);
24104
+ const tmp = join19(dirname4(file), `.${basename5(file)}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`);
23979
24105
  const fd = openSync4(tmp, "wx", mode);
23980
24106
  try {
23981
24107
  writeSync2(fd, text2);
@@ -24015,7 +24141,7 @@ function mount8(ctx) {
24015
24141
  return deny(c, "config.read", r.status, r.error);
24016
24142
  let raw2 = "";
24017
24143
  if (r.exists) {
24018
- if (statSync7(r.file).size > MAX_FILE)
24144
+ if (statSync8(r.file).size > MAX_FILE)
24019
24145
  return deny(c, "config.read", 413, "loki.yaml is too large");
24020
24146
  raw2 = readFileSync11(r.file, "utf8");
24021
24147
  }
@@ -24080,7 +24206,7 @@ function mount8(ctx) {
24080
24206
  return refuse(r.status, r.error);
24081
24207
  let raw2 = "";
24082
24208
  if (r.exists) {
24083
- if (statSync7(r.file).size > MAX_FILE)
24209
+ if (statSync8(r.file).size > MAX_FILE)
24084
24210
  return refuse(400, "loki.yaml is too large");
24085
24211
  raw2 = readFileSync11(r.file, "utf8");
24086
24212
  }
@@ -24107,7 +24233,7 @@ function mount8(ctx) {
24107
24233
  return refuse(400, "could not render the config safely");
24108
24234
  const changed = [...new Set([...Object.keys(prev), ...Object.keys(next)])].filter((k) => !deepEq(prev[k], next[k]));
24109
24235
  try {
24110
- const mode = r.exists ? statSync7(r.file).mode & 511 : 420;
24236
+ const mode = r.exists ? statSync8(r.file).mode & 511 : 420;
24111
24237
  if (r.exists)
24112
24238
  atomicWrite(`${r.file}.bak`, raw2, 384);
24113
24239
  atomicWrite(r.file, out, mode);
@@ -24126,7 +24252,7 @@ function mount8(ctx) {
24126
24252
 
24127
24253
  // src/server/routes/control.ts
24128
24254
  import { existsSync as existsSync9, realpathSync as realpathSync11 } from "fs";
24129
- import { join as join19, resolve as resolve5, sep as sep7 } from "path";
24255
+ import { join as join20, resolve as resolve5, sep as sep7 } from "path";
24130
24256
  init_run_pid();
24131
24257
  var ID4 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
24132
24258
  var busy = new Set;
@@ -24152,7 +24278,7 @@ function mount9(ctx) {
24152
24278
  }
24153
24279
  if (!repo)
24154
24280
  return done(404, "refused", { error: "this run's repo is not known on this machine" });
24155
- const runsRoot = join19(repo, ".loki", "runs"), runDir = resolve5(runsRoot, id);
24281
+ const runsRoot = join20(repo, ".loki", "runs"), runDir = resolve5(runsRoot, id);
24156
24282
  if (!runDir.startsWith(runsRoot + sep7))
24157
24283
  return done(400, "refused", { error: "invalid run id" }, "path escape");
24158
24284
  return handler({ source, run: id, repo, runDir }, done);
@@ -24200,7 +24326,7 @@ function mount9(ctx) {
24200
24326
  return done(404, "refused", { error: "run not found" });
24201
24327
  if (!blockedQuestion(loadEvents(db, a.source, a.run), row.verdict))
24202
24328
  return done(409, "refused", { error: "run is not BLOCKED, so there is nothing to resume" });
24203
- if (!existsSync9(join19(answerDir, a.source, `${a.run}.answer.txt`)))
24329
+ if (!existsSync9(join20(answerDir, a.source, `${a.run}.answer.txt`)))
24204
24330
  return done(409, "refused", { error: "no answer recorded for this run; answer it first" });
24205
24331
  return launch(a, [bin, "answer", a.run], done);
24206
24332
  });
@@ -24385,10 +24511,10 @@ function mount11(ctx) {
24385
24511
  // src/server/routes/fleet.ts
24386
24512
  import { readdirSync as readdirSync5, readFileSync as readFileSync12 } from "fs";
24387
24513
  import { homedir as homedir6 } from "os";
24388
- import { basename as basename6, join as join20 } from "path";
24514
+ import { basename as basename6, join as join21 } from "path";
24389
24515
  var isNum2 = (v) => typeof v === "number" && Number.isFinite(v);
24390
24516
  var isObj6 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
24391
- var registryFile = () => join20(process.env.HOME ?? homedir6(), ".loki", "dashboard", "projects.json");
24517
+ var registryFile = () => join21(process.env.HOME ?? homedir6(), ".loki", "dashboard", "projects.json");
24392
24518
  function pidAlive2(pid) {
24393
24519
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
24394
24520
  return false;
@@ -24403,33 +24529,33 @@ function projectSnapshot(path) {
24403
24529
  const snap = { phase: "", iteration: null, cost_usd: null, started_at: null, ended_at: null };
24404
24530
  if (!path)
24405
24531
  return snap;
24406
- const loki = join20(path, ".loki");
24407
- const st = readJson(join20(loki, "dashboard-state.json"));
24532
+ const loki = join21(path, ".loki");
24533
+ const st = readJson(join21(loki, "dashboard-state.json"));
24408
24534
  if (isObj6(st)) {
24409
24535
  snap.phase = typeof st.phase === "string" ? st.phase : "";
24410
24536
  snap.iteration = Number.isInteger(st.iteration) ? st.iteration : null;
24411
24537
  }
24412
- const ss = readJson(join20(loki, "session.json"));
24538
+ const ss = readJson(join21(loki, "session.json"));
24413
24539
  if (isObj6(ss)) {
24414
24540
  const a = ss.startedAt || ss.started_at, b = ss.endedAt || ss.ended_at;
24415
24541
  snap.started_at = typeof a === "string" ? a : null;
24416
24542
  snap.ended_at = typeof b === "string" ? b : null;
24417
24543
  }
24418
24544
  let cost = 0, found = false;
24419
- const eff = join20(loki, "metrics", "efficiency");
24545
+ const eff = join21(loki, "metrics", "efficiency");
24420
24546
  let names = [];
24421
24547
  try {
24422
24548
  names = readdirSync5(eff).filter((n2) => n2.endsWith(".json"));
24423
24549
  } catch {}
24424
24550
  for (const n2 of names) {
24425
- const d = readJson(join20(eff, n2));
24551
+ const d = readJson(join21(eff, n2));
24426
24552
  if (isObj6(d) && isNum2(d.cost_usd) && recordIsMeasured(d)) {
24427
24553
  cost += d.cost_usd;
24428
24554
  found = true;
24429
24555
  }
24430
24556
  }
24431
24557
  if (!found) {
24432
- const t = readJson(join20(loki, "context", "tracking.json"));
24558
+ const t = readJson(join21(loki, "context", "tracking.json"));
24433
24559
  const totals = isObj6(t) && isObj6(t.totals) ? t.totals : null;
24434
24560
  if (totals && isNum2(totals.total_cost_usd) && recordIsMeasured({ cost_usd: totals.total_cost_usd, input_tokens: totals.total_input, output_tokens: totals.total_output })) {
24435
24561
  cost = totals.total_cost_usd;
@@ -24502,8 +24628,8 @@ function mount12(ctx) {
24502
24628
  }
24503
24629
 
24504
24630
  // src/server/routes/memory.ts
24505
- import { existsSync as existsSync10, readFileSync as readFileSync13, readdirSync as readdirSync6, realpathSync as realpathSync12, statSync as statSync8 } from "fs";
24506
- import { join as join21, sep as sep8 } from "path";
24631
+ import { existsSync as existsSync10, readFileSync as readFileSync13, readdirSync as readdirSync6, realpathSync as realpathSync12, statSync as statSync9 } from "fs";
24632
+ import { join as join22, sep as sep8 } from "path";
24507
24633
  var isObj7 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
24508
24634
  var nonEmpty = (v) => !(v === undefined || v === null || v === "" || Array.isArray(v) && v.length === 0 || isObj7(v) && Object.keys(v).length === 0);
24509
24635
  var focus = { dir: null };
@@ -24534,7 +24660,7 @@ function jsonFiles(dir, cap = Infinity) {
24534
24660
  for (const e of ents.sort((a, b) => a.name < b.name ? -1 : 1)) {
24535
24661
  if (out2.length >= cap)
24536
24662
  return;
24537
- const p = join21(d, e.name);
24663
+ const p = join22(d, e.name);
24538
24664
  if (e.isDirectory())
24539
24665
  walk(p);
24540
24666
  else if (e.isFile() && e.name.endsWith(".json"))
@@ -24556,12 +24682,12 @@ function setFocus(repoDir, raw2, registry = registryFile()) {
24556
24682
  let real2 = "";
24557
24683
  try {
24558
24684
  real2 = realpathSync12(s);
24559
- if (!statSync8(real2).isDirectory())
24685
+ if (!statSync9(real2).isDirectory())
24560
24686
  throw new Error("not a dir");
24561
24687
  } catch {
24562
24688
  return { ok: false, error: `Directory does not exist: ${s}` };
24563
24689
  }
24564
- if (!existsSync10(join21(real2, ".loki")) || !statSync8(join21(real2, ".loki")).isDirectory())
24690
+ if (!existsSync10(join22(real2, ".loki")) || !statSync9(join22(real2, ".loki")).isDirectory())
24565
24691
  return { ok: false, error: `Directory does not contain a .loki/ subdirectory: ${s}` };
24566
24692
  const allowed = new Set;
24567
24693
  try {
@@ -24586,7 +24712,7 @@ var QUEUES = [["pending.json", "pending"], ["in-progress.json", "in_progress"],
24586
24712
  var RANK = { done: 3, in_progress: 2, review: 1, pending: 0 };
24587
24713
  function tasksList(loki, status) {
24588
24714
  const all = [];
24589
- const st = readJson(join21(loki, "dashboard-state.json"));
24715
+ const st = readJson(join22(loki, "dashboard-state.json"));
24590
24716
  const groups = isObj7(st) && isObj7(st.tasks) ? st.tasks : {};
24591
24717
  for (const [key, mapped] of GROUPS) {
24592
24718
  const g = groups[key];
@@ -24608,7 +24734,7 @@ function tasksList(loki, status) {
24608
24734
  });
24609
24735
  }
24610
24736
  for (const [file, qs] of QUEUES) {
24611
- const raw2 = readJson(join21(loki, "queue", file));
24737
+ const raw2 = readJson(join22(loki, "queue", file));
24612
24738
  const items = isObj7(raw2) ? raw2.tasks : raw2;
24613
24739
  if (!Array.isArray(items))
24614
24740
  continue;
@@ -24662,7 +24788,7 @@ function tasksList(loki, status) {
24662
24788
  }
24663
24789
  return status ? out2.filter((t) => t.status === status) : out2;
24664
24790
  }
24665
- var memDir = (loki, sub) => join21(loki, "memory", sub);
24791
+ var memDir = (loki, sub) => join22(loki, "memory", sub);
24666
24792
  function memoryEpisodes(loki, limit = 50) {
24667
24793
  const eps = jsonFiles(memDir(loki, "episodic")).map(readJson).filter(isObj7);
24668
24794
  eps.sort((a, b) => String(b.timestamp ?? "").localeCompare(String(a.timestamp ?? "")));
@@ -24677,13 +24803,13 @@ function memoryEpisode(loki, id) {
24677
24803
  return null;
24678
24804
  }
24679
24805
  function memoryPatterns(loki) {
24680
- const d = readJson(join21(memDir(loki, "semantic"), "patterns.json"));
24806
+ const d = readJson(join22(memDir(loki, "semantic"), "patterns.json"));
24681
24807
  const list = Array.isArray(d) ? d : isObj7(d) && Array.isArray(d.patterns) ? d.patterns : [];
24682
24808
  return list.filter(isObj7);
24683
24809
  }
24684
24810
  var memorySkills = (loki) => jsonFiles(memDir(loki, "skills")).map(readJson).filter(isObj7);
24685
24811
  function memoryEconomics(loki) {
24686
- const rawV = readJson(join21(loki, "memory", "token_economics.json"));
24812
+ const rawV = readJson(join22(loki, "memory", "token_economics.json"));
24687
24813
  const raw2 = isObj7(rawV) ? rawV : {};
24688
24814
  const m = isObj7(raw2.metrics) ? raw2.metrics : {};
24689
24815
  const n2 = (v) => typeof v === "number" && Number.isFinite(v) ? Math.trunc(v) : 0;
@@ -24719,7 +24845,7 @@ function memoryEconomics(loki) {
24719
24845
  };
24720
24846
  }
24721
24847
  function contextTracking(loki) {
24722
- const f = join21(loki, "context", "tracking.json");
24848
+ const f = join22(loki, "context", "tracking.json");
24723
24849
  if (!existsSync10(f)) {
24724
24850
  return { status: 200, body: {
24725
24851
  session_id: null,
@@ -24780,8 +24906,8 @@ function mount13(ctx) {
24780
24906
  }
24781
24907
 
24782
24908
  // src/server/routes/metrics.ts
24783
- import { readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync9 } from "fs";
24784
- import { join as join22 } from "path";
24909
+ import { readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync10 } from "fs";
24910
+ import { join as join23 } from "path";
24785
24911
  var isObj8 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
24786
24912
  var arr = (v) => Array.isArray(v) ? v : [];
24787
24913
  function buildMetricsText(repoDir, now2 = Date.now()) {
@@ -24798,7 +24924,7 @@ function buildMetricsText(repoDir, now2 = Date.now()) {
24798
24924
  L.push(...samples);
24799
24925
  L.push("");
24800
24926
  };
24801
- const stRaw = readJson(join22(loki, "dashboard-state.json"));
24927
+ const stRaw = readJson(join23(loki, "dashboard-state.json"));
24802
24928
  const state = isObj8(stRaw) ? stRaw : null;
24803
24929
  let status = 0;
24804
24930
  if (state?.mode === "paused")
@@ -24807,7 +24933,7 @@ function buildMetricsText(repoDir, now2 = Date.now()) {
24807
24933
  status = 1;
24808
24934
  else {
24809
24935
  try {
24810
- if (pidAlive2(parseInt(readFileSync14(join22(loki, "loki.pid"), "utf8").trim(), 10)))
24936
+ if (pidAlive2(parseInt(readFileSync14(join23(loki, "loki.pid"), "utf8").trim(), 10)))
24811
24937
  status = 1;
24812
24938
  } catch {}
24813
24939
  }
@@ -24823,7 +24949,7 @@ function buildMetricsText(repoDir, now2 = Date.now()) {
24823
24949
  `loki_tasks_total{status="failed"} ${arr(tasks.failed).length}`
24824
24950
  ] : null);
24825
24951
  let agents = null;
24826
- const af = readJson(join22(loki, "state", "agents.json"));
24952
+ const af = readJson(join23(loki, "state", "agents.json"));
24827
24953
  if (Array.isArray(af) && af.length)
24828
24954
  agents = af;
24829
24955
  else if (state && Array.isArray(state.agents) && state.agents.length)
@@ -24835,7 +24961,7 @@ function buildMetricsText(repoDir, now2 = Date.now()) {
24835
24961
  gauge("loki_cost_usd", "Estimated total cost in USD", "gauge", cost.estimated_cost_usd !== null ? [`loki_cost_usd ${cost.estimated_cost_usd}`] : null);
24836
24962
  let events2 = null;
24837
24963
  try {
24838
- events2 = readFileSync14(join22(loki, "events.jsonl"), "utf8").split(`
24964
+ events2 = readFileSync14(join23(loki, "events.jsonl"), "utf8").split(`
24839
24965
  `).filter((l) => l.trim()).length;
24840
24966
  } catch {}
24841
24967
  gauge("loki_events_total", "Total number of events recorded", "counter", events2 !== null ? [`loki_events_total ${events2}`] : null);
@@ -24847,19 +24973,19 @@ function buildMetricsText(repoDir, now2 = Date.now()) {
24847
24973
  }
24848
24974
  gauge("loki_uptime_seconds", "Seconds since session started", "gauge", uptime !== null ? [`loki_uptime_seconds ${uptime}`] : null);
24849
24975
  let total = 0, ver = 0, gaps = 0, notver = 0, unk = 0, att = 0, sig = 0;
24850
- const pdir = join22(loki, "proofs");
24976
+ const pdir = join23(loki, "proofs");
24851
24977
  let entries = [];
24852
24978
  try {
24853
24979
  entries = readdirSync7(pdir).sort();
24854
24980
  } catch {}
24855
24981
  for (const e of entries) {
24856
24982
  try {
24857
- if (!statSync9(join22(pdir, e)).isDirectory())
24983
+ if (!statSync10(join23(pdir, e)).isDirectory())
24858
24984
  continue;
24859
24985
  } catch {
24860
24986
  continue;
24861
24987
  }
24862
- const d = readJson(join22(pdir, e, "proof.json"));
24988
+ const d = readJson(join23(pdir, e, "proof.json"));
24863
24989
  if (!isObj8(d))
24864
24990
  continue;
24865
24991
  total++;
@@ -24904,7 +25030,7 @@ function mount14(ctx) {
24904
25030
 
24905
25031
  // src/server/routes/session_control.ts
24906
25032
  import { existsSync as existsSync11, mkdirSync as mkdirSync4, readdirSync as readdirSync8, readFileSync as readFileSync15, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
24907
- import { dirname as dirname5, join as join23 } from "path";
25033
+ import { dirname as dirname5, join as join24 } from "path";
24908
25034
  var isObj9 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
24909
25035
  var ACTIONS = ["pause", "resume", "stop", "council-review"];
24910
25036
  var isAction = (v) => ACTIONS.includes(v);
@@ -24929,7 +25055,7 @@ var readJson2 = (p) => {
24929
25055
  };
24930
25056
  function runnerPid(loki) {
24931
25057
  try {
24932
- const pid = parseInt(readFileSync15(join23(loki, "loki.pid"), "utf8").trim(), 10);
25058
+ const pid = parseInt(readFileSync15(join24(loki, "loki.pid"), "utf8").trim(), 10);
24933
25059
  return pidAlive2(pid) ? pid : null;
24934
25060
  } catch {
24935
25061
  return null;
@@ -24939,18 +25065,18 @@ function applyControl(repoDir, action) {
24939
25065
  const loki = lokiDirOf(repoDir);
24940
25066
  const running = runnerPid(loki) !== null;
24941
25067
  const put = (rel) => {
24942
- const f = join23(loki, rel);
25068
+ const f = join24(loki, rel);
24943
25069
  mkdirSync4(dirname5(f), { recursive: true });
24944
25070
  writeFileSync7(f, new Date().toISOString());
24945
25071
  };
24946
25072
  if (action === "council-review") {
24947
- put(join23("signals", "COUNCIL_REVIEW_REQUESTED"));
25073
+ put(join24("signals", "COUNCIL_REVIEW_REQUESTED"));
24948
25074
  return { status: 200, body: { success: true, message: "Council review requested" } };
24949
25075
  }
24950
25076
  if (action === "resume") {
24951
25077
  for (const n2 of ["PAUSE", "STOP"]) {
24952
25078
  try {
24953
- unlinkSync2(join23(loki, n2));
25079
+ unlinkSync2(join24(loki, n2));
24954
25080
  } catch {}
24955
25081
  }
24956
25082
  return running ? { status: 200, body: { success: true, message: "Session resumed", process_verified: true } } : { status: 503, body: { success: false, message: "Session process is not running; the signal files were cleared" } };
@@ -24970,16 +25096,16 @@ function runControl(db, repoDir, action, c, via) {
24970
25096
  return c.json(r.body, r.status);
24971
25097
  }
24972
25098
  function councilState(loki) {
24973
- const f = join23(loki, "council", "state.json");
25099
+ const f = join24(loki, "council", "state.json");
24974
25100
  if (!existsSync11(f))
24975
25101
  return { enabled: false, total_votes: 0, verdicts: [] };
24976
25102
  const d = readJson2(f);
24977
25103
  return isObj9(d) ? d : { enabled: null, total_votes: null, verdicts: null, error: "unreadable_state" };
24978
25104
  }
24979
25105
  function councilVerdicts(loki, limit = 20) {
24980
- const st = readJson2(join23(loki, "council", "state.json"));
25106
+ const st = readJson2(join24(loki, "council", "state.json"));
24981
25107
  const verdicts = isObj9(st) && Array.isArray(st.verdicts) ? st.verdicts : [];
24982
- const votes = join23(loki, "council", "votes");
25108
+ const votes = join24(loki, "council", "votes");
24983
25109
  const details = [];
24984
25110
  let names = [];
24985
25111
  try {
@@ -24993,8 +25119,8 @@ function councilVerdicts(loki, limit = 20) {
24993
25119
  }
24994
25120
  };
24995
25121
  for (const n2 of names.slice(0, limit)) {
24996
- const dir = join23(votes, n2), d = { iteration: n2 };
24997
- const ev = text2(join23(dir, "evidence.md"));
25122
+ const dir = join24(votes, n2), d = { iteration: n2 };
25123
+ const ev = text2(join24(dir, "evidence.md"));
24998
25124
  if (ev !== null)
24999
25125
  d.evidence_preview = ev.slice(0, 500);
25000
25126
  let files = [];
@@ -25002,10 +25128,10 @@ function councilVerdicts(loki, limit = 20) {
25002
25128
  files = readdirSync8(dir).filter((f) => /^member-.*\.txt$/.test(f)).sort();
25003
25129
  } catch {}
25004
25130
  d.members = files.flatMap((f) => {
25005
- const t = text2(join23(dir, f));
25131
+ const t = text2(join24(dir, f));
25006
25132
  return t === null ? [] : [{ member: f.replace(/\.txt$/, ""), content: t.trim() }];
25007
25133
  });
25008
- const con = text2(join23(dir, "contrarian.txt"));
25134
+ const con = text2(join24(dir, "contrarian.txt"));
25009
25135
  if (con !== null)
25010
25136
  d.contrarian = con.trim();
25011
25137
  details.push(d);
@@ -25016,7 +25142,7 @@ function councilConvergence(loki) {
25016
25142
  const dataPoints = [];
25017
25143
  let raw2 = "";
25018
25144
  try {
25019
- raw2 = readFileSync15(join23(loki, "council", "convergence.log"), "utf8");
25145
+ raw2 = readFileSync15(join24(loki, "council", "convergence.log"), "utf8");
25020
25146
  } catch {}
25021
25147
  for (const line2 of raw2.trim().split(`
25022
25148
  `)) {
@@ -25032,7 +25158,7 @@ function councilConvergence(loki) {
25032
25158
  }
25033
25159
  function councilReport(loki) {
25034
25160
  try {
25035
- return { report: readFileSync15(join23(loki, "council", "report.md"), "utf8") };
25161
+ return { report: readFileSync15(join24(loki, "council", "report.md"), "utf8") };
25036
25162
  } catch {
25037
25163
  return { report: null };
25038
25164
  }
@@ -25045,7 +25171,7 @@ function councilTranscripts(loki, q) {
25045
25171
  if (Number.isNaN(since))
25046
25172
  return { error: "Invalid 'since' timestamp format; expected ISO8601" };
25047
25173
  }
25048
- const dir = join23(loki, "council", "transcripts");
25174
+ const dir = join24(loki, "council", "transcripts");
25049
25175
  let names = [];
25050
25176
  try {
25051
25177
  names = readdirSync8(dir).filter((f) => /^iter-.*\.json$/.test(f)).sort().reverse();
@@ -25054,7 +25180,7 @@ function councilTranscripts(loki, q) {
25054
25180
  }
25055
25181
  const out2 = [];
25056
25182
  for (const n2 of names) {
25057
- const rec = readJson2(join23(dir, n2));
25183
+ const rec = readJson2(join24(dir, n2));
25058
25184
  if (!isObj9(rec) || typeof rec.iteration_id !== "string")
25059
25185
  continue;
25060
25186
  if (since !== null) {
@@ -25106,12 +25232,12 @@ function mount15(ctx) {
25106
25232
 
25107
25233
  // src/server/routes/integrations.ts
25108
25234
  import { spawn as spawn4 } from "child_process";
25109
- import { existsSync as existsSync12, readFileSync as readFileSync16, statSync as statSync10 } from "fs";
25110
- import { delimiter, join as join24 } from "path";
25235
+ import { existsSync as existsSync12, readFileSync as readFileSync16, statSync as statSync11 } from "fs";
25236
+ import { delimiter, join as join25 } from "path";
25111
25237
  var GH_TIMEOUT_MS = 3000;
25112
25238
  var isSet = (n2) => !!n2 && (process.env[n2] ?? "") !== "";
25113
25239
  function ghAuthed(pathVar = process.env.PATH ?? "", timeoutMs = GH_TIMEOUT_MS) {
25114
- const exe = pathVar.split(delimiter).filter(Boolean).map((d) => join24(d, "gh")).find((p) => existsSync12(p));
25240
+ const exe = pathVar.split(delimiter).filter(Boolean).map((d) => join25(d, "gh")).find((p) => existsSync12(p));
25115
25241
  if (!exe)
25116
25242
  return Promise.resolve(null);
25117
25243
  return new Promise((resolve6) => {
@@ -25143,7 +25269,7 @@ function ghAuthed(pathVar = process.env.PATH ?? "", timeoutMs = GH_TIMEOUT_MS) {
25143
25269
  function configuredName(repoDir, path) {
25144
25270
  try {
25145
25271
  const r = resolveConfigFile(repoDir);
25146
- if (!r.ok || !r.exists || statSync10(r.file).size > 1e6)
25272
+ if (!r.ok || !r.exists || statSync11(r.file).size > 1e6)
25147
25273
  return null;
25148
25274
  const doc = $parseDocument(readFileSync16(r.file, "utf8"));
25149
25275
  if (doc.errors.length)
@@ -25156,8 +25282,8 @@ function configuredName(repoDir, path) {
25156
25282
  }
25157
25283
  function mcpServers(repoDir) {
25158
25284
  try {
25159
- const p = join24(repoDir, ".mcp.json");
25160
- if (!existsSync12(p) || statSync10(p).size > 1e6)
25285
+ const p = join25(repoDir, ".mcp.json");
25286
+ if (!existsSync12(p) || statSync11(p).size > 1e6)
25161
25287
  return null;
25162
25288
  const j = JSON.parse(readFileSync16(p, "utf8"));
25163
25289
  return j.mcpServers && typeof j.mcpServers === "object" ? Object.keys(j.mcpServers).length : null;
@@ -25186,7 +25312,7 @@ function conv(s) {
25186
25312
  }
25187
25313
  async function listIntegrations(repoDir, gh = () => ghAuthed()) {
25188
25314
  const rows = [];
25189
- const gitEnv2 = configuredName(repoDir, ["git", "token_env"]);
25315
+ const gitEnv2 = configuredName(repoDir, "git.token_env".split("."));
25190
25316
  const ghOk = await gh();
25191
25317
  const gitEnvSet = isSet(gitEnv2);
25192
25318
  rows.push({
@@ -25548,7 +25674,7 @@ function mount18(ctx) {
25548
25674
  // src/server/routes/providers.ts
25549
25675
  import { spawn as spawn6 } from "child_process";
25550
25676
  import { existsSync as existsSync13, readFileSync as readFileSync17 } from "fs";
25551
- import { delimiter as delimiter2, join as join25 } from "path";
25677
+ import { delimiter as delimiter2, join as join26 } from "path";
25552
25678
  var ORDER = ["claude", "codex", "cline", "aider", "opencode"];
25553
25679
  var DEPRECATED = ["gemini"];
25554
25680
  var AUTH_ENV = {
@@ -25564,7 +25690,7 @@ function findOnPath(bin, pathVar) {
25564
25690
  for (const d of pathVar.split(delimiter2)) {
25565
25691
  if (!d)
25566
25692
  continue;
25567
- const p = join25(d, bin);
25693
+ const p = join26(d, bin);
25568
25694
  if (existsSync13(p))
25569
25695
  return p;
25570
25696
  }
@@ -25609,14 +25735,14 @@ function probeCli(bin, timeoutMs, pathVar = process.env.PATH ?? "") {
25609
25735
  });
25610
25736
  }
25611
25737
  function providersDir() {
25612
- const cands = [process.env.LOKI_PROVIDERS_DIR, join25(import.meta.dir, "../../../../../providers"), join25(import.meta.dir, "../../../providers")];
25613
- return cands.find((d) => !!d && existsSync13(join25(d, "model_catalog.json"))) ?? null;
25738
+ const cands = [process.env.LOKI_PROVIDERS_DIR, join26(import.meta.dir, "../../../../../providers"), join26(import.meta.dir, "../../../providers")];
25739
+ return cands.find((d) => !!d && existsSync13(join26(d, "model_catalog.json"))) ?? null;
25614
25740
  }
25615
25741
  function loadCatalog(dir) {
25616
25742
  if (!dir)
25617
25743
  return { providers: {}, updated: null };
25618
25744
  try {
25619
- const j = JSON.parse(readFileSync17(join25(dir, "model_catalog.json"), "utf8"));
25745
+ const j = JSON.parse(readFileSync17(join26(dir, "model_catalog.json"), "utf8"));
25620
25746
  return { providers: j.providers ?? {}, updated: typeof j.updated === "string" ? j.updated : null };
25621
25747
  } catch {
25622
25748
  return { providers: {}, updated: null };
@@ -25739,7 +25865,7 @@ function mount20(ctx) {
25739
25865
  // src/server/routes/verify.ts
25740
25866
  import { readFileSync as readFileSync54, realpathSync as realpathSync21 } from "fs";
25741
25867
  import { createPublicKey as createPublicKey5 } from "crypto";
25742
- import { join as join68, sep as sep13 } from "path";
25868
+ import { join as join67, sep as sep12 } from "path";
25743
25869
  init_verify_cmd();
25744
25870
  init_seal();
25745
25871
  init_receipt_dsse();
@@ -25766,15 +25892,15 @@ function mount21(ctx) {
25766
25892
  return done(404, "receipt not available", "not_found");
25767
25893
  let runDir, file;
25768
25894
  try {
25769
- const root = realpathSync21(join68(repo.p, ".loki", "runs"));
25770
- runDir = realpathSync21(join68(root, run2));
25771
- if (runDir !== join68(root, run2))
25895
+ const root = realpathSync21(join67(repo.p, ".loki", "runs"));
25896
+ runDir = realpathSync21(join67(root, run2));
25897
+ if (runDir !== join67(root, run2))
25772
25898
  return done(404, "receipt not found", "not_found");
25773
- file = realpathSync21(join68(runDir, "receipt.json"));
25899
+ file = realpathSync21(join67(runDir, "receipt.json"));
25774
25900
  } catch {
25775
25901
  return done(404, "receipt not found", "not_found");
25776
25902
  }
25777
- if (!file.startsWith(runDir + sep13))
25903
+ if (!file.startsWith(runDir + sep12))
25778
25904
  return done(404, "receipt not found", "not_found");
25779
25905
  let integrity, reasons, sha4 = null, outcome = "UNREADABLE";
25780
25906
  try {
@@ -25852,7 +25978,7 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
25852
25978
 
25853
25979
  // src/server/legacy/shim.ts
25854
25980
  import { existsSync as existsSync45, readFileSync as readFileSync55 } from "fs";
25855
- import { join as join69 } from "path";
25981
+ import { join as join68 } from "path";
25856
25982
 
25857
25983
  // src/server/legacy/routes.ts
25858
25984
  var LEGACY_ROUTES = [
@@ -26230,7 +26356,7 @@ var logged = new Set;
26230
26356
  var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
26231
26357
  var NOT_SUPPORTED = "not yet supported by the Control Plane";
26232
26358
  var repoVersion = () => {
26233
- for (const f of [join69(import.meta.dir, "../../../../../VERSION")]) {
26359
+ for (const f of [join68(import.meta.dir, "../../../../../VERSION")]) {
26234
26360
  try {
26235
26361
  if (existsSync45(f))
26236
26362
  return readFileSync55(f, "utf8").trim();
@@ -26415,7 +26541,7 @@ function legacyShim(opts) {
26415
26541
 
26416
26542
  // src/server/app.ts
26417
26543
  var MAX_BODY2 = 1e6;
26418
- var defaultUiDir = () => [join70(import.meta.dir, "../../ui/dist"), join70(import.meta.dir, "../ui/dist")].find((d) => existsSync46(join70(d, "index.html")));
26544
+ var defaultUiDir = () => [join69(import.meta.dir, "../../ui/dist"), join69(import.meta.dir, "../ui/dist")].find((d) => existsSync46(join69(d, "index.html")));
26419
26545
  function createApp(opts) {
26420
26546
  const uiDir = opts.uiDir ?? defaultUiDir();
26421
26547
  const { db, sqlite } = openDb(opts.dbPath);
@@ -26444,7 +26570,7 @@ function createApp(opts) {
26444
26570
  await next();
26445
26571
  });
26446
26572
  const readInstalled = () => {
26447
- for (const f of [process.env.LOKI_VERSION_FILE, join70(import.meta.dir, "../../../../VERSION")]) {
26573
+ for (const f of [process.env.LOKI_VERSION_FILE, join69(import.meta.dir, "../../../../VERSION")]) {
26448
26574
  try {
26449
26575
  if (f)
26450
26576
  return readFileSync56(f, "utf8").trim() || "unknown";
@@ -26558,11 +26684,11 @@ function createApp(opts) {
26558
26684
  return c.json({ error: "not found" }, 404);
26559
26685
  const root = resolve15(uiDir);
26560
26686
  const f = resolve15(root, `.${p}`);
26561
- if (f.startsWith(root + sep14) && existsSync46(f) && statSync23(f).isFile())
26687
+ if (f.startsWith(root + sep13) && existsSync46(f) && statSync23(f).isFile())
26562
26688
  return new Response(Bun.file(f));
26563
26689
  if (/\.[a-z0-9]+$/i.test(p))
26564
26690
  return c.json({ error: "not found" }, 404);
26565
- return new Response(Bun.file(join70(root, "index.html")));
26691
+ return new Response(Bun.file(join69(root, "index.html")));
26566
26692
  });
26567
26693
  return { app, db, close: () => {
26568
26694
  clearInterval(reconciler);