@inerrata-corporation/errata 2.0.23-dev.4864 → 2.0.23-dev.4881
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
CHANGED
|
@@ -78601,7 +78601,7 @@ var init_report_render = __esm({
|
|
|
78601
78601
|
|
|
78602
78602
|
// src/cli.ts
|
|
78603
78603
|
init_src6();
|
|
78604
|
-
import { closeSync as closeSync3, existsSync as existsSync41, openSync as openSync3, readFileSync as readFileSync49, renameSync as renameSync10, statSync as statSync17 } from "node:fs";
|
|
78604
|
+
import { closeSync as closeSync3, existsSync as existsSync41, openSync as openSync3, readFileSync as readFileSync49, renameSync as renameSync10, statSync as statSync17, writeFileSync as writeFileSync34 } from "node:fs";
|
|
78605
78605
|
import { join as join57, resolve as pathResolve2 } from "node:path";
|
|
78606
78606
|
import { spawn as spawn5 } from "node:child_process";
|
|
78607
78607
|
|
|
@@ -88321,7 +88321,7 @@ function createWatchBreaker(deps) {
|
|
|
88321
88321
|
}
|
|
88322
88322
|
|
|
88323
88323
|
// src/engine.ts
|
|
88324
|
-
var DAEMON_VERSION = true ? "2.0.23-dev.
|
|
88324
|
+
var DAEMON_VERSION = true ? "2.0.23-dev.4881" : "2.0.0-alpha.0";
|
|
88325
88325
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
88326
88326
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
88327
88327
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -93399,15 +93399,20 @@ async function runInstalledHookRefresh() {
|
|
|
93399
93399
|
child.on("close", (code) => resolve11(code === 0 ? output.trim() : ""));
|
|
93400
93400
|
});
|
|
93401
93401
|
if (!isAbsolute6(root)) return 1;
|
|
93402
|
-
|
|
93403
|
-
|
|
93404
|
-
|
|
93405
|
-
|
|
93406
|
-
|
|
93402
|
+
let worst = 0;
|
|
93403
|
+
for (const harness of ["codex", "claude"]) {
|
|
93404
|
+
const code = await new Promise((resolve11) => {
|
|
93405
|
+
const child = spawn2(process.execPath, [join42(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", harness, "--refresh-existing"], {
|
|
93406
|
+
windowsHide: true,
|
|
93407
|
+
stdio: "inherit",
|
|
93408
|
+
timeout: 3e4
|
|
93409
|
+
});
|
|
93410
|
+
child.on("error", () => resolve11(1));
|
|
93411
|
+
child.on("close", (exit) => resolve11(exit ?? 1));
|
|
93407
93412
|
});
|
|
93408
|
-
|
|
93409
|
-
|
|
93410
|
-
|
|
93413
|
+
worst = Math.max(worst, code);
|
|
93414
|
+
}
|
|
93415
|
+
return worst;
|
|
93411
93416
|
}
|
|
93412
93417
|
|
|
93413
93418
|
// src/multi.ts
|
|
@@ -99663,6 +99668,50 @@ function installedHookPort(settingsText) {
|
|
|
99663
99668
|
}
|
|
99664
99669
|
return null;
|
|
99665
99670
|
}
|
|
99671
|
+
var ERRATA_HOOK_TAG = "# errata-managed";
|
|
99672
|
+
function claudeErrataHookGroups(port) {
|
|
99673
|
+
const matcher = "Read|Edit|Write|Grep|Glob|NotebookEdit|Bash";
|
|
99674
|
+
const postMatcher = `${matcher}|ToolSearch|mcp__errata__.*`;
|
|
99675
|
+
const preMatcher = `${matcher}|Agent|Task`;
|
|
99676
|
+
const command = (cmd2) => [{ type: "command", command: `${cmd2} ${ERRATA_HOOK_TAG}` }];
|
|
99677
|
+
const toolHook = command(hookRelayCommand(port, "/api/hook"));
|
|
99678
|
+
const turn = command(hookCurlCommand(port, "/api/turn"));
|
|
99679
|
+
const inject = command(hookRelayCommand(port, "/api/context-inject"));
|
|
99680
|
+
return {
|
|
99681
|
+
PreToolUse: { matcher: preMatcher, hooks: toolHook },
|
|
99682
|
+
PostToolUse: { matcher: postMatcher, hooks: toolHook },
|
|
99683
|
+
PostToolUseFailure: { matcher: postMatcher, hooks: toolHook },
|
|
99684
|
+
Stop: { hooks: turn },
|
|
99685
|
+
SubagentStop: { hooks: turn },
|
|
99686
|
+
// The assistant's prose delivered LIVE by the harness: the transcript jsonl
|
|
99687
|
+
// drops mid-turn assistant text (anthropics/claude-code#21751), so this is the
|
|
99688
|
+
// reliable channel for inline tags and /api/turn is the backfill.
|
|
99689
|
+
MessageDisplay: { hooks: command(hookCurlCommand(port, "/api/message")) },
|
|
99690
|
+
// The gated end-of-session roll-up (P3).
|
|
99691
|
+
SessionEnd: { hooks: command(hookCurlCommand(port, "/api/session-end")) },
|
|
99692
|
+
SessionStart: { hooks: inject },
|
|
99693
|
+
UserPromptSubmit: { hooks: inject },
|
|
99694
|
+
SubagentStart: { hooks: inject }
|
|
99695
|
+
};
|
|
99696
|
+
}
|
|
99697
|
+
function applyClaudeErrataHooks(settings, port) {
|
|
99698
|
+
settings.hooks ??= {};
|
|
99699
|
+
for (const [event, group] of Object.entries(claudeErrataHookGroups(port))) {
|
|
99700
|
+
const list = settings.hooks[event] ??= [];
|
|
99701
|
+
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
99702
|
+
if (list[i2].hooks?.some((h) => typeof h.command === "string" && h.command.includes(ERRATA_HOOK_TAG))) list.splice(i2, 1);
|
|
99703
|
+
}
|
|
99704
|
+
list.push(group);
|
|
99705
|
+
}
|
|
99706
|
+
}
|
|
99707
|
+
function refreshClaudeHookSettings(text) {
|
|
99708
|
+
const port = installedHookPort(text);
|
|
99709
|
+
if (port === null) return null;
|
|
99710
|
+
const settings = JSON.parse(text);
|
|
99711
|
+
applyClaudeErrataHooks(settings, port);
|
|
99712
|
+
const next = JSON.stringify(settings, null, 2) + "\n";
|
|
99713
|
+
return next === text.replace(/\r\n/g, "\n") ? null : next;
|
|
99714
|
+
}
|
|
99666
99715
|
|
|
99667
99716
|
// src/codex-hook-relay.ts
|
|
99668
99717
|
var CODEX_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata install-hooks codex
|
|
@@ -101599,6 +101648,7 @@ async function cmdNotifyTest() {
|
|
|
101599
101648
|
}
|
|
101600
101649
|
async function cmdStart() {
|
|
101601
101650
|
refreshExistingCodexHooks();
|
|
101651
|
+
refreshExistingClaudeHooks();
|
|
101602
101652
|
if (!loadProfile(ROOT)) {
|
|
101603
101653
|
const cfg = loadConfig();
|
|
101604
101654
|
const locator = detectRepoLocator(ROOT);
|
|
@@ -102076,7 +102126,7 @@ async function cmdUpdate(args2) {
|
|
|
102076
102126
|
const code = await runNpmInstall(channel);
|
|
102077
102127
|
if (code === 0) {
|
|
102078
102128
|
if (await runInstalledHookRefresh() !== 0) {
|
|
102079
|
-
console.warn("[!] Package updated, but some
|
|
102129
|
+
console.warn("[!] Package updated, but some existing hooks could not be refreshed. Run `errata install-hooks codex --refresh-existing` and `errata install-hooks claude --refresh-existing`; daemon startup also retries.");
|
|
102080
102130
|
}
|
|
102081
102131
|
console.log(`
|
|
102082
102132
|
[OK] updated to ${status.latest}. Restart the daemon to run it:`);
|
|
@@ -103459,7 +103509,7 @@ async function gatherReportData(generatedAt) {
|
|
|
103459
103509
|
};
|
|
103460
103510
|
}
|
|
103461
103511
|
async function cmdReport(args2) {
|
|
103462
|
-
const { mkdirSync: mkdirSync13, writeFileSync:
|
|
103512
|
+
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
103463
103513
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
103464
103514
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
103465
103515
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -103472,7 +103522,7 @@ async function cmdReport(args2) {
|
|
|
103472
103522
|
const outDir = workspacePaths(ROOT).configDir;
|
|
103473
103523
|
mkdirSync13(outDir, { recursive: true });
|
|
103474
103524
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
103475
|
-
for (const f of files)
|
|
103525
|
+
for (const f of files) writeFileSync35(join57(outDir, f.name), f.html, "utf8");
|
|
103476
103526
|
const indexPath = join57(outDir, "report.html");
|
|
103477
103527
|
console.log(`report \u2192 ${indexPath}`);
|
|
103478
103528
|
console.log(
|
|
@@ -103573,6 +103623,10 @@ async function cmdInstallHooks(args2) {
|
|
|
103573
103623
|
const port = resolveHookPort(portIdx >= 0 && args2[portIdx + 1] ? Number(args2[portIdx + 1]) : void 0);
|
|
103574
103624
|
switch (harness) {
|
|
103575
103625
|
case "claude":
|
|
103626
|
+
if (args2.includes("--refresh-existing")) {
|
|
103627
|
+
if (!refreshExistingClaudeHooks()) process.exitCode = 1;
|
|
103628
|
+
return;
|
|
103629
|
+
}
|
|
103576
103630
|
await installClaudeHooks(port);
|
|
103577
103631
|
return;
|
|
103578
103632
|
case "cursor":
|
|
@@ -103598,7 +103652,7 @@ async function cmdInstallHooks(args2) {
|
|
|
103598
103652
|
}
|
|
103599
103653
|
}
|
|
103600
103654
|
async function installOpencodePlugin(port) {
|
|
103601
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync:
|
|
103655
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
103602
103656
|
const { join: join58 } = await import("node:path");
|
|
103603
103657
|
const dir = join58(ROOT, ".opencode", "plugin");
|
|
103604
103658
|
if (!existsSync42(dir)) mkdirSync13(dir, { recursive: true });
|
|
@@ -103610,7 +103664,7 @@ async function installOpencodePlugin(port) {
|
|
|
103610
103664
|
process.exit(2);
|
|
103611
103665
|
}
|
|
103612
103666
|
}
|
|
103613
|
-
|
|
103667
|
+
writeFileSync35(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
103614
103668
|
const cfgFile = join58(ROOT, "opencode.json");
|
|
103615
103669
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
103616
103670
|
if (existsSync42(cfgFile)) {
|
|
@@ -103626,7 +103680,7 @@ async function installOpencodePlugin(port) {
|
|
|
103626
103680
|
if (!hadErrata) {
|
|
103627
103681
|
const inv = errataMcpInvocation();
|
|
103628
103682
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
103629
|
-
|
|
103683
|
+
writeFileSync35(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103630
103684
|
}
|
|
103631
103685
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
103632
103686
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -103640,7 +103694,6 @@ async function installOpencodePlugin(port) {
|
|
|
103640
103694
|
console.log(` Cloud tools (search/contribute) are the MCP entry in opencode.json:`);
|
|
103641
103695
|
console.log(` { "mcp": { "inerrata": { "type": "remote", "url": "${mcpUrlFor(loadConfig().cloudUrl)}", "headers": { "Authorization": "Bearer <errk_\u2026>" } } } }`);
|
|
103642
103696
|
}
|
|
103643
|
-
var ERRATA_TAG = "# errata-managed";
|
|
103644
103697
|
function errataMcpInvocation() {
|
|
103645
103698
|
const { cmd: cmd2, args: args2 } = selfArgv("mcp");
|
|
103646
103699
|
return { command: cmd2, args: args2 };
|
|
@@ -103661,7 +103714,7 @@ function installClaudeMods() {
|
|
|
103661
103714
|
}
|
|
103662
103715
|
}
|
|
103663
103716
|
async function installClaudeHooks(port) {
|
|
103664
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync:
|
|
103717
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
103665
103718
|
const { join: join58 } = await import("node:path");
|
|
103666
103719
|
const dir = join58(ROOT, ".claude");
|
|
103667
103720
|
if (!existsSync42(dir)) mkdirSync13(dir, { recursive: true });
|
|
@@ -103675,50 +103728,9 @@ async function installClaudeHooks(port) {
|
|
|
103675
103728
|
process.exit(2);
|
|
103676
103729
|
}
|
|
103677
103730
|
}
|
|
103678
|
-
|
|
103679
|
-
const postMatcher = `${matcher}|ToolSearch|mcp__errata__.*`;
|
|
103680
|
-
const preMatcher = `${matcher}|Agent|Task`;
|
|
103681
|
-
const preCmd = `${hookRelayCommand(port, "/api/hook")} ${ERRATA_TAG}`;
|
|
103682
|
-
const postCmd = `${hookRelayCommand(port, "/api/hook")} ${ERRATA_TAG}`;
|
|
103683
|
-
settings.hooks ??= {};
|
|
103684
|
-
const dropErrata = (list) => {
|
|
103685
|
-
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
103686
|
-
if (list[i2].hooks.some((h) => h.command.includes(ERRATA_TAG))) list.splice(i2, 1);
|
|
103687
|
-
}
|
|
103688
|
-
};
|
|
103689
|
-
for (const [event, command, eventMatcher] of [
|
|
103690
|
-
["PreToolUse", preCmd, preMatcher],
|
|
103691
|
-
["PostToolUse", postCmd, postMatcher],
|
|
103692
|
-
["PostToolUseFailure", postCmd, postMatcher]
|
|
103693
|
-
]) {
|
|
103694
|
-
const list = settings.hooks[event] ??= [];
|
|
103695
|
-
dropErrata(list);
|
|
103696
|
-
list.push({ matcher: eventMatcher, hooks: [{ type: "command", command }] });
|
|
103697
|
-
}
|
|
103698
|
-
const turnCmd = `${hookCurlCommand(port, "/api/turn")} ${ERRATA_TAG}`;
|
|
103699
|
-
for (const event of ["Stop", "SubagentStop"]) {
|
|
103700
|
-
const list = settings.hooks[event] ??= [];
|
|
103701
|
-
dropErrata(list);
|
|
103702
|
-
list.push({ hooks: [{ type: "command", command: turnCmd }] });
|
|
103703
|
-
}
|
|
103704
|
-
const msgCmd = `${hookCurlCommand(port, "/api/message")} ${ERRATA_TAG}`;
|
|
103705
|
-
{
|
|
103706
|
-
const list = settings.hooks["MessageDisplay"] ??= [];
|
|
103707
|
-
dropErrata(list);
|
|
103708
|
-
list.push({ hooks: [{ type: "command", command: msgCmd }] });
|
|
103709
|
-
}
|
|
103710
|
-
const endCmd = `${hookCurlCommand(port, "/api/session-end")} ${ERRATA_TAG}`;
|
|
103711
|
-
const endList = settings.hooks["SessionEnd"] ??= [];
|
|
103712
|
-
dropErrata(endList);
|
|
103713
|
-
endList.push({ hooks: [{ type: "command", command: endCmd }] });
|
|
103714
|
-
const injectCmd = `${hookRelayCommand(port, "/api/context-inject")} ${ERRATA_TAG}`;
|
|
103715
|
-
for (const event of ["SessionStart", "UserPromptSubmit", "SubagentStart"]) {
|
|
103716
|
-
const list = settings.hooks[event] ??= [];
|
|
103717
|
-
dropErrata(list);
|
|
103718
|
-
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
103719
|
-
}
|
|
103731
|
+
applyClaudeErrataHooks(settings, port);
|
|
103720
103732
|
removeProjectStatusLine(settings);
|
|
103721
|
-
|
|
103733
|
+
writeFileSync35(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
103722
103734
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
103723
103735
|
console.log(` ${ensureStatusLine(port)}`);
|
|
103724
103736
|
console.log(` ${installClaudeMods().line}`);
|
|
@@ -103735,7 +103747,7 @@ async function installClaudeHooks(port) {
|
|
|
103735
103747
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
103736
103748
|
}
|
|
103737
103749
|
async function installClaudeMcpConfig() {
|
|
103738
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync:
|
|
103750
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
103739
103751
|
const { join: join58, dirname: dirname22 } = await import("node:path");
|
|
103740
103752
|
const file2 = join58(ROOT, ".mcp.json");
|
|
103741
103753
|
const dir = dirname22(file2);
|
|
@@ -103751,13 +103763,13 @@ async function installClaudeMcpConfig() {
|
|
|
103751
103763
|
}
|
|
103752
103764
|
cfg.mcpServers ??= {};
|
|
103753
103765
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
103754
|
-
|
|
103766
|
+
writeFileSync35(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103755
103767
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
103756
103768
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
103757
103769
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
103758
103770
|
}
|
|
103759
103771
|
async function installCursorMcpConfig() {
|
|
103760
|
-
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync:
|
|
103772
|
+
const { mkdirSync: mkdirSync13, existsSync: existsSync42, readFileSync: readFileSync50, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
103761
103773
|
const { join: join58 } = await import("node:path");
|
|
103762
103774
|
const dir = join58(ROOT, ".cursor");
|
|
103763
103775
|
if (!existsSync42(dir)) mkdirSync13(dir, { recursive: true });
|
|
@@ -103773,7 +103785,7 @@ async function installCursorMcpConfig() {
|
|
|
103773
103785
|
}
|
|
103774
103786
|
cfg.mcpServers ??= {};
|
|
103775
103787
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
103776
|
-
|
|
103788
|
+
writeFileSync35(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
103777
103789
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
103778
103790
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
103779
103791
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -103828,6 +103840,24 @@ function refreshExistingCodexHooks() {
|
|
|
103828
103840
|
}
|
|
103829
103841
|
return ok;
|
|
103830
103842
|
}
|
|
103843
|
+
function refreshExistingClaudeHooks() {
|
|
103844
|
+
let ok = true;
|
|
103845
|
+
const roots = [...listWorkspaceEntries().map((entry) => entry.path), process.cwd()];
|
|
103846
|
+
for (const root of codexHookRoots(roots)) {
|
|
103847
|
+
const file2 = join57(root, ".claude", "settings.json");
|
|
103848
|
+
try {
|
|
103849
|
+
if (!existsSync41(file2) || isReplayCheckout(root)) continue;
|
|
103850
|
+
const next = refreshClaudeHookSettings(readFileSync49(file2, "utf8"));
|
|
103851
|
+
if (next === null) continue;
|
|
103852
|
+
writeFileSync34(file2, next, "utf8");
|
|
103853
|
+
console.log(`updated existing Claude Code hooks \u2192 ${file2}`);
|
|
103854
|
+
} catch (error48) {
|
|
103855
|
+
ok = false;
|
|
103856
|
+
console.warn(`Claude Code hook refresh needs attention in ${root}: ${error48 instanceof Error ? error48.message : error48}`);
|
|
103857
|
+
}
|
|
103858
|
+
}
|
|
103859
|
+
return ok;
|
|
103860
|
+
}
|
|
103831
103861
|
async function refreshLinkedCodexHooks(args2) {
|
|
103832
103862
|
if (args2.includes("--skip-hooks") || !hasCodexConfig(ROOT)) return;
|
|
103833
103863
|
try {
|
|
@@ -103996,6 +104026,7 @@ async function cmdDash(args2) {
|
|
|
103996
104026
|
process.title = "errata-daemon";
|
|
103997
104027
|
installLogTimestamps();
|
|
103998
104028
|
refreshExistingCodexHooks();
|
|
104029
|
+
refreshExistingClaudeHooks();
|
|
103999
104030
|
const portIdx = args2.indexOf("--port");
|
|
104000
104031
|
const port = portIdx >= 0 && args2[portIdx + 1] ? Number(args2[portIdx + 1]) : 7891;
|
|
104001
104032
|
const reindexOnStart = !args2.includes("--no-reindex");
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
d3a9c0cdb6333538569766d24e122085d18c71a8c767f1b9edd5d73491450f77 .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|