diff --git a/.agents/skills/.gitignore b/.agents/skills/.gitignore new file mode 100644 index 0000000..5e4552b --- /dev/null +++ b/.agents/skills/.gitignore @@ -0,0 +1,2 @@ +# Generated by sync-ai-skills.sh. +# Keep this file so the directory exists even when no commands are synced yet. diff --git a/.agents/skills/open-pr/SKILL.md b/.agents/skills/open-pr/SKILL.md new file mode 100644 index 0000000..62b4355 --- /dev/null +++ b/.agents/skills/open-pr/SKILL.md @@ -0,0 +1,129 @@ +--- +name: open-pr +description: "Prepare the current worktree branch for a pull request: rebase, self-review, quality checks, and open a draft PR." +--- + +# Open PR + +Prepare the current worktree branch for a pull request: rebase, +self-review, quality checks, and open a draft PR. + +## Instructions + +1. **Verify you are on an isolated feature branch**: + + ```bash + CURRENT=$(git branch --show-current) + if [ -z "$CURRENT" ] || [ "$CURRENT" = "main" ] || [ "$CURRENT" = "master" ]; then + echo "Error: /open-pr must run from an active feature branch." + exit 1 + fi + ``` + + If on a default branch or detached HEAD, abort and ask the + user which feature branch to use. + + Check whether the current checkout is safe to use for PR prep: + + ```bash + git status --short + ``` + + If the checkout is the user's shared root checkout, has + unrelated local changes, or the work spans multiple repos or + submodules, stop and move to clean worktree(s) before rebasing + or committing. Create the worktree from the current feature + branch and continue the rest of this skill there; do not + rewrite history in the dirty root checkout. + +2. **Bootstrap the worktree before trusting failures**: + + Before running lint, typecheck, tests, or hooks, verify that + the worktree actually has the repo toolchain available + (`bun`, workspace dependencies, `turbo`, `oxlint`, project + bins, and env links if the repo expects them). + + If the worktree is missing the toolchain, run the repo's + normal install/setup flow first, then rerun the same command. + Do not treat missing-bin or module-resolution failures as + product-code regressions. Keep setup-only churn such as + accidental lockfile changes out of the PR unless the task + explicitly requires them. + +3. **Rebase onto the remote default branch**: + + ```bash + DEFAULT_BRANCH="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')" + if [ -z "$DEFAULT_BRANCH" ]; then + DEFAULT_BRANCH="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null)" + fi + if [ -z "$DEFAULT_BRANCH" ]; then + DEFAULT_BRANCH="main" + fi + + git fetch origin "$DEFAULT_BRANCH" + git rebase "origin/$DEFAULT_BRANCH" + ``` + + If conflicts arise, resolve them. After resolving, continue + the rebase. If a conflict is ambiguous, ask the user. + +4. **Self-review against CLAUDE.md conventions**: + + Get the full diff against the default branch: + + ```bash + git diff "origin/$DEFAULT_BRANCH" --name-only + ``` + + Read every changed file in full. Review against the + conventions in CLAUDE.md (TypeScript strictness, error + handling, security, naming, i18n, patterns). Fix any + violations directly; don't just list them. Commit fixes + separately with `fix: address self-review findings`. + +5. **Run quality checks using the repo's actual commands**: + + Run the checks the repository already defines for linting, + typechecking, tests, and non-mutating format verification. + If the repo defines `format:check`, use it. If it only + defines a mutating `format` script, do not run it as + verification unless you also commit the formatter output. + Prefer documenting a missing format check in the PR body over + inventing a one-off command that is inconsistent with the repo. + + If any check fails, fix the issue and re-run. Commit fixes + with `fix: lint/format/type errors`. + +6. **Security audit**: + + Run `/security-audit`. Fix any critical or high findings + in files changed in this PR before opening it. + Commit fixes with `fix: address security audit findings`. + +7. **Open the PR as draft**: + + Push the branch and create the PR as a **draft**: + + ```bash + git push --force-with-lease -u origin HEAD + gh pr create --fill --draft + ``` + + If `--fill` produces a poor title/body, write a proper one + following Conventional Commits (`feat:`, `fix:`, etc.) with + a very concise summary. Do not add a separate test plan unless + the user explicitly asks for one. Do not mention deployment + choices or attribute the motivation for the PR to a specific + person's feedback, request, or experience. + + This repository is public. Never include marketing language, + internal business context, pricing, competitive analysis, + user identities, conversation specifics, deployment specifics, + or security architecture beyond what the diff obviously shows. + Do not add details that would help a motivated attacker exploit + the code, especially a vulnerable previous version being fixed. + Assume the PR may be read by hostile adversaries, not only + friendly collaborators. When sensitive context would improve + readability, omit it by default; ask the user only if omission + would make the PR hard to review. diff --git a/.agents/skills/plan/SKILL.md b/.agents/skills/plan/SKILL.md new file mode 100644 index 0000000..fd5b535 --- /dev/null +++ b/.agents/skills/plan/SKILL.md @@ -0,0 +1,98 @@ +--- +name: plan +description: 'Create a new implementation plan in the repo''s planning area.' +--- + +# Create Plan + +Create a new implementation plan in the repo's planning area. + +## Arguments + +$ARGUMENTS — A short slug for the plan, ideally kebab-case. If empty, +derive a reasonable slug from the task. + +## Conventions + +Prefer this shared planning layout when the repo supports it: + +```text +.agents/ARCHITECTURE.md +.agents/GOALS.md +.agents/STATUS.md +.agents/plans/ +``` + +If the repo uses a different planning area, adapt to it rather than +creating duplicate systems. + +## Instructions + +1. **Read planning context**: + - `.agents/ARCHITECTURE.md` if present + - `.agents/GOALS.md` if present + - recent related plans if present + +2. **Determine the plan location**: + - prefer `.agents/plans/` + - if that directory does not exist, create it only if the repo is + clearly adopting the shared planning convention + - otherwise ask or use the repo's existing planning area + +3. **Determine the next plan number**: + + ```bash + ls .agents/plans/ + ``` + + Use the next sequential number when numbered plans are already in use. + If the repo does not number plans, follow its established naming. + +4. **Research before writing**: + - inspect the existing code + - read the relevant modules + - understand constraints, patterns, and likely blast radius + +5. **Write the plan** with this structure: + + ```markdown + # Plan: [Feature Name] + + Date: YYYY-MM-DD + + ## Goal + + What are we building and why? + + ## Design Decisions + + - **Decision**: Why this approach over alternatives. + + ## Scope + + **In scope:** + - ... + + **Out of scope:** + - ... + + ## Implementation + + - `path/to/file` — what changes here + + ## Test Cases + + What needs to be verified. + + ## Open Questions + + Any unresolved decisions. + ``` + +6. **Plan well, do not over-specify**: + - focus on _what_ and _why_ + - avoid locking in incidental implementation details too early + - call out migrations, security implications, and rollout risk when relevant + +7. **Confirm before finalizing** if the user is still shaping the task. + If they asked you to just create the plan, go ahead and write it. diff --git a/.agents/skills/product-think/SKILL.md b/.agents/skills/product-think/SKILL.md new file mode 100644 index 0000000..db9c256 --- /dev/null +++ b/.agents/skills/product-think/SKILL.md @@ -0,0 +1,68 @@ +--- +name: product-think +description: 'Shape a feature or problem before implementation. Use this when the request is still fuzzy, when several solutions are possible, or when execution risks outrunning product clarity.' +--- + +# Product Think + +Shape a feature or problem before implementation. Use this when the +request is still fuzzy, when several solutions are possible, or when +execution risks outrunning product clarity. + +## Arguments + +$ARGUMENTS — Feature idea, problem statement, or change request. + +## Instructions + +1. **Clarify the problem first**: + - who is affected? + - what pain or friction exists today? + - why does it matter now? + +2. **Separate problem from solution**: + - write down the user need + - write down the proposed solution + - check whether the solution actually addresses the need + +3. **Define outcome, not just output**: + - what should be better if this works? + - what user or business behavior should change? + +4. **State constraints**: + - technical constraints + - organizational constraints + - compliance or trust constraints + - timeline constraints + +5. **Explore options**: + - simplest viable option + - stronger but more expensive option + - what not to build yet + +6. **Make tradeoffs explicit**: + - speed vs correctness + - breadth vs depth + - automation vs control + - flexibility vs clarity + +7. **Define scope**: + - in scope + - out of scope + - follow-up ideas that should not block the first version + +8. **Define success**: + - what would we measure? + - what would we observe qualitatively? + - what would count as failure? + +9. **Produce a short product brief** in prose or markdown, with: + - problem + - user + - goal + - options considered + - recommendation + - risks + - success signal + +10. **Only move to implementation planning after this is coherent**. diff --git a/.agents/skills/rabbit-round/SKILL.md b/.agents/skills/rabbit-round/SKILL.md new file mode 100644 index 0000000..94965a8 --- /dev/null +++ b/.agents/skills/rabbit-round/SKILL.md @@ -0,0 +1,77 @@ +--- +name: rabbit-round +description: 'Process automated PR review comments systematically. Use this for CodeRabbit, Gemini, GitHub Copilot, Devin, Greptile, and similar bots.' +--- + +# Rabbit Round + +Process automated PR review comments systematically. Use this for +CodeRabbit, Gemini, GitHub Copilot, Devin, Greptile, and similar bots. + +## Instructions + +1. **Get context**: + + ```bash + PR_NUMBER=$(gh pr view --json number -q '.number') + gh api user --jq '.login' + git rev-parse HEAD + ``` + +2. **Fetch review comments** from the PR: + + ```bash + gh api repos/{owner}/{repo}/pulls/"$PR_NUMBER"/comments --paginate + ``` + + Filter for known bot accounts. Do not treat human review comments as bot comments. + +3. **Triage each bot comment**: + - **Accept** if it improves correctness, safety, maintainability, or follows repo conventions. + - **Push back** if it is incorrect, overreaching, or conflicts with documented conventions. + +4. **Implement accepted suggestions**: + - make the code changes + - group related fixes logically + - run the relevant project checks + +5. **Reply inline** to each bot comment: + + ```bash + COMMENT_ID="123456789" + gh api -X POST repos/{owner}/{repo}/pulls/"$PR_NUMBER"/comments/"$COMMENT_ID"/replies \ + -f body="[response]" + ``` + + Good response patterns: + - accepted and implemented + - agreed, implemented with a small adjustment + - already addressed in commit `{hash}` + - pushing back, with a concrete reason and source or repo convention + +6. **Never resolve human review threads**. For bot threads, resolve only after: + - the change is implemented, or + - the pushback is clearly documented + +7. **Check nit-level comments too**. Small ones still matter if they improve clarity + or remove avoidable friction. + +8. **Commit and push** if you made changes: + - use a neutral commit message such as `fix: address review comments` + - push to the active PR branch + +## Decision Guidelines + +**Accept when the suggestion:** +- fixes a bug or real edge case +- improves type safety +- adds missing tests +- aligns with existing repo patterns +- tightens security or validation appropriately + +**Push back when the suggestion:** +- assumes facts not true in this codebase +- conflicts with canonical specs or official sources +- adds complexity for little benefit +- would undo a deliberate, documented decision +- is purely stylistic and inconsistent with the repo diff --git a/.agents/skills/regression-hunt/SKILL.md b/.agents/skills/regression-hunt/SKILL.md new file mode 100644 index 0000000..e64d9a8 --- /dev/null +++ b/.agents/skills/regression-hunt/SKILL.md @@ -0,0 +1,206 @@ +--- +name: regression-hunt +description: 'Track down a behavior that used to work and now fails, changed, or regressed. Use this when a bug report points to a recent breakage, especially when the cause is not obvious yet.' +--- + +# Regression Hunt + +Track down a behavior that used to work and now fails, changed, or +regressed. Use this when a bug report points to a recent breakage, +especially when the cause is not obvious yet. + +## Arguments + +$ARGUMENTS — A short description of what regressed. + +Helpful extras when available: +- failing test name or file +- error message or log line +- expected vs actual behavior +- suspect PR, branch, commit, or file +- reproduction command, input, route, or endpoint + +A plain-English bug report is enough to start. + +## Instructions + +### 1. Restate the regression clearly + +- what used to work? +- what is broken now? +- what is expected instead? + +### 2. Build a feedback loop (this is the skill) + +Everything else is mechanical. With a fast, deterministic, agent-runnable +pass/fail signal, bisection and hypothesis testing all just consume it. +Without one, no amount of staring at code will save you. Spend +disproportionate effort here. Be aggressive. Be creative. Refuse to give up. + +Try these in roughly this order: + +1. Run the failing test via the package's test script — e.g. + `bun run test -- --bail -t ""` — so flags wired into the + script (`--preload`, custom setup) are preserved; calling `bun test` + directly bypasses them. Avoid `bun --bun test` from a worktree root. + Note that `bun test` positional arguments are **file path patterns**, + not test names; use `-t ""` to filter by test name and + `--bail` to fast-fail. +2. Curl / HTTP script against the backend dev server. Wrap fetches in + `AbortSignal.timeout(10_000)` so a hung request does not rot the loop. +3. CLI invocation diffing stdout against a known-good snapshot. +4. Headless browser (Chrome DevTools MCP, Playwright, or similar) against + the frontend dev server. +5. Replay a captured trace (saved payload, event log) through the code path + in isolation. +6. Throwaway harness exercising just the bug code path with a single + function call. For DB-touching code, a fresh test database per loop is + usually faster and more honest than mocking. +7. Differential loop: same input through old-commit vs new-commit, diff + outputs. +8. Bisection harness against the loop above. Drive it through the + package script so wired flags survive, e.g.: + `git bisect run bun run test -- --bail -t ""`. + Verify the harness actually fails on a known-bad commit before + starting — `bun test` exits 0 when no test names match, which would + silently mark every commit as good and produce the wrong culprit. +9. Property / fuzz loop if the bug is "sometimes wrong output". + +Then treat the loop as a product. Iterate on it: + +- **Faster?** Cache setup, skip unrelated init, narrow scope. +- **Sharper signal?** Assert on the specific symptom, not "didn't crash". +- **More deterministic?** Pin time, seed RNG, isolate filesystem, freeze + network. + +A 30-second flaky loop is barely better than no loop. A 2-second +deterministic loop is a debugging superpower. + +For non-deterministic bugs the goal is a **higher reproduction rate**, not a +clean repro. Loop the trigger 100×, parallelise, narrow timing windows, +inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the +rate until it is. + +If you genuinely cannot build a loop, stop and say so explicitly. List what +you tried. Ask the user for: environment access, a captured artifact (HAR, +log dump, screen recording with timestamps), or permission to add temporary +instrumentation. Do **not** proceed to hypothesise without a loop. + +### 3. Encode the regression in a test before fixing it + +Only if a **correct seam** exists — one where the test exercises the real +bug pattern as it occurs at the call site. A test at the wrong seam (too +shallow, single-caller test when the bug needs multiple callers, unit test +that cannot replicate the trigger chain) gives false confidence. + +If no correct seam exists, that itself is the finding. Note it and flag the +architectural gap for step 10. The codebase is preventing the bug from +being locked down. + +Prefer focused integration tests over deep unit tests when the regression +crosses layers. If the area has no automated harness, build the smallest +reproducible check and say why a proper regression test was not added yet. + +### 4. Generate 3–5 ranked hypotheses before instrumenting + +Single-hypothesis generation anchors on the first plausible idea. Each +hypothesis must be **falsifiable** — state its prediction: + +> If is the cause, then will make it disappear / +> will make it worse. + +If you cannot state a prediction, the hypothesis is a vibe — sharpen or +discard. Show the ranked list to the user before testing; domain knowledge +often re-ranks instantly ("we just deployed a change to #3"). Don't block +on it if the user is AFK; proceed with your own ranking. + +### 5. Inspect recent change history + +- current diff +- recent commits touching the area +- suspect PRs or refactors +- **React Compiler:** if the regression is a re-render / stale-closure / + perf shift in the frontend, check whether the compiler's output for the + affected component changed. A lot of "this used to memoize and now it + doesn't" bugs live here, not in your hand-written code. + +Use git history when helpful, but do not stop at blame; verify the actual +cause. For regressions specifically, `git bisect run` against your step 2 +loop is often the fastest path to the offending commit. + +### 6. Instrument + +Each probe must map to a specific prediction from step 4. Change one +variable at a time. + +Preference: + +1. **Bun inspector.** `bun --inspect-brk` is a runtime flag that must + attach to the process actually running the code, which means wrapping + it in `bun run