loki-mode 11.17.40 → 11.17.41
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/autonomy/lib/secure-scan.py +48 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +9 -9
- package/docs/v10/FAILURE-CLASSES.md +7 -0
- package/docs/v10/PROGRESS.md +3 -0
- package/loki-ts/dist/loki.js +1169 -1161
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +85 -36
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-DgI8B2Aw.js → AdminPage-BSR_64u1.js} +1 -1
- package/web-app/dist/assets/{Avatar-B_8yy8iY.js → Avatar-CnSNZSx6.js} +1 -1
- package/web-app/dist/assets/{Badge-CldU-vT_.js → Badge-C7p_bqIO.js} +1 -1
- package/web-app/dist/assets/{Button-BpQvTqIa.js → Button-5CI0TYxR.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-t3XC9izG.js → CockpitPage-CeiR5rfl.js} +1 -1
- package/web-app/dist/assets/{ComparePage-CHtGYEWI.js → ComparePage-Cwh3wcqg.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-ChO4RY3O.js → ErrorBoundary-VZcsEDJl.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DOrDxj2L.js → EvidenceReceiptPanel-Cf5DXTqo.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DEpNXTp_.js → GitHubIssuesPanel-C8pxgZhD.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-Bb3uLQbx.js → GitHubPRsPanel-Dfrm9QTz.js} +1 -1
- package/web-app/dist/assets/{HomePage-_-_Rk_C5.js → HomePage-Be-Hq5wb.js} +2 -2
- package/web-app/dist/assets/{LoginPage-BQ2k_mIH.js → LoginPage-DijL2orB.js} +1 -1
- package/web-app/dist/assets/{MagicPage-BEt2Y-hw.js → MagicPage-x-KpX3Zk.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-B5tQU5QT.js → MetricsPage-uoMG8P0x.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-CCL_Ubl7.js → NotFoundPage-DmW2a7pG.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-azR0ZXjf.js → ProjectPage-zpARxbll.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-rCLcH5bP.js → ProjectsPage-5dTAn3K7.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CKYC6E1u.js → SettingsPage-ptKy_Tbu.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-D1XPEQII.js → ShowcasePage-BkM5b-6b.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-BQkC6pPn.js → SystemSettingsPage-BbaZ8aqC.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-Cqr9g4dU.js → TeamsPage-CBgDSDWj.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-Cw_2IQ4v.js → TemplatesPage-IdBOifb1.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-BZGkuuBg.js → TerminalOutput-iLcaELwj.js} +1 -1
- package/web-app/dist/assets/{activity-CA-Uv87R.js → activity-Di09VZ-C.js} +1 -1
- package/web-app/dist/assets/{bell-BKUeJsc9.js → bell-CuHhohwY.js} +1 -1
- package/web-app/dist/assets/{bot-DQV5dtCP.js → bot-pGvyFisf.js} +1 -1
- package/web-app/dist/assets/{check-BAOpMn0h.js → check-DYPycZns.js} +1 -1
- package/web-app/dist/assets/{chevron-left-N282XJLx.js → chevron-left-lKRP1pKT.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DM1r83A3.js → circle-alert-D1rDQ9mD.js} +1 -1
- package/web-app/dist/assets/{clock-C-mYgAEh.js → clock-BGhPbAAa.js} +1 -1
- package/web-app/dist/assets/{cloud-YP7y_t17.js → cloud-WsT8-0Fu.js} +1 -1
- package/web-app/dist/assets/{code-xml-hdfcpa45.js → code-xml-DtutBX9b.js} +1 -1
- package/web-app/dist/assets/{database-Cnw7XVsm.js → database-LiEeNmyC.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-C5JkuNww.js → dollar-sign-adGlfVLa.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-CBmlYvL-.js → file-code-corner-DY5GkQGM.js} +1 -1
- package/web-app/dist/assets/{file-plus-DeUBJXx_.js → file-plus-RLd_hPU8.js} +1 -1
- package/web-app/dist/assets/{globe-oyhkB-N3.js → globe-CQvcGE8E.js} +1 -1
- package/web-app/dist/assets/{hammer-CtSvH7U4.js → hammer-BWOWu2Hf.js} +1 -1
- package/web-app/dist/assets/{index-BLc2yb4N.js → index-BBV2psih.js} +3 -3
- package/web-app/dist/assets/{layers-CDQYDQ6K.js → layers-C_cj_ShX.js} +1 -1
- package/web-app/dist/assets/{loader-circle-BtP3HE6o.js → loader-circle-BpyfPEFt.js} +1 -1
- package/web-app/dist/assets/{lock-td8sv77w.js → lock-Bivqy2kG.js} +1 -1
- package/web-app/dist/assets/{package-trunnqYD.js → package-DvDJIgWs.js} +1 -1
- package/web-app/dist/assets/{plus-fuJ7BLsH.js → plus-CVjTmPiU.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CWSAQRMi.js → refresh-cw-DPEeU-0s.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-lDG-5zfN.js → rotate-ccw-DZX_aED8.js} +1 -1
- package/web-app/dist/assets/{scroll-text-gNonKSJc.js → scroll-text-BBMfK4J7.js} +1 -1
- package/web-app/dist/assets/{server-B_i2HlpV.js → server-Bq18pHWE.js} +1 -1
- package/web-app/dist/assets/{shield-alert-4VXBQxgY.js → shield-alert-Dc5xbnOx.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-Dep29ImG.js → thumbs-up-4nFvjqQ-.js} +1 -1
- package/web-app/dist/assets/{trash-2-kEwKjXBG.js → trash-2-SjUKL3ek.js} +1 -1
- package/web-app/dist/assets/{trending-down-BGlFS9Sf.js → trending-down-B7_1Kuct.js} +1 -1
- package/web-app/dist/assets/{trending-up-eORQxMOu.js → trending-up-DgRWrCNb.js} +1 -1
- package/web-app/dist/assets/{upload-SPvyhOMU.js → upload-Cs07lSfb.js} +1 -1
- package/web-app/dist/assets/{usePolling-CDfhS2YL.js → usePolling-BAUxt1Nu.js} +1 -1
- package/web-app/dist/assets/{user-BmyaIilH.js → user-DC2T8RYB.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.41",
|
|
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",
|
|
@@ -158,5 +158,5 @@
|
|
|
158
158
|
"dependencies": {
|
|
159
159
|
"@resvg/resvg-wasm": "^2.6.2"
|
|
160
160
|
},
|
|
161
|
-
"gitHead": "
|
|
161
|
+
"gitHead": "511115313f825b09e87a9e4b5ff198b703b8f9de"
|
|
162
162
|
}
|
|
@@ -135,7 +135,7 @@ var init_events = __esm(() => {
|
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
// ../../loki-ts/src/util/redact.ts
|
|
138
|
-
var RULES, redactSecrets = (s) => RULES.reduce((a, [re, to]) => a.replace(re, to), s);
|
|
138
|
+
var RULES, QUERY_SEGMENT, SECRET_PARAM, redactQuery = (s) => s.replace(QUERY_SEGMENT, (q) => q.replace(SECRET_PARAM, "$1[REDACTED]")), redactSecrets = (s) => redactQuery(RULES.reduce((a, [re, to]) => a.replace(re, to), s));
|
|
139
139
|
var init_redact = __esm(() => {
|
|
140
140
|
RULES = [
|
|
141
141
|
[/sk-ant-[A-Za-z0-9_-]{20,}/g, "[REDACTED:ANTHROPIC_KEY]"],
|
|
@@ -155,6 +155,8 @@ var init_redact = __esm(() => {
|
|
|
155
155
|
[/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/?#@]+@/gi, "$1[REDACTED]@"],
|
|
156
156
|
[/(\bAuthorization\s*[:=]\s*)(?:Basic|Bearer|Token|Digest)?\s*[^\s,;"']+/gi, "$1[REDACTED]"]
|
|
157
157
|
];
|
|
158
|
+
QUERY_SEGMENT = /\?[^\s#"'<>]+/g;
|
|
159
|
+
SECRET_PARAM = /([?&](?:access_token|token|api_key|apikey|password|secret|sig)=)[^&\s#"']*/gi;
|
|
158
160
|
});
|
|
159
161
|
|
|
160
162
|
// ../../loki-ts/src/util/credential_env.ts
|
|
@@ -10363,8 +10365,45 @@ var init_state = __esm(() => {
|
|
|
10363
10365
|
});
|
|
10364
10366
|
|
|
10365
10367
|
// ../../loki-ts/src/runner/repo_profile.ts
|
|
10366
|
-
import {
|
|
10368
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
10369
|
+
import { existsSync as existsSync24, lstatSync as lstatSync9, readFileSync as readFileSync30, mkdirSync as mkdirSync14, readdirSync as readdirSync14, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
|
|
10367
10370
|
import { basename as basename12, join as join39, resolve as resolve13, isAbsolute as isAbsolute4 } from "path";
|
|
10371
|
+
function detectFormatters(repoDir) {
|
|
10372
|
+
const out2 = [];
|
|
10373
|
+
const has = (...fs2) => fs2.some((f) => existsSync24(join39(repoDir, f)));
|
|
10374
|
+
const pp = read(join39(repoDir, "pyproject.toml")), pj = read(join39(repoDir, "package.json"));
|
|
10375
|
+
if (/\[tool\.ruff/.test(pp) || has("ruff.toml", ".ruff.toml"))
|
|
10376
|
+
out2.push({ tool: "ruff", argv: ["ruff", "format"], exts: /\.pyi?$/ });
|
|
10377
|
+
let prettierKey = false;
|
|
10378
|
+
try {
|
|
10379
|
+
prettierKey = pj !== "" && "prettier" in JSON.parse(pj);
|
|
10380
|
+
} catch {}
|
|
10381
|
+
const local = join39(repoDir, "node_modules", ".bin", "prettier");
|
|
10382
|
+
if ((prettierKey || readdirSync14(repoDir).some((f) => /^(\.prettierrc(\.[a-z0-9]+)?|prettier\.config\.[cm]?[jt]s)$/.test(f))) && existsSync24(local))
|
|
10383
|
+
out2.push({ tool: "prettier", argv: [local, "--write"], exts: /\.(?:[cm]?[jt]sx?|json|css|scss|md|ya?ml|html)$/ });
|
|
10384
|
+
if (has("go.mod"))
|
|
10385
|
+
out2.push({ tool: "gofmt", argv: ["gofmt", "-w"], exts: /\.go$/ });
|
|
10386
|
+
if (has("rustfmt.toml", ".rustfmt.toml")) {
|
|
10387
|
+
const ed = /^\s*edition\s*=\s*"(\d+)"/m.exec(read(join39(repoDir, "Cargo.toml")))?.[1];
|
|
10388
|
+
out2.push({ tool: "rustfmt", argv: ["rustfmt", ...ed ? ["--edition", ed] : []], exts: /\.rs$/ });
|
|
10389
|
+
}
|
|
10390
|
+
return out2;
|
|
10391
|
+
}
|
|
10392
|
+
function runFormatters(repoDir, files, env) {
|
|
10393
|
+
const fmts = detectFormatters(repoDir);
|
|
10394
|
+
const mine = fmts.length ? files.filter((f) => {
|
|
10395
|
+
try {
|
|
10396
|
+
return lstatSync9(join39(repoDir, f)).isFile();
|
|
10397
|
+
} catch {
|
|
10398
|
+
return false;
|
|
10399
|
+
}
|
|
10400
|
+
}) : [];
|
|
10401
|
+
return fmts.flatMap((fm) => {
|
|
10402
|
+
const own = mine.filter((f) => fm.exts.test(f));
|
|
10403
|
+
const r = own.length ? spawnSync2(fm.argv[0], [...fm.argv.slice(1), ...own.map((f) => `./${f}`)], { cwd: repoDir, env, stdio: "ignore", timeout: 30000 }) : null;
|
|
10404
|
+
return r && !r.error && r.status === 0 ? own : [];
|
|
10405
|
+
});
|
|
10406
|
+
}
|
|
10368
10407
|
function loadProfile(repoDir) {
|
|
10369
10408
|
try {
|
|
10370
10409
|
const p = JSON.parse(readFileSync30(commandProfilePath(repoDir), "utf8"));
|
|
@@ -10458,7 +10497,13 @@ async function staticPreExisting(tool, prefix, files, io) {
|
|
|
10458
10497
|
}
|
|
10459
10498
|
return attributeStatic(tool, head.out, baseOut, 1).preExisting;
|
|
10460
10499
|
}
|
|
10461
|
-
var commandProfilePath = (repoDir) => join39(repoDir, ".loki", "state", "repo-profile.json"),
|
|
10500
|
+
var commandProfilePath = (repoDir) => join39(repoDir, ".loki", "state", "repo-profile.json"), read = (p) => {
|
|
10501
|
+
try {
|
|
10502
|
+
return readFileSync30(p, "utf8");
|
|
10503
|
+
} catch {
|
|
10504
|
+
return "";
|
|
10505
|
+
}
|
|
10506
|
+
}, STATIC_DIAG, STATIC_NOISE, STATIC_SUMMARY;
|
|
10462
10507
|
var init_repo_profile = __esm(() => {
|
|
10463
10508
|
init_failures();
|
|
10464
10509
|
init_check_result();
|
|
@@ -10500,7 +10545,7 @@ var init_context = __esm(() => {
|
|
|
10500
10545
|
});
|
|
10501
10546
|
|
|
10502
10547
|
// ../../loki-ts/src/util/steer.ts
|
|
10503
|
-
import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync15, lstatSync as
|
|
10548
|
+
import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync15, lstatSync as lstatSync10, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync31, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync25 } from "fs";
|
|
10504
10549
|
import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
|
|
10505
10550
|
import { basename as basename13, join as join40 } from "path";
|
|
10506
10551
|
function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
@@ -10527,7 +10572,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
|
10527
10572
|
}
|
|
10528
10573
|
}
|
|
10529
10574
|
function orphanAlreadyArchived(logs, claim) {
|
|
10530
|
-
const c =
|
|
10575
|
+
const c = lstatSync10(claim);
|
|
10531
10576
|
if (!c.isFile())
|
|
10532
10577
|
return false;
|
|
10533
10578
|
for (const a of readdirSync15(logs)) {
|
|
@@ -10629,7 +10674,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10629
10674
|
hooks2?.beforeRestore?.();
|
|
10630
10675
|
let restored = false;
|
|
10631
10676
|
try {
|
|
10632
|
-
if (
|
|
10677
|
+
if (lstatSync10(claimed).isDirectory())
|
|
10633
10678
|
renameSync10(claimed, f);
|
|
10634
10679
|
else
|
|
10635
10680
|
(hooks2?.link ?? linkSync2)(claimed, f);
|
|
@@ -10638,7 +10683,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10638
10683
|
if (!restored)
|
|
10639
10684
|
return reject("NOTFILE", "not a regular file");
|
|
10640
10685
|
try {
|
|
10641
|
-
if (!
|
|
10686
|
+
if (!lstatSync10(claimed, { throwIfNoEntry: false })?.isDirectory())
|
|
10642
10687
|
unlinkSync5(claimed);
|
|
10643
10688
|
} catch {}
|
|
10644
10689
|
claimed = "";
|
|
@@ -10648,7 +10693,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10648
10693
|
try {
|
|
10649
10694
|
fd = openSync8(claimed, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
|
|
10650
10695
|
} catch (e) {
|
|
10651
|
-
const l =
|
|
10696
|
+
const l = lstatSync10(claimed, { throwIfNoEntry: false });
|
|
10652
10697
|
if (!l)
|
|
10653
10698
|
throw e;
|
|
10654
10699
|
if (l.isSymbolicLink() || e.code === "ELOOP") {
|
|
@@ -10703,7 +10748,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10703
10748
|
}
|
|
10704
10749
|
} else
|
|
10705
10750
|
try {
|
|
10706
|
-
if (
|
|
10751
|
+
if (lstatSync10(f, { throwIfNoEntry: false }))
|
|
10707
10752
|
unapplied("logs dir unwritable or file unreadable");
|
|
10708
10753
|
} catch {}
|
|
10709
10754
|
return null;
|
|
@@ -11053,7 +11098,7 @@ var init_shell = __esm(() => {
|
|
|
11053
11098
|
|
|
11054
11099
|
// ../../loki-ts/src/util/python.ts
|
|
11055
11100
|
import { accessSync, constants as constants3, existsSync as existsSync27, mkdtempSync as mkdtempSync4, readFileSync as readFileSync33, realpathSync as realpathSync18, rmSync as rmSync11, statSync as statSync16 } from "fs";
|
|
11056
|
-
import { spawnSync as
|
|
11101
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
11057
11102
|
import { tmpdir as tmpdir5 } from "os";
|
|
11058
11103
|
async function findPython3() {
|
|
11059
11104
|
if (_pythonCache !== undefined)
|
|
@@ -11090,7 +11135,7 @@ function pySignatures(src) {
|
|
|
11090
11135
|
const py = resolvePython3();
|
|
11091
11136
|
if (!py)
|
|
11092
11137
|
return [];
|
|
11093
|
-
const r =
|
|
11138
|
+
const r = spawnSync3(py, ["-I", "-S", "-c", PY_SCRIPT], {
|
|
11094
11139
|
input: src.replace(/\r\n?/g, `
|
|
11095
11140
|
`),
|
|
11096
11141
|
cwd: tmpdir5(),
|
|
@@ -12241,7 +12286,7 @@ var init_runner_errors = __esm(() => {
|
|
|
12241
12286
|
});
|
|
12242
12287
|
|
|
12243
12288
|
// ../../loki-ts/src/runner/load_owner.ts
|
|
12244
|
-
import { spawnSync as
|
|
12289
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
12245
12290
|
import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync19, rmSync as rmSync14 } from "fs";
|
|
12246
12291
|
import { tmpdir as tmpdir8 } from "os";
|
|
12247
12292
|
import { basename as basename18, extname as extname2, join as join46 } from "path";
|
|
@@ -12286,7 +12331,7 @@ function sameLoadError(head, base, headRoots, baseRoots) {
|
|
|
12286
12331
|
function killTree(pid) {
|
|
12287
12332
|
const all = [pid];
|
|
12288
12333
|
for (let k = 0;k < all.length; k++) {
|
|
12289
|
-
const kids =
|
|
12334
|
+
const kids = spawnSync4("pgrep", ["-P", String(all[k])], { encoding: "utf8", env: process.env }).stdout.split(/\s+/).filter(Boolean).map(Number);
|
|
12290
12335
|
all.push(...kids.filter((x) => Number.isInteger(x) && !all.includes(x)));
|
|
12291
12336
|
}
|
|
12292
12337
|
try {
|
|
@@ -12434,7 +12479,7 @@ var init_wall_owned = __esm(() => {
|
|
|
12434
12479
|
});
|
|
12435
12480
|
|
|
12436
12481
|
// ../../loki-ts/src/util/app_probe.ts
|
|
12437
|
-
import { spawnSync as
|
|
12482
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
12438
12483
|
import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync37, renameSync as renameSync11, writeFileSync as writeFileSync21 } from "fs";
|
|
12439
12484
|
import { join as join48 } from "path";
|
|
12440
12485
|
function readJson4(p) {
|
|
@@ -12449,7 +12494,7 @@ function stopApp(repoDir, opts = {}) {
|
|
|
12449
12494
|
const runner = opts.runnerPath ?? join48(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
12450
12495
|
if (!existsSync29(runner) || !existsSync29(join48(repoDir, ".loki", "app-runner", "app.pid")))
|
|
12451
12496
|
return;
|
|
12452
|
-
|
|
12497
|
+
spawnSync5("bash", ["-c", STOP, "app-probe", repoDir, runner], { cwd: repoDir, env: plainTestEnv(), timeout: opts.timeoutMs ?? 60000, killSignal: "SIGKILL", stdio: "ignore" });
|
|
12453
12498
|
}
|
|
12454
12499
|
async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
12455
12500
|
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ?? join48(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
@@ -12457,7 +12502,7 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
12457
12502
|
const t0 = Date.now();
|
|
12458
12503
|
const mk2 = (name, result, reason) => ({ name, cmd: "autonomy/app-runner.sh", result, duration_s: (Date.now() - t0) / 1000, reason });
|
|
12459
12504
|
const sh = (script) => {
|
|
12460
|
-
const r =
|
|
12505
|
+
const r = spawnSync5("bash", ["-c", script, "app-probe", repoDir, runner], { cwd: repoDir, env: { ...plainTestEnv(), ...opts.env ?? {} }, encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
|
|
12461
12506
|
return { out: r.stdout ?? "", status: r.error ? null : r.status };
|
|
12462
12507
|
};
|
|
12463
12508
|
let pid = null, url = null;
|
|
@@ -12502,7 +12547,7 @@ async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
|
12502
12547
|
return res("not_run", "python3 or functional-verify.py unavailable");
|
|
12503
12548
|
const specFile = join48(dir, "spec.txt");
|
|
12504
12549
|
writeFileSync21(specFile, opts.specText ?? "");
|
|
12505
|
-
const r =
|
|
12550
|
+
const r = spawnSync5(py, ["-I", script, specFile, url], { env: plainTestEnv(), encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
|
|
12506
12551
|
let out2 = null;
|
|
12507
12552
|
try {
|
|
12508
12553
|
const v = JSON.parse(r.stdout ?? "");
|
|
@@ -12893,7 +12938,7 @@ var init_route_block = __esm(() => {
|
|
|
12893
12938
|
// ../../loki-ts/src/features/visual_evidence.ts
|
|
12894
12939
|
import { spawn as spawn7 } from "child_process";
|
|
12895
12940
|
import { createHash as createHash13, randomBytes as randomBytes5 } from "crypto";
|
|
12896
|
-
import { existsSync as existsSync31, lstatSync as
|
|
12941
|
+
import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync20, readdirSync as readdirSync16, readFileSync as readFileSync39, writeFileSync as writeFileSync23 } from "fs";
|
|
12897
12942
|
import { createServer } from "net";
|
|
12898
12943
|
import { dirname as dirname17, isAbsolute as isAbsolute8, join as join50, normalize as normalize3, relative as relative6, sep as sep12 } from "path";
|
|
12899
12944
|
function routeFor(file) {
|
|
@@ -13205,13 +13250,13 @@ test("loki e2e walkthrough", async ({ page }) => {
|
|
|
13205
13250
|
});
|
|
13206
13251
|
`, DEFAULT_BUDGET_MS = 25000, MAX_ROUTES = 5, isSymlink = (p) => {
|
|
13207
13252
|
try {
|
|
13208
|
-
return
|
|
13253
|
+
return lstatSync11(p).isSymbolicLink();
|
|
13209
13254
|
} catch {
|
|
13210
13255
|
return false;
|
|
13211
13256
|
}
|
|
13212
13257
|
}, isRegularFile = (p) => {
|
|
13213
13258
|
try {
|
|
13214
|
-
return
|
|
13259
|
+
return lstatSync11(p).isFile();
|
|
13215
13260
|
} catch {
|
|
13216
13261
|
return false;
|
|
13217
13262
|
}
|
|
@@ -13478,12 +13523,12 @@ var init_providers = __esm(() => {
|
|
|
13478
13523
|
});
|
|
13479
13524
|
|
|
13480
13525
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
13481
|
-
import { existsSync as existsSync34, lstatSync as
|
|
13526
|
+
import { existsSync as existsSync34, lstatSync as lstatSync12, mkdirSync as mkdirSync22, readFileSync as readFileSync42, writeFileSync as writeFileSync25 } from "fs";
|
|
13482
13527
|
import { join as join53 } from "path";
|
|
13483
13528
|
function loadRouteRecord(runDir) {
|
|
13484
13529
|
try {
|
|
13485
13530
|
const p = join53(runDir, ROUTE_RECORD_FILE);
|
|
13486
|
-
if (!existsSync34(p) || !
|
|
13531
|
+
if (!existsSync34(p) || !lstatSync12(p).isFile())
|
|
13487
13532
|
return;
|
|
13488
13533
|
const v = JSON.parse(readFileSync42(p, "utf8"));
|
|
13489
13534
|
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
|
|
@@ -13668,7 +13713,7 @@ __export(exports_deep, {
|
|
|
13668
13713
|
DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH,
|
|
13669
13714
|
DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
|
|
13670
13715
|
});
|
|
13671
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync35, lstatSync as
|
|
13716
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync35, lstatSync as lstatSync13, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync9, rmSync as rmSync17, writeFileSync as writeFileSync26 } from "fs";
|
|
13672
13717
|
import { tmpdir as tmpdir10 } from "os";
|
|
13673
13718
|
import { dirname as dirname20, join as join55 } from "path";
|
|
13674
13719
|
function sessionCouncil(sessions) {
|
|
@@ -13790,7 +13835,7 @@ async function secureScanChanged(repoDir, changed, opts) {
|
|
|
13790
13835
|
const dir = mkdtempSync9(join55(tmpdir10(), "loki-deep-secure-"));
|
|
13791
13836
|
try {
|
|
13792
13837
|
for (const f of changed)
|
|
13793
|
-
if (existsSync35(join55(repoDir, f)) &&
|
|
13838
|
+
if (existsSync35(join55(repoDir, f)) && lstatSync13(join55(repoDir, f)).isFile()) {
|
|
13794
13839
|
mkdirSync23(dirname20(join55(dir, f)), { recursive: true });
|
|
13795
13840
|
copyFileSync3(join55(repoDir, f), join55(dir, f));
|
|
13796
13841
|
}
|
|
@@ -14408,7 +14453,7 @@ var readJson5 = (p) => {
|
|
|
14408
14453
|
var init_conventions = () => {};
|
|
14409
14454
|
|
|
14410
14455
|
// ../../loki-ts/src/engine10/stages/wall.ts
|
|
14411
|
-
import { spawnSync as
|
|
14456
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
14412
14457
|
import { existsSync as existsSync38, mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync11, readFileSync as readFileSync44, readdirSync as readdirSync18, rmSync as rmSync19, writeFileSync as writeFileSync27 } from "fs";
|
|
14413
14458
|
import { tmpdir as tmpdir12 } from "os";
|
|
14414
14459
|
import { dirname as dirname23, join as join58, relative as relative8 } from "path";
|
|
@@ -14428,7 +14473,7 @@ class RealBaseTestRunner {
|
|
|
14428
14473
|
const api = this.api === undefined ? loadProjectApi(repoDir) : this.api;
|
|
14429
14474
|
for (const f of files) {
|
|
14430
14475
|
const { cmd, args, interpreter, cwd } = commandFor(f, repoDir, api);
|
|
14431
|
-
const r =
|
|
14476
|
+
const r = spawnSync6(cmd, f.runner === "pytest" ? [...args, "-rfE"] : args, { cwd, encoding: "utf8", timeout: Math.max(1000, this.timeoutMs), env: plainTestEnv() });
|
|
14432
14477
|
const status = r.error ? null : r.status;
|
|
14433
14478
|
const result = classify(f, status, stripAnsi(`${r.stdout ?? ""}
|
|
14434
14479
|
${r.stderr ?? ""}`), repoDir, interpreter);
|
|
@@ -14650,7 +14695,7 @@ var init_wall = __esm(() => {
|
|
|
14650
14695
|
});
|
|
14651
14696
|
|
|
14652
14697
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
14653
|
-
import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as
|
|
14698
|
+
import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync14, mkdirSync as mkdirSync25, openSync as openSync9, readFileSync as readFileSync45, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync28 } from "fs";
|
|
14654
14699
|
import { dirname as dirname24, join as join59, relative as relative9, sep as sep13 } from "path";
|
|
14655
14700
|
function safeRestore(repoDir, f, want, mode) {
|
|
14656
14701
|
const root = realpathSync23(repoDir), fp = join59(root, f), rel = relative9(root, dirname24(fp));
|
|
@@ -14661,7 +14706,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
14661
14706
|
cur = join59(cur, part);
|
|
14662
14707
|
let st2;
|
|
14663
14708
|
try {
|
|
14664
|
-
st2 =
|
|
14709
|
+
st2 = lstatSync14(cur);
|
|
14665
14710
|
} catch {
|
|
14666
14711
|
mkdirSync25(cur);
|
|
14667
14712
|
continue;
|
|
@@ -14671,7 +14716,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
14671
14716
|
}
|
|
14672
14717
|
let st;
|
|
14673
14718
|
try {
|
|
14674
|
-
st =
|
|
14719
|
+
st = lstatSync14(fp);
|
|
14675
14720
|
} catch {
|
|
14676
14721
|
st = null;
|
|
14677
14722
|
}
|
|
@@ -14716,7 +14761,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
|
|
|
14716
14761
|
const fp = join59(repoDir, f);
|
|
14717
14762
|
try {
|
|
14718
14763
|
if (v.startsWith("!")) {
|
|
14719
|
-
const st =
|
|
14764
|
+
const st = lstatSync14(fp);
|
|
14720
14765
|
if (`!${st.size}:${st.mtimeMs}:${st.ctimeMs}` !== v)
|
|
14721
14766
|
throw new Error("changed, not snapshotted");
|
|
14722
14767
|
continue;
|
|
@@ -14732,7 +14777,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
|
|
|
14732
14777
|
try {
|
|
14733
14778
|
let m = 420;
|
|
14734
14779
|
try {
|
|
14735
|
-
const l =
|
|
14780
|
+
const l = lstatSync14(join59(repoDir, f));
|
|
14736
14781
|
if (l.isFile())
|
|
14737
14782
|
m = l.mode & 511;
|
|
14738
14783
|
} catch {}
|
|
@@ -14769,9 +14814,10 @@ import { dirname as dirname25 } from "path";
|
|
|
14769
14814
|
function dropSet(repoDir, staged, preexistingDirty, env = process.env) {
|
|
14770
14815
|
return staged.concat(untouchedSinceIntake(repoDir, preexistingDirty, env).map((f) => ({ st: "L", f }))).filter(({ st, f }) => f.startsWith(".loki/") || st === "L" || /(^|\/)loki_wall_[^/]*$/.test(f) || st === "A" && !staged.some(({ f: m }) => /(^|\/)(package\.json|pyproject\.toml|requirements\.txt|Cargo\.toml|go\.mod)$/.test(m) && dirname25(m) === dirname25(f)) && /(^|\/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb?|poetry\.lock|Cargo\.lock|go\.sum)$/.test(f));
|
|
14771
14816
|
}
|
|
14772
|
-
var parseStaged = (out2) => out2.split("\x00").reduce((a, t, i, all) => i % 2 === 0 && t ? [...a, { st: t, f: all[i + 1] }] : a, []);
|
|
14817
|
+
var parseStaged = (out2) => out2.split("\x00").reduce((a, t, i, all) => i % 2 === 0 && t ? [...a, { st: t, f: all[i + 1] }] : a, []), formatChanged = (repoDir, staged, dropped2, env = process.env) => runFormatters(repoDir, staged.filter(({ st, f }) => (st === "A" || st === "M") && !dropped2.has(f) && !f.startsWith(".loki/")).map(({ f }) => f), tokenFreeEnv(env));
|
|
14773
14818
|
var init_commit_filter = __esm(() => {
|
|
14774
14819
|
init_preexisting_dirty();
|
|
14820
|
+
init_repo_profile();
|
|
14775
14821
|
init_safe_git();
|
|
14776
14822
|
});
|
|
14777
14823
|
|
|
@@ -15130,7 +15176,7 @@ See also: loki cost --detail (what a run ALREADY spent)
|
|
|
15130
15176
|
});
|
|
15131
15177
|
|
|
15132
15178
|
// ../../loki-ts/src/features/contract.ts
|
|
15133
|
-
import { existsSync as existsSync42, lstatSync as
|
|
15179
|
+
import { existsSync as existsSync42, lstatSync as lstatSync15, mkdirSync as mkdirSync28, readFileSync as readFileSync49, rmSync as rmSync20, writeFileSync as writeFileSync30 } from "fs";
|
|
15134
15180
|
import { dirname as dirname27, join as join64 } from "path";
|
|
15135
15181
|
import { createHash as createHash15 } from "crypto";
|
|
15136
15182
|
function contractEnabled(env = process.env) {
|
|
@@ -15169,7 +15215,7 @@ function readContract(repoDir) {
|
|
|
15169
15215
|
const p = contractPath(repoDir);
|
|
15170
15216
|
let st;
|
|
15171
15217
|
try {
|
|
15172
|
-
st =
|
|
15218
|
+
st = lstatSync15(p);
|
|
15173
15219
|
} catch {
|
|
15174
15220
|
return { contract: null, notes: [], sha256: null };
|
|
15175
15221
|
}
|
|
@@ -15214,7 +15260,7 @@ function sealContract(repoDir, body, rawDiff, checks, env = process.env, snap) {
|
|
|
15214
15260
|
const live2 = readContract(repoDir);
|
|
15215
15261
|
let exists2 = true;
|
|
15216
15262
|
try {
|
|
15217
|
-
|
|
15263
|
+
lstatSync15(contractPath(repoDir));
|
|
15218
15264
|
} catch {
|
|
15219
15265
|
exists2 = false;
|
|
15220
15266
|
}
|
|
@@ -15769,7 +15815,10 @@ var init_seal = __esm(() => {
|
|
|
15769
15815
|
return sat;
|
|
15770
15816
|
if (drop.length > 0 && (await git4(ctx, ["--literal-pathspecs", "reset", "-q", ctx.baseSha, "--", ...drop.map(({ f }) => f)])).code !== 0)
|
|
15771
15817
|
return { status: "failed", data: {}, reason: "git reset failed" };
|
|
15772
|
-
const dropped2 = new Set(drop.map(({ f }) => f)),
|
|
15818
|
+
const dropped2 = new Set(drop.map(({ f }) => f)), fmt = formatChanged(ctx.repoDir, staged, dropped2);
|
|
15819
|
+
if (fmt.length > 0)
|
|
15820
|
+
await git4(ctx, ["--literal-pathspecs", "add", "--", ...fmt], { repoDrivers: true });
|
|
15821
|
+
const notes = flagOutsideScope(ctx.outputs(), staged.filter(({ f }) => !dropped2.has(f)));
|
|
15773
15822
|
if ((await git4(ctx, ["diff", "--cached", "--quiet"])).code === 0)
|
|
15774
15823
|
return { status: "completed", data: { committed: false, scope_notes: notes } };
|
|
15775
15824
|
const title = (str3(ctx.outputs().intake?.title) ?? `run ${ctx.runId}`).split(`
|
|
@@ -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.41",
|
|
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-BBV2psih.js";import{B as C}from"./Button-5CI0TYxR.js";import{T as $e}from"./trending-up-DgRWrCNb.js";import{C as z}from"./clock-BGhPbAAa.js";import{A as Be,U as ue,M as De}from"./Avatar-CnSNZSx6.js";import{A as J}from"./activity-Di09VZ-C.js";import{R as pe}from"./refresh-cw-DPEeU-0s.js";import{G as ze}from"./globe-CQvcGE8E.js";import{C as Le}from"./chevron-left-lKRP1pKT.js";import{C as je}from"./check-DYPycZns.js";import{D as Y}from"./dollar-sign-adGlfVLa.js";import{U as Te}from"./user-DC2T8RYB.js";import{D as Me}from"./database-LiEeNmyC.js";import{L as Ue}from"./lock-Bivqy2kG.js";import{S as Re}from"./scroll-text-BBMfK4J7.js";import{S as Ie}from"./shield-alert-Dc5xbnOx.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-BBV2psih.js";import{C as r}from"./clock-BGhPbAAa.js";import{C as a}from"./circle-alert-D1rDQ9mD.js";import{C as l}from"./check-DYPycZns.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-BBV2psih.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-BBV2psih.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-VZcsEDJl.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-4nFvjqQ-.js";import{C as oe}from"./check-DYPycZns.js";import{C as Ye}from"./clock-BGhPbAAa.js";import{D as Xe}from"./dollar-sign-adGlfVLa.js";import{U as Ze}from"./upload-Cs07lSfb.js";import{L as V}from"./loader-circle-BpyfPEFt.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-BLc2yb4N.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-BBV2psih.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-DOrDxj2L.js → EvidenceReceiptPanel-Cf5DXTqo.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-BBV2psih.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-BBV2psih.js";import{B as N}from"./Button-5CI0TYxR.js";import{C as y}from"./thumbs-up-4nFvjqQ-.js";import{R as S}from"./refresh-cw-DPEeU-0s.js";import{C as z}from"./circle-alert-D1rDQ9mD.js";import{U as D}from"./user-DC2T8RYB.js";import{L as G}from"./loader-circle-BpyfPEFt.js";import{R as T}from"./rotate-ccw-DZX_aED8.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-BBV2psih.js";import{B as y}from"./Button-5CI0TYxR.js";import{C as ge}from"./chevron-left-lKRP1pKT.js";import{G as P}from"./thumbs-up-4nFvjqQ-.js";import{R as $}from"./refresh-cw-DPEeU-0s.js";import{C as Ne}from"./circle-alert-D1rDQ9mD.js";import{L as Q,S as je}from"./ProjectPage-zpARxbll.js";import{S as se}from"./shield-alert-Dc5xbnOx.js";import{F as ye}from"./file-code-corner-DY5GkQGM.js";import{C as V}from"./clock-BGhPbAAa.js";import{C as re}from"./check-DYPycZns.js";import"./ErrorBoundary-VZcsEDJl.js";import"./TerminalOutput-iLcaELwj.js";import"./lock-Bivqy2kG.js";import"./package-DvDJIgWs.js";import"./file-plus-RLd_hPU8.js";import"./activity-Di09VZ-C.js";import"./scroll-text-BBMfK4J7.js";import"./bot-pGvyFisf.js";import"./loader-circle-BpyfPEFt.js";import"./hammer-BWOWu2Hf.js";import"./dollar-sign-adGlfVLa.js";import"./globe-CQvcGE8E.js";import"./trash-2-SjUKL3ek.js";import"./upload-Cs07lSfb.js";import"./plus-CVjTmPiU.js";import"./rotate-ccw-DZX_aED8.js";import"./code-xml-DtutBX9b.js";import"./trending-up-DgRWrCNb.js";import"./layers-C_cj_ShX.js";import"./trending-down-B7_1Kuct.js";import"./server-Bq18pHWE.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|