@ai-support-agent/cli 0.1.32 → 0.1.33-beta.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/dist/alert-processor.d.ts +0 -8
- package/dist/alert-processor.d.ts.map +1 -1
- package/dist/alert-processor.js +5 -73
- package/dist/alert-processor.js.map +1 -1
- package/dist/api-client.d.ts +0 -4
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +0 -4
- package/dist/api-client.js.map +1 -1
- package/dist/commands/claude-code-args.d.ts +1 -0
- package/dist/commands/claude-code-args.d.ts.map +1 -1
- package/dist/commands/claude-code-args.js +3 -0
- package/dist/commands/claude-code-args.js.map +1 -1
- package/dist/commands/claude-code-runner.d.ts.map +1 -1
- package/dist/commands/claude-code-runner.js +2 -1
- package/dist/commands/claude-code-runner.js.map +1 -1
- package/dist/commands/plugin-dir.d.ts +20 -0
- package/dist/commands/plugin-dir.d.ts.map +1 -0
- package/dist/commands/plugin-dir.js +71 -0
- package/dist/commands/plugin-dir.js.map +1 -0
- package/dist/constants.d.ts +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -1
- package/dist/constants.js.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +9 -0
- package/dist/plugin/LICENSE +26 -0
- package/dist/plugin/README.md +86 -0
- package/dist/plugin/SYNC.md +113 -0
- package/dist/plugin/agents/build-error-resolver.md +159 -0
- package/dist/plugin/agents/code-reviewer.md +277 -0
- package/dist/plugin/agents/django-reviewer.md +159 -0
- package/dist/plugin/agents/infra-reviewer.md +172 -0
- package/dist/plugin/agents/investigator.md +75 -0
- package/dist/plugin/agents/nextjs-reviewer.md +191 -0
- package/dist/plugin/agents/php-reviewer.md +167 -0
- package/dist/plugin/agents/planner.md +184 -0
- package/dist/plugin/agents/python-reviewer.md +161 -0
- package/dist/plugin/agents/react-reviewer.md +150 -0
- package/dist/plugin/agents/silent-failure-hunter.md +158 -0
- package/dist/plugin/agents/typescript-reviewer.md +179 -0
- package/dist/plugin/agents/ui-reviewer.md +203 -0
- package/dist/plugin/commands/add-feature.md +301 -0
- package/dist/plugin/commands/build-fix.md +47 -0
- package/dist/plugin/commands/code-review.md +228 -0
- package/dist/plugin/commands/fix-defect.md +393 -0
- package/dist/plugin/commands/learn-eval.md +94 -0
- package/dist/plugin/commands/learn.md +84 -0
- package/dist/plugin/commands/plan.md +211 -0
- package/dist/plugin/commands/test-coverage.md +64 -0
- package/dist/plugin/commands/update-docs.md +98 -0
- package/dist/plugin/hooks/hooks.json +59 -0
- package/dist/plugin/hooks/scripts/auto-format.sh +63 -0
- package/dist/plugin/hooks/scripts/check-secrets-before-commit.sh +50 -0
- package/dist/plugin/hooks/scripts/guard-dangerous-commands.sh +55 -0
- package/dist/plugin/hooks/scripts/on-command-resume.sh +112 -0
- package/dist/plugin/hooks/scripts/on-command-stop.sh +200 -0
- package/dist/plugin/hooks/scripts/protect-sensitive-files.sh +58 -0
- package/dist/plugin/rules/common/coding-guidelines.md +73 -0
- package/dist/plugin/rules/documentation/api-docs.md +46 -0
- package/dist/plugin/rules/documentation/docs-site.md +60 -0
- package/dist/plugin/rules/documentation/source-docs.md +89 -0
- package/dist/plugin/rules/documentation/test-docs.md +39 -0
- package/dist/plugin/rules/logging/logging-rules.md +83 -0
- package/dist/plugin/rules/php/coding-rules.md +40 -0
- package/dist/plugin/rules/python/coding-rules.md +40 -0
- package/dist/plugin/rules/typescript/coding-rules.md +45 -0
- package/dist/plugin/skills/api-design/SKILL.md +269 -0
- package/dist/plugin/skills/backend-patterns/SKILL.md +312 -0
- package/dist/plugin/skills/database-migrations/SKILL.md +323 -0
- package/dist/plugin/skills/docker-patterns/SKILL.md +308 -0
- package/dist/plugin/skills/docs-site/SKILL.md +341 -0
- package/dist/plugin/skills/e2e-testing/SKILL.md +334 -0
- package/dist/plugin/skills/frontend-patterns/SKILL.md +318 -0
- package/dist/plugin/skills/integration-testing/SKILL.md +273 -0
- package/package.json +2 -2
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create an implementation plan grounded in the codebase's existing patterns before writing any code, and don't start implementing until it's approved
|
|
3
|
+
argument-hint: "[free-form request | path to a requirements markdown file | leave empty]"
|
|
4
|
+
resumable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /plan - Create an implementation plan
|
|
8
|
+
|
|
9
|
+
A command for drafting an implementation plan before writing code and getting the user's approval on it.
|
|
10
|
+
It exists to prevent rework, misalignment, and drift from existing patterns that come from starting to implement without a plan.
|
|
11
|
+
|
|
12
|
+
## Interpreting the input
|
|
13
|
+
|
|
14
|
+
Evaluate `$ARGUMENTS` in this order.
|
|
15
|
+
|
|
16
|
+
1. **Path to a markdown file**: read the file and treat its contents as the requirements/reference material.
|
|
17
|
+
2. **Free-form text**: treat the text as the implementation request.
|
|
18
|
+
3. **Empty input**: ask "What would you like a plan for? Please also share the purpose, background, and any constraints," and wait for the answer before continuing.
|
|
19
|
+
|
|
20
|
+
## Procedure
|
|
21
|
+
|
|
22
|
+
### Step 1: Restate the request
|
|
23
|
+
|
|
24
|
+
Restate the request you received in your own words, in one to three sentences, and present it up front.
|
|
25
|
+
Explicitly list any points open to interpretation and any assumptions you made.
|
|
26
|
+
This step must not be skipped — it lets the user catch a mismatch between your restatement and their actual request early.
|
|
27
|
+
|
|
28
|
+
### Step 2: Clarifying questions
|
|
29
|
+
|
|
30
|
+
**This step can be skipped for trivial changes. It is required for small and larger changes.**
|
|
31
|
+
|
|
32
|
+
Organize the ambiguities and open points left over from the restatement (Step 1) using the perspectives below,
|
|
33
|
+
and ask the user about them together in one batch. Don't re-ask about anything already clear. Wait for the answer before moving to the next step.
|
|
34
|
+
|
|
35
|
+
| Perspective | What to confirm |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Target users and permissions | Who will use this feature? What permissions/preconditions are needed to operate it? |
|
|
38
|
+
| Non-functional requirements | Are there performance, throughput, or scale targets? |
|
|
39
|
+
| Backward compatibility and constraints | Must existing APIs, data formats, or external integrations be preserved? Are any technologies off-limits? |
|
|
40
|
+
| Failure behavior | What should be returned to the user on failure? Is a rollback needed? |
|
|
41
|
+
| Definition of done | What state counts as "complete"? Are there acceptance criteria? |
|
|
42
|
+
|
|
43
|
+
If there's nothing unclear, declare "No clarifying questions" and move on.
|
|
44
|
+
Fold the user's answers directly into the plan and the codebase investigation that follows.
|
|
45
|
+
|
|
46
|
+
### Step 3: Codebase investigation
|
|
47
|
+
|
|
48
|
+
Search the existing implementation for related code to ground the plan in. Investigate from these angles:
|
|
49
|
+
|
|
50
|
+
- Naming conventions (file names, class names, function names, variable names)
|
|
51
|
+
- Error-handling approach (exceptions, return values, error types, retries)
|
|
52
|
+
- Logging approach (logger type, log-level usage, output format)
|
|
53
|
+
- Data-access approach (ORM, repository layer, query style)
|
|
54
|
+
- Testing conventions (framework, file placement, naming, mocking style)
|
|
55
|
+
|
|
56
|
+
**Important**: if no similar code exists, say so honestly — "no matching existing pattern was found."
|
|
57
|
+
Never fabricate a pattern that doesn't exist. Back every claim with a real file path.
|
|
58
|
+
|
|
59
|
+
### Step 4: Draft the plan
|
|
60
|
+
|
|
61
|
+
Based on the investigation, break the implementation into phases, and break each phase into steps.
|
|
62
|
+
Attach to each step: the target file path, what to do, why, dependencies, and risk level (High/Medium/Low).
|
|
63
|
+
Also include the test strategy (whether unit/integration/E2E tests are needed and what they cover), success criteria, and an overall complexity estimate (High/Medium/Low).
|
|
64
|
+
|
|
65
|
+
For large plans — four or more phases, or more than ten affected files — you may delegate investigation and drafting to the planner subagent. Even then, this command handles the final presentation and approval check.
|
|
66
|
+
(For a 3-phase plan, write the "Interfaces between phases" section yourself as described below; delegation is for four-plus phases.)
|
|
67
|
+
|
|
68
|
+
#### No placeholders allowed
|
|
69
|
+
|
|
70
|
+
Every step in the plan must be concrete enough to execute as written.
|
|
71
|
+
Any of the following counts as **a failed plan** and must not appear:
|
|
72
|
+
|
|
73
|
+
- "TBD," "TODO," "implement later," "details elsewhere"
|
|
74
|
+
- "Add appropriate error handling," "add validation," "handle edge cases" (without saying what, specifically)
|
|
75
|
+
- A step involving a code change with no code sample
|
|
76
|
+
- "Same as Phase N" (later steps must not reference earlier ones — repeat what's needed instead)
|
|
77
|
+
- Forward references to types, functions, or methods that aren't defined until a later step (e.g., a type used in Step N but only defined in Step N+1 or later)
|
|
78
|
+
|
|
79
|
+
#### Interfaces between phases (large plans)
|
|
80
|
+
|
|
81
|
+
For plans with three or more phases, add the following at the end of each phase:
|
|
82
|
+
|
|
83
|
+
- **Inputs**: the artifacts this phase depends on from prior phases (name the specific function names, types, and file paths)
|
|
84
|
+
- **Outputs**: what this phase hands off to later phases (name the specific function names, types, and file paths)
|
|
85
|
+
|
|
86
|
+
The goal is for whoever implements a later phase to be able to work without reading the earlier phase's details.
|
|
87
|
+
|
|
88
|
+
### Step 5: Self-review the plan
|
|
89
|
+
|
|
90
|
+
Before presenting the plan, check it yourself against these three points.
|
|
91
|
+
Fix any issues found on the spot. If nothing is wrong, move to the next step.
|
|
92
|
+
|
|
93
|
+
1. **Requirement coverage**: does every requirement (from the request or requirements file) have a corresponding step?
|
|
94
|
+
Add a step for any requirement that's missing one.
|
|
95
|
+
|
|
96
|
+
2. **Placeholder scan**: search for anything matching the "No placeholders allowed" list in Step 4.
|
|
97
|
+
Rewrite anything found into something concrete.
|
|
98
|
+
|
|
99
|
+
3. **Name consistency**: are function, type, and constant names defined in earlier steps referenced by
|
|
100
|
+
the same names in later steps? Reconcile any mismatches.
|
|
101
|
+
After reconciling, re-run Check 1 (requirement coverage) and Check 2 (placeholder scan)
|
|
102
|
+
to make sure the renaming didn't introduce new problems.
|
|
103
|
+
|
|
104
|
+
### Step 6: Present the plan
|
|
105
|
+
|
|
106
|
+
Output the plan using the following template.
|
|
107
|
+
|
|
108
|
+
```markdown
|
|
109
|
+
# Implementation Plan: <title>
|
|
110
|
+
|
|
111
|
+
## Restated request
|
|
112
|
+
<the request in your own words, 1-3 sentences, including assumptions and interpretations>
|
|
113
|
+
|
|
114
|
+
## Complexity estimate
|
|
115
|
+
High / Medium / Low — <one-sentence rationale>
|
|
116
|
+
|
|
117
|
+
## Existing patterns to follow
|
|
118
|
+
| Aspect | Pattern to use | Evidence (real file path) |
|
|
119
|
+
|------|----------------|--------------------------|
|
|
120
|
+
| Naming | ... | ... |
|
|
121
|
+
| Error handling | ... | ... |
|
|
122
|
+
| Logging | ... | ... |
|
|
123
|
+
| Data access | ... | ... |
|
|
124
|
+
| Testing | ... | ... |
|
|
125
|
+
|
|
126
|
+
*For any aspect with no matching pattern, write "No existing pattern (proposing a new approach)."*
|
|
127
|
+
|
|
128
|
+
## Implementation phases
|
|
129
|
+
|
|
130
|
+
### Phase 1: <phase name>
|
|
131
|
+
| # | Target file | What to do | Why | Depends on | Risk |
|
|
132
|
+
|---|------------|---------|------|------|--------|
|
|
133
|
+
| 1-1 | path/to/file | ... | ... | none | Low |
|
|
134
|
+
| 1-2 | path/to/file | ... | ... | 1-1 | Medium |
|
|
135
|
+
|
|
136
|
+
<!-- Only for plans with 3+ phases -->
|
|
137
|
+
- **Inputs**: (outputs from the prior phase; Phase 1 is "none")
|
|
138
|
+
- **Outputs**: `functionName(arg: Type): ReturnType` — defined in path/to/file
|
|
139
|
+
|
|
140
|
+
### Phase 2: <phase name>
|
|
141
|
+
| # | Target file | What to do | Why | Depends on | Risk |
|
|
142
|
+
|---|------------|---------|------|------|--------|
|
|
143
|
+
| 2-1 | path/to/file | ... | ... | none | Low |
|
|
144
|
+
| 2-2 | path/to/file | ... | ... | 2-1 | Medium |
|
|
145
|
+
|
|
146
|
+
<!-- Only for plans with 3+ phases -->
|
|
147
|
+
- **Inputs**: Phase 1's `functionName(arg: Type): ReturnType` — path/to/file
|
|
148
|
+
- **Outputs**: `functionName2(arg: Type): ReturnType2` — defined in path/to/file
|
|
149
|
+
|
|
150
|
+
## Test strategy
|
|
151
|
+
- Unit tests: <scope and approach>
|
|
152
|
+
- Integration tests: <scope and approach, or why they're not needed>
|
|
153
|
+
- E2E tests: <scope and approach, or why they're not needed>
|
|
154
|
+
|
|
155
|
+
## Success criteria
|
|
156
|
+
- [ ] <verifiable criteria as a checklist>
|
|
157
|
+
|
|
158
|
+
## Risks and mitigations
|
|
159
|
+
- <risk>: <mitigation>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 7: Confirm approval
|
|
163
|
+
|
|
164
|
+
After presenting the plan, always ask: "Should I go ahead and start implementing this plan?"
|
|
165
|
+
|
|
166
|
+
**The most important rule: don't write a single line of code until the user explicitly approves.**
|
|
167
|
+
That includes creating or editing files, committing, and any "just a small preview" implementation.
|
|
168
|
+
|
|
169
|
+
Handle the user's response as follows:
|
|
170
|
+
|
|
171
|
+
- **Approval** ("OK," "go ahead," "approved," etc.): start implementing according to the plan.
|
|
172
|
+
- **Requested changes** ("change this part," "drop Phase 2," etc.): revise the affected part of the plan, re-present it, and ask for approval again. Re-run the Step 5 self-review (all three checks) before re-presenting.
|
|
173
|
+
- **Request for an alternative** ("try a different approach," etc.): draft a plan with a different approach and re-present it, optionally with a comparison table against the original.
|
|
174
|
+
- **Rejection/abandonment**: discard the plan and don't implement anything.
|
|
175
|
+
|
|
176
|
+
## Completion Marker Convention
|
|
177
|
+
|
|
178
|
+
This command runs under `claude -p` (non-interactive), which restarts as a fresh process every turn — past turn 1, this command body is not guaranteed to be re-expanded, so gate discipline can silently erode across turns. To compensate, a hooks-based mechanism re-injects a digest of this command's must-obey constraints on the next turn whenever the flow is left incomplete.
|
|
179
|
+
|
|
180
|
+
If this command's flow is **not yet complete** (e.g. stopped at Step 7's approval gate, waiting on clarifying questions, etc.), your response **MUST end** with a line that is an exact match of:
|
|
181
|
+
|
|
182
|
+
`<!-- ai-support-agent:resume name="plan" -->`
|
|
183
|
+
|
|
184
|
+
If the flow **is complete** (final user approval was obtained, or the plan was rejected/discarded), do **not** output this marker.
|
|
185
|
+
|
|
186
|
+
Never output this marker inside a code block or as an illustrative example — only emit it as the actual last line of real output when the flow is genuinely incomplete.
|
|
187
|
+
|
|
188
|
+
<!-- RESUME_DIGEST_START -->
|
|
189
|
+
When resuming this command on turn 2+ without the full command body re-expanded, obey these constraints:
|
|
190
|
+
|
|
191
|
+
- **Approval gate (Step 7)**: don't write a single line of code — no creating/editing files, no committing, no "just a small preview" — until the user explicitly approves the presented plan. Silence or a vague "sounds good" is not approval; ask "Should I go ahead and start implementing this plan?" and wait for an explicit yes.
|
|
192
|
+
- Handle the user's response per Step 7: approval → start implementing; requested changes → revise only the affected part, re-present, and ask for approval again; request for an alternative → draft and present a different approach; rejection/abandonment → discard the plan and implement nothing.
|
|
193
|
+
- Never self-interpret "roughly agreed to," silence, or an unrelated follow-up question as approval.
|
|
194
|
+
- If clarifying questions (Step 2) are still outstanding for a small/standard-or-larger change, wait for the user's answers before drafting or re-drafting the plan.
|
|
195
|
+
- Before presenting (or re-presenting) any plan, re-run the Step 5 self-review's three checks:
|
|
196
|
+
1. Requirement coverage — every requirement has a corresponding step.
|
|
197
|
+
2. Placeholder scan — no "TBD," "TODO," "add appropriate error handling," "same as Phase N," or forward references to undefined types/functions.
|
|
198
|
+
3. Name consistency — function/type/constant names match across steps; re-run checks 1 and 2 after any renaming.
|
|
199
|
+
- **No placeholders allowed**: every step must be concrete enough to execute as written. A step with a code change but no code sample, or a vague instruction without specifics, is a failed plan.
|
|
200
|
+
- Every claim in the plan (patterns, existing code) must be backed by a real file path — never fabricate a pattern that doesn't exist; say "no matching existing pattern was found" if that's the truth.
|
|
201
|
+
- Once the user approves, implementation may begin; until then, remain at the gate and keep emitting the resume marker on every incomplete turn.
|
|
202
|
+
<!-- RESUME_DIGEST_END -->
|
|
203
|
+
|
|
204
|
+
## After implementation is done
|
|
205
|
+
|
|
206
|
+
Once the plan is approved and implementation is complete, point to the next command as appropriate:
|
|
207
|
+
|
|
208
|
+
- Code review: /code-review
|
|
209
|
+
- Resolving build errors: /build-fix
|
|
210
|
+
- Checking test coverage: /test-coverage
|
|
211
|
+
- Keeping docs in sync: /update-docs
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Measure test coverage, identify important uncovered paths, and present a prioritized plan for adding tests.
|
|
3
|
+
argument-hint: "[target directory/file | leave empty for the whole project]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /test-coverage command
|
|
7
|
+
|
|
8
|
+
**Input**: $ARGUMENTS
|
|
9
|
+
|
|
10
|
+
A command whose goal isn't "raise the number" but "close off the highest-risk gaps" — it measures coverage and points at what actually matters.
|
|
11
|
+
|
|
12
|
+
## Behavior
|
|
13
|
+
|
|
14
|
+
### 1. Measure coverage
|
|
15
|
+
|
|
16
|
+
Detect the project type and measure accordingly:
|
|
17
|
+
|
|
18
|
+
| Stack | Command |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Jest | `npx jest --coverage --coverageReporters=text-summary --coverageReporters=text` |
|
|
21
|
+
| Vitest | `npx vitest run --coverage` |
|
|
22
|
+
| pytest | `pytest --cov --cov-report=term-missing` |
|
|
23
|
+
| PHPUnit | `./vendor/bin/phpunit --coverage-text` (requires Xdebug/PCOV) |
|
|
24
|
+
|
|
25
|
+
If `$ARGUMENTS` specifies a path, scope the measurement to it. If no coverage tool is set up, present setup instructions and stop (don't add dependencies on your own).
|
|
26
|
+
|
|
27
|
+
### 2. Risk-assess the uncovered code
|
|
28
|
+
|
|
29
|
+
Evaluate by **the importance of what's uncovered**, not by how many lines are uncovered in the report:
|
|
30
|
+
|
|
31
|
+
| Priority | Scope |
|
|
32
|
+
|---|---|
|
|
33
|
+
| High | Payments/billing, authentication, authorization checks, data writes/deletes, external API integrations, error-handling branches |
|
|
34
|
+
| Medium | Business-logic branches, validation, data transformation |
|
|
35
|
+
| Low | Display formatters, reading config values, trivial getters |
|
|
36
|
+
|
|
37
|
+
Flag tests with weak assertions (tests that merely execute code without verifying anything), even if coverage is high.
|
|
38
|
+
Also flag any path involving DB reads/writes that is **covered only by mocked tests** (green in the coverage report but never verified against a real DB) as a gap needing an integration test against a real database (see the integration-testing skill).
|
|
39
|
+
|
|
40
|
+
### 3. Report
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
## Coverage report
|
|
44
|
+
|
|
45
|
+
Overall: <n>% (statements) / <n>% (branches)
|
|
46
|
+
|
|
47
|
+
### Highest-priority uncovered code
|
|
48
|
+
1. <file:line range> — <what it does> / <what breaks if it stays uncovered>
|
|
49
|
+
2. ...
|
|
50
|
+
|
|
51
|
+
### Recommended tests to add (by priority)
|
|
52
|
+
1. Add <case> to <test file> — <why>
|
|
53
|
+
2. ...
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Add tests (only with user approval)
|
|
57
|
+
|
|
58
|
+
After presenting the report, if the user approves, add tests starting with the highest priority. Match the style of the existing tests (framework, fixtures, naming). Don't change production code just to make it more testable (report testability problems instead of fixing them here).
|
|
59
|
+
|
|
60
|
+
## Notes
|
|
61
|
+
|
|
62
|
+
- Don't aim for 100% coverage. Covering the important paths is enough.
|
|
63
|
+
- Don't pad coverage numbers by adding only snapshot tests.
|
|
64
|
+
- Don't duplicate at the unit-test level what's already covered by E2E tests.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Update documentation (README, API specs, CLAUDE.md, etc.) to keep it in sync with code changes. Detects and fixes drift between implementation and docs.
|
|
3
|
+
argument-hint: "[target document | leave empty to auto-detect drift]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /update-docs command
|
|
7
|
+
|
|
8
|
+
**Input**: $ARGUMENTS
|
|
9
|
+
|
|
10
|
+
A command that detects drift between the implementation and its documentation, and updates the documentation to match reality.
|
|
11
|
+
|
|
12
|
+
## Behavior
|
|
13
|
+
|
|
14
|
+
### 1. Identify the target
|
|
15
|
+
|
|
16
|
+
- If `$ARGUMENTS` specifies a document, target that.
|
|
17
|
+
- If empty, infer which documents are affected from recent changes (`git diff HEAD~10 --name-only`, or uncommitted changes):
|
|
18
|
+
|
|
19
|
+
| Change | Documents to check |
|
|
20
|
+
|---|---|
|
|
21
|
+
| API endpoints/DTOs | API spec, OpenAPI definitions, README's API section |
|
|
22
|
+
| Public function signature changes | Function reference on the docs site (see the consistency check below) |
|
|
23
|
+
| Tests added/changed | describe/it spec descriptions (see the test-description check below) |
|
|
24
|
+
| Environment variables/config | README's setup section, `.env.example` |
|
|
25
|
+
| CLI commands/scripts | README's usage section, `package.json` scripts descriptions |
|
|
26
|
+
| DB schema | ER diagram/schema docs, migration instructions |
|
|
27
|
+
| Architecture/conventions | CLAUDE.md, ADRs, CONTRIBUTING |
|
|
28
|
+
|
|
29
|
+
### 2. Detect drift
|
|
30
|
+
|
|
31
|
+
Cross-check the documentation against the implementation and look for:
|
|
32
|
+
|
|
33
|
+
- References to files, commands, or endpoints that no longer exist
|
|
34
|
+
- Steps, parameters, or default values that differ from the implementation
|
|
35
|
+
- Added features/settings with no documentation
|
|
36
|
+
- Documentation for features that have since been removed
|
|
37
|
+
|
|
38
|
+
### 3. Update
|
|
39
|
+
|
|
40
|
+
- **Prioritize fixing factual errors** (wrong instructions do more harm than a missing mention of a new feature).
|
|
41
|
+
- Match the existing documentation's tone, structure, and language.
|
|
42
|
+
- For docs auto-generated from code (OpenAPI, etc.), suggest re-running the generation command rather than hand-editing.
|
|
43
|
+
- For anything you're not confident about (design rationale that isn't clear from the code, etc.), don't rewrite it blindly — list it as an open question instead.
|
|
44
|
+
|
|
45
|
+
### 4. Docs-site consistency check (only for projects with a docs site)
|
|
46
|
+
|
|
47
|
+
If a Docusaurus (or similar) docs-site directory exists, do the following.
|
|
48
|
+
For detailed build/generation pipeline patterns, see the docs-site skill.
|
|
49
|
+
|
|
50
|
+
1. **Cross-check hand-written function reference pages**
|
|
51
|
+
- Grep for pages whose frontmatter has a `source: <path>#<functionName>` key.
|
|
52
|
+
- For each such page, read the implementation at `source` and verify:
|
|
53
|
+
- **Errors**: function name, parameter names, required/optional status, or thrown exceptions that don't match the implementation
|
|
54
|
+
- **Missing coverage**: parameters or exceptions that exist in the implementation but aren't in the page's parameter table or error section
|
|
55
|
+
- **Stale content**: anything documented on the page that's been removed from the implementation
|
|
56
|
+
- Always correct the documentation **to match the implementation**. If the implementation itself looks wrong, don't fix it — add it to the open-questions list instead.
|
|
57
|
+
- List any hand-written reference page without a `source` key as "not checkable" and suggest adding the key.
|
|
58
|
+
2. **Auto-generated pages (OpenAPI/TypeDoc)**
|
|
59
|
+
- Don't edit generated pages directly — suggest re-running the generation command (`openapi:generate`, etc.).
|
|
60
|
+
- Regenerate the committed `openapi.json` and diff it to catch decorator changes that weren't reflected.
|
|
61
|
+
3. **Verify test links**
|
|
62
|
+
- For links to tests within reference pages, confirm the linked file actually exists in the repository.
|
|
63
|
+
4. **i18n translation freshness**
|
|
64
|
+
- For hand-written pages that exist in multiple locales, compare git's last-modified timestamps and flag any translation older than its source as "needs review."
|
|
65
|
+
|
|
66
|
+
### 5. Detect drift in test descriptions
|
|
67
|
+
|
|
68
|
+
- Detect mismatches between what a describe/it name claims and what the body actually asserts
|
|
69
|
+
(e.g., named "throws an exception" but never checks for one; named "gets persisted" but never reads back from the DB).
|
|
70
|
+
- Suggest renaming uninformative names ("happy path," "test1," etc.) only when a change already touches that test.
|
|
71
|
+
|
|
72
|
+
### 6. Report
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
## Documentation update
|
|
76
|
+
|
|
77
|
+
Files updated:
|
|
78
|
+
- <file>: <summary of the fix>
|
|
79
|
+
|
|
80
|
+
### Consistency check results (docs site)
|
|
81
|
+
- Errors: <page:item> — <discrepancy with the implementation> (fixed/needs review)
|
|
82
|
+
- Missing coverage: <page> — <item present in the implementation but undocumented>
|
|
83
|
+
- Stale content: <page> — <documented item removed from the implementation>
|
|
84
|
+
- Broken links: <page> — <nonexistent test file>
|
|
85
|
+
- Stale translations: <page> — <source update date vs. translation update date>
|
|
86
|
+
|
|
87
|
+
### Test descriptions
|
|
88
|
+
- <test file:test name> — <mismatch between the name and the assertions>
|
|
89
|
+
|
|
90
|
+
Detected but not fixed (needs review):
|
|
91
|
+
- <file:section> — <reason (unclear intent, needs a judgment call)>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Notes
|
|
95
|
+
|
|
96
|
+
- Only create new documentation when explicitly requested — the primary job here is fixing drift.
|
|
97
|
+
- Don't mechanically generate a CHANGELOG from commit history; keep it focused on user-facing changes.
|
|
98
|
+
- When updating CLAUDE.md, keep it concise — it gets loaded into every session, so bulk has a real cost.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Bash",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/guard-dangerous-commands.sh\""
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "command",
|
|
13
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-secrets-before-commit.sh\""
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"matcher": "Read|Edit|Write",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/protect-sensitive-files.sh\""
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"PostToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "Edit|Write",
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/auto-format.sh\""
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"UserPromptSubmit": [
|
|
39
|
+
{
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/on-command-resume.sh\""
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"Stop": [
|
|
49
|
+
{
|
|
50
|
+
"hooks": [
|
|
51
|
+
{
|
|
52
|
+
"type": "command",
|
|
53
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/on-command-stop.sh\""
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Auto-format after edits (PostToolUse / Edit, Write)
|
|
3
|
+
# Only formats the edited file when the project already has a matching
|
|
4
|
+
# formatter configured. Never performs network access to fetch tooling
|
|
5
|
+
# (e.g. downloading via npx). Always exits successfully.
|
|
6
|
+
set -u
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
10
|
+
|
|
11
|
+
fp=$(printf '%s' "$input" | python3 -c 'import json,sys
|
|
12
|
+
try:
|
|
13
|
+
print(json.load(sys.stdin).get("tool_input", {}).get("file_path", ""))
|
|
14
|
+
except Exception:
|
|
15
|
+
pass' 2>/dev/null) || exit 0
|
|
16
|
+
[ -n "$fp" ] && [ -f "$fp" ] || exit 0
|
|
17
|
+
|
|
18
|
+
proj="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
19
|
+
ext="${fp##*.}"
|
|
20
|
+
|
|
21
|
+
has_prettier_config() {
|
|
22
|
+
ls "$proj"/.prettierrc "$proj"/.prettierrc.* "$proj"/prettier.config.* >/dev/null 2>&1 && return 0
|
|
23
|
+
[ -f "$proj/package.json" ] && grep -q '"prettier"' "$proj/package.json" && return 0
|
|
24
|
+
return 1
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Resolve Python tools preferring the project's virtual environment.
|
|
28
|
+
# Priority order: $proj/.venv/bin -> $proj/venv/bin -> $VIRTUAL_ENV/bin -> global
|
|
29
|
+
find_py_tool() {
|
|
30
|
+
tool="$1"
|
|
31
|
+
for dir in "$proj/.venv/bin" "$proj/venv/bin" "${VIRTUAL_ENV:-}/bin"; do
|
|
32
|
+
if [ -x "$dir/$tool" ]; then
|
|
33
|
+
printf '%s' "$dir/$tool"
|
|
34
|
+
return 0
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
command -v "$tool" 2>/dev/null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
case "$ext" in
|
|
41
|
+
ts|tsx|js|jsx|mjs|cjs|json|css|scss|vue)
|
|
42
|
+
# Only use a locally installed prettier; never auto-fetch via npx.
|
|
43
|
+
if [ -x "$proj/node_modules/.bin/prettier" ] && has_prettier_config; then
|
|
44
|
+
"$proj/node_modules/.bin/prettier" --write --log-level silent "$fp" >/dev/null 2>&1 || true
|
|
45
|
+
fi
|
|
46
|
+
;;
|
|
47
|
+
py)
|
|
48
|
+
ruff_bin=$(find_py_tool ruff)
|
|
49
|
+
if [ -n "$ruff_bin" ]; then
|
|
50
|
+
if [ -f "$proj/ruff.toml" ] || [ -f "$proj/.ruff.toml" ] || { [ -f "$proj/pyproject.toml" ] && grep -q '\[tool\.ruff' "$proj/pyproject.toml"; }; then
|
|
51
|
+
"$ruff_bin" format --quiet "$fp" >/dev/null 2>&1 || true
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
;;
|
|
55
|
+
php)
|
|
56
|
+
if [ -x "$proj/vendor/bin/pint" ]; then
|
|
57
|
+
"$proj/vendor/bin/pint" --quiet "$fp" >/dev/null 2>&1 || true
|
|
58
|
+
elif [ -x "$proj/vendor/bin/php-cs-fixer" ] && { [ -f "$proj/.php-cs-fixer.php" ] || [ -f "$proj/.php-cs-fixer.dist.php" ]; }; then
|
|
59
|
+
"$proj/vendor/bin/php-cs-fixer" fix --quiet "$fp" >/dev/null 2>&1 || true
|
|
60
|
+
fi
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
exit 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Check for leaked secrets before committing (PreToolUse / Bash)
|
|
3
|
+
# When running git commit, inspect the staged content for known token
|
|
4
|
+
# formats. If any are found, require manual confirmation (ask).
|
|
5
|
+
# False positives can simply be approved by the user.
|
|
6
|
+
set -u
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
10
|
+
command -v git >/dev/null 2>&1 || exit 0
|
|
11
|
+
|
|
12
|
+
cmd=$(printf '%s' "$input" | python3 -c 'import json,sys
|
|
13
|
+
try:
|
|
14
|
+
print(json.load(sys.stdin).get("tool_input", {}).get("command", ""))
|
|
15
|
+
except Exception:
|
|
16
|
+
pass' 2>/dev/null) || exit 0
|
|
17
|
+
|
|
18
|
+
# Also detect commit invocations with extra options, e.g. git -C <dir> commit
|
|
19
|
+
# or git -c key=val commit.
|
|
20
|
+
printf '%s' "$cmd" | grep -Eq '(^|[;&|[:space:]])git[[:space:]][^;|&]*commit' || exit 0
|
|
21
|
+
|
|
22
|
+
cd "${CLAUDE_PROJECT_DIR:-.}" 2>/dev/null || exit 0
|
|
23
|
+
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || exit 0
|
|
24
|
+
|
|
25
|
+
# Only target high-confidence token formats (generic patterns like password=
|
|
26
|
+
# are excluded because they produce too many false positives).
|
|
27
|
+
pattern='AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|sk_live_[A-Za-z0-9]{20,}|AIza[0-9A-Za-z_-]{35}|-----BEGIN [A-Z ]*PRIVATE KEY-----'
|
|
28
|
+
|
|
29
|
+
# Read NUL-separated so filenames containing spaces are not missed.
|
|
30
|
+
hit_files=""
|
|
31
|
+
while IFS= read -r -d '' f; do
|
|
32
|
+
if git show ":$f" 2>/dev/null | grep -EIq "$pattern"; then
|
|
33
|
+
hit_files="$hit_files $f"
|
|
34
|
+
fi
|
|
35
|
+
done < <(git diff --cached --name-only --diff-filter=ACM -z 2>/dev/null)
|
|
36
|
+
|
|
37
|
+
if [ -n "$hit_files" ]; then
|
|
38
|
+
python3 - "$hit_files" <<'PYEOF'
|
|
39
|
+
import json, sys
|
|
40
|
+
files = sys.argv[1].strip()
|
|
41
|
+
print(json.dumps({
|
|
42
|
+
"hookSpecificOutput": {
|
|
43
|
+
"hookEventName": "PreToolUse",
|
|
44
|
+
"permissionDecision": "ask",
|
|
45
|
+
"permissionDecisionReason": "Guard: the staged content may contain secrets (API keys, tokens, or private keys). Affected files: " + files + " -- review the content and approve only if it is safe."
|
|
46
|
+
}
|
|
47
|
+
}, ensure_ascii=False))
|
|
48
|
+
PYEOF
|
|
49
|
+
fi
|
|
50
|
+
exit 0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Guard against dangerous commands before execution (PreToolUse / Bash)
|
|
3
|
+
# When a destructive command is detected, block execution and require the
|
|
4
|
+
# user to manually confirm (ask) before it proceeds.
|
|
5
|
+
# If python3 is unavailable, do nothing (fail open).
|
|
6
|
+
set -u
|
|
7
|
+
|
|
8
|
+
input=$(cat)
|
|
9
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
10
|
+
|
|
11
|
+
cmd=$(printf '%s' "$input" | python3 -c 'import json,sys
|
|
12
|
+
try:
|
|
13
|
+
print(json.load(sys.stdin).get("tool_input", {}).get("command", ""))
|
|
14
|
+
except Exception:
|
|
15
|
+
pass' 2>/dev/null) || exit 0
|
|
16
|
+
[ -z "$cmd" ] && exit 0
|
|
17
|
+
|
|
18
|
+
reason=""
|
|
19
|
+
# Detect rm with both recursive (-r/-R/--recursive) and force (-f/--force)
|
|
20
|
+
# flags, regardless of whether they are combined, separate, or long-form.
|
|
21
|
+
if printf '%s' "$cmd" | grep -Eq '(^|[;&|[:space:]])rm[[:space:]]' \
|
|
22
|
+
&& printf '%s' "$cmd" | grep -Eq '[[:space:]]-[a-zA-Z]*[rR]|[[:space:]]--recursive' \
|
|
23
|
+
&& printf '%s' "$cmd" | grep -Eq '[[:space:]]-[a-zA-Z]*f|[[:space:]]--force'; then
|
|
24
|
+
reason="recursive forced delete (rm -rf or equivalent)"
|
|
25
|
+
elif printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push[^;|&]*([[:space:]](--force|-f))([[:space:]]|$)'; then
|
|
26
|
+
reason="git force push"
|
|
27
|
+
elif printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+reset[[:space:]]+--hard'; then
|
|
28
|
+
reason="git reset --hard (discards working tree changes)"
|
|
29
|
+
elif printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+clean[^;|&]*[[:space:]]-[a-zA-Z]*f'; then
|
|
30
|
+
reason="git clean -f (removes untracked files)"
|
|
31
|
+
elif printf '%s' "$cmd" | grep -Eiq '(^|[^a-z])(drop[[:space:]]+(table|database|schema)|truncate[[:space:]]+table|truncate[[:space:]]+[a-z_]+;)'; then
|
|
32
|
+
reason="SQL containing DROP / TRUNCATE"
|
|
33
|
+
elif printf '%s' "$cmd" | grep -Eq 'chmod[[:space:]]+(-R[[:space:]]+)?777'; then
|
|
34
|
+
reason="chmod 777 (grants full permissions to everyone)"
|
|
35
|
+
elif printf '%s' "$cmd" | grep -Eq '(^|[;&|[:space:]])aws[[:space:]][^;|&]*[[:space:]](create|update|delete|put|terminate|stop|reboot|modify)-[a-z-]+'; then
|
|
36
|
+
reason="AWS resource mutation operation"
|
|
37
|
+
elif printf '%s' "$cmd" | grep -Eq '(^|[;&|[:space:]])aws[[:space:]]+lambda[[:space:]]+invoke'; then
|
|
38
|
+
reason="AWS Lambda invocation (lambda invoke)"
|
|
39
|
+
elif printf '%s' "$cmd" | grep -Eq '(^|[;&|[:space:]])aws[[:space:]]+ssm[[:space:]]+send-command'; then
|
|
40
|
+
reason="remote command execution via SSM"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ -n "$reason" ]; then
|
|
44
|
+
python3 - "$reason" <<'PYEOF'
|
|
45
|
+
import json, sys
|
|
46
|
+
print(json.dumps({
|
|
47
|
+
"hookSpecificOutput": {
|
|
48
|
+
"hookEventName": "PreToolUse",
|
|
49
|
+
"permissionDecision": "ask",
|
|
50
|
+
"permissionDecisionReason": "Guard: detected " + sys.argv[1] + ". Review the command and its target before approving."
|
|
51
|
+
}
|
|
52
|
+
}, ensure_ascii=False))
|
|
53
|
+
PYEOF
|
|
54
|
+
fi
|
|
55
|
+
exit 0
|