acstack 0.0.0-stage → 0.47.1

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 +334 -0
  27. package/assets/terminal-workspace/setup.sh +4404 -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 +1780 -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,68 @@
1
+ # Setup: report
2
+
3
+ `SKILL.md` decides when to read this file: every run ends at Step 14, and it runs from here.
4
+
5
+ ## Step 14: Report
6
+
7
+ Run the health check one last time, then report what stands:
8
+
9
+ ```
10
+ ## ACStack setup
11
+
12
+ Profile: [profile]
13
+ Source: [source dir]
14
+ Tests: [tests dir]
15
+ Grilling: [question tool/inline prose]
16
+ TDD: [strict/relaxed]
17
+ Orchestrator: [strict/relaxed]
18
+ Spec sync: [enabled/disabled]
19
+ Frontend: [configured/not configured]
20
+ Browser: [project's preferred mode / not configured]
21
+ Design: [on / off / not asked]
22
+ Host: [orchestrators + browser modes declared / not declared]
23
+ Workspace: [yes / yes, n updates available / not installed / declined / not asked]
24
+ Config: acstack/project.yaml
25
+ Domain map: acstack/domain-map.yaml ([n] domains / starter – fill in)
26
+ Output style: acstack:ac-writing-style (global) | (project) | not set
27
+
28
+ Health check: [n] pass, [n] fail, [n] info
29
+
30
+ Next: describe what you want to build, or run /acstack:bootstrap for existing code.
31
+ ```
32
+
33
+ Fill the `Host:` line and the `Orchestrator:` line from two different sources.
34
+ `Orchestrator:` is this project's delegation policy, read from
35
+ `workflow.tdd.orchestrator_strict` in `acstack/project.yaml`. It says whether
36
+ the coordinator may write code itself. `Host:` is about the machine. It names
37
+ which tool owns terminal panes and git worktrees, and which browser modes work
38
+ here.
39
+
40
+ The `host` skill declares both, and the global config holds them.
41
+
42
+ Fill `Workspace:` from `host.terminal_workspace`: `yes` on `true`, `declined` on
43
+ `false`, and `not asked` when it is unset.
44
+
45
+ The key records the answer, never the install. Setup writes it before anyone
46
+ runs the installer, so `yes` never claims this machine has the workspace. When
47
+ Step 12 asked in this run and the user said Yes, write `yes – run
48
+ /acstack:terminal-workspace` so the owed command stays on screen.
49
+
50
+ Two rows come from what `outdated` found in Step 12. Write `yes, n updates
51
+ available` when it reported stale or new components, with `n` as the number of
52
+ findings. Write `not installed` when it reported a `missing` row and the user
53
+ declined to install it.
54
+
55
+ Fill `Design:` from `workflow.design_review` and the `impeccable` row together:
56
+
57
+ - `on` when the key is `true` and the row is there
58
+ - `on – install open-designer and impeccable` when the key is `true` and no row
59
+ is there
60
+
61
+ - `off` when the key is `false`
62
+ - `not asked` when the key states nothing, or the project has no frontend
63
+
64
+ That key records the answer too, never the install. The `impeccable` row is the
65
+ only thing here that reports what the machine has, so `on` alone never claims a
66
+ plugin the user has yet to install.
67
+
68
+ List every row still failing under the summary. Name the row and what it needs.
@@ -0,0 +1,196 @@
1
+ # Setup: row fixes
2
+
3
+ `SKILL.md` decides when to read this file: Step 9 is fixing a `browser-mode:<mode>`, `frontend-verification`, `domain-map`, `agent-browser`, `agent-browser-json`, `verification-knowledge` or `output-style` row.
4
+
5
+ Five rows describe the machine: `required-axis`, `orchestrator`, `browser-mode`,
6
+ `preferred-browser-mode` and `optional-axis`. Invoke the `host` skill for each of
7
+ them, with one exception: `optional-axis:host.terminal_workspace` is Step 12's
8
+ question, and the `host` skill never asks it. It is safe to re-run, and it starts from the current answers.
9
+
10
+ A `preferred-browser-mode` row is the exception. It goes to the `host` skill only
11
+ on a `fail`, and to Step 10 on an `info`.
12
+
13
+ One row has second fixes: `browser-mode:<mode>`. Which one applies depends on the
14
+ mode, and for two of the three modes the `host` skill is no fix at all.
15
+
16
+ A `browser-mode:remote` failure says the machine declares the remote mode and
17
+ nothing answered on the port. If the machine really does drive a browser that
18
+ way, the bridge is down, so run Step 11. If it does not, the axis is wrong, so
19
+ run the `host` skill.
20
+
21
+ A `browser-mode:headless` or `browser-mode:local` failure says one thing and
22
+ nothing else: the machine declares the mode and no Chromium or Chrome binary sits
23
+ on PATH. The axis is right and the machine is short a browser. Re-running the
24
+ host interview changes nothing here, and answering the axis false records a lie
25
+ about what this machine can do.
26
+
27
+ Offer to install the browser instead:
28
+
29
+ ```bash
30
+ sudo apt install chromium-browser # Ubuntu/Debian
31
+ sudo dnf install chromium # Fedora
32
+ ```
33
+
34
+ Then re-run the health check from Step 7. The row passes once the binary is on
35
+ PATH.
36
+
37
+ A `frontend-verification` row needs no step of its own. The project configures a
38
+ frontend and has not turned browser verification on. Turn it on:
39
+
40
+ ```bash
41
+ ~/.claude/acstack/bin/acstack config set workflow.frontend_verification true
42
+ ```
43
+
44
+ `docs/config-reference.md` documents the key.
45
+
46
+ ### 9a. Generate the domain map
47
+
48
+ `acstack/domain-map.yaml` maps source paths to spec domains. Spec sync,
49
+ `/acstack:archive`, `/acstack:bootstrap` and `/acstack:pre-commit-review` all
50
+ read it. Without it, every path through spec sync skips in silence, and the
51
+ living specs never update.
52
+
53
+ Launch an **Explore subagent** over `directories.source` to propose domains. Ask
54
+ it for the top-level functional areas. Ask for a kebab-case name, the paths that
55
+ belong to it, and one line saying what it owns.
56
+
57
+ Guidance for the subagent:
58
+
59
+ - Group by responsibility, not by layer. Use `auth`, `billing` and `search`,
60
+ never `models`, `controllers` and `utils`.
61
+
62
+ - Prefer a directory prefix over a file list. Consumers match a path as a prefix.
63
+ - Aim for 3 to 10 domains. Fewer, and spec sync cannot tell two changes apart.
64
+ More, and every commit touches several.
65
+
66
+ - Leave tests, config, build files and docs unmapped. Consumers skip a path that
67
+ no domain covers.
68
+
69
+ If `acstack/specs/` already holds domain directories, propose those names first
70
+ and map the paths onto them. Renaming a domain here orphans its `spec.md`.
71
+
72
+ Print the proposal and confirm it with the question tool (AskUserQuestion on Claude Code). Ask "Use this domain map,
73
+ or adjust it?" and offer "Use it" against "Adjust (I'll give feedback)".
74
+
75
+ Then write the file:
76
+
77
+ ```yaml
78
+ # Domain Map: maps source paths to spec domains
79
+ # Read by spec sync, /acstack:archive, /acstack:bootstrap
80
+
81
+ domains:
82
+ <domain-name>:
83
+ paths:
84
+ - <path prefix>
85
+ description: <what this domain owns>
86
+ ```
87
+
88
+ A greenfield project has no code to group. Say so, write the header with one
89
+ commented example under `domains:`, and invent nothing. Tell the user to fill it
90
+ in, or to run `/acstack:setup` again once there is code to map.
91
+
92
+ ### 9b. Install the browser driver
93
+
94
+ `agent-browser` is the command line tool the frontend verifier drives a browser
95
+ with. Offer to install it:
96
+
97
+ ```bash
98
+ npm install -g agent-browser
99
+ ```
100
+
101
+ ### 9c. Write agent-browser.json
102
+
103
+ This file tells `agent-browser` which port to dial. Write it in the project root:
104
+
105
+ ```json
106
+ {"cdp": "<cdp_port>"}
107
+ ```
108
+
109
+ Take `<cdp_port>` from `frontend.browser.cdp_port` in `acstack/project.yaml`. With
110
+ no value there, the default is `19988` under `mode: remote` and `9555` otherwise.
111
+ The row fails when the two files name different ports, so change one of them.
112
+
113
+ ### 9d. Create the knowledge base for verification
114
+
115
+ The frontend verifier keeps what it learns in `VERIFICATION-KNOWLEDGE.md`, under
116
+ the directory `frontend.helpers_dir` names. If that key states nothing, ask for a
117
+ directory and write the key first. Then create the file:
118
+
119
+ ```markdown
120
+ # Verification Knowledge Base
121
+
122
+ Evolving reference for browser-based verification. Updated by the frontend-verifier agent after each run.
123
+
124
+ ## URL Patterns
125
+
126
+ <!-- Add URL patterns and routing rules here -->
127
+
128
+ ## Element Patterns
129
+
130
+ <!-- Add stable element identifiers discovered during testing.
131
+ Prefer data-testid attributes – they survive refactors.
132
+ Record the accessible name/role from agent-browser snapshots. -->
133
+
134
+ ## Gotchas & Lessons Learned
135
+
136
+ <!-- Add issues and workarounds discovered during testing -->
137
+
138
+ ## Proven Verification Sequences
139
+
140
+ <!-- Add step sequences that work reliably.
141
+ Example: "To verify login: open /login, snapshot, fill @username, fill @password, click @submit, wait 2s, snapshot again, check for dashboard heading" -->
142
+ ```
143
+
144
+ ### 9e. Offer the writing output style
145
+
146
+ The plugin ships an output style. Claude Code names it `acstack:ac-writing-style`.
147
+ It applies the `writing` skill's plain-language rules to every chat reply.
148
+
149
+ Offer it. Never set it without asking.
150
+
151
+ The row's message names which of the three settings files selects a style, and
152
+ which style it selects. `.claude/settings.local.json` wins over
153
+ `.claude/settings.json`, which wins over `~/.claude/settings.json`.
154
+
155
+ Ask once:
156
+
157
+ ```json
158
+ {
159
+ "question": "Apply the acstack:ac-writing-style output style?",
160
+ "options": [
161
+ {"label": "Global (recommended)", "description": "Write outputStyle into ~/.claude/settings.json, so it applies in every project"},
162
+ {"label": "This project only", "description": "Write outputStyle into .claude/settings.local.json, which overrides the global value here"},
163
+ {"label": "Skip", "description": "Leave the output style as it is"}
164
+ ]
165
+ }
166
+ ```
167
+
168
+ Load the chosen file as JSON, set the one key, then write it back. Use `python3`
169
+ or `jq`. Never edit the file with a regular expression, because that corrupts the
170
+ other keys.
171
+
172
+ Stop and report a file holding malformed JSON. Do not overwrite it.
173
+
174
+ ```bash
175
+ python3 - <<'PY'
176
+ import json, pathlib, sys
177
+ f = pathlib.Path("~/.claude/settings.json").expanduser() # or .claude/settings.local.json
178
+ f.parent.mkdir(parents=True, exist_ok=True)
179
+ try:
180
+ data = json.loads(f.read_text()) if f.exists() else {}
181
+ except json.JSONDecodeError:
182
+ sys.exit(f"{f}: malformed JSON, aborting")
183
+ data["outputStyle"] = "acstack:ac-writing-style"
184
+ f.write_text(json.dumps(data, indent=2) + "\n")
185
+ PY
186
+ ```
187
+
188
+ If the user chose global and a project file also sets `outputStyle`, say so. The
189
+ project value overrides the global one, so offer to remove that key.
190
+
191
+ Tell the user the style applies after `/clear`, or in a new session. Say that
192
+ `/config` -> Output style writes project scope only, which is why this step
193
+ offers the global path. Source: https://code.claude.com/docs/en/output-styles.md.
194
+
195
+ Claude Code has no command line flag for this. `claude config` does not exist,
196
+ and Claude Code dropped the `/output-style` command. Do not invent either.
@@ -0,0 +1,153 @@
1
+ # Setup: terminal workspace
2
+
3
+ `SKILL.md` decides when to read this file: every run reaches Step 12, and it runs from here.
4
+
5
+ ## Step 12: Offer the terminal workspace
6
+
7
+ The terminal workspace runs several coding agents side by side in one terminal,
8
+ on a machine the user reaches over the network. It installs herdr and the tools
9
+ that read diffs, pull requests and files around it.
10
+
11
+ ACStack needs none of it, so this step offers and never assumes.
12
+
13
+ Read what this machine already decided:
14
+
15
+ ```bash
16
+ ~/.claude/acstack/bin/acstack config get host.terminal_workspace
17
+ ```
18
+
19
+ On exit 0 the user has already answered. Read which way it went:
20
+
21
+ - On `false`, say nothing and go to Step 13
22
+ - On `true`, check whether the workspace on this machine has fallen behind
23
+
24
+ ```bash
25
+ PLUGIN=$(dirname "$(dirname "$(dirname "$(readlink -f ~/.claude/acstack/bin/acstack)")")")
26
+ SETUP="$PLUGIN/assets/terminal-workspace/setup.sh"
27
+ bash "$SETUP" outdated
28
+ ```
29
+
30
+ Resolve the script rather than guessing its path. The SessionStart hook
31
+ repoints that CLI symlink at every start, so it names the newest installed
32
+ version. The `terminal-workspace` skill resolves the same script the same
33
+ way.
34
+
35
+ If the file is not there, say nothing and go to Step 13.
36
+
37
+ Act on what `outdated` returned:
38
+
39
+ - **Exit 0** – nothing has moved on. Say nothing and go to Step 13
40
+ - **Exit 2** – it cannot tell. Say one line naming why, then go to Step 13
41
+ - **Exit 1** – there is something to do. Show the findings verbatim, one per line, then ask once
42
+
43
+ A user deciding whether to spend two minutes on downloads needs to see what the
44
+ findings are.
45
+
46
+ Exit 1 with no tab-separated row is an older script printing its usage for a
47
+ subcommand it does not know. Say nothing and go to Step 13.
48
+
49
+ The findings decide which question to ask. A `missing` row means this machine
50
+ never installed the workspace, and it takes the first question. Everything else
51
+ takes the second.
52
+
53
+ On a `missing` row:
54
+
55
+ ```json
56
+ {
57
+ "question": "You said yes but the workspace was never installed here. Install it?",
58
+ "header": "Workspace",
59
+ "options": [
60
+ {"label": "Yes", "description": "You then run /acstack:terminal-workspace, which installs herdr and the tools around it: several agents side by side in one terminal, sessions that survive a disconnect, and diffs, pull requests and files on one key each. Twelve components, every one reversible."},
61
+ {"label": "No", "description": "Leave this machine as it is. Nothing in ACStack needs the workspace, and the offer comes back next time you run setup."}
62
+ ]
63
+ }
64
+ ```
65
+
66
+ On **Yes**, print this line and go to Step 13:
67
+
68
+ ```
69
+ Run /acstack:terminal-workspace – the installer is reserved for you to start.
70
+ ```
71
+
72
+ On any other finding:
73
+
74
+ ```json
75
+ {
76
+ "question": "The terminal workspace has updates. Fetch them?",
77
+ "header": "Workspace",
78
+ "options": [
79
+ {"label": "Yes", "description": "You then run /acstack:terminal-workspace upgrade, which reinstalls each stale tool and adds any new component's config block to your file."},
80
+ {"label": "No", "description": "Leave this machine as it is. Everything installed keeps working, and the offer comes back next time you run setup."}
81
+ ]
82
+ }
83
+ ```
84
+
85
+ On **Yes**, print this line and go to Step 13:
86
+
87
+ ```
88
+ Run /acstack:terminal-workspace upgrade – the installer is reserved for you to start.
89
+ ```
90
+
91
+ Never run `upgrade` or `apply` yourself. Both install binaries and write the
92
+ user's config, which is the work the `terminal-workspace` skill owns. Running
93
+ `outdated` here is fine, because it only reads.
94
+
95
+ On **No**, go straight to Step 13 and record nothing. The next version may add
96
+ another component, so a "never ask" flag would silence a question nobody has
97
+ asked the user yet.
98
+
99
+ On any exit other than 0 or 2 the CLI is older than this skill and does not know
100
+ the key. Do not ask, and do not try to write the key. Say this instead, then go
101
+ to Step 13:
102
+
103
+ ```
104
+ The acstack CLI on this machine predates host.terminal_workspace, so I cannot
105
+ record an answer. Restart your agent session to relink the CLI, then run
106
+ /acstack:setup again.
107
+ ```
108
+
109
+ The SessionStart hook repoints `~/.claude/acstack/bin/acstack` at every start,
110
+ so a restart is the whole fix. This only happens when a plugin update lands
111
+ mid-session.
112
+
113
+ On exit 2 nobody has answered yet. Ask once:
114
+
115
+ ```json
116
+ {
117
+ "question": "Set up the terminal workspace on this machine?",
118
+ "header": "Workspace",
119
+ "options": [
120
+ {"label": "Yes", "description": "You then run /acstack:terminal-workspace, which installs herdr and the tools around it: several agents side by side in one terminal, sessions that survive a disconnect, and diffs, pull requests and files on one key each. Twelve components, every one reversible."},
121
+ {"label": "No", "description": "Leave this machine as it is. Nothing in ACStack needs the workspace, and /acstack:terminal-workspace installs it any time later."}
122
+ ]
123
+ }
124
+ ```
125
+
126
+ Write the answer, whichever way it went:
127
+
128
+ ```bash
129
+ ~/.claude/acstack/bin/acstack config set host.terminal_workspace true # or false
130
+ ```
131
+
132
+ Write it before doing anything else. The answer is the user's, and an installer
133
+ they never get round to running must not bring the question back on the next
134
+ project.
135
+
136
+ On **Yes**, hand the install to the user. The `terminal-workspace` skill sets
137
+ `disable-model-invocation: true`, so the host refuses every attempt to
138
+ call it from here. Print this line, then go to Step 13:
139
+
140
+ ```
141
+ Recorded. Run /acstack:terminal-workspace to install it – the installer is
142
+ reserved for you to start.
143
+ ```
144
+
145
+ Never replicate that skill's steps by hand. It installs binaries and writes one
146
+ config file, and a second writer of those files collides with it.
147
+
148
+ On **No**, go straight to Step 13. Name `/acstack:terminal-workspace` once, and
149
+ do not ask again.
150
+
151
+ This step is the only place that asks the axis. The `host` skill owns every
152
+ other `host.*` question, and leaves this one here. The workspace installs
153
+ binaries, so the offer belongs after the project works.
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: sync
3
+ description: Update living specs in acstack/specs/ from recent code changes. Called automatically by /commit for retroactive spec updates. Can also be invoked manually.
4
+ argument-hint: "[file-paths or 'staged']"
5
+ ---
6
+
7
+ ## User input
8
+
9
+ ```text
10
+ $ARGUMENTS
11
+ ```
12
+
13
+ You **MUST** consider the user input before proceeding (if not empty).
14
+
15
+ ## Purpose
16
+
17
+ This skill analyzes code changes. It updates the cumulative living specs in
18
+ `acstack/specs/` to reflect what changed. It is the "fast path" mechanism
19
+ that keeps specs current even when a workflow skips full spec planning.
20
+
21
+ ## Step 1: determine change scope
22
+
23
+ 1. If `$ARGUMENTS` is "staged", or `/commit` calls this skill, use `git diff --cached`
24
+ 2. If `$ARGUMENTS` contains file paths: Diff those files against HEAD
25
+ 3. If no arguments: Use `git diff HEAD` (staged + unstaged)
26
+
27
+ Extract from the diff: files added/modified/deleted, functions/classes changed.
28
+
29
+ ## Step 2: refresh DESIGN.md
30
+
31
+ `DESIGN.md` at the repo root records the project's design tokens. The
32
+ `impeccable document` command writes that file from the code. A **token
33
+ source** is a file that defines those tokens, meaning CSS custom properties or
34
+ a Tailwind theme.
35
+
36
+ This step runs before Step 3. Step 3 exits early when the diff touches no
37
+ domain, and a token source such as `app/globals.css` usually sits outside every
38
+ domain.
39
+
40
+ 1. Run `~/.claude/acstack/bin/acstack design-gate`
41
+ - It prints `on` and exits 0 when the design gate is on
42
+ - It prints `off: <reason>` and exits 1 when the gate is off
43
+ - Skip the whole step on a non-zero exit
44
+ 2. Check for `DESIGN.md` at the repo root
45
+ - Skip the whole step when the file is missing
46
+ - Sync never creates `DESIGN.md` – the open-designer plugin writes it
47
+ 3. Look for a token source in the diff Step 1 chose
48
+
49
+ A token source is exactly one of these four, matching what `impeccable
50
+ document` scans:
51
+
52
+ - a CSS file whose diff adds or changes a line holding `--color-`,
53
+ `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-` or
54
+ `--duration-`
55
+ - a Tailwind config: `tailwind.config.js`, `tailwind.config.ts` or
56
+ `tailwind.config.mjs`
57
+ - a CSS-in-JS theme file: `theme.ts`, `theme.js`, `tokens.ts` or `tokens.js`
58
+ - a token file: `tokens.json` or `design-tokens.json`
59
+
60
+ Grep the diff for the CSS-property case:
61
+
62
+ ```bash
63
+ git diff --cached -U0 -- '*.css' | grep -E '^[+-].*--(color|font|spacing|radius|shadow|ease|duration)-'
64
+ ```
65
+
66
+ Match the diff command to what Step 1 chose. Use `git diff HEAD -U0`
67
+ instead when Step 1 picked `git diff HEAD`.
68
+
69
+ Skip the whole step when the diff holds no token source.
70
+
71
+ 4. Run the `/impeccable document` slash command
72
+
73
+ `document` is a slash-command playbook, not a command-line verb.
74
+
75
+ The playbook finds `DESIGN.md` and stops. It asks whether to refresh,
76
+ overwrite, or merge. Answer refresh every time.
77
+
78
+ Do not call the question tool. Do not ask the user. The code is the only
79
+ source of truth for design tokens.
80
+
81
+ 5. Stage what `document` wrote
82
+
83
+ `document` writes `DESIGN.md` and `.impeccable/design.json`. Stage both
84
+ with the commit, the same way this skill stages an updated spec file.
85
+
86
+ ## Step 3: map changes to domains
87
+
88
+ 1. Read `acstack/domain-map.yaml`
89
+ 2. Match changed files against domain path patterns
90
+ 3. Group changes by domain
91
+ 4. Skip files outside all domains (tests, config, docs)
92
+
93
+ If the diff affects no domains, report "No spec-relevant changes". Then exit.
94
+
95
+ ## Step 4: generate lightweight deltas
96
+
97
+ For each affected domain:
98
+
99
+ 1. Read `acstack/specs/[domain]/spec.md` (if it exists)
100
+ 2. Analyze changes:
101
+ - New functions/endpoints/components -> ADDED requirements
102
+ - Modified signatures or behavior -> MODIFIED requirements
103
+ - Deleted functions/endpoints -> REMOVED requirements
104
+
105
+ Write each functional requirement (FR) entry per the `writing` skill.
106
+
107
+ **Example**
108
+
109
+ ```markdown
110
+ ### FR-014: The handoff anchor loads once
111
+
112
+ - **Description**: The SessionStart hook injects `acstack/HANDOFF.md` after a
113
+ compaction, then moves the file into `acstack/handoffs/`.
114
+ - **Behavior**: Given `acstack/HANDOFF.md` carries the `acstack_handoff`
115
+ marker, When a session starts with source `compact`, Then the hook injects
116
+ the file and retires it.
117
+ - **Source**: `hooks/session-start-handoff.sh`
118
+ ```
119
+
120
+ ## Step 5: apply deltas
121
+
122
+ For each affected domain:
123
+
124
+ - If the spec exists, merge ADDED/MODIFIED/REMOVED into it
125
+ - If no spec exists, create a minimal spec with ADDED entries and a comment:
126
+ `<!-- Auto-generated from code changes. Run /bootstrap for full spec. -->`
127
+
128
+ Write each merged FR per the `writing` skill.
129
+
130
+ ## Step 6: glossary check
131
+
132
+ Glossaries live in `CONTEXT.md` at the repo root (cross-domain terms) and
133
+ `acstack/specs/[domain]/CONTEXT.md` (domain terms). If neither exists, skip.
134
+
135
+ For each glossary term, check the diff. Look for a renamed or deleted
136
+ identifier that matches it: function, class, table, config key, route. If
137
+ so, surface it in the report:
138
+
139
+ ```
140
+ Glossary: 'ticket' may be stale – the diff renames Ticket to WorkItem
141
+ ```
142
+
143
+ Never edit the glossary. Never block the commit.
144
+
145
+ For specs, the code wins. For the glossary, the human wins. The glossary
146
+ records vocabulary that humans agreed on, so only a human decision changes
147
+ it.
148
+
149
+ This check only surfaces the drift.
150
+
151
+ ## Step 7: report
152
+
153
+ ```
154
+ Spec sync: [N] domains updated
155
+ - domain-a: +2 added, ~1 modified
156
+ - domain-b: +1 added, -1 removed
157
+ ```
158
+
159
+ ## Integration with /commit
160
+
161
+ When `/commit` calls this skill:
162
+
163
+ 1. Receives the staged diff as context
164
+ 2. Runs silently (no user prompts)
165
+ 3. Returns a list of modified spec files for staging
166
+ 4. Adds `DESIGN.md` and `.impeccable/design.json` when Step 2 refreshed them
167
+ 5. Outputs minimal detail so it does not interrupt the commit flow
168
+
169
+ ## Spec correction (fix it when you see it)
170
+
171
+ While reading existing specs to generate deltas, if you notice ANY existing FR that contradicts the code in the diff, fix it immediately.