acstack 0.53.1 → 0.54.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 (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 +713 -523
  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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "acstack",
3
3
  "description": "Agentic coding stack where planning grows only as far as needed: a map of decisions, tasks, checks, and handoffs behind a pluggable tracker.",
4
- "version": "0.53.1",
4
+ "version": "0.54.1",
5
5
  "author": {
6
6
  "name": "ac8318740"
7
7
  },
package/README.md CHANGED
@@ -61,11 +61,11 @@ Then, in your project:
61
61
  /acstack:setup
62
62
  ```
63
63
 
64
- - `/acstack:setup` detects the project type, then writes `.acstack/project.yaml` with workflow settings
65
- - All ACStack-owned project records stay local by default under `.acstack/`
66
- - Setup asks which parts to track, with none selected by default
67
- - Native exceptions after the root `.gitignore` baseline let you track configuration, specs, decisions, or any other part independently
68
- - See [Project data and migration](docs/config-reference.md#project-data-stays-local-by-default) for canonical paths and commands
64
+ - `/acstack:setup` detects the project type, then writes `project.yaml` with workflow settings into the project folder
65
+ - All ACStack-owned project records live in one project folder per repository, shared by all of its worktrees
66
+ - `~/.claude/acstack/bin/acstack project-data path` prints it; by default it is `~/.acstack/projects/<key>/`, outside the repository
67
+ - Run `acstack project-data mode tracked` to keep the records in the repository's `.acstack/` and commit them instead
68
+ - See [Where project data lives](docs/config-reference.md#where-project-data-lives) for paths, modes, and commands
69
69
  - Update installed ACStack tools before migrating an older project
70
70
  - Stop old agents and reviews, run `~/.claude/acstack/bin/acstack project-data migrate`, then restart with updated tools
71
71
  - Migration aborts on collisions without overwrites or Git index changes; tracked old paths become pending deletions
@@ -141,7 +141,7 @@ The three commands:
141
141
  - Each question comes with the agent's recommended answer
142
142
  - You provide feedback on the agent's recommended answer instead of prompting from scratch
143
143
  - Some requests only need one question
144
- - The agent writes that decision down as a short note under `.acstack/decisions/`
144
+ - The agent writes that decision down as a short note under `<project folder>/decisions/`
145
145
  - A big feature may need dozens of questions
146
146
  - The agent stores those questions as a **map**
147
147
  - You work through the map across several sessions
@@ -169,7 +169,7 @@ Each node also records six things.
169
169
  - **Who answers it**: you, or the agent working alone
170
170
  - **What kind it is**: a destination, a standing note, a decision, research, or work
171
171
  - **A short name**, which labels the node in a diagram
172
- - **Where it lives**: a GitHub issue by default, or a markdown file under `.acstack/maps/` with no GitHub remote
172
+ - **Where it lives**: a GitHub issue by default, or a markdown file under `<project folder>/maps/` with no GitHub remote
173
173
 
174
174
  Almost every node explains itself with a diagram.
175
175
 
@@ -193,9 +193,9 @@ For the full picture of each step and how they connect, read [docs/workflows.md]
193
193
 
194
194
  *The project states what to run. The machine states what it can do.*
195
195
 
196
- - `.acstack/project.yaml` holds every project-scoped setting
196
+ - `project.yaml` in the project folder holds every project-scoped setting
197
197
  - [docs/config-reference.md](docs/config-reference.md) gives each key, its values, its default and what changes
198
- - `~/.config/acstack/config.json` holds the nine `host.*` axes
198
+ - `~/.acstack/config.json` holds the nine `host.*` axes
199
199
  - `/acstack:host` writes eight of them once per machine, and `/acstack:setup` writes the ninth
200
200
  - [docs/dev-setups.md](docs/dev-setups.md) gives every axis, what reads it, and how to describe a fresh machine
201
201
  - `/acstack:setup` copies the commands and directories from one of three language profiles
@@ -216,7 +216,7 @@ ACStack ships a Node.js CLI: `acstack config`, `acstack list`, `acstack node ...
216
216
  - The first line of every issue body carries all of that node's edges
217
217
  - One call therefore reads the whole map
218
218
  - A sub-issue and an issue dependency mirror those edges, so GitHub's own interface draws the map
219
- - Markdown files are the fallback, one per node under `.acstack/maps/<name>/`
219
+ - Markdown files are the fallback, one per node under `<project folder>/maps/<name>/`
220
220
  - The CLI builds everything else on those four operations
221
221
  - `acstack node frontier` lists what is ready to start now, closest to the original goal first
222
222
  - `acstack node walk` packs the whole map into one brief for a fresh session, in the order the decisions happened
@@ -260,7 +260,7 @@ For work with open decisions, chart it with `/acstack:map` first.
260
260
 
261
261
  | Skill | Description |
262
262
  |-------|-------------|
263
- | `/acstack:commit` | Commit, and update the specs under `.acstack/specs/` from the diff first |
263
+ | `/acstack:commit` | Commit, and update the specs under `<project folder>/specs/` from the diff first |
264
264
  | `/acstack:archive` | Verify implemented specs and current design approval, retain review evidence, then dispose of temporary map nodes |
265
265
  | `/acstack:sync` | Update the specs from code changes, outside a commit |
266
266
  | `/acstack:handoff` | Hand work to a visible agent, a new one in its own pane or one already running, with acknowledgement |
@@ -22,7 +22,7 @@ You review screenshots. You report results. You do not need user approval.
22
22
 
23
23
  ## Project configuration
24
24
 
25
- Read `.acstack/project.yaml` for frontend settings:
25
+ ACStack keeps project data in the project folder, the path `~/.claude/acstack/bin/acstack project-data path` prints. Read `<project folder>/project.yaml` for frontend settings:
26
26
 
27
27
  - `frontend.directory` – frontend source directory
28
28
  - `frontend.dev_server_url` – dev server URL
@@ -33,14 +33,15 @@ Read `.acstack/project.yaml` for frontend settings:
33
33
 
34
34
  You do not read `frontend.browser.mode` or `frontend.browser.fallback`. Step 3 asks the ACStack CLI which browser mode to use, and the CLI reads both.
35
35
 
36
- If `.acstack/project.yaml` has no `frontend` section, report SKIP and exit.
36
+ If `<project folder>/project.yaml` has no `frontend` section, report SKIP and exit.
37
37
 
38
38
  ## Step 0: Read the knowledge base
39
39
 
40
40
  Before doing anything, check for a knowledge base:
41
41
 
42
42
  ```bash
43
- cat .acstack/verification/VERIFICATION-KNOWLEDGE.md 2>/dev/null
43
+ project="$(~/.claude/acstack/bin/acstack project-data path)"
44
+ cat "$project/verification/VERIFICATION-KNOWLEDGE.md" 2>/dev/null
44
45
  ```
45
46
 
46
47
  This file contains URL patterns, element patterns, gotchas, and lessons learned. Read it if it exists. If not, you'll create it in Step 7.
@@ -199,10 +200,10 @@ Track whether you launched the browser so you can clean it up in Step 8.
199
200
 
200
201
  ## Step 4: Verify with agent-browser
201
202
 
202
- Select the project's browser config explicitly from the project root:
203
+ Select the project's browser config explicitly by its absolute path:
203
204
 
204
205
  ```bash
205
- export AGENT_BROWSER_CONFIG="$(pwd)/.acstack/agent-browser.json"
206
+ export AGENT_BROWSER_CONFIG="$(~/.claude/acstack/bin/acstack project-data path)/agent-browser.json"
206
207
  ```
207
208
 
208
209
  Require the file for configured verification; do not assume root config autodiscovery.
@@ -293,13 +294,13 @@ After every verification run, update the knowledge base if you learned something
293
294
 
294
295
  ### Knowledge base
295
296
 
296
- `.acstack/verification/VERIFICATION-KNOWLEDGE.md` – URL patterns, element patterns, gotchas, lessons learned.
297
+ `<project folder>/verification/VERIFICATION-KNOWLEDGE.md` – URL patterns, element patterns, gotchas, lessons learned.
297
298
 
298
299
  If it doesn't exist, create it with what you learned during this run.
299
300
 
300
301
  ### Rules
301
302
 
302
- - All verification knowledge lives in `.acstack/verification/VERIFICATION-KNOWLEDGE.md`.
303
+ - All verification knowledge lives in `<project folder>/verification/VERIFICATION-KNOWLEDGE.md`.
303
304
  - Do NOT create knowledge files anywhere else.
304
305
  - If a selector or element pattern stops working, update the knowledge base.
305
306
  - If you discover a new pattern, add it.
@@ -15,7 +15,7 @@ You are read-only: do not edit source, tests, or specs.
15
15
  ## Establish scope and ownership
16
16
 
17
17
  Read the supplied requirements, affected paths, known risks, and available command results.
18
- Read `.acstack/project.yaml` for commands, directories, environment activation, and applicable frontend gates.
18
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for commands, directories, environment activation, and applicable frontend gates.
19
19
 
20
20
  - Distinguish focused review from ownership of completion verification
21
21
  - If the assignment is unclear, clarify it with the delegating session before duplicating checks
@@ -17,7 +17,7 @@ Implement the assigned requirements under the shared Implementation discipline i
17
17
 
18
18
  ## Project configuration
19
19
 
20
- Read `.acstack/project.yaml` for project-specific settings:
20
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
21
21
 
22
22
  - `directories.source` – where to write source code
23
23
  - `directories.tests` – test directory, subject to assigned ownership
@@ -26,7 +26,7 @@ You write tests from requirements and application programming interface (API) co
26
26
 
27
27
  ## Project configuration
28
28
 
29
- Read `.acstack/project.yaml` for project-specific settings:
29
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
30
30
 
31
31
  - `directories.tests` – where to create test files
32
32
  - `directories.source` – source code root (for mirroring structure)
@@ -22,7 +22,7 @@ You review screenshots. You report results. You do not need user approval.
22
22
 
23
23
  ## Project configuration
24
24
 
25
- Read `.acstack/project.yaml` for frontend settings:
25
+ ACStack keeps project data in the project folder, the path `~/.claude/acstack/bin/acstack project-data path` prints. Read `<project folder>/project.yaml` for frontend settings:
26
26
 
27
27
  - `frontend.directory` – frontend source directory
28
28
  - `frontend.dev_server_url` – dev server URL
@@ -33,14 +33,15 @@ Read `.acstack/project.yaml` for frontend settings:
33
33
 
34
34
  You do not read `frontend.browser.mode` or `frontend.browser.fallback`. Step 3 asks the ACStack CLI which browser mode to use, and the CLI reads both.
35
35
 
36
- If `.acstack/project.yaml` has no `frontend` section, report SKIP and exit.
36
+ If `<project folder>/project.yaml` has no `frontend` section, report SKIP and exit.
37
37
 
38
38
  ## Step 0: Read the knowledge base
39
39
 
40
40
  Before doing anything, check for a knowledge base:
41
41
 
42
42
  ```bash
43
- cat .acstack/verification/VERIFICATION-KNOWLEDGE.md 2>/dev/null
43
+ project="$(~/.claude/acstack/bin/acstack project-data path)"
44
+ cat "$project/verification/VERIFICATION-KNOWLEDGE.md" 2>/dev/null
44
45
  ```
45
46
 
46
47
  This file contains URL patterns, element patterns, gotchas, and lessons learned. Read it if it exists. If not, you'll create it in Step 7.
@@ -199,10 +200,10 @@ Track whether you launched the browser so you can clean it up in Step 8.
199
200
 
200
201
  ## Step 4: Verify with agent-browser
201
202
 
202
- Select the project's browser config explicitly from the project root:
203
+ Select the project's browser config explicitly by its absolute path:
203
204
 
204
205
  ```bash
205
- export AGENT_BROWSER_CONFIG="$(pwd)/.acstack/agent-browser.json"
206
+ export AGENT_BROWSER_CONFIG="$(~/.claude/acstack/bin/acstack project-data path)/agent-browser.json"
206
207
  ```
207
208
 
208
209
  Require the file for configured verification; do not assume root config autodiscovery.
@@ -293,13 +294,13 @@ After every verification run, update the knowledge base if you learned something
293
294
 
294
295
  ### Knowledge base
295
296
 
296
- `.acstack/verification/VERIFICATION-KNOWLEDGE.md` – URL patterns, element patterns, gotchas, lessons learned.
297
+ `<project folder>/verification/VERIFICATION-KNOWLEDGE.md` – URL patterns, element patterns, gotchas, lessons learned.
297
298
 
298
299
  If it doesn't exist, create it with what you learned during this run.
299
300
 
300
301
  ### Rules
301
302
 
302
- - All verification knowledge lives in `.acstack/verification/VERIFICATION-KNOWLEDGE.md`.
303
+ - All verification knowledge lives in `<project folder>/verification/VERIFICATION-KNOWLEDGE.md`.
303
304
  - Do NOT create knowledge files anywhere else.
304
305
  - If a selector or element pattern stops working, update the knowledge base.
305
306
  - If you discover a new pattern, add it.
@@ -15,7 +15,7 @@ You are read-only: do not edit source, tests, or specs.
15
15
  ## Establish scope and ownership
16
16
 
17
17
  Read the supplied requirements, affected paths, known risks, and available command results.
18
- Read `.acstack/project.yaml` for commands, directories, environment activation, and applicable frontend gates.
18
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for commands, directories, environment activation, and applicable frontend gates.
19
19
 
20
20
  - Distinguish focused review from ownership of completion verification
21
21
  - If the assignment is unclear, clarify it with the delegating session before duplicating checks
@@ -17,7 +17,7 @@ Implement the assigned requirements under the shared Implementation discipline i
17
17
 
18
18
  ## Project configuration
19
19
 
20
- Read `.acstack/project.yaml` for project-specific settings:
20
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
21
21
 
22
22
  - `directories.source` – where to write source code
23
23
  - `directories.tests` – test directory, subject to assigned ownership
@@ -26,7 +26,7 @@ You write tests from requirements and application programming interface (API) co
26
26
 
27
27
  ## Project configuration
28
28
 
29
- Read `.acstack/project.yaml` for project-specific settings:
29
+ Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
30
30
 
31
31
  - `directories.tests` – where to create test files
32
32
  - `directories.source` – source code root (for mirroring structure)
@@ -163,7 +163,7 @@ if (-not (Test-Path $openerToken)) {
163
163
  # A token here is only half of it: the dev machine needs the same bytes, and
164
164
  # nothing on this side can see whether it has them. Say so rather than
165
165
  # calling it green and leaving a VM that gets 401 on every request.
166
- Add-Result 'Opener token' 'green' 'present here (each VM needs the same copy at ~/.config/acstack/opener.token)'
166
+ Add-Result 'Opener token' 'green' 'present here (each VM needs the same copy at ~/.acstack/opener.token)'
167
167
  }
168
168
 
169
169
  if ($openerListener -and (Test-Path $openerToken)) {
@@ -258,7 +258,7 @@ if (-not (Test-Path $sshExe)) {
258
258
  # A warning, never a throw. The tasks are already registered by this
259
259
  # point and the start loop is still ahead, so throwing here left every
260
260
  # task registered and none of them running.
261
- Write-Warning "ssh.exe not found, so the opener token was not pushed. Enable the Windows OpenSSH Client optional feature, then copy $tokenFile to ~/.config/acstack/opener.token on each VM by hand."
261
+ Write-Warning "ssh.exe not found, so the opener token was not pushed. Enable the Windows OpenSSH Client optional feature, then copy $tokenFile to ~/.acstack/opener.token on each VM by hand."
262
262
  $sshExe = $null
263
263
  }
264
264
  }
@@ -268,7 +268,7 @@ foreach ($vm in $VMs) {
268
268
  # Single-quoted on the remote side so the shell there cannot interpret it,
269
269
  # and 0600 because it is a bearer credential for opening pages on this
270
270
  # screen.
271
- $cmd = "mkdir -p ~/.config/acstack && umask 077 && printf '%s' '$token' > ~/.config/acstack/opener.token"
271
+ $cmd = "mkdir -p ~/.acstack && umask 077 && printf '%s' '$token' > ~/.acstack/opener.token"
272
272
  # $ErrorActionPreference is 'Stop' for this script, and merging a native
273
273
  # command's stderr into the pipeline under it turns any stderr line into a
274
274
  # terminating NativeCommandError. ssh writes one on a first connection:
@@ -281,9 +281,9 @@ foreach ($vm in $VMs) {
281
281
  $sshCode = $LASTEXITCODE
282
282
  $ErrorActionPreference = $prevEap
283
283
  if ($sshCode -eq 0) {
284
- Write-Host " $vm : token installed at ~/.config/acstack/opener.token"
284
+ Write-Host " $vm : token installed at ~/.acstack/opener.token"
285
285
  } else {
286
- Write-Warning " $vm : could not push the token (ssh exit $sshCode). Copy $tokenFile to ~/.config/acstack/opener.token on that VM by hand."
286
+ Write-Warning " $vm : could not push the token (ssh exit $sshCode). Copy $tokenFile to ~/.acstack/opener.token on that VM by hand."
287
287
  }
288
288
  }
289
289
 
@@ -1,5 +1,5 @@
1
1
  # ACStack terminal workspace.
2
- # Copy to ~/.config/acstack/terminal-workspace.yaml, edit, then run
2
+ # Copy to ~/.acstack/terminal-workspace.yaml, edit, then run
3
3
  # setup.sh apply.
4
4
  #
5
5
  # This is machine-level, not per-project. It installs binaries and writes
@@ -190,7 +190,7 @@ harlequin:
190
190
  # schema, or a single connection_name pointing at a connection in
191
191
  # ~/.snowflake/connections.toml. Prefer the second: it keeps the secret out
192
192
  # of this file.
193
- config_path: "~/.config/acstack/harlequin.toml"
193
+ config_path: "~/.acstack/harlequin.toml"
194
194
 
195
195
  pi:
196
196
  # Off by default, because it writes into pi's own config in ~/.pi/agent.
@@ -17,7 +17,7 @@ set -uo pipefail
17
17
 
18
18
  BRIDGE="${ACSTACK_BRIDGE_URL:-http://127.0.0.1:19988}"
19
19
  OPENER="${ACSTACK_OPENER_URL:-http://127.0.0.1:19989}"
20
- OPENER_TOKEN="${XDG_CONFIG_HOME:-$HOME/.config}/acstack/opener.token"
20
+ OPENER_TOKEN="${ACSTACK_HOME:-$HOME/.acstack}/opener.token"
21
21
  FREE_PORT="${ACSTACK_FREE_PORT:-$HOME/.claude/acstack/bin/vm-free-port.sh}"
22
22
 
23
23
  CMD="${1:-status}"
@@ -120,6 +120,8 @@ case "$CMD" in
120
120
  echo "opener: reachable - $(printf '%s' "$health" | tr -d '[:space:]')"
121
121
  elif [ -z "$(tok)" ]; then
122
122
  echo "opener: no token at $OPENER_TOKEN (run register-tasks.ps1 on the laptop)"
123
+ [ -e "$HOME/.config/acstack/opener.token" ] \
124
+ && echo " an old one is in ~/.config/acstack: run ~/.claude/acstack/bin/acstack project-data migrate"
123
125
  else
124
126
  echo "opener: not reachable on $OPENER"
125
127
  fi
@@ -9,7 +9,7 @@
9
9
  set -uo pipefail
10
10
  # apply rewrites this line from harlequin.config_path. What ships here is the
11
11
  # default, so the helper is right even on a machine nothing rewrote it on.
12
- DB_CFG_DEFAULT="~/.config/acstack/harlequin.toml" # acstack:config_path
12
+ DB_CFG_DEFAULT="~/.acstack/harlequin.toml" # acstack:config_path
13
13
  CFG="${ACSTACK_DB_CONFIG:-$DB_CFG_DEFAULT}"
14
14
  # A human writes ~ for home, and a human writes this config. Expanding it here
15
15
  # rather than at write time keeps the helper right on a machine whose HOME is
@@ -29,7 +29,7 @@ BRIDGE="${ACSTACK_BRIDGE_URL:-http://127.0.0.1:19988}"
29
29
  OPENER="${ACSTACK_OPENER_URL:-http://127.0.0.1:19989}"
30
30
  # The opener refuses anything without this, so its absence is the same as the
31
31
  # opener being down - which is exactly how the route probe treats it.
32
- OPENER_TOKEN="${XDG_CONFIG_HOME:-$HOME/.config}/acstack/opener.token"
32
+ OPENER_TOKEN="${ACSTACK_HOME:-$HOME/.acstack}/opener.token"
33
33
  SERVE=0; ONLY=0; PREVIEW=0; HTML=0; BROWSER=0; NUMBERED=0; TOGGLE=0
34
34
  usage() { echo "usage: acstack-md [--preview] [--numbered] [--toggle-line-numbers] [--diagram N] [--serve|--html|--browser] FILE.md" >&2; exit 1; }
35
35
  # The preview pane and the key that flips it are two processes that never meet,
@@ -155,6 +155,8 @@ case "$(command -v acstack-open >/dev/null 2>&1 && acstack-open --why 2>/dev/nul
155
155
  if [ -z "$tok" ]; then
156
156
  echo "acstack-md: no opener token at $OPENER_TOKEN." >&2
157
157
  echo " run register-tasks.ps1 on the laptop to install one." >&2
158
+ [ -e "$HOME/.config/acstack/opener.token" ] \
159
+ && echo " or move the old one: ~/.claude/acstack/bin/acstack project-data migrate" >&2
158
160
  exit 1
159
161
  fi
160
162
  hex() { od -An -v -tx1 | tr -d ' \n'; }
@@ -163,7 +165,7 @@ case "$(command -v acstack-open >/dev/null 2>&1 && acstack-open --why 2>/dev/nul
163
165
  # Vendored mermaid, uploaded once so diagrams draw without reaching a
164
166
  # CDN. Best effort throughout: the opener redirects to the CDN when it
165
167
  # has no copy, so a failure here costs nothing but an outbound fetch.
166
- vendored="$HOME/.local/share/acstack/mermaid.min.js"
168
+ vendored="${ACSTACK_HOME:-$HOME/.acstack}/cache/mermaid.min.js"
167
169
  # tr, because whitespace inside JSON carries no meaning and a match that
168
170
  # depends on its absence is a match waiting to break. Same reasoning as
169
171
  # acstack-open's /json/list check.
@@ -105,14 +105,14 @@ if [ "${ACSTACK_MD_OPENER:-0}" = "1" ] && [ "$HTML" = "1" ]; then MODE=opener; f
105
105
  # exec -a names the process. Without it a running server is just "python3 -"
106
106
  # and there is nothing sensible to pkill.
107
107
  exec -a "$NAME" python3 - "$FILE" "$PORT" "$MODE" <<'PY'
108
- import html, http.server, pathlib, re, socketserver, sys
108
+ import html, http.server, os, pathlib, re, socketserver, sys
109
109
  try:
110
110
  import markdown
111
111
  except ImportError:
112
112
  sys.exit("acstack-md: needs the python markdown package: pip install --user markdown")
113
113
 
114
114
  src, port, MODE = pathlib.Path(sys.argv[1]), int(sys.argv[2]), sys.argv[3]
115
- VENDOR = pathlib.Path.home() / ".local/share/acstack/mermaid.min.js"
115
+ VENDOR = pathlib.Path(os.environ.get("ACSTACK_HOME") or pathlib.Path.home() / ".acstack") / "cache/mermaid.min.js"
116
116
 
117
117
  CSS = """*{box-sizing:border-box}body{max-width:54rem;margin:0 auto;padding:2rem 1.25rem;
118
118
  font:16px/1.65 -apple-system,Segoe UI,system-ui,sans-serif;color:#1a1a1a;background:#fff}
@@ -23,7 +23,7 @@ BRIDGE="${ACSTACK_BRIDGE_URL:-${AGENT_BROWSER_CDP:-http://127.0.0.1:19988}}"
23
23
  OPENER="${ACSTACK_OPENER_URL:-http://127.0.0.1:19989}"
24
24
  # The opener refuses anything without this, so its absence is the same as the
25
25
  # opener being down - which is exactly how the route probe treats it.
26
- OPENER_TOKEN="${XDG_CONFIG_HOME:-$HOME/.config}/acstack/opener.token"
26
+ OPENER_TOKEN="${ACSTACK_HOME:-$HOME/.acstack}/opener.token"
27
27
 
28
28
  WHY=0
29
29
  [ "${1:-}" = "--why" ] && { WHY=1; shift; }
@@ -2,7 +2,7 @@ apply_herdr_numbers() {
2
2
  have herdr || return 0
3
3
  [ "$(cfg_get herdr.renumber_plugin true)" = "true" ] || return 0
4
4
 
5
- local dir="$HOME/.config/acstack/herdr-numbers"
5
+ local dir="$ACSTACK_ROOT/herdr-numbers"
6
6
  mkdir -p "$dir"
7
7
  # An absolute command: herdr runs argv without a shell and resolves relative
8
8
  # commands from the plugin root, not from PATH.
@@ -4,7 +4,7 @@ apply_markdown() {
4
4
  install_binary glow charmbracelet/glow Linux_x86_64
5
5
  # Vendored so the preview page pulls nothing from a CDN: it works offline,
6
6
  # and on a managed laptop there is no third-party fetch to explain.
7
- local share="$HOME/.local/share/acstack"
7
+ local share="$ACSTACK_ROOT/cache"
8
8
  mkdir -p "$share"
9
9
  if [ ! -s "$share/mermaid.min.js" ]; then
10
10
  curl -fsSL -o "$share/mermaid.min.js" \
@@ -65,7 +65,7 @@ managed = set()
65
65
  if from_fork == "true":
66
66
  block += [
67
67
  "# These two keys exist only in the fork build. See the tuicr section",
68
- "# of ~/.config/acstack/terminal-workspace.yaml.",
68
+ "# of ~/.acstack/terminal-workspace.yaml.",
69
69
  f"show_file_line_stats = {stats}",
70
70
  f"file_list_width = {width}",
71
71
  "# A local build must not be replaced by a stock release.",
@@ -81,7 +81,7 @@ else:
81
81
  # terminal. Pinning the value sidesteps the whole detection path.
82
82
  if appearance:
83
83
  block += ["# Pinned rather than detected. See the tuicr section of",
84
- "# ~/.config/acstack/terminal-workspace.yaml.",
84
+ "# ~/.acstack/terminal-workspace.yaml.",
85
85
  f'appearance = "{appearance}"']
86
86
  managed.add("appearance")
87
87
  block.append(end)
@@ -238,7 +238,7 @@ PY
238
238
  # By prefix, which is why helpers are named acstack-*: anything this
239
239
  # script ever wrote goes, including helpers retired in an older version.
240
240
  herdr plugin unlink acstack.herdr-numbers >/dev/null 2>&1 || true
241
- rm -rf "$HOME/.config/acstack/herdr-numbers"
241
+ rm -rf "$ACSTACK_ROOT/herdr-numbers"
242
242
  rm -f "$BIN"/acstack-*
243
243
  # The xclip stand-in is the one managed file without the prefix.
244
244
  grep -q "Installed by acstack" "$BIN/xclip" 2>/dev/null && rm -f "$BIN/xclip"
@@ -15,7 +15,7 @@ write_helpers() {
15
15
 
16
16
  # The one helper with a path in the config. The source holds the default, so
17
17
  # this carries nothing but a value the user chose.
18
- ACSTACK_DB_CFG="$(cfg_get harlequin.config_path "~/.config/acstack/harlequin.toml")" \
18
+ ACSTACK_DB_CFG="$(cfg_get harlequin.config_path "~/.acstack/harlequin.toml")" \
19
19
  py "$BIN/acstack-db" <<'PY'
20
20
  import os, re, sys
21
21
  # A bash single-quoted literal, so a path with a space or a quote in it reaches
@@ -20,7 +20,12 @@ set -uo pipefail
20
20
 
21
21
  SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" && pwd)"
22
22
 
23
- CFG="${ACSTACK_TW_CONFIG:-$HOME/.config/acstack/terminal-workspace.yaml}"
23
+ # ACStack's machine-wide root. An empty ACSTACK_HOME counts as unset.
24
+ ACSTACK_ROOT="${ACSTACK_HOME:-$HOME/.acstack}"
25
+ CFG="${ACSTACK_TW_CONFIG:-$ACSTACK_ROOT/terminal-workspace.yaml}"
26
+ # The old home is never read, only named, so a move is one command away.
27
+ [ ! -e "$CFG" ] && [ -e "$HOME/.config/acstack/terminal-workspace.yaml" ] \
28
+ && echo "acstack: config is still at ~/.config/acstack; run ~/.claude/acstack/bin/acstack project-data migrate" >&2
24
29
  BIN="${ACSTACK_TW_BIN:-$HOME/.local/bin}"
25
30
  # Everything installs into $BIN, and the config steps then ask `have <tool>`
26
31
  # whether it worked. On a fresh machine $BIN is not on PATH yet, so without