gmc-openspec 1.0.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 (333) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +207 -0
  3. package/bin/openspec.js +3 -0
  4. package/dist/cli/index.d.ts +2 -0
  5. package/dist/cli/index.js +494 -0
  6. package/dist/commands/change.d.ts +35 -0
  7. package/dist/commands/change.js +277 -0
  8. package/dist/commands/completion.d.ts +72 -0
  9. package/dist/commands/completion.js +264 -0
  10. package/dist/commands/config.d.ts +36 -0
  11. package/dist/commands/config.js +611 -0
  12. package/dist/commands/feedback.d.ts +9 -0
  13. package/dist/commands/feedback.js +183 -0
  14. package/dist/commands/jira.d.ts +3 -0
  15. package/dist/commands/jira.js +249 -0
  16. package/dist/commands/schema.d.ts +6 -0
  17. package/dist/commands/schema.js +869 -0
  18. package/dist/commands/show.d.ts +14 -0
  19. package/dist/commands/show.js +132 -0
  20. package/dist/commands/spec.d.ts +15 -0
  21. package/dist/commands/spec.js +225 -0
  22. package/dist/commands/validate.d.ts +24 -0
  23. package/dist/commands/validate.js +294 -0
  24. package/dist/commands/workflow/index.d.ts +17 -0
  25. package/dist/commands/workflow/index.js +12 -0
  26. package/dist/commands/workflow/instructions.d.ts +29 -0
  27. package/dist/commands/workflow/instructions.js +336 -0
  28. package/dist/commands/workflow/new-change.d.ts +13 -0
  29. package/dist/commands/workflow/new-change.js +92 -0
  30. package/dist/commands/workflow/schemas.d.ts +10 -0
  31. package/dist/commands/workflow/schemas.js +34 -0
  32. package/dist/commands/workflow/shared.d.ts +57 -0
  33. package/dist/commands/workflow/shared.js +116 -0
  34. package/dist/commands/workflow/status.d.ts +14 -0
  35. package/dist/commands/workflow/status.js +87 -0
  36. package/dist/commands/workflow/templates.d.ts +16 -0
  37. package/dist/commands/workflow/templates.js +69 -0
  38. package/dist/commands/workspace/open.d.ts +29 -0
  39. package/dist/commands/workspace/open.js +84 -0
  40. package/dist/commands/workspace/operations.d.ts +23 -0
  41. package/dist/commands/workspace/operations.js +475 -0
  42. package/dist/commands/workspace/selection.d.ts +6 -0
  43. package/dist/commands/workspace/selection.js +113 -0
  44. package/dist/commands/workspace/types.d.ts +88 -0
  45. package/dist/commands/workspace/types.js +36 -0
  46. package/dist/commands/workspace.d.ts +6 -0
  47. package/dist/commands/workspace.js +868 -0
  48. package/dist/core/archive.d.ts +11 -0
  49. package/dist/core/archive.js +318 -0
  50. package/dist/core/artifact-graph/graph.d.ts +56 -0
  51. package/dist/core/artifact-graph/graph.js +141 -0
  52. package/dist/core/artifact-graph/index.d.ts +8 -0
  53. package/dist/core/artifact-graph/index.js +14 -0
  54. package/dist/core/artifact-graph/instruction-loader.d.ts +196 -0
  55. package/dist/core/artifact-graph/instruction-loader.js +317 -0
  56. package/dist/core/artifact-graph/outputs.d.ts +14 -0
  57. package/dist/core/artifact-graph/outputs.js +39 -0
  58. package/dist/core/artifact-graph/resolver.d.ts +81 -0
  59. package/dist/core/artifact-graph/resolver.js +257 -0
  60. package/dist/core/artifact-graph/schema.d.ts +13 -0
  61. package/dist/core/artifact-graph/schema.js +108 -0
  62. package/dist/core/artifact-graph/state.d.ts +12 -0
  63. package/dist/core/artifact-graph/state.js +31 -0
  64. package/dist/core/artifact-graph/types.d.ts +47 -0
  65. package/dist/core/artifact-graph/types.js +48 -0
  66. package/dist/core/available-tools.d.ts +17 -0
  67. package/dist/core/available-tools.js +43 -0
  68. package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
  69. package/dist/core/command-generation/adapters/amazon-q.js +26 -0
  70. package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
  71. package/dist/core/command-generation/adapters/antigravity.js +26 -0
  72. package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
  73. package/dist/core/command-generation/adapters/auggie.js +27 -0
  74. package/dist/core/command-generation/adapters/bob.d.ts +14 -0
  75. package/dist/core/command-generation/adapters/bob.js +45 -0
  76. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  77. package/dist/core/command-generation/adapters/claude.js +50 -0
  78. package/dist/core/command-generation/adapters/cline.d.ts +14 -0
  79. package/dist/core/command-generation/adapters/cline.js +27 -0
  80. package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
  81. package/dist/core/command-generation/adapters/codebuddy.js +28 -0
  82. package/dist/core/command-generation/adapters/codex.d.ts +16 -0
  83. package/dist/core/command-generation/adapters/codex.js +39 -0
  84. package/dist/core/command-generation/adapters/continue.d.ts +13 -0
  85. package/dist/core/command-generation/adapters/continue.js +28 -0
  86. package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
  87. package/dist/core/command-generation/adapters/costrict.js +27 -0
  88. package/dist/core/command-generation/adapters/crush.d.ts +13 -0
  89. package/dist/core/command-generation/adapters/crush.js +30 -0
  90. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  91. package/dist/core/command-generation/adapters/cursor.js +44 -0
  92. package/dist/core/command-generation/adapters/factory.d.ts +13 -0
  93. package/dist/core/command-generation/adapters/factory.js +27 -0
  94. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  95. package/dist/core/command-generation/adapters/gemini.js +26 -0
  96. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  97. package/dist/core/command-generation/adapters/github-copilot.js +26 -0
  98. package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
  99. package/dist/core/command-generation/adapters/iflow.js +29 -0
  100. package/dist/core/command-generation/adapters/index.d.ts +32 -0
  101. package/dist/core/command-generation/adapters/index.js +32 -0
  102. package/dist/core/command-generation/adapters/junie.d.ts +13 -0
  103. package/dist/core/command-generation/adapters/junie.js +26 -0
  104. package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
  105. package/dist/core/command-generation/adapters/kilocode.js +23 -0
  106. package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
  107. package/dist/core/command-generation/adapters/kiro.js +26 -0
  108. package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
  109. package/dist/core/command-generation/adapters/lingma.js +30 -0
  110. package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
  111. package/dist/core/command-generation/adapters/opencode.js +29 -0
  112. package/dist/core/command-generation/adapters/pi.d.ts +18 -0
  113. package/dist/core/command-generation/adapters/pi.js +55 -0
  114. package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
  115. package/dist/core/command-generation/adapters/qoder.js +30 -0
  116. package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
  117. package/dist/core/command-generation/adapters/qwen.js +26 -0
  118. package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
  119. package/dist/core/command-generation/adapters/roocode.js +27 -0
  120. package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
  121. package/dist/core/command-generation/adapters/windsurf.js +51 -0
  122. package/dist/core/command-generation/generator.d.ts +21 -0
  123. package/dist/core/command-generation/generator.js +27 -0
  124. package/dist/core/command-generation/index.d.ts +22 -0
  125. package/dist/core/command-generation/index.js +24 -0
  126. package/dist/core/command-generation/registry.d.ts +36 -0
  127. package/dist/core/command-generation/registry.js +98 -0
  128. package/dist/core/command-generation/types.d.ts +56 -0
  129. package/dist/core/command-generation/types.js +8 -0
  130. package/dist/core/completions/command-registry.d.ts +7 -0
  131. package/dist/core/completions/command-registry.js +626 -0
  132. package/dist/core/completions/completion-provider.d.ts +71 -0
  133. package/dist/core/completions/completion-provider.js +129 -0
  134. package/dist/core/completions/factory.d.ts +64 -0
  135. package/dist/core/completions/factory.js +75 -0
  136. package/dist/core/completions/generators/bash-generator.d.ts +35 -0
  137. package/dist/core/completions/generators/bash-generator.js +230 -0
  138. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  139. package/dist/core/completions/generators/fish-generator.js +160 -0
  140. package/dist/core/completions/generators/powershell-generator.d.ts +36 -0
  141. package/dist/core/completions/generators/powershell-generator.js +266 -0
  142. package/dist/core/completions/generators/zsh-generator.d.ts +47 -0
  143. package/dist/core/completions/generators/zsh-generator.js +274 -0
  144. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  145. package/dist/core/completions/installers/bash-installer.js +318 -0
  146. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  147. package/dist/core/completions/installers/fish-installer.js +143 -0
  148. package/dist/core/completions/installers/powershell-installer.d.ts +102 -0
  149. package/dist/core/completions/installers/powershell-installer.js +387 -0
  150. package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
  151. package/dist/core/completions/installers/zsh-installer.js +421 -0
  152. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  153. package/dist/core/completions/templates/bash-templates.js +30 -0
  154. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  155. package/dist/core/completions/templates/fish-templates.js +45 -0
  156. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  157. package/dist/core/completions/templates/powershell-templates.js +34 -0
  158. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  159. package/dist/core/completions/templates/zsh-templates.js +45 -0
  160. package/dist/core/completions/types.d.ts +101 -0
  161. package/dist/core/completions/types.js +2 -0
  162. package/dist/core/config-prompts.d.ts +9 -0
  163. package/dist/core/config-prompts.js +34 -0
  164. package/dist/core/config-schema.d.ts +86 -0
  165. package/dist/core/config-schema.js +213 -0
  166. package/dist/core/config.d.ts +18 -0
  167. package/dist/core/config.js +38 -0
  168. package/dist/core/converters/json-converter.d.ts +6 -0
  169. package/dist/core/converters/json-converter.js +51 -0
  170. package/dist/core/global-config.d.ts +49 -0
  171. package/dist/core/global-config.js +124 -0
  172. package/dist/core/index.d.ts +5 -0
  173. package/dist/core/index.js +6 -0
  174. package/dist/core/init.d.ts +37 -0
  175. package/dist/core/init.js +593 -0
  176. package/dist/core/jira/config.d.ts +35 -0
  177. package/dist/core/jira/config.js +151 -0
  178. package/dist/core/jira/constants.d.ts +20 -0
  179. package/dist/core/jira/constants.js +49 -0
  180. package/dist/core/jira/doctor.d.ts +19 -0
  181. package/dist/core/jira/doctor.js +173 -0
  182. package/dist/core/jira/hash.d.ts +3 -0
  183. package/dist/core/jira/hash.js +9 -0
  184. package/dist/core/jira/index.d.ts +11 -0
  185. package/dist/core/jira/index.js +11 -0
  186. package/dist/core/jira/intake.d.ts +40 -0
  187. package/dist/core/jira/intake.js +54 -0
  188. package/dist/core/jira/mcp-config.d.ts +13 -0
  189. package/dist/core/jira/mcp-config.js +259 -0
  190. package/dist/core/jira/paths.d.ts +12 -0
  191. package/dist/core/jira/paths.js +66 -0
  192. package/dist/core/jira/setup.d.ts +30 -0
  193. package/dist/core/jira/setup.js +99 -0
  194. package/dist/core/jira/templates.d.ts +12 -0
  195. package/dist/core/jira/templates.js +204 -0
  196. package/dist/core/jira/validation.d.ts +17 -0
  197. package/dist/core/jira/validation.js +341 -0
  198. package/dist/core/legacy-cleanup.d.ts +162 -0
  199. package/dist/core/legacy-cleanup.js +514 -0
  200. package/dist/core/list.d.ts +9 -0
  201. package/dist/core/list.js +171 -0
  202. package/dist/core/migration.d.ts +23 -0
  203. package/dist/core/migration.js +108 -0
  204. package/dist/core/parsers/change-parser.d.ts +13 -0
  205. package/dist/core/parsers/change-parser.js +197 -0
  206. package/dist/core/parsers/markdown-parser.d.ts +26 -0
  207. package/dist/core/parsers/markdown-parser.js +227 -0
  208. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  209. package/dist/core/parsers/requirement-blocks.js +201 -0
  210. package/dist/core/parsers/spec-structure.d.ts +9 -0
  211. package/dist/core/parsers/spec-structure.js +88 -0
  212. package/dist/core/planning-home.d.ts +21 -0
  213. package/dist/core/planning-home.js +124 -0
  214. package/dist/core/profile-sync-drift.d.ts +38 -0
  215. package/dist/core/profile-sync-drift.js +200 -0
  216. package/dist/core/profiles.d.ts +26 -0
  217. package/dist/core/profiles.js +40 -0
  218. package/dist/core/project-config.d.ts +64 -0
  219. package/dist/core/project-config.js +223 -0
  220. package/dist/core/schemas/base.schema.d.ts +13 -0
  221. package/dist/core/schemas/base.schema.js +13 -0
  222. package/dist/core/schemas/change.schema.d.ts +73 -0
  223. package/dist/core/schemas/change.schema.js +31 -0
  224. package/dist/core/schemas/index.d.ts +4 -0
  225. package/dist/core/schemas/index.js +4 -0
  226. package/dist/core/schemas/spec.schema.d.ts +18 -0
  227. package/dist/core/schemas/spec.schema.js +15 -0
  228. package/dist/core/shared/index.d.ts +8 -0
  229. package/dist/core/shared/index.js +8 -0
  230. package/dist/core/shared/skill-generation.d.ts +49 -0
  231. package/dist/core/shared/skill-generation.js +96 -0
  232. package/dist/core/shared/tool-detection.d.ts +71 -0
  233. package/dist/core/shared/tool-detection.js +158 -0
  234. package/dist/core/specs-apply.d.ts +73 -0
  235. package/dist/core/specs-apply.js +392 -0
  236. package/dist/core/styles/palette.d.ts +7 -0
  237. package/dist/core/styles/palette.js +8 -0
  238. package/dist/core/templates/index.d.ts +8 -0
  239. package/dist/core/templates/index.js +9 -0
  240. package/dist/core/templates/skill-templates.d.ts +19 -0
  241. package/dist/core/templates/skill-templates.js +18 -0
  242. package/dist/core/templates/types.d.ts +19 -0
  243. package/dist/core/templates/types.js +5 -0
  244. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  245. package/dist/core/templates/workflows/apply-change.js +314 -0
  246. package/dist/core/templates/workflows/archive-change.d.ts +10 -0
  247. package/dist/core/templates/workflows/archive-change.js +277 -0
  248. package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
  249. package/dist/core/templates/workflows/bulk-archive-change.js +492 -0
  250. package/dist/core/templates/workflows/continue-change.d.ts +10 -0
  251. package/dist/core/templates/workflows/continue-change.js +234 -0
  252. package/dist/core/templates/workflows/explore.d.ts +10 -0
  253. package/dist/core/templates/workflows/explore.js +459 -0
  254. package/dist/core/templates/workflows/feedback.d.ts +9 -0
  255. package/dist/core/templates/workflows/feedback.js +108 -0
  256. package/dist/core/templates/workflows/ff-change.d.ts +10 -0
  257. package/dist/core/templates/workflows/ff-change.js +200 -0
  258. package/dist/core/templates/workflows/new-change.d.ts +10 -0
  259. package/dist/core/templates/workflows/new-change.js +143 -0
  260. package/dist/core/templates/workflows/onboard.d.ts +10 -0
  261. package/dist/core/templates/workflows/onboard.js +563 -0
  262. package/dist/core/templates/workflows/propose.d.ts +10 -0
  263. package/dist/core/templates/workflows/propose.js +218 -0
  264. package/dist/core/templates/workflows/sync-specs.d.ts +10 -0
  265. package/dist/core/templates/workflows/sync-specs.js +290 -0
  266. package/dist/core/templates/workflows/verify-change.d.ts +10 -0
  267. package/dist/core/templates/workflows/verify-change.js +338 -0
  268. package/dist/core/update.d.ts +83 -0
  269. package/dist/core/update.js +573 -0
  270. package/dist/core/validation/constants.d.ts +34 -0
  271. package/dist/core/validation/constants.js +40 -0
  272. package/dist/core/validation/types.d.ts +18 -0
  273. package/dist/core/validation/types.js +2 -0
  274. package/dist/core/validation/validator.d.ts +33 -0
  275. package/dist/core/validation/validator.js +418 -0
  276. package/dist/core/view.d.ts +8 -0
  277. package/dist/core/view.js +168 -0
  278. package/dist/core/workspace/foundation.d.ts +87 -0
  279. package/dist/core/workspace/foundation.js +379 -0
  280. package/dist/core/workspace/index.d.ts +6 -0
  281. package/dist/core/workspace/index.js +6 -0
  282. package/dist/core/workspace/link-input.d.ts +9 -0
  283. package/dist/core/workspace/link-input.js +32 -0
  284. package/dist/core/workspace/open-surface.d.ts +24 -0
  285. package/dist/core/workspace/open-surface.js +137 -0
  286. package/dist/core/workspace/openers.d.ts +21 -0
  287. package/dist/core/workspace/openers.js +119 -0
  288. package/dist/core/workspace/skills.d.ts +55 -0
  289. package/dist/core/workspace/skills.js +334 -0
  290. package/dist/index.d.ts +3 -0
  291. package/dist/index.js +3 -0
  292. package/dist/prompts/searchable-multi-select.d.ts +28 -0
  293. package/dist/prompts/searchable-multi-select.js +159 -0
  294. package/dist/telemetry/config.d.ts +38 -0
  295. package/dist/telemetry/config.js +136 -0
  296. package/dist/telemetry/index.d.ts +31 -0
  297. package/dist/telemetry/index.js +164 -0
  298. package/dist/ui/ascii-patterns.d.ts +16 -0
  299. package/dist/ui/ascii-patterns.js +133 -0
  300. package/dist/ui/welcome-screen.d.ts +10 -0
  301. package/dist/ui/welcome-screen.js +146 -0
  302. package/dist/utils/change-metadata.d.ts +51 -0
  303. package/dist/utils/change-metadata.js +147 -0
  304. package/dist/utils/change-utils.d.ts +71 -0
  305. package/dist/utils/change-utils.js +123 -0
  306. package/dist/utils/command-references.d.ts +18 -0
  307. package/dist/utils/command-references.js +20 -0
  308. package/dist/utils/file-system.d.ts +41 -0
  309. package/dist/utils/file-system.js +301 -0
  310. package/dist/utils/index.d.ts +6 -0
  311. package/dist/utils/index.js +9 -0
  312. package/dist/utils/interactive.d.ts +18 -0
  313. package/dist/utils/interactive.js +21 -0
  314. package/dist/utils/item-discovery.d.ts +4 -0
  315. package/dist/utils/item-discovery.js +72 -0
  316. package/dist/utils/match.d.ts +3 -0
  317. package/dist/utils/match.js +22 -0
  318. package/dist/utils/shell-detection.d.ts +20 -0
  319. package/dist/utils/shell-detection.js +41 -0
  320. package/dist/utils/task-progress.d.ts +8 -0
  321. package/dist/utils/task-progress.js +36 -0
  322. package/package.json +79 -0
  323. package/schemas/spec-driven/schema.yaml +153 -0
  324. package/schemas/spec-driven/templates/design.md +19 -0
  325. package/schemas/spec-driven/templates/proposal.md +23 -0
  326. package/schemas/spec-driven/templates/spec.md +8 -0
  327. package/schemas/spec-driven/templates/tasks.md +9 -0
  328. package/schemas/workspace-planning/schema.yaml +72 -0
  329. package/schemas/workspace-planning/templates/design.md +33 -0
  330. package/schemas/workspace-planning/templates/proposal.md +28 -0
  331. package/schemas/workspace-planning/templates/spec.md +9 -0
  332. package/schemas/workspace-planning/templates/tasks.md +15 -0
  333. package/scripts/postinstall.js +83 -0
@@ -0,0 +1,183 @@
1
+ import { execSync, execFileSync } from 'child_process';
2
+ import { createRequire } from 'module';
3
+ import os from 'os';
4
+ const require = createRequire(import.meta.url);
5
+ /**
6
+ * Check if gh CLI is installed and available in PATH
7
+ * Uses platform-appropriate command: 'where' on Windows, 'which' on Unix/macOS
8
+ */
9
+ function isGhInstalled() {
10
+ try {
11
+ const command = process.platform === 'win32' ? 'where gh' : 'which gh';
12
+ execSync(command, { stdio: 'pipe' });
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ /**
20
+ * Check if gh CLI is authenticated
21
+ */
22
+ function isGhAuthenticated() {
23
+ try {
24
+ execSync('gh auth status', { stdio: 'pipe' });
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ /**
32
+ * Get OpenSpec version from package.json
33
+ */
34
+ function getVersion() {
35
+ try {
36
+ const { version } = require('../../package.json');
37
+ return version;
38
+ }
39
+ catch {
40
+ return 'unknown';
41
+ }
42
+ }
43
+ /**
44
+ * Get platform name
45
+ */
46
+ function getPlatform() {
47
+ return os.platform();
48
+ }
49
+ /**
50
+ * Get current timestamp in ISO format
51
+ */
52
+ function getTimestamp() {
53
+ return new Date().toISOString();
54
+ }
55
+ /**
56
+ * Generate metadata footer for feedback
57
+ */
58
+ function generateMetadata() {
59
+ const version = getVersion();
60
+ const platform = getPlatform();
61
+ const timestamp = getTimestamp();
62
+ return `---
63
+ Submitted via OpenSpec CLI
64
+ - Version: ${version}
65
+ - Platform: ${platform}
66
+ - Timestamp: ${timestamp}`;
67
+ }
68
+ /**
69
+ * Format the feedback title
70
+ */
71
+ function formatTitle(message) {
72
+ return `Feedback: ${message}`;
73
+ }
74
+ /**
75
+ * Format the full feedback body
76
+ */
77
+ function formatBody(bodyText) {
78
+ const parts = [];
79
+ if (bodyText) {
80
+ parts.push(bodyText);
81
+ parts.push(''); // Empty line before metadata
82
+ }
83
+ parts.push(generateMetadata());
84
+ return parts.join('\n');
85
+ }
86
+ /**
87
+ * Generate a pre-filled GitHub issue URL for manual submission
88
+ */
89
+ function generateManualSubmissionUrl(title, body) {
90
+ const repo = 'Fission-AI/OpenSpec';
91
+ const encodedTitle = encodeURIComponent(title);
92
+ const encodedBody = encodeURIComponent(body);
93
+ const encodedLabels = encodeURIComponent('feedback');
94
+ return `https://github.com/${repo}/issues/new?title=${encodedTitle}&body=${encodedBody}&labels=${encodedLabels}`;
95
+ }
96
+ /**
97
+ * Display formatted feedback content for manual submission
98
+ */
99
+ function displayFormattedFeedback(title, body) {
100
+ console.log('\n--- FORMATTED FEEDBACK ---');
101
+ console.log(`Title: ${title}`);
102
+ console.log(`Labels: feedback`);
103
+ console.log('\nBody:');
104
+ console.log(body);
105
+ console.log('--- END FEEDBACK ---\n');
106
+ }
107
+ /**
108
+ * Submit feedback via gh CLI
109
+ * Uses execFileSync to prevent shell injection vulnerabilities
110
+ */
111
+ function submitViaGhCli(title, body) {
112
+ try {
113
+ const result = execFileSync('gh', [
114
+ 'issue',
115
+ 'create',
116
+ '--repo',
117
+ 'Fission-AI/OpenSpec',
118
+ '--title',
119
+ title,
120
+ '--body',
121
+ body,
122
+ '--label',
123
+ 'feedback',
124
+ ], { encoding: 'utf-8', stdio: 'pipe' });
125
+ const issueUrl = result.trim();
126
+ console.log(`\n✓ Feedback submitted successfully!`);
127
+ console.log(`Issue URL: ${issueUrl}\n`);
128
+ }
129
+ catch (error) {
130
+ // Display the error output from gh CLI
131
+ if (error.stderr) {
132
+ console.error(error.stderr.toString());
133
+ }
134
+ else if (error.message) {
135
+ console.error(error.message);
136
+ }
137
+ // Exit with the same code as gh CLI
138
+ process.exit(error.status ?? 1);
139
+ }
140
+ }
141
+ /**
142
+ * Handle fallback when gh CLI is not available or not authenticated
143
+ */
144
+ function handleFallback(title, body, reason) {
145
+ if (reason === 'missing') {
146
+ console.log('⚠️ GitHub CLI not found. Manual submission required.');
147
+ }
148
+ else {
149
+ console.log('⚠️ GitHub authentication required. Manual submission required.');
150
+ }
151
+ displayFormattedFeedback(title, body);
152
+ const manualUrl = generateManualSubmissionUrl(title, body);
153
+ console.log('Please submit your feedback manually:');
154
+ console.log(manualUrl);
155
+ if (reason === 'unauthenticated') {
156
+ console.log('\nTo auto-submit in the future: gh auth login');
157
+ }
158
+ // Exit with success code (fallback is successful)
159
+ process.exit(0);
160
+ }
161
+ /**
162
+ * Feedback command implementation
163
+ */
164
+ export class FeedbackCommand {
165
+ async execute(message, options) {
166
+ // Format title and body once for all code paths
167
+ const title = formatTitle(message);
168
+ const body = formatBody(options?.body);
169
+ // Check if gh CLI is installed
170
+ if (!isGhInstalled()) {
171
+ handleFallback(title, body, 'missing');
172
+ return;
173
+ }
174
+ // Check if gh CLI is authenticated
175
+ if (!isGhAuthenticated()) {
176
+ handleFallback(title, body, 'unauthenticated');
177
+ return;
178
+ }
179
+ // Submit via gh CLI
180
+ submitViaGhCli(title, body);
181
+ }
182
+ }
183
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerJiraCommand(program: Command): void;
3
+ //# sourceMappingURL=jira.d.ts.map
@@ -0,0 +1,249 @@
1
+ import { createRequire } from 'module';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { getGlobalConfig } from '../core/global-config.js';
6
+ import { getAllowedNext, readJiraIntake, runJiraDoctor, setupJiraIntegration, validateJiraId, validateJiraIntake, } from '../core/jira/index.js';
7
+ const require = createRequire(import.meta.url);
8
+ const { version: OPENSPEC_VERSION } = require('../../package.json');
9
+ const VALID_STAGES = new Set(['source', 'requirement', 'stories', 'propose']);
10
+ export function registerJiraCommand(program) {
11
+ const jiraCmd = program
12
+ .command('jira')
13
+ .description('Manage Jira intake setup, validation, and status');
14
+ jiraCmd
15
+ .command('setup [path]')
16
+ .description('Set up Jira intake configuration and AI workflow artifacts')
17
+ .option('--tools <tools>', 'AI tools to configure: all, none, detected, or comma-separated tool IDs', 'detected')
18
+ .option('--provider <provider>', 'Jira provider (V1 supports atlassian-rovo)', 'atlassian-rovo')
19
+ .option('--endpoint <url>', 'Atlassian MCP endpoint')
20
+ .option('--force', 'Overwrite existing Jira setup files when needed')
21
+ .option('--json', 'Output setup result as JSON')
22
+ .action(async (targetPath = '.', options) => {
23
+ const spinner = options?.json ? undefined : ora('Setting up Jira intake...').start();
24
+ try {
25
+ const projectRoot = path.resolve(targetPath);
26
+ const globalConfig = getGlobalConfig();
27
+ const result = await setupJiraIntegration(projectRoot, {
28
+ tools: options?.tools,
29
+ provider: options?.provider,
30
+ endpoint: options?.endpoint,
31
+ force: options?.force,
32
+ delivery: globalConfig.delivery ?? 'both',
33
+ generatedByVersion: OPENSPEC_VERSION,
34
+ });
35
+ spinner?.succeed('Jira intake setup complete');
36
+ if (options?.json) {
37
+ console.log(JSON.stringify(result, null, 2));
38
+ }
39
+ else {
40
+ printSetupResult(result);
41
+ }
42
+ }
43
+ catch (error) {
44
+ spinner?.fail('Jira intake setup failed');
45
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
46
+ process.exitCode = 1;
47
+ }
48
+ });
49
+ jiraCmd
50
+ .command('doctor [path]')
51
+ .description('Check Jira intake configuration and local MCP prerequisites')
52
+ .option('--json', 'Output doctor report as JSON')
53
+ .action((targetPath = '.', options) => {
54
+ try {
55
+ const projectRoot = path.resolve(targetPath);
56
+ const report = runJiraDoctor(projectRoot);
57
+ if (options?.json) {
58
+ console.log(JSON.stringify(report, null, 2));
59
+ }
60
+ else {
61
+ printDoctorReport(report);
62
+ }
63
+ if (!report.ok)
64
+ process.exitCode = 1;
65
+ }
66
+ catch (error) {
67
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
68
+ process.exitCode = 1;
69
+ }
70
+ });
71
+ jiraCmd
72
+ .command('validate <jira-id>')
73
+ .description('Validate a Jira intake folder before moving to the next stage')
74
+ .option('--stage <stage>', 'Validation stage: source, requirement, stories, propose', 'source')
75
+ .option('--json', 'Output validation report as JSON')
76
+ .action((jiraId, options) => {
77
+ try {
78
+ const stage = normalizeStage(options?.stage);
79
+ const report = validateJiraIntake(process.cwd(), jiraId, stage);
80
+ if (options?.json) {
81
+ console.log(JSON.stringify(report, null, 2));
82
+ }
83
+ else {
84
+ printValidationReport(report);
85
+ }
86
+ if (!report.ok)
87
+ process.exitCode = 1;
88
+ }
89
+ catch (error) {
90
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
91
+ process.exitCode = 1;
92
+ }
93
+ });
94
+ jiraCmd
95
+ .command('status <jira-id>')
96
+ .description('Show Jira intake status and allowed next states')
97
+ .option('--json', 'Output status as JSON')
98
+ .action((jiraId, options) => {
99
+ try {
100
+ const idValidation = validateJiraId(jiraId);
101
+ if (!idValidation.valid) {
102
+ throw new Error(idValidation.error);
103
+ }
104
+ const intakeResult = readJiraIntake(process.cwd(), jiraId);
105
+ const status = intakeResult.intake?.status;
106
+ const blockingStage = status ? getStatusBlockingStage(status) : undefined;
107
+ const blockingValidation = blockingStage ? validateJiraIntake(process.cwd(), jiraId, blockingStage) : undefined;
108
+ const result = {
109
+ ok: intakeResult.intake != null,
110
+ jira: jiraId.toUpperCase(),
111
+ issueDir: intakeResult.issueDir,
112
+ intakePath: intakeResult.path,
113
+ status,
114
+ allowedNext: status ? getAllowedNext(status) : [],
115
+ nextCommands: status ? getNextCommands(status, jiraId.toUpperCase()) : [],
116
+ blockingStage,
117
+ blockingItems: blockingValidation?.errors ?? [],
118
+ warnings: intakeResult.warnings,
119
+ };
120
+ if (options?.json) {
121
+ console.log(JSON.stringify(result, null, 2));
122
+ }
123
+ else {
124
+ printStatusResult(result);
125
+ }
126
+ if (!result.ok)
127
+ process.exitCode = 1;
128
+ }
129
+ catch (error) {
130
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
131
+ process.exitCode = 1;
132
+ }
133
+ });
134
+ }
135
+ function normalizeStage(stage) {
136
+ const normalized = stage ?? 'source';
137
+ if (!VALID_STAGES.has(normalized)) {
138
+ throw new Error(`Invalid stage "${normalized}". Expected one of: ${[...VALID_STAGES].join(', ')}`);
139
+ }
140
+ return normalized;
141
+ }
142
+ function printSetupResult(result) {
143
+ console.log();
144
+ console.log(chalk.bold('Jira Intake Setup'));
145
+ console.log(`Config: ${result.configPath}`);
146
+ console.log(`Provider: ${result.config.provider}`);
147
+ console.log(`Endpoint: ${result.config.endpoint}`);
148
+ console.log(`Tools: ${result.tools.length > 0 ? result.tools.join(', ') : 'none'}`);
149
+ console.log(`Artifacts: ${result.skillsWritten} skills, ${result.commandsWritten} commands`);
150
+ printMcpConfigResults(result.mcpConfigResults);
151
+ if (result.commandsSkipped.length > 0) {
152
+ console.log(chalk.dim(`Commands skipped for: ${result.commandsSkipped.join(', ')} (no adapter)`));
153
+ }
154
+ console.log();
155
+ console.log(chalk.bold('MCP snippet'));
156
+ console.log(result.tools.length > 0 ? Object.values(result.snippets)[0] : 'Configure your AI client with an Atlassian MCP server before importing Jira tickets.');
157
+ console.log();
158
+ console.log('Next: restart your AI client, then run /opsx:jira-import ABC-123.');
159
+ }
160
+ function printMcpConfigResults(results) {
161
+ if (results.length === 0) {
162
+ return;
163
+ }
164
+ const summary = results.map((result) => `${result.toolId}: ${result.status}`).join(', ');
165
+ console.log(`MCP configs: ${summary}`);
166
+ for (const result of results) {
167
+ if (result.status === 'unsupported' || result.status === 'invalid-json') {
168
+ console.log(chalk.yellow(`MCP ${result.toolId}: ${result.message}`));
169
+ }
170
+ }
171
+ }
172
+ function printDoctorReport(report) {
173
+ console.log(chalk.bold('Jira Intake Doctor'));
174
+ for (const check of report.checks) {
175
+ const symbol = check.level === 'ok' ? chalk.green('✓') : check.level === 'error' ? chalk.red('✗') : chalk.yellow('!');
176
+ console.log(`${symbol} ${check.message}`);
177
+ if (check.details) {
178
+ console.log(chalk.dim(check.details));
179
+ }
180
+ }
181
+ console.log();
182
+ console.log(chalk.bold('AI client test prompt'));
183
+ console.log(report.testPrompt);
184
+ }
185
+ function printValidationReport(report) {
186
+ const status = report.ok ? chalk.green('valid') : chalk.red('invalid');
187
+ console.log(`Jira intake ${report.jira} (${report.stage}): ${status}`);
188
+ console.log(`Folder: ${report.issueDir}`);
189
+ if (report.status)
190
+ console.log(`Status: ${report.status}`);
191
+ for (const warning of report.warnings) {
192
+ console.log(chalk.yellow(`Warning [${warning.code}]: ${warning.message}${warning.file ? ` (${warning.file})` : ''}`));
193
+ }
194
+ for (const error of report.errors) {
195
+ console.log(chalk.red(`Error [${error.code}]: ${error.message}${error.file ? ` (${error.file})` : ''}`));
196
+ }
197
+ }
198
+ function printStatusResult(result) {
199
+ if (!result.ok) {
200
+ console.log(chalk.red(`No Jira intake found for ${result.jira}. Run /opsx:jira-import ${result.jira} first.`));
201
+ console.log(chalk.dim(`Expected: ${result.intakePath}`));
202
+ return;
203
+ }
204
+ console.log(chalk.bold(`Jira Intake ${result.jira}`));
205
+ console.log(`Status: ${result.status}`);
206
+ console.log(`Folder: ${result.issueDir}`);
207
+ console.log(`Allowed next: ${result.allowedNext.length > 0 ? result.allowedNext.join(', ') : 'none'}`);
208
+ const richResult = result;
209
+ console.log(`Next commands: ${richResult.nextCommands && richResult.nextCommands.length > 0 ? richResult.nextCommands.join(', ') : 'none'}`);
210
+ if (richResult.blockingStage) {
211
+ console.log(`Blocking check: ${richResult.blockingStage}`);
212
+ }
213
+ if (richResult.blockingItems && richResult.blockingItems.length > 0) {
214
+ for (const item of richResult.blockingItems) {
215
+ console.log(chalk.red(`Blocker [${item.code}]: ${item.message}${item.file ? ` (${item.file})` : ''}`));
216
+ }
217
+ }
218
+ for (const warning of result.warnings) {
219
+ console.log(chalk.yellow(`Warning: ${warning}`));
220
+ }
221
+ }
222
+ function getStatusBlockingStage(status) {
223
+ if (status === 'imported')
224
+ return 'source';
225
+ if (status === 'refining' || status === 'ready-for-review' || status === 'reviewed')
226
+ return 'requirement';
227
+ if (status === 'split' || status === 'stories-reviewed')
228
+ return 'stories';
229
+ return 'propose';
230
+ }
231
+ function getNextCommands(status, jiraId) {
232
+ switch (status) {
233
+ case 'imported':
234
+ case 'refining':
235
+ return [`/opsx:jira-refine ${jiraId}`];
236
+ case 'ready-for-review':
237
+ return [`/opsx:jira-review ${jiraId}`];
238
+ case 'reviewed':
239
+ case 'split':
240
+ return [`/opsx:jira-split ${jiraId}`];
241
+ case 'stories-reviewed':
242
+ return [`/opsx:jira-propose ${jiraId}`];
243
+ case 'proposed':
244
+ return [`/opsx:jira-sync ${jiraId}`];
245
+ case 'synced':
246
+ return [];
247
+ }
248
+ }
249
+ //# sourceMappingURL=jira.js.map
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Register the schema command and all its subcommands.
4
+ */
5
+ export declare function registerSchemaCommand(program: Command): void;
6
+ //# sourceMappingURL=schema.d.ts.map