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,233 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* HTTP client for communicating with hula-project REST API.
|
|
4
|
+
* Handles authentication, retries, and error mapping.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const client = new HulaApiClient({
|
|
8
|
+
* baseUrl: 'https://hula.example.com',
|
|
9
|
+
* apiKey: 'hula_sk_...'
|
|
10
|
+
* });
|
|
11
|
+
* const plans = await client.listPlans();
|
|
12
|
+
*/
|
|
13
|
+
export class HulaApiClient {
|
|
14
|
+
client;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.client = axios.create({
|
|
17
|
+
baseURL: config.baseUrl,
|
|
18
|
+
timeout: config.timeout || 10000,
|
|
19
|
+
headers: {
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
// Response interceptor for error handling
|
|
25
|
+
this.client.interceptors.response.use((response) => response, async (error) => {
|
|
26
|
+
return this.handleError(error);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* List all tracked plans for authenticated user
|
|
31
|
+
*/
|
|
32
|
+
async listPlans(filters) {
|
|
33
|
+
const params = new URLSearchParams();
|
|
34
|
+
if (filters?.status)
|
|
35
|
+
params.set('trackingStatus', filters.status);
|
|
36
|
+
if (filters?.priority)
|
|
37
|
+
params.set('priority', filters.priority);
|
|
38
|
+
if (filters?.project)
|
|
39
|
+
params.set('project', filters.project);
|
|
40
|
+
if (filters?.page)
|
|
41
|
+
params.set('page', filters.page.toString());
|
|
42
|
+
if (filters?.limit)
|
|
43
|
+
params.set('limit', filters.limit.toString());
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.client.get('/api/v1/plans', { params });
|
|
46
|
+
return response.data;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
this.maybeRethrowAsIncompatibleServer(err);
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Track a new plan
|
|
55
|
+
*/
|
|
56
|
+
async trackPlan(data) {
|
|
57
|
+
try {
|
|
58
|
+
const response = await this.client.post('/api/v1/plans', data);
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
this.maybeRethrowAsIncompatibleServer(err);
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get detailed status for a specific plan
|
|
68
|
+
*/
|
|
69
|
+
async getPlanStatus(owner, repo, issueNumber) {
|
|
70
|
+
const response = await this.client.get(`/api/v1/plans/status/${owner}/${repo}/${issueNumber}`);
|
|
71
|
+
return response.data;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Update plan priority
|
|
75
|
+
*/
|
|
76
|
+
async updatePlanPriority(planId, priority) {
|
|
77
|
+
const response = await this.client.patch(`/api/v1/plans/${planId}`, {
|
|
78
|
+
priority,
|
|
79
|
+
});
|
|
80
|
+
return response.data;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Untrack a plan
|
|
84
|
+
*/
|
|
85
|
+
async untrackPlan(planId) {
|
|
86
|
+
const response = await this.client.delete(`/api/v1/plans/${planId}`);
|
|
87
|
+
return response.data;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fetch the latest Task's logs for a tracked plan (plain text).
|
|
91
|
+
* Calls GET /api/v1/logs/:planName.
|
|
92
|
+
*
|
|
93
|
+
* The URL string `/api/v1/logs/<name>` is preserved across the server
|
|
94
|
+
* rename; only the underlying resolution semantics changed (the server
|
|
95
|
+
* now resolves the name to a Plan and reads its latest Task's log).
|
|
96
|
+
*/
|
|
97
|
+
async fetchTaskLogs(planName, options) {
|
|
98
|
+
const params = new URLSearchParams();
|
|
99
|
+
if (options.type)
|
|
100
|
+
params.set('type', options.type);
|
|
101
|
+
if (options.lines)
|
|
102
|
+
params.set('lines', options.lines.toString());
|
|
103
|
+
params.set('project', options.project);
|
|
104
|
+
const response = await this.client.get(`/api/v1/logs/${encodeURIComponent(planName)}`, {
|
|
105
|
+
params,
|
|
106
|
+
responseType: 'text',
|
|
107
|
+
headers: {
|
|
108
|
+
Accept: 'text/plain',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return response.data;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Detects when a 404 came from the `/api/v1/plans` collection endpoint
|
|
115
|
+
* and rethrows as an `IncompatibleServerError`. A collection 404 can
|
|
116
|
+
* only mean the server predates the Plan/Project/Task rename. Per-
|
|
117
|
+
* resource 404s (e.g. `/api/v1/plans/<id>`) keep `NotFoundError`
|
|
118
|
+
* semantics and are handled by `handleError()`.
|
|
119
|
+
*/
|
|
120
|
+
maybeRethrowAsIncompatibleServer(err) {
|
|
121
|
+
if (axios.isAxiosError(err) &&
|
|
122
|
+
err.response?.status === 404 &&
|
|
123
|
+
typeof err.config?.url === 'string' &&
|
|
124
|
+
/\/api\/v1\/plans(\?|$)/.test(err.config.url)) {
|
|
125
|
+
throw new IncompatibleServerError();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handle API errors with user-friendly messages
|
|
130
|
+
*/
|
|
131
|
+
async handleError(error) {
|
|
132
|
+
if (error.response) {
|
|
133
|
+
const status = error.response.status;
|
|
134
|
+
const data = error.response.data;
|
|
135
|
+
switch (status) {
|
|
136
|
+
case 401:
|
|
137
|
+
throw new AuthenticationError(data.message || "Run 'hula login' to authenticate");
|
|
138
|
+
case 403:
|
|
139
|
+
throw new AuthorizationError(data.message || 'You do not have access to this resource');
|
|
140
|
+
case 404:
|
|
141
|
+
throw new NotFoundError(data.message || 'Resource not found');
|
|
142
|
+
case 409:
|
|
143
|
+
throw new ConflictError(data.message || 'Resource already exists');
|
|
144
|
+
case 429:
|
|
145
|
+
throw new RateLimitError('Rate limit exceeded. Please slow down your requests.');
|
|
146
|
+
case 500:
|
|
147
|
+
case 502:
|
|
148
|
+
case 503:
|
|
149
|
+
throw new ServerError('Hula-project is temporarily unavailable. Please try again later.');
|
|
150
|
+
default:
|
|
151
|
+
throw new ApiError(data.message || `API error: ${status}`, status);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (error.code === 'ECONNABORTED') {
|
|
155
|
+
throw new TimeoutError('Request timed out. Check your internet connection.');
|
|
156
|
+
}
|
|
157
|
+
if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
|
|
158
|
+
throw new NetworkError('Cannot connect to hula-project. Check your internet connection.');
|
|
159
|
+
}
|
|
160
|
+
throw new ApiError(error.message);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Custom error classes
|
|
164
|
+
export class ApiError extends Error {
|
|
165
|
+
statusCode;
|
|
166
|
+
constructor(message, statusCode) {
|
|
167
|
+
super(message);
|
|
168
|
+
this.statusCode = statusCode;
|
|
169
|
+
this.name = 'ApiError';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export class AuthenticationError extends ApiError {
|
|
173
|
+
constructor(message) {
|
|
174
|
+
super(message, 401);
|
|
175
|
+
this.name = 'AuthenticationError';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export class AuthorizationError extends ApiError {
|
|
179
|
+
constructor(message) {
|
|
180
|
+
super(message, 403);
|
|
181
|
+
this.name = 'AuthorizationError';
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export class NotFoundError extends ApiError {
|
|
185
|
+
constructor(message) {
|
|
186
|
+
super(message, 404);
|
|
187
|
+
this.name = 'NotFoundError';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export class ConflictError extends ApiError {
|
|
191
|
+
constructor(message) {
|
|
192
|
+
super(message, 409);
|
|
193
|
+
this.name = 'ConflictError';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export class RateLimitError extends ApiError {
|
|
197
|
+
constructor(message) {
|
|
198
|
+
super(message, 429);
|
|
199
|
+
this.name = 'RateLimitError';
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export class ServerError extends ApiError {
|
|
203
|
+
constructor(message) {
|
|
204
|
+
super(message, 500);
|
|
205
|
+
this.name = 'ServerError';
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
export class TimeoutError extends ApiError {
|
|
209
|
+
constructor(message) {
|
|
210
|
+
super(message);
|
|
211
|
+
this.name = 'TimeoutError';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
export class NetworkError extends ApiError {
|
|
215
|
+
constructor(message) {
|
|
216
|
+
super(message);
|
|
217
|
+
this.name = 'NetworkError';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Raised when hub-launch detects that the connected hula-server predates
|
|
222
|
+
* the Plan/Project/Task rename (NoStackApp/hula-server PR #159) — i.e. a
|
|
223
|
+
* 404 on the `/api/v1/plans` collection endpoint.
|
|
224
|
+
*/
|
|
225
|
+
export class IncompatibleServerError extends ApiError {
|
|
226
|
+
constructor() {
|
|
227
|
+
super('hula-server is on an incompatible version. Upgrade to a release ' +
|
|
228
|
+
'that includes the Plan/Project/Task rename (NoStackApp/hula-server ' +
|
|
229
|
+
'PR #159) or downgrade hub-launch. See CHANGELOG.md for details.', 404);
|
|
230
|
+
this.name = 'IncompatibleServerError';
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=HulaApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HulaApiClient.js","sourceRoot":"","sources":["../../../src/services/api/HulaApiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File change information
|
|
3
|
+
*/
|
|
4
|
+
export interface FileChange {
|
|
5
|
+
filename: string;
|
|
6
|
+
status: "added" | "removed" | "modified" | "renamed";
|
|
7
|
+
additions: number;
|
|
8
|
+
deletions: number;
|
|
9
|
+
changes: number;
|
|
10
|
+
patch?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Service for PR diff operations
|
|
14
|
+
* Single Responsibility: Generating and formatting PR diffs
|
|
15
|
+
*/
|
|
16
|
+
export declare class DiffService {
|
|
17
|
+
private prService;
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Get diff for a PR
|
|
21
|
+
*/
|
|
22
|
+
getDiff(prNumber: number): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Get list of files changed in a PR
|
|
25
|
+
*/
|
|
26
|
+
getFiles(prNumber: number): Promise<FileChange[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Generate file link for editor
|
|
29
|
+
*/
|
|
30
|
+
generateFileLink(file: string, line?: number, editor?: "vscode" | "cursor"): string;
|
|
31
|
+
/**
|
|
32
|
+
* Format diff with clickable file links
|
|
33
|
+
*/
|
|
34
|
+
formatDiffWithLinks(prNumber: number, _diff: string, files: FileChange[], editor?: "vscode" | "cursor"): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Get emoji for file based on status
|
|
37
|
+
*/
|
|
38
|
+
private getFileEmoji;
|
|
39
|
+
/**
|
|
40
|
+
* Extract repo root from git
|
|
41
|
+
*/
|
|
42
|
+
getRepoRoot(): Promise<string>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=DiffService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiffService.d.ts","sourceRoot":"","sources":["../../../src/services/diff/DiffService.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAY;;IAM7B;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAYhD;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAUvD;;OAEG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,GAAE,QAAQ,GAAG,QAAmB,GACrC,MAAM;IAOT;;OAEG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,EAAE,EACnB,MAAM,GAAE,QAAQ,GAAG,QAAmB,GACrC,OAAO,CAAC,MAAM,CAAC;IA+DlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CAOrC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { runCommand } from "../../utils/shell.js";
|
|
2
|
+
import { ghApi, getRepoInfo } from "../../utils/github-cli.js";
|
|
3
|
+
import { logger } from "../../utils/logger.js";
|
|
4
|
+
import { PRService } from "../github/PRService.js";
|
|
5
|
+
/**
|
|
6
|
+
* Service for PR diff operations
|
|
7
|
+
* Single Responsibility: Generating and formatting PR diffs
|
|
8
|
+
*/
|
|
9
|
+
export class DiffService {
|
|
10
|
+
prService;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.prService = new PRService();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get diff for a PR
|
|
16
|
+
*/
|
|
17
|
+
async getDiff(prNumber) {
|
|
18
|
+
logger.debug(`Fetching diff for PR #${prNumber}`);
|
|
19
|
+
try {
|
|
20
|
+
const diff = await runCommand(`gh pr diff ${prNumber}`);
|
|
21
|
+
return diff;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
throw new Error(`Failed to get diff for PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get list of files changed in a PR
|
|
29
|
+
*/
|
|
30
|
+
async getFiles(prNumber) {
|
|
31
|
+
const repo = await getRepoInfo();
|
|
32
|
+
const response = await ghApi(`/repos/${repo.owner}/${repo.name}/pulls/${prNumber}/files`);
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generate file link for editor
|
|
37
|
+
*/
|
|
38
|
+
generateFileLink(file, line, editor = "vscode") {
|
|
39
|
+
const protocol = editor === "cursor" ? "cursor" : "vscode";
|
|
40
|
+
const lineNum = line ? `:${line}` : "";
|
|
41
|
+
// Use file:// protocol for local files
|
|
42
|
+
return `${protocol}://file/${file}${lineNum}`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Format diff with clickable file links
|
|
46
|
+
*/
|
|
47
|
+
async formatDiffWithLinks(prNumber, _diff, files, editor = "vscode") {
|
|
48
|
+
const pr = await this.prService.get(prNumber);
|
|
49
|
+
// Calculate totals
|
|
50
|
+
const totalAdditions = files.reduce((sum, f) => sum + f.additions, 0);
|
|
51
|
+
const totalDeletions = files.reduce((sum, f) => sum + f.deletions, 0);
|
|
52
|
+
// Build markdown content
|
|
53
|
+
let markdown = `# Pull Request #${prNumber} - Code Changes\n\n`;
|
|
54
|
+
markdown += `> **💡 How to View:** Press **Cmd+Shift+V** (Mac) or **Ctrl+Shift+V** (Windows/Linux) to see this rendered\n`;
|
|
55
|
+
markdown += `> \n`;
|
|
56
|
+
markdown += `> **Navigation:** Click any file name in the summary below to jump to its detailed diff section\n`;
|
|
57
|
+
markdown += `> - All internal links and navigation work in preview mode\n`;
|
|
58
|
+
markdown += `> - External links (like PR URLs) open in new tabs\n`;
|
|
59
|
+
markdown += `> - File editor links open the file directly in your configured editor\n\n`;
|
|
60
|
+
markdown += `---\n\n`;
|
|
61
|
+
// PR info
|
|
62
|
+
markdown += `**PR**: [#${prNumber} - ${pr.title}](${pr.html_url})\n`;
|
|
63
|
+
markdown += `**Branch**: \`${pr.head.ref}\`\n`;
|
|
64
|
+
markdown += `**Status**: ${pr.state}\n\n`;
|
|
65
|
+
markdown += `---\n\n`;
|
|
66
|
+
// Files summary
|
|
67
|
+
markdown += `## 📁 Changed Files (${files.length}) - Quick Navigation\n\n`;
|
|
68
|
+
markdown += `**Click file names below to jump to that section in this diff:**\n\n`;
|
|
69
|
+
files.forEach((file) => {
|
|
70
|
+
const emoji = this.getFileEmoji(file);
|
|
71
|
+
// VS Code/Cursor converts "### emoji filename" to anchor "#emoji-filename".
|
|
72
|
+
const anchorLink = `${emoji}-${file.filename}`.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
73
|
+
markdown += `- ${emoji} [${file.filename}](#${anchorLink}) `;
|
|
74
|
+
markdown += `(+${file.additions} -${file.deletions})\n`;
|
|
75
|
+
});
|
|
76
|
+
markdown += `\n**Total Changes**: +${totalAdditions} -${totalDeletions}\n\n`;
|
|
77
|
+
markdown += `---\n\n`;
|
|
78
|
+
markdown += `## 📝 Detailed Changes\n\n`;
|
|
79
|
+
// File details
|
|
80
|
+
for (const file of files) {
|
|
81
|
+
const emoji = this.getFileEmoji(file);
|
|
82
|
+
const editorLink = this.generateFileLink(file.filename, undefined, editor);
|
|
83
|
+
// Use standard markdown header (VS Code and Cursor automatically create anchors)
|
|
84
|
+
markdown += `### ${emoji} ${file.filename}\n\n`;
|
|
85
|
+
markdown += `**Changes**: +${file.additions} -${file.deletions}\n`;
|
|
86
|
+
markdown += `**Status**: ${file.status}\n`;
|
|
87
|
+
markdown += `**Open in Editor**: [${file.filename}](${editorLink})\n\n`;
|
|
88
|
+
if (file.patch) {
|
|
89
|
+
markdown += `\`\`\`diff\n${file.patch}\n\`\`\`\n\n`;
|
|
90
|
+
}
|
|
91
|
+
markdown += `---\n\n`;
|
|
92
|
+
}
|
|
93
|
+
markdown += `\n---\n\n`;
|
|
94
|
+
markdown += `**End of PR #${prNumber} Diff**\n`;
|
|
95
|
+
return markdown;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get emoji for file based on status
|
|
99
|
+
*/
|
|
100
|
+
getFileEmoji(file) {
|
|
101
|
+
switch (file.status) {
|
|
102
|
+
case "added":
|
|
103
|
+
return "✨";
|
|
104
|
+
case "removed":
|
|
105
|
+
return "🗑️";
|
|
106
|
+
case "modified":
|
|
107
|
+
return "📝";
|
|
108
|
+
case "renamed":
|
|
109
|
+
return "📋";
|
|
110
|
+
default:
|
|
111
|
+
return "📄";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Extract repo root from git
|
|
116
|
+
*/
|
|
117
|
+
async getRepoRoot() {
|
|
118
|
+
try {
|
|
119
|
+
return await runCommand("git rev-parse --show-toplevel");
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new Error("Not in a git repository");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=DiffService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiffService.js","sourceRoot":"","sources":["../../../src/services/diff/DiffService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Config } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Editor information
|
|
4
|
+
*/
|
|
5
|
+
export interface EditorInfo {
|
|
6
|
+
name: "cursor" | "vsCode" | "other";
|
|
7
|
+
command: string;
|
|
8
|
+
detected: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Service for editor detection and operations
|
|
12
|
+
* Single Responsibility: Editor-related functionality
|
|
13
|
+
*/
|
|
14
|
+
export declare class EditorService {
|
|
15
|
+
private editorCommand?;
|
|
16
|
+
constructor(editorCommand?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Open a file in the configured editor
|
|
19
|
+
*/
|
|
20
|
+
openFile(filePath: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Open a file in preview mode (markdown preview for VS Code/Cursor)
|
|
23
|
+
*/
|
|
24
|
+
openFileInPreview(filePath: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Detect available editor
|
|
27
|
+
*/
|
|
28
|
+
detectEditor(): Promise<EditorInfo>;
|
|
29
|
+
/**
|
|
30
|
+
* Get editor command from config or detect
|
|
31
|
+
*/
|
|
32
|
+
getEditorCommand(config: Config): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Get editor protocol for file links
|
|
35
|
+
*/
|
|
36
|
+
getEditorProtocol(editorCommand: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Create clickable file link for editor
|
|
39
|
+
*/
|
|
40
|
+
createFileLink(editorCommand: string, filePath: string, line?: number, column?: number): string;
|
|
41
|
+
/**
|
|
42
|
+
* Check if editor CLI needs installation
|
|
43
|
+
*/
|
|
44
|
+
checkEditorCLI(): Promise<{
|
|
45
|
+
cursorInstalled: boolean;
|
|
46
|
+
vscodeInstalled: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Show installation instructions for editor CLI
|
|
50
|
+
*/
|
|
51
|
+
showInstallInstructions(editor: "cursor" | "vsCode"): void;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=EditorService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorService.d.ts","sourceRoot":"","sources":["../../../src/services/editor/EditorService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEnB,aAAa,CAAC,EAAE,MAAM;IASlC;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/C;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IA0BzC;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBvD;;OAEG;IACH,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;IAShD;;OAEG;IACH,cAAc,CACZ,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,MAAM;IAmBT;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC;QAC9B,eAAe,EAAE,OAAO,CAAC;QACzB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IAOF;;OAEG;IACH,uBAAuB,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;CA0B3D"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { commandExists, runCommand } from "../../utils/shell.js";
|
|
2
|
+
import { logger } from "../../utils/logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* Service for editor detection and operations
|
|
5
|
+
* Single Responsibility: Editor-related functionality
|
|
6
|
+
*/
|
|
7
|
+
export class EditorService {
|
|
8
|
+
editorCommand;
|
|
9
|
+
constructor(editorCommand) {
|
|
10
|
+
// Normalize config value to actual command
|
|
11
|
+
if (editorCommand === "vsCode") {
|
|
12
|
+
this.editorCommand = "code";
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.editorCommand = editorCommand;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Open a file in the configured editor
|
|
20
|
+
*/
|
|
21
|
+
async openFile(filePath) {
|
|
22
|
+
const command = this.editorCommand ?? "code";
|
|
23
|
+
// Check if editor is available
|
|
24
|
+
if (!(await commandExists(command))) {
|
|
25
|
+
throw new Error(`Editor command '${command}' not found`);
|
|
26
|
+
}
|
|
27
|
+
// Quote file path to handle spaces and special characters
|
|
28
|
+
await runCommand(`${command} "${filePath}"`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Open a file in preview mode (markdown preview for VS Code/Cursor)
|
|
32
|
+
*/
|
|
33
|
+
async openFileInPreview(filePath) {
|
|
34
|
+
const command = this.editorCommand ?? "code";
|
|
35
|
+
// Check if editor is available
|
|
36
|
+
if (!(await commandExists(command))) {
|
|
37
|
+
throw new Error(`Editor command '${command}' not found`);
|
|
38
|
+
}
|
|
39
|
+
// Open file and trigger markdown preview
|
|
40
|
+
// -r flag reuses existing window
|
|
41
|
+
// Quote file path to handle spaces and special characters
|
|
42
|
+
await runCommand(`${command} -r "${filePath}"`);
|
|
43
|
+
// For VS Code/Cursor, trigger the markdown preview command
|
|
44
|
+
// This uses the vscode:// or cursor:// URL scheme
|
|
45
|
+
if (command === "code" || command === "cursor") {
|
|
46
|
+
try {
|
|
47
|
+
await runCommand(`${command} --command markdown.showPreview "${filePath}"`, { silent: true });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// If command fails, at least the file is open
|
|
51
|
+
logger.debug("Could not trigger preview command, file opened normally");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Detect available editor
|
|
57
|
+
*/
|
|
58
|
+
async detectEditor() {
|
|
59
|
+
// Check for Cursor
|
|
60
|
+
if (await commandExists("cursor")) {
|
|
61
|
+
return {
|
|
62
|
+
name: "cursor",
|
|
63
|
+
command: "cursor",
|
|
64
|
+
detected: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Check for VS Code
|
|
68
|
+
if (await commandExists("code")) {
|
|
69
|
+
return {
|
|
70
|
+
name: "vsCode",
|
|
71
|
+
command: "code",
|
|
72
|
+
detected: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
name: "other",
|
|
77
|
+
command: "",
|
|
78
|
+
detected: false,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get editor command from config or detect
|
|
83
|
+
*/
|
|
84
|
+
async getEditorCommand(config) {
|
|
85
|
+
if (config.editorCommand !== "other") {
|
|
86
|
+
// Use configured editor
|
|
87
|
+
const command = config.editorCommand === "cursor" ? "cursor" : "code";
|
|
88
|
+
if (await commandExists(command)) {
|
|
89
|
+
return command;
|
|
90
|
+
}
|
|
91
|
+
logger.warning(`Configured editor '${config.editorCommand}' not found, detecting...`);
|
|
92
|
+
}
|
|
93
|
+
// Auto-detect
|
|
94
|
+
const editor = await this.detectEditor();
|
|
95
|
+
if (editor.detected) {
|
|
96
|
+
return editor.command;
|
|
97
|
+
}
|
|
98
|
+
throw new Error("No supported editor found (cursor or code)");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get editor protocol for file links
|
|
102
|
+
*/
|
|
103
|
+
getEditorProtocol(editorCommand) {
|
|
104
|
+
if (editorCommand === "cursor") {
|
|
105
|
+
return "cursor://";
|
|
106
|
+
}
|
|
107
|
+
else if (editorCommand === "code") {
|
|
108
|
+
return "vscode://";
|
|
109
|
+
}
|
|
110
|
+
return "file://";
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create clickable file link for editor
|
|
114
|
+
*/
|
|
115
|
+
createFileLink(editorCommand, filePath, line, column) {
|
|
116
|
+
const protocol = this.getEditorProtocol(editorCommand);
|
|
117
|
+
if (protocol === "file://") {
|
|
118
|
+
return `file://${filePath}`;
|
|
119
|
+
}
|
|
120
|
+
let link = `${protocol}file${filePath}`;
|
|
121
|
+
if (line !== undefined) {
|
|
122
|
+
link += `:${line}`;
|
|
123
|
+
if (column !== undefined) {
|
|
124
|
+
link += `:${column}`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return link;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if editor CLI needs installation
|
|
131
|
+
*/
|
|
132
|
+
async checkEditorCLI() {
|
|
133
|
+
return {
|
|
134
|
+
cursorInstalled: await commandExists("cursor"),
|
|
135
|
+
vscodeInstalled: await commandExists("code"),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Show installation instructions for editor CLI
|
|
140
|
+
*/
|
|
141
|
+
showInstallInstructions(editor) {
|
|
142
|
+
logger.blank();
|
|
143
|
+
logger.section(`Install ${editor === "cursor" ? "Cursor" : "VS Code"} CLI`);
|
|
144
|
+
if (editor === "cursor") {
|
|
145
|
+
logger.info("To install Cursor CLI:");
|
|
146
|
+
logger.listItem("1. Open Cursor");
|
|
147
|
+
logger.listItem("2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)");
|
|
148
|
+
logger.listItem("3. Type 'Shell Command: Install cursor command in PATH'");
|
|
149
|
+
logger.listItem("4. Select it and restart your terminal");
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
logger.info("To install VS Code CLI:");
|
|
153
|
+
logger.listItem("1. Open VS Code");
|
|
154
|
+
logger.listItem("2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)");
|
|
155
|
+
logger.listItem("3. Type 'Shell Command: Install code command in PATH'");
|
|
156
|
+
logger.listItem("4. Select it and restart your terminal");
|
|
157
|
+
}
|
|
158
|
+
logger.blank();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=EditorService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorService.js","sourceRoot":"","sources":["../../../src/services/editor/EditorService.ts"],"names":[],"mappings":"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"}
|