@inerrata-corporation/errata 2.0.0-dev.71 → 2.0.0-dev.73
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 +297 -131
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -15388,7 +15388,11 @@ var init_symbol_intent = __esm({
|
|
|
15388
15388
|
function isCloudWritableNodeLabel(label) {
|
|
15389
15389
|
return CLOUD_WRITABLE_NODE_LABEL_SET.has(label);
|
|
15390
15390
|
}
|
|
15391
|
+
function isQuarantinedExtractionSource(source) {
|
|
15392
|
+
return typeof source === "string" && source.startsWith(QUARANTINE_EXTRACTION_SOURCE_PREFIX);
|
|
15393
|
+
}
|
|
15391
15394
|
function provenanceBand(source) {
|
|
15395
|
+
if (isQuarantinedExtractionSource(source)) return "seed";
|
|
15392
15396
|
switch (source) {
|
|
15393
15397
|
case "agent-observed":
|
|
15394
15398
|
case "user-edited":
|
|
@@ -15436,7 +15440,7 @@ function summarizeIngestResult(r) {
|
|
|
15436
15440
|
...r.patternReconciliation ? { patternReconciliation: r.patternReconciliation } : {}
|
|
15437
15441
|
};
|
|
15438
15442
|
}
|
|
15439
|
-
var CLOUD_NODE_LABELS, CLOUD_WRITABLE_NODE_LABELS, CLOUD_WRITABLE_NODE_LABEL_SET, CLOUD_EDGE_TYPES, INGEST_SOURCES, INGEST_EXTRACTION_SOURCES, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15443
|
+
var CLOUD_NODE_LABELS, CLOUD_WRITABLE_NODE_LABELS, CLOUD_WRITABLE_NODE_LABEL_SET, CLOUD_EDGE_TYPES, INGEST_SOURCES, INGEST_EXTRACTION_SOURCES, QUARANTINE_EXTRACTION_SOURCE_PREFIX, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15440
15444
|
var init_wire = __esm({
|
|
15441
15445
|
"../../packages/shared/src/wire.ts"() {
|
|
15442
15446
|
"use strict";
|
|
@@ -15481,6 +15485,7 @@ var init_wire = __esm({
|
|
|
15481
15485
|
"cold-start-seed",
|
|
15482
15486
|
"user-edited"
|
|
15483
15487
|
];
|
|
15488
|
+
QUARANTINE_EXTRACTION_SOURCE_PREFIX = "quarantined:";
|
|
15484
15489
|
MAX_NODES_PER_PAYLOAD = 200;
|
|
15485
15490
|
MAX_EDGES_PER_PAYLOAD = 500;
|
|
15486
15491
|
CastaliaIngestNodeSchema = external_exports.object({
|
|
@@ -15645,6 +15650,7 @@ __export(src_exports, {
|
|
|
15645
15650
|
MAX_SYMBOL_SUMMARY_CHARS: () => MAX_SYMBOL_SUMMARY_CHARS,
|
|
15646
15651
|
PAGERANK_EXCLUSIONS: () => PAGERANK_EXCLUSIONS,
|
|
15647
15652
|
PROBLEM_RESOLUTION: () => PROBLEM_RESOLUTION,
|
|
15653
|
+
QUARANTINE_EXTRACTION_SOURCE_PREFIX: () => QUARANTINE_EXTRACTION_SOURCE_PREFIX,
|
|
15648
15654
|
RESOLUTION_EDGES: () => RESOLUTION_EDGES,
|
|
15649
15655
|
RouteContextCountWireSchema: () => RouteContextCountWireSchema,
|
|
15650
15656
|
SEMANTIC_NODE_LABELS: () => SEMANTIC_NODE_LABELS,
|
|
@@ -15680,6 +15686,7 @@ __export(src_exports, {
|
|
|
15680
15686
|
isCodeLabel: () => isCodeLabel,
|
|
15681
15687
|
isContextLabel: () => isContextLabel,
|
|
15682
15688
|
isInferredSource: () => isInferredSource,
|
|
15689
|
+
isQuarantinedExtractionSource: () => isQuarantinedExtractionSource,
|
|
15683
15690
|
isSeedProvenance: () => isSeedProvenance,
|
|
15684
15691
|
isSemanticLabel: () => isSemanticLabel,
|
|
15685
15692
|
isTestRelPath: () => isTestRelPath,
|
|
@@ -20362,13 +20369,8 @@ function renderSnapshot(s) {
|
|
|
20362
20369
|
if (s.skills.length > 0) {
|
|
20363
20370
|
lines.push("### Skills available");
|
|
20364
20371
|
lines.push(
|
|
20365
|
-
`${s.skills.length} induced skill${s.skills.length === 1 ? "" : "s"} for this workspace.
|
|
20372
|
+
`${s.skills.length} induced skill${s.skills.length === 1 ? "" : "s"} for this workspace, installed as \`SKILL.md\` under \`.agents/skills/\` (and your harness's skills dir) \u2014 invoke natively. No auto-discovery (e.g. Aider)? \`/read-only\` the relevant \`.agents/skills/errata-*/SKILL.md\`.`
|
|
20366
20373
|
);
|
|
20367
|
-
for (const sk of [...s.skills].sort((a, b) => b.confidence - a.confidence).slice(0, 10)) {
|
|
20368
|
-
lines.push(
|
|
20369
|
-
`- **${sk.title}** (${sk.layer}, ${(sk.confidence * 100).toFixed(0)}%) \u2192 \`.errata/${sk.file}\``
|
|
20370
|
-
);
|
|
20371
|
-
}
|
|
20372
20374
|
lines.push("");
|
|
20373
20375
|
}
|
|
20374
20376
|
lines.push("### Prior knowledge sampled from the shared graph");
|
|
@@ -38554,12 +38556,12 @@ var init_report_render = __esm({
|
|
|
38554
38556
|
|
|
38555
38557
|
// src/cli.ts
|
|
38556
38558
|
init_src5();
|
|
38557
|
-
import { closeSync as closeSync2, existsSync as
|
|
38558
|
-
import { join as
|
|
38559
|
+
import { closeSync as closeSync2, existsSync as existsSync23, openSync as openSync2, readFileSync as readFileSync21, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
|
|
38560
|
+
import { join as join26 } from "node:path";
|
|
38559
38561
|
import { spawn as spawn3 } from "node:child_process";
|
|
38560
38562
|
|
|
38561
38563
|
// src/daemon.ts
|
|
38562
|
-
import { existsSync as
|
|
38564
|
+
import { existsSync as existsSync18, writeFileSync as writeFileSync14 } from "node:fs";
|
|
38563
38565
|
|
|
38564
38566
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
|
|
38565
38567
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -39139,8 +39141,8 @@ init_config();
|
|
|
39139
39141
|
|
|
39140
39142
|
// src/engine.ts
|
|
39141
39143
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
39142
|
-
import { existsSync as
|
|
39143
|
-
import { join as
|
|
39144
|
+
import { existsSync as existsSync17, statSync as statSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync8, renameSync as renameSync2, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
|
|
39145
|
+
import { join as join22, relative as relative6, sep as sep4 } from "node:path";
|
|
39144
39146
|
|
|
39145
39147
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
39146
39148
|
import { stat as statcb } from "fs";
|
|
@@ -42627,6 +42629,164 @@ async function syncSkills(paths, client, seed, pins = []) {
|
|
|
42627
42629
|
return { written: rows.length, pruned, ...staleDaemon ? { staleDaemon } : {} };
|
|
42628
42630
|
}
|
|
42629
42631
|
|
|
42632
|
+
// src/agent-skills.ts
|
|
42633
|
+
import {
|
|
42634
|
+
cpSync,
|
|
42635
|
+
existsSync as existsSync14,
|
|
42636
|
+
lstatSync,
|
|
42637
|
+
mkdirSync as mkdirSync6,
|
|
42638
|
+
readFileSync as readFileSync13,
|
|
42639
|
+
readdirSync as readdirSync7,
|
|
42640
|
+
rmSync as rmSync2,
|
|
42641
|
+
symlinkSync,
|
|
42642
|
+
writeFileSync as writeFileSync11
|
|
42643
|
+
} from "node:fs";
|
|
42644
|
+
import { join as join19 } from "node:path";
|
|
42645
|
+
var SKILL_NS = "errata-";
|
|
42646
|
+
var HARNESS_SKILL_DIRS = [
|
|
42647
|
+
{ configDir: ".claude", skillsDir: join19(".claude", "skills") },
|
|
42648
|
+
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
42649
|
+
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
42650
|
+
{ configDir: ".cursor", skillsDir: join19(".cursor", "skills") }
|
|
42651
|
+
];
|
|
42652
|
+
function skillSlug(title, id) {
|
|
42653
|
+
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
42654
|
+
return `${SKILL_NS}${base}`.slice(0, 64).replace(/-+$/, "");
|
|
42655
|
+
}
|
|
42656
|
+
function yamlScalar(s) {
|
|
42657
|
+
return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\s+/g, " ").trim()}"`;
|
|
42658
|
+
}
|
|
42659
|
+
function deriveDescription(title, layer, body2) {
|
|
42660
|
+
const firstProse = body2.split(/\r?\n/).map((l) => l.trim()).find((l) => l.length > 0 && !l.startsWith("#") && !l.startsWith("---"));
|
|
42661
|
+
const lead = firstProse && firstProse.length >= 24 ? firstProse : title;
|
|
42662
|
+
const when = ` Apply when working on ${layer === "antipattern" ? "code that risks this pitfall" : "problems in this area"}.`;
|
|
42663
|
+
return `${lead}${lead.endsWith(".") ? "" : "."}${when}`.slice(0, 1024);
|
|
42664
|
+
}
|
|
42665
|
+
function renderSkillMd(name2, description, body2) {
|
|
42666
|
+
return `---
|
|
42667
|
+
name: ${name2}
|
|
42668
|
+
description: ${yamlScalar(description)}
|
|
42669
|
+
---
|
|
42670
|
+
|
|
42671
|
+
${body2.trimEnd()}
|
|
42672
|
+
`;
|
|
42673
|
+
}
|
|
42674
|
+
function reconcileNamespaced(dir, keep) {
|
|
42675
|
+
if (!existsSync14(dir)) return 0;
|
|
42676
|
+
let pruned = 0;
|
|
42677
|
+
for (const name2 of readdirSync7(dir)) {
|
|
42678
|
+
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
42679
|
+
try {
|
|
42680
|
+
rmSync2(join19(dir, name2), { recursive: true, force: true });
|
|
42681
|
+
pruned++;
|
|
42682
|
+
} catch {
|
|
42683
|
+
}
|
|
42684
|
+
}
|
|
42685
|
+
return pruned;
|
|
42686
|
+
}
|
|
42687
|
+
function linkOrCopy(linkPath, target) {
|
|
42688
|
+
try {
|
|
42689
|
+
if (existsSync14(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
|
|
42690
|
+
} catch {
|
|
42691
|
+
}
|
|
42692
|
+
try {
|
|
42693
|
+
symlinkSync(target, linkPath, "junction");
|
|
42694
|
+
} catch {
|
|
42695
|
+
try {
|
|
42696
|
+
cpSync(target, linkPath, { recursive: true });
|
|
42697
|
+
} catch {
|
|
42698
|
+
}
|
|
42699
|
+
}
|
|
42700
|
+
}
|
|
42701
|
+
function safeLstat(p) {
|
|
42702
|
+
try {
|
|
42703
|
+
lstatSync(p);
|
|
42704
|
+
return true;
|
|
42705
|
+
} catch {
|
|
42706
|
+
return false;
|
|
42707
|
+
}
|
|
42708
|
+
}
|
|
42709
|
+
function emitAndProjectSkills(root, skills) {
|
|
42710
|
+
const agentsSkillsDir = join19(root, ".agents", "skills");
|
|
42711
|
+
mkdirSync6(agentsSkillsDir, { recursive: true });
|
|
42712
|
+
const slugs = [];
|
|
42713
|
+
const keep = /* @__PURE__ */ new Set();
|
|
42714
|
+
let emitted = 0;
|
|
42715
|
+
for (const s of skills) {
|
|
42716
|
+
let body2;
|
|
42717
|
+
try {
|
|
42718
|
+
body2 = readFileSync13(s.bodyPath, "utf8");
|
|
42719
|
+
} catch {
|
|
42720
|
+
continue;
|
|
42721
|
+
}
|
|
42722
|
+
const slug2 = skillSlug(s.title, s.id);
|
|
42723
|
+
if (keep.has(slug2)) continue;
|
|
42724
|
+
keep.add(slug2);
|
|
42725
|
+
slugs.push(slug2);
|
|
42726
|
+
const description = deriveDescription(s.title, s.layer, body2);
|
|
42727
|
+
mkdirSync6(join19(agentsSkillsDir, slug2), { recursive: true });
|
|
42728
|
+
writeFileSync11(
|
|
42729
|
+
join19(agentsSkillsDir, slug2, "SKILL.md"),
|
|
42730
|
+
renderSkillMd(slug2, description, body2),
|
|
42731
|
+
"utf8"
|
|
42732
|
+
);
|
|
42733
|
+
emitted++;
|
|
42734
|
+
}
|
|
42735
|
+
reconcileNamespaced(agentsSkillsDir, keep);
|
|
42736
|
+
let projected = 0;
|
|
42737
|
+
for (const h of HARNESS_SKILL_DIRS) {
|
|
42738
|
+
if (!existsSync14(join19(root, h.configDir))) continue;
|
|
42739
|
+
const dir = join19(root, h.skillsDir);
|
|
42740
|
+
mkdirSync6(dir, { recursive: true });
|
|
42741
|
+
for (const slug2 of slugs) {
|
|
42742
|
+
linkOrCopy(join19(dir, slug2), join19(agentsSkillsDir, slug2));
|
|
42743
|
+
projected++;
|
|
42744
|
+
}
|
|
42745
|
+
reconcileNamespaced(dir, keep);
|
|
42746
|
+
}
|
|
42747
|
+
ensureSkillGitignore(root);
|
|
42748
|
+
return { slugs, emitted, projected };
|
|
42749
|
+
}
|
|
42750
|
+
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
42751
|
+
if (!existsSync14(manifestPath)) return [];
|
|
42752
|
+
try {
|
|
42753
|
+
const parsed = JSON.parse(readFileSync13(manifestPath, "utf8"));
|
|
42754
|
+
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
42755
|
+
id: s.id,
|
|
42756
|
+
title: s.title ?? s.id,
|
|
42757
|
+
layer: s.layer ?? "technique",
|
|
42758
|
+
confidence: s.confidence ?? 0,
|
|
42759
|
+
bodyPath: join19(erretaDir, s.file)
|
|
42760
|
+
}));
|
|
42761
|
+
} catch {
|
|
42762
|
+
return [];
|
|
42763
|
+
}
|
|
42764
|
+
}
|
|
42765
|
+
var GITIGNORE_MARK = "# errata-managed agent skills (daemon-synced; namespaced)";
|
|
42766
|
+
var GITIGNORE_LINES = [
|
|
42767
|
+
GITIGNORE_MARK,
|
|
42768
|
+
".agents/skills/errata-*/",
|
|
42769
|
+
".claude/skills/errata-*/",
|
|
42770
|
+
".cursor/skills/errata-*/"
|
|
42771
|
+
];
|
|
42772
|
+
function ensureSkillGitignore(root) {
|
|
42773
|
+
const path2 = join19(root, ".gitignore");
|
|
42774
|
+
let current = "";
|
|
42775
|
+
try {
|
|
42776
|
+
current = existsSync14(path2) ? readFileSync13(path2, "utf8") : "";
|
|
42777
|
+
} catch {
|
|
42778
|
+
return;
|
|
42779
|
+
}
|
|
42780
|
+
if (current.includes(GITIGNORE_MARK)) return;
|
|
42781
|
+
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
42782
|
+
try {
|
|
42783
|
+
writeFileSync11(path2, `${current}${prefix}
|
|
42784
|
+
${GITIGNORE_LINES.join("\n")}
|
|
42785
|
+
`, "utf8");
|
|
42786
|
+
} catch {
|
|
42787
|
+
}
|
|
42788
|
+
}
|
|
42789
|
+
|
|
42630
42790
|
// src/working-file-state.ts
|
|
42631
42791
|
function createWorkingFileState() {
|
|
42632
42792
|
const bySession = /* @__PURE__ */ new Map();
|
|
@@ -42756,20 +42916,20 @@ var CausalBuffer = class {
|
|
|
42756
42916
|
// src/profile.ts
|
|
42757
42917
|
init_src2();
|
|
42758
42918
|
init_paths();
|
|
42759
|
-
import { existsSync as
|
|
42919
|
+
import { existsSync as existsSync16, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "node:fs";
|
|
42760
42920
|
import { createHash as createHash12 } from "node:crypto";
|
|
42761
|
-
import { join as
|
|
42921
|
+
import { join as join21 } from "node:path";
|
|
42762
42922
|
|
|
42763
42923
|
// src/git-remote.ts
|
|
42764
42924
|
init_src();
|
|
42765
|
-
import { existsSync as
|
|
42766
|
-
import { isAbsolute as isAbsolute3, join as
|
|
42925
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
42926
|
+
import { isAbsolute as isAbsolute3, join as join20, resolve as resolve5 } from "node:path";
|
|
42767
42927
|
function resolveGitDir(root) {
|
|
42768
|
-
const dotGit =
|
|
42928
|
+
const dotGit = join20(root, ".git");
|
|
42769
42929
|
try {
|
|
42770
42930
|
const st = statSync4(dotGit);
|
|
42771
42931
|
if (st.isDirectory()) return dotGit;
|
|
42772
|
-
const m = /^gitdir:\s*(.+?)\s*$/m.exec(
|
|
42932
|
+
const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync14(dotGit, "utf8"));
|
|
42773
42933
|
if (!m) return null;
|
|
42774
42934
|
const dir = m[1];
|
|
42775
42935
|
return isAbsolute3(dir) ? dir : resolve5(root, dir);
|
|
@@ -42778,22 +42938,22 @@ function resolveGitDir(root) {
|
|
|
42778
42938
|
}
|
|
42779
42939
|
}
|
|
42780
42940
|
function gitConfigPath(gitDir) {
|
|
42781
|
-
const commondirFile =
|
|
42782
|
-
if (
|
|
42783
|
-
const common =
|
|
42941
|
+
const commondirFile = join20(gitDir, "commondir");
|
|
42942
|
+
if (existsSync15(commondirFile)) {
|
|
42943
|
+
const common = readFileSync14(commondirFile, "utf8").trim();
|
|
42784
42944
|
const commonDir = isAbsolute3(common) ? common : resolve5(gitDir, common);
|
|
42785
|
-
return
|
|
42945
|
+
return join20(commonDir, "config");
|
|
42786
42946
|
}
|
|
42787
|
-
return
|
|
42947
|
+
return join20(gitDir, "config");
|
|
42788
42948
|
}
|
|
42789
42949
|
function readRemotes(root) {
|
|
42790
42950
|
const gitDir = resolveGitDir(root);
|
|
42791
42951
|
if (!gitDir) return [];
|
|
42792
42952
|
const cfgPath = gitConfigPath(gitDir);
|
|
42793
|
-
if (!
|
|
42953
|
+
if (!existsSync15(cfgPath)) return [];
|
|
42794
42954
|
let txt;
|
|
42795
42955
|
try {
|
|
42796
|
-
txt =
|
|
42956
|
+
txt = readFileSync14(cfgPath, "utf8");
|
|
42797
42957
|
} catch {
|
|
42798
42958
|
return [];
|
|
42799
42959
|
}
|
|
@@ -42825,13 +42985,13 @@ function refreshRepoLocator(root, profile) {
|
|
|
42825
42985
|
}
|
|
42826
42986
|
function loadProfile(root) {
|
|
42827
42987
|
const p = workspacePaths(root);
|
|
42828
|
-
if (!
|
|
42829
|
-
return JSON.parse(
|
|
42988
|
+
if (!existsSync16(p.workspaceJson)) return null;
|
|
42989
|
+
return JSON.parse(readFileSync15(p.workspaceJson, "utf8"));
|
|
42830
42990
|
}
|
|
42831
42991
|
function saveProfile(root, profile) {
|
|
42832
42992
|
const p = workspacePaths(root);
|
|
42833
42993
|
ensureDir(p.configDir);
|
|
42834
|
-
|
|
42994
|
+
writeFileSync12(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
|
|
42835
42995
|
}
|
|
42836
42996
|
function autodetectProfile(root) {
|
|
42837
42997
|
const id = workspaceId(root);
|
|
@@ -42839,10 +42999,10 @@ function autodetectProfile(root) {
|
|
|
42839
42999
|
const p = emptyProfile(id, name2);
|
|
42840
43000
|
const locator = detectRepoLocator(root);
|
|
42841
43001
|
if (locator) p.repoLocator = locator;
|
|
42842
|
-
const pkgPath =
|
|
42843
|
-
if (
|
|
43002
|
+
const pkgPath = join21(root, "package.json");
|
|
43003
|
+
if (existsSync16(pkgPath)) {
|
|
42844
43004
|
try {
|
|
42845
|
-
const pkg = JSON.parse(
|
|
43005
|
+
const pkg = JSON.parse(readFileSync15(pkgPath, "utf8"));
|
|
42846
43006
|
p.languages.push("typescript", "javascript");
|
|
42847
43007
|
const nodeVer = pkg.engines?.node ?? "node";
|
|
42848
43008
|
p.stack.push(`node@${nodeVer}`);
|
|
@@ -42863,10 +43023,10 @@ function autodetectProfile(root) {
|
|
|
42863
43023
|
} catch {
|
|
42864
43024
|
}
|
|
42865
43025
|
}
|
|
42866
|
-
const pyproject =
|
|
42867
|
-
if (
|
|
43026
|
+
const pyproject = join21(root, "pyproject.toml");
|
|
43027
|
+
if (existsSync16(pyproject)) {
|
|
42868
43028
|
try {
|
|
42869
|
-
const txt =
|
|
43029
|
+
const txt = readFileSync15(pyproject, "utf8");
|
|
42870
43030
|
const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
|
|
42871
43031
|
p.languages.push("python");
|
|
42872
43032
|
p.stack.push(`python@${py ?? "3"}`);
|
|
@@ -42877,16 +43037,16 @@ function autodetectProfile(root) {
|
|
|
42877
43037
|
} catch {
|
|
42878
43038
|
}
|
|
42879
43039
|
}
|
|
42880
|
-
const reqs =
|
|
42881
|
-
if (
|
|
43040
|
+
const reqs = join21(root, "requirements.txt");
|
|
43041
|
+
if (existsSync16(reqs)) {
|
|
42882
43042
|
if (!p.languages.includes("python")) p.languages.push("python");
|
|
42883
43043
|
if (!p.stack.includes("python@3")) p.stack.push("python@3");
|
|
42884
43044
|
}
|
|
42885
|
-
if (
|
|
43045
|
+
if (existsSync16(join21(root, "go.mod"))) {
|
|
42886
43046
|
p.languages.push("go");
|
|
42887
43047
|
p.stack.push("go");
|
|
42888
43048
|
}
|
|
42889
|
-
if (
|
|
43049
|
+
if (existsSync16(join21(root, "Cargo.toml"))) {
|
|
42890
43050
|
p.languages.push("rust");
|
|
42891
43051
|
p.stack.push("rust");
|
|
42892
43052
|
}
|
|
@@ -43044,7 +43204,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
43044
43204
|
}
|
|
43045
43205
|
|
|
43046
43206
|
// src/engine.ts
|
|
43047
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
43207
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.73" : "2.0.0-alpha.0";
|
|
43048
43208
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
43049
43209
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
43050
43210
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -43054,7 +43214,7 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
|
|
|
43054
43214
|
function appendIdentityAudit(path2, record2, line) {
|
|
43055
43215
|
if (!record2.accepted && record2.score <= 0) return;
|
|
43056
43216
|
try {
|
|
43057
|
-
if (
|
|
43217
|
+
if (existsSync17(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
43058
43218
|
renameSync2(path2, `${path2}.1`);
|
|
43059
43219
|
}
|
|
43060
43220
|
appendFileSync2(path2, line);
|
|
@@ -43064,14 +43224,14 @@ function appendIdentityAudit(path2, record2, line) {
|
|
|
43064
43224
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
43065
43225
|
function loadTurnCursors(path2) {
|
|
43066
43226
|
try {
|
|
43067
|
-
return new Map(Object.entries(JSON.parse(
|
|
43227
|
+
return new Map(Object.entries(JSON.parse(readFileSync16(path2, "utf8"))));
|
|
43068
43228
|
} catch {
|
|
43069
43229
|
return /* @__PURE__ */ new Map();
|
|
43070
43230
|
}
|
|
43071
43231
|
}
|
|
43072
43232
|
function saveTurnCursors(path2, cursors) {
|
|
43073
43233
|
try {
|
|
43074
|
-
|
|
43234
|
+
writeFileSync13(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
|
|
43075
43235
|
} catch {
|
|
43076
43236
|
}
|
|
43077
43237
|
}
|
|
@@ -43093,7 +43253,7 @@ function gitSourceWatchTargets(root) {
|
|
|
43093
43253
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
43094
43254
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
43095
43255
|
);
|
|
43096
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
43256
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join22(root, d) + sep4));
|
|
43097
43257
|
} catch {
|
|
43098
43258
|
}
|
|
43099
43259
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -43105,19 +43265,19 @@ function gitSourceWatchTargets(root) {
|
|
|
43105
43265
|
if (!f.startsWith(prefix)) continue;
|
|
43106
43266
|
const rest2 = f.slice(prefix.length);
|
|
43107
43267
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
43108
|
-
else targets.add(
|
|
43268
|
+
else targets.add(join22(root, f));
|
|
43109
43269
|
}
|
|
43110
43270
|
for (const c of children) {
|
|
43111
|
-
if (IGNORED_PATH.test(
|
|
43271
|
+
if (IGNORED_PATH.test(join22(root, c) + sep4)) continue;
|
|
43112
43272
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
43113
|
-
else targets.add(
|
|
43273
|
+
else targets.add(join22(root, c));
|
|
43114
43274
|
}
|
|
43115
43275
|
};
|
|
43116
43276
|
addUnder("");
|
|
43117
43277
|
if (targets.size > 0) return [...targets];
|
|
43118
43278
|
} catch {
|
|
43119
43279
|
}
|
|
43120
|
-
return
|
|
43280
|
+
return readdirSync8(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join22(root, String(e.name)) + sep4)).map((e) => join22(root, String(e.name)));
|
|
43121
43281
|
}
|
|
43122
43282
|
function createWorkspaceEngine(opts) {
|
|
43123
43283
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -43271,7 +43431,7 @@ function createWorkspaceEngine(opts) {
|
|
|
43271
43431
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
43272
43432
|
let episodeId2;
|
|
43273
43433
|
if (srcPaths.length > 0) {
|
|
43274
|
-
const abs = srcPaths.map((p) =>
|
|
43434
|
+
const abs = srcPaths.map((p) => join22(opts.workspaceRoot, p));
|
|
43275
43435
|
try {
|
|
43276
43436
|
const r = await runReindexPass(
|
|
43277
43437
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -43307,8 +43467,8 @@ function createWorkspaceEngine(opts) {
|
|
|
43307
43467
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
43308
43468
|
);
|
|
43309
43469
|
};
|
|
43310
|
-
const gitDir =
|
|
43311
|
-
if (
|
|
43470
|
+
const gitDir = join22(opts.workspaceRoot, ".git");
|
|
43471
|
+
if (existsSync17(gitDir)) {
|
|
43312
43472
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
43313
43473
|
void handleGitEvent(ev).catch((err2) => {
|
|
43314
43474
|
console.warn("[errata] git event handler failed:", err2);
|
|
@@ -43376,10 +43536,10 @@ function createWorkspaceEngine(opts) {
|
|
|
43376
43536
|
...pendingUpdate ? { pendingUpdate } : {}
|
|
43377
43537
|
});
|
|
43378
43538
|
doneRender?.();
|
|
43379
|
-
const target =
|
|
43539
|
+
const target = join22(opts.workspaceRoot, "AGENTS.md");
|
|
43380
43540
|
writeManagedBlock(target, { body: body2 });
|
|
43381
43541
|
if (elicit) {
|
|
43382
|
-
writePrimingHandles(
|
|
43542
|
+
writePrimingHandles(join22(paths.configDir, "priming-handles.json"), [
|
|
43383
43543
|
...snapshot.recentProblems.map((r) => r.node),
|
|
43384
43544
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
43385
43545
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -43549,7 +43709,7 @@ function createWorkspaceEngine(opts) {
|
|
|
43549
43709
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
43550
43710
|
});
|
|
43551
43711
|
};
|
|
43552
|
-
const turnCursorPath =
|
|
43712
|
+
const turnCursorPath = join22(paths.configDir, "turn-cursors.json");
|
|
43553
43713
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
43554
43714
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
43555
43715
|
const sessionThreads = /* @__PURE__ */ new Map();
|
|
@@ -43572,7 +43732,7 @@ function createWorkspaceEngine(opts) {
|
|
|
43572
43732
|
const t = Date.now();
|
|
43573
43733
|
let processedTurns = 0;
|
|
43574
43734
|
const elicit = isEdgeElicitationEnabled();
|
|
43575
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
43735
|
+
const handleMap = elicit ? readPrimingHandles(join22(paths.configDir, "priming-handles.json")) : {};
|
|
43576
43736
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
43577
43737
|
const toRel = (abs) => {
|
|
43578
43738
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -44049,7 +44209,13 @@ function createWorkspaceEngine(opts) {
|
|
|
44049
44209
|
return typeof cloudId === "string" && cloudId !== p.id ? [p.id, cloudId] : [p.id];
|
|
44050
44210
|
});
|
|
44051
44211
|
const pins = profile?.projectId ? await cloud.getSkillPins(profile.projectId).then((r) => r.pins).catch(() => []) : [];
|
|
44052
|
-
|
|
44212
|
+
const result = await syncSkills(paths, cloud, skillSeed, pins);
|
|
44213
|
+
try {
|
|
44214
|
+
emitAndProjectSkills(opts.workspaceRoot, emitInputsFromManifest(paths.configDir, paths.skillsManifest));
|
|
44215
|
+
} catch (err2) {
|
|
44216
|
+
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
44217
|
+
}
|
|
44218
|
+
return result;
|
|
44053
44219
|
};
|
|
44054
44220
|
return {
|
|
44055
44221
|
profile,
|
|
@@ -44231,7 +44397,7 @@ function createWorkspaceEngine(opts) {
|
|
|
44231
44397
|
console.log(
|
|
44232
44398
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
44233
44399
|
);
|
|
44234
|
-
const pending =
|
|
44400
|
+
const pending = existsSync17(paths.outbox) ? readdirSync8(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
44235
44401
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
44236
44402
|
}
|
|
44237
44403
|
try {
|
|
@@ -44318,7 +44484,7 @@ async function startDaemon(opts) {
|
|
|
44318
44484
|
reviewUrl: () => webUiUrl + "/review"
|
|
44319
44485
|
});
|
|
44320
44486
|
const writeLockFile = (url2) => {
|
|
44321
|
-
|
|
44487
|
+
writeFileSync14(
|
|
44322
44488
|
engine.paths.daemonLock,
|
|
44323
44489
|
JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
|
|
44324
44490
|
"utf8"
|
|
@@ -44361,7 +44527,7 @@ async function startDaemon(opts) {
|
|
|
44361
44527
|
);
|
|
44362
44528
|
await engine.stop();
|
|
44363
44529
|
try {
|
|
44364
|
-
if (
|
|
44530
|
+
if (existsSync18(engine.paths.daemonLock)) {
|
|
44365
44531
|
}
|
|
44366
44532
|
} catch {
|
|
44367
44533
|
}
|
|
@@ -44378,16 +44544,16 @@ async function listenServer(fetchFn, port) {
|
|
|
44378
44544
|
|
|
44379
44545
|
// src/registry.ts
|
|
44380
44546
|
init_paths();
|
|
44381
|
-
import { existsSync as
|
|
44382
|
-
import { join as
|
|
44547
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
|
|
44548
|
+
import { join as join23 } from "node:path";
|
|
44383
44549
|
function registryPath() {
|
|
44384
|
-
return process.env["ERRATA_REGISTRY_PATH"] ??
|
|
44550
|
+
return process.env["ERRATA_REGISTRY_PATH"] ?? join23(globalDir(), "workspaces.json");
|
|
44385
44551
|
}
|
|
44386
44552
|
function read() {
|
|
44387
44553
|
const p = registryPath();
|
|
44388
|
-
if (!
|
|
44554
|
+
if (!existsSync19(p)) return { version: 1, workspaces: {} };
|
|
44389
44555
|
try {
|
|
44390
|
-
const parsed = JSON.parse(
|
|
44556
|
+
const parsed = JSON.parse(readFileSync17(p, "utf8"));
|
|
44391
44557
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
44392
44558
|
} catch {
|
|
44393
44559
|
return { version: 1, workspaces: {} };
|
|
@@ -44395,7 +44561,7 @@ function read() {
|
|
|
44395
44561
|
}
|
|
44396
44562
|
function write(reg) {
|
|
44397
44563
|
ensureDir(globalDir());
|
|
44398
|
-
|
|
44564
|
+
writeFileSync15(registryPath(), JSON.stringify(reg, null, 2), "utf8");
|
|
44399
44565
|
}
|
|
44400
44566
|
function registerWorkspace(profile, root, now = Date.now()) {
|
|
44401
44567
|
const reg = read();
|
|
@@ -44412,7 +44578,7 @@ function pruneMissingWorkspaces() {
|
|
|
44412
44578
|
const reg = read();
|
|
44413
44579
|
const removed = [];
|
|
44414
44580
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
44415
|
-
if (!
|
|
44581
|
+
if (!existsSync19(entry.path)) {
|
|
44416
44582
|
removed.push(entry);
|
|
44417
44583
|
delete reg.workspaces[id];
|
|
44418
44584
|
}
|
|
@@ -44421,13 +44587,13 @@ function pruneMissingWorkspaces() {
|
|
|
44421
44587
|
return removed;
|
|
44422
44588
|
}
|
|
44423
44589
|
function workspaceStatus(entry) {
|
|
44424
|
-
const missing = !
|
|
44590
|
+
const missing = !existsSync19(entry.path);
|
|
44425
44591
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
44426
44592
|
let running = false;
|
|
44427
44593
|
let webUiUrl = null;
|
|
44428
|
-
if (
|
|
44594
|
+
if (existsSync19(lockPath)) {
|
|
44429
44595
|
try {
|
|
44430
|
-
const lock = JSON.parse(
|
|
44596
|
+
const lock = JSON.parse(readFileSync17(lockPath, "utf8"));
|
|
44431
44597
|
if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
|
|
44432
44598
|
running = true;
|
|
44433
44599
|
webUiUrl = lock.webUiUrl;
|
|
@@ -44455,7 +44621,7 @@ function pidAlive(pid) {
|
|
|
44455
44621
|
// src/multi.ts
|
|
44456
44622
|
init_dist();
|
|
44457
44623
|
init_src4();
|
|
44458
|
-
import { readFileSync as
|
|
44624
|
+
import { readFileSync as readFileSync20, unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "node:fs";
|
|
44459
44625
|
|
|
44460
44626
|
// src/principle-sync.ts
|
|
44461
44627
|
init_src4();
|
|
@@ -44482,8 +44648,8 @@ async function syncPrinciples(store, cloud, opts) {
|
|
|
44482
44648
|
init_reconcile();
|
|
44483
44649
|
|
|
44484
44650
|
// src/lockfile-auto.ts
|
|
44485
|
-
import { existsSync as
|
|
44486
|
-
import { join as
|
|
44651
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "node:fs";
|
|
44652
|
+
import { join as join24 } from "node:path";
|
|
44487
44653
|
|
|
44488
44654
|
// src/package-index.ts
|
|
44489
44655
|
init_src();
|
|
@@ -44747,11 +44913,11 @@ function runLockfilePass(opts) {
|
|
|
44747
44913
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
44748
44914
|
];
|
|
44749
44915
|
for (const c of candidates) {
|
|
44750
|
-
const p =
|
|
44751
|
-
if (!
|
|
44916
|
+
const p = join24(opts.root, c.file);
|
|
44917
|
+
if (!existsSync20(p)) continue;
|
|
44752
44918
|
let sbom;
|
|
44753
44919
|
try {
|
|
44754
|
-
sbom = c.parse(
|
|
44920
|
+
sbom = c.parse(readFileSync18(p, "utf8"));
|
|
44755
44921
|
} catch {
|
|
44756
44922
|
continue;
|
|
44757
44923
|
}
|
|
@@ -45027,7 +45193,7 @@ var ConsolidateWorker = class {
|
|
|
45027
45193
|
init_paths();
|
|
45028
45194
|
|
|
45029
45195
|
// src/lock.ts
|
|
45030
|
-
import { existsSync as
|
|
45196
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19 } from "node:fs";
|
|
45031
45197
|
function isProcessAlive(pid) {
|
|
45032
45198
|
if (!pid || pid <= 0) return false;
|
|
45033
45199
|
try {
|
|
@@ -45038,9 +45204,9 @@ function isProcessAlive(pid) {
|
|
|
45038
45204
|
}
|
|
45039
45205
|
}
|
|
45040
45206
|
function readDaemonLock(lockPath) {
|
|
45041
|
-
if (!
|
|
45207
|
+
if (!existsSync21(lockPath)) return null;
|
|
45042
45208
|
try {
|
|
45043
|
-
const lock = JSON.parse(
|
|
45209
|
+
const lock = JSON.parse(readFileSync19(lockPath, "utf8"));
|
|
45044
45210
|
return typeof lock.pid === "number" ? lock : null;
|
|
45045
45211
|
} catch {
|
|
45046
45212
|
return null;
|
|
@@ -45164,12 +45330,12 @@ async function ensureProjectLink(root, profile, client) {
|
|
|
45164
45330
|
}
|
|
45165
45331
|
|
|
45166
45332
|
// src/adopt.ts
|
|
45167
|
-
import { existsSync as
|
|
45168
|
-
import { dirname as dirname8, join as
|
|
45333
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
45334
|
+
import { dirname as dirname8, join as join25 } from "node:path";
|
|
45169
45335
|
function findGitRoot(absPath) {
|
|
45170
45336
|
let dir = absPath;
|
|
45171
45337
|
for (let depth = 0; depth < 64; depth++) {
|
|
45172
|
-
if (
|
|
45338
|
+
if (existsSync22(join25(dir, ".git"))) return dir;
|
|
45173
45339
|
const parent = dirname8(dir);
|
|
45174
45340
|
if (parent === dir) return null;
|
|
45175
45341
|
dir = parent;
|
|
@@ -45357,7 +45523,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45357
45523
|
void ambientLinkAll();
|
|
45358
45524
|
app.route(`/ws/${rec.id}`, rec.webApp);
|
|
45359
45525
|
try {
|
|
45360
|
-
|
|
45526
|
+
writeFileSync16(
|
|
45361
45527
|
rec.engine.paths.daemonLock,
|
|
45362
45528
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
|
|
45363
45529
|
"utf8"
|
|
@@ -45543,7 +45709,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45543
45709
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
45544
45710
|
try {
|
|
45545
45711
|
ensureDir(globalDir());
|
|
45546
|
-
|
|
45712
|
+
writeFileSync16(
|
|
45547
45713
|
lockPath,
|
|
45548
45714
|
JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
|
|
45549
45715
|
"utf8"
|
|
@@ -45552,7 +45718,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45552
45718
|
}
|
|
45553
45719
|
for (const r of records) {
|
|
45554
45720
|
try {
|
|
45555
|
-
|
|
45721
|
+
writeFileSync16(
|
|
45556
45722
|
r.engine.paths.daemonLock,
|
|
45557
45723
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
|
|
45558
45724
|
"utf8"
|
|
@@ -45906,7 +46072,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45906
46072
|
},
|
|
45907
46073
|
async stop() {
|
|
45908
46074
|
try {
|
|
45909
|
-
const cur =
|
|
46075
|
+
const cur = readFileSync20(lockPath, "utf8");
|
|
45910
46076
|
if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
|
|
45911
46077
|
} catch {
|
|
45912
46078
|
}
|
|
@@ -46501,21 +46667,21 @@ async function cmdInit() {
|
|
|
46501
46667
|
if (!skipHooks) {
|
|
46502
46668
|
console.log("");
|
|
46503
46669
|
console.log("installing harness hooks...");
|
|
46504
|
-
const { existsSync:
|
|
46505
|
-
const { join:
|
|
46670
|
+
const { existsSync: existsSync24 } = await import("node:fs");
|
|
46671
|
+
const { join: join27 } = await import("node:path");
|
|
46506
46672
|
try {
|
|
46507
46673
|
await installClaudeHooks(port);
|
|
46508
46674
|
} catch (err2) {
|
|
46509
46675
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46510
46676
|
}
|
|
46511
|
-
if (
|
|
46677
|
+
if (existsSync24(join27(ROOT, ".cursor"))) {
|
|
46512
46678
|
try {
|
|
46513
46679
|
await installCursorMcpConfig();
|
|
46514
46680
|
} catch (err2) {
|
|
46515
46681
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46516
46682
|
}
|
|
46517
46683
|
}
|
|
46518
|
-
if (
|
|
46684
|
+
if (existsSync24(join27(ROOT, ".codex"))) {
|
|
46519
46685
|
try {
|
|
46520
46686
|
await installCodexHooks(port);
|
|
46521
46687
|
} catch (err2) {
|
|
@@ -46672,8 +46838,8 @@ async function cmdStatus() {
|
|
|
46672
46838
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
46673
46839
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
46674
46840
|
}
|
|
46675
|
-
console.log(` graph db: ${
|
|
46676
|
-
console.log(` event log: ${
|
|
46841
|
+
console.log(` graph db: ${existsSync23(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
46842
|
+
console.log(` event log: ${existsSync23(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
46677
46843
|
const lockPath = globalDaemonLock();
|
|
46678
46844
|
const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
|
|
46679
46845
|
console.log(
|
|
@@ -47125,11 +47291,11 @@ async function cmdUse(args2) {
|
|
|
47125
47291
|
}
|
|
47126
47292
|
async function cmdReview() {
|
|
47127
47293
|
const paths = workspacePaths(ROOT);
|
|
47128
|
-
if (!
|
|
47294
|
+
if (!existsSync23(paths.reviewQueue)) {
|
|
47129
47295
|
console.log("(review queue empty)");
|
|
47130
47296
|
return;
|
|
47131
47297
|
}
|
|
47132
|
-
const queue = JSON.parse(
|
|
47298
|
+
const queue = JSON.parse(readFileSync21(paths.reviewQueue, "utf8"));
|
|
47133
47299
|
if (queue.length === 0) {
|
|
47134
47300
|
console.log("(review queue empty)");
|
|
47135
47301
|
return;
|
|
@@ -47783,7 +47949,7 @@ async function gatherRepo(store, ws) {
|
|
|
47783
47949
|
};
|
|
47784
47950
|
}
|
|
47785
47951
|
async function gatherReportData(generatedAt) {
|
|
47786
|
-
const { existsSync:
|
|
47952
|
+
const { existsSync: existsSync24 } = await import("node:fs");
|
|
47787
47953
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
47788
47954
|
const cfg = loadConfig();
|
|
47789
47955
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -47791,7 +47957,7 @@ async function gatherReportData(generatedAt) {
|
|
|
47791
47957
|
for (const ws of listWorkspaces()) {
|
|
47792
47958
|
if (ws.missing) continue;
|
|
47793
47959
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
47794
|
-
if (!
|
|
47960
|
+
if (!existsSync24(dbPath)) continue;
|
|
47795
47961
|
let store = null;
|
|
47796
47962
|
try {
|
|
47797
47963
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -47822,7 +47988,7 @@ async function gatherReportData(generatedAt) {
|
|
|
47822
47988
|
};
|
|
47823
47989
|
}
|
|
47824
47990
|
async function cmdReport(args2) {
|
|
47825
|
-
const { mkdirSync:
|
|
47991
|
+
const { mkdirSync: mkdirSync7, writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
47826
47992
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
47827
47993
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
47828
47994
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -47833,10 +47999,10 @@ async function cmdReport(args2) {
|
|
|
47833
47999
|
process.exit(2);
|
|
47834
48000
|
}
|
|
47835
48001
|
const outDir = workspacePaths(ROOT).configDir;
|
|
47836
|
-
|
|
48002
|
+
mkdirSync7(outDir, { recursive: true });
|
|
47837
48003
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
47838
|
-
for (const f of files)
|
|
47839
|
-
const indexPath =
|
|
48004
|
+
for (const f of files) writeFileSync17(join26(outDir, f.name), f.html, "utf8");
|
|
48005
|
+
const indexPath = join26(outDir, "report.html");
|
|
47840
48006
|
console.log(`report \u2192 ${indexPath}`);
|
|
47841
48007
|
console.log(` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`);
|
|
47842
48008
|
console.log(` open: file://${indexPath.replace(/\\/g, "/")}`);
|
|
@@ -47956,15 +48122,15 @@ function hookRelayCommand(port, path2) {
|
|
|
47956
48122
|
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 '{}'`;
|
|
47957
48123
|
}
|
|
47958
48124
|
async function installClaudeHooks(port) {
|
|
47959
|
-
const { mkdirSync:
|
|
47960
|
-
const { join:
|
|
47961
|
-
const dir =
|
|
47962
|
-
if (!
|
|
47963
|
-
const file2 =
|
|
48125
|
+
const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
48126
|
+
const { join: join27 } = await import("node:path");
|
|
48127
|
+
const dir = join27(ROOT, ".claude");
|
|
48128
|
+
if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
|
|
48129
|
+
const file2 = join27(dir, "settings.json");
|
|
47964
48130
|
let settings = {};
|
|
47965
|
-
if (
|
|
48131
|
+
if (existsSync24(file2)) {
|
|
47966
48132
|
try {
|
|
47967
|
-
settings = JSON.parse(
|
|
48133
|
+
settings = JSON.parse(readFileSync22(file2, "utf8"));
|
|
47968
48134
|
} catch {
|
|
47969
48135
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
47970
48136
|
process.exit(2);
|
|
@@ -48010,10 +48176,10 @@ async function installClaudeHooks(port) {
|
|
|
48010
48176
|
dropErrata(list);
|
|
48011
48177
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
48012
48178
|
}
|
|
48013
|
-
|
|
48179
|
+
writeFileSync17(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
48014
48180
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
48015
48181
|
await installClaudeMcpConfig();
|
|
48016
|
-
const claudeMd =
|
|
48182
|
+
const claudeMd = join27(ROOT, "CLAUDE.md");
|
|
48017
48183
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
48018
48184
|
if (recall.kind === "collision") {
|
|
48019
48185
|
console.warn(
|
|
@@ -48025,15 +48191,15 @@ async function installClaudeHooks(port) {
|
|
|
48025
48191
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
48026
48192
|
}
|
|
48027
48193
|
async function installClaudeMcpConfig() {
|
|
48028
|
-
const { mkdirSync:
|
|
48029
|
-
const { join:
|
|
48030
|
-
const file2 =
|
|
48194
|
+
const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
48195
|
+
const { join: join27, dirname: dirname9 } = await import("node:path");
|
|
48196
|
+
const file2 = join27(ROOT, ".mcp.json");
|
|
48031
48197
|
const dir = dirname9(file2);
|
|
48032
|
-
if (!
|
|
48198
|
+
if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
|
|
48033
48199
|
let cfg = {};
|
|
48034
|
-
if (
|
|
48200
|
+
if (existsSync24(file2)) {
|
|
48035
48201
|
try {
|
|
48036
|
-
cfg = JSON.parse(
|
|
48202
|
+
cfg = JSON.parse(readFileSync22(file2, "utf8"));
|
|
48037
48203
|
} catch {
|
|
48038
48204
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
48039
48205
|
process.exit(2);
|
|
@@ -48041,21 +48207,21 @@ async function installClaudeMcpConfig() {
|
|
|
48041
48207
|
}
|
|
48042
48208
|
cfg.mcpServers ??= {};
|
|
48043
48209
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
48044
|
-
|
|
48210
|
+
writeFileSync17(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
48045
48211
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
48046
48212
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
48047
48213
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
48048
48214
|
}
|
|
48049
48215
|
async function installCursorMcpConfig() {
|
|
48050
|
-
const { mkdirSync:
|
|
48051
|
-
const { join:
|
|
48052
|
-
const dir =
|
|
48053
|
-
if (!
|
|
48054
|
-
const file2 =
|
|
48216
|
+
const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
48217
|
+
const { join: join27 } = await import("node:path");
|
|
48218
|
+
const dir = join27(ROOT, ".cursor");
|
|
48219
|
+
if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
|
|
48220
|
+
const file2 = join27(dir, "mcp.json");
|
|
48055
48221
|
let cfg = {};
|
|
48056
|
-
if (
|
|
48222
|
+
if (existsSync24(file2)) {
|
|
48057
48223
|
try {
|
|
48058
|
-
cfg = JSON.parse(
|
|
48224
|
+
cfg = JSON.parse(readFileSync22(file2, "utf8"));
|
|
48059
48225
|
} catch {
|
|
48060
48226
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
48061
48227
|
process.exit(2);
|
|
@@ -48063,7 +48229,7 @@ async function installCursorMcpConfig() {
|
|
|
48063
48229
|
}
|
|
48064
48230
|
cfg.mcpServers ??= {};
|
|
48065
48231
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
48066
|
-
|
|
48232
|
+
writeFileSync17(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
48067
48233
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
48068
48234
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
48069
48235
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -48071,16 +48237,16 @@ async function installCursorMcpConfig() {
|
|
|
48071
48237
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
48072
48238
|
}
|
|
48073
48239
|
async function installCodexHooks(port) {
|
|
48074
|
-
const { mkdirSync:
|
|
48075
|
-
const { join:
|
|
48076
|
-
const dir =
|
|
48077
|
-
if (!
|
|
48078
|
-
const file2 =
|
|
48240
|
+
const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
48241
|
+
const { join: join27 } = await import("node:path");
|
|
48242
|
+
const dir = join27(ROOT, ".codex");
|
|
48243
|
+
if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
|
|
48244
|
+
const file2 = join27(dir, "config.toml");
|
|
48079
48245
|
const BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
48080
48246
|
const END = `# <<< errata hooks`;
|
|
48081
48247
|
let existing = "";
|
|
48082
|
-
if (
|
|
48083
|
-
existing =
|
|
48248
|
+
if (existsSync24(file2)) {
|
|
48249
|
+
existing = readFileSync22(file2, "utf8");
|
|
48084
48250
|
const beginIdx = existing.indexOf(BEGIN);
|
|
48085
48251
|
const endIdx = existing.indexOf(END);
|
|
48086
48252
|
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
@@ -48109,7 +48275,7 @@ ${END}
|
|
|
48109
48275
|
const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
48110
48276
|
|
|
48111
48277
|
${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
|
|
48112
|
-
|
|
48278
|
+
writeFileSync17(file2, final, "utf8");
|
|
48113
48279
|
console.log(`installed Codex hooks \u2192 ${file2}`);
|
|
48114
48280
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
48115
48281
|
console.log("");
|
|
@@ -48372,7 +48538,7 @@ async function cmdDash(args2) {
|
|
|
48372
48538
|
await yieldToLoop2();
|
|
48373
48539
|
try {
|
|
48374
48540
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
48375
|
-
const res = bleedRules(
|
|
48541
|
+
const res = bleedRules(join26(r.root, ".claude", "rules"), items);
|
|
48376
48542
|
if (res.written || res.pruned) {
|
|
48377
48543
|
console.log(
|
|
48378
48544
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|