aw-spec-cli 0.1.21 → 0.1.23
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/assets/.appweaver/STACK-PROFILES.md +87 -8
- package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +30 -0
- package/assets/.appweaver/orchestrator/orchestrator.py +47 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +41 -8
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +62 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +18 -5
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +4 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +115 -27
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +5 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +225 -27
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +4 -15
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +39 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-recall-delta.orch.yaml +28 -7
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +3 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +104 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +159 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +386 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-workflow-model.orch.yaml +153 -0
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +203 -212
- package/assets/.appweaver/scripts/bash/aw-xref.sh +4 -1
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +191 -224
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +4 -1
- package/assets/.appweaver/scripts/python/aw-crstate.py +127 -2
- package/assets/.appweaver/scripts/python/aw-gaps.py +119 -0
- package/assets/.appweaver/scripts/python/aw-payload-parity.py +17 -1
- package/assets/.appweaver/scripts/python/aw-plan-coverage.py +84 -4
- package/assets/.appweaver/scripts/python/aw-plangate.py +216 -0
- package/assets/.appweaver/scripts/python/aw-principles.py +108 -0
- package/assets/.appweaver/scripts/python/aw-stack.py +6 -0
- package/assets/.appweaver/scripts/python/aw-xref.py +141 -4
- package/assets/.appweaver/stack-profiles/angular.json +26 -0
- package/assets/.appweaver/stack-profiles/blazor-wasm.json +38 -0
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +38 -0
- package/assets/.appweaver/stack-profiles/java-spring.json +19 -0
- package/assets/.appweaver/stack-profiles/nextjs.json +26 -0
- package/assets/.appweaver/stack-profiles/node-express.json +26 -0
- package/assets/.appweaver/stack-profiles/python-fastapi.json +15 -0
- package/assets/.appweaver/stack-profiles/react-vite.json +26 -0
- package/assets/.appweaver/stack-profiles/sveltekit.json +26 -0
- package/assets/.appweaver/stack-profiles/vue-vite.json +26 -0
- package/assets/.appweaver/templates/ui-model-template.md +67 -0
- package/assets/.appweaver/templates/workflow-model-template.md +62 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +3 -3
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +5 -123
- package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +784 -0
- package/assets/foundations/java/Hexagonal/pack-foundation.sh +357 -0
- package/assets/foundations/java/Hexagonal/unpack-foundation.sh +399 -0
- package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +44 -0
- package/package.json +1 -1
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# aw-spec-ui-prototype (orchestrator) — Next.js UI prototype per domain
|
|
3
|
+
#
|
|
4
|
+
# Scaffolds a single shared Next.js prototype app per domain (prototypes/<domain>/),
|
|
5
|
+
# then on every subsequent run adds or regenerates just the active feature's screen/route inside it,
|
|
6
|
+
# driven by that feature's spec.md (+ any active delta-spec.md).
|
|
7
|
+
#
|
|
8
|
+
# Launch:
|
|
9
|
+
# /appweaver ui-prototype [strategy] [guidance]
|
|
10
|
+
# =============================================================================
|
|
11
|
+
|
|
12
|
+
name: aw-spec-ui-prototype
|
|
13
|
+
description: Generate or update a single screen/route inside a domain Next.js UI prototype, driven by the active feature's specification (referencing workflow-model.md and ui-model.md if available, or directly from spec.md).
|
|
14
|
+
version: 3.7.0
|
|
15
|
+
agent_agnostic: true
|
|
16
|
+
dialect: aw-spec.orchestrator/v1
|
|
17
|
+
|
|
18
|
+
inputs:
|
|
19
|
+
user_input:
|
|
20
|
+
description: Optional UI styling or behavior preferences (e.g. dark mode, Tailwind aesthetic, specific mock data).
|
|
21
|
+
required: false
|
|
22
|
+
bind: USER_INPUT
|
|
23
|
+
|
|
24
|
+
scripts:
|
|
25
|
+
actions:
|
|
26
|
+
sh: .appweaver/scripts/bash/aw-spec-actions.sh
|
|
27
|
+
ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
|
|
28
|
+
|
|
29
|
+
vars:
|
|
30
|
+
feature: ""
|
|
31
|
+
feature_dir: ""
|
|
32
|
+
feature_slug: ""
|
|
33
|
+
spec_file: ""
|
|
34
|
+
spec_exists: "false"
|
|
35
|
+
context: ""
|
|
36
|
+
context_dir: ""
|
|
37
|
+
domain_model: ""
|
|
38
|
+
domain_model_exists: "false"
|
|
39
|
+
active_change: ""
|
|
40
|
+
has_change: "false"
|
|
41
|
+
domain: ""
|
|
42
|
+
prototype_root: "prototype"
|
|
43
|
+
project_exists: "false"
|
|
44
|
+
|
|
45
|
+
workflow:
|
|
46
|
+
|
|
47
|
+
# 1. Resolve active feature and its spec directly from .appweaver/feature.json
|
|
48
|
+
# which points to the bounded context directory and then the feature (specs/<BoundedContext>/<Feature>/)
|
|
49
|
+
- id: feature_paths
|
|
50
|
+
action: execute_script
|
|
51
|
+
on_error: continue
|
|
52
|
+
script: { ref: actions }
|
|
53
|
+
subcommand: feature-paths
|
|
54
|
+
outputs:
|
|
55
|
+
- { name: feature, from: "$.feature" }
|
|
56
|
+
- { name: feature_slug, from: "$.feature_slug" } # kebab-case route segment
|
|
57
|
+
- { name: feature_dir, from: "$.feature_dir" }
|
|
58
|
+
- { name: spec_file, from: "$.spec_file" }
|
|
59
|
+
- { name: spec_exists, from: "$.spec_exists" }
|
|
60
|
+
|
|
61
|
+
- id: require_feature
|
|
62
|
+
action: verify_context
|
|
63
|
+
require_non_empty: feature_dir
|
|
64
|
+
on_empty: stop
|
|
65
|
+
on_empty_message: "No active feature. Run /appweaver select-feature first, then re-run ui-prototype."
|
|
66
|
+
|
|
67
|
+
- id: require_spec
|
|
68
|
+
action: verify_context
|
|
69
|
+
require_true: spec_exists
|
|
70
|
+
on_false: stop
|
|
71
|
+
on_false_message: "No specification found for this feature at {{spec_file}}. Run /appweaver specify first to create spec.md."
|
|
72
|
+
|
|
73
|
+
# 2. Resolve the bounded context containing this feature and its canonical domain model
|
|
74
|
+
- id: context_paths
|
|
75
|
+
action: execute_script
|
|
76
|
+
on_error: continue
|
|
77
|
+
script: { ref: actions }
|
|
78
|
+
subcommand: context-paths
|
|
79
|
+
args: ["--feature-dir", "{{feature_dir}}"]
|
|
80
|
+
outputs:
|
|
81
|
+
- { name: context, from: "$.context" }
|
|
82
|
+
- { name: context_dir, from: "$.context_dir" }
|
|
83
|
+
- { name: domain_model, from: "$.domain_model" }
|
|
84
|
+
- { name: domain_model_exists, from: "$.domain_model_exists" }
|
|
85
|
+
|
|
86
|
+
# 3. Resolve active domain
|
|
87
|
+
- id: resolve_domain
|
|
88
|
+
action: execute_script
|
|
89
|
+
on_error: continue
|
|
90
|
+
script: { ref: actions }
|
|
91
|
+
subcommand: resolve-domain
|
|
92
|
+
args: ["--command", "/aw-spec-ui-prototype"]
|
|
93
|
+
outputs:
|
|
94
|
+
- { name: domain, from: "$.domain" }
|
|
95
|
+
|
|
96
|
+
# 4. Resolve prototype root from stacks declaration (.appweaver/stacks.json)
|
|
97
|
+
- id: resolve_prototype_lane
|
|
98
|
+
action: execute_script
|
|
99
|
+
on_error: continue
|
|
100
|
+
script: { ref: actions }
|
|
101
|
+
subcommand: lane-resolve
|
|
102
|
+
outputs:
|
|
103
|
+
- { name: prototype_root, from: "$.prototype.root" }
|
|
104
|
+
|
|
105
|
+
# 5. Check for active change requests (feature-level)
|
|
106
|
+
- id: version_read
|
|
107
|
+
action: execute_script
|
|
108
|
+
on_error: continue
|
|
109
|
+
script: { ref: actions }
|
|
110
|
+
subcommand: version-read
|
|
111
|
+
args: ["--feature-dir", "{{feature_dir}}"]
|
|
112
|
+
outputs:
|
|
113
|
+
- { name: active_change, from: "$.active_change" }
|
|
114
|
+
- { name: has_change, from: "$.has_change" }
|
|
115
|
+
|
|
116
|
+
# 6. Check whether the domain prototype project already exists at prototype_root
|
|
117
|
+
- id: check_project
|
|
118
|
+
action: execute_script
|
|
119
|
+
on_error: continue
|
|
120
|
+
script: { ref: actions }
|
|
121
|
+
subcommand: path-exists
|
|
122
|
+
args: ["--path", "{{prototype_root}}/package.json"]
|
|
123
|
+
outputs:
|
|
124
|
+
- { name: project_exists, from: "$.exists" }
|
|
125
|
+
|
|
126
|
+
# 7. Assemble specification, bounded context domain model, optional UI artifacts, and rules context
|
|
127
|
+
- id: ctx_prototype
|
|
128
|
+
action: build_context
|
|
129
|
+
vars:
|
|
130
|
+
feature_name: "{{feature}}"
|
|
131
|
+
feature_slug: "{{feature_slug}}"
|
|
132
|
+
feature_dir: "{{feature_dir}}"
|
|
133
|
+
context_name: "{{context}}"
|
|
134
|
+
context_dir: "{{context_dir}}"
|
|
135
|
+
domain: "{{domain}}"
|
|
136
|
+
prototype_root: "{{prototype_root}}"
|
|
137
|
+
project_exists: "{{project_exists}}"
|
|
138
|
+
user_preferences: "{{USER_INPUT}}"
|
|
139
|
+
context:
|
|
140
|
+
- "{{spec_file}}"
|
|
141
|
+
- { path: "{{domain_model}}", optional: true }
|
|
142
|
+
- { path: "{{feature_dir}}/ui/workflow-model.md", optional: true }
|
|
143
|
+
- { path: "{{feature_dir}}/ui/ui-model.md", optional: true }
|
|
144
|
+
- { path: ".appweaver/memory/constitution.domain.md", optional: true }
|
|
145
|
+
- { path: ".appweaver/memory/constitution.ui.md", optional: true }
|
|
146
|
+
- { path: "{{feature_dir}}/changes/{{active_change}}/delta-spec.md", optional: true }
|
|
147
|
+
- { path: "{{prototype_root}}/screens.json", optional: true }
|
|
148
|
+
|
|
149
|
+
# 5a. First run only: scaffold the domain Next.js prototype shell if missing
|
|
150
|
+
- id: scaffold_project
|
|
151
|
+
action: agent_generate
|
|
152
|
+
condition: "{{project_exists}} == false"
|
|
153
|
+
tools: "Read,Write,Edit,Bash"
|
|
154
|
+
permission_mode: acceptEdits
|
|
155
|
+
task: |
|
|
156
|
+
There is no prototype project for domain `{{domain}}` yet. Scaffold ONE reusable Next.js application
|
|
157
|
+
shell for domain `{{domain}}` at `{{prototype_root}}/`. This project will be reused and extended by every
|
|
158
|
+
subsequent feature run for `{{domain}}` — do not build any single feature's screen content here.
|
|
159
|
+
|
|
160
|
+
Build only the shared shell:
|
|
161
|
+
1. `package.json`, Next.js App Router baseline (`app/layout.tsx`), global styles/design
|
|
162
|
+
tokens, and client-side state/provider pattern screens will share
|
|
163
|
+
(e.g. a lightweight context for active persona/role).
|
|
164
|
+
2. A shared nav/shell component (sidebar or top nav) that lists available screens by
|
|
165
|
+
reading dynamically from `lib/screens-registry.ts`. It renders each entry's
|
|
166
|
+
`title` field verbatim as the visible label — later screen runs are responsible for
|
|
167
|
+
putting a natural, product-appropriate name there (see the per-screen task), not
|
|
168
|
+
a raw spec title.
|
|
169
|
+
3. A shared persona/role-switcher component — its initial role and persona options
|
|
170
|
+
are populated directly from the actors/personas specified in `spec.md` (under `Actors` /
|
|
171
|
+
`Experience Scope` / `User Stories`) and `ui-model.md`, and registered in `lib/screens-registry.ts`.
|
|
172
|
+
4. `lib/screens-registry.ts` — an empty typed registry (array of
|
|
173
|
+
`{ slug, title, route, specVersion, roles }`) plus a `screens.json` mirror for
|
|
174
|
+
non-JS tooling. This file is APPENDED TO by screen runs.
|
|
175
|
+
5. A clean, production-feeling home page (`app/page.tsx`) for the domain application —
|
|
176
|
+
shared nav and an overview relevant to the domain — using the domain's real product
|
|
177
|
+
name (derive one from `{{domain}}`/spec/constitution, e.g. "Acme" not "Acme Prototype").
|
|
178
|
+
This home page is the app's actual dashboard/landing experience — the entry point a
|
|
179
|
+
real user of this product would land on — not a menu of "screens" or a list mirroring
|
|
180
|
+
spec structure.
|
|
181
|
+
|
|
182
|
+
Do not create the route for `{{feature_name}}` yet — that happens in the next step.
|
|
183
|
+
Ensure `npm install && npm run dev` works with just this shell.
|
|
184
|
+
|
|
185
|
+
**This must read as one coherent real application, never as a list of specs:**
|
|
186
|
+
- Never render the words "prototype", "mock", "demo", "scaffold", "shell", "sample",
|
|
187
|
+
or similar anywhere a user can see them — not in the page title, `<title>`/metadata,
|
|
188
|
+
headers, nav labels, empty states, placeholder copy, button text, or console-visible
|
|
189
|
+
UI. Those words are fine in code comments, filenames, or `PROTOTYPE_NOTES.md`, but
|
|
190
|
+
never in rendered UI.
|
|
191
|
+
- Never render raw spec/traceability identifiers anywhere in the UI — no `REQ-###`,
|
|
192
|
+
`SPEC-SCREEN-###`, `SPEC-COMP-###`, `MOCKDATA-###`, `FEEDBACK-###`, `CHANGE-###`, or
|
|
193
|
+
literal spec section titles/filenames. Those are internal authoring artifacts, not
|
|
194
|
+
product language a real user would ever see.
|
|
195
|
+
- The home page, nav, and browser tab title should use the actual product/domain name
|
|
196
|
+
as if this were the shipping application, not a label describing what this project is.
|
|
197
|
+
- The persona/role switcher must be styled and framed as a normal in-app affordance
|
|
198
|
+
(e.g. an account/role menu a real user of this kind of app would plausibly have),
|
|
199
|
+
not as an obvious dev/testing control bolted onto the UI.
|
|
200
|
+
|
|
201
|
+
**Styling must actually render — this is not optional:**
|
|
202
|
+
- Install and fully configure **Tailwind CSS** (latest stable version, matching whatever
|
|
203
|
+
the installed Next.js version's official setup docs specify — App Router's Tailwind
|
|
204
|
+
setup has changed across versions, e.g. `tailwind.config.ts`/PostCSS config differs
|
|
205
|
+
between Tailwind v3 and v4). Do not stop at `npm install tailwindcss` — verify the
|
|
206
|
+
PostCSS config, content globs, and `@tailwind base/components/utilities` (or v4's
|
|
207
|
+
`@import "tailwindcss"`) directives are all present and correct for the version installed.
|
|
208
|
+
- Create `app/globals.css` with the Tailwind directives plus any design-token CSS
|
|
209
|
+
variables (colors, spacing, radii, fonts), and **explicitly `import "./globals.css"`
|
|
210
|
+
at the top of `app/layout.tsx`.** A missing import here is the most common cause of
|
|
211
|
+
a fully unstyled app — verify it's present before finishing.
|
|
212
|
+
- After scaffolding, actually run `npm run dev` (or `next build`) and confirm no
|
|
213
|
+
Tailwind/PostCSS errors appear in the output before ending this step. Don't just
|
|
214
|
+
assume the config is correct because the files exist.
|
|
215
|
+
- If `constitution.ui.md` or USER_INPUT specifies a different styling approach
|
|
216
|
+
(CSS Modules, a specific component library with its own styling, styled-components,
|
|
217
|
+
etc.), follow that instead of Tailwind — but whichever system is chosen, the same
|
|
218
|
+
rule applies: install it fully, wire it into the root layout, and verify it actually
|
|
219
|
+
renders styled output, not just that the packages are present in `package.json`.
|
|
220
|
+
|
|
221
|
+
**Always use the latest versions and current best practices:**
|
|
222
|
+
- Scaffold against the latest stable Next.js (App Router) and React releases available
|
|
223
|
+
at the time of this run — do not pin to or reproduce an older remembered baseline.
|
|
224
|
+
Resolve versions with `npm view <package> version` (or `npm install <package>@latest`)
|
|
225
|
+
rather than assuming a version from memory.
|
|
226
|
+
- Use current, non-deprecated APIs and patterns for whatever is scaffolded (routing,
|
|
227
|
+
data fetching, styling setup). If a pattern you'd default to has since been superseded
|
|
228
|
+
(e.g. an older config format, a deprecated hook/API), use the current replacement.
|
|
229
|
+
- If a UI/component library or design-token approach is implied by
|
|
230
|
+
`constitution.ui.md`, USER_INPUT, or the spec, install its latest published version
|
|
231
|
+
and use its current component APIs — check the library's current docs/changelog
|
|
232
|
+
rather than relying on a possibly-stale remembered API surface.
|
|
233
|
+
- Note the resolved major versions of Next.js/React and any UI library in a short
|
|
234
|
+
comment at the top of `package.json` or in a `PROTOTYPE_NOTES.md`, so later screen
|
|
235
|
+
runs and reviewers know what "latest" resolved to at scaffold time.
|
|
236
|
+
|
|
237
|
+
# 5b. Every run: generate/update this feature's screen inside the existing domain prototype
|
|
238
|
+
- id: generate_screen
|
|
239
|
+
action: agent_generate
|
|
240
|
+
tools: "Read,Write,Edit,Bash"
|
|
241
|
+
permission_mode: acceptEdits
|
|
242
|
+
task: |
|
|
243
|
+
You are adding or regenerating ONE screen inside the existing Next.js prototype for domain `{{domain}}`
|
|
244
|
+
at `{{prototype_root}}/`. Do NOT touch project scaffolding, `package.json`, shared layout,
|
|
245
|
+
or other features' routes/components except where explicitly instructed below.
|
|
246
|
+
|
|
247
|
+
The feature specification is taken directly from the bounded context directory and feature path defined in `.appweaver/feature.json`:
|
|
248
|
+
`{{spec_file}}` (Bounded Context: `{{context_name}}`, Feature: `{{feature_name}}`).
|
|
249
|
+
Read this specification strictly from `{{spec_file}}`, along with the bounded context's canonical domain model (`{{domain_model}}`),
|
|
250
|
+
and when available, the Workflow Model (`{{feature_dir}}/ui/workflow-model.md`) and UI Model (`{{feature_dir}}/ui/ui-model.md`), plus `{{prototype_root}}/lib/screens-registry.ts` / `screens.json`.
|
|
251
|
+
If `workflow-model.md` and `ui-model.md` are not provided, derive all UI surfaces, workflows, and interaction states directly from `{{spec_file}}`.
|
|
252
|
+
|
|
253
|
+
**SPEC-DRIVEN PROTOTYPE GENERATION (STAGE 4 EXECUTION)**:
|
|
254
|
+
Your goal is to build the executable Next.js application surfaces defined in the spec and UI/workflow models (when available):
|
|
255
|
+
- Implement ALL UI surfaces (Primary Page `/{{feature_slug}}`, sub-routes, modal dialogs, drawers, forms, data grids/cards).
|
|
256
|
+
- Realize all user workflows (`WF-1`, `WF-2`, `WF-3`...) with realistic interactive behavior, persona role-switching, and surface navigation transitions.
|
|
257
|
+
- Handle all specified UI states (`Loading`, `Empty`, `Populated`, `Filtered / Searched`, `Validation Error`, `Submitting`, `Success`, `Error`).
|
|
258
|
+
|
|
259
|
+
1. **Multi-Surface & Route Implementation**:
|
|
260
|
+
- Create or fully regenerate `{{prototype_root}}/app/{{feature_slug}}/page.tsx`
|
|
261
|
+
(and any screen-scoped components under
|
|
262
|
+
`{{prototype_root}}/app/{{feature_slug}}/components/`).
|
|
263
|
+
- Treat this route as regenerated wholesale each run — don't hand-patch it.
|
|
264
|
+
- Build the full, finished screen the spec describes — not a wireframe, stub,
|
|
265
|
+
"coming soon," or reduced placeholder version. A user landing on this route should
|
|
266
|
+
see the actual working application screen, fully styled and populated, matching
|
|
267
|
+
spec.md as if it shipped this way.
|
|
268
|
+
- Never surface "prototype/mock/demo/sample" language, or raw spec/traceability IDs
|
|
269
|
+
(`REQ-###`, `SPEC-SCREEN-###`, etc.) anywhere in this screen's rendered UI (titles,
|
|
270
|
+
headers, empty states, tooltips, button copy). Keep all such labeling out of
|
|
271
|
+
user-visible text entirely.
|
|
272
|
+
|
|
273
|
+
2. **Integrate this screen into the app like a real feature, not a spec entry**:
|
|
274
|
+
- `{{feature_name}}` and any spec title/ID are internal identifiers for you to read —
|
|
275
|
+
never repeat them verbatim as the nav label, page heading, or route's display name.
|
|
276
|
+
Derive a natural, user-facing name the way a real product would phrase it (e.g. a
|
|
277
|
+
spec called "Project Creation Screen" surfaces as a "Projects" nav entry whose
|
|
278
|
+
content includes creating a project — not a nav item literally labeled
|
|
279
|
+
"Project Creation Screen").
|
|
280
|
+
- Decide where this screen naturally belongs in the app's information architecture
|
|
281
|
+
based on what the spec describes, the same way a product designer would: a
|
|
282
|
+
top-level nav item, a sub-page reached by an action on another already-generated
|
|
283
|
+
screen (e.g. a "New Project" button on the dashboard or on a "Projects" list),
|
|
284
|
+
or an entry point added to the shared dashboard — whichever fits how a real user
|
|
285
|
+
would discover and reach this functionality. Don't default to "flat nav item per
|
|
286
|
+
spec" if the spec's own content implies a more natural entry point (e.g. reached
|
|
287
|
+
via a button/action from another screen rather than the top-level nav).
|
|
288
|
+
- If the natural entry point is from another already-generated screen or the
|
|
289
|
+
dashboard, update that screen/dashboard minimally to add the real link/button/card
|
|
290
|
+
that leads here — don't leave this screen orphaned and reachable only by URL.
|
|
291
|
+
|
|
292
|
+
3. **Specification-driven behavior**:
|
|
293
|
+
- Derive all behavior exclusively from the active specification for this feature.
|
|
294
|
+
- Implement all functional requirements, business rules, invariants, validations,
|
|
295
|
+
constraints, state transitions, and workflows explicitly defined in spec.md.
|
|
296
|
+
- Do not invent business rules absent from the spec. Use reasonable UI defaults only
|
|
297
|
+
for presentation/interaction mechanics.
|
|
298
|
+
|
|
299
|
+
4. **Roles, personas, and permission rules from spec**:
|
|
300
|
+
- Derive all roles/personas directly from `spec.md` (under `Actors` / `Experience Scope` / `User Stories`) and `ui-model.md`.
|
|
301
|
+
- Ensure every role defined in the specification exists in the SHARED persona/role-switcher context.
|
|
302
|
+
- Wire the UI controls dynamically so switching persona demonstrates role-based visibility, disabled inputs, and permission workflows (e.g. PM vs PMO vs Delivery Head) strictly as specified.
|
|
303
|
+
|
|
304
|
+
5. **Mock data**:
|
|
305
|
+
- Place this feature's mock data under
|
|
306
|
+
`{{prototype_root}}/lib/mock-data/{{feature_slug}}.ts`, isolated from other screens.
|
|
307
|
+
- Data values should read as realistic, plausible content for this domain (real-sounding
|
|
308
|
+
names, dates, amounts, statuses) — not "Lorem ipsum," "Test User 1," "Sample Item,"
|
|
309
|
+
or other obviously-fake placeholder text. The screen should look fully populated and
|
|
310
|
+
real, even though the data behind it is static.
|
|
311
|
+
|
|
312
|
+
6. **Reuse, don't duplicate**:
|
|
313
|
+
- Reuse existing shared components (nav shell, buttons, layout primitives, design
|
|
314
|
+
tokens) from the shell in the project.
|
|
315
|
+
|
|
316
|
+
7. **Styling must render on this screen too**:
|
|
317
|
+
- Before writing this screen, confirm the shell's styling setup is actually wired
|
|
318
|
+
up — `app/globals.css` exists and is imported in `app/layout.tsx`, and the
|
|
319
|
+
Tailwind/CSS config from the shell is intact. If it's missing or broken, fix it
|
|
320
|
+
as part of this run and note that in your final summary; don't build a styled-looking
|
|
321
|
+
screen on top of a broken/absent styling pipeline.
|
|
322
|
+
- Use the shell's existing design tokens and Tailwind utility classes (or whatever
|
|
323
|
+
styling system the shell uses) rather than inline style objects or
|
|
324
|
+
ad-hoc CSS that bypasses the shared system — inline styles that "look fine" in
|
|
325
|
+
isolation are usually the sign the shared pipeline isn't actually being used.
|
|
326
|
+
- If this screen needs a component from a UI library not yet installed in the shell
|
|
327
|
+
(e.g. a data table, date picker), install it into the shell's `package.json` (latest
|
|
328
|
+
version, per below) and ensure its required CSS/theme setup is added to
|
|
329
|
+
`app/globals.css` or its own import — a component library added without its styles
|
|
330
|
+
wired in is another common source of unstyled output.
|
|
331
|
+
|
|
332
|
+
8. **Always use the latest UI, components, and libraries**:
|
|
333
|
+
- Any new dependency added for this screen (UI library, icon set, chart/table/form
|
|
334
|
+
component, date picker, etc.) must be the latest stable published version —
|
|
335
|
+
resolve it with `npm view <package> version` or install via `@latest` rather than
|
|
336
|
+
writing a version from memory.
|
|
337
|
+
- When reusing shared components from the shell, check whether the shell's installed
|
|
338
|
+
versions are current; if `{{prototype_root}}/PROTOTYPE_NOTES.md` or `package.json`
|
|
339
|
+
indicates they're stale relative to what's now available, flag it in your final
|
|
340
|
+
summary rather than silently building on outdated components — don't upgrade
|
|
341
|
+
shared/shell dependencies yourself from a screen run.
|
|
342
|
+
- Prefer each library's current, non-deprecated component API and patterns
|
|
343
|
+
(e.g. current shadcn/ui component structure, current Next.js Image/Link/Font APIs)
|
|
344
|
+
over older remembered forms of the same API.
|
|
345
|
+
- Do not introduce a second library that duplicates something the shell or an
|
|
346
|
+
earlier screen already standardized on — "latest" applies to versions, not to
|
|
347
|
+
swapping in a different library each run.
|
|
348
|
+
|
|
349
|
+
9. **Registry update**:
|
|
350
|
+
- Add or update this feature's entry in `lib/screens-registry.ts` and `screens.json`:
|
|
351
|
+
`{ slug: "{{feature_slug}}", title: "<natural product-facing name from step 2, NOT
|
|
352
|
+
the raw spec title>", route: "/{{feature_slug}}", specVersion: <from spec.md if
|
|
353
|
+
present>, roles: [...] }`.
|
|
354
|
+
- `title` here drives the visible nav label — it must be the naturalized name from
|
|
355
|
+
step 2, never `{{feature_name}}` or a spec ID verbatim. If you need to retain the
|
|
356
|
+
original spec title/ID for traceability, add it as a separate non-rendered field
|
|
357
|
+
(e.g. `specRef`) rather than reusing `title` for it.
|
|
358
|
+
|
|
359
|
+
User Preferences / Guidance:
|
|
360
|
+
{{user_preferences}}
|
|
361
|
+
|
|
362
|
+
End your final reply with a summary of what was added/changed and a ```json code block:
|
|
363
|
+
```json
|
|
364
|
+
{
|
|
365
|
+
"status": "ok",
|
|
366
|
+
"domain": "{{domain}}",
|
|
367
|
+
"feature": "{{feature_name}}",
|
|
368
|
+
"slug": "{{feature_slug}}",
|
|
369
|
+
"route": "/{{feature_slug}}",
|
|
370
|
+
"prototype_root": "{{prototype_root}}",
|
|
371
|
+
"launch_command": "cd {{prototype_root}} && npm run dev"
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
outputs:
|
|
375
|
+
- { name: result, from: "$" }
|
|
376
|
+
|
|
377
|
+
outputs:
|
|
378
|
+
domain: "{{domain}}"
|
|
379
|
+
context: "{{context}}"
|
|
380
|
+
context_dir: "{{context_dir}}"
|
|
381
|
+
feature: "{{feature}}"
|
|
382
|
+
spec_file: "{{spec_file}}"
|
|
383
|
+
route: "/{{feature_slug}}"
|
|
384
|
+
prototype_root: "{{prototype_root}}"
|
|
385
|
+
launch_hint: "First time: cd {{prototype_root}} && npm install && npm run dev — after that, just rerun ui-prototype per feature and refresh the browser."
|
|
386
|
+
next: "Visit http://localhost:3000/{{feature_slug}} to review this screen, or / for the full screen list."
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# aw-spec-workflow-model (orchestrator) — Derive Workflow Model from Feature Spec
|
|
3
|
+
#
|
|
4
|
+
# Stage 2 of the 4-Stage Spec-Driven UI Generation Pipeline.
|
|
5
|
+
# Consumes active feature's spec.md (+ active delta-spec.md) and derives user-oriented
|
|
6
|
+
# workflows (Actors, Goals, Primary Steps, Decisions, Alt Paths, Validation Failures, State Transitions).
|
|
7
|
+
# Writes output artifact to `specs/<Feature>/ui/workflow-model.md`.
|
|
8
|
+
#
|
|
9
|
+
# Launch:
|
|
10
|
+
# /appweaver workflow-model [strategy] [guidance]
|
|
11
|
+
# =============================================================================
|
|
12
|
+
|
|
13
|
+
name: aw-spec-workflow-model
|
|
14
|
+
description: Derive the Workflow Model (specs/<Feature>/ui/workflow-model.md) from the active feature's spec.md, describing user goals, interaction steps, decision branches, validation rules, and state transitions.
|
|
15
|
+
version: 1.0.0
|
|
16
|
+
agent_agnostic: true
|
|
17
|
+
dialect: aw-spec.orchestrator/v1
|
|
18
|
+
|
|
19
|
+
inputs:
|
|
20
|
+
user_input:
|
|
21
|
+
description: Optional guidance or specific workflow emphasis.
|
|
22
|
+
required: false
|
|
23
|
+
bind: USER_INPUT
|
|
24
|
+
|
|
25
|
+
scripts:
|
|
26
|
+
actions:
|
|
27
|
+
sh: .appweaver/scripts/bash/aw-spec-actions.sh
|
|
28
|
+
ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
|
|
29
|
+
|
|
30
|
+
vars:
|
|
31
|
+
feature: ""
|
|
32
|
+
feature_dir: ""
|
|
33
|
+
feature_slug: ""
|
|
34
|
+
spec_file: ""
|
|
35
|
+
spec_exists: "false"
|
|
36
|
+
active_change: ""
|
|
37
|
+
has_change: "false"
|
|
38
|
+
domain: ""
|
|
39
|
+
prototype_root: ""
|
|
40
|
+
|
|
41
|
+
workflow:
|
|
42
|
+
|
|
43
|
+
# 1. Resolve active feature and paths
|
|
44
|
+
- id: feature_paths
|
|
45
|
+
action: execute_script
|
|
46
|
+
on_error: continue
|
|
47
|
+
script: { ref: actions }
|
|
48
|
+
subcommand: feature-paths
|
|
49
|
+
outputs:
|
|
50
|
+
- { name: feature, from: "$.feature" }
|
|
51
|
+
- { name: feature_dir, from: "$.feature_dir" }
|
|
52
|
+
- { name: feature_slug, from: "$.feature_slug" } # kebab-case route segment
|
|
53
|
+
- { name: spec_file, from: "$.spec_file" }
|
|
54
|
+
- { name: spec_exists, from: "$.spec_exists" }
|
|
55
|
+
|
|
56
|
+
# domain and prototype_root have their OWN resolvers — feature-paths answers for the
|
|
57
|
+
# feature's documents and nothing else, so binding them here left both empty and the
|
|
58
|
+
# emptiness reached the prompts as a blank path segment rather than an error.
|
|
59
|
+
- id: resolve_domain
|
|
60
|
+
action: execute_script
|
|
61
|
+
on_error: continue
|
|
62
|
+
script: { ref: actions }
|
|
63
|
+
subcommand: resolve-domain
|
|
64
|
+
args: ["--command", "/aw-spec-workflow-model"]
|
|
65
|
+
outputs:
|
|
66
|
+
- { name: domain, from: "$.domain" }
|
|
67
|
+
|
|
68
|
+
- id: resolve_prototype_lane
|
|
69
|
+
action: execute_script
|
|
70
|
+
on_error: continue
|
|
71
|
+
script: { ref: actions }
|
|
72
|
+
subcommand: lane-resolve
|
|
73
|
+
outputs:
|
|
74
|
+
- { name: prototype_root, from: "$.prototype.root" }
|
|
75
|
+
|
|
76
|
+
- id: require_feature
|
|
77
|
+
action: verify_context
|
|
78
|
+
require_non_empty: feature_dir
|
|
79
|
+
on_empty: stop
|
|
80
|
+
on_empty_message: "No active feature selected. Run /appweaver select-feature first."
|
|
81
|
+
|
|
82
|
+
- id: require_spec
|
|
83
|
+
action: verify_context
|
|
84
|
+
require_true: spec_exists
|
|
85
|
+
on_false: stop
|
|
86
|
+
on_false_message: "No specification found for this feature. Run /appweaver specify first."
|
|
87
|
+
|
|
88
|
+
# 2. Check active change requests
|
|
89
|
+
- id: version_read
|
|
90
|
+
action: execute_script
|
|
91
|
+
on_error: continue
|
|
92
|
+
script: { ref: actions }
|
|
93
|
+
subcommand: version-read
|
|
94
|
+
args: ["--feature-dir", "{{feature_dir}}"]
|
|
95
|
+
outputs:
|
|
96
|
+
- { name: active_change, from: "$.active_change" }
|
|
97
|
+
- { name: has_change, from: "$.has_change" }
|
|
98
|
+
|
|
99
|
+
# 3. Assemble specification & template context
|
|
100
|
+
- id: ctx_workflow
|
|
101
|
+
action: build_context
|
|
102
|
+
vars:
|
|
103
|
+
feature_name: "{{feature}}"
|
|
104
|
+
feature_dir: "{{feature_dir}}"
|
|
105
|
+
user_preferences: "{{USER_INPUT}}"
|
|
106
|
+
context:
|
|
107
|
+
- "{{spec_file}}"
|
|
108
|
+
- { path: "{{feature_dir}}/changes/{{active_change}}/delta-spec.md", optional: true }
|
|
109
|
+
- { path: ".appweaver/templates/workflow-model-template.md", optional: true }
|
|
110
|
+
- { path: ".appweaver/memory/constitution.ui.md", optional: true }
|
|
111
|
+
|
|
112
|
+
# 4. Generate Workflow Model Artifact (specs/<Feature>/ui/workflow-model.md)
|
|
113
|
+
- id: generate_workflow_model
|
|
114
|
+
action: agent_generate
|
|
115
|
+
tools: "Read,Write,Edit,Bash"
|
|
116
|
+
permission_mode: acceptEdits
|
|
117
|
+
task: |
|
|
118
|
+
You are authoring Stage 2 (Workflow Model) of the 4-Stage Spec-Driven UI Pipeline for feature `{{feature_name}}`.
|
|
119
|
+
|
|
120
|
+
Target Artifact Path: `{{feature_dir}}/ui/workflow-model.md`
|
|
121
|
+
|
|
122
|
+
Instructions:
|
|
123
|
+
1. Read the feature specification (`spec.md` + active `delta-spec.md`) in context.
|
|
124
|
+
2. Identify ALL discrete user workflows required to fulfill the feature's capabilities, functional requirements (FRs), business rules (BRs), and user personas.
|
|
125
|
+
3. For EACH user workflow (WF-1, WF-2, ...), detail:
|
|
126
|
+
- **Actor / Persona**: Which role executes this flow (e.g. Project Manager, Delivery Head).
|
|
127
|
+
- **Goal**: Clear statement of user goal.
|
|
128
|
+
- **Preconditions**: Initial system state, permissions, or prerequisite conditions.
|
|
129
|
+
- **Primary Flow**: Step-by-step numbered interaction steps from start to completion.
|
|
130
|
+
- **Decision Points & Alternative Paths**: Clear branch logic (e.g. If user cancels, If user requests correction).
|
|
131
|
+
- **Validation Failures & Error Handling**: Inline system reaction when business rules or validations fail.
|
|
132
|
+
- **State Transitions**: `[Initial State]` → `[Resulting State]`.
|
|
133
|
+
4. Format the output according to `.appweaver/templates/workflow-model-template.md`.
|
|
134
|
+
5. Create the directory `{{feature_dir}}/ui/` if it does not exist, and write the authored markdown content to `{{feature_dir}}/ui/workflow-model.md`.
|
|
135
|
+
|
|
136
|
+
User Guidance:
|
|
137
|
+
{{user_preferences}}
|
|
138
|
+
|
|
139
|
+
End your final reply with a summary and a ```json fence:
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"status": "ok",
|
|
143
|
+
"feature": "{{feature_name}}",
|
|
144
|
+
"workflow_model_path": "{{feature_dir}}/ui/workflow-model.md"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
outputs:
|
|
148
|
+
- { name: result, from: "$" }
|
|
149
|
+
|
|
150
|
+
outputs:
|
|
151
|
+
feature: "{{feature}}"
|
|
152
|
+
workflow_model_path: "{{feature_dir}}/ui/workflow-model.md"
|
|
153
|
+
next: "Run /appweaver ui-model to derive the UI Model surfaces and interaction structure."
|