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,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;