@zephyrdeng/pi-review 0.17.3 → 0.18.1

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.
@@ -0,0 +1,69 @@
1
+ import assert from "node:assert/strict";
2
+ import path from "node:path";
3
+ import { test } from "vitest";
4
+ import { buildReviewerArgs, adjudicatorArgs } from "./panel.js";
5
+ import { rulesEnabled, rulesExtensionArgs, rulesExtensionPath } from "./review.js";
6
+ // Pin the config path so the machine's real ~/.pi/pi-review/config.json cannot
7
+ // flip childExtensions on during argv assertions.
8
+ const PINNED_ENV = { PI_REVIEW_CONFIG: "/tmp/pi-review-test-no-such-dir/config.json" };
9
+ function parsedArgs(overrides = {}) {
10
+ return {
11
+ mode: "code",
12
+ provider: undefined,
13
+ model: undefined,
14
+ thinking: undefined,
15
+ tools: undefined,
16
+ skills: [],
17
+ ...overrides,
18
+ };
19
+ }
20
+ function reviewerArgs(env, overrides = {}) {
21
+ const config = { piBin: "pi" };
22
+ return buildReviewerArgs(config, parsedArgs(overrides), {}, "review this", [], {}, undefined, "", env);
23
+ }
24
+ test("rulesExtensionPath resolves the shipped rules extension beside the module", () => {
25
+ const resolved = rulesExtensionPath();
26
+ assert.ok(resolved, "expected a rules-extension file next to review.ts");
27
+ const base = path.basename(resolved);
28
+ assert.ok(base === "rules-extension.js" || base === "rules-extension.ts", `unexpected ${base}`);
29
+ });
30
+ test("rulesEnabled defaults on and only the documented values disable it", () => {
31
+ assert.equal(rulesEnabled({}, undefined), true);
32
+ assert.equal(rulesEnabled({ PI_REVIEW_RULES: "" }, undefined), true);
33
+ assert.equal(rulesEnabled({ PI_REVIEW_RULES: "1" }, undefined), true);
34
+ assert.equal(rulesEnabled({ PI_REVIEW_RULES: "on" }, undefined), true);
35
+ for (const value of ["0", "false", "off", "no", "FALSE", "Off"]) {
36
+ assert.equal(rulesEnabled({ PI_REVIEW_RULES: value }, undefined), false, value);
37
+ }
38
+ assert.equal(rulesEnabled({}, true), false);
39
+ });
40
+ test("rulesExtensionArgs emits an explicit --extension after isolation", () => {
41
+ const args = rulesExtensionArgs(PINNED_ENV);
42
+ assert.equal(args[0], "--extension");
43
+ assert.equal(path.basename(args[1]), "rules-extension.ts");
44
+ assert.deepEqual(rulesExtensionArgs({ ...PINNED_ENV, PI_REVIEW_RULES: "0" }), []);
45
+ assert.deepEqual(rulesExtensionArgs({ ...PINNED_ENV, PI_REVIEW_RULES: "off" }), []);
46
+ assert.deepEqual(rulesExtensionArgs(PINNED_ENV, true), []);
47
+ });
48
+ test("buildReviewerArgs loads rules explicitly while staying isolated", () => {
49
+ const args = reviewerArgs(PINNED_ENV);
50
+ assert.ok(args.includes("--no-extensions"), args.join(" "));
51
+ assert.ok(args.includes("--extension"), args.join(" "));
52
+ const extensionPath = args[args.indexOf("--extension") + 1];
53
+ const base = path.basename(extensionPath);
54
+ assert.ok(base === "rules-extension.js" || base === "rules-extension.ts", base);
55
+ assert.ok(args.indexOf("--no-extensions") < args.indexOf("--extension"));
56
+ assert.ok(args.indexOf("--extension") < args.indexOf("--no-session"));
57
+ });
58
+ test("buildReviewerArgs drops the rules extension on env or --no-rules opt-out", () => {
59
+ assert.ok(!reviewerArgs({ ...PINNED_ENV, PI_REVIEW_RULES: "0" }).includes("--extension"));
60
+ assert.ok(!reviewerArgs({ ...PINNED_ENV, PI_REVIEW_RULES: "false" }).includes("--extension"));
61
+ assert.ok(!reviewerArgs(PINNED_ENV, { noRules: true }).includes("--extension"));
62
+ });
63
+ test("adjudicator argv is isolated and never loads the rules extension", () => {
64
+ const args = adjudicatorArgs("openai/gpt-5", "system", "prompt", PINNED_ENV);
65
+ assert.ok(args.includes("--no-extensions"), args.join(" "));
66
+ assert.ok(args.includes("--no-tools"));
67
+ assert.ok(!args.some((arg) => arg.includes("rules-extension")), args.join(" "));
68
+ });
69
+ //# sourceMappingURL=rules-argv.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-argv.test.js","sourceRoot":"","sources":["../src/rules-argv.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ export default function claudeRules(pi: ExtensionAPI): void;
3
+ //# sourceMappingURL=rules-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-extension.d.ts","sourceRoot":"","sources":["../src/rules-extension.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AASpE,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAqD1D"}
@@ -0,0 +1,68 @@
1
+ // Pi extension loaded into pi-review child sessions via an explicit
2
+ // `--extension <path>` (runtime import of @earendil-works/pi-coding-agent is
3
+ // type-only; the loadable file itself imports nothing but this module).
4
+ //
5
+ // It makes the review child consume `.claude/rules/` with Claude Code
6
+ // semantics: unconditional rules append to the system prompt (deduped against
7
+ // Pi's built-in context files by realpath), and `paths`-scoped rules inject
8
+ // into the matching `read` tool result once per file per process. No UI, no
9
+ // commands, no tools, and no writes — discovery and injection only.
10
+ import fs from "node:fs";
11
+ import os from "node:os";
12
+ import path from "node:path";
13
+ import { discoverRules, renderMatchedReminder, renderUnconditionalBlock, ruleMatchesFile, } from "./rules.js";
14
+ export default function claudeRules(pi) {
15
+ let rules = [];
16
+ let discoveredCwd;
17
+ // Already injected path-scoped rules (cleared after compact so they can re-inject).
18
+ let injected = new Set();
19
+ const ensureRules = (cwd) => {
20
+ if (discoveredCwd === cwd)
21
+ return;
22
+ rules = discoverRules(cwd, os.homedir());
23
+ discoveredCwd = cwd;
24
+ injected = new Set();
25
+ };
26
+ pi.on("session_start", async (_event, ctx) => {
27
+ ensureRules(ctx.cwd);
28
+ });
29
+ pi.on("session_compact", async () => {
30
+ injected = new Set(); // compact may drop injected content; re-arm
31
+ });
32
+ pi.on("before_agent_start", async (event, ctx) => {
33
+ ensureRules(ctx.cwd);
34
+ // Dedupe unconditional rules against Pi's built-in context files
35
+ // (AGENTS.md / CLAUDE.md) by realpath so the same file is never injected twice.
36
+ const builtin = new Set();
37
+ for (const f of event.systemPromptOptions?.contextFiles ?? []) {
38
+ try {
39
+ builtin.add(fs.realpathSync(f.path));
40
+ }
41
+ catch {
42
+ // context file missing on disk — ignore
43
+ }
44
+ }
45
+ const unconditional = rules.filter((r) => r.patterns === null && !builtin.has(r.realPath));
46
+ if (unconditional.length === 0)
47
+ return;
48
+ return { systemPrompt: event.systemPrompt + renderUnconditionalBlock(unconditional) };
49
+ });
50
+ pi.on("tool_result", async (event, ctx) => {
51
+ if (event.toolName !== "read" || event.isError)
52
+ return;
53
+ const rawPath = (event.input?.file_path ?? event.input?.path);
54
+ if (!rawPath)
55
+ return;
56
+ ensureRules(ctx.cwd);
57
+ const absFile = path.resolve(ctx.cwd, rawPath);
58
+ const matched = rules.filter((r) => r.patterns !== null && !injected.has(r.realPath) && ruleMatchesFile(r, absFile));
59
+ if (matched.length === 0)
60
+ return;
61
+ for (const r of matched)
62
+ injected.add(r.realPath);
63
+ return {
64
+ content: [...event.content, { type: "text", text: renderMatchedReminder(matched) }],
65
+ };
66
+ });
67
+ }
68
+ //# sourceMappingURL=rules-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-extension.js","sourceRoot":"","sources":["../src/rules-extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export type RuleScope = "user" | "project";
2
+ /** A parsed rule file: `paths === null` means unconditional. */
3
+ export interface ParsedRule {
4
+ content: string;
5
+ /** null = no frontmatter or no `paths` key → unconditional rule. */
6
+ paths: string[] | null;
7
+ }
8
+ export interface Rule {
9
+ /** Path as discovered (symlinks kept for display). */
10
+ file: string;
11
+ /** realpath, used for dedupe. */
12
+ realPath: string;
13
+ scope: RuleScope;
14
+ /** Base directory the `paths` globs are matched against (project root / cwd). */
15
+ baseDir: string;
16
+ content: string;
17
+ rawPaths: string[] | null;
18
+ /** null = unconditional; [] = `paths` present but every glob invalid → matches nothing. */
19
+ patterns: RegExp[] | null;
20
+ }
21
+ /** Split on top-level commas, ignoring commas inside `{}` / `[]` (brace globs). */
22
+ export declare function splitTopLevelCommas(input: string): string[];
23
+ /** Expand `a.{ts,tsx}` → `["a.ts", "a.tsx"]`, nesting supported. */
24
+ export declare function expandBraces(pattern: string): string[];
25
+ /** glob → RegExp; an invalid pattern returns null (callers treat it as "matches nothing"). */
26
+ export declare function compileGlob(pattern: string): RegExp | null;
27
+ /** Parse the YAML frontmatter `paths` key; the frontmatter is stripped from content. */
28
+ export declare function parseRuleFile(src: string): ParsedRule;
29
+ /** Recursively find every `.md` under `dir` (symlinks followed, realpath cycle detection), lexicographic. */
30
+ export declare function findMarkdownFiles(dir: string, visitedDirs?: Set<string>): string[];
31
+ /** Discover all rules: user `~/.claude/rules/` first, project scopes (cwd upward, outermost first) after. */
32
+ export declare function discoverRules(cwd: string, home: string): Rule[];
33
+ /** Whether a file path hits a rule's `paths` (original and realpath both matched, v2.1.198). */
34
+ export declare function ruleMatchesFile(rule: Rule, absFile: string): boolean;
35
+ /** Unconditional rules appended to the system prompt, using the reference scope labels. */
36
+ export declare function renderUnconditionalBlock(rules: Rule[]): string;
37
+ /** The `<system-reminder>` block appended to a matching `read` tool result. */
38
+ export declare function renderMatchedReminder(rules: Rule[]): string;
39
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAE3C,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,IAAI;IACnB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1B,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC3B;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB3D;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAsCtD;AAgFD,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAe1D;AAUD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA+BrD;AAED,6GAA6G;AAC7G,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAgClF;AAyCD,6GAA6G;AAC7G,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CAiB/D;AAED,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAqBpE;AAOD,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAK9D;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAQ3D"}
package/dist/rules.js ADDED
@@ -0,0 +1,374 @@
1
+ // Adapted from @masonchow/pi-claude-rules (MIT, commit 38d341ebde12010722e69046c941b79cef2b4241).
2
+ //
3
+ // Pure Claude Code `.claude/rules` semantics shared by the review child
4
+ // extension. Nothing here touches the filesystem beyond reading rule files:
5
+ //
6
+ // - Discovery: user `~/.claude/rules/` + project `<dir>/.claude/rules/`, walking
7
+ // up from cwd (skipping home itself). Recursive `.md`, symlinked dirs/files
8
+ // followed, realpath cycle detection, realpath dedupe. User scope first;
9
+ // project scopes outermost-first, innermost last (innermost wins). Same level
10
+ // sorted lexicographically.
11
+ // - Rules without a `paths` frontmatter key are unconditional: they append to
12
+ // the system prompt on every agent start, deduped by realpath against Pi's
13
+ // built-in context files (AGENTS.md / CLAUDE.md).
14
+ // - Rules with `paths` inject into the `read` tool result only, once per
15
+ // realpath per process and re-armed after `session_compact`. `write`/`edit`
16
+ // never trigger.
17
+ // - Glob supports `**` `*` `?` `{a,b}` `[...]`; an invalid bracket expression
18
+ // matches nothing (v2.1.207). Symlink and realpath paths both match
19
+ // (v2.1.198).
20
+ import fs from "node:fs";
21
+ import path from "node:path";
22
+ /** Split on top-level commas, ignoring commas inside `{}` / `[]` (brace globs). */
23
+ export function splitTopLevelCommas(input) {
24
+ const out = [];
25
+ let depth = 0;
26
+ let cur = "";
27
+ for (let i = 0; i < input.length; i++) {
28
+ const ch = input[i];
29
+ if (ch === "\\" && i + 1 < input.length) {
30
+ cur += ch + input[i + 1];
31
+ i++;
32
+ continue;
33
+ }
34
+ if (ch === "{" || ch === "[")
35
+ depth++;
36
+ else if (ch === "}" || ch === "]")
37
+ depth = Math.max(0, depth - 1);
38
+ if (ch === "," && depth === 0) {
39
+ out.push(cur);
40
+ cur = "";
41
+ }
42
+ else {
43
+ cur += ch;
44
+ }
45
+ }
46
+ out.push(cur);
47
+ return out.map((s) => s.trim()).filter((s) => s.length > 0);
48
+ }
49
+ /** Expand `a.{ts,tsx}` → `["a.ts", "a.tsx"]`, nesting supported. */
50
+ export function expandBraces(pattern) {
51
+ let start = -1;
52
+ for (let i = 0; i < pattern.length; i++) {
53
+ const ch = pattern[i];
54
+ if (ch === "\\") {
55
+ i++;
56
+ continue;
57
+ }
58
+ if (ch === "{") {
59
+ start = i;
60
+ break;
61
+ }
62
+ }
63
+ if (start === -1)
64
+ return [pattern];
65
+ let depth = 0;
66
+ let end = -1;
67
+ for (let i = start; i < pattern.length; i++) {
68
+ const ch = pattern[i];
69
+ if (ch === "\\") {
70
+ i++;
71
+ continue;
72
+ }
73
+ if (ch === "{")
74
+ depth++;
75
+ else if (ch === "}") {
76
+ depth--;
77
+ if (depth === 0) {
78
+ end = i;
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ if (end === -1)
84
+ return [pattern]; // unclosed → treat literally
85
+ const prefix = pattern.slice(0, start);
86
+ const inner = pattern.slice(start + 1, end);
87
+ const suffix = pattern.slice(end + 1);
88
+ const alts = splitTopLevelCommas(inner);
89
+ if (alts.length === 0)
90
+ return [pattern];
91
+ return alts.flatMap((alt) => expandBraces(prefix + alt + suffix));
92
+ }
93
+ function escapeRegExp(ch) {
94
+ return /[.*+?^${}()|[\]\\]/.test(ch) ? `\\${ch}` : ch;
95
+ }
96
+ /** One (brace-expanded) glob → regex source; an invalid bracket expression returns null. */
97
+ function compileSingle(pattern) {
98
+ let out = "";
99
+ let i = 0;
100
+ while (i < pattern.length) {
101
+ const ch = pattern[i];
102
+ if (ch === "\\" && i + 1 < pattern.length) {
103
+ out += escapeRegExp(pattern[i + 1]);
104
+ i += 2;
105
+ continue;
106
+ }
107
+ if (ch === "*") {
108
+ if (pattern[i + 1] === "*") {
109
+ const prevOk = i === 0 || pattern[i - 1] === "/";
110
+ const next = pattern[i + 2];
111
+ if (prevOk && next === "/") {
112
+ out += "(?:[^/]+/)*"; // '**/' matches zero or more directory levels
113
+ i += 3;
114
+ continue;
115
+ }
116
+ if (prevOk && next === undefined) {
117
+ out += ".*"; // trailing '**' matches any depth
118
+ i += 2;
119
+ continue;
120
+ }
121
+ out += "[^/]*"; // '**' not on a segment boundary degrades to '*'
122
+ i += 2;
123
+ continue;
124
+ }
125
+ out += "[^/]*";
126
+ i++;
127
+ continue;
128
+ }
129
+ if (ch === "?") {
130
+ out += "[^/]";
131
+ i++;
132
+ continue;
133
+ }
134
+ if (ch === "[") {
135
+ // Bracket expression: find the closing ] (leading ! negates, a leading ]
136
+ // right after is a literal).
137
+ let j = i + 1;
138
+ let negate = false;
139
+ if (pattern[j] === "!" || pattern[j] === "^") {
140
+ negate = true;
141
+ j++;
142
+ }
143
+ let body = "";
144
+ if (pattern[j] === "]") {
145
+ body += "\\]";
146
+ j++;
147
+ }
148
+ while (j < pattern.length && pattern[j] !== "]") {
149
+ if (pattern[j] === "\\" && j + 1 < pattern.length) {
150
+ body += "\\" + pattern[j + 1];
151
+ j += 2;
152
+ continue;
153
+ }
154
+ body += pattern[j] === "^" ? "\\^" : pattern[j];
155
+ j++;
156
+ }
157
+ if (j >= pattern.length || body.length === 0) {
158
+ return null; // unparseable bracket expression → whole pattern matches nothing
159
+ }
160
+ out += `[${negate ? "^" : ""}${body}]`;
161
+ i = j + 1;
162
+ continue;
163
+ }
164
+ out += escapeRegExp(ch);
165
+ i++;
166
+ }
167
+ return out;
168
+ }
169
+ /** glob → RegExp; an invalid pattern returns null (callers treat it as "matches nothing"). */
170
+ export function compileGlob(pattern) {
171
+ let p = pattern.trim();
172
+ if (p.startsWith("./"))
173
+ p = p.slice(2);
174
+ if (p.length === 0)
175
+ return null;
176
+ const sources = [];
177
+ for (const expanded of expandBraces(p)) {
178
+ const src = compileSingle(expanded);
179
+ if (src === null)
180
+ return null;
181
+ sources.push(src);
182
+ }
183
+ try {
184
+ return new RegExp(`^(?:${sources.join("|")})$`);
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ }
190
+ function stripQuotes(s) {
191
+ const t = s.trim();
192
+ if (t.length >= 2 && ((t[0] === '"' && t.endsWith('"')) || (t[0] === "'" && t.endsWith("'")))) {
193
+ return t.slice(1, -1);
194
+ }
195
+ return t;
196
+ }
197
+ /** Parse the YAML frontmatter `paths` key; the frontmatter is stripped from content. */
198
+ export function parseRuleFile(src) {
199
+ if (!/^---[ \t]*\r?\n/.test(src))
200
+ return { content: src, paths: null };
201
+ const closing = /\r?\n---[ \t]*(?:\r?\n|$)/.exec(src.slice(3));
202
+ if (!closing)
203
+ return { content: src, paths: null }; // unclosed → treat as no frontmatter
204
+ const fmEnd = 3 + closing.index;
205
+ const frontmatter = src.slice(3, fmEnd);
206
+ const body = src.slice(fmEnd + closing[0].length).replace(/^\r?\n/, "");
207
+ const lines = frontmatter.split(/\r?\n/);
208
+ let paths = null;
209
+ for (let i = 0; i < lines.length; i++) {
210
+ const m = /^paths:\s*(.*)$/.exec(lines[i]);
211
+ if (!m)
212
+ continue;
213
+ const value = m[1].trim();
214
+ if (value.length > 0) {
215
+ // Inline form: paths: "a, b" / paths: [a, b] / paths: a, b
216
+ let v = stripQuotes(value);
217
+ if (v.startsWith("[") && v.endsWith("]"))
218
+ v = v.slice(1, -1);
219
+ paths = splitTopLevelCommas(v).map(stripQuotes).filter((s) => s.length > 0);
220
+ }
221
+ else {
222
+ // Block list form: paths: then "- item" lines
223
+ const items = [];
224
+ for (let j = i + 1; j < lines.length; j++) {
225
+ const item = /^\s+-\s+(.+)$/.exec(lines[j]);
226
+ if (!item)
227
+ break;
228
+ items.push(stripQuotes(item[1]));
229
+ }
230
+ paths = items;
231
+ }
232
+ break;
233
+ }
234
+ return { content: body, paths };
235
+ }
236
+ /** Recursively find every `.md` under `dir` (symlinks followed, realpath cycle detection), lexicographic. */
237
+ export function findMarkdownFiles(dir, visitedDirs) {
238
+ const visited = visitedDirs ?? new Set();
239
+ let realDir;
240
+ try {
241
+ realDir = fs.realpathSync(dir);
242
+ }
243
+ catch {
244
+ return [];
245
+ }
246
+ if (visited.has(realDir))
247
+ return [];
248
+ visited.add(realDir);
249
+ let entries;
250
+ try {
251
+ entries = fs.readdirSync(dir, { withFileTypes: true });
252
+ }
253
+ catch {
254
+ return [];
255
+ }
256
+ const results = [];
257
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
258
+ const full = path.join(dir, entry.name);
259
+ let stat;
260
+ try {
261
+ stat = fs.statSync(full); // statSync follows symlinks
262
+ }
263
+ catch {
264
+ continue; // dangling symlink etc.
265
+ }
266
+ if (stat.isDirectory()) {
267
+ results.push(...findMarkdownFiles(full, visited));
268
+ }
269
+ else if (stat.isFile() && entry.name.endsWith(".md")) {
270
+ results.push(full);
271
+ }
272
+ }
273
+ return results;
274
+ }
275
+ function collectDir(rulesDir, scope, baseDir, seenReal) {
276
+ const rules = [];
277
+ for (const file of findMarkdownFiles(rulesDir)) {
278
+ let realPath;
279
+ try {
280
+ realPath = fs.realpathSync(file);
281
+ }
282
+ catch {
283
+ continue;
284
+ }
285
+ if (seenReal.has(realPath))
286
+ continue;
287
+ seenReal.add(realPath);
288
+ let src;
289
+ try {
290
+ src = fs.readFileSync(file, "utf8");
291
+ }
292
+ catch {
293
+ continue;
294
+ }
295
+ const parsed = parseRuleFile(src);
296
+ rules.push({
297
+ file,
298
+ realPath,
299
+ scope,
300
+ baseDir,
301
+ content: parsed.content,
302
+ rawPaths: parsed.paths,
303
+ patterns: parsed.paths === null
304
+ ? null
305
+ : parsed.paths.map(compileGlob).filter((r) => r !== null),
306
+ });
307
+ }
308
+ return rules;
309
+ }
310
+ /** Discover all rules: user `~/.claude/rules/` first, project scopes (cwd upward, outermost first) after. */
311
+ export function discoverRules(cwd, home) {
312
+ const seenReal = new Set();
313
+ const rules = [];
314
+ rules.push(...collectDir(path.join(home, ".claude", "rules"), "user", cwd, seenReal));
315
+ const ancestors = [];
316
+ let dir = path.resolve(cwd);
317
+ while (true) {
318
+ if (dir !== home)
319
+ ancestors.push(dir);
320
+ const parent = path.dirname(dir);
321
+ if (parent === dir)
322
+ break;
323
+ dir = parent;
324
+ }
325
+ ancestors.reverse(); // outermost project first, innermost (more specific) last, so it wins
326
+ for (const d of ancestors) {
327
+ rules.push(...collectDir(path.join(d, ".claude", "rules"), "project", d, seenReal));
328
+ }
329
+ return rules;
330
+ }
331
+ /** Whether a file path hits a rule's `paths` (original and realpath both matched, v2.1.198). */
332
+ export function ruleMatchesFile(rule, absFile) {
333
+ if (rule.patterns === null || rule.patterns.length === 0)
334
+ return false;
335
+ const candidates = new Set();
336
+ const rel = path.relative(rule.baseDir, absFile);
337
+ if (!rel.startsWith("..") && !path.isAbsolute(rel))
338
+ candidates.add(rel.split(path.sep).join("/"));
339
+ try {
340
+ const realFile = fs.realpathSync(absFile);
341
+ const realBase = fs.realpathSync(rule.baseDir);
342
+ const relReal = path.relative(realBase, realFile);
343
+ if (!relReal.startsWith("..") && !path.isAbsolute(relReal)) {
344
+ candidates.add(relReal.split(path.sep).join("/"));
345
+ }
346
+ }
347
+ catch {
348
+ // No realpath for file or base → match on the original path only.
349
+ }
350
+ for (const candidate of candidates) {
351
+ for (const re of rule.patterns) {
352
+ if (re.test(candidate))
353
+ return true;
354
+ }
355
+ }
356
+ return false;
357
+ }
358
+ const SCOPE_LABEL = {
359
+ user: "(user's private global instructions for all projects)",
360
+ project: "(project instructions, checked into the codebase)",
361
+ };
362
+ /** Unconditional rules appended to the system prompt, using the reference scope labels. */
363
+ export function renderUnconditionalBlock(rules) {
364
+ const sections = rules.map((r) => `Contents of ${r.file} ${SCOPE_LABEL[r.scope]}:\n\n${r.content.trim()}`);
365
+ return `\n\n# Rules\n\nThe following rules from .claude/rules directories apply to this session. Adhere to them.\n\n${sections.join("\n\n")}`;
366
+ }
367
+ /** The `<system-reminder>` block appended to a matching `read` tool result. */
368
+ export function renderMatchedReminder(rules) {
369
+ const reminder = rules
370
+ .map((r) => `Contents of ${r.file} ${SCOPE_LABEL[r.scope]} — applies to the file you just read:\n\n${r.content.trim()}`)
371
+ .join("\n\n");
372
+ return `\n<system-reminder>\n${reminder}\n</system-reminder>`;
373
+ }
374
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rules.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.test.d.ts","sourceRoot":"","sources":["../src/rules.test.ts"],"names":[],"mappings":""}