aw-spec-cli 0.1.8 → 0.1.9

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 (257) hide show
  1. package/assets/.appweaver/DESIGN-FORMAT.md +200 -0
  2. package/assets/.appweaver/ORCH-DIALECT.md +156 -0
  3. package/assets/.appweaver/RULE-PARTITION.md +175 -0
  4. package/assets/.appweaver/STACK-PROFILES.md +461 -0
  5. package/assets/.appweaver/ai-rules.md +180 -0
  6. package/assets/.appweaver/domain.json +1 -0
  7. package/assets/.appweaver/extensions/.registry +19 -0
  8. package/assets/.appweaver/extensions/agent-context/README.md +57 -0
  9. package/assets/.appweaver/extensions/agent-context/agent-context-config.yml +4 -0
  10. package/assets/.appweaver/extensions/agent-context/commands/aw-spec.agent-context.update.md +26 -0
  11. package/assets/.appweaver/extensions/agent-context/extension.yml +37 -0
  12. package/assets/.appweaver/extensions/agent-context/scripts/bash/update-agent-context.sh +201 -0
  13. package/assets/.appweaver/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +237 -0
  14. package/assets/.appweaver/extensions.yml +16 -0
  15. package/assets/.appweaver/feature.json +3 -0
  16. package/assets/.appweaver/init-options.json +9 -0
  17. package/assets/.appweaver/integration.json +15 -0
  18. package/assets/.appweaver/integrations/aw-spec.manifest.json +9 -0
  19. package/assets/.appweaver/interpreter/run-skill.py +1176 -0
  20. package/assets/.appweaver/memory/constitution.md +50 -0
  21. package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +6 -0
  22. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +94 -0
  23. package/assets/.appweaver/orchestrator/README.md +300 -0
  24. package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +74 -0
  25. package/assets/.appweaver/orchestrator/adapters/google_antigravity.py +74 -0
  26. package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +105 -0
  27. package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +101 -0
  28. package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +90 -0
  29. package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +126 -0
  30. package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +123 -0
  31. package/assets/.appweaver/orchestrator/orchestrator.py +1721 -0
  32. package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +40 -0
  33. package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +101 -0
  34. package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +245 -0
  35. package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +63 -0
  36. package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
  37. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +59 -0
  38. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
  39. package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +63 -0
  40. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +116 -0
  41. package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
  42. package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
  43. package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +125 -0
  44. package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +123 -0
  45. package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +294 -0
  46. package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +160 -0
  47. package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +270 -0
  48. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +934 -0
  49. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +251 -0
  50. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +265 -0
  51. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +437 -0
  52. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +197 -0
  53. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +475 -0
  54. package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
  55. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +727 -0
  56. package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +100 -0
  57. package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
  58. package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
  59. package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +386 -0
  60. package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
  61. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +462 -0
  62. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +265 -0
  63. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +253 -0
  64. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +267 -0
  65. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +287 -0
  66. package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +238 -0
  67. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1822 -0
  68. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
  69. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +194 -0
  70. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +83 -0
  71. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
  72. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +296 -0
  73. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +439 -0
  74. package/assets/.appweaver/scripts/bash/aw-inventory.sh +17 -0
  75. package/assets/.appweaver/scripts/bash/aw-parity.sh +13 -0
  76. package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +13 -0
  77. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2626 -0
  78. package/assets/.appweaver/scripts/bash/aw-xref.sh +15 -0
  79. package/assets/.appweaver/scripts/bash/common.sh +533 -0
  80. package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +17 -0
  81. package/assets/.appweaver/scripts/powershell/aw-parity.ps1 +13 -0
  82. package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +13 -0
  83. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2232 -0
  84. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +15 -0
  85. package/assets/.appweaver/scripts/python/aw-component-catalog.py +121 -0
  86. package/assets/.appweaver/scripts/python/aw-inventory.py +1180 -0
  87. package/assets/.appweaver/scripts/python/aw-parity.py +380 -0
  88. package/assets/.appweaver/scripts/python/aw-rev-constitution.py +329 -0
  89. package/assets/.appweaver/scripts/python/aw-stack.py +1251 -0
  90. package/assets/.appweaver/scripts/python/aw-xref.py +1330 -0
  91. package/assets/.appweaver/scripts/python/validate_okf.py +352 -0
  92. package/assets/.appweaver/stack-profiles/angular.json +16 -0
  93. package/assets/.appweaver/stack-profiles/blazor-wasm.json +17 -0
  94. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +15 -0
  95. package/assets/.appweaver/stack-profiles/go-chi.json +14 -0
  96. package/assets/.appweaver/stack-profiles/java-spring.json +16 -0
  97. package/assets/.appweaver/stack-profiles/nextjs.json +16 -0
  98. package/assets/.appweaver/stack-profiles/node-express.json +15 -0
  99. package/assets/.appweaver/stack-profiles/python-fastapi.json +16 -0
  100. package/assets/.appweaver/stack-profiles/react-vite.json +17 -0
  101. package/assets/.appweaver/stack-profiles/sveltekit.json +16 -0
  102. package/assets/.appweaver/stack-profiles/vue-vite.json +17 -0
  103. package/assets/.appweaver/stacks.json +3 -0
  104. package/assets/.appweaver/templates/constitution-domain-template.md +116 -0
  105. package/assets/.appweaver/templates/constitution-technical-template.md +108 -0
  106. package/assets/.appweaver/templates/constitution-ui-template.md +116 -0
  107. package/assets/.appweaver/templates/delta-design-template.md +69 -0
  108. package/assets/.appweaver/templates/delta-spec-template.md +63 -0
  109. package/assets/.appweaver/templates/design-template.md +383 -0
  110. package/assets/.appweaver/templates/okf-concept-template.md +114 -0
  111. package/assets/.appweaver/templates/parity-manifest-template.json +49 -0
  112. package/assets/.appweaver/templates/source-map-template.md +85 -0
  113. package/assets/.appweaver/templates/spec-template.md +309 -0
  114. package/assets/.appweaver/templates/ui-design-template.md +273 -0
  115. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.pack.txt +25248 -0
  116. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +5726 -0
  117. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.ps1 +145 -0
  118. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.sh +196 -0
  119. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.ps1 +157 -0
  120. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.sh +209 -0
  121. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.ps1 +126 -0
  122. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.sh +217 -0
  123. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.ps1 +129 -0
  124. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.sh +218 -0
  125. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.pack.txt +19318 -0
  126. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2833 -0
  127. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.ps1 +145 -0
  128. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.sh +196 -0
  129. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.ps1 +157 -0
  130. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.sh +209 -0
  131. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.ps1 +126 -0
  132. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.sh +217 -0
  133. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.ps1 +129 -0
  134. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.sh +218 -0
  135. package/assets/foundations/dotnet/components/Email/README.md +119 -0
  136. package/assets/foundations/dotnet/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +84 -0
  137. package/assets/foundations/dotnet/components/Email/integration.md +300 -0
  138. package/assets/foundations/dotnet/components/Jobs/README.md +113 -0
  139. package/assets/foundations/dotnet/components/Jobs/integration.md +259 -0
  140. package/assets/foundations/dotnet/components/QrGenerator/README.md +85 -0
  141. package/assets/foundations/dotnet/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +57 -0
  142. package/assets/foundations/dotnet/components/QrGenerator/integration.md +230 -0
  143. package/assets/foundations/dotnet/components/README.md +74 -0
  144. package/assets/guardrails/README.md +222 -0
  145. package/assets/guardrails/domain/healthcare/ai-rules.domain.md +34 -0
  146. package/assets/guardrails/domain/healthcare/api-versioning.domain.md +17 -0
  147. package/assets/guardrails/domain/healthcare/auditing.domain.md +97 -0
  148. package/assets/guardrails/domain/healthcare/authorization.domain.md +26 -0
  149. package/assets/guardrails/domain/healthcare/clinical-terms.md +20 -0
  150. package/assets/guardrails/domain/healthcare/coding-standards.domain.md +26 -0
  151. package/assets/guardrails/domain/healthcare/consent.md +19 -0
  152. package/assets/guardrails/domain/healthcare/cqrs.domain.md +12 -0
  153. package/assets/guardrails/domain/healthcare/data-classification.domain.md +28 -0
  154. package/assets/guardrails/domain/healthcare/dependency-policy.domain.md +11 -0
  155. package/assets/guardrails/domain/healthcare/dicom.md +15 -0
  156. package/assets/guardrails/domain/healthcare/domain-constitution.md +119 -0
  157. package/assets/guardrails/domain/healthcare/domain-driven-design.domain.md +28 -0
  158. package/assets/guardrails/domain/healthcare/eventing.domain.md +18 -0
  159. package/assets/guardrails/domain/healthcare/fhir.md +36 -0
  160. package/assets/guardrails/domain/healthcare/folder-structure.domain.md +25 -0
  161. package/assets/guardrails/domain/healthcare/hipaa.md +34 -0
  162. package/assets/guardrails/domain/healthcare/hl7.md +15 -0
  163. package/assets/guardrails/domain/healthcare/ihe-conformance.md +31 -0
  164. package/assets/guardrails/domain/healthcare/integration-terms.md +21 -0
  165. package/assets/guardrails/domain/healthcare/persistence.domain.md +20 -0
  166. package/assets/guardrails/domain/healthcare/terminology.md +30 -0
  167. package/assets/guardrails/domain/healthcare/testing.domain.md +15 -0
  168. package/assets/guardrails/domain/healthcare/ux/accessibility-standards.md +36 -0
  169. package/assets/guardrails/domain/healthcare/ux/content-design.md +32 -0
  170. package/assets/guardrails/domain/healthcare/ux/interaction-states.md +44 -0
  171. package/assets/guardrails/domain/healthcare/ux/journey-mapping.md +40 -0
  172. package/assets/guardrails/domain/healthcare/vertical-slices.domain.md +18 -0
  173. package/assets/guardrails/domain/healthcare/zero-trust.domain.md +12 -0
  174. package/assets/guardrails/domain/pharma/ai-rules.domain.md +32 -0
  175. package/assets/guardrails/domain/pharma/api-versioning.domain.md +20 -0
  176. package/assets/guardrails/domain/pharma/atc.md +22 -0
  177. package/assets/guardrails/domain/pharma/auditing.domain.md +90 -0
  178. package/assets/guardrails/domain/pharma/authorization.domain.md +25 -0
  179. package/assets/guardrails/domain/pharma/coding-standards.domain.md +28 -0
  180. package/assets/guardrails/domain/pharma/cqrs.domain.md +16 -0
  181. package/assets/guardrails/domain/pharma/data-classification.domain.md +24 -0
  182. package/assets/guardrails/domain/pharma/data-provenance.md +21 -0
  183. package/assets/guardrails/domain/pharma/dependency-policy.domain.md +11 -0
  184. package/assets/guardrails/domain/pharma/domain-constitution.md +113 -0
  185. package/assets/guardrails/domain/pharma/domain-driven-design.domain.md +36 -0
  186. package/assets/guardrails/domain/pharma/domain-requirements.sample.md +103 -0
  187. package/assets/guardrails/domain/pharma/eventing.domain.md +18 -0
  188. package/assets/guardrails/domain/pharma/fhir.md +31 -0
  189. package/assets/guardrails/domain/pharma/folder-structure.domain.md +26 -0
  190. package/assets/guardrails/domain/pharma/hl7.md +17 -0
  191. package/assets/guardrails/domain/pharma/idmp.md +26 -0
  192. package/assets/guardrails/domain/pharma/integration-terms.md +21 -0
  193. package/assets/guardrails/domain/pharma/ndc.md +28 -0
  194. package/assets/guardrails/domain/pharma/persistence.domain.md +23 -0
  195. package/assets/guardrails/domain/pharma/pharma-terms.md +27 -0
  196. package/assets/guardrails/domain/pharma/product-lifecycle.domain.md +30 -0
  197. package/assets/guardrails/domain/pharma/regulatory-compliance.md +19 -0
  198. package/assets/guardrails/domain/pharma/terminology.md +32 -0
  199. package/assets/guardrails/domain/pharma/testing.domain.md +19 -0
  200. package/assets/guardrails/domain/pharma/vertical-slices.domain.md +17 -0
  201. package/assets/guardrails/domain/pharma/zero-trust.domain.md +12 -0
  202. package/assets/guardrails/projects/dotnet-default-project/domain/domain-requirements.md +58 -0
  203. package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +113 -0
  204. package/assets/guardrails/projects/dotnet-default-project/frontend/ui-requirements.md +43 -0
  205. package/assets/guardrails/projects/dotnet-default-project/service/technical-requirements.md +40 -0
  206. package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +263 -0
  207. package/assets/guardrails/requirement-spec.txt +27 -0
  208. package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +184 -0
  209. package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +44 -0
  210. package/assets/guardrails/technology/dotnet-webapi/auditing.md +96 -0
  211. package/assets/guardrails/technology/dotnet-webapi/authorization-matrix.md +14 -0
  212. package/assets/guardrails/technology/dotnet-webapi/authorization.md +39 -0
  213. package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +54 -0
  214. package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +87 -0
  215. package/assets/guardrails/technology/dotnet-webapi/cqrs.md +63 -0
  216. package/assets/guardrails/technology/dotnet-webapi/data-classification.md +38 -0
  217. package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +40 -0
  218. package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +91 -0
  219. package/assets/guardrails/technology/dotnet-webapi/eventing.md +57 -0
  220. package/assets/guardrails/technology/dotnet-webapi/examples/api-versioning.md +75 -0
  221. package/assets/guardrails/technology/dotnet-webapi/examples/auditing.md +84 -0
  222. package/assets/guardrails/technology/dotnet-webapi/examples/authorization.md +68 -0
  223. package/assets/guardrails/technology/dotnet-webapi/examples/clean-architecture.md +37 -0
  224. package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +97 -0
  225. package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +141 -0
  226. package/assets/guardrails/technology/dotnet-webapi/examples/eventing.md +46 -0
  227. package/assets/guardrails/technology/dotnet-webapi/examples/persistence.md +207 -0
  228. package/assets/guardrails/technology/dotnet-webapi/examples/vertical-slices.md +151 -0
  229. package/assets/guardrails/technology/dotnet-webapi/examples/zero-trust.md +48 -0
  230. package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +61 -0
  231. package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +47 -0
  232. package/assets/guardrails/technology/dotnet-webapi/persistence.md +82 -0
  233. package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +162 -0
  234. package/assets/guardrails/technology/dotnet-webapi/testing.md +55 -0
  235. package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +70 -0
  236. package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +48 -0
  237. package/assets/guardrails/technology/java-spring/README.md +62 -0
  238. package/assets/guardrails/technology/nextjs/accessibility-implementation.md +56 -0
  239. package/assets/guardrails/technology/nextjs/api-client.md +56 -0
  240. package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +174 -0
  241. package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +203 -0
  242. package/assets/guardrails/technology/nextjs/auth-session.md +68 -0
  243. package/assets/guardrails/technology/nextjs/client-security.md +69 -0
  244. package/assets/guardrails/technology/nextjs/component-architecture.md +60 -0
  245. package/assets/guardrails/technology/nextjs/component-conventions.md +58 -0
  246. package/assets/guardrails/technology/nextjs/design-system.md +60 -0
  247. package/assets/guardrails/technology/nextjs/error-handling.md +72 -0
  248. package/assets/guardrails/technology/nextjs/forms-and-validation.md +75 -0
  249. package/assets/guardrails/technology/nextjs/frontend-testing.md +94 -0
  250. package/assets/guardrails/technology/nextjs/i18n.md +57 -0
  251. package/assets/guardrails/technology/nextjs/observability.md +67 -0
  252. package/assets/guardrails/technology/nextjs/performance-budgets.md +66 -0
  253. package/assets/guardrails/technology/nextjs/routing-navigation.md +52 -0
  254. package/assets/guardrails/technology/nextjs/state-management.md +70 -0
  255. package/assets/guardrails/technology/nextjs/ui-constitution.md +166 -0
  256. package/package.json +1 -1
  257. package/assets/docs/pharma-constitution.my-ref.md +0 -86
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ # aw-xref.sh — thin wrapper: delegate to the single python core.
3
+ #
4
+ # Cross-reference (OKF dependency) substrate. Logic lives ONCE in
5
+ # ../python/aw-xref.py; this wrapper exists only so the orchestrator's
6
+ # execute_script (sh:/ps1: dispatch) can invoke it. Args pass through.
7
+ #
8
+ # aw-xref.sh record --using X --design <design.md> [--origin ...] [--date YYYY-MM-DD] [--root DIR]
9
+ # aw-xref.sh list --aggregate Y [--root DIR] [--bundle knowledge]
10
+ # aw-xref.sh concept-upsert --aggregate X [--source-files a,b,c] [--description D] [--origin ...] [--root DIR]
11
+ # aw-xref.sh concept-overview --aggregate X (--text PROSE | --text-file F) [--root DIR]
12
+ # aw-xref.sh concept-paths --aggregate X | --feature-dir <dir> [--root DIR] [--bundle knowledge]
13
+ set -euo pipefail
14
+ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ exec python3 "$DIR/../python/aw-xref.py" "$@"
@@ -0,0 +1,533 @@
1
+ #!/usr/bin/env bash
2
+ # Common functions and variables for all scripts
3
+
4
+ # Find repository root by searching upward for .appweaver directory
5
+ # This is the primary marker for aw-spec projects
6
+ find_specify_root() {
7
+ local dir="${1:-$(pwd)}"
8
+ # Normalize to absolute path to prevent infinite loop with relative paths
9
+ # Use -- to handle paths starting with - (e.g., -P, -L)
10
+ dir="$(cd -- "$dir" 2>/dev/null && pwd)" || return 1
11
+ local prev_dir=""
12
+ while true; do
13
+ if [ -d "$dir/.appweaver" ]; then
14
+ echo "$dir"
15
+ return 0
16
+ fi
17
+ # Stop if we've reached filesystem root or dirname stops changing
18
+ if [ "$dir" = "/" ] || [ "$dir" = "$prev_dir" ]; then
19
+ break
20
+ fi
21
+ prev_dir="$dir"
22
+ dir="$(dirname "$dir")"
23
+ done
24
+ return 1
25
+ }
26
+
27
+ # Get repository root, prioritizing .appweaver directory
28
+ # This prevents using a parent repository when aw-spec is initialized in a subdirectory
29
+ get_repo_root() {
30
+ # First, look for .appweaver directory (aw-spec's own marker)
31
+ local specify_root
32
+ if specify_root=$(find_specify_root); then
33
+ echo "$specify_root"
34
+ return
35
+ fi
36
+
37
+ # Final fallback to script location
38
+ local script_dir="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
39
+ (cd "$script_dir/../../.." && pwd)
40
+ }
41
+
42
+ # FEATURE RESOLUTION IS SINGLE-CHANNEL: `.appweaver/feature.json`, written by
43
+ # select-feature (and adopt), read back by read_feature_json_feature_directory below.
44
+ # There is deliberately NO environment override. The retired get_feature_paths() +
45
+ # get_current_branch() pair honoured SPECIFY_FEATURE_DIRECTORY / SPECIFY_FEATURE, but
46
+ # they were dead code (zero callers) emitting the retired plan.md/tasks.md/research.md
47
+ # document set, and PowerShell never implemented either variable — so the "override"
48
+ # existed on one shell only and nothing in the pipeline could observe it. A second,
49
+ # invisible channel would also let one step diverge from the feature every OTHER step
50
+ # reads. Callers that need to act on a specific feature take an explicit `--feature-dir`
51
+ # argument, which wins over feature.json at the call site.
52
+
53
+ # Safely read .appweaver/feature.json's "feature_directory" value.
54
+ # Prints the raw value (possibly relative) to stdout, or empty string if the file
55
+ # is missing, unparseable, or does not contain the key. Always returns 0 so callers
56
+ # under `set -e` cannot be aborted by parser failure.
57
+ # Parser order: jq -> python3 -> grep/sed.
58
+ read_feature_json_feature_directory() {
59
+ local repo_root="$1"
60
+ local fj="$repo_root/.appweaver/feature.json"
61
+ [[ -f "$fj" ]] || { printf '%s' ''; return 0; }
62
+
63
+ local _fd=''
64
+ if command -v jq >/dev/null 2>&1; then
65
+ if ! _fd=$(jq -r '.feature_directory // empty' "$fj" 2>/dev/null); then
66
+ _fd=''
67
+ fi
68
+ elif command -v python3 >/dev/null 2>&1; then
69
+ # Use Python so pretty-printed/multi-line JSON still parses correctly.
70
+ if ! _fd=$(python3 -c "import json,sys; d=json.load(open(sys.argv[1])); v=d.get('feature_directory'); print(v if v else '')" "$fj" 2>/dev/null); then
71
+ _fd=''
72
+ fi
73
+ else
74
+ # Last-resort single-line grep/sed fallback. The `|| true` guards against
75
+ # grep returning 1 (no match) aborting under `set -e` / `pipefail`.
76
+ _fd=$( { grep -E '"feature_directory"[[:space:]]*:' "$fj" 2>/dev/null || true; } \
77
+ | head -n 1 \
78
+ | sed -E 's/^[^:]*:[[:space:]]*"([^"]*)".*$/\1/' )
79
+ fi
80
+
81
+ printf '%s' "$_fd"
82
+ return 0
83
+ }
84
+
85
+ # Persist a feature_directory value to .appweaver/feature.json.
86
+ # Writes only when the file is missing or the value differs from what's stored.
87
+ # Accepts the raw (possibly relative) path — callers should pass the original
88
+ # user-supplied value, not the normalized absolute path.
89
+ _persist_feature_json() {
90
+ local repo_root="$1"
91
+ local feature_dir_value="$2"
92
+ local fj="$repo_root/.appweaver/feature.json"
93
+
94
+ # Strip repo_root prefix if the value is absolute and under repo_root
95
+ if [[ "$feature_dir_value" == "$repo_root/"* ]]; then
96
+ feature_dir_value="${feature_dir_value#"$repo_root/"}"
97
+ fi
98
+
99
+ # Read current value (if any) and skip write when unchanged
100
+ local current_val
101
+ current_val=$(read_feature_json_feature_directory "$repo_root")
102
+ if [[ "$current_val" == "$feature_dir_value" ]]; then
103
+ return 0
104
+ fi
105
+
106
+ # Ensure .appweaver/ directory exists
107
+ mkdir -p "$repo_root/.appweaver"
108
+
109
+ # Write feature.json — prefer jq for safe JSON, fall back to printf
110
+ if command -v jq >/dev/null 2>&1; then
111
+ jq -cn --arg fd "$feature_dir_value" '{feature_directory:$fd}' > "$fj"
112
+ else
113
+ printf '{"feature_directory":"%s"}\n' "$(json_escape "$feature_dir_value")" > "$fj"
114
+ fi
115
+ }
116
+
117
+ # Check if jq is available for safe JSON construction
118
+ has_jq() {
119
+ command -v jq >/dev/null 2>&1
120
+ }
121
+
122
+ get_invoke_separator() {
123
+ local repo_root="${1:-$(get_repo_root)}"
124
+ if [[ "${_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT:-}" == "$repo_root" && -n "${_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE:-}" ]]; then
125
+ printf '%s\n' "$_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE"
126
+ return 0
127
+ fi
128
+
129
+ local integration_json="$repo_root/.appweaver/integration.json"
130
+ local separator="."
131
+ local parsed_with_jq=0
132
+
133
+ if [[ -f "$integration_json" ]]; then
134
+ if command -v jq >/dev/null 2>&1; then
135
+ local jq_separator
136
+ if jq_separator=$(jq -r '(.default_integration // .integration // "") as $k | if $k == "" then "." else (.integration_settings[$k].invoke_separator // ".") end' "$integration_json" 2>/dev/null); then
137
+ parsed_with_jq=1
138
+ case "$jq_separator" in
139
+ "."|"-") separator="$jq_separator" ;;
140
+ esac
141
+ fi
142
+ fi
143
+
144
+ if [[ "$parsed_with_jq" -eq 0 ]] && command -v python3 >/dev/null 2>&1; then
145
+ if separator=$(python3 - "$integration_json" <<'PY' 2>/dev/null
146
+ import json
147
+ import sys
148
+
149
+ try:
150
+ with open(sys.argv[1], encoding="utf-8") as fh:
151
+ state = json.load(fh)
152
+ key = state.get("default_integration") or state.get("integration") or ""
153
+ settings = state.get("integration_settings")
154
+ separator = "."
155
+ if isinstance(key, str) and isinstance(settings, dict):
156
+ entry = settings.get(key)
157
+ if isinstance(entry, dict) and entry.get("invoke_separator") in {".", "-"}:
158
+ separator = entry["invoke_separator"]
159
+ print(separator)
160
+ except Exception:
161
+ print(".")
162
+ PY
163
+ ); then
164
+ case "$separator" in
165
+ "."|"-") ;;
166
+ *) separator="." ;;
167
+ esac
168
+ else
169
+ separator="."
170
+ fi
171
+ fi
172
+ fi
173
+
174
+ _SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT="$repo_root"
175
+ _SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE="$separator"
176
+ printf '%s\n' "$separator"
177
+ }
178
+
179
+ format_aw-spec_command() {
180
+ local command_name="$1"
181
+ local repo_root="${2:-$(get_repo_root)}"
182
+ local separator
183
+ if [[ "${_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT:-}" == "$repo_root" && -n "${_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE:-}" ]]; then
184
+ separator="$_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE"
185
+ else
186
+ separator=$(get_invoke_separator "$repo_root")
187
+ _SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT="$repo_root"
188
+ _SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE="$separator"
189
+ fi
190
+
191
+ command_name="${command_name#/}"
192
+ command_name="${command_name#aw-spec.}"
193
+ command_name="${command_name#aw-spec-}"
194
+ command_name="${command_name//./$separator}"
195
+
196
+ printf '/aw-spec%s%s\n' "$separator" "$command_name"
197
+ }
198
+
199
+ # Escape a string for safe embedding in a JSON value (fallback when jq is unavailable).
200
+ # Handles backslash, double-quote, and JSON-required control character escapes (RFC 8259).
201
+ json_escape() {
202
+ local s="$1"
203
+ s="${s//\\/\\\\}"
204
+ s="${s//\"/\\\"}"
205
+ s="${s//$'\n'/\\n}"
206
+ s="${s//$'\t'/\\t}"
207
+ s="${s//$'\r'/\\r}"
208
+ s="${s//$'\b'/\\b}"
209
+ s="${s//$'\f'/\\f}"
210
+ # Escape any remaining U+0001-U+001F control characters as \uXXXX.
211
+ # (U+0000/NUL cannot appear in bash strings and is excluded.)
212
+ # LC_ALL=C ensures ${#s} counts bytes and ${s:$i:1} yields single bytes,
213
+ # so multi-byte UTF-8 sequences (first byte >= 0xC0) pass through intact.
214
+ local LC_ALL=C
215
+ local i char code
216
+ for (( i=0; i<${#s}; i++ )); do
217
+ char="${s:$i:1}"
218
+ printf -v code '%d' "'$char" 2>/dev/null || code=256
219
+ if (( code >= 1 && code <= 31 )); then
220
+ printf '\\u%04x' "$code"
221
+ else
222
+ printf '%s' "$char"
223
+ fi
224
+ done
225
+ }
226
+
227
+ check_file() { [[ -f "$1" ]] && echo " ✓ $2" || echo " ✗ $2"; }
228
+ check_dir() { [[ -d "$1" && -n $(ls -A "$1" 2>/dev/null) ]] && echo " ✓ $2" || echo " ✗ $2"; }
229
+
230
+ # Resolve a template name to a file path using the priority stack:
231
+ # 1. .appweaver/templates/overrides/
232
+ # 2. .appweaver/presets/<preset-id>/templates/ (sorted by priority from .registry)
233
+ # 3. .appweaver/extensions/<ext-id>/templates/
234
+ # 4. .appweaver/templates/ (core)
235
+ resolve_template() {
236
+ local template_name="$1"
237
+ local repo_root="$2"
238
+ local base="$repo_root/.appweaver/templates"
239
+
240
+ # Priority 1: Project overrides
241
+ local override="$base/overrides/${template_name}.md"
242
+ [ -f "$override" ] && echo "$override" && return 0
243
+
244
+ # Priority 2: Installed presets (sorted by priority from .registry)
245
+ local presets_dir="$repo_root/.appweaver/presets"
246
+ if [ -d "$presets_dir" ]; then
247
+ local registry_file="$presets_dir/.registry"
248
+ if [ -f "$registry_file" ] && command -v python3 >/dev/null 2>&1; then
249
+ # Read preset IDs sorted by priority (lower number = higher precedence).
250
+ # The python3 call is wrapped in an if-condition so that set -e does not
251
+ # abort the function when python3 exits non-zero (e.g. invalid JSON).
252
+ local sorted_presets=""
253
+ if sorted_presets=$(AW_SPEC_REGISTRY="$registry_file" python3 -c "
254
+ import json, sys, os
255
+ try:
256
+ with open(os.environ['AW_SPEC_REGISTRY']) as f:
257
+ data = json.load(f)
258
+ presets = data.get('presets', {})
259
+ for pid, meta in sorted(presets.items(), key=lambda x: x[1].get('priority', 10) if isinstance(x[1], dict) else 10):
260
+ if isinstance(meta, dict) and meta.get('enabled', True) is not False:
261
+ print(pid)
262
+ except Exception:
263
+ sys.exit(1)
264
+ " 2>/dev/null); then
265
+ if [ -n "$sorted_presets" ]; then
266
+ # python3 succeeded and returned preset IDs — search in priority order
267
+ while IFS= read -r preset_id; do
268
+ local candidate="$presets_dir/$preset_id/templates/${template_name}.md"
269
+ [ -f "$candidate" ] && echo "$candidate" && return 0
270
+ done <<< "$sorted_presets"
271
+ fi
272
+ # python3 succeeded but registry has no presets — nothing to search
273
+ else
274
+ # python3 failed (missing, or registry parse error) — fall back to unordered directory scan
275
+ for preset in "$presets_dir"/*/; do
276
+ [ -d "$preset" ] || continue
277
+ local candidate="$preset/templates/${template_name}.md"
278
+ [ -f "$candidate" ] && echo "$candidate" && return 0
279
+ done
280
+ fi
281
+ else
282
+ # Fallback: alphabetical directory order (no python3 available)
283
+ for preset in "$presets_dir"/*/; do
284
+ [ -d "$preset" ] || continue
285
+ local candidate="$preset/templates/${template_name}.md"
286
+ [ -f "$candidate" ] && echo "$candidate" && return 0
287
+ done
288
+ fi
289
+ fi
290
+
291
+ # Priority 3: Extension-provided templates
292
+ local ext_dir="$repo_root/.appweaver/extensions"
293
+ if [ -d "$ext_dir" ]; then
294
+ for ext in "$ext_dir"/*/; do
295
+ [ -d "$ext" ] || continue
296
+ # Skip hidden directories (e.g. .backup, .cache)
297
+ case "$(basename "$ext")" in .*) continue;; esac
298
+ local candidate="$ext/templates/${template_name}.md"
299
+ [ -f "$candidate" ] && echo "$candidate" && return 0
300
+ done
301
+ fi
302
+
303
+ # Priority 4: Core templates
304
+ local core="$base/${template_name}.md"
305
+ [ -f "$core" ] && echo "$core" && return 0
306
+
307
+ # Template not found in any location.
308
+ # Return 1 so callers can distinguish "not found" from "found".
309
+ # Callers running under set -e should use: TEMPLATE=$(resolve_template ...) || true
310
+ return 1
311
+ }
312
+
313
+ # Resolve a template name to composed content using composition strategies.
314
+ # Reads strategy metadata from preset manifests and composes content
315
+ # from multiple layers using prepend, append, or wrap strategies.
316
+ #
317
+ # Usage: CONTENT=$(resolve_template_content "template-name" "$REPO_ROOT")
318
+ # Returns composed content string on stdout; exit code 1 if not found.
319
+ resolve_template_content() {
320
+ local template_name="$1"
321
+ local repo_root="$2"
322
+ local base="$repo_root/.appweaver/templates"
323
+
324
+ # Collect all layers (highest priority first)
325
+ local -a layer_paths=()
326
+ local -a layer_strategies=()
327
+
328
+ # Priority 1: Project overrides (always "replace")
329
+ local override="$base/overrides/${template_name}.md"
330
+ if [ -f "$override" ]; then
331
+ layer_paths+=("$override")
332
+ layer_strategies+=("replace")
333
+ fi
334
+
335
+ # Priority 2: Installed presets (sorted by priority from .registry)
336
+ local presets_dir="$repo_root/.appweaver/presets"
337
+ if [ -d "$presets_dir" ]; then
338
+ local registry_file="$presets_dir/.registry"
339
+ local sorted_presets=""
340
+ if [ -f "$registry_file" ] && command -v python3 >/dev/null 2>&1; then
341
+ if sorted_presets=$(AW_SPEC_REGISTRY="$registry_file" python3 -c "
342
+ import json, sys, os
343
+ try:
344
+ with open(os.environ['AW_SPEC_REGISTRY']) as f:
345
+ data = json.load(f)
346
+ presets = data.get('presets', {})
347
+ for pid, meta in sorted(presets.items(), key=lambda x: x[1].get('priority', 10) if isinstance(x[1], dict) else 10):
348
+ if isinstance(meta, dict) and meta.get('enabled', True) is not False:
349
+ print(pid)
350
+ except Exception:
351
+ sys.exit(1)
352
+ " 2>/dev/null); then
353
+ if [ -n "$sorted_presets" ]; then
354
+ local yaml_warned=false
355
+ while IFS= read -r preset_id; do
356
+ # Read strategy and file path from preset manifest
357
+ local strategy="replace"
358
+ local manifest_file=""
359
+ local manifest="$presets_dir/$preset_id/preset.yml"
360
+ if [ -f "$manifest" ] && command -v python3 >/dev/null 2>&1; then
361
+ # Requires PyYAML; falls back to replace/convention if unavailable
362
+ local result
363
+ local py_stderr
364
+ py_stderr=$(mktemp)
365
+ result=$(AW_SPEC_MANIFEST="$manifest" AW_SPEC_TMPL="$template_name" python3 -c "
366
+ import sys, os
367
+ try:
368
+ import yaml
369
+ except ImportError:
370
+ print('yaml_missing', file=sys.stderr)
371
+ print('replace\t')
372
+ sys.exit(0)
373
+ try:
374
+ with open(os.environ['AW_SPEC_MANIFEST']) as f:
375
+ data = yaml.safe_load(f)
376
+ for t in data.get('provides', {}).get('templates', []):
377
+ if t.get('name') == os.environ['AW_SPEC_TMPL'] and t.get('type', 'template') == 'template':
378
+ print(t.get('strategy', 'replace') + '\t' + t.get('file', ''))
379
+ sys.exit(0)
380
+ print('replace\t')
381
+ except Exception:
382
+ print('replace\t')
383
+ " 2>"$py_stderr")
384
+ local parse_status=$?
385
+ if [ $parse_status -eq 0 ] && [ -n "$result" ]; then
386
+ IFS=$'\t' read -r strategy manifest_file <<< "$result"
387
+ strategy=$(printf '%s' "$strategy" | tr '[:upper:]' '[:lower:]')
388
+ fi
389
+ if [ "$yaml_warned" = false ] && grep -q 'yaml_missing' "$py_stderr" 2>/dev/null; then
390
+ echo "Warning: PyYAML not available; composition strategies may be ignored" >&2
391
+ yaml_warned=true
392
+ fi
393
+ rm -f "$py_stderr"
394
+ fi
395
+ # Try manifest file path first, then convention path
396
+ local candidate=""
397
+ if [ -n "$manifest_file" ]; then
398
+ # Reject absolute paths and parent traversal
399
+ case "$manifest_file" in
400
+ /*|*../*|../*) manifest_file="" ;;
401
+ esac
402
+ fi
403
+ if [ -n "$manifest_file" ]; then
404
+ local mf="$presets_dir/$preset_id/$manifest_file"
405
+ [ -f "$mf" ] && candidate="$mf"
406
+ fi
407
+ if [ -z "$candidate" ]; then
408
+ local cf="$presets_dir/$preset_id/templates/${template_name}.md"
409
+ [ -f "$cf" ] && candidate="$cf"
410
+ fi
411
+ if [ -n "$candidate" ]; then
412
+ layer_paths+=("$candidate")
413
+ layer_strategies+=("$strategy")
414
+ fi
415
+ done <<< "$sorted_presets"
416
+ fi
417
+ else
418
+ # python3 failed — fall back to unordered directory scan (replace only)
419
+ for preset in "$presets_dir"/*/; do
420
+ [ -d "$preset" ] || continue
421
+ local candidate="$preset/templates/${template_name}.md"
422
+ if [ -f "$candidate" ]; then
423
+ layer_paths+=("$candidate")
424
+ layer_strategies+=("replace")
425
+ fi
426
+ done
427
+ fi
428
+ else
429
+ # No python3 or registry — fall back to unordered directory scan (replace only)
430
+ for preset in "$presets_dir"/*/; do
431
+ [ -d "$preset" ] || continue
432
+ local candidate="$preset/templates/${template_name}.md"
433
+ if [ -f "$candidate" ]; then
434
+ layer_paths+=("$candidate")
435
+ layer_strategies+=("replace")
436
+ fi
437
+ done
438
+ fi
439
+ fi
440
+
441
+ # Priority 3: Extension-provided templates (always "replace")
442
+ local ext_dir="$repo_root/.appweaver/extensions"
443
+ if [ -d "$ext_dir" ]; then
444
+ for ext in "$ext_dir"/*/; do
445
+ [ -d "$ext" ] || continue
446
+ case "$(basename "$ext")" in .*) continue;; esac
447
+ local candidate="$ext/templates/${template_name}.md"
448
+ if [ -f "$candidate" ]; then
449
+ layer_paths+=("$candidate")
450
+ layer_strategies+=("replace")
451
+ fi
452
+ done
453
+ fi
454
+
455
+ # Priority 4: Core templates (always "replace")
456
+ local core="$base/${template_name}.md"
457
+ if [ -f "$core" ]; then
458
+ layer_paths+=("$core")
459
+ layer_strategies+=("replace")
460
+ fi
461
+
462
+ local count=${#layer_paths[@]}
463
+ [ "$count" -eq 0 ] && return 1
464
+
465
+ # Check if any layer uses a non-replace strategy
466
+ local has_composition=false
467
+ for s in "${layer_strategies[@]}"; do
468
+ [ "$s" != "replace" ] && has_composition=true && break
469
+ done
470
+
471
+ # If the top (highest-priority) layer is replace, it wins entirely —
472
+ # lower layers are irrelevant regardless of their strategies.
473
+ if [ "${layer_strategies[0]}" = "replace" ]; then
474
+ cat "${layer_paths[0]}"
475
+ return 0
476
+ fi
477
+
478
+ if [ "$has_composition" = false ]; then
479
+ cat "${layer_paths[0]}"
480
+ return 0
481
+ fi
482
+
483
+ # Find the effective base: scan from highest priority (index 0) downward
484
+ # to find the nearest replace layer. Only compose layers above that base.
485
+ local base_idx=-1
486
+ local i
487
+ for (( i=0; i<count; i++ )); do
488
+ if [ "${layer_strategies[$i]}" = "replace" ]; then
489
+ base_idx=$i
490
+ break
491
+ fi
492
+ done
493
+
494
+ if [ $base_idx -lt 0 ]; then
495
+ return 1 # no base layer found
496
+ fi
497
+
498
+ # Read the base content; compose layers above the base (higher priority)
499
+ local content
500
+ content=$(cat "${layer_paths[$base_idx]}"; printf x)
501
+ content="${content%x}"
502
+
503
+ for (( i=base_idx-1; i>=0; i-- )); do
504
+ local path="${layer_paths[$i]}"
505
+ local strat="${layer_strategies[$i]}"
506
+ local layer_content
507
+ # Preserve trailing newlines
508
+ layer_content=$(cat "$path"; printf x)
509
+ layer_content="${layer_content%x}"
510
+
511
+ case "$strat" in
512
+ replace) content="$layer_content" ;;
513
+ prepend) content="$(printf '%s\n\n%s' "$layer_content" "$content")" ;;
514
+ append) content="$(printf '%s\n\n%s' "$content" "$layer_content")" ;;
515
+ wrap)
516
+ case "$layer_content" in
517
+ *'{CORE_TEMPLATE}'*) ;;
518
+ *) echo "Error: wrap strategy missing {CORE_TEMPLATE} placeholder" >&2; return 1 ;;
519
+ esac
520
+ while [[ "$layer_content" == *'{CORE_TEMPLATE}'* ]]; do
521
+ local before="${layer_content%%\{CORE_TEMPLATE\}*}"
522
+ local after="${layer_content#*\{CORE_TEMPLATE\}}"
523
+ layer_content="${before}${content}${after}"
524
+ done
525
+ content="$layer_content"
526
+ ;;
527
+ *) echo "Error: unknown strategy '$strat'" >&2; return 1 ;;
528
+ esac
529
+ done
530
+
531
+ printf '%s' "$content"
532
+ return 0
533
+ }
@@ -0,0 +1,17 @@
1
+ # aw-inventory.ps1 — thin wrapper: delegate to the single python core.
2
+ #
3
+ # The brownfield inventory logic lives ONCE in ../python/aw-inventory.py (a
4
+ # faithful cross-platform port of Reference/okf-inventory.sh + aggregate-root
5
+ # signals). This wrapper exists only so the orchestrator's execute_script,
6
+ # which dispatches sh:/ps1: variants, can invoke it. All args (subcommand +
7
+ # options) pass straight through.
8
+ #
9
+ # aw-inventory.ps1 scan [--root <dir>] [--out <path>] [--bundle <dir>] [--config <yml>]
10
+ # [--service-root <p>] [--ui-root <p>] (the declared lane paths:
11
+ # backend signals come from outside the UI subtree, frontend
12
+ # signals from inside it, so neither carries the other's files)
13
+ # aw-inventory.ps1 validate --bundle <dir> [--repo-root <dir>]
14
+ $ErrorActionPreference = "Stop"
15
+ $core = Join-Path $PSScriptRoot "..\python\aw-inventory.py"
16
+ & python3 $core @args
17
+ exit $LASTEXITCODE
@@ -0,0 +1,13 @@
1
+ # aw-parity.ps1 — thin wrapper: delegate to the single python core.
2
+ #
3
+ # Brownfield PARITY runner (the cutover gate). Logic lives ONCE in
4
+ # ../python/aw-parity.py; this wrapper exists only so the orchestrator's
5
+ # execute_script (sh:/ps1: dispatch) can invoke it. All args pass through.
6
+ #
7
+ # aw-parity.ps1 scaffold --feature-dir <dir>
8
+ # aw-parity.ps1 check --manifest <path>
9
+ # aw-parity.ps1 run --manifest <path> [--out <report.md>]
10
+ $ErrorActionPreference = "Stop"
11
+ $core = Join-Path $PSScriptRoot "..\python\aw-parity.py"
12
+ & python3 $core @args
13
+ exit $LASTEXITCODE
@@ -0,0 +1,13 @@
1
+ # aw-rev-constitution.ps1 — thin wrapper: delegate to the single python core.
2
+ #
3
+ # Brownfield GOVERN-BACKWARD substrate, driven by `/appweaver onboard` (the
4
+ # standalone rev-constitution workflow is RETIRED). Logic lives
5
+ # ONCE in ..\python\aw-rev-constitution.py; this wrapper exists only so the
6
+ # orchestrator's execute_script (sh:/ps1: dispatch) can invoke it. Args pass through.
7
+ #
8
+ # aw-rev-constitution.ps1 list-adopted [--root <dir>] [--specs <dir>] [--bundle <dir>]
9
+ # aw-rev-constitution.ps1 project-setup --name <domain> [--fallback <name>] [--root <dir>]
10
+ $ErrorActionPreference = "Stop"
11
+ $core = Join-Path $PSScriptRoot "..\python\aw-rev-constitution.py"
12
+ & python3 $core @args
13
+ exit $LASTEXITCODE