@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.4864" : "2.0.0-alpha.0";
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
- return new Promise((resolve11) => {
93403
- const child = spawn2(process.execPath, [join42(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
93404
- windowsHide: true,
93405
- stdio: "inherit",
93406
- timeout: 3e4
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
- child.on("error", () => resolve11(1));
93409
- child.on("close", (code) => resolve11(code ?? 1));
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 Codex relays could not be refreshed. Run `errata install-hooks codex --refresh-existing`; daemon startup also retries.");
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: writeFileSync34 } = await import("node:fs");
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) writeFileSync34(join57(outDir, f.name), f.html, "utf8");
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: writeFileSync34 } = await import("node:fs");
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
- writeFileSync34(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
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
- writeFileSync34(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
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: writeFileSync34 } = await import("node:fs");
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
- const matcher = "Read|Edit|Write|Grep|Glob|NotebookEdit|Bash";
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
- writeFileSync34(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
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: writeFileSync34 } = await import("node:fs");
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
- writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
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: writeFileSync34 } = await import("node:fs");
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
- writeFileSync34(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.23-dev.4864",
3
+ "version": "2.0.23-dev.4881",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errata-context",
3
- "version": "2.0.23-dev.4864",
3
+ "version": "2.0.23-dev.4881",
4
4
  "description": "A minimal 3D view of loaded Errata priors and recent graph bursts.",
5
5
  "author": {
6
6
  "name": "inErrata"
@@ -1,4 +1,4 @@
1
- d2a34f333032bcc14b4e3da00eaa5038b377c3d0f1e279b9b245e4c1634d5992 .codex-plugin/plugin.json
1
+ d3a9c0cdb6333538569766d24e122085d18c71a8c767f1b9edd5d73491450f77 .codex-plugin/plugin.json
2
2
  a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
3
3
  fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
4
4
  73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js