Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions .agents/skills/issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
---
name: issue
description: Create GitHub issues with repo conventions, issue templates, audience control (internal/community), and issue type assignment. Also switches existing issues between internal and community. Use when user says "create an issue", "file a bug", "open an issue", "make this community", "switch issue to internal", or wants to create or manage issues.
---

# issue

Create issues or switch the audience of existing issues, respecting repo conventions.

## Prerequisites

- `gh` CLI installed and authenticated. If missing, stop and tell the user.

## Modes

Detect mode from user input:

- **Create** — no existing issue number referenced. Default mode.
- **Switch** — an existing issue number is referenced with an audience change intent (e.g., "make #42 community", "switch #42 to internal").

---

## Create Mode

### 1. Read repo conventions

Read these files in order, skipping any that don't exist:

1. **`docs/agents/issue-tracker.md`** — determines which tracker and CLI to use. If missing, assume GitHub + `gh`.
2. **`docs/agents/issue-audience.md`** — audience labels and footers. If missing, offer to set it up (see [Setup Flow](#setup-flow)).
3. **`docs/agents/triage-labels.md`** — triage label vocabulary. If missing, skip triage labels entirely.
4. **`GLOSSARY.md`** — domain glossary for terminology. Use canonical terms in issue title and body.
5. **`.github/ISSUE_TEMPLATE/`** — parse frontmatter `type:` field from each template to determine available issue types. If no templates exist, fall back to: Bug, Feature, Task.

### 2. Gather context

If conversation context exists (e.g., from a prior /grill-with-docs, /triage, or discussion), draft the issue from that context. Otherwise, ask the user to describe the issue.

### 3. Explore the codebase

Scale exploration depth to the issue type:

- **Task** — minimal. Skim relevant files to confirm terminology and add a sentence of context.
- **Bug / Spike** — moderate. Trace the relevant code path, check recent git history in the area, note related files or modules.
- **Feature / Epic** — light touch only. These are expected to go through /to-prd and /grill-with-docs for full scoping. Add enough context to orient a reader, not to scope the work.

Use findings to enrich the issue body with technical context the user didn't provide. Use domain glossary terms from `GLOSSARY.md`.

### 4. Determine issue type

If the type is obvious from context, confirm it with the user. Otherwise, present the available types (derived from templates) and ask.

**Important:** The issue type (Bug, Feature, Task, etc.) is NOT a label. It is set at creation time with `gh issue create --type <name>` (see step 11). Do not add the issue type as a label. When the user says "create a bug issue" or "file a bug", interpret "bug" as the issue type, not a label to apply.

### 5. Check available labels

Fetch the repo's label list:
```bash
gh label list --limit 100
```

Select labels that are relevant to the issue based on the content, area of code, or category. Do NOT apply the issue type as a label (see step 4). Only apply labels that actually exist in the repo.

### 6. Search for related issues

Search open issues that might be related:
```bash
gh issue list --state open --search "<relevant keywords>"
```

If related issues exist, mention them in the draft body under a "Related Issues" section (e.g., `Related: #123, #456`). If a duplicate is found, flag it to the user before drafting.

### 7. Ask about audience

Always ask explicitly:

> Is this issue internal (core team only) or open for community contribution? (default: internal)

Never assume. Apply the label and footer from `docs/agents/issue-audience.md` based on the answer.

### 8. Ask about parent issue

If the user mentioned a parent issue, link it. Do NOT prompt for a parent — only pick it up if volunteered.

### 9. Draft the issue

Compose the issue using the corresponding issue template (if one exists for the chosen type). Fill in template sections from gathered context. Add:

- The correct audience footer, wrapped in `<audience-footer>` tags. GitHub does not render unknown HTML elements, so they act as invisible markers:
```
<audience-footer>

> [!IMPORTANT]
> Footer text here.

</audience-footer>
```

**Redaction rules** — never include in title or body:
- Security vulnerabilities, CVEs, CWEs, or attack vectors
- Secrets, API keys, tokens
- PII

If an `issue-internal` skill is available, invoke it now, before the preview in step 10, so the draft the user reviews has already been screened.

### 10. Preview and confirm

Show the user the full draft:
- Title
- Type
- Labels (audience + triage if applicable)
- Parent issue (if any)
- Body (rendered)

Wait for explicit approval. If the user requests edits, apply them and re-preview.

### 11. Publish

Create the issue in one command, setting the type, parent, and any dependencies as flags (requires `gh` 2.94.0+):

```bash
gh issue create --title "<title>" --body "<body>" --label "<labels>" --type "<type>" \
--parent <parent-number-or-url> \
--blocked-by <numbers> --blocking <numbers>
```

`--type` sets the issue type, `--parent` links it as a sub-issue, and `--blocked-by`/`--blocking` mark dependencies (comma-separated numbers or URLs). Omit any flag you don't need.

If the triage system is present and the issue type has a default triage state, apply the triage label.

Print the issue URL when done.

---

## Switch Mode

Switch an existing issue's audience between internal and community.

### 1. Read conventions

Read `docs/agents/issue-audience.md`. If missing, offer to set it up.

### 2. Determine current audience

Check the issue's labels for the internal label defined in `issue-audience.md`.

### 3. Confirm the switch

Tell the user the current audience and ask to confirm the target:
> Issue #42 is currently **internal**. Switch to **community**?

### 4. Update the footer

Replace the footer in the issue body using this priority:

1. **`<audience-footer>` tags** — if `<audience-footer>` and `</audience-footer>` exist, replace content between them.
2. **Legacy HTML comment markers** — if `<!-- audience-footer-start -->` and `<!-- audience-footer-end -->` exist, replace the entire block (including markers) with the new `<audience-footer>` format.
3. **Known footer text** — if the current footer text (from `issue-audience.md`) is found in the body, replace it and wrap with `<audience-footer>` tags.
4. **Append** — if neither is found, append the new footer wrapped in `<audience-footer>` tags.

### 5. Update labels

**Switching to internal:**
- Add the internal label
- Remove any signal labels defined in the community section of `issue-audience.md`

**Switching to community:**
- Remove the internal label
- Add the primary signal label defined in the community section of `issue-audience.md`

### 6. Apply changes

```bash
gh issue edit <number> --body "<updated body>" --add-label "<label>" --remove-label "<label>"
```

Print the issue URL when done.

---

## Setup Flow

When `docs/agents/issue-audience.md` is missing, offer to create it with these defaults:

```markdown
# Issue Audience

How issues in this repo are marked for internal team use vs. open community contribution.

## Internal

- **Label:** `internal`
- **Footer:**

> [!IMPORTANT]
> Internal only — this issue is maintained by the core team and is not accepting external contributions.

## Community

- **Signal labels:** `help-wanted`
- **Footer:**

> [!IMPORTANT]
> If you are interested in working on this issue, please leave a comment.

> [!TIP]
> Please use a 👍 reaction to provide a +1/vote. This helps the community and maintainers prioritize this request.
```

Present these defaults and ask: "Does this look right for your repo, or do you want to change any of the labels or footer text?"

Apply edits, then write the file and continue with the original task.
4 changes: 3 additions & 1 deletion .agents/skills/pr/CREDITS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Credits

The **Summary** section's menu of visuals (pseudocode, call trees, component trees, file trees, Mermaid, diffs) and its placement guidance come from [Dex Horthy](https://github.com/dexhorthy)'s [`show-me`](https://github.com/humanlayer/humanlayer) skill, reproduced almost word for word and aimed at a diff instead of a live conversation. `pr` does not depend on `show-me` as a skill (it isn't part of this repo, and a hard dependency would break standalone installs), so the content is copied in rather than pointed at; this file is the attribution a dependency would otherwise have carried.
The template, its section guidance, and the layout of this skill come from [Matt Pocock](https://github.com/mattpocock)'s [`pr`](https://github.com/mattpocock/skills/blob/main/skills/engineering/pr/SKILL.md) skill, extended here with a publish workflow, related-issue linking, and language screening.

The **Summary** section's menu of visuals (pseudocode, call trees, component trees, file trees, Mermaid, diffs) and its placement guidance come from [Dex Horthy](https://github.com/dexhorthy)'s [`show-me`](https://github.com/humanlayer/humanlayer) skill, by way of Matt's, reproduced almost word for word and aimed at a diff instead of a live conversation. `pr` does not depend on `show-me` as a skill (it isn't part of this repo, and a hard dependency would break standalone installs), so the content is copied in rather than pointed at; this file is the attribution a dependency would otherwise have carried.
111 changes: 99 additions & 12 deletions .agents/skills/pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,42 @@ Use this template for writing the PR body:
```markdown
## Summary

<one sentence on why>

<diagram, diff-sketch, or tree>

## Evidence

- **Before:** <screenshot/output/failing test run>
**After:** <screenshot/output/passing test run>
**Before:** <one line on the old behavior, or the failing test>
**After:** <screenshot, video, or passing test>

**Verified live:** <what was exercised, against what>

## Merge Danger

**Door:** <one-way or two-way>

<optional: description>

**Blast Radius:** <one-word description>
**Impact:** <one-word description>

<optional: potential ramifications of merge>

## Related

- Closes #123
- Related to #456
```

## Sections

Skip all preambles and keep prose brief. Use the user's domain language from `GLOSSARY.md`.
Skip all preambles and keep prose brief. Use the domain language from `GLOSSARY.md` when present. Scale depth to diff size: a 3-line fix gets a sentence and a danger line, a 20-file feature gets the full set. Describe the **final diff** against the target branch, not the commit-by-commit journey.

### Summary

Pick the smallest view that makes the key point clear.
Open with one sentence on why: the problem or goal. If the session context cannot explain why, pause and ask the user.

Then pick the smallest view that makes the key point clear.

- Show logic or an algorithm as pseudocode:

Expand Down Expand Up @@ -140,7 +151,7 @@ For a state or control-flow change:
+ invalidate cache
```

- Show the whole block when most of it is new, when omitted context would hide ownership or order, or when the user needs a copyable target shape:
- Show the whole block when most of it is new, when omitted context would hide ownership or order, or when the reader needs a copyable target shape:

```ts
function expandSkill(command: string): string {
Expand All @@ -151,20 +162,96 @@ function expandSkill(command: string): string {

#### Guidance

Place each visual next to the short text it supports. Keep only the calls, files, props, states, and boundaries needed to answer the user's current question or the options to resolve the current discussion point.
Place each visual next to the short text it supports. Keep only the calls, files, props, states, and boundaries a reviewer needs to follow the change.

You may use one of these, you may use several, it is unlikely you will use all of them. Use your judgement and don't overwhelm the user.
You may use one of these, you may use several, it is unlikely you will use all of them. Use your judgement and don't overwhelm the reader.

### Evidence

Concrete evidence that the change works. Show a before and after.
Concrete evidence that this change works. Before is one line on the old behavior.

Screenshots are S-tier - when the environment is set up for it and the change is visual.
- **Screenshots are S-tier.** When the diff changes anything a user can see in the UI, including behavior that shows through the UI, the After is a screenshot, or a video when the point is an interaction or motion. Done when every UI-visible change has an After. Capture them with the session's browser tooling; when there is none, ask the user for the files. See [references/evidence.md](references/evidence.md) for attaching them.
- **Execution-based evidence is A-tier.** Show the exact test that failed before and passes now, using pseudocode, or the console output that changed.
- **Verified live**: when this session exercised the change by hand, such as clicking through it in a browser or running it against a real database or service, name what was exercised and against what. Omit the line when nothing ran live.

Execution-based evidence is A-tier. Test results, console output. Show the exact test that now fails and passes, using pseudocode.
Evidence is specific to this change. CI reports the suite, lint, and typecheck.

Omit the section when there is nothing observable to show, such as docs or a pure refactor.

### Merge Danger

Describe whether it's a one-way or two-way door. You can walk back through two-way doors, but not one-way doors. A PR that is cheap to roll back is lower risk. Changes that involve destructive actions or hard-to-reverse decisions are one-way doors.

The blast radius is the potential impact or scope of the changes introduced by this PR. Consider all possibilities. Examples are layout shift, breakages for consumers, mobile responsiveness, etc.
The impact is the potential scope of the changes introduced by this PR. Consider all possibilities. Examples are layout shift, breakage for consumers, data or migration impact, mobile responsiveness. Add a line of ramifications only when they are not obvious.

### Related

The classified issues from step 3 as a bulleted list, required for GitHub's title expansion. Omit the section when there are none.

### Redaction

Never mention these in the title or body, Merge Danger included:

- Security fixes, CVEs, CWEs, or how an issue is triggered. Frame impact as consumer breakage, data or migration impact, or rollback cost.
- Secrets, API keys, tokens.
- PII (personally identifiable information): names of real users, email addresses, phone numbers, physical addresses, IP addresses, account IDs, or any data that could identify a specific person.

## Workflow

Requires the `gh` CLI, installed and authenticated. If missing, stop and tell the user.

### 1. Pre-flight checks

1. **Target branch**: `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`. Refuse if the current branch is the target branch.
2. **Uncommitted changes**: Run `git status --porcelain`. If dirty, show the user what's uncommitted and ask whether to commit or abort.
3. **Remote**: Use the branch's upstream tracking remote if set, otherwise default to `origin`.
4. **Branch name**: when `/language-rules` is available, screen the branch name with it now. The name goes public the moment step 2 runs and stays in the remote's reflog and in any notification sent after a delete. Rename with `git branch -m <new-name>` when it needs one. When an earlier run already pushed the flagged name, say so and let the user choose: delete the remote branch and push the new name, or accept that the old one stays.

### 2. Push

Push the branch to the remote. Use `git push -u <remote> HEAD`.

### 3. Search backlog for related issues

Determine the tracker from `docs/agents/issue-tracker.md` if present; otherwise use whatever issue tooling is available (e.g., `gh`, an MCP server).

Gather issue references from two sources:

1. **Explicit references** — scan commit messages and branch name for issue references (e.g., `#<number>`).
2. **Backlog search** — extract 2–4 keywords from the diff (changed module names, feature area, error being fixed) and search open issues. Run multiple searches if the diff spans unrelated areas. Include recently closed issues if the diff is a follow-up fix.

**Completion criterion**: every issue that a reviewer would say "this is related" has been found. Err toward inclusion — a spurious "Related to" link is cheap; a missing "Closes" leaves an issue open.

Classify each found issue:
- **Closes** — this PR fully resolves the issue.
- **Related to** — the PR touches the same area or partially addresses it.

Discard issues that share only surface keywords but describe unrelated work.

### 4. Write the PR

**Title**: Generate from the diff — concise, imperative mood. Apply a conventional prefix only when `CONTRIBUTING.md` or recent merged PR titles use one.

**Body**: the template above. Capture every screenshot and video now, saved outside the repo, since they upload in step 6.

### 5. Screen

When `/language-rules` is available, apply it to the title, body, and every screenshot and video. These are written from session context, so a ticket id, a doc name, or a system name can reach them without ever appearing in the code. The why sentence and the Related lines are the likeliest places.

- Rewrite replaceable terms on the spot.
- A term quoted from the diff stays, since the text describes code that already carries it. Name it once as separate diff cleanup and keep publishing.
- When a reference is load-bearing and has no public form, show the user the sentence and ask.
- Open each screenshot, and the screens each video passes through, and check the browser chrome and page content for hostnames, account ids, aliases, and ticket ids. Retake or crop rather than attach.

Show the final title and body, separated from your own text by horizontal rules, with any screening changes called out in one line.

### 6. Publish

Create the PR once, open for review, with the final body. Screenshots and video upload in this same call with `--attach`.

```bash
gh pr create --title "<title>" --body "<body>" --base <target-branch> \
--attach './after.png#After'
```

No labels, reviewers, or assignees. Print the PR URL when done.
3 changes: 0 additions & 3 deletions .agents/skills/pr/agents/openai.yaml

This file was deleted.

Loading
Loading