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,263 @@
1
+ import { chromium } from '@playwright/test';
2
+ import { existsSync, readdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { homedir } from 'os';
5
+ import { logger } from './logger.js';
6
+ import { runCommand } from './shell.js';
7
+ const DEFAULT_TIMEOUT = 30000;
8
+ export const COMMON_CHROME_ARGS = [
9
+ '--disable-blink-features=AutomationControlled',
10
+ '--disable-background-timer-throttling',
11
+ '--disable-renderer-backgrounding',
12
+ '--disable-backgrounding-occluded-windows',
13
+ ];
14
+ /**
15
+ * Check if user data directory has existing session
16
+ */
17
+ export function hasExistingSession(userDataDir) {
18
+ const cookiesPath = join(userDataDir, 'Default', 'Cookies');
19
+ const networkPath = join(userDataDir, 'Default', 'Network');
20
+ return existsSync(cookiesPath) || existsSync(networkPath);
21
+ }
22
+ /**
23
+ * Determine if browser should run in headless mode
24
+ */
25
+ export function shouldRunHeadless(hasSession, config) {
26
+ const mode = config.browserHeadless ?? 'auto';
27
+ switch (mode) {
28
+ case 'always':
29
+ return true;
30
+ case 'never':
31
+ return false;
32
+ case 'auto':
33
+ default:
34
+ return hasSession; // Headless only if session exists
35
+ }
36
+ }
37
+ /**
38
+ * Launch browser with conditional headless mode
39
+ *
40
+ * Returns context and metadata about launch configuration
41
+ */
42
+ export async function launchBrowser(options) {
43
+ const { userDataDir, serviceName, config, timeout = DEFAULT_TIMEOUT, extraArgs = [], } = options;
44
+ const hasSession = hasExistingSession(userDataDir);
45
+ // IMPORTANT: GitHub detects headless browsers and blocks them
46
+ // Always use visible mode for GitHub to avoid 404 errors
47
+ // For other services, use the configured mode
48
+ const headless = serviceName === 'GitHub'
49
+ ? false // Always visible for GitHub
50
+ : shouldRunHeadless(hasSession, config);
51
+ // Log what we're doing
52
+ if (hasSession) {
53
+ logger.info(`Using saved ${serviceName} session...`);
54
+ }
55
+ else {
56
+ logger.info(`Loading ${serviceName} authentication profile...`);
57
+ }
58
+ if (config.browserHeadless === 'always') {
59
+ logger.debug('Config: Force headless mode');
60
+ }
61
+ else if (config.browserHeadless === 'never') {
62
+ logger.debug('Config: Force visible browser');
63
+ }
64
+ // Prepare launch arguments
65
+ const args = [...COMMON_CHROME_ARGS, ...extraArgs];
66
+ try {
67
+ // Use system Chrome directly - more stable than Playwright's bundled Chromium
68
+ // which can crash on some systems
69
+ // First try to find Chrome, then fall back to bundled Chromium
70
+ const chromePaths = [
71
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', // macOS
72
+ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', // Windows
73
+ 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', // Windows x86
74
+ '/usr/bin/google-chrome', // Linux
75
+ '/usr/bin/google-chrome-stable', // Linux
76
+ ];
77
+ const fs = await import('fs');
78
+ const chromePath = chromePaths.find(p => fs.existsSync(p));
79
+ const launchOptions = {
80
+ headless,
81
+ timeout,
82
+ args,
83
+ };
84
+ if (chromePath) {
85
+ launchOptions.executablePath = chromePath;
86
+ logger.debug(`Using Chrome at: ${chromePath}`);
87
+ }
88
+ else {
89
+ // Fall back to channel: 'chrome' which may work on some systems
90
+ launchOptions.channel = 'chrome';
91
+ logger.debug('Using Playwright channel: chrome');
92
+ }
93
+ const context = await chromium.launchPersistentContext(userDataDir, launchOptions);
94
+ logger.debug(`Browser launched in ${headless ? 'headless' : 'visible'} mode`);
95
+ return {
96
+ context,
97
+ wasHeadless: headless,
98
+ needsLogin: !hasSession,
99
+ };
100
+ }
101
+ catch (error) {
102
+ // Check if Playwright browsers aren't installed
103
+ const errorMessage = error instanceof Error ? error.message : String(error);
104
+ if (errorMessage.includes("Executable doesn't exist") ||
105
+ errorMessage.includes('browserType.launchPersistentContext')) {
106
+ logger.blank();
107
+ logger.error('Playwright browser not installed');
108
+ logger.blank();
109
+ logger.info('Please install Playwright browsers by running:');
110
+ logger.blank();
111
+ logger.info(' npx playwright install chromium');
112
+ logger.blank();
113
+ logger.info('Or install all browsers:');
114
+ logger.blank();
115
+ logger.info(' npx playwright install');
116
+ logger.blank();
117
+ throw new Error('Playwright browser not installed. Run: npx playwright install chromium');
118
+ }
119
+ // Check if session might be corrupted
120
+ if (hasSession && headless) {
121
+ logger.error('Failed to launch browser in headless mode');
122
+ logger.info('Session may be expired or corrupted');
123
+ logger.blank();
124
+ logger.info('Try removing session directory:');
125
+ if (process.platform === 'win32') {
126
+ logger.info(` PowerShell: Remove-Item -Recurse -Force "${userDataDir}"`);
127
+ logger.info(` CMD: rmdir /s /q "${userDataDir}"`);
128
+ }
129
+ else {
130
+ logger.info(` rm -rf "${userDataDir}"`);
131
+ }
132
+ logger.info('Then run the command again to re-authenticate');
133
+ logger.blank();
134
+ }
135
+ throw error;
136
+ }
137
+ }
138
+ /**
139
+ * Handle session expiration with clear error message
140
+ */
141
+ export function handleSessionExpired(serviceName, userDataDir) {
142
+ logger.blank();
143
+ logger.error(`${serviceName} session has expired or is corrupted`);
144
+ logger.blank();
145
+ logger.info('To fix this, please remove the session and re-authenticate:');
146
+ logger.blank();
147
+ // Provide platform-specific commands
148
+ if (process.platform === 'win32') {
149
+ logger.info(` PowerShell: Remove-Item -Recurse -Force "${userDataDir}"`);
150
+ logger.info(` CMD: rmdir /s /q "${userDataDir}"`);
151
+ }
152
+ else {
153
+ logger.info(` rm -rf "${userDataDir}"`);
154
+ }
155
+ logger.blank();
156
+ logger.info(' Then run your command again to login with a fresh session');
157
+ logger.blank();
158
+ throw new Error(`${serviceName} session expired`);
159
+ }
160
+ /**
161
+ * Check if Playwright Chromium is installed
162
+ *
163
+ * @returns true if Chromium browser is installed, false otherwise
164
+ */
165
+ export async function checkChromiumInstalled() {
166
+ try {
167
+ // Playwright installs browsers in specific directories
168
+ // macOS: ~/Library/Caches/ms-playwright
169
+ // Linux: ~/.cache/ms-playwright
170
+ // Windows: %USERPROFILE%\AppData\Local\ms-playwright
171
+ const platform = process.platform;
172
+ let playwrightDir;
173
+ if (platform === 'darwin') {
174
+ playwrightDir = join(homedir(), 'Library', 'Caches', 'ms-playwright');
175
+ }
176
+ else if (platform === 'win32') {
177
+ playwrightDir = join(homedir(), 'AppData', 'Local', 'ms-playwright');
178
+ }
179
+ else {
180
+ // Linux and others
181
+ playwrightDir = join(homedir(), '.cache', 'ms-playwright');
182
+ }
183
+ // Check if Chromium directory exists
184
+ if (!existsSync(playwrightDir)) {
185
+ logger.debug('Playwright cache directory not found');
186
+ return false;
187
+ }
188
+ // Look for chromium-* directories
189
+ const entries = readdirSync(playwrightDir);
190
+ const hasChromium = entries.some((entry) => entry.startsWith('chromium-'));
191
+ if (!hasChromium) {
192
+ logger.debug('No Chromium installation found in Playwright cache');
193
+ return false;
194
+ }
195
+ logger.debug('Playwright Chromium installation detected');
196
+ return true;
197
+ }
198
+ catch (error) {
199
+ logger.debug(`Error checking Chromium installation: ${error}`);
200
+ return false;
201
+ }
202
+ }
203
+ /**
204
+ * Install Playwright Chromium browser
205
+ *
206
+ * @returns true if installation succeeded, false otherwise
207
+ */
208
+ export async function installChromium() {
209
+ try {
210
+ logger.info('Installing Playwright Chromium...');
211
+ logger.info('This may take a few minutes...');
212
+ logger.blank();
213
+ // Run playwright install chromium (not silent - show progress)
214
+ await runCommand('npx playwright install chromium', { silent: false });
215
+ logger.blank();
216
+ logger.success('✓ Chromium installed successfully');
217
+ return true;
218
+ }
219
+ catch (error) {
220
+ logger.error('Failed to install Chromium:');
221
+ logger.error(error instanceof Error ? error.message : String(error));
222
+ logger.info('');
223
+ logger.info('You can install manually later with:');
224
+ logger.info(' npx playwright install chromium');
225
+ return false;
226
+ }
227
+ }
228
+ /**
229
+ * Ensure Playwright Chromium is available, prompting for installation if needed.
230
+ *
231
+ * @returns true if Playwright is available, false if user declined or installation failed
232
+ */
233
+ export async function requirePlaywright(options) {
234
+ const hasChromium = await checkChromiumInstalled();
235
+ if (hasChromium) {
236
+ return true;
237
+ }
238
+ logger.blank();
239
+ logger.warning('Playwright Chromium is not installed');
240
+ logger.info(options.featureDescription);
241
+ logger.blank();
242
+ // Non-interactive mode
243
+ if (options.nonInteractive) {
244
+ if (options.autoInstall) {
245
+ logger.info('Auto-installing Playwright Chromium...');
246
+ return await installChromium();
247
+ }
248
+ logger.error('Playwright is required but not installed.');
249
+ logger.info('Install with: npx playwright install chromium');
250
+ logger.info('Or use --install-playwright flag to auto-install.');
251
+ return false;
252
+ }
253
+ // Interactive mode - prompt user
254
+ const { confirm } = await import('./prompts.js');
255
+ const shouldInstall = await confirm('Would you like to install Chromium now?', true);
256
+ if (shouldInstall) {
257
+ return await installChromium();
258
+ }
259
+ logger.info('Skipping installation.');
260
+ logger.info('Install later with: npx playwright install chromium');
261
+ return false;
262
+ }
263
+ //# sourceMappingURL=browser-launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-launcher.js","sourceRoot":"","sources":["../../src/utils/browser-launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Thread-safe in-memory cache service
3
+ */
4
+ export declare class Cache {
5
+ private store;
6
+ /**
7
+ * Set a value in the cache
8
+ */
9
+ set<T>(key: string, value: T, ttlSeconds?: number): void;
10
+ /**
11
+ * Get a value from the cache
12
+ */
13
+ get<T>(key: string): T | null;
14
+ /**
15
+ * Check if a key exists in the cache
16
+ */
17
+ has(key: string): boolean;
18
+ /**
19
+ * Delete a key from the cache
20
+ */
21
+ delete(key: string): void;
22
+ /**
23
+ * Clear all cache entries
24
+ */
25
+ clear(): void;
26
+ /**
27
+ * Get or set a value (lazy loading)
28
+ */
29
+ getOrSet<T>(key: string, factory: () => Promise<T>, ttlSeconds?: number): Promise<T>;
30
+ /**
31
+ * Get cache statistics
32
+ */
33
+ stats(): {
34
+ size: number;
35
+ keys: string[];
36
+ };
37
+ /**
38
+ * Clean up expired entries
39
+ */
40
+ cleanup(): number;
41
+ }
42
+ declare const globalCache: Cache;
43
+ export { globalCache };
44
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA+C;IAE5D;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQxD;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAmB7B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,QAAQ,CAAC,CAAC,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,CAAC;IAWb;;OAEG;IACH,KAAK,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;IAOzC;;OAEG;IACH,OAAO,IAAI,MAAM;CAgBlB;AAGD,QAAA,MAAM,WAAW,OAAc,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Thread-safe in-memory cache service
3
+ */
4
+ export class Cache {
5
+ store = new Map();
6
+ /**
7
+ * Set a value in the cache
8
+ */
9
+ set(key, value, ttlSeconds) {
10
+ this.store.set(key, {
11
+ value,
12
+ timestamp: Date.now(),
13
+ ttl: ttlSeconds ? ttlSeconds * 1000 : undefined,
14
+ });
15
+ }
16
+ /**
17
+ * Get a value from the cache
18
+ */
19
+ get(key) {
20
+ const entry = this.store.get(key);
21
+ if (!entry) {
22
+ return null;
23
+ }
24
+ // Check if expired
25
+ if (entry.ttl) {
26
+ const age = Date.now() - entry.timestamp;
27
+ if (age > entry.ttl) {
28
+ this.store.delete(key);
29
+ return null;
30
+ }
31
+ }
32
+ return entry.value;
33
+ }
34
+ /**
35
+ * Check if a key exists in the cache
36
+ */
37
+ has(key) {
38
+ return this.get(key) !== null;
39
+ }
40
+ /**
41
+ * Delete a key from the cache
42
+ */
43
+ delete(key) {
44
+ this.store.delete(key);
45
+ }
46
+ /**
47
+ * Clear all cache entries
48
+ */
49
+ clear() {
50
+ this.store.clear();
51
+ }
52
+ /**
53
+ * Get or set a value (lazy loading)
54
+ */
55
+ async getOrSet(key, factory, ttlSeconds) {
56
+ const cached = this.get(key);
57
+ if (cached !== null) {
58
+ return cached;
59
+ }
60
+ const value = await factory();
61
+ this.set(key, value, ttlSeconds);
62
+ return value;
63
+ }
64
+ /**
65
+ * Get cache statistics
66
+ */
67
+ stats() {
68
+ return {
69
+ size: this.store.size,
70
+ keys: Array.from(this.store.keys()),
71
+ };
72
+ }
73
+ /**
74
+ * Clean up expired entries
75
+ */
76
+ cleanup() {
77
+ let removed = 0;
78
+ const now = Date.now();
79
+ for (const [key, entry] of this.store.entries()) {
80
+ if (entry.ttl) {
81
+ const age = now - entry.timestamp;
82
+ if (age > entry.ttl) {
83
+ this.store.delete(key);
84
+ removed++;
85
+ }
86
+ }
87
+ }
88
+ return removed;
89
+ }
90
+ }
91
+ // Global cache instance
92
+ const globalCache = new Cache();
93
+ export { globalCache };
94
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Parse existing config file and extract current values
3
+ * Handles both .js and .ts config files
4
+ */
5
+ export declare function parseExistingConfig(configPath: string): Promise<Partial<Record<string, any>> | null>;
6
+ /**
7
+ * Extract config values using regex patterns (fallback method)
8
+ * Useful when dynamic import fails due to syntax errors
9
+ */
10
+ export declare function extractConfigViaRegex(content: string): Partial<Record<string, any>>;
11
+ /**
12
+ * Merge existing config values with new config values
13
+ * Priority: existing > new (preserve user customizations)
14
+ */
15
+ export declare function mergeConfigs(existing: Partial<Record<string, any>> | null, newConfig: Record<string, any>): Record<string, any>;
16
+ //# sourceMappingURL=config-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../../src/utils/config-parser.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAoD9C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CA6K9B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAC7C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAkBrB"}
@@ -0,0 +1,210 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { pathToFileURL } from 'url';
4
+ import { logger } from './logger.js';
5
+ /**
6
+ * Parse existing config file and extract current values
7
+ * Handles both .js and .ts config files
8
+ */
9
+ export async function parseExistingConfig(configPath) {
10
+ if (!existsSync(configPath)) {
11
+ return null;
12
+ }
13
+ const spinner = logger.spinner('Parsing existing configuration...');
14
+ try {
15
+ // Try dynamic import first (best for valid JS/TS files)
16
+ const configUrl = pathToFileURL(configPath).href;
17
+ const moduleUrl = `${configUrl}?parse=${Date.now()}`;
18
+ const configModule = (await import(moduleUrl));
19
+ const parsed = (configModule.default ||
20
+ configModule.config ||
21
+ configModule);
22
+ spinner.stop();
23
+ return parsed;
24
+ }
25
+ catch (importError) {
26
+ // Fallback: Regex extraction for malformed files
27
+ spinner.update('Config has errors, using fallback parser...');
28
+ logger.debug(`Dynamic import failed: ${importError instanceof Error ? importError.message : String(importError)}`);
29
+ try {
30
+ const content = await readFile(configPath, 'utf-8');
31
+ const result = extractConfigViaRegex(content);
32
+ spinner.stop();
33
+ logger.warning('⚠️ Config file has syntax errors. Preserved values using regex extraction.');
34
+ return result;
35
+ }
36
+ catch (readError) {
37
+ spinner.stop();
38
+ logger.error(`Failed to parse existing config: ${readError instanceof Error ? readError.message : String(readError)}`);
39
+ logger.warning('Config preservation failed. Proceeding with fresh initialization.');
40
+ return null;
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Extract config values using regex patterns (fallback method)
46
+ * Useful when dynamic import fails due to syntax errors
47
+ */
48
+ export function extractConfigViaRegex(content) {
49
+ const extracted = {};
50
+ // Extract hulaApiKey
51
+ const apiKeyMatch = content.match(/hulaApiKey:\s*['"]([^'"]+)['"]/);
52
+ if (apiKeyMatch) {
53
+ extracted.hulaApiKey = apiKeyMatch[1];
54
+ }
55
+ // Extract anthropicApiKey
56
+ const anthropicKeyMatch = content.match(/anthropicApiKey:\s*['"]([^'"]+)['"]/);
57
+ if (anthropicKeyMatch) {
58
+ extracted.anthropicApiKey = anthropicKeyMatch[1];
59
+ }
60
+ // Extract daytonaApiKey
61
+ const daytonaKeyMatch = content.match(/daytonaApiKey:\s*['"]([^'"]+)['"]/);
62
+ if (daytonaKeyMatch) {
63
+ extracted.daytonaApiKey = daytonaKeyMatch[1];
64
+ }
65
+ // Extract daytonaTier (number)
66
+ const daytonaTierMatch = content.match(/daytonaTier:\s*(\d+)/);
67
+ if (daytonaTierMatch && daytonaTierMatch[1]) {
68
+ extracted.daytonaTier = parseInt(daytonaTierMatch[1], 10);
69
+ }
70
+ // Extract hulaProjectUrl
71
+ const urlMatch = content.match(/hulaProjectUrl:\s*['"]([^'"]+)['"]/);
72
+ if (urlMatch) {
73
+ extracted.hulaProjectUrl = urlMatch[1];
74
+ }
75
+ // Detect legacy hulaRepository key and fail fast with remediation
76
+ if (/hulaRepository\s*:/.test(content)) {
77
+ throw new Error('Config key `hulaRepository` is no longer supported. Rename it to ' +
78
+ '`hulaProject` in .hublaunch/hublaunch.config.js. See CHANGELOG.md.');
79
+ }
80
+ // Extract hulaProject (formerly hulaRepository)
81
+ const repoMatch = content.match(/hulaProject:\s*['"]([^'"]+)['"]/);
82
+ if (repoMatch) {
83
+ extracted.hulaProject = repoMatch[1];
84
+ }
85
+ // Extract editorCommand
86
+ const editorMatch = content.match(/editorCommand:\s*['"]([^'"]+)['"]/);
87
+ if (editorMatch) {
88
+ extracted.editorCommand = editorMatch[1];
89
+ }
90
+ // Extract planPath
91
+ const planPathMatch = content.match(/planPath:\s*['"]([^'"]+)['"]/);
92
+ if (planPathMatch) {
93
+ extracted.planPath = planPathMatch[1];
94
+ }
95
+ // Extract trackingFile
96
+ const trackingMatch = content.match(/trackingFile:\s*['"]([^'"]+)['"]/);
97
+ if (trackingMatch) {
98
+ extracted.trackingFile = trackingMatch[1];
99
+ }
100
+ // Extract createIssuesPreference
101
+ const createIssuesMatch = content.match(/createIssuesPreference:\s*['"]([^'"]+)['"]/);
102
+ if (createIssuesMatch) {
103
+ extracted.createIssuesPreference = createIssuesMatch[1];
104
+ }
105
+ // Extract planChoices (number)
106
+ const planChoicesMatch = content.match(/planChoices:\s*(\d+)/);
107
+ if (planChoicesMatch && planChoicesMatch[1]) {
108
+ extracted.planChoices = parseInt(planChoicesMatch[1], 10);
109
+ }
110
+ // Extract skipUntrackedPrompt (boolean)
111
+ const skipMatch = content.match(/skipUntrackedPrompt:\s*(true|false)/);
112
+ if (skipMatch) {
113
+ extracted.skipUntrackedPrompt = skipMatch[1] === 'true';
114
+ }
115
+ // Extract teamMembers array
116
+ const teamMembersMatch = content.match(/teamMembers:\s*\[([\s\S]*?)\]/);
117
+ if (teamMembersMatch) {
118
+ try {
119
+ const arrayContent = teamMembersMatch[1];
120
+ // Extract quoted strings
121
+ const members = arrayContent?.match(/['"]([^'"]+)['"]/g);
122
+ if (members) {
123
+ extracted.teamMembers = members.map((m) => m.slice(1, -1));
124
+ }
125
+ }
126
+ catch {
127
+ // Ignore parsing errors
128
+ }
129
+ }
130
+ // Extract services object (simplified)
131
+ const servicesMatch = content.match(/services:\s*{([\s\S]*?)},?\s*\n/);
132
+ if (servicesMatch) {
133
+ const servicesContent = servicesMatch[1];
134
+ const services = {};
135
+ // Extract authentication provider
136
+ const authMatch = servicesContent?.match(/authentication:\s*{\s*provider:\s*['"]([^'"]+)['"]/);
137
+ if (authMatch) {
138
+ services.authentication = { provider: authMatch[1] };
139
+ }
140
+ if (Object.keys(services).length > 0) {
141
+ extracted.services = services;
142
+ }
143
+ }
144
+ // Extract hooks object
145
+ const hooksMatch = content.match(/hooks:\s*{([\s\S]*?)},?\s*\n/);
146
+ if (hooksMatch) {
147
+ const hooksContent = hooksMatch[1];
148
+ const hooks = {};
149
+ // Extract deploymentStartup
150
+ const deployMatch = hooksContent?.match(/deploymentStartup:\s*['"]([^'"]+)['"]/);
151
+ if (deployMatch && deployMatch[1]) {
152
+ hooks.deploymentStartup = deployMatch[1];
153
+ }
154
+ if (Object.keys(hooks).length > 0) {
155
+ extracted.hooks = hooks;
156
+ }
157
+ }
158
+ // Extract worktreeBasePath
159
+ const worktreeBaseMatch = content.match(/worktreeBasePath:\s*['"]([^'"]+)['"]/);
160
+ if (worktreeBaseMatch) {
161
+ extracted.worktreeBasePath = worktreeBaseMatch[1];
162
+ }
163
+ // Extract browserHeadless
164
+ const browserMatch = content.match(/browserHeadless:\s*['"]([^'"]+)['"]/);
165
+ if (browserMatch) {
166
+ extracted.browserHeadless = browserMatch[1];
167
+ }
168
+ // Extract containerResources object
169
+ const containerResourcesMatch = content.match(/containerResources:\s*\{([^}]+)\}/);
170
+ if (containerResourcesMatch && containerResourcesMatch[1]) {
171
+ const resourcesContent = containerResourcesMatch[1];
172
+ const resources = {};
173
+ const cpuMatch = resourcesContent.match(/cpu:\s*(\d+)/);
174
+ if (cpuMatch && cpuMatch[1])
175
+ resources.cpu = parseInt(cpuMatch[1], 10);
176
+ const memoryMatch = resourcesContent.match(/memory:\s*(\d+)/);
177
+ if (memoryMatch && memoryMatch[1])
178
+ resources.memory = parseInt(memoryMatch[1], 10);
179
+ const diskMatch = resourcesContent.match(/disk:\s*(\d+)/);
180
+ if (diskMatch && diskMatch[1])
181
+ resources.disk = parseInt(diskMatch[1], 10);
182
+ if (Object.keys(resources).length > 0) {
183
+ extracted.containerResources = resources;
184
+ }
185
+ }
186
+ return extracted;
187
+ }
188
+ /**
189
+ * Merge existing config values with new config values
190
+ * Priority: existing > new (preserve user customizations)
191
+ */
192
+ export function mergeConfigs(existing, newConfig) {
193
+ if (!existing) {
194
+ return newConfig;
195
+ }
196
+ return {
197
+ ...newConfig,
198
+ ...existing,
199
+ // Deep merge for nested objects
200
+ services: {
201
+ ...newConfig.services,
202
+ ...existing.services,
203
+ },
204
+ hooks: {
205
+ ...newConfig.hooks,
206
+ ...existing.hooks,
207
+ },
208
+ };
209
+ }
210
+ //# sourceMappingURL=config-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../../src/utils/config-parser.ts"],"names":[],"mappings":"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"}