azcodr 1.5.0 → 1.5.2
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 -0
- package/.agents/hooks.json.example +42 -42
- package/.agents/mcp_config.json.example +29 -24
- package/.agents/scripts/safety_guard.sh +34 -16
- package/.agents/scripts/verify_completion.sh +27 -13
- 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 -362
- 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 -172
- 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 +255 -253
- 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/copilot-instructions.md +1 -0
- package/.github/workflows/ci.yml +78 -0
- package/.gitignore +25 -25
- package/AGENTS.md +102 -102
- package/LICENSE +21 -21
- package/README.md +165 -154
- package/bin/azcodr.js +228 -228
- package/data/.gitkeep +0 -0
- package/docs/knowledge/ubiquitous_language.md +18 -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 +52 -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/index.d.ts +134 -123
- package/lib/index.js +5 -5
- package/lib/scaffold.js +448 -351
- package/memory.md +36 -36
- package/package.json +62 -59
- package/scripts/test_coverage.js +38 -0
- package/scripts/validate.js +258 -0
package/bin/azcodr.js
CHANGED
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const readline = require('node:readline');
|
|
6
|
-
const fs = require('node:fs');
|
|
7
|
-
const { scaffold, getTemplateDir } = require('../lib/scaffold.js');
|
|
8
|
-
const pkg = require('../package.json');
|
|
9
|
-
|
|
10
|
-
function printHelp(out = console.log) {
|
|
11
|
-
out(`
|
|
12
|
-
azcodr v${pkg.version}
|
|
13
|
-
Enterprise Multi-Tenant Architecture & Agentic Engineering Starter Template
|
|
14
|
-
|
|
15
|
-
Usage:
|
|
16
|
-
npx azcodr [directory] [options]
|
|
17
|
-
|
|
18
|
-
Commands:
|
|
19
|
-
[directory] Scaffold azcodr template into directory (default: current directory)
|
|
20
|
-
|
|
21
|
-
Options:
|
|
22
|
-
-d, --dry-run Simulate scaffolding without modifying filesystem
|
|
23
|
-
-s, --silent Suppress console output messages
|
|
24
|
-
-f, --force Overwrite existing files in target directory without confirmation
|
|
25
|
-
--no-git Do not initialize a git repository
|
|
26
|
-
-v, --version Display version number
|
|
27
|
-
-h, --help Display this help message
|
|
28
|
-
|
|
29
|
-
Examples:
|
|
30
|
-
npx azcodr my-project
|
|
31
|
-
npx azcodr . --dry-run
|
|
32
|
-
npx azcodr . --force
|
|
33
|
-
`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function printVersion(out = console.log) {
|
|
37
|
-
out(pkg.version);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function askQuestion(query, { input = process.stdin, output = process.stdout } = {}) {
|
|
41
|
-
const rl = readline.createInterface({ input, output });
|
|
42
|
-
|
|
43
|
-
return new Promise((resolve) => {
|
|
44
|
-
let resolved = false;
|
|
45
|
-
rl.question(query, (answer) => {
|
|
46
|
-
if (!resolved) {
|
|
47
|
-
resolved = true;
|
|
48
|
-
rl.close();
|
|
49
|
-
resolve(answer.trim());
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
rl.on('close', () => {
|
|
53
|
-
if (!resolved) {
|
|
54
|
-
resolved = true;
|
|
55
|
-
resolve('');
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function runCli(rawArgs = process.argv.slice(2), io = {}) {
|
|
62
|
-
const {
|
|
63
|
-
out = console.log,
|
|
64
|
-
err = console.error,
|
|
65
|
-
exit = process.exit,
|
|
66
|
-
stdin = process.stdin,
|
|
67
|
-
stdout = process.stdout,
|
|
68
|
-
cwd = process.cwd(),
|
|
69
|
-
templateDir = getTemplateDir(),
|
|
70
|
-
scaffold: scaffoldFn = scaffold
|
|
71
|
-
} = io;
|
|
72
|
-
|
|
73
|
-
let targetDir = null;
|
|
74
|
-
let force = false;
|
|
75
|
-
let noGit = false;
|
|
76
|
-
let dryRun = false;
|
|
77
|
-
let silent = false;
|
|
78
|
-
|
|
79
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
80
|
-
const arg = rawArgs[i];
|
|
81
|
-
if (arg === '-h' || arg === '--help') {
|
|
82
|
-
printHelp(out);
|
|
83
|
-
return exit(0);
|
|
84
|
-
} else if (arg === '-v' || arg === '--version') {
|
|
85
|
-
printVersion(out);
|
|
86
|
-
return exit(0);
|
|
87
|
-
} else if (arg === '-f' || arg === '--force') {
|
|
88
|
-
force = true;
|
|
89
|
-
} else if (arg === '--no-git') {
|
|
90
|
-
noGit = true;
|
|
91
|
-
} else if (arg === '-d' || arg === '--dry-run') {
|
|
92
|
-
dryRun = true;
|
|
93
|
-
} else if (arg === '-s' || arg === '--silent') {
|
|
94
|
-
silent = true;
|
|
95
|
-
} else if (arg.startsWith('-')) {
|
|
96
|
-
err(`❌ Error: Unknown argument '${arg}'. Run 'npx azcodr --help' for available options.`);
|
|
97
|
-
return exit(1);
|
|
98
|
-
} else if (!targetDir) {
|
|
99
|
-
targetDir = arg;
|
|
100
|
-
} else {
|
|
101
|
-
err(`❌ Error: Unexpected argument '${arg}'. Run 'npx azcodr --help' for available options.`);
|
|
102
|
-
return exit(1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (!silent) {
|
|
107
|
-
out('\n🚀 azcodr - Enterprise Multi-Tenant Architecture & Agentic Engineering\n');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (!targetDir) {
|
|
111
|
-
if (stdin.isTTY) {
|
|
112
|
-
const answer = await askQuestion('? Where would you like to initialize your project? (./) ', {
|
|
113
|
-
input: stdin,
|
|
114
|
-
output: stdout
|
|
115
|
-
});
|
|
116
|
-
targetDir = answer || '.';
|
|
117
|
-
} else {
|
|
118
|
-
targetDir = '.';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const resolvedTarget = path.resolve(cwd, targetDir);
|
|
123
|
-
|
|
124
|
-
if (resolvedTarget === templateDir) {
|
|
125
|
-
err(`❌ Error: Cannot scaffold into the template directory itself: ${resolvedTarget}`);
|
|
126
|
-
return exit(1);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (fs.existsSync(resolvedTarget)) {
|
|
130
|
-
const stat = fs.statSync(resolvedTarget);
|
|
131
|
-
if (!stat.isDirectory()) {
|
|
132
|
-
err(`❌ Error: Target '${resolvedTarget}' already exists and is not a directory.`);
|
|
133
|
-
return exit(1);
|
|
134
|
-
}
|
|
135
|
-
const entries = fs.readdirSync(resolvedTarget);
|
|
136
|
-
if (entries.length > 0 && !force) {
|
|
137
|
-
if (stdin.isTTY) {
|
|
138
|
-
const confirm = await askQuestion(
|
|
139
|
-
`⚠️ Target directory '${targetDir}' is not empty (${entries.length} items). Continue? (y/N) `,
|
|
140
|
-
{ input: stdin, output: stdout }
|
|
141
|
-
);
|
|
142
|
-
if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
|
|
143
|
-
out('Scaffolding aborted.');
|
|
144
|
-
return exit(0);
|
|
145
|
-
}
|
|
146
|
-
force = true;
|
|
147
|
-
} else {
|
|
148
|
-
err(`❌ Error: Target directory '${resolvedTarget}' is not empty. Use --force to proceed.`);
|
|
149
|
-
return exit(1);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (dryRun) {
|
|
155
|
-
if (!silent) {
|
|
156
|
-
out(`🔍 DRY RUN: Simulating azcodr scaffolding into: ${resolvedTarget}\n`);
|
|
157
|
-
}
|
|
158
|
-
} else if (!silent) {
|
|
159
|
-
out(`📦 Scaffolding azcodr into: ${resolvedTarget}`);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
try {
|
|
163
|
-
const result = scaffoldFn({
|
|
164
|
-
targetDir: resolvedTarget,
|
|
165
|
-
force,
|
|
166
|
-
noGit,
|
|
167
|
-
templateDir,
|
|
168
|
-
dryRun,
|
|
169
|
-
silent
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
if (dryRun) {
|
|
173
|
-
if (!silent) {
|
|
174
|
-
for (const action of result.actions) {
|
|
175
|
-
out(` [preview] ${action}`);
|
|
176
|
-
}
|
|
177
|
-
out('\n🎉 Dry run completed. 0 files modified on disk.\n');
|
|
178
|
-
}
|
|
179
|
-
return exit(0);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (!silent) {
|
|
183
|
-
out(' ✅ Progressive disclosure rules copied (docs/rules/)');
|
|
184
|
-
out(' ✅ Workspace knowledge hub and ADR ledger copied (docs/knowledge/, memory.md)');
|
|
185
|
-
out(' ✅ Specialized agentic skills copied (.agents/skills/)');
|
|
186
|
-
out(' ✅ Editor formatting standards initialized (.editorconfig)');
|
|
187
|
-
out(' ✅ Agent directives and harness symlinks established (AGENTS.md, CLAUDE.md, agents.md, GEMINI.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md)');
|
|
188
|
-
out(' ✅ Project configuration initialized (package.json)');
|
|
189
|
-
if (result.gitInitialized) {
|
|
190
|
-
out(' ✅ Git repository initialized');
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
out('\n🎉 azcodr initialized successfully!\n');
|
|
194
|
-
out('Next steps:');
|
|
195
|
-
let step = 1;
|
|
196
|
-
if (targetDir !== '.' && targetDir !== './') {
|
|
197
|
-
out(` ${step++}. cd ${targetDir}`);
|
|
198
|
-
}
|
|
199
|
-
out(` ${step++}. Open the project in your AI coding assistant (Antigravity, Claude Code, Cursor, OpenHands)`);
|
|
200
|
-
out(` ${step++}. Run /lets-build to start the architectural interview and scaffold your application stack!\n`);
|
|
201
|
-
}
|
|
202
|
-
return exit(0);
|
|
203
|
-
} catch (error) {
|
|
204
|
-
err(`\n❌ Scaffolding failed: ${error.message}\n`);
|
|
205
|
-
return exit(1);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async function main() {
|
|
210
|
-
try {
|
|
211
|
-
await runCli(process.argv.slice(2));
|
|
212
|
-
} catch (err) {
|
|
213
|
-
console.error('Unexpected error:', err);
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (require.main === module) {
|
|
219
|
-
main();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
module.exports = {
|
|
223
|
-
runCli,
|
|
224
|
-
askQuestion,
|
|
225
|
-
printHelp,
|
|
226
|
-
printVersion,
|
|
227
|
-
main
|
|
228
|
-
};
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const readline = require('node:readline');
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const { scaffold, getTemplateDir } = require('../lib/scaffold.js');
|
|
8
|
+
const pkg = require('../package.json');
|
|
9
|
+
|
|
10
|
+
function printHelp(out = console.log) {
|
|
11
|
+
out(`
|
|
12
|
+
azcodr v${pkg.version}
|
|
13
|
+
Enterprise Multi-Tenant Architecture & Agentic Engineering Starter Template
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
npx azcodr [directory] [options]
|
|
17
|
+
|
|
18
|
+
Commands:
|
|
19
|
+
[directory] Scaffold azcodr template into directory (default: current directory)
|
|
20
|
+
|
|
21
|
+
Options:
|
|
22
|
+
-d, --dry-run Simulate scaffolding without modifying filesystem
|
|
23
|
+
-s, --silent Suppress console output messages
|
|
24
|
+
-f, --force Overwrite existing files in target directory without confirmation
|
|
25
|
+
--no-git Do not initialize a git repository
|
|
26
|
+
-v, --version Display version number
|
|
27
|
+
-h, --help Display this help message
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
npx azcodr my-project
|
|
31
|
+
npx azcodr . --dry-run
|
|
32
|
+
npx azcodr . --force
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function printVersion(out = console.log) {
|
|
37
|
+
out(pkg.version);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function askQuestion(query, { input = process.stdin, output = process.stdout } = {}) {
|
|
41
|
+
const rl = readline.createInterface({ input, output });
|
|
42
|
+
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
let resolved = false;
|
|
45
|
+
rl.question(query, (answer) => {
|
|
46
|
+
if (!resolved) {
|
|
47
|
+
resolved = true;
|
|
48
|
+
rl.close();
|
|
49
|
+
resolve(answer.trim());
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
rl.on('close', () => {
|
|
53
|
+
if (!resolved) {
|
|
54
|
+
resolved = true;
|
|
55
|
+
resolve('');
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function runCli(rawArgs = process.argv.slice(2), io = {}) {
|
|
62
|
+
const {
|
|
63
|
+
out = console.log,
|
|
64
|
+
err = console.error,
|
|
65
|
+
exit = process.exit,
|
|
66
|
+
stdin = process.stdin,
|
|
67
|
+
stdout = process.stdout,
|
|
68
|
+
cwd = process.cwd(),
|
|
69
|
+
templateDir = getTemplateDir(),
|
|
70
|
+
scaffold: scaffoldFn = scaffold
|
|
71
|
+
} = io;
|
|
72
|
+
|
|
73
|
+
let targetDir = null;
|
|
74
|
+
let force = false;
|
|
75
|
+
let noGit = false;
|
|
76
|
+
let dryRun = false;
|
|
77
|
+
let silent = false;
|
|
78
|
+
|
|
79
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
80
|
+
const arg = rawArgs[i];
|
|
81
|
+
if (arg === '-h' || arg === '--help') {
|
|
82
|
+
printHelp(out);
|
|
83
|
+
return exit(0);
|
|
84
|
+
} else if (arg === '-v' || arg === '--version') {
|
|
85
|
+
printVersion(out);
|
|
86
|
+
return exit(0);
|
|
87
|
+
} else if (arg === '-f' || arg === '--force') {
|
|
88
|
+
force = true;
|
|
89
|
+
} else if (arg === '--no-git') {
|
|
90
|
+
noGit = true;
|
|
91
|
+
} else if (arg === '-d' || arg === '--dry-run') {
|
|
92
|
+
dryRun = true;
|
|
93
|
+
} else if (arg === '-s' || arg === '--silent') {
|
|
94
|
+
silent = true;
|
|
95
|
+
} else if (arg.startsWith('-')) {
|
|
96
|
+
err(`❌ Error: Unknown argument '${arg}'. Run 'npx azcodr --help' for available options.`);
|
|
97
|
+
return exit(1);
|
|
98
|
+
} else if (!targetDir) {
|
|
99
|
+
targetDir = arg;
|
|
100
|
+
} else {
|
|
101
|
+
err(`❌ Error: Unexpected argument '${arg}'. Run 'npx azcodr --help' for available options.`);
|
|
102
|
+
return exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!silent) {
|
|
107
|
+
out('\n🚀 azcodr - Enterprise Multi-Tenant Architecture & Agentic Engineering\n');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!targetDir) {
|
|
111
|
+
if (stdin.isTTY) {
|
|
112
|
+
const answer = await askQuestion('? Where would you like to initialize your project? (./) ', {
|
|
113
|
+
input: stdin,
|
|
114
|
+
output: stdout
|
|
115
|
+
});
|
|
116
|
+
targetDir = answer || '.';
|
|
117
|
+
} else {
|
|
118
|
+
targetDir = '.';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const resolvedTarget = path.resolve(cwd, targetDir);
|
|
123
|
+
|
|
124
|
+
if (resolvedTarget === templateDir) {
|
|
125
|
+
err(`❌ Error: Cannot scaffold into the template directory itself: ${resolvedTarget}`);
|
|
126
|
+
return exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (fs.existsSync(resolvedTarget)) {
|
|
130
|
+
const stat = fs.statSync(resolvedTarget);
|
|
131
|
+
if (!stat.isDirectory()) {
|
|
132
|
+
err(`❌ Error: Target '${resolvedTarget}' already exists and is not a directory.`);
|
|
133
|
+
return exit(1);
|
|
134
|
+
}
|
|
135
|
+
const entries = fs.readdirSync(resolvedTarget);
|
|
136
|
+
if (entries.length > 0 && !force) {
|
|
137
|
+
if (stdin.isTTY) {
|
|
138
|
+
const confirm = await askQuestion(
|
|
139
|
+
`⚠️ Target directory '${targetDir}' is not empty (${entries.length} items). Continue? (y/N) `,
|
|
140
|
+
{ input: stdin, output: stdout }
|
|
141
|
+
);
|
|
142
|
+
if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
|
|
143
|
+
out('Scaffolding aborted.');
|
|
144
|
+
return exit(0);
|
|
145
|
+
}
|
|
146
|
+
force = true;
|
|
147
|
+
} else {
|
|
148
|
+
err(`❌ Error: Target directory '${resolvedTarget}' is not empty. Use --force to proceed.`);
|
|
149
|
+
return exit(1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (dryRun) {
|
|
155
|
+
if (!silent) {
|
|
156
|
+
out(`🔍 DRY RUN: Simulating azcodr scaffolding into: ${resolvedTarget}\n`);
|
|
157
|
+
}
|
|
158
|
+
} else if (!silent) {
|
|
159
|
+
out(`📦 Scaffolding azcodr into: ${resolvedTarget}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
const result = scaffoldFn({
|
|
164
|
+
targetDir: resolvedTarget,
|
|
165
|
+
force,
|
|
166
|
+
noGit,
|
|
167
|
+
templateDir,
|
|
168
|
+
dryRun,
|
|
169
|
+
silent
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
if (dryRun) {
|
|
173
|
+
if (!silent) {
|
|
174
|
+
for (const action of result.actions) {
|
|
175
|
+
out(` [preview] ${action}`);
|
|
176
|
+
}
|
|
177
|
+
out('\n🎉 Dry run completed. 0 files modified on disk.\n');
|
|
178
|
+
}
|
|
179
|
+
return exit(0);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!silent) {
|
|
183
|
+
out(' ✅ Progressive disclosure rules copied (docs/rules/)');
|
|
184
|
+
out(' ✅ Workspace knowledge hub and ADR ledger copied (docs/knowledge/, memory.md)');
|
|
185
|
+
out(' ✅ Specialized agentic skills copied (.agents/skills/)');
|
|
186
|
+
out(' ✅ Editor formatting standards initialized (.editorconfig)');
|
|
187
|
+
out(' ✅ Agent directives and harness symlinks established (AGENTS.md, CLAUDE.md, agents.md, GEMINI.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md)');
|
|
188
|
+
out(' ✅ Project configuration initialized (package.json)');
|
|
189
|
+
if (result.gitInitialized) {
|
|
190
|
+
out(' ✅ Git repository initialized');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
out('\n🎉 azcodr initialized successfully!\n');
|
|
194
|
+
out('Next steps:');
|
|
195
|
+
let step = 1;
|
|
196
|
+
if (targetDir !== '.' && targetDir !== './') {
|
|
197
|
+
out(` ${step++}. cd ${targetDir}`);
|
|
198
|
+
}
|
|
199
|
+
out(` ${step++}. Open the project in your AI coding assistant (Antigravity, Claude Code, Cursor, OpenHands)`);
|
|
200
|
+
out(` ${step++}. Run /lets-build to start the architectural interview and scaffold your application stack!\n`);
|
|
201
|
+
}
|
|
202
|
+
return exit(0);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
err(`\n❌ Scaffolding failed: ${error.message}\n`);
|
|
205
|
+
return exit(1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async function main() {
|
|
210
|
+
try {
|
|
211
|
+
await runCli(process.argv.slice(2));
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.error('Unexpected error:', err);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (require.main === module) {
|
|
219
|
+
main();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
module.exports = {
|
|
223
|
+
runCli,
|
|
224
|
+
askQuestion,
|
|
225
|
+
printHelp,
|
|
226
|
+
printVersion,
|
|
227
|
+
main
|
|
228
|
+
};
|
package/data/.gitkeep
ADDED
|
File without changes
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
# Living Ubiquitous Language Glossary Template
|
|
2
|
-
|
|
3
|
-
> **Source of Truth:** Authoritative terminology dictionary binding domain concepts, business definitions, and exact code identifiers. Customize this glossary per project.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Canonical Domain Vocabulary Matrix
|
|
8
|
-
|
|
9
|
-
| Canonical Term | Business Definition | Bounded Context | Forbidden Synonyms | Code & Database Identifiers |
|
|
10
|
-
|---|---|---|---|---|
|
|
11
|
-
| *(No domain terms defined yet)* | *Define business meaning during Phase 1 Domain Discovery.* | *e.g. Core Domain* | *Synonyms strictly forbidden across code & UI.* | *Exact type, class, or table name.* |
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Linguistic Invariants & Rules
|
|
16
|
-
1. **The Single Name Rule:** Every domain concept has exactly one authoritative name. Synonyms are strictly forbidden across code, schemas, and UI.
|
|
17
|
-
2. **Contextual Boundaries:** If a word has multiple meanings across business departments, isolate the terms within dedicated Bounded Contexts.
|
|
18
|
-
3. **Continuous Updating:** When domain experts establish or rename a term, update this glossary immediately, record an ADR in `memory.md`, and refactor all occurrences.
|
|
1
|
+
# Living Ubiquitous Language Glossary Template
|
|
2
|
+
|
|
3
|
+
> **Source of Truth:** Authoritative terminology dictionary binding domain concepts, business definitions, and exact code identifiers. Customize this glossary per project.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Canonical Domain Vocabulary Matrix
|
|
8
|
+
|
|
9
|
+
| Canonical Term | Business Definition | Bounded Context | Forbidden Synonyms | Code & Database Identifiers |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| *(No domain terms defined yet)* | *Define business meaning during Phase 1 Domain Discovery.* | *e.g. Core Domain* | *Synonyms strictly forbidden across code & UI.* | *Exact type, class, or table name.* |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Linguistic Invariants & Rules
|
|
16
|
+
1. **The Single Name Rule:** Every domain concept has exactly one authoritative name. Synonyms are strictly forbidden across code, schemas, and UI.
|
|
17
|
+
2. **Contextual Boundaries:** If a word has multiple meanings across business departments, isolate the terms within dedicated Bounded Contexts.
|
|
18
|
+
3. **Continuous Updating:** When domain experts establish or rename a term, update this glossary immediately, record an ADR in `memory.md`, and refactor all occurrences.
|