chore: bump version to 0.4.0
CHANGELOG.md updated with the audit-driven hardening pass spanning 13 findings across cmd/ and internal/. Adds CLAUDE.md documenting dev workflow, codex review pattern, release process, and homebrew tap update steps.
This commit is contained in:
parent
373c769d2c
commit
0069198ca6
3 changed files with 268 additions and 1 deletions
166
CLAUDE.md
Normal file
166
CLAUDE.md
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
# fj — guide for Claude Code sessions
|
||||
|
||||
`fj` is a personal Forgejo/Gitea CLI tool, modeled on GitHub's `gh`. It targets `forgejo.zerova.net` (and Codeberg). The user (sid) owns it; the canonical repo is `public/fj` on forgejo.zerova.net (mirrored from there to nowhere else).
|
||||
|
||||
This file is read first by Claude Code when working in `~/repos/fj`. Goal: get a session productive quickly without re-deriving the dev workflow each time.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
~/repos/fj/
|
||||
├── cmd/ cobra command definitions, one file per subject area
|
||||
│ ├── root.go rootCmd, --config plumbing, OnInitialize
|
||||
│ ├── auth.go login/status/logout/token (uses persistent --hostname)
|
||||
│ ├── api.go raw API access; --json/--json-fields/--jq/--paginate
|
||||
│ ├── json.go shared JSON output helpers (addJSONFlags/wantJSON/outputJSON)
|
||||
│ ├── paginate.go generic paginateGitea[T] helper for list commands
|
||||
│ ├── errors.go CLIError with structured Hint field
|
||||
│ ├── actions.go Forgejo Actions; runs/workflows via factory functions
|
||||
│ ├── aliases.go top-level `fj run` / `fj workflow` aliases — calls actions.go factories
|
||||
│ ├── repo.go pr.go issue.go release.go wiki.go label.go milestone.go
|
||||
│ └── ...
|
||||
├── internal/
|
||||
│ ├── api/client.go SharedHTTPClient (30s timeout); GetJSON/DoJSON/DownloadFile
|
||||
│ ├── config/config.go YAML config; honors --config via SetExplicitConfigPath
|
||||
│ ├── git/ repo + host detection from `git remote`
|
||||
│ ├── iostreams/ wrapped stdin/stdout/stderr + spinner + pager + colors
|
||||
│ └── text/ formatting helpers
|
||||
├── main.go thin entrypoint; ContextualError + JSON-error rendering
|
||||
├── Makefile build / lint / test (no release automation)
|
||||
├── CHANGELOG.md Keep-a-Changelog format
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Build, install, test
|
||||
|
||||
```bash
|
||||
go build ./... # quick build check
|
||||
go test ./... # unit tests
|
||||
go install . # build + install to ~/go/bin/fj (the binary that's on PATH)
|
||||
make lint # golangci-lint, if you have it
|
||||
```
|
||||
|
||||
After any change in cmd/ or internal/, run `go install .` and the global `fj` reflects it immediately. There's no daemon/restart.
|
||||
|
||||
## Auth
|
||||
|
||||
The user is authenticated as `sid` on `forgejo.zerova.net`. Token lives in `~/.config/fj/config.yaml` (mode 0600). For HTTPS git pushes from this host, the token can be injected via `git -c "http.extraHeader=Authorization: token <T>" push` — the local SSH key (`sid@debian` on forgejo) is also registered, so `git@forgejo.zerova.net:public/fj.git` works directly.
|
||||
|
||||
## Code review pattern (use this for non-trivial changes)
|
||||
|
||||
For audits or significant refactors, run **three reviewers in parallel** with non-overlapping focuses (we did this in the v0.4.0 cycle and it found bugs none would have caught alone):
|
||||
|
||||
- **Codex** — read-only sandbox, peer-AI cross-check
|
||||
```bash
|
||||
codex exec --skip-git-repo-check --sandbox read-only \
|
||||
-m gpt-5.4-mini --config model_reasoning_effort="medium" "<prompt>" 2>/dev/null
|
||||
```
|
||||
For follow-up rounds resume the same session: `echo "<prompt>" | codex exec --skip-git-repo-check resume --last 2>/dev/null`. Codex remembers prior critique.
|
||||
|
||||
- **Claude general-purpose agent A** — architecture / UX / code-quality
|
||||
- **Claude general-purpose agent B** — security / correctness / error handling
|
||||
|
||||
Tell each reviewer what the **siblings** are covering so they don't duplicate. Cap reports at ~600 words. Consolidate findings by severity (HIGH / MEDIUM / LOW) before presenting to the user.
|
||||
|
||||
## Release process
|
||||
|
||||
We use semver. **Pre-1.0**: breaking change → minor bump (e.g. v0.3.x → v0.4.0).
|
||||
|
||||
1. **Bump version**
|
||||
```go
|
||||
// cmd/root.go
|
||||
Version: "0.4.0",
|
||||
```
|
||||
|
||||
2. **Update CHANGELOG.md** — prepend a new section. Format:
|
||||
```markdown
|
||||
## [0.4.0] - YYYY-MM-DD
|
||||
|
||||
### BREAKING
|
||||
- <thing that broke>
|
||||
|
||||
### Added
|
||||
- ...
|
||||
### Changed
|
||||
- ...
|
||||
### Fixed
|
||||
- ...
|
||||
### Security
|
||||
- ...
|
||||
```
|
||||
|
||||
3. **Commit** the version+changelog bump as a single commit:
|
||||
```bash
|
||||
git commit -m "chore: bump version to 0.4.0"
|
||||
```
|
||||
|
||||
4. **Tag** the commit:
|
||||
```bash
|
||||
git tag -a v0.4.0 -m "Release v0.4.0: <one-line summary>"
|
||||
```
|
||||
|
||||
5. **Push** commits and tag:
|
||||
```bash
|
||||
git push origin main
|
||||
git push origin v0.4.0
|
||||
```
|
||||
|
||||
6. **Create the Forgejo release page** via fj itself:
|
||||
```bash
|
||||
fj release create v0.4.0 \
|
||||
--title "v0.4.0: <summary>" \
|
||||
--notes "$(awk '/^## \[0.4.0\]/{flag=1;next} /^## /{flag=0} flag' CHANGELOG.md)"
|
||||
```
|
||||
(The awk one-liner extracts the just-added CHANGELOG section as release notes.)
|
||||
|
||||
7. **Update the homebrew tap** — see the next section.
|
||||
|
||||
## Updating the homebrew tap (`public/homebrew-sid`)
|
||||
|
||||
The tap lives at `~/repos/homebrew-sid` (or `git@forgejo.zerova.net:public/homebrew-sid.git`). The `Formula/fj.rb` formula references the source by `tag:` + `revision:` (SHA), so a release bump touches three lines:
|
||||
|
||||
```ruby
|
||||
url "ssh://git@forgejo.zerova.net/public/fj.git",
|
||||
tag: "v0.4.0", # was v0.3.2
|
||||
revision: "<SHA of v0.4.0 tag>" # update
|
||||
|
||||
test do
|
||||
assert_match "0.4.0", shell_output("#{bin}/fj --version") # update
|
||||
end
|
||||
```
|
||||
|
||||
To get the SHA:
|
||||
```bash
|
||||
git -C ~/repos/fj rev-parse v0.4.0
|
||||
```
|
||||
|
||||
Then in `~/repos/homebrew-sid`:
|
||||
```bash
|
||||
# edit Formula/fj.rb (the three lines above)
|
||||
git commit -am "fj: bump to v0.4.0"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
After push, users can `brew update && brew upgrade fj` to pick up the new version.
|
||||
|
||||
## Common footguns
|
||||
|
||||
- **`fj` reads the current dir's `git origin`** to detect the host. In a directory whose origin points at github.com (e.g. /opt/stacks/claude-code-proxy/build), bare `fj api ...` errors with "no configuration found for host github.com". Pass `--hostname forgejo.zerova.net` explicitly, or `cd` somewhere else.
|
||||
- **`--json=fields` was removed in v0.4.0** in favor of `--json-fields fields` (or `--json-fields=fields`). The old `=fields` form was a `NoOptDefVal=" "` sentinel hack. `--json` is now a plain Bool meaning "as JSON".
|
||||
- **`--config` was silently ignored before v0.4.0.** Old fj versions read --config into Viper but `internal/config.Load()` always read the default path. Fixed; `fj --config other.yaml auth login` now writes to other.yaml.
|
||||
- **The `actions` and `run`/`workflow` command trees share factory functions** in `cmd/actions.go` (`newRunCmd`, `newWorkflowCmd`). Don't add flags directly to `runListCmd` style globals — they don't exist anymore. Edit the factory and both `fj actions run list` and `fj run list` get the change.
|
||||
|
||||
## Useful commands
|
||||
|
||||
```bash
|
||||
# Live test against forgejo (using the new flags)
|
||||
fj --hostname forgejo.zerova.net api repos/public/fj --json-fields full_name,description
|
||||
|
||||
# Walk paginated endpoints
|
||||
fj --hostname forgejo.zerova.net api 'repos/public/fj/commits?limit=10' --paginate --jq '.[].sha[0:8]'
|
||||
|
||||
# Confirm both command trees stay in sync after edits
|
||||
diff <(fj run list --help | grep -E "^ -|^ --" | sort) \
|
||||
<(fj actions run list --help | grep -E "^ -|^ --" | sort)
|
||||
# Empty diff = trees agree. Any output = factory drift.
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue