Skip to content

Commit b798419

Browse files
authored
feat: rewrite skills/agent docs (#24584)
Adds core skills for working with docker/docs - catches common issues and improves agent task execution. These tasks were derived from a self-learning harness setup I've used separately; but a separate harness doesn't exactly work well as a collaboration platform. So this PR merges the main features of the harness into the canonical repo. Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2 parents 658a21f + 2c4facb commit b798419

File tree

18 files changed

+1010
-441
lines changed

18 files changed

+1010
-441
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
# PreToolUse hook for the Bash tool.
3+
# Blocks dangerous git patterns that cause CI failures.
4+
set -euo pipefail
5+
6+
input=$(cat)
7+
command=$(echo "$input" | jq -r '.tool_input.command // empty')
8+
9+
if [ -z "$command" ]; then
10+
exit 0
11+
fi
12+
13+
# Block 'git add .' / 'git add -A' / 'git add --all'
14+
# These stage package-lock.json and other generated files.
15+
if echo "$command" | grep -qE 'git\s+add\s+(\.|--all|-A)(\s|$|;)'; then
16+
echo "BLOCKED: do not use 'git add .' / 'git add -A' / 'git add --all'. Stage files explicitly by name." >&2
17+
exit 2
18+
fi
19+
20+
exit 0

.agents/hooks/enforce-vendored.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
# PreToolUse hook for Edit and Write tools.
3+
# Blocks edits to vendored content that must be fixed upstream.
4+
set -euo pipefail
5+
6+
input=$(cat)
7+
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
8+
9+
if [ -z "$file_path" ]; then
10+
exit 0
11+
fi
12+
13+
# Block edits to vendored Hugo modules.
14+
if echo "$file_path" | grep -qE '/_vendor/'; then
15+
echo "BLOCKED: _vendor/ is vendored from upstream Hugo modules. Fix in the source repo instead." >&2
16+
exit 2
17+
fi
18+
19+
# Block edits to vendored CLI reference data.
20+
if echo "$file_path" | grep -qE '/data/cli/'; then
21+
echo "BLOCKED: data/cli/ is generated from upstream repos (docker/cli, docker/buildx, etc.). Fix in the source repo instead." >&2
22+
exit 2
23+
fi
24+
25+
exit 0

.agents/settings.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"hooks": {
3+
"PreToolUse": [
4+
{
5+
"matcher": "Edit|Write",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "bash .agents/hooks/enforce-vendored.sh"
10+
}
11+
],
12+
"description": "Block edits to vendored content (_vendor/, data/cli/)"
13+
},
14+
{
15+
"matcher": "Bash",
16+
"hooks": [
17+
{
18+
"type": "command",
19+
"command": "bash .agents/hooks/enforce-git-hygiene.sh"
20+
}
21+
],
22+
"description": "Block git add . and dangerous patterns"
23+
}
24+
]
25+
}
26+
}

.agents/skills/check-pr/SKILL.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
name: check-pr
3+
description: >
4+
Check a single PR's CI status, review comments, and requested changes.
5+
Fix actionable failures and address feedback. "check PR 1234", "what's
6+
the status of my PR", "address review comments on #500".
7+
argument-hint: "<pr-number>"
8+
context: fork
9+
---
10+
11+
# Check PR
12+
13+
Do one pass over PR **$ARGUMENTS**: check CI, read reviews, fix what's
14+
actionable, report status.
15+
16+
## 1. Gather PR state
17+
18+
```bash
19+
# Overall state
20+
gh pr view $ARGUMENTS --repo docker/docs --json state,title,url,headRefName
21+
22+
# CI checks
23+
gh pr checks $ARGUMENTS --repo docker/docs --json name,state,detailsUrl
24+
25+
# Top-level reviews
26+
gh pr view $ARGUMENTS --repo docker/docs --json reviews,reviewDecision
27+
28+
# Inline (line-level) comments — NOT included in the above
29+
gh api repos/docker/docs/pulls/$ARGUMENTS/comments \
30+
--jq '[.[] | {id: .id, author: .user.login, body: .body, path: .path, line: .line}]'
31+
```
32+
33+
Always check both the reviews endpoint and the inline comments endpoint.
34+
A review with an empty body may still have line-level comments requiring
35+
action.
36+
37+
## 2. If merged
38+
39+
Report the final state. No further action needed.
40+
41+
## 3. If closed without merge
42+
43+
Read the closing context to understand why:
44+
45+
```bash
46+
gh pr view $ARGUMENTS --repo docker/docs --json closedAt,comments \
47+
--jq '{closedAt, lastComment: .comments[-1].body}'
48+
```
49+
50+
Report the reason. Common causes: rejected by maintainers, superseded by
51+
another PR, closed by automation.
52+
53+
## 4. If CI is failing
54+
55+
- Read the failure details (follow `detailsUrl` if needed)
56+
- Determine if the failure is in the PR's changed files or pre-existing
57+
- **Actionable:** check out the branch, fix, commit, push
58+
```bash
59+
git checkout <branch>
60+
# fix the issue
61+
git add <files>
62+
git commit -m "fix: <description>"
63+
git push
64+
```
65+
- **Pre-existing / upstream:** note it, do not block
66+
67+
## 5. If review comments or changes requested
68+
69+
- Read each unresolved comment
70+
- Address feedback in a follow-up commit
71+
- Push, then reply to each comment explaining what was done:
72+
```bash
73+
gh api repos/docker/docs/pulls/$ARGUMENTS/comments \
74+
--method POST \
75+
--field in_reply_to=<comment-id> \
76+
--field body="<response>"
77+
```
78+
- End every comment with a `Generated by [Claude Code](https://claude.com/claude-code)` footer
79+
- Re-request review if changes were requested
80+
81+
## 6. Report
82+
83+
```
84+
## PR #$ARGUMENTS: <title>
85+
86+
**State:** <open|merged|closed>
87+
**CI:** <passing|failing|pending>
88+
**Review:** <approved|changes requested|pending>
89+
**Action taken:** <what was done, or "none needed">
90+
```

.agents/skills/create-pr/SKILL.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
name: create-pr
3+
description: >
4+
Push the current branch and create a pull request against docker/docs.
5+
Use after changes are committed and reviewed. "create a PR", "submit the
6+
fix", "open a pull request for this".
7+
---
8+
9+
# Create PR
10+
11+
Push the branch and create a properly structured pull request.
12+
13+
## 1. Verify the branch
14+
15+
```bash
16+
git log --oneline main..HEAD # confirm commits exist
17+
git diff --quiet # confirm no unstaged changes
18+
```
19+
20+
## 2. Push the branch
21+
22+
Confirm origin points to your fork, not upstream:
23+
24+
```bash
25+
git remote get-url origin
26+
```
27+
28+
Then push:
29+
30+
```bash
31+
git push -u origin <branch-name>
32+
```
33+
34+
## 3. Create the PR
35+
36+
Derive the fork owner dynamically:
37+
38+
```bash
39+
FORK_OWNER=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+)/[^/]+(\.git)?$|\1|')
40+
```
41+
42+
```bash
43+
gh pr create --repo docker/docs \
44+
--head "${FORK_OWNER}:<branch-name>" \
45+
--title "<concise summary under 70 chars>" \
46+
--body "$(cat <<'EOF'
47+
## Summary
48+
49+
<1-2 sentences: what was wrong and what was changed>
50+
51+
Closes #NNNN
52+
53+
Generated by [Claude Code](https://claude.com/claude-code)
54+
EOF
55+
)"
56+
```
57+
58+
Keep the body short. Reviewers need to know what changed and why — nothing
59+
else.
60+
61+
### Optional: Learnings section
62+
63+
If while working on this PR you discovered something non-obvious about the
64+
repo — a convention not documented in AGENTS.md, a gotcha that tripped you
65+
up, a pattern that should be codified — add a Learnings section to the PR
66+
body:
67+
68+
```markdown
69+
## Learnings
70+
71+
- <what you learned and why it matters>
72+
```
73+
74+
Add this section between the Summary and the `Closes` line. Only include
75+
learnings that would help future contributors avoid the same issue. Do not
76+
include things already documented in AGENTS.md or STYLE.md.
77+
78+
The weekly PR learnings scanner reads these sections to surface recurring
79+
patterns for the team to codify.
80+
81+
## 4. Apply labels and request review
82+
83+
Use the Issues API for labels — `gh pr edit --add-label` silently fails:
84+
85+
```bash
86+
gh api repos/docker/docs/issues/<pr-number>/labels \
87+
--method POST \
88+
--field 'labels[]=status/review'
89+
```
90+
91+
Request review:
92+
93+
```bash
94+
gh pr edit <pr-number> --repo docker/docs --add-reviewer docker/docs-team
95+
```
96+
97+
Verify the reviewer was assigned:
98+
99+
```bash
100+
gh pr view <pr-number> --repo docker/docs --json reviewRequests \
101+
--jq '.reviewRequests[].slug'
102+
```
103+
104+
If the team doesn't appear, use the API directly:
105+
106+
```bash
107+
gh api repos/docker/docs/pulls/<pr-number>/requested_reviewers \
108+
--method POST --field 'team_reviewers[]=docs-team'
109+
```
110+
111+
## 5. Report
112+
113+
Print the PR URL and current CI state:
114+
115+
```bash
116+
gh pr view <pr-number> --repo docker/docs --json url,state
117+
gh pr checks <pr-number> --repo docker/docs --json name,state
118+
```
119+
120+
## Notes
121+
122+
- Always use `Closes #NNNN` (not "Fixes") for GitHub auto-close linkage
123+
- One issue, one branch, one PR — never combine

.agents/skills/fix-issue/SKILL.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
name: fix-issue
3+
description: >
4+
Fix a single GitHub issue end-to-end: triage, research, write the fix,
5+
review, and create a PR. Use when asked to fix an issue: "fix issue 1234",
6+
"resolve #500", "create a PR for issue 200".
7+
argument-hint: "<issue-number>"
8+
---
9+
10+
# Fix Issue
11+
12+
Given GitHub issue **$ARGUMENTS**, decide what to do with it and either
13+
close it or fix it. This skill orchestrates the composable skills — it owns
14+
the decision tree, not the individual steps.
15+
16+
## 1. Triage
17+
18+
Invoke `/triage-issue $ARGUMENTS` to understand the issue and decide what
19+
to do. This runs in a forked subagent and returns a verdict.
20+
21+
## 2. Act on the triage result
22+
23+
If triage says **close it** — comment with the reason and close:
24+
```bash
25+
gh issue close $ARGUMENTS --repo docker/docs \
26+
--comment "<one sentence explaining why>
27+
28+
Generated by [Claude Code](https://claude.com/claude-code)"
29+
```
30+
Done.
31+
32+
If triage says **escalate upstream** — comment noting the repo and stop:
33+
```bash
34+
gh issue comment $ARGUMENTS --repo docker/docs \
35+
--body "This needs to be fixed in <upstream-repo>.
36+
37+
Generated by [Claude Code](https://claude.com/claude-code)"
38+
```
39+
Done.
40+
41+
If triage says **leave it open** — comment explaining what was checked and
42+
what's unclear. Do not close.
43+
Done.
44+
45+
End every issue comment with a `Generated by [Claude Code](https://claude.com/claude-code)` footer.
46+
47+
If triage says **fix it** — proceed to step 3.
48+
49+
## 3. Research
50+
51+
Invoke `/research` to locate affected files, verify facts, and identify
52+
the fix. The issue context carries over from triage. This runs inline —
53+
findings stay in conversation context for the write step.
54+
55+
If research reveals the issue is upstream or cannot be fixed (e.g.
56+
unverifiable URLs), comment on the issue and stop.
57+
58+
## 4. Write
59+
60+
Invoke `/write` to create a branch, make the change, format, self-review,
61+
and commit.
62+
63+
## 5. Review
64+
65+
Invoke `/review-changes` to check the diff for correctness, coherence, and
66+
mechanical compliance. This runs in a forked subagent with fresh context.
67+
68+
If issues are found, fix them and re-review until clean.
69+
70+
## 6. Create PR
71+
72+
Invoke `/create-pr` to push the branch and open a pull request.
73+
74+
## 7. Return to main
75+
76+
```bash
77+
git checkout main
78+
```
79+
80+
## 8. Report
81+
82+
Summarize what happened: the issue number, what was done (closed, escalated,
83+
fixed with a PR link), and why — in a sentence or two.

0 commit comments

Comments
 (0)