prjct-cli 0.8.8 → 0.9.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/core/__tests__/agentic/agent-router.test.js +398 -0
  3. package/core/__tests__/agentic/context-filter.test.js +494 -0
  4. package/core/__tests__/domain/analyzer.test.js +324 -0
  5. package/core/__tests__/infrastructure/author-detector.test.js +103 -0
  6. package/core/__tests__/infrastructure/config-manager.test.js +454 -0
  7. package/core/__tests__/infrastructure/path-manager.test.js +412 -0
  8. package/core/__tests__/utils/jsonl-helper.test.js +387 -0
  9. package/core/agentic/agent-router.js +482 -0
  10. package/core/agentic/command-executor.js +70 -15
  11. package/core/agentic/context-filter.js +549 -0
  12. package/core/agentic/prompt-builder.js +48 -38
  13. package/core/command-registry.js +104 -164
  14. package/core/domain/agent-generator.js +55 -44
  15. package/core/domain/architecture-generator.js +561 -0
  16. package/core/domain/task-stack.js +496 -0
  17. package/package.json +2 -1
  18. package/templates/commands/analyze.md +10 -53
  19. package/templates/commands/bug.md +11 -70
  20. package/templates/commands/build.md +7 -37
  21. package/templates/commands/cleanup.md +9 -32
  22. package/templates/commands/dash.md +241 -0
  23. package/templates/commands/design.md +5 -28
  24. package/templates/commands/done.md +6 -20
  25. package/templates/commands/feature.md +11 -83
  26. package/templates/commands/help.md +9 -38
  27. package/templates/commands/idea.md +7 -28
  28. package/templates/commands/init.md +10 -89
  29. package/templates/commands/next.md +6 -26
  30. package/templates/commands/now.md +6 -26
  31. package/templates/commands/pause.md +18 -0
  32. package/templates/commands/progress.md +5 -50
  33. package/templates/commands/recap.md +5 -54
  34. package/templates/commands/resume.md +97 -0
  35. package/templates/commands/ship.md +13 -68
  36. package/templates/commands/status.md +7 -32
  37. package/templates/commands/sync.md +7 -24
  38. package/templates/commands/work.md +44 -0
  39. package/templates/commands/workflow.md +3 -25
  40. package/templates/planning-methodology.md +195 -0
@@ -0,0 +1,561 @@
1
+ /**
2
+ * Architecture Generator - Transforms ideas into complete technical specifications
3
+ * Uses AI-driven methodology to develop ideas through discovery, design, and planning phases
4
+ */
5
+
6
+ const path = require('path');
7
+ const fs = require('fs').promises;
8
+
9
+ class ArchitectureGenerator {
10
+ constructor() {
11
+ this.phases = [
12
+ 'discovery',
13
+ 'user-flows',
14
+ 'domain-modeling',
15
+ 'api-design',
16
+ 'architecture',
17
+ 'data-design',
18
+ 'tech-stack',
19
+ 'roadmap'
20
+ ];
21
+ }
22
+
23
+ /**
24
+ * Generate complete architecture from an idea
25
+ * @param {string} idea - The initial idea description
26
+ * @param {object} context - Project context and constraints
27
+ * @returns {Promise<object>} Complete architecture specification
28
+ */
29
+ async generateArchitecture(idea, context = {}) {
30
+ const architecture = {
31
+ id: `arch-${Date.now()}`,
32
+ idea,
33
+ createdAt: new Date().toISOString(),
34
+ phases: {}
35
+ };
36
+
37
+ // Phase 1: Discovery & Problem Definition
38
+ architecture.phases.discovery = await this.discovery(idea, context);
39
+
40
+ // Phase 2: User Flows & Journeys
41
+ architecture.phases.userFlows = await this.userFlows();
42
+
43
+ // Phase 3: Domain Modeling
44
+ architecture.phases.domainModel = await this.domainModeling();
45
+
46
+ // Phase 4: API Contract Design
47
+ architecture.phases.apiDesign = await this.apiDesign();
48
+
49
+ // Phase 5: System Architecture
50
+ architecture.phases.systemArchitecture = await this.systemArchitecture();
51
+
52
+ // Phase 6: Data Architecture
53
+ architecture.phases.dataArchitecture = await this.dataArchitecture(
54
+ architecture.phases.domainModel
55
+ );
56
+
57
+ // Phase 7: Tech Stack Decision
58
+ architecture.phases.techStack = await this.techStackDecision();
59
+
60
+ // Phase 8: Implementation Roadmap
61
+ architecture.phases.roadmap = await this.roadmap();
62
+
63
+ return architecture;
64
+ }
65
+
66
+ /**
67
+ * Phase 1: Discovery & Problem Definition
68
+ */
69
+ async discovery(idea, context) {
70
+ return {
71
+ problemStatement: {
72
+ problem: `Analyzing: ${idea}`,
73
+ currentPainPoint: 'To be determined through analysis',
74
+ impact: 'To be evaluated'
75
+ },
76
+ targetUsers: {
77
+ primary: {
78
+ persona: 'Primary User',
79
+ goals: [],
80
+ frustrations: [],
81
+ technicalProficiency: 'medium'
82
+ },
83
+ secondary: []
84
+ },
85
+ constraints: {
86
+ budget: context.budget || 'bootstrapped',
87
+ timeline: context.timeline || 'MVP in 4 weeks',
88
+ teamSize: context.teamSize || 1,
89
+ regulatory: context.regulatory || []
90
+ },
91
+ successMetrics: {
92
+ primary: 'User adoption rate',
93
+ secondary: ['engagement', 'retention'],
94
+ mvpThreshold: '100 active users'
95
+ }
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Phase 2: User Flows & Journeys
101
+ */
102
+ async userFlows() {
103
+ return {
104
+ coreJourneys: [
105
+ {
106
+ name: 'Primary User Flow',
107
+ entryPoint: 'Landing page or direct link',
108
+ steps: [
109
+ { action: 'Arrive', response: 'Show welcome', next: 'Onboarding' },
110
+ { action: 'Complete onboarding', response: 'Create account', next: 'Dashboard' },
111
+ { action: 'Use core feature', response: 'Process request', next: 'Results' }
112
+ ],
113
+ successState: 'Task completed successfully',
114
+ errorStates: ['Network error', 'Validation error', 'Permission denied']
115
+ }
116
+ ],
117
+ jobsToBeDone: [
118
+ {
119
+ situation: 'When I need to solve the core problem',
120
+ motivation: 'I want to use this solution',
121
+ expectedOutcome: 'So I can achieve my goal efficiently'
122
+ }
123
+ ]
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Phase 3: Domain Modeling
129
+ */
130
+ async domainModeling() {
131
+ return {
132
+ entities: [
133
+ {
134
+ name: 'User',
135
+ description: 'System user account',
136
+ attributes: [
137
+ { name: 'id', type: 'uuid', constraints: 'primary key' },
138
+ { name: 'email', type: 'string', constraints: 'unique, not null' },
139
+ { name: 'createdAt', type: 'timestamp', constraints: 'not null' }
140
+ ],
141
+ relationships: [],
142
+ businessRules: ['Email must be verified', 'User must accept terms'],
143
+ lifecycle: ['pending', 'active', 'suspended', 'deleted']
144
+ }
145
+ ],
146
+ boundedContexts: [
147
+ {
148
+ name: 'User Management',
149
+ entities: ['User', 'Profile', 'Session'],
150
+ dependencies: [],
151
+ eventsPublished: ['UserCreated', 'UserUpdated'],
152
+ eventsConsumed: []
153
+ }
154
+ ]
155
+ };
156
+ }
157
+
158
+ /**
159
+ * Phase 4: API Design
160
+ */
161
+ async apiDesign() {
162
+ return {
163
+ style: 'REST',
164
+ reasoning: 'Simple CRUD operations with broad compatibility',
165
+ endpoints: [
166
+ {
167
+ name: 'Create User',
168
+ method: 'POST',
169
+ path: '/api/users',
170
+ authentication: 'Optional',
171
+ inputSchema: {
172
+ email: 'string',
173
+ password: 'string'
174
+ },
175
+ outputSchema: {
176
+ id: 'string',
177
+ email: 'string',
178
+ createdAt: 'string'
179
+ },
180
+ errorResponses: [
181
+ { code: 400, description: 'Invalid input' },
182
+ { code: 409, description: 'Email already exists' }
183
+ ]
184
+ }
185
+ ],
186
+ authentication: {
187
+ method: 'JWT',
188
+ implementation: 'Lucia',
189
+ tokenStorage: 'httpOnly cookie',
190
+ sessionDuration: '7 days'
191
+ }
192
+ };
193
+ }
194
+
195
+ /**
196
+ * Phase 5: System Architecture
197
+ */
198
+ async systemArchitecture() {
199
+ return {
200
+ pattern: 'Modular Monolith',
201
+ reasoning: 'Fast iteration for MVP with small team',
202
+ components: {
203
+ frontend: 'Next.js App',
204
+ backend: 'Next.js API Routes',
205
+ database: 'PostgreSQL',
206
+ cache: 'Redis',
207
+ storage: 'S3-compatible'
208
+ },
209
+ deploymentModel: 'Serverless (Vercel)',
210
+ scalingStrategy: 'Horizontal with auto-scaling'
211
+ };
212
+ }
213
+
214
+ /**
215
+ * Phase 6: Data Architecture
216
+ */
217
+ async dataArchitecture(domainModel) {
218
+ const schemas = [];
219
+
220
+ for (const entity of domainModel.entities) {
221
+ schemas.push({
222
+ table: entity.name.toLowerCase() + 's',
223
+ columns: entity.attributes,
224
+ indexes: [
225
+ { name: `idx_${entity.name.toLowerCase()}_created`, columns: ['createdAt'] }
226
+ ],
227
+ relationships: entity.relationships
228
+ });
229
+ }
230
+
231
+ return {
232
+ primaryDatabase: 'PostgreSQL',
233
+ reasoning: 'ACID compliance, complex queries, proven reliability',
234
+ schemas,
235
+ caching: {
236
+ strategy: 'Cache-aside',
237
+ ttl: {
238
+ user: 3600,
239
+ session: 1800
240
+ }
241
+ },
242
+ migration: {
243
+ tool: 'Drizzle Kit',
244
+ strategy: 'Forward-only migrations'
245
+ }
246
+ };
247
+ }
248
+
249
+ /**
250
+ * Phase 7: Tech Stack Decision
251
+ */
252
+ async techStackDecision() {
253
+ return {
254
+ frontend: {
255
+ framework: 'Next.js 14',
256
+ styling: 'Tailwind CSS',
257
+ state: 'Zustand',
258
+ forms: 'React Hook Form',
259
+ dataFetching: 'TanStack Query',
260
+ ui: 'shadcn/ui'
261
+ },
262
+ backend: {
263
+ runtime: 'Node.js',
264
+ framework: 'Next.js API Routes',
265
+ orm: 'Drizzle',
266
+ validation: 'Zod',
267
+ auth: 'Lucia',
268
+ background: 'Inngest'
269
+ },
270
+ infrastructure: {
271
+ hosting: 'Vercel',
272
+ database: 'Neon',
273
+ cache: 'Upstash Redis',
274
+ storage: 'Cloudflare R2',
275
+ monitoring: 'Sentry'
276
+ },
277
+ reasoning: {
278
+ frontend: 'Type-safe, modern DX, strong ecosystem',
279
+ backend: 'Unified codebase, serverless-first',
280
+ infrastructure: 'Cost-effective for MVP, scales well'
281
+ }
282
+ };
283
+ }
284
+
285
+ /**
286
+ * Phase 8: Implementation Roadmap
287
+ */
288
+ async roadmap() {
289
+ return {
290
+ mvpScope: {
291
+ goal: 'Validate core value proposition',
292
+ features: [
293
+ 'User authentication',
294
+ 'Core feature implementation',
295
+ 'Basic dashboard',
296
+ 'Essential API endpoints'
297
+ ],
298
+ excluded: [
299
+ 'Advanced analytics',
300
+ 'Third-party integrations',
301
+ 'Mobile app'
302
+ ],
303
+ successCriteria: {
304
+ users: 100,
305
+ retention: '40% weekly active'
306
+ }
307
+ },
308
+ phases: [
309
+ {
310
+ name: 'Phase 1: Foundation',
311
+ duration: '1 week',
312
+ tasks: [
313
+ 'Project setup and configuration',
314
+ 'Database schema and migrations',
315
+ 'Authentication system',
316
+ 'Basic UI components'
317
+ ],
318
+ deliverable: 'Working authentication and base UI'
319
+ },
320
+ {
321
+ name: 'Phase 2: Core Features',
322
+ duration: '2 weeks',
323
+ tasks: [
324
+ 'Implement core domain logic',
325
+ 'API endpoints',
326
+ 'User dashboard',
327
+ 'Data validation'
328
+ ],
329
+ deliverable: 'Functional MVP'
330
+ },
331
+ {
332
+ name: 'Phase 3: Polish & Launch',
333
+ duration: '1 week',
334
+ tasks: [
335
+ 'Error handling',
336
+ 'Performance optimization',
337
+ 'Security audit',
338
+ 'Production deployment'
339
+ ],
340
+ deliverable: 'Production-ready application'
341
+ }
342
+ ],
343
+ estimatedTotal: '4 weeks',
344
+ risks: [
345
+ {
346
+ risk: 'Scope creep',
347
+ mitigation: 'Strict MVP feature set'
348
+ },
349
+ {
350
+ risk: 'Technical complexity',
351
+ mitigation: 'Use proven patterns and libraries'
352
+ }
353
+ ]
354
+ };
355
+ }
356
+
357
+ /**
358
+ * Save architecture to files
359
+ */
360
+ async saveArchitecture(architecture, projectPath) {
361
+ const archPath = path.join(projectPath, 'planning', 'architectures', architecture.id);
362
+ await fs.mkdir(archPath, { recursive: true });
363
+
364
+ // Save each phase as a separate markdown file
365
+ const files = {
366
+ 'discovery.md': this.formatDiscovery(architecture.phases.discovery),
367
+ 'user-flows.md': this.formatUserFlows(architecture.phases.userFlows),
368
+ 'domain-model.md': this.formatDomainModel(architecture.phases.domainModel),
369
+ 'api-spec.md': this.formatApiSpec(architecture.phases.apiDesign),
370
+ 'architecture.md': this.formatArchitecture(architecture.phases.systemArchitecture),
371
+ 'database.sql': this.generateSQLSchema(architecture.phases.dataArchitecture),
372
+ 'tech-stack.md': this.formatTechStack(architecture.phases.techStack),
373
+ 'roadmap.md': this.formatRoadmap(architecture.phases.roadmap),
374
+ 'summary.json': JSON.stringify(architecture, null, 2)
375
+ };
376
+
377
+ for (const [filename, content] of Object.entries(files)) {
378
+ await fs.writeFile(path.join(archPath, filename), content);
379
+ }
380
+
381
+ return archPath;
382
+ }
383
+
384
+ // Formatting methods for each phase
385
+ formatDiscovery(discovery) {
386
+ return `# Discovery & Problem Definition
387
+
388
+ ## Problem Statement
389
+
390
+ **Problem**: ${discovery.problemStatement.problem}
391
+ **Current Pain Point**: ${discovery.problemStatement.currentPainPoint}
392
+ **Impact**: ${discovery.problemStatement.impact}
393
+
394
+ ## Target Users
395
+
396
+ ### Primary User
397
+ - **Persona**: ${discovery.targetUsers.primary.persona}
398
+ - **Technical Proficiency**: ${discovery.targetUsers.primary.technicalProficiency}
399
+
400
+ ## Constraints
401
+ - **Budget**: ${discovery.constraints.budget}
402
+ - **Timeline**: ${discovery.constraints.timeline}
403
+ - **Team Size**: ${discovery.constraints.teamSize}
404
+
405
+ ## Success Metrics
406
+ - **Primary KPI**: ${discovery.successMetrics.primary}
407
+ - **MVP Threshold**: ${discovery.successMetrics.mvpThreshold}
408
+ `;
409
+ }
410
+
411
+ formatUserFlows(userFlows) {
412
+ let content = '# User Flows & Journeys\n\n';
413
+
414
+ for (const journey of userFlows.coreJourneys) {
415
+ content += `## ${journey.name}\n\n`;
416
+ content += `**Entry Point**: ${journey.entryPoint}\n\n`;
417
+ content += '### Steps\n';
418
+ for (const step of journey.steps) {
419
+ content += `1. **${step.action}** → ${step.response} → ${step.next}\n`;
420
+ }
421
+ content += `\n**Success State**: ${journey.successState}\n\n`;
422
+ }
423
+
424
+ return content;
425
+ }
426
+
427
+ formatDomainModel(domainModel) {
428
+ let content = '# Domain Model\n\n## Entities\n\n';
429
+
430
+ for (const entity of domainModel.entities) {
431
+ content += `### ${entity.name}\n`;
432
+ content += `${entity.description}\n\n`;
433
+ content += '**Attributes**:\n';
434
+ for (const attr of entity.attributes) {
435
+ content += `- ${attr.name}: ${attr.type} (${attr.constraints})\n`;
436
+ }
437
+ content += '\n';
438
+ }
439
+
440
+ return content;
441
+ }
442
+
443
+ formatApiSpec(apiDesign) {
444
+ let content = `# API Specification\n\n`;
445
+ content += `**Style**: ${apiDesign.style}\n`;
446
+ content += `**Reasoning**: ${apiDesign.reasoning}\n\n`;
447
+ content += '## Endpoints\n\n';
448
+
449
+ for (const endpoint of apiDesign.endpoints) {
450
+ content += `### ${endpoint.name}\n`;
451
+ content += `- **Method**: ${endpoint.method}\n`;
452
+ content += `- **Path**: ${endpoint.path}\n`;
453
+ content += `- **Authentication**: ${endpoint.authentication}\n\n`;
454
+ }
455
+
456
+ return content;
457
+ }
458
+
459
+ formatArchitecture(architecture) {
460
+ return `# System Architecture
461
+
462
+ **Pattern**: ${architecture.pattern}
463
+ **Reasoning**: ${architecture.reasoning}
464
+
465
+ ## Components
466
+ - **Frontend**: ${architecture.components.frontend}
467
+ - **Backend**: ${architecture.components.backend}
468
+ - **Database**: ${architecture.components.database}
469
+ - **Cache**: ${architecture.components.cache}
470
+
471
+ ## Deployment
472
+ - **Model**: ${architecture.deploymentModel}
473
+ - **Scaling**: ${architecture.scalingStrategy}
474
+ `;
475
+ }
476
+
477
+ generateSQLSchema(dataArchitecture) {
478
+ let sql = '-- Generated Database Schema\n\n';
479
+
480
+ for (const schema of dataArchitecture.schemas) {
481
+ sql += `CREATE TABLE ${schema.table} (\n`;
482
+ for (const col of schema.columns) {
483
+ sql += ` ${col.name} ${this.sqlType(col.type)} ${col.constraints || ''},\n`;
484
+ }
485
+ sql = sql.slice(0, -2) + '\n);\n\n';
486
+
487
+ for (const index of schema.indexes) {
488
+ sql += `CREATE INDEX ${index.name} ON ${schema.table}(${index.columns.join(', ')});\n`;
489
+ }
490
+ sql += '\n';
491
+ }
492
+
493
+ return sql;
494
+ }
495
+
496
+ sqlType(type) {
497
+ const typeMap = {
498
+ 'uuid': 'UUID',
499
+ 'string': 'VARCHAR(255)',
500
+ 'text': 'TEXT',
501
+ 'int': 'INTEGER',
502
+ 'timestamp': 'TIMESTAMP',
503
+ 'boolean': 'BOOLEAN',
504
+ 'json': 'JSONB'
505
+ };
506
+ return typeMap[type] || 'TEXT';
507
+ }
508
+
509
+ formatTechStack(techStack) {
510
+ return `# Tech Stack Decision
511
+
512
+ ## Frontend
513
+ - **Framework**: ${techStack.frontend.framework}
514
+ - **Styling**: ${techStack.frontend.styling}
515
+ - **State Management**: ${techStack.frontend.state}
516
+ - **Forms**: ${techStack.frontend.forms}
517
+ - **Data Fetching**: ${techStack.frontend.dataFetching}
518
+ - **UI Library**: ${techStack.frontend.ui}
519
+
520
+ ## Backend
521
+ - **Runtime**: ${techStack.backend.runtime}
522
+ - **Framework**: ${techStack.backend.framework}
523
+ - **ORM**: ${techStack.backend.orm}
524
+ - **Validation**: ${techStack.backend.validation}
525
+ - **Auth**: ${techStack.backend.auth}
526
+
527
+ ## Infrastructure
528
+ - **Hosting**: ${techStack.infrastructure.hosting}
529
+ - **Database**: ${techStack.infrastructure.database}
530
+ - **Cache**: ${techStack.infrastructure.cache}
531
+ - **Monitoring**: ${techStack.infrastructure.monitoring}
532
+ `;
533
+ }
534
+
535
+ formatRoadmap(roadmap) {
536
+ let content = `# Implementation Roadmap\n\n`;
537
+ content += `## MVP Scope\n\n`;
538
+ content += `**Goal**: ${roadmap.mvpScope.goal}\n\n`;
539
+ content += '### Included Features\n';
540
+ for (const feature of roadmap.mvpScope.features) {
541
+ content += `- ${feature}\n`;
542
+ }
543
+ content += '\n## Development Phases\n\n';
544
+
545
+ for (const phase of roadmap.phases) {
546
+ content += `### ${phase.name}\n`;
547
+ content += `**Duration**: ${phase.duration}\n\n`;
548
+ content += '**Tasks**:\n';
549
+ for (const task of phase.tasks) {
550
+ content += `- ${task}\n`;
551
+ }
552
+ content += `\n**Deliverable**: ${phase.deliverable}\n\n`;
553
+ }
554
+
555
+ content += `## Total Estimate: ${roadmap.estimatedTotal}\n`;
556
+
557
+ return content;
558
+ }
559
+ }
560
+
561
+ module.exports = ArchitectureGenerator;