claude-autopm 1.17.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 (76) 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/bin/commands/team.js +86 -0
  38. package/package.json +1 -1
  39. package/lib/agentExecutor.js.deprecated +0 -101
  40. package/lib/azure/cache.js +0 -80
  41. package/lib/azure/client.js +0 -77
  42. package/lib/azure/formatter.js +0 -177
  43. package/lib/commandHelpers.js +0 -177
  44. package/lib/context/manager.js +0 -290
  45. package/lib/documentation/manager.js +0 -528
  46. package/lib/github/workflow-manager.js +0 -546
  47. package/lib/helpers/azure-batch-api.js +0 -133
  48. package/lib/helpers/azure-cache-manager.js +0 -287
  49. package/lib/helpers/azure-parallel-processor.js +0 -158
  50. package/lib/helpers/azure-work-item-create.js +0 -278
  51. package/lib/helpers/gh-issue-create.js +0 -250
  52. package/lib/helpers/interactive-prompt.js +0 -336
  53. package/lib/helpers/output-manager.js +0 -335
  54. package/lib/helpers/progress-indicator.js +0 -258
  55. package/lib/performance/benchmarker.js +0 -429
  56. package/lib/pm/epic-decomposer.js +0 -273
  57. package/lib/pm/epic-syncer.js +0 -221
  58. package/lib/prdMetadata.js +0 -270
  59. package/lib/providers/azure/index.js +0 -234
  60. package/lib/providers/factory.js +0 -87
  61. package/lib/providers/github/index.js +0 -204
  62. package/lib/providers/interface.js +0 -73
  63. package/lib/python/scaffold-manager.js +0 -576
  64. package/lib/react/scaffold-manager.js +0 -745
  65. package/lib/regression/analyzer.js +0 -578
  66. package/lib/release/manager.js +0 -324
  67. package/lib/tailwind/manager.js +0 -486
  68. package/lib/traefik/manager.js +0 -484
  69. package/lib/utils/colors.js +0 -126
  70. package/lib/utils/config.js +0 -317
  71. package/lib/utils/filesystem.js +0 -316
  72. package/lib/utils/logger.js +0 -135
  73. package/lib/utils/prompts.js +0 -294
  74. package/lib/utils/shell.js +0 -237
  75. package/lib/validators/email-validator.js +0 -337
  76. 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();