hub-launch 1.0.3

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 (331) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/README.md +195 -0
  3. package/bin/hublaunch +20 -0
  4. package/dist/commands/checkout.d.ts +7 -0
  5. package/dist/commands/checkout.d.ts.map +1 -0
  6. package/dist/commands/checkout.js +164 -0
  7. package/dist/commands/checkout.js.map +1 -0
  8. package/dist/commands/clean.d.ts +7 -0
  9. package/dist/commands/clean.d.ts.map +1 -0
  10. package/dist/commands/clean.js +206 -0
  11. package/dist/commands/clean.js.map +1 -0
  12. package/dist/commands/close.d.ts +7 -0
  13. package/dist/commands/close.d.ts.map +1 -0
  14. package/dist/commands/close.js +109 -0
  15. package/dist/commands/close.js.map +1 -0
  16. package/dist/commands/create.d.ts +7 -0
  17. package/dist/commands/create.d.ts.map +1 -0
  18. package/dist/commands/create.js +367 -0
  19. package/dist/commands/create.js.map +1 -0
  20. package/dist/commands/diff.d.ts +7 -0
  21. package/dist/commands/diff.d.ts.map +1 -0
  22. package/dist/commands/diff.js +98 -0
  23. package/dist/commands/diff.js.map +1 -0
  24. package/dist/commands/execute.d.ts +7 -0
  25. package/dist/commands/execute.d.ts.map +1 -0
  26. package/dist/commands/execute.js +376 -0
  27. package/dist/commands/execute.js.map +1 -0
  28. package/dist/commands/init.d.ts +8 -0
  29. package/dist/commands/init.d.ts.map +1 -0
  30. package/dist/commands/init.js +1243 -0
  31. package/dist/commands/init.js.map +1 -0
  32. package/dist/commands/interactive.d.ts +12 -0
  33. package/dist/commands/interactive.d.ts.map +1 -0
  34. package/dist/commands/interactive.js +1071 -0
  35. package/dist/commands/interactive.js.map +1 -0
  36. package/dist/commands/launch.d.ts +16 -0
  37. package/dist/commands/launch.d.ts.map +1 -0
  38. package/dist/commands/launch.js +684 -0
  39. package/dist/commands/launch.js.map +1 -0
  40. package/dist/commands/login.d.ts +40 -0
  41. package/dist/commands/login.d.ts.map +1 -0
  42. package/dist/commands/login.js +469 -0
  43. package/dist/commands/login.js.map +1 -0
  44. package/dist/commands/logs.d.ts +22 -0
  45. package/dist/commands/logs.d.ts.map +1 -0
  46. package/dist/commands/logs.js +105 -0
  47. package/dist/commands/logs.js.map +1 -0
  48. package/dist/commands/merge.d.ts +7 -0
  49. package/dist/commands/merge.d.ts.map +1 -0
  50. package/dist/commands/merge.js +240 -0
  51. package/dist/commands/merge.js.map +1 -0
  52. package/dist/commands/preview.d.ts +7 -0
  53. package/dist/commands/preview.d.ts.map +1 -0
  54. package/dist/commands/preview.js +160 -0
  55. package/dist/commands/preview.js.map +1 -0
  56. package/dist/commands/project.d.ts +18 -0
  57. package/dist/commands/project.d.ts.map +1 -0
  58. package/dist/commands/project.js +352 -0
  59. package/dist/commands/project.js.map +1 -0
  60. package/dist/commands/respond.d.ts +7 -0
  61. package/dist/commands/respond.d.ts.map +1 -0
  62. package/dist/commands/respond.js +112 -0
  63. package/dist/commands/respond.js.map +1 -0
  64. package/dist/commands/setPriority.d.ts +7 -0
  65. package/dist/commands/setPriority.d.ts.map +1 -0
  66. package/dist/commands/setPriority.js +112 -0
  67. package/dist/commands/setPriority.js.map +1 -0
  68. package/dist/commands/track.d.ts +7 -0
  69. package/dist/commands/track.d.ts.map +1 -0
  70. package/dist/commands/track.js +140 -0
  71. package/dist/commands/track.js.map +1 -0
  72. package/dist/commands/upload.d.ts +21 -0
  73. package/dist/commands/upload.d.ts.map +1 -0
  74. package/dist/commands/upload.js +145 -0
  75. package/dist/commands/upload.js.map +1 -0
  76. package/dist/commands/view.d.ts +7 -0
  77. package/dist/commands/view.d.ts.map +1 -0
  78. package/dist/commands/view.js +168 -0
  79. package/dist/commands/view.js.map +1 -0
  80. package/dist/commands/watch.d.ts +7 -0
  81. package/dist/commands/watch.d.ts.map +1 -0
  82. package/dist/commands/watch.js +438 -0
  83. package/dist/commands/watch.js.map +1 -0
  84. package/dist/commands/worktree.d.ts +7 -0
  85. package/dist/commands/worktree.d.ts.map +1 -0
  86. package/dist/commands/worktree.js +122 -0
  87. package/dist/commands/worktree.js.map +1 -0
  88. package/dist/config/command-names.d.ts +16 -0
  89. package/dist/config/command-names.d.ts.map +1 -0
  90. package/dist/config/command-names.js +17 -0
  91. package/dist/config/command-names.js.map +1 -0
  92. package/dist/config/constants.d.ts +12 -0
  93. package/dist/config/constants.d.ts.map +1 -0
  94. package/dist/config/constants.js +12 -0
  95. package/dist/config/constants.js.map +1 -0
  96. package/dist/config/index.d.ts +47 -0
  97. package/dist/config/index.d.ts.map +1 -0
  98. package/dist/config/index.js +175 -0
  99. package/dist/config/index.js.map +1 -0
  100. package/dist/index.d.ts +3 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +148 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/services/api/HulaApiClient.d.ts +170 -0
  105. package/dist/services/api/HulaApiClient.d.ts.map +1 -0
  106. package/dist/services/api/HulaApiClient.js +233 -0
  107. package/dist/services/api/HulaApiClient.js.map +1 -0
  108. package/dist/services/diff/DiffService.d.ts +44 -0
  109. package/dist/services/diff/DiffService.d.ts.map +1 -0
  110. package/dist/services/diff/DiffService.js +126 -0
  111. package/dist/services/diff/DiffService.js.map +1 -0
  112. package/dist/services/editor/EditorService.d.ts +53 -0
  113. package/dist/services/editor/EditorService.d.ts.map +1 -0
  114. package/dist/services/editor/EditorService.js +161 -0
  115. package/dist/services/editor/EditorService.js.map +1 -0
  116. package/dist/services/git/GitService.d.ts +124 -0
  117. package/dist/services/git/GitService.d.ts.map +1 -0
  118. package/dist/services/git/GitService.js +423 -0
  119. package/dist/services/git/GitService.js.map +1 -0
  120. package/dist/services/git/WorktreeService.d.ts +144 -0
  121. package/dist/services/git/WorktreeService.d.ts.map +1 -0
  122. package/dist/services/git/WorktreeService.js +505 -0
  123. package/dist/services/git/WorktreeService.js.map +1 -0
  124. package/dist/services/github/ActionsService.d.ts +66 -0
  125. package/dist/services/github/ActionsService.d.ts.map +1 -0
  126. package/dist/services/github/ActionsService.js +114 -0
  127. package/dist/services/github/ActionsService.js.map +1 -0
  128. package/dist/services/github/AssetUploadService.d.ts +103 -0
  129. package/dist/services/github/AssetUploadService.d.ts.map +1 -0
  130. package/dist/services/github/AssetUploadService.js +299 -0
  131. package/dist/services/github/AssetUploadService.js.map +1 -0
  132. package/dist/services/github/BatchCopilotDetectionService.d.ts +58 -0
  133. package/dist/services/github/BatchCopilotDetectionService.d.ts.map +1 -0
  134. package/dist/services/github/BatchCopilotDetectionService.js +321 -0
  135. package/dist/services/github/BatchCopilotDetectionService.js.map +1 -0
  136. package/dist/services/github/CopilotDetectionService.d.ts +40 -0
  137. package/dist/services/github/CopilotDetectionService.d.ts.map +1 -0
  138. package/dist/services/github/CopilotDetectionService.js +280 -0
  139. package/dist/services/github/CopilotDetectionService.js.map +1 -0
  140. package/dist/services/github/CopilotService.d.ts +27 -0
  141. package/dist/services/github/CopilotService.d.ts.map +1 -0
  142. package/dist/services/github/CopilotService.js +249 -0
  143. package/dist/services/github/CopilotService.js.map +1 -0
  144. package/dist/services/github/DeploymentDetectionService.d.ts +38 -0
  145. package/dist/services/github/DeploymentDetectionService.d.ts.map +1 -0
  146. package/dist/services/github/DeploymentDetectionService.js +104 -0
  147. package/dist/services/github/DeploymentDetectionService.js.map +1 -0
  148. package/dist/services/github/GithubAppService.d.ts +40 -0
  149. package/dist/services/github/GithubAppService.d.ts.map +1 -0
  150. package/dist/services/github/GithubAppService.js +187 -0
  151. package/dist/services/github/GithubAppService.js.map +1 -0
  152. package/dist/services/github/IssueService.d.ts +65 -0
  153. package/dist/services/github/IssueService.d.ts.map +1 -0
  154. package/dist/services/github/IssueService.js +231 -0
  155. package/dist/services/github/IssueService.js.map +1 -0
  156. package/dist/services/github/LabelService.d.ts +36 -0
  157. package/dist/services/github/LabelService.d.ts.map +1 -0
  158. package/dist/services/github/LabelService.js +122 -0
  159. package/dist/services/github/LabelService.js.map +1 -0
  160. package/dist/services/github/PRService.d.ts +77 -0
  161. package/dist/services/github/PRService.d.ts.map +1 -0
  162. package/dist/services/github/PRService.js +287 -0
  163. package/dist/services/github/PRService.js.map +1 -0
  164. package/dist/services/github/ProjectService.d.ts +144 -0
  165. package/dist/services/github/ProjectService.d.ts.map +1 -0
  166. package/dist/services/github/ProjectService.js +804 -0
  167. package/dist/services/github/ProjectService.js.map +1 -0
  168. package/dist/services/hooks/HookExecutor.d.ts +66 -0
  169. package/dist/services/hooks/HookExecutor.d.ts.map +1 -0
  170. package/dist/services/hooks/HookExecutor.js +227 -0
  171. package/dist/services/hooks/HookExecutor.js.map +1 -0
  172. package/dist/services/hooks/index.d.ts +2 -0
  173. package/dist/services/hooks/index.d.ts.map +1 -0
  174. package/dist/services/hooks/index.js +2 -0
  175. package/dist/services/hooks/index.js.map +1 -0
  176. package/dist/services/logs/LogFormatterService.d.ts +17 -0
  177. package/dist/services/logs/LogFormatterService.d.ts.map +1 -0
  178. package/dist/services/logs/LogFormatterService.js +35 -0
  179. package/dist/services/logs/LogFormatterService.js.map +1 -0
  180. package/dist/services/logs/TempFileService.d.ts +27 -0
  181. package/dist/services/logs/TempFileService.d.ts.map +1 -0
  182. package/dist/services/logs/TempFileService.js +90 -0
  183. package/dist/services/logs/TempFileService.js.map +1 -0
  184. package/dist/services/logs/index.d.ts +3 -0
  185. package/dist/services/logs/index.d.ts.map +1 -0
  186. package/dist/services/logs/index.js +4 -0
  187. package/dist/services/logs/index.js.map +1 -0
  188. package/dist/services/plan/PlanService.d.ts +70 -0
  189. package/dist/services/plan/PlanService.d.ts.map +1 -0
  190. package/dist/services/plan/PlanService.js +211 -0
  191. package/dist/services/plan/PlanService.js.map +1 -0
  192. package/dist/services/polling/GitHubDirectPollingAdapter.d.ts +16 -0
  193. package/dist/services/polling/GitHubDirectPollingAdapter.d.ts.map +1 -0
  194. package/dist/services/polling/GitHubDirectPollingAdapter.js +87 -0
  195. package/dist/services/polling/GitHubDirectPollingAdapter.js.map +1 -0
  196. package/dist/services/polling/HulaServerPollingAdapter.d.ts +23 -0
  197. package/dist/services/polling/HulaServerPollingAdapter.d.ts.map +1 -0
  198. package/dist/services/polling/HulaServerPollingAdapter.js +78 -0
  199. package/dist/services/polling/HulaServerPollingAdapter.js.map +1 -0
  200. package/dist/services/polling/IStatusPollingAdapter.d.ts +29 -0
  201. package/dist/services/polling/IStatusPollingAdapter.d.ts.map +1 -0
  202. package/dist/services/polling/IStatusPollingAdapter.js +2 -0
  203. package/dist/services/polling/IStatusPollingAdapter.js.map +1 -0
  204. package/dist/services/polling/StatusPollingAdapterFactory.d.ts +14 -0
  205. package/dist/services/polling/StatusPollingAdapterFactory.d.ts.map +1 -0
  206. package/dist/services/polling/StatusPollingAdapterFactory.js +41 -0
  207. package/dist/services/polling/StatusPollingAdapterFactory.js.map +1 -0
  208. package/dist/services/polling/index.d.ts +5 -0
  209. package/dist/services/polling/index.d.ts.map +1 -0
  210. package/dist/services/polling/index.js +5 -0
  211. package/dist/services/polling/index.js.map +1 -0
  212. package/dist/services/preview/PreviewService.d.ts +86 -0
  213. package/dist/services/preview/PreviewService.d.ts.map +1 -0
  214. package/dist/services/preview/PreviewService.js +439 -0
  215. package/dist/services/preview/PreviewService.js.map +1 -0
  216. package/dist/services/tracking/ProjectTrackingAdapter.d.ts +41 -0
  217. package/dist/services/tracking/ProjectTrackingAdapter.d.ts.map +1 -0
  218. package/dist/services/tracking/ProjectTrackingAdapter.js +230 -0
  219. package/dist/services/tracking/ProjectTrackingAdapter.js.map +1 -0
  220. package/dist/services/tracking/RemoteTrackingAdapter.d.ts +62 -0
  221. package/dist/services/tracking/RemoteTrackingAdapter.d.ts.map +1 -0
  222. package/dist/services/tracking/RemoteTrackingAdapter.js +242 -0
  223. package/dist/services/tracking/RemoteTrackingAdapter.js.map +1 -0
  224. package/dist/services/tracking/TrackingAdapterFactory.d.ts +25 -0
  225. package/dist/services/tracking/TrackingAdapterFactory.d.ts.map +1 -0
  226. package/dist/services/tracking/TrackingAdapterFactory.js +55 -0
  227. package/dist/services/tracking/TrackingAdapterFactory.js.map +1 -0
  228. package/dist/services/tracking/TrackingService.d.ts +104 -0
  229. package/dist/services/tracking/TrackingService.d.ts.map +1 -0
  230. package/dist/services/tracking/TrackingService.js +256 -0
  231. package/dist/services/tracking/TrackingService.js.map +1 -0
  232. package/dist/services/tracking/UntrackedIssuesService.d.ts +20 -0
  233. package/dist/services/tracking/UntrackedIssuesService.d.ts.map +1 -0
  234. package/dist/services/tracking/UntrackedIssuesService.js +148 -0
  235. package/dist/services/tracking/UntrackedIssuesService.js.map +1 -0
  236. package/dist/services/tracking/local-file-migration.d.ts +16 -0
  237. package/dist/services/tracking/local-file-migration.d.ts.map +1 -0
  238. package/dist/services/tracking/local-file-migration.js +86 -0
  239. package/dist/services/tracking/local-file-migration.js.map +1 -0
  240. package/dist/templates/planning-instructions.md +752 -0
  241. package/dist/templates/proceed-instructions.md +453 -0
  242. package/dist/templates/scripts/hula-fix-commit.sh +110 -0
  243. package/dist/templates/scripts/hula-fix-setup.sh +145 -0
  244. package/dist/templates/scripts/hula-launch-run.sh +89 -0
  245. package/dist/templates/scripts/hula-merge-local.sh +138 -0
  246. package/dist/templates/scripts/hula-merge-remote.sh +74 -0
  247. package/dist/templates/scripts/hula-read-config.sh +38 -0
  248. package/dist/templates/scripts/hula-verify-gather.sh +135 -0
  249. package/dist/templates/scripts/hula-verify-post.sh +84 -0
  250. package/dist/templates/skills/hula-confirm/SKILL.md +361 -0
  251. package/dist/templates/skills/hula-create/SKILL.md +211 -0
  252. package/dist/templates/skills/hula-fix/SKILL.md +224 -0
  253. package/dist/templates/skills/hula-launch/SKILL.md +159 -0
  254. package/dist/templates/skills/hula-log/SKILL.md +105 -0
  255. package/dist/templates/skills/hula-merge/SKILL.md +387 -0
  256. package/dist/templates/skills/hula-plan/SKILL.md +148 -0
  257. package/dist/templates/skills/hula-upload/SKILL.md +115 -0
  258. package/dist/templates/skills/hula-verify/SKILL.md +754 -0
  259. package/dist/types/common.schema.d.ts +46 -0
  260. package/dist/types/common.schema.d.ts.map +1 -0
  261. package/dist/types/common.schema.js +60 -0
  262. package/dist/types/common.schema.js.map +1 -0
  263. package/dist/types/config.schema.d.ts +443 -0
  264. package/dist/types/config.schema.d.ts.map +1 -0
  265. package/dist/types/config.schema.js +126 -0
  266. package/dist/types/config.schema.js.map +1 -0
  267. package/dist/types/index.d.ts +6 -0
  268. package/dist/types/index.d.ts.map +1 -0
  269. package/dist/types/index.js +7 -0
  270. package/dist/types/index.js.map +1 -0
  271. package/dist/types/issue.schema.d.ts +136 -0
  272. package/dist/types/issue.schema.d.ts.map +1 -0
  273. package/dist/types/issue.schema.js +49 -0
  274. package/dist/types/issue.schema.js.map +1 -0
  275. package/dist/types/pr.schema.d.ts +118 -0
  276. package/dist/types/pr.schema.d.ts.map +1 -0
  277. package/dist/types/pr.schema.js +40 -0
  278. package/dist/types/pr.schema.js.map +1 -0
  279. package/dist/types/tracking.schema.d.ts +340 -0
  280. package/dist/types/tracking.schema.d.ts.map +1 -0
  281. package/dist/types/tracking.schema.js +56 -0
  282. package/dist/types/tracking.schema.js.map +1 -0
  283. package/dist/utils/browser-launcher.d.ts +60 -0
  284. package/dist/utils/browser-launcher.d.ts.map +1 -0
  285. package/dist/utils/browser-launcher.js +263 -0
  286. package/dist/utils/browser-launcher.js.map +1 -0
  287. package/dist/utils/cache.d.ts +44 -0
  288. package/dist/utils/cache.d.ts.map +1 -0
  289. package/dist/utils/cache.js +94 -0
  290. package/dist/utils/cache.js.map +1 -0
  291. package/dist/utils/config-parser.d.ts +16 -0
  292. package/dist/utils/config-parser.d.ts.map +1 -0
  293. package/dist/utils/config-parser.js +210 -0
  294. package/dist/utils/config-parser.js.map +1 -0
  295. package/dist/utils/editor.d.ts +21 -0
  296. package/dist/utils/editor.d.ts.map +1 -0
  297. package/dist/utils/editor.js +213 -0
  298. package/dist/utils/editor.js.map +1 -0
  299. package/dist/utils/git-utils.d.ts +5 -0
  300. package/dist/utils/git-utils.d.ts.map +1 -0
  301. package/dist/utils/git-utils.js +18 -0
  302. package/dist/utils/git-utils.js.map +1 -0
  303. package/dist/utils/github-cli.d.ts +62 -0
  304. package/dist/utils/github-cli.d.ts.map +1 -0
  305. package/dist/utils/github-cli.js +492 -0
  306. package/dist/utils/github-cli.js.map +1 -0
  307. package/dist/utils/logger.d.ts +45 -0
  308. package/dist/utils/logger.d.ts.map +1 -0
  309. package/dist/utils/logger.js +118 -0
  310. package/dist/utils/logger.js.map +1 -0
  311. package/dist/utils/open-url.d.ts +19 -0
  312. package/dist/utils/open-url.d.ts.map +1 -0
  313. package/dist/utils/open-url.js +37 -0
  314. package/dist/utils/open-url.js.map +1 -0
  315. package/dist/utils/project-resolver.d.ts +13 -0
  316. package/dist/utils/project-resolver.d.ts.map +1 -0
  317. package/dist/utils/project-resolver.js +35 -0
  318. package/dist/utils/project-resolver.js.map +1 -0
  319. package/dist/utils/prompts.d.ts +80 -0
  320. package/dist/utils/prompts.d.ts.map +1 -0
  321. package/dist/utils/prompts.js +326 -0
  322. package/dist/utils/prompts.js.map +1 -0
  323. package/dist/utils/shell.d.ts +54 -0
  324. package/dist/utils/shell.d.ts.map +1 -0
  325. package/dist/utils/shell.js +152 -0
  326. package/dist/utils/shell.js.map +1 -0
  327. package/dist/utils/validators.d.ts +32 -0
  328. package/dist/utils/validators.d.ts.map +1 -0
  329. package/dist/utils/validators.js +64 -0
  330. package/dist/utils/validators.js.map +1 -0
  331. package/package.json +73 -0
@@ -0,0 +1,118 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * Colored console logger with status indicators
4
+ */
5
+ // Status indicators with colored emoji
6
+ const STATUS_ICONS = {
7
+ unassigned: { emoji: '📋', color: 'cyan' },
8
+ initialWaiting: { emoji: '🟡', color: 'yellow' },
9
+ waiting: { emoji: '🟠', color: 'yellow' },
10
+ inProcess: { emoji: '🔄', color: 'blue' },
11
+ ready: { emoji: '✅', color: 'green' },
12
+ merged: { emoji: '🎉', color: 'magenta' },
13
+ closed: { emoji: '✖️', color: 'red' },
14
+ empty: { emoji: '⏳', color: 'gray' },
15
+ };
16
+ // Priority colors
17
+ const PRIORITY_COLORS = {
18
+ Critical: 'red',
19
+ High: 'yellow',
20
+ Medium: 'blue',
21
+ Low: 'green',
22
+ Minimal: 'gray',
23
+ };
24
+ export const logger = {
25
+ info: (msg) => console.log(chalk.white(msg)),
26
+ success: (msg) => console.log(chalk.green(`✓ ${msg}`)),
27
+ warning: (msg) => console.log(chalk.yellow(`⚠ ${msg}`)),
28
+ error: (msg) => console.error(chalk.red(`✗ ${msg}`)),
29
+ debug: (msg) => {
30
+ // Only print debug messages if DEBUG env var is explicitly set to "1" or "true"
31
+ if (process.env.DEBUG === '1' || process.env.DEBUG === 'true') {
32
+ console.log(chalk.gray(`[DEBUG] ${msg}`));
33
+ }
34
+ },
35
+ /**
36
+ * Print a section header
37
+ */
38
+ section: (title) => {
39
+ console.log('\n' + chalk.blue('═'.repeat(60)));
40
+ console.log(chalk.bold.blue(title));
41
+ console.log(chalk.blue('═'.repeat(60)) + '\n');
42
+ },
43
+ /**
44
+ * Display issue with status indicator
45
+ */
46
+ issue: (status, msg) => {
47
+ const icon = STATUS_ICONS[status];
48
+ const colorFn = chalk[icon.color];
49
+ console.log(colorFn(`${icon.emoji} ${msg}`));
50
+ },
51
+ /**
52
+ * Display priority with colored emoji
53
+ */
54
+ priority: (level, emoji, msg) => {
55
+ const color = PRIORITY_COLORS[level];
56
+ const colorFn = chalk[color];
57
+ console.log(colorFn(`${emoji} ${msg}`));
58
+ },
59
+ /**
60
+ * Display a list item
61
+ */
62
+ listItem: (msg, indent = 0) => {
63
+ const spaces = ' '.repeat(indent * 2);
64
+ console.log(`${spaces}• ${msg}`);
65
+ },
66
+ /**
67
+ * Display a numbered list item
68
+ */
69
+ numberedItem: (num, msg, indent = 0) => {
70
+ const spaces = ' '.repeat(indent * 2);
71
+ console.log(`${spaces}${num}. ${msg}`);
72
+ },
73
+ /**
74
+ * Print blank line
75
+ */
76
+ blank: () => console.log(),
77
+ /**
78
+ * Raw console.log passthrough
79
+ */
80
+ log: (...args) => console.log(...args),
81
+ /**
82
+ * Create a spinner/loading indicator
83
+ * Returns an object with stop() method to clear the spinner
84
+ */
85
+ spinner: (msg) => {
86
+ const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
87
+ let i = 0;
88
+ // Don't show spinner if output is not a TTY (e.g., piped)
89
+ if (!process.stdout.isTTY) {
90
+ console.log(msg);
91
+ return {
92
+ stop: (_finalMsg) => { },
93
+ update: (_newMsg) => { }
94
+ };
95
+ }
96
+ process.stdout.write(`${chalk.cyan(frames[i])} ${msg}`);
97
+ const interval = setInterval(() => {
98
+ i = (i + 1) % frames.length;
99
+ process.stdout.clearLine(0);
100
+ process.stdout.cursorTo(0);
101
+ process.stdout.write(`${chalk.cyan(frames[i])} ${msg}`);
102
+ }, 80);
103
+ return {
104
+ stop: (finalMsg) => {
105
+ clearInterval(interval);
106
+ process.stdout.clearLine(0);
107
+ process.stdout.cursorTo(0);
108
+ if (finalMsg) {
109
+ console.log(finalMsg);
110
+ }
111
+ },
112
+ update: (newMsg) => {
113
+ msg = newMsg;
114
+ }
115
+ };
116
+ },
117
+ };
118
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;GAEG;AAEH,uCAAuC;AACvC,MAAM,YAAY,GAAG;IACnB,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IAC1C,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;IAChD,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;IACzC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IACzC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACrC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IACzC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;IACrC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;CAC5B,CAAC;AAEX,kBAAkB;AAClB,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,OAAO;IACZ,OAAO,EAAE,MAAM;CACP,CAAC;AAEX,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC5D,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE;QACrB,gFAAgF;QAChF,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO,EAAE,CAAC,KAAa,EAAE,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,EAAE,CAAC,MAAmB,EAAE,GAAW,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,KAAK,CACnB,IAAI,CAAC,KAA2B,CACZ,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAe,EAAE,KAAa,EAAE,GAAW,EAAE,EAAE;QACxD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,KAAK,CAAC,KAA2B,CAAsB,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,QAAQ,EAAE,CAAC,GAAW,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,YAAY,EAAE,CAAC,GAAW,EAAE,GAAW,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;IAE1B;;OAEG;IACH,GAAG,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAEjD;;;OAGG;IACH,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAClE,IAAI,CAAC,GAAG,CAAC,CAAC;QAEV,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjB,OAAO;gBACL,IAAI,EAAE,CAAC,SAAkB,EAAE,EAAE,GAAE,CAAC;gBAChC,MAAM,EAAE,CAAC,OAAe,EAAE,EAAE,GAAE,CAAC;aAChC,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC1D,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO;YACL,IAAI,EAAE,CAAC,QAAiB,EAAE,EAAE;gBAC1B,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC3B,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,MAAM,EAAE,CAAC,MAAc,EAAE,EAAE;gBACzB,GAAG,GAAG,MAAM,CAAC;YACf,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Open a URL in the default browser (cross-platform)
3
+ *
4
+ * Uses the 'open' package for reliable cross-platform support
5
+ *
6
+ * @param url - The URL to open
7
+ * @returns Promise<void>
8
+ */
9
+ export declare function openUrl(url: string): Promise<void>;
10
+ /**
11
+ * Synchronous version of openUrl for use in execSync contexts
12
+ *
13
+ * Note: This still uses the async 'open' package but doesn't await
14
+ * For truly synchronous behavior, we fall back to exec commands
15
+ *
16
+ * @param url - The URL to open
17
+ */
18
+ export declare function openUrlSync(url: string): void;
19
+ //# sourceMappingURL=open-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-url.d.ts","sourceRoot":"","sources":["../../src/utils/open-url.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAO7C"}
@@ -0,0 +1,37 @@
1
+ import { logger } from './logger.js';
2
+ import open from 'open';
3
+ /**
4
+ * Open a URL in the default browser (cross-platform)
5
+ *
6
+ * Uses the 'open' package for reliable cross-platform support
7
+ *
8
+ * @param url - The URL to open
9
+ * @returns Promise<void>
10
+ */
11
+ export async function openUrl(url) {
12
+ try {
13
+ await open(url);
14
+ }
15
+ catch (error) {
16
+ logger.error(`Failed to open URL: ${url}`);
17
+ logger.info('Please open the URL manually in your browser.');
18
+ throw error;
19
+ }
20
+ }
21
+ /**
22
+ * Synchronous version of openUrl for use in execSync contexts
23
+ *
24
+ * Note: This still uses the async 'open' package but doesn't await
25
+ * For truly synchronous behavior, we fall back to exec commands
26
+ *
27
+ * @param url - The URL to open
28
+ */
29
+ export function openUrlSync(url) {
30
+ // Fire and forget - open is async but we don't wait
31
+ open(url).catch((error) => {
32
+ logger.error(`Failed to open URL: ${url}`);
33
+ logger.info('Please open the URL manually in your browser.');
34
+ logger.debug(error instanceof Error ? error.message : String(error));
35
+ });
36
+ }
37
+ //# sourceMappingURL=open-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-url.js","sourceRoot":"","sources":["../../src/utils/open-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC7D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,oDAAoD;IACpD,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Config } from '../types/config.schema.js';
2
+ /**
3
+ * Resolve the target project (formatted `owner/repo`) for hula-server API calls.
4
+ *
5
+ * Resolution order:
6
+ * 1. `optionProject` (CLI flag override)
7
+ * 2. `config.hulaProject` (set by `hula login` or `hula init`)
8
+ * 3. Git remote detection via `GitService.getRemoteRepository()`
9
+ *
10
+ * Calls `process.exit(1)` with actionable error messages if none of the above resolves.
11
+ */
12
+ export declare function resolveProject(config: Config, optionProject?: string): Promise<string>;
13
+ //# sourceMappingURL=project-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/project-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAIxD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CAsBjB"}
@@ -0,0 +1,35 @@
1
+ import { GitService } from '../services/git/GitService.js';
2
+ import { logger } from './logger.js';
3
+ /**
4
+ * Resolve the target project (formatted `owner/repo`) for hula-server API calls.
5
+ *
6
+ * Resolution order:
7
+ * 1. `optionProject` (CLI flag override)
8
+ * 2. `config.hulaProject` (set by `hula login` or `hula init`)
9
+ * 3. Git remote detection via `GitService.getRemoteRepository()`
10
+ *
11
+ * Calls `process.exit(1)` with actionable error messages if none of the above resolves.
12
+ */
13
+ export async function resolveProject(config, optionProject) {
14
+ if (optionProject)
15
+ return optionProject;
16
+ if (config.hulaProject)
17
+ return config.hulaProject;
18
+ const gitService = new GitService();
19
+ try {
20
+ const repoInfo = await gitService.getRemoteRepository();
21
+ if (repoInfo) {
22
+ const project = `${repoInfo.owner}/${repoInfo.repo}`;
23
+ logger.info(`Project detected: ${project}`);
24
+ return project;
25
+ }
26
+ }
27
+ catch {
28
+ // fall through to error
29
+ }
30
+ logger.error('No project configured.');
31
+ logger.info('Could not detect project from git remote.');
32
+ logger.info('Pass --project <owner/repo>, set hulaProject in config, or run "hula login".');
33
+ process.exit(1);
34
+ }
35
+ //# sourceMappingURL=project-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-resolver.js","sourceRoot":"","sources":["../../src/utils/project-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,aAAsB;IAEtB,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,IAAI,MAAM,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC,WAAW,CAAC;IAElD,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,mBAAmB,EAAE,CAAC;QACxD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;YAC5C,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACzD,MAAM,CAAC,IAAI,CACT,8EAA8E,CAC/E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,80 @@
1
+ import type { Priority } from '../types/index.js';
2
+ /**
3
+ * Custom error class for user cancellation
4
+ */
5
+ export declare class UserCancelledError extends Error {
6
+ constructor();
7
+ }
8
+ /**
9
+ * Confirm prompt with y/n format
10
+ *
11
+ * Displays a prompt asking the user to confirm with y (yes) or n (no).
12
+ * Input is case-insensitive and whitespace is trimmed. Invalid input
13
+ * shows an error message and re-prompts immediately.
14
+ *
15
+ * @param message - The question to ask the user
16
+ * @param defaultValue - Default answer (true for y, false for n)
17
+ * @returns Promise<boolean> - true if user enters 'y', false if user enters 'n'
18
+ * @throws UserCancelledError - If user presses Ctrl+C
19
+ *
20
+ * @example
21
+ * const confirmed = await confirm("Proceed with merge?", false);
22
+ * // Displays: ? Proceed with merge? (y/n) ‣ n
23
+ * // Initial value shown: n (based on defaultValue = false)
24
+ * // User can enter: y, n, Y, N (case-insensitive)
25
+ * // Pressing Enter uses the default value
26
+ * // Invalid input (e.g., "yes", "true") shows error and re-prompts
27
+ */
28
+ export declare function confirm(message: string, defaultValue?: boolean): Promise<boolean>;
29
+ /**
30
+ * Text input prompt
31
+ */
32
+ export declare function input(message: string, defaultValue?: string): Promise<string>;
33
+ /**
34
+ * Select from list prompt
35
+ */
36
+ export declare function select<T extends string>(message: string, choices: T[], defaultValue?: T): Promise<T>;
37
+ /**
38
+ * Multi-select from list prompt
39
+ */
40
+ export declare function multiSelect<T extends string>(message: string, choices: T[] | Array<{
41
+ name: string;
42
+ value: T;
43
+ }>): Promise<T[]>;
44
+ /**
45
+ * Select priority level
46
+ */
47
+ export declare function selectPriority(message: string, priorities: {
48
+ name: Priority;
49
+ emoji: string;
50
+ }[]): Promise<Priority>;
51
+ /**
52
+ * Select from list with search
53
+ */
54
+ export declare function searchSelect<T extends string>(message: string, choices: Array<{
55
+ name: string;
56
+ value: T;
57
+ }>): Promise<T>;
58
+ /**
59
+ * Number input prompt
60
+ */
61
+ export declare function numberInput(message: string, defaultValue?: number): Promise<number>;
62
+ /**
63
+ * Editor prompt for multi-line text
64
+ */
65
+ export declare function editor(message: string, defaultValue?: string): Promise<string>;
66
+ /**
67
+ * Toggle prompt for boolean values (enquirer-specific)
68
+ */
69
+ export declare function toggle(message: string, defaultValue?: boolean): Promise<boolean>;
70
+ /**
71
+ * Form prompt for multiple fields at once (enquirer-specific)
72
+ * Validates all fields after submission and re-prompts if any are invalid
73
+ */
74
+ export declare function form<T = Record<string, string>>(message: string, choices: Array<{
75
+ name: string;
76
+ message: string;
77
+ initial?: string;
78
+ validate?: (value: string) => boolean | string;
79
+ }>): Promise<T>;
80
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAgClD;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;;CAK5C;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,YAAY,UAAQ,GACnB,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,CAAC,SAAS,MAAM,EAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,EAAE,EACZ,YAAY,CAAC,EAAE,CAAC,GACf,OAAO,CAAC,CAAC,CAAC,CAkBZ;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,MAAM,EAChD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,GAC/C,OAAO,CAAC,CAAC,EAAE,CAAC,CAgBd;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAC9C,OAAO,CAAC,QAAQ,CAAC,CAwBnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EACjD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,GACzC,OAAO,CAAC,CAAC,CAAC,CAoBZ;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,YAAY,UAAQ,GACnB,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;CAChD,CAAC,GACD,OAAO,CAAC,CAAC,CAAC,CA4DZ"}
@@ -0,0 +1,326 @@
1
+ import Enquirer from 'enquirer';
2
+ /**
3
+ * User input prompt utilities using enquirer
4
+ */
5
+ // Setup SIGINT handler to exit cleanly and suppress enquirer's ERR_USE_AFTER_CLOSE error
6
+ let sigintHandlerInstalled = false;
7
+ function installSigintHandler() {
8
+ if (sigintHandlerInstalled)
9
+ return;
10
+ sigintHandlerInstalled = true;
11
+ // Capture and suppress uncaught errors from enquirer on SIGINT
12
+ process.on('uncaughtException', (error) => {
13
+ if (error.message.includes('ERR_USE_AFTER_CLOSE') ||
14
+ error.message.includes('readline was closed')) {
15
+ // Silently exit on this specific error
16
+ console.log('\n');
17
+ process.exit(130);
18
+ }
19
+ // Re-throw other errors
20
+ throw error;
21
+ });
22
+ // Use prependListener to ensure our SIGINT handler runs BEFORE enquirer's
23
+ process.prependListener('SIGINT', () => {
24
+ // Just print newline and exit - let the uncaughtException handler deal with enquirer errors
25
+ console.log('\n');
26
+ process.exit(130);
27
+ });
28
+ }
29
+ /**
30
+ * Custom error class for user cancellation
31
+ */
32
+ export class UserCancelledError extends Error {
33
+ constructor() {
34
+ super('User cancelled the prompt');
35
+ this.name = 'UserCancelledError';
36
+ }
37
+ }
38
+ /**
39
+ * Check if an error is a user cancellation (Ctrl+C)
40
+ */
41
+ function isUserCancellation(error) {
42
+ return error === '' || (error instanceof Error && error.message === '');
43
+ }
44
+ /**
45
+ * Confirm prompt with y/n format
46
+ *
47
+ * Displays a prompt asking the user to confirm with y (yes) or n (no).
48
+ * Input is case-insensitive and whitespace is trimmed. Invalid input
49
+ * shows an error message and re-prompts immediately.
50
+ *
51
+ * @param message - The question to ask the user
52
+ * @param defaultValue - Default answer (true for y, false for n)
53
+ * @returns Promise<boolean> - true if user enters 'y', false if user enters 'n'
54
+ * @throws UserCancelledError - If user presses Ctrl+C
55
+ *
56
+ * @example
57
+ * const confirmed = await confirm("Proceed with merge?", false);
58
+ * // Displays: ? Proceed with merge? (y/n) ‣ n
59
+ * // Initial value shown: n (based on defaultValue = false)
60
+ * // User can enter: y, n, Y, N (case-insensitive)
61
+ * // Pressing Enter uses the default value
62
+ * // Invalid input (e.g., "yes", "true") shows error and re-prompts
63
+ */
64
+ export async function confirm(message, defaultValue = false) {
65
+ installSigintHandler();
66
+ // Add (y/n) to the message with parentheses for clarity
67
+ const defaultHint = defaultValue ? 'y' : 'n';
68
+ const promptMessage = `${message} (y/n)`;
69
+ // Helper function to normalize input consistently
70
+ const normalizeInput = (input) => input.toLowerCase().trim();
71
+ const prompt = new Enquirer.Input({
72
+ message: promptMessage,
73
+ initial: defaultHint,
74
+ validate: (input) => {
75
+ const normalized = normalizeInput(input);
76
+ if (normalized === 'y' || normalized === 'n') {
77
+ return true;
78
+ }
79
+ // Validation error appears inline and re-prompts immediately
80
+ return 'Please enter y or n';
81
+ },
82
+ });
83
+ try {
84
+ const result = await prompt.run();
85
+ const normalized = normalizeInput(result);
86
+ return normalized === 'y';
87
+ }
88
+ catch (error) {
89
+ if (isUserCancellation(error)) {
90
+ throw new UserCancelledError();
91
+ }
92
+ throw error;
93
+ }
94
+ }
95
+ /**
96
+ * Text input prompt
97
+ */
98
+ export async function input(message, defaultValue) {
99
+ installSigintHandler();
100
+ const prompt = new Enquirer.Input({
101
+ message,
102
+ initial: defaultValue,
103
+ });
104
+ try {
105
+ return await prompt.run();
106
+ }
107
+ catch (error) {
108
+ if (isUserCancellation(error)) {
109
+ throw new UserCancelledError();
110
+ }
111
+ throw error;
112
+ }
113
+ }
114
+ /**
115
+ * Select from list prompt
116
+ */
117
+ export async function select(message, choices, defaultValue) {
118
+ installSigintHandler();
119
+ const initialIndex = defaultValue ? choices.indexOf(defaultValue) : 0;
120
+ const prompt = new Enquirer.Select({
121
+ message,
122
+ choices,
123
+ initial: initialIndex >= 0 ? initialIndex : 0,
124
+ });
125
+ try {
126
+ return (await prompt.run());
127
+ }
128
+ catch (error) {
129
+ if (isUserCancellation(error)) {
130
+ throw new UserCancelledError();
131
+ }
132
+ throw error;
133
+ }
134
+ }
135
+ /**
136
+ * Multi-select from list prompt
137
+ */
138
+ export async function multiSelect(message, choices) {
139
+ installSigintHandler();
140
+ const prompt = new Enquirer.MultiSelect({
141
+ message,
142
+ choices,
143
+ });
144
+ try {
145
+ return (await prompt.run());
146
+ }
147
+ catch (error) {
148
+ if (isUserCancellation(error)) {
149
+ throw new UserCancelledError();
150
+ }
151
+ throw error;
152
+ }
153
+ }
154
+ /**
155
+ * Select priority level
156
+ */
157
+ export async function selectPriority(message, priorities) {
158
+ installSigintHandler();
159
+ const choices = priorities.map((p) => ({
160
+ name: `${p.emoji} ${p.name}`,
161
+ value: p.name,
162
+ }));
163
+ const prompt = new Enquirer.Select({
164
+ message,
165
+ choices,
166
+ });
167
+ try {
168
+ const result = await prompt.run();
169
+ // Find the priority name from the selected choice
170
+ const selected = choices.find((c) => c.name === result || c.value === result);
171
+ return (selected?.value || result);
172
+ }
173
+ catch (error) {
174
+ if (isUserCancellation(error)) {
175
+ throw new UserCancelledError();
176
+ }
177
+ throw error;
178
+ }
179
+ }
180
+ /**
181
+ * Select from list with search
182
+ */
183
+ export async function searchSelect(message, choices) {
184
+ installSigintHandler();
185
+ const prompt = new Enquirer.Select({
186
+ message,
187
+ choices,
188
+ limit: 15,
189
+ });
190
+ try {
191
+ const result = await prompt.run();
192
+ // Find the value from the selected choice
193
+ const selected = choices.find((c) => c.name === result || c.value === result);
194
+ return (selected?.value || result);
195
+ }
196
+ catch (error) {
197
+ if (isUserCancellation(error)) {
198
+ throw new UserCancelledError();
199
+ }
200
+ throw error;
201
+ }
202
+ }
203
+ /**
204
+ * Number input prompt
205
+ */
206
+ export async function numberInput(message, defaultValue) {
207
+ installSigintHandler();
208
+ const prompt = new Enquirer.Input({
209
+ message,
210
+ initial: defaultValue?.toString(),
211
+ validate: (input) => {
212
+ const num = parseInt(input, 10);
213
+ return !isNaN(num) || 'Please enter a valid number';
214
+ },
215
+ });
216
+ try {
217
+ const value = await prompt.run();
218
+ return parseInt(value, 10);
219
+ }
220
+ catch (error) {
221
+ if (isUserCancellation(error)) {
222
+ throw new UserCancelledError();
223
+ }
224
+ throw error;
225
+ }
226
+ }
227
+ /**
228
+ * Editor prompt for multi-line text
229
+ */
230
+ export async function editor(message, defaultValue) {
231
+ installSigintHandler();
232
+ // Enquirer doesn't have a built-in editor prompt, use Input for now
233
+ const prompt = new Enquirer.Input({
234
+ message,
235
+ initial: defaultValue,
236
+ multiline: true,
237
+ });
238
+ try {
239
+ return await prompt.run();
240
+ }
241
+ catch (error) {
242
+ if (isUserCancellation(error)) {
243
+ throw new UserCancelledError();
244
+ }
245
+ throw error;
246
+ }
247
+ }
248
+ /**
249
+ * Toggle prompt for boolean values (enquirer-specific)
250
+ */
251
+ export async function toggle(message, defaultValue = false) {
252
+ installSigintHandler();
253
+ const prompt = new Enquirer.Toggle({
254
+ message,
255
+ enabled: 'Yes',
256
+ disabled: 'No',
257
+ initial: defaultValue,
258
+ });
259
+ try {
260
+ return await prompt.run();
261
+ }
262
+ catch (error) {
263
+ if (isUserCancellation(error)) {
264
+ throw new UserCancelledError();
265
+ }
266
+ throw error;
267
+ }
268
+ }
269
+ /**
270
+ * Form prompt for multiple fields at once (enquirer-specific)
271
+ * Validates all fields after submission and re-prompts if any are invalid
272
+ */
273
+ export async function form(message, choices) {
274
+ installSigintHandler();
275
+ // Create a mutable copy of choices to update initial values on re-prompt
276
+ let currentChoices = choices.map((c) => ({ ...c }));
277
+ // Keep prompting until all validations pass
278
+ while (true) {
279
+ const prompt = new Enquirer.Form({
280
+ name: 'form',
281
+ message,
282
+ choices: currentChoices,
283
+ align: 'left',
284
+ });
285
+ let result;
286
+ try {
287
+ result = (await prompt.run());
288
+ }
289
+ catch (error) {
290
+ if (isUserCancellation(error)) {
291
+ throw new UserCancelledError();
292
+ }
293
+ throw error;
294
+ }
295
+ // Validate all fields
296
+ const errors = [];
297
+ for (const choice of currentChoices) {
298
+ if (choice.validate) {
299
+ const value = result[choice.name] || '';
300
+ const validationResult = choice.validate(value);
301
+ if (validationResult !== true) {
302
+ const errorMsg = typeof validationResult === 'string'
303
+ ? validationResult
304
+ : `Invalid value for ${choice.message}`;
305
+ errors.push(` ❌ ${choice.message}: ${errorMsg}`);
306
+ }
307
+ }
308
+ }
309
+ // If there are validation errors, show them and re-prompt
310
+ if (errors.length > 0) {
311
+ console.log('\n⚠️ Validation errors:');
312
+ errors.forEach((err) => console.log(err));
313
+ console.log('\nPlease correct the values and try again.\n');
314
+ // Create new choices array with updated initial values from user's input
315
+ currentChoices = currentChoices.map((choice) => ({
316
+ ...choice,
317
+ initial: result[choice.name] !== undefined
318
+ ? result[choice.name]
319
+ : choice.initial,
320
+ }));
321
+ continue;
322
+ }
323
+ return result;
324
+ }
325
+ }
326
+ //# sourceMappingURL=prompts.js.map