Skip to content

Commit a50f551

Browse files
committed
Add agent instructions file
1 parent a4397f4 commit a50f551

3 files changed

Lines changed: 137 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
!README.md
1717
!docker-bake.hcl
1818
!Dockerfile
19+
!AGENTS.md
20+
!CLAUDE.md
1921
!.oxfmtrc.json
2022
!.git-blame-ignore-revs
2123

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

CLAUDE.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# wpm
2+
3+
Go package manager for WordPress plugins and themes. Cobra-based CLI, binary
4+
name `wpm`. See `@README.md` for the user-facing overview.
5+
6+
**This is a Go project.** `package.json`, `bun.lock`, and `node_modules/` exist
7+
only to vendor `oxfmt` for Markdown/JSON/YAML formatting. Never propose
8+
JavaScript for runtime code, and never add a Node dep for anything but
9+
formatting.
10+
11+
## Commands
12+
13+
- Build: `go build -o build/wpm ./cmd/wpm` (or `./scripts/build/binary`)
14+
- Run without building: `go run ./cmd/wpm <command>`
15+
- Format Go: `golangci-lint fmt`**never** call `go fmt`, `gofmt`, or
16+
`gofumpt` directly. Project `gci` order, `gofumpt` rules, and
17+
`interface{} → any` rewrite all flow through this command.
18+
- Lint Go: `golangci-lint run`
19+
- Format non-Go: `bunx format`
20+
- Test single package: `go test ./pkg/pm/installer/...`
21+
- Test with race detector (required for `pkg/pm/installer` or
22+
`pkg/pm/resolution` work): `go test -race ./...`
23+
- Regenerate CLI reference docs: `./scripts/docs/generate-md`
24+
25+
## Layout
26+
27+
Three-layer separation — do not collapse layers for convenience:
28+
29+
- `cmd/wpm/` — entrypoint and signal handling
30+
- `cmd/docgen/` — regenerates marker regions in `docs/cli/*.md`
31+
- `cli/` — arg parsing, output, error→exit-code mapping. Commands registered in
32+
`cli/command/commands/commands.go`. **The `cli/` layer must not contain
33+
package-manager logic** — it builds an options struct and delegates to `pkg/`.
34+
- `pkg/pm/{wpmjson,wpmlock,wpmignore,registry,resolution,installer,workspace,signatures}`
35+
— the package-manager engine
36+
- `pkg/api/` — registry HTTP client and cache
37+
- `pkg/archive/` — tar/zip extraction (handles untrusted content)
38+
- `pkg/output/`, `pkg/progress/`, `pkg/streams/` — CLI UI primitives
39+
- `pkg/{config,version,wp,jsonpretty,asciisanitizer,unsafeconv}` — utilities
40+
41+
## Project conventions
42+
43+
- **No `fmt.Printf`/`Println` in `pkg/`.** Return values or use `pkg/output` /
44+
`pkg/progress` so the CLI can honor `--verbose` and future JSON output.
45+
`forbidigo` enforces.
46+
- **Errors:** never `panic()` outside `main`. Wrap with `%w`. Inspect with
47+
`errors.Is` / `errors.As` — never string-match error messages.
48+
- **Concurrency:** use `golang.org/x/sync/errgroup`. Always honor
49+
`context.Context` cancellation.
50+
- **Logging:** use `logrus`, not stdlib `log` (depguard enforces). Stdlib
51+
`io/ioutil` is denied — use `os` / `io`.
52+
- **CLI reference docs** (`docs/cli/*.md`) have an auto-generated marker block
53+
(`<!---MARKER_GEN_START-->` / `<!---MARKER_GEN_END-->`). **Never edit inside
54+
the markers.** Only `## Description` and `## Examples` are read by the
55+
generator — don't add other top-level `##` headings. Full conventions and
56+
workflow: `@docs/README.md`.
57+
58+
## Testing
59+
60+
- **Append tests to the existing `_test.go`** for the code you're changing.
61+
Create a new test file only when adding a new source file with no natural test
62+
home.
63+
- **Verify the test actually tests your change.** A passing test that would also
64+
pass on `origin/main` isn't testing your fix:
65+
66+
```sh
67+
git stash
68+
go test -run TestName ./path/to/pkg # should FAIL
69+
git stash pop
70+
go test -run TestName ./path/to/pkg # should PASS
71+
```
72+
73+
If it passes in both states, rewrite the test.
74+
75+
- **Never use `time.Sleep` to wait for a condition.** Use channels,
76+
`sync.WaitGroup`, `context` deadlines, or bounded polling against the actual
77+
condition.
78+
- Mock the registry with `net/http/httptest`. Existing patterns: `pkg/api/`,
79+
`pkg/pm/registry/`.
80+
- Use `t.TempDir()`, `t.Setenv()`, `t.Helper()` (lint-enforced).
81+
- For CLI output assertions, drive through `cli/command.Cli` and capture `Out()`
82+
/ `Err()`. Don't touch global state.
83+
84+
## Git & remote operations
85+
86+
- **Explicit ask → do it.** "Commit", "push", "open a PR" — perform the
87+
operation and report what was done. Don't re-ask.
88+
- **Ambiguous ask → confirm first.** If changes were described but no
89+
push/PR/tag word appeared, confirm before any remote-write operation. Local
90+
commits on a working branch don't need confirmation.
91+
- **Never push directly to `main`.** Always open a PR.
92+
- **Never bypass safety controls**: no `--no-verify`, no force-push to shared
93+
branches, no skipping signature verification.
94+
- Branch names: any reasonable name. Attribution belongs in the PR body.
95+
96+
## Before referencing a symbol
97+
98+
Don't assume functions, interfaces, fields, methods, flags, or config keys
99+
exist. Search the repo or read the file first. Common traps:
100+
101+
- CLI flags → `cli/flags/` and `cli/command/<name>/`
102+
- `wpm.json` fields → `pkg/pm/wpmjson/types/types.go`
103+
- Command names / aliases → `cli/command/commands/commands.go`
104+
- `Cli` interface methods → `cli/command/cli.go`
105+
- Issue / PR numbers (in tests, comments, commits) — must be real, never
106+
placeholders
107+
108+
## Deeper context — fetch when relevant
109+
110+
Project documentation is hosted at <https://wpm.so/docs>. Do not preload these;
111+
fetch on demand when the task touches the area.
112+
113+
- **Discover what's available**: <https://wpm.so/docs/sitemap.xml>
114+
- **Read a page as markdown** — transform the URL:
115+
116+
```
117+
page: https://wpm.so/docs/fundamentals/dependencies
118+
md: https://wpm.so/docs/llms.mdx/docs/fundamentals/dependencies/content.md
119+
```
120+
121+
Typical triggers: `wpm.json` schema or scripts work → fundamentals docs;
122+
registry/auth/tokens → registry docs; resolution or lockfile semantics →
123+
resolution docs; signature verification → signatures docs.
124+
125+
## Gotchas
126+
127+
1. **Project root**: don't assume `os.Getwd()` is the `wpm.json` root in nested
128+
package logic. Walk up, or accept the root as a parameter.
129+
2. **`wpm.json` field changes** require all of: update
130+
`pkg/pm/wpmjson/types/types.go` (and `validator/` if constrained), update
131+
`README.md` and `docs/`, add a manifest test case.
132+
3. **Untrusted archives**: `pkg/archive` and `pkg/pm/installer` extract registry
133+
content. Zip Slip is a real risk — reuse the existing extraction helpers,
134+
don't reimplement.

0 commit comments

Comments
 (0)