loki-mode 10.10.5 → 10.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +6 -4
- package/docs/v10/CP-ASK-PLAN.md +85 -0
- package/docs/v10/DEPS.md +3 -0
- package/docs/v10/FAILURE-CLASSES.md +32 -0
- package/docs/v10/FC21B-FC22-PLAN.md +107 -0
- package/docs/v10/FOUNDER-QUEUE.md +2 -0
- package/docs/v10/METRICS.md +1 -0
- package/docs/v10/PROGRESS.md +21 -0
- package/loki-ts/dist/loki.js +683 -678
- package/mcp/__init__.py +1 -1
- package/mcp/server.py +86 -3
- package/mcp/tests/_read_only_wall_probe.py +156 -0
- package/mcp/tests/test_read_only.py +289 -0
- package/memory/storage.py +41 -3
- package/package.json +1 -1
- package/packages/control-plane/dist/server.js +289 -210
- package/packages/control-plane/drizzle/0005_ask.sql +39 -0
- package/packages/control-plane/drizzle/meta/0005_snapshot.json +800 -0
- package/packages/control-plane/drizzle/meta/_journal.json +7 -0
- package/packages/control-plane/package.json +3 -1
- package/packages/control-plane/src/ask/parse.ts +120 -0
- package/packages/control-plane/src/ask/tools.ts +111 -0
- package/packages/control-plane/src/ask/tools_server.ts +46 -0
- package/packages/control-plane/src/db/schema.ts +43 -1
- package/packages/control-plane/src/server/routes/artifacts.ts +3 -3
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-qj6cyTT6.js → AdminPage-CmgIgBFY.js} +1 -1
- package/web-app/dist/assets/{Avatar-Dg4WrYYd.js → Avatar-Dm3ypJzh.js} +1 -1
- package/web-app/dist/assets/{Badge-DHiwSg-p.js → Badge-0siYUwAA.js} +1 -1
- package/web-app/dist/assets/{Button-gi8XEzIU.js → Button-EMKQXvZe.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-B1QNjPBn.js → CockpitPage-Z60eDvJ9.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DW-oUaDu.js → ComparePage-D4L7nViy.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-BK5zjqn-.js → ErrorBoundary--v9DugrJ.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-F58cuFm9.js → EvidenceReceiptPanel-CA866XsM.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-QVyvF19M.js → GitHubIssuesPanel-Bi6FJmR2.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-BRFHMzwy.js → GitHubPRsPanel-CgSfcWOg.js} +1 -1
- package/web-app/dist/assets/{HomePage-Cpskd4yM.js → HomePage-BxQtk9Ec.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CteYWi5M.js → LoginPage-CCSxWlFA.js} +1 -1
- package/web-app/dist/assets/{MagicPage-CCLor0AU.js → MagicPage-B4eYm0jJ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-WgsOaLoq.js → MetricsPage-Bp4Hh0p2.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-DXSCr9P6.js → NotFoundPage-DTXk_JK4.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-sR0kaaXV.js → ProjectPage-6S1v0GHS.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-J3TNS42-.js → ProjectsPage-9foqEwG2.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-Cil5837P.js → SettingsPage-CWOG_hhD.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-C3_oWYJa.js → ShowcasePage-Du9LYlao.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Sddw1fFS.js → SystemSettingsPage-BQconaDX.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-B0poySCt.js → TeamsPage-_NsqtVmC.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-pcYSxHam.js → TemplatesPage-DyTEGBpR.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-CRWTZM7F.js → TerminalOutput-XHOYTpky.js} +1 -1
- package/web-app/dist/assets/{activity-D3aR95zO.js → activity-B9KiMdEs.js} +1 -1
- package/web-app/dist/assets/{bell-WdWaPIBo.js → bell-Oe4lG6kK.js} +1 -1
- package/web-app/dist/assets/{bot-CzD3xokc.js → bot-D86Qmxfy.js} +1 -1
- package/web-app/dist/assets/{check-DMYJiYcm.js → check-BvW6_ni0.js} +1 -1
- package/web-app/dist/assets/{chevron-left-DY0FSKvI.js → chevron-left-DYA62-3g.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DVPtG3Pe.js → circle-alert-CHW8ye4p.js} +1 -1
- package/web-app/dist/assets/{clock-BjjLL6uI.js → clock-QbQ2XfbM.js} +1 -1
- package/web-app/dist/assets/{cloud-CnUCVZhm.js → cloud-ylzrY7eL.js} +1 -1
- package/web-app/dist/assets/{code-xml-BPoxcFNK.js → code-xml-DdKKw2Y9.js} +1 -1
- package/web-app/dist/assets/{database-ClVgDBYt.js → database-BLY_OWs3.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-Ui4BIml8.js → dollar-sign-CsFIa1e2.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BNYl7J1Z.js → file-code-corner-Df4nyrCW.js} +1 -1
- package/web-app/dist/assets/{file-plus-BxkSyRVn.js → file-plus-_MWEY2WY.js} +1 -1
- package/web-app/dist/assets/{globe-b2poyDKT.js → globe-Dpc7QU9m.js} +1 -1
- package/web-app/dist/assets/{hammer-D_0BUpBG.js → hammer-B-PldT0c.js} +1 -1
- package/web-app/dist/assets/{index-D8TYtITk.js → index-gq0R3j-o.js} +3 -3
- package/web-app/dist/assets/{layers-Co1szEIf.js → layers-BjcNwHLZ.js} +1 -1
- package/web-app/dist/assets/{loader-circle-DylW-nwq.js → loader-circle-CoTgcqkV.js} +1 -1
- package/web-app/dist/assets/{lock-D7aFdKw7.js → lock-JEI8O6TS.js} +1 -1
- package/web-app/dist/assets/{package-ElSsRKiN.js → package-CXWkNS40.js} +1 -1
- package/web-app/dist/assets/{plus-CVWgRxDX.js → plus-CRK4U5b0.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-B2azSZHT.js → refresh-cw-CrzWr4cw.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-BdQHOrf0.js → rotate-ccw-DV7UZyUw.js} +1 -1
- package/web-app/dist/assets/{scroll-text-9m-YKf83.js → scroll-text-CXEqRrXU.js} +1 -1
- package/web-app/dist/assets/{server-BYq99Fe1.js → server-CDFfFP10.js} +1 -1
- package/web-app/dist/assets/{shield-alert-BNCiHXhR.js → shield-alert-B5EC_m6_.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BB_EJkat.js → thumbs-up-BeLDemd2.js} +1 -1
- package/web-app/dist/assets/{trash-2-BMF4kFvy.js → trash-2-B7kS86-0.js} +1 -1
- package/web-app/dist/assets/{trending-down-BiqiTPXx.js → trending-down-BGvuLayo.js} +1 -1
- package/web-app/dist/assets/{trending-up-Bq6qyKub.js → trending-up-BkPM2tiK.js} +1 -1
- package/web-app/dist/assets/{upload-1HzIJHHR.js → upload-CXVI0GRU.js} +1 -1
- package/web-app/dist/assets/{usePolling-FNwpjURt.js → usePolling-CMGMVsMA.js} +1 -1
- package/web-app/dist/assets/{user-DrORfQv3.js → user-DPcXNtfj.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -10473,6 +10473,9 @@ class Index {
|
|
|
10473
10473
|
function index(name) {
|
|
10474
10474
|
return new IndexBuilderOn(name, false);
|
|
10475
10475
|
}
|
|
10476
|
+
function uniqueIndex(name) {
|
|
10477
|
+
return new IndexBuilderOn(name, true);
|
|
10478
|
+
}
|
|
10476
10479
|
|
|
10477
10480
|
// node_modules/drizzle-orm/sqlite-core/primary-keys.js
|
|
10478
10481
|
function primaryKey(...config) {
|
|
@@ -12521,6 +12524,9 @@ __export(exports_schema, {
|
|
|
12521
12524
|
localRepos: () => localRepos,
|
|
12522
12525
|
events: () => events,
|
|
12523
12526
|
audit: () => audit2,
|
|
12527
|
+
askThreads: () => askThreads,
|
|
12528
|
+
askMessages: () => askMessages,
|
|
12529
|
+
askEvents: () => askEvents,
|
|
12524
12530
|
actions: () => actions
|
|
12525
12531
|
});
|
|
12526
12532
|
var sources = sqliteTable("sources", {
|
|
@@ -12601,6 +12607,42 @@ var actions = sqliteTable("actions", {
|
|
|
12601
12607
|
result: text("result").notNull(),
|
|
12602
12608
|
detail: text("detail")
|
|
12603
12609
|
}, (t) => [index("actions_ts").on(t.ts)]);
|
|
12610
|
+
var askThreads = sqliteTable("ask_threads", {
|
|
12611
|
+
id: text("id").primaryKey(),
|
|
12612
|
+
createdAt: text("created_at").notNull(),
|
|
12613
|
+
updatedAt: text("updated_at").notNull(),
|
|
12614
|
+
repo: text("repo"),
|
|
12615
|
+
provider: text("provider").notNull(),
|
|
12616
|
+
model: text("model"),
|
|
12617
|
+
title: text("title")
|
|
12618
|
+
});
|
|
12619
|
+
var askMessages = sqliteTable("ask_messages", {
|
|
12620
|
+
id: text("id").primaryKey(),
|
|
12621
|
+
threadId: text("thread_id").notNull().references(() => askThreads.id),
|
|
12622
|
+
seq: integer("seq").notNull(),
|
|
12623
|
+
role: text("role").notNull(),
|
|
12624
|
+
text: text("text").notNull(),
|
|
12625
|
+
status: text("status").notNull(),
|
|
12626
|
+
workerPid: integer("worker_pid"),
|
|
12627
|
+
pgid: integer("pgid"),
|
|
12628
|
+
costUsd: real("cost_usd"),
|
|
12629
|
+
error: text("error"),
|
|
12630
|
+
startedAt: text("started_at"),
|
|
12631
|
+
finishedAt: text("finished_at")
|
|
12632
|
+
}, (t) => [
|
|
12633
|
+
uniqueIndex("ask_messages_thread_seq").on(t.threadId, t.seq),
|
|
12634
|
+
index("ask_messages_status").on(t.status)
|
|
12635
|
+
]);
|
|
12636
|
+
var askEvents = sqliteTable("ask_events", {
|
|
12637
|
+
id: text("id").primaryKey(),
|
|
12638
|
+
messageId: text("message_id").notNull().references(() => askMessages.id),
|
|
12639
|
+
seq: integer("seq").notNull(),
|
|
12640
|
+
kind: text("kind").notNull(),
|
|
12641
|
+
payload: text("payload").notNull(),
|
|
12642
|
+
ts: text("ts").notNull()
|
|
12643
|
+
}, (t) => [
|
|
12644
|
+
uniqueIndex("ask_events_message_seq").on(t.messageId, t.seq)
|
|
12645
|
+
]);
|
|
12604
12646
|
|
|
12605
12647
|
// src/db/migrate.ts
|
|
12606
12648
|
function openDb(path) {
|
|
@@ -16891,204 +16933,11 @@ function dropSet(repoDir, staged, preexistingDirty, env = process.env) {
|
|
|
16891
16933
|
import { basename as basename9, dirname as dirname7 } from "path";
|
|
16892
16934
|
|
|
16893
16935
|
// ../../loki-ts/src/engine10/testmap.ts
|
|
16894
|
-
import { basename as basename8, extname, join as
|
|
16895
|
-
var SKIP_DIRS = new Set([
|
|
16896
|
-
".git",
|
|
16897
|
-
"node_modules",
|
|
16898
|
-
"dist",
|
|
16899
|
-
"build",
|
|
16900
|
-
"target",
|
|
16901
|
-
"coverage",
|
|
16902
|
-
".venv",
|
|
16903
|
-
"venv",
|
|
16904
|
-
"__pycache__",
|
|
16905
|
-
".tox",
|
|
16906
|
-
".pytest_cache",
|
|
16907
|
-
".loki",
|
|
16908
|
-
".next"
|
|
16909
|
-
]);
|
|
16910
|
-
var JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
|
|
16911
|
-
var PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
|
|
16912
|
-
var GO_TEST_RE = /_test\.go$/;
|
|
16913
|
-
function isTestFile(rel) {
|
|
16914
|
-
const name = basename8(rel);
|
|
16915
|
-
return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
|
|
16916
|
-
}
|
|
16917
|
-
|
|
16918
|
-
// ../../loki-ts/src/features/speed/unit_mode.ts
|
|
16919
|
-
import { closeSync as closeSync6, constants, fstatSync as fstatSync4, lstatSync as lstatSync4, openSync as openSync6, readSync as readSync4, realpathSync as realpathSync12 } from "fs";
|
|
16920
|
-
var MAX_SPEC_BYTES = 1024 * 1024;
|
|
16921
|
-
var MAX_TOKEN_BUDGET = 1e9;
|
|
16922
|
-
var norm2 = (p) => p.replace(/^\.\//, "");
|
|
16923
|
-
var CTRL = /[\x00-\x1f\x7f]/;
|
|
16924
|
-
var strs = (v) => Array.isArray(v) && v.every((x) => typeof x === "string" && !CTRL.test(x)) ? v.map(norm2) : null;
|
|
16925
|
-
function readBounded(path) {
|
|
16926
|
-
const l = lstatSync4(path);
|
|
16927
|
-
if (l.isSymbolicLink() || !l.isFile() || l.size > MAX_SPEC_BYTES)
|
|
16928
|
-
return null;
|
|
16929
|
-
const fd = openSync6(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
16930
|
-
try {
|
|
16931
|
-
const st = fstatSync4(fd);
|
|
16932
|
-
if (!st.isFile() || st.size > MAX_SPEC_BYTES)
|
|
16933
|
-
return null;
|
|
16934
|
-
const buf = Buffer.alloc(st.size + 1);
|
|
16935
|
-
let n2 = 0;
|
|
16936
|
-
for (;; ) {
|
|
16937
|
-
const r = readSync4(fd, buf, n2, buf.length - n2, null);
|
|
16938
|
-
if (r <= 0)
|
|
16939
|
-
break;
|
|
16940
|
-
n2 += r;
|
|
16941
|
-
if (n2 >= buf.length)
|
|
16942
|
-
return null;
|
|
16943
|
-
}
|
|
16944
|
-
return buf.subarray(0, n2).toString("utf8");
|
|
16945
|
-
} finally {
|
|
16946
|
-
closeSync6(fd);
|
|
16947
|
-
}
|
|
16948
|
-
}
|
|
16949
|
-
function parseText(txt) {
|
|
16950
|
-
try {
|
|
16951
|
-
const j = JSON.parse(txt), ws = strs(j.writeSet), pack = strs(j.pack), tb = j.tokenBudget;
|
|
16952
|
-
if (typeof j.id !== "string" || !j.id || !ws || ws.length === 0 || !pack || typeof tb !== "number" || !Number.isFinite(tb) || !(tb > 0) || tb > MAX_TOKEN_BUDGET)
|
|
16953
|
-
return null;
|
|
16954
|
-
return { id: j.id, writeSet: ws, pack, tokenBudget: tb };
|
|
16955
|
-
} catch {
|
|
16956
|
-
return null;
|
|
16957
|
-
}
|
|
16958
|
-
}
|
|
16959
|
-
function parseSpec(path) {
|
|
16960
|
-
try {
|
|
16961
|
-
const txt = readBounded(path);
|
|
16962
|
-
return txt === null ? null : parseText(txt);
|
|
16963
|
-
} catch {
|
|
16964
|
-
return null;
|
|
16965
|
-
}
|
|
16966
|
-
}
|
|
16967
|
-
var memo = new Map;
|
|
16968
|
-
function unitSpec(env = process.env) {
|
|
16969
|
-
const path = env["LOKI_UNIT_SPEC"], frozen = env["LOKI_UNIT_SPEC_FROZEN"];
|
|
16970
|
-
if (env["LOKI_SPEED"] === "0" || !path)
|
|
16971
|
-
return null;
|
|
16972
|
-
if (frozen !== undefined)
|
|
16973
|
-
return frozen.length <= MAX_SPEC_BYTES ? parseText(frozen) : null;
|
|
16974
|
-
if (!memo.has(path))
|
|
16975
|
-
memo.set(path, parseSpec(path));
|
|
16976
|
-
return memo.get(path) ?? null;
|
|
16977
|
-
}
|
|
16978
|
-
var inWriteSet = (spec, f) => spec.writeSet.some((w) => w.endsWith("/") ? f.startsWith(w) : f === w);
|
|
16979
|
-
function unitFlags(staged, env = process.env, pre = {}) {
|
|
16980
|
-
const s = unitSpec(env);
|
|
16981
|
-
return s ? staged.filter(({ f }) => !inWriteSet(s, f) && !Object.hasOwn(pre, f)).map(({ f }) => f) : null;
|
|
16982
|
-
}
|
|
16983
|
-
|
|
16984
|
-
// ../../loki-ts/src/e10ext/scope.ts
|
|
16985
|
-
var SCOPE_UNDETERMINED = "scope not determined; all edits committed";
|
|
16986
|
-
var outsideNote = (f) => `outside stated scope: ${f}`;
|
|
16987
|
-
var esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16988
|
-
var mentions = (text2, name) => new RegExp(`(?<![\\w./-])${esc(name)}(?![\\w-]|\\.\\w)`).test(text2);
|
|
16989
|
-
var STOP = new Set(["the", "and", "for", "with", "that", "this", "all", "any", "src", "from", "into", "each", "across", "apply", "add", "use", "make"]);
|
|
16990
|
-
var stem = (w) => w.length > 3 && w.endsWith("s") ? w.slice(0, -1) : w;
|
|
16991
|
-
var surfaceTokens = (text2) => new Set((text2.toLowerCase().match(/[a-z][a-z0-9_-]{2,}/g) ?? []).filter((w) => !STOP.has(w)).map(stem));
|
|
16992
|
-
var dirSegs = (f) => f.split("/").slice(0, -1).map((d) => stem(d.toLowerCase()));
|
|
16993
|
-
function contractText(o) {
|
|
16994
|
-
const c = o.intake?.contract_snapshot?.contract;
|
|
16995
|
-
return Array.isArray(c?.criteria) ? c.criteria.map((x) => typeof x?.text === "string" ? x.text : "").join(`
|
|
16996
|
-
`) : "";
|
|
16997
|
-
}
|
|
16998
|
-
function outsideScope(o, staged) {
|
|
16999
|
-
const rel = Array.isArray(o.plan?.relevant_files) ? o.plan.relevant_files.filter((x) => typeof x === "string") : [];
|
|
17000
|
-
const plan = typeof o.plan?.plan === "string" ? o.plan.plan : "";
|
|
17001
|
-
if (rel.length === 0 && plan.trim() === "")
|
|
17002
|
-
return null;
|
|
17003
|
-
const text2 = `${plan}
|
|
17004
|
-
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
17005
|
-
${contractText(o)}`, pre = o.intake?.preexisting_dirty ?? {};
|
|
17006
|
-
const toks = surfaceTokens(text2), plannedDirs = new Set(rel.map((r) => dirname7(r)).filter((d) => d !== "."));
|
|
17007
|
-
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename9(f)) && !plannedDirs.has(dirname7(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
|
|
17008
|
-
}
|
|
17009
|
-
function flagOutsideScope(o, staged) {
|
|
17010
|
-
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
17011
|
-
const un = outsideScope(o, staged), seen = new Set((unit ?? []).map(outsideNote));
|
|
17012
|
-
return [...(unit ?? []).map(outsideNote), ...un ? un.map(outsideNote).filter((n2) => !seen.has(n2)) : staged.length > 0 ? [SCOPE_UNDETERMINED] : []];
|
|
17013
|
-
}
|
|
17014
|
-
|
|
17015
|
-
// ../../loki-ts/src/util/receipt_signer.ts
|
|
17016
|
-
var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem";
|
|
17017
|
-
|
|
17018
|
-
// ../../loki-ts/src/util/shell.ts
|
|
17019
|
-
var MAX_STDOUT_BYTES = 16 * 1024 * 1024;
|
|
17020
|
-
async function readStreamCapped(stream, maxBytes = MAX_STDOUT_BYTES) {
|
|
17021
|
-
const reader = stream.getReader();
|
|
17022
|
-
const decoder = new TextDecoder;
|
|
17023
|
-
let out2 = "";
|
|
17024
|
-
let total = 0;
|
|
17025
|
-
try {
|
|
17026
|
-
while (total < maxBytes) {
|
|
17027
|
-
const { done, value } = await reader.read();
|
|
17028
|
-
if (done)
|
|
17029
|
-
break;
|
|
17030
|
-
if (!value)
|
|
17031
|
-
continue;
|
|
17032
|
-
total += value.byteLength;
|
|
17033
|
-
if (total > maxBytes) {
|
|
17034
|
-
const keep = value.byteLength - (total - maxBytes);
|
|
17035
|
-
out2 += decoder.decode(value.subarray(0, keep), { stream: true });
|
|
17036
|
-
break;
|
|
17037
|
-
}
|
|
17038
|
-
out2 += decoder.decode(value, { stream: true });
|
|
17039
|
-
}
|
|
17040
|
-
out2 += decoder.decode();
|
|
17041
|
-
} finally {
|
|
17042
|
-
try {
|
|
17043
|
-
await reader.cancel();
|
|
17044
|
-
} catch {}
|
|
17045
|
-
reader.releaseLock();
|
|
17046
|
-
}
|
|
17047
|
-
return out2;
|
|
17048
|
-
}
|
|
17049
|
-
async function run(argv, opts = {}) {
|
|
17050
|
-
const proc = Bun.spawn({
|
|
17051
|
-
cmd: [...argv],
|
|
17052
|
-
stdout: "pipe",
|
|
17053
|
-
stderr: "pipe",
|
|
17054
|
-
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
17055
|
-
cwd: opts.cwd
|
|
17056
|
-
});
|
|
17057
|
-
let timer;
|
|
17058
|
-
let killTimer;
|
|
17059
|
-
if (opts.timeoutMs && opts.timeoutMs > 0) {
|
|
17060
|
-
timer = setTimeout(() => {
|
|
17061
|
-
try {
|
|
17062
|
-
proc.kill("SIGTERM");
|
|
17063
|
-
} catch {}
|
|
17064
|
-
killTimer = setTimeout(() => {
|
|
17065
|
-
try {
|
|
17066
|
-
proc.kill("SIGKILL");
|
|
17067
|
-
} catch {}
|
|
17068
|
-
}, 2000);
|
|
17069
|
-
}, opts.timeoutMs);
|
|
17070
|
-
}
|
|
17071
|
-
try {
|
|
17072
|
-
const [stdout, stderr, exitCode] = await Promise.all([
|
|
17073
|
-
readStreamCapped(proc.stdout),
|
|
17074
|
-
new Response(proc.stderr).text(),
|
|
17075
|
-
proc.exited
|
|
17076
|
-
]);
|
|
17077
|
-
return { stdout, stderr, exitCode };
|
|
17078
|
-
} finally {
|
|
17079
|
-
if (timer)
|
|
17080
|
-
clearTimeout(timer);
|
|
17081
|
-
if (killTimer)
|
|
17082
|
-
clearTimeout(killTimer);
|
|
17083
|
-
}
|
|
17084
|
-
}
|
|
17085
|
-
|
|
17086
|
-
// ../../loki-ts/src/features/visual_evidence.ts
|
|
17087
|
-
import { spawn as spawn5 } from "child_process";
|
|
16936
|
+
import { basename as basename8, extname, join as join26, relative as relative2, sep as sep10 } from "path";
|
|
17088
16937
|
|
|
17089
16938
|
// ../../loki-ts/src/project_model/discover.ts
|
|
17090
16939
|
import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync19, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
17091
|
-
import { join as
|
|
16940
|
+
import { join as join25 } from "path";
|
|
17092
16941
|
|
|
17093
16942
|
// ../../loki-ts/src/engine10/types.ts
|
|
17094
16943
|
var STAGE_BUDGETS = {
|
|
@@ -17105,23 +16954,23 @@ var STAGE_BUDGETS = {
|
|
|
17105
16954
|
};
|
|
17106
16955
|
|
|
17107
16956
|
// ../../loki-ts/src/project_model/schema.ts
|
|
17108
|
-
import { existsSync as existsSync13, lstatSync as
|
|
17109
|
-
import { isAbsolute, join as
|
|
16957
|
+
import { existsSync as existsSync13, lstatSync as lstatSync4, realpathSync as realpathSync12, statSync as statSync10 } from "fs";
|
|
16958
|
+
import { isAbsolute, join as join24, normalize, sep as sep9 } from "path";
|
|
17110
16959
|
var PROJECT_MODEL_SCHEMA = "loki.v10.project/1";
|
|
17111
16960
|
var COMMAND_KINDS = ["test", "lint", "build", "start"];
|
|
17112
16961
|
var isRec = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
17113
16962
|
var isStr = (v) => typeof v === "string" && v.trim() !== "";
|
|
17114
16963
|
function safeRel(p) {
|
|
17115
|
-
const n2 = normalize(p.trim()).split(
|
|
16964
|
+
const n2 = normalize(p.trim()).split(sep9).join("/").replace(/\/$/, "");
|
|
17116
16965
|
if (n2 === "" || isAbsolute(n2) || n2 === ".." || n2.startsWith("../"))
|
|
17117
16966
|
return null;
|
|
17118
16967
|
return n2;
|
|
17119
16968
|
}
|
|
17120
16969
|
function insideRepo(repoDir, rel) {
|
|
17121
16970
|
try {
|
|
17122
|
-
const real2 =
|
|
17123
|
-
const base =
|
|
17124
|
-
return real2 === base || real2.startsWith(base +
|
|
16971
|
+
const real2 = realpathSync12(join24(repoDir, rel));
|
|
16972
|
+
const base = realpathSync12(repoDir);
|
|
16973
|
+
return real2 === base || real2.startsWith(base + sep9);
|
|
17125
16974
|
} catch {
|
|
17126
16975
|
return false;
|
|
17127
16976
|
}
|
|
@@ -17132,7 +16981,7 @@ function checkCitation(repoDir, raw2) {
|
|
|
17132
16981
|
const rel = safeRel(raw2.replace(/:\d+(?:-\d+)?$/, ""));
|
|
17133
16982
|
if (rel === null)
|
|
17134
16983
|
return `citation "${raw2}" is not a repo-relative path`;
|
|
17135
|
-
const abs =
|
|
16984
|
+
const abs = join24(repoDir, rel);
|
|
17136
16985
|
if (!existsSync13(abs) || !statSync10(abs).isFile() || !insideRepo(repoDir, rel))
|
|
17137
16986
|
return `citation "${raw2}" names a file that does not exist`;
|
|
17138
16987
|
return null;
|
|
@@ -17144,7 +16993,7 @@ function checkFingerprint(repoDir, raw2) {
|
|
|
17144
16993
|
if (rel === null)
|
|
17145
16994
|
return `fingerprint "${raw2}" is not a repo-relative path`;
|
|
17146
16995
|
try {
|
|
17147
|
-
if (!
|
|
16996
|
+
if (!lstatSync4(join24(repoDir, rel)).isFile() || !insideRepo(repoDir, rel))
|
|
17148
16997
|
return `fingerprint "${raw2}" is not a regular file inside the repo`;
|
|
17149
16998
|
} catch {
|
|
17150
16999
|
return `fingerprint "${raw2}" names a file that does not exist`;
|
|
@@ -17172,7 +17021,7 @@ function checkDir(repoDir, v, where, errs) {
|
|
|
17172
17021
|
errs.push(`${where}: must be a repo-relative directory ("." for the repo root)`);
|
|
17173
17022
|
return ".";
|
|
17174
17023
|
}
|
|
17175
|
-
const abs =
|
|
17024
|
+
const abs = join24(repoDir, rel);
|
|
17176
17025
|
if (!existsSync13(abs) || !statSync10(abs).isDirectory() || !insideRepo(repoDir, rel))
|
|
17177
17026
|
errs.push(`${where}: directory "${rel}" does not exist`);
|
|
17178
17027
|
return rel;
|
|
@@ -17187,6 +17036,21 @@ function checkCommand(repoDir, v, where, errs) {
|
|
|
17187
17036
|
const cwd = checkDir(repoDir, v.cwd, `${where}.cwd`, errs);
|
|
17188
17037
|
return { cmd: v.cmd.trim(), cwd, cite: checkCites(repoDir, v.cite, `${where}.cite`, errs) };
|
|
17189
17038
|
}
|
|
17039
|
+
function rawDeps(v, where, errs) {
|
|
17040
|
+
if (!Array.isArray(v)) {
|
|
17041
|
+
errs.push(`${where}: must be an array of package roots`);
|
|
17042
|
+
return [];
|
|
17043
|
+
}
|
|
17044
|
+
const out2 = [];
|
|
17045
|
+
for (const d of v) {
|
|
17046
|
+
const rel = isStr(d) ? safeRel(d) : null;
|
|
17047
|
+
if (rel === null)
|
|
17048
|
+
errs.push(`${where}: "${String(d)}" is not a repo-relative package root`);
|
|
17049
|
+
else if (!out2.includes(rel))
|
|
17050
|
+
out2.push(rel);
|
|
17051
|
+
}
|
|
17052
|
+
return out2;
|
|
17053
|
+
}
|
|
17190
17054
|
function validateAnswer(repoDir, raw2) {
|
|
17191
17055
|
const errs = [];
|
|
17192
17056
|
if (!isRec(raw2))
|
|
@@ -17219,9 +17083,16 @@ function validateAnswer(repoDir, raw2) {
|
|
|
17219
17083
|
runner: isStr(p.runner) ? p.runner.trim() : null,
|
|
17220
17084
|
commands,
|
|
17221
17085
|
ui: { present: ui.present === true, boot: checkCommand(repoDir, ui.boot, `${w}.ui.boot`, errs), cite: checkCites(repoDir, ui.cite, `${w}.ui.cite`, errs) },
|
|
17222
|
-
cite: checkCites(repoDir, p.cite, `${w}.cite`, errs)
|
|
17086
|
+
cite: checkCites(repoDir, p.cite, `${w}.cite`, errs),
|
|
17087
|
+
...p.install === undefined ? {} : { install: checkCommand(repoDir, p.install, `${w}.install`, errs) },
|
|
17088
|
+
...p.dependsOn === undefined ? {} : { dependsOn: rawDeps(p.dependsOn, `${w}.dependsOn`, errs) }
|
|
17223
17089
|
});
|
|
17224
17090
|
}
|
|
17091
|
+
const roots = new Set(packages.map((p) => p.root));
|
|
17092
|
+
for (const p of packages)
|
|
17093
|
+
for (const d of p.dependsOn ?? [])
|
|
17094
|
+
if (!roots.has(d))
|
|
17095
|
+
errs.push(`package "${p.name}".dependsOn: "${d}" is not the root of any listed package`);
|
|
17225
17096
|
if (!Array.isArray(raw2.fingerprintFiles))
|
|
17226
17097
|
errs.push("fingerprintFiles: required array of the manifest and lockfile paths");
|
|
17227
17098
|
const fingerprintFiles = (Array.isArray(raw2.fingerprintFiles) ? raw2.fingerprintFiles : []).filter((f) => {
|
|
@@ -17267,7 +17138,7 @@ var PROJECT_FILE = ".loki/project.json";
|
|
|
17267
17138
|
var UNKNOWN_TTL_MS = 60 * 60 * 1000;
|
|
17268
17139
|
function loadCached(repoDir, now = Date.now()) {
|
|
17269
17140
|
try {
|
|
17270
|
-
return parseCached(repoDir, JSON.parse(readFileSync19(
|
|
17141
|
+
return parseCached(repoDir, JSON.parse(readFileSync19(join25(repoDir, PROJECT_FILE), "utf8")), now);
|
|
17271
17142
|
} catch {
|
|
17272
17143
|
return null;
|
|
17273
17144
|
}
|
|
@@ -17305,6 +17176,14 @@ function projectApi(model) {
|
|
|
17305
17176
|
return p ? p.root === "." ? clean(file) : clean(file).slice(p.root.length + 1) : null;
|
|
17306
17177
|
},
|
|
17307
17178
|
commandFor: (pkg, kind) => (packages.find((p) => p.root === clean(pkg) || p.name === pkg) ?? null)?.commands?.[kind] ?? null,
|
|
17179
|
+
dependsOn: (pkg) => {
|
|
17180
|
+
const d = (packages.find((p) => p.root === clean(pkg) || p.name === pkg) ?? null)?.dependsOn;
|
|
17181
|
+
return Array.isArray(d) ? d.filter((x) => typeof x === "string") : null;
|
|
17182
|
+
},
|
|
17183
|
+
installFor: (pkg) => {
|
|
17184
|
+
const i = (packages.find((p) => p.root === clean(pkg) || p.name === pkg) ?? null)?.install;
|
|
17185
|
+
return isRec2(i) && typeof i.cmd === "string" ? i : null;
|
|
17186
|
+
},
|
|
17308
17187
|
hasUI: () => packages.some((p) => isRec2(p.ui) && p.ui.present === true),
|
|
17309
17188
|
uiBoot: () => {
|
|
17310
17189
|
for (const p of packages)
|
|
@@ -17331,7 +17210,205 @@ function isMultiRoot(api) {
|
|
|
17331
17210
|
return !!api && api.known() && api.packages().some((p) => p.root !== ".");
|
|
17332
17211
|
}
|
|
17333
17212
|
|
|
17213
|
+
// ../../loki-ts/src/project_model/scope.ts
|
|
17214
|
+
var apis = new WeakMap;
|
|
17215
|
+
var imports = new WeakMap;
|
|
17216
|
+
var dropped = new WeakMap;
|
|
17217
|
+
|
|
17218
|
+
// ../../loki-ts/src/engine10/testmap.ts
|
|
17219
|
+
var SKIP_DIRS = new Set([
|
|
17220
|
+
".git",
|
|
17221
|
+
"node_modules",
|
|
17222
|
+
"dist",
|
|
17223
|
+
"build",
|
|
17224
|
+
"target",
|
|
17225
|
+
"coverage",
|
|
17226
|
+
".venv",
|
|
17227
|
+
"venv",
|
|
17228
|
+
"__pycache__",
|
|
17229
|
+
".tox",
|
|
17230
|
+
".pytest_cache",
|
|
17231
|
+
".loki",
|
|
17232
|
+
".next"
|
|
17233
|
+
]);
|
|
17234
|
+
var JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
|
|
17235
|
+
var PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
|
|
17236
|
+
var GO_TEST_RE = /_test\.go$/;
|
|
17237
|
+
function isTestFile(rel) {
|
|
17238
|
+
const name = basename8(rel);
|
|
17239
|
+
return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
|
|
17240
|
+
}
|
|
17241
|
+
|
|
17242
|
+
// ../../loki-ts/src/features/speed/unit_mode.ts
|
|
17243
|
+
import { closeSync as closeSync6, constants, fstatSync as fstatSync4, lstatSync as lstatSync5, openSync as openSync6, readSync as readSync4, realpathSync as realpathSync13 } from "fs";
|
|
17244
|
+
var MAX_SPEC_BYTES = 1024 * 1024;
|
|
17245
|
+
var MAX_TOKEN_BUDGET = 1e9;
|
|
17246
|
+
var norm2 = (p) => p.replace(/^\.\//, "");
|
|
17247
|
+
var CTRL = /[\x00-\x1f\x7f]/;
|
|
17248
|
+
var strs = (v) => Array.isArray(v) && v.every((x) => typeof x === "string" && !CTRL.test(x)) ? v.map(norm2) : null;
|
|
17249
|
+
function readBounded(path) {
|
|
17250
|
+
const l = lstatSync5(path);
|
|
17251
|
+
if (l.isSymbolicLink() || !l.isFile() || l.size > MAX_SPEC_BYTES)
|
|
17252
|
+
return null;
|
|
17253
|
+
const fd = openSync6(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
17254
|
+
try {
|
|
17255
|
+
const st = fstatSync4(fd);
|
|
17256
|
+
if (!st.isFile() || st.size > MAX_SPEC_BYTES)
|
|
17257
|
+
return null;
|
|
17258
|
+
const buf = Buffer.alloc(st.size + 1);
|
|
17259
|
+
let n2 = 0;
|
|
17260
|
+
for (;; ) {
|
|
17261
|
+
const r = readSync4(fd, buf, n2, buf.length - n2, null);
|
|
17262
|
+
if (r <= 0)
|
|
17263
|
+
break;
|
|
17264
|
+
n2 += r;
|
|
17265
|
+
if (n2 >= buf.length)
|
|
17266
|
+
return null;
|
|
17267
|
+
}
|
|
17268
|
+
return buf.subarray(0, n2).toString("utf8");
|
|
17269
|
+
} finally {
|
|
17270
|
+
closeSync6(fd);
|
|
17271
|
+
}
|
|
17272
|
+
}
|
|
17273
|
+
function parseText(txt) {
|
|
17274
|
+
try {
|
|
17275
|
+
const j = JSON.parse(txt), ws = strs(j.writeSet), pack = strs(j.pack), tb = j.tokenBudget;
|
|
17276
|
+
if (typeof j.id !== "string" || !j.id || !ws || ws.length === 0 || !pack || typeof tb !== "number" || !Number.isFinite(tb) || !(tb > 0) || tb > MAX_TOKEN_BUDGET)
|
|
17277
|
+
return null;
|
|
17278
|
+
return { id: j.id, writeSet: ws, pack, tokenBudget: tb };
|
|
17279
|
+
} catch {
|
|
17280
|
+
return null;
|
|
17281
|
+
}
|
|
17282
|
+
}
|
|
17283
|
+
function parseSpec(path) {
|
|
17284
|
+
try {
|
|
17285
|
+
const txt = readBounded(path);
|
|
17286
|
+
return txt === null ? null : parseText(txt);
|
|
17287
|
+
} catch {
|
|
17288
|
+
return null;
|
|
17289
|
+
}
|
|
17290
|
+
}
|
|
17291
|
+
var memo = new Map;
|
|
17292
|
+
function unitSpec(env = process.env) {
|
|
17293
|
+
const path = env["LOKI_UNIT_SPEC"], frozen = env["LOKI_UNIT_SPEC_FROZEN"];
|
|
17294
|
+
if (env["LOKI_SPEED"] === "0" || !path)
|
|
17295
|
+
return null;
|
|
17296
|
+
if (frozen !== undefined)
|
|
17297
|
+
return frozen.length <= MAX_SPEC_BYTES ? parseText(frozen) : null;
|
|
17298
|
+
if (!memo.has(path))
|
|
17299
|
+
memo.set(path, parseSpec(path));
|
|
17300
|
+
return memo.get(path) ?? null;
|
|
17301
|
+
}
|
|
17302
|
+
var inWriteSet = (spec, f) => spec.writeSet.some((w) => w.endsWith("/") ? f.startsWith(w) : f === w);
|
|
17303
|
+
function unitFlags(staged, env = process.env, pre = {}) {
|
|
17304
|
+
const s = unitSpec(env);
|
|
17305
|
+
return s ? staged.filter(({ f }) => !inWriteSet(s, f) && !Object.hasOwn(pre, f)).map(({ f }) => f) : null;
|
|
17306
|
+
}
|
|
17307
|
+
|
|
17308
|
+
// ../../loki-ts/src/e10ext/scope.ts
|
|
17309
|
+
var SCOPE_UNDETERMINED = "scope not determined; all edits committed";
|
|
17310
|
+
var outsideNote = (f) => `outside stated scope: ${f}`;
|
|
17311
|
+
var esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17312
|
+
var mentions = (text2, name) => new RegExp(`(?<![\\w./-])${esc(name)}(?![\\w-]|\\.\\w)`).test(text2);
|
|
17313
|
+
var STOP = new Set(["the", "and", "for", "with", "that", "this", "all", "any", "src", "from", "into", "each", "across", "apply", "add", "use", "make"]);
|
|
17314
|
+
var stem = (w) => w.length > 3 && w.endsWith("s") ? w.slice(0, -1) : w;
|
|
17315
|
+
var surfaceTokens = (text2) => new Set((text2.toLowerCase().match(/[a-z][a-z0-9_-]{2,}/g) ?? []).filter((w) => !STOP.has(w)).map(stem));
|
|
17316
|
+
var dirSegs = (f) => f.split("/").slice(0, -1).map((d) => stem(d.toLowerCase()));
|
|
17317
|
+
function contractText(o) {
|
|
17318
|
+
const c = o.intake?.contract_snapshot?.contract;
|
|
17319
|
+
return Array.isArray(c?.criteria) ? c.criteria.map((x) => typeof x?.text === "string" ? x.text : "").join(`
|
|
17320
|
+
`) : "";
|
|
17321
|
+
}
|
|
17322
|
+
function outsideScope(o, staged) {
|
|
17323
|
+
const rel = Array.isArray(o.plan?.relevant_files) ? o.plan.relevant_files.filter((x) => typeof x === "string") : [];
|
|
17324
|
+
const plan = typeof o.plan?.plan === "string" ? o.plan.plan : "";
|
|
17325
|
+
if (rel.length === 0 && plan.trim() === "")
|
|
17326
|
+
return null;
|
|
17327
|
+
const text2 = `${plan}
|
|
17328
|
+
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
17329
|
+
${contractText(o)}`, pre = o.intake?.preexisting_dirty ?? {};
|
|
17330
|
+
const toks = surfaceTokens(text2), plannedDirs = new Set(rel.map((r) => dirname7(r)).filter((d) => d !== "."));
|
|
17331
|
+
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename9(f)) && !plannedDirs.has(dirname7(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
|
|
17332
|
+
}
|
|
17333
|
+
function flagOutsideScope(o, staged) {
|
|
17334
|
+
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
17335
|
+
const un = outsideScope(o, staged), seen = new Set((unit ?? []).map(outsideNote));
|
|
17336
|
+
return [...(unit ?? []).map(outsideNote), ...un ? un.map(outsideNote).filter((n2) => !seen.has(n2)) : staged.length > 0 ? [SCOPE_UNDETERMINED] : []];
|
|
17337
|
+
}
|
|
17338
|
+
|
|
17339
|
+
// ../../loki-ts/src/util/receipt_signer.ts
|
|
17340
|
+
var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem";
|
|
17341
|
+
|
|
17342
|
+
// ../../loki-ts/src/util/shell.ts
|
|
17343
|
+
var MAX_STDOUT_BYTES = 16 * 1024 * 1024;
|
|
17344
|
+
async function readStreamCapped(stream, maxBytes = MAX_STDOUT_BYTES) {
|
|
17345
|
+
const reader = stream.getReader();
|
|
17346
|
+
const decoder = new TextDecoder;
|
|
17347
|
+
let out2 = "";
|
|
17348
|
+
let total = 0;
|
|
17349
|
+
try {
|
|
17350
|
+
while (total < maxBytes) {
|
|
17351
|
+
const { done, value } = await reader.read();
|
|
17352
|
+
if (done)
|
|
17353
|
+
break;
|
|
17354
|
+
if (!value)
|
|
17355
|
+
continue;
|
|
17356
|
+
total += value.byteLength;
|
|
17357
|
+
if (total > maxBytes) {
|
|
17358
|
+
const keep = value.byteLength - (total - maxBytes);
|
|
17359
|
+
out2 += decoder.decode(value.subarray(0, keep), { stream: true });
|
|
17360
|
+
break;
|
|
17361
|
+
}
|
|
17362
|
+
out2 += decoder.decode(value, { stream: true });
|
|
17363
|
+
}
|
|
17364
|
+
out2 += decoder.decode();
|
|
17365
|
+
} finally {
|
|
17366
|
+
try {
|
|
17367
|
+
await reader.cancel();
|
|
17368
|
+
} catch {}
|
|
17369
|
+
reader.releaseLock();
|
|
17370
|
+
}
|
|
17371
|
+
return out2;
|
|
17372
|
+
}
|
|
17373
|
+
async function run(argv, opts = {}) {
|
|
17374
|
+
const proc = Bun.spawn({
|
|
17375
|
+
cmd: [...argv],
|
|
17376
|
+
stdout: "pipe",
|
|
17377
|
+
stderr: "pipe",
|
|
17378
|
+
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
17379
|
+
cwd: opts.cwd
|
|
17380
|
+
});
|
|
17381
|
+
let timer;
|
|
17382
|
+
let killTimer;
|
|
17383
|
+
if (opts.timeoutMs && opts.timeoutMs > 0) {
|
|
17384
|
+
timer = setTimeout(() => {
|
|
17385
|
+
try {
|
|
17386
|
+
proc.kill("SIGTERM");
|
|
17387
|
+
} catch {}
|
|
17388
|
+
killTimer = setTimeout(() => {
|
|
17389
|
+
try {
|
|
17390
|
+
proc.kill("SIGKILL");
|
|
17391
|
+
} catch {}
|
|
17392
|
+
}, 2000);
|
|
17393
|
+
}, opts.timeoutMs);
|
|
17394
|
+
}
|
|
17395
|
+
try {
|
|
17396
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
17397
|
+
readStreamCapped(proc.stdout),
|
|
17398
|
+
new Response(proc.stderr).text(),
|
|
17399
|
+
proc.exited
|
|
17400
|
+
]);
|
|
17401
|
+
return { stdout, stderr, exitCode };
|
|
17402
|
+
} finally {
|
|
17403
|
+
if (timer)
|
|
17404
|
+
clearTimeout(timer);
|
|
17405
|
+
if (killTimer)
|
|
17406
|
+
clearTimeout(killTimer);
|
|
17407
|
+
}
|
|
17408
|
+
}
|
|
17409
|
+
|
|
17334
17410
|
// ../../loki-ts/src/features/visual_evidence.ts
|
|
17411
|
+
import { spawn as spawn5 } from "child_process";
|
|
17335
17412
|
import { createHash as createHash6, randomBytes as randomBytes2 } from "crypto";
|
|
17336
17413
|
import { existsSync as existsSync15, lstatSync as lstatSync6, mkdirSync as mkdirSync7, readdirSync as readdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync8 } from "fs";
|
|
17337
17414
|
import { createServer } from "net";
|
|
@@ -18015,7 +18092,7 @@ var commitStage = {
|
|
|
18015
18092
|
return sat;
|
|
18016
18093
|
if (drop.length > 0 && (await git(ctx, ["--literal-pathspecs", "reset", "-q", ctx.baseSha, "--", ...drop.map(({ f }) => f)])).code !== 0)
|
|
18017
18094
|
return { status: "failed", data: {}, reason: "git reset failed" };
|
|
18018
|
-
const
|
|
18095
|
+
const dropped2 = new Set(drop.map(({ f }) => f)), notes = flagOutsideScope(ctx.outputs(), staged.filter(({ f }) => !dropped2.has(f)));
|
|
18019
18096
|
if ((await git(ctx, ["diff", "--cached", "--quiet"])).code === 0)
|
|
18020
18097
|
return { status: "completed", data: { committed: false, scope_notes: notes } };
|
|
18021
18098
|
const title = (str3(ctx.outputs().intake?.title) ?? `run ${ctx.runId}`).split(`
|
|
@@ -18105,6 +18182,8 @@ var sealStage = {
|
|
|
18105
18182
|
}
|
|
18106
18183
|
if (wallNotRun > 0)
|
|
18107
18184
|
notProven.add(`wall base run not_run: ${wallNotRun}`);
|
|
18185
|
+
for (const d of Array.isArray(o.wall?.discarded) ? o.wall.discarded : [])
|
|
18186
|
+
notProven.add(`wall test discarded: ${String(d.file)} (${String(d.reason)})`);
|
|
18108
18187
|
if (wallNotRun > 0) {
|
|
18109
18188
|
try {
|
|
18110
18189
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename10(String(f.path))));
|
|
@@ -18115,7 +18194,7 @@ var sealStage = {
|
|
|
18115
18194
|
}
|
|
18116
18195
|
if (!diffOk)
|
|
18117
18196
|
notProven.add("diff not computed (git diff-tree failed)");
|
|
18118
|
-
const
|
|
18197
|
+
const dropped2 = new Set;
|
|
18119
18198
|
const tcs = o.verify?.["test_counts"];
|
|
18120
18199
|
const cnt = (x) => {
|
|
18121
18200
|
const c = x;
|
|
@@ -18130,7 +18209,7 @@ var sealStage = {
|
|
|
18130
18209
|
const mine = assertDeltaNotes(ctx.repoDir, ctx.baseSha, head, t, str3(o.intake?.task) ?? "", cnt(tc?.b), cnt(tc?.h));
|
|
18131
18210
|
if (!mine || mine.length !== vl.length || mine.some((n2) => !vl.includes(n2)))
|
|
18132
18211
|
for (const v of vl)
|
|
18133
|
-
|
|
18212
|
+
dropped2.add(v);
|
|
18134
18213
|
}
|
|
18135
18214
|
for (const c of checks)
|
|
18136
18215
|
if (c.result === "not_run")
|
|
@@ -18138,7 +18217,7 @@ var sealStage = {
|
|
|
18138
18217
|
for (const f of strs2(o.verify?.flaky))
|
|
18139
18218
|
notProven.add(`flaky test: ${f}`);
|
|
18140
18219
|
for (const n2 of verifyNotProven)
|
|
18141
|
-
if (!
|
|
18220
|
+
if (!dropped2.has(n2))
|
|
18142
18221
|
notProven.add(n2);
|
|
18143
18222
|
for (const n2 of [...strs2(o.commit?.not_proven), ...strs2(o.commit?.scope_notes)])
|
|
18144
18223
|
notProven.add(n2);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS `ask_threads` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`created_at` text NOT NULL,
|
|
4
|
+
`updated_at` text NOT NULL,
|
|
5
|
+
`repo` text,
|
|
6
|
+
`provider` text NOT NULL,
|
|
7
|
+
`model` text,
|
|
8
|
+
`title` text
|
|
9
|
+
);
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
CREATE TABLE IF NOT EXISTS `ask_messages` (
|
|
12
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
13
|
+
`thread_id` text NOT NULL,
|
|
14
|
+
`seq` integer NOT NULL,
|
|
15
|
+
`role` text NOT NULL,
|
|
16
|
+
`text` text NOT NULL,
|
|
17
|
+
`status` text NOT NULL,
|
|
18
|
+
`worker_pid` integer,
|
|
19
|
+
`pgid` integer,
|
|
20
|
+
`cost_usd` real,
|
|
21
|
+
`error` text,
|
|
22
|
+
`started_at` text,
|
|
23
|
+
`finished_at` text,
|
|
24
|
+
FOREIGN KEY (`thread_id`) REFERENCES `ask_threads`(`id`) ON UPDATE no action ON DELETE no action
|
|
25
|
+
);
|
|
26
|
+
--> statement-breakpoint
|
|
27
|
+
CREATE UNIQUE INDEX IF NOT EXISTS `ask_messages_thread_seq` ON `ask_messages` (`thread_id`,`seq`);--> statement-breakpoint
|
|
28
|
+
CREATE INDEX IF NOT EXISTS `ask_messages_status` ON `ask_messages` (`status`);--> statement-breakpoint
|
|
29
|
+
CREATE TABLE IF NOT EXISTS `ask_events` (
|
|
30
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
31
|
+
`message_id` text NOT NULL,
|
|
32
|
+
`seq` integer NOT NULL,
|
|
33
|
+
`kind` text NOT NULL,
|
|
34
|
+
`payload` text NOT NULL,
|
|
35
|
+
`ts` text NOT NULL,
|
|
36
|
+
FOREIGN KEY (`message_id`) REFERENCES `ask_messages`(`id`) ON UPDATE no action ON DELETE no action
|
|
37
|
+
);
|
|
38
|
+
--> statement-breakpoint
|
|
39
|
+
CREATE UNIQUE INDEX IF NOT EXISTS `ask_events_message_seq` ON `ask_events` (`message_id`,`seq`);
|