aw-spec-cli 0.1.21 → 0.1.23

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 (51) hide show
  1. package/assets/.appweaver/STACK-PROFILES.md +87 -8
  2. package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +30 -0
  3. package/assets/.appweaver/orchestrator/orchestrator.py +47 -3
  4. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +41 -8
  5. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +62 -2
  6. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +18 -5
  7. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +1 -1
  8. package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +4 -1
  9. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +115 -27
  10. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +5 -1
  11. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +225 -27
  12. package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +4 -15
  13. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1 -1
  14. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +39 -0
  15. package/assets/.appweaver/orchestrator/workflows/aw-spec-recall-delta.orch.yaml +28 -7
  16. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +3 -1
  17. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +104 -1
  18. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +159 -0
  19. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +386 -0
  20. package/assets/.appweaver/orchestrator/workflows/aw-spec-workflow-model.orch.yaml +153 -0
  21. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +203 -212
  22. package/assets/.appweaver/scripts/bash/aw-xref.sh +4 -1
  23. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +191 -224
  24. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +4 -1
  25. package/assets/.appweaver/scripts/python/aw-crstate.py +127 -2
  26. package/assets/.appweaver/scripts/python/aw-gaps.py +119 -0
  27. package/assets/.appweaver/scripts/python/aw-payload-parity.py +17 -1
  28. package/assets/.appweaver/scripts/python/aw-plan-coverage.py +84 -4
  29. package/assets/.appweaver/scripts/python/aw-plangate.py +216 -0
  30. package/assets/.appweaver/scripts/python/aw-principles.py +108 -0
  31. package/assets/.appweaver/scripts/python/aw-stack.py +6 -0
  32. package/assets/.appweaver/scripts/python/aw-xref.py +141 -4
  33. package/assets/.appweaver/stack-profiles/angular.json +26 -0
  34. package/assets/.appweaver/stack-profiles/blazor-wasm.json +38 -0
  35. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +38 -0
  36. package/assets/.appweaver/stack-profiles/java-spring.json +19 -0
  37. package/assets/.appweaver/stack-profiles/nextjs.json +26 -0
  38. package/assets/.appweaver/stack-profiles/node-express.json +26 -0
  39. package/assets/.appweaver/stack-profiles/python-fastapi.json +15 -0
  40. package/assets/.appweaver/stack-profiles/react-vite.json +26 -0
  41. package/assets/.appweaver/stack-profiles/sveltekit.json +26 -0
  42. package/assets/.appweaver/stack-profiles/vue-vite.json +26 -0
  43. package/assets/.appweaver/templates/ui-model-template.md +67 -0
  44. package/assets/.appweaver/templates/workflow-model-template.md +62 -0
  45. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +3 -3
  46. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +5 -123
  47. package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +784 -0
  48. package/assets/foundations/java/Hexagonal/pack-foundation.sh +357 -0
  49. package/assets/foundations/java/Hexagonal/unpack-foundation.sh +399 -0
  50. package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +44 -0
  51. package/package.json +1 -1
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # pack-foundation.sh — Java foundation packer for AW-Spec
4
+ #
5
+ # Packs the Java Hexagonal foundation into a single AW-Spec foundation pack.
6
+ #
7
+ # Source foundation:
8
+ # foundation/appweaver.hexagonal
9
+ #
10
+ # The packer does NOT rename the Java package.
11
+ # The Java package replacement is performed during unpacking.
12
+ #
13
+ # Java foundation sentinel:
14
+ # io.appweaver
15
+ #
16
+ # Example:
17
+ # ./pack-foundation.sh \
18
+ # --source-dir /path/to/appweaver-java-library/foundation/appweaver.hexagonal \
19
+ # --out-file ./Hexagonal.pack.txt
20
+ #
21
+
22
+ set -euo pipefail
23
+
24
+ # ------------------------------------------------------------------ defaults ---
25
+
26
+ SENTINEL='io.appweaver'
27
+ FOUNDATION='Hexagonal'
28
+ SOURCE_DIR=''
29
+ OUT_FILE=''
30
+ ALLOW_SECRETS=0
31
+
32
+ usage() {
33
+ cat >&2 <<'EOF'
34
+ Usage: pack-foundation.sh --source-dir <dir> [--out-file <file>]
35
+ [--sentinel <name>] [--foundation <name>]
36
+ [--allow-secrets]
37
+
38
+ -s, --source-dir <dir> Java foundation directory (required)
39
+ -o, --out-file <file> Output pack file (default: ./Hexagonal.pack.txt)
40
+ --sentinel <name> Java package sentinel (default: io.appweaver)
41
+ --foundation <name> Foundation name (default: Hexagonal)
42
+ --allow-secrets Pack even if credential markers exist
43
+ -h, --help Show this help
44
+
45
+ Positional fallback:
46
+ pack-foundation.sh <source-dir> [out-file]
47
+ EOF
48
+ }
49
+
50
+ # -------------------------------------------------------------- argument parsing
51
+
52
+ while [ $# -gt 0 ]; do
53
+ case "$1" in
54
+ -s|--source-dir)
55
+ SOURCE_DIR="${2:?--source-dir needs a value}"
56
+ shift 2
57
+ ;;
58
+
59
+ -o|--out-file)
60
+ OUT_FILE="${2:?--out-file needs a value}"
61
+ shift 2
62
+ ;;
63
+
64
+ --sentinel)
65
+ SENTINEL="${2:?--sentinel needs a value}"
66
+ shift 2
67
+ ;;
68
+
69
+ --foundation)
70
+ FOUNDATION="${2:?--foundation needs a value}"
71
+ shift 2
72
+ ;;
73
+
74
+ --allow-secrets)
75
+ ALLOW_SECRETS=1
76
+ shift
77
+ ;;
78
+
79
+ -h|--help)
80
+ usage
81
+ exit 0
82
+ ;;
83
+
84
+ --)
85
+ shift
86
+ break
87
+ ;;
88
+
89
+ -*)
90
+ echo "Error: unknown option: $1" >&2
91
+ usage
92
+ exit 2
93
+ ;;
94
+
95
+ *)
96
+ if [ -z "$SOURCE_DIR" ]; then
97
+ SOURCE_DIR="$1"
98
+ elif [ -z "$OUT_FILE" ]; then
99
+ OUT_FILE="$1"
100
+ else
101
+ echo "Error: unexpected argument: $1" >&2
102
+ usage
103
+ exit 2
104
+ fi
105
+ shift
106
+ ;;
107
+ esac
108
+ done
109
+
110
+ [ -n "$SOURCE_DIR" ] || {
111
+ echo "Error: --source-dir is required." >&2
112
+ usage
113
+ exit 2
114
+ }
115
+
116
+ [ -d "$SOURCE_DIR" ] || {
117
+ echo "Error: SourceDir is not a folder: $SOURCE_DIR" >&2
118
+ exit 1
119
+ }
120
+
121
+ SRC="$(cd "$SOURCE_DIR" && pwd -P)"
122
+
123
+ [ -n "$OUT_FILE" ] || {
124
+ OUT_FILE="$(pwd)/$FOUNDATION.pack.txt"
125
+ }
126
+
127
+ # -------------------------------------------------------------- exclusions ------
128
+
129
+ # Java/Maven/IDE/build artifacts that should never be included in the foundation.
130
+ EXCLUDE_DIRS=(
131
+ target
132
+ .gradle
133
+ .git
134
+ .idea
135
+ .vscode
136
+ .settings
137
+ TestResults
138
+ logs
139
+ artifacts
140
+ )
141
+
142
+ EXCLUDE_FILES=(
143
+ '*.class'
144
+ '*.log'
145
+ '*.db'
146
+ '*.db-shm'
147
+ '*.db-wal'
148
+ '*.sqlite'
149
+ '.env.*'
150
+ '*.pfx'
151
+ '*.pem'
152
+ '*.key'
153
+ '*.snk'
154
+ 'id_rsa'
155
+ 'id_rsa.pub'
156
+ 'secrets.json'
157
+ '.DS_Store'
158
+ )
159
+
160
+ # -------------------------------------------------------------- secret patterns -
161
+
162
+ SECRET_NAMES=(
163
+ 'Private key block'
164
+ 'AWS access key id'
165
+ 'Azure DevOps PAT-ish'
166
+ 'Generic password assignment'
167
+ )
168
+
169
+ SECRET_RX=(
170
+ 'BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY'
171
+ 'AKIA[0-9A-Z]{16}'
172
+ '[A-Za-z0-9]{52}AZDO[A-Za-z0-9]'
173
+ 'password[[:space:]]*=[[:space:]]*["'\''][^"'\'']+'
174
+ )
175
+
176
+ is_excluded() {
177
+ local rel="$1"
178
+ local seg leaf g
179
+ local -a segs
180
+
181
+ IFS='/' read -ra segs <<< "$rel"
182
+
183
+ for seg in "${segs[@]}"; do
184
+ for g in "${EXCLUDE_DIRS[@]}"; do
185
+ [ "$seg" = "$g" ] && return 0
186
+ done
187
+ done
188
+
189
+ leaf="${rel##*/}"
190
+
191
+ for g in "${EXCLUDE_FILES[@]}"; do
192
+ case "$leaf" in
193
+ $g)
194
+ return 0
195
+ ;;
196
+ esac
197
+ done
198
+
199
+ return 1
200
+ }
201
+
202
+ is_binary() {
203
+ local f="$1"
204
+ local n1 n2
205
+
206
+ n1="$(head -c 8000 "$f" | wc -c | tr -d '[:space:]')"
207
+ n2="$(head -c 8000 "$f" | LC_ALL=C tr -d '\000' | wc -c | tr -d '[:space:]')"
208
+
209
+ [ "$n1" != "$n2" ]
210
+ }
211
+
212
+ # ----------------------------------------------------------- collect + sort -----
213
+
214
+ picked_files=()
215
+ picked_dirs=()
216
+
217
+ # Collect files.
218
+ while IFS= read -r full; do
219
+ rel="${full#"$SRC"}"
220
+ rel="${rel#/}"
221
+
222
+ [ -n "$rel" ] || continue
223
+
224
+ is_excluded "$rel" && continue
225
+
226
+ picked_files+=("$rel")
227
+ done < <(find "$SRC" -type f | LC_ALL=C sort)
228
+
229
+ # Collect directories.
230
+ #
231
+ # All non-excluded directories are packed so that empty directories
232
+ # are preserved during unpacking.
233
+ while IFS= read -r full; do
234
+ rel="${full#"$SRC"}"
235
+ rel="${rel#/}"
236
+
237
+ # Do not include the source root itself.
238
+ [ -n "$rel" ] || continue
239
+
240
+ is_excluded "$rel" && continue
241
+
242
+ picked_dirs+=("$rel")
243
+ done < <(find "$SRC" -type d | LC_ALL=C sort)
244
+
245
+ [ "${#picked_files[@]}" -gt 0 ] || {
246
+ echo "Error: No files to pack under: $SRC" >&2
247
+ exit 1
248
+ }
249
+
250
+ # ----------------------------------------------------------- secret scan --------
251
+
252
+ findings=()
253
+
254
+ for rel in "${picked_files[@]}"; do
255
+ f="$SRC/$rel"
256
+
257
+ for i in "${!SECRET_RX[@]}"; do
258
+ if LC_ALL=C grep -aEq -- "${SECRET_RX[$i]}" "$f" 2>/dev/null; then
259
+ findings+=(" $rel -> ${SECRET_NAMES[$i]}")
260
+ fi
261
+ done
262
+ done
263
+
264
+ if [ "${#findings[@]}" -gt 0 ]; then
265
+
266
+ if [ "$ALLOW_SECRETS" -eq 1 ]; then
267
+ echo "WARNING: Potential secret(s) detected — packing anyway:" >&2
268
+ printf '%s\n' "${findings[@]}" >&2
269
+ else
270
+ echo "Error: Potential secret(s) detected — refusing to pack:" >&2
271
+ printf '%s\n' "${findings[@]}" >&2
272
+ echo "Remove the secrets or use --allow-secrets if this is intentional." >&2
273
+ exit 1
274
+ fi
275
+
276
+ fi
277
+
278
+ # ----------------------------------------------------------- sentinel check ------
279
+
280
+ hits=0
281
+
282
+ for rel in "${picked_files[@]}"; do
283
+ if LC_ALL=C grep -aFq -- "$SENTINEL" "$SRC/$rel" 2>/dev/null; then
284
+ hits=$((hits + 1))
285
+ fi
286
+ done
287
+
288
+ if [ "$hits" -eq 0 ]; then
289
+ echo "WARNING: Sentinel '$SENTINEL' not found in any file." >&2
290
+ echo "Expected Java foundation package references such as:" >&2
291
+ echo " package io.appweaver...." >&2
292
+ else
293
+ echo "Sentinel '$SENTINEL' found in $hits file(s)."
294
+ fi
295
+
296
+ # ----------------------------------------------------------- write the pack ------
297
+
298
+ outdir="$(dirname "$OUT_FILE")"
299
+
300
+ [ -d "$outdir" ] || mkdir -p "$outdir"
301
+
302
+ {
303
+ printf '%s\n' '# AW-SPEC FOUNDATION PACK'
304
+ printf '# foundation: %s\n' "$FOUNDATION"
305
+ printf '# sentinel: %s\n' "$SENTINEL"
306
+ printf '# generated: %s\n' "$(date -u +%Y-%m-%dT%H:%M:%S.0000000Z)"
307
+ printf '# files: %s\n' "${#picked_files[@]}"
308
+ printf '# directories: %s\n' "${#picked_dirs[@]}"
309
+ printf '%s\n' '# format: aw-spec-pack/v1'
310
+ printf '%s\n' '# --- Java foundation replacement contract ---'
311
+ printf '%s\n' '# Java content: io.appweaver -> <lowercase-app-name>'
312
+ printf '%s\n' '# Java path: io/appweaver -> <lowercase-app-name>'
313
+ printf '%s\n' '# Application directory preserves the user-provided name.'
314
+ printf '%s\n' '# ============================================================'
315
+ printf '\n'
316
+ } > "$OUT_FILE"
317
+
318
+ # ----------------------------------------------------------- write directories ---
319
+
320
+ for rel in "${picked_dirs[@]}"; do
321
+ {
322
+ printf '<<<DIR path="%s">>>\n' "$rel"
323
+ printf '%s\n' '<<<ENDDIR>>>'
324
+ } >> "$OUT_FILE"
325
+ done
326
+
327
+ # ----------------------------------------------------------- write files ---------
328
+
329
+ for rel in "${picked_files[@]}"; do
330
+
331
+ f="$SRC/$rel"
332
+
333
+ if is_binary "$f"; then
334
+
335
+ {
336
+ printf '<<<FILE path="%s" encoding="base64">>>\n' "$rel"
337
+ base64 < "$f" | tr -d '\n'
338
+ printf '\n'
339
+ printf '%s\n' '<<<ENDFILE>>>'
340
+ } >> "$OUT_FILE"
341
+
342
+ else
343
+
344
+ {
345
+ printf '<<<FILE path="%s">>>\n' "$rel"
346
+
347
+ # Normalize CRLF -> LF.
348
+ awk '{ sub(/\r$/, ""); print }' "$f"
349
+
350
+ printf '%s\n' '<<<ENDFILE>>>'
351
+ } >> "$OUT_FILE"
352
+
353
+ fi
354
+
355
+ done
356
+
357
+ echo "Packed ${#picked_files[@]} file(s) and ${#picked_dirs[@]} directorie(s) -> $OUT_FILE"