@plainconceptsplatform/agent-harness 3.10.0 → 3.11.0

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 CHANGED
@@ -133,6 +133,8 @@ Commands that other commands (or agents) need to execute are thin wrappers aroun
133
133
  | `/repo-audit` | Read-only audit of every configured source root against fullstack abilities and guardrails. Reports prioritized architecture, quality, dependency, lockfile, tooling, and CI findings. |
134
134
  | `/repo-initialize` | Initialize the project. Asks greenfield versus brownfield, then activates the agent team. |
135
135
  | `/plan-explore` | Think through an idea or investigate a problem before committing to a plan. |
136
+ | `/plan-mockup <screen or flow>` | Draw a self-contained HTML mockup of a UI change from this repository's own design tokens and components, with every region mapped to the real component to build it with. States UX intent, not a spec. Can publish it to an issue, where the refine and implement workflows pick it up. |
137
+ | `/plan-story <feature or need>` | Write a repo-aware user story from a feature idea: Gherkin acceptance criteria and an implementation plan, wrapped in the repository's issue form. Writes no files. |
136
138
  | `/plan-propose <url or idea>` | Parse a GitHub Issue, Azure DevOps, Jira, or browser URL, or a direct idea, into a structured plan (proposal, specs, tasks). Enriches each task with agent and model assignments. |
137
139
  | `/plan-quick <task>` | Quick plan for focused changes. Reads the codebase, creates a task checklist in the Todo pane, and stops. No OpenSpec, no proposals, no specs. |
138
140
  | `/plan-apply` | Implement tasks from the current plan. Detects format automatically: OpenSpec-annotated tasks run as parallel subagent waves; plain checkboxes run sequentially in-session. |
@@ -204,6 +206,8 @@ Built-in skills (`pc-` prefix) shipped with agent-harness:
204
206
  | `pc-userstory-browser` | Parse work item from any URL via browser automation (Linear, Trello, and so on) |
205
207
  | `browser-automation` | Browser control via `browse` (user's real browser, localhost + external sites with handoffs) |
206
208
  | `pc-plan-explore` | Read-only exploration procedure behind `/plan-explore`; autonomous mode used by `/plan-goal` |
209
+ | `pc-plan-mockup` | HTML mockup procedure behind `/plan-mockup`; autonomous mode used by the refine workflow |
210
+ | `pc-plan-story` | User story procedure behind `/plan-story`; used by the refine workflow |
207
211
  | `pc-plan-propose` | Proposal + task-enrichment procedure behind `/plan-propose`; autonomous mode used by `/plan-goal` |
208
212
  | `pc-plan-apply` | Wave-implementation procedure behind `/plan-apply`; autonomous mode used by `/plan-goal` |
209
213
  | `pc-plan-archive` | Archive procedure behind `/plan-archive` (platform flow injected at onboarding); autonomous mode used by `/plan-goal` |
@@ -1,7 +1,8 @@
1
+ import { execa } from 'execa'
1
2
  import fse from 'fs-extra'
2
3
  import path from 'path'
3
4
  import { fileURLToPath } from 'url'
4
- import { info, success } from '../../utils/exec.js'
5
+ import { info, success, warn } from '../../utils/exec.js'
5
6
  import { canUpdateManagedFile, readUpdateManifest, recordManagedFile, writeUpdateManifest } from '../../utils/update-manifest.js'
6
7
  import { RETIRED_PATHS } from '../../utils/paths.js'
7
8
 
@@ -294,7 +295,9 @@ export async function installSkills(backlogPlatform = 'github', repoPlatform, op
294
295
  if (await fse.pathExists(CONTENT_SKILLS_LOCK)) {
295
296
  const destLock = path.join(process.cwd(), 'skills-lock.json')
296
297
  if (await fse.pathExists(destLock) && (opts.updateMode || !opts.forceOverwrite)) {
297
- info('skills-lock.json already exists, skipping')
298
+ const added = opts.updateMode ? await mergeShippedSkillsLock(destLock) : []
299
+ if (added.length > 0) await installLockedSkills(added)
300
+ else info('skills-lock.json already exists, skipping')
298
301
  } else {
299
302
  await fse.copy(CONTENT_SKILLS_LOCK, destLock, { overwrite: true })
300
303
  success(`${opts.forceOverwrite ? 'Updated' : 'Installed'} skills-lock.json`)
@@ -306,6 +309,40 @@ export async function installSkills(backlogPlatform = 'github', repoPlatform, op
306
309
  // This avoids multiple npx skills add calls during onboarding.
307
310
  }
308
311
 
312
+ // A project's skills-lock.json is its own: it holds the skills the wizard and
313
+ // /make-engineer added. Replacing it on update would drop those, and skipping it
314
+ // meant a third-party skill the harness starts shipping never reached a project
315
+ // installed before that release. So update adds only the entries it lacks.
316
+ export async function mergeShippedSkillsLock(destLock) {
317
+ const shipped = await fse.readJson(CONTENT_SKILLS_LOCK)
318
+ let lock
319
+ try {
320
+ lock = await fse.readJson(destLock)
321
+ } catch {
322
+ warn('Could not parse skills-lock.json, leaving it as it is')
323
+ return []
324
+ }
325
+ lock.skills ??= {}
326
+ const added = Object.keys(shipped.skills ?? {}).filter(name => !lock.skills[name])
327
+ if (added.length === 0) return []
328
+ for (const name of added) lock.skills[name] = shipped.skills[name]
329
+ await fse.writeJson(destLock, lock, { spaces: 2 })
330
+ success(`Added to skills-lock.json: ${added.join(', ')}`)
331
+ return added
332
+ }
333
+
334
+ async function installLockedSkills(added) {
335
+ const result = await execa('npx', ['skills', 'experimental_install', '--yes'], {
336
+ cwd: process.cwd(),
337
+ reject: false,
338
+ stdio: 'pipe',
339
+ timeout: 600000,
340
+ })
341
+ if (result.exitCode !== 0) {
342
+ warn(`${added.join(', ')} added to skills-lock.json but not installed. Run npx skills experimental_install --yes.`)
343
+ }
344
+ }
345
+
309
346
  export async function removeRetiredFiles(cwd = process.cwd()) {
310
347
  for (const relative of RETIRED_PATHS) {
311
348
  const target = path.join(cwd, relative)
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Draw a self-contained HTML mockup of a UI change from this repository's own tokens and components.
3
+ agent: planner
4
+ subagent: false
5
+ ---
6
+
7
+ Load the `pc-plan-mockup` skill and execute it in **interactive mode**.
8
+
9
+ Input:
10
+
11
+ $ARGUMENTS
@@ -7,11 +7,17 @@
7
7
  "skillPath": "skills/find-skills/SKILL.md",
8
8
  "computedHash": "781bd6d3f9b19f8c9af6b53d8d0e4876d0183841b565db34ca7092ffa412d111"
9
9
  },
10
+ "html-prototype": {
11
+ "source": "plannotator/effective-html",
12
+ "sourceType": "github",
13
+ "skillPath": "skills/html-prototype/SKILL.md",
14
+ "computedHash": "7f82fd83b81f853e3b3f973073be4e82f93875b190f4a3f4a35b9801ace825cd"
15
+ },
10
16
  "user-story": {
11
17
  "source": "deanpeters/product-manager-skills",
12
18
  "sourceType": "github",
13
19
  "skillPath": "skills/user-story/SKILL.md",
14
- "computedHash": "user-story-placeholder"
20
+ "computedHash": "d2f39a6b17e9635da6c93003029c6ade7a20c17a44b0a17bf871bb0faabb33ed"
15
21
  }
16
22
  }
17
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plainconceptsplatform/agent-harness",
3
- "version": "3.10.0",
3
+ "version": "3.11.0",
4
4
  "description": "Installs the Plain Concepts Platform Harness into any codebase, and keeps it up to date. Wires OpenCode, OpenSpec, codegraph, and agentmemory into a multi-agent workflow that runs on native parallel subagents.",
5
5
  "keywords": [
6
6
  "opencode",
@@ -41,6 +41,8 @@ Core rule: push, don't pull. A worker is born with its work: every `task()` spaw
41
41
 
42
42
  When `.platform/contract.yml` declares `reuse` and the change's `proposal.md` has no `## What is reused` section, stop the APPLY stage and report it: the plan never checked what the template already ships. Otherwise every spawn prompt in step 7 carries that section.
43
43
 
44
+ When the change comes from an issue that carries a mockup (a section reading `UX mockup: intent, not a spec`, or a `mockups` branch folder for it), every spawn prompt for UI work in step 7 carries its component table and this line: the mockup states UX intent only; build with the components the table names, `DESIGN.md` and the repository's conventions, and never copy its markup, styles or `data-mockup-section` and `data-component` attributes. A `new:<Name>` entry is a component this change builds.
45
+
44
46
  Before hydrating the Todo board, resolve every task's annotated worker. If any task has a blank agent annotation, its base template is missing, its tier variant is unavailable, or the manifest has no effective model for its tier, stop the APPLY stage and report the task ID, expected worker, and missing file. Do not replace the worker with `fullstack-engineer`, `general`, or the lead session.
45
47
 
46
48
  **3. Hydrate the Todo board.** `todowrite` one item per task: `pending`. The Todo pane is the visible subagent board (opencode plugins cannot draw a custom pane, so the native Todo widget is the live UI). While a task is in flight, its label must carry the worker: `<agent> · <model>`, with the model read from `.opencode/harness-models.json`, so the pane shows which agent on which model is doing what. The Todo list is a projection only: never read it for recovery; rebuild it from `tasks.md` and git and `.opencode/harness-run.json`.
@@ -10,6 +10,7 @@ Explore, then hand back what you learned. `@openspec-explore` supplies the stanc
10
10
 
11
11
  - Never write, edit, or create a file while this skill is loaded, OpenSpec artifacts included. This overrides `@openspec-explore`, which says creating them is "fine". Reading, searching, and discussing are the whole job.
12
12
  - If the conversation turns toward implementation, say explore mode is active and point at `/plan-apply`.
13
+ - When the idea changes what someone sees on screen, point at `/plan-mockup` once the direction is settled: a picture settles layout questions faster than prose.
13
14
 
14
15
  Load `@openspec-explore` for the approach.
15
16
 
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: pc-plan-mockup
3
+ description: Build a self-contained HTML mockup of a UI change from this repository's own design tokens and components, so a person and the implementing agent agree on the experience before any code is written. The mockup states UX intent, not a spec. Use when a feature touches the frontend and the layout, flow or states are worth seeing. Invoked by the /plan-mockup command (interactive) and by the refine workflow (autonomous).
4
+ license: MIT
5
+ ---
6
+
7
+ Draw the change before building it. The mockup answers one question: is this the experience we mean? It is never the implementation. The real components, `DESIGN.md` and `ARCHITECTURE.md` decide how it is built, and the mockup tells the implementer which of those components each part of the screen should be.
8
+
9
+ [The contract](mockup-contract.md) defines the files, the HTML rules and `mockup.json`. Read it before writing anything.
10
+
11
+ ## Input
12
+
13
+ A feature idea, an exploration brief from `/plan-explore`, a story from `/plan-story`, or an issue. Ask what screen or flow to draw only when none of those says.
14
+
15
+ ## Modes
16
+
17
+ - `interactive` (default): the person is here. Show the mockup, ask what to change, iterate until they are happy.
18
+ - `autonomous`: a workflow called this skill and gave an output directory. Ask nothing. Write `index.html` and `mockup.json` there and stop.
19
+
20
+ <!-- PC-OPTIMIZATION-MEMORY-START -->
21
+ <!-- PC-OPTIMIZATION-MEMORY-END -->
22
+
23
+ ## Rules
24
+
25
+ - Never use a component, colour or font the repository does not have. When the screen needs something that does not exist, mark it `new:<Name>` so the implementer knows it is new work.
26
+ - Never load anything from outside the file, and never use a utility framework runtime. Plain CSS from the tokens keeps it approximate, and approximate is the point.
27
+ - Never touch the source tree. The mockup lives in `.mockups/` locally and on the `mockups` branch once published.
28
+ - Data is invented. No real names, customers or email addresses, even ones the conversation used.
29
+
30
+ ## Flow
31
+
32
+ 1. **Tokens.** Find `DESIGN.md` at the root, or in `ai/` or `docs/`. Read its frontmatter by meaning, not by exact key: `color.primitives.brand-blue` and `color.primitive.brand_blue` are the same token. If it is missing or still the placeholder, in interactive mode run `/make-design` first; in autonomous mode read the theme stylesheet the web app imports and set `designSource` to `theme-css`.
33
+
34
+ 2. **Components.** List the UI components the area uses: the shared UI folder (often `src/shared/ui/` or `src/components/ui/`), the feature's own components, and the packages they import from. Read the few the screen needs, enough to draw them with the right anatomy (a table's header and pagination, a sheet's footer actions), never to copy their code.
35
+
36
+ 3. **States.** Decide which states the scenario can reach: empty, loading, error, success, disabled, mobile, or one the issue names. Draw only those.
37
+
38
+ 4. **Method.** If `@html-prototype` is installed, load it and use it in mockup mode for how to scope the flow, model states and check widths. This skill stays the authority on look and components.
39
+
40
+ 5. **Write.** `index.html` and `mockup.json`, as the contract says. Tag every region with `data-mockup-section` and every component stand-in with `data-component`. Interactive mode writes to `.mockups/<slug>/` and adds `.mockups/` to `.gitignore` when it is missing; autonomous mode writes to the directory it was given.
41
+
42
+ 6. **Check.** Open the file at 1440 and 390 pixels wide, with `@browser-automation` when it is available, and save `desktop.png` and `mobile.png` beside it. Look for overflow, unreadable contrast and empty regions. Without a browser, say which checks did not run.
43
+
44
+ 7. **Hand off.** In interactive mode, show the screenshots and the component table (section, element, component, path), then ask what next.
45
+
46
+ ## Publish
47
+
48
+ When the person picks Publish, or names an issue, put the folder on the `mockups` branch so the refine and implement workflows find it:
49
+
50
+ ```bash
51
+ issue=<number>
52
+ dir=$(mktemp -d)
53
+ git fetch origin mockups 2>/dev/null || true
54
+ if git rev-parse --verify -q origin/mockups >/dev/null; then
55
+ git worktree add "$dir" origin/mockups --detach
56
+ else
57
+ git worktree add --detach "$dir" && git -C "$dir" checkout --orphan mockups && git -C "$dir" rm -rfq .
58
+ fi
59
+ rm -rf "$dir/issue-$issue" && mkdir -p "$dir/issue-$issue"
60
+ cp .mockups/<slug>/* "$dir/issue-$issue/"
61
+ git -C "$dir" add "issue-$issue"
62
+ git -C "$dir" commit -m "mockup: issue #$issue [skip ci]"
63
+ git -C "$dir" push origin HEAD:refs/heads/mockups
64
+ git worktree remove --force "$dir"
65
+ ```
66
+
67
+ Set `issue` in `mockup.json` before copying. Then comment on the issue with a link to `issue-<number>/index.html` on that branch, the desktop screenshot when there is one, the component table and the line `UX mockup: intent, not a spec. Build with the components listed.` Use the repository's platform CLI for the comment; when there is none, give the person the text to paste.
68
+
69
+ ## Contracts
70
+
71
+ ```json
72
+ {
73
+ "questions": [
74
+ {
75
+ "header": "What next",
76
+ "question": "What next?",
77
+ "options": [
78
+ { "label": "Change the mockup", "description": "Say what to move, add or remove." },
79
+ { "label": "/plan-story", "description": "Write the user story, with this mockup in its UX section." },
80
+ { "label": "Publish", "description": "Put the mockup on the mockups branch and link it from an issue." }
81
+ ]
82
+ }
83
+ ]
84
+ }
85
+ ```
@@ -0,0 +1,65 @@
1
+ # Mockup contract
2
+
3
+ What a mockup folder holds, so the people and the workflows that read it can rely on it. The agentic workflows validate a mockup against this file before they render or publish it; a mockup that breaks it is dropped, never fixed up.
4
+
5
+ ## Files
6
+
7
+ | File | Required | What it is |
8
+ |---|---|---|
9
+ | `index.html` | yes | The mockup. One file, opens offline in any browser. |
10
+ | `mockup.json` | yes | What the mockup claims, in a form a workflow can read without parsing HTML. |
11
+ | `desktop.png`, `mobile.png` | no | Screenshots at 1440 and 390 pixels wide. The refine workflow renders them itself when they are missing. |
12
+
13
+ ## `index.html`
14
+
15
+ - One self-contained file under 400 KB. Styles sit in one inline `<style>`; a small inline `<script>` is allowed for toggling states.
16
+ - Nothing is loaded from anywhere: no `http://` or `https://` URL, no `<script src>`, no `<link href>` to a stylesheet, no web font, no image file. Icons are inline SVG or text.
17
+ - Colours, radii, spacing and type come from the repository's design tokens, declared once as CSS custom properties on `:root` (and `.dark` when the repository has a dark mode). No utility framework runtime, Tailwind included: the mockup is approximate on purpose, and a runtime would make it look more authoritative than it is.
18
+ - The first element in `<body>` is a banner reading `UX mockup: intent, not a spec`.
19
+ - Every screen region carries `data-mockup-section="<id>"`, a kebab-case id unique in the file.
20
+ - Every element that stands for a real component carries `data-component="<reference>"`:
21
+ - a path relative to the repository root for a component the repository owns, such as `apps/web/src/shared/ui/button.tsx`;
22
+ - a package export for a component it imports, such as `@plainconceptsplatform/ui-components/data-table`;
23
+ - `new:<Name>` for a component that does not exist yet and the change has to build.
24
+ - Data is fictional and internally consistent. No real person, customer, email address or identifier.
25
+
26
+ ## `mockup.json`
27
+
28
+ ```json
29
+ {
30
+ "version": 1,
31
+ "title": "Claim timeline panel",
32
+ "issue": 42,
33
+ "designSource": "DESIGN.md",
34
+ "sections": [
35
+ { "id": "timeline", "purpose": "Every status change of the claim, newest first" }
36
+ ],
37
+ "components": [
38
+ { "section": "timeline", "element": "Status chip", "component": "Badge", "path": "apps/web/src/shared/ui/badge.tsx" },
39
+ { "section": "timeline", "element": "Timeline row", "component": "new:TimelineItem", "path": "new" }
40
+ ],
41
+ "states": ["empty", "loading", "mobile"],
42
+ "notes": "The approver's comment is collapsed past three lines."
43
+ }
44
+ ```
45
+
46
+ | Field | Rule |
47
+ |---|---|
48
+ | `version` | `1`. |
49
+ | `title` | Short name of the screen or flow. |
50
+ | `issue` | The issue number, or `null` before there is one. |
51
+ | `designSource` | `DESIGN.md`, `theme-css` (tokens read from the theme stylesheet because `DESIGN.md` was missing) or `none`. |
52
+ | `sections` | One entry per `data-mockup-section` in the HTML, same ids, same order. |
53
+ | `components` | One entry per distinct `data-component` reference. `component` is the name the code uses; `path` is the reference from the HTML, or `new`. |
54
+ | `states` | The states the mockup draws, from `default`, `empty`, `loading`, `error`, `success`, `disabled`, `mobile`, or a domain state named in the issue. |
55
+ | `notes` | Optional. Behaviour the picture cannot show. |
56
+
57
+ ## When the work is split
58
+
59
+ Each smaller issue covers some sections of the one mockup. Its body says which, on a line of its own: `Mockup sections: timeline, filters`, using the section ids. The refine workflow reads that line and links the issue to those sections.
60
+
61
+ ## Where a published mockup lives
62
+
63
+ On the repository's `mockups` branch, an orphan branch that never merges into anything, at `issue-<number>/`. Every publish replaces that folder. Nothing on that branch is source code, and nothing in the source tree may import or copy from it.
64
+
65
+ The issue links it from a section the workflow writes between `<!-- agent-mockup:start -->` and `<!-- agent-mockup:end -->`, which opens with `<!-- agent-mockup: issue-<number> -->` naming the folder. A split child names its parent's folder there.
@@ -49,7 +49,9 @@ The caller may pass exploration findings from a prior `/plan-explore` session. T
49
49
 
50
50
  *Fill:* Draw every field's content from your exploration findings. Required fields always get real content; optional fields only when you genuinely have something for them. The story narrative lands in the field that asks for it — proposal, description, or what-happened, depending on the form. The Given/When/Then scenarios go into the form's acceptance-criteria field when it has one; otherwise they stay a section of their own. The Mermaid diagram goes where it reads best inside the filled form.
51
51
 
52
- 9. **Plan section.** Using the codebase investigation from step 3, produce a structured implementation plan that goes after the story inside the issue form body. Format it as follows:
52
+ 9. **UX section.** When this conversation produced a mockup with `/plan-mockup` (its `.mockups/<slug>/mockup.json`), or the issue already links one, add a short UX section inside the filled form: the mockup's title, where it lives, its component table (section, element, component, path) and the line `UX mockup: intent, not a spec. Build with the components listed.` Acceptance scenarios describe behaviour, never pixels, so none of them may say "matches the mockup". When the story touches the UI and there is no mockup, offer `/plan-mockup` in step 11.
53
+
54
+ 10. **Plan section.** Using the codebase investigation from step 3, produce a structured implementation plan that goes after the story inside the issue form body. Format it as follows:
53
55
 
54
56
  Start with a one-line scope summary, then a context paragraph describing what areas the plan touches, how many changes it breaks into, and whether the changes are independent.
55
57
 
@@ -72,7 +74,7 @@ The caller may pass exploration findings from a prior `/plan-explore` session. T
72
74
 
73
75
  Do not write any files. The plan is part of the story output, read-only. It tells the implementer what to touch and why, so they can start without re-investigating.
74
76
 
75
- 10. Show the story with the issue form wrapping, the plan, and the artefacts it is grounded in, then ask what is next. If the plan has an open clarification — a wording choice, a missing constraint, an unknown API — ask it before the contracts question.
77
+ 11. Show the story with the issue form wrapping, the plan, and the artefacts it is grounded in, then ask what is next. If the plan has an open clarification — a wording choice, a missing constraint, an unknown API — ask it before the contracts question.
76
78
 
77
79
  ## Contracts
78
80
 
@@ -85,6 +87,7 @@ The caller may pass exploration findings from a prior `/plan-explore` session. T
85
87
  "options": [
86
88
  { "label": "/plan-propose", "description": "Turn this user story into a full OpenSpec proposal with design, specs, and tasks." },
87
89
  { "label": "/plan-quick", "description": "Create a lightweight task checklist from this story." },
90
+ { "label": "/plan-mockup", "description": "Draw the UI this story describes before planning it. Offered when the story touches the UI and has no mockup yet." },
88
91
  { "label": "Refine the story", "description": "Iterate on the story with feedback." }
89
92
  ]
90
93
  }
@@ -22,6 +22,8 @@ Display the following reference to the user exactly as written. Do not summarize
22
22
 
23
23
  **`/plan-story <feature or need>`**: Write a detailed, repo-aware user story from a feature idea. Loads the `@user-story` skill (Mike Cohn format + Gherkin acceptance criteria), analyzes your codebase for concrete context, and produces a development-ready story with specific personas, real outcomes, and testable criteria grounded in your actual file paths, component names, and data models. No files written — just the story.
24
24
 
25
+ **`/plan-mockup <screen or flow>`**: Draw the UI change before building it: a self-contained HTML mockup built from this repository's own design tokens and components, with every region mapped to the real component the implementer should use. It states UX intent, not a spec. Writes to `.mockups/` and can publish to an issue, where the refine and implement workflows pick it up.
26
+
25
27
  **`/plan-propose <url or idea>`**: You have a work item URL, or a clear idea and you want to turn it into a structured plan (proposal, specs, tasks). Enriches each task with the best matching agent and model before showing you the plan. Nothing is implemented until you confirm.
26
28
 
27
29
  ---
@@ -69,6 +71,7 @@ Display the following reference to the user exactly as written. Do not summarize
69
71
  **Complex change:**
70
72
  ```
71
73
  /plan-explore ← optional: think it through first
74
+ /plan-mockup ← optional: see the UI before planning it
72
75
  /plan-propose ← create the plan
73
76
  /plan-apply ← implement with the team
74
77
  /ops-ship ← ship
@@ -19,7 +19,7 @@ A guided tour of this repository and the harness installed in it, for somebody w
19
19
 
20
20
  | Group | Commands |
21
21
  |---|---|
22
- | Planning | `/plan-explore`, `/plan-story`, `/plan-propose`, `/plan-quick`, `/plan-goal` |
22
+ | Planning | `/plan-explore`, `/plan-mockup`, `/plan-story`, `/plan-propose`, `/plan-quick`, `/plan-goal` |
23
23
  | Implementation | `/plan-apply`, `/plan-archive` |
24
24
  | Maintenance | `/make-architecture`, `/make-design`, `/make-engineer`, `/make-guardrails` |
25
25
  | Shipping | `/ops-ship`, `/ops-review`, `/ops-backlog` |