Contributing
Quick start
git clone https://github.com/yogasw/wick.git
cd wick
cp .env.example .env
go run . setup
go run . devDev server starts at http://localhost:9425.
Repo layout
app/ # RegisterTool / RegisterJob wiring (framework core)
cmd/cli/ # wick CLI commands (init, dev, server, worker, skill, build)
internal/ # framework internals — admin UI, auth, SSO, tags, job runner, agents
pkg/ # public packages used by scaffolded projects (tool, job, connector, entity)
template/ # project scaffold — copied verbatim by `wick init`
docs/ # this documentation site (VitePress)Where to make changes
| What you're changing | Where |
|---|---|
| Framework internals (new admin page, new pkg/ API) | internal/ or pkg/ |
Project scaffold (example tool/job, AGENTS.md, wick.yml) | template/ |
Bundled AI skills (tool-module, connector-module, design-system) | .claude/skills/ |
| Docs | docs/ |
Changing the scaffold
template/ is copied as-is by wick init. If you add a new file there, every new project gets it. If you change an existing file, run wick init in a temp dir and verify the output looks right before opening a PR.
Code conventions
Avoid os/exec.LookPath in wick-agent code paths
Inside everything that runs in the wick-agent binary (app/, internal/agents/, internal/pkg/api/, and anything reachable from template/main.go), use github.com/yogasw/wick/internal/safeexec instead of os/exec.LookPath:
safeexec.LookPath(name)— drop-in replacement.safeexec.ResolveBin(name)— call beforeexec.Command(name, ...)whennamemight be a bare binary name without a slash.exec.CommandcallsLookPathinternally duringCmdconstruction whenever the argument has no slash.
Why: Go's stdlib exec.LookPath uses the faccessat2(2) Linux syscall, which Android's seccomp filter on kernels < 5.8 rejects with SIGSYS (killing the process) instead of the ENOSYS Go's runtime falls back on. This affects Termux users running on phones where the kernel is older than the Android version suggests — Android 13 with kernel 4.14 is a common combination on devices that shipped before 2022.
CLI tooling under cmd/cli/, internal/builder/, and internal/updater/ runs on the developer's host (kernel ≥ 5.8 in practice) and can keep using stdlib exec.LookPath.
See Termux / Android for the full background.
Running tests
go build ./... # must compile cleanly
go test ./... -race # must pass, no data racesNo additional setup required — tests use SQLite in-memory.
Building the binary
go build -o wick .
./wick versionWorking on the docs site
cd docs
npm install
npm run dev # http://localhost:5173Docs use VitePress. Pages live in docs/guide/.
Commit style
Follow Conventional Commits:
feat(cli): add --dry-run flag to wick init
fix(job): prevent duplicate cron registration on restart
docs: add agent-host quickstart page
refactor(agents): extract pool slot allocation into separate structTypes: feat, fix, docs, refactor, test, chore, ci.
Scope is the affected package or area: cli, agents, job, tool, connector, mcp, admin, auth, docs.
Subject line ≤ 72 characters. No period at the end. Body only when the why isn't obvious from the diff.
Submitting a PR
- Fork and branch:
git checkout -b feat/my-feature - Make changes, add tests where appropriate
go build ./...andgo test ./... -race— both must pass- Open a pull request against
master - Fill in the PR description: what changed, why, how to test
Docs stay in sync. When you work in this repo with Claude Code, a
doc-syncagent reviews your branch diff before a PR is opened — aPreToolUsehook blocksgh pr createuntil it has run — and updatesdocs/when the change is user-facing. See.claude/agents/doc-sync.md.
Reporting issues
Open an issue at github.com/yogasw/wick/issues with:
- What you expected
- What happened
- Steps to reproduce
- OS, Go version, wick version (
wick version)