@inerrata-corporation/errata 2.0.0-dev.47 → 2.0.0-dev.48
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 +139 -44
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -20946,6 +20946,20 @@ var init_client = __esm({
|
|
|
20946
20946
|
async createProject(name2) {
|
|
20947
20947
|
return this.json("POST", "/api/gate/projects/create", { name: name2 });
|
|
20948
20948
|
}
|
|
20949
|
+
/** Read-only discovery (PJ-attach clone tripwire): the org's claim on a
|
|
20950
|
+
* locator, or null. NEVER creates — 404 means the org hasn't linked it. */
|
|
20951
|
+
async lookupProject(locator) {
|
|
20952
|
+
try {
|
|
20953
|
+
const res = await this.json(
|
|
20954
|
+
"GET",
|
|
20955
|
+
`/api/gate/projects/lookup?locator=${encodeURIComponent(locator)}`
|
|
20956
|
+
);
|
|
20957
|
+
return res.project;
|
|
20958
|
+
} catch (err2) {
|
|
20959
|
+
if (err2 instanceof CloudError && err2.status === 404) return null;
|
|
20960
|
+
throw err2;
|
|
20961
|
+
}
|
|
20962
|
+
}
|
|
20949
20963
|
// ─── ingest ────────────────────────────────────────────────────────
|
|
20950
20964
|
/** Upload one outbox batch (projected onto the reconciled wire) and fold
|
|
20951
20965
|
* the per-decision response into flush accounting.
|
|
@@ -38269,8 +38283,8 @@ var init_report_render = __esm({
|
|
|
38269
38283
|
|
|
38270
38284
|
// src/cli.ts
|
|
38271
38285
|
init_src5();
|
|
38272
|
-
import { closeSync as closeSync2, existsSync as
|
|
38273
|
-
import { join as
|
|
38286
|
+
import { closeSync as closeSync2, existsSync as existsSync22, openSync as openSync2, readFileSync as readFileSync20, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
|
|
38287
|
+
import { join as join25 } from "node:path";
|
|
38274
38288
|
import { spawn as spawn3 } from "node:child_process";
|
|
38275
38289
|
|
|
38276
38290
|
// src/daemon.ts
|
|
@@ -39586,9 +39600,9 @@ var NodeFsHandler = class {
|
|
|
39586
39600
|
if (this.fsw.closed) {
|
|
39587
39601
|
return;
|
|
39588
39602
|
}
|
|
39589
|
-
const
|
|
39603
|
+
const dirname9 = sysPath.dirname(file2);
|
|
39590
39604
|
const basename5 = sysPath.basename(file2);
|
|
39591
|
-
const parent = this.fsw._getWatchedDir(
|
|
39605
|
+
const parent = this.fsw._getWatchedDir(dirname9);
|
|
39592
39606
|
let prevStats = stats;
|
|
39593
39607
|
if (parent.has(basename5))
|
|
39594
39608
|
return;
|
|
@@ -39615,7 +39629,7 @@ var NodeFsHandler = class {
|
|
|
39615
39629
|
prevStats = newStats2;
|
|
39616
39630
|
}
|
|
39617
39631
|
} catch (error48) {
|
|
39618
|
-
this.fsw._remove(
|
|
39632
|
+
this.fsw._remove(dirname9, basename5);
|
|
39619
39633
|
}
|
|
39620
39634
|
} else if (parent.has(basename5)) {
|
|
39621
39635
|
const at = newStats.atimeMs;
|
|
@@ -42679,7 +42693,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
42679
42693
|
}
|
|
42680
42694
|
|
|
42681
42695
|
// src/engine.ts
|
|
42682
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
42696
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.48" : "2.0.0-alpha.0";
|
|
42683
42697
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
42684
42698
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
42685
42699
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -44761,6 +44775,48 @@ async function ensureProjectLink(root, profile, client) {
|
|
|
44761
44775
|
}
|
|
44762
44776
|
}
|
|
44763
44777
|
|
|
44778
|
+
// src/adopt.ts
|
|
44779
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
44780
|
+
import { dirname as dirname8, join as join24 } from "node:path";
|
|
44781
|
+
function findGitRoot(absPath) {
|
|
44782
|
+
let dir = absPath;
|
|
44783
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
44784
|
+
if (existsSync21(join24(dir, ".git"))) return dir;
|
|
44785
|
+
const parent = dirname8(dir);
|
|
44786
|
+
if (parent === dir) return null;
|
|
44787
|
+
dir = parent;
|
|
44788
|
+
}
|
|
44789
|
+
return null;
|
|
44790
|
+
}
|
|
44791
|
+
var RETRY_COOLDOWN_MS = 15 * 6e4;
|
|
44792
|
+
function createRootAdopter(deps) {
|
|
44793
|
+
const attempted = /* @__PURE__ */ new Map();
|
|
44794
|
+
let chain = Promise.resolve();
|
|
44795
|
+
const tryAdopt = async (path2) => {
|
|
44796
|
+
if (!deps.linkingAllowed()) return;
|
|
44797
|
+
const root = findGitRoot(path2);
|
|
44798
|
+
if (!root || deps.isKnownRoot(root)) return;
|
|
44799
|
+
const last = attempted.get(root);
|
|
44800
|
+
const now = Date.now();
|
|
44801
|
+
if (last !== void 0 && now - last < RETRY_COOLDOWN_MS) return;
|
|
44802
|
+
attempted.set(root, now);
|
|
44803
|
+
if (!resolveGitDir(root)) return;
|
|
44804
|
+
const locator = detectRepoLocator(root);
|
|
44805
|
+
if (!locator) return;
|
|
44806
|
+
const claimed = await deps.lookup(locator);
|
|
44807
|
+
if (!claimed) return;
|
|
44808
|
+
await deps.adopt(root);
|
|
44809
|
+
deps.log(`[errata] adopted ${root} \u2014 ${locator} is claimed by your org (project ${claimed.id})`);
|
|
44810
|
+
};
|
|
44811
|
+
return {
|
|
44812
|
+
noteMiss(path2) {
|
|
44813
|
+
if (!path2) return;
|
|
44814
|
+
chain = chain.then(() => tryAdopt(path2)).catch(() => void 0);
|
|
44815
|
+
},
|
|
44816
|
+
idle: () => chain
|
|
44817
|
+
};
|
|
44818
|
+
}
|
|
44819
|
+
|
|
44764
44820
|
// src/multi.ts
|
|
44765
44821
|
function normPath(p) {
|
|
44766
44822
|
return p.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
@@ -45023,7 +45079,10 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45023
45079
|
return c.json({ error: "bad-json" }, 400);
|
|
45024
45080
|
}
|
|
45025
45081
|
const owner = ownerOf(records, pathInBody(body2));
|
|
45026
|
-
if (!owner)
|
|
45082
|
+
if (!owner) {
|
|
45083
|
+
rootAdopter.noteMiss(pathInBody(body2));
|
|
45084
|
+
return c.json({ error: "no-matching-project" }, 404);
|
|
45085
|
+
}
|
|
45027
45086
|
const sub = c.req.path;
|
|
45028
45087
|
const done = markPass(`${sub}:${owner.entry.name}`);
|
|
45029
45088
|
try {
|
|
@@ -45116,6 +45175,25 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45116
45175
|
if (opts.reindexOnStart !== false && records.length > 0) {
|
|
45117
45176
|
void reindexAll({ skipEmbed: opts.skipEmbed ?? true });
|
|
45118
45177
|
}
|
|
45178
|
+
const rootAdopter = createRootAdopter({
|
|
45179
|
+
isKnownRoot: (root) => pickOwnerRoot(records.map((r) => r.root), root) !== null,
|
|
45180
|
+
linkingAllowed: () => {
|
|
45181
|
+
const c = loadConfig();
|
|
45182
|
+
return c.consent.sync && hasCloudCredential(c);
|
|
45183
|
+
},
|
|
45184
|
+
lookup: async (locator) => cloudNow().lookupProject(locator),
|
|
45185
|
+
adopt: async (root) => {
|
|
45186
|
+
let profile = loadProfile(root);
|
|
45187
|
+
if (!profile) {
|
|
45188
|
+
profile = autodetectProfile(root);
|
|
45189
|
+
saveProfile(root, profile);
|
|
45190
|
+
}
|
|
45191
|
+
registerWorkspace(profile, root);
|
|
45192
|
+
attachWorkspace(root);
|
|
45193
|
+
},
|
|
45194
|
+
// eslint-disable-next-line no-console
|
|
45195
|
+
log: (line) => console.log(line)
|
|
45196
|
+
});
|
|
45119
45197
|
const ambientLinkAll = async () => {
|
|
45120
45198
|
const c = loadConfig();
|
|
45121
45199
|
if (!c.consent.sync || !hasCloudCredential(c)) return;
|
|
@@ -46009,21 +46087,21 @@ async function cmdInit() {
|
|
|
46009
46087
|
if (!skipHooks) {
|
|
46010
46088
|
console.log("");
|
|
46011
46089
|
console.log("installing harness hooks...");
|
|
46012
|
-
const { existsSync:
|
|
46013
|
-
const { join:
|
|
46090
|
+
const { existsSync: existsSync23 } = await import("node:fs");
|
|
46091
|
+
const { join: join26 } = await import("node:path");
|
|
46014
46092
|
try {
|
|
46015
46093
|
await installClaudeHooks(port);
|
|
46016
46094
|
} catch (err2) {
|
|
46017
46095
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46018
46096
|
}
|
|
46019
|
-
if (
|
|
46097
|
+
if (existsSync23(join26(ROOT, ".cursor"))) {
|
|
46020
46098
|
try {
|
|
46021
46099
|
await installCursorMcpConfig();
|
|
46022
46100
|
} catch (err2) {
|
|
46023
46101
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46024
46102
|
}
|
|
46025
46103
|
}
|
|
46026
|
-
if (
|
|
46104
|
+
if (existsSync23(join26(ROOT, ".codex"))) {
|
|
46027
46105
|
try {
|
|
46028
46106
|
await installCodexHooks(port);
|
|
46029
46107
|
} catch (err2) {
|
|
@@ -46097,6 +46175,23 @@ async function cmdNotifyTest() {
|
|
|
46097
46175
|
}
|
|
46098
46176
|
}
|
|
46099
46177
|
async function cmdStart() {
|
|
46178
|
+
if (!loadProfile(ROOT)) {
|
|
46179
|
+
const cfg = loadConfig();
|
|
46180
|
+
const locator = detectRepoLocator(ROOT);
|
|
46181
|
+
if (locator && cfg.consent.sync && hasCloudCredential(cfg)) {
|
|
46182
|
+
try {
|
|
46183
|
+
const claimed = await authedCloudClient(cfg).lookupProject(locator);
|
|
46184
|
+
if (claimed) {
|
|
46185
|
+
const adopted = autodetectProfile(ROOT);
|
|
46186
|
+
saveProfile(ROOT, adopted);
|
|
46187
|
+
console.log(
|
|
46188
|
+
`adopted: ${locator} is claimed by your org (project ${claimed.id}) \u2014 workspace initialized`
|
|
46189
|
+
);
|
|
46190
|
+
}
|
|
46191
|
+
} catch {
|
|
46192
|
+
}
|
|
46193
|
+
}
|
|
46194
|
+
}
|
|
46100
46195
|
await ensureProfile();
|
|
46101
46196
|
const profile = loadProfile(ROOT);
|
|
46102
46197
|
if (profile) registerWorkspace(profile, ROOT);
|
|
@@ -46160,8 +46255,8 @@ async function cmdStatus() {
|
|
|
46160
46255
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
46161
46256
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
46162
46257
|
}
|
|
46163
|
-
console.log(` graph db: ${
|
|
46164
|
-
console.log(` event log: ${
|
|
46258
|
+
console.log(` graph db: ${existsSync22(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
46259
|
+
console.log(` event log: ${existsSync22(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
46165
46260
|
const lockPath = globalDaemonLock();
|
|
46166
46261
|
const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
|
|
46167
46262
|
console.log(
|
|
@@ -46576,7 +46671,7 @@ async function cmdUse(args2) {
|
|
|
46576
46671
|
}
|
|
46577
46672
|
async function cmdReview() {
|
|
46578
46673
|
const paths = workspacePaths(ROOT);
|
|
46579
|
-
if (!
|
|
46674
|
+
if (!existsSync22(paths.reviewQueue)) {
|
|
46580
46675
|
console.log("(review queue empty)");
|
|
46581
46676
|
return;
|
|
46582
46677
|
}
|
|
@@ -47210,7 +47305,7 @@ async function gatherRepo(store, ws) {
|
|
|
47210
47305
|
};
|
|
47211
47306
|
}
|
|
47212
47307
|
async function gatherReportData(generatedAt) {
|
|
47213
|
-
const { existsSync:
|
|
47308
|
+
const { existsSync: existsSync23 } = await import("node:fs");
|
|
47214
47309
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
47215
47310
|
const cfg = loadConfig();
|
|
47216
47311
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -47218,7 +47313,7 @@ async function gatherReportData(generatedAt) {
|
|
|
47218
47313
|
for (const ws of listWorkspaces()) {
|
|
47219
47314
|
if (ws.missing) continue;
|
|
47220
47315
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
47221
|
-
if (!
|
|
47316
|
+
if (!existsSync23(dbPath)) continue;
|
|
47222
47317
|
let store = null;
|
|
47223
47318
|
try {
|
|
47224
47319
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -47262,8 +47357,8 @@ async function cmdReport(args2) {
|
|
|
47262
47357
|
const outDir = workspacePaths(ROOT).configDir;
|
|
47263
47358
|
mkdirSync6(outDir, { recursive: true });
|
|
47264
47359
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
47265
|
-
for (const f of files) writeFileSync16(
|
|
47266
|
-
const indexPath =
|
|
47360
|
+
for (const f of files) writeFileSync16(join25(outDir, f.name), f.html, "utf8");
|
|
47361
|
+
const indexPath = join25(outDir, "report.html");
|
|
47267
47362
|
console.log(`report \u2192 ${indexPath}`);
|
|
47268
47363
|
console.log(` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`);
|
|
47269
47364
|
console.log(` open: file://${indexPath.replace(/\\/g, "/")}`);
|
|
@@ -47383,13 +47478,13 @@ function hookRelayCommand(port, path2) {
|
|
|
47383
47478
|
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST -H \\"Content-Type: application/json\\" --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
|
|
47384
47479
|
}
|
|
47385
47480
|
async function installClaudeHooks(port) {
|
|
47386
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
47387
|
-
const { join:
|
|
47388
|
-
const dir =
|
|
47389
|
-
if (!
|
|
47390
|
-
const file2 =
|
|
47481
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync23, readFileSync: readFileSync21, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
47482
|
+
const { join: join26 } = await import("node:path");
|
|
47483
|
+
const dir = join26(ROOT, ".claude");
|
|
47484
|
+
if (!existsSync23(dir)) mkdirSync6(dir, { recursive: true });
|
|
47485
|
+
const file2 = join26(dir, "settings.json");
|
|
47391
47486
|
let settings = {};
|
|
47392
|
-
if (
|
|
47487
|
+
if (existsSync23(file2)) {
|
|
47393
47488
|
try {
|
|
47394
47489
|
settings = JSON.parse(readFileSync21(file2, "utf8"));
|
|
47395
47490
|
} catch {
|
|
@@ -47440,7 +47535,7 @@ async function installClaudeHooks(port) {
|
|
|
47440
47535
|
writeFileSync16(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
47441
47536
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
47442
47537
|
await installClaudeMcpConfig();
|
|
47443
|
-
const claudeMd =
|
|
47538
|
+
const claudeMd = join26(ROOT, "CLAUDE.md");
|
|
47444
47539
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
47445
47540
|
if (recall.kind === "collision") {
|
|
47446
47541
|
console.warn(
|
|
@@ -47452,13 +47547,13 @@ async function installClaudeHooks(port) {
|
|
|
47452
47547
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
47453
47548
|
}
|
|
47454
47549
|
async function installClaudeMcpConfig() {
|
|
47455
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
47456
|
-
const { join:
|
|
47457
|
-
const file2 =
|
|
47458
|
-
const dir =
|
|
47459
|
-
if (!
|
|
47550
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync23, readFileSync: readFileSync21, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
47551
|
+
const { join: join26, dirname: dirname9 } = await import("node:path");
|
|
47552
|
+
const file2 = join26(ROOT, ".mcp.json");
|
|
47553
|
+
const dir = dirname9(file2);
|
|
47554
|
+
if (!existsSync23(dir)) mkdirSync6(dir, { recursive: true });
|
|
47460
47555
|
let cfg = {};
|
|
47461
|
-
if (
|
|
47556
|
+
if (existsSync23(file2)) {
|
|
47462
47557
|
try {
|
|
47463
47558
|
cfg = JSON.parse(readFileSync21(file2, "utf8"));
|
|
47464
47559
|
} catch {
|
|
@@ -47474,13 +47569,13 @@ async function installClaudeMcpConfig() {
|
|
|
47474
47569
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
47475
47570
|
}
|
|
47476
47571
|
async function installCursorMcpConfig() {
|
|
47477
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
47478
|
-
const { join:
|
|
47479
|
-
const dir =
|
|
47480
|
-
if (!
|
|
47481
|
-
const file2 =
|
|
47572
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync23, readFileSync: readFileSync21, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
47573
|
+
const { join: join26 } = await import("node:path");
|
|
47574
|
+
const dir = join26(ROOT, ".cursor");
|
|
47575
|
+
if (!existsSync23(dir)) mkdirSync6(dir, { recursive: true });
|
|
47576
|
+
const file2 = join26(dir, "mcp.json");
|
|
47482
47577
|
let cfg = {};
|
|
47483
|
-
if (
|
|
47578
|
+
if (existsSync23(file2)) {
|
|
47484
47579
|
try {
|
|
47485
47580
|
cfg = JSON.parse(readFileSync21(file2, "utf8"));
|
|
47486
47581
|
} catch {
|
|
@@ -47498,15 +47593,15 @@ async function installCursorMcpConfig() {
|
|
|
47498
47593
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
47499
47594
|
}
|
|
47500
47595
|
async function installCodexHooks(port) {
|
|
47501
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
47502
|
-
const { join:
|
|
47503
|
-
const dir =
|
|
47504
|
-
if (!
|
|
47505
|
-
const file2 =
|
|
47596
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync23, readFileSync: readFileSync21, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
47597
|
+
const { join: join26 } = await import("node:path");
|
|
47598
|
+
const dir = join26(ROOT, ".codex");
|
|
47599
|
+
if (!existsSync23(dir)) mkdirSync6(dir, { recursive: true });
|
|
47600
|
+
const file2 = join26(dir, "config.toml");
|
|
47506
47601
|
const BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
47507
47602
|
const END = `# <<< errata hooks`;
|
|
47508
47603
|
let existing = "";
|
|
47509
|
-
if (
|
|
47604
|
+
if (existsSync23(file2)) {
|
|
47510
47605
|
existing = readFileSync21(file2, "utf8");
|
|
47511
47606
|
const beginIdx = existing.indexOf(BEGIN);
|
|
47512
47607
|
const endIdx = existing.indexOf(END);
|
|
@@ -47799,7 +47894,7 @@ async function cmdDash(args2) {
|
|
|
47799
47894
|
await yieldToLoop2();
|
|
47800
47895
|
try {
|
|
47801
47896
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
47802
|
-
const res = bleedRules(
|
|
47897
|
+
const res = bleedRules(join25(r.root, ".claude", "rules"), items);
|
|
47803
47898
|
if (res.written || res.pruned) {
|
|
47804
47899
|
console.log(
|
|
47805
47900
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|