loki-mode 11.17.39 → 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 +51 -1
- package/autonomy/loki +46 -36
- package/completions/_loki +1 -0
- package/completions/loki.bash +1 -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 +26 -24
- package/docs/v10/FAILURE-CLASSES.md +7 -0
- package/docs/v10/PROGRESS.md +6 -0
- package/loki-ts/dist/loki.js +1156 -1119
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +188 -55
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-sMRXVp8V.js → AdminPage-BSR_64u1.js} +1 -1
- package/web-app/dist/assets/{Avatar-sqshsKDj.js → Avatar-CnSNZSx6.js} +1 -1
- package/web-app/dist/assets/{Badge-DVLT6AZl.js → Badge-C7p_bqIO.js} +1 -1
- package/web-app/dist/assets/{Button-CUGOx2F-.js → Button-5CI0TYxR.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-_5XpWSyB.js → CockpitPage-CeiR5rfl.js} +1 -1
- package/web-app/dist/assets/{ComparePage-CHybAwF6.js → ComparePage-Cwh3wcqg.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-yws0dvvJ.js → ErrorBoundary-VZcsEDJl.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DQPXKaYq.js → EvidenceReceiptPanel-Cf5DXTqo.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-CDnklfFn.js → GitHubIssuesPanel-C8pxgZhD.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-F1H3q6Mg.js → GitHubPRsPanel-Dfrm9QTz.js} +1 -1
- package/web-app/dist/assets/{HomePage-Donxu3UG.js → HomePage-Be-Hq5wb.js} +2 -2
- package/web-app/dist/assets/{LoginPage-vabZaQ4T.js → LoginPage-DijL2orB.js} +1 -1
- package/web-app/dist/assets/{MagicPage-zJiSFKm6.js → MagicPage-x-KpX3Zk.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-tW1d9Pc4.js → MetricsPage-uoMG8P0x.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-DfL2kcAp.js → NotFoundPage-DmW2a7pG.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-Bnx3Slii.js → ProjectPage-zpARxbll.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C74jNljb.js → ProjectsPage-5dTAn3K7.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-FA9_6XvR.js → SettingsPage-ptKy_Tbu.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-CUYKoPB0.js → ShowcasePage-BkM5b-6b.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-ClEk_OL-.js → SystemSettingsPage-BbaZ8aqC.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-CZod1nxw.js → TeamsPage-CBgDSDWj.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-ftxcEJ5S.js → TemplatesPage-IdBOifb1.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-C-ztoDne.js → TerminalOutput-iLcaELwj.js} +1 -1
- package/web-app/dist/assets/{activity-ClWb6nuh.js → activity-Di09VZ-C.js} +1 -1
- package/web-app/dist/assets/{bell-DSdTj9Kf.js → bell-CuHhohwY.js} +1 -1
- package/web-app/dist/assets/{bot-DX8ebhTj.js → bot-pGvyFisf.js} +1 -1
- package/web-app/dist/assets/{check-6OAuuO_W.js → check-DYPycZns.js} +1 -1
- package/web-app/dist/assets/{chevron-left-DTdjxSL_.js → chevron-left-lKRP1pKT.js} +1 -1
- package/web-app/dist/assets/{circle-alert-B40DtHik.js → circle-alert-D1rDQ9mD.js} +1 -1
- package/web-app/dist/assets/{clock-cVEP2obv.js → clock-BGhPbAAa.js} +1 -1
- package/web-app/dist/assets/{cloud-CmG80ODy.js → cloud-WsT8-0Fu.js} +1 -1
- package/web-app/dist/assets/{code-xml-uDISZWZx.js → code-xml-DtutBX9b.js} +1 -1
- package/web-app/dist/assets/{database-BBjrBzZH.js → database-LiEeNmyC.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-QuSiEBvi.js → dollar-sign-adGlfVLa.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DaYWw_54.js → file-code-corner-DY5GkQGM.js} +1 -1
- package/web-app/dist/assets/{file-plus-DBrjgfG0.js → file-plus-RLd_hPU8.js} +1 -1
- package/web-app/dist/assets/{globe-yLg95rUG.js → globe-CQvcGE8E.js} +1 -1
- package/web-app/dist/assets/{hammer-Cm_tQ3f7.js → hammer-BWOWu2Hf.js} +1 -1
- package/web-app/dist/assets/{index-WwgJyEgR.js → index-BBV2psih.js} +3 -3
- package/web-app/dist/assets/{layers-CVu0QAr_.js → layers-C_cj_ShX.js} +1 -1
- package/web-app/dist/assets/{loader-circle-C1ByA4HR.js → loader-circle-BpyfPEFt.js} +1 -1
- package/web-app/dist/assets/{lock-COFCj4kU.js → lock-Bivqy2kG.js} +1 -1
- package/web-app/dist/assets/{package-DPdWCR4l.js → package-DvDJIgWs.js} +1 -1
- package/web-app/dist/assets/{plus-CP2Oh8yP.js → plus-CVjTmPiU.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CR9Wf9cI.js → refresh-cw-DPEeU-0s.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-jJugFDir.js → rotate-ccw-DZX_aED8.js} +1 -1
- package/web-app/dist/assets/{scroll-text-BiJUO5k9.js → scroll-text-BBMfK4J7.js} +1 -1
- package/web-app/dist/assets/{server-US70f4RI.js → server-Bq18pHWE.js} +1 -1
- package/web-app/dist/assets/{shield-alert-C7ig1ziQ.js → shield-alert-Dc5xbnOx.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-D3SDwx7o.js → thumbs-up-4nFvjqQ-.js} +1 -1
- package/web-app/dist/assets/{trash-2-CikJqAs_.js → trash-2-SjUKL3ek.js} +1 -1
- package/web-app/dist/assets/{trending-down-Bcyok37Q.js → trending-down-B7_1Kuct.js} +1 -1
- package/web-app/dist/assets/{trending-up-CFJbw392.js → trending-up-DgRWrCNb.js} +1 -1
- package/web-app/dist/assets/{upload-BvhLwHkC.js → upload-Cs07lSfb.js} +1 -1
- package/web-app/dist/assets/{usePolling-Bck_ydy1.js → usePolling-BAUxt1Nu.js} +1 -1
- package/web-app/dist/assets/{user-BpuwYFeB.js → user-DC2T8RYB.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -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]"],
|
|
@@ -145,11 +145,18 @@ var init_redact = __esm(() => {
|
|
|
145
145
|
[/AKIA[0-9A-Z]{16}/g, "[REDACTED:AWS_KEY]"],
|
|
146
146
|
[/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[REDACTED:JWT]"],
|
|
147
147
|
[/AI[a-zA-Z0-9_-]{30,}/g, "[REDACTED:GOOGLE_KEY]"],
|
|
148
|
+
[/glpat-[A-Za-z0-9_-]{20,}/g, "[REDACTED:GITLAB_TOKEN]"],
|
|
149
|
+
[/npm_[A-Za-z0-9]{36}/g, "[REDACTED:NPM_TOKEN]"],
|
|
150
|
+
[/hf_[A-Za-z0-9]{30,}/g, "[REDACTED:HF_TOKEN]"],
|
|
151
|
+
[/[sr]k_live_[A-Za-z0-9]{16,}/g, "[REDACTED:STRIPE_KEY]"],
|
|
152
|
+
[/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g, "[REDACTED:PRIVATE_KEY]"],
|
|
148
153
|
[/sk-[A-Za-z0-9_-]{20,}/g, "[REDACTED:OPENAI_KEY]"],
|
|
149
154
|
[/(Bearer\s+)[A-Za-z0-9._~+/=-]{20,}/g, "$1[REDACTED]"],
|
|
150
155
|
[/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/?#@]+@/gi, "$1[REDACTED]@"],
|
|
151
156
|
[/(\bAuthorization\s*[:=]\s*)(?:Basic|Bearer|Token|Digest)?\s*[^\s,;"']+/gi, "$1[REDACTED]"]
|
|
152
157
|
];
|
|
158
|
+
QUERY_SEGMENT = /\?[^\s#"'<>]+/g;
|
|
159
|
+
SECRET_PARAM = /([?&](?:access_token|token|api_key|apikey|password|secret|sig)=)[^&\s#"']*/gi;
|
|
153
160
|
});
|
|
154
161
|
|
|
155
162
|
// ../../loki-ts/src/util/credential_env.ts
|
|
@@ -10018,7 +10025,41 @@ function summaryOf(a) {
|
|
|
10018
10025
|
}
|
|
10019
10026
|
function markExecuted(a, executed) {
|
|
10020
10027
|
const checks_deferred = deferredOf(a.tier, a.checks_selected, executed);
|
|
10021
|
-
return { ...a, checks_deferred, summary: summaryOf({ ...a, checks_deferred }) };
|
|
10028
|
+
return { ...a, checks_deferred, summary: summaryOf({ ...a, checks_deferred }) + (a.advisories?.length ? `; advisory: ${a.advisories.join(", ")}` : "") };
|
|
10029
|
+
}
|
|
10030
|
+
function manifestDepsChanged(path, oldText, newText, patch) {
|
|
10031
|
+
if (/(^|\/)package\.json$/.test(path)) {
|
|
10032
|
+
try {
|
|
10033
|
+
const o = oldText.trim() ? JSON.parse(oldText) : {}, n2 = newText.trim() ? JSON.parse(newText) : {};
|
|
10034
|
+
return PKG_DEP_KEYS.some((k) => JSON.stringify(o?.[k] ?? {}) !== JSON.stringify(n2?.[k] ?? {}));
|
|
10035
|
+
} catch {
|
|
10036
|
+
return true;
|
|
10037
|
+
}
|
|
10038
|
+
}
|
|
10039
|
+
const changed = patch.split(`
|
|
10040
|
+
`).filter((l) => /^[+-]/.test(l) && !/^(\+\+\+|---)/.test(l));
|
|
10041
|
+
if (/(^|\/)go\.mod$/.test(path))
|
|
10042
|
+
return changed.some((l) => {
|
|
10043
|
+
const b = l.slice(1).trim();
|
|
10044
|
+
return b !== "" && !b.startsWith("//") && !/^(module|go|toolchain)\b/.test(b);
|
|
10045
|
+
});
|
|
10046
|
+
return changed.some((l) => {
|
|
10047
|
+
const b = l.slice(1).trim();
|
|
10048
|
+
if (/^"[A-Za-z][\w.-]*(\[[\w,.-]+\])?\s*([<>=~!]|;|@|"\s*,?\s*$)/.test(b))
|
|
10049
|
+
return true;
|
|
10050
|
+
const m = /^([A-Za-z][\w.-]*)\s*=\s*("[\^~<>=!*\d]|\{[^}]*version)/.exec(b);
|
|
10051
|
+
return !!m && !PYPROJECT_NONDEP.test(m[1]);
|
|
10052
|
+
});
|
|
10053
|
+
}
|
|
10054
|
+
function manifestsWithoutLock(files) {
|
|
10055
|
+
return files.filter((f) => f.deps && f.status !== "deleted").flatMap((f) => {
|
|
10056
|
+
const pair = MANIFEST_LOCKS.find(([m]) => m.test(f.path));
|
|
10057
|
+
if (!pair)
|
|
10058
|
+
return [];
|
|
10059
|
+
const d = dirOf(f.path);
|
|
10060
|
+
const locked = files.some((g) => pair[1].test(g.path) && (dirOf(g.path) === "" || d === dirOf(g.path) || d.startsWith(dirOf(g.path) + "/")));
|
|
10061
|
+
return locked ? [] : [f.path];
|
|
10062
|
+
});
|
|
10022
10063
|
}
|
|
10023
10064
|
function classifyRisk(files, env = process.env) {
|
|
10024
10065
|
const lines = files.reduce((n2, f) => n2 + f.added + f.deleted, 0);
|
|
@@ -10063,7 +10104,8 @@ function classifyRisk(files, env = process.env) {
|
|
|
10063
10104
|
ignored = `LOKI_RISK_TIER=${asked} ignored: lowering from ${computed} needs LOKI_RISK_OVERRIDE_REASON`;
|
|
10064
10105
|
}
|
|
10065
10106
|
const plan = PLAN[tier], checks_deferred = deferredOf(tier, plan.selected, []);
|
|
10066
|
-
const
|
|
10107
|
+
const advisories = manifestsWithoutLock(files).map((p) => `manifest changed without lockfile: ${p}`);
|
|
10108
|
+
const summary = summaryOf({ tier, computed, reasons, ...override ? { override } : {}, checks_deferred }) + (advisories.length ? `; advisory: ${advisories.join(", ")}` : "");
|
|
10067
10109
|
return {
|
|
10068
10110
|
version: 1,
|
|
10069
10111
|
tier,
|
|
@@ -10074,6 +10116,7 @@ function classifyRisk(files, env = process.env) {
|
|
|
10074
10116
|
checks_deferred,
|
|
10075
10117
|
...override ? { override } : {},
|
|
10076
10118
|
...ignored ? { override_ignored: ignored } : {},
|
|
10119
|
+
...advisories.length ? { advisories } : {},
|
|
10077
10120
|
summary
|
|
10078
10121
|
};
|
|
10079
10122
|
}
|
|
@@ -10098,7 +10141,7 @@ function diffFiles(repoDir, baseSha) {
|
|
|
10098
10141
|
if (f)
|
|
10099
10142
|
f.status = s?.startsWith("A") ? "added" : s?.startsWith("D") ? "deleted" : "modified";
|
|
10100
10143
|
}
|
|
10101
|
-
|
|
10144
|
+
const out2 = paths.map((path) => {
|
|
10102
10145
|
const f = stat.get(path);
|
|
10103
10146
|
if (f)
|
|
10104
10147
|
return f;
|
|
@@ -10109,6 +10152,20 @@ function diffFiles(repoDir, baseSha) {
|
|
|
10109
10152
|
} catch {}
|
|
10110
10153
|
return { path, added: n2, deleted: 0, status: "added" };
|
|
10111
10154
|
});
|
|
10155
|
+
for (const f of out2) {
|
|
10156
|
+
if (f.status === "deleted" || !MANIFEST_LOCKS.some(([m]) => m.test(f.path)))
|
|
10157
|
+
continue;
|
|
10158
|
+
try {
|
|
10159
|
+
const oldText = f.status === "added" ? "" : safeGit(repoDir, ["show", `${baseSha}:${f.path}`]);
|
|
10160
|
+
const newText = readFileSync29(join38(repoDir, f.path), "utf8");
|
|
10161
|
+
const patch = f.status === "added" ? newText.split(`
|
|
10162
|
+
`).map((l) => `+${l}`).join(`
|
|
10163
|
+
`) : safeGit(repoDir, ["diff", "-U0", baseSha, "--", f.path]);
|
|
10164
|
+
if (manifestDepsChanged(f.path, oldText, newText, patch))
|
|
10165
|
+
f.deps = true;
|
|
10166
|
+
} catch {}
|
|
10167
|
+
}
|
|
10168
|
+
return out2;
|
|
10112
10169
|
}
|
|
10113
10170
|
function recordRisk(repoDir, a) {
|
|
10114
10171
|
try {
|
|
@@ -10251,7 +10308,7 @@ function classify(f, status, output, repoDir, interpreter) {
|
|
|
10251
10308
|
}
|
|
10252
10309
|
var NO_TESTS_REASON = "no tests executed", GO_EXIT0_REASON = "test count could not be confirmed: go test output is produced by the code under test and cannot confirm execution (a Go exit 0 is never a pass)", UNCONFIRMED_REASON = "test count could not be confirmed", FAIL_EVIDENCE, GO_FAIL_EVIDENCE, UNMEASURED_REASON = "executed count unmeasured (Loki could not parse the runner summary, harness-owned)", stripAnsi = (s) => s.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, "").replace(/(?:\u001b\[|\u009b)[0-9;?]*[ -\/]*[@-~]/g, "").replace(/\r\n?/g, `
|
|
10253
10310
|
`), tailLines = (out2) => out2.split(`
|
|
10254
|
-
`).filter((x) => x.trim()).slice(-12), GO_PKG_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, normPath = (p) => p.replace(/^(?:\.\/)+/, ""), hasExogenousProof = (checks, ctx) => checks.some((c) => isExecutedProof(c) && ((p) => p !== "agent_authored" && p !== "llm_judge")(checkProvenance(c.name ?? "", ctx))), SENSITIVE, API, TEST_CFG, RANK2, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), EXCERPT_GROUP_CAP = 1500, EXCERPT_TOTAL_CAP = 6144;
|
|
10311
|
+
`).filter((x) => x.trim()).slice(-12), GO_PKG_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, normPath = (p) => p.replace(/^(?:\.\/)+/, ""), hasExogenousProof = (checks, ctx) => checks.some((c) => isExecutedProof(c) && ((p) => p !== "agent_authored" && p !== "llm_judge")(checkProvenance(c.name ?? "", ctx))), SENSITIVE, API, TEST_CFG, RANK2, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), MANIFEST_LOCKS, dirOf = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "", PKG_DEP_KEYS, PYPROJECT_NONDEP, EXCERPT_GROUP_CAP = 1500, EXCERPT_TOTAL_CAP = 6144;
|
|
10255
10312
|
var init_check_result = __esm(() => {
|
|
10256
10313
|
init_testmap();
|
|
10257
10314
|
init_safe_git();
|
|
@@ -10281,6 +10338,13 @@ var init_check_result = __esm(() => {
|
|
|
10281
10338
|
high: { selected: [...RAN_ALWAYS, "full test command", "full suite", "council", "security scan"] }
|
|
10282
10339
|
};
|
|
10283
10340
|
LOW_SKIPPED = ["full test command", "reviewer", "council", "security scan"];
|
|
10341
|
+
MANIFEST_LOCKS = [
|
|
10342
|
+
[/(^|\/)package\.json$/, /(^|\/)(package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/],
|
|
10343
|
+
[/(^|\/)pyproject\.toml$/, /(^|\/)(poetry\.lock|uv\.lock|pdm\.lock|Pipfile\.lock)$/],
|
|
10344
|
+
[/(^|\/)go\.mod$/, /(^|\/)go\.sum$/]
|
|
10345
|
+
];
|
|
10346
|
+
PKG_DEP_KEYS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
10347
|
+
PYPROJECT_NONDEP = /^(name|version|description|readme|license|requires-python|python|authors|maintainers|keywords|classifiers|homepage|repository|documentation|packages|include|exclude)$/;
|
|
10284
10348
|
});
|
|
10285
10349
|
|
|
10286
10350
|
// ../../loki-ts/src/runner/state.ts
|
|
@@ -10301,8 +10365,45 @@ var init_state = __esm(() => {
|
|
|
10301
10365
|
});
|
|
10302
10366
|
|
|
10303
10367
|
// ../../loki-ts/src/runner/repo_profile.ts
|
|
10304
|
-
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";
|
|
10305
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
|
+
}
|
|
10306
10407
|
function loadProfile(repoDir) {
|
|
10307
10408
|
try {
|
|
10308
10409
|
const p = JSON.parse(readFileSync30(commandProfilePath(repoDir), "utf8"));
|
|
@@ -10396,7 +10497,13 @@ async function staticPreExisting(tool, prefix, files, io) {
|
|
|
10396
10497
|
}
|
|
10397
10498
|
return attributeStatic(tool, head.out, baseOut, 1).preExisting;
|
|
10398
10499
|
}
|
|
10399
|
-
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;
|
|
10400
10507
|
var init_repo_profile = __esm(() => {
|
|
10401
10508
|
init_failures();
|
|
10402
10509
|
init_check_result();
|
|
@@ -10438,7 +10545,7 @@ var init_context = __esm(() => {
|
|
|
10438
10545
|
});
|
|
10439
10546
|
|
|
10440
10547
|
// ../../loki-ts/src/util/steer.ts
|
|
10441
|
-
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";
|
|
10442
10549
|
import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
|
|
10443
10550
|
import { basename as basename13, join as join40 } from "path";
|
|
10444
10551
|
function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
@@ -10465,7 +10572,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
|
10465
10572
|
}
|
|
10466
10573
|
}
|
|
10467
10574
|
function orphanAlreadyArchived(logs, claim) {
|
|
10468
|
-
const c =
|
|
10575
|
+
const c = lstatSync10(claim);
|
|
10469
10576
|
if (!c.isFile())
|
|
10470
10577
|
return false;
|
|
10471
10578
|
for (const a of readdirSync15(logs)) {
|
|
@@ -10567,7 +10674,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10567
10674
|
hooks2?.beforeRestore?.();
|
|
10568
10675
|
let restored = false;
|
|
10569
10676
|
try {
|
|
10570
|
-
if (
|
|
10677
|
+
if (lstatSync10(claimed).isDirectory())
|
|
10571
10678
|
renameSync10(claimed, f);
|
|
10572
10679
|
else
|
|
10573
10680
|
(hooks2?.link ?? linkSync2)(claimed, f);
|
|
@@ -10576,7 +10683,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10576
10683
|
if (!restored)
|
|
10577
10684
|
return reject("NOTFILE", "not a regular file");
|
|
10578
10685
|
try {
|
|
10579
|
-
if (!
|
|
10686
|
+
if (!lstatSync10(claimed, { throwIfNoEntry: false })?.isDirectory())
|
|
10580
10687
|
unlinkSync5(claimed);
|
|
10581
10688
|
} catch {}
|
|
10582
10689
|
claimed = "";
|
|
@@ -10586,7 +10693,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10586
10693
|
try {
|
|
10587
10694
|
fd = openSync8(claimed, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
|
|
10588
10695
|
} catch (e) {
|
|
10589
|
-
const l =
|
|
10696
|
+
const l = lstatSync10(claimed, { throwIfNoEntry: false });
|
|
10590
10697
|
if (!l)
|
|
10591
10698
|
throw e;
|
|
10592
10699
|
if (l.isSymbolicLink() || e.code === "ELOOP") {
|
|
@@ -10641,7 +10748,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
10641
10748
|
}
|
|
10642
10749
|
} else
|
|
10643
10750
|
try {
|
|
10644
|
-
if (
|
|
10751
|
+
if (lstatSync10(f, { throwIfNoEntry: false }))
|
|
10645
10752
|
unapplied("logs dir unwritable or file unreadable");
|
|
10646
10753
|
} catch {}
|
|
10647
10754
|
return null;
|
|
@@ -10991,7 +11098,7 @@ var init_shell = __esm(() => {
|
|
|
10991
11098
|
|
|
10992
11099
|
// ../../loki-ts/src/util/python.ts
|
|
10993
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";
|
|
10994
|
-
import { spawnSync as
|
|
11101
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
10995
11102
|
import { tmpdir as tmpdir5 } from "os";
|
|
10996
11103
|
async function findPython3() {
|
|
10997
11104
|
if (_pythonCache !== undefined)
|
|
@@ -11028,7 +11135,7 @@ function pySignatures(src) {
|
|
|
11028
11135
|
const py = resolvePython3();
|
|
11029
11136
|
if (!py)
|
|
11030
11137
|
return [];
|
|
11031
|
-
const r =
|
|
11138
|
+
const r = spawnSync3(py, ["-I", "-S", "-c", PY_SCRIPT], {
|
|
11032
11139
|
input: src.replace(/\r\n?/g, `
|
|
11033
11140
|
`),
|
|
11034
11141
|
cwd: tmpdir5(),
|
|
@@ -11248,14 +11355,14 @@ function importsNamed(path, raw2, stems, importStems = stems, hits = () => false
|
|
|
11248
11355
|
for (const m of py.matchAll(/(?:^|:)[ \t\f]*import[ \t\f]+([^\n#;]+?)[ \t\f]*(?:#.*)?$/gm))
|
|
11249
11356
|
specs.push(...names(m[1]));
|
|
11250
11357
|
}
|
|
11251
|
-
const dir =
|
|
11358
|
+
const dir = dirOf2(path);
|
|
11252
11359
|
if (specs.some((s) => s.trim().startsWith(".") && hits(resolveRel(dir, s.trim()))))
|
|
11253
11360
|
return true;
|
|
11254
11361
|
for (const py of views)
|
|
11255
11362
|
for (const m of py.matchAll(/(?:^|:)[ \t\f]*from[ \t\f]+(\.+)([\w.]*?)[ \t\f]*\bimport\b[ \t\f]*(?:\(([^)]*)\)|([^\n]*))/gm)) {
|
|
11256
11363
|
let base = dir;
|
|
11257
11364
|
for (let i = 1;i < m[1].length; i++)
|
|
11258
|
-
base =
|
|
11365
|
+
base = dirOf2(base);
|
|
11259
11366
|
const r = resolveRel(base, (m[2] ?? "").replace(/\./g, "/"));
|
|
11260
11367
|
if (hits(r) || names(m[3] ?? m[4] ?? "").some((n2) => hits(resolveRel(r, n2))))
|
|
11261
11368
|
return true;
|
|
@@ -11293,13 +11400,13 @@ function buildWallManifest(files, taskModules, alsoNamed = []) {
|
|
|
11293
11400
|
const s = stemsOfTarget(m);
|
|
11294
11401
|
return s.length > 1 ? s.slice(1) : s;
|
|
11295
11402
|
}));
|
|
11296
|
-
const info = excl.map((m) => ({ noext: m.replace(/\.[^./]*$/, "").toLowerCase(), dir:
|
|
11403
|
+
const info = excl.map((m) => ({ noext: m.replace(/\.[^./]*$/, "").toLowerCase(), dir: dirOf2(m).toLowerCase(), mod: !!dirOf2(m) && ["index", "__init__", "mod", "main"].includes(stemOf(m).toLowerCase()), src: !TEST_FILE.test(m) }));
|
|
11297
11404
|
const hits = (r) => {
|
|
11298
11405
|
const low = r.toLowerCase().replace(/\.(?:[cm]?[jt]sx?|py)$/, "");
|
|
11299
11406
|
return [low, low.replace(/\/(?:index|__init__|mod|main)$/, "")].some((v) => info.some((t) => v === t.noext || t.mod && v === t.dir || v === "" || t.noext.startsWith(`${v}/`)));
|
|
11300
11407
|
};
|
|
11301
11408
|
const inTargetArea = (p) => {
|
|
11302
|
-
const d =
|
|
11409
|
+
const d = dirOf2(p).toLowerCase();
|
|
11303
11410
|
return info.some((t) => t.src && (d === t.dir || t.mod && d.startsWith(`${t.dir}/`)));
|
|
11304
11411
|
};
|
|
11305
11412
|
const backstop = [...stems].filter((s) => !GENERIC_STEMS.includes(s));
|
|
@@ -11321,7 +11428,7 @@ function buildWallManifest(files, taskModules, alsoNamed = []) {
|
|
|
11321
11428
|
var MANIFEST_MAX_LINES = 400, MAX_EXAMPLES = 2, EXAMPLE_LINES = 40, MAX_LAYOUT = 60, TEST_PATH, TEST_FILE, EXAMPLE_EXT, baseOf = (p) => p.split("/").pop() ?? p, normStem = (s) => s.toLowerCase().replace(/[._-]+/g, ".").replace(/^\.|\.$/g, ""), GENERIC_STEMS, mentionsStem = (content, stems) => {
|
|
11322
11429
|
const c = content.toLowerCase().replace(/[._-]+/g, ".");
|
|
11323
11430
|
return stems.some((s) => new RegExp(`(?<![a-z0-9])${s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![a-z0-9])`).test(c));
|
|
11324
|
-
},
|
|
11431
|
+
}, dirOf2 = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "", resolveRel = (dir, spec) => {
|
|
11325
11432
|
const out2 = dir ? dir.split("/") : [];
|
|
11326
11433
|
for (const seg of spec.split("/")) {
|
|
11327
11434
|
if (seg === "" || seg === ".")
|
|
@@ -12125,6 +12232,21 @@ out("value-change" if ok and items else "weakened", items if ok else [])
|
|
|
12125
12232
|
`;
|
|
12126
12233
|
});
|
|
12127
12234
|
|
|
12235
|
+
// ../../loki-ts/src/e10ext/select.ts
|
|
12236
|
+
function refName(t) {
|
|
12237
|
+
return `${t.runner}:${t.path}`;
|
|
12238
|
+
}
|
|
12239
|
+
function failedFirst(tests, prior) {
|
|
12240
|
+
const red = new Set((prior ?? []).filter((c) => c.result === "fail" && typeof c.name === "string").map((c) => c.name));
|
|
12241
|
+
if (red.size === 0)
|
|
12242
|
+
return tests;
|
|
12243
|
+
return [...tests.filter((t) => red.has(refName(t))), ...tests.filter((t) => !red.has(refName(t)))];
|
|
12244
|
+
}
|
|
12245
|
+
var PYTEST_COLLECTION_EXITS;
|
|
12246
|
+
var init_select = __esm(() => {
|
|
12247
|
+
PYTEST_COLLECTION_EXITS = new Set([2, 3, 4, 5]);
|
|
12248
|
+
});
|
|
12249
|
+
|
|
12128
12250
|
// ../../loki-ts/src/runner/runner_errors.ts
|
|
12129
12251
|
function hasRealTestFailure(out2) {
|
|
12130
12252
|
return /^\s*Tests:?\s+.*\b[1-9]\d* failed\b/m.test(out2) || /^(?:=+ )?.*\b[1-9]\d* failed\b.* in [\d.]+s/m.test(out2) || /^FAILED \S+::/m.test(out2) || /^(?:#|\u2139) fail [1-9]/m.test(out2) || /^\s*[1-9]\d*\s+fail\s*$/m.test(out2) || /^\s*(?:FAIL|\u00D7)\s+\S.*\s>\s/m.test(out2) || /\bAssertionError\b/.test(out2);
|
|
@@ -12164,7 +12286,7 @@ var init_runner_errors = __esm(() => {
|
|
|
12164
12286
|
});
|
|
12165
12287
|
|
|
12166
12288
|
// ../../loki-ts/src/runner/load_owner.ts
|
|
12167
|
-
import { spawnSync as
|
|
12289
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
12168
12290
|
import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync19, rmSync as rmSync14 } from "fs";
|
|
12169
12291
|
import { tmpdir as tmpdir8 } from "os";
|
|
12170
12292
|
import { basename as basename18, extname as extname2, join as join46 } from "path";
|
|
@@ -12209,7 +12331,7 @@ function sameLoadError(head, base, headRoots, baseRoots) {
|
|
|
12209
12331
|
function killTree(pid) {
|
|
12210
12332
|
const all = [pid];
|
|
12211
12333
|
for (let k = 0;k < all.length; k++) {
|
|
12212
|
-
const kids =
|
|
12334
|
+
const kids = spawnSync4("pgrep", ["-P", String(all[k])], { encoding: "utf8", env: process.env }).stdout.split(/\s+/).filter(Boolean).map(Number);
|
|
12213
12335
|
all.push(...kids.filter((x) => Number.isInteger(x) && !all.includes(x)));
|
|
12214
12336
|
}
|
|
12215
12337
|
try {
|
|
@@ -12357,7 +12479,7 @@ var init_wall_owned = __esm(() => {
|
|
|
12357
12479
|
});
|
|
12358
12480
|
|
|
12359
12481
|
// ../../loki-ts/src/util/app_probe.ts
|
|
12360
|
-
import { spawnSync as
|
|
12482
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
12361
12483
|
import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync37, renameSync as renameSync11, writeFileSync as writeFileSync21 } from "fs";
|
|
12362
12484
|
import { join as join48 } from "path";
|
|
12363
12485
|
function readJson4(p) {
|
|
@@ -12372,7 +12494,7 @@ function stopApp(repoDir, opts = {}) {
|
|
|
12372
12494
|
const runner = opts.runnerPath ?? join48(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
12373
12495
|
if (!existsSync29(runner) || !existsSync29(join48(repoDir, ".loki", "app-runner", "app.pid")))
|
|
12374
12496
|
return;
|
|
12375
|
-
|
|
12497
|
+
spawnSync5("bash", ["-c", STOP, "app-probe", repoDir, runner], { cwd: repoDir, env: plainTestEnv(), timeout: opts.timeoutMs ?? 60000, killSignal: "SIGKILL", stdio: "ignore" });
|
|
12376
12498
|
}
|
|
12377
12499
|
async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
12378
12500
|
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ?? join48(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
@@ -12380,7 +12502,7 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
12380
12502
|
const t0 = Date.now();
|
|
12381
12503
|
const mk2 = (name, result, reason) => ({ name, cmd: "autonomy/app-runner.sh", result, duration_s: (Date.now() - t0) / 1000, reason });
|
|
12382
12504
|
const sh = (script) => {
|
|
12383
|
-
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"] });
|
|
12384
12506
|
return { out: r.stdout ?? "", status: r.error ? null : r.status };
|
|
12385
12507
|
};
|
|
12386
12508
|
let pid = null, url = null;
|
|
@@ -12425,7 +12547,7 @@ async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
|
12425
12547
|
return res("not_run", "python3 or functional-verify.py unavailable");
|
|
12426
12548
|
const specFile = join48(dir, "spec.txt");
|
|
12427
12549
|
writeFileSync21(specFile, opts.specText ?? "");
|
|
12428
|
-
const r =
|
|
12550
|
+
const r = spawnSync5(py, ["-I", script, specFile, url], { env: plainTestEnv(), encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
|
|
12429
12551
|
let out2 = null;
|
|
12430
12552
|
try {
|
|
12431
12553
|
const v = JSON.parse(r.stdout ?? "");
|
|
@@ -12497,13 +12619,18 @@ async function runSecureScan(targetDir, opts = {}) {
|
|
|
12497
12619
|
const findings = obj.findings;
|
|
12498
12620
|
if (res.exitCode === 1 !== findings.length > 0)
|
|
12499
12621
|
return fail(`secure-scan exit ${res.exitCode} disagrees with ${findings.length} findings`);
|
|
12622
|
+
const summary = obj.summary && typeof obj.summary === "object" ? obj.summary : undefined;
|
|
12623
|
+
const filesScanned = typeof summary?.["files_scanned"] === "number" ? summary["files_scanned"] : undefined;
|
|
12624
|
+
if (filesScanned === 0 && findings.length === 0)
|
|
12625
|
+
return { ok: false, findings: [], error: "secure-scan scanned 0 files (not_run)", filesScanned: 0, notRun: true };
|
|
12626
|
+
const meta = filesScanned === undefined ? {} : { filesScanned };
|
|
12500
12627
|
if (opts.secretsEverywhere || opts.diffBase === false)
|
|
12501
|
-
return { ok: true, findings };
|
|
12628
|
+
return { ok: true, findings, ...meta };
|
|
12502
12629
|
const added = await scanAddedLines(targetDir, { ...opts, scriptPath: script, timeoutMs });
|
|
12503
12630
|
if (!added.ok)
|
|
12504
12631
|
return added;
|
|
12505
12632
|
const seen = new Set(findings.map((f) => `${f.file}|${f.line}`));
|
|
12506
|
-
return { ok: true, findings: [...findings, ...added.findings.filter((f) => !seen.has(`${f.file}|${f.line}`))] };
|
|
12633
|
+
return { ok: true, findings: [...findings, ...added.findings.filter((f) => !seen.has(`${f.file}|${f.line}`))], ...meta };
|
|
12507
12634
|
}
|
|
12508
12635
|
if (res.exitCode !== 0 && res.exitCode !== 1 && res.exitCode !== 2 && elapsed >= timeoutMs) {
|
|
12509
12636
|
return fail(`secure-scan timed out after ${timeoutMs}ms`);
|
|
@@ -12811,7 +12938,7 @@ var init_route_block = __esm(() => {
|
|
|
12811
12938
|
// ../../loki-ts/src/features/visual_evidence.ts
|
|
12812
12939
|
import { spawn as spawn7 } from "child_process";
|
|
12813
12940
|
import { createHash as createHash13, randomBytes as randomBytes5 } from "crypto";
|
|
12814
|
-
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";
|
|
12815
12942
|
import { createServer } from "net";
|
|
12816
12943
|
import { dirname as dirname17, isAbsolute as isAbsolute8, join as join50, normalize as normalize3, relative as relative6, sep as sep12 } from "path";
|
|
12817
12944
|
function routeFor(file) {
|
|
@@ -13123,13 +13250,13 @@ test("loki e2e walkthrough", async ({ page }) => {
|
|
|
13123
13250
|
});
|
|
13124
13251
|
`, DEFAULT_BUDGET_MS = 25000, MAX_ROUTES = 5, isSymlink = (p) => {
|
|
13125
13252
|
try {
|
|
13126
|
-
return
|
|
13253
|
+
return lstatSync11(p).isSymbolicLink();
|
|
13127
13254
|
} catch {
|
|
13128
13255
|
return false;
|
|
13129
13256
|
}
|
|
13130
13257
|
}, isRegularFile = (p) => {
|
|
13131
13258
|
try {
|
|
13132
|
-
return
|
|
13259
|
+
return lstatSync11(p).isFile();
|
|
13133
13260
|
} catch {
|
|
13134
13261
|
return false;
|
|
13135
13262
|
}
|
|
@@ -13240,12 +13367,6 @@ var init_pr_lessons = __esm(() => {
|
|
|
13240
13367
|
KINDS = new Set(["pr", "receipt", "ticket", "rejected"]);
|
|
13241
13368
|
});
|
|
13242
13369
|
|
|
13243
|
-
// ../../loki-ts/src/e10ext/select.ts
|
|
13244
|
-
var PYTEST_COLLECTION_EXITS;
|
|
13245
|
-
var init_select = __esm(() => {
|
|
13246
|
-
PYTEST_COLLECTION_EXITS = new Set([2, 3, 4, 5]);
|
|
13247
|
-
});
|
|
13248
|
-
|
|
13249
13370
|
// ../../loki-ts/src/e10ext/treeswap.ts
|
|
13250
13371
|
var init_treeswap = __esm(() => {
|
|
13251
13372
|
init_safe_git();
|
|
@@ -13402,12 +13523,12 @@ var init_providers = __esm(() => {
|
|
|
13402
13523
|
});
|
|
13403
13524
|
|
|
13404
13525
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
13405
|
-
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";
|
|
13406
13527
|
import { join as join53 } from "path";
|
|
13407
13528
|
function loadRouteRecord(runDir) {
|
|
13408
13529
|
try {
|
|
13409
13530
|
const p = join53(runDir, ROUTE_RECORD_FILE);
|
|
13410
|
-
if (!existsSync34(p) || !
|
|
13531
|
+
if (!existsSync34(p) || !lstatSync12(p).isFile())
|
|
13411
13532
|
return;
|
|
13412
13533
|
const v = JSON.parse(readFileSync42(p, "utf8"));
|
|
13413
13534
|
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
|
|
@@ -13592,7 +13713,7 @@ __export(exports_deep, {
|
|
|
13592
13713
|
DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH,
|
|
13593
13714
|
DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
|
|
13594
13715
|
});
|
|
13595
|
-
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";
|
|
13596
13717
|
import { tmpdir as tmpdir10 } from "os";
|
|
13597
13718
|
import { dirname as dirname20, join as join55 } from "path";
|
|
13598
13719
|
function sessionCouncil(sessions) {
|
|
@@ -13714,7 +13835,7 @@ async function secureScanChanged(repoDir, changed, opts) {
|
|
|
13714
13835
|
const dir = mkdtempSync9(join55(tmpdir10(), "loki-deep-secure-"));
|
|
13715
13836
|
try {
|
|
13716
13837
|
for (const f of changed)
|
|
13717
|
-
if (existsSync35(join55(repoDir, f)) &&
|
|
13838
|
+
if (existsSync35(join55(repoDir, f)) && lstatSync13(join55(repoDir, f)).isFile()) {
|
|
13718
13839
|
mkdirSync23(dirname20(join55(dir, f)), { recursive: true });
|
|
13719
13840
|
copyFileSync3(join55(repoDir, f), join55(dir, f));
|
|
13720
13841
|
}
|
|
@@ -14091,6 +14212,7 @@ var init_verify = __esm(() => {
|
|
|
14091
14212
|
init_runner_config();
|
|
14092
14213
|
init_assert_delta();
|
|
14093
14214
|
init_failures();
|
|
14215
|
+
init_select();
|
|
14094
14216
|
init_load_owner();
|
|
14095
14217
|
init_sizing();
|
|
14096
14218
|
init_testmap();
|
|
@@ -14143,7 +14265,7 @@ var init_verify = __esm(() => {
|
|
|
14143
14265
|
const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute9(f.path) ? relative7(ctx.repoDir, f.path) : f.path));
|
|
14144
14266
|
const wallTests = map.tests.filter((t) => wallPaths.has(t.path));
|
|
14145
14267
|
const intake = ctx.outputs().intake, relevant2 = ctx.tests.impacted(map, namedFiles(intake?.task ?? "", loadRepoMap(intake?.repomap_ref)));
|
|
14146
|
-
const tests = dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]);
|
|
14268
|
+
const tests = failedFirst(dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]), ctx.outputs().verify?.checks);
|
|
14147
14269
|
const scopedOut = scopedOutOf(map);
|
|
14148
14270
|
if (scopedOut.length)
|
|
14149
14271
|
ctx.emit("test.scoped_out", "verify", { tests: scopedOut });
|
|
@@ -14331,7 +14453,7 @@ var readJson5 = (p) => {
|
|
|
14331
14453
|
var init_conventions = () => {};
|
|
14332
14454
|
|
|
14333
14455
|
// ../../loki-ts/src/engine10/stages/wall.ts
|
|
14334
|
-
import { spawnSync as
|
|
14456
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
14335
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";
|
|
14336
14458
|
import { tmpdir as tmpdir12 } from "os";
|
|
14337
14459
|
import { dirname as dirname23, join as join58, relative as relative8 } from "path";
|
|
@@ -14351,7 +14473,7 @@ class RealBaseTestRunner {
|
|
|
14351
14473
|
const api = this.api === undefined ? loadProjectApi(repoDir) : this.api;
|
|
14352
14474
|
for (const f of files) {
|
|
14353
14475
|
const { cmd, args, interpreter, cwd } = commandFor(f, repoDir, api);
|
|
14354
|
-
const r =
|
|
14476
|
+
const r = spawnSync6(cmd, f.runner === "pytest" ? [...args, "-rfE"] : args, { cwd, encoding: "utf8", timeout: Math.max(1000, this.timeoutMs), env: plainTestEnv() });
|
|
14355
14477
|
const status = r.error ? null : r.status;
|
|
14356
14478
|
const result = classify(f, status, stripAnsi(`${r.stdout ?? ""}
|
|
14357
14479
|
${r.stderr ?? ""}`), repoDir, interpreter);
|
|
@@ -14573,7 +14695,7 @@ var init_wall = __esm(() => {
|
|
|
14573
14695
|
});
|
|
14574
14696
|
|
|
14575
14697
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
14576
|
-
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";
|
|
14577
14699
|
import { dirname as dirname24, join as join59, relative as relative9, sep as sep13 } from "path";
|
|
14578
14700
|
function safeRestore(repoDir, f, want, mode) {
|
|
14579
14701
|
const root = realpathSync23(repoDir), fp = join59(root, f), rel = relative9(root, dirname24(fp));
|
|
@@ -14584,7 +14706,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
14584
14706
|
cur = join59(cur, part);
|
|
14585
14707
|
let st2;
|
|
14586
14708
|
try {
|
|
14587
|
-
st2 =
|
|
14709
|
+
st2 = lstatSync14(cur);
|
|
14588
14710
|
} catch {
|
|
14589
14711
|
mkdirSync25(cur);
|
|
14590
14712
|
continue;
|
|
@@ -14594,7 +14716,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
14594
14716
|
}
|
|
14595
14717
|
let st;
|
|
14596
14718
|
try {
|
|
14597
|
-
st =
|
|
14719
|
+
st = lstatSync14(fp);
|
|
14598
14720
|
} catch {
|
|
14599
14721
|
st = null;
|
|
14600
14722
|
}
|
|
@@ -14639,7 +14761,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
|
|
|
14639
14761
|
const fp = join59(repoDir, f);
|
|
14640
14762
|
try {
|
|
14641
14763
|
if (v.startsWith("!")) {
|
|
14642
|
-
const st =
|
|
14764
|
+
const st = lstatSync14(fp);
|
|
14643
14765
|
if (`!${st.size}:${st.mtimeMs}:${st.ctimeMs}` !== v)
|
|
14644
14766
|
throw new Error("changed, not snapshotted");
|
|
14645
14767
|
continue;
|
|
@@ -14655,7 +14777,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
|
|
|
14655
14777
|
try {
|
|
14656
14778
|
let m = 420;
|
|
14657
14779
|
try {
|
|
14658
|
-
const l =
|
|
14780
|
+
const l = lstatSync14(join59(repoDir, f));
|
|
14659
14781
|
if (l.isFile())
|
|
14660
14782
|
m = l.mode & 511;
|
|
14661
14783
|
} catch {}
|
|
@@ -14692,9 +14814,10 @@ import { dirname as dirname25 } from "path";
|
|
|
14692
14814
|
function dropSet(repoDir, staged, preexistingDirty, env = process.env) {
|
|
14693
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));
|
|
14694
14816
|
}
|
|
14695
|
-
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));
|
|
14696
14818
|
var init_commit_filter = __esm(() => {
|
|
14697
14819
|
init_preexisting_dirty();
|
|
14820
|
+
init_repo_profile();
|
|
14698
14821
|
init_safe_git();
|
|
14699
14822
|
});
|
|
14700
14823
|
|
|
@@ -15053,7 +15176,7 @@ See also: loki cost --detail (what a run ALREADY spent)
|
|
|
15053
15176
|
});
|
|
15054
15177
|
|
|
15055
15178
|
// ../../loki-ts/src/features/contract.ts
|
|
15056
|
-
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";
|
|
15057
15180
|
import { dirname as dirname27, join as join64 } from "path";
|
|
15058
15181
|
import { createHash as createHash15 } from "crypto";
|
|
15059
15182
|
function contractEnabled(env = process.env) {
|
|
@@ -15092,7 +15215,7 @@ function readContract(repoDir) {
|
|
|
15092
15215
|
const p = contractPath(repoDir);
|
|
15093
15216
|
let st;
|
|
15094
15217
|
try {
|
|
15095
|
-
st =
|
|
15218
|
+
st = lstatSync15(p);
|
|
15096
15219
|
} catch {
|
|
15097
15220
|
return { contract: null, notes: [], sha256: null };
|
|
15098
15221
|
}
|
|
@@ -15137,7 +15260,7 @@ function sealContract(repoDir, body, rawDiff, checks, env = process.env, snap) {
|
|
|
15137
15260
|
const live2 = readContract(repoDir);
|
|
15138
15261
|
let exists2 = true;
|
|
15139
15262
|
try {
|
|
15140
|
-
|
|
15263
|
+
lstatSync15(contractPath(repoDir));
|
|
15141
15264
|
} catch {
|
|
15142
15265
|
exists2 = false;
|
|
15143
15266
|
}
|
|
@@ -15692,7 +15815,10 @@ var init_seal = __esm(() => {
|
|
|
15692
15815
|
return sat;
|
|
15693
15816
|
if (drop.length > 0 && (await git4(ctx, ["--literal-pathspecs", "reset", "-q", ctx.baseSha, "--", ...drop.map(({ f }) => f)])).code !== 0)
|
|
15694
15817
|
return { status: "failed", data: {}, reason: "git reset failed" };
|
|
15695
|
-
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)));
|
|
15696
15822
|
if ((await git4(ctx, ["diff", "--cached", "--quiet"])).code === 0)
|
|
15697
15823
|
return { status: "completed", data: { committed: false, scope_notes: notes } };
|
|
15698
15824
|
const title = (str3(ctx.outputs().intake?.title) ?? `run ${ctx.runId}`).split(`
|
|
@@ -16052,6 +16178,11 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
16052
16178
|
const lprob = logProblem(runDir, integ);
|
|
16053
16179
|
if (lprob)
|
|
16054
16180
|
return bad(lprob);
|
|
16181
|
+
if (receipt["toolchain"] !== undefined) {
|
|
16182
|
+
const tp = toolchainProblem(receipt["toolchain"]);
|
|
16183
|
+
if (tp)
|
|
16184
|
+
return bad(tp);
|
|
16185
|
+
}
|
|
16055
16186
|
const heads = isObj10(integ["heads"]) ? integ["heads"] : {}, outcomes = integ["outcomes"];
|
|
16056
16187
|
const stated = receipt["integration"];
|
|
16057
16188
|
if (stated !== undefined) {
|
|
@@ -16113,10 +16244,12 @@ function compositeHash(r) {
|
|
|
16113
16244
|
const { composite_sha256: _c, verification: _v, ...body } = r;
|
|
16114
16245
|
return sha3(canonicalJson(body));
|
|
16115
16246
|
}
|
|
16116
|
-
var COMPOSITE_SCHEMA = "loki.v10.composite/1", slugOf = (repo) => repo.replace(/\//g, "__"), isComposite = (r) => r["schema"] === COMPOSITE_SCHEMA, relOk = (p) => p !== "" && !p.startsWith("/") && !p.split("/").includes("..");
|
|
16247
|
+
var COMPOSITE_SCHEMA = "loki.v10.composite/1", TOOLCHAIN_KEYS, toolchainProblem = (t) => isObj10(t) && Object.keys(t).length === TOOLCHAIN_KEYS.length && TOOLCHAIN_KEYS.every((k) => t[k] === null || typeof t[k] === "string") ? null : "toolchain section is malformed", slugOf = (repo) => repo.replace(/\//g, "__"), isComposite = (r) => r["schema"] === COMPOSITE_SCHEMA, relOk = (p) => p !== "" && !p.startsWith("/") && !p.split("/").includes("..");
|
|
16117
16248
|
var init_composite_seal = __esm(() => {
|
|
16118
16249
|
init_receipt_signer();
|
|
16250
|
+
init_check_result();
|
|
16119
16251
|
init_seal_group();
|
|
16252
|
+
TOOLCHAIN_KEYS = ["bun", "node", "python3", "git"];
|
|
16120
16253
|
});
|
|
16121
16254
|
|
|
16122
16255
|
// ../../loki-ts/src/engine10/keys_cmd.ts
|
|
@@ -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",
|