aw-spec-cli 0.1.26 → 0.1.28
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/.agents/skills/appweaver/SKILL.md +7 -47
- package/assets/.appweaver/ORCH-DIALECT.md +13 -9
- package/assets/.appweaver/RULE-PARTITION.md +11 -12
- package/assets/.appweaver/STACK-PROFILES.md +260 -108
- package/assets/.appweaver/domain.json +1 -1
- package/assets/.appweaver/interpreter/run-skill.py +28 -7
- package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +38 -10
- package/assets/.appweaver/orchestrator/LAUNCHER.md +88 -0
- package/assets/.appweaver/orchestrator/README.md +120 -53
- package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +1 -1
- package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +17 -7
- package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +6 -4
- package/assets/.appweaver/orchestrator/modules/foundation-lane.orch.yaml +237 -0
- package/assets/.appweaver/orchestrator/modules/foundation-pack.orch.yaml +392 -0
- package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +548 -0
- package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/orchestrator.py +162 -63
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +5 -4
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +3 -1
- package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +21 -13
- package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +28 -31
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +3 -3
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +4 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +6 -4
- package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +41 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +17 -16
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +7 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +7 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +61 -12
- package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +172 -293
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +253 -44
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +72 -71
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +38 -14
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +26 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +21 -15
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +14 -14
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +6 -6
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +371 -131
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +293 -76
- package/assets/.appweaver/scripts/python/aw-foundation.py +885 -20
- package/assets/.appweaver/scripts/python/aw-inventory.py +28 -21
- package/assets/.appweaver/scripts/python/aw-plan-coverage.py +2 -2
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +6 -6
- package/assets/.appweaver/scripts/python/aw-stack.py +676 -99
- package/assets/.appweaver/stack-profiles/angular.json +2 -1
- package/assets/.appweaver/stack-profiles/blazor-wasm.json +2 -1
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +18 -3
- package/assets/.appweaver/stack-profiles/go-chi.json +6 -1
- package/assets/.appweaver/stack-profiles/java-spring.json +14 -5
- package/assets/.appweaver/stack-profiles/nextjs.json +2 -1
- package/assets/.appweaver/stack-profiles/node-express.json +8 -2
- package/assets/.appweaver/stack-profiles/python-fastapi.json +9 -2
- package/assets/.appweaver/stack-profiles/react-vite.json +2 -1
- package/assets/.appweaver/stack-profiles/sveltekit.json +2 -1
- package/assets/.appweaver/stack-profiles/vue-vite.json +2 -1
- package/assets/.appweaver/stacks.json +40 -1
- package/assets/.appweaver/templates/constitution-ui-template.md +2 -2
- package/assets/.appweaver/templates/delta-design-template.md +7 -5
- package/assets/.appweaver/templates/design-template.md +3 -0
- package/assets/.appweaver/templates/ui-delta-design-template.md +1 -1
- package/assets/.appweaver/templates/ui-design-template.md +6 -4
- package/assets/.claude/skills/appweaver/SKILL.md +7 -46
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.rules.json +31 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.lane.json +6 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.rules.json +16 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.lane.json +6 -0
- package/assets/foundations/foundation.spec.template.txt +98 -0
- package/assets/foundations/java/Hexagonal/Hexagonal.lane.json +6 -0
- package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +8 -1
- package/assets/foundations/java/Hexagonal/unpack-foundation.sh +4 -5
- package/assets/foundations/node/NextAppRouter/NextAppRouter.spec.txt +68 -0
- package/assets/guardrails/README.md +31 -17
- package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain-rule-bindings.md +25 -13
- package/assets/guardrails/project-specific/tech-rule-bindings.md +296 -0
- package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +58 -4
- package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/auditing.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/authorization.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/cqrs.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/data-classification.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/eventing.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/persistence.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +1 -1
- package/assets/guardrails/technology/nextjs/accessibility-implementation.md +1 -1
- package/assets/guardrails/technology/nextjs/api-client.md +1 -1
- package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +1 -1
- package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +1 -1
- package/assets/guardrails/technology/nextjs/auth-session.md +1 -1
- package/assets/guardrails/technology/nextjs/client-security.md +1 -1
- package/assets/guardrails/technology/nextjs/component-architecture.md +1 -1
- package/assets/guardrails/technology/nextjs/component-conventions.md +2 -2
- package/assets/guardrails/technology/nextjs/design-system.md +1 -1
- package/assets/guardrails/technology/nextjs/error-handling.md +1 -1
- package/assets/guardrails/technology/nextjs/forms-and-validation.md +1 -1
- package/assets/guardrails/technology/nextjs/frontend-testing.md +1 -1
- package/assets/guardrails/technology/nextjs/i18n.md +1 -1
- package/assets/guardrails/technology/nextjs/observability.md +1 -1
- package/assets/guardrails/technology/nextjs/performance-budgets.md +1 -1
- package/assets/guardrails/technology/nextjs/routing-navigation.md +1 -1
- package/assets/guardrails/technology/nextjs/state-management.md +1 -1
- package/assets/guardrails/technology/nextjs/ui-constitution.md +3 -3
- package/package.json +1 -1
- package/assets/.agents/skills/appweaver-demo/SKILL.md +0 -59
- package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +0 -6
- package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -100
- package/assets/.claude/skills/appweaver-demo/SKILL.md +0 -59
- package/assets/.kilocode/agent.json +0 -28
- package/assets/.kilocode/workflows/appweaver-demo.md +0 -59
- package/assets/.kilocode/workflows/appweaver.md +0 -55
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +0 -271
- /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain/domain-requirements.md +0 -0
- /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/frontend/ui-requirements.md +0 -0
- /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/service/technical-requirements.md +0 -0
|
@@ -4,11 +4,26 @@
|
|
|
4
4
|
"title": "ASP.NET Core Web API",
|
|
5
5
|
"language": "C#",
|
|
6
6
|
"ecosystem": "dotnet",
|
|
7
|
-
"root": "
|
|
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
|
+
"*.sln",
|
|
14
|
+
"*.slnx",
|
|
15
|
+
"*.csproj"
|
|
16
|
+
],
|
|
9
17
|
"build": "dotnet build",
|
|
10
18
|
"test": "dotnet test",
|
|
11
|
-
"run": "dotnet run --project {{
|
|
19
|
+
"run": "dotnet run --project {{host}}",
|
|
20
|
+
"contract_run": "dotnet run --project {{host}} -- --environment Development --urls http://localhost:5000",
|
|
21
|
+
"contract": "http://localhost:5000/swagger/v1/swagger.json",
|
|
22
|
+
"host_patterns": [
|
|
23
|
+
"**/*.AppHost.csproj",
|
|
24
|
+
"**/*.Api.csproj",
|
|
25
|
+
"**/*.Service.csproj"
|
|
26
|
+
],
|
|
12
27
|
"detect": [
|
|
13
28
|
"*.sln",
|
|
14
29
|
"src/**/*.csproj"
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
"title": "Go + chi",
|
|
5
5
|
"language": "Go",
|
|
6
6
|
"ecosystem": "go",
|
|
7
|
-
"root": "
|
|
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,21 @@
|
|
|
4
4
|
"title": "Spring Boot",
|
|
5
5
|
"language": "Java",
|
|
6
6
|
"ecosystem": "java",
|
|
7
|
-
"root": "
|
|
8
|
-
"test_root": "src/test/java/",
|
|
7
|
+
"root": "backend/",
|
|
8
|
+
"test_root": "backend/src/test/java/",
|
|
9
9
|
"run_from": "root",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
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",
|
|
20
|
+
"contract_run": "./mvnw spring-boot:run -Dspring-boot.run.arguments=--server.port=8080",
|
|
21
|
+
"contract": "http://localhost:8080/v3/api-docs",
|
|
13
22
|
"detect": [
|
|
14
23
|
"pom.xml",
|
|
15
24
|
"build.gradle"
|
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
"title": "Express + TypeScript",
|
|
5
5
|
"language": "Node.js",
|
|
6
6
|
"ecosystem": "node",
|
|
7
|
-
"root": "
|
|
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": "
|
|
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",
|
|
@@ -1,3 +1,42 @@
|
|
|
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
|
+
"contract_run": "dotnet run --project {{host}} -- --environment Development --urls http://localhost:5000",
|
|
19
|
+
"contract": "http://localhost:5000/swagger/v1/swagger.json"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "web",
|
|
23
|
+
"kind": "frontend",
|
|
24
|
+
"profile": "nextjs",
|
|
25
|
+
"stack": "Next.js",
|
|
26
|
+
"origin": "declared",
|
|
27
|
+
"root": "frontend/",
|
|
28
|
+
"test_root": "frontend/",
|
|
29
|
+
"run_from": "root",
|
|
30
|
+
"build": "npm run build",
|
|
31
|
+
"test": "npm test",
|
|
32
|
+
"run": "npm run dev",
|
|
33
|
+
"migrate": "",
|
|
34
|
+
"client": "npx openapi-typescript {{contract}} -o lib/api/schema.d.ts"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"prototype": {
|
|
38
|
+
"root": "prototype/",
|
|
39
|
+
"run": "npm run dev --prefix prototype"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
3
42
|
}
|
|
@@ -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
|
|
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]
|
|
@@ -89,7 +89,7 @@ it realises. "Realisation only — no spec delta" for a plan-only change.]
|
|
|
89
89
|
| Section (§) | Element | Kind | Serves |
|
|
90
90
|
|---|---|---|---|
|
|
91
91
|
| Application (§2) | `[Command/Query]` + handler | use-case | US-[n] · FR-[nnn] |
|
|
92
|
-
| API (§3) | `[VERB] [/route]` | endpoint | US-[n] · FR-[nnn] |
|
|
92
|
+
| API (§3) | `[OperationId]` · `[VERB] [/route]` | endpoint | US-[n] · FR-[nnn] |
|
|
93
93
|
| Domain (§1) | `[Event]` handling / `[VO]` mapping | model realisation | BR-[nnn] · CN-[nnn] |
|
|
94
94
|
| Infrastructure (§4.2) | `I[External]` adapter | contract realisation | IC-[nnn] |
|
|
95
95
|
| Cross-cutting (§5) | [audit / retention / exposure decision] | constraint realisation | CN-[nnn] · DC-[nnn] |
|
|
@@ -118,12 +118,14 @@ realisation); new migration needed? (yes/no); any contract change other systems
|
|
|
118
118
|
What this change adds to or alters in the service's PUBLISHED surface — the only part
|
|
119
119
|
of this document the frontend lane may bind against. One row per contract; the frontend
|
|
120
120
|
delta plan cites these rather than re-deriving them. "None" when the surface is
|
|
121
|
-
unchanged, which is what a purely internal refactor should say.
|
|
121
|
+
unchanged, which is what a purely internal refactor should say. The operation id is the
|
|
122
|
+
endpoint's name in the published API document, unique across the service; an endpoint
|
|
123
|
+
the master plan already names keeps that id.
|
|
122
124
|
-->
|
|
123
125
|
|
|
124
|
-
| Contract | Change | Shape | Serves |
|
|
125
|
-
|
|
126
|
-
| `[VERB] [/route]` | added / changed | [request → response field shapes] | IC-[nnn] · FR-[nnn] |
|
|
126
|
+
| Operation id | Contract | Change | Shape | Serves |
|
|
127
|
+
|---|---|---|---|---|
|
|
128
|
+
| `[OperationId]` | `[VERB] [/route]` | added / changed | [request → response field shapes] | IC-[nnn] · FR-[nnn] |
|
|
127
129
|
|
|
128
130
|
## Other open deltas
|
|
129
131
|
|
|
@@ -254,10 +254,13 @@ text, and do not add a rule the model does not carry)*
|
|
|
254
254
|
per the constitution — adapt for gRPC/GraphQL/CLI if the stack differs), NOT as
|
|
255
255
|
controller code. Pin route, verb, auth, request/response shape, status codes, and
|
|
256
256
|
the error contract. Delegates to an Application use-case; no business logic here.
|
|
257
|
+
The OPERATION ID is the endpoint's name in the published API document, unique across
|
|
258
|
+
the service: the frontend plan cites it, and implement gives the endpoint exactly it.
|
|
257
259
|
-->
|
|
258
260
|
|
|
259
261
|
### `[VERB] [/route]` — [purpose] · Serves US-Y · FR-00X
|
|
260
262
|
|
|
263
|
+
- **Operation id**: `[OperationId]`
|
|
261
264
|
- **Auth**: [required role/scope]
|
|
262
265
|
- **Request**: `[path/query params]` + body `{ [field]: [type], … }`
|
|
263
266
|
- **Success**: `2xx` → `{ [response shape] }`
|
|
@@ -76,7 +76,7 @@ CN-/DC-/IC-) it realises. "Realisation only — no spec delta" for a plan-only c
|
|
|
76
76
|
| Navigation & Screens (§1) | `[screen]` | screen | US-[n] |
|
|
77
77
|
| Component Structure (§3) | `[component]` | component | US-[n] · FR-[nnn] |
|
|
78
78
|
| Client State (§2) | `[state]` | state | FR-[nnn] · DC-[nnn] |
|
|
79
|
-
| Contract Binding (§5) | `[VERB] [/route]` | binding | IC-[nnn] |
|
|
79
|
+
| Contract Binding (§5) | `[OperationId]` · `[VERB] [/route]` | binding | IC-[nnn] |
|
|
80
80
|
|
|
81
81
|
## MODIFIED — existing experience elements
|
|
82
82
|
|
|
@@ -196,11 +196,13 @@ a lost connection mid-flight.]
|
|
|
196
196
|
internals: no table, no handler, no persistence assumption crosses this
|
|
197
197
|
line. An interface the experience needs and the service does not offer is a
|
|
198
198
|
CONTRACT DELTA raised back to the service lane, never a workaround in the
|
|
199
|
-
client.
|
|
199
|
+
client. The OPERATION ID is the one backend-plan.md §3 gives the endpoint —
|
|
200
|
+
the name implement finds it by in the exported API document, and checks
|
|
201
|
+
before generating. `—` when no service plan names it yet, with a §8 DA-n. -->
|
|
200
202
|
|
|
201
|
-
| Screen / component | Operation | Sends (field shape) | Receives (field shape) | Failure handling | Serves |
|
|
202
|
-
|
|
203
|
-
| `[Screen]` | `[operation]` | [field: type, …] | [field: type, …] | [the §4 state it produces] | FR-[nnn] · IC-[nnn] |
|
|
203
|
+
| Screen / component | Operation id | Operation | Sends (field shape) | Receives (field shape) | Failure handling | Serves |
|
|
204
|
+
|---|---|---|---|---|---|---|
|
|
205
|
+
| `[Screen]` | `[OperationId]` | `[operation]` | [field: type, …] | [field: type, …] | [the §4 state it produces] | FR-[nnn] · IC-[nnn] |
|
|
204
206
|
|
|
205
207
|
**Write semantics**: [per mutating operation — optimistic or pessimistic, what
|
|
206
208
|
it invalidates, and how an optimistic update rolls back.]
|
|
@@ -1,55 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "appweaver"
|
|
3
|
-
description: "Parametric launcher
|
|
4
|
-
argument-hint: "<skill> [strategy] [input…] — e.g. 'select-
|
|
5
|
-
compatibility: "Requires .appweaver/orchestrator/ and
|
|
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
|
-
#
|
|
10
|
+
# AppWeaver launcher
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Read `.appweaver/orchestrator/LAUNCHER.md` and follow it exactly.
|
|
13
13
|
|
|
14
|
-
|
|
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
|
-
|
|
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,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "aw-spec-pack-lane/v1",
|
|
3
|
+
"note": "How this pack's service is started on its own to export its API document. The AppHost (the lane's run command) needs Docker for its infrastructure; the API project alone runs on the local infrastructure. Development keeps HTTPS redirection off so the document is served over http. The pack's configuration carries no ConnectionStrings:SqliteConnection, which the local infrastructure reads, so the command supplies one.",
|
|
4
|
+
"contract_run": "dotnet run --project src/AppWeaver.ModularMonolith.API -- --environment Development --urls http://localhost:5000 --ConnectionStrings:SqliteConnection \"Data Source=App_Data/app.db\"",
|
|
5
|
+
"contract": "http://localhost:5000/swagger/v1/swagger.json"
|
|
6
|
+
}
|
|
@@ -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,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "aw-spec-pack-lane/v1",
|
|
3
|
+
"note": "How this pack's service is started on its own to export its API document. The AppHost (the lane's run command) needs Docker for Postgres and Redis; the Service project alone runs on SQLite. Development keeps HTTPS redirection off so the document is served over http. The pack's configuration carries no ConnectionStrings:SqliteConnection, which the local infrastructure reads, so the command supplies one.",
|
|
4
|
+
"contract_run": "dotnet run --project src/AppWeaver.VerticalSlice.Service -- --environment Development --urls http://localhost:5000 --ConnectionStrings:SqliteConnection \"Data Source=App_Data/app.db\"",
|
|
5
|
+
"contract": "http://localhost:5000/swagger/v1/swagger.json"
|
|
6
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# kind: backend
|
|
2
|
+
# profiles: dotnet-webapi
|
|
3
|
+
# title: <one line shown in the /appweaver foundation pick list>
|
|
4
|
+
# contract-run: dotnet run --project src/<App>.Api -- --environment Development --urls http://localhost:5000
|
|
5
|
+
# contract: http://localhost:5000/swagger/v1/swagger.json
|
|
6
|
+
#
|
|
7
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
# FOUNDATION SPEC TEMPLATE — how to describe a base project for /appweaver foundation
|
|
9
|
+
#
|
|
10
|
+
# A spec is the alternative to a pack. A pack (<Name>.pack.txt) is a verified project
|
|
11
|
+
# unpacked byte-for-byte; a spec DESCRIBES the project, and an agent builds it into the
|
|
12
|
+
# lane root folder when the operator picks it. Use one where no pack ships for the
|
|
13
|
+
# stack, or where the project is easier to describe than to keep as a frozen copy.
|
|
14
|
+
#
|
|
15
|
+
# WHERE IT GOES. Copy this file to foundations/<ecosystem>/<Name>/<Name>.spec.txt —
|
|
16
|
+
# <ecosystem> is the `ecosystem` of the stack profile (.appweaver/stack-profiles/*.json:
|
|
17
|
+
# dotnet, java, node, python, go …). A directory may hold a pack, specs, or both; every
|
|
18
|
+
# *.spec.txt in it is its own entry, named after the file. It is listed for a lane only
|
|
19
|
+
# when its header admits that lane:
|
|
20
|
+
#
|
|
21
|
+
# # kind: backend | frontend (absent = backend)
|
|
22
|
+
# # profiles: stack-profile ids, comma-separated (absent = any profile of that kind
|
|
23
|
+
# in the ecosystem — say which, because `node` covers Next.js, Angular,
|
|
24
|
+
# Vue, SvelteKit and the Express backend alike)
|
|
25
|
+
# # title: the label in the pick list
|
|
26
|
+
#
|
|
27
|
+
# Three more header lines carry the API CONTRACT between the lanes. /appweaver foundation
|
|
28
|
+
# records them on the lane in .appweaver/stacks.json once the project is built, and
|
|
29
|
+
# /appweaver implement uses them to export the service's OpenAPI document and generate the
|
|
30
|
+
# frontend's client from it before it generates the frontend. A spec that leaves one out
|
|
31
|
+
# is asked for it at the end of the build; leaving the answer empty keeps the stack
|
|
32
|
+
# profile's default.
|
|
33
|
+
#
|
|
34
|
+
# # contract-run: (backend) the command that starts the API ON ITS OWN — no
|
|
35
|
+
# orchestration host, nothing it needs that is not on this machine —
|
|
36
|
+
# run in the lane root folder. <App> stands for the app name given
|
|
37
|
+
# at /appweaver foundation
|
|
38
|
+
# # contract: (backend) the URL that running API serves its OpenAPI document at
|
|
39
|
+
# # client: (frontend) the command that generates the API client from that
|
|
40
|
+
# document; {{contract}} in it stands for the document's path
|
|
41
|
+
#
|
|
42
|
+
# The header is the leading block of `#` lines; the first line that does not start with
|
|
43
|
+
# `#` ends it. Everything after this header block is the spec itself, written for the
|
|
44
|
+
# agent that builds the project — be concrete. The same shape works for a spec given at
|
|
45
|
+
# the [manual spec] prompt (as a file path, or pasted as text).
|
|
46
|
+
#
|
|
47
|
+
# WHAT THE AGENT ALREADY KNOWS, so the spec need not repeat it: the lane root folder (the
|
|
48
|
+
# WHOLE project goes inside it: build files, source and tests), its test
|
|
49
|
+
# path inside that folder, and its build command, which runs in that folder (from
|
|
50
|
+
# .appweaver/stacks.json), the project name the operator entered, and the technical rules
|
|
51
|
+
# the selected project maps under `## /aw-spec-foundation-backend` or
|
|
52
|
+
# `## /aw-spec-foundation-frontend` in its tech-rule-bindings.md. Where this spec is
|
|
53
|
+
# silent the agent follows those rules; where the two disagree the spec wins and the
|
|
54
|
+
# agent names the conflict. Paths below are relative to the lane root folder.
|
|
55
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
# <Project kind> foundation — <stack and version>
|
|
58
|
+
|
|
59
|
+
## Purpose
|
|
60
|
+
One or two sentences: what this base project is for, and what it deliberately leaves out
|
|
61
|
+
(business features come later from /appweaver implement).
|
|
62
|
+
|
|
63
|
+
## Create
|
|
64
|
+
The commands that create the project, in order, and where their output must land.
|
|
65
|
+
- e.g. `dotnet new webapi -n <ProjectName> -o src/<ProjectName>.Api`
|
|
66
|
+
- e.g. a solution file at the top of the lane root folder, referencing every project
|
|
67
|
+
|
|
68
|
+
## Packages
|
|
69
|
+
Exact packages (and versions where it matters), split by project.
|
|
70
|
+
|
|
71
|
+
## Layout
|
|
72
|
+
The folder structure the project starts with, as a tree. Name the folders feature code will
|
|
73
|
+
later go into, even when they start empty (add a .gitkeep).
|
|
74
|
+
|
|
75
|
+
## Starter files
|
|
76
|
+
Each file the base project needs beyond what the tools generate — what it contains, not
|
|
77
|
+
just its name: configuration, the composition root, a health endpoint, the error-handling
|
|
78
|
+
middleware, a sample test that proves the test project runs.
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
Settings files, environment variables, ports, connection strings (placeholders, never
|
|
82
|
+
secrets).
|
|
83
|
+
|
|
84
|
+
## API document
|
|
85
|
+
Backend: the API serves its OpenAPI document at the `# contract:` URL, and the
|
|
86
|
+
`# contract-run:` command starts it on its own on the port that URL names — over http, with
|
|
87
|
+
every setting it needs to start present in its configuration (a local database file, not a
|
|
88
|
+
container). Frontend: say which tool the `# client:` command runs, so it is installed as a
|
|
89
|
+
development dependency.
|
|
90
|
+
|
|
91
|
+
## Tests
|
|
92
|
+
The test project(s): framework, where they live (the lane's test path), and the one test that
|
|
93
|
+
must pass on a fresh scaffold.
|
|
94
|
+
|
|
95
|
+
## Done when
|
|
96
|
+
How to confirm the scaffold works — the lane's build passes, the test command passes, the app
|
|
97
|
+
starts and answers a named URL (for a backend, the `# contract:` URL, started with the
|
|
98
|
+
`# contract-run:` command).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "aw-spec-pack-lane/v1",
|
|
3
|
+
"note": "How this pack's service is started on its own to export its API document. It is one Maven module on a local H2 file database, so the Maven wrapper starts it as it is; springdoc serves the OpenAPI document at /v3/api-docs. The port is pinned so the URL below is where it answers.",
|
|
4
|
+
"contract_run": "./mvnw spring-boot:run -Dspring-boot.run.arguments=--server.port=8080",
|
|
5
|
+
"contract": "http://localhost:8080/v3/api-docs"
|
|
6
|
+
}
|
|
@@ -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
|
-
#
|
|
11
|
+
# Unpacked into --out-dir as-is: that directory is the Maven module.
|
|
12
12
|
# ============================================================
|
|
13
13
|
|
|
14
14
|
<<<DIR path=".mvn">>>
|
|
@@ -657,6 +657,13 @@ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
|
|
657
657
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
658
658
|
</dependency>
|
|
659
659
|
|
|
660
|
+
<!-- OpenAPI document at /v3/api-docs and Swagger UI at /swagger-ui.html -->
|
|
661
|
+
<dependency>
|
|
662
|
+
<groupId>org.springdoc</groupId>
|
|
663
|
+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
|
664
|
+
<version>3.1.1</version>
|
|
665
|
+
</dependency>
|
|
666
|
+
|
|
660
667
|
<dependency>
|
|
661
668
|
<groupId>org.springframework.boot</groupId>
|
|
662
669
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
|
@@ -206,11 +206,10 @@ apply_repl() {
|
|
|
206
206
|
|
|
207
207
|
# ----------------------------------------------------------- output root ------------
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
|