From 549eda39ff1178d119c07280891d6c066b8048d1 Mon Sep 17 00:00:00 2001 From: "K. Isom" Date: Wed, 23 Sep 2026 07:40:14 -0700 Subject: [PATCH] add in-repo agent skill for working on the tracker project skills/tracker/SKILL.md documents build/run/vet, layout, and conventions. Anchor the .gitignore binary pattern to /tracker so the skill dir is tracked. --- .gitignore | 2 +- skills/tracker/SKILL.md | 76 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 skills/tracker/SKILL.md diff --git a/.gitignore b/.gitignore index 42fb354..ddbea9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -tracker +/tracker tracker.db tracker.db-shm tracker.db-wal diff --git a/skills/tracker/SKILL.md b/skills/tracker/SKILL.md new file mode 100644 index 0000000..baa5dfd --- /dev/null +++ b/skills/tracker/SKILL.md @@ -0,0 +1,76 @@ +--- +name: tracker +description: > + Work on the tracker project — a single-binary Go + SQLite project tracker with + server-rendered HTML, bcrypt auth, sessions, and a JSON API. Triggers when + editing files under internal/ or main.go, running/building the tracker binary, + touching auth or the store, or any request to add a feature or fix a bug in + this repo. Use it to keep changes consistent with the existing conventions. +--- + +# Tracker Skill + +A single-binary project tracker. Go + SQLite (pure-Go driver, no cgo), +server-rendered templates, no build step and no JS at runtime. Keep changes +small, match the surrounding style, and rebuild + `go vet` before finishing. + +## Build, run, vet + +``` +go build -o tracker . # build the binary +go vet ./... # static checks — run after every change +``` + +Run it: `./tracker -db ` listens on `:8420` by default. +Create a user: `./tracker -adduser kyle` (prompts for a passphrase, min 8 chars), +or non-interactively with `TRACKER_PASSWORD=... ./tracker -adduser kyle`. +Change a passphrase: `./tracker -changepw kyle` (same env-var variant). + +There are no automated tests yet. If you add code, verify by building, `go vet`, +and exercising the binary or the running server manually. + +## Layout + +- `main.go` — CLI flags (`-db`, `-addr`, `-adduser`, `-changepw`), the + interactive passphrase prompts (`golang.org/x/term`), bcrypt hashing. +- `internal/server/` — HTTP handlers and templates. + - `server.go` — `Routes()` wiring, embedded templates/static, page handlers. + - `api.go` — JSON API handlers under `/api/v1/`. + - `auth.go` — password check, sessions, api keys, auth middleware. +- `internal/store/` — SQLite access (modernc.org/sqlite, pure Go). + - `store.go` — schema/migrate, projects/notes/tasks/search/stats. + - `auth.go` — users, api keys, sessions. + +Templates live in `internal/server/templates/` and are embedded with +`//go:embed all:templates`; shared markup is in `partial.html` +(`header`/`footer` defines). CSS is `internal/server/static/style.css`. + +## Conventions + +- **Add a store method before a handler.** Data access belongs in + `internal/store/`; handlers in `internal/server/` stay thin. Use parameterized + queries (`?`) — never string-concatenated SQL. +- **Error handling:** the store returns `store.ErrNotFound` (from + `sql.ErrNoRows`) and `store.ErrConflict` (UNIQUE violations). Handlers surface + these via `s.apiNotFound` (JSON) or `s.error` (HTML page). `checkAffected` + turns zero-rows-into-`ErrNotFound` for updates/deletes — reuse it. +- **Validation** is done up front: trim whitespace, reject empty required + fields, and for the CLI enforce the min-8-char passphrase + match check. +- **Auth:** passwords are bcrypt-hashed only (never plaintext). Session tokens + and api keys are stored as SHA-256 hex hashes; the raw token is shown once. + `checkPassword` burns comparable time for missing users to avoid an + enumeration timing signal. +- **Style:** minimal, no comments unless the logic is non-obvious. HTML uses the + existing classes and `{{dateFmt}}` template helper; keep the Hackerman + terminal aesthetic. +- **Schema changes:** extend the `migrate()` block (all tables use + `CREATE TABLE IF NOT EXISTS`). The pure-Go driver supports `ALTER` at runtime + but existing deployments only run `IF NOT EXISTS` migrations — be careful + adding columns to shipped tables. + +## When making a change + +1. Read the neighboring file to match its exact style and framework choices. +2. Implement in the store first, then the handler/route. +3. `go build -o tracker .` and `go vet ./...` — both must pass. +4. If the change is user-facing, update the relevant README section.