forked from earendil-works/pi
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathclaude-rules.ts
More file actions
86 lines (69 loc) · 2.43 KB
/
Copy pathclaude-rules.ts
File metadata and controls
86 lines (69 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* Claude Rules Extension
*
* Scans the project's .claude/rules/ folder for rule files and lists them
* in the system prompt. The agent can then use the read tool to load
* specific rules when needed.
*
* Best practices for .claude/rules/:
* - Keep rules focused: Each file should cover one topic (e.g., testing.md, api-design.md)
* - Use descriptive filenames: The filename should indicate what the rules cover
* - Use conditional rules sparingly: Only add paths frontmatter when rules truly apply to specific file types
* - Organize with subdirectories: Group related rules (e.g., frontend/, backend/)
*
* Usage:
* 1. Copy this file to ~/.pi/agent/extensions/ or your project's .pi/extensions/
* 2. Create .claude/rules/ folder in your project root
* 3. Add .md files with your rules
*/
import * as fs from "node:fs";
import * as path from "node:path";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
/**
* Recursively find all .md files in a directory
*/
function findMarkdownFiles(dir: string, basePath: string = ""): string[] {
const results: string[] = [];
if (!fs.existsSync(dir)) {
return results;
}
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
if (entry.isDirectory()) {
results.push(...findMarkdownFiles(path.join(dir, entry.name), relativePath));
} else if (entry.isFile() && entry.name.endsWith(".md")) {
results.push(relativePath);
}
}
return results;
}
export default function claudeRulesExtension(pi: ExtensionAPI) {
let ruleFiles: string[] = [];
let rulesDir: string = "";
// Scan for rules on session start
pi.on("session_start", async (_event, ctx) => {
rulesDir = path.join(ctx.cwd, ".claude", "rules");
ruleFiles = findMarkdownFiles(rulesDir);
if (ruleFiles.length > 0) {
ctx.ui.notify(`Found ${ruleFiles.length} rule(s) in .claude/rules/`, "info");
}
});
// Append available rules to system prompt
pi.on("before_agent_start", async (event) => {
if (ruleFiles.length === 0) {
return;
}
const rulesList = ruleFiles.map((f) => `- .claude/rules/${f}`).join("\n");
return {
systemPrompt:
event.systemPrompt +
`
## Project Rules
The following project rules are available in .claude/rules/:
${rulesList}
When working on tasks related to these rules, use the read tool to load the relevant rule files for guidance.
`,
};
});
}