tlc-claude-code 1.2.28 → 1.3.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 (87) hide show
  1. package/README.md +9 -4
  2. package/dashboard/dist/components/UsagePane.d.ts +13 -0
  3. package/dashboard/dist/components/UsagePane.js +51 -0
  4. package/dashboard/dist/components/UsagePane.test.d.ts +1 -0
  5. package/dashboard/dist/components/UsagePane.test.js +142 -0
  6. package/dashboard/dist/components/WorkspaceDocsPane.d.ts +19 -0
  7. package/dashboard/dist/components/WorkspaceDocsPane.js +146 -0
  8. package/dashboard/dist/components/WorkspaceDocsPane.test.d.ts +1 -0
  9. package/dashboard/dist/components/WorkspaceDocsPane.test.js +242 -0
  10. package/dashboard/dist/components/WorkspacePane.d.ts +18 -0
  11. package/dashboard/dist/components/WorkspacePane.js +17 -0
  12. package/dashboard/dist/components/WorkspacePane.test.d.ts +1 -0
  13. package/dashboard/dist/components/WorkspacePane.test.js +84 -0
  14. package/package.json +15 -4
  15. package/scripts/capture-screenshots.js +170 -0
  16. package/scripts/docs-update.js +253 -0
  17. package/scripts/generate-screenshots.js +321 -0
  18. package/scripts/project-docs.js +377 -0
  19. package/scripts/vps-setup.sh +477 -0
  20. package/server/lib/architecture-command.js +450 -0
  21. package/server/lib/architecture-command.test.js +754 -0
  22. package/server/lib/ast-analyzer.js +324 -0
  23. package/server/lib/ast-analyzer.test.js +437 -0
  24. package/server/lib/auth-system.test.js +4 -1
  25. package/server/lib/boundary-detector.js +427 -0
  26. package/server/lib/boundary-detector.test.js +320 -0
  27. package/server/lib/budget-alerts.js +138 -0
  28. package/server/lib/budget-alerts.test.js +235 -0
  29. package/server/lib/candidates-tracker.js +210 -0
  30. package/server/lib/candidates-tracker.test.js +300 -0
  31. package/server/lib/checkpoint-manager.js +251 -0
  32. package/server/lib/checkpoint-manager.test.js +474 -0
  33. package/server/lib/circular-detector.js +337 -0
  34. package/server/lib/circular-detector.test.js +353 -0
  35. package/server/lib/cohesion-analyzer.js +310 -0
  36. package/server/lib/cohesion-analyzer.test.js +447 -0
  37. package/server/lib/contract-testing.js +625 -0
  38. package/server/lib/contract-testing.test.js +342 -0
  39. package/server/lib/conversion-planner.js +469 -0
  40. package/server/lib/conversion-planner.test.js +361 -0
  41. package/server/lib/convert-command.js +351 -0
  42. package/server/lib/convert-command.test.js +608 -0
  43. package/server/lib/coupling-calculator.js +189 -0
  44. package/server/lib/coupling-calculator.test.js +509 -0
  45. package/server/lib/dependency-graph.js +367 -0
  46. package/server/lib/dependency-graph.test.js +516 -0
  47. package/server/lib/duplication-detector.js +349 -0
  48. package/server/lib/duplication-detector.test.js +401 -0
  49. package/server/lib/example-service.js +616 -0
  50. package/server/lib/example-service.test.js +397 -0
  51. package/server/lib/impact-scorer.js +184 -0
  52. package/server/lib/impact-scorer.test.js +211 -0
  53. package/server/lib/mermaid-generator.js +358 -0
  54. package/server/lib/mermaid-generator.test.js +301 -0
  55. package/server/lib/messaging-patterns.js +750 -0
  56. package/server/lib/messaging-patterns.test.js +213 -0
  57. package/server/lib/microservice-template.js +386 -0
  58. package/server/lib/microservice-template.test.js +325 -0
  59. package/server/lib/new-project-microservice.js +450 -0
  60. package/server/lib/new-project-microservice.test.js +600 -0
  61. package/server/lib/refactor-command.js +326 -0
  62. package/server/lib/refactor-command.test.js +528 -0
  63. package/server/lib/refactor-executor.js +254 -0
  64. package/server/lib/refactor-executor.test.js +305 -0
  65. package/server/lib/refactor-observer.js +292 -0
  66. package/server/lib/refactor-observer.test.js +422 -0
  67. package/server/lib/refactor-progress.js +193 -0
  68. package/server/lib/refactor-progress.test.js +251 -0
  69. package/server/lib/refactor-reporter.js +237 -0
  70. package/server/lib/refactor-reporter.test.js +247 -0
  71. package/server/lib/semantic-analyzer.js +198 -0
  72. package/server/lib/semantic-analyzer.test.js +474 -0
  73. package/server/lib/service-scaffold.js +486 -0
  74. package/server/lib/service-scaffold.test.js +373 -0
  75. package/server/lib/shared-kernel.js +578 -0
  76. package/server/lib/shared-kernel.test.js +255 -0
  77. package/server/lib/traefik-config.js +282 -0
  78. package/server/lib/traefik-config.test.js +312 -0
  79. package/server/lib/usage-command.js +218 -0
  80. package/server/lib/usage-command.test.js +391 -0
  81. package/server/lib/usage-formatter.js +192 -0
  82. package/server/lib/usage-formatter.test.js +267 -0
  83. package/server/lib/usage-history.js +122 -0
  84. package/server/lib/usage-history.test.js +206 -0
  85. package/server/package-lock.json +14 -0
  86. package/server/package.json +1 -0
  87. package/templates/docs-sync.yml +91 -0
@@ -0,0 +1,578 @@
1
+ /**
2
+ * Shared Kernel Generator Module
3
+ * Generates shared code structure for microservices
4
+ */
5
+
6
+ /**
7
+ * Capitalize first letter of string
8
+ * @param {string} str - String to capitalize
9
+ * @returns {string} Capitalized string
10
+ */
11
+ function capitalize(str) {
12
+ if (!str) return '';
13
+ return str.charAt(0).toUpperCase() + str.slice(1);
14
+ }
15
+
16
+ /**
17
+ * Generate package.json for shared kernel
18
+ * @param {Object} config - Configuration
19
+ * @param {string} config.projectName - Project name
20
+ * @returns {Object} Package.json content
21
+ */
22
+ function generatePackageJson(config) {
23
+ const { projectName = 'app' } = config;
24
+
25
+ return {
26
+ name: `@${projectName}/shared`,
27
+ version: '1.0.0',
28
+ description: `Shared types, contracts, and utilities for ${projectName}`,
29
+ type: 'module',
30
+ main: './index.js',
31
+ types: './index.d.ts',
32
+ exports: {
33
+ '.': {
34
+ types: './index.d.ts',
35
+ import: './index.js',
36
+ },
37
+ './types': {
38
+ types: './types/index.d.ts',
39
+ import: './types/index.js',
40
+ },
41
+ './contracts': {
42
+ types: './contracts/index.d.ts',
43
+ import: './contracts/index.js',
44
+ },
45
+ './events': {
46
+ types: './events/index.d.ts',
47
+ import: './events/index.js',
48
+ },
49
+ './utils': {
50
+ types: './utils/index.d.ts',
51
+ import: './utils/index.js',
52
+ },
53
+ },
54
+ scripts: {
55
+ build: 'tsc',
56
+ clean: 'rm -rf dist',
57
+ },
58
+ devDependencies: {
59
+ typescript: '^5.0.0',
60
+ },
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Generate TypeScript types for shared kernel
66
+ * @param {Object} config - Configuration
67
+ * @param {Array<string>} config.services - Service names
68
+ * @returns {string} TypeScript type definitions
69
+ */
70
+ function generateTypes(config) {
71
+ const { services = [] } = config;
72
+
73
+ const lines = [];
74
+
75
+ // Common types
76
+ lines.push('// Common Types');
77
+ lines.push('');
78
+ lines.push('export type ID = string;');
79
+ lines.push('');
80
+ lines.push('export type Timestamp = string;');
81
+ lines.push('');
82
+ lines.push('export interface PaginatedResponse<T> {');
83
+ lines.push(' data: T[];');
84
+ lines.push(' total: number;');
85
+ lines.push(' page: number;');
86
+ lines.push(' pageSize: number;');
87
+ lines.push(' hasMore: boolean;');
88
+ lines.push('}');
89
+ lines.push('');
90
+
91
+ // Service-specific types
92
+ if (services.length > 0) {
93
+ lines.push('// Service-Specific Types');
94
+ lines.push('');
95
+
96
+ for (const service of services) {
97
+ const typeName = capitalize(service);
98
+ lines.push(`export interface ${typeName} {`);
99
+ lines.push(' id: ID;');
100
+ lines.push(' createdAt: Timestamp;');
101
+ lines.push(' updatedAt: Timestamp;');
102
+ lines.push('}');
103
+ lines.push('');
104
+ }
105
+ }
106
+
107
+ return lines.join('\n');
108
+ }
109
+
110
+ /**
111
+ * Generate JSON Schema contracts for services
112
+ * @param {Array<string>} services - Service names
113
+ * @returns {Object} Contract schemas by service
114
+ */
115
+ function generateContracts(services) {
116
+ const contracts = {};
117
+
118
+ for (const service of services) {
119
+ const serviceName = capitalize(service);
120
+
121
+ contracts[service] = {
122
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
123
+ $id: `${service}-contract`,
124
+ title: `${serviceName} Service Contract`,
125
+ description: `API contract for ${serviceName} service`,
126
+ definitions: {
127
+ Request: {
128
+ type: 'object',
129
+ properties: {
130
+ id: { type: 'string', description: 'Resource identifier' },
131
+ },
132
+ },
133
+ Response: {
134
+ type: 'object',
135
+ properties: {
136
+ id: { type: 'string' },
137
+ createdAt: { type: 'string', format: 'date-time' },
138
+ updatedAt: { type: 'string', format: 'date-time' },
139
+ },
140
+ required: ['id'],
141
+ },
142
+ ErrorResponse: {
143
+ type: 'object',
144
+ properties: {
145
+ error: {
146
+ type: 'object',
147
+ properties: {
148
+ code: { type: 'string' },
149
+ message: { type: 'string' },
150
+ details: { type: 'object' },
151
+ },
152
+ required: ['code', 'message'],
153
+ },
154
+ },
155
+ required: ['error'],
156
+ },
157
+ },
158
+ };
159
+ }
160
+
161
+ return contracts;
162
+ }
163
+
164
+ /**
165
+ * Generate event definitions for shared kernel
166
+ * @param {Array<string>} events - Event names
167
+ * @returns {Object} Event definitions
168
+ */
169
+ function generateEvents(events) {
170
+ // Base event interface
171
+ const base = `// Base Event Interface
172
+ export interface BaseEvent<T = unknown> {
173
+ id: string;
174
+ timestamp: string;
175
+ source: string;
176
+ type: string;
177
+ payload: T;
178
+ metadata?: Record<string, unknown>;
179
+ }
180
+ `;
181
+
182
+ // Per-event schemas
183
+ const schemas = {};
184
+ for (const event of events) {
185
+ schemas[event] = `export interface ${event}Event extends BaseEvent<${event}Payload> {
186
+ type: '${event}';
187
+ payload: ${event}Payload;
188
+ }
189
+
190
+ export interface ${event}Payload {
191
+ // Define payload fields for ${event}
192
+ }
193
+ `;
194
+ }
195
+
196
+ // Event catalog
197
+ const catalogLines = [
198
+ '// Event Catalog',
199
+ '',
200
+ 'export const EventCatalog = {',
201
+ ];
202
+
203
+ for (const event of events) {
204
+ catalogLines.push(` ${event}: '${event}',`);
205
+ }
206
+
207
+ catalogLines.push('} as const;');
208
+ catalogLines.push('');
209
+ catalogLines.push('export type EventType = keyof typeof EventCatalog;');
210
+
211
+ const catalog = catalogLines.join('\n');
212
+
213
+ return {
214
+ base,
215
+ schemas,
216
+ catalog,
217
+ };
218
+ }
219
+
220
+ /**
221
+ * Generate utility modules for shared kernel
222
+ * @returns {Object} Utility module contents
223
+ */
224
+ function generateUtils() {
225
+ const logger = `// Logger Utility
226
+
227
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
228
+
229
+ export interface Logger {
230
+ debug(message: string, meta?: Record<string, unknown>): void;
231
+ info(message: string, meta?: Record<string, unknown>): void;
232
+ warn(message: string, meta?: Record<string, unknown>): void;
233
+ error(message: string, meta?: Record<string, unknown>): void;
234
+ log(level: LogLevel, message: string, meta?: Record<string, unknown>): void;
235
+ }
236
+
237
+ export function createLogger(name: string): Logger {
238
+ const log = (level: LogLevel, message: string, meta?: Record<string, unknown>) => {
239
+ const timestamp = new Date().toISOString();
240
+ console[level](\`[\${timestamp}] [\${level.toUpperCase()}] [\${name}] \${message}\`, meta || '');
241
+ };
242
+
243
+ return {
244
+ debug: (message, meta) => log('debug', message, meta),
245
+ info: (message, meta) => log('info', message, meta),
246
+ warn: (message, meta) => log('warn', message, meta),
247
+ error: (message, meta) => log('error', message, meta),
248
+ log,
249
+ };
250
+ }
251
+ `;
252
+
253
+ const errors = `// Error Classes
254
+
255
+ export class AppError extends Error {
256
+ public readonly code: string;
257
+ public readonly statusCode: number;
258
+ public readonly details?: Record<string, unknown>;
259
+
260
+ constructor(message: string, code: string = 'APP_ERROR', statusCode: number = 500, details?: Record<string, unknown>) {
261
+ super(message);
262
+ this.name = this.constructor.name;
263
+ this.code = code;
264
+ this.statusCode = statusCode;
265
+ this.details = details;
266
+ Error.captureStackTrace(this, this.constructor);
267
+ }
268
+
269
+ toJSON() {
270
+ return {
271
+ error: {
272
+ code: this.code,
273
+ message: this.message,
274
+ details: this.details,
275
+ },
276
+ };
277
+ }
278
+ }
279
+
280
+ export class ValidationError extends AppError {
281
+ constructor(message: string, details?: Record<string, unknown>) {
282
+ super(message, 'VALIDATION_ERROR', 400, details);
283
+ }
284
+ }
285
+
286
+ export class NotFoundError extends AppError {
287
+ constructor(resource: string, id?: string) {
288
+ const message = id ? \`\${resource} with id '\${id}' not found\` : \`\${resource} not found\`;
289
+ super(message, 'NOT_FOUND', 404, { resource, id });
290
+ }
291
+ }
292
+
293
+ export class UnauthorizedError extends AppError {
294
+ constructor(message: string = 'Unauthorized') {
295
+ super(message, 'UNAUTHORIZED', 401);
296
+ }
297
+ }
298
+
299
+ export class ForbiddenError extends AppError {
300
+ constructor(message: string = 'Forbidden') {
301
+ super(message, 'FORBIDDEN', 403);
302
+ }
303
+ }
304
+ `;
305
+
306
+ const validation = `// Validation Helpers
307
+
308
+ export interface ValidationResult {
309
+ valid: boolean;
310
+ errors: ValidationError[];
311
+ }
312
+
313
+ export interface ValidationError {
314
+ field: string;
315
+ message: string;
316
+ code: string;
317
+ }
318
+
319
+ export function validate<T>(
320
+ data: T,
321
+ rules: Record<keyof T, (value: unknown) => string | null>
322
+ ): ValidationResult {
323
+ const errors: ValidationError[] = [];
324
+
325
+ for (const [field, rule] of Object.entries(rules) as Array<[keyof T, (value: unknown) => string | null]>) {
326
+ const error = rule(data[field]);
327
+ if (error) {
328
+ errors.push({
329
+ field: String(field),
330
+ message: error,
331
+ code: 'VALIDATION_FAILED',
332
+ });
333
+ }
334
+ }
335
+
336
+ return {
337
+ valid: errors.length === 0,
338
+ errors,
339
+ };
340
+ }
341
+
342
+ export const validators = {
343
+ required: (value: unknown) => (value == null || value === '' ? 'Required' : null),
344
+ email: (value: unknown) =>
345
+ typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value) ? null : 'Invalid email',
346
+ minLength: (min: number) => (value: unknown) =>
347
+ typeof value === 'string' && value.length >= min ? null : \`Minimum length is \${min}\`,
348
+ maxLength: (max: number) => (value: unknown) =>
349
+ typeof value === 'string' && value.length <= max ? null : \`Maximum length is \${max}\`,
350
+ uuid: (value: unknown) =>
351
+ typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)
352
+ ? null
353
+ : 'Invalid UUID',
354
+ };
355
+ `;
356
+
357
+ return {
358
+ logger,
359
+ errors,
360
+ validation,
361
+ };
362
+ }
363
+
364
+ /**
365
+ * Shared Kernel class for generating microservice shared code
366
+ */
367
+ class SharedKernel {
368
+ /**
369
+ * Create a SharedKernel instance
370
+ * @param {Object} options - Configuration options
371
+ * @param {string} options.projectName - Project name
372
+ */
373
+ constructor(options = {}) {
374
+ this.projectName = options.projectName || 'app';
375
+ }
376
+
377
+ /**
378
+ * Generate complete shared kernel
379
+ * @param {Object} config - Generation config
380
+ * @param {Array<string>} config.services - Service names
381
+ * @param {Array<string>} config.events - Event names
382
+ * @returns {Object} Generated structure
383
+ */
384
+ generate(config) {
385
+ const { services = [], events = [] } = config;
386
+
387
+ const directories = [
388
+ 'shared',
389
+ 'shared/types',
390
+ 'shared/contracts',
391
+ 'shared/events',
392
+ 'shared/utils',
393
+ ];
394
+
395
+ const files = [];
396
+
397
+ // Package.json
398
+ const pkg = generatePackageJson({ projectName: this.projectName });
399
+ files.push({
400
+ path: 'shared/package.json',
401
+ content: JSON.stringify(pkg, null, 2),
402
+ });
403
+
404
+ // Types
405
+ const types = generateTypes({ services });
406
+ files.push({
407
+ path: 'shared/types/index.ts',
408
+ content: types,
409
+ });
410
+
411
+ // Contracts
412
+ const contracts = generateContracts(services);
413
+ files.push({
414
+ path: 'shared/contracts/index.ts',
415
+ content: this._generateContractsIndex(contracts),
416
+ });
417
+
418
+ for (const [service, schema] of Object.entries(contracts)) {
419
+ files.push({
420
+ path: `shared/contracts/${service}.schema.json`,
421
+ content: JSON.stringify(schema, null, 2),
422
+ });
423
+ }
424
+
425
+ // Events
426
+ const eventDefs = generateEvents(events);
427
+ files.push({
428
+ path: 'shared/events/index.ts',
429
+ content: this._generateEventsIndex(eventDefs, events),
430
+ });
431
+
432
+ // Utils
433
+ const utils = generateUtils();
434
+ files.push({
435
+ path: 'shared/utils/logger.ts',
436
+ content: utils.logger,
437
+ });
438
+ files.push({
439
+ path: 'shared/utils/errors.ts',
440
+ content: utils.errors,
441
+ });
442
+ files.push({
443
+ path: 'shared/utils/validation.ts',
444
+ content: utils.validation,
445
+ });
446
+ files.push({
447
+ path: 'shared/utils/index.ts',
448
+ content: this._generateUtilsIndex(),
449
+ });
450
+
451
+ // Root index
452
+ files.push({
453
+ path: 'shared/index.ts',
454
+ content: this._generateRootIndex(),
455
+ });
456
+
457
+ // tsconfig
458
+ files.push({
459
+ path: 'shared/tsconfig.json',
460
+ content: JSON.stringify(this._generateTsConfig(), null, 2),
461
+ });
462
+
463
+ return { directories, files };
464
+ }
465
+
466
+ /**
467
+ * Generate contracts index file
468
+ * @private
469
+ */
470
+ _generateContractsIndex(contracts) {
471
+ const lines = ['// Contract schemas'];
472
+ lines.push('');
473
+
474
+ for (const service of Object.keys(contracts)) {
475
+ lines.push(`export { default as ${capitalize(service)}Contract } from './${service}.schema.json';`);
476
+ }
477
+
478
+ if (Object.keys(contracts).length === 0) {
479
+ lines.push('// No contracts defined');
480
+ }
481
+
482
+ return lines.join('\n') + '\n';
483
+ }
484
+
485
+ /**
486
+ * Generate events index file
487
+ * @private
488
+ */
489
+ _generateEventsIndex(eventDefs, events) {
490
+ const lines = [];
491
+ lines.push(eventDefs.base);
492
+ lines.push('');
493
+
494
+ for (const event of events) {
495
+ lines.push(eventDefs.schemas[event]);
496
+ }
497
+
498
+ lines.push(eventDefs.catalog);
499
+
500
+ return lines.join('\n');
501
+ }
502
+
503
+ /**
504
+ * Generate utils index file
505
+ * @private
506
+ */
507
+ _generateUtilsIndex() {
508
+ return `export * from './logger';
509
+ export * from './errors';
510
+ export * from './validation';
511
+ `;
512
+ }
513
+
514
+ /**
515
+ * Generate root index file
516
+ * @private
517
+ */
518
+ _generateRootIndex() {
519
+ return `export * from './types';
520
+ export * from './events';
521
+ export * from './utils';
522
+ `;
523
+ }
524
+
525
+ /**
526
+ * Generate TypeScript config
527
+ * @private
528
+ */
529
+ _generateTsConfig() {
530
+ return {
531
+ compilerOptions: {
532
+ target: 'ES2020',
533
+ module: 'ESNext',
534
+ moduleResolution: 'node',
535
+ declaration: true,
536
+ declarationMap: true,
537
+ sourceMap: true,
538
+ outDir: './dist',
539
+ rootDir: './',
540
+ strict: true,
541
+ esModuleInterop: true,
542
+ skipLibCheck: true,
543
+ forceConsistentCasingInFileNames: true,
544
+ resolveJsonModule: true,
545
+ },
546
+ include: ['./**/*.ts'],
547
+ exclude: ['node_modules', 'dist'],
548
+ };
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Create shared kernel generator instance
554
+ * @param {Object} options - Generator options
555
+ * @returns {Object} Generator instance
556
+ */
557
+ function createSharedKernel(options = {}) {
558
+ const kernel = new SharedKernel(options);
559
+ return {
560
+ generate: (config) => kernel.generate(config),
561
+ generatePackageJson: () => generatePackageJson({ projectName: kernel.projectName }),
562
+ generateTypes: (config) => generateTypes(config),
563
+ generateContracts: (services) => generateContracts(services),
564
+ generateEvents: (events) => generateEvents(events),
565
+ generateUtils: () => generateUtils(),
566
+ };
567
+ }
568
+
569
+ module.exports = {
570
+ SharedKernel,
571
+ createSharedKernel,
572
+ generatePackageJson,
573
+ generateTypes,
574
+ generateContracts,
575
+ generateEvents,
576
+ generateUtils,
577
+ capitalize,
578
+ };