claude-autopm 1.18.0 → 1.20.1

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 (108) hide show
  1. package/README.md +159 -0
  2. package/autopm/.claude/agents/README.md +1 -1
  3. package/autopm/.claude/agents/core/mcp-manager.md +1 -1
  4. package/autopm/.claude/agents/decision-matrices/python-backend-selection.md +25 -25
  5. package/autopm/.claude/agents/decision-matrices/ui-framework-selection.md +43 -43
  6. package/autopm/.claude/agents/devops/github-operations-specialist.md +1 -1
  7. package/autopm/.claude/agents/frameworks/README.md +5 -5
  8. package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +1 -1
  9. package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +1 -1
  10. package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +1 -1
  11. package/autopm/.claude/agents/frameworks/react-ui-expert.md +3 -3
  12. package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +3 -3
  13. package/autopm/.claude/agents/frameworks/ux-design-expert.md +3 -3
  14. package/autopm/.claude/commands/infrastructure/traefik-setup.md +1 -1
  15. package/autopm/.claude/commands/playwright/test-scaffold.md +1 -1
  16. package/autopm/.claude/commands/pm/context.md +11 -0
  17. package/autopm/.claude/commands/pm/epic-decompose.md +25 -2
  18. package/autopm/.claude/commands/pm/epic-oneshot.md +13 -0
  19. package/autopm/.claude/commands/pm/epic-start.md +19 -0
  20. package/autopm/.claude/commands/pm/epic-sync-modular.md +10 -10
  21. package/autopm/.claude/commands/pm/epic-sync.md +14 -14
  22. package/autopm/.claude/commands/pm/issue-start.md +50 -5
  23. package/autopm/.claude/commands/pm/issue-sync.md +15 -15
  24. package/autopm/.claude/commands/pm/what-next.md +11 -0
  25. package/autopm/.claude/commands/ui/bootstrap-scaffold.md +6 -5
  26. package/autopm/.claude/commands/ui/tailwind-system.md +1 -1
  27. package/autopm/.claude/examples/mcp/playwright-mcp.md +2 -2
  28. package/autopm/.claude/examples/mcp-servers.example.json +2 -2
  29. package/autopm/.claude/hooks/docker-first-enforcement.sh +1 -1
  30. package/autopm/.claude/mcp/MCP-REGISTRY.md +1 -1
  31. package/autopm/.claude/mcp/playwright-mcp.md +2 -2
  32. package/autopm/.claude/rules/agent-coordination.md +26 -24
  33. package/autopm/.claude/rules/docker-first-development.md +1 -1
  34. package/autopm/.claude/rules/infrastructure-pipeline.md +1 -1
  35. package/autopm/.claude/rules/ui-development-standards.md +1 -1
  36. package/autopm/.claude/rules/visual-testing.md +3 -3
  37. package/autopm/.claude/scripts/azure/active-work.js +2 -2
  38. package/autopm/.claude/scripts/azure/blocked.js +13 -13
  39. package/autopm/.claude/scripts/azure/daily.js +1 -1
  40. package/autopm/.claude/scripts/azure/dashboard.js +1 -1
  41. package/autopm/.claude/scripts/azure/feature-list.js +2 -2
  42. package/autopm/.claude/scripts/azure/feature-status.js +1 -1
  43. package/autopm/.claude/scripts/azure/next-task.js +1 -1
  44. package/autopm/.claude/scripts/azure/search.js +1 -1
  45. package/autopm/.claude/scripts/azure/setup.js +15 -15
  46. package/autopm/.claude/scripts/azure/sprint-report.js +2 -2
  47. package/autopm/.claude/scripts/azure/sync.js +1 -1
  48. package/autopm/.claude/scripts/azure/us-list.js +1 -1
  49. package/autopm/.claude/scripts/azure/us-status.js +1 -1
  50. package/autopm/.claude/scripts/azure/validate.js +13 -13
  51. package/autopm/.claude/scripts/lib/frontmatter-utils.sh +42 -7
  52. package/autopm/.claude/scripts/lib/logging-utils.sh +20 -16
  53. package/autopm/.claude/scripts/lib/validation-utils.sh +1 -1
  54. package/autopm/.claude/scripts/pm/context.js +338 -0
  55. package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +3 -3
  56. package/autopm/.claude/scripts/pm/lib/README.md +85 -0
  57. package/autopm/.claude/scripts/pm/lib/logger.js +78 -0
  58. package/autopm/.claude/scripts/pm/next.js +25 -1
  59. package/autopm/.claude/scripts/pm/what-next.js +660 -0
  60. package/autopm/.claude/teams.json +3 -5
  61. package/autopm/.claude/templates/claude-templates/addons/devops-agents.md +2 -2
  62. package/autopm/.claude/templates/claude-templates/addons/docker-agents.md +4 -4
  63. package/autopm/.claude/templates/claude-templates/addons/minimal-agents.md +1 -1
  64. package/autopm/.claude/templates/issue-decomposition/api.yaml +2 -2
  65. package/autopm/.claude/templates/issue-decomposition/auth.yaml +4 -4
  66. package/autopm/.claude/templates/issue-decomposition/crud.yaml +3 -3
  67. package/autopm/.claude/templates/issue-decomposition/default.yaml +1 -1
  68. package/autopm/.claude/templates/issue-decomposition/ui-feature.yaml +2 -2
  69. package/bin/autopm.js +25 -0
  70. package/package.json +1 -2
  71. package/lib/agentExecutor.js.deprecated +0 -101
  72. package/lib/azure/cache.js +0 -80
  73. package/lib/azure/client.js +0 -77
  74. package/lib/azure/formatter.js +0 -177
  75. package/lib/commandHelpers.js +0 -177
  76. package/lib/context/manager.js +0 -290
  77. package/lib/documentation/manager.js +0 -528
  78. package/lib/github/workflow-manager.js +0 -546
  79. package/lib/helpers/azure-batch-api.js +0 -133
  80. package/lib/helpers/azure-cache-manager.js +0 -287
  81. package/lib/helpers/azure-parallel-processor.js +0 -158
  82. package/lib/helpers/azure-work-item-create.js +0 -278
  83. package/lib/helpers/gh-issue-create.js +0 -250
  84. package/lib/helpers/interactive-prompt.js +0 -336
  85. package/lib/helpers/output-manager.js +0 -335
  86. package/lib/helpers/progress-indicator.js +0 -258
  87. package/lib/performance/benchmarker.js +0 -429
  88. package/lib/pm/epic-decomposer.js +0 -273
  89. package/lib/pm/epic-syncer.js +0 -221
  90. package/lib/prdMetadata.js +0 -270
  91. package/lib/providers/azure/index.js +0 -234
  92. package/lib/providers/factory.js +0 -87
  93. package/lib/providers/github/index.js +0 -204
  94. package/lib/providers/interface.js +0 -73
  95. package/lib/python/scaffold-manager.js +0 -576
  96. package/lib/react/scaffold-manager.js +0 -745
  97. package/lib/regression/analyzer.js +0 -578
  98. package/lib/release/manager.js +0 -324
  99. package/lib/tailwind/manager.js +0 -486
  100. package/lib/traefik/manager.js +0 -484
  101. package/lib/utils/colors.js +0 -126
  102. package/lib/utils/config.js +0 -317
  103. package/lib/utils/filesystem.js +0 -316
  104. package/lib/utils/logger.js +0 -135
  105. package/lib/utils/prompts.js +0 -294
  106. package/lib/utils/shell.js +0 -237
  107. package/lib/validators/email-validator.js +0 -337
  108. package/lib/workflow/manager.js +0 -449
@@ -1,335 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Output Manager
4
- * Handles verbose/quiet output modes and formatting
5
- */
6
-
7
- const chalk = require('chalk');
8
-
9
- class OutputManager {
10
- constructor(options = {}) {
11
- this.mode = options.mode || process.env.OUTPUT_MODE || 'normal'; // quiet, normal, verbose, debug
12
- this.useColor = options.color !== false && process.stdout.isTTY;
13
- this.format = options.format || 'text'; // text, json, csv, table
14
- this.logFile = options.logFile;
15
- this.timestamps = options.timestamps || false;
16
-
17
- // Set up chalk
18
- if (!this.useColor) {
19
- chalk.level = 0;
20
- }
21
-
22
- // Output levels
23
- this.levels = {
24
- debug: 0,
25
- verbose: 1,
26
- normal: 2,
27
- quiet: 3,
28
- silent: 4
29
- };
30
-
31
- this.currentLevel = this.levels[this.mode] || 2;
32
- }
33
-
34
- /**
35
- * Set output mode
36
- */
37
- setMode(mode) {
38
- this.mode = mode;
39
- this.currentLevel = this.levels[mode] || 2;
40
- }
41
-
42
- /**
43
- * Check if should output at level
44
- */
45
- shouldOutput(level) {
46
- return this.currentLevel <= this.levels[level];
47
- }
48
-
49
- /**
50
- * Debug output (only in debug mode)
51
- */
52
- debug(...args) {
53
- if (this.shouldOutput('debug')) {
54
- const message = this.formatMessage('[DEBUG]', ...args);
55
- console.error(this.useColor ? chalk.gray(message) : message);
56
- this.log(message);
57
- }
58
- }
59
-
60
- /**
61
- * Verbose output (verbose and debug modes)
62
- */
63
- verbose(...args) {
64
- if (this.shouldOutput('verbose')) {
65
- const message = this.formatMessage('[VERBOSE]', ...args);
66
- console.log(this.useColor ? chalk.dim(message) : message);
67
- this.log(message);
68
- }
69
- }
70
-
71
- /**
72
- * Normal output (normal, verbose, and debug modes)
73
- */
74
- info(...args) {
75
- if (this.shouldOutput('normal')) {
76
- const message = this.formatMessage(...args);
77
- console.log(message);
78
- this.log(message);
79
- }
80
- }
81
-
82
- /**
83
- * Important output (all modes except silent)
84
- */
85
- important(...args) {
86
- if (this.mode !== 'silent') {
87
- const message = this.formatMessage(...args);
88
- console.log(this.useColor ? chalk.bold(message) : message);
89
- this.log(message);
90
- }
91
- }
92
-
93
- /**
94
- * Success message
95
- */
96
- success(...args) {
97
- if (this.shouldOutput('normal')) {
98
- const message = this.formatMessage('✅', ...args);
99
- console.log(this.useColor ? chalk.green(message) : message);
100
- this.log(message);
101
- }
102
- }
103
-
104
- /**
105
- * Warning message
106
- */
107
- warn(...args) {
108
- if (this.mode !== 'silent') {
109
- const message = this.formatMessage('⚠️', ...args);
110
- console.warn(this.useColor ? chalk.yellow(message) : message);
111
- this.log(message);
112
- }
113
- }
114
-
115
- /**
116
- * Error message
117
- */
118
- error(...args) {
119
- const message = this.formatMessage('❌', ...args);
120
- console.error(this.useColor ? chalk.red(message) : message);
121
- this.log(message);
122
- }
123
-
124
- /**
125
- * Format message with optional timestamp
126
- * @private
127
- */
128
- formatMessage(...args) {
129
- let message = args.join(' ');
130
-
131
- if (this.timestamps) {
132
- const timestamp = new Date().toISOString();
133
- message = `[${timestamp}] ${message}`;
134
- }
135
-
136
- return message;
137
- }
138
-
139
- /**
140
- * Log to file if configured
141
- * @private
142
- */
143
- log(message) {
144
- if (this.logFile) {
145
- const fs = require('fs');
146
- fs.appendFileSync(this.logFile, message + '\n');
147
- }
148
- }
149
-
150
- /**
151
- * Output data in specified format
152
- */
153
- output(data, options = {}) {
154
- const format = options.format || this.format;
155
-
156
- switch (format) {
157
- case 'json':
158
- this.outputJSON(data, options);
159
- break;
160
- case 'table':
161
- this.outputTable(data, options);
162
- break;
163
- case 'csv':
164
- this.outputCSV(data, options);
165
- break;
166
- default:
167
- this.outputText(data, options);
168
- }
169
- }
170
-
171
- /**
172
- * Output as JSON
173
- */
174
- outputJSON(data, options = {}) {
175
- const pretty = options.pretty !== false;
176
- const output = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
177
- console.log(output);
178
- }
179
-
180
- /**
181
- * Output as table
182
- */
183
- outputTable(data, options = {}) {
184
- if (!Array.isArray(data) || data.length === 0) {
185
- console.log('No data to display');
186
- return;
187
- }
188
-
189
- const headers = options.headers || Object.keys(data[0]);
190
- const columnWidths = this.calculateColumnWidths(data, headers);
191
-
192
- // Print header
193
- this.printTableRow(headers, columnWidths, true);
194
- this.printTableSeparator(columnWidths);
195
-
196
- // Print data rows
197
- for (const row of data) {
198
- const values = headers.map(h => row[h]);
199
- this.printTableRow(values, columnWidths);
200
- }
201
- }
202
-
203
- /**
204
- * Output as CSV
205
- */
206
- outputCSV(data, options = {}) {
207
- if (!Array.isArray(data) || data.length === 0) {
208
- return;
209
- }
210
-
211
- const headers = options.headers || Object.keys(data[0]);
212
- console.log(headers.join(','));
213
-
214
- for (const row of data) {
215
- const values = headers.map(h => {
216
- const value = row[h];
217
- // Escape values containing commas or quotes
218
- if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
219
- return `"${value.replace(/"/g, '""')}"`;
220
- }
221
- return value;
222
- });
223
- console.log(values.join(','));
224
- }
225
- }
226
-
227
- /**
228
- * Output as text
229
- */
230
- outputText(data, options = {}) {
231
- if (typeof data === 'string') {
232
- console.log(data);
233
- } else if (Array.isArray(data)) {
234
- data.forEach(item => console.log(item));
235
- } else {
236
- console.log(JSON.stringify(data, null, 2));
237
- }
238
- }
239
-
240
- /**
241
- * Calculate column widths for table
242
- * @private
243
- */
244
- calculateColumnWidths(data, headers) {
245
- const widths = {};
246
-
247
- for (const header of headers) {
248
- widths[header] = header.length;
249
-
250
- for (const row of data) {
251
- const value = String(row[header] || '');
252
- widths[header] = Math.max(widths[header], value.length);
253
- }
254
- }
255
-
256
- return widths;
257
- }
258
-
259
- /**
260
- * Print table row
261
- * @private
262
- */
263
- printTableRow(values, widths, isHeader = false) {
264
- const cells = values.map((value, index) => {
265
- const width = widths[Object.keys(widths)[index]];
266
- const str = String(value || '').padEnd(width);
267
- return isHeader && this.useColor ? chalk.bold(str) : str;
268
- });
269
-
270
- console.log('| ' + cells.join(' | ') + ' |');
271
- }
272
-
273
- /**
274
- * Print table separator
275
- * @private
276
- */
277
- printTableSeparator(widths) {
278
- const separators = Object.values(widths).map(w => '-'.repeat(w));
279
- console.log('|-' + separators.join('-|-') + '-|');
280
- }
281
-
282
- /**
283
- * Create section header
284
- */
285
- section(title) {
286
- if (this.shouldOutput('normal')) {
287
- const line = '='.repeat(title.length + 4);
288
- console.log('\n' + (this.useColor ? chalk.cyan(line) : line));
289
- console.log((this.useColor ? chalk.cyan.bold(` ${title} `) : ` ${title} `));
290
- console.log((this.useColor ? chalk.cyan(line) : line) + '\n');
291
- }
292
- }
293
-
294
- /**
295
- * Create subsection header
296
- */
297
- subsection(title) {
298
- if (this.shouldOutput('normal')) {
299
- console.log('\n' + (this.useColor ? chalk.blue.bold(title) : title));
300
- console.log((this.useColor ? chalk.blue('-'.repeat(title.length)) : '-'.repeat(title.length)));
301
- }
302
- }
303
-
304
- /**
305
- * Print list items
306
- */
307
- list(items, options = {}) {
308
- if (!this.shouldOutput('normal')) return;
309
-
310
- const bullet = options.bullet || '•';
311
- const indent = options.indent || 2;
312
-
313
- for (const item of items) {
314
- const padding = ' '.repeat(indent);
315
- console.log(`${padding}${bullet} ${item}`);
316
- }
317
- }
318
-
319
- /**
320
- * Print key-value pairs
321
- */
322
- keyValue(pairs, options = {}) {
323
- if (!this.shouldOutput('normal')) return;
324
-
325
- const maxKeyLength = Math.max(...Object.keys(pairs).map(k => k.length));
326
-
327
- for (const [key, value] of Object.entries(pairs)) {
328
- const paddedKey = key.padEnd(maxKeyLength);
329
- const formattedKey = this.useColor ? chalk.gray(paddedKey + ':') : paddedKey + ':';
330
- console.log(` ${formattedKey} ${value}`);
331
- }
332
- }
333
- }
334
-
335
- module.exports = OutputManager;
@@ -1,258 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Progress Indicator Helper
4
- * Provides various progress indicators for long operations
5
- */
6
-
7
- const readline = require('readline');
8
-
9
- class ProgressIndicator {
10
- constructor(options = {}) {
11
- this.total = options.total || 0;
12
- this.current = 0;
13
- this.startTime = Date.now();
14
- this.lastUpdate = 0;
15
- this.updateInterval = options.updateInterval || 100; // ms
16
- this.width = options.width || 40;
17
- this.showETA = options.showETA !== false;
18
- this.showSpeed = options.showSpeed !== false;
19
- this.style = options.style || 'bar'; // bar, dots, spinner
20
- this.message = options.message || 'Processing';
21
- this.spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
22
- this.spinnerIndex = 0;
23
- }
24
-
25
- /**
26
- * Start progress tracking
27
- */
28
- start(message) {
29
- if (message) this.message = message;
30
- this.startTime = Date.now();
31
- this.current = 0;
32
- this.lastUpdate = 0;
33
-
34
- if (this.style === 'spinner') {
35
- this.startSpinner();
36
- }
37
- }
38
-
39
- /**
40
- * Update progress
41
- */
42
- update(current, message) {
43
- if (current !== undefined) this.current = current;
44
- if (message) this.message = message;
45
-
46
- const now = Date.now();
47
- if (now - this.lastUpdate < this.updateInterval) {
48
- return;
49
- }
50
-
51
- this.lastUpdate = now;
52
-
53
- switch (this.style) {
54
- case 'bar':
55
- this.renderBar();
56
- break;
57
- case 'dots':
58
- this.renderDots();
59
- break;
60
- case 'spinner':
61
- this.renderSpinner();
62
- break;
63
- case 'percentage':
64
- this.renderPercentage();
65
- break;
66
- }
67
- }
68
-
69
- /**
70
- * Increment progress by 1
71
- */
72
- increment(message) {
73
- this.current++;
74
- this.update(this.current, message);
75
- }
76
-
77
- /**
78
- * Complete progress
79
- */
80
- complete(message) {
81
- this.current = this.total;
82
- this.update(this.current, message || 'Complete');
83
- process.stdout.write('\n');
84
-
85
- if (this.spinnerInterval) {
86
- clearInterval(this.spinnerInterval);
87
- this.spinnerInterval = null;
88
- }
89
- }
90
-
91
- /**
92
- * Render progress bar
93
- * @private
94
- */
95
- renderBar() {
96
- const percent = this.total > 0 ? this.current / this.total : 0;
97
- const filled = Math.round(percent * this.width);
98
- const empty = this.width - filled;
99
-
100
- const bar = '█'.repeat(filled) + '░'.repeat(empty);
101
- const percentStr = `${Math.round(percent * 100)}%`;
102
-
103
- let output = `\r${this.message}: ${bar} ${percentStr}`;
104
-
105
- if (this.total > 0) {
106
- output += ` (${this.current}/${this.total})`;
107
- }
108
-
109
- if (this.showETA && this.total > 0 && this.current > 0) {
110
- const eta = this.calculateETA();
111
- output += ` ETA: ${eta}`;
112
- }
113
-
114
- if (this.showSpeed && this.current > 0) {
115
- const speed = this.calculateSpeed();
116
- output += ` ${speed}/s`;
117
- }
118
-
119
- process.stdout.write(output);
120
- }
121
-
122
- /**
123
- * Render dots progress
124
- * @private
125
- */
126
- renderDots() {
127
- const dots = '.'.repeat((this.current % 4) + 1).padEnd(4);
128
- const percent = this.total > 0 ? Math.round((this.current / this.total) * 100) : 0;
129
-
130
- let output = `\r${this.message}${dots}`;
131
-
132
- if (this.total > 0) {
133
- output += ` ${percent}% (${this.current}/${this.total})`;
134
- }
135
-
136
- process.stdout.write(output.padEnd(80));
137
- }
138
-
139
- /**
140
- * Render spinner
141
- * @private
142
- */
143
- renderSpinner() {
144
- const frame = this.spinnerFrames[this.spinnerIndex];
145
- let output = `\r${frame} ${this.message}`;
146
-
147
- if (this.total > 0 && this.current > 0) {
148
- const percent = Math.round((this.current / this.total) * 100);
149
- output += ` ${percent}% (${this.current}/${this.total})`;
150
- }
151
-
152
- process.stdout.write(output.padEnd(80));
153
- }
154
-
155
- /**
156
- * Render percentage only
157
- * @private
158
- */
159
- renderPercentage() {
160
- const percent = this.total > 0 ? Math.round((this.current / this.total) * 100) : 0;
161
- const output = `\r${this.message}: ${percent}% (${this.current}/${this.total})`;
162
- process.stdout.write(output.padEnd(80));
163
- }
164
-
165
- /**
166
- * Start spinner animation
167
- * @private
168
- */
169
- startSpinner() {
170
- this.spinnerInterval = setInterval(() => {
171
- this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
172
- this.renderSpinner();
173
- }, 80);
174
- }
175
-
176
- /**
177
- * Calculate ETA
178
- * @private
179
- */
180
- calculateETA() {
181
- const elapsed = Date.now() - this.startTime;
182
- const rate = this.current / elapsed;
183
- const remaining = this.total - this.current;
184
- const eta = remaining / rate;
185
-
186
- return this.formatTime(eta);
187
- }
188
-
189
- /**
190
- * Calculate processing speed
191
- * @private
192
- */
193
- calculateSpeed() {
194
- const elapsed = (Date.now() - this.startTime) / 1000; // seconds
195
- const speed = this.current / elapsed;
196
-
197
- if (speed > 1000) {
198
- return `${(speed / 1000).toFixed(1)}k`;
199
- }
200
- return speed.toFixed(1);
201
- }
202
-
203
- /**
204
- * Format time duration
205
- * @private
206
- */
207
- formatTime(ms) {
208
- const seconds = Math.floor(ms / 1000);
209
- const minutes = Math.floor(seconds / 60);
210
- const hours = Math.floor(minutes / 60);
211
-
212
- if (hours > 0) {
213
- return `${hours}h ${minutes % 60}m`;
214
- }
215
- if (minutes > 0) {
216
- return `${minutes}m ${seconds % 60}s`;
217
- }
218
- return `${seconds}s`;
219
- }
220
-
221
- /**
222
- * Create a simple progress callback
223
- */
224
- static create(total, message = 'Processing') {
225
- const progress = new ProgressIndicator({ total, message });
226
- progress.start();
227
-
228
- return {
229
- update: (current, msg) => progress.update(current, msg),
230
- increment: (msg) => progress.increment(msg),
231
- complete: (msg) => progress.complete(msg)
232
- };
233
- }
234
-
235
- /**
236
- * Wrap an async function with progress tracking
237
- */
238
- static async withProgress(items, processor, message = 'Processing items') {
239
- const progress = new ProgressIndicator({
240
- total: items.length,
241
- message,
242
- style: 'bar'
243
- });
244
-
245
- progress.start();
246
-
247
- const results = [];
248
- for (let i = 0; i < items.length; i++) {
249
- results.push(await processor(items[i], i));
250
- progress.increment();
251
- }
252
-
253
- progress.complete();
254
- return results;
255
- }
256
- }
257
-
258
- module.exports = ProgressIndicator;