Skip to content

Commit f2880d0

Browse files
OriNachumclaude
andauthored
docs: refresh architecture, event system docs, Jekyll cream theme, and skills (#46)
* docs: refresh architecture, add event system docs, Jekyll cream theme, and skills - Create docs/events-and-tool-handling.md with comprehensive SSE event types, emission sequences, MCP vs non-MCP tool flows, tool injection, and conversation history documentation - Rewrite docs/open-responses-server.md with current modular architecture, module map, config table, and startup lifecycle - Enrich docs/responses_flow.md with 4 mermaid sequence diagrams covering plain text, MCP tool, non-MCP tool, and chat completions tool loop flows - Set up Jekyll GitHub Pages with just-the-docs theme and anthropic cream color scheme (Gemfile, _config.yml, SCSS, index.md, pages.yml workflow) - Add Jekyll front matter to all doc files for navigation - Create CLAUDE.md with build/test/lint commands and architecture overview - Add .claude/skills/pr-review for automated PR review workflow - Add .claude/skills/markdownlint with lint-docs.sh script Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review comments and fix failing CI pipelines Review fixes: - Fix docs to correctly note that response.tool_calls.created is only emitted in the legacy delta.function_call path, not the modern delta.tool_calls path (which emits response.in_progress instead) - Fix lint-docs.sh set -e bug that prevented exit code capture Pipeline fixes: - Dockerfile: add gcc/build-essential/libffi-dev to builder stage for cffi compilation on arm architectures - security-checks.yml: upgrade CodeQL init from v2 to v3 to match analyze@v3 - test_server.py: fix test_proxy_endpoint to mock LLMClient.get_client instead of non-existent api_controller.httpx - test_e2e.py: fix async fixture usage (remove __anext__ calls) - conftest.py: add base_url to MockAsyncClient - pyproject.toml: add asyncio_mode = "auto" for pytest-asyncio All 20 tests now pass (was 15 passed / 6 failed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ff84197 commit f2880d0

File tree

23 files changed

+1313
-159
lines changed

23 files changed

+1313
-159
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
name: markdownlint
3+
description: >
4+
Lint and auto-fix markdown files in the open-responses-server repo using
5+
markdownlint-cli2. Use when: editing markdown docs, before committing doc
6+
changes, or when the user says "lint docs", "check markdown", or "fix
7+
markdown".
8+
---
9+
10+
# Markdownlint Skill
11+
12+
Lint all documentation markdown files and optionally auto-fix issues.
13+
14+
## Quick Usage
15+
16+
### Check all docs
17+
18+
```bash
19+
bash .claude/skills/markdownlint/scripts/lint-docs.sh
20+
```
21+
22+
### Auto-fix fixable issues
23+
24+
```bash
25+
bash .claude/skills/markdownlint/scripts/lint-docs.sh --fix
26+
```
27+
28+
### Check specific files
29+
30+
```bash
31+
bash .claude/skills/markdownlint/scripts/lint-docs.sh docs/events-and-tool-handling.md
32+
```
33+
34+
## What Gets Linted
35+
36+
By default the script lints:
37+
38+
- `docs/*.md` — top-level documentation
39+
- `index.md` — Jekyll home page
40+
- `CLAUDE.md` — repo guidance
41+
- `.claude/skills/**/*.md` — skill definitions
42+
43+
Excluded by default:
44+
45+
- `docs/plan/` — historical planning archives
46+
- `docs/prompts/` — prompt templates
47+
- `docs/pip-publish-instructions.md` — legacy doc
48+
- `docs/using-uv.md` — legacy doc
49+
50+
## Configuration
51+
52+
The script uses whichever config is found first:
53+
54+
1. Project-level `.markdownlint-cli2.yaml` (in repo root)
55+
2. Global `~/.markdownlint-cli2.yaml`
56+
3. markdownlint built-in defaults
57+
58+
The global config disables:
59+
60+
- **MD013** (line length) — too noisy for content-heavy docs and tables
61+
- **MD060** (table pipe spacing) — stylistic preference
62+
63+
## Workflow
64+
65+
After editing any `.md` file:
66+
67+
1. Run `bash .claude/skills/markdownlint/scripts/lint-docs.sh`
68+
2. If issues found, run with `--fix` to auto-fix what can be fixed
69+
3. Manually fix remaining issues
70+
4. Re-run to verify clean
71+
72+
## Common Rules
73+
74+
| Rule | What It Checks |
75+
| --- | --- |
76+
| MD001 | Heading levels increment by one |
77+
| MD004 | Consistent unordered list style (dashes) |
78+
| MD009 | No trailing spaces |
79+
| MD022 | Blank lines around headings |
80+
| MD025 | Single H1 per document (use front matter title) |
81+
| MD031 | Blank lines around fenced code blocks |
82+
| MD032 | Blank lines around lists |
83+
| MD040 | Fenced code blocks should have a language |
84+
| MD047 | Files end with a single newline |
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
# Lint all documentation markdown files in the open-responses-server repo.
3+
# Uses the global markdownlint config at ~/.markdownlint-cli2.yaml unless
4+
# a project-level .markdownlint-cli2.yaml exists.
5+
#
6+
# Usage:
7+
# bash lint-docs.sh # check all docs
8+
# bash lint-docs.sh --fix # auto-fix fixable issues
9+
# bash lint-docs.sh FILE... # check specific files
10+
11+
set -euo pipefail
12+
13+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
14+
15+
# Determine config: project-level takes precedence over global
16+
if [ -f "$REPO_ROOT/.markdownlint-cli2.yaml" ]; then
17+
CONFIG_FLAG=""
18+
elif [ -f "$HOME/.markdownlint-cli2.yaml" ]; then
19+
CONFIG_FLAG="--config $HOME/.markdownlint-cli2.yaml"
20+
else
21+
CONFIG_FLAG=""
22+
fi
23+
24+
# Check for --fix flag
25+
FIX_FLAG=""
26+
FILES=()
27+
for arg in "$@"; do
28+
if [ "$arg" = "--fix" ]; then
29+
FIX_FLAG="--fix"
30+
else
31+
FILES+=("$arg")
32+
fi
33+
done
34+
35+
# Default file set: docs/ (excluding plan/ and prompts/), index.md, CLAUDE.md, skills
36+
if [ ${#FILES[@]} -eq 0 ]; then
37+
FILES=(
38+
"$REPO_ROOT/docs/*.md"
39+
"$REPO_ROOT/index.md"
40+
"$REPO_ROOT/CLAUDE.md"
41+
"$REPO_ROOT/.claude/skills/**/*.md"
42+
)
43+
fi
44+
45+
# Ignore patterns for historical/archive docs
46+
IGNORE_FLAGS=(
47+
"!$REPO_ROOT/docs/plan/**"
48+
"!$REPO_ROOT/docs/prompts/**"
49+
"!$REPO_ROOT/docs/pip-publish-instructions.md"
50+
"!$REPO_ROOT/docs/using-uv.md"
51+
)
52+
53+
echo "Running markdownlint-cli2 on ${#FILES[@]} pattern(s)..."
54+
# shellcheck disable=SC2086
55+
set +e
56+
markdownlint-cli2 $FIX_FLAG $CONFIG_FLAG "${FILES[@]}" "${IGNORE_FLAGS[@]}"
57+
EXIT_CODE=$?
58+
set -e
59+
60+
if [ $EXIT_CODE -eq 0 ]; then
61+
echo "All files pass."
62+
else
63+
echo "Found lint issues (exit code $EXIT_CODE)."
64+
fi
65+
66+
exit $EXIT_CODE

.claude/skills/pr-review/SKILL.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
---
2+
name: pr-review
3+
description: >
4+
Full PR workflow for open-responses-server: branch, commit, push, create PR,
5+
wait for automated reviewers, fetch comments, fix or pushback, reply, resolve
6+
threads. Use when: creating PRs, handling review feedback, or the user says
7+
"create PR", "review comments", "address feedback", or "resolve threads".
8+
---
9+
10+
# PR Review Workflow
11+
12+
Complete pull request lifecycle for the open-responses-server project. Follow
13+
every step in order.
14+
15+
## Step 1 — Branch
16+
17+
If you are on `main`, create a feature branch first:
18+
19+
```bash
20+
git checkout -b <branch-name>
21+
```
22+
23+
Branch naming conventions:
24+
25+
| Type | Pattern | Example |
26+
| --- | --- | --- |
27+
| Bug fix | `fix/<short-desc>` | `fix/streaming-error-handling` |
28+
| Feature | `feat/<short-desc>` | `feat/persistent-history` |
29+
| Docs | `docs/<short-desc>` | `docs/event-system-refresh` |
30+
31+
## Step 1b — Check for existing PRs on the branch
32+
33+
Before adding new work to an existing branch, check if there's already an
34+
open PR:
35+
36+
```bash
37+
gh pr view --json number,title,state --jq '{number,title,state}'
38+
```
39+
40+
If the command fails with "no pull requests found", there is no open PR —
41+
proceed normally. Only act on the result if it returns valid JSON with
42+
`state: "OPEN"`.
43+
44+
If an open PR exists and your new changes are **unrelated** to that PR's
45+
scope, **stop and ask the user**:
46+
47+
> "There's an open PR (#N: 'title') on this branch. The new changes
48+
> are unrelated to that PR. Would you like to merge the existing PR
49+
> first before starting the new work?"
50+
51+
Wait for the user's answer before proceeding.
52+
53+
## Step 2 — Make changes, commit, push
54+
55+
1. Edit code
56+
2. Run tests: `python -m pytest tests/ -v`
57+
3. Run lint: `flake8 src/`
58+
4. Stage and commit:
59+
60+
```bash
61+
git add <files>
62+
git commit -m "$(cat <<'EOF'
63+
Commit message here.
64+
65+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
66+
EOF
67+
)"
68+
```
69+
70+
5. Push:
71+
72+
```bash
73+
git push -u origin <branch-name>
74+
```
75+
76+
## Step 3 — Create PR
77+
78+
```bash
79+
gh pr create --title "Short title" --body "$(cat <<'EOF'
80+
## Summary
81+
- Bullet points describing changes
82+
83+
## Test plan
84+
- [ ] Test items
85+
86+
- Claude
87+
EOF
88+
)"
89+
```
90+
91+
## Step 4 — Wait for reviewers
92+
93+
Automated reviewers (Qodo, Copilot) need time to post comments.
94+
95+
**Wait 5 minutes** after creating the PR before checking for comments:
96+
97+
```bash
98+
sleep 300
99+
```
100+
101+
## Step 5 — Poll for comments
102+
103+
After the initial wait, poll every 2 minutes until comments appear:
104+
105+
```bash
106+
bash ~/.claude/skills/pr-review/scripts/pr-comments.sh <PR_NUMBER>
107+
```
108+
109+
If no comments yet, wait and retry:
110+
111+
```bash
112+
sleep 120
113+
bash ~/.claude/skills/pr-review/scripts/pr-comments.sh <PR_NUMBER>
114+
```
115+
116+
Continue until at least one unresolved comment exists, or 3 consecutive polls
117+
return zero comments (reviewers are done / not configured).
118+
119+
## Step 6 — Triage each comment
120+
121+
**Enter plan mode** to present a triage table to the user before making changes.
122+
123+
For every review comment, decide:
124+
125+
- **FIX** — valid concern, make the code change
126+
- **PUSHBACK** — disagree, explain why in the reply
127+
128+
Present as a table:
129+
130+
| # | File | Issue | Decision | Reason |
131+
| --- | --- | --- | --- | --- |
132+
| 1 | `file.py` | Missing null check | FIX | Valid edge case |
133+
| 2 | `other.py` | Rename variable | PUSHBACK | Matches project convention |
134+
135+
Guidelines:
136+
137+
- Exception type mismatches are always valid
138+
- Test requests are always valid — add them
139+
- Style nits are usually valid — fix them
140+
- Architecture opinions may warrant pushback if they conflict with project
141+
conventions (check `CLAUDE.md` and `docs/`)
142+
143+
**Wait for user approval** before proceeding to fixes.
144+
145+
## Step 7 — Fix code and push
146+
147+
1. Make all code fixes
148+
2. Run tests: `python -m pytest tests/ -v`
149+
3. Run lint: `flake8 src/`
150+
4. Commit with a descriptive message
151+
5. Push: `git push`
152+
153+
## Step 8 — Reply and resolve threads
154+
155+
Use batch mode to reply to all comments at once:
156+
157+
```bash
158+
bash ~/.claude/skills/pr-review/scripts/pr-batch.sh --resolve <PR_NUMBER> <<'EOF'
159+
{"comment_id": 123, "body": "Fixed -- changed X to Y.\n\n- Claude"}
160+
{"comment_id": 456, "body": "Intentional -- this follows the pattern in Z because...\n\n- Claude"}
161+
EOF
162+
```
163+
164+
Or reply to a single comment:
165+
166+
```bash
167+
bash ~/.claude/skills/pr-review/scripts/pr-reply.sh --resolve <PR_NUMBER> <COMMENT_ID> "Fixed -- updated.\n\n- Claude"
168+
```
169+
170+
**Important:**
171+
172+
- Always sign replies with `\n\n- Claude`
173+
- Always use `--resolve` to resolve the thread after replying
174+
- Every comment must get a reply — no silent fixes
175+
176+
## Step 9 — Wait for merge
177+
178+
**Never merge the PR yourself.** The PR is merged manually on the GitHub site.
179+
180+
Report to the user that all review threads are addressed and the PR is ready
181+
for merge.
182+
183+
## Script reference
184+
185+
| Script | Purpose |
186+
| --- | --- |
187+
| `pr-comments.sh <PR>` | Fetch all review comments |
188+
| `pr-reply.sh [--resolve] <PR> <ID> "body"` | Reply to one comment |
189+
| `pr-batch.sh [--resolve] <PR> < jsonl` | Batch reply from JSONL stdin |
190+
191+
All scripts auto-detect `owner/repo` from the current git remote.
192+
193+
## Quick reference — full flow
194+
195+
```text
196+
git checkout -b docs/my-change
197+
# ... make changes ...
198+
python -m pytest tests/ -v
199+
flake8 src/
200+
git add <files> && git commit -m "message"
201+
git push -u origin docs/my-change
202+
gh pr create --title "..." --body "..."
203+
sleep 300
204+
bash ~/.claude/skills/pr-review/scripts/pr-comments.sh <PR>
205+
# ... enter plan mode, triage, get approval ...
206+
# ... fix issues, commit, push ...
207+
bash ~/.claude/skills/pr-review/scripts/pr-batch.sh --resolve <PR> <<< '{"comment_id":N,"body":"Fixed\n\n- Claude"}'
208+
# Wait for manual merge — never merge yourself
209+
```

0 commit comments

Comments
 (0)