@dxos/plugin-github 0.7.4 → 0.13.0
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/LICENSE +102 -5
- package/PLUGIN.mdl +784 -0
- package/dist/lib/GitHubCapabilities.mjs +10 -0
- package/dist/lib/GitHubCapabilities.mjs.map +1 -0
- package/dist/lib/GitHubEvents.mjs +15 -0
- package/dist/lib/GitHubEvents.mjs.map +1 -0
- package/dist/lib/GitHubOperation.mjs +358 -0
- package/dist/lib/GitHubOperation.mjs.map +1 -0
- package/dist/lib/GitHubPlugin.mjs +16 -0
- package/dist/lib/GitHubPlugin.mjs.map +1 -0
- package/dist/lib/Walkthrough.mjs +59 -0
- package/dist/lib/Walkthrough.mjs.map +1 -0
- package/dist/lib/capabilities.browser.mjs +54 -0
- package/dist/lib/capabilities.browser.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +54 -0
- package/dist/lib/capabilities.mjs.map +1 -0
- package/dist/lib/capabilities.node.mjs +30 -0
- package/dist/lib/capabilities.node.mjs.map +1 -0
- package/dist/lib/capabilities.tauri.mjs +54 -0
- package/dist/lib/capabilities.tauri.mjs.map +1 -0
- package/dist/lib/capabilities.workerd.mjs +30 -0
- package/dist/lib/capabilities.workerd.mjs.map +1 -0
- package/dist/lib/chunk-ImportPullRequestDialog.mjs +116 -0
- package/dist/lib/chunk-ImportPullRequestDialog.mjs.map +1 -0
- package/dist/lib/chunk-PLUGIN.mjs +6 -0
- package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
- package/dist/lib/chunk-PullRequestArticle.mjs +1486 -0
- package/dist/lib/chunk-PullRequestArticle.mjs.map +1 -0
- package/dist/lib/chunk-PullRequestArticle2.mjs +2 -0
- package/dist/lib/chunk-PullRequestCardMenu.mjs +123 -0
- package/dist/lib/chunk-PullRequestCardMenu.mjs.map +1 -0
- package/dist/lib/chunk-PullRequestsArticle.mjs +594 -0
- package/dist/lib/chunk-PullRequestsArticle.mjs.map +1 -0
- package/dist/lib/chunk-WalkthroughArticle.mjs +26 -0
- package/dist/lib/chunk-WalkthroughArticle.mjs.map +1 -0
- package/dist/lib/chunk-add-pull-request-comment.mjs +19 -0
- package/dist/lib/chunk-add-pull-request-comment.mjs.map +1 -0
- package/dist/lib/chunk-add-pull-request-review-comment.mjs +25 -0
- package/dist/lib/chunk-add-pull-request-review-comment.mjs.map +1 -0
- package/dist/lib/chunk-app-graph-builder.mjs +39 -0
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
- package/dist/lib/chunk-connector.mjs +70 -0
- package/dist/lib/chunk-connector.mjs.map +1 -0
- package/dist/lib/chunk-constants.mjs +11 -0
- package/dist/lib/chunk-constants.mjs.map +1 -0
- package/dist/lib/chunk-errors.mjs +29 -0
- package/dist/lib/chunk-errors.mjs.map +1 -0
- package/dist/lib/chunk-generate-walkthrough.mjs +86 -0
- package/dist/lib/chunk-generate-walkthrough.mjs.map +1 -0
- package/dist/lib/chunk-generate.mjs +719 -0
- package/dist/lib/chunk-generate.mjs.map +1 -0
- package/dist/lib/chunk-get-pull-request-diff.mjs +25 -0
- package/dist/lib/chunk-get-pull-request-diff.mjs.map +1 -0
- package/dist/lib/chunk-get-pull-request-status.mjs +29 -0
- package/dist/lib/chunk-get-pull-request-status.mjs.map +1 -0
- package/dist/lib/chunk-get-repositories.mjs +32 -0
- package/dist/lib/chunk-get-repositories.mjs.map +1 -0
- package/dist/lib/chunk-github-api.mjs +375 -0
- package/dist/lib/chunk-github-api.mjs.map +1 -0
- package/dist/lib/chunk-github-link.mjs +59 -0
- package/dist/lib/chunk-github-link.mjs.map +1 -0
- package/dist/lib/chunk-import-pull-request-from-snapshot.mjs +25 -0
- package/dist/lib/chunk-import-pull-request-from-snapshot.mjs.map +1 -0
- package/dist/lib/chunk-import-pull-request.mjs +96 -0
- package/dist/lib/chunk-import-pull-request.mjs.map +1 -0
- package/dist/lib/chunk-link-resolver.mjs +109 -0
- package/dist/lib/chunk-link-resolver.mjs.map +1 -0
- package/dist/lib/chunk-markdown-extension.mjs +92 -0
- package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
- package/dist/lib/chunk-materialize-target.mjs +36 -0
- package/dist/lib/chunk-materialize-target.mjs.map +1 -0
- package/dist/lib/chunk-operation-handler.mjs +12 -0
- package/dist/lib/chunk-operation-handler.mjs.map +1 -0
- package/dist/lib/chunk-page-action.mjs +22 -0
- package/dist/lib/chunk-page-action.mjs.map +1 -0
- package/dist/lib/chunk-pull-request.mjs +58 -0
- package/dist/lib/chunk-pull-request.mjs.map +1 -0
- package/dist/lib/chunk-pull-request2.mjs +110 -0
- package/dist/lib/chunk-pull-request2.mjs.map +1 -0
- package/dist/lib/chunk-react-surface.mjs +233 -0
- package/dist/lib/chunk-react-surface.mjs.map +1 -0
- package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
- package/dist/lib/chunk-schema.mjs +15 -0
- package/dist/lib/chunk-schema.mjs.map +1 -0
- package/dist/lib/chunk-skill-definition.mjs +10 -0
- package/dist/lib/chunk-skill-definition.mjs.map +1 -0
- package/dist/lib/chunk-submit-pull-request-approval.mjs +56 -0
- package/dist/lib/chunk-submit-pull-request-approval.mjs.map +1 -0
- package/dist/lib/chunk-sync-pull-request.mjs +24 -0
- package/dist/lib/chunk-sync-pull-request.mjs.map +1 -0
- package/dist/lib/chunk-sync.mjs +481 -0
- package/dist/lib/chunk-sync.mjs.map +1 -0
- package/dist/lib/chunk-useOpenObject.mjs +43 -0
- package/dist/lib/chunk-useOpenObject.mjs.map +1 -0
- package/dist/lib/extensions.mjs +132 -0
- package/dist/lib/extensions.mjs.map +1 -0
- package/dist/lib/index.mjs +4 -0
- package/dist/lib/meta.mjs +47 -0
- package/dist/lib/meta.mjs.map +1 -0
- package/dist/lib/ns/Extensions.mjs +18 -0
- package/dist/lib/ns/Extensions.mjs.map +1 -0
- package/dist/lib/operations.mjs +22 -0
- package/dist/lib/operations.mjs.map +1 -0
- package/dist/lib/plugin.mjs +9 -0
- package/dist/lib/plugin.mjs.map +1 -0
- package/dist/lib/skills.mjs +44 -0
- package/dist/lib/skills.mjs.map +1 -0
- package/dist/lib/testing.mjs +189 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/lib/translations.mjs +136 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/lib/types.mjs +5 -0
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/Extensions.d.ts +2 -0
- package/dist/types/src/Extensions.d.ts.map +1 -0
- package/dist/types/src/GitHubPlugin.d.ts +37 -0
- package/dist/types/src/GitHubPlugin.d.ts.map +1 -0
- package/dist/types/src/GitHubPlugin.workerd.test.d.ts +2 -0
- package/dist/types/src/GitHubPlugin.workerd.test.d.ts.map +1 -0
- package/dist/types/src/approval.d.ts +21 -0
- package/dist/types/src/approval.d.ts.map +1 -0
- package/dist/types/src/approval.test.d.ts +2 -0
- package/dist/types/src/approval.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +9 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/connector.d.ts +17 -0
- package/dist/types/src/capabilities/connector.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/browser.d.ts +13 -0
- package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/node.d.ts +13 -0
- package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts +13 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts +13 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +13 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/link-resolver.d.ts +10 -0
- package/dist/types/src/capabilities/link-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/markdown-extension.d.ts +14 -0
- package/dist/types/src/capabilities/markdown-extension.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +5 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/page-action.d.ts +5 -0
- package/dist/types/src/capabilities/page-action.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/schema.d.ts +12 -0
- package/dist/types/src/capabilities/schema.d.ts.map +1 -0
- package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
- package/dist/types/src/cards/GitHubCard.d.ts +11 -0
- package/dist/types/src/cards/GitHubCard.d.ts.map +1 -0
- package/dist/types/src/cards/GitHubCard.stories.d.ts +45 -0
- package/dist/types/src/cards/GitHubCard.stories.d.ts.map +1 -0
- package/dist/types/src/cards/PullRequestCard.d.ts +9 -0
- package/dist/types/src/cards/PullRequestCard.d.ts.map +1 -0
- package/dist/types/src/cards/index.d.ts +3 -0
- package/dist/types/src/cards/index.d.ts.map +1 -0
- package/dist/types/src/components/CommentComposer/CommentComposer.d.ts +30 -0
- package/dist/types/src/components/CommentComposer/CommentComposer.d.ts.map +1 -0
- package/dist/types/src/components/CommentComposer/index.d.ts +2 -0
- package/dist/types/src/components/CommentComposer/index.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/DiffStat.d.ts +8 -0
- package/dist/types/src/components/PullRequestFiles/DiffStat.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/FileTree.d.ts +17 -0
- package/dist/types/src/components/PullRequestFiles/FileTree.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/PullRequestFiles.d.ts +23 -0
- package/dist/types/src/components/PullRequestFiles/PullRequestFiles.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/files.d.ts +39 -0
- package/dist/types/src/components/PullRequestFiles/files.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/files.test.d.ts +2 -0
- package/dist/types/src/components/PullRequestFiles/files.test.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestFiles/index.d.ts +5 -0
- package/dist/types/src/components/PullRequestFiles/index.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/ArtifactPill.d.ts +21 -0
- package/dist/types/src/components/PullRequestOverview/ArtifactPill.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts +15 -0
- package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/PullRequestDetails.d.ts +10 -0
- package/dist/types/src/components/PullRequestOverview/PullRequestDetails.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/PullRequestOverview.d.ts +16 -0
- package/dist/types/src/components/PullRequestOverview/PullRequestOverview.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/RelatedCards.d.ts +28 -0
- package/dist/types/src/components/PullRequestOverview/RelatedCards.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestOverview/index.d.ts +6 -0
- package/dist/types/src/components/PullRequestOverview/index.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestStatus/PullRequestStatus.d.ts +20 -0
- package/dist/types/src/components/PullRequestStatus/PullRequestStatus.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestStatus/index.d.ts +2 -0
- package/dist/types/src/components/PullRequestStatus/index.d.ts.map +1 -0
- package/dist/types/src/components/WalkthroughView/WalkthroughView.d.ts +18 -0
- package/dist/types/src/components/WalkthroughView/WalkthroughView.d.ts.map +1 -0
- package/dist/types/src/components/WalkthroughView/extensions.d.ts +16 -0
- package/dist/types/src/components/WalkthroughView/extensions.d.ts.map +1 -0
- package/dist/types/src/components/WalkthroughView/index.d.ts +3 -0
- package/dist/types/src/components/WalkthroughView/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +5 -8
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/constants.d.ts +7 -0
- package/dist/types/src/constants.d.ts.map +1 -0
- package/dist/types/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.d.ts +6 -0
- package/dist/types/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.d.ts.map +1 -0
- package/dist/types/src/containers/ImportPullRequestDialog/index.d.ts +3 -0
- package/dist/types/src/containers/ImportPullRequestDialog/index.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestArticle/PullRequestArticle.d.ts +15 -0
- package/dist/types/src/containers/PullRequestArticle/PullRequestArticle.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestArticle/failure.d.ts +10 -0
- package/dist/types/src/containers/PullRequestArticle/failure.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestArticle/failure.test.d.ts +2 -0
- package/dist/types/src/containers/PullRequestArticle/failure.test.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestArticle/index.d.ts +2 -0
- package/dist/types/src/containers/PullRequestArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestCardMenu/PullRequestCardMenu.d.ts +14 -0
- package/dist/types/src/containers/PullRequestCardMenu/PullRequestCardMenu.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestCardMenu/index.d.ts +2 -0
- package/dist/types/src/containers/PullRequestCardMenu/index.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestsArticle/PullRequestsArticle.d.ts +13 -0
- package/dist/types/src/containers/PullRequestsArticle/PullRequestsArticle.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestsArticle/arrange.d.ts +44 -0
- package/dist/types/src/containers/PullRequestsArticle/arrange.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestsArticle/arrange.test.d.ts +2 -0
- package/dist/types/src/containers/PullRequestsArticle/arrange.test.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestsArticle/format.d.ts +3 -0
- package/dist/types/src/containers/PullRequestsArticle/format.d.ts.map +1 -0
- package/dist/types/src/containers/PullRequestsArticle/index.d.ts +2 -0
- package/dist/types/src/containers/PullRequestsArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/WalkthroughArticle/WalkthroughArticle.d.ts +13 -0
- package/dist/types/src/containers/WalkthroughArticle/WalkthroughArticle.d.ts.map +1 -0
- package/dist/types/src/containers/WalkthroughArticle/index.d.ts +2 -0
- package/dist/types/src/containers/WalkthroughArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +7 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +157 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +3 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/links.d.ts +21 -0
- package/dist/types/src/extensions/links.d.ts.map +1 -0
- package/dist/types/src/extensions/links.test.d.ts +2 -0
- package/dist/types/src/extensions/links.test.d.ts.map +1 -0
- package/dist/types/src/extensions/references.d.ts +23 -0
- package/dist/types/src/extensions/references.d.ts.map +1 -0
- package/dist/types/src/extensions/references.test.d.ts +2 -0
- package/dist/types/src/extensions/references.test.d.ts.map +1 -0
- package/dist/types/src/github-link.d.ts +29 -0
- package/dist/types/src/github-link.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +5 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useOpenObject.d.ts +9 -0
- package/dist/types/src/hooks/useOpenObject.d.ts.map +1 -0
- package/dist/types/src/hooks/usePullRequestChecks.d.ts +10 -0
- package/dist/types/src/hooks/usePullRequestChecks.d.ts.map +1 -0
- package/dist/types/src/hooks/usePullRequestDiff.d.ts +12 -0
- package/dist/types/src/hooks/usePullRequestDiff.d.ts.map +1 -0
- package/dist/types/src/hooks/usePullRequestFiles.d.ts +22 -0
- package/dist/types/src/hooks/usePullRequestFiles.d.ts.map +1 -0
- package/dist/types/src/hooks/useSyncPullRequest.d.ts +10 -0
- package/dist/types/src/hooks/useSyncPullRequest.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +34 -11
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/add-pull-request-comment.d.ts +5 -0
- package/dist/types/src/operations/add-pull-request-comment.d.ts.map +1 -0
- package/dist/types/src/operations/add-pull-request-review-comment.d.ts +5 -0
- package/dist/types/src/operations/add-pull-request-review-comment.d.ts.map +1 -0
- package/dist/types/src/operations/generate-walkthrough.d.ts +11 -0
- package/dist/types/src/operations/generate-walkthrough.d.ts.map +1 -0
- package/dist/types/src/operations/get-pull-request-diff.d.ts +5 -0
- package/dist/types/src/operations/get-pull-request-diff.d.ts.map +1 -0
- package/dist/types/src/operations/get-pull-request-status.d.ts +5 -0
- package/dist/types/src/operations/get-pull-request-status.d.ts.map +1 -0
- package/dist/types/src/operations/get-repositories.d.ts +13 -0
- package/dist/types/src/operations/get-repositories.d.ts.map +1 -0
- package/dist/types/src/operations/import-pull-request-from-snapshot.d.ts +12 -0
- package/dist/types/src/operations/import-pull-request-from-snapshot.d.ts.map +1 -0
- package/dist/types/src/operations/import-pull-request.d.ts +63 -0
- package/dist/types/src/operations/import-pull-request.d.ts.map +1 -0
- package/dist/types/src/operations/import-pull-request.test.d.ts +2 -0
- package/dist/types/src/operations/import-pull-request.test.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/materialize-target.d.ts +12 -0
- package/dist/types/src/operations/materialize-target.d.ts.map +1 -0
- package/dist/types/src/operations/pull-request.d.ts +48 -0
- package/dist/types/src/operations/pull-request.d.ts.map +1 -0
- package/dist/types/src/operations/pull-request.test.d.ts +2 -0
- package/dist/types/src/operations/pull-request.test.d.ts.map +1 -0
- package/dist/types/src/operations/submit-pull-request-approval.d.ts +5 -0
- package/dist/types/src/operations/submit-pull-request-approval.d.ts.map +1 -0
- package/dist/types/src/operations/sync-pull-request.d.ts +5 -0
- package/dist/types/src/operations/sync-pull-request.d.ts.map +1 -0
- package/dist/types/src/operations/sync.d.ts +123 -0
- package/dist/types/src/operations/sync.d.ts.map +1 -0
- package/dist/types/src/operations/sync.test.d.ts +2 -0
- package/dist/types/src/operations/sync.test.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/plugin.test.d.ts +2 -0
- package/dist/types/src/plugin.test.d.ts.map +1 -0
- package/dist/types/src/pull-request-body.d.ts +37 -0
- package/dist/types/src/pull-request-body.d.ts.map +1 -0
- package/dist/types/src/pull-request-body.test.d.ts +2 -0
- package/dist/types/src/pull-request-body.test.d.ts.map +1 -0
- package/dist/types/src/pull-request.d.ts +28 -0
- package/dist/types/src/pull-request.d.ts.map +1 -0
- package/dist/types/src/pull-request.test.d.ts +2 -0
- package/dist/types/src/pull-request.test.d.ts.map +1 -0
- package/dist/types/src/services/github-api.d.ts +332 -0
- package/dist/types/src/services/github-api.d.ts.map +1 -0
- package/dist/types/src/services/index.d.ts +2 -0
- package/dist/types/src/services/index.d.ts.map +1 -0
- package/dist/types/src/skills/GitHubSkill.d.ts +12 -0
- package/dist/types/src/skills/GitHubSkill.d.ts.map +1 -0
- package/dist/types/src/skills/index.d.ts +2 -0
- package/dist/types/src/skills/index.d.ts.map +1 -0
- package/dist/types/src/stories/Generate.stories.d.ts +27 -0
- package/dist/types/src/stories/Generate.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Links.stories.d.ts +23 -0
- package/dist/types/src/stories/Links.stories.d.ts.map +1 -0
- package/dist/types/src/stories/PullRequestArticle.stories.d.ts +359 -0
- package/dist/types/src/stories/PullRequestArticle.stories.d.ts.map +1 -0
- package/dist/types/src/stories/PullRequestFiles.stories.d.ts +365 -0
- package/dist/types/src/stories/PullRequestFiles.stories.d.ts.map +1 -0
- package/dist/types/src/stories/PullRequestOverview.stories.d.ts +367 -0
- package/dist/types/src/stories/PullRequestOverview.stories.d.ts.map +1 -0
- package/dist/types/src/stories/PullRequestsArticle.stories.d.ts +357 -0
- package/dist/types/src/stories/PullRequestsArticle.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Walkthrough.stories.d.ts +380 -0
- package/dist/types/src/stories/Walkthrough.stories.d.ts.map +1 -0
- package/dist/types/src/stories/github.d.ts +23 -0
- package/dist/types/src/stories/github.d.ts.map +1 -0
- package/dist/types/src/stories/github.test.d.ts +2 -0
- package/dist/types/src/stories/github.test.d.ts.map +1 -0
- package/dist/types/src/stories/walkthrough-fixture.d.ts +8 -0
- package/dist/types/src/stories/walkthrough-fixture.d.ts.map +1 -0
- package/dist/types/src/testing/fixtures.d.ts +14 -0
- package/dist/types/src/testing/fixtures.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +4 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/plugin.d.ts +4 -0
- package/dist/types/src/testing/plugin.d.ts.map +1 -0
- package/dist/types/src/testing/pull-request-13348.d.ts +6 -0
- package/dist/types/src/testing/pull-request-13348.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +339 -53
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/GitHubCapabilities.d.ts +13 -0
- package/dist/types/src/types/GitHubCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/GitHubEvents.d.ts +8 -0
- package/dist/types/src/types/GitHubEvents.d.ts.map +1 -0
- package/dist/types/src/types/GitHubOperation.d.ts +270 -0
- package/dist/types/src/types/GitHubOperation.d.ts.map +1 -0
- package/dist/types/src/types/PullRequestsView.d.ts +35 -0
- package/dist/types/src/types/PullRequestsView.d.ts.map +1 -0
- package/dist/types/src/types/Walkthrough.d.ts +31 -0
- package/dist/types/src/types/Walkthrough.d.ts.map +1 -0
- package/dist/types/src/types/Walkthrough.test.d.ts +2 -0
- package/dist/types/src/types/Walkthrough.test.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +5 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/walkthrough/fill.d.ts +28 -0
- package/dist/types/src/walkthrough/fill.d.ts.map +1 -0
- package/dist/types/src/walkthrough/fill.test.d.ts +2 -0
- package/dist/types/src/walkthrough/fill.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/generate.d.ts +67 -0
- package/dist/types/src/walkthrough/generate.d.ts.map +1 -0
- package/dist/types/src/walkthrough/generate.test.d.ts +2 -0
- package/dist/types/src/walkthrough/generate.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/generated.d.ts +20 -0
- package/dist/types/src/walkthrough/generated.d.ts.map +1 -0
- package/dist/types/src/walkthrough/generated.test.d.ts +2 -0
- package/dist/types/src/walkthrough/generated.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/headings.d.ts +8 -0
- package/dist/types/src/walkthrough/headings.d.ts.map +1 -0
- package/dist/types/src/walkthrough/headings.test.d.ts +2 -0
- package/dist/types/src/walkthrough/headings.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/index.d.ts +9 -0
- package/dist/types/src/walkthrough/index.d.ts.map +1 -0
- package/dist/types/src/walkthrough/patch.d.ts +48 -0
- package/dist/types/src/walkthrough/patch.d.ts.map +1 -0
- package/dist/types/src/walkthrough/plan.d.ts +55 -0
- package/dist/types/src/walkthrough/plan.d.ts.map +1 -0
- package/dist/types/src/walkthrough/plan.test.d.ts +2 -0
- package/dist/types/src/walkthrough/plan.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/prompt.d.ts +33 -0
- package/dist/types/src/walkthrough/prompt.d.ts.map +1 -0
- package/dist/types/src/walkthrough/prompt.test.d.ts +2 -0
- package/dist/types/src/walkthrough/prompt.test.d.ts.map +1 -0
- package/dist/types/src/walkthrough/score.d.ts +43 -0
- package/dist/types/src/walkthrough/score.d.ts.map +1 -0
- package/dist/types/src/walkthrough/score.test.d.ts +2 -0
- package/dist/types/src/walkthrough/score.test.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dx.config.ts +39 -0
- package/package.json +167 -48
- package/src/Extensions.ts +7 -0
- package/src/GitHubPlugin.ts +15 -0
- package/src/GitHubPlugin.workerd.test.ts +23 -0
- package/src/approval.test.ts +40 -0
- package/src/approval.ts +39 -0
- package/src/capabilities/app-graph-builder.ts +47 -0
- package/src/capabilities/connector.ts +95 -0
- package/src/capabilities/gen/browser.ts +82 -0
- package/src/capabilities/gen/node.ts +43 -0
- package/src/capabilities/gen/tauri.ts +82 -0
- package/src/capabilities/gen/workerd.ts +43 -0
- package/src/capabilities/index.ts +71 -0
- package/src/capabilities/link-resolver.ts +137 -0
- package/src/capabilities/markdown-extension.ts +146 -0
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/page-action.ts +32 -0
- package/src/capabilities/react-surface.ts +98 -0
- package/src/capabilities/schema.ts +16 -0
- package/src/capabilities/skill-definition.ts +14 -0
- package/src/cards/GitHubCard.stories.tsx +165 -0
- package/src/cards/GitHubCard.tsx +93 -0
- package/src/cards/PullRequestCard.tsx +23 -0
- package/src/cards/index.ts +6 -0
- package/src/components/CommentComposer/CommentComposer.tsx +109 -0
- package/src/components/CommentComposer/index.ts +5 -0
- package/src/components/PullRequestFiles/DiffStat.tsx +15 -0
- package/src/components/PullRequestFiles/FileTree.tsx +102 -0
- package/src/components/PullRequestFiles/PullRequestFiles.tsx +87 -0
- package/src/components/PullRequestFiles/files.test.ts +59 -0
- package/src/components/PullRequestFiles/files.ts +115 -0
- package/src/components/PullRequestFiles/index.ts +8 -0
- package/src/components/PullRequestOverview/ArtifactPill.tsx +82 -0
- package/src/components/PullRequestOverview/CheckRunList.tsx +120 -0
- package/src/components/PullRequestOverview/PullRequestDetails.tsx +15 -0
- package/src/components/PullRequestOverview/PullRequestOverview.tsx +110 -0
- package/src/components/PullRequestOverview/RelatedCards.tsx +147 -0
- package/src/components/PullRequestOverview/index.ts +9 -0
- package/src/components/PullRequestStatus/PullRequestStatus.tsx +81 -0
- package/src/components/PullRequestStatus/index.ts +5 -0
- package/src/components/WalkthroughView/WalkthroughView.tsx +62 -0
- package/src/components/WalkthroughView/extensions.ts +53 -0
- package/src/components/WalkthroughView/index.ts +6 -0
- package/src/components/index.ts +6 -9
- package/src/constants.ts +12 -0
- package/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.tsx +160 -0
- package/src/containers/ImportPullRequestDialog/index.ts +7 -0
- package/src/containers/PullRequestArticle/PullRequestArticle.tsx +573 -0
- package/src/containers/PullRequestArticle/failure.test.ts +42 -0
- package/src/containers/PullRequestArticle/failure.ts +16 -0
- package/src/containers/PullRequestArticle/index.ts +5 -0
- package/src/containers/PullRequestCardMenu/PullRequestCardMenu.tsx +134 -0
- package/src/containers/PullRequestCardMenu/index.ts +5 -0
- package/src/containers/PullRequestsArticle/PullRequestsArticle.tsx +361 -0
- package/src/containers/PullRequestsArticle/arrange.test.ts +122 -0
- package/src/containers/PullRequestsArticle/arrange.ts +245 -0
- package/src/containers/PullRequestsArticle/format.ts +31 -0
- package/src/containers/PullRequestsArticle/index.ts +5 -0
- package/src/containers/WalkthroughArticle/WalkthroughArticle.tsx +31 -0
- package/src/containers/WalkthroughArticle/index.ts +5 -0
- package/src/containers/index.ts +11 -0
- package/src/errors.ts +61 -0
- package/src/extensions/index.ts +6 -0
- package/src/extensions/links.test.ts +133 -0
- package/src/extensions/links.ts +91 -0
- package/src/extensions/references.test.ts +83 -0
- package/src/extensions/references.ts +100 -0
- package/src/github-link.ts +70 -0
- package/src/hooks/index.ts +6 -3
- package/src/hooks/useOpenObject.ts +48 -0
- package/src/hooks/usePullRequestChecks.ts +81 -0
- package/src/hooks/usePullRequestDiff.ts +57 -0
- package/src/hooks/usePullRequestFiles.ts +98 -0
- package/src/hooks/useSyncPullRequest.ts +51 -0
- package/src/index.ts +4 -6
- package/src/meta.ts +8 -13
- package/src/operations/add-pull-request-comment.ts +31 -0
- package/src/operations/add-pull-request-review-comment.ts +32 -0
- package/src/operations/generate-walkthrough.ts +124 -0
- package/src/operations/get-pull-request-diff.ts +37 -0
- package/src/operations/get-pull-request-status.ts +44 -0
- package/src/operations/get-repositories.ts +53 -0
- package/src/operations/import-pull-request-from-snapshot.ts +48 -0
- package/src/operations/import-pull-request.test.ts +151 -0
- package/src/operations/import-pull-request.ts +141 -0
- package/src/operations/index.ts +29 -0
- package/src/operations/materialize-target.ts +60 -0
- package/src/operations/pull-request.test.ts +120 -0
- package/src/operations/pull-request.ts +141 -0
- package/src/operations/submit-pull-request-approval.ts +41 -0
- package/src/operations/sync-pull-request.ts +37 -0
- package/src/operations/sync.test.ts +453 -0
- package/src/operations/sync.ts +807 -0
- package/src/plugin.test.ts +40 -0
- package/src/plugin.ts +37 -0
- package/src/pull-request-body.test.ts +61 -0
- package/src/pull-request-body.ts +144 -0
- package/src/pull-request.test.ts +67 -0
- package/src/pull-request.ts +80 -0
- package/src/services/github-api.ts +735 -0
- package/src/services/index.ts +5 -0
- package/src/skills/GitHubSkill.ts +46 -0
- package/src/skills/index.ts +5 -0
- package/src/stories/Generate.stories.tsx +152 -0
- package/src/stories/Links.stories.tsx +153 -0
- package/src/stories/PullRequestArticle.stories.tsx +107 -0
- package/src/stories/PullRequestFiles.stories.tsx +69 -0
- package/src/stories/PullRequestOverview.stories.tsx +113 -0
- package/src/stories/PullRequestsArticle.stories.tsx +170 -0
- package/src/stories/Walkthrough.stories.tsx +110 -0
- package/src/stories/github.test.ts +65 -0
- package/src/stories/github.ts +70 -0
- package/src/stories/walkthrough-fixture.ts +115 -0
- package/src/testing/fixtures.ts +99 -0
- package/src/testing/index.ts +7 -0
- package/src/testing/plugin.ts +25 -0
- package/src/testing/pull-request-13348.ts +104 -0
- package/src/testing/pull-request-13363.patch +2981 -0
- package/src/translations.ts +135 -63
- package/src/types/GitHubCapabilities.ts +27 -0
- package/src/types/GitHubEvents.ts +16 -0
- package/src/types/GitHubOperation.ts +371 -0
- package/src/types/PullRequestsView.ts +45 -0
- package/src/types/Walkthrough.test.ts +75 -0
- package/src/types/Walkthrough.ts +66 -0
- package/src/types/index.ts +8 -0
- package/src/vite-env.d.ts +15 -0
- package/src/walkthrough/fill.test.ts +337 -0
- package/src/walkthrough/fill.ts +246 -0
- package/src/walkthrough/generate.test.ts +219 -0
- package/src/walkthrough/generate.ts +248 -0
- package/src/walkthrough/generated.test.ts +70 -0
- package/src/walkthrough/generated.ts +70 -0
- package/src/walkthrough/headings.test.ts +40 -0
- package/src/walkthrough/headings.ts +39 -0
- package/src/walkthrough/index.ts +12 -0
- package/src/walkthrough/patch.ts +154 -0
- package/src/walkthrough/plan.test.ts +178 -0
- package/src/walkthrough/plan.ts +251 -0
- package/src/walkthrough/prompt.test.ts +100 -0
- package/src/walkthrough/prompt.ts +147 -0
- package/src/walkthrough/score.test.ts +272 -0
- package/src/walkthrough/score.ts +430 -0
- package/README.md +0 -15
- package/dist/lib/browser/chunk-S4MPSBA5.mjs +0 -21
- package/dist/lib/browser/chunk-S4MPSBA5.mjs.map +0 -7
- package/dist/lib/browser/index.css +0 -7
- package/dist/lib/browser/index.css.map +0 -7
- package/dist/lib/browser/index.mjs +0 -1535
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/meta.mjs +0 -11
- package/dist/lib/browser/meta.mjs.map +0 -7
- package/dist/types/src/GithubPlugin.d.ts +0 -4
- package/dist/types/src/GithubPlugin.d.ts.map +0 -1
- package/dist/types/src/components/EmbeddedMain/EmbeddedMain.d.ts +0 -4
- package/dist/types/src/components/EmbeddedMain/EmbeddedMain.d.ts.map +0 -1
- package/dist/types/src/components/EmbeddedMain/GfmPreview.d.ts +0 -9
- package/dist/types/src/components/EmbeddedMain/GfmPreview.d.ts.map +0 -1
- package/dist/types/src/components/EmbeddedMain/index.d.ts +0 -2
- package/dist/types/src/components/EmbeddedMain/index.d.ts.map +0 -1
- package/dist/types/src/components/ExportDialog.d.ts +0 -8
- package/dist/types/src/components/ExportDialog.d.ts.map +0 -1
- package/dist/types/src/components/GithubApiProviders/GitHubSettings.d.ts +0 -3
- package/dist/types/src/components/GithubApiProviders/GitHubSettings.d.ts.map +0 -1
- package/dist/types/src/components/GithubApiProviders/OctokitProvider.d.ts +0 -15
- package/dist/types/src/components/GithubApiProviders/OctokitProvider.d.ts.map +0 -1
- package/dist/types/src/components/GithubApiProviders/index.d.ts +0 -3
- package/dist/types/src/components/GithubApiProviders/index.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/DocumentTreeItem.d.ts +0 -6
- package/dist/types/src/components/GithubEchoResolverProviders/DocumentTreeItem.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverContext.d.ts +0 -7
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverContext.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverDialog.d.ts +0 -6
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverDialog.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverProps.d.ts +0 -16
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverProps.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverTree.d.ts +0 -3
- package/dist/types/src/components/GithubEchoResolverProviders/ResolverTree.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.d.ts +0 -11
- package/dist/types/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/index.d.ts +0 -3
- package/dist/types/src/components/GithubEchoResolverProviders/index.d.ts.map +0 -1
- package/dist/types/src/components/GithubEchoResolverProviders/spaceResolvers.d.ts +0 -6
- package/dist/types/src/components/GithubEchoResolverProviders/spaceResolvers.d.ts.map +0 -1
- package/dist/types/src/components/ImportDialog.d.ts +0 -7
- package/dist/types/src/components/ImportDialog.d.ts.map +0 -1
- package/dist/types/src/components/Issue.d.ts +0 -5
- package/dist/types/src/components/Issue.d.ts.map +0 -1
- package/dist/types/src/components/Loading/Loading.d.ts +0 -15
- package/dist/types/src/components/Loading/Loading.d.ts.map +0 -1
- package/dist/types/src/components/Loading/Loading.stories.d.ts +0 -40
- package/dist/types/src/components/Loading/Loading.stories.d.ts.map +0 -1
- package/dist/types/src/components/Loading/index.d.ts +0 -2
- package/dist/types/src/components/Loading/index.d.ts.map +0 -1
- package/dist/types/src/components/MarkdownActions.d.ts +0 -7
- package/dist/types/src/components/MarkdownActions.d.ts.map +0 -1
- package/dist/types/src/components/UrlDialog.d.ts +0 -6
- package/dist/types/src/components/UrlDialog.d.ts.map +0 -1
- package/dist/types/src/hooks/useDocGhId.d.ts +0 -6
- package/dist/types/src/hooks/useDocGhId.d.ts.map +0 -1
- package/dist/types/src/hooks/useGhIdFromUrl.d.ts +0 -2
- package/dist/types/src/hooks/useGhIdFromUrl.d.ts.map +0 -1
- package/dist/types/src/types.d.ts +0 -30
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/GithubPlugin.tsx +0 -127
- package/src/components/EmbeddedMain/EmbeddedMain.tsx +0 -294
- package/src/components/EmbeddedMain/GfmPreview.tsx +0 -110
- package/src/components/EmbeddedMain/embedded.css +0 -3
- package/src/components/EmbeddedMain/index.ts +0 -5
- package/src/components/ExportDialog.tsx +0 -157
- package/src/components/GithubApiProviders/GitHubSettings.tsx +0 -72
- package/src/components/GithubApiProviders/OctokitProvider.tsx +0 -60
- package/src/components/GithubApiProviders/index.ts +0 -6
- package/src/components/GithubEchoResolverProviders/DocumentTreeItem.tsx +0 -26
- package/src/components/GithubEchoResolverProviders/ResolverContext.tsx +0 -137
- package/src/components/GithubEchoResolverProviders/ResolverDialog.tsx +0 -34
- package/src/components/GithubEchoResolverProviders/ResolverProps.ts +0 -23
- package/src/components/GithubEchoResolverProviders/ResolverTree.tsx +0 -86
- package/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.tsx +0 -105
- package/src/components/GithubEchoResolverProviders/index.ts +0 -6
- package/src/components/GithubEchoResolverProviders/spaceResolvers.ts +0 -86
- package/src/components/ImportDialog.tsx +0 -72
- package/src/components/Issue.tsx +0 -62
- package/src/components/Loading/Loading.stories.tsx +0 -32
- package/src/components/Loading/Loading.tsx +0 -70
- package/src/components/Loading/index.ts +0 -5
- package/src/components/MarkdownActions.tsx +0 -136
- package/src/components/UrlDialog.tsx +0 -52
- package/src/hooks/useDocGhId.ts +0 -38
- package/src/hooks/useGhIdFromUrl.ts +0 -26
- package/src/types.ts +0 -51
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
|
|
8
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
9
|
+
|
|
10
|
+
import { GitHubOperation } from '#types';
|
|
11
|
+
|
|
12
|
+
import { GitHubApi } from '../services/index.ts';
|
|
13
|
+
import { resolvePullRequest } from './pull-request.ts';
|
|
14
|
+
|
|
15
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.AddPullRequestReviewComment> =
|
|
16
|
+
GitHubOperation.AddPullRequestReviewComment.pipe(
|
|
17
|
+
Operation.withHandler(
|
|
18
|
+
Effect.fn(function* ({ pullRequest: ref, body, commit, path, line, side }) {
|
|
19
|
+
const { pullRequest, credentials } = yield* resolvePullRequest(ref);
|
|
20
|
+
const comment = yield* GitHubApi.createReviewComment(pullRequest.owner, pullRequest.repo, pullRequest.number, {
|
|
21
|
+
body,
|
|
22
|
+
commit_id: commit,
|
|
23
|
+
path,
|
|
24
|
+
line,
|
|
25
|
+
side,
|
|
26
|
+
}).pipe(Effect.provide(credentials));
|
|
27
|
+
return { commentId: comment.id, url: comment.html_url ?? undefined };
|
|
28
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export default handler;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as LanguageModel from 'effect/ai/LanguageModel';
|
|
6
|
+
import * as Cause from 'effect/Cause';
|
|
7
|
+
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as Exit from 'effect/Exit';
|
|
9
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
10
|
+
import * as Layer from 'effect/Layer';
|
|
11
|
+
|
|
12
|
+
import { AiService } from '@dxos/ai';
|
|
13
|
+
import * as Progress from '@dxos/app-toolkit/Progress';
|
|
14
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
15
|
+
import * as Trace from '@dxos/compute/Trace';
|
|
16
|
+
import { Database, Obj, Ref } from '@dxos/echo';
|
|
17
|
+
import { PullRequest } from '@dxos/types';
|
|
18
|
+
|
|
19
|
+
import { GitHubOperation } from '#types';
|
|
20
|
+
|
|
21
|
+
import { GitHubPullRequestUnstoredError } from '../errors.ts';
|
|
22
|
+
import { GitHubApi } from '../services/index.ts';
|
|
23
|
+
import { GENERATE_PHASES, generateWalkthrough } from '../walkthrough/index.ts';
|
|
24
|
+
import { githubToken } from './pull-request.ts';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* One-shot for now; a multi-turn agent that reads the repository is the obvious next step.
|
|
28
|
+
*
|
|
29
|
+
* The prompt's diff budget matters more than it looks: this model's output allowance covers its
|
|
30
|
+
* reasoning as well as its answer, so an unbounded diff yields a response that is all reasoning and
|
|
31
|
+
* no walkthrough. See `DEFAULT_MAX_DIFF_CHARS`.
|
|
32
|
+
*/
|
|
33
|
+
const MODEL = 'com.anthropic.model.claude-sonnet-5.default';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Generate a walkthrough of a pull request.
|
|
37
|
+
*
|
|
38
|
+
* Only the I/O is here — fetch the pull request, fetch its diff, run the model — because that is the
|
|
39
|
+
* part a test cannot reach. The decisions live in {@link generateWalkthrough}.
|
|
40
|
+
*/
|
|
41
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.GenerateWalkthrough> =
|
|
42
|
+
GitHubOperation.GenerateWalkthrough.pipe(
|
|
43
|
+
Operation.withHandler(
|
|
44
|
+
Effect.fn(function* ({ pullRequest: pullRequestRef, force }) {
|
|
45
|
+
// The invoker carries no database resolver, so the handler derives one from its input, as
|
|
46
|
+
// every other operation in this plugin does.
|
|
47
|
+
const pullRequest = pullRequestRef.target;
|
|
48
|
+
const db = pullRequest ? Obj.getDatabase(pullRequest) : undefined;
|
|
49
|
+
if (!pullRequest || !db) {
|
|
50
|
+
// A preview card mints a pull request in memory rather than storing it, and there is
|
|
51
|
+
// nowhere to put a walkthrough of one.
|
|
52
|
+
return yield* Effect.die(new GitHubPullRequestUnstoredError());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const traceWriter = yield* Trace.TraceService;
|
|
56
|
+
const progressKey = GitHubOperation.createWalkthroughProgressKey(pullRequest);
|
|
57
|
+
const label = `Walkthrough of ${PullRequest.reference(pullRequest)}`;
|
|
58
|
+
// Phase-first, since several meters on one object otherwise truncate to the same text.
|
|
59
|
+
const report = (message: string, current: number) =>
|
|
60
|
+
traceWriter.write(Trace.StatusUpdate, {
|
|
61
|
+
message,
|
|
62
|
+
progress: { key: progressKey, current, total: GENERATE_PHASES },
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return yield* Effect.gen(function* () {
|
|
66
|
+
report(label, 0);
|
|
67
|
+
const { owner, repo, number } = pullRequest;
|
|
68
|
+
const credentials = Layer.succeed(GitHubApi.GitHubCredentials, { token: yield* githubToken() });
|
|
69
|
+
|
|
70
|
+
report(`${label}: reading the pull request`, 1);
|
|
71
|
+
const remote = yield* GitHubApi.fetchPullRequest(owner, repo, number).pipe(Effect.provide(credentials));
|
|
72
|
+
|
|
73
|
+
report(`${label}: fetching the diff`, 2);
|
|
74
|
+
const diff = yield* GitHubApi.fetchPullRequestDiff(owner, repo, number).pipe(Effect.provide(credentials));
|
|
75
|
+
|
|
76
|
+
const result = yield* generateWalkthrough({
|
|
77
|
+
pullRequest,
|
|
78
|
+
remote: {
|
|
79
|
+
title: remote.title,
|
|
80
|
+
description: remote.body ?? undefined,
|
|
81
|
+
baseBranch: remote.base?.ref,
|
|
82
|
+
headBranch: remote.head?.ref,
|
|
83
|
+
commit: remote.head?.sha,
|
|
84
|
+
},
|
|
85
|
+
diff,
|
|
86
|
+
force,
|
|
87
|
+
model: MODEL,
|
|
88
|
+
report,
|
|
89
|
+
narrate: (prompt) =>
|
|
90
|
+
LanguageModel.generateText({ prompt }).pipe(
|
|
91
|
+
Effect.map((response) => response.text),
|
|
92
|
+
Effect.provide(AiService.languageModel(MODEL).pipe(Layer.orDie)),
|
|
93
|
+
Effect.orDie,
|
|
94
|
+
),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
walkthrough: Ref.make(result.walkthrough),
|
|
99
|
+
generated: result.generated,
|
|
100
|
+
covered: result.covered,
|
|
101
|
+
total: result.total,
|
|
102
|
+
};
|
|
103
|
+
}).pipe(
|
|
104
|
+
// The meter stays open forever without a terminal, and the sentinel is all the UI shows —
|
|
105
|
+
// the failure itself goes to the log.
|
|
106
|
+
// `onExit`, not `tapError`: the model call and the database both surface as DEFECTS rather
|
|
107
|
+
// than typed errors, and interruption raises neither. A meter with no terminal stays open
|
|
108
|
+
// and leaves the action disabled.
|
|
109
|
+
Effect.onExit((exit) =>
|
|
110
|
+
Effect.sync(() => {
|
|
111
|
+
if (Exit.isSuccess(exit)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const terminal = Cause.hasInterrupts(exit.cause) ? Progress.STATUS_CANCELLED : Progress.STATUS_FAILED;
|
|
115
|
+
report(terminal, GENERATE_PHASES);
|
|
116
|
+
}),
|
|
117
|
+
),
|
|
118
|
+
Effect.provide(Database.layer(db)),
|
|
119
|
+
);
|
|
120
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
121
|
+
),
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
export default handler;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
|
|
8
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
9
|
+
|
|
10
|
+
import { GitHubOperation } from '#types';
|
|
11
|
+
|
|
12
|
+
import { GitHubApi } from '../services/index.ts';
|
|
13
|
+
import { resolvePullRequest } from './pull-request.ts';
|
|
14
|
+
|
|
15
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.GetPullRequestDiff> =
|
|
16
|
+
GitHubOperation.GetPullRequestDiff.pipe(
|
|
17
|
+
Operation.withHandler(
|
|
18
|
+
Effect.fn(function* ({ pullRequest: ref }) {
|
|
19
|
+
const { pullRequest, credentials } = yield* resolvePullRequest(ref);
|
|
20
|
+
const { owner, repo, number } = pullRequest;
|
|
21
|
+
const [before, diff, after] = yield* Effect.all(
|
|
22
|
+
[
|
|
23
|
+
GitHubApi.fetchPullRequest(owner, repo, number),
|
|
24
|
+
GitHubApi.fetchPullRequestDiff(owner, repo, number),
|
|
25
|
+
GitHubApi.fetchPullRequest(owner, repo, number),
|
|
26
|
+
],
|
|
27
|
+
{ concurrency: 1 },
|
|
28
|
+
).pipe(Effect.provide(credentials));
|
|
29
|
+
// A push between the reads would pair the diff with another commit's line numbers, so the
|
|
30
|
+
// commit is only reported when the head held still across the diff.
|
|
31
|
+
const commit = before.head?.sha;
|
|
32
|
+
return { diff, ...(commit && commit === after.head?.sha ? { commit } : {}) };
|
|
33
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
34
|
+
),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export default handler;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
|
|
8
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
9
|
+
import { type PullRequest } from '@dxos/types';
|
|
10
|
+
|
|
11
|
+
import { GitHubOperation } from '#types';
|
|
12
|
+
|
|
13
|
+
import { GitHubApi } from '../services/index.ts';
|
|
14
|
+
import { resolvePullRequest, summarizeCheckRuns, summarizeReviews, toCheckRun } from './pull-request.ts';
|
|
15
|
+
|
|
16
|
+
const toState = (pull: GitHubApi.GitHubPull): PullRequest.State =>
|
|
17
|
+
pull.merged || pull.merged_at ? 'merged' : pull.draft ? 'draft' : pull.state === 'closed' ? 'closed' : 'open';
|
|
18
|
+
|
|
19
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.GetPullRequestStatus> =
|
|
20
|
+
GitHubOperation.GetPullRequestStatus.pipe(
|
|
21
|
+
Operation.withHandler(
|
|
22
|
+
Effect.fn(function* ({ pullRequest: ref }) {
|
|
23
|
+
const { pullRequest, credentials } = yield* resolvePullRequest(ref);
|
|
24
|
+
const { owner, repo, number } = pullRequest;
|
|
25
|
+
const pull = yield* GitHubApi.fetchPullRequest(owner, repo, number).pipe(Effect.provide(credentials));
|
|
26
|
+
const commit = pull.head?.sha;
|
|
27
|
+
const runs = commit
|
|
28
|
+
? yield* GitHubApi.fetchCheckRuns(owner, repo, commit).pipe(Effect.provide(credentials))
|
|
29
|
+
: [];
|
|
30
|
+
const reviews = yield* GitHubApi.fetchReviews(owner, repo, number).pipe(Effect.provide(credentials));
|
|
31
|
+
return {
|
|
32
|
+
state: toState(pull),
|
|
33
|
+
title: pull.title,
|
|
34
|
+
commit,
|
|
35
|
+
...(pull.body ? { body: pull.body } : {}),
|
|
36
|
+
...summarizeCheckRuns(runs),
|
|
37
|
+
runs: runs.map(toCheckRun),
|
|
38
|
+
...summarizeReviews(reviews),
|
|
39
|
+
};
|
|
40
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export default handler;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
import * as Layer from 'effect/Layer';
|
|
8
|
+
|
|
9
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
10
|
+
import { Database, Obj } from '@dxos/echo';
|
|
11
|
+
|
|
12
|
+
import { GitHubOperation } from '#types';
|
|
13
|
+
|
|
14
|
+
import { GitHubApi } from '../services/index.ts';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Discovery only — list GitHub repositories reachable from the connection's
|
|
18
|
+
* token. Read-only: NO local Projects are created here. Materialization is
|
|
19
|
+
* handled by the connector's `materializeTarget` when a binding is created.
|
|
20
|
+
*
|
|
21
|
+
* Output is sorted by `full_name` (case-insensitive) so the picker is stable
|
|
22
|
+
* regardless of GitHub's response order.
|
|
23
|
+
*/
|
|
24
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.GetGitHubRepositories> =
|
|
25
|
+
GitHubOperation.GetGitHubRepositories.pipe(
|
|
26
|
+
Operation.withHandler(
|
|
27
|
+
Effect.fn(function* ({ connection }) {
|
|
28
|
+
// TODO(wittjosiah): Mirror the Trello pattern — derive the db from the input ref's
|
|
29
|
+
// target until the OperationInvoker has a `databaseResolver` and the operation
|
|
30
|
+
// can declare `services: [Database.Service]` directly.
|
|
31
|
+
const target = connection.target;
|
|
32
|
+
const db = target ? Obj.getDatabase(target) : undefined;
|
|
33
|
+
if (!db) {
|
|
34
|
+
return yield* Effect.die(new Error('No database for connection ref.'));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return yield* Effect.gen(function* () {
|
|
38
|
+
const remoteRepos = yield* GitHubApi.fetchUserRepos();
|
|
39
|
+
const sorted = [...remoteRepos].sort((left, right) =>
|
|
40
|
+
left.full_name.toLowerCase().localeCompare(right.full_name.toLowerCase()),
|
|
41
|
+
);
|
|
42
|
+
const targets = sorted.map((repo) => ({
|
|
43
|
+
id: String(repo.id),
|
|
44
|
+
name: repo.full_name,
|
|
45
|
+
description: repo.description ?? undefined,
|
|
46
|
+
}));
|
|
47
|
+
return { targets };
|
|
48
|
+
}).pipe(Effect.provide(Layer.provideMerge(Database.layer(db), GitHubApi.fromConnection(connection))));
|
|
49
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
export default handler;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
8
|
+
|
|
9
|
+
import { GitHubOperation } from '#types';
|
|
10
|
+
|
|
11
|
+
import { GitHubPullRequestReferenceError } from '../errors.ts';
|
|
12
|
+
import { parsePullRequestReference } from '../github-link.ts';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Import the pull request the extension's page is showing.
|
|
16
|
+
*
|
|
17
|
+
* The snapshot is read for its URL alone — the page's DOM says nothing GitHub's API does not say
|
|
18
|
+
* better — and the import itself is delegated, so the anonymous fallback and the existing-object
|
|
19
|
+
* check stay in one place.
|
|
20
|
+
*/
|
|
21
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.ImportPullRequestFromSnapshot> =
|
|
22
|
+
GitHubOperation.ImportPullRequestFromSnapshot.pipe(
|
|
23
|
+
Operation.withHandler(
|
|
24
|
+
Effect.fn(function* ({ snapshot, target }) {
|
|
25
|
+
const reference = snapshot.source.url;
|
|
26
|
+
if (!parsePullRequestReference(reference)) {
|
|
27
|
+
return yield* Effect.die(new GitHubPullRequestReferenceError({ context: { reference } }));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { pullRequest } = yield* Operation.invoke(
|
|
31
|
+
GitHubOperation.ImportPullRequest,
|
|
32
|
+
{ reference },
|
|
33
|
+
{ spaceId: target.spaceId },
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// The extension acks with an object id so the page can open what it just imported; a ref
|
|
37
|
+
// whose target did not resolve would ack success on nothing.
|
|
38
|
+
const object = pullRequest.target;
|
|
39
|
+
if (!object) {
|
|
40
|
+
return yield* Effect.die(new GitHubPullRequestReferenceError({ context: { reference } }));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { id: object.id };
|
|
44
|
+
}),
|
|
45
|
+
),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
export default handler;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
import * as HttpClient from 'effect/http/HttpClient';
|
|
8
|
+
import * as HttpClientError from 'effect/http/HttpClientError';
|
|
9
|
+
import * as HttpClientRequest from 'effect/http/HttpClientRequest';
|
|
10
|
+
import * as HttpClientResponse from 'effect/http/HttpClientResponse';
|
|
11
|
+
import { describe, test } from 'vitest';
|
|
12
|
+
|
|
13
|
+
import * as EffectEx from '@dxos/effect/EffectEx';
|
|
14
|
+
|
|
15
|
+
import { GitHubRepoInaccessibleError } from '../errors.ts';
|
|
16
|
+
import { GitHubApi } from '../services/index.ts';
|
|
17
|
+
import { fetchPullRequestWithFallback } from './import-pull-request.ts';
|
|
18
|
+
|
|
19
|
+
const reference = { owner: 'dxos', repo: 'dxos', number: 13188 };
|
|
20
|
+
|
|
21
|
+
/** The stubs answer without a request, but the fetch signature still carries the client the real one needs. */
|
|
22
|
+
const run = <T>(effect: Effect.Effect<T, never, HttpClient.HttpClient>) =>
|
|
23
|
+
EffectEx.runAndForwardErrors(effect.pipe(Effect.provide(FetchHttpClient.layer)));
|
|
24
|
+
|
|
25
|
+
const pull: GitHubApi.GitHubPull = { id: 1, number: reference.number, title: 'Walkthroughs', state: 'open' };
|
|
26
|
+
|
|
27
|
+
/** The failure `HttpClient.filterStatusOk` produces for a non-2xx GitHub response. */
|
|
28
|
+
const statusError = (status: number) => {
|
|
29
|
+
const request = HttpClientRequest.get('https://api.github.com/repos/dxos/dxos/pulls/13188');
|
|
30
|
+
return new HttpClientError.HttpClientError({
|
|
31
|
+
reason: new HttpClientError.StatusCodeError({
|
|
32
|
+
request,
|
|
33
|
+
response: HttpClientResponse.fromWeb(request, new Response(null, { status })),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Answers every authenticated request with `status` and every anonymous one with the pull request. */
|
|
39
|
+
const fetchRejectingToken = (status: number, tokens: string[]) => (_owner: string, _repo: string, _number: number) =>
|
|
40
|
+
Effect.gen(function* () {
|
|
41
|
+
const { token } = yield* GitHubApi.GitHubCredentials;
|
|
42
|
+
tokens.push(token);
|
|
43
|
+
if (token !== '') {
|
|
44
|
+
return yield* Effect.fail(statusError(status));
|
|
45
|
+
}
|
|
46
|
+
return pull;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('import — token fallback', () => {
|
|
50
|
+
test('a token GitHub rejects is retried anonymously', async ({ expect }) => {
|
|
51
|
+
const tokens: string[] = [];
|
|
52
|
+
const result = await run(fetchPullRequestWithFallback(reference, 'dead-token', fetchRejectingToken(401, tokens)));
|
|
53
|
+
|
|
54
|
+
expect(result).toEqual(pull);
|
|
55
|
+
expect(tokens).toEqual(['dead-token', '']);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('a token that works is not retried', async ({ expect }) => {
|
|
59
|
+
const tokens: string[] = [];
|
|
60
|
+
const result = await run(
|
|
61
|
+
fetchPullRequestWithFallback(reference, 'live-token', (_owner, _repo, _number) =>
|
|
62
|
+
Effect.gen(function* () {
|
|
63
|
+
tokens.push((yield* GitHubApi.GitHubCredentials).token);
|
|
64
|
+
return pull;
|
|
65
|
+
}),
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(result).toEqual(pull);
|
|
70
|
+
expect(tokens).toEqual(['live-token']);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('unauthorized anonymously too reports the repository as inaccessible', async ({ expect }) => {
|
|
74
|
+
const tokens: string[] = [];
|
|
75
|
+
const error = await run(
|
|
76
|
+
fetchPullRequestWithFallback(reference, 'dead-token', (_owner, _repo, _number) =>
|
|
77
|
+
Effect.gen(function* () {
|
|
78
|
+
tokens.push((yield* GitHubApi.GitHubCredentials).token);
|
|
79
|
+
return yield* Effect.fail(statusError(401));
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
).then(
|
|
83
|
+
() => undefined,
|
|
84
|
+
(error) => error,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
expect(GitHubRepoInaccessibleError.is(error)).toBe(true);
|
|
88
|
+
expect((error as GitHubRepoInaccessibleError).context).toMatchObject({
|
|
89
|
+
...reference,
|
|
90
|
+
status: 401,
|
|
91
|
+
connected: true,
|
|
92
|
+
tokenStatus: 401,
|
|
93
|
+
});
|
|
94
|
+
expect(tokens).toEqual(['dead-token', '']);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// GitHub answers 404 rather than 403 wherever a credential lacks access, so a GitHub App token
|
|
98
|
+
// whose installation does not cover the repository reports a PUBLIC pull request as absent.
|
|
99
|
+
// Retrying anonymously is the only way to tell that apart from one that really does not exist.
|
|
100
|
+
for (const status of [403, 404]) {
|
|
101
|
+
test(`a public pull request survives a token scoped away from it (${status})`, async ({ expect }) => {
|
|
102
|
+
const tokens: string[] = [];
|
|
103
|
+
const result = await run(
|
|
104
|
+
fetchPullRequestWithFallback(reference, 'scoped-token', fetchRejectingToken(status, tokens)),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
expect(result).toEqual(pull);
|
|
108
|
+
expect(tokens).toEqual(['scoped-token', '']);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
test('a pull request unreachable with and without the token keeps the token status', async ({ expect }) => {
|
|
113
|
+
const error = await run(
|
|
114
|
+
fetchPullRequestWithFallback(reference, 'scoped-token', () => Effect.fail(statusError(404))),
|
|
115
|
+
).then(
|
|
116
|
+
() => undefined,
|
|
117
|
+
(error) => error,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
expect(GitHubRepoInaccessibleError.is(error)).toBe(true);
|
|
121
|
+
expect((error as GitHubRepoInaccessibleError).context).toMatchObject({
|
|
122
|
+
status: 404,
|
|
123
|
+
connected: true,
|
|
124
|
+
tokenStatus: 404,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('a space with no connection reports itself as unconnected', async ({ expect }) => {
|
|
129
|
+
const tokens: string[] = [];
|
|
130
|
+
const error = await run(
|
|
131
|
+
fetchPullRequestWithFallback(reference, '', (_owner, _repo, _number) =>
|
|
132
|
+
Effect.gen(function* () {
|
|
133
|
+
tokens.push((yield* GitHubApi.GitHubCredentials).token);
|
|
134
|
+
return yield* Effect.fail(statusError(404));
|
|
135
|
+
}),
|
|
136
|
+
),
|
|
137
|
+
).then(
|
|
138
|
+
() => undefined,
|
|
139
|
+
(error) => error,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(GitHubRepoInaccessibleError.is(error)).toBe(true);
|
|
143
|
+
expect((error as GitHubRepoInaccessibleError).context).toMatchObject({
|
|
144
|
+
status: 404,
|
|
145
|
+
connected: false,
|
|
146
|
+
tokenStatus: undefined,
|
|
147
|
+
});
|
|
148
|
+
// No credential to fall back from, so the anonymous request is the only one made.
|
|
149
|
+
expect(tokens).toEqual(['']);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as FetchHttpClient from 'effect/http/FetchHttpClient';
|
|
7
|
+
import * as Layer from 'effect/Layer';
|
|
8
|
+
|
|
9
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
10
|
+
import { Database, Filter, Ref } from '@dxos/echo';
|
|
11
|
+
import * as SpaceOperation from '@dxos/plugin-space/SpaceOperation';
|
|
12
|
+
import { PullRequest } from '@dxos/types';
|
|
13
|
+
|
|
14
|
+
import { GitHubOperation } from '#types';
|
|
15
|
+
|
|
16
|
+
import { GitHubPullRequestReferenceError, GitHubRepoInaccessibleError } from '../errors.ts';
|
|
17
|
+
import { type PullRequestReference, parsePullRequestReference } from '../github-link.ts';
|
|
18
|
+
import { toPullRequestProps } from '../pull-request.ts';
|
|
19
|
+
import { GitHubApi } from '../services/index.ts';
|
|
20
|
+
import { githubToken } from './pull-request.ts';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Statuses that may report the token's reach rather than the repository's absence, and so are worth
|
|
24
|
+
* a second, anonymous attempt.
|
|
25
|
+
*
|
|
26
|
+
* 404 is the load-bearing one. GitHub answers 404 rather than 403 wherever a credential lacks access,
|
|
27
|
+
* so as not to confirm what it cannot show, and a GitHub App user-to-server token — what this
|
|
28
|
+
* connector holds — reaches only the repositories the App is installed on. A public repository the
|
|
29
|
+
* App was never installed on therefore reads as absent. (A fine-grained PAT would not behave this
|
|
30
|
+
* way: those carry read access to every public repository regardless of their selection.)
|
|
31
|
+
*
|
|
32
|
+
* Whatever produced it, the rule is the same: a status that a credential could have caused says
|
|
33
|
+
* nothing about what an anonymous reader can see, and only the anonymous request settles it.
|
|
34
|
+
*/
|
|
35
|
+
const MAY_REFLECT_TOKEN_SCOPE = new Set([401, 403, 404]);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The pull request as the space's GitHub connection, falling back to an anonymous read whenever the
|
|
39
|
+
* stored token is what stood in the way.
|
|
40
|
+
*
|
|
41
|
+
* A public pull request must never fail because of a credential. Three separate conditions make one
|
|
42
|
+
* look unreachable — a revoked token (401), a suspended or SSO-blocked one (403), and a repository
|
|
43
|
+
* outside the App installation the token belongs to (404) — and the anonymous retry, which is the
|
|
44
|
+
* same request a space with no connection would make, resolves all three. The cost is one extra
|
|
45
|
+
* request on a pull request that genuinely does not exist.
|
|
46
|
+
*
|
|
47
|
+
* `fetch` is injected so the fallback can be exercised without an HTTP client.
|
|
48
|
+
*/
|
|
49
|
+
export const fetchPullRequestWithFallback = (
|
|
50
|
+
{ owner, repo, number }: PullRequestReference,
|
|
51
|
+
token: string,
|
|
52
|
+
fetch: (
|
|
53
|
+
owner: string,
|
|
54
|
+
repo: string,
|
|
55
|
+
number: number,
|
|
56
|
+
) => GitHubApi.GitHubEffect<GitHubApi.GitHubPull> = GitHubApi.fetchPullRequest,
|
|
57
|
+
) =>
|
|
58
|
+
// Suspended so each run starts with its own `tokenStatus`, which the fallback sets as it runs.
|
|
59
|
+
Effect.suspend(() => {
|
|
60
|
+
const fetchAs = (token: string) =>
|
|
61
|
+
fetch(owner, repo, number).pipe(Effect.provide(Layer.succeed(GitHubApi.GitHubCredentials, { token })));
|
|
62
|
+
|
|
63
|
+
// What the authenticated attempt answered, kept so a rejected credential (401) can be told from a
|
|
64
|
+
// repository the credential simply does not reach (403/404) once the retry has also failed.
|
|
65
|
+
let tokenStatus: number | undefined;
|
|
66
|
+
|
|
67
|
+
return fetchAs(token).pipe(
|
|
68
|
+
Effect.catchIf(
|
|
69
|
+
(error) => {
|
|
70
|
+
const status = GitHubApi.responseStatus(error);
|
|
71
|
+
return token !== '' && status !== undefined && MAY_REFLECT_TOKEN_SCOPE.has(status);
|
|
72
|
+
},
|
|
73
|
+
(error) => {
|
|
74
|
+
tokenStatus = GitHubApi.responseStatus(error);
|
|
75
|
+
return fetchAs('');
|
|
76
|
+
},
|
|
77
|
+
),
|
|
78
|
+
// Out of reach anonymously too (GitHub answers 404 for a private repository seen without
|
|
79
|
+
// credentials): a typed failure lets the dialog name the connection rather than the reference.
|
|
80
|
+
Effect.catchIf(
|
|
81
|
+
(error) => {
|
|
82
|
+
const status = GitHubApi.responseStatus(error);
|
|
83
|
+
return status !== undefined && MAY_REFLECT_TOKEN_SCOPE.has(status);
|
|
84
|
+
},
|
|
85
|
+
(error) =>
|
|
86
|
+
Effect.die(
|
|
87
|
+
new GitHubRepoInaccessibleError({
|
|
88
|
+
context: {
|
|
89
|
+
owner,
|
|
90
|
+
repo,
|
|
91
|
+
number,
|
|
92
|
+
status: GitHubApi.responseStatus(error),
|
|
93
|
+
connected: token !== '',
|
|
94
|
+
tokenStatus,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
),
|
|
98
|
+
),
|
|
99
|
+
Effect.orDie,
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Import a pull request the user named, as the space's GitHub connection or anonymously.
|
|
105
|
+
*
|
|
106
|
+
* The object is filed through `SpaceOperation.AddObject` rather than added directly: an imported
|
|
107
|
+
* pull request is something the user went looking for, so it belongs where they can find it again.
|
|
108
|
+
*/
|
|
109
|
+
const handler: Operation.WithHandler<typeof GitHubOperation.ImportPullRequest> = GitHubOperation.ImportPullRequest.pipe(
|
|
110
|
+
Operation.withHandler(
|
|
111
|
+
Effect.fn(function* ({ reference }) {
|
|
112
|
+
const parsed = parsePullRequestReference(reference);
|
|
113
|
+
if (!parsed) {
|
|
114
|
+
return yield* Effect.die(new GitHubPullRequestReferenceError({ context: { reference } }));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const { owner, repo, number } = parsed;
|
|
118
|
+
const [existing] = yield* Database.query(Filter.type(PullRequest.PullRequest, { owner, repo, number })).run.pipe(
|
|
119
|
+
Effect.orDie,
|
|
120
|
+
);
|
|
121
|
+
if (existing) {
|
|
122
|
+
return { pullRequest: Ref.make(existing), imported: false };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const pull = yield* fetchPullRequestWithFallback(parsed, yield* githubToken());
|
|
126
|
+
|
|
127
|
+
const { object } = yield* Operation.invoke(SpaceOperation.AddObject, {
|
|
128
|
+
object: PullRequest.make(toPullRequestProps(parsed, pull)),
|
|
129
|
+
});
|
|
130
|
+
// `AddObject` answers with what it filed, typed as any object; the narrowing is what makes the
|
|
131
|
+
// returned ref a pull request's rather than a cast.
|
|
132
|
+
if (!PullRequest.instanceOf(object)) {
|
|
133
|
+
return yield* Effect.die(new GitHubPullRequestReferenceError({ context: { reference } }));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { pullRequest: Ref.make(object), imported: true };
|
|
137
|
+
}, Effect.provide(FetchHttpClient.layer)),
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
export default handler;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
6
|
+
import * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';
|
|
7
|
+
|
|
8
|
+
import { GitHubOperation } from '#types';
|
|
9
|
+
|
|
10
|
+
export const GitHubOperationHandlerSet = OperationHandlerSet.lazy([
|
|
11
|
+
GitHubOperation.GetGitHubRepositories.pipe(Operation.lazyHandler(() => import('./get-repositories.ts'))),
|
|
12
|
+
GitHubOperation.MaterializeGitHubTarget.pipe(Operation.lazyHandler(() => import('./materialize-target.ts'))),
|
|
13
|
+
GitHubOperation.SyncGitHubRepositories.pipe(Operation.lazyHandler(() => import('./sync.ts'))),
|
|
14
|
+
GitHubOperation.GenerateWalkthrough.pipe(Operation.lazyHandler(() => import('./generate-walkthrough.ts'))),
|
|
15
|
+
GitHubOperation.ImportPullRequest.pipe(Operation.lazyHandler(() => import('./import-pull-request.ts'))),
|
|
16
|
+
GitHubOperation.ImportPullRequestFromSnapshot.pipe(
|
|
17
|
+
Operation.lazyHandler(() => import('./import-pull-request-from-snapshot.ts')),
|
|
18
|
+
),
|
|
19
|
+
GitHubOperation.SubmitPullRequestApproval.pipe(
|
|
20
|
+
Operation.lazyHandler(() => import('./submit-pull-request-approval.ts')),
|
|
21
|
+
),
|
|
22
|
+
GitHubOperation.AddPullRequestComment.pipe(Operation.lazyHandler(() => import('./add-pull-request-comment.ts'))),
|
|
23
|
+
GitHubOperation.AddPullRequestReviewComment.pipe(
|
|
24
|
+
Operation.lazyHandler(() => import('./add-pull-request-review-comment.ts')),
|
|
25
|
+
),
|
|
26
|
+
GitHubOperation.GetPullRequestStatus.pipe(Operation.lazyHandler(() => import('./get-pull-request-status.ts'))),
|
|
27
|
+
GitHubOperation.SyncPullRequest.pipe(Operation.lazyHandler(() => import('./sync-pull-request.ts'))),
|
|
28
|
+
GitHubOperation.GetPullRequestDiff.pipe(Operation.lazyHandler(() => import('./get-pull-request-diff.ts'))),
|
|
29
|
+
]);
|