claude-autopm 2.7.0 → 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.
Files changed (281) hide show
  1. package/README.md +307 -56
  2. package/autopm/.claude/.env +158 -0
  3. package/autopm/.claude/settings.local.json +9 -0
  4. package/bin/autopm.js +11 -2
  5. package/bin/commands/epic.js +23 -3
  6. package/bin/commands/plugin.js +395 -0
  7. package/bin/commands/team.js +184 -10
  8. package/install/install.js +223 -4
  9. package/lib/cli/commands/issue.js +360 -20
  10. package/lib/plugins/PluginManager.js +1328 -0
  11. package/lib/plugins/PluginManager.old.js +400 -0
  12. package/lib/providers/AzureDevOpsProvider.js +575 -0
  13. package/lib/providers/GitHubProvider.js +475 -0
  14. package/lib/services/EpicService.js +1092 -3
  15. package/lib/services/IssueService.js +991 -0
  16. package/package.json +9 -1
  17. package/scripts/publish-plugins.sh +166 -0
  18. package/autopm/.claude/agents/cloud/README.md +0 -55
  19. package/autopm/.claude/agents/cloud/aws-cloud-architect.md +0 -521
  20. package/autopm/.claude/agents/cloud/azure-cloud-architect.md +0 -436
  21. package/autopm/.claude/agents/cloud/gcp-cloud-architect.md +0 -385
  22. package/autopm/.claude/agents/cloud/gcp-cloud-functions-engineer.md +0 -306
  23. package/autopm/.claude/agents/cloud/gemini-api-expert.md +0 -880
  24. package/autopm/.claude/agents/cloud/kubernetes-orchestrator.md +0 -566
  25. package/autopm/.claude/agents/cloud/openai-python-expert.md +0 -1087
  26. package/autopm/.claude/agents/cloud/terraform-infrastructure-expert.md +0 -454
  27. package/autopm/.claude/agents/core/agent-manager.md +0 -296
  28. package/autopm/.claude/agents/core/code-analyzer.md +0 -131
  29. package/autopm/.claude/agents/core/file-analyzer.md +0 -162
  30. package/autopm/.claude/agents/core/test-runner.md +0 -200
  31. package/autopm/.claude/agents/data/airflow-orchestration-expert.md +0 -52
  32. package/autopm/.claude/agents/data/kedro-pipeline-expert.md +0 -50
  33. package/autopm/.claude/agents/data/langgraph-workflow-expert.md +0 -520
  34. package/autopm/.claude/agents/databases/README.md +0 -50
  35. package/autopm/.claude/agents/databases/bigquery-expert.md +0 -392
  36. package/autopm/.claude/agents/databases/cosmosdb-expert.md +0 -368
  37. package/autopm/.claude/agents/databases/mongodb-expert.md +0 -398
  38. package/autopm/.claude/agents/databases/postgresql-expert.md +0 -321
  39. package/autopm/.claude/agents/databases/redis-expert.md +0 -52
  40. package/autopm/.claude/agents/devops/README.md +0 -52
  41. package/autopm/.claude/agents/devops/azure-devops-specialist.md +0 -308
  42. package/autopm/.claude/agents/devops/docker-containerization-expert.md +0 -298
  43. package/autopm/.claude/agents/devops/github-operations-specialist.md +0 -335
  44. package/autopm/.claude/agents/devops/mcp-context-manager.md +0 -319
  45. package/autopm/.claude/agents/devops/observability-engineer.md +0 -574
  46. package/autopm/.claude/agents/devops/ssh-operations-expert.md +0 -1093
  47. package/autopm/.claude/agents/devops/traefik-proxy-expert.md +0 -444
  48. package/autopm/.claude/agents/frameworks/README.md +0 -64
  49. package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +0 -360
  50. package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +0 -254
  51. package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +0 -217
  52. package/autopm/.claude/agents/frameworks/react-ui-expert.md +0 -226
  53. package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +0 -770
  54. package/autopm/.claude/agents/frameworks/ux-design-expert.md +0 -244
  55. package/autopm/.claude/agents/integration/message-queue-engineer.md +0 -794
  56. package/autopm/.claude/agents/languages/README.md +0 -50
  57. package/autopm/.claude/agents/languages/bash-scripting-expert.md +0 -541
  58. package/autopm/.claude/agents/languages/javascript-frontend-engineer.md +0 -197
  59. package/autopm/.claude/agents/languages/nodejs-backend-engineer.md +0 -226
  60. package/autopm/.claude/agents/languages/python-backend-engineer.md +0 -214
  61. package/autopm/.claude/agents/languages/python-backend-expert.md +0 -289
  62. package/autopm/.claude/agents/testing/frontend-testing-engineer.md +0 -395
  63. package/autopm/.claude/commands/ai/langgraph-workflow.md +0 -65
  64. package/autopm/.claude/commands/ai/openai-chat.md +0 -65
  65. package/autopm/.claude/commands/azure/COMMANDS.md +0 -107
  66. package/autopm/.claude/commands/azure/COMMAND_MAPPING.md +0 -252
  67. package/autopm/.claude/commands/azure/INTEGRATION_FIX.md +0 -103
  68. package/autopm/.claude/commands/azure/README.md +0 -246
  69. package/autopm/.claude/commands/azure/active-work.md +0 -198
  70. package/autopm/.claude/commands/azure/aliases.md +0 -143
  71. package/autopm/.claude/commands/azure/blocked-items.md +0 -287
  72. package/autopm/.claude/commands/azure/clean.md +0 -93
  73. package/autopm/.claude/commands/azure/docs-query.md +0 -48
  74. package/autopm/.claude/commands/azure/feature-decompose.md +0 -380
  75. package/autopm/.claude/commands/azure/feature-list.md +0 -61
  76. package/autopm/.claude/commands/azure/feature-new.md +0 -115
  77. package/autopm/.claude/commands/azure/feature-show.md +0 -205
  78. package/autopm/.claude/commands/azure/feature-start.md +0 -130
  79. package/autopm/.claude/commands/azure/fix-integration-example.md +0 -93
  80. package/autopm/.claude/commands/azure/help.md +0 -150
  81. package/autopm/.claude/commands/azure/import-us.md +0 -269
  82. package/autopm/.claude/commands/azure/init.md +0 -211
  83. package/autopm/.claude/commands/azure/next-task.md +0 -262
  84. package/autopm/.claude/commands/azure/search.md +0 -160
  85. package/autopm/.claude/commands/azure/sprint-status.md +0 -235
  86. package/autopm/.claude/commands/azure/standup.md +0 -260
  87. package/autopm/.claude/commands/azure/sync-all.md +0 -99
  88. package/autopm/.claude/commands/azure/task-analyze.md +0 -186
  89. package/autopm/.claude/commands/azure/task-close.md +0 -329
  90. package/autopm/.claude/commands/azure/task-edit.md +0 -145
  91. package/autopm/.claude/commands/azure/task-list.md +0 -263
  92. package/autopm/.claude/commands/azure/task-new.md +0 -84
  93. package/autopm/.claude/commands/azure/task-reopen.md +0 -79
  94. package/autopm/.claude/commands/azure/task-show.md +0 -126
  95. package/autopm/.claude/commands/azure/task-start.md +0 -301
  96. package/autopm/.claude/commands/azure/task-status.md +0 -65
  97. package/autopm/.claude/commands/azure/task-sync.md +0 -67
  98. package/autopm/.claude/commands/azure/us-edit.md +0 -164
  99. package/autopm/.claude/commands/azure/us-list.md +0 -202
  100. package/autopm/.claude/commands/azure/us-new.md +0 -265
  101. package/autopm/.claude/commands/azure/us-parse.md +0 -253
  102. package/autopm/.claude/commands/azure/us-show.md +0 -188
  103. package/autopm/.claude/commands/azure/us-status.md +0 -320
  104. package/autopm/.claude/commands/azure/validate.md +0 -86
  105. package/autopm/.claude/commands/azure/work-item-sync.md +0 -47
  106. package/autopm/.claude/commands/cloud/infra-deploy.md +0 -38
  107. package/autopm/.claude/commands/github/workflow-create.md +0 -42
  108. package/autopm/.claude/commands/infrastructure/ssh-security.md +0 -65
  109. package/autopm/.claude/commands/infrastructure/traefik-setup.md +0 -65
  110. package/autopm/.claude/commands/kubernetes/deploy.md +0 -37
  111. package/autopm/.claude/commands/playwright/test-scaffold.md +0 -38
  112. package/autopm/.claude/commands/pm/blocked.md +0 -28
  113. package/autopm/.claude/commands/pm/clean.md +0 -119
  114. package/autopm/.claude/commands/pm/context-create.md +0 -136
  115. package/autopm/.claude/commands/pm/context-prime.md +0 -170
  116. package/autopm/.claude/commands/pm/context-update.md +0 -292
  117. package/autopm/.claude/commands/pm/context.md +0 -28
  118. package/autopm/.claude/commands/pm/epic-close.md +0 -86
  119. package/autopm/.claude/commands/pm/epic-decompose.md +0 -370
  120. package/autopm/.claude/commands/pm/epic-edit.md +0 -83
  121. package/autopm/.claude/commands/pm/epic-list.md +0 -30
  122. package/autopm/.claude/commands/pm/epic-merge.md +0 -222
  123. package/autopm/.claude/commands/pm/epic-oneshot.md +0 -119
  124. package/autopm/.claude/commands/pm/epic-refresh.md +0 -119
  125. package/autopm/.claude/commands/pm/epic-show.md +0 -28
  126. package/autopm/.claude/commands/pm/epic-split.md +0 -120
  127. package/autopm/.claude/commands/pm/epic-start.md +0 -195
  128. package/autopm/.claude/commands/pm/epic-status.md +0 -28
  129. package/autopm/.claude/commands/pm/epic-sync-modular.md +0 -338
  130. package/autopm/.claude/commands/pm/epic-sync-original.md +0 -473
  131. package/autopm/.claude/commands/pm/epic-sync.md +0 -486
  132. package/autopm/.claude/commands/pm/help.md +0 -28
  133. package/autopm/.claude/commands/pm/import.md +0 -115
  134. package/autopm/.claude/commands/pm/in-progress.md +0 -28
  135. package/autopm/.claude/commands/pm/init.md +0 -28
  136. package/autopm/.claude/commands/pm/issue-analyze.md +0 -202
  137. package/autopm/.claude/commands/pm/issue-close.md +0 -119
  138. package/autopm/.claude/commands/pm/issue-edit.md +0 -93
  139. package/autopm/.claude/commands/pm/issue-reopen.md +0 -87
  140. package/autopm/.claude/commands/pm/issue-show.md +0 -41
  141. package/autopm/.claude/commands/pm/issue-start.md +0 -234
  142. package/autopm/.claude/commands/pm/issue-status.md +0 -95
  143. package/autopm/.claude/commands/pm/issue-sync.md +0 -411
  144. package/autopm/.claude/commands/pm/next.md +0 -28
  145. package/autopm/.claude/commands/pm/prd-edit.md +0 -82
  146. package/autopm/.claude/commands/pm/prd-list.md +0 -28
  147. package/autopm/.claude/commands/pm/prd-new.md +0 -55
  148. package/autopm/.claude/commands/pm/prd-parse.md +0 -42
  149. package/autopm/.claude/commands/pm/prd-status.md +0 -28
  150. package/autopm/.claude/commands/pm/search.md +0 -28
  151. package/autopm/.claude/commands/pm/standup.md +0 -28
  152. package/autopm/.claude/commands/pm/status.md +0 -28
  153. package/autopm/.claude/commands/pm/sync.md +0 -99
  154. package/autopm/.claude/commands/pm/test-reference-update.md +0 -151
  155. package/autopm/.claude/commands/pm/validate.md +0 -28
  156. package/autopm/.claude/commands/pm/what-next.md +0 -28
  157. package/autopm/.claude/commands/python/api-scaffold.md +0 -50
  158. package/autopm/.claude/commands/python/docs-query.md +0 -48
  159. package/autopm/.claude/commands/react/app-scaffold.md +0 -50
  160. package/autopm/.claude/commands/testing/prime.md +0 -314
  161. package/autopm/.claude/commands/testing/run.md +0 -125
  162. package/autopm/.claude/commands/ui/bootstrap-scaffold.md +0 -65
  163. package/autopm/.claude/commands/ui/tailwind-system.md +0 -64
  164. package/autopm/.claude/rules/ai-integration-patterns.md +0 -219
  165. package/autopm/.claude/rules/ci-cd-kubernetes-strategy.md +0 -25
  166. package/autopm/.claude/rules/database-management-strategy.md +0 -17
  167. package/autopm/.claude/rules/database-pipeline.md +0 -94
  168. package/autopm/.claude/rules/devops-troubleshooting-playbook.md +0 -450
  169. package/autopm/.claude/rules/docker-first-development.md +0 -404
  170. package/autopm/.claude/rules/infrastructure-pipeline.md +0 -128
  171. package/autopm/.claude/rules/performance-guidelines.md +0 -403
  172. package/autopm/.claude/rules/ui-development-standards.md +0 -281
  173. package/autopm/.claude/rules/ui-framework-rules.md +0 -151
  174. package/autopm/.claude/rules/ux-design-rules.md +0 -209
  175. package/autopm/.claude/rules/visual-testing.md +0 -223
  176. package/autopm/.claude/scripts/azure/README.md +0 -192
  177. package/autopm/.claude/scripts/azure/active-work.js +0 -524
  178. package/autopm/.claude/scripts/azure/active-work.sh +0 -20
  179. package/autopm/.claude/scripts/azure/blocked.js +0 -520
  180. package/autopm/.claude/scripts/azure/blocked.sh +0 -20
  181. package/autopm/.claude/scripts/azure/daily.js +0 -533
  182. package/autopm/.claude/scripts/azure/daily.sh +0 -20
  183. package/autopm/.claude/scripts/azure/dashboard.js +0 -970
  184. package/autopm/.claude/scripts/azure/dashboard.sh +0 -20
  185. package/autopm/.claude/scripts/azure/feature-list.js +0 -254
  186. package/autopm/.claude/scripts/azure/feature-list.sh +0 -20
  187. package/autopm/.claude/scripts/azure/feature-show.js +0 -7
  188. package/autopm/.claude/scripts/azure/feature-show.sh +0 -20
  189. package/autopm/.claude/scripts/azure/feature-status.js +0 -604
  190. package/autopm/.claude/scripts/azure/feature-status.sh +0 -20
  191. package/autopm/.claude/scripts/azure/help.js +0 -342
  192. package/autopm/.claude/scripts/azure/help.sh +0 -20
  193. package/autopm/.claude/scripts/azure/next-task.js +0 -508
  194. package/autopm/.claude/scripts/azure/next-task.sh +0 -20
  195. package/autopm/.claude/scripts/azure/search.js +0 -469
  196. package/autopm/.claude/scripts/azure/search.sh +0 -20
  197. package/autopm/.claude/scripts/azure/setup.js +0 -745
  198. package/autopm/.claude/scripts/azure/setup.sh +0 -20
  199. package/autopm/.claude/scripts/azure/sprint-report.js +0 -1012
  200. package/autopm/.claude/scripts/azure/sprint-report.sh +0 -20
  201. package/autopm/.claude/scripts/azure/sync.js +0 -563
  202. package/autopm/.claude/scripts/azure/sync.sh +0 -20
  203. package/autopm/.claude/scripts/azure/us-list.js +0 -210
  204. package/autopm/.claude/scripts/azure/us-list.sh +0 -20
  205. package/autopm/.claude/scripts/azure/us-status.js +0 -238
  206. package/autopm/.claude/scripts/azure/us-status.sh +0 -20
  207. package/autopm/.claude/scripts/azure/validate.js +0 -626
  208. package/autopm/.claude/scripts/azure/validate.sh +0 -20
  209. package/autopm/.claude/scripts/azure/wrapper-template.sh +0 -20
  210. package/autopm/.claude/scripts/github/dependency-tracker.js +0 -554
  211. package/autopm/.claude/scripts/github/dependency-validator.js +0 -545
  212. package/autopm/.claude/scripts/github/dependency-visualizer.js +0 -477
  213. package/autopm/.claude/scripts/pm/analytics.js +0 -425
  214. package/autopm/.claude/scripts/pm/blocked.js +0 -164
  215. package/autopm/.claude/scripts/pm/blocked.sh +0 -78
  216. package/autopm/.claude/scripts/pm/clean.js +0 -464
  217. package/autopm/.claude/scripts/pm/context-create.js +0 -216
  218. package/autopm/.claude/scripts/pm/context-prime.js +0 -335
  219. package/autopm/.claude/scripts/pm/context-update.js +0 -344
  220. package/autopm/.claude/scripts/pm/context.js +0 -338
  221. package/autopm/.claude/scripts/pm/epic-close.js +0 -347
  222. package/autopm/.claude/scripts/pm/epic-edit.js +0 -382
  223. package/autopm/.claude/scripts/pm/epic-list.js +0 -273
  224. package/autopm/.claude/scripts/pm/epic-list.sh +0 -109
  225. package/autopm/.claude/scripts/pm/epic-show.js +0 -291
  226. package/autopm/.claude/scripts/pm/epic-show.sh +0 -105
  227. package/autopm/.claude/scripts/pm/epic-split.js +0 -522
  228. package/autopm/.claude/scripts/pm/epic-start/epic-start.js +0 -183
  229. package/autopm/.claude/scripts/pm/epic-start/epic-start.sh +0 -94
  230. package/autopm/.claude/scripts/pm/epic-status.js +0 -291
  231. package/autopm/.claude/scripts/pm/epic-status.sh +0 -104
  232. package/autopm/.claude/scripts/pm/epic-sync/README.md +0 -208
  233. package/autopm/.claude/scripts/pm/epic-sync/create-epic-issue.sh +0 -77
  234. package/autopm/.claude/scripts/pm/epic-sync/create-task-issues.sh +0 -86
  235. package/autopm/.claude/scripts/pm/epic-sync/update-epic-file.sh +0 -79
  236. package/autopm/.claude/scripts/pm/epic-sync/update-references.sh +0 -89
  237. package/autopm/.claude/scripts/pm/epic-sync.sh +0 -137
  238. package/autopm/.claude/scripts/pm/help.js +0 -92
  239. package/autopm/.claude/scripts/pm/help.sh +0 -90
  240. package/autopm/.claude/scripts/pm/in-progress.js +0 -178
  241. package/autopm/.claude/scripts/pm/in-progress.sh +0 -93
  242. package/autopm/.claude/scripts/pm/init.js +0 -321
  243. package/autopm/.claude/scripts/pm/init.sh +0 -178
  244. package/autopm/.claude/scripts/pm/issue-close.js +0 -232
  245. package/autopm/.claude/scripts/pm/issue-edit.js +0 -310
  246. package/autopm/.claude/scripts/pm/issue-show.js +0 -272
  247. package/autopm/.claude/scripts/pm/issue-start.js +0 -181
  248. package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +0 -468
  249. package/autopm/.claude/scripts/pm/issue-sync/gather-updates.sh +0 -460
  250. package/autopm/.claude/scripts/pm/issue-sync/post-comment.sh +0 -330
  251. package/autopm/.claude/scripts/pm/issue-sync/preflight-validation.sh +0 -348
  252. package/autopm/.claude/scripts/pm/issue-sync/update-frontmatter.sh +0 -387
  253. package/autopm/.claude/scripts/pm/lib/README.md +0 -85
  254. package/autopm/.claude/scripts/pm/lib/epic-discovery.js +0 -119
  255. package/autopm/.claude/scripts/pm/lib/logger.js +0 -78
  256. package/autopm/.claude/scripts/pm/next.js +0 -189
  257. package/autopm/.claude/scripts/pm/next.sh +0 -72
  258. package/autopm/.claude/scripts/pm/optimize.js +0 -407
  259. package/autopm/.claude/scripts/pm/pr-create.js +0 -337
  260. package/autopm/.claude/scripts/pm/pr-list.js +0 -257
  261. package/autopm/.claude/scripts/pm/prd-list.js +0 -242
  262. package/autopm/.claude/scripts/pm/prd-list.sh +0 -103
  263. package/autopm/.claude/scripts/pm/prd-new.js +0 -684
  264. package/autopm/.claude/scripts/pm/prd-parse.js +0 -547
  265. package/autopm/.claude/scripts/pm/prd-status.js +0 -152
  266. package/autopm/.claude/scripts/pm/prd-status.sh +0 -63
  267. package/autopm/.claude/scripts/pm/release.js +0 -460
  268. package/autopm/.claude/scripts/pm/search.js +0 -192
  269. package/autopm/.claude/scripts/pm/search.sh +0 -89
  270. package/autopm/.claude/scripts/pm/standup.js +0 -362
  271. package/autopm/.claude/scripts/pm/standup.sh +0 -95
  272. package/autopm/.claude/scripts/pm/status.js +0 -148
  273. package/autopm/.claude/scripts/pm/status.sh +0 -59
  274. package/autopm/.claude/scripts/pm/sync-batch.js +0 -337
  275. package/autopm/.claude/scripts/pm/sync.js +0 -343
  276. package/autopm/.claude/scripts/pm/template-list.js +0 -141
  277. package/autopm/.claude/scripts/pm/template-new.js +0 -366
  278. package/autopm/.claude/scripts/pm/validate.js +0 -274
  279. package/autopm/.claude/scripts/pm/validate.sh +0 -106
  280. package/autopm/.claude/scripts/pm/what-next.js +0 -660
  281. package/bin/node/azure-feature-show.js +0 -7
@@ -351,33 +351,142 @@ async function issueEdit(argv) {
351
351
  * @param {Object} argv - Command arguments
352
352
  */
353
353
  async function issueSync(argv) {
354
- const spinner = ora(`Syncing issue: #${argv.number}`).start();
354
+ const provider = argv.provider || 'github';
355
+ const spinner = ora(`Syncing issue: #${argv.number} (${provider})`).start();
355
356
 
356
357
  try {
357
- const issueService = new IssueService();
358
+ let providerInstance;
359
+ let issueService;
360
+
361
+ // Load provider based on --provider flag
362
+ if (provider === 'azure') {
363
+ // Load Azure DevOps provider
364
+ const AzureDevOpsProvider = require('../../providers/AzureDevOpsProvider');
365
+ providerInstance = new AzureDevOpsProvider({
366
+ token: process.env.AZURE_DEVOPS_PAT,
367
+ organization: process.env.AZURE_DEVOPS_ORG,
368
+ project: process.env.AZURE_DEVOPS_PROJECT
369
+ });
358
370
 
359
- // Check if issue exists
360
- const issue = await issueService.getLocalIssue(argv.number);
371
+ await providerInstance.authenticate();
372
+ issueService = new IssueService({ provider: providerInstance });
361
373
 
362
- // TODO: Implement provider integration
363
- // For now, just show a message
364
- spinner.info(chalk.yellow('Provider sync not yet implemented'));
374
+ let result;
365
375
 
366
- console.log(chalk.yellow(`\n⚠️ GitHub/Azure sync feature coming soon!\n`));
376
+ if (argv.push) {
377
+ // Push to Azure
378
+ spinner.text = 'Pushing to Azure DevOps...';
379
+ result = await issueService.syncToAzure(argv.number, { detectConflicts: true });
380
+ } else if (argv.pull && argv.azure) {
381
+ // Pull from Azure
382
+ spinner.text = 'Pulling from Azure DevOps...';
383
+ result = await issueService.syncFromAzure(argv.azure, { detectConflicts: true });
384
+ } else {
385
+ // Default: bidirectional sync
386
+ spinner.text = 'Bidirectional sync...';
387
+ result = await issueService.syncBidirectionalAzure(argv.number, { conflictStrategy: 'detect' });
388
+ }
367
389
 
368
- console.log(chalk.dim('This feature will:'));
369
- console.log(chalk.dim(' - Create GitHub/Azure issue if not exists'));
370
- console.log(chalk.dim(' - Update existing issue'));
371
- console.log(chalk.dim(' - Sync issue status and comments\n'));
390
+ if (!result.success && result.conflict) {
391
+ spinner.warn(chalk.yellow('Conflict detected'));
372
392
 
373
- console.log(chalk.bold('For now, you can:'));
374
- console.log(` ${chalk.cyan('1.')} View issue: ${chalk.yellow('autopm issue show ' + argv.number)}`);
375
- console.log(` ${chalk.cyan('2.')} Check status: ${chalk.yellow('autopm issue status ' + argv.number)}\n`);
393
+ console.log(chalk.yellow(`\n⚠️ Sync Conflict Detected!\n`));
394
+ console.log(chalk.bold('Conflict Details:'));
395
+ console.log(` Local newer: ${result.conflict.localNewer}`);
396
+ console.log(` Remote newer: ${result.conflict.remoteNewer}\n`);
397
+
398
+ console.log(chalk.bold('Resolution Options:'));
399
+ console.log(` ${chalk.cyan('1.')} Use local: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --provider azure --strategy local')}`);
400
+ console.log(` ${chalk.cyan('2.')} Use remote: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --provider azure --strategy remote')}`);
401
+ console.log(` ${chalk.cyan('3.')} Use newest: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --provider azure --strategy newest')}\n`);
402
+ } else {
403
+ spinner.succeed(chalk.green('Sync complete'));
404
+
405
+ console.log(chalk.green(`\n✅ Issue #${argv.number} synced successfully!\n`));
406
+ console.log(chalk.bold('Sync Details:'));
407
+ console.log(` Provider: Azure DevOps`);
408
+ console.log(` Action: ${result.action || 'synced'}`);
409
+ if (result.workItemId) {
410
+ console.log(` Work Item #: ${result.workItemId}`);
411
+ }
412
+ if (result.direction) {
413
+ console.log(` Direction: ${result.direction}`);
414
+ }
415
+ console.log();
416
+ }
417
+
418
+ } else {
419
+ // Load GitHub provider (default)
420
+ const GitHubProvider = require('../../providers/GitHubProvider');
421
+ providerInstance = new GitHubProvider({
422
+ token: process.env.GITHUB_TOKEN,
423
+ owner: process.env.GITHUB_OWNER || process.env.GITHUB_USER,
424
+ repo: process.env.GITHUB_REPO
425
+ });
426
+
427
+ await providerInstance.authenticate();
428
+ issueService = new IssueService({ provider: providerInstance });
429
+
430
+ let result;
431
+
432
+ if (argv.push) {
433
+ // Push to GitHub
434
+ spinner.text = 'Pushing to GitHub...';
435
+ result = await issueService.syncToGitHub(argv.number, { detectConflicts: true });
436
+ } else if (argv.pull && argv.github) {
437
+ // Pull from GitHub
438
+ spinner.text = 'Pulling from GitHub...';
439
+ result = await issueService.syncFromGitHub(argv.github, { detectConflicts: true });
440
+ } else {
441
+ // Default: bidirectional sync
442
+ spinner.text = 'Bidirectional sync...';
443
+ result = await issueService.syncBidirectional(argv.number, { conflictStrategy: 'detect' });
444
+ }
445
+
446
+ if (!result.success && result.conflict) {
447
+ spinner.warn(chalk.yellow('Conflict detected'));
448
+
449
+ console.log(chalk.yellow(`\n⚠️ Sync Conflict Detected!\n`));
450
+ console.log(chalk.bold('Conflict Details:'));
451
+ console.log(` Local newer: ${result.conflict.localNewer}`);
452
+ console.log(` Remote newer: ${result.conflict.remoteNewer}`);
453
+ console.log(` Fields: ${result.conflict.conflictFields.join(', ')}\n`);
454
+
455
+ console.log(chalk.bold('Resolution Options:'));
456
+ console.log(` ${chalk.cyan('1.')} Use local: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --strategy local')}`);
457
+ console.log(` ${chalk.cyan('2.')} Use remote: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --strategy remote')}`);
458
+ console.log(` ${chalk.cyan('3.')} Use newest: ${chalk.yellow('autopm issue sync-resolve ' + argv.number + ' --strategy newest')}\n`);
459
+ } else {
460
+ spinner.succeed(chalk.green('Sync complete'));
461
+
462
+ console.log(chalk.green(`\n✅ Issue #${argv.number} synced successfully!\n`));
463
+ console.log(chalk.bold('Sync Details:'));
464
+ console.log(` Provider: GitHub`);
465
+ console.log(` Action: ${result.action || 'synced'}`);
466
+ if (result.githubNumber) {
467
+ console.log(` GitHub #: ${result.githubNumber}`);
468
+ }
469
+ if (result.direction) {
470
+ console.log(` Direction: ${result.direction}`);
471
+ }
472
+ console.log();
473
+ }
474
+ }
376
475
 
377
476
  } catch (error) {
378
477
  spinner.fail(chalk.red('Failed to sync issue'));
379
478
 
380
- if (error.message.includes('not found')) {
479
+ if (error.message.includes('GITHUB_TOKEN')) {
480
+ console.error(chalk.red(`\n❌ GitHub token not configured`));
481
+ console.error(chalk.yellow('Set: export GITHUB_TOKEN=your_token'));
482
+ console.error(chalk.yellow('Set: export GITHUB_OWNER=username'));
483
+ console.error(chalk.yellow('Set: export GITHUB_REPO=repository\n'));
484
+ } else if (error.message.includes('AZURE_DEVOPS_PAT')) {
485
+ console.error(chalk.red(`\n❌ Azure DevOps token not configured`));
486
+ console.error(chalk.yellow('Set: export AZURE_DEVOPS_PAT=your_pat_token'));
487
+ console.error(chalk.yellow('Set: export AZURE_DEVOPS_ORG=your_organization'));
488
+ console.error(chalk.yellow('Set: export AZURE_DEVOPS_PROJECT=your_project\n'));
489
+ } else if (error.message.includes('not found')) {
381
490
  console.error(chalk.red(`\nError: ${error.message}`));
382
491
  } else {
383
492
  console.error(chalk.red(`\nError: ${error.message}`));
@@ -385,6 +494,180 @@ async function issueSync(argv) {
385
494
  }
386
495
  }
387
496
 
497
+ /**
498
+ * Check sync status of an issue
499
+ * @param {Object} argv - Command arguments
500
+ */
501
+ async function issueSyncStatus(argv) {
502
+ const provider = argv.provider || 'github';
503
+ const spinner = ora(`Checking sync status: #${argv.number} (${provider})`).start();
504
+
505
+ try {
506
+ let providerInstance;
507
+ let issueService;
508
+
509
+ if (provider === 'azure') {
510
+ // Load Azure DevOps provider
511
+ const AzureDevOpsProvider = require('../../providers/AzureDevOpsProvider');
512
+ providerInstance = new AzureDevOpsProvider({
513
+ token: process.env.AZURE_DEVOPS_PAT,
514
+ organization: process.env.AZURE_DEVOPS_ORG,
515
+ project: process.env.AZURE_DEVOPS_PROJECT
516
+ });
517
+
518
+ await providerInstance.authenticate();
519
+ issueService = new IssueService({ provider: providerInstance });
520
+ const status = await issueService.getAzureSyncStatus(argv.number);
521
+
522
+ spinner.succeed(chalk.green('Status retrieved'));
523
+
524
+ console.log('\n' + chalk.bold('🔄 Sync Status (Azure DevOps)') + '\n');
525
+ console.log(chalk.gray('─'.repeat(50)) + '\n');
526
+
527
+ console.log(chalk.bold('Issue:'));
528
+ console.log(` Local #: ${status.localNumber}`);
529
+ console.log(` Work Item #: ${status.workItemId || 'Not synced'}`);
530
+ console.log(` Status: ${status.synced ? chalk.green('✓ Synced') : chalk.yellow('⚠ Out of sync')}`);
531
+
532
+ if (status.lastSync) {
533
+ console.log(` Last Sync: ${new Date(status.lastSync).toLocaleString()}`);
534
+ }
535
+
536
+ console.log('\n' + chalk.gray('─'.repeat(50)) + '\n');
537
+
538
+ if (!status.synced) {
539
+ console.log(chalk.yellow('💡 Tip: Run sync to update:'));
540
+ console.log(` ${chalk.cyan('autopm issue sync ' + argv.number + ' --provider azure')}\n`);
541
+ }
542
+
543
+ } else {
544
+ // Load GitHub provider
545
+ const GitHubProvider = require('../../providers/GitHubProvider');
546
+ providerInstance = new GitHubProvider({
547
+ token: process.env.GITHUB_TOKEN,
548
+ owner: process.env.GITHUB_OWNER || process.env.GITHUB_USER,
549
+ repo: process.env.GITHUB_REPO
550
+ });
551
+
552
+ await providerInstance.authenticate();
553
+ issueService = new IssueService({ provider: providerInstance });
554
+ const status = await issueService.getSyncStatus(argv.number);
555
+
556
+ spinner.succeed(chalk.green('Status retrieved'));
557
+
558
+ console.log('\n' + chalk.bold('🔄 Sync Status') + '\n');
559
+ console.log(chalk.gray('─'.repeat(50)) + '\n');
560
+
561
+ console.log(chalk.bold('Issue:'));
562
+ console.log(` Local #: ${status.localNumber}`);
563
+ console.log(` GitHub #: ${status.githubNumber || 'Not synced'}`);
564
+ console.log(` Status: ${status.synced ? chalk.green('✓ Synced') : chalk.yellow('⚠ Out of sync')}`);
565
+
566
+ if (status.lastSync) {
567
+ console.log(` Last Sync: ${new Date(status.lastSync).toLocaleString()}`);
568
+ }
569
+
570
+ console.log('\n' + chalk.gray('─'.repeat(50)) + '\n');
571
+
572
+ if (!status.synced) {
573
+ console.log(chalk.yellow('💡 Tip: Run sync to update:'));
574
+ console.log(` ${chalk.cyan('autopm issue sync ' + argv.number)}\n`);
575
+ }
576
+ }
577
+
578
+ } catch (error) {
579
+ spinner.fail(chalk.red('Failed to check status'));
580
+ console.error(chalk.red(`\nError: ${error.message}`));
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Resolve sync conflict
586
+ * @param {Object} argv - Command arguments
587
+ */
588
+ async function issueSyncResolve(argv) {
589
+ const provider = argv.provider || 'github';
590
+ const spinner = ora(`Resolving conflict: #${argv.number} (${provider})`).start();
591
+
592
+ try {
593
+ let providerInstance;
594
+ let issueService;
595
+
596
+ if (provider === 'azure') {
597
+ // Load Azure DevOps provider
598
+ const AzureDevOpsProvider = require('../../providers/AzureDevOpsProvider');
599
+ providerInstance = new AzureDevOpsProvider({
600
+ token: process.env.AZURE_DEVOPS_PAT,
601
+ organization: process.env.AZURE_DEVOPS_ORG,
602
+ project: process.env.AZURE_DEVOPS_PROJECT
603
+ });
604
+
605
+ await providerInstance.authenticate();
606
+ issueService = new IssueService({ provider: providerInstance });
607
+ const result = await issueService.resolveAzureConflict(argv.number, argv.strategy);
608
+
609
+ if (result.resolved) {
610
+ spinner.succeed(chalk.green('Conflict resolved'));
611
+
612
+ console.log(chalk.green(`\n✅ Conflict resolved using "${result.appliedStrategy}" strategy\n`));
613
+ console.log(chalk.bold('Result:'));
614
+ console.log(` Provider: Azure DevOps`);
615
+ console.log(` Action: ${result.result.action || 'resolved'}`);
616
+ if (result.result.workItemId) {
617
+ console.log(` Work Item #: ${result.result.workItemId}`);
618
+ }
619
+ console.log();
620
+ } else {
621
+ spinner.info(chalk.yellow('Manual resolution required'));
622
+
623
+ console.log(chalk.yellow(`\n⚠️ Manual resolution required\n`));
624
+ console.log(chalk.bold('Available strategies:'));
625
+ console.log(` ${chalk.cyan('local')} - Use local version`);
626
+ console.log(` ${chalk.cyan('remote')} - Use remote (Azure DevOps) version`);
627
+ console.log(` ${chalk.cyan('newest')} - Use most recently updated\n`);
628
+ }
629
+
630
+ } else {
631
+ // Load GitHub provider (default)
632
+ const GitHubProvider = require('../../providers/GitHubProvider');
633
+ providerInstance = new GitHubProvider({
634
+ token: process.env.GITHUB_TOKEN,
635
+ owner: process.env.GITHUB_OWNER || process.env.GITHUB_USER,
636
+ repo: process.env.GITHUB_REPO
637
+ });
638
+
639
+ await providerInstance.authenticate();
640
+ issueService = new IssueService({ provider: providerInstance });
641
+ const result = await issueService.resolveConflict(argv.number, argv.strategy);
642
+
643
+ if (result.resolved) {
644
+ spinner.succeed(chalk.green('Conflict resolved'));
645
+
646
+ console.log(chalk.green(`\n✅ Conflict resolved using "${result.appliedStrategy}" strategy\n`));
647
+ console.log(chalk.bold('Result:'));
648
+ console.log(` Provider: GitHub`);
649
+ console.log(` Action: ${result.result.action || 'resolved'}`);
650
+ if (result.result.githubNumber) {
651
+ console.log(` GitHub #: ${result.result.githubNumber}`);
652
+ }
653
+ console.log();
654
+ } else {
655
+ spinner.info(chalk.yellow('Manual resolution required'));
656
+
657
+ console.log(chalk.yellow(`\n⚠️ Manual resolution required\n`));
658
+ console.log(chalk.bold('Available strategies:'));
659
+ console.log(` ${chalk.cyan('local')} - Use local version`);
660
+ console.log(` ${chalk.cyan('remote')} - Use remote (GitHub) version`);
661
+ console.log(` ${chalk.cyan('newest')} - Use most recently updated\n`);
662
+ }
663
+ }
664
+
665
+ } catch (error) {
666
+ spinner.fail(chalk.red('Failed to resolve conflict'));
667
+ console.error(chalk.red(`\nError: ${error.message}`));
668
+ }
669
+ }
670
+
388
671
  /**
389
672
  * Command builder - registers all subcommands
390
673
  * @param {Object} yargs - Yargs instance
@@ -467,6 +750,12 @@ function builder(yargs) {
467
750
  describe: 'Issue number',
468
751
  type: 'number'
469
752
  })
753
+ .option('provider', {
754
+ describe: 'Provider to sync with',
755
+ type: 'string',
756
+ choices: ['github', 'azure'],
757
+ default: 'github'
758
+ })
470
759
  .option('push', {
471
760
  describe: 'Push local changes to provider',
472
761
  type: 'boolean',
@@ -477,12 +766,59 @@ function builder(yargs) {
477
766
  type: 'boolean',
478
767
  default: false
479
768
  })
480
- .example('autopm issue sync 123', 'Sync issue #123 with provider')
481
- .example('autopm issue sync 123 --push', 'Push local changes')
482
- .example('autopm issue sync 123 --pull', 'Pull remote updates');
769
+ .example('autopm issue sync 123', 'Sync issue #123 with GitHub (default)')
770
+ .example('autopm issue sync 123 --provider azure', 'Sync with Azure DevOps')
771
+ .example('autopm issue sync 123 --push', 'Push local changes to GitHub')
772
+ .example('autopm issue sync 123 --provider azure --push', 'Push to Azure DevOps');
483
773
  },
484
774
  issueSync
485
775
  )
776
+ .command(
777
+ 'sync-status <number>',
778
+ 'Check sync status for issue',
779
+ (yargs) => {
780
+ return yargs
781
+ .positional('number', {
782
+ describe: 'Issue number',
783
+ type: 'number'
784
+ })
785
+ .option('provider', {
786
+ describe: 'Provider to check status with',
787
+ type: 'string',
788
+ choices: ['github', 'azure'],
789
+ default: 'github'
790
+ })
791
+ .example('autopm issue sync-status 123', 'Check GitHub sync status (default)')
792
+ .example('autopm issue sync-status 123 --provider azure', 'Check Azure DevOps sync status');
793
+ },
794
+ issueSyncStatus
795
+ )
796
+ .command(
797
+ 'sync-resolve <number>',
798
+ 'Resolve sync conflict',
799
+ (yargs) => {
800
+ return yargs
801
+ .positional('number', {
802
+ describe: 'Issue number',
803
+ type: 'number'
804
+ })
805
+ .option('provider', {
806
+ describe: 'Provider to resolve conflict with',
807
+ type: 'string',
808
+ choices: ['github', 'azure'],
809
+ default: 'github'
810
+ })
811
+ .option('strategy', {
812
+ describe: 'Resolution strategy',
813
+ type: 'string',
814
+ choices: ['local', 'remote', 'newest', 'manual'],
815
+ demandOption: true
816
+ })
817
+ .example('autopm issue sync-resolve 123 --strategy newest', 'Use newest version (GitHub)')
818
+ .example('autopm issue sync-resolve 123 --provider azure --strategy local', 'Use local version (Azure)');
819
+ },
820
+ issueSyncResolve
821
+ )
486
822
  .demandCommand(1, 'You must specify an issue command')
487
823
  .strictCommands()
488
824
  .help();
@@ -506,6 +842,8 @@ module.exports = {
506
842
  console.log(' status <number> Check issue status');
507
843
  console.log(' edit <number> Edit issue in editor');
508
844
  console.log(' sync <number> Sync with GitHub/Azure');
845
+ console.log(' sync-status <number> Check sync status');
846
+ console.log(' sync-resolve <number> Resolve sync conflict');
509
847
  console.log('\nUse: autopm issue <command> --help for more info\n');
510
848
  }
511
849
  },
@@ -515,6 +853,8 @@ module.exports = {
515
853
  close: issueClose,
516
854
  status: issueStatus,
517
855
  edit: issueEdit,
518
- sync: issueSync
856
+ sync: issueSync,
857
+ syncStatus: issueSyncStatus,
858
+ syncResolve: issueSyncResolve
519
859
  }
520
860
  };