acstack 0.0.0-stage → 0.47.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.
Files changed (143) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +389 -2
  4. package/THIRD_PARTY_NOTICES +14 -0
  5. package/TROUBLESHOOTING.md +225 -0
  6. package/agents/codex/frontend-verifier.toml +352 -0
  7. package/agents/codex/task-checker.toml +345 -0
  8. package/agents/codex/task-executor.toml +157 -0
  9. package/agents/codex/test-writer.toml +149 -0
  10. package/agents/frontend-verifier.md +351 -0
  11. package/agents/task-checker.md +344 -0
  12. package/agents/task-executor.md +156 -0
  13. package/agents/test-writer.md +148 -0
  14. package/assets/playwriter-bridge/build-launcher.ps1 +32 -0
  15. package/assets/playwriter-bridge/doctor.ps1 +450 -0
  16. package/assets/playwriter-bridge/launcher-src.cs +131 -0
  17. package/assets/playwriter-bridge/opener.js +330 -0
  18. package/assets/playwriter-bridge/opener.ps1 +63 -0
  19. package/assets/playwriter-bridge/register-tasks.ps1 +328 -0
  20. package/assets/playwriter-bridge/relay.ps1 +50 -0
  21. package/assets/playwriter-bridge/stop.ps1 +125 -0
  22. package/assets/playwriter-bridge/sync.ps1 +271 -0
  23. package/assets/playwriter-bridge/tunnel.ps1 +325 -0
  24. package/assets/playwriter-bridge/vm-free-port.sh +166 -0
  25. package/assets/terminal-workspace/client-keybindings.md +87 -0
  26. package/assets/terminal-workspace/config.example.yaml +329 -0
  27. package/assets/terminal-workspace/setup.sh +4317 -0
  28. package/cli/README.md +47 -0
  29. package/cli/bin/acstack.js +3 -0
  30. package/cli/dist/index.js +25984 -0
  31. package/cli/dist/index.js.map +7 -0
  32. package/cli/package.json +59 -0
  33. package/docs/adr/0001-ste-writing-standard.md +16 -0
  34. package/docs/adr/0002-version-gate-not-auto-bump.md +35 -0
  35. package/docs/adr/0003-handoff-ack-command.md +19 -0
  36. package/docs/adr/0004-dev-setup-per-host.md +13 -0
  37. package/docs/adr/0005-two-orchestrators-per-host.md +25 -0
  38. package/docs/adr/0006-document-opener-service.md +89 -0
  39. package/docs/adr/0007-lead-check-reads-the-transcript.md +87 -0
  40. package/docs/adr/0008-cli-audits-skill-interviews.md +37 -0
  41. package/docs/adr/0009-verify-the-write-not-the-writer.md +51 -0
  42. package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +115 -0
  43. package/docs/adr/0011-node-header-is-the-edge-encoding.md +20 -0
  44. package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +31 -0
  45. package/docs/adr/0013-the-diagram-renderer-is-pure.md +23 -0
  46. package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +29 -0
  47. package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +37 -0
  48. package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +21 -0
  49. package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +13 -0
  50. package/docs/adr/index.md +17 -0
  51. package/docs/config-reference.md +572 -0
  52. package/docs/dev-setups.md +164 -0
  53. package/docs/migrate-0.8.md +28 -0
  54. package/docs/playwriter-bridge-windows.md +15 -0
  55. package/docs/terminal-workspace-keys.md +137 -0
  56. package/docs/terminal-workspace.md +1774 -0
  57. package/docs/workflows.md +309 -0
  58. package/hooks/ac-writing-style-reminder.sh +86 -0
  59. package/hooks/context-pressure.sh +583 -0
  60. package/hooks/hooks.json +50 -0
  61. package/hooks/session-start-handoff.sh +165 -0
  62. package/hooks/session-start.sh +214 -0
  63. package/orchestrator/AGENTS.md +532 -0
  64. package/output-styles/ac-writing-style.md +286 -0
  65. package/package.json +50 -4
  66. package/pi/agents/frontend-verifier.md +357 -0
  67. package/pi/agents/task-checker.md +348 -0
  68. package/pi/agents/task-executor.md +160 -0
  69. package/pi/agents/test-writer.md +154 -0
  70. package/pi/extension.ts +723 -0
  71. package/profiles/fullstack-python.yaml +29 -0
  72. package/profiles/node-typescript.yaml +23 -0
  73. package/profiles/python.yaml +24 -0
  74. package/skills/archive/SKILL.md +160 -0
  75. package/skills/bootstrap/SKILL.md +109 -0
  76. package/skills/bridge/HANDOFF.md +93 -0
  77. package/skills/bridge/SKILL-VM.md +292 -0
  78. package/skills/bridge/SKILL-WINDOWS.md +526 -0
  79. package/skills/bridge/SKILL.md +121 -0
  80. package/skills/browser-verify/SKILL.md +229 -0
  81. package/skills/code-review/SKILL.md +44 -0
  82. package/skills/commit/SKILL.md +106 -0
  83. package/skills/compact-and-continue/SKILL.md +241 -0
  84. package/skills/explore/SKILL.md +149 -0
  85. package/skills/grilling/SKILL.md +134 -0
  86. package/skills/handoff/SKILL.md +250 -0
  87. package/skills/handoff/launch-herdr.md +197 -0
  88. package/skills/handoff/launch-without-herdr.md +30 -0
  89. package/skills/handoff/lead-check.md +59 -0
  90. package/skills/handoff/outcomes.md +162 -0
  91. package/skills/handoff/running-agent.md +50 -0
  92. package/skills/handoff/watch.md +115 -0
  93. package/skills/host/SKILL.md +247 -0
  94. package/skills/host/detect-host.sh +297 -0
  95. package/skills/host/herdr.md +79 -0
  96. package/skills/host/install-herdr-block.sh +467 -0
  97. package/skills/host/install-orca.sh +512 -0
  98. package/skills/host/notes.md +97 -0
  99. package/skills/host/orca.md +160 -0
  100. package/skills/host/questions.md +163 -0
  101. package/skills/host/report.md +42 -0
  102. package/skills/implement/SKILL.md +230 -0
  103. package/skills/implement/decision-log.md +62 -0
  104. package/skills/implement/design-pass.md +32 -0
  105. package/skills/implement/relaxed-tdd.md +28 -0
  106. package/skills/map/SKILL.md +250 -0
  107. package/skills/map/frontend.md +227 -0
  108. package/skills/map/trackers/files.md +74 -0
  109. package/skills/map/trackers/github.md +180 -0
  110. package/skills/map/visuals.md +387 -0
  111. package/skills/new-worktree/SKILL.md +155 -0
  112. package/skills/new-worktree/detect-orchestrator.sh +328 -0
  113. package/skills/new-worktree/detect-orchestrator.test.sh +894 -0
  114. package/skills/new-worktree/herdr.md +84 -0
  115. package/skills/new-worktree/orca.md +101 -0
  116. package/skills/pre-commit-review/SKILL.md +242 -0
  117. package/skills/pre-commit-review/auto-fix.md +19 -0
  118. package/skills/pre-commit-review/interactive.md +35 -0
  119. package/skills/quick-fix/SKILL.md +125 -0
  120. package/skills/record-context/SKILL.md +106 -0
  121. package/skills/setup/SKILL.md +250 -0
  122. package/skills/setup/browser.md +123 -0
  123. package/skills/setup/design-review.md +97 -0
  124. package/skills/setup/first-run.md +114 -0
  125. package/skills/setup/report.md +68 -0
  126. package/skills/setup/row-fixes.md +196 -0
  127. package/skills/setup/terminal-workspace.md +153 -0
  128. package/skills/sync/SKILL.md +171 -0
  129. package/skills/teardown-worktree/SKILL.md +245 -0
  130. package/skills/teardown-worktree/detector.md +39 -0
  131. package/skills/teardown-worktree/herdr.md +113 -0
  132. package/skills/teardown-worktree/orca.md +61 -0
  133. package/skills/terminal-workspace/SKILL.md +249 -0
  134. package/skills/terminal-workspace/components.md +36 -0
  135. package/skills/terminal-workspace/config-choices.md +69 -0
  136. package/skills/terminal-workspace/emulator-keys.md +48 -0
  137. package/skills/terminal-workspace/headless-clipboard.md +175 -0
  138. package/skills/terminal-workspace/turn-off-and-update.md +104 -0
  139. package/skills/test-conventions/SKILL.md +59 -0
  140. package/skills/visual-docs/SKILL.md +246 -0
  141. package/skills/writing/SKILL.md +231 -0
  142. package/skills/writing/examples.md +153 -0
  143. package/skills/writing/vocabulary.md +96 -0
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: record-context
3
+ description: Write durable records when a decision lands – an architecture decision record (ADR), a short file stating one decision and why, if the decision is hard to reverse and surprising and a real trade-off; a glossary entry if a term got settled; both, or neither. Invoke after a map node resolves or after an equivalent decision is settled in conversation. Neither is the common case; silence is a valid outcome.
4
+ ---
5
+
6
+ # Record durable context
7
+
8
+ A decision just landed. Two independent tests decide what, if anything, it
9
+ leaves behind. Apply both; they share a trigger and nothing else.
10
+
11
+ ## ADR – all three, or no ADR
12
+
13
+ An ADR is an architecture decision record: a short file that states one
14
+ decision and the reasoning behind it. Write one only when the decision is:
15
+
16
+ 1. **Hard to reverse** – undoing it later means real rework, not an edit.
17
+ 2. **Surprising without context** – a competent newcomer would ask "why on
18
+ earth is it like this?"
19
+
20
+ 3. **A real trade-off** – the decision gives something up. A choice with no
21
+ losing side needs no record.
22
+
23
+ Most decisions meet none of these. Do not lower the bar – an ADR that records
24
+ an obvious choice buries the ones that matter.
25
+
26
+ ### Writing one
27
+
28
+ - Path: `docs/adr/NNNN-slug.md`. The number is the highest existing number plus
29
+ one, zero-padded to four digits. Create the directory lazily.
30
+
31
+ If the file for that number appeared since you scanned (a parallel teammate
32
+ wrote one), renumber to the new highest plus one. In agent teams, ADR
33
+ writing is a shared-file concern – route it through the orchestrator or the
34
+ sequential after-team step, never two teammates at once.
35
+
36
+ - Body: a `# title` heading, then one to three sentences stating the decision
37
+ and the why. Optional short `## Considered options` and `## Consequences`
38
+ sections when they carry weight the summary cannot.
39
+
40
+ - Tone: per the `writing` skill.
41
+
42
+ ### Example
43
+
44
+ `docs/adr/0004-invariant-tool-path.md`:
45
+
46
+ ```markdown
47
+ # One invariant path for the command line tool
48
+
49
+ Every skill calls the command line tool for ACStack as
50
+ `~/.claude/acstack/bin/acstack`. The SessionStart hook repoints that symlink
51
+ at the copy inside the current plugin cache. A version bump moves the target.
52
+ No skill file changes.
53
+
54
+ ## Considered options
55
+
56
+ A bare `acstack` command reads the user's shell PATH. A subshell, a fresh
57
+ agent context and a continuous integration run each start without that PATH.
58
+
59
+ ## Consequences
60
+
61
+ A skill that runs before the hook finds no symlink. An absent symlink means
62
+ the hook has not run. The fix is to restart the agent session.
63
+ ```
64
+
65
+ ### You generate the index
66
+
67
+ After writing any ADR, rewrite `docs/adr/index.md` in full, with one line
68
+ per ADR. Sort the lines by number, ascending. Each line takes its number
69
+ and slug from the filename, and its title from the file's first heading:
70
+
71
+ ```markdown
72
+ - [0001](0001-one-node-type.md) – One node type for questions and work
73
+ ```
74
+
75
+ Generated, never hand-edited – a derived view cannot drift from its source.
76
+ If you find hand edits in it, regenerate; the files are the truth.
77
+
78
+ ## Glossary – when a term got settled
79
+
80
+ If the decision fixed what a word means – picked between competing names,
81
+ sharpened a fuzzy term, coined one – record it:
82
+
83
+ - **Cross-domain terms** go in `CONTEXT.md` at the repo root.
84
+ - **Domain terms** go in `acstack/specs/<domain>/CONTEXT.md`, beside that
85
+ domain's `spec.md`. Find the domain in `acstack/domain-map.yaml`.
86
+
87
+ - Create both files lazily; there is no index file –
88
+ `domain-map.yaml` already lists every domain.
89
+
90
+ Format: a `# Glossary` heading, then one `**term** – definition` line per
91
+ term, alphabetical, one or two sentences each. Each definition follows the
92
+ `writing` skill.
93
+
94
+ Glossary and nothing else – no implementation notes, no specs, no scratch
95
+ content. The moment it accepts anything else it becomes another document
96
+ competing with the living specs.
97
+
98
+ **The human wins.** A glossary records the vocabulary humans agreed on.
99
+ Nobody rewrites it to match code. If code and glossary disagree, surface the
100
+ disagreement to the user; only a human decision changes the entry.
101
+
102
+ ## Neither
103
+
104
+ If the decision fails the ADR bar and settled no term, write nothing and
105
+ say nothing. The durable trail for ordinary decisions is the resolved node
106
+ and the living specs.
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: setup
3
+ description: Set up ACStack in a project, and change how an already configured project is set up. With no acstack/project.yaml it detects the project type, writes the config, generates the domain map and offers browser verification. With one already there it leads with the health check, then offers to fix each row that failed. Both paths end in the same check, so it is safe to run on the first day and on any day after.
4
+ argument-hint: "[what to set up or change]"
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ ## User input
9
+
10
+ ```text
11
+ $ARGUMENTS
12
+ ```
13
+
14
+ # Setup
15
+
16
+ One skill, two paths. What the project already has picks the path. Both paths
17
+ join at the health check, so this skill states every fix once.
18
+
19
+ ```mermaid
20
+ flowchart TD
21
+ HOST["Step 1<br/>declare this machine"] --> FORK{"acstack/project.yaml<br/>is here?"}
22
+ FORK -- no --> FIRST["Steps 3 to 6<br/>detect, ask, write the config"]
23
+ FORK -- yes --> CHECK
24
+ FIRST --> CHECK["Step 7<br/>acstack config check --json"]
25
+ CHECK --> MENU["Step 8<br/>offer the rows that need a fix"]
26
+ MENU --> FIX["Step 9<br/>fix one row at a time"]
27
+ FIX --> BROWSER["Steps 10 and 11<br/>browser mode, Playwriter bridge"]
28
+ FIX --> OFFERS["Steps 12 and 13<br/>offer the workspace and the design review"]
29
+ OFFERS --> REPORT["Step 14<br/>report"]
30
+ BROWSER --> OFFERS
31
+ ```
32
+
33
+ Three terms, before they get used:
34
+
35
+ - A **health check** is one run of `acstack config check`. It audits the machine
36
+ and the project. It changes nothing.
37
+
38
+ - A **row** is one line of that report. It carries an `id`, a `status` and a
39
+ `message`.
40
+
41
+ - An **axis** is one setting of the machine, recorded as one `host.*` key in the
42
+ global config.
43
+
44
+ The command line tool audits. This skill interviews and writes. Neither one does
45
+ the other's job.
46
+
47
+ See `docs/adr/0008-cli-audits-skill-interviews.md`.
48
+
49
+ ## Step 1: Declare this machine
50
+
51
+ The dev setup of the machine is per machine, not per project. It covers which
52
+ orchestrator hosts terminal panes and git worktrees. It also covers which
53
+ browser-verification modes work here.
54
+
55
+ Those answers live in the global config under the `host.*` keys.
56
+
57
+ Read what this machine declares:
58
+
59
+ ```bash
60
+ ~/.claude/acstack/bin/acstack config get host
61
+ ```
62
+
63
+ On exit 0 the command prints the declared axes, and Step 2 follows. Exit code 2
64
+ means this machine declares nothing yet.
65
+
66
+ On exit 2, invoke the `host` skill and run its whole interview here. Do not tell
67
+ the user to go and run it later.
68
+
69
+ Host setup is per machine and safe to re-run, and a half-finished machine leaves
70
+ axes unset. The health check in Step 7 then fails on those axes and blocks
71
+ everything after it.
72
+
73
+ Do not restate the host skill's questions. It owns them, and it writes its own
74
+ answers. Come back to Step 2 when it finishes.
75
+
76
+ ## Step 2: Choose the path
77
+
78
+ ```bash
79
+ test -f acstack/project.yaml && echo present || echo absent
80
+ ```
81
+
82
+ - **absent** – take the first-run path. Go to Step 3.
83
+ - **present** – take the re-run path. Go straight to Step 7.
84
+
85
+ ## Step 3: Detect the project type and propose defaults
86
+
87
+ Read [`first-run.md`](first-run.md) on the first-run path, and run Steps 3 to 6 from it.
88
+
89
+ ## Step 4: Ask what to customise
90
+
91
+ In [`first-run.md`](first-run.md).
92
+
93
+ ## Step 5: Customise the selected sections
94
+
95
+ In [`first-run.md`](first-run.md).
96
+
97
+ ## Step 6: Write the config
98
+
99
+ In [`first-run.md`](first-run.md). Then go to Step 7.
100
+
101
+ ## Step 7: Run the health check
102
+
103
+ Both paths arrive here. Run the check and read its JSON:
104
+
105
+ ```bash
106
+ ~/.claude/acstack/bin/acstack config check --json
107
+ ```
108
+
109
+ That path is a symlink into the released plugin cache, so it carries the shipped
110
+ CLI. An agent testing this branch before the release runs
111
+ `node cli/dist/index.js config check --json` from the repo instead.
112
+
113
+ It prints one object to standard output and nothing else:
114
+
115
+ ```json
116
+ {"checks": [{"id": "domain-map", "status": "pass", "message": "acstack/domain-map.yaml maps 4 domains"}]}
117
+ ```
118
+
119
+ Each `status` is `pass`, `fail` or `info`. The exit codes carry the same news:
120
+
121
+ | Exit code | What it means |
122
+ | --- | --- |
123
+ | 0 | nothing failed, though rows still report info |
124
+ | 1 | at least one row failed |
125
+ | 2 | a required host axis has no value |
126
+
127
+ Branch on the `id` of a row. Never branch on its `message`. The identifiers are
128
+ an interface and the messages get reworded.
129
+
130
+ On exit 2, go back to Step 1 and run the host interview. Nothing else can be
131
+ trusted until every required axis has a value.
132
+
133
+ Print the failing rows to the user before you ask anything. A project set up
134
+ months ago deserves to hear what fails first.
135
+
136
+ ## Step 8: Offer the rows that need a fix
137
+
138
+ Build one multi-select question in the question tool (AskUserQuestion with
139
+ `multiSelect: true` on Claude Code). Put one option in it per row you are going
140
+ to offer, and say in each description what the row reported. This is the pre-selection the user sees: only real gaps reach the menu.
141
+
142
+ Offer a row when any of these holds:
143
+
144
+ - Its `status` is `fail`.
145
+ - Its `id` is `preferred-browser-mode`, its `status` is `info`, and
146
+ `acstack/project.yaml` configures a `frontend` block. The project has a
147
+ frontend and has named no browser mode for it.
148
+
149
+ - Its `id` is `output-style` and its `status` is `info`. The row passes when the
150
+ settings files select `acstack:ac-writing-style`, so `info` means they select
151
+ some other style, or select none.
152
+
153
+ - Its `id` is `frontend-verification` and its `status` is `info`. The project
154
+ configures a frontend and `workflow.frontend_verification` is not `true`.
155
+
156
+ Each of those rules reads the `status` and the `id`. Read neither row's message
157
+ to decide, for the reason Step 7 gives: the message is prose and it gets
158
+ reworded.
159
+
160
+ Add three options at the end of the list, whatever the check reported:
161
+
162
+ - **Re-declare this machine** – invoke the `host` skill. It re-asks every axis,
163
+ required and optional, and starts from the current answers.
164
+
165
+ The check reports an `optional-axis:<key>` row as `info`, never as `fail`.
166
+ So this option is the only way one of them reaches a question.
167
+
168
+ - **Change one setting** – for a key the check has no opinion about, such as
169
+ `workflow.tdd.strict`. Point the user at `docs/config-reference.md`, which
170
+ lists every key, its values and its default. Then write the key:
171
+
172
+ ```bash
173
+ ~/.claude/acstack/bin/acstack config set workflow.tdd.strict false
174
+ ```
175
+
176
+ Do not restate the reference here.
177
+
178
+ - **Skip** – leave everything as it is.
179
+
180
+ ## Step 9: Fix one row at a time
181
+
182
+ Each `id` maps to one fix. Work the selected rows in this order:
183
+
184
+ | Row id | The fix |
185
+ | --- | --- |
186
+ | `no-project` | there is no project here, so go to Step 3 |
187
+ | `required-axis:<key>` | invoke the `host` skill |
188
+ | `orchestrator:<name>` | invoke the `host` skill |
189
+ | `browser-mode:<mode>` | invoke the `host` skill, or the second fix in `row-fixes.md` for the mode that failed |
190
+ | `preferred-browser-mode` | invoke the `host` skill on a `fail`, Step 10 on an `info` |
191
+ | `optional-axis:host.terminal_workspace` | Step 12 |
192
+ | `optional-axis:<key>` | invoke the `host` skill, through the menu option in Step 8 |
193
+ | `domain-map` | Step 9a in `row-fixes.md` |
194
+ | `agent-browser` | Step 9b in `row-fixes.md` |
195
+ | `agent-browser-json` | Step 9c in `row-fixes.md` |
196
+ | `verification-knowledge` | Step 9d in `row-fixes.md` |
197
+ | `frontend-verification` | run `acstack config set workflow.frontend_verification true` |
198
+ | `output-style` | Step 9e in `row-fixes.md` |
199
+
200
+ Read [`row-fixes.md`](row-fixes.md) when a selected row is `browser-mode:<mode>`, `frontend-verification`, `domain-map`, `agent-browser`, `agent-browser-json`, `verification-knowledge` or `output-style`. It holds the second fixes and Steps 9a to 9e.
201
+
202
+ ## Step 10: Ask the project's browser mode
203
+
204
+ Read [`browser.md`](browser.md) when a `preferred-browser-mode` row reports `info`.
205
+
206
+ ## Step 11: Connect the Playwriter bridge
207
+
208
+ Read [`browser.md`](browser.md) when the user picks the remote mode in Step 10, or a `browser-mode:remote` row fails.
209
+
210
+ ## Step 12: Offer the terminal workspace
211
+
212
+ Read [`terminal-workspace.md`](terminal-workspace.md) on every run, after the rows are fixed.
213
+
214
+ ## Step 13: Offer the design review
215
+
216
+ Read [`design-review.md`](design-review.md) when Step 7 reported a `frontend-verification` row. With no such row the project has no frontend, so go to Step 14.
217
+
218
+ ## Step 14: Report
219
+
220
+ Read [`report.md`](report.md) on every run, as the last step.
221
+
222
+ ## What this skill leaves to others
223
+
224
+ - `acstack config check` owns every audit rule. Do not re-probe the machine with
225
+ shell commands of your own.
226
+
227
+ - `acstack config show` owns printing the current setup. It reports the profile,
228
+ the commands, the directories and what the project says about its browser. This
229
+ skill never re-prints those itself.
230
+
231
+ - `docs/config-reference.md` owns the key reference. It lists each key, its
232
+ values, its default, and what changes when you change it.
233
+
234
+ - `acstack config set <key> <value>` owns the single-key change, in both files.
235
+ It reads the key to decide which one.
236
+
237
+ A `host.*` key goes to the global config at `~/.config/acstack/config.json`.
238
+ Every other key it knows goes to `acstack/project.yaml`, and the write keeps
239
+ the comments and the key order. It refuses a key neither schema knows, so
240
+ never fall back to editing the file.
241
+
242
+ - The `host` skill owns the machine interview and every `host.*` question, with
243
+ one exception. Step 12 of this skill asks `host.terminal_workspace`. The
244
+ workspace installs binaries, so the offer belongs after the project works.
245
+
246
+ - The `impeccable` plugin owns its own install and its own `PRODUCT.md`.
247
+ `/impeccable init` writes that file. Step 13 names the command and copies
248
+ nothing out of the plugin.
249
+
250
+ - `docs/dev-setups.md` documents the nine `host.*` axes.
@@ -0,0 +1,123 @@
1
+ # Setup: browser mode and Playwriter bridge
2
+
3
+ `SKILL.md` decides when to read this file: Step 9 routes a `preferred-browser-mode` info row to Step 10, or a `browser-mode:remote` failure to Step 11.
4
+
5
+ ## Step 10: Ask the project's browser mode
6
+
7
+ Both paths reach this step. The first run reaches it because a fresh frontend
8
+ project states no preference. A re-run reaches it because the user picked that
9
+ row from the menu.
10
+
11
+ The machine says what it can do, in the `host.browser.*` axes. This question asks
12
+ a different thing: which of those modes this project would like to use.
13
+
14
+ Offer only the modes the machine declares available. When the machine declares
15
+ none, offer all three and run the `host` skill first.
16
+
17
+ The block below is the full menu, not the question to ask word for word. Drop the
18
+ entry for any mode the machine declares unavailable, then ask the rest.
19
+
20
+ ```json
21
+ {
22
+ "question": "How will you connect a browser for frontend verification?",
23
+ "options": [
24
+ {"label": "Remote browser (Playwriter bridge)", "description": "Best experience – drive Chrome on your desktop/laptop via the Playwriter extension over SSH. Choose this if you develop on a remote VM."},
25
+ {"label": "Headless (automatic)", "description": "The frontend-verifier launches headless Chromium when needed. No setup required. Choose this for CI or if you don't need to see the browser."},
26
+ {"label": "Local with display", "description": "Launch a visible browser on this machine. Choose this for desktop Linux, macOS, or WSL with display access."},
27
+ {"label": "Skip for now", "description": "I'll set this up later – /acstack:host to declare what this machine can do, /acstack:setup for the project's preference"}
28
+ ]
29
+ }
30
+ ```
31
+
32
+ Write the answer as `remote`, `headless` or `local`. Write the port beside it:
33
+ `19988` for `remote`, and `9555` for the other two.
34
+
35
+ ```bash
36
+ ~/.claude/acstack/bin/acstack config set frontend.browser.mode remote
37
+ ~/.claude/acstack/bin/acstack config set frontend.browser.cdp_port 19988
38
+ ```
39
+
40
+ Then write `agent-browser.json` with the same port, the way Step 9c in `row-fixes.md` does.
41
+
42
+ On **Skip for now**, leave `frontend.browser` unset and write no
43
+ `agent-browser.json`. Say that `docs/config-reference.md` documents the three
44
+ keys for later.
45
+
46
+ On **Headless**, no setup follows. Tell the user the frontend verifier launches
47
+ headless Chromium when it needs one.
48
+
49
+ On **Local with display**, look for a Chromium binary. Tell the user the frontend
50
+ verifier launches it when it needs one.
51
+
52
+ On **Remote browser**, ask what the verifier does when the browser answers nothing:
53
+
54
+ ```json
55
+ {
56
+ "question": "When the remote browser isn't connected, what should the frontend-verifier do?",
57
+ "options": [
58
+ {"label": "Fall back to headless", "description": "Launch headless Chromium automatically. Verification still runs, just without your real browser."},
59
+ {"label": "Fail", "description": "Report FAIL so you know the bridge is down. Choose this if headless results aren't useful for your app."}
60
+ ]
61
+ }
62
+ ```
63
+
64
+ Write `frontend.browser.fallback` as `headless` for the first answer, and as
65
+ `none` for the second. Only `none` acts. It forbids another mode from standing
66
+ in.
67
+
68
+ Then go to Step 11.
69
+
70
+ ## Step 11: Connect the Playwriter bridge
71
+
72
+ This step is the one copy of the bridge setup. Step 10 reaches it on a `remote`
73
+ answer. Step 9 reaches it on a `browser-mode:remote` failure.
74
+
75
+ Remote mode drives Chrome through the Playwriter extension, which uses the
76
+ `chrome.debugger` API. Chrome itself opens no CDP listener. Show these steps:
77
+
78
+ ```
79
+ To connect your browser via the Playwriter bridge:
80
+
81
+ 1. On the browser machine, install Node 18+ and Playwriter:
82
+
83
+ npm install -g playwriter
84
+
85
+ 2. In Chrome on the browser machine (preferably a dedicated profile), install the Playwriter extension and pin it:
86
+
87
+ https://chromewebstore.google.com/detail/playwriter-mcp/jfeammnjpkecdekppnclgkkffahnhfhe
88
+
89
+ 3. Run two long-running processes on the browser machine:
90
+
91
+ Relay: playwriter serve --host 127.0.0.1
92
+ Reverse tunnel: ssh -N -R 19988:127.0.0.1:19988 <user>@<dev-machine>
93
+
94
+ 4. In Chrome, click the Playwriter toolbar icon on each tab you want automated.
95
+
96
+ 5. Verify from this (dev) machine:
97
+
98
+ curl -s http://localhost:19988/json/version
99
+ ```
100
+
101
+ Show these gotchas after the steps:
102
+
103
+ - Playwriter hardcodes port `19988`. Nobody can change it.
104
+ - The relay runs on the same host as Chrome. The extension rejects any
105
+ `/extension` client that is not `127.0.0.1`.
106
+
107
+ - Each tab needs the extension icon clicked once. Playwriter cannot attach to a
108
+ `chrome://` or `about:` page.
109
+
110
+ - A stale relay holds port 19988 on the browser machine. Run
111
+ `playwriter serve --host 127.0.0.1 --replace` to kick the previous one.
112
+
113
+ For a Windows laptop setup that opens no window, see
114
+ `plugins/acstack/docs/playwriter-bridge-windows.md`. It covers auto-reconnecting
115
+ scheduled tasks, ssh-agent key persistence and one-time admin registration. It
116
+ ships `relay.ps1`, `tunnel.ps1` and `register-tasks.ps1` under
117
+ `plugins/acstack/assets/playwriter-bridge/`.
118
+
119
+ Then re-run the health check from Step 7 and read the `browser-mode:remote` row.
120
+ It passes once something answers on the port.
121
+
122
+ Do not curl the port yourself. The check is the one place that probes the
123
+ machine.
@@ -0,0 +1,97 @@
1
+ # Setup: design review
2
+
3
+ `SKILL.md` decides when to read this file: Step 7 reported a `frontend-verification` row, so the project has a frontend and Step 13 runs from here.
4
+
5
+ ## Step 13: Offer the design review
6
+
7
+ The design review is two plugins working on the frontend:
8
+
9
+ - **open-designer** writes a design you can look at before anyone builds it
10
+ - **impeccable** reviews a UI change against the product's own design rules
11
+
12
+ ACStack needs neither, so this step offers and never assumes.
13
+
14
+ Ask it only of a project with a frontend. The health check in Step 7 reports a
15
+ `frontend-verification` row for those projects and for no others, so no such row
16
+ means no frontend. Go to Step 14.
17
+
18
+ Read what this project already decided:
19
+
20
+ ```bash
21
+ ~/.claude/acstack/bin/acstack config get workflow.design_review
22
+ ```
23
+
24
+ On exit 0 the user has already answered, either way. Say nothing and go to
25
+ Step 14.
26
+
27
+ On any exit other than 0 or 2 the CLI is older than this skill and does not know
28
+ the key. Do not ask, and do not try to write the key. Say this instead, then go
29
+ to Step 14:
30
+
31
+ ```
32
+ The acstack CLI on this machine predates workflow.design_review, so I cannot
33
+ record an answer. Restart your agent session to relink the CLI, then run
34
+ /acstack:setup again.
35
+ ```
36
+
37
+ The SessionStart hook repoints `~/.claude/acstack/bin/acstack` at every start,
38
+ so a restart is the whole fix.
39
+
40
+ On exit 2 nobody has answered yet. Ask once:
41
+
42
+ ```json
43
+ {
44
+ "question": "Turn on design review for this project's frontend?",
45
+ "header": "Design",
46
+ "options": [
47
+ {"label": "Yes", "description": "You then install two plugins: open-designer, which writes a design you can look at before anyone builds it, and impeccable, which reviews a UI change against the product's design rules. Both are reversible."},
48
+ {"label": "No", "description": "Leave this project as it is. Nothing in ACStack needs either plugin, and setup never asks again."}
49
+ ]
50
+ }
51
+ ```
52
+
53
+ Write the answer, whichever way it went:
54
+
55
+ ```bash
56
+ ~/.claude/acstack/bin/acstack config set workflow.design_review true # or false
57
+ ```
58
+
59
+ Write it before doing anything else. The answer is the user's, and two plugins
60
+ they never get round to installing must not bring the question back on the next
61
+ run.
62
+
63
+ On **Yes**, hand the install to the user. Print these lines, then go to Step 14:
64
+
65
+ ```
66
+ Recorded. Install the two plugins yourself – the installer is reserved for you
67
+ to start:
68
+
69
+ /plugin marketplace add ac8318740/ac-agentic-coding
70
+ /plugin install open-designer@ac-agentic-coding
71
+
72
+ /plugin marketplace add pbakaus/impeccable
73
+ /plugin install impeccable@impeccable
74
+
75
+ Then run /impeccable init once. It writes PRODUCT.md, the file the design
76
+ review reads.
77
+ ```
78
+
79
+ Three things this step never does:
80
+
81
+ - It never runs an install. Both plugins change what Claude Code loads, so the
82
+ user starts them.
83
+
84
+ - It never writes `PRODUCT.md`. `/impeccable init` owns that file, and a second
85
+ writer collides with it.
86
+
87
+ - It never copies a file out of impeccable. Setup names the plugin and stops
88
+ there.
89
+
90
+ `acstack config check` grows an `impeccable` row once the user installs the
91
+ plugin, so a later `/acstack:setup` run confirms the install landed.
92
+
93
+ On **No**, go straight to Step 14. Name neither plugin again, and do not ask
94
+ again.
95
+
96
+ The key records the answer, never the install. Setup writes it before the user
97
+ installs anything, so `true` never claims either plugin is here.
@@ -0,0 +1,114 @@
1
+ # Setup: first run
2
+
3
+ `SKILL.md` decides when to read this file: Step 2 found no `acstack/project.yaml`, so the first-run path runs Steps 3 to 6 from here.
4
+
5
+ The file keeps its schema on both paths, so nothing migrates. `docs/config-reference.md`
6
+ lists every key it can hold.
7
+
8
+ ## Step 3: Detect the project type and propose defaults
9
+
10
+ Scan the project root for `pyproject.toml`, `package.json`, `go.mod` and
11
+ `Cargo.toml`. If the root gives nothing away, infer the type from `$ARGUMENTS`.
12
+ Read the matching profile from the plugin's `profiles/` directory.
13
+
14
+ Show a summary:
15
+
16
+ ```
17
+ Profile: [detected]
18
+ Directories: src/, tests/
19
+ Commands: [from profile]
20
+ Frontend: [if applicable]
21
+ Workflow: strict TDD, strict orchestrator, spec sync on, grilling via question tool
22
+ ```
23
+
24
+ ## Step 4: Ask what to customise
25
+
26
+ Ask through the question tool (AskUserQuestion on Claude Code) with EXACTLY this
27
+ JSON. On a host without one, print the same questions and options as a
28
+ numbered list. It holds two questions in one call:
29
+
30
+ ```json
31
+ {
32
+ "questions": [
33
+ {
34
+ "question": "Customize project setup? Select items to change, or skip to keep defaults.",
35
+ "header": "Setup",
36
+ "multiSelect": true,
37
+ "options": [
38
+ {"label": "Profile & paths", "description": "Change language/framework, source dir, test dir"},
39
+ {"label": "Commands", "description": "Adjust test, build, lint, typecheck, format commands"},
40
+ {"label": "Frontend", "description": "Change directory, dev server, commands"}
41
+ ]
42
+ },
43
+ {
44
+ "question": "Customize workflow? Select items to change, or skip to keep defaults.",
45
+ "header": "Workflow",
46
+ "multiSelect": true,
47
+ "options": [
48
+ {"label": "Grilling", "description": "How grilling asks its questions – a question tool (default) or plain prose"},
49
+ {"label": "TDD strictness", "description": "Relaxed writes the tests after the code; all three phases still run"},
50
+ {"label": "Orchestrator", "description": "Allow direct code work instead of subagent delegation"},
51
+ {"label": "Spec sync", "description": "Disable automatic spec sync on commit"}
52
+ ]
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ Read `answers["0"]` as the setup selections and `answers["1"]` as the workflow
59
+ selections. An empty selection means the defaults stand.
60
+
61
+ ## Step 5: Customise the selected sections
62
+
63
+ Ask one follow-up question at a time through the question tool. Skip every item the
64
+ user did not select.
65
+
66
+ - **Profile & paths** – ask the language or framework, then the source and test
67
+ directories.
68
+
69
+ - **Commands** – show the proposed commands and ask what to adjust.
70
+ - **Frontend** – show the proposed frontend settings and ask what to adjust.
71
+ - **Grilling** – ask `tool`, the host's question tool, against `inline` prose.
72
+ Recommend `tool`. It writes `workflow.grilling.questions`.
73
+
74
+ - **TDD strictness** – ask strict against relaxed, and write
75
+ `workflow.tdd.strict`.
76
+
77
+ Strict runs the test-writer first, so the tests exist before the code.
78
+ Relaxed runs the task-executor first and the test-writer after it. Relaxed
79
+ drops no phase, and all three agents run under both.
80
+
81
+ Recommend strict, because the relaxed test-writer works beside an
82
+ implementation it must not read.
83
+
84
+ - **Orchestrator** – ask strict against relaxed.
85
+ - **Spec sync** – ask enabled against disabled.
86
+ - **Python venv** – ask the activation command. Ask it only for a Python profile.
87
+
88
+ Leave the whole `frontend.browser` block out here. Step 10 owns it, and both
89
+ paths reach Step 10 through the health check.
90
+
91
+ ## Step 6: Write the config
92
+
93
+ 1. Create the `acstack/` directory.
94
+ 2. Write `acstack/project.yaml` from the profile and the answers.
95
+ 3. Leave the project CLAUDE.md alone. The SessionStart hook loads the
96
+ orchestrator instructions.
97
+
98
+ 4. Remove a legacy `@import` line from the project CLAUDE.md, if one is there.
99
+ It points at `.../plugins/cache/ac8318740-plugins/acstack/<version>/CLAUDE.md`.
100
+
101
+ Then go to Step 7. Everything a fresh project still lacks shows up there as a
102
+ failing row.
103
+
104
+ ## What Steps 7 and 8 show after a first run
105
+
106
+ A `no-project` row means Step 6 wrote no config. Go back to Step 3 and write it.
107
+
108
+ On a first run the menu carries several rows, and only one of them failed. A
109
+ fresh project has no domain map, so `domain-map` fails. It selects no output
110
+ style, so `output-style` reports `info`.
111
+
112
+ A fresh project that configures a frontend adds `preferred-browser-mode` and
113
+ `frontend-verification`, both `info` as well, because it has named no browser
114
+ mode and turned no verification on.