haac-aikit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/catalog/agents/backend.md +49 -0
- package/catalog/agents/devops.md +74 -0
- package/catalog/agents/frontend.md +49 -0
- package/catalog/agents/implementer.md +55 -0
- package/catalog/agents/mobile.md +48 -0
- package/catalog/agents/orchestrator.md +53 -0
- package/catalog/agents/planner.md +59 -0
- package/catalog/agents/researcher.md +62 -0
- package/catalog/agents/reviewer.md +70 -0
- package/catalog/agents/security-auditor.md +73 -0
- package/catalog/agents/tester.md +63 -0
- package/catalog/ci/agents-md-sync.yml +42 -0
- package/catalog/ci/ci.yml +24 -0
- package/catalog/ci/claude.yml +20 -0
- package/catalog/ci/secret-scan.yml +20 -0
- package/catalog/commands/commit-push-pr.md +21 -0
- package/catalog/commands/commit.md +17 -0
- package/catalog/commands/debug.md +17 -0
- package/catalog/commands/execute.md +13 -0
- package/catalog/commands/explore.md +26 -0
- package/catalog/commands/plan.md +19 -0
- package/catalog/commands/review.md +17 -0
- package/catalog/commands/security-review.md +33 -0
- package/catalog/commands/ship.md +21 -0
- package/catalog/commands/tdd.md +21 -0
- package/catalog/devcontainer/devcontainer.json +24 -0
- package/catalog/hooks/block-dangerous-bash.sh +30 -0
- package/catalog/hooks/block-force-push-main.sh +22 -0
- package/catalog/hooks/block-secrets-in-commits.sh +37 -0
- package/catalog/hooks/compaction-preservation.sh +29 -0
- package/catalog/hooks/file-guard.sh +30 -0
- package/catalog/hooks/format-on-save.sh +43 -0
- package/catalog/hooks/hooks.json +70 -0
- package/catalog/hooks/session-start-prime.sh +31 -0
- package/catalog/husky/commit-msg +4 -0
- package/catalog/husky/commitlint.config.js +8 -0
- package/catalog/husky/gitleaks.toml +10 -0
- package/catalog/husky/lintstagedrc.json +5 -0
- package/catalog/husky/pre-commit +4 -0
- package/catalog/husky/pre-push +18 -0
- package/catalog/mcp/mcp.json +19 -0
- package/catalog/plugin/plugin.json +10 -0
- package/catalog/rules/AGENTS.md.tmpl +46 -0
- package/catalog/rules/CLAUDE.md.shim +5 -0
- package/catalog/rules/GEMINI.md.shim +5 -0
- package/catalog/rules/aider-conventions.md +5 -0
- package/catalog/rules/aider.conf.yml +5 -0
- package/catalog/rules/copilot-instructions.md +6 -0
- package/catalog/rules/cursor-base.mdc +13 -0
- package/catalog/rules/windsurf-rules.md +7 -0
- package/catalog/settings/env.example +7 -0
- package/catalog/settings/settings.json +45 -0
- package/catalog/skills/tier1/brainstorming.md +39 -0
- package/catalog/skills/tier1/codebase-exploration.md +55 -0
- package/catalog/skills/tier1/executing-plans.md +34 -0
- package/catalog/skills/tier1/requesting-code-review.md +37 -0
- package/catalog/skills/tier1/systematic-debugging.md +50 -0
- package/catalog/skills/tier1/test-driven-development.md +44 -0
- package/catalog/skills/tier1/using-git-worktrees.md +43 -0
- package/catalog/skills/tier1/verification-before-completion.md +46 -0
- package/catalog/skills/tier1/writing-commits.md +52 -0
- package/catalog/skills/tier1/writing-plans.md +42 -0
- package/catalog/skills/tier2/claude-md-improver.md +42 -0
- package/catalog/skills/tier2/dependency-hygiene.md +52 -0
- package/catalog/skills/tier2/dispatching-parallel-agents.md +43 -0
- package/catalog/skills/tier2/finishing-a-development-branch.md +48 -0
- package/catalog/skills/tier2/receiving-code-review.md +49 -0
- package/catalog/skills/tier2/refactoring-simplify.md +40 -0
- package/catalog/skills/tier2/security-review.md +48 -0
- package/catalog/skills/tier2/writing-pull-requests.md +47 -0
- package/dist/cli.mjs +2161 -0
- package/dist/cli.mjs.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-auditor
|
|
3
|
+
description: OWASP-aligned security sweep and secrets scan. Checks for injection vulnerabilities, broken auth, sensitive data exposure, access control gaps, and hardcoded credentials. Use before any PR that touches auth, API endpoints, or file/env handling.
|
|
4
|
+
model: claude-opus-4-5
|
|
5
|
+
tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Grep
|
|
8
|
+
- Glob
|
|
9
|
+
- Bash
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Security Auditor
|
|
13
|
+
|
|
14
|
+
You perform security reviews. You do not fix issues — you report them with enough detail for an implementer to act.
|
|
15
|
+
|
|
16
|
+
## Scope
|
|
17
|
+
|
|
18
|
+
Focus on OWASP Top 10:
|
|
19
|
+
- **A01 Broken Access Control**: missing authorisation checks, IDOR, privilege escalation
|
|
20
|
+
- **A02 Cryptographic Failures**: plaintext secrets, weak algorithms, insecure storage
|
|
21
|
+
- **A03 Injection**: SQL injection, command injection, XSS, template injection
|
|
22
|
+
- **A05 Security Misconfiguration**: debug mode, default credentials, verbose errors
|
|
23
|
+
- **A07 Auth Failures**: broken session management, insecure tokens
|
|
24
|
+
- **A09 Logging Failures**: sensitive data in logs, insufficient audit trail
|
|
25
|
+
|
|
26
|
+
## Protocol
|
|
27
|
+
|
|
28
|
+
1. **Grep for high-risk patterns**:
|
|
29
|
+
```bash
|
|
30
|
+
grep -r "password\|secret\|api_key\|apikey\|token" --include="*.ts" .
|
|
31
|
+
grep -r "eval\|dangerouslySetInner\|innerHTML" --include="*.ts" .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. **Read all auth middleware** and verify:
|
|
35
|
+
- Authentication and authorisation are both present
|
|
36
|
+
- Token validation is cryptographically sound
|
|
37
|
+
- Session tokens are not logged
|
|
38
|
+
|
|
39
|
+
3. **Check environment variable handling**:
|
|
40
|
+
- No hardcoded secrets in source
|
|
41
|
+
- Required env vars validated at startup
|
|
42
|
+
- `.env*` files in `.gitignore`
|
|
43
|
+
|
|
44
|
+
4. **Review file I/O operations**:
|
|
45
|
+
- User-supplied paths are bounded and canonicalised
|
|
46
|
+
- Uploads are validated for type and size
|
|
47
|
+
|
|
48
|
+
## Output format
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Security audit: [scope]
|
|
52
|
+
|
|
53
|
+
CRITICAL (must fix before merge)
|
|
54
|
+
- [file:line] [vulnerability type] — [description] — [remediation]
|
|
55
|
+
|
|
56
|
+
HIGH (should fix)
|
|
57
|
+
- [file:line] [vulnerability type] — [description] — [remediation]
|
|
58
|
+
|
|
59
|
+
INFO
|
|
60
|
+
- [observation]
|
|
61
|
+
|
|
62
|
+
Verdict: PASS | FAIL | CONDITIONAL
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Handoff format
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
[security-auditor] → [implementer | orchestrator]
|
|
69
|
+
Summary: Audited [scope], verdict: [PASS/FAIL/CONDITIONAL]
|
|
70
|
+
Artifacts: audit report (inline)
|
|
71
|
+
Next: [address CRITICAL findings before merge]
|
|
72
|
+
Status: DONE | DONE_WITH_CONCERNS
|
|
73
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tester
|
|
3
|
+
description: Writes and runs tests. Identifies coverage gaps, writes missing tests, and reports test results. Use after implementation to verify correctness and catch regressions before merge.
|
|
4
|
+
model: claude-sonnet-4-5
|
|
5
|
+
tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Edit
|
|
8
|
+
- Write
|
|
9
|
+
- Grep
|
|
10
|
+
- Glob
|
|
11
|
+
- Bash
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Tester
|
|
15
|
+
|
|
16
|
+
You write and run tests. Your goal is to ensure the implemented behaviour is verified and regressions are prevented.
|
|
17
|
+
|
|
18
|
+
## Protocol
|
|
19
|
+
|
|
20
|
+
1. **Assess existing coverage**:
|
|
21
|
+
- Which functions/branches are untested?
|
|
22
|
+
- Are there tests for the happy path but not edge cases?
|
|
23
|
+
- Are there regression tests for recently fixed bugs?
|
|
24
|
+
|
|
25
|
+
2. **Write missing tests** following the project's test framework:
|
|
26
|
+
- Happy path
|
|
27
|
+
- Error/edge cases
|
|
28
|
+
- Boundary conditions
|
|
29
|
+
- Any scenario that would have caught a recent bug
|
|
30
|
+
|
|
31
|
+
3. **Run the full suite** and report:
|
|
32
|
+
- Pass/fail count
|
|
33
|
+
- Any regressions introduced
|
|
34
|
+
- Coverage delta (if available)
|
|
35
|
+
|
|
36
|
+
## Good test structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
describe('[unit under test]', () => {
|
|
40
|
+
it('should [verb] [noun] when [condition]', () => {
|
|
41
|
+
// Arrange
|
|
42
|
+
// Act
|
|
43
|
+
// Assert (one per test)
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## What makes a good test
|
|
49
|
+
|
|
50
|
+
- **One assertion per test** (or logically cohesive assertions)
|
|
51
|
+
- **Tests behaviour, not implementation** — don't test private methods
|
|
52
|
+
- **Fails for the right reason** — a passing test that passes for the wrong reason is noise
|
|
53
|
+
- **No shared mutable state** between tests — each test is independent
|
|
54
|
+
|
|
55
|
+
## Handoff format
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
[tester] → [reviewer | orchestrator]
|
|
59
|
+
Summary: Added N tests, suite at X/Y passing
|
|
60
|
+
Artifacts: [test files modified]
|
|
61
|
+
Next: Review test quality / merge
|
|
62
|
+
Status: DONE | DONE_WITH_CONCERNS
|
|
63
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: AI kit sync
|
|
2
|
+
on:
|
|
3
|
+
schedule:
|
|
4
|
+
- cron: "0 9 * * 1" # weekly on Mondays
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
pull-requests: write
|
|
9
|
+
concurrency:
|
|
10
|
+
group: aikit-sync
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
jobs:
|
|
13
|
+
sync:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 10
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
18
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
19
|
+
with:
|
|
20
|
+
node-version: "20"
|
|
21
|
+
- name: Run aikit sync
|
|
22
|
+
run: npx haac-aikit sync --yes
|
|
23
|
+
- name: Check for drift
|
|
24
|
+
id: drift
|
|
25
|
+
run: |
|
|
26
|
+
git diff --exit-code || echo "DRIFT=true" >> "$GITHUB_OUTPUT"
|
|
27
|
+
- name: Open PR for drift
|
|
28
|
+
if: steps.drift.outputs.DRIFT == 'true'
|
|
29
|
+
run: |
|
|
30
|
+
git config user.name "github-actions[bot]"
|
|
31
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
32
|
+
BRANCH="aikit/sync-$(date +%Y-%m-%d)"
|
|
33
|
+
git checkout -b "$BRANCH"
|
|
34
|
+
git add .
|
|
35
|
+
git commit -m "chore(aikit): weekly sync from catalog"
|
|
36
|
+
git push origin "$BRANCH"
|
|
37
|
+
gh pr create \
|
|
38
|
+
--title "chore(aikit): weekly catalog sync" \
|
|
39
|
+
--body "Automated sync from haac-aikit catalog. Review and merge if changes look good." \
|
|
40
|
+
--label "automated"
|
|
41
|
+
env:
|
|
42
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
17
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
18
|
+
with:
|
|
19
|
+
node-version: "20"
|
|
20
|
+
cache: "npm"
|
|
21
|
+
- run: npm ci
|
|
22
|
+
- run: npm run typecheck
|
|
23
|
+
- run: npm run lint
|
|
24
|
+
- run: npm test
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Claude Code review
|
|
2
|
+
on:
|
|
3
|
+
issue_comment:
|
|
4
|
+
types: [created]
|
|
5
|
+
pull_request_review_comment:
|
|
6
|
+
types: [created]
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pull-requests: write
|
|
10
|
+
issues: write
|
|
11
|
+
jobs:
|
|
12
|
+
claude:
|
|
13
|
+
if: contains(github.event.comment.body, '@claude')
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 15
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
18
|
+
- uses: anthropics/claude-code-action@abd8191b0b84413a7e6a5614d17be66e70c2c38e # v1
|
|
19
|
+
with:
|
|
20
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Secret scan
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
pull_request:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
concurrency:
|
|
8
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
9
|
+
cancel-in-progress: true
|
|
10
|
+
jobs:
|
|
11
|
+
gitleaks:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 10
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
- uses: gitleaks/gitleaks-action@cb7149a9b57195b609c63e8518d2c6ef8e3475d3 # v2.3.9
|
|
19
|
+
env:
|
|
20
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Commit all staged changes, push to the current branch, and open a pull request.
|
|
2
|
+
|
|
3
|
+
1. Run the `/commit` flow (stage, draft message, commit).
|
|
4
|
+
2. Push: `git push -u origin HEAD`
|
|
5
|
+
3. Open a PR using the writing-pull-requests skill:
|
|
6
|
+
- Title: ≤70 chars, Conventional Commits format
|
|
7
|
+
- Body: Summary bullets + Test plan checklist
|
|
8
|
+
```bash
|
|
9
|
+
gh pr create --title "type(scope): description" --body "$(cat <<'EOF'
|
|
10
|
+
## Summary
|
|
11
|
+
- [what changed]
|
|
12
|
+
|
|
13
|
+
## Test plan
|
|
14
|
+
- [ ] [how to verify]
|
|
15
|
+
- [ ] Full suite passes: `npm test`
|
|
16
|
+
|
|
17
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
18
|
+
EOF
|
|
19
|
+
)"
|
|
20
|
+
```
|
|
21
|
+
4. Report the PR URL.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Stage changed files, draft a Conventional Commits message, and commit using the writing-commits skill.
|
|
2
|
+
|
|
3
|
+
1. Run `git status` to see what's changed.
|
|
4
|
+
2. Run `git diff --staged` — confirm no secrets, debug logs, or `.env*` files.
|
|
5
|
+
3. Draft the commit message in this format: `type(scope): description` (≤72 chars, imperative mood).
|
|
6
|
+
4. Commit using HEREDOC format:
|
|
7
|
+
```bash
|
|
8
|
+
git commit -m "$(cat <<'EOF'
|
|
9
|
+
type(scope): description
|
|
10
|
+
|
|
11
|
+
[optional body explaining WHY]
|
|
12
|
+
|
|
13
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
14
|
+
EOF
|
|
15
|
+
)"
|
|
16
|
+
```
|
|
17
|
+
5. Report: commit hash + message.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Investigate and fix a bug using the systematic-debugging skill.
|
|
2
|
+
|
|
3
|
+
1. Reproduce: confirm you can trigger the problem reliably.
|
|
4
|
+
2. Form hypotheses before touching code:
|
|
5
|
+
```
|
|
6
|
+
HYPOTHESES:
|
|
7
|
+
H1: [cause] → evidence needed: [what to check]
|
|
8
|
+
H2: [cause] → evidence needed: [what to check]
|
|
9
|
+
```
|
|
10
|
+
3. Test each hypothesis cheaply (add a temporary log/assertion, run the test).
|
|
11
|
+
4. Narrow to root cause — the one thing that explains all symptoms.
|
|
12
|
+
5. Fix only the root cause (minimal change).
|
|
13
|
+
6. Verify:
|
|
14
|
+
- Original reproduction no longer triggers the problem
|
|
15
|
+
- All existing tests pass
|
|
16
|
+
7. Write a regression test that would have caught this bug.
|
|
17
|
+
8. Remove any temporary debug output before committing.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Execute the current implementation plan using the executing-plans skill.
|
|
2
|
+
|
|
3
|
+
1. Read the full plan before starting.
|
|
4
|
+
2. Execute one step at a time:
|
|
5
|
+
- Make the change
|
|
6
|
+
- Verify (run affected test / check output)
|
|
7
|
+
- Report: `Step N done: [what changed]`
|
|
8
|
+
3. Pause on blockers: if a step fails or reveals new information, STOP and report before continuing.
|
|
9
|
+
4. After the last step:
|
|
10
|
+
- Run `npm test` (or the project's test command)
|
|
11
|
+
- Run `tsc --noEmit`
|
|
12
|
+
- Report: pass/fail count, any regressions
|
|
13
|
+
5. Use the verification-before-completion skill before claiming done.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Explore the codebase to understand how something works, using the codebase-exploration skill.
|
|
2
|
+
|
|
3
|
+
This is a read-only reconnaissance — no file edits during exploration.
|
|
4
|
+
|
|
5
|
+
1. Orient (≤3 minutes):
|
|
6
|
+
```bash
|
|
7
|
+
ls -la
|
|
8
|
+
cat package.json | head -30
|
|
9
|
+
git log --oneline -10
|
|
10
|
+
```
|
|
11
|
+
2. Find entry points (index.ts, main.go, app/layout.tsx, bin fields).
|
|
12
|
+
3. Trace the critical path for the feature/area in question:
|
|
13
|
+
- Triggering event → handler → service → data layer
|
|
14
|
+
- Note each I/O boundary
|
|
15
|
+
4. Map dependencies: what does this module import? What imports it?
|
|
16
|
+
5. Read the test file for the module before the source — tests reveal intent.
|
|
17
|
+
|
|
18
|
+
Output:
|
|
19
|
+
```
|
|
20
|
+
Understanding:
|
|
21
|
+
- Entry: [file:line]
|
|
22
|
+
- Critical path: [A → B → C]
|
|
23
|
+
- Key dependencies: [list]
|
|
24
|
+
- Gotchas: [anything surprising]
|
|
25
|
+
→ Ready to proceed / Need to clarify: [question]
|
|
26
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Write an implementation plan for the current task using the writing-plans skill.
|
|
2
|
+
|
|
3
|
+
1. Confirm the goal in one sentence (ask if unclear).
|
|
4
|
+
2. Explore the relevant codebase area: identify entry points, existing patterns, files to touch.
|
|
5
|
+
3. Produce a sequenced plan:
|
|
6
|
+
```
|
|
7
|
+
PLAN:
|
|
8
|
+
1. [action] — [why]
|
|
9
|
+
2. [action] — [why]
|
|
10
|
+
...
|
|
11
|
+
N. Run tests — confirm no regressions
|
|
12
|
+
→ Executing unless you redirect.
|
|
13
|
+
```
|
|
14
|
+
- Each step: one verifiable artifact produced
|
|
15
|
+
- Maximum 12 steps; split into phases if longer
|
|
16
|
+
- Label parallel steps: `(parallel with step N)`
|
|
17
|
+
|
|
18
|
+
4. Identify the key risk — the one decision that invalidates everything downstream.
|
|
19
|
+
5. Present the plan and wait for approval before executing.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Review recent changes using the requesting-code-review skill.
|
|
2
|
+
|
|
3
|
+
1. Gather context:
|
|
4
|
+
```bash
|
|
5
|
+
git diff main...HEAD --stat
|
|
6
|
+
git log main...HEAD --oneline
|
|
7
|
+
```
|
|
8
|
+
2. Dispatch the reviewer agent with:
|
|
9
|
+
- Files changed (list)
|
|
10
|
+
- What the change does (1-2 sentences)
|
|
11
|
+
- Intentional tradeoffs (things the reviewer might question)
|
|
12
|
+
- Focus areas or "general review"
|
|
13
|
+
3. For each finding:
|
|
14
|
+
- CRITICAL / MAJOR: fix before proceeding
|
|
15
|
+
- MINOR: note and consider
|
|
16
|
+
4. Implement all agreed-upon changes. Verify fixes with tests.
|
|
17
|
+
5. Report: "Review addressed — N changes made, M findings declined (reason)."
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Run an OWASP-aligned security sweep using the security-review skill.
|
|
2
|
+
|
|
3
|
+
Check the recent changes (or the specified scope) for:
|
|
4
|
+
|
|
5
|
+
**Injection (A03)**
|
|
6
|
+
- SQL queries use parameterised statements — no string concatenation
|
|
7
|
+
- Shell commands use execFile with arg arrays — no user data in shell strings
|
|
8
|
+
- Template rendering sanitises HTML output
|
|
9
|
+
|
|
10
|
+
**Auth & session (A07)**
|
|
11
|
+
- Tokens not in logs or error responses
|
|
12
|
+
- Session IDs regenerated on privilege escalation
|
|
13
|
+
|
|
14
|
+
**Sensitive data (A02)**
|
|
15
|
+
- No hardcoded secrets, API keys, or credentials
|
|
16
|
+
- Env vars validated at startup
|
|
17
|
+
- No sensitive fields in console.log output
|
|
18
|
+
|
|
19
|
+
**Access control (A01)**
|
|
20
|
+
- Every route checks authorisation, not just authentication
|
|
21
|
+
- Resource ownership verified
|
|
22
|
+
|
|
23
|
+
**Supply chain (A06)**
|
|
24
|
+
- No new dependencies without hygiene check
|
|
25
|
+
- `npm audit` passes
|
|
26
|
+
|
|
27
|
+
Output:
|
|
28
|
+
```
|
|
29
|
+
Security sweep: [scope]
|
|
30
|
+
✓ No issues in [category]
|
|
31
|
+
⚠ [category]: [finding] at [file:line] — [fix]
|
|
32
|
+
✗ [critical] — MUST fix before merge
|
|
33
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Run the full release checklist before tagging a release.
|
|
2
|
+
|
|
3
|
+
1. **Tests**: `npm test` — all pass, 0 failures.
|
|
4
|
+
2. **Types**: `tsc --noEmit` — clean.
|
|
5
|
+
3. **Lint**: `npm run lint` — clean.
|
|
6
|
+
4. **Security sweep**: run the `/security-review` command on changed files.
|
|
7
|
+
5. **Changelog**: confirm CHANGELOG.md or release notes are updated.
|
|
8
|
+
6. **Version bump**: update `package.json` version, commit with `chore(release): vX.Y.Z`.
|
|
9
|
+
7. **Tag**:
|
|
10
|
+
```bash
|
|
11
|
+
git tag -a vX.Y.Z -m "Release vX.Y.Z"
|
|
12
|
+
git push origin vX.Y.Z
|
|
13
|
+
```
|
|
14
|
+
8. **Publish** (if npm package):
|
|
15
|
+
```bash
|
|
16
|
+
npm publish --dry-run # inspect first
|
|
17
|
+
npm publish
|
|
18
|
+
```
|
|
19
|
+
9. **Post-release**: create a GitHub release with the changelog entry.
|
|
20
|
+
|
|
21
|
+
Only mark shipped when all 9 steps are complete.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Implement a feature or fix using test-driven development.
|
|
2
|
+
|
|
3
|
+
Follow the red-green-refactor loop:
|
|
4
|
+
|
|
5
|
+
**RED**: Write a failing test that describes the exact behaviour needed.
|
|
6
|
+
- Name: `it('should [verb] [noun] when [condition]', ...)`
|
|
7
|
+
- Assert on observable output, not internal implementation
|
|
8
|
+
- Run it — confirm it fails for the right reason (not a compile error)
|
|
9
|
+
|
|
10
|
+
**GREEN**: Write the minimal implementation to make the test pass.
|
|
11
|
+
- Only enough code to pass the test — no extra features
|
|
12
|
+
- Don't modify the test to make it pass
|
|
13
|
+
|
|
14
|
+
**CHECK**: Run the test suite — confirm the new test passes and nothing else broke.
|
|
15
|
+
|
|
16
|
+
**REFACTOR**: Clean up without changing behaviour.
|
|
17
|
+
- Remove duplication
|
|
18
|
+
- Improve naming
|
|
19
|
+
- Re-run tests after each change
|
|
20
|
+
|
|
21
|
+
Done when: all tests pass, no test was modified to accommodate implementation, no production code exists without a covering test.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "AI-agentic dev container",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",
|
|
4
|
+
"features": {
|
|
5
|
+
"ghcr.io/devcontainers/features/git:1": {},
|
|
6
|
+
"ghcr.io/devcontainers/features/github-cli:1": {}
|
|
7
|
+
},
|
|
8
|
+
"customizations": {
|
|
9
|
+
"vscode": {
|
|
10
|
+
"extensions": [
|
|
11
|
+
"anthropic.claude-code"
|
|
12
|
+
],
|
|
13
|
+
"settings": {
|
|
14
|
+
"terminal.integrated.defaultProfile.linux": "bash"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"forwardPorts": [],
|
|
19
|
+
"postCreateCommand": "npm install",
|
|
20
|
+
"remoteUser": "node",
|
|
21
|
+
"mounts": [
|
|
22
|
+
"source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached,readonly"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Blocks destructive shell commands before they execute.
|
|
3
|
+
# Fires on PreToolUse(Bash).
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT="$(cat)"
|
|
8
|
+
COMMAND="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))" 2>/dev/null || echo "")"
|
|
9
|
+
|
|
10
|
+
PATTERNS=(
|
|
11
|
+
"rm -rf /"
|
|
12
|
+
"rm -rf ~"
|
|
13
|
+
"rm -rf \*"
|
|
14
|
+
"dd if="
|
|
15
|
+
"mkfs"
|
|
16
|
+
":(){:|:&};:"
|
|
17
|
+
"chmod -R 777"
|
|
18
|
+
"> /dev/sda"
|
|
19
|
+
"shred -"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
for pattern in "${PATTERNS[@]}"; do
|
|
23
|
+
if echo "$COMMAND" | grep -qF "$pattern"; then
|
|
24
|
+
echo "BLOCKED: dangerous command pattern detected: $pattern" >&2
|
|
25
|
+
echo '{"decision":"block","reason":"Dangerous bash command blocked by haac-aikit safety hook"}'
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
done
|
|
29
|
+
|
|
30
|
+
echo '{"decision":"approve"}'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Blocks force-push to protected branches.
|
|
3
|
+
# Fires on PreToolUse(Bash).
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT="$(cat)"
|
|
8
|
+
COMMAND="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))" 2>/dev/null || echo "")"
|
|
9
|
+
|
|
10
|
+
PROTECTED_BRANCHES=("main" "master" "develop" "production" "staging")
|
|
11
|
+
|
|
12
|
+
if echo "$COMMAND" | grep -qE "git push.*(--force|-f)"; then
|
|
13
|
+
for branch in "${PROTECTED_BRANCHES[@]}"; do
|
|
14
|
+
if echo "$COMMAND" | grep -qE "(^| )${branch}( |$)"; then
|
|
15
|
+
echo "BLOCKED: force-push to protected branch '$branch'" >&2
|
|
16
|
+
echo "{\"decision\":\"block\",\"reason\":\"Force-push to $branch is blocked by haac-aikit safety hook. Use a PR instead.\"}"
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
done
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo '{"decision":"approve"}'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Blocks git commits when staged diff contains likely secrets.
|
|
3
|
+
# Fires on PreToolUse(Bash) when the command contains 'git commit'.
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT="$(cat)"
|
|
8
|
+
COMMAND="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))" 2>/dev/null || echo "")"
|
|
9
|
+
|
|
10
|
+
if ! echo "$COMMAND" | grep -q "git commit"; then
|
|
11
|
+
echo '{"decision":"approve"}'
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Check staged diff for secret-like patterns
|
|
16
|
+
DIFF="$(git diff --cached --unified=0 2>/dev/null || echo "")"
|
|
17
|
+
|
|
18
|
+
SECRET_PATTERNS=(
|
|
19
|
+
"AKIA[0-9A-Z]{16}" # AWS access key
|
|
20
|
+
"sk-[a-zA-Z0-9]{48}" # OpenAI API key
|
|
21
|
+
"ghp_[a-zA-Z0-9]{36}" # GitHub personal access token
|
|
22
|
+
"ghs_[a-zA-Z0-9]{36}" # GitHub app token
|
|
23
|
+
"xoxb-[0-9A-Za-z-]+" # Slack bot token
|
|
24
|
+
"password[[:space:]]*=[[:space:]]*['\"][^'\"]{8,}" # password = "..."
|
|
25
|
+
"secret[[:space:]]*=[[:space:]]*['\"][^'\"]{8,}" # secret = "..."
|
|
26
|
+
"api_key[[:space:]]*=[[:space:]]*['\"][^'\"]{8,}" # api_key = "..."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
for pattern in "${SECRET_PATTERNS[@]}"; do
|
|
30
|
+
if echo "$DIFF" | grep -qP "^\+.*${pattern}" 2>/dev/null; then
|
|
31
|
+
echo "BLOCKED: potential secret detected in staged changes (pattern: $pattern)" >&2
|
|
32
|
+
echo "{\"decision\":\"block\",\"reason\":\"Potential secret in staged diff. Review with 'git diff --cached' before committing.\"}"
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
echo '{"decision":"approve"}'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Writes a scratch file before compaction to preserve working state.
|
|
3
|
+
# Fires on PreCompact.
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRATCH_FILE=".claude/pre-compact-state.md"
|
|
8
|
+
mkdir -p .claude
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
echo "# Pre-compaction state"
|
|
12
|
+
echo "## Timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
13
|
+
echo ""
|
|
14
|
+
echo "## Modified files"
|
|
15
|
+
git status --porcelain 2>/dev/null || echo "(not a git repo)"
|
|
16
|
+
echo ""
|
|
17
|
+
echo "## Recent commits"
|
|
18
|
+
git log --oneline -5 2>/dev/null || echo "(not a git repo)"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "## Failing tests"
|
|
21
|
+
if [[ -f ".last-test-result" ]]; then
|
|
22
|
+
cat .last-test-result
|
|
23
|
+
else
|
|
24
|
+
echo "(no test result recorded)"
|
|
25
|
+
fi
|
|
26
|
+
} > "$SCRATCH_FILE"
|
|
27
|
+
|
|
28
|
+
echo "Pre-compact state saved to $SCRATCH_FILE"
|
|
29
|
+
exit 0
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Blocks reads and writes to sensitive files.
|
|
3
|
+
# Fires on PreToolUse(Read|Edit|Write).
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT="$(cat)"
|
|
8
|
+
FILE_PATH="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path','') or d.get('path',''))" 2>/dev/null || echo "")"
|
|
9
|
+
|
|
10
|
+
BLOCKED_PATTERNS=(
|
|
11
|
+
".env"
|
|
12
|
+
"secrets/"
|
|
13
|
+
".ssh/"
|
|
14
|
+
".aws/"
|
|
15
|
+
"*.pem"
|
|
16
|
+
"id_rsa"
|
|
17
|
+
"id_ed25519"
|
|
18
|
+
".netrc"
|
|
19
|
+
"credentials"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
for pattern in "${BLOCKED_PATTERNS[@]}"; do
|
|
23
|
+
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
|
|
24
|
+
echo "BLOCKED: access to sensitive file: $FILE_PATH" >&2
|
|
25
|
+
echo "{\"decision\":\"block\",\"reason\":\"Access to sensitive file blocked: $pattern. Override in .claude/settings.local.json if needed.\"}"
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
done
|
|
29
|
+
|
|
30
|
+
echo '{"decision":"approve"}'
|