@inerrata-corporation/errata 2.0.2-dev.204 → 2.0.2-dev.208

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.
Files changed (2) hide show
  1. package/errata.mjs +86 -14
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -25270,15 +25270,17 @@ function triageBullet(ref) {
25270
25270
  }
25271
25271
  function linkBullet(ref) {
25272
25272
  return [
25273
- " \u2022 you flagged a problem \u2014 LINK it, and do it ESPECIALLY when the finding feels novel.",
25274
- " Work you just did feels specific to here; that feeling is why links go unwritten, and it is",
25275
- " exactly backwards \u2014 a finding nobody can reach from anywhere else is one nobody reuses:",
25273
+ // Lead-in states the trigger without the old "resembles prior knowledge"
25274
+ // conditional (which gated the whole bullet on recognising a prior). Kept to ONE
25275
+ // line on purpose: Cycle 13 measured this instruction at 55% of the 9,000-char
25276
+ // passive-context budget, and every char here is paid for by evicting a prior the
25277
+ // agent could have cited — so unproven framing is a net loss, however good it reads.
25278
+ " \u2022 you flagged a problem \u2014 LINK it, ESPECIALLY when the finding feels novel to here:",
25276
25279
  ` \xB7 (instance:[${ref}],[another-prior],\u2026) \u2014 the priors this problem is an instance of.`,
25277
25280
  " Aim for ~3 DIFFERENT relevant priors; one link is weak, three triangulate it.",
25278
25281
  ` \xB7 ${TAG_EXAMPLE.pattern()} \u2014 name the general shape it instantiates (e.g. (pattern: unbounded`,
25279
25282
  " queue growth under backpressure)) \u2014 this works with NO code anchor, and two agents naming",
25280
- " the same pattern converge on one node. Naming the shape costs your finding nothing and is",
25281
- " what lets a stranger hit it. Cite a shown Pattern by handle: (pattern:[handle]).",
25283
+ " the same pattern converge on one node. Cite a shown Pattern by handle: (pattern:[handle]).",
25282
25284
  ` \xB7 ${TAG_EXAMPLE.package()} \u2014 the PUBLIC PACKAGE the problem is about, even when this`,
25283
25285
  " workspace doesn't depend on it (e.g. (package: chokidar), (package: pypi/requests)) \u2014 a",
25284
25286
  " public-registry anchor lets the knowledge cross to the collective; internal names stay private.",
@@ -25385,7 +25387,7 @@ var init_agent_signals = __esm({
25385
25387
  // contribution, so stating the general area reads as vague restatement — exactly
25386
25388
  // when it matters most, because precise wording is what makes a problem
25387
25389
  // unfindable to anyone who doesn't already share it.
25388
- domain: "you flagged a problem that isn't about one specific file \u2014 name the AREA it's about. Precision is not a substitute: the sharper your wording, the LESS anyone else will search for it, and an abstract problem with no area is an invisible island. Title Case",
25390
+ domain: "you flagged a problem that isn't about one specific file \u2014 name the AREA it's about. The sharper your wording, the LESS anyone else will search for it; an abstract problem with no area is an invisible island. Title Case",
25389
25391
  link: "the problem you flagged is an instance of priors/abstractions you can name \u2014 (instance:[h1],[h2],\u2026) / (pattern: \u2026) / (aids:[h]); rendered whole via linkBullet"
25390
25392
  };
25391
25393
  }
@@ -49650,6 +49652,39 @@ init_review2();
49650
49652
  import { closeSync, existsSync as existsSync12, fstatSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync3 } from "node:fs";
49651
49653
  import { basename as basename3, dirname as dirname8, join as join15 } from "node:path";
49652
49654
  import { homedir as homedir3 } from "node:os";
49655
+ function readFrom(path2, fromByte) {
49656
+ let fd;
49657
+ try {
49658
+ fd = openSync(path2, "r");
49659
+ } catch {
49660
+ return { text: "", nextOffset: fromByte };
49661
+ }
49662
+ try {
49663
+ const size = fstatSync(fd).size;
49664
+ const start2 = fromByte > 0 && fromByte <= size ? fromByte : 0;
49665
+ const len = size - start2;
49666
+ if (len <= 0) return { text: "", nextOffset: size };
49667
+ const buf = Buffer.allocUnsafe(len);
49668
+ readSync(fd, buf, 0, len, start2);
49669
+ return { text: buf.toString("utf8"), nextOffset: size };
49670
+ } catch {
49671
+ return { text: "", nextOffset: fromByte };
49672
+ } finally {
49673
+ closeSync(fd);
49674
+ }
49675
+ }
49676
+ function transcriptSize(path2) {
49677
+ try {
49678
+ const fd = openSync(path2, "r");
49679
+ try {
49680
+ return fstatSync(fd).size;
49681
+ } finally {
49682
+ closeSync(fd);
49683
+ }
49684
+ } catch {
49685
+ return 0;
49686
+ }
49687
+ }
49653
49688
  function readTail(path2, maxBytes) {
49654
49689
  let fd;
49655
49690
  try {
@@ -49727,7 +49762,13 @@ function isUserTurnBoundary(obj) {
49727
49762
  return blocks.some((b) => b["type"] === "text");
49728
49763
  }
49729
49764
  function readAssistantTurns(transcriptPath, includeThinking = true, maxBytes = 2e6) {
49730
- const raw2 = readTail(transcriptPath, maxBytes);
49765
+ return parseAssistantTurns(readTail(transcriptPath, maxBytes), includeThinking);
49766
+ }
49767
+ function readAssistantTurnsFrom(transcriptPath, fromByte, includeThinking = true) {
49768
+ const { text, nextOffset } = readFrom(transcriptPath, fromByte);
49769
+ return { turns: parseAssistantTurns(text, includeThinking), nextOffset };
49770
+ }
49771
+ function parseAssistantTurns(raw2, includeThinking) {
49731
49772
  if (!raw2) return [];
49732
49773
  const turns = [];
49733
49774
  const lines = raw2.split(/\r?\n/);
@@ -52274,7 +52315,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
52274
52315
  }
52275
52316
 
52276
52317
  // src/engine.ts
52277
- var DAEMON_VERSION = true ? "2.0.2-dev.204" : "2.0.0-alpha.0";
52318
+ var DAEMON_VERSION = true ? "2.0.2-dev.208" : "2.0.0-alpha.0";
52278
52319
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
52279
52320
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
52280
52321
  var GIT_OP_MUTE_MS = 4e3;
@@ -52294,14 +52335,33 @@ function appendIdentityAudit(path2, record2, line) {
52294
52335
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
52295
52336
  function loadTurnCursors(path2) {
52296
52337
  try {
52297
- return new Map(Object.entries(JSON.parse(readFileSync18(path2, "utf8"))));
52338
+ const raw2 = JSON.parse(readFileSync18(path2, "utf8"));
52339
+ return new Map(
52340
+ Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
52341
+ );
52298
52342
  } catch {
52299
52343
  return /* @__PURE__ */ new Map();
52300
52344
  }
52301
52345
  }
52302
- function saveTurnCursors(path2, cursors) {
52346
+ function loadTurnOffsets(path2) {
52303
52347
  try {
52304
- writeFileSync15(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
52348
+ const raw2 = JSON.parse(readFileSync18(path2, "utf8"));
52349
+ const out2 = /* @__PURE__ */ new Map();
52350
+ for (const [k, v] of Object.entries(raw2)) {
52351
+ const off = typeof v === "object" && v !== null ? v.offset : void 0;
52352
+ if (typeof off === "number" && off >= 0) out2.set(k, off);
52353
+ }
52354
+ return out2;
52355
+ } catch {
52356
+ return /* @__PURE__ */ new Map();
52357
+ }
52358
+ }
52359
+ function saveTurnCursors(path2, cursors, offsets) {
52360
+ try {
52361
+ const merged = {};
52362
+ for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
52363
+ for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
52364
+ writeFileSync15(path2, JSON.stringify(merged), "utf8");
52305
52365
  } catch {
52306
52366
  }
52307
52367
  }
@@ -52818,6 +52878,7 @@ function createWorkspaceEngine(opts) {
52818
52878
  };
52819
52879
  const turnCursorPath = join23(paths.configDir, "turn-cursors.json");
52820
52880
  const lastTurnUuid = loadTurnCursors(turnCursorPath);
52881
+ const turnOffset = loadTurnOffsets(turnCursorPath);
52821
52882
  const sessionLastProblem = /* @__PURE__ */ new Map();
52822
52883
  const sessionThreads = /* @__PURE__ */ new Map();
52823
52884
  const harvestTexts = async (sessionId, items) => {
@@ -53221,17 +53282,28 @@ function createWorkspaceEngine(opts) {
53221
53282
  }
53222
53283
  };
53223
53284
  const harvestTurns = async (sessionId, transcriptPath) => {
53285
+ const known = turnOffset.get(sessionId);
53224
53286
  let turns;
53287
+ let nextOffset;
53225
53288
  try {
53226
- turns = readAssistantTurns(transcriptPath);
53289
+ if (known === void 0) {
53290
+ turns = readAssistantTurns(transcriptPath);
53291
+ nextOffset = transcriptSize(transcriptPath);
53292
+ } else {
53293
+ ({ turns, nextOffset } = readAssistantTurnsFrom(transcriptPath, known));
53294
+ }
53227
53295
  } catch {
53228
53296
  return;
53229
53297
  }
53230
53298
  const fresh = turnsSince(turns, lastTurnUuid.get(sessionId));
53231
- if (fresh.length === 0) return;
53299
+ turnOffset.set(sessionId, nextOffset);
53300
+ if (fresh.length === 0) {
53301
+ saveTurnCursors(turnCursorPath, lastTurnUuid, turnOffset);
53302
+ return;
53303
+ }
53232
53304
  lastTurnUuid.set(sessionId, turns[turns.length - 1].uuid);
53233
53305
  await harvestTexts(sessionId, fresh);
53234
- saveTurnCursors(turnCursorPath, lastTurnUuid);
53306
+ saveTurnCursors(turnCursorPath, lastTurnUuid, turnOffset);
53235
53307
  };
53236
53308
  const seenMessageIds = /* @__PURE__ */ new Set();
53237
53309
  const onMessage = (e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.204",
3
+ "version": "2.0.2-dev.208",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {