@dxos/plugin-github 0.13.0 → 0.14.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/dist/lib/GitHubOperation.mjs +27 -1
- package/dist/lib/GitHubOperation.mjs.map +1 -1
- package/dist/lib/chunk-PullRequestArticle.mjs +31 -11
- package/dist/lib/chunk-PullRequestArticle.mjs.map +1 -1
- package/dist/lib/chunk-import-pull-request.mjs +78 -3
- package/dist/lib/chunk-import-pull-request.mjs.map +1 -1
- package/dist/lib/chunk-refresh-pull-requests.mjs +49 -0
- package/dist/lib/chunk-refresh-pull-requests.mjs.map +1 -0
- package/dist/lib/chunk-sync-pull-request.mjs +11 -9
- package/dist/lib/chunk-sync-pull-request.mjs.map +1 -1
- package/dist/lib/operations.mjs +2 -1
- package/dist/lib/operations.mjs.map +1 -1
- package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts +5 -2
- package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts.map +1 -1
- package/dist/types/src/components/PullRequestOverview/CheckRunList.test.d.ts +2 -0
- package/dist/types/src/components/PullRequestOverview/CheckRunList.test.d.ts.map +1 -0
- package/dist/types/src/components/PullRequestStatus/PullRequestStatus.d.ts.map +1 -1
- package/dist/types/src/operations/import-pull-request.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/operations/refresh-pull-requests.d.ts +5 -0
- package/dist/types/src/operations/refresh-pull-requests.d.ts.map +1 -0
- package/dist/types/src/operations/refresh.d.ts +37 -0
- package/dist/types/src/operations/refresh.d.ts.map +1 -0
- package/dist/types/src/operations/refresh.test.d.ts +2 -0
- package/dist/types/src/operations/refresh.test.d.ts.map +1 -0
- package/dist/types/src/operations/sync-pull-request.d.ts.map +1 -1
- package/dist/types/src/stories/PullRequestOverview.stories.d.ts.map +1 -1
- package/dist/types/src/types/GitHubOperation.d.ts +11 -0
- package/dist/types/src/types/GitHubOperation.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -42
- package/src/components/PullRequestOverview/ArtifactPill.tsx +1 -1
- package/src/components/PullRequestOverview/CheckRunList.test.ts +29 -0
- package/src/components/PullRequestOverview/CheckRunList.tsx +28 -7
- package/src/components/PullRequestStatus/PullRequestStatus.tsx +8 -5
- package/src/operations/import-pull-request.ts +8 -0
- package/src/operations/index.ts +1 -0
- package/src/operations/refresh-pull-requests.ts +69 -0
- package/src/operations/refresh.test.ts +112 -0
- package/src/operations/refresh.ts +111 -0
- package/src/operations/sync-pull-request.ts +10 -13
- package/src/stories/PullRequestOverview.stories.tsx +2 -1
- package/src/types/GitHubOperation.ts +26 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-PullRequestArticle.mjs","names":[],"sources":["../../src/components/PullRequestFiles/files.ts","../../src/hooks/usePullRequestFiles.ts","../../src/hooks/usePullRequestDiff.ts","../../src/components/CommentComposer/CommentComposer.tsx","../../src/components/PullRequestFiles/DiffStat.tsx","../../src/components/PullRequestFiles/FileTree.tsx","../../src/components/WalkthroughView/extensions.ts","../../src/components/WalkthroughView/WalkthroughView.tsx","../../src/components/PullRequestFiles/PullRequestFiles.tsx","../../src/components/PullRequestOverview/ArtifactPill.tsx","../../src/components/PullRequestOverview/CheckRunList.tsx","../../src/components/PullRequestOverview/PullRequestDetails.tsx","../../src/pull-request-body.ts","../../src/components/PullRequestOverview/RelatedCards.tsx","../../src/components/PullRequestOverview/PullRequestOverview.tsx","../../src/components/PullRequestStatus/PullRequestStatus.tsx","../../src/containers/PullRequestArticle/failure.ts","../../src/containers/PullRequestArticle/PullRequestArticle.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type PatchFile, renderHunks } from '../../walkthrough/patch.ts';\n\n/** A node of the changed-file tree: a directory (with children) or a changed file (with its patch). */\nexport type FileNode = {\n /**\n * A generated id rather than the path: the tree joins ids into row paths with a separator a file\n * name may itself contain (`+page.svelte`).\n */\n id: string;\n /** The full path of the file or directory; the synthetic root's is empty. */\n path: string;\n /** What the row shows: a base name, or a run of directories that each hold only one child. */\n name: string;\n file?: PatchFile;\n children: FileNode[];\n added: number;\n removed: number;\n};\n\n/** Id of the synthetic root the tree model anchors its top-level rows to; never rendered. */\nexport const FILE_TREE_ROOT = 'root';\n\n/**\n * The changed files as a directory tree, directories before files and each alphabetical — the order\n * GitHub's own file tree uses. A directory whose only child is another directory is folded into one\n * row (`src/components`), since a chain of single-entry folders is depth without information.\n */\nexport const buildFileTree = (files: readonly PatchFile[]): FileNode => {\n let count = 0;\n const nextId = () => `node-${++count}`;\n const root: FileNode = { id: FILE_TREE_ROOT, path: '', name: '', children: [], added: 0, removed: 0 };\n for (const file of files) {\n const segments = file.path.split('/');\n let parent = root;\n for (let index = 0; index < segments.length - 1; index++) {\n const path = segments.slice(0, index + 1).join('/');\n // Directories only: a change can replace a file with a directory of the same name.\n let directory = parent.children.find((child) => !child.file && child.path === path);\n if (!directory) {\n directory = { id: nextId(), path, name: segments[index], children: [], added: 0, removed: 0 };\n parent.children.push(directory);\n }\n parent = directory;\n }\n parent.children.push({\n id: nextId(),\n path: file.path,\n name: segments.at(-1) ?? file.path,\n file,\n children: [],\n added: file.added,\n removed: file.removed,\n });\n }\n\n const finish = (node: FileNode): FileNode => {\n const children = node.children.map(finish).sort(compareNodes);\n let folded: FileNode = {\n ...node,\n children,\n added: node.file ? node.added : children.reduce((sum, child) => sum + child.added, 0),\n removed: node.file ? node.removed : children.reduce((sum, child) => sum + child.removed, 0),\n };\n while (folded !== root && !folded.file && folded.children.length === 1 && !folded.children[0].file) {\n const [only] = folded.children;\n folded = { ...only, name: `${folded.name}/${only.name}` };\n }\n return folded;\n };\n\n return finish(root);\n};\n\nconst compareNodes = (left: FileNode, right: FileNode): number =>\n Number(!!left.file) - Number(!!right.file) || left.name.localeCompare(right.name);\n\n/** The files in the order the tree lists them, which is the order previous/next walks. */\nexport const flattenFiles = (node: FileNode): PatchFile[] =>\n node.file ? [node.file] : node.children.flatMap(flattenFiles);\n\n/**\n * One file's change as the ```diff fence the walkthrough renders, so the files view shows a file\n * exactly as a walkthrough chunk would. The fence is one backtick longer than any run in the body:\n * a context line of a markdown file can itself be a fence, which would otherwise close this one.\n */\nexport const diffFence = (file: PatchFile): string => {\n const body = renderHunks(file.hunks);\n const longest = Math.max(0, ...(body.match(/`+/g) ?? []).map((run) => run.length));\n const fence = '`'.repeat(Math.max(3, longest + 1));\n return `${fence}diff file=${file.path}\\n${body}\\n${fence}`;\n};\n\n/**\n * A short digest of a file's change. A file is reviewed at a signature: when a push changes the\n * file its signature moves and the check falls away, as GitHub's \"Viewed\" does.\n */\nexport const fileSignature = (file: PatchFile): string => {\n // FNV-1a over the hunk text; collisions only cost a stale check, never correctness.\n let hash = 0x811c9dc5;\n for (const hunk of file.hunks) {\n for (const line of [hunk.header, ...hunk.lines]) {\n for (let index = 0; index < line.length; index++) {\n hash ^= line.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n hash ^= 10;\n hash = Math.imul(hash, 0x01000193);\n }\n }\n return (hash >>> 0).toString(36);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { log } from '@dxos/log';\n\nimport { type FileNode, buildFileTree, fileSignature, flattenFiles } from '../components/PullRequestFiles/files.ts';\nimport { type PatchFile, parsePatch } from '../walkthrough/patch.ts';\n\nexport type PullRequestFiles = {\n tree?: FileNode;\n files: PatchFile[];\n /** The file on screen. */\n file?: PatchFile;\n reviewed: ReadonlySet<string>;\n select: (path: string) => void;\n /** Moves to the file `delta` places away in tree order; a no-op past either end. */\n step: (delta: number) => void;\n setReviewed: (path: string, reviewed: boolean) => void;\n};\n\n/** Paths the reader checked off, each at the signature of the change they reviewed. */\ntype ReviewedRecord = Record<string, string>;\n\nconst readRecord = (key: string): ReviewedRecord => {\n try {\n const value = localStorage.getItem(key);\n return value ? JSON.parse(value) : {};\n } catch (error) {\n // Blocked or cleared storage leaves the reader with nothing checked, which is recoverable.\n log.warn('reviewed files unreadable', { error });\n return {};\n }\n};\n\nconst writeRecord = (key: string, record: ReviewedRecord): void => {\n try {\n localStorage.setItem(key, JSON.stringify(record));\n } catch (error) {\n log.warn('reviewed files not saved', { error });\n }\n};\n\n/**\n * A pull request's changed files, the one on screen, and which the reader has reviewed.\n *\n * Reviewed state is the reader's own, so it lives in their browser under `storageKey` rather than in\n * the space. A file is reviewed at the change it had when checked: a push that changes it unchecks\n * it, as GitHub's \"Viewed\" does.\n */\nexport const usePullRequestFiles = (diff: string | undefined, storageKey: string): PullRequestFiles => {\n const files = useMemo(() => (diff === undefined ? [] : parsePatch(diff)), [diff]);\n const tree = useMemo(() => (diff === undefined ? undefined : buildFileTree(files)), [diff, files]);\n const order = useMemo(() => (tree ? flattenFiles(tree) : []), [tree]);\n const signatures = useMemo(() => new Map(files.map((file) => [file.path, fileSignature(file)])), [files]);\n\n const [record, setRecord] = useState<ReviewedRecord>(() => readRecord(storageKey));\n useEffect(() => setRecord(readRecord(storageKey)), [storageKey]);\n\n const reviewed = useMemo(\n () => new Set(Object.keys(record).filter((path) => signatures.get(path) === record[path])),\n [record, signatures],\n );\n\n const setReviewed = useCallback(\n (path: string, value: boolean) => {\n setRecord((previous) => {\n const next = { ...previous };\n const signature = signatures.get(path);\n if (value && signature) {\n next[path] = signature;\n } else {\n delete next[path];\n }\n writeRecord(storageKey, next);\n return next;\n });\n },\n [signatures, storageKey],\n );\n\n const [selected, setSelected] = useState<string>();\n const file = order.find((candidate) => candidate.path === selected) ?? order[0];\n const step = useCallback(\n (delta: number) => {\n const index = order.findIndex((candidate) => candidate.path === file?.path);\n const next = order[index + delta];\n if (next) {\n setSelected(next.path);\n }\n },\n [order, file],\n );\n\n return { tree, files, file, reviewed, select: setSelected, step, setReviewed };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type Ref } from '@dxos/echo';\nimport { type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PullRequest } from '@dxos/types';\n\nimport { GitHubOperation } from '#types';\n\nexport type PullRequestDiff = {\n diff?: string;\n /** Head commit the diff was read at, which a line comment on it must name. */\n commit?: string;\n error?: Error;\n};\n\n/** Reads a pull request's diff through the space's GitHub connection, once `enabled` first turns true. */\nexport const usePullRequestDiff = (\n pullRequest: Ref.Ref<PullRequest.PullRequest>,\n spaceId: SpaceId | undefined,\n enabled: boolean,\n): PullRequestDiff => {\n const { invokePromise } = Hooks.useOperationInvoker();\n const [result, setResult] = useState<PullRequestDiff>({});\n const [requested, setRequested] = useState(false);\n useEffect(() => {\n if (enabled) {\n setRequested(true);\n }\n }, [enabled]);\n\n useEffect(() => {\n if (!requested) {\n return;\n }\n let cancelled = false;\n void invokePromise(GitHubOperation.GetPullRequestDiff, { pullRequest }, { spaceId }).then(({ data, error }) => {\n if (cancelled) {\n return;\n }\n if (error) {\n log.warn('pull request diff failed', { error });\n }\n setResult({ diff: data?.diff, commit: data?.commit, error });\n });\n return () => {\n cancelled = true;\n };\n }, [requested, invokePromise, pullRequest, spaceId]);\n\n return result;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type KeyboardEvent, type RefObject, useCallback } from 'react';\n\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Popover from '@dxos/react-ui/Popover';\nimport * as VirtualAnchor from '@dxos/react-ui/VirtualAnchor';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\n\nexport type CommentComposerProps = {\n value: string;\n busy?: boolean;\n /** The diff line the comment is addressed to, named above the field; absent for a pull request comment. */\n target?: DiffLineTarget;\n onValueChange: (value: string) => void;\n onSubmit: () => void;\n onCancel: () => void;\n};\n\n/**\n * The comment field, its target and its buttons — rendered as a band under the pull request header\n * when the comment is about the pull request, and inside {@link LineCommentPopover} when it is\n * about one line of a diff.\n */\nexport const CommentComposer = ({ value, busy, target, onValueChange, onSubmit, onCancel }: CommentComposerProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n // Cmd/Ctrl+Enter submits, matching GitHub's own comment form.\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n if (!busy && value.trim()) {\n onSubmit();\n }\n }\n },\n [busy, value, onSubmit],\n );\n\n return (\n <>\n {target && (\n <span className='text-sm text-fg-muted'>\n {t('comment-line.label', { file: target.file, line: target.line })}\n </span>\n )}\n <Field.Root>\n <Input.Textarea\n autoFocus\n rows={4}\n placeholder={t('comment-placeholder.label')}\n value={value}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n </Field.Root>\n <Layout.Flex justify='end' gap='sm'>\n <Button.Root onClick={onCancel}>{t('comment-cancel.label')}</Button.Root>\n <Button.Root variant='primary' disabled={busy || !value.trim()} onClick={onSubmit}>\n {t('comment-submit.label')}\n </Button.Root>\n </Layout.Flex>\n </>\n );\n};\n\n/** The composer as a band under the toolbar, for a comment on the pull request as a whole. */\nexport const CommentBand = (props: CommentComposerProps) => (\n <Layout.Flex column gap='sm' classNames='p-3 border-b border-separator'>\n <CommentComposer {...props} />\n </Layout.Flex>\n);\n\nexport type LineCommentPopoverProps = CommentComposerProps & {\n open: boolean;\n /** The diff line's comment button, which CodeMirror owns; the popover is positioned at it. */\n anchorRef: RefObject<HTMLElement | null>;\n};\n\n/**\n * The composer floated at the diff line it addresses, so the reader reads the comment against the\n * code it is about rather than against a band at the other end of the document.\n */\nexport const LineCommentPopover = ({ open, anchorRef, ...props }: LineCommentPopoverProps) => (\n <Popover.Root\n open={open}\n onOpenChange={({ open: next }) => {\n if (!next) {\n props.onCancel();\n }\n }}\n positioning={{ ...VirtualAnchor.virtualAnchor(anchorRef), placement: 'bottom-start' }}\n >\n <Popover.Content classNames='w-[28rem] max-w-[90cqi]'>\n <Popover.Body classNames='flex flex-col gap-2 p-2'>\n <CommentComposer {...props} />\n </Popover.Body>\n </Popover.Content>\n </Popover.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nexport type DiffStatProps = { added: number; removed: number };\n\n/** `+12 -3`, coloured as the diff gutters are, with a zero count left out. */\nexport const DiffStat = ({ added, removed }: DiffStatProps) => (\n <span className='flex items-center gap-1 ps-2 text-xs tabular-nums whitespace-nowrap'>\n {added > 0 && <span className='text-(--color-cm-diff-add-gutter)'>+{added}</span>}\n {removed > 0 && <span className='text-(--color-cm-diff-remove-gutter)'>-{removed}</span>}\n </span>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { Tree, type TreeNode, type TreeSelectEvent, createStaticTreeModel } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { meta } from '#meta';\n\nimport { DiffStat } from './DiffStat.tsx';\nimport { type FileNode } from './files.ts';\n\nexport type FileTreeProps = {\n root: FileNode;\n /** Path of the file on screen. */\n selected?: string;\n /** Paths of the files the reader has checked off. */\n reviewed: ReadonlySet<string>;\n onSelect: (path: string) => void;\n onReviewedChange: (path: string, reviewed: boolean) => void;\n};\n\n/**\n * The changed files as a tree: a checkbox per file to mark it reviewed, its change counts at the\n * trailing edge, and the file on screen as the current row.\n */\nexport const FileTree = ({ root, selected, reviewed, onSelect, onReviewedChange }: FileTreeProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n // The model is rebuilt whenever the selection moves, so the reader's collapses live outside it.\n const [closed, setClosed] = useState<ReadonlySet<string>>(() => new Set());\n\n const model = useMemo(\n () =>\n createStaticTreeModel<FileNode>(root, {\n getChildren: (node) => node.children,\n // `count` off: the counts that matter here are the change counts in the trailing column.\n getProps: (node) => ({ label: node.name, count: undefined, testId: 'pull-request.files.row' }),\n isOpen: (node) => !closed.has(node.id),\n isCurrent: (node) => node.file !== undefined && node.path === selected,\n }),\n [root, selected, closed],\n );\n\n const handleOpenChange = useCallback(\n ({ item, open }: { item: FileNode; open: boolean }) =>\n setClosed((previous) => {\n const next = new Set(previous);\n if (open) {\n next.delete(item.id);\n } else {\n next.add(item.id);\n }\n return next;\n }),\n [],\n );\n\n const handleSelect = useCallback(\n ({ item }: TreeSelectEvent<FileNode>) => {\n if (item.file) {\n onSelect(item.path);\n }\n },\n [onSelect],\n );\n\n const renderRow = useCallback(\n (node: TreeNode<FileNode>) => {\n const item = node.item;\n return (\n <Tree.Item node={node}>\n <Tree.ItemIndicator />\n <Tree.ItemIcon icon={item?.file ? undefined : 'ph--folder--regular'}>\n {item?.file && (\n <Input.Checkbox\n checked={reviewed.has(item.path)}\n onCheckedChange={({ checked }) => onReviewedChange(item.path, checked === true)}\n // Checking a file off is not a request to open it.\n onClick={(event) => event.stopPropagation()}\n aria-label={t('file-reviewed.label')}\n data-testid='pull-request.files.reviewed'\n />\n )}\n </Tree.ItemIcon>\n <Tree.ItemText />\n {item && <DiffStat added={item.added} removed={item.removed} />}\n </Tree.Item>\n );\n },\n [reviewed, onReviewedChange, t],\n );\n\n return (\n <Tree.Root id={root.id} model={model} size='sm' onOpenChange={handleOpenChange} onSelect={handleSelect}>\n <Tree.Label srOnly>{t('files-tree.label')}</Tree.Label>\n <Tree.Content>{renderRow}</Tree.Content>\n </Tree.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\n\nimport {\n type DiffLayout,\n type DiffLineTarget,\n type ThemeExtensionsOptions,\n createBasicExtensions,\n createMarkdownExtensions,\n createThemeExtensions,\n decorateMarkdown,\n diffBlocks,\n scrollbarAutohide,\n walkthroughSidebar,\n walkthroughTheme,\n} from '@dxos/ui-editor';\nimport { type ThemeMode } from '@dxos/ui-types';\n\n/** A definite content width, which the diff chunks cap themselves against. */\nconst slots: ThemeExtensionsOptions['slots'] = {\n content: { className: 'dx-container-type-inline-size w-full mx-auto! max-w-[min(72rem,100%-3rem)] py-3!' },\n};\n\nexport type DiffDocumentOptions = {\n themeMode: ThemeMode;\n /** The navigation rail beside the document; `none` for a document that is a single file. */\n sidebar?: 'full' | 'stats' | 'none';\n layout?: DiffLayout;\n onLineComment?: (target: DiffLineTarget, anchor: HTMLElement) => void;\n};\n\n/**\n * A read-only markdown document whose ```diff fences render as diff chunks — the one reading surface\n * both a walkthrough and a single changed file are shown in, so the two cannot drift apart.\n */\nexport const diffDocumentExtensions = ({\n themeMode,\n sidebar = 'none',\n layout,\n onLineComment,\n}: DiffDocumentOptions): Extension => [\n createThemeExtensions({ themeMode, slots }),\n createBasicExtensions({ lineWrapping: true, readOnly: true }),\n createMarkdownExtensions(),\n decorateMarkdown(),\n scrollbarAutohide(),\n walkthroughTheme(),\n diffBlocks({ layout, ...(onLineComment ? { onLineComment } : {}) }),\n sidebar === 'none' ? [] : walkthroughSidebar({ variant: sidebar }),\n];\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { TextEditor } from '@dxos/react-ui-editor';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\n\nimport { spaceHeadings } from '../../walkthrough/headings.ts';\nimport { type DiffDocumentOptions, diffDocumentExtensions } from './extensions.ts';\n\nexport type WalkthroughViewProps = Omit<DiffDocumentOptions, 'themeMode'> & {\n /** The markdown document: prose, headings and ```diff fences. */\n value: string;\n};\n\n/**\n * A read-only diff document: a whole walkthrough with its navigation rail, or one file's change as a\n * single fence. Either way the chunks are the walkthrough's own, so a file reads the same in both.\n */\nexport const WalkthroughView = ({ value, sidebar, layout, onLineComment }: WalkthroughViewProps) => {\n const themeMode = Hooks.useThemeMode();\n const extensions = useMemo(\n () => diffDocumentExtensions({ themeMode, sidebar, layout, onLineComment }),\n [themeMode, sidebar, layout, onLineComment],\n );\n\n // Walkthroughs stored before generation spaced their headings still read with a blank line above each.\n const markdown = useMemo(() => spaceHeadings(value), [value]);\n\n // Only CodeMirror's own scroller may scroll: it carries the editor's themed scrollbar, whereas an\n // overflowing host would draw the browser's.\n return (\n <TextEditor value={markdown} extensions={extensions} focusable={false} classNames='dx-expand overflow-hidden' />\n );\n};\n\nexport type WalkthroughPlaceholderProps = {\n generating?: boolean;\n onGenerate: () => void;\n};\n\n/** What the walkthrough tab shows before there is a walkthrough: the offer to write one, or its progress. */\nexport const WalkthroughPlaceholder = ({ generating, onGenerate }: WalkthroughPlaceholderProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Layout.Flex column center gap='md' classNames='dx-expand'>\n <Status.Empty>{t(generating ? 'walkthrough-generating.message' : 'no-walkthrough.message')}</Status.Empty>\n {!generating && (\n <Button.Root variant='primary' onClick={onGenerate}>\n {t('generate-walkthrough.label')}\n </Button.Root>\n )}\n </Layout.Flex>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Status from '@dxos/react-ui/Status';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\n\nimport { type PatchFile } from '../../walkthrough/patch.ts';\nimport { WalkthroughView } from '../WalkthroughView/index.ts';\nimport { type FileNode, diffFence } from './files.ts';\nimport { FileTree } from './FileTree.tsx';\n\nexport type PullRequestFilesProps = {\n /** Undefined while the diff is loading. */\n tree?: FileNode;\n /** The file on screen. */\n file?: PatchFile;\n reviewed: ReadonlySet<string>;\n total: number;\n /** Shown in place of the files when the diff could not be read. */\n error?: string;\n onSelect: (path: string) => void;\n onReviewedChange: (path: string, reviewed: boolean) => void;\n onLineComment?: (target: DiffLineTarget, anchor: HTMLElement) => void;\n};\n\n/**\n * Every changed file, one at a time: the file's diff rendered as a walkthrough chunk, beside a rail\n * listing the changed files as a tree the reader checks off as they go.\n */\nexport const PullRequestFiles = ({\n tree,\n file,\n reviewed,\n total,\n error,\n onSelect,\n onReviewedChange,\n onLineComment,\n}: PullRequestFilesProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const fence = useMemo(() => (file && file.hunks.length > 0 ? diffFence(file) : undefined), [file]);\n\n if (error) {\n return (\n <Status.Empty icon='ph--warning--regular' classNames='dx-expand'>\n {error}\n </Status.Empty>\n );\n }\n if (!tree) {\n return <Status.Empty classNames='dx-expand'>{t('files-loading.message')}</Status.Empty>;\n }\n\n return (\n <Layout.Grid grow cols={['fill', '18rem']} data-testid='pull-request.files'>\n {fence ? (\n // Keyed by file so the next file opens at its top rather than at the previous one's scroll.\n <WalkthroughView key={file?.path} value={fence} onLineComment={onLineComment} />\n ) : (\n <Status.Empty classNames='dx-expand'>{t(file ? 'file-no-diff.message' : 'no-files.message')}</Status.Empty>\n )}\n <ScrollArea.Root classNames='border-s border-separator-subtle'>\n <ScrollArea.Viewport classNames='p-2'>\n <Field.Root>\n <Field.Label classNames='px-2'>{t('files-reviewed.label', { reviewed: reviewed.size, total })}</Field.Label>\n </Field.Root>\n <FileTree\n root={tree}\n selected={file?.path}\n reviewed={reviewed}\n onSelect={onSelect}\n onReviewedChange={onReviewedChange}\n />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Layout.Grid>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type ReactNode } from 'react';\n\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Popover from '@dxos/react-ui/Popover';\n\nimport { type ArtifactKind, type ArtifactLink } from '../../pull-request-body.ts';\n\n/** The leading icon for each kind of artifact. */\nexport const artifactIcon: Record<ArtifactKind, string> = {\n video: 'ph--film-strip--regular',\n image: 'ph--image--regular',\n file: 'ph--file--regular',\n};\n\n/** The image or video itself, or nothing for a file the browser cannot show inline. */\nexport const ArtifactMedia = ({ artifact, classNames }: { artifact: ArtifactLink; classNames?: string }) =>\n artifact.kind === 'video' ? (\n <video\n src={artifact.url}\n controls\n muted\n playsInline\n preload='metadata'\n className={['block w-full bg-black rounded-sm', classNames].filter(Boolean).join(' ')}\n data-testid='pull-request.artifact.video'\n />\n ) : artifact.kind === 'image' ? (\n <img\n src={artifact.url}\n alt={artifact.label ?? artifact.name}\n loading='lazy'\n className={['block w-full object-contain rounded-sm', classNames].filter(Boolean).join(' ')}\n data-testid='pull-request.artifact.image'\n />\n ) : null;\n\nexport type ArtifactPillProps = {\n artifact: ArtifactLink;\n /** The link's text; the file name when it was written bare. */\n children?: ReactNode;\n};\n\n/**\n * An artifact link as a pill that previews its image or video in place, so a reader sees the demo\n * without leaving the pull request. The outline matches the anchor chip a GitHub link becomes, so\n * the body's links read as one kind of thing.\n */\nexport const ArtifactPill = ({ artifact, children }: ArtifactPillProps) => {\n const label = typeof children === 'string' && children !== artifact.url ? children : artifact.name;\n if (artifact.kind === 'file') {\n return (\n <a href={artifact.url} target='_blank' rel='noopener noreferrer' className='dx-tag-anchor'>\n {label}\n </a>\n );\n }\n\n return (\n <Popover.Root autoFocus={false}>\n <Popover.Trigger asChild>\n <Button.Root\n hue='neutral'\n size='sm'\n classNames='bg-input-surface text-fg font-normal ring-inset ring ring-neutral-border hover:bg-hover-surface hover:ring-info-border align-baseline'\n icon={artifactIcon[artifact.kind]}\n iconClassNames={artifact.kind === 'video' ? 'text-violet-500' : 'text-sky-500'}\n label={label}\n data-testid='pull-request.artifact.pill'\n />\n </Popover.Trigger>\n <Popover.Content classNames='w-[min(40rem,90vw)]'>\n <Popover.Body classNames='p-1'>\n <ArtifactMedia artifact={artifact} />\n </Popover.Body>\n </Popover.Content>\n </Popover.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { Listbox } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nconst outcomeIcon: Record<GitHubOperation.CheckOutcome, { icon: string; classNames: string }> = {\n failure: { icon: 'ph--x-circle--fill', classNames: 'text-error-text' },\n pending: { icon: 'ph--circle-notch--regular', classNames: 'text-warning-text animate-spin' },\n success: { icon: 'ph--check-circle--fill', classNames: 'text-success-text' },\n neutral: { icon: 'ph--minus-circle--regular', classNames: 'text-fg-muted' },\n skipped: { icon: 'ph--prohibit--regular', classNames: 'text-fg-muted' },\n};\n\n// What needs attention first: a failure is the reason to open the list, a running check the next.\nconst outcomeOrder: GitHubOperation.CheckOutcome[] = ['failure', 'pending', 'success', 'neutral', 'skipped'];\n\n/** `4m 12s`, or undefined for a run that has not both started and finished. */\nexport const formatDuration = (startedAt?: string, completedAt?: string): string | undefined => {\n if (!startedAt || !completedAt) {\n return undefined;\n }\n const seconds = Math.max(0, Math.round((Date.parse(completedAt) - Date.parse(startedAt)) / 1000));\n if (Number.isNaN(seconds)) {\n return undefined;\n }\n const minutes = Math.floor(seconds / 60);\n return minutes > 0 ? `${minutes}m ${seconds % 60}s` : `${seconds}s`;\n};\n\n/** Sorts runs by what needs attention, then by name so shards read in order. */\nexport const sortCheckRuns = (runs: readonly GitHubOperation.CheckRun[]): GitHubOperation.CheckRun[] =>\n [...runs].sort(\n (a, b) =>\n outcomeOrder.indexOf(a.outcome) - outcomeOrder.indexOf(b.outcome) ||\n a.name.localeCompare(b.name, undefined, { numeric: true }),\n );\n\nexport type CheckRunListProps = {\n /** Undefined while the status is loading. */\n runs?: readonly GitHubOperation.CheckRun[];\n};\n\n/** Every check on the head commit: its outcome, how long it took, and its logs a click away. */\nexport const CheckRunList = ({ runs }: CheckRunListProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const sorted = useMemo(() => (runs ? sortCheckRuns(runs) : undefined), [runs]);\n const summary = useCheckSummary(runs);\n\n if (!sorted || sorted.length === 0) {\n return <Status.Empty>{t(sorted ? 'no-checks.message' : 'checks-loading.message')}</Status.Empty>;\n }\n\n return (\n <Listbox.Root items={sorted.map((run) => ({ value: `${run.name}-${run.url ?? ''}`, label: run.name }))}>\n <Listbox.Content aria-label={summary} data-testid='pull-request.checks'>\n {sorted.map((run) => {\n const { icon, classNames } = outcomeIcon[run.outcome];\n const duration = formatDuration(run.startedAt, run.completedAt);\n // GitHub's own word when it says more than the outcome: `timed out` rather than `failed`.\n const detail =\n run.conclusion && run.conclusion !== run.outcome && run.conclusion !== 'failure'\n ? run.conclusion.replace(/_/g, ' ')\n : undefined;\n const outcome =\n run.outcome === 'skipped'\n ? t('check-outcome.skipped.label')\n : (duration ?? t(`check-outcome.${run.outcome}.label`));\n const url = run.url;\n return (\n <Listbox.Item\n key={`${run.name}-${url ?? ''}`}\n id={`${run.name}-${url ?? ''}`}\n data-outcome={run.outcome}\n data-testid='pull-request.check'\n onClick={url ? () => window.open(url, '_blank', 'noopener,noreferrer') : undefined}\n >\n <Listbox.ItemIcon icon={icon} classNames={classNames} />\n <Listbox.ItemText>{run.name}</Listbox.ItemText>\n <Listbox.ItemDescription>{[detail, outcome].filter(Boolean).join(' · ')}</Listbox.ItemDescription>\n </Listbox.Item>\n );\n })}\n </Listbox.Content>\n </Listbox.Root>\n );\n};\n\n/** The label the checks section carries: the counts once there are runs to count. */\nexport const useCheckSummary = (runs?: readonly GitHubOperation.CheckRun[]): string => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return useMemo(() => {\n if (!runs || runs.length === 0) {\n return t('checks.label');\n }\n const counts: Record<GitHubOperation.CheckOutcome, number> = {\n success: 0,\n failure: 0,\n pending: 0,\n skipped: 0,\n neutral: 0,\n };\n for (const run of runs) {\n counts[run.outcome]++;\n }\n return t('checks-summary.label', {\n passed: counts.success + counts.neutral,\n failed: counts.failure,\n pending: counts.pending,\n skipped: counts.skipped,\n });\n }, [runs, t]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\n/** What the overview's details section shows, as a read-only form: one row per fact about the pull request. */\nexport const PullRequestDetailsSchema = Schema.Struct({\n reference: Schema.String.annotate({ title: 'Pull request' }),\n state: Schema.optional(Schema.String.annotate({ title: 'State' })),\n checks: Schema.optional(Schema.String.annotate({ title: 'Checks' })),\n branches: Schema.optional(Schema.String.annotate({ title: 'Branches' })),\n});\n\nexport type PullRequestDetailsValues = Schema.Schema.Type<typeof PullRequestDetailsSchema>;\n","//\n// Copyright 2026 DXOS.org\n//\n\n/** Public host of the `agent-artifacts` R2 bucket that demo videos and screenshots are linked from. */\nexport const ARTIFACTS_HOST = 'pub-39066a86073446d7b77b1c157b660bb5.r2.dev';\n\nexport type ArtifactKind = 'video' | 'image' | 'file';\n\n/** A file in the artifacts bucket that a pull request body links to. */\nexport type ArtifactLink = {\n url: string;\n kind: ArtifactKind;\n /** The file name, the last path segment. */\n name: string;\n /** The link's own text, when it was written as `[label](url)` rather than bare. */\n label?: string;\n};\n\n/** What a pull request body says beyond its prose: the footers the harness and CI append, and the media it links. */\nexport type PullRequestBody = {\n /** The prose, with the footers taken out. */\n markdown: string;\n /** Present when the body carries the Claude Code footer. */\n claudeCode?: {\n /** The session that wrote the pull request. */\n sessionUrl?: string;\n };\n /** The Composer deployment built from the pull request's head. */\n previewUrl?: string;\n /** Artifacts in first-mention order, each once. */\n artifacts: ArtifactLink[];\n};\n\nconst VIDEO_EXTENSIONS = ['webm', 'mp4', 'mov', 'm4v', 'ogv'];\nconst IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'avif'];\n\n/** The artifact a URL names, or undefined when it is not in the artifacts bucket. */\nexport const parseArtifactLink = (url: string): Omit<ArtifactLink, 'label'> | undefined => {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return undefined;\n }\n if (parsed.protocol !== 'https:' || parsed.hostname !== ARTIFACTS_HOST) {\n return undefined;\n }\n const segment = parsed.pathname.split('/').at(-1) ?? '';\n if (!segment) {\n return undefined;\n }\n const name = safeDecode(segment);\n const extension = name.split('.').at(-1)?.toLowerCase() ?? '';\n const kind: ArtifactKind = VIDEO_EXTENSIONS.includes(extension)\n ? 'video'\n : IMAGE_EXTENSIONS.includes(extension)\n ? 'image'\n : 'file';\n return { url, kind, name };\n};\n\nconst CLAUDE_SESSION = /https:\\/\\/claude\\.ai\\/code\\/session_[A-Za-z0-9]+/;\nconst PREVIEW_BLOCK = /<!--\\s*composer-preview:begin\\s*-->([\\s\\S]*?)<!--\\s*composer-preview:end\\s*-->/;\nconst PREVIEW_LINE = /^\\s*🚀\\s*Composer preview:\\s*(https?:\\/\\/\\S+)\\s*$/m;\n// Each footer line is removed whole; they are recognised by their text, not their position.\nconst FOOTER_LINES: RegExp[] = [\n /^\\s*🤖\\s*Generated with \\[?Claude Code\\]?(\\([^)]*\\))?\\s*$/,\n /^\\s*_?Generated by \\[Claude Code\\]\\([^)]*\\)_?\\s*$/,\n new RegExp(`^\\\\s*<?${CLAUDE_SESSION.source}>?\\\\s*$`),\n];\n// `[label](url)` first so a labelled link is not also counted bare.\nconst MARKDOWN_LINK = /!?\\[([^\\]]*)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g;\nconst BARE_URL = /https?:\\/\\/[^\\s)<>\\]|]+/g;\n\n/**\n * Splits a pull request body into its prose and what the footers and links say.\n *\n * The footers are the harness's (`🤖 Generated with Claude Code` and the session URL) and CI's\n * (the Composer preview block); the article shows them as cards, so they are taken out of the prose\n * rather than rendered twice.\n */\nexport const parsePullRequestBody = (body: string | undefined): PullRequestBody => {\n let text = (body ?? '').replace(/\\r\\n/g, '\\n');\n\n const sessionUrl = text.match(CLAUDE_SESSION)?.[0];\n const hasClaudeFooter = FOOTER_LINES.slice(0, 2).some((pattern) =>\n text.split('\\n').some((line) => pattern.test(line)),\n );\n\n let previewUrl: string | undefined;\n const block = text.match(PREVIEW_BLOCK);\n if (block) {\n previewUrl = block[1].match(PREVIEW_LINE)?.[1];\n text = text.replace(PREVIEW_BLOCK, '');\n }\n const line = text.match(PREVIEW_LINE);\n if (line) {\n previewUrl ??= line[1];\n text = text.replace(PREVIEW_LINE, '');\n }\n\n const lines = text.split('\\n').filter((line) => !FOOTER_LINES.some((pattern) => pattern.test(line)));\n // The footers leave their `---` rules and blank lines behind at the end.\n while (lines.length > 0 && /^\\s*(---+|\\*\\*\\*+|___+)?\\s*$/.test(lines[lines.length - 1])) {\n lines.pop();\n }\n const markdown = lines.join('\\n').trim();\n\n return {\n markdown,\n ...(hasClaudeFooter || sessionUrl ? { claudeCode: sessionUrl ? { sessionUrl } : {} } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n artifacts: findArtifacts(markdown),\n };\n};\n\n/** Every artifact the prose links, in order of first mention. */\nconst findArtifacts = (markdown: string): ArtifactLink[] => {\n const found = new Map<string, ArtifactLink>();\n const add = (url: string, label?: string) => {\n const artifact = found.has(url) ? undefined : parseArtifactLink(url);\n if (artifact) {\n found.set(url, { ...artifact, ...(label && label !== url ? { label } : {}) });\n }\n };\n for (const [, label, url] of markdown.matchAll(MARKDOWN_LINK)) {\n add(url, label);\n }\n for (const [url] of markdown.replace(MARKDOWN_LINK, '').matchAll(BARE_URL)) {\n add(url);\n }\n\n // Order by where each first appears, since labelled links were collected before bare ones.\n return [...found.values()].sort((a, b) => markdown.indexOf(a.url) - markdown.indexOf(b.url));\n};\n\nconst safeDecode = (segment: string): string => {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { Masonry } from '@dxos/react-ui-masonry';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Card from '@dxos/react-ui/Card';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\n\nimport { meta } from '#meta';\n\nimport { type ArtifactLink, type PullRequestBody } from '../../pull-request-body.ts';\nimport { ArtifactMedia, artifactIcon } from './ArtifactPill.tsx';\n\n/** One tile of the related grid: a demo artifact, or a link out of the pull request. */\nexport type RelatedItem =\n | { kind: 'artifact'; id: string; artifact: ArtifactLink }\n | { kind: 'link'; id: string; icon: string; iconClassNames?: string; title: string; href?: string; detail?: string };\n\nexport type RelatedCardsProps = Pick<PullRequestBody, 'artifacts' | 'claudeCode' | 'previewUrl'>;\n\n/** What {@link RelatedCards} would show; empty when the pull request links to nothing beyond its diff. */\nexport const useRelatedItems = ({ artifacts, claudeCode, previewUrl }: RelatedCardsProps): RelatedItem[] => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return useMemo(() => {\n const items: RelatedItem[] = artifacts.map((artifact) => ({ kind: 'artifact', id: artifact.url, artifact }));\n if (previewUrl) {\n items.push({\n kind: 'link',\n id: 'preview',\n icon: 'ph--rocket-launch--regular',\n iconClassNames: 'text-success-text',\n title: t('preview-deployment.label'),\n href: previewUrl,\n detail: hostOf(previewUrl),\n });\n }\n if (claudeCode) {\n items.push({\n kind: 'link',\n id: 'claude',\n icon: 'px--anthropic--regular',\n iconClassNames: 'text-warning-text',\n title: claudeCode.sessionUrl ? t('claude-session.label') : t('claude-generated.label'),\n href: claudeCode.sessionUrl,\n detail: claudeCode.sessionUrl?.split('/').at(-1),\n });\n }\n return items;\n }, [artifacts, claudeCode, previewUrl, t]);\n};\n\n/**\n * What the pull request points at beyond its diff, one card each — its demo media, the preview\n * deployment built from it, and the session that wrote it — in the masonry grid related objects\n * use everywhere else. Renders inside its host's scroller rather than owning one.\n */\nexport const RelatedCards = ({ items }: { items: readonly RelatedItem[] }) => (\n <Masonry.Root Tile={RelatedCard} centered={false}>\n <Masonry.Viewport items={items} getId={(item: RelatedItem) => item.id} scroll={false} />\n </Masonry.Root>\n);\n\nconst RelatedCard = ({ data: item }: { data: RelatedItem }) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n if (item.kind === 'link') {\n return (\n <Card.Root data-testid={`pull-request.related.${item.id}`}>\n <CardHeading icon={item.icon} iconClassNames={item.iconClassNames} title={item.title} href={item.href} />\n {item.detail && (\n <Card.Row>\n <Card.Text variant='muted' truncate>\n {item.detail}\n </Card.Text>\n </Card.Row>\n )}\n </Card.Root>\n );\n }\n\n const { artifact } = item;\n return (\n <Card.Root data-testid='pull-request.related.artifact'>\n <CardHeading\n icon={artifactIcon[artifact.kind]}\n title={artifact.label ?? t(`artifact-${artifact.kind}.label`)}\n href={artifact.url}\n />\n <Card.Row>\n <Card.Text variant='muted' truncate>\n {artifact.name}\n </Card.Text>\n </Card.Row>\n {artifact.kind !== 'file' && (\n <Card.Body>\n {/* `col-span-3` spans the card's gutters, as `Card.Poster` does; the body is `display: contents`. */}\n <ArtifactMedia artifact={artifact} classNames='col-span-3 aspect-video max-h-[200px] object-cover' />\n </Card.Body>\n )}\n </Card.Root>\n );\n};\n\nconst CardHeading = ({\n icon,\n iconClassNames,\n title,\n href,\n}: {\n icon: string;\n iconClassNames?: string;\n title: string;\n href?: string;\n}) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Card.Header>\n <Layout.Block>\n <Icon.Icon icon={icon} classNames={iconClassNames} />\n </Layout.Block>\n <Card.Title>{title}</Card.Title>\n {href && (\n <Layout.Block rail='end'>\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--arrow-square-out--regular'\n label={t('open-link.label')}\n onClick={() => window.open(href, '_blank', 'noopener,noreferrer')}\n />\n </Layout.Block>\n )}\n </Card.Header>\n );\n};\n\nconst hostOf = (url: string): string => {\n try {\n return new URL(url).host;\n } catch {\n return url;\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { DxAnchor } from '@dxos/lit-ui/react';\nimport * as PreviewCapabilities from '@dxos/plugin-preview/PreviewCapabilities';\nimport { Form } from '@dxos/react-ui-form';\nimport { MarkdownLink, MarkdownView, type MarkdownViewProps } from '@dxos/react-ui-markdown';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nimport { parseArtifactLink, parsePullRequestBody } from '../../pull-request-body.ts';\nimport { ArtifactPill } from './ArtifactPill.tsx';\nimport { CheckRunList, useCheckSummary } from './CheckRunList.tsx';\nimport { PullRequestDetailsSchema, type PullRequestDetailsValues } from './PullRequestDetails.tsx';\nimport { RelatedCards, useRelatedItems } from './RelatedCards.tsx';\n\nexport type PullRequestOverviewProps = {\n /** The pull request's description as written on GitHub, footers included. */\n body?: string;\n details: PullRequestDetailsValues;\n /** Undefined while the status is loading. */\n runs?: readonly GitHubOperation.CheckRun[];\n};\n\n/**\n * A pull request as its author presented it: the description, the facts about it, what it links to\n * beyond the diff, and every check on its head commit.\n */\nexport const PullRequestOverview = ({ body, details, runs }: PullRequestOverviewProps) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const parsed = useMemo(() => parsePullRequestBody(body), [body]);\n const components = useBodyComponents();\n const related = useRelatedItems(parsed);\n const checkSummary = useCheckSummary(runs);\n\n // One form hosts the whole tab, so the description and every section share its viewport's column\n // rather than each nesting a gutter of its own.\n return (\n <Form.Root schema={PullRequestDetailsSchema} values={details} layout='static' readonly>\n <Form.Viewport scroll width='document'>\n <Form.Content>\n {parsed.markdown ? (\n <MarkdownView content={parsed.markdown} components={components} data-testid='pull-request.body' />\n ) : (\n <Status.Empty>{t('no-description.message')}</Status.Empty>\n )}\n <Form.FieldSet label={t('details.label')} data-testid='pull-request.details'>\n <Form.Fields />\n </Form.FieldSet>\n {related.length > 0 && (\n <Form.FieldSet label={t('related.label')}>\n <RelatedCards items={related} />\n </Form.FieldSet>\n )}\n <Form.FieldSet label={checkSummary}>\n <CheckRunList runs={runs} />\n </Form.FieldSet>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\n/**\n * Links in the body as pills: an artifact previews its media in place, and a link a preview\n * resolver answers (another pull request, an issue) becomes the anchor chip the editor makes of it.\n */\nconst useBodyComponents = (): MarkdownViewProps['components'] => {\n const resolvers = Hooks.useCapabilities(PreviewCapabilities.LinkResolver);\n return useMemo(\n () => ({\n a: ({ children, href, node: _node, ...props }) => {\n const artifact = href ? parseArtifactLink(href) : undefined;\n if (artifact) {\n return <ArtifactPill artifact={artifact}>{children}</ArtifactPill>;\n }\n const all = resolvers.flat();\n if (!href || !PreviewCapabilities.isPreviewLink(all, href)) {\n return (\n <MarkdownLink href={href} {...props}>\n {children}\n </MarkdownLink>\n );\n }\n const icon = PreviewCapabilities.linkIcon(all, href);\n return (\n <DxAnchor eid={href} className='dx-tag-anchor'>\n {icon && (\n <Icon.Icon\n icon={icon.icon}\n size='md'\n classNames={['inline-block align-[-0.125em] me-1', icon.classNames]}\n />\n )}\n {children === href ? (PreviewCapabilities.linkLabel(all, href) ?? children) : children}\n </DxAnchor>\n );\n },\n }),\n [resolvers],\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport { type PullRequest } from '@dxos/types';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nconst stateHue: Record<PullRequest.State, string> = {\n open: 'green',\n closed: 'red',\n merged: 'purple',\n draft: 'neutral',\n};\n\nconst reviewHue: Record<GitHubOperation.ReviewState, string> = {\n approved: 'green',\n changes_requested: 'red',\n none: 'neutral',\n};\n\nconst ciHue: Record<GitHubOperation.CiState, string> = {\n success: 'green',\n failure: 'red',\n pending: 'amber',\n none: 'neutral',\n};\n\nexport type PullRequestStatusProps = {\n reference: string;\n title?: string;\n state?: PullRequest.State;\n /** Absent until the live status has arrived; the review and CI tags read as unknown until then. */\n review?: { state: GitHubOperation.ReviewState; approvals: number };\n ci?: { state: GitHubOperation.CiState; checks: GitHubOperation.CheckCounts };\n};\n\n/** One line answering where the pull request stands: open or merged, approved or not, CI green or red. */\nexport const PullRequestStatus = ({ reference, title, state, review, ci }: PullRequestStatusProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <div\n role='status'\n className='flex items-center gap-2 px-3 py-1.5 border-b border-separator-subtle text-sm min-w-0'\n data-testid='pull-request.status'\n >\n <span className='dx-tag dx-tag-inline shrink-0' data-hue='neutral'>\n {reference}\n </span>\n {title && <span className='truncate grow'>{title}</span>}\n <div className='flex items-center gap-2 shrink-0 ml-auto'>\n {state && (\n <span className='dx-tag dx-tag-inline' data-hue={stateHue[state]} data-testid='pull-request.status.state'>\n {t(`pull-request-state.${state}.label`)}\n </span>\n )}\n <span\n className='dx-tag dx-tag-inline'\n data-hue={review ? reviewHue[review.state] : 'neutral'}\n data-testid='pull-request.status.review'\n >\n {review\n ? t(`review-status.${review.state}.label`, { count: review.approvals })\n : t('review-status.unknown.label')}\n </span>\n <span\n className='dx-tag dx-tag-inline'\n data-hue={ci ? ciHue[ci.state] : 'neutral'}\n data-testid='pull-request.status.ci'\n >\n {ci ? t(`ci-status.${ci.state}.label`) : t('ci-status.unknown.label')}\n {ci && ci.checks.total > 0 && ` ${ci.checks.passed}/${ci.checks.total}`}\n </span>\n </div>\n </div>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { GitHubApi } from '../../services/index.ts';\n\n/**\n * Names a pull-request action's failure so the user knows what to do about it.\n *\n * A rejected credential is the one failure the user can fix themselves, and it is indistinguishable\n * from any other error once it reaches the toast as `error.message` — GitHub answers it as a bare\n * `401`, which surfaces as `StatusCode: non 2xx status code (401 GET …)`. Matches the same\n * distinction `ImportPullRequestDialog` already draws on `tokenStatus`.\n */\nexport const pullRequestFailureKey = (error: unknown, fallbackKey: string): string =>\n GitHubApi.responseStatus(error) === 401 ? 'github-token-rejected.title' : fallbackKey;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport type * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as ToolkitHooks from '@dxos/app-toolkit/Hooks';\nimport * as LayoutOperation from '@dxos/app-toolkit/LayoutOperation';\nimport { Database, Filter, Obj, Ref } from '@dxos/echo';\nimport { useObject, useQuery } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport * as Binding from '@dxos/plugin-connector/Binding';\nimport { ProgressMeter } from '@dxos/react-ui-components';\nimport { ActionToolbar, MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport { PullRequest } from '@dxos/types';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\nimport { GitHubOperation, Walkthrough } from '#types';\n\nimport {\n CommentBand,\n LineCommentPopover,\n type PullRequestDetailsValues,\n PullRequestFiles,\n PullRequestOverview,\n PullRequestStatus,\n WalkthroughPlaceholder,\n WalkthroughView,\n} from '../../components/index.ts';\nimport { usePullRequestDiff, usePullRequestFiles, useSyncPullRequest } from '../../hooks/index.ts';\nimport { githubConnection } from '../../operations/pull-request.ts';\nimport { newestWalkthrough } from '../../walkthrough/index.ts';\nimport { pullRequestFailureKey } from './failure.ts';\n\nconst ciLabel: Record<GitHubOperation.CiState, string> = {\n success: 'ci-status.success.label',\n failure: 'ci-status.failure.label',\n pending: 'ci-status.pending.label',\n none: 'ci-status.none.label',\n};\n\ntype Status = {\n state: PullRequest.State;\n body?: string;\n ci: GitHubOperation.CiState;\n checks: GitHubOperation.CheckCounts;\n runs: readonly GitHubOperation.CheckRun[];\n review: GitHubOperation.ReviewState;\n approvals: number;\n};\n\ntype Tab = 'overview' | 'walkthrough' | 'files';\n\nconst TABS: readonly Tab[] = ['overview', 'walkthrough', 'files'];\n\nexport type PullRequestArticleProps = AppSurface.ObjectArticleProps<PullRequest.PullRequest>;\n\n/**\n * A pull request read as a review: its number, state and CI outcome above whatever narration the\n * space holds, with approving and commenting one click away. Everything GitHub-side goes through\n * the space's GitHub connection.\n *\n * The pull request is the subject rather than the walkthrough because one exists before the other\n * does: a pull request just imported has no narration yet, and generating it is an action ON the\n * pull request, not a different object to open.\n */\nexport const PullRequestArticle = ({ role, attendableId, subject: pullRequest }: PullRequestArticleProps) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const { invokePromise } = Hooks.useOperationInvoker();\n const [subject] = useObject(pullRequest);\n const db = Obj.getDatabase(pullRequest);\n const spaceId = db?.spaceId;\n\n const walkthroughs = useQuery(db, Filter.type(Walkthrough.Walkthrough, { pullRequest: Ref.make(pullRequest) }));\n const walkthrough = useMemo(() => newestWalkthrough(walkthroughs), [walkthroughs]);\n // Watched by key rather than tied to `generating`, so a run started elsewhere shows here too.\n const walkthroughProgress = ToolkitHooks.useProgressMonitor(\n GitHubOperation.createWalkthroughProgressKey(pullRequest),\n );\n // Present only when plugin-progress is loaded; it is what lets the meter cancel or dismiss a run.\n const progressRegistry = Hooks.useOptionalCapability(AppCapabilities.ProgressRegistry);\n\n const [status, setStatus] = useState<Status>();\n // The live state where it has arrived, the stored one until then — an absent status is unknown,\n // not \"open\", and GitHub accepts an approval on a merged pull request rather than rejecting it.\n const state = status?.state ?? subject.state;\n const [tab, setTab] = useState<Tab>('overview');\n const [busy, setBusy] = useState(false);\n const [generating, setGenerating] = useState(false);\n const [composing, setComposing] = useState(false);\n const [comment, setComment] = useState('');\n // Set when the composer was opened from a diff line; the comment then goes on that line.\n const [lineTarget, setLineTarget] = useState<{ target: DiffLineTarget; commit: string }>();\n // The diff line's own button, which the composer is positioned at: the anchor is a DOM node\n // CodeMirror owns, so it is held in a ref rather than state and never re-renders the article.\n const lineAnchorRef = useRef<HTMLElement | null>(null);\n\n const openLineComment = useCallback((target: DiffLineTarget, anchor: HTMLElement, commit: string) => {\n lineAnchorRef.current = anchor;\n // The commit travels with the target: a regeneration or push between opening the composer and\n // posting would otherwise pair the NEW commit with line numbers read from the old diff, which\n // GitHub either rejects or anchors to the wrong line.\n setLineTarget({ target, commit });\n setComposing(true);\n }, []);\n\n const handleWalkthroughLineComment = useCallback(\n (target: DiffLineTarget, anchor: HTMLElement) => walkthrough && openLineComment(target, anchor, walkthrough.commit),\n [walkthrough, openLineComment],\n );\n\n /** The toolbar's composer is about the pull request, so it drops whatever line was targeted. */\n const handleToggleComposer = useCallback(() => {\n setLineTarget(undefined);\n lineAnchorRef.current = null;\n setComposing((value) => value === false || lineTarget !== undefined);\n }, [lineTarget]);\n\n const handleCloseComposer = useCallback(() => {\n setComposing(false);\n setLineTarget(undefined);\n lineAnchorRef.current = null;\n }, []);\n\n const pullRequestRef = useMemo(() => Ref.make(pullRequest), [pullRequest]);\n const reference = PullRequest.reference(pullRequest);\n\n // The diff is only read once the files tab is first opened: most visits never look at it.\n const diff = usePullRequestDiff(pullRequestRef, spaceId, tab === 'files');\n const files = usePullRequestFiles(diff.diff, `${meta.profile.key}.reviewed.${reference}`);\n const { file, step, setReviewed } = files;\n\n const handleFilesLineComment = useCallback(\n (target: DiffLineTarget, anchor: HTMLElement) => diff.commit && openLineComment(target, anchor, diff.commit),\n [diff.commit, openLineComment],\n );\n\n /** Checking a file off moves on to the next one, the way a reader works down the list. */\n const handleToggleReviewed = useCallback(() => {\n if (!file) {\n return;\n }\n const reviewed = !files.reviewed.has(file.path);\n setReviewed(file.path, reviewed);\n if (reviewed) {\n step(1);\n }\n }, [file, files.reviewed, setReviewed, step]);\n\n const refreshStatus = useCallback(async () => {\n const { data, error } = await invokePromise(\n GitHubOperation.GetPullRequestStatus,\n { pullRequest: pullRequestRef },\n { spaceId },\n );\n if (error) {\n log.warn('pull request status failed', { error });\n return;\n }\n if (data) {\n setStatus({\n state: data.state,\n body: data.body,\n ci: data.ci,\n checks: data.checks,\n runs: data.runs,\n review: data.review,\n approvals: data.approvals,\n });\n }\n }, [invokePromise, pullRequestRef, spaceId]);\n\n useEffect(() => {\n void refreshStatus();\n }, [refreshStatus]);\n\n useSyncPullRequest(pullRequest);\n\n const toast = useCallback(\n (id: string, title: string, success: boolean, description?: string) =>\n invokePromise(LayoutOperation.AddToast, {\n id: `${meta.profile.key}.${id}`,\n icon: success ? 'ph--check-circle--regular' : 'ph--warning--regular',\n title: [title, { ns: meta.profile.key }],\n ...(description ? { description } : {}),\n }),\n [invokePromise],\n );\n\n /**\n * A rejected credential is the one failure the user can fix, so it names the fix and links to the\n * connection; any other failure shows the raw error under the action's own title.\n */\n const failureToast = useCallback(\n async (id: string, fallbackKey: string, error: Error) => {\n const key = pullRequestFailureKey(error, fallbackKey);\n if (key === fallbackKey || !db) {\n return toast(id, key, false, error.message);\n }\n\n const connection = (\n await EffectEx.runPromise(\n githubConnection().pipe(\n Effect.provide(Database.layer(db)),\n Effect.orElseSucceed(() => undefined),\n ),\n )\n )?.connection;\n return invokePromise(LayoutOperation.AddToast, {\n id: `${meta.profile.key}.${id}`,\n icon: 'ph--warning--regular',\n title: [key, { ns: meta.profile.key }],\n ...(connection\n ? {\n actionLabel: ['open-github-connection.label', { ns: meta.profile.key }],\n actionAlt: ['open-github-connection.label', { ns: meta.profile.key }],\n onAction: () =>\n void invokePromise(LayoutOperation.Open, {\n subject: [Binding.connectionSubject(db.spaceId, connection.id)],\n navigation: 'immediate',\n }),\n }\n : {}),\n });\n },\n [db, invokePromise, toast],\n );\n\n const handleApprove = useCallback(async () => {\n setBusy(true);\n const { data, error } = await invokePromise(\n GitHubOperation.SubmitPullRequestApproval,\n { pullRequest: pullRequestRef },\n { spaceId },\n );\n setBusy(false);\n if (error) {\n log.warn('approve failed', { error });\n await failureToast('approve', 'approve-pull-request-error.title', error);\n return;\n }\n await toast(\n 'approve',\n data?.commented ? 'approve-pull-request-commented.title' : 'approve-pull-request-success.title',\n true,\n );\n void refreshStatus();\n }, [invokePromise, pullRequestRef, spaceId, toast, failureToast, refreshStatus]);\n\n /** `force` is what makes the toolbar's entry a REgeneration: the same head would otherwise no-op. */\n const handleGenerate = useCallback(async () => {\n setTab('walkthrough');\n setGenerating(true);\n const { error } = await invokePromise(\n GitHubOperation.GenerateWalkthrough,\n { pullRequest: pullRequestRef, force: walkthrough !== undefined },\n { spaceId },\n );\n\n setGenerating(false);\n if (error) {\n log.warn('walkthrough generation failed', { error });\n await failureToast('walkthrough', 'walkthrough-failed.title', error);\n return;\n }\n await toast('walkthrough', 'walkthrough-ready.title', true);\n }, [invokePromise, pullRequestRef, spaceId, walkthrough, toast, failureToast]);\n\n const handleCopyLink = useCallback(async () => {\n if (!subject.url) {\n return;\n }\n\n try {\n await navigator.clipboard.writeText(subject.url);\n } catch (error) {\n // Denied permission, or a document that is not focused; either way the link is not on the\n // clipboard and the success toast would be a lie.\n log.warn('copy link failed', { error });\n await toast('copy-link', 'copy-link-error.title', false);\n return;\n }\n await toast('copy-link', 'copy-link-success.title', true);\n }, [subject.url, toast]);\n\n const handleComment = useCallback(async () => {\n const text = comment.trim();\n if (!text) {\n return;\n }\n setBusy(true);\n const { error } = lineTarget\n ? await invokePromise(\n GitHubOperation.AddPullRequestReviewComment,\n {\n pullRequest: pullRequestRef,\n body: text,\n commit: lineTarget.commit,\n path: lineTarget.target.file,\n line: lineTarget.target.line,\n side: lineTarget.target.side === 'before' ? ('LEFT' as const) : ('RIGHT' as const),\n },\n { spaceId },\n )\n : await invokePromise(\n GitHubOperation.AddPullRequestComment,\n { pullRequest: pullRequestRef, body: text },\n { spaceId },\n );\n setBusy(false);\n if (error) {\n log.warn('comment failed', { error });\n await failureToast('comment', 'comment-error.title', error);\n return;\n }\n setComment('');\n handleCloseComposer();\n await toast('comment', 'comment-success.title', true);\n }, [comment, lineTarget, invokePromise, pullRequestRef, spaceId, toast, failureToast, handleCloseComposer]);\n\n // The tablist only needs the `Tabs.Root` context, which wraps the whole panel.\n const tabs = useMemo(\n () => (\n <Tabs.List>\n {TABS.map((value) => (\n <Tabs.Trigger key={value} value={value} data-testid={`pull-request.tab.${value}`}>\n {t(`${value}-tab.label`)}\n </Tabs.Trigger>\n ))}\n </Tabs.List>\n ),\n [t],\n );\n\n const fileReviewed = file !== undefined && files.reviewed.has(file.path);\n const menuActions = useMenuBuilder(() => {\n const builder = MenuBuilder.make()\n .action(\n 'tabs',\n {\n variant: 'custom',\n label: ['views.label', { ns: meta.profile.key }],\n render: () => tabs,\n },\n () => {},\n )\n // The one growing gap: everything after it sits at the trailing edge.\n .separator();\n\n if (tab === 'files') {\n builder\n .action(\n 'previousFile',\n {\n label: ['previous-file.label', { ns: meta.profile.key }],\n icon: 'ph--caret-up--regular',\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.previous-file',\n },\n () => step(-1),\n )\n .action(\n 'nextFile',\n {\n label: ['next-file.label', { ns: meta.profile.key }],\n icon: 'ph--caret-down--regular',\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.next-file',\n },\n () => step(1),\n )\n .action(\n 'reviewed',\n {\n label: ['file-reviewed.label', { ns: meta.profile.key }],\n icon: fileReviewed ? 'ph--check-square--fill' : 'ph--square--regular',\n iconOnly: false,\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.reviewed',\n },\n () => handleToggleReviewed(),\n )\n .separator('line');\n }\n\n return builder\n .action(\n 'approve',\n {\n label: ['approve-pull-request.label', { ns: meta.profile.key }],\n icon: 'ph--check-circle--regular',\n variant: 'primary',\n iconOnly: false,\n disabled: busy || state === 'merged' || state === 'closed',\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.approve',\n },\n () => void handleApprove(),\n )\n .action(\n 'comment',\n {\n label: ['comment-pull-request.label', { ns: meta.profile.key }],\n icon: 'ph--chat-text--regular',\n disabled: busy,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.comment',\n },\n () => handleToggleComposer(),\n )\n .separator('line')\n .action(\n 'generateWalkthrough',\n {\n label: [\n walkthrough ? 'regenerate-walkthrough.label' : 'generate-walkthrough.label',\n { ns: meta.profile.key },\n ],\n icon: 'ph--path--regular',\n disabled: generating,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.generate-walkthrough',\n },\n () => void handleGenerate(),\n )\n .action(\n 'openOnGitHub',\n {\n label: ['open-on-github.label', { ns: meta.profile.key }],\n icon: 'ph--arrow-square-out--regular',\n disabled: !subject.url,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.open-on-github',\n },\n () => subject.url && window.open(subject.url, '_blank', 'noopener,noreferrer'),\n )\n .action(\n 'copyLink',\n {\n label: ['copy-link.label', { ns: meta.profile.key }],\n icon: 'ph--link--regular',\n disabled: !subject.url,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.copy-link',\n },\n () => void handleCopyLink(),\n )\n .build();\n }, [\n tabs,\n tab,\n file,\n fileReviewed,\n step,\n handleToggleReviewed,\n busy,\n generating,\n walkthrough,\n subject.url,\n state,\n handleApprove,\n handleGenerate,\n handleCopyLink,\n handleToggleComposer,\n ]);\n\n const details = useMemo<PullRequestDetailsValues>(\n () => ({\n reference,\n state,\n checks: status\n ? `${t(ciLabel[status.ci])}${status.checks.total > 0 ? ` ${status.checks.passed}/${status.checks.total}` : ''}`\n : t('ci-status.unknown.label'),\n branches:\n subject.headBranch &&\n (subject.baseBranch ? `${subject.headBranch} → ${subject.baseBranch}` : subject.headBranch),\n }),\n [reference, state, status, subject.headBranch, subject.baseBranch, t],\n );\n\n const composerProps = {\n value: comment,\n busy,\n onValueChange: setComment,\n onSubmit: () => void handleComment(),\n onCancel: handleCloseComposer,\n };\n\n return (\n <Tabs.Root\n asChild\n orientation='horizontal'\n value={tab}\n onValueChange={(value) => setTab(TABS.find((candidate) => candidate === value) ?? 'overview')}\n >\n <Panel.Root role={role}>\n <Panel.Header>\n {/* `alwaysActive`: the tablist is navigation, not an attention-gated action, and a disabled\n Next toolbar disables every item in it. */}\n <ActionToolbar {...menuActions} attendableId={attendableId} alwaysActive />\n </Panel.Header>\n <Panel.Body asChild>\n <Layout.Flex column>\n <PullRequestStatus\n reference={reference}\n title={subject.title}\n state={state}\n review={status && { state: status.review, approvals: status.approvals }}\n ci={status && { state: status.ci, checks: status.checks }}\n />\n {composing && !lineTarget && <CommentBand {...composerProps} />}\n <LineCommentPopover\n {...composerProps}\n open={composing && !!lineTarget}\n anchorRef={lineAnchorRef}\n target={lineTarget?.target}\n />\n {/* Rendered by hand rather than through `Tabs.Panel`, so each tab's editor exists only while\n the tab is shown and is built against a visible, measured element. */}\n {tab === 'overview' && (\n <PullRequestOverview body={status?.body ?? subject.description} details={details} runs={status?.runs} />\n )}\n {tab === 'walkthrough' &&\n (walkthrough ? (\n <WalkthroughView value={walkthrough.body} sidebar='full' onLineComment={handleWalkthroughLineComment} />\n ) : (\n <WalkthroughPlaceholder generating={generating} onGenerate={() => void handleGenerate()} />\n ))}\n {tab === 'files' && (\n <PullRequestFiles\n tree={files.tree}\n file={file}\n reviewed={files.reviewed}\n total={files.files.length}\n error={diff.error && t('files-error.message')}\n onSelect={files.select}\n onReviewedChange={setReviewed}\n onLineComment={diff.commit ? handleFilesLineComment : undefined}\n />\n )}\n </Layout.Flex>\n </Panel.Body>\n <Panel.Footer classNames='border-t border-separator-subtle'>\n <ProgressMeter\n state={\n walkthroughProgress?.status === 'running' || walkthroughProgress?.status === 'error'\n ? walkthroughProgress\n : undefined\n }\n onCancel={\n progressRegistry && walkthroughProgress\n ? () => progressRegistry.cancel(walkthroughProgress.name)\n : undefined\n }\n />\n </Panel.Footer>\n </Panel.Root>\n </Tabs.Root>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chunk-PullRequestArticle.mjs","names":[],"sources":["../../src/components/PullRequestFiles/files.ts","../../src/hooks/usePullRequestFiles.ts","../../src/hooks/usePullRequestDiff.ts","../../src/components/CommentComposer/CommentComposer.tsx","../../src/components/PullRequestFiles/DiffStat.tsx","../../src/components/PullRequestFiles/FileTree.tsx","../../src/components/WalkthroughView/extensions.ts","../../src/components/WalkthroughView/WalkthroughView.tsx","../../src/components/PullRequestFiles/PullRequestFiles.tsx","../../src/components/PullRequestOverview/ArtifactPill.tsx","../../src/components/PullRequestOverview/CheckRunList.tsx","../../src/components/PullRequestOverview/PullRequestDetails.tsx","../../src/pull-request-body.ts","../../src/components/PullRequestOverview/RelatedCards.tsx","../../src/components/PullRequestOverview/PullRequestOverview.tsx","../../src/components/PullRequestStatus/PullRequestStatus.tsx","../../src/containers/PullRequestArticle/failure.ts","../../src/containers/PullRequestArticle/PullRequestArticle.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type PatchFile, renderHunks } from '../../walkthrough/patch.ts';\n\n/** A node of the changed-file tree: a directory (with children) or a changed file (with its patch). */\nexport type FileNode = {\n /**\n * A generated id rather than the path: the tree joins ids into row paths with a separator a file\n * name may itself contain (`+page.svelte`).\n */\n id: string;\n /** The full path of the file or directory; the synthetic root's is empty. */\n path: string;\n /** What the row shows: a base name, or a run of directories that each hold only one child. */\n name: string;\n file?: PatchFile;\n children: FileNode[];\n added: number;\n removed: number;\n};\n\n/** Id of the synthetic root the tree model anchors its top-level rows to; never rendered. */\nexport const FILE_TREE_ROOT = 'root';\n\n/**\n * The changed files as a directory tree, directories before files and each alphabetical — the order\n * GitHub's own file tree uses. A directory whose only child is another directory is folded into one\n * row (`src/components`), since a chain of single-entry folders is depth without information.\n */\nexport const buildFileTree = (files: readonly PatchFile[]): FileNode => {\n let count = 0;\n const nextId = () => `node-${++count}`;\n const root: FileNode = { id: FILE_TREE_ROOT, path: '', name: '', children: [], added: 0, removed: 0 };\n for (const file of files) {\n const segments = file.path.split('/');\n let parent = root;\n for (let index = 0; index < segments.length - 1; index++) {\n const path = segments.slice(0, index + 1).join('/');\n // Directories only: a change can replace a file with a directory of the same name.\n let directory = parent.children.find((child) => !child.file && child.path === path);\n if (!directory) {\n directory = { id: nextId(), path, name: segments[index], children: [], added: 0, removed: 0 };\n parent.children.push(directory);\n }\n parent = directory;\n }\n parent.children.push({\n id: nextId(),\n path: file.path,\n name: segments.at(-1) ?? file.path,\n file,\n children: [],\n added: file.added,\n removed: file.removed,\n });\n }\n\n const finish = (node: FileNode): FileNode => {\n const children = node.children.map(finish).sort(compareNodes);\n let folded: FileNode = {\n ...node,\n children,\n added: node.file ? node.added : children.reduce((sum, child) => sum + child.added, 0),\n removed: node.file ? node.removed : children.reduce((sum, child) => sum + child.removed, 0),\n };\n while (folded !== root && !folded.file && folded.children.length === 1 && !folded.children[0].file) {\n const [only] = folded.children;\n folded = { ...only, name: `${folded.name}/${only.name}` };\n }\n return folded;\n };\n\n return finish(root);\n};\n\nconst compareNodes = (left: FileNode, right: FileNode): number =>\n Number(!!left.file) - Number(!!right.file) || left.name.localeCompare(right.name);\n\n/** The files in the order the tree lists them, which is the order previous/next walks. */\nexport const flattenFiles = (node: FileNode): PatchFile[] =>\n node.file ? [node.file] : node.children.flatMap(flattenFiles);\n\n/**\n * One file's change as the ```diff fence the walkthrough renders, so the files view shows a file\n * exactly as a walkthrough chunk would. The fence is one backtick longer than any run in the body:\n * a context line of a markdown file can itself be a fence, which would otherwise close this one.\n */\nexport const diffFence = (file: PatchFile): string => {\n const body = renderHunks(file.hunks);\n const longest = Math.max(0, ...(body.match(/`+/g) ?? []).map((run) => run.length));\n const fence = '`'.repeat(Math.max(3, longest + 1));\n return `${fence}diff file=${file.path}\\n${body}\\n${fence}`;\n};\n\n/**\n * A short digest of a file's change. A file is reviewed at a signature: when a push changes the\n * file its signature moves and the check falls away, as GitHub's \"Viewed\" does.\n */\nexport const fileSignature = (file: PatchFile): string => {\n // FNV-1a over the hunk text; collisions only cost a stale check, never correctness.\n let hash = 0x811c9dc5;\n for (const hunk of file.hunks) {\n for (const line of [hunk.header, ...hunk.lines]) {\n for (let index = 0; index < line.length; index++) {\n hash ^= line.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n hash ^= 10;\n hash = Math.imul(hash, 0x01000193);\n }\n }\n return (hash >>> 0).toString(36);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { log } from '@dxos/log';\n\nimport { type FileNode, buildFileTree, fileSignature, flattenFiles } from '../components/PullRequestFiles/files.ts';\nimport { type PatchFile, parsePatch } from '../walkthrough/patch.ts';\n\nexport type PullRequestFiles = {\n tree?: FileNode;\n files: PatchFile[];\n /** The file on screen. */\n file?: PatchFile;\n reviewed: ReadonlySet<string>;\n select: (path: string) => void;\n /** Moves to the file `delta` places away in tree order; a no-op past either end. */\n step: (delta: number) => void;\n setReviewed: (path: string, reviewed: boolean) => void;\n};\n\n/** Paths the reader checked off, each at the signature of the change they reviewed. */\ntype ReviewedRecord = Record<string, string>;\n\nconst readRecord = (key: string): ReviewedRecord => {\n try {\n const value = localStorage.getItem(key);\n return value ? JSON.parse(value) : {};\n } catch (error) {\n // Blocked or cleared storage leaves the reader with nothing checked, which is recoverable.\n log.warn('reviewed files unreadable', { error });\n return {};\n }\n};\n\nconst writeRecord = (key: string, record: ReviewedRecord): void => {\n try {\n localStorage.setItem(key, JSON.stringify(record));\n } catch (error) {\n log.warn('reviewed files not saved', { error });\n }\n};\n\n/**\n * A pull request's changed files, the one on screen, and which the reader has reviewed.\n *\n * Reviewed state is the reader's own, so it lives in their browser under `storageKey` rather than in\n * the space. A file is reviewed at the change it had when checked: a push that changes it unchecks\n * it, as GitHub's \"Viewed\" does.\n */\nexport const usePullRequestFiles = (diff: string | undefined, storageKey: string): PullRequestFiles => {\n const files = useMemo(() => (diff === undefined ? [] : parsePatch(diff)), [diff]);\n const tree = useMemo(() => (diff === undefined ? undefined : buildFileTree(files)), [diff, files]);\n const order = useMemo(() => (tree ? flattenFiles(tree) : []), [tree]);\n const signatures = useMemo(() => new Map(files.map((file) => [file.path, fileSignature(file)])), [files]);\n\n const [record, setRecord] = useState<ReviewedRecord>(() => readRecord(storageKey));\n useEffect(() => setRecord(readRecord(storageKey)), [storageKey]);\n\n const reviewed = useMemo(\n () => new Set(Object.keys(record).filter((path) => signatures.get(path) === record[path])),\n [record, signatures],\n );\n\n const setReviewed = useCallback(\n (path: string, value: boolean) => {\n setRecord((previous) => {\n const next = { ...previous };\n const signature = signatures.get(path);\n if (value && signature) {\n next[path] = signature;\n } else {\n delete next[path];\n }\n writeRecord(storageKey, next);\n return next;\n });\n },\n [signatures, storageKey],\n );\n\n const [selected, setSelected] = useState<string>();\n const file = order.find((candidate) => candidate.path === selected) ?? order[0];\n const step = useCallback(\n (delta: number) => {\n const index = order.findIndex((candidate) => candidate.path === file?.path);\n const next = order[index + delta];\n if (next) {\n setSelected(next.path);\n }\n },\n [order, file],\n );\n\n return { tree, files, file, reviewed, select: setSelected, step, setReviewed };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type Ref } from '@dxos/echo';\nimport { type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PullRequest } from '@dxos/types';\n\nimport { GitHubOperation } from '#types';\n\nexport type PullRequestDiff = {\n diff?: string;\n /** Head commit the diff was read at, which a line comment on it must name. */\n commit?: string;\n error?: Error;\n};\n\n/** Reads a pull request's diff through the space's GitHub connection, once `enabled` first turns true. */\nexport const usePullRequestDiff = (\n pullRequest: Ref.Ref<PullRequest.PullRequest>,\n spaceId: SpaceId | undefined,\n enabled: boolean,\n): PullRequestDiff => {\n const { invokePromise } = Hooks.useOperationInvoker();\n const [result, setResult] = useState<PullRequestDiff>({});\n const [requested, setRequested] = useState(false);\n useEffect(() => {\n if (enabled) {\n setRequested(true);\n }\n }, [enabled]);\n\n useEffect(() => {\n if (!requested) {\n return;\n }\n let cancelled = false;\n void invokePromise(GitHubOperation.GetPullRequestDiff, { pullRequest }, { spaceId }).then(({ data, error }) => {\n if (cancelled) {\n return;\n }\n if (error) {\n log.warn('pull request diff failed', { error });\n }\n setResult({ diff: data?.diff, commit: data?.commit, error });\n });\n return () => {\n cancelled = true;\n };\n }, [requested, invokePromise, pullRequest, spaceId]);\n\n return result;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type KeyboardEvent, type RefObject, useCallback } from 'react';\n\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Popover from '@dxos/react-ui/Popover';\nimport * as VirtualAnchor from '@dxos/react-ui/VirtualAnchor';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\n\nexport type CommentComposerProps = {\n value: string;\n busy?: boolean;\n /** The diff line the comment is addressed to, named above the field; absent for a pull request comment. */\n target?: DiffLineTarget;\n onValueChange: (value: string) => void;\n onSubmit: () => void;\n onCancel: () => void;\n};\n\n/**\n * The comment field, its target and its buttons — rendered as a band under the pull request header\n * when the comment is about the pull request, and inside {@link LineCommentPopover} when it is\n * about one line of a diff.\n */\nexport const CommentComposer = ({ value, busy, target, onValueChange, onSubmit, onCancel }: CommentComposerProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n\n // Cmd/Ctrl+Enter submits, matching GitHub's own comment form.\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n if (!busy && value.trim()) {\n onSubmit();\n }\n }\n },\n [busy, value, onSubmit],\n );\n\n return (\n <>\n {target && (\n <span className='text-sm text-fg-muted'>\n {t('comment-line.label', { file: target.file, line: target.line })}\n </span>\n )}\n <Field.Root>\n <Input.Textarea\n autoFocus\n rows={4}\n placeholder={t('comment-placeholder.label')}\n value={value}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n </Field.Root>\n <Layout.Flex justify='end' gap='sm'>\n <Button.Root onClick={onCancel}>{t('comment-cancel.label')}</Button.Root>\n <Button.Root variant='primary' disabled={busy || !value.trim()} onClick={onSubmit}>\n {t('comment-submit.label')}\n </Button.Root>\n </Layout.Flex>\n </>\n );\n};\n\n/** The composer as a band under the toolbar, for a comment on the pull request as a whole. */\nexport const CommentBand = (props: CommentComposerProps) => (\n <Layout.Flex column gap='sm' classNames='p-3 border-b border-separator'>\n <CommentComposer {...props} />\n </Layout.Flex>\n);\n\nexport type LineCommentPopoverProps = CommentComposerProps & {\n open: boolean;\n /** The diff line's comment button, which CodeMirror owns; the popover is positioned at it. */\n anchorRef: RefObject<HTMLElement | null>;\n};\n\n/**\n * The composer floated at the diff line it addresses, so the reader reads the comment against the\n * code it is about rather than against a band at the other end of the document.\n */\nexport const LineCommentPopover = ({ open, anchorRef, ...props }: LineCommentPopoverProps) => (\n <Popover.Root\n open={open}\n onOpenChange={({ open: next }) => {\n if (!next) {\n props.onCancel();\n }\n }}\n positioning={{ ...VirtualAnchor.virtualAnchor(anchorRef), placement: 'bottom-start' }}\n >\n <Popover.Content classNames='w-[28rem] max-w-[90cqi]'>\n <Popover.Body classNames='flex flex-col gap-2 p-2'>\n <CommentComposer {...props} />\n </Popover.Body>\n </Popover.Content>\n </Popover.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nexport type DiffStatProps = { added: number; removed: number };\n\n/** `+12 -3`, coloured as the diff gutters are, with a zero count left out. */\nexport const DiffStat = ({ added, removed }: DiffStatProps) => (\n <span className='flex items-center gap-1 ps-2 text-xs tabular-nums whitespace-nowrap'>\n {added > 0 && <span className='text-(--color-cm-diff-add-gutter)'>+{added}</span>}\n {removed > 0 && <span className='text-(--color-cm-diff-remove-gutter)'>-{removed}</span>}\n </span>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { Tree, type TreeNode, type TreeSelectEvent, createStaticTreeModel } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { meta } from '#meta';\n\nimport { DiffStat } from './DiffStat.tsx';\nimport { type FileNode } from './files.ts';\n\nexport type FileTreeProps = {\n root: FileNode;\n /** Path of the file on screen. */\n selected?: string;\n /** Paths of the files the reader has checked off. */\n reviewed: ReadonlySet<string>;\n onSelect: (path: string) => void;\n onReviewedChange: (path: string, reviewed: boolean) => void;\n};\n\n/**\n * The changed files as a tree: a checkbox per file to mark it reviewed, its change counts at the\n * trailing edge, and the file on screen as the current row.\n */\nexport const FileTree = ({ root, selected, reviewed, onSelect, onReviewedChange }: FileTreeProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n // The model is rebuilt whenever the selection moves, so the reader's collapses live outside it.\n const [closed, setClosed] = useState<ReadonlySet<string>>(() => new Set());\n\n const model = useMemo(\n () =>\n createStaticTreeModel<FileNode>(root, {\n getChildren: (node) => node.children,\n // `count` off: the counts that matter here are the change counts in the trailing column.\n getProps: (node) => ({ label: node.name, count: undefined, testId: 'pull-request.files.row' }),\n isOpen: (node) => !closed.has(node.id),\n isCurrent: (node) => node.file !== undefined && node.path === selected,\n }),\n [root, selected, closed],\n );\n\n const handleOpenChange = useCallback(\n ({ item, open }: { item: FileNode; open: boolean }) =>\n setClosed((previous) => {\n const next = new Set(previous);\n if (open) {\n next.delete(item.id);\n } else {\n next.add(item.id);\n }\n return next;\n }),\n [],\n );\n\n const handleSelect = useCallback(\n ({ item }: TreeSelectEvent<FileNode>) => {\n if (item.file) {\n onSelect(item.path);\n }\n },\n [onSelect],\n );\n\n const renderRow = useCallback(\n (node: TreeNode<FileNode>) => {\n const item = node.item;\n return (\n <Tree.Item node={node}>\n <Tree.ItemIndicator />\n <Tree.ItemIcon icon={item?.file ? undefined : 'ph--folder--regular'}>\n {item?.file && (\n <Input.Checkbox\n checked={reviewed.has(item.path)}\n onCheckedChange={({ checked }) => onReviewedChange(item.path, checked === true)}\n // Checking a file off is not a request to open it.\n onClick={(event) => event.stopPropagation()}\n aria-label={t('file-reviewed.label')}\n data-testid='pull-request.files.reviewed'\n />\n )}\n </Tree.ItemIcon>\n <Tree.ItemText />\n {item && <DiffStat added={item.added} removed={item.removed} />}\n </Tree.Item>\n );\n },\n [reviewed, onReviewedChange, t],\n );\n\n return (\n <Tree.Root id={root.id} model={model} size='sm' onOpenChange={handleOpenChange} onSelect={handleSelect}>\n <Tree.Label srOnly>{t('files-tree.label')}</Tree.Label>\n <Tree.Content>{renderRow}</Tree.Content>\n </Tree.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\n\nimport {\n type DiffLayout,\n type DiffLineTarget,\n type ThemeExtensionsOptions,\n createBasicExtensions,\n createMarkdownExtensions,\n createThemeExtensions,\n decorateMarkdown,\n diffBlocks,\n scrollbarAutohide,\n walkthroughSidebar,\n walkthroughTheme,\n} from '@dxos/ui-editor';\nimport { type ThemeMode } from '@dxos/ui-types';\n\n/** A definite content width, which the diff chunks cap themselves against. */\nconst slots: ThemeExtensionsOptions['slots'] = {\n content: { className: 'dx-container-type-inline-size w-full mx-auto! max-w-[min(72rem,100%-3rem)] py-3!' },\n};\n\nexport type DiffDocumentOptions = {\n themeMode: ThemeMode;\n /** The navigation rail beside the document; `none` for a document that is a single file. */\n sidebar?: 'full' | 'stats' | 'none';\n layout?: DiffLayout;\n onLineComment?: (target: DiffLineTarget, anchor: HTMLElement) => void;\n};\n\n/**\n * A read-only markdown document whose ```diff fences render as diff chunks — the one reading surface\n * both a walkthrough and a single changed file are shown in, so the two cannot drift apart.\n */\nexport const diffDocumentExtensions = ({\n themeMode,\n sidebar = 'none',\n layout,\n onLineComment,\n}: DiffDocumentOptions): Extension => [\n createThemeExtensions({ themeMode, slots }),\n createBasicExtensions({ lineWrapping: true, readOnly: true }),\n createMarkdownExtensions(),\n decorateMarkdown(),\n scrollbarAutohide(),\n walkthroughTheme(),\n diffBlocks({ layout, ...(onLineComment ? { onLineComment } : {}) }),\n sidebar === 'none' ? [] : walkthroughSidebar({ variant: sidebar }),\n];\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { TextEditor } from '@dxos/react-ui-editor';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\n\nimport { spaceHeadings } from '../../walkthrough/headings.ts';\nimport { type DiffDocumentOptions, diffDocumentExtensions } from './extensions.ts';\n\nexport type WalkthroughViewProps = Omit<DiffDocumentOptions, 'themeMode'> & {\n /** The markdown document: prose, headings and ```diff fences. */\n value: string;\n};\n\n/**\n * A read-only diff document: a whole walkthrough with its navigation rail, or one file's change as a\n * single fence. Either way the chunks are the walkthrough's own, so a file reads the same in both.\n */\nexport const WalkthroughView = ({ value, sidebar, layout, onLineComment }: WalkthroughViewProps) => {\n const themeMode = Hooks.useThemeMode();\n const extensions = useMemo(\n () => diffDocumentExtensions({ themeMode, sidebar, layout, onLineComment }),\n [themeMode, sidebar, layout, onLineComment],\n );\n\n // Walkthroughs stored before generation spaced their headings still read with a blank line above each.\n const markdown = useMemo(() => spaceHeadings(value), [value]);\n\n // Only CodeMirror's own scroller may scroll: it carries the editor's themed scrollbar, whereas an\n // overflowing host would draw the browser's.\n return (\n <TextEditor value={markdown} extensions={extensions} focusable={false} classNames='dx-expand overflow-hidden' />\n );\n};\n\nexport type WalkthroughPlaceholderProps = {\n generating?: boolean;\n onGenerate: () => void;\n};\n\n/** What the walkthrough tab shows before there is a walkthrough: the offer to write one, or its progress. */\nexport const WalkthroughPlaceholder = ({ generating, onGenerate }: WalkthroughPlaceholderProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Layout.Flex column center gap='md' classNames='dx-expand'>\n <Status.Empty>{t(generating ? 'walkthrough-generating.message' : 'no-walkthrough.message')}</Status.Empty>\n {!generating && (\n <Button.Root variant='primary' onClick={onGenerate}>\n {t('generate-walkthrough.label')}\n </Button.Root>\n )}\n </Layout.Flex>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Status from '@dxos/react-ui/Status';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\n\nimport { type PatchFile } from '../../walkthrough/patch.ts';\nimport { WalkthroughView } from '../WalkthroughView/index.ts';\nimport { type FileNode, diffFence } from './files.ts';\nimport { FileTree } from './FileTree.tsx';\n\nexport type PullRequestFilesProps = {\n /** Undefined while the diff is loading. */\n tree?: FileNode;\n /** The file on screen. */\n file?: PatchFile;\n reviewed: ReadonlySet<string>;\n total: number;\n /** Shown in place of the files when the diff could not be read. */\n error?: string;\n onSelect: (path: string) => void;\n onReviewedChange: (path: string, reviewed: boolean) => void;\n onLineComment?: (target: DiffLineTarget, anchor: HTMLElement) => void;\n};\n\n/**\n * Every changed file, one at a time: the file's diff rendered as a walkthrough chunk, beside a rail\n * listing the changed files as a tree the reader checks off as they go.\n */\nexport const PullRequestFiles = ({\n tree,\n file,\n reviewed,\n total,\n error,\n onSelect,\n onReviewedChange,\n onLineComment,\n}: PullRequestFilesProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const fence = useMemo(() => (file && file.hunks.length > 0 ? diffFence(file) : undefined), [file]);\n\n if (error) {\n return (\n <Status.Empty icon='ph--warning--regular' classNames='dx-expand'>\n {error}\n </Status.Empty>\n );\n }\n if (!tree) {\n return <Status.Empty classNames='dx-expand'>{t('files-loading.message')}</Status.Empty>;\n }\n\n return (\n <Layout.Grid grow cols={['fill', '18rem']} data-testid='pull-request.files'>\n {fence ? (\n // Keyed by file so the next file opens at its top rather than at the previous one's scroll.\n <WalkthroughView key={file?.path} value={fence} onLineComment={onLineComment} />\n ) : (\n <Status.Empty classNames='dx-expand'>{t(file ? 'file-no-diff.message' : 'no-files.message')}</Status.Empty>\n )}\n <ScrollArea.Root classNames='border-s border-separator-subtle'>\n <ScrollArea.Viewport classNames='p-2'>\n <Field.Root>\n <Field.Label classNames='px-2'>{t('files-reviewed.label', { reviewed: reviewed.size, total })}</Field.Label>\n </Field.Root>\n <FileTree\n root={tree}\n selected={file?.path}\n reviewed={reviewed}\n onSelect={onSelect}\n onReviewedChange={onReviewedChange}\n />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Layout.Grid>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type ReactNode } from 'react';\n\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Popover from '@dxos/react-ui/Popover';\n\nimport { type ArtifactKind, type ArtifactLink } from '../../pull-request-body.ts';\n\n/** The leading icon for each kind of artifact. */\nexport const artifactIcon: Record<ArtifactKind, string> = {\n video: 'ph--film-strip--regular',\n image: 'ph--image--regular',\n file: 'ph--file--regular',\n};\n\n/** The image or video itself, or nothing for a file the browser cannot show inline. */\nexport const ArtifactMedia = ({ artifact, classNames }: { artifact: ArtifactLink; classNames?: string }) =>\n artifact.kind === 'video' ? (\n <video\n src={artifact.url}\n controls\n muted\n playsInline\n preload='metadata'\n className={['block w-full bg-black rounded-sm', classNames].filter(Boolean).join(' ')}\n data-testid='pull-request.artifact.video'\n />\n ) : artifact.kind === 'image' ? (\n <img\n src={artifact.url}\n alt={artifact.label ?? artifact.name}\n loading='lazy'\n className={['block w-full object-contain rounded-sm', classNames].filter(Boolean).join(' ')}\n data-testid='pull-request.artifact.image'\n />\n ) : null;\n\nexport type ArtifactPillProps = {\n artifact: ArtifactLink;\n /** The link's text; the file name when it was written bare. */\n children?: ReactNode;\n};\n\n/**\n * An artifact link as a pill that previews its image or video in place, so a reader sees the demo\n * without leaving the pull request. The outline matches the anchor chip a GitHub link becomes, so\n * the body's links read as one kind of thing.\n */\nexport const ArtifactPill = ({ artifact, children }: ArtifactPillProps) => {\n const label = typeof children === 'string' && children !== artifact.url ? children : artifact.name;\n if (artifact.kind === 'file') {\n return (\n <a href={artifact.url} target='_blank' rel='noopener noreferrer' className='dx-tag-anchor'>\n {label}\n </a>\n );\n }\n\n return (\n <Popover.Root autoFocus={false}>\n <Popover.Trigger asChild>\n <Button.Root\n hue='neutral'\n size='sm'\n classNames='bg-input-surface text-fg font-normal ring-inset ring ring-neutral-border hover:bg-hover-surface hover:ring-info-border align-baseline'\n icon={artifactIcon[artifact.kind]}\n iconClassNames={artifact.kind === 'video' ? 'text-violet-text' : 'text-sky-text'}\n label={label}\n data-testid='pull-request.artifact.pill'\n />\n </Popover.Trigger>\n <Popover.Content classNames='w-[min(40rem,90vw)]'>\n <Popover.Body classNames='p-1'>\n <ArtifactMedia artifact={artifact} />\n </Popover.Body>\n </Popover.Content>\n </Popover.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useState } from 'react';\n\nimport { Listbox } from '@dxos/react-ui-list';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nconst outcomeIcon: Record<GitHubOperation.CheckOutcome, { icon: string; classNames: string }> = {\n failure: { icon: 'ph--x-circle--fill', classNames: 'text-error-text' },\n pending: { icon: 'ph--circle-notch--regular', classNames: 'text-warning-text animate-spin' },\n success: { icon: 'ph--check-circle--fill', classNames: 'text-success-text' },\n neutral: { icon: 'ph--minus-circle--regular', classNames: 'text-fg-muted' },\n skipped: { icon: 'ph--prohibit--regular', classNames: 'text-fg-muted' },\n};\n\n// What needs attention first: a failure is the reason to open the list, a running check the next.\nconst outcomeOrder: GitHubOperation.CheckOutcome[] = ['failure', 'pending', 'success', 'neutral', 'skipped'];\n\n/**\n * `4m 12s` from start to finish, or to `now` for a run still in progress;\n * undefined for a run that has not started, or has not finished when no `now` is given.\n */\nexport const formatDuration = (startedAt?: string, completedAt?: string, now?: number): string | undefined => {\n const end = completedAt ? Date.parse(completedAt) : now;\n if (!startedAt || end === undefined) {\n return undefined;\n }\n const seconds = Math.max(0, Math.round((end - Date.parse(startedAt)) / 1000));\n if (Number.isNaN(seconds)) {\n return undefined;\n }\n const minutes = Math.floor(seconds / 60);\n return minutes > 0 ? `${minutes}m ${seconds % 60}s` : `${seconds}s`;\n};\n\n/** The current time, re-rendering once a second while `active` so elapsed times stay current. */\nconst useNow = (active: boolean): number => {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!active) {\n return;\n }\n setNow(Date.now());\n const interval = setInterval(() => setNow(Date.now()), 1_000);\n return () => clearInterval(interval);\n }, [active]);\n return now;\n};\n\n/** Sorts runs by what needs attention, then by name so shards read in order. */\nexport const sortCheckRuns = (runs: readonly GitHubOperation.CheckRun[]): GitHubOperation.CheckRun[] =>\n [...runs].sort(\n (a, b) =>\n outcomeOrder.indexOf(a.outcome) - outcomeOrder.indexOf(b.outcome) ||\n a.name.localeCompare(b.name, undefined, { numeric: true }),\n );\n\nexport type CheckRunListProps = {\n /** Undefined while the status is loading. */\n runs?: readonly GitHubOperation.CheckRun[];\n};\n\n/** Every check on the head commit: its outcome, how long it took, and its logs a click away. */\nexport const CheckRunList = ({ runs }: CheckRunListProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n const sorted = useMemo(() => (runs ? sortCheckRuns(runs) : undefined), [runs]);\n const summary = useCheckSummary(runs);\n const now = useNow(runs?.some((run) => run.outcome === 'pending' && run.startedAt) ?? false);\n\n if (!sorted || sorted.length === 0) {\n return <Status.Empty>{t(sorted ? 'no-checks.message' : 'checks-loading.message')}</Status.Empty>;\n }\n\n return (\n <Listbox.Root items={sorted.map((run) => ({ value: `${run.name}-${run.url ?? ''}`, label: run.name }))}>\n <Listbox.Content aria-label={summary} data-testid='pull-request.checks'>\n {sorted.map((run) => {\n const { icon, classNames } = outcomeIcon[run.outcome];\n const duration = formatDuration(run.startedAt, run.completedAt, run.outcome === 'pending' ? now : undefined);\n // GitHub's own word when it says more than the outcome: `timed out` rather than `failed`.\n const detail =\n run.conclusion && run.conclusion !== run.outcome && run.conclusion !== 'failure'\n ? run.conclusion.replace(/_/g, ' ')\n : undefined;\n const outcome =\n run.outcome === 'skipped'\n ? t('check-outcome.skipped.label')\n : run.outcome === 'pending'\n ? [t('check-outcome.pending.label'), duration].filter(Boolean).join(' · ')\n : (duration ?? t(`check-outcome.${run.outcome}.label`));\n const url = run.url;\n return (\n <Listbox.Item\n key={`${run.name}-${url ?? ''}`}\n id={`${run.name}-${url ?? ''}`}\n data-outcome={run.outcome}\n data-testid='pull-request.check'\n onClick={url ? () => window.open(url, '_blank', 'noopener,noreferrer') : undefined}\n >\n <Listbox.ItemIcon icon={icon} classNames={classNames} />\n <Listbox.ItemText>{run.name}</Listbox.ItemText>\n <Listbox.ItemDescription>{[detail, outcome].filter(Boolean).join(' · ')}</Listbox.ItemDescription>\n </Listbox.Item>\n );\n })}\n </Listbox.Content>\n </Listbox.Root>\n );\n};\n\n/** The label the checks section carries: the counts once there are runs to count. */\nexport const useCheckSummary = (runs?: readonly GitHubOperation.CheckRun[]): string => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return useMemo(() => {\n if (!runs || runs.length === 0) {\n return t('checks.label');\n }\n const counts: Record<GitHubOperation.CheckOutcome, number> = {\n success: 0,\n failure: 0,\n pending: 0,\n skipped: 0,\n neutral: 0,\n };\n for (const run of runs) {\n counts[run.outcome]++;\n }\n return t('checks-summary.label', {\n passed: counts.success + counts.neutral,\n failed: counts.failure,\n pending: counts.pending,\n skipped: counts.skipped,\n });\n }, [runs, t]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\n/** What the overview's details section shows, as a read-only form: one row per fact about the pull request. */\nexport const PullRequestDetailsSchema = Schema.Struct({\n reference: Schema.String.annotate({ title: 'Pull request' }),\n state: Schema.optional(Schema.String.annotate({ title: 'State' })),\n checks: Schema.optional(Schema.String.annotate({ title: 'Checks' })),\n branches: Schema.optional(Schema.String.annotate({ title: 'Branches' })),\n});\n\nexport type PullRequestDetailsValues = Schema.Schema.Type<typeof PullRequestDetailsSchema>;\n","//\n// Copyright 2026 DXOS.org\n//\n\n/** Public host of the `agent-artifacts` R2 bucket that demo videos and screenshots are linked from. */\nexport const ARTIFACTS_HOST = 'pub-39066a86073446d7b77b1c157b660bb5.r2.dev';\n\nexport type ArtifactKind = 'video' | 'image' | 'file';\n\n/** A file in the artifacts bucket that a pull request body links to. */\nexport type ArtifactLink = {\n url: string;\n kind: ArtifactKind;\n /** The file name, the last path segment. */\n name: string;\n /** The link's own text, when it was written as `[label](url)` rather than bare. */\n label?: string;\n};\n\n/** What a pull request body says beyond its prose: the footers the harness and CI append, and the media it links. */\nexport type PullRequestBody = {\n /** The prose, with the footers taken out. */\n markdown: string;\n /** Present when the body carries the Claude Code footer. */\n claudeCode?: {\n /** The session that wrote the pull request. */\n sessionUrl?: string;\n };\n /** The Composer deployment built from the pull request's head. */\n previewUrl?: string;\n /** Artifacts in first-mention order, each once. */\n artifacts: ArtifactLink[];\n};\n\nconst VIDEO_EXTENSIONS = ['webm', 'mp4', 'mov', 'm4v', 'ogv'];\nconst IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'avif'];\n\n/** The artifact a URL names, or undefined when it is not in the artifacts bucket. */\nexport const parseArtifactLink = (url: string): Omit<ArtifactLink, 'label'> | undefined => {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return undefined;\n }\n if (parsed.protocol !== 'https:' || parsed.hostname !== ARTIFACTS_HOST) {\n return undefined;\n }\n const segment = parsed.pathname.split('/').at(-1) ?? '';\n if (!segment) {\n return undefined;\n }\n const name = safeDecode(segment);\n const extension = name.split('.').at(-1)?.toLowerCase() ?? '';\n const kind: ArtifactKind = VIDEO_EXTENSIONS.includes(extension)\n ? 'video'\n : IMAGE_EXTENSIONS.includes(extension)\n ? 'image'\n : 'file';\n return { url, kind, name };\n};\n\nconst CLAUDE_SESSION = /https:\\/\\/claude\\.ai\\/code\\/session_[A-Za-z0-9]+/;\nconst PREVIEW_BLOCK = /<!--\\s*composer-preview:begin\\s*-->([\\s\\S]*?)<!--\\s*composer-preview:end\\s*-->/;\nconst PREVIEW_LINE = /^\\s*🚀\\s*Composer preview:\\s*(https?:\\/\\/\\S+)\\s*$/m;\n// Each footer line is removed whole; they are recognised by their text, not their position.\nconst FOOTER_LINES: RegExp[] = [\n /^\\s*🤖\\s*Generated with \\[?Claude Code\\]?(\\([^)]*\\))?\\s*$/,\n /^\\s*_?Generated by \\[Claude Code\\]\\([^)]*\\)_?\\s*$/,\n new RegExp(`^\\\\s*<?${CLAUDE_SESSION.source}>?\\\\s*$`),\n];\n// `[label](url)` first so a labelled link is not also counted bare.\nconst MARKDOWN_LINK = /!?\\[([^\\]]*)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g;\nconst BARE_URL = /https?:\\/\\/[^\\s)<>\\]|]+/g;\n\n/**\n * Splits a pull request body into its prose and what the footers and links say.\n *\n * The footers are the harness's (`🤖 Generated with Claude Code` and the session URL) and CI's\n * (the Composer preview block); the article shows them as cards, so they are taken out of the prose\n * rather than rendered twice.\n */\nexport const parsePullRequestBody = (body: string | undefined): PullRequestBody => {\n let text = (body ?? '').replace(/\\r\\n/g, '\\n');\n\n const sessionUrl = text.match(CLAUDE_SESSION)?.[0];\n const hasClaudeFooter = FOOTER_LINES.slice(0, 2).some((pattern) =>\n text.split('\\n').some((line) => pattern.test(line)),\n );\n\n let previewUrl: string | undefined;\n const block = text.match(PREVIEW_BLOCK);\n if (block) {\n previewUrl = block[1].match(PREVIEW_LINE)?.[1];\n text = text.replace(PREVIEW_BLOCK, '');\n }\n const line = text.match(PREVIEW_LINE);\n if (line) {\n previewUrl ??= line[1];\n text = text.replace(PREVIEW_LINE, '');\n }\n\n const lines = text.split('\\n').filter((line) => !FOOTER_LINES.some((pattern) => pattern.test(line)));\n // The footers leave their `---` rules and blank lines behind at the end.\n while (lines.length > 0 && /^\\s*(---+|\\*\\*\\*+|___+)?\\s*$/.test(lines[lines.length - 1])) {\n lines.pop();\n }\n const markdown = lines.join('\\n').trim();\n\n return {\n markdown,\n ...(hasClaudeFooter || sessionUrl ? { claudeCode: sessionUrl ? { sessionUrl } : {} } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n artifacts: findArtifacts(markdown),\n };\n};\n\n/** Every artifact the prose links, in order of first mention. */\nconst findArtifacts = (markdown: string): ArtifactLink[] => {\n const found = new Map<string, ArtifactLink>();\n const add = (url: string, label?: string) => {\n const artifact = found.has(url) ? undefined : parseArtifactLink(url);\n if (artifact) {\n found.set(url, { ...artifact, ...(label && label !== url ? { label } : {}) });\n }\n };\n for (const [, label, url] of markdown.matchAll(MARKDOWN_LINK)) {\n add(url, label);\n }\n for (const [url] of markdown.replace(MARKDOWN_LINK, '').matchAll(BARE_URL)) {\n add(url);\n }\n\n // Order by where each first appears, since labelled links were collected before bare ones.\n return [...found.values()].sort((a, b) => markdown.indexOf(a.url) - markdown.indexOf(b.url));\n};\n\nconst safeDecode = (segment: string): string => {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { Masonry } from '@dxos/react-ui-masonry';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Card from '@dxos/react-ui/Card';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\n\nimport { meta } from '#meta';\n\nimport { type ArtifactLink, type PullRequestBody } from '../../pull-request-body.ts';\nimport { ArtifactMedia, artifactIcon } from './ArtifactPill.tsx';\n\n/** One tile of the related grid: a demo artifact, or a link out of the pull request. */\nexport type RelatedItem =\n | { kind: 'artifact'; id: string; artifact: ArtifactLink }\n | { kind: 'link'; id: string; icon: string; iconClassNames?: string; title: string; href?: string; detail?: string };\n\nexport type RelatedCardsProps = Pick<PullRequestBody, 'artifacts' | 'claudeCode' | 'previewUrl'>;\n\n/** What {@link RelatedCards} would show; empty when the pull request links to nothing beyond its diff. */\nexport const useRelatedItems = ({ artifacts, claudeCode, previewUrl }: RelatedCardsProps): RelatedItem[] => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return useMemo(() => {\n const items: RelatedItem[] = artifacts.map((artifact) => ({ kind: 'artifact', id: artifact.url, artifact }));\n if (previewUrl) {\n items.push({\n kind: 'link',\n id: 'preview',\n icon: 'ph--rocket-launch--regular',\n iconClassNames: 'text-success-text',\n title: t('preview-deployment.label'),\n href: previewUrl,\n detail: hostOf(previewUrl),\n });\n }\n if (claudeCode) {\n items.push({\n kind: 'link',\n id: 'claude',\n icon: 'px--anthropic--regular',\n iconClassNames: 'text-warning-text',\n title: claudeCode.sessionUrl ? t('claude-session.label') : t('claude-generated.label'),\n href: claudeCode.sessionUrl,\n detail: claudeCode.sessionUrl?.split('/').at(-1),\n });\n }\n return items;\n }, [artifacts, claudeCode, previewUrl, t]);\n};\n\n/**\n * What the pull request points at beyond its diff, one card each — its demo media, the preview\n * deployment built from it, and the session that wrote it — in the masonry grid related objects\n * use everywhere else. Renders inside its host's scroller rather than owning one.\n */\nexport const RelatedCards = ({ items }: { items: readonly RelatedItem[] }) => (\n <Masonry.Root Tile={RelatedCard} centered={false}>\n <Masonry.Viewport items={items} getId={(item: RelatedItem) => item.id} scroll={false} />\n </Masonry.Root>\n);\n\nconst RelatedCard = ({ data: item }: { data: RelatedItem }) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n if (item.kind === 'link') {\n return (\n <Card.Root data-testid={`pull-request.related.${item.id}`}>\n <CardHeading icon={item.icon} iconClassNames={item.iconClassNames} title={item.title} href={item.href} />\n {item.detail && (\n <Card.Row>\n <Card.Text variant='muted' truncate>\n {item.detail}\n </Card.Text>\n </Card.Row>\n )}\n </Card.Root>\n );\n }\n\n const { artifact } = item;\n return (\n <Card.Root data-testid='pull-request.related.artifact'>\n <CardHeading\n icon={artifactIcon[artifact.kind]}\n title={artifact.label ?? t(`artifact-${artifact.kind}.label`)}\n href={artifact.url}\n />\n <Card.Row>\n <Card.Text variant='muted' truncate>\n {artifact.name}\n </Card.Text>\n </Card.Row>\n {artifact.kind !== 'file' && (\n <Card.Body>\n {/* `col-span-3` spans the card's gutters, as `Card.Poster` does; the body is `display: contents`. */}\n <ArtifactMedia artifact={artifact} classNames='col-span-3 aspect-video max-h-[200px] object-cover' />\n </Card.Body>\n )}\n </Card.Root>\n );\n};\n\nconst CardHeading = ({\n icon,\n iconClassNames,\n title,\n href,\n}: {\n icon: string;\n iconClassNames?: string;\n title: string;\n href?: string;\n}) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Card.Header>\n <Layout.Block>\n <Icon.Icon icon={icon} classNames={iconClassNames} />\n </Layout.Block>\n <Card.Title>{title}</Card.Title>\n {href && (\n <Layout.Block rail='end'>\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--arrow-square-out--regular'\n label={t('open-link.label')}\n onClick={() => window.open(href, '_blank', 'noopener,noreferrer')}\n />\n </Layout.Block>\n )}\n </Card.Header>\n );\n};\n\nconst hostOf = (url: string): string => {\n try {\n return new URL(url).host;\n } catch {\n return url;\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { DxAnchor } from '@dxos/lit-ui/react';\nimport * as PreviewCapabilities from '@dxos/plugin-preview/PreviewCapabilities';\nimport { Form } from '@dxos/react-ui-form';\nimport { MarkdownLink, MarkdownView, type MarkdownViewProps } from '@dxos/react-ui-markdown';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Status from '@dxos/react-ui/Status';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nimport { parseArtifactLink, parsePullRequestBody } from '../../pull-request-body.ts';\nimport { ArtifactPill } from './ArtifactPill.tsx';\nimport { CheckRunList, useCheckSummary } from './CheckRunList.tsx';\nimport { PullRequestDetailsSchema, type PullRequestDetailsValues } from './PullRequestDetails.tsx';\nimport { RelatedCards, useRelatedItems } from './RelatedCards.tsx';\n\nexport type PullRequestOverviewProps = {\n /** The pull request's description as written on GitHub, footers included. */\n body?: string;\n details: PullRequestDetailsValues;\n /** Undefined while the status is loading. */\n runs?: readonly GitHubOperation.CheckRun[];\n};\n\n/**\n * A pull request as its author presented it: the description, the facts about it, what it links to\n * beyond the diff, and every check on its head commit.\n */\nexport const PullRequestOverview = ({ body, details, runs }: PullRequestOverviewProps) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const parsed = useMemo(() => parsePullRequestBody(body), [body]);\n const components = useBodyComponents();\n const related = useRelatedItems(parsed);\n const checkSummary = useCheckSummary(runs);\n\n // One form hosts the whole tab, so the description and every section share its viewport's column\n // rather than each nesting a gutter of its own.\n return (\n <Form.Root schema={PullRequestDetailsSchema} values={details} layout='static' readonly>\n <Form.Viewport scroll width='document'>\n <Form.Content>\n {parsed.markdown ? (\n <MarkdownView content={parsed.markdown} components={components} data-testid='pull-request.body' />\n ) : (\n <Status.Empty>{t('no-description.message')}</Status.Empty>\n )}\n <Form.FieldSet label={t('details.label')} data-testid='pull-request.details'>\n <Form.Fields />\n </Form.FieldSet>\n {related.length > 0 && (\n <Form.FieldSet label={t('related.label')}>\n <RelatedCards items={related} />\n </Form.FieldSet>\n )}\n <Form.FieldSet label={checkSummary}>\n <CheckRunList runs={runs} />\n </Form.FieldSet>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\n/**\n * Links in the body as pills: an artifact previews its media in place, and a link a preview\n * resolver answers (another pull request, an issue) becomes the anchor chip the editor makes of it.\n */\nconst useBodyComponents = (): MarkdownViewProps['components'] => {\n const resolvers = Hooks.useCapabilities(PreviewCapabilities.LinkResolver);\n return useMemo(\n () => ({\n a: ({ children, href, node: _node, ...props }) => {\n const artifact = href ? parseArtifactLink(href) : undefined;\n if (artifact) {\n return <ArtifactPill artifact={artifact}>{children}</ArtifactPill>;\n }\n const all = resolvers.flat();\n if (!href || !PreviewCapabilities.isPreviewLink(all, href)) {\n return (\n <MarkdownLink href={href} {...props}>\n {children}\n </MarkdownLink>\n );\n }\n const icon = PreviewCapabilities.linkIcon(all, href);\n return (\n <DxAnchor eid={href} className='dx-tag-anchor'>\n {icon && (\n <Icon.Icon\n icon={icon.icon}\n size='md'\n classNames={['inline-block align-[-0.125em] me-1', icon.classNames]}\n />\n )}\n {children === href ? (PreviewCapabilities.linkLabel(all, href) ?? children) : children}\n </DxAnchor>\n );\n },\n }),\n [resolvers],\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport { type PullRequest } from '@dxos/types';\n\nimport { meta } from '#meta';\nimport { type GitHubOperation } from '#types';\n\nconst stateHue: Record<PullRequest.State, string> = {\n open: 'green',\n closed: 'red',\n merged: 'purple',\n draft: 'neutral',\n};\n\nconst reviewHue: Record<GitHubOperation.ReviewState, string> = {\n approved: 'green',\n changes_requested: 'red',\n none: 'neutral',\n};\n\nconst ciHue: Record<GitHubOperation.CiState, string> = {\n success: 'green',\n failure: 'red',\n pending: 'amber',\n none: 'neutral',\n};\n\nexport type PullRequestStatusProps = {\n reference: string;\n title?: string;\n state?: PullRequest.State;\n /** Absent until the live status has arrived; the review and CI tags read as unknown until then. */\n review?: { state: GitHubOperation.ReviewState; approvals: number };\n ci?: { state: GitHubOperation.CiState; checks: GitHubOperation.CheckCounts };\n};\n\n/** One line answering where the pull request stands: open or merged, approved or not, CI green or red. */\nexport const PullRequestStatus = ({ reference, title, state, review, ci }: PullRequestStatusProps) => {\n const { t } = Hooks.useTranslation(meta.profile.key);\n return (\n <Layout.Flex\n align='center'\n gap='sm'\n role='status'\n classNames='px-3 py-1.5 border-b border-separator-subtle text-sm min-w-0'\n data-testid='pull-request.status'\n >\n <span className='dx-tag dx-tag-inline shrink-0' data-hue='neutral'>\n {reference}\n </span>\n {title && <span className='truncate grow'>{title}</span>}\n <Layout.Flex align='center' gap='sm' classNames='shrink-0 ml-auto'>\n {state && (\n <span className='dx-tag dx-tag-inline' data-hue={stateHue[state]} data-testid='pull-request.status.state'>\n {t(`pull-request-state.${state}.label`)}\n </span>\n )}\n <span\n className='dx-tag dx-tag-inline'\n data-hue={review ? reviewHue[review.state] : 'neutral'}\n data-testid='pull-request.status.review'\n >\n {review\n ? t(`review-status.${review.state}.label`, { count: review.approvals })\n : t('review-status.unknown.label')}\n </span>\n <span\n className='dx-tag dx-tag-inline'\n data-hue={ci ? ciHue[ci.state] : 'neutral'}\n data-testid='pull-request.status.ci'\n >\n {ci ? t(`ci-status.${ci.state}.label`) : t('ci-status.unknown.label')}\n {ci && ci.checks.total > 0 && ` ${ci.checks.passed}/${ci.checks.total}`}\n </span>\n </Layout.Flex>\n </Layout.Flex>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { GitHubApi } from '../../services/index.ts';\n\n/**\n * Names a pull-request action's failure so the user knows what to do about it.\n *\n * A rejected credential is the one failure the user can fix themselves, and it is indistinguishable\n * from any other error once it reaches the toast as `error.message` — GitHub answers it as a bare\n * `401`, which surfaces as `StatusCode: non 2xx status code (401 GET …)`. Matches the same\n * distinction `ImportPullRequestDialog` already draws on `tokenStatus`.\n */\nexport const pullRequestFailureKey = (error: unknown, fallbackKey: string): string =>\n GitHubApi.responseStatus(error) === 401 ? 'github-token-rejected.title' : fallbackKey;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport type * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as ToolkitHooks from '@dxos/app-toolkit/Hooks';\nimport * as LayoutOperation from '@dxos/app-toolkit/LayoutOperation';\nimport { Database, Filter, Obj, Ref } from '@dxos/echo';\nimport { useObject, useQuery } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport * as Binding from '@dxos/plugin-connector/Binding';\nimport { ProgressMeter } from '@dxos/react-ui-components';\nimport { ActionToolbar, MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as Tabs from '@dxos/react-ui/Tabs';\nimport { PullRequest } from '@dxos/types';\nimport { type DiffLineTarget } from '@dxos/ui-editor';\n\nimport { meta } from '#meta';\nimport { GitHubOperation, Walkthrough } from '#types';\n\nimport {\n CommentBand,\n LineCommentPopover,\n type PullRequestDetailsValues,\n PullRequestFiles,\n PullRequestOverview,\n PullRequestStatus,\n WalkthroughPlaceholder,\n WalkthroughView,\n} from '../../components/index.ts';\nimport { usePullRequestDiff, usePullRequestFiles, useSyncPullRequest } from '../../hooks/index.ts';\nimport { githubConnection } from '../../operations/pull-request.ts';\nimport { newestWalkthrough } from '../../walkthrough/index.ts';\nimport { pullRequestFailureKey } from './failure.ts';\n\nconst ciLabel: Record<GitHubOperation.CiState, string> = {\n success: 'ci-status.success.label',\n failure: 'ci-status.failure.label',\n pending: 'ci-status.pending.label',\n none: 'ci-status.none.label',\n};\n\ntype Status = {\n state: PullRequest.State;\n body?: string;\n ci: GitHubOperation.CiState;\n checks: GitHubOperation.CheckCounts;\n runs: readonly GitHubOperation.CheckRun[];\n review: GitHubOperation.ReviewState;\n approvals: number;\n};\n\ntype Tab = 'overview' | 'walkthrough' | 'files';\n\nconst TABS: readonly Tab[] = ['overview', 'walkthrough', 'files'];\n\nexport type PullRequestArticleProps = AppSurface.ObjectArticleProps<PullRequest.PullRequest>;\n\n/**\n * A pull request read as a review: its number, state and CI outcome above whatever narration the\n * space holds, with approving and commenting one click away. Everything GitHub-side goes through\n * the space's GitHub connection.\n *\n * The pull request is the subject rather than the walkthrough because one exists before the other\n * does: a pull request just imported has no narration yet, and generating it is an action ON the\n * pull request, not a different object to open.\n */\nexport const PullRequestArticle = ({ role, attendableId, subject: pullRequest }: PullRequestArticleProps) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const { invokePromise } = Hooks.useOperationInvoker();\n const [subject] = useObject(pullRequest);\n const db = Obj.getDatabase(pullRequest);\n const spaceId = db?.spaceId;\n\n const walkthroughs = useQuery(db, Filter.type(Walkthrough.Walkthrough, { pullRequest: Ref.make(pullRequest) }));\n const walkthrough = useMemo(() => newestWalkthrough(walkthroughs), [walkthroughs]);\n // Watched by key rather than tied to `generating`, so a run started elsewhere shows here too.\n const walkthroughProgress = ToolkitHooks.useProgressMonitor(\n GitHubOperation.createWalkthroughProgressKey(pullRequest),\n );\n // Present only when plugin-progress is loaded; it is what lets the meter cancel or dismiss a run.\n const progressRegistry = Hooks.useOptionalCapability(AppCapabilities.ProgressRegistry);\n\n const [status, setStatus] = useState<Status>();\n // The live state where it has arrived, the stored one until then — an absent status is unknown,\n // not \"open\", and GitHub accepts an approval on a merged pull request rather than rejecting it.\n const state = status?.state ?? subject.state;\n const [tab, setTab] = useState<Tab>('overview');\n const [busy, setBusy] = useState(false);\n const [generating, setGenerating] = useState(false);\n const [composing, setComposing] = useState(false);\n const [comment, setComment] = useState('');\n // Set when the composer was opened from a diff line; the comment then goes on that line.\n const [lineTarget, setLineTarget] = useState<{ target: DiffLineTarget; commit: string }>();\n // The diff line's own button, which the composer is positioned at: the anchor is a DOM node\n // CodeMirror owns, so it is held in a ref rather than state and never re-renders the article.\n const lineAnchorRef = useRef<HTMLElement | null>(null);\n\n const openLineComment = useCallback((target: DiffLineTarget, anchor: HTMLElement, commit: string) => {\n lineAnchorRef.current = anchor;\n // The commit travels with the target: a regeneration or push between opening the composer and\n // posting would otherwise pair the NEW commit with line numbers read from the old diff, which\n // GitHub either rejects or anchors to the wrong line.\n setLineTarget({ target, commit });\n setComposing(true);\n }, []);\n\n const handleWalkthroughLineComment = useCallback(\n (target: DiffLineTarget, anchor: HTMLElement) => walkthrough && openLineComment(target, anchor, walkthrough.commit),\n [walkthrough, openLineComment],\n );\n\n /** The toolbar's composer is about the pull request, so it drops whatever line was targeted. */\n const handleToggleComposer = useCallback(() => {\n setLineTarget(undefined);\n lineAnchorRef.current = null;\n setComposing((value) => value === false || lineTarget !== undefined);\n }, [lineTarget]);\n\n const handleCloseComposer = useCallback(() => {\n setComposing(false);\n setLineTarget(undefined);\n lineAnchorRef.current = null;\n }, []);\n\n const pullRequestRef = useMemo(() => Ref.make(pullRequest), [pullRequest]);\n const reference = PullRequest.reference(pullRequest);\n\n // The diff is only read once the files tab is first opened: most visits never look at it.\n const diff = usePullRequestDiff(pullRequestRef, spaceId, tab === 'files');\n const files = usePullRequestFiles(diff.diff, `${meta.profile.key}.reviewed.${reference}`);\n const { file, step, setReviewed } = files;\n\n const handleFilesLineComment = useCallback(\n (target: DiffLineTarget, anchor: HTMLElement) => diff.commit && openLineComment(target, anchor, diff.commit),\n [diff.commit, openLineComment],\n );\n\n /** Checking a file off moves on to the next one, the way a reader works down the list. */\n const handleToggleReviewed = useCallback(() => {\n if (!file) {\n return;\n }\n const reviewed = !files.reviewed.has(file.path);\n setReviewed(file.path, reviewed);\n if (reviewed) {\n step(1);\n }\n }, [file, files.reviewed, setReviewed, step]);\n\n const refreshStatus = useCallback(async () => {\n const { data, error } = await invokePromise(\n GitHubOperation.GetPullRequestStatus,\n { pullRequest: pullRequestRef },\n { spaceId },\n );\n if (error) {\n log.warn('pull request status failed', { error });\n return;\n }\n if (data) {\n setStatus({\n state: data.state,\n body: data.body,\n ci: data.ci,\n checks: data.checks,\n runs: data.runs,\n review: data.review,\n approvals: data.approvals,\n });\n }\n }, [invokePromise, pullRequestRef, spaceId]);\n\n useEffect(() => {\n void refreshStatus();\n }, [refreshStatus]);\n\n useSyncPullRequest(pullRequest);\n\n const toast = useCallback(\n (id: string, title: string, success: boolean, description?: string) =>\n invokePromise(LayoutOperation.AddToast, {\n id: `${meta.profile.key}.${id}`,\n icon: success ? 'ph--check-circle--regular' : 'ph--warning--regular',\n title: [title, { ns: meta.profile.key }],\n ...(description ? { description } : {}),\n }),\n [invokePromise],\n );\n\n /**\n * A rejected credential is the one failure the user can fix, so it names the fix and links to the\n * connection; any other failure shows the raw error under the action's own title.\n */\n const failureToast = useCallback(\n async (id: string, fallbackKey: string, error: Error) => {\n const key = pullRequestFailureKey(error, fallbackKey);\n if (key === fallbackKey || !db) {\n return toast(id, key, false, error.message);\n }\n\n const connection = (\n await EffectEx.runPromise(\n githubConnection().pipe(\n Effect.provide(Database.layer(db)),\n Effect.orElseSucceed(() => undefined),\n ),\n )\n )?.connection;\n return invokePromise(LayoutOperation.AddToast, {\n id: `${meta.profile.key}.${id}`,\n icon: 'ph--warning--regular',\n title: [key, { ns: meta.profile.key }],\n ...(connection\n ? {\n actionLabel: ['open-github-connection.label', { ns: meta.profile.key }],\n actionAlt: ['open-github-connection.label', { ns: meta.profile.key }],\n onAction: () =>\n void invokePromise(LayoutOperation.Open, {\n subject: [Binding.connectionSubject(db.spaceId, connection.id)],\n navigation: 'immediate',\n }),\n }\n : {}),\n });\n },\n [db, invokePromise, toast],\n );\n\n const handleApprove = useCallback(async () => {\n setBusy(true);\n const { data, error } = await invokePromise(\n GitHubOperation.SubmitPullRequestApproval,\n { pullRequest: pullRequestRef },\n { spaceId },\n );\n setBusy(false);\n if (error) {\n log.warn('approve failed', { error });\n await failureToast('approve', 'approve-pull-request-error.title', error);\n return;\n }\n await toast(\n 'approve',\n data?.commented ? 'approve-pull-request-commented.title' : 'approve-pull-request-success.title',\n true,\n );\n void refreshStatus();\n }, [invokePromise, pullRequestRef, spaceId, toast, failureToast, refreshStatus]);\n\n /** `force` is what makes the toolbar's entry a REgeneration: the same head would otherwise no-op. */\n const handleGenerate = useCallback(async () => {\n setTab('walkthrough');\n setGenerating(true);\n const { error } = await invokePromise(\n GitHubOperation.GenerateWalkthrough,\n { pullRequest: pullRequestRef, force: walkthrough !== undefined },\n { spaceId },\n );\n\n setGenerating(false);\n if (error) {\n log.warn('walkthrough generation failed', { error });\n await failureToast('walkthrough', 'walkthrough-failed.title', error);\n return;\n }\n await toast('walkthrough', 'walkthrough-ready.title', true);\n }, [invokePromise, pullRequestRef, spaceId, walkthrough, toast, failureToast]);\n\n const handleCopyLink = useCallback(async () => {\n if (!subject.url) {\n return;\n }\n\n try {\n await navigator.clipboard.writeText(subject.url);\n } catch (error) {\n // Denied permission, or a document that is not focused; either way the link is not on the\n // clipboard and the success toast would be a lie.\n log.warn('copy link failed', { error });\n await toast('copy-link', 'copy-link-error.title', false);\n return;\n }\n await toast('copy-link', 'copy-link-success.title', true);\n }, [subject.url, toast]);\n\n const handleComment = useCallback(async () => {\n const text = comment.trim();\n if (!text) {\n return;\n }\n setBusy(true);\n const { error } = lineTarget\n ? await invokePromise(\n GitHubOperation.AddPullRequestReviewComment,\n {\n pullRequest: pullRequestRef,\n body: text,\n commit: lineTarget.commit,\n path: lineTarget.target.file,\n line: lineTarget.target.line,\n side: lineTarget.target.side === 'before' ? ('LEFT' as const) : ('RIGHT' as const),\n },\n { spaceId },\n )\n : await invokePromise(\n GitHubOperation.AddPullRequestComment,\n { pullRequest: pullRequestRef, body: text },\n { spaceId },\n );\n setBusy(false);\n if (error) {\n log.warn('comment failed', { error });\n await failureToast('comment', 'comment-error.title', error);\n return;\n }\n setComment('');\n handleCloseComposer();\n await toast('comment', 'comment-success.title', true);\n }, [comment, lineTarget, invokePromise, pullRequestRef, spaceId, toast, failureToast, handleCloseComposer]);\n\n // The tablist only needs the `Tabs.Root` context, which wraps the whole panel.\n const tabs = useMemo(\n () => (\n <Tabs.List>\n {TABS.map((value) => (\n <Tabs.Trigger key={value} value={value} data-testid={`pull-request.tab.${value}`}>\n {t(`${value}-tab.label`)}\n </Tabs.Trigger>\n ))}\n </Tabs.List>\n ),\n [t],\n );\n\n const fileReviewed = file !== undefined && files.reviewed.has(file.path);\n const menuActions = useMenuBuilder(() => {\n const builder = MenuBuilder.make()\n .action(\n 'tabs',\n {\n variant: 'custom',\n label: ['views.label', { ns: meta.profile.key }],\n render: () => tabs,\n },\n () => {},\n )\n // The one growing gap: everything after it sits at the trailing edge.\n .separator();\n\n if (tab === 'files') {\n builder\n .action(\n 'previousFile',\n {\n label: ['previous-file.label', { ns: meta.profile.key }],\n icon: 'ph--caret-up--regular',\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.previous-file',\n },\n () => step(-1),\n )\n .action(\n 'nextFile',\n {\n label: ['next-file.label', { ns: meta.profile.key }],\n icon: 'ph--caret-down--regular',\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.next-file',\n },\n () => step(1),\n )\n .action(\n 'reviewed',\n {\n label: ['file-reviewed.label', { ns: meta.profile.key }],\n icon: fileReviewed ? 'ph--check-square--fill' : 'ph--square--regular',\n iconOnly: false,\n disabled: !file,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.reviewed',\n },\n () => handleToggleReviewed(),\n )\n .separator('line');\n }\n\n return builder\n .action(\n 'approve',\n {\n label: ['approve-pull-request.label', { ns: meta.profile.key }],\n icon: 'ph--check-circle--regular',\n variant: 'primary',\n iconOnly: false,\n disabled: busy || state === 'merged' || state === 'closed',\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.approve',\n },\n () => void handleApprove(),\n )\n .action(\n 'comment',\n {\n label: ['comment-pull-request.label', { ns: meta.profile.key }],\n icon: 'ph--chat-text--regular',\n disabled: busy,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.comment',\n },\n () => handleToggleComposer(),\n )\n .separator('line')\n .action(\n 'generateWalkthrough',\n {\n label: [\n walkthrough ? 'regenerate-walkthrough.label' : 'generate-walkthrough.label',\n { ns: meta.profile.key },\n ],\n icon: 'ph--path--regular',\n disabled: generating,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.generate-walkthrough',\n },\n () => void handleGenerate(),\n )\n .action(\n 'openOnGitHub',\n {\n label: ['open-on-github.label', { ns: meta.profile.key }],\n icon: 'ph--arrow-square-out--regular',\n disabled: !subject.url,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.open-on-github',\n },\n () => subject.url && window.open(subject.url, '_blank', 'noopener,noreferrer'),\n )\n .action(\n 'copyLink',\n {\n label: ['copy-link.label', { ns: meta.profile.key }],\n icon: 'ph--link--regular',\n disabled: !subject.url,\n disposition: 'toolbar',\n testId: 'pull-request.toolbar.copy-link',\n },\n () => void handleCopyLink(),\n )\n .build();\n }, [\n tabs,\n tab,\n file,\n fileReviewed,\n step,\n handleToggleReviewed,\n busy,\n generating,\n walkthrough,\n subject.url,\n state,\n handleApprove,\n handleGenerate,\n handleCopyLink,\n handleToggleComposer,\n ]);\n\n const details = useMemo<PullRequestDetailsValues>(\n () => ({\n reference,\n state,\n checks: status\n ? `${t(ciLabel[status.ci])}${status.checks.total > 0 ? ` ${status.checks.passed}/${status.checks.total}` : ''}`\n : t('ci-status.unknown.label'),\n branches:\n subject.headBranch &&\n (subject.baseBranch ? `${subject.headBranch} → ${subject.baseBranch}` : subject.headBranch),\n }),\n [reference, state, status, subject.headBranch, subject.baseBranch, t],\n );\n\n const composerProps = {\n value: comment,\n busy,\n onValueChange: setComment,\n onSubmit: () => void handleComment(),\n onCancel: handleCloseComposer,\n };\n\n return (\n <Tabs.Root\n asChild\n orientation='horizontal'\n value={tab}\n onValueChange={(value) => setTab(TABS.find((candidate) => candidate === value) ?? 'overview')}\n >\n <Panel.Root role={role}>\n <Panel.Header>\n {/* `alwaysActive`: the tablist is navigation, not an attention-gated action, and a disabled\n Next toolbar disables every item in it. */}\n <ActionToolbar {...menuActions} attendableId={attendableId} alwaysActive />\n </Panel.Header>\n <Panel.Body asChild>\n <Layout.Flex column>\n <PullRequestStatus\n reference={reference}\n title={subject.title}\n state={state}\n review={status && { state: status.review, approvals: status.approvals }}\n ci={status && { state: status.ci, checks: status.checks }}\n />\n {composing && !lineTarget && <CommentBand {...composerProps} />}\n <LineCommentPopover\n {...composerProps}\n open={composing && !!lineTarget}\n anchorRef={lineAnchorRef}\n target={lineTarget?.target}\n />\n {/* Rendered by hand rather than through `Tabs.Panel`, so each tab's editor exists only while\n the tab is shown and is built against a visible, measured element. */}\n {tab === 'overview' && (\n <PullRequestOverview body={status?.body ?? subject.description} details={details} runs={status?.runs} />\n )}\n {tab === 'walkthrough' &&\n (walkthrough ? (\n <WalkthroughView value={walkthrough.body} sidebar='full' onLineComment={handleWalkthroughLineComment} />\n ) : (\n <WalkthroughPlaceholder generating={generating} onGenerate={() => void handleGenerate()} />\n ))}\n {tab === 'files' && (\n <PullRequestFiles\n tree={files.tree}\n file={file}\n reviewed={files.reviewed}\n total={files.files.length}\n error={diff.error && t('files-error.message')}\n onSelect={files.select}\n onReviewedChange={setReviewed}\n onLineComment={diff.commit ? handleFilesLineComment : undefined}\n />\n )}\n </Layout.Flex>\n </Panel.Body>\n <Panel.Footer classNames='border-t border-separator-subtle'>\n <ProgressMeter\n state={\n walkthroughProgress?.status === 'running' || walkthroughProgress?.status === 'error'\n ? walkthroughProgress\n : undefined\n }\n onCancel={\n progressRegistry && walkthroughProgress\n ? () => progressRegistry.cancel(walkthroughProgress.name)\n : undefined\n }\n />\n </Panel.Footer>\n </Panel.Root>\n </Tabs.Root>\n );\n};\n"],"mappings":"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"}
|