@codenhub/skills 0.0.2

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.
Files changed (43) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +53 -0
  3. package/dist/cli.js +213 -0
  4. package/package.json +36 -0
  5. package/src/agents-md-improver/SKILL.md +216 -0
  6. package/src/agents-md-improver/agents/openai.yaml +4 -0
  7. package/src/agents-md-improver/references/quality-criteria.md +116 -0
  8. package/src/agents-md-improver/references/templates.md +255 -0
  9. package/src/agents-md-improver/references/update-guidelines.md +155 -0
  10. package/src/brainstorming/SKILL.md +118 -0
  11. package/src/brainstorming/agents/openai.yaml +4 -0
  12. package/src/caveman/SKILL.md +59 -0
  13. package/src/caveman/agents/openai.yaml +4 -0
  14. package/src/caveman-commit/SKILL.md +68 -0
  15. package/src/caveman-commit/agents/openai.yaml +4 -0
  16. package/src/caveman-review/SKILL.md +54 -0
  17. package/src/caveman-review/agents/openai.yaml +4 -0
  18. package/src/cli.test.ts +102 -0
  19. package/src/cli.ts +311 -0
  20. package/src/executing-plans/SKILL.md +92 -0
  21. package/src/executing-plans/agents/openai.yaml +4 -0
  22. package/src/frontend-design/SKILL.md +60 -0
  23. package/src/frontend-design/agents/openai.yaml +4 -0
  24. package/src/subagent-specialist/SKILL.md +226 -0
  25. package/src/subagent-specialist/agents/openai.yaml +4 -0
  26. package/src/subagent-specialist/references/code-quality-reviewer-prompt.md +48 -0
  27. package/src/subagent-specialist/references/implementer-prompt.md +84 -0
  28. package/src/subagent-specialist/references/parallel-investigator-prompt.md +49 -0
  29. package/src/subagent-specialist/references/spec-reviewer-prompt.md +52 -0
  30. package/src/test-driven-development/SKILL.md +239 -0
  31. package/src/test-driven-development/agents/openai.yaml +11 -0
  32. package/src/test-driven-development/testing-anti-patterns.md +162 -0
  33. package/src/test-driven-development/verification-baselines.md +42 -0
  34. package/src/writing-plans/SKILL.md +169 -0
  35. package/src/writing-plans/agents/openai.yaml +4 -0
  36. package/src/writing-skills/SKILL.md +222 -0
  37. package/src/writing-skills/agents/openai.yaml +4 -0
  38. package/src/writing-skills/best-practices.md +321 -0
  39. package/src/writing-skills/examples/SKILL_AUTHORING_GUIDE_TESTING.md +156 -0
  40. package/src/writing-skills/persuasion-principles.md +172 -0
  41. package/src/writing-skills/testing-skills-with-subagents.md +310 -0
  42. package/src/writing-specs/SKILL.md +72 -0
  43. package/src/writing-specs/agents/openai.yaml +4 -0
@@ -0,0 +1,155 @@
1
+ # AGENTS.md Update Guidelines
2
+
3
+ ## Core Principle
4
+
5
+ Only add information that will genuinely help future agent sessions. Attention
6
+ and context are limited, so every line must earn its place.
7
+
8
+ ## What TO Add
9
+
10
+ ### 1. Commands or Workflows Discovered
11
+
12
+ ```markdown
13
+ ## Build
14
+
15
+ `npm run build:prod` - Full production build with optimization
16
+ `npm run build:dev` - Fast development build without minification
17
+ ```
18
+
19
+ Why: Saves future sessions from rediscovering these commands.
20
+
21
+ ### 2. Gotchas and Non-Obvious Patterns
22
+
23
+ ```markdown
24
+ ## Gotchas
25
+
26
+ - Tests must run sequentially (`--runInBand`) due to shared DB state
27
+ - `yarn.lock` is authoritative; delete `node_modules` if deps mismatch
28
+ ```
29
+
30
+ Why: Prevents repeated debugging sessions.
31
+
32
+ ### 3. Package Relationships
33
+
34
+ ```markdown
35
+ ## Dependencies
36
+
37
+ The `auth` module depends on `crypto` being initialized first.
38
+ Import order matters in `src/bootstrap.ts`.
39
+ ```
40
+
41
+ Why: Captures architecture knowledge that is not obvious from the code alone.
42
+
43
+ ### 4. Testing Approaches That Worked
44
+
45
+ ```markdown
46
+ ## Testing
47
+
48
+ For API endpoints: Use `supertest` with the helper in `tests/setup.ts`
49
+ Mocking: Factory functions in `tests/factories/` instead of inline mocks
50
+ ```
51
+
52
+ Why: Establishes patterns that are known to work.
53
+
54
+ ### 5. Configuration Quirks
55
+
56
+ ```markdown
57
+ ## Config
58
+
59
+ - `NEXT_PUBLIC_*` variables must be set at build time, not runtime
60
+ - Redis connection requires the `?family=0` suffix for IPv6
61
+ ```
62
+
63
+ Why: Preserves environment-specific knowledge.
64
+
65
+ ## What NOT to Add
66
+
67
+ ### 1. Obvious Code Information
68
+
69
+ Bad:
70
+
71
+ ```markdown
72
+ The `UserService` class handles user operations.
73
+ ```
74
+
75
+ The class name already tells us this.
76
+
77
+ ### 2. Generic Best Practices
78
+
79
+ Bad:
80
+
81
+ ```markdown
82
+ Always write tests for new features.
83
+ Use meaningful variable names.
84
+ ```
85
+
86
+ This is universal advice, not project-specific guidance.
87
+
88
+ ### 3. One-Off Fixes
89
+
90
+ Bad:
91
+
92
+ ```markdown
93
+ We fixed a bug in commit abc123 where the login button did not work.
94
+ ```
95
+
96
+ It will not help future sessions and only adds clutter.
97
+
98
+ ### 4. Verbose Explanations
99
+
100
+ Bad:
101
+
102
+ ```markdown
103
+ The authentication system uses JWT tokens. JWT (JSON Web Tokens) are
104
+ an open standard that defines a compact and self-contained way for securely
105
+ transmitting information between parties as a JSON object. In our
106
+ implementation, we use the HS256 algorithm which...
107
+ ```
108
+
109
+ Good:
110
+
111
+ ```markdown
112
+ Auth: JWT with HS256, tokens in `Authorization: Bearer <token>`.
113
+ ```
114
+
115
+ ## Diff Format for Updates
116
+
117
+ For each suggested change:
118
+
119
+ ### 1. Identify the File
120
+
121
+ ```text
122
+ File: ./AGENTS.md
123
+ Section: Commands (new section after ## Architecture)
124
+ ```
125
+
126
+ ### 2. Show the Change
127
+
128
+ ```diff
129
+ ## Architecture
130
+ ...
131
+
132
+ +## Commands
133
+ +
134
+ +| Command | Purpose |
135
+ +|---------|---------|
136
+ +| `npm run dev` | Dev server with HMR |
137
+ +| `npm run build` | Production build |
138
+ +| `npm test` | Run test suite |
139
+ ```
140
+
141
+ ### 3. Explain Why
142
+
143
+ > **Why this helps:** The build commands were not documented, which forces
144
+ > future sessions to inspect `package.json` before they can work efficiently.
145
+
146
+ ## Validation Checklist
147
+
148
+ Before finalizing an update, verify:
149
+
150
+ - [ ] Each addition is project-specific
151
+ - [ ] There is no generic advice or obvious information
152
+ - [ ] Commands are tested or otherwise verified
153
+ - [ ] File paths are accurate
154
+ - [ ] A new agent session would actually find this helpful
155
+ - [ ] This is the most concise way to express the information
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: brainstorming
3
+ description: "Use when the work needs collaborative design before implementation, especially for new features, behavior changes, or unclear requirements. Explores user intent, requirements, and design before implementation."
4
+ metadata:
5
+ short-description: Brainstorm ideas into approved designs
6
+ ---
7
+
8
+ # Brainstorming Ideas Into Designs
9
+
10
+ Help turn ideas into fully formed designs through natural collaborative dialogue. Start by understanding the current project context, then ask simple, direct questions to refine the idea.
11
+
12
+ Once you understand what you're building, present the design and get user approval before any implementation action. Do NOT invoke any implementation skill, write any code, scaffold any project, or take any implementation action until you have presented a design and the user has approved it. Design approval does not approve the spec, the plan, or implementation. After approval, invoke `writing-specs` when the user wants the design documented or wants to continue through the default spec-first pipeline. If the user explicitly wants brainstorming only, stop after the approved design. If the next step is unclear, ask one short question such as `Do you want more planning first, or should I proceed to the change?` instead of assuming a handoff.
13
+
14
+ ## Anti-Pattern: "This Is Too Simple To Need A Design"
15
+
16
+ Do not skip design just because something looks simple if there is any meaningful choice about behavior, interface, structure, or constraints.
17
+
18
+ For trivial, low-risk work with one obvious shape, keep the design lightweight: confirm the goal, state the intended approach briefly, and get acknowledgement before moving on. If you are unsure whether the work is trivial, treat it as non-trivial.
19
+
20
+ ## Checklist
21
+
22
+ Use these stages as the default flow. For complex work, cover them all. For simple work, collapse them into the lightest version that still confirms the design before implementation. Track them explicitly when the environment supports task tracking:
23
+
24
+ 1. **Explore project context** - inspect enough of the project to understand current patterns and constraints; if the request is obviously too large for one design/spec, do only enough to confirm that and decompose first
25
+ 2. **Ask clarifying questions** - keep them simple and direct; group closely related easy questions when they can be answered together; separate questions that need discussion
26
+ 3. **Propose options** - compare 2-3 approaches when there are meaningful choices; otherwise state the single obvious approach and why it is sufficient
27
+ 4. **Present design** - for complex work, present the design in sections, get a response on each section, revisit any deferred or partial approvals, then give a short summary of the full design and get one final approval; for simple work, a single concise design and one approval is enough
28
+ 5. **Transition or stop** - invoke `writing-specs` when the approved design should be documented or carried forward in the default pipeline; if the user wants to proceed directly, complete brainstorming and hand off to implementation outside this skill; if the user explicitly wants brainstorming only, stop after the approved design; if the next step is unclear, ask one short question
29
+
30
+ ## Tool Compatibility
31
+
32
+ - Keep instructions tool-agnostic and avoid provider-specific wording.
33
+ - When behavior differs across tools, resolve conflicts in this order: OpenCode > Claude Code > Codex CLI > Gemini CLI.
34
+
35
+ ## Process Flow
36
+
37
+ ```text
38
+ Explore project context
39
+ -> If the request is too large for one design/spec: decompose it immediately, recommend the first sub-project, get agreement on that slice, then continue
40
+ -> Ask simple, direct questions
41
+ -> Propose options when there are real choices
42
+ -> Present design
43
+ -> complex work: section response -> revisit deferred/partial items -> final summary -> final approval
44
+ -> simple work: concise design -> approval
45
+ -> Final design approved?
46
+ -> no: revise and continue
47
+ -> yes + wants documentation or wants to continue in the default pipeline: invoke writing-specs
48
+ -> yes + wants to proceed directly: brainstorming complete; end this skill and hand off to the implementation phase
49
+ -> yes + explicitly wants brainstorming only: stop after the approved design
50
+ -> yes + next step unclear: ask one short question
51
+ ```
52
+
53
+ Do NOT invoke `frontend-design` or any other implementation skill from brainstorming. If the user wants to proceed directly, finish brainstorming first, then let implementation happen as the next phase outside this skill.
54
+
55
+ Invoke `writing-specs` only when the approved design should be documented or used to continue into the default pipeline. If the user explicitly wants to stop at brainstorming, defer documentation, or proceed directly to the change, do not force it. When the user's intent is unclear after final design approval, ask one short question such as `Do you want more planning first, or should I proceed to the change?`.
56
+
57
+ ## The Process
58
+
59
+ **Understanding the idea:**
60
+
61
+ - Inspect enough of the current project state first: relevant files, docs, or recent commits when helpful. If the request is obviously too large for one design/spec, do only enough inspection to confirm that and move straight to decomposition.
62
+ - Decide whether the request needs the full brainstorming flow or a lightweight design confirmation. Use the full flow for new functionality, behavior changes, unclear requirements, multiple reasonable approaches, or work that spans multiple components. For trivial, low-risk, self-evident changes with one obvious path, keep the design brief but still confirm it before moving on. If unsure, use the full flow.
63
+ - Before asking detailed questions, assess scope. If the request describes multiple independent subsystems, for example "build a platform with chat, file storage, billing, and analytics", flag this immediately. Do not spend questions refining details of a project that needs to be decomposed first.
64
+ - If the project is too large for a single spec, decompose it into sub-projects, recommend the first sub-project to tackle, and get agreement on that slice before going deeper. Then brainstorm that sub-project through the normal design flow. In the default workflow, each sub-project gets its own spec-first cycle before implementation; if the user wants a different handoff, follow that intent.
65
+ - For appropriately scoped projects, ask simple, direct questions to refine the idea.
66
+ - Group closely related easy questions when the user can answer them together. If a question is complex, high-impact, or likely to need back-and-forth, ask it by itself.
67
+ - Prefer multiple choice questions when possible, but open-ended is fine too.
68
+ - Focus on understanding: purpose, constraints, success criteria.
69
+
70
+ **Exploring approaches:**
71
+
72
+ - When there are materially different reasonable options, propose 2-3 different approaches with trade-offs.
73
+ - For trivial or single-path work, state the chosen approach and why it is sufficient.
74
+ - Present options conversationally with your recommendation and reasoning.
75
+ - Lead with your recommended option and explain why.
76
+
77
+ **Presenting the design:**
78
+
79
+ - Once you believe you understand what you're building, present the design.
80
+ - For complex work with multiple decisions or issues, split the design into sections. Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced.
81
+ - Ask after each section whether it looks right so far.
82
+ - Partial approvals and deferrals are fine, but track every unresolved point and revisit it before the final summary.
83
+ - After the last section, give a short summary of the whole design and ask for one final approval. Do not treat the design as fully approved until this final approval happens.
84
+ - For simple, obvious work, skip the sectioned flow and present one concise design for approval.
85
+ - For complex work, cover architecture, components, data flow, error handling, and testing. For simple work, cover only the parts that matter.
86
+ - Be ready to go back and clarify if something does not make sense.
87
+
88
+ **Design for isolation and clarity:**
89
+
90
+ - Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently.
91
+ - For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?
92
+ - Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.
93
+ - Smaller, well-bounded units are also easier for you to work with. You reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that is often a signal that it is doing too much.
94
+
95
+ **Working in existing codebases:**
96
+
97
+ - Explore the current structure before proposing changes. Follow existing patterns.
98
+ - Where existing code has problems that affect the work, for example a file that has grown too large, unclear boundaries, or tangled responsibilities, include targeted improvements as part of the design, the way a good developer improves code they are working in.
99
+ - Do not propose unrelated refactoring. Stay focused on what serves the current goal.
100
+
101
+ ## After the Design
102
+
103
+ **Documentation:**
104
+
105
+ - Invoke `writing-specs` to write the validated design to a spec document when the approved design should be documented or carried forward.
106
+ - If the user explicitly wants brainstorming only or to defer documentation, stop after the approved design instead of forcing a handoff.
107
+ - If the user wants to keep going but it is unclear whether they want more planning or direct implementation, ask `Do you want more planning first, or should I proceed to the change?`.
108
+ - If the user explicitly wants to proceed directly, do not force `writing-specs`.
109
+ - Keep `writing-specs` as the default handoff for documented, spec-first work. If the user explicitly asks to do planning next, you may invoke `writing-plans` directly instead.
110
+
111
+ ## Key Principles
112
+
113
+ - **Simple questions first** - Ask simple, direct questions. Group closely related easy questions when useful, and separate questions that need discussion.
114
+ - **Multiple choice preferred** - Easier to answer than open-ended when possible.
115
+ - **YAGNI ruthlessly** - Remove unnecessary features from all designs.
116
+ - **Explore alternatives** - Propose 2-3 approaches when there are real choices; otherwise state the single obvious approach.
117
+ - **Incremental validation** - For complex work, get section responses, revisit any deferred or partial items, and always finish with final whole-design approval. For simple work, one approval is enough.
118
+ - **Be flexible** - Go back and clarify when something does not make sense.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Brainstorming"
3
+ short_description: "Turn ideas into approved designs before coding"
4
+ default_prompt: "Use $brainstorming to explore the idea before coding: inspect enough context to understand the request, ask simple direct questions, group closely related easy questions when useful, and compare meaningful approaches. If the request is too large for one design, decompose it immediately, recommend the first slice, and get agreement on that slice before going deeper. For complex work, present the design in sections, revisit deferred or partial approvals, then give a short final summary and require final approval before treating the design as approved. For simple work, keep it lightweight. After approval, invoke `writing-specs` only when the user wants documentation or the default pipeline, and invoke `writing-plans` directly when the user explicitly asks to plan next; if the user wants to proceed directly, end brainstorming and hand off to implementation, and if the next step is unclear, ask whether they want more planning or you should proceed to the change."
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: caveman
3
+ description: Ultra-compressed communication mode. Supports intensity levels: lite, full (default), ultra. Use when user explicitly requests or token efficiency is requested.
4
+ ---
5
+
6
+ Respond terse like smart caveman. All technical substance stay. Only fluff die.
7
+
8
+ ## Persistence
9
+
10
+ ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode".
11
+
12
+ Default: **full**. Switch (lite|full|ultra) only if user explicitly asks.
13
+
14
+ ## Rules
15
+
16
+ Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Technical terms exact. Code blocks unchanged. Errors quoted exact.
17
+
18
+ Pattern: `[thing] [action] [reason]. [next step].`
19
+
20
+ Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
21
+ Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"
22
+
23
+ ## Intensity
24
+
25
+ | Level | What change |
26
+ | --------- | ---------------------------------------------------------------------------------------------------------------------------- |
27
+ | **lite** | No filler/hedging. Keep articles + full sentences. Professional but tight |
28
+ | **full** | Drop articles, fragments OK, short synonyms. Classic caveman |
29
+ | **ultra** | Abbreviate (DB/auth/config/req/res/fn/impl), strip conjunctions, arrows for causality (X → Y), one word when one word enough |
30
+
31
+ Example — "Why React component re-render?"
32
+
33
+ - lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`."
34
+ - full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
35
+ - ultra: "Inline obj prop → new ref → re-render. `useMemo`."
36
+
37
+ Example — "Explain database connection pooling."
38
+
39
+ - lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead."
40
+ - full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."
41
+ - ultra: "Pool = reuse DB conn. Skip handshake → fast under load."
42
+
43
+ ## Auto-Clarity
44
+
45
+ Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question. Resume caveman after clear part done.
46
+
47
+ Example — destructive op:
48
+
49
+ > **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.
50
+ >
51
+ > ```sql
52
+ > DROP TABLE users;
53
+ > ```
54
+ >
55
+ > Caveman resume. Verify backup exist first.
56
+
57
+ ## Boundaries
58
+
59
+ Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Level persist until changed or session end.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Caveman"
3
+ short_description: "Speak tersely with full technical accuracy"
4
+ default_prompt: "Use $caveman to respond in ultra-compressed caveman mode with full technical accuracy, default to full intensity unless the user explicitly asks for lite or ultra, keep code and formal artifacts in normal style, and switch to clearer prose whenever safety or sequencing matters more than brevity."
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: caveman-commit
3
+ description: Ultra-compressed commit message generator. Cuts noise from commit messages while preserving intent and reasoning. Conventional Commits format. Subject ≤50 chars, body only when "why" isn't obvious. Use when user says "write a commit", "commit message", "generate commit". Auto-triggers when staging changes.
4
+ ---
5
+
6
+ Write commit messages terse and exact. Conventional Commits format. No fluff. Why over what.
7
+
8
+ ## Rules
9
+
10
+ **Subject line:**
11
+
12
+ - `<type>(<scope>): <imperative summary>` — `<scope>` optional
13
+ - Types: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `chore`, `build`, `ci`, `style`, `revert`
14
+ - Imperative mood: "add", "fix", "remove" — not "added", "adds", "adding"
15
+ - ≤50 chars when possible, hard cap 72
16
+ - No trailing period
17
+ - Match project convention for capitalization after the colon
18
+
19
+ **Body (only if needed):**
20
+
21
+ - Skip entirely when subject is self-explanatory
22
+ - Add body only for: non-obvious _why_, breaking changes, migration notes, linked issues
23
+ - Wrap at 72 chars
24
+ - Bullets `-` not `*`
25
+ - Reference issues/PRs at end: `Closes #42`, `Refs #17`
26
+
27
+ **What NEVER goes in:**
28
+
29
+ - "This commit does X", "I", "we", "now", "currently" — the diff says what
30
+ - "As requested by..." — use Co-authored-by trailer
31
+ - "Generated with Claude Code" or any AI attribution
32
+ - Emoji (unless project convention requires)
33
+ - Restating the file name when scope already says it
34
+
35
+ ## Examples
36
+
37
+ Diff: new endpoint for user profile with body explaining the why
38
+
39
+ - ❌ "feat: add a new endpoint to get user profile information from the database"
40
+ - ✅
41
+
42
+ ```
43
+ feat(api): add GET /users/:id/profile
44
+
45
+ Mobile client needs profile data without the full user payload
46
+ to reduce LTE bandwidth on cold-launch screens.
47
+
48
+ Closes #128
49
+ ```
50
+
51
+ Diff: breaking API change
52
+
53
+ - ✅
54
+
55
+ ```
56
+ feat(api)!: rename /v1/orders to /v1/checkout
57
+
58
+ BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout
59
+ before 2026-06-01. Old route returns 410 after that date.
60
+ ```
61
+
62
+ ## Auto-Clarity
63
+
64
+ Always include body for: breaking changes, security fixes, data migrations, anything reverting a prior commit. Never compress these into subject-only — future debuggers need the context.
65
+
66
+ ## Boundaries
67
+
68
+ Only generates the commit message. Does not run `git commit`, does not stage files, does not amend. Output the message as a code block ready to paste. "stop caveman-commit" or "normal mode": revert to verbose commit style.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Caveman Commit"
3
+ short_description: "Generate terse Conventional Commit messages"
4
+ default_prompt: "Use $caveman-commit to generate a terse Conventional Commit message focused on why over what, keep the subject concise, add a body only when needed, and always include fuller context for breaking changes, security fixes, data migrations, or reverts."
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: caveman-review
3
+ description: Ultra-compressed code review comments. Cuts noise from PR feedback while preserving actionable signal. Each comment is one line: location, problem, fix. Use when explicitly requested by the user or when reviewing PRs.
4
+ ---
5
+
6
+ Write code review comments terse and actionable. One line per finding. Location, problem, fix. No throat-clearing.
7
+
8
+ ## Rules
9
+
10
+ **Format:** `L<line>: <problem>. <fix>.` — or `<file>:L<line>: ...` when reviewing multi-file diffs.
11
+
12
+ **Severity prefix (optional, when mixed):**
13
+
14
+ - `🔴 bug:` — broken behavior, will cause incident
15
+ - `🟡 risk:` — works but fragile (race, missing null check, swallowed error)
16
+ - `🔵 nit:` — style, naming, micro-optim. Author can ignore
17
+ - `❓ q:` — genuine question, not a suggestion
18
+
19
+ **Drop:**
20
+
21
+ - "I noticed that...", "It seems like...", "You might want to consider..."
22
+ - "This is just a suggestion but..." — use `nit:` instead
23
+ - "Great work!", "Looks good overall but..." — say it once at the top, not per comment
24
+ - Restating what the line does — the reviewer can read the diff
25
+ - Hedging ("perhaps", "maybe", "I think") — if unsure use `q:`
26
+
27
+ **Keep:**
28
+
29
+ - Exact line numbers
30
+ - Exact symbol/function/variable names in backticks
31
+ - Concrete fix, not "consider refactoring this"
32
+ - The _why_ if the fix isn't obvious from the problem statement
33
+
34
+ ## Examples
35
+
36
+ ❌ "I noticed that on line 42 you're not checking if the user object is null before accessing the email property. This could potentially cause a crash if the user is not found in the database. You might want to add a null check here."
37
+
38
+ ✅ `L42: 🔴 bug: user can be null after .find(). Add guard before .email.`
39
+
40
+ ❌ "It looks like this function is doing a lot of things and might benefit from being broken up into smaller functions for readability."
41
+
42
+ ✅ `L88-140: 🔵 nit: 50-line fn does 4 things. Extract validate/normalize/persist.`
43
+
44
+ ❌ "Have you considered what happens if the API returns a 429? I think we should probably handle that case."
45
+
46
+ ✅ `L23: 🟡 risk: no retry on 429. Wrap in withBackoff(3).`
47
+
48
+ ## Auto-Clarity
49
+
50
+ Drop terse mode for: security findings (CVE-class bugs need full explanation + reference), architectural disagreements (need rationale, not just a one-liner), and onboarding contexts where the author is new and needs the "why". In those cases write a normal paragraph, then resume terse for the rest.
51
+
52
+ ## Boundaries
53
+
54
+ Reviews only — does not write the code fix, does not approve/request-changes, does not run linters. Output the comment(s) ready to paste into the PR. "stop caveman-review" or "normal mode": revert to verbose review style.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Caveman Review"
3
+ short_description: "Write terse one-line code review findings"
4
+ default_prompt: "Use $caveman-review to write terse actionable code review comments, one line per finding with exact line or file references, problem, and fix; only expand into normal prose for security issues, architectural disagreements, or other cases where the rationale needs more explanation."
@@ -0,0 +1,102 @@
1
+ import * as fs from "fs";
2
+ import * as os from "os";
3
+ import * as path from "path";
4
+
5
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
6
+
7
+ import { parseFrontmatter, getSkills, copyRecursiveSync } from "./cli.js";
8
+
9
+ describe("Skills Helper functions", () => {
10
+ let tempDir: string;
11
+
12
+ beforeEach(() => {
13
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "codenhub-skills-test-"));
14
+ });
15
+
16
+ afterEach(() => {
17
+ fs.rmSync(tempDir, { recursive: true, force: true });
18
+ });
19
+
20
+ describe("parseFrontmatter", () => {
21
+ it("should parse valid frontmatter", () => {
22
+ const content = `---\nname: test-skill\ndescription: A test skill description\n---\nSome markdown here`;
23
+ const meta = parseFrontmatter(content);
24
+ expect(meta).toEqual({
25
+ name: "test-skill",
26
+ description: "A test skill description",
27
+ });
28
+ });
29
+
30
+ it("should return empty object if no frontmatter", () => {
31
+ const content = "no frontmatter here";
32
+ const meta = parseFrontmatter(content);
33
+ expect(meta).toEqual({});
34
+ });
35
+ });
36
+
37
+ describe("getSkills", () => {
38
+ it("should return skills list from directory", () => {
39
+ const skill1Dir = path.join(tempDir, "skill-1");
40
+ fs.mkdirSync(skill1Dir, { recursive: true });
41
+ fs.writeFileSync(path.join(skill1Dir, "SKILL.md"), `---\nname: Skill One\ndescription: First skill\n---\n`);
42
+
43
+ const skill2Dir = path.join(tempDir, "skill-2");
44
+ fs.mkdirSync(skill2Dir, { recursive: true });
45
+ fs.writeFileSync(path.join(skill2Dir, "SKILL.md"), `---\nname: Skill Two\ndescription: Second skill\n---\n`);
46
+
47
+ // Non-skill dir (no SKILL.md)
48
+ const otherDir = path.join(tempDir, "other");
49
+ fs.mkdirSync(otherDir, { recursive: true });
50
+
51
+ const skills = getSkills(tempDir);
52
+ expect(skills).toHaveLength(2);
53
+ expect(skills.find((s) => s.id === "skill-1")).toEqual({
54
+ id: "skill-1",
55
+ name: "Skill One",
56
+ description: "First skill",
57
+ path: skill1Dir,
58
+ });
59
+ });
60
+
61
+ it("should return empty array if directory does not exist", () => {
62
+ const skills = getSkills(path.join(tempDir, "non-existent"));
63
+ expect(skills).toEqual([]);
64
+ });
65
+ });
66
+
67
+ describe("copyRecursiveSync", () => {
68
+ it("should recursively copy files and folders", () => {
69
+ const srcDir = path.join(tempDir, "src");
70
+ const destDir = path.join(tempDir, "dest");
71
+
72
+ fs.mkdirSync(path.join(srcDir, "subdir"), { recursive: true });
73
+ fs.writeFileSync(path.join(srcDir, "file1.txt"), "content 1");
74
+ fs.writeFileSync(path.join(srcDir, "subdir", "file2.txt"), "content 2");
75
+
76
+ copyRecursiveSync(srcDir, destDir);
77
+
78
+ expect(fs.existsSync(path.join(destDir, "file1.txt"))).toBe(true);
79
+ expect(fs.readFileSync(path.join(destDir, "file1.txt"), "utf8")).toBe("content 1");
80
+ expect(fs.existsSync(path.join(destDir, "subdir", "file2.txt"))).toBe(true);
81
+ expect(fs.readFileSync(path.join(destDir, "subdir", "file2.txt"), "utf8")).toBe("content 2");
82
+ });
83
+
84
+ it("should ignore paths in ignoreList", () => {
85
+ const srcDir = path.join(tempDir, "src-ignore");
86
+ const destDir = path.join(tempDir, "dest-ignore");
87
+
88
+ fs.mkdirSync(path.join(srcDir, "subdir"), { recursive: true });
89
+ fs.mkdirSync(path.join(srcDir, "ignored-dir"), { recursive: true });
90
+ fs.writeFileSync(path.join(srcDir, "file1.txt"), "content 1");
91
+ fs.writeFileSync(path.join(srcDir, "subdir", "file2.txt"), "content 2");
92
+ fs.writeFileSync(path.join(srcDir, "ignored-dir", "file3.txt"), "content 3");
93
+
94
+ copyRecursiveSync(srcDir, destDir, ["ignored-dir"]);
95
+
96
+ expect(fs.existsSync(path.join(destDir, "file1.txt"))).toBe(true);
97
+ expect(fs.existsSync(path.join(destDir, "subdir", "file2.txt"))).toBe(true);
98
+ expect(fs.existsSync(path.join(destDir, "ignored-dir"))).toBe(false);
99
+ expect(fs.existsSync(path.join(destDir, "ignored-dir", "file3.txt"))).toBe(false);
100
+ });
101
+ });
102
+ });