azcodr 1.5.2 → 2.1.0
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/.agents/hooks.json +42 -42
- package/.agents/hooks.json.example +42 -42
- package/.agents/mcp_config.json.example +29 -29
- package/.agents/scripts/safety_guard.sh +143 -34
- package/.agents/scripts/verify_completion.sh +90 -27
- package/.agents/skills/agentic-architect/SKILL.md +125 -125
- package/.agents/skills/agentic-architect/references/agents_md_template.md +62 -62
- package/.agents/skills/agentic-architect/references/refinement_workflow.md +32 -32
- package/.agents/skills/agentic-architect/references/skill_architecture_inquiry.md +63 -63
- package/.agents/skills/agentic-architect/references/skill_template.md +56 -56
- package/.agents/skills/agentic-architect/scripts/validate_agentic_configs.sh +402 -402
- package/.agents/skills/clean-code-refactor/SKILL.md +91 -91
- package/.agents/skills/clean-code-refactor/references/clean_code_smells.md +27 -27
- package/.agents/skills/clean-code-refactor/references/design_patterns_ts.md +65 -65
- package/.agents/skills/compliance-audit/SKILL.md +120 -120
- package/.agents/skills/compliance-audit/references/owasp_top10_controls.md +16 -16
- package/.agents/skills/compliance-audit/references/soc2_iso_controls.md +28 -28
- package/.agents/skills/lets-build/SKILL.md +173 -173
- package/.agents/skills/lets-build/references/architecture_interview_matrix.md +115 -115
- package/.agents/skills/lets-build/references/hexagonal_bootstrap_scaffolds.md +160 -160
- package/.agents/skills/lets-build/references/project_readme_template.md +79 -79
- package/.agents/skills/lets-build/scripts/bootstrap_workspace.sh +419 -255
- package/.agents/skills/product-analyst/SKILL.md +154 -154
- package/.agents/skills/product-analyst/references/backlog_ordering_techniques.md +107 -107
- package/.agents/skills/product-analyst/references/gherkin_patterns.md +46 -46
- package/.agents/skills/product-analyst/references/invest_checklist.md +38 -38
- package/.agents/skills/product-analyst/references/okr_alignment_guide.md +76 -76
- package/.agents/skills/product-analyst/references/smart_tasks.md +59 -59
- package/.agents/skills/relentless-questioner/SKILL.md +128 -128
- package/.agents/skills/relentless-questioner/references/adaptive_question_trees.md +102 -102
- package/.editorconfig +19 -19
- package/.github/workflows/ci.yml +167 -78
- package/.github/workflows/publish.yml +196 -0
- package/.gitignore +40 -25
- package/AGENTS.md +103 -102
- package/LICENSE +21 -21
- package/README.md +168 -165
- package/bin/azcodr.js +19 -228
- package/docs/knowledge/ubiquitous_language.md +31 -18
- package/docs/rules/agentic_configuration.md +259 -259
- package/docs/rules/api_architecture.md +179 -179
- package/docs/rules/authentication.md +76 -76
- package/docs/rules/authorization.md +75 -75
- package/docs/rules/caching.md +69 -69
- package/docs/rules/clean_code.md +62 -62
- package/docs/rules/cloud_native.md +41 -41
- package/docs/rules/cqrs.md +203 -203
- package/docs/rules/database_design.md +125 -125
- package/docs/rules/database_operations.md +69 -69
- package/docs/rules/design_patterns.md +98 -98
- package/docs/rules/devops_ci_cd.md +76 -76
- package/docs/rules/domain_driven_design.md +122 -122
- package/docs/rules/error_handling.md +54 -52
- package/docs/rules/feature_flags.md +59 -59
- package/docs/rules/frontend_architecture.md +157 -157
- package/docs/rules/multitenancy_architecture.md +98 -98
- package/docs/rules/product_ownership.md +127 -127
- package/docs/rules/project_management.md +49 -49
- package/docs/rules/relentless_questioning.md +52 -52
- package/docs/rules/requirements_engineering.md +98 -98
- package/docs/rules/security_compliance.md +53 -53
- package/docs/rules/server_driven_ui.md +88 -88
- package/docs/rules/test_driven_development.md +185 -185
- package/docs/rules/transactional_email.md +27 -27
- package/docs/rules/type_safety.md +65 -65
- package/docs/rules/ui_ux_architecture.md +150 -150
- package/docs/rules/workflow_state_machines.md +117 -117
- package/lib/cli-parse.d.ts +32 -0
- package/lib/cli-parse.d.ts.map +1 -0
- package/lib/cli-parse.js +55 -0
- package/lib/cli-parse.js.map +1 -0
- package/lib/cli-target.d.ts +66 -0
- package/lib/cli-target.d.ts.map +1 -0
- package/lib/cli-target.js +102 -0
- package/lib/cli-target.js.map +1 -0
- package/lib/cli.d.ts +40 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +166 -0
- package/lib/cli.js.map +1 -0
- package/lib/errors.d.ts +39 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +26 -0
- package/lib/errors.js.map +1 -0
- package/lib/git.d.ts +15 -0
- package/lib/git.d.ts.map +1 -0
- package/lib/git.js +32 -0
- package/lib/git.js.map +1 -0
- package/lib/guards.d.ts +35 -0
- package/lib/guards.d.ts.map +1 -0
- package/lib/guards.js +95 -0
- package/lib/guards.js.map +1 -0
- package/lib/index.d.ts +6 -134
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +4 -5
- package/lib/index.js.map +1 -0
- package/lib/links.d.ts +28 -0
- package/lib/links.d.ts.map +1 -0
- package/lib/links.js +129 -0
- package/lib/links.js.map +1 -0
- package/lib/permissions.d.ts +9 -0
- package/lib/permissions.d.ts.map +1 -0
- package/lib/permissions.js +44 -0
- package/lib/permissions.js.map +1 -0
- package/lib/repo.d.ts +20 -0
- package/lib/repo.d.ts.map +1 -0
- package/lib/repo.js +92 -0
- package/lib/repo.js.map +1 -0
- package/lib/scaffold.d.ts +80 -0
- package/lib/scaffold.d.ts.map +1 -0
- package/lib/scaffold.js +201 -448
- package/lib/scaffold.js.map +1 -0
- package/memory.md +135 -36
- package/package.json +75 -62
- package/scripts/test_coverage.js +66 -38
- package/scripts/validate/adr.js +155 -0
- package/scripts/validate/io.js +82 -0
- package/scripts/validate/links.js +166 -0
- package/scripts/validate/parity.js +122 -0
- package/scripts/validate/root.js +183 -0
- package/scripts/validate/rules.js +42 -0
- package/scripts/validate/skills.js +94 -0
- package/scripts/validate/text.js +27 -0
- package/scripts/validate-cli.js +12 -0
- package/scripts/validate.js +158 -258
- package/src/cli-parse.ts +77 -0
- package/src/cli-target.ts +167 -0
- package/src/cli.ts +240 -0
- package/src/errors.ts +35 -0
- package/src/git.ts +34 -0
- package/src/guards.ts +101 -0
- package/src/index.ts +39 -0
- package/src/links.ts +139 -0
- package/src/permissions.ts +42 -0
- package/src/repo.ts +94 -0
- package/src/scaffold.ts +273 -0
- package/.github/copilot-instructions.md +0 -1
|
@@ -1,255 +1,419 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# ==============================================================================
|
|
3
|
-
# bootstrap_workspace.sh
|
|
4
|
-
# Topology-Aware Deterministic Scaffolder (Strict YAGNI, Zero Speculative Bloat)
|
|
5
|
-
# ==============================================================================
|
|
6
|
-
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
WORKSPACE_ROOT="${1:-$(pwd)}"
|
|
10
|
-
TOPOLOGY="${2:-backend}"
|
|
11
|
-
LANGUAGE="${3:-generic}"
|
|
12
|
-
|
|
13
|
-
echo "🚀 Initializing Topology-Aware Workspace in: ${WORKSPACE_ROOT}"
|
|
14
|
-
echo "🏗️ Target Topology: ${TOPOLOGY}"
|
|
15
|
-
echo "📦 Target Language Profile: ${LANGUAGE}"
|
|
16
|
-
echo "--------------------------------------------------------------"
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
create_leaf "${WORKSPACE_ROOT}/src/
|
|
121
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
125
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
create_leaf "${WORKSPACE_ROOT}/tests/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
"
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
create_leaf "${WORKSPACE_ROOT}/src/
|
|
166
|
-
create_leaf "${WORKSPACE_ROOT}/src/
|
|
167
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
create_leaf "${WORKSPACE_ROOT}/tests/
|
|
177
|
-
create_leaf "${WORKSPACE_ROOT}/tests/
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
create_leaf "${WORKSPACE_ROOT}/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# bootstrap_workspace.sh
|
|
4
|
+
# Topology-Aware Deterministic Scaffolder (Strict YAGNI, Zero Speculative Bloat)
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
WORKSPACE_ROOT="${1:-$(pwd)}"
|
|
10
|
+
TOPOLOGY="${2:-backend}"
|
|
11
|
+
LANGUAGE="${3:-generic}"
|
|
12
|
+
|
|
13
|
+
echo "🚀 Initializing Topology-Aware Workspace in: ${WORKSPACE_ROOT}"
|
|
14
|
+
echo "🏗️ Target Topology: ${TOPOLOGY}"
|
|
15
|
+
echo "📦 Target Language Profile: ${LANGUAGE}"
|
|
16
|
+
echo "--------------------------------------------------------------"
|
|
17
|
+
|
|
18
|
+
# ------------------------------------------------------------------------------
|
|
19
|
+
# LANGUAGE is validated, not merely echoed. It previously appeared in the
|
|
20
|
+
# banner and nowhere else: every language produced an identical tree, which
|
|
21
|
+
# made the "deterministic scaffolder" claim false and hid typos from the agent.
|
|
22
|
+
# Unknown values are rejected instead of silently producing a generic layout.
|
|
23
|
+
# ------------------------------------------------------------------------------
|
|
24
|
+
case "${LANGUAGE}" in
|
|
25
|
+
typescript|javascript|python|rust|go|java|csharp|cpp|c|generic|deno|bun)
|
|
26
|
+
;;
|
|
27
|
+
*)
|
|
28
|
+
echo "❌ Unknown language profile: '${LANGUAGE}'" >&2
|
|
29
|
+
cat >&2 << 'EOF'
|
|
30
|
+
|
|
31
|
+
Supported language profiles:
|
|
32
|
+
typescript javascript deno bun python rust go java csharp cpp c
|
|
33
|
+
generic
|
|
34
|
+
|
|
35
|
+
Use 'generic' when the language has not been decided yet.
|
|
36
|
+
EOF
|
|
37
|
+
exit 2
|
|
38
|
+
;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
# ------------------------------------------------------------------------------
|
|
42
|
+
# PROTECTED TARGETS. The scaffolder creates directories and files, so it must
|
|
43
|
+
# never run against the filesystem root, the user's home directory, or the
|
|
44
|
+
# home directory's parent (scaffolding into /home or C:\Users affects every
|
|
45
|
+
# user on the machine). This mirrors lib/scaffold.js isProtectedTarget(), which
|
|
46
|
+
# enforces the same rule -- plus template-ancestor and symlink checks -- for
|
|
47
|
+
# the Node scaffolder with E_TARGET_IS_PROTECTED.
|
|
48
|
+
#
|
|
49
|
+
# The check runs BEFORE anything is created: even the .azcodr profile write
|
|
50
|
+
# below must not execute for a protected target.
|
|
51
|
+
# ------------------------------------------------------------------------------
|
|
52
|
+
resolve_absolute() {
|
|
53
|
+
local p="$1"
|
|
54
|
+
if [[ -e "$p" ]]; then
|
|
55
|
+
(cd "$p" 2>/dev/null && pwd -P)
|
|
56
|
+
elif [[ -d "$(dirname "$p")" ]]; then
|
|
57
|
+
printf '%s/%s' "$(cd "$(dirname "$p")" 2>/dev/null && pwd -P)" "$(basename "$p")"
|
|
58
|
+
elif [[ "$p" = /* ]]; then
|
|
59
|
+
printf '%s' "$p"
|
|
60
|
+
else
|
|
61
|
+
printf '%s/%s' "$(pwd -P)" "$p"
|
|
62
|
+
fi
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
lowercase() {
|
|
66
|
+
# ${var,,} needs bash 4+; macOS ships bash 3.2, so use tr.
|
|
67
|
+
printf '%s' "$1" | tr '[:upper:]' '[:lower:]'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
RESOLVED_ROOT="$(resolve_absolute "${WORKSPACE_ROOT}")"
|
|
71
|
+
RESOLVED_HOME="$(resolve_absolute "${HOME:-/nonexistent-home}")"
|
|
72
|
+
LOWER_ROOT="$(lowercase "${RESOLVED_ROOT}")"
|
|
73
|
+
LOWER_HOME="$(lowercase "${RESOLVED_HOME}")"
|
|
74
|
+
HOME_PARENT="$(dirname "${RESOLVED_HOME}")"
|
|
75
|
+
LOWER_HOME_PARENT="$(lowercase "${HOME_PARENT}")"
|
|
76
|
+
|
|
77
|
+
PROTECTED_REASON=""
|
|
78
|
+
if [[ "${RESOLVED_ROOT}" == "/" ]]; then
|
|
79
|
+
PROTECTED_REASON="the filesystem root"
|
|
80
|
+
elif [[ "${RESOLVED_ROOT}" =~ ^/[a-zA-Z]$ ]]; then
|
|
81
|
+
# Git-Bash drive root (/c, /d, ...).
|
|
82
|
+
PROTECTED_REASON="a drive root"
|
|
83
|
+
elif [[ "$RESOLVED_ROOT" =~ ^[a-zA-Z]:[\\/]?$ ]]; then
|
|
84
|
+
# Native Windows drive root (C:\, D:).
|
|
85
|
+
PROTECTED_REASON="a drive root"
|
|
86
|
+
elif [[ "${LOWER_ROOT}" == "${LOWER_HOME}" ]]; then
|
|
87
|
+
PROTECTED_REASON="the home directory (${RESOLVED_HOME})"
|
|
88
|
+
elif [[ "${LOWER_ROOT}" == "${LOWER_HOME_PARENT}" ]]; then
|
|
89
|
+
PROTECTED_REASON="the home directory's parent (${HOME_PARENT})"
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if [[ -n "${PROTECTED_REASON}" && "${AZCODR_ALLOW_PROTECTED:-0}" != "1" ]]; then
|
|
93
|
+
echo "❌ Refusing to scaffold into protected directory: ${RESOLVED_ROOT} (${PROTECTED_REASON})." >&2
|
|
94
|
+
echo " Choose a project subdirectory instead." >&2
|
|
95
|
+
echo " Embedders that genuinely need this path: AZCODR_ALLOW_PROTECTED=1 <this command>" >&2
|
|
96
|
+
exit 2
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# Record the decided language so downstream phases can read it instead of
|
|
100
|
+
# re-deriving it (and so the scaffolder's own claim is verifiable).
|
|
101
|
+
mkdir -p "${WORKSPACE_ROOT}/.azcodr"
|
|
102
|
+
printf 'topology=%s\nlanguage=%s\n' "${TOPOLOGY}" "${LANGUAGE}" \
|
|
103
|
+
> "${WORKSPACE_ROOT}/.azcodr/workspace-profile.env"
|
|
104
|
+
|
|
105
|
+
# Helper to create leaf directory with .gitkeep to ensure Git tracks empty structures
|
|
106
|
+
create_leaf() {
|
|
107
|
+
local dir="$1"
|
|
108
|
+
mkdir -p "${dir}"
|
|
109
|
+
if [[ -z "$(ls -A "${dir}" 2>/dev/null)" ]]; then
|
|
110
|
+
touch "${dir}/.gitkeep"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
case "${TOPOLOGY}" in
|
|
115
|
+
extension)
|
|
116
|
+
echo "1. Scaffolding Browser Extension Source Tree (src/)..."
|
|
117
|
+
create_leaf "${WORKSPACE_ROOT}/src/background"
|
|
118
|
+
create_leaf "${WORKSPACE_ROOT}/src/content"
|
|
119
|
+
create_leaf "${WORKSPACE_ROOT}/src/popup"
|
|
120
|
+
create_leaf "${WORKSPACE_ROOT}/src/shared"
|
|
121
|
+
create_leaf "${WORKSPACE_ROOT}/public"
|
|
122
|
+
|
|
123
|
+
echo "2. Scaffolding Extension Test Suites (tests/)..."
|
|
124
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
125
|
+
create_leaf "${WORKSPACE_ROOT}/tests/e2e"
|
|
126
|
+
;;
|
|
127
|
+
|
|
128
|
+
game|engine)
|
|
129
|
+
echo "1. Scaffolding Game/Engine Source Tree (src/)..."
|
|
130
|
+
create_leaf "${WORKSPACE_ROOT}/src/core"
|
|
131
|
+
create_leaf "${WORKSPACE_ROOT}/src/ecs"
|
|
132
|
+
create_leaf "${WORKSPACE_ROOT}/src/renderer"
|
|
133
|
+
create_leaf "${WORKSPACE_ROOT}/src/assets"
|
|
134
|
+
|
|
135
|
+
echo "2. Scaffolding Game/Engine Test Suites (tests/)..."
|
|
136
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
137
|
+
create_leaf "${WORKSPACE_ROOT}/tests/benchmarks"
|
|
138
|
+
;;
|
|
139
|
+
|
|
140
|
+
cli)
|
|
141
|
+
echo "1. Scaffolding CLI Source Tree (src/)..."
|
|
142
|
+
create_leaf "${WORKSPACE_ROOT}/src/cmd"
|
|
143
|
+
create_leaf "${WORKSPACE_ROOT}/src/core"
|
|
144
|
+
create_leaf "${WORKSPACE_ROOT}/src/io"
|
|
145
|
+
|
|
146
|
+
echo "2. Scaffolding CLI Test Suites (tests/)..."
|
|
147
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
148
|
+
create_leaf "${WORKSPACE_ROOT}/tests/integration"
|
|
149
|
+
;;
|
|
150
|
+
|
|
151
|
+
web|saas|fullstack)
|
|
152
|
+
echo "1. Scaffolding Backend / Enterprise Source Tree (src/)..."
|
|
153
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/entities"
|
|
154
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/value_objects"
|
|
155
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/services"
|
|
156
|
+
create_leaf "${WORKSPACE_ROOT}/src/ports/primary"
|
|
157
|
+
create_leaf "${WORKSPACE_ROOT}/src/ports/secondary"
|
|
158
|
+
create_leaf "${WORKSPACE_ROOT}/src/adapters/primary"
|
|
159
|
+
create_leaf "${WORKSPACE_ROOT}/src/adapters/secondary"
|
|
160
|
+
|
|
161
|
+
echo "2. Scaffolding Web Frontend Client Source Tree (client/)..."
|
|
162
|
+
create_leaf "${WORKSPACE_ROOT}/client/src/components/layout"
|
|
163
|
+
create_leaf "${WORKSPACE_ROOT}/client/src/components/ui"
|
|
164
|
+
create_leaf "${WORKSPACE_ROOT}/client/src/pages"
|
|
165
|
+
create_leaf "${WORKSPACE_ROOT}/client/src/hooks"
|
|
166
|
+
create_leaf "${WORKSPACE_ROOT}/client/src/services"
|
|
167
|
+
create_leaf "${WORKSPACE_ROOT}/client/public"
|
|
168
|
+
|
|
169
|
+
echo "3. Scaffolding Specifications (specs/)..."
|
|
170
|
+
create_leaf "${WORKSPACE_ROOT}/specs/openapi"
|
|
171
|
+
create_leaf "${WORKSPACE_ROOT}/specs/tokens"
|
|
172
|
+
|
|
173
|
+
echo "4. Scaffolding Fullstack Test Suites (tests/)..."
|
|
174
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
175
|
+
create_leaf "${WORKSPACE_ROOT}/tests/integration"
|
|
176
|
+
create_leaf "${WORKSPACE_ROOT}/tests/contracts"
|
|
177
|
+
create_leaf "${WORKSPACE_ROOT}/tests/client"
|
|
178
|
+
create_leaf "${WORKSPACE_ROOT}/tests/acceptance"
|
|
179
|
+
|
|
180
|
+
echo "5. Scaffolding Deployment Infrastructure (deploy/)..."
|
|
181
|
+
create_leaf "${WORKSPACE_ROOT}/deploy/docker"
|
|
182
|
+
create_leaf "${WORKSPACE_ROOT}/deploy/compose"
|
|
183
|
+
|
|
184
|
+
TOKEN_SPEC="${WORKSPACE_ROOT}/specs/tokens/tokens.json"
|
|
185
|
+
if [[ ! -f "${TOKEN_SPEC}" ]]; then
|
|
186
|
+
cat << 'EOF' > "${TOKEN_SPEC}"
|
|
187
|
+
{
|
|
188
|
+
"color": {
|
|
189
|
+
"brand": {
|
|
190
|
+
"primary": { "$value": "#2563eb", "$type": "color" },
|
|
191
|
+
"secondary": { "$value": "#475569", "$type": "color" },
|
|
192
|
+
"accent": { "$value": "#f59e0b", "$type": "color" }
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"dimension": {
|
|
196
|
+
"radius": {
|
|
197
|
+
"base": { "$value": "6px", "$type": "dimension" }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
EOF
|
|
202
|
+
fi
|
|
203
|
+
;;
|
|
204
|
+
|
|
205
|
+
backend)
|
|
206
|
+
echo "1. Scaffolding Headless Backend Source Tree (src/)..."
|
|
207
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/entities"
|
|
208
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/value_objects"
|
|
209
|
+
create_leaf "${WORKSPACE_ROOT}/src/domain/services"
|
|
210
|
+
create_leaf "${WORKSPACE_ROOT}/src/ports/primary"
|
|
211
|
+
create_leaf "${WORKSPACE_ROOT}/src/ports/secondary"
|
|
212
|
+
create_leaf "${WORKSPACE_ROOT}/src/adapters/primary"
|
|
213
|
+
create_leaf "${WORKSPACE_ROOT}/src/adapters/secondary"
|
|
214
|
+
|
|
215
|
+
echo "2. Scaffolding Specifications (specs/)..."
|
|
216
|
+
create_leaf "${WORKSPACE_ROOT}/specs/openapi"
|
|
217
|
+
create_leaf "${WORKSPACE_ROOT}/specs/tokens"
|
|
218
|
+
|
|
219
|
+
echo "3. Scaffolding Backend Test Suites (tests/)..."
|
|
220
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
221
|
+
create_leaf "${WORKSPACE_ROOT}/tests/integration"
|
|
222
|
+
create_leaf "${WORKSPACE_ROOT}/tests/contracts"
|
|
223
|
+
create_leaf "${WORKSPACE_ROOT}/tests/acceptance"
|
|
224
|
+
|
|
225
|
+
echo "4. Scaffolding Deployment Infrastructure (deploy/)..."
|
|
226
|
+
create_leaf "${WORKSPACE_ROOT}/deploy/docker"
|
|
227
|
+
create_leaf "${WORKSPACE_ROOT}/deploy/compose"
|
|
228
|
+
|
|
229
|
+
TOKEN_SPEC="${WORKSPACE_ROOT}/specs/tokens/tokens.json"
|
|
230
|
+
if [[ ! -f "${TOKEN_SPEC}" ]]; then
|
|
231
|
+
cat << 'EOF' > "${TOKEN_SPEC}"
|
|
232
|
+
{
|
|
233
|
+
"color": {
|
|
234
|
+
"brand": {
|
|
235
|
+
"primary": { "$value": "#2563eb", "$type": "color" },
|
|
236
|
+
"secondary": { "$value": "#475569", "$type": "color" },
|
|
237
|
+
"accent": { "$value": "#f59e0b", "$type": "color" }
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"dimension": {
|
|
241
|
+
"radius": {
|
|
242
|
+
"base": { "$value": "6px", "$type": "dimension" }
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
EOF
|
|
247
|
+
fi
|
|
248
|
+
;;
|
|
249
|
+
|
|
250
|
+
frontend)
|
|
251
|
+
echo "1. Scaffolding Frontend Client Source Tree (src/)..."
|
|
252
|
+
create_leaf "${WORKSPACE_ROOT}/src/components/layout"
|
|
253
|
+
create_leaf "${WORKSPACE_ROOT}/src/components/ui"
|
|
254
|
+
create_leaf "${WORKSPACE_ROOT}/src/pages"
|
|
255
|
+
create_leaf "${WORKSPACE_ROOT}/src/hooks"
|
|
256
|
+
create_leaf "${WORKSPACE_ROOT}/src/services"
|
|
257
|
+
create_leaf "${WORKSPACE_ROOT}/public"
|
|
258
|
+
|
|
259
|
+
echo "2. Scaffolding Specifications (specs/)..."
|
|
260
|
+
create_leaf "${WORKSPACE_ROOT}/specs/tokens"
|
|
261
|
+
|
|
262
|
+
echo "3. Scaffolding Frontend Test Suites (tests/)..."
|
|
263
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
264
|
+
create_leaf "${WORKSPACE_ROOT}/tests/acceptance"
|
|
265
|
+
;;
|
|
266
|
+
|
|
267
|
+
canvas-game|canvas|webgame)
|
|
268
|
+
# Topology D: Browser / Canvas Game (HTML5 Canvas / WebGL / WebGPU).
|
|
269
|
+
# Game Loop shaped: Input -> Update -> Render.
|
|
270
|
+
echo "1. Scaffolding Canvas Game Source Tree (game loop shaped)..."
|
|
271
|
+
create_leaf "${WORKSPACE_ROOT}/src/entities"
|
|
272
|
+
create_leaf "${WORKSPACE_ROOT}/src/systems/update"
|
|
273
|
+
create_leaf "${WORKSPACE_ROOT}/src/systems/render"
|
|
274
|
+
create_leaf "${WORKSPACE_ROOT}/src/input"
|
|
275
|
+
create_leaf "${WORKSPACE_ROOT}/src/audio"
|
|
276
|
+
create_leaf "${WORKSPACE_ROOT}/src/ui"
|
|
277
|
+
create_leaf "${WORKSPACE_ROOT}/src/scenes"
|
|
278
|
+
create_leaf "${WORKSPACE_ROOT}/src/config"
|
|
279
|
+
|
|
280
|
+
echo "2. Scaffolding Canvas Game Tests (tests/)..."
|
|
281
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
282
|
+
create_leaf "${WORKSPACE_ROOT}/tests/e2e"
|
|
283
|
+
|
|
284
|
+
echo "3. Scaffolding Public Assets (public/)..."
|
|
285
|
+
create_leaf "${WORKSPACE_ROOT}/public/assets"
|
|
286
|
+
;;
|
|
287
|
+
|
|
288
|
+
systems-library|embedded|systems)
|
|
289
|
+
# Topology F: Embedded / Systems Library.
|
|
290
|
+
# No heap assumptions, no dynamic allocation in the hot path.
|
|
291
|
+
echo "1. Scaffolding Systems Library Source Tree (src/)..."
|
|
292
|
+
create_leaf "${WORKSPACE_ROOT}/src/core"
|
|
293
|
+
create_leaf "${WORKSPACE_ROOT}/src/hal"
|
|
294
|
+
create_leaf "${WORKSPACE_ROOT}/src/drivers"
|
|
295
|
+
create_leaf "${WORKSPACE_ROOT}/src/protocol"
|
|
296
|
+
create_leaf "${WORKSPACE_ROOT}/src/utils"
|
|
297
|
+
|
|
298
|
+
echo "2. Scaffolding Systems Library Tests (tests/)..."
|
|
299
|
+
create_leaf "${WORKSPACE_ROOT}/tests/unit"
|
|
300
|
+
create_leaf "${WORKSPACE_ROOT}/tests/hal"
|
|
301
|
+
create_leaf "${WORKSPACE_ROOT}/tests/benchmarks"
|
|
302
|
+
;;
|
|
303
|
+
|
|
304
|
+
*)
|
|
305
|
+
# Fail loudly rather than scaffolding a generic tree and exiting 0. A
|
|
306
|
+
# wrong-but-successful scaffold is worse than a refusal: the agent reports
|
|
307
|
+
# success to the user and the mismatch surfaces much later.
|
|
308
|
+
echo "❌ Unknown topology: '${TOPOLOGY}'" >&2
|
|
309
|
+
cat >&2 << 'EOF'
|
|
310
|
+
|
|
311
|
+
Supported topologies:
|
|
312
|
+
extension Topology B Browser Extension (Manifest V3)
|
|
313
|
+
game|engine Topology C Game Engine / High-Performance Simulator
|
|
314
|
+
canvas-game Topology D Browser / Canvas Game (Canvas/WebGL/WebGPU)
|
|
315
|
+
cli Topology E Desktop Application / CLI Utility
|
|
316
|
+
backend Topology A Headless API / Service
|
|
317
|
+
web|saas|fullstack Topology A Fullstack Web Application
|
|
318
|
+
frontend Topology A Frontend-only Client
|
|
319
|
+
systems-library Topology F Embedded / Systems Library
|
|
320
|
+
EOF
|
|
321
|
+
echo >&2
|
|
322
|
+
echo "Re-run with one of the above." >&2
|
|
323
|
+
exit 2
|
|
324
|
+
;;
|
|
325
|
+
esac
|
|
326
|
+
|
|
327
|
+
# ------------------------------------------------------------------------------
|
|
328
|
+
# memory.md is an APPEND-ONLY LEDGER. It is never rewritten automatically.
|
|
329
|
+
#
|
|
330
|
+
# HISTORY (this was a data-loss bug): this script previously overwrote
|
|
331
|
+
# memory.md with a template whenever the file contained any ADR heading that
|
|
332
|
+
# was not the untouched placeholder. Re-running /lets-build on a live project
|
|
333
|
+
# silently destroyed every recorded architectural decision -- irreplaceable
|
|
334
|
+
# work, with no backup and no error. ADRs are immutable history by rule
|
|
335
|
+
# (docs/rules/agentic_configuration.md); a scaffolder has no business
|
|
336
|
+
# rewriting them.
|
|
337
|
+
#
|
|
338
|
+
# Resetting the ledger is now opt-in, always backed up, and always announced.
|
|
339
|
+
# ------------------------------------------------------------------------------
|
|
340
|
+
MEMORY_FILE="${WORKSPACE_ROOT}/memory.md"
|
|
341
|
+
if [[ -f "${MEMORY_FILE}" ]]; then
|
|
342
|
+
# Only a genuinely recorded decision counts as "has content": an h4 ADR
|
|
343
|
+
# heading outside of an HTML comment.
|
|
344
|
+
RECORDED_ADRS="$(grep -cE '^####[[:space:]]+ADR-[0-9]+' "${MEMORY_FILE}" 2>/dev/null || true)"
|
|
345
|
+
RECORDED_ADRS="${RECORDED_ADRS:-0}"
|
|
346
|
+
|
|
347
|
+
if [[ "${RECORDED_ADRS}" -gt 0 ]]; then
|
|
348
|
+
if [[ "${AZCODR_RESET_MEMORY:-0}" == "1" ]]; then
|
|
349
|
+
BACKUP="${MEMORY_FILE}.bak"
|
|
350
|
+
cp -p "${MEMORY_FILE}" "${BACKUP}"
|
|
351
|
+
echo "⚠️ AZCODR_RESET_MEMORY=1 -- RESETTING ${RECORDED_ADRS} recorded ADR(s) in memory.md"
|
|
352
|
+
echo " Backup written to ${BACKUP}"
|
|
353
|
+
cat << 'EOF' > "${MEMORY_FILE}"
|
|
354
|
+
# Workspace Memory, Architecture Decisions & Knowledge Hub
|
|
355
|
+
|
|
356
|
+
> **Core Purpose:** Authoritative persistent memory ledger for the workspace repository (`./`), maintaining Lightweight Architectural Decision Records (ADRs), system topologies, and living domain contracts.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 1. Quick Navigation & Knowledge Repositories
|
|
361
|
+
|
|
362
|
+
- 📖 **[Living Ubiquitous Language Glossary](./docs/knowledge/ubiquitous_language.md)**: Authoritative, single-name domain vocabulary contract.
|
|
363
|
+
- 📜 **[Lightweight ADR Master Index](#adr-master-index)**: Summary of all architectural decisions and direct links to governing rules.
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 2. Consolidated Architectural Decision Records (ADRs)
|
|
368
|
+
|
|
369
|
+
### ADR Master Index
|
|
370
|
+
|
|
371
|
+
| ID | Title | Date | Status | Governing Rule / Skill |
|
|
372
|
+
|---|---|---|---|---|
|
|
373
|
+
| *(No decisions recorded yet)* | *Record initial architecture decisions during Phase 3 of /lets-build.* | *YYYY-MM-DD* | *ACCEPTED* | *e.g. [`clean_code.md`](./docs/rules/clean_code.md)* |
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### Lightweight Decision Summaries
|
|
378
|
+
|
|
379
|
+
<!--
|
|
380
|
+
Record project Architectural Decision Records (ADRs) below as decisions are finalized.
|
|
381
|
+
Format:
|
|
382
|
+
|
|
383
|
+
#### ADR-001: [Imperative Title]
|
|
384
|
+
- **Date:** YYYY-MM-DD | **Status:** ACCEPTED
|
|
385
|
+
- **Context:** Problem space, constraints, and operational context requiring a decision.
|
|
386
|
+
- **Decision:** Chosen architecture, invariants, and implementation patterns.
|
|
387
|
+
- **Consequences:** Positive benefits and deliberate trade-offs accepted.
|
|
388
|
+
- **Enforced In:** Relevant rule files in docs/rules/ or code paths.
|
|
389
|
+
-->
|
|
390
|
+
EOF
|
|
391
|
+
else
|
|
392
|
+
echo "🧠 Preserving memory.md: ${RECORDED_ADRS} recorded ADR(s) found."
|
|
393
|
+
echo " memory.md is append-only and is never rewritten by the scaffolder."
|
|
394
|
+
echo " To intentionally reset the ledger: AZCODR_RESET_MEMORY=1 <this command>"
|
|
395
|
+
fi
|
|
396
|
+
fi
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
# Deterministically generate boundary verification smoke test script (Phase 5 requirement)
|
|
400
|
+
SMOKE_TEST="${WORKSPACE_ROOT}/scripts/smoke_test.sh"
|
|
401
|
+
if [[ ! -f "${SMOKE_TEST}" ]]; then
|
|
402
|
+
echo "5. Generating boundary smoke test verification script (scripts/smoke_test.sh)..."
|
|
403
|
+
mkdir -p "${WORKSPACE_ROOT}/scripts"
|
|
404
|
+
cat << 'EOF' > "${SMOKE_TEST}"
|
|
405
|
+
#!/usr/bin/env bash
|
|
406
|
+
# ==============================================================================
|
|
407
|
+
# Boundary Verification Smoke Test (Phase 5 Verification Gate)
|
|
408
|
+
# ==============================================================================
|
|
409
|
+
set -euo pipefail
|
|
410
|
+
|
|
411
|
+
echo "Running boundary smoke verification..."
|
|
412
|
+
# Extend with project-specific runtime health checks (e.g. ping health endpoint, CLI --help)
|
|
413
|
+
echo "✅ Boundary smoke verification passed!"
|
|
414
|
+
EOF
|
|
415
|
+
chmod +x "${SMOKE_TEST}"
|
|
416
|
+
fi
|
|
417
|
+
|
|
418
|
+
echo "--------------------------------------------------------------"
|
|
419
|
+
echo "✅ Topology '${TOPOLOGY}' scaffolded with strict YAGNI (0 speculative folders)!"
|