@plaited/development-skills 0.6.0 → 0.6.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.
- package/.plaited/rules/code-review.md +1 -1
- package/.plaited/rules/documentation.md +41 -0
- package/.plaited/rules/git-workflow.md +0 -5
- package/.plaited/rules/github.md +4 -4
- package/.plaited/rules/module-organization.md +0 -7
- package/.plaited/rules/testing.md +0 -5
- package/package.json +1 -1
- package/src/scaffold-rules.ts +20 -23
- package/src/tests/scaffold-rules.spec.ts +119 -20
|
@@ -13,7 +13,7 @@ Before completing a code review, run these validation scripts:
|
|
|
13
13
|
|
|
14
14
|
### AgentSkills Validation
|
|
15
15
|
|
|
16
|
-
When working with AgentSkills directories (`.claude/skills/`, `.cursor/skills/`, `.factory/skills/`, etc.):
|
|
16
|
+
When working with AgentSkills directories (`.plaited/skills/`, `.claude/skills/`, `.cursor/skills/`, `.factory/skills/`, etc.):
|
|
17
17
|
|
|
18
18
|
{{#if development-skills}}
|
|
19
19
|
**Validate structure:**
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Documentation Standards
|
|
2
|
+
|
|
3
|
+
## TSDoc Requirements
|
|
4
|
+
|
|
5
|
+
Public APIs require comprehensive TSDoc documentation following these conventions:
|
|
6
|
+
|
|
7
|
+
- **No `@example` sections** - Tests serve as living examples
|
|
8
|
+
- **Use `@internal` marker** - Mark non-public APIs explicitly
|
|
9
|
+
- **Always use `type`** - Prefer type aliases over interfaces
|
|
10
|
+
|
|
11
|
+
### TSDoc Template
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
/**
|
|
15
|
+
* Brief description of what this does
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Additional context, usage notes, or implementation details.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Description of the parameter
|
|
21
|
+
* @returns Description of return value
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Diagrams
|
|
28
|
+
|
|
29
|
+
Use Mermaid diagrams only (not ASCII art):
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
\```mermaid
|
|
33
|
+
flowchart TD
|
|
34
|
+
A[Start] --> B[Process]
|
|
35
|
+
B --> C[End]
|
|
36
|
+
\```
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Avoid**: ASCII box-drawing characters (`┌`, `│`, `└`, `─`, etc.)
|
|
40
|
+
|
|
41
|
+
**Rationale:** Token efficiency, clearer semantic meaning, easier maintenance.
|
package/.plaited/rules/github.md
CHANGED
|
@@ -58,7 +58,7 @@ gh api repos/<owner>/<repo>/pulls/<number>/comments --jq '
|
|
|
58
58
|
**Step 4: Address ALL feedback**
|
|
59
59
|
Create a checklist and address each item:
|
|
60
60
|
- [ ] Human reviewer comments
|
|
61
|
-
- [ ]
|
|
61
|
+
- [ ] Agentic Code review comments
|
|
62
62
|
- [ ] GitHub Advanced Security alerts (ReDoS, injection, etc.)
|
|
63
63
|
- [ ] GitHub Code Quality comments (dead code, useless assignments)
|
|
64
64
|
- [ ] Inline review suggestions
|
|
@@ -68,7 +68,7 @@ Create a checklist and address each item:
|
|
|
68
68
|
| Source | API/Location | Description |
|
|
69
69
|
|--------|--------------|-------------|
|
|
70
70
|
| Human reviewers | `gh pr view --json reviews` | Code owners, team members |
|
|
71
|
-
|
|
|
71
|
+
| AI code review | `gh pr view --json comments` | AI-generated review |
|
|
72
72
|
| GitHub Advanced Security | `gh api .../code-scanning/alerts` | Security vulnerabilities (ReDoS, injection) |
|
|
73
73
|
| GitHub Code Quality | `gh api .../pulls/.../comments` | Code quality issues (login: `github-code-quality[bot]`) |
|
|
74
74
|
| Inline suggestions | `gh api .../pulls/.../comments` | Line-specific review comments |
|
|
@@ -76,9 +76,9 @@ Create a checklist and address each item:
|
|
|
76
76
|
### Filtering by Author
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
# Get all automated reviews from PR
|
|
79
|
+
# Get all automated reviews from PR (adjust regex for your AI reviewer logins)
|
|
80
80
|
gh pr view <number> --repo <owner>/<repo> --json reviews --jq '
|
|
81
|
-
.reviews[] | select(.author.login | test("github-|
|
|
81
|
+
.reviews[] | select(.author.login | test("github-|bot")) | {author: .author.login, state: .state}
|
|
82
82
|
'
|
|
83
83
|
|
|
84
84
|
# Get specific inline comment by ID
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
RULE TEMPLATE - Distributed via scaffold-rules skill
|
|
3
|
-
Variables: {{#if bun}}
|
|
4
|
-
-->
|
|
5
|
-
|
|
6
1
|
# Module Organization
|
|
7
2
|
|
|
8
3
|
## No Index Files
|
|
@@ -43,9 +38,7 @@ Only use `main.ts` if the package truly has multiple co-equal entry points that
|
|
|
43
38
|
|
|
44
39
|
## Explicit Import Extensions
|
|
45
40
|
|
|
46
|
-
{{#if bun}}
|
|
47
41
|
Always include `.ts` extensions in imports. Bun runs TypeScript natively—no compilation required:
|
|
48
|
-
{{/if}}
|
|
49
42
|
|
|
50
43
|
```typescript
|
|
51
44
|
// ✅ Good
|
package/package.json
CHANGED
package/src/scaffold-rules.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* and outputs JSON for agent consumption.
|
|
7
7
|
*
|
|
8
8
|
* All agents use `.plaited/rules/` as the unified default location.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* AGENTS.md serves as the single source of truth for rules content,
|
|
10
|
+
* while CLAUDE.md simply references it via @AGENTS.md syntax.
|
|
11
11
|
*
|
|
12
12
|
* Options:
|
|
13
13
|
* - --rules-dir, -d: Custom rules directory path (overrides default .plaited/rules)
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* - --list, -l: List available rules without full output
|
|
16
16
|
*
|
|
17
17
|
* Output includes:
|
|
18
|
-
* - claudeMdSection: Marker-wrapped section with @ syntax for CLAUDE.md
|
|
19
18
|
* - agentsMdSection: Marker-wrapped section with markdown links for AGENTS.md
|
|
19
|
+
* - claudeMdReference: Short reference snippet pointing to @AGENTS.md
|
|
20
20
|
* - templates: Processed rule content for each selected rule
|
|
21
21
|
*
|
|
22
22
|
* Template syntax:
|
|
@@ -95,10 +95,10 @@ export type ProcessedTemplate = {
|
|
|
95
95
|
*/
|
|
96
96
|
export type ScaffoldOutput = {
|
|
97
97
|
rulesPath: string
|
|
98
|
-
/** Marker-wrapped section with @ syntax for CLAUDE.md */
|
|
99
|
-
claudeMdSection: string
|
|
100
98
|
/** Marker-wrapped section with markdown links for AGENTS.md */
|
|
101
99
|
agentsMdSection: string
|
|
100
|
+
/** Short reference snippet for CLAUDE.md pointing to AGENTS.md */
|
|
101
|
+
claudeMdReference: string
|
|
102
102
|
templates: Record<string, ProcessedTemplate>
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -214,38 +214,34 @@ const processTemplate = (content: string, context: TemplateContext): string => {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/**
|
|
217
|
-
* Generate marker-wrapped
|
|
217
|
+
* Generate marker-wrapped reference snippet for CLAUDE.md
|
|
218
218
|
*
|
|
219
219
|
* @remarks
|
|
220
|
-
* Claude Code uses `@
|
|
220
|
+
* Claude Code uses `@file.md` syntax to include file contents.
|
|
221
|
+
* This generates a short reference pointing to AGENTS.md as the single source of truth.
|
|
221
222
|
* The markers allow this section to be updated without affecting other content.
|
|
222
223
|
*/
|
|
223
|
-
const
|
|
224
|
+
const generateClaudeMdReference = (): string => {
|
|
224
225
|
const lines = [
|
|
225
226
|
MARKERS.start,
|
|
226
227
|
'',
|
|
227
228
|
'## Project Rules',
|
|
228
229
|
'',
|
|
229
|
-
|
|
230
|
-
'Each rule file covers a specific topic:',
|
|
230
|
+
'See @AGENTS.md for shared development rules.',
|
|
231
231
|
'',
|
|
232
|
+
MARKERS.end,
|
|
232
233
|
]
|
|
233
234
|
|
|
234
|
-
for (const [_ruleId, template] of Object.entries(templates)) {
|
|
235
|
-
lines.push(`- @${rulesPath}/${template.filename} - ${template.description}`)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
lines.push('')
|
|
239
|
-
lines.push(MARKERS.end)
|
|
240
|
-
|
|
241
235
|
return lines.join('\n')
|
|
242
236
|
}
|
|
243
237
|
|
|
244
238
|
/**
|
|
245
|
-
* Generate marker-wrapped section for AGENTS.md with
|
|
239
|
+
* Generate marker-wrapped section for AGENTS.md with dual format
|
|
246
240
|
*
|
|
247
241
|
* @remarks
|
|
248
|
-
* AGENTS.md
|
|
242
|
+
* AGENTS.md uses both formats for maximum compatibility:
|
|
243
|
+
* - `@path` syntax for Claude Code to load file contents
|
|
244
|
+
* - `[name](path)` markdown links for other tools and GitHub rendering
|
|
249
245
|
* The markers allow this section to be updated without affecting other content.
|
|
250
246
|
*/
|
|
251
247
|
const generateAgentsMdSection = (templates: Record<string, ProcessedTemplate>, rulesPath: string): string => {
|
|
@@ -260,7 +256,8 @@ const generateAgentsMdSection = (templates: Record<string, ProcessedTemplate>, r
|
|
|
260
256
|
]
|
|
261
257
|
|
|
262
258
|
for (const [ruleId, template] of Object.entries(templates)) {
|
|
263
|
-
|
|
259
|
+
// Dual format: @ syntax for Claude Code, markdown link for other tools
|
|
260
|
+
lines.push(`- @${rulesPath}/${template.filename} - [${ruleId}](${rulesPath}/${template.filename})`)
|
|
264
261
|
}
|
|
265
262
|
|
|
266
263
|
lines.push('')
|
|
@@ -358,15 +355,15 @@ export const scaffoldRules = async (args: string[]): Promise<void> => {
|
|
|
358
355
|
}
|
|
359
356
|
}
|
|
360
357
|
|
|
361
|
-
// Generate marker-wrapped
|
|
362
|
-
const claudeMdSection = generateClaudeMdSection(templates, rulesPath)
|
|
358
|
+
// Generate marker-wrapped section for AGENTS.md and reference for CLAUDE.md
|
|
363
359
|
const agentsMdSection = generateAgentsMdSection(templates, rulesPath)
|
|
360
|
+
const claudeMdReference = generateClaudeMdReference()
|
|
364
361
|
|
|
365
362
|
// Build output
|
|
366
363
|
const output: ScaffoldOutput = {
|
|
367
364
|
rulesPath,
|
|
368
|
-
claudeMdSection,
|
|
369
365
|
agentsMdSection,
|
|
366
|
+
claudeMdReference,
|
|
370
367
|
templates,
|
|
371
368
|
}
|
|
372
369
|
|
|
@@ -10,8 +10,8 @@ type Template = {
|
|
|
10
10
|
|
|
11
11
|
type ScaffoldOutput = {
|
|
12
12
|
rulesPath: string
|
|
13
|
-
claudeMdSection: string
|
|
14
13
|
agentsMdSection: string
|
|
14
|
+
claudeMdReference: string
|
|
15
15
|
templates: Record<string, Template>
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -121,42 +121,138 @@ describe('scaffold-rules', () => {
|
|
|
121
121
|
expect(result.rulesPath).toBe('.plaited/rules')
|
|
122
122
|
})
|
|
123
123
|
|
|
124
|
-
test('includes
|
|
124
|
+
test('includes claudeMdReference with markers and @AGENTS.md', async () => {
|
|
125
125
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
126
126
|
|
|
127
|
-
expect(result.
|
|
128
|
-
expect(result.
|
|
129
|
-
expect(result.
|
|
130
|
-
expect(result.
|
|
127
|
+
expect(result.claudeMdReference).toContain('<!-- PLAITED-RULES-START -->')
|
|
128
|
+
expect(result.claudeMdReference).toContain('<!-- PLAITED-RULES-END -->')
|
|
129
|
+
expect(result.claudeMdReference).toContain('@AGENTS.md')
|
|
130
|
+
expect(result.claudeMdReference).toContain('## Project Rules')
|
|
131
131
|
})
|
|
132
132
|
|
|
133
|
-
test('includes agentsMdSection with markers and
|
|
133
|
+
test('includes agentsMdSection with markers and dual format', async () => {
|
|
134
134
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
135
135
|
|
|
136
136
|
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-START -->')
|
|
137
137
|
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-END -->')
|
|
138
|
-
|
|
138
|
+
// Should have @ syntax for Claude Code
|
|
139
|
+
expect(result.agentsMdSection).toContain('@.plaited/rules/')
|
|
140
|
+
// Should have markdown links for other tools
|
|
139
141
|
expect(result.agentsMdSection).toContain('](.plaited/rules/')
|
|
140
142
|
expect(result.agentsMdSection).toContain('## Rules')
|
|
141
143
|
})
|
|
142
144
|
|
|
143
|
-
test('
|
|
145
|
+
test('claudeMdReference does not list individual rules', async () => {
|
|
144
146
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
145
147
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
// claudeMdReference should be a simple reference to AGENTS.md, not a list of rules
|
|
149
|
+
expect(result.claudeMdReference).not.toContain('.plaited/rules/')
|
|
150
|
+
expect(result.claudeMdReference).toContain('@AGENTS.md')
|
|
149
151
|
})
|
|
150
152
|
|
|
151
|
-
test('agentsMdSection lists all selected rules', async () => {
|
|
153
|
+
test('agentsMdSection lists all selected rules in dual format', async () => {
|
|
152
154
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
153
155
|
|
|
154
156
|
for (const [ruleId, template] of Object.entries(result.templates)) {
|
|
157
|
+
// Each rule should have both @ syntax and markdown link
|
|
158
|
+
expect(result.agentsMdSection).toContain(`@.plaited/rules/${template.filename}`)
|
|
155
159
|
expect(result.agentsMdSection).toContain(`[${ruleId}](.plaited/rules/${template.filename})`)
|
|
156
160
|
}
|
|
157
161
|
})
|
|
158
162
|
})
|
|
159
163
|
|
|
164
|
+
describe('claudeMdReference behavior', () => {
|
|
165
|
+
test('has exact expected content structure', async () => {
|
|
166
|
+
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
167
|
+
|
|
168
|
+
// Verify the exact structure of claudeMdReference
|
|
169
|
+
const lines = result.claudeMdReference.split('\n')
|
|
170
|
+
expect(lines[0]).toBe('<!-- PLAITED-RULES-START -->')
|
|
171
|
+
expect(lines[1]).toBe('')
|
|
172
|
+
expect(lines[2]).toBe('## Project Rules')
|
|
173
|
+
expect(lines[3]).toBe('')
|
|
174
|
+
expect(lines[4]).toBe('See @AGENTS.md for shared development rules.')
|
|
175
|
+
expect(lines[5]).toBe('')
|
|
176
|
+
expect(lines[6]).toBe('<!-- PLAITED-RULES-END -->')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('is constant regardless of rules selected', async () => {
|
|
180
|
+
const allRules: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
181
|
+
const oneRule: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules testing`.json()
|
|
182
|
+
const twoRules: ScaffoldOutput =
|
|
183
|
+
await $`bun ${binDir}/cli.ts scaffold-rules --rules testing --rules accuracy`.json()
|
|
184
|
+
|
|
185
|
+
// claudeMdReference should be identical in all cases
|
|
186
|
+
expect(oneRule.claudeMdReference).toBe(allRules.claudeMdReference)
|
|
187
|
+
expect(twoRules.claudeMdReference).toBe(allRules.claudeMdReference)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
test('is constant regardless of rules-dir', async () => {
|
|
191
|
+
const defaultPath: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
192
|
+
const customPath: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules-dir=.cursor/rules`.json()
|
|
193
|
+
const anotherPath: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules-dir=custom/path`.json()
|
|
194
|
+
|
|
195
|
+
// claudeMdReference should be identical regardless of rules-dir
|
|
196
|
+
expect(customPath.claudeMdReference).toBe(defaultPath.claudeMdReference)
|
|
197
|
+
expect(anotherPath.claudeMdReference).toBe(defaultPath.claudeMdReference)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
test('uses shared markers with agentsMdSection', async () => {
|
|
201
|
+
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
202
|
+
|
|
203
|
+
// Both sections should use the same markers for consistency
|
|
204
|
+
const startMarker = '<!-- PLAITED-RULES-START -->'
|
|
205
|
+
const endMarker = '<!-- PLAITED-RULES-END -->'
|
|
206
|
+
|
|
207
|
+
expect(result.claudeMdReference).toContain(startMarker)
|
|
208
|
+
expect(result.claudeMdReference).toContain(endMarker)
|
|
209
|
+
expect(result.agentsMdSection).toContain(startMarker)
|
|
210
|
+
expect(result.agentsMdSection).toContain(endMarker)
|
|
211
|
+
})
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
describe('agentsMdSection with filtered rules', () => {
|
|
215
|
+
test('only includes selected rules in dual format', async () => {
|
|
216
|
+
const result: ScaffoldOutput =
|
|
217
|
+
await $`bun ${binDir}/cli.ts scaffold-rules --rules testing --rules bun-apis`.json()
|
|
218
|
+
|
|
219
|
+
// Should contain selected rules (both @ and markdown formats)
|
|
220
|
+
expect(result.agentsMdSection).toContain('@.plaited/rules/testing.md')
|
|
221
|
+
expect(result.agentsMdSection).toContain('[testing]')
|
|
222
|
+
expect(result.agentsMdSection).toContain('@.plaited/rules/bun-apis.md')
|
|
223
|
+
expect(result.agentsMdSection).toContain('[bun-apis]')
|
|
224
|
+
|
|
225
|
+
// Should NOT contain other rules
|
|
226
|
+
expect(result.agentsMdSection).not.toContain('@.plaited/rules/accuracy.md')
|
|
227
|
+
expect(result.agentsMdSection).not.toContain('[accuracy]')
|
|
228
|
+
expect(result.agentsMdSection).not.toContain('@.plaited/rules/git-workflow.md')
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
test('has valid structure with single rule in dual format', async () => {
|
|
232
|
+
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules testing`.json()
|
|
233
|
+
|
|
234
|
+
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-START -->')
|
|
235
|
+
expect(result.agentsMdSection).toContain('## Rules')
|
|
236
|
+
// Both formats present
|
|
237
|
+
expect(result.agentsMdSection).toContain('@.plaited/rules/testing.md')
|
|
238
|
+
expect(result.agentsMdSection).toContain('[testing](.plaited/rules/testing.md)')
|
|
239
|
+
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-END -->')
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
test('has empty rules list when no rules match', async () => {
|
|
243
|
+
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules nonexistent`.nothrow().json()
|
|
244
|
+
|
|
245
|
+
// Should still have valid structure with markers
|
|
246
|
+
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-START -->')
|
|
247
|
+
expect(result.agentsMdSection).toContain('## Rules')
|
|
248
|
+
expect(result.agentsMdSection).toContain('<!-- PLAITED-RULES-END -->')
|
|
249
|
+
|
|
250
|
+
// But no rule references (neither @ nor markdown)
|
|
251
|
+
expect(result.agentsMdSection).not.toMatch(/@\.plaited\/rules\/.*\.md/)
|
|
252
|
+
expect(result.agentsMdSection).not.toMatch(/\[.*\]\(\.plaited\/rules\/.*\.md\)/)
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
|
|
160
256
|
describe('template content', () => {
|
|
161
257
|
test('git-workflow uses standard commit format', async () => {
|
|
162
258
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules`.json()
|
|
@@ -194,17 +290,20 @@ describe('scaffold-rules', () => {
|
|
|
194
290
|
expect(result.rulesPath).toBe('.cursor/rules')
|
|
195
291
|
})
|
|
196
292
|
|
|
197
|
-
test('
|
|
293
|
+
test('claudeMdReference is path-independent', async () => {
|
|
198
294
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules-dir=.cursor/rules`.json()
|
|
199
295
|
|
|
200
|
-
|
|
201
|
-
expect(result.
|
|
296
|
+
// claudeMdReference always references AGENTS.md regardless of rules path
|
|
297
|
+
expect(result.claudeMdReference).toContain('@AGENTS.md')
|
|
298
|
+
expect(result.claudeMdReference).not.toContain('.cursor/rules')
|
|
202
299
|
})
|
|
203
300
|
|
|
204
|
-
test('agentsMdSection uses custom path', async () => {
|
|
301
|
+
test('agentsMdSection uses custom path in both formats', async () => {
|
|
205
302
|
const result: ScaffoldOutput = await $`bun ${binDir}/cli.ts scaffold-rules --rules-dir=.cursor/rules`.json()
|
|
206
303
|
|
|
207
|
-
|
|
304
|
+
// Both @ syntax and markdown links should use custom path
|
|
305
|
+
expect(result.agentsMdSection).toContain('@.cursor/rules/')
|
|
306
|
+
expect(result.agentsMdSection).toContain('](.cursor/rules/')
|
|
208
307
|
expect(result.agentsMdSection).not.toContain('.plaited/rules/')
|
|
209
308
|
})
|
|
210
309
|
|
|
@@ -278,8 +377,8 @@ describe('scaffold-rules', () => {
|
|
|
278
377
|
|
|
279
378
|
// Should return valid output with empty templates
|
|
280
379
|
expect(result.templates).toEqual({})
|
|
281
|
-
expect(result.
|
|
282
|
-
expect(result.
|
|
380
|
+
expect(result.claudeMdReference).toContain('<!-- PLAITED-RULES-START -->')
|
|
381
|
+
expect(result.claudeMdReference).toContain('<!-- PLAITED-RULES-END -->')
|
|
283
382
|
})
|
|
284
383
|
|
|
285
384
|
test('description extraction falls back for heading-only content', async () => {
|