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.
- package/.claude-plugin/plugin.json +19 -0
- package/LICENSE +21 -0
- package/README.md +389 -2
- package/THIRD_PARTY_NOTICES +14 -0
- package/TROUBLESHOOTING.md +225 -0
- package/agents/codex/frontend-verifier.toml +352 -0
- package/agents/codex/task-checker.toml +345 -0
- package/agents/codex/task-executor.toml +157 -0
- package/agents/codex/test-writer.toml +149 -0
- package/agents/frontend-verifier.md +351 -0
- package/agents/task-checker.md +344 -0
- package/agents/task-executor.md +156 -0
- package/agents/test-writer.md +148 -0
- package/assets/playwriter-bridge/build-launcher.ps1 +32 -0
- package/assets/playwriter-bridge/doctor.ps1 +450 -0
- package/assets/playwriter-bridge/launcher-src.cs +131 -0
- package/assets/playwriter-bridge/opener.js +330 -0
- package/assets/playwriter-bridge/opener.ps1 +63 -0
- package/assets/playwriter-bridge/register-tasks.ps1 +328 -0
- package/assets/playwriter-bridge/relay.ps1 +50 -0
- package/assets/playwriter-bridge/stop.ps1 +125 -0
- package/assets/playwriter-bridge/sync.ps1 +271 -0
- package/assets/playwriter-bridge/tunnel.ps1 +325 -0
- package/assets/playwriter-bridge/vm-free-port.sh +166 -0
- package/assets/terminal-workspace/client-keybindings.md +87 -0
- package/assets/terminal-workspace/config.example.yaml +329 -0
- package/assets/terminal-workspace/setup.sh +4317 -0
- package/cli/README.md +47 -0
- package/cli/bin/acstack.js +3 -0
- package/cli/dist/index.js +25984 -0
- package/cli/dist/index.js.map +7 -0
- package/cli/package.json +59 -0
- package/docs/adr/0001-ste-writing-standard.md +16 -0
- package/docs/adr/0002-version-gate-not-auto-bump.md +35 -0
- package/docs/adr/0003-handoff-ack-command.md +19 -0
- package/docs/adr/0004-dev-setup-per-host.md +13 -0
- package/docs/adr/0005-two-orchestrators-per-host.md +25 -0
- package/docs/adr/0006-document-opener-service.md +89 -0
- package/docs/adr/0007-lead-check-reads-the-transcript.md +87 -0
- package/docs/adr/0008-cli-audits-skill-interviews.md +37 -0
- package/docs/adr/0009-verify-the-write-not-the-writer.md +51 -0
- package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +115 -0
- package/docs/adr/0011-node-header-is-the-edge-encoding.md +20 -0
- package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +31 -0
- package/docs/adr/0013-the-diagram-renderer-is-pure.md +23 -0
- package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +29 -0
- package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +37 -0
- package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +21 -0
- package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +13 -0
- package/docs/adr/index.md +17 -0
- package/docs/config-reference.md +572 -0
- package/docs/dev-setups.md +164 -0
- package/docs/migrate-0.8.md +28 -0
- package/docs/playwriter-bridge-windows.md +15 -0
- package/docs/terminal-workspace-keys.md +137 -0
- package/docs/terminal-workspace.md +1774 -0
- package/docs/workflows.md +309 -0
- package/hooks/ac-writing-style-reminder.sh +86 -0
- package/hooks/context-pressure.sh +583 -0
- package/hooks/hooks.json +50 -0
- package/hooks/session-start-handoff.sh +165 -0
- package/hooks/session-start.sh +214 -0
- package/orchestrator/AGENTS.md +532 -0
- package/output-styles/ac-writing-style.md +286 -0
- package/package.json +50 -4
- package/pi/agents/frontend-verifier.md +357 -0
- package/pi/agents/task-checker.md +348 -0
- package/pi/agents/task-executor.md +160 -0
- package/pi/agents/test-writer.md +154 -0
- package/pi/extension.ts +723 -0
- package/profiles/fullstack-python.yaml +29 -0
- package/profiles/node-typescript.yaml +23 -0
- package/profiles/python.yaml +24 -0
- package/skills/archive/SKILL.md +160 -0
- package/skills/bootstrap/SKILL.md +109 -0
- package/skills/bridge/HANDOFF.md +93 -0
- package/skills/bridge/SKILL-VM.md +292 -0
- package/skills/bridge/SKILL-WINDOWS.md +526 -0
- package/skills/bridge/SKILL.md +121 -0
- package/skills/browser-verify/SKILL.md +229 -0
- package/skills/code-review/SKILL.md +44 -0
- package/skills/commit/SKILL.md +106 -0
- package/skills/compact-and-continue/SKILL.md +241 -0
- package/skills/explore/SKILL.md +149 -0
- package/skills/grilling/SKILL.md +134 -0
- package/skills/handoff/SKILL.md +250 -0
- package/skills/handoff/launch-herdr.md +197 -0
- package/skills/handoff/launch-without-herdr.md +30 -0
- package/skills/handoff/lead-check.md +59 -0
- package/skills/handoff/outcomes.md +162 -0
- package/skills/handoff/running-agent.md +50 -0
- package/skills/handoff/watch.md +115 -0
- package/skills/host/SKILL.md +247 -0
- package/skills/host/detect-host.sh +297 -0
- package/skills/host/herdr.md +79 -0
- package/skills/host/install-herdr-block.sh +467 -0
- package/skills/host/install-orca.sh +512 -0
- package/skills/host/notes.md +97 -0
- package/skills/host/orca.md +160 -0
- package/skills/host/questions.md +163 -0
- package/skills/host/report.md +42 -0
- package/skills/implement/SKILL.md +230 -0
- package/skills/implement/decision-log.md +62 -0
- package/skills/implement/design-pass.md +32 -0
- package/skills/implement/relaxed-tdd.md +28 -0
- package/skills/map/SKILL.md +250 -0
- package/skills/map/frontend.md +227 -0
- package/skills/map/trackers/files.md +74 -0
- package/skills/map/trackers/github.md +180 -0
- package/skills/map/visuals.md +387 -0
- package/skills/new-worktree/SKILL.md +155 -0
- package/skills/new-worktree/detect-orchestrator.sh +328 -0
- package/skills/new-worktree/detect-orchestrator.test.sh +894 -0
- package/skills/new-worktree/herdr.md +84 -0
- package/skills/new-worktree/orca.md +101 -0
- package/skills/pre-commit-review/SKILL.md +242 -0
- package/skills/pre-commit-review/auto-fix.md +19 -0
- package/skills/pre-commit-review/interactive.md +35 -0
- package/skills/quick-fix/SKILL.md +125 -0
- package/skills/record-context/SKILL.md +106 -0
- package/skills/setup/SKILL.md +250 -0
- package/skills/setup/browser.md +123 -0
- package/skills/setup/design-review.md +97 -0
- package/skills/setup/first-run.md +114 -0
- package/skills/setup/report.md +68 -0
- package/skills/setup/row-fixes.md +196 -0
- package/skills/setup/terminal-workspace.md +153 -0
- package/skills/sync/SKILL.md +171 -0
- package/skills/teardown-worktree/SKILL.md +245 -0
- package/skills/teardown-worktree/detector.md +39 -0
- package/skills/teardown-worktree/herdr.md +113 -0
- package/skills/teardown-worktree/orca.md +61 -0
- package/skills/terminal-workspace/SKILL.md +249 -0
- package/skills/terminal-workspace/components.md +36 -0
- package/skills/terminal-workspace/config-choices.md +69 -0
- package/skills/terminal-workspace/emulator-keys.md +48 -0
- package/skills/terminal-workspace/headless-clipboard.md +175 -0
- package/skills/terminal-workspace/turn-off-and-update.md +104 -0
- package/skills/test-conventions/SKILL.md +59 -0
- package/skills/visual-docs/SKILL.md +246 -0
- package/skills/writing/SKILL.md +231 -0
- package/skills/writing/examples.md +153 -0
- 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.
|