loki-mode 11.63.7 → 11.63.9

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 (68) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/dashboard/__init__.py +1 -1
  4. package/docs/CLI-REFERENCE.md +1 -1
  5. package/docs/INSTALLATION.md +1 -1
  6. package/docs/v10/FAILURE-CLASSES.md +48 -0
  7. package/loki-ts/dist/loki.js +1143 -1141
  8. package/mcp/__init__.py +1 -1
  9. package/package.json +2 -2
  10. package/packages/control-plane/dist/server.js +78 -55
  11. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  12. package/web-app/dist/assets/{AdminPage-Cp2bWPgv.js → AdminPage-DVMNRlUX.js} +1 -1
  13. package/web-app/dist/assets/{Avatar-BWkjgfpQ.js → Avatar-BNJ5Hy3D.js} +1 -1
  14. package/web-app/dist/assets/{Badge-DplLKpsq.js → Badge-kTzAMem_.js} +1 -1
  15. package/web-app/dist/assets/{Button-Bi9cmTkv.js → Button-CIPzEBGi.js} +1 -1
  16. package/web-app/dist/assets/{CockpitPage-ZBt9jJqb.js → CockpitPage-Cnekildp.js} +1 -1
  17. package/web-app/dist/assets/{ComparePage-BtfjcKUw.js → ComparePage-CLR-fJb-.js} +1 -1
  18. package/web-app/dist/assets/{ErrorBoundary-D7gzKuQl.js → ErrorBoundary-WSSOc7ES.js} +1 -1
  19. package/web-app/dist/assets/{EvidenceReceiptPanel-B0qgQSt7.js → EvidenceReceiptPanel-5mVPOgON.js} +1 -1
  20. package/web-app/dist/assets/{GitHubIssuesPanel-D7DLUV5y.js → GitHubIssuesPanel-CkcGGhlu.js} +1 -1
  21. package/web-app/dist/assets/{GitHubPRsPanel-B-tSxFMu.js → GitHubPRsPanel-2Zie2x_4.js} +1 -1
  22. package/web-app/dist/assets/{HomePage-9zMRoQ2-.js → HomePage-DI8GDmWZ.js} +2 -2
  23. package/web-app/dist/assets/{LoginPage-CHahatjI.js → LoginPage-DxaGdSYM.js} +1 -1
  24. package/web-app/dist/assets/{MagicPage-CWDBY117.js → MagicPage-DyvUmyQQ.js} +1 -1
  25. package/web-app/dist/assets/{MetricsPage-i0sQqMu5.js → MetricsPage-DMAyTD9l.js} +1 -1
  26. package/web-app/dist/assets/{NotFoundPage-Cep2hjC4.js → NotFoundPage-Cf21HwA9.js} +1 -1
  27. package/web-app/dist/assets/{ProjectPage-B9jVtdf_.js → ProjectPage-DW7ukkoR.js} +3 -3
  28. package/web-app/dist/assets/{ProjectsPage-DT6qTa8F.js → ProjectsPage-CCus6FE7.js} +1 -1
  29. package/web-app/dist/assets/{SettingsPage-DMVIxFyL.js → SettingsPage-Dz9uez0N.js} +1 -1
  30. package/web-app/dist/assets/{ShowcasePage-CenA1vR9.js → ShowcasePage-C5LpPIbE.js} +1 -1
  31. package/web-app/dist/assets/{SystemSettingsPage-Qqy7C834.js → SystemSettingsPage-CRKU-Cry.js} +1 -1
  32. package/web-app/dist/assets/{TeamsPage-Dbc7PMBa.js → TeamsPage-Brk-Kvz_.js} +1 -1
  33. package/web-app/dist/assets/{TemplatesPage-BNpJysCP.js → TemplatesPage-CoozICfx.js} +1 -1
  34. package/web-app/dist/assets/{TerminalOutput-DrhATQOU.js → TerminalOutput-VgpLSPkM.js} +1 -1
  35. package/web-app/dist/assets/{activity-DO1Lb3p_.js → activity-J2SLOoNT.js} +1 -1
  36. package/web-app/dist/assets/{bell-6USNNqOU.js → bell-BpycUrjA.js} +1 -1
  37. package/web-app/dist/assets/{bot-C3WPr7Jc.js → bot-tblN7jAd.js} +1 -1
  38. package/web-app/dist/assets/{check-0PtXKfN0.js → check-7SqhHzzP.js} +1 -1
  39. package/web-app/dist/assets/{chevron-left-xlhDqXSB.js → chevron-left-ntaBx_xF.js} +1 -1
  40. package/web-app/dist/assets/{circle-alert-GKhWaSzf.js → circle-alert-BBSjoKIc.js} +1 -1
  41. package/web-app/dist/assets/{clock-ui1bNcXF.js → clock-_dswOp5X.js} +1 -1
  42. package/web-app/dist/assets/{cloud-CKrUG6Hi.js → cloud-DKOb75-2.js} +1 -1
  43. package/web-app/dist/assets/{code-xml-E0yaCnLv.js → code-xml-D18z-R40.js} +1 -1
  44. package/web-app/dist/assets/{database-CKoePHfR.js → database-DIncPJaM.js} +1 -1
  45. package/web-app/dist/assets/{dollar-sign-BLLEGeDo.js → dollar-sign-BYygqtPF.js} +1 -1
  46. package/web-app/dist/assets/{file-code-corner-DNkK9sHC.js → file-code-corner-BkQxBzA8.js} +1 -1
  47. package/web-app/dist/assets/{file-plus-BZRpulA3.js → file-plus-DQRpTsb-.js} +1 -1
  48. package/web-app/dist/assets/{globe-B8KkmQx6.js → globe-Cb9UTYDC.js} +1 -1
  49. package/web-app/dist/assets/{hammer-Bm6aLg_e.js → hammer-CWs4fhYA.js} +1 -1
  50. package/web-app/dist/assets/{index-BQ_6SUYj.js → index-DhSRa3OQ.js} +3 -3
  51. package/web-app/dist/assets/{layers-BwI4LLZC.js → layers-C9izFUFb.js} +1 -1
  52. package/web-app/dist/assets/{loader-circle-DNNb2uHm.js → loader-circle-BDCpAcJw.js} +1 -1
  53. package/web-app/dist/assets/{lock-C_-piZan.js → lock-DJ1UtPoh.js} +1 -1
  54. package/web-app/dist/assets/{package-CGJ-QLzA.js → package-Dozswt2D.js} +1 -1
  55. package/web-app/dist/assets/{plus-BI3waAt8.js → plus-CLQz8B-L.js} +1 -1
  56. package/web-app/dist/assets/{refresh-cw-Cyc0Be2K.js → refresh-cw-CZ2b-hL5.js} +1 -1
  57. package/web-app/dist/assets/{rotate-ccw-BMF9rcHQ.js → rotate-ccw-CgX6ORxy.js} +1 -1
  58. package/web-app/dist/assets/{scroll-text-DeoapOot.js → scroll-text-B2BrQ69A.js} +1 -1
  59. package/web-app/dist/assets/{server-DvyYi0cU.js → server-BFaVBWgX.js} +1 -1
  60. package/web-app/dist/assets/{shield-alert-Bon6ZnUv.js → shield-alert-xpurE7SL.js} +1 -1
  61. package/web-app/dist/assets/{thumbs-up-98YsSw4r.js → thumbs-up-Cn-1rP6c.js} +1 -1
  62. package/web-app/dist/assets/{trash-2-1U-mCJzW.js → trash-2-SyTF24MM.js} +1 -1
  63. package/web-app/dist/assets/{trending-down-BlHQF7ZA.js → trending-down-B00sbl8f.js} +1 -1
  64. package/web-app/dist/assets/{trending-up-C3BNDS1Z.js → trending-up-s2d_s3Dt.js} +1 -1
  65. package/web-app/dist/assets/{upload-CGW0PxJo.js → upload-Cmg63NHC.js} +1 -1
  66. package/web-app/dist/assets/{usePolling-l8CCUq6q.js → usePolling-C11hGYdh.js} +1 -1
  67. package/web-app/dist/assets/{user-CTHngdi9.js → user-lWcI4YnK.js} +1 -1
  68. package/web-app/dist/index.html +1 -1
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '11.63.7'
78
+ __version__ = '11.63.9'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "11.63.7",
4
+ "version": "11.63.9",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -160,5 +160,5 @@
160
160
  "dependencies": {
161
161
  "@resvg/resvg-wasm": "^2.6.2"
162
162
  },
163
- "gitHead": "d88d9353867c6fd4e04f94357ca0ef0cd4eca602"
163
+ "gitHead": "3f958a8df48b094a2cc397e0981f75b7b3193366"
164
164
  }
@@ -7841,6 +7841,11 @@ var init_watchdog = __esm(() => {
7841
7841
  warned = new Set;
7842
7842
  });
7843
7843
 
7844
+ // ../../loki-ts/src/runner/retry_class.ts
7845
+ var init_retry_class = __esm(() => {
7846
+ init_redact();
7847
+ });
7848
+
7844
7849
  // ../../loki-ts/src/util/cost_breakdown.ts
7845
7850
  function costBreakdown(recs, missing = []) {
7846
7851
  const out2 = { usd: missing.length > 0 ? null : 0, per_stage: {}, retry_usd: missing.length > 0 ? null : 0, retry_sessions: 0 };
@@ -9094,6 +9099,7 @@ var init_sdk_stream_parser = __esm(() => {
9094
9099
  init_budget();
9095
9100
  init_advisor_probe();
9096
9101
  init_paths();
9102
+ init_retry_class();
9097
9103
  });
9098
9104
 
9099
9105
  // ../../loki-ts/src/runner/trim.ts
@@ -9110,6 +9116,7 @@ var _installedVersionCache;
9110
9116
  var init_providers = __esm(() => {
9111
9117
  init_shell();
9112
9118
  init_paths();
9119
+ init_retry_class();
9113
9120
  init_claude_flags();
9114
9121
  init_mcp_config();
9115
9122
  init_lean_prefix();
@@ -9168,6 +9175,7 @@ var init_budget_cap = __esm(() => {
9168
9175
  var STDERR_TAIL_BYTES, ADVISOR_MARKED_STAGES, sessionEffort, lastStageEnd;
9169
9176
  var init_session = __esm(() => {
9170
9177
  init_watchdog();
9178
+ init_retry_class();
9171
9179
  init_run_pid();
9172
9180
  init_provider_cost();
9173
9181
  init_model_routes();
@@ -10228,6 +10236,12 @@ function runnerCmd(t, repoDir) {
10228
10236
  return CARGO_TEST_FILE_RE.test(t.path) ? ["cargo", ["test", "--test", basename12(t.path, ".rs")]] : ["cargo", ["test"]];
10229
10237
  }
10230
10238
  }
10239
+ function fullSuiteCmd(runner, repoDir) {
10240
+ if (runner !== "pytest")
10241
+ return FULL_SUITE_STATIC[runner];
10242
+ const [cmd, interpreter, pre] = resolveTool(repoDir, "python", "python3", "python");
10243
+ return { cmd, args: [...pre, "-m", "pytest", "-q"], interpreter };
10244
+ }
10231
10245
  function commandFor(t, repoDir, api) {
10232
10246
  const site = siteFor(api, repoDir, t.path);
10233
10247
  const [cmd, args, interpreter] = runnerCmd(site ? { runner: t.runner, path: site.file } : t, repoDir);
@@ -10312,7 +10326,7 @@ var NO_TESTS_REASON = "no tests executed", NO_RUNNER_REASON = "no runner of this
10312
10326
  }, EXCERPT_GROUP_CAP = 1500, EXCERPT_TOTAL_CAP = 6144, verifyJobs = () => {
10313
10327
  const n2 = Number.parseInt(process.env["LOKI_E10_VERIFY_JOBS"] ?? "", 10);
10314
10328
  return Number.isFinite(n2) && n2 >= 1 ? Math.min(n2, 8) : 1;
10315
- }, FULL_SUITE_CMD, ALREADY_FAILING_ON_BASE = "already failing on base, not caused by this change", SKIPPED_BY_REPO = "skipped by the repo on base and head", checkResultLabel = (result, preRed, repoSkipped = false) => result === "fail" && preRed ? `fail (${ALREADY_FAILING_ON_BASE})` : result === "not_run" && repoSkipped ? `not_run (${SKIPPED_BY_REPO})` : result, blobSha = (b, hex) => createHash8(hex === 64 ? "sha256" : "sha1").update(Buffer.concat([Buffer.from(`blob ${b.length}\x00`), b])).digest("hex");
10329
+ }, FULL_SUITE_STATIC, ALREADY_FAILING_ON_BASE = "already failing on base, not caused by this change", SKIPPED_BY_REPO = "skipped by the repo on base and head", checkResultLabel = (result, preRed, repoSkipped = false) => result === "fail" && preRed ? `fail (${ALREADY_FAILING_ON_BASE})` : result === "not_run" && repoSkipped ? `not_run (${SKIPPED_BY_REPO})` : result, blobSha = (b, hex) => createHash8(hex === 64 ? "sha256" : "sha1").update(Buffer.concat([Buffer.from(`blob ${b.length}\x00`), b])).digest("hex");
10316
10330
  var init_check_result = __esm(() => {
10317
10331
  init_resolve();
10318
10332
  init_testmap();
@@ -10362,8 +10376,7 @@ var init_check_result = __esm(() => {
10362
10376
  DOC_FILE = /\.(md|mdx|txt|rst|adoc)$/i;
10363
10377
  OWNER_FILES = [".github/CODEOWNERS", "CODEOWNERS", "docs/CODEOWNERS"];
10364
10378
  CRITICAL_TOKENS = /^(release|publish|sign|signing|signer|auth|security|seal|verif\w*)$/i;
10365
- FULL_SUITE_CMD = {
10366
- pytest: { cmd: "python", args: ["-m", "pytest", "-q"] },
10379
+ FULL_SUITE_STATIC = {
10367
10380
  vitest: { cmd: "npx", args: ["vitest", "run"] },
10368
10381
  jest: { cmd: "npx", args: ["jest"] },
10369
10382
  bun: { cmd: "bun", args: ["test"] },
@@ -14510,9 +14523,6 @@ var init_secure_scan = __esm(() => {
14510
14523
  MAX_ADDED_FILE_BYTES = 64 * 1024 * 1024;
14511
14524
  });
14512
14525
 
14513
- // ../../loki-ts/src/runner/retry_class.ts
14514
- var init_retry_class = () => {};
14515
-
14516
14526
  // ../../loki-ts/src/project_model/conventions.ts
14517
14527
  import { existsSync as existsSync34, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "fs";
14518
14528
  import { basename as basename22, dirname as dirname21, isAbsolute as isAbsolute9, join as join53, relative as relative10, resolve as resolve18 } from "path";
@@ -15264,11 +15274,12 @@ async function sealEvidence(repoDir, runDir, o, notProven, signal, emit) {
15264
15274
  const ev = await captureVisualEvidence(repoDir, runDir, cf, { signal, onServer: (pgid) => emit?.("session.started", "seal", { session_id: "visual-evidence", provider: "visual-evidence", model: null, pgid }) });
15265
15275
  if (signal?.aborted)
15266
15276
  throw new Error("seal aborted: visual evidence discarded");
15267
- if (ev.skipped)
15277
+ const noUi = ev.skipped !== null && ev.skipped !== undefined && /^no package\.json$|^no dev, preview or start script$/.test(ev.skipped) && process.env["LOKI_VISUAL_EVIDENCE"] !== "1" && !cf.some(isPageFile);
15278
+ if (ev.skipped && !noUi)
15268
15279
  notProven.add(`visual evidence skipped: ${ev.skipped}`);
15269
15280
  if (ev.e2eSkipped)
15270
15281
  notProven.add(ev.e2eSkipped);
15271
- if (visualGateEnabled() && ev.skipped && !/^no changed page files/.test(ev.skipped))
15282
+ if (visualGateEnabled() && ev.skipped && !noUi && !/^no changed page files/.test(ev.skipped))
15272
15283
  return { evidence_failed: ev.skipped };
15273
15284
  return ev.screens.length > 0 ? { evidence_screens: ev.screens } : {};
15274
15285
  }
@@ -15620,7 +15631,7 @@ async function runFullSuite(ctx, signal, opts, checks, notProven) {
15620
15631
  return;
15621
15632
  }
15622
15633
  for (const runner of map.runners) {
15623
- const spec = FULL_SUITE_CMD[runner];
15634
+ const spec = fullSuiteCmd(runner, ctx.repoDir);
15624
15635
  const name = `full suite: ${runner}`;
15625
15636
  if (!Bun.which(spec.cmd, opts.path ? { PATH: opts.path } : undefined)) {
15626
15637
  checks.push({ name, cmd: [spec.cmd, ...spec.args].join(" "), result: "not_run", duration_s: 0 });
@@ -15854,7 +15865,7 @@ var init_deep = __esm(() => {
15854
15865
  });
15855
15866
 
15856
15867
  // ../../loki-ts/src/engine10/stages/verify.ts
15857
- import { existsSync as existsSync39, mkdtempSync as mkdtempSync10, rmSync as rmSync19 } from "fs";
15868
+ import { existsSync as existsSync39, mkdtempSync as mkdtempSync10, readFileSync as readFileSync48, rmSync as rmSync19 } from "fs";
15858
15869
  import { tmpdir as tmpdir11 } from "os";
15859
15870
  import { basename as basename23, isAbsolute as isAbsolute11, join as join60, relative as relative12 } from "path";
15860
15871
  async function runOnce2(cmd2, args, cwd, signal, opts) {
@@ -15971,13 +15982,25 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
15971
15982
  function isLokiModeRepo(repoDir) {
15972
15983
  return existsSync39(join60(repoDir, "scripts", "select-tests.sh"));
15973
15984
  }
15985
+ function projectDeclaresRuff(repoDir) {
15986
+ if (["ruff.toml", ".ruff.toml"].some((f) => existsSync39(join60(repoDir, f))))
15987
+ return true;
15988
+ const files = ["pyproject.toml", "setup.cfg", "tox.ini", ".pre-commit-config.yaml", "Pipfile", "requirements.txt", "requirements-dev.txt", "dev-requirements.txt"];
15989
+ return files.some((f) => {
15990
+ try {
15991
+ return /\bruff\b/i.test(readFileSync48(join60(repoDir, f), "utf8"));
15992
+ } catch {
15993
+ return false;
15994
+ }
15995
+ });
15996
+ }
15974
15997
  async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
15975
15998
  const { api, ...runOpts } = opts;
15976
15999
  opts = runOpts;
15977
16000
  const pre = [];
15978
16001
  const py = changed.filter((f) => f.endsWith(".py"));
15979
- if (py.length) {
15980
- const [ruffCmd, interpreter, uvPre] = resolveTool(ctx.repoDir, "ruff", "ruff");
16002
+ const [ruffCmd, interpreter, uvPre] = py.length ? resolveTool(ctx.repoDir, "ruff", "ruff") : ["ruff", "system", []];
16003
+ if (py.length && (interpreter !== "system" || Bun.which("ruff", { PATH: process.env["PATH"] ?? "" }) || projectDeclaresRuff(ctx.repoDir))) {
15981
16004
  const c = await runCheck(ctx, "lint:ruff", ruffCmd, [...uvPre, "check", "--output-format=concise", ...py], signal, checks, { ...opts, interpreter, kind: "static" });
15982
16005
  if (await excuseLint(ctx, signal, c, "ruff", ruffCmd, [...uvPre, "check"], ctx.repoDir, py, opts))
15983
16006
  pre.push(c.name);
@@ -16192,7 +16215,7 @@ ${x}` : c.cmd };
16192
16215
 
16193
16216
  // ../../loki-ts/src/engine10/stages/wall.ts
16194
16217
  import { spawnSync as spawnSync7 } from "child_process";
16195
- import { existsSync as existsSync40, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync11, readFileSync as readFileSync48, readdirSync as readdirSync21, rmSync as rmSync20, writeFileSync as writeFileSync28 } from "fs";
16218
+ import { existsSync as existsSync40, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync11, readFileSync as readFileSync49, readdirSync as readdirSync21, rmSync as rmSync20, writeFileSync as writeFileSync28 } from "fs";
16196
16219
  import { tmpdir as tmpdir12 } from "os";
16197
16220
  import { dirname as dirname26, join as join61, relative as relative13 } from "path";
16198
16221
 
@@ -16262,7 +16285,7 @@ function loadTaskText(ctx, fromPrior) {
16262
16285
  const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join61(ctx.runDir, "issue.json");
16263
16286
  if (existsSync40(issueJsonPath)) {
16264
16287
  try {
16265
- const issue = JSON.parse(readFileSync48(issueJsonPath, "utf8"));
16288
+ const issue = JSON.parse(readFileSync49(issueJsonPath, "utf8"));
16266
16289
  const text2 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
16267
16290
 
16268
16291
  `);
@@ -16322,20 +16345,20 @@ async function wallAuthor(ctx, signal, retry) {
16322
16345
  }
16323
16346
  const planText = typeof prior.plan?.plan === "string" ? prior.plan.plan : null, repoFiles = repoMap?.files ?? [];
16324
16347
  const oor = () => readdirSync21(cwd).filter((f) => f.startsWith(WALL_PREFIX)).flatMap((name) => {
16325
- const text2 = readFileSync48(join61(cwd, name), "utf8"), why = outOfRepoTarget(text2) ?? phantomReason(phantomRepoPaths(text2, name, targetDir, ctx.repoDir, planText), repoFiles, relative13(ctx.repoDir, targetDir), pkg?.root ?? "");
16348
+ const text2 = readFileSync49(join61(cwd, name), "utf8"), why = outOfRepoTarget(text2) ?? phantomReason(phantomRepoPaths(text2, name, targetDir, ctx.repoDir, planText), repoFiles, relative13(ctx.repoDir, targetDir), pkg?.root ?? "");
16326
16349
  return why ? [{ name, why }] : [];
16327
16350
  });
16328
16351
  const bad1 = oor();
16329
16352
  if (bad1.length > 0 && !signal.aborted && !ctx.overCap?.())
16330
16353
  await ctx.sessions.run({ stage: "wall", brief: withStagePrefix(outOfRepoReask("Rewrite these Wall files in place, keeping the same names and acceptance coverage.", bad1)), tier: "development", model, iterationId: `${iterationId}-oor`, limitS: wallLimitS(sz.size), signal, cwd });
16331
- const oorBad = new Map(oor().map((b) => [b.name, b.why])), all = readdirSync21(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !oorBad.has(n2) && !conventionViolation(conv2, n2, readFileSync48(join61(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
16354
+ const oorBad = new Map(oor().map((b) => [b.name, b.why])), all = readdirSync21(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !oorBad.has(n2) && !conventionViolation(conv2, n2, readFileSync49(join61(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
16332
16355
  const sealedDir = join61(ctx.runDir, "wall");
16333
16356
  if (generated.length > 0)
16334
16357
  mkdirSync25(sealedDir, { recursive: true });
16335
16358
  const contents = new Map;
16336
16359
  const discarded = [];
16337
16360
  for (const name of generated) {
16338
- const content = readFileSync48(join61(cwd, name), "utf8"), oorWhy = oorBad.get(name), bad = oorWhy ?? conventionViolation(conv2, name, content);
16361
+ const content = readFileSync49(join61(cwd, name), "utf8"), oorWhy = oorBad.get(name), bad = oorWhy ?? conventionViolation(conv2, name, content);
16339
16362
  writeFileSync28(join61(sealedDir, name), content, "utf8");
16340
16363
  if (oorWhy)
16341
16364
  discarded.push({ file: name, reason: `${oorWhy}; wall test discarded after one rewrite request` });
@@ -16459,7 +16482,7 @@ var init_wall = __esm(() => {
16459
16482
  });
16460
16483
 
16461
16484
  // ../../loki-ts/src/e10ext/discard.ts
16462
- import { chmodSync as chmodSync6, closeSync as closeSync9, lstatSync as lstatSync16, mkdirSync as mkdirSync26, openSync as openSync9, readFileSync as readFileSync49, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync7, writeFileSync as writeFileSync29 } from "fs";
16485
+ import { chmodSync as chmodSync6, closeSync as closeSync9, lstatSync as lstatSync16, mkdirSync as mkdirSync26, openSync as openSync9, readFileSync as readFileSync50, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync7, writeFileSync as writeFileSync29 } from "fs";
16463
16486
  import { dirname as dirname27, join as join62, relative as relative14, sep as sep14 } from "path";
16464
16487
  function safeRestore(repoDir, f, want, mode) {
16465
16488
  const root = realpathSync23(repoDir), fp = join62(root, f), rel = relative14(root, dirname27(fp));
@@ -16484,7 +16507,7 @@ function safeRestore(repoDir, f, want, mode) {
16484
16507
  } catch {
16485
16508
  st = null;
16486
16509
  }
16487
- if (st?.isFile() && readFileSync49(fp).equals(want)) {
16510
+ if (st?.isFile() && readFileSync50(fp).equals(want)) {
16488
16511
  chmodSync6(fp, mode);
16489
16512
  return;
16490
16513
  }
@@ -16586,14 +16609,14 @@ var init_scope2 = __esm(() => {
16586
16609
  });
16587
16610
 
16588
16611
  // ../../loki-ts/src/council/role_agents.ts
16589
- import { existsSync as existsSync41, readdirSync as readdirSync22, readFileSync as readFileSync50 } from "fs";
16612
+ import { existsSync as existsSync41, readdirSync as readdirSync22, readFileSync as readFileSync51 } from "fs";
16590
16613
  import { homedir as homedir9 } from "os";
16591
16614
  import { join as join63 } from "path";
16592
16615
  function agentDirs(repoDir, env = process.env) {
16593
16616
  return [env["LOKI_AGENTS_PROJECT_DIR"] || join63(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join63(env["XDG_CONFIG_HOME"] || join63(homedir9(), ".config"), "loki", "agents")];
16594
16617
  }
16595
16618
  function parseAgent(file, stem2) {
16596
- const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync50(file, "utf8"));
16619
+ const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync51(file, "utf8"));
16597
16620
  if (!m)
16598
16621
  return null;
16599
16622
  const body = m[2].trim();
@@ -16713,14 +16736,14 @@ var init_colors = __esm(() => {
16713
16736
  });
16714
16737
 
16715
16738
  // ../../loki-ts/src/util/run_summary.ts
16716
- import { existsSync as existsSync42, mkdirSync as mkdirSync28, readFileSync as readFileSync51, renameSync as renameSync13, statSync as statSync20, writeFileSync as writeFileSync30 } from "fs";
16739
+ import { existsSync as existsSync42, mkdirSync as mkdirSync28, readFileSync as readFileSync52, renameSync as renameSync13, statSync as statSync20, writeFileSync as writeFileSync30 } from "fs";
16717
16740
  import { join as join65 } from "path";
16718
16741
  function readRiskRecord(repoDir, sinceMs = 0) {
16719
16742
  try {
16720
16743
  const p = join65(repoDir, ".loki", "state", "risk-tier.json");
16721
16744
  if (statSync20(p).mtimeMs < sinceMs)
16722
16745
  return null;
16723
- const r = JSON.parse(readFileSync51(p, "utf8"));
16746
+ const r = JSON.parse(readFileSync52(p, "utf8"));
16724
16747
  return r && typeof r === "object" ? r : null;
16725
16748
  } catch {
16726
16749
  return null;
@@ -16736,7 +16759,7 @@ var init_run_summary = __esm(() => {
16736
16759
  });
16737
16760
 
16738
16761
  // ../../loki-ts/src/engine10/stages/xreview.ts
16739
- import { existsSync as existsSync43, readFileSync as readFileSync52 } from "fs";
16762
+ import { existsSync as existsSync43, readFileSync as readFileSync53 } from "fs";
16740
16763
  import { join as join66 } from "path";
16741
16764
  function minVerdict(verdict, review) {
16742
16765
  const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
@@ -16754,7 +16777,7 @@ function explicitReview(repoDir, env) {
16754
16777
  if (!existsSync43(p))
16755
16778
  continue;
16756
16779
  try {
16757
- const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync52(p, "utf8"));
16780
+ const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync53(p, "utf8"));
16758
16781
  const v = asProvider(m?.[1]);
16759
16782
  if (v)
16760
16783
  return v;
@@ -16949,7 +16972,7 @@ See also: loki cost --detail (what a run ALREADY spent)
16949
16972
  });
16950
16973
 
16951
16974
  // ../../loki-ts/src/features/contract.ts
16952
- import { existsSync as existsSync44, lstatSync as lstatSync17, mkdirSync as mkdirSync29, readFileSync as readFileSync53, rmSync as rmSync21, writeFileSync as writeFileSync31 } from "fs";
16975
+ import { existsSync as existsSync44, lstatSync as lstatSync17, mkdirSync as mkdirSync29, readFileSync as readFileSync54, rmSync as rmSync21, writeFileSync as writeFileSync31 } from "fs";
16953
16976
  import { dirname as dirname29, join as join67 } from "path";
16954
16977
  import { createHash as createHash18 } from "crypto";
16955
16978
  function contractEnabled(env = process.env) {
@@ -16998,7 +17021,7 @@ function readContract(repoDir) {
16998
17021
  return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
16999
17022
  let raw2;
17000
17023
  try {
17001
- raw2 = readFileSync53(p);
17024
+ raw2 = readFileSync54(p);
17002
17025
  } catch {
17003
17026
  return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
17004
17027
  }
@@ -17073,7 +17096,7 @@ var init_contract = __esm(() => {
17073
17096
 
17074
17097
  // ../../loki-ts/src/features/speed/seal_group.ts
17075
17098
  import { createHash as createHash19 } from "crypto";
17076
- import { existsSync as existsSync45, mkdirSync as mkdirSync30, readdirSync as readdirSync23, readFileSync as readFileSync54, renameSync as renameSync14, statSync as statSync21, writeFileSync as writeFileSync32 } from "fs";
17099
+ import { existsSync as existsSync45, mkdirSync as mkdirSync30, readdirSync as readdirSync23, readFileSync as readFileSync55, renameSync as renameSync14, statSync as statSync21, writeFileSync as writeFileSync32 } from "fs";
17077
17100
  import { dirname as dirname30, join as join68 } from "path";
17078
17101
  function sealGroup(runDir, rh) {
17079
17102
  const manifestPath = join68(runDir, "group", "manifest.json");
@@ -17104,7 +17127,7 @@ function sealGroup(runDir, rh) {
17104
17127
  const dir = join68(unitsDir(runDir), id), rp = join68(dir, "receipt.json"), ep = join68(dir, "events.jsonl");
17105
17128
  let bytes;
17106
17129
  try {
17107
- bytes = readFileSync54(rp);
17130
+ bytes = readFileSync55(rp);
17108
17131
  } catch {
17109
17132
  return fail2(`unit ${id} sub-receipt missing`);
17110
17133
  }
@@ -17121,7 +17144,7 @@ function sealGroup(runDir, rh) {
17121
17144
  unit_id: id,
17122
17145
  sub_receipt_sha256: sha3(bytes),
17123
17146
  receipt_sha256: sub2["receipt_sha256"],
17124
- events_file_sha256: existsSync45(ep) ? sha3(readFileSync54(ep)) : null,
17147
+ events_file_sha256: existsSync45(ep) ? sha3(readFileSync55(ep)) : null,
17125
17148
  verdict,
17126
17149
  goal: text2(u["goal"], 200),
17127
17150
  files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
@@ -17165,13 +17188,13 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
17165
17188
  try {
17166
17189
  if (!statSync21(dir).isDirectory())
17167
17190
  return bad(`unit ${id} is not a directory`);
17168
- bytes = readFileSync54(rp);
17191
+ bytes = readFileSync55(rp);
17169
17192
  } catch {
17170
17193
  return bad(`unit ${id} sub-receipt missing`);
17171
17194
  }
17172
17195
  if (sha3(bytes) !== e["sub_receipt_sha256"])
17173
17196
  return bad(`unit ${id} sub-receipt does not match its recorded hash`);
17174
- const evSha = existsSync45(ep) ? sha3(readFileSync54(ep)) : null;
17197
+ const evSha = existsSync45(ep) ? sha3(readFileSync55(ep)) : null;
17175
17198
  if (evSha !== (e["events_file_sha256"] ?? null))
17176
17199
  return bad(`unit ${id} events.jsonl does not match its recorded hash`);
17177
17200
  const sub2 = readJson6(rp);
@@ -17196,7 +17219,7 @@ function compositeVerdict(childVerdicts) {
17196
17219
  }
17197
17220
  var ID_RE, PASSING, sha3 = (b) => createHash19("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) => join68(runDir, "group", "units"), readJson6 = (p) => {
17198
17221
  try {
17199
- return JSON.parse(readFileSync54(p, "utf8"));
17222
+ return JSON.parse(readFileSync55(p, "utf8"));
17200
17223
  } catch {
17201
17224
  return;
17202
17225
  }
@@ -17214,7 +17237,7 @@ var init_seal_group = __esm(() => {
17214
17237
  });
17215
17238
 
17216
17239
  // ../../loki-ts/src/supply/supply_guard.ts
17217
- import { existsSync as existsSync46, readFileSync as readFileSync55, statSync as statSync22 } from "fs";
17240
+ import { existsSync as existsSync46, readFileSync as readFileSync56, statSync as statSync22 } from "fs";
17218
17241
  import { basename as basename25, join as join69 } from "path";
17219
17242
  function supplyEnabled(env) {
17220
17243
  return env["LOKI_SUPPLY_GUARD"] !== "0";
@@ -17236,7 +17259,7 @@ function readDeclared(repoDir) {
17236
17259
  try {
17237
17260
  if (statSync22(p).size > MAX_FILE_BYTES)
17238
17261
  return { deps: [], problem: "declaration file too large" };
17239
- const j = JSON.parse(readFileSync55(p, "utf8"));
17262
+ const j = JSON.parse(readFileSync56(p, "utf8"));
17240
17263
  if (!Array.isArray(j))
17241
17264
  return { deps: [], problem: "declaration is not a JSON array" };
17242
17265
  const deps = [];
@@ -17260,7 +17283,7 @@ function readAllowlist(repoDir) {
17260
17283
  if (!existsSync46(p))
17261
17284
  return new Set;
17262
17285
  try {
17263
- return new Set(readFileSync55(p, "utf8").split(`
17286
+ return new Set(readFileSync56(p, "utf8").split(`
17264
17287
  `).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
17265
17288
  } catch {
17266
17289
  return new Set;
@@ -17443,7 +17466,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
17443
17466
  }
17444
17467
  }, PUBLIC_HOSTS, hostOf = (u) => u.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//, "").replace(/^www\./, "").split(/[/?#\s]/)[0].replace(/^[^@]*@/, "").replace(/:\d+$/, ""), privateUrl = (u) => /[a-z0-9]/i.test(u) && !PUBLIC_HOSTS.has(hostOf(u)), readSmall = (p) => {
17445
17468
  try {
17446
- return statSync22(p).size <= MAX_FILE_BYTES ? readFileSync55(p, "utf8") : "";
17469
+ return statSync22(p).size <= MAX_FILE_BYTES ? readFileSync56(p, "utf8") : "";
17447
17470
  } catch {
17448
17471
  return "";
17449
17472
  }
@@ -17459,7 +17482,7 @@ var init_supply_guard = __esm(() => {
17459
17482
 
17460
17483
  // ../../loki-ts/src/engine10/stages/seal.ts
17461
17484
  import { createHash as createHash20 } from "crypto";
17462
- import { existsSync as existsSync47, readdirSync as readdirSync24, mkdirSync as mkdirSync31, readFileSync as readFileSync56 } from "fs";
17485
+ import { existsSync as existsSync47, readdirSync as readdirSync24, mkdirSync as mkdirSync31, readFileSync as readFileSync57 } from "fs";
17463
17486
  import { basename as basename26, isAbsolute as isAbsolute13, join as join70, relative as relative15 } from "path";
17464
17487
  function receiptSha256(r) {
17465
17488
  const { verification: _v, receipt_sha256: _h, ...body } = r;
@@ -17725,7 +17748,7 @@ var init_seal = __esm(() => {
17725
17748
  if (mp?.outcome === "no")
17726
17749
  notProven.add(`Wall tests passed without the fix (mutation proof)${verdict !== verdict2 ? "; verdict downgraded to PARTIAL (LOKI_MUTATION_STRICT=1, declared behavior change)" : ""}`);
17727
17750
  if (repo === null)
17728
- notProven.add("repo not recorded by intake");
17751
+ notProven.add(o.intake && "repo" in o.intake ? "repo identity unknown: the repo has no origin remote (run: git remote add origin <url>)" : "repo not recorded by intake");
17729
17752
  if (typeof o.intake?.resumed !== "boolean")
17730
17753
  notProven.add("resume state not recorded by intake");
17731
17754
  const stages = {};
@@ -17786,7 +17809,7 @@ var init_seal = __esm(() => {
17786
17809
  provider: ctx.provider,
17787
17810
  model: ctx.model,
17788
17811
  resumed: o.intake?.resumed === true,
17789
- events_sha256: sha2562(existsSync47(eventsPath) ? readFileSync56(eventsPath) : ""),
17812
+ events_sha256: sha2562(existsSync47(eventsPath) ? readFileSync57(eventsPath) : ""),
17790
17813
  ...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
17791
17814
  log_seal: true,
17792
17815
  toolchain: collectToolchain(),
@@ -17842,14 +17865,14 @@ var init_seal = __esm(() => {
17842
17865
  });
17843
17866
 
17844
17867
  // ../../loki-ts/src/util/composite_seal.ts
17845
- import { existsSync as existsSync48, readFileSync as readFileSync57 } from "fs";
17868
+ import { existsSync as existsSync48, readFileSync as readFileSync58 } from "fs";
17846
17869
  import { basename as basename27, dirname as dirname32, join as join71 } from "path";
17847
17870
  function logProblem(runDir, integ) {
17848
17871
  if (typeof integ["log_sha256"] !== "string")
17849
17872
  return null;
17850
17873
  let b;
17851
17874
  try {
17852
- b = readFileSync57(join71(runDir, "integration.log"));
17875
+ b = readFileSync58(join71(runDir, "integration.log"));
17853
17876
  } catch {
17854
17877
  return "integration.log is missing but integration.json records its hash";
17855
17878
  }
@@ -17872,7 +17895,7 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
17872
17895
  return bad("body malformed");
17873
17896
  let ibytes;
17874
17897
  try {
17875
- ibytes = readFileSync57(join71(runDir, "integration.json"));
17898
+ ibytes = readFileSync58(join71(runDir, "integration.json"));
17876
17899
  } catch {
17877
17900
  return bad("integration.json missing");
17878
17901
  }
@@ -17916,7 +17939,7 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
17916
17939
  const rp = join71(runDir, rel);
17917
17940
  let bytes;
17918
17941
  try {
17919
- bytes = readFileSync57(rp);
17942
+ bytes = readFileSync58(rp);
17920
17943
  } catch {
17921
17944
  return bad(`child ${repo} receipt missing`);
17922
17945
  }
@@ -17965,7 +17988,7 @@ var init_keys_cmd = __esm(() => {
17965
17988
  });
17966
17989
 
17967
17990
  // ../../loki-ts/src/engine10/verify_cmd.ts
17968
- import { existsSync as existsSync49, readFileSync as readFileSync58, renameSync as renameSync15, statSync as statSync24, writeFileSync as writeFileSync34 } from "fs";
17991
+ import { existsSync as existsSync49, readFileSync as readFileSync59, renameSync as renameSync15, statSync as statSync24, writeFileSync as writeFileSync34 } from "fs";
17969
17992
  import { basename as basename28, dirname as dirname33, join as join72 } from "path";
17970
17993
  import { createHash as createHash21, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
17971
17994
  function pubFor(kid, given) {
@@ -17974,7 +17997,7 @@ function pubFor(kid, given) {
17974
17997
  const active = loadSigningKey(false);
17975
17998
  const pubs = (process.env["LOKI_RECEIPT_RETIRED_PUBKEYS"] ?? "").split(":").map((f) => f.trim()).filter(Boolean).flatMap((f) => {
17976
17999
  try {
17977
- return [createPublicKey4(readFileSync58(f))];
18000
+ return [createPublicKey4(readFileSync59(f))];
17978
18001
  } catch {
17979
18002
  return [];
17980
18003
  }
@@ -18021,7 +18044,7 @@ function checkEventLog(receiptPath, receipt) {
18021
18044
  const path = join72(dirname33(receiptPath), "events.jsonl");
18022
18045
  if (!existsSync49(path))
18023
18046
  return "events.jsonl is missing";
18024
- const raw2 = readFileSync58(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
18047
+ const raw2 = readFileSync59(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
18025
18048
  `).filter((l) => l.trim() !== "");
18026
18049
  if (events2.length !== lines2.length || events2.some((e, i) => e.seq !== i))
18027
18050
  return "events.jsonl has a forged, edited or missing line";
@@ -18045,7 +18068,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
18045
18068
  const seal = events2[done + 1], d = seal?.type === "log.sealed" ? seal.data : null;
18046
18069
  if (!d)
18047
18070
  return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
18048
- const lines2 = readFileSync58(path, "utf8").split(`
18071
+ const lines2 = readFileSync59(path, "utf8").split(`
18049
18072
  `).filter((l) => l.trim() !== ""), sha4 = createHash21("sha256").update(lines2.slice(0, done + 1).join(`
18050
18073
  `) + `
18051
18074
  `).digest("hex");
@@ -18059,7 +18082,7 @@ async function verifyReceipt(receiptPath, deps = {}) {
18059
18082
  return { verdict: "UNCHECKED", reasons: [`receipt not found: ${receiptPath}`] };
18060
18083
  let receipt;
18061
18084
  try {
18062
- receipt = JSON.parse((deps.read ?? ((p) => readFileSync58(p, "utf8")))(receiptPath));
18085
+ receipt = JSON.parse((deps.read ?? ((p) => readFileSync59(p, "utf8")))(receiptPath));
18063
18086
  } catch {
18064
18087
  return { verdict: "UNCHECKED", reasons: ["receipt.json is not valid JSON"] };
18065
18088
  }
@@ -18148,7 +18171,7 @@ var init_verify_cmd = __esm(() => {
18148
18171
  });
18149
18172
 
18150
18173
  // src/server/app.ts
18151
- import { existsSync as existsSync51, readFileSync as readFileSync61, statSync as statSync25 } from "fs";
18174
+ import { existsSync as existsSync51, readFileSync as readFileSync62, statSync as statSync25 } from "fs";
18152
18175
  import { join as join75, resolve as resolve19, sep as sep16 } from "path";
18153
18176
 
18154
18177
  // node_modules/hono/dist/request/constants.js
@@ -28460,7 +28483,7 @@ function mount20(ctx) {
28460
28483
  }
28461
28484
 
28462
28485
  // src/server/routes/verify.ts
28463
- import { readFileSync as readFileSync59, realpathSync as realpathSync25 } from "fs";
28486
+ import { readFileSync as readFileSync60, realpathSync as realpathSync25 } from "fs";
28464
28487
  import { createPublicKey as createPublicKey5 } from "crypto";
28465
28488
  import { join as join73, sep as sep15 } from "path";
28466
28489
  init_verify_cmd();
@@ -28512,7 +28535,7 @@ function mount21(ctx) {
28512
28535
  sha4 = r.receiptSha256 ?? null;
28513
28536
  }
28514
28537
  try {
28515
- outcome = outcomeOf(JSON.parse(readFileSync59(file, "utf8")));
28538
+ outcome = outcomeOf(JSON.parse(readFileSync60(file, "utf8")));
28516
28539
  } catch {
28517
28540
  outcome = "UNREADABLE";
28518
28541
  }
@@ -28574,7 +28597,7 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
28574
28597
  }
28575
28598
 
28576
28599
  // src/server/legacy/shim.ts
28577
- import { existsSync as existsSync50, readFileSync as readFileSync60 } from "fs";
28600
+ import { existsSync as existsSync50, readFileSync as readFileSync61 } from "fs";
28578
28601
  import { join as join74 } from "path";
28579
28602
 
28580
28603
  // src/server/legacy/routes.ts
@@ -28956,7 +28979,7 @@ var repoVersion = () => {
28956
28979
  for (const f of [join74(import.meta.dir, "../../../../../VERSION")]) {
28957
28980
  try {
28958
28981
  if (existsSync50(f))
28959
- return readFileSync60(f, "utf8").trim();
28982
+ return readFileSync61(f, "utf8").trim();
28960
28983
  } catch {}
28961
28984
  }
28962
28985
  return "unknown";
@@ -29170,7 +29193,7 @@ function createApp(opts) {
29170
29193
  for (const f of [process.env.LOKI_VERSION_FILE, join75(import.meta.dir, "../../../../VERSION")]) {
29171
29194
  try {
29172
29195
  if (f)
29173
- return readFileSync61(f, "utf8").trim() || "unknown";
29196
+ return readFileSync62(f, "utf8").trim() || "unknown";
29174
29197
  } catch {}
29175
29198
  }
29176
29199
  return "unknown";
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "11.63.7",
5
+ "version": "11.63.9",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -1,4 +1,4 @@
1
- import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-BQ_6SUYj.js";import{B as C}from"./Button-Bi9cmTkv.js";import{T as $e}from"./trending-up-C3BNDS1Z.js";import{C as z}from"./clock-ui1bNcXF.js";import{A as Be,U as ue,M as De}from"./Avatar-BWkjgfpQ.js";import{A as J}from"./activity-DO1Lb3p_.js";import{R as pe}from"./refresh-cw-Cyc0Be2K.js";import{G as ze}from"./globe-B8KkmQx6.js";import{C as Le}from"./chevron-left-xlhDqXSB.js";import{C as je}from"./check-0PtXKfN0.js";import{D as Y}from"./dollar-sign-BLLEGeDo.js";import{U as Te}from"./user-CTHngdi9.js";import{D as Me}from"./database-CKoePHfR.js";import{L as Ue}from"./lock-C_-piZan.js";import{S as Re}from"./scroll-text-DeoapOot.js";import{S as Ie}from"./shield-alert-Bon6ZnUv.js";/**
1
+ import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-DhSRa3OQ.js";import{B as C}from"./Button-CIPzEBGi.js";import{T as $e}from"./trending-up-s2d_s3Dt.js";import{C as z}from"./clock-_dswOp5X.js";import{A as Be,U as ue,M as De}from"./Avatar-BNJ5Hy3D.js";import{A as J}from"./activity-J2SLOoNT.js";import{R as pe}from"./refresh-cw-CZ2b-hL5.js";import{G as ze}from"./globe-Cb9UTYDC.js";import{C as Le}from"./chevron-left-ntaBx_xF.js";import{C as je}from"./check-7SqhHzzP.js";import{D as Y}from"./dollar-sign-BYygqtPF.js";import{U as Te}from"./user-lWcI4YnK.js";import{D as Me}from"./database-DIncPJaM.js";import{L as Ue}from"./lock-DJ1UtPoh.js";import{S as Re}from"./scroll-text-B2BrQ69A.js";import{S as Ie}from"./shield-alert-xpurE7SL.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as l,j as s}from"./index-BQ_6SUYj.js";/**
1
+ import{c as l,j as s}from"./index-DhSRa3OQ.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as e}from"./index-BQ_6SUYj.js";import{C as r}from"./clock-ui1bNcXF.js";import{C as a}from"./circle-alert-GKhWaSzf.js";import{C as l}from"./check-0PtXKfN0.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
1
+ import{j as e}from"./index-DhSRa3OQ.js";import{C as r}from"./clock-_dswOp5X.js";import{C as a}from"./circle-alert-BBSjoKIc.js";import{C as l}from"./check-7SqhHzzP.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
@@ -1 +1 @@
1
- import{r as p,j as t}from"./index-BQ_6SUYj.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
1
+ import{r as p,j as t}from"./index-DhSRa3OQ.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
@@ -1,4 +1,4 @@
1
- import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-BQ_6SUYj.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-D7gzKuQl.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-98YsSw4r.js";import{C as oe}from"./check-0PtXKfN0.js";import{C as Ye}from"./clock-ui1bNcXF.js";import{D as Xe}from"./dollar-sign-BLLEGeDo.js";import{U as Ze}from"./upload-CGW0PxJo.js";import{L as V}from"./loader-circle-DNNb2uHm.js";/**
1
+ import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-DhSRa3OQ.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-WSSOc7ES.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-Cn-1rP6c.js";import{C as oe}from"./check-7SqhHzzP.js";import{C as Ye}from"./clock-_dswOp5X.js";import{D as Xe}from"./dollar-sign-BYygqtPF.js";import{U as Ze}from"./upload-Cmg63NHC.js";import{L as V}from"./loader-circle-BDCpAcJw.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.