aw-spec-cli 0.1.26 → 0.1.27

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 (98) hide show
  1. package/assets/.agents/skills/appweaver/SKILL.md +7 -47
  2. package/assets/.appweaver/ORCH-DIALECT.md +13 -9
  3. package/assets/.appweaver/RULE-PARTITION.md +3 -3
  4. package/assets/.appweaver/STACK-PROFILES.md +188 -101
  5. package/assets/.appweaver/domain.json +1 -1
  6. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +38 -10
  7. package/assets/.appweaver/orchestrator/LAUNCHER.md +88 -0
  8. package/assets/.appweaver/orchestrator/README.md +120 -53
  9. package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +1 -1
  10. package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +6 -4
  11. package/assets/.appweaver/orchestrator/modules/foundation-lane.orch.yaml +237 -0
  12. package/assets/.appweaver/orchestrator/modules/foundation-pack.orch.yaml +349 -0
  13. package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +381 -0
  14. package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +4 -4
  15. package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +3 -3
  16. package/assets/.appweaver/orchestrator/orchestrator.py +162 -63
  17. package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +2 -2
  18. package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
  19. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +5 -5
  20. package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +1 -1
  21. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +14 -14
  22. package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +2 -2
  23. package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
  24. package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +3 -3
  25. package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +41 -3
  26. package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +1 -1
  27. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +13 -13
  28. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +3 -3
  29. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +3 -3
  30. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
  31. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +2 -2
  32. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +61 -12
  33. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +172 -293
  34. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +29 -28
  35. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +53 -53
  36. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
  37. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +3 -3
  38. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +4 -4
  39. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +26 -2
  40. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +21 -15
  41. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +14 -14
  42. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +2 -2
  43. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +3 -3
  44. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +6 -6
  45. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +284 -128
  46. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +224 -70
  47. package/assets/.appweaver/scripts/python/aw-foundation.py +809 -20
  48. package/assets/.appweaver/scripts/python/aw-inventory.py +28 -21
  49. package/assets/.appweaver/scripts/python/aw-plan-coverage.py +2 -2
  50. package/assets/.appweaver/scripts/python/aw-rev-constitution.py +6 -6
  51. package/assets/.appweaver/scripts/python/aw-stack.py +195 -89
  52. package/assets/.appweaver/stack-profiles/angular.json +2 -1
  53. package/assets/.appweaver/stack-profiles/blazor-wasm.json +2 -1
  54. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +16 -3
  55. package/assets/.appweaver/stack-profiles/go-chi.json +6 -1
  56. package/assets/.appweaver/stack-profiles/java-spring.json +12 -5
  57. package/assets/.appweaver/stack-profiles/nextjs.json +2 -1
  58. package/assets/.appweaver/stack-profiles/node-express.json +8 -2
  59. package/assets/.appweaver/stack-profiles/python-fastapi.json +9 -2
  60. package/assets/.appweaver/stack-profiles/react-vite.json +2 -1
  61. package/assets/.appweaver/stack-profiles/sveltekit.json +2 -1
  62. package/assets/.appweaver/stack-profiles/vue-vite.json +2 -1
  63. package/assets/.appweaver/stacks.json +37 -1
  64. package/assets/.appweaver/templates/constitution-ui-template.md +2 -2
  65. package/assets/.claude/skills/appweaver/SKILL.md +7 -46
  66. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.rules.json +31 -0
  67. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.rules.json +16 -0
  68. package/assets/foundations/foundation.spec.template.txt +73 -0
  69. package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +1 -1
  70. package/assets/foundations/java/Hexagonal/unpack-foundation.sh +4 -5
  71. package/assets/foundations/node/NextAppRouter/NextAppRouter.spec.txt +68 -0
  72. package/assets/guardrails/README.md +31 -17
  73. package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain-rule-bindings.md +5 -5
  74. package/assets/guardrails/{projects/dotnet-default-project → project-specific}/tech-rule-bindings.md +151 -114
  75. package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +58 -4
  76. package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +1 -1
  77. package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +1 -1
  78. package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +1 -1
  79. package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +1 -1
  80. package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
  81. package/assets/guardrails/technology/nextjs/api-client.md +1 -1
  82. package/assets/guardrails/technology/nextjs/component-architecture.md +1 -1
  83. package/assets/guardrails/technology/nextjs/component-conventions.md +2 -2
  84. package/assets/guardrails/technology/nextjs/design-system.md +1 -1
  85. package/assets/guardrails/technology/nextjs/frontend-testing.md +1 -1
  86. package/assets/guardrails/technology/nextjs/routing-navigation.md +1 -1
  87. package/assets/guardrails/technology/nextjs/ui-constitution.md +3 -3
  88. package/package.json +1 -1
  89. package/assets/.agents/skills/appweaver-demo/SKILL.md +0 -59
  90. package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +0 -6
  91. package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -100
  92. package/assets/.claude/skills/appweaver-demo/SKILL.md +0 -59
  93. package/assets/.kilocode/agent.json +0 -28
  94. package/assets/.kilocode/workflows/appweaver-demo.md +0 -59
  95. package/assets/.kilocode/workflows/appweaver.md +0 -55
  96. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain/domain-requirements.md +0 -0
  97. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/frontend/ui-requirements.md +0 -0
  98. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/service/technical-requirements.md +0 -0
@@ -4,7 +4,12 @@
4
4
  "title": "Go + chi",
5
5
  "language": "Go",
6
6
  "ecosystem": "go",
7
- "root": "internal/",
7
+ "root": "backend/",
8
+ "run_from": "root",
9
+ "conventional_root": "internal/",
10
+ "build_files": [
11
+ "go.mod"
12
+ ],
8
13
  "build": "go build ./...",
9
14
  "test": "go test ./...",
10
15
  "run": "go run ./cmd/api",
@@ -4,12 +4,19 @@
4
4
  "title": "Spring Boot",
5
5
  "language": "Java",
6
6
  "ecosystem": "java",
7
- "root": "src/main/java/",
8
- "test_root": "src/test/java/",
7
+ "root": "backend/",
8
+ "test_root": "backend/src/test/java/",
9
9
  "run_from": "root",
10
- "build": "./mvn clean install",
11
- "test": "./mvn test",
12
- "run": "./mvn spring-boot:run",
10
+ "conventional_root": "src/main/java/",
11
+ "conventional_test_root": "src/test/java/",
12
+ "build_files": [
13
+ "pom.xml",
14
+ "build.gradle",
15
+ "build.gradle.kts"
16
+ ],
17
+ "build": "./mvnw clean install",
18
+ "test": "./mvnw test",
19
+ "run": "./mvnw spring-boot:run",
13
20
  "detect": [
14
21
  "pom.xml",
15
22
  "build.gradle"
@@ -4,8 +4,9 @@
4
4
  "title": "Next.js",
5
5
  "language": "TypeScript",
6
6
  "ecosystem": "node",
7
- "root": "web/",
7
+ "root": "frontend/",
8
8
  "run_from": "root",
9
+ "conventional_root": "web/",
9
10
  "build": "npm run build",
10
11
  "test": "npm test",
11
12
  "run": "npm run dev",
@@ -4,8 +4,14 @@
4
4
  "title": "Express + TypeScript",
5
5
  "language": "Node.js",
6
6
  "ecosystem": "node",
7
- "root": "src/",
8
- "test_root": "tests/",
7
+ "root": "backend/",
8
+ "test_root": "backend/tests/",
9
+ "run_from": "root",
10
+ "conventional_root": "src/",
11
+ "conventional_test_root": "tests/",
12
+ "build_files": [
13
+ "package.json"
14
+ ],
9
15
  "build": "npm run build",
10
16
  "test": "npm test",
11
17
  "run": "npm run dev",
@@ -4,8 +4,15 @@
4
4
  "title": "FastAPI",
5
5
  "language": "Python",
6
6
  "ecosystem": "python",
7
- "root": "app/",
8
- "test_root": "tests/",
7
+ "root": "backend/",
8
+ "test_root": "backend/tests/",
9
+ "run_from": "root",
10
+ "conventional_root": "app/",
11
+ "conventional_test_root": "tests/",
12
+ "build_files": [
13
+ "pyproject.toml",
14
+ "requirements.txt"
15
+ ],
9
16
  "build": "python -m compileall {{root}}",
10
17
  "test": "pytest",
11
18
  "run": "uvicorn app.main:app --reload",
@@ -4,8 +4,9 @@
4
4
  "title": "React + Vite",
5
5
  "language": "TypeScript",
6
6
  "ecosystem": "node",
7
- "root": "web/",
7
+ "root": "frontend/",
8
8
  "run_from": "root",
9
+ "conventional_root": "web/",
9
10
  "build": "npm run build",
10
11
  "test": "npm test",
11
12
  "run": "npm run dev",
@@ -4,8 +4,9 @@
4
4
  "title": "SvelteKit",
5
5
  "language": "TypeScript",
6
6
  "ecosystem": "node",
7
- "root": "web/",
7
+ "root": "frontend/",
8
8
  "run_from": "root",
9
+ "conventional_root": "web/",
9
10
  "build": "npm run build",
10
11
  "test": "npm test",
11
12
  "run": "npm run dev",
@@ -4,8 +4,9 @@
4
4
  "title": "Vue 3 + Vite",
5
5
  "language": "TypeScript",
6
6
  "ecosystem": "node",
7
- "root": "web/",
7
+ "root": "frontend/",
8
8
  "run_from": "root",
9
+ "conventional_root": "web/",
9
10
  "build": "npm run build",
10
11
  "test": "npm test",
11
12
  "run": "npm run dev",
@@ -1,3 +1,39 @@
1
1
  {
2
- "lanes": []
2
+ "lanes": [],
3
+ "_lane_format": {
4
+ "lanes": [
5
+ {
6
+ "id": "service",
7
+ "kind": "backend",
8
+ "profile": "dotnet-webapi",
9
+ "stack": "ASP.NET Core Web API",
10
+ "origin": "declared",
11
+ "root": "backend/",
12
+ "test_root": "backend/tests/",
13
+ "run_from": "root",
14
+ "build": "dotnet build",
15
+ "test": "dotnet test",
16
+ "run": "dotnet run --project {{host}}",
17
+ "migrate": "dotnet ef database update --project {{host}}"
18
+ },
19
+ {
20
+ "id": "web",
21
+ "kind": "frontend",
22
+ "profile": "nextjs",
23
+ "stack": "Next.js",
24
+ "origin": "declared",
25
+ "root": "frontend/",
26
+ "test_root": "frontend/",
27
+ "run_from": "root",
28
+ "build": "npm run build",
29
+ "test": "npm test",
30
+ "run": "npm run dev",
31
+ "migrate": ""
32
+ }
33
+ ],
34
+ "prototype": {
35
+ "root": "prototype/",
36
+ "run": "npm run dev --prefix prototype"
37
+ }
38
+ }
3
39
  }
@@ -90,9 +90,9 @@
90
90
  <!-- Form: the lane's structural mandate, named as the lane rules name it. -->
91
91
 
92
92
  [UI_STRUCTURE_CONTENT]
93
- <!-- Form: the lane root and the layout beneath it, as the mapped rules define it for this
93
+ <!-- Form: the lane root folder and the layout beneath it, as the mapped rules define it for this
94
94
  lane's stack, including where generated contract clients land. This layout sits
95
- ENTIRELY under the lane's root; it never adds to the service lane's structure in
95
+ ENTIRELY under the lane root folder; it never adds to the service lane's structure in
96
96
  constitution.technical.md. -->
97
97
 
98
98
  ## [UI_CONVENTIONS_SECTION_NAME]
@@ -1,55 +1,16 @@
1
1
  ---
2
2
  name: "appweaver"
3
- description: "Parametric launcher (Claude Code): run ANY converted aw-spec skill on the aw-orchestrator under one of the 4 strategies (agent [default], spawn, sdk, sdk-apply)."
4
- argument-hint: "<skill> [strategy] [input…] — e.g. 'select-domain', 'specify spawn Build an order API', 'analyze-slice'"
5
- compatibility: "Requires .appweaver/orchestrator/ and the claude CLI on PATH"
3
+ description: "Parametric launcher: run ANY converted aw-spec skill on the aw-orchestrator under one of the 4 strategies (agent [default], spawn, sdk, sdk-apply)."
4
+ argument-hint: "<skill> [strategy] [input…] — e.g. 'select-stack', 'specify spawn Build an order API', 'analyze-slice'"
5
+ compatibility: "Requires .appweaver/orchestrator/ and python3"
6
6
  user-invocable: true
7
7
  disable-model-invocation: false
8
8
  ---
9
9
 
10
- # Orchestrator Skill Launcher
10
+ # AppWeaver launcher
11
11
 
12
- Runs one converted `aw-spec-*` workflow on the shared, agent-agnostic engine. All orchestration and **all context management live in the workflow YAML + engine** (`.appweaver/orchestrator/orchestrator.py`): the interpreter assembles the COMPLETE payload (system + user) for every request; you never author generation context yourself. Execution follows the chosen strategy; the checkpoint channel carries every human-facing interaction regardless of strategy.
12
+ Read `.appweaver/orchestrator/LAUNCHER.md` and follow it exactly.
13
13
 
14
- - **Engine + workflows (common, shared by all agents):** `.appweaver/orchestrator/orchestrator.py`, `.appweaver/orchestrator/workflows/aw-spec-<skill>.orch.yaml`, shared modules in `.appweaver/orchestrator/modules/`, shared scripts in `.appweaver/scripts/`
15
- - **This agent's transport profile:** `.claude/agent.json`
14
+ Several agents read this folder, so this launcher names no agent: find the row for the agent you are in the profile table of `LAUNCHER.md` — that row is your transport profile. If you have no row, only the `agent` strategy is available.
16
15
 
17
- > Claude Code spawns via the `claude -p` CLI (native `--system-prompt`,
18
- > `--tools`, and `--bare` isolation). Its `sdk` block declares the SDK the
19
- > `sdk`/`sdk-apply` strategies import (`claude-agent-sdk`) and the adapter
20
- > (`.appweaver/orchestrator/adapters/claude_agent_sdk.py`, shared per-SDK)
21
- > that owns its calling convention.
22
-
23
- ## Execution Steps
24
-
25
- 1. **Parse Arguments** (`<skill> [strategy] [input…]`):
26
- - `skill` (required): the aw-spec skill name, e.g. `demo`, `select-domain`, `foundation`, `specify`, `design`, `implement`, `build`. Resolve the workflow file `.appweaver/orchestrator/workflows/aw-spec-<skill>.orch.yaml`. If it does not exist, list the available `aw-spec-*.orch.yaml` files in that folder and stop.
27
- - `strategy` (optional, one of `agent`, `spawn`, `sdk`, `sdk-apply`; default `agent` — YOU fulfill each generation through the checkpoint channel, no profile needed): who executes each generation. Always pass `--strategy <strategy>`.
28
- - Everything after the strategy is the user input: pass it as `--input "<text>"` (omit when empty).
29
- - `--agent-profile .claude/agent.json` is required for `spawn`, `sdk`, and `sdk-apply` (`agent` needs no profile). If the SDK package isn't installed, add `--sdk-install`.
30
- - **Always** pass `--checkpoint .appweaver/orchestrator/.state/<skill>.state.json` — for EVERY strategy. Converted skills contain interactive steps (questions, selections, hooks); the checkpoint is how they reach you and the user. Strategies only govern who generates.
31
- - `spawn` may also add `--isolation bare|fresh` and `--model <name>`; `sdk`/`sdk-apply` accept `--model <name>`.
32
-
33
- 2. **Run the Interpreter**:
34
- ```bash
35
- python3 .appweaver/orchestrator/orchestrator.py \
36
- .appweaver/orchestrator/workflows/aw-spec-<skill>.orch.yaml \
37
- --strategy <strategy> \
38
- --checkpoint .appweaver/orchestrator/.state/<skill>.state.json \
39
- [--agent-profile .claude/agent.json] # spawn, sdk, sdk-apply \
40
- [--input "<user input>"] \
41
- --json
42
- ```
43
-
44
- 3. **Handle the Suspend/Resume Loop** — whenever the command exits with code `2`, read the printed `pending` JSON and dispatch on `pending.kind`; fulfill it, write the response to `pending.response_path`, then re-run the SAME command. Repeat until exit `0` (done) or `1` (stopped by a gate).
45
- - **`ask`** — ask the USER the `prompt` with the listed `options` (use your question tool). Write the chosen answer as PLAIN TEXT to `response_path` (comma-separated values when `multi` is true).
46
- - **`select`** — ask the USER to pick ONE of `options`; write the chosen value as plain text to `response_path`.
47
- - **`hook`** — run each MANDATORY hook in `hooks` (each is a slash command of THIS agent) in this conversation; optional hooks at your discretion. Then write `done` to `response_path`.
48
- - **`author`** — read `system_path` + `user_path` and treat them as your ONLY standards and context. Author the COMPLETE content of the file named in `target` and write it — content ONLY, no commentary, no code fence — to `response_path`. Do NOT write the target file yourself; the interpreter does that.
49
- - **`agent_generate`** — read `system_path` + `user_path`; perform the task YOURSELF with the listed `tools` within `permission_mode`; write your full final reply — ending with the required ```json fence — to `response_path`.
50
- - **`agent_query` / `agent_review`** — same as above but READ-ONLY (do not modify files); the reply must end with the required ```json fence.
51
- - **`apply`** — an isolated generation already decided the changes: read `artifact_path` and write its file contents EXACTLY to the paths it names, then write the confirmation ```json fence to `response_path`.
52
- - If `pending.note` is present, your previous response was rejected — follow the note and rewrite `response_path`.
53
-
54
- 4. **Report**:
55
- Report the final JSON (`status`, `outputs`, and any `reason`) to the user. On `stopped`, relay the gate message verbatim — it tells the user what to fix or run first.
16
+ The arguments are the text the user typed after `/appweaver`.
@@ -0,0 +1,31 @@
1
+ {
2
+ "format": "aw-spec-pack-rules/v1",
3
+ "rules": [
4
+ {
5
+ "path": "src/AppWeaver.ModularMonolith.Infrastructure/DatabaseContext/ApplicationDbContext.cs",
6
+ "action": "merge",
7
+ "note": "The base project's DbContext has the full OnModelCreating and no DbSet<> properties; the sample's has the sample's DbSet<> properties, its own usings, and nothing else.",
8
+ "instruction": [
9
+ "Produce one ApplicationDbContext based on the EXISTING file (the base project's DbContext):",
10
+ "- add every using directive the INCOMING file has that the EXISTING file lacks;",
11
+ "- insert every INCOMING `public DbSet<...>` property, with any comment above it, as one block right after the class's opening brace (before OnModelCreating);",
12
+ "- keep everything else in the EXISTING file unchanged."
13
+ ]
14
+ },
15
+ {
16
+ "path": "src/AppWeaver.ModularMonolith.Domain/Interfaces/IApplicationDbContext.cs",
17
+ "action": "merge",
18
+ "note": "The base project's interface has the usings, the namespace and SaveChangesAsync; the sample's has only the sample's DbSet<> properties.",
19
+ "instruction": [
20
+ "Produce one IApplicationDbContext based on the EXISTING file (the base project's interface), keeping its using directives, its namespace and SaveChangesAsync:",
21
+ "- insert every INCOMING `DbSet<...>` property, with any comment above it, as one block right after the interface's opening brace (before SaveChangesAsync);",
22
+ "- keep everything else in the EXISTING file unchanged."
23
+ ]
24
+ },
25
+ {
26
+ "path": "src/AppWeaver.ModularMonolith.Domain/AppWeaver.ModularMonolith.Domain.csproj",
27
+ "action": "replace",
28
+ "note": "The sample ships the Domain project file too; its copy is written over the base project's."
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "format": "aw-spec-pack-rules/v1",
3
+ "rules": [
4
+ {
5
+ "path": "src/AppWeaver.VerticalSlice.Service/Infrastructure/ApplicationDbContext.cs",
6
+ "action": "merge",
7
+ "note": "The base project's DbContext has the full OnModelCreating and no DbSet<> properties; the sample's has the sample's DbSet<> properties, its own usings, and nothing else.",
8
+ "instruction": [
9
+ "Produce one ApplicationDbContext based on the EXISTING file (the base project's DbContext):",
10
+ "- add every using directive the INCOMING file has that the EXISTING file lacks;",
11
+ "- insert every INCOMING `public DbSet<...>` property, with any comment above it, as one block right after the class's opening brace (before OnModelCreating);",
12
+ "- keep everything else in the EXISTING file unchanged."
13
+ ]
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,73 @@
1
+ # kind: backend
2
+ # profiles: dotnet-webapi
3
+ # title: <one line shown in the /appweaver foundation pick list>
4
+ #
5
+ # ─────────────────────────────────────────────────────────────────────────────
6
+ # FOUNDATION SPEC TEMPLATE — how to describe a base project for /appweaver foundation
7
+ #
8
+ # A spec is the alternative to a pack. A pack (<Name>.pack.txt) is a verified project
9
+ # unpacked byte-for-byte; a spec DESCRIBES the project, and an agent builds it into the
10
+ # lane root folder when the operator picks it. Use one where no pack ships for the
11
+ # stack, or where the project is easier to describe than to keep as a frozen copy.
12
+ #
13
+ # WHERE IT GOES. Copy this file to foundations/<ecosystem>/<Name>/<Name>.spec.txt —
14
+ # <ecosystem> is the `ecosystem` of the stack profile (.appweaver/stack-profiles/*.json:
15
+ # dotnet, java, node, python, go …). A directory may hold a pack, specs, or both; every
16
+ # *.spec.txt in it is its own entry, named after the file. It is listed for a lane only
17
+ # when its header admits that lane:
18
+ #
19
+ # # kind: backend | frontend (absent = backend)
20
+ # # profiles: stack-profile ids, comma-separated (absent = any profile of that kind
21
+ # in the ecosystem — say which, because `node` covers Next.js, Angular,
22
+ # Vue, SvelteKit and the Express backend alike)
23
+ # # title: the label in the pick list
24
+ #
25
+ # The header is the leading block of `#` lines; the first line that does not start with
26
+ # `#` ends it. Everything after this header block is the spec itself, written for the
27
+ # agent that builds the project — be concrete. The same shape works for a spec given at
28
+ # the [manual spec] prompt (as a file path, or pasted as text).
29
+ #
30
+ # WHAT THE AGENT ALREADY KNOWS, so the spec need not repeat it: the lane root folder (the
31
+ # WHOLE project goes inside it: build files, source and tests), its test
32
+ # path inside that folder, and its build command, which runs in that folder (from
33
+ # .appweaver/stacks.json), the project name the operator entered, and the technical rules
34
+ # the selected project maps under `## /aw-spec-foundation-backend` or
35
+ # `## /aw-spec-foundation-frontend` in its tech-rule-bindings.md. Where this spec is
36
+ # silent the agent follows those rules; where the two disagree the spec wins and the
37
+ # agent names the conflict. Paths below are relative to the lane root folder.
38
+ # ─────────────────────────────────────────────────────────────────────────────
39
+
40
+ # <Project kind> foundation — <stack and version>
41
+
42
+ ## Purpose
43
+ One or two sentences: what this base project is for, and what it deliberately leaves out
44
+ (business features come later from /appweaver implement).
45
+
46
+ ## Create
47
+ The commands that create the project, in order, and where their output must land.
48
+ - e.g. `dotnet new webapi -n <ProjectName> -o src/<ProjectName>.Api`
49
+ - e.g. a solution file at the top of the lane root folder, referencing every project
50
+
51
+ ## Packages
52
+ Exact packages (and versions where it matters), split by project.
53
+
54
+ ## Layout
55
+ The folder structure the project starts with, as a tree. Name the folders feature code will
56
+ later go into, even when they start empty (add a .gitkeep).
57
+
58
+ ## Starter files
59
+ Each file the base project needs beyond what the tools generate — what it contains, not
60
+ just its name: configuration, the composition root, a health endpoint, the error-handling
61
+ middleware, a sample test that proves the test project runs.
62
+
63
+ ## Configuration
64
+ Settings files, environment variables, ports, connection strings (placeholders, never
65
+ secrets).
66
+
67
+ ## Tests
68
+ The test project(s): framework, where they live (the lane's test path), and the one test that
69
+ must pass on a fresh scaffold.
70
+
71
+ ## Done when
72
+ How to confirm the scaffold works — the lane's build passes, the test command passes, the app
73
+ starts and answers a named URL.
@@ -8,7 +8,7 @@
8
8
  # --- Java foundation replacement contract ---
9
9
  # Java content: io.appweaver -> <lowercase-app-name>
10
10
  # Java path: io/appweaver -> <lowercase-app-name>
11
- # Application directory preserves the user-provided name.
11
+ # Unpacked into --out-dir as-is: that directory is the Maven module.
12
12
  # ============================================================
13
13
 
14
14
  <<<DIR path=".mvn">>>
@@ -206,11 +206,10 @@ apply_repl() {
206
206
 
207
207
  # ----------------------------------------------------------- output root ------------
208
208
 
209
- if [ "$OUT_DIR" = "." ]; then
210
- OUT_ROOT="$TARGET_APP_NAME"
211
- else
212
- OUT_ROOT="$OUT_DIR/$TARGET_APP_NAME"
213
- fi
209
+ # The pack is the Maven module itself (pom.xml, mvnw, src/main/java, src/test/java), and it
210
+ # lands in --out-dir exactly as packed: that directory IS the module. The app name renames
211
+ # the Java package; it does not add a folder.
212
+ OUT_ROOT="$OUT_DIR"
214
213
 
215
214
  # ----------------------------------------------------------- parse pack blocks -------
216
215
 
@@ -0,0 +1,68 @@
1
+ # kind: frontend
2
+ # profiles: nextjs
3
+ # title: Next.js App Router base (TypeScript, ESLint, Vitest) built from this spec
4
+
5
+ # Next.js App Router foundation — frontend lane
6
+
7
+ ## Purpose
8
+ A clean, building Next.js frontend for the lane: App Router, TypeScript in strict mode,
9
+ ESLint, a token-based design-system layer and a working test setup. No business screens —
10
+ /appweaver implement adds those per feature later, from frontend-plan.md.
11
+
12
+ ## Create
13
+ Run at the repository root, naming the lane root folder, so the app lands directly in that
14
+ folder (not in a folder inside or beside it):
15
+ - `npx create-next-app@latest <lane root folder without trailing slash> --typescript --eslint --app --no-src-dir --import-alias "@/*" --use-npm --no-tailwind --yes`
16
+ Set `"name"` in package.json to the project name in lower-kebab form
17
+ (e.g. AppWeaver.Health -> appweaver-health).
18
+
19
+ ## Packages
20
+ Development dependencies:
21
+ - vitest, @vitejs/plugin-react, jsdom
22
+ - @testing-library/react, @testing-library/jest-dom, @testing-library/user-event
23
+ - vitest-axe (accessibility assertions)
24
+
25
+ ## Layout
26
+ Under the lane root folder (create empty folders with a .gitkeep):
27
+ ```
28
+ app/ App Router — layout.tsx, page.tsx, loading.tsx, error.tsx, not-found.tsx
29
+ components/ design-system compositions, presentational only
30
+ features/ one folder per spec feature (empty at start)
31
+ lib/api/ the generated contract client (empty at start — never hand-written)
32
+ lib/ cross-feature client utilities
33
+ locales/ locale catalogues — en.json to start
34
+ styles/tokens.css the semantic design tokens
35
+ tests/ component, integration and accessibility tests
36
+ ```
37
+
38
+ ## Starter files
39
+ - `styles/tokens.css` — semantic CSS custom properties only (`--color-surface`,
40
+ `--color-text`, `--color-muted`, `--color-danger`, `--space-1..6`, `--radius-1..3`,
41
+ `--font-body`), with a `prefers-color-scheme: dark` block. Imported once by
42
+ `app/layout.tsx`; no literal colour anywhere else.
43
+ - `app/layout.tsx` — html `lang` from the default locale, the tokens import, a skip-to-content
44
+ link, `<main id="main">`.
45
+ - `app/page.tsx` — a server component rendering the app name and one line of text.
46
+ - `app/loading.tsx`, `app/error.tsx` (client component with a retry button), `app/not-found.tsx`.
47
+ - `components/Button.tsx` — one presentational component styled only with tokens, as the
48
+ pattern later components follow.
49
+ - `lib/env.ts` — reads `NEXT_PUBLIC_API_BASE_URL` once and exports it typed; nothing else
50
+ reads `process.env`.
51
+ - `locales/en.json` — the strings the starter pages use.
52
+ - `.env.example` — `NEXT_PUBLIC_API_BASE_URL=http://localhost:5000`.
53
+ Remove the create-next-app demo content (the default page body, its CSS module and images).
54
+
55
+ ## Configuration
56
+ - `tsconfig.json`: `"strict": true`, keep the `@/*` alias.
57
+ - `vitest.config.ts`: jsdom environment, the React plugin, `tests/setup.ts` as setup file
58
+ (registers jest-dom and vitest-axe matchers), the `@/*` alias.
59
+ - package.json scripts: `dev`, `build`, `start`, `lint` (from create-next-app), plus
60
+ `"test": "vitest run"` and `"typecheck": "tsc --noEmit"`.
61
+
62
+ ## Tests
63
+ - `tests/page.test.tsx` — renders the home page and asserts the app name is shown.
64
+ - `tests/button.a11y.test.tsx` — renders `Button` and asserts no axe violations.
65
+
66
+ ## Done when
67
+ `npm install`, `npm run build`, `npm test` and `npm run lint` all pass in the lane root
68
+ folder, and `npm run dev` serves the home page at http://localhost:3000.
@@ -13,27 +13,39 @@ guardrails/
13
13
  ├── domain/<industry>/ domain rules — vary by industry, never by stack
14
14
  │ ├── healthcare/
15
15
  │ └── pharma/
16
- └── projects/<project>/ what a project SELECTS
17
- └── dotnet-default-project/
18
- ├── tech-rule-bindings.md → technology/dotnet-webapi/ + technology/nextjs/
19
- ├── domain-rule-bindings.md → domain/healthcare/
20
- ├── service/technical-requirements.md PROJECT-SUPPLIED
21
- ├── frontend/ui-requirements.md PROJECT-SUPPLIED
22
- └── domain/domain-requirements.md PROJECT-SUPPLIED
16
+ ├── project-specific/ the project's own rules — what it SELECTS from the corpora
17
+ │ ├── tech-rule-bindings.md → technology/{{backend_stack}}/ + technology/{{frontend_stack}}/
18
+ │ ├── domain-rule-bindings.md → domain/healthcare/
19
+ │ ├── service/technical-requirements.md PROJECT-SUPPLIED
20
+ │ ├── frontend/ui-requirements.md PROJECT-SUPPLIED
21
+ │ └── domain/domain-requirements.md PROJECT-SUPPLIED
22
+ └── brf-<name>/ a project `onboard` reverse-engineers from existing code
23
23
  ```
24
24
 
25
- `/appweaver select-domain` selects a **project** folder and stores it in `.appweaver/domain.json`;
26
- `resolve-tech` and `resolve-domain` read that project's two maps. **To change what a command loads,
27
- edit the map — never a workflow.** The folder names `technology/` and `domain/` are the only
25
+ **The active project is the folder `.appweaver/domain.json` names** — `project-specific` as shipped,
26
+ and `brf-<name>` once `onboard` has run, because onboard creates that folder and writes its name
27
+ there. No sequence selects a project. To use another one, copy `project-specific/` to a new folder
28
+ here, change the `guardrails/project-specific/` paths inside its two maps to the new folder, and run
29
+ the optional `/appweaver select-domain <name>` — it lists the folders here that hold a map and
30
+ writes the one picked into `domain.json` (editing `"domain"` by hand does the same). It never
31
+ creates a folder. Re-run `/appweaver constitution` after switching so the constitution follows.
32
+ `resolve-tech` and `resolve-domain` read the active project's two maps. **To change what a command
33
+ loads, edit the map — never a workflow.** The folder names `technology/` and `domain/` are the only
28
34
  vocabulary here: a project's maps may point anywhere, in any combination.
29
35
 
30
- **A directory under `projects/` is a project only if it carries a rule map.** Both shells'
31
- `list-domains` enforces that, exactly as `foundations/` requires a `*.pack.txt`. Either map
36
+ **A directory under `guardrails/` is a project only if it carries a rule map.** Both shells'
37
+ `list-domains` enforces that, exactly as `foundations/` requires a `*.pack.txt` or `*.spec.txt` — the
38
+ corpora `technology/` and `domain/` carry no map, so they are never taken for a project. Either map
32
39
  qualifies, because `onboard` writes the domain map several steps before the technical one.
33
40
 
34
- **A brownfield project owns its rules outright.** `dotnet-default-project` above holds only three
41
+ **The technical map names no stack.** Every path in `project-specific/tech-rule-bindings.md` writes
42
+ its stack directory as `{{backend_stack}}` or `{{frontend_stack}}`, resolved from the lanes in
43
+ `.appweaver/stacks.json`, so the same map serves a .NET repo and a Spring one. A corpus that lacks a
44
+ mapped file reports it as missing and loads nothing in its place.
45
+
46
+ **A brownfield project owns its rules outright.** `project-specific/` above holds only three
35
47
  files because it maps the rest from the shared corpora. A project `onboard` reverse-engineers —
36
- `projects/brf-<name>/` — holds everything: the domain set in `domain/`, the technical set in
48
+ `brf-<name>/` — holds everything: the domain set in `domain/`, the technical set in
37
49
  `service/`, the lane set in `frontend/`, and its own charter at `domain/domain-constitution.md`,
38
50
  named the way an industry corpus names its charter. Both maps still sit at the project root, and
39
51
  nothing a project owns is written outside its own folder — which is what lets two onboarded
@@ -91,7 +103,7 @@ is what lists it. Infer the tier from the folder and the fold breaks.
91
103
  `stacks.json` and a rule folder are the same word.
92
104
  - **An industry** — create `domain/<industry>/`, author the overlays, point a project's
93
105
  `domain-rule-bindings.md` at it. The technical map needs no edit.
94
- - **A project** — copy `projects/dotnet-default-project/`, repoint the bullets, replace the three
106
+ - **A project** — fill in `project-specific/`: repoint the bullets and replace the three
95
107
  project-supplied files. Nothing outside that folder changes.
96
108
 
97
109
  ## Files — technical (`technology/dotnet-webapi/`)
@@ -214,8 +226,10 @@ Everything this tree once held that governance does not load left it on 2026-08-
214
226
  `foundations/<stack>/`:
215
227
 
216
228
  - **Scaffold corpora** — `foundations/dotnet/ModularMonolith/` and `foundations/dotnet/VerticalSlice/`:
217
- a `<Name>.pack.txt` payload and the scripts that pack and unpack it, read by
218
- `/appweaver foundation`.
229
+ a `<Name>.pack.txt` payload and the scripts that pack and unpack it; and specs —
230
+ `foundations/node/NextAppRouter/NextAppRouter.spec.txt` — that describe a project an agent
231
+ builds into the lane. Both read by `/appweaver foundation`; the shape of a spec is
232
+ `foundations/foundation.spec.template.txt`.
219
233
  - **Framework component runbooks** — `foundations/dotnet/components/`: the integration contracts
220
234
  `/appweaver add-component` follows when wiring an opt-in component into a scaffolded project.
221
235
 
@@ -1,4 +1,4 @@
1
- # dotnet-default-project — Command → Domain-Rule-File Map
1
+ # project-specific — Command → Domain-Rule-File Map
2
2
 
3
3
  Per-command list of the **domain** rule files this project loads (via `resolve-domain`
4
4
  + the `domain-select` module, into the sticky standards set) for the spec-anchored
@@ -19,8 +19,8 @@ through the spec/design (as CN-/DC-/IC- ids).
19
19
  - To govern a different industry, repoint these bullets at another
20
20
  `guardrails/domain/<industry>/` corpus — `guardrails/domain/pharma/` also ships. Nothing
21
21
  else changes: the technical map, the workflows and the engine are untouched.
22
- - This file is the **canonical domain mapping** for this project; `/appweaver
23
- select-domain` selects this project folder as active.
22
+ - This file is the **canonical domain mapping** for this project; it is used whenever
23
+ `.appweaver/domain.json` names `project-specific`, which it does by default.
24
24
 
25
25
  ---
26
26
 
@@ -49,12 +49,12 @@ through the spec/design (as CN-/DC-/IC- ids).
49
49
  - guardrails/domain/healthcare/zero-trust.domain.md
50
50
  - guardrails/domain/healthcare/ai-rules.domain.md
51
51
  - guardrails/domain/healthcare/folder-structure.domain.md
52
- - guardrails/projects/dotnet-default-project/domain/domain-requirements.md
52
+ - guardrails/project-specific/domain/domain-requirements.md
53
53
 
54
54
  ## /aw-spec-specify
55
55
  <!-- The FULL domain set. Specify models the domain COMPLETELY and LIFTS the constraint
56
56
  overlays into the spec's CN-/DC-/IC- sections (design/implement never see these files). -->
57
- - guardrails/projects/dotnet-default-project/domain/domain-requirements.md
57
+ - guardrails/project-specific/domain/domain-requirements.md
58
58
  - guardrails/domain/healthcare/domain-driven-design.domain.md
59
59
  - guardrails/domain/healthcare/clinical-terms.md
60
60
  - guardrails/domain/healthcare/terminology.md