@inerrata-corporation/errata 2.0.6-dev.2081 → 2.0.6-dev.2082
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/errata.mjs +102 -9
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -77056,7 +77056,7 @@ function createWatchBreaker(deps) {
|
|
|
77056
77056
|
}
|
|
77057
77057
|
|
|
77058
77058
|
// src/engine.ts
|
|
77059
|
-
var DAEMON_VERSION = true ? "2.0.6-dev.
|
|
77059
|
+
var DAEMON_VERSION = true ? "2.0.6-dev.2082" : "2.0.0-alpha.0";
|
|
77060
77060
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
77061
77061
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
77062
77062
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -83159,6 +83159,76 @@ function codexWakeCandidates(input) {
|
|
|
83159
83159
|
return out2;
|
|
83160
83160
|
}
|
|
83161
83161
|
|
|
83162
|
+
// src/hook-route.ts
|
|
83163
|
+
function msysToWindowsPath(p, platform = process.platform) {
|
|
83164
|
+
if (platform !== "win32") return p;
|
|
83165
|
+
const m = /^\/([a-zA-Z])(\/.*)?$/.exec(p);
|
|
83166
|
+
return m ? `${m[1].toUpperCase()}:${m[2] ?? "/"}` : p;
|
|
83167
|
+
}
|
|
83168
|
+
var SHELL_BREAK = /[\s"'`;&|()<>=]+/;
|
|
83169
|
+
function absolutePathsInCommand(command, platform = process.platform) {
|
|
83170
|
+
const out2 = [];
|
|
83171
|
+
for (const raw2 of command.split(SHELL_BREAK)) {
|
|
83172
|
+
const token = raw2.replace(/^[:,]+/, "").replace(/[,:]+$/, "");
|
|
83173
|
+
if (!token) continue;
|
|
83174
|
+
if (/^[a-zA-Z]:[\\/]/.test(token)) {
|
|
83175
|
+
out2.push(token);
|
|
83176
|
+
} else if (token.startsWith("/") && !token.startsWith("//")) {
|
|
83177
|
+
if (platform === "win32") {
|
|
83178
|
+
if (/^\/[a-zA-Z](\/|$)/.test(token)) out2.push(msysToWindowsPath(token, platform));
|
|
83179
|
+
} else if (token.length > 1) {
|
|
83180
|
+
out2.push(token);
|
|
83181
|
+
}
|
|
83182
|
+
}
|
|
83183
|
+
}
|
|
83184
|
+
return out2;
|
|
83185
|
+
}
|
|
83186
|
+
function hookPathCandidates(body2, platform = process.platform) {
|
|
83187
|
+
const input = body2["tool_input"] ?? {};
|
|
83188
|
+
const str = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
83189
|
+
const out2 = [];
|
|
83190
|
+
for (const key of ["file_path", "notebook_path", "path"]) {
|
|
83191
|
+
const v = str(input[key]);
|
|
83192
|
+
if (v) out2.push(msysToWindowsPath(v, platform));
|
|
83193
|
+
}
|
|
83194
|
+
const command = str(input["command"]);
|
|
83195
|
+
if (command) out2.push(...absolutePathsInCommand(command, platform));
|
|
83196
|
+
const cwd = str(body2["cwd"]);
|
|
83197
|
+
if (cwd) out2.push(msysToWindowsPath(cwd, platform));
|
|
83198
|
+
return [...new Set(out2)];
|
|
83199
|
+
}
|
|
83200
|
+
var SESSION_AFFINITY_TTL_MS = 30 * 6e4;
|
|
83201
|
+
var SessionAffinity = class {
|
|
83202
|
+
constructor(ttlMs = SESSION_AFFINITY_TTL_MS, maxSessions = 500) {
|
|
83203
|
+
this.ttlMs = ttlMs;
|
|
83204
|
+
this.maxSessions = maxSessions;
|
|
83205
|
+
}
|
|
83206
|
+
bySession = /* @__PURE__ */ new Map();
|
|
83207
|
+
note(sessionId, root, now = Date.now()) {
|
|
83208
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) return;
|
|
83209
|
+
this.bySession.delete(sessionId);
|
|
83210
|
+
this.bySession.set(sessionId, { root, at: now });
|
|
83211
|
+
while (this.bySession.size > this.maxSessions) {
|
|
83212
|
+
const oldest = this.bySession.keys().next().value;
|
|
83213
|
+
if (oldest === void 0) break;
|
|
83214
|
+
this.bySession.delete(oldest);
|
|
83215
|
+
}
|
|
83216
|
+
}
|
|
83217
|
+
rootFor(sessionId, now = Date.now()) {
|
|
83218
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) return null;
|
|
83219
|
+
const hit = this.bySession.get(sessionId);
|
|
83220
|
+
if (!hit) return null;
|
|
83221
|
+
if (now - hit.at > this.ttlMs) {
|
|
83222
|
+
this.bySession.delete(sessionId);
|
|
83223
|
+
return null;
|
|
83224
|
+
}
|
|
83225
|
+
return hit.root;
|
|
83226
|
+
}
|
|
83227
|
+
forget(sessionId) {
|
|
83228
|
+
if (typeof sessionId === "string") this.bySession.delete(sessionId);
|
|
83229
|
+
}
|
|
83230
|
+
};
|
|
83231
|
+
|
|
83162
83232
|
// src/multi.ts
|
|
83163
83233
|
var projectSymbolSalts = /* @__PURE__ */ new Map();
|
|
83164
83234
|
async function resolveProjectSymbolSalt(client, projectId) {
|
|
@@ -83609,7 +83679,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
83609
83679
|
}))
|
|
83610
83680
|
})
|
|
83611
83681
|
);
|
|
83612
|
-
const
|
|
83682
|
+
const sessionAffinity = new SessionAffinity();
|
|
83683
|
+
const forward = async (c, pathInBody, opts2 = {}) => {
|
|
83613
83684
|
const raw2 = await c.req.text();
|
|
83614
83685
|
let body2 = {};
|
|
83615
83686
|
try {
|
|
@@ -83618,7 +83689,21 @@ async function startMultiDaemon(opts = {}) {
|
|
|
83618
83689
|
return c.json({ error: "bad-json" }, 400);
|
|
83619
83690
|
}
|
|
83620
83691
|
lastHook = { at: Date.now(), event: typeof body2["hook_event_name"] === "string" ? body2["hook_event_name"] : c.req.path };
|
|
83621
|
-
|
|
83692
|
+
const primary = pathInBody(body2);
|
|
83693
|
+
const others = (opts2.extraPaths?.(body2) ?? []).filter((p) => p !== primary);
|
|
83694
|
+
let owner = ownerOf(records, primary);
|
|
83695
|
+
for (const p of others) {
|
|
83696
|
+
if (owner) break;
|
|
83697
|
+
owner = ownerOf(records, p);
|
|
83698
|
+
}
|
|
83699
|
+
if (!owner && others.length > 0) {
|
|
83700
|
+
const registryRoots = listWorkspaceEntries().map((e) => e.path);
|
|
83701
|
+
const registered = others.map((p) => pickOwnerRoot(registryRoots, p)).find((r) => r != null);
|
|
83702
|
+
if (registered && attachWorkspace(registered).attached) {
|
|
83703
|
+
owner = records.find((r) => r.root === registered) ?? null;
|
|
83704
|
+
if (owner) console.log(`[errata] woke workspace ${owner.entry.name}`);
|
|
83705
|
+
}
|
|
83706
|
+
}
|
|
83622
83707
|
if (!owner) {
|
|
83623
83708
|
const missPath = pathInBody(body2);
|
|
83624
83709
|
const registeredRoot = missPath ? pickOwnerRoot(listWorkspaceEntries().map((e) => e.path), missPath) : null;
|
|
@@ -83628,10 +83713,18 @@ async function startMultiDaemon(opts = {}) {
|
|
|
83628
83713
|
if (owner) console.log(`[errata] woke workspace ${owner.entry.name}`);
|
|
83629
83714
|
}
|
|
83630
83715
|
}
|
|
83716
|
+
if (!owner && opts2.affinity === "follow") {
|
|
83717
|
+
const root = sessionAffinity.rootFor(body2["session_id"]);
|
|
83718
|
+
if (root) {
|
|
83719
|
+
owner = records.find((r) => r.root === root) ?? null;
|
|
83720
|
+
if (!owner && attachWorkspace(root).attached) owner = records.find((r) => r.root === root) ?? null;
|
|
83721
|
+
}
|
|
83722
|
+
}
|
|
83631
83723
|
if (!owner) {
|
|
83632
|
-
rootAdopter.noteMiss(
|
|
83724
|
+
rootAdopter.noteMiss(primary);
|
|
83633
83725
|
return c.json({ error: "no-matching-project" }, 404);
|
|
83634
83726
|
}
|
|
83727
|
+
if (opts2.affinity === "note") sessionAffinity.note(body2["session_id"], owner.root);
|
|
83635
83728
|
owner.lastHookAt = Date.now();
|
|
83636
83729
|
const sub = c.req.path;
|
|
83637
83730
|
const done = markPass(`${sub}:${owner.entry.name}`);
|
|
@@ -83654,7 +83747,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
83654
83747
|
const fp = input["file_path"];
|
|
83655
83748
|
const cwd = b["cwd"];
|
|
83656
83749
|
return (typeof fp === "string" ? fp : void 0) ?? (typeof cwd === "string" ? cwd : void 0);
|
|
83657
|
-
})
|
|
83750
|
+
}, { extraPaths: (b) => hookPathCandidates(b), affinity: "note" })
|
|
83658
83751
|
);
|
|
83659
83752
|
app.post(
|
|
83660
83753
|
"/api/diagnostics",
|
|
@@ -83664,10 +83757,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
83664
83757
|
})
|
|
83665
83758
|
);
|
|
83666
83759
|
const cwdOf = (b) => typeof b["cwd"] === "string" ? b["cwd"] : void 0;
|
|
83667
|
-
app.post("/api/turn", (c) => forward(c, cwdOf));
|
|
83668
|
-
app.post("/api/message", (c) => forward(c, cwdOf));
|
|
83669
|
-
app.post("/api/session-end", (c) => forward(c, cwdOf));
|
|
83670
|
-
app.post("/api/context-inject", (c) => forward(c, cwdOf));
|
|
83760
|
+
app.post("/api/turn", (c) => forward(c, cwdOf, { affinity: "follow" }));
|
|
83761
|
+
app.post("/api/message", (c) => forward(c, cwdOf, { affinity: "follow" }));
|
|
83762
|
+
app.post("/api/session-end", (c) => forward(c, cwdOf, { affinity: "follow" }));
|
|
83763
|
+
app.post("/api/context-inject", (c) => forward(c, cwdOf, { affinity: "follow" }));
|
|
83671
83764
|
for (const r of records) {
|
|
83672
83765
|
mountedIds.add(r.id);
|
|
83673
83766
|
app.route(`/ws/${r.id}`, r.webApp);
|