@agimon-ai/po-git 0.0.0-alpha.0 → 0.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/native.mjs +1079 -0
- package/dist/extensions/native.mjs.map +1 -0
- package/dist/extensions/web.mjs +9 -23
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +30 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.mjs","names":["isRecord","optionalText","optionalErrorTarget","WebPluginSlotProps","Button","Input","ListRow","Sheet","SheetBody","SheetContent","SheetHeader","SheetTitle","useCallback","useState","useSyncExternalStore","StyleSheet","requestWorktreeClose","requestWorktreeCreate","worktreeActivity","useWorktrees","sessionId","subscribe","listener","sub","store","unsubscribe","select","state","worktreesTab","Parameters","id","label","panel","WorktreesPanel","sessionReservationId","openSession","creating","setCreating","branch","setBranch","baseRef","setBaseRef","closing","setClosing","busy","pending","undefined","styles","body","meta","error","worktrees","map","worktree","card","path","orphaned","unowned","length","trim","open","create","theme","padding","spacing","gap","uni__dependencies","borderWidth","borderColor","colors","borderRadius","md","backgroundColor","color","dim","fontSize","sm","red","styles","isRecord","WebPluginSlotProps","Button","Input","Sheet","SheetBody","SheetContent","SheetHeader","SheetTitle","Textarea","fontOf","useCallback","useEffect","useRef","useState","useSyncExternalStore","StyleSheet","GitDiffRow","GitReviewFileDiff","GitReviewSummary","GitSyncAction","gitChanges","requestGitSync","fetchReviewFile","fetchReviewSummary","addReviewComment","clearReviewComments","gitReview","removeReviewComment","conflictPrompt","deliverToAgent","reviewHeading","useGitChanges","sessionId","subscribe","listener","sub","store","unsubscribe","select","state","reviewTab","Parameters","id","label","panel","GitReviewPanel","sendSessionFrame","activity","comments","summary","setSummary","file","setFile","error","setError","dismissedError","setDismissedError","confirm","setConfirm","draft","setDraft","path","rows","comment","setComment","start","setStart","end","setEnd","request","AbortController","undefined","fingerprint","JSON","stringify","changes","controller","signal","then","result","aborted","ok","catch","cause","Error","message","String","abort","current","loadFile","diff","busy","pending","paused","rebase","send","onSent","failure","sync","action","forceRequired","errorTarget","styles","body","title","branch","meta","base","added","removed","upstream","ahead","behind","ref","actions","conflicts","join","files","map","entry","status","length","repository","truncated","binary","tooLarge","hunks","hunk","index","row","rowIndex","marker","line","content","item","relPath","startLine","endLine","anchor","side","quoted","snippet","split","slice","trim","open","Boolean","Number","isInteger","filter","kept","numbered","Math","min","max","create","theme","padding","spacing","gap","uni__dependencies","flexDirection","flexWrap","color","colors","hi","fontSize","fontWeight","dim","sm","red","fontFamily","mono","green","text","paddingVertical","WebPluginSlotProps","Button","Dot","ListRow","reviewTab","useGitChanges","useWorktrees","worktreesTab","WorktreesActivitySection","sessionId","openTransientTab","git","state","worktrees","filter","item","changes","branch","added","removed","pending","map","id","orphaned","unowned","Boolean","join","length","undefined","activityGroupGit","channelGitChanges","channelGitWorktrees","fillWorktrees","lifecycleStart"],"sources":["../../src/types/webWorktrees.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/worktreesActivityStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/WorktreesPanel.native.tsx","../../src/types/gitReview.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitChangesStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/git.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/git-changes.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/git-worktrees.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/gitReviewView.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/GitReviewPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreesActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.native.ts","../../generated/native.ts"],"sourcesContent":["/**\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/native';\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/native';\nimport {\n Button,\n Input,\n ListRow,\n Sheet,\n SheetBody,\n SheetContent,\n SheetHeader,\n SheetTitle,\n} from '@agimon-ai/po-native-components';\nimport { useCallback, useState, useSyncExternalStore } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { requestWorktreeClose, requestWorktreeCreate, worktreeActivity } from '../_lib/worktreesActivityStore.native';\n\nexport function useWorktrees(sessionId: string | null) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = worktreeActivity.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n return useSyncExternalStore(subscribe, () => worktreeActivity.select(worktreeActivity.store.state, sessionId));\n}\nexport function worktreesTab(): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return { id: 'git-worktrees', label: 'worktrees', panel: WorktreesPanel };\n}\nexport function WorktreesPanel({ sessionId, sessionReservationId, openSession }: WebPluginSlotProps) {\n const state = useWorktrees(sessionId);\n const [creating, setCreating] = useState(false);\n const [branch, setBranch] = useState('');\n const [baseRef, setBaseRef] = useState('');\n const [closing, setClosing] = useState<string>();\n const busy = state.pending !== undefined;\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Button testID=\"git-worktree-create\" disabled={sessionId === null || busy} onPress={() => setCreating(true)}>\n Create a worktree\n </Button>\n {state.pending ? <Text style={styles.meta}>{state.pending}</Text> : null}\n {state.error ? <Text style={styles.error}>{state.error}</Text> : null}\n {state.worktrees.map((worktree) => (\n <View key={worktree.id} style={styles.card}>\n <ListRow\n title={worktree.branch}\n description={`${worktree.path}${worktree.orphaned ? '\\nOrphaned' : ''}${worktree.unowned ? '\\nUnowned' : ''}`}\n />\n {worktree.sessionId && openSession ? (\n <Button variant=\"outline\" onPress={() => openSession(worktree.sessionId!)}>\n Open session\n </Button>\n ) : null}\n <Button\n variant=\"danger-outline\"\n disabled={sessionId === null || busy}\n testID={`git-worktree-close-${worktree.id}`}\n onPress={() => setClosing(worktree.id)}\n >\n Close worktree\n </Button>\n </View>\n ))}\n {state.worktrees.length === 0 ? (\n <Text style={styles.meta}>No worktrees yet. A worktree is its own checkout, branch and session.</Text>\n ) : null}\n <Sheet open={creating} onOpenChange={setCreating}>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Create a worktree</SheetTitle>\n </SheetHeader>\n <SheetBody>\n <View style={styles.body}>\n <Input accessibilityLabel=\"Branch\" placeholder=\"wt/fix-auth\" value={branch} onChangeText={setBranch} />\n <Input\n accessibilityLabel=\"Base ref\"\n placeholder=\"Base (current)\"\n value={baseRef}\n onChangeText={setBaseRef}\n />\n <Text style={styles.meta}>\n Creates the worktree outside the repository and starts a session nested under this one.\n </Text>\n <Button\n disabled={sessionId === null || busy || branch.trim() === ''}\n onPress={() => {\n if (sessionId === null) return;\n requestWorktreeCreate(sessionId, branch, baseRef, sessionReservationId);\n setCreating(false);\n if (sessionReservationId === undefined) {\n setBranch('');\n setBaseRef('');\n }\n }}\n >\n Create\n </Button>\n </View>\n </SheetBody>\n </SheetContent>\n </Sheet>\n <Sheet\n open={closing !== undefined}\n onOpenChange={(open) => {\n if (!open) setClosing(undefined);\n }}\n >\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Close this worktree?</SheetTitle>\n </SheetHeader>\n <SheetBody>\n <Text style={styles.meta}>The checkout is removed. Git refuses a dirty worktree.</Text>\n <Button\n variant=\"danger-outline\"\n disabled={busy}\n onPress={() => {\n if (sessionId !== null && closing !== undefined) requestWorktreeClose(sessionId, closing);\n setClosing(undefined);\n }}\n >\n Close worktree\n </Button>\n </SheetBody>\n </SheetContent>\n </Sheet>\n </ScrollView>\n );\n}\nconst styles = StyleSheet.create((theme) => ({\n body: { padding: theme.spacing(3), gap: theme.spacing(2) },\n card: {\n borderWidth: 1,\n borderColor: theme.colors['border-soft'],\n borderRadius: theme.borderRadius.md,\n backgroundColor: theme.colors.panel,\n padding: theme.spacing(2),\n gap: theme.spacing(1),\n },\n meta: { color: theme.colors.dim, fontSize: theme.fontSize.sm },\n error: { color: theme.colors.red, fontSize: theme.fontSize.sm },\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/native';\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/native';\nimport { BranchIcon } from '@agimon-ai/po-native-components';\nimport { createElement } from 'react';\n\nimport { worktreesTab } from '../_components/WorktreesPanel.native';\nimport { gitChangesActivitySource } from '../_lib/gitChangesStore.native';\nimport { worktreeActivitySource } from '../_lib/worktreesActivityStore.native';\n\nexport default defineActivityGroup({\n keys: 'g w',\n icon: () => createElement(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/native';\n\nimport { gitChangesChannel } from '../_lib/gitChangesStore.native';\nexport default defineChannelFile(gitChangesChannel);\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { worktreesChannel } from '../_lib/worktreesActivityStore.native';\nexport default defineChannelFile(worktreesChannel);\n","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, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\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: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import { api } from '../../../../../../generated/client.native';\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/native';\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 = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\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\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 * 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 type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport {\n Button,\n Input,\n Sheet,\n SheetBody,\n SheetContent,\n SheetHeader,\n SheetTitle,\n Textarea,\n fontOf,\n} from '@agimon-ai/po-native-components';\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { GitDiffRow, GitReviewFileDiff, GitReviewSummary, GitSyncAction } from '../../../../../types/gitReview';\nimport { gitChanges, requestGitSync } from '../_lib/gitChangesStore.native';\nimport { fetchReviewFile, fetchReviewSummary } from '../_lib/gitReviewApi.native';\nimport { addReviewComment, clearReviewComments, gitReview, removeReviewComment } from '../_lib/gitReviewStore.native';\nimport { conflictPrompt, deliverToAgent, reviewHeading } from '../_lib/gitReviewView';\n\nexport function useGitChanges(sessionId: string | null) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = gitChanges.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n return useSyncExternalStore(subscribe, () => gitChanges.select(gitChanges.store.state, sessionId));\n}\nexport function reviewTab(): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return { id: 'git-review', label: 'review', panel: GitReviewPanel };\n}\nexport function GitReviewPanel({ sessionId, sendSessionFrame }: WebPluginSlotProps) {\n const activity = useGitChanges(sessionId);\n const subscribe = useCallback((listener: () => void) => {\n const sub = gitReview.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n const comments = useSyncExternalStore(subscribe, () => gitReview.select(gitReview.store.state, sessionId).comments);\n const [summary, setSummary] = useState<GitReviewSummary>();\n const [file, setFile] = useState<GitReviewFileDiff>();\n const [error, setError] = useState<string>();\n const [dismissedError, setDismissedError] = useState<string>();\n const [confirm, setConfirm] = useState<'force' | 'abort' | 'discard'>();\n const [draft, setDraft] = useState<{ path: string; rows: GitDiffRow[] }>();\n const [comment, setComment] = useState('');\n const [start, setStart] = useState('');\n const [end, setEnd] = useState('');\n const request = useRef<AbortController | undefined>(undefined);\n const fingerprint = JSON.stringify(activity.changes);\n useEffect(() => {\n if (sessionId === null) return undefined;\n const controller = new AbortController();\n void fetchReviewSummary(sessionId, controller.signal)\n .then((result) => {\n if (!controller.signal.aborted) {\n if (result.ok) setSummary(result.summary);\n else setError(result.error);\n }\n })\n .catch((cause: unknown) => {\n if (!controller.signal.aborted) setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n controller.abort();\n request.current?.abort();\n };\n }, [sessionId, fingerprint]);\n const loadFile = async (path: string) => {\n if (sessionId === null) return;\n request.current?.abort();\n const controller = new AbortController();\n request.current = controller;\n setFile(undefined);\n setError(undefined);\n try {\n const result = await fetchReviewFile(sessionId, path, controller.signal);\n if (!controller.signal.aborted) {\n if (result.ok) setFile(result.diff);\n else setError(result.error);\n }\n } catch (cause) {\n if (!controller.signal.aborted) setError(cause instanceof Error ? cause.message : String(cause));\n }\n };\n if (sessionId === null) return null;\n const changes = activity.changes;\n const busy = activity.pending !== undefined;\n const paused = changes?.rebase !== undefined;\n const send = (message: string, onSent?: () => void) => {\n const failure = deliverToAgent(sendSessionFrame, sessionId, message);\n setError(failure);\n if (failure === undefined) onSent?.();\n };\n const sync = (action: GitSyncAction) => requestGitSync(sessionId, action);\n const forceRequired =\n activity.error !== dismissedError &&\n activity.errorTarget?.action === 'push' &&\n activity.errorTarget.forceRequired === true;\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Text style={styles.title}>{changes?.branch ?? 'Detached HEAD'}</Text>\n <Text style={styles.meta}>\n {changes?.base ? `vs ${changes.base}` : 'Uncommitted changes'} · +{changes?.added ?? 0} -{changes?.removed ?? 0}\n \\n\n {changes?.upstream\n ? `↑${changes.upstream.ahead} ↓${changes.upstream.behind} ${changes.upstream.ref}`\n : 'No upstream yet'}\n </Text>\n <View style={styles.actions}>\n <Button\n variant=\"outline\"\n disabled={busy || paused || changes?.upstream === undefined}\n onPress={() => sync('pull')}\n >\n Pull\n </Button>\n <Button\n variant=\"outline\"\n disabled={busy || paused || changes?.branch === undefined}\n onPress={() => sync('push')}\n >\n Push\n </Button>\n <Button\n variant=\"outline\"\n disabled={busy || paused || changes?.base === undefined}\n onPress={() => sync('rebase')}\n >\n Rebase\n </Button>\n </View>\n {activity.pending ? <Text style={styles.meta}>{activity.pending}</Text> : null}\n {activity.error && activity.error !== dismissedError ? (\n <View>\n <Text style={styles.error}>{activity.error}</Text>\n <Button variant=\"ghost\" onPress={() => setDismissedError(activity.error)}>\n Dismiss\n </Button>\n </View>\n ) : null}\n {forceRequired ? (\n <Button variant=\"danger-outline\" disabled={busy} onPress={() => setConfirm('force')}>\n Force push with lease…\n </Button>\n ) : null}\n {paused ? (\n <View style={styles.body}>\n <Text style={styles.error}>Rebase paused\\n{changes.rebase?.conflicts.join('\\n')}</Text>\n <Button disabled={busy} onPress={() => send(conflictPrompt(changes.branch, changes.rebase?.conflicts ?? []))}>\n Ask agent to resolve\n </Button>\n <Button variant=\"danger-outline\" disabled={busy} onPress={() => setConfirm('abort')}>\n Abort rebase…\n </Button>\n </View>\n ) : null}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {summary ? (\n summary.files.map((entry) => (\n <Button\n key={entry.path}\n variant=\"ghost\"\n testID={`git-review-file-${entry.path}`}\n onPress={() => void loadFile(entry.path)}\n >\n {entry.path} · {entry.status} · +{entry.added} -{entry.removed}\n </Button>\n ))\n ) : (\n <Text style={styles.meta}>Loading changes…</Text>\n )}\n {summary?.files.length === 0 ? (\n <Text style={styles.meta}>{summary.repository ? 'No changed files' : 'Not a Git checkout'}</Text>\n ) : null}\n {summary?.truncated ? <Text style={styles.meta}>The file list was truncated.</Text> : null}\n {file ? (\n <View style={styles.body}>\n <Text style={styles.title}>{file.path}</Text>\n {file.binary || file.tooLarge ? (\n <Text style={styles.meta}>{file.binary ? 'Binary file' : 'Diff too large to display'}</Text>\n ) : (\n file.hunks.map((hunk, index) => (\n <View key={index}>\n {hunk.rows.map((row, rowIndex) => (\n <Text\n selectable\n key={rowIndex}\n style={styles.diff(row.marker)}\n onPress={() => {\n setDraft({ path: file.path, rows: hunk.rows });\n setStart(String(row.line));\n setEnd(String(row.line));\n }}\n >\n {row.marker} {row.line} {row.content}\n </Text>\n ))}\n </View>\n ))\n )}\n <Button\n variant=\"outline\"\n onPress={() => {\n setDraft({ path: file.path, rows: [] });\n setStart('');\n setEnd('');\n }}\n >\n Comment on file\n </Button>\n </View>\n ) : null}\n {comments.map((item) => (\n <View key={item.id}>\n <Text style={styles.meta}>\n {item.relPath}\n {item.startLine === undefined ? '' : `:${item.startLine}-${item.endLine ?? item.startLine}`}\\n{item.body}\n </Text>\n <Button variant=\"ghost\" onPress={() => removeReviewComment(sessionId, item.id)}>\n Remove comment\n </Button>\n </View>\n ))}\n {comments.length > 0 ? (\n <View style={styles.actions}>\n <Button\n onPress={() => {\n const body = comments\n .map((item) => {\n const anchor =\n item.startLine === undefined\n ? item.relPath\n : item.side === 'old'\n ? `${item.relPath} (removed lines ${item.startLine}-${item.endLine ?? item.startLine})`\n : `${item.relPath}:${item.startLine}-${item.endLine ?? item.startLine}`;\n const quoted = item.snippet\n .split('\\n')\n .slice(0, 20)\n .join('\\n')\n .slice(0, 2000)\n .split('\\n')\n .map((line) => `> ${line}`)\n .join('\\n');\n return `### ${anchor}\\n\\n${quoted}\\n\\n${item.body.trim()}`;\n })\n .join('\\n\\n');\n send(`${reviewHeading(comments.length, summary?.branch, summary?.base)}\\n\\n${body}`, () =>\n clearReviewComments(sessionId),\n );\n }}\n >\n Send review\n </Button>\n <Button variant=\"outline\" onPress={() => setConfirm('discard')}>\n Discard review…\n </Button>\n </View>\n ) : null}\n <Sheet\n open={draft !== undefined}\n onOpenChange={(open) => {\n if (!open) setDraft(undefined);\n }}\n >\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Review comment</SheetTitle>\n </SheetHeader>\n <SheetBody>\n <View style={styles.body}>\n {draft?.rows.length ? (\n <>\n <Input\n accessibilityLabel=\"Start line\"\n value={start}\n onChangeText={setStart}\n keyboardType=\"number-pad\"\n />\n <Input accessibilityLabel=\"End line\" value={end} onChangeText={setEnd} keyboardType=\"number-pad\" />\n </>\n ) : null}\n <Textarea accessibilityLabel=\"Comment\" value={comment} onChangeText={setComment} />\n <Button\n disabled={\n comment.trim() === '' ||\n (Boolean(draft?.rows.length) &&\n (!Number.isInteger(Number(start)) ||\n Number(start) < 1 ||\n !Number.isInteger(Number(end)) ||\n Number(end) < Number(start)))\n }\n onPress={() => {\n if (!draft) return;\n const rows = draft.rows.filter((row) => row.line >= Number(start) && row.line <= Number(end));\n const kept = rows.filter((row) => row.marker !== '-');\n const numbered = kept.length > 0 ? kept : rows;\n addReviewComment(sessionId, {\n path: draft.path,\n relPath: draft.path,\n body: comment.trim(),\n snippet: numbered.map((row) => row.content).join('\\n'),\n ...(numbered.length === 0\n ? {}\n : {\n side: kept.length > 0 ? 'new' : 'old',\n startLine: Math.min(...numbered.map((row) => row.line)),\n endLine: Math.max(...numbered.map((row) => row.line)),\n }),\n });\n setDraft(undefined);\n setComment('');\n }}\n >\n Add comment\n </Button>\n </View>\n </SheetBody>\n </SheetContent>\n </Sheet>\n <Sheet\n open={confirm !== undefined}\n onOpenChange={(open) => {\n if (!open) setConfirm(undefined);\n }}\n >\n <SheetContent>\n <SheetHeader>\n <SheetTitle>\n {confirm === 'force'\n ? 'Force push with lease?'\n : confirm === 'abort'\n ? 'Abort rebase?'\n : 'Discard review?'}\n </SheetTitle>\n </SheetHeader>\n <SheetBody>\n <Text style={styles.meta}>\n {confirm === 'force'\n ? 'Git refuses this if the remote holds commits you never fetched and integrated.'\n : confirm === 'abort'\n ? 'Abort discards any conflict resolution in progress.'\n : 'Your queued comments will be removed.'}\n </Text>\n <Button\n variant=\"danger-outline\"\n onPress={() => {\n if (confirm === 'force') requestGitSync(sessionId, 'push', true);\n else if (confirm === 'abort') sync('abort-rebase');\n else clearReviewComments(sessionId);\n setConfirm(undefined);\n }}\n >\n Confirm\n </Button>\n </SheetBody>\n </SheetContent>\n </Sheet>\n </ScrollView>\n );\n}\nconst styles = StyleSheet.create((theme) => ({\n body: { padding: theme.spacing(3), gap: theme.spacing(2) },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: theme.spacing(1) },\n title: { color: theme.colors.hi, fontSize: theme.fontSize.base, fontWeight: '600' },\n meta: { color: theme.colors.dim, fontSize: theme.fontSize.sm },\n error: { color: theme.colors.red, fontSize: theme.fontSize.sm },\n diff: (marker: GitDiffRow['marker']) => ({\n fontFamily: fontOf(theme.fontFamily.mono),\n fontSize: theme.fontSize.sm,\n color: marker === '+' ? theme.colors.green : marker === '-' ? theme.colors.red : theme.colors.text,\n paddingVertical: theme.spacing(1),\n }),\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, Dot, ListRow } from '@agimon-ai/po-native-components';\nimport { View } from 'react-native';\n\nimport { reviewTab, useGitChanges } from '../../_components/GitReviewPanel.native';\nimport { useWorktrees, worktreesTab } from '../../_components/WorktreesPanel.native';\n\nexport function WorktreesActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {\n const git = useGitChanges(sessionId);\n const state = useWorktrees(sessionId);\n const worktrees = state.worktrees.filter((item) => item.sessionId !== sessionId);\n return (\n <View>\n {git.changes ? (\n <Button variant=\"ghost\" testID=\"activity-diff-changes\" onPress={() => openTransientTab(reviewTab())}>\n {git.changes.branch ?? 'Detached HEAD'} · +{git.changes.added} -{git.changes.removed}\n </Button>\n ) : null}\n {state.pending ? <ListRow title={state.pending} /> : null}\n {worktrees.map((item) => (\n <ListRow\n key={item.id}\n leading={<Dot tone={item.orphaned ? 'red' : item.sessionId === null ? 'muted' : 'blue'} />}\n title={\n <Button variant=\"ghost\" onPress={() => openTransientTab(worktreesTab())}>\n {item.branch}\n </Button>\n }\n description={[item.orphaned ? 'Orphaned' : '', item.unowned ? 'Unowned' : ''].filter(Boolean).join(' · ')}\n />\n ))}\n {worktrees.length === 0 && state.pending === undefined ? (\n <Button\n variant=\"ghost\"\n testID=\"activity-git-create\"\n disabled={sessionId === null}\n onPress={() => openTransientTab(worktreesTab())}\n >\n Create a worktree\n </Button>\n ) : null}\n </View>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { WorktreesActivitySection } from './_components/WorktreesActivitySection.native';\nexport default defineFill({ component: WorktreesActivitySection });\n","import { defineWebLifecycle } from '@agimon-ai/po-core/native';\n\nimport { startGitChangesRuntime } from '../_lib/gitChangesStore.native';\nimport { startWorktreeRuntime } from '../_lib/worktreesActivityStore.native';\nexport default defineWebLifecycle((runtime) => {\n const stopWorktrees = startWorktreeRuntime(runtime);\n const stopChanges = startGitChangesRuntime(runtime);\n return () => {\n stopChanges();\n stopWorktrees();\n };\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport activityGroupGit from '../src/extensions/workspaces/sessions/(frontend)/activity-group/git.native';\nimport channelGitChanges from '../src/extensions/workspaces/sessions/(frontend)/channel/git-changes.native';\nimport channelGitWorktrees from '../src/extensions/workspaces/sessions/(frontend)/channel/git-worktrees.native';\nimport fillWorktrees from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.native';\nimport lifecycleStart from '../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'git',\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: 'activity.git', id: 'worktrees' }, fillWorktrees)]; },\n get start(): WebPluginContributions['start'] { return lifecycleStart; },\n },\n});\n"],"mappings":"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"}
|
package/dist/extensions/web.mjs
CHANGED
|
@@ -1,64 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createApiClient, defineActivityGroup, defineChannelFile, defineFill, defineGlobalStore, defineLeaderBinding, defineRepositorySettingsPanel, defineSessionStore, defineToolRenderer, defineWebLifecycle, defineWebPlugin, sessionApiAddress } from "@agimon-ai/po-core/web";
|
|
2
2
|
import { AlertIcon, ArrowRightIcon, BranchIcon, Button, CheckIcon, ChevronDownIcon, ChevronRightIcon, CloseIcon, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DiffView, Dot, DropdownMenuItem, EmptyState, Input, MessageIcon, MessageItem, MessageItemBody, MessageItemHeader, OptionRow, RadioGroup, RadioGroupCard, ReviewCommentDraft, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SettingsActions, SettingsCard, SettingsField, SettingsNote, SettingsRow, SettingsRowDescription, SettingsRowText, SettingsRowTitle, SettingsSection, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle, ShieldIcon, Spinner, StatusBadge, buildReviewPrompt, reviewCommentAnchor, toolTone } from "@agimon-ai/po-web-components";
|
|
3
3
|
import { createElement, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { sealedTransport } 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
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The routes the page calls, as data.
|
|
10
|
-
*
|
|
11
|
-
* No scope and no base path: the build reads both off
|
|
12
|
-
* `src/extensions/(backend)/api/git/`, which mounts at global scope and so
|
|
13
|
-
* answers workspace and session requests too. Each route answers only where it
|
|
14
|
-
* belongs (auth on a workspace mount, the review on a session mount), so a
|
|
15
|
-
* client accessor on the wrong scope gets a 404 rather than a second way in.
|
|
16
|
-
*
|
|
17
|
-
* Only what the browser calls is listed. The worktree routes stay HTTP for
|
|
18
|
-
* other callers, but the dock drives worktrees over its channel.
|
|
19
|
-
*/
|
|
20
|
-
var apiRoutes_default = defineApiRoutes({
|
|
7
|
+
const api = createApiClient({
|
|
21
8
|
/** Workspace: the new-session dialog's branch list. */
|
|
22
9
|
branches: {
|
|
23
10
|
method: "GET",
|
|
24
11
|
path: "/branches",
|
|
25
|
-
response:
|
|
12
|
+
response: void 0
|
|
26
13
|
},
|
|
27
14
|
/** Workspace: a top-level worktree session on an existing or new branch. */
|
|
28
15
|
createSession: {
|
|
29
16
|
method: "POST",
|
|
30
17
|
path: "/sessions",
|
|
31
|
-
response:
|
|
18
|
+
response: void 0
|
|
32
19
|
},
|
|
33
20
|
/** Workspace: that workspace's saved remote auth, never the token itself. */
|
|
34
21
|
auth: {
|
|
35
22
|
method: "GET",
|
|
36
23
|
path: "/auth",
|
|
37
24
|
query: ["repositoryId"],
|
|
38
|
-
response:
|
|
25
|
+
response: void 0
|
|
39
26
|
},
|
|
40
27
|
/** Workspace: replaces that workspace's remote auth. Passkey step-up gated for remote devices. */
|
|
41
28
|
saveAuth: {
|
|
42
29
|
method: "PUT",
|
|
43
30
|
path: "/auth",
|
|
44
31
|
query: ["repositoryId"],
|
|
45
|
-
response:
|
|
32
|
+
response: void 0
|
|
46
33
|
},
|
|
47
34
|
/** Session: the files this session's checkout changed against its base. */
|
|
48
35
|
review: {
|
|
49
36
|
method: "GET",
|
|
50
37
|
path: "/review",
|
|
51
|
-
response:
|
|
38
|
+
response: void 0
|
|
52
39
|
},
|
|
53
40
|
/** Session: one changed file's hunks. */
|
|
54
41
|
reviewFile: {
|
|
55
42
|
method: "GET",
|
|
56
43
|
path: "/review/file",
|
|
57
44
|
query: ["path"],
|
|
58
|
-
response:
|
|
45
|
+
response: void 0
|
|
59
46
|
}
|
|
60
|
-
}
|
|
61
|
-
const api = createApiClient(apiRoutes_default, {
|
|
47
|
+
}, {
|
|
62
48
|
scopes: [
|
|
63
49
|
"global",
|
|
64
50
|
"workspace",
|