all-for-claudecode 2.4.0 → 2.6.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +15 -3
- package/agents/afc-impl-worker.md +2 -0
- package/agents/afc-pr-analyst.md +57 -0
- package/agents/afc-security.md +5 -0
- package/commands/auto.md +1 -1
- package/commands/doctor.md +63 -22
- package/commands/implement.md +14 -10
- package/commands/init.md +42 -21
- package/commands/pr-comment.md +181 -0
- package/commands/qa.md +191 -0
- package/commands/release-notes.md +219 -0
- package/commands/resume.md +1 -1
- package/commands/triage.md +222 -0
- package/docs/phase-gate-protocol.md +1 -1
- package/package.json +6 -4
- package/scripts/afc-bash-guard.sh +3 -3
- package/scripts/afc-blast-radius.sh +41 -119
- package/scripts/afc-config-change.sh +8 -0
- package/scripts/afc-consistency-check.sh +58 -19
- package/scripts/afc-dag-validate.sh +1 -1
- package/scripts/afc-doctor.sh +445 -0
- package/scripts/afc-failure-hint.sh +24 -2
- package/scripts/afc-qa-audit.sh +536 -0
- package/scripts/afc-state.sh +3 -3
- package/scripts/afc-subagent-context.sh +1 -1
- package/scripts/afc-sync-cache.sh +49 -0
- package/scripts/afc-triage.sh +142 -0
- package/scripts/afc-user-prompt-submit.sh +9 -4
- package/scripts/pre-compact-checkpoint.sh +2 -2
- package/scripts/session-start-context.sh +27 -1
- package/scripts/track-afc-changes.sh +3 -3
package/commands/qa.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: afc:qa
|
|
3
|
+
description: "Project quality audit — detect gaps between structure and runtime behavior"
|
|
4
|
+
argument-hint: "[scope: all, tests, errors, coverage, or specific concern]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
context: fork
|
|
7
|
+
allowed-tools:
|
|
8
|
+
- Read
|
|
9
|
+
- Grep
|
|
10
|
+
- Glob
|
|
11
|
+
- Bash
|
|
12
|
+
model: sonnet
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# /afc:qa — Project Quality Audit
|
|
16
|
+
|
|
17
|
+
> Detects quality gaps between structural correctness and actual runtime behavior.
|
|
18
|
+
> **Read-only** — does not modify any files. Reports findings to console only.
|
|
19
|
+
|
|
20
|
+
## Arguments
|
|
21
|
+
|
|
22
|
+
- `$ARGUMENTS` — (optional) scope of audit. Defaults to `all`.
|
|
23
|
+
- `all` — run all 5 categories
|
|
24
|
+
- `tests` — category A only (Test Confidence)
|
|
25
|
+
- `errors` — category B only (Error Resilience)
|
|
26
|
+
- `coverage` — categories A + D (Test Confidence + API & Contract Safety)
|
|
27
|
+
- Or a free-form concern (e.g., "are error messages user-friendly", "check for dead exports")
|
|
28
|
+
|
|
29
|
+
## Config Load
|
|
30
|
+
|
|
31
|
+
**Always** read `.claude/afc.config.md` first. This file contains free-form markdown sections:
|
|
32
|
+
- `## Architecture` — architecture pattern, layers, import rules
|
|
33
|
+
- `## Code Style` — language, naming conventions, lint rules
|
|
34
|
+
- `## CI Commands` — test, lint, gate commands (YAML)
|
|
35
|
+
- `## Project Context` — framework, state management, testing strategy
|
|
36
|
+
|
|
37
|
+
If config file is missing: read `CLAUDE.md` for project info. Proceed without config if neither exists.
|
|
38
|
+
|
|
39
|
+
## Audit Categories
|
|
40
|
+
|
|
41
|
+
### A. Test Confidence
|
|
42
|
+
|
|
43
|
+
Evaluate whether the test suite actually catches regressions.
|
|
44
|
+
|
|
45
|
+
Checks:
|
|
46
|
+
- **Assertion density**: ratio of assertions to test functions (low ratio = weak tests)
|
|
47
|
+
- **Test-to-code ratio**: test LOC vs source LOC per layer (guided by `{config.architecture}`)
|
|
48
|
+
- **Mock overuse**: tests that mock so much they only test the mock setup
|
|
49
|
+
- **Runtime verification**: execute `{config.test}` and analyze output (pass/fail counts, skipped tests, timing)
|
|
50
|
+
- **Missing coverage**: source files/modules with zero test coverage
|
|
51
|
+
|
|
52
|
+
### B. Error Resilience
|
|
53
|
+
|
|
54
|
+
Evaluate whether errors are handled consistently and helpfully.
|
|
55
|
+
|
|
56
|
+
Checks:
|
|
57
|
+
- **Catch consistency**: unhandled promise rejections, empty catch blocks, swallowed errors
|
|
58
|
+
- **Error propagation**: errors that lose context through the call chain
|
|
59
|
+
- **User-facing messages**: cryptic error strings, raw stack traces exposed to users
|
|
60
|
+
- **Boundary validation**: missing input validation at API/CLI/form boundaries
|
|
61
|
+
- Apply `{config.code_style}` error handling rules if available
|
|
62
|
+
|
|
63
|
+
### C. Build & CI Integrity
|
|
64
|
+
|
|
65
|
+
Evaluate whether CI pipeline is healthy and reproducible.
|
|
66
|
+
|
|
67
|
+
Checks:
|
|
68
|
+
- **CI execution**: run `{config.ci}` and `{config.gate}` commands, verify they pass
|
|
69
|
+
- **Lock file integrity**: lock file present, consistent with manifest (package.json vs lock, etc.)
|
|
70
|
+
- **Unused dependencies**: declared but never imported packages
|
|
71
|
+
- **Build reproducibility**: environment-dependent paths, hardcoded secrets, missing env vars
|
|
72
|
+
|
|
73
|
+
### D. API & Contract Safety
|
|
74
|
+
|
|
75
|
+
Evaluate whether interfaces between modules are sound.
|
|
76
|
+
|
|
77
|
+
Checks:
|
|
78
|
+
- **Type mismatches**: function signatures vs actual usage at call sites
|
|
79
|
+
- **Dead exports**: exported symbols never imported elsewhere
|
|
80
|
+
- **Deprecated usage**: calls to deprecated APIs (internal or external)
|
|
81
|
+
- **Layer boundary violations**: imports that cross architecture boundaries (guided by `{config.architecture}`)
|
|
82
|
+
|
|
83
|
+
### E. Code Health Signals
|
|
84
|
+
|
|
85
|
+
Evaluate general code quality indicators.
|
|
86
|
+
|
|
87
|
+
Checks:
|
|
88
|
+
- **Complexity hotspots**: deeply nested logic, functions exceeding ~50 LOC
|
|
89
|
+
- **Duplication**: near-identical code blocks across files
|
|
90
|
+
- **Magic numbers/strings**: unexplained literals in logic
|
|
91
|
+
- **TODO/FIXME accumulation**: stale markers (count, age if git history available)
|
|
92
|
+
- Compare against `{config.code_style}` rules if available
|
|
93
|
+
|
|
94
|
+
## Execution Steps
|
|
95
|
+
|
|
96
|
+
### 1. Load Config
|
|
97
|
+
|
|
98
|
+
Read `.claude/afc.config.md` (or fallback to `CLAUDE.md`). Extract:
|
|
99
|
+
- Test command (`{config.test}`)
|
|
100
|
+
- CI/gate commands (`{config.ci}`, `{config.gate}`)
|
|
101
|
+
- Architecture layers (`{config.architecture}`)
|
|
102
|
+
- Code style rules (`{config.code_style}`)
|
|
103
|
+
|
|
104
|
+
### 2. Parse Scope
|
|
105
|
+
|
|
106
|
+
Interpret `$ARGUMENTS` to determine which categories to run:
|
|
107
|
+
|
|
108
|
+
| Argument | Categories |
|
|
109
|
+
|----------|-----------|
|
|
110
|
+
| `all` or empty | A, B, C, D, E |
|
|
111
|
+
| `tests` | A |
|
|
112
|
+
| `errors` | B |
|
|
113
|
+
| `coverage` | A, D |
|
|
114
|
+
| free-form text | best-matching subset |
|
|
115
|
+
|
|
116
|
+
### 3. Lightweight Runtime
|
|
117
|
+
|
|
118
|
+
Run commands that produce real output:
|
|
119
|
+
- `{config.test}` — capture pass/fail/skip counts and timing
|
|
120
|
+
- `{config.gate}` or `{config.ci}` — capture exit code and output
|
|
121
|
+
|
|
122
|
+
Only run commands that exist in config. Skip gracefully if not configured.
|
|
123
|
+
|
|
124
|
+
### 4. Codebase Scan
|
|
125
|
+
|
|
126
|
+
For each active category:
|
|
127
|
+
1. Use Glob to discover relevant files
|
|
128
|
+
2. Use Grep for pattern-based detection (empty catches, TODO markers, etc.)
|
|
129
|
+
3. Use Read for targeted inspection of flagged files
|
|
130
|
+
4. Cross-reference findings against `{config.architecture}` layer structure
|
|
131
|
+
|
|
132
|
+
### 5. Critic Loop
|
|
133
|
+
|
|
134
|
+
Apply `docs/critic-loop-rules.md` with **safety cap: 3 rounds**.
|
|
135
|
+
|
|
136
|
+
Focus the critic on:
|
|
137
|
+
- Are the findings actionable or just noise?
|
|
138
|
+
- Did I miss obvious quality gaps?
|
|
139
|
+
- Are severity ratings justified by evidence?
|
|
140
|
+
|
|
141
|
+
### 6. Console Report
|
|
142
|
+
|
|
143
|
+
Output the final report in this format:
|
|
144
|
+
|
|
145
|
+
```markdown
|
|
146
|
+
## QA Audit: {project name or directory}
|
|
147
|
+
|
|
148
|
+
### Category A: Test Confidence
|
|
149
|
+
{findings with file:line references}
|
|
150
|
+
Verdict: PASS | WARN | FAIL
|
|
151
|
+
|
|
152
|
+
### Category B: Error Resilience
|
|
153
|
+
{findings with file:line references}
|
|
154
|
+
Verdict: PASS | WARN | FAIL
|
|
155
|
+
|
|
156
|
+
### Category C: Build & CI Integrity
|
|
157
|
+
{findings with file:line references}
|
|
158
|
+
Verdict: PASS | WARN | FAIL
|
|
159
|
+
|
|
160
|
+
### Category D: API & Contract Safety
|
|
161
|
+
{findings with file:line references}
|
|
162
|
+
Verdict: PASS | WARN | FAIL
|
|
163
|
+
|
|
164
|
+
### Category E: Code Health Signals
|
|
165
|
+
{findings with file:line references}
|
|
166
|
+
Verdict: PASS | WARN | FAIL
|
|
167
|
+
|
|
168
|
+
### Summary
|
|
169
|
+
├─ A: Test Confidence — {PASS|WARN|FAIL} {(N issues) if any}
|
|
170
|
+
├─ B: Error Resilience — {PASS|WARN|FAIL} {(N issues) if any}
|
|
171
|
+
├─ C: Build & CI — {PASS|WARN|FAIL} {(N issues) if any}
|
|
172
|
+
├─ D: API & Contract — {PASS|WARN|FAIL} {(N issues) if any}
|
|
173
|
+
└─ E: Code Health — {PASS|WARN|FAIL} {(N issues) if any}
|
|
174
|
+
|
|
175
|
+
Total: {N} PASS, {N} WARN, {N} FAIL
|
|
176
|
+
Priority fixes: {top 3 most impactful issues}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Verdict Criteria
|
|
180
|
+
|
|
181
|
+
- **PASS** — no issues found, or only cosmetic observations
|
|
182
|
+
- **WARN** — issues found but not blocking; quality could degrade over time
|
|
183
|
+
- **FAIL** — critical gaps that likely cause bugs, outages, or security issues
|
|
184
|
+
|
|
185
|
+
## Notes
|
|
186
|
+
|
|
187
|
+
- **Read-only**: Do not modify any files. Report only.
|
|
188
|
+
- **Evidence-based**: Every finding must include a `file:line` reference or command output.
|
|
189
|
+
- **Config-aware**: Adapt checks to the project's declared architecture and conventions.
|
|
190
|
+
- **Scope discipline**: Only run categories matching the requested scope.
|
|
191
|
+
- **Not a linter**: Focus on semantic quality gaps that automated tools miss.
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: afc:release-notes
|
|
3
|
+
description: "Generate user-facing release notes from git history"
|
|
4
|
+
argument-hint: "[v1.0.0..v2.0.0 | v2.0.0 | --post]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
model: sonnet
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# /afc:release-notes — Generate Release Notes
|
|
14
|
+
|
|
15
|
+
> Rewrites commit/PR history into user-facing release notes and optionally publishes to GitHub Releases.
|
|
16
|
+
> This is a **standalone utility** — not part of the auto pipeline.
|
|
17
|
+
> Does NOT modify local files (CHANGELOG updates are handled by `/afc:launch`).
|
|
18
|
+
|
|
19
|
+
## Arguments
|
|
20
|
+
|
|
21
|
+
- `$ARGUMENTS` — (optional) Version range and flags
|
|
22
|
+
- `v2.3.0..v2.4.0` — specific tag range
|
|
23
|
+
- `v2.4.0` — from that tag to HEAD
|
|
24
|
+
- Not specified — auto-detect last tag to HEAD
|
|
25
|
+
- `--post` — publish to GitHub Releases after preview (can combine with any range)
|
|
26
|
+
|
|
27
|
+
Parse the arguments:
|
|
28
|
+
1. Extract `--post` flag if present
|
|
29
|
+
2. Parse remaining as version range:
|
|
30
|
+
- If contains `..`: split into `{from_tag}..{to_tag}`
|
|
31
|
+
- If single version: use `{version}..HEAD`
|
|
32
|
+
- If empty: auto-detect with `git describe --tags --abbrev=0`
|
|
33
|
+
|
|
34
|
+
## Execution Steps
|
|
35
|
+
|
|
36
|
+
### 1. Determine Range
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Auto-detect last tag if no range specified
|
|
40
|
+
git describe --tags --abbrev=0 2>/dev/null
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- If a tag is found, set `from_tag` to that tag, `to_tag` to HEAD
|
|
44
|
+
- If no tags exist, inform the user: "No tags found. Include all commits? (y/n)"
|
|
45
|
+
- If a `to_tag` is specified (not HEAD), verify it exists: `git rev-parse --verify {to_tag} 2>/dev/null`
|
|
46
|
+
- Determine the version label for the notes header:
|
|
47
|
+
- If `to_tag` is a version tag: use it (e.g., `v2.4.0`)
|
|
48
|
+
- If `to_tag` is HEAD: use "Unreleased" or the `from_tag` bumped (ask user)
|
|
49
|
+
|
|
50
|
+
### 2. Collect Raw Data
|
|
51
|
+
|
|
52
|
+
Run these commands to gather change context:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Commit history (no merges)
|
|
56
|
+
git log {from_tag}..{to_tag} --pretty=format:"%H %s" --no-merges
|
|
57
|
+
|
|
58
|
+
# Merged PRs since the from_tag date
|
|
59
|
+
from_date=$(git log -1 --format=%aI {from_tag})
|
|
60
|
+
gh pr list --state merged --search "merged:>$from_date" --json number,title,author,labels,body --limit 100
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If `gh` is not available or the repo has no remote, skip PR collection — proceed with git-only data.
|
|
64
|
+
|
|
65
|
+
### 3. Detect Breaking Changes
|
|
66
|
+
|
|
67
|
+
Search commit messages and PR titles for breaking change indicators:
|
|
68
|
+
|
|
69
|
+
- Patterns: `BREAKING`, `BREAKING CHANGE`, `!:` (conventional commits `feat!:`, `fix!:`)
|
|
70
|
+
- Also check PR labels for: `breaking`, `breaking-change`, `semver-major`
|
|
71
|
+
|
|
72
|
+
Flag any matches for the Breaking Changes section.
|
|
73
|
+
|
|
74
|
+
### 4. Categorize and Rewrite
|
|
75
|
+
|
|
76
|
+
Categorize each commit/PR into one of:
|
|
77
|
+
|
|
78
|
+
| Category | Conventional Commit Prefixes | Fallback Heuristics |
|
|
79
|
+
|----------|------------------------------|---------------------|
|
|
80
|
+
| Breaking Changes | `!:` suffix, `BREAKING` | Label: `breaking` |
|
|
81
|
+
| New Features | `feat:` | "add", "new", "implement", "support" |
|
|
82
|
+
| Bug Fixes | `fix:` | "fix", "resolve", "correct", "patch" |
|
|
83
|
+
| Other Changes | `chore:`, `docs:`, `ci:`, `refactor:`, `perf:`, `test:`, `style:`, `build:` | Everything else |
|
|
84
|
+
|
|
85
|
+
**Rewriting rules** — transform each entry from developer-speak to user-facing language:
|
|
86
|
+
|
|
87
|
+
1. Remove conventional commit prefixes (`feat:`, `fix(scope):`, etc.)
|
|
88
|
+
2. Rewrite in terms of **what the user experiences**, not what the developer changed
|
|
89
|
+
- Bad: "Refactor ThemeProvider to use context API"
|
|
90
|
+
- Good: "Improved theme switching reliability"
|
|
91
|
+
- Bad: "Fix race condition in afc-state.sh"
|
|
92
|
+
- Good: "Fixed an issue where pipeline state could become corrupted during concurrent execution"
|
|
93
|
+
3. Merge related commits into a single entry when they address the same feature/fix
|
|
94
|
+
4. Include PR number references where available: `(#42)`
|
|
95
|
+
5. For breaking changes, add a brief migration note after the description
|
|
96
|
+
|
|
97
|
+
### 5. Collect Contributor Info
|
|
98
|
+
|
|
99
|
+
Build a contributors section:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Get commit authors with their commit counts
|
|
103
|
+
git log {from_tag}..{to_tag} --format="%aN" | sort | uniq -c | sort -rn
|
|
104
|
+
|
|
105
|
+
# Resolve repo identity for GitHub username lookup
|
|
106
|
+
gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'
|
|
107
|
+
|
|
108
|
+
# Map git authors to GitHub usernames via commit SHAs
|
|
109
|
+
git log {from_tag}..{to_tag} --format="%H" | head -100 | while read sha; do
|
|
110
|
+
gh api "repos/{owner}/{repo}/commits/$sha" --jq '.author.login // empty' 2>/dev/null
|
|
111
|
+
done | sort -u
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For each contributor:
|
|
115
|
+
- Try to resolve GitHub username via the commit SHA lookup above, or from PR author data collected in step 2
|
|
116
|
+
- List their PR numbers if available
|
|
117
|
+
- Fall back to git author name if no GitHub username found
|
|
118
|
+
- If `gh` is not available, skip username resolution entirely — use git author names
|
|
119
|
+
|
|
120
|
+
### 6. Compose Release Notes
|
|
121
|
+
|
|
122
|
+
Assemble the final release notes in this format:
|
|
123
|
+
|
|
124
|
+
```markdown
|
|
125
|
+
# {version}
|
|
126
|
+
|
|
127
|
+
{2-3 sentence summary: what is the most important thing in this release? Written for end users.}
|
|
128
|
+
|
|
129
|
+
## Breaking Changes
|
|
130
|
+
|
|
131
|
+
- {description + migration guide}
|
|
132
|
+
|
|
133
|
+
## New Features
|
|
134
|
+
|
|
135
|
+
- {user-facing description} (#{pr_number})
|
|
136
|
+
|
|
137
|
+
## Bug Fixes
|
|
138
|
+
|
|
139
|
+
- {user-facing description} (#{pr_number})
|
|
140
|
+
|
|
141
|
+
## Other Changes
|
|
142
|
+
|
|
143
|
+
- {description} (#{pr_number})
|
|
144
|
+
|
|
145
|
+
## Contributors
|
|
146
|
+
|
|
147
|
+
{contributor list with @mentions and PR numbers}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Format rules**:
|
|
151
|
+
- Omit empty sections entirely (if no breaking changes, skip that section)
|
|
152
|
+
- Breaking Changes section always comes first when present
|
|
153
|
+
- Each entry is a single bullet point, max 2 sentences
|
|
154
|
+
- Summary paragraph should highlight the top 1-2 changes
|
|
155
|
+
- Contributors section: `@username (#42, #45)` format, or `Name (#42)` if no GitHub username
|
|
156
|
+
|
|
157
|
+
### 7. Preview Output
|
|
158
|
+
|
|
159
|
+
Display the complete release notes to the user in the console.
|
|
160
|
+
|
|
161
|
+
Print a summary:
|
|
162
|
+
```
|
|
163
|
+
Release notes generated
|
|
164
|
+
├─ Version: {version}
|
|
165
|
+
├─ Range: {from_tag}..{to_tag}
|
|
166
|
+
├─ Commits: {N}
|
|
167
|
+
├─ PRs referenced: {N}
|
|
168
|
+
├─ Breaking changes: {count or "none"}
|
|
169
|
+
├─ Contributors: {N}
|
|
170
|
+
└─ --post: {will publish / preview only}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 8. Publish to GitHub Releases (if --post)
|
|
174
|
+
|
|
175
|
+
If `--post` flag is present:
|
|
176
|
+
|
|
177
|
+
1. Determine the tag name:
|
|
178
|
+
- If `to_tag` is a specific tag: use it
|
|
179
|
+
- If `to_tag` is HEAD: ask the user what tag to create (suggest next version)
|
|
180
|
+
|
|
181
|
+
2. Ask user to confirm using AskUserQuestion:
|
|
182
|
+
- **Post as-is** — Publish the GitHub Release immediately
|
|
183
|
+
- **Post as draft** — Create as draft release (can review and publish later from GitHub)
|
|
184
|
+
- **Edit first** — Let me modify the notes before posting
|
|
185
|
+
- **Cancel** — Do not post
|
|
186
|
+
|
|
187
|
+
3. On approval, write to a temp file and publish:
|
|
188
|
+
```bash
|
|
189
|
+
tmp_file=$(mktemp)
|
|
190
|
+
cat > "$tmp_file" << 'NOTES_EOF'
|
|
191
|
+
{release notes content}
|
|
192
|
+
NOTES_EOF
|
|
193
|
+
# Add --draft if user chose "Post as draft"
|
|
194
|
+
gh release create {tag} --notes-file "$tmp_file" --title "{version}" [--draft]
|
|
195
|
+
rm -f "$tmp_file"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
4. Print result:
|
|
199
|
+
```
|
|
200
|
+
GitHub Release published
|
|
201
|
+
├─ Tag: {tag}
|
|
202
|
+
├─ Title: {version}
|
|
203
|
+
├─ Status: {published / draft}
|
|
204
|
+
└─ URL: {release URL from gh output}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
If `--post` is not present, print:
|
|
208
|
+
```
|
|
209
|
+
To publish these notes as a GitHub Release, run again with --post flag.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Notes
|
|
213
|
+
|
|
214
|
+
- **Read-only by default**: Without `--post`, this command only outputs to console. No files are created or modified.
|
|
215
|
+
- **Complements `/afc:launch`**: Use `launch` for local artifact generation (CHANGELOG, README). Use `release-notes` for GitHub Release publishing.
|
|
216
|
+
- **Conventional Commits aware**: Projects using conventional commits get better categorization. Projects without them still get reasonable results via heuristic matching.
|
|
217
|
+
- **Contributor attribution**: Best effort. GitHub username resolution requires `gh` CLI and repository access.
|
|
218
|
+
- **User confirmation required**: `--post` always asks for explicit approval before publishing to GitHub.
|
|
219
|
+
- **Idempotent**: Running without `--post` is safe to repeat. With `--post`, GitHub Releases for existing tags will fail (GitHub does not allow duplicate release tags).
|
package/commands/resume.md
CHANGED
|
@@ -22,7 +22,7 @@ allowed-tools:
|
|
|
22
22
|
### 1. Load Checkpoint
|
|
23
23
|
|
|
24
24
|
Read `.claude/afc/memory/checkpoint.md`:
|
|
25
|
-
- If not found: check **auto-memory fallback** — read `~/.claude/projects/{ENCODED_PATH}/
|
|
25
|
+
- If not found: check **auto-memory fallback** — read `~/.claude/projects/{ENCODED_PATH}/memory/checkpoint.md` (where `ENCODED_PATH` = project path with `/` replaced by `-`):
|
|
26
26
|
- If fallback found: use it as the checkpoint source (auto-memory is written by `pre-compact-checkpoint.sh` during context compaction)
|
|
27
27
|
- If fallback also not found: output "No saved checkpoint found. Use `/afc:checkpoint` to create one, or checkpoints are created automatically on context compaction." then **stop**
|
|
28
28
|
- If found: parse the full contents (extract branch, commit hash, pipeline feature, task progress, modified files)
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: afc:triage
|
|
3
|
+
description: "Parallel triage of open PRs and issues"
|
|
4
|
+
argument-hint: "[scope: --pr, --issue, --all (default), or specific numbers]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Grep
|
|
8
|
+
- Glob
|
|
9
|
+
- Bash
|
|
10
|
+
- Task
|
|
11
|
+
- Write
|
|
12
|
+
model: sonnet
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# /afc:triage — PR & Issue Triage
|
|
16
|
+
|
|
17
|
+
> Collects open PRs and issues, analyzes them in parallel, and produces a priority-ranked triage report.
|
|
18
|
+
> Uses lightweight analysis first (no checkout), then selective deep analysis with worktree isolation for PRs that require build/test verification.
|
|
19
|
+
|
|
20
|
+
## Arguments
|
|
21
|
+
|
|
22
|
+
- `$ARGUMENTS` — (optional) Triage scope
|
|
23
|
+
- `--pr` — PRs only
|
|
24
|
+
- `--issue` — Issues only
|
|
25
|
+
- `--all` — Both PRs and issues (default)
|
|
26
|
+
- Specific numbers (e.g., `#42 #43`) — Analyze only those items
|
|
27
|
+
- `--deep` — Force deep analysis (worktree) for all PRs
|
|
28
|
+
|
|
29
|
+
## Execution Steps
|
|
30
|
+
|
|
31
|
+
### 1. Collect Targets
|
|
32
|
+
|
|
33
|
+
Run the metadata collection script:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
"${CLAUDE_PLUGIN_ROOT}/scripts/afc-triage.sh" "$ARGUMENTS"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This returns JSON with PR/issue metadata. If the script is not available, fall back to direct `gh` commands:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# PRs
|
|
43
|
+
gh pr list --json number,title,headRefName,author,labels,additions,deletions,changedFiles,createdAt,updatedAt,reviewDecision,isDraft --limit 50
|
|
44
|
+
|
|
45
|
+
# Issues
|
|
46
|
+
gh issue list --json number,title,labels,author,createdAt,updatedAt,comments --limit 50
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. Phase 1 — Lightweight Parallel Analysis (no checkout)
|
|
50
|
+
|
|
51
|
+
For each PR/issue, gather analysis data **without** checking out branches:
|
|
52
|
+
|
|
53
|
+
#### PR Analysis (parallel — one agent per PR, max 5 concurrent)
|
|
54
|
+
|
|
55
|
+
Spawn parallel agents in a **single message**:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Task("Triage PR #{number}: {title}", subagent_type: "general-purpose",
|
|
59
|
+
prompt: "Analyze this PR without checking out the branch.
|
|
60
|
+
|
|
61
|
+
PR #{number}: {title}
|
|
62
|
+
Author: {author}
|
|
63
|
+
Branch: {headRefName}
|
|
64
|
+
Changed files: {changedFiles}, +{additions}/-{deletions}
|
|
65
|
+
Labels: {labels}
|
|
66
|
+
Review status: {reviewDecision}
|
|
67
|
+
Draft: {isDraft}
|
|
68
|
+
|
|
69
|
+
Steps:
|
|
70
|
+
1. Run: gh pr diff {number}
|
|
71
|
+
2. Run: gh pr view {number} --comments
|
|
72
|
+
3. Analyze the diff for:
|
|
73
|
+
- What the PR does (1-2 sentence summary)
|
|
74
|
+
- Risk level: Critical (core logic, auth, data) / Medium (features, UI) / Low (docs, config, tests)
|
|
75
|
+
- Complexity: High (>10 files or cross-cutting) / Medium (3-10 files) / Low (<3 files)
|
|
76
|
+
- Whether build/test verification is needed (yes/no + reason)
|
|
77
|
+
- Potential issues or concerns (max 3)
|
|
78
|
+
- Suggested reviewers or labels if obvious
|
|
79
|
+
|
|
80
|
+
Output as structured text:
|
|
81
|
+
SUMMARY: ...
|
|
82
|
+
RISK: Critical|Medium|Low
|
|
83
|
+
COMPLEXITY: High|Medium|Low
|
|
84
|
+
NEEDS_DEEP: yes|no
|
|
85
|
+
DEEP_REASON: ... (if yes)
|
|
86
|
+
CONCERNS: ...
|
|
87
|
+
SUGGESTION: ...")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Issue Analysis (parallel — one agent per batch of 5 issues)
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Task("Triage Issues #{n1}-#{n5}", subagent_type: "general-purpose",
|
|
94
|
+
prompt: "Analyze these issues:
|
|
95
|
+
{issue list with titles, labels, comment count}
|
|
96
|
+
|
|
97
|
+
For each issue:
|
|
98
|
+
1. Read issue body and comments: gh issue view {number} --comments
|
|
99
|
+
2. Classify:
|
|
100
|
+
- Type: Bug / Feature / Enhancement / Question / Maintenance
|
|
101
|
+
- Priority: P0 (blocking) / P1 (important) / P2 (nice-to-have) / P3 (backlog)
|
|
102
|
+
- Estimated effort: Small (< 1 day) / Medium (1-3 days) / Large (3+ days)
|
|
103
|
+
- Related PRs (if any mentioned)
|
|
104
|
+
3. One-line summary
|
|
105
|
+
|
|
106
|
+
Output as structured text per issue:
|
|
107
|
+
ISSUE #{number}: {title}
|
|
108
|
+
TYPE: ...
|
|
109
|
+
PRIORITY: P0|P1|P2|P3
|
|
110
|
+
EFFORT: Small|Medium|Large
|
|
111
|
+
RELATED_PR: #N or none
|
|
112
|
+
SUMMARY: ...")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3. Phase 2 — Selective Deep Analysis (worktree, optional)
|
|
116
|
+
|
|
117
|
+
From Phase 1 results, identify PRs where `NEEDS_DEEP: yes`.
|
|
118
|
+
|
|
119
|
+
For each deep-analysis PR, spawn a **worktree-isolated agent**:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Task("Deep triage PR #{number}", subagent_type: "afc:afc-pr-analyst",
|
|
123
|
+
isolation: "worktree",
|
|
124
|
+
prompt: "Deep-analyze PR #{number} ({title}).
|
|
125
|
+
|
|
126
|
+
Branch: {headRefName}
|
|
127
|
+
Phase 1 concerns: {concerns from Phase 1}
|
|
128
|
+
|
|
129
|
+
Steps:
|
|
130
|
+
1. Checkout the PR branch: gh pr checkout {number}
|
|
131
|
+
2. Run project CI/test commands if available (from .claude/afc.config.md or CLAUDE.md)
|
|
132
|
+
3. Check for type errors, lint issues, test failures
|
|
133
|
+
4. Analyze architectural impact
|
|
134
|
+
5. Report findings
|
|
135
|
+
|
|
136
|
+
Output:
|
|
137
|
+
BUILD_STATUS: pass|fail|skip
|
|
138
|
+
TEST_STATUS: pass|fail|skip (N passed, M failed)
|
|
139
|
+
LINT_STATUS: pass|fail|skip
|
|
140
|
+
DEEP_FINDINGS: ...
|
|
141
|
+
RECOMMENDATION: merge|request-changes|needs-discussion")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Important**: Launch at most 3 worktree agents concurrently to avoid resource contention.
|
|
145
|
+
|
|
146
|
+
If `--deep` flag was specified, run Phase 2 for **all** PRs regardless of Phase 1 classification.
|
|
147
|
+
|
|
148
|
+
### 4. Consolidate Triage Report
|
|
149
|
+
|
|
150
|
+
Merge Phase 1 and Phase 2 results into a single report:
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
# Triage Report
|
|
154
|
+
|
|
155
|
+
> Date: {YYYY-MM-DD}
|
|
156
|
+
> Repository: {owner/repo}
|
|
157
|
+
> Scope: {PRs: N, Issues: M}
|
|
158
|
+
|
|
159
|
+
## PRs ({count})
|
|
160
|
+
|
|
161
|
+
### Priority Actions
|
|
162
|
+
|
|
163
|
+
| # | Title | Risk | Complexity | Status | Action |
|
|
164
|
+
|---|-------|------|------------|--------|--------|
|
|
165
|
+
| {sorted by: Critical first, then by staleness} |
|
|
166
|
+
|
|
167
|
+
### PR Details
|
|
168
|
+
|
|
169
|
+
#### PR #{number}: {title}
|
|
170
|
+
- **Author**: {author} | **Branch**: {branch}
|
|
171
|
+
- **Changes**: +{add}/-{del} across {files} files
|
|
172
|
+
- **Risk**: {risk} | **Complexity**: {complexity}
|
|
173
|
+
- **Summary**: {summary}
|
|
174
|
+
- **Concerns**: {concerns or "None"}
|
|
175
|
+
- **Deep analysis**: {findings if Phase 2 ran, otherwise "Skipped"}
|
|
176
|
+
- **Recommendation**: {recommendation}
|
|
177
|
+
|
|
178
|
+
## Issues ({count})
|
|
179
|
+
|
|
180
|
+
### By Priority
|
|
181
|
+
|
|
182
|
+
| Priority | # | Title | Type | Effort | Related PR |
|
|
183
|
+
|----------|---|-------|------|--------|------------|
|
|
184
|
+
| {sorted by priority, then by creation date} |
|
|
185
|
+
|
|
186
|
+
## Summary
|
|
187
|
+
|
|
188
|
+
- **Immediate attention**: {list of Critical PRs and P0 issues}
|
|
189
|
+
- **Ready to merge**: {PRs with no concerns and passing checks}
|
|
190
|
+
- **Needs discussion**: {PRs/issues requiring team input}
|
|
191
|
+
- **Stale items**: {PRs/issues with no activity > 14 days}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 5. Save Report
|
|
195
|
+
|
|
196
|
+
Save the triage report:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
.claude/afc/memory/triage/{YYYY-MM-DD}.md
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
If a previous triage report exists for today, overwrite it.
|
|
203
|
+
|
|
204
|
+
### 6. Final Output
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
Triage complete
|
|
208
|
+
├─ PRs analyzed: {N} (deep: {M})
|
|
209
|
+
├─ Issues analyzed: {N}
|
|
210
|
+
├─ Immediate attention: {count}
|
|
211
|
+
├─ Ready to merge: {count}
|
|
212
|
+
├─ Report: .claude/afc/memory/triage/{date}.md
|
|
213
|
+
└─ Duration: {elapsed}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Notes
|
|
217
|
+
|
|
218
|
+
- **Read-only**: Triage does not modify any code, merge PRs, or close issues.
|
|
219
|
+
- **Rate limits**: `gh` API calls are rate-limited. For repos with 50+ open items, consider using `--pr` or `--issue` to reduce scope.
|
|
220
|
+
- **Worktree cleanup**: Worktree agents auto-clean on completion. If a worktree is left behind, use `git worktree prune`.
|
|
221
|
+
- **NEVER use `run_in_background: true` on Phase 1 Task calls**: agents must run in foreground so results are collected before consolidation. Phase 2 worktree agents also run in foreground.
|
|
222
|
+
- **Parallel limits**: Phase 1 — max 5 concurrent agents. Phase 2 — max 3 concurrent worktree agents.
|
|
@@ -34,7 +34,7 @@ Quantitatively inspect changed files within the Phase against `{config.code_styl
|
|
|
34
34
|
After passing the Phase gate, automatically save session state:
|
|
35
35
|
|
|
36
36
|
1. Create `.claude/afc/memory/` directory if it does not exist
|
|
37
|
-
2. Write/update `.claude/afc/memory/checkpoint.md` **and** `~/.claude/projects/{ENCODED_PATH}/
|
|
37
|
+
2. Write/update `.claude/afc/memory/checkpoint.md` **and** `~/.claude/projects/{ENCODED_PATH}/memory/checkpoint.md` (dual-write for compaction resilience — `ENCODED_PATH` = project path with `/` replaced by `-`):
|
|
38
38
|
|
|
39
39
|
```markdown
|
|
40
40
|
# Phase Gate Checkpoint
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "all-for-claudecode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Claude Code plugin that automates the full dev cycle — spec, plan, implement, review, clean.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"all-for-claudecode": "bin/cli.mjs"
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
"url": "https://github.com/jhlee0409/all-for-claudecode/issues"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"lint": "shellcheck -x --source-path=scripts scripts/*.sh && bash scripts/afc-schema-validate.sh --all && bash scripts/afc-consistency-check.sh",
|
|
37
|
+
"lint": "shellcheck -x --source-path=scripts --severity=warning scripts/*.sh && bash scripts/afc-schema-validate.sh --all && bash scripts/afc-consistency-check.sh",
|
|
38
|
+
"qa": "bash scripts/afc-qa-audit.sh",
|
|
38
39
|
"test": "vendor/shellspec/shellspec",
|
|
39
|
-
"test:all": "npm run lint && npm run test",
|
|
40
|
-
"setup:test": "bash scripts/install-shellspec.sh"
|
|
40
|
+
"test:all": "npm run lint && npm run qa && npm run test",
|
|
41
|
+
"setup:test": "bash scripts/install-shellspec.sh",
|
|
42
|
+
"sync:cache": "bash scripts/afc-sync-cache.sh"
|
|
41
43
|
},
|
|
42
44
|
"engines": {
|
|
43
45
|
"node": ">=18"
|
|
@@ -14,15 +14,15 @@ cleanup() {
|
|
|
14
14
|
}
|
|
15
15
|
trap cleanup EXIT
|
|
16
16
|
|
|
17
|
+
# Consume stdin immediately (prevents SIGPIPE if exiting early)
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
|
|
17
20
|
# If pipeline is inactive -> allow
|
|
18
21
|
if ! afc_state_is_active; then
|
|
19
22
|
printf '{"hookSpecificOutput":{"permissionDecision":"allow"}}\n'
|
|
20
23
|
exit 0
|
|
21
24
|
fi
|
|
22
25
|
|
|
23
|
-
# Parse tool input from stdin
|
|
24
|
-
INPUT=$(cat)
|
|
25
|
-
|
|
26
26
|
# If stdin is empty -> allow
|
|
27
27
|
if [ -z "$INPUT" ]; then
|
|
28
28
|
printf '{"hookSpecificOutput":{"permissionDecision":"allow"}}\n'
|