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,292 @@
1
+ # Playwriter bridge – Linux / VM runbook
2
+
3
+ > Stop reading if you are on Windows. This file is bash-only and assumes a
4
+ > Linux or macOS shell. Windows agents: read
5
+ > [`SKILL-WINDOWS.md`](SKILL-WINDOWS.md) instead.
6
+
7
+ ## What the VM side owns
8
+
9
+ - An SSH service that accepts a reverse forward from the laptop and
10
+ binds `127.0.0.1:19988` on this host.
11
+
12
+ - `agent-browser` (installed per the `browser-verify` skill) pointed at
13
+ that endpoint via `agent-browser.json`.
14
+
15
+ - `vm-free-port.sh` for clearing a stuck port 19988 after a dropped
16
+ session.
17
+
18
+ - An optional `sshd_config` tweak that reaps dead client sessions
19
+ naturally.
20
+
21
+ The VM does **not** run the relay and does **not** run Chrome. Those
22
+ live on the laptop. See [`SKILL-WINDOWS.md`](SKILL-WINDOWS.md) if you
23
+ need to understand what the other side is doing.
24
+
25
+ ## Architecture (from the VM's viewpoint)
26
+
27
+ ```
28
+ laptop opens:
29
+ ssh -N -R 19988:127.0.0.1:19988 <you>@<this-vm>
30
+
31
+ sshd on this VM then binds 127.0.0.1:19988 and forwards it back to the
32
+ laptop's 127.0.0.1:19988, where the Playwriter relay is listening.
33
+
34
+ agent-browser on this VM then speaks CDP against
35
+ http://127.0.0.1:19988
36
+ and is driving a real Chrome on the laptop.
37
+ ```
38
+
39
+ ## Setup (once per VM)
40
+
41
+ ### 1. Install agent-browser
42
+
43
+ See the `browser-verify` skill for the install command.
44
+
45
+ ### 2. Create `agent-browser.json` in each project root
46
+
47
+ ```json
48
+ { "cdp": "19988" }
49
+ ```
50
+
51
+ ### 3. Accept the laptop's key
52
+
53
+ Append the laptop's SSH public key to `~/.ssh/authorized_keys`.
54
+
55
+ If the Windows side asks for a handoff to fix this (they typically will
56
+ during initial setup), confirm by running on this VM:
57
+
58
+ ```bash
59
+ ssh-keygen -l -f ~/.ssh/authorized_keys | tail
60
+ ```
61
+
62
+ and pasting the tail output back to the Windows agent as the handoff
63
+ "Report back".
64
+
65
+ ### 4. Enable server-side keepalive (required for self-heal)
66
+
67
+ When the laptop drops abruptly (sleep, network change, VPN flap), the
68
+ half-open SSH session leaves an `sshd` forward channel bound to port
69
+ 19988, now orphaned. The VM only releases it once `sshd` reaps the
70
+ dead client, which takes `ClientAliveInterval × ClientAliveCountMax`
71
+ seconds. Until then the laptop's reconnect hits
72
+ `remote port forwarding failed`.
73
+
74
+ The Windows `tunnel.ps1` retries a stuck port forever. It waits 30 s, then
75
+ doubles the wait to a 120 s cap. The bridge therefore self-heals whenever
76
+ the reap happens.
77
+
78
+ What keepalive changes is how long that takes:
79
+
80
+ - **Keepalive disabled** (`ClientAliveInterval 0`) – the orphan never reaps
81
+ and the port stays wedged until someone frees it by hand. The tunnel
82
+ keeps retrying, and writes `tunnel-<host>[-<port>].stuck` after 8
83
+ consecutive stuck attempts (~11 min) so `doctor.ps1` reports it in red.
84
+
85
+ Run `vm-free-port.sh` and the next attempt binds. You restart nothing.
86
+
87
+ - **Keepalive very loose** – recovery is slow. A default Azure / cloud
88
+ image ships `ClientAliveInterval 120` (≈360 s reap); the runbook value
89
+ of 30 (≈90 s) recovers about 4× faster.
90
+
91
+ Check the *effective* value. This needs root – the drop-in files under
92
+ `sshd_config.d/` are not world-readable, so a non-root `sshd -T` prints
93
+ nothing useful:
94
+
95
+ ```bash
96
+ sudo sshd -T | grep -E '^(clientaliveinterval|clientalivecountmax)'
97
+ ```
98
+
99
+ Want:
100
+
101
+ ```
102
+ clientaliveinterval 30
103
+ clientalivecountmax 3
104
+ ```
105
+
106
+ **Do not just append to `/etc/ssh/sshd_config`.** Cloud images set this
107
+ in a drop-in (e.g. `/etc/ssh/sshd_config.d/50-cloudimg-settings.conf`),
108
+ and sshd uses the *first* value it reads. The
109
+ `Include /etc/ssh/sshd_config.d/*.conf` line sits near the top of the
110
+ main config and globs in lexical order, so a later append loses to the
111
+ existing `50-` drop-in.
112
+
113
+ Win by adding a drop-in that sorts *before* it:
114
+
115
+ ```bash
116
+ printf 'ClientAliveInterval 30\nClientAliveCountMax 3\n' | \
117
+ sudo tee /etc/ssh/sshd_config.d/10-playwriter-keepalive.conf
118
+ sudo systemctl reload ssh || sudo systemctl reload sshd
119
+ ```
120
+
121
+ Re-run the `sudo sshd -T` check. Confirm it now reports 30 / 3.
122
+
123
+ If it still shows the loose value, this distro orders `Include`
124
+ differently. Edit the drop-in that set it instead of adding a new one.
125
+
126
+ ### 5. The SessionStart hook auto-links `vm-free-port.sh`
127
+
128
+ The ACStack SessionStart hook links the helper to an invariant path on
129
+ each Claude Code launch:
130
+
131
+ ```
132
+ ~/.claude/acstack/bin/vm-free-port.sh -> <plugin cache>/assets/playwriter-bridge/vm-free-port.sh
133
+ ```
134
+
135
+ Invoke it by that path. The symlink always points at the current plugin
136
+ version, so the helper stays current with no manual copy. If you prefer a
137
+ copy on your `PATH` instead, copy the file and `chmod +x` it – but then you
138
+ own keeping it updated.
139
+
140
+ The script has a guardrail: it refuses to kill the port holder if that
141
+ holder is your own interactive SSH session. The guardrail scopes it
142
+ strictly to port 19988.
143
+
144
+ ## Routine diagnostics on the VM
145
+
146
+ ### Is the tunnel up?
147
+
148
+ ```bash
149
+ ss -lnt 'sport = :19988'
150
+ ```
151
+
152
+ If empty: the tunnel from the laptop has not connected. Produce a
153
+ VM-side handoff to the Windows agent – see [`HANDOFF.md`](HANDOFF.md).
154
+
155
+ ### Does the relay respond?
156
+
157
+ ```bash
158
+ curl -sS -m 3 http://127.0.0.1:19988/json/version
159
+ ```
160
+
161
+ Playwriter-flavored JSON means the full path (tunnel + relay) is up.
162
+ Empty or timeout with a listener present on 19988 means the tunnel is
163
+ half-open – ask the Windows side to restart the tunnel task.
164
+
165
+ ### Is the extension armed?
166
+
167
+ ```bash
168
+ curl -sS -m 3 http://127.0.0.1:19988/json/list
169
+ ```
170
+
171
+ `[]` means the extension has not attached to any tab. Ask the user to
172
+ click the Playwriter icon on a normal web page in the Playwriter Dev
173
+ Chrome profile. (This is a user action, not a coding-agent one, unless
174
+ a Windows agent is available to drive Chrome.)
175
+
176
+ ### Smoke test
177
+
178
+ ```bash
179
+ agent-browser open https://example.com
180
+ agent-browser screenshot /tmp/ok.png
181
+ ```
182
+
183
+ ## When port 19988 is stuck
184
+
185
+ Symptom: the Windows `tunnel-<this-host>.log` shows
186
+ `remote port forwarding failed for listen port 19988` repeatedly, or
187
+ `ss -lnt 'sport = :19988'` shows an `sshd` bound but the relay is
188
+ unreachable.
189
+
190
+ The Windows agent sees this first. `doctor.ps1` turns its `Tunnel logs` row
191
+ amber as soon as `tunnel-*.log` carries a `stuck-retry` line under 5 minutes
192
+ old. The row names the host and the port. It goes red later, once the `.stuck`
193
+ marker file lands.
194
+
195
+ Either colour gives you the same instruction below.
196
+
197
+ Run:
198
+
199
+ ```bash
200
+ bash ~/.claude/acstack/bin/vm-free-port.sh
201
+ ```
202
+
203
+ The script walks the situation and either clears the socket or refuses
204
+ with a clear reason. Common outcomes:
205
+
206
+ - **"port 19988 is already free"** – nothing to do. The Windows tunnel
207
+ should reconnect within the backoff window.
208
+
209
+ - **"port is held by your own interactive session"** – you have an SSH
210
+ session alive that is carrying the forward. Exit that session (from
211
+ another terminal) and re-run.
212
+
213
+ - **Holder is a non-`sshd` process** – the script refuses. Something
214
+ else (local test server, stray `nc`) is on 19988. Stop it manually.
215
+
216
+ - **Holder is an `sshd` forward channel, now orphaned** – the script
217
+ kills it. `ClientAliveInterval` would have prevented this; consider
218
+ adding the config from step 4.
219
+
220
+ - **"port 19988 is carrying a live tunnel"** – the script refuses and exits
221
+ non-zero without killing anything. Before it looks at the holder at all it
222
+ asks the port for an HTTP response, bounded at 3 seconds.
223
+
224
+ Any answer counts as alive. It asks the port rather than the process
225
+ because a non-root `ss` cannot name who owns someone else's socket.
226
+
227
+ A 401 or a 404 still means something is serving. Only silence means a
228
+ half-open forward.
229
+
230
+ That last refusal matters because the amber `Tunnel logs` row trails five
231
+ minutes behind the log line that raised it.
232
+
233
+ A tunnel often wedges and then heals itself while the row stays amber. So
234
+ you usually reach this script after the forward has already healed.
235
+ Running it then costs nothing.
236
+
237
+ No flag overrides the refusal. To free a port that a live forward holds,
238
+ close the session holding it. On the laptop, run `stop.ps1`.
239
+
240
+ After clearing, confirm:
241
+
242
+ ```bash
243
+ ss -lnt 'sport = :19988'
244
+ ```
245
+
246
+ Should be empty.
247
+
248
+ ## What you CANNOT do from the VM
249
+
250
+ - **Rearm the extension on a tab.** That is a click in the user's Chrome,
251
+ inside a third-party extension. Nothing on either machine can press it.
252
+
253
+ - **Restart the relay or a tunnel task.** Both are Windows-side scheduled
254
+ tasks. The VM reaches them only when the opener is up, which the next
255
+ section covers.
256
+
257
+ For anything left, produce a `VM-SIDE HANDOFF` block per
258
+ [`HANDOFF.md`](HANDOFF.md). Hand it to the Windows agent, or tell the
259
+ user to paste it into PowerShell themselves.
260
+
261
+ ## Restarting the laptop's tasks from here
262
+
263
+ When the **opener** is up, the restart above is no longer a handoff.
264
+
265
+ The opener is a small service on the laptop. It takes a page from the VM and
266
+ puts it in the default browser there. Because it runs on the laptop, it can also
267
+ restart the scheduled tasks the VM cannot reach.
268
+
269
+ See section 9.5, "The opener", of `docs/terminal-workspace.md`.
270
+
271
+ ```bash
272
+ acstack-bridge status # both machines' view, including the tasks
273
+ acstack-bridge fix [relay|tunnel|both]
274
+ ```
275
+
276
+ `fix` reports success only once the relay answers on the VM again. The opener
277
+ can accept a restart request while the bridge is still down. That is why `fix`
278
+ waits for the relay itself, rather than trusting the opener's reply.
279
+
280
+ When the opener is unreachable too, `acstack-bridge` prints the
281
+ `VM-SIDE HANDOFF` block for you rather than leaving you to write one.
282
+
283
+ The opener still does not cover arming. Nothing changes that.
284
+
285
+ ## What this intentionally does NOT do
286
+
287
+ - **No relay on the VM.** The Playwriter extension hard-rejects any
288
+ `/extension` client that is not `127.0.0.1`, so the relay must run
289
+ next to Chrome.
290
+
291
+ - **No unprompted port scan.** `vm-free-port.sh` scopes itself strictly
292
+ to 19988 and refuses anything ambiguous. Do not generalise it.