aw-spec-cli 0.1.4 → 0.1.6

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 (225) hide show
  1. package/assets/.agents/agent.json +28 -0
  2. package/assets/.agents/skills/appweaver/SKILL.md +56 -0
  3. package/assets/.agents/skills/appweaver-demo/SKILL.md +59 -0
  4. package/assets/.claude/agent.json +27 -0
  5. package/assets/.claude/skills/appweaver/SKILL.md +55 -0
  6. package/assets/.claude/skills/appweaver-demo/SKILL.md +59 -0
  7. package/assets/.kilocode/agent.json +28 -0
  8. package/assets/.kilocode/workflows/appweaver-demo.md +59 -0
  9. package/assets/.kilocode/workflows/appweaver.md +55 -0
  10. package/dist/commands/init.d.ts.map +1 -1
  11. package/dist/commands/init.js +7 -54
  12. package/dist/commands/init.js.map +1 -1
  13. package/dist/index.js +0 -2
  14. package/dist/index.js.map +1 -1
  15. package/package.json +1 -1
  16. package/assets/.agents/skills/aw-spec-addcomponent/SKILL.md +0 -129
  17. package/assets/.agents/skills/aw-spec-agent-context-update/SKILL.md +0 -31
  18. package/assets/.agents/skills/aw-spec-analyze/SKILL.md +0 -296
  19. package/assets/.agents/skills/aw-spec-checklist/SKILL.md +0 -374
  20. package/assets/.agents/skills/aw-spec-clarify/SKILL.md +0 -320
  21. package/assets/.agents/skills/aw-spec-constitution/SKILL.md +0 -194
  22. package/assets/.agents/skills/aw-spec-fast-implement/SKILL.md +0 -268
  23. package/assets/.agents/skills/aw-spec-foundation/SKILL.md +0 -358
  24. package/assets/.agents/skills/aw-spec-implement/SKILL.md +0 -279
  25. package/assets/.agents/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
  26. package/assets/.agents/skills/aw-spec-plan/SKILL.md +0 -221
  27. package/assets/.agents/skills/aw-spec-select-domain/SKILL.md +0 -73
  28. package/assets/.agents/skills/aw-spec-specify/SKILL.md +0 -382
  29. package/assets/.agents/skills/aw-spec-tasks/SKILL.md +0 -259
  30. package/assets/.agents/skills/aw-spec-taskstoissues/SKILL.md +0 -107
  31. package/assets/.aw-spec/domain.json +0 -3
  32. package/assets/.aw-spec/extensions/.registry +0 -19
  33. package/assets/.aw-spec/extensions/agent-context/README.md +0 -57
  34. package/assets/.aw-spec/extensions/agent-context/agent-context-config.yml +0 -4
  35. package/assets/.aw-spec/extensions/agent-context/commands/aw-spec.agent-context.update.md +0 -26
  36. package/assets/.aw-spec/extensions/agent-context/extension.yml +0 -34
  37. package/assets/.aw-spec/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -201
  38. package/assets/.aw-spec/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -237
  39. package/assets/.aw-spec/extensions.yml +0 -23
  40. package/assets/.aw-spec/feature.json +0 -3
  41. package/assets/.aw-spec/init-options.json +0 -9
  42. package/assets/.aw-spec/integration.json +0 -15
  43. package/assets/.aw-spec/integrations/aw-spec.manifest.json +0 -17
  44. package/assets/.aw-spec/integrations/claude.manifest.json +0 -17
  45. package/assets/.aw-spec/memory/constitution.md +0 -50
  46. package/assets/.aw-spec/scripts/bash/check-prerequisites.sh +0 -189
  47. package/assets/.aw-spec/scripts/bash/common.sh +0 -582
  48. package/assets/.aw-spec/scripts/bash/create-new-feature.sh +0 -299
  49. package/assets/.aw-spec/scripts/bash/setup-plan.sh +0 -84
  50. package/assets/.aw-spec/scripts/bash/setup-tasks.sh +0 -91
  51. package/assets/.aw-spec/templates/checklist-template.md +0 -40
  52. package/assets/.aw-spec/templates/constitution-template.md +0 -57
  53. package/assets/.aw-spec/templates/plan-template.md +0 -113
  54. package/assets/.aw-spec/templates/spec-template.md +0 -131
  55. package/assets/.aw-spec/templates/tasks-template.md +0 -252
  56. package/assets/.aw-spec/workflows/aw-spec/workflow.yml +0 -77
  57. package/assets/.aw-spec/workflows/workflow-registry.json +0 -13
  58. package/assets/.claude/skills/aw-spec-addcomponent/SKILL.md +0 -129
  59. package/assets/.claude/skills/aw-spec-agent-context-update/SKILL.md +0 -31
  60. package/assets/.claude/skills/aw-spec-analyze/SKILL.md +0 -296
  61. package/assets/.claude/skills/aw-spec-checklist/SKILL.md +0 -374
  62. package/assets/.claude/skills/aw-spec-clarify/SKILL.md +0 -320
  63. package/assets/.claude/skills/aw-spec-constitution/SKILL.md +0 -194
  64. package/assets/.claude/skills/aw-spec-fast-implement/SKILL.md +0 -268
  65. package/assets/.claude/skills/aw-spec-foundation/SKILL.md +0 -358
  66. package/assets/.claude/skills/aw-spec-implement/SKILL.md +0 -279
  67. package/assets/.claude/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
  68. package/assets/.claude/skills/aw-spec-plan/SKILL.md +0 -221
  69. package/assets/.claude/skills/aw-spec-select-domain/SKILL.md +0 -73
  70. package/assets/.claude/skills/aw-spec-specify/SKILL.md +0 -382
  71. package/assets/.claude/skills/aw-spec-tasks/SKILL.md +0 -259
  72. package/assets/.claude/skills/aw-spec-taskstoissues/SKILL.md +0 -107
  73. package/assets/.kilocode/rules/specify-rules.md +0 -4
  74. package/assets/.kilocode/workflows/aw-spec-addcomponent.md +0 -129
  75. package/assets/.kilocode/workflows/aw-spec-agent-context.update.md +0 -31
  76. package/assets/.kilocode/workflows/aw-spec-analyze.md +0 -296
  77. package/assets/.kilocode/workflows/aw-spec-checklist.md +0 -374
  78. package/assets/.kilocode/workflows/aw-spec-clarify.md +0 -320
  79. package/assets/.kilocode/workflows/aw-spec-constitution.md +0 -194
  80. package/assets/.kilocode/workflows/aw-spec-fast-implement.md +0 -263
  81. package/assets/.kilocode/workflows/aw-spec-foundation.md +0 -358
  82. package/assets/.kilocode/workflows/aw-spec-implement.md +0 -279
  83. package/assets/.kilocode/workflows/aw-spec-minimal-implementation.md +0 -204
  84. package/assets/.kilocode/workflows/aw-spec-plan.md +0 -221
  85. package/assets/.kilocode/workflows/aw-spec-select-domain.md +0 -73
  86. package/assets/.kilocode/workflows/aw-spec-specify.md +0 -382
  87. package/assets/.kilocode/workflows/aw-spec-tasks.md +0 -259
  88. package/assets/.kilocode/workflows/aw-spec-taskstoissues.md +0 -107
  89. package/assets/docs/ModularMonolith/ModularMonolith.Reference.pack.txt +0 -25248
  90. package/assets/docs/ModularMonolith/ModularMonolith.pack.txt +0 -5726
  91. package/assets/docs/ModularMonolith/pack-foundation.ps1 +0 -145
  92. package/assets/docs/ModularMonolith/pack-foundation.sh +0 -196
  93. package/assets/docs/ModularMonolith/pack-reference-foundation.ps1 +0 -157
  94. package/assets/docs/ModularMonolith/pack-reference-foundation.sh +0 -209
  95. package/assets/docs/ModularMonolith/unpack-foundation.ps1 +0 -126
  96. package/assets/docs/ModularMonolith/unpack-foundation.sh +0 -217
  97. package/assets/docs/ModularMonolith/unpack-reference-foundation.ps1 +0 -129
  98. package/assets/docs/ModularMonolith/unpack-reference-foundation.sh +0 -218
  99. package/assets/docs/README.md +0 -106
  100. package/assets/docs/UI.Visualization/PACKAGING.md +0 -191
  101. package/assets/docs/UI.Visualization/UI.Visualization.Reference.pack.txt +0 -11768
  102. package/assets/docs/UI.Visualization/UI.Visualization.pack.txt +0 -11214
  103. package/assets/docs/UI.Visualization/pack-foundation.ps1 +0 -165
  104. package/assets/docs/UI.Visualization/pack-foundation.sh +0 -206
  105. package/assets/docs/UI.Visualization/pack-reference-foundation.ps1 +0 -159
  106. package/assets/docs/UI.Visualization/pack-reference-foundation.sh +0 -205
  107. package/assets/docs/UI.Visualization/unpack-foundation.ps1 +0 -126
  108. package/assets/docs/UI.Visualization/unpack-foundation.sh +0 -217
  109. package/assets/docs/UI.Visualization/unpack-reference-foundation.ps1 +0 -129
  110. package/assets/docs/UI.Visualization/unpack-reference-foundation.sh +0 -218
  111. package/assets/docs/VerticalSlice/PACKAGING.md +0 -185
  112. package/assets/docs/VerticalSlice/VerticalSlice.Reference.pack.txt +0 -19318
  113. package/assets/docs/VerticalSlice/VerticalSlice.pack.txt +0 -2833
  114. package/assets/docs/VerticalSlice/pack-foundation.ps1 +0 -145
  115. package/assets/docs/VerticalSlice/pack-foundation.sh +0 -196
  116. package/assets/docs/VerticalSlice/pack-reference-foundation.ps1 +0 -157
  117. package/assets/docs/VerticalSlice/pack-reference-foundation.sh +0 -209
  118. package/assets/docs/VerticalSlice/unpack-foundation.ps1 +0 -126
  119. package/assets/docs/VerticalSlice/unpack-foundation.sh +0 -217
  120. package/assets/docs/VerticalSlice/unpack-reference-foundation.ps1 +0 -129
  121. package/assets/docs/VerticalSlice/unpack-reference-foundation.sh +0 -218
  122. package/assets/docs/architecture/clean-architecture.md +0 -71
  123. package/assets/docs/architecture/cqrs.md +0 -141
  124. package/assets/docs/architecture/eventing.md +0 -83
  125. package/assets/docs/architecture/folder-structure.md +0 -61
  126. package/assets/docs/architecture/modular-monolith.md +0 -47
  127. package/assets/docs/architecture/persistence.md +0 -269
  128. package/assets/docs/architecture/testing.md +0 -55
  129. package/assets/docs/architecture/vertical-slices.md +0 -201
  130. package/assets/docs/command.txt +0 -295
  131. package/assets/docs/components/Email/README.md +0 -119
  132. package/assets/docs/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +0 -84
  133. package/assets/docs/components/Email/integration.md +0 -300
  134. package/assets/docs/components/Jobs/README.md +0 -113
  135. package/assets/docs/components/Jobs/integration.md +0 -259
  136. package/assets/docs/components/QrGenerator/README.md +0 -85
  137. package/assets/docs/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +0 -57
  138. package/assets/docs/components/QrGenerator/integration.md +0 -230
  139. package/assets/docs/components/README.md +0 -74
  140. package/assets/docs/domain/domain-driven-design.md +0 -212
  141. package/assets/docs/domainspecs/UIVisualization/chart-bubble.md +0 -70
  142. package/assets/docs/domainspecs/UIVisualization/chart-dimred.md +0 -58
  143. package/assets/docs/domainspecs/UIVisualization/chart-heatmap.md +0 -62
  144. package/assets/docs/domainspecs/UIVisualization/chart-network.md +0 -69
  145. package/assets/docs/domainspecs/UIVisualization/chart-parallel.md +0 -75
  146. package/assets/docs/domainspecs/UIVisualization/chart-scurve.md +0 -66
  147. package/assets/docs/domainspecs/UIVisualization/chart-survival.md +0 -69
  148. package/assets/docs/domainspecs/UIVisualization/chart-trellis.md +0 -68
  149. package/assets/docs/domainspecs/UIVisualization/chart-violin.md +0 -61
  150. package/assets/docs/domainspecs/UIVisualization/chart-volcano.md +0 -63
  151. package/assets/docs/domainspecs/UIVisualization/charting-standards.domain.md +0 -80
  152. package/assets/docs/domainspecs/UIVisualization/clean-architecture.domain.md +0 -87
  153. package/assets/docs/domainspecs/UIVisualization/coding-standards.domain.md +0 -47
  154. package/assets/docs/domainspecs/UIVisualization/comandrulemap.md +0 -130
  155. package/assets/docs/domainspecs/UIVisualization/component-contracts.domain.md +0 -67
  156. package/assets/docs/domainspecs/UIVisualization/data-source.domain.md +0 -68
  157. package/assets/docs/domainspecs/UIVisualization/domain-requirements.md +0 -110
  158. package/assets/docs/domainspecs/UIVisualization/folder-structure.domain.md +0 -55
  159. package/assets/docs/domainspecs/UIVisualization/state-management.domain.md +0 -67
  160. package/assets/docs/domainspecs/UIVisualization/testing.domain.md +0 -52
  161. package/assets/docs/domainspecs/UIVisualization/ui-viz-terms.md +0 -39
  162. package/assets/docs/domainspecs/healthcare/ai-rules.domain.md +0 -34
  163. package/assets/docs/domainspecs/healthcare/api-versioning.domain.md +0 -17
  164. package/assets/docs/domainspecs/healthcare/auditing.domain.md +0 -29
  165. package/assets/docs/domainspecs/healthcare/authorization.domain.md +0 -26
  166. package/assets/docs/domainspecs/healthcare/clinical-terms.md +0 -20
  167. package/assets/docs/domainspecs/healthcare/coding-standards.domain.md +0 -26
  168. package/assets/docs/domainspecs/healthcare/comandrulemap.md +0 -166
  169. package/assets/docs/domainspecs/healthcare/consent.md +0 -19
  170. package/assets/docs/domainspecs/healthcare/cqrs.domain.md +0 -12
  171. package/assets/docs/domainspecs/healthcare/data-classification.domain.md +0 -28
  172. package/assets/docs/domainspecs/healthcare/dependency-policy.domain.md +0 -11
  173. package/assets/docs/domainspecs/healthcare/dicom.md +0 -15
  174. package/assets/docs/domainspecs/healthcare/domain-driven-design.domain.md +0 -28
  175. package/assets/docs/domainspecs/healthcare/domain-requirements.md +0 -55
  176. package/assets/docs/domainspecs/healthcare/eventing.domain.md +0 -18
  177. package/assets/docs/domainspecs/healthcare/fhir.md +0 -36
  178. package/assets/docs/domainspecs/healthcare/folder-structure.domain.md +0 -23
  179. package/assets/docs/domainspecs/healthcare/hipaa.md +0 -34
  180. package/assets/docs/domainspecs/healthcare/hl7.md +0 -15
  181. package/assets/docs/domainspecs/healthcare/integration-terms.md +0 -21
  182. package/assets/docs/domainspecs/healthcare/persistence.domain.md +0 -20
  183. package/assets/docs/domainspecs/healthcare/terminology.md +0 -30
  184. package/assets/docs/domainspecs/healthcare/testing.domain.md +0 -15
  185. package/assets/docs/domainspecs/healthcare/vertical-slices.domain.md +0 -18
  186. package/assets/docs/domainspecs/healthcare/zero-trust.domain.md +0 -12
  187. package/assets/docs/domainspecs/pharma/ai-rules.domain.md +0 -32
  188. package/assets/docs/domainspecs/pharma/api-versioning.domain.md +0 -20
  189. package/assets/docs/domainspecs/pharma/atc.md +0 -22
  190. package/assets/docs/domainspecs/pharma/auditing.domain.md +0 -26
  191. package/assets/docs/domainspecs/pharma/authorization.domain.md +0 -25
  192. package/assets/docs/domainspecs/pharma/coding-standards.domain.md +0 -28
  193. package/assets/docs/domainspecs/pharma/comandrulemap.md +0 -186
  194. package/assets/docs/domainspecs/pharma/cqrs.domain.md +0 -16
  195. package/assets/docs/domainspecs/pharma/data-classification.domain.md +0 -24
  196. package/assets/docs/domainspecs/pharma/data-provenance.md +0 -21
  197. package/assets/docs/domainspecs/pharma/dependency-policy.domain.md +0 -11
  198. package/assets/docs/domainspecs/pharma/domain-driven-design.domain.md +0 -36
  199. package/assets/docs/domainspecs/pharma/domain-requirements.md +0 -99
  200. package/assets/docs/domainspecs/pharma/eventing.domain.md +0 -18
  201. package/assets/docs/domainspecs/pharma/fhir.md +0 -31
  202. package/assets/docs/domainspecs/pharma/folder-structure.domain.md +0 -24
  203. package/assets/docs/domainspecs/pharma/hl7.md +0 -17
  204. package/assets/docs/domainspecs/pharma/idmp.md +0 -26
  205. package/assets/docs/domainspecs/pharma/integration-terms.md +0 -21
  206. package/assets/docs/domainspecs/pharma/ndc.md +0 -28
  207. package/assets/docs/domainspecs/pharma/persistence.domain.md +0 -23
  208. package/assets/docs/domainspecs/pharma/pharma-terms.md +0 -27
  209. package/assets/docs/domainspecs/pharma/product-lifecycle.domain.md +0 -30
  210. package/assets/docs/domainspecs/pharma/regulatory-compliance.md +0 -19
  211. package/assets/docs/domainspecs/pharma/terminology.md +0 -32
  212. package/assets/docs/domainspecs/pharma/testing.domain.md +0 -19
  213. package/assets/docs/domainspecs/pharma/vertical-slices.domain.md +0 -17
  214. package/assets/docs/domainspecs/pharma/zero-trust.domain.md +0 -12
  215. package/assets/docs/glossary/ai-rules.md +0 -59
  216. package/assets/docs/governance/api-versioning.md +0 -99
  217. package/assets/docs/governance/coding-standards.md +0 -87
  218. package/assets/docs/governance/dependency-policy.md +0 -40
  219. package/assets/docs/interop/ihe-conformance.md +0 -31
  220. package/assets/docs/security/auditing.md +0 -117
  221. package/assets/docs/security/authorization-matrix.md +0 -14
  222. package/assets/docs/security/authorization.md +0 -87
  223. package/assets/docs/security/data-classification.md +0 -38
  224. package/assets/docs/security/zero-trust.md +0 -76
  225. package/assets/docs/technology-constitution.md +0 -172
@@ -1,145 +0,0 @@
1
- #requires -Version 5.1
2
- <#
3
- .SYNOPSIS
4
- Pack a verified foundation solution into a single AW-Spec text pack file.
5
-
6
- .DESCRIPTION
7
- Walks -SourceDir, excludes build/IDE artifacts, and writes every remaining file
8
- into one pack file using <<<FILE>>> / <<<ENDFILE>>> markers. Text files are stored
9
- verbatim (UTF-8, LF); binary files are base64-encoded. The resulting pack file is
10
- the single bundled artifact consumed by /aw-spec-foundation (see PACKAGING.md).
11
-
12
- .EXAMPLE
13
- ./pack-foundation.ps1 -SourceDir ../../.foundation-build -OutFile ./VerticalSlice.pack.txt
14
- #>
15
- [CmdletBinding()]
16
- param(
17
- [Parameter(Mandatory)] [string] $SourceDir,
18
- [string] $OutFile,
19
- [string] $Sentinel = 'AppWeaver.Foundation',
20
- [string] $Foundation = 'VerticalSlice',
21
- [switch] $AllowSecrets
22
- )
23
-
24
- $ErrorActionPreference = 'Stop'
25
-
26
- $src = (Resolve-Path -LiteralPath $SourceDir).Path
27
- if (-not (Test-Path -LiteralPath $src -PathType Container)) {
28
- throw "SourceDir is not a folder: $SourceDir"
29
- }
30
- if (-not $OutFile) { $OutFile = Join-Path (Get-Location).Path "$Foundation.pack.txt" }
31
-
32
- # Entire subtree excluded if any path segment matches one of these
33
- $excludeDirs = @('bin','obj','.vs','.git','.idea','.vscode','TestResults','node_modules','packages','App_Data','artifacts','.next','logs')
34
- # Files excluded by name glob (build noise, local dbs, and secret-bearing files)
35
- # NOTE: the root '.env' is intentionally NOT excluded — it carries required sample config
36
- # and is bundled on purpose. Per-environment overrides ('.env.local', '.env.production', ...)
37
- # stay excluded via the '.env.*' glob. Real credentials are still caught by the content scan.
38
- $excludeFiles = @(
39
- '*.user','*.suo','*.DotSettings.user','*.db','*.db-shm','*.db-wal','*.sqlite','*.log',
40
- '.env.*','*.pfx','*.pem','*.key','*.snk','id_rsa','id_rsa.pub','secrets.json'
41
- )
42
-
43
- # Content patterns that indicate a real secret; packing aborts on a hit unless -AllowSecrets.
44
- $secretPatterns = @(
45
- @{ Name = 'NuGet ClearTextPassword'; Rx = 'ClearTextPassword' }
46
- @{ Name = 'Private key block'; Rx = 'BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY' }
47
- @{ Name = 'AWS access key id'; Rx = 'AKIA[0-9A-Z]{16}' }
48
- @{ Name = 'Azure DevOps PAT-ish'; Rx = '[A-Za-z0-9]{52}AZDO[A-Za-z0-9]' }
49
- )
50
-
51
- function Test-Excluded([string] $relPath) {
52
- foreach ($seg in ($relPath -split '[\\/]')) {
53
- if ($excludeDirs -contains $seg) { return $true }
54
- }
55
- $leaf = Split-Path $relPath -Leaf
56
- foreach ($g in $excludeFiles) { if ($leaf -like $g) { return $true } }
57
- return $false
58
- }
59
-
60
- function Test-Binary([byte[]] $bytes) {
61
- $n = [Math]::Min(8000, $bytes.Length)
62
- for ($i = 0; $i -lt $n; $i++) { if ($bytes[$i] -eq 0) { return $true } }
63
- return $false
64
- }
65
-
66
- # Collect + filter
67
- $picked = New-Object System.Collections.Generic.List[object]
68
- foreach ($f in (Get-ChildItem -LiteralPath $src -Recurse -File -Force)) {
69
- $rel = ($f.FullName.Substring($src.Length).TrimStart('\','/')) -replace '\\','/'
70
- if (Test-Excluded $rel) { continue }
71
- $picked.Add([pscustomobject]@{ Rel = $rel; Full = $f.FullName })
72
- }
73
- $picked = @($picked | Sort-Object Rel)
74
- if ($picked.Count -eq 0) { throw "No files to pack under: $src" }
75
-
76
- # Secret scan — fail closed so credentials never get baked into the committed bundle
77
- $findings = New-Object System.Collections.Generic.List[string]
78
- foreach ($p in $picked) {
79
- try {
80
- $t = [System.IO.File]::ReadAllText($p.Full)
81
- } catch { continue }
82
- foreach ($pat in $secretPatterns) {
83
- if ($t -match $pat.Rx) { $findings.Add(" $($p.Rel) -> $($pat.Name)") }
84
- }
85
- }
86
- if ($findings.Count -gt 0) {
87
- $msg = "Potential secret(s) detected — refusing to pack (rotate + remove them, or pass -AllowSecrets):`n" + ($findings -join "`n")
88
- if ($AllowSecrets) { Write-Warning $msg } else { throw $msg }
89
- }
90
-
91
- # Sentinel sanity check
92
- $hits = 0
93
- foreach ($p in $picked) {
94
- try {
95
- $t = [System.IO.File]::ReadAllText($p.Full)
96
- if ($t.Contains($Sentinel)) { $hits++ }
97
- } catch { }
98
- }
99
- if ($hits -eq 0) {
100
- Write-Warning "Sentinel '$Sentinel' not found in any file. Did you build the sample under that exact name?"
101
- } else {
102
- Write-Host "Sentinel '$Sentinel' found in $hits file(s)."
103
- }
104
-
105
- # Build the pack (explicit LF newlines throughout)
106
- $sb = [System.Text.StringBuilder]::new()
107
- function AddLine([string] $s) { [void]$sb.Append($s); [void]$sb.Append("`n") }
108
-
109
- AddLine '# AW-SPEC FOUNDATION PACK'
110
- AddLine "# foundation: $Foundation"
111
- AddLine "# sentinel: $Sentinel"
112
- AddLine "# generated: $([DateTime]::UtcNow.ToString('o'))"
113
- AddLine "# files: $($picked.Count)"
114
- AddLine '# format: aw-spec-pack/v1'
115
- AddLine '# --- replacement contract (ordinal, case-sensitive, longest-first) ---'
116
- AddLine '# <Sentinel> -> <AppName> (dotted: namespaces, csproj/sln, refs)'
117
- AddLine '# <Sentinel _-form> -> <AppName _-form> (underscored: Aspire project class names)'
118
- AddLine '# <sentinel --form> -> <appname --form> (lower-hyphen: UserSecretsId, db/containers)'
119
- AddLine '# <sentinel .-form> -> <appname lower-dot> (lower-dot: lowercased identifiers)'
120
- AddLine '# Applied to file CONTENTS and file/dir PATHS. Never touch other AppWeaver.* tokens.'
121
- AddLine '# ============================================================'
122
- AddLine ''
123
-
124
- foreach ($p in $picked) {
125
- $bytes = [System.IO.File]::ReadAllBytes($p.Full)
126
- if (Test-Binary $bytes) {
127
- AddLine "<<<FILE path=`"$($p.Rel)`" encoding=`"base64`">>>"
128
- AddLine ([Convert]::ToBase64String($bytes))
129
- AddLine '<<<ENDFILE>>>'
130
- } else {
131
- $text = ([System.IO.File]::ReadAllText($p.Full)) -replace "`r`n", "`n"
132
- AddLine "<<<FILE path=`"$($p.Rel)`">>>"
133
- [void]$sb.Append($text)
134
- if (-not $text.EndsWith("`n")) { [void]$sb.Append("`n") }
135
- AddLine '<<<ENDFILE>>>'
136
- }
137
- }
138
-
139
- $outDir = Split-Path -Parent $OutFile
140
- if ($outDir -and -not (Test-Path -LiteralPath $outDir)) {
141
- New-Item -ItemType Directory -Force -Path $outDir | Out-Null
142
- }
143
- [System.IO.File]::WriteAllText($OutFile, $sb.ToString(), [System.Text.UTF8Encoding]::new($false))
144
-
145
- Write-Host "Packed $($picked.Count) file(s) -> $OutFile"
@@ -1,196 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # pack-foundation.sh — bash/macOS+Unix port of pack-foundation.ps1
4
- #
5
- # SYNOPSIS
6
- # Pack a verified foundation solution into a single AW-Spec text pack file.
7
- #
8
- # DESCRIPTION
9
- # Walks --source-dir, excludes build/IDE artifacts and secret-bearing files, and
10
- # writes every remaining file into one pack file using <<<FILE>>> / <<<ENDFILE>>>
11
- # markers. Text files are stored verbatim (UTF-8, LF); binary files are
12
- # base64-encoded. The resulting pack file is the single bundled artifact consumed
13
- # by /aw-spec-foundation (see PACKAGING.md). This is byte-for-byte format-compatible
14
- # with pack-foundation.ps1 / unpack-foundation.ps1.
15
- #
16
- # EXAMPLE
17
- # ./pack-foundation.sh --source-dir ../../.foundation-build --out-file ./VerticalSlice.pack.txt --allow-secrets
18
- #
19
- set -euo pipefail
20
-
21
- # ------------------------------------------------------------------ defaults ---
22
- SENTINEL='AppWeaver.Foundation'
23
- FOUNDATION='VerticalSlice'
24
- SOURCE_DIR=''
25
- OUT_FILE=''
26
- ALLOW_SECRETS=0
27
-
28
- usage() {
29
- cat >&2 <<'EOF'
30
- Usage: pack-foundation.sh --source-dir <dir> [--out-file <file>] [--sentinel <name>]
31
- [--foundation <name>] [--allow-secrets]
32
-
33
- -s, --source-dir <dir> Folder holding the foundation solution (required)
34
- -o, --out-file <file> Output pack file (default: ./<foundation>.pack.txt)
35
- --sentinel <name> Sentinel app name (default: AppWeaver.Foundation)
36
- --foundation <name> Foundation name (default: VerticalSlice)
37
- --allow-secrets Pack even if credential markers are detected
38
- -h, --help Show this help
39
-
40
- Positional fallback: pack-foundation.sh <source-dir> [out-file]
41
- EOF
42
- }
43
-
44
- # -------------------------------------------------------------- arg parsing ---
45
- while [ $# -gt 0 ]; do
46
- case "$1" in
47
- -s|--source-dir) SOURCE_DIR="${2:?--source-dir needs a value}"; shift 2 ;;
48
- -o|--out-file) OUT_FILE="${2:?--out-file needs a value}"; shift 2 ;;
49
- --sentinel) SENTINEL="${2:?--sentinel needs a value}"; shift 2 ;;
50
- --foundation) FOUNDATION="${2:?--foundation needs a value}"; shift 2 ;;
51
- --allow-secrets) ALLOW_SECRETS=1; shift ;;
52
- -h|--help) usage; exit 0 ;;
53
- --) shift; break ;;
54
- -*) echo "Error: unknown option: $1" >&2; usage; exit 2 ;;
55
- *)
56
- if [ -z "$SOURCE_DIR" ]; then SOURCE_DIR="$1"
57
- elif [ -z "$OUT_FILE" ]; then OUT_FILE="$1"
58
- else echo "Error: unexpected argument: $1" >&2; usage; exit 2
59
- fi
60
- shift ;;
61
- esac
62
- done
63
-
64
- [ -n "$SOURCE_DIR" ] || { echo "Error: --source-dir is required." >&2; usage; exit 2; }
65
- [ -d "$SOURCE_DIR" ] || { echo "Error: SourceDir is not a folder: $SOURCE_DIR" >&2; exit 1; }
66
-
67
- SRC="$(cd "$SOURCE_DIR" && pwd -P)"
68
- [ -n "$OUT_FILE" ] || OUT_FILE="$(pwd)/$FOUNDATION.pack.txt"
69
-
70
- # -------------------------------------------------------------- exclusions ---
71
- # Entire subtree excluded if any path segment matches one of these.
72
- EXCLUDE_DIRS=(bin obj .vs .git .idea .vscode TestResults node_modules packages App_Data artifacts .next logs)
73
- # Files excluded by leaf-name glob (build noise, local dbs, and secret-bearing files).
74
- # NOTE: the root `.env` is intentionally NOT excluded — it carries required sample config
75
- # and is bundled on purpose. Per-environment overrides (`.env.local`, `.env.production`, ...)
76
- # stay excluded via the `.env.*` glob. Real credentials are still caught by the content scan.
77
- EXCLUDE_FILES=('*.user' '*.suo' '*.DotSettings.user' '*.db' '*.db-shm' '*.db-wal' '*.sqlite' '*.log' \
78
- '.env.*' '*.pfx' '*.pem' '*.key' '*.snk' 'id_rsa' 'id_rsa.pub' 'secrets.json')
79
-
80
- # Content patterns that indicate a real secret; packing aborts on a hit unless --allow-secrets.
81
- SECRET_NAMES=('NuGet ClearTextPassword' 'Private key block' 'AWS access key id' 'Azure DevOps PAT-ish')
82
- SECRET_RX=('ClearTextPassword' \
83
- 'BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY' \
84
- 'AKIA[0-9A-Z]{16}' \
85
- '[A-Za-z0-9]{52}AZDO[A-Za-z0-9]')
86
-
87
- is_excluded() { # $1 = repo-relative path with '/' separators
88
- local rel="$1" seg leaf g
89
- local -a segs
90
- IFS='/' read -ra segs <<< "$rel"
91
- for seg in "${segs[@]}"; do
92
- for g in "${EXCLUDE_DIRS[@]}"; do
93
- [ "$seg" = "$g" ] && return 0
94
- done
95
- done
96
- leaf="${rel##*/}"
97
- for g in "${EXCLUDE_FILES[@]}"; do
98
- # shellcheck disable=SC2254 # intentional glob match
99
- case "$leaf" in $g) return 0 ;; esac
100
- done
101
- return 1
102
- }
103
-
104
- is_binary() { # $1 = file path; true if a NUL byte appears in the first 8000 bytes
105
- local f="$1" n1 n2
106
- n1="$(head -c 8000 "$f" | wc -c | tr -d '[:space:]')"
107
- n2="$(head -c 8000 "$f" | LC_ALL=C tr -d '\000' | wc -c | tr -d '[:space:]')"
108
- [ "$n1" != "$n2" ]
109
- }
110
-
111
- # ----------------------------------------------------------- collect + sort ---
112
- picked=()
113
- while IFS= read -r full; do
114
- rel="${full#"$SRC"/}"
115
- is_excluded "$rel" && continue
116
- picked+=("$rel")
117
- done < <(find "$SRC" -type f | LC_ALL=C sort)
118
-
119
- [ "${#picked[@]}" -gt 0 ] || { echo "Error: No files to pack under: $SRC" >&2; exit 1; }
120
-
121
- # ----------------------------------------------------------- secret scan -----
122
- # Fail closed so credentials never get baked into the committed bundle.
123
- findings=()
124
- for rel in "${picked[@]}"; do
125
- f="$SRC/$rel"
126
- for i in "${!SECRET_RX[@]}"; do
127
- if LC_ALL=C grep -aEq -- "${SECRET_RX[$i]}" "$f" 2>/dev/null; then
128
- findings+=(" $rel -> ${SECRET_NAMES[$i]}")
129
- fi
130
- done
131
- done
132
- if [ "${#findings[@]}" -gt 0 ]; then
133
- if [ "$ALLOW_SECRETS" -eq 1 ]; then
134
- echo "WARNING: Potential secret(s) detected — packing anyway (--allow-secrets):" >&2
135
- printf '%s\n' "${findings[@]}" >&2
136
- else
137
- echo "Error: Potential secret(s) detected — refusing to pack (rotate + remove them, or pass --allow-secrets):" >&2
138
- printf '%s\n' "${findings[@]}" >&2
139
- exit 1
140
- fi
141
- fi
142
-
143
- # ----------------------------------------------------------- sentinel check --
144
- hits=0
145
- for rel in "${picked[@]}"; do
146
- if LC_ALL=C grep -aFq -- "$SENTINEL" "$SRC/$rel" 2>/dev/null; then
147
- hits=$((hits + 1))
148
- fi
149
- done
150
- if [ "$hits" -eq 0 ]; then
151
- echo "WARNING: Sentinel '$SENTINEL' not found in any file. Did you build the sample under that exact name?" >&2
152
- else
153
- echo "Sentinel '$SENTINEL' found in $hits file(s)."
154
- fi
155
-
156
- # ----------------------------------------------------------- write the pack --
157
- outdir="$(dirname "$OUT_FILE")"
158
- [ -d "$outdir" ] || mkdir -p "$outdir"
159
-
160
- {
161
- printf '%s\n' '# AW-SPEC FOUNDATION PACK'
162
- printf '# foundation: %s\n' "$FOUNDATION"
163
- printf '# sentinel: %s\n' "$SENTINEL"
164
- printf '# generated: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%S.0000000Z)"
165
- printf '# files: %s\n' "${#picked[@]}"
166
- printf '%s\n' '# format: aw-spec-pack/v1'
167
- printf '%s\n' '# --- replacement contract (ordinal, case-sensitive, longest-first) ---'
168
- printf '%s\n' '# <Sentinel> -> <AppName> (dotted: namespaces, csproj/sln, refs)'
169
- printf '%s\n' '# <Sentinel _-form> -> <AppName _-form> (underscored: Aspire project class names)'
170
- printf '%s\n' '# <sentinel --form> -> <appname --form> (lower-hyphen: UserSecretsId, db/containers)'
171
- printf '%s\n' '# <sentinel .-form> -> <appname lower-dot> (lower-dot: lowercased identifiers)'
172
- printf '%s\n' '# Applied to file CONTENTS and file/dir PATHS. Never touch other AppWeaver.* tokens.'
173
- printf '%s\n' '# ============================================================'
174
- printf '\n'
175
- } > "$OUT_FILE"
176
-
177
- for rel in "${picked[@]}"; do
178
- f="$SRC/$rel"
179
- if is_binary "$f"; then
180
- {
181
- printf '<<<FILE path="%s" encoding="base64">>>\n' "$rel"
182
- base64 < "$f" | tr -d '\n'
183
- printf '\n'
184
- printf '%s\n' '<<<ENDFILE>>>'
185
- } >> "$OUT_FILE"
186
- else
187
- {
188
- printf '<<<FILE path="%s">>>\n' "$rel"
189
- # CRLF -> LF, and guarantee the content ends with exactly one trailing newline.
190
- awk '{ sub(/\r$/, ""); print }' "$f"
191
- printf '%s\n' '<<<ENDFILE>>>'
192
- } >> "$OUT_FILE"
193
- fi
194
- done
195
-
196
- echo "Packed ${#picked[@]} file(s) -> $OUT_FILE"
@@ -1,157 +0,0 @@
1
- #requires -Version 5.1
2
- <#
3
- .SYNOPSIS
4
- Pack a verified feature reference template into a single AW-Spec text pack file.
5
-
6
- .DESCRIPTION
7
- Walks -SourceDir (a templates/features/<Name>.SimpleSample folder), excludes build/IDE
8
- artifacts, template meta-files, and secret-bearing files, and writes every remaining file
9
- into one pack file using <<<FILE>>> / <<<ENDFILE>>> markers. Text files are stored verbatim
10
- (UTF-8, LF); binary files are base64-encoded. The resulting pack file is the single bundled
11
- artifact consumed by /aw-spec-addcomponent or /aw-spec-implement unpack workflows.
12
-
13
- .EXAMPLE
14
- ./pack-reference-foundation.ps1 `
15
- -SourceDir ../../templates/features/VerticalSlice.SimpleSample `
16
- -OutFile ./VerticalSlice.Reference.pack.txt `
17
- -Sentinel AppWeaver.VerticalSlice `
18
- -Foundation VerticalSlice.Reference
19
-
20
- .EXAMPLE
21
- ./pack-reference-foundation.ps1 `
22
- -SourceDir ../../templates/features/ModularMonolith.SimpleSample `
23
- -OutFile ../ModularMonolith/ModularMonolith.Reference.pack.txt `
24
- -Sentinel AppWeaver.ModularMonolith `
25
- -Foundation ModularMonolith.Reference
26
- #>
27
- [CmdletBinding()]
28
- param(
29
- [Parameter(Mandatory)] [string] $SourceDir,
30
- [string] $OutFile,
31
- [string] $Sentinel = 'AppWeaver.VerticalSlice',
32
- [string] $Foundation = 'VerticalSlice.Reference',
33
- [switch] $AllowSecrets
34
- )
35
-
36
- $ErrorActionPreference = 'Stop'
37
-
38
- $src = (Resolve-Path -LiteralPath $SourceDir).Path
39
- if (-not (Test-Path -LiteralPath $src -PathType Container)) {
40
- throw "SourceDir is not a folder: $SourceDir"
41
- }
42
- if (-not $OutFile) { $OutFile = Join-Path (Get-Location).Path "$Foundation.pack.txt" }
43
-
44
- # Entire subtree excluded if any path segment matches one of these.
45
- $excludeDirs = @('bin','obj','.vs','.git','.idea','.vscode','TestResults','node_modules','packages','App_Data','artifacts','.next','logs')
46
-
47
- # Files excluded by leaf-name glob (build noise, local dbs, secret-bearing files, and
48
- # template meta-files that should never appear in unpacked output).
49
- $excludeFiles = @(
50
- '*.user','*.suo','*.DotSettings.user','*.db','*.db-shm','*.db-wal','*.sqlite','*.log',
51
- '.env','*.env.*','.env.*','*.pfx','*.pem','*.key','*.snk','id_rsa','id_rsa.pub','secrets.json',
52
- '.DS_Store', # macOS metadata
53
- '*.my-ref.*', # template annotation files (Action: Exclude in TemplateConfig)
54
- '*TemplateConfig.config' # template configuration meta-files
55
- )
56
-
57
- # Content patterns that indicate a real secret; packing aborts on a hit unless -AllowSecrets.
58
- $secretPatterns = @(
59
- @{ Name = 'NuGet ClearTextPassword'; Rx = 'ClearTextPassword' }
60
- @{ Name = 'Private key block'; Rx = 'BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY' }
61
- @{ Name = 'AWS access key id'; Rx = 'AKIA[0-9A-Z]{16}' }
62
- @{ Name = 'Azure DevOps PAT-ish'; Rx = '[A-Za-z0-9]{52}AZDO[A-Za-z0-9]' }
63
- )
64
-
65
- function Test-Excluded([string] $relPath) {
66
- foreach ($seg in ($relPath -split '[\\/]')) {
67
- if ($excludeDirs -contains $seg) { return $true }
68
- }
69
- $leaf = Split-Path $relPath -Leaf
70
- foreach ($g in $excludeFiles) { if ($leaf -like $g) { return $true } }
71
- return $false
72
- }
73
-
74
- function Test-Binary([byte[]] $bytes) {
75
- $n = [Math]::Min(8000, $bytes.Length)
76
- for ($i = 0; $i -lt $n; $i++) { if ($bytes[$i] -eq 0) { return $true } }
77
- return $false
78
- }
79
-
80
- # Collect + filter
81
- $picked = New-Object System.Collections.Generic.List[object]
82
- foreach ($f in (Get-ChildItem -LiteralPath $src -Recurse -File -Force)) {
83
- $rel = ($f.FullName.Substring($src.Length).TrimStart('\','/')) -replace '\\','/'
84
- if (Test-Excluded $rel) { continue }
85
- $picked.Add([pscustomobject]@{ Rel = $rel; Full = $f.FullName })
86
- }
87
- $picked = @($picked | Sort-Object Rel)
88
- if ($picked.Count -eq 0) { throw "No files to pack under: $src" }
89
-
90
- # Secret scan — fail closed so credentials never get baked into the committed bundle.
91
- $findings = New-Object System.Collections.Generic.List[string]
92
- foreach ($p in $picked) {
93
- try { $t = [System.IO.File]::ReadAllText($p.Full) } catch { continue }
94
- foreach ($pat in $secretPatterns) {
95
- if ($t -match $pat.Rx) { $findings.Add(" $($p.Rel) -> $($pat.Name)") }
96
- }
97
- }
98
- if ($findings.Count -gt 0) {
99
- $msg = "Potential secret(s) detected — refusing to pack (rotate + remove them, or pass -AllowSecrets):`n" + ($findings -join "`n")
100
- if ($AllowSecrets) { Write-Warning $msg } else { throw $msg }
101
- }
102
-
103
- # Sentinel sanity check
104
- $hits = 0
105
- foreach ($p in $picked) {
106
- try {
107
- $t = [System.IO.File]::ReadAllText($p.Full)
108
- if ($t.Contains($Sentinel)) { $hits++ }
109
- } catch { }
110
- }
111
- if ($hits -eq 0) {
112
- Write-Warning "Sentinel '$Sentinel' not found in any file. Did you build the sample under that exact name?"
113
- } else {
114
- Write-Host "Sentinel '$Sentinel' found in $hits file(s)."
115
- }
116
-
117
- # Build the pack (explicit LF newlines throughout)
118
- $sb = [System.Text.StringBuilder]::new()
119
- function AddLine([string] $s) { [void]$sb.Append($s); [void]$sb.Append("`n") }
120
-
121
- AddLine '# AW-SPEC REFERENCE PACK'
122
- AddLine "# foundation: $Foundation"
123
- AddLine "# sentinel: $Sentinel"
124
- AddLine "# generated: $([DateTime]::UtcNow.ToString('o'))"
125
- AddLine "# files: $($picked.Count)"
126
- AddLine '# format: aw-spec-pack/v1'
127
- AddLine '# --- replacement contract (ordinal, case-sensitive, longest-first) ---'
128
- AddLine '# <Sentinel> -> <AppName> (dotted: namespaces, csproj/sln, refs)'
129
- AddLine '# <Sentinel _-form> -> <AppName _-form> (underscored: Aspire project class names)'
130
- AddLine '# <sentinel --form> -> <appname --form> (lower-hyphen: UserSecretsId, db/containers)'
131
- AddLine '# <sentinel .-form> -> <appname lower-dot> (lower-dot: lowercased identifiers)'
132
- AddLine '# Applied to file CONTENTS and file/dir PATHS. Never touch other AppWeaver.* tokens.'
133
- AddLine '# ============================================================'
134
- AddLine ''
135
-
136
- foreach ($p in $picked) {
137
- $bytes = [System.IO.File]::ReadAllBytes($p.Full)
138
- if (Test-Binary $bytes) {
139
- AddLine "<<<FILE path=`"$($p.Rel)`" encoding=`"base64`">>>"
140
- AddLine ([Convert]::ToBase64String($bytes))
141
- AddLine '<<<ENDFILE>>>'
142
- } else {
143
- $text = ([System.IO.File]::ReadAllText($p.Full)) -replace "`r`n", "`n"
144
- AddLine "<<<FILE path=`"$($p.Rel)`">>>"
145
- [void]$sb.Append($text)
146
- if (-not $text.EndsWith("`n")) { [void]$sb.Append("`n") }
147
- AddLine '<<<ENDFILE>>>'
148
- }
149
- }
150
-
151
- $outDir = Split-Path -Parent $OutFile
152
- if ($outDir -and -not (Test-Path -LiteralPath $outDir)) {
153
- New-Item -ItemType Directory -Force -Path $outDir | Out-Null
154
- }
155
- [System.IO.File]::WriteAllText($OutFile, $sb.ToString(), [System.Text.UTF8Encoding]::new($false))
156
-
157
- Write-Host "Packed $($picked.Count) file(s) -> $OutFile"