claude-autopm 2.8.1 → 2.8.2
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 +116 -8
- package/bin/autopm.js +2 -0
- package/bin/commands/plugin.js +395 -0
- package/bin/commands/team.js +184 -10
- package/install/install.js +223 -4
- package/lib/plugins/PluginManager.js +1328 -0
- package/lib/plugins/PluginManager.old.js +400 -0
- package/package.json +4 -1
- package/scripts/publish-plugins.sh +166 -0
- package/autopm/.claude/agents/cloud/README.md +0 -55
- package/autopm/.claude/agents/cloud/aws-cloud-architect.md +0 -521
- package/autopm/.claude/agents/cloud/azure-cloud-architect.md +0 -436
- package/autopm/.claude/agents/cloud/gcp-cloud-architect.md +0 -385
- package/autopm/.claude/agents/cloud/gcp-cloud-functions-engineer.md +0 -306
- package/autopm/.claude/agents/cloud/gemini-api-expert.md +0 -880
- package/autopm/.claude/agents/cloud/kubernetes-orchestrator.md +0 -566
- package/autopm/.claude/agents/cloud/openai-python-expert.md +0 -1087
- package/autopm/.claude/agents/cloud/terraform-infrastructure-expert.md +0 -454
- package/autopm/.claude/agents/core/agent-manager.md +0 -296
- package/autopm/.claude/agents/core/code-analyzer.md +0 -131
- package/autopm/.claude/agents/core/file-analyzer.md +0 -162
- package/autopm/.claude/agents/core/test-runner.md +0 -200
- package/autopm/.claude/agents/data/airflow-orchestration-expert.md +0 -52
- package/autopm/.claude/agents/data/kedro-pipeline-expert.md +0 -50
- package/autopm/.claude/agents/data/langgraph-workflow-expert.md +0 -520
- package/autopm/.claude/agents/databases/README.md +0 -50
- package/autopm/.claude/agents/databases/bigquery-expert.md +0 -392
- package/autopm/.claude/agents/databases/cosmosdb-expert.md +0 -368
- package/autopm/.claude/agents/databases/mongodb-expert.md +0 -398
- package/autopm/.claude/agents/databases/postgresql-expert.md +0 -321
- package/autopm/.claude/agents/databases/redis-expert.md +0 -52
- package/autopm/.claude/agents/devops/README.md +0 -52
- package/autopm/.claude/agents/devops/azure-devops-specialist.md +0 -308
- package/autopm/.claude/agents/devops/docker-containerization-expert.md +0 -298
- package/autopm/.claude/agents/devops/github-operations-specialist.md +0 -335
- package/autopm/.claude/agents/devops/mcp-context-manager.md +0 -319
- package/autopm/.claude/agents/devops/observability-engineer.md +0 -574
- package/autopm/.claude/agents/devops/ssh-operations-expert.md +0 -1093
- package/autopm/.claude/agents/devops/traefik-proxy-expert.md +0 -444
- package/autopm/.claude/agents/frameworks/README.md +0 -64
- package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +0 -360
- package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +0 -254
- package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +0 -217
- package/autopm/.claude/agents/frameworks/react-ui-expert.md +0 -226
- package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +0 -770
- package/autopm/.claude/agents/frameworks/ux-design-expert.md +0 -244
- package/autopm/.claude/agents/integration/message-queue-engineer.md +0 -794
- package/autopm/.claude/agents/languages/README.md +0 -50
- package/autopm/.claude/agents/languages/bash-scripting-expert.md +0 -541
- package/autopm/.claude/agents/languages/javascript-frontend-engineer.md +0 -197
- package/autopm/.claude/agents/languages/nodejs-backend-engineer.md +0 -226
- package/autopm/.claude/agents/languages/python-backend-engineer.md +0 -214
- package/autopm/.claude/agents/languages/python-backend-expert.md +0 -289
- package/autopm/.claude/agents/testing/frontend-testing-engineer.md +0 -395
- package/autopm/.claude/commands/ai/langgraph-workflow.md +0 -65
- package/autopm/.claude/commands/ai/openai-chat.md +0 -65
- package/autopm/.claude/commands/azure/COMMANDS.md +0 -107
- package/autopm/.claude/commands/azure/COMMAND_MAPPING.md +0 -252
- package/autopm/.claude/commands/azure/INTEGRATION_FIX.md +0 -103
- package/autopm/.claude/commands/azure/README.md +0 -246
- package/autopm/.claude/commands/azure/active-work.md +0 -198
- package/autopm/.claude/commands/azure/aliases.md +0 -143
- package/autopm/.claude/commands/azure/blocked-items.md +0 -287
- package/autopm/.claude/commands/azure/clean.md +0 -93
- package/autopm/.claude/commands/azure/docs-query.md +0 -48
- package/autopm/.claude/commands/azure/feature-decompose.md +0 -380
- package/autopm/.claude/commands/azure/feature-list.md +0 -61
- package/autopm/.claude/commands/azure/feature-new.md +0 -115
- package/autopm/.claude/commands/azure/feature-show.md +0 -205
- package/autopm/.claude/commands/azure/feature-start.md +0 -130
- package/autopm/.claude/commands/azure/fix-integration-example.md +0 -93
- package/autopm/.claude/commands/azure/help.md +0 -150
- package/autopm/.claude/commands/azure/import-us.md +0 -269
- package/autopm/.claude/commands/azure/init.md +0 -211
- package/autopm/.claude/commands/azure/next-task.md +0 -262
- package/autopm/.claude/commands/azure/search.md +0 -160
- package/autopm/.claude/commands/azure/sprint-status.md +0 -235
- package/autopm/.claude/commands/azure/standup.md +0 -260
- package/autopm/.claude/commands/azure/sync-all.md +0 -99
- package/autopm/.claude/commands/azure/task-analyze.md +0 -186
- package/autopm/.claude/commands/azure/task-close.md +0 -329
- package/autopm/.claude/commands/azure/task-edit.md +0 -145
- package/autopm/.claude/commands/azure/task-list.md +0 -263
- package/autopm/.claude/commands/azure/task-new.md +0 -84
- package/autopm/.claude/commands/azure/task-reopen.md +0 -79
- package/autopm/.claude/commands/azure/task-show.md +0 -126
- package/autopm/.claude/commands/azure/task-start.md +0 -301
- package/autopm/.claude/commands/azure/task-status.md +0 -65
- package/autopm/.claude/commands/azure/task-sync.md +0 -67
- package/autopm/.claude/commands/azure/us-edit.md +0 -164
- package/autopm/.claude/commands/azure/us-list.md +0 -202
- package/autopm/.claude/commands/azure/us-new.md +0 -265
- package/autopm/.claude/commands/azure/us-parse.md +0 -253
- package/autopm/.claude/commands/azure/us-show.md +0 -188
- package/autopm/.claude/commands/azure/us-status.md +0 -320
- package/autopm/.claude/commands/azure/validate.md +0 -86
- package/autopm/.claude/commands/azure/work-item-sync.md +0 -47
- package/autopm/.claude/commands/cloud/infra-deploy.md +0 -38
- package/autopm/.claude/commands/github/workflow-create.md +0 -42
- package/autopm/.claude/commands/infrastructure/ssh-security.md +0 -65
- package/autopm/.claude/commands/infrastructure/traefik-setup.md +0 -65
- package/autopm/.claude/commands/kubernetes/deploy.md +0 -37
- package/autopm/.claude/commands/playwright/test-scaffold.md +0 -38
- package/autopm/.claude/commands/pm/blocked.md +0 -28
- package/autopm/.claude/commands/pm/clean.md +0 -119
- package/autopm/.claude/commands/pm/context-create.md +0 -136
- package/autopm/.claude/commands/pm/context-prime.md +0 -170
- package/autopm/.claude/commands/pm/context-update.md +0 -292
- package/autopm/.claude/commands/pm/context.md +0 -28
- package/autopm/.claude/commands/pm/epic-close.md +0 -86
- package/autopm/.claude/commands/pm/epic-decompose.md +0 -370
- package/autopm/.claude/commands/pm/epic-edit.md +0 -83
- package/autopm/.claude/commands/pm/epic-list.md +0 -30
- package/autopm/.claude/commands/pm/epic-merge.md +0 -222
- package/autopm/.claude/commands/pm/epic-oneshot.md +0 -119
- package/autopm/.claude/commands/pm/epic-refresh.md +0 -119
- package/autopm/.claude/commands/pm/epic-show.md +0 -28
- package/autopm/.claude/commands/pm/epic-split.md +0 -120
- package/autopm/.claude/commands/pm/epic-start.md +0 -195
- package/autopm/.claude/commands/pm/epic-status.md +0 -28
- package/autopm/.claude/commands/pm/epic-sync-modular.md +0 -338
- package/autopm/.claude/commands/pm/epic-sync-original.md +0 -473
- package/autopm/.claude/commands/pm/epic-sync.md +0 -486
- package/autopm/.claude/commands/pm/help.md +0 -28
- package/autopm/.claude/commands/pm/import.md +0 -115
- package/autopm/.claude/commands/pm/in-progress.md +0 -28
- package/autopm/.claude/commands/pm/init.md +0 -28
- package/autopm/.claude/commands/pm/issue-analyze.md +0 -202
- package/autopm/.claude/commands/pm/issue-close.md +0 -119
- package/autopm/.claude/commands/pm/issue-edit.md +0 -93
- package/autopm/.claude/commands/pm/issue-reopen.md +0 -87
- package/autopm/.claude/commands/pm/issue-show.md +0 -41
- package/autopm/.claude/commands/pm/issue-start.md +0 -234
- package/autopm/.claude/commands/pm/issue-status.md +0 -95
- package/autopm/.claude/commands/pm/issue-sync.md +0 -411
- package/autopm/.claude/commands/pm/next.md +0 -28
- package/autopm/.claude/commands/pm/prd-edit.md +0 -82
- package/autopm/.claude/commands/pm/prd-list.md +0 -28
- package/autopm/.claude/commands/pm/prd-new.md +0 -55
- package/autopm/.claude/commands/pm/prd-parse.md +0 -42
- package/autopm/.claude/commands/pm/prd-status.md +0 -28
- package/autopm/.claude/commands/pm/search.md +0 -28
- package/autopm/.claude/commands/pm/standup.md +0 -28
- package/autopm/.claude/commands/pm/status.md +0 -28
- package/autopm/.claude/commands/pm/sync.md +0 -99
- package/autopm/.claude/commands/pm/test-reference-update.md +0 -151
- package/autopm/.claude/commands/pm/validate.md +0 -28
- package/autopm/.claude/commands/pm/what-next.md +0 -28
- package/autopm/.claude/commands/python/api-scaffold.md +0 -50
- package/autopm/.claude/commands/python/docs-query.md +0 -48
- package/autopm/.claude/commands/react/app-scaffold.md +0 -50
- package/autopm/.claude/commands/testing/prime.md +0 -314
- package/autopm/.claude/commands/testing/run.md +0 -125
- package/autopm/.claude/commands/ui/bootstrap-scaffold.md +0 -65
- package/autopm/.claude/commands/ui/tailwind-system.md +0 -64
- package/autopm/.claude/rules/ai-integration-patterns.md +0 -219
- package/autopm/.claude/rules/ci-cd-kubernetes-strategy.md +0 -25
- package/autopm/.claude/rules/database-management-strategy.md +0 -17
- package/autopm/.claude/rules/database-pipeline.md +0 -94
- package/autopm/.claude/rules/devops-troubleshooting-playbook.md +0 -450
- package/autopm/.claude/rules/docker-first-development.md +0 -404
- package/autopm/.claude/rules/infrastructure-pipeline.md +0 -128
- package/autopm/.claude/rules/performance-guidelines.md +0 -403
- package/autopm/.claude/rules/ui-development-standards.md +0 -281
- package/autopm/.claude/rules/ui-framework-rules.md +0 -151
- package/autopm/.claude/rules/ux-design-rules.md +0 -209
- package/autopm/.claude/rules/visual-testing.md +0 -223
- package/autopm/.claude/scripts/azure/README.md +0 -192
- package/autopm/.claude/scripts/azure/active-work.js +0 -524
- package/autopm/.claude/scripts/azure/active-work.sh +0 -20
- package/autopm/.claude/scripts/azure/blocked.js +0 -520
- package/autopm/.claude/scripts/azure/blocked.sh +0 -20
- package/autopm/.claude/scripts/azure/daily.js +0 -533
- package/autopm/.claude/scripts/azure/daily.sh +0 -20
- package/autopm/.claude/scripts/azure/dashboard.js +0 -970
- package/autopm/.claude/scripts/azure/dashboard.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-list.js +0 -254
- package/autopm/.claude/scripts/azure/feature-list.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-show.js +0 -7
- package/autopm/.claude/scripts/azure/feature-show.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-status.js +0 -604
- package/autopm/.claude/scripts/azure/feature-status.sh +0 -20
- package/autopm/.claude/scripts/azure/help.js +0 -342
- package/autopm/.claude/scripts/azure/help.sh +0 -20
- package/autopm/.claude/scripts/azure/next-task.js +0 -508
- package/autopm/.claude/scripts/azure/next-task.sh +0 -20
- package/autopm/.claude/scripts/azure/search.js +0 -469
- package/autopm/.claude/scripts/azure/search.sh +0 -20
- package/autopm/.claude/scripts/azure/setup.js +0 -745
- package/autopm/.claude/scripts/azure/setup.sh +0 -20
- package/autopm/.claude/scripts/azure/sprint-report.js +0 -1012
- package/autopm/.claude/scripts/azure/sprint-report.sh +0 -20
- package/autopm/.claude/scripts/azure/sync.js +0 -563
- package/autopm/.claude/scripts/azure/sync.sh +0 -20
- package/autopm/.claude/scripts/azure/us-list.js +0 -210
- package/autopm/.claude/scripts/azure/us-list.sh +0 -20
- package/autopm/.claude/scripts/azure/us-status.js +0 -238
- package/autopm/.claude/scripts/azure/us-status.sh +0 -20
- package/autopm/.claude/scripts/azure/validate.js +0 -626
- package/autopm/.claude/scripts/azure/validate.sh +0 -20
- package/autopm/.claude/scripts/azure/wrapper-template.sh +0 -20
- package/autopm/.claude/scripts/github/dependency-tracker.js +0 -554
- package/autopm/.claude/scripts/github/dependency-validator.js +0 -545
- package/autopm/.claude/scripts/github/dependency-visualizer.js +0 -477
- package/autopm/.claude/scripts/pm/analytics.js +0 -425
- package/autopm/.claude/scripts/pm/blocked.js +0 -164
- package/autopm/.claude/scripts/pm/blocked.sh +0 -78
- package/autopm/.claude/scripts/pm/clean.js +0 -464
- package/autopm/.claude/scripts/pm/context-create.js +0 -216
- package/autopm/.claude/scripts/pm/context-prime.js +0 -335
- package/autopm/.claude/scripts/pm/context-update.js +0 -344
- package/autopm/.claude/scripts/pm/context.js +0 -338
- package/autopm/.claude/scripts/pm/epic-close.js +0 -347
- package/autopm/.claude/scripts/pm/epic-edit.js +0 -382
- package/autopm/.claude/scripts/pm/epic-list.js +0 -273
- package/autopm/.claude/scripts/pm/epic-list.sh +0 -109
- package/autopm/.claude/scripts/pm/epic-show.js +0 -291
- package/autopm/.claude/scripts/pm/epic-show.sh +0 -105
- package/autopm/.claude/scripts/pm/epic-split.js +0 -522
- package/autopm/.claude/scripts/pm/epic-start/epic-start.js +0 -183
- package/autopm/.claude/scripts/pm/epic-start/epic-start.sh +0 -94
- package/autopm/.claude/scripts/pm/epic-status.js +0 -291
- package/autopm/.claude/scripts/pm/epic-status.sh +0 -104
- package/autopm/.claude/scripts/pm/epic-sync/README.md +0 -208
- package/autopm/.claude/scripts/pm/epic-sync/create-epic-issue.sh +0 -77
- package/autopm/.claude/scripts/pm/epic-sync/create-task-issues.sh +0 -86
- package/autopm/.claude/scripts/pm/epic-sync/update-epic-file.sh +0 -79
- package/autopm/.claude/scripts/pm/epic-sync/update-references.sh +0 -89
- package/autopm/.claude/scripts/pm/epic-sync.sh +0 -137
- package/autopm/.claude/scripts/pm/help.js +0 -92
- package/autopm/.claude/scripts/pm/help.sh +0 -90
- package/autopm/.claude/scripts/pm/in-progress.js +0 -178
- package/autopm/.claude/scripts/pm/in-progress.sh +0 -93
- package/autopm/.claude/scripts/pm/init.js +0 -321
- package/autopm/.claude/scripts/pm/init.sh +0 -178
- package/autopm/.claude/scripts/pm/issue-close.js +0 -232
- package/autopm/.claude/scripts/pm/issue-edit.js +0 -310
- package/autopm/.claude/scripts/pm/issue-show.js +0 -272
- package/autopm/.claude/scripts/pm/issue-start.js +0 -181
- package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +0 -468
- package/autopm/.claude/scripts/pm/issue-sync/gather-updates.sh +0 -460
- package/autopm/.claude/scripts/pm/issue-sync/post-comment.sh +0 -330
- package/autopm/.claude/scripts/pm/issue-sync/preflight-validation.sh +0 -348
- package/autopm/.claude/scripts/pm/issue-sync/update-frontmatter.sh +0 -387
- package/autopm/.claude/scripts/pm/lib/README.md +0 -85
- package/autopm/.claude/scripts/pm/lib/epic-discovery.js +0 -119
- package/autopm/.claude/scripts/pm/lib/logger.js +0 -78
- package/autopm/.claude/scripts/pm/next.js +0 -189
- package/autopm/.claude/scripts/pm/next.sh +0 -72
- package/autopm/.claude/scripts/pm/optimize.js +0 -407
- package/autopm/.claude/scripts/pm/pr-create.js +0 -337
- package/autopm/.claude/scripts/pm/pr-list.js +0 -257
- package/autopm/.claude/scripts/pm/prd-list.js +0 -242
- package/autopm/.claude/scripts/pm/prd-list.sh +0 -103
- package/autopm/.claude/scripts/pm/prd-new.js +0 -684
- package/autopm/.claude/scripts/pm/prd-parse.js +0 -547
- package/autopm/.claude/scripts/pm/prd-status.js +0 -152
- package/autopm/.claude/scripts/pm/prd-status.sh +0 -63
- package/autopm/.claude/scripts/pm/release.js +0 -460
- package/autopm/.claude/scripts/pm/search.js +0 -192
- package/autopm/.claude/scripts/pm/search.sh +0 -89
- package/autopm/.claude/scripts/pm/standup.js +0 -362
- package/autopm/.claude/scripts/pm/standup.sh +0 -95
- package/autopm/.claude/scripts/pm/status.js +0 -148
- package/autopm/.claude/scripts/pm/status.sh +0 -59
- package/autopm/.claude/scripts/pm/sync-batch.js +0 -337
- package/autopm/.claude/scripts/pm/sync.js +0 -343
- package/autopm/.claude/scripts/pm/template-list.js +0 -141
- package/autopm/.claude/scripts/pm/template-new.js +0 -366
- package/autopm/.claude/scripts/pm/validate.js +0 -274
- package/autopm/.claude/scripts/pm/validate.sh +0 -106
- package/autopm/.claude/scripts/pm/what-next.js +0 -660
- package/bin/node/azure-feature-show.js +0 -7
|
@@ -1,626 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Azure DevOps Validation Script
|
|
5
|
-
* Migrated from autopm/.claude/scripts/azure/validate.sh to Node.js
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Validates work items for completeness and quality
|
|
9
|
-
* - Checks for missing fields, invalid states, etc.
|
|
10
|
-
* - Supports sprint filtering and fix mode
|
|
11
|
-
* - Provides validation reports and suggestions
|
|
12
|
-
* - Cross-platform compatibility
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const fs = require('fs').promises;
|
|
17
|
-
const https = require('https');
|
|
18
|
-
const yargs = require('yargs/yargs');
|
|
19
|
-
const { hideBin } = require('yargs/helpers');
|
|
20
|
-
|
|
21
|
-
// TODO: Implement utility modules before using this script
|
|
22
|
-
// const Logger = require('../../lib/utils/logger');
|
|
23
|
-
// const FileSystem = require('../../lib/utils/filesystem');
|
|
24
|
-
// const Config = require('../../lib/utils/config');
|
|
25
|
-
|
|
26
|
-
class AzureValidate {
|
|
27
|
-
constructor(options = {}) {
|
|
28
|
-
// Initialize utilities (commented out until utils are implemented)
|
|
29
|
-
// const loggerOptions = {
|
|
30
|
-
// verbose: options.verbose || false,
|
|
31
|
-
// silent: options.silent || false
|
|
32
|
-
// };
|
|
33
|
-
|
|
34
|
-
// this.logger = new Logger(loggerOptions);
|
|
35
|
-
// this.fs = new FileSystem(this.logger);
|
|
36
|
-
// this.config = new Config(this.logger);
|
|
37
|
-
|
|
38
|
-
// Set options
|
|
39
|
-
this.options = {
|
|
40
|
-
projectPath: options.projectPath || process.cwd(),
|
|
41
|
-
verbose: options.verbose || false,
|
|
42
|
-
silent: options.silent || false,
|
|
43
|
-
sprintFilter: options.sprintFilter || null,
|
|
44
|
-
fixMode: options.fixMode || false
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
// Set paths
|
|
48
|
-
this.envPath = path.join(this.options.projectPath, '.claude', '.env');
|
|
49
|
-
|
|
50
|
-
// Environment variables
|
|
51
|
-
this.envVars = {};
|
|
52
|
-
|
|
53
|
-
// Colors (disabled in silent mode)
|
|
54
|
-
this.colors = this.options.silent ? {
|
|
55
|
-
green: '',
|
|
56
|
-
yellow: '',
|
|
57
|
-
red: '',
|
|
58
|
-
blue: '',
|
|
59
|
-
cyan: '',
|
|
60
|
-
reset: ''
|
|
61
|
-
} : {
|
|
62
|
-
green: '\x1b[32m',
|
|
63
|
-
yellow: '\x1b[33m',
|
|
64
|
-
red: '\x1b[31m',
|
|
65
|
-
blue: '\x1b[34m',
|
|
66
|
-
cyan: '\x1b[36m',
|
|
67
|
-
reset: '\x1b[0m'
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Validation rules
|
|
71
|
-
this.validationRules = {
|
|
72
|
-
required_fields: {
|
|
73
|
-
'Task': ['System.Title', 'System.AssignedTo', 'Microsoft.VSTS.Scheduling.RemainingWork'],
|
|
74
|
-
'User Story': ['System.Title', 'System.Description', 'Microsoft.VSTS.Common.AcceptanceCriteria'],
|
|
75
|
-
'Bug': ['System.Title', 'System.AssignedTo', 'Microsoft.VSTS.TCM.ReproSteps'],
|
|
76
|
-
'Feature': ['System.Title', 'System.Description']
|
|
77
|
-
},
|
|
78
|
-
valid_states: {
|
|
79
|
-
'Task': ['To Do', 'In Progress', 'Done'],
|
|
80
|
-
'User Story': ['New', 'Active', 'Resolved', 'Closed'],
|
|
81
|
-
'Bug': ['New', 'Active', 'Resolved', 'Closed'],
|
|
82
|
-
'Feature': ['New', 'In Progress', 'Done']
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// For testing - allow dependency injection
|
|
87
|
-
this.https = options.https || https;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Main execution function
|
|
92
|
-
*/
|
|
93
|
-
async run() {
|
|
94
|
-
try {
|
|
95
|
-
if (!this.options.silent) {
|
|
96
|
-
this.logger.info('✅ Azure DevOps Work Item Validation');
|
|
97
|
-
this.logger.info('====================================');
|
|
98
|
-
this.logger.info('');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Load environment variables
|
|
102
|
-
await this.loadEnvironment();
|
|
103
|
-
|
|
104
|
-
// Validate environment
|
|
105
|
-
const envValidation = this.validateEnvironment();
|
|
106
|
-
if (!envValidation.valid) {
|
|
107
|
-
return {
|
|
108
|
-
success: false,
|
|
109
|
-
error: `Missing required environment variables: ${envValidation.errors.join(', ')}`
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Fetch work items to validate
|
|
114
|
-
const workItems = await this.fetchWorkItemsToValidate();
|
|
115
|
-
|
|
116
|
-
if (workItems.length === 0) {
|
|
117
|
-
const output = `${this.colors.green}✅ No work items found to validate.${this.colors.reset}`;
|
|
118
|
-
if (!this.options.silent) {
|
|
119
|
-
this.logger.info(output);
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
success: true,
|
|
123
|
-
output,
|
|
124
|
-
validation: { passed: 0, failed: 0, warnings: 0 }
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Fetch detailed information and validate
|
|
129
|
-
const validationResults = [];
|
|
130
|
-
for (const item of workItems) {
|
|
131
|
-
try {
|
|
132
|
-
const details = await this.fetchWorkItem(item.id);
|
|
133
|
-
if (details) {
|
|
134
|
-
const validation = this.validateWorkItem(details);
|
|
135
|
-
validationResults.push({
|
|
136
|
-
item: details,
|
|
137
|
-
validation: validation
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
} catch (error) {
|
|
141
|
-
if (this.options.verbose) {
|
|
142
|
-
this.logger.warn(`Failed to validate item ${item.id}: ${error.message}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Generate validation report
|
|
148
|
-
const report = this.generateValidationReport(validationResults);
|
|
149
|
-
const summary = this.calculateValidationSummary(validationResults);
|
|
150
|
-
|
|
151
|
-
const outputSections = [];
|
|
152
|
-
outputSections.push(report);
|
|
153
|
-
outputSections.push(this.formatValidationSummary(summary));
|
|
154
|
-
|
|
155
|
-
if (this.options.fixMode) {
|
|
156
|
-
outputSections.push(this.formatFixSuggestions(validationResults));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
outputSections.push(this.formatQuickActions());
|
|
160
|
-
|
|
161
|
-
const fullOutput = outputSections.join('\n');
|
|
162
|
-
|
|
163
|
-
if (!this.options.silent) {
|
|
164
|
-
console.log(fullOutput);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
success: true,
|
|
169
|
-
output: fullOutput,
|
|
170
|
-
validation: summary,
|
|
171
|
-
results: validationResults
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
} catch (error) {
|
|
175
|
-
this.logger.error('Work item validation failed', error);
|
|
176
|
-
return {
|
|
177
|
-
success: false,
|
|
178
|
-
error: error.message
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Load environment variables from .env file and process.env
|
|
185
|
-
*/
|
|
186
|
-
async loadEnvironment() {
|
|
187
|
-
// Load from process.env first
|
|
188
|
-
this.envVars = {
|
|
189
|
-
AZURE_DEVOPS_PAT: process.env.AZURE_DEVOPS_PAT || '',
|
|
190
|
-
AZURE_DEVOPS_ORG: process.env.AZURE_DEVOPS_ORG || '',
|
|
191
|
-
AZURE_DEVOPS_PROJECT: process.env.AZURE_DEVOPS_PROJECT || ''
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// Override with .env file if exists
|
|
195
|
-
try {
|
|
196
|
-
if (await this.fs.exists(this.envPath)) {
|
|
197
|
-
const content = await fs.readFile(this.envPath, 'utf8');
|
|
198
|
-
const lines = content.split('\n');
|
|
199
|
-
|
|
200
|
-
for (const line of lines) {
|
|
201
|
-
const trimmed = line.trim();
|
|
202
|
-
if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {
|
|
203
|
-
const [key, ...valueParts] = trimmed.split('=');
|
|
204
|
-
const value = valueParts.join('=').replace(/^["']|["']$/g, '');
|
|
205
|
-
if (key && value && this.envVars.hasOwnProperty(key)) {
|
|
206
|
-
this.envVars[key] = value;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
} catch (error) {
|
|
212
|
-
// Non-critical error, continue with process.env values
|
|
213
|
-
if (this.options.verbose) {
|
|
214
|
-
this.logger.warn(`Could not load .env file: ${error.message}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Validate required environment variables
|
|
221
|
-
*/
|
|
222
|
-
validateEnvironment() {
|
|
223
|
-
const required = ['AZURE_DEVOPS_PAT', 'AZURE_DEVOPS_ORG', 'AZURE_DEVOPS_PROJECT'];
|
|
224
|
-
const missing = required.filter(key => !this.envVars[key]);
|
|
225
|
-
|
|
226
|
-
return {
|
|
227
|
-
valid: missing.length === 0,
|
|
228
|
-
errors: missing
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Build WIQL query for work items to validate
|
|
234
|
-
*/
|
|
235
|
-
buildValidationQuery() {
|
|
236
|
-
let query = `SELECT [System.Id]
|
|
237
|
-
FROM workitems
|
|
238
|
-
WHERE [System.WorkItemType] IN ('Task', 'User Story', 'Bug', 'Feature')
|
|
239
|
-
AND [System.State] NOT IN ('Closed', 'Done', 'Removed')`;
|
|
240
|
-
|
|
241
|
-
if (this.options.sprintFilter) {
|
|
242
|
-
if (this.options.sprintFilter === 'current') {
|
|
243
|
-
query += ' AND [System.IterationPath] = @CurrentIteration';
|
|
244
|
-
} else {
|
|
245
|
-
query += ` AND [System.IterationPath] CONTAINS '${this.options.sprintFilter}'`;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
query += ' ORDER BY [System.ChangedDate] DESC';
|
|
250
|
-
|
|
251
|
-
return query;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Fetch work items to validate
|
|
256
|
-
*/
|
|
257
|
-
async fetchWorkItemsToValidate() {
|
|
258
|
-
const query = this.buildValidationQuery();
|
|
259
|
-
const queryData = { query: query };
|
|
260
|
-
|
|
261
|
-
const response = await this.callAzureApi('wit/wiql', {
|
|
262
|
-
method: 'POST',
|
|
263
|
-
headers: {
|
|
264
|
-
'Content-Type': 'application/json'
|
|
265
|
-
},
|
|
266
|
-
body: JSON.stringify(queryData)
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
const data = JSON.parse(response);
|
|
270
|
-
return data.workItems || [];
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Fetch detailed work item information
|
|
275
|
-
*/
|
|
276
|
-
async fetchWorkItem(id) {
|
|
277
|
-
const response = await this.callAzureApi(`wit/workitems/${id}`);
|
|
278
|
-
const data = JSON.parse(response);
|
|
279
|
-
|
|
280
|
-
const fields = data.fields || {};
|
|
281
|
-
|
|
282
|
-
return {
|
|
283
|
-
id: data.id,
|
|
284
|
-
title: fields['System.Title'] || '',
|
|
285
|
-
type: fields['System.WorkItemType'] || '',
|
|
286
|
-
state: fields['System.State'] || '',
|
|
287
|
-
assignedTo: fields['System.AssignedTo'] ?
|
|
288
|
-
(fields['System.AssignedTo'].displayName || fields['System.AssignedTo']) : '',
|
|
289
|
-
description: fields['System.Description'] || '',
|
|
290
|
-
acceptanceCriteria: fields['Microsoft.VSTS.Common.AcceptanceCriteria'] || '',
|
|
291
|
-
reproSteps: fields['Microsoft.VSTS.TCM.ReproSteps'] || '',
|
|
292
|
-
remainingWork: fields['Microsoft.VSTS.Scheduling.RemainingWork'] || null,
|
|
293
|
-
priority: fields['Microsoft.VSTS.Common.Priority'] || null,
|
|
294
|
-
tags: fields['System.Tags'] || '',
|
|
295
|
-
sprint: fields['System.IterationPath'] ?
|
|
296
|
-
fields['System.IterationPath'].split('\\').pop() : '',
|
|
297
|
-
fields: fields
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Validate a single work item
|
|
303
|
-
*/
|
|
304
|
-
validateWorkItem(item) {
|
|
305
|
-
const validation = {
|
|
306
|
-
errors: [],
|
|
307
|
-
warnings: [],
|
|
308
|
-
passed: []
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
// Check required fields
|
|
312
|
-
const requiredFields = this.validationRules.required_fields[item.type] || [];
|
|
313
|
-
for (const field of requiredFields) {
|
|
314
|
-
const value = item.fields[field];
|
|
315
|
-
if (!value || (typeof value === 'string' && value.trim() === '')) {
|
|
316
|
-
validation.errors.push(`Missing required field: ${field}`);
|
|
317
|
-
} else {
|
|
318
|
-
validation.passed.push(`Required field present: ${field}`);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Check valid states
|
|
323
|
-
const validStates = this.validationRules.valid_states[item.type] || [];
|
|
324
|
-
if (validStates.length > 0 && !validStates.includes(item.state)) {
|
|
325
|
-
validation.errors.push(`Invalid state '${item.state}' for ${item.type}`);
|
|
326
|
-
} else if (validStates.length > 0) {
|
|
327
|
-
validation.passed.push(`Valid state: ${item.state}`);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Type-specific validations
|
|
331
|
-
this.validateTypeSpecific(item, validation);
|
|
332
|
-
|
|
333
|
-
return validation;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Perform type-specific validations
|
|
338
|
-
*/
|
|
339
|
-
validateTypeSpecific(item, validation) {
|
|
340
|
-
switch (item.type) {
|
|
341
|
-
case 'Task':
|
|
342
|
-
if (item.remainingWork === null || item.remainingWork === 0) {
|
|
343
|
-
validation.warnings.push('Remaining work not specified');
|
|
344
|
-
}
|
|
345
|
-
if (item.state === 'In Progress' && !item.assignedTo) {
|
|
346
|
-
validation.errors.push('In Progress tasks must be assigned');
|
|
347
|
-
}
|
|
348
|
-
break;
|
|
349
|
-
|
|
350
|
-
case 'User Story':
|
|
351
|
-
if (!item.acceptanceCriteria) {
|
|
352
|
-
validation.errors.push('User Stories must have acceptance criteria');
|
|
353
|
-
}
|
|
354
|
-
if (item.description && item.description.length < 50) {
|
|
355
|
-
validation.warnings.push('Description is very short');
|
|
356
|
-
}
|
|
357
|
-
break;
|
|
358
|
-
|
|
359
|
-
case 'Bug':
|
|
360
|
-
if (!item.reproSteps) {
|
|
361
|
-
validation.errors.push('Bugs must have reproduction steps');
|
|
362
|
-
}
|
|
363
|
-
if (item.priority === null) {
|
|
364
|
-
validation.warnings.push('Bug priority not set');
|
|
365
|
-
}
|
|
366
|
-
break;
|
|
367
|
-
|
|
368
|
-
case 'Feature':
|
|
369
|
-
if (item.description && item.description.length < 100) {
|
|
370
|
-
validation.warnings.push('Feature description should be more detailed');
|
|
371
|
-
}
|
|
372
|
-
break;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Call Azure DevOps REST API
|
|
378
|
-
*/
|
|
379
|
-
async callAzureApi(endpoint, options = {}) {
|
|
380
|
-
const { AZURE_DEVOPS_PAT, AZURE_DEVOPS_ORG, AZURE_DEVOPS_PROJECT } = this.envVars;
|
|
381
|
-
|
|
382
|
-
const auth = Buffer.from(`:${AZURE_DEVOPS_PAT}`).toString('base64');
|
|
383
|
-
const url = `https://dev.azure.com/${AZURE_DEVOPS_ORG}/${AZURE_DEVOPS_PROJECT}/_apis/${endpoint}?api-version=7.0`;
|
|
384
|
-
|
|
385
|
-
const requestOptions = {
|
|
386
|
-
method: options.method || 'GET',
|
|
387
|
-
headers: {
|
|
388
|
-
'Authorization': `Basic ${auth}`,
|
|
389
|
-
'User-Agent': 'ClaudeAutoPM/1.0',
|
|
390
|
-
...options.headers
|
|
391
|
-
}
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
return new Promise((resolve, reject) => {
|
|
395
|
-
const req = this.https.request(url, requestOptions, (res) => {
|
|
396
|
-
let data = '';
|
|
397
|
-
|
|
398
|
-
res.on('data', (chunk) => {
|
|
399
|
-
data += chunk;
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
res.on('end', () => {
|
|
403
|
-
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
404
|
-
resolve(data);
|
|
405
|
-
} else {
|
|
406
|
-
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
req.on('error', (error) => {
|
|
412
|
-
reject(error);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
if (options.body) {
|
|
416
|
-
req.write(options.body);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
req.end();
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Generate validation report
|
|
425
|
-
*/
|
|
426
|
-
generateValidationReport(results) {
|
|
427
|
-
let output = '📋 Validation Report\n';
|
|
428
|
-
output += '===================\n\n';
|
|
429
|
-
|
|
430
|
-
const failed = results.filter(r => r.validation.errors.length > 0);
|
|
431
|
-
const warnings = results.filter(r => r.validation.warnings.length > 0);
|
|
432
|
-
|
|
433
|
-
if (failed.length > 0) {
|
|
434
|
-
output += `${this.colors.red}❌ Failed Items (${failed.length})${this.colors.reset}\n`;
|
|
435
|
-
output += '-------------------\n';
|
|
436
|
-
for (const result of failed) {
|
|
437
|
-
output += `• #${result.item.id} - ${result.item.title}\n`;
|
|
438
|
-
for (const error of result.validation.errors) {
|
|
439
|
-
output += ` ❌ ${error}\n`;
|
|
440
|
-
}
|
|
441
|
-
output += '\n';
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (warnings.length > 0) {
|
|
446
|
-
output += `${this.colors.yellow}⚠️ Items with Warnings (${warnings.length})${this.colors.reset}\n`;
|
|
447
|
-
output += '-------------------------\n';
|
|
448
|
-
for (const result of warnings) {
|
|
449
|
-
if (result.validation.warnings.length > 0) {
|
|
450
|
-
output += `• #${result.item.id} - ${result.item.title}\n`;
|
|
451
|
-
for (const warning of result.validation.warnings) {
|
|
452
|
-
output += ` ⚠️ ${warning}\n`;
|
|
453
|
-
}
|
|
454
|
-
output += '\n';
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
const passed = results.filter(r => r.validation.errors.length === 0);
|
|
460
|
-
if (passed.length > 0) {
|
|
461
|
-
output += `${this.colors.green}✅ Passed Items (${passed.length})${this.colors.reset}\n`;
|
|
462
|
-
output += '----------------\n';
|
|
463
|
-
for (const result of passed.slice(0, 5)) { // Show only first 5
|
|
464
|
-
output += `• #${result.item.id} - ${result.item.title}\n`;
|
|
465
|
-
}
|
|
466
|
-
if (passed.length > 5) {
|
|
467
|
-
output += `... and ${passed.length - 5} more\n`;
|
|
468
|
-
}
|
|
469
|
-
output += '\n';
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
return output;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Calculate validation summary
|
|
477
|
-
*/
|
|
478
|
-
calculateValidationSummary(results) {
|
|
479
|
-
const summary = {
|
|
480
|
-
total: results.length,
|
|
481
|
-
passed: 0,
|
|
482
|
-
failed: 0,
|
|
483
|
-
warnings: 0
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
for (const result of results) {
|
|
487
|
-
if (result.validation.errors.length > 0) {
|
|
488
|
-
summary.failed++;
|
|
489
|
-
} else {
|
|
490
|
-
summary.passed++;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
if (result.validation.warnings.length > 0) {
|
|
494
|
-
summary.warnings++;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return summary;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Format validation summary
|
|
503
|
-
*/
|
|
504
|
-
formatValidationSummary(summary) {
|
|
505
|
-
let output = '📊 Validation Summary\n';
|
|
506
|
-
output += '====================\n';
|
|
507
|
-
output += `Total Items Validated: ${summary.total}\n`;
|
|
508
|
-
output += `${this.colors.green}✅ Passed: ${summary.passed}${this.colors.reset}\n`;
|
|
509
|
-
output += `${this.colors.red}❌ Failed: ${summary.failed}${this.colors.reset}\n`;
|
|
510
|
-
output += `${this.colors.yellow}⚠️ Warnings: ${summary.warnings}${this.colors.reset}\n`;
|
|
511
|
-
|
|
512
|
-
const passRate = summary.total > 0 ? ((summary.passed / summary.total) * 100).toFixed(1) : 0;
|
|
513
|
-
output += `\nPass Rate: ${passRate}%\n`;
|
|
514
|
-
|
|
515
|
-
return output;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Format fix suggestions
|
|
520
|
-
*/
|
|
521
|
-
formatFixSuggestions(results) {
|
|
522
|
-
let output = '\n🔧 Fix Suggestions\n';
|
|
523
|
-
output += '==================\n';
|
|
524
|
-
|
|
525
|
-
const commonIssues = {};
|
|
526
|
-
for (const result of results) {
|
|
527
|
-
for (const error of result.validation.errors) {
|
|
528
|
-
commonIssues[error] = (commonIssues[error] || 0) + 1;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const sortedIssues = Object.entries(commonIssues)
|
|
533
|
-
.sort(([,a], [,b]) => b - a)
|
|
534
|
-
.slice(0, 5);
|
|
535
|
-
|
|
536
|
-
output += 'Most Common Issues:\n';
|
|
537
|
-
for (const [issue, count] of sortedIssues) {
|
|
538
|
-
output += `• ${issue} (${count} items)\n`;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
output += '\nRecommended Actions:\n';
|
|
542
|
-
output += '1. Review failed items and update missing fields\n';
|
|
543
|
-
output += '2. Ensure all work items have proper assignees\n';
|
|
544
|
-
output += '3. Add detailed descriptions and acceptance criteria\n';
|
|
545
|
-
output += '4. Set appropriate priorities and remaining work estimates\n';
|
|
546
|
-
output += '5. Schedule regular validation checks\n';
|
|
547
|
-
|
|
548
|
-
return output;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* Format quick actions
|
|
553
|
-
*/
|
|
554
|
-
formatQuickActions() {
|
|
555
|
-
let output = '\n⚡ Quick Actions\n';
|
|
556
|
-
output += '===============\n';
|
|
557
|
-
output += '• View item details: /azure:task-show <id>\n';
|
|
558
|
-
output += '• Update work item: /azure:task-edit <id>\n';
|
|
559
|
-
output += '• Bulk update: /azure:bulk-update\n';
|
|
560
|
-
output += '• Run validation again: /azure:validate\n';
|
|
561
|
-
output += '• Generate detailed report: /azure:validate --verbose\n';
|
|
562
|
-
|
|
563
|
-
return output;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// CLI interface
|
|
568
|
-
if (require.main === module) {
|
|
569
|
-
const argv = yargs(hideBin(process.argv))
|
|
570
|
-
.option('path', {
|
|
571
|
-
alias: 'p',
|
|
572
|
-
describe: 'Project path',
|
|
573
|
-
type: 'string',
|
|
574
|
-
default: process.cwd()
|
|
575
|
-
})
|
|
576
|
-
.option('sprint', {
|
|
577
|
-
alias: 's',
|
|
578
|
-
describe: 'Filter by sprint (current or sprint name)',
|
|
579
|
-
type: 'string'
|
|
580
|
-
})
|
|
581
|
-
.option('fix', {
|
|
582
|
-
alias: 'f',
|
|
583
|
-
describe: 'Show fix suggestions',
|
|
584
|
-
type: 'boolean',
|
|
585
|
-
default: false
|
|
586
|
-
})
|
|
587
|
-
.option('verbose', {
|
|
588
|
-
alias: 'v',
|
|
589
|
-
describe: 'Verbose output',
|
|
590
|
-
type: 'boolean',
|
|
591
|
-
default: false
|
|
592
|
-
})
|
|
593
|
-
.option('silent', {
|
|
594
|
-
describe: 'Silent mode',
|
|
595
|
-
type: 'boolean',
|
|
596
|
-
default: false
|
|
597
|
-
})
|
|
598
|
-
.help()
|
|
599
|
-
.argv;
|
|
600
|
-
|
|
601
|
-
const validate = new AzureValidate({
|
|
602
|
-
projectPath: argv.path,
|
|
603
|
-
sprintFilter: argv.sprint,
|
|
604
|
-
fixMode: argv.fix,
|
|
605
|
-
verbose: argv.verbose,
|
|
606
|
-
silent: argv.silent
|
|
607
|
-
});
|
|
608
|
-
|
|
609
|
-
validate.run()
|
|
610
|
-
.then((result) => {
|
|
611
|
-
if (!result.success) {
|
|
612
|
-
console.error('Azure work item validation failed:', result.error);
|
|
613
|
-
process.exit(1);
|
|
614
|
-
}
|
|
615
|
-
// Exit with code 1 if validation found errors
|
|
616
|
-
if (result.validation && result.validation.failed > 0) {
|
|
617
|
-
process.exit(1);
|
|
618
|
-
}
|
|
619
|
-
})
|
|
620
|
-
.catch((error) => {
|
|
621
|
-
console.error('Azure work item validation failed:', error.message);
|
|
622
|
-
process.exit(1);
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
module.exports = AzureValidate;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Azure Script - Wrapper for Node.js implementation
|
|
4
|
-
# This wrapper maintains backward compatibility while delegating to the Node.js version
|
|
5
|
-
|
|
6
|
-
# Get the directory of this script
|
|
7
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
-
SCRIPT_NAME="$(basename "$0" .sh)"
|
|
9
|
-
|
|
10
|
-
# Check if Node.js is available and the .js file exists
|
|
11
|
-
if command -v node >/dev/null 2>&1 && [ -f "$SCRIPT_DIR/$SCRIPT_NAME.js" ]; then
|
|
12
|
-
# Use the Node.js implementation
|
|
13
|
-
node "$SCRIPT_DIR/$SCRIPT_NAME.js" "$@"
|
|
14
|
-
exit $?
|
|
15
|
-
else
|
|
16
|
-
# Fallback message
|
|
17
|
-
echo "⚠️ Node.js not found or $SCRIPT_NAME.js missing"
|
|
18
|
-
echo "Please ensure Node.js is installed and all files are present"
|
|
19
|
-
exit 1
|
|
20
|
-
fi
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Azure Script - Wrapper for Node.js implementation
|
|
4
|
-
# This wrapper maintains backward compatibility while delegating to the Node.js version
|
|
5
|
-
|
|
6
|
-
# Get the directory of this script
|
|
7
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
-
SCRIPT_NAME="$(basename "$0" .sh)"
|
|
9
|
-
|
|
10
|
-
# Check if Node.js is available and the .js file exists
|
|
11
|
-
if command -v node >/dev/null 2>&1 && [ -f "$SCRIPT_DIR/$SCRIPT_NAME.js" ]; then
|
|
12
|
-
# Use the Node.js implementation
|
|
13
|
-
node "$SCRIPT_DIR/$SCRIPT_NAME.js" "$@"
|
|
14
|
-
exit $?
|
|
15
|
-
else
|
|
16
|
-
# Fallback message
|
|
17
|
-
echo "⚠️ Node.js not found or $SCRIPT_NAME.js missing"
|
|
18
|
-
echo "Please ensure Node.js is installed and all files are present"
|
|
19
|
-
exit 1
|
|
20
|
-
fi
|