claude-autopm 1.18.0 → 1.20.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 (75) hide show
  1. package/README.md +159 -0
  2. package/autopm/.claude/agents/core/mcp-manager.md +1 -1
  3. package/autopm/.claude/commands/pm/context.md +11 -0
  4. package/autopm/.claude/commands/pm/epic-decompose.md +25 -2
  5. package/autopm/.claude/commands/pm/epic-oneshot.md +13 -0
  6. package/autopm/.claude/commands/pm/epic-start.md +19 -0
  7. package/autopm/.claude/commands/pm/epic-sync-modular.md +10 -10
  8. package/autopm/.claude/commands/pm/epic-sync.md +14 -14
  9. package/autopm/.claude/commands/pm/issue-start.md +50 -5
  10. package/autopm/.claude/commands/pm/issue-sync.md +15 -15
  11. package/autopm/.claude/commands/pm/what-next.md +11 -0
  12. package/autopm/.claude/mcp/MCP-REGISTRY.md +1 -1
  13. package/autopm/.claude/scripts/azure/active-work.js +2 -2
  14. package/autopm/.claude/scripts/azure/blocked.js +13 -13
  15. package/autopm/.claude/scripts/azure/daily.js +1 -1
  16. package/autopm/.claude/scripts/azure/dashboard.js +1 -1
  17. package/autopm/.claude/scripts/azure/feature-list.js +2 -2
  18. package/autopm/.claude/scripts/azure/feature-status.js +1 -1
  19. package/autopm/.claude/scripts/azure/next-task.js +1 -1
  20. package/autopm/.claude/scripts/azure/search.js +1 -1
  21. package/autopm/.claude/scripts/azure/setup.js +15 -15
  22. package/autopm/.claude/scripts/azure/sprint-report.js +2 -2
  23. package/autopm/.claude/scripts/azure/sync.js +1 -1
  24. package/autopm/.claude/scripts/azure/us-list.js +1 -1
  25. package/autopm/.claude/scripts/azure/us-status.js +1 -1
  26. package/autopm/.claude/scripts/azure/validate.js +13 -13
  27. package/autopm/.claude/scripts/lib/frontmatter-utils.sh +42 -7
  28. package/autopm/.claude/scripts/lib/logging-utils.sh +20 -16
  29. package/autopm/.claude/scripts/lib/validation-utils.sh +1 -1
  30. package/autopm/.claude/scripts/pm/context.js +338 -0
  31. package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +3 -3
  32. package/autopm/.claude/scripts/pm/lib/README.md +85 -0
  33. package/autopm/.claude/scripts/pm/lib/logger.js +78 -0
  34. package/autopm/.claude/scripts/pm/next.js +25 -1
  35. package/autopm/.claude/scripts/pm/what-next.js +660 -0
  36. package/bin/autopm.js +25 -0
  37. package/package.json +1 -1
  38. package/lib/agentExecutor.js.deprecated +0 -101
  39. package/lib/azure/cache.js +0 -80
  40. package/lib/azure/client.js +0 -77
  41. package/lib/azure/formatter.js +0 -177
  42. package/lib/commandHelpers.js +0 -177
  43. package/lib/context/manager.js +0 -290
  44. package/lib/documentation/manager.js +0 -528
  45. package/lib/github/workflow-manager.js +0 -546
  46. package/lib/helpers/azure-batch-api.js +0 -133
  47. package/lib/helpers/azure-cache-manager.js +0 -287
  48. package/lib/helpers/azure-parallel-processor.js +0 -158
  49. package/lib/helpers/azure-work-item-create.js +0 -278
  50. package/lib/helpers/gh-issue-create.js +0 -250
  51. package/lib/helpers/interactive-prompt.js +0 -336
  52. package/lib/helpers/output-manager.js +0 -335
  53. package/lib/helpers/progress-indicator.js +0 -258
  54. package/lib/performance/benchmarker.js +0 -429
  55. package/lib/pm/epic-decomposer.js +0 -273
  56. package/lib/pm/epic-syncer.js +0 -221
  57. package/lib/prdMetadata.js +0 -270
  58. package/lib/providers/azure/index.js +0 -234
  59. package/lib/providers/factory.js +0 -87
  60. package/lib/providers/github/index.js +0 -204
  61. package/lib/providers/interface.js +0 -73
  62. package/lib/python/scaffold-manager.js +0 -576
  63. package/lib/react/scaffold-manager.js +0 -745
  64. package/lib/regression/analyzer.js +0 -578
  65. package/lib/release/manager.js +0 -324
  66. package/lib/tailwind/manager.js +0 -486
  67. package/lib/traefik/manager.js +0 -484
  68. package/lib/utils/colors.js +0 -126
  69. package/lib/utils/config.js +0 -317
  70. package/lib/utils/filesystem.js +0 -316
  71. package/lib/utils/logger.js +0 -135
  72. package/lib/utils/prompts.js +0 -294
  73. package/lib/utils/shell.js +0 -237
  74. package/lib/validators/email-validator.js +0 -337
  75. package/lib/workflow/manager.js +0 -449
@@ -1,484 +0,0 @@
1
- /**
2
- * Traefik Configuration Manager
3
- * Centralized Traefik setup and configuration functionality
4
- */
5
-
6
- const fs = require('fs').promises;
7
- const path = require('path');
8
- const { exec } = require('child_process');
9
- const { promisify } = require('util');
10
- const execAsync = promisify(exec);
11
-
12
- /**
13
- * Configuration constants
14
- */
15
- const CONFIG = {
16
- directories: {
17
- traefik: '.claude/traefik'
18
- },
19
- defaults: {
20
- traefikImage: 'traefik:v2.9',
21
- network: 'web',
22
- dashboardPort: 8080,
23
- httpPort: 80,
24
- httpsPort: 443
25
- },
26
- files: {
27
- config: 'traefik.yml',
28
- dockerCompose: 'docker-compose.yml',
29
- routes: 'routes.json'
30
- }
31
- };
32
-
33
- /**
34
- * Default configurations
35
- */
36
- const DEFAULT_CONFIGS = {
37
- traefik: {
38
- api: {
39
- dashboard: true,
40
- debug: false
41
- },
42
- entryPoints: {
43
- web: {
44
- address: ':80'
45
- },
46
- websecure: {
47
- address: ':443'
48
- }
49
- },
50
- providers: {
51
- docker: {
52
- endpoint: 'unix:///var/run/docker.sock',
53
- exposedByDefault: false
54
- },
55
- file: {
56
- directory: '/etc/traefik/dynamic',
57
- watch: true
58
- }
59
- },
60
- log: {
61
- level: 'INFO'
62
- },
63
- accessLog: {}
64
- },
65
- routes: {
66
- routes: [
67
- {
68
- name: 'api',
69
- rule: 'PathPrefix(`/api`)',
70
- service: 'api-service',
71
- servers: [{ url: 'http://api:3000' }]
72
- },
73
- {
74
- name: 'web',
75
- rule: 'Host(`localhost`)',
76
- service: 'web-service',
77
- servers: [{ url: 'http://web:80' }]
78
- }
79
- ]
80
- }
81
- };
82
-
83
- class TraefikManager {
84
- constructor(projectRoot = process.cwd()) {
85
- this.projectRoot = projectRoot;
86
- this.traefikDir = path.join(projectRoot, CONFIG.directories.traefik);
87
- }
88
-
89
- /**
90
- * Generates Traefik configuration
91
- */
92
- async generateConfig(options = {}) {
93
- await fs.mkdir(this.traefikDir, { recursive: true });
94
-
95
- const config = {
96
- ...DEFAULT_CONFIGS.traefik,
97
- api: {
98
- ...DEFAULT_CONFIGS.traefik.api,
99
- debug: options.debug || false
100
- },
101
- log: {
102
- level: options.logLevel || 'INFO'
103
- }
104
- };
105
-
106
- const configPath = path.join(this.traefikDir, CONFIG.files.config);
107
- const yaml = this.generateYAML(config);
108
- await fs.writeFile(configPath, yaml);
109
-
110
- return {
111
- path: configPath,
112
- config: config
113
- };
114
- }
115
-
116
- /**
117
- * Generates Docker Compose configuration
118
- */
119
- async generateDockerCompose(options = {}) {
120
- await fs.mkdir(this.traefikDir, { recursive: true });
121
-
122
- const dockerCompose = {
123
- version: '3.8',
124
- services: {
125
- traefik: {
126
- image: options.image || CONFIG.defaults.traefikImage,
127
- container_name: 'traefik',
128
- restart: 'unless-stopped',
129
- ports: [
130
- `${CONFIG.defaults.httpPort}:80`,
131
- `${CONFIG.defaults.httpsPort}:443`,
132
- `${CONFIG.defaults.dashboardPort}:8080`
133
- ],
134
- volumes: [
135
- '/var/run/docker.sock:/var/run/docker.sock:ro',
136
- './traefik.yml:/traefik.yml:ro',
137
- './dynamic:/etc/traefik/dynamic:ro',
138
- './letsencrypt:/letsencrypt'
139
- ],
140
- networks: [CONFIG.defaults.network],
141
- labels: {
142
- 'traefik.enable': 'true',
143
- 'traefik.http.routers.dashboard.rule': 'Host(`traefik.localhost`)',
144
- 'traefik.http.routers.dashboard.service': 'api@internal',
145
- 'traefik.http.routers.dashboard.middlewares': 'auth'
146
- }
147
- }
148
- },
149
- networks: {
150
- [CONFIG.defaults.network]: {
151
- external: true
152
- }
153
- }
154
- };
155
-
156
- const dockerPath = path.join(this.traefikDir, CONFIG.files.dockerCompose);
157
- const yaml = this.generateYAML(dockerCompose);
158
- await fs.writeFile(dockerPath, yaml);
159
-
160
- return {
161
- path: dockerPath,
162
- config: dockerCompose
163
- };
164
- }
165
-
166
- /**
167
- * Configures routes
168
- */
169
- async configureRoutes(customRoutes = null) {
170
- await fs.mkdir(this.traefikDir, { recursive: true });
171
- const routesPath = path.join(this.traefikDir, CONFIG.files.routes);
172
-
173
- let routesConfig;
174
- if (customRoutes) {
175
- routesConfig = customRoutes;
176
- } else {
177
- try {
178
- const content = await fs.readFile(routesPath, 'utf8');
179
- routesConfig = JSON.parse(content);
180
- } catch (error) {
181
- routesConfig = DEFAULT_CONFIGS.routes;
182
- await fs.writeFile(routesPath, JSON.stringify(routesConfig, null, 2));
183
- }
184
- }
185
-
186
- // Generate dynamic configuration for each route
187
- for (const route of routesConfig.routes) {
188
- const dynamicConfig = {
189
- http: {
190
- routers: {
191
- [route.name]: {
192
- rule: route.rule,
193
- service: route.service,
194
- middlewares: route.middlewares || []
195
- }
196
- },
197
- services: {
198
- [route.service]: {
199
- loadBalancer: {
200
- servers: route.servers || [{ url: 'http://localhost:3000' }]
201
- }
202
- }
203
- }
204
- }
205
- };
206
-
207
- const dynamicPath = path.join(this.traefikDir, `dynamic-${route.name}.yml`);
208
- await fs.writeFile(dynamicPath, this.generateYAML(dynamicConfig));
209
- }
210
-
211
- return {
212
- routes: routesConfig.routes,
213
- path: routesPath
214
- };
215
- }
216
-
217
- /**
218
- * Configures SSL/TLS
219
- */
220
- async configureSSL(domain) {
221
- await fs.mkdir(this.traefikDir, { recursive: true });
222
-
223
- const sslConfig = {
224
- tls: {
225
- certificates: [
226
- {
227
- certFile: `/letsencrypt/certs/${domain}.crt`,
228
- keyFile: `/letsencrypt/certs/${domain}.key`
229
- }
230
- ],
231
- stores: {
232
- default: {
233
- defaultCertificate: {
234
- certFile: `/letsencrypt/certs/${domain}.crt`,
235
- keyFile: `/letsencrypt/certs/${domain}.key`
236
- }
237
- }
238
- }
239
- }
240
- };
241
-
242
- const sslPath = path.join(this.traefikDir, 'ssl-config.yml');
243
- await fs.writeFile(sslPath, this.generateYAML(sslConfig));
244
-
245
- return {
246
- path: sslPath,
247
- domain: domain,
248
- config: sslConfig
249
- };
250
- }
251
-
252
- /**
253
- * Configures Let's Encrypt
254
- */
255
- async configureLetsEncrypt(email, staging = false) {
256
- await fs.mkdir(this.traefikDir, { recursive: true });
257
-
258
- const acmeConfig = {
259
- certificatesResolvers: {
260
- letsencrypt: {
261
- acme: {
262
- email: email,
263
- storage: '/letsencrypt/acme.json',
264
- httpChallenge: {
265
- entryPoint: 'web'
266
- },
267
- caServer: staging
268
- ? 'https://acme-staging-v02.api.letsencrypt.org/directory'
269
- : 'https://acme-v02.api.letsencrypt.org/directory'
270
- }
271
- }
272
- }
273
- };
274
-
275
- const acmePath = path.join(this.traefikDir, 'letsencrypt-config.yml');
276
- await fs.writeFile(acmePath, this.generateYAML(acmeConfig));
277
-
278
- return {
279
- path: acmePath,
280
- email: email,
281
- staging: staging,
282
- config: acmeConfig
283
- };
284
- }
285
-
286
- /**
287
- * Configures middleware
288
- */
289
- async configureMiddleware(type, options = {}) {
290
- await fs.mkdir(this.traefikDir, { recursive: true });
291
-
292
- const middlewares = {
293
- http: {
294
- middlewares: {}
295
- }
296
- };
297
-
298
- switch (type) {
299
- case 'auth':
300
- middlewares.http.middlewares.auth = {
301
- basicAuth: {
302
- users: options.users || ['admin:$2y$10$...']
303
- }
304
- };
305
- break;
306
-
307
- case 'compress':
308
- middlewares.http.middlewares.compress = {
309
- compress: {}
310
- };
311
- break;
312
-
313
- case 'redirect':
314
- middlewares.http.middlewares['redirect-to-https'] = {
315
- redirectScheme: {
316
- scheme: 'https',
317
- permanent: true
318
- }
319
- };
320
- break;
321
-
322
- case 'ratelimit':
323
- middlewares.http.middlewares['rate-limit'] = {
324
- rateLimit: {
325
- average: options.average || 100,
326
- burst: options.burst || 200,
327
- period: '1m'
328
- }
329
- };
330
- break;
331
-
332
- default:
333
- throw new Error(`Unknown middleware type: ${type}`);
334
- }
335
-
336
- const middlewarePath = path.join(this.traefikDir, `middleware-${type}.yml`);
337
- await fs.writeFile(middlewarePath, this.generateYAML(middlewares));
338
-
339
- return {
340
- path: middlewarePath,
341
- type: type,
342
- config: middlewares
343
- };
344
- }
345
-
346
- /**
347
- * Configures service discovery
348
- */
349
- async configureDiscovery(provider, options = {}) {
350
- await fs.mkdir(this.traefikDir, { recursive: true });
351
-
352
- let discoveryConfig = {};
353
-
354
- switch (provider) {
355
- case 'docker':
356
- discoveryConfig = {
357
- providers: {
358
- docker: {
359
- endpoint: 'unix:///var/run/docker.sock',
360
- exposedByDefault: false,
361
- network: options.network || CONFIG.defaults.network,
362
- watch: true
363
- }
364
- }
365
- };
366
- break;
367
-
368
- case 'kubernetes':
369
- case 'k8s':
370
- discoveryConfig = {
371
- providers: {
372
- kubernetes: {
373
- namespace: options.namespace || 'default',
374
- labelSelector: options.selector || '',
375
- ingressClass: 'traefik'
376
- }
377
- }
378
- };
379
- break;
380
-
381
- case 'consul':
382
- discoveryConfig = {
383
- providers: {
384
- consul: {
385
- endpoint: options.endpoint || 'http://localhost:8500',
386
- prefix: 'traefik',
387
- watch: true
388
- }
389
- }
390
- };
391
- break;
392
-
393
- default:
394
- throw new Error(`Unknown provider: ${provider}`);
395
- }
396
-
397
- const discoveryPath = path.join(this.traefikDir, `discovery-${provider}.yml`);
398
- await fs.writeFile(discoveryPath, this.generateYAML(discoveryConfig));
399
-
400
- return {
401
- path: discoveryPath,
402
- provider: provider,
403
- config: discoveryConfig
404
- };
405
- }
406
-
407
- /**
408
- * Checks Traefik status
409
- */
410
- async checkStatus() {
411
- const status = {
412
- configuration: {
413
- exists: false,
414
- files: []
415
- },
416
- container: {
417
- running: false,
418
- status: 'unknown'
419
- },
420
- dashboard: {
421
- url: `http://localhost:${CONFIG.defaults.dashboardPort}/dashboard`
422
- }
423
- };
424
-
425
- // Check configuration files
426
- try {
427
- const files = await fs.readdir(this.traefikDir);
428
- status.configuration.exists = true;
429
- for (const file of files) {
430
- const stats = await fs.stat(path.join(this.traefikDir, file));
431
- status.configuration.files.push({
432
- name: file,
433
- size: stats.size
434
- });
435
- }
436
- } catch (error) {
437
- // No configuration directory
438
- }
439
-
440
- // Check Docker container status
441
- try {
442
- const { stdout } = await execAsync('docker ps --filter name=traefik --format "{{.Status}}"');
443
- if (stdout.includes('Up')) {
444
- status.container.running = true;
445
- status.container.status = stdout.trim();
446
- }
447
- } catch (error) {
448
- // Docker not available or container not running
449
- }
450
-
451
- return status;
452
- }
453
-
454
- /**
455
- * Simple YAML generator
456
- */
457
- generateYAML(obj, indent = 0) {
458
- let yaml = '';
459
- const spaces = ' '.repeat(indent);
460
-
461
- for (const [key, value] of Object.entries(obj)) {
462
- if (value === null || value === undefined) {
463
- yaml += `${spaces}${key}:\n`;
464
- } else if (typeof value === 'object' && !Array.isArray(value)) {
465
- yaml += `${spaces}${key}:\n${this.generateYAML(value, indent + 1)}`;
466
- } else if (Array.isArray(value)) {
467
- yaml += `${spaces}${key}:\n`;
468
- for (const item of value) {
469
- if (typeof item === 'object') {
470
- yaml += `${spaces} -\n${this.generateYAML(item, indent + 2)}`;
471
- } else {
472
- yaml += `${spaces} - ${item}\n`;
473
- }
474
- }
475
- } else {
476
- yaml += `${spaces}${key}: ${value}\n`;
477
- }
478
- }
479
-
480
- return yaml;
481
- }
482
- }
483
-
484
- module.exports = TraefikManager;
@@ -1,126 +0,0 @@
1
- /**
2
- * Cross-platform color utility
3
- * Works with or without chalk library
4
- */
5
-
6
- // Color codes for fallback
7
- const colors = {
8
- reset: '\x1b[0m',
9
- bold: '\x1b[1m',
10
- underline: '\x1b[4m',
11
-
12
- // Foreground colors
13
- black: '\x1b[30m',
14
- red: '\x1b[31m',
15
- green: '\x1b[32m',
16
- yellow: '\x1b[33m',
17
- blue: '\x1b[34m',
18
- magenta: '\x1b[35m',
19
- cyan: '\x1b[36m',
20
- white: '\x1b[37m',
21
- gray: '\x1b[90m',
22
- grey: '\x1b[90m',
23
-
24
- // Background colors
25
- bgBlack: '\x1b[40m',
26
- bgRed: '\x1b[41m',
27
- bgGreen: '\x1b[42m',
28
- bgYellow: '\x1b[43m',
29
- bgBlue: '\x1b[44m',
30
- bgMagenta: '\x1b[45m',
31
- bgCyan: '\x1b[46m',
32
- bgWhite: '\x1b[47m'
33
- };
34
-
35
- class ColorHelper {
36
- constructor() {
37
- this.supportsColor = process.stdout.isTTY &&
38
- process.env.TERM !== 'dumb' &&
39
- !process.env.NO_COLOR;
40
- }
41
-
42
- colorize(text, color) {
43
- if (!this.supportsColor) {
44
- return text;
45
- }
46
-
47
- const code = colors[color] || '';
48
- return code + text + colors.reset;
49
- }
50
-
51
- // Basic colors
52
- red(text) {
53
- return this.colorize(text, 'red');
54
- }
55
-
56
- green(text) {
57
- return this.colorize(text, 'green');
58
- }
59
-
60
- yellow(text) {
61
- return this.colorize(text, 'yellow');
62
- }
63
-
64
- blue(text) {
65
- return this.colorize(text, 'blue');
66
- }
67
-
68
- magenta(text) {
69
- return this.colorize(text, 'magenta');
70
- }
71
-
72
- cyan(text) {
73
- return this.colorize(text, 'cyan');
74
- }
75
-
76
- white(text) {
77
- return this.colorize(text, 'white');
78
- }
79
-
80
- gray(text) {
81
- return this.colorize(text, 'gray');
82
- }
83
-
84
- grey(text) {
85
- return this.colorize(text, 'grey');
86
- }
87
-
88
- // Styles
89
- bold(text) {
90
- return this.colorize(text, 'bold');
91
- }
92
-
93
- underline(text) {
94
- return this.colorize(text, 'underline');
95
- }
96
-
97
- // Combined styles
98
- boldRed(text) {
99
- return this.bold(this.red(text));
100
- }
101
-
102
- boldGreen(text) {
103
- return this.bold(this.green(text));
104
- }
105
-
106
- boldYellow(text) {
107
- return this.bold(this.yellow(text));
108
- }
109
-
110
- boldBlue(text) {
111
- return this.bold(this.blue(text));
112
- }
113
-
114
- boldCyan(text) {
115
- return this.bold(this.cyan(text));
116
- }
117
-
118
- boldUnderline(text) {
119
- return this.bold(this.underline(text));
120
- }
121
-
122
- // Note: Removed chaining support due to infinite recursion issues
123
- // Use direct method calls instead (e.g., boldRed(), boldGreen(), etc.)
124
- }
125
-
126
- module.exports = new ColorHelper();