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.
- package/CHANGELOG.md +144 -0
- package/README.md +195 -0
- package/bin/hublaunch +20 -0
- package/dist/commands/checkout.d.ts +7 -0
- package/dist/commands/checkout.d.ts.map +1 -0
- package/dist/commands/checkout.js +164 -0
- package/dist/commands/checkout.js.map +1 -0
- package/dist/commands/clean.d.ts +7 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +206 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/close.d.ts +7 -0
- package/dist/commands/close.d.ts.map +1 -0
- package/dist/commands/close.js +109 -0
- package/dist/commands/close.js.map +1 -0
- package/dist/commands/create.d.ts +7 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +367 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/diff.d.ts +7 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +98 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/execute.d.ts +7 -0
- package/dist/commands/execute.d.ts.map +1 -0
- package/dist/commands/execute.js +376 -0
- package/dist/commands/execute.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1243 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/interactive.d.ts +12 -0
- package/dist/commands/interactive.d.ts.map +1 -0
- package/dist/commands/interactive.js +1071 -0
- package/dist/commands/interactive.js.map +1 -0
- package/dist/commands/launch.d.ts +16 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +684 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/login.d.ts +40 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +469 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +22 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +105 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/merge.d.ts +7 -0
- package/dist/commands/merge.d.ts.map +1 -0
- package/dist/commands/merge.js +240 -0
- package/dist/commands/merge.js.map +1 -0
- package/dist/commands/preview.d.ts +7 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +160 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/project.d.ts +18 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +352 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/respond.d.ts +7 -0
- package/dist/commands/respond.d.ts.map +1 -0
- package/dist/commands/respond.js +112 -0
- package/dist/commands/respond.js.map +1 -0
- package/dist/commands/setPriority.d.ts +7 -0
- package/dist/commands/setPriority.d.ts.map +1 -0
- package/dist/commands/setPriority.js +112 -0
- package/dist/commands/setPriority.js.map +1 -0
- package/dist/commands/track.d.ts +7 -0
- package/dist/commands/track.d.ts.map +1 -0
- package/dist/commands/track.js +140 -0
- package/dist/commands/track.js.map +1 -0
- package/dist/commands/upload.d.ts +21 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +145 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/view.d.ts +7 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +168 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/watch.d.ts +7 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +438 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/worktree.d.ts +7 -0
- package/dist/commands/worktree.d.ts.map +1 -0
- package/dist/commands/worktree.js +122 -0
- package/dist/commands/worktree.js.map +1 -0
- package/dist/config/command-names.d.ts +16 -0
- package/dist/config/command-names.d.ts.map +1 -0
- package/dist/config/command-names.js +17 -0
- package/dist/config/command-names.js.map +1 -0
- package/dist/config/constants.d.ts +12 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +12 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/index.d.ts +47 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +175 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +148 -0
- package/dist/index.js.map +1 -0
- package/dist/services/api/HulaApiClient.d.ts +170 -0
- package/dist/services/api/HulaApiClient.d.ts.map +1 -0
- package/dist/services/api/HulaApiClient.js +233 -0
- package/dist/services/api/HulaApiClient.js.map +1 -0
- package/dist/services/diff/DiffService.d.ts +44 -0
- package/dist/services/diff/DiffService.d.ts.map +1 -0
- package/dist/services/diff/DiffService.js +126 -0
- package/dist/services/diff/DiffService.js.map +1 -0
- package/dist/services/editor/EditorService.d.ts +53 -0
- package/dist/services/editor/EditorService.d.ts.map +1 -0
- package/dist/services/editor/EditorService.js +161 -0
- package/dist/services/editor/EditorService.js.map +1 -0
- package/dist/services/git/GitService.d.ts +124 -0
- package/dist/services/git/GitService.d.ts.map +1 -0
- package/dist/services/git/GitService.js +423 -0
- package/dist/services/git/GitService.js.map +1 -0
- package/dist/services/git/WorktreeService.d.ts +144 -0
- package/dist/services/git/WorktreeService.d.ts.map +1 -0
- package/dist/services/git/WorktreeService.js +505 -0
- package/dist/services/git/WorktreeService.js.map +1 -0
- package/dist/services/github/ActionsService.d.ts +66 -0
- package/dist/services/github/ActionsService.d.ts.map +1 -0
- package/dist/services/github/ActionsService.js +114 -0
- package/dist/services/github/ActionsService.js.map +1 -0
- package/dist/services/github/AssetUploadService.d.ts +103 -0
- package/dist/services/github/AssetUploadService.d.ts.map +1 -0
- package/dist/services/github/AssetUploadService.js +299 -0
- package/dist/services/github/AssetUploadService.js.map +1 -0
- package/dist/services/github/BatchCopilotDetectionService.d.ts +58 -0
- package/dist/services/github/BatchCopilotDetectionService.d.ts.map +1 -0
- package/dist/services/github/BatchCopilotDetectionService.js +321 -0
- package/dist/services/github/BatchCopilotDetectionService.js.map +1 -0
- package/dist/services/github/CopilotDetectionService.d.ts +40 -0
- package/dist/services/github/CopilotDetectionService.d.ts.map +1 -0
- package/dist/services/github/CopilotDetectionService.js +280 -0
- package/dist/services/github/CopilotDetectionService.js.map +1 -0
- package/dist/services/github/CopilotService.d.ts +27 -0
- package/dist/services/github/CopilotService.d.ts.map +1 -0
- package/dist/services/github/CopilotService.js +249 -0
- package/dist/services/github/CopilotService.js.map +1 -0
- package/dist/services/github/DeploymentDetectionService.d.ts +38 -0
- package/dist/services/github/DeploymentDetectionService.d.ts.map +1 -0
- package/dist/services/github/DeploymentDetectionService.js +104 -0
- package/dist/services/github/DeploymentDetectionService.js.map +1 -0
- package/dist/services/github/GithubAppService.d.ts +40 -0
- package/dist/services/github/GithubAppService.d.ts.map +1 -0
- package/dist/services/github/GithubAppService.js +187 -0
- package/dist/services/github/GithubAppService.js.map +1 -0
- package/dist/services/github/IssueService.d.ts +65 -0
- package/dist/services/github/IssueService.d.ts.map +1 -0
- package/dist/services/github/IssueService.js +231 -0
- package/dist/services/github/IssueService.js.map +1 -0
- package/dist/services/github/LabelService.d.ts +36 -0
- package/dist/services/github/LabelService.d.ts.map +1 -0
- package/dist/services/github/LabelService.js +122 -0
- package/dist/services/github/LabelService.js.map +1 -0
- package/dist/services/github/PRService.d.ts +77 -0
- package/dist/services/github/PRService.d.ts.map +1 -0
- package/dist/services/github/PRService.js +287 -0
- package/dist/services/github/PRService.js.map +1 -0
- package/dist/services/github/ProjectService.d.ts +144 -0
- package/dist/services/github/ProjectService.d.ts.map +1 -0
- package/dist/services/github/ProjectService.js +804 -0
- package/dist/services/github/ProjectService.js.map +1 -0
- package/dist/services/hooks/HookExecutor.d.ts +66 -0
- package/dist/services/hooks/HookExecutor.d.ts.map +1 -0
- package/dist/services/hooks/HookExecutor.js +227 -0
- package/dist/services/hooks/HookExecutor.js.map +1 -0
- package/dist/services/hooks/index.d.ts +2 -0
- package/dist/services/hooks/index.d.ts.map +1 -0
- package/dist/services/hooks/index.js +2 -0
- package/dist/services/hooks/index.js.map +1 -0
- package/dist/services/logs/LogFormatterService.d.ts +17 -0
- package/dist/services/logs/LogFormatterService.d.ts.map +1 -0
- package/dist/services/logs/LogFormatterService.js +35 -0
- package/dist/services/logs/LogFormatterService.js.map +1 -0
- package/dist/services/logs/TempFileService.d.ts +27 -0
- package/dist/services/logs/TempFileService.d.ts.map +1 -0
- package/dist/services/logs/TempFileService.js +90 -0
- package/dist/services/logs/TempFileService.js.map +1 -0
- package/dist/services/logs/index.d.ts +3 -0
- package/dist/services/logs/index.d.ts.map +1 -0
- package/dist/services/logs/index.js +4 -0
- package/dist/services/logs/index.js.map +1 -0
- package/dist/services/plan/PlanService.d.ts +70 -0
- package/dist/services/plan/PlanService.d.ts.map +1 -0
- package/dist/services/plan/PlanService.js +211 -0
- package/dist/services/plan/PlanService.js.map +1 -0
- package/dist/services/polling/GitHubDirectPollingAdapter.d.ts +16 -0
- package/dist/services/polling/GitHubDirectPollingAdapter.d.ts.map +1 -0
- package/dist/services/polling/GitHubDirectPollingAdapter.js +87 -0
- package/dist/services/polling/GitHubDirectPollingAdapter.js.map +1 -0
- package/dist/services/polling/HulaServerPollingAdapter.d.ts +23 -0
- package/dist/services/polling/HulaServerPollingAdapter.d.ts.map +1 -0
- package/dist/services/polling/HulaServerPollingAdapter.js +78 -0
- package/dist/services/polling/HulaServerPollingAdapter.js.map +1 -0
- package/dist/services/polling/IStatusPollingAdapter.d.ts +29 -0
- package/dist/services/polling/IStatusPollingAdapter.d.ts.map +1 -0
- package/dist/services/polling/IStatusPollingAdapter.js +2 -0
- package/dist/services/polling/IStatusPollingAdapter.js.map +1 -0
- package/dist/services/polling/StatusPollingAdapterFactory.d.ts +14 -0
- package/dist/services/polling/StatusPollingAdapterFactory.d.ts.map +1 -0
- package/dist/services/polling/StatusPollingAdapterFactory.js +41 -0
- package/dist/services/polling/StatusPollingAdapterFactory.js.map +1 -0
- package/dist/services/polling/index.d.ts +5 -0
- package/dist/services/polling/index.d.ts.map +1 -0
- package/dist/services/polling/index.js +5 -0
- package/dist/services/polling/index.js.map +1 -0
- package/dist/services/preview/PreviewService.d.ts +86 -0
- package/dist/services/preview/PreviewService.d.ts.map +1 -0
- package/dist/services/preview/PreviewService.js +439 -0
- package/dist/services/preview/PreviewService.js.map +1 -0
- package/dist/services/tracking/ProjectTrackingAdapter.d.ts +41 -0
- package/dist/services/tracking/ProjectTrackingAdapter.d.ts.map +1 -0
- package/dist/services/tracking/ProjectTrackingAdapter.js +230 -0
- package/dist/services/tracking/ProjectTrackingAdapter.js.map +1 -0
- package/dist/services/tracking/RemoteTrackingAdapter.d.ts +62 -0
- package/dist/services/tracking/RemoteTrackingAdapter.d.ts.map +1 -0
- package/dist/services/tracking/RemoteTrackingAdapter.js +242 -0
- package/dist/services/tracking/RemoteTrackingAdapter.js.map +1 -0
- package/dist/services/tracking/TrackingAdapterFactory.d.ts +25 -0
- package/dist/services/tracking/TrackingAdapterFactory.d.ts.map +1 -0
- package/dist/services/tracking/TrackingAdapterFactory.js +55 -0
- package/dist/services/tracking/TrackingAdapterFactory.js.map +1 -0
- package/dist/services/tracking/TrackingService.d.ts +104 -0
- package/dist/services/tracking/TrackingService.d.ts.map +1 -0
- package/dist/services/tracking/TrackingService.js +256 -0
- package/dist/services/tracking/TrackingService.js.map +1 -0
- package/dist/services/tracking/UntrackedIssuesService.d.ts +20 -0
- package/dist/services/tracking/UntrackedIssuesService.d.ts.map +1 -0
- package/dist/services/tracking/UntrackedIssuesService.js +148 -0
- package/dist/services/tracking/UntrackedIssuesService.js.map +1 -0
- package/dist/services/tracking/local-file-migration.d.ts +16 -0
- package/dist/services/tracking/local-file-migration.d.ts.map +1 -0
- package/dist/services/tracking/local-file-migration.js +86 -0
- package/dist/services/tracking/local-file-migration.js.map +1 -0
- package/dist/templates/planning-instructions.md +752 -0
- package/dist/templates/proceed-instructions.md +453 -0
- package/dist/templates/scripts/hula-fix-commit.sh +110 -0
- package/dist/templates/scripts/hula-fix-setup.sh +145 -0
- package/dist/templates/scripts/hula-launch-run.sh +89 -0
- package/dist/templates/scripts/hula-merge-local.sh +138 -0
- package/dist/templates/scripts/hula-merge-remote.sh +74 -0
- package/dist/templates/scripts/hula-read-config.sh +38 -0
- package/dist/templates/scripts/hula-verify-gather.sh +135 -0
- package/dist/templates/scripts/hula-verify-post.sh +84 -0
- package/dist/templates/skills/hula-confirm/SKILL.md +361 -0
- package/dist/templates/skills/hula-create/SKILL.md +211 -0
- package/dist/templates/skills/hula-fix/SKILL.md +224 -0
- package/dist/templates/skills/hula-launch/SKILL.md +159 -0
- package/dist/templates/skills/hula-log/SKILL.md +105 -0
- package/dist/templates/skills/hula-merge/SKILL.md +387 -0
- package/dist/templates/skills/hula-plan/SKILL.md +148 -0
- package/dist/templates/skills/hula-upload/SKILL.md +115 -0
- package/dist/templates/skills/hula-verify/SKILL.md +754 -0
- package/dist/types/common.schema.d.ts +46 -0
- package/dist/types/common.schema.d.ts.map +1 -0
- package/dist/types/common.schema.js +60 -0
- package/dist/types/common.schema.js.map +1 -0
- package/dist/types/config.schema.d.ts +443 -0
- package/dist/types/config.schema.d.ts.map +1 -0
- package/dist/types/config.schema.js +126 -0
- package/dist/types/config.schema.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/issue.schema.d.ts +136 -0
- package/dist/types/issue.schema.d.ts.map +1 -0
- package/dist/types/issue.schema.js +49 -0
- package/dist/types/issue.schema.js.map +1 -0
- package/dist/types/pr.schema.d.ts +118 -0
- package/dist/types/pr.schema.d.ts.map +1 -0
- package/dist/types/pr.schema.js +40 -0
- package/dist/types/pr.schema.js.map +1 -0
- package/dist/types/tracking.schema.d.ts +340 -0
- package/dist/types/tracking.schema.d.ts.map +1 -0
- package/dist/types/tracking.schema.js +56 -0
- package/dist/types/tracking.schema.js.map +1 -0
- package/dist/utils/browser-launcher.d.ts +60 -0
- package/dist/utils/browser-launcher.d.ts.map +1 -0
- package/dist/utils/browser-launcher.js +263 -0
- package/dist/utils/browser-launcher.js.map +1 -0
- package/dist/utils/cache.d.ts +44 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +94 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/config-parser.d.ts +16 -0
- package/dist/utils/config-parser.d.ts.map +1 -0
- package/dist/utils/config-parser.js +210 -0
- package/dist/utils/config-parser.js.map +1 -0
- package/dist/utils/editor.d.ts +21 -0
- package/dist/utils/editor.d.ts.map +1 -0
- package/dist/utils/editor.js +213 -0
- package/dist/utils/editor.js.map +1 -0
- package/dist/utils/git-utils.d.ts +5 -0
- package/dist/utils/git-utils.d.ts.map +1 -0
- package/dist/utils/git-utils.js +18 -0
- package/dist/utils/git-utils.js.map +1 -0
- package/dist/utils/github-cli.d.ts +62 -0
- package/dist/utils/github-cli.d.ts.map +1 -0
- package/dist/utils/github-cli.js +492 -0
- package/dist/utils/github-cli.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +118 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/open-url.d.ts +19 -0
- package/dist/utils/open-url.d.ts.map +1 -0
- package/dist/utils/open-url.js +37 -0
- package/dist/utils/open-url.js.map +1 -0
- package/dist/utils/project-resolver.d.ts +13 -0
- package/dist/utils/project-resolver.d.ts.map +1 -0
- package/dist/utils/project-resolver.js +35 -0
- package/dist/utils/project-resolver.js.map +1 -0
- package/dist/utils/prompts.d.ts +80 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +326 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/shell.d.ts +54 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +152 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/validators.d.ts +32 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +64 -0
- package/dist/utils/validators.js.map +1 -0
- 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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB;IAElB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,wDAAwD;QACxD,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QACjD,MAAM,SAAS,GAAG,GAAG,SAAS,UAAU,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAG5C,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,YAAY,CAAC,OAAO;YAClC,YAAY,CAAC,MAAM;YACnB,YAAY,CAAwB,CAAC;QAEvC,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,WAAW,EAAE,CAAC;QACrB,iDAAiD;QACjD,OAAO,CAAC,MAAM,CAAC,6CAA6C,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,CACV,0BACE,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CACzE,EAAE,CACH,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,CAAC,OAAO,CACZ,6EAA6E,CAC9E,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV,oCACE,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CACnE,EAAE,CACH,CAAC;YACF,MAAM,CAAC,OAAO,CACZ,mEAAmE,CACpE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAe;IAEf,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,qBAAqB;IACrB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpE,IAAI,WAAW,EAAE,CAAC;QAChB,SAAS,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,0BAA0B;IAC1B,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CACrC,qCAAqC,CACtC,CAAC;IACF,IAAI,iBAAiB,EAAE,CAAC;QACtB,SAAS,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,wBAAwB;IACxB,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CACnC,mCAAmC,CACpC,CAAC;IACF,IAAI,eAAe,EAAE,CAAC;QACpB,SAAS,CAAC,aAAa,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC/D,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,yBAAyB;IACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACrE,IAAI,QAAQ,EAAE,CAAC;QACb,SAAS,CAAC,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,kEAAkE;IAClE,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,mEAAmE;YACjE,oEAAoE,CACvE,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACnE,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,wBAAwB;IACxB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvE,IAAI,WAAW,EAAE,CAAC;QAChB,SAAS,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,mBAAmB;IACnB,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpE,IAAI,aAAa,EAAE,CAAC;QAClB,SAAS,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,uBAAuB;IACvB,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACxE,IAAI,aAAa,EAAE,CAAC;QAClB,SAAS,CAAC,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,iCAAiC;IACjC,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CACrC,4CAA4C,CAC7C,CAAC;IACF,IAAI,iBAAiB,EAAE,CAAC;QACtB,SAAS,CAAC,sBAAsB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC/D,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,wCAAwC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACvE,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;IAC1D,CAAC;IAED,4BAA4B;IAC5B,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACxE,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACzC,yBAAyB;YACzB,MAAM,OAAO,GAAG,YAAY,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACzD,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACvE,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAwB,EAAE,CAAC;QAEzC,kCAAkC;QAClC,MAAM,SAAS,GAAG,eAAe,EAAE,KAAK,CACtC,oDAAoD,CACrD,CAAC;QACF,IAAI,SAAS,EAAE,CAAC;YACd,QAAQ,CAAC,cAAc,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAChC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjE,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,KAAK,GAA2B,EAAE,CAAC;QAEzC,4BAA4B;QAC5B,MAAM,WAAW,GAAG,YAAY,EAAE,KAAK,CACrC,uCAAuC,CACxC,CAAC;QACF,IAAI,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,iBAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAChF,IAAI,iBAAiB,EAAE,CAAC;QACtB,SAAS,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,0BAA0B;IAC1B,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC1E,IAAI,YAAY,EAAE,CAAC;QACjB,SAAS,CAAC,eAAe,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,oCAAoC;IACpC,MAAM,uBAAuB,GAAG,OAAO,CAAC,KAAK,CAC3C,mCAAmC,CACpC,CAAC;IACF,IAAI,uBAAuB,IAAI,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,SAAS,GAAqD,EAAE,CAAC;QACvE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACxD,IAAI,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS,CAAC,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC9D,IAAI,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC;YAAE,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnF,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC;YAAE,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,SAAS,CAAC,kBAAkB,GAAG,SAAS,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA6C,EAC7C,SAA8B;IAE9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,GAAG,SAAS;QACZ,GAAG,QAAQ;QACX,gCAAgC;QAChC,QAAQ,EAAE;YACR,GAAG,SAAS,CAAC,QAAQ;YACrB,GAAG,QAAQ,CAAC,QAAQ;SACrB;QACD,KAAK,EAAE;YACL,GAAG,SAAS,CAAC,KAAK;YAClB,GAAG,QAAQ,CAAC,KAAK;SAClB;KACF,CAAC;AACJ,CAAC"}
|