acstack 0.53.1 → 0.54.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 (87) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +11 -11
  3. package/agents/codex/frontend-verifier.toml +8 -7
  4. package/agents/codex/task-checker.toml +1 -1
  5. package/agents/codex/task-executor.toml +1 -1
  6. package/agents/codex/test-writer.toml +1 -1
  7. package/agents/frontend-verifier.md +8 -7
  8. package/agents/task-checker.md +1 -1
  9. package/agents/task-executor.md +1 -1
  10. package/agents/test-writer.md +1 -1
  11. package/assets/playwriter-bridge/doctor.ps1 +1 -1
  12. package/assets/playwriter-bridge/register-tasks.ps1 +4 -4
  13. package/assets/terminal-workspace/config.example.yaml +2 -2
  14. package/assets/terminal-workspace/helpers/acstack-bridge +3 -1
  15. package/assets/terminal-workspace/helpers/acstack-db +1 -1
  16. package/assets/terminal-workspace/helpers/acstack-md +4 -2
  17. package/assets/terminal-workspace/helpers/acstack-md-lib +2 -2
  18. package/assets/terminal-workspace/helpers/acstack-open +1 -1
  19. package/assets/terminal-workspace/lib/apply-herdr-numbers.sh +1 -1
  20. package/assets/terminal-workspace/lib/apply-tools.sh +1 -1
  21. package/assets/terminal-workspace/lib/apply-tuicr.sh +2 -2
  22. package/assets/terminal-workspace/lib/commands.sh +1 -1
  23. package/assets/terminal-workspace/lib/helper-install.sh +1 -1
  24. package/assets/terminal-workspace/setup.sh +6 -1
  25. package/cli/dist/index.js +697 -509
  26. package/cli/dist/index.js.map +4 -4
  27. package/cli/package.json +1 -1
  28. package/docs/config-reference.md +129 -87
  29. package/docs/dev-setups.md +4 -4
  30. package/docs/terminal-workspace.md +7 -6
  31. package/docs/workflows.md +13 -12
  32. package/examples/design-doc/acstack/README.md +3 -3
  33. package/examples/design-doc/acstack/journey.md +1 -1
  34. package/examples/design-doc/acstack/publication.md +1 -1
  35. package/hooks/context-pressure.sh +6 -2
  36. package/hooks/lib/read-guard.mjs +25 -21
  37. package/hooks/project-data.sh +5 -34
  38. package/hooks/session-start-handoff.sh +11 -22
  39. package/hooks/session-start.sh +5 -6
  40. package/orchestrator/AGENTS.md +30 -25
  41. package/package.json +1 -1
  42. package/pi/agents/frontend-verifier.md +8 -7
  43. package/pi/agents/task-checker.md +1 -1
  44. package/pi/agents/task-executor.md +1 -1
  45. package/pi/agents/test-writer.md +1 -1
  46. package/pi/extension.ts +39 -57
  47. package/profiles/fullstack-python.yaml +1 -1
  48. package/profiles/node-typescript.yaml +1 -1
  49. package/profiles/python.yaml +1 -1
  50. package/skills/archive/SKILL.md +20 -18
  51. package/skills/bootstrap/SKILL.md +6 -6
  52. package/skills/bridge/SKILL-VM.md +5 -5
  53. package/skills/bridge/SKILL-WINDOWS.md +1 -1
  54. package/skills/browser-verify/SKILL.md +6 -6
  55. package/skills/commit/SKILL.md +8 -8
  56. package/skills/compact-and-continue/SKILL.md +11 -9
  57. package/skills/design-doc/SKILL.md +8 -5
  58. package/skills/explore/SKILL.md +1 -1
  59. package/skills/grilling/SKILL.md +4 -3
  60. package/skills/handoff/SKILL.md +4 -4
  61. package/skills/host/SKILL.md +2 -2
  62. package/skills/host/detect-host.sh +8 -4
  63. package/skills/host/herdr.md +1 -1
  64. package/skills/host/install-herdr-block.sh +1 -1
  65. package/skills/host/notes.md +5 -4
  66. package/skills/host/questions.md +1 -1
  67. package/skills/host/report.md +2 -2
  68. package/skills/implement/SKILL.md +6 -5
  69. package/skills/implement/decision-log.md +10 -15
  70. package/skills/implement/design-pass.md +2 -2
  71. package/skills/map/SKILL.md +5 -3
  72. package/skills/map/frontend.md +2 -2
  73. package/skills/map/materialising.md +5 -3
  74. package/skills/map/trackers/files.md +6 -4
  75. package/skills/pre-commit-review/SKILL.md +3 -3
  76. package/skills/quick-fix/SKILL.md +1 -1
  77. package/skills/record-context/SKILL.md +6 -6
  78. package/skills/setup/SKILL.md +20 -11
  79. package/skills/setup/browser.md +2 -2
  80. package/skills/setup/first-run.md +14 -16
  81. package/skills/setup/report.md +4 -3
  82. package/skills/setup/row-fixes.md +7 -8
  83. package/skills/sync/SKILL.md +14 -12
  84. package/skills/terminal-workspace/SKILL.md +4 -4
  85. package/skills/terminal-workspace/headless-clipboard.md +1 -1
  86. package/skills/terminal-workspace/turn-off-and-update.md +1 -1
  87. package/skills/test-conventions/SKILL.md +2 -2
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acstack-cli",
3
- "version": "0.53.1",
3
+ "version": "0.54.0",
4
4
  "description": "CLI for the ACStack agentic coding stack",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,8 +1,9 @@
1
1
  # Project configuration
2
2
 
3
- *Every key in `.acstack/project.yaml`, the values it takes, its default, and what changes when you change it.*
3
+ *Every key in `project.yaml`, the values it takes, its default, and what changes when you change it.*
4
4
 
5
- One file, `.acstack/project.yaml`, holds every setting that belongs to a project.
5
+ One file, `<project folder>/project.yaml`, holds every setting that belongs to a project.
6
+ The project folder is the repository's ACStack data folder, the path `~/.claude/acstack/bin/acstack project-data path` prints (section 1 explains where it lives).
6
7
 
7
8
  - **It names what to run**: the test, build, lint, typecheck, and format commands
8
9
  - **It names where to look**: the source and test directories, and the frontend
@@ -18,14 +19,14 @@ Three terms first.
18
19
 
19
20
  ```mermaid
20
21
  flowchart TD
21
- FILE[".acstack/project.yaml<br/>(written by /acstack:setup)"] --> WF["workflow.*<br/>switches, maps, handoff"]
22
+ FILE["project.yaml in the project folder<br/>(written by /acstack:setup)"] --> WF["workflow.*<br/>switches, maps, handoff"]
22
23
  FILE --> RUN["commands.*, directories.*,<br/>test_markers, venv"]
23
24
  FILE --> FE["frontend.*<br/>dev server, browser"]
24
25
  WF --> SKILLS["commit, grilling, map,<br/>archive, handoff"]
25
26
  WF --> HOOK["hooks/context-pressure.sh"]
26
27
  RUN --> AGENTS["Completion owner<br/>and delegated agents"]
27
28
  FE --> FV["frontend-verifier"]
28
- HOST["~/.config/acstack/config.json<br/>host.* keys - see dev-setups.md"] --> FV
29
+ HOST["~/.acstack/config.json<br/>host.* keys - see dev-setups.md"] --> FV
29
30
  ```
30
31
 
31
32
  | Step in the diagram | Detail |
@@ -44,7 +45,7 @@ flowchart TD
44
45
 
45
46
  *The setup skill writes the whole file. To change one key, run `acstack config set`.*
46
47
 
47
- - `.acstack/project.yaml` sits under the project root, beside `.acstack/domain-map.yaml`
48
+ - `<project folder>/project.yaml` sits beside `<project folder>/domain-map.yaml`
48
49
  - `/acstack:setup` writes it
49
50
  - On a fresh project the skill detects the project type, then writes every key from a profile under `profiles/`
50
51
  - On a project that already has the file, the skill leads with the health check and offers a menu of changes
@@ -55,7 +56,6 @@ flowchart TD
55
56
  - An omitted one names nothing at all
56
57
 
57
58
  These commands report configuration without changing settings.
58
- CLI startup can repair the root Git ignore baseline before the command runs.
59
59
 
60
60
  | Command | What it prints |
61
61
  | --- | --- |
@@ -64,84 +64,126 @@ CLI startup can repair the root Git ignore baseline before the command runs.
64
64
  | `acstack config list` | every key the file states |
65
65
  | `acstack design-gate` | whether a design review runs here, as `on` and exit 0 or one `off: <reason>` line per reason and exit 1 (section 3) |
66
66
 
67
- ### Project data stays local by default
67
+ ### Where project data lives
68
68
 
69
- - All ACStack-owned project records live under `.acstack/`
70
- - The root `.gitignore` controls tracking, independently for every part
71
- - No configuration key controls tracking
69
+ *Each repository has one project folder, outside the repository by default. All of its worktrees share it.*
72
70
 
73
- | Part | Canonical path |
71
+ - `~/.claude/acstack/bin/acstack project-data path` prints the project folder's absolute path, even before the folder exists
72
+ - It exits non-zero outside a Git repository
73
+ - It exits non-zero with a message naming the fix when legacy data, an orphaned entry, or a conflict needs attention
74
+ - The session-start hook states the same path in the agent's context
75
+ - This document writes a part inside it as `<project folder>/project.yaml`, `<project folder>/specs/`, and so on
76
+ - `/acstack:setup` creates the folder with `mkdir -p "$(~/.claude/acstack/bin/acstack project-data path)"`
77
+ - No configuration key and no `.gitignore` rule controls where project data lives
78
+
79
+ A project uses one of two modes.
80
+
81
+ | Mode | Where the records live | What the repository holds |
82
+ | --- | --- | --- |
83
+ | Global (default) | `~/.acstack/projects/<key>/`, a real folder | No ACStack files, and no `.gitignore` rules |
84
+ | Tracked (opt-in) | The main checkout's `.acstack/`; `~/.acstack/projects/<key>` is a link to it | `.acstack/`, which the developer commits |
85
+
86
+ - `<key>` is the main checkout's folder name, a hyphen, and a short hash of the repository's shared Git folder, for example `shop-3f9a2c`
87
+ - Every worktree reports the same shared Git folder, so every worktree finds the same entry
88
+ - `ls -l ~/.acstack/projects/` lists every project and shows which are tracked
89
+ - `ACSTACK_HOME` replaces `~/.acstack` for every path in this section
90
+ - In tracked mode the project folder resolves into the main checkout
91
+ - Edits to a feature branch's own `.acstack/` take effect only once they reach the main checkout
92
+ - A teammate's clone links its entry to the committed `.acstack/` automatically on first use
93
+ - Spec sync stages updated specs only when they sit inside the working tree being committed
94
+ - In global mode they never do
95
+ - In tracked mode they do only for a commit made in the main checkout
96
+
97
+ Every part keeps its name inside the project folder.
98
+
99
+ | Part | Path |
74
100
  | --- | --- |
75
- | Project configuration | `.acstack/project.yaml` |
76
- | Domain map | `.acstack/domain-map.yaml` |
77
- | Living specs | `.acstack/specs/` |
78
- | Maps | `.acstack/maps/` |
79
- | Authored design sources | `.acstack/designs/` |
80
- | Archives | `.acstack/archive/` |
81
- | Legacy change records | `.acstack/changes/` |
82
- | Legacy review artifacts (retained for explicit import) | `.acstack/alignment-packs/` |
83
- | Canonical design reviews and imported history | `.acstack/design-reviews/` |
84
- | Architecture decisions | `.acstack/decisions/` |
85
- | Cross-domain glossary | `.acstack/CONTEXT.md` |
86
- | Browser connection | `.acstack/agent-browser.json` |
87
- | Verification knowledge | `.acstack/verification/VERIFICATION-KNOWLEDGE.md` |
88
- | Test baseline | `.acstack/.test-baseline` |
89
- | Decision logs | `.acstack/decision-logs/` |
90
- | Continuation anchor | `.acstack/HANDOFF.md` |
91
- | Agent handoffs | `.acstack/handoffs/` |
92
-
93
- - `/acstack:setup` creates `.acstack/`, then immediately runs `~/.claude/acstack/bin/acstack project-data ensure`
94
- - Setup asks which parts to track with a multi-select question, with none selected by default
95
- - CLI and host session startup run `project-data ensure` before checking configuration
96
- - `ensure` needs no config when `.acstack/` exists and does nothing when no project data exists
97
- - It installs a managed `/.acstack/**` baseline at the start of the root `.gitignore`
98
- - Existing user rules follow the baseline, preserving their exceptions
99
- - Bare filesystem creation cannot trigger a command
100
- - The first ACStack CLI invocation or session startup enforces the baseline; ACStack runs no filesystem watcher
101
- - Add native exceptions after existing rules, outside the managed baseline, to track selected parts
102
- - The user can select configuration, specs, and architecture decisions independently
103
-
104
- ```gitignore
105
- # User rules after existing rules and the ACStack-managed baseline
106
- !/.acstack/
107
- !/.acstack/project.yaml
108
- !/.acstack/specs/
109
- !/.acstack/specs/**
110
- !/.acstack/decisions/
111
- !/.acstack/decisions/**
112
- ```
101
+ | Project configuration | `<project folder>/project.yaml` |
102
+ | Domain map | `<project folder>/domain-map.yaml` |
103
+ | Living specs | `<project folder>/specs/` |
104
+ | Maps | `<project folder>/maps/` |
105
+ | Authored design sources | `<project folder>/designs/` |
106
+ | Archives | `<project folder>/archive/` |
107
+ | Legacy change records | `<project folder>/changes/` |
108
+ | Legacy review artifacts (retained for explicit import) | `<project folder>/alignment-packs/` |
109
+ | Canonical design reviews and imported history | `<project folder>/design-reviews/` |
110
+ | Architecture decisions | `<project folder>/decisions/` |
111
+ | Cross-domain glossary | `<project folder>/CONTEXT.md` |
112
+ | Browser connection | `<project folder>/agent-browser.json` |
113
+ | Verification knowledge | `<project folder>/verification/VERIFICATION-KNOWLEDGE.md` |
114
+ | Test baseline | `<project folder>/.test-baseline` |
115
+ | Decision logs | `<project folder>/decision-logs/` |
116
+ | Continuation anchor | `<project folder>/HANDOFF.md` |
117
+ | Agent handoffs | `<project folder>/handoffs/` |
113
118
 
114
- - Reopen `.acstack/` before any selected part to override earlier whole-directory ignores
115
- - A nested file also needs its parent directory reopened, for example `!/.acstack/verification/` before its file exception
116
- - Git ignore rules do not untrack files already in the Git index
117
- - ACStack never force-adds ignored files or changes the Git index to enforce this policy
118
119
  - ACStack retires `workflow.alignment_packs` auto-generation, approval, and tracking settings; existing fields have no effect
119
120
  - This includes `approval_gate` and `commit_generated_packs`
120
121
  - Setup and config writes no longer offer them; ACStack never silently rewrites or deletes existing files
121
- - Native Git ignore rules alone control tracking
122
122
  - Map-linked design approval uses the exact source, saved comments, and contribution inputs, without a new workflow flag
123
123
  - `workflow.design_review` still controls only the frontend design pass
124
- - Installed tools under `~/.claude/acstack/bin/`, XDG configuration, and host-owned `.claude/` settings keep their existing locations
124
+ - Installed tools under `~/.claude/acstack/bin/` and host-owned `.claude/` settings keep their existing locations
125
125
  - Helper programs and user code under `frontend.helpers_dir` stay where they are
126
- - Verification metadata always uses `.acstack/verification/VERIFICATION-KNOWLEDGE.md`
127
-
128
- ### Explicit migration from the old layout
129
-
130
- 1. Update installed ACStack tools before moving project data
131
- 2. Stop old agent sessions and review processes; old CLI versions and hooks cannot read the new layout
132
- 3. From the checkout to migrate, run `~/.claude/acstack/bin/acstack project-data migrate`
133
- 4. Review the working-tree changes, then restart agents and reviews with the updated tools
134
-
135
- - Migration preflights all moves and aborts on collisions without overwriting destination data
136
- - It moves old `acstack/` project records, root `CONTEXT.md`, `.test-baseline`, and `agent-browser.json` into the canonical destinations
137
- - It moves `docs/adr/` to `.acstack/decisions/` and old decision logs to `.acstack/decision-logs/`
138
- - It moves verification knowledge, not arbitrary helper directories or their programs
139
- - Previously tracked old paths become pending deletions; their new destinations stay local unless the user opts in
140
- - Migration preserves local data and makes no Git index changes or automatic tracking exceptions
141
- - Migrate each checkout explicitly; never move another checkout's data automatically
142
- - Decision logs still belong to the main checkout at `<main checkout>/.acstack/decision-logs/`
143
- - If that checkout remains on the legacy layout, stop and report an actionable migration error
144
- - Do not create a partial `.acstack/` directory there as a workaround
126
+ - Verification metadata always uses `<project folder>/verification/VERIFICATION-KNOWLEDGE.md`
127
+
128
+ ### Machine-wide files
129
+
130
+ *ACStack's own settings and caches share the same root, `~/.acstack/` or `$ACSTACK_HOME`.*
131
+
132
+ | File | Path | Was |
133
+ | --- | --- | --- |
134
+ | Global config (`host.*` keys) | `~/.acstack/config.json` | `~/.config/acstack/config.json` |
135
+ | Opener token | `~/.acstack/opener.token` | `~/.config/acstack/opener.token` |
136
+ | Terminal-workspace files | `~/.acstack/terminal-workspace.yaml` and its siblings | `~/.config/acstack/` |
137
+ | Cached assets | `~/.acstack/cache/` | `~/.local/share/acstack/` |
138
+ | ac-teams state | `~/.acstack/ac-teams/` | unchanged |
139
+
140
+ ACStack no longer reads the `XDG_CONFIG_HOME` or `XDG_DATA_HOME` variables.
141
+
142
+ ### Project data commands
143
+
144
+ *Four commands move project data, and only when the developer runs them.*
145
+
146
+ | Command | What it does |
147
+ | --- | --- |
148
+ | `acstack project-data migrate` | Moves legacy machine-wide files and this repository's legacy `.acstack/` into the new layout |
149
+ | `acstack project-data mode tracked` | Moves the project folder's contents into the main checkout's `.acstack/` and replaces the folder with a link; commit `.acstack/` from the main checkout afterwards |
150
+ | `acstack project-data mode global` | Moves the main checkout's `.acstack/` into the project folder and removes the link; commit the removal of `.acstack/` afterwards |
151
+ | `acstack project-data relink <entry>` | Gives the named entry, orphaned by moving the repository on disk, the repository's current key; `project-data path` names the entry |
152
+
153
+ Every command:
154
+
155
+ - Preflights every move and aborts on a collision without writing anything
156
+ - Never changes the Git index, commits, or force-adds files
157
+ - Reports any other worktree that still holds its own `.acstack/` changes, which ACStack no longer reads; move what you need from it, then delete it
158
+
159
+ ### Explicit migration from a legacy layout
160
+
161
+ *ACStack stops reading the old locations. It warns once per session while legacy data exists, and names `acstack project-data migrate`.*
162
+
163
+ Legacy data is any of:
164
+
165
+ - `~/.config/acstack/` or `~/.local/share/acstack/`, or their `XDG_*` equivalents
166
+ - A repository's `.acstack/` that no project entry links to
167
+ - The older in-repository layout: `acstack/`, `docs/adr/`, `.decisions/`, and root `CONTEXT.md`, `.test-baseline`, or `agent-browser.json`
168
+
169
+ Migrate each machine and each repository explicitly.
170
+
171
+ 1. Update installed ACStack tools before moving any data
172
+ 2. Stop old agent sessions and review servers; old CLI versions and hooks cannot read the new layout
173
+ 3. Back up the legacy locations
174
+ 4. From any worktree of each repository, run `~/.claude/acstack/bin/acstack project-data migrate`
175
+ 5. Review the result, then restart agents and review servers with the updated tools
176
+
177
+ What migration does:
178
+
179
+ - The first run on a machine moves `~/.config/acstack/*` to `~/.acstack/` and `~/.local/share/acstack/*` to `~/.acstack/cache/`
180
+ - It moves the older in-repository layout into `.acstack/` first, including `docs/adr/` to `decisions/` and old decision logs to `decision-logs/`
181
+ - It moves verification knowledge, not arbitrary helper directories or their programs
182
+ - A main checkout whose `.acstack/` files are in the Git index becomes tracked mode; only the link is created
183
+ - Otherwise the main checkout's `.acstack/` moves into its project folder, and the old ACStack-managed block in the root `.gitignore` is removed
184
+ - Previously tracked paths that moved show up as pending deletions for the developer to commit
185
+ - It preflights every move and aborts on a collision, such as an existing project folder, without overwriting anything
186
+ - Never migrate a repository silently, or work around legacy data by creating a partial project folder
145
187
 
146
188
  ### Explicit import from retired map reviews
147
189
 
@@ -155,7 +197,7 @@ CLI startup can repair the root Git ignore baseline before the command runs.
155
197
  --legacy-dir <path> --mapping <json-file> [--feedback <json-file>]
156
198
  ```
157
199
 
158
- - Choose a nonsymlink directory under `.acstack/alignment-packs/`
200
+ - Choose a nonsymlink directory under `<project folder>/alignment-packs/`
159
201
  - Supply explicit target mappings; see the `design-doc` skill for mapping and reconciliation instructions
160
202
  - Migration preserves source artifacts and decision logs unchanged
161
203
  - Canonical `review.json` keeps imported feedback and approval history; historical approval never authorizes the current design
@@ -167,9 +209,9 @@ CLI startup can repair the root Git ignore baseline before the command runs.
167
209
  *The key decides, and the key alone.*
168
210
 
169
211
  - A `host.*` key describes the machine
170
- - It goes to the global config at `~/.config/acstack/config.json`
212
+ - It goes to the global config at `~/.acstack/config.json`
171
213
  - Every other key in this document describes the project
172
- - It goes to `.acstack/project.yaml`
214
+ - It goes to `<project folder>/project.yaml`
173
215
  - Section 10 covers the `host.*` keys
174
216
  - `acstack config get <key>` and `acstack config unset <key>` read the same key table and route the same way
175
217
 
@@ -251,7 +293,7 @@ So the result decides which path a write takes, and never the shape of the key.
251
293
 
252
294
  *A file ACStack itself produced always reads back.*
253
295
 
254
- - A project that holds `.acstack/` and no `project.yaml` gets the file created
296
+ - A project folder that exists without `project.yaml` gets the file created
255
297
  - A block stating nothing takes a key underneath it, whether the file spells that block as a bare colon, as `null` or as `~`
256
298
  - That is the state `acstack config unset` leaves behind
257
299
  - The tool accepts its own output
@@ -309,7 +351,7 @@ Three refusals protect a file neither command can handle.
309
351
 
310
352
  | Key | Values | Default | What changes |
311
353
  | --- | --- | --- | --- |
312
- | `workflow.spec_sync` | `true`, `false` | `true` | the `commit` skill runs spec sync before it commits, unless this says `false`; with `false` the living specs under `.acstack/specs/` stop tracking the code |
354
+ | `workflow.spec_sync` | `true`, `false` | `true` | the `commit` skill runs spec sync before it commits, unless this says `false`; with `false` the living specs under `<project folder>/specs/` stop tracking the code |
313
355
  | `workflow.tdd.strict` | `true`, `false` | none | deprecated compatibility boolean; no sequencing effect, including explicit `true` |
314
356
  | `workflow.tdd.orchestrator_strict` | `true`, `false` | none | deprecated compatibility boolean; no delegation effect, including explicit `true` |
315
357
  | `workflow.frontend_verification` | `true`, `false` | `false` | the frontend-verifier runs only when this is `true`, the file configures a `frontend` block, and the change touched frontend files |
@@ -392,7 +434,7 @@ A **map** is a graph of question nodes and work nodes. A **tracker** is the back
392
434
  | Key | Values | Default | What changes |
393
435
  | --- | --- | --- | --- |
394
436
  | `workflow.maps.tracker` | `github`, `files` | none | the `map`, `implement`, and `archive` skills read the matching backend document and use its operations |
395
- | `workflow.maps.persist` | `true`, `false` | `false` | `true` moves a cleared map's node files to `.acstack/archive/[YYYY-MM-DD]-[name]/nodes/`; `false` deletes `.acstack/maps/<name>/` |
437
+ | `workflow.maps.persist` | `true`, `false` | `false` | `true` moves a cleared map's node files to `<project folder>/archive/[YYYY-MM-DD]-[name]/nodes/`; `false` deletes `<project folder>/maps/<name>/` |
396
438
 
397
439
  - An absent `workflow.maps.tracker` means nobody has chosen yet
398
440
  - The `map` skill then picks at the moment it first writes a map's nodes down, confirms the choice with the user, and writes the key
@@ -544,8 +586,8 @@ Two limits are worth knowing.
544
586
  - `200_000` reads as 200,000
545
587
  - Exponent and float notation do not
546
588
  - `2e5` and `2.0` fall back to the default
547
- - The hook opens `.acstack/project.yaml` relative to the working directory
548
- - A session running outside the project root therefore gets the defaults, whatever the file says
589
+ - The hook opens `<project folder>/project.yaml`, finding the folder with `acstack project-data path`
590
+ - A session running outside a Git repository therefore gets the defaults
549
591
 
550
592
  ## 7. commands, directories, test_markers and venv
551
593
 
@@ -554,7 +596,7 @@ Two limits are worth knowing.
554
596
  | Key | Values | Default | What changes |
555
597
  | --- | --- | --- | --- |
556
598
  | `commands.test` | a shell command, or `null` | from the profile | the verification owner runs the configured tests |
557
- | `commands.test_collect` | a shell command, or `null` | from the profile | the verification owner compares counts with `.acstack/.test-baseline`; counts alone do not prove coverage |
599
+ | `commands.test_collect` | a shell command, or `null` | from the profile | the verification owner compares counts with `<project folder>/.test-baseline`; counts alone do not prove coverage |
558
600
  | `commands.build` | a shell command, or `null` | from the profile | the verification owner checks the build with it |
559
601
  | `commands.lint` | a shell command, or `null` | from the profile | the verification owner lints with it, usually with a fix flag |
560
602
  | `commands.typecheck` | a shell command, or `null` | from the profile | the verification owner type-checks with it |
@@ -582,7 +624,7 @@ Two limits are worth knowing.
582
624
  | `frontend.directory` | a path | `frontend/` | where the frontend lives |
583
625
  | `frontend.dev_server_url` | a URL | `http://localhost:3000` | the address the frontend-verifier opens |
584
626
  | `frontend.dev_server_check` | a shell command | a `curl` of the URL | how the frontend-verifier decides the dev server is up |
585
- | `frontend.helpers_dir` | a path | `<frontend.directory>/tests/helpers/` | where helper programs live; verification metadata always lives at `.acstack/verification/VERIFICATION-KNOWLEDGE.md` |
627
+ | `frontend.helpers_dir` | a path | `<frontend.directory>/tests/helpers/` | where helper programs live; verification metadata always lives at `<project folder>/verification/VERIFICATION-KNOWLEDGE.md` |
586
628
  | `frontend.commands.dev` | a shell command | none | how the frontend-verifier starts the dev server; without it the verifier cannot start one itself |
587
629
  | `frontend.commands.build` | a shell command | from the profile | the frontend build the verification owner runs |
588
630
  | `frontend.commands.lint` | a shell command | from the profile | the frontend lint the verification owner runs |
@@ -601,7 +643,7 @@ The Chrome DevTools Protocol (CDP) is the wire protocol the verifier drives a br
601
643
  | --- | --- | --- | --- |
602
644
  | `frontend.browser.mode` | `remote`, `headless`, `local` | none | the mode `acstack config browser-mode` resolves for the frontend-verifier, weighed against the three host axes; it also picks the `cdp_port` default |
603
645
  | `frontend.browser.fallback` | `none`, `remote`, `headless`, `local` | none | only `none` acts: it forbids another mode from standing in when the host does not declare the preferred one |
604
- | `frontend.browser.cdp_port` | a whole number from 1 to 65535 | `19988` under `mode: remote`, `9555` otherwise | the port the frontend-verifier dials, and the port the `agent-browser-json` row of the check requires `.acstack/agent-browser.json` to name |
646
+ | `frontend.browser.cdp_port` | a whole number from 1 to 65535 | `19988` under `mode: remote`, `9555` otherwise | the port the frontend-verifier dials, and the port the `agent-browser-json` row of the check requires `<project folder>/agent-browser.json` to name |
605
647
 
606
648
  The two defaults come from two different browsers.
607
649
 
@@ -612,7 +654,7 @@ The two defaults come from two different browsers.
612
654
  The port default applies wherever the CLI needs a number.
613
655
 
614
656
  - `acstack config check` holds a project that states no `cdp_port` to the default its mode implies
615
- - It fails when `.acstack/agent-browser.json` names a different port
657
+ - It fails when `<project folder>/agent-browser.json` names a different port
616
658
  - `acstack config show` behaves the other way, printing only what the project states
617
659
  - "What did the project say" and "which port do we dial" are different questions
618
660
 
@@ -639,7 +681,7 @@ Only the literal `none` gives `frontend.browser.fallback` any effect.
639
681
  - The `host.*` keys are not `project.yaml` keys either
640
682
  - They describe the machine rather than the project
641
683
  - The same repository opens on several machines with different setups
642
- - They live in the global config at `~/.config/acstack/config.json`
684
+ - They live in the global config at `~/.acstack/config.json`
643
685
  - `acstack config set` is what writes them
644
686
  - [dev-setups.md](dev-setups.md) documents all nine axes
645
687
 
@@ -9,7 +9,7 @@ You run ACStack on more than one machine. Those machines are not the same.
9
9
  - **Another has no display at all**
10
10
  - **A skill cannot guess which**
11
11
  - Each machine answers nine questions once, with `/acstack:host` and `/acstack:setup`
12
- - **The answers live in `~/.config/acstack/config.json`** as `host.*` keys
12
+ - **The answers live in `~/.acstack/config.json`** as `host.*` keys
13
13
  - **The worktree skills and the frontend verifier read them** instead of probing
14
14
 
15
15
  Four terms first.
@@ -21,7 +21,7 @@ Four terms first.
21
21
 
22
22
  ```mermaid
23
23
  flowchart TD
24
- HOST["Describe this machine once<br/>(/acstack:host - section 4)"] --> AXES["Every axis, and what reads it<br/>(host.* in ~/.config/acstack/config.json - section 1)"]
24
+ HOST["Describe this machine once<br/>(/acstack:host - section 4)"] --> AXES["Every axis, and what reads it<br/>(host.* in ~/.acstack/config.json - section 1)"]
25
25
  AXES --> ORCH["Orchestrator axes<br/>(host.orchestrators.* - section 2)"]
26
26
  AXES --> BROW["Browser axes<br/>(host.browser.* - section 3)"]
27
27
  AXES --> OPT["Optional axes<br/>(preview, terminal workspace, element picker, Orca topology)"]
@@ -52,8 +52,8 @@ flowchart TD
52
52
 
53
53
  Where the file lives, and how the CLI reads a value:
54
54
 
55
- - The global config is a JSON file at `~/.config/acstack/config.json`
56
- - It moves under `$XDG_CONFIG_HOME` when you set that variable
55
+ - The global config is a JSON file at `~/.acstack/config.json`
56
+ - It moves to `$ACSTACK_HOME/config.json` when you set that variable
57
57
  - Run `~/.claude/acstack/bin/acstack config path` for the real location
58
58
  - `acstack config show` prints every axis with the project's settings
59
59
  - The CLI matches an enum value case-sensitively
@@ -18,7 +18,8 @@ This is an optional setup for running several coding agents on a remote machine,
18
18
  - The server keeps every pane alive when your connection drops
19
19
  - The local client is what lets your own clipboard and browser reach the session, which an SSH shell cannot do
20
20
  - Run `/acstack:terminal-workspace` to install and configure all of it
21
- - One file, `~/.config/acstack/terminal-workspace.yaml`, turns each part on or off
21
+ - One file, `~/.acstack/terminal-workspace.yaml`, turns each part on or off
22
+ - `ACSTACK_HOME` moves that folder, `~/.acstack/`, for every ACStack file in it
22
23
  - The rest of this document explains what that sets up and why
23
24
  - Read it if you would rather configure it by hand or change the defaults
24
25
 
@@ -157,7 +158,7 @@ What `uninstall` removes:
157
158
 
158
159
  What the config holds:
159
160
 
160
- - The script reads `~/.config/acstack/terminal-workspace.yaml`, which the skill copies from `assets/terminal-workspace/config.example.yaml`
161
+ - The script reads `~/.acstack/terminal-workspace.yaml`, which the skill copies from `assets/terminal-workspace/config.example.yaml`
161
162
  - The config holds twelve components, each with its own `enabled` key
162
163
  - You turn a part off there and run `apply` again
163
164
  - Eight components name a tool this setup installs: `herdr`, `gh_dash`, `diffnav`, `delta`, `tuicr`, `lazygit`, `yazi`, and `harlequin`
@@ -237,7 +238,7 @@ Three more steps `apply` handles that no release tarball covers:
237
238
 
238
239
  - `ya pkg add yazi-rs/plugins:piper`, the yazi plugin that lets `acstack-md` draw the preview pane
239
240
  - `pip install --user markdown`, which `acstack-md --serve` needs
240
- - a copy of `mermaid.min.js` at `~/.local/share/acstack/mermaid.min.js`
241
+ - a copy of `mermaid.min.js` at `~/.acstack/cache/mermaid.min.js`
241
242
  - A served page fetches nothing from a content delivery network (CDN)
242
243
 
243
244
  ### 3.2. Let herdr read agent state from the agent
@@ -411,7 +412,7 @@ How it treats pi's files:
411
412
  - `apply` installs and removes packages through `pi install` and `pi remove`, and never edits `packages` itself
412
413
  - `apply` touches nothing in a file that does not parse, and names it
413
414
  - A broken `settings.json` stops the whole component, because `pi install` rewrites that file
414
- - `~/.config/acstack/terminal-workspace.pi.json` records what `apply` added
415
+ - `~/.acstack/terminal-workspace.pi.json` records what `apply` added
415
416
  - `disable pi` and `uninstall` undo only what that file names
416
417
  - A package or a key you had before `apply` stays yours
417
418
  - A value of yours that `apply` replaced goes back, and so does an ACStack pin it moved forward
@@ -1120,7 +1121,7 @@ We measured one delivery rather than estimating it.
1120
1121
  *`alt+q` opens harlequin on a connection profile. `alt+shift+q` opens it in a tab.*
1121
1122
 
1122
1123
  - Query on the left, rows on the right, schema tree beside both
1123
- - Profiles live in `~/.config/acstack/harlequin.toml`, which `acstack-db` writes once and never touches again
1124
+ - Profiles live in `~/.acstack/harlequin.toml`, which `acstack-db` writes once and never touches again
1124
1125
  - `acstack-db` with no argument launches the only profile, or opens an fzf menu when there is more than one
1125
1126
  - `acstack-db <profile>` skips the menu
1126
1127
 
@@ -1586,7 +1587,7 @@ cd $env:USERPROFILE\playwriter-bridge
1586
1587
  ```
1587
1588
 
1588
1589
  - That generates a shared secret and stores it at `%LOCALAPPDATA%\playwriter-bridge\opener.token`
1589
- - It copies the secret to each dev machine at `~/.config/acstack/opener.token`, over the same ssh the tunnel uses
1590
+ - It copies the secret to each dev machine at `~/.acstack/opener.token`, over the same ssh the tunnel uses
1590
1591
  - Every request from the dev machine carries it
1591
1592
  - Loopback binding alone would not be enough
1592
1593
  - The reverse tunnel makes the port reachable by anything running on the dev machine
package/docs/workflows.md CHANGED
@@ -9,6 +9,7 @@ ACStack routes a request down one of three paths. Every path ends at a commit th
9
9
  - **A bug goes to root-cause analysis first** (see section 2)
10
10
  - **A request with open questions becomes a to-do graph** you work through (see section 1)
11
11
  - **The rest of this document** is the detail behind one box of the diagram below
12
+ - **Project records live in the project folder**, the path `~/.claude/acstack/bin/acstack project-data path` prints; this document writes its parts as `<project folder>/specs/` and so on ([config-reference.md](config-reference.md) explains where it lives)
12
13
 
13
14
  ```mermaid
14
15
  flowchart TD
@@ -21,7 +22,7 @@ flowchart TD
21
22
  F --> T
22
23
  T --> C["Commit<br/>(acstack:commit)"]
23
24
  C --> Y["Sync specs from the diff<br/>(domain-map.yaml)"]
24
- Y --> L[("Living specs<br/>.acstack/specs/")]
25
+ Y --> L[("Living specs<br/>in the project folder")]
25
26
  M -->|"every question answered"| A["Archive<br/>(check the decisions landed,<br/>then delete the nodes)"]
26
27
  A --> L
27
28
  ```
@@ -102,7 +103,7 @@ Nodes live in a tracker. That is the storage layer, and you can swap it.
102
103
  - The first line of every issue body carries all of that node's edges
103
104
  - One list call therefore returns the whole graph
104
105
  - A sub-issue and a dependency mirror those edges, so GitHub's own interface draws the map
105
- - Files under `.acstack/maps/<name>/` are the fallback
106
+ - Files under `<project folder>/maps/<name>/` are the fallback
106
107
  - Frontmatter holds the edges, so those files carry no header line
107
108
  - Frontier, claim, and resolve build on those four operations
108
109
  - No tracker implements them itself
@@ -152,9 +153,9 @@ Nodes live in a tracker. That is the storage layer, and you can swap it.
152
153
  - There is no question cap
153
154
  - The set of answerable questions bounds itself
154
155
  - **`record-context`** fires when a decision lands
155
- - It writes an ADR under `.acstack/decisions/` only when the decision is hard to reverse *and* surprising *and* a real trade-off
156
- - It writes a glossary term when a term got settled, in `.acstack/CONTEXT.md` for cross-domain vocabulary
157
- - It writes a domain term in `.acstack/specs/<domain>/CONTEXT.md` instead
156
+ - It writes an ADR under `<project folder>/decisions/` only when the decision is hard to reverse *and* surprising *and* a real trade-off
157
+ - It writes a glossary term when a term got settled, in `<project folder>/CONTEXT.md` for cross-domain vocabulary
158
+ - It writes a domain term in `<project folder>/specs/<domain>/CONTEXT.md` instead
158
159
  - It can write both, or neither
159
160
  - ACStack generates the ADR index from the files
160
161
  - Nobody hand-edits it
@@ -199,9 +200,9 @@ flowchart LR
199
200
 
200
201
  `/acstack:commit` groups changes into MECE commits. MECE means mutually exclusive and collectively exhaustive: no change appears twice, and no change goes missing. Before writing them it does five things.
201
202
 
202
- 1. Reads `.acstack/domain-map.yaml` to map each changed file to a domain.
203
+ 1. Reads `<project folder>/domain-map.yaml` to map each changed file to a domain.
203
204
  2. Works out what the diff adds, modifies or removes, for each affected domain with a `spec.md`.
204
- 3. Writes those entries into the domain's spec; it stages tracked specs and preserves ignored specs locally without force-adding them.
205
+ 3. Writes those entries into the domain's spec; it stages the specs only when they sit inside the working tree being committed, which happens only in tracked mode from the main checkout.
205
206
  4. Flags source files that match no domain.
206
207
  5. Checks the glossaries.
207
208
 
@@ -219,7 +220,7 @@ Four cases stop sync.
219
220
  - no file matching a domain
220
221
  - a change that touches only docs and config
221
222
 
222
- **Without `.acstack/domain-map.yaml` this step does nothing, silently.**
223
+ **Without `<project folder>/domain-map.yaml` this step does nothing, silently.**
223
224
 
224
225
  - `/acstack:setup` generates that file
225
226
  - `acstack config check` reports it as missing on a project set up before that existed
@@ -237,7 +238,7 @@ Four cases stop sync.
237
238
  - Archive never recursively deletes review artifacts or evidence-bearing handoffs
238
239
  - It then disposes of the nodes
239
240
  - It deletes them by default
240
- - It moves them to `.acstack/archive/<date>-<name>/nodes/` when `workflow.maps.persist` is `true`
241
+ - It moves them to `<project folder>/archive/<date>-<name>/nodes/` when `workflow.maps.persist` is `true`
241
242
  - Keeping nodes is off by default
242
243
  - A kept map is a second copy of every decision
243
244
  - The two drift apart
@@ -247,14 +248,14 @@ Four cases stop sync.
247
248
  - The user types `/acstack:archive`
248
249
  - `/acstack:map` hands off to it once every node resolves
249
250
  - The disposal step then asks you first
250
- - Legacy `.acstack/changes/` directories from the pre-map workflow still archive the old way
251
+ - Legacy `<project folder>/changes/` directories from the pre-map workflow still archive the old way
251
252
  - An upgrade therefore never strands work
252
253
 
253
254
  ## 7. Living specs
254
255
 
255
- *What the project keeps. ACStack deletes a map once every question resolves. `.acstack/specs/` outlives it.*
256
+ *What the project keeps. ACStack deletes a map once every question resolves. `<project folder>/specs/` outlives it.*
256
257
 
257
- - Specs live at `.acstack/specs/<domain>/spec.md`, organised by the domains in `domain-map.yaml`
258
+ - Specs live at `<project folder>/specs/<domain>/spec.md`, organised by the domains in `domain-map.yaml`
258
259
  - Each spec states numbered functional requirements (`FR-NNN`) in Given, When, Then form
259
260
  - They are cumulative
260
261
  - They describe only what the code already does
@@ -109,7 +109,7 @@ The ACStack plugin contains Agent skills, Agent session setup, and the CLI packa
109
109
  - Choose `--port <port>` if another review uses the default port
110
110
  - Use an unused path for each Markdown export
111
111
  - Keep the companion beside source when its relative links must work on GitHub
112
- - New designs default to Git-ignored `.acstack/designs/`; this repository intentionally tracks this public example
112
+ - New designs default to `designs/` in the project folder, outside the repository unless the project uses tracked mode; this repository intentionally tracks this public example
113
113
 
114
114
 
115
115
  ## Project developer
@@ -237,7 +237,7 @@ Authored design files define the design in the local checkout; GitHub hosts a pu
237
237
  - Ignore rules exclude matching untracked files from ordinary staging
238
238
  - Removing an ignore rule does not stage, commit, or push anything
239
239
  - Already tracked files remain tracked even if an ignore rule later matches them
240
- - New project designs under `.acstack/` stay ignored by default; this public example is tracked separately
240
+ - New project designs in the project folder stay outside the repository by default; this public example is tracked separately
241
241
 
242
242
 
243
243
  ## Offline review
@@ -270,4 +270,4 @@ Authored design files define the design in the local checkout; GitHub hosts a pu
270
270
  - Ignore rules exclude matching untracked files from ordinary staging
271
271
  - Removing an ignore rule does not stage, commit, or push anything
272
272
  - Already tracked files remain tracked even if an ignore rule later matches them
273
- - New project designs under `.acstack/` stay ignored by default; this public example is tracked separately
273
+ - New project designs in the project folder stay outside the repository by default; this public example is tracked separately
@@ -82,4 +82,4 @@ The ACStack plugin contains Agent skills, Agent session setup, and the CLI packa
82
82
  - Choose `--port <port>` if another review uses the default port
83
83
  - Use an unused path for each Markdown export
84
84
  - Keep the companion beside source when its relative links must work on GitHub
85
- - New designs default to Git-ignored `.acstack/designs/`; this repository intentionally tracks this public example
85
+ - New designs default to `designs/` in the project folder, outside the repository unless the project uses tracked mode; this repository intentionally tracks this public example
@@ -13,4 +13,4 @@ Authored design files define the design in the local checkout; GitHub hosts a pu
13
13
  - Ignore rules exclude matching untracked files from ordinary staging
14
14
  - Removing an ignore rule does not stage, commit, or push anything
15
15
  - Already tracked files remain tracked even if an ignore rule later matches them
16
- - New project designs under `.acstack/` stay ignored by default; this public example is tracked separately
16
+ - New project designs in the project folder stay outside the repository by default; this public example is tracked separately
@@ -40,7 +40,7 @@
40
40
  # nudge when it crosses each rung rather than on every single stop.
41
41
  #
42
42
  # The default rungs are workflow.handoff.nudge_warn and nudge_severe from
43
- # .acstack/project.yaml (defaulting to 200000 / 500000), and then one rung
43
+ # <project folder>/project.yaml (defaulting to 200000 / 500000), and then one rung
44
44
  # every workflow.handoff.nudge_step tokens (default 100000) above the last
45
45
  # one. Setting workflow.handoff.context_thresholds replaces the default rungs
46
46
  # entirely with the listed ones - written either block style (one "- item"
@@ -103,6 +103,10 @@ export ACSTACK_HOOK_INPUT
103
103
  ACSTACK_CONTEXT_PRESSURE_DIR="${ACSTACK_CONTEXT_PRESSURE_DIR:-${TMPDIR:-/tmp}/acstack-context-pressure}"
104
104
  export ACSTACK_CONTEXT_PRESSURE_DIR
105
105
 
106
+ # The project folder holds project.yaml; empty outside a project, so defaults apply.
107
+ ACSTACK_PROJECT_FOLDER=$("${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/cli/bin/acstack.js" project-data path 2>/dev/null)
108
+ export ACSTACK_PROJECT_FOLDER
109
+
106
110
  # stderr goes nowhere: a hook that writes to stderr is noise at best, and a
107
111
  # traceback from an unforeseen payload must never reach the user. Every failure
108
112
  # path inside is already a silent no-op; this is the backstop.
@@ -361,7 +365,7 @@ def read_config():
361
365
  "context_thresholds": None,
362
366
  }
363
367
  try:
364
- with open(os.path.join(".acstack", "project.yaml"), encoding="utf-8", errors="replace") as f:
368
+ with open(os.path.join(os.environ.get("ACSTACK_PROJECT_FOLDER") or "/nonexistent", "project.yaml"), encoding="utf-8", errors="replace") as f:
365
369
  lines = f.read().split("\n")
366
370
  except OSError:
367
371
  return cfg