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.
- package/README.md +159 -0
- package/autopm/.claude/agents/README.md +1 -1
- package/autopm/.claude/agents/core/mcp-manager.md +1 -1
- package/autopm/.claude/agents/decision-matrices/python-backend-selection.md +25 -25
- package/autopm/.claude/agents/decision-matrices/ui-framework-selection.md +43 -43
- package/autopm/.claude/agents/devops/github-operations-specialist.md +1 -1
- package/autopm/.claude/agents/frameworks/README.md +5 -5
- package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +1 -1
- package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +1 -1
- package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +1 -1
- package/autopm/.claude/agents/frameworks/react-ui-expert.md +3 -3
- package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +3 -3
- package/autopm/.claude/agents/frameworks/ux-design-expert.md +3 -3
- package/autopm/.claude/commands/infrastructure/traefik-setup.md +1 -1
- package/autopm/.claude/commands/playwright/test-scaffold.md +1 -1
- package/autopm/.claude/commands/pm/context.md +11 -0
- package/autopm/.claude/commands/pm/epic-decompose.md +25 -2
- package/autopm/.claude/commands/pm/epic-oneshot.md +13 -0
- package/autopm/.claude/commands/pm/epic-start.md +19 -0
- package/autopm/.claude/commands/pm/epic-sync-modular.md +10 -10
- package/autopm/.claude/commands/pm/epic-sync.md +14 -14
- package/autopm/.claude/commands/pm/issue-start.md +50 -5
- package/autopm/.claude/commands/pm/issue-sync.md +15 -15
- package/autopm/.claude/commands/pm/what-next.md +11 -0
- package/autopm/.claude/commands/ui/bootstrap-scaffold.md +6 -5
- package/autopm/.claude/commands/ui/tailwind-system.md +1 -1
- package/autopm/.claude/examples/mcp/playwright-mcp.md +2 -2
- package/autopm/.claude/examples/mcp-servers.example.json +2 -2
- package/autopm/.claude/hooks/docker-first-enforcement.sh +1 -1
- package/autopm/.claude/mcp/MCP-REGISTRY.md +1 -1
- package/autopm/.claude/mcp/playwright-mcp.md +2 -2
- package/autopm/.claude/rules/agent-coordination.md +26 -24
- package/autopm/.claude/rules/docker-first-development.md +1 -1
- package/autopm/.claude/rules/infrastructure-pipeline.md +1 -1
- package/autopm/.claude/rules/ui-development-standards.md +1 -1
- package/autopm/.claude/rules/visual-testing.md +3 -3
- package/autopm/.claude/scripts/azure/active-work.js +2 -2
- package/autopm/.claude/scripts/azure/blocked.js +13 -13
- package/autopm/.claude/scripts/azure/daily.js +1 -1
- package/autopm/.claude/scripts/azure/dashboard.js +1 -1
- package/autopm/.claude/scripts/azure/feature-list.js +2 -2
- package/autopm/.claude/scripts/azure/feature-status.js +1 -1
- package/autopm/.claude/scripts/azure/next-task.js +1 -1
- package/autopm/.claude/scripts/azure/search.js +1 -1
- package/autopm/.claude/scripts/azure/setup.js +15 -15
- package/autopm/.claude/scripts/azure/sprint-report.js +2 -2
- package/autopm/.claude/scripts/azure/sync.js +1 -1
- package/autopm/.claude/scripts/azure/us-list.js +1 -1
- package/autopm/.claude/scripts/azure/us-status.js +1 -1
- package/autopm/.claude/scripts/azure/validate.js +13 -13
- package/autopm/.claude/scripts/lib/frontmatter-utils.sh +42 -7
- package/autopm/.claude/scripts/lib/logging-utils.sh +20 -16
- package/autopm/.claude/scripts/lib/validation-utils.sh +1 -1
- package/autopm/.claude/scripts/pm/context.js +338 -0
- package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +3 -3
- package/autopm/.claude/scripts/pm/lib/README.md +85 -0
- package/autopm/.claude/scripts/pm/lib/logger.js +78 -0
- package/autopm/.claude/scripts/pm/next.js +25 -1
- package/autopm/.claude/scripts/pm/what-next.js +660 -0
- package/autopm/.claude/teams.json +3 -5
- package/autopm/.claude/templates/claude-templates/addons/devops-agents.md +2 -2
- package/autopm/.claude/templates/claude-templates/addons/docker-agents.md +4 -4
- package/autopm/.claude/templates/claude-templates/addons/minimal-agents.md +1 -1
- package/autopm/.claude/templates/issue-decomposition/api.yaml +2 -2
- package/autopm/.claude/templates/issue-decomposition/auth.yaml +4 -4
- package/autopm/.claude/templates/issue-decomposition/crud.yaml +3 -3
- package/autopm/.claude/templates/issue-decomposition/default.yaml +1 -1
- package/autopm/.claude/templates/issue-decomposition/ui-feature.yaml +2 -2
- package/bin/autopm.js +25 -0
- package/package.json +1 -2
- package/lib/agentExecutor.js.deprecated +0 -101
- package/lib/azure/cache.js +0 -80
- package/lib/azure/client.js +0 -77
- package/lib/azure/formatter.js +0 -177
- package/lib/commandHelpers.js +0 -177
- package/lib/context/manager.js +0 -290
- package/lib/documentation/manager.js +0 -528
- package/lib/github/workflow-manager.js +0 -546
- package/lib/helpers/azure-batch-api.js +0 -133
- package/lib/helpers/azure-cache-manager.js +0 -287
- package/lib/helpers/azure-parallel-processor.js +0 -158
- package/lib/helpers/azure-work-item-create.js +0 -278
- package/lib/helpers/gh-issue-create.js +0 -250
- package/lib/helpers/interactive-prompt.js +0 -336
- package/lib/helpers/output-manager.js +0 -335
- package/lib/helpers/progress-indicator.js +0 -258
- package/lib/performance/benchmarker.js +0 -429
- package/lib/pm/epic-decomposer.js +0 -273
- package/lib/pm/epic-syncer.js +0 -221
- package/lib/prdMetadata.js +0 -270
- package/lib/providers/azure/index.js +0 -234
- package/lib/providers/factory.js +0 -87
- package/lib/providers/github/index.js +0 -204
- package/lib/providers/interface.js +0 -73
- package/lib/python/scaffold-manager.js +0 -576
- package/lib/react/scaffold-manager.js +0 -745
- package/lib/regression/analyzer.js +0 -578
- package/lib/release/manager.js +0 -324
- package/lib/tailwind/manager.js +0 -486
- package/lib/traefik/manager.js +0 -484
- package/lib/utils/colors.js +0 -126
- package/lib/utils/config.js +0 -317
- package/lib/utils/filesystem.js +0 -316
- package/lib/utils/logger.js +0 -135
- package/lib/utils/prompts.js +0 -294
- package/lib/utils/shell.js +0 -237
- package/lib/validators/email-validator.js +0 -337
- package/lib/workflow/manager.js +0 -449
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Email Validator Module
|
|
3
|
-
*
|
|
4
|
-
* A robust email validation implementation following RFC 5322 standards
|
|
5
|
-
* with performance optimizations and security considerations.
|
|
6
|
-
*
|
|
7
|
-
* Implemented using TDD methodology.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Core email validation function
|
|
12
|
-
*
|
|
13
|
-
* @param {*} email - The email address to validate
|
|
14
|
-
* @returns {boolean} - True if valid email, false otherwise
|
|
15
|
-
*/
|
|
16
|
-
function validateEmail(email) {
|
|
17
|
-
// Handle non-string inputs
|
|
18
|
-
if (email === null || email === undefined) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (typeof email !== 'string') {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Check for empty string
|
|
27
|
-
if (email.length === 0) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check maximum length (RFC 5321)
|
|
32
|
-
if (email.length > 320) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Split into local and domain parts
|
|
37
|
-
const atIndex = email.lastIndexOf('@');
|
|
38
|
-
|
|
39
|
-
// Must have exactly one @ symbol, not at the beginning or end
|
|
40
|
-
if (atIndex <= 0 || atIndex === email.length - 1) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Check for multiple @ symbols
|
|
45
|
-
if (email.indexOf('@') !== atIndex) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const localPart = email.substring(0, atIndex);
|
|
50
|
-
const domainPart = email.substring(atIndex + 1);
|
|
51
|
-
|
|
52
|
-
// Validate local part
|
|
53
|
-
if (!validateLocalPart(localPart)) {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Validate domain part
|
|
58
|
-
if (!validateDomainPart(domainPart)) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Validates the local part of an email address (before @)
|
|
67
|
-
*
|
|
68
|
-
* @param {string} localPart - The local part to validate
|
|
69
|
-
* @returns {boolean} - True if valid, false otherwise
|
|
70
|
-
*/
|
|
71
|
-
function validateLocalPart(localPart) {
|
|
72
|
-
// Check length (max 64 characters)
|
|
73
|
-
if (localPart.length === 0 || localPart.length > 64) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Check for spaces
|
|
78
|
-
if (localPart.includes(' ')) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Check for invalid start/end characters
|
|
83
|
-
if (localPart[0] === '.' || localPart[localPart.length - 1] === '.') {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Check for consecutive dots
|
|
88
|
-
if (localPart.includes('..')) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Basic check for valid characters (alphanumeric, dots, hyphens, underscores, plus)
|
|
93
|
-
// This is a simplified version - full RFC 5322 allows more characters
|
|
94
|
-
const validLocalPartRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+$/;
|
|
95
|
-
|
|
96
|
-
if (!validLocalPartRegex.test(localPart)) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Validates the domain part of an email address (after @)
|
|
105
|
-
*
|
|
106
|
-
* @param {string} domainPart - The domain part to validate
|
|
107
|
-
* @returns {boolean} - True if valid, false otherwise
|
|
108
|
-
*/
|
|
109
|
-
function validateDomainPart(domainPart) {
|
|
110
|
-
// Check length (max 253 characters for domain)
|
|
111
|
-
// Note: Some very long domains might be technically valid but we limit for practical reasons
|
|
112
|
-
if (domainPart.length === 0 || domainPart.length > 253) {
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Check for spaces
|
|
117
|
-
if (domainPart.includes(' ')) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Must contain at least one dot for TLD
|
|
122
|
-
if (!domainPart.includes('.')) {
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Check for invalid start/end characters
|
|
127
|
-
if (domainPart[0] === '.' ||
|
|
128
|
-
domainPart[0] === '-' ||
|
|
129
|
-
domainPart[domainPart.length - 1] === '.' ||
|
|
130
|
-
domainPart[domainPart.length - 1] === '-') {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Split by dots to check each label
|
|
135
|
-
const labels = domainPart.split('.');
|
|
136
|
-
|
|
137
|
-
for (let i = 0; i < labels.length; i++) {
|
|
138
|
-
const label = labels[i];
|
|
139
|
-
const isLastLabel = i === labels.length - 1;
|
|
140
|
-
|
|
141
|
-
// TLD (last label) should be at least 2 characters and not purely numeric
|
|
142
|
-
if (isLastLabel) {
|
|
143
|
-
if (label.length < 2) {
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
// Reject purely numeric TLDs
|
|
147
|
-
if (/^\d+$/.test(label)) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (!validateDomainLabel(label)) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Validates a single domain label
|
|
162
|
-
*
|
|
163
|
-
* @param {string} label - The domain label to validate
|
|
164
|
-
* @returns {boolean} - True if valid, false otherwise
|
|
165
|
-
*/
|
|
166
|
-
function validateDomainLabel(label) {
|
|
167
|
-
// Check length (max 63 characters per label)
|
|
168
|
-
// TLD should be at least 2 characters
|
|
169
|
-
if (label.length === 0 || label.length > 63) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Check for invalid start/end with hyphen
|
|
174
|
-
if (label[0] === '-' || label[label.length - 1] === '-') {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Must contain only alphanumeric and hyphens
|
|
179
|
-
const validLabelRegex = /^[a-zA-Z0-9-]+$/;
|
|
180
|
-
|
|
181
|
-
if (!validLabelRegex.test(label)) {
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* EmailValidator class for advanced configuration
|
|
190
|
-
*/
|
|
191
|
-
class EmailValidator {
|
|
192
|
-
constructor(options = {}) {
|
|
193
|
-
this.options = {
|
|
194
|
-
allowInternational: options.allowInternational || false,
|
|
195
|
-
allowQuoted: options.allowQuoted || false,
|
|
196
|
-
maxLength: options.maxLength || 320,
|
|
197
|
-
...options
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
validate(email) {
|
|
202
|
-
// Check custom max length
|
|
203
|
-
if (typeof email === 'string' && email.length > this.options.maxLength) {
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// For now, use the same validation logic
|
|
208
|
-
// In future, we can add support for international domains and quoted strings
|
|
209
|
-
return validateEmail(email);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Detailed validation with error information
|
|
215
|
-
*
|
|
216
|
-
* @param {string} email - The email to validate
|
|
217
|
-
* @returns {object} - Validation result with details
|
|
218
|
-
*/
|
|
219
|
-
function validateEmailDetailed(email) {
|
|
220
|
-
const result = {
|
|
221
|
-
valid: false,
|
|
222
|
-
localPart: null,
|
|
223
|
-
domain: null,
|
|
224
|
-
errors: []
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
if (typeof email !== 'string') {
|
|
228
|
-
result.errors.push('Email must be a string');
|
|
229
|
-
return result;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const atIndex = email.lastIndexOf('@');
|
|
233
|
-
|
|
234
|
-
if (atIndex <= 0) {
|
|
235
|
-
result.errors.push('Missing or invalid @ symbol');
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (atIndex === email.length - 1) {
|
|
240
|
-
result.errors.push('Email cannot end with @');
|
|
241
|
-
return result;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (email.indexOf('@') !== atIndex) {
|
|
245
|
-
result.errors.push('Multiple @ symbols found');
|
|
246
|
-
return result;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
result.localPart = email.substring(0, atIndex);
|
|
250
|
-
result.domain = email.substring(atIndex + 1);
|
|
251
|
-
|
|
252
|
-
if (!validateLocalPart(result.localPart)) {
|
|
253
|
-
result.errors.push('Invalid local part (before @)');
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (!validateDomainPart(result.domain)) {
|
|
257
|
-
result.errors.push('Invalid domain part (after @)');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
result.valid = result.errors.length === 0;
|
|
261
|
-
|
|
262
|
-
return result;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Async validation wrapper (for future extensibility)
|
|
267
|
-
*
|
|
268
|
-
* @param {string} email - The email to validate
|
|
269
|
-
* @returns {Promise<boolean>} - Promise resolving to validation result
|
|
270
|
-
*/
|
|
271
|
-
async function validateEmailAsync(email) {
|
|
272
|
-
// Could add DNS validation, blacklist checking, etc.
|
|
273
|
-
return Promise.resolve(validateEmail(email));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Sanitizes email for safe display (removes potential XSS vectors)
|
|
278
|
-
*
|
|
279
|
-
* @param {string} email - The email to sanitize
|
|
280
|
-
* @returns {string} - Sanitized email
|
|
281
|
-
*/
|
|
282
|
-
function sanitizeEmail(email) {
|
|
283
|
-
if (typeof email !== 'string') {
|
|
284
|
-
return '';
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Remove HTML tags and script content
|
|
288
|
-
// Also handle already escaped entities
|
|
289
|
-
return email
|
|
290
|
-
.replace(/&/g, '&') // Must be first to avoid double-encoding
|
|
291
|
-
.replace(/</g, '<')
|
|
292
|
-
.replace(/>/g, '>')
|
|
293
|
-
.replace(/"/g, '"')
|
|
294
|
-
.replace(/'/g, ''')
|
|
295
|
-
.replace(/\//g, '/')
|
|
296
|
-
.replace(/onerror/gi, '') // Remove event handlers
|
|
297
|
-
.replace(/onclick/gi, '')
|
|
298
|
-
.replace(/onload/gi, '');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Creates an email validation rule for form validators
|
|
303
|
-
*
|
|
304
|
-
* @param {object} options - Validation options
|
|
305
|
-
* @returns {function} - Validation rule function
|
|
306
|
-
*/
|
|
307
|
-
function emailRule(options = {}) {
|
|
308
|
-
return function(value) {
|
|
309
|
-
if (options.required && !value) {
|
|
310
|
-
return 'Email is required';
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (value && !validateEmail(value)) {
|
|
314
|
-
return options.message || 'Invalid email address';
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return null; // Valid
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Export everything
|
|
322
|
-
module.exports = validateEmail;
|
|
323
|
-
module.exports.validateEmail = validateEmail;
|
|
324
|
-
module.exports.EmailValidator = EmailValidator;
|
|
325
|
-
module.exports.validateEmailDetailed = validateEmailDetailed;
|
|
326
|
-
module.exports.validateEmailAsync = validateEmailAsync;
|
|
327
|
-
module.exports.sanitizeEmail = sanitizeEmail;
|
|
328
|
-
module.exports.emailRule = emailRule;
|
|
329
|
-
|
|
330
|
-
// For testing internal functions
|
|
331
|
-
if (process.env.NODE_ENV === 'test') {
|
|
332
|
-
module.exports._internal = {
|
|
333
|
-
validateLocalPart,
|
|
334
|
-
validateDomainPart,
|
|
335
|
-
validateDomainLabel
|
|
336
|
-
};
|
|
337
|
-
}
|