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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +11 -11
- package/agents/codex/frontend-verifier.toml +8 -7
- package/agents/codex/task-checker.toml +1 -1
- package/agents/codex/task-executor.toml +1 -1
- package/agents/codex/test-writer.toml +1 -1
- package/agents/frontend-verifier.md +8 -7
- package/agents/task-checker.md +1 -1
- package/agents/task-executor.md +1 -1
- package/agents/test-writer.md +1 -1
- package/assets/playwriter-bridge/doctor.ps1 +1 -1
- package/assets/playwriter-bridge/register-tasks.ps1 +4 -4
- package/assets/terminal-workspace/config.example.yaml +2 -2
- package/assets/terminal-workspace/helpers/acstack-bridge +3 -1
- package/assets/terminal-workspace/helpers/acstack-db +1 -1
- package/assets/terminal-workspace/helpers/acstack-md +4 -2
- package/assets/terminal-workspace/helpers/acstack-md-lib +2 -2
- package/assets/terminal-workspace/helpers/acstack-open +1 -1
- package/assets/terminal-workspace/lib/apply-herdr-numbers.sh +1 -1
- package/assets/terminal-workspace/lib/apply-tools.sh +1 -1
- package/assets/terminal-workspace/lib/apply-tuicr.sh +2 -2
- package/assets/terminal-workspace/lib/commands.sh +1 -1
- package/assets/terminal-workspace/lib/helper-install.sh +1 -1
- package/assets/terminal-workspace/setup.sh +6 -1
- package/cli/dist/index.js +697 -509
- package/cli/dist/index.js.map +4 -4
- package/cli/package.json +1 -1
- package/docs/config-reference.md +129 -87
- package/docs/dev-setups.md +4 -4
- package/docs/terminal-workspace.md +7 -6
- package/docs/workflows.md +13 -12
- package/examples/design-doc/acstack/README.md +3 -3
- package/examples/design-doc/acstack/journey.md +1 -1
- package/examples/design-doc/acstack/publication.md +1 -1
- package/hooks/context-pressure.sh +6 -2
- package/hooks/lib/read-guard.mjs +25 -21
- package/hooks/project-data.sh +5 -34
- package/hooks/session-start-handoff.sh +11 -22
- package/hooks/session-start.sh +5 -6
- package/orchestrator/AGENTS.md +30 -25
- package/package.json +1 -1
- package/pi/agents/frontend-verifier.md +8 -7
- package/pi/agents/task-checker.md +1 -1
- package/pi/agents/task-executor.md +1 -1
- package/pi/agents/test-writer.md +1 -1
- package/pi/extension.ts +39 -57
- package/profiles/fullstack-python.yaml +1 -1
- package/profiles/node-typescript.yaml +1 -1
- package/profiles/python.yaml +1 -1
- package/skills/archive/SKILL.md +20 -18
- package/skills/bootstrap/SKILL.md +6 -6
- package/skills/bridge/SKILL-VM.md +5 -5
- package/skills/bridge/SKILL-WINDOWS.md +1 -1
- package/skills/browser-verify/SKILL.md +6 -6
- package/skills/commit/SKILL.md +8 -8
- package/skills/compact-and-continue/SKILL.md +11 -9
- package/skills/design-doc/SKILL.md +8 -5
- package/skills/explore/SKILL.md +1 -1
- package/skills/grilling/SKILL.md +4 -3
- package/skills/handoff/SKILL.md +4 -4
- package/skills/host/SKILL.md +2 -2
- package/skills/host/detect-host.sh +8 -4
- package/skills/host/herdr.md +1 -1
- package/skills/host/install-herdr-block.sh +1 -1
- package/skills/host/notes.md +5 -4
- package/skills/host/questions.md +1 -1
- package/skills/host/report.md +2 -2
- package/skills/implement/SKILL.md +6 -5
- package/skills/implement/decision-log.md +10 -15
- package/skills/implement/design-pass.md +2 -2
- package/skills/map/SKILL.md +5 -3
- package/skills/map/frontend.md +2 -2
- package/skills/map/materialising.md +5 -3
- package/skills/map/trackers/files.md +6 -4
- package/skills/pre-commit-review/SKILL.md +3 -3
- package/skills/quick-fix/SKILL.md +1 -1
- package/skills/record-context/SKILL.md +6 -6
- package/skills/setup/SKILL.md +20 -11
- package/skills/setup/browser.md +2 -2
- package/skills/setup/first-run.md +14 -16
- package/skills/setup/report.md +4 -3
- package/skills/setup/row-fixes.md +7 -8
- package/skills/sync/SKILL.md +14 -12
- package/skills/terminal-workspace/SKILL.md +4 -4
- package/skills/terminal-workspace/headless-clipboard.md +1 -1
- package/skills/terminal-workspace/turn-off-and-update.md +1 -1
- package/skills/test-conventions/SKILL.md +2 -2
package/hooks/lib/read-guard.mjs
CHANGED
|
@@ -12,6 +12,8 @@ import * as fs from 'node:fs';
|
|
|
12
12
|
import * as os from 'node:os';
|
|
13
13
|
import * as path from 'node:path';
|
|
14
14
|
import { createHash } from 'node:crypto';
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
15
17
|
|
|
16
18
|
export const DEFAULT_MIN_BYTES = 32768;
|
|
17
19
|
|
|
@@ -25,13 +27,13 @@ export function envSaysNotMain(env = process.env) {
|
|
|
25
27
|
|
|
26
28
|
/**
|
|
27
29
|
* The one settings function: workflow.read_guard and
|
|
28
|
-
* workflow.read_guard_bytes from the
|
|
29
|
-
* .
|
|
30
|
-
*
|
|
30
|
+
* workflow.read_guard_bytes from project.yaml in the repository's project
|
|
31
|
+
* folder. Hand-rolled like the other hooks' readers, because no YAML library
|
|
32
|
+
* is guaranteed at hook time. pi passes the folder it already resolved.
|
|
31
33
|
*/
|
|
32
|
-
export function readGuardSettings(cwd) {
|
|
34
|
+
export function readGuardSettings(cwd, folder = projectFolder(cwd)) {
|
|
33
35
|
const settings = { enabled: true, minBytes: DEFAULT_MIN_BYTES };
|
|
34
|
-
const yaml =
|
|
36
|
+
const yaml = folder ? readText(path.join(folder, 'project.yaml')) : undefined;
|
|
35
37
|
if (yaml === undefined) return settings;
|
|
36
38
|
const stack = [];
|
|
37
39
|
for (const raw of yaml.split('\n')) {
|
|
@@ -54,20 +56,19 @@ export function readGuardSettings(cwd) {
|
|
|
54
56
|
return settings;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
dir = parent;
|
|
59
|
+
const CLI = fileURLToPath(new URL('../../cli/bin/acstack.js', import.meta.url));
|
|
60
|
+
|
|
61
|
+
/** The project folder the CLI reports for cwd, or undefined outside a project. */
|
|
62
|
+
function projectFolder(cwd) {
|
|
63
|
+
const result = spawnSync(process.execPath, [CLI, 'project-data', 'path'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
64
|
+
return result.status === 0 ? result.stdout.trim() || undefined : undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readText(file) {
|
|
68
|
+
try {
|
|
69
|
+
return fs.readFileSync(file, 'utf8');
|
|
70
|
+
} catch {
|
|
71
|
+
return undefined;
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -118,11 +119,14 @@ function resolvePath(file, cwd) {
|
|
|
118
119
|
* `ledger` has has(key) and add(key); add throws when it cannot record, and
|
|
119
120
|
* then the read is allowed so a repeat can never be trapped.
|
|
120
121
|
*/
|
|
121
|
-
export function decide({ toolName, toolInput, cwd, main, ledger, settings
|
|
122
|
+
export function decide({ toolName, toolInput, cwd, main, ledger, settings }) {
|
|
122
123
|
try {
|
|
123
|
-
if (!main || !
|
|
124
|
+
if (!main || !ledger) return { block: false };
|
|
124
125
|
const file = wholeReadTarget(toolName, toolInput, cwd);
|
|
125
126
|
if (!file) return { block: false };
|
|
127
|
+
// Resolved only for a whole-file read, since it costs a CLI call.
|
|
128
|
+
settings ??= readGuardSettings(cwd);
|
|
129
|
+
if (!settings.enabled) return { block: false };
|
|
126
130
|
const stat = fs.statSync(file);
|
|
127
131
|
if (!stat.isFile() || stat.size < settings.minBytes) return { block: false };
|
|
128
132
|
const key = `${fs.realpathSync(file)}\0${stat.size}\0${stat.mtimeMs}`;
|
package/hooks/project-data.sh
CHANGED
|
@@ -1,38 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Source from host hooks before reading config or writing project data.
|
|
3
|
-
acstack_has_legacy_project_data() {
|
|
4
|
-
local root="$1" name
|
|
5
|
-
for name in project.yaml domain-map.yaml; do
|
|
6
|
-
{ [ -f "$root/acstack/$name" ] || [ -L "$root/acstack/$name" ]; } && return 0
|
|
7
|
-
done
|
|
8
|
-
for name in alignment-packs design-reviews maps specs changes archive decision-logs; do
|
|
9
|
-
{ [ -d "$root/acstack/$name" ] || [ -L "$root/acstack/$name" ]; } && return 0
|
|
10
|
-
done
|
|
11
|
-
return 1
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
acstack_project_root() {
|
|
15
|
-
local root
|
|
16
|
-
root="$PWD"
|
|
17
|
-
while [ "$root" != / ]; do
|
|
18
|
-
if [ -d "$root/.acstack" ] || acstack_has_legacy_project_data "$root"; then
|
|
19
|
-
printf '%s\n' "$root"
|
|
20
|
-
return
|
|
21
|
-
fi
|
|
22
|
-
root=$(dirname "$root")
|
|
23
|
-
done
|
|
24
|
-
git rev-parse --show-toplevel 2>/dev/null || printf '%s\n' "$PWD"
|
|
25
|
-
}
|
|
26
3
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if ! (cd "$root" && "$bundled_cli" project-data ensure >&2); then
|
|
33
|
-
echo 'acstack: project-data ensure failed; ignore policy is not confirmed installed. Skipping project activation and private writes.' >&2
|
|
34
|
-
return 1
|
|
35
|
-
fi
|
|
36
|
-
# A second config root must never hide unmigrated project data.
|
|
37
|
-
! acstack_has_legacy_project_data "$root"
|
|
4
|
+
# Print the project folder for the current repository. Fails outside Git, or
|
|
5
|
+
# when the CLI names a fix (legacy data, orphaned entry, conflicting modes);
|
|
6
|
+
# that message and any legacy-data warning reach the user on stderr.
|
|
7
|
+
acstack_project_folder() {
|
|
8
|
+
"$1" project-data path
|
|
38
9
|
}
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
# the load-bearing state the summary may have compressed away (next action, task
|
|
10
10
|
# ledger, agent-team file ownership, blockers).
|
|
11
11
|
#
|
|
12
|
-
# Active (pending) handoff lives at the fixed path
|
|
13
|
-
# hook
|
|
12
|
+
# Active (pending) handoff lives at the fixed path <project folder>/HANDOFF.md;
|
|
13
|
+
# the hook asks the CLI for the folder once. The file's frontmatter records the
|
|
14
14
|
# change it belongs to. On consume, the file is MOVED into that change's own
|
|
15
15
|
# folder, accumulating a per-change history:
|
|
16
16
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
17
|
+
# <project folder>/changes/<change>/handoffs/<timestamp>.md (when the change dir exists)
|
|
18
|
+
# <project folder>/handoffs/<change>/<timestamp>.md (ad-hoc, or change archived)
|
|
19
19
|
#
|
|
20
20
|
# Storing consumed handoffs inside the change dir means they travel with the
|
|
21
21
|
# change when /acstack:archive moves it. Names are timestamped with a numeric
|
|
@@ -33,11 +33,8 @@ set -u
|
|
|
33
33
|
|
|
34
34
|
command -v python3 >/dev/null 2>&1 || exit 0
|
|
35
35
|
source "$(dirname "${BASH_SOURCE[0]}")/project-data.sh"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
acstack_has_legacy_project_data "$project_root" && ACSTACK_LEGACY_PROJECT_DATA=1
|
|
39
|
-
export ACSTACK_BUNDLED_CLI="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/cli/bin/acstack.js"
|
|
40
|
-
cd "$project_root" || exit 0
|
|
36
|
+
project_folder=$(acstack_project_folder "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/cli/bin/acstack.js") || exit 0
|
|
37
|
+
cd "$project_folder" 2>/dev/null || exit 0
|
|
41
38
|
|
|
42
39
|
# Capture the hook payload from stdin before running python. The heredoc below
|
|
43
40
|
# becomes python's stdin (the program source), so the payload must travel via an
|
|
@@ -46,7 +43,7 @@ ACSTACK_HOOK_INPUT="$(cat)"
|
|
|
46
43
|
export ACSTACK_HOOK_INPUT
|
|
47
44
|
|
|
48
45
|
python3 <<'PY'
|
|
49
|
-
import json, os, re, shutil,
|
|
46
|
+
import json, os, re, shutil, sys
|
|
50
47
|
|
|
51
48
|
try:
|
|
52
49
|
data = json.loads(os.environ.get("ACSTACK_HOOK_INPUT", ""))
|
|
@@ -59,7 +56,7 @@ if not isinstance(data, dict):
|
|
|
59
56
|
if data.get("source") != "compact":
|
|
60
57
|
sys.exit(0)
|
|
61
58
|
|
|
62
|
-
active =
|
|
59
|
+
active = "HANDOFF.md"
|
|
63
60
|
try:
|
|
64
61
|
with open(active, encoding="utf-8") as f:
|
|
65
62
|
raw = f.read()
|
|
@@ -105,7 +102,7 @@ if not body.strip():
|
|
|
105
102
|
# "map" is the current key; "change" is accepted for anchors written by
|
|
106
103
|
# pre-map versions of the handoff skill. The value feeds os.path.join, so
|
|
107
104
|
# sanitize it the same way as the stamp – a name with "/" or ".." must not
|
|
108
|
-
# route the archived handoff outside
|
|
105
|
+
# route the archived handoff outside the project folder.
|
|
109
106
|
change = meta.get("map") or meta.get("change") or "ad-hoc"
|
|
110
107
|
change = re.sub(r"[^A-Za-z0-9._-]", "-", str(change))
|
|
111
108
|
if not change.strip("."):
|
|
@@ -121,22 +118,14 @@ if not stamp:
|
|
|
121
118
|
# Route to the change's own folder when that change dir exists, so consumed
|
|
122
119
|
# handoffs travel with the change on /acstack:archive. Otherwise fall back to a
|
|
123
120
|
# neutral top-level handoffs dir (ad-hoc work, or a change already archived).
|
|
124
|
-
change_dir = os.path.join("
|
|
121
|
+
change_dir = os.path.join("changes", change)
|
|
125
122
|
if change != "ad-hoc" and os.path.isdir(change_dir):
|
|
126
123
|
archive_dir = os.path.join(change_dir, "handoffs")
|
|
127
124
|
else:
|
|
128
|
-
archive_dir = os.path.join("
|
|
125
|
+
archive_dir = os.path.join("handoffs", change)
|
|
129
126
|
|
|
130
127
|
# Find a non-colliding destination: <stamp>.md, then <stamp>-2.md, -3.md, ...
|
|
131
128
|
dest = None
|
|
132
|
-
try:
|
|
133
|
-
subprocess.run([os.environ["ACSTACK_BUNDLED_CLI"], "project-data", "ensure"],
|
|
134
|
-
check=True, stdout=sys.stderr, stderr=sys.stderr)
|
|
135
|
-
if os.environ["ACSTACK_LEGACY_PROJECT_DATA"] == "1":
|
|
136
|
-
raise OSError("Legacy project data found; run ~/.claude/acstack/bin/acstack project-data migrate first")
|
|
137
|
-
except (OSError, subprocess.CalledProcessError) as error:
|
|
138
|
-
print("acstack: project-data ensure failed; ignore policy is not confirmed installed. Leaving the active handoff untouched. " + str(error), file=sys.stderr)
|
|
139
|
-
sys.exit(0)
|
|
140
129
|
try:
|
|
141
130
|
os.makedirs(archive_dir, exist_ok=True)
|
|
142
131
|
candidate = os.path.join(archive_dir, stamp + ".md")
|
package/hooks/session-start.sh
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# Both symlinks point at ${CLAUDE_PLUGIN_ROOT}/cli/bin/acstack.js, which is a
|
|
18
18
|
# tiny node wrapper that loads ../dist/index.js.
|
|
19
19
|
#
|
|
20
|
-
# When a project is initialized (
|
|
20
|
+
# When a project is initialized (its project folder holds project.yaml), the hook also
|
|
21
21
|
# injects the plugin's orchestrator instructions as additionalContext so installs
|
|
22
22
|
# stay version-agnostic. Otherwise prints a one-line reminder.
|
|
23
23
|
|
|
@@ -181,14 +181,12 @@ if [ -n "$plugin_root" ]; then
|
|
|
181
181
|
esac
|
|
182
182
|
fi
|
|
183
183
|
|
|
184
|
-
# Install the ignore baseline even when setup has not written project.yaml.
|
|
185
184
|
source "${plugin_root}/hooks/project-data.sh"
|
|
186
|
-
|
|
187
|
-
if ! acstack_ensure_project_data "$project_root" "$cli_wrapper"; then
|
|
185
|
+
if ! project_folder=$(acstack_project_folder "$cli_wrapper"); then
|
|
188
186
|
exit 0
|
|
189
187
|
fi
|
|
190
188
|
|
|
191
|
-
if [ ! -f "$
|
|
189
|
+
if [ ! -f "$project_folder/project.yaml" ]; then
|
|
192
190
|
echo 'acstack: no project config found. Run /acstack:setup to set up.' >&2
|
|
193
191
|
exit 0
|
|
194
192
|
fi
|
|
@@ -205,7 +203,7 @@ if ! command -v python3 >/dev/null 2>&1; then
|
|
|
205
203
|
exit 0
|
|
206
204
|
fi
|
|
207
205
|
|
|
208
|
-
python3 - "$claude_md" <<'PY'
|
|
206
|
+
python3 - "$claude_md" "$project_folder" <<'PY'
|
|
209
207
|
import json, re, sys
|
|
210
208
|
path = sys.argv[1]
|
|
211
209
|
with open(path, 'r', encoding='utf-8') as f:
|
|
@@ -213,6 +211,7 @@ with open(path, 'r', encoding='utf-8') as f:
|
|
|
213
211
|
# SessionStart reaches the lead session, so it keeps the lead block and drops the delegated one.
|
|
214
212
|
content = re.sub(r'<!-- acstack:delegated:start -->[\s\S]*?<!-- acstack:delegated:end -->\n?', '', content)
|
|
215
213
|
content = re.sub(r'<!-- acstack:lead:(start|end) -->\n?', '', content)
|
|
214
|
+
content += "\n\nThis repository's ACStack project folder: " + sys.argv[2] + "\n"
|
|
216
215
|
print(json.dumps({
|
|
217
216
|
"hookSpecificOutput": {
|
|
218
217
|
"hookEventName": "SessionStart",
|
package/orchestrator/AGENTS.md
CHANGED
|
@@ -87,17 +87,22 @@ ACStack runs on Claude Code, Codex, and pi. The skills name each capability once
|
|
|
87
87
|
|
|
88
88
|
## Project configuration
|
|
89
89
|
|
|
90
|
-
- All ACStack-owned project data lives
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
- All ACStack-owned project data lives in one folder per repository, the **project folder**
|
|
91
|
+
- `~/.claude/acstack/bin/acstack project-data path` prints its absolute path, even before it exists
|
|
92
|
+
- Every worktree of a repository shares it; the session-start hook also states it in your context
|
|
93
|
+
- The command exits non-zero outside a Git repository, and names the fix for legacy data, orphaned entries, or conflicts
|
|
94
|
+
- These files write its parts as `<project folder>/project.yaml`, `<project folder>/specs/`, and so on
|
|
95
|
+
- **Global mode** (the default) keeps the project folder under `~/.acstack/projects/` (or `$ACSTACK_HOME/projects/`)
|
|
96
|
+
- The repository holds no ACStack files and needs no `.gitignore` rules
|
|
97
|
+
- **Tracked mode** (opt-in) keeps the records in the main checkout's committed `.acstack/`; the project folder is a link to it
|
|
98
|
+
- Edits to a feature branch's own `.acstack/` take effect only once they reach the main checkout
|
|
99
|
+
- Data moves only when the developer asks: `acstack project-data mode tracked|global`, `migrate`, or `relink <entry>`
|
|
100
|
+
- For legacy layouts, follow the explicit migration procedure in `docs/config-reference.md`
|
|
101
|
+
- Update installed tools first, stop old agents and review servers, migrate, then restart with updated tools
|
|
102
|
+
- Never silently migrate data or work around legacy data by creating a partial project folder
|
|
103
|
+
- Never change the Git index or force-add files to track project data
|
|
104
|
+
|
|
105
|
+
All project-specific commands and paths come from `<project folder>/project.yaml`. Read this file before you run any build, test or lint command. If it doesn't exist, prompt the user to run `/acstack:setup`.
|
|
101
106
|
|
|
102
107
|
Key fields:
|
|
103
108
|
|
|
@@ -331,19 +336,19 @@ The investigator reports:
|
|
|
331
336
|
|
|
332
337
|
Spec sync keeps living specs current, whichever workflow you ran. It runs as part of every `/acstack:commit`.
|
|
333
338
|
|
|
334
|
-
When `workflow.spec_sync` is `true` in
|
|
339
|
+
When `workflow.spec_sync` is `true` in `<project folder>/project.yaml`:
|
|
335
340
|
|
|
336
341
|
1. Run `git diff --staged` to see what is changing
|
|
337
|
-
2. Map changed files to spec domains via
|
|
338
|
-
3. For each affected domain with a
|
|
342
|
+
2. Map changed files to spec domains via `<project folder>/domain-map.yaml`
|
|
343
|
+
3. For each affected domain with a `<project folder>/specs/[domain]/spec.md`:
|
|
339
344
|
- Analyze what the staged changes ADD, MODIFY, or REMOVE
|
|
340
345
|
- Generate lightweight ADDED/MODIFIED/REMOVED entries
|
|
341
346
|
- Update the spec.md
|
|
342
|
-
4. Stage updated specs only when
|
|
343
|
-
-
|
|
347
|
+
4. Stage updated specs only in tracked mode, when you commit in the main checkout
|
|
348
|
+
- In global mode, and from other worktrees in tracked mode, specs update in place and stay out of the commit
|
|
344
349
|
5. Flag unmapped source files. Prompt the user to map them.
|
|
345
350
|
|
|
346
|
-
Spec sync updates
|
|
351
|
+
Spec sync updates the living specs with every commit, whether or not the commit includes them.
|
|
347
352
|
|
|
348
353
|
---
|
|
349
354
|
|
|
@@ -360,9 +365,9 @@ Spec sync updates local records with every commit, including when those records
|
|
|
360
365
|
|
|
361
366
|
## Living specs
|
|
362
367
|
|
|
363
|
-
-
|
|
368
|
+
- `<project folder>/specs/` contains the cumulative source of truth for the system
|
|
364
369
|
- `/acstack:commit` updates them automatically through spec sync; `/acstack:archive` closes out a cleared map
|
|
365
|
-
- Domain-organized per
|
|
370
|
+
- Domain-organized per `<project folder>/domain-map.yaml`
|
|
366
371
|
- Format: Given/When/Then, FR-NNN requirements
|
|
367
372
|
- Bootstrap from existing codebase: `/acstack:bootstrap`
|
|
368
373
|
- Map nodes: ACStack CLI (`~/.claude/acstack/bin/acstack node create | read | update | list`, plus the composed `node frontier` and `node walk` queries)
|
|
@@ -385,12 +390,12 @@ Read-only reviewers report discrepancies to the completion owner.
|
|
|
385
390
|
|
|
386
391
|
The verification owner gathers evidence for the final revision. Opening a PR does not require running every test locally.
|
|
387
392
|
|
|
388
|
-
Read
|
|
393
|
+
Read `<project folder>/project.yaml` for the available commands and inspect the project's CI configuration before relying on it:
|
|
389
394
|
|
|
390
395
|
1. Use focused local checks by default: cover changed behavior, affected callers, and relevant integration paths
|
|
391
396
|
2. Run applicable build, lint, and typecheck checks; scope them when the tooling supports it
|
|
392
397
|
3. A configured command is not a requirement to run its entire suite. Run the full suite locally only when explicitly required by the user or project instructions, or when broad or uncertain impact cannot be covered adequately by narrower checks
|
|
393
|
-
4. When `commands.test_collect` is configured, compare the count against
|
|
398
|
+
4. When `commands.test_collect` is configured, compare the count against `<project folder>/.test-baseline` if present; investigate removed coverage and honor project baseline requirements
|
|
394
399
|
5. Run configured frontend build, lint, and tests when frontend files changed, and complete applicable design and browser gates
|
|
395
400
|
|
|
396
401
|
Required CI checks must pass before merge, not before opening a PR. Defer broader checks to CI only after confirming it runs them for this change; do not assume CI runs every test.
|
|
@@ -419,7 +424,7 @@ Do not claim completion with failed or blocked required checks. Investigate, fix
|
|
|
419
424
|
|
|
420
425
|
## Frontend visual verification
|
|
421
426
|
|
|
422
|
-
**This section applies only when
|
|
427
|
+
**This section applies only when `<project folder>/project.yaml` sets `frontend` and `workflow.frontend_verification` is `true`.**
|
|
423
428
|
|
|
424
429
|
When a change touches frontend files, delegate real-browser verification to frontend-verifier after required checks pass. Never substitute a confidence claim for browser evidence.
|
|
425
430
|
|
|
@@ -427,7 +432,7 @@ The design pass runs before browser verification when the design gate is on, fol
|
|
|
427
432
|
|
|
428
433
|
The frontend-verifier agent:
|
|
429
434
|
|
|
430
|
-
1. Reads the project's verification knowledge base (
|
|
435
|
+
1. Reads the project's verification knowledge base (`<project folder>/verification/VERIFICATION-KNOWLEDGE.md`)
|
|
431
436
|
2. Checks what frontend files changed
|
|
432
437
|
3. Starts the dev server if it's not running
|
|
433
438
|
4. Connects to a browser through the Chrome DevTools Protocol (CDP), over a remote tunnel or local headless Chromium
|
|
@@ -440,8 +445,8 @@ The frontend-verifier agent:
|
|
|
440
445
|
|
|
441
446
|
Run `/acstack:setup` to set up browser verification. This creates:
|
|
442
447
|
|
|
443
|
-
-
|
|
444
|
-
-
|
|
448
|
+
- **`<project folder>/agent-browser.json`** – CDP connection config, selected by an absolute `--config` path or `AGENT_BROWSER_CONFIG`
|
|
449
|
+
- **`<project folder>/verification/VERIFICATION-KNOWLEDGE.md`** – Evolving knowledge base of element patterns, gotchas, and proven verification sequences
|
|
445
450
|
|
|
446
451
|
`frontend.browser.mode` in project.yaml holds the browser environment: remote, headless, or local.
|
|
447
452
|
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@ You review screenshots. You report results. You do not need user approval.
|
|
|
28
28
|
|
|
29
29
|
## Project configuration
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
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:
|
|
32
32
|
|
|
33
33
|
- `frontend.directory` – frontend source directory
|
|
34
34
|
- `frontend.dev_server_url` – dev server URL
|
|
@@ -39,14 +39,15 @@ Read `.acstack/project.yaml` for frontend settings:
|
|
|
39
39
|
|
|
40
40
|
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.
|
|
41
41
|
|
|
42
|
-
If
|
|
42
|
+
If `<project folder>/project.yaml` has no `frontend` section, report SKIP and exit.
|
|
43
43
|
|
|
44
44
|
## Step 0: Read the knowledge base
|
|
45
45
|
|
|
46
46
|
Before doing anything, check for a knowledge base:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
|
|
49
|
+
project="$(~/.claude/acstack/bin/acstack project-data path)"
|
|
50
|
+
cat "$project/verification/VERIFICATION-KNOWLEDGE.md" 2>/dev/null
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
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.
|
|
@@ -205,10 +206,10 @@ Track whether you launched the browser so you can clean it up in Step 8.
|
|
|
205
206
|
|
|
206
207
|
## Step 4: Verify with agent-browser
|
|
207
208
|
|
|
208
|
-
Select the project's browser config explicitly
|
|
209
|
+
Select the project's browser config explicitly by its absolute path:
|
|
209
210
|
|
|
210
211
|
```bash
|
|
211
|
-
export AGENT_BROWSER_CONFIG="$(
|
|
212
|
+
export AGENT_BROWSER_CONFIG="$(~/.claude/acstack/bin/acstack project-data path)/agent-browser.json"
|
|
212
213
|
```
|
|
213
214
|
|
|
214
215
|
Require the file for configured verification; do not assume root config autodiscovery.
|
|
@@ -299,13 +300,13 @@ After every verification run, update the knowledge base if you learned something
|
|
|
299
300
|
|
|
300
301
|
### Knowledge base
|
|
301
302
|
|
|
302
|
-
|
|
303
|
+
`<project folder>/verification/VERIFICATION-KNOWLEDGE.md` – URL patterns, element patterns, gotchas, lessons learned.
|
|
303
304
|
|
|
304
305
|
If it doesn't exist, create it with what you learned during this run.
|
|
305
306
|
|
|
306
307
|
### Rules
|
|
307
308
|
|
|
308
|
-
- All verification knowledge lives in
|
|
309
|
+
- All verification knowledge lives in `<project folder>/verification/VERIFICATION-KNOWLEDGE.md`.
|
|
309
310
|
- Do NOT create knowledge files anywhere else.
|
|
310
311
|
- If a selector or element pattern stops working, update the knowledge base.
|
|
311
312
|
- If you discover a new pattern, add it.
|
|
@@ -19,7 +19,7 @@ You are read-only: do not edit source, tests, or specs.
|
|
|
19
19
|
## Establish scope and ownership
|
|
20
20
|
|
|
21
21
|
Read the supplied requirements, affected paths, known risks, and available command results.
|
|
22
|
-
Read
|
|
22
|
+
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.
|
|
23
23
|
|
|
24
24
|
- Distinguish focused review from ownership of completion verification
|
|
25
25
|
- If the assignment is unclear, clarify it with the delegating session before duplicating checks
|
|
@@ -23,7 +23,7 @@ Implement the assigned requirements under the shared Implementation discipline i
|
|
|
23
23
|
|
|
24
24
|
## Project configuration
|
|
25
25
|
|
|
26
|
-
Read
|
|
26
|
+
Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
|
|
27
27
|
|
|
28
28
|
- `directories.source` – where to write source code
|
|
29
29
|
- `directories.tests` – test directory, subject to assigned ownership
|
package/pi/agents/test-writer.md
CHANGED
|
@@ -32,7 +32,7 @@ You write tests from requirements and application programming interface (API) co
|
|
|
32
32
|
|
|
33
33
|
## Project configuration
|
|
34
34
|
|
|
35
|
-
Read
|
|
35
|
+
Read `project.yaml` in the project folder that `~/.claude/acstack/bin/acstack project-data path` prints for project-specific settings:
|
|
36
36
|
|
|
37
37
|
- `directories.tests` – where to create test files
|
|
38
38
|
- `directories.source` – source code root (for mirroring structure)
|