specweave 0.6.8 → 0.7.0

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 (255) hide show
  1. package/.claude-plugin/README.md +1 -1
  2. package/CLAUDE.md +903 -99
  3. package/README.md +143 -207
  4. package/bin/specweave.js +67 -0
  5. package/dist/cli/commands/abandon.d.ts +13 -0
  6. package/dist/cli/commands/abandon.d.ts.map +1 -0
  7. package/dist/cli/commands/abandon.js +15 -0
  8. package/dist/cli/commands/abandon.js.map +1 -0
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +90 -18
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/pause.d.ts +13 -0
  13. package/dist/cli/commands/pause.d.ts.map +1 -0
  14. package/dist/cli/commands/pause.js +15 -0
  15. package/dist/cli/commands/pause.js.map +1 -0
  16. package/dist/cli/commands/qa.d.ts +54 -0
  17. package/dist/cli/commands/qa.d.ts.map +1 -0
  18. package/dist/cli/commands/qa.js +98 -0
  19. package/dist/cli/commands/qa.js.map +1 -0
  20. package/dist/cli/commands/resume.d.ts +12 -0
  21. package/dist/cli/commands/resume.d.ts.map +1 -0
  22. package/dist/cli/commands/resume.js +14 -0
  23. package/dist/cli/commands/resume.js.map +1 -0
  24. package/dist/cli/commands/status.d.ts +12 -0
  25. package/dist/cli/commands/status.d.ts.map +1 -0
  26. package/dist/cli/commands/status.js +23 -0
  27. package/dist/cli/commands/status.js.map +1 -0
  28. package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
  29. package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
  30. package/dist/cli/helpers/issue-tracker/ado.js +223 -0
  31. package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
  32. package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
  33. package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
  34. package/dist/cli/helpers/issue-tracker/github.js +284 -0
  35. package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
  36. package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
  37. package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
  38. package/dist/cli/helpers/issue-tracker/index.js +270 -0
  39. package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
  40. package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
  41. package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
  42. package/dist/cli/helpers/issue-tracker/jira.js +265 -0
  43. package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
  44. package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
  45. package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
  46. package/dist/cli/helpers/issue-tracker/types.js +16 -0
  47. package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
  48. package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
  49. package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
  50. package/dist/cli/helpers/issue-tracker/utils.js +240 -0
  51. package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
  52. package/dist/core/increment/limits.d.ts +68 -0
  53. package/dist/core/increment/limits.d.ts.map +1 -0
  54. package/dist/core/increment/limits.js +224 -0
  55. package/dist/core/increment/limits.js.map +1 -0
  56. package/dist/core/increment/metadata-manager.d.ts +114 -0
  57. package/dist/core/increment/metadata-manager.d.ts.map +1 -0
  58. package/dist/core/increment/metadata-manager.js +320 -0
  59. package/dist/core/increment/metadata-manager.js.map +1 -0
  60. package/dist/core/increment/status-commands.d.ts +43 -0
  61. package/dist/core/increment/status-commands.d.ts.map +1 -0
  62. package/dist/core/increment/status-commands.js +277 -0
  63. package/dist/core/increment/status-commands.js.map +1 -0
  64. package/dist/core/plugin-detector.d.ts +1 -0
  65. package/dist/core/plugin-detector.d.ts.map +1 -1
  66. package/dist/core/plugin-detector.js +25 -0
  67. package/dist/core/plugin-detector.js.map +1 -1
  68. package/dist/core/qa/qa-runner.d.ts +16 -0
  69. package/dist/core/qa/qa-runner.d.ts.map +1 -0
  70. package/dist/core/qa/qa-runner.js +404 -0
  71. package/dist/core/qa/qa-runner.js.map +1 -0
  72. package/dist/core/qa/quality-gate-decider.d.ts +53 -0
  73. package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
  74. package/dist/core/qa/quality-gate-decider.js +268 -0
  75. package/dist/core/qa/quality-gate-decider.js.map +1 -0
  76. package/dist/core/qa/risk-calculator.d.ts +126 -0
  77. package/dist/core/qa/risk-calculator.d.ts.map +1 -0
  78. package/dist/core/qa/risk-calculator.js +247 -0
  79. package/dist/core/qa/risk-calculator.js.map +1 -0
  80. package/dist/core/qa/types.d.ts +315 -0
  81. package/dist/core/qa/types.d.ts.map +1 -0
  82. package/dist/core/qa/types.js +8 -0
  83. package/dist/core/qa/types.js.map +1 -0
  84. package/dist/core/types/config.d.ts +35 -0
  85. package/dist/core/types/config.d.ts.map +1 -1
  86. package/dist/core/types/config.js +16 -0
  87. package/dist/core/types/config.js.map +1 -1
  88. package/dist/core/types/increment-metadata.d.ts +120 -0
  89. package/dist/core/types/increment-metadata.d.ts.map +1 -0
  90. package/dist/core/types/increment-metadata.js +138 -0
  91. package/dist/core/types/increment-metadata.js.map +1 -0
  92. package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
  93. package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
  94. package/dist/hooks/lib/invoke-translator-skill.js +201 -0
  95. package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
  96. package/dist/hooks/lib/translate-file.d.ts +59 -0
  97. package/dist/hooks/lib/translate-file.d.ts.map +1 -0
  98. package/dist/hooks/lib/translate-file.js +350 -0
  99. package/dist/hooks/lib/translate-file.js.map +1 -0
  100. package/dist/locales/en/cli.json +3 -1
  101. package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
  102. package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
  103. package/dist/metrics/calculators/change-failure-rate.js +70 -0
  104. package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
  105. package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
  106. package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
  107. package/dist/metrics/calculators/deployment-frequency.js +61 -0
  108. package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
  109. package/dist/metrics/calculators/lead-time.d.ts +22 -0
  110. package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
  111. package/dist/metrics/calculators/lead-time.js +82 -0
  112. package/dist/metrics/calculators/lead-time.js.map +1 -0
  113. package/dist/metrics/calculators/mttr.d.ts +21 -0
  114. package/dist/metrics/calculators/mttr.d.ts.map +1 -0
  115. package/dist/metrics/calculators/mttr.js +60 -0
  116. package/dist/metrics/calculators/mttr.js.map +1 -0
  117. package/dist/metrics/dora-calculator.d.ts +24 -0
  118. package/dist/metrics/dora-calculator.d.ts.map +1 -0
  119. package/dist/metrics/dora-calculator.js +104 -0
  120. package/dist/metrics/dora-calculator.js.map +1 -0
  121. package/dist/metrics/github-client.d.ts +51 -0
  122. package/dist/metrics/github-client.d.ts.map +1 -0
  123. package/dist/metrics/github-client.js +133 -0
  124. package/dist/metrics/github-client.js.map +1 -0
  125. package/dist/metrics/types.d.ts +112 -0
  126. package/dist/metrics/types.d.ts.map +1 -0
  127. package/dist/metrics/types.js +10 -0
  128. package/dist/metrics/types.js.map +1 -0
  129. package/dist/metrics/utils/percentile.d.ts +25 -0
  130. package/dist/metrics/utils/percentile.d.ts.map +1 -0
  131. package/dist/metrics/utils/percentile.js +46 -0
  132. package/dist/metrics/utils/percentile.js.map +1 -0
  133. package/dist/metrics/utils/tier-classifier.d.ts +61 -0
  134. package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
  135. package/dist/metrics/utils/tier-classifier.js +100 -0
  136. package/dist/metrics/utils/tier-classifier.js.map +1 -0
  137. package/dist/utils/auth-helpers.d.ts +58 -0
  138. package/dist/utils/auth-helpers.d.ts.map +1 -0
  139. package/dist/utils/auth-helpers.js +108 -0
  140. package/dist/utils/auth-helpers.js.map +1 -0
  141. package/dist/utils/env-file.d.ts +88 -0
  142. package/dist/utils/env-file.d.ts.map +1 -0
  143. package/dist/utils/env-file.js +180 -0
  144. package/dist/utils/env-file.js.map +1 -0
  145. package/dist/utils/plugin-detection.d.ts +50 -0
  146. package/dist/utils/plugin-detection.d.ts.map +1 -0
  147. package/dist/utils/plugin-detection.js +229 -0
  148. package/dist/utils/plugin-detection.js.map +1 -0
  149. package/dist/utils/secrets-loader.d.ts +88 -0
  150. package/dist/utils/secrets-loader.d.ts.map +1 -0
  151. package/dist/utils/secrets-loader.js +271 -0
  152. package/dist/utils/secrets-loader.js.map +1 -0
  153. package/dist/utils/translation.d.ts +187 -0
  154. package/dist/utils/translation.d.ts.map +1 -0
  155. package/dist/utils/translation.js +414 -0
  156. package/dist/utils/translation.js.map +1 -0
  157. package/package.json +28 -44
  158. package/plugins/specweave/.claude-plugin/plugin.json +3 -3
  159. package/plugins/specweave/agents/pm/AGENT.md +330 -54
  160. package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
  161. package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
  162. package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
  163. package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
  164. package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
  165. package/plugins/specweave/commands/README.md +88 -163
  166. package/plugins/specweave/commands/specweave-abandon.md +314 -0
  167. package/plugins/specweave/commands/specweave-check-tests.md +546 -0
  168. package/plugins/specweave/commands/{do.md → specweave-do.md} +5 -7
  169. package/plugins/specweave/commands/{increment.md → specweave-increment.md} +231 -4
  170. package/plugins/specweave/commands/specweave-pause.md +189 -0
  171. package/plugins/specweave/commands/specweave-qa.md +245 -0
  172. package/plugins/specweave/commands/specweave-resume.md +216 -0
  173. package/plugins/specweave/commands/specweave-status.md +397 -0
  174. package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
  175. package/plugins/specweave/commands/{translate.md → specweave-translate.md} +3 -3
  176. package/plugins/specweave/commands/specweave-update-scope.md +351 -0
  177. package/plugins/specweave/commands/specweave.md +21 -21
  178. package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
  179. package/plugins/specweave/hooks/post-task-completion.sh +141 -0
  180. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  181. package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
  182. package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
  183. package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
  184. package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
  185. package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
  186. package/plugins/specweave/skills/{rfc-generator → spec-generator}/SKILL.md +22 -29
  187. package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
  188. package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
  189. package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
  190. package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
  191. package/plugins/specweave-ado/commands/close-workitem.md +52 -0
  192. package/plugins/specweave-ado/commands/create-workitem.md +53 -0
  193. package/plugins/specweave-ado/commands/status.md +53 -0
  194. package/plugins/specweave-ado/commands/sync.md +55 -0
  195. package/plugins/specweave-ado/lib/ado-client.ts +361 -0
  196. package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
  197. package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
  198. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
  199. package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
  200. package/plugins/specweave-github/commands/{github-close-issue.md → close-issue.md} +1 -1
  201. package/plugins/specweave-github/commands/{github-create-issue.md → create-issue.md} +1 -1
  202. package/plugins/specweave-github/commands/{github-status.md → status.md} +1 -1
  203. package/plugins/specweave-github/commands/{github-sync-tasks.md → sync-tasks.md} +1 -1
  204. package/plugins/specweave-github/commands/{github-sync.md → sync.md} +1 -1
  205. package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
  206. package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
  207. package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md → monitor-setup.md} +5 -0
  208. package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md → slo-implement.md} +5 -0
  209. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
  210. package/plugins/specweave-jira/commands/{specweave.sync-jira.md → sync.md} +1 -1
  211. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
  212. package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
  213. package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
  214. package/plugins/specweave-ml/commands/ml-explain.md +1 -1
  215. package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md → ml-pipeline.md} +5 -0
  216. package/src/templates/AGENTS.md.template +331 -31
  217. package/src/templates/CLAUDE.md.template +36 -21
  218. package/src/templates/COMPLETION-REPORT.template.md +128 -0
  219. package/src/templates/README.md.template +17 -16
  220. package/src/templates/docs/README.md +11 -9
  221. package/src/templates/docs/spec-template.md +229 -0
  222. package/plugins/specweave/commands/inc.md +0 -85
  223. package/plugins/specweave/commands/list-increments.md +0 -180
  224. package/src/adapters/README.md +0 -275
  225. package/src/adapters/adapter-base.ts +0 -182
  226. package/src/adapters/adapter-interface.ts +0 -166
  227. package/src/adapters/adapter-loader.ts +0 -256
  228. package/src/adapters/agents-md-generator.ts +0 -228
  229. package/src/adapters/claude/README.md +0 -233
  230. package/src/adapters/claude/adapter.ts +0 -468
  231. package/src/adapters/claude-md-generator.ts +0 -377
  232. package/src/adapters/codex/README.md +0 -105
  233. package/src/adapters/codex/adapter.ts +0 -333
  234. package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
  235. package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
  236. package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
  237. package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
  238. package/src/adapters/cursor/README.md +0 -283
  239. package/src/adapters/cursor/adapter.ts +0 -451
  240. package/src/adapters/doc-generator.ts +0 -331
  241. package/src/adapters/gemini/README.md +0 -97
  242. package/src/adapters/gemini/adapter.ts +0 -298
  243. package/src/adapters/generic/README.md +0 -277
  244. package/src/adapters/generic/adapter.ts +0 -378
  245. package/src/adapters/registry.yaml +0 -187
  246. /package/plugins/specweave/commands/{costs.md → specweave-costs.md} +0 -0
  247. /package/plugins/specweave/commands/{done.md → specweave-done.md} +0 -0
  248. /package/plugins/specweave/commands/{next.md → specweave-next.md} +0 -0
  249. /package/plugins/specweave/commands/{progress.md → specweave-progress.md} +0 -0
  250. /package/plugins/specweave/commands/{sync-docs.md → specweave-sync-docs.md} +0 -0
  251. /package/plugins/specweave/commands/{tdd-cycle.md → specweave-tdd-cycle.md} +0 -0
  252. /package/plugins/specweave/commands/{tdd-green.md → specweave-tdd-green.md} +0 -0
  253. /package/plugins/specweave/commands/{tdd-red.md → specweave-tdd-red.md} +0 -0
  254. /package/plugins/specweave/commands/{tdd-refactor.md → specweave-tdd-refactor.md} +0 -0
  255. /package/plugins/specweave/commands/{validate.md → specweave-validate.md} +0 -0
@@ -0,0 +1,23 @@
1
+ import { showStatus } from '../../core/increment/status-commands.js';
2
+ /**
3
+ * CLI command to show increment status overview
4
+ *
5
+ * @param options - Command options (verbose, type filter)
6
+ */
7
+ export async function statusCommand(options = {}) {
8
+ const statusOptions = {
9
+ verbose: options.verbose
10
+ };
11
+ // Validate and convert type if provided
12
+ if (options.type) {
13
+ const validTypes = ['feature', 'hotfix', 'bug', 'change-request', 'refactor', 'experiment'];
14
+ if (!validTypes.includes(options.type)) {
15
+ console.error(`Invalid type: ${options.type}`);
16
+ console.error(`Valid types: ${validTypes.join(', ')}`);
17
+ process.exit(1);
18
+ }
19
+ statusOptions.type = options.type;
20
+ }
21
+ await showStatus(statusOptions);
22
+ }
23
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,yCAAyC,CAAC;AAQpF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAgC,EAAE;IACpE,MAAM,aAAa,GAAkB;QACnC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,wCAAwC;IACxC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,UAAU,GAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QACtG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,gBAAgB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,aAAa,CAAC,IAAI,GAAG,OAAO,CAAC,IAAqB,CAAC;IACrD,CAAC;IAED,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Azure DevOps Integration for Issue Tracker Setup
3
+ *
4
+ * Handles Azure DevOps authentication and connection validation
5
+ *
6
+ * @module cli/helpers/issue-tracker/ado
7
+ */
8
+ import type { AzureDevOpsCredentials, ExistingCredentials, ValidationResult } from './types.js';
9
+ import type { SupportedLanguage } from '../../../core/i18n/types.js';
10
+ /**
11
+ * Check for existing Azure DevOps credentials
12
+ *
13
+ * @param projectPath - Path to project root
14
+ * @returns Existing credentials or null
15
+ */
16
+ export declare function checkExistingAzureDevOpsCredentials(projectPath: string): Promise<ExistingCredentials | null>;
17
+ /**
18
+ * Prompt user for Azure DevOps credentials
19
+ *
20
+ * @param language - User's language
21
+ * @returns Credentials or null if skipped
22
+ */
23
+ export declare function promptAzureDevOpsCredentials(language: SupportedLanguage): Promise<AzureDevOpsCredentials | null>;
24
+ /**
25
+ * Validate Azure DevOps connection
26
+ *
27
+ * Tests authentication and returns project information
28
+ * Handles rate limiting with retry logic
29
+ *
30
+ * @param credentials - Azure DevOps credentials
31
+ * @param maxRetries - Maximum retry attempts (default: 3)
32
+ * @returns Validation result
33
+ */
34
+ export declare function validateAzureDevOpsConnection(credentials: AzureDevOpsCredentials, maxRetries?: number): Promise<ValidationResult>;
35
+ /**
36
+ * Get Azure DevOps environment variables for .env file
37
+ *
38
+ * @param credentials - Azure DevOps credentials
39
+ * @returns Array of key-value pairs for .env
40
+ */
41
+ export declare function getAzureDevOpsEnvVars(credentials: AzureDevOpsCredentials): Array<{
42
+ key: string;
43
+ value: string;
44
+ }>;
45
+ /**
46
+ * Show Azure DevOps setup complete message
47
+ *
48
+ * @param language - User's language
49
+ */
50
+ export declare function showAzureDevOpsSetupComplete(language: SupportedLanguage): void;
51
+ /**
52
+ * Show Azure DevOps setup skipped message
53
+ *
54
+ * @param language - User's language
55
+ */
56
+ export declare function showAzureDevOpsSetupSkipped(language: SupportedLanguage): void;
57
+ //# sourceMappingURL=ado.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado.d.ts","sourceRoot":"","sources":["../../../../src/cli/helpers/issue-tracker/ado.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAIrE;;;;;GAKG;AACH,wBAAsB,mCAAmC,CACvD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA2BrC;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAyExC;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,sBAAsB,EACnC,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA+D3B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,sBAAsB,GAClC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAMvC;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAS9E;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAO7E"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Azure DevOps Integration for Issue Tracker Setup
3
+ *
4
+ * Handles Azure DevOps authentication and connection validation
5
+ *
6
+ * @module cli/helpers/issue-tracker/ado
7
+ */
8
+ import chalk from 'chalk';
9
+ import inquirer from 'inquirer';
10
+ import ora from 'ora';
11
+ import { getAzureDevOpsAuth } from '../../../utils/auth-helpers.js';
12
+ import { parseEnvFile, readEnvFile } from '../../../utils/env-file.js';
13
+ import { retryWithBackoff, checkRateLimit } from './utils.js';
14
+ import { getLocaleManager } from '../../../core/i18n/locale-manager.js';
15
+ import { RateLimitError } from './types.js';
16
+ /**
17
+ * Check for existing Azure DevOps credentials
18
+ *
19
+ * @param projectPath - Path to project root
20
+ * @returns Existing credentials or null
21
+ */
22
+ export async function checkExistingAzureDevOpsCredentials(projectPath) {
23
+ // 1. Check project .env file
24
+ const envContent = readEnvFile(projectPath);
25
+ if (envContent) {
26
+ const parsed = parseEnvFile(envContent);
27
+ if (parsed.AZURE_DEVOPS_PAT && parsed.AZURE_DEVOPS_ORG && parsed.AZURE_DEVOPS_PROJECT) {
28
+ return {
29
+ source: '.env',
30
+ credentials: {
31
+ pat: parsed.AZURE_DEVOPS_PAT,
32
+ org: parsed.AZURE_DEVOPS_ORG,
33
+ project: parsed.AZURE_DEVOPS_PROJECT
34
+ }
35
+ };
36
+ }
37
+ }
38
+ // 2. Check environment variables
39
+ const auth = getAzureDevOpsAuth();
40
+ if (auth) {
41
+ return {
42
+ source: 'env-vars',
43
+ credentials: auth
44
+ };
45
+ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Prompt user for Azure DevOps credentials
50
+ *
51
+ * @param language - User's language
52
+ * @returns Credentials or null if skipped
53
+ */
54
+ export async function promptAzureDevOpsCredentials(language) {
55
+ const locale = getLocaleManager(language);
56
+ console.log(chalk.white('\nšŸ“‹ Azure DevOps Integration Setup\n'));
57
+ console.log(chalk.gray('SpecWeave will sync increments with Azure DevOps Work Items.\n'));
58
+ // Show setup instructions
59
+ console.log(chalk.cyan('šŸ“‹ Quick Setup:'));
60
+ console.log(chalk.gray(' 1. Go to: https://dev.azure.com/{org}/_usersSettings/tokens'));
61
+ console.log(chalk.gray(' 2. Click "New Token"'));
62
+ console.log(chalk.gray(' 3. Scopes: Work Items (Read, Write, Manage), Code (Read), Project (Read)'));
63
+ console.log(chalk.gray(' 4. Copy the token\n'));
64
+ const { continueSetup } = await inquirer.prompt([{
65
+ type: 'confirm',
66
+ name: 'continueSetup',
67
+ message: 'Continue with Azure DevOps setup?',
68
+ default: true
69
+ }]);
70
+ if (!continueSetup) {
71
+ return null;
72
+ }
73
+ // Collect credentials
74
+ const questions = [
75
+ {
76
+ type: 'input',
77
+ name: 'org',
78
+ message: 'Azure DevOps organization name:',
79
+ validate: (input) => {
80
+ if (!input || input.trim() === '') {
81
+ return 'Organization cannot be empty';
82
+ }
83
+ return true;
84
+ }
85
+ },
86
+ {
87
+ type: 'input',
88
+ name: 'project',
89
+ message: 'Project name:',
90
+ validate: (input) => {
91
+ if (!input || input.trim() === '') {
92
+ return 'Project cannot be empty';
93
+ }
94
+ return true;
95
+ }
96
+ },
97
+ {
98
+ type: 'password',
99
+ name: 'pat',
100
+ message: 'Paste your Personal Access Token:',
101
+ mask: '*',
102
+ validate: (input) => {
103
+ if (!input || input.length === 0) {
104
+ return 'Token cannot be empty';
105
+ }
106
+ // ADO PATs are typically 52 characters, but fine-grained tokens can be >= 40
107
+ if (input.length < 40) {
108
+ return 'Azure DevOps tokens should be at least 40 characters';
109
+ }
110
+ return true;
111
+ }
112
+ }
113
+ ];
114
+ const answers = await inquirer.prompt(questions);
115
+ return {
116
+ pat: answers.pat,
117
+ org: answers.org,
118
+ project: answers.project
119
+ };
120
+ }
121
+ /**
122
+ * Validate Azure DevOps connection
123
+ *
124
+ * Tests authentication and returns project information
125
+ * Handles rate limiting with retry logic
126
+ *
127
+ * @param credentials - Azure DevOps credentials
128
+ * @param maxRetries - Maximum retry attempts (default: 3)
129
+ * @returns Validation result
130
+ */
131
+ export async function validateAzureDevOpsConnection(credentials, maxRetries = 3) {
132
+ const spinner = ora('Testing connection...').start();
133
+ try {
134
+ const result = await retryWithBackoff(async () => {
135
+ // Test connection by fetching project details
136
+ const projectEndpoint = `https://dev.azure.com/${credentials.org}/_apis/projects/${credentials.project}?api-version=7.0`;
137
+ // Basic auth with PAT (username can be empty)
138
+ const auth = Buffer.from(`:${credentials.pat}`).toString('base64');
139
+ const response = await fetch(projectEndpoint, {
140
+ headers: {
141
+ 'Authorization': `Basic ${auth}`,
142
+ 'Accept': 'application/json'
143
+ }
144
+ });
145
+ // Check for rate limiting
146
+ const rateLimitInfo = checkRateLimit(response);
147
+ if (rateLimitInfo) {
148
+ throw new RateLimitError('Azure DevOps API rate limit exceeded', rateLimitInfo);
149
+ }
150
+ if (!response.ok) {
151
+ const errorText = await response.text();
152
+ let errorMessage = 'Authentication failed';
153
+ if (response.status === 401) {
154
+ errorMessage = 'Invalid Personal Access Token';
155
+ }
156
+ else if (response.status === 403) {
157
+ errorMessage = 'Access forbidden (check token scopes)';
158
+ }
159
+ else if (response.status === 404) {
160
+ errorMessage = 'Project not found (check organization and project name)';
161
+ }
162
+ else {
163
+ errorMessage = `HTTP ${response.status}: ${errorText}`;
164
+ }
165
+ throw new Error(errorMessage);
166
+ }
167
+ const project = await response.json();
168
+ return project;
169
+ }, maxRetries);
170
+ spinner.succeed(`Connected to Azure DevOps project: ${result.name}`);
171
+ return {
172
+ success: true,
173
+ username: result.name
174
+ };
175
+ }
176
+ catch (error) {
177
+ spinner.fail('Azure DevOps authentication failed');
178
+ return {
179
+ success: false,
180
+ error: error.message || 'Unknown error'
181
+ };
182
+ }
183
+ }
184
+ /**
185
+ * Get Azure DevOps environment variables for .env file
186
+ *
187
+ * @param credentials - Azure DevOps credentials
188
+ * @returns Array of key-value pairs for .env
189
+ */
190
+ export function getAzureDevOpsEnvVars(credentials) {
191
+ return [
192
+ { key: 'AZURE_DEVOPS_PAT', value: credentials.pat },
193
+ { key: 'AZURE_DEVOPS_ORG', value: credentials.org },
194
+ { key: 'AZURE_DEVOPS_PROJECT', value: credentials.project }
195
+ ];
196
+ }
197
+ /**
198
+ * Show Azure DevOps setup complete message
199
+ *
200
+ * @param language - User's language
201
+ */
202
+ export function showAzureDevOpsSetupComplete(language) {
203
+ const locale = getLocaleManager(language);
204
+ console.log(chalk.green.bold('\nāœ… Azure DevOps integration complete!\n'));
205
+ console.log(chalk.white('Available commands:'));
206
+ console.log(chalk.gray(' /specweave-ado:sync'));
207
+ console.log(chalk.gray(' /specweave-ado:status\n'));
208
+ console.log(chalk.cyan('šŸ’” Tip: Use /specweave:inc "feature" to create an increment'));
209
+ console.log(chalk.gray(' It will automatically sync to Azure DevOps Work Items!\n'));
210
+ }
211
+ /**
212
+ * Show Azure DevOps setup skipped message
213
+ *
214
+ * @param language - User's language
215
+ */
216
+ export function showAzureDevOpsSetupSkipped(language) {
217
+ const locale = getLocaleManager(language);
218
+ console.log(chalk.yellow('\nā­ļø Skipped Azure DevOps setup\n'));
219
+ console.log(chalk.white('You can configure later:'));
220
+ console.log(chalk.gray(' 1. Add AZURE_DEVOPS_PAT, AZURE_DEVOPS_ORG, AZURE_DEVOPS_PROJECT to .env'));
221
+ console.log(chalk.gray(' 2. Install plugin: /plugin install specweave-ado@specweave\n'));
222
+ }
223
+ //# sourceMappingURL=ado.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado.js","sourceRoot":"","sources":["../../../../src/cli/helpers/issue-tracker/ado.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * GitHub Integration for Issue Tracker Setup
3
+ *
4
+ * Handles GitHub.com and GitHub Enterprise authentication
5
+ * Supports manual token entry and gh CLI auto-detection
6
+ *
7
+ * @module cli/helpers/issue-tracker/github
8
+ */
9
+ import type { GitHubCredentials, ExistingCredentials, ValidationResult } from './types.js';
10
+ import type { SupportedLanguage } from '../../../core/i18n/types.js';
11
+ /**
12
+ * Check for existing GitHub credentials
13
+ *
14
+ * Priority: .env > GH_TOKEN > GITHUB_TOKEN > gh CLI config
15
+ *
16
+ * @param projectPath - Path to project root
17
+ * @returns Existing credentials or null
18
+ */
19
+ export declare function checkExistingGitHubCredentials(projectPath: string): Promise<ExistingCredentials | null>;
20
+ /**
21
+ * Prompt user for GitHub credentials
22
+ *
23
+ * Supports:
24
+ * - Manual token entry
25
+ * - gh CLI auto-detection
26
+ * - GitHub.com vs GitHub Enterprise selection
27
+ *
28
+ * @param language - User's language
29
+ * @returns Credentials or null if skipped
30
+ */
31
+ export declare function promptGitHubCredentials(language: SupportedLanguage): Promise<GitHubCredentials | null>;
32
+ /**
33
+ * Validate GitHub connection
34
+ *
35
+ * Tests authentication and returns user information
36
+ * Handles rate limiting with retry logic
37
+ *
38
+ * @param credentials - GitHub credentials
39
+ * @param maxRetries - Maximum retry attempts (default: 3)
40
+ * @returns Validation result
41
+ */
42
+ export declare function validateGitHubConnection(credentials: GitHubCredentials, maxRetries?: number): Promise<ValidationResult>;
43
+ /**
44
+ * Get GitHub environment variables for .env file
45
+ *
46
+ * @param credentials - GitHub credentials
47
+ * @returns Array of key-value pairs for .env
48
+ */
49
+ export declare function getGitHubEnvVars(credentials: GitHubCredentials): Array<{
50
+ key: string;
51
+ value: string;
52
+ }>;
53
+ /**
54
+ * Show GitHub setup complete message
55
+ *
56
+ * @param language - User's language
57
+ */
58
+ export declare function showGitHubSetupComplete(language: SupportedLanguage): void;
59
+ /**
60
+ * Show GitHub setup skipped message
61
+ *
62
+ * @param language - User's language
63
+ */
64
+ export declare function showGitHubSetupSkipped(language: SupportedLanguage): void;
65
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../../src/cli/helpers/issue-tracker/github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAOpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAIrE;;;;;;;GAOG;AACH,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA6BrC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAoInC;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,iBAAiB,EAC9B,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA2D3B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAWtG;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAWzE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAOxE"}
@@ -0,0 +1,284 @@
1
+ /**
2
+ * GitHub Integration for Issue Tracker Setup
3
+ *
4
+ * Handles GitHub.com and GitHub Enterprise authentication
5
+ * Supports manual token entry and gh CLI auto-detection
6
+ *
7
+ * @module cli/helpers/issue-tracker/github
8
+ */
9
+ import chalk from 'chalk';
10
+ import inquirer from 'inquirer';
11
+ import ora from 'ora';
12
+ import { getGitHubAuth } from '../../../utils/auth-helpers.js';
13
+ import { parseEnvFile, readEnvFile } from '../../../utils/env-file.js';
14
+ import { isGhCliAvailable, retryWithBackoff, checkRateLimit } from './utils.js';
15
+ import { getLocaleManager } from '../../../core/i18n/locale-manager.js';
16
+ import { RateLimitError } from './types.js';
17
+ /**
18
+ * Check for existing GitHub credentials
19
+ *
20
+ * Priority: .env > GH_TOKEN > GITHUB_TOKEN > gh CLI config
21
+ *
22
+ * @param projectPath - Path to project root
23
+ * @returns Existing credentials or null
24
+ */
25
+ export async function checkExistingGitHubCredentials(projectPath) {
26
+ // 1. Check project .env file
27
+ const envContent = readEnvFile(projectPath);
28
+ if (envContent) {
29
+ const parsed = parseEnvFile(envContent);
30
+ if (parsed.GH_TOKEN) {
31
+ return {
32
+ source: '.env',
33
+ credentials: {
34
+ token: parsed.GH_TOKEN,
35
+ instanceType: 'cloud' // Assume cloud unless specified
36
+ }
37
+ };
38
+ }
39
+ }
40
+ // 2. Check environment variables and gh CLI
41
+ const auth = getGitHubAuth();
42
+ if (auth.source !== 'none') {
43
+ return {
44
+ source: auth.source,
45
+ credentials: {
46
+ token: auth.token,
47
+ instanceType: 'cloud'
48
+ }
49
+ };
50
+ }
51
+ return null;
52
+ }
53
+ /**
54
+ * Prompt user for GitHub credentials
55
+ *
56
+ * Supports:
57
+ * - Manual token entry
58
+ * - gh CLI auto-detection
59
+ * - GitHub.com vs GitHub Enterprise selection
60
+ *
61
+ * @param language - User's language
62
+ * @returns Credentials or null if skipped
63
+ */
64
+ export async function promptGitHubCredentials(language) {
65
+ const locale = getLocaleManager(language);
66
+ console.log(chalk.white('\nšŸ“‹ GitHub Integration Setup\n'));
67
+ console.log(chalk.gray('SpecWeave will sync increments with GitHub Issues.\n'));
68
+ // Step 1: Ask about instance type (Cloud vs Enterprise)
69
+ const { instanceType } = await inquirer.prompt([{
70
+ type: 'list',
71
+ name: 'instanceType',
72
+ message: 'Which GitHub instance are you using?',
73
+ choices: [
74
+ { name: 'GitHub.com (cloud)', value: 'cloud' },
75
+ { name: 'GitHub Enterprise (self-hosted)', value: 'enterprise' }
76
+ ],
77
+ default: 'cloud'
78
+ }]);
79
+ let apiEndpoint;
80
+ // Step 2: If Enterprise, ask for API endpoint
81
+ if (instanceType === 'enterprise') {
82
+ console.log(chalk.gray('\nGitHub Enterprise requires a custom API endpoint.\n'));
83
+ const { endpoint } = await inquirer.prompt([{
84
+ type: 'input',
85
+ name: 'endpoint',
86
+ message: 'GitHub Enterprise API endpoint:',
87
+ default: 'https://github.company.com/api/v3',
88
+ validate: (input) => {
89
+ if (!input.startsWith('https://')) {
90
+ return 'API endpoint must use HTTPS (http:// is not secure)';
91
+ }
92
+ return true;
93
+ }
94
+ }]);
95
+ apiEndpoint = endpoint;
96
+ }
97
+ // Step 3: Show setup instructions
98
+ console.log(chalk.cyan('\nšŸ“‹ Quick Setup:'));
99
+ if (instanceType === 'cloud') {
100
+ console.log(chalk.gray(' 1. Go to: https://github.com/settings/tokens/new'));
101
+ }
102
+ else {
103
+ console.log(chalk.gray(` 1. Go to: ${apiEndpoint}/settings/tokens/new`));
104
+ }
105
+ console.log(chalk.gray(' 2. Token name: "SpecWeave - [your-project]"'));
106
+ console.log(chalk.gray(' 3. Scopes needed: ā˜‘ repo, ā˜‘ workflow'));
107
+ console.log(chalk.gray(' 4. Click "Generate token"'));
108
+ console.log(chalk.gray(' 5. Copy the token (ghp_...)\n'));
109
+ // Step 4: Check if gh CLI is available (only for GitHub.com)
110
+ const ghCliAvailable = instanceType === 'cloud' && await isGhCliAvailable();
111
+ const choices = [
112
+ { name: 'Enter token manually', value: 'manual' },
113
+ ...(ghCliAvailable ? [{ name: 'Use gh CLI (auto-detect)', value: 'gh-cli' }] : []),
114
+ { name: 'Skip for now', value: 'skip' }
115
+ ];
116
+ const { method } = await inquirer.prompt([{
117
+ type: 'list',
118
+ name: 'method',
119
+ message: 'How would you like to authenticate?',
120
+ choices
121
+ }]);
122
+ if (method === 'skip') {
123
+ return null;
124
+ }
125
+ // Step 5: Get token based on method
126
+ let token;
127
+ if (method === 'gh-cli') {
128
+ const auth = getGitHubAuth();
129
+ if (auth.source === 'gh-cli') {
130
+ console.log(chalk.green('āœ“ Found gh CLI token'));
131
+ token = auth.token;
132
+ }
133
+ else {
134
+ console.log(chalk.red('āŒ Could not detect gh CLI token'));
135
+ console.log(chalk.yellow(' Make sure you\'re logged in: gh auth login\n'));
136
+ // Fallback to manual entry
137
+ const { retryMethod } = await inquirer.prompt([{
138
+ type: 'list',
139
+ name: 'retryMethod',
140
+ message: 'What would you like to do?',
141
+ choices: [
142
+ { name: 'Enter token manually', value: 'manual' },
143
+ { name: 'Skip for now', value: 'skip' }
144
+ ]
145
+ }]);
146
+ if (retryMethod === 'skip') {
147
+ return null;
148
+ }
149
+ // Fall through to manual entry
150
+ }
151
+ }
152
+ // Manual token entry
153
+ if (method === 'manual' || !token) {
154
+ const { manualToken } = await inquirer.prompt([{
155
+ type: 'password',
156
+ name: 'manualToken',
157
+ message: 'Paste your GitHub token:',
158
+ mask: '*',
159
+ validate: (input) => {
160
+ if (!input || input.length < 20) {
161
+ return 'Invalid token format (should be at least 20 characters)';
162
+ }
163
+ // GitHub tokens start with ghp_ (classic) or github_pat_ (fine-grained)
164
+ if (instanceType === 'cloud') {
165
+ if (!input.startsWith('ghp_') && !input.startsWith('github_pat_')) {
166
+ return 'GitHub tokens typically start with "ghp_" or "github_pat_"';
167
+ }
168
+ }
169
+ return true;
170
+ }
171
+ }]);
172
+ token = manualToken;
173
+ }
174
+ return {
175
+ token,
176
+ instanceType: instanceType,
177
+ apiEndpoint
178
+ };
179
+ }
180
+ /**
181
+ * Validate GitHub connection
182
+ *
183
+ * Tests authentication and returns user information
184
+ * Handles rate limiting with retry logic
185
+ *
186
+ * @param credentials - GitHub credentials
187
+ * @param maxRetries - Maximum retry attempts (default: 3)
188
+ * @returns Validation result
189
+ */
190
+ export async function validateGitHubConnection(credentials, maxRetries = 3) {
191
+ const spinner = ora('Testing connection...').start();
192
+ try {
193
+ const result = await retryWithBackoff(async () => {
194
+ // Determine API endpoint
195
+ const apiBase = credentials.apiEndpoint || 'https://api.github.com';
196
+ const userEndpoint = `${apiBase}/user`;
197
+ const response = await fetch(userEndpoint, {
198
+ headers: {
199
+ 'Authorization': `Bearer ${credentials.token}`,
200
+ 'Accept': 'application/vnd.github+json',
201
+ 'X-GitHub-Api-Version': '2022-11-28'
202
+ }
203
+ });
204
+ // Check for rate limiting
205
+ const rateLimitInfo = checkRateLimit(response);
206
+ if (rateLimitInfo) {
207
+ throw new RateLimitError('GitHub API rate limit exceeded', rateLimitInfo);
208
+ }
209
+ if (!response.ok) {
210
+ const errorText = await response.text();
211
+ let errorMessage = 'Authentication failed';
212
+ if (response.status === 401) {
213
+ errorMessage = 'Invalid authentication credentials';
214
+ }
215
+ else if (response.status === 403) {
216
+ errorMessage = 'Access forbidden (check token scopes)';
217
+ }
218
+ else {
219
+ errorMessage = `HTTP ${response.status}: ${errorText}`;
220
+ }
221
+ throw new Error(errorMessage);
222
+ }
223
+ const user = await response.json();
224
+ return user;
225
+ }, maxRetries);
226
+ spinner.succeed(`Connected to GitHub as @${result.login}`);
227
+ return {
228
+ success: true,
229
+ username: result.login
230
+ };
231
+ }
232
+ catch (error) {
233
+ spinner.fail('GitHub authentication failed');
234
+ return {
235
+ success: false,
236
+ error: error.message || 'Unknown error'
237
+ };
238
+ }
239
+ }
240
+ /**
241
+ * Get GitHub environment variables for .env file
242
+ *
243
+ * @param credentials - GitHub credentials
244
+ * @returns Array of key-value pairs for .env
245
+ */
246
+ export function getGitHubEnvVars(credentials) {
247
+ const vars = [
248
+ { key: 'GH_TOKEN', value: credentials.token }
249
+ ];
250
+ // Add Enterprise-specific variables
251
+ if (credentials.instanceType === 'enterprise' && credentials.apiEndpoint) {
252
+ vars.push({ key: 'GITHUB_API_URL', value: credentials.apiEndpoint });
253
+ }
254
+ return vars;
255
+ }
256
+ /**
257
+ * Show GitHub setup complete message
258
+ *
259
+ * @param language - User's language
260
+ */
261
+ export function showGitHubSetupComplete(language) {
262
+ const locale = getLocaleManager(language);
263
+ console.log(chalk.green.bold('\nāœ… GitHub integration complete!\n'));
264
+ console.log(chalk.white('Available commands:'));
265
+ console.log(chalk.gray(' /specweave-github:create-issue'));
266
+ console.log(chalk.gray(' /specweave-github:sync'));
267
+ console.log(chalk.gray(' /specweave-github:close-issue'));
268
+ console.log(chalk.gray(' /specweave-github:status\n'));
269
+ console.log(chalk.cyan('šŸ’” Tip: Use /specweave:inc "feature" to create an increment'));
270
+ console.log(chalk.gray(' It will automatically sync to GitHub Issues!\n'));
271
+ }
272
+ /**
273
+ * Show GitHub setup skipped message
274
+ *
275
+ * @param language - User's language
276
+ */
277
+ export function showGitHubSetupSkipped(language) {
278
+ const locale = getLocaleManager(language);
279
+ console.log(chalk.yellow('\nā­ļø Skipped GitHub setup\n'));
280
+ console.log(chalk.white('You can configure later:'));
281
+ console.log(chalk.gray(' 1. Add GH_TOKEN to .env file'));
282
+ console.log(chalk.gray(' 2. Install plugin: /plugin install specweave-github@specweave\n'));
283
+ }
284
+ //# sourceMappingURL=github.js.map