aw-spec-cli 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/.appweaver/ORCH-DIALECT.md +3 -3
- package/assets/.appweaver/RULE-PARTITION.md +41 -28
- package/assets/.appweaver/orchestrator/orchestrator.py +139 -17
- package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +3 -3
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +19 -12
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +25 -17
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +10 -10
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +28 -17
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +22 -24
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +29 -19
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +27 -20
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +184 -37
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +18 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +19 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +18 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +4 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +5 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +58 -43
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +650 -205
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +19 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +3 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +5 -5
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +4 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +34 -6
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +40 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-workflow-model.orch.yaml +23 -4
- package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +1 -1
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +82 -10
- package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +1 -1
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +67 -2
- package/assets/.appweaver/scripts/python/aw-inventory.py +1809 -156
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +106 -145
- package/assets/.appweaver/scripts/python/aw-stack.py +45 -1
- package/assets/.appweaver/scripts/python/aw-xref.py +73 -2
- package/assets/.appweaver/scripts/python/validate_okf.py +10 -5
- package/assets/.appweaver/templates/okf-concept-template.md +10 -2
- package/assets/.appweaver/templates/proposed-inventory-template.md +100 -48
- package/assets/.appweaver/templates/source-map-template.md +14 -6
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +3 -3
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +5 -123
- package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +784 -0
- package/assets/foundations/java/Hexagonal/pack-foundation.sh +357 -0
- package/assets/foundations/java/Hexagonal/unpack-foundation.sh +399 -0
- package/package.json +1 -1
|
@@ -631,6 +631,9 @@ function Invoke-LaneResolve {
|
|
|
631
631
|
for ($i = 0; $i -lt $Rest.Count; $i++) {
|
|
632
632
|
switch ($Rest[$i]) {
|
|
633
633
|
{ $_ -in '--kind','--id' } { $fwd += $Rest[$i]; $fwd += $Rest[++$i] }
|
|
634
|
+
# An EMPTY --feature-dir is dropped: a workflow renders the argument whole, and a
|
|
635
|
+
# feature that is not resolved yet means "the repo's declaration as it stands".
|
|
636
|
+
'--feature-dir' { $v = $Rest[++$i]; if ($v) { $fwd += '--feature-dir'; $fwd += $v } }
|
|
634
637
|
default { Write-Error "lane-resolve: unknown arg '$($Rest[$i])'"; exit 1 }
|
|
635
638
|
}
|
|
636
639
|
}
|
|
@@ -1084,6 +1087,31 @@ elif op == "init":
|
|
|
1084
1087
|
d["bootstrap_pending"] = True
|
|
1085
1088
|
save(d)
|
|
1086
1089
|
out["created"] = (not existed)
|
|
1090
|
+
elif op == "lanes":
|
|
1091
|
+
# WHICH DECLARED LANES THIS FEATURE HAS A SURFACE IN. Absent means every lane the repo
|
|
1092
|
+
# declares, which is the ordinary case and needs no record. A feature that genuinely has
|
|
1093
|
+
# no part of one lane's surface — a job-only or shared-kernel slice in a repo that also
|
|
1094
|
+
# has a UI — records the kinds it does have, and `lane-resolve --feature-dir` then reports
|
|
1095
|
+
# the other lane as not declared FOR THIS FEATURE, so no phase plans, gates or builds a
|
|
1096
|
+
# surface the feature does not own. `all` removes the record; an empty value only reads.
|
|
1097
|
+
# Refuses to create the file: init is its one creator, and a record with no version
|
|
1098
|
+
# spine would read as a feature nobody specified.
|
|
1099
|
+
want = os.environ.get("AW_LANES", "").strip()
|
|
1100
|
+
if want and not existed:
|
|
1101
|
+
out["ok"] = False
|
|
1102
|
+
out["error"] = "no active_version.json for this feature yet — it is created by specify or adopt"
|
|
1103
|
+
elif want == "all":
|
|
1104
|
+
d.pop("lanes", None)
|
|
1105
|
+
save(d)
|
|
1106
|
+
elif want:
|
|
1107
|
+
kinds = [k.strip() for k in want.split(",") if k.strip()]
|
|
1108
|
+
bad = [k for k in kinds if k not in ("backend", "frontend")]
|
|
1109
|
+
if bad or not kinds:
|
|
1110
|
+
out["ok"] = False
|
|
1111
|
+
out["error"] = "lanes takes backend, frontend or both (comma-separated), or all; got '%s'" % want
|
|
1112
|
+
else:
|
|
1113
|
+
d["lanes"] = [k for k in ("backend", "frontend") if k in kinds]
|
|
1114
|
+
save(d)
|
|
1087
1115
|
elif op == "bootstrap-done":
|
|
1088
1116
|
# THE ONLY THING THAT CLEARS THE MARKER, called by the phase that raised it once the
|
|
1089
1117
|
# first draft is actually finished. It is a separate op, not a side effect of writing
|
|
@@ -1183,6 +1211,7 @@ elif op == "close":
|
|
|
1183
1211
|
out["previous"] = prev; out["closed_change"] = closed
|
|
1184
1212
|
out["open_changes"] = opens; out["open_count"] = len(opens)
|
|
1185
1213
|
out["bootstrap_pending"] = bool(d.get("bootstrap_pending"))
|
|
1214
|
+
out["lanes"] = list(d.get("lanes") or []) # empty = every declared lane
|
|
1186
1215
|
out["has_change"] = bool(out.get("active_change", "")) # clean branch signal for design
|
|
1187
1216
|
# What a close from THIS state would produce. One bump() authority, read by BOTH
|
|
1188
1217
|
# finalize-delta (to write the right number into the Change History rows it appends)
|
|
@@ -1194,10 +1223,10 @@ print(json.dumps(out))
|
|
|
1194
1223
|
'@
|
|
1195
1224
|
|
|
1196
1225
|
function Invoke-ActiveVersion {
|
|
1197
|
-
param([string]$FeatureDir, [string]$Op, [string]$CrId = '', [string]$Force = '', [string]$Boot = '')
|
|
1226
|
+
param([string]$FeatureDir, [string]$Op, [string]$CrId = '', [string]$Force = '', [string]$Boot = '', [string]$Lanes = '')
|
|
1198
1227
|
$py = Get-Py; if (-not $py) { Write-Error "version-$Op`: python3 required"; exit 1 }
|
|
1199
1228
|
$env:AW_FD = $FeatureDir; $env:AW_OP = $Op; $env:AW_CR = $CrId; $env:AW_FORCE = $Force
|
|
1200
|
-
$env:AW_BOOT = $Boot
|
|
1229
|
+
$env:AW_BOOT = $Boot; $env:AW_LANES = $Lanes
|
|
1201
1230
|
# CrId names the change on BOTH open and close: many may be open at once, so a close
|
|
1202
1231
|
# has to say which one it is closing rather than assuming the only one.
|
|
1203
1232
|
$PyActiveVersion | & $py -
|
|
@@ -1216,6 +1245,32 @@ function Invoke-VersionState { # op in read|init (feature-dir only)
|
|
|
1216
1245
|
Invoke-ActiveVersion -FeatureDir $fd -Op $Op -Boot $boot
|
|
1217
1246
|
}
|
|
1218
1247
|
|
|
1248
|
+
# The lane kinds this feature has a surface in, recorded in its active_version.json. Twin
|
|
1249
|
+
# of bash cmd_feature_lanes: adopt records `backend` for a slice that owns no part of a
|
|
1250
|
+
# declared frontend's surface, and `lane-resolve --feature-dir` reads it back. No argument
|
|
1251
|
+
# reads; --clear drops the record so the feature follows every declared lane again.
|
|
1252
|
+
function Invoke-FeatureLanes {
|
|
1253
|
+
param([string[]]$Rest)
|
|
1254
|
+
$fdArg = ''; $lanes = ''
|
|
1255
|
+
for ($i = 0; $i -lt $Rest.Count; $i++) {
|
|
1256
|
+
switch ($Rest[$i]) {
|
|
1257
|
+
{ $_ -in '--feature-dir','-FeatureDir' } { $fdArg = $Rest[++$i] }
|
|
1258
|
+
'--set' { $lanes = $Rest[++$i] }
|
|
1259
|
+
'--clear' { $lanes = 'all' }
|
|
1260
|
+
default { Write-Error "feature-lanes: unknown arg '$($Rest[$i])'"; exit 1 }
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
$repo = Get-RepoRoot
|
|
1264
|
+
$fd = Resolve-FeatureDir -Arg $fdArg -RepoRoot $repo
|
|
1265
|
+
if (-not $fd) { Write-Error 'feature-lanes: no feature set and no --feature-dir'; exit 1 }
|
|
1266
|
+
$out = Invoke-ActiveVersion -FeatureDir $fd -Op 'lanes' -Lanes $lanes
|
|
1267
|
+
$out
|
|
1268
|
+
# A refused write is a failure the caller has to see: the orchestrator reports a failed
|
|
1269
|
+
# script from stderr, so the reason goes there too.
|
|
1270
|
+
$res = $out | ConvertFrom-Json
|
|
1271
|
+
if (-not $res.ok) { [Console]::Error.WriteLine("feature-lanes: $($res.error)"); exit 1 }
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1219
1274
|
|
|
1220
1275
|
|
|
1221
1276
|
# ─────────────────────────── feature-paths ─────────────────────────────────
|
|
@@ -1230,6 +1285,14 @@ function Invoke-FeaturePaths {
|
|
|
1230
1285
|
if (-not $fd) { Write-Error 'feature-paths: no feature set (run /appweaver select-feature first)'; exit 1 }
|
|
1231
1286
|
if (-not [System.IO.Path]::IsPathRooted($fd)) { $fd = Join-Path $repo $fd }
|
|
1232
1287
|
$feature = Split-Path $fd -Leaf # the aggregate name (feature = specs/<Feature>)
|
|
1288
|
+
# feature_slug is the URL-safe form of that name, and it is what the UI stages use
|
|
1289
|
+
# as a route segment and a directory name (app/<slug>/page.tsx). It is derived here
|
|
1290
|
+
# rather than per workflow so every reader gets the same segment for one feature.
|
|
1291
|
+
# CamelCase splits on the case boundary before the non-alphanumeric squeeze, so
|
|
1292
|
+
# OrderManagement and "Order Management" both reach order-management.
|
|
1293
|
+
$featureSlug = $feature -creplace '([a-z0-9])([A-Z])', '$1-$2'
|
|
1294
|
+
$featureSlug = $featureSlug -creplace '([A-Z]+)([A-Z][a-z])', '$1-$2'
|
|
1295
|
+
$featureSlug = ($featureSlug.ToLowerInvariant() -replace '[^a-z0-9]+', '-').Trim('-')
|
|
1233
1296
|
# The master documents of a feature: spec.md (WHAT/WHY) + one LANE PLAN per declared
|
|
1234
1297
|
# lane (each lane's HOW) — backend-plan.md for the service lane, frontend-plan.md for
|
|
1235
1298
|
# the frontend lane. `plan` writes them; nothing else does.
|
|
@@ -1264,6 +1327,7 @@ function Invoke-FeaturePaths {
|
|
|
1264
1327
|
$specExists = (Test-Path $spec)
|
|
1265
1328
|
Write-Json ([ordered]@{
|
|
1266
1329
|
feature = $feature
|
|
1330
|
+
feature_slug = $featureSlug
|
|
1267
1331
|
feature_dir = $fd
|
|
1268
1332
|
spec_file = $spec
|
|
1269
1333
|
backend_plan = $design
|
|
@@ -4394,6 +4458,7 @@ switch ($sub) {
|
|
|
4394
4458
|
'version-read' { Invoke-VersionState 'read' $rest }
|
|
4395
4459
|
'version-init' { Invoke-VersionState 'init' $rest }
|
|
4396
4460
|
'version-bootstrap-done' { Invoke-VersionState 'bootstrap-done' $rest }
|
|
4461
|
+
'feature-lanes' { Invoke-FeatureLanes -Rest $rest }
|
|
4397
4462
|
'feature-paths' { Invoke-FeaturePaths -Rest $rest }
|
|
4398
4463
|
'design-scaffold' { Invoke-DesignScaffold -Rest $rest }
|
|
4399
4464
|
# The plan phase's name for the same op. Both spellings reach one implementation:
|