@agimon-ai/po-git 0.0.0-alpha.37 → 0.0.0-alpha.39

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.
@@ -1,7 +1,7 @@
1
1
  import { createApiClient, defineActivityGroup, defineChannelFile, defineFill, defineGlobalStore, defineLeaderBinding, defineRepositorySettingsPanel, defineSessionStore, defineToolRenderer, defineWebLifecycle, defineWebPlugin, sessionApiAddress } from "@agimon-ai/po-core/web";
2
2
  import { ArrowRightIcon, BranchIcon, Button, CheckIcon, ChevronDownIcon, ChevronUpIcon, Dialog, DialogContent, DialogTitle, DiffView, Dot, DropdownMenuItem, EmptyState, Input, MessageIcon, MessageItem, MessageItemBody, ReviewCommentDraft, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SettingsActions, SettingsCard, SettingsNote, SettingsRow, SettingsRowDescription, SettingsRowText, SettingsRowTitle, SettingsSection, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle, ShieldIcon, Spinner, StatusBadge, Tabs, TabsContent, TabsList, TabsTrigger, buildReviewPrompt } from "@agimon-ai/po-web-components";
3
3
  import { createElement, useCallback, useEffect, useId, useRef, useState } from "react";
4
- import { sealedTransport } from "@agimon-ai/po-web-security/browser";
4
+ import { browserTransport } from "@agimon-ai/po-web-security/browser";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useStore } from "@tanstack/react-store";
7
7
  const api = createApiClient({
@@ -51,7 +51,7 @@ const api = createApiClient({
51
51
  "session"
52
52
  ],
53
53
  basePath: "git",
54
- transport: (input, init) => sealedTransport.fetch(input, init),
54
+ transport: (input, init) => browserTransport.fetch(input, init),
55
55
  sessionAddress: sessionApiAddress
56
56
  });
57
57
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"web.mjs","names":["formProblem","Field","formProblem","errorOf","loaded","isRecord","optionalText","optionalErrorTarget","isRecord","contribution","fillGitNewSession","repositorySettingsPanelGit","activityGroupGit","channelGitChanges","channelGitWorktrees","fillWorktree","fillWorktreeCreate","fillWorktrees","leaderReview","lifecycleStart","toolRunWorktree"],"sources":["../../src/types/apiRoutes.ts","../../generated/client.ts","../../src/extensions/workspaces/(frontend)/_lib/newSessionForm.ts","../../src/extensions/workspaces/(frontend)/fill/_components/GitNewSessionDialog.tsx","../../src/extensions/workspaces/(frontend)/fill/GitNewSession.new-session.web.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_lib/gitAuthForm.ts","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_components/GitAuthForm.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_components/GitAuthPanel.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/git.web.tsx","../../src/types/webWorktrees.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/worktreesActivityStore.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreeCreateDialog.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/WorktreesPanel.tsx","../../src/types/gitReview.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitChangesStore.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitChanges.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewApi.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewStore.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewView.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewBrowser.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitSyncBar.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewView.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewPanel.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/DiffActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreesActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/leader/review.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/RunWorktreeToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web.tsx","../../generated/web.ts"],"sourcesContent":["import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { GitAuthView } from './gitAuth';\nimport type { GitReviewFileDiff, GitReviewSummary } from './gitReview';\nimport type { GitBranchesResponse, GitSessionCreated } from './gitSessions';\n\n/**\n * The routes the page calls, as data.\n *\n * No scope and no base path: the build reads both off\n * `src/extensions/(backend)/api/git/`, which mounts at global scope and so\n * answers workspace and session requests too. Each route answers only where it\n * belongs (auth on a workspace mount, the review on a session mount), so a\n * client accessor on the wrong scope gets a 404 rather than a second way in.\n *\n * Only what the browser calls is listed. The worktree routes stay HTTP for\n * other callers, but the dock drives worktrees over its channel.\n */\nconst routes = {\n /** Workspace: the new-session dialog's branch list. */\n branches: {\n method: 'GET',\n path: '/branches',\n response: undefined as unknown as ApiResponseOf<GitBranchesResponse>,\n },\n /** Workspace: a top-level worktree session on an existing or new branch. */\n createSession: {\n method: 'POST',\n path: '/sessions',\n response: undefined as unknown as ApiResponseOf<GitSessionCreated>,\n },\n /** Workspace: that workspace's saved remote auth, never the token itself. */\n auth: {\n method: 'GET',\n path: '/auth',\n query: ['repositoryId'],\n response: undefined as unknown as ApiResponseOf<GitAuthView>,\n },\n /** Workspace: replaces that workspace's remote auth. Passkey step-up gated for remote devices. */\n saveAuth: {\n method: 'PUT',\n path: '/auth',\n query: ['repositoryId'],\n response: undefined as unknown as ApiResponseOf<GitAuthView>,\n },\n /** Session: the files this session's checkout changed against its base. */\n review: {\n method: 'GET',\n path: '/review',\n response: undefined as unknown as ApiResponseOf<GitReviewSummary>,\n },\n /** Session: one changed file's hunks. */\n reviewFile: {\n method: 'GET',\n path: '/review/file',\n query: ['path'],\n response: undefined as unknown as ApiResponseOf<GitReviewFileDiff>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, sessionApiAddress } from '@agimon-ai/po-core/web';\nimport { sealedTransport } from '@agimon-ai/po-web-security/browser';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'git' at. */\nexport const apiScopes = ['global', 'workspace', 'session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'git',\n transport: (input, init) => sealedTransport.fetch(input, init),\n sessionAddress: sessionApiAddress,\n});\n","import type { GitBranches, GitSessionCreateRequest } from '../../../../types/gitSessions';\n\nexport type NewSessionMode = 'existing' | 'new' | 'plain';\n\n/** One row of the branch picker: a local branch, or a remote-only one. */\nexport interface BranchOption {\n key: string;\n name: string;\n remote?: string;\n current: boolean;\n /** Set when the branch is checked out elsewhere and cannot get a second worktree. */\n busyAt?: string;\n}\n\nexport interface NewSessionFormState {\n mode: NewSessionMode;\n /** The picked existing branch. */\n selected?: BranchOption;\n newBranch: string;\n baseRef: string;\n name: string;\n}\n\nconst MAX_LISTED = 200;\n\n/** Local branches first, then remote-only ones, filtered by a case-insensitive substring. */\nexport function branchOptions(branches: GitBranches, query: string): BranchOption[] {\n const needle = query.trim().toLowerCase();\n const matches = (text: string): boolean => needle === '' || text.toLowerCase().includes(needle);\n const local = branches.local\n .filter((branch) => matches(branch.name))\n .map((branch) => ({\n key: `local:${branch.name}`,\n name: branch.name,\n current: branch.name === branches.current,\n ...(branch.checkedOutAt === undefined ? {} : { busyAt: branch.checkedOutAt }),\n }));\n const remote = branches.remote\n .filter((branch) => matches(`${branch.remote}/${branch.name}`))\n .map((branch) => ({\n key: `remote:${branch.remote}/${branch.name}`,\n name: branch.name,\n remote: branch.remote,\n current: false,\n }));\n return [...local, ...remote].slice(0, MAX_LISTED);\n}\n\n/** Every base a new branch can start from: the default first, then remote-tracking names, then local branches. */\nexport function baseOptions(branches: GitBranches): string[] {\n const names = new Set([\n ...(branches.defaultBase === undefined ? [] : [branches.defaultBase]),\n ...branches.remote.map((branch) => `${branch.remote}/${branch.name}`),\n ...branches.local.map((branch) => branch.name),\n ]);\n return [...names];\n}\n\n/** Why the form cannot be submitted yet, or undefined when it can. */\nexport function formProblem(state: NewSessionFormState): string | undefined {\n if (state.mode === 'existing') {\n if (state.selected === undefined) return 'Pick a branch.';\n if (state.selected.busyAt !== undefined) return `That branch is checked out at ${state.selected.busyAt}.`;\n }\n if (state.mode === 'new' && state.newBranch.trim() === '') return 'Name the new branch.';\n return undefined;\n}\n\n/** The worktree create request for the form, or undefined in plain mode. */\nexport function createRequest(state: NewSessionFormState): GitSessionCreateRequest | undefined {\n const name = state.name.trim();\n const named = name === '' ? {} : { name };\n if (state.mode === 'existing' && state.selected !== undefined)\n return {\n mode: 'existing-branch',\n branch: state.selected.name,\n ...(state.selected.remote === undefined ? {} : { remote: state.selected.remote }),\n ...named,\n };\n if (state.mode === 'new') {\n const baseRef = state.baseRef.trim();\n return {\n mode: 'new-branch',\n branch: state.newBranch.trim(),\n ...(baseRef === '' ? {} : { baseRef }),\n ...named,\n };\n }\n return undefined;\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport {\n Button,\n CheckIcon,\n Dialog,\n DialogContent,\n DialogTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { api } from '../../../../../../generated/client';\nimport type { GitBranchesResponse, GitSessionCreated } from '../../../../../types/gitSessions';\nimport {\n baseOptions,\n branchOptions,\n createRequest,\n formProblem,\n type NewSessionFormState,\n type NewSessionMode,\n} from '../../_lib/newSessionForm';\n\nfunction Field({ label, children }: { label: ReactNode; children: ReactNode }) {\n return (\n <label className=\"flex flex-col gap-2 text-base text-po-text\">\n <span>{label}</span>\n {children}\n </label>\n );\n}\n\nexport interface GitNewSessionDialogViewProps {\n workspaceRoot: string;\n branches: GitBranchesResponse | null;\n loadError?: string;\n initialForm?: Partial<NewSessionFormState>;\n busy?: boolean;\n error?: string;\n onClose: () => void;\n onCreate: (form: NewSessionFormState) => void;\n}\n\n/** Inline presentation also lets story capture inspect content, rather than a portal-only root. */\nexport function GitNewSessionDialogView({\n workspaceRoot,\n branches,\n loadError = '',\n initialForm,\n busy = false,\n error = '',\n onClose,\n onCreate,\n}: GitNewSessionDialogViewProps) {\n const [form, setForm] = useState<NewSessionFormState>({\n mode: 'existing',\n newBranch: '',\n baseRef: branches?.defaultBase ?? '',\n name: '',\n ...initialForm,\n });\n const [query, setQuery] = useState('');\n const ready = branches?.repository === true && loadError === '';\n const loading = branches === null && loadError === '';\n const mode = ready || loading ? form.mode : 'plain';\n const state = { ...form, mode, baseRef: form.baseRef || branches?.defaultBase || '' };\n const problem = formProblem(state);\n const update = (patch: Partial<NewSessionFormState>): void => setForm((current) => ({ ...current, ...patch }));\n const options = branches === null ? [] : branchOptions(branches, query);\n const bases = branches === null ? [] : baseOptions(branches);\n const submit = (): void => {\n if (!busy && !loading && problem === undefined) onCreate(state);\n };\n return (\n <section\n data-testid=\"new-session-dialog\"\n aria-label=\"New session\"\n className=\"shrink-0 overflow-hidden rounded-lg border border-po-border bg-po-panel shadow-sm\"\n >\n <header className=\"border-b border-po-border-soft px-6 py-4\">\n <h3 className=\"text-xl font-semibold text-po-hi\">New session</h3>\n <p className=\"mt-1 font-mono text-sm text-po-dim\">{workspaceRoot}</p>\n </header>\n <div className=\"flex flex-col gap-5 p-6\">\n {!ready ? (\n <p data-testid=\"git-new-session-plain-note\" className=\"text-base text-po-dim\">\n {loading\n ? 'Reading branches...'\n : loadError || 'This workspace is not a git checkout. Start a plain session in this folder.'}\n </p>\n ) : (\n <Tabs\n value={mode}\n onValueChange={(value) => update({ mode: value as NewSessionMode })}\n className=\"flex flex-col gap-5\"\n >\n <TabsList aria-label=\"Session kind\" className=\"rounded-md border border-po-border-soft bg-po-bg p-1\">\n <TabsTrigger\n data-testid=\"git-new-session-mode-existing\"\n value=\"existing\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n Existing branch\n </TabsTrigger>\n <TabsTrigger\n data-testid=\"git-new-session-mode-new\"\n value=\"new\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n New branch\n </TabsTrigger>\n <TabsTrigger\n data-testid=\"git-new-session-mode-plain\"\n value=\"plain\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n No branch\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"existing\" className=\"flex flex-col gap-2\">\n <p className=\"text-base font-medium\">Branch</p>\n <Input\n data-testid=\"git-new-session-branch-search\"\n aria-label=\"Find a branch\"\n placeholder=\"Find a branch\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n disabled={busy}\n />\n <fieldset\n aria-label=\"Branches\"\n className=\"max-h-64 min-w-0 overflow-y-auto rounded-md border border-po-border-soft bg-po-bg p-1\"\n >\n {options.length === 0 ? <p className=\"px-3 py-2 text-sm text-po-dim\">No matching branches</p> : null}\n {options.map((branch, index) => (\n <div key={branch.key}>\n {branch.remote !== undefined && (index === 0 || options[index - 1]?.remote === undefined) ? (\n <p className=\"mt-1 border-t border-po-border-soft px-3 pt-2 text-sm text-po-dim\">\n Remote branches\n </p>\n ) : null}\n <button\n data-testid=\"git-new-session-branch-option\"\n data-branch={branch.name}\n data-remote={branch.remote}\n aria-pressed={form.selected?.key === branch.key}\n disabled={branch.busyAt !== undefined || busy}\n onClick={() => update({ selected: branch })}\n className={`flex w-full flex-col gap-1 rounded px-3 py-2 text-left text-base ${form.selected?.key === branch.key ? 'bg-po-tint-green text-po-green' : 'text-po-text'}`}\n >\n <span className=\"flex items-center justify-between gap-2\">\n <span className=\"font-mono\">\n {branch.remote === undefined ? branch.name : `${branch.remote}/${branch.name}`}\n </span>\n {form.selected?.key === branch.key ? <CheckIcon className=\"size-4\" /> : null}\n </span>\n {branch.busyAt !== undefined ? (\n <span className=\"text-sm text-po-dim\">\n Checked out in <span className=\"font-mono break-all\">{branch.busyAt}</span>\n </span>\n ) : branch.current ? (\n <span className=\"text-sm text-po-dim\">Current</span>\n ) : null}\n </button>\n </div>\n ))}\n </fieldset>\n </TabsContent>\n <TabsContent value=\"new\" className=\"flex flex-col gap-4\">\n <Field label=\"Branch name\">\n <Input\n data-testid=\"git-new-session-new-branch\"\n aria-label=\"Branch name\"\n placeholder=\"feature/my-change\"\n className=\"font-mono\"\n value={form.newBranch}\n onChange={(event) => update({ newBranch: event.target.value })}\n disabled={busy}\n />\n </Field>\n <Field label=\"From\">\n <Select\n value={form.baseRef || branches?.defaultBase || ''}\n onValueChange={(baseRef) => update({ baseRef })}\n disabled={busy}\n >\n <SelectTrigger data-testid=\"git-new-session-base\" aria-label=\"From\" className=\"font-mono\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {bases.map((base) => (\n <SelectItem key={base} value={base}>\n {base}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </TabsContent>\n <TabsContent value=\"plain\">\n <p className=\"text-base text-po-dim\">Start in this workspace folder, without creating a worktree.</p>\n </TabsContent>\n </Tabs>\n )}\n <Field\n label={\n <>\n Name{' '}\n <span className=\"text-sm text-po-dim\">\n {mode === 'plain' ? '(optional)' : '(optional, defaults to the branch)'}\n </span>\n </>\n }\n >\n <Input\n data-testid=\"new-session-name\"\n aria-label=\"Session name\"\n placeholder=\"Session name\"\n value={form.name}\n onChange={(event) => update({ name: event.target.value })}\n onKeyDown={(event) => {\n if (event.key === 'Enter') submit();\n }}\n disabled={busy}\n />\n </Field>\n {mode !== 'plain' ? (\n <p className=\"text-sm leading-relaxed text-po-dim\">\n Runs in its own worktree, so this checkout stays as it is.\n </p>\n ) : null}\n {error ? (\n <p\n data-testid=\"new-session-error\"\n role=\"alert\"\n className=\"rounded-md border border-po-edge-red bg-po-tint-red p-3 text-sm text-po-red\"\n >\n {error}\n </p>\n ) : null}\n </div>\n <footer className=\"flex items-center justify-between border-t border-po-border-soft px-6 py-4\">\n <Button data-testid=\"new-session-cancel\" variant=\"ghost\" disabled={busy} onClick={onClose}>\n Cancel\n </Button>\n <Button\n data-testid=\"new-session-create\"\n variant=\"primary\"\n title={problem}\n disabled={busy || loading || problem !== undefined}\n onClick={submit}\n >\n {busy ? (mode === 'plain' ? 'Creating session...' : 'Creating worktree...') : 'Create session'}\n </Button>\n </footer>\n </section>\n );\n}\n\nfunction errorOf(body: unknown, status: number): string {\n return typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : `The cockpit answered ${String(status)}.`;\n}\n\n/**\n * The new-session dialog when git is installed: a worktree on an existing or a\n * new branch, or a plain session in the workspace root. A worktree session\n * starts at the top level of the rail, with no parent.\n */\nexport function GitNewSessionDialog({ newSession }: WebPluginSlotProps) {\n const [branches, setBranches] = useState<GitBranchesResponse | null>(null);\n const [loadError, setLoadError] = useState('');\n const [error, setError] = useState('');\n const [busy, setBusy] = useState(false);\n const workspaceId = newSession?.workspaceId;\n const request = newSession?.requestWithStepUp;\n\n useEffect(() => {\n if (workspaceId === undefined || request === undefined) return;\n let stale = false;\n const url = api.workspace(workspaceId).branches.url();\n void request(url)\n .then(async (response) => {\n const body: unknown = await response.json().catch(() => undefined);\n if (stale) return;\n if (!response.ok) {\n setLoadError(errorOf(body, response.status));\n return;\n }\n const loaded = body as GitBranchesResponse;\n setBranches(loaded);\n })\n .catch(() => {\n if (!stale) setLoadError('The branches could not be loaded.');\n });\n return () => {\n stale = true;\n };\n }, [workspaceId, request]);\n\n if (newSession === undefined) return null;\n\n const submit = async (state: NewSessionFormState): Promise<void> => {\n if (busy || formProblem(state) !== undefined) return;\n setBusy(true);\n setError('');\n const body = createRequest(state);\n let failure: string | undefined;\n try {\n if (body === undefined) {\n failure = await newSession.createPlain(state.name);\n } else {\n const response = await newSession.requestWithStepUp(api.workspace(newSession.workspaceId).createSession.url(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const answer: unknown = await response.json().catch(() => undefined);\n failure = response.ok\n ? await newSession.openCreated((answer as GitSessionCreated).sessionId)\n : errorOf(answer, response.status);\n }\n } catch {\n failure = 'The cockpit is unreachable.';\n }\n if (failure === undefined) return;\n setError(failure);\n setBusy(false);\n };\n\n return (\n <Dialog\n open\n onOpenChange={(next) => {\n if (!next && !busy) newSession.close();\n }}\n >\n <DialogContent width=\"md\" className=\"overflow-y-auto p-0\" aria-describedby={undefined}>\n <DialogTitle className=\"sr-only\">New session</DialogTitle>\n <GitNewSessionDialogView\n workspaceRoot={newSession.workspaceRoot}\n branches={branches}\n loadError={loadError}\n busy={busy}\n error={error}\n onClose={newSession.close}\n onCreate={(state) => void submit(state)}\n />\n </DialogContent>\n </Dialog>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { GitNewSessionDialog } from './_components/GitNewSessionDialog';\n\nexport default defineFill({ component: GitNewSessionDialog });\n","import type { GitAuthMethod, GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\n\n/**\n * Pure form logic for a workspace's git auth panel: what the fields start as,\n * what is wrong with them, and what a save sends.\n *\n * The server validates again; this only keeps the page from sending what it\n * already knows will be refused, and says why in words next to the field.\n */\n\nexport const DEFAULT_HTTPS_HOST = 'github.com';\n\nexport interface GitAuthFormState {\n method: GitAuthMethod;\n keyPath: string;\n host: string;\n username: string;\n /** Never prefilled. Empty keeps the saved token when there is one for this host. */\n token: string;\n}\n\nexport function formFromView(view: GitAuthView): GitAuthFormState {\n return {\n method: view.method,\n keyPath: view.ssh?.keyPath ?? '',\n host: view.https?.host ?? DEFAULT_HTTPS_HOST,\n username: view.https?.username ?? '',\n token: '',\n };\n}\n\nconst HOST_PATTERN = /^[a-z0-9.-]{1,253}(:\\d{1,5})?$/u;\n/** Whether a value holds an ASCII control character; a newline in a credential field could add a line to git's credential protocol. */\nfunction hasControl(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code < 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\n/** Whether the saved token can stay: only when one exists and the host has not moved. */\nfunction keepsToken(form: GitAuthFormState, saved: GitAuthView): boolean {\n return saved.https?.hasToken === true && saved.https.host === form.host.trim().toLowerCase();\n}\n\n/** The first thing wrong with the form, in words, or undefined when it can be saved. */\nexport function formProblem(form: GitAuthFormState, saved: GitAuthView): string | undefined {\n if (form.method === 'ssh') {\n const keyPath = form.keyPath.trim();\n if (keyPath === '') return undefined;\n if (hasControl(keyPath)) return 'The key path has a control character in it.';\n if (!keyPath.startsWith('/') && !keyPath.startsWith('~/'))\n return 'Give the key as an absolute path or one under ~/.';\n return undefined;\n }\n if (form.method === 'https') {\n const host = form.host.trim().toLowerCase();\n if (!HOST_PATTERN.test(host)) return 'The host should look like github.com, with an optional :port.';\n if (form.username.trim() === '') return 'A username is required.';\n if (hasControl(form.username) || hasControl(form.token))\n return 'Remove the control character from the username or token.';\n if (form.token === '' && !keepsToken(form, saved)) {\n return saved.https?.hasToken === true\n ? 'The host changed, so enter the token for the new host.'\n : 'A token is required.';\n }\n }\n return undefined;\n}\n\n/** What a save sends. The token goes only when the reader typed one. */\nexport function saveRequestOf(form: GitAuthFormState): GitAuthSaveRequest {\n if (form.method === 'ssh') {\n const keyPath = form.keyPath.trim();\n return keyPath === '' ? { method: 'ssh' } : { method: 'ssh', keyPath };\n }\n if (form.method === 'https') {\n return {\n method: 'https',\n host: form.host.trim().toLowerCase(),\n username: form.username.trim(),\n ...(form.token === '' ? {} : { token: form.token }),\n };\n }\n return { method: 'none' };\n}\n","/**\n * A workspace's git remote panel body: how po-git reaches the remote when\n * you pull, push or rebase from this workspace's sessions in the cockpit.\n *\n * DESIGN PATTERNS:\n * - Per workspace. Worktree sessions use the setup of the workspace they\n * belong to. A workspace with nothing set uses this machine's own git.\n * - Three choices as cards, the way the tunnel picker offers them: this\n * machine's own git, an SSH key, or an HTTPS token. The fields a choice\n * needs follow in one card of form rows.\n * - The token is write-only. The field is never prefilled; a saved token shows\n * as a badge, and leaving the field empty keeps it.\n * - Form state is the reader's until they save. The owner remounts the form\n * after a save so it starts again from what the server now holds.\n *\n * AVOID:\n * - Echoing a token back. The view the server sends has none to echo.\n */\nimport {\n Button,\n CheckIcon,\n Input,\n SettingsActions,\n SettingsNote,\n SettingsSection,\n SettingsSectionDescription,\n SettingsSectionHeader,\n SettingsSectionTitle,\n ShieldIcon,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\n\nimport type { GitAuthMethod, GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\nimport { formFromView, formProblem, saveRequestOf, type GitAuthFormState } from '../_lib/gitAuthForm';\n\nfunction Field({ label, children }: { label: ReactNode; children: ReactNode }) {\n return (\n <label className=\"flex flex-col gap-2 text-base text-po-text\">\n <span>{label}</span>\n {children}\n </label>\n );\n}\n\nexport interface GitAuthFormProps {\n saved: GitAuthView;\n saving: boolean;\n saveError?: string;\n savedNotice?: boolean;\n onSave: (request: GitAuthSaveRequest) => void;\n}\nconst METHODS: readonly { method: GitAuthMethod; title: string; detail: string }[] = [\n { method: 'none', title: \"This machine's git\", detail: 'Your credential helper, SSH config and agent, as they are.' },\n { method: 'ssh', title: 'SSH key', detail: 'A key file on this machine, or your ssh-agent.' },\n { method: 'https', title: 'HTTPS token', detail: 'A username and personal access token for one host.' },\n];\n\nexport function GitAuthForm({ saved, saving, saveError, savedNotice = false, onSave }: GitAuthFormProps) {\n const [form, setForm] = useState<GitAuthFormState>(() => formFromView(saved));\n const [edited, setEdited] = useState(false);\n const update = (patch: Partial<GitAuthFormState>): void => {\n setEdited(true);\n setForm((current) => ({ ...current, ...patch }));\n };\n const problem = formProblem(form, saved);\n const tokenSaved = saved.https?.hasToken === true && saved.https.host === form.host.trim().toLowerCase();\n const host = form.host.trim() === '' ? 'this host' : form.host.trim();\n return (\n <SettingsSection data-testid=\"git-auth-form\">\n <SettingsSectionHeader>\n <SettingsSectionTitle>Connection</SettingsSectionTitle>\n <SettingsSectionDescription>\n Worktree sessions use the setup of the workspace they belong to.\n </SettingsSectionDescription>\n </SettingsSectionHeader>\n <div aria-label=\"How git reaches your remote\" className=\"flex flex-col gap-3\">\n {METHODS.map((choice) => (\n <div\n key={choice.method}\n className={`overflow-hidden rounded-lg border ${form.method === choice.method ? 'border-po-green' : 'border-po-border-soft'}`}\n >\n <button\n type=\"button\"\n aria-pressed={form.method === choice.method}\n disabled={saving}\n data-testid={`git-auth-method-${choice.method}`}\n onClick={() => update({ method: choice.method })}\n className={`flex w-full items-start gap-3 p-4 text-left ${form.method === choice.method ? 'bg-po-tint-green' : 'bg-po-bg'}`}\n >\n <span className=\"flex flex-1 flex-col gap-1\">\n <span className=\"text-base font-semibold text-po-hi\">{choice.title}</span>\n <span className=\"text-sm leading-relaxed text-po-dim\">{choice.detail}</span>\n </span>\n {form.method === choice.method ? <CheckIcon className=\"mt-0.5 size-4 shrink-0 text-po-green\" /> : null}\n </button>\n {form.method === choice.method && form.method === 'ssh' ? (\n <div className=\"flex flex-col gap-3 border-t border-po-border-soft p-4\">\n <Field label=\"Key path\">\n <Input\n data-testid=\"git-auth-key-path\"\n value={form.keyPath}\n placeholder=\"~/.ssh/id_ed25519\"\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ keyPath: event.target.value })}\n className=\"font-mono\"\n />\n </Field>\n <p className=\"text-sm leading-relaxed text-po-dim\">\n Leave blank to use SSH config and ssh-agent. Passphrases need ssh-agent. Trust an unknown host in a\n terminal first.\n </p>\n </div>\n ) : null}\n {form.method === choice.method && form.method === 'https' ? (\n <div className=\"flex flex-col gap-4 border-t border-po-border-soft p-4\">\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Host\">\n <Input\n data-testid=\"git-auth-host\"\n value={form.host}\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ host: event.target.value })}\n className=\"font-mono\"\n />\n </Field>\n <Field label=\"Username\">\n <Input\n data-testid=\"git-auth-username\"\n value={form.username}\n autoComplete=\"username\"\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ username: event.target.value })}\n />\n </Field>\n </div>\n <Field\n label={\n <>\n Token{' '}\n {tokenSaved ? (\n <span data-testid=\"git-auth-token-saved\" className=\"ml-2 text-sm text-po-green\">\n A token is saved\n </span>\n ) : null}\n </>\n }\n >\n <Input\n data-testid=\"git-auth-token\"\n type=\"password\"\n value={form.token}\n autoComplete=\"new-password\"\n placeholder={tokenSaved ? 'Leave blank to keep it' : 'Personal access token'}\n disabled={saving}\n onChange={(event) => update({ token: event.target.value })}\n />\n </Field>\n <p className=\"text-sm text-po-dim\">\n Sent only to <span className=\"font-mono\">{host}</span>. Other hosts use this machine's git.\n </p>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n <SettingsNote className=\"flex items-start gap-2 leading-relaxed\">\n <ShieldIcon aria-hidden className=\"mt-0.5 size-4 shrink-0\" />\n <span>\n Only cockpit pull, push and rebase use these credentials, not the agent.\n <br />\n Stored in <span className=\"font-mono\">~/.po/git/credentials.json</span>, readable only by you.\n </span>\n </SettingsNote>\n <SettingsActions className=\"gap-4\">\n <Button\n variant=\"primary\"\n data-testid=\"git-auth-save\"\n disabled={problem !== undefined || saving}\n loading={saving}\n loadingLabel=\"Saving...\"\n onClick={() => {\n if (!saving && problem === undefined) onSave(saveRequestOf(form));\n }}\n >\n Save connection\n </Button>\n {savedNotice && !edited && problem === undefined && saveError === undefined ? (\n <span data-testid=\"git-auth-saved\" className=\"text-sm text-po-green\">\n Saved.\n </span>\n ) : null}\n </SettingsActions>\n {problem !== undefined ? (\n <p data-testid=\"git-auth-problem\" className=\"text-sm text-po-red\">\n {problem}\n </p>\n ) : null}\n {saveError !== undefined ? (\n <p role=\"alert\" data-testid=\"git-auth-error\" className=\"text-sm text-po-red\">\n {saveError}\n </p>\n ) : null}\n </SettingsSection>\n );\n}\n","import type { RepositorySettingsPanelProps } from '@agimon-ai/po-core/web';\n/**\n * A workspace's git remote panel: loads that workspace's saved auth and saves a\n * new one. Lives under settings, in the repository section the host scopes.\n *\n * DESIGN PATTERNS:\n * - Per workspace. The host hands the selected repository; its opaque id is\n * the only thing sent, and the hub resolves it to an admitted root. A\n * browser never names a path.\n * - Reads through the host's sealed request and writes through its step-up\n * request, so a remote device proves itself with a passkey before it can\n * change credentials. The URLs come from the generated client.\n * - After a save the form remounts from what the server returned, which is how\n * the token field empties and the \"token saved\" badge appears.\n */\nimport {\n Button,\n SettingsCard,\n SettingsRow,\n SettingsRowDescription,\n SettingsRowText,\n SettingsRowTitle,\n Spinner,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { api } from '../../../../../../generated/client';\nimport type { GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\nimport { GitAuthForm } from './GitAuthForm';\n\nfunction isAuthView(value: unknown): value is GitAuthView {\n return (\n typeof value === 'object' &&\n value !== null &&\n ['none', 'ssh', 'https'].includes(String((value as { method?: unknown }).method))\n );\n}\n\nfunction errorOf(body: unknown, status: number): string {\n return typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : `The cockpit answered ${String(status)}.`;\n}\n\n/** The one-row card every non-form state of this panel is told in. */\nfunction StateCard({\n testId,\n title,\n children,\n action,\n}: {\n testId: string;\n title: string;\n children: ReactNode;\n action?: ReactNode;\n}) {\n return (\n <SettingsCard data-testid={testId}>\n <SettingsRow>\n <SettingsRowText>\n <SettingsRowTitle>{title}</SettingsRowTitle>\n <SettingsRowDescription>{children}</SettingsRowDescription>\n </SettingsRowText>\n {action}\n </SettingsRow>\n </SettingsCard>\n );\n}\n\nexport function GitAuthPanel({ repository, request, requestWithStepUp }: RepositorySettingsPanelProps) {\n const repositoryId = repository?.id;\n const [loaded, setLoaded] = useState<{ repositoryId: string; saved: GitAuthView }>();\n const [loadError, setLoadError] = useState<{ repositoryId: string; error: string }>();\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string>();\n const [savedNotice, setSavedNotice] = useState(false);\n const [generation, setGeneration] = useState(0);\n const [attempt, setAttempt] = useState(0);\n\n useEffect(() => {\n if (repositoryId === undefined) return;\n let stale = false;\n request(api.workspace(repositoryId).auth.url({ query: { repositoryId } }))\n .then(async (response) => {\n const body: unknown = await response.json().catch(() => undefined);\n if (stale) return;\n if (response.ok && isAuthView(body)) setLoaded({ repositoryId, saved: body });\n else setLoadError({ repositoryId, error: errorOf(body, response.status) });\n })\n .catch(() => {\n if (!stale) setLoadError({ repositoryId, error: 'The cockpit is unreachable.' });\n });\n return () => {\n stale = true;\n };\n }, [repositoryId, request, attempt]);\n\n if (repository === null || repositoryId === undefined) {\n return (\n <StateCard testId=\"git-auth-no-repository\" title=\"No repository picked\">\n Git remote access is set per workspace. Pick one above.\n </StateCard>\n );\n }\n\n const save = async (next: GitAuthSaveRequest): Promise<void> => {\n setSaving(true);\n setSaveError(undefined);\n setSavedNotice(false);\n try {\n const response = await requestWithStepUp(api.workspace(repositoryId).saveAuth.url({ query: { repositoryId } }), {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(next),\n });\n const body: unknown = await response.json().catch(() => undefined);\n if (response.ok && isAuthView(body)) {\n setLoaded({ repositoryId, saved: body });\n setGeneration((current) => current + 1);\n setSavedNotice(true);\n } else {\n setSaveError(errorOf(body, response.status));\n }\n } catch {\n setSaveError('The cockpit is unreachable.');\n } finally {\n setSaving(false);\n }\n };\n\n if (loadError?.repositoryId === repositoryId) {\n return (\n <div role=\"alert\" data-testid=\"git-auth-load-error\">\n <StateCard\n testId=\"git-auth-load-error-card\"\n title=\"Po couldn't read this workspace's git settings just now\"\n action={\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setLoadError(undefined);\n setAttempt((current) => current + 1);\n }}\n >\n Try again\n </Button>\n }\n >\n {loadError.error} Nothing has changed.\n </StateCard>\n </div>\n );\n }\n if (loaded?.repositoryId !== repositoryId) {\n return (\n <StateCard testId=\"git-auth-loading\" title=\"Reading git settings\">\n <span className=\"inline-flex items-center gap-2\">\n <Spinner className=\"size-3 text-po-faint\" label=\"Loading git settings\" />\n This takes a moment.\n </span>\n </StateCard>\n );\n }\n return (\n <GitAuthForm\n key={`${repositoryId}-${String(generation)}`}\n saved={loaded.saved}\n saving={saving}\n savedNotice={savedNotice}\n onSave={(next) => void save(next)}\n {...(saveError === undefined ? {} : { saveError })}\n />\n );\n}\n","import { defineRepositorySettingsPanel } from '@agimon-ai/po-core/web';\n\nimport { GitAuthPanel } from './_components/GitAuthPanel';\n\nexport default defineRepositorySettingsPanel({\n label: 'Git remote',\n detail: \"How this workspace's sessions reach the remote when you pull, push or rebase from the cockpit.\",\n order: 50,\n component: GitAuthPanel,\n});\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The dock's view of this session's worktrees, and the commands it sends.\n *\n * DESIGN PATTERNS:\n * - Session-scoped store fed by one hub channel. The hub is authoritative; the\n * page never reads a registry and never guesses.\n * - Actions are channel frames, not prompts. The hub half owns the tool's\n * operations, so the panel names the work and the hub performs it; a\n * worktree made from the dock is the same object the tool makes, without\n * spending a turn of the conversation to ask for it.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - Calling the hub package API from here. A dock slot gets no sealed request\n * transport, and raw fetch breaks the remote cockpit.\n * - `sendSessionFrame` for a command. It envelopes the frame as a session\n * command bound for the agent, which never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../../types/webWorktrees';\n\nexport interface WorktreesSession {\n /** The worktrees the hub last reported for this session's repository. */\n worktrees: WorktreeView[];\n /** Label of the operation the hub is running for this session. */\n pending: string | undefined;\n /** The last failure the hub reported, shown until the next command. */\n error: string | undefined;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n\nexport const worktreeActivity = defineSessionStore<WorktreesSession>({\n worktrees: [],\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** Captures the clicked card, so a focus change cannot retarget an open dialog. */\nexport const worktreeCreateDialog = defineGlobalStore<{ sessionId: string; reservationId?: string } | null>(null);\n/**\n * The page's hub socket sender, held for as long as the plugin runs.\n *\n * Undefined before `startWorktreeRuntime` and after it disposes; a command\n * sent in that window is dropped rather than queued, because a queue would\n * replay a worktree create against a socket that has since changed sessions.\n */\nconst worktreeSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket. The plugin host calls this once per page. */\nexport function startWorktreeRuntime(runtime: WebPluginRuntime): () => void {\n // Wrapped rather than referenced: an unbound method would lose the runtime\n // it belongs to the moment the store hands it back.\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n worktreeSender.update(() => send);\n return () => {\n worktreeSender.update((current) => (current === send ? undefined : current));\n worktreeCreateDialog.update(() => null);\n };\n}\n\n/**\n * Whether this session has worktree work in flight.\n *\n * A standing worktree is state, not work: it sits there until someone closes\n * it, so counting it would leave the session reading as busy forever, with a\n * \"background work is still running\" notice under a conversation where\n * nothing is running. Only a create or close actually in progress counts.\n *\n * The group stays visible either way. Declaring an active source at all is\n * what keeps it in the dock; this answers how it is drawn, not whether it is\n * there.\n */\nexport const worktreeActivitySource = {\n subscribe(listener: () => void) {\n const subscription = worktreeActivity.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return worktreeActivity.select(worktreeActivity.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction optionalErrorTarget(value: unknown): WorktreeErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'create') return { action: 'create' };\n if (value.action === 'close' && typeof value.id === 'string' && value.id !== '') {\n return { action: 'close', id: value.id };\n }\n return undefined;\n}\n\n/** The plugin's session data channel: 'git_worktrees' payloads into the store. */\nexport const worktreesChannel = worktreeActivity.channel<WorktreesSession>({\n channel: GIT_WORKTREES_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.worktrees)) return null;\n return {\n worktrees: input.worktrees.filter(isRecord) as unknown as WorktreeView[],\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/** Sends one command to the session's worktrees channel. */\nfunction command(sessionId: string, payload: GitWorktreesCommand): void {\n worktreeSender.store.state?.({ type: GIT_WORKTREES_TYPE, sessionId, payload });\n}\n\n/** Asks the hub for a worktree. The hub answers on the same channel. */\nexport function requestWorktreeCreate(\n sessionId: string,\n branch: string,\n baseRef: string,\n reservationId?: string,\n): void {\n const trimmedBase = baseRef.trim();\n command(sessionId, {\n action: 'create',\n branch: branch.trim(),\n ...(trimmedBase === '' ? {} : { baseRef: trimmedBase }),\n ...(reservationId === undefined ? {} : { reservationId }),\n });\n}\n\n/** Asks the hub to close one worktree. Refusal on a dirty tree stays the hub's call. */\nexport function requestWorktreeClose(sessionId: string, id: string): void {\n command(sessionId, { action: 'close', id });\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport {\n Dialog,\n Button,\n Input,\n Spinner,\n DialogContent,\n DialogTitle,\n DropdownMenuItem,\n} from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useId, useRef, useState } from 'react';\n\nimport {\n requestWorktreeCreate,\n worktreeActivity,\n worktreeCreateDialog,\n worktreesChannel,\n} from '../../_lib/worktreesActivityStore';\n\nexport function WorktreeSessionMenu({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n return (\n <DropdownMenuItem\n disabled={sessionId === null}\n data-testid={`session-worktree-${sessionReservationId ?? sessionId}`}\n onSelect={() => {\n if (sessionId !== null)\n worktreeCreateDialog.update(() => ({\n sessionId,\n ...(sessionReservationId === undefined ? {} : { reservationId: sessionReservationId }),\n }));\n }}\n >\n Create worktree session...\n </DropdownMenuItem>\n );\n}\n\nexport function WorktreeCreateOverlay(props: WebPluginSlotProps) {\n const target = useStore(worktreeCreateDialog.store);\n const { holdSessionChannels } = props;\n useEffect(() => {\n if (target === null) return;\n return holdSessionChannels?.(target.sessionId, (frame) => {\n if (frame.type !== worktreesChannel.channel) return;\n const payload = worktreesChannel.parse(frame.payload);\n if (payload !== null) worktreesChannel.apply(target.sessionId, payload);\n });\n }, [target, holdSessionChannels]);\n if (target === null) return null;\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) worktreeCreateDialog.update(() => null);\n }}\n >\n <DialogContent\n width=\"md\"\n className=\"w-96 overflow-y-auto border-0\"\n data-testid=\"session-worktree-dialog\"\n aria-describedby={undefined}\n >\n <DialogTitle className=\"sr-only\">Create a worktree session</DialogTitle>\n <WorktreeCreateForm\n {...props}\n key={`${target.sessionId}:${target.reservationId ?? ''}`}\n sessionId={target.sessionId}\n sessionReservationId={target.reservationId}\n onCancel={() => worktreeCreateDialog.update(() => null)}\n onCreated={() => worktreeCreateDialog.update(() => null)}\n />\n </DialogContent>\n </Dialog>\n );\n}\n\nexport function WorktreeCreateForm({\n sessionId,\n sessionReservationId,\n onCancel,\n onRequested,\n onCreated,\n}: WebPluginSlotProps & {\n onCancel: () => void;\n onRequested?: (branch: string) => void;\n /** Called once the hub finishes this form's request without a create error. */\n onCreated?: () => void;\n}) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n const [branch, setBranch] = useState('');\n const [baseRef, setBaseRef] = useState('');\n // The hub owns `pending`; a request is done once it was seen and cleared, or its record arrived.\n const sent = useRef<{ branch: string; sawPending: boolean } | undefined>(undefined);\n useEffect(() => {\n const request = sent.current;\n if (request === undefined) return;\n if (session.pending !== undefined) {\n request.sawPending = true;\n return;\n }\n const arrived = session.worktrees.some((worktree) => worktree.branch === request.branch);\n if (!arrived && !request.sawPending) return;\n sent.current = undefined;\n if (session.errorTarget?.action !== 'create') onCreated?.();\n }, [session.pending, session.worktrees, session.errorTarget, onCreated]);\n return (\n <WorktreeCreateView\n branch={branch}\n baseRef={baseRef}\n onBranchChange={setBranch}\n onBaseChange={setBaseRef}\n busy={session.pending !== undefined}\n error={session.errorTarget?.action === 'create' ? session.error : undefined}\n onCancel={onCancel}\n onCreate={() => {\n if (sessionId !== null) {\n sent.current = { branch: branch.trim(), sawPending: false };\n onRequested?.(branch.trim());\n requestWorktreeCreate(sessionId, branch, baseRef, sessionReservationId);\n }\n }}\n disabled={sessionId === null}\n />\n );\n}\nexport function WorktreeCreateView({\n branch,\n baseRef,\n onBranchChange,\n onBaseChange,\n busy = false,\n error,\n onCancel,\n onCreate,\n disabled = false,\n}: {\n branch: string;\n baseRef: string;\n onBranchChange?: (value: string) => void;\n onBaseChange?: (value: string) => void;\n busy?: boolean;\n error?: string;\n onCancel?: () => void;\n onCreate?: () => void;\n disabled?: boolean;\n}) {\n const id = useId();\n return (\n <div className=\"rounded-lg border border-po-border-soft bg-po-panel p-5 text-po-text shadow-sm\">\n <h2 id={`${id}-title`} className=\"text-xl font-semibold text-po-hi\">\n Create a worktree session\n </h2>\n <p className=\"mt-2 text-sm leading-relaxed text-po-dim\">\n Create a separate checkout and session without moving your existing sessions.\n </p>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n if (!busy && !disabled && branch.trim()) onCreate?.();\n }}\n >\n <div className=\"mt-5 flex flex-col gap-4\">\n <div className=\"flex flex-col gap-2\">\n <label htmlFor={`${id}-branch`} className=\"text-base font-medium\">\n Branch\n </label>\n <Input\n id={`${id}-branch`}\n data-testid=\"git-worktree-branch\"\n className=\"font-mono\"\n placeholder=\"wt/fix-auth\"\n value={branch}\n onChange={(e) => onBranchChange?.(e.target.value)}\n disabled={busy}\n aria-invalid={!!error}\n aria-describedby={error ? `${id}-error` : undefined}\n />\n {error && (\n <p id={`${id}-error`} role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-sm text-po-red\">\n {error}\n </p>\n )}\n </div>\n <div className=\"flex flex-col gap-2\">\n <label htmlFor={`${id}-base`} className=\"text-base font-medium\">\n Start from\n </label>\n <Input\n size=\"sm\"\n id={`${id}-base`}\n data-testid=\"git-worktree-base\"\n className=\"font-mono\"\n placeholder=\"Current branch\"\n value={baseRef}\n onChange={(e) => onBaseChange?.(e.target.value)}\n disabled={busy}\n />\n </div>\n </div>\n <footer className=\"mt-5 flex items-center justify-end gap-2 border-t border-po-border-soft pt-4\">\n <Button type=\"button\" variant=\"ghost\" disabled={busy} onClick={onCancel}>\n Cancel\n </Button>\n <Button\n type=\"submit\"\n variant=\"primary\"\n data-testid=\"git-worktree-create\"\n disabled={busy || disabled || !branch.trim()}\n >\n {busy && <Spinner className=\"size-3\" label=\"Creating worktree\" />}\n {busy ? 'Creating worktree...' : 'Create worktree'}\n </Button>\n </footer>\n </form>\n </div>\n );\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport { Button, Dot, EmptyState, Spinner, StatusBadge } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport type { WorktreeView } from '../../../../../types/webWorktrees';\nimport { requestWorktreeClose, worktreeActivity } from '../_lib/worktreesActivityStore';\nimport { WorktreeCreateForm } from '../fill/_components/WorktreeCreateDialog';\n\nexport function worktreesTab(): TransientTab {\n return { id: 'git-worktrees', label: 'worktrees', panel: WorktreesPanel };\n}\nexport function WorktreesPanel(props: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, props.sessionId));\n const [creating, setCreating] = useState(session.errorTarget?.action === 'create');\n const [requestedBranch, setRequestedBranch] = useState<string>();\n const sawPending = useRef(false);\n useEffect(() => {\n if (!requestedBranch) return;\n if (\n session.worktrees.some((w) => w.branch === requestedBranch) ||\n (sawPending.current && session.pending === undefined)\n ) {\n setRequestedBranch(undefined);\n } else if (session.pending !== undefined) {\n sawPending.current = true;\n }\n }, [requestedBranch, session.pending, session.worktrees]);\n return (\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <WorktreesPanelView\n worktrees={session.worktrees}\n pending={session.pending}\n startingBranch={\n session.pending === undefined || session.worktrees.some((w) => w.branch === requestedBranch)\n ? undefined\n : requestedBranch\n }\n error={session.errorTarget?.action === 'create' && creating ? undefined : session.error}\n closeErrorId={session.errorTarget?.action === 'close' ? session.errorTarget.id : undefined}\n onNew={() => setCreating(true)}\n onClose={props.sessionId === null ? undefined : (id) => requestWorktreeClose(props.sessionId!, id)}\n form={\n creating ? (\n <WorktreeCreateForm\n {...props}\n onCancel={() => setCreating(false)}\n onCreated={() => setCreating(false)}\n onRequested={(branch) => {\n sawPending.current = false;\n setRequestedBranch(branch);\n }}\n />\n ) : undefined\n }\n />\n </div>\n );\n}\nexport function WorktreesPanelView({\n worktrees,\n pending,\n error,\n closeErrorId,\n onNew,\n onClose,\n form,\n startingIds = [],\n startingBranch,\n}: {\n worktrees: WorktreeView[];\n pending?: string;\n error?: string;\n closeErrorId?: string;\n onNew?: () => void;\n onClose?: (id: string) => void;\n form?: ReactNode;\n startingIds?: string[];\n startingBranch?: string;\n}) {\n const groups = [worktrees.filter((w) => !w.orphaned && !w.unowned), worktrees.filter((w) => w.orphaned || w.unowned)];\n return (\n <div data-testid=\"git-worktrees-panel\" className=\"rounded-lg border border-po-border-soft bg-po-panel p-5\">\n <header className=\"flex items-center justify-between gap-4 border-b border-po-border-soft pb-4\">\n <h2 className=\"text-lg font-semibold text-po-hi\">Worktrees</h2>\n <span data-testid=\"git-worktrees-count\" className=\"sr-only\">\n {worktrees.length === 0 ? 'none yet' : `${worktrees.length} open`}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={onNew}>\n New worktree\n </Button>\n </header>\n {form}\n {/* The starting row already says it; the hub's label arrives lowercase, so raise its first letter. */}\n {pending && !startingBranch && (\n <p data-testid=\"git-worktree-pending\" className=\"flex items-center gap-2 pt-3 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n {error && (!closeErrorId || !worktrees.some((w) => w.id === closeErrorId)) && (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-sm text-po-red\">\n {error}\n </p>\n )}\n {worktrees.length === 0 && !startingBranch ? (\n <EmptyState\n data-testid=\"git-worktrees-empty\"\n className=\"py-10\"\n title=\"No worktrees yet\"\n description=\"A worktree gives a branch its own checkout and a session nested under this one.\"\n />\n ) : (\n <div data-testid=\"git-worktrees-list\">\n {groups.map(\n (group, i) =>\n (group.length > 0 || (i === 0 && startingBranch)) && (\n <section key={i}>\n <h3 className=\"flex items-center gap-2 pt-5 text-lg font-semibold text-po-hi\">\n {i === 0 ? 'Working' : 'Needs a look'}{' '}\n <span className=\"text-sm font-normal text-po-dim\">\n {group.length + (i === 0 && startingBranch ? 1 : 0)} open\n </span>\n </h3>\n {i === 1 && (\n <p className=\"pt-2 text-sm leading-relaxed text-po-dim\">\n {group.length === 2\n ? 'Two worktrees'\n : group.length === 1\n ? 'One worktree'\n : `${group.length} worktrees`}{' '}\n would like your eye, whenever you are ready.\n </p>\n )}\n {i === 0 && startingBranch && (\n <div\n data-testid=\"git-worktree-starting\"\n className=\"flex min-w-0 flex-col gap-2 border-b border-po-border-soft py-4\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Spinner className=\"size-3 shrink-0 text-po-dim\" label=\"Starting session\" />\n <span className=\"min-w-0 flex-1 truncate font-mono text-base font-medium text-po-hi\">\n {startingBranch}\n </span>\n </div>\n <p className=\"pl-4 text-sm text-po-dim\">Starting session...</p>\n </div>\n )}\n {group.map((w) => (\n <WorktreeRow\n key={w.id}\n worktree={w}\n starting={\n startingIds.includes(w.id) ||\n (!!pending?.includes('starting') && w.sessionId === null && !w.orphaned && !w.unowned)\n }\n disabled={!!pending || !onClose}\n onClose={() => onClose?.(w.id)}\n error={closeErrorId === w.id ? error : undefined}\n />\n ))}\n </section>\n ),\n )}\n </div>\n )}\n </div>\n );\n}\nexport function WorktreeBadge({ worktree }: { worktree: WorktreeView }) {\n if (worktree.orphaned)\n return (\n <StatusBadge tone=\"neutral\" size=\"xs\" className=\"bg-po-tint-yellow text-po-yellow\">\n Orphaned\n </StatusBadge>\n );\n if (worktree.unowned)\n return (\n <StatusBadge tone=\"info\" size=\"xs\">\n Unowned\n </StatusBadge>\n );\n return null;\n}\n\nexport function WorktreeRow({\n worktree,\n compact = false,\n starting = false,\n error,\n disabled = false,\n onClose,\n}: {\n worktree: WorktreeView;\n compact?: boolean;\n starting?: boolean;\n error?: string;\n disabled?: boolean;\n onClose?: () => void;\n}) {\n return (\n <div\n data-testid={`git-worktree-${worktree.id}`}\n className={\n compact ? 'flex min-w-0 flex-col gap-1 py-2' : 'flex min-w-0 flex-col gap-2 border-b border-po-border-soft py-4'\n }\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {starting ? (\n <Spinner className=\"size-3 shrink-0 text-po-dim\" label=\"Starting session\" />\n ) : (\n <Dot size=\"md\" tone={worktree.orphaned ? 'yellow' : worktree.unowned ? 'blue' : 'green'} />\n )}\n <span title={worktree.branch} className=\"min-w-0 flex-1 truncate font-mono text-base font-medium text-po-hi\">\n {worktree.branch}\n </span>\n <WorktreeBadge worktree={worktree} />\n {!compact && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClose}\n disabled={starting || disabled}\n data-testid={`git-worktree-close-${worktree.id}`}\n aria-label={`Close ${worktree.branch}`}\n >\n Close\n </Button>\n )}\n </div>\n {!compact && (\n <p className=\"truncate pl-4 font-mono text-sm text-po-dim\" title={worktree.path}>\n {worktree.path}\n </p>\n )}\n {starting && <p className=\"pl-4 text-sm text-po-dim\">Starting session...</p>}\n {!compact && (worktree.orphaned || worktree.unowned) && (\n <p className=\"pl-4 text-sm text-po-dim first-letter:uppercase\">\n {worktree.orphaned ? 'its folder is missing' : 'its session has ended'}\n </p>\n )}\n {error && (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"pl-4 text-sm text-po-red\">\n {error}\n </p>\n )}\n </div>\n );\n}\n","/**\n * The cockpit's view of what this session changed against its base: the counts\n * the '# diff' group shows, what the review tab lists and draws, and the manual\n * sync that sits beside them.\n *\n * DESIGN PATTERNS:\n * - Declarations only, shared by the hub and the page.\n * - Its own channel, apart from worktrees. Worktrees are repository\n * management; the diff is this session's code change.\n * - A diff row carries one line number whose file follows from its marker: the\n * new file's for context and additions, the old file's for removals. It is\n * the same shape the shared DiffView draws.\n *\n * AVOID:\n * - Behaviour or node builtins. Browser code imports this file.\n */\n\n/** The session channel carrying this checkout's changes and the sync around them. */\nexport const GIT_CHANGES_TYPE = 'git_changes';\n\n/** The sync actions the review tab offers. */\nexport type GitSyncAction = 'pull' | 'push' | 'rebase' | 'abort-rebase';\n\n/** What the review tab asks the hub to run. `force` only follows a confirmed rejected push. */\nexport type GitChangesCommand =\n | { action: 'pull' }\n | { action: 'push'; force?: true }\n | { action: 'rebase' }\n | { action: 'abort-rebase' };\n\nexport type GitSyncErrorTarget =\n | { action: 'pull' | 'rebase' | 'abort-rebase' }\n /** A push the remote rejected as non-fast-forward; the tab offers a lease force after a confirm. */\n | { action: 'push'; forceRequired?: true };\n\nexport interface GitChangesPayload {\n /** Absent outside a git checkout. */\n changes?: GitChangesView;\n /** Label of the sync command in flight. */\n pending?: string;\n /** The last sync failure, cleared when the next command starts. */\n error?: string;\n errorTarget?: GitSyncErrorTarget;\n}\n\n/** What the session changed since its base, as the '# diff' lane and the review header show it. */\nexport interface GitChangesView {\n /** The checked-out branch; absent on a detached HEAD. */\n branch?: string;\n /** The ref the changes are measured against; absent when none resolved, so only uncommitted work counts. */\n base?: string;\n added: number;\n removed: number;\n files: number;\n /** More files changed than were counted. */\n truncated?: boolean;\n /** The branch's upstream and how far apart the two are. */\n upstream?: { ref: string; ahead: number; behind: number };\n /** Present while a rebase is paused on conflicts. */\n rebase?: { conflicts: string[] };\n}\n\nexport type GitReviewFileStatus = 'added' | 'modified' | 'deleted' | 'untracked' | 'conflicted';\n\n/** One changed file in the review list. */\nexport interface GitReviewFileEntry {\n /** Repository-relative, forward slashes. */\n path: string;\n status: GitReviewFileStatus;\n added: number;\n removed: number;\n binary?: boolean;\n}\n\n/** The review tab's file list. */\nexport interface GitReviewSummary {\n /** False when the session's directory is not a git checkout. */\n repository: boolean;\n branch?: string;\n base?: string;\n /** Short sha of the commit the diff starts from. */\n mergeBase?: string;\n files: GitReviewFileEntry[];\n truncated?: boolean;\n}\n\nexport interface GitDiffRow {\n marker: '+' | '-' | ' ';\n line: number;\n content: string;\n}\n\nexport interface GitDiffHunk {\n start: number;\n rows: GitDiffRow[];\n}\n\n/** One file's hunks, fetched when the reader expands it. */\nexport interface GitReviewFileDiff {\n path: string;\n hunks: GitDiffHunk[];\n binary?: true;\n /** The diff was past the size cap and is not drawn. */\n tooLarge?: true;\n}\n","/**\n * This session's code change against its base, and the manual sync beside it.\n *\n * DESIGN PATTERNS:\n * - Its own session store and hub channel, apart from worktrees. Worktrees are\n * repository management; this is the session's diff.\n * - The hub is authoritative: it computes the counts, runs pull, push and\n * rebase one at a time, and reports pending, errors and a paused rebase here.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - `sendSessionFrame` for a sync command. That frame is bound for the agent\n * and never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport {\n GIT_CHANGES_TYPE,\n type GitChangesCommand,\n type GitChangesView,\n type GitSyncAction,\n type GitSyncErrorTarget,\n} from '../../../../../types/gitReview';\n\nexport interface GitChangesSession {\n /** Absent until the hub reports, and outside a git checkout. */\n changes: GitChangesView | undefined;\n pending: string | undefined;\n error: string | undefined;\n errorTarget: GitSyncErrorTarget | undefined;\n}\n\nexport const gitChanges = defineSessionStore<GitChangesSession>({\n changes: undefined,\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** The page's hub socket sender; undefined before start and after dispose, when a command is dropped. */\nconst changesSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket for sync commands. The plugin host calls this once per page. */\nexport function startGitChangesRuntime(runtime: WebPluginRuntime): () => void {\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n changesSender.update(() => send);\n return () => {\n changesSender.update((current) => (current === send ? undefined : current));\n };\n}\n\n/** Whether a sync command is running for this session. */\nexport const gitChangesActivitySource = {\n subscribe(listener: () => void) {\n const subscription = gitChanges.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return gitChanges.select(gitChanges.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction count(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0 ? value : undefined;\n}\n\n/** The page never trusts a frame's shape: a malformed field drops, the rest still renders. */\nconst MAX_CONFLICTS = 100;\n\nfunction optionalChanges(value: unknown): GitChangesView | undefined {\n if (!isRecord(value)) return undefined;\n const added = count(value.added);\n const removed = count(value.removed);\n const files = count(value.files);\n if (added === undefined || removed === undefined || files === undefined) return undefined;\n const branch = optionalText(value.branch);\n const base = optionalText(value.base);\n const upstream = isRecord(value.upstream) ? value.upstream : undefined;\n const ahead = count(upstream?.ahead);\n const behind = count(upstream?.behind);\n const upstreamRef = optionalText(upstream?.ref);\n const conflicts =\n isRecord(value.rebase) && Array.isArray(value.rebase.conflicts)\n ? value.rebase.conflicts.filter((file): file is string => typeof file === 'string').slice(0, MAX_CONFLICTS)\n : undefined;\n return {\n added,\n removed,\n files,\n ...(branch === undefined ? {} : { branch }),\n ...(base === undefined ? {} : { base }),\n ...(value.truncated === true ? { truncated: true } : {}),\n ...(upstreamRef === undefined || ahead === undefined || behind === undefined\n ? {}\n : { upstream: { ref: upstreamRef, ahead, behind } }),\n ...(conflicts === undefined ? {} : { rebase: { conflicts } }),\n };\n}\n\nfunction optionalErrorTarget(value: unknown): GitSyncErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'pull' || value.action === 'rebase' || value.action === 'abort-rebase')\n return { action: value.action };\n if (value.action === 'push')\n return value.forceRequired === true ? { action: 'push', forceRequired: true } : { action: 'push' };\n return undefined;\n}\n\n/** The session data channel: 'git_changes' payloads into the store. */\nexport const gitChangesChannel = gitChanges.channel<GitChangesSession>({\n channel: GIT_CHANGES_TYPE,\n parse(input) {\n if (!isRecord(input)) return null;\n return {\n changes: optionalChanges(input.changes),\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/**\n * Asks the hub to pull, push, rebase or abort a paused rebase. `force` is only\n * ever sent after the reader confirmed a lease force for a rejected push.\n */\nexport function requestGitSync(sessionId: string, action: GitSyncAction, force = false): void {\n const payload: GitChangesCommand = action === 'push' && force ? { action: 'push', force: true } : { action };\n changesSender.store.state?.({ type: GIT_CHANGES_TYPE, sessionId, payload });\n}\n","import { defineActivityGroup } from '@agimon-ai/po-core/web';\nimport { BranchIcon } from '@agimon-ai/po-web-components';\n\nimport { worktreesTab } from '../_components/WorktreesPanel';\nimport { gitChangesActivitySource } from '../_lib/gitChangesStore';\nimport { worktreeActivitySource } from '../_lib/worktreesActivityStore';\n\nexport default defineActivityGroup({\n keys: 'g w',\n icon: BranchIcon,\n activeSource: {\n subscribe(listener) {\n const stopWorktrees = worktreeActivitySource.subscribe(listener);\n const stopChanges = gitChangesActivitySource.subscribe(listener);\n return () => {\n stopWorktrees();\n stopChanges();\n };\n },\n isActive(sessionId) {\n return worktreeActivitySource.isActive(sessionId) || gitChangesActivitySource.isActive(sessionId);\n },\n },\n marksBackgroundWork: false,\n transientTab: worktreesTab,\n order: 30,\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/web';\n\nimport { gitChangesChannel } from '../_lib/gitChangesStore';\n\nexport default defineChannelFile(gitChangesChannel);\n","import { defineChannelFile } from '@agimon-ai/po-core/web';\n\nimport { worktreesChannel } from '../_lib/worktreesActivityStore';\n\nexport default defineChannelFile(worktreesChannel);\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreeSessionMenu } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeSessionMenu });\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreeCreateOverlay } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeCreateOverlay });\n","import { api } from '../../../../../../generated/client';\nimport type { GitReviewFileDiff, GitReviewSummary } from '../../../../../types/gitReview';\n\n/**\n * The review tab's half of the session API: the changed-file list and one\n * file's hunks.\n *\n * The generated client owns the URL and the sealed transport, so nothing here\n * spells a route or reaches for `fetch`. What travels is file contents, which a\n * tunnel's relay must never see in the clear.\n */\n\nconst UNREACHABLE = 'The session is unreachable.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The message a reader is shown: the route's own words, or why there were none. */\nfunction messageOf(result: { status: number; error: string }): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === '' ? `The session answered ${String(result.status)}.` : result.error;\n}\n\nexport type ReviewSummaryResult = { ok: true; summary: GitReviewSummary } | { ok: false; error: string };\n\nexport async function fetchReviewSummary(sessionId: string, signal?: AbortSignal): Promise<ReviewSummaryResult> {\n const result = await api.session(sessionId).review(signal === undefined ? {} : { signal });\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data) || !Array.isArray(result.data.files)) {\n return { ok: false, error: 'The session answered with no file list.' };\n }\n return { ok: true, summary: result.data };\n}\n\nexport type ReviewFileResult = { ok: true; diff: GitReviewFileDiff } | { ok: false; error: string };\n\nexport async function fetchReviewFile(\n sessionId: string,\n path: string,\n signal?: AbortSignal,\n): Promise<ReviewFileResult> {\n const result = await api\n .session(sessionId)\n .reviewFile({ query: { path }, ...(signal === undefined ? {} : { signal }) });\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data) || !Array.isArray(result.data.hunks)) {\n return { ok: false, error: 'The session answered with no diff.' };\n }\n return { ok: true, diff: result.data };\n}\n","import { defineSessionStore } from '@agimon-ai/po-core/web';\n/**\n * Review comments queued on this session, waiting to go to the agent as one\n * message.\n *\n * DESIGN PATTERNS:\n * - Session-scoped and in memory: comments survive closing and reopening the\n * review tab, not a page reload. The same trade the files tab makes.\n * - Comments are cleared only after a send the host accepted, never before.\n */\nimport type { ReviewComment } from '@agimon-ai/po-web-components';\n\nexport interface GitReviewSession {\n comments: ReviewComment[];\n}\n\nexport const gitReview = defineSessionStore<GitReviewSession>({ comments: [] });\n\nexport function addReviewComment(sessionId: string, comment: Omit<ReviewComment, 'id'>): void {\n const id = globalThis.crypto.randomUUID();\n gitReview.update(sessionId, (current) => ({ comments: [...current.comments, { ...comment, id }] }));\n}\n\nexport function removeReviewComment(sessionId: string, id: string): void {\n gitReview.update(sessionId, (current) => ({ comments: current.comments.filter((comment) => comment.id !== id) }));\n}\n\nexport function clearReviewComments(sessionId: string): void {\n gitReview.update(sessionId, () => ({ comments: [] }));\n}\n","import type { SessionFrameSender } from '@agimon-ai/po-core/web';\n\nimport type { GitChangesView } from '../../../../../types/gitReview';\n\n/**\n * Pure wording for what the review tab sends the agent, and the one send.\n *\n * Both messages go as `follow_up`: the host starts a turn when idle, or after\n * the current one, without treating a review send as an explicit Queue action.\n * A `prompt` frame instead fails while a turn runs.\n */\n\n/** The opening line of a review, naming what was reviewed. */\nexport function reviewHeading(count: number, branch: string | undefined, base: string | undefined): string {\n const what = branch === undefined ? 'this checkout' : `branch ${branch}`;\n const against = base === undefined ? 'its uncommitted changes' : `its changes against ${base}`;\n const comments = count === 1 ? 'one review comment' : `${String(count)} review comments`;\n const address = count === 1 ? 'Please address it.' : 'Please address them all.';\n return `I reviewed ${what} (${against}) and left ${comments}. ${address}`;\n}\n\n/** What \"ask agent to resolve\" sends: the files, and the steps that finish a paused rebase. */\nexport function conflictPrompt(branch: string | undefined, conflicts: readonly string[]): string {\n const files =\n conflicts.length === 0 ? '- (git reports no unmerged paths yet)' : conflicts.map((file) => `- ${file}`).join('\\n');\n return [\n `A rebase of ${branch ?? 'this checkout'} stopped on conflicts in:`,\n '',\n files,\n '',\n 'Please resolve them:',\n '1. Fix the conflict markers in each file, keeping the intent of both sides.',\n '2. `git add` each resolved file.',\n '3. Run `GIT_EDITOR=true git rebase --continue`, and repeat if it stops again.',\n '',\n 'Do not push. I will push from the cockpit once the rebase is done.',\n ].join('\\n');\n}\n\n/**\n * The one sync the bar fills in: pull while the branch is behind (a push would\n * be rejected), push while it is only ahead or has no upstream yet. Nothing\n * while a rebase is paused, detached, or already level.\n */\nexport function suggestedSyncAction(changes: GitChangesView | undefined): 'pull' | 'push' | undefined {\n if (changes?.branch === undefined || changes.rebase !== undefined) return undefined;\n if (changes.upstream === undefined) return 'push';\n if (changes.upstream.behind > 0) return 'pull';\n return changes.upstream.ahead > 0 ? 'push' : undefined;\n}\n\n/** \"2 to push, 1 new on origin/feat/git\", or \"Up to date with origin/feat/git\". */\nexport function upstreamSummary(upstream: GitChangesView['upstream']): string {\n if (upstream === undefined) return 'No upstream yet';\n const parts = [\n ...(upstream.ahead > 0 ? [`${String(upstream.ahead)} to push`] : []),\n ...(upstream.behind > 0 ? [`${String(upstream.behind)} new on ${upstream.ref}`] : []),\n ];\n return parts.length === 0 ? `Up to date with ${upstream.ref}` : parts.join(', ');\n}\n/**\n * Hands one deferred follow-up to the session. Returns the reason it failed,\n * or undefined once sent. The sender throws when the session is disconnected.\n */\nexport function deliverToAgent(send: SessionFrameSender, sessionId: string, message: string): string | undefined {\n try {\n send(sessionId, { type: 'follow_up', message });\n return undefined;\n } catch (error) {\n return error instanceof Error ? error.message : 'The session did not take the message.';\n }\n}\n","import { Input, MessageIcon } from '@agimon-ai/po-web-components';\nimport { useEffect, useRef, useState, type KeyboardEvent } from 'react';\n\nimport type { GitReviewFileEntry } from '../../../../../types/gitReview';\n\nconst status = {\n added: ['A', 'text-po-green', 'Added'],\n modified: ['M', 'text-po-yellow', 'Modified'],\n deleted: ['D', 'text-po-red', 'Deleted'],\n untracked: ['U', 'text-po-blue', 'Untracked'],\n conflicted: ['C', 'text-po-red', 'Conflicted'],\n};\nexport interface GitReviewBrowserProps {\n files: readonly GitReviewFileEntry[];\n /** The file the diff pane is showing, highlighted here. */\n activePath?: string;\n commentCounts: Readonly<Record<string, number>>;\n onPick: (path: string) => void;\n}\n\nexport function GitReviewBrowser({ files, activePath, commentCounts, onPick }: GitReviewBrowserProps) {\n const [query, setQuery] = useState('');\n const shown = files.filter((f) => f.path.toLowerCase().includes(query.trim().toLowerCase()));\n const listRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (activePath === undefined) return;\n listRef.current\n ?.querySelector<HTMLElement>(`[data-path=\"${CSS.escape(activePath)}\"]`)\n ?.scrollIntoView({ block: 'nearest' });\n }, [activePath]);\n\n /** Arrow keys pick the neighbouring row and move focus with it, so the diff follows the cursor. */\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>): void => {\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n if (shown.length === 0) return;\n event.preventDefault();\n const current = shown.findIndex((file) => file.path === activePath);\n const step = event.key === 'ArrowDown' ? 1 : -1;\n const next = current === -1 ? 0 : (current + step + shown.length) % shown.length;\n const file = shown[next];\n if (file === undefined) return;\n onPick(file.path);\n const list = event.currentTarget.closest('[data-git-review-list]');\n list?.querySelectorAll<HTMLButtonElement>('[data-git-review-row]')[next]?.focus();\n };\n\n return (\n <nav\n aria-label=\"Changed files\"\n data-testid=\"git-review-browser\"\n className=\"flex min-h-0 w-80 shrink-0 flex-col border-r border-po-border-soft\"\n >\n <div className=\"flex flex-col gap-3 border-b border-po-border-soft p-3\">\n <Input\n data-testid=\"git-review-search\"\n size=\"sm\"\n aria-label=\"Search paths\"\n placeholder=\"Search paths\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <span className=\"text-sm text-po-dim\">{shown.length} changed</span>\n </div>\n <div ref={listRef} data-git-review-list className=\"min-h-0 flex-1 overflow-y-auto\">\n {shown.map((f) => {\n const slash = f.path.lastIndexOf('/');\n const count = commentCounts[f.path] ?? 0;\n return (\n <button\n key={f.path}\n data-git-review-row\n data-path={f.path}\n data-testid={`git-review-browser-file-${f.path}`}\n onKeyDown={onKeyDown}\n title={f.path}\n aria-current={activePath === f.path ? 'true' : undefined}\n onClick={() => onPick(f.path)}\n className={`flex w-full min-w-0 items-start gap-2 border-l-2 px-3 py-3 text-left ${activePath === f.path ? 'border-po-green bg-po-tint-green' : 'border-transparent hover:bg-po-panel'}`}\n >\n <span className={`pt-0.5 text-sm font-semibold ${status[f.status][1]}`}>{status[f.status][0]}</span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-base text-po-text\">{f.path.slice(slash + 1)}</span>\n {slash < 0 ? null : (\n <span className=\"block truncate font-mono text-sm text-po-dim\">{f.path.slice(0, slash)}</span>\n )}\n </span>\n <span className=\"flex shrink-0 flex-col items-end gap-1 text-sm\">\n <span>\n <span className=\"text-po-green\">+{f.added}</span> <span className=\"text-po-red\">-{f.removed}</span>\n </span>\n {count > 0 && (\n <span className=\"flex items-center gap-1 text-po-blue\">\n <MessageIcon className=\"h-3 w-3\" />\n {count}\n </span>\n )}\n </span>\n </button>\n );\n })}\n {shown.length === 0 && <p className=\"p-3 text-sm text-po-dim\">No paths match.</p>}\n </div>\n </nav>\n );\n}\n","import { BranchIcon, Button, Spinner, StatusBadge } from '@agimon-ai/po-web-components';\n\nimport type { GitChangesView, GitSyncAction, GitSyncErrorTarget } from '../../../../../types/gitReview';\nimport { suggestedSyncAction, upstreamSummary } from '../_lib/gitReviewView';\n\nexport interface GitSyncBarProps {\n /** Use an outline suggestion when review sending owns the primary action. */\n secondary?: boolean;\n /** Absent until the hub has reported this session's checkout. */\n changes?: GitChangesView;\n /** Short sha the review diff starts from. */\n mergeBase?: string;\n /** Label of the command the hub is running. */\n pending?: string;\n error?: string;\n errorTarget?: GitSyncErrorTarget;\n onSync: (action: GitSyncAction) => void;\n onForcePush: () => void;\n onAskAgent: () => void;\n onDismissError: () => void;\n}\n\nexport function GitSyncBar({ secondary = false, ...props }: GitSyncBarProps) {\n const c = props.changes;\n const paused = c?.rebase !== undefined;\n const busy = props.pending !== undefined;\n const rejected = props.errorTarget?.action === 'push' && props.errorTarget.forceRequired;\n const suggested = suggestedSyncAction(c);\n const upstream = upstreamSummary(c?.upstream);\n return (\n <div data-testid=\"git-sync-bar\" className=\"flex flex-col gap-3 border-b border-po-border-soft p-4\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n <BranchIcon className=\"h-4 w-4 text-po-dim\" />\n <span data-testid=\"git-review-branch\" className=\"font-mono text-base font-semibold text-po-hi\">\n {c?.branch ?? 'Detached HEAD'}\n </span>\n <span className=\"text-po-dim\">\n {c?.base === undefined ? (\n 'Uncommitted changes'\n ) : (\n <>\n vs <span className=\"font-mono\">{c.base}</span>\n </>\n )}\n </span>\n {props.mergeBase && (\n <span className=\"text-po-dim\">\n from <span className=\"font-mono\">{props.mergeBase}</span>\n </span>\n )}\n {c === undefined ? null : (\n <span data-testid=\"git-review-totals\" className=\"contents\">\n <span className=\"text-po-green\">+{c?.added}</span>\n <span className=\"text-po-red\">-{c?.removed}</span>\n <span className=\"text-po-dim\">\n {c?.files}\n {c?.truncated ? '+' : ''} {c?.files === 1 ? 'file' : 'files'}\n </span>\n </span>\n )}\n <span className=\"flex-1\" />\n <span className=\"text-po-dim\">\n {c?.branch === undefined ? (\n 'No branch checked out'\n ) : c.upstream === undefined || !upstream.endsWith(c.upstream.ref) ? (\n upstream\n ) : (\n <>\n {upstream.slice(0, -c.upstream.ref.length)}\n <span className=\"font-mono\">{c.upstream.ref}</span>\n </>\n )}\n </span>\n <div className=\"flex gap-1.5\">\n {(['pull', 'push', 'rebase'] as const).map((action) => (\n <Button\n key={action}\n data-testid={`git-sync-${action}`}\n size=\"sm\"\n variant={\n !busy && !paused && !rejected && !props.error && c?.branch !== undefined && suggested === action\n ? secondary\n ? 'outline'\n : 'primary'\n : 'ghost'\n }\n disabled={\n busy ||\n paused ||\n (action !== 'rebase' && c?.branch === undefined) ||\n (action === 'pull' && c?.upstream === undefined) ||\n (action === 'rebase' && c?.base === undefined)\n }\n onClick={() => props.onSync(action)}\n >\n {action === 'pull' ? 'Pull' : action === 'push' ? 'Push' : 'Rebase'}\n </Button>\n ))}\n </div>\n </div>\n {busy && (\n <div data-testid=\"git-sync-pending\" className=\"flex items-center gap-2 text-sm text-po-dim\">\n <Spinner className=\"h-4 w-4 text-po-dim\" label={props.pending} />\n {props.pending}\n </div>\n )}\n {rejected ? (\n <div\n data-testid=\"git-push-force-confirm\"\n className=\"flex flex-wrap items-center gap-3 rounded-md border border-po-edge-yellow bg-po-tint-yellow p-3\"\n >\n <span className=\"flex-1 text-base text-po-text\">origin has commits you have not pulled yet.</span>\n <Button\n size=\"sm\"\n variant=\"danger-outline\"\n data-testid=\"git-push-force\"\n disabled={busy}\n onClick={props.onForcePush}\n >\n Force push with lease\n </Button>\n <Button size=\"sm\" variant=\"ghost\" data-testid=\"git-push-force-cancel\" onClick={props.onDismissError}>\n Not now\n </Button>\n </div>\n ) : (\n props.error && (\n <div\n role=\"alert\"\n data-testid=\"git-sync-error\"\n className=\"flex items-center gap-3 rounded-md border border-po-edge-red bg-po-tint-red p-3 text-base text-po-red\"\n >\n <span className=\"flex-1\">{props.error}</span>\n <Button size=\"sm\" variant=\"ghost\" onClick={props.onDismissError}>\n Dismiss\n </Button>\n </div>\n )\n )}\n {paused && (\n <div\n data-testid=\"git-rebase-banner\"\n className=\"flex flex-col gap-2 rounded-md border border-po-edge-yellow bg-po-tint-yellow p-3\"\n >\n <div>\n <StatusBadge tone=\"running\" size=\"xs\">\n Rebase paused\n </StatusBadge>\n <span className=\"ml-2 text-base text-po-text\">\n Conflicts in {c.rebase?.conflicts.length} {c.rebase?.conflicts.length === 1 ? 'file' : 'files'}\n </span>\n </div>\n {c.rebase?.conflicts.map((path) => (\n <p key={path} className=\"font-mono text-sm text-po-dim\">\n {path}\n </p>\n ))}\n <div className=\"flex items-center gap-2\">\n <Button\n variant={secondary ? 'outline' : 'primary'}\n size=\"sm\"\n data-testid=\"git-rebase-ask-agent\"\n disabled={busy}\n onClick={props.onAskAgent}\n >\n Ask Po to resolve\n </Button>\n <Button\n variant=\"danger-outline\"\n size=\"sm\"\n data-testid=\"git-rebase-abort\"\n disabled={busy}\n onClick={() => props.onSync('abort-rebase')}\n >\n Abort rebase\n </Button>\n <span className=\"text-sm text-po-dim\">Abort discards conflict resolution in progress.</span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import {\n Button,\n DiffView,\n EmptyState,\n MessageIcon,\n ReviewCommentDraft,\n Spinner,\n type DiffRow,\n type DiffSelection,\n type ReviewComment,\n} from '@agimon-ai/po-web-components';\nimport { useEffect, useState } from 'react';\n\nimport type { GitReviewFileDiff, GitReviewFileEntry, GitReviewSummary } from '../../../../../types/gitReview';\nimport { GitReviewBrowser } from './GitReviewBrowser';\nimport { GitSyncBar, type GitSyncBarProps } from './GitSyncBar';\n\nconst NO_FILES: readonly GitReviewFileEntry[] = [];\n\nexport type ReviewSummaryState =\n | { state: 'loading' }\n | { state: 'error'; error: string }\n | { state: 'ready'; summary: GitReviewSummary };\n\nexport type ReviewFileState =\n | { state: 'loading' }\n | { state: 'error'; error: string }\n | { state: 'ready'; diff: GitReviewFileDiff };\n\nexport interface GitReviewViewProps {\n sync: GitSyncBarProps;\n summary: ReviewSummaryState;\n files: Readonly<Record<string, ReviewFileState | undefined>>;\n comments: readonly ReviewComment[];\n onLoadFile: (path: string) => void;\n onAddComment: (comment: Omit<ReviewComment, 'id'>) => void;\n onRemoveComment: (id: string) => void;\n onSendReview: () => void;\n onDiscard: () => void;\n /** Defer refresh while an unsent draft owns local input state. */\n onDraftChange?: (open: boolean) => void;\n /** Why the last send did not reach the session; the comments are still here. */\n sendError?: string;\n /** Initial file for deterministic previews. */\n initialPath?: string;\n /** Opens with this draft already raised. Stories use it; the panel never does. */\n initialDraft?: { path: string; selection: DiffSelection };\n}\n\n/** Stable, URL-safe element id for one file's section. */\nfunction sectionId(index: number): string {\n return `git-review-file-${String(index)}`;\n}\n\nfunction sideOf(row: DiffRow): 'old' | 'new' {\n return row.marker === '-' ? 'old' : 'new';\n}\n\nexport function GitReviewView({\n sync,\n summary,\n files,\n comments,\n onLoadFile,\n onAddComment,\n onRemoveComment,\n onSendReview,\n onDiscard,\n onDraftChange,\n sendError,\n initialDraft,\n initialPath,\n}: GitReviewViewProps) {\n const entries = summary.state === 'ready' ? summary.summary.files : NO_FILES;\n const [picked, setPicked] = useState(initialPath ?? initialDraft?.path);\n const activePath = entries.some((entry) => entry.path === picked) ? picked : entries[0]?.path;\n const index = entries.findIndex((entry) => entry.path === activePath);\n const file = entries[index];\n const [draft, setDraft] = useState<{ path: string; selection: DiffSelection } | undefined>(initialDraft);\n\n useEffect(() => {\n if (activePath !== undefined && files[activePath] === undefined) onLoadFile(activePath);\n }, [activePath, files, onLoadFile]);\n\n const commentCounts: Record<string, number> = {};\n for (const comment of comments) commentCounts[comment.path] = (commentCounts[comment.path] ?? 0) + 1;\n\n const pick = (path: string): void => {\n if (!entries.some((entry) => entry.path === path)) return;\n if (path !== activePath && draft !== undefined) {\n if (!window.confirm('Discard the unsent comment and open another file?')) return;\n setDraft(undefined);\n onDraftChange?.(false);\n }\n setPicked(path);\n };\n\n const submitDraft = (body: string): void => {\n if (draft === undefined) return;\n onAddComment({\n path: draft.path,\n relPath: draft.path,\n side: draft.selection.side,\n startLine: draft.selection.startLine,\n endLine: draft.selection.endLine,\n snippet: draft.selection.snippet,\n body: body.trim(),\n });\n setDraft(undefined);\n onDraftChange?.(false);\n };\n\n return (\n <div data-testid=\"git-review-panel\" className=\"flex min-h-0 flex-1 flex-col\">\n <GitSyncBar\n {...sync}\n secondary={comments.length > 0}\n {...(summary.state === 'ready' && summary.summary.mergeBase !== undefined\n ? { mergeBase: summary.summary.mergeBase }\n : {})}\n />\n\n {summary.state === 'loading' ? (\n <div\n data-testid=\"git-review-loading\"\n className=\"flex min-h-48 flex-1 items-center justify-center gap-2 text-sm text-po-dim\"\n >\n <Spinner className=\"h-4 w-4 text-po-dim\" label=\"Reading changes\" />\n <span className=\"text-sm text-po-dim\">Reading changes...</span>\n </div>\n ) : summary.state === 'error' ? (\n <EmptyState\n data-testid=\"git-review-error\"\n className=\"min-h-48 text-po-red\"\n title={<span className=\"text-po-red\">Changes could not be read</span>}\n description={summary.error}\n />\n ) : !summary.summary.repository ? (\n <EmptyState\n data-testid=\"git-review-no-repository\"\n className=\"min-h-48\"\n title=\"Not a Git checkout\"\n description=\"This session's folder is not inside a Git repository.\"\n />\n ) : entries.length === 0 ? (\n <EmptyState\n data-testid=\"git-review-empty\"\n className=\"min-h-48\"\n title=\"No changes yet\"\n description={\n summary.summary.base === undefined\n ? 'Nothing uncommitted in this checkout.'\n : `Nothing differs from ${summary.summary.base}, committed or not.`\n }\n />\n ) : (\n <div data-testid=\"git-review-content\" className=\"flex min-h-0 flex-1\">\n <GitReviewBrowser\n files={entries}\n commentCounts={commentCounts}\n onPick={pick}\n {...(activePath === undefined ? {} : { activePath })}\n />\n <main data-testid=\"git-review-diffs\" className=\"min-h-0 min-w-0 flex-1 overflow-y-auto\">\n {summary.summary.truncated ? (\n <p className=\"px-4 pt-2 text-sm text-po-dim\">\n More files changed than the review lists; the rest are left out.\n </p>\n ) : null}\n <div className=\"flex items-center justify-between border-b border-po-border-soft px-4 py-2\">\n <Button variant=\"ghost\" size=\"sm\" disabled={index <= 0} onClick={() => pick(entries[index - 1]!.path)}>\n Previous file\n </Button>\n <span className=\"text-sm text-po-dim\">\n {index + 1} of {entries.length}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={index >= entries.length - 1}\n onClick={() => pick(entries[index + 1]!.path)}\n >\n Next file\n </Button>\n </div>\n {file === undefined ? null : (\n <FileSection\n key={file.path}\n id={sectionId(index)}\n entry={file}\n state={files[file.path]}\n comments={comments.filter((comment) => comment.path === file.path)}\n draft={draft?.path === file.path ? draft.selection : undefined}\n onSelect={(selection) => {\n setDraft({ path: file.path, selection });\n onDraftChange?.(true);\n }}\n onSubmitDraft={submitDraft}\n onCancelDraft={() => {\n setDraft(undefined);\n onDraftChange?.(false);\n }}\n onRemoveComment={onRemoveComment}\n onRetry={() => onLoadFile(file.path)}\n />\n )}\n </main>\n </div>\n )}\n\n <div\n data-testid=\"git-review-footer\"\n className=\"flex shrink-0 flex-wrap items-center gap-3 border-t border-po-border-soft bg-po-panel px-4 py-3\"\n >\n <MessageIcon aria-hidden className=\"h-4 w-4 text-po-blue\" />\n <span data-testid=\"git-review-comment-count\" className=\"text-sm text-po-dim\">\n {comments.length === 0\n ? 'No comments yet: select lines or click a line number'\n : `${String(comments.length)} ${comments.length === 1 ? 'comment' : 'comments'} queued`}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {sendError === undefined ? null : (\n <span role=\"alert\" data-testid=\"git-review-send-error\" className=\"min-w-0 truncate text-sm text-po-red\">\n {sendError}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"git-review-discard\"\n disabled={comments.length === 0}\n onClick={onDiscard}\n >\n Discard\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n data-testid=\"git-review-send\"\n disabled={comments.length === 0}\n onClick={onSendReview}\n >\n Send review\n </Button>\n </div>\n </div>\n );\n}\n\nconst STATUS_WORD: Readonly<Record<GitReviewFileEntry['status'], string>> = {\n added: 'Added',\n modified: 'Modified',\n deleted: 'Deleted',\n untracked: 'Untracked',\n conflicted: 'Conflicted',\n};\n\n/** One file: a pinned header, then its diff with comments drawn under the lines they are about. */\nfunction FileSection({\n id,\n entry,\n state,\n comments,\n draft,\n onSelect,\n onSubmitDraft,\n onCancelDraft,\n onRemoveComment,\n onRetry,\n}: {\n id: string;\n entry: GitReviewFileEntry;\n state: ReviewFileState | undefined;\n comments: readonly ReviewComment[];\n draft: DiffSelection | undefined;\n onSelect: (selection: DiffSelection) => void;\n onSubmitDraft: (body: string) => void;\n onCancelDraft: () => void;\n onRemoveComment: (id: string) => void;\n onRetry: () => void;\n}) {\n const renderAfterRow = (row: DiffRow) => {\n const side = sideOf(row);\n const here = comments.filter(\n (comment) => (comment.side ?? 'new') === side && (comment.endLine ?? comment.startLine) === row.line,\n );\n const drafting = draft !== undefined && draft.side === side && draft.endLine === row.line;\n if (here.length === 0 && !drafting) return null;\n return (\n <div className=\"font-sans whitespace-normal\">\n {here.map((comment) => (\n <div\n key={comment.id}\n data-testid={`git-review-comment-${comment.id}`}\n className=\"m-3 flex items-start gap-3 rounded-md border border-po-border-soft bg-po-panel p-3 font-sans whitespace-normal\"\n >\n <MessageIcon aria-hidden className=\"mt-1 h-4 w-4 shrink-0 text-po-blue\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"mb-1 text-sm text-po-dim\">You · line {comment.endLine ?? comment.startLine}</span>\n <span className=\"text-base whitespace-pre-wrap text-po-text\">{comment.body}</span>\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Remove comment\"\n title=\"Remove comment\"\n onClick={() => onRemoveComment(comment.id)}\n >\n Remove\n </Button>\n </div>\n ))}\n {drafting ? (\n <div className=\"m-3 rounded-md border border-po-border-soft bg-po-panel font-sans whitespace-normal [&_pre]:text-sm [&_p]:first-letter:uppercase\">\n <ReviewCommentDraft\n snippet={draft.snippet}\n startLine={draft.startLine}\n endLine={draft.endLine}\n side={draft.side}\n testIdPrefix=\"git-review-comment\"\n onSubmit={onSubmitDraft}\n onCancel={onCancelDraft}\n />\n </div>\n ) : null}\n </div>\n );\n };\n\n return (\n <section id={id} data-review-path={entry.path} data-testid={`git-review-file-${entry.path}`}>\n <div className=\"flex flex-wrap items-center gap-3 border-b border-po-border-soft bg-po-panel px-4 py-3\">\n <span className=\"min-w-0 flex-1 truncate font-mono text-base text-po-hi\">{entry.path}</span>\n <span className=\"shrink-0 text-sm text-po-dim\">{STATUS_WORD[entry.status]}</span>\n {entry.binary ? null : (\n <>\n <span className=\"text-sm text-po-green\">+{entry.added}</span>\n <span className=\"text-sm text-po-red\">-{entry.removed}</span>\n </>\n )}\n {comments.length === 0 ? null : (\n <span className=\"flex shrink-0 items-center gap-1 text-sm text-po-blue\">\n <MessageIcon aria-hidden className=\"h-3 w-3\" />\n {comments.length} {comments.length === 1 ? 'comment' : 'comments'}\n </span>\n )}\n </div>\n <div data-review-body={state === undefined || state.state === 'loading' ? 'loading' : 'measured'}>\n {state === undefined || state.state === 'loading' ? (\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <Spinner className=\"h-3 w-3 text-po-faint\" label={`Loading ${entry.path}`} />\n <span className=\"text-sm text-po-dim\">Loading diff...</span>\n </div>\n ) : state.state === 'error' ? (\n <div className=\"flex min-h-48 flex-col items-center justify-center gap-3\">\n <span role=\"alert\" className=\"text-base text-po-red\">\n {state.error}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n Retry\n </Button>\n </div>\n ) : state.diff.binary ? (\n <EmptyState\n className=\"min-h-48\"\n title=\"Binary file\"\n description={`${entry.path} cannot be shown as a text diff.`}\n />\n ) : state.diff.tooLarge ? (\n <EmptyState\n className=\"min-h-48\"\n title=\"This diff is too large to show\"\n description=\"Other changed files are still available to review.\"\n />\n ) : (\n <DiffView\n hunks={state.diff.hunks}\n testId={`git-review-diff-${id}`}\n onSelect={onSelect}\n renderAfterRow={renderAfterRow}\n />\n )}\n </div>\n </section>\n );\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\n/**\n * The review tab: this session's changes against its base, the comments on\n * them, and the manual sync beside them.\n *\n * DESIGN PATTERNS:\n * - Opened from the '# diff' group as a transient tab, one per session.\n * - The hub's channel says when something changed (counts, base, a paused\n * rebase); the panel refetches the file list then, and each file's hunks\n * when it is opened. Nothing polls.\n * - Comments live in a session store and are cleared only after the host took\n * the message. Both messages go as `enqueue_automatic`, which queues behind a\n * running turn instead of failing.\n *\n * AVOID:\n * - Sending sync as a session frame. Sync is a channel command; the hub runs\n * it with the configured auth, one command per session.\n */\nimport { buildReviewPrompt } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { gitChanges, requestGitSync } from '../_lib/gitChangesStore';\nimport { fetchReviewFile, fetchReviewSummary } from '../_lib/gitReviewApi';\nimport { clearReviewComments, addReviewComment, gitReview, removeReviewComment } from '../_lib/gitReviewStore';\nimport { conflictPrompt, deliverToAgent, reviewHeading } from '../_lib/gitReviewView';\nimport { GitReviewView, type ReviewFileState, type ReviewSummaryState } from './GitReviewView';\n\nconst REVIEW_TAB_ID = 'git-review';\n\nexport function reviewTab(): TransientTab {\n return { id: REVIEW_TAB_ID, label: 'review', panel: GitReviewPanel };\n}\n\nexport function GitReviewPanel({ sessionId, sendSessionFrame }: WebPluginSlotProps) {\n const activity = useStore(gitChanges.store, (state) => gitChanges.select(state, sessionId));\n const comments = useStore(gitReview.store, (state) => gitReview.select(state, sessionId).comments);\n const [summary, setSummary] = useState<ReviewSummaryState>({ state: 'loading' });\n const [files, setFiles] = useState<Record<string, ReviewFileState | undefined>>({});\n const [sendError, setSendError] = useState<string>();\n const [dismissedError, setDismissedError] = useState<string>();\n const [draftSnapshot, setDraftSnapshot] = useState<{ sessionId: string | null; fingerprint: string }>();\n const changes = activity.changes;\n const generation = useRef(0);\n const pendingFiles = useRef(new Map<string, AbortController>());\n const readyGeneration = useRef(false);\n\n // What the hub reported, reduced to the facts that move the file list. A new\n // value means the list and every loaded hunk may be stale.\n const fingerprint = JSON.stringify([\n changes?.branch,\n changes?.base,\n changes?.added,\n changes?.removed,\n changes?.files,\n changes?.rebase?.conflicts.length,\n ]);\n // Keep the mounted draft input intact until it is submitted or cancelled.\n const refreshFingerprint = draftSnapshot?.sessionId === sessionId ? draftSnapshot.fingerprint : fingerprint;\n useEffect(() => {\n generation.current += 1;\n readyGeneration.current = false;\n const pending = pendingFiles.current;\n for (const request of pending.values()) request.abort();\n pending.clear();\n // Invalidate the visible snapshot while the external change notification is being reread.\n // eslint-disable-next-line react/set-state-in-effect\n setSummary({ state: 'loading' });\n setFiles({});\n setDraftSnapshot((current) => (current?.sessionId === sessionId ? current : undefined));\n if (sessionId === null) return;\n const controller = new AbortController();\n fetchReviewSummary(sessionId, controller.signal)\n .then((result) => {\n if (controller.signal.aborted) return;\n readyGeneration.current = result.ok;\n setSummary(result.ok ? { state: 'ready', summary: result.summary } : { state: 'error', error: result.error });\n setFiles({});\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n setSummary({\n state: 'error',\n error: error instanceof Error ? error.message : 'The changes could not be read.',\n });\n });\n return () => {\n controller.abort();\n generation.current += 1;\n readyGeneration.current = false;\n for (const request of pending.values()) request.abort();\n pending.clear();\n };\n }, [sessionId, refreshFingerprint]);\n\n const loadFile = useCallback(\n (path: string): void => {\n if (sessionId === null || !readyGeneration.current || pendingFiles.current.has(path)) return;\n const requestGeneration = generation.current;\n const controller = new AbortController();\n pendingFiles.current.set(path, controller);\n setFiles((current) => ({ ...current, [path]: { state: 'loading' } }));\n const settle = (state: ReviewFileState): void => {\n if (controller.signal.aborted || requestGeneration !== generation.current) return;\n setFiles((current) => ({ ...current, [path]: state }));\n };\n fetchReviewFile(sessionId, path, controller.signal)\n .then((result) =>\n settle(result.ok ? { state: 'ready', diff: result.diff } : { state: 'error', error: result.error }),\n )\n .catch((error: unknown) =>\n settle({ state: 'error', error: error instanceof Error ? error.message : 'The diff could not be read.' }),\n )\n .finally(() => {\n if (pendingFiles.current.get(path) === controller) pendingFiles.current.delete(path);\n });\n },\n [sessionId],\n );\n\n if (sessionId === null) return null;\n\n const branch = summary.state === 'ready' ? summary.summary.branch : changes?.branch;\n const base = summary.state === 'ready' ? summary.summary.base : changes?.base;\n const error = activity.error === dismissedError ? undefined : activity.error;\n\n const send = (message: string, onSent?: () => void): void => {\n const failure = deliverToAgent(sendSessionFrame, sessionId, message);\n setSendError(failure);\n if (failure === undefined) onSent?.();\n };\n\n return (\n <GitReviewView\n key={sessionId}\n onDraftChange={(open) =>\n setDraftSnapshot((current) =>\n open ? (current?.sessionId === sessionId ? current : { sessionId, fingerprint }) : undefined,\n )\n }\n sync={{\n ...(changes === undefined ? {} : { changes }),\n ...(activity.pending === undefined ? {} : { pending: activity.pending }),\n ...(error === undefined ? {} : { error }),\n ...(activity.errorTarget === undefined || error === undefined ? {} : { errorTarget: activity.errorTarget }),\n onSync: (action) => {\n if (\n action === 'abort-rebase' &&\n !window.confirm('Abort rebase? This discards conflict resolution in progress.')\n )\n return;\n requestGitSync(sessionId, action);\n },\n onForcePush: () => requestGitSync(sessionId, 'push', true),\n onAskAgent: () => send(conflictPrompt(branch, changes?.rebase?.conflicts ?? [])),\n onDismissError: () => setDismissedError(activity.error),\n }}\n summary={summary}\n files={files}\n comments={comments}\n onLoadFile={loadFile}\n onAddComment={(comment) => addReviewComment(sessionId, comment)}\n onRemoveComment={(id) => removeReviewComment(sessionId, id)}\n onSendReview={() =>\n send(buildReviewPrompt(comments, reviewHeading(comments.length, branch, base)), () =>\n clearReviewComments(sessionId),\n )\n }\n onDiscard={() => clearReviewComments(sessionId)}\n {...(sendError === undefined ? {} : { sendError })}\n />\n );\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\n/**\n * The '# git' group's branch row: this session's code change against its base.\n *\n * DESIGN PATTERNS:\n * - One lane, branch and `+A -R`, straight on the group body like every other\n * activity group: the dock already draws the card, so no inner card or heading.\n * Files, base, upstream and a paused rebase live in the review tab's header,\n * which this lane opens.\n * - Stays clickable at zero, because the review tab is also where pull, push\n * and rebase live.\n * - Reads the focused session's checkout, whether it is a worktree or not.\n *\n * AVOID:\n * - Doing work here. This section reports and opens the tab.\n */\nimport { Button, Spinner } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport { reviewTab } from '../../_components/GitReviewPanel';\nimport { gitChanges } from '../../_lib/gitChangesStore';\n\nexport function DiffActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {\n const session = useStore(gitChanges.store, (state) => gitChanges.select(state, sessionId));\n const changes = session.changes;\n\n if (sessionId === null || changes === undefined) return null;\n\n return (\n <DiffActivityView changes={changes} pending={session.pending} onReview={() => openTransientTab(reviewTab())} />\n );\n}\nexport function DiffActivityView({\n changes,\n pending,\n onReview,\n branch,\n}: {\n branch?: string;\n changes?: { branch?: string; base?: string; added: number; removed: number; files: number };\n pending?: string;\n onReview?: () => void;\n}) {\n const zero = changes?.added === 0 && changes?.removed === 0;\n const against = changes?.base === undefined ? 'uncommitted' : `vs ${changes.base}`;\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <Button\n variant=\"ghost\"\n size=\"card\"\n data-testid=\"activity-diff-changes\"\n className=\"min-w-0 flex-row items-center gap-2 rounded-md px-1 py-1 font-normal hover:bg-po-panel\"\n aria-label={\n changes\n ? `review ${changes.branch ?? 'detached HEAD'} changes: ${changes.added} added, ${changes.removed} removed ${against}`\n : 'Changes not reported yet'\n }\n title={changes ? `${changes.files} ${changes.files === 1 ? 'file' : 'files'} ${against}` : undefined}\n onClick={onReview}\n >\n <span className=\"min-w-0 flex-1 truncate text-left font-mono text-sm text-po-hi\">\n {changes?.branch ?? branch ?? 'detached HEAD'}\n </span>\n {!changes || zero ? (\n <span className=\"shrink-0 text-sm text-po-dim\">{zero ? 'No changes yet' : 'Not reported yet'}</span>\n ) : (\n <span className=\"flex shrink-0 gap-2 text-sm\">\n <span className=\"text-po-green\">+{changes.added}</span>\n <span className=\"text-po-red\">-{changes.removed}</span>\n </span>\n )}\n </Button>\n {pending && (\n <p className=\"flex items-center gap-2 px-1 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n </div>\n );\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport { ArrowRightIcon, Button, Spinner } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport type { WorktreeView } from '../../../../../../types/webWorktrees';\nimport { WorktreeRow, worktreesTab } from '../../_components/WorktreesPanel';\nimport { worktreeActivity, worktreeCreateDialog } from '../../_lib/worktreesActivityStore';\nimport { DiffActivitySection } from './DiffActivitySection';\n\nexport function WorktreesActivitySection(props: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, props.sessionId));\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <DiffActivitySection {...props} />\n <WorktreesActivityView\n worktrees={session.worktrees.filter((w) => w.sessionId !== props.sessionId)}\n pending={session.pending}\n onOpen={() => props.openTransientTab(worktreesTab())}\n onCreate={\n props.sessionId === null\n ? undefined\n : () =>\n worktreeCreateDialog.update(() => ({\n sessionId: props.sessionId!,\n ...(props.sessionReservationId === undefined ? {} : { reservationId: props.sessionReservationId }),\n }))\n }\n />\n </div>\n );\n}\nexport function WorktreesActivityView({\n worktrees,\n pending,\n onOpen,\n onCreate,\n startingIds = [],\n}: {\n worktrees: WorktreeView[];\n pending?: string;\n onOpen?: () => void;\n onCreate?: () => void;\n startingIds?: string[];\n}) {\n // The dock draws the group card and heading; this body sits straight on it, as Runners does.\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n {pending && (\n <p className=\"flex items-center gap-2 px-1 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n {/* The hub's progress label arrives lowercase. */}\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n {worktrees.length === 0 ? (\n onCreate ? (\n <Button\n variant=\"link\"\n size=\"sm\"\n data-testid=\"activity-git-create\"\n className=\"h-auto self-start gap-1 px-1 text-po-green\"\n onClick={onCreate}\n >\n Create a worktree\n <ArrowRightIcon aria-hidden className=\"size-3.5\" />\n </Button>\n ) : (\n <span data-testid=\"activity-summary-git\" className=\"px-1 text-sm text-po-dim\">\n Idle\n </span>\n )\n ) : (\n <div data-testid=\"activity-git-worktrees\">\n {worktrees.map((w) => (\n <Button\n key={w.id}\n variant=\"ghost\"\n size=\"card\"\n className=\"block w-full min-w-0 p-0 text-left font-normal\"\n data-testid={`activity-git-worktree-${w.id}`}\n onClick={onOpen}\n >\n <WorktreeRow\n compact\n worktree={w}\n starting={\n startingIds.includes(w.id) ||\n (!!pending?.includes('starting') && w.sessionId === null && !w.orphaned && !w.unowned)\n }\n />\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreesActivitySection } from './_components/WorktreesActivitySection';\n\nexport default defineFill({ component: WorktreesActivitySection });\n","import { defineLeaderBinding } from '@agimon-ai/po-core/web';\n\nimport { reviewTab } from '../_components/GitReviewPanel';\n\nexport default defineLeaderBinding({\n path: [\n // The shared g prefix must keep the existing Goal group's label.\n { key: 'g', label: 'goal' },\n { key: 'd', label: 'diff', detail: 'review this checkout’s changes' },\n ],\n run: (context) => context.openTransientTab(reviewTab()),\n});\n","import type { WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport { startGitChangesRuntime } from '../../_lib/gitChangesStore';\nimport { startWorktreeRuntime } from '../../_lib/worktreesActivityStore';\n\n/** Binds both hub channels' senders: worktrees, and this session's diff and sync. */\nexport default function startGitRuntime(runtime: WebPluginRuntime): () => void {\n const stopWorktrees = startWorktreeRuntime(runtime);\n const stopChanges = startGitChangesRuntime(runtime);\n return () => {\n stopChanges();\n stopWorktrees();\n };\n}\n","import { defineWebLifecycle } from '@agimon-ai/po-core/web';\n\nimport contribution from './_lib/start.web';\n\nexport default defineWebLifecycle(contribution);\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n Button,\n ChevronDownIcon,\n ChevronUpIcon,\n MessageItem,\n MessageItemBody,\n Spinner,\n StatusBadge,\n} from '@agimon-ai/po-web-components';\n\nconst VERBS: Readonly<Record<string, [string, string, string]>> = {\n spawn_worktree: ['is creating', 'created', 'create'],\n close_worktree: ['is closing', 'closed', 'close'],\n list: ['is listing', 'listed', 'list'],\n status: ['is checking', 'checked', 'check'],\n merge: ['is merging', 'merged', 'merge'],\n prune: ['is pruning', 'pruned', 'prune'],\n send: ['is messaging', 'messaged', 'message'],\n messages: ['is reading messages from', 'read messages from', 'read messages from'],\n};\nexport function RunWorktreeToolMessage({ args, output, running, isError }: ToolMessageRenderProps) {\n return (\n <RunWorktreeToolMessageView\n action={typeof args.action === 'string' ? args.action : ''}\n subject={typeof args.branch === 'string' ? args.branch : typeof args.id === 'string' ? args.id : ''}\n output={output}\n running={running}\n isError={isError}\n />\n );\n}\nexport function RunWorktreeToolMessageView({\n action,\n subject = '',\n output = '',\n running = false,\n isError = false,\n defaultExpanded = false,\n}: {\n action: string;\n subject?: string;\n output?: string;\n running?: boolean;\n isError?: boolean;\n defaultExpanded?: boolean;\n}) {\n const tone = running ? 'neutral' : isError ? 'error' : 'ok';\n const verbs = VERBS[action] ?? ['is running', 'finished', 'run'];\n const rows =\n action === 'list'\n ? output\n .split('\\n')\n .map((line) => line.split(/\\s{2,}/))\n .filter((parts) => parts.length >= 3)\n : [];\n const listingCount = output.match(/^(\\d+) worktree/);\n return (\n <MessageItem tone={tone} expandable defaultExpanded={defaultExpanded} className=\"bg-po-panel\">\n {({ expanded, toggle }) => (\n <>\n <div className=\"flex items-start gap-3 p-4\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-base font-semibold leading-relaxed text-po-hi\">\n Po {isError && !running ? `could not ${verbs[2]}` : verbs[running ? 0 : 1]}{' '}\n {action === 'list' && !running && !isError ? (\n `${listingCount?.[1] ?? rows.length} ${Number(listingCount?.[1] ?? rows.length) === 1 ? 'worktree' : 'worktrees'}`\n ) : subject ? (\n <span className=\"font-mono\">{subject}</span>\n ) : (\n 'worktrees'\n )}\n {running ? '...' : isError && output ? `: ${output.split('\\n')[0]}` : ''}\n </p>\n </div>\n <StatusBadge tone={tone} size=\"xs\" className={running ? 'gap-1 bg-po-rail text-po-dim' : ''}>\n {running && <Spinner className=\"size-3\" label=\"Running\" />}\n {running ? 'Running' : isError ? 'Failed' : 'Completed'}\n </StatusBadge>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={toggle} aria-expanded={expanded} className=\"mb-2 ml-3 text-po-dim\">\n Details {expanded ? <ChevronUpIcon className=\"size-3\" /> : <ChevronDownIcon className=\"size-3\" />}\n </Button>\n {expanded && (\n <MessageItemBody>\n {rows.length > 0 && !isError ? (\n <table className=\"w-full text-left text-sm\">\n <thead>\n <tr className=\"border-b border-po-border-soft\">\n <th className=\"pb-2 font-medium\">Branch</th>\n <th className=\"pb-2 font-medium\">Path</th>\n <th className=\"pb-2 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((parts, i) => {\n const real = parts.length >= 5;\n const status = parts[2];\n return (\n <tr key={i} className=\"border-b border-po-border-soft\">\n <td className=\"py-3 pr-3 font-mono text-po-text\">\n {real ? parts[1] : parts[0]}\n {real && <span className=\"mt-1 block text-po-dim\">{parts[0]}</span>}\n </td>\n <td className=\"py-3 pr-3 font-mono text-po-dim\">\n {real ? parts.slice(4).join(' ') : parts[1]}\n </td>\n <td>\n <StatusBadge\n tone={status === 'orphaned' ? 'neutral' : status === 'unowned' ? 'info' : 'ok'}\n size=\"xs\"\n className={status === 'orphaned' ? 'bg-po-tint-yellow text-po-yellow' : ''}\n >\n {/* The tool prints statuses lowercase; a badge is sentence case. */}\n <span className=\"inline-block first-letter:uppercase\">{status}</span>\n </StatusBadge>\n {real && <span className=\"ml-2 text-po-dim\">{parts[3]}</span>}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n ) : (\n <pre className={`whitespace-pre-wrap font-mono text-sm ${isError ? 'text-po-red' : 'text-po-dim'}`}>\n {output}\n </pre>\n )}\n </MessageItemBody>\n )}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { RunWorktreeToolMessage } from './_components/RunWorktreeToolMessage';\n\nexport default defineToolRenderer({ message: RunWorktreeToolMessage });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport fillGitNewSession from '../src/extensions/workspaces/(frontend)/fill/GitNewSession.new-session.web';\nimport repositorySettingsPanelGit from '../src/extensions/workspaces/(frontend)/repository-settings-panel/git.web';\nimport activityGroupGit from '../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web';\nimport channelGitChanges from '../src/extensions/workspaces/sessions/(frontend)/channel/gitChanges.web';\nimport channelGitWorktrees from '../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web';\nimport fillWorktree from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web';\nimport fillWorktreeCreate from '../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web';\nimport fillWorktrees from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web';\nimport leaderReview from '../src/extensions/workspaces/sessions/(frontend)/leader/review.web';\nimport lifecycleStart from '../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'git',\n workspace: {\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'new-session', id: 'git-new-session' }, fillGitNewSession)]; },\n get repositorySettingsPanel(): WebPluginContributions['repositorySettingsPanel'] { return repositorySettingsPanelGit; },\n },\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'git' }, activityGroupGit)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'git_changes' }, channelGitChanges), via({ channel: 'git_worktrees' }, channelGitWorktrees)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'session-menu', id: 'worktree' }, fillWorktree), via({ slot: 'overlay', id: 'worktree-create' }, fillWorktreeCreate), via({ slot: 'activity.git', id: 'worktrees' }, fillWorktrees)]; },\n get leaderBindings(): WebPluginContributions['leaderBindings'] { return [via({ id: 'git.review' }, leaderReview)]; },\n get start(): WebPluginContributions['start'] { return lifecycleStart; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['run_worktree'] }, toolRunWorktree)]; },\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"web.mjs","names":["formProblem","Field","formProblem","errorOf","loaded","isRecord","optionalText","optionalErrorTarget","isRecord","contribution","fillGitNewSession","repositorySettingsPanelGit","activityGroupGit","channelGitChanges","channelGitWorktrees","fillWorktree","fillWorktreeCreate","fillWorktrees","leaderReview","lifecycleStart","toolRunWorktree"],"sources":["../../src/types/apiRoutes.ts","../../generated/client.ts","../../src/extensions/workspaces/(frontend)/_lib/newSessionForm.ts","../../src/extensions/workspaces/(frontend)/fill/_components/GitNewSessionDialog.tsx","../../src/extensions/workspaces/(frontend)/fill/GitNewSession.new-session.web.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_lib/gitAuthForm.ts","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_components/GitAuthForm.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/_components/GitAuthPanel.tsx","../../src/extensions/workspaces/(frontend)/repository-settings-panel/git.web.tsx","../../src/types/webWorktrees.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/worktreesActivityStore.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreeCreateDialog.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/WorktreesPanel.tsx","../../src/types/gitReview.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitChangesStore.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitChanges.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewApi.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewStore.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewView.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewBrowser.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitSyncBar.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewView.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewPanel.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/DiffActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreesActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/leader/review.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/RunWorktreeToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web.tsx","../../generated/web.ts"],"sourcesContent":["import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { GitAuthView } from './gitAuth';\nimport type { GitReviewFileDiff, GitReviewSummary } from './gitReview';\nimport type { GitBranchesResponse, GitSessionCreated } from './gitSessions';\n\n/**\n * The routes the page calls, as data.\n *\n * No scope and no base path: the build reads both off\n * `src/extensions/(backend)/api/git/`, which mounts at global scope and so\n * answers workspace and session requests too. Each route answers only where it\n * belongs (auth on a workspace mount, the review on a session mount), so a\n * client accessor on the wrong scope gets a 404 rather than a second way in.\n *\n * Only what the browser calls is listed. The worktree routes stay HTTP for\n * other callers, but the dock drives worktrees over its channel.\n */\nconst routes = {\n /** Workspace: the new-session dialog's branch list. */\n branches: {\n method: 'GET',\n path: '/branches',\n response: undefined as unknown as ApiResponseOf<GitBranchesResponse>,\n },\n /** Workspace: a top-level worktree session on an existing or new branch. */\n createSession: {\n method: 'POST',\n path: '/sessions',\n response: undefined as unknown as ApiResponseOf<GitSessionCreated>,\n },\n /** Workspace: that workspace's saved remote auth, never the token itself. */\n auth: {\n method: 'GET',\n path: '/auth',\n query: ['repositoryId'],\n response: undefined as unknown as ApiResponseOf<GitAuthView>,\n },\n /** Workspace: replaces that workspace's remote auth. Passkey step-up gated for remote devices. */\n saveAuth: {\n method: 'PUT',\n path: '/auth',\n query: ['repositoryId'],\n response: undefined as unknown as ApiResponseOf<GitAuthView>,\n },\n /** Session: the files this session's checkout changed against its base. */\n review: {\n method: 'GET',\n path: '/review',\n response: undefined as unknown as ApiResponseOf<GitReviewSummary>,\n },\n /** Session: one changed file's hunks. */\n reviewFile: {\n method: 'GET',\n path: '/review/file',\n query: ['path'],\n response: undefined as unknown as ApiResponseOf<GitReviewFileDiff>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, sessionApiAddress } from '@agimon-ai/po-core/web';\nimport { browserTransport } from '@agimon-ai/po-web-security/browser';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'git' at. */\nexport const apiScopes = ['global', 'workspace', 'session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'git',\n transport: (input, init) => browserTransport.fetch(input, init),\n sessionAddress: sessionApiAddress,\n});\n","import type { GitBranches, GitSessionCreateRequest } from '../../../../types/gitSessions';\n\nexport type NewSessionMode = 'existing' | 'new' | 'plain';\n\n/** One row of the branch picker: a local branch, or a remote-only one. */\nexport interface BranchOption {\n key: string;\n name: string;\n remote?: string;\n current: boolean;\n /** Set when the branch is checked out elsewhere and cannot get a second worktree. */\n busyAt?: string;\n}\n\nexport interface NewSessionFormState {\n mode: NewSessionMode;\n /** The picked existing branch. */\n selected?: BranchOption;\n newBranch: string;\n baseRef: string;\n name: string;\n}\n\nconst MAX_LISTED = 200;\n\n/** Local branches first, then remote-only ones, filtered by a case-insensitive substring. */\nexport function branchOptions(branches: GitBranches, query: string): BranchOption[] {\n const needle = query.trim().toLowerCase();\n const matches = (text: string): boolean => needle === '' || text.toLowerCase().includes(needle);\n const local = branches.local\n .filter((branch) => matches(branch.name))\n .map((branch) => ({\n key: `local:${branch.name}`,\n name: branch.name,\n current: branch.name === branches.current,\n ...(branch.checkedOutAt === undefined ? {} : { busyAt: branch.checkedOutAt }),\n }));\n const remote = branches.remote\n .filter((branch) => matches(`${branch.remote}/${branch.name}`))\n .map((branch) => ({\n key: `remote:${branch.remote}/${branch.name}`,\n name: branch.name,\n remote: branch.remote,\n current: false,\n }));\n return [...local, ...remote].slice(0, MAX_LISTED);\n}\n\n/** Every base a new branch can start from: the default first, then remote-tracking names, then local branches. */\nexport function baseOptions(branches: GitBranches): string[] {\n const names = new Set([\n ...(branches.defaultBase === undefined ? [] : [branches.defaultBase]),\n ...branches.remote.map((branch) => `${branch.remote}/${branch.name}`),\n ...branches.local.map((branch) => branch.name),\n ]);\n return [...names];\n}\n\n/** Why the form cannot be submitted yet, or undefined when it can. */\nexport function formProblem(state: NewSessionFormState): string | undefined {\n if (state.mode === 'existing') {\n if (state.selected === undefined) return 'Pick a branch.';\n if (state.selected.busyAt !== undefined) return `That branch is checked out at ${state.selected.busyAt}.`;\n }\n if (state.mode === 'new' && state.newBranch.trim() === '') return 'Name the new branch.';\n return undefined;\n}\n\n/** The worktree create request for the form, or undefined in plain mode. */\nexport function createRequest(state: NewSessionFormState): GitSessionCreateRequest | undefined {\n const name = state.name.trim();\n const named = name === '' ? {} : { name };\n if (state.mode === 'existing' && state.selected !== undefined)\n return {\n mode: 'existing-branch',\n branch: state.selected.name,\n ...(state.selected.remote === undefined ? {} : { remote: state.selected.remote }),\n ...named,\n };\n if (state.mode === 'new') {\n const baseRef = state.baseRef.trim();\n return {\n mode: 'new-branch',\n branch: state.newBranch.trim(),\n ...(baseRef === '' ? {} : { baseRef }),\n ...named,\n };\n }\n return undefined;\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport {\n Button,\n CheckIcon,\n Dialog,\n DialogContent,\n DialogTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { api } from '../../../../../../generated/client';\nimport type { GitBranchesResponse, GitSessionCreated } from '../../../../../types/gitSessions';\nimport {\n baseOptions,\n branchOptions,\n createRequest,\n formProblem,\n type NewSessionFormState,\n type NewSessionMode,\n} from '../../_lib/newSessionForm';\n\nfunction Field({ label, children }: { label: ReactNode; children: ReactNode }) {\n return (\n <label className=\"flex flex-col gap-2 text-base text-po-text\">\n <span>{label}</span>\n {children}\n </label>\n );\n}\n\nexport interface GitNewSessionDialogViewProps {\n workspaceRoot: string;\n branches: GitBranchesResponse | null;\n loadError?: string;\n initialForm?: Partial<NewSessionFormState>;\n busy?: boolean;\n error?: string;\n onClose: () => void;\n onCreate: (form: NewSessionFormState) => void;\n}\n\n/** Inline presentation also lets story capture inspect content, rather than a portal-only root. */\nexport function GitNewSessionDialogView({\n workspaceRoot,\n branches,\n loadError = '',\n initialForm,\n busy = false,\n error = '',\n onClose,\n onCreate,\n}: GitNewSessionDialogViewProps) {\n const [form, setForm] = useState<NewSessionFormState>({\n mode: 'existing',\n newBranch: '',\n baseRef: branches?.defaultBase ?? '',\n name: '',\n ...initialForm,\n });\n const [query, setQuery] = useState('');\n const ready = branches?.repository === true && loadError === '';\n const loading = branches === null && loadError === '';\n const mode = ready || loading ? form.mode : 'plain';\n const state = { ...form, mode, baseRef: form.baseRef || branches?.defaultBase || '' };\n const problem = formProblem(state);\n const update = (patch: Partial<NewSessionFormState>): void => setForm((current) => ({ ...current, ...patch }));\n const options = branches === null ? [] : branchOptions(branches, query);\n const bases = branches === null ? [] : baseOptions(branches);\n const submit = (): void => {\n if (!busy && !loading && problem === undefined) onCreate(state);\n };\n return (\n <section\n data-testid=\"new-session-dialog\"\n aria-label=\"New session\"\n className=\"shrink-0 overflow-hidden rounded-lg border border-po-border bg-po-panel shadow-sm\"\n >\n <header className=\"border-b border-po-border-soft px-6 py-4\">\n <h3 className=\"text-xl font-semibold text-po-hi\">New session</h3>\n <p className=\"mt-1 font-mono text-sm text-po-dim\">{workspaceRoot}</p>\n </header>\n <div className=\"flex flex-col gap-5 p-6\">\n {!ready ? (\n <p data-testid=\"git-new-session-plain-note\" className=\"text-base text-po-dim\">\n {loading\n ? 'Reading branches...'\n : loadError || 'This workspace is not a git checkout. Start a plain session in this folder.'}\n </p>\n ) : (\n <Tabs\n value={mode}\n onValueChange={(value) => update({ mode: value as NewSessionMode })}\n className=\"flex flex-col gap-5\"\n >\n <TabsList aria-label=\"Session kind\" className=\"rounded-md border border-po-border-soft bg-po-bg p-1\">\n <TabsTrigger\n data-testid=\"git-new-session-mode-existing\"\n value=\"existing\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n Existing branch\n </TabsTrigger>\n <TabsTrigger\n data-testid=\"git-new-session-mode-new\"\n value=\"new\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n New branch\n </TabsTrigger>\n <TabsTrigger\n data-testid=\"git-new-session-mode-plain\"\n value=\"plain\"\n disabled={busy}\n className=\"flex-1 justify-center\"\n >\n No branch\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"existing\" className=\"flex flex-col gap-2\">\n <p className=\"text-base font-medium\">Branch</p>\n <Input\n data-testid=\"git-new-session-branch-search\"\n aria-label=\"Find a branch\"\n placeholder=\"Find a branch\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n disabled={busy}\n />\n <fieldset\n aria-label=\"Branches\"\n className=\"max-h-64 min-w-0 overflow-y-auto rounded-md border border-po-border-soft bg-po-bg p-1\"\n >\n {options.length === 0 ? <p className=\"px-3 py-2 text-sm text-po-dim\">No matching branches</p> : null}\n {options.map((branch, index) => (\n <div key={branch.key}>\n {branch.remote !== undefined && (index === 0 || options[index - 1]?.remote === undefined) ? (\n <p className=\"mt-1 border-t border-po-border-soft px-3 pt-2 text-sm text-po-dim\">\n Remote branches\n </p>\n ) : null}\n <button\n data-testid=\"git-new-session-branch-option\"\n data-branch={branch.name}\n data-remote={branch.remote}\n aria-pressed={form.selected?.key === branch.key}\n disabled={branch.busyAt !== undefined || busy}\n onClick={() => update({ selected: branch })}\n className={`flex w-full flex-col gap-1 rounded px-3 py-2 text-left text-base ${form.selected?.key === branch.key ? 'bg-po-tint-green text-po-green' : 'text-po-text'}`}\n >\n <span className=\"flex items-center justify-between gap-2\">\n <span className=\"font-mono\">\n {branch.remote === undefined ? branch.name : `${branch.remote}/${branch.name}`}\n </span>\n {form.selected?.key === branch.key ? <CheckIcon className=\"size-4\" /> : null}\n </span>\n {branch.busyAt !== undefined ? (\n <span className=\"text-sm text-po-dim\">\n Checked out in <span className=\"font-mono break-all\">{branch.busyAt}</span>\n </span>\n ) : branch.current ? (\n <span className=\"text-sm text-po-dim\">Current</span>\n ) : null}\n </button>\n </div>\n ))}\n </fieldset>\n </TabsContent>\n <TabsContent value=\"new\" className=\"flex flex-col gap-4\">\n <Field label=\"Branch name\">\n <Input\n data-testid=\"git-new-session-new-branch\"\n aria-label=\"Branch name\"\n placeholder=\"feature/my-change\"\n className=\"font-mono\"\n value={form.newBranch}\n onChange={(event) => update({ newBranch: event.target.value })}\n disabled={busy}\n />\n </Field>\n <Field label=\"From\">\n <Select\n value={form.baseRef || branches?.defaultBase || ''}\n onValueChange={(baseRef) => update({ baseRef })}\n disabled={busy}\n >\n <SelectTrigger data-testid=\"git-new-session-base\" aria-label=\"From\" className=\"font-mono\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {bases.map((base) => (\n <SelectItem key={base} value={base}>\n {base}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </TabsContent>\n <TabsContent value=\"plain\">\n <p className=\"text-base text-po-dim\">Start in this workspace folder, without creating a worktree.</p>\n </TabsContent>\n </Tabs>\n )}\n <Field\n label={\n <>\n Name{' '}\n <span className=\"text-sm text-po-dim\">\n {mode === 'plain' ? '(optional)' : '(optional, defaults to the branch)'}\n </span>\n </>\n }\n >\n <Input\n data-testid=\"new-session-name\"\n aria-label=\"Session name\"\n placeholder=\"Session name\"\n value={form.name}\n onChange={(event) => update({ name: event.target.value })}\n onKeyDown={(event) => {\n if (event.key === 'Enter') submit();\n }}\n disabled={busy}\n />\n </Field>\n {mode !== 'plain' ? (\n <p className=\"text-sm leading-relaxed text-po-dim\">\n Runs in its own worktree, so this checkout stays as it is.\n </p>\n ) : null}\n {error ? (\n <p\n data-testid=\"new-session-error\"\n role=\"alert\"\n className=\"rounded-md border border-po-edge-red bg-po-tint-red p-3 text-sm text-po-red\"\n >\n {error}\n </p>\n ) : null}\n </div>\n <footer className=\"flex items-center justify-between border-t border-po-border-soft px-6 py-4\">\n <Button data-testid=\"new-session-cancel\" variant=\"ghost\" disabled={busy} onClick={onClose}>\n Cancel\n </Button>\n <Button\n data-testid=\"new-session-create\"\n variant=\"primary\"\n title={problem}\n disabled={busy || loading || problem !== undefined}\n onClick={submit}\n >\n {busy ? (mode === 'plain' ? 'Creating session...' : 'Creating worktree...') : 'Create session'}\n </Button>\n </footer>\n </section>\n );\n}\n\nfunction errorOf(body: unknown, status: number): string {\n return typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : `The cockpit answered ${String(status)}.`;\n}\n\n/**\n * The new-session dialog when git is installed: a worktree on an existing or a\n * new branch, or a plain session in the workspace root. A worktree session\n * starts at the top level of the rail, with no parent.\n */\nexport function GitNewSessionDialog({ newSession }: WebPluginSlotProps) {\n const [branches, setBranches] = useState<GitBranchesResponse | null>(null);\n const [loadError, setLoadError] = useState('');\n const [error, setError] = useState('');\n const [busy, setBusy] = useState(false);\n const workspaceId = newSession?.workspaceId;\n const request = newSession?.requestWithStepUp;\n\n useEffect(() => {\n if (workspaceId === undefined || request === undefined) return;\n let stale = false;\n const url = api.workspace(workspaceId).branches.url();\n void request(url)\n .then(async (response) => {\n const body: unknown = await response.json().catch(() => undefined);\n if (stale) return;\n if (!response.ok) {\n setLoadError(errorOf(body, response.status));\n return;\n }\n const loaded = body as GitBranchesResponse;\n setBranches(loaded);\n })\n .catch(() => {\n if (!stale) setLoadError('The branches could not be loaded.');\n });\n return () => {\n stale = true;\n };\n }, [workspaceId, request]);\n\n if (newSession === undefined) return null;\n\n const submit = async (state: NewSessionFormState): Promise<void> => {\n if (busy || formProblem(state) !== undefined) return;\n setBusy(true);\n setError('');\n const body = createRequest(state);\n let failure: string | undefined;\n try {\n if (body === undefined) {\n failure = await newSession.createPlain(state.name);\n } else {\n const response = await newSession.requestWithStepUp(api.workspace(newSession.workspaceId).createSession.url(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const answer: unknown = await response.json().catch(() => undefined);\n failure = response.ok\n ? await newSession.openCreated((answer as GitSessionCreated).sessionId)\n : errorOf(answer, response.status);\n }\n } catch {\n failure = 'The cockpit is unreachable.';\n }\n if (failure === undefined) return;\n setError(failure);\n setBusy(false);\n };\n\n return (\n <Dialog\n open\n onOpenChange={(next) => {\n if (!next && !busy) newSession.close();\n }}\n >\n <DialogContent width=\"md\" className=\"overflow-y-auto p-0\" aria-describedby={undefined}>\n <DialogTitle className=\"sr-only\">New session</DialogTitle>\n <GitNewSessionDialogView\n workspaceRoot={newSession.workspaceRoot}\n branches={branches}\n loadError={loadError}\n busy={busy}\n error={error}\n onClose={newSession.close}\n onCreate={(state) => void submit(state)}\n />\n </DialogContent>\n </Dialog>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { GitNewSessionDialog } from './_components/GitNewSessionDialog';\n\nexport default defineFill({ component: GitNewSessionDialog });\n","import type { GitAuthMethod, GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\n\n/**\n * Pure form logic for a workspace's git auth panel: what the fields start as,\n * what is wrong with them, and what a save sends.\n *\n * The server validates again; this only keeps the page from sending what it\n * already knows will be refused, and says why in words next to the field.\n */\n\nexport const DEFAULT_HTTPS_HOST = 'github.com';\n\nexport interface GitAuthFormState {\n method: GitAuthMethod;\n keyPath: string;\n host: string;\n username: string;\n /** Never prefilled. Empty keeps the saved token when there is one for this host. */\n token: string;\n}\n\nexport function formFromView(view: GitAuthView): GitAuthFormState {\n return {\n method: view.method,\n keyPath: view.ssh?.keyPath ?? '',\n host: view.https?.host ?? DEFAULT_HTTPS_HOST,\n username: view.https?.username ?? '',\n token: '',\n };\n}\n\nconst HOST_PATTERN = /^[a-z0-9.-]{1,253}(:\\d{1,5})?$/u;\n/** Whether a value holds an ASCII control character; a newline in a credential field could add a line to git's credential protocol. */\nfunction hasControl(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code < 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\n/** Whether the saved token can stay: only when one exists and the host has not moved. */\nfunction keepsToken(form: GitAuthFormState, saved: GitAuthView): boolean {\n return saved.https?.hasToken === true && saved.https.host === form.host.trim().toLowerCase();\n}\n\n/** The first thing wrong with the form, in words, or undefined when it can be saved. */\nexport function formProblem(form: GitAuthFormState, saved: GitAuthView): string | undefined {\n if (form.method === 'ssh') {\n const keyPath = form.keyPath.trim();\n if (keyPath === '') return undefined;\n if (hasControl(keyPath)) return 'The key path has a control character in it.';\n if (!keyPath.startsWith('/') && !keyPath.startsWith('~/'))\n return 'Give the key as an absolute path or one under ~/.';\n return undefined;\n }\n if (form.method === 'https') {\n const host = form.host.trim().toLowerCase();\n if (!HOST_PATTERN.test(host)) return 'The host should look like github.com, with an optional :port.';\n if (form.username.trim() === '') return 'A username is required.';\n if (hasControl(form.username) || hasControl(form.token))\n return 'Remove the control character from the username or token.';\n if (form.token === '' && !keepsToken(form, saved)) {\n return saved.https?.hasToken === true\n ? 'The host changed, so enter the token for the new host.'\n : 'A token is required.';\n }\n }\n return undefined;\n}\n\n/** What a save sends. The token goes only when the reader typed one. */\nexport function saveRequestOf(form: GitAuthFormState): GitAuthSaveRequest {\n if (form.method === 'ssh') {\n const keyPath = form.keyPath.trim();\n return keyPath === '' ? { method: 'ssh' } : { method: 'ssh', keyPath };\n }\n if (form.method === 'https') {\n return {\n method: 'https',\n host: form.host.trim().toLowerCase(),\n username: form.username.trim(),\n ...(form.token === '' ? {} : { token: form.token }),\n };\n }\n return { method: 'none' };\n}\n","/**\n * A workspace's git remote panel body: how po-git reaches the remote when\n * you pull, push or rebase from this workspace's sessions in the cockpit.\n *\n * DESIGN PATTERNS:\n * - Per workspace. Worktree sessions use the setup of the workspace they\n * belong to. A workspace with nothing set uses this machine's own git.\n * - Three choices as cards, the way the tunnel picker offers them: this\n * machine's own git, an SSH key, or an HTTPS token. The fields a choice\n * needs follow in one card of form rows.\n * - The token is write-only. The field is never prefilled; a saved token shows\n * as a badge, and leaving the field empty keeps it.\n * - Form state is the reader's until they save. The owner remounts the form\n * after a save so it starts again from what the server now holds.\n *\n * AVOID:\n * - Echoing a token back. The view the server sends has none to echo.\n */\nimport {\n Button,\n CheckIcon,\n Input,\n SettingsActions,\n SettingsNote,\n SettingsSection,\n SettingsSectionDescription,\n SettingsSectionHeader,\n SettingsSectionTitle,\n ShieldIcon,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\n\nimport type { GitAuthMethod, GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\nimport { formFromView, formProblem, saveRequestOf, type GitAuthFormState } from '../_lib/gitAuthForm';\n\nfunction Field({ label, children }: { label: ReactNode; children: ReactNode }) {\n return (\n <label className=\"flex flex-col gap-2 text-base text-po-text\">\n <span>{label}</span>\n {children}\n </label>\n );\n}\n\nexport interface GitAuthFormProps {\n saved: GitAuthView;\n saving: boolean;\n saveError?: string;\n savedNotice?: boolean;\n onSave: (request: GitAuthSaveRequest) => void;\n}\nconst METHODS: readonly { method: GitAuthMethod; title: string; detail: string }[] = [\n { method: 'none', title: \"This machine's git\", detail: 'Your credential helper, SSH config and agent, as they are.' },\n { method: 'ssh', title: 'SSH key', detail: 'A key file on this machine, or your ssh-agent.' },\n { method: 'https', title: 'HTTPS token', detail: 'A username and personal access token for one host.' },\n];\n\nexport function GitAuthForm({ saved, saving, saveError, savedNotice = false, onSave }: GitAuthFormProps) {\n const [form, setForm] = useState<GitAuthFormState>(() => formFromView(saved));\n const [edited, setEdited] = useState(false);\n const update = (patch: Partial<GitAuthFormState>): void => {\n setEdited(true);\n setForm((current) => ({ ...current, ...patch }));\n };\n const problem = formProblem(form, saved);\n const tokenSaved = saved.https?.hasToken === true && saved.https.host === form.host.trim().toLowerCase();\n const host = form.host.trim() === '' ? 'this host' : form.host.trim();\n return (\n <SettingsSection data-testid=\"git-auth-form\">\n <SettingsSectionHeader>\n <SettingsSectionTitle>Connection</SettingsSectionTitle>\n <SettingsSectionDescription>\n Worktree sessions use the setup of the workspace they belong to.\n </SettingsSectionDescription>\n </SettingsSectionHeader>\n <div aria-label=\"How git reaches your remote\" className=\"flex flex-col gap-3\">\n {METHODS.map((choice) => (\n <div\n key={choice.method}\n className={`overflow-hidden rounded-lg border ${form.method === choice.method ? 'border-po-green' : 'border-po-border-soft'}`}\n >\n <button\n type=\"button\"\n aria-pressed={form.method === choice.method}\n disabled={saving}\n data-testid={`git-auth-method-${choice.method}`}\n onClick={() => update({ method: choice.method })}\n className={`flex w-full items-start gap-3 p-4 text-left ${form.method === choice.method ? 'bg-po-tint-green' : 'bg-po-bg'}`}\n >\n <span className=\"flex flex-1 flex-col gap-1\">\n <span className=\"text-base font-semibold text-po-hi\">{choice.title}</span>\n <span className=\"text-sm leading-relaxed text-po-dim\">{choice.detail}</span>\n </span>\n {form.method === choice.method ? <CheckIcon className=\"mt-0.5 size-4 shrink-0 text-po-green\" /> : null}\n </button>\n {form.method === choice.method && form.method === 'ssh' ? (\n <div className=\"flex flex-col gap-3 border-t border-po-border-soft p-4\">\n <Field label=\"Key path\">\n <Input\n data-testid=\"git-auth-key-path\"\n value={form.keyPath}\n placeholder=\"~/.ssh/id_ed25519\"\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ keyPath: event.target.value })}\n className=\"font-mono\"\n />\n </Field>\n <p className=\"text-sm leading-relaxed text-po-dim\">\n Leave blank to use SSH config and ssh-agent. Passphrases need ssh-agent. Trust an unknown host in a\n terminal first.\n </p>\n </div>\n ) : null}\n {form.method === choice.method && form.method === 'https' ? (\n <div className=\"flex flex-col gap-4 border-t border-po-border-soft p-4\">\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Host\">\n <Input\n data-testid=\"git-auth-host\"\n value={form.host}\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ host: event.target.value })}\n className=\"font-mono\"\n />\n </Field>\n <Field label=\"Username\">\n <Input\n data-testid=\"git-auth-username\"\n value={form.username}\n autoComplete=\"username\"\n spellCheck={false}\n disabled={saving}\n onChange={(event) => update({ username: event.target.value })}\n />\n </Field>\n </div>\n <Field\n label={\n <>\n Token{' '}\n {tokenSaved ? (\n <span data-testid=\"git-auth-token-saved\" className=\"ml-2 text-sm text-po-green\">\n A token is saved\n </span>\n ) : null}\n </>\n }\n >\n <Input\n data-testid=\"git-auth-token\"\n type=\"password\"\n value={form.token}\n autoComplete=\"new-password\"\n placeholder={tokenSaved ? 'Leave blank to keep it' : 'Personal access token'}\n disabled={saving}\n onChange={(event) => update({ token: event.target.value })}\n />\n </Field>\n <p className=\"text-sm text-po-dim\">\n Sent only to <span className=\"font-mono\">{host}</span>. Other hosts use this machine's git.\n </p>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n <SettingsNote className=\"flex items-start gap-2 leading-relaxed\">\n <ShieldIcon aria-hidden className=\"mt-0.5 size-4 shrink-0\" />\n <span>\n Only cockpit pull, push and rebase use these credentials, not the agent.\n <br />\n Stored in <span className=\"font-mono\">~/.po/git/credentials.json</span>, readable only by you.\n </span>\n </SettingsNote>\n <SettingsActions className=\"gap-4\">\n <Button\n variant=\"primary\"\n data-testid=\"git-auth-save\"\n disabled={problem !== undefined || saving}\n loading={saving}\n loadingLabel=\"Saving...\"\n onClick={() => {\n if (!saving && problem === undefined) onSave(saveRequestOf(form));\n }}\n >\n Save connection\n </Button>\n {savedNotice && !edited && problem === undefined && saveError === undefined ? (\n <span data-testid=\"git-auth-saved\" className=\"text-sm text-po-green\">\n Saved.\n </span>\n ) : null}\n </SettingsActions>\n {problem !== undefined ? (\n <p data-testid=\"git-auth-problem\" className=\"text-sm text-po-red\">\n {problem}\n </p>\n ) : null}\n {saveError !== undefined ? (\n <p role=\"alert\" data-testid=\"git-auth-error\" className=\"text-sm text-po-red\">\n {saveError}\n </p>\n ) : null}\n </SettingsSection>\n );\n}\n","import type { RepositorySettingsPanelProps } from '@agimon-ai/po-core/web';\n/**\n * A workspace's git remote panel: loads that workspace's saved auth and saves a\n * new one. Lives under settings, in the repository section the host scopes.\n *\n * DESIGN PATTERNS:\n * - Per workspace. The host hands the selected repository; its opaque id is\n * the only thing sent, and the hub resolves it to an admitted root. A\n * browser never names a path.\n * - Reads through the host's sealed request and writes through its step-up\n * request, so a remote device proves itself with a passkey before it can\n * change credentials. The URLs come from the generated client.\n * - After a save the form remounts from what the server returned, which is how\n * the token field empties and the \"token saved\" badge appears.\n */\nimport {\n Button,\n SettingsCard,\n SettingsRow,\n SettingsRowDescription,\n SettingsRowText,\n SettingsRowTitle,\n Spinner,\n} from '@agimon-ai/po-web-components';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { api } from '../../../../../../generated/client';\nimport type { GitAuthSaveRequest, GitAuthView } from '../../../../../types/gitAuth';\nimport { GitAuthForm } from './GitAuthForm';\n\nfunction isAuthView(value: unknown): value is GitAuthView {\n return (\n typeof value === 'object' &&\n value !== null &&\n ['none', 'ssh', 'https'].includes(String((value as { method?: unknown }).method))\n );\n}\n\nfunction errorOf(body: unknown, status: number): string {\n return typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : `The cockpit answered ${String(status)}.`;\n}\n\n/** The one-row card every non-form state of this panel is told in. */\nfunction StateCard({\n testId,\n title,\n children,\n action,\n}: {\n testId: string;\n title: string;\n children: ReactNode;\n action?: ReactNode;\n}) {\n return (\n <SettingsCard data-testid={testId}>\n <SettingsRow>\n <SettingsRowText>\n <SettingsRowTitle>{title}</SettingsRowTitle>\n <SettingsRowDescription>{children}</SettingsRowDescription>\n </SettingsRowText>\n {action}\n </SettingsRow>\n </SettingsCard>\n );\n}\n\nexport function GitAuthPanel({ repository, request, requestWithStepUp }: RepositorySettingsPanelProps) {\n const repositoryId = repository?.id;\n const [loaded, setLoaded] = useState<{ repositoryId: string; saved: GitAuthView }>();\n const [loadError, setLoadError] = useState<{ repositoryId: string; error: string }>();\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string>();\n const [savedNotice, setSavedNotice] = useState(false);\n const [generation, setGeneration] = useState(0);\n const [attempt, setAttempt] = useState(0);\n\n useEffect(() => {\n if (repositoryId === undefined) return;\n let stale = false;\n request(api.workspace(repositoryId).auth.url({ query: { repositoryId } }))\n .then(async (response) => {\n const body: unknown = await response.json().catch(() => undefined);\n if (stale) return;\n if (response.ok && isAuthView(body)) setLoaded({ repositoryId, saved: body });\n else setLoadError({ repositoryId, error: errorOf(body, response.status) });\n })\n .catch(() => {\n if (!stale) setLoadError({ repositoryId, error: 'The cockpit is unreachable.' });\n });\n return () => {\n stale = true;\n };\n }, [repositoryId, request, attempt]);\n\n if (repository === null || repositoryId === undefined) {\n return (\n <StateCard testId=\"git-auth-no-repository\" title=\"No repository picked\">\n Git remote access is set per workspace. Pick one above.\n </StateCard>\n );\n }\n\n const save = async (next: GitAuthSaveRequest): Promise<void> => {\n setSaving(true);\n setSaveError(undefined);\n setSavedNotice(false);\n try {\n const response = await requestWithStepUp(api.workspace(repositoryId).saveAuth.url({ query: { repositoryId } }), {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(next),\n });\n const body: unknown = await response.json().catch(() => undefined);\n if (response.ok && isAuthView(body)) {\n setLoaded({ repositoryId, saved: body });\n setGeneration((current) => current + 1);\n setSavedNotice(true);\n } else {\n setSaveError(errorOf(body, response.status));\n }\n } catch {\n setSaveError('The cockpit is unreachable.');\n } finally {\n setSaving(false);\n }\n };\n\n if (loadError?.repositoryId === repositoryId) {\n return (\n <div role=\"alert\" data-testid=\"git-auth-load-error\">\n <StateCard\n testId=\"git-auth-load-error-card\"\n title=\"Po couldn't read this workspace's git settings just now\"\n action={\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setLoadError(undefined);\n setAttempt((current) => current + 1);\n }}\n >\n Try again\n </Button>\n }\n >\n {loadError.error} Nothing has changed.\n </StateCard>\n </div>\n );\n }\n if (loaded?.repositoryId !== repositoryId) {\n return (\n <StateCard testId=\"git-auth-loading\" title=\"Reading git settings\">\n <span className=\"inline-flex items-center gap-2\">\n <Spinner className=\"size-3 text-po-faint\" label=\"Loading git settings\" />\n This takes a moment.\n </span>\n </StateCard>\n );\n }\n return (\n <GitAuthForm\n key={`${repositoryId}-${String(generation)}`}\n saved={loaded.saved}\n saving={saving}\n savedNotice={savedNotice}\n onSave={(next) => void save(next)}\n {...(saveError === undefined ? {} : { saveError })}\n />\n );\n}\n","import { defineRepositorySettingsPanel } from '@agimon-ai/po-core/web';\n\nimport { GitAuthPanel } from './_components/GitAuthPanel';\n\nexport default defineRepositorySettingsPanel({\n label: 'Git remote',\n detail: \"How this workspace's sessions reach the remote when you pull, push or rebase from the cockpit.\",\n order: 50,\n component: GitAuthPanel,\n});\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The dock's view of this session's worktrees, and the commands it sends.\n *\n * DESIGN PATTERNS:\n * - Session-scoped store fed by one hub channel. The hub is authoritative; the\n * page never reads a registry and never guesses.\n * - Actions are channel frames, not prompts. The hub half owns the tool's\n * operations, so the panel names the work and the hub performs it; a\n * worktree made from the dock is the same object the tool makes, without\n * spending a turn of the conversation to ask for it.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - Calling the hub package API from here. A dock slot gets no sealed request\n * transport, and raw fetch breaks the remote cockpit.\n * - `sendSessionFrame` for a command. It envelopes the frame as a session\n * command bound for the agent, which never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../../types/webWorktrees';\n\nexport interface WorktreesSession {\n /** The worktrees the hub last reported for this session's repository. */\n worktrees: WorktreeView[];\n /** Label of the operation the hub is running for this session. */\n pending: string | undefined;\n /** The last failure the hub reported, shown until the next command. */\n error: string | undefined;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n\nexport const worktreeActivity = defineSessionStore<WorktreesSession>({\n worktrees: [],\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** Captures the clicked card, so a focus change cannot retarget an open dialog. */\nexport const worktreeCreateDialog = defineGlobalStore<{ sessionId: string; reservationId?: string } | null>(null);\n/**\n * The page's hub socket sender, held for as long as the plugin runs.\n *\n * Undefined before `startWorktreeRuntime` and after it disposes; a command\n * sent in that window is dropped rather than queued, because a queue would\n * replay a worktree create against a socket that has since changed sessions.\n */\nconst worktreeSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket. The plugin host calls this once per page. */\nexport function startWorktreeRuntime(runtime: WebPluginRuntime): () => void {\n // Wrapped rather than referenced: an unbound method would lose the runtime\n // it belongs to the moment the store hands it back.\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n worktreeSender.update(() => send);\n return () => {\n worktreeSender.update((current) => (current === send ? undefined : current));\n worktreeCreateDialog.update(() => null);\n };\n}\n\n/**\n * Whether this session has worktree work in flight.\n *\n * A standing worktree is state, not work: it sits there until someone closes\n * it, so counting it would leave the session reading as busy forever, with a\n * \"background work is still running\" notice under a conversation where\n * nothing is running. Only a create or close actually in progress counts.\n *\n * The group stays visible either way. Declaring an active source at all is\n * what keeps it in the dock; this answers how it is drawn, not whether it is\n * there.\n */\nexport const worktreeActivitySource = {\n subscribe(listener: () => void) {\n const subscription = worktreeActivity.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return worktreeActivity.select(worktreeActivity.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction optionalErrorTarget(value: unknown): WorktreeErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'create') return { action: 'create' };\n if (value.action === 'close' && typeof value.id === 'string' && value.id !== '') {\n return { action: 'close', id: value.id };\n }\n return undefined;\n}\n\n/** The plugin's session data channel: 'git_worktrees' payloads into the store. */\nexport const worktreesChannel = worktreeActivity.channel<WorktreesSession>({\n channel: GIT_WORKTREES_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.worktrees)) return null;\n return {\n worktrees: input.worktrees.filter(isRecord) as unknown as WorktreeView[],\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/** Sends one command to the session's worktrees channel. */\nfunction command(sessionId: string, payload: GitWorktreesCommand): void {\n worktreeSender.store.state?.({ type: GIT_WORKTREES_TYPE, sessionId, payload });\n}\n\n/** Asks the hub for a worktree. The hub answers on the same channel. */\nexport function requestWorktreeCreate(\n sessionId: string,\n branch: string,\n baseRef: string,\n reservationId?: string,\n): void {\n const trimmedBase = baseRef.trim();\n command(sessionId, {\n action: 'create',\n branch: branch.trim(),\n ...(trimmedBase === '' ? {} : { baseRef: trimmedBase }),\n ...(reservationId === undefined ? {} : { reservationId }),\n });\n}\n\n/** Asks the hub to close one worktree. Refusal on a dirty tree stays the hub's call. */\nexport function requestWorktreeClose(sessionId: string, id: string): void {\n command(sessionId, { action: 'close', id });\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport {\n Dialog,\n Button,\n Input,\n Spinner,\n DialogContent,\n DialogTitle,\n DropdownMenuItem,\n} from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useId, useRef, useState } from 'react';\n\nimport {\n requestWorktreeCreate,\n worktreeActivity,\n worktreeCreateDialog,\n worktreesChannel,\n} from '../../_lib/worktreesActivityStore';\n\nexport function WorktreeSessionMenu({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n return (\n <DropdownMenuItem\n disabled={sessionId === null}\n data-testid={`session-worktree-${sessionReservationId ?? sessionId}`}\n onSelect={() => {\n if (sessionId !== null)\n worktreeCreateDialog.update(() => ({\n sessionId,\n ...(sessionReservationId === undefined ? {} : { reservationId: sessionReservationId }),\n }));\n }}\n >\n Create worktree session...\n </DropdownMenuItem>\n );\n}\n\nexport function WorktreeCreateOverlay(props: WebPluginSlotProps) {\n const target = useStore(worktreeCreateDialog.store);\n const { holdSessionChannels } = props;\n useEffect(() => {\n if (target === null) return;\n return holdSessionChannels?.(target.sessionId, (frame) => {\n if (frame.type !== worktreesChannel.channel) return;\n const payload = worktreesChannel.parse(frame.payload);\n if (payload !== null) worktreesChannel.apply(target.sessionId, payload);\n });\n }, [target, holdSessionChannels]);\n if (target === null) return null;\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) worktreeCreateDialog.update(() => null);\n }}\n >\n <DialogContent\n width=\"md\"\n className=\"w-96 overflow-y-auto border-0\"\n data-testid=\"session-worktree-dialog\"\n aria-describedby={undefined}\n >\n <DialogTitle className=\"sr-only\">Create a worktree session</DialogTitle>\n <WorktreeCreateForm\n {...props}\n key={`${target.sessionId}:${target.reservationId ?? ''}`}\n sessionId={target.sessionId}\n sessionReservationId={target.reservationId}\n onCancel={() => worktreeCreateDialog.update(() => null)}\n onCreated={() => worktreeCreateDialog.update(() => null)}\n />\n </DialogContent>\n </Dialog>\n );\n}\n\nexport function WorktreeCreateForm({\n sessionId,\n sessionReservationId,\n onCancel,\n onRequested,\n onCreated,\n}: WebPluginSlotProps & {\n onCancel: () => void;\n onRequested?: (branch: string) => void;\n /** Called once the hub finishes this form's request without a create error. */\n onCreated?: () => void;\n}) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n const [branch, setBranch] = useState('');\n const [baseRef, setBaseRef] = useState('');\n // The hub owns `pending`; a request is done once it was seen and cleared, or its record arrived.\n const sent = useRef<{ branch: string; sawPending: boolean } | undefined>(undefined);\n useEffect(() => {\n const request = sent.current;\n if (request === undefined) return;\n if (session.pending !== undefined) {\n request.sawPending = true;\n return;\n }\n const arrived = session.worktrees.some((worktree) => worktree.branch === request.branch);\n if (!arrived && !request.sawPending) return;\n sent.current = undefined;\n if (session.errorTarget?.action !== 'create') onCreated?.();\n }, [session.pending, session.worktrees, session.errorTarget, onCreated]);\n return (\n <WorktreeCreateView\n branch={branch}\n baseRef={baseRef}\n onBranchChange={setBranch}\n onBaseChange={setBaseRef}\n busy={session.pending !== undefined}\n error={session.errorTarget?.action === 'create' ? session.error : undefined}\n onCancel={onCancel}\n onCreate={() => {\n if (sessionId !== null) {\n sent.current = { branch: branch.trim(), sawPending: false };\n onRequested?.(branch.trim());\n requestWorktreeCreate(sessionId, branch, baseRef, sessionReservationId);\n }\n }}\n disabled={sessionId === null}\n />\n );\n}\nexport function WorktreeCreateView({\n branch,\n baseRef,\n onBranchChange,\n onBaseChange,\n busy = false,\n error,\n onCancel,\n onCreate,\n disabled = false,\n}: {\n branch: string;\n baseRef: string;\n onBranchChange?: (value: string) => void;\n onBaseChange?: (value: string) => void;\n busy?: boolean;\n error?: string;\n onCancel?: () => void;\n onCreate?: () => void;\n disabled?: boolean;\n}) {\n const id = useId();\n return (\n <div className=\"rounded-lg border border-po-border-soft bg-po-panel p-5 text-po-text shadow-sm\">\n <h2 id={`${id}-title`} className=\"text-xl font-semibold text-po-hi\">\n Create a worktree session\n </h2>\n <p className=\"mt-2 text-sm leading-relaxed text-po-dim\">\n Create a separate checkout and session without moving your existing sessions.\n </p>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n if (!busy && !disabled && branch.trim()) onCreate?.();\n }}\n >\n <div className=\"mt-5 flex flex-col gap-4\">\n <div className=\"flex flex-col gap-2\">\n <label htmlFor={`${id}-branch`} className=\"text-base font-medium\">\n Branch\n </label>\n <Input\n id={`${id}-branch`}\n data-testid=\"git-worktree-branch\"\n className=\"font-mono\"\n placeholder=\"wt/fix-auth\"\n value={branch}\n onChange={(e) => onBranchChange?.(e.target.value)}\n disabled={busy}\n aria-invalid={!!error}\n aria-describedby={error ? `${id}-error` : undefined}\n />\n {error && (\n <p id={`${id}-error`} role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-sm text-po-red\">\n {error}\n </p>\n )}\n </div>\n <div className=\"flex flex-col gap-2\">\n <label htmlFor={`${id}-base`} className=\"text-base font-medium\">\n Start from\n </label>\n <Input\n size=\"sm\"\n id={`${id}-base`}\n data-testid=\"git-worktree-base\"\n className=\"font-mono\"\n placeholder=\"Current branch\"\n value={baseRef}\n onChange={(e) => onBaseChange?.(e.target.value)}\n disabled={busy}\n />\n </div>\n </div>\n <footer className=\"mt-5 flex items-center justify-end gap-2 border-t border-po-border-soft pt-4\">\n <Button type=\"button\" variant=\"ghost\" disabled={busy} onClick={onCancel}>\n Cancel\n </Button>\n <Button\n type=\"submit\"\n variant=\"primary\"\n data-testid=\"git-worktree-create\"\n disabled={busy || disabled || !branch.trim()}\n >\n {busy && <Spinner className=\"size-3\" label=\"Creating worktree\" />}\n {busy ? 'Creating worktree...' : 'Create worktree'}\n </Button>\n </footer>\n </form>\n </div>\n );\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport { Button, Dot, EmptyState, Spinner, StatusBadge } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport type { WorktreeView } from '../../../../../types/webWorktrees';\nimport { requestWorktreeClose, worktreeActivity } from '../_lib/worktreesActivityStore';\nimport { WorktreeCreateForm } from '../fill/_components/WorktreeCreateDialog';\n\nexport function worktreesTab(): TransientTab {\n return { id: 'git-worktrees', label: 'worktrees', panel: WorktreesPanel };\n}\nexport function WorktreesPanel(props: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, props.sessionId));\n const [creating, setCreating] = useState(session.errorTarget?.action === 'create');\n const [requestedBranch, setRequestedBranch] = useState<string>();\n const sawPending = useRef(false);\n useEffect(() => {\n if (!requestedBranch) return;\n if (\n session.worktrees.some((w) => w.branch === requestedBranch) ||\n (sawPending.current && session.pending === undefined)\n ) {\n setRequestedBranch(undefined);\n } else if (session.pending !== undefined) {\n sawPending.current = true;\n }\n }, [requestedBranch, session.pending, session.worktrees]);\n return (\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <WorktreesPanelView\n worktrees={session.worktrees}\n pending={session.pending}\n startingBranch={\n session.pending === undefined || session.worktrees.some((w) => w.branch === requestedBranch)\n ? undefined\n : requestedBranch\n }\n error={session.errorTarget?.action === 'create' && creating ? undefined : session.error}\n closeErrorId={session.errorTarget?.action === 'close' ? session.errorTarget.id : undefined}\n onNew={() => setCreating(true)}\n onClose={props.sessionId === null ? undefined : (id) => requestWorktreeClose(props.sessionId!, id)}\n form={\n creating ? (\n <WorktreeCreateForm\n {...props}\n onCancel={() => setCreating(false)}\n onCreated={() => setCreating(false)}\n onRequested={(branch) => {\n sawPending.current = false;\n setRequestedBranch(branch);\n }}\n />\n ) : undefined\n }\n />\n </div>\n );\n}\nexport function WorktreesPanelView({\n worktrees,\n pending,\n error,\n closeErrorId,\n onNew,\n onClose,\n form,\n startingIds = [],\n startingBranch,\n}: {\n worktrees: WorktreeView[];\n pending?: string;\n error?: string;\n closeErrorId?: string;\n onNew?: () => void;\n onClose?: (id: string) => void;\n form?: ReactNode;\n startingIds?: string[];\n startingBranch?: string;\n}) {\n const groups = [worktrees.filter((w) => !w.orphaned && !w.unowned), worktrees.filter((w) => w.orphaned || w.unowned)];\n return (\n <div data-testid=\"git-worktrees-panel\" className=\"rounded-lg border border-po-border-soft bg-po-panel p-5\">\n <header className=\"flex items-center justify-between gap-4 border-b border-po-border-soft pb-4\">\n <h2 className=\"text-lg font-semibold text-po-hi\">Worktrees</h2>\n <span data-testid=\"git-worktrees-count\" className=\"sr-only\">\n {worktrees.length === 0 ? 'none yet' : `${worktrees.length} open`}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={onNew}>\n New worktree\n </Button>\n </header>\n {form}\n {/* The starting row already says it; the hub's label arrives lowercase, so raise its first letter. */}\n {pending && !startingBranch && (\n <p data-testid=\"git-worktree-pending\" className=\"flex items-center gap-2 pt-3 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n {error && (!closeErrorId || !worktrees.some((w) => w.id === closeErrorId)) && (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-sm text-po-red\">\n {error}\n </p>\n )}\n {worktrees.length === 0 && !startingBranch ? (\n <EmptyState\n data-testid=\"git-worktrees-empty\"\n className=\"py-10\"\n title=\"No worktrees yet\"\n description=\"A worktree gives a branch its own checkout and a session nested under this one.\"\n />\n ) : (\n <div data-testid=\"git-worktrees-list\">\n {groups.map(\n (group, i) =>\n (group.length > 0 || (i === 0 && startingBranch)) && (\n <section key={i}>\n <h3 className=\"flex items-center gap-2 pt-5 text-lg font-semibold text-po-hi\">\n {i === 0 ? 'Working' : 'Needs a look'}{' '}\n <span className=\"text-sm font-normal text-po-dim\">\n {group.length + (i === 0 && startingBranch ? 1 : 0)} open\n </span>\n </h3>\n {i === 1 && (\n <p className=\"pt-2 text-sm leading-relaxed text-po-dim\">\n {group.length === 2\n ? 'Two worktrees'\n : group.length === 1\n ? 'One worktree'\n : `${group.length} worktrees`}{' '}\n would like your eye, whenever you are ready.\n </p>\n )}\n {i === 0 && startingBranch && (\n <div\n data-testid=\"git-worktree-starting\"\n className=\"flex min-w-0 flex-col gap-2 border-b border-po-border-soft py-4\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Spinner className=\"size-3 shrink-0 text-po-dim\" label=\"Starting session\" />\n <span className=\"min-w-0 flex-1 truncate font-mono text-base font-medium text-po-hi\">\n {startingBranch}\n </span>\n </div>\n <p className=\"pl-4 text-sm text-po-dim\">Starting session...</p>\n </div>\n )}\n {group.map((w) => (\n <WorktreeRow\n key={w.id}\n worktree={w}\n starting={\n startingIds.includes(w.id) ||\n (!!pending?.includes('starting') && w.sessionId === null && !w.orphaned && !w.unowned)\n }\n disabled={!!pending || !onClose}\n onClose={() => onClose?.(w.id)}\n error={closeErrorId === w.id ? error : undefined}\n />\n ))}\n </section>\n ),\n )}\n </div>\n )}\n </div>\n );\n}\nexport function WorktreeBadge({ worktree }: { worktree: WorktreeView }) {\n if (worktree.orphaned)\n return (\n <StatusBadge tone=\"neutral\" size=\"xs\" className=\"bg-po-tint-yellow text-po-yellow\">\n Orphaned\n </StatusBadge>\n );\n if (worktree.unowned)\n return (\n <StatusBadge tone=\"info\" size=\"xs\">\n Unowned\n </StatusBadge>\n );\n return null;\n}\n\nexport function WorktreeRow({\n worktree,\n compact = false,\n starting = false,\n error,\n disabled = false,\n onClose,\n}: {\n worktree: WorktreeView;\n compact?: boolean;\n starting?: boolean;\n error?: string;\n disabled?: boolean;\n onClose?: () => void;\n}) {\n return (\n <div\n data-testid={`git-worktree-${worktree.id}`}\n className={\n compact ? 'flex min-w-0 flex-col gap-1 py-2' : 'flex min-w-0 flex-col gap-2 border-b border-po-border-soft py-4'\n }\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {starting ? (\n <Spinner className=\"size-3 shrink-0 text-po-dim\" label=\"Starting session\" />\n ) : (\n <Dot size=\"md\" tone={worktree.orphaned ? 'yellow' : worktree.unowned ? 'blue' : 'green'} />\n )}\n <span title={worktree.branch} className=\"min-w-0 flex-1 truncate font-mono text-base font-medium text-po-hi\">\n {worktree.branch}\n </span>\n <WorktreeBadge worktree={worktree} />\n {!compact && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClose}\n disabled={starting || disabled}\n data-testid={`git-worktree-close-${worktree.id}`}\n aria-label={`Close ${worktree.branch}`}\n >\n Close\n </Button>\n )}\n </div>\n {!compact && (\n <p className=\"truncate pl-4 font-mono text-sm text-po-dim\" title={worktree.path}>\n {worktree.path}\n </p>\n )}\n {starting && <p className=\"pl-4 text-sm text-po-dim\">Starting session...</p>}\n {!compact && (worktree.orphaned || worktree.unowned) && (\n <p className=\"pl-4 text-sm text-po-dim first-letter:uppercase\">\n {worktree.orphaned ? 'its folder is missing' : 'its session has ended'}\n </p>\n )}\n {error && (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"pl-4 text-sm text-po-red\">\n {error}\n </p>\n )}\n </div>\n );\n}\n","/**\n * The cockpit's view of what this session changed against its base: the counts\n * the '# diff' group shows, what the review tab lists and draws, and the manual\n * sync that sits beside them.\n *\n * DESIGN PATTERNS:\n * - Declarations only, shared by the hub and the page.\n * - Its own channel, apart from worktrees. Worktrees are repository\n * management; the diff is this session's code change.\n * - A diff row carries one line number whose file follows from its marker: the\n * new file's for context and additions, the old file's for removals. It is\n * the same shape the shared DiffView draws.\n *\n * AVOID:\n * - Behaviour or node builtins. Browser code imports this file.\n */\n\n/** The session channel carrying this checkout's changes and the sync around them. */\nexport const GIT_CHANGES_TYPE = 'git_changes';\n\n/** The sync actions the review tab offers. */\nexport type GitSyncAction = 'pull' | 'push' | 'rebase' | 'abort-rebase';\n\n/** What the review tab asks the hub to run. `force` only follows a confirmed rejected push. */\nexport type GitChangesCommand =\n | { action: 'pull' }\n | { action: 'push'; force?: true }\n | { action: 'rebase' }\n | { action: 'abort-rebase' };\n\nexport type GitSyncErrorTarget =\n | { action: 'pull' | 'rebase' | 'abort-rebase' }\n /** A push the remote rejected as non-fast-forward; the tab offers a lease force after a confirm. */\n | { action: 'push'; forceRequired?: true };\n\nexport interface GitChangesPayload {\n /** Absent outside a git checkout. */\n changes?: GitChangesView;\n /** Label of the sync command in flight. */\n pending?: string;\n /** The last sync failure, cleared when the next command starts. */\n error?: string;\n errorTarget?: GitSyncErrorTarget;\n}\n\n/** What the session changed since its base, as the '# diff' lane and the review header show it. */\nexport interface GitChangesView {\n /** The checked-out branch; absent on a detached HEAD. */\n branch?: string;\n /** The ref the changes are measured against; absent when none resolved, so only uncommitted work counts. */\n base?: string;\n added: number;\n removed: number;\n files: number;\n /** More files changed than were counted. */\n truncated?: boolean;\n /** The branch's upstream and how far apart the two are. */\n upstream?: { ref: string; ahead: number; behind: number };\n /** Present while a rebase is paused on conflicts. */\n rebase?: { conflicts: string[] };\n}\n\nexport type GitReviewFileStatus = 'added' | 'modified' | 'deleted' | 'untracked' | 'conflicted';\n\n/** One changed file in the review list. */\nexport interface GitReviewFileEntry {\n /** Repository-relative, forward slashes. */\n path: string;\n status: GitReviewFileStatus;\n added: number;\n removed: number;\n binary?: boolean;\n}\n\n/** The review tab's file list. */\nexport interface GitReviewSummary {\n /** False when the session's directory is not a git checkout. */\n repository: boolean;\n branch?: string;\n base?: string;\n /** Short sha of the commit the diff starts from. */\n mergeBase?: string;\n files: GitReviewFileEntry[];\n truncated?: boolean;\n}\n\nexport interface GitDiffRow {\n marker: '+' | '-' | ' ';\n line: number;\n content: string;\n}\n\nexport interface GitDiffHunk {\n start: number;\n rows: GitDiffRow[];\n}\n\n/** One file's hunks, fetched when the reader expands it. */\nexport interface GitReviewFileDiff {\n path: string;\n hunks: GitDiffHunk[];\n binary?: true;\n /** The diff was past the size cap and is not drawn. */\n tooLarge?: true;\n}\n","/**\n * This session's code change against its base, and the manual sync beside it.\n *\n * DESIGN PATTERNS:\n * - Its own session store and hub channel, apart from worktrees. Worktrees are\n * repository management; this is the session's diff.\n * - The hub is authoritative: it computes the counts, runs pull, push and\n * rebase one at a time, and reports pending, errors and a paused rebase here.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - `sendSessionFrame` for a sync command. That frame is bound for the agent\n * and never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport {\n GIT_CHANGES_TYPE,\n type GitChangesCommand,\n type GitChangesView,\n type GitSyncAction,\n type GitSyncErrorTarget,\n} from '../../../../../types/gitReview';\n\nexport interface GitChangesSession {\n /** Absent until the hub reports, and outside a git checkout. */\n changes: GitChangesView | undefined;\n pending: string | undefined;\n error: string | undefined;\n errorTarget: GitSyncErrorTarget | undefined;\n}\n\nexport const gitChanges = defineSessionStore<GitChangesSession>({\n changes: undefined,\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** The page's hub socket sender; undefined before start and after dispose, when a command is dropped. */\nconst changesSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket for sync commands. The plugin host calls this once per page. */\nexport function startGitChangesRuntime(runtime: WebPluginRuntime): () => void {\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n changesSender.update(() => send);\n return () => {\n changesSender.update((current) => (current === send ? undefined : current));\n };\n}\n\n/** Whether a sync command is running for this session. */\nexport const gitChangesActivitySource = {\n subscribe(listener: () => void) {\n const subscription = gitChanges.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return gitChanges.select(gitChanges.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction count(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0 ? value : undefined;\n}\n\n/** The page never trusts a frame's shape: a malformed field drops, the rest still renders. */\nconst MAX_CONFLICTS = 100;\n\nfunction optionalChanges(value: unknown): GitChangesView | undefined {\n if (!isRecord(value)) return undefined;\n const added = count(value.added);\n const removed = count(value.removed);\n const files = count(value.files);\n if (added === undefined || removed === undefined || files === undefined) return undefined;\n const branch = optionalText(value.branch);\n const base = optionalText(value.base);\n const upstream = isRecord(value.upstream) ? value.upstream : undefined;\n const ahead = count(upstream?.ahead);\n const behind = count(upstream?.behind);\n const upstreamRef = optionalText(upstream?.ref);\n const conflicts =\n isRecord(value.rebase) && Array.isArray(value.rebase.conflicts)\n ? value.rebase.conflicts.filter((file): file is string => typeof file === 'string').slice(0, MAX_CONFLICTS)\n : undefined;\n return {\n added,\n removed,\n files,\n ...(branch === undefined ? {} : { branch }),\n ...(base === undefined ? {} : { base }),\n ...(value.truncated === true ? { truncated: true } : {}),\n ...(upstreamRef === undefined || ahead === undefined || behind === undefined\n ? {}\n : { upstream: { ref: upstreamRef, ahead, behind } }),\n ...(conflicts === undefined ? {} : { rebase: { conflicts } }),\n };\n}\n\nfunction optionalErrorTarget(value: unknown): GitSyncErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'pull' || value.action === 'rebase' || value.action === 'abort-rebase')\n return { action: value.action };\n if (value.action === 'push')\n return value.forceRequired === true ? { action: 'push', forceRequired: true } : { action: 'push' };\n return undefined;\n}\n\n/** The session data channel: 'git_changes' payloads into the store. */\nexport const gitChangesChannel = gitChanges.channel<GitChangesSession>({\n channel: GIT_CHANGES_TYPE,\n parse(input) {\n if (!isRecord(input)) return null;\n return {\n changes: optionalChanges(input.changes),\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/**\n * Asks the hub to pull, push, rebase or abort a paused rebase. `force` is only\n * ever sent after the reader confirmed a lease force for a rejected push.\n */\nexport function requestGitSync(sessionId: string, action: GitSyncAction, force = false): void {\n const payload: GitChangesCommand = action === 'push' && force ? { action: 'push', force: true } : { action };\n changesSender.store.state?.({ type: GIT_CHANGES_TYPE, sessionId, payload });\n}\n","import { defineActivityGroup } from '@agimon-ai/po-core/web';\nimport { BranchIcon } from '@agimon-ai/po-web-components';\n\nimport { worktreesTab } from '../_components/WorktreesPanel';\nimport { gitChangesActivitySource } from '../_lib/gitChangesStore';\nimport { worktreeActivitySource } from '../_lib/worktreesActivityStore';\n\nexport default defineActivityGroup({\n keys: 'g w',\n icon: BranchIcon,\n activeSource: {\n subscribe(listener) {\n const stopWorktrees = worktreeActivitySource.subscribe(listener);\n const stopChanges = gitChangesActivitySource.subscribe(listener);\n return () => {\n stopWorktrees();\n stopChanges();\n };\n },\n isActive(sessionId) {\n return worktreeActivitySource.isActive(sessionId) || gitChangesActivitySource.isActive(sessionId);\n },\n },\n marksBackgroundWork: false,\n transientTab: worktreesTab,\n order: 30,\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/web';\n\nimport { gitChangesChannel } from '../_lib/gitChangesStore';\n\nexport default defineChannelFile(gitChangesChannel);\n","import { defineChannelFile } from '@agimon-ai/po-core/web';\n\nimport { worktreesChannel } from '../_lib/worktreesActivityStore';\n\nexport default defineChannelFile(worktreesChannel);\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreeSessionMenu } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeSessionMenu });\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreeCreateOverlay } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeCreateOverlay });\n","import { api } from '../../../../../../generated/client';\nimport type { GitReviewFileDiff, GitReviewSummary } from '../../../../../types/gitReview';\n\n/**\n * The review tab's half of the session API: the changed-file list and one\n * file's hunks.\n *\n * The generated client owns the URL and the sealed transport, so nothing here\n * spells a route or reaches for `fetch`. What travels is file contents, which a\n * tunnel's relay must never see in the clear.\n */\n\nconst UNREACHABLE = 'The session is unreachable.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The message a reader is shown: the route's own words, or why there were none. */\nfunction messageOf(result: { status: number; error: string }): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === '' ? `The session answered ${String(result.status)}.` : result.error;\n}\n\nexport type ReviewSummaryResult = { ok: true; summary: GitReviewSummary } | { ok: false; error: string };\n\nexport async function fetchReviewSummary(sessionId: string, signal?: AbortSignal): Promise<ReviewSummaryResult> {\n const result = await api.session(sessionId).review(signal === undefined ? {} : { signal });\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data) || !Array.isArray(result.data.files)) {\n return { ok: false, error: 'The session answered with no file list.' };\n }\n return { ok: true, summary: result.data };\n}\n\nexport type ReviewFileResult = { ok: true; diff: GitReviewFileDiff } | { ok: false; error: string };\n\nexport async function fetchReviewFile(\n sessionId: string,\n path: string,\n signal?: AbortSignal,\n): Promise<ReviewFileResult> {\n const result = await api\n .session(sessionId)\n .reviewFile({ query: { path }, ...(signal === undefined ? {} : { signal }) });\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data) || !Array.isArray(result.data.hunks)) {\n return { ok: false, error: 'The session answered with no diff.' };\n }\n return { ok: true, diff: result.data };\n}\n","import { defineSessionStore } from '@agimon-ai/po-core/web';\n/**\n * Review comments queued on this session, waiting to go to the agent as one\n * message.\n *\n * DESIGN PATTERNS:\n * - Session-scoped and in memory: comments survive closing and reopening the\n * review tab, not a page reload. The same trade the files tab makes.\n * - Comments are cleared only after a send the host accepted, never before.\n */\nimport type { ReviewComment } from '@agimon-ai/po-web-components';\n\nexport interface GitReviewSession {\n comments: ReviewComment[];\n}\n\nexport const gitReview = defineSessionStore<GitReviewSession>({ comments: [] });\n\nexport function addReviewComment(sessionId: string, comment: Omit<ReviewComment, 'id'>): void {\n const id = globalThis.crypto.randomUUID();\n gitReview.update(sessionId, (current) => ({ comments: [...current.comments, { ...comment, id }] }));\n}\n\nexport function removeReviewComment(sessionId: string, id: string): void {\n gitReview.update(sessionId, (current) => ({ comments: current.comments.filter((comment) => comment.id !== id) }));\n}\n\nexport function clearReviewComments(sessionId: string): void {\n gitReview.update(sessionId, () => ({ comments: [] }));\n}\n","import type { SessionFrameSender } from '@agimon-ai/po-core/web';\n\nimport type { GitChangesView } from '../../../../../types/gitReview';\n\n/**\n * Pure wording for what the review tab sends the agent, and the one send.\n *\n * Both messages go as `follow_up`: the host starts a turn when idle, or after\n * the current one, without treating a review send as an explicit Queue action.\n * A `prompt` frame instead fails while a turn runs.\n */\n\n/** The opening line of a review, naming what was reviewed. */\nexport function reviewHeading(count: number, branch: string | undefined, base: string | undefined): string {\n const what = branch === undefined ? 'this checkout' : `branch ${branch}`;\n const against = base === undefined ? 'its uncommitted changes' : `its changes against ${base}`;\n const comments = count === 1 ? 'one review comment' : `${String(count)} review comments`;\n const address = count === 1 ? 'Please address it.' : 'Please address them all.';\n return `I reviewed ${what} (${against}) and left ${comments}. ${address}`;\n}\n\n/** What \"ask agent to resolve\" sends: the files, and the steps that finish a paused rebase. */\nexport function conflictPrompt(branch: string | undefined, conflicts: readonly string[]): string {\n const files =\n conflicts.length === 0 ? '- (git reports no unmerged paths yet)' : conflicts.map((file) => `- ${file}`).join('\\n');\n return [\n `A rebase of ${branch ?? 'this checkout'} stopped on conflicts in:`,\n '',\n files,\n '',\n 'Please resolve them:',\n '1. Fix the conflict markers in each file, keeping the intent of both sides.',\n '2. `git add` each resolved file.',\n '3. Run `GIT_EDITOR=true git rebase --continue`, and repeat if it stops again.',\n '',\n 'Do not push. I will push from the cockpit once the rebase is done.',\n ].join('\\n');\n}\n\n/**\n * The one sync the bar fills in: pull while the branch is behind (a push would\n * be rejected), push while it is only ahead or has no upstream yet. Nothing\n * while a rebase is paused, detached, or already level.\n */\nexport function suggestedSyncAction(changes: GitChangesView | undefined): 'pull' | 'push' | undefined {\n if (changes?.branch === undefined || changes.rebase !== undefined) return undefined;\n if (changes.upstream === undefined) return 'push';\n if (changes.upstream.behind > 0) return 'pull';\n return changes.upstream.ahead > 0 ? 'push' : undefined;\n}\n\n/** \"2 to push, 1 new on origin/feat/git\", or \"Up to date with origin/feat/git\". */\nexport function upstreamSummary(upstream: GitChangesView['upstream']): string {\n if (upstream === undefined) return 'No upstream yet';\n const parts = [\n ...(upstream.ahead > 0 ? [`${String(upstream.ahead)} to push`] : []),\n ...(upstream.behind > 0 ? [`${String(upstream.behind)} new on ${upstream.ref}`] : []),\n ];\n return parts.length === 0 ? `Up to date with ${upstream.ref}` : parts.join(', ');\n}\n/**\n * Hands one deferred follow-up to the session. Returns the reason it failed,\n * or undefined once sent. The sender throws when the session is disconnected.\n */\nexport function deliverToAgent(send: SessionFrameSender, sessionId: string, message: string): string | undefined {\n try {\n send(sessionId, { type: 'follow_up', message });\n return undefined;\n } catch (error) {\n return error instanceof Error ? error.message : 'The session did not take the message.';\n }\n}\n","import { Input, MessageIcon } from '@agimon-ai/po-web-components';\nimport { useEffect, useRef, useState, type KeyboardEvent } from 'react';\n\nimport type { GitReviewFileEntry } from '../../../../../types/gitReview';\n\nconst status = {\n added: ['A', 'text-po-green', 'Added'],\n modified: ['M', 'text-po-yellow', 'Modified'],\n deleted: ['D', 'text-po-red', 'Deleted'],\n untracked: ['U', 'text-po-blue', 'Untracked'],\n conflicted: ['C', 'text-po-red', 'Conflicted'],\n};\nexport interface GitReviewBrowserProps {\n files: readonly GitReviewFileEntry[];\n /** The file the diff pane is showing, highlighted here. */\n activePath?: string;\n commentCounts: Readonly<Record<string, number>>;\n onPick: (path: string) => void;\n}\n\nexport function GitReviewBrowser({ files, activePath, commentCounts, onPick }: GitReviewBrowserProps) {\n const [query, setQuery] = useState('');\n const shown = files.filter((f) => f.path.toLowerCase().includes(query.trim().toLowerCase()));\n const listRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (activePath === undefined) return;\n listRef.current\n ?.querySelector<HTMLElement>(`[data-path=\"${CSS.escape(activePath)}\"]`)\n ?.scrollIntoView({ block: 'nearest' });\n }, [activePath]);\n\n /** Arrow keys pick the neighbouring row and move focus with it, so the diff follows the cursor. */\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>): void => {\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;\n if (shown.length === 0) return;\n event.preventDefault();\n const current = shown.findIndex((file) => file.path === activePath);\n const step = event.key === 'ArrowDown' ? 1 : -1;\n const next = current === -1 ? 0 : (current + step + shown.length) % shown.length;\n const file = shown[next];\n if (file === undefined) return;\n onPick(file.path);\n const list = event.currentTarget.closest('[data-git-review-list]');\n list?.querySelectorAll<HTMLButtonElement>('[data-git-review-row]')[next]?.focus();\n };\n\n return (\n <nav\n aria-label=\"Changed files\"\n data-testid=\"git-review-browser\"\n className=\"flex min-h-0 w-80 shrink-0 flex-col border-r border-po-border-soft\"\n >\n <div className=\"flex flex-col gap-3 border-b border-po-border-soft p-3\">\n <Input\n data-testid=\"git-review-search\"\n size=\"sm\"\n aria-label=\"Search paths\"\n placeholder=\"Search paths\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <span className=\"text-sm text-po-dim\">{shown.length} changed</span>\n </div>\n <div ref={listRef} data-git-review-list className=\"min-h-0 flex-1 overflow-y-auto\">\n {shown.map((f) => {\n const slash = f.path.lastIndexOf('/');\n const count = commentCounts[f.path] ?? 0;\n return (\n <button\n key={f.path}\n data-git-review-row\n data-path={f.path}\n data-testid={`git-review-browser-file-${f.path}`}\n onKeyDown={onKeyDown}\n title={f.path}\n aria-current={activePath === f.path ? 'true' : undefined}\n onClick={() => onPick(f.path)}\n className={`flex w-full min-w-0 items-start gap-2 border-l-2 px-3 py-3 text-left ${activePath === f.path ? 'border-po-green bg-po-tint-green' : 'border-transparent hover:bg-po-panel'}`}\n >\n <span className={`pt-0.5 text-sm font-semibold ${status[f.status][1]}`}>{status[f.status][0]}</span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-base text-po-text\">{f.path.slice(slash + 1)}</span>\n {slash < 0 ? null : (\n <span className=\"block truncate font-mono text-sm text-po-dim\">{f.path.slice(0, slash)}</span>\n )}\n </span>\n <span className=\"flex shrink-0 flex-col items-end gap-1 text-sm\">\n <span>\n <span className=\"text-po-green\">+{f.added}</span> <span className=\"text-po-red\">-{f.removed}</span>\n </span>\n {count > 0 && (\n <span className=\"flex items-center gap-1 text-po-blue\">\n <MessageIcon className=\"h-3 w-3\" />\n {count}\n </span>\n )}\n </span>\n </button>\n );\n })}\n {shown.length === 0 && <p className=\"p-3 text-sm text-po-dim\">No paths match.</p>}\n </div>\n </nav>\n );\n}\n","import { BranchIcon, Button, Spinner, StatusBadge } from '@agimon-ai/po-web-components';\n\nimport type { GitChangesView, GitSyncAction, GitSyncErrorTarget } from '../../../../../types/gitReview';\nimport { suggestedSyncAction, upstreamSummary } from '../_lib/gitReviewView';\n\nexport interface GitSyncBarProps {\n /** Use an outline suggestion when review sending owns the primary action. */\n secondary?: boolean;\n /** Absent until the hub has reported this session's checkout. */\n changes?: GitChangesView;\n /** Short sha the review diff starts from. */\n mergeBase?: string;\n /** Label of the command the hub is running. */\n pending?: string;\n error?: string;\n errorTarget?: GitSyncErrorTarget;\n onSync: (action: GitSyncAction) => void;\n onForcePush: () => void;\n onAskAgent: () => void;\n onDismissError: () => void;\n}\n\nexport function GitSyncBar({ secondary = false, ...props }: GitSyncBarProps) {\n const c = props.changes;\n const paused = c?.rebase !== undefined;\n const busy = props.pending !== undefined;\n const rejected = props.errorTarget?.action === 'push' && props.errorTarget.forceRequired;\n const suggested = suggestedSyncAction(c);\n const upstream = upstreamSummary(c?.upstream);\n return (\n <div data-testid=\"git-sync-bar\" className=\"flex flex-col gap-3 border-b border-po-border-soft p-4\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n <BranchIcon className=\"h-4 w-4 text-po-dim\" />\n <span data-testid=\"git-review-branch\" className=\"font-mono text-base font-semibold text-po-hi\">\n {c?.branch ?? 'Detached HEAD'}\n </span>\n <span className=\"text-po-dim\">\n {c?.base === undefined ? (\n 'Uncommitted changes'\n ) : (\n <>\n vs <span className=\"font-mono\">{c.base}</span>\n </>\n )}\n </span>\n {props.mergeBase && (\n <span className=\"text-po-dim\">\n from <span className=\"font-mono\">{props.mergeBase}</span>\n </span>\n )}\n {c === undefined ? null : (\n <span data-testid=\"git-review-totals\" className=\"contents\">\n <span className=\"text-po-green\">+{c?.added}</span>\n <span className=\"text-po-red\">-{c?.removed}</span>\n <span className=\"text-po-dim\">\n {c?.files}\n {c?.truncated ? '+' : ''} {c?.files === 1 ? 'file' : 'files'}\n </span>\n </span>\n )}\n <span className=\"flex-1\" />\n <span className=\"text-po-dim\">\n {c?.branch === undefined ? (\n 'No branch checked out'\n ) : c.upstream === undefined || !upstream.endsWith(c.upstream.ref) ? (\n upstream\n ) : (\n <>\n {upstream.slice(0, -c.upstream.ref.length)}\n <span className=\"font-mono\">{c.upstream.ref}</span>\n </>\n )}\n </span>\n <div className=\"flex gap-1.5\">\n {(['pull', 'push', 'rebase'] as const).map((action) => (\n <Button\n key={action}\n data-testid={`git-sync-${action}`}\n size=\"sm\"\n variant={\n !busy && !paused && !rejected && !props.error && c?.branch !== undefined && suggested === action\n ? secondary\n ? 'outline'\n : 'primary'\n : 'ghost'\n }\n disabled={\n busy ||\n paused ||\n (action !== 'rebase' && c?.branch === undefined) ||\n (action === 'pull' && c?.upstream === undefined) ||\n (action === 'rebase' && c?.base === undefined)\n }\n onClick={() => props.onSync(action)}\n >\n {action === 'pull' ? 'Pull' : action === 'push' ? 'Push' : 'Rebase'}\n </Button>\n ))}\n </div>\n </div>\n {busy && (\n <div data-testid=\"git-sync-pending\" className=\"flex items-center gap-2 text-sm text-po-dim\">\n <Spinner className=\"h-4 w-4 text-po-dim\" label={props.pending} />\n {props.pending}\n </div>\n )}\n {rejected ? (\n <div\n data-testid=\"git-push-force-confirm\"\n className=\"flex flex-wrap items-center gap-3 rounded-md border border-po-edge-yellow bg-po-tint-yellow p-3\"\n >\n <span className=\"flex-1 text-base text-po-text\">origin has commits you have not pulled yet.</span>\n <Button\n size=\"sm\"\n variant=\"danger-outline\"\n data-testid=\"git-push-force\"\n disabled={busy}\n onClick={props.onForcePush}\n >\n Force push with lease\n </Button>\n <Button size=\"sm\" variant=\"ghost\" data-testid=\"git-push-force-cancel\" onClick={props.onDismissError}>\n Not now\n </Button>\n </div>\n ) : (\n props.error && (\n <div\n role=\"alert\"\n data-testid=\"git-sync-error\"\n className=\"flex items-center gap-3 rounded-md border border-po-edge-red bg-po-tint-red p-3 text-base text-po-red\"\n >\n <span className=\"flex-1\">{props.error}</span>\n <Button size=\"sm\" variant=\"ghost\" onClick={props.onDismissError}>\n Dismiss\n </Button>\n </div>\n )\n )}\n {paused && (\n <div\n data-testid=\"git-rebase-banner\"\n className=\"flex flex-col gap-2 rounded-md border border-po-edge-yellow bg-po-tint-yellow p-3\"\n >\n <div>\n <StatusBadge tone=\"running\" size=\"xs\">\n Rebase paused\n </StatusBadge>\n <span className=\"ml-2 text-base text-po-text\">\n Conflicts in {c.rebase?.conflicts.length} {c.rebase?.conflicts.length === 1 ? 'file' : 'files'}\n </span>\n </div>\n {c.rebase?.conflicts.map((path) => (\n <p key={path} className=\"font-mono text-sm text-po-dim\">\n {path}\n </p>\n ))}\n <div className=\"flex items-center gap-2\">\n <Button\n variant={secondary ? 'outline' : 'primary'}\n size=\"sm\"\n data-testid=\"git-rebase-ask-agent\"\n disabled={busy}\n onClick={props.onAskAgent}\n >\n Ask Po to resolve\n </Button>\n <Button\n variant=\"danger-outline\"\n size=\"sm\"\n data-testid=\"git-rebase-abort\"\n disabled={busy}\n onClick={() => props.onSync('abort-rebase')}\n >\n Abort rebase\n </Button>\n <span className=\"text-sm text-po-dim\">Abort discards conflict resolution in progress.</span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import {\n Button,\n DiffView,\n EmptyState,\n MessageIcon,\n ReviewCommentDraft,\n Spinner,\n type DiffRow,\n type DiffSelection,\n type ReviewComment,\n} from '@agimon-ai/po-web-components';\nimport { useEffect, useState } from 'react';\n\nimport type { GitReviewFileDiff, GitReviewFileEntry, GitReviewSummary } from '../../../../../types/gitReview';\nimport { GitReviewBrowser } from './GitReviewBrowser';\nimport { GitSyncBar, type GitSyncBarProps } from './GitSyncBar';\n\nconst NO_FILES: readonly GitReviewFileEntry[] = [];\n\nexport type ReviewSummaryState =\n | { state: 'loading' }\n | { state: 'error'; error: string }\n | { state: 'ready'; summary: GitReviewSummary };\n\nexport type ReviewFileState =\n | { state: 'loading' }\n | { state: 'error'; error: string }\n | { state: 'ready'; diff: GitReviewFileDiff };\n\nexport interface GitReviewViewProps {\n sync: GitSyncBarProps;\n summary: ReviewSummaryState;\n files: Readonly<Record<string, ReviewFileState | undefined>>;\n comments: readonly ReviewComment[];\n onLoadFile: (path: string) => void;\n onAddComment: (comment: Omit<ReviewComment, 'id'>) => void;\n onRemoveComment: (id: string) => void;\n onSendReview: () => void;\n onDiscard: () => void;\n /** Defer refresh while an unsent draft owns local input state. */\n onDraftChange?: (open: boolean) => void;\n /** Why the last send did not reach the session; the comments are still here. */\n sendError?: string;\n /** Initial file for deterministic previews. */\n initialPath?: string;\n /** Opens with this draft already raised. Stories use it; the panel never does. */\n initialDraft?: { path: string; selection: DiffSelection };\n}\n\n/** Stable, URL-safe element id for one file's section. */\nfunction sectionId(index: number): string {\n return `git-review-file-${String(index)}`;\n}\n\nfunction sideOf(row: DiffRow): 'old' | 'new' {\n return row.marker === '-' ? 'old' : 'new';\n}\n\nexport function GitReviewView({\n sync,\n summary,\n files,\n comments,\n onLoadFile,\n onAddComment,\n onRemoveComment,\n onSendReview,\n onDiscard,\n onDraftChange,\n sendError,\n initialDraft,\n initialPath,\n}: GitReviewViewProps) {\n const entries = summary.state === 'ready' ? summary.summary.files : NO_FILES;\n const [picked, setPicked] = useState(initialPath ?? initialDraft?.path);\n const activePath = entries.some((entry) => entry.path === picked) ? picked : entries[0]?.path;\n const index = entries.findIndex((entry) => entry.path === activePath);\n const file = entries[index];\n const [draft, setDraft] = useState<{ path: string; selection: DiffSelection } | undefined>(initialDraft);\n\n useEffect(() => {\n if (activePath !== undefined && files[activePath] === undefined) onLoadFile(activePath);\n }, [activePath, files, onLoadFile]);\n\n const commentCounts: Record<string, number> = {};\n for (const comment of comments) commentCounts[comment.path] = (commentCounts[comment.path] ?? 0) + 1;\n\n const pick = (path: string): void => {\n if (!entries.some((entry) => entry.path === path)) return;\n if (path !== activePath && draft !== undefined) {\n if (!window.confirm('Discard the unsent comment and open another file?')) return;\n setDraft(undefined);\n onDraftChange?.(false);\n }\n setPicked(path);\n };\n\n const submitDraft = (body: string): void => {\n if (draft === undefined) return;\n onAddComment({\n path: draft.path,\n relPath: draft.path,\n side: draft.selection.side,\n startLine: draft.selection.startLine,\n endLine: draft.selection.endLine,\n snippet: draft.selection.snippet,\n body: body.trim(),\n });\n setDraft(undefined);\n onDraftChange?.(false);\n };\n\n return (\n <div data-testid=\"git-review-panel\" className=\"flex min-h-0 flex-1 flex-col\">\n <GitSyncBar\n {...sync}\n secondary={comments.length > 0}\n {...(summary.state === 'ready' && summary.summary.mergeBase !== undefined\n ? { mergeBase: summary.summary.mergeBase }\n : {})}\n />\n\n {summary.state === 'loading' ? (\n <div\n data-testid=\"git-review-loading\"\n className=\"flex min-h-48 flex-1 items-center justify-center gap-2 text-sm text-po-dim\"\n >\n <Spinner className=\"h-4 w-4 text-po-dim\" label=\"Reading changes\" />\n <span className=\"text-sm text-po-dim\">Reading changes...</span>\n </div>\n ) : summary.state === 'error' ? (\n <EmptyState\n data-testid=\"git-review-error\"\n className=\"min-h-48 text-po-red\"\n title={<span className=\"text-po-red\">Changes could not be read</span>}\n description={summary.error}\n />\n ) : !summary.summary.repository ? (\n <EmptyState\n data-testid=\"git-review-no-repository\"\n className=\"min-h-48\"\n title=\"Not a Git checkout\"\n description=\"This session's folder is not inside a Git repository.\"\n />\n ) : entries.length === 0 ? (\n <EmptyState\n data-testid=\"git-review-empty\"\n className=\"min-h-48\"\n title=\"No changes yet\"\n description={\n summary.summary.base === undefined\n ? 'Nothing uncommitted in this checkout.'\n : `Nothing differs from ${summary.summary.base}, committed or not.`\n }\n />\n ) : (\n <div data-testid=\"git-review-content\" className=\"flex min-h-0 flex-1\">\n <GitReviewBrowser\n files={entries}\n commentCounts={commentCounts}\n onPick={pick}\n {...(activePath === undefined ? {} : { activePath })}\n />\n <main data-testid=\"git-review-diffs\" className=\"min-h-0 min-w-0 flex-1 overflow-y-auto\">\n {summary.summary.truncated ? (\n <p className=\"px-4 pt-2 text-sm text-po-dim\">\n More files changed than the review lists; the rest are left out.\n </p>\n ) : null}\n <div className=\"flex items-center justify-between border-b border-po-border-soft px-4 py-2\">\n <Button variant=\"ghost\" size=\"sm\" disabled={index <= 0} onClick={() => pick(entries[index - 1]!.path)}>\n Previous file\n </Button>\n <span className=\"text-sm text-po-dim\">\n {index + 1} of {entries.length}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={index >= entries.length - 1}\n onClick={() => pick(entries[index + 1]!.path)}\n >\n Next file\n </Button>\n </div>\n {file === undefined ? null : (\n <FileSection\n key={file.path}\n id={sectionId(index)}\n entry={file}\n state={files[file.path]}\n comments={comments.filter((comment) => comment.path === file.path)}\n draft={draft?.path === file.path ? draft.selection : undefined}\n onSelect={(selection) => {\n setDraft({ path: file.path, selection });\n onDraftChange?.(true);\n }}\n onSubmitDraft={submitDraft}\n onCancelDraft={() => {\n setDraft(undefined);\n onDraftChange?.(false);\n }}\n onRemoveComment={onRemoveComment}\n onRetry={() => onLoadFile(file.path)}\n />\n )}\n </main>\n </div>\n )}\n\n <div\n data-testid=\"git-review-footer\"\n className=\"flex shrink-0 flex-wrap items-center gap-3 border-t border-po-border-soft bg-po-panel px-4 py-3\"\n >\n <MessageIcon aria-hidden className=\"h-4 w-4 text-po-blue\" />\n <span data-testid=\"git-review-comment-count\" className=\"text-sm text-po-dim\">\n {comments.length === 0\n ? 'No comments yet: select lines or click a line number'\n : `${String(comments.length)} ${comments.length === 1 ? 'comment' : 'comments'} queued`}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {sendError === undefined ? null : (\n <span role=\"alert\" data-testid=\"git-review-send-error\" className=\"min-w-0 truncate text-sm text-po-red\">\n {sendError}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"git-review-discard\"\n disabled={comments.length === 0}\n onClick={onDiscard}\n >\n Discard\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n data-testid=\"git-review-send\"\n disabled={comments.length === 0}\n onClick={onSendReview}\n >\n Send review\n </Button>\n </div>\n </div>\n );\n}\n\nconst STATUS_WORD: Readonly<Record<GitReviewFileEntry['status'], string>> = {\n added: 'Added',\n modified: 'Modified',\n deleted: 'Deleted',\n untracked: 'Untracked',\n conflicted: 'Conflicted',\n};\n\n/** One file: a pinned header, then its diff with comments drawn under the lines they are about. */\nfunction FileSection({\n id,\n entry,\n state,\n comments,\n draft,\n onSelect,\n onSubmitDraft,\n onCancelDraft,\n onRemoveComment,\n onRetry,\n}: {\n id: string;\n entry: GitReviewFileEntry;\n state: ReviewFileState | undefined;\n comments: readonly ReviewComment[];\n draft: DiffSelection | undefined;\n onSelect: (selection: DiffSelection) => void;\n onSubmitDraft: (body: string) => void;\n onCancelDraft: () => void;\n onRemoveComment: (id: string) => void;\n onRetry: () => void;\n}) {\n const renderAfterRow = (row: DiffRow) => {\n const side = sideOf(row);\n const here = comments.filter(\n (comment) => (comment.side ?? 'new') === side && (comment.endLine ?? comment.startLine) === row.line,\n );\n const drafting = draft !== undefined && draft.side === side && draft.endLine === row.line;\n if (here.length === 0 && !drafting) return null;\n return (\n <div className=\"font-sans whitespace-normal\">\n {here.map((comment) => (\n <div\n key={comment.id}\n data-testid={`git-review-comment-${comment.id}`}\n className=\"m-3 flex items-start gap-3 rounded-md border border-po-border-soft bg-po-panel p-3 font-sans whitespace-normal\"\n >\n <MessageIcon aria-hidden className=\"mt-1 h-4 w-4 shrink-0 text-po-blue\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"mb-1 text-sm text-po-dim\">You · line {comment.endLine ?? comment.startLine}</span>\n <span className=\"text-base whitespace-pre-wrap text-po-text\">{comment.body}</span>\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Remove comment\"\n title=\"Remove comment\"\n onClick={() => onRemoveComment(comment.id)}\n >\n Remove\n </Button>\n </div>\n ))}\n {drafting ? (\n <div className=\"m-3 rounded-md border border-po-border-soft bg-po-panel font-sans whitespace-normal [&_pre]:text-sm [&_p]:first-letter:uppercase\">\n <ReviewCommentDraft\n snippet={draft.snippet}\n startLine={draft.startLine}\n endLine={draft.endLine}\n side={draft.side}\n testIdPrefix=\"git-review-comment\"\n onSubmit={onSubmitDraft}\n onCancel={onCancelDraft}\n />\n </div>\n ) : null}\n </div>\n );\n };\n\n return (\n <section id={id} data-review-path={entry.path} data-testid={`git-review-file-${entry.path}`}>\n <div className=\"flex flex-wrap items-center gap-3 border-b border-po-border-soft bg-po-panel px-4 py-3\">\n <span className=\"min-w-0 flex-1 truncate font-mono text-base text-po-hi\">{entry.path}</span>\n <span className=\"shrink-0 text-sm text-po-dim\">{STATUS_WORD[entry.status]}</span>\n {entry.binary ? null : (\n <>\n <span className=\"text-sm text-po-green\">+{entry.added}</span>\n <span className=\"text-sm text-po-red\">-{entry.removed}</span>\n </>\n )}\n {comments.length === 0 ? null : (\n <span className=\"flex shrink-0 items-center gap-1 text-sm text-po-blue\">\n <MessageIcon aria-hidden className=\"h-3 w-3\" />\n {comments.length} {comments.length === 1 ? 'comment' : 'comments'}\n </span>\n )}\n </div>\n <div data-review-body={state === undefined || state.state === 'loading' ? 'loading' : 'measured'}>\n {state === undefined || state.state === 'loading' ? (\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <Spinner className=\"h-3 w-3 text-po-faint\" label={`Loading ${entry.path}`} />\n <span className=\"text-sm text-po-dim\">Loading diff...</span>\n </div>\n ) : state.state === 'error' ? (\n <div className=\"flex min-h-48 flex-col items-center justify-center gap-3\">\n <span role=\"alert\" className=\"text-base text-po-red\">\n {state.error}\n </span>\n <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n Retry\n </Button>\n </div>\n ) : state.diff.binary ? (\n <EmptyState\n className=\"min-h-48\"\n title=\"Binary file\"\n description={`${entry.path} cannot be shown as a text diff.`}\n />\n ) : state.diff.tooLarge ? (\n <EmptyState\n className=\"min-h-48\"\n title=\"This diff is too large to show\"\n description=\"Other changed files are still available to review.\"\n />\n ) : (\n <DiffView\n hunks={state.diff.hunks}\n testId={`git-review-diff-${id}`}\n onSelect={onSelect}\n renderAfterRow={renderAfterRow}\n />\n )}\n </div>\n </section>\n );\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\n/**\n * The review tab: this session's changes against its base, the comments on\n * them, and the manual sync beside them.\n *\n * DESIGN PATTERNS:\n * - Opened from the '# diff' group as a transient tab, one per session.\n * - The hub's channel says when something changed (counts, base, a paused\n * rebase); the panel refetches the file list then, and each file's hunks\n * when it is opened. Nothing polls.\n * - Comments live in a session store and are cleared only after the host took\n * the message. Both messages go as `enqueue_automatic`, which queues behind a\n * running turn instead of failing.\n *\n * AVOID:\n * - Sending sync as a session frame. Sync is a channel command; the hub runs\n * it with the configured auth, one command per session.\n */\nimport { buildReviewPrompt } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { gitChanges, requestGitSync } from '../_lib/gitChangesStore';\nimport { fetchReviewFile, fetchReviewSummary } from '../_lib/gitReviewApi';\nimport { clearReviewComments, addReviewComment, gitReview, removeReviewComment } from '../_lib/gitReviewStore';\nimport { conflictPrompt, deliverToAgent, reviewHeading } from '../_lib/gitReviewView';\nimport { GitReviewView, type ReviewFileState, type ReviewSummaryState } from './GitReviewView';\n\nconst REVIEW_TAB_ID = 'git-review';\n\nexport function reviewTab(): TransientTab {\n return { id: REVIEW_TAB_ID, label: 'review', panel: GitReviewPanel };\n}\n\nexport function GitReviewPanel({ sessionId, sendSessionFrame }: WebPluginSlotProps) {\n const activity = useStore(gitChanges.store, (state) => gitChanges.select(state, sessionId));\n const comments = useStore(gitReview.store, (state) => gitReview.select(state, sessionId).comments);\n const [summary, setSummary] = useState<ReviewSummaryState>({ state: 'loading' });\n const [files, setFiles] = useState<Record<string, ReviewFileState | undefined>>({});\n const [sendError, setSendError] = useState<string>();\n const [dismissedError, setDismissedError] = useState<string>();\n const [draftSnapshot, setDraftSnapshot] = useState<{ sessionId: string | null; fingerprint: string }>();\n const changes = activity.changes;\n const generation = useRef(0);\n const pendingFiles = useRef(new Map<string, AbortController>());\n const readyGeneration = useRef(false);\n\n // What the hub reported, reduced to the facts that move the file list. A new\n // value means the list and every loaded hunk may be stale.\n const fingerprint = JSON.stringify([\n changes?.branch,\n changes?.base,\n changes?.added,\n changes?.removed,\n changes?.files,\n changes?.rebase?.conflicts.length,\n ]);\n // Keep the mounted draft input intact until it is submitted or cancelled.\n const refreshFingerprint = draftSnapshot?.sessionId === sessionId ? draftSnapshot.fingerprint : fingerprint;\n useEffect(() => {\n generation.current += 1;\n readyGeneration.current = false;\n const pending = pendingFiles.current;\n for (const request of pending.values()) request.abort();\n pending.clear();\n // Invalidate the visible snapshot while the external change notification is being reread.\n // eslint-disable-next-line react/set-state-in-effect\n setSummary({ state: 'loading' });\n setFiles({});\n setDraftSnapshot((current) => (current?.sessionId === sessionId ? current : undefined));\n if (sessionId === null) return;\n const controller = new AbortController();\n fetchReviewSummary(sessionId, controller.signal)\n .then((result) => {\n if (controller.signal.aborted) return;\n readyGeneration.current = result.ok;\n setSummary(result.ok ? { state: 'ready', summary: result.summary } : { state: 'error', error: result.error });\n setFiles({});\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n setSummary({\n state: 'error',\n error: error instanceof Error ? error.message : 'The changes could not be read.',\n });\n });\n return () => {\n controller.abort();\n generation.current += 1;\n readyGeneration.current = false;\n for (const request of pending.values()) request.abort();\n pending.clear();\n };\n }, [sessionId, refreshFingerprint]);\n\n const loadFile = useCallback(\n (path: string): void => {\n if (sessionId === null || !readyGeneration.current || pendingFiles.current.has(path)) return;\n const requestGeneration = generation.current;\n const controller = new AbortController();\n pendingFiles.current.set(path, controller);\n setFiles((current) => ({ ...current, [path]: { state: 'loading' } }));\n const settle = (state: ReviewFileState): void => {\n if (controller.signal.aborted || requestGeneration !== generation.current) return;\n setFiles((current) => ({ ...current, [path]: state }));\n };\n fetchReviewFile(sessionId, path, controller.signal)\n .then((result) =>\n settle(result.ok ? { state: 'ready', diff: result.diff } : { state: 'error', error: result.error }),\n )\n .catch((error: unknown) =>\n settle({ state: 'error', error: error instanceof Error ? error.message : 'The diff could not be read.' }),\n )\n .finally(() => {\n if (pendingFiles.current.get(path) === controller) pendingFiles.current.delete(path);\n });\n },\n [sessionId],\n );\n\n if (sessionId === null) return null;\n\n const branch = summary.state === 'ready' ? summary.summary.branch : changes?.branch;\n const base = summary.state === 'ready' ? summary.summary.base : changes?.base;\n const error = activity.error === dismissedError ? undefined : activity.error;\n\n const send = (message: string, onSent?: () => void): void => {\n const failure = deliverToAgent(sendSessionFrame, sessionId, message);\n setSendError(failure);\n if (failure === undefined) onSent?.();\n };\n\n return (\n <GitReviewView\n key={sessionId}\n onDraftChange={(open) =>\n setDraftSnapshot((current) =>\n open ? (current?.sessionId === sessionId ? current : { sessionId, fingerprint }) : undefined,\n )\n }\n sync={{\n ...(changes === undefined ? {} : { changes }),\n ...(activity.pending === undefined ? {} : { pending: activity.pending }),\n ...(error === undefined ? {} : { error }),\n ...(activity.errorTarget === undefined || error === undefined ? {} : { errorTarget: activity.errorTarget }),\n onSync: (action) => {\n if (\n action === 'abort-rebase' &&\n !window.confirm('Abort rebase? This discards conflict resolution in progress.')\n )\n return;\n requestGitSync(sessionId, action);\n },\n onForcePush: () => requestGitSync(sessionId, 'push', true),\n onAskAgent: () => send(conflictPrompt(branch, changes?.rebase?.conflicts ?? [])),\n onDismissError: () => setDismissedError(activity.error),\n }}\n summary={summary}\n files={files}\n comments={comments}\n onLoadFile={loadFile}\n onAddComment={(comment) => addReviewComment(sessionId, comment)}\n onRemoveComment={(id) => removeReviewComment(sessionId, id)}\n onSendReview={() =>\n send(buildReviewPrompt(comments, reviewHeading(comments.length, branch, base)), () =>\n clearReviewComments(sessionId),\n )\n }\n onDiscard={() => clearReviewComments(sessionId)}\n {...(sendError === undefined ? {} : { sendError })}\n />\n );\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\n/**\n * The '# git' group's branch row: this session's code change against its base.\n *\n * DESIGN PATTERNS:\n * - One lane, branch and `+A -R`, straight on the group body like every other\n * activity group: the dock already draws the card, so no inner card or heading.\n * Files, base, upstream and a paused rebase live in the review tab's header,\n * which this lane opens.\n * - Stays clickable at zero, because the review tab is also where pull, push\n * and rebase live.\n * - Reads the focused session's checkout, whether it is a worktree or not.\n *\n * AVOID:\n * - Doing work here. This section reports and opens the tab.\n */\nimport { Button, Spinner } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport { reviewTab } from '../../_components/GitReviewPanel';\nimport { gitChanges } from '../../_lib/gitChangesStore';\n\nexport function DiffActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {\n const session = useStore(gitChanges.store, (state) => gitChanges.select(state, sessionId));\n const changes = session.changes;\n\n if (sessionId === null || changes === undefined) return null;\n\n return (\n <DiffActivityView changes={changes} pending={session.pending} onReview={() => openTransientTab(reviewTab())} />\n );\n}\nexport function DiffActivityView({\n changes,\n pending,\n onReview,\n branch,\n}: {\n branch?: string;\n changes?: { branch?: string; base?: string; added: number; removed: number; files: number };\n pending?: string;\n onReview?: () => void;\n}) {\n const zero = changes?.added === 0 && changes?.removed === 0;\n const against = changes?.base === undefined ? 'uncommitted' : `vs ${changes.base}`;\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <Button\n variant=\"ghost\"\n size=\"card\"\n data-testid=\"activity-diff-changes\"\n className=\"min-w-0 flex-row items-center gap-2 rounded-md px-1 py-1 font-normal hover:bg-po-panel\"\n aria-label={\n changes\n ? `review ${changes.branch ?? 'detached HEAD'} changes: ${changes.added} added, ${changes.removed} removed ${against}`\n : 'Changes not reported yet'\n }\n title={changes ? `${changes.files} ${changes.files === 1 ? 'file' : 'files'} ${against}` : undefined}\n onClick={onReview}\n >\n <span className=\"min-w-0 flex-1 truncate text-left font-mono text-sm text-po-hi\">\n {changes?.branch ?? branch ?? 'detached HEAD'}\n </span>\n {!changes || zero ? (\n <span className=\"shrink-0 text-sm text-po-dim\">{zero ? 'No changes yet' : 'Not reported yet'}</span>\n ) : (\n <span className=\"flex shrink-0 gap-2 text-sm\">\n <span className=\"text-po-green\">+{changes.added}</span>\n <span className=\"text-po-red\">-{changes.removed}</span>\n </span>\n )}\n </Button>\n {pending && (\n <p className=\"flex items-center gap-2 px-1 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n </div>\n );\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/web';\nimport { ArrowRightIcon, Button, Spinner } from '@agimon-ai/po-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport type { WorktreeView } from '../../../../../../types/webWorktrees';\nimport { WorktreeRow, worktreesTab } from '../../_components/WorktreesPanel';\nimport { worktreeActivity, worktreeCreateDialog } from '../../_lib/worktreesActivityStore';\nimport { DiffActivitySection } from './DiffActivitySection';\n\nexport function WorktreesActivitySection(props: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, props.sessionId));\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <DiffActivitySection {...props} />\n <WorktreesActivityView\n worktrees={session.worktrees.filter((w) => w.sessionId !== props.sessionId)}\n pending={session.pending}\n onOpen={() => props.openTransientTab(worktreesTab())}\n onCreate={\n props.sessionId === null\n ? undefined\n : () =>\n worktreeCreateDialog.update(() => ({\n sessionId: props.sessionId!,\n ...(props.sessionReservationId === undefined ? {} : { reservationId: props.sessionReservationId }),\n }))\n }\n />\n </div>\n );\n}\nexport function WorktreesActivityView({\n worktrees,\n pending,\n onOpen,\n onCreate,\n startingIds = [],\n}: {\n worktrees: WorktreeView[];\n pending?: string;\n onOpen?: () => void;\n onCreate?: () => void;\n startingIds?: string[];\n}) {\n // The dock draws the group card and heading; this body sits straight on it, as Runners does.\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n {pending && (\n <p className=\"flex items-center gap-2 px-1 text-sm text-po-dim\">\n <Spinner className=\"size-3\" label={pending} />\n {/* The hub's progress label arrives lowercase. */}\n <span className=\"inline-block first-letter:uppercase\">{pending}</span>\n </p>\n )}\n {worktrees.length === 0 ? (\n onCreate ? (\n <Button\n variant=\"link\"\n size=\"sm\"\n data-testid=\"activity-git-create\"\n className=\"h-auto self-start gap-1 px-1 text-po-green\"\n onClick={onCreate}\n >\n Create a worktree\n <ArrowRightIcon aria-hidden className=\"size-3.5\" />\n </Button>\n ) : (\n <span data-testid=\"activity-summary-git\" className=\"px-1 text-sm text-po-dim\">\n Idle\n </span>\n )\n ) : (\n <div data-testid=\"activity-git-worktrees\">\n {worktrees.map((w) => (\n <Button\n key={w.id}\n variant=\"ghost\"\n size=\"card\"\n className=\"block w-full min-w-0 p-0 text-left font-normal\"\n data-testid={`activity-git-worktree-${w.id}`}\n onClick={onOpen}\n >\n <WorktreeRow\n compact\n worktree={w}\n starting={\n startingIds.includes(w.id) ||\n (!!pending?.includes('starting') && w.sessionId === null && !w.orphaned && !w.unowned)\n }\n />\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/web';\n\nimport { WorktreesActivitySection } from './_components/WorktreesActivitySection';\n\nexport default defineFill({ component: WorktreesActivitySection });\n","import { defineLeaderBinding } from '@agimon-ai/po-core/web';\n\nimport { reviewTab } from '../_components/GitReviewPanel';\n\nexport default defineLeaderBinding({\n path: [\n // The shared g prefix must keep the existing Goal group's label.\n { key: 'g', label: 'goal' },\n { key: 'd', label: 'diff', detail: 'review this checkout’s changes' },\n ],\n run: (context) => context.openTransientTab(reviewTab()),\n});\n","import type { WebPluginRuntime } from '@agimon-ai/po-core/web';\n\nimport { startGitChangesRuntime } from '../../_lib/gitChangesStore';\nimport { startWorktreeRuntime } from '../../_lib/worktreesActivityStore';\n\n/** Binds both hub channels' senders: worktrees, and this session's diff and sync. */\nexport default function startGitRuntime(runtime: WebPluginRuntime): () => void {\n const stopWorktrees = startWorktreeRuntime(runtime);\n const stopChanges = startGitChangesRuntime(runtime);\n return () => {\n stopChanges();\n stopWorktrees();\n };\n}\n","import { defineWebLifecycle } from '@agimon-ai/po-core/web';\n\nimport contribution from './_lib/start.web';\n\nexport default defineWebLifecycle(contribution);\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n Button,\n ChevronDownIcon,\n ChevronUpIcon,\n MessageItem,\n MessageItemBody,\n Spinner,\n StatusBadge,\n} from '@agimon-ai/po-web-components';\n\nconst VERBS: Readonly<Record<string, [string, string, string]>> = {\n spawn_worktree: ['is creating', 'created', 'create'],\n close_worktree: ['is closing', 'closed', 'close'],\n list: ['is listing', 'listed', 'list'],\n status: ['is checking', 'checked', 'check'],\n merge: ['is merging', 'merged', 'merge'],\n prune: ['is pruning', 'pruned', 'prune'],\n send: ['is messaging', 'messaged', 'message'],\n messages: ['is reading messages from', 'read messages from', 'read messages from'],\n};\nexport function RunWorktreeToolMessage({ args, output, running, isError }: ToolMessageRenderProps) {\n return (\n <RunWorktreeToolMessageView\n action={typeof args.action === 'string' ? args.action : ''}\n subject={typeof args.branch === 'string' ? args.branch : typeof args.id === 'string' ? args.id : ''}\n output={output}\n running={running}\n isError={isError}\n />\n );\n}\nexport function RunWorktreeToolMessageView({\n action,\n subject = '',\n output = '',\n running = false,\n isError = false,\n defaultExpanded = false,\n}: {\n action: string;\n subject?: string;\n output?: string;\n running?: boolean;\n isError?: boolean;\n defaultExpanded?: boolean;\n}) {\n const tone = running ? 'neutral' : isError ? 'error' : 'ok';\n const verbs = VERBS[action] ?? ['is running', 'finished', 'run'];\n const rows =\n action === 'list'\n ? output\n .split('\\n')\n .map((line) => line.split(/\\s{2,}/))\n .filter((parts) => parts.length >= 3)\n : [];\n const listingCount = output.match(/^(\\d+) worktree/);\n return (\n <MessageItem tone={tone} expandable defaultExpanded={defaultExpanded} className=\"bg-po-panel\">\n {({ expanded, toggle }) => (\n <>\n <div className=\"flex items-start gap-3 p-4\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-base font-semibold leading-relaxed text-po-hi\">\n Po {isError && !running ? `could not ${verbs[2]}` : verbs[running ? 0 : 1]}{' '}\n {action === 'list' && !running && !isError ? (\n `${listingCount?.[1] ?? rows.length} ${Number(listingCount?.[1] ?? rows.length) === 1 ? 'worktree' : 'worktrees'}`\n ) : subject ? (\n <span className=\"font-mono\">{subject}</span>\n ) : (\n 'worktrees'\n )}\n {running ? '...' : isError && output ? `: ${output.split('\\n')[0]}` : ''}\n </p>\n </div>\n <StatusBadge tone={tone} size=\"xs\" className={running ? 'gap-1 bg-po-rail text-po-dim' : ''}>\n {running && <Spinner className=\"size-3\" label=\"Running\" />}\n {running ? 'Running' : isError ? 'Failed' : 'Completed'}\n </StatusBadge>\n </div>\n <Button variant=\"ghost\" size=\"sm\" onClick={toggle} aria-expanded={expanded} className=\"mb-2 ml-3 text-po-dim\">\n Details {expanded ? <ChevronUpIcon className=\"size-3\" /> : <ChevronDownIcon className=\"size-3\" />}\n </Button>\n {expanded && (\n <MessageItemBody>\n {rows.length > 0 && !isError ? (\n <table className=\"w-full text-left text-sm\">\n <thead>\n <tr className=\"border-b border-po-border-soft\">\n <th className=\"pb-2 font-medium\">Branch</th>\n <th className=\"pb-2 font-medium\">Path</th>\n <th className=\"pb-2 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((parts, i) => {\n const real = parts.length >= 5;\n const status = parts[2];\n return (\n <tr key={i} className=\"border-b border-po-border-soft\">\n <td className=\"py-3 pr-3 font-mono text-po-text\">\n {real ? parts[1] : parts[0]}\n {real && <span className=\"mt-1 block text-po-dim\">{parts[0]}</span>}\n </td>\n <td className=\"py-3 pr-3 font-mono text-po-dim\">\n {real ? parts.slice(4).join(' ') : parts[1]}\n </td>\n <td>\n <StatusBadge\n tone={status === 'orphaned' ? 'neutral' : status === 'unowned' ? 'info' : 'ok'}\n size=\"xs\"\n className={status === 'orphaned' ? 'bg-po-tint-yellow text-po-yellow' : ''}\n >\n {/* The tool prints statuses lowercase; a badge is sentence case. */}\n <span className=\"inline-block first-letter:uppercase\">{status}</span>\n </StatusBadge>\n {real && <span className=\"ml-2 text-po-dim\">{parts[3]}</span>}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n ) : (\n <pre className={`whitespace-pre-wrap font-mono text-sm ${isError ? 'text-po-red' : 'text-po-dim'}`}>\n {output}\n </pre>\n )}\n </MessageItemBody>\n )}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { RunWorktreeToolMessage } from './_components/RunWorktreeToolMessage';\n\nexport default defineToolRenderer({ message: RunWorktreeToolMessage });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport fillGitNewSession from '../src/extensions/workspaces/(frontend)/fill/GitNewSession.new-session.web';\nimport repositorySettingsPanelGit from '../src/extensions/workspaces/(frontend)/repository-settings-panel/git.web';\nimport activityGroupGit from '../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web';\nimport channelGitChanges from '../src/extensions/workspaces/sessions/(frontend)/channel/gitChanges.web';\nimport channelGitWorktrees from '../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web';\nimport fillWorktree from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web';\nimport fillWorktreeCreate from '../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web';\nimport fillWorktrees from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web';\nimport leaderReview from '../src/extensions/workspaces/sessions/(frontend)/leader/review.web';\nimport lifecycleStart from '../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'git',\n workspace: {\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'new-session', id: 'git-new-session' }, fillGitNewSession)]; },\n get repositorySettingsPanel(): WebPluginContributions['repositorySettingsPanel'] { return repositorySettingsPanelGit; },\n },\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'git' }, activityGroupGit)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'git_changes' }, channelGitChanges), via({ channel: 'git_worktrees' }, channelGitWorktrees)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'session-menu', id: 'worktree' }, fillWorktree), via({ slot: 'overlay', id: 'worktree-create' }, fillWorktreeCreate), via({ slot: 'activity.git', id: 'worktrees' }, fillWorktrees)]; },\n get leaderBindings(): WebPluginContributions['leaderBindings'] { return [via({ id: 'git.review' }, leaderReview)]; },\n get start(): WebPluginContributions['start'] { return lifecycleStart; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['run_worktree'] }, toolRunWorktree)]; },\n },\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-git",
3
- "version": "0.0.0-alpha.37",
3
+ "version": "0.0.0-alpha.39",
4
4
  "description": "Git worktree sessions for Po: spawn an isolated worktree with its own session and manage it from the parent",
5
5
  "keywords": [
6
6
  "ai",
@@ -65,29 +65,29 @@
65
65
  "access": "public"
66
66
  },
67
67
  "dependencies": {
68
- "@agimon-ai/po-core": "0.0.0-alpha.37",
69
- "@agimon-ai/po-session": "0.0.0-alpha.37",
70
- "@agimon-ai/po-web-components": "0.0.0-alpha.37",
71
- "@agimon-ai/po-web-security": "0.0.0-alpha.37",
68
+ "@agimon-ai/po-core": "0.0.0-alpha.39",
69
+ "@agimon-ai/po-session": "0.0.0-alpha.39",
70
+ "@agimon-ai/po-web-components": "0.0.0-alpha.39",
71
+ "@agimon-ai/po-web-security": "0.0.0-alpha.39",
72
72
  "@deepseek-ai/cordis": "4.0.5",
73
73
  "@tanstack/react-store": "0.11.2",
74
74
  "@tanstack/store": "0.11.2",
75
- "js-yaml": "5.4.3",
76
- "typebox": "1.3.37"
75
+ "js-yaml": "5.5.0",
76
+ "typebox": "1.4.2"
77
77
  },
78
78
  "devDependencies": {
79
- "@agimon-ai/po-build": "0.0.0-alpha.37",
80
- "@agimon-ai/po-native-components": "0.0.0-alpha.37",
81
- "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.37",
79
+ "@agimon-ai/po-build": "0.0.0-alpha.39",
80
+ "@agimon-ai/po-native-components": "0.0.0-alpha.39",
81
+ "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.39",
82
82
  "@babel/core": "7.29.7",
83
83
  "@earendil-works/pi-agent-core": "1.3.0",
84
84
  "@earendil-works/pi-coding-agent": "1.3.0",
85
85
  "@types/node": "26.6.5",
86
86
  "@types/react": "19.3.0",
87
87
  "@vitest/coverage-v8": "5.0.4",
88
- "react": "19.3.0",
89
- "react-dom": "19.3.0",
90
- "react-native": "0.86.3",
88
+ "react": "19.3.1",
89
+ "react-dom": "19.3.1",
90
+ "react-native": "0.88.0",
91
91
  "react-native-unistyles": "3.5.3",
92
92
  "tsdown": "0.23.1",
93
93
  "typescript": "7.0.2",