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