agents-templated 2.0.0 → 2.2.0
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/bin/cli.js +141 -65
- package/index.js +2 -3
- package/lib/instructions.js +163 -129
- package/lib/layout.js +9 -1
- package/package.json +1 -1
- package/templates/AGENTS.md +3 -7
- package/templates/CLAUDE.md +150 -7
- package/templates/agents/rules/ai-integration.mdc +54 -0
- package/templates/agents/rules/guardrails.mdc +97 -0
- package/templates/agents/rules/intent-routing.mdc +9 -0
- package/templates/agents/rules/planning.mdc +69 -0
- package/templates/agents/skills/api-design/SKILL.md +59 -0
- package/templates/agents/skills/llm-integration/SKILL.md +64 -0
- package/templates/agents/subagents/README.md +76 -0
- package/templates/agents/subagents/architect.md +106 -0
- package/templates/agents/subagents/build-error-resolver.md +119 -0
- package/templates/agents/subagents/code-reviewer.md +116 -0
- package/templates/agents/subagents/doc-updater.md +130 -0
- package/templates/agents/subagents/e2e-runner.md +122 -0
- package/templates/agents/subagents/planner.md +87 -0
- package/templates/agents/subagents/refactor-cleaner.md +137 -0
- package/templates/agents/subagents/security-reviewer.md +138 -0
- package/templates/agents/subagents/tdd-guide.md +98 -0
package/lib/instructions.js
CHANGED
|
@@ -1,175 +1,209 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const GENERATED_INSTRUCTION_PATHS = {
|
|
7
|
-
canonical: {
|
|
8
|
-
generic: '.github/instructions/AGENTS.md'
|
|
9
|
-
},
|
|
10
|
-
compatibility: {
|
|
11
|
-
generic: 'AGENTS.MD',
|
|
12
|
-
copilot: '.github/copilot-instructions.md',
|
|
13
|
-
claude: 'CLAUDE.md',
|
|
14
|
-
cursor: '.cursorrules'
|
|
15
|
-
}
|
|
16
|
-
};
|
|
4
|
+
// CLAUDE.md is the single source of truth. Edit it directly — no generation needed.
|
|
5
|
+
const CANONICAL_INSTRUCTION_FILE = 'CLAUDE.md';
|
|
17
6
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'.github/instructions
|
|
22
|
-
|
|
23
|
-
'.github/instructions/agents.instructions.md',
|
|
24
|
-
'.github/instructions/copilot-instructions.md',
|
|
25
|
-
'.claude/rules/claude.instructions.md',
|
|
26
|
-
'GEMINI.md'
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
function getLegacyCoreCandidates() {
|
|
30
|
-
return ['AGENTS.MD', 'AGENTS.md'];
|
|
31
|
-
}
|
|
7
|
+
// Thin compatibility pointer files — policy lives in CLAUDE.md, not here.
|
|
8
|
+
const POINTER_FILES = {
|
|
9
|
+
agents: 'AGENTS.MD',
|
|
10
|
+
copilot: '.github/copilot-instructions.md'
|
|
11
|
+
};
|
|
32
12
|
|
|
33
|
-
function
|
|
13
|
+
function buildAgentsPointer() {
|
|
34
14
|
return [
|
|
35
|
-
'
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
''
|
|
15
|
+
'# AGENTS Instructions',
|
|
16
|
+
'',
|
|
17
|
+
'> Primary policy: [`CLAUDE.md`](CLAUDE.md).',
|
|
18
|
+
'> This file is a compatibility pointer. All policy lives in CLAUDE.md.',
|
|
19
|
+
'> If this file and CLAUDE.md conflict, CLAUDE.md wins.'
|
|
39
20
|
].join('\n');
|
|
40
21
|
}
|
|
41
22
|
|
|
42
|
-
function
|
|
43
|
-
const titles = {
|
|
44
|
-
generic: '# AGENTS Instructions',
|
|
45
|
-
copilot: '# GitHub Copilot Instructions',
|
|
46
|
-
claude: '# Claude Instructions',
|
|
47
|
-
cursor: '# Cursor Rules'
|
|
48
|
-
};
|
|
49
|
-
|
|
23
|
+
function buildCopilotPointer() {
|
|
50
24
|
return [
|
|
51
|
-
|
|
25
|
+
'<!-- Tool profile: copilot-compat -->',
|
|
26
|
+
'# GitHub Copilot Instructions',
|
|
52
27
|
'',
|
|
53
|
-
|
|
28
|
+
'Primary policy source: `CLAUDE.md`.',
|
|
54
29
|
'Load policy only from the canonical source file above.',
|
|
55
|
-
'
|
|
56
|
-
'If this file and the canonical source conflict, the canonical source wins.',
|
|
57
|
-
''
|
|
30
|
+
'If this file and CLAUDE.md conflict, CLAUDE.md wins.'
|
|
58
31
|
].join('\n');
|
|
59
32
|
}
|
|
60
33
|
|
|
61
|
-
function
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
files[GENERATED_INSTRUCTION_PATHS.compatibility.copilot] = `${buildHeaders('copilot-compat')}${buildCompatInstruction('copilot', corePath)}`;
|
|
68
|
-
files[GENERATED_INSTRUCTION_PATHS.compatibility.claude] = `${buildHeaders('claude-compat')}${buildCompatInstruction('claude', corePath)}`;
|
|
69
|
-
files[GENERATED_INSTRUCTION_PATHS.compatibility.cursor] = `${buildHeaders('cursor-compat')}${buildCompatInstruction('cursor', corePath)}`;
|
|
70
|
-
|
|
71
|
-
return files;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function resolveCoreContent(targetDir, templateDir) {
|
|
75
|
-
const canonicalPath = path.join(targetDir, CORE_SOURCE_REL_PATH);
|
|
76
|
-
if (await fs.pathExists(canonicalPath)) {
|
|
77
|
-
return fs.readFile(canonicalPath, 'utf8');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
for (const legacyFile of getLegacyCoreCandidates()) {
|
|
81
|
-
const legacyPath = path.join(targetDir, legacyFile);
|
|
82
|
-
if (await fs.pathExists(legacyPath)) {
|
|
83
|
-
const legacyContent = await fs.readFile(legacyPath, 'utf8');
|
|
84
|
-
const isWrapper =
|
|
85
|
-
legacyContent.includes(`Source of truth: ${CORE_SOURCE_REL_PATH}`) ||
|
|
86
|
-
legacyContent.includes('Primary policy source: `instructions/source/core.md`.');
|
|
87
|
-
|
|
88
|
-
if (!isWrapper) {
|
|
89
|
-
return legacyContent;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const templateCorePath = path.join(templateDir, CORE_SOURCE_REL_PATH);
|
|
95
|
-
return fs.readFile(templateCorePath, 'utf8');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async function ensureCoreSource(targetDir, templateDir, force = false) {
|
|
99
|
-
const targetCorePath = path.join(targetDir, CORE_SOURCE_REL_PATH);
|
|
100
|
-
|
|
101
|
-
if (await fs.pathExists(targetCorePath) && !force) {
|
|
102
|
-
return;
|
|
34
|
+
async function writeGeneratedInstructions(targetDir, templateDir, force = false) {
|
|
35
|
+
// Copy CLAUDE.md from template if not present (or forced)
|
|
36
|
+
const targetClaude = path.join(targetDir, CANONICAL_INSTRUCTION_FILE);
|
|
37
|
+
if (!(await fs.pathExists(targetClaude)) || force) {
|
|
38
|
+
const templateClaude = path.join(templateDir, CANONICAL_INSTRUCTION_FILE);
|
|
39
|
+
await fs.copy(templateClaude, targetClaude);
|
|
103
40
|
}
|
|
104
41
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
async function writeGeneratedInstructions(targetDir, templateDir, force = false) {
|
|
111
|
-
await ensureCoreSource(targetDir, templateDir, force);
|
|
112
|
-
const artifacts = buildGeneratedArtifacts();
|
|
42
|
+
// Write thin pointer files
|
|
43
|
+
const pointers = {
|
|
44
|
+
[POINTER_FILES.agents]: buildAgentsPointer(),
|
|
45
|
+
[POINTER_FILES.copilot]: buildCopilotPointer()
|
|
46
|
+
};
|
|
113
47
|
|
|
114
|
-
for (const [relPath, content] of Object.entries(
|
|
48
|
+
for (const [relPath, content] of Object.entries(pointers)) {
|
|
115
49
|
const targetPath = path.join(targetDir, relPath);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
50
|
+
if (!(await fs.pathExists(targetPath)) || force) {
|
|
51
|
+
await fs.ensureDir(path.dirname(targetPath));
|
|
52
|
+
await fs.writeFile(targetPath, content, 'utf8');
|
|
119
53
|
}
|
|
120
|
-
|
|
121
|
-
await fs.ensureDir(path.dirname(targetPath));
|
|
122
|
-
await fs.writeFile(targetPath, content, 'utf8');
|
|
123
54
|
}
|
|
124
55
|
}
|
|
125
56
|
|
|
126
57
|
async function validateInstructionDrift(targetDir) {
|
|
127
|
-
const
|
|
128
|
-
if (!(await fs.pathExists(
|
|
129
|
-
return {
|
|
130
|
-
ok: false,
|
|
131
|
-
missingCore: true,
|
|
132
|
-
driftFiles: [],
|
|
133
|
-
orphanedPolicyFiles: []
|
|
134
|
-
};
|
|
58
|
+
const claudePath = path.join(targetDir, CANONICAL_INSTRUCTION_FILE);
|
|
59
|
+
if (!(await fs.pathExists(claudePath))) {
|
|
60
|
+
return { ok: false, missingCanonical: true, driftFiles: [] };
|
|
135
61
|
}
|
|
136
62
|
|
|
137
|
-
const expected = buildGeneratedArtifacts();
|
|
138
63
|
const driftFiles = [];
|
|
64
|
+
const expectedPointers = {
|
|
65
|
+
[POINTER_FILES.agents]: buildAgentsPointer(),
|
|
66
|
+
[POINTER_FILES.copilot]: buildCopilotPointer()
|
|
67
|
+
};
|
|
139
68
|
|
|
140
|
-
for (const [relPath, expectedContent] of Object.entries(
|
|
69
|
+
for (const [relPath, expectedContent] of Object.entries(expectedPointers)) {
|
|
141
70
|
const filePath = path.join(targetDir, relPath);
|
|
142
71
|
if (!(await fs.pathExists(filePath))) {
|
|
143
72
|
driftFiles.push(relPath);
|
|
144
73
|
continue;
|
|
145
74
|
}
|
|
146
|
-
|
|
147
75
|
const actual = await fs.readFile(filePath, 'utf8');
|
|
148
76
|
if (actual !== expectedContent) {
|
|
149
77
|
driftFiles.push(relPath);
|
|
150
78
|
}
|
|
151
79
|
}
|
|
152
80
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
81
|
+
return { ok: driftFiles.length === 0, missingCanonical: false, driftFiles };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function scaffoldSkill(targetDir, skillName) {
|
|
85
|
+
const skillDir = path.join(targetDir, 'agents', 'skills', skillName);
|
|
86
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
87
|
+
|
|
88
|
+
if (await fs.pathExists(skillFile)) {
|
|
89
|
+
throw new Error(`Skill already exists: agents/skills/${skillName}/SKILL.md`);
|
|
159
90
|
}
|
|
160
91
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
92
|
+
const title = skillName.split('-').map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
|
|
93
|
+
const content = [
|
|
94
|
+
`---`,
|
|
95
|
+
`name: ${skillName}`,
|
|
96
|
+
`description: TODO — describe what this skill does.`,
|
|
97
|
+
`---`,
|
|
98
|
+
``,
|
|
99
|
+
`# ${title}`,
|
|
100
|
+
``,
|
|
101
|
+
`## Trigger Conditions`,
|
|
102
|
+
``,
|
|
103
|
+
`- TODO — when should this skill activate?`,
|
|
104
|
+
``,
|
|
105
|
+
`## Workflow`,
|
|
106
|
+
``,
|
|
107
|
+
`1. TODO`,
|
|
108
|
+
``,
|
|
109
|
+
`## Output Contract`,
|
|
110
|
+
``,
|
|
111
|
+
`- TODO`,
|
|
112
|
+
``,
|
|
113
|
+
`## Guardrails`,
|
|
114
|
+
``,
|
|
115
|
+
`- Do not override security or testing constraints.`,
|
|
116
|
+
``
|
|
117
|
+
].join('\n');
|
|
118
|
+
|
|
119
|
+
await fs.ensureDir(skillDir);
|
|
120
|
+
await fs.writeFile(skillFile, content, 'utf8');
|
|
121
|
+
return `agents/skills/${skillName}/SKILL.md`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function scaffoldRule(targetDir, ruleName) {
|
|
125
|
+
const rulesDir = path.join(targetDir, 'agents', 'rules');
|
|
126
|
+
const ruleFile = path.join(rulesDir, `${ruleName}.mdc`);
|
|
127
|
+
|
|
128
|
+
if (await fs.pathExists(ruleFile)) {
|
|
129
|
+
throw new Error(`Rule already exists: agents/rules/${ruleName}.mdc`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const content = [
|
|
133
|
+
`---`,
|
|
134
|
+
`title: "TODO — Rule Title"`,
|
|
135
|
+
`description: "TODO — describe what this rule enforces."`,
|
|
136
|
+
`version: "1.0.0"`,
|
|
137
|
+
`tags: ["${ruleName}"]`,
|
|
138
|
+
`alwaysApply: false`,
|
|
139
|
+
`---`,
|
|
140
|
+
``,
|
|
141
|
+
`## Purpose`,
|
|
142
|
+
``,
|
|
143
|
+
`TODO — explain the purpose of this rule.`,
|
|
144
|
+
``,
|
|
145
|
+
`## Requirements`,
|
|
146
|
+
``,
|
|
147
|
+
`1. TODO`,
|
|
148
|
+
``,
|
|
149
|
+
`## Guardrails`,
|
|
150
|
+
``,
|
|
151
|
+
`- This rule does not override security or testing constraints.`,
|
|
152
|
+
``
|
|
153
|
+
].join('\n');
|
|
154
|
+
|
|
155
|
+
await fs.ensureDir(rulesDir);
|
|
156
|
+
await fs.writeFile(ruleFile, content, 'utf8');
|
|
157
|
+
return `agents/rules/${ruleName}.mdc`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function scaffoldSubagent(targetDir, name) {
|
|
161
|
+
const subagentFile = path.join(targetDir, 'agents', 'subagents', `${name}.md`);
|
|
162
|
+
|
|
163
|
+
if (await fs.pathExists(subagentFile)) {
|
|
164
|
+
throw new Error(`Subagent already exists: agents/subagents/${name}.md`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const title = name.split('-').map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
|
|
168
|
+
const content = [
|
|
169
|
+
`---`,
|
|
170
|
+
`name: ${name}`,
|
|
171
|
+
`description: TODO — describe when this subagent should activate.`,
|
|
172
|
+
`tools: ["Read", "Grep", "Glob"]`,
|
|
173
|
+
`model: claude-sonnet-4-5`,
|
|
174
|
+
`---`,
|
|
175
|
+
``,
|
|
176
|
+
`# ${title}`,
|
|
177
|
+
``,
|
|
178
|
+
`## Activation Conditions`,
|
|
179
|
+
``,
|
|
180
|
+
`- TODO — when should this subagent activate?`,
|
|
181
|
+
``,
|
|
182
|
+
`## Workflow`,
|
|
183
|
+
``,
|
|
184
|
+
`1. TODO`,
|
|
185
|
+
``,
|
|
186
|
+
`## Output Format`,
|
|
187
|
+
``,
|
|
188
|
+
`- TODO`,
|
|
189
|
+
``,
|
|
190
|
+
`## Guardrails`,
|
|
191
|
+
``,
|
|
192
|
+
`- Do not override security or testing constraints.`,
|
|
193
|
+
``
|
|
194
|
+
].join('\n');
|
|
195
|
+
|
|
196
|
+
await fs.ensureDir(path.dirname(subagentFile));
|
|
197
|
+
await fs.writeFile(subagentFile, content, 'utf8');
|
|
198
|
+
return `agents/subagents/${name}.md`;
|
|
167
199
|
}
|
|
168
200
|
|
|
169
201
|
module.exports = {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
KNOWN_ORPHAN_PATHS,
|
|
202
|
+
CANONICAL_INSTRUCTION_FILE,
|
|
203
|
+
POINTER_FILES,
|
|
173
204
|
writeGeneratedInstructions,
|
|
174
|
-
validateInstructionDrift
|
|
205
|
+
validateInstructionDrift,
|
|
206
|
+
scaffoldSkill,
|
|
207
|
+
scaffoldRule,
|
|
208
|
+
scaffoldSubagent
|
|
175
209
|
};
|
package/lib/layout.js
CHANGED
|
@@ -5,7 +5,8 @@ const LAYOUT = {
|
|
|
5
5
|
canonical: {
|
|
6
6
|
docsDir: 'agent-docs',
|
|
7
7
|
rulesDir: '.github/instructions/rules',
|
|
8
|
-
skillsDir: '.github/skills'
|
|
8
|
+
skillsDir: '.github/skills',
|
|
9
|
+
subagentsDir: 'agents/subagents'
|
|
9
10
|
},
|
|
10
11
|
legacy: {
|
|
11
12
|
rulesDirs: ['agents/rules'],
|
|
@@ -39,10 +40,16 @@ function resolveSkillsDir(baseDir) {
|
|
|
39
40
|
return firstExistingPath(baseDir, candidates) || LAYOUT.canonical.skillsDir;
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
function resolveSubagentsDir(baseDir) {
|
|
44
|
+
const candidates = [LAYOUT.canonical.subagentsDir];
|
|
45
|
+
return firstExistingPath(baseDir, candidates) || LAYOUT.canonical.subagentsDir;
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
async function hasAnyLayout(baseDir) {
|
|
43
49
|
const checks = [
|
|
44
50
|
path.join(baseDir, LAYOUT.canonical.rulesDir),
|
|
45
51
|
path.join(baseDir, LAYOUT.canonical.skillsDir),
|
|
52
|
+
path.join(baseDir, LAYOUT.canonical.subagentsDir),
|
|
46
53
|
...LAYOUT.compatible.rulesDirs.map((relPath) => path.join(baseDir, relPath)),
|
|
47
54
|
...LAYOUT.compatible.skillsDirs.map((relPath) => path.join(baseDir, relPath)),
|
|
48
55
|
...LAYOUT.legacy.rulesDirs.map((relPath) => path.join(baseDir, relPath)),
|
|
@@ -90,6 +97,7 @@ module.exports = {
|
|
|
90
97
|
LAYOUT,
|
|
91
98
|
resolveRulesDir,
|
|
92
99
|
resolveSkillsDir,
|
|
100
|
+
resolveSubagentsDir,
|
|
93
101
|
hasAnyLayout,
|
|
94
102
|
getLegacyMigrationPlan
|
|
95
103
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agents-templated",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Technology-agnostic development template with multi-AI agent support (Cursor, Copilot, VSCode, Gemini), security-first patterns, and comprehensive testing guidelines",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/templates/AGENTS.md
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
<!-- GENERATED FILE - DO NOT EDIT DIRECTLY -->
|
|
2
|
-
<!-- Source of truth: instructions/source/core.md -->
|
|
3
|
-
<!-- Tool profile: generic-compat -->
|
|
4
1
|
# AGENTS Instructions
|
|
5
2
|
|
|
6
|
-
Primary policy
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
If this file and the canonical source conflict, the canonical source wins.
|
|
3
|
+
> Primary policy: [`CLAUDE.md`](CLAUDE.md).
|
|
4
|
+
> This file is a compatibility pointer. All policy lives in CLAUDE.md.
|
|
5
|
+
> If this file and CLAUDE.md conflict, CLAUDE.md wins.
|
package/templates/CLAUDE.md
CHANGED
|
@@ -1,9 +1,152 @@
|
|
|
1
|
-
<!-- GENERATED FILE - DO NOT EDIT DIRECTLY -->
|
|
2
|
-
<!-- Source of truth: instructions/source/core.md -->
|
|
3
|
-
<!-- Tool profile: claude-compat -->
|
|
4
1
|
# Claude Instructions
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
This is the single source of truth for AI development policy in this repository.
|
|
4
|
+
All policy, routing, and skill governance lives here — edit this file directly.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Reference Index
|
|
9
|
+
|
|
10
|
+
### Rule modules (`.github/instructions/rules/`)
|
|
11
|
+
|
|
12
|
+
| Module | File | Governs |
|
|
13
|
+
|--------|------|---------|
|
|
14
|
+
| Security | `.github/instructions/rules/security.mdc` | Validation, authn/authz, secrets, rate limiting |
|
|
15
|
+
| Testing | `.github/instructions/rules/testing.mdc` | Strategy, coverage mix, test discipline |
|
|
16
|
+
| Core | `.github/instructions/rules/core.mdc` | Type safety, runtime boundaries, error modeling |
|
|
17
|
+
| Database | `.github/instructions/rules/database.mdc` | ORM patterns, migrations, query safety |
|
|
18
|
+
| Frontend | `.github/instructions/rules/frontend.mdc` | Accessibility, responsiveness, client trust boundaries |
|
|
19
|
+
| Style | `.github/instructions/rules/style.mdc` | Naming, modularity, separation of concerns |
|
|
20
|
+
| System Workflow | `.github/instructions/rules/system-workflow.mdc` | Branching, PR structure, review gates |
|
|
21
|
+
| Workflows | `.github/instructions/rules/workflows.mdc` | Automation, CI/CD, deployment gates |
|
|
22
|
+
| Hardening | `.github/instructions/rules/hardening.mdc` | Threat modeling, audit mode, dependency review |
|
|
23
|
+
| Intent Routing | `.github/instructions/rules/intent-routing.mdc` | Deterministic task-to-rule mapping |
|
|
24
|
+
| Planning | `.github/instructions/rules/planning.mdc` | Feature discussion and implementation planning |
|
|
25
|
+
| AI Integration | `.github/instructions/rules/ai-integration.mdc` | LLM safety, cost controls, fallback behavior |
|
|
26
|
+
| Guardrails | `.github/instructions/rules/guardrails.mdc` | Hard stops, scope control, reversibility, minimal footprint |
|
|
27
|
+
|
|
28
|
+
### Skill modules (`.github/skills/`)
|
|
29
|
+
|
|
30
|
+
| Skill | Path | Activate when... |
|
|
31
|
+
|-------|------|------------------|
|
|
32
|
+
| app-hardening | `.github/skills/app-hardening/SKILL.md` | Hardening, anti-tamper, integrity controls |
|
|
33
|
+
| bug-triage | `.github/skills/bug-triage/SKILL.md` | Something is broken, failing, or crashing |
|
|
34
|
+
| feature-delivery | `.github/skills/feature-delivery/SKILL.md` | Build/add/implement feature work |
|
|
35
|
+
| find-skills | `.github/skills/find-skills/SKILL.md` | User asks to discover a skill |
|
|
36
|
+
| ui-ux-pro-max | `.github/skills/ui-ux-pro-max/SKILL.md` | UI, layout, design, visual work |
|
|
37
|
+
| api-design | `.github/skills/api-design/SKILL.md` | REST/GraphQL API design, OpenAPI specs, versioning |
|
|
38
|
+
| llm-integration | `.github/skills/llm-integration/SKILL.md` | LLM integrations, RAG, prompt engineering, evaluation |
|
|
39
|
+
|
|
40
|
+
Skills add capability only. They must not override security, testing, or core constraints.
|
|
41
|
+
|
|
42
|
+
### Subagent modules (`agents/subagents/`)
|
|
43
|
+
|
|
44
|
+
| Subagent | Path | Invoke when... |
|
|
45
|
+
|----------|------|----------------|
|
|
46
|
+
| planner | `agents/subagents/planner.md` | Breaking down features into phased plans |
|
|
47
|
+
| architect | `agents/subagents/architect.md` | System design decisions, ADRs, trade-off analysis |
|
|
48
|
+
| tdd-guide | `agents/subagents/tdd-guide.md` | Writing tests before implementation |
|
|
49
|
+
| code-reviewer | `agents/subagents/code-reviewer.md` | Reviewing code for quality and correctness |
|
|
50
|
+
| security-reviewer | `agents/subagents/security-reviewer.md` | Scanning for security vulnerabilities |
|
|
51
|
+
| build-error-resolver | `agents/subagents/build-error-resolver.md` | Fixing build and type errors |
|
|
52
|
+
| e2e-runner | `agents/subagents/e2e-runner.md` | Running Playwright E2E test suites |
|
|
53
|
+
| refactor-cleaner | `agents/subagents/refactor-cleaner.md` | Removing dead code and unused dependencies |
|
|
54
|
+
| doc-updater | `agents/subagents/doc-updater.md` | Syncing docs and READMEs after code changes |
|
|
55
|
+
|
|
56
|
+
Subagents are bounded agents with limited tool access. They inherit all policy from this file and may not override security, testing, or core constraints.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Always Enforce
|
|
61
|
+
|
|
62
|
+
1. **Security-first (non-overrideable)** — `.github/instructions/rules/security.mdc`
|
|
63
|
+
- Validate all external inputs at boundaries.
|
|
64
|
+
- Require authentication and role-based authorization for protected operations.
|
|
65
|
+
- Rate-limit public APIs.
|
|
66
|
+
- Never expose secrets, credentials, or PII in logs/errors/responses.
|
|
67
|
+
|
|
68
|
+
2. **Testing discipline (non-overrideable)** — `.github/instructions/rules/testing.mdc`
|
|
69
|
+
- Coverage mix target: Unit 80% / Integration 15% / E2E 5%.
|
|
70
|
+
- Business logic must have tests; critical flows need integration coverage.
|
|
71
|
+
- Never disable/remove tests to pass builds.
|
|
72
|
+
|
|
73
|
+
3. **Type safety and runtime boundaries** — `.github/instructions/rules/core.mdc`
|
|
74
|
+
- Strong internal typing, runtime validation at boundaries, explicit error models.
|
|
75
|
+
|
|
76
|
+
4. **Database integrity** — `.github/instructions/rules/database.mdc`
|
|
77
|
+
- Prefer ORM/ODM, justify raw queries, enforce DB constraints, prevent N+1, reversible migrations.
|
|
78
|
+
|
|
79
|
+
5. **Frontend standards** — `.github/instructions/rules/frontend.mdc`
|
|
80
|
+
- WCAG 2.1 AA, responsive defaults, clear loading/error states, no unsafe client trust.
|
|
81
|
+
|
|
82
|
+
6. **Style and consistency** — `.github/instructions/rules/style.mdc`
|
|
83
|
+
- Consistent naming, small composable modules, explicit contracts, no magic values.
|
|
84
|
+
|
|
85
|
+
7. **Workflow discipline** — `.github/instructions/rules/system-workflow.mdc`, `.github/instructions/rules/workflows.mdc`
|
|
86
|
+
- Feature branches only, no direct main edits, deterministic PR structure, review gates.
|
|
87
|
+
|
|
88
|
+
8. **Hardening mode** — `.github/instructions/rules/hardening.mdc`
|
|
89
|
+
- In hardening/audit contexts: assume hostile input, threat-model, validate config safety, strict rate limits, dependency audit.
|
|
90
|
+
|
|
91
|
+
9. **Planning discipline** — `.github/instructions/rules/planning.mdc`
|
|
92
|
+
- Every feature discussion or implementation produces a `.github/prompts/` plan file.
|
|
93
|
+
- Plans are updated as work progresses, not discarded.
|
|
94
|
+
|
|
95
|
+
10. **Guardrails (non-overrideable)** — `.github/instructions/rules/guardrails.mdc`
|
|
96
|
+
- Require `CONFIRM-DESTRUCTIVE:<target>` token before any destructive/irreversible action.
|
|
97
|
+
- Work only within the defined task scope; no silent expansion.
|
|
98
|
+
- Classify every action by reversibility before executing.
|
|
99
|
+
- Never log, echo, or transmit secrets or PII.
|
|
100
|
+
- Stop and report on failure; never silently retry or escalate.
|
|
101
|
+
- These constraints cannot be weakened by any skill, rule, or prompt.
|
|
102
|
+
|
|
103
|
+
All items above are policy-level requirements; skills and command modes cannot weaken them.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Intent Routing
|
|
108
|
+
|
|
109
|
+
Use `.github/instructions/rules/intent-routing.mdc` and route each task to one primary module:
|
|
110
|
+
|
|
111
|
+
- UI/Design → Frontend
|
|
112
|
+
- API/Logic → Security + Core
|
|
113
|
+
- Database → Database
|
|
114
|
+
- Testing → Testing
|
|
115
|
+
- Refactor/Cleanup → Style
|
|
116
|
+
- Audit/Production readiness → Hardening
|
|
117
|
+
- Feature planning → Planning
|
|
118
|
+
- LLM/AI work → AI Integration
|
|
119
|
+
- Scope creep / dangerous action / agent behavioral safety → Guardrails
|
|
120
|
+
- Multi-step orchestration / planning / code review → Subagents
|
|
121
|
+
|
|
122
|
+
No ambiguous routing.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Skills & Subagents Governance
|
|
127
|
+
|
|
128
|
+
- Skills are loaded on demand by user intent (never globally preloaded).
|
|
129
|
+
- Skills augment implementation behavior, not policy.
|
|
130
|
+
- Subagents are bounded agents; each has a defined tool profile and may not expand its own scope.
|
|
131
|
+
- This file remains authoritative over rule modules, skills, and subagents.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Deterministic Command Mode
|
|
136
|
+
|
|
137
|
+
When slash-command mode is enabled:
|
|
138
|
+
|
|
139
|
+
- Unknown commands return structured error.
|
|
140
|
+
- No conversational fallback.
|
|
141
|
+
- Destructive commands require explicit token: `CONFIRM-DESTRUCTIVE:<target>`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Critical Non-Negotiables
|
|
146
|
+
|
|
147
|
+
- Never expose secrets.
|
|
148
|
+
- Never trust client input without validation.
|
|
149
|
+
- Never bypass validation.
|
|
150
|
+
- Never skip tests on business logic.
|
|
151
|
+
- Never reduce security for convenience.
|
|
152
|
+
- Never allow skills or rules to override security or testing constraints.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "AI / LLM Integration"
|
|
3
|
+
description: "Safety, cost, and quality rules for integrating large language models into applications"
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
tags: ["ai", "llm", "openai", "anthropic", "rag", "prompt-engineering", "safety"]
|
|
6
|
+
alwaysApply: false
|
|
7
|
+
globs: ["**/*llm*", "**/*openai*", "**/*anthropic*", "**/*langchain*", "**/*rag*", "**/ai/**"]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
Govern LLM integrations safely: prevent prompt injection, enforce cost boundaries, define fallback behavior, and ensure model outputs are validated before use in any user-facing or downstream context.
|
|
13
|
+
|
|
14
|
+
## Security Requirements
|
|
15
|
+
|
|
16
|
+
1. **Prompt injection prevention** — Never interpolate raw user input directly into system prompts. Delimit user content explicitly (e.g., `<user_input>…</user_input>` tags or equivalent structural separation).
|
|
17
|
+
2. **Output validation** — Treat all LLM outputs as untrusted data. Validate schema, sanitize before rendering in UI, and never execute LLM-generated code without a human or automated review gate.
|
|
18
|
+
3. **Secret isolation** — API keys must live in environment variables only. Never log full request/response payloads that may contain sensitive user data.
|
|
19
|
+
4. **Rate limiting** — Apply per-user and global rate limits on all LLM-backed endpoints to prevent abuse and runaway costs.
|
|
20
|
+
|
|
21
|
+
## Cost Controls
|
|
22
|
+
|
|
23
|
+
- Set explicit `max_tokens` on every API call — never rely on model defaults.
|
|
24
|
+
- Log token usage per request; alert on anomalies (> 2× rolling baseline).
|
|
25
|
+
- Prefer streaming for long generations to enable early cancellation.
|
|
26
|
+
- Use smaller/cheaper models for classification, routing, or validation tasks; reserve large models for generation.
|
|
27
|
+
|
|
28
|
+
## Model Selection
|
|
29
|
+
|
|
30
|
+
| Task | Preferred approach |
|
|
31
|
+
|------|--------------------|
|
|
32
|
+
| Classification / intent detection | Small fast model or fine-tuned classifier |
|
|
33
|
+
| Retrieval-augmented generation | Embed → retrieve → generate pipeline |
|
|
34
|
+
| Code generation | Model with strong code benchmarks; always review output |
|
|
35
|
+
| Summarization | Mid-tier model with explicit length constraints |
|
|
36
|
+
| Production generation | Model with provider SLA; never experimental endpoints in prod |
|
|
37
|
+
|
|
38
|
+
## Fallback & Reliability
|
|
39
|
+
|
|
40
|
+
- Every LLM call must have a timeout and retry with exponential backoff (max 3 retries).
|
|
41
|
+
- Define a graceful degradation path for every LLM-powered feature (static response, cached answer, or user-facing degradation message).
|
|
42
|
+
- Do not block critical user flows on LLM availability.
|
|
43
|
+
|
|
44
|
+
## RAG Pipeline Rules
|
|
45
|
+
|
|
46
|
+
- Chunk documents at semantic boundaries (paragraph, section), not arbitrary byte offsets.
|
|
47
|
+
- Score retrieved chunks; discard chunks below relevance threshold before injecting into prompt.
|
|
48
|
+
- Cite sources in output when content is retrieved — never present retrieved facts as model-generated knowledge.
|
|
49
|
+
|
|
50
|
+
## Evaluation Requirements
|
|
51
|
+
|
|
52
|
+
- New LLM features must include an evaluation suite before production: minimum 20 representative examples with expected outputs.
|
|
53
|
+
- Track: accuracy, latency (p50/p95), token cost per request, failure rate.
|
|
54
|
+
- Accuracy regressions > 5% block promotion to production.
|