@inerrata-corporation/errata 2.0.6-dev.2505 → 2.0.6-dev.2511

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 +47 -8
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -24184,7 +24184,12 @@ function renderSnapshot(s) {
24184
24184
  if (s.pendingUpdate) {
24185
24185
  lines.push("### \u26A1 errata update available");
24186
24186
  lines.push(
24187
- `\`${s.pendingUpdate.current}\` \u2192 \`${s.pendingUpdate.latest}\` on the \`${s.pendingUpdate.channel}\` channel. Tell your user \u2014 or run \`errata update\` yourself if they've asked you to keep errata current. It restarts the daemon; that's safe mid-session (hooks fail open, MCP reconnects).`
24187
+ `\`${s.pendingUpdate.current}\` \u2192 \`${s.pendingUpdate.latest}\` on the \`${s.pendingUpdate.channel}\` channel. ` + (s.pendingUpdate.localBuildEntry ? (
24188
+ // A local build holds the lock and `errata update` cannot replace it, so
24189
+ // "run errata update" was an instruction that could never clear this
24190
+ // notice (dogfood 2026-09-20: it nagged every prompt for days).
24191
+ `This daemon is a LOCAL BUILD running from \`${s.pendingUpdate.localBuildEntry}\`, which \`errata update\` does not replace. Tell your user \u2014 or, if they've asked you to keep errata current: \`errata update\`, then \`errata stop\`, then \`errata dash\` to start the installed one. `
24192
+ ) : "Tell your user \u2014 or, if they've asked you to keep errata current, run `errata update` and then `errata stop`: update only INSTALLS, and the running daemon stays on the old build until it is restarted. ") + "A restart is safe mid-session (hooks fail open, MCP reconnects)."
24188
24193
  );
24189
24194
  lines.push("");
24190
24195
  }
@@ -70828,7 +70833,7 @@ var init_report_render = __esm({
70828
70833
  // src/cli.ts
70829
70834
  init_src6();
70830
70835
  import { closeSync as closeSync2, existsSync as existsSync33, openSync as openSync2, readFileSync as readFileSync32, renameSync as renameSync4, statSync as statSync8 } from "node:fs";
70831
- import { join as join37, resolve as pathResolve } from "node:path";
70836
+ import { join as join37, resolve as pathResolve2 } from "node:path";
70832
70837
  import { spawn as spawn3 } from "node:child_process";
70833
70838
 
70834
70839
  // src/daemon.ts
@@ -78138,7 +78143,7 @@ function createWatchBreaker(deps) {
78138
78143
  }
78139
78144
 
78140
78145
  // src/engine.ts
78141
- var DAEMON_VERSION = true ? "2.0.6-dev.2505" : "2.0.0-alpha.0";
78146
+ var DAEMON_VERSION = true ? "2.0.6-dev.2511" : "2.0.0-alpha.0";
78142
78147
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
78143
78148
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
78144
78149
  var GIT_OP_MUTE_MS = 4e3;
@@ -80515,6 +80520,7 @@ init_identity2();
80515
80520
  init_dist();
80516
80521
  init_src5();
80517
80522
  import { existsSync as existsSync32, readFileSync as readFileSync31, unlinkSync as unlinkSync3, writeFileSync as writeFileSync23 } from "node:fs";
80523
+ import { resolve as pathResolve } from "node:path";
80518
80524
 
80519
80525
  // src/principle-sync.ts
80520
80526
  init_src5();
@@ -81502,9 +81508,28 @@ function daemonLockPayload(lock) {
81502
81508
  pid: lock.pid,
81503
81509
  webUiUrl: lock.webUiUrl,
81504
81510
  startedAt: lock.processStartedAt,
81505
- ...lock.wokeAt !== void 0 ? { wokeAt: lock.wokeAt } : {}
81511
+ ...lock.wokeAt !== void 0 ? { wokeAt: lock.wokeAt } : {},
81512
+ ...lock.entry ? { entry: lock.entry } : {},
81513
+ ...lock.version ? { version: lock.version } : {}
81506
81514
  });
81507
81515
  }
81516
+ var normEntry = (p) => {
81517
+ const s = p.replace(/\\/g, "/").replace(/\/+$/, "");
81518
+ return /^[A-Za-z]:\//.test(s) ? s.toLowerCase() : s;
81519
+ };
81520
+ function isInstalledEntry(entry) {
81521
+ return /\/node_modules\/@inerrata-corporation\/errata\//.test(normEntry(entry) + "/");
81522
+ }
81523
+ function foreignDaemonNote(lock, selfEntry) {
81524
+ if (!lock.entry || normEntry(lock.entry) === normEntry(selfEntry)) return null;
81525
+ const runningInstalled = isInstalledEntry(lock.entry);
81526
+ const head2 = [
81527
+ `launched from ${runningInstalled ? "the installed package" : "a LOCAL BUILD"}, not this one${lock.version ? ` (it is ${lock.version})` : ""}:`,
81528
+ ` running: ${lock.entry}`,
81529
+ ` this: ${selfEntry}`
81530
+ ];
81531
+ return runningInstalled ? [...head2, "this CLI is a different bundle from the daemon it is talking to \u2014 its view may not match what the daemon runs."] : [...head2, "`errata update` does not replace it. To move onto the installed package: errata stop, then errata dash."];
81532
+ }
81508
81533
  function isProcessAlive(pid) {
81509
81534
  if (!pid || pid <= 0) return false;
81510
81535
  try {
@@ -84450,6 +84475,12 @@ var SessionAffinity = class {
84450
84475
 
84451
84476
  // src/multi.ts
84452
84477
  var PROCESS_STARTED_AT = Date.now();
84478
+ var SELF_ENTRY = process.argv[1] ? pathResolve(process.argv[1]) : "";
84479
+ var LOCAL_BUILD_ENTRY = SELF_ENTRY && !isInstalledEntry(SELF_ENTRY) ? SELF_ENTRY : void 0;
84480
+ function withLaunchOrigin(pending) {
84481
+ if (!pending) return null;
84482
+ return LOCAL_BUILD_ENTRY ? { ...pending, localBuildEntry: LOCAL_BUILD_ENTRY } : pending;
84483
+ }
84453
84484
  var projectSymbolSalts = /* @__PURE__ */ new Map();
84454
84485
  async function resolveProjectSymbolSalt(client, projectId) {
84455
84486
  const cached2 = projectSymbolSalts.get(projectId);
@@ -84710,7 +84741,7 @@ async function startMultiDaemon(opts = {}) {
84710
84741
  apiKey: opts.apiKey,
84711
84742
  reviewUrl: () => `${baseUrl}/ws/${id}/review`,
84712
84743
  sharedStore,
84713
- pendingUpdate: () => serverPending ?? updatePoller?.current() ?? null,
84744
+ pendingUpdate: () => withLaunchOrigin(serverPending ?? updatePoller?.current() ?? null),
84714
84745
  // Ops-gated (default OFF): the 🚨 notice reads as "errata broke my
84715
84746
  // machine" to a non-operator. Detection + ledger run regardless — only
84716
84747
  // this push surface (and the toast, gated in notifyOpsEvent) is scoped.
@@ -84797,6 +84828,8 @@ async function startMultiDaemon(opts = {}) {
84797
84828
  pid: process.pid,
84798
84829
  webUiUrl: `${baseUrl}/ws/${rec.id}`,
84799
84830
  processStartedAt: PROCESS_STARTED_AT,
84831
+ entry: SELF_ENTRY,
84832
+ version: DAEMON_VERSION,
84800
84833
  wokeAt: Date.now()
84801
84834
  }),
84802
84835
  "utf8"
@@ -84828,7 +84861,7 @@ async function startMultiDaemon(opts = {}) {
84828
84861
  "/",
84829
84862
  (c) => c.json({
84830
84863
  daemonVersion: DAEMON_VERSION,
84831
- pendingUpdate: updatePoller?.current() ?? null,
84864
+ pendingUpdate: withLaunchOrigin(updatePoller?.current() ?? null),
84832
84865
  projects: records.map((r) => ({
84833
84866
  id: r.id,
84834
84867
  name: r.entry.name,
@@ -85102,7 +85135,7 @@ async function startMultiDaemon(opts = {}) {
85102
85135
  ensureDir(globalDir());
85103
85136
  writeFileSync23(
85104
85137
  lockPath,
85105
- daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT }),
85138
+ daemonLockPayload({ pid: process.pid, webUiUrl: baseUrl, processStartedAt: PROCESS_STARTED_AT, entry: SELF_ENTRY, version: DAEMON_VERSION }),
85106
85139
  "utf8"
85107
85140
  );
85108
85141
  } catch {
@@ -85115,6 +85148,8 @@ async function startMultiDaemon(opts = {}) {
85115
85148
  pid: process.pid,
85116
85149
  webUiUrl: `${baseUrl}/ws/${r.id}`,
85117
85150
  processStartedAt: PROCESS_STARTED_AT,
85151
+ entry: SELF_ENTRY,
85152
+ version: DAEMON_VERSION,
85118
85153
  wokeAt: PROCESS_STARTED_AT
85119
85154
  }),
85120
85155
  "utf8"
@@ -87257,6 +87292,10 @@ async function cmdStatus() {
87257
87292
  console.log(
87258
87293
  ` daemon: ${running ? `running \xB7 pid ${running.pid} \xB7 ${running.webUiUrl ?? "(running)"}` : "not running (run: errata start)"}`
87259
87294
  );
87295
+ if (running && process.argv[1]) {
87296
+ const note = foreignDaemonNote(running, pathResolve2(process.argv[1]));
87297
+ if (note) for (const l of note) console.log(` \u26A0 ${l}`);
87298
+ }
87260
87299
  if (running?.webUiUrl) {
87261
87300
  try {
87262
87301
  const res = await fetch(`${running.webUiUrl}/health`, {
@@ -87406,7 +87445,7 @@ async function cmdWhoami(args2) {
87406
87445
  const cfg = loadConfig();
87407
87446
  const wIdx = args2.indexOf("--workspace");
87408
87447
  if (wIdx >= 0) {
87409
- const path2 = pathResolve(args2[wIdx + 1] ?? process.cwd());
87448
+ const path2 = pathResolve2(args2[wIdx + 1] ?? process.cwd());
87410
87449
  const entry = workspaceEntryForPath(path2);
87411
87450
  const identity = resolveWorkspaceIdentity(cfg, entry);
87412
87451
  const lines = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.6-dev.2505",
3
+ "version": "2.0.6-dev.2511",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {