loki-mode 11.17.82 → 11.17.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/FAILURE-CLASSES.md +8 -0
- package/docs/v10/PROGRESS.md +3 -0
- package/loki-ts/dist/loki.js +1230 -1229
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +186 -25
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-BRdwyMOz.js → AdminPage-CrFXPtYq.js} +1 -1
- package/web-app/dist/assets/{Avatar-BgBez5kw.js → Avatar-ByHPLzy-.js} +1 -1
- package/web-app/dist/assets/{Badge-DI1obeQL.js → Badge-Cv86Tg1z.js} +1 -1
- package/web-app/dist/assets/{Button-K12ksdPS.js → Button-Cmt4rAI6.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-CcdJJz6Y.js → CockpitPage-C5oGG7HK.js} +1 -1
- package/web-app/dist/assets/{ComparePage-BjQE-BcT.js → ComparePage-BLHQkb2H.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-CSeWwyja.js → ErrorBoundary-CFYb0Cvs.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-BG3DhGvM.js → EvidenceReceiptPanel-f7UV0iq8.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DNzidZZs.js → GitHubIssuesPanel-B9naEGop.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-B5NcUHit.js → GitHubPRsPanel-D_Sdx1xa.js} +1 -1
- package/web-app/dist/assets/{HomePage-CDojDo58.js → HomePage-fgOLpLKO.js} +2 -2
- package/web-app/dist/assets/{LoginPage-3BFNzUcW.js → LoginPage-5GbmfJoR.js} +1 -1
- package/web-app/dist/assets/{MagicPage-NY1Zawdf.js → MagicPage-CuBB-UdE.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-CfxGwjFC.js → MetricsPage-CcDxBoQB.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-i3_qnVi1.js → NotFoundPage-BRay4BL5.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-CqGmrK1T.js → ProjectPage-Du8YJlry.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C36P0Irr.js → ProjectsPage--psgDFsh.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-DTzb0uKT.js → SettingsPage-C4D9Jar9.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-CfY4ALt_.js → ShowcasePage-BHTTqg8U.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-CDjjQUIO.js → SystemSettingsPage-BPVW2bM6.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-DEvPeYoV.js → TeamsPage-D2XZA8JP.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-C2pvQh6p.js → TemplatesPage-BT5ReLll.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DSt6ijzO.js → TerminalOutput-CG-tEIma.js} +1 -1
- package/web-app/dist/assets/{activity-cQKc7Qz3.js → activity-D4VfYw_h.js} +1 -1
- package/web-app/dist/assets/{bell-DvuiCdXA.js → bell-AnG3l9wT.js} +1 -1
- package/web-app/dist/assets/{bot-xQfFCnf-.js → bot-CxMiwdYy.js} +1 -1
- package/web-app/dist/assets/{check-0by_ASuL.js → check-BrO9f5gl.js} +1 -1
- package/web-app/dist/assets/{chevron-left-FwfCMqen.js → chevron-left-HpEtIo4e.js} +1 -1
- package/web-app/dist/assets/{circle-alert-1tiUDoUg.js → circle-alert-S__4Lj5Y.js} +1 -1
- package/web-app/dist/assets/{clock-DVN3Nu7G.js → clock-87ZkFFKd.js} +1 -1
- package/web-app/dist/assets/{cloud-hIv4Jsym.js → cloud-CaoiXqrq.js} +1 -1
- package/web-app/dist/assets/{code-xml-D-71nPRE.js → code-xml-Djv6HpN2.js} +1 -1
- package/web-app/dist/assets/{database-Da0-3m0h.js → database-QSkMsaL0.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-BXSYlXLl.js → dollar-sign-DsIbt7E9.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BoLea73g.js → file-code-corner-DQY_EKG0.js} +1 -1
- package/web-app/dist/assets/{file-plus-BW3QvU13.js → file-plus-CeFRVlCc.js} +1 -1
- package/web-app/dist/assets/{globe-B7VuWP4E.js → globe-CYIZDx5y.js} +1 -1
- package/web-app/dist/assets/{hammer-KlXonR5y.js → hammer-QPHdCfpp.js} +1 -1
- package/web-app/dist/assets/{index-UfHXAUkp.js → index-QoGQRWyx.js} +3 -3
- package/web-app/dist/assets/{layers-CiiwhXq6.js → layers-CtcDx8kr.js} +1 -1
- package/web-app/dist/assets/{loader-circle-Ddov0Hjc.js → loader-circle-CRP0ymla.js} +1 -1
- package/web-app/dist/assets/{lock-Bf_LkHux.js → lock-DC_-r7Nn.js} +1 -1
- package/web-app/dist/assets/{package-DaF0Dad-.js → package-C0utKSsc.js} +1 -1
- package/web-app/dist/assets/{plus-nPhC7bJ0.js → plus-DN-1ptdd.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-BDtpGNOs.js → refresh-cw-ClVo1weu.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-B3YXhasa.js → rotate-ccw-buy6n4Dj.js} +1 -1
- package/web-app/dist/assets/{scroll-text-CCf8dMB0.js → scroll-text-fNFIg342.js} +1 -1
- package/web-app/dist/assets/{server-BkKkvfJb.js → server-JcjFhb66.js} +1 -1
- package/web-app/dist/assets/{shield-alert-Bx-2t6AA.js → shield-alert-DGjhsZZQ.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-AjAA5tox.js → thumbs-up-Cu9bXhPK.js} +1 -1
- package/web-app/dist/assets/{trash-2-YSiRb9MG.js → trash-2-DQh5erCE.js} +1 -1
- package/web-app/dist/assets/{trending-down-dZxc5O7C.js → trending-down-DCQoOPWu.js} +1 -1
- package/web-app/dist/assets/{trending-up-Dl-LwOqo.js → trending-up-Dj30VoUY.js} +1 -1
- package/web-app/dist/assets/{upload-Csn6khaL.js → upload-f7HNT6Li.js} +1 -1
- package/web-app/dist/assets/{usePolling-qReatY5K.js → usePolling-T-0o6PGt.js} +1 -1
- package/web-app/dist/assets/{user-5eHbCeDU.js → user-9GLVvJkd.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/mcp/__init__.py
CHANGED
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.17.
|
|
4
|
+
"version": "11.17.83",
|
|
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": "
|
|
163
|
+
"gitHead": "1dfd5fe8d716d65d135b969c08e120091be0885f"
|
|
164
164
|
}
|
|
@@ -10002,6 +10002,18 @@ async function zeroOnBase(cands, baseDir, repoDir, run, note) {
|
|
|
10002
10002
|
}
|
|
10003
10003
|
return zero;
|
|
10004
10004
|
}
|
|
10005
|
+
function addedSymlinkNotes(rawDiff, planText) {
|
|
10006
|
+
const asks = (w) => [...(planText ?? "").matchAll(new RegExp(`\\b${w}s?\\b`, "gi"))].some((m) => !/\b(?:no|not|never|without|avoid|don'?t|cannot|can'?t)\b[^.\n]{0,40}$/i.test(planText.slice(Math.max(0, m.index - 45), m.index)));
|
|
10007
|
+
const out2 = [];
|
|
10008
|
+
for (let i = 0;i + 1 < rawDiff.length; i += 2) {
|
|
10009
|
+
const f = rawDiff[i].trim().split(" "), oldMode = f[0].replace(/^:/, ""), st = f[f.length - 1], p = rawDiff[i + 1];
|
|
10010
|
+
if (f[1] === "120000" && (st === "A" || st === "T" && oldMode !== "120000") && !asks("symlink"))
|
|
10011
|
+
out2.push(`symlink added by the change (a link can stand in for missing work; the plan did not ask for one): ${p}`);
|
|
10012
|
+
else if (f[1] === "160000" && (st === "A" || st === "T") && !asks("submodule"))
|
|
10013
|
+
out2.push(`submodule pointer added by the change (it can stand in for missing work; the plan did not ask for one): ${p}`);
|
|
10014
|
+
}
|
|
10015
|
+
return out2;
|
|
10016
|
+
}
|
|
10005
10017
|
var WALK_BOUND = 50000, REPO_LINK_FILE;
|
|
10006
10018
|
var init_base_guard = __esm(() => {
|
|
10007
10019
|
init_check_result();
|
|
@@ -15340,7 +15352,7 @@ ${x}` : c.cmd };
|
|
|
15340
15352
|
|
|
15341
15353
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
15342
15354
|
import { existsSync as existsSync39, readdirSync as readdirSync20, readFileSync as readFileSync46 } from "fs";
|
|
15343
|
-
import { dirname as dirname23, join as join59 } from "path";
|
|
15355
|
+
import { basename as basename23, dirname as dirname23, isAbsolute as isAbsolute10, join as join59, relative as relative10, resolve as resolve17 } from "path";
|
|
15344
15356
|
function parseJsonc(text2) {
|
|
15345
15357
|
let out2 = "", i = 0;
|
|
15346
15358
|
while (i < text2.length) {
|
|
@@ -15428,6 +15440,149 @@ function outOfRepoTarget(content) {
|
|
|
15428
15440
|
}
|
|
15429
15441
|
return null;
|
|
15430
15442
|
}
|
|
15443
|
+
function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
15444
|
+
if (!/\.[cm]?[jt]sx?$/.test(fileName))
|
|
15445
|
+
return [];
|
|
15446
|
+
const code = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1").replace(/\(\s+/g, "(").replace(/\s+\)/g, ")").replace(/,\s*\n\s*/g, ", ").replace(/=\s*\n\s*/g, "= ");
|
|
15447
|
+
let pkg = testDir;
|
|
15448
|
+
while (pkg !== repoDir && pkg !== dirname23(pkg) && !MANIFESTS.some((m) => existsSync39(join59(pkg, m))))
|
|
15449
|
+
pkg = dirname23(pkg);
|
|
15450
|
+
const split2 = (s) => {
|
|
15451
|
+
const out2 = [];
|
|
15452
|
+
let d = 0, q = "", cur = "";
|
|
15453
|
+
for (let i = 0;i < s.length; i++) {
|
|
15454
|
+
const c = s[i];
|
|
15455
|
+
if (q) {
|
|
15456
|
+
cur += c;
|
|
15457
|
+
if (c === "\\")
|
|
15458
|
+
cur += s[++i] ?? "";
|
|
15459
|
+
else if (c === q)
|
|
15460
|
+
q = "";
|
|
15461
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
15462
|
+
q = c;
|
|
15463
|
+
cur += c;
|
|
15464
|
+
} else if ("([{".includes(c)) {
|
|
15465
|
+
d++;
|
|
15466
|
+
cur += c;
|
|
15467
|
+
} else if (")]}".includes(c)) {
|
|
15468
|
+
d--;
|
|
15469
|
+
cur += c;
|
|
15470
|
+
} else if (c === "," && d === 0) {
|
|
15471
|
+
out2.push(cur);
|
|
15472
|
+
cur = "";
|
|
15473
|
+
} else
|
|
15474
|
+
cur += c;
|
|
15475
|
+
}
|
|
15476
|
+
if (cur.trim())
|
|
15477
|
+
out2.push(cur);
|
|
15478
|
+
return out2;
|
|
15479
|
+
};
|
|
15480
|
+
const close = (line2, at) => {
|
|
15481
|
+
let d = 0;
|
|
15482
|
+
for (let j = at;j < line2.length; j++) {
|
|
15483
|
+
if (line2[j] === "(")
|
|
15484
|
+
d++;
|
|
15485
|
+
else if (line2[j] === ")" && --d === 0)
|
|
15486
|
+
return j;
|
|
15487
|
+
}
|
|
15488
|
+
return -1;
|
|
15489
|
+
};
|
|
15490
|
+
const scan = (cwd) => {
|
|
15491
|
+
const vars = new Map, reports = new Map, created = [];
|
|
15492
|
+
let ln = 0;
|
|
15493
|
+
const ev = (raw2, report) => {
|
|
15494
|
+
const e = raw2.trim().replace(/^await\s+/, "").replace(/\s+as\s+\w+$/, "").replace(/!$/, "");
|
|
15495
|
+
if (/^import\.meta\.(dir|dirname)$|^__dirname$/.test(e))
|
|
15496
|
+
return testDir;
|
|
15497
|
+
if (e === "process.cwd()")
|
|
15498
|
+
return cwd;
|
|
15499
|
+
const env = /^process\.env(?:\.[\w$]+|\[[^\]]+\])\s*(?:\?\?|\|\|)\s*([\s\S]+)$/.exec(e);
|
|
15500
|
+
if (env)
|
|
15501
|
+
return ev(env[1], report);
|
|
15502
|
+
if (e === "fileURLToPath(import.meta.url)" || e === "__filename")
|
|
15503
|
+
return join59(testDir, "__self__");
|
|
15504
|
+
const url = /^fileURLToPath\(new URL\((["'])([^"']*)\1\s*,\s*import\.meta\.url\)\)$/.exec(e);
|
|
15505
|
+
if (url)
|
|
15506
|
+
return resolve17(testDir, url[2]);
|
|
15507
|
+
const lit = /^(["'`])((?:\\.|(?!\1)[^\\])*)\1$/.exec(e);
|
|
15508
|
+
if (lit)
|
|
15509
|
+
return lit[2].includes("${") ? null : lit[2];
|
|
15510
|
+
if (/^[A-Za-z_$][\w$]*$/.test(e))
|
|
15511
|
+
return vars.get(e) ?? null;
|
|
15512
|
+
const call = /^(?:path\.)?(join|resolve|dirname)\(([\s\S]*)\)$/.exec(e);
|
|
15513
|
+
if (!call)
|
|
15514
|
+
return null;
|
|
15515
|
+
const parts = split2(call[2]), args = parts.map((a) => ev(a, report));
|
|
15516
|
+
if (args.some((a) => a === null))
|
|
15517
|
+
return null;
|
|
15518
|
+
if (call[1] === "dirname")
|
|
15519
|
+
return dirname23(args[0]);
|
|
15520
|
+
const out2 = resolve17(...args);
|
|
15521
|
+
if (report && relative10(testDir, out2).startsWith("..") && parts.some((a) => /^\s*["'`]/.test(a)))
|
|
15522
|
+
reports.set(`${ln}|${e}`, { out: out2, rel: relative10(repoDir, out2) });
|
|
15523
|
+
return out2;
|
|
15524
|
+
};
|
|
15525
|
+
for (const line2 of code.split(`
|
|
15526
|
+
`)) {
|
|
15527
|
+
ln++;
|
|
15528
|
+
for (const m of line2.matchAll(CREATORS)) {
|
|
15529
|
+
const j = close(line2, m.index + m[0].length - 1);
|
|
15530
|
+
if (j > 0)
|
|
15531
|
+
for (const a of split2(line2.slice(m.index + m[0].length, j))) {
|
|
15532
|
+
const v = ev(a, false);
|
|
15533
|
+
if (v)
|
|
15534
|
+
created.push(v);
|
|
15535
|
+
}
|
|
15536
|
+
}
|
|
15537
|
+
const skip = /^\s*(?:await\s+)?(?:expect|assert\w*)\b|\b(?:write\w*|mkdir\w*|rm\w*|cp\w*|copy\w*|rename\w*|symlink\w*|mkdtemp\w*|tmpdir|outputFile|touch)\b/.test(line2);
|
|
15538
|
+
const asg = /^\s*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*(?::[^=]+)?=\s*(.+?);?\s*$/.exec(line2);
|
|
15539
|
+
if (asg) {
|
|
15540
|
+
const v = ev(asg[2], !skip);
|
|
15541
|
+
if (v !== null)
|
|
15542
|
+
vars.set(asg[1], v);
|
|
15543
|
+
continue;
|
|
15544
|
+
}
|
|
15545
|
+
if (skip)
|
|
15546
|
+
continue;
|
|
15547
|
+
for (const m of line2.matchAll(/(?:path\.)?(?:join|resolve)\(/g)) {
|
|
15548
|
+
const j = close(line2, m.index + m[0].length - 1);
|
|
15549
|
+
if (j > 0)
|
|
15550
|
+
ev(line2.slice(m.index, j + 1), true);
|
|
15551
|
+
}
|
|
15552
|
+
}
|
|
15553
|
+
return { reports, created };
|
|
15554
|
+
};
|
|
15555
|
+
const runs2 = [...new Set([pkg, repoDir])].map(scan);
|
|
15556
|
+
const planned = (rel) => !!planText && rel.split("/").some((_, i, a) => {
|
|
15557
|
+
const pre = a.slice(0, i + 1).join("/");
|
|
15558
|
+
return (i > 0 || a.length === 1) && !existsSync39(join59(repoDir, pre)) && new RegExp(`(?<![\\w-])${pre.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(planText);
|
|
15559
|
+
});
|
|
15560
|
+
const phantom = (r, created) => {
|
|
15561
|
+
const rel = r.rel;
|
|
15562
|
+
if (!rel || rel.startsWith("..") || isAbsolute10(rel) || /(^|\/)(node_modules|\.git|\.loki|dist|build|coverage|tmp)(\/|$)/.test(rel) || existsSync39(r.out) || planned(rel))
|
|
15563
|
+
return false;
|
|
15564
|
+
if (created.some((c) => c === r.out || c.startsWith(r.out + "/") || r.out.startsWith(c + "/")))
|
|
15565
|
+
return false;
|
|
15566
|
+
return safeGitSpawn(repoDir, ["check-ignore", "-q", "--", rel], { timeout: 5000 }).status !== 0;
|
|
15567
|
+
};
|
|
15568
|
+
const missing = [];
|
|
15569
|
+
for (const [k, r] of runs2[0].reports)
|
|
15570
|
+
if (runs2.every((x) => x.reports.has(k) && phantom(x.reports.get(k), x.created)) && !missing.includes(r.rel))
|
|
15571
|
+
missing.push(r.rel);
|
|
15572
|
+
return missing.slice(0, 3);
|
|
15573
|
+
}
|
|
15574
|
+
function phantomReason(miss, repoFiles) {
|
|
15575
|
+
if (miss.length === 0)
|
|
15576
|
+
return null;
|
|
15577
|
+
const hint = (m) => {
|
|
15578
|
+
const n2 = basename23(m), near = [...new Set(repoFiles.flatMap((f) => {
|
|
15579
|
+
const s = f.split("/"), k = s.indexOf(n2);
|
|
15580
|
+
return k >= 0 && s.slice(0, k + 1).join("/") !== m ? [s.slice(0, k + 1).join("/")] : [];
|
|
15581
|
+
}))].slice(0, 3);
|
|
15582
|
+
return near.length ? `${m} (a path named ${n2} exists at ${near.join(", ")})` : m;
|
|
15583
|
+
};
|
|
15584
|
+
return `references repo path(s) that do not exist in the repository and that the plan does not create: ${miss.map(hint).join("; ")}. Locate the real code by searching the repository; do not copy a name from the task text as a path`;
|
|
15585
|
+
}
|
|
15431
15586
|
var readJson5 = (p) => {
|
|
15432
15587
|
try {
|
|
15433
15588
|
const v = parseJsonc(readFileSync46(p, "utf8"));
|
|
@@ -15435,14 +15590,18 @@ var readJson5 = (p) => {
|
|
|
15435
15590
|
} catch {
|
|
15436
15591
|
return null;
|
|
15437
15592
|
}
|
|
15438
|
-
};
|
|
15439
|
-
var init_conventions = () => {
|
|
15593
|
+
}, MANIFESTS, CREATORS;
|
|
15594
|
+
var init_conventions = __esm(() => {
|
|
15595
|
+
init_safe_git();
|
|
15596
|
+
MANIFESTS = ["package.json", "pyproject.toml", "go.mod", "Cargo.toml"];
|
|
15597
|
+
CREATORS = /\b(?:mkdirSync|writeFileSync|appendFileSync|cpSync|copyFileSync|renameSync|symlinkSync|mkdir|writeFile|appendFile|cp|copyFile|rename|outputFile|ensureDir|mkdirp)\(/g;
|
|
15598
|
+
});
|
|
15440
15599
|
|
|
15441
15600
|
// ../../loki-ts/src/engine10/stages/wall.ts
|
|
15442
15601
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
15443
15602
|
import { existsSync as existsSync40, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync11, readFileSync as readFileSync47, readdirSync as readdirSync21, rmSync as rmSync19, writeFileSync as writeFileSync28 } from "fs";
|
|
15444
15603
|
import { tmpdir as tmpdir12 } from "os";
|
|
15445
|
-
import { dirname as dirname24, join as join60, relative as
|
|
15604
|
+
import { dirname as dirname24, join as join60, relative as relative11 } from "path";
|
|
15446
15605
|
|
|
15447
15606
|
class RealBaseTestRunner {
|
|
15448
15607
|
api;
|
|
@@ -15553,7 +15712,7 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
15553
15712
|
return done({ status: "skipped", data: { size: sz.size, files: [], no_interpreter: true, not_proven: ["Wall skipped: no project test interpreter"] }, reason: "Wall skipped: no project test interpreter" });
|
|
15554
15713
|
const tree = prior.intake?.tree;
|
|
15555
15714
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
15556
|
-
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${
|
|
15715
|
+
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative11(ctx.repoDir, targetDir)}/x`);
|
|
15557
15716
|
const conv2 = readPackageConventions(join60(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
15558
15717
|
const cwd = mkdtempSync11(join60(tmpdir12(), "loki-e15-wall-"));
|
|
15559
15718
|
const wm = wallManifestFor(ctx.repoDir, tree, task);
|
|
@@ -15574,8 +15733,9 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
15574
15733
|
rmSync19(cwd, { recursive: true, force: true });
|
|
15575
15734
|
return done({ status: "failed", data: { iteration_ids: [iterationId], model }, reason: "wall session aborted, killed, or timed out", killed: true });
|
|
15576
15735
|
}
|
|
15736
|
+
const planText = typeof prior.plan?.plan === "string" ? prior.plan.plan : null, repoFiles = repoMap?.files ?? [];
|
|
15577
15737
|
const oor = () => readdirSync21(cwd).filter((f) => f.startsWith(WALL_PREFIX)).flatMap((name) => {
|
|
15578
|
-
const
|
|
15738
|
+
const text2 = readFileSync47(join60(cwd, name), "utf8"), why = outOfRepoTarget(text2) ?? phantomReason(phantomRepoPaths(text2, name, targetDir, ctx.repoDir, planText), repoFiles);
|
|
15579
15739
|
return why ? [{ name, why }] : [];
|
|
15580
15740
|
});
|
|
15581
15741
|
const bad1 = oor();
|
|
@@ -15627,7 +15787,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
15627
15787
|
sealedFiles.push({ path: dest, sha256: sha2562(content) });
|
|
15628
15788
|
readOnlyFiles.push({ path: dest, content });
|
|
15629
15789
|
if (runner)
|
|
15630
|
-
wallTests.push({ runner, path:
|
|
15790
|
+
wallTests.push({ runner, path: relative11(ctx.repoDir, dest) });
|
|
15631
15791
|
}
|
|
15632
15792
|
ctx.wallSealed = true;
|
|
15633
15793
|
ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
|
|
@@ -15712,9 +15872,9 @@ var init_wall = __esm(() => {
|
|
|
15712
15872
|
|
|
15713
15873
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
15714
15874
|
import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync15, mkdirSync as mkdirSync26, openSync as openSync9, readFileSync as readFileSync48, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync7, writeFileSync as writeFileSync29 } from "fs";
|
|
15715
|
-
import { dirname as dirname25, join as join61, relative as
|
|
15875
|
+
import { dirname as dirname25, join as join61, relative as relative12, sep as sep14 } from "path";
|
|
15716
15876
|
function safeRestore(repoDir, f, want, mode) {
|
|
15717
|
-
const root = realpathSync23(repoDir), fp = join61(root, f), rel =
|
|
15877
|
+
const root = realpathSync23(repoDir), fp = join61(root, f), rel = relative12(root, dirname25(fp));
|
|
15718
15878
|
if (rel.startsWith(".."))
|
|
15719
15879
|
throw new Error("outside repo");
|
|
15720
15880
|
let cur = root;
|
|
@@ -15839,7 +15999,7 @@ var init_commit_filter = __esm(() => {
|
|
|
15839
15999
|
});
|
|
15840
16000
|
|
|
15841
16001
|
// ../../loki-ts/src/e10ext/scope.ts
|
|
15842
|
-
import { basename as
|
|
16002
|
+
import { basename as basename24, dirname as dirname27 } from "path";
|
|
15843
16003
|
function contractText(o) {
|
|
15844
16004
|
const c = o.intake?.contract_snapshot?.contract;
|
|
15845
16005
|
return Array.isArray(c?.criteria) ? c.criteria.map((x) => typeof x?.text === "string" ? x.text : "").join(`
|
|
@@ -15854,7 +16014,7 @@ function outsideScope(o, staged) {
|
|
|
15854
16014
|
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
15855
16015
|
${contractText(o)}`, pre = o.intake?.preexisting_dirty ?? {};
|
|
15856
16016
|
const toks = surfaceTokens(text2), plannedDirs = new Set(rel.map((r) => dirname27(r)).filter((d) => d !== "."));
|
|
15857
|
-
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2,
|
|
16017
|
+
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename24(f)) && !plannedDirs.has(dirname27(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
|
|
15858
16018
|
}
|
|
15859
16019
|
function flagOutsideScope(o, staged) {
|
|
15860
16020
|
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
@@ -16481,7 +16641,7 @@ var init_seal_group = __esm(() => {
|
|
|
16481
16641
|
|
|
16482
16642
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
16483
16643
|
import { existsSync as existsSync46, readFileSync as readFileSync54, statSync as statSync22 } from "fs";
|
|
16484
|
-
import { basename as
|
|
16644
|
+
import { basename as basename25, join as join68 } from "path";
|
|
16485
16645
|
function supplyEnabled(env) {
|
|
16486
16646
|
return env["LOKI_SUPPLY_GUARD"] !== "0";
|
|
16487
16647
|
}
|
|
@@ -16493,7 +16653,7 @@ function supplyVerdict(verdict, r) {
|
|
|
16493
16653
|
return r.blocked && verdict === "VERIFIED" ? "FAILED" : verdict;
|
|
16494
16654
|
}
|
|
16495
16655
|
function isManifestPath(path) {
|
|
16496
|
-
return
|
|
16656
|
+
return MANIFESTS2.test(basename25(path));
|
|
16497
16657
|
}
|
|
16498
16658
|
function readDeclared(repoDir) {
|
|
16499
16659
|
const p = join68(repoDir, ".loki", DECLARED_FILE);
|
|
@@ -16691,7 +16851,7 @@ async function supplyGuard(repoDir, changedFiles2, declared, env, opts = {}) {
|
|
|
16691
16851
|
}
|
|
16692
16852
|
return { block: { guard: "v2", warn_age_days: MIN_AGE_DAYS, fail_age_days: failAge, declared: declared.deps.length, entries }, notProven, blocked };
|
|
16693
16853
|
}
|
|
16694
|
-
var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50, MAX_DECLARED = 200, MAX_FILE_BYTES, DAY_MS = 86400000,
|
|
16854
|
+
var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50, MAX_DECLARED = 200, MAX_FILE_BYTES, DAY_MS = 86400000, MANIFESTS2, ECO, NAME2, defaultResolver = async (dep, cwd) => {
|
|
16695
16855
|
const argv = {
|
|
16696
16856
|
npm: ["npm", "view", dep.name, "time.created", "--json"],
|
|
16697
16857
|
pypi: ["pip", "index", "versions", "--pre", "--ignore-requires-python", dep.name],
|
|
@@ -16717,7 +16877,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
|
|
|
16717
16877
|
var init_supply_guard = __esm(() => {
|
|
16718
16878
|
init_shell();
|
|
16719
16879
|
MAX_FILE_BYTES = 64 * 1024;
|
|
16720
|
-
|
|
16880
|
+
MANIFESTS2 = /^(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb?|requirements.*\.txt|pyproject\.toml|poetry\.lock|uv\.lock|Pipfile|Pipfile\.lock|go\.mod|go\.sum|Cargo\.toml|Cargo\.lock|Gemfile|Gemfile\.lock|composer\.json|composer\.lock|pom\.xml|build\.gradle(\.kts)?)$/;
|
|
16721
16881
|
ECO = { npm: "npm", node: "npm", pypi: "pypi", pip: "pypi", python: "pypi", cargo: "cargo", crates: "cargo", go: "go", golang: "go" };
|
|
16722
16882
|
NAME2 = /^[A-Za-z0-9@][A-Za-z0-9@._/~+-]{0,213}$/;
|
|
16723
16883
|
PUBLIC_HOSTS = new Set(["registry.npmjs.org", "registry.npmjs.com", "registry.yarnpkg.com", "npmjs.com", "npmjs.org", "pypi.org", "pypi.python.org", "files.pythonhosted.org", "crates.io", "index.crates.io", "static.crates.io", "proxy.golang.org", "golang.org", "pkg.go.dev"]);
|
|
@@ -16726,7 +16886,7 @@ var init_supply_guard = __esm(() => {
|
|
|
16726
16886
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
16727
16887
|
import { createHash as createHash18 } from "crypto";
|
|
16728
16888
|
import { existsSync as existsSync47, readdirSync as readdirSync24, mkdirSync as mkdirSync31, readFileSync as readFileSync55 } from "fs";
|
|
16729
|
-
import { basename as
|
|
16889
|
+
import { basename as basename26, isAbsolute as isAbsolute12, join as join69, relative as relative13 } from "path";
|
|
16730
16890
|
function receiptSha256(r) {
|
|
16731
16891
|
const { verification: _v, receipt_sha256: _h, ...body } = r;
|
|
16732
16892
|
return sha2562(canonicalJson(body));
|
|
@@ -16798,8 +16958,8 @@ function renderReceiptMd(r) {
|
|
|
16798
16958
|
`);
|
|
16799
16959
|
}
|
|
16800
16960
|
var SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", WALL_GREEN_ON_BASE_REASON = "Wall green on base: no Wall test discriminates the change", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash18("sha256").update(s).digest("hex"), str4 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], receiptRel = (ctx) => {
|
|
16801
|
-
const r =
|
|
16802
|
-
return r.startsWith("..") ||
|
|
16961
|
+
const r = relative13(ctx.repoDir, join69(ctx.runDir, "receipt.json"));
|
|
16962
|
+
return r.startsWith("..") || isAbsolute12(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
16803
16963
|
}, commitStage, wallGreenOnBaseOf = (o) => {
|
|
16804
16964
|
const b = o.wall?.base_run ?? {};
|
|
16805
16965
|
return typeof b.pass === "number" && b.pass > 0 && b.fail === 0 && (typeof b.not_run === "number" ? b.not_run : 0) === 0;
|
|
@@ -16834,6 +16994,7 @@ var init_seal = __esm(() => {
|
|
|
16834
16994
|
init_hooks();
|
|
16835
16995
|
init_atomic();
|
|
16836
16996
|
init_safe_git();
|
|
16997
|
+
init_base_guard();
|
|
16837
16998
|
commitStage = {
|
|
16838
16999
|
name: "commit",
|
|
16839
17000
|
...STAGE_BUDGETS.commit,
|
|
@@ -16888,7 +17049,7 @@ var init_seal = __esm(() => {
|
|
|
16888
17049
|
for (let i = 0;i + 1 < rawDiff.length; i += 2)
|
|
16889
17050
|
if ((rawDiff[i].trim().split(" ").pop() ?? "") !== "A" && isTestFile(rawDiff[i + 1]))
|
|
16890
17051
|
weakTests.push(rawDiff[i + 1]);
|
|
16891
|
-
const rcNotes = diffOk ? runnerConfigNotes(ctx.repoDir, ctx.baseSha, head, rawDiff.filter((_, i) => i % 2 === 1), signal) : [];
|
|
17052
|
+
const rcNotes = diffOk ? [...runnerConfigNotes(ctx.repoDir, ctx.baseSha, head, rawDiff.filter((_, i) => i % 2 === 1), signal), ...addedSymlinkNotes(rawDiff, str4(o.plan?.plan))] : [];
|
|
16892
17053
|
const grp = sealGroup(ctx.runDir, receiptSha256);
|
|
16893
17054
|
const vraw = Array.isArray(o.verify?.checks) ? o.verify.checks : [], executed = hasExecutedProof(vraw), proof = process.env["LOKI_EXOGENOUS_PROOF"] === "0" ? executed : hasExogenousProof(vraw, pctx);
|
|
16894
17055
|
const uncoveredAfterLimit = o.implement?.exit === "killed" ? strs2(o.verify?.uncovered_changed) : [];
|
|
@@ -16917,7 +17078,7 @@ var init_seal = __esm(() => {
|
|
|
16917
17078
|
notProven.add(`Wall test not executed: ${wallNotRun} file(s), no reason recorded`);
|
|
16918
17079
|
if (wallNotRun > 0) {
|
|
16919
17080
|
try {
|
|
16920
|
-
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) =>
|
|
17081
|
+
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename26(String(f.path))));
|
|
16921
17082
|
for (const n3 of readdirSync24(join69(ctx.runDir, "wall")).sort())
|
|
16922
17083
|
if (!kept.has(n3))
|
|
16923
17084
|
notProven.add(`wall test discarded: ${n3} (not_run)`);
|
|
@@ -17093,7 +17254,7 @@ var init_seal = __esm(() => {
|
|
|
17093
17254
|
|
|
17094
17255
|
// ../../loki-ts/src/util/composite_seal.ts
|
|
17095
17256
|
import { existsSync as existsSync48, readFileSync as readFileSync56 } from "fs";
|
|
17096
|
-
import { basename as
|
|
17257
|
+
import { basename as basename27, dirname as dirname31, join as join70 } from "path";
|
|
17097
17258
|
function logProblem(runDir, integ) {
|
|
17098
17259
|
if (typeof integ["log_sha256"] !== "string")
|
|
17099
17260
|
return null;
|
|
@@ -17216,7 +17377,7 @@ var init_keys_cmd = __esm(() => {
|
|
|
17216
17377
|
|
|
17217
17378
|
// ../../loki-ts/src/engine10/verify_cmd.ts
|
|
17218
17379
|
import { existsSync as existsSync49, readFileSync as readFileSync57, renameSync as renameSync14, statSync as statSync24, writeFileSync as writeFileSync33 } from "fs";
|
|
17219
|
-
import { basename as
|
|
17380
|
+
import { basename as basename28, dirname as dirname32, join as join71 } from "path";
|
|
17220
17381
|
import { createHash as createHash19, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
|
|
17221
17382
|
function pubFor(kid, given) {
|
|
17222
17383
|
if (given)
|
|
@@ -17399,7 +17560,7 @@ var init_verify_cmd = __esm(() => {
|
|
|
17399
17560
|
|
|
17400
17561
|
// src/server/app.ts
|
|
17401
17562
|
import { existsSync as existsSync51, readFileSync as readFileSync60, statSync as statSync25 } from "fs";
|
|
17402
|
-
import { join as join74, resolve as
|
|
17563
|
+
import { join as join74, resolve as resolve18, sep as sep16 } from "path";
|
|
17403
17564
|
|
|
17404
17565
|
// node_modules/hono/dist/request/constants.js
|
|
17405
17566
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -28490,8 +28651,8 @@ function createApp(opts) {
|
|
|
28490
28651
|
}
|
|
28491
28652
|
if (!uiDir || p.startsWith("/v1/"))
|
|
28492
28653
|
return c.json({ error: "not found" }, 404);
|
|
28493
|
-
const root =
|
|
28494
|
-
const f =
|
|
28654
|
+
const root = resolve18(uiDir);
|
|
28655
|
+
const f = resolve18(root, `.${p}`);
|
|
28495
28656
|
if (f.startsWith(root + sep16) && existsSync51(f) && statSync25(f).isFile())
|
|
28496
28657
|
return new Response(Bun.file(f));
|
|
28497
28658
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
@@ -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.17.
|
|
5
|
+
"version": "11.17.83",
|
|
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-
|
|
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-QoGQRWyx.js";import{B as C}from"./Button-Cmt4rAI6.js";import{T as $e}from"./trending-up-Dj30VoUY.js";import{C as z}from"./clock-87ZkFFKd.js";import{A as Be,U as ue,M as De}from"./Avatar-ByHPLzy-.js";import{A as J}from"./activity-D4VfYw_h.js";import{R as pe}from"./refresh-cw-ClVo1weu.js";import{G as ze}from"./globe-CYIZDx5y.js";import{C as Le}from"./chevron-left-HpEtIo4e.js";import{C as je}from"./check-BrO9f5gl.js";import{D as Y}from"./dollar-sign-DsIbt7E9.js";import{U as Te}from"./user-9GLVvJkd.js";import{D as Me}from"./database-QSkMsaL0.js";import{L as Ue}from"./lock-DC_-r7Nn.js";import{S as Re}from"./scroll-text-fNFIg342.js";import{S as Ie}from"./shield-alert-DGjhsZZQ.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-
|
|
1
|
+
import{j as e}from"./index-QoGQRWyx.js";import{C as r}from"./clock-87ZkFFKd.js";import{C as a}from"./circle-alert-S__4Lj5Y.js";import{C as l}from"./check-BrO9f5gl.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-
|
|
1
|
+
import{r as p,j as t}from"./index-QoGQRWyx.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-
|
|
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-QoGQRWyx.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-CFYb0Cvs.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-Cu9bXhPK.js";import{C as oe}from"./check-BrO9f5gl.js";import{C as Ye}from"./clock-87ZkFFKd.js";import{D as Xe}from"./dollar-sign-DsIbt7E9.js";import{U as Ze}from"./upload-f7HNT6Li.js";import{L as V}from"./loader-circle-CRP0ymla.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{r as o,j as e}from"./index-UfHXAUkp.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
|
|
1
|
+
import{r as o,j as e}from"./index-QoGQRWyx.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
|
package/web-app/dist/assets/{EvidenceReceiptPanel-BG3DhGvM.js → EvidenceReceiptPanel-f7UV0iq8.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as l,a as x,j as e}from"./index-
|
|
1
|
+
import{r as l,a as x,j as e}from"./index-QoGQRWyx.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-
|
|
1
|
+
import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-QoGQRWyx.js";import{B as N}from"./Button-Cmt4rAI6.js";import{C as y}from"./thumbs-up-Cu9bXhPK.js";import{R as S}from"./refresh-cw-ClVo1weu.js";import{C as z}from"./circle-alert-S__4Lj5Y.js";import{U as D}from"./user-9GLVvJkd.js";import{L as G}from"./loader-circle-CRP0ymla.js";import{R as T}from"./rotate-ccw-buy6n4Dj.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 I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-
|
|
1
|
+
import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-QoGQRWyx.js";import{B as y}from"./Button-Cmt4rAI6.js";import{C as ge}from"./chevron-left-HpEtIo4e.js";import{G as P}from"./thumbs-up-Cu9bXhPK.js";import{R as $}from"./refresh-cw-ClVo1weu.js";import{C as Ne}from"./circle-alert-S__4Lj5Y.js";import{L as Q,S as je}from"./ProjectPage-Du8YJlry.js";import{S as se}from"./shield-alert-DGjhsZZQ.js";import{F as ye}from"./file-code-corner-DQY_EKG0.js";import{C as V}from"./clock-87ZkFFKd.js";import{C as re}from"./check-BrO9f5gl.js";import"./ErrorBoundary-CFYb0Cvs.js";import"./TerminalOutput-CG-tEIma.js";import"./lock-DC_-r7Nn.js";import"./package-C0utKSsc.js";import"./file-plus-CeFRVlCc.js";import"./activity-D4VfYw_h.js";import"./scroll-text-fNFIg342.js";import"./bot-CxMiwdYy.js";import"./loader-circle-CRP0ymla.js";import"./hammer-QPHdCfpp.js";import"./dollar-sign-DsIbt7E9.js";import"./globe-CYIZDx5y.js";import"./trash-2-DQh5erCE.js";import"./upload-f7HNT6Li.js";import"./plus-DN-1ptdd.js";import"./rotate-ccw-buy6n4Dj.js";import"./code-xml-Djv6HpN2.js";import"./trending-up-Dj30VoUY.js";import"./layers-CtcDx8kr.js";import"./trending-down-DCQoOPWu.js";import"./server-JcjFhb66.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|