loki-mode 11.17.97 → 11.17.99
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/run.sh +21 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/image-provenance.md +11 -2
- package/docs/v10/FAILURE-CLASSES.md +31 -0
- package/docs/v10/PROGRESS.md +6 -0
- package/loki-ts/dist/loki.js +1114 -1113
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/ask-tools-server.js +3 -2
- package/packages/control-plane/dist/server.js +82 -32
- package/packages/control-plane/src/ask/policy.ts +9 -2
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-BytHjrWT.js → AdminPage-BCWegSLH.js} +1 -1
- package/web-app/dist/assets/{Avatar-dNf3amMe.js → Avatar-rCCQR-SZ.js} +1 -1
- package/web-app/dist/assets/{Badge-CnvI2YSE.js → Badge-DgaQE-EZ.js} +1 -1
- package/web-app/dist/assets/{Button-Bh6HJSx6.js → Button-CFwG7fak.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-Cgb8AAHQ.js → CockpitPage-iRCYOfDe.js} +1 -1
- package/web-app/dist/assets/{ComparePage-CRiAPbds.js → ComparePage-IjQ7WEBZ.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-t-0AuXcR.js → ErrorBoundary-DZ0DjicT.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-BQMuZ040.js → EvidenceReceiptPanel-B9r_xHvw.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-243WSJem.js → GitHubIssuesPanel-D1YGko2a.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-Bzen0ew8.js → GitHubPRsPanel-CHsW_7qg.js} +1 -1
- package/web-app/dist/assets/{HomePage-_V2-Ukxv.js → HomePage-aD56XkX1.js} +2 -2
- package/web-app/dist/assets/{LoginPage-DYKXRZEd.js → LoginPage-CwcZseio.js} +1 -1
- package/web-app/dist/assets/{MagicPage-BXo9VpH1.js → MagicPage-BuK7xSe2.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-BOHwqyBx.js → MetricsPage-flgWztdQ.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-m1C1pOjw.js → NotFoundPage-Dpn9qKCu.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-Don7b0uX.js → ProjectPage-CW4IMU4E.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-CT05Xbvx.js → ProjectsPage-CeuozETO.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-K1RdqdPo.js → SettingsPage-BQ7bGlPZ.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-BNMXSbLn.js → ShowcasePage-BUN7HHsl.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Cb5sPNHw.js → SystemSettingsPage-BYKqCe0V.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-DwIExIGI.js → TeamsPage-BEx0UUvn.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-Bbp0kGfr.js → TemplatesPage-BoX5Df-b.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-B7SAJSSx.js → TerminalOutput-B2TSSpbN.js} +1 -1
- package/web-app/dist/assets/{activity-DLDtD-RP.js → activity-DqTXb5xR.js} +1 -1
- package/web-app/dist/assets/{bell-BhnIrwOh.js → bell-C8GQEJAm.js} +1 -1
- package/web-app/dist/assets/{bot-Bi7rc3U-.js → bot-LHRcGGY4.js} +1 -1
- package/web-app/dist/assets/{check-BOKbqsD5.js → check-E-mC9uGB.js} +1 -1
- package/web-app/dist/assets/{chevron-left-CoVTOJ_R.js → chevron-left-CG9JI3Un.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CKekYuWI.js → circle-alert-uLOdudrY.js} +1 -1
- package/web-app/dist/assets/{clock-aZ0Z-ePQ.js → clock-CTfYZuHT.js} +1 -1
- package/web-app/dist/assets/{cloud-BxoicqtX.js → cloud-CvHYqZb4.js} +1 -1
- package/web-app/dist/assets/{code-xml-C1Rs6VBh.js → code-xml-DdiAYav6.js} +1 -1
- package/web-app/dist/assets/{database-FZtGtKtF.js → database-BVupYiyp.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DXLiAjF0.js → dollar-sign-Buovjluk.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-Dd3V5YQW.js → file-code-corner-CZxdOs7f.js} +1 -1
- package/web-app/dist/assets/{file-plus-CSYUdRrx.js → file-plus-CLoz9fGY.js} +1 -1
- package/web-app/dist/assets/{globe-fdKGcy1_.js → globe-Bz38POnM.js} +1 -1
- package/web-app/dist/assets/{hammer-Def0UqNM.js → hammer-BcdWir52.js} +1 -1
- package/web-app/dist/assets/{index-CNMmdSPA.js → index-CnWjN0Ms.js} +3 -3
- package/web-app/dist/assets/{layers-Bgc7TP2t.js → layers-B4JZh2PQ.js} +1 -1
- package/web-app/dist/assets/{loader-circle-jmPs0bD2.js → loader-circle-B4pVqJjl.js} +1 -1
- package/web-app/dist/assets/{lock-BKIF1VmL.js → lock-BYyyOsOt.js} +1 -1
- package/web-app/dist/assets/{package-DhhpGwnm.js → package-D3g7EPnP.js} +1 -1
- package/web-app/dist/assets/{plus-BlNVdkl3.js → plus-BWn9Hhkg.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C20PCDgA.js → refresh-cw-CIZSiLmc.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-C4PlFq8d.js → rotate-ccw-eFQJMvH2.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DAbCSrb9.js → scroll-text-Scmlp_4R.js} +1 -1
- package/web-app/dist/assets/{server-4AzyKwOe.js → server-kRjjEnwM.js} +1 -1
- package/web-app/dist/assets/{shield-alert-DMZNCvUV.js → shield-alert-BE0_s4mo.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-D8m-2YKD.js → thumbs-up-DrNJGF29.js} +1 -1
- package/web-app/dist/assets/{trash-2-D_bXC3JF.js → trash-2-BmIPNtTb.js} +1 -1
- package/web-app/dist/assets/{trending-down-4BqvwC8V.js → trending-down-CwXb1mRC.js} +1 -1
- package/web-app/dist/assets/{trending-up-C8eCGVRi.js → trending-up-PkkVVpMi.js} +1 -1
- package/web-app/dist/assets/{upload-DtXbAChx.js → upload-HzVQ78Nw.js} +1 -1
- package/web-app/dist/assets/{usePolling-BQG2Axwp.js → usePolling-9x-bTHUr.js} +1 -1
- package/web-app/dist/assets/{user-CIHTfrI5.js → user-D_3xowXu.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.99",
|
|
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": "2739c8e268391ef7a65d54711830a2151661c4ee"
|
|
164
164
|
}
|
|
@@ -40799,8 +40799,9 @@ var configEnumTimeoutMs = () => {
|
|
|
40799
40799
|
const n = Number(process.env.LOKI_SAFE_GIT_CONFIG_TIMEOUT_MS);
|
|
40800
40800
|
return Number.isFinite(n) && n > 0 ? n : 30000;
|
|
40801
40801
|
};
|
|
40802
|
-
|
|
40803
|
-
|
|
40802
|
+
var driverKeys = (repoDir) => repoKeysMatching(repoDir, DRIVER_KEY_RE);
|
|
40803
|
+
function repoKeysMatching(repoDir, keyRe) {
|
|
40804
|
+
const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", keyRe], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: configEnumTimeoutMs(), killSignal: "SIGKILL" });
|
|
40804
40805
|
if (r.error)
|
|
40805
40806
|
throw r.error;
|
|
40806
40807
|
if (r.status === 1)
|
|
@@ -282,8 +282,8 @@ function tokenFreeEnv(env = process.env) {
|
|
|
282
282
|
hardenCredentialEnv(out);
|
|
283
283
|
return out;
|
|
284
284
|
}
|
|
285
|
-
function
|
|
286
|
-
const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp",
|
|
285
|
+
function repoKeysMatching(repoDir, keyRe) {
|
|
286
|
+
const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", keyRe], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: configEnumTimeoutMs(), killSignal: "SIGKILL" });
|
|
287
287
|
if (r.error)
|
|
288
288
|
throw r.error;
|
|
289
289
|
if (r.status === 1)
|
|
@@ -438,7 +438,7 @@ var SAFE_GIT_CONFIG, CREDENTIAL_CONFIG, DRIVER_CONFIG, ATTRS_OFF = "core.attribu
|
|
|
438
438
|
}, configEnumTimeoutMs = () => {
|
|
439
439
|
const n2 = Number(process.env.LOKI_SAFE_GIT_CONFIG_TIMEOUT_MS);
|
|
440
440
|
return Number.isFinite(n2) && n2 > 0 ? n2 : 30000;
|
|
441
|
-
}, NET_CMD_KEY_RE = "^(core\\.(sshcommand|gitproxy|askpass)|remote\\..*\\.(uploadpack|receivepack|proxy)|credential(\\..*)?\\.helper|https?\\.(.*\\.)?(proxy|sslverify|sslcainfo|sslcapath|curloptresolve))$", BOOL_SAFE_DEFAULT, LOCAL_SCOPES, PUSH_CMD, PACK_OPTS, TRANSPORT_OR_LOCAL;
|
|
441
|
+
}, driverKeys = (repoDir) => repoKeysMatching(repoDir, DRIVER_KEY_RE), NET_CMD_KEY_RE = "^(core\\.(sshcommand|gitproxy|askpass)|remote\\..*\\.(uploadpack|receivepack|proxy)|credential(\\..*)?\\.helper|https?\\.(.*\\.)?(proxy|sslverify|sslcainfo|sslcapath|curloptresolve))$", BOOL_SAFE_DEFAULT, LOCAL_SCOPES, PUSH_CMD, PACK_OPTS, TRANSPORT_OR_LOCAL;
|
|
442
442
|
var init_safe_git = __esm(() => {
|
|
443
443
|
init_credential_env();
|
|
444
444
|
SAFE_GIT_CONFIG = ["-c", "core.fsmonitor=", "-c", "core.hooksPath=/dev/null", "-c", "core.sshCommand=", "-c", "protocol.ext.allow=never", "-c", "credential.helper="];
|
|
@@ -12842,7 +12842,7 @@ var init_load_owner = __esm(() => {
|
|
|
12842
12842
|
});
|
|
12843
12843
|
|
|
12844
12844
|
// ../../loki-ts/src/project_model/package_suite.ts
|
|
12845
|
-
import { join as join47 } from "path";
|
|
12845
|
+
import { isAbsolute as isAbsolute7, join as join47, relative as relative7 } from "path";
|
|
12846
12846
|
function packageSuiteSpecs(api) {
|
|
12847
12847
|
if (!isMultiRoot(api))
|
|
12848
12848
|
return null;
|
|
@@ -12855,6 +12855,13 @@ function packageSuiteSpecs(api) {
|
|
|
12855
12855
|
function suiteEnv(path) {
|
|
12856
12856
|
return path ? { ...plainTestEnv(), PATH: path } : plainTestEnv();
|
|
12857
12857
|
}
|
|
12858
|
+
function execProves(repoDir, o, owned) {
|
|
12859
|
+
const proofs = o.proofFiles ?? [], rel = (f) => isAbsolute7(f) ? relative7(repoDir, f) : f;
|
|
12860
|
+
if (!o.wallBaseRed || !proofs.length || !o.changed)
|
|
12861
|
+
return false;
|
|
12862
|
+
const wall = new Set(proofs.map(rel)), rest = o.changed.filter((f) => !wall.has(rel(f)));
|
|
12863
|
+
return rest.length > 0 && !o.changed.some((f) => f.startsWith('"')) && rest.every(owned);
|
|
12864
|
+
}
|
|
12858
12865
|
async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
12859
12866
|
const api = loadProjectApi(repoDir), specs = packageSuiteSpecs(api);
|
|
12860
12867
|
if (!api || !specs)
|
|
@@ -12887,11 +12894,15 @@ ${r.stderr}`);
|
|
|
12887
12894
|
const o = api.packageOf(f);
|
|
12888
12895
|
return !o || f.startsWith('"') || o.root === pkg.root;
|
|
12889
12896
|
});
|
|
12890
|
-
|
|
12897
|
+
const proven = (opts.proofFiles ?? []).some((f) => api.packageOf(f)?.root === pkg.root) || execProves(repoDir, opts, (c) => api.packageOf(c)?.root === pkg.root);
|
|
12898
|
+
notProven.add(ran2 && !(owns && !proven) ? NA_PREFIX + note : note);
|
|
12891
12899
|
}
|
|
12892
12900
|
return true;
|
|
12893
12901
|
}
|
|
12894
|
-
var NA_PREFIX = "n/a: ", naNote = (n2) => n2.startsWith(NA_PREFIX) || n2.startsWith("full suite (no test runner"), naText = (n2) => n2.startsWith(NA_PREFIX) ? n2.slice(NA_PREFIX.length) : n2,
|
|
12902
|
+
var NA_PREFIX = "n/a: ", naNote = (n2) => n2.startsWith(NA_PREFIX) || n2.startsWith("full suite (no test runner"), naText = (n2) => n2.startsWith(NA_PREFIX) ? n2.slice(NA_PREFIX.length) : n2, wallRedOnBaseOf = (baseRun) => {
|
|
12903
|
+
const f = baseRun?.fail;
|
|
12904
|
+
return typeof f === "number" && f > 0;
|
|
12905
|
+
}, wallProofOf = (checks, wall) => {
|
|
12895
12906
|
const n2 = new Set(wall.map((w2) => w2.name)), w = checks.filter((c) => n2.has(c.name) || c.name.startsWith("holdout"));
|
|
12896
12907
|
return w.length > 0 && w.every((c) => c.result === "pass") ? wall.map((x) => x.path) : [];
|
|
12897
12908
|
};
|
|
@@ -13553,7 +13564,7 @@ var init_select = __esm(() => {
|
|
|
13553
13564
|
});
|
|
13554
13565
|
|
|
13555
13566
|
// ../../loki-ts/src/util/wall_owned.ts
|
|
13556
|
-
import { isAbsolute as
|
|
13567
|
+
import { isAbsolute as isAbsolute8, join as join50, relative as relative8 } from "path";
|
|
13557
13568
|
function failingLocations(raw2, cwd, repoDir) {
|
|
13558
13569
|
const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
|
|
13559
13570
|
`), files = new Set;
|
|
@@ -13585,7 +13596,7 @@ function failingLocations(raw2, cwd, repoDir) {
|
|
|
13585
13596
|
}
|
|
13586
13597
|
if (errors2 === 0 || located !== errors2)
|
|
13587
13598
|
return null;
|
|
13588
|
-
return [...files].map((f) =>
|
|
13599
|
+
return [...files].map((f) => relative8(repoDir, isAbsolute8(f) ? f : join50(cwd, f)));
|
|
13589
13600
|
}
|
|
13590
13601
|
function wallOwnedFailure(raw2, cwd, repoDir, wall) {
|
|
13591
13602
|
const locs = failingLocations(raw2, cwd, repoDir);
|
|
@@ -14013,7 +14024,7 @@ var init_retry_class = () => {};
|
|
|
14013
14024
|
|
|
14014
14025
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
14015
14026
|
import { existsSync as existsSync33, readdirSync as readdirSync19, readFileSync as readFileSync42 } from "fs";
|
|
14016
|
-
import { basename as basename22, dirname as dirname19, isAbsolute as
|
|
14027
|
+
import { basename as basename22, dirname as dirname19, isAbsolute as isAbsolute9, join as join53, relative as relative9, resolve as resolve17 } from "path";
|
|
14017
14028
|
function parseJsonc(text2) {
|
|
14018
14029
|
let out2 = "", i = 0;
|
|
14019
14030
|
while (i < text2.length) {
|
|
@@ -14105,7 +14116,7 @@ function outOfRepoTarget(content) {
|
|
|
14105
14116
|
function nearestPackageRoot(testDir, repoDir, fileName) {
|
|
14106
14117
|
const api = loadProjectApi(repoDir);
|
|
14107
14118
|
if (api)
|
|
14108
|
-
return siteFor(api, repoDir,
|
|
14119
|
+
return siteFor(api, repoDir, relative9(repoDir, join53(testDir, fileName)))?.cwd ?? repoDir;
|
|
14109
14120
|
const shaped = (d) => {
|
|
14110
14121
|
try {
|
|
14111
14122
|
return readdirSync19(d).some((f) => {
|
|
@@ -14171,7 +14182,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
14171
14182
|
return -1;
|
|
14172
14183
|
};
|
|
14173
14184
|
const strayInTestDir = (out2) => {
|
|
14174
|
-
const first =
|
|
14185
|
+
const first = relative9(testDir, out2).split("/")[0];
|
|
14175
14186
|
return !!first && first !== "__self__" && !existsSync33(join53(testDir, first)) && [pkg, repoDir].some((d) => d !== testDir && existsSync33(join53(d, first)));
|
|
14176
14187
|
};
|
|
14177
14188
|
const scan = (cwd) => {
|
|
@@ -14206,8 +14217,8 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
14206
14217
|
return dirname19(args[0]);
|
|
14207
14218
|
const out2 = resolve17(...args);
|
|
14208
14219
|
const first = parts.slice(1).map((a) => /^\s*["'`]([^"'`]*)["'`]\s*$/.exec(a)?.[1]).find((x) => x), viaWalk = !!first && walk.has(parts[0].trim()) && [pkg, repoDir].some((d) => existsSync33(join53(d, first.split("/").filter(Boolean)[0] ?? "\x00")));
|
|
14209
|
-
if (report && (viaWalk || !parts.some((a) => walk.has(a.trim()) || taint.has(a.trim())) && (
|
|
14210
|
-
reports.set(`${ln}|${e}`, { out: out2, rel:
|
|
14220
|
+
if (report && (viaWalk || !parts.some((a) => walk.has(a.trim()) || taint.has(a.trim())) && (relative9(testDir, out2).startsWith("..") || strayInTestDir(out2))) && parts.some((a) => /^\s*["'`]/.test(a)))
|
|
14221
|
+
reports.set(`${ln}|${e}`, { out: out2, rel: relative9(repoDir, out2), tail: viaWalk ? join53(...args.slice(1)) : undefined });
|
|
14211
14222
|
return out2;
|
|
14212
14223
|
};
|
|
14213
14224
|
for (const line2 of walkCode.split(`
|
|
@@ -14259,7 +14270,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
14259
14270
|
});
|
|
14260
14271
|
const phantom = (r, created) => {
|
|
14261
14272
|
const rel = r.rel;
|
|
14262
|
-
if (!rel || rel.startsWith("..") ||
|
|
14273
|
+
if (!rel || rel.startsWith("..") || isAbsolute9(rel) || /(^|\/)(\.git|\.loki|dist|build|coverage|tmp)(\/|$)/.test(rel) || existsSync33(r.out) || planned(rel))
|
|
14263
14274
|
return false;
|
|
14264
14275
|
if (r.tail) {
|
|
14265
14276
|
const seen = (from) => {
|
|
@@ -14456,7 +14467,7 @@ import { spawn as spawn8 } from "child_process";
|
|
|
14456
14467
|
import { createHash as createHash14, randomBytes as randomBytes6 } from "crypto";
|
|
14457
14468
|
import { existsSync as existsSync34, lstatSync as lstatSync12, mkdirSync as mkdirSync21, readdirSync as readdirSync20, readFileSync as readFileSync43, writeFileSync as writeFileSync24 } from "fs";
|
|
14458
14469
|
import { createServer } from "net";
|
|
14459
|
-
import { dirname as dirname21, isAbsolute as
|
|
14470
|
+
import { dirname as dirname21, isAbsolute as isAbsolute10, join as join54, normalize as normalize3, relative as relative10, sep as sep13 } from "path";
|
|
14460
14471
|
function routeFor(file) {
|
|
14461
14472
|
let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
|
|
14462
14473
|
r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
|
|
@@ -14477,7 +14488,7 @@ function checkScreens(runDir, screens) {
|
|
|
14477
14488
|
for (const s of screens) {
|
|
14478
14489
|
if (typeof s?.path !== "string" || typeof s.sha256 !== "string")
|
|
14479
14490
|
return "evidence_screens entry is malformed";
|
|
14480
|
-
if (
|
|
14491
|
+
if (isAbsolute10(s.path) || normalize3(s.path).startsWith(".."))
|
|
14481
14492
|
return `evidence screenshot path escapes the evidence dir: ${s.path}`;
|
|
14482
14493
|
const file = join54(runDir, s.path);
|
|
14483
14494
|
let cur = runDir;
|
|
@@ -14561,7 +14572,7 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
|
|
|
14561
14572
|
if (e.isDirectory())
|
|
14562
14573
|
walk(full);
|
|
14563
14574
|
else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
|
|
14564
|
-
rels.push(join54(relDir, "e2e",
|
|
14575
|
+
rels.push(join54(relDir, "e2e", relative10(dir, full)));
|
|
14565
14576
|
}
|
|
14566
14577
|
};
|
|
14567
14578
|
walk(join54(dir, "out"));
|
|
@@ -15237,7 +15248,7 @@ function sessionCouncil(sessions) {
|
|
|
15237
15248
|
} };
|
|
15238
15249
|
}
|
|
15239
15250
|
async function runFullSuite(ctx, signal, opts, checks, notProven) {
|
|
15240
|
-
if (await runPackageSuites(ctx.repoDir, signal, { path: opts.path, timeoutMs: opts.fullSuiteTimeoutMs ?? FULL_SUITE_TIMEOUT_MS, baseSha: ctx.baseSha, skip: installOwned(ctx.repoDir, ctx.outputs().intake?.install_created), changed: opts.changed, proofFiles: opts.proofFiles }, checks, notProven))
|
|
15251
|
+
if (await runPackageSuites(ctx.repoDir, signal, { path: opts.path, timeoutMs: opts.fullSuiteTimeoutMs ?? FULL_SUITE_TIMEOUT_MS, baseSha: ctx.baseSha, skip: installOwned(ctx.repoDir, ctx.outputs().intake?.install_created), changed: opts.changed, proofFiles: opts.proofFiles, wallBaseRed: opts.wallBaseRed }, checks, notProven))
|
|
15241
15252
|
return;
|
|
15242
15253
|
const map = await ctx.tests.detect(ctx.repoDir);
|
|
15243
15254
|
if (map.runners.length === 0) {
|
|
@@ -15485,7 +15496,7 @@ var init_deep = __esm(() => {
|
|
|
15485
15496
|
// ../../loki-ts/src/engine10/stages/verify.ts
|
|
15486
15497
|
import { existsSync as existsSync39, mkdtempSync as mkdtempSync10, rmSync as rmSync18 } from "fs";
|
|
15487
15498
|
import { tmpdir as tmpdir11 } from "os";
|
|
15488
|
-
import { isAbsolute as
|
|
15499
|
+
import { isAbsolute as isAbsolute11, join as join59, relative as relative11 } from "path";
|
|
15489
15500
|
async function runOnce2(cmd2, args, cwd, signal, opts) {
|
|
15490
15501
|
if (!Bun.which(cmd2, { PATH: opts.path ?? process.env["PATH"] ?? "" }))
|
|
15491
15502
|
return { ok: false, missing: true, cut: false, out: "" };
|
|
@@ -15637,7 +15648,7 @@ var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name),
|
|
|
15637
15648
|
return r.missing || r.cut ? null : r;
|
|
15638
15649
|
}, base: (f) => {
|
|
15639
15650
|
try {
|
|
15640
|
-
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${
|
|
15651
|
+
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative11(ctx.repoDir, join59(cwd, f))}`], { stdio: ["ignore", "pipe", "ignore"] });
|
|
15641
15652
|
} catch {
|
|
15642
15653
|
return null;
|
|
15643
15654
|
}
|
|
@@ -15703,7 +15714,7 @@ var init_verify = __esm(() => {
|
|
|
15703
15714
|
const impacted = ctx.tests.impacted(map, changed);
|
|
15704
15715
|
const changedTestFiles = map.tests.filter((t) => changed.includes(t.path));
|
|
15705
15716
|
const wall = ctx.outputs().wall ?? {};
|
|
15706
|
-
const wallPaths = new Set((wall.files ?? []).map((f) =>
|
|
15717
|
+
const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute11(f.path) ? relative11(ctx.repoDir, f.path) : f.path));
|
|
15707
15718
|
const intake = ctx.outputs().intake, repoMap = loadRepoMap(intake?.repomap_ref), relevant2 = ctx.tests.impacted(map, namedFiles(intake?.task ?? "", repoMap));
|
|
15708
15719
|
const harness = map.runners.length === 0 ? harnessRunners(map.runners, repoMap?.files ?? [])[0] : undefined, wallTests = [...map.tests.filter((t) => wallPaths.has(t.path)), ...harness ? [...wallPaths].filter((p) => /[._](?:test|spec)\.[cm]?[jt]sx?$/.test(p) && !map.tests.some((t) => t.path === p)).map((path) => ({ runner: harness, path })) : []];
|
|
15709
15720
|
const tests = failedFirst(dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]), ctx.outputs().verify?.checks);
|
|
@@ -15758,7 +15769,7 @@ var init_verify = __esm(() => {
|
|
|
15758
15769
|
if (risk && risk.tier !== "low" && !signal.aborted) {
|
|
15759
15770
|
const { runFullSuite: runFullSuite2 } = await Promise.resolve().then(() => (init_deep(), exports_deep));
|
|
15760
15771
|
const full = [];
|
|
15761
|
-
await runFullSuite2(ctx, signal, { changed, proofFiles: wallProofOf(checks, [...wallTests.map((t) => ({ name: testCheckName(t), path: t.path })), ...(hold?.tests ?? []).map((h, i) => ({ name: `holdout:${i + 1}`, path: h.path }))]) }, full, fullNotProven);
|
|
15772
|
+
await runFullSuite2(ctx, signal, { changed, wallBaseRed: wallRedOnBaseOf(ctx.outputs().wall?.base_run), proofFiles: wallProofOf(checks, [...wallTests.map((t) => ({ name: testCheckName(t), path: t.path })), ...(hold?.tests ?? []).map((h, i) => ({ name: `holdout:${i + 1}`, path: h.path }))]) }, full, fullNotProven);
|
|
15762
15773
|
for (const c of full) {
|
|
15763
15774
|
const k = { name: c.name, cmd: c.cmd, result: c.result, duration_s: c.duration_s, ...c.reason ? { reason: c.reason } : {} };
|
|
15764
15775
|
checks.push(k);
|
|
@@ -15814,7 +15825,7 @@ ${x}` : c.cmd };
|
|
|
15814
15825
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
15815
15826
|
import { existsSync as existsSync40, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync11, readFileSync as readFileSync47, readdirSync as readdirSync21, rmSync as rmSync19, writeFileSync as writeFileSync28 } from "fs";
|
|
15816
15827
|
import { tmpdir as tmpdir12 } from "os";
|
|
15817
|
-
import { dirname as dirname25, join as join60, relative as
|
|
15828
|
+
import { dirname as dirname25, join as join60, relative as relative12 } from "path";
|
|
15818
15829
|
|
|
15819
15830
|
class RealBaseTestRunner {
|
|
15820
15831
|
api;
|
|
@@ -15926,7 +15937,7 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
15926
15937
|
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" });
|
|
15927
15938
|
const tree = prior.intake?.tree;
|
|
15928
15939
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
15929
|
-
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${
|
|
15940
|
+
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative12(ctx.repoDir, targetDir)}/x`);
|
|
15930
15941
|
const conv2 = readPackageConventions(join60(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
15931
15942
|
const cwd = mkdtempSync11(join60(tmpdir12(), "loki-e15-wall-"));
|
|
15932
15943
|
const wm = wallManifestFor(ctx.repoDir, tree, task);
|
|
@@ -15935,7 +15946,7 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
15935
15946
|
const model = retry?.model ?? wallFirstModel(sz.size), iterationId = `${ctx.runId}-wall${retry?.suffix ?? ""}`;
|
|
15936
15947
|
const session = await ctx.sessions.run({
|
|
15937
15948
|
stage: "wall",
|
|
15938
|
-
brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2), unitSpec()?.acceptance ?? [],
|
|
15949
|
+
brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2), unitSpec()?.acceptance ?? [], relative12(ctx.repoDir, targetDir)),
|
|
15939
15950
|
tier: "development",
|
|
15940
15951
|
model,
|
|
15941
15952
|
iterationId,
|
|
@@ -15949,7 +15960,7 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
15949
15960
|
}
|
|
15950
15961
|
const planText = typeof prior.plan?.plan === "string" ? prior.plan.plan : null, repoFiles = repoMap?.files ?? [];
|
|
15951
15962
|
const oor = () => readdirSync21(cwd).filter((f) => f.startsWith(WALL_PREFIX)).flatMap((name) => {
|
|
15952
|
-
const text2 = readFileSync47(join60(cwd, name), "utf8"), why = outOfRepoTarget(text2) ?? phantomReason(phantomRepoPaths(text2, name, targetDir, ctx.repoDir, planText), repoFiles,
|
|
15963
|
+
const text2 = readFileSync47(join60(cwd, name), "utf8"), why = outOfRepoTarget(text2) ?? phantomReason(phantomRepoPaths(text2, name, targetDir, ctx.repoDir, planText), repoFiles, relative12(ctx.repoDir, targetDir), pkg?.root ?? "");
|
|
15953
15964
|
return why ? [{ name, why }] : [];
|
|
15954
15965
|
});
|
|
15955
15966
|
const bad1 = oor();
|
|
@@ -15997,7 +16008,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
15997
16008
|
sealedFiles.push({ path: dest, sha256: sha2562(content) });
|
|
15998
16009
|
readOnlyFiles.push({ path: dest, content });
|
|
15999
16010
|
if (runner)
|
|
16000
|
-
wallTests.push({ runner, path:
|
|
16011
|
+
wallTests.push({ runner, path: relative12(ctx.repoDir, dest) });
|
|
16001
16012
|
}
|
|
16002
16013
|
ctx.wallSealed = true;
|
|
16003
16014
|
ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
|
|
@@ -16082,9 +16093,9 @@ var init_wall = __esm(() => {
|
|
|
16082
16093
|
|
|
16083
16094
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
16084
16095
|
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";
|
|
16085
|
-
import { dirname as dirname26, join as join61, relative as
|
|
16096
|
+
import { dirname as dirname26, join as join61, relative as relative13, sep as sep14 } from "path";
|
|
16086
16097
|
function safeRestore(repoDir, f, want, mode) {
|
|
16087
|
-
const root = realpathSync23(repoDir), fp = join61(root, f), rel =
|
|
16098
|
+
const root = realpathSync23(repoDir), fp = join61(root, f), rel = relative13(root, dirname26(fp));
|
|
16088
16099
|
if (rel.startsWith(".."))
|
|
16089
16100
|
throw new Error("outside repo");
|
|
16090
16101
|
let cur = root;
|
|
@@ -17082,7 +17093,7 @@ var init_supply_guard = __esm(() => {
|
|
|
17082
17093
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
17083
17094
|
import { createHash as createHash18 } from "crypto";
|
|
17084
17095
|
import { existsSync as existsSync47, readdirSync as readdirSync24, mkdirSync as mkdirSync31, readFileSync as readFileSync55 } from "fs";
|
|
17085
|
-
import { basename as basename26, isAbsolute as
|
|
17096
|
+
import { basename as basename26, isAbsolute as isAbsolute13, join as join69, relative as relative14 } from "path";
|
|
17086
17097
|
function receiptSha256(r) {
|
|
17087
17098
|
const { verification: _v, receipt_sha256: _h, ...body } = r;
|
|
17088
17099
|
return sha2562(canonicalJson(body));
|
|
@@ -17155,8 +17166,8 @@ function renderReceiptMd(r) {
|
|
|
17155
17166
|
`);
|
|
17156
17167
|
}
|
|
17157
17168
|
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) => {
|
|
17158
|
-
const r =
|
|
17159
|
-
return r.startsWith("..") ||
|
|
17169
|
+
const r = relative14(ctx.repoDir, join69(ctx.runDir, "receipt.json"));
|
|
17170
|
+
return r.startsWith("..") || isAbsolute13(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
17160
17171
|
}, commitStage, wallGreenOnBaseOf = (o) => {
|
|
17161
17172
|
const b = o.wall?.base_run ?? {};
|
|
17162
17173
|
return typeof b.pass === "number" && b.pass > 0 && b.fail === 0 && (typeof b.not_run === "number" ? b.not_run : 0) === 0;
|
|
@@ -24351,6 +24362,45 @@ var DENIED_TOOLS = [
|
|
|
24351
24362
|
"Bash(git -C:*)",
|
|
24352
24363
|
"Bash(git --git-dir:*)",
|
|
24353
24364
|
"Bash(git -c:*)",
|
|
24365
|
+
"Bash(git --exec-path:*)",
|
|
24366
|
+
"Bash(git diff --output:*)",
|
|
24367
|
+
"Bash(git diff --output=:*)",
|
|
24368
|
+
"Bash(git diff --ext-diff:*)",
|
|
24369
|
+
"Bash(git diff --no-index:*)",
|
|
24370
|
+
"Bash(git log --output:*)",
|
|
24371
|
+
"Bash(git log --output=:*)",
|
|
24372
|
+
"Bash(git log --ext-diff:*)",
|
|
24373
|
+
"Bash(git show --output:*)",
|
|
24374
|
+
"Bash(git show --output=:*)",
|
|
24375
|
+
"Bash(git show --ext-diff:*)",
|
|
24376
|
+
"Bash(git blame --output:*)",
|
|
24377
|
+
"Bash(git blame --output=:*)",
|
|
24378
|
+
"Bash(rg --pre:*)",
|
|
24379
|
+
"Bash(rg --pre=:*)",
|
|
24380
|
+
"Bash(rg --pre-glob:*)",
|
|
24381
|
+
"Bash(rg --pre-glob=:*)",
|
|
24382
|
+
"Bash(rg --hostname-bin:*)",
|
|
24383
|
+
"Bash(rg --hostname-bin=:*)",
|
|
24384
|
+
"Bash(find -delete:*)",
|
|
24385
|
+
"Bash(find -exec:*)",
|
|
24386
|
+
"Bash(find -execdir:*)",
|
|
24387
|
+
"Bash(find -ok:*)",
|
|
24388
|
+
"Bash(find -fprint:*)",
|
|
24389
|
+
"Bash(find -fprintf:*)",
|
|
24390
|
+
"Bash(find -fls:*)",
|
|
24391
|
+
"Bash(git * --output*)",
|
|
24392
|
+
"Bash(git * --ext-diff*)",
|
|
24393
|
+
"Bash(git * --no-index*)",
|
|
24394
|
+
"Bash(rg * --pre*)",
|
|
24395
|
+
"Bash(rg * --hostname-bin*)",
|
|
24396
|
+
"Bash(rg --pre*)",
|
|
24397
|
+
"Bash(rg --hostname-bin*)",
|
|
24398
|
+
"Bash(find * -delete*)",
|
|
24399
|
+
"Bash(find * -exec*)",
|
|
24400
|
+
"Bash(find * -execdir*)",
|
|
24401
|
+
"Bash(find * -fprint*)",
|
|
24402
|
+
"Bash(find * -fls*)",
|
|
24403
|
+
"Bash(find * -ok*)",
|
|
24354
24404
|
"Bash",
|
|
24355
24405
|
"WebFetch",
|
|
24356
24406
|
"WebSearch",
|
|
@@ -21,9 +21,16 @@ export function resolveToolsServer(startDir: string): string | null {
|
|
|
21
21
|
export const ALLOWED_TOOLS = `mcp__${MCP_SERVER_NAME}__*`;
|
|
22
22
|
|
|
23
23
|
// Deny wins over allow in claude. Includes the loki-ts review denylist tokens (mutation forms) and every built-in that can touch files, a shell, the web or sub-agents.
|
|
24
|
+
// Mirror of REVIEW_GUARD_DENYLIST (loki-ts/src/providers/claude_flags.ts). The control-plane package ships alone (its Docker image has no loki-ts), so it cannot import it;
|
|
25
|
+
// test/server/ask_policy.test.ts fails and names every missing token when the two drift (FC-CP-DENYLIST-DRIFT).
|
|
24
26
|
export const DENIED_TOOLS = [
|
|
25
|
-
"Edit", "Write", "NotebookEdit",
|
|
26
|
-
"Bash(git
|
|
27
|
+
"Edit", "Write", "NotebookEdit", "Bash(git commit:*)", "Bash(git reset:*)", "Bash(git push:*)", "Bash(git checkout:*)", "Bash(git clean:*)", "Bash(git rm:*)", "Bash(git stash:*)", "Bash(git -C:*)",
|
|
28
|
+
"Bash(git --git-dir:*)", "Bash(git -c:*)", "Bash(git --exec-path:*)", "Bash(git diff --output:*)", "Bash(git diff --output=:*)", "Bash(git diff --ext-diff:*)", "Bash(git diff --no-index:*)",
|
|
29
|
+
"Bash(git log --output:*)", "Bash(git log --output=:*)", "Bash(git log --ext-diff:*)", "Bash(git show --output:*)", "Bash(git show --output=:*)", "Bash(git show --ext-diff:*)",
|
|
30
|
+
"Bash(git blame --output:*)", "Bash(git blame --output=:*)", "Bash(rg --pre:*)", "Bash(rg --pre=:*)", "Bash(rg --pre-glob:*)", "Bash(rg --pre-glob=:*)", "Bash(rg --hostname-bin:*)",
|
|
31
|
+
"Bash(rg --hostname-bin=:*)", "Bash(find -delete:*)", "Bash(find -exec:*)", "Bash(find -execdir:*)", "Bash(find -ok:*)", "Bash(find -fprint:*)", "Bash(find -fprintf:*)", "Bash(find -fls:*)",
|
|
32
|
+
"Bash(git * --output*)", "Bash(git * --ext-diff*)", "Bash(git * --no-index*)", "Bash(rg * --pre*)", "Bash(rg * --hostname-bin*)", "Bash(rg --pre*)", "Bash(rg --hostname-bin*)",
|
|
33
|
+
"Bash(find * -delete*)", "Bash(find * -exec*)", "Bash(find * -execdir*)", "Bash(find * -fprint*)", "Bash(find * -fls*)", "Bash(find * -ok*)",
|
|
27
34
|
"Bash", "WebFetch", "WebSearch", "Task", "Read", "Grep", "Glob",
|
|
28
35
|
].join(",");
|
|
29
36
|
|
|
@@ -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.99",
|
|
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-CnWjN0Ms.js";import{B as C}from"./Button-CFwG7fak.js";import{T as $e}from"./trending-up-PkkVVpMi.js";import{C as z}from"./clock-CTfYZuHT.js";import{A as Be,U as ue,M as De}from"./Avatar-rCCQR-SZ.js";import{A as J}from"./activity-DqTXb5xR.js";import{R as pe}from"./refresh-cw-CIZSiLmc.js";import{G as ze}from"./globe-Bz38POnM.js";import{C as Le}from"./chevron-left-CG9JI3Un.js";import{C as je}from"./check-E-mC9uGB.js";import{D as Y}from"./dollar-sign-Buovjluk.js";import{U as Te}from"./user-D_3xowXu.js";import{D as Me}from"./database-BVupYiyp.js";import{L as Ue}from"./lock-BYyyOsOt.js";import{S as Re}from"./scroll-text-Scmlp_4R.js";import{S as Ie}from"./shield-alert-BE0_s4mo.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-CnWjN0Ms.js";import{C as r}from"./clock-CTfYZuHT.js";import{C as a}from"./circle-alert-uLOdudrY.js";import{C as l}from"./check-E-mC9uGB.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-CnWjN0Ms.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-CnWjN0Ms.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DZ0DjicT.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-DrNJGF29.js";import{C as oe}from"./check-E-mC9uGB.js";import{C as Ye}from"./clock-CTfYZuHT.js";import{D as Xe}from"./dollar-sign-Buovjluk.js";import{U as Ze}from"./upload-HzVQ78Nw.js";import{L as V}from"./loader-circle-B4pVqJjl.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-CNMmdSPA.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-CnWjN0Ms.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-BQMuZ040.js → EvidenceReceiptPanel-B9r_xHvw.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-CnWjN0Ms.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-CnWjN0Ms.js";import{B as N}from"./Button-CFwG7fak.js";import{C as y}from"./thumbs-up-DrNJGF29.js";import{R as S}from"./refresh-cw-CIZSiLmc.js";import{C as z}from"./circle-alert-uLOdudrY.js";import{U as D}from"./user-D_3xowXu.js";import{L as G}from"./loader-circle-B4pVqJjl.js";import{R as T}from"./rotate-ccw-eFQJMvH2.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-CnWjN0Ms.js";import{B as y}from"./Button-CFwG7fak.js";import{C as ge}from"./chevron-left-CG9JI3Un.js";import{G as P}from"./thumbs-up-DrNJGF29.js";import{R as $}from"./refresh-cw-CIZSiLmc.js";import{C as Ne}from"./circle-alert-uLOdudrY.js";import{L as Q,S as je}from"./ProjectPage-CW4IMU4E.js";import{S as se}from"./shield-alert-BE0_s4mo.js";import{F as ye}from"./file-code-corner-CZxdOs7f.js";import{C as V}from"./clock-CTfYZuHT.js";import{C as re}from"./check-E-mC9uGB.js";import"./ErrorBoundary-DZ0DjicT.js";import"./TerminalOutput-B2TSSpbN.js";import"./lock-BYyyOsOt.js";import"./package-D3g7EPnP.js";import"./file-plus-CLoz9fGY.js";import"./activity-DqTXb5xR.js";import"./scroll-text-Scmlp_4R.js";import"./bot-LHRcGGY4.js";import"./loader-circle-B4pVqJjl.js";import"./hammer-BcdWir52.js";import"./dollar-sign-Buovjluk.js";import"./globe-Bz38POnM.js";import"./trash-2-BmIPNtTb.js";import"./upload-HzVQ78Nw.js";import"./plus-BWn9Hhkg.js";import"./rotate-ccw-eFQJMvH2.js";import"./code-xml-DdiAYav6.js";import"./trending-up-PkkVVpMi.js";import"./layers-B4JZh2PQ.js";import"./trending-down-CwXb1mRC.js";import"./server-kRjjEnwM.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|