@aicgen/aicgen 1.0.0-beta.1 → 1.0.0-beta.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 (136) hide show
  1. package/.vs/ProjectSettings.json +2 -2
  2. package/.vs/VSWorkspaceState.json +15 -15
  3. package/.vs/aicgen.slnx/v18/DocumentLayout.json +53 -53
  4. package/assets/icon.svg +33 -33
  5. package/bun.lock +0 -43
  6. package/data/architecture/microservices/api-gateway.md +56 -56
  7. package/data/devops/observability.md +73 -73
  8. package/dist/index.js +9299 -9299
  9. package/package.json +2 -2
  10. package/.claude/agents/architecture-reviewer.md +0 -88
  11. package/.claude/agents/guideline-checker.md +0 -73
  12. package/.claude/agents/security-auditor.md +0 -108
  13. package/.claude/guidelines/api-design.md +0 -645
  14. package/.claude/guidelines/architecture.md +0 -2503
  15. package/.claude/guidelines/best-practices.md +0 -618
  16. package/.claude/guidelines/code-style.md +0 -304
  17. package/.claude/guidelines/design-patterns.md +0 -573
  18. package/.claude/guidelines/devops.md +0 -226
  19. package/.claude/guidelines/error-handling.md +0 -413
  20. package/.claude/guidelines/language.md +0 -782
  21. package/.claude/guidelines/performance.md +0 -706
  22. package/.claude/guidelines/security.md +0 -583
  23. package/.claude/guidelines/testing.md +0 -568
  24. package/.claude/settings.json +0 -98
  25. package/.claude/settings.local.json +0 -8
  26. package/.eslintrc.json +0 -28
  27. package/.github/workflows/release.yml +0 -180
  28. package/.github/workflows/test.yml +0 -81
  29. package/CONTRIBUTING.md +0 -821
  30. package/dist/commands/init.d.ts +0 -8
  31. package/dist/commands/init.d.ts.map +0 -1
  32. package/dist/commands/init.js +0 -46
  33. package/dist/commands/init.js.map +0 -1
  34. package/dist/config/profiles.d.ts +0 -4
  35. package/dist/config/profiles.d.ts.map +0 -1
  36. package/dist/config/profiles.js +0 -30
  37. package/dist/config/profiles.js.map +0 -1
  38. package/dist/config/settings.d.ts +0 -7
  39. package/dist/config/settings.d.ts.map +0 -1
  40. package/dist/config/settings.js +0 -7
  41. package/dist/config/settings.js.map +0 -1
  42. package/dist/index.d.ts +0 -3
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.js.map +0 -1
  45. package/dist/models/guideline.d.ts +0 -15
  46. package/dist/models/guideline.d.ts.map +0 -1
  47. package/dist/models/guideline.js +0 -2
  48. package/dist/models/guideline.js.map +0 -1
  49. package/dist/models/preference.d.ts +0 -9
  50. package/dist/models/preference.d.ts.map +0 -1
  51. package/dist/models/preference.js +0 -2
  52. package/dist/models/preference.js.map +0 -1
  53. package/dist/models/profile.d.ts +0 -9
  54. package/dist/models/profile.d.ts.map +0 -1
  55. package/dist/models/profile.js +0 -2
  56. package/dist/models/profile.js.map +0 -1
  57. package/dist/models/project.d.ts +0 -13
  58. package/dist/models/project.d.ts.map +0 -1
  59. package/dist/models/project.js +0 -2
  60. package/dist/models/project.js.map +0 -1
  61. package/dist/services/ai/anthropic.d.ts +0 -7
  62. package/dist/services/ai/anthropic.d.ts.map +0 -1
  63. package/dist/services/ai/anthropic.js +0 -39
  64. package/dist/services/ai/anthropic.js.map +0 -1
  65. package/dist/services/generator.d.ts +0 -2
  66. package/dist/services/generator.d.ts.map +0 -1
  67. package/dist/services/generator.js +0 -4
  68. package/dist/services/generator.js.map +0 -1
  69. package/dist/services/learner.d.ts +0 -2
  70. package/dist/services/learner.d.ts.map +0 -1
  71. package/dist/services/learner.js +0 -4
  72. package/dist/services/learner.js.map +0 -1
  73. package/dist/services/scanner.d.ts +0 -3
  74. package/dist/services/scanner.d.ts.map +0 -1
  75. package/dist/services/scanner.js +0 -54
  76. package/dist/services/scanner.js.map +0 -1
  77. package/dist/utils/errors.d.ts +0 -15
  78. package/dist/utils/errors.d.ts.map +0 -1
  79. package/dist/utils/errors.js +0 -27
  80. package/dist/utils/errors.js.map +0 -1
  81. package/dist/utils/file.d.ts +0 -7
  82. package/dist/utils/file.d.ts.map +0 -1
  83. package/dist/utils/file.js +0 -32
  84. package/dist/utils/file.js.map +0 -1
  85. package/dist/utils/logger.d.ts +0 -6
  86. package/dist/utils/logger.d.ts.map +0 -1
  87. package/dist/utils/logger.js +0 -17
  88. package/dist/utils/logger.js.map +0 -1
  89. package/dist/utils/path.d.ts +0 -6
  90. package/dist/utils/path.d.ts.map +0 -1
  91. package/dist/utils/path.js +0 -14
  92. package/dist/utils/path.js.map +0 -1
  93. package/docs/planning/memory-lane.md +0 -83
  94. package/packaging/linux/aicgen.spec +0 -23
  95. package/packaging/linux/control +0 -9
  96. package/packaging/macos/scripts/postinstall +0 -12
  97. package/packaging/windows/setup.nsi +0 -92
  98. package/scripts/add-categories.ts +0 -87
  99. package/scripts/build-binary.ts +0 -46
  100. package/scripts/embed-data.ts +0 -105
  101. package/scripts/generate-version.ts +0 -150
  102. package/scripts/test-decompress.ts +0 -27
  103. package/scripts/test-extract.ts +0 -31
  104. package/src/__tests__/services/assistant-file-writer.test.ts +0 -400
  105. package/src/__tests__/services/guideline-loader.test.ts +0 -281
  106. package/src/__tests__/services/tarball-extraction.test.ts +0 -125
  107. package/src/commands/add-guideline.ts +0 -296
  108. package/src/commands/clear.ts +0 -61
  109. package/src/commands/guideline-selector.ts +0 -123
  110. package/src/commands/init.ts +0 -645
  111. package/src/commands/quick-add.ts +0 -586
  112. package/src/commands/remove-guideline.ts +0 -152
  113. package/src/commands/stats.ts +0 -49
  114. package/src/commands/update.ts +0 -240
  115. package/src/config.ts +0 -82
  116. package/src/embedded-data.ts +0 -1492
  117. package/src/index.ts +0 -67
  118. package/src/models/profile.ts +0 -24
  119. package/src/models/project.ts +0 -43
  120. package/src/services/assistant-file-writer.ts +0 -612
  121. package/src/services/config-generator.ts +0 -150
  122. package/src/services/config-manager.ts +0 -70
  123. package/src/services/data-source.ts +0 -248
  124. package/src/services/first-run-init.ts +0 -148
  125. package/src/services/guideline-loader.ts +0 -311
  126. package/src/services/hook-generator.ts +0 -178
  127. package/src/services/subagent-generator.ts +0 -310
  128. package/src/utils/banner.ts +0 -66
  129. package/src/utils/errors.ts +0 -27
  130. package/src/utils/file.ts +0 -67
  131. package/src/utils/formatting.ts +0 -172
  132. package/src/utils/logger.ts +0 -89
  133. package/src/utils/path.ts +0 -17
  134. package/src/utils/wizard-state.ts +0 -132
  135. package/tsconfig.json +0 -25
  136. /package/{CLAUDE.md → claude.md} +0 -0
@@ -1,573 +0,0 @@
1
- # Design Patterns
2
-
3
- # Base Patterns
4
-
5
- ## Value Object
6
-
7
- Immutable object defined by its value, not identity.
8
-
9
- ```typescript
10
- class Email {
11
- private readonly value: string;
12
-
13
- constructor(email: string) {
14
- if (!this.isValid(email)) throw new Error('Invalid email');
15
- this.value = email.toLowerCase();
16
- }
17
-
18
- equals(other: Email): boolean {
19
- return this.value === other.value;
20
- }
21
- }
22
-
23
- class Money {
24
- constructor(
25
- public readonly amount: number,
26
- public readonly currency: Currency
27
- ) {
28
- Object.freeze(this);
29
- }
30
-
31
- add(other: Money): Money {
32
- this.assertSameCurrency(other);
33
- return new Money(this.amount + other.amount, this.currency);
34
- }
35
- }
36
- ```
37
-
38
- ## Special Case (Null Object)
39
-
40
- Replace null checks with polymorphism.
41
-
42
- ```typescript
43
- abstract class Customer {
44
- abstract getDiscount(): number;
45
- }
46
-
47
- class RealCustomer extends Customer {
48
- getDiscount(): number { return 0.1; }
49
- }
50
-
51
- class GuestCustomer extends Customer {
52
- getDiscount(): number { return 0; } // No discount
53
- }
54
-
55
- // No null checks needed
56
- const customer = repo.findById(id) || new GuestCustomer();
57
- const discount = customer.getDiscount();
58
- ```
59
-
60
- ## Registry
61
-
62
- Global access point for services.
63
-
64
- ```typescript
65
- class ServiceRegistry {
66
- private static services = new Map<string, any>();
67
-
68
- static register<T>(key: string, service: T): void {
69
- this.services.set(key, service);
70
- }
71
-
72
- static get<T>(key: string): T {
73
- return this.services.get(key);
74
- }
75
- }
76
-
77
- // Prefer dependency injection over registry
78
- ```
79
-
80
- ## Plugin
81
-
82
- Extend behavior without modifying core code.
83
-
84
- ```typescript
85
- interface ValidationPlugin {
86
- validate(user: User): ValidationResult;
87
- }
88
-
89
- class UserValidator {
90
- private plugins: ValidationPlugin[] = [];
91
-
92
- registerPlugin(plugin: ValidationPlugin): void {
93
- this.plugins.push(plugin);
94
- }
95
-
96
- validate(user: User): ValidationResult[] {
97
- return this.plugins.map(p => p.validate(user));
98
- }
99
- }
100
- ```
101
-
102
- ## Best Practices
103
-
104
- - Use Value Objects to avoid primitive obsession
105
- - Make Value Objects immutable
106
- - Use Special Case instead of null checks
107
- - Prefer dependency injection over Registry
108
-
109
-
110
- ---
111
-
112
- # Concurrency Patterns
113
-
114
- ## Optimistic Locking
115
-
116
- Detect conflicts on commit using version numbers.
117
-
118
- ```typescript
119
- class Product {
120
- constructor(
121
- public id: string,
122
- public name: string,
123
- public version: number = 1
124
- ) {}
125
- }
126
-
127
- class ProductRepository {
128
- async save(product: Product): Promise<void> {
129
- const result = await this.db.execute(
130
- `UPDATE products SET name = $1, version = version + 1
131
- WHERE id = $2 AND version = $3`,
132
- [product.name, product.id, product.version]
133
- );
134
-
135
- if (result.rowCount === 0) {
136
- throw new OptimisticLockException('Product was modified');
137
- }
138
- product.version++;
139
- }
140
- }
141
- ```
142
-
143
- ## Pessimistic Locking
144
-
145
- Lock resources before editing.
146
-
147
- ```typescript
148
- class LockManager {
149
- async acquireLock(resourceId: string, ownerId: string): Promise<boolean> {
150
- const existing = await this.db.queryOne(
151
- 'SELECT * FROM locks WHERE resource_id = $1 AND expires_at > NOW()',
152
- [resourceId]
153
- );
154
-
155
- if (existing) return false;
156
-
157
- await this.db.execute(
158
- 'INSERT INTO locks (resource_id, owner_id, expires_at) VALUES ($1, $2, $3)',
159
- [resourceId, ownerId, new Date(Date.now() + 30000)]
160
- );
161
- return true;
162
- }
163
-
164
- async releaseLock(resourceId: string, ownerId: string): Promise<void> {
165
- await this.db.execute(
166
- 'DELETE FROM locks WHERE resource_id = $1 AND owner_id = $2',
167
- [resourceId, ownerId]
168
- );
169
- }
170
- }
171
- ```
172
-
173
- ## Coarse-Grained Lock
174
-
175
- Lock entire aggregate rather than individual entities.
176
-
177
- ```typescript
178
- class OrderRepository {
179
- async save(order: Order): Promise<void> {
180
- // Lock aggregate root, all children implicitly locked
181
- await this.db.execute(
182
- 'SELECT * FROM orders WHERE id = $1 FOR UPDATE',
183
- [order.id]
184
- );
185
-
186
- // Update order and all items in single transaction
187
- await this.updateOrder(order);
188
- await this.updateOrderItems(order.items);
189
- }
190
- }
191
- ```
192
-
193
- ## Best Practices
194
-
195
- - Use optimistic locking for low-contention scenarios
196
- - Use pessimistic locking for high-contention or critical data
197
- - Always set lock timeouts
198
- - Implement retry logic with exponential backoff
199
-
200
-
201
- ---
202
-
203
- # Data Access Patterns
204
-
205
- ## Repository
206
-
207
- Collection-like interface for domain objects.
208
-
209
- ```typescript
210
- interface UserRepository {
211
- findById(id: string): Promise<User | null>;
212
- findByEmail(email: string): Promise<User | null>;
213
- save(user: User): Promise<void>;
214
- delete(user: User): Promise<void>;
215
- }
216
-
217
- class PostgreSQLUserRepository implements UserRepository {
218
- async findById(id: string): Promise<User | null> {
219
- const row = await this.db.queryOne('SELECT * FROM users WHERE id = $1', [id]);
220
- return row ? this.mapToUser(row) : null;
221
- }
222
- }
223
- ```
224
-
225
- ## Data Mapper
226
-
227
- Complete separation between domain and persistence.
228
-
229
- ```typescript
230
- class UserMapper {
231
- toDomain(row: DbRow): User {
232
- return new User(row.id, row.name, new Email(row.email));
233
- }
234
-
235
- toDatabase(user: User): DbRow {
236
- return { id: user.id, name: user.name, email: user.email.toString() };
237
- }
238
- }
239
- ```
240
-
241
- ## Unit of Work
242
-
243
- Track changes and commit together.
244
-
245
- ```typescript
246
- class UnitOfWork {
247
- private newObjects = new Set<any>();
248
- private dirtyObjects = new Set<any>();
249
-
250
- registerNew(obj: any): void { this.newObjects.add(obj); }
251
- registerDirty(obj: any): void { this.dirtyObjects.add(obj); }
252
-
253
- async commit(): Promise<void> {
254
- await this.db.beginTransaction();
255
- try {
256
- for (const obj of this.newObjects) await this.insert(obj);
257
- for (const obj of this.dirtyObjects) await this.update(obj);
258
- await this.db.commit();
259
- } catch (e) {
260
- await this.db.rollback();
261
- throw e;
262
- }
263
- }
264
- }
265
- ```
266
-
267
- ## Identity Map
268
-
269
- Ensure each object loaded only once per session.
270
-
271
- ```typescript
272
- class IdentityMap {
273
- private map = new Map<string, any>();
274
-
275
- get(id: string): any | null { return this.map.get(id) || null; }
276
- put(id: string, obj: any): void { this.map.set(id, obj); }
277
- }
278
- ```
279
-
280
- ## Best Practices
281
-
282
- - Return domain objects from repositories
283
- - Use one repository per aggregate root
284
- - Keep repositories focused on persistence
285
- - Don't leak database details into domain
286
-
287
-
288
- ---
289
-
290
- # Distribution Patterns
291
-
292
- ## Remote Facade
293
-
294
- Coarse-grained interface to reduce network calls.
295
-
296
- ```typescript
297
- // Bad: Multiple network calls
298
- const customer = await api.getCustomer(id);
299
- const orders = await api.getOrders(id);
300
- const addresses = await api.getAddresses(id);
301
-
302
- // Good: Single call via facade
303
- const details = await api.getCustomerDetails(id);
304
- // Returns { customer, orders, addresses }
305
- ```
306
-
307
- ## Data Transfer Object (DTO)
308
-
309
- Bundle data for transfer across boundaries.
310
-
311
- ```typescript
312
- interface OrderDTO {
313
- id: string;
314
- customerId: string;
315
- items: OrderItemDTO[];
316
- total: number;
317
- status: string;
318
- }
319
-
320
- class OrderDTOMapper {
321
- static toDTO(order: Order): OrderDTO {
322
- return {
323
- id: order.id,
324
- customerId: order.customer.id,
325
- items: order.items.map(i => this.itemToDTO(i)),
326
- total: order.total.amount,
327
- status: order.status.toString()
328
- };
329
- }
330
- }
331
- ```
332
-
333
- ## Gateway
334
-
335
- Abstract external system access.
336
-
337
- ```typescript
338
- interface PaymentGateway {
339
- charge(amount: Money, method: PaymentMethod): Promise<PaymentResult>;
340
- }
341
-
342
- class StripeGateway implements PaymentGateway {
343
- async charge(amount: Money, method: PaymentMethod): Promise<PaymentResult> {
344
- const result = await this.stripe.paymentIntents.create({
345
- amount: amount.cents,
346
- currency: amount.currency
347
- });
348
- return this.mapToResult(result);
349
- }
350
- }
351
- ```
352
-
353
- ## Service Stub
354
-
355
- Test double for external services.
356
-
357
- ```typescript
358
- class StubPaymentGateway implements PaymentGateway {
359
- private shouldSucceed = true;
360
-
361
- async charge(amount: Money): Promise<PaymentResult> {
362
- if (!this.shouldSucceed) throw new PaymentDeclinedError();
363
- return { success: true, transactionId: 'stub-123' };
364
- }
365
-
366
- configureFail(): void { this.shouldSucceed = false; }
367
- }
368
- ```
369
-
370
- ## Best Practices
371
-
372
- - Design facades around client use cases
373
- - Keep DTOs simple and serializable
374
- - Isolate vendor code in gateways
375
- - Use stubs for testing, not production
376
-
377
-
378
- ---
379
-
380
- # Domain Logic Patterns
381
-
382
- ## Transaction Script
383
-
384
- Procedural approach - one procedure per operation.
385
-
386
- ```typescript
387
- async function transferMoney(fromId: string, toId: string, amount: number) {
388
- const db = await Database.connect();
389
- await db.beginTransaction();
390
-
391
- try {
392
- const from = await db.query('SELECT * FROM accounts WHERE id = $1', [fromId]);
393
- if (from.balance < amount) throw new Error('Insufficient funds');
394
-
395
- await db.execute('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, fromId]);
396
- await db.execute('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, toId]);
397
- await db.commit();
398
- } catch (e) {
399
- await db.rollback();
400
- throw e;
401
- }
402
- }
403
- ```
404
-
405
- **Use for:** Simple apps, CRUD, reports.
406
-
407
- ## Domain Model
408
-
409
- Rich objects with behavior.
410
-
411
- ```typescript
412
- class Account {
413
- constructor(private balance: Money, private overdraftLimit: Money) {}
414
-
415
- withdraw(amount: Money): void {
416
- if (!this.canWithdraw(amount)) throw new InsufficientFundsError();
417
- this.balance = this.balance.subtract(amount);
418
- }
419
-
420
- transfer(amount: Money, recipient: Account): void {
421
- this.withdraw(amount);
422
- recipient.deposit(amount);
423
- }
424
- }
425
- ```
426
-
427
- **Use for:** Complex business rules, rich domains.
428
-
429
- ## Service Layer
430
-
431
- Application boundary coordinating domain objects.
432
-
433
- ```typescript
434
- class AccountService {
435
- constructor(
436
- private accountRepo: AccountRepository,
437
- private unitOfWork: UnitOfWork
438
- ) {}
439
-
440
- async transfer(fromId: string, toId: string, amount: Money): Promise<void> {
441
- const from = await this.accountRepo.findById(fromId);
442
- const to = await this.accountRepo.findById(toId);
443
-
444
- from.transfer(amount, to); // Domain logic
445
-
446
- await this.accountRepo.save(from);
447
- await this.accountRepo.save(to);
448
- await this.unitOfWork.commit();
449
- }
450
- }
451
- ```
452
-
453
- **Use for:** API boundaries, multiple clients, transaction coordination.
454
-
455
- ## Best Practices
456
-
457
- - Choose pattern based on complexity
458
- - Service layer orchestrates, domain model contains logic
459
- - Keep services thin, domain objects rich
460
- - Combine Domain Model + Service Layer for complex apps
461
-
462
-
463
- ---
464
-
465
- # Gang of Four Patterns
466
-
467
- ## Creational
468
-
469
- ### Factory Method
470
- ```typescript
471
- interface Logger { log(msg: string): void; }
472
-
473
- abstract class Application {
474
- abstract createLogger(): Logger;
475
- run(): void { this.createLogger().log('Started'); }
476
- }
477
-
478
- class DevApp extends Application {
479
- createLogger(): Logger { return new ConsoleLogger(); }
480
- }
481
- ```
482
-
483
- ### Builder
484
- ```typescript
485
- const query = new QueryBuilder()
486
- .from('users')
487
- .select('id', 'name')
488
- .where('active = true')
489
- .limit(10)
490
- .build();
491
- ```
492
-
493
- ## Structural
494
-
495
- ### Adapter
496
- ```typescript
497
- class PaymentAdapter implements PaymentProcessor {
498
- constructor(private legacy: OldPaymentSystem) {}
499
-
500
- async process(amount: number): Promise<boolean> {
501
- return this.legacy.makePayment(amount);
502
- }
503
- }
504
- ```
505
-
506
- ### Decorator
507
- ```typescript
508
- interface Coffee { cost(): number; }
509
-
510
- class MilkDecorator implements Coffee {
511
- constructor(private coffee: Coffee) {}
512
- cost(): number { return this.coffee.cost() + 2; }
513
- }
514
-
515
- let coffee: Coffee = new SimpleCoffee();
516
- coffee = new MilkDecorator(coffee);
517
- ```
518
-
519
- ### Facade
520
- ```typescript
521
- class ComputerFacade {
522
- start(): void {
523
- this.cpu.freeze();
524
- this.memory.load(0, this.hdd.read(0, 1024));
525
- this.cpu.execute();
526
- }
527
- }
528
- ```
529
-
530
- ## Behavioral
531
-
532
- ### Strategy
533
- ```typescript
534
- interface SortStrategy { sort(data: number[]): number[]; }
535
-
536
- class Sorter {
537
- constructor(private strategy: SortStrategy) {}
538
- sort(data: number[]): number[] { return this.strategy.sort(data); }
539
- }
540
- ```
541
-
542
- ### Observer
543
- ```typescript
544
- class Stock {
545
- private observers: Observer[] = [];
546
-
547
- attach(o: Observer): void { this.observers.push(o); }
548
- notify(): void { this.observers.forEach(o => o.update(this)); }
549
-
550
- setPrice(price: number): void {
551
- this.price = price;
552
- this.notify();
553
- }
554
- }
555
- ```
556
-
557
- ### Command
558
- ```typescript
559
- interface Command { execute(): void; undo(): void; }
560
-
561
- class AppendCommand implements Command {
562
- constructor(private editor: Editor, private text: string) {}
563
- execute(): void { this.editor.append(this.text); }
564
- undo(): void { this.editor.delete(this.text.length); }
565
- }
566
- ```
567
-
568
- ## Best Practices
569
-
570
- - Use patterns to solve specific problems, not everywhere
571
- - Combine patterns when appropriate
572
- - Favor composition over inheritance
573
- - Keep implementations simple