compound-workflow 1.8.0 → 1.9.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/README.md +61 -69
- package/package.json +2 -8
- package/scripts/check-pack-readme.mjs +1 -16
- package/scripts/check-workflow-contracts.mjs +34 -44
- package/scripts/install-cli.mjs +273 -555
- package/src/AGENTS.md +59 -192
- package/src/{.agents/agents → agents}/research/best-practices-researcher.md +2 -2
- package/src/{.agents/commands → commands}/assess.md +4 -4
- package/src/commands/install.md +43 -0
- package/src/{.agents/commands → commands}/metrics.md +1 -1
- package/src/commands/workflow-agents.md +101 -0
- package/src/{.agents/commands → commands}/workflow-compound.md +1 -1
- package/src/{.agents/commands → commands}/workflow-plan.md +24 -33
- package/src/commands/workflow-work.md +836 -0
- package/src/{.agents/references → references}/README.md +1 -1
- package/src/{.agents/skills → skills}/capture-skill/SKILL.md +1 -1
- package/src/{.agents/skills → skills}/compound-docs/SKILL.md +6 -6
- package/src/{.agents/skills → skills}/compound-docs/references/yaml-schema.md +2 -2
- package/src/skills/setup-agents/SKILL.md +250 -0
- package/src/skills/standards/SKILL.md +79 -0
- package/src/skills/standards/references/architecture.md +228 -0
- package/src/skills/standards/references/code-quality.md +192 -0
- package/src/skills/standards/references/presentation.md +515 -0
- package/src/skills/standards/references/services.md +172 -0
- package/src/skills/standards/references/state-management.md +936 -0
- package/.claude-plugin/plugin.json +0 -7
- package/.cursor-plugin/plugin.json +0 -20
- package/.cursor-plugin/registration.json +0 -5
- package/scripts/check-version-parity.mjs +0 -36
- package/scripts/generate-platform-artifacts.mjs +0 -230
- package/src/.agents/commands/install.md +0 -51
- package/src/.agents/commands/workflow-work.md +0 -690
- package/src/.agents/registry.json +0 -48
- package/src/.agents/scripts/self-check.mjs +0 -227
- package/src/.agents/scripts/sync-opencode.mjs +0 -362
- package/src/.agents/skills/presentation-composability/SKILL.md +0 -72
- package/src/.agents/skills/react-ddd-mvc-frontend/SKILL.md +0 -51
- package/src/.agents/skills/react-ddd-mvc-frontend/references/feature-structure.md +0 -25
- package/src/.agents/skills/react-ddd-mvc-frontend/references/implementation-principles.md +0 -21
- package/src/.agents/skills/react-ddd-mvc-frontend/references/responsibility-gates.md +0 -41
- package/src/.agents/skills/react-ddd-mvc-frontend/references/source-map.md +0 -11
- package/src/.agents/skills/standards/SKILL.md +0 -747
- package/src/.agents/skills/xstate-actor-orchestration/SKILL.md +0 -197
- package/src/.agents/skills/xstate-actor-orchestration/agents/openai.yaml +0 -4
- package/src/.agents/skills/xstate-actor-orchestration/assets/statecharts/.gitkeep +0 -0
- package/src/.agents/skills/xstate-actor-orchestration/references/actor-system-patterns.md +0 -71
- package/src/.agents/skills/xstate-actor-orchestration/references/event-contracts.md +0 -73
- package/src/.agents/skills/xstate-actor-orchestration/references/functional-domain-patterns.md +0 -53
- package/src/.agents/skills/xstate-actor-orchestration/references/machine-structure-and-tags.md +0 -36
- package/src/.agents/skills/xstate-actor-orchestration/references/react-container-pattern.md +0 -45
- package/src/.agents/skills/xstate-actor-orchestration/references/reliability-observability.md +0 -39
- package/src/.agents/skills/xstate-actor-orchestration/references/skill-validation.md +0 -33
- package/src/.agents/skills/xstate-actor-orchestration/references/source-map.md +0 -44
- package/src/.agents/skills/xstate-actor-orchestration/references/statechart-review-and-signoff.md +0 -59
- package/src/.agents/skills/xstate-actor-orchestration/references/testing-strategy.md +0 -35
- package/src/.agents/skills/xstate-actor-orchestration/scripts/create-statechart-artifact.sh +0 -71
- package/src/.agents/skills/xstate-actor-orchestration/scripts/validate-skill.sh +0 -138
- package/src/generated/opencode.managed.json +0 -115
- /package/src/{.agents/agents → agents}/research/framework-docs-researcher.md +0 -0
- /package/src/{.agents/agents → agents}/research/git-history-analyzer.md +0 -0
- /package/src/{.agents/agents → agents}/research/learnings-researcher.md +0 -0
- /package/src/{.agents/agents → agents}/research/repo-research-analyst.md +0 -0
- /package/src/{.agents/agents → agents}/review/agent-native-reviewer.md +0 -0
- /package/src/{.agents/agents → agents}/review/planning-technical-reviewer.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/bug-reproduction-validator.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/lint.md +0 -0
- /package/src/{.agents/agents → agents}/workflow/spec-flow-analyzer.md +0 -0
- /package/src/{.agents/commands → commands}/test-browser.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-brainstorm.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-review.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-tech-review.md +0 -0
- /package/src/{.agents/commands → commands}/workflow-triage.md +0 -0
- /package/src/{.agents/references → references}/standards/README.md +0 -0
- /package/src/{.agents/skills → skills}/agent-browser/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/audit-traceability/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/brainstorming/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/assets/critical-pattern-template.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/assets/resolution-template.md +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/schema.project.yaml +0 -0
- /package/src/{.agents/skills → skills}/compound-docs/schema.yaml +0 -0
- /package/src/{.agents/skills → skills}/data-foundations/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/document-review/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/file-todos/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/file-todos/assets/todo-template.md +0 -0
- /package/src/{.agents/skills → skills}/financial-workflow-integrity/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/git-worktree/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/pii-protection-prisma/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/SKILL.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/daily-template.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/monthly-template.md +0 -0
- /package/src/{.agents/skills → skills}/process-metrics/assets/weekly-template.md +0 -0
- /package/src/{.agents/skills → skills}/technical-review/SKILL.md +0 -0
|
@@ -12,7 +12,7 @@ This skill extracts reusable knowledge from the current conversation and stores
|
|
|
12
12
|
`capture-skill` uses an overlay model by default:
|
|
13
13
|
|
|
14
14
|
- Treat existing repo-provided skills as immutable unless the user explicitly asks to edit a specific one.
|
|
15
|
-
- Store project-specific refinements in a project overlay skill (for example,
|
|
15
|
+
- Store project-specific refinements in a project overlay skill (for example, a `project-standards/` skill in the current harness skills directory — resolve from `harnesses` in AGENTS.md Repo Config).
|
|
16
16
|
- Only modify an existing skill when the user clearly says to do so (for example, "update skill X").
|
|
17
17
|
- Promote overlay content into base skills only as an explicit, deliberate follow-up action.
|
|
18
18
|
|
|
@@ -153,8 +153,8 @@ Format: `YYYY-MM-DD-<module-slug>-<symptom-slug>.md`
|
|
|
153
153
|
|
|
154
154
|
**Validate against schema:**
|
|
155
155
|
|
|
156
|
-
1. Load
|
|
157
|
-
2. If
|
|
156
|
+
1. Load `schema.yaml` from the same directory as this skill file.
|
|
157
|
+
2. If `schema.project.yaml` exists in the same directory, validate against it as the repo-specific overlay.
|
|
158
158
|
3. Use [yaml-schema.md](./references/yaml-schema.md) as the human-readable reference.
|
|
159
159
|
|
|
160
160
|
Ensure all required fields are present and match allowed values exactly for enum fields.
|
|
@@ -335,8 +335,8 @@ Action:
|
|
|
335
335
|
|
|
336
336
|
Example:
|
|
337
337
|
|
|
338
|
-
- Add to
|
|
339
|
-
- Add to
|
|
338
|
+
- Add to `<skill-name>/references/resources.md` in the current harness skills directory (resolve from `harnesses` in AGENTS.md Repo Config) under "Project-Specific Resources" (if it exists)
|
|
339
|
+
- Add to `<skill-name>/references/examples.md` in the current harness skills directory with a link to the solution doc (if it exists)
|
|
340
340
|
|
|
341
341
|
**Option 6: Create new skill**
|
|
342
342
|
|
|
@@ -344,8 +344,8 @@ User selects this when the solution represents the start of a new learning domai
|
|
|
344
344
|
|
|
345
345
|
Action:
|
|
346
346
|
1. Prompt: "What should the new skill be called? (e.g., stripe-billing, email-processing)"
|
|
347
|
-
2. Create a new skill directory:
|
|
348
|
-
3. Add
|
|
347
|
+
2. Create a new skill directory: `<skill-name>/` in the skills directory of the current harness (resolve from `harnesses` in AGENTS.md Repo Config)
|
|
348
|
+
3. Add `SKILL.md` in the new skill directory with a clear description (what + when to use)
|
|
349
349
|
4. Create initial reference files (optional) and add this solution doc as the first example
|
|
350
350
|
5. Confirm: "✓ Created new <skill-name> skill with this solution as first example"
|
|
351
351
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# YAML Frontmatter Schema
|
|
2
2
|
|
|
3
|
-
**See
|
|
3
|
+
**See `schema.yaml` in the same directory as this skill for the core portable schema specification.**
|
|
4
4
|
|
|
5
|
-
If present,
|
|
5
|
+
If present, `schema.project.yaml` in the same directory acts as an optional repo-specific overlay for stricter enums.
|
|
6
6
|
|
|
7
7
|
## Required Fields
|
|
8
8
|
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-agents
|
|
3
|
+
description: Create or update AGENTS.md for any project. Detects project stack and installed harness directories, prompts for missing config, curates the Skill Index from installed skills, and writes a clean minimal AGENTS.md. Use when onboarding a new project or refreshing an existing config.
|
|
4
|
+
triggers:
|
|
5
|
+
- setting up a new project
|
|
6
|
+
- initialising AGENTS.md for the first time
|
|
7
|
+
- updating or refreshing an existing AGENTS.md
|
|
8
|
+
- onboarding a new repo to the workflow
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Setup AGENTS.md
|
|
12
|
+
|
|
13
|
+
<!-- Structural source of truth for AGENTS.md format. The default template shipped in
|
|
14
|
+
src/AGENTS.md is a populated instance of the Phase 4 template below.
|
|
15
|
+
When changing the template here, update src/AGENTS.md to match (and vice versa). -->
|
|
16
|
+
|
|
17
|
+
Create or update a minimal, authoritative `AGENTS.md` for any project.
|
|
18
|
+
|
|
19
|
+
## Mode Detection
|
|
20
|
+
|
|
21
|
+
Before doing anything, check whether `AGENTS.md` exists in the repo root.
|
|
22
|
+
|
|
23
|
+
- **If it does not exist:** run in `init` mode — build from scratch.
|
|
24
|
+
- **If it exists:** run in `update` mode — read the current file, preserve what is correct, update what is stale, and prompt for anything missing.
|
|
25
|
+
|
|
26
|
+
Announce the mode before proceeding.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Phase 1: Detect Harness Directories and Project Stack
|
|
31
|
+
|
|
32
|
+
### Harness detection
|
|
33
|
+
|
|
34
|
+
Check which directories exist at the project root. Do not assume any are present — record only what is actually found on disk.
|
|
35
|
+
|
|
36
|
+
Known harness patterns to check: directories named `.agents`, `.claude`, `.cursor`. Check all three; others may exist.
|
|
37
|
+
|
|
38
|
+
For each found harness, note where its skills live:
|
|
39
|
+
- `<harness>/skills/` — if that subdirectory exists
|
|
40
|
+
- `.claude/` has no skills directory (agents only, in `.claude/agents/`)
|
|
41
|
+
|
|
42
|
+
Record detected harnesses as `$harnesses` (ordered list of directories found). This will be written to AGENTS.md.
|
|
43
|
+
|
|
44
|
+
If **no harness directories exist**, stop and tell the user:
|
|
45
|
+
> No harness directories found. Run `npx compound-workflow install` first, then re-run this skill.
|
|
46
|
+
|
|
47
|
+
Use the **first found skills directory** across `$harnesses` as the canonical source for skill discovery in Phase 3. Record this as `$skills_dir`.
|
|
48
|
+
|
|
49
|
+
> **Note:** `harnesses` in AGENTS.md Repo Config may become stale if harness directories are added or removed. Re-run `/setup-agents` to refresh it.
|
|
50
|
+
|
|
51
|
+
### Project stack detection
|
|
52
|
+
|
|
53
|
+
Read the following files if they exist (do not error if missing):
|
|
54
|
+
|
|
55
|
+
- `package.json` (scripts, dependencies, devDependencies)
|
|
56
|
+
- `vite.config.ts` / `vite.config.js`
|
|
57
|
+
- `tsconfig.json`
|
|
58
|
+
- `.eslintrc.*` / `eslint.config.*`
|
|
59
|
+
- `vitest.config.ts` / `jest.config.*`
|
|
60
|
+
- `turbo.json` / `nx.json` (monorepo signals)
|
|
61
|
+
|
|
62
|
+
From these, infer:
|
|
63
|
+
|
|
64
|
+
| Config key | Detection signal |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `test_command` | `scripts.test` in package.json; vitest/jest config presence |
|
|
67
|
+
| `test_fast_command` | `scripts.test:fast`, `scripts.test:watch`, or vitest equivalent |
|
|
68
|
+
| `lint_command` | `scripts.lint` in package.json; eslint config presence |
|
|
69
|
+
| `typecheck_command` | `scripts.typecheck` or `scripts.type-check`; tsconfig presence |
|
|
70
|
+
| `format_command` | `scripts.format` in package.json; prettier config presence |
|
|
71
|
+
| `dev_server_url` | vite config `server.port`; default `http://localhost:5173` for Vite, `http://localhost:3000` for others |
|
|
72
|
+
| `worktree_install_command` | `package-lock.json` → `npm ci`; `yarn.lock` → `yarn install`; `pnpm-lock.yaml` → `pnpm install` |
|
|
73
|
+
|
|
74
|
+
For each value, state whether it was detected or assumed.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Phase 2: Prompt for Missing or Undetectable Values
|
|
79
|
+
|
|
80
|
+
Ask for any values that could not be detected. Ask one at a time.
|
|
81
|
+
|
|
82
|
+
Required:
|
|
83
|
+
|
|
84
|
+
- `default_branch` — cannot be reliably detected; ask (suggest `main`)
|
|
85
|
+
- `project_tracker` — ask: `github`, `linear`, or none
|
|
86
|
+
- `dev_server_url` — confirm detected value or ask
|
|
87
|
+
- `worktree_dir` — suggest `.worktrees`
|
|
88
|
+
- `worktree_copy_files` — ask which env/config files should be copied into new worktrees (e.g. `.env.local`)
|
|
89
|
+
- `harnesses` — show detected list from Phase 1; confirm or correct
|
|
90
|
+
|
|
91
|
+
**Update mode only:** Show the current values and ask: "These values are already configured — confirm, update, or skip each?"
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Phase 3: Curate the Skill Index
|
|
96
|
+
|
|
97
|
+
List all directories under `$skills_dir` (resolved in Phase 1). For each one, read `SKILL.md` frontmatter to get `name` and `description`. These are the only skills that may appear in the Skill Index — never reference a skill not present on disk.
|
|
98
|
+
|
|
99
|
+
Present the full discovered list to the user as a numbered menu:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
Installed skills (from <$skills_dir>):
|
|
103
|
+
1. <name> — <description from frontmatter>
|
|
104
|
+
2. <name> — <description from frontmatter>
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
Which should appear in the Skill Index? (Enter numbers, or "all", or "all except N,N")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Init mode:** Ask which to include.
|
|
111
|
+
**Update mode:** Show which are currently included and ask: "Keep, remove, or any to add?"
|
|
112
|
+
|
|
113
|
+
Do not categorise skills in advance — the user decides what is relevant for their project.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Phase 4: Write AGENTS.md
|
|
118
|
+
|
|
119
|
+
Using all resolved values, write a clean `AGENTS.md` following this exact template.
|
|
120
|
+
|
|
121
|
+
**Init mode:** write the full file.
|
|
122
|
+
**Update mode:** preserve any sections the user confirmed as correct; replace only what changed.
|
|
123
|
+
|
|
124
|
+
```markdown
|
|
125
|
+
# Agent Operating Principles
|
|
126
|
+
|
|
127
|
+
This workspace is portable and command-first.
|
|
128
|
+
|
|
129
|
+
## Core Principles
|
|
130
|
+
|
|
131
|
+
1. Commands are the public API. Skills and agents are composable internals.
|
|
132
|
+
2. Core workflows stay generic. Domain-specific behavior loads only when context requires it.
|
|
133
|
+
3. Planning quality is explicit via fidelity selection.
|
|
134
|
+
4. Selection must be deterministic and visible: always state which skills/agents were selected and why.
|
|
135
|
+
5. Brainstorm and plan do not write code.
|
|
136
|
+
|
|
137
|
+
## Contract Precedence
|
|
138
|
+
|
|
139
|
+
If workflow documents conflict, resolve in this order:
|
|
140
|
+
|
|
141
|
+
1. `docs/principles/workflow-baseline-principles.md`
|
|
142
|
+
2. This file — non-negotiables and repo config
|
|
143
|
+
3. Workflow command specs
|
|
144
|
+
4. Skill docs
|
|
145
|
+
|
|
146
|
+
## Canonical Workflow
|
|
147
|
+
|
|
148
|
+
1. `/workflow:brainstorm` — clarify what to build
|
|
149
|
+
2. `/workflow:plan` — define how to build it
|
|
150
|
+
3. `/workflow:work` — implement (includes triage gate)
|
|
151
|
+
4. `/workflow:review` — validate quality
|
|
152
|
+
5. `/workflow:compound` — capture durable learnings
|
|
153
|
+
|
|
154
|
+
Optional:
|
|
155
|
+
|
|
156
|
+
- `/workflow:triage` — manually curate/prioritize queue before execution
|
|
157
|
+
- `/workflow:tech-review` — technical correctness check on a plan before build
|
|
158
|
+
|
|
159
|
+
Continuous improvement:
|
|
160
|
+
|
|
161
|
+
- `/metrics` — log + assess a session
|
|
162
|
+
- `/assess` — aggregate metrics and propose improvements
|
|
163
|
+
|
|
164
|
+
## Non-negotiables (Structure Integrity)
|
|
165
|
+
|
|
166
|
+
- **Commands are the public API.** Keep `/workflow:*` command docs stable; add capability via skills/agents, not new command variants.
|
|
167
|
+
- **Brainstorm = WHAT, Plan = HOW.** `/workflow:plan` must not re-litigate decisions already captured in `docs/brainstorms/`.
|
|
168
|
+
- **Local grounding is mandatory.** Every plan must cite at least 1–3 internal file path/line refs and any relevant `docs/solutions/**` learnings.
|
|
169
|
+
- **Fidelity + confidence are required declarations** in every plan file.
|
|
170
|
+
- **Solution scope contract is mandatory in every plan.** Plans must declare `solution_scope` (`partial_fix|full_remediation|migration`) plus completion expectation and non-goals.
|
|
171
|
+
- **Isolation preflight is a hard gate.** `/workflow:work` must complete and record worktree/isolation preflight before any implementation commands.
|
|
172
|
+
- **Triage before execution is mandatory.** `/workflow:work` must run a triage pass before executing todos.
|
|
173
|
+
- **Independent review is required for code/config changes.** `/workflow:review` must emit `review_independence_mode: independent|degraded`.
|
|
174
|
+
- **Standards baseline is mandatory for code/config changes.** `/workflow:work` and `/workflow:review` must apply `skill: standards` as a hard gate.
|
|
175
|
+
- **Todo completion requires evidence.** A todo may move to `complete` only after success criteria and quality gate evidence are recorded.
|
|
176
|
+
- **No ad-hoc artifacts outside canonical outputs** (`docs/plans`, `todos`, `docs/solutions`, `docs/metrics`) unless explicitly requested.
|
|
177
|
+
|
|
178
|
+
## Planning Fidelity Model
|
|
179
|
+
|
|
180
|
+
`/workflow:plan` must always declare: `Fidelity`, `Confidence`, `solution_scope`, rationale, research mode, and open questions.
|
|
181
|
+
|
|
182
|
+
- **Low** — problem, constraints, acceptance criteria, implementation outline, verification checklist.
|
|
183
|
+
- **Medium** — all Low + alternatives/tradeoffs, dependency/risk table, rollout notes, observability/test notes.
|
|
184
|
+
- **High** — all Medium + failure modes, rollback plan, deployment gates, migration/data safety checks, expanded test matrix.
|
|
185
|
+
|
|
186
|
+
Select `High` if any high-risk trigger exists (security, payments, privacy, data migration, production infra). Default to `Medium` for mixed signals. Otherwise `Low`.
|
|
187
|
+
|
|
188
|
+
## Routing Rules
|
|
189
|
+
|
|
190
|
+
- **Centralized skill routing:** Add new domain/reference skill routing in this file (Skill Index) rather than per-command.
|
|
191
|
+
- **Default selection order:** (1) safety/guardrail standards, (2) domain architecture/reference skills, (3) workflow execution skills. Minimal set that covers the problem.
|
|
192
|
+
- **Explain selection:** Always state which skills were selected and why.
|
|
193
|
+
- Run local repo + institutional learnings research first for planning. External research based on fidelity and risk.
|
|
194
|
+
|
|
195
|
+
## Repo Config Block
|
|
196
|
+
|
|
197
|
+
\`\`\`yaml
|
|
198
|
+
default_branch: <value>
|
|
199
|
+
project_tracker: <github|linear|none>
|
|
200
|
+
dev_server_url: <value>
|
|
201
|
+
test_command: <value>
|
|
202
|
+
test_fast_command: <value or omit>
|
|
203
|
+
lint_command: <value or omit>
|
|
204
|
+
typecheck_command: <value or omit>
|
|
205
|
+
format_command: <value or omit>
|
|
206
|
+
worktree_dir: <value>
|
|
207
|
+
worktree_install_command: <value>
|
|
208
|
+
worktree_copy_files:
|
|
209
|
+
- <file1>
|
|
210
|
+
harnesses:
|
|
211
|
+
- <detected harness dir 1>
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
## Skill Index
|
|
215
|
+
|
|
216
|
+
| Skill | Use when |
|
|
217
|
+
| --- | --- |
|
|
218
|
+
[... one row per skill the user selected in Phase 3; use the description from each skill's SKILL.md frontmatter ...]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Confirm: "AGENTS.md written."
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Phase 5: Validation
|
|
226
|
+
|
|
227
|
+
After writing, verify:
|
|
228
|
+
|
|
229
|
+
- [ ] All required Repo Config Block keys are present and non-empty
|
|
230
|
+
- [ ] `harnesses` lists only directories detected on disk in Phase 1 — no invented entries
|
|
231
|
+
- [ ] Every skill in the Skill Index was discovered from `$skills_dir` — no invented entries
|
|
232
|
+
- [ ] All skill descriptions come from `SKILL.md` frontmatter — none invented by the agent
|
|
233
|
+
- [ ] No hardcoded tool, platform, or directory names
|
|
234
|
+
- [ ] File is under 130 lines
|
|
235
|
+
|
|
236
|
+
If any check fails, fix before confirming completion.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Rules
|
|
241
|
+
|
|
242
|
+
- Never add sections beyond what the template defines — keep it minimal
|
|
243
|
+
- Never hardcode skill names — discover everything from the detected skills directory
|
|
244
|
+
- Never hardcode harness paths — detect what exists on disk first; `harnesses` in AGENTS.md reflects reality, not assumptions
|
|
245
|
+
- Never invent skill descriptions — always read from the skill's `SKILL.md` frontmatter
|
|
246
|
+
- Never hardcode tool or platform names
|
|
247
|
+
- Never duplicate content that lives in command or skill docs
|
|
248
|
+
- In update mode, never silently overwrite values the user confirmed as correct
|
|
249
|
+
- If a detected value looks wrong, surface it and ask — do not assume
|
|
250
|
+
- When the Phase 4 template changes, update `src/AGENTS.md` to match (it is the populated default instance)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: standards
|
|
3
|
+
description: >
|
|
4
|
+
Enforce frontend code standards when writing, reviewing, or refactoring frontend code.
|
|
5
|
+
Use this skill for all frontend work — new features, PR reviews, refactors,
|
|
6
|
+
component creation, or any code quality assessment. This skill defines mandatory pass/fail gates.
|
|
7
|
+
If the user is writing, reading, or evaluating frontend code in any form, use this skill
|
|
8
|
+
immediately — do not rely on general knowledge.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Frontend Standards
|
|
12
|
+
|
|
13
|
+
Five themes apply to all frontend work. All must be satisfied.
|
|
14
|
+
|
|
15
|
+
| Theme | Concern |
|
|
16
|
+
|---|---|
|
|
17
|
+
| **Architecture** | Layered model, layer boundaries, data flow direction |
|
|
18
|
+
| **Code Quality** | Control flow, immutability, error handling |
|
|
19
|
+
| **Services** | IO boundary, Effect Layer structure, runtime composition |
|
|
20
|
+
| **State Management** | Controller responsibilities, state and event contracts |
|
|
21
|
+
| **Presentation** | Component structure, composition patterns, visual conventions |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to Load Reference Files
|
|
26
|
+
|
|
27
|
+
Load the relevant reference before reviewing or writing code in that area.
|
|
28
|
+
|
|
29
|
+
| Situation | Load |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Layer structure, boundaries, or data flow | `references/architecture.md` |
|
|
32
|
+
| Control flow, error handling, or data transforms | `references/code-quality.md` |
|
|
33
|
+
| Effect services, Layers, or runtime composition | `references/services.md` |
|
|
34
|
+
| State machines, events, context, or actor patterns | `references/state-management.md` |
|
|
35
|
+
| Component structure or visual conventions | `references/presentation.md` |
|
|
36
|
+
| Full review or uncertainty about which layer applies | All five |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Mandatory Gates
|
|
41
|
+
|
|
42
|
+
Each is **pass/fail**. A single `fail` means the work is incomplete.
|
|
43
|
+
|
|
44
|
+
| Gate | Theme | Rule |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `architecture` | Architecture | All layers honour their boundaries — no layer reaches past its neighbour |
|
|
47
|
+
| `code_quality` | Code Quality | Control flow is flat, transforms are immutable, errors are handled explicitly |
|
|
48
|
+
| `services` | Services | All IO is isolated to the service layer — no IO in entities, controllers, or containers |
|
|
49
|
+
| `state_management` | State Management | Controllers own state; containers extract values and callbacks — never pass raw machine internals to components |
|
|
50
|
+
| `presentation` | Presentation | Components follow the folder, composition, and visual conventions |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Required Evidence Format
|
|
55
|
+
|
|
56
|
+
Record in all work outputs and code reviews:
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
standards_compliance:
|
|
60
|
+
- architecture: pass|fail (evidence: file:line)
|
|
61
|
+
- code_quality: pass|fail (evidence: file:line)
|
|
62
|
+
- services: pass|fail (evidence: file:line)
|
|
63
|
+
- state_management: pass|fail (evidence: file:line)
|
|
64
|
+
- presentation: pass|fail (evidence: file:line)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
On any `fail`: load the relevant reference file, surface the specific violation with evidence, explain the rule broken, and show the corrected pattern. List **all** failures before summarising — do not stop at the first.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Reference Files
|
|
72
|
+
|
|
73
|
+
| File | Theme | Contents |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `references/architecture.md` | Architecture | Layered model, layer responsibilities, file structure, import rules |
|
|
76
|
+
| `references/code-quality.md` | Code Quality | Control flow, immutability, error handling, validation boundary |
|
|
77
|
+
| `references/services.md` | Services | Effect Layer pattern, service structure, runtime composition |
|
|
78
|
+
| `references/state-management.md` | State Management | XState v5 patterns, events, guards, actions, actor communication |
|
|
79
|
+
| `references/presentation.md` | Presentation | Folder structure, compound components, barrel pattern, visual conventions |
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Architecture Reference
|
|
2
|
+
|
|
3
|
+
## The Layered Model
|
|
4
|
+
|
|
5
|
+
All frontend code follows a strict five-layer architecture. Data flows in one direction. Layers do not skip.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Entities (pure functions — transforms and predicates)
|
|
9
|
+
↓ consumed by
|
|
10
|
+
Services (Effect Layers — all IO and side effects)
|
|
11
|
+
↓ consumed by
|
|
12
|
+
Controllers (XState machines — own state and transitions)
|
|
13
|
+
↓ consumed by
|
|
14
|
+
Containers (composition layer — wire state to UI)
|
|
15
|
+
↓ consumed by
|
|
16
|
+
Presentation (UI only)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Each layer has a single responsibility. No layer reaches past its neighbour.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Layer Responsibilities
|
|
24
|
+
|
|
25
|
+
### Entities
|
|
26
|
+
|
|
27
|
+
Location: `src/features/{feature}/domain/entities/`
|
|
28
|
+
|
|
29
|
+
Entities are pure functions. They have no knowledge of state machines, services, React, or the UI. They do two things:
|
|
30
|
+
|
|
31
|
+
1. **Transforms** — `toX` functions, input → output, inbound and outbound data shaping
|
|
32
|
+
2. **Predicates** — `hasX`, `isX` functions, inferring facts from data
|
|
33
|
+
|
|
34
|
+
Entities are the data boundary for backend responses — they apply defaults and ensure correct shape as part of the transform. They may use Effect's typed utilities (`Effect.try`, `Option`, `Either`) for safe transforms, but must remain pure. No runtime, no Layer dependencies.
|
|
35
|
+
|
|
36
|
+
**Rules:**
|
|
37
|
+
- Pure functions only — no side effects, no framework imports, no IO
|
|
38
|
+
- No classes — functions only
|
|
39
|
+
- One file per concern (`PlaylistSelectionEntity.ts` vs `PlaylistReorderEntity.ts`)
|
|
40
|
+
- Private helpers stay internal — no `export`
|
|
41
|
+
|
|
42
|
+
**Naming conventions:**
|
|
43
|
+
|
|
44
|
+
| Prefix | Purpose | Example |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `hasX` | Boolean predicate | `hasAddedPlaylists` |
|
|
47
|
+
| `isX` | Boolean predicate | `isValidState` |
|
|
48
|
+
| `getX` | Retrieve/extract | `getAddedPlaylists` |
|
|
49
|
+
| `toX` | Transform | `toPlaylistIds` |
|
|
50
|
+
|
|
51
|
+
**Function signatures** — use object params for 2+ arguments:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export const hasAddedPlaylists = ({
|
|
55
|
+
current,
|
|
56
|
+
incoming,
|
|
57
|
+
}: {
|
|
58
|
+
current: InputOption[];
|
|
59
|
+
incoming: InputOption[];
|
|
60
|
+
}): boolean => { ... };
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Imports** — import as namespace:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import * as playlistSelectionEntity from "src/features/{feature}/domain/entities/PlaylistSelectionEntity";
|
|
67
|
+
playlistSelectionEntity.hasAddedPlaylists({ ... });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Services
|
|
73
|
+
|
|
74
|
+
Location: `src/features/{feature}/infrastructure/services/`
|
|
75
|
+
|
|
76
|
+
Services own all IO and side effects. Controllers call services — they never perform IO directly.
|
|
77
|
+
|
|
78
|
+
See `references/services.md` for the full Effect Layer pattern, service structure, and runtime composition.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Controllers
|
|
83
|
+
|
|
84
|
+
Location: `src/features/{feature}/application/controllers/`
|
|
85
|
+
|
|
86
|
+
Controllers own state and transitions. They delegate transforms and predicates to entities, and IO to services via the injected runtime.
|
|
87
|
+
|
|
88
|
+
See `references/state-management.md` for the full XState v5 pattern.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Containers
|
|
93
|
+
|
|
94
|
+
Location: `src/features/{feature}/application/containers/`
|
|
95
|
+
|
|
96
|
+
Containers are the composition layer. Three responsibilities:
|
|
97
|
+
|
|
98
|
+
1. **Map state** from the controller via `useSelector` and tags
|
|
99
|
+
2. **Forward events** to the controller — unconditionally
|
|
100
|
+
3. **Compose** hooks, translations, and presentation components
|
|
101
|
+
|
|
102
|
+
**Rules:**
|
|
103
|
+
- One container per controller
|
|
104
|
+
- No logic — no transforms, no business rules
|
|
105
|
+
- No conditionals around events — forward unconditionally, let the controller decide
|
|
106
|
+
- Targeted `useSelector` — select only what this container needs
|
|
107
|
+
- Never pass `send` or raw `snapshot` to presentation components — extract values and create specific callbacks
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// ❌ Bad — leaks machine internals into presentation
|
|
111
|
+
<Sidebar snapshot={snapshot} send={send} />
|
|
112
|
+
|
|
113
|
+
// ✅ Good — extract values, create specific callbacks
|
|
114
|
+
const { sidebarCollapsed, currentRoute } = snapshot.context;
|
|
115
|
+
const handleToggleSidebar = useCallback(() => send({ type: 'TOGGLE_SIDEBAR' }), [send]);
|
|
116
|
+
|
|
117
|
+
<Sidebar collapsed={sidebarCollapsed} onToggle={handleToggleSidebar} currentRoute={currentRoute} />
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Folder naming:** The container folder name must match the exported component name **exactly**, including any suffix (e.g. `Container`). Never shorten the folder name.
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
application/containers/
|
|
124
|
+
AuthGuardContainer/ ← exports AuthGuardContainer ✅
|
|
125
|
+
GlobalLoaderContainer/ ← exports GlobalLoaderContainer ✅
|
|
126
|
+
|
|
127
|
+
AuthGuard/ ← exports AuthGuardContainer ❌ (name mismatch)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This keeps the folder path and the import name in sync — reading either one tells you the other without opening the file.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// ✅ Forwards unconditionally
|
|
134
|
+
const onAction = useCallback(() => {
|
|
135
|
+
actor.send({ type: "playlist.action" });
|
|
136
|
+
}, [actor]);
|
|
137
|
+
|
|
138
|
+
// ❌ Container deciding — belongs in the controller
|
|
139
|
+
const onAction = useCallback(() => {
|
|
140
|
+
if (isEditing) actor.send({ type: "playlist.save" });
|
|
141
|
+
else actor.send({ type: "playlist.cancel" });
|
|
142
|
+
}, [actor, isEditing]);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### Presentation
|
|
148
|
+
|
|
149
|
+
Location: `src/features/{feature}/presentation/`
|
|
150
|
+
|
|
151
|
+
Presentation components are UI only. They receive props and render. No state machines, no services, no business logic.
|
|
152
|
+
|
|
153
|
+
See `references/presentation.md` for folder structure and composition rules.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## File Structure
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
src/
|
|
161
|
+
├── effects.ts # App runtime — composed once here
|
|
162
|
+
└── features/{feature}/
|
|
163
|
+
├── application/
|
|
164
|
+
│ ├── containers/ # Composition layer
|
|
165
|
+
│ └── controllers/ # State machines
|
|
166
|
+
├── domain/
|
|
167
|
+
│ └── entities/ # Pure functions
|
|
168
|
+
├── infrastructure/
|
|
169
|
+
│ └── services/ # Effect Layers — all IO
|
|
170
|
+
│ ├── PlaylistService.ts
|
|
171
|
+
│ ├── FolderService.ts
|
|
172
|
+
│ └── index.ts # Feature layer composition
|
|
173
|
+
├── presentation/ # UI components
|
|
174
|
+
└── types.ts # Public events (create only when needed)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Import paths** — use absolute paths from `src/`:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import * as playlistSelectionEntity from "src/features/{feature}/domain/entities/PlaylistSelectionEntity";
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Relative paths are acceptable within the same feature for deeply nested files.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Quick Check — Common Violations
|
|
188
|
+
|
|
189
|
+
**Logic in a container:**
|
|
190
|
+
```typescript
|
|
191
|
+
// ❌ Container deciding
|
|
192
|
+
if (isEditing) actor.send({ type: "playlist.save" });
|
|
193
|
+
|
|
194
|
+
// ✅ Controller decides — container forwards
|
|
195
|
+
actor.send({ type: "playlist.action", payload: { isEditing } });
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Side effect in an entity:**
|
|
199
|
+
```typescript
|
|
200
|
+
// ❌ Entity performing IO
|
|
201
|
+
export const fetchPlaylists = async (folderId: string) => {
|
|
202
|
+
return await api.get(`/folders/${folderId}/playlists`);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// ✅ Entity is a pure transform
|
|
206
|
+
export const toPlaylistItems = (raw: RawPlaylist[]): PlaylistItem[] =>
|
|
207
|
+
raw.map(r => ({ id: r.playlistId, label: r.playlistTitle ?? "Untitled" }));
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Layer skipping:**
|
|
211
|
+
```typescript
|
|
212
|
+
// ❌ Container importing an entity directly
|
|
213
|
+
import * as playlistEntity from "src/features/{feature}/domain/entities/PlaylistEntity";
|
|
214
|
+
|
|
215
|
+
// ✅ Container reads from controller state only
|
|
216
|
+
const playlists = useSelector(actor, s => s.context.playlists);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Passing machine internals to presentation:**
|
|
220
|
+
```typescript
|
|
221
|
+
// ❌ Presentation receives send/snapshot — leaks machine contract into UI layer
|
|
222
|
+
<Sidebar snapshot={snapshot} send={send} />
|
|
223
|
+
|
|
224
|
+
// ✅ Container extracts values and creates callbacks
|
|
225
|
+
const collapsed = snapshot.context.sidebarCollapsed;
|
|
226
|
+
const onToggle = useCallback(() => send({ type: 'TOGGLE_SIDEBAR' }), [send]);
|
|
227
|
+
<Sidebar collapsed={collapsed} onToggle={onToggle} />
|
|
228
|
+
```
|