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,135 +0,0 @@
1
- /**
2
- * Logger utility for consistent output formatting
3
- * Provides cross-platform colored console output
4
- */
5
-
6
- const chalk = require('./colors');
7
-
8
- class Logger {
9
- constructor(options = {}) {
10
- this.verbose = options.verbose || false;
11
- this.silent = options.silent || false;
12
-
13
- // Ensure logger is always safe to use
14
- if (!this.silent && typeof this.silent !== 'boolean') {
15
- this.silent = false;
16
- }
17
- }
18
-
19
- // Success messages
20
- success(message) {
21
- if (!this.silent) {
22
- console.log(chalk.green('✅'), message);
23
- }
24
- }
25
-
26
- // Error messages
27
- error(message, error = null) {
28
- if (!this.silent) {
29
- console.error(chalk.red('❌'), chalk.red(message));
30
- if (error && this.verbose) {
31
- console.error(chalk.gray(error.stack || error));
32
- }
33
- }
34
- }
35
-
36
- // Warning messages
37
- warn(message) {
38
- if (!this.silent) {
39
- console.log(chalk.yellow('⚠️ '), chalk.yellow(message));
40
- }
41
- }
42
-
43
- // Info messages
44
- info(message) {
45
- if (!this.silent) {
46
- console.log(chalk.blue('ℹ️ '), message);
47
- }
48
- }
49
-
50
- // Debug messages (only shown in verbose mode)
51
- debug(message) {
52
- if (this.verbose && !this.silent) {
53
- console.log(chalk.gray('🔍'), chalk.gray(message));
54
- }
55
- }
56
-
57
- // Section headers
58
- header(title) {
59
- if (!this.silent) {
60
- console.log('\n' + chalk.boldUnderline(title));
61
- }
62
- }
63
-
64
- // Step indicators
65
- step(number, total, message) {
66
- if (!this.silent) {
67
- console.log(chalk.cyan(`[${number}/${total}]`), message);
68
- }
69
- }
70
-
71
- // Progress indicators
72
- progress(message) {
73
- if (!this.silent) {
74
- console.log(chalk.gray('⏳'), message);
75
- }
76
- }
77
-
78
- // Completion message
79
- complete(message) {
80
- if (!this.silent) {
81
- console.log(chalk.boldGreen('🎉'), chalk.green(message));
82
- }
83
- }
84
-
85
- // Box drawing for important messages
86
- box(message, color = 'cyan') {
87
- if (!this.silent) {
88
- const lines = message.split('\n');
89
- const maxLength = Math.max(...lines.map(l => l.length));
90
- const horizontal = '─'.repeat(maxLength + 2);
91
-
92
- console.log(chalk[color](`┌${horizontal}┐`));
93
- lines.forEach(line => {
94
- const padding = ' '.repeat(maxLength - line.length);
95
- console.log(chalk[color]('│'), line + padding, chalk[color]('│'));
96
- });
97
- console.log(chalk[color](`└${horizontal}┘`));
98
- }
99
- }
100
-
101
- // Simple list formatting
102
- list(items, ordered = false) {
103
- if (!this.silent) {
104
- items.forEach((item, index) => {
105
- const bullet = ordered ? `${index + 1}.` : '•';
106
- console.log(` ${chalk.gray(bullet)} ${item}`);
107
- });
108
- }
109
- }
110
-
111
- // Table formatting (simple)
112
- table(headers, rows) {
113
- if (!this.silent) {
114
- try {
115
- const { table } = require('table');
116
- const data = [headers, ...rows];
117
- console.log(table(data));
118
- } catch (error) {
119
- // Fallback to simple table
120
- console.log(headers.join(' | '));
121
- console.log('-'.repeat(headers.join(' | ').length));
122
- rows.forEach(row => console.log(row.join(' | ')));
123
- }
124
- }
125
- }
126
-
127
- // Divider
128
- divider() {
129
- if (!this.silent) {
130
- console.log(chalk.gray('━'.repeat(50)));
131
- }
132
- }
133
- }
134
-
135
- module.exports = Logger;
@@ -1,294 +0,0 @@
1
- /**
2
- * Prompts utility for consistent user interaction
3
- * Wraps inquirer with common prompt patterns
4
- */
5
-
6
- const inquirer = require('inquirer');
7
- const chalk = require('./colors');
8
-
9
- class Prompts {
10
- constructor(logger) {
11
- this.logger = logger;
12
- }
13
-
14
- /**
15
- * Simple yes/no confirmation
16
- */
17
- async confirm(message, defaultValue = false) {
18
- const { confirmed } = await inquirer.prompt([
19
- {
20
- type: 'confirm',
21
- name: 'confirmed',
22
- message,
23
- default: defaultValue
24
- }
25
- ]);
26
- return confirmed;
27
- }
28
-
29
- /**
30
- * Text input
31
- */
32
- async input(message, defaultValue = '', options = {}) {
33
- const { value } = await inquirer.prompt([
34
- {
35
- type: 'input',
36
- name: 'value',
37
- message,
38
- default: defaultValue,
39
- ...options
40
- }
41
- ]);
42
- return value;
43
- }
44
-
45
- /**
46
- * Password input
47
- */
48
- async password(message, options = {}) {
49
- const { value } = await inquirer.prompt([
50
- {
51
- type: 'password',
52
- name: 'value',
53
- message,
54
- mask: '*',
55
- ...options
56
- }
57
- ]);
58
- return value;
59
- }
60
-
61
- /**
62
- * Single selection from list
63
- */
64
- async select(message, choices, defaultValue = null) {
65
- const { selected } = await inquirer.prompt([
66
- {
67
- type: 'list',
68
- name: 'selected',
69
- message,
70
- choices,
71
- default: defaultValue
72
- }
73
- ]);
74
- return selected;
75
- }
76
-
77
- /**
78
- * Multiple selection from list
79
- */
80
- async multiSelect(message, choices, defaultValues = []) {
81
- const { selected } = await inquirer.prompt([
82
- {
83
- type: 'checkbox',
84
- name: 'selected',
85
- message,
86
- choices,
87
- default: defaultValues
88
- }
89
- ]);
90
- return selected;
91
- }
92
-
93
- /**
94
- * Number input
95
- */
96
- async number(message, defaultValue = 0, options = {}) {
97
- const { value } = await inquirer.prompt([
98
- {
99
- type: 'number',
100
- name: 'value',
101
- message,
102
- default: defaultValue,
103
- ...options
104
- }
105
- ]);
106
- return value;
107
- }
108
-
109
- /**
110
- * Platform selection helper
111
- */
112
- async selectPlatform() {
113
- return this.select(
114
- 'Choose your project management platform:',
115
- [
116
- { name: '📙 GitHub (Issues, Projects, Pull Requests)', value: 'github' },
117
- { name: '🔷 Azure DevOps (Work Items, Boards, Repos)', value: 'azure' }
118
- ],
119
- 'github'
120
- );
121
- }
122
-
123
- /**
124
- * Configuration type selection
125
- */
126
- async selectConfiguration() {
127
- return this.select(
128
- 'Choose your configuration:',
129
- [
130
- {
131
- name: '1) Minimal - Traditional development (no Docker/K8s)',
132
- value: 'minimal'
133
- },
134
- {
135
- name: '2) Docker-only - Container-first development',
136
- value: 'docker'
137
- },
138
- {
139
- name: '3) Full DevOps - Enterprise with Docker + K8s (RECOMMENDED)',
140
- value: 'devops'
141
- },
142
- {
143
- name: '4) Performance - Hybrid parallel execution for power users',
144
- value: 'performance'
145
- },
146
- {
147
- name: '5) Custom - Manual configuration',
148
- value: 'custom'
149
- }
150
- ],
151
- 'devops'
152
- );
153
- }
154
-
155
- /**
156
- * Ask for API key/token with validation
157
- */
158
- async askForToken(service, required = false) {
159
- const message = required
160
- ? `Enter your ${service} token (required):`
161
- : `Enter your ${service} token (optional, press Enter to skip):`;
162
-
163
- const token = await this.password(message, {
164
- validate: (input) => {
165
- if (required && !input.trim()) {
166
- return `${service} token is required`;
167
- }
168
- return true;
169
- }
170
- });
171
-
172
- return token.trim();
173
- }
174
-
175
- /**
176
- * Pause execution and wait for user
177
- */
178
- async pause(message = 'Press Enter to continue...') {
179
- await inquirer.prompt([
180
- {
181
- type: 'input',
182
- name: 'pause',
183
- message: chalk.gray(message)
184
- }
185
- ]);
186
- }
187
-
188
- /**
189
- * Display menu and get selection
190
- */
191
- async menu(title, items) {
192
- this.logger.header(title);
193
-
194
- const choices = items.map((item, index) => ({
195
- name: `${index + 1}) ${item.label}`,
196
- value: item.value,
197
- short: item.short || item.label
198
- }));
199
-
200
- choices.push(new inquirer.Separator());
201
- choices.push({ name: 'Exit', value: 'exit' });
202
-
203
- return this.select('Select an option:', choices);
204
- }
205
-
206
- /**
207
- * Ask series of questions
208
- */
209
- async askQuestions(questions) {
210
- return inquirer.prompt(questions);
211
- }
212
-
213
- /**
214
- * Path input with validation
215
- */
216
- async askForPath(message, defaultPath = '.', mustExist = false) {
217
- return this.input(message, defaultPath, {
218
- validate: async (input) => {
219
- if (!input.trim()) {
220
- return 'Path cannot be empty';
221
- }
222
-
223
- if (mustExist) {
224
- const fs = require('fs-extra');
225
- const exists = await fs.pathExists(input);
226
- if (!exists) {
227
- return `Path does not exist: ${input}`;
228
- }
229
- }
230
-
231
- return true;
232
- }
233
- });
234
- }
235
-
236
- /**
237
- * URL input with validation
238
- */
239
- async askForUrl(message, defaultUrl = '') {
240
- return this.input(message, defaultUrl, {
241
- validate: (input) => {
242
- if (!input.trim()) {
243
- return true; // Allow empty for optional URLs
244
- }
245
-
246
- try {
247
- new URL(input);
248
- return true;
249
- } catch {
250
- return 'Please enter a valid URL';
251
- }
252
- }
253
- });
254
- }
255
-
256
- /**
257
- * Email input with validation
258
- */
259
- async askForEmail(message, defaultEmail = '') {
260
- return this.input(message, defaultEmail, {
261
- validate: (input) => {
262
- if (!input.trim()) {
263
- return true; // Allow empty for optional emails
264
- }
265
-
266
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
267
- if (!emailRegex.test(input)) {
268
- return 'Please enter a valid email address';
269
- }
270
-
271
- return true;
272
- }
273
- });
274
- }
275
-
276
- /**
277
- * Show spinner during async operation
278
- */
279
- async withSpinner(message, asyncFn) {
280
- const ora = require('ora');
281
- const spinner = ora(message).start();
282
-
283
- try {
284
- const result = await asyncFn();
285
- spinner.succeed();
286
- return result;
287
- } catch (error) {
288
- spinner.fail();
289
- throw error;
290
- }
291
- }
292
- }
293
-
294
- module.exports = Prompts;
@@ -1,237 +0,0 @@
1
- /**
2
- * Shell command execution utility
3
- * Wraps execa for safe cross-platform command execution
4
- */
5
-
6
- const { execa } = require('execa');
7
- const which = require('which');
8
-
9
- class Shell {
10
- constructor(logger) {
11
- this.logger = logger;
12
- }
13
-
14
- /**
15
- * Execute a command
16
- */
17
- async exec(command, args = [], options = {}) {
18
- try {
19
- this.logger.debug(`Executing: ${command} ${args.join(' ')}`);
20
-
21
- const result = await execa(command, args, {
22
- ...options,
23
- preferLocal: true,
24
- reject: false
25
- });
26
-
27
- if (result.exitCode !== 0) {
28
- throw new Error(`Command failed with exit code ${result.exitCode}: ${result.stderr}`);
29
- }
30
-
31
- return result;
32
- } catch (error) {
33
- this.logger.error(`Failed to execute: ${command}`, error);
34
- throw error;
35
- }
36
- }
37
-
38
- /**
39
- * Execute command and return stdout
40
- */
41
- async execOutput(command, args = [], options = {}) {
42
- const result = await this.exec(command, args, options);
43
- return result.stdout;
44
- }
45
-
46
- /**
47
- * Check if command exists
48
- */
49
- async commandExists(command) {
50
- try {
51
- await which(command);
52
- return true;
53
- } catch {
54
- return false;
55
- }
56
- }
57
-
58
- /**
59
- * Execute git command
60
- */
61
- async git(args, options = {}) {
62
- return this.exec('git', args, options);
63
- }
64
-
65
- /**
66
- * Execute npm command
67
- */
68
- async npm(args, options = {}) {
69
- return this.exec('npm', args, options);
70
- }
71
-
72
- /**
73
- * Execute node command
74
- */
75
- async node(args, options = {}) {
76
- return this.exec('node', args, options);
77
- }
78
-
79
- /**
80
- * Get current git branch
81
- */
82
- async getCurrentBranch() {
83
- try {
84
- const branch = await this.execOutput('git', ['branch', '--show-current']);
85
- return branch.trim();
86
- } catch {
87
- return null;
88
- }
89
- }
90
-
91
- /**
92
- * Check if in git repository
93
- */
94
- async isGitRepo() {
95
- try {
96
- await this.exec('git', ['rev-parse', '--git-dir']);
97
- return true;
98
- } catch {
99
- return false;
100
- }
101
- }
102
-
103
- /**
104
- * Get git remote URL
105
- */
106
- async getGitRemote(remote = 'origin') {
107
- try {
108
- const url = await this.execOutput('git', ['remote', 'get-url', remote]);
109
- return url.trim();
110
- } catch {
111
- return null;
112
- }
113
- }
114
-
115
- /**
116
- * Run command with live output
117
- */
118
- async execInteractive(command, args = [], options = {}) {
119
- this.logger.debug(`Executing interactive: ${command} ${args.join(' ')}`);
120
-
121
- return execa(command, args, {
122
- ...options,
123
- preferLocal: true,
124
- stdio: 'inherit'
125
- });
126
- }
127
-
128
- /**
129
- * Execute shell script content
130
- */
131
- async execScript(script, options = {}) {
132
- const shell = process.platform === 'win32' ? 'powershell' : 'bash';
133
- return this.exec(shell, ['-c', script], options);
134
- }
135
-
136
- /**
137
- * Get environment variable
138
- */
139
- getEnv(key, defaultValue = '') {
140
- return process.env[key] || defaultValue;
141
- }
142
-
143
- /**
144
- * Set environment variable
145
- */
146
- setEnv(key, value) {
147
- process.env[key] = value;
148
- }
149
-
150
- /**
151
- * Check if running in CI
152
- */
153
- isCI() {
154
- return process.env.CI === 'true' || process.env.CONTINUOUS_INTEGRATION === 'true';
155
- }
156
-
157
- /**
158
- * Get platform
159
- */
160
- getPlatform() {
161
- return process.platform;
162
- }
163
-
164
- /**
165
- * Check if Windows
166
- */
167
- isWindows() {
168
- return process.platform === 'win32';
169
- }
170
-
171
- /**
172
- * Check if macOS
173
- */
174
- isMacOS() {
175
- return process.platform === 'darwin';
176
- }
177
-
178
- /**
179
- * Check if Linux
180
- */
181
- isLinux() {
182
- return process.platform === 'linux';
183
- }
184
-
185
- /**
186
- * Execute with timeout
187
- */
188
- async execWithTimeout(command, args = [], timeout = 30000, options = {}) {
189
- return this.exec(command, args, {
190
- ...options,
191
- timeout
192
- });
193
- }
194
-
195
- /**
196
- * Execute and parse JSON output
197
- */
198
- async execJson(command, args = [], options = {}) {
199
- const output = await this.execOutput(command, args, options);
200
- try {
201
- return JSON.parse(output);
202
- } catch (error) {
203
- this.logger.error(`Failed to parse JSON output from: ${command}`, error);
204
- throw error;
205
- }
206
- }
207
-
208
- /**
209
- * Check GitHub CLI availability
210
- */
211
- async hasGitHubCLI() {
212
- return this.commandExists('gh');
213
- }
214
-
215
- /**
216
- * Check Azure CLI availability
217
- */
218
- async hasAzureCLI() {
219
- return this.commandExists('az');
220
- }
221
-
222
- /**
223
- * Check Docker availability
224
- */
225
- async hasDocker() {
226
- return this.commandExists('docker');
227
- }
228
-
229
- /**
230
- * Check kubectl availability
231
- */
232
- async hasKubectl() {
233
- return this.commandExists('kubectl');
234
- }
235
- }
236
-
237
- module.exports = Shell;