aw-spec-cli 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/assets/.appweaver/STACK-PROFILES.md +87 -8
  2. package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +30 -0
  3. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +41 -8
  4. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +62 -2
  5. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +18 -5
  6. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +115 -27
  7. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +225 -27
  8. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +39 -0
  9. package/assets/.appweaver/orchestrator/workflows/aw-spec-recall-delta.orch.yaml +28 -7
  10. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +100 -0
  11. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +141 -0
  12. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +386 -0
  13. package/assets/.appweaver/orchestrator/workflows/aw-spec-workflow-model.orch.yaml +135 -0
  14. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +190 -209
  15. package/assets/.appweaver/scripts/bash/aw-xref.sh +4 -1
  16. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +182 -224
  17. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +4 -1
  18. package/assets/.appweaver/scripts/python/aw-crstate.py +127 -2
  19. package/assets/.appweaver/scripts/python/aw-gaps.py +119 -0
  20. package/assets/.appweaver/scripts/python/aw-payload-parity.py +17 -1
  21. package/assets/.appweaver/scripts/python/aw-plan-coverage.py +84 -4
  22. package/assets/.appweaver/scripts/python/aw-plangate.py +216 -0
  23. package/assets/.appweaver/scripts/python/aw-principles.py +108 -0
  24. package/assets/.appweaver/scripts/python/aw-stack.py +6 -0
  25. package/assets/.appweaver/scripts/python/aw-xref.py +141 -4
  26. package/assets/.appweaver/stack-profiles/angular.json +26 -0
  27. package/assets/.appweaver/stack-profiles/blazor-wasm.json +38 -0
  28. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +38 -0
  29. package/assets/.appweaver/stack-profiles/java-spring.json +19 -0
  30. package/assets/.appweaver/stack-profiles/nextjs.json +26 -0
  31. package/assets/.appweaver/stack-profiles/node-express.json +26 -0
  32. package/assets/.appweaver/stack-profiles/python-fastapi.json +15 -0
  33. package/assets/.appweaver/stack-profiles/react-vite.json +26 -0
  34. package/assets/.appweaver/stack-profiles/sveltekit.json +26 -0
  35. package/assets/.appweaver/stack-profiles/vue-vite.json +26 -0
  36. package/assets/.appweaver/templates/ui-model-template.md +67 -0
  37. package/assets/.appweaver/templates/workflow-model-template.md +62 -0
  38. package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +44 -0
  39. package/package.json +1 -1
@@ -107,6 +107,14 @@ standards:
107
107
 
108
108
  vars:
109
109
  spec_all_pass: "false" # validation-loop guard, flipped by the validate query
110
+ nn_count: "0" # ratified NON-NEGOTIABLE principles, from principles-list.
111
+ # 0 = a project that ratified none, which skips the gate.
112
+ nn_titles: "" # those principles, for the judge's prompt
113
+ nn_compliant: "false" # per-clarification verdict. DEFAULTS TO REFUSE: the gate
114
+ # reads it, so a judge that never answered stops the run
115
+ # rather than passing an unexamined answer through.
116
+ nn_principle: "" # the principle a departing answer was judged against
117
+ nn_why: "" # what it requires and what the answer does instead
110
118
  checklist_total: "0" # bound by checklist-read
111
119
  checklist_passed: "0" # stays 0 when the checklist has no items to score
112
120
  cr_id: "" # set on the DELTA path only
@@ -520,6 +528,23 @@ workflow:
520
528
 
521
529
  # 6. Resolve [NEEDS CLARIFICATION] markers interactively (≤3). Non-interactive
522
530
  # runs answer with the first/recommended option (a documented default).
531
+ #
532
+ # THE DEFAULT IS WHY THIS IS GOVERNED. A non-interactive run answers with options[0],
533
+ # so whatever the extraction listed first becomes project policy unattended — and a
534
+ # clarification is asked at exactly the altitude where a ratified principle already
535
+ # has an answer. The constitution halves ARE in context here (build_context put them
536
+ # in the envelope, which include_standards: false does not touch), but nothing told
537
+ # the extraction that a principle outranks a question, and nothing checked the answer
538
+ # afterwards. Both halves of that are below: the ordering rule in the task, and the
539
+ # per-answer gate inside the loop.
540
+ - id: nn_principles
541
+ action: execute_script
542
+ script: { ref: actions }
543
+ subcommand: principles-list
544
+ outputs:
545
+ - { name: nn_count, from: "$.count" }
546
+ - { name: nn_titles, from: "$.titles_csv" }
547
+
523
548
  - id: extract_clarifications
524
549
  action: agent_query
525
550
  context: ["{{quality_target}}"]
@@ -528,6 +553,15 @@ workflow:
528
553
  Extract up to 3 unresolved "[NEEDS CLARIFICATION: <question>]" markers from
529
554
  the document in context (a feature spec, or one change's delta-spec), most
530
555
  scope/security/UX-impacting first. Return {"clarifications":[]} if there are none.
556
+
557
+ A RATIFIED PRINCIPLE IS NOT A QUESTION. The constitution halves in context carry
558
+ principles marked (NON-NEGOTIABLE). Where one of them already settles a marker,
559
+ it is not a clarification: DROP it from the list — the answer is the principle,
560
+ and the document is corrected to match it in the quality loop. Offering it as a
561
+ choice invites a project to vote on something already ratified.
562
+ For a marker that merely TOUCHES such a principle, every option you list must be
563
+ compatible with it, and the most compliant option must be FIRST — an unattended
564
+ run takes the first one.
531
565
  schema: { clarifications: [ { id: c1, question: "<the question>", options: ["<answer A>", "<answer B>", "<answer C>"] } ] }
532
566
  mock: { clarifications: [] }
533
567
  outputs:
@@ -545,6 +579,72 @@ workflow:
545
579
  options_from: "{{c.options}}"
546
580
  answer_key: "{{c.id}}"
547
581
  answer_var: c_answer
582
+
583
+ # THE ANSWER IS CHECKED BEFORE IT IS WRITTEN IN. Placed between the ask and the
584
+ # rewrite on purpose: once resolve_clar has folded the answer into a requirement it
585
+ # is ordinary spec prose, and catching it then means unpicking a document rather
586
+ # than declining an answer. Judged one answer at a time so the stop can quote the
587
+ # question that caused it.
588
+ #
589
+ # The agent judges ONLY against the principles nn_principles found — a citation
590
+ # outside that list is visibly wrong, which is the point of enumerating them with a
591
+ # script instead of asking one agent to both find the principle and object to it.
592
+ #
593
+ # ASKED IN THE POSITIVE, AND RESET FIRST. The gate below reads nn_compliant, so an
594
+ # answer the judge never delivered — a malformed reply, a step that did not run —
595
+ # leaves "false" standing and STOPS. Asking "does it contradict?" would invert that:
596
+ # the same silence would read as no contradiction found. The reset is what makes it
597
+ # per-iteration; vars outlive a loop pass, so without it the second clarification
598
+ # would inherit the first one's verdict.
599
+ - id: governance_reset
600
+ action: set
601
+ vars:
602
+ nn_compliant: "false"
603
+ nn_principle: ""
604
+ nn_why: ""
605
+
606
+ # Skipped where a project ratified no NON-NEGOTIABLE principle: with nothing to
607
+ # depart from there is nothing to ask, and the gate is skipped on the same
608
+ # condition rather than reading the "false" this reset just wrote.
609
+ - id: governance_check
610
+ condition: "{{nn_count}} != 0"
611
+ action: agent_query
612
+ context: ["{{quality_target}}"]
613
+ include_standards: false
614
+ task: |
615
+ The constitution halves in context ratify these NON-NEGOTIABLE principles:
616
+ {{nn_titles}}
617
+ A question was raised about this specification and has just been answered:
618
+ Question: {{c.question}}
619
+ Answer: {{c_answer}}
620
+ Is that answer COMPLIANT with those principles — that is, can the specification
621
+ be amended to say it without asserting something a principle forbids or omitting
622
+ something a principle requires?
623
+ Judge only against the principles listed above, and when it is not compliant
624
+ cite the one it departs from by its id. A principle the question does not engage
625
+ is not a departure, and neither is an answer a principle simply does not speak
626
+ to; where none is engaged the answer is compliant. Report a departure only where
627
+ you can state what the principle requires and what the answer does instead.
628
+ schema: { compliant: true, principle: "<id, or empty>", why: "<one sentence, or empty>" }
629
+ mock: { compliant: true, principle: "", why: "" }
630
+ outputs:
631
+ - { name: nn_compliant, from: "$.compliant" }
632
+ - { name: nn_principle, from: "$.principle" }
633
+ - { name: nn_why, from: "$.why" }
634
+
635
+ # FAIL CLOSED. The constitution's own Governance says a deviation with no named
636
+ # approver is a defect, not a decision — and this answer has no approver at all: it
637
+ # was settled in the run, by an operator picking from a menu or by a non-interactive
638
+ # default. Recording it and carrying on is how an unapproved departure from a
639
+ # NON-NEGOTIABLE principle reaches code, so the run stops here and the choice goes
640
+ # back to a human who can either comply or amend the constitution properly.
641
+ - id: governance_gate
642
+ condition: "{{nn_count}} != 0"
643
+ action: verify_context
644
+ require_true: nn_compliant
645
+ on_false: stop
646
+ on_false_message: "The answer to \"{{c.question}}\" departs from NON-NEGOTIABLE principle {{nn_principle}}: {{nn_why}}. That principle is ratified in .appweaver/memory/ and this answer has no approver — it was settled in this run, not by a domain owner, and the constitution's Governance section holds that a deviation with no named approver is a defect rather than a decision. Re-run specify and answer in a way the principle allows; if the project genuinely intends to depart from it, amend the constitution through its own amendment process FIRST (which names the approver the departure needs) and re-run. Nothing was written to {{quality_target}} for this clarification."
647
+
548
648
  - id: resolve_clar
549
649
  action: agent_author
550
650
  context: ["{{quality_target}}"]
@@ -0,0 +1,141 @@
1
+ # =============================================================================
2
+ # aw-spec-ui-model (orchestrator) — Derive UI Model from Workflow Model
3
+ #
4
+ # Stage 3 of the 4-Stage Spec-Driven UI Generation Pipeline.
5
+ # Consumes `specs/<Feature>/ui/workflow-model.md` and maps workflows into concrete UI surfaces
6
+ # (Pages, Sub-Pages, Drawers, Modals, Dialogs), interaction states (Loading, Empty, Populated, Filtered, Error, Success),
7
+ # user actions, and surface transitions.
8
+ # Writes output artifact to `specs/<Feature>/ui/ui-model.md`.
9
+ #
10
+ # Launch:
11
+ # /appweaver ui-model [strategy] [guidance]
12
+ # =============================================================================
13
+
14
+ name: aw-spec-ui-model
15
+ description: Derive the UI Model (specs/<Feature>/ui/ui-model.md) from workflow-model.md, specifying UI surfaces (pages, dialogs, drawers, modals), routes, interaction states, actions, and navigation transitions.
16
+ version: 1.0.0
17
+ agent_agnostic: true
18
+ dialect: aw-spec.orchestrator/v1
19
+
20
+ inputs:
21
+ user_input:
22
+ description: Optional UI layout or surface guidance.
23
+ required: false
24
+ bind: USER_INPUT
25
+
26
+ scripts:
27
+ actions:
28
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
29
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
30
+
31
+ vars:
32
+ feature: ""
33
+ feature_dir: ""
34
+ feature_slug: ""
35
+ spec_file: ""
36
+ spec_exists: "false"
37
+ workflow_model_file: ""
38
+ workflow_model_exists: "false"
39
+ active_change: ""
40
+ has_change: "false"
41
+ domain: ""
42
+ prototype_root: ""
43
+
44
+ workflow:
45
+
46
+ # 1. Resolve active feature and paths
47
+ - id: feature_paths
48
+ action: execute_script
49
+ on_error: continue
50
+ script: { ref: actions }
51
+ subcommand: feature-paths
52
+ outputs:
53
+ - { name: feature, from: "$.feature" }
54
+ - { name: feature_dir, from: "$.feature_dir" }
55
+ - { name: feature_slug, from: "$.feature_slug" }
56
+ - { name: spec_file, from: "$.spec_file" }
57
+ - { name: spec_exists, from: "$.spec_exists" }
58
+ - { name: domain, from: "$.domain" }
59
+ - { name: prototype_root, from: "$.prototype_root" }
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 selected. Run /appweaver select-feature first."
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. Run /appweaver specify first."
72
+
73
+ # 2. Check workflow-model.md existence
74
+ - id: check_workflow_model
75
+ action: execute_script
76
+ on_error: continue
77
+ script: { ref: actions }
78
+ subcommand: path-exists
79
+ args: ["--path", "{{feature_dir}}/ui/workflow-model.md"]
80
+ outputs:
81
+ - { name: workflow_model_exists, from: "$.exists" }
82
+
83
+ - id: require_workflow_model
84
+ action: verify_context
85
+ require_true: workflow_model_exists
86
+ on_false: stop
87
+ on_false_message: "No Workflow Model found at specs/{{feature}}/ui/workflow-model.md. Run /appweaver workflow-model first."
88
+
89
+ # 3. Assemble workflow model & template context
90
+ - id: ctx_ui_model
91
+ action: build_context
92
+ vars:
93
+ feature_name: "{{feature}}"
94
+ feature_dir: "{{feature_dir}}"
95
+ user_preferences: "{{USER_INPUT}}"
96
+ context:
97
+ - "{{feature_dir}}/ui/workflow-model.md"
98
+ - "{{spec_file}}"
99
+ - { path: ".appweaver/templates/ui-model-template.md", optional: true }
100
+ - { path: ".appweaver/memory/constitution.ui.md", optional: true }
101
+
102
+ # 4. Generate UI Model Artifact (specs/<Feature>/ui/ui-model.md)
103
+ - id: generate_ui_model
104
+ action: agent_generate
105
+ tools: "Read,Write,Edit,Bash"
106
+ permission_mode: acceptEdits
107
+ task: |
108
+ You are authoring Stage 3 (UI Model) of the 4-Stage Spec-Driven UI Pipeline for feature `{{feature_name}}`.
109
+
110
+ Target Artifact Path: `{{feature_dir}}/ui/ui-model.md`
111
+
112
+ Instructions:
113
+ 1. Read `specs/{{feature}}/ui/workflow-model.md` and `spec.md` in context.
114
+ 2. Translate EVERY workflow (WF-1, WF-2, ...) into explicit **UI Surfaces**:
115
+ - Determine the appropriate UI surface type for each workflow step: `Page`, `Sub-Page`, `Dialog`, `Drawer`, `Modal`, `View`.
116
+ - Map routes or component mount paths (e.g. `/{{feature_slug}}`, `/{{feature_slug}}/create`, modal dialog triggers).
117
+ - Define supported interaction states per surface (`Loading`, `Empty`, `Populated`, `Filtered / Searched`, `Validation Error`, `Submitting`, `Success`, `Error`).
118
+ - Specify interactive controls, form fields, action buttons, and table/card layouts.
119
+ - Map explicit navigation & transition triggers (`On Action -> Opens Surface X`).
120
+ 3. Remember the core rule: **Workflow != Single Screen**. A workflow can span multiple surfaces or reuse surfaces with state changes.
121
+ 4. Format output according to `.appweaver/templates/ui-model-template.md`.
122
+ 5. Write the authored markdown content to `{{feature_dir}}/ui/ui-model.md`.
123
+
124
+ User Guidance:
125
+ {{user_preferences}}
126
+
127
+ End your final reply with a summary and a ```json fence:
128
+ ```json
129
+ {
130
+ "status": "ok",
131
+ "feature": "{{feature_name}}",
132
+ "ui_model_path": "{{feature_dir}}/ui/ui-model.md"
133
+ }
134
+ ```
135
+ outputs:
136
+ - { name: result, from: "$" }
137
+
138
+ outputs:
139
+ feature: "{{feature}}"
140
+ ui_model_path: "{{feature_dir}}/ui/ui-model.md"
141
+ next: "Run /appweaver ui-prototype to generate the executable Next.js prototype application."
@@ -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."