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 @@
|
|
|
1
|
+
{"version":3,"file":"PlanService.d.ts","sourceRoot":"","sources":["../../../src/services/plan/PlanService.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEpC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAsCtC;;OAEG;IACG,UAAU,CACd,UAAU,EAAE,cAAc,GAAG,kBAAkB,EAC/C,UAAU,SAAI,GACb,OAAO,CAAC,QAAQ,CAAC;IAgCpB;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAoCtD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAK/C;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAWrD;;;OAGG;IACG,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA2BzE;;OAEG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA0BrE;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAazC;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIjC;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAgBtC"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'fs/promises';
|
|
2
|
+
import { join, basename, resolve, isAbsolute } from 'path';
|
|
3
|
+
import { existsSync, unlinkSync } from 'fs';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { searchSelect } from '../../utils/prompts.js';
|
|
6
|
+
/**
|
|
7
|
+
* Service for plan file operations
|
|
8
|
+
* Single Responsibility: Plan file management
|
|
9
|
+
*/
|
|
10
|
+
export class PlanService {
|
|
11
|
+
planPath;
|
|
12
|
+
constructor(planPath) {
|
|
13
|
+
this.planPath = planPath;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* List all plan files
|
|
17
|
+
*/
|
|
18
|
+
async listPlans() {
|
|
19
|
+
if (!existsSync(this.planPath)) {
|
|
20
|
+
logger.warning(`Plan path does not exist: ${this.planPath}`);
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const files = await readdir(this.planPath);
|
|
24
|
+
const planFiles = [];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
if (!file.endsWith('.md')) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const filePath = join(this.planPath, file);
|
|
30
|
+
const stats = await stat(filePath);
|
|
31
|
+
const content = await readFile(filePath, 'utf-8');
|
|
32
|
+
// Extract title from first # heading
|
|
33
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
34
|
+
const title = titleMatch?.[1] ?? file.replace('.md', '');
|
|
35
|
+
planFiles.push({
|
|
36
|
+
path: filePath,
|
|
37
|
+
filename: file,
|
|
38
|
+
title,
|
|
39
|
+
content,
|
|
40
|
+
createdAt: stats.mtime,
|
|
41
|
+
size: stats.size,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Sort by creation date (newest first)
|
|
45
|
+
return planFiles.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Select a plan file interactively
|
|
49
|
+
*/
|
|
50
|
+
async selectPlan(preference, maxChoices = 5) {
|
|
51
|
+
const plans = await this.listPlans();
|
|
52
|
+
if (plans.length === 0) {
|
|
53
|
+
throw new Error(`No plan files found in ${this.planPath}`);
|
|
54
|
+
}
|
|
55
|
+
if (preference === 'alwaysLatest') {
|
|
56
|
+
return plans[0];
|
|
57
|
+
}
|
|
58
|
+
// Show recent plans for selection
|
|
59
|
+
const recentPlans = plans.slice(0, maxChoices);
|
|
60
|
+
const choices = recentPlans.map((plan) => ({
|
|
61
|
+
name: `${plan.filename} - ${plan.title}`,
|
|
62
|
+
value: plan.path,
|
|
63
|
+
}));
|
|
64
|
+
const selectedPath = await searchSelect('Select a plan file to create issue from:', choices);
|
|
65
|
+
const selectedPlan = plans.find((p) => p.path === selectedPath);
|
|
66
|
+
if (!selectedPlan) {
|
|
67
|
+
throw new Error('Selected plan not found');
|
|
68
|
+
}
|
|
69
|
+
return selectedPlan;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse a plan file
|
|
73
|
+
*/
|
|
74
|
+
async parsePlan(filePath) {
|
|
75
|
+
const content = await readFile(filePath, 'utf-8');
|
|
76
|
+
// Extract title from first # heading
|
|
77
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
78
|
+
const title = titleMatch?.[1] ?? basename(filePath, '.md');
|
|
79
|
+
// Extract metadata from frontmatter if present
|
|
80
|
+
const metadata = {};
|
|
81
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
82
|
+
if (frontmatterMatch) {
|
|
83
|
+
const frontmatter = frontmatterMatch[1];
|
|
84
|
+
const lines = frontmatter.split('\n');
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
const match = line.match(/^(\w+):\s*(.+)$/);
|
|
87
|
+
if (match) {
|
|
88
|
+
metadata[match[1]] = match[2];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Body is everything after frontmatter (if present) or entire content
|
|
93
|
+
let body = content;
|
|
94
|
+
if (frontmatterMatch) {
|
|
95
|
+
body = content.slice(frontmatterMatch[0].length).trim();
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
title,
|
|
99
|
+
body,
|
|
100
|
+
metadata,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get the most recent plan file
|
|
105
|
+
*/
|
|
106
|
+
async getLatestPlan() {
|
|
107
|
+
const plans = await this.listPlans();
|
|
108
|
+
return plans[0] ?? null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Search plans by title or content
|
|
112
|
+
*/
|
|
113
|
+
async searchPlans(query) {
|
|
114
|
+
const plans = await this.listPlans();
|
|
115
|
+
const lowerQuery = query.toLowerCase();
|
|
116
|
+
return plans.filter((plan) => plan.title.toLowerCase().includes(lowerQuery) ||
|
|
117
|
+
plan.content.toLowerCase().includes(lowerQuery));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get plan by filename or path
|
|
121
|
+
* Searches config planPath, then direct path
|
|
122
|
+
*/
|
|
123
|
+
async getPlanByFilename(filenameOrPath) {
|
|
124
|
+
const plans = await this.listPlans();
|
|
125
|
+
// Extract just the filename if a path was provided
|
|
126
|
+
const filename = basename(filenameOrPath);
|
|
127
|
+
// Try to match by filename first
|
|
128
|
+
const byFilename = plans.find((p) => p.filename === filename);
|
|
129
|
+
if (byFilename) {
|
|
130
|
+
return byFilename;
|
|
131
|
+
}
|
|
132
|
+
// Also try to match by full path for backwards compatibility
|
|
133
|
+
const byPath = plans.find((p) => p.path === filenameOrPath);
|
|
134
|
+
if (byPath) {
|
|
135
|
+
return byPath;
|
|
136
|
+
}
|
|
137
|
+
// Try to resolve as a direct file path (absolute or relative)
|
|
138
|
+
const directPlan = await this.getPlanByDirectPath(filenameOrPath);
|
|
139
|
+
if (directPlan) {
|
|
140
|
+
return directPlan;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve a plan by direct file path (absolute or relative)
|
|
146
|
+
*/
|
|
147
|
+
async getPlanByDirectPath(filePath) {
|
|
148
|
+
const resolvedPath = isAbsolute(filePath) ? filePath : resolve(filePath);
|
|
149
|
+
if (!existsSync(resolvedPath)) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const stats = await stat(resolvedPath);
|
|
154
|
+
const content = await readFile(resolvedPath, 'utf-8');
|
|
155
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
156
|
+
const title = titleMatch?.[1] ?? basename(resolvedPath, '.md');
|
|
157
|
+
return {
|
|
158
|
+
path: resolvedPath,
|
|
159
|
+
filename: basename(resolvedPath),
|
|
160
|
+
title,
|
|
161
|
+
content,
|
|
162
|
+
createdAt: stats.mtime,
|
|
163
|
+
size: stats.size,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get the relative path for a plan (relative to repo root)
|
|
172
|
+
*/
|
|
173
|
+
getRelativePath(planPath) {
|
|
174
|
+
// If already relative, return as-is
|
|
175
|
+
if (!planPath.startsWith('/')) {
|
|
176
|
+
return planPath;
|
|
177
|
+
}
|
|
178
|
+
// Strip repo root prefix if present
|
|
179
|
+
const planDirIndex = planPath.indexOf('.hublaunch/plans');
|
|
180
|
+
if (planDirIndex !== -1) {
|
|
181
|
+
return planPath.substring(planDirIndex);
|
|
182
|
+
}
|
|
183
|
+
return planPath;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if a plan file exists at the given path
|
|
187
|
+
*/
|
|
188
|
+
exists(planPath) {
|
|
189
|
+
return existsSync(planPath);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Delete a local plan file (e.g. after it has been uploaded to origin/main)
|
|
193
|
+
* Non-throwing: logs warning on failure, returns success boolean.
|
|
194
|
+
*/
|
|
195
|
+
deletePlan(planPath) {
|
|
196
|
+
try {
|
|
197
|
+
if (!existsSync(planPath)) {
|
|
198
|
+
logger.debug(`Plan file already removed: ${planPath}`);
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
unlinkSync(planPath);
|
|
202
|
+
logger.debug(`Removed local plan file (synced to origin/main)`);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
logger.warning(`Could not remove local plan file: ${error instanceof Error ? error.message : String(error)}`);
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=PlanService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlanService.js","sourceRoot":"","sources":["../../../src/services/plan/PlanService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IStatusPollingAdapter, StatusChange } from './IStatusPollingAdapter.js';
|
|
2
|
+
import type { TrackedPlan } from '../../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Polls GitHub GraphQL API directly for Copilot status and deployment changes.
|
|
5
|
+
* Used by free-tier users who don't have Hula Server access.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GitHubDirectPollingAdapter implements IStatusPollingAdapter {
|
|
8
|
+
readonly name = "github";
|
|
9
|
+
private copilotService;
|
|
10
|
+
private deploymentService;
|
|
11
|
+
private issueService;
|
|
12
|
+
constructor();
|
|
13
|
+
validate(): void;
|
|
14
|
+
pollForChanges(currentIssues: TrackedPlan[]): Promise<StatusChange[]>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=GitHubDirectPollingAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitHubDirectPollingAdapter.d.ts","sourceRoot":"","sources":["../../../src/services/polling/GitHubDirectPollingAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOxD;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,qBAAqB;IACtE,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,YAAY,CAAe;;IAQnC,QAAQ,IAAI,IAAI;IAaV,cAAc,CAAC,aAAa,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAqF5E"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { BatchCopilotDetectionService } from '../github/BatchCopilotDetectionService.js';
|
|
2
|
+
import { DeploymentDetectionService } from '../github/DeploymentDetectionService.js';
|
|
3
|
+
import { IssueService } from '../github/IssueService.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
/**
|
|
7
|
+
* Polls GitHub GraphQL API directly for Copilot status and deployment changes.
|
|
8
|
+
* Used by free-tier users who don't have Hula Server access.
|
|
9
|
+
*/
|
|
10
|
+
export class GitHubDirectPollingAdapter {
|
|
11
|
+
name = 'github';
|
|
12
|
+
copilotService;
|
|
13
|
+
deploymentService;
|
|
14
|
+
issueService;
|
|
15
|
+
constructor() {
|
|
16
|
+
this.copilotService = new BatchCopilotDetectionService();
|
|
17
|
+
this.deploymentService = new DeploymentDetectionService();
|
|
18
|
+
this.issueService = new IssueService();
|
|
19
|
+
}
|
|
20
|
+
validate() {
|
|
21
|
+
// GitHub CLI must be available and authenticated.
|
|
22
|
+
try {
|
|
23
|
+
execSync('gh auth status', { stdio: 'pipe' });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error('GitHubDirectPollingAdapter requires GitHub CLI authentication. ' +
|
|
27
|
+
'Run "gh auth login" to authenticate, or switch to pollingProvider: "hula-server" ' +
|
|
28
|
+
'in .hublaunch/hublaunch.config.js');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async pollForChanges(currentIssues) {
|
|
32
|
+
const changes = [];
|
|
33
|
+
// Filter to plans with numbers (required for GitHub API)
|
|
34
|
+
const issuesWithNumbers = currentIssues.filter((issue) => issue.number !== undefined);
|
|
35
|
+
if (issuesWithNumbers.length === 0)
|
|
36
|
+
return changes;
|
|
37
|
+
// Check Copilot status changes
|
|
38
|
+
const statusChanges = await this.copilotService.detectStatusChanges(issuesWithNumbers.map((issue) => ({
|
|
39
|
+
number: issue.number,
|
|
40
|
+
status: issue.trackingStatus,
|
|
41
|
+
})));
|
|
42
|
+
for (const change of statusChanges) {
|
|
43
|
+
changes.push({
|
|
44
|
+
issueNumber: change.issueNumber,
|
|
45
|
+
field: 'trackingStatus',
|
|
46
|
+
oldValue: change.oldStatus,
|
|
47
|
+
newValue: change.newStatus,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// Check deployment status changes
|
|
51
|
+
const deploymentChanges = await this.copilotService.detectDeploymentStatus(issuesWithNumbers.map((issue) => issue.number));
|
|
52
|
+
for (const depChange of deploymentChanges) {
|
|
53
|
+
const currentIssue = issuesWithNumbers.find((i) => i.number === depChange.issueNumber);
|
|
54
|
+
if (!currentIssue)
|
|
55
|
+
continue;
|
|
56
|
+
const newStatus = depChange.deploymentStatus.status;
|
|
57
|
+
if (newStatus !== currentIssue.deploymentStatus) {
|
|
58
|
+
changes.push({
|
|
59
|
+
issueNumber: depChange.issueNumber,
|
|
60
|
+
field: 'deploymentStatus',
|
|
61
|
+
oldValue: currentIssue.deploymentStatus,
|
|
62
|
+
newValue: newStatus,
|
|
63
|
+
});
|
|
64
|
+
// Notify Copilot about deployment failures
|
|
65
|
+
if (newStatus === 'failed') {
|
|
66
|
+
const issue = issuesWithNumbers.find(i => i.number === depChange.issueNumber);
|
|
67
|
+
if (issue &&
|
|
68
|
+
this.deploymentService.shouldNotifyCopilot(depChange.deploymentStatus, issue.deploymentNotifiedAt)) {
|
|
69
|
+
try {
|
|
70
|
+
const targetNumber = depChange.prNumber ?? depChange.issueNumber;
|
|
71
|
+
await this.issueService.addComment(targetNumber, '@copilot The deployment has failed. Please check the logs and fix the issues.');
|
|
72
|
+
logger.debug(`Copilot notified about deployment failure on PR #${targetNumber} (issue #${depChange.issueNumber})`);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
logger.debug(`Failed to notify Copilot about deployment failure for #${depChange.issueNumber}: ${error instanceof Error ? error.message : String(error)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (changes.length > 0) {
|
|
82
|
+
logger.debug(`[github] Detected ${changes.length} status change(s)`);
|
|
83
|
+
}
|
|
84
|
+
return changes;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=GitHubDirectPollingAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitHubDirectPollingAdapter.js","sourceRoot":"","sources":["../../../src/services/polling/GitHubDirectPollingAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IAC5B,IAAI,GAAG,QAAQ,CAAC;IACjB,cAAc,CAA+B;IAC7C,iBAAiB,CAA6B;IAC9C,YAAY,CAAe;IAEnC;QACE,IAAI,CAAC,cAAc,GAAG,IAAI,4BAA4B,EAAE,CAAC;QACzD,IAAI,CAAC,iBAAiB,GAAG,IAAI,0BAA0B,EAAE,CAAC;QAC1D,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACzC,CAAC;IAED,QAAQ;QACN,kDAAkD;QAClD,IAAI,CAAC;YACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,iEAAiE;gBACjE,mFAAmF;gBACnF,mCAAmC,CACpC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,aAA4B;QAC/C,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,yDAAyD;QACzD,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAC5C,CAAC,KAAK,EAA6C,EAAE,CACnD,KAAK,CAAC,MAAM,KAAK,SAAS,CAC7B,CAAC;QAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAEnD,+BAA+B;QAC/B,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,mBAAmB,CACjE,iBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAChC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,cAAc;SAC7B,CAAC,CAAC,CACJ,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC;gBACX,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,MAAM,CAAC,SAAS;gBAC1B,QAAQ,EAAE,MAAM,CAAC,SAAS;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,kCAAkC;QAClC,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,CACxE,iBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAC/C,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC1C,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,WAAW,CAC1C,CAAC;YACF,IAAI,CAAC,YAAY;gBAAE,SAAS;YAE5B,MAAM,SAAS,GAAG,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC;YACpD,IAAI,SAAS,KAAK,YAAY,CAAC,gBAAgB,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC;oBACX,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,KAAK,EAAE,kBAAkB;oBACzB,QAAQ,EAAE,YAAY,CAAC,gBAAgB;oBACvC,QAAQ,EAAE,SAAS;iBACpB,CAAC,CAAC;gBAEH,2CAA2C;gBAC3C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC;oBAC9E,IACE,KAAK;wBACL,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CACxC,SAAS,CAAC,gBAAgB,EAC1B,KAAK,CAAC,oBAAoB,CAC3B,EACD,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,WAAW,CAAC;4BACjE,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,YAAY,EACZ,+EAA+E,CAChF,CAAC;4BACF,MAAM,CAAC,KAAK,CACV,oDAAoD,YAAY,YAAY,SAAS,CAAC,WAAW,GAAG,CACrG,CAAC;wBACJ,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,CAAC,KAAK,CACV,0DAA0D,SAAS,CAAC,WAAW,KAC7E,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,qBAAqB,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IStatusPollingAdapter, StatusChange } from './IStatusPollingAdapter.js';
|
|
2
|
+
import type { TrackedPlan } from '../../types/index.js';
|
|
3
|
+
import type { TrackingService } from '../tracking/TrackingService.js';
|
|
4
|
+
/**
|
|
5
|
+
* Polls the Hula Server API for status changes.
|
|
6
|
+
*
|
|
7
|
+
* Uses a snapshot pattern to avoid cache bugs.
|
|
8
|
+
* The `currentPlans` parameter (passed in from the caller) represents the
|
|
9
|
+
* FRESH data fetched this cycle. On the first poll, we just store the snapshot
|
|
10
|
+
* and return no changes. On subsequent polls, we compare the new fresh data
|
|
11
|
+
* against the stored previous snapshot.
|
|
12
|
+
*/
|
|
13
|
+
export declare class HulaServerPollingAdapter implements IStatusPollingAdapter {
|
|
14
|
+
private trackingService;
|
|
15
|
+
readonly name = "hula-server";
|
|
16
|
+
private previousSnapshot;
|
|
17
|
+
private hasSnapshot;
|
|
18
|
+
constructor(trackingService: TrackingService);
|
|
19
|
+
validate(): void;
|
|
20
|
+
pollForChanges(currentPlans: TrackedPlan[]): Promise<StatusChange[]>;
|
|
21
|
+
private storeSnapshot;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=HulaServerPollingAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HulaServerPollingAdapter.d.ts","sourceRoot":"","sources":["../../../src/services/polling/HulaServerPollingAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,wBAAyB,YAAW,qBAAqB;IAKxD,OAAO,CAAC,eAAe;IAJnC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,OAAO,CAAC,gBAAgB,CAAuC;IAC/D,OAAO,CAAC,WAAW,CAAS;gBAER,eAAe,EAAE,eAAe;IAEpD,QAAQ,IAAI,IAAI;IASV,cAAc,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsD1E,OAAO,CAAC,aAAa;CAMtB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { logger } from '../../utils/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Polls the Hula Server API for status changes.
|
|
4
|
+
*
|
|
5
|
+
* Uses a snapshot pattern to avoid cache bugs.
|
|
6
|
+
* The `currentPlans` parameter (passed in from the caller) represents the
|
|
7
|
+
* FRESH data fetched this cycle. On the first poll, we just store the snapshot
|
|
8
|
+
* and return no changes. On subsequent polls, we compare the new fresh data
|
|
9
|
+
* against the stored previous snapshot.
|
|
10
|
+
*/
|
|
11
|
+
export class HulaServerPollingAdapter {
|
|
12
|
+
trackingService;
|
|
13
|
+
name = 'hula-server';
|
|
14
|
+
previousSnapshot = new Map();
|
|
15
|
+
hasSnapshot = false;
|
|
16
|
+
constructor(trackingService) {
|
|
17
|
+
this.trackingService = trackingService;
|
|
18
|
+
}
|
|
19
|
+
validate() {
|
|
20
|
+
if (!this.trackingService) {
|
|
21
|
+
throw new Error('HulaServerPollingAdapter requires a TrackingService instance. ' +
|
|
22
|
+
'Ensure hulaApiKey and hulaProjectUrl are set in .hublaunch/hublaunch.config.js');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async pollForChanges(currentPlans) {
|
|
26
|
+
const changes = [];
|
|
27
|
+
// On first poll, just store the snapshot — no comparison possible yet
|
|
28
|
+
if (!this.hasSnapshot) {
|
|
29
|
+
this.storeSnapshot(currentPlans);
|
|
30
|
+
this.hasSnapshot = true;
|
|
31
|
+
logger.debug('[hula-server] First poll — stored initial snapshot');
|
|
32
|
+
return changes;
|
|
33
|
+
}
|
|
34
|
+
// Compare current (fresh) data against the stored previous snapshot
|
|
35
|
+
for (const current of currentPlans) {
|
|
36
|
+
const previous = this.previousSnapshot.get(current.name);
|
|
37
|
+
if (!previous)
|
|
38
|
+
continue; // New plan, skip (not a "change")
|
|
39
|
+
if (current.trackingStatus !== previous.trackingStatus) {
|
|
40
|
+
changes.push({
|
|
41
|
+
issueNumber: current.number ?? 0,
|
|
42
|
+
field: 'trackingStatus',
|
|
43
|
+
oldValue: previous.trackingStatus,
|
|
44
|
+
newValue: current.trackingStatus,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (current.deploymentStatus !== previous.deploymentStatus) {
|
|
48
|
+
changes.push({
|
|
49
|
+
issueNumber: current.number ?? 0,
|
|
50
|
+
field: 'deploymentStatus',
|
|
51
|
+
oldValue: previous.deploymentStatus,
|
|
52
|
+
newValue: current.deploymentStatus,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (current.githubState !== previous.githubState) {
|
|
56
|
+
changes.push({
|
|
57
|
+
issueNumber: current.number ?? 0,
|
|
58
|
+
field: 'githubState',
|
|
59
|
+
oldValue: previous.githubState,
|
|
60
|
+
newValue: current.githubState,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Update snapshot for next poll cycle
|
|
65
|
+
this.storeSnapshot(currentPlans);
|
|
66
|
+
if (changes.length > 0) {
|
|
67
|
+
logger.debug(`[hula-server] Detected ${changes.length} status change(s)`);
|
|
68
|
+
}
|
|
69
|
+
return changes;
|
|
70
|
+
}
|
|
71
|
+
storeSnapshot(plans) {
|
|
72
|
+
this.previousSnapshot.clear();
|
|
73
|
+
for (const plan of plans) {
|
|
74
|
+
this.previousSnapshot.set(plan.name, { ...plan });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=HulaServerPollingAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HulaServerPollingAdapter.js","sourceRoot":"","sources":["../../../src/services/polling/HulaServerPollingAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,OAAO,wBAAwB;IAKf;IAJX,IAAI,GAAG,aAAa,CAAC;IACtB,gBAAgB,GAA6B,IAAI,GAAG,EAAE,CAAC;IACvD,WAAW,GAAG,KAAK,CAAC;IAE5B,YAAoB,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAExD,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,gEAAgE;gBAChE,gFAAgF,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,YAA2B;QAC9C,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,sEAAsE;QACtE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACjC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACnE,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,oEAAoE;QACpE,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,CAAC,QAAQ;gBAAE,SAAS,CAAC,kCAAkC;YAE3D,IAAI,OAAO,CAAC,cAAc,KAAK,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACvD,OAAO,CAAC,IAAI,CAAC;oBACX,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;oBAChC,KAAK,EAAE,gBAAgB;oBACvB,QAAQ,EAAE,QAAQ,CAAC,cAAc;oBACjC,QAAQ,EAAE,OAAO,CAAC,cAAc;iBACjC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,gBAAgB,KAAK,QAAQ,CAAC,gBAAgB,EAAE,CAAC;gBAC3D,OAAO,CAAC,IAAI,CAAC;oBACX,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;oBAChC,KAAK,EAAE,kBAAkB;oBACzB,QAAQ,EAAE,QAAQ,CAAC,gBAAgB;oBACnC,QAAQ,EAAE,OAAO,CAAC,gBAAgB;iBACnC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC;oBACX,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;oBAChC,KAAK,EAAE,aAAa;oBACpB,QAAQ,EAAE,QAAQ,CAAC,WAAW;oBAC9B,QAAQ,EAAE,OAAO,CAAC,WAAW;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAEjC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,0BAA0B,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { TrackedPlan } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of a single status change detected by polling
|
|
4
|
+
*/
|
|
5
|
+
export interface StatusChange {
|
|
6
|
+
issueNumber: number;
|
|
7
|
+
field: 'trackingStatus' | 'deploymentStatus' | 'githubState';
|
|
8
|
+
oldValue: string | undefined;
|
|
9
|
+
newValue: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Interface for status polling adapters.
|
|
13
|
+
* Implementations detect plan status changes through different backends.
|
|
14
|
+
*/
|
|
15
|
+
export interface IStatusPollingAdapter {
|
|
16
|
+
/** Human-readable name for logging */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/**
|
|
19
|
+
* Validate that the adapter is properly configured.
|
|
20
|
+
* Throws descriptive errors if misconfigured.
|
|
21
|
+
*/
|
|
22
|
+
validate(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Poll for status changes compared to the given current plans.
|
|
25
|
+
* Returns an array of detected changes.
|
|
26
|
+
*/
|
|
27
|
+
pollForChanges(currentPlans: TrackedPlan[]): Promise<StatusChange[]>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=IStatusPollingAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IStatusPollingAdapter.d.ts","sourceRoot":"","sources":["../../../src/services/polling/IStatusPollingAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,aAAa,CAAC;IAC7D,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;;OAGG;IACH,cAAc,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IStatusPollingAdapter.js","sourceRoot":"","sources":["../../../src/services/polling/IStatusPollingAdapter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config } from '../../types/index.js';
|
|
2
|
+
import type { IStatusPollingAdapter } from './IStatusPollingAdapter.js';
|
|
3
|
+
import { TrackingService } from '../tracking/TrackingService.js';
|
|
4
|
+
/**
|
|
5
|
+
* Factory for creating the appropriate polling adapter based on config.pollingProvider.
|
|
6
|
+
*/
|
|
7
|
+
export declare class StatusPollingAdapterFactory {
|
|
8
|
+
/**
|
|
9
|
+
* Create the polling adapter specified by config.
|
|
10
|
+
* Throws descriptive errors if the selected adapter is misconfigured.
|
|
11
|
+
*/
|
|
12
|
+
static create(config: Config, trackingService: TrackingService): IStatusPollingAdapter;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=StatusPollingAdapterFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusPollingAdapterFactory.d.ts","sourceRoot":"","sources":["../../../src/services/polling/StatusPollingAdapterFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGxE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGjE;;GAEG;AACH,qBAAa,2BAA2B;IACtC;;;OAGG;IACH,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,eAAe,GAC/B,qBAAqB;CAqCzB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { HulaServerPollingAdapter } from './HulaServerPollingAdapter.js';
|
|
2
|
+
import { GitHubDirectPollingAdapter } from './GitHubDirectPollingAdapter.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* Factory for creating the appropriate polling adapter based on config.pollingProvider.
|
|
6
|
+
*/
|
|
7
|
+
export class StatusPollingAdapterFactory {
|
|
8
|
+
/**
|
|
9
|
+
* Create the polling adapter specified by config.
|
|
10
|
+
* Throws descriptive errors if the selected adapter is misconfigured.
|
|
11
|
+
*/
|
|
12
|
+
static create(config, trackingService) {
|
|
13
|
+
const provider = config.pollingProvider ?? 'hula-server';
|
|
14
|
+
logger.debug(`Creating polling adapter: ${provider}`);
|
|
15
|
+
let adapter;
|
|
16
|
+
switch (provider) {
|
|
17
|
+
case 'hula-server': {
|
|
18
|
+
if (!config.hulaApiKey || !config.hulaProjectUrl) {
|
|
19
|
+
throw new Error(`Polling provider "hula-server" requires hulaApiKey and hulaProjectUrl ` +
|
|
20
|
+
`to be set in .hublaunch/hublaunch.config.js. ` +
|
|
21
|
+
`Run "hula login" to configure, or set pollingProvider: "github" ` +
|
|
22
|
+
`to use GitHub API directly.`);
|
|
23
|
+
}
|
|
24
|
+
adapter = new HulaServerPollingAdapter(trackingService);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case 'github': {
|
|
28
|
+
adapter = new GitHubDirectPollingAdapter();
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(`Unknown pollingProvider "${provider}". ` +
|
|
33
|
+
`Supported values: "hula-server", "github". ` +
|
|
34
|
+
`Set pollingProvider in .hublaunch/hublaunch.config.js`);
|
|
35
|
+
}
|
|
36
|
+
// Validate the adapter is properly configured
|
|
37
|
+
adapter.validate();
|
|
38
|
+
return adapter;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=StatusPollingAdapterFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusPollingAdapterFactory.js","sourceRoot":"","sources":["../../../src/services/polling/StatusPollingAdapterFactory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAE7E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,2BAA2B;IACtC;;;OAGG;IACH,MAAM,CAAC,MAAM,CACX,MAAc,EACd,eAAgC;QAEhC,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI,aAAa,CAAC;QAEzD,MAAM,CAAC,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QAEtD,IAAI,OAA8B,CAAC;QAEnC,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;oBACjD,MAAM,IAAI,KAAK,CACb,wEAAwE;wBACxE,+CAA+C;wBAC/C,kEAAkE;wBAClE,6BAA6B,CAC9B,CAAC;gBACJ,CAAC;gBACD,OAAO,GAAG,IAAI,wBAAwB,CAAC,eAAe,CAAC,CAAC;gBACxD,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,OAAO,GAAG,IAAI,0BAA0B,EAAE,CAAC;gBAC3C,MAAM;YACR,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CACb,4BAA4B,QAAkB,KAAK;oBACnD,6CAA6C;oBAC7C,uDAAuD,CACxD,CAAC;QACN,CAAC;QAED,8CAA8C;QAC9C,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEnB,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/polling/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/polling/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC"}
|