@doidor/agentrig 0.5.3

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -0
  3. package/dist/agent/claude.js +125 -0
  4. package/dist/agent/claude.js.map +1 -0
  5. package/dist/agent/copilot.js +147 -0
  6. package/dist/agent/copilot.js.map +1 -0
  7. package/dist/agent/index.js +17 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/agent/provider.js +10 -0
  10. package/dist/agent/provider.js.map +1 -0
  11. package/dist/cli.js +169 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/commands/compile.js +42 -0
  14. package/dist/commands/compile.js.map +1 -0
  15. package/dist/commands/dashboard.js +35 -0
  16. package/dist/commands/dashboard.js.map +1 -0
  17. package/dist/commands/doctor.js +40 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/eval.js +178 -0
  20. package/dist/commands/eval.js.map +1 -0
  21. package/dist/commands/init.js +100 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/commands/update.js +176 -0
  24. package/dist/commands/update.js.map +1 -0
  25. package/dist/core/activity.js +80 -0
  26. package/dist/core/activity.js.map +1 -0
  27. package/dist/core/audit.js +112 -0
  28. package/dist/core/audit.js.map +1 -0
  29. package/dist/core/compile.js +250 -0
  30. package/dist/core/compile.js.map +1 -0
  31. package/dist/core/fsutil.js +45 -0
  32. package/dist/core/fsutil.js.map +1 -0
  33. package/dist/core/install.js +97 -0
  34. package/dist/core/install.js.map +1 -0
  35. package/dist/core/knowledge.js +34 -0
  36. package/dist/core/knowledge.js.map +1 -0
  37. package/dist/core/logger.js +31 -0
  38. package/dist/core/logger.js.map +1 -0
  39. package/dist/core/paths.js +22 -0
  40. package/dist/core/paths.js.map +1 -0
  41. package/dist/core/setupsteps.js +72 -0
  42. package/dist/core/setupsteps.js.map +1 -0
  43. package/dist/core/state.js +19 -0
  44. package/dist/core/state.js.map +1 -0
  45. package/dist/core/surfaces.js +62 -0
  46. package/dist/core/surfaces.js.map +1 -0
  47. package/dist/prompts/index.js +117 -0
  48. package/dist/prompts/index.js.map +1 -0
  49. package/dist/version.js +26 -0
  50. package/dist/version.js.map +1 -0
  51. package/knowledge/PRINCIPLES.md +106 -0
  52. package/knowledge/manifest.json +247 -0
  53. package/knowledge/templates/AGENTS.md +66 -0
  54. package/knowledge/templates/AGENTS.package.example.md +19 -0
  55. package/knowledge/templates/agents/README.md +33 -0
  56. package/knowledge/templates/agents/developer.md +7 -0
  57. package/knowledge/templates/agents/developer.yml +7 -0
  58. package/knowledge/templates/agents/judge.md +6 -0
  59. package/knowledge/templates/agents/judge.yml +6 -0
  60. package/knowledge/templates/agents/reviewer.md +6 -0
  61. package/knowledge/templates/agents/reviewer.yml +7 -0
  62. package/knowledge/templates/agents/triager.md +8 -0
  63. package/knowledge/templates/agents/triager.yml +8 -0
  64. package/knowledge/templates/dashboard/dashboard.mjs +261 -0
  65. package/knowledge/templates/eval/RUBRIC.md +94 -0
  66. package/knowledge/templates/eval/axes.json +56 -0
  67. package/knowledge/templates/eval/checks.json +304 -0
  68. package/knowledge/templates/eval/sandbox/eval-rules.md +23 -0
  69. package/knowledge/templates/eval/scenarios/README.md +24 -0
  70. package/knowledge/templates/eval/scenarios/add-small-feature.md +28 -0
  71. package/knowledge/templates/eval/scenarios/fix-failing-test.md +27 -0
  72. package/knowledge/templates/eval/scenarios/review-catches-bug.md +30 -0
  73. package/knowledge/templates/eval/score.mjs +257 -0
  74. package/knowledge/templates/eval/static-audit.mjs +112 -0
  75. package/knowledge/templates/harness/ORCHESTRATION.md +53 -0
  76. package/knowledge/templates/harness/state-machine.yml +105 -0
  77. package/knowledge/templates/mcp/mcp.json +12 -0
  78. package/knowledge/templates/rules/README.md +32 -0
  79. package/knowledge/templates/rules/code-review.md +26 -0
  80. package/knowledge/templates/rules/coding-standards.md +15 -0
  81. package/knowledge/templates/rules/no-debug-logging.md +16 -0
  82. package/knowledge/templates/rules/security.md +23 -0
  83. package/knowledge/templates/scripts/repair-worktrees.sh +124 -0
  84. package/knowledge/templates/skills/fix-ci/SKILL.md +17 -0
  85. package/knowledge/templates/skills/harness-eval/SKILL.md +83 -0
  86. package/knowledge/templates/skills/self-verify/SKILL.md +25 -0
  87. package/knowledge/templates/skills/skill-authoring/SKILL.md +35 -0
  88. package/knowledge/templates/skills/skill-improver/SKILL.md +23 -0
  89. package/knowledge/templates/skills/verify-loop/SKILL.md +35 -0
  90. package/knowledge/templates/wiki/README.md +23 -0
  91. package/knowledge/templates/wiki/_TEMPLATE.md +16 -0
  92. package/knowledge/templates/wiki/index.md +29 -0
  93. package/knowledge/templates/wiki/troubleshooting.md +14 -0
  94. package/package.json +70 -0
@@ -0,0 +1,176 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { createHash } from "node:crypto";
3
+ import { spawnSync } from "node:child_process";
4
+ import { writeState, readState } from "../core/state.js";
5
+ import { loadManifest, refreshPolicy } from "../core/knowledge.js";
6
+ import { install, baseVars, addOnlyCopy } from "../core/install.js";
7
+ import { linkSurfaces } from "../core/surfaces.js";
8
+ import { compileSurfaces } from "../core/compile.js";
9
+ import { resolveSrc } from "../core/knowledge.js";
10
+ import { auditHarness } from "../core/audit.js";
11
+ import { color, log } from "../core/logger.js";
12
+ import { ActivityMonitor } from "../core/activity.js";
13
+ import { getProvider } from "../agent/index.js";
14
+ import { buildUpdatePrompt, SYSTEM_MESSAGE } from "../prompts/index.js";
15
+ import { renderAudit } from "./eval.js";
16
+ import { join } from "../core/fsutil.js";
17
+ import pkg from "../version.js";
18
+ function hashFile(path) {
19
+ if (!existsSync(path))
20
+ return null;
21
+ return createHash("sha256").update(readFileSync(path)).digest("hex");
22
+ }
23
+ /** Read-only: show how preserved (tailorable) files differ from the latest canonical version. */
24
+ function diffPreserved(repoRoot) {
25
+ const manifest = loadManifest();
26
+ const preserved = manifest.artifacts.filter((a) => a.kind !== "template" && refreshPolicy(a) === "preserve");
27
+ let any = false;
28
+ for (const a of preserved) {
29
+ const { drifted } = addOnlyCopy(repoRoot, resolveSrc(a.src), join(repoRoot, a.dest), a.mode, false);
30
+ for (const relPath of drifted) {
31
+ any = true;
32
+ const repoFile = join(repoRoot, relPath);
33
+ // Map the drifted repo-relative path back to its canonical source file.
34
+ const sub = relPath.slice(a.dest.length).replace(/^\//, "");
35
+ const canonical = sub ? join(resolveSrc(a.src), sub) : resolveSrc(a.src);
36
+ log.info(color.bold(`\n• ${relPath}`) + color.dim(" (preserved; canonical drifted)"));
37
+ const res = spawnSync("diff", ["-u", "--label", "canonical", canonical, "--label", relPath, repoFile], { encoding: "utf8" });
38
+ log.info(res.stdout ? res.stdout.trimEnd() : color.dim(" (binary or unreadable diff)"));
39
+ }
40
+ }
41
+ if (!any)
42
+ log.ok("no preserved files have drifted from canonical.");
43
+ return 0;
44
+ }
45
+ /**
46
+ * Re-sync the latest canonical best practices into a repo. Machinery files are overwritten;
47
+ * tailorable artifacts are refreshed add-only (new files added, existing ones preserved) with any
48
+ * canonical drift handed to the agent reconcile. Templates (AGENTS.md) are reconciled by the agent.
49
+ */
50
+ export async function updateCommand(repoRoot, options) {
51
+ const state = readState(repoRoot);
52
+ if (!state) {
53
+ log.error("No AgentRig harness here. Run `agentrig init` first.");
54
+ return 1;
55
+ }
56
+ if (options.diff) {
57
+ log.info(color.bold("AgentRig — drift of preserved files vs canonical\n"));
58
+ return diffPreserved(repoRoot);
59
+ }
60
+ const manifest = loadManifest();
61
+ const versionBump = state.knowledgeVersion !== manifest.knowledgeVersion;
62
+ const refreshable = manifest.artifacts.filter((a) => a.kind !== "template");
63
+ const templates = manifest.artifacts.filter((a) => a.kind === "template").map((a) => a.dest);
64
+ // Split by refresh policy. `overwrite` = AgentRig-owned machinery/docs (replace to stay current);
65
+ // `preserve` = tailorable content (add-only; never clobber existing files).
66
+ const toOverwrite = [];
67
+ for (const a of refreshable.filter((a) => refreshPolicy(a) === "overwrite")) {
68
+ if (a.kind === "dir") {
69
+ if (versionBump)
70
+ toOverwrite.push(a);
71
+ }
72
+ else if (hashFile(resolveSrc(a.src)) !== hashFile(join(repoRoot, a.dest))) {
73
+ toOverwrite.push(a);
74
+ }
75
+ }
76
+ // Add-only refresh for preserved artifacts: classify first (apply only when not a dry run).
77
+ const added = [];
78
+ const drifted = [];
79
+ for (const a of refreshable.filter((a) => refreshPolicy(a) === "preserve")) {
80
+ const r = addOnlyCopy(repoRoot, resolveSrc(a.src), join(repoRoot, a.dest), a.mode, !options.dryRun);
81
+ added.push(...r.added);
82
+ drifted.push(...r.drifted);
83
+ }
84
+ log.info(color.bold(`AgentRig — updating harness (knowledge ${state.knowledgeVersion} → ${manifest.knowledgeVersion})\n`));
85
+ if (toOverwrite.length === 0 && added.length === 0 && drifted.length === 0 && !versionBump) {
86
+ log.ok("already up to date — nothing to refresh.");
87
+ return 0;
88
+ }
89
+ if (options.dryRun) {
90
+ if (toOverwrite.length) {
91
+ log.step("dry run — would overwrite (AgentRig-owned):");
92
+ for (const a of toOverwrite)
93
+ log.info(` ${a.dest}`);
94
+ }
95
+ if (added.length) {
96
+ log.step("dry run — would add new files:");
97
+ for (const f of added)
98
+ log.info(` ${f}`);
99
+ }
100
+ if (drifted.length) {
101
+ log.step("dry run — preserved (local edits kept); agent would reconcile canonical drift:");
102
+ for (const f of drifted)
103
+ log.info(color.dim(` ${f}`));
104
+ }
105
+ log.step("dry run — agent would reconcile templates:");
106
+ for (const t of templates)
107
+ log.info(color.dim(` ${t}`));
108
+ return 0;
109
+ }
110
+ // Apply: overwrite machinery (preserved files were already add-only-applied above).
111
+ log.step("refreshing harness…");
112
+ const onlyOverwrite = { ...manifest, artifacts: toOverwrite };
113
+ const { installed } = install(repoRoot, onlyOverwrite, { vars: baseVars(repoRoot) });
114
+ log.ok(`overwrote ${installed.length} owned file(s); added ${added.length} new file(s); preserved ${drifted.length} edited file(s)`);
115
+ // Ensure vendor-surface symlinks exist (added in later knowledge versions).
116
+ const surfaces = linkSurfaces(repoRoot);
117
+ if (surfaces.created.length)
118
+ log.ok(`linked surfaces: ${surfaces.created.join(", ")} → .agents`);
119
+ // Re-project the canonical source into every agent surface (local + remote).
120
+ const compiled = compileSurfaces(repoRoot);
121
+ log.ok(`compiled ${compiled.generated.length} agent-surface file(s)`);
122
+ // The agent reconciles templates plus any preserved files whose canonical version drifted.
123
+ const reconcileList = [...drifted, ...templates];
124
+ if (!options.skipAgent) {
125
+ const provider = getProvider();
126
+ const pre = await provider.preflight();
127
+ if (pre.ok) {
128
+ log.ok(`agent ready (${pre.detail})`);
129
+ log.step("reconciling repo-specific content…");
130
+ const monitor = new ActivityMonitor().start();
131
+ const convo = await provider.startConversation({
132
+ cwd: repoRoot,
133
+ ...(options.model ? { model: options.model } : {}),
134
+ systemMessage: SYSTEM_MESSAGE,
135
+ onEvent: monitor.handle,
136
+ });
137
+ try {
138
+ const summary = await convo.send(buildUpdatePrompt(reconcileList));
139
+ monitor.stop();
140
+ log.ok("reconciliation complete");
141
+ if (options.verbose)
142
+ log.info(color.dim(summary));
143
+ }
144
+ finally {
145
+ monitor.stop();
146
+ await convo.end();
147
+ }
148
+ }
149
+ else {
150
+ log.warn(`agent unavailable (${pre.detail}); skipped reconciliation.`);
151
+ }
152
+ }
153
+ else if (drifted.length) {
154
+ log.warn(`--skip-agent: ${drifted.length} edited file(s) were preserved; canonical updates to them were NOT applied.`);
155
+ log.warn("Run `agentrig update` (with the agent) to reconcile them, or diff against the templates manually.");
156
+ }
157
+ // Merge installed records: every refreshable artifact is present/current after update.
158
+ const now = new Date().toISOString();
159
+ const byId = new Map(state.installed.map((i) => [i.id, i]));
160
+ for (const a of refreshable) {
161
+ byId.set(a.id, { id: a.id, dest: a.dest, knowledgeVersion: manifest.knowledgeVersion, installedAt: now });
162
+ }
163
+ const newState = {
164
+ ...state,
165
+ agentrigVersion: pkg.version,
166
+ knowledgeVersion: manifest.knowledgeVersion,
167
+ updatedAt: now,
168
+ installed: [...byId.values()],
169
+ };
170
+ writeState(repoRoot, newState);
171
+ log.ok("updated .agentrig/state.json");
172
+ log.info("");
173
+ renderAudit(auditHarness(repoRoot));
174
+ return 0;
175
+ }
176
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { color, log, isVerbose } from "./logger.js";
2
+ function truncate(s, n) {
3
+ const oneLine = s.replace(/\s+/g, " ").trim();
4
+ return oneLine.length > n ? oneLine.slice(0, n - 1) + "…" : oneLine;
5
+ }
6
+ /**
7
+ * Renders the agent's live activity (intents, tool calls, reasoning, narration) as timestamped
8
+ * lines, and emits a heartbeat so long, quiet steps never look frozen. Pass its `handle` as the
9
+ * conversation's `onEvent`.
10
+ */
11
+ export class ActivityMonitor {
12
+ heartbeatSeconds;
13
+ startMs = Date.now();
14
+ lastEventMs = Date.now();
15
+ toolCount = 0;
16
+ lastLabel = "thinking…";
17
+ timer = null;
18
+ verbose = isVerbose();
19
+ constructor(heartbeatSeconds = 15) {
20
+ this.heartbeatSeconds = heartbeatSeconds;
21
+ }
22
+ elapsed() {
23
+ const s = Math.floor((Date.now() - this.startMs) / 1000);
24
+ return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m${String(s % 60).padStart(2, "0")}s`;
25
+ }
26
+ line(symbol, text) {
27
+ log.activity(`[${this.elapsed()}] ${symbol} ${text}`);
28
+ }
29
+ /** Start the heartbeat. Call `stop()` when the step completes. */
30
+ start() {
31
+ this.timer = setInterval(() => {
32
+ const quietFor = Math.floor((Date.now() - this.lastEventMs) / 1000);
33
+ if (quietFor >= this.heartbeatSeconds) {
34
+ this.line("·", `still working — ${this.toolCount} tool calls so far, last: ${this.lastLabel}`);
35
+ this.lastEventMs = Date.now();
36
+ }
37
+ }, this.heartbeatSeconds * 1000);
38
+ if (this.timer.unref)
39
+ this.timer.unref();
40
+ return this;
41
+ }
42
+ stop() {
43
+ if (this.timer)
44
+ clearInterval(this.timer);
45
+ this.timer = null;
46
+ }
47
+ /** Bind for use as `onEvent`. */
48
+ handle = (e) => {
49
+ this.lastEventMs = Date.now();
50
+ switch (e.type) {
51
+ case "intent":
52
+ this.lastLabel = truncate(e.text, 50);
53
+ this.line(color.cyan("▸"), truncate(e.text, 100));
54
+ break;
55
+ case "tool_start":
56
+ this.toolCount++;
57
+ this.lastLabel = e.text;
58
+ this.line("⚙", `${e.text}${e.detail ? color.dim(" · " + truncate(e.detail, 60)) : ""}`);
59
+ break;
60
+ case "tool_done":
61
+ if (e.ok === false)
62
+ this.line(color.red("✗"), `tool failed: ${truncate(e.text, 80)}`);
63
+ else if (this.verbose)
64
+ this.line(color.dim("✓"), "ok");
65
+ break;
66
+ case "assistant":
67
+ // Intermediate narration between tool batches — show a short summary.
68
+ this.line(color.dim("…"), truncate(e.text, 100));
69
+ break;
70
+ case "reasoning":
71
+ if (this.verbose)
72
+ this.line(color.dim("~"), truncate(e.text, 100));
73
+ break;
74
+ case "compaction":
75
+ this.line(color.yellow("⟳"), e.text);
76
+ break;
77
+ }
78
+ };
79
+ }
80
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/core/activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGpD,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAQG;IAPZ,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,SAAS,GAAG,CAAC,CAAC;IACd,SAAS,GAAG,WAAW,CAAC;IACxB,KAAK,GAA0C,IAAI,CAAC;IAC3C,OAAO,GAAG,SAAS,EAAE,CAAC;IAEvC,YAA6B,mBAAmB,EAAE;QAArB,qBAAgB,GAAhB,gBAAgB,CAAK;IAAG,CAAC;IAE9C,OAAO;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IACxF,CAAC;IAEO,IAAI,CAAC,MAAc,EAAE,IAAY;QACvC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,kEAAkE;IAClE,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;YACpE,IAAI,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,IAAI,CAAC,SAAS,6BAA6B,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC/F,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAChC,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,iCAAiC;IACxB,MAAM,GAAG,CAAC,CAAa,EAAQ,EAAE;QACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,QAAQ;gBACX,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,YAAY;gBACf,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxF,MAAM;YACR,KAAK,WAAW;gBACd,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK;oBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAgB,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;qBACjF,IAAI,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,WAAW;gBACd,sEAAsE;gBACtE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;gBACjD,MAAM;YACR,KAAK,WAAW;gBACd,IAAI,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;gBACnE,MAAM;YACR,KAAK,YAAY;gBACf,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM;QACV,CAAC;IACH,CAAC,CAAC;CACH"}
@@ -0,0 +1,112 @@
1
+ import { existsSync, statSync, readdirSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { readText } from "./fsutil.js";
4
+ import { loadCanonicalChecks } from "./knowledge.js";
5
+ function frontmatter(text) {
6
+ if (!text || !text.startsWith("---"))
7
+ return null;
8
+ const end = text.indexOf("\n---", 3);
9
+ return end < 0 ? null : text.slice(3, end);
10
+ }
11
+ function extractValue(text, key) {
12
+ if (!text)
13
+ return null;
14
+ const m = text.match(new RegExp("^\\s*" + key + "\\s*:\\s*(.+)\\s*$", "m"));
15
+ return m ? m[1].trim() : null;
16
+ }
17
+ function scoreCheck(repoRoot, c) {
18
+ const rel = (p) => resolve(repoRoot, p);
19
+ const read = (p) => readText(rel(p));
20
+ switch (c.type) {
21
+ case "path-exists": {
22
+ const p = String(c.path);
23
+ return existsSync(rel(p)) ? { score: 1, evidence: "" } : { score: 0, evidence: `missing ${p}` };
24
+ }
25
+ case "file-contains": {
26
+ const p = String(c.path);
27
+ const text = read(p);
28
+ if (text == null)
29
+ return { score: 0, evidence: `missing ${p}` };
30
+ const patterns = c.patterns ?? [];
31
+ const missing = patterns.filter((x) => !text.includes(x));
32
+ return missing.length === 0
33
+ ? { score: 1, evidence: "" }
34
+ : { score: 0.5, evidence: `present but missing markers: ${missing.join(", ")}` };
35
+ }
36
+ case "dir-min": {
37
+ const p = String(c.path);
38
+ const abs = rel(p);
39
+ if (!existsSync(abs) || !statSync(abs).isDirectory())
40
+ return { score: 0, evidence: `missing dir ${p}` };
41
+ const n = readdirSync(abs).filter((e) => !e.startsWith(".")).length;
42
+ const min = Number(c.min ?? 1);
43
+ return n >= min ? { score: 1, evidence: "" } : { score: 0.5, evidence: `${n} entries, need ${min}` };
44
+ }
45
+ case "frontmatter-keys": {
46
+ const p = String(c.path);
47
+ const fm = frontmatter(read(p));
48
+ if (fm == null)
49
+ return { score: 0, evidence: `no frontmatter in ${p}` };
50
+ const keys = c.keys ?? [];
51
+ const missing = keys.filter((k) => !new RegExp("^\\s*" + k + "\\s*:", "m").test(fm));
52
+ return missing.length === 0
53
+ ? { score: 1, evidence: "" }
54
+ : { score: 0.5, evidence: `missing keys: ${missing.join(", ")}` };
55
+ }
56
+ case "roles-distinct-models": {
57
+ const key = String(c.key ?? "model");
58
+ const dev = extractValue(read(String(c.developer)), key);
59
+ const rev = extractValue(read(String(c.reviewer)), key);
60
+ if (!dev || !rev)
61
+ return { score: 0, evidence: "developer/reviewer model not declared" };
62
+ return dev !== rev
63
+ ? { score: 1, evidence: "" }
64
+ : { score: 0.5, evidence: `developer and reviewer share model "${dev}"` };
65
+ }
66
+ default:
67
+ return { score: 0, evidence: `unknown check type ${c.type}` };
68
+ }
69
+ }
70
+ /** Resolve which checks to use: prefer the repo's installed checks.json, else AgentRig canonical. */
71
+ function resolveChecks(repoRoot) {
72
+ const repoChecks = readText(join(repoRoot, ".agentrig", "eval", "checks.json"));
73
+ if (repoChecks) {
74
+ try {
75
+ return { checks: (JSON.parse(repoChecks).checks ?? []), source: "repo" };
76
+ }
77
+ catch {
78
+ /* fall through to canonical */
79
+ }
80
+ }
81
+ return { checks: loadCanonicalChecks(), source: "canonical" };
82
+ }
83
+ export function auditHarness(repoRoot) {
84
+ const { checks, source } = resolveChecks(repoRoot);
85
+ const results = checks.map((c) => {
86
+ const { score, evidence } = scoreCheck(repoRoot, c);
87
+ return { id: c.id, principle: c.principle, title: c.title, score, evidence };
88
+ });
89
+ let wSum = 0;
90
+ let wScore = 0;
91
+ const principleAcc = new Map();
92
+ for (let i = 0; i < results.length; i++) {
93
+ const w = Number(checks[i].weight ?? 1);
94
+ wSum += w;
95
+ wScore += w * results[i].score;
96
+ const acc = principleAcc.get(results[i].principle) ?? { sum: 0, n: 0 };
97
+ acc.sum += results[i].score;
98
+ acc.n += 1;
99
+ principleAcc.set(results[i].principle, acc);
100
+ }
101
+ const aggregate = wSum ? wScore / wSum : 0;
102
+ return {
103
+ harnessScore: Math.round(aggregate * 1000) / 10,
104
+ aggregate,
105
+ results,
106
+ byPrinciple: [...principleAcc.entries()]
107
+ .sort((a, b) => a[0] - b[0])
108
+ .map(([principle, v]) => ({ principle, score: v.sum / v.n })),
109
+ source,
110
+ };
111
+ }
112
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/core/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,250 @@
1
+ import { existsSync, readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { ensureDir } from "./fsutil.js";
4
+ const GEN_MD = "<!-- Generated by AgentRig from AGENTS.md + .agents/rules/. Do not edit here — edit the source and run `agentrig compile`. -->";
5
+ const GEN_HASH = "# Generated by AgentRig. Do not edit here — edit the source and run `agentrig compile`.";
6
+ /** Extract a section from AGENTS.md: prefer the AGENTRIG marker block, fall back to a `## Heading`. */
7
+ function extractAgentsSection(text, marker, heading) {
8
+ const start = `<!-- AGENTRIG:${marker}:start -->`;
9
+ const end = `<!-- AGENTRIG:${marker}:end -->`;
10
+ const si = text.indexOf(start);
11
+ const ei = text.indexOf(end);
12
+ if (si >= 0 && ei > si)
13
+ return text.slice(si + start.length, ei).trim();
14
+ // Heading fallback: from "## <heading>" to the next "## ".
15
+ const h = new RegExp(`^##\\s+${heading}.*$`, "mi");
16
+ const m = h.exec(text);
17
+ if (!m)
18
+ return "";
19
+ const after = text.slice(m.index + m[0].length);
20
+ const nextH = after.search(/^##\s+/m);
21
+ return (nextH < 0 ? after : after.slice(0, nextH)).trim();
22
+ }
23
+ /** Drop lines still containing unfilled {{PLACEHOLDER}} template tokens. */
24
+ function dropPlaceholders(text) {
25
+ return text
26
+ .split("\n")
27
+ .filter((l) => !/\{\{[A-Z0-9_]+\}\}/.test(l))
28
+ .join("\n")
29
+ .trim();
30
+ }
31
+ function parseGlobs(raw) {
32
+ if (!raw)
33
+ return ["**/*"];
34
+ const arr = raw.match(/\[(.*)\]/);
35
+ const inner = arr ? arr[1] : raw;
36
+ const globs = inner
37
+ .split(",")
38
+ .map((s) => s.trim().replace(/^["']|["']$/g, ""))
39
+ .filter(Boolean);
40
+ return globs.length ? globs : ["**/*"];
41
+ }
42
+ function loadRules(repoRoot) {
43
+ const dir = join(repoRoot, ".agents", "rules");
44
+ if (!existsSync(dir))
45
+ return [];
46
+ const rules = [];
47
+ for (const file of readdirSync(dir)) {
48
+ if (!file.endsWith(".md") || file === "README.md")
49
+ continue;
50
+ const text = readFileSync(join(dir, file), "utf8");
51
+ const fm = text.startsWith("---") ? text.slice(3, text.indexOf("\n---", 3)) : "";
52
+ const body = text.startsWith("---") ? text.slice(text.indexOf("\n---", 3) + 4).trim() : text.trim();
53
+ const globs = parseGlobs((fm.match(/^\s*globs\s*:\s*(.+)$/m) || [])[1]);
54
+ const description = ((fm.match(/^\s*description\s*:\s*(.+)$/m) || [])[1] || file.replace(/\.md$/, "")).trim();
55
+ rules.push({ name: file.replace(/\.md$/, ""), globs, description, body });
56
+ }
57
+ return rules;
58
+ }
59
+ function detectSetup(repoRoot) {
60
+ const has = (f) => existsSync(join(repoRoot, f));
61
+ if (has("package.json")) {
62
+ let install = "npm install";
63
+ let cache = "npm";
64
+ if (has("pnpm-lock.yaml")) {
65
+ install = "corepack enable && pnpm install --frozen-lockfile";
66
+ cache = "pnpm";
67
+ }
68
+ else if (has("yarn.lock")) {
69
+ install = "corepack enable && yarn install --frozen-lockfile";
70
+ cache = "yarn";
71
+ }
72
+ else if (has("package-lock.json")) {
73
+ install = "npm ci";
74
+ cache = "npm";
75
+ }
76
+ return {
77
+ name: "Node.js",
78
+ steps: ` - name: Set up Node.js
79
+ uses: actions/setup-node@v4
80
+ with:
81
+ node-version: "22"
82
+ cache: "${cache}"
83
+ - name: Install dependencies
84
+ run: ${install}`,
85
+ };
86
+ }
87
+ if (has("pyproject.toml") || has("requirements.txt")) {
88
+ return {
89
+ name: "Python",
90
+ steps: ` - name: Set up Python
91
+ uses: actions/setup-python@v5
92
+ with:
93
+ python-version: "3.x"
94
+ - name: Install dependencies
95
+ run: pip install -e . || pip install -r requirements.txt`,
96
+ };
97
+ }
98
+ if (has("go.mod")) {
99
+ return {
100
+ name: "Go",
101
+ steps: ` - name: Set up Go
102
+ uses: actions/setup-go@v5
103
+ with:
104
+ go-version: "stable"
105
+ - name: Download modules
106
+ run: go mod download`,
107
+ };
108
+ }
109
+ return {
110
+ name: "generic",
111
+ steps: ` # TODO: set up your toolchain and install dependencies here so Copilot's
112
+ # ephemeral environment is ready before it starts working.`,
113
+ };
114
+ }
115
+ function write(repoRoot, rel, content, result) {
116
+ const abs = join(repoRoot, rel);
117
+ ensureDir(join(abs, ".."));
118
+ writeFileSync(abs, content.endsWith("\n") ? content : content + "\n");
119
+ result.generated.push(rel);
120
+ }
121
+ /**
122
+ * Project the canonical source (AGENTS.md + .agents/rules/) into every agent ecosystem's NATIVE
123
+ * surface — local and remote — so any agent benefits without lock-in. Idempotent. Pure projections
124
+ * are regenerated each run; `copilot-setup-steps.yml` is scaffolded once (user-owned).
125
+ */
126
+ export function compileSurfaces(repoRoot) {
127
+ const result = { generated: [], skipped: [] };
128
+ const agentsPath = join(repoRoot, "AGENTS.md");
129
+ if (!existsSync(agentsPath)) {
130
+ result.skipped.push({ path: "AGENTS.md", reason: "missing — run `agentrig init` first" });
131
+ return result;
132
+ }
133
+ const agents = readFileSync(agentsPath, "utf8");
134
+ const critical = extractAgentsSection(agents, "critical-rules", "Critical Rules");
135
+ const context = dropPlaceholders(extractAgentsSection(agents, "context", "What this repository is"));
136
+ const rules = loadRules(repoRoot);
137
+ // --- GitHub Copilot (remote coding agent + IDE): repo-wide custom instructions ---
138
+ write(repoRoot, ".github/copilot-instructions.md", [
139
+ GEN_MD,
140
+ "",
141
+ "# Copilot instructions",
142
+ "",
143
+ critical || "See AGENTS.md for the project's agent instructions.",
144
+ "",
145
+ context ? "## About this repository\n\n" + context + "\n" : "",
146
+ "The full agent guide is in [AGENTS.md](../AGENTS.md). Path-specific rules live in",
147
+ "`.github/instructions/`.",
148
+ ].join("\n"), result);
149
+ // --- GitHub path-scoped instructions, one per rule (applyTo = the rule's globs) ---
150
+ for (const rule of rules) {
151
+ write(repoRoot, `.github/instructions/${rule.name}.instructions.md`, [
152
+ "---",
153
+ `applyTo: "${rule.globs.join(",")}"`,
154
+ "---",
155
+ GEN_MD,
156
+ "",
157
+ rule.body,
158
+ ].join("\n"), result);
159
+ }
160
+ // --- Cursor: .cursor/rules/*.mdc, one per rule ---
161
+ for (const rule of rules) {
162
+ const alwaysApply = rule.globs.length === 1 && rule.globs[0] === "**/*";
163
+ write(repoRoot, `.cursor/rules/${rule.name}.mdc`, [
164
+ "---",
165
+ `description: ${rule.description}`,
166
+ `globs: ${rule.globs.join(",")}`,
167
+ `alwaysApply: ${alwaysApply}`,
168
+ "---",
169
+ GEN_MD,
170
+ "",
171
+ rule.body,
172
+ ].join("\n"), result);
173
+ }
174
+ // --- Claude Code: CLAUDE.md imports AGENTS.md + inlines the critical rules ---
175
+ write(repoRoot, "CLAUDE.md", [
176
+ GEN_MD,
177
+ "",
178
+ "# Claude Code instructions",
179
+ "",
180
+ "@AGENTS.md",
181
+ "",
182
+ critical ? "## Critical rules\n\n" + critical : "",
183
+ ].join("\n"), result);
184
+ // --- MCP: project .mcp.json to the surfaces that read their own location ---
185
+ const mcpPath = join(repoRoot, ".mcp.json");
186
+ if (existsSync(mcpPath)) {
187
+ try {
188
+ const mcp = JSON.parse(readFileSync(mcpPath, "utf8"));
189
+ const servers = mcp.mcpServers ?? mcp.servers ?? {};
190
+ // VS Code reads `.vscode/mcp.json` with a top-level `servers` key.
191
+ write(repoRoot, ".vscode/mcp.json", JSON.stringify({ servers }, null, 2), result);
192
+ // Reference for the GitHub Copilot coding agent (also configurable in repo settings).
193
+ write(repoRoot, ".github/copilot/mcp.json", JSON.stringify({
194
+ $comment: "AgentRig: MCP servers for the Copilot coding agent. Add these in Settings → Copilot → coding agent if not auto-loaded.",
195
+ mcpServers: servers,
196
+ }, null, 2), result);
197
+ }
198
+ catch {
199
+ result.skipped.push({ path: ".vscode/mcp.json", reason: "could not parse .mcp.json" });
200
+ }
201
+ }
202
+ // --- Remote env: copilot-setup-steps.yml (scaffold once; user-owned thereafter) ---
203
+ const setupRel = ".github/workflows/copilot-setup-steps.yml";
204
+ if (existsSync(join(repoRoot, setupRel))) {
205
+ result.skipped.push({ path: setupRel, reason: "exists (user-owned; left untouched)" });
206
+ }
207
+ else {
208
+ const setup = detectSetup(repoRoot);
209
+ write(repoRoot, setupRel, `name: "Copilot Setup Steps"
210
+ ${GEN_HASH}
211
+ # Prepares the Copilot coding agent's ephemeral environment (detected stack: ${setup.name}).
212
+ # Customize freely — this file is yours after the first scaffold.
213
+
214
+ on:
215
+ workflow_dispatch:
216
+ push:
217
+ paths:
218
+ - .github/workflows/copilot-setup-steps.yml
219
+ pull_request:
220
+ paths:
221
+ - .github/workflows/copilot-setup-steps.yml
222
+
223
+ jobs:
224
+ # The job MUST be named \`copilot-setup-steps\` or Copilot will not pick it up.
225
+ copilot-setup-steps:
226
+ runs-on: ubuntu-latest
227
+ permissions:
228
+ contents: read
229
+ steps:
230
+ - name: Checkout code
231
+ uses: actions/checkout@v5
232
+ ${setup.steps}
233
+ `, result);
234
+ }
235
+ return result;
236
+ }
237
+ /** Files compileSurfaces is responsible for (used by audit/checks awareness). */
238
+ export function compiledSurfacePaths(repoRoot) {
239
+ const paths = [
240
+ ".github/copilot-instructions.md",
241
+ "CLAUDE.md",
242
+ ".vscode/mcp.json",
243
+ ".github/workflows/copilot-setup-steps.yml",
244
+ ];
245
+ const instr = join(repoRoot, ".github", "instructions");
246
+ if (existsSync(instr) && statSync(instr).isDirectory())
247
+ paths.push(".github/instructions");
248
+ return paths;
249
+ }
250
+ //# sourceMappingURL=compile.js.map