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,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for WorktreeService
|
|
3
|
+
*/
|
|
4
|
+
export interface WorktreeConfig {
|
|
5
|
+
/** Base directory for worktrees, e.g. '.hula-worktrees' */
|
|
6
|
+
basePath: string;
|
|
7
|
+
/** Repository name, e.g. 'hub-launch' */
|
|
8
|
+
repoName: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Service for Git worktree operations
|
|
12
|
+
* Single Responsibility: Temporary worktree management for plan and fix isolation
|
|
13
|
+
*/
|
|
14
|
+
export declare class WorktreeService {
|
|
15
|
+
/** Legacy hardcoded worktree directory for backwards compatibility */
|
|
16
|
+
private readonly WORKTREE_DIR;
|
|
17
|
+
private readonly FIX_WORKTREE_PREFIX;
|
|
18
|
+
private readonly basePath;
|
|
19
|
+
private readonly repoName;
|
|
20
|
+
constructor(config?: WorktreeConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Get the worktree directory path for a given type and identifier.
|
|
23
|
+
* Format: <basePath>/hula/<repoName>/<type>-<identifier>
|
|
24
|
+
*/
|
|
25
|
+
getWorktreeDir(type: string, identifier: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Validate a path segment to prevent command injection.
|
|
28
|
+
* Uses a blocklist of known dangerous characters including newlines and null bytes.
|
|
29
|
+
*/
|
|
30
|
+
private validatePathSegment;
|
|
31
|
+
/**
|
|
32
|
+
* Create a generic worktree at the given path from a specified branch.
|
|
33
|
+
* @param worktreePath - Absolute path for the new worktree
|
|
34
|
+
* @param branch - Branch name or ref to check out (e.g. 'origin/main', 'fix/issue-42')
|
|
35
|
+
* @param detached - If true, creates a detached HEAD worktree
|
|
36
|
+
* @returns The resolved worktree path
|
|
37
|
+
*/
|
|
38
|
+
createWorktreeAt(worktreePath: string, branch: string, detached?: boolean): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Check whether a worktree exists at the given path.
|
|
41
|
+
*/
|
|
42
|
+
worktreeExistsAt(worktreePath: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Remove the worktree at the given path.
|
|
45
|
+
*/
|
|
46
|
+
removeWorktreeAt(worktreePath: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if there are uncommitted changes in a worktree at the given path.
|
|
49
|
+
*/
|
|
50
|
+
hasChangesAt(worktreePath: string): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Stage and commit all changes in the worktree at the given path.
|
|
53
|
+
*/
|
|
54
|
+
commitChangesAt(worktreePath: string, message: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Push the current branch in the worktree at the given path.
|
|
57
|
+
*/
|
|
58
|
+
pushAt(worktreePath: string, branch: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* List all active hula worktrees (paths containing '/hula/').
|
|
61
|
+
*/
|
|
62
|
+
listHulaWorktrees(): Promise<string[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Validate worktree directory name to prevent command injection
|
|
65
|
+
*/
|
|
66
|
+
private validateWorktreeDirName;
|
|
67
|
+
/**
|
|
68
|
+
* Validate branch name to prevent command injection
|
|
69
|
+
*/
|
|
70
|
+
private validateBranchName;
|
|
71
|
+
/**
|
|
72
|
+
* Get the repository name from the git root directory
|
|
73
|
+
*/
|
|
74
|
+
getRepoName(): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Get the directory path for a fix worktree
|
|
77
|
+
* Returns: <basePath>/hula/<repoName>/fix-<issueNumber>
|
|
78
|
+
*/
|
|
79
|
+
getFixWorktreeDir(issueNumber: number): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Create a fix worktree for the given PR branch and issue number
|
|
82
|
+
* @param branchName - The PR branch name to check out in the worktree
|
|
83
|
+
* @param issueNumber - The issue number (used for directory naming)
|
|
84
|
+
* @returns Absolute path to the created worktree
|
|
85
|
+
*/
|
|
86
|
+
createFixWorktree(branchName: string, issueNumber: number): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Find any existing fix worktree by scanning git worktree list.
|
|
89
|
+
* Matches both new convention (fix-<N>) and legacy convention (<repo>-fix-<N>).
|
|
90
|
+
* @returns Object with path and issueNumber, or null if none found
|
|
91
|
+
*/
|
|
92
|
+
getAnyFixWorktree(): Promise<{
|
|
93
|
+
path: string;
|
|
94
|
+
issueNumber: number;
|
|
95
|
+
} | null>;
|
|
96
|
+
/**
|
|
97
|
+
* Check if a fix worktree exists for the given issue number
|
|
98
|
+
*/
|
|
99
|
+
fixWorktreeExists(issueNumber: number): Promise<boolean>;
|
|
100
|
+
/**
|
|
101
|
+
* Get the path to a fix worktree for the given issue number
|
|
102
|
+
* @returns Absolute path to the worktree, or null if not found
|
|
103
|
+
*/
|
|
104
|
+
getFixWorktreePath(issueNumber: number): Promise<string | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Remove the fix worktree for the given issue number
|
|
107
|
+
*/
|
|
108
|
+
removeFixWorktree(issueNumber: number): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Commit and push changes in the fix worktree
|
|
111
|
+
*/
|
|
112
|
+
commitAndPushFixWorktree(issueNumber: number, message: string): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Create a temporary worktree off origin/main
|
|
115
|
+
* @returns Path to the worktree directory
|
|
116
|
+
*/
|
|
117
|
+
createPlanWorktree(): Promise<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Check if a plan worktree exists
|
|
120
|
+
*/
|
|
121
|
+
worktreeExists(): Promise<boolean>;
|
|
122
|
+
/**
|
|
123
|
+
* Get the path to existing worktree
|
|
124
|
+
*/
|
|
125
|
+
getWorktreePath(): Promise<string | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Remove the worktree after upload
|
|
128
|
+
*/
|
|
129
|
+
removeWorktree(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Check if there are uncommitted changes in worktree
|
|
132
|
+
*/
|
|
133
|
+
hasWorktreeChanges(): Promise<boolean>;
|
|
134
|
+
/**
|
|
135
|
+
* Commit changes in the worktree
|
|
136
|
+
*/
|
|
137
|
+
commitWorktreeChanges(message: string): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Get the HEAD ref (commit SHA) of the worktree
|
|
140
|
+
* Used when merging worktree changes into main
|
|
141
|
+
*/
|
|
142
|
+
getHeadRef(): Promise<string>;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=WorktreeService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreeService.d.ts","sourceRoot":"","sources":["../../../src/services/git/WorktreeService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
import { basename, resolve } from 'path';
|
|
2
|
+
import { runCommand } from '../../utils/shell.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* Service for Git worktree operations
|
|
6
|
+
* Single Responsibility: Temporary worktree management for plan and fix isolation
|
|
7
|
+
*/
|
|
8
|
+
export class WorktreeService {
|
|
9
|
+
/** Legacy hardcoded worktree directory for backwards compatibility */
|
|
10
|
+
WORKTREE_DIR = '.hula-plan-worktree';
|
|
11
|
+
FIX_WORKTREE_PREFIX = '-fix-';
|
|
12
|
+
basePath;
|
|
13
|
+
repoName;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.basePath = config?.basePath ?? '.hula-worktrees';
|
|
16
|
+
this.repoName = config?.repoName ?? '';
|
|
17
|
+
}
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Generic parameterized worktree methods
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Get the worktree directory path for a given type and identifier.
|
|
23
|
+
* Format: <basePath>/hula/<repoName>/<type>-<identifier>
|
|
24
|
+
*/
|
|
25
|
+
getWorktreeDir(type, identifier) {
|
|
26
|
+
return `${this.basePath}/hula/${this.repoName}/${type}-${identifier}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate a path segment to prevent command injection.
|
|
30
|
+
* Uses a blocklist of known dangerous characters including newlines and null bytes.
|
|
31
|
+
*/
|
|
32
|
+
validatePathSegment(segment, label) {
|
|
33
|
+
if (segment.includes(';') ||
|
|
34
|
+
segment.includes('|') ||
|
|
35
|
+
segment.includes('&') ||
|
|
36
|
+
segment.includes('$') ||
|
|
37
|
+
segment.includes('`') ||
|
|
38
|
+
segment.includes('\\') ||
|
|
39
|
+
segment.includes('..') ||
|
|
40
|
+
segment.includes('\n') ||
|
|
41
|
+
segment.includes('\r') ||
|
|
42
|
+
segment.includes('\0') ||
|
|
43
|
+
segment.trim() === '') {
|
|
44
|
+
throw new Error(`Invalid ${label}: "${segment}"`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a generic worktree at the given path from a specified branch.
|
|
49
|
+
* @param worktreePath - Absolute path for the new worktree
|
|
50
|
+
* @param branch - Branch name or ref to check out (e.g. 'origin/main', 'fix/issue-42')
|
|
51
|
+
* @param detached - If true, creates a detached HEAD worktree
|
|
52
|
+
* @returns The resolved worktree path
|
|
53
|
+
*/
|
|
54
|
+
async createWorktreeAt(worktreePath, branch, detached = false) {
|
|
55
|
+
this.validatePathSegment(worktreePath, 'worktree path');
|
|
56
|
+
this.validatePathSegment(branch, 'branch');
|
|
57
|
+
logger.debug(`Creating worktree at: ${worktreePath} (branch: ${branch})`);
|
|
58
|
+
try {
|
|
59
|
+
// Fetch latest remote state
|
|
60
|
+
await runCommand('git fetch origin');
|
|
61
|
+
// Check if worktree already exists
|
|
62
|
+
if (await this.worktreeExistsAt(worktreePath)) {
|
|
63
|
+
logger.debug(`Worktree already exists at: ${worktreePath}`);
|
|
64
|
+
return worktreePath;
|
|
65
|
+
}
|
|
66
|
+
const detachedFlag = detached ? ' --detach' : '';
|
|
67
|
+
await runCommand(`git worktree add ${JSON.stringify(worktreePath)} ${JSON.stringify(branch)}${detachedFlag}`);
|
|
68
|
+
logger.debug(`Successfully created worktree at: ${worktreePath}`);
|
|
69
|
+
return worktreePath;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw new Error(`Failed to create worktree at ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check whether a worktree exists at the given path.
|
|
77
|
+
*/
|
|
78
|
+
async worktreeExistsAt(worktreePath) {
|
|
79
|
+
try {
|
|
80
|
+
const output = await runCommand('git worktree list --porcelain', {
|
|
81
|
+
silent: true,
|
|
82
|
+
});
|
|
83
|
+
const lines = output.split('\n');
|
|
84
|
+
return lines.some(line => line === `worktree ${worktreePath}`);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Remove the worktree at the given path.
|
|
92
|
+
*/
|
|
93
|
+
async removeWorktreeAt(worktreePath) {
|
|
94
|
+
this.validatePathSegment(worktreePath, 'worktree path');
|
|
95
|
+
logger.debug(`Removing worktree at: ${worktreePath}`);
|
|
96
|
+
try {
|
|
97
|
+
const exists = await this.worktreeExistsAt(worktreePath);
|
|
98
|
+
if (!exists) {
|
|
99
|
+
logger.debug(`No worktree found at: ${worktreePath}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
await runCommand(`git worktree remove ${JSON.stringify(worktreePath)} --force`);
|
|
103
|
+
logger.debug(`Successfully removed worktree at: ${worktreePath}`);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw new Error(`Failed to remove worktree at ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if there are uncommitted changes in a worktree at the given path.
|
|
111
|
+
*/
|
|
112
|
+
async hasChangesAt(worktreePath) {
|
|
113
|
+
try {
|
|
114
|
+
const status = await runCommand('git status --porcelain', {
|
|
115
|
+
cwd: worktreePath,
|
|
116
|
+
silent: true,
|
|
117
|
+
});
|
|
118
|
+
return status.trim() !== '';
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
logger.debug(`Failed to check worktree status at ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Stage and commit all changes in the worktree at the given path.
|
|
127
|
+
*/
|
|
128
|
+
async commitChangesAt(worktreePath, message) {
|
|
129
|
+
logger.debug(`Committing changes in worktree at: ${worktreePath}`);
|
|
130
|
+
try {
|
|
131
|
+
await runCommand('git add .', { cwd: worktreePath });
|
|
132
|
+
await runCommand(`git commit -m ${JSON.stringify(message)}`, {
|
|
133
|
+
cwd: worktreePath,
|
|
134
|
+
});
|
|
135
|
+
logger.debug(`Successfully committed changes at: ${worktreePath}`);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to commit changes at ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Push the current branch in the worktree at the given path.
|
|
143
|
+
*/
|
|
144
|
+
async pushAt(worktreePath, branch) {
|
|
145
|
+
this.validatePathSegment(worktreePath, 'worktree path');
|
|
146
|
+
this.validatePathSegment(branch, 'branch refspec');
|
|
147
|
+
logger.debug(`Pushing branch ${branch} from worktree at: ${worktreePath}`);
|
|
148
|
+
try {
|
|
149
|
+
await runCommand(`git push origin ${JSON.stringify(branch)} --no-verify`, {
|
|
150
|
+
cwd: worktreePath,
|
|
151
|
+
});
|
|
152
|
+
logger.debug(`Successfully pushed from worktree at: ${worktreePath}`);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new Error(`Failed to push from worktree at ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* List all active hula worktrees (paths containing '/hula/').
|
|
160
|
+
*/
|
|
161
|
+
async listHulaWorktrees() {
|
|
162
|
+
try {
|
|
163
|
+
const output = await runCommand('git worktree list --porcelain', {
|
|
164
|
+
silent: true,
|
|
165
|
+
});
|
|
166
|
+
const paths = [];
|
|
167
|
+
const lines = output.split('\n');
|
|
168
|
+
for (const line of lines) {
|
|
169
|
+
if (line.startsWith('worktree ')) {
|
|
170
|
+
const path = line.substring('worktree '.length).trim();
|
|
171
|
+
if (path.includes('/hula/')) {
|
|
172
|
+
paths.push(path);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return paths;
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Legacy plan-worktree methods (backwards compatibility)
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
/**
|
|
186
|
+
* Validate worktree directory name to prevent command injection
|
|
187
|
+
*/
|
|
188
|
+
validateWorktreeDirName() {
|
|
189
|
+
if (this.WORKTREE_DIR.includes(';') ||
|
|
190
|
+
this.WORKTREE_DIR.includes('|') ||
|
|
191
|
+
this.WORKTREE_DIR.includes('&') ||
|
|
192
|
+
this.WORKTREE_DIR.includes('$') ||
|
|
193
|
+
this.WORKTREE_DIR.includes('`') ||
|
|
194
|
+
this.WORKTREE_DIR.includes('\\')) {
|
|
195
|
+
throw new Error('Invalid worktree directory name');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Validate branch name to prevent command injection
|
|
200
|
+
*/
|
|
201
|
+
validateBranchName(branch) {
|
|
202
|
+
if (branch.includes(';') ||
|
|
203
|
+
branch.includes('|') ||
|
|
204
|
+
branch.includes('&') ||
|
|
205
|
+
branch.includes('$') ||
|
|
206
|
+
branch.includes('`') ||
|
|
207
|
+
branch.includes('\\') ||
|
|
208
|
+
branch.includes(' ') ||
|
|
209
|
+
branch.includes('\n') ||
|
|
210
|
+
branch.includes('\r')) {
|
|
211
|
+
throw new Error(`Invalid branch name: ${branch}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get the repository name from the git root directory
|
|
216
|
+
*/
|
|
217
|
+
async getRepoName() {
|
|
218
|
+
const root = await runCommand('git rev-parse --show-toplevel', {
|
|
219
|
+
silent: true,
|
|
220
|
+
});
|
|
221
|
+
return basename(root.trim());
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get the directory path for a fix worktree
|
|
225
|
+
* Returns: <basePath>/hula/<repoName>/fix-<issueNumber>
|
|
226
|
+
*/
|
|
227
|
+
async getFixWorktreeDir(issueNumber) {
|
|
228
|
+
const repoName = this.repoName || await this.getRepoName();
|
|
229
|
+
return `${this.basePath}/hula/${repoName}/fix-${issueNumber}`;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create a fix worktree for the given PR branch and issue number
|
|
233
|
+
* @param branchName - The PR branch name to check out in the worktree
|
|
234
|
+
* @param issueNumber - The issue number (used for directory naming)
|
|
235
|
+
* @returns Absolute path to the created worktree
|
|
236
|
+
*/
|
|
237
|
+
async createFixWorktree(branchName, issueNumber) {
|
|
238
|
+
this.validateBranchName(branchName);
|
|
239
|
+
logger.debug(`Creating fix worktree for branch ${branchName}, issue #${issueNumber}`);
|
|
240
|
+
try {
|
|
241
|
+
// Fetch the branch from origin
|
|
242
|
+
await runCommand(`git fetch origin ${branchName}`);
|
|
243
|
+
const dirName = await this.getFixWorktreeDir(issueNumber);
|
|
244
|
+
// Check if any fix worktree already exists
|
|
245
|
+
const existingFixWorktree = await this.getAnyFixWorktree();
|
|
246
|
+
if (existingFixWorktree &&
|
|
247
|
+
existingFixWorktree.issueNumber !== issueNumber) {
|
|
248
|
+
throw new Error(`A fix worktree already exists for issue #${existingFixWorktree.issueNumber} at ${existingFixWorktree.path}. ` +
|
|
249
|
+
`Remove it first with: git worktree remove ${existingFixWorktree.path} --force`);
|
|
250
|
+
}
|
|
251
|
+
// If worktree already exists for this issue, return existing path
|
|
252
|
+
if (existingFixWorktree) {
|
|
253
|
+
logger.debug(`Fix worktree already exists at: ${existingFixWorktree.path}`);
|
|
254
|
+
return existingFixWorktree.path;
|
|
255
|
+
}
|
|
256
|
+
// Create worktree on the PR branch (not detached — use actual branch)
|
|
257
|
+
await runCommand(`git worktree add ${JSON.stringify(dirName)} ${JSON.stringify(branchName)}`);
|
|
258
|
+
const resolvedPath = resolve(process.cwd(), dirName);
|
|
259
|
+
logger.debug(`Successfully created fix worktree at: ${resolvedPath}`);
|
|
260
|
+
return resolvedPath;
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
throw new Error(`Failed to create fix worktree: ${error instanceof Error ? error.message : String(error)}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Find any existing fix worktree by scanning git worktree list.
|
|
268
|
+
* Matches both new convention (fix-<N>) and legacy convention (<repo>-fix-<N>).
|
|
269
|
+
* @returns Object with path and issueNumber, or null if none found
|
|
270
|
+
*/
|
|
271
|
+
async getAnyFixWorktree() {
|
|
272
|
+
try {
|
|
273
|
+
const output = await runCommand('git worktree list --porcelain', {
|
|
274
|
+
silent: true,
|
|
275
|
+
});
|
|
276
|
+
const lines = output.split('\n');
|
|
277
|
+
for (let i = 0; i < lines.length; i++) {
|
|
278
|
+
const line = lines[i];
|
|
279
|
+
if (line && line.startsWith('worktree ')) {
|
|
280
|
+
const worktreePath = line.substring('worktree '.length).trim();
|
|
281
|
+
const dirBasename = basename(worktreePath);
|
|
282
|
+
// Match new convention: fix-<N> (only if path contains /hula/)
|
|
283
|
+
const fixMatch = dirBasename.match(/^fix-(\d+)$/);
|
|
284
|
+
if (fixMatch && fixMatch[1] && worktreePath.includes('/hula/')) {
|
|
285
|
+
return { path: worktreePath, issueNumber: parseInt(fixMatch[1], 10) };
|
|
286
|
+
}
|
|
287
|
+
// Match legacy convention: <repo>-fix-<N>
|
|
288
|
+
const legacyFixIndex = dirBasename.indexOf(this.FIX_WORKTREE_PREFIX);
|
|
289
|
+
if (legacyFixIndex !== -1) {
|
|
290
|
+
const suffix = dirBasename.substring(legacyFixIndex + this.FIX_WORKTREE_PREFIX.length);
|
|
291
|
+
const issueNumber = parseInt(suffix, 10);
|
|
292
|
+
if (!isNaN(issueNumber) && String(issueNumber) === suffix) {
|
|
293
|
+
return { path: worktreePath, issueNumber };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Check if a fix worktree exists for the given issue number
|
|
306
|
+
*/
|
|
307
|
+
async fixWorktreeExists(issueNumber) {
|
|
308
|
+
const existing = await this.getAnyFixWorktree();
|
|
309
|
+
return existing !== null && existing.issueNumber === issueNumber;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get the path to a fix worktree for the given issue number
|
|
313
|
+
* @returns Absolute path to the worktree, or null if not found
|
|
314
|
+
*/
|
|
315
|
+
async getFixWorktreePath(issueNumber) {
|
|
316
|
+
const existing = await this.getAnyFixWorktree();
|
|
317
|
+
if (existing && existing.issueNumber === issueNumber) {
|
|
318
|
+
return existing.path;
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Remove the fix worktree for the given issue number
|
|
324
|
+
*/
|
|
325
|
+
async removeFixWorktree(issueNumber) {
|
|
326
|
+
logger.debug(`Removing fix worktree for issue #${issueNumber}`);
|
|
327
|
+
try {
|
|
328
|
+
const path = await this.getFixWorktreePath(issueNumber);
|
|
329
|
+
if (!path) {
|
|
330
|
+
logger.debug('No fix worktree to remove');
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
await runCommand(`git worktree remove ${JSON.stringify(path)} --force`);
|
|
334
|
+
logger.debug('Successfully removed fix worktree');
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
throw new Error(`Failed to remove fix worktree: ${error instanceof Error ? error.message : String(error)}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Commit and push changes in the fix worktree
|
|
342
|
+
*/
|
|
343
|
+
async commitAndPushFixWorktree(issueNumber, message) {
|
|
344
|
+
logger.debug(`Committing and pushing fix worktree changes for issue #${issueNumber}`);
|
|
345
|
+
try {
|
|
346
|
+
const path = await this.getFixWorktreePath(issueNumber);
|
|
347
|
+
if (!path) {
|
|
348
|
+
throw new Error(`No fix worktree found for issue #${issueNumber}`);
|
|
349
|
+
}
|
|
350
|
+
await runCommand('git add -A', { cwd: path });
|
|
351
|
+
await runCommand(`git commit -m ${JSON.stringify(message)}`, {
|
|
352
|
+
cwd: path,
|
|
353
|
+
});
|
|
354
|
+
await runCommand('git push', { cwd: path });
|
|
355
|
+
logger.debug('Successfully committed and pushed fix worktree changes');
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
throw new Error(`Failed to commit and push fix worktree: ${error instanceof Error ? error.message : String(error)}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Create a temporary worktree off origin/main
|
|
363
|
+
* @returns Path to the worktree directory
|
|
364
|
+
*/
|
|
365
|
+
async createPlanWorktree() {
|
|
366
|
+
this.validateWorktreeDirName();
|
|
367
|
+
logger.debug('Creating plan worktree');
|
|
368
|
+
try {
|
|
369
|
+
// Fetch latest from origin/main
|
|
370
|
+
await runCommand('git fetch origin main');
|
|
371
|
+
// Check if worktree already exists
|
|
372
|
+
if (await this.worktreeExists()) {
|
|
373
|
+
const path = await this.getWorktreePath();
|
|
374
|
+
logger.debug(`Worktree already exists at: ${path}`);
|
|
375
|
+
return path;
|
|
376
|
+
}
|
|
377
|
+
// Create worktree in detached HEAD mode off origin/main
|
|
378
|
+
await runCommand(`git worktree add ${this.WORKTREE_DIR} origin/main --detach`);
|
|
379
|
+
const path = await this.getWorktreePath();
|
|
380
|
+
logger.debug(`Successfully created worktree at: ${path}`);
|
|
381
|
+
return path;
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
throw new Error(`Failed to create worktree: ${error instanceof Error ? error.message : String(error)}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Check if a plan worktree exists
|
|
389
|
+
*/
|
|
390
|
+
async worktreeExists() {
|
|
391
|
+
try {
|
|
392
|
+
const output = await runCommand('git worktree list --porcelain', {
|
|
393
|
+
silent: true,
|
|
394
|
+
});
|
|
395
|
+
return output.includes(this.WORKTREE_DIR);
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Get the path to existing worktree
|
|
403
|
+
*/
|
|
404
|
+
async getWorktreePath() {
|
|
405
|
+
try {
|
|
406
|
+
const output = await runCommand('git worktree list --porcelain', {
|
|
407
|
+
silent: true,
|
|
408
|
+
});
|
|
409
|
+
const lines = output.split('\n');
|
|
410
|
+
for (let i = 0; i < lines.length; i++) {
|
|
411
|
+
const line = lines[i];
|
|
412
|
+
if (line && line.startsWith('worktree ')) {
|
|
413
|
+
const path = line.substring('worktree '.length);
|
|
414
|
+
if (path.includes(this.WORKTREE_DIR)) {
|
|
415
|
+
return path;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Remove the worktree after upload
|
|
427
|
+
*/
|
|
428
|
+
async removeWorktree() {
|
|
429
|
+
this.validateWorktreeDirName();
|
|
430
|
+
logger.debug('Removing worktree');
|
|
431
|
+
try {
|
|
432
|
+
const path = await this.getWorktreePath();
|
|
433
|
+
if (!path) {
|
|
434
|
+
logger.debug('No worktree to remove');
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
await runCommand(`git worktree remove ${this.WORKTREE_DIR} --force`);
|
|
438
|
+
logger.debug('Successfully removed worktree');
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
throw new Error(`Failed to remove worktree: ${error instanceof Error ? error.message : String(error)}`);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Check if there are uncommitted changes in worktree
|
|
446
|
+
*/
|
|
447
|
+
async hasWorktreeChanges() {
|
|
448
|
+
try {
|
|
449
|
+
const path = await this.getWorktreePath();
|
|
450
|
+
if (!path) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
const status = await runCommand('git status --porcelain', {
|
|
454
|
+
cwd: path,
|
|
455
|
+
silent: true,
|
|
456
|
+
});
|
|
457
|
+
return status.trim() !== '';
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
logger.debug(`Failed to check worktree status: ${error instanceof Error ? error.message : String(error)}`);
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Commit changes in the worktree
|
|
466
|
+
*/
|
|
467
|
+
async commitWorktreeChanges(message) {
|
|
468
|
+
logger.debug(`Committing worktree changes: ${message}`);
|
|
469
|
+
try {
|
|
470
|
+
const path = await this.getWorktreePath();
|
|
471
|
+
if (!path) {
|
|
472
|
+
throw new Error('No worktree found');
|
|
473
|
+
}
|
|
474
|
+
// Add all changes
|
|
475
|
+
await runCommand('git add .', { cwd: path });
|
|
476
|
+
// Commit with properly escaped message
|
|
477
|
+
await runCommand(`git commit -m ${JSON.stringify(message)}`, { cwd: path });
|
|
478
|
+
logger.debug('Successfully committed worktree changes');
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
throw new Error(`Failed to commit worktree changes: ${error instanceof Error ? error.message : String(error)}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Get the HEAD ref (commit SHA) of the worktree
|
|
486
|
+
* Used when merging worktree changes into main
|
|
487
|
+
*/
|
|
488
|
+
async getHeadRef() {
|
|
489
|
+
try {
|
|
490
|
+
const path = await this.getWorktreePath();
|
|
491
|
+
if (!path) {
|
|
492
|
+
throw new Error('No worktree found');
|
|
493
|
+
}
|
|
494
|
+
const ref = await runCommand('git rev-parse HEAD', {
|
|
495
|
+
cwd: path,
|
|
496
|
+
silent: true,
|
|
497
|
+
});
|
|
498
|
+
return ref.trim();
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
throw new Error(`Failed to get worktree HEAD ref: ${error instanceof Error ? error.message : String(error)}`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
//# sourceMappingURL=WorktreeService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreeService.js","sourceRoot":"","sources":["../../../src/services/git/WorktreeService.ts"],"names":[],"mappings":"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"}
|