dhurandhar 1.0.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.
Files changed (54) hide show
  1. package/.dhurandhar-session-start.md +242 -0
  2. package/LICENSE +21 -0
  3. package/README.md +416 -0
  4. package/docs/ARCHITECTURE_V2.md +249 -0
  5. package/docs/DECISION_REGISTRY.md +357 -0
  6. package/docs/IMPLEMENTATION_PERSONAS.md +406 -0
  7. package/docs/PLUGGABLE_STRATEGIES.md +439 -0
  8. package/docs/SYSTEM_OBSERVER.md +433 -0
  9. package/docs/TEST_FIRST_AGILE.md +359 -0
  10. package/docs/architecture.md +279 -0
  11. package/docs/engineering-first-philosophy.md +263 -0
  12. package/docs/getting-started.md +218 -0
  13. package/docs/module-development.md +323 -0
  14. package/docs/strategy-example.md +299 -0
  15. package/docs/test-first-example.md +392 -0
  16. package/package.json +79 -0
  17. package/src/core/README.md +92 -0
  18. package/src/core/agent-instructions/backend-developer.md +412 -0
  19. package/src/core/agent-instructions/devops-engineer.md +372 -0
  20. package/src/core/agent-instructions/dhurandhar-council.md +547 -0
  21. package/src/core/agent-instructions/edge-case-hunter.md +322 -0
  22. package/src/core/agent-instructions/frontend-developer.md +494 -0
  23. package/src/core/agent-instructions/lead-system-architect.md +631 -0
  24. package/src/core/agent-instructions/system-observer.md +319 -0
  25. package/src/core/agent-instructions/test-architect.md +284 -0
  26. package/src/core/module.yaml +54 -0
  27. package/src/core/schemas/design-module-schema.yaml +995 -0
  28. package/src/core/schemas/system-design-map-schema.yaml +324 -0
  29. package/src/modules/example/README.md +130 -0
  30. package/src/modules/example/module.yaml +252 -0
  31. package/tools/cli/commands/audit.js +267 -0
  32. package/tools/cli/commands/config.js +113 -0
  33. package/tools/cli/commands/context.js +170 -0
  34. package/tools/cli/commands/decisions.js +398 -0
  35. package/tools/cli/commands/entity.js +218 -0
  36. package/tools/cli/commands/epic.js +125 -0
  37. package/tools/cli/commands/install.js +172 -0
  38. package/tools/cli/commands/module.js +109 -0
  39. package/tools/cli/commands/service.js +167 -0
  40. package/tools/cli/commands/story.js +225 -0
  41. package/tools/cli/commands/strategy.js +294 -0
  42. package/tools/cli/commands/test.js +277 -0
  43. package/tools/cli/commands/validate.js +107 -0
  44. package/tools/cli/dhurandhar.js +212 -0
  45. package/tools/lib/config-manager.js +170 -0
  46. package/tools/lib/filesystem.js +126 -0
  47. package/tools/lib/module-installer.js +61 -0
  48. package/tools/lib/module-manager.js +149 -0
  49. package/tools/lib/sdm-manager.js +982 -0
  50. package/tools/lib/test-engine.js +255 -0
  51. package/tools/lib/test-templates/api-client.template.js +100 -0
  52. package/tools/lib/test-templates/vitest.config.template.js +37 -0
  53. package/tools/lib/validators/config-validator.js +113 -0
  54. package/tools/lib/validators/module-validator.js +137 -0
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Test Command - Contract-First Testing
3
+ * Generate and validate test suites from Agile Blueprint
4
+ */
5
+
6
+ import * as clack from '@clack/prompts';
7
+ import chalk from 'chalk';
8
+ import { SDMManager } from '../../lib/sdm-manager.js';
9
+ import { ConfigManager } from '../../lib/config-manager.js';
10
+ import { TestEngine } from '../../lib/test-engine.js';
11
+ import { existsSync } from 'fs';
12
+ import { readFile, writeFile, copyFile } from 'fs/promises';
13
+ import { join } from 'path';
14
+
15
+ export async function testCommand(options) {
16
+ try {
17
+ const sdmManager = new SDMManager(process.cwd());
18
+ const configManager = new ConfigManager(process.cwd());
19
+
20
+ if (!configManager.exists()) {
21
+ clack.log.error(chalk.red('Framework not installed.'));
22
+ clack.log.info('Run: dhurandhar install');
23
+ process.exit(1);
24
+ }
25
+
26
+ if (!sdmManager.exists()) {
27
+ clack.log.error(chalk.red('SYSTEM_DESIGN_MAP.yaml not found.'));
28
+ process.exit(1);
29
+ }
30
+
31
+ const testEngine = new TestEngine(process.cwd());
32
+
33
+ if (options.generate) {
34
+ // Generate test suite from Agile Blueprint
35
+ await generateTestSuite(sdmManager, testEngine);
36
+
37
+ } else if (options.validate) {
38
+ // Validate implementation against Agile Blueprint
39
+ await validateCoverage(sdmManager, testEngine);
40
+
41
+ } else if (options.edgeCases) {
42
+ // Generate edge case tests for specific story
43
+ await generateEdgeCases(sdmManager, testEngine, options.edgeCases);
44
+
45
+ } else if (options.init) {
46
+ // Initialize test infrastructure
47
+ await initializeTestInfra(testEngine);
48
+
49
+ } else {
50
+ // Show help
51
+ console.log(chalk.cyan('Usage:'));
52
+ console.log(' dhurandhar test --init Initialize test infrastructure');
53
+ console.log(' dhurandhar test --generate Generate tests from Agile Blueprint');
54
+ console.log(' dhurandhar test --validate Validate coverage against Stories');
55
+ console.log(' dhurandhar test --edge-cases ID Generate edge cases for Story');
56
+ }
57
+
58
+ } catch (error) {
59
+ clack.log.error(chalk.red('Test operation failed:'), error.message);
60
+ process.exit(1);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Generate test suite from SDM Agile Blueprint
66
+ */
67
+ async function generateTestSuite(sdmManager, testEngine) {
68
+ clack.intro(chalk.cyan.bold('📋 Generate Contract-First Test Suite'));
69
+
70
+ const sdm = await sdmManager.load();
71
+
72
+ if (!sdm.agile_blueprint || !sdm.agile_blueprint.epics) {
73
+ clack.log.warn('No Agile Blueprint found in SDM.');
74
+ clack.log.info('Add Epics and Stories first: dhurandhar epic add');
75
+ process.exit(0);
76
+ }
77
+
78
+ const spinner = clack.spinner();
79
+ spinner.start('Generating tests from Agile Blueprint...');
80
+
81
+ // Initialize test structure
82
+ await testEngine.initializeTestStructure();
83
+
84
+ let totalTests = 0;
85
+ const generatedFiles = [];
86
+
87
+ // Iterate through all Epics and Stories
88
+ for (const epic of sdm.agile_blueprint.epics) {
89
+ for (const story of epic.stories) {
90
+ spinner.message(`Generating tests for ${story.id}: ${story.name}`);
91
+
92
+ // Generate test suite for this story
93
+ const tests = await testEngine.generateStoryTests(story, epic);
94
+
95
+ // Save tests to files
96
+ const files = await testEngine.saveTests(story, tests);
97
+ generatedFiles.push(...files);
98
+ totalTests += 3; // standard, errors, edge cases
99
+ }
100
+ }
101
+
102
+ spinner.stop(`Generated ${totalTests} test suites`);
103
+
104
+ // Copy test utilities
105
+ await copyTestUtilities();
106
+
107
+ // Generate package.json test scripts
108
+ await addTestScripts();
109
+
110
+ clack.outro(chalk.green('✓ Contract-first test suite generated'));
111
+
112
+ console.log('');
113
+ console.log(chalk.cyan('Generated files:'));
114
+ generatedFiles.slice(0, 10).forEach(file => {
115
+ console.log(` ${chalk.dim(file)}`);
116
+ });
117
+ if (generatedFiles.length > 10) {
118
+ console.log(` ${chalk.dim(`... and ${generatedFiles.length - 10} more`)}`);
119
+ }
120
+ console.log('');
121
+ console.log(chalk.cyan('Next steps:'));
122
+ console.log(' 1. Install test dependencies: npm install -D vitest');
123
+ console.log(' 2. Review generated tests in tests/ directory');
124
+ console.log(' 3. Run tests: npm test');
125
+ console.log(' 4. Implement services to pass the tests');
126
+ console.log('');
127
+ }
128
+
129
+ /**
130
+ * Validate implementation coverage against Agile Blueprint
131
+ */
132
+ async function validateCoverage(sdmManager, testEngine) {
133
+ clack.intro(chalk.cyan.bold('✅ Validate Story Coverage'));
134
+
135
+ const sdm = await sdmManager.load();
136
+
137
+ if (!sdm.agile_blueprint) {
138
+ clack.log.warn('No Agile Blueprint to validate.');
139
+ process.exit(0);
140
+ }
141
+
142
+ const results = {
143
+ total_stories: 0,
144
+ tested_stories: 0,
145
+ implemented_stories: 0,
146
+ uncovered_stories: [],
147
+ };
148
+
149
+ // Check each Story
150
+ for (const epic of sdm.agile_blueprint.epics || []) {
151
+ for (const story of epic.stories || []) {
152
+ results.total_stories++;
153
+
154
+ // Check if tests exist
155
+ const testFile = join(process.cwd(), 'tests', 'contracts',
156
+ `${story.id.toLowerCase()}-standard.test.js`);
157
+
158
+ if (existsSync(testFile)) {
159
+ results.tested_stories++;
160
+ }
161
+
162
+ // Check if tasks are complete
163
+ const allTasksComplete = story.tasks?.every(t => t.status === 'complete');
164
+ if (allTasksComplete) {
165
+ results.implemented_stories++;
166
+ } else {
167
+ results.uncovered_stories.push({
168
+ id: story.id,
169
+ name: story.name,
170
+ has_tests: existsSync(testFile),
171
+ pending_tasks: story.tasks?.filter(t => t.status !== 'complete').length || 0,
172
+ });
173
+ }
174
+ }
175
+ }
176
+
177
+ // Calculate coverage
178
+ const testCoverage = results.total_stories > 0
179
+ ? ((results.tested_stories / results.total_stories) * 100).toFixed(1)
180
+ : 0;
181
+
182
+ const implCoverage = results.total_stories > 0
183
+ ? ((results.implemented_stories / results.total_stories) * 100).toFixed(1)
184
+ : 0;
185
+
186
+ // Update SDM
187
+ sdm.agile_blueprint.test_suite_status = {
188
+ total_stories: results.total_stories,
189
+ tested_stories: results.tested_stories,
190
+ coverage_percentage: parseFloat(testCoverage),
191
+ last_test_run: new Date().toISOString(),
192
+ };
193
+ await sdmManager.save(sdm);
194
+
195
+ // Display results
196
+ console.log('');
197
+ console.log(chalk.bold('Coverage Report:'));
198
+ console.log(` Total Stories: ${results.total_stories}`);
199
+ console.log(` Test Coverage: ${testCoverage}% (${results.tested_stories}/${results.total_stories})`);
200
+ console.log(` Implementation: ${implCoverage}% (${results.implemented_stories}/${results.total_stories})`);
201
+ console.log('');
202
+
203
+ if (results.uncovered_stories.length > 0) {
204
+ console.log(chalk.yellow('Uncovered Stories:'));
205
+ results.uncovered_stories.forEach(story => {
206
+ const status = story.has_tests ? '🟡 Tests exist' : '🔴 No tests';
207
+ console.log(` ${status} ${story.id}: ${story.name}`);
208
+ console.log(` Pending tasks: ${story.pending_tasks}`);
209
+ });
210
+ console.log('');
211
+ }
212
+
213
+ clack.outro(testCoverage === '100.0' ? chalk.green('✓ Full coverage!') : chalk.yellow('⚠ Incomplete coverage'));
214
+ }
215
+
216
+ /**
217
+ * Generate edge case tests
218
+ */
219
+ async function generateEdgeCases(sdmManager, testEngine, storyId) {
220
+ // TODO: Implement edge case generation
221
+ console.log(chalk.cyan(`Generating edge cases for ${storyId}...`));
222
+ }
223
+
224
+ /**
225
+ * Initialize test infrastructure
226
+ */
227
+ async function initializeTestInfra(testEngine) {
228
+ clack.intro(chalk.cyan.bold('🔧 Initialize Test Infrastructure'));
229
+
230
+ const spinner = clack.spinner();
231
+ spinner.start('Setting up test structure...');
232
+
233
+ await testEngine.initializeTestStructure();
234
+ await copyTestUtilities();
235
+ await addTestScripts();
236
+
237
+ spinner.stop('Test infrastructure ready');
238
+
239
+ clack.outro(chalk.green('✓ Initialized'));
240
+ }
241
+
242
+ /**
243
+ * Copy test utilities
244
+ */
245
+ async function copyTestUtilities() {
246
+ const templatesDir = join(process.cwd(), 'tools/lib/test-templates');
247
+ const testUtilsDir = join(process.cwd(), 'tests/utils');
248
+
249
+ const files = [
250
+ 'api-client.template.js',
251
+ 'vitest.config.template.js',
252
+ ];
253
+
254
+ for (const file of files) {
255
+ const src = join(templatesDir, file);
256
+ const dest = join(testUtilsDir, file.replace('.template', ''));
257
+
258
+ if (existsSync(src)) {
259
+ await copyFile(src, dest);
260
+ }
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Add test scripts to package.json
266
+ */
267
+ async function addTestScripts() {
268
+ const pkgPath = join(process.cwd(), 'package.json');
269
+ const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
270
+
271
+ pkg.scripts = pkg.scripts || {};
272
+ pkg.scripts.test = pkg.scripts.test || 'vitest run';
273
+ pkg.scripts['test:watch'] = 'vitest watch';
274
+ pkg.scripts['test:coverage'] = 'vitest run --coverage';
275
+
276
+ await writeFile(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
277
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Validate Command
3
+ * Validates configuration and modules
4
+ */
5
+
6
+ import * as clack from '@clack/prompts';
7
+ import chalk from 'chalk';
8
+ import { ConfigValidator } from '../../lib/validators/config-validator.js';
9
+ import { ModuleValidator } from '../../lib/validators/module-validator.js';
10
+ import { ConfigManager } from '../../lib/config-manager.js';
11
+
12
+ export async function validateCommand(options) {
13
+ try {
14
+ const configManager = new ConfigManager(process.cwd());
15
+
16
+ if (!configManager.exists()) {
17
+ clack.log.error(chalk.red('Dhurandhar is not installed in this directory.'));
18
+ clack.log.info('Run: dhurandhar install');
19
+ process.exit(1);
20
+ }
21
+
22
+ clack.intro(chalk.cyan.bold('Dhurandhar Validation'));
23
+
24
+ const results = {
25
+ config: { valid: true, errors: [], warnings: [] },
26
+ modules: { valid: true, errors: [], warnings: [] },
27
+ };
28
+
29
+ // Validate configuration
30
+ if (!options.modules) {
31
+ const spinner = clack.spinner();
32
+ spinner.start('Validating configuration...');
33
+
34
+ const configValidator = new ConfigValidator(process.cwd());
35
+ results.config = await configValidator.validate(options.strict);
36
+
37
+ if (results.config.valid) {
38
+ spinner.stop(chalk.green('✓ Configuration is valid'));
39
+ } else {
40
+ spinner.stop(chalk.red('✗ Configuration has errors'));
41
+ }
42
+ }
43
+
44
+ // Validate modules
45
+ if (!options.config) {
46
+ const spinner = clack.spinner();
47
+ spinner.start('Validating modules...');
48
+
49
+ const moduleValidator = new ModuleValidator(process.cwd());
50
+ results.modules = await moduleValidator.validate(options.strict);
51
+
52
+ if (results.modules.valid) {
53
+ spinner.stop(chalk.green('✓ Modules are valid'));
54
+ } else {
55
+ spinner.stop(chalk.red('✗ Modules have errors'));
56
+ }
57
+ }
58
+
59
+ // Display detailed results
60
+ console.log('');
61
+
62
+ if (results.config.errors.length > 0) {
63
+ console.log(chalk.red.bold('Configuration Errors:'));
64
+ results.config.errors.forEach(error => {
65
+ console.log(` ${chalk.red('✗')} ${error}`);
66
+ });
67
+ console.log('');
68
+ }
69
+
70
+ if (results.config.warnings.length > 0) {
71
+ console.log(chalk.yellow.bold('Configuration Warnings:'));
72
+ results.config.warnings.forEach(warning => {
73
+ console.log(` ${chalk.yellow('⚠')} ${warning}`);
74
+ });
75
+ console.log('');
76
+ }
77
+
78
+ if (results.modules.errors.length > 0) {
79
+ console.log(chalk.red.bold('Module Errors:'));
80
+ results.modules.errors.forEach(error => {
81
+ console.log(` ${chalk.red('✗')} ${error}`);
82
+ });
83
+ console.log('');
84
+ }
85
+
86
+ if (results.modules.warnings.length > 0) {
87
+ console.log(chalk.yellow.bold('Module Warnings:'));
88
+ results.modules.warnings.forEach(warning => {
89
+ console.log(` ${chalk.yellow('⚠')} ${warning}`);
90
+ });
91
+ console.log('');
92
+ }
93
+
94
+ const allValid = results.config.valid && results.modules.valid;
95
+
96
+ if (allValid) {
97
+ clack.outro(chalk.green('✓ All validations passed!'));
98
+ } else {
99
+ clack.outro(chalk.red('✗ Validation failed. Please fix the errors above.'));
100
+ process.exit(1);
101
+ }
102
+
103
+ } catch (error) {
104
+ clack.log.error(chalk.red('Validation failed:'), error.message);
105
+ process.exit(1);
106
+ }
107
+ }
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Dhurandhar CLI
5
+ * Main entry point for the Dhurandhar system design framework
6
+ */
7
+
8
+ import { program } from 'commander';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname, join } from 'path';
11
+ import { readFileSync } from 'fs';
12
+ import chalk from 'chalk';
13
+ import { installCommand } from './commands/install.js';
14
+ import { configCommand } from './commands/config.js';
15
+ import { moduleCommand } from './commands/module.js';
16
+ import { validateCommand } from './commands/validate.js';
17
+ import { serviceCommand } from './commands/service.js';
18
+ import { entityCommand } from './commands/entity.js';
19
+ import { contextCommand } from './commands/context.js';
20
+ import { epicCommand } from './commands/epic.js';
21
+ import { storyCommand } from './commands/story.js';
22
+ import { testCommand } from './commands/test.js';
23
+ import { strategyCommand } from './commands/strategy.js';
24
+ import { auditCommand } from './commands/audit.js';
25
+ import { decisionsCommand } from './commands/decisions.js';
26
+
27
+ const __filename = fileURLToPath(import.meta.url);
28
+ const __dirname = dirname(__filename);
29
+
30
+ // Read package.json for version info
31
+ const packagePath = join(__dirname, '../../package.json');
32
+ const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
33
+
34
+ // Configure CLI
35
+ program
36
+ .name('dhurandhar')
37
+ .description('A System Building Mapwork - Framework for system design and build processes')
38
+ .version(packageJson.version, '-v, --version', 'Output the current version');
39
+
40
+ // Install command - Initialize framework in a project
41
+ program
42
+ .command('install')
43
+ .description('Install Dhurandhar framework in the current project')
44
+ .option('-d, --directory <path>', 'Target directory', process.cwd())
45
+ .option('-m, --modules <modules...>', 'Modules to install')
46
+ .option('-y, --yes', 'Skip prompts and use defaults')
47
+ .action(installCommand);
48
+
49
+ // Config command - Manage configuration
50
+ program
51
+ .command('config')
52
+ .description('Manage Dhurandhar configuration')
53
+ .option('-s, --show', 'Show current configuration')
54
+ .option('-e, --edit', 'Edit configuration interactively')
55
+ .option('-r, --reset', 'Reset to default configuration')
56
+ .action(configCommand);
57
+
58
+ // Module command - Manage modules
59
+ program
60
+ .command('module')
61
+ .description('Manage Dhurandhar modules')
62
+ .option('-l, --list', 'List available modules')
63
+ .option('-i, --info <module>', 'Show module information')
64
+ .option('-a, --add <module>', 'Add a module')
65
+ .option('-r, --remove <module>', 'Remove a module')
66
+ .action(moduleCommand);
67
+
68
+ // Validate command - Validate configuration and modules
69
+ program
70
+ .command('validate')
71
+ .description('Validate Dhurandhar configuration and modules')
72
+ .option('-c, --config', 'Validate configuration only')
73
+ .option('-m, --modules', 'Validate modules only')
74
+ .option('--strict', 'Use strict validation')
75
+ .action(validateCommand);
76
+
77
+ // Service command - Engineering-first service management
78
+ program
79
+ .command('service')
80
+ .description('Manage microservices and system components')
81
+ .option('-l, --list', 'List all services')
82
+ .option('-a, --add [spec]', 'Add service (optional quick spec: "name: description")')
83
+ .action(serviceCommand);
84
+
85
+ // Entity command - Engineering-first entity management
86
+ program
87
+ .command('entity')
88
+ .description('Manage database entities and relationships')
89
+ .option('-l, --list', 'List all entities')
90
+ .option('-a, --add [name]', 'Add entity')
91
+ .option('-r, --relate', 'Add relationship between entities')
92
+ .action(entityCommand);
93
+
94
+ // Context command - Display SDM for rehydration
95
+ program
96
+ .command('context')
97
+ .description('Display system architecture context')
98
+ .option('-s, --summary', 'Show brief summary')
99
+ .option('-f, --full', 'Show full architecture')
100
+ .option('--json', 'Output JSON format')
101
+ .action(contextCommand);
102
+
103
+ // Epic command - Agile Blueprint (high-level capabilities)
104
+ program
105
+ .command('epic')
106
+ .description('Manage Epics (system capabilities)')
107
+ .option('-l, --list', 'List all epics')
108
+ .option('-a, --add [name]', 'Add epic')
109
+ .action(epicCommand);
110
+
111
+ // Story command - User journeys with API contracts
112
+ program
113
+ .command('story')
114
+ .description('Manage Stories (user journeys)')
115
+ .option('-l, --list', 'List all stories')
116
+ .option('-a, --add [name]', 'Add story')
117
+ .option('-e, --epic <id>', 'Target epic ID')
118
+ .action(storyCommand);
119
+
120
+ // Test command - Contract-first test generation
121
+ program
122
+ .command('test')
123
+ .description('Contract-first testing')
124
+ .option('--init', 'Initialize test infrastructure')
125
+ .option('--generate', 'Generate tests from Agile Blueprint')
126
+ .option('--validate', 'Validate coverage against Stories')
127
+ .option('--edge-cases <id>', 'Generate edge cases for Story ID')
128
+ .action(testCommand);
129
+
130
+ // Strategy command - Pluggable architectural patterns
131
+ program
132
+ .command('strategy')
133
+ .description('Manage architectural strategies')
134
+ .option('--show', 'Show active strategies')
135
+ .option('--set <category>', 'Set strategy (persistence, communication, state, security, resilience)')
136
+ .option('--pivot <category>', 'Pivot existing strategy')
137
+ .option('--align', 'Align all services to current strategies')
138
+ .action(strategyCommand);
139
+
140
+ // Audit command - Architectural drift detection
141
+ program
142
+ .command('audit')
143
+ .description('Detect architectural drift (SDM vs codebase)')
144
+ .option('--summary', 'Show high-level alignment status')
145
+ .option('--drift', 'Show detailed drift report')
146
+ .option('--sync', 'Sync SDM to match codebase state')
147
+ .action(auditCommand);
148
+
149
+ // Decisions command - Technical decision registry
150
+ program
151
+ .command('decisions')
152
+ .description('Manage technical decision registry (Bmad-inspired)')
153
+ .option('--show', 'Show all registered decisions')
154
+ .option('--set <category>', 'Set decisions (naming, patterns, errors, observability)')
155
+ .option('--stock', 'Stock all decisions (complete setup)')
156
+ .action(decisionsCommand);
157
+
158
+ // Help command enhancement
159
+ program.on('--help', () => {
160
+ console.log('');
161
+ console.log(chalk.cyan('Examples - Engineering-First + Test-First Workflow:'));
162
+ console.log('');
163
+ console.log(chalk.bold('1. Initialize:'));
164
+ console.log(' $ dhurandhar install # Framework setup');
165
+ console.log('');
166
+ console.log(chalk.bold('2. Define Architecture:'));
167
+ console.log(' $ dhurandhar service add "auth: JWT auth" # Add service');
168
+ console.log(' $ dhurandhar entity add User # Add entity');
169
+ console.log('');
170
+ console.log(chalk.bold('3. Test-First Agile:'));
171
+ console.log(' $ dhurandhar epic add "User Authentication" # Add Epic');
172
+ console.log(' $ dhurandhar story add --epic EPIC-001 # Add Story');
173
+ console.log(' $ dhurandhar test --generate # Generate contract tests');
174
+ console.log(' $ npm test # Run tests (will fail)');
175
+ console.log(' $ # Implement services to pass tests');
176
+ console.log('');
177
+ console.log(chalk.bold('4. Validate:'));
178
+ console.log(' $ dhurandhar test --validate # Check coverage');
179
+ console.log(' $ dhurandhar context --full # View full architecture');
180
+ console.log('');
181
+ console.log(chalk.cyan('Test-First Philosophy:'));
182
+ console.log(' 1. Epic/Story define WHAT (capabilities & journeys)');
183
+ console.log(' 2. Tests define HOW (API contracts & boundaries)');
184
+ console.log(' 3. Implementation fulfills the contract');
185
+ console.log('');
186
+ console.log(chalk.cyan('Context Persistence:'));
187
+ console.log(' SYSTEM_DESIGN_MAP.yaml contains:');
188
+ console.log(' - Services & Entities (architecture)');
189
+ console.log(' - Epics & Stories (agile blueprint)');
190
+ console.log(' - Test coverage status (definition of done)');
191
+ console.log('');
192
+ console.log(chalk.cyan('Documentation:'));
193
+ console.log(' https://github.com/yourusername/dhurandhar');
194
+ console.log('');
195
+ });
196
+
197
+ // Error handling
198
+ program.exitOverride();
199
+
200
+ try {
201
+ await program.parseAsync(process.argv);
202
+ } catch (err) {
203
+ if (err.code === 'commander.help') {
204
+ process.exit(0);
205
+ }
206
+ if (err.code === 'commander.version') {
207
+ process.exit(0);
208
+ }
209
+
210
+ console.error(chalk.red('Error:'), err.message);
211
+ process.exit(1);
212
+ }