From 717c7daa7bb38b9a50d5457d64ba69ffa1fd3a21 Mon Sep 17 00:00:00 2001 From: Johannes Stein Date: Tue, 2 Jun 2026 22:31:50 +0200 Subject: [PATCH] Update skills --- .agents/skills/create-issue/SKILL.md | 158 ++++++--- .agents/skills/create-pr/SKILL.md | 110 ++++--- .agents/skills/git-workflow/SKILL.md | 80 +++++ .agents/skills/implement-idea/SKILL.md | 152 +++++++++ .agents/skills/implement-issue/SKILL.md | 165 ++++++++-- .../skills/native-nostalgia-stack/SKILL.md | 150 +++++++++ .agents/skills/project-structure/SKILL.md | 305 ++++++++++++++++++ .agents/skills/review-pr/SKILL.md | 65 +++- .agents/skills/update-pr/SKILL.md | 79 +++-- .github/workflows/pr.yml | 1 + skills-lock.json | 54 ++++ 11 files changed, 1144 insertions(+), 175 deletions(-) create mode 100644 .agents/skills/git-workflow/SKILL.md create mode 100644 .agents/skills/implement-idea/SKILL.md create mode 100644 .agents/skills/native-nostalgia-stack/SKILL.md create mode 100644 .agents/skills/project-structure/SKILL.md diff --git a/.agents/skills/create-issue/SKILL.md b/.agents/skills/create-issue/SKILL.md index 9eb32e67..5c6e7f24 100644 --- a/.agents/skills/create-issue/SKILL.md +++ b/.agents/skills/create-issue/SKILL.md @@ -1,58 +1,118 @@ --- name: create-issue -description: Create a well-structured GocciaScript GitHub issue from a tagline or short description, using the repository issue template and project issue style. Use when the user enters /create-issue. +description: >- + Creates a well-structured GitHub issue from a tagline or short description in + any repository, investigating for duplicates and invoking the grill skill + (grill-with-docs / grill-me) as a mandatory gate before drafting, using the + project's issue template and label conventions, and capturing UI/UX context + (screenshots, design references, accessibility, responsive, theme) when the + change is user-facing. Use when the user runs /create-issue or asks to file a + GitHub issue. +license: Unlicense OR MIT +compatibility: >- + Requires the GitHub CLI (gh) authenticated to the target repository and + network access. --- -# Create Issue +# Create issue -Create a GitHub issue from the user's tagline or short description. +## Instructions -## Steps +Create a GitHub issue in the current repository from the user's tagline or short description. -1. Parse the user's tagline or short description from the command arguments. If it is missing, ask for it. -2. Read `.github/ISSUE_TEMPLATE/default.md`. -3. Use the established GocciaScript issue style. Good issues in this repo typically include: - - A specific, plain-language title without an area prefix. +### Non-negotiable gates (do not skip, do not rationalize) + +These gates are mandatory. Do not skip them because the tagline "looks clear" or because creating an issue feels like a quick task. + +1. **GATE A — Grill before drafting.** When a grill skill is registered, you **must** invoke it (step 4) before drafting the issue body. Do not draft without it. +2. **GATE B — Investigate before drafting.** You **must** complete the investigation in step 3 (search for duplicates, read the implementation area) before drafting. Do not draft from the tagline alone. + +**Forbidden rationalizations** — if you catch yourself writing any of these, stop and follow the gate instead: + +- ❌ "The tagline is clear enough, I'll just draft it." → No. Grill and investigate first; a sharper issue comes from the questions you haven't asked yet. +- ❌ "Grill isn't necessary for a simple issue." → No. If it's registered, run it. +- ❌ "I treated `grill-with-docs` as 'answer with doc-grounding' instead of actually running the grilling loop." → No. Invoking grill means **executing the grill skill itself** — its real, interactive question loop — not answering in a doc-grounded style, not paraphrasing what it would ask. Load the skill and run it. +- ❌ "I'll ask a couple of clarifying questions of my own; that's basically grilling." → No. That is not the grill skill. Run the actual `grill-with-docs` / `grill-me` skill. + +### Use the grill skill for thoroughness (always when available) + +Before drafting, the agent **always invokes the grill skill** when it is registered in this environment — not only when something is ambiguous. This is GATE A above. The grill output is folded into the issue body so the result is more thorough than the raw tagline would produce. + +**Invoking the grill skill means literally running that skill — not imitating its spirit.** `grill-with-docs` and `grill-me` are separate skills with their own multi-question interrogation loop. To invoke one you **read its `SKILL.md` and execute its procedure**: actually ask the user the grilling questions it generates and wait for the answers, iterating until the loop completes. The following are **NOT** invoking it and are forbidden substitutes: + +- Treating the mention of `grill-with-docs` as a style instruction — "answer with doc-grounding," "be thorough," "cite the docs" — and then proceeding. ❌ +- Summarizing or paraphrasing the questions grilling *would* ask instead of asking them. ❌ +- Asking one or two clarifying questions of your own and calling that grilling. ❌ +- Skipping it because you believe you already understand the tagline. ❌ + +If you cannot run the grill skill, do not silently downgrade it to "doc-grounded answering" — say explicitly that no grill skill was found (see discovery hint) and proceed on the input as given. + +- **`/grill-with-docs` is preferred.** Use `/grill-me` only when `/grill-with-docs` is not registered. +- Discovery hint: look for a skill or command named `grill-with-docs` or `grill-me` (e.g. `~/.cursor/skills/grill-with-docs/`, `~/.cursor/skills/grill-me/`, `.cursor/skills/...`, `.agents/skills/...`). +- If neither is registered, state explicitly that no grill skill was found, then proceed with the workflow on the input as given. + +### Steps + +1. Parse the tagline or short description. If missing, ask. +2. Resolve the issue template: + - Prefer `.github/ISSUE_TEMPLATE/` (multiple templates); pick the one matching the issue type (bug, feature, chore, etc.). + - Fall back to `.github/ISSUE_TEMPLATE/default.md` or `.github/ISSUE_TEMPLATE.md`. + - If no template exists, use a minimal structure: Summary, Reproduction (bugs), Current vs Expected, Scope, Related. +3. **Investigate before drafting (GATE B):** + - Search code, docs, tests, and existing open/closed issues for duplicates and related work. + - Read the implementation area the issue touches. Do not draft from the tagline alone. + - If the tagline cannot become a concrete issue without guessing, stop and ask. +4. **Run the grill skill (GATE A).** When `grill-with-docs` / `grill-me` is registered, **read that skill and execute its actual question loop now** on the tagline plus your investigation findings — ask the questions, wait for answers, iterate to completion — then fold its output into the issue body. Do not substitute a "doc-grounded" answer or your own ad-hoc questions for the skill. If none is registered, say so explicitly and continue. +5. Draft the issue. A good issue typically includes: + - A specific, plain-language title with no area prefix (use labels for area/type). - A short problem summary. - - Reproduction commands or a minimal code sample for bugs. - - Current behavior and expected behavior. - - Spec context or project context when relevant. - - Test impact, blocked tests, or user impact. + - For bugs: reproduction command or minimal code/UI sample; current vs expected behavior. + - Project context (spec, RFC, related issue) when relevant. + - Test impact, user impact, or blocked work. - Likely fix area, scope notes, constraints, and related issues. -4. Investigate the codebase enough to avoid creating a vague or duplicate issue. Search for related code, docs, tests, and existing issues. If the tagline cannot be turned into a concrete issue without guessing, ask clarifying questions. -5. Draft the issue using the repository template. Preserve the template's headings unless another project issue pattern is clearly more appropriate for the issue type. -6. Choose labels by matching existing project label conventions. Use labels, not title prefixes, to capture area and type. Do not invent new labels unless the user asks. -7. Show the title, labels, and body draft to the user before creating the issue unless the user explicitly asked to create it without review. -8. Create the issue with GraphQL first. Include `labelIds` only when labels were selected: - -```bash -gh api graphql \ - -f query='mutation($repositoryId:ID!, $title:String!, $body:String!, $labelIds:[ID!]) { - createIssue(input: { - repositoryId: $repositoryId, - title: $title, - body: $body, - labelIds: $labelIds - }) { - issue { url number } - } - }' \ - -F repositoryId="$REPOSITORY_ID" \ - -f title="$ISSUE_TITLE" \ - -f body="$ISSUE_BODY" -``` - -When labels were selected, append one `-F labelIds[]="$LABEL_ID"` argument per label ID. - -9. If GraphQL is rate-limited or unavailable, create the issue with REST: - -```bash -gh api "repos/$OWNER/$REPO/issues" \ - -f title="$ISSUE_TITLE" \ - -f body="$ISSUE_BODY" \ - --jq '.html_url' -``` - -When labels were selected, append one `-f labels[]="$LABEL_NAME"` argument per label name. - -10. Return the issue URL to the user. +6. **If the change is UI/UX, also include:** + - Affected screens, routes, or components. + - Current visual state: screenshot, short recording, or precise description (layout, copy, state). + - Expected visual state: screenshot, mock, design link (Figma, etc.), or precise description. + - Accessibility expectations: keyboard navigation, focus order, visible focus, ARIA roles/labels, color contrast (target WCAG AA or the project's standard), motion / `prefers-reduced-motion`. + - Responsive scope: which breakpoints and devices apply, and which themes (light/dark/system). + - Design system or component library in use, and the specific tokens or components involved. +7. Choose labels by matching existing repo conventions. Use labels (not title prefixes) for area and type. Do not invent labels unless the user asks. +8. Show the title, labels, and body to the user before creating, unless the user asked to create without review. +9. Resolve the repository ID, then create the issue with GraphQL: + + ```bash + REPOSITORY_ID=$(gh api graphql \ + -f query='query($owner:String!,$name:String!){repository(owner:$owner,name:$name){id}}' \ + -f owner="$OWNER" -f name="$REPO" --jq '.data.repository.id') + + gh api graphql \ + -f query='mutation($repositoryId:ID!, $title:String!, $body:String!, $labelIds:[ID!]) { + createIssue(input: { + repositoryId: $repositoryId, + title: $title, + body: $body, + labelIds: $labelIds + }) { + issue { url number } + } + }' \ + -F repositoryId="$REPOSITORY_ID" \ + -f title="$ISSUE_TITLE" \ + -f body="$ISSUE_BODY" + ``` + + When labels were selected, append one `-F labelIds[]="$LABEL_ID"` argument per label ID. + +10. If GraphQL is rate-limited or unavailable, fall back to REST: + + ```bash + gh api "repos/$OWNER/$REPO/issues" \ + -f title="$ISSUE_TITLE" \ + -f body="$ISSUE_BODY" \ + --jq '.html_url' + ``` + + When labels were selected, append one `-f labels[]="$LABEL_NAME"` argument per label name. + +11. Return the issue URL. diff --git a/.agents/skills/create-pr/SKILL.md b/.agents/skills/create-pr/SKILL.md index 710c0237..9badd8bf 100644 --- a/.agents/skills/create-pr/SKILL.md +++ b/.agents/skills/create-pr/SKILL.md @@ -1,60 +1,78 @@ --- name: create-pr -description: Commit relevant changes, push the branch, and create a GocciaScript pull request using the repository PR template. Use when the user enters /create-pr. +description: >- + Commits relevant local changes, pushes a focused branch, and opens a draft + pull request on the current GitHub repository using the project's PR template + (single or multi-template). Use when the user runs /create-pr. +license: Unlicense OR MIT +compatibility: >- + Requires git and the GitHub CLI (gh) authenticated to the target repository, + plus network access. --- # Create PR -This command is explicit permission to commit relevant changes, push the branch, and create a pull request. +## Instructions -## Steps +Explicit permission to commit relevant changes, push the branch, and open a draft pull request. -1. Inspect the repository state: +### Steps + +1. Inspect the repository: - `git status --short --branch` - `git diff` - `git diff --staged` - `git log --oneline -5` -2. Confirm there are changes to commit. If there are none, stop. -3. If the current branch is `main`, create a focused branch before committing. Use an issue number or change summary for the branch name when available; otherwise ask the user. -4. Stage only relevant files. Exclude secrets and unrelated user changes. -5. Commit with a concise message passed via HEREDOC. -6. Push the branch with upstream tracking when needed: `git push -u origin HEAD`. -7. Build the PR body from the repository's pull request template. Read `.github/pull_request_template.md`, or the relevant template under `.github/PULL_REQUEST_TEMPLATE/` if the repository uses multiple templates. Fill the template faithfully and preserve its structure. -8. Create the pull request as a **draft** with GraphQL first: - -```bash -gh api graphql \ - -f query='mutation($repositoryId:ID!, $base:String!, $head:String!, $title:String!, $body:String!) { - createPullRequest(input: { - repositoryId: $repositoryId, - baseRefName: $base, - headRefName: $head, - title: $title, - body: $body, - draft: true - }) { - pullRequest { url number } - } - }' \ - -F repositoryId="$REPOSITORY_ID" \ - -f base="$BASE_BRANCH" \ - -f head="$HEAD_BRANCH" \ - -f title="$PR_TITLE" \ - -f body="$PR_BODY" -``` - -9. If GraphQL is rate-limited or unavailable, create the pull request as a **draft** with REST: - -```bash -gh api "repos/$OWNER/$REPO/pulls" \ - -f title="$PR_TITLE" \ - -f head="$HEAD_BRANCH" \ - -f base="$BASE_BRANCH" \ - -f body="$PR_BODY" \ - -F draft=true \ - --jq '.html_url' -``` - -10. Return the PR URL to the user. +2. If there is nothing to commit, stop. +3. Resolve the base branch from the remote default (do not hardcode `main`): + + ```bash + BASE_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name') + ``` + +4. If the current branch is the base branch, create a focused branch first. Use the issue number or a change summary; ask when ambiguous. +5. Stage only relevant files. Exclude secrets and unrelated local changes. +6. Commit with a concise message passed via HEREDOC. +7. Push with upstream tracking when needed: `git push -u origin HEAD`. +8. Resolve the PR template: + - Read `.github/pull_request_template.md`, or pick the matching template under `.github/PULL_REQUEST_TEMPLATE/` if the repo uses multiple. + - If none exists, use a minimal structure: Summary, Testing, Linked issues. + - Fill the template faithfully and preserve its structure. +9. Open as a **draft** via GraphQL first: + + ```bash + gh api graphql \ + -f query='mutation($repositoryId:ID!, $base:String!, $head:String!, $title:String!, $body:String!) { + createPullRequest(input: { + repositoryId: $repositoryId, + baseRefName: $base, + headRefName: $head, + title: $title, + body: $body, + draft: true + }) { + pullRequest { url number } + } + }' \ + -F repositoryId="$REPOSITORY_ID" \ + -f base="$BASE_BRANCH" \ + -f head="$HEAD_BRANCH" \ + -f title="$PR_TITLE" \ + -f body="$PR_BODY" + ``` + +10. If GraphQL is rate-limited or unavailable, fall back to REST as a **draft**: + + ```bash + gh api "repos/$OWNER/$REPO/pulls" \ + -f title="$PR_TITLE" \ + -f head="$HEAD_BRANCH" \ + -f base="$BASE_BRANCH" \ + -f body="$PR_BODY" \ + -F draft=true \ + --jq '.html_url' + ``` + +11. Return the PR URL. Do not skip git hooks or verification unless the user explicitly asks. diff --git a/.agents/skills/git-workflow/SKILL.md b/.agents/skills/git-workflow/SKILL.md new file mode 100644 index 00000000..17050af6 --- /dev/null +++ b/.agents/skills/git-workflow/SKILL.md @@ -0,0 +1,80 @@ +--- +name: git-workflow +description: >- + Default git workflow for the user's repositories: feature branches off the + remote default branch, merge (never rebase) to take baseline updates, plain + pushes (no --force or --force-with-lease), always-new commits (no amend), and + squash-merge for all pull requests. Use when running any git action — + branching, syncing, conflict resolution, committing, pushing, or merging — on + the user's repos. +license: Unlicense OR MIT +compatibility: >- + Requires git; pull-request operations also require the GitHub CLI (gh) and + network access. +--- + +# Git workflow + +## Instructions + +These are the user's repository defaults. Apply them on every git action unless the user explicitly overrides them in the same turn. + +### Rules + +- **Squash-merge** every pull request. Never use "Create a merge commit" or "Rebase and merge" on GitHub. +- **Never rebase.** Use merge to integrate changes — including baseline catch-up and conflict resolution. +- **Never force push.** Plain `git push` only. No `--force`, no `--force-with-lease`. +- **Never amend commits.** Always create new commits. `git commit --amend` is forbidden, even for typo fixes, unless the user explicitly asks in the same turn. + +### Branching + +Resolve the base branch from the remote default — do not hardcode `main`: + +```bash +BASE_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name') +``` + +- Create focused branches off the base. Name them from the issue or change (e.g. `issue-123-short-slug`, `fix-checkout-validation`). +- Never commit directly to the base branch. + +### Keeping a branch up to date + +When the branch is behind the remote base, **merge** the baseline: + +```bash +git fetch origin "$BASE_BRANCH" +git merge "origin/$BASE_BRANCH" --no-edit +``` + +Resolve any conflicts and commit the merge before continuing. Do not `git rebase origin/$BASE_BRANCH`. + +### Commits + +- Each logical change is its own commit. Use a HEREDOC for multi-line messages so formatting is preserved. +- Do not amend. If a commit needs a fix-up, add a new commit. +- Do not skip hooks (`--no-verify`) unless the user explicitly asks. + +### Pushing + +```bash +git push # routine push +git push -u origin HEAD # first push of a new branch +``` + +Never `git push --force` or `git push --force-with-lease`. If a remote push is rejected because the histories diverged, stop and ask the user — do not paper over with a force push. + +### Merging pull requests + +- Always **squash-merge** on GitHub. Edit the squash commit message to a clean summary before confirming the merge. +- Delete the source branch after the squash-merge (the GitHub option, or local cleanup). +- After the squash-merge, sync any local working copy that still has the merged branch: + +```bash +git checkout "$BASE_BRANCH" +git pull origin "$BASE_BRANCH" +git branch -D +``` + +### Exceptions + +Deviate from any rule only when the user explicitly asks in the same turn. State the deviation in chat so it is not silently normalized. diff --git a/.agents/skills/implement-idea/SKILL.md b/.agents/skills/implement-idea/SKILL.md new file mode 100644 index 00000000..98624ddf --- /dev/null +++ b/.agents/skills/implement-idea/SKILL.md @@ -0,0 +1,152 @@ +--- +name: implement-idea +description: >- + Turns a raw idea or feature request (no GitHub issue) into a confirmed + mini-spec by asking follow-up questions about scope, desired outcome, and + success criteria, then implements it with the same rigor as /implement-issue: + reads AGENTS.md/area context and applicable stack/conventions skills, runs a + full-context investigation, invokes the grill skill when registered, presents + exactly three options and stops for the user's choice before coding, + implements the chosen option, runs verification (UI/UX checks plus the + project's full check gate), reviews for shortcuts and tech debt, and prepares + a draft PR via /create-pr. Use when the user runs /implement-idea or wants to + build something that is not an existing issue. +license: Unlicense OR MIT +compatibility: >- + Requires git and the GitHub CLI (gh) for the /create-pr handoff, plus network + access; verification examples assume a Bun toolchain. +--- + +# Implement idea + +## Instructions + +Turn a raw idea into a confirmed mini-spec, then implement it in the current repository. This is `/implement-issue` without a GitHub issue — the idea-formulation phase (step 2) produces the spec that an issue would otherwise provide. + +### Non-negotiable gates (do not skip, do not rationalize) + +These four gates are mandatory. Most failures of this skill come from skipping one of them under time pressure or because the idea "looks simple." Being an implementation command is **not** a license to skip any gate. + +1. **GATE A — Formulate and confirm the idea before anything else.** You **must** complete the questioning in step 2 (scope, outcome, success criteria — shaped like a well-structured issue, borrowing `/create-issue`'s components) and get the user's explicit confirmation of the written mini-spec before investigating, grilling, or planning. Do not start designing from a vague one-liner. +2. **GATE B — Grill before planning.** When a grill skill is registered, you **must** invoke it (step 5) before presenting options. Do not proceed to options without it. +3. **GATE C — Full-context investigation before concluding.** You **must** complete the investigation in step 4 (enumerate the project's real commands, trace the relevant code paths) before forming any conclusion. A conclusion drawn from a single file or a guessed command is invalid. +4. **GATE D — Wait for the user's choice.** After presenting options (step 7) you **must stop and wait** for the user to pick one. Do **not** continue to implementation on your own. + +**Forbidden rationalizations** — if you catch yourself writing any of these, you are violating the skill, stop and follow the gate instead: + +- ❌ "The idea is clear enough, I'll just start building." → No. Formulate scope, outcome, and success criteria and get confirmation first (GATE A). +- ❌ "Since `/implement-idea` is an implementation command, I'll proceed with option A." → No. The command requires you to wait for the choice. Implementation is what happens *after* the user picks. +- ❌ "The choice is obvious, so I'll skip the question." → No. Present options and wait. The user may know constraints you don't. +- ❌ "Grill isn't strictly necessary here." → No. If it's registered, run it. +- ❌ "I treated `grill-with-docs` as 'answer with doc-grounding' instead of actually running the grilling loop." → No. Invoking grill means **executing the grill skill itself** — its real, interactive question loop — not answering in a doc-grounded style, not paraphrasing what it would ask. Load the skill and run it. +- ❌ "I'll ask a couple of clarifying questions of my own; that's basically grilling." → No. That is not the grill skill. Run the actual `grill-with-docs` / `grill-me` skill. + +If you are a smaller / non-frontier model: treat steps 2, 4, 5, and 7 as literal hard stops. Ask the questions, finish the checklist, run the tool, ask the question, then wait. + +### Formulating the idea + +The idea-formulation phase (step 2) is what makes this skill different from `/implement-issue`. Its job is to convert a vague idea into a concrete, confirmed mini-spec that is good enough to implement against and to verify against later. Drive it with focused follow-up questions across three axes: + +- **Scope.** What is in scope and — just as important — what is explicitly out of scope (non-goals)? What constraints apply (tech, deadlines, compatibility, data)? How big should this first cut be (MVP vs full)? +- **Outcome.** What does the end state look like? Who is the user and what problem does this solve for them? What is the desired behavior / UX / API surface? What changes for the user once it ships? +- **Success criteria.** How will we know it is done and working? What are the acceptance criteria, and which of them are testable / measurable? What would prove the idea succeeded versus merely "ran"? + +Ask only the questions that are actually open — do not interrogate the user about things they already stated. Iterate until the three axes are pinned down, then write the mini-spec back to the user (a short Scope / Outcome / Success criteria block) and get explicit confirmation before proceeding. This is separate from the grill skill: formulation establishes the spec; grilling (step 5) sharpens the plan against it. + +**Shape the mini-spec like a well-structured issue.** The `/create-issue` skill defines what a good issue contains; borrow those components so the formulated spec is as implementable as one that went through the proven `create-issue` → `implement-issue` loop: + +- A specific, plain-language title — the idea in one line. +- A short problem statement: what is missing or wrong today. +- Current vs desired behavior, with a concrete example or minimal sample where it helps. +- Project context (related work, prior art, spec/RFC, related items) when relevant. +- User impact and which work it unblocks. +- Likely affected area, scope notes, constraints, and non-goals. +- For UI/UX ideas, also: affected screens/routes/components, current and expected visual state, accessibility expectations (keyboard, focus, ARIA, contrast, motion), responsive scope and themes, and the design system / tokens involved — mirroring `/create-issue`'s UI/UX checklist. + +Map these onto the three axes: title + problem + current/desired behavior → **outcome**; affected area + constraints + non-goals → **scope**; acceptance examples + user-visible signals → **success criteria**. + +### Use the grill skill for thoroughness (always when available) + +Before presenting options, the agent **always invokes the grill skill** when it is registered in this environment — not only when something is ambiguous. This is GATE B above. The grill output is folded into the implementation plan and verification so the result is more thorough than the confirmed mini-spec alone would produce. + +**Invoking the grill skill means literally running that skill — not imitating its spirit.** `grill-with-docs` and `grill-me` are separate skills with their own multi-question interrogation loop. To invoke one you **read its `SKILL.md` and execute its procedure**: actually ask the user the grilling questions it generates and wait for the answers, iterating until the loop completes. The following are **NOT** invoking it and are forbidden substitutes: + +- Treating the mention of `grill-with-docs` as a style instruction — "answer with doc-grounding," "be thorough," "cite the docs" — and then proceeding. ❌ +- Summarizing or paraphrasing the questions grilling *would* ask instead of asking them. ❌ +- Asking one or two clarifying questions of your own and calling that grilling. ❌ +- Skipping it because you believe you already understand the idea. ❌ + +If you cannot run the grill skill, do not silently downgrade it to "doc-grounded answering" — say explicitly that no grill skill was found (see discovery hint) and proceed on the input as given. + +- **`/grill-with-docs` is preferred.** Use `/grill-me` only when `/grill-with-docs` is not registered. +- Discovery hint: look for a skill or command named `grill-with-docs` or `grill-me` (e.g. `~/.cursor/skills/grill-with-docs/`, `~/.cursor/skills/grill-me/`, `.cursor/skills/...`, `.agents/skills/...`). +- If neither is registered, state explicitly that no grill skill was found, then proceed with the workflow on the input as given. + +### Steps + +1. Capture the raw idea from the user. If no idea was provided, ask for it. +2. **Formulate and confirm the idea (GATE A).** Ask focused follow-up questions across **scope**, **outcome**, and **success criteria**, shaping the spec with `/create-issue`'s good-issue components (see "Formulating the idea" above). Iterate until all three are pinned down, then write the mini-spec back as a short Scope / Outcome / Success-criteria block and get the user's explicit confirmation. Do not investigate or plan until the spec is confirmed. If the user cannot commit to success criteria, surface that as a risk and agree on a provisional definition of done. +3. **Read the project's agent context before forming a hypothesis or editing.** In this order: + - The **root** `AGENTS.md` (and `CLAUDE.md` if present — usually an alias). + - The **nearest** `/AGENTS.md` to the files the idea touches in a multi-area repo. Nested files override the root for that area. + - `CONTRIBUTING.md` when it exists; treat it as authoritative for what may be merged. + - The repo's `docs/` index (`docs/README.md`, `docs/architecture.md`, `docs/code-style.md`, or equivalent) for the area being changed. + Do not skip this step even when the idea looks small — Hard Constraints sections (e.g. "Bun only, no npm/pnpm/yarn", "AI SDK via Vercel AI Gateway only") frequently change the implementation path. + + **Discover and use implementation-specific skills and context (required).** Before planning, check what specialized skills and context apply to the area being changed, and use them: + - **Registered skills.** Look for skills that match the project's stack or domain (e.g. a stack skill like `react-stack` / `native-nostalgia-stack`, a conventions skill like `convex-conventions`, or any project-provided skill in `.agents/skills/` ↔ `.claude/skills/`). When one matches the change, read it and follow it — its rules override generic defaults for that area. + - **In-repo context.** Honor area-specific `docs/` (e.g. `docs/code-style.md`, a feature MVP doc), `.cursor/rules`, and any `AGENTS.md`-referenced guides for the files you're touching. + - If a clearly relevant skill or context exists, using it is **not optional**. Implementing without consulting an applicable stack/conventions skill is a shortcut (see step 14). If none applies, note that briefly and proceed. + +4. **Investigate the whole codebase before concluding (GATE C). Do not take shortcuts.** A conclusion drawn from a single file or an assumed command is invalid. Before forming any plan: + - **Enumerate the project's real commands instead of guessing.** Read the manifest's script section (`package.json` `scripts`, `Makefile` / `Justfile` / `Taskfile`, `pyproject.toml`, `Cargo.toml`, etc.) and the `docs/tooling.md` / `docs/quick-start.md` equivalents. Use the commands the project actually defines (e.g. the project's `check`, `test`, `lint`, `dev` names) — never invent a command or assume a default that the repo hasn't declared. + - **Search broadly, not narrowly.** Use codebase search and grep to find where the idea fits: existing patterns to reuse, the modules and layers it touches, sibling features, config, and tests. Read the surrounding modules, not just the first match. + - **Assess feasibility against the confirmed spec.** Map each part of the mini-spec to where it would live in the codebase and flag anything the current architecture makes hard. + - If after a genuine investigation something is still unclear, that is a finding to raise in the options — not a reason to guess. + + **If the idea (or a close variant) already exists, do not rebuild it.** Surface that and carry it into the options (step 7): + - **Case: already implemented and covered.** Point to the existing implementation and its tests. The recommended outcome is to use it as-is or close the idea as already covered, not to write duplicate code. + - **Case: partially implemented.** Identify what exists versus what the spec still needs; the work becomes extending the existing implementation, not starting fresh. + - Confirm any "already exists" conclusion with evidence (the responsible code and tests) before presenting it. +5. **Run the grill skill (GATE B).** When `grill-with-docs` / `grill-me` is registered, **read that skill and execute its actual question loop now** on the confirmed mini-spec plus your investigation findings — ask the questions, wait for answers, iterate to completion — then fold its output into the options and verification plan. Do not substitute a "doc-grounded" answer or your own ad-hoc questions for the skill. If none is registered, say so explicitly and continue. +6. Validate before coding: + - The mini-spec is confirmed, the scope is bounded, and the success criteria are clear enough to verify against. + - The idea is not already fully implemented (per step 4). + - If the spec is still ambiguous or the scope keeps growing, stop and return to step 2. +7. **Present implementation options, then STOP and wait (GATE D).** Always present exactly three distinct options for delivering the idea, with tradeoffs, a verification plan tied to the success criteria, and a recommendation grounded in the step 4 investigation and step 5 grill output. The three must be genuinely different approaches (e.g. scope/architecture/effort tradeoffs), not trivial variations of one. When step 4 found the idea **already implemented**, the options reflect that instead of inventing duplicate code — e.g. (a) use/close as already covered, (b) extend the existing implementation to meet the remaining spec, (c) a thin alternative that reuses the existing code. **Do not write any implementation code until the user explicitly picks an option or explicitly tells you to proceed with the recommendation.** Do not interpret "this is an implementation command" as permission to skip the choice. End your turn here and wait for the user's reply. + *If the chosen option is "already covered" with no code or test change, skip steps 8–15: report the existing implementation and stop. The remaining steps apply only when there is a code or test change to ship.* + +8. Branch / worktree: + - Prefer reusing an existing focused branch or worktree for the idea. + - If a branch exists without a worktree, use or create a worktree when that best isolates the work. + - Otherwise create a focused branch named from the idea (e.g. `idea-short-slug`); use a worktree when practical. +9. Implement the smallest complete change that satisfies the chosen approach and the confirmed success criteria. +10. Update tests and documentation per the repository's contribution guidance (`CONTRIBUTING.md`, `AGENTS.md`, or equivalent) when present. +11. Run targeted verification first (focused tests, types, lint) on the changed area, then broader verification when the change has wider impact. +12. **If the change is UI/UX, also:** + - Run the app (or Storybook / component sandbox) and load the affected screens or components. + - Compare against the outcome described in the confirmed spec. Capture before/after screenshots or short recordings. + - Verify accessibility: keyboard navigation and focus order, visible focus styles, ARIA roles/labels for new interactive elements, color contrast meeting WCAG AA (or the project's standard), and `prefers-reduced-motion` respected for animations. + - Verify responsive behavior at the project's supported breakpoints and across light/dark/system themes when applicable. + - Reuse existing design-system components and tokens; do not introduce one-off styles for primitives that already exist. + - Attach before/after media and accessibility notes to the PR description so reviewers can evaluate without re-running the app. +13. **Run the project's full verification gate before invoking `/create-pr`.** Prefer the project's aggregator script when it exists (e.g. `bun run check`) — that's the canonical "ready to commit" signal. Otherwise run the per-step gate explicitly: + + ```bash + bun install --frozen-lockfile + bun run format:check # or biome check + bun run lint # or biome lint . + bun test + bun run typecheck # or tsc --noEmit / bunx tsc --noEmit + bun run build + ``` + + Do not skip steps because they "should pass." If any step fails, fix the cause; do not invoke `/create-pr` with a red gate. + +14. **Review the implementation before handoff (do not skip).** After the gate is green but before `/create-pr`, audit your own change critically — as a reviewer who did not write it would: + - **Matches the spec.** The change satisfies the confirmed mini-spec's scope, outcome, and success criteria. The exception: when the scope was deliberately changed across later turns or grill sessions, match that updated intent instead — and note the divergence from the original idea in the PR description so reviewers understand why. + - **No shortcuts.** No stubbed logic, hardcoded values standing in for real behavior, `TODO`/`FIXME` left behind, swallowed errors, skipped/`.only`/commented-out tests, or "happy path only" handling of cases the spec requires. Confirm the real layer was built, not a façade. + - **No tech debt introduced.** No dead code, no duplication that should be extracted, no copy-paste of an existing pattern that has a shared helper, no weakened types (`any`, unsafe casts) or loosened lint/type rules to make the gate pass, no leftover debug output. + - **Consistency.** The change follows the repo's conventions (from step 3 agent context and `docs/code-style.md`) and reuses existing components/utilities rather than reinventing them. + - If this review surfaces a problem, fix it and re-run the relevant verification (step 11/13) before proceeding. Do not defer found issues to "a follow-up" unless the user explicitly agrees. +15. Invoke `/create-pr` to commit, push, and open the draft pull request. Summarize the idea and its success criteria in the PR body. There is no issue to close. diff --git a/.agents/skills/implement-issue/SKILL.md b/.agents/skills/implement-issue/SKILL.md index 2c58ae49..066f6f74 100644 --- a/.agents/skills/implement-issue/SKILL.md +++ b/.agents/skills/implement-issue/SKILL.md @@ -1,35 +1,138 @@ --- name: implement-issue -description: Validate a GitHub issue against the GocciaScript codebase, present implementation options, implement the chosen fix, and prepare a PR. Use when the user enters /implement-issue with an issue number. +description: >- + Validates a GitHub issue against the current codebase, reading the nearest + AGENTS.md/CLAUDE.md, area context, and any applicable stack/conventions + skills first. Runs a full-context investigation (real project commands, whole + code path, no shortcuts), handles already-fixed issues by closing or adding + regression tests, invokes the grill skill when registered, then presents + implementation options and stops for the user's choice before coding. + Implements the chosen option, runs verification (UI/UX checks plus the + project's full check gate), reviews for shortcuts and tech debt, and prepares + a draft PR via /create-pr. Use when the user runs /implement-issue with an + issue number. +license: Unlicense OR MIT +compatibility: >- + Requires the GitHub CLI (gh) authenticated to the target repository and + network access; verification examples assume a Bun toolchain. --- -# Implement Issue - -Validate and implement the requested GitHub issue. - -## Steps - -1. Parse the issue number. If it is missing or not numeric, ask the user for the issue number. -2. Fetch the issue with GraphQL first, including title, body, state, labels, assignees, URL, comments, and whether the issue is actually a pull request. -3. If GraphQL is rate-limited or unavailable, fetch the issue with REST: - -```bash -gh api "repos/$OWNER/$REPO/issues/$ISSUE_NUMBER" -``` - -4. Thoroughly review and validate the issue before coding: - - The issue exists. - - The issue is open. - - The issue is not a pull request. - - Labels or comments do not indicate `blocked`, `duplicate`, `wontfix`, or equivalent. - - The reported behavior has been checked against the current codebase, not just accepted from the issue text. - - When the issue body provides a reproduction command, test path, or references an external test (test262, etc.), fetch and run that exact artifact first — before forming any hypothesis about the cause. Do not reconstruct a scenario from the title; the title is a pointer to the bug, not a spec for it. - - The problem statement is verified as an actual issue in this codebase by reading the relevant implementation, running the provided reproduction (or adding a focused one when none is provided), and comparing observed behavior with the expected behavior. - - The expected behavior and acceptance criteria are clear enough to implement. -5. If validation fails or requirements are ambiguous, stop and ask the user. -6. Present the user with different implementation options, including tradeoffs, recommended verification, and the option you recommend. Do not code until the user chooses an option or explicitly asks you to proceed with the recommendation. -7. Check whether a focused branch or worktree for the issue already exists locally or on `origin`. Prefer reusing the existing focused worktree when present. If a branch exists without a worktree, use or create a worktree for it when that best isolates the work. If no focused branch exists, create one named from the issue, for example `issue-123-short-slug`, and use a worktree when practical. -8. Implement the smallest complete change that satisfies the chosen approach. -9. Add or update tests and documentation according to `CONTRIBUTING.md`. -10. Run targeted verification, then broader verification when the change has wider impact. -11. Invoke the `/create-pr` skill to commit, push, and open the pull request. Include `Closes #` in the PR body. +# Implement issue + +## Instructions + +Validate and implement a GitHub issue in the current repository. + +### Non-negotiable gates (do not skip, do not rationalize) + +These three gates are mandatory. Most failures of this skill come from skipping one of them under time pressure or because the task "looks simple." Being an implementation command is **not** a license to skip any gate. + +1. **GATE A — Grill before planning.** When a grill skill is registered, you **must** invoke it (step 6) before forming a hypothesis or presenting options. Do not proceed to options without it. +2. **GATE B — Full-context investigation before concluding.** You **must** complete the investigation in step 5 (enumerate the project's real commands, trace the full code path, reproduce) before forming any conclusion. A conclusion drawn from a single file or a guessed command is invalid. +3. **GATE C — Wait for the user's choice.** After presenting options (step 8) you **must stop and wait** for the user to pick one. Do **not** continue to implementation on your own. + +**Forbidden rationalizations** — if you catch yourself writing any of these, you are violating the skill, stop and follow the gate instead: + +- ❌ "Since `/implement-issue` is an implementation command, I'll proceed with option A." → No. The command requires you to wait for the choice. Implementation is what happens *after* the user picks. +- ❌ "The choice is obvious, so I'll skip the question." → No. Present options and wait. The user may know constraints you don't. +- ❌ "Grill isn't strictly necessary here." → No. If it's registered, run it. +- ❌ "I treated `grill-with-docs` as 'answer with doc-grounding' instead of actually running the grilling loop." → No. Invoking grill means **executing the grill skill itself** — its real, interactive question loop — not answering in a doc-grounded style, not paraphrasing what it would ask. Load the skill and run it. +- ❌ "I'll ask a couple of clarifying questions of my own; that's basically grilling." → No. That is not the grill skill. Run the actual `grill-with-docs` / `grill-me` skill. +- ❌ "I found the likely cause in this one file, no need to look further." → No. Complete the full-context investigation first. + +If you are a smaller / non-frontier model: treat steps 6, 5, and 8 as literal hard stops. Run the tool, finish the checklist, ask the question, then wait. + +### Use the grill skill for thoroughness (always when available) + +Before forming a hypothesis or presenting implementation options, the agent **always invokes the grill skill** when it is registered in this environment — not only when something is ambiguous. This is GATE A above. The grill output is folded into the implementation plan and validation step so the result is more thorough than the raw issue text would produce. + +**Invoking the grill skill means literally running that skill — not imitating its spirit.** `grill-with-docs` and `grill-me` are separate skills with their own multi-question interrogation loop. To invoke one you **read its `SKILL.md` and execute its procedure**: actually ask the user the grilling questions it generates and wait for the answers, iterating until the loop completes. The following are **NOT** invoking it and are forbidden substitutes: + +- Treating the mention of `grill-with-docs` as a style instruction — "answer with doc-grounding," "be thorough," "cite the docs" — and then proceeding. ❌ +- Summarizing or paraphrasing the questions grilling *would* ask instead of asking them. ❌ +- Asking one or two clarifying questions of your own and calling that grilling. ❌ +- Skipping it because you believe you already understand the request. ❌ + +If you cannot run the grill skill, do not silently downgrade it to "doc-grounded answering" — say explicitly that no grill skill was found (see discovery hint) and proceed on the input as given. + +- **`/grill-with-docs` is preferred.** Use `/grill-me` only when `/grill-with-docs` is not registered. +- Discovery hint: look for a skill or command named `grill-with-docs` or `grill-me` (e.g. `~/.cursor/skills/grill-with-docs/`, `~/.cursor/skills/grill-me/`, `.cursor/skills/...`, `.agents/skills/...`). +- If neither is registered, state explicitly that no grill skill was found, then proceed with the workflow on the input as given. + +### Steps + +1. Parse the issue number. If missing or non-numeric, ask. +2. Fetch the issue with GraphQL first: title, body, state, labels, assignees, URL, comments, and whether the entity is actually a pull request. +3. Fall back to REST when GraphQL is unavailable: + + ```bash + gh api "repos/$OWNER/$REPO/issues/$ISSUE_NUMBER" + ``` + +4. **Read the project's agent context before forming a hypothesis or editing.** In this order: + - The **root** `AGENTS.md` (and `CLAUDE.md` if present — usually an alias). + - The **nearest** `/AGENTS.md` to the files the issue touches in a multi-area repo. Nested files override the root for that area. + - `CONTRIBUTING.md` when it exists; treat it as authoritative for what may be merged. + - The repo's `docs/` index (`docs/README.md`, `docs/architecture.md`, `docs/code-style.md`, or equivalent) for the area being changed. + Do not skip this step even when the issue looks small — Hard Constraints sections (e.g. "Bun only, no npm/pnpm/yarn", "AI SDK via Vercel AI Gateway only") frequently change the implementation path. + + **Discover and use implementation-specific skills and context (required).** Before planning, check what specialized skills and context apply to the area being changed, and use them: + - **Registered skills.** Look for skills that match the project's stack or domain (e.g. a stack skill like `react-stack` / `native-nostalgia-stack`, a conventions skill like `convex-conventions`, or any project-provided skill in `.agents/skills/` ↔ `.claude/skills/`). When one matches the change, read it and follow it — its rules override generic defaults for that area. + - **In-repo context.** Honor area-specific `docs/` (e.g. `docs/code-style.md`, a feature MVP doc), `.cursor/rules`, and any `AGENTS.md`-referenced guides for the files you're touching. + - If a clearly relevant skill or context exists, using it is **not optional**. Implementing without consulting an applicable stack/conventions skill is a shortcut (see step 15). If none applies, note that briefly and proceed. + +5. **Investigate the whole codebase before concluding (GATE B). Do not take shortcuts.** A conclusion drawn from a single file or an assumed command is invalid. Before forming any hypothesis: + - **Enumerate the project's real commands instead of guessing.** Read the manifest's script section (`package.json` `scripts`, `Makefile` / `Justfile` / `Taskfile`, `pyproject.toml`, `Cargo.toml`, etc.) and the `docs/tooling.md` / `docs/quick-start.md` equivalents. Use the commands the project actually defines (e.g. the project's `check`, `test`, `lint`, `dev` names) — never invent a command or assume a default that the repo hasn't declared. + - **Search broadly, not narrowly.** Use codebase search and grep to find every site related to the issue: the symbol, its callers, its tests, sibling implementations, and config. Read the surrounding modules, not just the first match. + - **Trace the full code path** from entrypoint to the reported symptom. Identify the actual layer where the behavior originates rather than patching the first place the symptom appears. + - **Reproduce the reported behavior** against current code; do not trust the issue text alone. When the issue cites a reproduction command, test path, or external artifact (test262, Playwright run, etc.), fetch and run that exact artifact. The title is a pointer, not a spec. + - If after a genuine investigation something is still unclear, that is a finding to raise in the options — not a reason to guess. + + **If the reported behavior does NOT reproduce, the issue may already be fixed. Do not invent a change to justify the command.** Determine which case applies and carry it into the options (step 8): + - **Case: already fixed AND already covered by a test.** Find the commit/code that fixed it and the test that locks it in. The recommended outcome is to close the issue as already resolved (referencing the fixing commit and the covering test), not to write new code. Only add something if the user wants extra coverage. + - **Case: already fixed BUT not covered by a regression test.** The behavior works but nothing prevents it from regressing. The work becomes **adding a regression test** (and any missing edge-case tests) that would fail against the pre-fix code and passes now — no production-code change. Name the test after the issue so the linkage is obvious. + - **Case: fixed for the reported path but adjacent paths are untested or still broken.** Add tests for the sibling paths surfaced in the broad search above, and fix any that are genuinely broken. Treat each broken sibling as in-scope only if it shares the issue's root cause; otherwise note it for a separate issue. + - In all three cases, confirm the "already fixed" conclusion with evidence (the passing reproduction, the responsible code, the existing or missing test) before presenting it — a behavior that merely looks fixed in one spot may still fail on another path. +6. **Run the grill skill (GATE A).** When `grill-with-docs` / `grill-me` is registered, **read that skill and execute its actual question loop now** on the issue plus your investigation findings — ask the questions, wait for answers, iterate to completion — then fold its output into the options and verification plan. Do not substitute a "doc-grounded" answer or your own ad-hoc questions for the skill. If none is registered, say so explicitly and continue. +7. Validate before coding: + - The issue exists, is open, and is not a pull request. + - No `blocked`, `duplicate`, `wontfix`, or equivalent label/comment. + - Expected behavior and acceptance criteria are clear enough to implement. + - If validation fails or requirements are ambiguous, stop and ask. +8. **Present implementation options, then STOP and wait (GATE C).** Always present exactly three distinct options with tradeoffs, a verification plan, and a recommendation grounded in the step 5 investigation and step 6 grill output. The three must be genuinely different approaches, not trivial variations of one. When step 5 found the issue **already fixed**, the options reflect that situation instead of inventing a code change — e.g. (a) close as already resolved citing the fixing commit and covering test, (b) add a regression test (plus missing edge-case tests) that would have caught the original bug, (c) extend coverage/fixes to the adjacent paths surfaced in the search. **Do not write any implementation code until the user explicitly picks an option or explicitly tells you to proceed with the recommendation.** Do not interpret "this is an implementation command" as permission to skip the choice. End your turn here and wait for the user's reply. + *If the chosen option is "close as already resolved" with no code or test change, skip steps 9–16: instead, comment on the issue with the evidence (fixing commit + covering test) and close it (or ask the user to). The remaining steps apply only when there is a code or test change to ship.* + +9. Branch / worktree: + - Prefer reusing an existing focused branch or worktree for the issue. + - If a branch exists without a worktree, use or create a worktree when that best isolates the work. + - Otherwise create a focused branch named from the issue (e.g. `issue-123-short-slug`); use a worktree when practical. +10. Implement the smallest complete change that satisfies the chosen approach. +11. Update tests and documentation per the repository's contribution guidance (`CONTRIBUTING.md`, `AGENTS.md`, or equivalent) when present. +12. Run targeted verification first (focused tests, types, lint) on the changed area, then broader verification when the change has wider impact. +13. **If the change is UI/UX, also:** + - Run the app (or Storybook / component sandbox) and load the affected screens or components. + - Compare against the design or current state from the issue. Capture before/after screenshots or short recordings. + - Verify accessibility: keyboard navigation and focus order, visible focus styles, ARIA roles/labels for new interactive elements, color contrast meeting WCAG AA (or the project's standard), and `prefers-reduced-motion` respected for animations. + - Verify responsive behavior at the project's supported breakpoints and across light/dark/system themes when applicable. + - Reuse existing design-system components and tokens; do not introduce one-off styles for primitives that already exist. + - Attach before/after media and accessibility notes to the PR description so reviewers can evaluate without re-running the app. +14. **Run the project's full verification gate before invoking `/create-pr`.** Prefer the project's aggregator script when it exists (e.g. `bun run check`) — that's the canonical "ready to commit" signal. Otherwise run the per-step gate explicitly: + + ```bash + bun install --frozen-lockfile + bun run format:check # or biome check + bun run lint # or biome lint . + bun test + bun run typecheck # or tsc --noEmit / bunx tsc --noEmit + bun run build + ``` + + Do not skip steps because they "should pass." If any step fails, fix the cause; do not invoke `/create-pr` with a red gate. + +15. **Review the implementation before handoff (do not skip).** After the gate is green but before `/create-pr`, audit your own change critically — as a reviewer who did not write it would: + - **Matches the issue.** The change satisfies the original issue's intent, description, and acceptance criteria. The exception: when the scope was deliberately changed across later turns or grill sessions, match that updated intent instead — and note the divergence from the original issue text in the PR description so reviewers understand why. + - **No shortcuts.** No stubbed logic, hardcoded values standing in for real behavior, `TODO`/`FIXME` left behind, swallowed errors, skipped/`.only`/commented-out tests, or "happy path only" handling of cases the issue requires. Re-trace the full code path from step 5 and confirm the real layer was fixed, not just the symptom. + - **No tech debt introduced.** No dead code, no duplication that should be extracted, no copy-paste of an existing pattern that has a shared helper, no weakened types (`any`, unsafe casts) or loosened lint/type rules to make the gate pass, no leftover debug output. + - **Consistency.** The change follows the repo's conventions (from step 4 agent context and `docs/code-style.md`) and reuses existing components/utilities rather than reinventing them. + - If this review surfaces a problem, fix it and re-run the relevant verification (step 12/14) before proceeding. Do not defer found issues to "a follow-up" unless the user explicitly agrees. +16. Invoke `/create-pr` to commit, push, and open the draft pull request. Include `Closes #` in the PR body. diff --git a/.agents/skills/native-nostalgia-stack/SKILL.md b/.agents/skills/native-nostalgia-stack/SKILL.md new file mode 100644 index 00000000..3a73fb23 --- /dev/null +++ b/.agents/skills/native-nostalgia-stack/SKILL.md @@ -0,0 +1,150 @@ +--- +name: native-nostalgia-stack +description: >- + Defines the user's FreePascal toolchain — FPC as the compiler in Delphi mode + by default, the contract every project's build system must satisfy, the + contract every project's formatter / linter must satisfy, Lefthook + pre-commit, and co-located unit tests. Implementation of the build system + and the formatter is the project's choice (Pascal program, Makefile, shell + script, etc.) as long as the contract holds. Implementation specifics for + any individual project (engine rules, spec compliance, runtime + configuration, etc.) belong in that project's own AGENTS.md and docs. + Use when scaffolding or working in a FreePascal project that follows this + toolchain. +license: Unlicense OR MIT +compatibility: >- + Assumes a FreePascal project compiled with FPC in Delphi mode, with Lefthook + for pre-commit hooks. +--- + +# Native nostalgia stack + +## Instructions + +This skill describes the **toolchain contract and project-specific structure** for a FreePascal project on this stack. Universal repo layout, AGENTS.md shape, docs template, pre-commit hook contract, scripts directory, agent-skill symlinks, and changelog generation live in `project-structure/SKILL.md`. Implementation rules for any individual project (engine internals, spec compliance, runtime configuration shape, etc.) belong in that project's own AGENTS.md and docs. + +### Principles + +- **Smallest viable toolchain.** Pick the smallest set of tools that satisfy the build-system and formatter contracts below. Do not pull in additional toolchains (CMake, Bazel, Gradle, etc.) when a smaller mechanism already satisfies the contract. +- **Verify versions at implementation:** the agent confirms the FPC version and any pinned tool versions in use at the moment of work — not from memory. + +### Compiler + +- **FreePascal (FPC), latest stable.** Verify the version pinned in `docs/tooling.md` (or the equivalent) and CI workflows before assuming it. +- **Delphi mode by default.** Delphi mode is the default unless the project explicitly pins another (`objfpc`, `mac`, `tp`). When a project pins another mode, that pin lives in `docs/code-style.md`. +- **Compiler flags live in a shared include file**, not inline in every unit. The project keeps a single `.inc` file (e.g. `source/.inc`) holding `{$mode delphi}`, `{$H+}`, and any other project-wide directives. Every unit pulls the include via `{$I .inc}` (or the project's chosen path); the directives are not repeated in each unit. Changing a project-wide flag means editing the include, not every file. + +### Code style starting points + +Enforced by the formatter where possible, otherwise by review. + +- **Naming.** + - Classes `T`, interfaces `I`, exceptions `E`. + - Private fields use the `F` prefix. + - Parameters with two or more letters use the `A` prefix; single-letter parameters (`A`, `B`, `E`, `T`) keep their name. + - Functions, procedures, methods, locals, and constants use `PascalCase`. No underscores. No numeric suffixes (`PrimaryScope`, not `Scope1`). + - **No abbreviations.** Full words for class, function, method, and type names. Industry-standard acronyms (`AST`, `JSON`, `ISO`, `UUID`, `URL`, `HTTP`, etc.) are kept as-is. +- **OOP by default.** Classes are the modeling primitive: each domain concept gets its own class with explicit responsibilities, and variation is expressed through inheritance and polymorphism. Reach for records, plain procedures, or generic data structures only when there is no behavior to attach. +- **Mark small subroutines `inline` where it makes sense.** Add `inline;` to small functions, procedures, and methods (trivial accessors, hot-path one-liners). `inline` is a compiler hint — FPC decides whether to actually inline based on size and content; the directive nudges it without forcing it. Skip `inline` on large bodies, recursive routines, and routines that take their own address. +- **`const` parameters by default.** Use `var` or `out` only when the parameter is mutated. `const` applies to objects, strings, records, integers — anything not intentionally written. +- **No magic literals.** Bare numeric and string literals are extracted into named constants and declared in `interface` when shared between `interface` and `implementation`. +- **Uses clauses: one unit per line, alphabetized within groups, blank line between groups.** Group order: system units → third-party / non-prefixed project units → namespaced project units → relative-path units. Enforced by the formatter. +- **File organization.** `interface` declares only the public API. Heavy or cycle-causing dependencies go in the `implementation uses` clause to break circular references. +- **Generic specializations have named aliases.** When a generic specialization (`TObjectList`, `TOrderedMap`, etc.) is used across more than one unit, declare a single named alias in the unit that owns the parameter type. Do not re-specialize the same generic locally — separate VMTs cause cross-unit type-cast failures under strict object checks. +- **RTTI via `TypInfo` when introspection is needed.** When a class needs to be inspected, configured, or dispatched dynamically at runtime (serialization, configuration binding, generic forms, scripted property access, etc.), expose the relevant properties and methods in the `published` section and read or write them through FPC's `TypInfo` (`GetPropInfo`, `GetPropValue`, `SetPropValue`, `GetMethodProp`, `SetMethodProp`, etc.). Do not put what does not need introspection into `published`. +- **Minimal public API.** Units expose only what's needed; implementation details stay inside `implementation`. + +### Build system contract + +Every project on this stack has a build system. The **implementation is the project's choice** (a Pascal program compiled by FPC, a Makefile, a Justfile, a shell script, etc.) as long as it satisfies this contract: + +- **Single entry point** invoked from the repo root. The same command — whatever it is — drives every build. +- **Default target.** The bare invocation performs a clean dev build of every binary the project produces. +- **Named targets** per binary, addressable as positional arguments. Multiple targets can be passed at once. +- **Dev / prod distinction.** A `--dev` flag is the default (fast feedback); a `--prod` flag switches every step to release flags. +- **`clean` is a target,** not a separate script. A bare `clean` cleans everything; `clean ` cleans then builds that target. +- **Single output directory.** All binaries land under `build/` at the repo root. `build/` is never committed. + +The choice of implementation, the list of targets, and the available flags are recorded in the project's `docs/build-system.md` (or equivalent). Read that file before adding or renaming a target. + +### Formatter / linter contract + +Every project on this stack has a formatter / linter that combines style rewriting and lint-style checks. The **implementation is the project's choice** (a Pascal program, `ptop`, `fpcformat`, a wrapper around an external tool, etc.) as long as it satisfies this contract: + +- **No-flag invocation rewrites Pascal sources in place** to the project's canonical style. +- **`--check` flag exits non-zero on any deviation** without modifying files. This is the form CI and the pre-commit hook call. +- **Project-specific style rules are encoded inside the tool**, not scattered across config files. Adding or changing a rule means updating the formatter, recorded in `docs/code-style.md`. +- **Lint and format are one step** from the contributor's perspective. There is no "run lint, then run formatter" sequence; one command covers both. + +### Codebase health contract + +Every project on this stack runs a codebase-health check that surfaces structural risk. The **implementation is the project's choice** (a Pascal program, a wrapper around external tooling, etc.) as long as it satisfies this contract: + +- **Duplication is reported** — copy-paste between units and within a single unit, above a project-defined size threshold. Output names the duplicated regions and their locations. +- **Per-function complexity is reported** using cyclomatic and cognitive complexity metrics. Functions exceeding project-defined thresholds are flagged. +- **Per-file health is reported** as a single aggregate signal contributors can sort on. +- **Hotspots are surfaced** by combining structural findings with git churn, so refactor effort lands on code that is both complex and frequently changed. +- **Non-zero exit on threshold breach.** When any project-configured threshold is violated, the check exits non-zero so CI and the pre-commit hook can enforce it. +- **Single config file at the repo root** holds the thresholds and any ignores. Tweaking the bar means editing that one file. + +The choice of implementation and the configured thresholds are recorded in the project's `docs/tooling.md` (or equivalent). The check is wired into the project's verification gate alongside the formatter and build-and-test steps. + +### Pre-commit hook (Lefthook) + +`project-structure/SKILL.md` covers the pre-commit hook contract and explains why Lefthook is the default. For a FreePascal project on this toolchain, the canonical `lefthook.yml` runs the project's format-check and a build-and-test step on staged sources: + +```yaml +pre-commit: + commands: + format-check: + glob: "*.pas" + run: {staged_files} + build-check: + run: +``` + +Replace the placeholder commands with the project's actual entry points (whatever satisfies the contracts above). Wire `lefthook install` into `docs/quick-start.md`. Do not skip hooks (`--no-verify`) unless the user explicitly asks. Verify the current Lefthook major version before pinning. + +### Repo layout + +Defer the universal patterns to `project-structure/SKILL.md` (top-level layout, docs template, AGENTS.md template with "Hard Constraints", agent-file symlinks, multi-area repos, scripts directory, changelog with git-cliff). Stack-specific conventions: + +- **Source organization: namespace-based filenames, flat by default.** All Pascal source lives under `source/` (Pascal convention; `src/` is acceptable when the project prefers it — pick one and stay consistent). Units are named `ProjectName.Namespace.UnitName.pas` (the project may use a `ProjectShortName` prefix instead) so the namespace tree is encoded in the filename. The default layout is flat: every unit sits directly under `source/`. Introduce subfolders only when a single namespace has grown enough that flat browsing is hard to manage, and keep the folder name aligned with the namespace it groups. The shared compiler-flag include and toolchain entry points live at the repo root. +- **Build artifacts** land under `build/` and are not committed. +- **Co-located unit tests** alongside the Pascal unit they cover. End-to-end test corpora (when the project has them) live under `tests/`, organized by feature. +- **Scripts: InstantFPC.** One-off scripts are written in Pascal and run via **InstantFPC** (`#!/usr/bin/env instantfpc`) so they execute directly without a separate compile step. Fall back to a `Makefile` / `Justfile` or another dynamic language only when an InstantFPC script would be heavier than the task warrants. See `project-structure/SKILL.md` for the language-of-scripts rule. + +### Rules + +- **FPC version is verified live.** Before adding or changing any code path that depends on FPC behavior, the agent confirms the version in use (`fpc -iV`) against the pin in `docs/tooling.md` or CI. Memory and prior conversation turns are not acceptable sources. +- **Project-specific tool versions are verified live.** Before touching them, the agent confirms versions of the build system, the formatter / linter, the `git-cliff` pinned by `cliff.toml`, and the Lefthook pinned by `lefthook.yml`. +- **The project's `AGENTS.md` Hard Constraints are read first** — the root file plus the area-specific `AGENTS.md` for the area being touched in a multi-area repo. +- **The project's `docs/build-system.md` (or equivalent) is the source of truth for build entry points and target list.** This skill describes the contract, not the project's specific entry point or target names. +- **The project's verification gate runs clean before handoff.** Both the format-check command and the build-and-test command exit zero. Typical shape: + +```bash + + +``` + +- **Substantive changes update the relevant `docs/` file** per the no-duplication and immutability rules in `project-structure/SKILL.md`. +- **Anything not prescribed by this skill** is governed by the project's own AGENTS.md and `docs/`. + +## Examples + +**Build system contract — same shape, different implementations:** + +| Implementation | Default build | Single target | Prod build | Clean | +| --- | --- | --- | --- | --- | +| Pascal program | `./build` | `./build mytool` | `./build --prod` | `./build clean` | +| Makefile | `make` | `make mytool` | `make MODE=prod` | `make clean` | +| Justfile | `just` | `just build mytool` | `just build --prod` | `just clean` | + +Any of these is acceptable as long as the project documents the entry point and the contract holds. + +**Pre-commit gate (after substituting placeholders):** + +```bash + + +``` diff --git a/.agents/skills/project-structure/SKILL.md b/.agents/skills/project-structure/SKILL.md new file mode 100644 index 00000000..4f1db591 --- /dev/null +++ b/.agents/skills/project-structure/SKILL.md @@ -0,0 +1,305 @@ +--- +name: project-structure +description: >- + Language-agnostic repo structure conventions used across the user's projects + in any language — the user-facing README.md structure (name, logo, + description, install, usage, optional background, contribution, references), + the docs/ template (application, architecture, code-style, + quick-start, tooling, deployment), the AGENTS.md template with a Hard + Constraints section (symlinked to CLAUDE.md), nested area AGENTS.md for + multi-area repos, optional CONTRIBUTING.md, the pre-commit hook contract + with Lefthook as the default and explicit alternatives, scripts directory in + the project's own language, co-located tests, the .agents/skills folder + symlinked to .claude/skills, and changelog generation with git-cliff. + Stack-specific tools (test runners, linters, generators) live in the + matching stack skill. Use when scaffolding or restructuring any repo, + writing AGENTS.md or docs, or laying out folders. +license: Unlicense OR MIT +--- + +# Project structure + +## Instructions + +This skill describes **layout and documentation patterns that hold regardless of language or runtime**. Stack-specific tooling (test runners, linters, generators, hook config) lives in the matching stack skill (e.g. `react-stack/SKILL.md`, `native-nostalgia-stack/SKILL.md`). + +### Top-level layout (by role, not filename) + +A repo on this style has these **roles** at the root, named with whatever convention the language community uses: + +| Role | What it holds | Examples (varies by language) | +| --- | --- | --- | +| **Agent context** | Operating manual for AI assistants. Symlinked across agent filenames. | `AGENTS.md` ↔ `CLAUDE.md` | +| **Contribution rules** | Authoritative rules for human contributors. Optional. | `CONTRIBUTING.md` | +| **Project intro** | What the project is and how to run it. | `README.md` | +| **Build / package manifest** | Dependency declaration. | `package.json`, `Cargo.toml`, `Gemfile`, `pyproject.toml`, `*.cabal`, `*.dpr` / `*.lpi`, etc. | +| **Lockfile** | One canonical lockfile for the project's PM. | Whatever the PM produces; forbid all others. | +| **Source** | Project code. | `src/`, `app/`, `lib/`, `source/`, `units/`, etc. | +| **Tests** | Co-located next to the source they cover. | `*_test.*`, `*.test.*`, language-native test units alongside the unit under test. | +| **Scripts** | One-off automation: env sync, codegen, seed, copy, generate. | `scripts/`, `bin/`, `tools/` | +| **Docs** | See the docs/ template below. | `docs/` | +| **Generator templates** (optional) | When a generator tool is in use. | `plop-templates/`, `templates/`, `_template/` | +| **Provisioned agent skills** | When the project adopts curated skill packs. Symlinked across agent paths. | `.agents/skills/` ↔ `.claude/skills/` | +| **Static assets** (when relevant) | Public files served as-is. | `public/`, `static/`, `assets/` | +| **Generated output** | Build artifacts. Not committed unless the language requires it. | `dist/`, `build/`, `target/`, `out/` | + +The **filenames** are language- and ecosystem-specific. The **roles** are constant. + +### `README.md` structure + +The root `README.md` is the **project intro for a user**, not a contributor manual. It follows this section order. Sections marked optional are left off entirely when they don't apply — **never invent content to fill a section**. + +1. **Headline.** A single top-level Markdown heading (`# Project Name`) — not an HTML `

` tag — that is the project name. +2. **Logo** — shown only if a logo asset exists in the repo. Skip the section entirely when there is none. +3. **Short description.** Max 350 characters. What the project is and what its features are. Link to in-depth documentation (`docs/`, a docs site) when it exists rather than expanding here. +4. **Install.** Max 100 characters. The single canonical install line — `npm install `, `brew install `, `cargo add `, etc. +5. **Usage.** How a **user** (not a contributor) uses the project — command-line, code, or a combination. Show the 1–3 most relevant flows and link back to deeper docs (developer flow, full API, configuration) for the rest. Do not document how to work *on* the project here. +6. **(Optional) Background.** Anything important for understanding the project's design — mission statement, philosophy, core decisions still open. Include only when it adds real understanding; leave off rather than invent. +7. **Contribution.** Max 150 characters describing how to install the project locally for development and what's required, then link to the detailed `CONTRIBUTING.md` / contributing docs when they exist. +8. **References.** Links to the agent documentation (`AGENTS.md`) and the license. + +Rules: + +- The README is **user-facing**; deep developer/build/test detail lives in `docs/` and `CONTRIBUTING.md`, linked from sections 5 and 7 — not inlined. +- Respect the character caps on sections 3, 4, and 7. When the content doesn't fit, link out instead of overflowing. +- Optional sections (logo, background) are omitted cleanly when they don't apply; do not emit an empty heading. +- Markdown linting and the link check (below) apply to `README.md` like any other committed markdown. + +### Tests + +Tests must provide regression coverage and real value. **Tests are not a checkbox exercise** — delete or rewrite tests that no longer catch regressions, and don't author trivial tests to satisfy a coverage target. + +- **End-to-end tests are the core mechanism.** They exercise the system the way it's used in production and are the primary regression net. They live in a dedicated top-level location chosen by the project and run via the project's E2E runner. +- **Unit tests cover public API surfaces** of the modules under test. They are co-located next to the module they exercise. They do not duplicate coverage that an end-to-end test already provides. +- **Layer-specific tests** (CLI invocation, HTTP integration, language interop, fuzzing, etc.) are added when that layer is a delivered artifact or a real source of regressions. They are not added by default. + +Project-specific conventions (test granularity, what counts as the public API for a given module, edge-case placement, fixture handling) live in the project's `docs/code-style.md` or `docs/testing.md`. + +### `docs/` template (filenames are universal) + +Every project ships these files in `docs/`: + +| File | Contents | +| --- | --- | +| `README.md` (optional) | Index of the docs folder. | +| `application.md` or `architecture.md` | Tech stack, key concepts, core data model, cross-cutting concerns. | +| `quick-start.md` | Install + configure + run, fast. Zero to working. | +| `tooling.md` | Development commands, environment variables, lint/format/test setup. | +| `code-style.md` | Naming, file layout, design tokens (or equivalent project conventions), import/dependency rules. | +| `deployment.md` | Build profiles, release/store submission, CI/CD, rollback. | + +Optional additions when they apply: + +- `testing-pattern.md` — when tests follow a non-obvious convention. +- `mcp.md` — when the project exposes an MCP server. +- `-mvp.md` — feature scope notes for in-flight work. +- `decision-log.md` — append-only record of decisions. +- `spikes/` — point-in-time investigation snapshots. + +**Documentation rules (apply to every project):** + +- **Every `docs/` file (except `decision-log.md` and root entry points like `README.md` / `AGENTS.md` / `CONTRIBUTING.md`) must include an `## Executive Summary`** with 3–6 bulleted key points placed after the title and any subtitle. An italic subtitle alone does not satisfy this requirement. +- **No duplication.** Each topic has one authoritative document; other docs link to it with a one-liner. +- **Spikes are snapshots.** Files under `docs/spikes/` are point-in-time records; do not update after creation. Add a decision log entry instead. +- **Decision log entries are immutable.** New decisions get new entries; existing entries are not rewritten to match later reality. Cross-links from entries to other docs may be updated when the target is renamed. + +### Agent file naming and symlinks + +Multiple AI tools expect different filenames for the same content. Maintain **one canonical file** and **symlink the others**, so the source of truth is unambiguous and edits propagate. + +- **Canonical:** `AGENTS.md` at the repo root. +- **Symlink:** `CLAUDE.md` → `AGENTS.md`. (Use a real symlink: `ln -s AGENTS.md CLAUDE.md`. A `@AGENTS.md` include line is acceptable when symlinks are not viable on the platform, but symlinks are preferred.) +- **Canonical:** `.agents/skills/` directory at the repo root. +- **Symlink:** `.claude/skills` → `.agents/skills`. + +Edit only the canonical file or directory. Never write divergent content into the symlinked path. + +### `AGENTS.md` template (universal across languages) + +The **default** is a **single** `AGENTS.md` at the repo root (with `CLAUDE.md` symlinked to it as above). Promote to richer variants only when needed. + +Required sections, in this order: + +```markdown +# Agent Instructions + +## Hard Constraints +- +- + +## Runtime / Commands + + +## Code Organization + + +## Testing + + +## Safety / Boundaries + +``` + +Optional sections (add only when they earn their token cost): + +- **Product Positioning** — what this repo is and is not. +- **Built-ins / preferred APIs** — when the language or runtime has built-ins to prefer over third-party packages. +- **MCP Boundary** — when the project exposes an MCP server. +- **Quick Reference** — short build/run/test command table. + +Variants: + +- **Nested `/AGENTS.md`** in multi-area repos. The root file points to the area files; each area file owns its rules. The nearest file wins for that area. +- **`CONTRIBUTING.md`** alongside `AGENTS.md` when humans contribute under strict rules. Treat `CONTRIBUTING.md` as authoritative for what may be merged; `AGENTS.md` is agent-only operating context. Do not duplicate content between them — link instead. + +### Pre-commit hooks + +Every project on this style has a pre-commit hook that runs the project's format/lint/fix on staged files and re-stages anything that gets autofixed. The contract: + +1. Hook fires on `git commit`. +2. It runs the project's canonical "format and fix" command on the staged set only. +3. Files modified by the autofix are re-staged so the commit reflects the fixed state. +4. If the command fails on something it cannot autofix, the commit is rejected. + +**Default tool: Lefthook.** Lefthook is the default because it is language-agnostic, declared in a single `lefthook.yml`, runs in parallel, supports per-glob commands, and re-stages autofixes via `stage_fixed: true`. The stack skill (e.g. `react-stack/SKILL.md`) holds the canonical `lefthook.yml` for that stack. + +**Alternatives are only acceptable when Lefthook cannot meet a specific need:** + +| Alternative | Pick when | +| --- | --- | +| **Husky** (Node-only) | The project is Node-only and you want hooks declared inside `package.json` rather than a separate config file. Note: this gains nothing Lefthook doesn't already provide; pick only if the team has prior Husky muscle memory and no language-mixed concerns. | +| **`pre-commit` framework** (Python) | The project's primary language is Python and the team already uses the upstream `pre-commit` ecosystem (`.pre-commit-config.yaml`) for shared hook repos. | +| **Native `.git/hooks/pre-commit`** | The project must avoid adding any toolchain just for hooks (single-language, single-binary repos with strict zero-extra-deps rules). | + +For each deviation, record the reason in the PR introducing the alternative. Do not skip hooks (`--no-verify` and equivalents) unless the user explicitly asks. + +### Scripts directory + +`scripts/` (or the language's equivalent) holds **one-off automation** that's not part of the build: env sync, secrets pull, seed data, codegen, asset copy, release notes generation, mock data generation. + +**Language of the scripts follows the project's own constraints**, not a generic preference. Pick from these in order of preference for the host project: + +1. **The project's primary language** when it can run scripts directly (TypeScript scripts in a TypeScript project run by the project's runtime; Python scripts in a Python project; Ruby scripts in a Ruby project). +2. **A `Makefile` / `Justfile` / `Taskfile`** when the project's primary language is compiled and recompiling for one-off work is heavy. +3. **A different dynamic language** (typically Python or Ruby) when the project's primary language cannot run direct scripts and the team accepts a second runtime locally — common in compiled-native projects. + +Rules that apply regardless of language: + +- One file per task. +- Each script is invokable directly with the language's runner. +- Each script is also wired into the project's manifest under a stable name (`package.json` `scripts:`, `Makefile` target, `taskfile`, `justfile`, etc.) so contributors don't need to remember the path. +- Exit non-zero on failure. Print actionable error context. +- Do not commit secrets, generated data, or large fixtures into the script files themselves. + +Promote a script to part of the build pipeline only when more than one workflow depends on its output. + +### `.agents/skills/` and `skills-lock.json` + +`.agents/skills/` materialises curated agent skill packs into the repo. `skills-lock.json`, when present, is **output produced by the agent-skills CLI / sync command** — it is not authored by hand and not a project pattern to invent. + +- Treat `.agents/skills//SKILL.md` and `skills-lock.json` as **generated**. +- Symlink `.claude/skills` → `.agents/skills` so Claude tooling sees the same materialised content. +- Do not hand-edit either path; run the skills tool to add, update, or remove a skill. +- This whole pattern is **opt-in** — not every project needs curated skill packs. + +### Changelog (git-cliff) + +Generate the changelog from conventional commits with **git-cliff**. + +- `cliff.toml` at the repo root configures sections, commit-type mapping, and the template. +- Adopt conventional commit messages so types map cleanly to changelog sections (`feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `build`, `ci`, `style`, `revert`). +- Verify the current `git-cliff` version before running. +- `git-cliff --tag ` produces the release notes; do not hand-edit them. If wording is wrong, edit the conventional commit and regenerate. + +git-cliff is the default because it is language-agnostic, single-binary, reads commit history directly, and uses one declarative config file. **Alternatives are only acceptable when git-cliff cannot meet a specific need:** + +| Alternative | Pick when | +| --- | --- | +| **release-please** (Google) | The project lives in a polyrepo of similar npm packages and relies on automated PR-based release flows tied to GitHub. | +| **conventional-changelog / standard-version** | The project is Node-only, cannot add a non-npm binary, and the team accepts the older toolchain. | +| **Hand-written `CHANGELOG.md`** | The project is small enough that the cost of automating exceeds the benefit, and the team commits to keeping the file by hand. | + +For each deviation, record the reason in the PR introducing the alternative. + +### Markdown linting (markdownlint) + +Lint all committed markdown — `README.md`, `AGENTS.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, everything under `docs/` — so structure, links, headings, and code-fence usage stay consistent across the repo. + +**Default tool: markdownlint** (typically via `markdownlint-cli2`), configured by a single `.markdownlint.json` / `.markdownlint-cli2.yaml` at the repo root. Wire it into the project's verification gate and into the Lefthook pre-commit hook for staged `.md` files. + +markdownlint is the default because it is the de-facto standard for markdown linting, has a stable preset of structural rules, and integrates cleanly with Lefthook. **Alternatives are only acceptable when markdownlint cannot meet a specific need:** + +| Alternative | Pick when | +| --- | --- | +| **`vale`** (alongside or instead of markdownlint) | The project also needs prose-quality linting (style guide, sentence-level checks). `vale` is for prose, not markdown structure; use it as a complement when prose quality matters, or as the sole linter when the project's docs are prose-heavy and structure matters less. | +| **`remark-lint`** | The project is Node-only, already uses the unified/remark ecosystem, and wants plugin-based markdown processing. | + +For each deviation, record the reason in the PR introducing the alternative. + +### Duplication check contract + +Every project on this style runs a duplication check that surfaces copy-paste across the codebase. The **implementation is the project's choice** (a multi-language tool, a language-specific analyzer, a wrapper around an existing codebase-health tool, etc.) as long as it satisfies this contract: + +- **Reports duplication** above a project-defined size threshold — both within a single file and across files. +- **Output names the duplicated regions and their locations** so the regions can be merged or extracted. +- **Configurable thresholds and ignores** live in a single project-owned config file at the repo root. +- **Non-zero exit on threshold breach** so CI and the pre-commit hook can enforce it. + +The choice of implementation and the configured thresholds are recorded in the project's `docs/tooling.md` (or equivalent). The check is wired into the project's verification gate. + +### Link check contract + +Every project on this style runs a link check on its markdown content and any other documentation surface. The **implementation is the project's choice** (a markdown-specific link checker, a generic HTTP link checker, a wrapper, etc.) as long as it satisfies this contract: + +- **Verifies every link** in committed markdown — internal anchors, relative paths, and external URLs. +- **Differentiates internal and external links** so an internal-only mode can run offline / fast in CI, separate from a slower full-network mode. +- **Configurable allowlist** for known-broken or intentionally-unstable external links, recorded in a single project-owned config file at the repo root. +- **Non-zero exit when any link in scope is broken** so CI can enforce it. + +The choice of implementation, the network-mode policy, and the allowlist are recorded in the project's `docs/tooling.md` (or equivalent). The check is wired into the project's verification gate. + +### Architectural drift check contract + +Every project on this style runs a drift check that detects mismatches between **what the project's documentation claims** and **what the code, manifest, and tooling actually do**, and outputs each mismatch as an actionable finding. This is the project's authoritative answer to "does the implementation still match the architecture and ways of working we wrote down?" + +The **implementation is the project's choice** (a dependency analyzer, a docs-vs-code crawler, a wrapper around an existing drift / codebase-intelligence tool, a custom script, etc.) as long as it satisfies this contract. + +**Surfaces in scope (the check covers all of them):** + +- **Layering / module boundaries.** The architecture documented in `docs/architecture.md` (or equivalent) — which modules or layers may depend on which — vs. the actual import / dependency graph. +- **Hard Constraints.** The forbiddens declared in `AGENTS.md` (e.g. package-manager restrictions, AI lane restrictions, language restrictions) vs. what the manifest, lockfile, and source actually contain or allow. +- **Setup, run, test, and build commands.** The commands documented in `docs/quick-start.md` / `docs/tooling.md` / `docs/build-system.md` vs. the commands actually defined in the project's runner, manifest, or build entry point. Stale or missing commands are findings. +- **Ways of working.** Conventions documented in `docs/code-style.md` (naming patterns, file layout, export policy, import ordering, etc.) vs. the actual codebase. +- **Dependency declarations.** Tools and libraries documented as "in use" vs. the actual manifest and lockfile. Undocumented dependencies and documented-but-absent dependencies are both findings. +- **Environment and configuration documentation.** Variables and config keys documented in `docs/tooling.md` / `.env.example` vs. what the code actually reads. Gaps in either direction are findings. + +**Output requirements:** + +- **Each finding names the documented claim, the code reality, and the file locations involved** (with line numbers where applicable) so the source of truth is unambiguous. +- **Each finding indicates the resolution direction** when determinable: update the docs to match the code, update the code to match the docs, or update the rule itself. +- **Findings are grouped by surface** (layering, hard constraints, commands, ways of working, dependencies, environment) so reviewers can triage. +- **Configurable allowlist** for findings that are intentional mismatches, recorded in a single project-owned config file at the repo root. Each allowlist entry carries a comment justifying it. +- **Non-zero exit on any unallowed drift** so CI and the pre-commit hook can enforce it. + +The choice of implementation, the configured surfaces, and the allowlist live alongside the architecture docs (typically `docs/architecture.md`) and `docs/tooling.md`. The check is wired into the project's verification gate. + +This contract is **opt-out** only for projects with effectively no documentation surface (single-file scripts, throwaway tools). Every project that ships a `docs/` folder adopts the contract from the start. + +### Multi-area repos + +When a repo holds multiple deliverables (a web app, mock data tooling, a prototype, a CLI, etc.): + +- Root `README.md` and root `AGENTS.md` cover the whole repo and point to area docs. +- Each area has its own subfolder with a local `README.md` and a local `AGENTS.md` if its rules differ from the root. +- The root `AGENTS.md` should explicitly say "scope your changes to the right area" and list the areas. +- Area-specific docs live under `docs//` or under the area folder itself; pick one and stay consistent. + +## Examples + +**Minimal repo (single language, small project):** `AGENTS.md` (Hard Constraints + Commands + Code Organization), `CLAUDE.md` symlinked to `AGENTS.md`, `README.md`, `docs/quick-start.md`, a manifest, a lockfile, a Lefthook pre-commit, and a `check` / `format` / `test` command set. + +**Multi-area repo:** Root `AGENTS.md` (constraints common to the whole repo + table of areas), nested `/AGENTS.md` for each area, `docs/` at the root for cross-cutting docs, `docs//` for area-specific docs. + +**Strict-rules project with human contributors:** `CONTRIBUTING.md` (authoritative for merge requirements), `AGENTS.md` short and agent-only with a link to `CONTRIBUTING.md` for the rules, plus the standard `docs/` template. + +**Compiled-native project:** Source under the project's chosen single root (`source/` or `src/`) using the stack's source-organization rule, native unit tests co-located with the unit they cover, end-to-end suites in the project's chosen top-level E2E location. diff --git a/.agents/skills/review-pr/SKILL.md b/.agents/skills/review-pr/SKILL.md index b8732861..4de446a3 100644 --- a/.agents/skills/review-pr/SKILL.md +++ b/.agents/skills/review-pr/SKILL.md @@ -1,26 +1,61 @@ --- name: review-pr -description: Resolve review comments on the current GocciaScript pull request without posting top-level PR comments. Use when the user enters /review-pr. +description: >- + Resolves outstanding review comments on the current pull request by replying + in-thread and pushing fixes in any GitHub repository, without leaving new + top-level PR or issue comments. Prefers the /resolve-reviews skill when it is + available and falls back to a standalone workflow otherwise. Use when the + user runs /review-pr. +license: Unlicense OR MIT +compatibility: >- + Requires the GitHub CLI (gh) authenticated to the target repository and + network access. --- # Review PR -Resolve review comments on the current PR by following `.agents/skills/resolve-reviews/SKILL.md`, with these project-specific overrides. +## Instructions -## Rules +Resolve review comments on the current pull request. -- Do not leave top-level PR comments, PR review summaries, or issue comments. -- Replies to existing review comments or review threads are allowed when needed to resolve those comments. -- Keep the final summary in chat unless the user explicitly asks to post it to GitHub. -- Preserve unrelated work in the working tree. Do not revert changes you did not make. -- Run relevant verification before committing review fixes. -- **Merge the `main` baseline** before starting review work if the branch is behind `origin/main`: +### Prefer `/resolve-reviews` when available -```bash -git fetch origin main -git merge origin/main --no-edit -``` +If a `resolve-reviews` skill (or `/resolve-reviews` command) is available in this environment, **prefer it** for the per-thread resolution workflow. - If the merge has conflicts, resolve them and commit the merge before addressing review comments. +- Delegate per-thread resolution mechanics (listing threads, navigating to comment locations, replying inline, marking threads resolved) to `/resolve-reviews`. +- **The Rules section in this skill always applies, even when `/resolve-reviews` is driving.** Rules are non-negotiable overrides — if `/resolve-reviews`'s default behavior would conflict with a rule (e.g. posting a top-level summary comment, force-pushing, reverting unrelated changes), follow the rule, not `/resolve-reviews`. +- The **Steps** below are the standalone fallback. Use them only when `/resolve-reviews` is not available. -Avoid commands that create top-level comments, including `gh pr comment`, REST issue comment endpoints, or a review body that is not tied to an existing thread. +To check availability, look for a skill or command named `resolve-reviews` (e.g. `~/.cursor/skills/resolve-reviews/`, `.cursor/skills/resolve-reviews/`, or `.agents/skills/resolve-reviews/`). If none is registered, run the standalone workflow below. + +### Rules + +- No new top-level PR comments, PR review summaries, or issue comments. Replies to existing review threads are allowed when they help resolve a thread. +- Keep the final summary in chat. Only post it to GitHub if the user explicitly asks. +- Preserve unrelated work in the tree. Never revert changes you did not author. +- Run relevant verification before committing fixes. +- Avoid commands that create top-level comments: `gh pr comment`, REST issue-comment endpoints, or any review body not tied to an existing thread. + +### Steps + +1. Confirm the current branch has an open PR: + + ```bash + gh pr view --json url,number,title,reviewDecision + ``` + +2. Merge the remote default baseline if the branch is behind: + + ```bash + BASE_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name') + git fetch origin "$BASE_BRANCH" + git merge "origin/$BASE_BRANCH" --no-edit + ``` + + Resolve conflicts and commit the merge before addressing reviews. + +3. List unresolved review threads and inline comments. Address each one in code where it requires a code change. +4. When a thread needs acknowledgement, clarification, or a follow-up question, reply **inline on the originating thread** — never via a new top-level comment. +5. Run relevant verification: typecheck, lint, tests, and targeted UI checks (visual, accessibility, responsive, theme) for user-facing changes. +6. Invoke the `/update-pr` skill to commit and push the review fixes. Do not run commit/push commands directly — `/update-pr` enforces the no-amend, no-force-push, baseline-merge, and PR title/body reconciliation rules. If the `/update-pr` skill is not invokable in this environment (not registered, not available as a command), follow the rules and steps documented in the `update-pr` skill manually to commit and push. +7. Report in chat: the threads addressed, the commits pushed, verification run, and the PR URL. diff --git a/.agents/skills/update-pr/SKILL.md b/.agents/skills/update-pr/SKILL.md index 0e684560..50e90412 100644 --- a/.agents/skills/update-pr/SKILL.md +++ b/.agents/skills/update-pr/SKILL.md @@ -1,50 +1,61 @@ --- name: update-pr -description: Commit relevant local changes and push them to the current GocciaScript pull request branch. Use when the user enters /update-pr. +description: >- + Commits relevant local changes, merges origin/main when the branch is behind, + pushes to the current PR branch, and refreshes PR title/body when stale. Use + when the user runs /update-pr or asks to update a pull request with the latest + commits. +license: Unlicense OR MIT +compatibility: >- + Requires git and the GitHub CLI (gh) authenticated to the target repository, + plus network access. --- # Update PR -This command is explicit permission to commit relevant changes and push them to the current PR branch. +## Instructions -## Rules +This workflow is explicit permission to commit relevant changes and push to the current PR branch. + +### Rules - **Never amend commits.** Always create new commits. - **Never force push.** Use `git push` without `--force` or `--force-with-lease`. -## Steps +### Steps -1. Inspect the repository state: +1. Inspect repository state: - `git status --short --branch` - `git diff` - `git diff --staged` - `git log --oneline -5` -2. Confirm the current branch is not `main`. If it is `main`, stop and ask for the intended PR branch. -3. Confirm the branch has an associated PR with `gh pr view`. If there is no PR, ask whether to run `/create-pr` instead. -4. **Merge the `main` baseline** if the branch is behind `origin/main`: - -```bash -git fetch origin main -git merge origin/main --no-edit -``` - - If the merge has conflicts, resolve them and commit the merge before continuing. -5. Confirm there are changes to commit. If there are none (beyond the merge), skip to step 7. -6. Stage only relevant files. Exclude secrets and unrelated user changes. -7. Commit with a concise message passed via HEREDOC. -8. Push the branch, setting upstream tracking if needed: - -```bash -git push -u origin HEAD -``` - -9. Review the current PR title and body against the latest implementation: - - Read `.github/pull_request_template.md`, or the relevant template under `.github/PULL_REQUEST_TEMPLATE/` if the repository uses multiple templates. - - Fetch the PR body with `gh pr view --json body,url,title`. - - Compare the title, Summary, Testing, linked issues, and any scope notes with the actual commits and verification just performed. - - If the title is stale, too narrow, or no longer matches the implementation, update it with `gh pr edit --title "$PR_TITLE"`. - - If the body is stale, incomplete, or no longer matches the implementation, update it with `gh pr edit --body-file `. - - Preserve the repository pull request template structure and avoid removing useful reviewer context. -10. Report the commit hash, pushed branch, PR URL, whether the PR title or body was updated, and verification performed. - -Do not skip git hooks or verification unless the user explicitly asks. +2. If the current branch is `main`, stop and ask for the intended PR branch. +3. Confirm an open PR exists: `gh pr view`. If none, ask whether to run `/create-pr` instead. +4. If the branch is behind `origin/main`, merge baseline: + + ```bash + git fetch origin main + git merge origin/main --no-edit + ``` + + Resolve conflicts and commit the merge if needed before continuing. + +5. If there is nothing new to commit (aside from an already-finished merge), skip to step 8. +6. Stage only relevant files. Exclude secrets and unrelated local changes. +7. Commit with a concise message via HEREDOC. +8. Push (set upstream if needed): + + ```bash + git push -u origin HEAD + ``` + +9. Reconcile PR title and body with the latest implementation: + - Read `.github/pull_request_template.md` or `.github/PULL_REQUEST_TEMPLATE/` if present. + - `gh pr view --json body,url,title` + - Align title, Summary, Testing, linked issues, and scope with commits and verification. + - Update title: `gh pr edit --title "$PR_TITLE"` when stale. + - Update body: `gh pr edit --body-file ` when stale. Keep template structure and reviewer context. + +10. Report: commit hash, branch, PR URL, whether title/body changed, and verification performed. + +Do not skip git hooks or verification unless the user explicitly requests it. diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 8b8af231..8ff3a79c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -928,3 +928,4 @@ jobs: run: | echo "::error::test262 regression detected vs cached main baseline. See the PR comment for per-test deltas." exit 1 + diff --git a/skills-lock.json b/skills-lock.json index 8bb0bed8..2e9f1dcc 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -1,6 +1,18 @@ { "version": 1, "skills": { + "create-issue": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "create-issue/SKILL.md", + "computedHash": "327eb529723ac979773cc31e1d7cd411c31ddece715f6299009fcb543568111b" + }, + "create-pr": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "create-pr/SKILL.md", + "computedHash": "f1492d9b535190e046327563ef8f391d51bea7d30c610cd504d1aac2996ec0ee" + }, "documentation-writer": { "source": "github/awesome-copilot", "sourceType": "github", @@ -11,6 +23,12 @@ "sourceType": "github", "computedHash": "9e1c8b3103f92fa8092568a44fe64858de7c5c9dc65ce4bea8f168080e889cfd" }, + "git-workflow": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "git-workflow/SKILL.md", + "computedHash": "23f328d4cca106d571aa88e079c96c7a73f90fdb9b02ea8ad1a61fde0de0383d" + }, "grill-with-docs": { "source": "mattpocock/skills", "sourceType": "github", @@ -23,16 +41,52 @@ "skillPath": "skills/productivity/handoff/SKILL.md", "computedHash": "1a78d774f8a59db5daa6e65e20a6596872fa8cde769f9a6e3a09b678dd5ae8cc" }, + "implement-idea": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "implement-idea/SKILL.md", + "computedHash": "4d20d696d000d8f82e0e7a5efb7ddc0ba682597173f6291f323069d8b68f54da" + }, + "implement-issue": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "implement-issue/SKILL.md", + "computedHash": "51927cbc8b1b4768c63c2803e969502f4125acfb92517660ad41aef8555074aa" + }, "improve-codebase-architecture": { "source": "mattpocock/skills", "sourceType": "github", "skillPath": "skills/engineering/improve-codebase-architecture/SKILL.md", "computedHash": "ef32aea0a8fab9b365ff9e08a95f8d353e20ca21ea46ec2e73587c86dd341351" }, + "native-nostalgia-stack": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "native-nostalgia-stack/SKILL.md", + "computedHash": "ac1b3dbbaf7a40323cc9301d25fdc2d91e5cc6c734d80eab3e87fd941d7f6cc2" + }, + "project-structure": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "project-structure/SKILL.md", + "computedHash": "b7727a378c0dccbddd7e0aacbf828b4ee53b38d8a039b1739cefa920ba0c445b" + }, "resolve-reviews": { "source": "pbakaus/agent-reviews", "sourceType": "github", "computedHash": "bc9d5432eae35775eefda3eeb944b5e7e899954ede190213edb67c9154267e07" + }, + "review-pr": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "review-pr/SKILL.md", + "computedHash": "7e7f3768689d5ab488e3b56c8ca204e4af4d0a967cbda933cb451ff091a699f3" + }, + "update-pr": { + "source": "frostney/known-good-route", + "sourceType": "github", + "skillPath": "update-pr/SKILL.md", + "computedHash": "ba8aaa2b169742cdb89ecf3e7b16b3f7fc49acea01fc0b2581193350c1e81b77" } } }