@cleocode/skills 2026.5.84 → 2026.5.87
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/package.json +1 -1
- package/skills/ct-adr-recorder/SKILL.md +74 -0
- package/skills/ct-adr-recorder/__tests__/skill-adr-recorder.test.ts +65 -0
- package/skills/ct-docs-lookup/SKILL.md +116 -1
- package/skills/ct-docs-lookup/references/ctx7-workflow.md +198 -0
- package/skills/ct-docs-lookup/references/library-id-resolution.md +217 -0
- package/skills/ct-docs-lookup/references/version-specific-docs.md +220 -0
- package/skills/ct-docs-review/SKILL.md +133 -1
- package/skills/ct-docs-review/__tests__/skill-docs-review.test.ts +53 -0
- package/skills/ct-docs-review/references/inline-comment-patterns.md +268 -0
- package/skills/ct-docs-review/references/pr-review-mode.md +270 -0
- package/skills/ct-docs-review/references/style-violations.md +341 -0
- package/skills/ct-docs-write/SKILL.md +157 -1
- package/skills/ct-docs-write/__tests__/skill-docs-write.test.ts +55 -0
- package/skills/ct-docs-write/references/audience-targeting.md +305 -0
- package/skills/ct-docs-write/references/cleo-style-guide.md +234 -0
- package/skills/ct-docs-write/references/markdown-patterns.md +329 -0
- package/skills/ct-documentor/SKILL.md +11 -0
- package/skills/ct-documentor/references/anti-patterns.md +216 -0
- package/skills/ct-documentor/references/chain-orchestration.md +194 -0
- package/skills/ct-documentor/references/doc-types-and-templates.md +301 -0
- package/skills/ct-documentor/references/style-coordination.md +195 -0
- package/skills/ct-research-agent/SKILL.md +9 -0
- package/skills/ct-research-agent/references/anti-patterns.md +154 -0
- package/skills/ct-research-agent/references/citation-and-evidence.md +140 -0
- package/skills/ct-research-agent/references/source-strategy.md +116 -0
- package/skills/ct-research-agent/references/triggers-and-routing.md +93 -0
- package/skills/ct-skill-validator/SKILL.md +19 -0
- package/skills/ct-skill-validator/scripts/check_depth.py +306 -0
- package/skills/ct-spec-writer/SKILL.md +71 -1
- package/skills/ct-spec-writer/__tests__/skill-spec-writer.test.ts +60 -0
- package/skills/ct-spec-writer/references/anti-patterns.md +176 -0
- package/skills/ct-spec-writer/references/rfc2119-language.md +138 -0
- package/skills/ct-spec-writer/references/spec-templates.md +233 -0
- package/skills/ct-spec-writer/references/traceability-matrix.md +145 -0
- package/skills/ct-task-executor/SKILL.md +10 -0
- package/skills/ct-task-executor/references/acceptance-criteria-mapping.md +163 -0
- package/skills/ct-task-executor/references/anti-patterns.md +201 -0
- package/skills/ct-task-executor/references/common-failures.md +193 -0
- package/skills/ct-task-executor/references/evidence-and-gates.md +179 -0
- package/skills/ct-task-executor/references/implementation-patterns.md +160 -0
- package/skills/ct-validator/SKILL.md +9 -0
- package/skills/ct-validator/references/anti-patterns.md +194 -0
- package/skills/ct-validator/references/compliance-reports.md +199 -0
- package/skills/ct-validator/references/schema-checking.md +191 -0
- package/skills/ct-validator/references/validation-modes.md +185 -0
- package/skills/manifest.json +46 -8
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Version-Specific Docs
|
|
2
|
+
|
|
3
|
+
Library APIs drift across versions — sometimes silently (default value
|
|
4
|
+
changes), sometimes loudly (renames, removals). This reference covers
|
|
5
|
+
how to lock the docs lookup to the version the user actually runs,
|
|
6
|
+
and how to handle migrations and deprecated APIs.
|
|
7
|
+
|
|
8
|
+
## Why Version Pinning Matters
|
|
9
|
+
|
|
10
|
+
The cost of citing the wrong version is high.
|
|
11
|
+
|
|
12
|
+
- Drizzle ORM v1.0.0-beta renamed `relations()` to `defineRelations()`.
|
|
13
|
+
A 0.x user given a v1 example will copy code that doesn't import.
|
|
14
|
+
- Next.js 15 changed default `fetch` cache from `force-cache` to
|
|
15
|
+
`no-store`. A user on 14 reading a 15 doc will not see the behavior
|
|
16
|
+
they expect.
|
|
17
|
+
- React 19 introduced new hooks. A React 18 user copying a React 19
|
|
18
|
+
example gets `useActionState is not defined`.
|
|
19
|
+
|
|
20
|
+
In each case, the failure mode is "confidently wrong answer". The
|
|
21
|
+
remedy is always: pin to the user's actual version before fetching.
|
|
22
|
+
|
|
23
|
+
## Finding the User's Version
|
|
24
|
+
|
|
25
|
+
The skill SHOULD detect the user's installed version before opening
|
|
26
|
+
Step 2.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Node.js projects
|
|
30
|
+
jq -r '.dependencies.next, .devDependencies.next | select(.)' package.json
|
|
31
|
+
|
|
32
|
+
# Cargo projects
|
|
33
|
+
cargo tree -p drizzle 2>/dev/null # if applicable
|
|
34
|
+
grep -A 1 '^drizzle-orm =' Cargo.toml
|
|
35
|
+
|
|
36
|
+
# Python projects
|
|
37
|
+
grep '^next' requirements.txt
|
|
38
|
+
pip show next 2>/dev/null | grep '^Version'
|
|
39
|
+
|
|
40
|
+
# Generic — search for any lockfile entry
|
|
41
|
+
grep -A 1 'next:' pnpm-lock.yaml | head -3
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If detection fails (no lockfile, version not pinned), ask the user
|
|
45
|
+
or default to the project's stated version.
|
|
46
|
+
|
|
47
|
+
## Version Format Matching
|
|
48
|
+
|
|
49
|
+
Context7 IDs accept several version forms:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
/vercel/next.js # all versions; unspecified
|
|
53
|
+
/vercel/next.js/v15 # latest within v15.x
|
|
54
|
+
/vercel/next.js/v15.0.0 # exactly v15.0.0
|
|
55
|
+
/vercel/next.js/v15.0.0-canary.7 # specific canary
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Match the granularity of the user's question:
|
|
59
|
+
|
|
60
|
+
- General "how do I do X with library" → unversioned or major-pinned.
|
|
61
|
+
- Migration "from N to M" → both major-pinned: `/lib/vN` and `/lib/vM`.
|
|
62
|
+
- Bug investigation "in 15.0.3 specifically X happens" → exact pin.
|
|
63
|
+
|
|
64
|
+
## Major-Version Migrations
|
|
65
|
+
|
|
66
|
+
When the user is upgrading from major N to major N+1, run two fetches.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# From-version: what works today
|
|
70
|
+
npx ctx7@latest docs /drizzle-team/drizzle-orm/v0.36 "how do I define relations"
|
|
71
|
+
|
|
72
|
+
# To-version: what they will move to
|
|
73
|
+
npx ctx7@latest docs /drizzle-team/drizzle-orm/v1.0.0-beta "how do I define relations"
|
|
74
|
+
|
|
75
|
+
# Compose the migration story:
|
|
76
|
+
# 1. Show the current API
|
|
77
|
+
# 2. Show the new API
|
|
78
|
+
# 3. Show the mapping
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The migration story has THREE parts. Skipping any of them produces
|
|
82
|
+
confusion:
|
|
83
|
+
|
|
84
|
+
- **Current API.** What the user has now.
|
|
85
|
+
- **New API.** What it becomes.
|
|
86
|
+
- **Mapping.** Mechanical translation between them.
|
|
87
|
+
|
|
88
|
+
Documenting only the new API leaves the user wondering "but my code
|
|
89
|
+
uses X — what does that become?"
|
|
90
|
+
|
|
91
|
+
## Deprecated APIs
|
|
92
|
+
|
|
93
|
+
When a fetched doc mentions an API as deprecated:
|
|
94
|
+
|
|
95
|
+
1. Surface the deprecation explicitly. Don't bury it.
|
|
96
|
+
2. Show the recommended replacement, fetched from the same docs.
|
|
97
|
+
3. Cite when deprecation began and when removal is planned (if stated).
|
|
98
|
+
|
|
99
|
+
Example output:
|
|
100
|
+
|
|
101
|
+
```markdown
|
|
102
|
+
The `relations()` helper in Drizzle ORM 0.x is deprecated as of v1.0.0-beta.
|
|
103
|
+
Use `defineRelations` instead.
|
|
104
|
+
|
|
105
|
+
| Drizzle 0.x | Drizzle 1.x (beta) |
|
|
106
|
+
|-------------|--------------------|
|
|
107
|
+
| `relations(table, (helpers) => ({ ... }))` | `defineRelations(schema, (t) => ({ ... }))` |
|
|
108
|
+
|
|
109
|
+
Deprecation announced: v1.0.0-beta (2025-Q4).
|
|
110
|
+
Planned removal: TBD (the 0.x line is still supported through 2026).
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Version Drift Detection
|
|
114
|
+
|
|
115
|
+
Run a sanity check before answering — does the user's installed
|
|
116
|
+
version match what they think they're using?
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# User says "I'm on Next.js 15".
|
|
120
|
+
$ jq -r '.dependencies.next' package.json
|
|
121
|
+
"14.3.0"
|
|
122
|
+
|
|
123
|
+
# Drift! Surface it:
|
|
124
|
+
# > Your package.json says Next.js 14.3.0, not 15. Are you planning
|
|
125
|
+
# > to upgrade, or did you mean 14? I'll fetch docs for what's
|
|
126
|
+
# > installed unless you confirm 15 is the target.
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This catches the common case where the user's mental model is ahead
|
|
130
|
+
of (or behind) their actual install.
|
|
131
|
+
|
|
132
|
+
## Multi-Library Lookups
|
|
133
|
+
|
|
134
|
+
A single question may span multiple libraries. Resolve each
|
|
135
|
+
independently with the right version pin.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Question: "How do I integrate Better-Auth with Drizzle ORM in a
|
|
139
|
+
# Svelte 5 SvelteKit project?"
|
|
140
|
+
|
|
141
|
+
# Three libraries; resolve each with project's actual version
|
|
142
|
+
npx ctx7@latest library "Better-Auth" "..."
|
|
143
|
+
npx ctx7@latest library "Drizzle ORM" "..."
|
|
144
|
+
npx ctx7@latest library "SvelteKit" "..."
|
|
145
|
+
|
|
146
|
+
# Then three fetches:
|
|
147
|
+
npx ctx7@latest docs /better-auth/better-auth "integration with drizzle"
|
|
148
|
+
npx ctx7@latest docs /drizzle-team/drizzle-orm/v1 "integration with better-auth"
|
|
149
|
+
npx ctx7@latest docs /sveltejs/kit/v2 "hooks for auth middleware"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Compose the answer from the three. Cite each library's version
|
|
153
|
+
explicitly so the user knows what works with what.
|
|
154
|
+
|
|
155
|
+
## When Versioned Docs Aren't Available
|
|
156
|
+
|
|
157
|
+
Context7's catalog doesn't always have per-version slices. When a
|
|
158
|
+
version pin returns "no matches":
|
|
159
|
+
|
|
160
|
+
1. Drop one granularity level (e.g., `/v15.0.0-canary.7` → `/v15`).
|
|
161
|
+
2. Drop another (`/v15` → `/vercel/next.js` unversioned).
|
|
162
|
+
3. Add a note that version-specific data may be missing — recommend
|
|
163
|
+
the user verify against the official release notes.
|
|
164
|
+
|
|
165
|
+
## Reading Release Notes
|
|
166
|
+
|
|
167
|
+
When the question is "what changed in version X", release notes are
|
|
168
|
+
often a better source than API docs. Two routes:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Route 1 — Context7 may have it indexed
|
|
172
|
+
npx ctx7@latest docs /vercel/next.js "release notes for v15"
|
|
173
|
+
|
|
174
|
+
# Route 2 — WebFetch the official release notes page
|
|
175
|
+
# (use when Context7 doesn't have release notes specifically)
|
|
176
|
+
WebFetch: https://nextjs.org/blog/next-15 "summarize the breaking changes"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Release notes are more concise than docs and explicitly call out
|
|
180
|
+
deprecations and removals — exactly what migration questions need.
|
|
181
|
+
|
|
182
|
+
## Citing Versions
|
|
183
|
+
|
|
184
|
+
Every code example produced from a version-pinned fetch MUST cite the
|
|
185
|
+
version.
|
|
186
|
+
|
|
187
|
+
```markdown
|
|
188
|
+
GOOD:
|
|
189
|
+
Use `defineRelations` (Drizzle ORM v1.0.0-beta and later):
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { defineRelations } from "drizzle-orm";
|
|
193
|
+
// ...
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
BAD:
|
|
197
|
+
Use `defineRelations`:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { defineRelations } from "drizzle-orm";
|
|
201
|
+
// ...
|
|
202
|
+
```
|
|
203
|
+
(no version context — reader doesn't know if their version supports it)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
When the user copies the code and it doesn't work, the version citation
|
|
207
|
+
is the first thing they check. Give it to them up front.
|
|
208
|
+
|
|
209
|
+
## Skill Boundary
|
|
210
|
+
|
|
211
|
+
This reference covers version handling within docs-lookup. It does NOT
|
|
212
|
+
cover:
|
|
213
|
+
|
|
214
|
+
- Migration code generators (out of scope; that's task-executor work).
|
|
215
|
+
- Upgrade plan authoring (out of scope; that's spec-writer work).
|
|
216
|
+
- Pinning the user's project to a new version (out of scope; that's a
|
|
217
|
+
task for the human or the executor).
|
|
218
|
+
|
|
219
|
+
Docs-lookup just produces the version-accurate documentation. The
|
|
220
|
+
downstream skills act on it.
|
|
@@ -20,6 +20,75 @@ license: MIT
|
|
|
20
20
|
|
|
21
21
|
@skills/_shared/cleo-style-guide.md
|
|
22
22
|
|
|
23
|
+
## Through SDK (preferred)
|
|
24
|
+
|
|
25
|
+
Read the doc through the docs SSoT — not the filesystem. Reviews that grep
|
|
26
|
+
loose files miss every doc that lives only as a blob, and miss the version
|
|
27
|
+
history that makes "what changed?" reviews possible.
|
|
28
|
+
|
|
29
|
+
### Fetch the doc to review
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# By slug (preferred — stable handle survives renames):
|
|
33
|
+
cleo docs fetch saml-setup-draft
|
|
34
|
+
|
|
35
|
+
# By attachment ID (when the slug is unknown):
|
|
36
|
+
cleo docs fetch att_01HXYZ...
|
|
37
|
+
|
|
38
|
+
# By SHA-256 (when reviewing a specific version):
|
|
39
|
+
cleo docs fetch 7a3f9b...
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`cleo docs fetch` returns the full attachment envelope: metadata, slug,
|
|
43
|
+
type, owner, refCount, and the bytes (base64-inline for files ≤ 1 MB,
|
|
44
|
+
storage path for larger blobs).
|
|
45
|
+
|
|
46
|
+
### Diff two versions of the same doc
|
|
47
|
+
|
|
48
|
+
CLEO doesn't ship a dedicated `cleo docs diff` verb. Use version listing
|
|
49
|
+
plus two fetches to compose the diff:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cleo docs versions --for T1234 --name saml-setup-draft
|
|
53
|
+
# Returns every SHA-256 version with timestamps.
|
|
54
|
+
|
|
55
|
+
cleo docs fetch <sha-v1> > /tmp/v1.md
|
|
56
|
+
cleo docs fetch <sha-v2> > /tmp/v2.md
|
|
57
|
+
diff -u /tmp/v1.md /tmp/v2.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Reviewers SHOULD anchor every issue to a specific SHA so the author can
|
|
61
|
+
reproduce the exact state being flagged.
|
|
62
|
+
|
|
63
|
+
### List candidate docs by type
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
cleo docs list --type spec --project # all specs in this project
|
|
67
|
+
cleo docs list --task T1234 --type research # research notes attached to T1234
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### PR review mode — still SDK-grounded
|
|
71
|
+
|
|
72
|
+
When reviewing a GitHub PR that touches a published doc, fetch the SSoT
|
|
73
|
+
copy alongside the diff so you can compare the on-disk file in the PR
|
|
74
|
+
against the canonical blob. Drift between the two is its own review
|
|
75
|
+
finding — flag it as Issue N: docs SSoT drift.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
gh pr diff <pr-number> -- docs/saml-setup.md
|
|
79
|
+
cleo docs fetch saml-setup-draft # SSoT canonical
|
|
80
|
+
cleo docs status # full drift report
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Deprecated: Direct filesystem reads
|
|
84
|
+
|
|
85
|
+
The legacy "open the .md file in the working tree and review it"
|
|
86
|
+
pattern is deprecated. The on-disk file may lag the SSoT, the slug-
|
|
87
|
+
based linkage to the originating task is invisible, and the version
|
|
88
|
+
history needed for "what changed?" reviews is missing. Migrate to
|
|
89
|
+
`cleo docs fetch <slug>` for every review — and run `cleo docs status`
|
|
90
|
+
to surface drift before commenting.
|
|
91
|
+
|
|
23
92
|
## Review mode detection
|
|
24
93
|
|
|
25
94
|
**IMPORTANT: Before starting the review, determine which mode to use:**
|
|
@@ -172,4 +241,67 @@ This could be more conversational. Consider: "You can't..." instead of "You cann
|
|
|
172
241
|
1. Remove any issues from your assessment that won't make a material difference to the reader if addressed. Only flag issues worth the author's time to fix.
|
|
173
242
|
2. **Verify all issues are numbered sequentially** starting from Issue 1 with no gaps in numbering.
|
|
174
243
|
3. Confirm the format exactly matches: `**Issue N: [Brief title]**` where N is the issue number.
|
|
175
|
-
4. **In PR mode**: Verify each issue was posted as a separate GitHub comment (not output to conversation).
|
|
244
|
+
4. **In PR mode**: Verify each issue was posted as a separate GitHub comment (not output to conversation).
|
|
245
|
+
|
|
246
|
+
## Issue length guidelines
|
|
247
|
+
|
|
248
|
+
| Doc size | Typical issue count | Red flag |
|
|
249
|
+
|----------|---------------------|----------|
|
|
250
|
+
| Small (< 100 lines) | 0-3 issues | 10+ issues |
|
|
251
|
+
| Medium (100-300 lines) | 0-8 issues | 20+ issues |
|
|
252
|
+
| Large (300+ lines) | 0-15 issues | 30+ issues |
|
|
253
|
+
|
|
254
|
+
A flood of low-value flags trains the author to ignore reviews. Apply
|
|
255
|
+
the materiality filter aggressively — be selective up front; flag only
|
|
256
|
+
what matters.
|
|
257
|
+
|
|
258
|
+
## Workflow discipline
|
|
259
|
+
|
|
260
|
+
| Step | Anti-pattern | Correct |
|
|
261
|
+
|------|--------------|---------|
|
|
262
|
+
| Start | Post comments immediately | Start pending review first |
|
|
263
|
+
| Identify | Post issues one-by-one | Collect ALL, then post in parallel |
|
|
264
|
+
| Format | Plain text bodies | `**Issue N: [Title]**` prefix |
|
|
265
|
+
| Submit | `event: REQUEST_CHANGES` blocks PR | `event: COMMENT` is non-blocking |
|
|
266
|
+
| Body | Long summary body on submit | Empty body — let inline comments speak |
|
|
267
|
+
|
|
268
|
+
## When review should block
|
|
269
|
+
|
|
270
|
+
The default event is `COMMENT` (non-blocking). Use `REQUEST_CHANGES`
|
|
271
|
+
only when the PR contains issues that, if shipped, would actively harm
|
|
272
|
+
readers:
|
|
273
|
+
|
|
274
|
+
- Broken code examples that would fail when copy-pasted
|
|
275
|
+
- Outdated security guidance
|
|
276
|
+
- Links to deprecated APIs in setup instructions
|
|
277
|
+
- Patronizing language to vulnerable audiences
|
|
278
|
+
|
|
279
|
+
For everything else, use COMMENT. Trust the author to take feedback
|
|
280
|
+
seriously without being forced.
|
|
281
|
+
|
|
282
|
+
## Re-review after fix
|
|
283
|
+
|
|
284
|
+
When the author addresses feedback and pushes new commits, run the
|
|
285
|
+
review again on the updated diff. Don't re-flag issues already fixed;
|
|
286
|
+
do flag new issues introduced in the fix.
|
|
287
|
+
|
|
288
|
+
For re-reviews, start the comment with a status line:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
**Issue 2 (UPDATED): Vague heading**
|
|
292
|
+
|
|
293
|
+
The previous fix changed "Setup" to "Setup Steps" — still vague.
|
|
294
|
+
Try "Install dependencies, then run init".
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
The "(UPDATED)" tag signals iteration, not a brand-new flag.
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## See references/
|
|
302
|
+
|
|
303
|
+
Progressive disclosure — load on demand only:
|
|
304
|
+
|
|
305
|
+
- `references/style-violations.md` — taxonomy of violations with detection patterns, issue titles, and remediation messages
|
|
306
|
+
- `references/pr-review-mode.md` — pending-review workflow, comment format, gh CLI fallback, materiality filter
|
|
307
|
+
- `references/inline-comment-patterns.md` — comment anatomy, single-line/multi-line/pattern fixes, anti-patterns
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for ct-docs-review/SKILL.md (T9642 / Epic T9629 / Saga T9625).
|
|
3
|
+
*
|
|
4
|
+
* Pins the SDK-first review contract: reviewers MUST read docs through
|
|
5
|
+
* `cleo docs fetch <slug>` rather than the working-tree file. Documents
|
|
6
|
+
* the version-diff recipe (`versions` + two `fetch`es) since the CLI has
|
|
7
|
+
* no dedicated `cleo docs diff` verb yet, and forces the Deprecated
|
|
8
|
+
* direct-filesystem section to stay in the file.
|
|
9
|
+
*
|
|
10
|
+
* @task T9642
|
|
11
|
+
* @epic T9629
|
|
12
|
+
* @saga T9625
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
import { dirname, join, resolve } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import { describe, expect, it } from 'vitest';
|
|
19
|
+
|
|
20
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
21
|
+
const skillRoot = resolve(dirname(thisFile), '..');
|
|
22
|
+
const skillPath = join(skillRoot, 'SKILL.md');
|
|
23
|
+
const skillContent = readFileSync(skillPath, 'utf-8');
|
|
24
|
+
|
|
25
|
+
describe('ct-docs-review SKILL.md — SDK-first contract (T9642)', () => {
|
|
26
|
+
it('teaches `cleo docs fetch` as the canonical read path', () => {
|
|
27
|
+
expect(skillContent).toContain('cleo docs fetch');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('documents fetch by slug, attachment ID, AND SHA-256', () => {
|
|
31
|
+
expect(skillContent).toMatch(/By slug/i);
|
|
32
|
+
expect(skillContent).toMatch(/By attachment ID/i);
|
|
33
|
+
expect(skillContent).toMatch(/By SHA-256/i);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('documents the version-diff recipe (no dedicated `cleo docs diff` verb yet)', () => {
|
|
37
|
+
expect(skillContent).toContain('cleo docs versions');
|
|
38
|
+
// The diff recipe MUST show two fetches piped to `diff`
|
|
39
|
+
expect(skillContent).toMatch(/cleo docs fetch[\s\S]+cleo docs fetch[\s\S]+diff/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('teaches `cleo docs list --type` for candidate discovery', () => {
|
|
43
|
+
expect(skillContent).toMatch(/cleo docs list\s+--type/);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('shows `cleo docs status` for SSoT drift detection in PR review mode', () => {
|
|
47
|
+
expect(skillContent).toContain('cleo docs status');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('marks the old direct-filesystem read path as deprecated', () => {
|
|
51
|
+
expect(skillContent).toContain('Deprecated: Direct filesystem');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Inline Comment Patterns
|
|
2
|
+
|
|
3
|
+
How to construct individual review comments that are concrete,
|
|
4
|
+
actionable, and respectful. Each pattern below covers a common
|
|
5
|
+
review situation with a template and a worked example.
|
|
6
|
+
|
|
7
|
+
## Anatomy of a Good Comment
|
|
8
|
+
|
|
9
|
+
A review comment has four parts:
|
|
10
|
+
|
|
11
|
+
1. **Title line.** `**Issue N: [Brief title]**` — always.
|
|
12
|
+
2. **Location.** Line number or "throughout the file".
|
|
13
|
+
3. **Description.** What's wrong, one sentence.
|
|
14
|
+
4. **Suggestion.** Concrete fix, copy-paste-ready when possible.
|
|
15
|
+
|
|
16
|
+
Skipping any part degrades the comment. Skipping the title makes
|
|
17
|
+
issues unfindable; skipping location makes the fix scope unclear;
|
|
18
|
+
skipping description makes the rule arbitrary; skipping suggestion
|
|
19
|
+
makes the comment unactionable.
|
|
20
|
+
|
|
21
|
+
## Pattern: Single-Line Fix
|
|
22
|
+
|
|
23
|
+
When the fix is a one-line replacement, use the GitHub `suggestion`
|
|
24
|
+
block.
|
|
25
|
+
|
|
26
|
+
````text
|
|
27
|
+
**Issue 1: Missing contraction**
|
|
28
|
+
|
|
29
|
+
Line 15: CLEO docs use contractions. Change "cannot" to "can't".
|
|
30
|
+
|
|
31
|
+
```suggestion
|
|
32
|
+
You can't run this command on a dirty tree.
|
|
33
|
+
```
|
|
34
|
+
````
|
|
35
|
+
|
|
36
|
+
The suggestion block renders as a one-click "Commit suggestion"
|
|
37
|
+
button. Author applies it without leaving the PR view.
|
|
38
|
+
|
|
39
|
+
## Pattern: Multi-Line Fix
|
|
40
|
+
|
|
41
|
+
When the fix spans multiple lines, use a diff fence.
|
|
42
|
+
|
|
43
|
+
````text
|
|
44
|
+
**Issue 2: Buried lead**
|
|
45
|
+
|
|
46
|
+
Lines 14-18: The action is buried in the third sentence. Lead with it.
|
|
47
|
+
|
|
48
|
+
Suggested fix:
|
|
49
|
+
|
|
50
|
+
```diff
|
|
51
|
+
-Configuration files in CLEO support various format options including
|
|
52
|
+
-JSON, YAML, and TOML. When choosing a format, consider readability,
|
|
53
|
+
-merge-conflict friendliness, and editor support. Use JSON for the
|
|
54
|
+
-primary config file because it's the project default.
|
|
55
|
+
+Use JSON for the primary CLEO config file (the project default).
|
|
56
|
+
+CLEO also supports YAML and TOML if your team prefers them.
|
|
57
|
+
```
|
|
58
|
+
````
|
|
59
|
+
|
|
60
|
+
The diff fence shows before and after side-by-side. No one-click apply,
|
|
61
|
+
but the structure is clear.
|
|
62
|
+
|
|
63
|
+
## Pattern: Pattern Issue (Throughout File)
|
|
64
|
+
|
|
65
|
+
When the same issue appears in multiple places, flag once with
|
|
66
|
+
representative examples — not once per occurrence.
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
**Issue 4: "Users" instead of "people"**
|
|
70
|
+
|
|
71
|
+
The word "users" appears throughout the file (lines 8, 14, 22, 37, 51,
|
|
72
|
+
68). CLEO docs say "people" or "companies".
|
|
73
|
+
|
|
74
|
+
Examples to fix:
|
|
75
|
+
- Line 8: "users can configure" → "people can configure"
|
|
76
|
+
- Line 22: "our users expect" → "our customers expect"
|
|
77
|
+
- Line 51: "user input" → "what people type"
|
|
78
|
+
|
|
79
|
+
Apply the same pattern to remaining instances.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This compresses a 6-comment flood into a 1-comment summary. The author
|
|
83
|
+
gets the message without scrolling through duplicates.
|
|
84
|
+
|
|
85
|
+
## Pattern: Question (Clarification Needed)
|
|
86
|
+
|
|
87
|
+
Sometimes the issue is "I don't understand the intent". Phrase as a
|
|
88
|
+
question, not a demand.
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
**Issue 5: Ambiguous step**
|
|
92
|
+
|
|
93
|
+
Line 33: "Configure the cache before deployment."
|
|
94
|
+
|
|
95
|
+
The step doesn't say HOW to configure the cache or WHERE to deploy.
|
|
96
|
+
Is this the production cache or the dev cache? Should it reference
|
|
97
|
+
the `cacheTimeout` config or the `cacheStore` setting?
|
|
98
|
+
|
|
99
|
+
Suggested expansion:
|
|
100
|
+
"Set `cacheTimeout` to 30000 (30s) in `cleo.config.json` before
|
|
101
|
+
deploying to production."
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Questions are respectful — they assume the author had a reason and
|
|
105
|
+
you're inviting them to make it visible.
|
|
106
|
+
|
|
107
|
+
## Pattern: Code-Example Failure
|
|
108
|
+
|
|
109
|
+
When a code example wouldn't run, show the error.
|
|
110
|
+
|
|
111
|
+
````text
|
|
112
|
+
**Issue 6: Code example doesn't compile**
|
|
113
|
+
|
|
114
|
+
Lines 42-46: The TypeScript example imports `defineRelations` from
|
|
115
|
+
`drizzle-orm`, but the function isn't exported from the top-level
|
|
116
|
+
package in v0.x — it's in `drizzle-orm/relations`.
|
|
117
|
+
|
|
118
|
+
Tested:
|
|
119
|
+
```bash
|
|
120
|
+
$ npx tsc --noEmit example.ts
|
|
121
|
+
example.ts:1:10 - error TS2305: Module '"drizzle-orm"' has no
|
|
122
|
+
exported member 'defineRelations'.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Either:
|
|
126
|
+
- Import from the subpath: `import { defineRelations } from "drizzle-orm/relations";`
|
|
127
|
+
- Or cite the version that has the top-level export (v1.0.0-beta and later)
|
|
128
|
+
````
|
|
129
|
+
|
|
130
|
+
The error excerpt gives the author proof. Without it, the author may
|
|
131
|
+
push back ("works on my machine"); with it, the issue is unambiguous.
|
|
132
|
+
|
|
133
|
+
## Pattern: Style Choice with Rationale
|
|
134
|
+
|
|
135
|
+
When flagging style violations, cite the rule. Don't enforce personal
|
|
136
|
+
preference disguised as style.
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
**Issue 7: Formal language**
|
|
140
|
+
|
|
141
|
+
Line 27 uses "utilize" — too formal for CLEO docs. Use "use".
|
|
142
|
+
|
|
143
|
+
Source: CLEO style guide §Conversational Pillar — "utilize" is on
|
|
144
|
+
the avoid-list because it's just "use" wearing a suit.
|
|
145
|
+
|
|
146
|
+
```suggestion
|
|
147
|
+
Use the orchestrator to dispatch wave 3.
|
|
148
|
+
```
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The source line lets the author verify the rule. Without it, the
|
|
152
|
+
flag feels arbitrary.
|
|
153
|
+
|
|
154
|
+
## Pattern: Praise (Sometimes)
|
|
155
|
+
|
|
156
|
+
When the doc does something particularly well, a short positive note
|
|
157
|
+
can be valuable feedback. Keep them sparse — too much praise reads as
|
|
158
|
+
performative.
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
**Issue 8 (note, not a fix): Excellent structure**
|
|
162
|
+
|
|
163
|
+
The migration table at lines 60-75 is exactly the right pattern for
|
|
164
|
+
a v0.x → v1.x guide — current API, new API, mapping. Consider
|
|
165
|
+
extracting this table format into a shared template for future
|
|
166
|
+
migration docs.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Note: even praise gets a number — sequential numbering throughout.
|
|
170
|
+
|
|
171
|
+
## Anti-Patterns
|
|
172
|
+
|
|
173
|
+
### "This is wrong" (no fix)
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
BAD:
|
|
177
|
+
**Issue 9: Wrong**
|
|
178
|
+
Line 22 is wrong.
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
No location specificity, no description, no fix. Useless.
|
|
182
|
+
|
|
183
|
+
### "Maybe consider perhaps"
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
BAD:
|
|
187
|
+
**Issue 10: Possibly an issue**
|
|
188
|
+
Line 33: This might be slightly suboptimal, maybe consider...
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Hedging tells the author you don't trust your own judgment. Either
|
|
192
|
+
flag it confidently or skip it.
|
|
193
|
+
|
|
194
|
+
### "Bikeshedding"
|
|
195
|
+
|
|
196
|
+
```text
|
|
197
|
+
BAD:
|
|
198
|
+
**Issue 11: Two spaces**
|
|
199
|
+
Line 18 has two spaces after the period — CLEO docs use one.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
If the rule isn't material to readers, don't flag it. Whitespace
|
|
203
|
+
between sentences is invisible in rendered markdown.
|
|
204
|
+
|
|
205
|
+
### "Personal preference disguised as rule"
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
BAD:
|
|
209
|
+
**Issue 12: I'd write this differently**
|
|
210
|
+
Line 41 isn't how I'd phrase it — I'd say...
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Style preference is not a rule. Either it's in the style guide (cite
|
|
214
|
+
it) or it's not (skip the flag).
|
|
215
|
+
|
|
216
|
+
### "Compound issue"
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
BAD:
|
|
220
|
+
**Issue 13: Multiple problems**
|
|
221
|
+
Line 22 has formal tone, a vague heading, and a missing serial comma.
|
|
222
|
+
Also lines 30-35 have user-construct issues.
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Split into separate numbered issues. The author may want to fix one
|
|
226
|
+
but not the others; combined flags can't be resolved partially.
|
|
227
|
+
|
|
228
|
+
## Length Discipline
|
|
229
|
+
|
|
230
|
+
Keep each comment short. 3-6 lines for the description; 3-10 lines
|
|
231
|
+
for the suggestion block.
|
|
232
|
+
|
|
233
|
+
Long comments lose the author. If the explanation needs 20 lines, you
|
|
234
|
+
might be over-explaining — trust the author to understand the rule
|
|
235
|
+
after the suggestion.
|
|
236
|
+
|
|
237
|
+
## Tone
|
|
238
|
+
|
|
239
|
+
Comments are feedback, not judgment. Aim for:
|
|
240
|
+
|
|
241
|
+
- **Specific** — "line 22 uses X" not "the writing feels wrong"
|
|
242
|
+
- **Concrete** — show the fix, don't describe it
|
|
243
|
+
- **Respectful** — assume the author had a reason; don't assume bad faith
|
|
244
|
+
- **Time-respecting** — short over long; one issue per comment
|
|
245
|
+
|
|
246
|
+
## Comment Lifecycle
|
|
247
|
+
|
|
248
|
+
After the author addresses feedback, the comment can be:
|
|
249
|
+
|
|
250
|
+
- **Resolved** — author marks the conversation resolved when fixed
|
|
251
|
+
- **Unresolved** — left as historical record if not addressed
|
|
252
|
+
- **Updated** — reviewer adds follow-up after author's fix
|
|
253
|
+
|
|
254
|
+
The skill doesn't need to track resolution — that's GitHub's job. But
|
|
255
|
+
when re-reviewing, scan unresolved threads to see what's still pending.
|
|
256
|
+
|
|
257
|
+
## Cross-Reference to Other Comments
|
|
258
|
+
|
|
259
|
+
When two issues are related, reference the prior issue's number:
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
**Issue 14: Related to Issue 3**
|
|
263
|
+
|
|
264
|
+
Line 47 has the same "users" problem as Issue 3. Apply the same fix
|
|
265
|
+
here too.
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
This compresses the review and shows the author the pattern.
|