45 lines
3.5 KiB
Markdown
45 lines
3.5 KiB
Markdown
# claude-playground
|
||
|
||
A tiny zero-dependency Node.js todo CLI, used as a sandbox for trying Claude Code features.
|
||
|
||
## Commands
|
||
- `npm test` — run the test suite (built-in `node:test`, no install needed)
|
||
- `npm start -- add "something"` / `npm start -- ls` — run the CLI (data in `todos.json`, override with `TODO_FILE`)
|
||
|
||
## Conventions
|
||
- ES modules, Node >= 20, no third-party dependencies.
|
||
- `src/todo.js` holds pure functions; keep I/O in `load`/`save` and `src/cli.js`.
|
||
- Every behavior change gets a test in `test/`.
|
||
- Commit messages: short imperative subject line.
|
||
|
||
## Workflow (required)
|
||
Never commit, merge, or push to `main`. Only a human (Christian) merges into `main`.
|
||
These rules are instructions, not a lock. Gitea branch protection on `main` is the real guard; the `git push … main` deny rules in `.claude/settings.json` only catch the obvious spellings.
|
||
1. Start every change from a fresh `main`. Run `git fetch origin` as its own command, then `git switch --no-track -c <type>/<short-name> origin/main` (e.g. `fix/duplicate-ids`, `docs/readme`). `--no-track` keeps the branch from tracking `main`.
|
||
2. Commit on that branch; run `npm test` before every push.
|
||
3. Push with `git push -u origin HEAD`, then open a PR against `main` (see "Gitea API" below).
|
||
4. Review it with `/code-review <branch>`. Always name the branch, so the review diffs it against `main` whatever its upstream is.
|
||
5. Post the result as a PR comment. The first line is the verdict: **Needs fixes** if there is any correctness finding, otherwise **Approved** (cleanup-only findings are listed but don't block). The second line is `_Automated self-review by Claude; not an independent review._`, followed by the findings.
|
||
6. If it needs fixes, fix the correctness findings on the same branch and repeat steps 2–5. At most 2 fix rounds: after that, post what's left and hand off to the human.
|
||
7. Stop there. Do not merge the PR, even if approved; tell the human it's ready.
|
||
|
||
### Gitea API
|
||
No `gh`/`tea`: use `curl` with `$GITEA_TOKEN`. One-time human setup in the git-ignored `.claude/settings.local.json`: set `env.GITEA_TOKEN` and add `code.westerkam.org` to `sandbox.network.allowedDomains`. Settings load at session start, so after adding them the session must be restarted (`claude --continue`). If the token is unset, stop and ask the human; don't work around it.
|
||
|
||
Shell state doesn't persist between commands, so set every variable in the same command as the call. Write comment bodies to `$TMPDIR`, never into the repo. `-fsS` makes HTTP errors fail loudly; check that the PR response has a `.number`.
|
||
```sh
|
||
API=https://code.westerkam.org/api/v1/repos/christian/claude-playground
|
||
# Open a PR
|
||
BRANCH=fix/x TITLE="Fix x" BODY="…"
|
||
jq -n --arg head "$BRANCH" --arg title "$TITLE" --arg body "$BODY" '{head:$head, base:"main", title:$title, body:$body}' \
|
||
| curl -fsS -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d @- "$API/pulls" | jq -e .number
|
||
# Comment on PR number $N
|
||
N=1
|
||
jq -n --rawfile body "$TMPDIR/comment.md" '{body:$body}' \
|
||
| curl -fsS -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d @- "$API/issues/$N/comments" | jq -r .html_url
|
||
```
|
||
Run `git fetch`, `git commit` and `git push` as standalone commands (no `cd … &&` prefix, nothing chained after them): only then do they run outside the sandbox, which reaching the remote and commit signing need.
|
||
|
||
## Remote
|
||
Gitea at code.westerkam.org — `origin` = `git@code.westerkam.org:christian/claude-playground.git`.
|