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,533 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Azure DevOps Daily Report
|
|
5
|
-
* Generates a daily stand-up report with yesterday's progress and today's plans
|
|
6
|
-
* Full implementation with TDD approach
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const fs = require('fs').promises;
|
|
11
|
-
const chalk = require('chalk');
|
|
12
|
-
const dotenv = require('dotenv');
|
|
13
|
-
const AzureDevOpsClient = require('../../providers/azure/lib/client');
|
|
14
|
-
|
|
15
|
-
class AzureDaily {
|
|
16
|
-
constructor(options = {}) {
|
|
17
|
-
this.options = options;
|
|
18
|
-
this.projectPath = options.projectPath || process.cwd();
|
|
19
|
-
this.silent = options.silent || false;
|
|
20
|
-
this.format = options.format || 'table';
|
|
21
|
-
|
|
22
|
-
// Initialize colors based on silent mode
|
|
23
|
-
this.colors = this.silent ? {
|
|
24
|
-
green: (str) => str,
|
|
25
|
-
blue: (str) => str,
|
|
26
|
-
yellow: (str) => str,
|
|
27
|
-
red: (str) => str,
|
|
28
|
-
cyan: (str) => str,
|
|
29
|
-
gray: (str) => str,
|
|
30
|
-
bold: (str) => str
|
|
31
|
-
} : {
|
|
32
|
-
green: chalk.green || ((str) => str),
|
|
33
|
-
blue: chalk.blue || ((str) => str),
|
|
34
|
-
yellow: chalk.yellow || ((str) => str),
|
|
35
|
-
red: chalk.red || ((str) => str),
|
|
36
|
-
cyan: chalk.cyan || ((str) => str),
|
|
37
|
-
gray: chalk.gray || ((str) => str),
|
|
38
|
-
bold: chalk.bold || ((str) => str)
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// Environment variables container
|
|
42
|
-
this.envVars = {};
|
|
43
|
-
this.client = null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async loadEnvironment() {
|
|
47
|
-
// Start with process.env values
|
|
48
|
-
this.envVars = {
|
|
49
|
-
AZURE_DEVOPS_PAT: process.env.AZURE_DEVOPS_PAT,
|
|
50
|
-
AZURE_DEVOPS_ORG: process.env.AZURE_DEVOPS_ORG,
|
|
51
|
-
AZURE_DEVOPS_PROJECT: process.env.AZURE_DEVOPS_PROJECT
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Try to load from .claude/.env first (override process.env)
|
|
55
|
-
const claudeEnvPath = path.join(this.projectPath, '.claude', '.env');
|
|
56
|
-
const envPath = path.join(this.projectPath, '.env');
|
|
57
|
-
|
|
58
|
-
let envFromFile = {};
|
|
59
|
-
try {
|
|
60
|
-
await fs.access(claudeEnvPath);
|
|
61
|
-
envFromFile = dotenv.parse(await fs.readFile(claudeEnvPath, 'utf8'));
|
|
62
|
-
} catch (err) {
|
|
63
|
-
// File doesn't exist, try regular .env
|
|
64
|
-
try {
|
|
65
|
-
await fs.access(envPath);
|
|
66
|
-
envFromFile = dotenv.parse(await fs.readFile(envPath, 'utf8'));
|
|
67
|
-
} catch (err2) {
|
|
68
|
-
// File doesn't exist, ignore
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Override with file values where they exist
|
|
73
|
-
if (envFromFile.AZURE_DEVOPS_PAT) this.envVars.AZURE_DEVOPS_PAT = envFromFile.AZURE_DEVOPS_PAT;
|
|
74
|
-
if (envFromFile.AZURE_DEVOPS_ORG) this.envVars.AZURE_DEVOPS_ORG = envFromFile.AZURE_DEVOPS_ORG;
|
|
75
|
-
if (envFromFile.AZURE_DEVOPS_PROJECT) this.envVars.AZURE_DEVOPS_PROJECT = envFromFile.AZURE_DEVOPS_PROJECT;
|
|
76
|
-
|
|
77
|
-
// Initialize client if environment is valid
|
|
78
|
-
const validation = this.validateEnvironment();
|
|
79
|
-
if (validation.valid) {
|
|
80
|
-
this.client = new AzureDevOpsClient({
|
|
81
|
-
organization: this.envVars.AZURE_DEVOPS_ORG,
|
|
82
|
-
project: this.envVars.AZURE_DEVOPS_PROJECT,
|
|
83
|
-
pat: this.envVars.AZURE_DEVOPS_PAT
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
validateEnvironment() {
|
|
89
|
-
const errors = [];
|
|
90
|
-
|
|
91
|
-
if (!this.envVars.AZURE_DEVOPS_PAT) {
|
|
92
|
-
errors.push('AZURE_DEVOPS_PAT is not set');
|
|
93
|
-
}
|
|
94
|
-
if (!this.envVars.AZURE_DEVOPS_ORG) {
|
|
95
|
-
errors.push('AZURE_DEVOPS_ORG is not set');
|
|
96
|
-
}
|
|
97
|
-
if (!this.envVars.AZURE_DEVOPS_PROJECT) {
|
|
98
|
-
errors.push('AZURE_DEVOPS_PROJECT is not set');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
valid: errors.length === 0,
|
|
103
|
-
errors: errors
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
getYesterdayDate() {
|
|
108
|
-
const date = new Date();
|
|
109
|
-
date.setDate(date.getDate() - 1);
|
|
110
|
-
// Return in YYYY-MM-DD format
|
|
111
|
-
return date.toISOString().split('T')[0];
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
buildCompletedTasksQuery(yesterday) {
|
|
115
|
-
return `
|
|
116
|
-
SELECT [System.Id], [System.Title], [System.WorkItemType],
|
|
117
|
-
[System.State], [System.AssignedTo], [System.ChangedDate]
|
|
118
|
-
FROM workitems
|
|
119
|
-
WHERE [System.WorkItemType] = 'Task'
|
|
120
|
-
AND [System.State] = 'Done'
|
|
121
|
-
AND [System.AssignedTo] = @Me
|
|
122
|
-
AND [System.ChangedDate] >= '${yesterday}'
|
|
123
|
-
ORDER BY [System.ChangedDate] DESC
|
|
124
|
-
`;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
buildActiveTasksQuery() {
|
|
128
|
-
return `
|
|
129
|
-
SELECT [System.Id], [System.Title], [System.WorkItemType],
|
|
130
|
-
[System.State], [System.AssignedTo],
|
|
131
|
-
[Microsoft.VSTS.Scheduling.RemainingWork]
|
|
132
|
-
FROM workitems
|
|
133
|
-
WHERE [System.WorkItemType] = 'Task'
|
|
134
|
-
AND [System.State] = 'In Progress'
|
|
135
|
-
AND [System.AssignedTo] = @Me
|
|
136
|
-
ORDER BY [Microsoft.VSTS.Common.Priority] ASC
|
|
137
|
-
`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
buildBlockedItemsQuery() {
|
|
141
|
-
return `
|
|
142
|
-
SELECT [System.Id], [System.Title], [System.Tags], [System.State]
|
|
143
|
-
FROM workitems
|
|
144
|
-
WHERE [System.Tags] CONTAINS 'blocked'
|
|
145
|
-
AND [System.State] != 'Closed'
|
|
146
|
-
ORDER BY [Microsoft.VSTS.Common.Priority] ASC
|
|
147
|
-
`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
buildNextTaskQuery() {
|
|
151
|
-
return `
|
|
152
|
-
SELECT TOP 1 [System.Id], [System.Title], [System.WorkItemType],
|
|
153
|
-
[System.State], [System.AssignedTo],
|
|
154
|
-
[Microsoft.VSTS.Common.Priority]
|
|
155
|
-
FROM workitems
|
|
156
|
-
WHERE [System.WorkItemType] = 'Task'
|
|
157
|
-
AND [System.State] = 'To Do'
|
|
158
|
-
AND ([System.AssignedTo] = '' OR [System.AssignedTo] = @Me)
|
|
159
|
-
ORDER BY [Microsoft.VSTS.Common.Priority] ASC
|
|
160
|
-
`;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async fetchCompletedTasks(yesterday) {
|
|
164
|
-
if (!this.client) {
|
|
165
|
-
throw new Error('Azure DevOps client not initialized');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
const query = this.buildCompletedTasksQuery(yesterday);
|
|
170
|
-
const result = await this.client.executeWiql(query);
|
|
171
|
-
|
|
172
|
-
if (result && result.workItems) {
|
|
173
|
-
return result.workItems.map(item => ({ id: item.id }));
|
|
174
|
-
}
|
|
175
|
-
return [];
|
|
176
|
-
} catch (error) {
|
|
177
|
-
if (error.message.includes('500')) {
|
|
178
|
-
throw new Error('Azure DevOps API returned 500 error');
|
|
179
|
-
}
|
|
180
|
-
throw error;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async fetchActiveTasks() {
|
|
185
|
-
if (!this.client) {
|
|
186
|
-
throw new Error('Azure DevOps client not initialized');
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
const query = this.buildActiveTasksQuery();
|
|
191
|
-
const result = await this.client.executeWiql(query);
|
|
192
|
-
|
|
193
|
-
if (result && result.workItems) {
|
|
194
|
-
return result.workItems.map(item => ({ id: item.id }));
|
|
195
|
-
}
|
|
196
|
-
return [];
|
|
197
|
-
} catch (error) {
|
|
198
|
-
if (error.message.includes('401')) {
|
|
199
|
-
throw new Error('Authentication failed');
|
|
200
|
-
}
|
|
201
|
-
throw error;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async fetchBlockedItems() {
|
|
206
|
-
if (!this.client) {
|
|
207
|
-
throw new Error('Azure DevOps client not initialized');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
const query = this.buildBlockedItemsQuery();
|
|
212
|
-
const result = await this.client.executeWiql(query);
|
|
213
|
-
|
|
214
|
-
if (result && result.workItems) {
|
|
215
|
-
return result.workItems.map(item => ({ id: item.id }));
|
|
216
|
-
}
|
|
217
|
-
return [];
|
|
218
|
-
} catch (error) {
|
|
219
|
-
throw error;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async fetchCurrentIteration() {
|
|
224
|
-
if (!this.client) {
|
|
225
|
-
throw new Error('Azure DevOps client not initialized');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
const sprint = await this.client.getCurrentSprint();
|
|
230
|
-
if (sprint) {
|
|
231
|
-
return {
|
|
232
|
-
name: sprint.name,
|
|
233
|
-
id: sprint.id
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
return null;
|
|
237
|
-
} catch (error) {
|
|
238
|
-
throw error;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async fetchNextTask() {
|
|
243
|
-
if (!this.client) {
|
|
244
|
-
throw new Error('Azure DevOps client not initialized');
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
const query = this.buildNextTaskQuery();
|
|
249
|
-
const result = await this.client.executeWiql(query);
|
|
250
|
-
|
|
251
|
-
if (result && result.workItems) {
|
|
252
|
-
return result.workItems.map(item => ({ id: item.id }));
|
|
253
|
-
}
|
|
254
|
-
return [];
|
|
255
|
-
} catch (error) {
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
generateStandupSummary(completedTasks) {
|
|
261
|
-
let summary = this.colors.cyan(this.colors.bold('📋 Daily Standup Summary\n'));
|
|
262
|
-
summary += '='.repeat(40) + '\n\n';
|
|
263
|
-
|
|
264
|
-
const count = completedTasks.length;
|
|
265
|
-
if (count > 0) {
|
|
266
|
-
summary += this.colors.green(`✅ Tasks completed yesterday: ${count}\n`);
|
|
267
|
-
completedTasks.forEach(task => {
|
|
268
|
-
summary += ` - Task #${task.id}\n`;
|
|
269
|
-
});
|
|
270
|
-
} else {
|
|
271
|
-
summary += this.colors.yellow('✅ Tasks completed yesterday: 0\n');
|
|
272
|
-
summary += this.colors.gray(' No tasks completed yesterday\n');
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return summary;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
generateActiveWorkSummary(activeTasks) {
|
|
279
|
-
let summary = '\n' + this.colors.blue(this.colors.bold('🔄 Your Active Work\n'));
|
|
280
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
281
|
-
|
|
282
|
-
const count = activeTasks.length;
|
|
283
|
-
if (count > 0) {
|
|
284
|
-
summary += this.colors.blue(`Active tasks: ${count}\n`);
|
|
285
|
-
activeTasks.forEach(task => {
|
|
286
|
-
summary += ` - Task #${task.id}\n`;
|
|
287
|
-
});
|
|
288
|
-
} else {
|
|
289
|
-
summary += this.colors.yellow('Active tasks: 0\n');
|
|
290
|
-
summary += this.colors.gray(' No active tasks\n');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return summary;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
generateBlockersCheck(blockedItems) {
|
|
297
|
-
let summary = '\n' + this.colors.yellow(this.colors.bold('🚧 Checking for Blockers\n'));
|
|
298
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
299
|
-
|
|
300
|
-
const count = blockedItems.length;
|
|
301
|
-
if (count > 0) {
|
|
302
|
-
summary += this.colors.red(`⚠️ Found ${count} blocked items!\n`);
|
|
303
|
-
blockedItems.forEach(item => {
|
|
304
|
-
summary += ` - Item #${item.id}\n`;
|
|
305
|
-
});
|
|
306
|
-
} else {
|
|
307
|
-
summary += this.colors.green('✅ No blockers found\n');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return summary;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
generateSprintStatus(iteration) {
|
|
314
|
-
let summary = '\n' + this.colors.blue(this.colors.bold('📊 Sprint Status\n'));
|
|
315
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
316
|
-
|
|
317
|
-
if (iteration) {
|
|
318
|
-
summary += `Current Sprint: ${iteration.name}\n`;
|
|
319
|
-
summary += `Sprint ID: ${iteration.id}\n`;
|
|
320
|
-
} else {
|
|
321
|
-
summary += this.colors.gray('No active sprint\n');
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return summary;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
generateNextTaskSuggestion(nextTask) {
|
|
328
|
-
let summary = '\n' + this.colors.green(this.colors.bold('🎯 Suggested Next Task\n'));
|
|
329
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
330
|
-
|
|
331
|
-
if (nextTask && nextTask.length > 0) {
|
|
332
|
-
const task = nextTask[0];
|
|
333
|
-
summary += this.colors.green(`Recommended: Task #${task.id}\n`);
|
|
334
|
-
summary += `To start, run: /azure:task-start ${task.id}\n`;
|
|
335
|
-
} else {
|
|
336
|
-
summary += this.colors.yellow('No tasks available. Check backlog or blocked items.\n');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
return summary;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
generateTimeTrackingSummary(completedTasks) {
|
|
343
|
-
let summary = '\n' + this.colors.cyan(this.colors.bold('⏱️ Time Tracking Summary\n'));
|
|
344
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
345
|
-
|
|
346
|
-
let totalCompleted = 0;
|
|
347
|
-
let totalEstimate = 0;
|
|
348
|
-
let hasTimeData = false;
|
|
349
|
-
|
|
350
|
-
completedTasks.forEach(task => {
|
|
351
|
-
if (task.completedWork !== undefined) {
|
|
352
|
-
totalCompleted += task.completedWork;
|
|
353
|
-
hasTimeData = true;
|
|
354
|
-
}
|
|
355
|
-
if (task.originalEstimate !== undefined) {
|
|
356
|
-
totalEstimate += task.originalEstimate;
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
if (hasTimeData) {
|
|
361
|
-
summary += `Total hours logged yesterday: ${totalCompleted}\n`;
|
|
362
|
-
if (totalEstimate > 0) {
|
|
363
|
-
summary += `Original estimate: ${totalEstimate} hours\n`;
|
|
364
|
-
const accuracy = Math.round((totalCompleted / totalEstimate) * 100);
|
|
365
|
-
summary += `Accuracy: ${accuracy}%\n`;
|
|
366
|
-
}
|
|
367
|
-
} else {
|
|
368
|
-
summary += this.colors.gray('No time tracking data available\n');
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return summary;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
generateVelocityMetrics(activeTasks) {
|
|
375
|
-
let summary = '\n' + this.colors.blue(this.colors.bold('📈 Velocity Metrics\n'));
|
|
376
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
377
|
-
|
|
378
|
-
let totalRemaining = 0;
|
|
379
|
-
let tasksWithEstimates = 0;
|
|
380
|
-
|
|
381
|
-
activeTasks.forEach(task => {
|
|
382
|
-
if (task.remainingWork !== undefined) {
|
|
383
|
-
totalRemaining += task.remainingWork;
|
|
384
|
-
tasksWithEstimates++;
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
if (tasksWithEstimates > 0) {
|
|
389
|
-
summary += `Remaining work: ${totalRemaining} hours\n`;
|
|
390
|
-
summary += `Tasks with estimates: ${tasksWithEstimates}/${activeTasks.length}\n`;
|
|
391
|
-
} else {
|
|
392
|
-
summary += this.colors.gray('No velocity data available\n');
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return summary;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
generateQuickActions() {
|
|
399
|
-
let summary = '\n' + this.colors.cyan(this.colors.bold('⚡ Quick Actions\n'));
|
|
400
|
-
summary += '-'.repeat(40) + '\n\n';
|
|
401
|
-
|
|
402
|
-
summary += 'Quick actions:\n';
|
|
403
|
-
summary += '1. Start recommended task\n';
|
|
404
|
-
summary += '2. View sprint dashboard (/azure:sprint-status)\n';
|
|
405
|
-
summary += '3. Check blocked items (/azure:blocked-items)\n';
|
|
406
|
-
summary += '4. View all your tasks (/azure:task-list --my-tasks)\n';
|
|
407
|
-
|
|
408
|
-
return summary;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
formatDailyOutput(sections) {
|
|
412
|
-
let output = '\n';
|
|
413
|
-
output += this.colors.cyan(this.colors.bold('🌅 Starting Azure DevOps Daily Workflow\n'));
|
|
414
|
-
output += '='.repeat(50) + '\n';
|
|
415
|
-
|
|
416
|
-
sections.forEach(section => {
|
|
417
|
-
output += section;
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
output += '\n' + '='.repeat(50) + '\n';
|
|
421
|
-
output += this.colors.green(this.colors.bold('✅ Daily workflow complete!\n'));
|
|
422
|
-
|
|
423
|
-
return output;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async run() {
|
|
427
|
-
try {
|
|
428
|
-
// Load environment
|
|
429
|
-
await this.loadEnvironment();
|
|
430
|
-
|
|
431
|
-
// Validate environment
|
|
432
|
-
const validation = this.validateEnvironment();
|
|
433
|
-
if (!validation.valid) {
|
|
434
|
-
return {
|
|
435
|
-
success: false,
|
|
436
|
-
error: `Environment validation failed: ${validation.errors.join(', ')}`
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Get yesterday's date
|
|
441
|
-
const yesterday = this.getYesterdayDate();
|
|
442
|
-
|
|
443
|
-
// Fetch all data
|
|
444
|
-
const [completedTasks, activeTasks, blockedItems, iteration, nextTask] = await Promise.all([
|
|
445
|
-
this.fetchCompletedTasks(yesterday).catch(() => []),
|
|
446
|
-
this.fetchActiveTasks().catch(() => []),
|
|
447
|
-
this.fetchBlockedItems().catch(() => []),
|
|
448
|
-
this.fetchCurrentIteration().catch(() => null),
|
|
449
|
-
this.fetchNextTask().catch(() => [])
|
|
450
|
-
]);
|
|
451
|
-
|
|
452
|
-
// Generate all sections
|
|
453
|
-
const sections = [
|
|
454
|
-
this.generateStandupSummary(completedTasks),
|
|
455
|
-
this.generateTimeTrackingSummary(completedTasks),
|
|
456
|
-
this.generateActiveWorkSummary(activeTasks),
|
|
457
|
-
this.generateVelocityMetrics(activeTasks),
|
|
458
|
-
this.generateBlockersCheck(blockedItems),
|
|
459
|
-
this.generateSprintStatus(iteration),
|
|
460
|
-
this.generateNextTaskSuggestion(nextTask),
|
|
461
|
-
this.generateQuickActions()
|
|
462
|
-
];
|
|
463
|
-
|
|
464
|
-
// Format and return output
|
|
465
|
-
const output = this.formatDailyOutput(sections);
|
|
466
|
-
|
|
467
|
-
return {
|
|
468
|
-
success: true,
|
|
469
|
-
output: output
|
|
470
|
-
};
|
|
471
|
-
} catch (error) {
|
|
472
|
-
return {
|
|
473
|
-
success: false,
|
|
474
|
-
error: error.message
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// For testing - allow injection of HTTP client
|
|
480
|
-
_setHttpClient(client) {
|
|
481
|
-
this.httpClient = client;
|
|
482
|
-
// Mock the Azure client
|
|
483
|
-
if (client) {
|
|
484
|
-
this.client = {
|
|
485
|
-
executeWiql: async (query) => {
|
|
486
|
-
try {
|
|
487
|
-
const response = await client.post('/wit/wiql', { query });
|
|
488
|
-
return response.data;
|
|
489
|
-
} catch (error) {
|
|
490
|
-
if (error.status === 500) {
|
|
491
|
-
throw new Error('Azure DevOps API returned 500 error');
|
|
492
|
-
}
|
|
493
|
-
if (error.status === 401) {
|
|
494
|
-
throw new Error('Authentication failed');
|
|
495
|
-
}
|
|
496
|
-
throw error;
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
getCurrentSprint: async () => {
|
|
500
|
-
try {
|
|
501
|
-
const response = await client.get('/iterations?$timeframe=current');
|
|
502
|
-
if (response.data && response.data.value && response.data.value.length > 0) {
|
|
503
|
-
return response.data.value[0];
|
|
504
|
-
}
|
|
505
|
-
return null;
|
|
506
|
-
} catch (error) {
|
|
507
|
-
throw error;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
// Export the class
|
|
516
|
-
module.exports = AzureDaily;
|
|
517
|
-
|
|
518
|
-
// Run if called directly
|
|
519
|
-
if (require.main === module) {
|
|
520
|
-
const daily = new AzureDaily({
|
|
521
|
-
silent: process.argv.includes('--silent')
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
daily.run().then(result => {
|
|
525
|
-
if (result.success) {
|
|
526
|
-
console.log(result.output);
|
|
527
|
-
process.exit(0);
|
|
528
|
-
} else {
|
|
529
|
-
console.error('Error:', result.error);
|
|
530
|
-
process.exit(1);
|
|
531
|
-
}
|
|
532
|
-
});
|
|
533
|
-
}
|
|
@@ -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
|