@dxos/plugin-github 0.14.0 → 0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a

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.
Files changed (86) hide show
  1. package/dist/lib/GitHubCapabilities.mjs +1 -10
  2. package/dist/lib/GitHubEvents.mjs +1 -15
  3. package/dist/lib/GitHubOperation.mjs +1 -384
  4. package/dist/lib/GitHubPlugin.mjs +1 -16
  5. package/dist/lib/Walkthrough.mjs +1 -59
  6. package/dist/lib/capabilities.browser.mjs +1 -2
  7. package/dist/lib/capabilities.browser.mjs.map +1 -1
  8. package/dist/lib/capabilities.mjs +1 -2
  9. package/dist/lib/capabilities.mjs.map +1 -1
  10. package/dist/lib/capabilities.tauri.mjs +1 -2
  11. package/dist/lib/capabilities.tauri.mjs.map +1 -1
  12. package/dist/lib/chunk-Extensions.mjs +18 -0
  13. package/dist/lib/chunk-Extensions.mjs.map +1 -0
  14. package/dist/lib/chunk-GitHubCapabilities.mjs +10 -0
  15. package/dist/lib/chunk-GitHubCapabilities.mjs.map +1 -0
  16. package/dist/lib/chunk-GitHubEvents.mjs +15 -0
  17. package/dist/lib/chunk-GitHubEvents.mjs.map +1 -0
  18. package/dist/lib/chunk-GitHubOperation.mjs +386 -0
  19. package/dist/lib/chunk-GitHubOperation.mjs.map +1 -0
  20. package/dist/lib/chunk-GitHubPlugin.mjs +16 -0
  21. package/dist/lib/chunk-GitHubPlugin.mjs.map +1 -0
  22. package/dist/lib/chunk-ImportPullRequestDialog.mjs.map +1 -1
  23. package/dist/lib/chunk-PLUGIN.mjs +1 -1
  24. package/dist/lib/chunk-PullRequestArticle.mjs +33 -10
  25. package/dist/lib/chunk-PullRequestArticle.mjs.map +1 -1
  26. package/dist/lib/chunk-PullRequestArticle2.mjs +1 -2
  27. package/dist/lib/chunk-PullRequestCardMenu.mjs +1 -1
  28. package/dist/lib/chunk-PullRequestsArticle.mjs +3 -3
  29. package/dist/lib/chunk-PullRequestsArticle.mjs.map +1 -1
  30. package/dist/lib/chunk-Walkthrough.mjs +59 -0
  31. package/dist/lib/chunk-Walkthrough.mjs.map +1 -0
  32. package/dist/lib/chunk-WalkthroughArticle.mjs +1 -1
  33. package/dist/lib/chunk-add-pull-request-comment.mjs.map +1 -1
  34. package/dist/lib/chunk-add-pull-request-review-comment.mjs.map +1 -1
  35. package/dist/lib/chunk-connector.mjs.map +1 -1
  36. package/dist/lib/chunk-generate-walkthrough.mjs.map +1 -1
  37. package/dist/lib/chunk-get-pull-request-diff.mjs.map +1 -1
  38. package/dist/lib/chunk-get-pull-request-status.mjs.map +1 -1
  39. package/dist/lib/chunk-get-repositories.mjs.map +1 -1
  40. package/dist/lib/chunk-github-api.mjs +1 -0
  41. package/dist/lib/chunk-github-api.mjs.map +1 -1
  42. package/dist/lib/chunk-import-pull-request.mjs.map +1 -1
  43. package/dist/lib/chunk-link-resolver.mjs.map +1 -1
  44. package/dist/lib/chunk-pull-request2.mjs +1 -0
  45. package/dist/lib/chunk-pull-request2.mjs.map +1 -1
  46. package/dist/lib/chunk-react-surface.mjs +4 -4
  47. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  48. package/dist/lib/chunk-submit-pull-request-approval.mjs.map +1 -1
  49. package/dist/lib/chunk-sync.mjs.map +1 -1
  50. package/dist/lib/index.mjs +2 -2
  51. package/dist/lib/meta.mjs.map +1 -1
  52. package/dist/lib/ns/Extensions.mjs +2 -16
  53. package/dist/lib/types.mjs +4 -4
  54. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -1
  55. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  57. package/dist/types/src/cards/GitHubCard.d.ts.map +1 -1
  58. package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts +1 -1
  59. package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts.map +1 -1
  60. package/dist/types/src/components/PullRequestOverview/PullRequestOverview.d.ts.map +1 -1
  61. package/dist/types/src/operations/pull-request.d.ts.map +1 -1
  62. package/dist/types/src/services/github-api.d.ts +1 -0
  63. package/dist/types/src/services/github-api.d.ts.map +1 -1
  64. package/dist/types/src/stories/PullRequestOverview.stories.d.ts +2 -0
  65. package/dist/types/src/stories/PullRequestOverview.stories.d.ts.map +1 -1
  66. package/dist/types/src/types/GitHubOperation.d.ts +3 -0
  67. package/dist/types/src/types/GitHubOperation.d.ts.map +1 -1
  68. package/dist/types/tsconfig.tsbuildinfo +1 -1
  69. package/package.json +47 -47
  70. package/src/capabilities/gen/browser.ts +1 -3
  71. package/src/capabilities/gen/tauri.ts +1 -3
  72. package/src/capabilities/index.ts +1 -4
  73. package/src/cards/GitHubCard.tsx +7 -3
  74. package/src/components/PullRequestOverview/CheckRunList.tsx +34 -6
  75. package/src/components/PullRequestOverview/PullRequestOverview.tsx +5 -1
  76. package/src/containers/PullRequestsArticle/PullRequestsArticle.tsx +12 -10
  77. package/src/operations/pull-request.ts +1 -0
  78. package/src/services/github-api.ts +1 -0
  79. package/src/stories/PullRequestOverview.stories.tsx +20 -0
  80. package/src/types/GitHubOperation.ts +2 -0
  81. package/dist/lib/GitHubCapabilities.mjs.map +0 -1
  82. package/dist/lib/GitHubEvents.mjs.map +0 -1
  83. package/dist/lib/GitHubOperation.mjs.map +0 -1
  84. package/dist/lib/GitHubPlugin.mjs.map +0 -1
  85. package/dist/lib/Walkthrough.mjs.map +0 -1
  86. package/dist/lib/ns/Extensions.mjs.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-github",
3
- "version": "0.14.0",
3
+ "version": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
4
4
  "description": "DXOS plugin that integrates GitHub as a sync source via the generic Integration mechanism.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -133,61 +133,61 @@
133
133
  "@codemirror/language": "^6.12.4",
134
134
  "@codemirror/state": "^6.7.6",
135
135
  "@codemirror/view": "^6.43.13",
136
- "effect": "4.0.0",
137
- "@dxos/ai": "0.14.0",
138
- "@dxos/app-framework": "0.14.0",
139
- "@dxos/app-graph": "0.14.0",
140
- "@dxos/app-toolkit": "0.14.0",
141
- "@dxos/compute": "0.14.0",
142
- "@dxos/echo": "0.14.0",
143
- "@dxos/echo-query": "0.14.0",
144
- "@dxos/echo-react": "0.14.0",
145
- "@dxos/effect": "0.14.0",
146
- "@dxos/errors": "0.14.0",
147
- "@dxos/graph": "0.14.0",
148
- "@dxos/keys": "0.14.0",
149
- "@dxos/link": "0.14.0",
150
- "@dxos/lit-ui": "0.14.0",
151
- "@dxos/log": "0.14.0",
152
- "@dxos/plugin-connector": "0.14.0",
153
- "@dxos/plugin-crx": "0.14.0",
154
- "@dxos/plugin-markdown": "0.14.0",
155
- "@dxos/plugin-preview": "0.14.0",
156
- "@dxos/plugin-space": "0.14.0",
157
- "@dxos/protocols": "0.14.0",
158
- "@dxos/react-client": "0.14.0",
159
- "@dxos/react-ui": "0.14.0",
160
- "@dxos/react-ui-attention": "0.14.0",
161
- "@dxos/react-ui-components": "0.14.0",
162
- "@dxos/react-ui-editor": "0.14.0",
163
- "@dxos/react-ui-form": "0.14.0",
164
- "@dxos/react-ui-list": "0.14.0",
165
- "@dxos/react-ui-markdown": "0.14.0",
166
- "@dxos/react-ui-menu": "0.14.0",
167
- "@dxos/react-ui-masonry": "0.14.0",
168
- "@dxos/react-ui-query": "0.14.0",
169
- "@dxos/types": "0.14.0",
170
- "@dxos/ui-editor": "0.14.0",
171
- "@dxos/ui-types": "0.14.0",
172
- "@dxos/util": "0.14.0"
136
+ "effect": "4.0.4",
137
+ "@dxos/ai": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
138
+ "@dxos/app-framework": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
139
+ "@dxos/app-graph": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
140
+ "@dxos/app-toolkit": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
141
+ "@dxos/compute": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
142
+ "@dxos/echo": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
143
+ "@dxos/echo-query": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
144
+ "@dxos/echo-react": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
145
+ "@dxos/effect": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
146
+ "@dxos/errors": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
147
+ "@dxos/graph": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
148
+ "@dxos/keys": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
149
+ "@dxos/link": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
150
+ "@dxos/lit-ui": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
151
+ "@dxos/log": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
152
+ "@dxos/plugin-connector": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
153
+ "@dxos/plugin-crx": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
154
+ "@dxos/plugin-markdown": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
155
+ "@dxos/plugin-preview": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
156
+ "@dxos/plugin-space": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
157
+ "@dxos/protocols": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
158
+ "@dxos/react-client": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
159
+ "@dxos/react-ui": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
160
+ "@dxos/react-ui-attention": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
161
+ "@dxos/react-ui-components": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
162
+ "@dxos/react-ui-editor": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
163
+ "@dxos/react-ui-list": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
164
+ "@dxos/react-ui-form": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
165
+ "@dxos/react-ui-markdown": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
166
+ "@dxos/react-ui-masonry": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
167
+ "@dxos/react-ui-menu": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
168
+ "@dxos/react-ui-query": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
169
+ "@dxos/ui-editor": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
170
+ "@dxos/types": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
171
+ "@dxos/ui-types": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
172
+ "@dxos/util": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a"
173
173
  },
174
174
  "devDependencies": {
175
- "@effect/atom-react": "4.0.0",
175
+ "@effect/atom-react": "4.0.4",
176
176
  "@storybook/react-vite": "^10.6.0",
177
177
  "@types/react": "~19.2.17",
178
178
  "@types/react-dom": "~19.2.3",
179
179
  "react": "~19.2.7",
180
180
  "react-dom": "~19.2.7",
181
- "vite": "^8.2.2",
182
- "@dxos/echo-client": "0.14.0",
183
- "@dxos/plugin-client": "0.14.0",
184
- "@dxos/plugin-testing": "0.14.0",
185
- "@dxos/random": "0.14.0",
186
- "@dxos/react-ui-editor": "0.14.0"
181
+ "vite": "^8.3.4",
182
+ "@dxos/echo-client": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
183
+ "@dxos/plugin-client": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
184
+ "@dxos/plugin-testing": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
185
+ "@dxos/random": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a",
186
+ "@dxos/react-ui-editor": "0.16.0-next-60712ab191a99ba90316cc4be753e9e11b17100a"
187
187
  },
188
188
  "peerDependencies": {
189
- "@effect/atom-react": "4.0.0",
190
- "effect": "4.0.0",
189
+ "@effect/atom-react": "4.0.4",
190
+ "effect": "4.0.4",
191
191
  "react": "~19.2.7",
192
192
  "react-dom": "~19.2.7"
193
193
  },
@@ -19,8 +19,6 @@ import * as PreviewEvents from '@dxos/plugin-preview/PreviewEvents';
19
19
  import { meta } from '#meta';
20
20
  import { translations } from '#translations';
21
21
 
22
- import pluginSpec from '../../../PLUGIN.mdl?raw';
23
-
24
22
  export const Connector = Capability.lazyModule(
25
23
  'GitHubConnector',
26
24
  { provides: [ConnectorSpec.Connector], activatesOn: ConnectorEvents.Start },
@@ -75,7 +73,7 @@ export const ReactSurface = AppCapability.surface(() => import('../react-surface
75
73
  export const PluginAsset = AppCapability.pluginAsset({
76
74
  pluginId: meta.profile.key,
77
75
  path: 'PLUGIN.mdl',
78
- content: pluginSpec,
76
+ content: () => import('../../../PLUGIN.mdl?raw'),
79
77
  mimeType: 'application/x-mdl',
80
78
  });
81
79
 
@@ -19,8 +19,6 @@ import * as PreviewEvents from '@dxos/plugin-preview/PreviewEvents';
19
19
  import { meta } from '#meta';
20
20
  import { translations } from '#translations';
21
21
 
22
- import pluginSpec from '../../../PLUGIN.mdl?raw';
23
-
24
22
  export const Connector = Capability.lazyModule(
25
23
  'GitHubConnector',
26
24
  { provides: [ConnectorSpec.Connector], activatesOn: ConnectorEvents.Start },
@@ -75,7 +73,7 @@ export const ReactSurface = AppCapability.surface(() => import('../react-surface
75
73
  export const PluginAsset = AppCapability.pluginAsset({
76
74
  pluginId: meta.profile.key,
77
75
  path: 'PLUGIN.mdl',
78
- content: pluginSpec,
76
+ content: () => import('../../../PLUGIN.mdl?raw'),
79
77
  mimeType: 'application/x-mdl',
80
78
  });
81
79
 
@@ -17,9 +17,6 @@ import * as PreviewEvents from '@dxos/plugin-preview/PreviewEvents';
17
17
  import { meta } from '#meta';
18
18
  import { translations } from '#translations';
19
19
 
20
- // eslint-disable-next-line import/no-relative-packages
21
- import pluginSpec from '../../PLUGIN.mdl?raw';
22
-
23
20
  export const Connector = Capability.lazyModule(
24
21
  'GitHubConnector',
25
22
  { provides: [ConnectorSpec.Connector], activatesOn: ConnectorEvents.Start },
@@ -65,7 +62,7 @@ export const ReactSurface = AppCapability.surface(() => import('./react-surface.
65
62
  export const PluginAsset = AppCapability.pluginAsset({
66
63
  pluginId: meta.profile.key,
67
64
  path: 'PLUGIN.mdl',
68
- content: pluginSpec,
65
+ content: () => import('../../PLUGIN.mdl?raw'),
69
66
  mimeType: 'application/x-mdl',
70
67
  });
71
68
  export const Translations = AppCapability.translations(translations);
@@ -5,6 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import type * as AppSurface from '@dxos/app-toolkit/AppSurface';
8
+ import { useObject } from '@dxos/echo-react';
8
9
  import * as Card from '@dxos/react-ui/Card';
9
10
  import * as Hooks from '@dxos/react-ui/Hooks';
10
11
  import * as Layout from '@dxos/react-ui/Layout';
@@ -21,6 +22,8 @@ type Subject = Repo.Repo | Issue.Issue | PullRequest.PullRequest;
21
22
  */
22
23
  type Fields = {
23
24
  owner: string;
25
+ name?: string;
26
+ repo?: string;
24
27
  number?: number;
25
28
  state?: PullRequest.State;
26
29
  author?: string;
@@ -44,8 +47,9 @@ const stateHue: Record<PullRequest.State, Tag.TagHue> = {
44
47
  */
45
48
  export const GitHubCard = ({ subject }: AppSurface.ObjectCardProps<Subject>) => {
46
49
  const { t } = Hooks.useTranslation(meta.profile.key);
47
- const { owner, number, state, author, additions, deletions, defaultBranch, description, url }: Fields = subject;
48
- const name = 'name' in subject ? subject.name : subject.repo;
50
+ const [object] = useObject(subject);
51
+ const { owner, name, repo, number, state, author, additions, deletions, defaultBranch, description, url }: Fields =
52
+ object;
49
53
 
50
54
  return (
51
55
  <Card.Body>
@@ -59,7 +63,7 @@ export const GitHubCard = ({ subject }: AppSurface.ObjectCardProps<Subject>) =>
59
63
  ) : undefined
60
64
  }
61
65
  >
62
- <Card.Text variant='muted'>{[`${owner}/${name}`, number].filter(Boolean).join('#')}</Card.Text>
66
+ <Card.Text variant='muted'>{[`${owner}/${name ?? repo}`, number].filter(Boolean).join('#')}</Card.Text>
63
67
  </Card.Row>
64
68
  {author && (
65
69
  <Card.Row icon='ph--user--regular'>
@@ -5,6 +5,7 @@
5
5
  import React, { useEffect, useMemo, useState } from 'react';
6
6
 
7
7
  import { Listbox } from '@dxos/react-ui-list';
8
+ import * as Button from '@dxos/react-ui/Button';
8
9
  import * as Hooks from '@dxos/react-ui/Hooks';
9
10
  import * as Status from '@dxos/react-ui/Status';
10
11
 
@@ -53,6 +54,10 @@ const useNow = (active: boolean): number => {
53
54
  return now;
54
55
  };
55
56
 
57
+ /** The row's value: GitHub's run id, or its name and URL for a run recorded without one. */
58
+ const checkRunId = (run: GitHubOperation.CheckRun): string =>
59
+ run.id !== undefined ? String(run.id) : `${run.name}-${run.url ?? ''}`;
60
+
56
61
  /** Sorts runs by what needs attention, then by name so shards read in order. */
57
62
  export const sortCheckRuns = (runs: readonly GitHubOperation.CheckRun[]): GitHubOperation.CheckRun[] =>
58
63
  [...runs].sort(
@@ -66,19 +71,25 @@ export type CheckRunListProps = {
66
71
  runs?: readonly GitHubOperation.CheckRun[];
67
72
  };
68
73
 
69
- /** Every check on the head commit: its outcome, how long it took, and its logs a click away. */
74
+ /** Every check on the head commit: its outcome, how long it took, and a button to its logs. */
70
75
  export const CheckRunList = ({ runs }: CheckRunListProps) => {
71
76
  const { t } = Hooks.useTranslation(meta.profile.key);
72
77
  const sorted = useMemo(() => (runs ? sortCheckRuns(runs) : undefined), [runs]);
73
78
  const summary = useCheckSummary(runs);
74
79
  const now = useNow(runs?.some((run) => run.outcome === 'pending' && run.startedAt) ?? false);
80
+ const [current, setCurrent] = useState<string>();
75
81
 
76
82
  if (!sorted || sorted.length === 0) {
77
83
  return <Status.Empty>{t(sorted ? 'no-checks.message' : 'checks-loading.message')}</Status.Empty>;
78
84
  }
79
85
 
80
86
  return (
81
- <Listbox.Root items={sorted.map((run) => ({ value: `${run.name}-${run.url ?? ''}`, label: run.name }))}>
87
+ <Listbox.Root
88
+ items={sorted.map((run) => ({ value: checkRunId(run), label: run.name }))}
89
+ // Icon, name, a short time column, then the open button: one line per check.
90
+ columns='var(--dx-block-size) minmax(0, 1fr) max-content var(--dx-block-size)'
91
+ onHighlightChange={(value) => value && setCurrent(value)}
92
+ >
82
93
  <Listbox.Content aria-label={summary} data-testid='pull-request.checks'>
83
94
  {sorted.map((run) => {
84
95
  const { icon, classNames } = outcomeIcon[run.outcome];
@@ -95,17 +106,34 @@ export const CheckRunList = ({ runs }: CheckRunListProps) => {
95
106
  ? [t('check-outcome.pending.label'), duration].filter(Boolean).join(' · ')
96
107
  : (duration ?? t(`check-outcome.${run.outcome}.label`));
97
108
  const url = run.url;
109
+ const id = checkRunId(run);
98
110
  return (
99
111
  <Listbox.Item
100
- key={`${run.name}-${url ?? ''}`}
101
- id={`${run.name}-${url ?? ''}`}
112
+ key={id}
113
+ id={id}
114
+ current={id === current}
115
+ highlightOnHover={false}
116
+ classNames='dx-hover'
102
117
  data-outcome={run.outcome}
103
118
  data-testid='pull-request.check'
104
- onClick={url ? () => window.open(url, '_blank', 'noopener,noreferrer') : undefined}
105
119
  >
106
120
  <Listbox.ItemIcon icon={icon} classNames={classNames} />
107
121
  <Listbox.ItemText>{run.name}</Listbox.ItemText>
108
- <Listbox.ItemDescription>{[detail, outcome].filter(Boolean).join(' · ')}</Listbox.ItemDescription>
122
+ <Listbox.ItemDescription classNames='text-right tabular-nums'>
123
+ {[detail, outcome].filter(Boolean).join(' · ')}
124
+ </Listbox.ItemDescription>
125
+ {url ? (
126
+ <Button.Root
127
+ iconOnly
128
+ variant='ghost'
129
+ icon='ph--arrow-square-out--regular'
130
+ label={t('open-link.label')}
131
+ data-testid='pull-request.check.open'
132
+ onClick={() => window.open(url, '_blank', 'noopener,noreferrer')}
133
+ />
134
+ ) : (
135
+ <span />
136
+ )}
109
137
  </Listbox.Item>
110
138
  );
111
139
  })}
@@ -12,6 +12,7 @@ import { MarkdownLink, MarkdownView, type MarkdownViewProps } from '@dxos/react-
12
12
  import * as UiHooks from '@dxos/react-ui/Hooks';
13
13
  import * as Icon from '@dxos/react-ui/Icon';
14
14
  import * as Status from '@dxos/react-ui/Status';
15
+ import * as Typography from '@dxos/react-ui/Typography';
15
16
 
16
17
  import { meta } from '#meta';
17
18
  import { type GitHubOperation } from '#types';
@@ -60,7 +61,10 @@ export const PullRequestOverview = ({ body, details, runs }: PullRequestOverview
60
61
  <RelatedCards items={related} />
61
62
  </Form.FieldSet>
62
63
  )}
63
- <Form.FieldSet label={checkSummary}>
64
+ <Form.FieldSet label={t('checks.label')}>
65
+ {runs && runs.length > 0 && (
66
+ <Typography.Text data-testid='pull-request.checks.summary'>{checkSummary}</Typography.Text>
67
+ )}
64
68
  <CheckRunList runs={runs} />
65
69
  </Form.FieldSet>
66
70
  </Form.Content>
@@ -185,16 +185,18 @@ const PullRequestList = ({ role, attendableId, db }: PullRequestsArticleProps &
185
185
  </Status.Empty>
186
186
  ) : (
187
187
  <Listbox.Root items={options}>
188
- <Listbox.Content
189
- classNames='dx-expand'
190
- aria-label={t('typename.label_other', { ns: PULL_REQUEST_TYPENAME })}
191
- >
192
- {groups
193
- ? groups
194
- .filter((group) => group.rows.length > 0)
195
- .map((group) => <GroupSection key={group.id} group={group} onOpen={openObject} />)
196
- : rows.map((row) => <PullRequestListRow key={row.pullRequest.id} row={row} onOpen={openObject} />)}
197
- </Listbox.Content>
188
+ <Listbox.Viewport>
189
+ <Listbox.Content
190
+ classNames='dx-expand'
191
+ aria-label={t('typename.label_other', { ns: PULL_REQUEST_TYPENAME })}
192
+ >
193
+ {groups
194
+ ? groups
195
+ .filter((group) => group.rows.length > 0)
196
+ .map((group) => <GroupSection key={group.id} group={group} onOpen={openObject} />)
197
+ : rows.map((row) => <PullRequestListRow key={row.pullRequest.id} row={row} onOpen={openObject} />)}
198
+ </Listbox.Content>
199
+ </Listbox.Viewport>
198
200
  </Listbox.Root>
199
201
  )}
200
202
  </Panel.Body>
@@ -82,6 +82,7 @@ export const toCheckRun = (run: GitHubApi.GitHubCheckRun): GitHubOperation.Check
82
82
  : 'success';
83
83
  const url = run.details_url ?? run.html_url;
84
84
  return {
85
+ ...(run.id !== undefined ? { id: run.id } : {}),
85
86
  name: run.name,
86
87
  outcome,
87
88
  ...(run.conclusion ? { conclusion: run.conclusion } : {}),
@@ -676,6 +676,7 @@ export const createIssueComment = (
676
676
  );
677
677
 
678
678
  const GitHubCheckRunSchema = Schema.Struct({
679
+ id: Schema.Number.pipe(Schema.optional),
679
680
  name: Schema.String,
680
681
  /** `queued`, `in_progress` or `completed`. */
681
682
  status: Schema.String,
@@ -72,6 +72,7 @@ export const Default: Story = {
72
72
  'session_016GM9fXXzbrr6JGNeeQBCmj',
73
73
  );
74
74
  await expect(canvas.getAllByTestId('pull-request.check')).toHaveLength(PULL_REQUEST_13348_RUNS.length);
75
+ await expect(canvas.getByTestId('pull-request.checks.summary')).toHaveTextContent(/\d+ passed/);
75
76
  },
76
77
  };
77
78
 
@@ -96,6 +97,25 @@ export const FailingChecks: Story = {
96
97
  },
97
98
  };
98
99
 
100
+ /** Rows are navigated, not followed: a click or an arrow key moves the current row; the trailing button opens the logs. */
101
+ export const CheckNavigation: Story = {
102
+ args: { ...REAL_PULL_REQUEST },
103
+ play: async ({ canvasElement }) => {
104
+ const canvas = within(canvasElement);
105
+ const list = await canvas.findByTestId('pull-request.checks', {}, { timeout: 10_000 });
106
+ // The tab's viewport scrolls, so the list must not trap wheel gestures in a scroller of its own.
107
+ await expect(list.querySelector('.dx-scroll-viewport')).toBeNull();
108
+ const [first, second] = canvas.getAllByTestId('pull-request.check');
109
+ await expect(first).toHaveClass('dx-hover');
110
+ await userEvent.click(first);
111
+ await expect(first).toHaveAttribute('aria-current', 'true');
112
+ await userEvent.keyboard('{ArrowDown}');
113
+ await expect(second).toHaveAttribute('aria-current', 'true');
114
+ await expect(first).not.toHaveAttribute('aria-current');
115
+ await expect(within(first).getByTestId('pull-request.check.open')).toBeInTheDocument();
116
+ },
117
+ };
118
+
99
119
  /** A pill opens its demo video in place. */
100
120
  export const ArtifactPreview: Story = {
101
121
  args: { ...REAL_PULL_REQUEST },
@@ -329,6 +329,8 @@ export type CheckOutcome = Schema.Schema.Type<typeof CheckOutcome>;
329
329
 
330
330
  /** One check run on the head commit, as the article lists it. */
331
331
  export const CheckRun = Schema.Struct({
332
+ /** GitHub's id for the run; two runs can share a name and a URL. */
333
+ id: Schema.Number.pipe(Schema.optional),
332
334
  name: Schema.String,
333
335
  outcome: CheckOutcome,
334
336
  /** GitHub's own `conclusion` (`timed_out`, `cancelled`, …), kept for the label when it says more than the outcome. */
@@ -1 +0,0 @@
1
- {"version":3,"file":"GitHubCapabilities.mjs","names":[],"sources":["../../src/types/GitHubCapabilities.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport type * as PreviewCapabilities from '@dxos/plugin-preview/PreviewCapabilities';\nimport { type Issue, type PullRequest, type Repo } from '@dxos/types';\n\nimport { meta } from '#meta';\n\nimport { type GitHubLink } from '../extensions/index.ts';\n\n/**\n * Where a previewed link's repository, pull request or issue comes from. The plugin's default fetches it from\n * the GitHub API with the space's connection token (anonymously when there is none); a host that\n * contributes one — a story, a test, an offline build — replaces the fetch.\n */\nexport type GitHubLinkSource = (\n link: GitHubLink,\n context: PreviewCapabilities.PreviewLinkContext,\n) => Effect.Effect<Repo.Repo | Issue.Issue | PullRequest.PullRequest | undefined>;\n\nexport const LinkSource = Capability.make<GitHubLinkSource>()(`${meta.profile.key}.capability.linkSource`);\n"],"mappings":";;;;;AA0BA,IAAa,aAAa,WAAW,KAAuB,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,uBAAuB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GitHubEvents.mjs","names":[],"sources":["../../src/types/GitHubEvents.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as ActivationEvent from '@dxos/app-framework/ActivationEvent';\n\nimport { meta } from '#meta';\n\n/**\n * The feature's start event: the plugin's start-gated modules (and cross-plugin\n * contributions consumed by this feature) activate here. Fired on demand and by the\n * host's idle trickle.\n */\nexport const Start = ActivationEvent.pluginStart(meta.profile.key);\n"],"mappings":";;;;;;;;;;AAeA,IAAa,QAAQ,gBAAgB,YAAY,KAAK,QAAQ,GAAG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GitHubOperation.mjs","names":[],"sources":["../../src/types/GitHubOperation.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { AiService } from '@dxos/ai';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as Trace from '@dxos/compute/Trace';\nimport { Database, DXN, Obj, Ref } from '@dxos/echo';\n// Referenced in the emitted .d.ts of the operations (via `ConnectorSpec`'s schemas); importing it\n// lets TypeScript name it (TS2883).\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport { Connection } from '@dxos/link';\nimport * as ConnectorSpec from '@dxos/plugin-connector/ConnectorSpec';\nimport * as PageAction from '@dxos/plugin-crx/PageAction';\nimport { PullRequest } from '@dxos/types';\n\nimport * as Walkthrough from './Walkthrough.ts';\n\n/**\n * Discovery only — list GitHub repositories the connection's token can see.\n * Returns one descriptor per repo across all the user's orgs (and personal\n * account). Read-only: NEVER materializes local objects — materialization is\n * handled by the connector's `materializeTarget` when a `Cursor` is created.\n *\n * Orgs and their members are NOT presented as sync targets — they are\n * auto-synced as part of the sync of any repo they own.\n */\nexport const GetGitHubRepositories = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.getRepositories'),\n name: 'Get GitHub Repositories',\n description: 'List GitHub repositories reachable from a connection without materializing local objects.',\n icon: 'ph--github-logo--regular',\n },\n input: ConnectorSpec.GetSyncTargetsInput,\n output: ConnectorSpec.GetSyncTargetsOutput,\n});\n\n/**\n * Find-or-create the empty local root Project for a selected GitHub repo so a\n * cursor can reference it as its `spec.target`. Keyed by the repo's\n * GitHub foreign id (`remoteTarget.id`), so it is idempotent across re-selection.\n */\nexport const MaterializeGitHubTarget = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.materializeTarget'),\n name: 'Materialize GitHub Target',\n description: 'Create the empty local root Project bound to a selected GitHub repository.',\n icon: 'ph--github-logo--regular',\n },\n input: ConnectorSpec.MaterializeTargetInput,\n output: ConnectorSpec.MaterializeTargetOutput,\n});\n\n/**\n * Per-target options. `maxDaysBack` caps how far back issues/PRs are pulled\n * (mirrors the Gmail mailbox `daysBack`). Default — when unset — is \"sync\n * everything ever opened or edited.\"\n */\nexport const SyncOptions = Schema.Struct({\n maxDaysBack: Schema.Number.annotate({\n title: 'Sync history (days)',\n description: 'Pull issues and PRs updated within this many days. Leave empty to sync everything.',\n }).pipe(Schema.optional),\n});\n\nexport interface SyncOptions extends Schema.Schema.Type<typeof SyncOptions> {}\n\n/**\n * Reconcile GitHub data for every repo bound to a connection (one cursor per repo).\n *\n * Pull-then-push per bound repo: auto-upsert its owning org + members,\n * three-way merge the repo as a Project and its issues/PRs as Tasks (respecting\n * `maxDaysBack` if set), then push diverged Project/Task fields back to GitHub.\n * Sync state (`lastTick`/`lastError`/`spec.snapshots`) is written onto each binding.\n */\nexport const SyncGitHubRepositories = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.syncRepositories'),\n name: 'Sync GitHub Repositories',\n description: 'Reconcile every bound GitHub repo plus its owning org, members, issues, PRs, and comments.',\n icon: 'ph--arrows-clockwise--regular',\n },\n input: ConnectorSpec.SyncInput,\n output: Schema.Struct({\n pulled: Schema.Struct({\n organizations: Schema.Number,\n people: Schema.Number,\n projects: Schema.Number,\n tasks: Schema.Number,\n comments: Schema.Number,\n }),\n }),\n}).pipe(Operation.visible);\n\n/**\n * Import a pull request named by a github.com URL or `owner/repo#123` into the space, so it can be\n * opened, reviewed and walked through without waiting for a sync of the whole repository.\n *\n * Idempotent by coordinates — a pull request the space already holds is returned as it stands\n * rather than duplicated.\n */\nexport const ImportPullRequest = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.importPullRequest'),\n name: 'Import Pull Request',\n description: 'Add a pull request to the space, named by its URL or as owner/repo#number.',\n icon: 'ph--git-pull-request--regular',\n },\n services: [Database.Service],\n input: Schema.Struct({\n /** A github.com pull request URL, or `owner/repo#123`. */\n reference: Schema.String,\n }),\n output: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n /** False where the space already held the pull request, which is then returned unchanged. */\n imported: Schema.Boolean,\n }),\n types: [PullRequest.PullRequest],\n}).pipe(Operation.visible, Operation.mutation('write'));\n\n/**\n * Import the pull request the browser extension is looking at, named by the page's own URL.\n *\n * Separate from {@link ImportPullRequest} because the extension bridge invokes every page action\n * with the fixed `{ snapshot, target }` shape and reads an `{ id }` back. Nothing is extracted from\n * the page: the URL in the snapshot's source names the pull request, and GitHub is the authority on\n * everything else.\n */\nexport const ImportPullRequestFromSnapshot = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.importPullRequestFromSnapshot'),\n name: 'Open pull request in Composer',\n description: \"Import the pull request a browser page shows, named by that page's URL.\",\n icon: 'ph--git-pull-request--regular',\n },\n input: Schema.Struct({\n snapshot: PageAction.Snapshot,\n target: Database.Database.annotate({ description: 'The database to add the pull request to.' }),\n }),\n output: Schema.Struct({\n id: Schema.String,\n }),\n types: [PullRequest.PullRequest],\n}).pipe(Operation.mutation('write'));\n\n/**\n * Generate a walkthrough of a pull request: one markdown document narrating the change in reading\n * order, with its diff chunks spliced in from the patch itself.\n *\n * Idempotent by commit — a walkthrough already generated for the pull request's head is returned\n * unchanged unless `force` says otherwise, since the answer cannot have changed.\n */\nexport const GenerateWalkthrough = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.generateWalkthrough'),\n name: 'Generate Walkthrough',\n description: \"Narrate a pull request as one markdown document, with the change's diffs embedded in it.\",\n icon: 'ph--path--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n /** Regenerate even where a walkthrough for this head already exists. */\n force: Schema.Boolean.pipe(Schema.optional),\n }),\n output: Schema.Struct({\n walkthrough: Ref.Ref(Walkthrough.Walkthrough),\n /** Whether the model ran, as against an existing walkthrough being returned unchanged. */\n generated: Schema.Boolean,\n /** Hunks the prose accounts for, over the patch's total. */\n covered: Schema.Number,\n total: Schema.Number,\n }),\n types: [Walkthrough.Walkthrough, PullRequest.PullRequest],\n // `AiService` must be declared, not merely provided: the invoker builds the runtime from THIS list\n // and `Layer.orDie` clears a layer's error channel, never its requirement.\n services: [Trace.TraceService, AiService.AiService],\n}).pipe(Operation.visible);\n\n/**\n * Submit an approving review on a pull request, as the space's GitHub connection.\n *\n * Falls back to a marked conversation comment where GitHub refuses the review — the author's own\n * pull request, or a token with no review permission — so the approval is still recorded and still\n * detectable by an agent deciding whether the pull request is good to land.\n */\nexport const SubmitPullRequestApproval = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.submitPullRequestApproval'),\n name: 'Submit Pull Request Approval',\n description: 'Submit an approving review on a pull request, or record the approval as a comment.',\n icon: 'ph--check-circle--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n /** Optional review summary. */\n body: Schema.String.pipe(Schema.optional),\n }),\n output: Schema.Struct({\n /** Set where the approving review was accepted. */\n reviewId: Schema.Number.pipe(Schema.optional),\n /** Set instead where the approval was recorded as a comment. */\n commentId: Schema.Number.pipe(Schema.optional),\n url: Schema.String.pipe(Schema.optional),\n /** Whether the approval is a comment rather than a review. */\n commented: Schema.Boolean,\n }),\n types: [PullRequest.PullRequest],\n});\n\n/** Post a conversation comment on a pull request, as the space's GitHub connection. */\nexport const AddPullRequestComment = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.addPullRequestComment'),\n name: 'Add Pull Request Comment',\n description: 'Post a comment on a pull request.',\n icon: 'ph--chat-text--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n body: Schema.String,\n }),\n output: Schema.Struct({\n commentId: Schema.Number,\n url: Schema.String.pipe(Schema.optional),\n }),\n types: [PullRequest.PullRequest],\n});\n\n/** Post a review comment on one line of a pull request's diff, as the space's GitHub connection. */\nexport const AddPullRequestReviewComment = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.addPullRequestReviewComment'),\n name: 'Add Pull Request Review Comment',\n description: 'Post a review comment on a line of a pull request diff.',\n icon: 'ph--chat-centered-text--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n body: Schema.String,\n /** Head SHA the line numbers refer to; a walkthrough's `commit`. */\n commit: Schema.String,\n path: Schema.String,\n line: Schema.Number,\n /** `LEFT` for the removed side, `RIGHT` for added and context lines. */\n side: Schema.Literals(['LEFT', 'RIGHT']),\n }),\n output: Schema.Struct({\n commentId: Schema.Number,\n url: Schema.String.pipe(Schema.optional),\n }),\n types: [PullRequest.PullRequest],\n});\n\n/**\n * Re-read a stored pull request from GitHub and write back whatever has changed — its title, state,\n * description, branches and size — so the object in the space does not go stale between syncs.\n */\nexport const SyncPullRequest = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.syncPullRequest'),\n name: 'Sync Pull Request',\n description: 'Refresh a stored pull request from GitHub.',\n icon: 'ph--arrows-clockwise--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n }),\n output: Schema.Struct({\n /** Names of the fields that changed; empty where the stored pull request was already current. */\n updated: Schema.Array(Schema.String),\n }),\n types: [PullRequest.PullRequest],\n}).pipe(Operation.mutation('write'));\n\n/**\n * Refresh every pull request in the space that is still in flight (open or draft) from GitHub.\n *\n * Run on a schedule by the space's refresh trigger (see `ensureRefreshTrigger`), so pull requests the\n * user is not looking at still track their state; one unreachable pull request does not fail the rest.\n */\nexport const RefreshPullRequests = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.refreshPullRequests'),\n name: 'Refresh Pull Requests',\n description: 'Refresh every open pull request in the space from GitHub.',\n icon: 'ph--arrows-clockwise--regular',\n },\n services: [Database.Service],\n input: Schema.Struct({}),\n output: Schema.Struct({\n /** Open pull requests read from GitHub. */\n checked: Schema.Number,\n /** Of those, the ones whose stored fields changed. */\n updated: Schema.Number,\n /** Of those, the ones GitHub could not be read for. */\n failed: Schema.Number,\n }),\n types: [PullRequest.PullRequest],\n}).pipe(Operation.mutation('write'));\n\n/** Aggregate outcome of a commit's check runs; `none` when the commit has no checks at all. */\nexport const CiState = Schema.Literals(['success', 'failure', 'pending', 'none']);\nexport type CiState = Schema.Schema.Type<typeof CiState>;\n\nexport const CheckCounts = Schema.Struct({\n total: Schema.Number,\n passed: Schema.Number,\n failed: Schema.Number,\n pending: Schema.Number,\n});\nexport interface CheckCounts extends Schema.Schema.Type<typeof CheckCounts> {}\n\n/**\n * Where the reviews stand, from each reviewer's latest verdict: any outstanding request for changes\n * outweighs approvals, and `none` means no reviewer has approved or asked for changes.\n */\nexport const ReviewState = Schema.Literals(['approved', 'changes_requested', 'none']);\nexport type ReviewState = Schema.Schema.Type<typeof ReviewState>;\n\n/** How one check run ended, folded to what a reader acts on; `skipped` is neither passing nor failing. */\nexport const CheckOutcome = Schema.Literals(['success', 'failure', 'pending', 'skipped', 'neutral']);\nexport type CheckOutcome = Schema.Schema.Type<typeof CheckOutcome>;\n\n/** One check run on the head commit, as the article lists it. */\nexport const CheckRun = Schema.Struct({\n name: Schema.String,\n outcome: CheckOutcome,\n /** GitHub's own `conclusion` (`timed_out`, `cancelled`, …), kept for the label when it says more than the outcome. */\n conclusion: Schema.String.pipe(Schema.optional),\n /** Where the run's logs live: the provider's page when it has one, else GitHub's. */\n url: Schema.String.pipe(Schema.optional),\n startedAt: Schema.String.pipe(Schema.optional),\n completedAt: Schema.String.pipe(Schema.optional),\n});\nexport interface CheckRun extends Schema.Schema.Type<typeof CheckRun> {}\n\n/** Read a pull request's live state and the CI outcome of its head commit from GitHub. */\nexport const GetPullRequestStatus = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.getPullRequestStatus'),\n name: 'Get Pull Request Status',\n description: \"Read a pull request's state, its review verdict and the CI status of its head commit.\",\n icon: 'ph--git-pull-request--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n }),\n output: Schema.Struct({\n state: PullRequest.State,\n title: Schema.String,\n commit: Schema.String.pipe(Schema.optional),\n /** The live description, which may have changed since the pull request was imported. */\n body: Schema.String.pipe(Schema.optional),\n ci: CiState,\n checks: CheckCounts,\n runs: Schema.Array(CheckRun),\n review: ReviewState,\n /** Reviewers whose latest verdict is an approval. */\n approvals: Schema.Number,\n }),\n types: [PullRequest.PullRequest],\n});\n\n/**\n * Read a pull request's whole change as a unified diff, with the head commit it was taken at so a\n * line comment on it anchors to the lines the reader saw.\n */\nexport const GetPullRequestDiff = Operation.make({\n meta: {\n key: DXN.make('org.dxos.operation.github.getPullRequestDiff'),\n name: 'Get Pull Request Diff',\n description: \"Read a pull request's changed files as a unified diff.\",\n icon: 'ph--git-diff--regular',\n },\n input: Schema.Struct({\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n }),\n output: Schema.Struct({\n commit: Schema.String.pipe(Schema.optional),\n diff: Schema.String,\n }),\n types: [PullRequest.PullRequest],\n});\n\n/**\n * Progress key for {@link GenerateWalkthrough}, derived from the pull request rather than passed, so\n * the UI can watch a run it did not start. The absolute URI form is required: a hydration-dependent\n * one would not match the key the producer mints.\n */\nexport const createWalkthroughProgressKey = (pullRequest: PullRequest.PullRequest): string =>\n Obj.getURI(pullRequest, { prefer: 'absolute' }).toString() + '#walkthrough';\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GitHubPlugin.mjs","names":[],"sources":["../../src/GitHubPlugin.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport { meta as pluginMeta } from '#meta';\n\n/** Plugin metadata, available without loading the plugin body. */\nexport const meta = pluginMeta;\n\n/** Constructs the plugin; the body loads on first enable. */\nexport const make = Plugin.lazy(meta, () => import('#plugin'));\n"],"mappings":";;;;;;;;;AAWA,IAAa,OAAO;;AAGpB,IAAa,OAAO,OAAO,KAAK,YAAY,OAAO,UAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Walkthrough.mjs","names":[],"sources":["../../src/types/Walkthrough.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, DXN, Format, Obj, Ref, Type } from '@dxos/echo';\nimport { PullRequest } from '@dxos/types';\n\n/**\n * A narrated reading of a pull request: one markdown document whose prose, headings and ```diff\n * fences describe the change in the order a reviewer should meet it.\n *\n * Generated against ONE commit and stale the moment the branch moves, which is why `commit` is part\n * of the record rather than something to infer — see {@link isStale}.\n */\nexport class Walkthrough extends Type.makeObject<Walkthrough>(DXN.make('org.dxos.type.walkthrough', '0.1.0'))(\n Schema.Struct({\n /** The pull request this narrates. */\n pullRequest: Ref.Ref(PullRequest.PullRequest),\n\n /** `owner/repo#123: title`, copied at generation so the label needs no ref load. */\n title: Schema.String.pipe(Schema.annotate({ title: 'Title' }), Schema.optional),\n\n /**\n * The whole document, as a plain string rather than a text object.\n *\n * A walkthrough is replaced wholesale on every regeneration and is never co-edited character by\n * character, so the CRDT a text object would impose is pure cost: it would keep per-character\n * history for a document nobody edits.\n */\n body: Schema.String.pipe(Schema.annotate({ title: 'Body' })),\n\n /** Head SHA the walkthrough was generated from; anything else means it describes another change. */\n commit: Schema.String.pipe(Schema.annotate({ title: 'Commit' })),\n\n generatedAt: Format.DateTime.pipe(Schema.annotate({ title: 'Generated' }), Schema.optional),\n\n /** Model that produced the prose, so a regression can be attributed after the default moves. */\n model: Schema.String.pipe(Schema.annotate({ title: 'Model' }), Schema.optional),\n\n /** Hunks the prose accounts for, over the patch's total — how much of the change it narrates. */\n covered: Schema.Number.pipe(Schema.annotate({ title: 'Hunks covered' }), Schema.optional),\n total: Schema.Number.pipe(Schema.annotate({ title: 'Hunks total' }), Schema.optional),\n }).pipe(\n Schema.annotate({ title: 'Walkthrough', description: 'A narrated reading of a pull request.' }),\n Annotation.LabelAnnotation.set(['title', 'commit']),\n Annotation.IconAnnotation.set({ icon: 'ph--path--regular', hue: 'indigo' }),\n Annotation.UserType.set(),\n ),\n) {}\n\n/** Factory wrapper around `Obj.make` for {@link Walkthrough}. */\nexport const make = (props: Obj.MakeProps<typeof Walkthrough>): Walkthrough => Obj.make(Walkthrough, props);\n\n/** Returns true when value is a Walkthrough object. */\nexport const instanceOf = (value: unknown): value is Walkthrough => Obj.instanceOf(Walkthrough, value);\n\n/** The label a walkthrough of this pull request carries. */\nexport const makeTitle = (pullRequest: PullRequest.PullRequest, title = pullRequest.title): string =>\n `${PullRequest.reference(pullRequest)}: ${title}`;\n\n/** Whether the walkthrough describes a commit other than the one given. */\nexport const isStale = (walkthrough: Walkthrough, head: string): boolean => walkthrough.commit !== head;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,IAAa,cAAb,cAAiC,KAAK,WAAwB,IAAI,KAAK,6BAA6B,OAAO,CAAC,CAAC,CAC3G,OAAO,OAAO;;CAEZ,aAAa,IAAI,IAAI,YAAY,WAAW;;CAG5C,OAAO,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,OAAO,QAAQ;;;;;;;;CAS9E,MAAM,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,OAAO,CAAC,CAAC;;CAG3D,QAAQ,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,SAAS,CAAC,CAAC;CAE/D,aAAa,OAAO,SAAS,KAAK,OAAO,SAAS,EAAE,OAAO,YAAY,CAAC,GAAG,OAAO,QAAQ;;CAG1F,OAAO,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,OAAO,QAAQ;;CAG9E,SAAS,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,gBAAgB,CAAC,GAAG,OAAO,QAAQ;CACxF,OAAO,OAAO,OAAO,KAAK,OAAO,SAAS,EAAE,OAAO,cAAc,CAAC,GAAG,OAAO,QAAQ;AACtF,CAAC,CAAC,CAAC,KACD,OAAO,SAAS;CAAE,OAAO;CAAe,aAAa;AAAwC,CAAC,GAC9F,WAAW,gBAAgB,IAAI,CAAC,SAAS,QAAQ,CAAC,GAClD,WAAW,eAAe,IAAI;CAAE,MAAM;CAAqB,KAAK;AAAS,CAAC,GAC1E,WAAW,SAAS,IAAI,CAC1B,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,QAAQ,UAA0D,IAAI,KAAK,aAAa,KAAK;;AAG1G,IAAa,cAAc,UAAyC,IAAI,WAAW,aAAa,KAAK;;AAGrG,IAAa,aAAa,aAAsC,QAAQ,YAAY,UAClF,GAAG,YAAY,UAAU,WAAW,EAAE,IAAI;;AAG5C,IAAa,WAAW,aAA0B,SAA0B,YAAY,WAAW"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Extensions.mjs","names":[],"sources":["../../../src/Extensions.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport * from './extensions/index.ts';\n"],"mappings":""}