@jesdi/skills 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -3
- package/package.json +1 -1
- package/skills/backlog/SKILL.md +12 -6
- package/skills/backlog/references/graphql.md +2 -1
- package/skills/prototype/LICENSE +21 -0
- package/skills/prototype/LOGIC.md +67 -0
- package/skills/prototype/SKILL.md +39 -0
- package/skills/prototype/UI.md +99 -0
- package/skills/to-spec/LICENSE +21 -0
- package/skills/to-spec/SKILL.md +119 -0
- package/skills/to-tickets/LICENSE +21 -0
- package/skills/to-tickets/SKILL.md +95 -0
- package/skills/wizard/LICENSE +21 -0
- package/skills/wizard/SKILL.md +65 -0
- package/skills/wizard/template.sh +229 -0
- package/skills-manifest.json +27 -3
package/README.md
CHANGED
|
@@ -20,6 +20,24 @@ directory.
|
|
|
20
20
|
npx @jesdi/skills-cli sync
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
It looks like this:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"schemaVersion": 1,
|
|
28
|
+
"agents": ["claude", "opencode"],
|
|
29
|
+
"skills": {
|
|
30
|
+
"crap-gate": { "version": "1.2.0", "package": "1.4.0" },
|
|
31
|
+
"backlog": { "version": "0.3.0", "package": "1.4.0", "agents": ["claude"] }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The top-level `agents` is the default for every skill; a skill's own `agents`
|
|
37
|
+
overrides it. `install <skill>` inherits the default (the first interactive
|
|
38
|
+
install asks once and stores it), while `install --agent ...` writes a
|
|
39
|
+
per-skill override. In scripts, pass `--agent` or commit the top-level default.
|
|
40
|
+
|
|
23
41
|
## Commands
|
|
24
42
|
|
|
25
43
|
```
|
|
@@ -35,11 +53,12 @@ npx @jesdi/skills-cli uninstall <skill> [--global]
|
|
|
35
53
|
|
|
36
54
|
Skills authored by other people are **not** copied into this repo — they keep
|
|
37
55
|
their own authors, upstreams, and licenses. `external-skills.json` records
|
|
38
|
-
which ones are part of the standard setup
|
|
39
|
-
|
|
56
|
+
which ones are part of the standard setup, where they come from, and (under
|
|
57
|
+
`pins`) the upstream commit the box set is taken from. Install them from
|
|
58
|
+
upstream with the [skills.sh](https://skills.sh/) CLI:
|
|
40
59
|
|
|
41
60
|
```bash
|
|
42
|
-
npx skills add mattpocock/skills # grill-me, grill-with-docs, improve-codebase-architecture
|
|
61
|
+
npx skills add mattpocock/skills # grill-me, grill-with-docs, grilling, improve-codebase-architecture, to-questionnaire, tdd, code-review, codebase-design, diagnosing-bugs, resolving-merge-conflicts
|
|
43
62
|
npx skills add JuliusBrussee/caveman # caveman suite
|
|
44
63
|
npx skills add vercel-labs/skills # find-skills
|
|
45
64
|
npx skills add vercel-labs/agent-skills # vercel-react-best-practices
|
|
@@ -49,6 +68,23 @@ npx skills add anthropics/skills # frontend-design (skip if using the C
|
|
|
49
68
|
The skills.sh lockfile (`~/.agents/.skill-lock.json`) tracks installed
|
|
50
69
|
versions; `npx skills update` refreshes them.
|
|
51
70
|
|
|
71
|
+
### Forks (the one exception)
|
|
72
|
+
|
|
73
|
+
`to-spec`, `to-tickets`, `prototype` and `wizard` are modified copies of the
|
|
74
|
+
mattpocock/skills originals, vendored under `skills/<name>/` with the upstream
|
|
75
|
+
MIT `LICENSE` and a header naming the upstream commit. They keep their upstream
|
|
76
|
+
names on purpose, so **never install the upstream copies of those four names
|
|
77
|
+
alongside them** (`npx skills add mattpocock/skills` installs the whole set —
|
|
78
|
+
deselect those four, or uninstall them afterwards). `external-skills.json`
|
|
79
|
+
lists them under `forks`.
|
|
80
|
+
|
|
81
|
+
### The box set
|
|
82
|
+
|
|
83
|
+
`external-skills.json` → `sets.box` names the skills the agent-ops box
|
|
84
|
+
receives: `own` from this package, `external` from the pinned upstream.
|
|
85
|
+
agent-ops vendors that set into its claude-home seed with its own refresh
|
|
86
|
+
command; this repo's job is to publish the set and keep the pins resolvable.
|
|
87
|
+
|
|
52
88
|
## Authoring skills
|
|
53
89
|
|
|
54
90
|
Add `skills/<name>/SKILL.md` (frontmatter `name` must match the directory,
|
package/package.json
CHANGED
package/skills/backlog/SKILL.md
CHANGED
|
@@ -71,16 +71,19 @@ these labels (`setup` provisions them all) — never invent new ones.
|
|
|
71
71
|
| `testing` | Test coverage, test infrastructure, flaky tests |
|
|
72
72
|
| `dependencies` | Upgrading or managing third-party dependencies |
|
|
73
73
|
|
|
74
|
-
**Pipeline —
|
|
74
|
+
**Pipeline — orthogonal to Type and Area:**
|
|
75
75
|
|
|
76
|
-
Whether an issue is ready for an unattended agent to pick up
|
|
76
|
+
Whether an issue is ready for an unattended agent to pick up, and what it
|
|
77
|
+
carries. `auto` and `human-required` are mutually exclusive; leave both off
|
|
77
78
|
when it is genuinely unclear — an unlabelled issue is simply not routed, which
|
|
78
|
-
is the safe default.
|
|
79
|
+
is the safe default. `spec-ready` may sit alongside `auto`. Dispatchers filter
|
|
80
|
+
on `auto` and read `spec-ready`; nothing else reads these.
|
|
79
81
|
|
|
80
82
|
| Label | Apply when |
|
|
81
83
|
|-------|-----------|
|
|
82
84
|
| `auto` | Trivial, or close enough to previously automated work — suitable for the unattended agents pipeline |
|
|
83
85
|
| `human-required` | Substantial fog of war remains; needs heavy human interaction before an agent can take it |
|
|
86
|
+
| `spec-ready` | The issue body already carries a settled design (Problem, Solution, Implementation and Testing Decisions), typically written by `to-spec` after a grilling session — the pipeline skips its own interview and reconciles the design against current code |
|
|
84
87
|
|
|
85
88
|
## `setup` — create the board once (idempotent)
|
|
86
89
|
|
|
@@ -92,7 +95,7 @@ dir.
|
|
|
92
95
|
1. Ensure the `project` scope: `gh auth status`; if Projects calls 403, run
|
|
93
96
|
`gh auth refresh -s project`.
|
|
94
97
|
2. Follow `references/graphql.md` → **Setup**: create the Project, link the repo,
|
|
95
|
-
add the six fields, create the `inbox` label plus the
|
|
98
|
+
add the six fields, create the `inbox` label plus the 15 taxonomy labels
|
|
96
99
|
(idempotent — `--force` reconciles color/description on re-runs). On a
|
|
97
100
|
brand-new board the `Area`
|
|
98
101
|
single-select is created with the generic default options
|
|
@@ -171,7 +174,9 @@ Reuse the **dedup discipline** from the `file-bug-issue` skill, but take the
|
|
|
171
174
|
3. Otherwise infer labels from the idea text per the **Label taxonomy** above,
|
|
172
175
|
then create it (see `references/graphql.md` → Capture): `--label inbox` plus
|
|
173
176
|
one `--label` per inferred label, body = the idea as-is (one loose sentence
|
|
174
|
-
is fine; no required structure).
|
|
177
|
+
is fine; no required structure). Add `spec-ready` only when the body being
|
|
178
|
+
filed is a settled design (the `to-spec` skill does this itself); a one-line
|
|
179
|
+
idea is never spec-ready.
|
|
175
180
|
4. Report the new issue URL and the labels applied. If mid-task, treat as a
|
|
176
181
|
side-quest and return.
|
|
177
182
|
|
|
@@ -182,7 +187,8 @@ Reuse the **dedup discipline** from the `file-bug-issue` skill, but take the
|
|
|
182
187
|
(skip = leave in inbox). Offer label corrections per the **Label taxonomy**
|
|
183
188
|
above; apply via `gh issue edit N --add-label … --remove-label …`
|
|
184
189
|
(graphql.md → Triage). Labels stay independent of the board `Area` gathered
|
|
185
|
-
next.
|
|
190
|
+
next. If the issue carries `spec-ready`, confirm the body really is a
|
|
191
|
+
settled design with its sections intact; remove the label when it is not.
|
|
186
192
|
3. For a promoted issue, gather `Impact` (1–5), `Effort` (1–5), `Area` (**pick one
|
|
187
193
|
from the options present in `.backlog/project-meta.json`** → `fields.Area.options`),
|
|
188
194
|
and optional blockers.
|
|
@@ -47,9 +47,10 @@ gh label create security --repo <repo> --description "Vulnerabilities, auth, per
|
|
|
47
47
|
gh label create performance --repo <repo> --description "Speed, memory, efficiency, scalability" --color f9d0c4 --force
|
|
48
48
|
gh label create testing --repo <repo> --description "Test coverage, test infrastructure, flaky tests" --color 0e8a16 --force
|
|
49
49
|
gh label create dependencies --repo <repo> --description "Upgrading or managing third-party dependencies" --color 0366d6 --force
|
|
50
|
-
# Pipeline labels (
|
|
50
|
+
# Pipeline labels (auto/human-required mutually exclusive; spec-ready may co-exist; read by dispatchers)
|
|
51
51
|
gh label create auto --repo <repo> --description "Suitable for the unattended agents pipeline" --color 5319E7 --force
|
|
52
52
|
gh label create human-required --repo <repo> --description "Needs heavy human interaction before automation" --color B60205 --force
|
|
53
|
+
gh label create spec-ready --repo <repo> --description "Issue body carries a settled design; the pipeline skips its interview" --color 006B75 --force
|
|
53
54
|
|
|
54
55
|
# 5. Discover IDs to build .backlog/project-meta.json
|
|
55
56
|
gh project view <projectNumber> --owner <owner> --format json # -> id (projectId)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Pocock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Logic Prototype
|
|
2
|
+
|
|
3
|
+
A single, self-contained HTML file (a **shareable demo**) that lets anyone drive a state model by clicking buttons. Use this when the question is about **business logic, state transitions, or data shape**: the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
|
4
|
+
|
|
5
|
+
Because it's one file with nothing to install, you can hand it to a non-developer (a designer, a PM, a domain expert) and let them feel the model for themselves. So it speaks their language, not the code's.
|
|
6
|
+
|
|
7
|
+
## When this is the right shape
|
|
8
|
+
|
|
9
|
+
- "I'm not sure if this state machine handles the edge case where X then Y."
|
|
10
|
+
- "Does this data model actually let me represent the case where..."
|
|
11
|
+
- "I want to feel out what the API should look like before writing it."
|
|
12
|
+
- Anything where someone wants to **press buttons and watch state change**.
|
|
13
|
+
|
|
14
|
+
If the question is "what should this look like," this is the wrong branch. Use [UI.md](UI.md).
|
|
15
|
+
|
|
16
|
+
## Process
|
|
17
|
+
|
|
18
|
+
### 1. State the question
|
|
19
|
+
|
|
20
|
+
Before writing code, write down what state model and what question you're prototyping. One paragraph, at the top of the demo (in a visible intro, not just a comment). A logic prototype that answers the wrong question is pure waste, so make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
|
|
21
|
+
|
|
22
|
+
### 2. Isolate the logic in a portable module
|
|
23
|
+
|
|
24
|
+
Put the actual logic (the bit that's answering the question) in a single `<script>` block written as a small, pure module that could be lifted out and dropped into the real codebase later. The page around it is throwaway; this module isn't.
|
|
25
|
+
|
|
26
|
+
The right shape depends on the question:
|
|
27
|
+
|
|
28
|
+
- **A pure reducer**: `(state, action) => state`. Good when actions are discrete events and state is a single value.
|
|
29
|
+
- **A state machine**: explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
|
|
30
|
+
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state, just transformations.
|
|
31
|
+
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
|
32
|
+
|
|
33
|
+
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a page. Keep it pure: no DOM, no `document`, no button handlers reaching inside it. The page calls into it; nothing flows the other direction. This is what makes the prototype useful past its own lifetime: once the question's answered, the validated reducer / machine / function set lifts into the real module on its own.
|
|
34
|
+
|
|
35
|
+
### 3. Build the shareable HTML file
|
|
36
|
+
|
|
37
|
+
One file, plain HTML/CSS/JS: no framework, no bundler, no server, everything inline so it opens by double-click and survives being emailed around. Anyone should be able to run it by opening it. Write it to the path the invoking prompt names (see [SKILL.md](SKILL.md) rule 1).
|
|
38
|
+
|
|
39
|
+
Write it for a non-developer. Every label is in **domain language**, not code: buttons and state read like the business, not the reducer. Explain in plain words what's happening.
|
|
40
|
+
|
|
41
|
+
Lay it out with a clean hierarchy, top to bottom:
|
|
42
|
+
|
|
43
|
+
1. **Title and one-line explanation** of what this demo lets you explore (the question from step 1).
|
|
44
|
+
2. **Current state**: the full relevant state, rendered as a readable panel (labelled fields, not a raw JSON dump), re-rendered after every click so the change is visible. Where it helps a non-developer follow, call out what just changed.
|
|
45
|
+
3. **Free-play buttons**: one button per action, always available, so anyone can poke at the model in any order. Each click dispatches its action and re-renders the state.
|
|
46
|
+
4. **Guided walkthroughs**: a set of **scenarios**, one per tab. Each tab holds a short plain-language description of the scenario (the situation it sets up and what to watch for) and underneath it, the ordered **buttons to press** for that scenario. Each step is a real button: clicking it performs that action and moves to the next step. Starting a walkthrough resets to a known initial state so the scenario runs the same way every time.
|
|
47
|
+
|
|
48
|
+
Choose scenarios that demonstrate the awkward cases, the ones hard to reason about on paper: the happy path, a tricky edge case, an attempt at something that should be illegal.
|
|
49
|
+
|
|
50
|
+
Keep it beautiful but restrained: clean typography, generous spacing, one accent colour. No animations, no gimmicks: nothing that competes with the state and the buttons. It must read well on a phone: a single column, buttons at least 44px tall.
|
|
51
|
+
|
|
52
|
+
### 4. Hand it over
|
|
53
|
+
|
|
54
|
+
Send them the file, or open it for them. They'll click through the walkthroughs and free-play whenever they get to it; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different"; those are the bugs in the _idea_, which is the whole point. If they want new actions or a new scenario, add them. Prototypes evolve.
|
|
55
|
+
|
|
56
|
+
### 5. Capture the answer
|
|
57
|
+
|
|
58
|
+
Once the prototype has answered its question, capture the verdict the way [SKILL.md](SKILL.md) rule 6 describes (an issue comment when there is an issue). The validated reducer / machine / function set lifts into the real module; the HTML shell is thrown away.
|
|
59
|
+
|
|
60
|
+
## Anti-patterns
|
|
61
|
+
|
|
62
|
+
- **Don't add tests.** A prototype that needs tests is no longer a prototype.
|
|
63
|
+
- **Don't wire it to the real database.** Use in-memory state unless the question is specifically about persistence.
|
|
64
|
+
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
|
|
65
|
+
- **Don't blur the logic and the page together.** If the pure module references the DOM, `document`, or button handlers, it's no longer liftable. Keep the page as a thin shell over a pure module.
|
|
66
|
+
- **Don't reach for a framework, bundler, or server.** One file the recipient double-clicks; a React app or a dev server defeats "shareable".
|
|
67
|
+
- **Don't ship the HTML shell into production.** The page is optimised for being clicked through by hand. The logic module behind it is the bit worth keeping.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prototype
|
|
3
|
+
description: Build a throwaway prototype to answer a design question, delivered as one self-contained HTML file. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!--
|
|
7
|
+
Modified copy of https://github.com/mattpocock/skills/tree/3cca18b368ae95cdbdebbff572ccafa662551015/skills/engineering/prototype
|
|
8
|
+
(mattpocock-skills v1.2.3). Copyright (c) 2026 Matt Pocock, MIT — see LICENSE.
|
|
9
|
+
Changes: the UI branch produces one self-contained HTML file holding every
|
|
10
|
+
variation (no routes, no dev server) instead of routes in the running app; the
|
|
11
|
+
file is written to the path the invoking prompt names; the verdict is captured as
|
|
12
|
+
an issue comment instead of a throwaway branch.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
# Prototype
|
|
16
|
+
|
|
17
|
+
A prototype is **throwaway code that answers a question**. The question decides the shape, but the delivery is always the same: **one self-contained HTML file** that opens by double-click, with no build step and no server. That is what lets a machine with no browser serve it as a file and a person open it on a phone.
|
|
18
|
+
|
|
19
|
+
## Pick a branch
|
|
20
|
+
|
|
21
|
+
Identify which question is being answered, using the user's prompt, the surrounding code, or by asking if the user is around:
|
|
22
|
+
|
|
23
|
+
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Free-play buttons plus tabbed guided walkthroughs that push the state machine through cases that are hard to reason about on paper, and that a non-developer can drive.
|
|
24
|
+
- **"What should this look like?"** → [UI.md](UI.md). Several radically different UI variations in one page, switchable inside the page from a floating bottom bar.
|
|
25
|
+
|
|
26
|
+
The two branches produce very different pages, so getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
|
|
27
|
+
|
|
28
|
+
## Rules that apply to both
|
|
29
|
+
|
|
30
|
+
1. **One file, clearly a prototype.** Everything inline: HTML, CSS, JS, sample data. No framework, no bundler, no server, no network requests. Write it to the path the invoking prompt names; with no path given, put it next to the module or page it prototypes for, named `<name>.prototype.html`, so a casual reader sees it is a prototype and not production.
|
|
31
|
+
2. **Trivial to run.** Opening the file is the whole procedure. No thinking required to start it.
|
|
32
|
+
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on.
|
|
33
|
+
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast.
|
|
34
|
+
5. **Surface the state.** After every action (logic) or on every variant switch (UI), render the full relevant state so the user can see what changed.
|
|
35
|
+
6. **Capture the verdict where the next reader looks.** When the work has a GitHub issue, post the verdict as a comment on it: the question, the answer (which variant, which model, or "none of these"), and the reason. The next stage is often a fresh session that reads the issue thread and has never seen the file. With no issue, tell the user the verdict and where the file is. Fold any validated decision into the real code (a validated reducer lifts into the real module; a winning layout is rebuilt properly, not copied). The prototype file itself never lands on `main`: leave it uncommitted, or delete it once the verdict is recorded.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
gh issue comment <number> --repo <owner/repo> --body-file /tmp/verdict.md
|
|
39
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# UI Prototype
|
|
2
|
+
|
|
3
|
+
Generate **several radically different UI variations** inside one self-contained HTML file, switchable from a floating bottom bar. The user flips between variants in the page, picks one (or steals bits from each), then throws the rest away.
|
|
4
|
+
|
|
5
|
+
If the question is about logic/state rather than what something looks like, this is the wrong branch. Use [LOGIC.md](LOGIC.md).
|
|
6
|
+
|
|
7
|
+
## When this is the right shape
|
|
8
|
+
|
|
9
|
+
- "What should this page look like?"
|
|
10
|
+
- "I want to see a few options for this dashboard before committing."
|
|
11
|
+
- "Try a different layout for the settings screen."
|
|
12
|
+
- Any time the user would otherwise spend a day picking between three vague mockups in their head.
|
|
13
|
+
|
|
14
|
+
## Why one file and not routes in the app
|
|
15
|
+
|
|
16
|
+
A prototype mounted in the running application is easier to judge because it sits among the real header, sidebar and data, but it needs a dev server and a browser on the machine that built it. The reviewer here may be looking at a file served from a machine with neither, on a phone. So the page recreates enough of the surrounding app to judge the variant against (a header strip, a sidebar outline, realistic density of sample data) and nothing more. Every variant lives in the same file, so what is being compared is the structure, not the chrome.
|
|
17
|
+
|
|
18
|
+
## Process
|
|
19
|
+
|
|
20
|
+
### 1. State the question and pick N
|
|
21
|
+
|
|
22
|
+
Default to **3 variants**. More than 5 stops being radically different and starts being noise, so cap there.
|
|
23
|
+
|
|
24
|
+
Write down the plan in one line at the top of the file, visible on the page:
|
|
25
|
+
|
|
26
|
+
> "Three variants of the settings page. Use the bar at the bottom or ←/→ to switch."
|
|
27
|
+
|
|
28
|
+
### 2. Generate radically different variants
|
|
29
|
+
|
|
30
|
+
Draft each variant. Hold each one to:
|
|
31
|
+
|
|
32
|
+
- The page's purpose and the data it has access to. Inline realistic sample data once and let every variant render it.
|
|
33
|
+
- The project's look: copy its colours, fonts, spacing and border radii into the page's `<style>` so a variant does not look foreign. Do not import the real component library; approximate it in plain CSS.
|
|
34
|
+
- A clear name, e.g. `A (Sidebar layout)`, `B (Cards)`, `C (Single column)`.
|
|
35
|
+
|
|
36
|
+
Variants must be **structurally different**: different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
|
|
37
|
+
|
|
38
|
+
### 3. Wire them together
|
|
39
|
+
|
|
40
|
+
Each variant is one `<section data-variant="A">` (B, C, …) in the file. Only the section for the current variant is displayed. The current variant is stored in the URL hash (`#variant=B`) so a specific one can be linked and survives reload:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<!-- pseudo-code, adapt freely -->
|
|
44
|
+
<section data-variant="A"> … </section>
|
|
45
|
+
<section data-variant="B"> … </section>
|
|
46
|
+
<section data-variant="C"> … </section>
|
|
47
|
+
<div id="switcher"><button data-dir="-1">←</button><span id="label"></span><button data-dir="1">→</button></div>
|
|
48
|
+
<script>
|
|
49
|
+
const variants = [...document.querySelectorAll('[data-variant]')];
|
|
50
|
+
const names = { A: 'Sidebar layout', B: 'Cards', C: 'Single column' };
|
|
51
|
+
function current() { return (location.hash.match(/variant=(\w)/) || [, variants[0].dataset.variant])[1]; }
|
|
52
|
+
function show(key) {
|
|
53
|
+
variants.forEach(s => s.hidden = s.dataset.variant !== key);
|
|
54
|
+
label.textContent = `${key} (${names[key]})`;
|
|
55
|
+
if (current() !== key) location.hash = `variant=${key}`;
|
|
56
|
+
}
|
|
57
|
+
function cycle(dir) {
|
|
58
|
+
const keys = variants.map(s => s.dataset.variant);
|
|
59
|
+
show(keys[(keys.indexOf(current()) + dir + keys.length) % keys.length]);
|
|
60
|
+
}
|
|
61
|
+
document.querySelectorAll('#switcher button').forEach(b => b.onclick = () => cycle(+b.dataset.dir));
|
|
62
|
+
addEventListener('keydown', e => {
|
|
63
|
+
if (e.target.matches('input, textarea, [contenteditable]')) return;
|
|
64
|
+
if (e.key === 'ArrowLeft') cycle(-1); if (e.key === 'ArrowRight') cycle(1);
|
|
65
|
+
});
|
|
66
|
+
addEventListener('hashchange', () => show(current()));
|
|
67
|
+
show(current());
|
|
68
|
+
</script>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 4. Build the floating switcher
|
|
72
|
+
|
|
73
|
+
A small fixed-position bar at the bottom-centre of the screen with three pieces:
|
|
74
|
+
|
|
75
|
+
- **Left arrow**: cycles to the previous variant (wraps around).
|
|
76
|
+
- **Variant label**: shows the current variant key and its name, e.g. `B (Cards)`.
|
|
77
|
+
- **Right arrow**: cycles forward (wraps around).
|
|
78
|
+
|
|
79
|
+
Behaviour:
|
|
80
|
+
|
|
81
|
+
- Clicking an arrow updates the URL hash so the variant is shareable and reload-stable.
|
|
82
|
+
- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an `<input>`, `<textarea>`, or `[contenteditable]` is focused.
|
|
83
|
+
- Touch: the arrows are at least 44px tall so the bar works on a phone.
|
|
84
|
+
- Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it's obviously not part of the design being evaluated.
|
|
85
|
+
|
|
86
|
+
### 5. Hand it over
|
|
87
|
+
|
|
88
|
+
Say where the file is and list the variant keys with their `#variant=` links. The user will flip through whenever they get to it. The interesting feedback is usually **"I want the header from B with the sidebar from C"**, which is the actual design they want.
|
|
89
|
+
|
|
90
|
+
### 6. Capture the answer and clean up
|
|
91
|
+
|
|
92
|
+
Once a variant has won, record the verdict the way [SKILL.md](SKILL.md) rule 6 describes: an issue comment naming the winner and why, and any parts borrowed from the others. Rebuild the winner properly in the real code with the project's real components; nothing is copied out of the prototype file. The file itself never lands on `main`.
|
|
93
|
+
|
|
94
|
+
## Anti-patterns
|
|
95
|
+
|
|
96
|
+
- **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree about structure.
|
|
97
|
+
- **Sharing too much markup between variants.** A shared header strip is fine; a shared layout defeats the point. Each variant should be free to throw out the layout.
|
|
98
|
+
- **Loading anything from the network.** No CDN scripts, no web fonts, no images by URL. The file must render from disk with no connection.
|
|
99
|
+
- **Promoting the prototype directly to production.** The variant markup was written under prototype constraints (no components, no tests, no accessibility pass). Rebuild it properly when you fold it in.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Pocock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: to-spec
|
|
3
|
+
description: "Turn the current conversation into a design spec and write it where the next stage reads it: a GitHub issue body labelled spec-ready (after a grilling session), or a dated design file on the current branch (an unattended spec stage). No interview, just synthesis of what you've already discussed."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!--
|
|
7
|
+
Modified copy of https://github.com/mattpocock/skills/tree/3cca18b368ae95cdbdebbff572ccafa662551015/skills/engineering/to-spec
|
|
8
|
+
(mattpocock-skills v1.2.3). Copyright (c) 2026 Matt Pocock, MIT — see LICENSE.
|
|
9
|
+
Changes: publishes to an issue body or a design file instead of an issue tracker;
|
|
10
|
+
seams are stated rather than confirmed when unattended; the document must pass the
|
|
11
|
+
agent-ops mechanical spec check; Testing Decisions must name the seams; the
|
|
12
|
+
`ready-for-agent` label became `spec-ready`; model invocation is allowed.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
This skill takes the current conversation context and codebase understanding and produces a spec. Do NOT interview the user; just synthesize what you already know.
|
|
16
|
+
|
|
17
|
+
## Destination
|
|
18
|
+
|
|
19
|
+
Decide where the spec goes before writing it. There are exactly two destinations:
|
|
20
|
+
|
|
21
|
+
- **Issue body.** Use this when a human settled the design with you interactively (a grilling session) and the unattended pipeline will pick the work up later. Create a GitHub issue in the current repo whose body is the spec, labelled `spec-ready`. If the conversation started from an existing issue, replace that issue's body and add the label instead of creating a new issue. The spec's H1 becomes the issue title and is omitted from the body.
|
|
22
|
+
- **Design file.** Use this when the invoking prompt names a file path, or when you are running unattended on a task branch. Write the spec to that path; with no path given, use `docs/specs/<YYYY-MM-DD>-<slug>-design.md`. Keep the H1 as the first line. Commit it to the current branch with a `docs:` message.
|
|
23
|
+
|
|
24
|
+
If neither is clear, ask once: "Issue body or design file?". Never publish anywhere else.
|
|
25
|
+
|
|
26
|
+
## Process
|
|
27
|
+
|
|
28
|
+
1. Explore the repo to understand the current state of the codebase, if you haven't already. Use the project's domain glossary vocabulary throughout the spec, and respect any ADRs in the area you're touching.
|
|
29
|
+
|
|
30
|
+
2. Sketch out the seams at which you're going to test the feature. Existing seams should be preferred to new ones. Use the highest seam possible. If new seams are needed, propose them at the highest point you can. The fewer seams across the codebase, the better - the ideal number is one.
|
|
31
|
+
|
|
32
|
+
With a human present, check that these seams match their expectations. Unattended, state your choice in the Testing Decisions section instead: a later implement session treats that section as the seams already agreed and cannot stop to ask.
|
|
33
|
+
|
|
34
|
+
3. Write the spec using the template below, then deliver it to the destination.
|
|
35
|
+
|
|
36
|
+
## Mechanical requirements
|
|
37
|
+
|
|
38
|
+
The unattended pipeline rejects a spec that fails a format check, so every spec must have:
|
|
39
|
+
|
|
40
|
+
- One `# <title>` H1 as the first line (file destination) or as the issue title (issue destination).
|
|
41
|
+
- At least two `## ` sections. Use every section of the template; write "None." rather than dropping one.
|
|
42
|
+
- A **Testing Decisions** section that names each seam explicitly: the module, function, command or endpoint the tests drive through, and whether it exists today or is new.
|
|
43
|
+
|
|
44
|
+
## Delivery commands
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Issue body (new issue). Write the body to a temp file first.
|
|
48
|
+
gh issue create --repo <owner/repo> --title "<H1 text>" --label spec-ready --body-file /tmp/spec.md
|
|
49
|
+
|
|
50
|
+
# Issue body (existing issue)
|
|
51
|
+
gh issue edit <number> --repo <owner/repo> --body-file /tmp/spec.md --add-label spec-ready
|
|
52
|
+
|
|
53
|
+
# If the label does not exist yet (the backlog skill's setup normally provisions it)
|
|
54
|
+
gh label create spec-ready --repo <owner/repo> --description "Issue body carries a settled design; the pipeline skips its interview" --color 006B75 --force
|
|
55
|
+
|
|
56
|
+
# Design file
|
|
57
|
+
git add docs/specs/<date>-<slug>-design.md && git commit -m "docs: spec for <slug>"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Read `<owner/repo>` from `gh repo view --json nameWithOwner -q .nameWithOwner`.
|
|
61
|
+
|
|
62
|
+
<spec-template>
|
|
63
|
+
|
|
64
|
+
# <Feature title>
|
|
65
|
+
|
|
66
|
+
## Problem Statement
|
|
67
|
+
|
|
68
|
+
The problem that the user is facing, from the user's perspective.
|
|
69
|
+
|
|
70
|
+
## Solution
|
|
71
|
+
|
|
72
|
+
The solution to the problem, from the user's perspective.
|
|
73
|
+
|
|
74
|
+
## User Stories
|
|
75
|
+
|
|
76
|
+
A LONG, numbered list of user stories. Each user story should be in the format of:
|
|
77
|
+
|
|
78
|
+
1. As an <actor>, I want a <feature>, so that <benefit>
|
|
79
|
+
|
|
80
|
+
<user-story-example>
|
|
81
|
+
1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
|
|
82
|
+
</user-story-example>
|
|
83
|
+
|
|
84
|
+
This list of user stories should be extremely extensive and cover all aspects of the feature.
|
|
85
|
+
|
|
86
|
+
## Implementation Decisions
|
|
87
|
+
|
|
88
|
+
A list of implementation decisions that were made. This can include:
|
|
89
|
+
|
|
90
|
+
- The modules that will be built/modified
|
|
91
|
+
- The interfaces of those modules that will be modified
|
|
92
|
+
- Technical clarifications from the developer
|
|
93
|
+
- Architectural decisions
|
|
94
|
+
- Schema changes
|
|
95
|
+
- API contracts
|
|
96
|
+
- Specific interactions
|
|
97
|
+
|
|
98
|
+
Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
|
|
99
|
+
|
|
100
|
+
Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it within the relevant decision and note briefly that it came from a prototype. Trim to the decision-rich parts, not a working demo, just the important bits.
|
|
101
|
+
|
|
102
|
+
## Testing Decisions
|
|
103
|
+
|
|
104
|
+
A list of testing decisions that were made. Include:
|
|
105
|
+
|
|
106
|
+
- A description of what makes a good test (only test external behavior, not implementation details)
|
|
107
|
+
- **The seams**: every interface the tests drive through, named (module, function, command or endpoint), each marked existing or new. This list is the agreement a later implement session works from.
|
|
108
|
+
- Which modules will be tested
|
|
109
|
+
- Prior art for the tests (i.e. similar types of tests in the codebase)
|
|
110
|
+
|
|
111
|
+
## Out of Scope
|
|
112
|
+
|
|
113
|
+
A description of the things that are out of scope for this spec.
|
|
114
|
+
|
|
115
|
+
## Further Notes
|
|
116
|
+
|
|
117
|
+
Any further notes about the feature.
|
|
118
|
+
|
|
119
|
+
</spec-template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Pocock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: to-tickets
|
|
3
|
+
description: Break a spec, plan, or the current conversation into numbered tracer-bullet ticket files under .agent/tickets/, each declaring its blocking edges and acceptance criteria phrased as observable behavior. Use after a spec is approved and before implementation starts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!--
|
|
7
|
+
Modified copy of https://github.com/mattpocock/skills/tree/3cca18b368ae95cdbdebbff572ccafa662551015/skills/engineering/to-tickets
|
|
8
|
+
(mattpocock-skills v1.2.3). Copyright (c) 2026 Matt Pocock, MIT — see LICENSE.
|
|
9
|
+
Changes: tickets always go to `.agent/tickets/<NN>-<slug>.md` (no tracker path);
|
|
10
|
+
numbering is contiguous from 01 in dependency order; acceptance criteria must state
|
|
11
|
+
observable behavior; the approval quiz is skipped when unattended; model
|
|
12
|
+
invocation is allowed.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
# To Tickets
|
|
16
|
+
|
|
17
|
+
Break a plan, spec, or conversation into a set of **tickets**: tracer-bullet vertical slices, each declaring the tickets that **block** it.
|
|
18
|
+
|
|
19
|
+
## Process
|
|
20
|
+
|
|
21
|
+
### 1. Gather context
|
|
22
|
+
|
|
23
|
+
Work from whatever is already in the conversation context. If the user passes a reference (a spec path, an issue number or URL) as an argument, fetch it and read its full body and comments.
|
|
24
|
+
|
|
25
|
+
### 2. Explore the codebase (optional)
|
|
26
|
+
|
|
27
|
+
If you have not already explored the codebase, do so to understand the current state of the code. Ticket titles and descriptions should use the project's domain glossary vocabulary, and respect ADRs in the area you're touching.
|
|
28
|
+
|
|
29
|
+
Look for opportunities to prefactor the code to make the implementation easier. "Make the change easy, then make the easy change."
|
|
30
|
+
|
|
31
|
+
### 3. Draft vertical slices
|
|
32
|
+
|
|
33
|
+
Break the work into **tracer bullet** tickets.
|
|
34
|
+
|
|
35
|
+
<vertical-slice-rules>
|
|
36
|
+
|
|
37
|
+
- Each slice cuts a narrow but COMPLETE path through every layer (schema, API, UI, tests): vertical, NOT a horizontal slice of one layer
|
|
38
|
+
- A completed slice is demoable or verifiable on its own
|
|
39
|
+
- Each slice is sized to fit in a single fresh context window
|
|
40
|
+
- Any prefactoring should be done first
|
|
41
|
+
|
|
42
|
+
</vertical-slice-rules>
|
|
43
|
+
|
|
44
|
+
Give each ticket its **blocking edges**: the other tickets that must complete before it can start. A ticket with no blockers can start immediately.
|
|
45
|
+
|
|
46
|
+
**Wide refactors are the exception to vertical slicing.** A **wide refactor** is one mechanical change (rename a column, retype a shared symbol) whose **blast radius** fans across the whole codebase, so a single edit breaks thousands of call sites at once and no vertical slice can land green. Don't force it into a tracer bullet; sequence it as **expand–contract**. First expand: add the new form beside the old so nothing breaks. Then migrate the call sites over in batches sized by blast radius (per package, per directory), each batch its own ticket blocked by the expand, keeping CI green batch to batch because the old form still exists. Finally contract: delete the old form once no caller remains, in a ticket blocked by every migrate batch. When even the batches can't stay green alone, keep the sequence but let them share an integration branch that all block a final integrate-and-verify ticket; green is promised only there.
|
|
47
|
+
|
|
48
|
+
### 4. Quiz the user (attended only)
|
|
49
|
+
|
|
50
|
+
When a human is in the loop, present the proposed breakdown as a numbered list. For each ticket, show:
|
|
51
|
+
|
|
52
|
+
- **Title**: short descriptive name
|
|
53
|
+
- **Blocked by**: which other tickets (if any) must complete first
|
|
54
|
+
- **What it delivers**: the end-to-end behaviour this ticket makes work
|
|
55
|
+
|
|
56
|
+
Ask the user:
|
|
57
|
+
|
|
58
|
+
- Does the granularity feel right? (too coarse / too fine)
|
|
59
|
+
- Are the blocking edges correct: does each ticket only depend on tickets that genuinely gate it?
|
|
60
|
+
- Should any tickets be merged or split further?
|
|
61
|
+
|
|
62
|
+
Iterate until the user approves the breakdown.
|
|
63
|
+
|
|
64
|
+
Running unattended (no human to answer), skip this step: the approved spec and the plan stage's own reviewers are the checkpoints. Write the tickets directly.
|
|
65
|
+
|
|
66
|
+
### 5. Write the ticket files
|
|
67
|
+
|
|
68
|
+
Write one file per ticket under `.agent/tickets/<NN>-<slug>.md`. `NN` is a two-digit number starting at `01`, assigned in dependency order (blockers first) with no gaps and no duplicates: a reader executes them in numeric order and the sequence must never stop early. Delete any stale files in that directory first so the set is exactly the tickets you drafted. Use the template below: one ticket per file, never a single combined file.
|
|
69
|
+
|
|
70
|
+
`.agent/` is working state, not source. It is never committed; check it is gitignored before committing anything else.
|
|
71
|
+
|
|
72
|
+
Work the **frontier**: any ticket whose blockers are all done. For a purely linear chain that means top to bottom.
|
|
73
|
+
|
|
74
|
+
Do NOT close or modify any parent issue.
|
|
75
|
+
|
|
76
|
+
<ticket-template>
|
|
77
|
+
|
|
78
|
+
# <NN>: <Ticket title>
|
|
79
|
+
|
|
80
|
+
**What to build:** the end-to-end behaviour this ticket makes work, from the user's perspective, not a layer-by-layer implementation list.
|
|
81
|
+
|
|
82
|
+
**Blocked by:** the numbers/titles of the tickets that gate this one, or "None (can start immediately)".
|
|
83
|
+
|
|
84
|
+
- [ ] Acceptance criterion 1
|
|
85
|
+
- [ ] Acceptance criterion 2
|
|
86
|
+
|
|
87
|
+
</ticket-template>
|
|
88
|
+
|
|
89
|
+
<acceptance-criteria-rule>
|
|
90
|
+
|
|
91
|
+
Every acceptance criterion states **observable behavior**: something a reviewer can check by running the product, a command, or a test, without reading the implementation. "Running `make test` passes with the new endpoint covered" and "A user with an expired token sees the login page" are criteria. "Add a `TokenExpiry` class" and "Refactor the auth module" are implementation steps and do not belong here.
|
|
92
|
+
|
|
93
|
+
</acceptance-criteria-rule>
|
|
94
|
+
|
|
95
|
+
Avoid specific file paths or code snippets: they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it and note briefly that it came from a prototype. Trim to the decision-rich parts, not a working demo, just the important bits.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Pocock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wizard
|
|
3
|
+
description: Generate an interactive bash wizard that walks a human through steps only they can perform, and that says for every captured value whether it ends up in CI, on the agent-ops box (1Password), or local only. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!--
|
|
7
|
+
Modified copy of https://github.com/mattpocock/skills/tree/3cca18b368ae95cdbdebbff572ccafa662551015/skills/engineering/wizard
|
|
8
|
+
(mattpocock-skills v1.2.3). Copyright (c) 2026 Matt Pocock, MIT — see LICENSE.
|
|
9
|
+
Changes: every captured value declares a destination (ci, box, local); box values
|
|
10
|
+
are recorded with `box_ref` and the closing summary prints the exact 1Password
|
|
11
|
+
reference lines for the box's env template plus the not-live-until-converged
|
|
12
|
+
warning.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
# Wizard
|
|
16
|
+
|
|
17
|
+
A **wizard** is a bash script that walks a human, step by step, through a manual procedure that's tedious to do by hand and tedious to re-explain to an AI every time. It opens each URL, says exactly what to click and copy, captures the values, writes them where they belong (`.env`, GitHub secrets, 1Password for the box), confirms at every stage, and shows how many stages are left. It might configure third-party services, run a one-off migration, or move the project from one state to another.
|
|
18
|
+
|
|
19
|
+
The delightful UX is already solved by [template.sh](template.sh): stage-by-stage progress, confirmation gates, cross-platform URL opening (including WSL), hidden secret entry, idempotent `.env` upserts, `gh secret`/`gh variable` writes, box credential references, and a closing summary. **Your job is only to scope the procedure and author its stages.** The library above the `STAGES` marker is identical in every wizard; that consistency is the point: never hand-edit it.
|
|
20
|
+
|
|
21
|
+
A wizard is ephemeral by default: built for one run, saved to a scratch or `scripts/` path, deleted when the job's done. Commit it only when the user wants a repeatable setup path that should live in the repo.
|
|
22
|
+
|
|
23
|
+
## Destinations
|
|
24
|
+
|
|
25
|
+
Every captured value has exactly one of three destinations, decided in step 1 and visible in the script:
|
|
26
|
+
|
|
27
|
+
| Destination | Meaning | Helper |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `ci` | GitHub Actions reads it | `set_secret` / `set_var` |
|
|
30
|
+
| `box` | The agent-ops box reads it from 1Password through its env template | `box_ref KEY "op://agent-ops/<item>/<FIELD>"` after the human stores it |
|
|
31
|
+
| `local` | Only this machine's `.env` needs it | `write_env` alone |
|
|
32
|
+
|
|
33
|
+
A value can also be written to `.env` for local development on top of `ci` or `box`. The box is the one that silently fails: a wizard that captures a value the box needs but stops at the laptop finishes green while the box still cannot see it. `box_ref` is what makes that visible.
|
|
34
|
+
|
|
35
|
+
## Process
|
|
36
|
+
|
|
37
|
+
### 1. Scope the procedure
|
|
38
|
+
|
|
39
|
+
Work out every manual step the human must take and every value that gets captured along the way. Read the repo first, don't ask cold:
|
|
40
|
+
|
|
41
|
+
- For setup: `.env`, `.env.example`, `.env.*`, `README`, `docker-compose*`, framework config, and `.github/workflows/*` (every `secrets.*` / `vars.*` reference is a value the wizard must produce). For anything the box runs, also the env template in agent-ops (`provision/op.env.tpl`): every key there is a `box` value.
|
|
42
|
+
- For a migration or transition: the current state, the target state, and the irreversible actions between them.
|
|
43
|
+
|
|
44
|
+
Then show the user the ordered list of stages and the values each produces, and confirm: they may add, drop, or reorder.
|
|
45
|
+
|
|
46
|
+
**Done when:** every stage is named in order, and for each captured value you know (a) where the human gets it, (b) its destination (`ci`, `box` or `local`) plus whether `.env` also gets it, and (c) whether it's secret (hidden entry) or public.
|
|
47
|
+
|
|
48
|
+
### 2. Map each stage's journey
|
|
49
|
+
|
|
50
|
+
For each stage, write the precise path a human follows: which URL to open, what to do there, where a value is shown, which variable it fills: e.g. "Dashboard → Developers → API keys → Reveal test key → copy". For a `box` value the journey continues into 1Password: which vault, item and field the human stores it under, which is exactly the `op://` reference the box will read. Where you don't actually know the current UI or the exact command, say so and ask the user or check the docs: never invent steps that may not exist.
|
|
51
|
+
|
|
52
|
+
**Done when:** every stage traces to concrete instructions a stranger could follow.
|
|
53
|
+
|
|
54
|
+
### 3. Author the wizard
|
|
55
|
+
|
|
56
|
+
Copy `template.sh` to the target path. Replace the example stage with one `stage` per step, in dependency order. Use the library helpers: `stage`, `say`/`step`, `open_url`, `ask`/`ask_secret`, `write_env`, `set_secret`/`set_var`, `box_ref`, `pause`/`confirm`. Set `TOTAL_STAGES` to the number of stages you wrote.
|
|
57
|
+
|
|
58
|
+
Hold the bar the template sets: open the URL before asking for its value, use `ask_secret` for anything secret, `write_env` every value local development needs, `set_secret` only the values CI actually needs, `box_ref` every value the box needs (after a `step` telling the human where to store it in 1Password and a `pause`), and `confirm` before any irreversible action. Each `stage` clears the screen so only the current step is visible: keep a stage to one focused task so nothing the human needs scrolls away. Don't touch the library above the marker.
|
|
59
|
+
|
|
60
|
+
### 4. Verify and hand off
|
|
61
|
+
|
|
62
|
+
- `bash -n <script>`; run `shellcheck` if available.
|
|
63
|
+
- `chmod +x <script>`.
|
|
64
|
+
- Don't run it end-to-end yourself: it opens browsers and blocks on human input. Trace it statically instead: every value from step 1 is captured and lands where step 1 said, every `set_secret` name exactly matches a `secrets.*` reference in CI, and every `box_ref` key matches a key the box's env template has or will get.
|
|
65
|
+
- Tell the user how to run it, and repeat what the closing summary will say: box values are not live until the env template change is merged in agent-ops and the box has converged. If it's a repeatable setup path, commit it and link it from the README so the next person runs the script instead of asking an AI.
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# A wizard walks a human through a manual procedure, step by step.
|
|
4
|
+
# Generated by the /wizard skill.
|
|
5
|
+
#
|
|
6
|
+
# Modified copy of mattpocock/skills skills/engineering/wizard/template.sh
|
|
7
|
+
# @ 3cca18b (v1.2.3). Copyright (c) 2026 Matt Pocock, MIT. Change: box_ref
|
|
8
|
+
# records values the agent-ops box reads from 1Password, and finish prints
|
|
9
|
+
# the template lines that make them visible to it.
|
|
10
|
+
#
|
|
11
|
+
# Everything above the "STAGES" marker is the wizard library: do not hand-edit
|
|
12
|
+
# it. Author the per-step stages below the marker.
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
17
|
+
# Wizard library: delightful, consistent UX, identical across every wizard.
|
|
18
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
if [[ -t 1 ]] && command -v tput >/dev/null 2>&1 && [[ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]]; then
|
|
21
|
+
BOLD=$(tput bold); DIM=$(tput dim); RESET=$(tput sgr0)
|
|
22
|
+
BLUE=$(tput setaf 4); GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3); RED=$(tput setaf 1)
|
|
23
|
+
else
|
|
24
|
+
BOLD=""; DIM=""; RESET=""; BLUE=""; GREEN=""; YELLOW=""; RED=""
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Author sets this at the top of the stages section.
|
|
28
|
+
TOTAL_STAGES=0
|
|
29
|
+
|
|
30
|
+
_STAGE_INDEX=0
|
|
31
|
+
ENV_FILE="${ENV_FILE:-.env}"
|
|
32
|
+
BOX_ENV_TEMPLATE="${BOX_ENV_TEMPLATE:-provision/op.env.tpl}" # in agent-ops
|
|
33
|
+
WRITTEN_ENV=() # KEYs written to ENV_FILE this run
|
|
34
|
+
WRITTEN_SECRET=() # secret NAMEs set this run
|
|
35
|
+
BOX_REFS=() # "KEY=op://vault/item/FIELD" lines the box's env template needs
|
|
36
|
+
SKIPPED=() # things we couldn't do (e.g. gh missing)
|
|
37
|
+
|
|
38
|
+
# _clear wipes the terminal so only the current step is on screen. No-op when
|
|
39
|
+
# output isn't a terminal, so piped logs stay readable.
|
|
40
|
+
_clear() {
|
|
41
|
+
[[ -t 1 ]] || return 0
|
|
42
|
+
if command -v tput >/dev/null 2>&1; then tput clear; else printf '\033[2J\033[3J\033[H'; fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# banner "Title" shows the opening frame: what this wizard does.
|
|
46
|
+
banner() {
|
|
47
|
+
_clear
|
|
48
|
+
printf '\n%s%s %s%s\n' "$BOLD" "$BLUE" "$1" "$RESET"
|
|
49
|
+
printf '%s %s stages%s\n\n' "$DIM" "$TOTAL_STAGES" "$RESET"
|
|
50
|
+
printf '%s You drive the browser; this wizard tells you exactly what to do and\n' "$DIM"
|
|
51
|
+
printf ' captures the values you copy back. Stop any time with Ctrl-C and re-run\n'
|
|
52
|
+
printf ' later, since it remembers values already saved.%s\n' "$RESET"
|
|
53
|
+
pause "Ready to start?"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# stage "Name" clears the screen, then announces a stage and shows progress.
|
|
57
|
+
# Clearing keeps only the current step on screen.
|
|
58
|
+
stage() {
|
|
59
|
+
_clear
|
|
60
|
+
_STAGE_INDEX=$((_STAGE_INDEX + 1))
|
|
61
|
+
printf '\n%s%s▸ Stage %s/%s · %s%s\n' \
|
|
62
|
+
"$BOLD" "$BLUE" "$_STAGE_INDEX" "$TOTAL_STAGES" "$1" "$RESET"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# say "..." prints a plain instruction line.
|
|
66
|
+
say() { printf ' %s\n' "$1"; }
|
|
67
|
+
# step "..." is a numbered-feeling action the human takes in the browser.
|
|
68
|
+
step() { printf ' %s•%s %s\n' "$BLUE" "$RESET" "$1"; }
|
|
69
|
+
note() { printf ' %s%s%s\n' "$DIM" "$1" "$RESET"; }
|
|
70
|
+
warn() { printf ' %s⚠ %s%s\n' "$YELLOW" "$1" "$RESET"; }
|
|
71
|
+
|
|
72
|
+
# open_url URL opens it in the human's browser, cross-platform incl. WSL.
|
|
73
|
+
open_url() {
|
|
74
|
+
local url="$1"
|
|
75
|
+
printf ' %s↗ opening%s %s\n' "$GREEN" "$RESET" "$url"
|
|
76
|
+
{ if command -v wslview >/dev/null 2>&1; then wslview "$url"
|
|
77
|
+
elif command -v explorer.exe >/dev/null 2>&1; then explorer.exe "$url"
|
|
78
|
+
elif command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"
|
|
79
|
+
elif command -v open >/dev/null 2>&1; then open "$url"
|
|
80
|
+
else warn "couldn't open a browser; visit it manually: $url"; fi
|
|
81
|
+
} >/dev/null 2>&1 || warn "couldn't open a browser, so visit it manually: $url"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# pause "msg" waits for the human to confirm they've done the manual part.
|
|
85
|
+
pause() {
|
|
86
|
+
printf ' %s%s%s ' "$DIM" "${1:-Press Enter to continue}" "$RESET"
|
|
87
|
+
read -r _ || true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# confirm "question" is a y/N gate; returns success on yes.
|
|
91
|
+
confirm() {
|
|
92
|
+
local reply=""
|
|
93
|
+
printf ' %s? %s [y/N] ' "$YELLOW" "$1"
|
|
94
|
+
read -r reply || true
|
|
95
|
+
[[ "$reply" =~ ^[Yy] ]]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# _existing KEY: current value of KEY in ENV_FILE, if any.
|
|
99
|
+
_existing() {
|
|
100
|
+
[[ -f "$ENV_FILE" ]] || return 1
|
|
101
|
+
local line; line=$(grep -E "^${1}=" "$ENV_FILE" | tail -n1) || return 1
|
|
102
|
+
printf '%s' "${line#*=}"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# ask KEY "Prompt" reads a value into $KEY. Offers the existing .env value as
|
|
106
|
+
# a default on re-runs (Enter keeps it). Visible input (non-secret).
|
|
107
|
+
ask() {
|
|
108
|
+
local key="$1" prompt="$2" current input
|
|
109
|
+
current=$(_existing "$key" || true)
|
|
110
|
+
if [[ -n "$current" ]]; then
|
|
111
|
+
printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
|
|
112
|
+
else
|
|
113
|
+
printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
|
|
114
|
+
fi
|
|
115
|
+
read -r input || true
|
|
116
|
+
[[ -z "$input" && -n "$current" ]] && input="$current"
|
|
117
|
+
printf -v "$key" '%s' "$input"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# ask_secret KEY "Prompt" is like ask, but input is hidden.
|
|
121
|
+
ask_secret() {
|
|
122
|
+
local key="$1" prompt="$2" current input
|
|
123
|
+
current=$(_existing "$key" || true)
|
|
124
|
+
if [[ -n "$current" ]]; then
|
|
125
|
+
printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"
|
|
126
|
+
else
|
|
127
|
+
printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"
|
|
128
|
+
fi
|
|
129
|
+
read -rs input || true
|
|
130
|
+
printf '\n'
|
|
131
|
+
[[ -z "$input" && -n "$current" ]] && input="$current"
|
|
132
|
+
printf -v "$key" '%s' "$input"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces
|
|
136
|
+
# any existing line). Idempotent.
|
|
137
|
+
write_env() {
|
|
138
|
+
local key="$1" value="$2" tmp
|
|
139
|
+
touch "$ENV_FILE"
|
|
140
|
+
tmp=$(mktemp)
|
|
141
|
+
grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true
|
|
142
|
+
printf '%s=%s\n' "$key" "$value" >> "$tmp"
|
|
143
|
+
mv "$tmp" "$ENV_FILE"
|
|
144
|
+
WRITTEN_ENV+=("$key")
|
|
145
|
+
printf ' %s✓ wrote%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# set_secret NAME VALUE sets a GitHub Actions repo secret via gh. Falls back
|
|
149
|
+
# to a warning (and records it) if gh is unavailable or unauthenticated.
|
|
150
|
+
set_secret() {
|
|
151
|
+
local name="$1" value="$2"
|
|
152
|
+
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then
|
|
153
|
+
if printf '%s' "$value" | gh secret set "$name" >/dev/null 2>&1; then
|
|
154
|
+
WRITTEN_SECRET+=("$name")
|
|
155
|
+
printf ' %s✓ set%s GitHub secret %s\n' "$GREEN" "$RESET" "$name"
|
|
156
|
+
return
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
SKIPPED+=("GitHub secret $name (set it manually: gh secret set $name)")
|
|
160
|
+
warn "skipped GitHub secret $name: gh not ready; set it later"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# set_var NAME VALUE sets a GitHub Actions repo variable (non-secret).
|
|
164
|
+
set_var() {
|
|
165
|
+
local name="$1" value="$2"
|
|
166
|
+
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then
|
|
167
|
+
if gh variable set "$name" --body "$value" >/dev/null 2>&1; then
|
|
168
|
+
printf ' %s✓ set%s GitHub variable %s\n' "$GREEN" "$RESET" "$name"
|
|
169
|
+
return
|
|
170
|
+
fi
|
|
171
|
+
fi
|
|
172
|
+
SKIPPED+=("GitHub variable $name")
|
|
173
|
+
warn "skipped GitHub variable $name, gh not ready; set it later"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# box_ref KEY "op://vault/item/FIELD" records that the agent-ops box must read
|
|
177
|
+
# KEY from that 1Password reference. The wizard never writes to 1Password; the
|
|
178
|
+
# stage tells the human to store the value there, and finish prints the exact
|
|
179
|
+
# line the box's env template needs.
|
|
180
|
+
box_ref() {
|
|
181
|
+
BOX_REFS+=("$1=$2")
|
|
182
|
+
printf ' %s✓ box%s %s → %s\n' "$GREEN" "$RESET" "$1" "$2"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# finish clears, then shows a closing summary of everything configured.
|
|
186
|
+
finish() {
|
|
187
|
+
_clear
|
|
188
|
+
printf '\n%s%s ✓ Setup complete%s\n' "$BOLD" "$GREEN" "$RESET"
|
|
189
|
+
(( ${#WRITTEN_ENV[@]} )) && note "wrote ${#WRITTEN_ENV[@]} value(s) to $ENV_FILE: ${WRITTEN_ENV[*]}"
|
|
190
|
+
(( ${#WRITTEN_SECRET[@]} )) && note "set ${#WRITTEN_SECRET[@]} GitHub secret(s): ${WRITTEN_SECRET[*]}"
|
|
191
|
+
if (( ${#BOX_REFS[@]} )); then
|
|
192
|
+
printf '\n'; warn "box credentials: add these lines to $BOX_ENV_TEMPLATE in agent-ops"
|
|
193
|
+
for r in "${BOX_REFS[@]}"; do printf ' %s\n' "$r"; done
|
|
194
|
+
note "Each value must exist in 1Password at the reference shown."
|
|
195
|
+
note "The box cannot see these until that change is merged and the box has converged."
|
|
196
|
+
fi
|
|
197
|
+
if (( ${#SKIPPED[@]} )); then
|
|
198
|
+
printf '\n'; warn "still to do by hand:"
|
|
199
|
+
for s in "${SKIPPED[@]}"; do note " - $s"; done
|
|
200
|
+
fi
|
|
201
|
+
printf '\n'
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
205
|
+
# STAGES: author this section. One stage() per step the human takes.
|
|
206
|
+
# Replace the example below. Set TOTAL_STAGES to match the stages you write.
|
|
207
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
208
|
+
|
|
209
|
+
TOTAL_STAGES=1
|
|
210
|
+
|
|
211
|
+
banner "Stripe setup"
|
|
212
|
+
|
|
213
|
+
# ── Example stage: replace with your real steps ───────────────────────────
|
|
214
|
+
stage "Stripe: API keys"
|
|
215
|
+
say "We'll grab your Stripe test keys and store them for local dev, CI and the box."
|
|
216
|
+
open_url "https://dashboard.stripe.com/test/apikeys"
|
|
217
|
+
step "On the API keys page, copy the Publishable key (starts pk_test_)."
|
|
218
|
+
ask STRIPE_PUBLISHABLE_KEY "Paste the publishable key:"
|
|
219
|
+
step "Click 'Reveal test key' on the Secret key row, then copy it."
|
|
220
|
+
ask_secret STRIPE_SECRET_KEY "Paste the secret key:"
|
|
221
|
+
write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY" # local only
|
|
222
|
+
write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"
|
|
223
|
+
set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY" # CI needs this one
|
|
224
|
+
step "In 1Password, vault agent-ops, item agent-ops-stripe: add field STRIPE_SECRET_KEY with the same value."
|
|
225
|
+
pause "Stored in 1Password?"
|
|
226
|
+
box_ref STRIPE_SECRET_KEY "op://agent-ops/agent-ops-stripe/STRIPE_SECRET_KEY" # the box needs this one
|
|
227
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
228
|
+
|
|
229
|
+
finish
|
package/skills-manifest.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-09-
|
|
3
|
+
"generatedAt": "2026-09-07T15:08:46.060Z",
|
|
4
4
|
"skills": [
|
|
5
5
|
{
|
|
6
6
|
"name": "backlog",
|
|
7
|
-
"version": "0.1.
|
|
8
|
-
"hash": "sha256-
|
|
7
|
+
"version": "0.1.7",
|
|
8
|
+
"hash": "sha256-652964aebeadbd2a4ecafd5a588f0bd0c31b90442f3133f64d7d663893a1f7a0",
|
|
9
9
|
"description": "Manage a GitHub-Issues-backed backlog and a Projects-v2 work graph via five verbs. Use when the user wants to CAPTURE an idea/research thread (\"add to backlog\", \"capture this\", \"note this idea\", \"log a task\"), TRIAGE the inbox (\"triage the backlog\", \"score the inbox\"), see what to work on NEXT (\"what's next\", \"what should I work on\", \"ranked backlog\", \"next actionable task\"), LAND a finished item (\"mark done\", \"close out #N\"), or SETUP the board the first time. Ranks open issues by impact÷effort, respecting `Blocked by:` edges, so only actionable work surfaces."
|
|
10
10
|
},
|
|
11
11
|
{
|
|
@@ -49,6 +49,30 @@
|
|
|
49
49
|
"version": "0.1.0",
|
|
50
50
|
"hash": "sha256-4e386dd175a34e55e89e0e29e37f5d0afd927560b7e3ba4c5f3ef482fb73f722",
|
|
51
51
|
"description": "Capture before/after screenshots of UI views with Playwright and embed them in a PR. Use this skill whenever creating or preparing a pull request that touches frontend code (components, views, styles, layout, Tailwind classes) — even if the user just says \"open a PR\" or \"create the PR\" after UI work, and especially if they mention screenshots, visual diff, before/after, or \"show what changed\". Also use when the user asks to add screenshots to an existing PR."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "prototype",
|
|
55
|
+
"version": "0.1.0",
|
|
56
|
+
"hash": "sha256-211e0e116ff6efbc4589ea7264835855b9495ba535f242733af913903fe7707d",
|
|
57
|
+
"description": "Build a throwaway prototype to answer a design question, delivered as one self-contained HTML file. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "to-spec",
|
|
61
|
+
"version": "0.1.0",
|
|
62
|
+
"hash": "sha256-146048bc0d698b92c330e860dc5c052b4645e1ba69f5b094270632daec82e40b",
|
|
63
|
+
"description": "Turn the current conversation into a design spec and write it where the next stage reads it: a GitHub issue body labelled spec-ready (after a grilling session), or a dated design file on the current branch (an unattended spec stage). No interview, just synthesis of what you've already discussed."
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "to-tickets",
|
|
67
|
+
"version": "0.1.0",
|
|
68
|
+
"hash": "sha256-23e1381b40dd4ffa151a2f89dcb82462464ea424228b45a31e6656406d34fedc",
|
|
69
|
+
"description": "Break a spec, plan, or the current conversation into numbered tracer-bullet ticket files under .agent/tickets/, each declaring its blocking edges and acceptance criteria phrased as observable behavior. Use after a spec is approved and before implementation starts."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "wizard",
|
|
73
|
+
"version": "0.1.0",
|
|
74
|
+
"hash": "sha256-ebcd06573861f575707717ef65218b52436256c33a8cb1da12484c5b58ce9294",
|
|
75
|
+
"description": "Generate an interactive bash wizard that walks a human through steps only they can perform, and that says for every captured value whether it ends up in CI, on the agent-ops box (1Password), or local only. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself."
|
|
52
76
|
}
|
|
53
77
|
]
|
|
54
78
|
}
|