@agimon-ai/po-artifact 0.0.0-alpha.71 → 0.0.0-alpha.73
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.
|
@@ -631,7 +631,7 @@ function ArtifactBrowser({ items, onOpen, loading, error, browser: b }) {
|
|
|
631
631
|
renderItem: ({ item: row }) => {
|
|
632
632
|
if (row.kind === "dir") return /* @__PURE__ */ jsxs(Button, {
|
|
633
633
|
variant: "ghost",
|
|
634
|
-
style: [styles$3.row,
|
|
634
|
+
style: [styles$3.row, styles$3.indent(row.depth)],
|
|
635
635
|
accessibilityLabel: `${row.open ? "Collapse" : "Expand"} ${row.path}`,
|
|
636
636
|
accessibilityState: { expanded: row.open },
|
|
637
637
|
onPress: () => b.onToggleDirectory(row.path),
|
|
@@ -662,7 +662,7 @@ function ArtifactBrowser({ items, onOpen, loading, error, browser: b }) {
|
|
|
662
662
|
style: [
|
|
663
663
|
grid ? styles$3.tile : styles$3.row,
|
|
664
664
|
selected && styles$3.selected,
|
|
665
|
-
!grid &&
|
|
665
|
+
!grid && styles$3.indent(row.depth)
|
|
666
666
|
],
|
|
667
667
|
children: [
|
|
668
668
|
b.layout === "tree" ? /* @__PURE__ */ jsx(View, {
|
|
@@ -812,8 +812,13 @@ const styles$3 = StyleSheet.create((theme) => ({
|
|
|
812
812
|
borderColor: theme.colors["border-soft"],
|
|
813
813
|
borderRadius: theme.borderRadius.DEFAULT,
|
|
814
814
|
paddingVertical: theme.spacing(2),
|
|
815
|
+
paddingRight: theme.spacing(3),
|
|
815
816
|
uni__dependencies: [0]
|
|
816
817
|
},
|
|
818
|
+
indent: (depth) => ({
|
|
819
|
+
paddingLeft: theme.spacing(3) + depth * 16,
|
|
820
|
+
uni__dependencies: [0]
|
|
821
|
+
}),
|
|
817
822
|
chevronGutter: { width: 16 },
|
|
818
823
|
columns: {
|
|
819
824
|
gap: theme.spacing(2),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.mjs","names":["Button","FolderIcon","FileIcon","ImageIcon","SearchIcon","SlidersIcon","CloseIcon","ChevronDownIcon","ChevronRightIcon","Input","SegmentedControl","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","DropdownMenuCheckboxItem","DropdownMenuSeparator","fontOf","Sheet","SheetContent","SheetList","PoNativeTheme","useCallback","ReactNode","ListViewToken","StyleSheet","ArtifactItem","artifactKind","sizeLabel","isArtifactLayout","ArtifactLayout","ArtifactKind","ArtifactModified","ArtifactSort","ArtifactSortDirection","ArtifactTreeRow","ArtifactBrowserProps","layout","onLayoutChange","query","onQueryChange","type","onTypeChange","modified","onModifiedChange","sort","onSortChange","direction","onDirectionChange","rows","onToggleDirectory","path","selected","onSelect","item","onCloseSelection","totalCount","onViewableImagesChange","paths","renderImage","header","sheet","ArtifactListProps","items","onOpen","loading","error","grid","browser","ArtifactList","styles","list","meta","length","map","label","name","size","toLocaleString","LAYOUTS","value","TYPES","const","MODIFIED","SORTS","ROW_HEIGHT","IMAGE_VIEWABILITY","itemVisiblePercentThreshold","ArtifactBrowser","b","onViewableItemsChanged","viewableItems","Omit","flatMap","isViewable","kind","depth","List","FlatList","embedded","columns","undefined","row","head","toolbar","search","searchInput","chips","find","option","inset","paddingLeft","open","expanded","count","image","tile","chevronGutter","thumbnail","foot","selection","actions","create","theme","gap","spacing","padding","paddingBottom","uni__dependencies","paddingTop","paddingHorizontal","flexDirection","alignItems","flex","minWidth","borderWidth","borderColor","colors","border","borderRadius","DEFAULT","backgroundColor","deep","flexWrap","marginHorizontal","marginBottom","minHeight","justifyContent","paddingVertical","width","maxWidth","height","overflow","flexShrink","panel","fontFamily","sans","fontWeight","fontSize","base","color","text","mono","sm","dim","red","styles","WebPluginSlotProps","CodeBlock","Markdown","fontOf","PoNativeTheme","StyleSheet","ArtifactPreview","Preview","artifactAssetPath","artifactPreviewMode","ArtifactPreviewProps","preview","sessionId","renderFilePreview","renderMediaPreview","media","data","mimeType","mediaError","onOpen","path","mode","styles","error","meta","key","title","unavailable","reason","html","content","resolved","undefined","split","at","text","create","theme","minHeight","spacing","uni__dependencies","fontFamily","mono","fontSize","sm","lineHeight","color","colors","sans","dim","red","styles","WebPluginSlotProps","Button","CloseIcon","CopyButton","DownloadIcon","fontOf","PoNativeTheme","useEffect","useRef","useState","StyleSheet","ArtifactPreview","Preview","ArtifactScope","fetchArtifactMedia","fetchArtifactPreview","prepareArtifactSave","artifactKind","artifactPreviewMode","artifactTabId","modifiedLabel","sizeLabel","useArtifacts","Loaded","key","preview","error","media","data","mimeType","mediaError","HostCopyButton","ArtifactPanel","path","scope","props","snapshot","sessionId","item","items","find","version","modifiedAt","size","downloadKey","loaded","setLoaded","controller","AbortController","signal","then","aborted","renderMediaPreview","Error","message","String","catch","abort","current","undefined","downloadController","download","setDownload","saving","note","save","nativeSaveFile","file","cancel","handlers","setTabHeader","canSave","subtitle","offline","action","styles","meta","body","renderFilePreview","openTransientTab","artifactTab","screen","stage","content","ArtifactPathStrip","now","Date","strip","stripPath","ArtifactPanelHeader","disabled","onDownload","onCancel","header","label","Parameters","id","split","at","panel","create","theme","rt","flex","padding","spacing","gap","uni__dependencies","flexDirection","alignItems","paddingHorizontal","paddingTop","paddingBottom","insets","bottom","borderTopWidth","borderTopColor","colors","backgroundColor","bg","flexShrink","borderBottomWidth","borderBottomColor","minWidth","fontFamily","mono","fontSize","sm","color","dim","sans","red","styles","WebPluginSlotProps","ImageIcon","useEffect","useState","useSyncExternalStore","StyleSheet","ArtifactItem","fetchArtifactMedia","artifactLayout","artifacts","markArtifactViewed","artifactTree","filterArtifacts","sortArtifacts","ArtifactKind","ArtifactModified","ArtifactSort","ArtifactSortDirection","authorSourceAction","useArtifacts","ArtifactList","artifactTab","authorTab","props","path","sessionId","undefined","createTab","ArtifactsPanel","SessionArtifactsPanel","snapshot","layout","listener","subscription","store","subscribe","unsubscribe","state","now","setNow","Date","query","setQuery","type","setType","modified","setModified","sort","setSort","direction","setDirection","expanded","setExpanded","selection","setSelection","viewable","setViewable","loaded","items","some","item","hasFilters","visible","error","openTransientTab","find","entry","header","dockHeader","sheet","onLayoutChange","next","update","onQueryChange","onTypeChange","onModifiedChange","value","onSortChange","onDirectionChange","rows","includes","onToggleDirectory","paths","filter","selected","onSelect","onCloseSelection","totalCount","length","onViewableImagesChange","renderImage","modifiedAt","size","ArtifactThumbnail","active","uri","setUri","controller","AbortController","signal","then","media","aborted","mimeType","startsWith","data","catch","abort","name","styles","image","create","width","height","channelArtifacts","dockArtifacts","fileLinksArtifacts"],"sources":["../../src/types/artifacts.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactView.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactsStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/artifacts.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactsApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/authorSourceAction.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/artifactHooks.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactList.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactPreview.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactsPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/dock/artifacts.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_lib/temporaryFiles.ts","../../src/extensions/workspaces/sessions/(frontend)/file-links/artifacts.native.ts","../../generated/native.ts"],"sourcesContent":["export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { COMPACTION_ARTIFACT_DIRECTORY } from '../../../../../constants/artifacts';\nimport type { ArtifactItem, ArtifactSnapshot } from '../../../../../types/artifacts';\n\nexport type ArtifactLayout = 'tree' | 'list' | 'grid';\nexport type ArtifactKind = 'Markdown' | 'Image' | 'Code' | 'Data' | 'Document' | 'Other';\nexport type ArtifactModified = 'any' | 'today' | '7days' | '30days';\nexport type ArtifactSort = 'name' | 'size' | 'modified';\nexport type ArtifactSortDirection = 'asc' | 'desc';\n\nexport interface ArtifactFilters {\n query?: string;\n type?: ArtifactKind | 'any';\n modified?: ArtifactModified;\n}\n\nexport function isArtifactLayout(value: unknown): value is ArtifactLayout {\n return value === 'tree' || value === 'list' || value === 'grid';\n}\n\nexport function artifactKind(path: string): ArtifactKind {\n if (/\\.(?:md|markdown)$/iu.test(path)) return 'Markdown';\n if (/\\.(?:png|jpe?g|gif|webp|avif|bmp|svg|ico|tiff?)$/iu.test(path)) return 'Image';\n if (/\\.(?:jsonl?|csv|tsv|ya?ml|xml|toml|parquet|sqlite|db)$/iu.test(path)) return 'Data';\n if (\n /\\.(?:[cm]?[jt]sx?|html?|css|scss|sass|less|py|sh|bash|go|rs|rb|java|c|cpp|cc|h|hpp|sql|swift|kt|kts|php|vue|svelte)$/iu.test(\n path,\n )\n )\n return 'Code';\n if (/\\.(?:pdf|txt|rtf|docx?|xlsx?|pptx?|odt|ods|odp)$/iu.test(path)) return 'Document';\n return 'Other';\n}\n\n/** Time is supplied by the caller. Today starts at local midnight; day windows are inclusive. */\nexport function filterArtifacts(items: readonly ArtifactItem[], filters: ArtifactFilters, now: number): ArtifactItem[] {\n const query = (filters.query ?? '').trim().toLowerCase();\n const modified = filters.modified ?? 'any';\n const day = 24 * 60 * 60 * 1000;\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n const since = modified === 'today' ? midnight.getTime() : now - (modified === '7days' ? 7 : 30) * day;\n return items.filter(\n (item) =>\n item.path.toLowerCase().includes(query) &&\n (!filters.type || filters.type === 'any' || artifactKind(item.path) === filters.type) &&\n (modified === 'any' || (item.modifiedAt >= since && item.modifiedAt <= now)),\n );\n}\n\n/** Sort a copy, with an ascending full-path tie breaker in either direction. */\nexport function sortArtifacts(\n items: readonly ArtifactItem[],\n sort: ArtifactSort,\n direction: ArtifactSortDirection,\n): ArtifactItem[] {\n return [...items].sort((left, right) => {\n const order =\n sort === 'name'\n ? comparePaths(left.name.toLowerCase(), right.name.toLowerCase())\n : sort === 'size'\n ? left.size - right.size\n : left.modifiedAt - right.modifiedAt;\n return order * (direction === 'asc' ? 1 : -1) || comparePaths(left.path, right.path);\n });\n}\n\nfunction comparePaths(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n\ninterface ArtifactDirectory {\n path: string;\n dirs: Map<string, ArtifactDirectory>;\n files: ArtifactItem[];\n count: number;\n}\n\nexport type ArtifactTreeRow =\n | { kind: 'dir'; path: string; name: string; depth: number; open: boolean; count: number }\n | { kind: 'file'; item: ArtifactItem; depth: number };\n\n/** Derive folders from already filtered, sorted files. Folders precede files and compact single-child chains. */\nexport function artifactTree(items: readonly ArtifactItem[], isOpen: (path: string) => boolean): ArtifactTreeRow[] {\n const root: ArtifactDirectory = { path: '', dirs: new Map(), files: [], count: 0 };\n for (const item of items) {\n let dir = root;\n dir.count++;\n for (const segment of item.path.split('/').slice(0, -1)) {\n let next = dir.dirs.get(segment);\n if (!next) {\n next = { path: dir.path ? `${dir.path}/${segment}` : segment, dirs: new Map(), files: [], count: 0 };\n dir.dirs.set(segment, next);\n }\n dir = next;\n dir.count++;\n }\n dir.files.push(item);\n }\n const rows: ArtifactTreeRow[] = [];\n const walk = (dir: ArtifactDirectory, depth: number): void => {\n for (const [segment, child] of [...dir.dirs].sort(([left], [right]) => comparePaths(left, right))) {\n let name = segment;\n let node = child;\n while (node.files.length === 0 && node.dirs.size === 1) {\n const [[nextName, next]] = [...node.dirs] as [[string, ArtifactDirectory]];\n name = `${name}/${nextName}`;\n node = next;\n }\n const open = isOpen(node.path);\n rows.push({ kind: 'dir', path: node.path, name, depth, open, count: node.count });\n if (open) walk(node, depth + 1);\n }\n for (const item of dir.files) rows.push({ kind: 'file', item, depth });\n };\n walk(root, 0);\n return rows;\n}\n\n/** `Modified today` on the same calendar day, otherwise the short date. */\nexport function modifiedLabel(modifiedAt: number, now: number): string {\n const date = new Date(modifiedAt);\n return date.toDateString() === new Date(now).toDateString()\n ? 'Modified today'\n : `Modified ${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`;\n}\n\n/** What the person has seen: New (never opened), Edited (changed since opened), or Viewed. */\nexport type ArtifactStatus = 'new' | 'edited' | 'viewed';\n\n/** One session's seen record in this browser. */\nexport interface ArtifactSeenRecord {\n /** Newest server mtime when this browser first saw the session; older unopened files count as seen. */\n baseline: number;\n /** The mtime each file had when the person last opened it. */\n seen: Readonly<Record<string, number>>;\n}\n\nexport function artifactStatus(item: ArtifactItem, record: ArtifactSeenRecord | undefined): ArtifactStatus {\n if (record === undefined) return 'viewed';\n const seen = record.seen[item.path];\n if (seen !== undefined) return item.modifiedAt > seen ? 'edited' : 'viewed';\n return item.modifiedAt > record.baseline ? 'new' : 'viewed';\n}\n\n/** The web rail has no List layout; a stored `list` (shared with native) reads as Tree there. */\nexport type ArtifactRailLayout = 'tree' | 'grid';\nexport type ArtifactStatusFilter = 'all' | ArtifactStatus;\nexport type ArtifactLocation = 'artifacts' | 'temporary';\n\nexport interface ArtifactRailFilters {\n status: ArtifactStatusFilter;\n type: ArtifactKind | 'any';\n modified: ArtifactModified;\n location: ArtifactLocation;\n}\n\nexport const DEFAULT_ARTIFACT_RAIL_FILTERS: ArtifactRailFilters = {\n status: 'all',\n type: 'any',\n modified: 'any',\n location: 'artifacts',\n};\n\n/** Compact age for a narrow row: `now`, `5m`, `3h`, `2d`, then the short date. */\nexport function ageLabel(modifiedAt: number, now: number): string {\n const minutes = Math.floor(Math.max(0, now - modifiedAt) / 60000);\n if (minutes < 1) return 'now';\n if (minutes < 60) return `${minutes}m`;\n if (minutes < 60 * 24) return `${Math.floor(minutes / 60)}h`;\n if (minutes < 60 * 24 * 7) return `${Math.floor(minutes / (60 * 24))}d`;\n return new Date(modifiedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\nexport function sizeLabel(size: number): string {\n return size < 1024\n ? `${size} B`\n : size < 1024 * 1024\n ? `${Math.ceil(size / 1024)} KB`\n : `${(size / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function sortedArtifacts(items: readonly ArtifactItem[]): ArtifactItem[] {\n return [...items].sort(\n (left, right) =>\n right.modifiedAt - left.modifiedAt || (left.path < right.path ? -1 : left.path > right.path ? 1 : 0),\n );\n}\n\n/** The recent card shows the person's documents; compaction history stays in the full grid. */\nexport function recentArtifacts(items: readonly ArtifactItem[]): ArtifactItem[] {\n return sortedArtifacts(items.filter((item) => !item.path.startsWith(`${COMPACTION_ARTIFACT_DIRECTORY}/`))).slice(\n 0,\n 3,\n );\n}\n\nexport function artifactTabId(sessionId: string, path: string): string {\n return `artifact:${encodeURIComponent(sessionId)}:${encodeURIComponent(path)}`;\n}\n\n/** Resolves document assets within the artifact folder, never into another filesystem root. */\nexport function artifactAssetPath(documentPath: string, imagePath: string): string {\n if (!imagePath || imagePath.startsWith('/') || imagePath.includes('\\\\') || /^[a-z][a-z0-9+.-]*:/iu.test(imagePath))\n throw new Error('Artifact images must use a relative path.');\n const segments = documentPath.split('/').slice(0, -1);\n for (const segment of imagePath.split('/')) {\n if (segment === '' || segment === '.') continue;\n if (segment === '..') {\n if (segments.length === 0) throw new Error('The image is outside this artifact folder.');\n segments.pop();\n } else segments.push(segment);\n }\n if (segments.length === 0) throw new Error('The image path is empty.');\n return segments.join('/');\n}\n\nexport function artifactPreviewMode(path: string): 'markdown' | 'html' | 'media' | 'code' | 'text' {\n if (/\\.(?:png|jpe?g|gif|webp|avif|bmp|svg|ico|mp3|wav|m4a|ogg|mp4|mov|webm|pdf)$/iu.test(path)) return 'media';\n if (/\\.(?:md|markdown)$/iu.test(path)) return 'markdown';\n if (/\\.html?$/iu.test(path)) return 'html';\n if (/\\.(?:[cm]?[jt]sx?|json|ya?ml|css|scss|py|sh|bash|go|rs|rb|java|c|cpp|h|sql|xml|toml)$/iu.test(path))\n return 'code';\n return 'text';\n}\n\n/** A malformed channel frame must not replace the current session's known inventory. */\nexport function parseArtifactSnapshot(input: unknown): ArtifactSnapshot | null {\n if (typeof input !== 'object' || input === null || !('items' in input) || !Array.isArray(input.items)) return null;\n if ('error' in input && input.error !== undefined && typeof input.error !== 'string') return null;\n const items: ArtifactItem[] = [];\n for (const item of input.items) {\n if (\n typeof item !== 'object' ||\n item === null ||\n typeof item.path !== 'string' ||\n !item.path ||\n item.path.startsWith('/') ||\n item.path.includes('\\\\') ||\n item.path.split('/').some((part: string) => part === '..' || part === '.') ||\n typeof item.name !== 'string' ||\n !item.name ||\n typeof item.size !== 'number' ||\n !Number.isFinite(item.size) ||\n item.size < 0 ||\n typeof item.modifiedAt !== 'number' ||\n !Number.isFinite(item.modifiedAt) ||\n item.modifiedAt < 0\n )\n return null;\n items.push({ path: item.path, name: item.name, size: item.size, modifiedAt: item.modifiedAt });\n }\n return {\n items: sortedArtifacts(items),\n ...('temporaryRoot' in input && typeof input.temporaryRoot === 'string'\n ? { temporaryRoot: input.temporaryRoot }\n : {}),\n ...('error' in input && typeof input.error === 'string' ? { error: input.error } : {}),\n };\n}\n","import { defineGlobalStore, defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { artifactsChannelType, type ArtifactItem, type ArtifactSnapshot } from '../../../../../types/artifacts';\nimport {\n artifactStatus,\n parseArtifactSnapshot,\n sortedArtifacts,\n type ArtifactLayout,\n type ArtifactSeenRecord,\n} from './artifactView';\n\n/** Shared across browser mounts, in memory only until the native app restarts. */\nexport const artifactLayout = defineGlobalStore<ArtifactLayout>('tree');\n\nexport interface ArtifactsSession extends ArtifactSnapshot {\n loaded: boolean;\n}\n\nexport const artifacts = defineSessionStore<ArtifactsSession>({ items: [], loaded: false });\n\nexport const artifactsChannel = artifacts.channel<ArtifactSnapshot>({\n channel: artifactsChannelType,\n parse: parseArtifactSnapshot,\n reduce: (_current, snapshot) => ({ ...snapshot, items: sortedArtifacts(snapshot.items), loaded: true }),\n});\n\n/** An idle library remains reachable, without marking it as background work. */\nexport const artifactActivitySource = {\n subscribe: (listener: () => void) => {\n const subscription = artifacts.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive: () => false,\n};\n\n/** Files remembered per session; the earliest opened is forgotten first and then reads by the baseline. */\nconst SEEN_PATH_LIMIT = 1000;\n\n/**\n * What the person has seen, per session, as the web store records it.\n *\n * ponytail: in memory only, like the layout. After an app restart the first list\n * re-seeds the baseline, so files made while the app was closed read as seen.\n * Persist through the host's storage if people notice.\n */\nexport const artifactSeen = defineGlobalStore<Readonly<Record<string, ArtifactSeenRecord>>>({});\n\nfunction firstRecord(sessionId: string): ArtifactSeenRecord | undefined {\n const snapshot = artifacts.select(artifacts.store.state, sessionId);\n if (!snapshot.loaded || snapshot.error !== undefined) return undefined;\n return { baseline: Math.max(0, ...snapshot.items.map((item) => item.modifiedAt)), seen: {} };\n}\n\nfunction updateSeen(sessionId: string, update: (record: ArtifactSeenRecord) => ArtifactSeenRecord): void {\n const current = artifactSeen.store.state[sessionId] ?? firstRecord(sessionId);\n if (current === undefined) return;\n const next = update(current);\n if (next !== current || artifactSeen.store.state[sessionId] === undefined)\n artifactSeen.update((records) => ({ ...records, [sessionId]: next }));\n}\n\nexport function markArtifactViewed(sessionId: string, item: Pick<ArtifactItem, 'path' | 'modifiedAt'>): void {\n updateSeen(sessionId, (record) => {\n if (record.seen[item.path] === item.modifiedAt) return record;\n const others = Object.entries(record.seen).filter(([path]) => path !== item.path);\n return {\n ...record,\n seen: Object.fromEntries([...others, [item.path, item.modifiedAt] as const].slice(-SEEN_PATH_LIMIT)),\n };\n });\n}\n\nexport function markAllArtifactsViewed(sessionId: string, items: readonly ArtifactItem[]): void {\n updateSeen(sessionId, () => ({ baseline: Math.max(0, ...items.map((item) => item.modifiedAt)), seen: {} }));\n}\n\n/** Files the person has not opened yet or that changed since: New plus Edited. */\nexport function unviewedArtifactCount(sessionId: string | null): number {\n if (sessionId === null) return 0;\n const record = artifactSeen.store.state[sessionId];\n return artifacts\n .select(artifacts.store.state, sessionId)\n .items.filter((item) => artifactStatus(item, record) !== 'viewed').length;\n}\n\n// The first list for a session sets its baseline, so a batch made before the face opens still reads New.\nartifacts.store.subscribe(() => {\n for (const sessionId of Object.keys(artifacts.store.state))\n if (artifactSeen.store.state[sessionId] === undefined) updateSeen(sessionId, (record) => record);\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { artifactsChannel } from '../_lib/artifactsStore.native';\n\nexport default defineChannelFile(artifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\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 'artifacts' at. */\nexport const apiScopes = ['session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'artifacts',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import { encodeBase64 } from '@agimon-ai/po-core/native';\nimport type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\n\nimport { api } from '../../../../../../generated/client.native';\nimport type { ArtifactPreview, ArtifactScope, ArtifactSnapshot } from '../../../../../types/artifacts';\nimport { parseArtifactSnapshot } from './artifactView';\n\nconst MAX_MEDIA_BYTES = 5 * 1024 * 1024;\n\nexport async function fetchArtifacts(\n sessionId: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<ArtifactSnapshot> {\n const result = await api.session(sessionId).list({ ...(scope === 'temporary' ? { query: { scope } } : {}), signal });\n if (!result.ok) throw new Error(result.error || 'Artifacts could not be loaded.');\n const snapshot = parseArtifactSnapshot(result.data);\n if (!snapshot) throw new Error('The session returned an invalid artifact list.');\n return snapshot;\n}\n\nexport async function fetchArtifactPreview(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<ArtifactPreview> {\n const result = await api\n .session(sessionId)\n .preview({ query: { path, ...(scope === 'temporary' ? { scope } : {}) }, signal });\n if (!result.ok) throw new Error(result.error || 'This artifact could not be read.');\n const preview = result.data;\n if (\n !preview ||\n typeof preview.path !== 'string' ||\n typeof preview.content !== 'string' ||\n typeof preview.mimeType !== 'string'\n )\n throw new Error('The session returned an invalid artifact preview.');\n return preview;\n}\n\nexport async function fetchArtifactMedia(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<{ data: string; mimeType: string }> {\n const source = await prepareArtifactSave(sessionId, path, signal, scope);\n if (source.size > MAX_MEDIA_BYTES) throw new Error('This media is too large to preview.');\n const mimeType = source.mimeType.toLowerCase();\n if (!/^(?:image\\/[a-z0-9.+-]+|audio\\/[a-z0-9.+-]+|video\\/[a-z0-9.+-]+|application\\/pdf)$/u.test(mimeType))\n throw new Error('This media type cannot be previewed.');\n const bytes = new Uint8Array(source.size);\n for (let offset = 0; offset < source.size; offset += 1024 * 1024) {\n bytes.set(await source.read(offset, Math.min(1024 * 1024, source.size - offset), signal), offset);\n }\n return { data: encodeBase64(bytes), mimeType };\n}\n\n/** The native host owns saving, with bounded version-checked reads supplied by this package. */\nexport async function prepareArtifactSave(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<Parameters<NonNullable<WebPluginSlotProps['nativeSaveFile']>>[0]> {\n const load = async (headers: Record<string, string>, signal: AbortSignal): Promise<Response> => {\n if (signal.aborted) throw new Error('Download cancelled.');\n const result = await api\n .session(sessionId)\n .content({ query: { path, ...(scope === 'temporary' ? { scope } : {}) }, headers, signal });\n if (!result.ok && result.status !== 416) throw new Error(result.error || 'This artifact could not be read.');\n if (!result.response) throw new Error('This artifact could not be read.');\n return result.response;\n };\n const probe = await load({ Range: 'bytes=0-0' }, signal);\n const range = /^bytes 0-0\\/(\\d+)$/u.exec(probe.headers.get('content-range') ?? '');\n const empty =\n (probe.status === 416 && probe.headers.get('content-range') === 'bytes */0') ||\n (probe.status === 200 && probe.headers.get('content-length') === '0');\n if (!empty && (probe.status !== 206 || !range)) throw new Error('This artifact does not support bounded downloads.');\n const size = empty ? 0 : Number(range![1]);\n if (!Number.isSafeInteger(size) || size < 0) throw new Error('Invalid artifact size.');\n if ((await probe.arrayBuffer()).byteLength !== (empty ? 0 : 1)) throw new Error('Invalid artifact response.');\n if (signal.aborted) throw new Error('Download cancelled.');\n const version = probe.headers.get('etag');\n if (!version) throw new Error('The artifact has no version validator.');\n return {\n name: path.split('/').at(-1) ?? 'artifact',\n mimeType: probe.headers.get('content-type')?.split(';')[0]?.trim() || 'application/octet-stream',\n size,\n signal,\n read: async (offset, count, signal) => {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(count) ||\n offset < 0 ||\n count < 1 ||\n count > 1024 * 1024 ||\n offset + count > size\n )\n throw new Error('Invalid download range.');\n const end = offset + count - 1;\n const response = await load({ Range: `bytes=${offset}-${end}`, 'If-Match': version }, signal);\n if (\n response.status !== 206 ||\n response.headers.get('etag') !== version ||\n response.headers.get('content-range') !== `bytes ${offset}-${end}/${size}`\n )\n throw new Error('The artifact changed or its range response is invalid.');\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (signal.aborted) throw new Error('Download cancelled.');\n if (bytes.byteLength !== count) throw new Error('The artifact response is incomplete.');\n return bytes;\n },\n };\n}\n","import type { SlotDeclaration, TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\n\n/**\n * Author's `author.open-source` slot, declared by duck type. A web plugin can't\n * import another feature package, so this mirrors po-browse's local copy.\n */\ninterface AuthorSourceAction {\n version: 1;\n createTab(input: { sessionId: string; path: string }): TransientTab;\n}\n\nexport const authorSourceActionSlot: SlotDeclaration<AuthorSourceAction> = {\n slot: 'author.open-source',\n parse(input) {\n if (typeof input !== 'object' || input === null) return null;\n const action = input as Partial<AuthorSourceAction>;\n return action.version === 1 && typeof action.createTab === 'function' ? (action as AuthorSourceAction) : null;\n },\n};\n\n/** Author's open action when the installed plugin contributes it. */\nexport function authorSourceAction(props: WebPluginSlotProps): AuthorSourceAction | undefined {\n return props.sessionId !== null ? props.slotData?.(authorSourceActionSlot)?.[0]?.data : undefined;\n}\n","import { useEffect, useSyncExternalStore } from 'react';\n\nimport { fetchArtifacts } from '../_lib/artifactsApi.native';\nimport { artifactActivitySource, artifacts } from '../_lib/artifactsStore.native';\n\n/** A fresh grid read complements the live session channel and seeds a newly attached rail. */\nexport function useArtifacts(sessionId: string | null, refreshOnMount = false) {\n const snapshot = useSyncExternalStore(artifactActivitySource.subscribe, () =>\n artifacts.select(artifacts.store.state, sessionId),\n );\n useEffect(() => {\n if (sessionId === null) return;\n const before = artifacts.select(artifacts.store.state, sessionId);\n if (before.loaded && !refreshOnMount) return;\n const controller = new AbortController();\n void fetchArtifacts(sessionId, controller.signal)\n .then((next) => {\n if (!controller.signal.aborted)\n artifacts.update(sessionId, (current) => (current === before ? { ...next, loaded: true } : current));\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n artifacts.update(sessionId, (current) =>\n current === before\n ? { ...current, loaded: true, error: error instanceof Error ? error.message : String(error) }\n : current,\n );\n });\n return () => controller.abort();\n }, [sessionId, refreshOnMount]);\n return snapshot;\n}\n","import {\n Button,\n FolderIcon,\n FileIcon,\n ImageIcon,\n SearchIcon,\n SlidersIcon,\n CloseIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n Input,\n SegmentedControl,\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuCheckboxItem,\n DropdownMenuSeparator,\n fontOf,\n Sheet,\n SheetContent,\n SheetList,\n} from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useCallback, type ReactNode } from 'react';\nimport { FlatList, Text, View, type ListViewToken } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactItem } from '../../../../../types/artifacts';\nimport {\n artifactKind,\n sizeLabel,\n isArtifactLayout,\n type ArtifactLayout,\n type ArtifactKind,\n type ArtifactModified,\n type ArtifactSort,\n type ArtifactSortDirection,\n type ArtifactTreeRow,\n} from '../_lib/artifactView';\n\nexport interface ArtifactBrowserProps {\n layout: ArtifactLayout;\n onLayoutChange: (layout: ArtifactLayout) => void;\n query: string;\n onQueryChange: (query: string) => void;\n type: ArtifactKind | 'any';\n onTypeChange: (type: ArtifactKind | 'any') => void;\n modified: ArtifactModified;\n onModifiedChange: (modified: ArtifactModified) => void;\n sort: ArtifactSort;\n onSortChange: (sort: ArtifactSort) => void;\n direction: ArtifactSortDirection;\n onDirectionChange: (direction: ArtifactSortDirection) => void;\n rows: readonly ArtifactTreeRow[];\n onToggleDirectory: (path: string) => void;\n selected?: ArtifactItem;\n onSelect: (item: ArtifactItem) => void;\n onCloseSelection: () => void;\n totalCount: number;\n onViewableImagesChange?: (paths: readonly string[]) => void;\n renderImage?: (item: ArtifactItem) => ReactNode;\n /** Drawn first in the list, above the controls, such as the native dock's tab strip. */\n header?: ReactNode;\n /** Inside a bottom sheet with no scroll view of its own: the list is the sheet's only scroll owner. */\n sheet?: boolean;\n}\n\nexport interface ArtifactListProps {\n items: readonly ArtifactItem[];\n onOpen: (path: string) => void;\n loading?: boolean;\n error?: string;\n grid?: boolean;\n browser?: ArtifactBrowserProps;\n}\n\n/** Presentation only. The session store and guarded API belong to the containers. */\nexport function ArtifactList({ items, onOpen, loading, error, grid = false, browser }: ArtifactListProps) {\n if (browser)\n return <ArtifactBrowser items={items} onOpen={onOpen} loading={loading} error={error} browser={browser} />;\n return (\n <View testID={grid ? 'artifacts-grid' : 'artifacts-recent'} style={styles.list}>\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {loading ? <Text style={styles.meta}>Loading artifacts...</Text> : null}\n {!loading && !error && items.length === 0 ? (\n <Text style={styles.meta}>Documents saved for this session will appear here.</Text>\n ) : null}\n {items.map((item) => (\n <Button\n key={item.path}\n variant={grid ? 'outline' : 'ghost'}\n size=\"card\"\n accessibilityLabel={`Open ${item.path}`}\n testID={`artifact-${item.path}`}\n onPress={() => onOpen(item.path)}\n style={styles.item}\n >\n <FileIcon size={18} color=\"dim\" />\n <View style={styles.label}>\n <Text numberOfLines={1} style={styles.name}>\n {item.name}\n </Text>\n {grid || item.path !== item.name ? (\n <Text numberOfLines={1} style={styles.path}>\n {item.path}\n </Text>\n ) : null}\n {grid ? <Text style={styles.meta}>{item.size.toLocaleString('en-US')} bytes</Text> : null}\n </View>\n </Button>\n ))}\n </View>\n );\n}\n\nconst LAYOUTS = [\n { value: 'tree', label: 'Tree' },\n { value: 'list', label: 'List' },\n { value: 'grid', label: 'Grid' },\n];\nconst TYPES = ['any', 'Markdown', 'Image', 'Code', 'Data', 'Document', 'Other'] as const;\nconst MODIFIED = [\n { value: 'any', label: 'Any time' },\n { value: 'today', label: 'Today' },\n { value: '7days', label: 'Last 7 days' },\n { value: '30days', label: 'Last 30 days' },\n] as const;\nconst SORTS = [\n { value: 'name', label: 'Name' },\n { value: 'modified', label: 'Modified' },\n { value: 'size', label: 'Size' },\n] as const;\nconst ROW_HEIGHT = 48;\nconst IMAGE_VIEWABILITY = { itemVisiblePercentThreshold: 1 };\n\nfunction ArtifactBrowser({\n items,\n onOpen,\n loading,\n error,\n browser: b,\n}: ArtifactListProps & { browser: ArtifactBrowserProps }) {\n const grid = b.layout === 'grid';\n const onViewableImagesChange = b.onViewableImagesChange;\n const onViewableItemsChanged = useCallback(\n ({ viewableItems }: { viewableItems: (Omit<ListViewToken, 'item'> & { item: ArtifactTreeRow })[] }) => {\n onViewableImagesChange?.(\n viewableItems.flatMap(({ item, isViewable }) =>\n grid && isViewable && item.kind === 'file' && artifactKind(item.item.path) === 'Image'\n ? [item.item.path]\n : [],\n ),\n );\n },\n [grid, onViewableImagesChange],\n );\n const rows: readonly ArtifactTreeRow[] =\n b.layout === 'tree' ? b.rows : items.map((item) => ({ kind: 'file', item, depth: 0 }));\n const List = b.sheet ? SheetList<ArtifactTreeRow> : FlatList<ArtifactTreeRow>;\n const list = (\n <List\n {...(b.sheet ? { embedded: true } : {})}\n key={b.layout}\n testID=\"artifacts-browser\"\n onViewableItemsChanged={onViewableItemsChanged}\n viewabilityConfig={IMAGE_VIEWABILITY}\n data={loading || error ? [] : rows}\n numColumns={grid ? 2 : 1}\n columnWrapperStyle={grid ? styles.columns : undefined}\n keyExtractor={(row) => (row.kind === 'dir' ? `dir:${row.path}` : row.item.path)}\n keyboardShouldPersistTaps=\"handled\"\n ListHeaderComponent={\n <>\n {b.header}\n <View style={styles.head}>\n <SegmentedControl\n accessibilityLabel=\"Artifact layout\"\n options={LAYOUTS}\n value={b.layout}\n onValueChange={(value) => {\n if (isArtifactLayout(value)) b.onLayoutChange(value);\n }}\n />\n <View style={styles.toolbar}>\n <View style={styles.search}>\n <SearchIcon size={18} />\n <Input\n variant=\"bare\"\n accessibilityLabel=\"Search artifacts\"\n placeholder=\"Search artifacts\"\n value={b.query}\n onChangeText={b.onQueryChange}\n style={styles.searchInput}\n autoCapitalize=\"none\"\n />\n </View>\n <DropdownMenu>\n <DropdownMenuTrigger variant=\"outline\" accessibilityLabel=\"Filters\">\n <SlidersIcon />\n Filters\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuLabel>Type</DropdownMenuLabel>\n {TYPES.map((type) => (\n <DropdownMenuCheckboxItem\n key={type}\n checked={b.type === type}\n onCheckedChange={() => b.onTypeChange(type)}\n >\n {type === 'any' ? 'All types' : type}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>Modified</DropdownMenuLabel>\n {MODIFIED.map(({ value, label }) => (\n <DropdownMenuCheckboxItem\n key={value}\n checked={b.modified === value}\n onCheckedChange={() => b.onModifiedChange(value)}\n >\n {label}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>Sort</DropdownMenuLabel>\n {SORTS.map(({ value, label }) => (\n <DropdownMenuCheckboxItem\n key={value}\n checked={b.sort === value}\n onCheckedChange={() => b.onSortChange(value)}\n >\n {label}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuCheckboxItem\n checked={b.direction === 'asc'}\n onCheckedChange={() => b.onDirectionChange('asc')}\n >\n Ascending\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={b.direction === 'desc'}\n onCheckedChange={() => b.onDirectionChange('desc')}\n >\n Descending\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </View>\n <View style={styles.chips}>\n {b.query ? (\n <Button variant=\"outline\" accessibilityLabel=\"Remove search filter\" onPress={() => b.onQueryChange('')}>\n Search: {b.query}\n <CloseIcon />\n </Button>\n ) : null}\n {b.type !== 'any' ? (\n <Button variant=\"outline\" accessibilityLabel=\"Remove type filter\" onPress={() => b.onTypeChange('any')}>\n {b.type}\n <CloseIcon />\n </Button>\n ) : null}\n {b.modified !== 'any' ? (\n <Button\n variant=\"outline\"\n accessibilityLabel=\"Remove modified filter\"\n onPress={() => b.onModifiedChange('any')}\n >\n {MODIFIED.find((option) => option.value === b.modified)?.label}\n <CloseIcon />\n </Button>\n ) : null}\n </View>\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {loading ? <Text style={styles.meta}>Loading artifacts...</Text> : null}\n </View>\n </>\n }\n ListEmptyComponent={\n !loading && !error ? (\n <Text style={[styles.meta, styles.inset]}>\n {b.totalCount ? 'No artifacts match these filters.' : 'Documents saved for this session will appear here.'}\n </Text>\n ) : undefined\n }\n renderItem={({ item: row }) => {\n if (row.kind === 'dir')\n return (\n <Button\n variant=\"ghost\"\n style={[styles.row, { paddingLeft: row.depth * 16 }]}\n accessibilityLabel={`${row.open ? 'Collapse' : 'Expand'} ${row.path}`}\n accessibilityState={{ expanded: row.open }}\n onPress={() => b.onToggleDirectory(row.path)}\n >\n {row.open ? <ChevronDownIcon /> : <ChevronRightIcon />}\n <FolderIcon />\n <Text numberOfLines={1} style={[styles.name, styles.label]}>\n {row.name}\n </Text>\n <Text style={styles.meta}>{row.count}</Text>\n </Button>\n );\n const item = row.item;\n const image = artifactKind(item.path) === 'Image';\n const selected = b.selected?.path === item.path;\n return (\n <Button\n variant=\"ghost\"\n size=\"card\"\n testID={`artifact-${item.path}`}\n accessibilityLabel={`Select ${item.path}`}\n accessibilityState={{ selected }}\n onPress={() => b.onSelect(item)}\n style={[\n grid ? styles.tile : styles.row,\n selected && styles.selected,\n !grid && { paddingLeft: row.depth * 16 },\n ]}\n >\n {b.layout === 'tree' ? <View accessible={false} style={styles.chevronGutter} /> : null}\n {grid ? (\n <View style={styles.thumbnail}>\n {image && b.renderImage ? (\n b.renderImage(item)\n ) : image ? (\n <ImageIcon size={28} />\n ) : (\n <FileIcon size={28} />\n )}\n </View>\n ) : image ? (\n <ImageIcon size={18} />\n ) : (\n <FileIcon size={18} />\n )}\n <View style={styles.label}>\n <Text numberOfLines={1} style={styles.name}>\n {item.name}\n </Text>\n <Text numberOfLines={1} style={styles.path}>\n {item.path}\n </Text>\n </View>\n <Text style={styles.meta}>{sizeLabel(item.size)}</Text>\n </Button>\n );\n }}\n ListFooterComponent={\n <View style={styles.foot}>\n <Text style={styles.meta}>\n {items.length} of {b.totalCount} artifacts\n </Text>\n </View>\n }\n />\n );\n return (\n <>\n {list}\n <Sheet\n open={b.selected !== undefined}\n onOpenChange={(open) => {\n if (!open) b.onCloseSelection();\n }}\n >\n <SheetContent>\n {b.selected ? (\n <View style={styles.foot}>\n <View style={styles.selection} testID=\"artifact-selection\">\n <Text accessibilityRole=\"header\" numberOfLines={1} style={styles.name}>\n {b.selected.name}\n </Text>\n <Text numberOfLines={2} style={styles.path}>\n {b.selected.path}\n </Text>\n <Text style={styles.meta}>\n {artifactKind(b.selected.path)} · {sizeLabel(b.selected.size)}\n </Text>\n <View style={styles.actions}>\n <Button variant=\"outline\" onPress={b.onCloseSelection}>\n Close\n </Button>\n <Button\n variant=\"primary\"\n onPress={() => {\n if (b.selected) {\n b.onCloseSelection();\n onOpen(b.selected.path);\n }\n }}\n >\n Open\n </Button>\n </View>\n </View>\n </View>\n ) : null}\n </SheetContent>\n </Sheet>\n </>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n head: { gap: theme.spacing(3), padding: theme.spacing(4), paddingBottom: theme.spacing(3) },\n foot: { gap: theme.spacing(3), padding: theme.spacing(4), paddingTop: theme.spacing(3) },\n inset: { paddingHorizontal: theme.spacing(4) },\n toolbar: { flexDirection: 'row', alignItems: 'center', gap: theme.spacing(2) },\n search: {\n flex: 1,\n minWidth: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingHorizontal: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.DEFAULT,\n backgroundColor: theme.colors.deep,\n },\n searchInput: { flex: 1 },\n chips: { flexDirection: 'row', flexWrap: 'wrap', gap: theme.spacing(2) },\n row: {\n marginHorizontal: theme.spacing(4),\n marginBottom: theme.spacing(2),\n // A file row holds two lines; a fixed height pressed them against the border.\n minHeight: ROW_HEIGHT,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-start',\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors['border-soft'],\n borderRadius: theme.borderRadius.DEFAULT,\n paddingVertical: theme.spacing(2),\n },\n chevronGutter: { width: 16 },\n columns: { gap: theme.spacing(2), paddingHorizontal: theme.spacing(4) },\n tile: {\n flex: 1,\n maxWidth: '50%',\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors['border-soft'],\n marginBottom: theme.spacing(2),\n },\n thumbnail: {\n height: 96,\n backgroundColor: theme.colors.deep,\n borderRadius: theme.borderRadius.DEFAULT,\n overflow: 'hidden',\n alignItems: 'center',\n justifyContent: 'center',\n },\n selected: { backgroundColor: theme.colors['tint-green'], borderColor: theme.colors['edge-green'] },\n selection: {\n flexShrink: 0,\n padding: theme.spacing(3),\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.DEFAULT,\n backgroundColor: theme.colors.panel,\n },\n actions: { flexDirection: 'row', justifyContent: 'flex-end', gap: theme.spacing(2) },\n list: { gap: theme.spacing(2) },\n // The card size stacks its children; a recent row reads like the browser's list row instead.\n item: {\n minHeight: 44,\n flexDirection: 'row',\n justifyContent: 'flex-start',\n alignItems: 'center',\n gap: theme.spacing(3),\n },\n label: { flex: 1, gap: theme.spacing(1), minWidth: 0 },\n name: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontWeight: '600',\n fontSize: theme.fontSize.base,\n color: theme.colors.text,\n },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { CodeBlock, Markdown, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactPreview as Preview } from '../../../../../types/artifacts';\nimport { artifactAssetPath, artifactPreviewMode } from '../_lib/artifactView';\n\nexport interface ArtifactPreviewProps {\n preview: Preview;\n sessionId: string;\n renderFilePreview?: WebPluginSlotProps['renderFilePreview'];\n renderMediaPreview?: WebPluginSlotProps['renderMediaPreview'];\n media?: { data: string; mimeType: string };\n mediaError?: string;\n onOpen: (path: string) => void;\n}\n\n/** The host receives only content fetched through the artifact's bounded route. */\nexport function ArtifactPreview({\n preview,\n sessionId,\n renderFilePreview,\n renderMediaPreview,\n media,\n mediaError,\n onOpen,\n}: ArtifactPreviewProps) {\n const mode = artifactPreviewMode(preview.path);\n if (mode === 'media') {\n if (mediaError)\n return (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {mediaError}\n </Text>\n );\n if (!renderMediaPreview) return <Text style={styles.meta}>This host cannot display this media preview.</Text>;\n if (!media) return <Text style={styles.meta}>Loading media...</Text>;\n return (\n <>\n {renderMediaPreview({\n key: `artifact-media-${sessionId}-${preview.path}`,\n title: preview.path,\n path: preview.path,\n data: media.data,\n mimeType: media.mimeType,\n })}\n </>\n );\n }\n if (preview.unavailable)\n return <Text style={styles.meta}>{preview.reason ?? 'This artifact cannot be previewed.'}</Text>;\n if (mode === 'html') {\n return renderFilePreview ? (\n <View style={styles.html}>\n {renderFilePreview({\n key: `artifact-html-${sessionId}-${preview.path}`,\n html: preview.content,\n title: preview.path,\n })}\n </View>\n ) : (\n <Text style={styles.meta}>This host cannot display HTML previews.</Text>\n );\n }\n if (mode === 'markdown') {\n return (\n <Markdown\n text={preview.content}\n onFileLink={(path) => {\n try {\n const resolved = artifactAssetPath(preview.path, path);\n return () => onOpen(resolved);\n } catch {\n // An out-of-folder or non-file link is not an artifact action.\n return undefined;\n }\n }}\n />\n );\n }\n if (mode === 'code') return <CodeBlock text={preview.content} language={preview.path.split('.').at(-1)} />;\n return (\n <Text selectable style={styles.text}>\n {preview.content}\n </Text>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n html: { minHeight: theme.spacing(90) },\n text: {\n fontFamily: fontOf(theme.fontFamily.mono),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.text,\n },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, CloseIcon, CopyButton, DownloadIcon, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useEffect, useRef, useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactPreview as Preview, ArtifactScope } from '../../../../../types/artifacts';\nimport { fetchArtifactMedia, fetchArtifactPreview, prepareArtifactSave } from '../_lib/artifactsApi.native';\nimport { artifactKind, artifactPreviewMode, artifactTabId, modifiedLabel, sizeLabel } from '../_lib/artifactView';\nimport { useArtifacts } from './artifactHooks.native';\nimport { ArtifactPreview } from './ArtifactPreview.native';\n\ninterface Loaded {\n key: string;\n preview?: Preview;\n error?: string;\n media?: { data: string; mimeType: string };\n mediaError?: string;\n}\n\n// Older app builds lack this export; the strip then leaves the path selectable without a copy control.\nconst HostCopyButton: typeof CopyButton | undefined = CopyButton;\n\nexport function ArtifactPanel({\n path,\n scope = 'artifacts',\n ...props\n}: WebPluginSlotProps & { path: string; scope?: ArtifactScope }) {\n const snapshot = useArtifacts(props.sessionId);\n const item = snapshot.items.find((item) => item.path === path);\n const version = `${item?.modifiedAt ?? ''}:${item?.size ?? ''}`;\n const downloadKey = `${scope === 'temporary' ? 'temporary:' : ''}${props.sessionId}:${path}`;\n const key = `${downloadKey}:${version}`;\n const [loaded, setLoaded] = useState<Loaded>();\n useEffect(() => {\n if (props.sessionId === null) return;\n const sessionId = props.sessionId;\n const controller = new AbortController();\n void fetchArtifactPreview(sessionId, path, controller.signal, scope)\n .then(async (preview) => {\n if (controller.signal.aborted) return;\n setLoaded({ key, preview });\n if (artifactPreviewMode(path) !== 'media' || !props.renderMediaPreview) return;\n try {\n const media = await fetchArtifactMedia(sessionId, path, controller.signal, scope);\n if (!controller.signal.aborted) setLoaded({ key, preview, media });\n } catch (error) {\n if (!controller.signal.aborted)\n setLoaded({ key, preview, mediaError: error instanceof Error ? error.message : String(error) });\n }\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n setLoaded({ key, error: error instanceof Error ? error.message : String(error) });\n });\n return () => controller.abort();\n }, [props.sessionId, path, key, props.renderMediaPreview, scope]);\n const current = loaded?.key === key ? loaded : undefined;\n const downloadController = useRef<AbortController | undefined>(undefined);\n const [download, setDownload] = useState<{ key: string; saving?: boolean; note?: string }>();\n useEffect(\n () => () => {\n downloadController.current?.abort();\n downloadController.current = undefined;\n },\n [props.sessionId, path, scope],\n );\n const saving = download?.key === downloadKey && download.saving === true;\n const save = async () => {\n if (props.sessionId === null || !props.nativeSaveFile || downloadController.current) return;\n const controller = new AbortController();\n downloadController.current = controller;\n setDownload({ key: downloadKey, saving: true });\n try {\n const file = await prepareArtifactSave(props.sessionId, path, controller.signal, scope);\n if (controller.signal.aborted || downloadController.current !== controller) return;\n await props.nativeSaveFile(file);\n if (!controller.signal.aborted && downloadController.current === controller)\n setDownload({ key: downloadKey, note: 'Saved.' });\n } catch (error) {\n if (!controller.signal.aborted && downloadController.current === controller)\n setDownload({ key: downloadKey, note: error instanceof Error ? error.message : String(error) });\n } finally {\n if (downloadController.current === controller) downloadController.current = undefined;\n }\n };\n const cancel = () => {\n downloadController.current?.abort();\n downloadController.current = undefined;\n setDownload({ key: downloadKey, note: 'Download cancelled.' });\n };\n // The top bar's control outlives this render; it reaches the latest handlers through a ref synced after commit.\n const handlers = useRef({ save, cancel });\n useEffect(() => {\n handlers.current = { save, cancel };\n });\n const { setTabHeader } = props;\n const canSave = props.nativeSaveFile !== undefined;\n // Once the host's media view is showing, it names and saves the media in the top bar; the panel speaks otherwise.\n const media =\n artifactPreviewMode(path) === 'media' && props.renderMediaPreview !== undefined && current?.media !== undefined;\n const subtitle = `${artifactKind(path)}${item ? ` · ${sizeLabel(item.size)}` : ''}`;\n const offline = props.sessionId === null;\n useEffect(() => {\n if (!setTabHeader || media) return;\n setTabHeader({\n subtitle,\n action: canSave ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={offline}\n accessibilityLabel={saving ? 'Cancel download' : 'Download'}\n onPress={() => (saving ? handlers.current.cancel() : void handlers.current.save())}\n >\n {saving ? <CloseIcon color=\"hi\" /> : <DownloadIcon color=\"hi\" />}\n </Button>\n ) : undefined,\n });\n }, [setTabHeader, media, subtitle, canSave, saving, offline]);\n const note =\n download?.key === downloadKey && download.note ? (\n <Text accessibilityLiveRegion=\"polite\" style={styles.meta}>\n {download.note}\n </Text>\n ) : null;\n const body =\n props.sessionId === null ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n The session is unavailable.\n </Text>\n ) : current?.error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {current.error}\n </Text>\n ) : current?.preview ? (\n <ArtifactPreview\n preview={current.preview}\n sessionId={props.sessionId}\n renderFilePreview={props.renderFilePreview}\n renderMediaPreview={props.renderMediaPreview}\n media={current.media}\n mediaError={current.mediaError}\n onOpen={(path) => {\n if (props.sessionId !== null) props.openTransientTab(artifactTab(props.sessionId, path, scope));\n }}\n />\n ) : (\n <Text style={styles.meta}>Reading this artifact...</Text>\n );\n return (\n <View style={styles.screen}>\n {media ? (\n <View style={styles.stage}>{body}</View>\n ) : (\n <ScrollView style={styles.stage} contentContainerStyle={styles.content}>\n {setTabHeader ? null : (\n <ArtifactPanelHeader\n path={path}\n size={item?.size}\n saving={saving}\n canSave={canSave}\n disabled={offline}\n onDownload={() => void save()}\n onCancel={cancel}\n />\n )}\n {note}\n {body}\n </ScrollView>\n )}\n <ArtifactPathStrip path={path} modifiedAt={item?.modifiedAt} />\n </View>\n );\n}\n\n/** Where the file lives and when it last changed, pinned under the preview. */\nexport function ArtifactPathStrip({ path, modifiedAt }: { path: string; modifiedAt?: number }) {\n // Read once per mount: a preview left open past midnight keeps its first label, which is still true then.\n const [now] = useState(Date.now);\n return (\n <View style={styles.strip}>\n <Text selectable numberOfLines={1} ellipsizeMode=\"middle\" style={[styles.path, styles.stripPath]}>\n {path}\n </Text>\n {HostCopyButton ? <HostCopyButton text={path} label=\"path\" /> : null}\n {modifiedAt === undefined ? null : <Text style={styles.meta}>{modifiedLabel(modifiedAt, now)}</Text>}\n </View>\n );\n}\n\n/** The preview's quiet header: where the file lives, what it is, and the one action on it. */\nexport function ArtifactPanelHeader({\n path,\n size,\n saving,\n canSave,\n disabled,\n onDownload,\n onCancel,\n}: {\n path: string;\n size?: number;\n saving: boolean;\n canSave: boolean;\n disabled: boolean;\n onDownload: () => void;\n onCancel: () => void;\n}) {\n return (\n <View style={styles.header}>\n <View style={styles.label}>\n <Text selectable numberOfLines={1} ellipsizeMode=\"middle\" style={styles.path}>\n {path}\n </Text>\n <Text style={styles.meta}>\n {artifactKind(path)}\n {size === undefined ? '' : ` · ${sizeLabel(size)}`}\n {canSave ? '' : ' · This host cannot save artifact downloads.'}\n </Text>\n </View>\n {canSave && saving ? (\n <Button variant=\"ghost\" size=\"sm\" onPress={onCancel}>\n Cancel\n </Button>\n ) : null}\n {canSave ? (\n <Button variant=\"outline\" size=\"sm\" disabled={saving || disabled} onPress={onDownload}>\n Download\n </Button>\n ) : null}\n </View>\n );\n}\n\nexport function artifactTab(\n sessionId: string,\n path: string,\n scope: ArtifactScope = 'artifacts',\n): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return {\n id: `${scope === 'temporary' ? 'temporary:' : ''}${artifactTabId(sessionId, path)}`,\n label: path.split('/').at(-1) ?? path,\n panel: (props) => <ArtifactPanel {...props} sessionId={sessionId} path={path} scope={scope} />,\n };\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme, rt) => ({\n screen: { flex: 1 },\n stage: { flex: 1 },\n content: { padding: theme.spacing(4), gap: theme.spacing(3) },\n strip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingHorizontal: theme.spacing(4),\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2) + rt.insets.bottom,\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n backgroundColor: theme.colors.bg,\n },\n stripPath: { flexShrink: 1 },\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingBottom: theme.spacing(3),\n borderBottomWidth: 1,\n borderBottomColor: theme.colors['border-soft'],\n },\n label: { flex: 1, minWidth: 0, gap: theme.spacing(0.5) },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { ImageIcon } from '@agimon-ai/po-native-components';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport { Image } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactItem } from '../../../../../types/artifacts';\nimport { fetchArtifactMedia } from '../_lib/artifactsApi.native';\nimport { artifactLayout, artifacts, markArtifactViewed } from '../_lib/artifactsStore.native';\nimport {\n artifactTree,\n filterArtifacts,\n sortArtifacts,\n type ArtifactKind,\n type ArtifactModified,\n type ArtifactSort,\n type ArtifactSortDirection,\n} from '../_lib/artifactView';\nimport { authorSourceAction } from '../_lib/authorSourceAction';\nimport { useArtifacts } from './artifactHooks.native';\nimport { ArtifactList } from './ArtifactList.native';\nimport { artifactTab } from './ArtifactPanel.native';\n\n/** With Author installed, a file it can mark up opens in Author's canvas; it refuses the rest, which keep this viewer. */\nfunction authorTab(props: WebPluginSlotProps, path: string) {\n try {\n return props.sessionId === null\n ? undefined\n : authorSourceAction(props)?.createTab({ sessionId: props.sessionId, path: `artifact:${path}` });\n } catch {\n return undefined;\n }\n}\n\nexport function ArtifactsPanel(props: WebPluginSlotProps) {\n // Remount session-local controls synchronously, without flashing another session's selection.\n return <SessionArtifactsPanel key={props.sessionId} {...props} />;\n}\n\nfunction SessionArtifactsPanel(props: WebPluginSlotProps) {\n const snapshot = useArtifacts(props.sessionId, true);\n const layout = useSyncExternalStore(\n (listener) => {\n const subscription = artifactLayout.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n () => artifactLayout.store.state,\n );\n const [now, setNow] = useState(Date.now);\n useEffect(() => {\n const subscription = artifacts.store.subscribe(() => setNow(Date.now()));\n return () => subscription.unsubscribe();\n }, []);\n const [query, setQuery] = useState('');\n const [type, setType] = useState<ArtifactKind | 'any'>('any');\n const [modified, setModified] = useState<ArtifactModified>('any');\n const [sort, setSort] = useState<ArtifactSort>('name');\n const [direction, setDirection] = useState<ArtifactSortDirection>('asc');\n const [expanded, setExpanded] = useState<string[]>([]);\n const [selection, setSelection] = useState<string>();\n const [viewable, setViewable] = useState<readonly string[]>([]);\n if (snapshot.loaded && selection && !snapshot.items.some((item) => item.path === selection)) setSelection(undefined);\n const hasFilters = query !== '' || type !== 'any' || modified !== 'any';\n const visible = sortArtifacts(filterArtifacts(snapshot.items, { query, type, modified }, now), sort, direction);\n return (\n <ArtifactList\n items={visible}\n loading={!snapshot.loaded}\n error={props.sessionId === null ? 'The session is unavailable.' : snapshot.error}\n onOpen={(path) => {\n if (props.sessionId === null) return;\n props.openTransientTab(authorTab(props, path) ?? artifactTab(props.sessionId, path));\n const item = snapshot.items.find((entry) => entry.path === path);\n if (item !== undefined) markArtifactViewed(props.sessionId, item);\n }}\n browser={{\n header: props.dockHeader,\n sheet: true,\n layout,\n onLayoutChange: (next) => {\n setViewable([]);\n artifactLayout.update(() => next);\n },\n query,\n onQueryChange: setQuery,\n type,\n onTypeChange: setType,\n modified,\n onModifiedChange: (value) => {\n setModified(value);\n setNow(Date.now());\n },\n sort,\n onSortChange: setSort,\n direction,\n onDirectionChange: setDirection,\n rows: artifactTree(visible, (path) => hasFilters || expanded.includes(path)),\n onToggleDirectory: (path) =>\n setExpanded((paths) => (paths.includes(path) ? paths.filter((value) => value !== path) : [...paths, path])),\n selected: snapshot.items.find((item) => item.path === selection),\n onSelect: (item) => setSelection(item.path),\n onCloseSelection: () => setSelection(undefined),\n totalCount: snapshot.items.length,\n onViewableImagesChange: setViewable,\n renderImage: (item) => (\n <ArtifactThumbnail\n key={`${props.sessionId}:${item.path}:${item.modifiedAt}:${item.size}`}\n sessionId={props.sessionId}\n item={item}\n active={layout === 'grid' && viewable.includes(item.path)}\n />\n ),\n }}\n />\n );\n}\n\nfunction ArtifactThumbnail({\n sessionId,\n item,\n active,\n}: {\n sessionId: string | null;\n item: ArtifactItem;\n active: boolean;\n}) {\n const [uri, setUri] = useState<string>();\n useEffect(() => {\n if (uri !== undefined || !active || sessionId === null || item.size > 5 * 1024 * 1024) return;\n const controller = new AbortController();\n void fetchArtifactMedia(sessionId, item.path, controller.signal)\n .then((media) => {\n if (!controller.signal.aborted && media.mimeType.startsWith('image/'))\n setUri(`data:${media.mimeType};base64,${media.data}`);\n })\n // A failed thumbnail keeps the image placeholder; opening still uses the full preview route.\n .catch(() => {\n if (!controller.signal.aborted) setUri(undefined);\n });\n return () => controller.abort();\n }, [sessionId, item.path, item.size, item.modifiedAt, active, uri]);\n return active && uri ? (\n <Image accessibilityLabel={item.name} source={{ uri }} resizeMode=\"contain\" style={styles.image} />\n ) : (\n <ImageIcon size={28} />\n );\n}\n\nconst styles = StyleSheet.create({\n image: { width: '100%', height: '100%' },\n});\n","import { defineDockFace } from '@agimon-ai/po-core/native';\n\nimport { ArtifactsPanel } from '../_components/ArtifactsPanel.native';\nimport { artifacts, artifactSeen, unviewedArtifactCount } from '../_lib/artifactsStore.native';\n\nexport default defineDockFace({\n id: 'artifacts',\n label: 'Artifacts',\n order: 10,\n panel: ArtifactsPanel,\n ownsScroll: true,\n badge: {\n subscribe(listener: () => void) {\n const files = artifacts.store.subscribe(listener);\n const seen = artifactSeen.store.subscribe(listener);\n return () => {\n files.unsubscribe();\n seen.unsubscribe();\n };\n },\n count: unviewedArtifactCount,\n },\n});\n","/** Matching links is presentation only. The server independently selects and guards the root. */\nexport function temporaryFileReference(reference: string, root: string | undefined): string | undefined {\n const value = reference.trim();\n const prefix = 'temporary:';\n let relative: string;\n if (value.startsWith(prefix)) relative = value.slice(prefix.length);\n else {\n if (!root || !root.startsWith('/')) return undefined;\n const base = root.replace(/\\/+$/u, '');\n if (!value.startsWith(`${base}/`)) return undefined;\n relative = value.slice(base.length + 1);\n }\n if (\n !relative ||\n relative.includes('\\\\') ||\n relative.includes('\\0') ||\n relative.split('/').some((part) => !part || part === '.' || part === '..')\n )\n return undefined;\n return relative;\n}\n","import { defineFileLinks } from '@agimon-ai/po-core/native';\n\nimport { artifactTab } from '../_components/ArtifactPanel.native';\nimport { artifacts } from '../_lib/artifactsStore.native';\nimport { temporaryFileReference } from '../_lib/temporaryFiles';\n\nexport default defineFileLinks({\n subscribe(listener) {\n const subscription = artifacts.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n fingerprint: (sessionId) => artifacts.select(artifacts.store.state, sessionId).temporaryRoot ?? '',\n resolve(sessionId, path) {\n if (sessionId === null) return undefined;\n const reference = path.trim();\n const temporary = temporaryFileReference(\n reference,\n artifacts.select(artifacts.store.state, sessionId).temporaryRoot,\n );\n if (temporary) return artifactTab(sessionId, temporary, 'temporary');\n if (!reference.startsWith('artifact:')) return undefined;\n const relative = reference.slice('artifact:'.length);\n return relative ? artifactTab(sessionId, relative) : undefined;\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 channelArtifacts from '../src/extensions/workspaces/sessions/(frontend)/channel/artifacts.native';\nimport dockArtifacts from '../src/extensions/workspaces/sessions/(frontend)/dock/artifacts.native';\nimport fileLinksArtifacts from '../src/extensions/workspaces/sessions/(frontend)/file-links/artifacts.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: 'artifacts',\n session: {\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'artifacts' }, channelArtifacts)]; },\n get dockFaces(): WebPluginContributions['dockFaces'] { return [via({ id: 'artifacts' }, dockArtifacts)]; },\n get fileLinks(): WebPluginContributions['fileLinks'] { return fileLinksArtifacts; },\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"native.mjs","names":["Button","FolderIcon","FileIcon","ImageIcon","SearchIcon","SlidersIcon","CloseIcon","ChevronDownIcon","ChevronRightIcon","Input","SegmentedControl","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","DropdownMenuCheckboxItem","DropdownMenuSeparator","fontOf","Sheet","SheetContent","SheetList","PoNativeTheme","useCallback","ReactNode","ListViewToken","StyleSheet","ArtifactItem","artifactKind","sizeLabel","isArtifactLayout","ArtifactLayout","ArtifactKind","ArtifactModified","ArtifactSort","ArtifactSortDirection","ArtifactTreeRow","ArtifactBrowserProps","layout","onLayoutChange","query","onQueryChange","type","onTypeChange","modified","onModifiedChange","sort","onSortChange","direction","onDirectionChange","rows","onToggleDirectory","path","selected","onSelect","item","onCloseSelection","totalCount","onViewableImagesChange","paths","renderImage","header","sheet","ArtifactListProps","items","onOpen","loading","error","grid","browser","ArtifactList","styles","list","meta","length","map","label","name","size","toLocaleString","LAYOUTS","value","TYPES","const","MODIFIED","SORTS","ROW_HEIGHT","IMAGE_VIEWABILITY","itemVisiblePercentThreshold","ArtifactBrowser","b","onViewableItemsChanged","viewableItems","Omit","flatMap","isViewable","kind","depth","List","FlatList","embedded","columns","undefined","row","head","toolbar","search","searchInput","chips","find","option","inset","indent","open","expanded","count","image","tile","chevronGutter","thumbnail","foot","selection","actions","create","theme","gap","spacing","padding","paddingBottom","uni__dependencies","paddingTop","paddingHorizontal","flexDirection","alignItems","flex","minWidth","borderWidth","borderColor","colors","border","borderRadius","DEFAULT","backgroundColor","deep","flexWrap","marginHorizontal","marginBottom","minHeight","justifyContent","paddingVertical","paddingRight","paddingLeft","width","maxWidth","height","overflow","flexShrink","panel","fontFamily","sans","fontWeight","fontSize","base","color","text","mono","sm","dim","red","styles","WebPluginSlotProps","CodeBlock","Markdown","fontOf","PoNativeTheme","StyleSheet","ArtifactPreview","Preview","artifactAssetPath","artifactPreviewMode","ArtifactPreviewProps","preview","sessionId","renderFilePreview","renderMediaPreview","media","data","mimeType","mediaError","onOpen","path","mode","styles","error","meta","key","title","unavailable","reason","html","content","resolved","undefined","split","at","text","create","theme","minHeight","spacing","uni__dependencies","fontFamily","mono","fontSize","sm","lineHeight","color","colors","sans","dim","red","styles","WebPluginSlotProps","Button","CloseIcon","CopyButton","DownloadIcon","fontOf","PoNativeTheme","useEffect","useRef","useState","StyleSheet","ArtifactPreview","Preview","ArtifactScope","fetchArtifactMedia","fetchArtifactPreview","prepareArtifactSave","artifactKind","artifactPreviewMode","artifactTabId","modifiedLabel","sizeLabel","useArtifacts","Loaded","key","preview","error","media","data","mimeType","mediaError","HostCopyButton","ArtifactPanel","path","scope","props","snapshot","sessionId","item","items","find","version","modifiedAt","size","downloadKey","loaded","setLoaded","controller","AbortController","signal","then","aborted","renderMediaPreview","Error","message","String","catch","abort","current","undefined","downloadController","download","setDownload","saving","note","save","nativeSaveFile","file","cancel","handlers","setTabHeader","canSave","subtitle","offline","action","styles","meta","body","renderFilePreview","openTransientTab","artifactTab","screen","stage","content","ArtifactPathStrip","now","Date","strip","stripPath","ArtifactPanelHeader","disabled","onDownload","onCancel","header","label","Parameters","id","split","at","panel","create","theme","rt","flex","padding","spacing","gap","uni__dependencies","flexDirection","alignItems","paddingHorizontal","paddingTop","paddingBottom","insets","bottom","borderTopWidth","borderTopColor","colors","backgroundColor","bg","flexShrink","borderBottomWidth","borderBottomColor","minWidth","fontFamily","mono","fontSize","sm","color","dim","sans","red","styles","WebPluginSlotProps","ImageIcon","useEffect","useState","useSyncExternalStore","StyleSheet","ArtifactItem","fetchArtifactMedia","artifactLayout","artifacts","markArtifactViewed","artifactTree","filterArtifacts","sortArtifacts","ArtifactKind","ArtifactModified","ArtifactSort","ArtifactSortDirection","authorSourceAction","useArtifacts","ArtifactList","artifactTab","authorTab","props","path","sessionId","undefined","createTab","ArtifactsPanel","SessionArtifactsPanel","snapshot","layout","listener","subscription","store","subscribe","unsubscribe","state","now","setNow","Date","query","setQuery","type","setType","modified","setModified","sort","setSort","direction","setDirection","expanded","setExpanded","selection","setSelection","viewable","setViewable","loaded","items","some","item","hasFilters","visible","error","openTransientTab","find","entry","header","dockHeader","sheet","onLayoutChange","next","update","onQueryChange","onTypeChange","onModifiedChange","value","onSortChange","onDirectionChange","rows","includes","onToggleDirectory","paths","filter","selected","onSelect","onCloseSelection","totalCount","length","onViewableImagesChange","renderImage","modifiedAt","size","ArtifactThumbnail","active","uri","setUri","controller","AbortController","signal","then","media","aborted","mimeType","startsWith","data","catch","abort","name","styles","image","create","width","height","channelArtifacts","dockArtifacts","fileLinksArtifacts"],"sources":["../../src/types/artifacts.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactView.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactsStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/artifacts.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/artifactsApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/authorSourceAction.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/artifactHooks.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactList.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactPreview.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_components/ArtifactsPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/dock/artifacts.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/_lib/temporaryFiles.ts","../../src/extensions/workspaces/sessions/(frontend)/file-links/artifacts.native.ts","../../generated/native.ts"],"sourcesContent":["export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { COMPACTION_ARTIFACT_DIRECTORY } from '../../../../../constants/artifacts';\nimport type { ArtifactItem, ArtifactSnapshot } from '../../../../../types/artifacts';\n\nexport type ArtifactLayout = 'tree' | 'list' | 'grid';\nexport type ArtifactKind = 'Markdown' | 'Image' | 'Code' | 'Data' | 'Document' | 'Other';\nexport type ArtifactModified = 'any' | 'today' | '7days' | '30days';\nexport type ArtifactSort = 'name' | 'size' | 'modified';\nexport type ArtifactSortDirection = 'asc' | 'desc';\n\nexport interface ArtifactFilters {\n query?: string;\n type?: ArtifactKind | 'any';\n modified?: ArtifactModified;\n}\n\nexport function isArtifactLayout(value: unknown): value is ArtifactLayout {\n return value === 'tree' || value === 'list' || value === 'grid';\n}\n\nexport function artifactKind(path: string): ArtifactKind {\n if (/\\.(?:md|markdown)$/iu.test(path)) return 'Markdown';\n if (/\\.(?:png|jpe?g|gif|webp|avif|bmp|svg|ico|tiff?)$/iu.test(path)) return 'Image';\n if (/\\.(?:jsonl?|csv|tsv|ya?ml|xml|toml|parquet|sqlite|db)$/iu.test(path)) return 'Data';\n if (\n /\\.(?:[cm]?[jt]sx?|html?|css|scss|sass|less|py|sh|bash|go|rs|rb|java|c|cpp|cc|h|hpp|sql|swift|kt|kts|php|vue|svelte)$/iu.test(\n path,\n )\n )\n return 'Code';\n if (/\\.(?:pdf|txt|rtf|docx?|xlsx?|pptx?|odt|ods|odp)$/iu.test(path)) return 'Document';\n return 'Other';\n}\n\n/** Time is supplied by the caller. Today starts at local midnight; day windows are inclusive. */\nexport function filterArtifacts(items: readonly ArtifactItem[], filters: ArtifactFilters, now: number): ArtifactItem[] {\n const query = (filters.query ?? '').trim().toLowerCase();\n const modified = filters.modified ?? 'any';\n const day = 24 * 60 * 60 * 1000;\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n const since = modified === 'today' ? midnight.getTime() : now - (modified === '7days' ? 7 : 30) * day;\n return items.filter(\n (item) =>\n item.path.toLowerCase().includes(query) &&\n (!filters.type || filters.type === 'any' || artifactKind(item.path) === filters.type) &&\n (modified === 'any' || (item.modifiedAt >= since && item.modifiedAt <= now)),\n );\n}\n\n/** Sort a copy, with an ascending full-path tie breaker in either direction. */\nexport function sortArtifacts(\n items: readonly ArtifactItem[],\n sort: ArtifactSort,\n direction: ArtifactSortDirection,\n): ArtifactItem[] {\n return [...items].sort((left, right) => {\n const order =\n sort === 'name'\n ? comparePaths(left.name.toLowerCase(), right.name.toLowerCase())\n : sort === 'size'\n ? left.size - right.size\n : left.modifiedAt - right.modifiedAt;\n return order * (direction === 'asc' ? 1 : -1) || comparePaths(left.path, right.path);\n });\n}\n\nfunction comparePaths(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n\ninterface ArtifactDirectory {\n path: string;\n dirs: Map<string, ArtifactDirectory>;\n files: ArtifactItem[];\n count: number;\n}\n\nexport type ArtifactTreeRow =\n | { kind: 'dir'; path: string; name: string; depth: number; open: boolean; count: number }\n | { kind: 'file'; item: ArtifactItem; depth: number };\n\n/** Derive folders from already filtered, sorted files. Folders precede files and compact single-child chains. */\nexport function artifactTree(items: readonly ArtifactItem[], isOpen: (path: string) => boolean): ArtifactTreeRow[] {\n const root: ArtifactDirectory = { path: '', dirs: new Map(), files: [], count: 0 };\n for (const item of items) {\n let dir = root;\n dir.count++;\n for (const segment of item.path.split('/').slice(0, -1)) {\n let next = dir.dirs.get(segment);\n if (!next) {\n next = { path: dir.path ? `${dir.path}/${segment}` : segment, dirs: new Map(), files: [], count: 0 };\n dir.dirs.set(segment, next);\n }\n dir = next;\n dir.count++;\n }\n dir.files.push(item);\n }\n const rows: ArtifactTreeRow[] = [];\n const walk = (dir: ArtifactDirectory, depth: number): void => {\n for (const [segment, child] of [...dir.dirs].sort(([left], [right]) => comparePaths(left, right))) {\n let name = segment;\n let node = child;\n while (node.files.length === 0 && node.dirs.size === 1) {\n const [[nextName, next]] = [...node.dirs] as [[string, ArtifactDirectory]];\n name = `${name}/${nextName}`;\n node = next;\n }\n const open = isOpen(node.path);\n rows.push({ kind: 'dir', path: node.path, name, depth, open, count: node.count });\n if (open) walk(node, depth + 1);\n }\n for (const item of dir.files) rows.push({ kind: 'file', item, depth });\n };\n walk(root, 0);\n return rows;\n}\n\n/** `Modified today` on the same calendar day, otherwise the short date. */\nexport function modifiedLabel(modifiedAt: number, now: number): string {\n const date = new Date(modifiedAt);\n return date.toDateString() === new Date(now).toDateString()\n ? 'Modified today'\n : `Modified ${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`;\n}\n\n/** What the person has seen: New (never opened), Edited (changed since opened), or Viewed. */\nexport type ArtifactStatus = 'new' | 'edited' | 'viewed';\n\n/** One session's seen record in this browser. */\nexport interface ArtifactSeenRecord {\n /** Newest server mtime when this browser first saw the session; older unopened files count as seen. */\n baseline: number;\n /** The mtime each file had when the person last opened it. */\n seen: Readonly<Record<string, number>>;\n}\n\nexport function artifactStatus(item: ArtifactItem, record: ArtifactSeenRecord | undefined): ArtifactStatus {\n if (record === undefined) return 'viewed';\n const seen = record.seen[item.path];\n if (seen !== undefined) return item.modifiedAt > seen ? 'edited' : 'viewed';\n return item.modifiedAt > record.baseline ? 'new' : 'viewed';\n}\n\n/** The web rail has no List layout; a stored `list` (shared with native) reads as Tree there. */\nexport type ArtifactRailLayout = 'tree' | 'grid';\nexport type ArtifactStatusFilter = 'all' | ArtifactStatus;\nexport type ArtifactLocation = 'artifacts' | 'temporary';\n\nexport interface ArtifactRailFilters {\n status: ArtifactStatusFilter;\n type: ArtifactKind | 'any';\n modified: ArtifactModified;\n location: ArtifactLocation;\n}\n\nexport const DEFAULT_ARTIFACT_RAIL_FILTERS: ArtifactRailFilters = {\n status: 'all',\n type: 'any',\n modified: 'any',\n location: 'artifacts',\n};\n\n/** Compact age for a narrow row: `now`, `5m`, `3h`, `2d`, then the short date. */\nexport function ageLabel(modifiedAt: number, now: number): string {\n const minutes = Math.floor(Math.max(0, now - modifiedAt) / 60000);\n if (minutes < 1) return 'now';\n if (minutes < 60) return `${minutes}m`;\n if (minutes < 60 * 24) return `${Math.floor(minutes / 60)}h`;\n if (minutes < 60 * 24 * 7) return `${Math.floor(minutes / (60 * 24))}d`;\n return new Date(modifiedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\nexport function sizeLabel(size: number): string {\n return size < 1024\n ? `${size} B`\n : size < 1024 * 1024\n ? `${Math.ceil(size / 1024)} KB`\n : `${(size / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function sortedArtifacts(items: readonly ArtifactItem[]): ArtifactItem[] {\n return [...items].sort(\n (left, right) =>\n right.modifiedAt - left.modifiedAt || (left.path < right.path ? -1 : left.path > right.path ? 1 : 0),\n );\n}\n\n/** The recent card shows the person's documents; compaction history stays in the full grid. */\nexport function recentArtifacts(items: readonly ArtifactItem[]): ArtifactItem[] {\n return sortedArtifacts(items.filter((item) => !item.path.startsWith(`${COMPACTION_ARTIFACT_DIRECTORY}/`))).slice(\n 0,\n 3,\n );\n}\n\nexport function artifactTabId(sessionId: string, path: string): string {\n return `artifact:${encodeURIComponent(sessionId)}:${encodeURIComponent(path)}`;\n}\n\n/** Resolves document assets within the artifact folder, never into another filesystem root. */\nexport function artifactAssetPath(documentPath: string, imagePath: string): string {\n if (!imagePath || imagePath.startsWith('/') || imagePath.includes('\\\\') || /^[a-z][a-z0-9+.-]*:/iu.test(imagePath))\n throw new Error('Artifact images must use a relative path.');\n const segments = documentPath.split('/').slice(0, -1);\n for (const segment of imagePath.split('/')) {\n if (segment === '' || segment === '.') continue;\n if (segment === '..') {\n if (segments.length === 0) throw new Error('The image is outside this artifact folder.');\n segments.pop();\n } else segments.push(segment);\n }\n if (segments.length === 0) throw new Error('The image path is empty.');\n return segments.join('/');\n}\n\nexport function artifactPreviewMode(path: string): 'markdown' | 'html' | 'media' | 'code' | 'text' {\n if (/\\.(?:png|jpe?g|gif|webp|avif|bmp|svg|ico|mp3|wav|m4a|ogg|mp4|mov|webm|pdf)$/iu.test(path)) return 'media';\n if (/\\.(?:md|markdown)$/iu.test(path)) return 'markdown';\n if (/\\.html?$/iu.test(path)) return 'html';\n if (/\\.(?:[cm]?[jt]sx?|json|ya?ml|css|scss|py|sh|bash|go|rs|rb|java|c|cpp|h|sql|xml|toml)$/iu.test(path))\n return 'code';\n return 'text';\n}\n\n/** A malformed channel frame must not replace the current session's known inventory. */\nexport function parseArtifactSnapshot(input: unknown): ArtifactSnapshot | null {\n if (typeof input !== 'object' || input === null || !('items' in input) || !Array.isArray(input.items)) return null;\n if ('error' in input && input.error !== undefined && typeof input.error !== 'string') return null;\n const items: ArtifactItem[] = [];\n for (const item of input.items) {\n if (\n typeof item !== 'object' ||\n item === null ||\n typeof item.path !== 'string' ||\n !item.path ||\n item.path.startsWith('/') ||\n item.path.includes('\\\\') ||\n item.path.split('/').some((part: string) => part === '..' || part === '.') ||\n typeof item.name !== 'string' ||\n !item.name ||\n typeof item.size !== 'number' ||\n !Number.isFinite(item.size) ||\n item.size < 0 ||\n typeof item.modifiedAt !== 'number' ||\n !Number.isFinite(item.modifiedAt) ||\n item.modifiedAt < 0\n )\n return null;\n items.push({ path: item.path, name: item.name, size: item.size, modifiedAt: item.modifiedAt });\n }\n return {\n items: sortedArtifacts(items),\n ...('temporaryRoot' in input && typeof input.temporaryRoot === 'string'\n ? { temporaryRoot: input.temporaryRoot }\n : {}),\n ...('error' in input && typeof input.error === 'string' ? { error: input.error } : {}),\n };\n}\n","import { defineGlobalStore, defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { artifactsChannelType, type ArtifactItem, type ArtifactSnapshot } from '../../../../../types/artifacts';\nimport {\n artifactStatus,\n parseArtifactSnapshot,\n sortedArtifacts,\n type ArtifactLayout,\n type ArtifactSeenRecord,\n} from './artifactView';\n\n/** Shared across browser mounts, in memory only until the native app restarts. */\nexport const artifactLayout = defineGlobalStore<ArtifactLayout>('tree');\n\nexport interface ArtifactsSession extends ArtifactSnapshot {\n loaded: boolean;\n}\n\nexport const artifacts = defineSessionStore<ArtifactsSession>({ items: [], loaded: false });\n\nexport const artifactsChannel = artifacts.channel<ArtifactSnapshot>({\n channel: artifactsChannelType,\n parse: parseArtifactSnapshot,\n reduce: (_current, snapshot) => ({ ...snapshot, items: sortedArtifacts(snapshot.items), loaded: true }),\n});\n\n/** An idle library remains reachable, without marking it as background work. */\nexport const artifactActivitySource = {\n subscribe: (listener: () => void) => {\n const subscription = artifacts.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive: () => false,\n};\n\n/** Files remembered per session; the earliest opened is forgotten first and then reads by the baseline. */\nconst SEEN_PATH_LIMIT = 1000;\n\n/**\n * What the person has seen, per session, as the web store records it.\n *\n * ponytail: in memory only, like the layout. After an app restart the first list\n * re-seeds the baseline, so files made while the app was closed read as seen.\n * Persist through the host's storage if people notice.\n */\nexport const artifactSeen = defineGlobalStore<Readonly<Record<string, ArtifactSeenRecord>>>({});\n\nfunction firstRecord(sessionId: string): ArtifactSeenRecord | undefined {\n const snapshot = artifacts.select(artifacts.store.state, sessionId);\n if (!snapshot.loaded || snapshot.error !== undefined) return undefined;\n return { baseline: Math.max(0, ...snapshot.items.map((item) => item.modifiedAt)), seen: {} };\n}\n\nfunction updateSeen(sessionId: string, update: (record: ArtifactSeenRecord) => ArtifactSeenRecord): void {\n const current = artifactSeen.store.state[sessionId] ?? firstRecord(sessionId);\n if (current === undefined) return;\n const next = update(current);\n if (next !== current || artifactSeen.store.state[sessionId] === undefined)\n artifactSeen.update((records) => ({ ...records, [sessionId]: next }));\n}\n\nexport function markArtifactViewed(sessionId: string, item: Pick<ArtifactItem, 'path' | 'modifiedAt'>): void {\n updateSeen(sessionId, (record) => {\n if (record.seen[item.path] === item.modifiedAt) return record;\n const others = Object.entries(record.seen).filter(([path]) => path !== item.path);\n return {\n ...record,\n seen: Object.fromEntries([...others, [item.path, item.modifiedAt] as const].slice(-SEEN_PATH_LIMIT)),\n };\n });\n}\n\nexport function markAllArtifactsViewed(sessionId: string, items: readonly ArtifactItem[]): void {\n updateSeen(sessionId, () => ({ baseline: Math.max(0, ...items.map((item) => item.modifiedAt)), seen: {} }));\n}\n\n/** Files the person has not opened yet or that changed since: New plus Edited. */\nexport function unviewedArtifactCount(sessionId: string | null): number {\n if (sessionId === null) return 0;\n const record = artifactSeen.store.state[sessionId];\n return artifacts\n .select(artifacts.store.state, sessionId)\n .items.filter((item) => artifactStatus(item, record) !== 'viewed').length;\n}\n\n// The first list for a session sets its baseline, so a batch made before the face opens still reads New.\nartifacts.store.subscribe(() => {\n for (const sessionId of Object.keys(artifacts.store.state))\n if (artifactSeen.store.state[sessionId] === undefined) updateSeen(sessionId, (record) => record);\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { artifactsChannel } from '../_lib/artifactsStore.native';\n\nexport default defineChannelFile(artifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\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 'artifacts' at. */\nexport const apiScopes = ['session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'artifacts',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import { encodeBase64 } from '@agimon-ai/po-core/native';\nimport type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\n\nimport { api } from '../../../../../../generated/client.native';\nimport type { ArtifactPreview, ArtifactScope, ArtifactSnapshot } from '../../../../../types/artifacts';\nimport { parseArtifactSnapshot } from './artifactView';\n\nconst MAX_MEDIA_BYTES = 5 * 1024 * 1024;\n\nexport async function fetchArtifacts(\n sessionId: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<ArtifactSnapshot> {\n const result = await api.session(sessionId).list({ ...(scope === 'temporary' ? { query: { scope } } : {}), signal });\n if (!result.ok) throw new Error(result.error || 'Artifacts could not be loaded.');\n const snapshot = parseArtifactSnapshot(result.data);\n if (!snapshot) throw new Error('The session returned an invalid artifact list.');\n return snapshot;\n}\n\nexport async function fetchArtifactPreview(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<ArtifactPreview> {\n const result = await api\n .session(sessionId)\n .preview({ query: { path, ...(scope === 'temporary' ? { scope } : {}) }, signal });\n if (!result.ok) throw new Error(result.error || 'This artifact could not be read.');\n const preview = result.data;\n if (\n !preview ||\n typeof preview.path !== 'string' ||\n typeof preview.content !== 'string' ||\n typeof preview.mimeType !== 'string'\n )\n throw new Error('The session returned an invalid artifact preview.');\n return preview;\n}\n\nexport async function fetchArtifactMedia(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<{ data: string; mimeType: string }> {\n const source = await prepareArtifactSave(sessionId, path, signal, scope);\n if (source.size > MAX_MEDIA_BYTES) throw new Error('This media is too large to preview.');\n const mimeType = source.mimeType.toLowerCase();\n if (!/^(?:image\\/[a-z0-9.+-]+|audio\\/[a-z0-9.+-]+|video\\/[a-z0-9.+-]+|application\\/pdf)$/u.test(mimeType))\n throw new Error('This media type cannot be previewed.');\n const bytes = new Uint8Array(source.size);\n for (let offset = 0; offset < source.size; offset += 1024 * 1024) {\n bytes.set(await source.read(offset, Math.min(1024 * 1024, source.size - offset), signal), offset);\n }\n return { data: encodeBase64(bytes), mimeType };\n}\n\n/** The native host owns saving, with bounded version-checked reads supplied by this package. */\nexport async function prepareArtifactSave(\n sessionId: string,\n path: string,\n signal: AbortSignal,\n scope: ArtifactScope = 'artifacts',\n): Promise<Parameters<NonNullable<WebPluginSlotProps['nativeSaveFile']>>[0]> {\n const load = async (headers: Record<string, string>, signal: AbortSignal): Promise<Response> => {\n if (signal.aborted) throw new Error('Download cancelled.');\n const result = await api\n .session(sessionId)\n .content({ query: { path, ...(scope === 'temporary' ? { scope } : {}) }, headers, signal });\n if (!result.ok && result.status !== 416) throw new Error(result.error || 'This artifact could not be read.');\n if (!result.response) throw new Error('This artifact could not be read.');\n return result.response;\n };\n const probe = await load({ Range: 'bytes=0-0' }, signal);\n const range = /^bytes 0-0\\/(\\d+)$/u.exec(probe.headers.get('content-range') ?? '');\n const empty =\n (probe.status === 416 && probe.headers.get('content-range') === 'bytes */0') ||\n (probe.status === 200 && probe.headers.get('content-length') === '0');\n if (!empty && (probe.status !== 206 || !range)) throw new Error('This artifact does not support bounded downloads.');\n const size = empty ? 0 : Number(range![1]);\n if (!Number.isSafeInteger(size) || size < 0) throw new Error('Invalid artifact size.');\n if ((await probe.arrayBuffer()).byteLength !== (empty ? 0 : 1)) throw new Error('Invalid artifact response.');\n if (signal.aborted) throw new Error('Download cancelled.');\n const version = probe.headers.get('etag');\n if (!version) throw new Error('The artifact has no version validator.');\n return {\n name: path.split('/').at(-1) ?? 'artifact',\n mimeType: probe.headers.get('content-type')?.split(';')[0]?.trim() || 'application/octet-stream',\n size,\n signal,\n read: async (offset, count, signal) => {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(count) ||\n offset < 0 ||\n count < 1 ||\n count > 1024 * 1024 ||\n offset + count > size\n )\n throw new Error('Invalid download range.');\n const end = offset + count - 1;\n const response = await load({ Range: `bytes=${offset}-${end}`, 'If-Match': version }, signal);\n if (\n response.status !== 206 ||\n response.headers.get('etag') !== version ||\n response.headers.get('content-range') !== `bytes ${offset}-${end}/${size}`\n )\n throw new Error('The artifact changed or its range response is invalid.');\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (signal.aborted) throw new Error('Download cancelled.');\n if (bytes.byteLength !== count) throw new Error('The artifact response is incomplete.');\n return bytes;\n },\n };\n}\n","import type { SlotDeclaration, TransientTab, WebPluginSlotProps } from '@agimon-ai/po-core/web';\n\n/**\n * Author's `author.open-source` slot, declared by duck type. A web plugin can't\n * import another feature package, so this mirrors po-browse's local copy.\n */\ninterface AuthorSourceAction {\n version: 1;\n createTab(input: { sessionId: string; path: string }): TransientTab;\n}\n\nexport const authorSourceActionSlot: SlotDeclaration<AuthorSourceAction> = {\n slot: 'author.open-source',\n parse(input) {\n if (typeof input !== 'object' || input === null) return null;\n const action = input as Partial<AuthorSourceAction>;\n return action.version === 1 && typeof action.createTab === 'function' ? (action as AuthorSourceAction) : null;\n },\n};\n\n/** Author's open action when the installed plugin contributes it. */\nexport function authorSourceAction(props: WebPluginSlotProps): AuthorSourceAction | undefined {\n return props.sessionId !== null ? props.slotData?.(authorSourceActionSlot)?.[0]?.data : undefined;\n}\n","import { useEffect, useSyncExternalStore } from 'react';\n\nimport { fetchArtifacts } from '../_lib/artifactsApi.native';\nimport { artifactActivitySource, artifacts } from '../_lib/artifactsStore.native';\n\n/** A fresh grid read complements the live session channel and seeds a newly attached rail. */\nexport function useArtifacts(sessionId: string | null, refreshOnMount = false) {\n const snapshot = useSyncExternalStore(artifactActivitySource.subscribe, () =>\n artifacts.select(artifacts.store.state, sessionId),\n );\n useEffect(() => {\n if (sessionId === null) return;\n const before = artifacts.select(artifacts.store.state, sessionId);\n if (before.loaded && !refreshOnMount) return;\n const controller = new AbortController();\n void fetchArtifacts(sessionId, controller.signal)\n .then((next) => {\n if (!controller.signal.aborted)\n artifacts.update(sessionId, (current) => (current === before ? { ...next, loaded: true } : current));\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n artifacts.update(sessionId, (current) =>\n current === before\n ? { ...current, loaded: true, error: error instanceof Error ? error.message : String(error) }\n : current,\n );\n });\n return () => controller.abort();\n }, [sessionId, refreshOnMount]);\n return snapshot;\n}\n","import {\n Button,\n FolderIcon,\n FileIcon,\n ImageIcon,\n SearchIcon,\n SlidersIcon,\n CloseIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n Input,\n SegmentedControl,\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuCheckboxItem,\n DropdownMenuSeparator,\n fontOf,\n Sheet,\n SheetContent,\n SheetList,\n} from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useCallback, type ReactNode } from 'react';\nimport { FlatList, Text, View, type ListViewToken } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactItem } from '../../../../../types/artifacts';\nimport {\n artifactKind,\n sizeLabel,\n isArtifactLayout,\n type ArtifactLayout,\n type ArtifactKind,\n type ArtifactModified,\n type ArtifactSort,\n type ArtifactSortDirection,\n type ArtifactTreeRow,\n} from '../_lib/artifactView';\n\nexport interface ArtifactBrowserProps {\n layout: ArtifactLayout;\n onLayoutChange: (layout: ArtifactLayout) => void;\n query: string;\n onQueryChange: (query: string) => void;\n type: ArtifactKind | 'any';\n onTypeChange: (type: ArtifactKind | 'any') => void;\n modified: ArtifactModified;\n onModifiedChange: (modified: ArtifactModified) => void;\n sort: ArtifactSort;\n onSortChange: (sort: ArtifactSort) => void;\n direction: ArtifactSortDirection;\n onDirectionChange: (direction: ArtifactSortDirection) => void;\n rows: readonly ArtifactTreeRow[];\n onToggleDirectory: (path: string) => void;\n selected?: ArtifactItem;\n onSelect: (item: ArtifactItem) => void;\n onCloseSelection: () => void;\n totalCount: number;\n onViewableImagesChange?: (paths: readonly string[]) => void;\n renderImage?: (item: ArtifactItem) => ReactNode;\n /** Drawn first in the list, above the controls, such as the native dock's tab strip. */\n header?: ReactNode;\n /** Inside a bottom sheet with no scroll view of its own: the list is the sheet's only scroll owner. */\n sheet?: boolean;\n}\n\nexport interface ArtifactListProps {\n items: readonly ArtifactItem[];\n onOpen: (path: string) => void;\n loading?: boolean;\n error?: string;\n grid?: boolean;\n browser?: ArtifactBrowserProps;\n}\n\n/** Presentation only. The session store and guarded API belong to the containers. */\nexport function ArtifactList({ items, onOpen, loading, error, grid = false, browser }: ArtifactListProps) {\n if (browser)\n return <ArtifactBrowser items={items} onOpen={onOpen} loading={loading} error={error} browser={browser} />;\n return (\n <View testID={grid ? 'artifacts-grid' : 'artifacts-recent'} style={styles.list}>\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {loading ? <Text style={styles.meta}>Loading artifacts...</Text> : null}\n {!loading && !error && items.length === 0 ? (\n <Text style={styles.meta}>Documents saved for this session will appear here.</Text>\n ) : null}\n {items.map((item) => (\n <Button\n key={item.path}\n variant={grid ? 'outline' : 'ghost'}\n size=\"card\"\n accessibilityLabel={`Open ${item.path}`}\n testID={`artifact-${item.path}`}\n onPress={() => onOpen(item.path)}\n style={styles.item}\n >\n <FileIcon size={18} color=\"dim\" />\n <View style={styles.label}>\n <Text numberOfLines={1} style={styles.name}>\n {item.name}\n </Text>\n {grid || item.path !== item.name ? (\n <Text numberOfLines={1} style={styles.path}>\n {item.path}\n </Text>\n ) : null}\n {grid ? <Text style={styles.meta}>{item.size.toLocaleString('en-US')} bytes</Text> : null}\n </View>\n </Button>\n ))}\n </View>\n );\n}\n\nconst LAYOUTS = [\n { value: 'tree', label: 'Tree' },\n { value: 'list', label: 'List' },\n { value: 'grid', label: 'Grid' },\n];\nconst TYPES = ['any', 'Markdown', 'Image', 'Code', 'Data', 'Document', 'Other'] as const;\nconst MODIFIED = [\n { value: 'any', label: 'Any time' },\n { value: 'today', label: 'Today' },\n { value: '7days', label: 'Last 7 days' },\n { value: '30days', label: 'Last 30 days' },\n] as const;\nconst SORTS = [\n { value: 'name', label: 'Name' },\n { value: 'modified', label: 'Modified' },\n { value: 'size', label: 'Size' },\n] as const;\nconst ROW_HEIGHT = 48;\nconst IMAGE_VIEWABILITY = { itemVisiblePercentThreshold: 1 };\n\nfunction ArtifactBrowser({\n items,\n onOpen,\n loading,\n error,\n browser: b,\n}: ArtifactListProps & { browser: ArtifactBrowserProps }) {\n const grid = b.layout === 'grid';\n const onViewableImagesChange = b.onViewableImagesChange;\n const onViewableItemsChanged = useCallback(\n ({ viewableItems }: { viewableItems: (Omit<ListViewToken, 'item'> & { item: ArtifactTreeRow })[] }) => {\n onViewableImagesChange?.(\n viewableItems.flatMap(({ item, isViewable }) =>\n grid && isViewable && item.kind === 'file' && artifactKind(item.item.path) === 'Image'\n ? [item.item.path]\n : [],\n ),\n );\n },\n [grid, onViewableImagesChange],\n );\n const rows: readonly ArtifactTreeRow[] =\n b.layout === 'tree' ? b.rows : items.map((item) => ({ kind: 'file', item, depth: 0 }));\n const List = b.sheet ? SheetList<ArtifactTreeRow> : FlatList<ArtifactTreeRow>;\n const list = (\n <List\n {...(b.sheet ? { embedded: true } : {})}\n key={b.layout}\n testID=\"artifacts-browser\"\n onViewableItemsChanged={onViewableItemsChanged}\n viewabilityConfig={IMAGE_VIEWABILITY}\n data={loading || error ? [] : rows}\n numColumns={grid ? 2 : 1}\n columnWrapperStyle={grid ? styles.columns : undefined}\n keyExtractor={(row) => (row.kind === 'dir' ? `dir:${row.path}` : row.item.path)}\n keyboardShouldPersistTaps=\"handled\"\n ListHeaderComponent={\n <>\n {b.header}\n <View style={styles.head}>\n <SegmentedControl\n accessibilityLabel=\"Artifact layout\"\n options={LAYOUTS}\n value={b.layout}\n onValueChange={(value) => {\n if (isArtifactLayout(value)) b.onLayoutChange(value);\n }}\n />\n <View style={styles.toolbar}>\n <View style={styles.search}>\n <SearchIcon size={18} />\n <Input\n variant=\"bare\"\n accessibilityLabel=\"Search artifacts\"\n placeholder=\"Search artifacts\"\n value={b.query}\n onChangeText={b.onQueryChange}\n style={styles.searchInput}\n autoCapitalize=\"none\"\n />\n </View>\n <DropdownMenu>\n <DropdownMenuTrigger variant=\"outline\" accessibilityLabel=\"Filters\">\n <SlidersIcon />\n Filters\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuLabel>Type</DropdownMenuLabel>\n {TYPES.map((type) => (\n <DropdownMenuCheckboxItem\n key={type}\n checked={b.type === type}\n onCheckedChange={() => b.onTypeChange(type)}\n >\n {type === 'any' ? 'All types' : type}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>Modified</DropdownMenuLabel>\n {MODIFIED.map(({ value, label }) => (\n <DropdownMenuCheckboxItem\n key={value}\n checked={b.modified === value}\n onCheckedChange={() => b.onModifiedChange(value)}\n >\n {label}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>Sort</DropdownMenuLabel>\n {SORTS.map(({ value, label }) => (\n <DropdownMenuCheckboxItem\n key={value}\n checked={b.sort === value}\n onCheckedChange={() => b.onSortChange(value)}\n >\n {label}\n </DropdownMenuCheckboxItem>\n ))}\n <DropdownMenuCheckboxItem\n checked={b.direction === 'asc'}\n onCheckedChange={() => b.onDirectionChange('asc')}\n >\n Ascending\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={b.direction === 'desc'}\n onCheckedChange={() => b.onDirectionChange('desc')}\n >\n Descending\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </View>\n <View style={styles.chips}>\n {b.query ? (\n <Button variant=\"outline\" accessibilityLabel=\"Remove search filter\" onPress={() => b.onQueryChange('')}>\n Search: {b.query}\n <CloseIcon />\n </Button>\n ) : null}\n {b.type !== 'any' ? (\n <Button variant=\"outline\" accessibilityLabel=\"Remove type filter\" onPress={() => b.onTypeChange('any')}>\n {b.type}\n <CloseIcon />\n </Button>\n ) : null}\n {b.modified !== 'any' ? (\n <Button\n variant=\"outline\"\n accessibilityLabel=\"Remove modified filter\"\n onPress={() => b.onModifiedChange('any')}\n >\n {MODIFIED.find((option) => option.value === b.modified)?.label}\n <CloseIcon />\n </Button>\n ) : null}\n </View>\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {loading ? <Text style={styles.meta}>Loading artifacts...</Text> : null}\n </View>\n </>\n }\n ListEmptyComponent={\n !loading && !error ? (\n <Text style={[styles.meta, styles.inset]}>\n {b.totalCount ? 'No artifacts match these filters.' : 'Documents saved for this session will appear here.'}\n </Text>\n ) : undefined\n }\n renderItem={({ item: row }) => {\n if (row.kind === 'dir')\n return (\n <Button\n variant=\"ghost\"\n style={[styles.row, styles.indent(row.depth)]}\n accessibilityLabel={`${row.open ? 'Collapse' : 'Expand'} ${row.path}`}\n accessibilityState={{ expanded: row.open }}\n onPress={() => b.onToggleDirectory(row.path)}\n >\n {row.open ? <ChevronDownIcon /> : <ChevronRightIcon />}\n <FolderIcon />\n <Text numberOfLines={1} style={[styles.name, styles.label]}>\n {row.name}\n </Text>\n <Text style={styles.meta}>{row.count}</Text>\n </Button>\n );\n const item = row.item;\n const image = artifactKind(item.path) === 'Image';\n const selected = b.selected?.path === item.path;\n return (\n <Button\n variant=\"ghost\"\n size=\"card\"\n testID={`artifact-${item.path}`}\n accessibilityLabel={`Select ${item.path}`}\n accessibilityState={{ selected }}\n onPress={() => b.onSelect(item)}\n style={[grid ? styles.tile : styles.row, selected && styles.selected, !grid && styles.indent(row.depth)]}\n >\n {b.layout === 'tree' ? <View accessible={false} style={styles.chevronGutter} /> : null}\n {grid ? (\n <View style={styles.thumbnail}>\n {image && b.renderImage ? (\n b.renderImage(item)\n ) : image ? (\n <ImageIcon size={28} />\n ) : (\n <FileIcon size={28} />\n )}\n </View>\n ) : image ? (\n <ImageIcon size={18} />\n ) : (\n <FileIcon size={18} />\n )}\n <View style={styles.label}>\n <Text numberOfLines={1} style={styles.name}>\n {item.name}\n </Text>\n <Text numberOfLines={1} style={styles.path}>\n {item.path}\n </Text>\n </View>\n <Text style={styles.meta}>{sizeLabel(item.size)}</Text>\n </Button>\n );\n }}\n ListFooterComponent={\n <View style={styles.foot}>\n <Text style={styles.meta}>\n {items.length} of {b.totalCount} artifacts\n </Text>\n </View>\n }\n />\n );\n return (\n <>\n {list}\n <Sheet\n open={b.selected !== undefined}\n onOpenChange={(open) => {\n if (!open) b.onCloseSelection();\n }}\n >\n <SheetContent>\n {b.selected ? (\n <View style={styles.foot}>\n <View style={styles.selection} testID=\"artifact-selection\">\n <Text accessibilityRole=\"header\" numberOfLines={1} style={styles.name}>\n {b.selected.name}\n </Text>\n <Text numberOfLines={2} style={styles.path}>\n {b.selected.path}\n </Text>\n <Text style={styles.meta}>\n {artifactKind(b.selected.path)} · {sizeLabel(b.selected.size)}\n </Text>\n <View style={styles.actions}>\n <Button variant=\"outline\" onPress={b.onCloseSelection}>\n Close\n </Button>\n <Button\n variant=\"primary\"\n onPress={() => {\n if (b.selected) {\n b.onCloseSelection();\n onOpen(b.selected.path);\n }\n }}\n >\n Open\n </Button>\n </View>\n </View>\n </View>\n ) : null}\n </SheetContent>\n </Sheet>\n </>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n head: { gap: theme.spacing(3), padding: theme.spacing(4), paddingBottom: theme.spacing(3) },\n foot: { gap: theme.spacing(3), padding: theme.spacing(4), paddingTop: theme.spacing(3) },\n inset: { paddingHorizontal: theme.spacing(4) },\n toolbar: { flexDirection: 'row', alignItems: 'center', gap: theme.spacing(2) },\n search: {\n flex: 1,\n minWidth: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingHorizontal: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.DEFAULT,\n backgroundColor: theme.colors.deep,\n },\n searchInput: { flex: 1 },\n chips: { flexDirection: 'row', flexWrap: 'wrap', gap: theme.spacing(2) },\n row: {\n marginHorizontal: theme.spacing(4),\n marginBottom: theme.spacing(2),\n // A file row holds two lines; a fixed height pressed them against the border.\n minHeight: ROW_HEIGHT,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-start',\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors['border-soft'],\n borderRadius: theme.borderRadius.DEFAULT,\n paddingVertical: theme.spacing(2),\n paddingRight: theme.spacing(3),\n },\n // Tree depth adds to the row's own inset; replacing it put the icon against the border.\n indent: (depth: number) => ({ paddingLeft: theme.spacing(3) + depth * 16 }),\n chevronGutter: { width: 16 },\n columns: { gap: theme.spacing(2), paddingHorizontal: theme.spacing(4) },\n tile: {\n flex: 1,\n maxWidth: '50%',\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors['border-soft'],\n marginBottom: theme.spacing(2),\n },\n thumbnail: {\n height: 96,\n backgroundColor: theme.colors.deep,\n borderRadius: theme.borderRadius.DEFAULT,\n overflow: 'hidden',\n alignItems: 'center',\n justifyContent: 'center',\n },\n selected: { backgroundColor: theme.colors['tint-green'], borderColor: theme.colors['edge-green'] },\n selection: {\n flexShrink: 0,\n padding: theme.spacing(3),\n gap: theme.spacing(2),\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.DEFAULT,\n backgroundColor: theme.colors.panel,\n },\n actions: { flexDirection: 'row', justifyContent: 'flex-end', gap: theme.spacing(2) },\n list: { gap: theme.spacing(2) },\n // The card size stacks its children; a recent row reads like the browser's list row instead.\n item: {\n minHeight: 44,\n flexDirection: 'row',\n justifyContent: 'flex-start',\n alignItems: 'center',\n gap: theme.spacing(3),\n },\n label: { flex: 1, gap: theme.spacing(1), minWidth: 0 },\n name: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontWeight: '600',\n fontSize: theme.fontSize.base,\n color: theme.colors.text,\n },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { CodeBlock, Markdown, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactPreview as Preview } from '../../../../../types/artifacts';\nimport { artifactAssetPath, artifactPreviewMode } from '../_lib/artifactView';\n\nexport interface ArtifactPreviewProps {\n preview: Preview;\n sessionId: string;\n renderFilePreview?: WebPluginSlotProps['renderFilePreview'];\n renderMediaPreview?: WebPluginSlotProps['renderMediaPreview'];\n media?: { data: string; mimeType: string };\n mediaError?: string;\n onOpen: (path: string) => void;\n}\n\n/** The host receives only content fetched through the artifact's bounded route. */\nexport function ArtifactPreview({\n preview,\n sessionId,\n renderFilePreview,\n renderMediaPreview,\n media,\n mediaError,\n onOpen,\n}: ArtifactPreviewProps) {\n const mode = artifactPreviewMode(preview.path);\n if (mode === 'media') {\n if (mediaError)\n return (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {mediaError}\n </Text>\n );\n if (!renderMediaPreview) return <Text style={styles.meta}>This host cannot display this media preview.</Text>;\n if (!media) return <Text style={styles.meta}>Loading media...</Text>;\n return (\n <>\n {renderMediaPreview({\n key: `artifact-media-${sessionId}-${preview.path}`,\n title: preview.path,\n path: preview.path,\n data: media.data,\n mimeType: media.mimeType,\n })}\n </>\n );\n }\n if (preview.unavailable)\n return <Text style={styles.meta}>{preview.reason ?? 'This artifact cannot be previewed.'}</Text>;\n if (mode === 'html') {\n return renderFilePreview ? (\n <View style={styles.html}>\n {renderFilePreview({\n key: `artifact-html-${sessionId}-${preview.path}`,\n html: preview.content,\n title: preview.path,\n })}\n </View>\n ) : (\n <Text style={styles.meta}>This host cannot display HTML previews.</Text>\n );\n }\n if (mode === 'markdown') {\n return (\n <Markdown\n text={preview.content}\n onFileLink={(path) => {\n try {\n const resolved = artifactAssetPath(preview.path, path);\n return () => onOpen(resolved);\n } catch {\n // An out-of-folder or non-file link is not an artifact action.\n return undefined;\n }\n }}\n />\n );\n }\n if (mode === 'code') return <CodeBlock text={preview.content} language={preview.path.split('.').at(-1)} />;\n return (\n <Text selectable style={styles.text}>\n {preview.content}\n </Text>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n html: { minHeight: theme.spacing(90) },\n text: {\n fontFamily: fontOf(theme.fontFamily.mono),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.text,\n },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, CloseIcon, CopyButton, DownloadIcon, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useEffect, useRef, useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactPreview as Preview, ArtifactScope } from '../../../../../types/artifacts';\nimport { fetchArtifactMedia, fetchArtifactPreview, prepareArtifactSave } from '../_lib/artifactsApi.native';\nimport { artifactKind, artifactPreviewMode, artifactTabId, modifiedLabel, sizeLabel } from '../_lib/artifactView';\nimport { useArtifacts } from './artifactHooks.native';\nimport { ArtifactPreview } from './ArtifactPreview.native';\n\ninterface Loaded {\n key: string;\n preview?: Preview;\n error?: string;\n media?: { data: string; mimeType: string };\n mediaError?: string;\n}\n\n// Older app builds lack this export; the strip then leaves the path selectable without a copy control.\nconst HostCopyButton: typeof CopyButton | undefined = CopyButton;\n\nexport function ArtifactPanel({\n path,\n scope = 'artifacts',\n ...props\n}: WebPluginSlotProps & { path: string; scope?: ArtifactScope }) {\n const snapshot = useArtifacts(props.sessionId);\n const item = snapshot.items.find((item) => item.path === path);\n const version = `${item?.modifiedAt ?? ''}:${item?.size ?? ''}`;\n const downloadKey = `${scope === 'temporary' ? 'temporary:' : ''}${props.sessionId}:${path}`;\n const key = `${downloadKey}:${version}`;\n const [loaded, setLoaded] = useState<Loaded>();\n useEffect(() => {\n if (props.sessionId === null) return;\n const sessionId = props.sessionId;\n const controller = new AbortController();\n void fetchArtifactPreview(sessionId, path, controller.signal, scope)\n .then(async (preview) => {\n if (controller.signal.aborted) return;\n setLoaded({ key, preview });\n if (artifactPreviewMode(path) !== 'media' || !props.renderMediaPreview) return;\n try {\n const media = await fetchArtifactMedia(sessionId, path, controller.signal, scope);\n if (!controller.signal.aborted) setLoaded({ key, preview, media });\n } catch (error) {\n if (!controller.signal.aborted)\n setLoaded({ key, preview, mediaError: error instanceof Error ? error.message : String(error) });\n }\n })\n .catch((error: unknown) => {\n if (!controller.signal.aborted)\n setLoaded({ key, error: error instanceof Error ? error.message : String(error) });\n });\n return () => controller.abort();\n }, [props.sessionId, path, key, props.renderMediaPreview, scope]);\n const current = loaded?.key === key ? loaded : undefined;\n const downloadController = useRef<AbortController | undefined>(undefined);\n const [download, setDownload] = useState<{ key: string; saving?: boolean; note?: string }>();\n useEffect(\n () => () => {\n downloadController.current?.abort();\n downloadController.current = undefined;\n },\n [props.sessionId, path, scope],\n );\n const saving = download?.key === downloadKey && download.saving === true;\n const save = async () => {\n if (props.sessionId === null || !props.nativeSaveFile || downloadController.current) return;\n const controller = new AbortController();\n downloadController.current = controller;\n setDownload({ key: downloadKey, saving: true });\n try {\n const file = await prepareArtifactSave(props.sessionId, path, controller.signal, scope);\n if (controller.signal.aborted || downloadController.current !== controller) return;\n await props.nativeSaveFile(file);\n if (!controller.signal.aborted && downloadController.current === controller)\n setDownload({ key: downloadKey, note: 'Saved.' });\n } catch (error) {\n if (!controller.signal.aborted && downloadController.current === controller)\n setDownload({ key: downloadKey, note: error instanceof Error ? error.message : String(error) });\n } finally {\n if (downloadController.current === controller) downloadController.current = undefined;\n }\n };\n const cancel = () => {\n downloadController.current?.abort();\n downloadController.current = undefined;\n setDownload({ key: downloadKey, note: 'Download cancelled.' });\n };\n // The top bar's control outlives this render; it reaches the latest handlers through a ref synced after commit.\n const handlers = useRef({ save, cancel });\n useEffect(() => {\n handlers.current = { save, cancel };\n });\n const { setTabHeader } = props;\n const canSave = props.nativeSaveFile !== undefined;\n // Once the host's media view is showing, it names and saves the media in the top bar; the panel speaks otherwise.\n const media =\n artifactPreviewMode(path) === 'media' && props.renderMediaPreview !== undefined && current?.media !== undefined;\n const subtitle = `${artifactKind(path)}${item ? ` · ${sizeLabel(item.size)}` : ''}`;\n const offline = props.sessionId === null;\n useEffect(() => {\n if (!setTabHeader || media) return;\n setTabHeader({\n subtitle,\n action: canSave ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={offline}\n accessibilityLabel={saving ? 'Cancel download' : 'Download'}\n onPress={() => (saving ? handlers.current.cancel() : void handlers.current.save())}\n >\n {saving ? <CloseIcon color=\"hi\" /> : <DownloadIcon color=\"hi\" />}\n </Button>\n ) : undefined,\n });\n }, [setTabHeader, media, subtitle, canSave, saving, offline]);\n const note =\n download?.key === downloadKey && download.note ? (\n <Text accessibilityLiveRegion=\"polite\" style={styles.meta}>\n {download.note}\n </Text>\n ) : null;\n const body =\n props.sessionId === null ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n The session is unavailable.\n </Text>\n ) : current?.error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {current.error}\n </Text>\n ) : current?.preview ? (\n <ArtifactPreview\n preview={current.preview}\n sessionId={props.sessionId}\n renderFilePreview={props.renderFilePreview}\n renderMediaPreview={props.renderMediaPreview}\n media={current.media}\n mediaError={current.mediaError}\n onOpen={(path) => {\n if (props.sessionId !== null) props.openTransientTab(artifactTab(props.sessionId, path, scope));\n }}\n />\n ) : (\n <Text style={styles.meta}>Reading this artifact...</Text>\n );\n return (\n <View style={styles.screen}>\n {media ? (\n <View style={styles.stage}>{body}</View>\n ) : (\n <ScrollView style={styles.stage} contentContainerStyle={styles.content}>\n {setTabHeader ? null : (\n <ArtifactPanelHeader\n path={path}\n size={item?.size}\n saving={saving}\n canSave={canSave}\n disabled={offline}\n onDownload={() => void save()}\n onCancel={cancel}\n />\n )}\n {note}\n {body}\n </ScrollView>\n )}\n <ArtifactPathStrip path={path} modifiedAt={item?.modifiedAt} />\n </View>\n );\n}\n\n/** Where the file lives and when it last changed, pinned under the preview. */\nexport function ArtifactPathStrip({ path, modifiedAt }: { path: string; modifiedAt?: number }) {\n // Read once per mount: a preview left open past midnight keeps its first label, which is still true then.\n const [now] = useState(Date.now);\n return (\n <View style={styles.strip}>\n <Text selectable numberOfLines={1} ellipsizeMode=\"middle\" style={[styles.path, styles.stripPath]}>\n {path}\n </Text>\n {HostCopyButton ? <HostCopyButton text={path} label=\"path\" /> : null}\n {modifiedAt === undefined ? null : <Text style={styles.meta}>{modifiedLabel(modifiedAt, now)}</Text>}\n </View>\n );\n}\n\n/** The preview's quiet header: where the file lives, what it is, and the one action on it. */\nexport function ArtifactPanelHeader({\n path,\n size,\n saving,\n canSave,\n disabled,\n onDownload,\n onCancel,\n}: {\n path: string;\n size?: number;\n saving: boolean;\n canSave: boolean;\n disabled: boolean;\n onDownload: () => void;\n onCancel: () => void;\n}) {\n return (\n <View style={styles.header}>\n <View style={styles.label}>\n <Text selectable numberOfLines={1} ellipsizeMode=\"middle\" style={styles.path}>\n {path}\n </Text>\n <Text style={styles.meta}>\n {artifactKind(path)}\n {size === undefined ? '' : ` · ${sizeLabel(size)}`}\n {canSave ? '' : ' · This host cannot save artifact downloads.'}\n </Text>\n </View>\n {canSave && saving ? (\n <Button variant=\"ghost\" size=\"sm\" onPress={onCancel}>\n Cancel\n </Button>\n ) : null}\n {canSave ? (\n <Button variant=\"outline\" size=\"sm\" disabled={saving || disabled} onPress={onDownload}>\n Download\n </Button>\n ) : null}\n </View>\n );\n}\n\nexport function artifactTab(\n sessionId: string,\n path: string,\n scope: ArtifactScope = 'artifacts',\n): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return {\n id: `${scope === 'temporary' ? 'temporary:' : ''}${artifactTabId(sessionId, path)}`,\n label: path.split('/').at(-1) ?? path,\n panel: (props) => <ArtifactPanel {...props} sessionId={sessionId} path={path} scope={scope} />,\n };\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme, rt) => ({\n screen: { flex: 1 },\n stage: { flex: 1 },\n content: { padding: theme.spacing(4), gap: theme.spacing(3) },\n strip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingHorizontal: theme.spacing(4),\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2) + rt.insets.bottom,\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n backgroundColor: theme.colors.bg,\n },\n stripPath: { flexShrink: 1 },\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingBottom: theme.spacing(3),\n borderBottomWidth: 1,\n borderBottomColor: theme.colors['border-soft'],\n },\n label: { flex: 1, minWidth: 0, gap: theme.spacing(0.5) },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n meta: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontFamily: fontOf(theme.fontFamily.sans), fontSize: theme.fontSize.sm, color: theme.colors.red },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { ImageIcon } from '@agimon-ai/po-native-components';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport { Image } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { ArtifactItem } from '../../../../../types/artifacts';\nimport { fetchArtifactMedia } from '../_lib/artifactsApi.native';\nimport { artifactLayout, artifacts, markArtifactViewed } from '../_lib/artifactsStore.native';\nimport {\n artifactTree,\n filterArtifacts,\n sortArtifacts,\n type ArtifactKind,\n type ArtifactModified,\n type ArtifactSort,\n type ArtifactSortDirection,\n} from '../_lib/artifactView';\nimport { authorSourceAction } from '../_lib/authorSourceAction';\nimport { useArtifacts } from './artifactHooks.native';\nimport { ArtifactList } from './ArtifactList.native';\nimport { artifactTab } from './ArtifactPanel.native';\n\n/** With Author installed, a file it can mark up opens in Author's canvas; it refuses the rest, which keep this viewer. */\nfunction authorTab(props: WebPluginSlotProps, path: string) {\n try {\n return props.sessionId === null\n ? undefined\n : authorSourceAction(props)?.createTab({ sessionId: props.sessionId, path: `artifact:${path}` });\n } catch {\n return undefined;\n }\n}\n\nexport function ArtifactsPanel(props: WebPluginSlotProps) {\n // Remount session-local controls synchronously, without flashing another session's selection.\n return <SessionArtifactsPanel key={props.sessionId} {...props} />;\n}\n\nfunction SessionArtifactsPanel(props: WebPluginSlotProps) {\n const snapshot = useArtifacts(props.sessionId, true);\n const layout = useSyncExternalStore(\n (listener) => {\n const subscription = artifactLayout.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n () => artifactLayout.store.state,\n );\n const [now, setNow] = useState(Date.now);\n useEffect(() => {\n const subscription = artifacts.store.subscribe(() => setNow(Date.now()));\n return () => subscription.unsubscribe();\n }, []);\n const [query, setQuery] = useState('');\n const [type, setType] = useState<ArtifactKind | 'any'>('any');\n const [modified, setModified] = useState<ArtifactModified>('any');\n const [sort, setSort] = useState<ArtifactSort>('name');\n const [direction, setDirection] = useState<ArtifactSortDirection>('asc');\n const [expanded, setExpanded] = useState<string[]>([]);\n const [selection, setSelection] = useState<string>();\n const [viewable, setViewable] = useState<readonly string[]>([]);\n if (snapshot.loaded && selection && !snapshot.items.some((item) => item.path === selection)) setSelection(undefined);\n const hasFilters = query !== '' || type !== 'any' || modified !== 'any';\n const visible = sortArtifacts(filterArtifacts(snapshot.items, { query, type, modified }, now), sort, direction);\n return (\n <ArtifactList\n items={visible}\n loading={!snapshot.loaded}\n error={props.sessionId === null ? 'The session is unavailable.' : snapshot.error}\n onOpen={(path) => {\n if (props.sessionId === null) return;\n props.openTransientTab(authorTab(props, path) ?? artifactTab(props.sessionId, path));\n const item = snapshot.items.find((entry) => entry.path === path);\n if (item !== undefined) markArtifactViewed(props.sessionId, item);\n }}\n browser={{\n header: props.dockHeader,\n sheet: true,\n layout,\n onLayoutChange: (next) => {\n setViewable([]);\n artifactLayout.update(() => next);\n },\n query,\n onQueryChange: setQuery,\n type,\n onTypeChange: setType,\n modified,\n onModifiedChange: (value) => {\n setModified(value);\n setNow(Date.now());\n },\n sort,\n onSortChange: setSort,\n direction,\n onDirectionChange: setDirection,\n rows: artifactTree(visible, (path) => hasFilters || expanded.includes(path)),\n onToggleDirectory: (path) =>\n setExpanded((paths) => (paths.includes(path) ? paths.filter((value) => value !== path) : [...paths, path])),\n selected: snapshot.items.find((item) => item.path === selection),\n onSelect: (item) => setSelection(item.path),\n onCloseSelection: () => setSelection(undefined),\n totalCount: snapshot.items.length,\n onViewableImagesChange: setViewable,\n renderImage: (item) => (\n <ArtifactThumbnail\n key={`${props.sessionId}:${item.path}:${item.modifiedAt}:${item.size}`}\n sessionId={props.sessionId}\n item={item}\n active={layout === 'grid' && viewable.includes(item.path)}\n />\n ),\n }}\n />\n );\n}\n\nfunction ArtifactThumbnail({\n sessionId,\n item,\n active,\n}: {\n sessionId: string | null;\n item: ArtifactItem;\n active: boolean;\n}) {\n const [uri, setUri] = useState<string>();\n useEffect(() => {\n if (uri !== undefined || !active || sessionId === null || item.size > 5 * 1024 * 1024) return;\n const controller = new AbortController();\n void fetchArtifactMedia(sessionId, item.path, controller.signal)\n .then((media) => {\n if (!controller.signal.aborted && media.mimeType.startsWith('image/'))\n setUri(`data:${media.mimeType};base64,${media.data}`);\n })\n // A failed thumbnail keeps the image placeholder; opening still uses the full preview route.\n .catch(() => {\n if (!controller.signal.aborted) setUri(undefined);\n });\n return () => controller.abort();\n }, [sessionId, item.path, item.size, item.modifiedAt, active, uri]);\n return active && uri ? (\n <Image accessibilityLabel={item.name} source={{ uri }} resizeMode=\"contain\" style={styles.image} />\n ) : (\n <ImageIcon size={28} />\n );\n}\n\nconst styles = StyleSheet.create({\n image: { width: '100%', height: '100%' },\n});\n","import { defineDockFace } from '@agimon-ai/po-core/native';\n\nimport { ArtifactsPanel } from '../_components/ArtifactsPanel.native';\nimport { artifacts, artifactSeen, unviewedArtifactCount } from '../_lib/artifactsStore.native';\n\nexport default defineDockFace({\n id: 'artifacts',\n label: 'Artifacts',\n order: 10,\n panel: ArtifactsPanel,\n ownsScroll: true,\n badge: {\n subscribe(listener: () => void) {\n const files = artifacts.store.subscribe(listener);\n const seen = artifactSeen.store.subscribe(listener);\n return () => {\n files.unsubscribe();\n seen.unsubscribe();\n };\n },\n count: unviewedArtifactCount,\n },\n});\n","/** Matching links is presentation only. The server independently selects and guards the root. */\nexport function temporaryFileReference(reference: string, root: string | undefined): string | undefined {\n const value = reference.trim();\n const prefix = 'temporary:';\n let relative: string;\n if (value.startsWith(prefix)) relative = value.slice(prefix.length);\n else {\n if (!root || !root.startsWith('/')) return undefined;\n const base = root.replace(/\\/+$/u, '');\n if (!value.startsWith(`${base}/`)) return undefined;\n relative = value.slice(base.length + 1);\n }\n if (\n !relative ||\n relative.includes('\\\\') ||\n relative.includes('\\0') ||\n relative.split('/').some((part) => !part || part === '.' || part === '..')\n )\n return undefined;\n return relative;\n}\n","import { defineFileLinks } from '@agimon-ai/po-core/native';\n\nimport { artifactTab } from '../_components/ArtifactPanel.native';\nimport { artifacts } from '../_lib/artifactsStore.native';\nimport { temporaryFileReference } from '../_lib/temporaryFiles';\n\nexport default defineFileLinks({\n subscribe(listener) {\n const subscription = artifacts.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n fingerprint: (sessionId) => artifacts.select(artifacts.store.state, sessionId).temporaryRoot ?? '',\n resolve(sessionId, path) {\n if (sessionId === null) return undefined;\n const reference = path.trim();\n const temporary = temporaryFileReference(\n reference,\n artifacts.select(artifacts.store.state, sessionId).temporaryRoot,\n );\n if (temporary) return artifactTab(sessionId, temporary, 'temporary');\n if (!reference.startsWith('artifact:')) return undefined;\n const relative = reference.slice('artifact:'.length);\n return relative ? artifactTab(sessionId, relative) : undefined;\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 channelArtifacts from '../src/extensions/workspaces/sessions/(frontend)/channel/artifacts.native';\nimport dockArtifacts from '../src/extensions/workspaces/sessions/(frontend)/dock/artifacts.native';\nimport fileLinksArtifacts from '../src/extensions/workspaces/sessions/(frontend)/file-links/artifacts.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: 'artifacts',\n session: {\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'artifacts' }, channelArtifacts)]; },\n get dockFaces(): WebPluginContributions['dockFaces'] { return [via({ id: 'artifacts' }, dockArtifacts)]; },\n get fileLinks(): WebPluginContributions['fileLinks'] { return fileLinksArtifacts; },\n },\n});\n"],"mappings":"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"}
|
|
@@ -153,8 +153,10 @@ function createArtifactSession({ host, context: root }, storage) {
|
|
|
153
153
|
scan: new AbortController(),
|
|
154
154
|
...fileAccess === void 0 ? {} : { closeAccess: fileAccess.register(root) }
|
|
155
155
|
};
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
const runtime = active;
|
|
157
|
+
refresh().finally(() => {
|
|
158
|
+
if (!closed && active === runtime) schedule();
|
|
159
|
+
});
|
|
158
160
|
return stop;
|
|
159
161
|
}
|
|
160
162
|
}],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs","names":["artifactRoot","ensureArtifactRoot","ArtifactAccessError","listArtifactSessions","Service","ARTIFACTS_SERVICE","defineRoot","ensureArtifactRoot","ArtifactAccessError","readPoFileAccess","listArtifacts","setTimeout","ARTIFACT_REFRESH_MS","artifactRoot","defineRoot","listArtifacts","artifactRoot","defineChannel","Hono","ArtifactAccessError","listArtifacts","openArtifact","readArtifactBytes","MAX_PREVIEW_BYTES","path","MAX_CONTENT_BYTES","artifactRoot","defineRoute","defineHook","defineHook","defineServerPlugin","composeServerProviderOverrides","rootGlobal","rootSession","composeRootInjects","composeRootHooks","channelArtifacts","apiRoute","hookBeforeAgentStart","hookToolExecutionEnd"],"sources":["../../src/services/artifacts/index.ts","../../src/extensions/(backend)/root.server.ts","../../src/types/artifacts.ts","../../src/services/artifactSession/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/artifactChannel/index.ts","../../src/extensions/(backend)/channel/artifacts.server.ts","../../src/types/apiRoutes.ts","../../src/services/artifactsApi/index.ts","../../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../generated/server.ts"],"sourcesContent":["import { type Context, Service } from '@deepseek-ai/cordis';\n\nimport { ARTIFACTS_SERVICE } from '../../constants/artifacts';\nimport type { ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifactSessions } from '../artifactFiles';\nimport type { ArtifactStorage } from './type';\n\n/** Roots come only from admitted host configuration, never a file request. */\nexport function createArtifactStorage(environment: Readonly<Record<string, string | undefined>>): ArtifactStorage {\n const policies = new Map<symbol, ArtifactWorkflowVisibility>();\n return {\n async rootForSession(sessionId, admittedEnvironment = environment) {\n const root = artifactRoot(sessionId, admittedEnvironment);\n try {\n await ensureArtifactRoot(root);\n return root;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return undefined;\n throw error;\n }\n },\n sessions: (admittedEnvironment = environment) => listArtifactSessions(admittedEnvironment),\n registerWorkflowVisibility(policy) {\n const owner = Symbol('workflow visibility');\n policies.set(owner, policy);\n return () => {\n policies.delete(owner);\n };\n },\n workflowVisible: (relativePath, kind) =>\n policies.size > 0 && [...policies.values()].every((policy) => policy(relativePath, kind)),\n };\n}\n\n/** Publish the same storage instance used by this scope's artifact reader. */\nexport class ArtifactsService extends Service implements ArtifactStorage {\n constructor(\n context: Context,\n private readonly storage: ArtifactStorage,\n ) {\n super(context, ARTIFACTS_SERVICE);\n }\n rootForSession(sessionId: string, environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.rootForSession(sessionId, environment);\n }\n sessions(environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.sessions(environment);\n }\n registerWorkflowVisibility(policy: ArtifactWorkflowVisibility) {\n return this.storage.registerWorkflowVisibility(policy);\n }\n workflowVisible(relativePath: string, kind: 'file' | 'directory') {\n return this.storage.workflowVisible(relativePath, kind);\n }\n}\n\nexport function createArtifactsPlugin(storage: ArtifactStorage): (context: Context) => void {\n return (context) => {\n new ArtifactsService(context, storage);\n };\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/artifacts': ArtifactsService;\n }\n}\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactStorage, createArtifactsPlugin } from '../../services/artifacts';\n\nexport default defineRoot(({ host }: PoServerPluginContext) => {\n const storage = createArtifactStorage(Object.freeze({ ...host.context.environment }));\n return { value: storage, services: [createArtifactsPlugin(storage)] };\n});\n","export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { clearTimeout, setTimeout } from 'node:timers';\n\nimport type { PoHeadlessActivity, PoHeadlessExecutionContext, PoHeadlessHook } from '@agimon-ai/po-core/headless';\nimport { readPoFileAccess } from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { ARTIFACT_REFRESH_MS } from '../../constants/artifacts';\nimport { artifactsChannelType } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifacts } from '../artifactFiles';\nimport { createArtifactStorage } from '../artifacts';\nimport type { ArtifactStorage } from '../artifacts/type';\n\n/**\n * Creates the session artifact folder. Resolves false when the host has no artifact folder\n * (the edge build in M1 rejects with a 404); Node never rejects with that status here.\n */\nasync function prepareArtifactRoot(root: string): Promise<boolean> {\n try {\n await ensureArtifactRoot(root);\n return true;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return false;\n throw error;\n }\n}\n\nexport function createArtifactSession({ host, context: root }: PoServerPluginContext, storage?: ArtifactStorage) {\n const environment = Object.freeze({ ...host.context.environment });\n const artifactStorage = storage ?? createArtifactStorage(environment);\n // So a paired client can open what the agent saved here, as it can the session's own folder.\n const fileAccess = readPoFileAccess(root);\n let active:\n | {\n context: PoHeadlessExecutionContext;\n root: string;\n scan: AbortController;\n pending?: Promise<void>;\n fingerprint?: string;\n closeAccess?: () => void;\n }\n | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n const refresh = (): Promise<void> => {\n const runtime = active;\n if (!runtime || closed) return Promise.resolve();\n if (runtime.pending) return runtime.pending;\n const signal = runtime.scan.signal;\n runtime.pending = (async () => {\n const snapshot = {\n ...(await listArtifacts(runtime.root, artifactStorage.workflowVisible, signal)),\n ...(environment.PO_SESSION_TEMP_DIR ? { temporaryRoot: environment.PO_SESSION_TEMP_DIR } : {}),\n };\n if (closed || active !== runtime) return;\n // Temporary files share the channel's invalidation signal, but are fetched only while visible.\n const temporary = environment.PO_SESSION_TEMP_DIR\n ? await listArtifacts(environment.PO_SESSION_TEMP_DIR, undefined, signal)\n : undefined;\n if (closed || active !== runtime) return;\n const fingerprint = JSON.stringify([snapshot, temporary]);\n if (fingerprint === runtime.fingerprint) return;\n runtime.fingerprint = fingerprint;\n host.context.directEvents?.publish(artifactsChannelType, runtime.context.sessionId, snapshot);\n })()\n .catch((error: unknown) => {\n // Cancellation deliberately leaves the last snapshot alone.\n if (!signal.aborted)\n host.context.onNotice(`Artifact refresh failed: ${error instanceof Error ? error.message : String(error)}`);\n })\n .finally(() => {\n runtime.pending = undefined;\n });\n return runtime.pending;\n };\n const schedule = (): void => {\n const runtime = active;\n if (!runtime || closed) return;\n timer = setTimeout(() => {\n timer = undefined;\n void refresh().finally(() => {\n if (active === runtime) schedule();\n });\n }, ARTIFACT_REFRESH_MS);\n };\n const stop = (): void => {\n active?.closeAccess?.();\n // Scans only read. Cancel them, but never hold session teardown on filesystem I/O.\n active?.scan.abort();\n active = undefined;\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n };\n const activity: PoHeadlessActivity = {\n name: 'artifacts',\n async start(context) {\n if (closed) throw new Error('Artifact session is closed.');\n stop();\n const root = artifactRoot(context.sessionId, environment);\n if (!(await prepareArtifactRoot(root))) return stop;\n if (closed) throw new Error('Artifact session is closed.');\n active = {\n context,\n root,\n scan: new AbortController(),\n ...(fileAccess === undefined ? {} : { closeAccess: fileAccess.register(root) }),\n };\n await refresh();\n schedule();\n return stop;\n },\n };\n const beforeAgentStart: PoHeadlessHook = {\n event: 'before_agent_start',\n async handle(event, context) {\n const root = artifactRoot(context.sessionId, environment);\n const systemPrompt = typeof event.systemPrompt === 'string' ? event.systemPrompt : '';\n if (!(await prepareArtifactRoot(root))) return { systemPrompt };\n const declaration = `Session artifact folder: ${root}`;\n if (systemPrompt.includes(declaration)) return { systemPrompt };\n return {\n systemPrompt:\n `${systemPrompt}\\n\\n${declaration}\\nSave user-designated artifacts and important deliverable documents in this folder, using descriptive filenames. Keep ordinary repository source edits in their existing locations. Do not move existing documents or overwrite artifacts without the user's intent. This folder belongs only to the current session. When a message names \\`@artifact:<path>\\`, it means the file at <path> inside this folder.`.trim(),\n };\n },\n };\n const toolExecutionEnd: PoHeadlessHook = {\n event: 'tool_execution_end',\n handle(_event, context) {\n // Snapshot reads must not hold the runtime's event drain open during shutdown.\n if (active?.context.sessionId === context.sessionId) void refresh();\n },\n };\n return {\n activities: [activity],\n beforeAgentStart,\n toolExecutionEnd,\n onDispose: () => {\n closed = true;\n stop();\n return Promise.resolve();\n },\n };\n}\n","import type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactsPlugin } from '../../../../../services/artifacts';\nimport type { ArtifactStorage } from '../../../../../services/artifacts/type';\nimport { createArtifactSession } from '../../../../../services/artifactSession';\n\nexport const createArtifactServerRoot = (context: WithRoot<PoServerPluginContext, ArtifactStorage>) => {\n const storage = context.root;\n const runtime = createArtifactSession(context, storage);\n // An outer level that runs this package built the global root there, so its services never ran in this session.\n const services = context.hosted('global') ? [createArtifactsPlugin(storage)] : [];\n return { value: { ...runtime, storage }, services, activities: runtime.activities, onDispose: runtime.onDispose };\n};\nexport type ArtifactServerScope = ReturnType<typeof createArtifactServerRoot>['value'];\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createArtifactServerRoot);\n","import type { PoHubChannel } from '@agimon-ai/po-core/hubChannel';\n\nimport { artifactsChannelType, type ArtifactSnapshot } from '../../types/artifacts';\nimport { artifactRoot, listArtifacts } from '../artifactFiles';\n\nfunction snapshotOf(value: unknown): value is ArtifactSnapshot {\n if (typeof value !== 'object' || value === null) return false;\n const snapshot = value as Partial<ArtifactSnapshot>;\n return (\n Array.isArray(snapshot.items) &&\n (snapshot.error === undefined || typeof snapshot.error === 'string') &&\n (snapshot.temporaryRoot === undefined || typeof snapshot.temporaryRoot === 'string') &&\n snapshot.items.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.path === 'string' &&\n typeof item.name === 'string' &&\n typeof item.size === 'number' &&\n Number.isFinite(item.size) &&\n typeof item.modifiedAt === 'number' &&\n Number.isFinite(item.modifiedAt),\n )\n );\n}\n\nexport function createArtifactsChannel(): PoHubChannel {\n return {\n frameType: artifactsChannelType,\n start(host) {\n const sessions = new Map<string, { snapshot?: ArtifactSnapshot; unsubscribe: () => void }>();\n return {\n payloadFor(scope) {\n return sessions.get(scope.sessionId)?.snapshot;\n },\n sessionAdded(scope) {\n sessions.get(scope.sessionId)?.unsubscribe();\n const state: { snapshot?: ArtifactSnapshot; unsubscribe: () => void } = { unsubscribe: () => undefined };\n sessions.set(scope.sessionId, state);\n state.unsubscribe = host.directEvents.subscribe(\n artifactsChannelType,\n scope.sessionId,\n (snapshot) => {\n if (!snapshotOf(snapshot) || sessions.get(scope.sessionId) !== state) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n },\n { replayLatest: true },\n );\n void (async () => {\n let snapshot: ArtifactSnapshot;\n try {\n snapshot = {\n ...(await listArtifacts(artifactRoot(scope.sessionId, scope.environment ?? {}))),\n ...(scope.environment?.PO_SESSION_TEMP_DIR\n ? { temporaryRoot: scope.environment.PO_SESSION_TEMP_DIR }\n : {}),\n };\n } catch (error) {\n snapshot = {\n items: [],\n error: error instanceof Error ? error.message : 'The artifact folder could not be read.',\n };\n }\n // A live session event wins over the earlier seed read.\n if (sessions.get(scope.sessionId) !== state || state.snapshot !== undefined) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n })();\n },\n sessionRemoved(sessionId) {\n sessions.get(sessionId)?.unsubscribe();\n sessions.delete(sessionId);\n },\n close() {\n for (const state of sessions.values()) state.unsubscribe();\n sessions.clear();\n },\n };\n },\n };\n}\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactsChannel } from '../../../services/artifactChannel';\n\nexport default defineChannel(createArtifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","import path from 'node:path';\n\nimport type { PoApi, PoApiContext } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { MAX_CONTENT_BYTES, MAX_PREVIEW_BYTES, MAX_RANGED_VIDEO_BYTES } from '../../constants/artifacts';\nimport routes from '../../types/apiRoutes';\nimport type { ArtifactPreview, ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, listArtifacts, openArtifact, readArtifactBytes } from '../artifactFiles';\nimport type { ArtifactStorage } from '../artifacts/type';\n\nexport function createArtifactsApi(\n root: string,\n options: { temporaryRoot?: string; workflowVisible?: ArtifactWorkflowVisibility } = {},\n): Hono {\n const app = new Hono();\n const selectedRoot = (scope: string | undefined): string => {\n if (scope === undefined || scope === 'artifacts') return root;\n if (scope !== 'temporary') throw new ArtifactAccessError('Invalid file scope.', 400);\n if (!options.temporaryRoot) throw new ArtifactAccessError('Temporary files are unavailable for this session.', 404);\n return options.temporaryRoot;\n };\n app.onError((error, context) =>\n context.json(\n { error: error instanceof ArtifactAccessError ? error.message : 'The artifact could not be read.' },\n error instanceof ArtifactAccessError ? error.status : 500,\n ),\n );\n app.get(routes.list.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const snapshot = await listArtifacts(selected, selected === root ? options.workflowVisible : () => true);\n return context.json(\n { ...snapshot, ...(options.temporaryRoot ? { temporaryRoot: options.temporaryRoot } : {}) },\n snapshot.error === undefined ? 200 : 500,\n );\n });\n app.get(routes.preview.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const preview: ArtifactPreview = { path: file.path, content: '', mimeType: file.mimeType };\n if (file.stat.size > MAX_PREVIEW_BYTES) {\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n }\n const bytes = await readArtifactBytes(file.handle, MAX_PREVIEW_BYTES + 1);\n if (bytes.byteLength > MAX_PREVIEW_BYTES)\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n if (bytes.subarray(0, 8192).includes(0))\n return context.json({ ...preview, unavailable: true, reason: 'This artifact is binary.' });\n return context.json({ ...preview, content: new TextDecoder().decode(bytes) });\n } finally {\n await file.handle.close();\n }\n });\n app.get(routes.content.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const range = context.req.header('range');\n // Videos past the download cap (computer-use recordings) are served only in bounded ranges.\n const ranged =\n file.stat.size > MAX_CONTENT_BYTES &&\n file.mimeType.startsWith('video/') &&\n file.stat.size <= MAX_RANGED_VIDEO_BYTES &&\n range !== undefined;\n if (file.stat.size > MAX_CONTENT_BYTES && !ranged)\n throw new ArtifactAccessError('This artifact is too large to download.', 413);\n const version = `\"${file.stat.dev}-${file.stat.ino}-${file.stat.size}-${file.stat.mtimeMs}-${file.stat.ctimeMs}\"`;\n const name = encodeURIComponent(path.basename(file.path)).replace(\n /[!'()*]/gu,\n (value) => `%${value.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n const headers = new Headers({\n 'content-type': file.mimeType,\n 'content-disposition': `attachment; filename*=UTF-8''${name}`,\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"default-src 'none'; sandbox\",\n 'accept-ranges': 'bytes',\n etag: version,\n });\n const expectedVersion = context.req.header('if-match');\n if (expectedVersion !== undefined && expectedVersion !== version)\n return new Response(null, { status: 412, headers });\n let start = 0;\n let end = file.stat.size - 1;\n if (range !== undefined) {\n const match = /^bytes=(\\d*)-(\\d*)$/u.exec(range);\n if (\n !match ||\n (!match[1] && !match[2]) ||\n file.stat.size === 0 ||\n [match[1], match[2]].some((value) => value !== '' && !Number.isSafeInteger(Number(value)))\n ) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (match[1] === '') {\n const suffix = Number(match[2]);\n start = suffix > 0 ? Math.max(0, file.stat.size - suffix) : file.stat.size;\n } else {\n start = Number(match[1]);\n end = match[2] === '' ? end : Math.min(end, Number(match[2]));\n }\n if (start > end || start >= file.stat.size) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (ranged) end = Math.min(end, start + MAX_CONTENT_BYTES - 1);\n headers.set('content-range', `bytes ${start}-${end}/${file.stat.size}`);\n }\n const bytes = await readArtifactBytes(file.handle, Math.max(0, end - start + 1), start);\n const after = await file.handle.stat();\n if (after.size !== file.stat.size || after.mtimeMs !== file.stat.mtimeMs || after.ctimeMs !== file.stat.ctimeMs)\n return new Response(null, { status: 412, headers });\n headers.set('content-length', String(bytes.byteLength));\n return new Response(bytes, { status: range === undefined ? 200 : 206, headers });\n } finally {\n await file.handle.close();\n }\n });\n return app;\n}\n\nexport function createArtifactApi(storage?: ArtifactStorage): PoApi {\n return {\n basePath: 'artifacts',\n start(context: PoApiContext) {\n if (!context.sessionId) throw new Error('Artifacts requires a session identity.');\n const app = createArtifactsApi(artifactRoot(context.sessionId, context.environment ?? {}), {\n temporaryRoot: context.environment?.PO_SESSION_TEMP_DIR,\n workflowVisible: storage?.workflowVisible,\n });\n return { fetch: (request) => app.fetch(request), close: () => undefined };\n },\n };\n}\n\nexport const api: PoApi = createArtifactApi();\n","import { defineRoute, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactApi } from '../../../../../../services/artifactsApi';\nimport type { ArtifactServerScope } from '../../_lib/serverRoot';\n\nexport default defineRoute(({ root }: WithRoot<PoServerPluginContext, ArtifactServerScope>) =>\n createArtifactApi(root.storage),\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.beforeAgentStart,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.toolExecutionEnd,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport channelArtifacts from '../src/extensions/(backend)/channel/artifacts.server';\nimport apiRoute from '../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-artifact',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return [() => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n const contextSession = { ...contextGlobal, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextSession)]; },\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n get hooks(): PoServerSessionPlugin['hooks'] { return [via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]; },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;AAQA,SAAgB,sBAAsB,aAA4E;CAChH,MAAM,2BAAW,IAAI,IAAwC;CAC7D,OAAO;EACL,MAAM,eAAe,WAAW,sBAAsB,aAAa;GACjE,MAAM,OAAOA,sBAAAA,aAAa,WAAW,mBAAmB;GACxD,IAAI;IACF,MAAMC,sBAAAA,mBAAmB,IAAI;IAC7B,OAAO;GACT,SAAS,OAAO;IACd,IAAI,iBAAiBC,sBAAAA,uBAAuB,MAAM,WAAW,KAAK,OAAO,KAAA;IACzE,MAAM;GACR;EACF;EACA,WAAW,sBAAsB,gBAAgBC,sBAAAA,qBAAqB,mBAAmB;EACzF,2BAA2B,QAAQ;GACjC,MAAM,QAAQ,OAAO,qBAAqB;GAC1C,SAAS,IAAI,OAAO,MAAM;GAC1B,aAAa;IACX,SAAS,OAAO,KAAK;GACvB;EACF;EACA,kBAAkB,cAAc,SAC9B,SAAS,OAAO,KAAK,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,WAAW,OAAO,cAAc,IAAI,CAAC;CAC5F;AACF;;AAGA,IAAa,mBAAb,cAAsCC,oBAAAA,QAAmC;CAGpD;CAFnB,YACE,SACA,SACA;EACA,MAAM,SAASC,kBAAAA,iBAAiB;EAFf,KAAA,UAAA;CAGnB;CACA,eAAe,WAAmB,aAA4D;EAC5F,OAAO,KAAK,QAAQ,eAAe,WAAW,WAAW;CAC3D;CACA,SAAS,aAA4D;EACnE,OAAO,KAAK,QAAQ,SAAS,WAAW;CAC1C;CACA,2BAA2B,QAAoC;EAC7D,OAAO,KAAK,QAAQ,2BAA2B,MAAM;CACvD;CACA,gBAAgB,cAAsB,MAA4B;EAChE,OAAO,KAAK,QAAQ,gBAAgB,cAAc,IAAI;CACxD;AACF;AAEA,SAAgB,sBAAsB,SAAsD;CAC1F,QAAQ,YAAY;EAClB,IAAI,iBAAiB,SAAS,OAAO;CACvC;AACF;;;ACvDA,IAAA,yBAAA,GAAeC,iCAAAA,WAAAA,EAAY,EAAE,WAAkC;CAC7D,MAAM,UAAU,sBAAsB,OAAO,OAAO,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC,CAAC;CACpF,OAAO;EAAE,OAAO;EAAS,UAAU,CAAC,sBAAsB,OAAO,CAAC;CAAE;AACtE,CAAC;;;ACoBD,MAAa,uBAAuB;;;;;;;ACZpC,eAAe,oBAAoB,MAAgC;CACjE,IAAI;EACF,MAAMC,sBAAAA,mBAAmB,IAAI;EAC7B,OAAO;CACT,SAAS,OAAO;EACd,IAAI,iBAAiBC,sBAAAA,uBAAuB,MAAM,WAAW,KAAK,OAAO;EACzE,MAAM;CACR;AACF;AAEA,SAAgB,sBAAsB,EAAE,MAAM,SAAS,QAA+B,SAA2B;CAC/G,MAAM,cAAc,OAAO,OAAO,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC;CACjE,MAAM,kBAAkB,WAAW,sBAAsB,WAAW;CAEpE,MAAM,cAAA,GAAaC,4BAAAA,iBAAAA,CAAiB,IAAI;CACxC,IAAI;CAUJ,IAAI;CACJ,IAAI,SAAS;CACb,MAAM,gBAA+B;EACnC,MAAM,UAAU;EAChB,IAAI,CAAC,WAAW,QAAQ,OAAO,QAAQ,QAAQ;EAC/C,IAAI,QAAQ,SAAS,OAAO,QAAQ;EACpC,MAAM,SAAS,QAAQ,KAAK;EAC5B,QAAQ,WAAW,YAAY;GAC7B,MAAM,WAAW;IACf,GAAI,MAAMC,sBAAAA,cAAc,QAAQ,MAAM,gBAAgB,iBAAiB,MAAM;IAC7E,GAAI,YAAY,sBAAsB,EAAE,eAAe,YAAY,oBAAoB,IAAI,CAAC;GAC9F;GACA,IAAI,UAAU,WAAW,SAAS;GAElC,MAAM,YAAY,YAAY,sBAC1B,MAAMA,sBAAAA,cAAc,YAAY,qBAAqB,KAAA,GAAW,MAAM,IACtE,KAAA;GACJ,IAAI,UAAU,WAAW,SAAS;GAClC,MAAM,cAAc,KAAK,UAAU,CAAC,UAAU,SAAS,CAAC;GACxD,IAAI,gBAAgB,QAAQ,aAAa;GACzC,QAAQ,cAAc;GACtB,KAAK,QAAQ,cAAc,QAAQ,sBAAsB,QAAQ,QAAQ,WAAW,QAAQ;EAC9F,EAAA,CAAG,CAAC,CACD,OAAO,UAAmB;GAEzB,IAAI,CAAC,OAAO,SACV,KAAK,QAAQ,SAAS,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;EAC9G,CAAC,CAAC,CACD,cAAc;GACb,QAAQ,UAAU,KAAA;EACpB,CAAC;EACH,OAAO,QAAQ;CACjB;CACA,MAAM,iBAAuB;EAC3B,MAAM,UAAU;EAChB,IAAI,CAAC,WAAW,QAAQ;EACxB,SAAA,GAAQC,YAAAA,WAAAA,OAAiB;GACvB,QAAQ,KAAA;GACR,QAAa,CAAC,CAAC,cAAc;IAC3B,IAAI,WAAW,SAAS,SAAS;GACnC,CAAC;EACH,GAAGC,kBAAAA,mBAAmB;CACxB;CACA,MAAM,aAAmB;EACvB,QAAQ,cAAc;EAEtB,QAAQ,KAAK,MAAM;EACnB,SAAS,KAAA;EACT,IAAI,UAAU,KAAA,GAAW,CAAA,GAAA,YAAA,aAAA,CAAa,KAAK;EAC3C,QAAQ,KAAA;CACV;CAyCA,OAAO;EACL,YAAY,CAAC;GAxCb,MAAM;GACN,MAAM,MAAM,SAAS;IACnB,IAAI,QAAQ,MAAM,IAAI,MAAM,6BAA6B;IACzD,KAAK;IACL,MAAM,OAAOC,sBAAAA,aAAa,QAAQ,WAAW,WAAW;IACxD,IAAI,CAAE,MAAM,oBAAoB,IAAI,GAAI,OAAO;IAC/C,IAAI,QAAQ,MAAM,IAAI,MAAM,6BAA6B;IACzD,SAAS;KACP;KACA;KACA,MAAM,IAAI,gBAAgB;KAC1B,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,WAAW,SAAS,IAAI,EAAE;IAC/E;IACA,MAAM,QAAQ;IACd,SAAS;IACT,OAAO;GACT;EAwBoB,CAAC;EACrB,kBAAA;GAtBA,OAAO;GACP,MAAM,OAAO,OAAO,SAAS;IAC3B,MAAM,OAAOA,sBAAAA,aAAa,QAAQ,WAAW,WAAW;IACxD,MAAM,eAAe,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe;IACnF,IAAI,CAAE,MAAM,oBAAoB,IAAI,GAAI,OAAO,EAAE,aAAa;IAC9D,MAAM,cAAc,4BAA4B;IAChD,IAAI,aAAa,SAAS,WAAW,GAAG,OAAO,EAAE,aAAa;IAC9D,OAAO,EACL,cACE,GAAG,aAAa,MAAM,YAAY,mZAAmZ,KAAK,EAC9b;GACF;EAWe;EACf,kBAAA;GATA,OAAO;GACP,OAAO,QAAQ,SAAS;IAEtB,IAAI,QAAQ,QAAQ,cAAc,QAAQ,WAAW,QAAa;GACpE;EAKe;EACf,iBAAiB;GACf,SAAS;GACT,KAAK;GACL,OAAO,QAAQ,QAAQ;EACzB;CACF;AACF;;;ACvIA,MAAa,4BAA4B,YAA8D;CACrG,MAAM,UAAU,QAAQ;CACxB,MAAM,UAAU,sBAAsB,SAAS,OAAO;CAEtD,MAAM,WAAW,QAAQ,OAAO,QAAQ,IAAI,CAAC,sBAAsB,OAAO,CAAC,IAAI,CAAC;CAChF,OAAO;EAAE,OAAO;GAAE,GAAG;GAAS;EAAQ;EAAG;EAAU,YAAY,QAAQ;EAAY,WAAW,QAAQ;CAAU;AAClH;;;ACTA,IAAA,uBAAA,GAAeC,iCAAAA,WAAAA,CAAW,wBAAwB;;;ACClD,SAAS,WAAW,OAA2C;CAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,WAAW;CACjB,OACE,MAAM,QAAQ,SAAS,KAAK,MAC3B,SAAS,UAAU,KAAA,KAAa,OAAO,SAAS,UAAU,cAC1D,SAAS,kBAAkB,KAAA,KAAa,OAAO,SAAS,kBAAkB,aAC3E,SAAS,MAAM,OACZ,SACC,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,KAAK,SAAS,YACrB,OAAO,KAAK,SAAS,YACrB,OAAO,KAAK,SAAS,YACrB,OAAO,SAAS,KAAK,IAAI,KACzB,OAAO,KAAK,eAAe,YAC3B,OAAO,SAAS,KAAK,UAAU,CACnC;AAEJ;AAEA,SAAgB,yBAAuC;CACrD,OAAO;EACL,WAAW;EACX,MAAM,MAAM;GACV,MAAM,2BAAW,IAAI,IAAsE;GAC3F,OAAO;IACL,WAAW,OAAO;KAChB,OAAO,SAAS,IAAI,MAAM,SAAS,CAAC,EAAE;IACxC;IACA,aAAa,OAAO;KAClB,SAAS,IAAI,MAAM,SAAS,CAAC,EAAE,YAAY;KAC3C,MAAM,QAAkE,EAAE,mBAAmB,KAAA,EAAU;KACvG,SAAS,IAAI,MAAM,WAAW,KAAK;KACnC,MAAM,cAAc,KAAK,aAAa,UACpC,sBACA,MAAM,YACL,aAAa;MACZ,IAAI,CAAC,WAAW,QAAQ,KAAK,SAAS,IAAI,MAAM,SAAS,MAAM,OAAO;MACtE,MAAM,WAAW;MACjB,KAAK,QAAQ,MAAM,WAAW,QAAQ;KACxC,GACA,EAAE,cAAc,KAAK,CACvB;KACA,CAAM,YAAY;MAChB,IAAI;MACJ,IAAI;OACF,WAAW;QACT,GAAI,MAAMC,sBAAAA,cAAcC,sBAAAA,aAAa,MAAM,WAAW,MAAM,eAAe,CAAC,CAAC,CAAC;QAC9E,GAAI,MAAM,aAAa,sBACnB,EAAE,eAAe,MAAM,YAAY,oBAAoB,IACvD,CAAC;OACP;MACF,SAAS,OAAO;OACd,WAAW;QACT,OAAO,CAAC;QACR,OAAO,iBAAiB,QAAQ,MAAM,UAAU;OAClD;MACF;MAEA,IAAI,SAAS,IAAI,MAAM,SAAS,MAAM,SAAS,MAAM,aAAa,KAAA,GAAW;MAC7E,MAAM,WAAW;MACjB,KAAK,QAAQ,MAAM,WAAW,QAAQ;KACxC,EAAA,CAAG;IACL;IACA,eAAe,WAAW;KACxB,SAAS,IAAI,SAAS,CAAC,EAAE,YAAY;KACrC,SAAS,OAAO,SAAS;IAC3B;IACA,QAAQ;KACN,KAAK,MAAM,SAAS,SAAS,OAAO,GAAG,MAAM,YAAY;KACzD,SAAS,MAAM;IACjB;GACF;EACF;CACF;AACF;;;AC7EA,IAAA,4BAAA,GAAeC,iCAAAA,cAAAA,CAAc,sBAAsB;;;ACAnD,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,OAAO;EACf,UAAU,KAAA;CACZ;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,QAAQ,OAAO;EACvB,UAAU,KAAA;CACZ;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,QAAQ,OAAO;EACvB,KAAK;CACP;AACF;;;ACZA,SAAgB,mBACd,MACA,UAAoF,CAAC,GAC/E;CACN,MAAM,MAAM,IAAIC,KAAAA,KAAK;CACrB,MAAM,gBAAgB,UAAsC;EAC1D,IAAI,UAAU,KAAA,KAAa,UAAU,aAAa,OAAO;EACzD,IAAI,UAAU,aAAa,MAAM,IAAIC,sBAAAA,oBAAoB,uBAAuB,GAAG;EACnF,IAAI,CAAC,QAAQ,eAAe,MAAM,IAAIA,sBAAAA,oBAAoB,qDAAqD,GAAG;EAClH,OAAO,QAAQ;CACjB;CACA,IAAI,SAAS,OAAO,YAClB,QAAQ,KACN,EAAE,OAAO,iBAAiBA,sBAAAA,sBAAsB,MAAM,UAAU,kCAAkC,GAClG,iBAAiBA,sBAAAA,sBAAsB,MAAM,SAAS,GACxD,CACF;CACA,IAAI,IAAI,OAAO,KAAK,MAAM,OAAO,YAAY;EAC3C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,WAAW,MAAMC,sBAAAA,cAAc,UAAU,aAAa,OAAO,QAAQ,wBAAwB,IAAI;EACvG,OAAO,QAAQ,KACb;GAAE,GAAG;GAAU,GAAI,QAAQ,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;EAAG,GAC1F,SAAS,UAAU,KAAA,IAAY,MAAM,GACvC;CACF,CAAC;CACD,IAAI,IAAI,OAAO,QAAQ,MAAM,OAAO,YAAY;EAC9C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,OAAO,MAAMC,sBAAAA,aACjB,UACA,QAAQ,IAAI,MAAM,MAAM,GACxB,aAAa,OAAO,QAAQ,wBAAwB,IACtD;EACA,IAAI;GACF,MAAM,UAA2B;IAAE,MAAM,KAAK;IAAM,SAAS;IAAI,UAAU,KAAK;GAAS;GACzF,IAAI,KAAK,KAAK,OAAA,SACZ,OAAO,QAAQ,KAAK;IAClB,GAAG;IACH,aAAa;IACb,QAAQ;GACV,CAAC;GAEH,MAAM,QAAQ,MAAMC,sBAAAA,kBAAkB,KAAK,QAAQC,kBAAAA,oBAAoB,CAAC;GACxE,IAAI,MAAM,aAAA,SACR,OAAO,QAAQ,KAAK;IAClB,GAAG;IACH,aAAa;IACb,QAAQ;GACV,CAAC;GACH,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC,GACpC,OAAO,QAAQ,KAAK;IAAE,GAAG;IAAS,aAAa;IAAM,QAAQ;GAA2B,CAAC;GAC3F,OAAO,QAAQ,KAAK;IAAE,GAAG;IAAS,SAAS,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;GAAE,CAAC;EAC9E,UAAU;GACR,MAAM,KAAK,OAAO,MAAM;EAC1B;CACF,CAAC;CACD,IAAI,IAAI,OAAO,QAAQ,MAAM,OAAO,YAAY;EAC9C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,OAAO,MAAMF,sBAAAA,aACjB,UACA,QAAQ,IAAI,MAAM,MAAM,GACxB,aAAa,OAAO,QAAQ,wBAAwB,IACtD;EACA,IAAI;GACF,MAAM,QAAQ,QAAQ,IAAI,OAAO,OAAO;GAExC,MAAM,SACJ,KAAK,KAAK,OAAA,YACV,KAAK,SAAS,WAAW,QAAQ,KACjC,KAAK,KAAK,QAAA,aACV,UAAU,KAAA;GACZ,IAAI,KAAK,KAAK,OAAA,YAA4B,CAAC,QACzC,MAAM,IAAIF,sBAAAA,oBAAoB,2CAA2C,GAAG;GAC9E,MAAM,UAAU,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK,QAAQ;GAC/G,MAAM,OAAO,mBAAmBK,UAAAA,QAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,QACxD,cACC,UAAU,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,GAC9D;GACA,MAAM,UAAU,IAAI,QAAQ;IAC1B,gBAAgB,KAAK;IACrB,uBAAuB,gCAAgC;IACvD,iBAAiB;IACjB,0BAA0B;IAC1B,2BAA2B;IAC3B,iBAAiB;IACjB,MAAM;GACR,CAAC;GACD,MAAM,kBAAkB,QAAQ,IAAI,OAAO,UAAU;GACrD,IAAI,oBAAoB,KAAA,KAAa,oBAAoB,SACvD,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK;GAAQ,CAAC;GACpD,IAAI,QAAQ;GACZ,IAAI,MAAM,KAAK,KAAK,OAAO;GAC3B,IAAI,UAAU,KAAA,GAAW;IACvB,MAAM,QAAQ,uBAAuB,KAAK,KAAK;IAC/C,IACE,CAAC,SACA,CAAC,MAAM,MAAM,CAAC,MAAM,MACrB,KAAK,KAAK,SAAS,KACnB,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,MAAM,UAAU,UAAU,MAAM,CAAC,OAAO,cAAc,OAAO,KAAK,CAAC,CAAC,GACzF;KACA,QAAQ,IAAI,iBAAiB,WAAW,KAAK,KAAK,MAAM;KACxD,OAAO,IAAI,SAAS,MAAM;MAAE,QAAQ;MAAK;KAAQ,CAAC;IACpD;IACA,IAAI,MAAM,OAAO,IAAI;KACnB,MAAM,SAAS,OAAO,MAAM,EAAE;KAC9B,QAAQ,SAAS,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,MAAM,IAAI,KAAK,KAAK;IACxE,OAAO;KACL,QAAQ,OAAO,MAAM,EAAE;KACvB,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,KAAK,OAAO,MAAM,EAAE,CAAC;IAC9D;IACA,IAAI,QAAQ,OAAO,SAAS,KAAK,KAAK,MAAM;KAC1C,QAAQ,IAAI,iBAAiB,WAAW,KAAK,KAAK,MAAM;KACxD,OAAO,IAAI,SAAS,MAAM;MAAE,QAAQ;MAAK;KAAQ,CAAC;IACpD;IACA,IAAI,QAAQ,MAAM,KAAK,IAAI,KAAK,QAAQC,kBAAAA,oBAAoB,CAAC;IAC7D,QAAQ,IAAI,iBAAiB,SAAS,MAAM,GAAG,IAAI,GAAG,KAAK,KAAK,MAAM;GACxE;GACA,MAAM,QAAQ,MAAMH,sBAAAA,kBAAkB,KAAK,QAAQ,KAAK,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,KAAK;GACtF,MAAM,QAAQ,MAAM,KAAK,OAAO,KAAK;GACrC,IAAI,MAAM,SAAS,KAAK,KAAK,QAAQ,MAAM,YAAY,KAAK,KAAK,WAAW,MAAM,YAAY,KAAK,KAAK,SACtG,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK;GAAQ,CAAC;GACpD,QAAQ,IAAI,kBAAkB,OAAO,MAAM,UAAU,CAAC;GACtD,OAAO,IAAI,SAAS,OAAO;IAAE,QAAQ,UAAU,KAAA,IAAY,MAAM;IAAK;GAAQ,CAAC;EACjF,UAAU;GACR,MAAM,KAAK,OAAO,MAAM;EAC1B;CACF,CAAC;CACD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAkC;CAClE,OAAO;EACL,UAAU;EACV,MAAM,SAAuB;GAC3B,IAAI,CAAC,QAAQ,WAAW,MAAM,IAAI,MAAM,wCAAwC;GAChF,MAAM,MAAM,mBAAmBI,sBAAAA,aAAa,QAAQ,WAAW,QAAQ,eAAe,CAAC,CAAC,GAAG;IACzF,eAAe,QAAQ,aAAa;IACpC,iBAAiB,SAAS;GAC5B,CAAC;GACD,OAAO;IAAE,QAAQ,YAAY,IAAI,MAAM,OAAO;IAAG,aAAa,KAAA;GAAU;EAC1E;CACF;AACF;;;AClJA,IAAA,wBAAA,GAAeC,iCAAAA,YAAAA,EAAa,EAAE,WAC5B,kBAAkB,KAAK,OAAO,CAChC;;;ACHA,IAAA,qCAAA,GAAeC,iCAAAA,WAAAA,EACZ,YAAkE,QAAQ,KAAK,gBAClF;;;ACFA,IAAA,qCAAA,GAAeC,iCAAAA,WAAAA,EACZ,YAAkE,QAAQ,KAAK,gBAClF;;;ACMA,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;;AAEpE,MAAM,WAAc,WAClB,OAAO,QAAQ,UAAsB,UAAU,KAAA,CAAS;AAC1D,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,gBAAA,GAAeC,gCAAAA,mBAAAA,CAAmB;CAC7C,MAAM;CACN,oBAAA,GAAmBC,gCAAAA,+BAAAA,CAA+BC,uBAAYC,mBAAW;CACzE,UAAA,GAASC,iCAAAA,mBAAAA,CAAmB;EAAE,QAAQ,CAACF,qBAAU;EAAG,WAAW,CAACA,qBAAU;EAAG,SAAS,CAACA,uBAAYC,mBAAW;CAAE,CAAC;CACjH,QAAQ,OAAO,YAAY;EACzB,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUD,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,OAAO;GACL,IAAA,GAAGG,iCAAAA,iBAAAA,CAAiB,WAAW;GAC/B,IAAI,WAA8C;IAAE,OAAO,OAAO,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGC,0BAAkB,aAAa,CAAC,CAAC;GAAG;GACzI,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,CAAE;EAC5C;CACF;CACA,WAAW,OAAO,YAAY;EAC5B,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUJ,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,OAAO;GACL,IAAA,GAAGG,iCAAAA,iBAAAA,CAAiB,WAAW;GAC/B,IAAI,WAA8C;IAAE,OAAO,QAAQ,CAAC,QAAQ,OAAO,QAAQ,IAAI,KAAA,UAAkB,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGC,0BAAkB,aAAa,CAAC,CAAC,CAAC;GAAG;GACzL,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,CAAE;EAC5C;CACF;CACA,SAAS,OAAO,YAAY;EAC1B,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUJ,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,MAAM,eAAe,MAAM,QAAQ,UAAU,WAAWC,qBAAa,aAAa;EAClF,MAAM,iBAAiB;GAAE,GAAG;GAAe,MAAM,aAAa;EAAM;EACpE,OAAO;GACL,IAAA,GAAGE,iCAAAA,iBAAAA,CAAiB,aAAa,YAAY;GAC7C,IAAI,MAAoC;IAAE,OAAO,CAAC,GAAGE,sBAAU,cAAc,CAAC;GAAG;GACjF,IAAI,WAA8C;IAAE,OAAO,QAAQ,CAAC,QAAQ,OAAO,QAAQ,IAAI,KAAA,UAAkB,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGD,0BAAkB,aAAa,CAAC,CAAC,CAAC;GAAG;GACzL,IAAI,QAAwC;IAAE,OAAO,CAAC,IAAI,EAAE,OAAO,qBAAqB,GAAG,GAAGE,mCAAsB,cAAc,CAAC,GAAG,IAAI,EAAE,OAAO,qBAAqB,GAAG,GAAGC,mCAAsB,cAAc,CAAC,CAAC;GAAG;GACvN,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,GAAI,GAAI,aAAa,YAAY,CAAC,CAAE;GAC5E,IAAI,aAAkD;IAAE,OAAO,CAAC,GAAI,YAAY,cAAc,CAAC,GAAI,GAAI,aAAa,cAAc,CAAC,CAAE;GAAG;EAC1I;CACF;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["artifactRoot","ensureArtifactRoot","ArtifactAccessError","listArtifactSessions","Service","ARTIFACTS_SERVICE","defineRoot","ensureArtifactRoot","ArtifactAccessError","readPoFileAccess","listArtifacts","setTimeout","ARTIFACT_REFRESH_MS","artifactRoot","defineRoot","listArtifacts","artifactRoot","defineChannel","Hono","ArtifactAccessError","listArtifacts","openArtifact","readArtifactBytes","MAX_PREVIEW_BYTES","path","MAX_CONTENT_BYTES","artifactRoot","defineRoute","defineHook","defineHook","defineServerPlugin","composeServerProviderOverrides","rootGlobal","rootSession","composeRootInjects","composeRootHooks","channelArtifacts","apiRoute","hookBeforeAgentStart","hookToolExecutionEnd"],"sources":["../../src/services/artifacts/index.ts","../../src/extensions/(backend)/root.server.ts","../../src/types/artifacts.ts","../../src/services/artifactSession/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/artifactChannel/index.ts","../../src/extensions/(backend)/channel/artifacts.server.ts","../../src/types/apiRoutes.ts","../../src/services/artifactsApi/index.ts","../../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../generated/server.ts"],"sourcesContent":["import { type Context, Service } from '@deepseek-ai/cordis';\n\nimport { ARTIFACTS_SERVICE } from '../../constants/artifacts';\nimport type { ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifactSessions } from '../artifactFiles';\nimport type { ArtifactStorage } from './type';\n\n/** Roots come only from admitted host configuration, never a file request. */\nexport function createArtifactStorage(environment: Readonly<Record<string, string | undefined>>): ArtifactStorage {\n const policies = new Map<symbol, ArtifactWorkflowVisibility>();\n return {\n async rootForSession(sessionId, admittedEnvironment = environment) {\n const root = artifactRoot(sessionId, admittedEnvironment);\n try {\n await ensureArtifactRoot(root);\n return root;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return undefined;\n throw error;\n }\n },\n sessions: (admittedEnvironment = environment) => listArtifactSessions(admittedEnvironment),\n registerWorkflowVisibility(policy) {\n const owner = Symbol('workflow visibility');\n policies.set(owner, policy);\n return () => {\n policies.delete(owner);\n };\n },\n workflowVisible: (relativePath, kind) =>\n policies.size > 0 && [...policies.values()].every((policy) => policy(relativePath, kind)),\n };\n}\n\n/** Publish the same storage instance used by this scope's artifact reader. */\nexport class ArtifactsService extends Service implements ArtifactStorage {\n constructor(\n context: Context,\n private readonly storage: ArtifactStorage,\n ) {\n super(context, ARTIFACTS_SERVICE);\n }\n rootForSession(sessionId: string, environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.rootForSession(sessionId, environment);\n }\n sessions(environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.sessions(environment);\n }\n registerWorkflowVisibility(policy: ArtifactWorkflowVisibility) {\n return this.storage.registerWorkflowVisibility(policy);\n }\n workflowVisible(relativePath: string, kind: 'file' | 'directory') {\n return this.storage.workflowVisible(relativePath, kind);\n }\n}\n\nexport function createArtifactsPlugin(storage: ArtifactStorage): (context: Context) => void {\n return (context) => {\n new ArtifactsService(context, storage);\n };\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/artifacts': ArtifactsService;\n }\n}\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactStorage, createArtifactsPlugin } from '../../services/artifacts';\n\nexport default defineRoot(({ host }: PoServerPluginContext) => {\n const storage = createArtifactStorage(Object.freeze({ ...host.context.environment }));\n return { value: storage, services: [createArtifactsPlugin(storage)] };\n});\n","export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { clearTimeout, setTimeout } from 'node:timers';\n\nimport type { PoHeadlessActivity, PoHeadlessExecutionContext, PoHeadlessHook } from '@agimon-ai/po-core/headless';\nimport { readPoFileAccess } from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { ARTIFACT_REFRESH_MS } from '../../constants/artifacts';\nimport { artifactsChannelType } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifacts } from '../artifactFiles';\nimport { createArtifactStorage } from '../artifacts';\nimport type { ArtifactStorage } from '../artifacts/type';\n\n/**\n * Creates the session artifact folder. Resolves false when the host has no artifact folder\n * (the edge build in M1 rejects with a 404); Node never rejects with that status here.\n */\nasync function prepareArtifactRoot(root: string): Promise<boolean> {\n try {\n await ensureArtifactRoot(root);\n return true;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return false;\n throw error;\n }\n}\n\nexport function createArtifactSession({ host, context: root }: PoServerPluginContext, storage?: ArtifactStorage) {\n const environment = Object.freeze({ ...host.context.environment });\n const artifactStorage = storage ?? createArtifactStorage(environment);\n // So a paired client can open what the agent saved here, as it can the session's own folder.\n const fileAccess = readPoFileAccess(root);\n let active:\n | {\n context: PoHeadlessExecutionContext;\n root: string;\n scan: AbortController;\n pending?: Promise<void>;\n fingerprint?: string;\n closeAccess?: () => void;\n }\n | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n const refresh = (): Promise<void> => {\n const runtime = active;\n if (!runtime || closed) return Promise.resolve();\n if (runtime.pending) return runtime.pending;\n const signal = runtime.scan.signal;\n runtime.pending = (async () => {\n const snapshot = {\n ...(await listArtifacts(runtime.root, artifactStorage.workflowVisible, signal)),\n ...(environment.PO_SESSION_TEMP_DIR ? { temporaryRoot: environment.PO_SESSION_TEMP_DIR } : {}),\n };\n if (closed || active !== runtime) return;\n // Temporary files share the channel's invalidation signal, but are fetched only while visible.\n const temporary = environment.PO_SESSION_TEMP_DIR\n ? await listArtifacts(environment.PO_SESSION_TEMP_DIR, undefined, signal)\n : undefined;\n if (closed || active !== runtime) return;\n const fingerprint = JSON.stringify([snapshot, temporary]);\n if (fingerprint === runtime.fingerprint) return;\n runtime.fingerprint = fingerprint;\n host.context.directEvents?.publish(artifactsChannelType, runtime.context.sessionId, snapshot);\n })()\n .catch((error: unknown) => {\n // Cancellation deliberately leaves the last snapshot alone.\n if (!signal.aborted)\n host.context.onNotice(`Artifact refresh failed: ${error instanceof Error ? error.message : String(error)}`);\n })\n .finally(() => {\n runtime.pending = undefined;\n });\n return runtime.pending;\n };\n const schedule = (): void => {\n const runtime = active;\n if (!runtime || closed) return;\n timer = setTimeout(() => {\n timer = undefined;\n void refresh().finally(() => {\n if (active === runtime) schedule();\n });\n }, ARTIFACT_REFRESH_MS);\n };\n const stop = (): void => {\n active?.closeAccess?.();\n // Scans only read. Cancel them, but never hold session teardown on filesystem I/O.\n active?.scan.abort();\n active = undefined;\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n };\n const activity: PoHeadlessActivity = {\n name: 'artifacts',\n async start(context) {\n if (closed) throw new Error('Artifact session is closed.');\n stop();\n const root = artifactRoot(context.sessionId, environment);\n if (!(await prepareArtifactRoot(root))) return stop;\n if (closed) throw new Error('Artifact session is closed.');\n active = {\n context,\n root,\n scan: new AbortController(),\n ...(fileAccess === undefined ? {} : { closeAccess: fileAccess.register(root) }),\n };\n const runtime = active;\n // Listing files is advisory; opening a session only needs its folder and access ready.\n void refresh().finally(() => {\n if (!closed && active === runtime) schedule();\n });\n return stop;\n },\n };\n const beforeAgentStart: PoHeadlessHook = {\n event: 'before_agent_start',\n async handle(event, context) {\n const root = artifactRoot(context.sessionId, environment);\n const systemPrompt = typeof event.systemPrompt === 'string' ? event.systemPrompt : '';\n if (!(await prepareArtifactRoot(root))) return { systemPrompt };\n const declaration = `Session artifact folder: ${root}`;\n if (systemPrompt.includes(declaration)) return { systemPrompt };\n return {\n systemPrompt:\n `${systemPrompt}\\n\\n${declaration}\\nSave user-designated artifacts and important deliverable documents in this folder, using descriptive filenames. Keep ordinary repository source edits in their existing locations. Do not move existing documents or overwrite artifacts without the user's intent. This folder belongs only to the current session. When a message names \\`@artifact:<path>\\`, it means the file at <path> inside this folder.`.trim(),\n };\n },\n };\n const toolExecutionEnd: PoHeadlessHook = {\n event: 'tool_execution_end',\n handle(_event, context) {\n // Snapshot reads must not hold the runtime's event drain open during shutdown.\n if (active?.context.sessionId === context.sessionId) void refresh();\n },\n };\n return {\n activities: [activity],\n beforeAgentStart,\n toolExecutionEnd,\n onDispose: () => {\n closed = true;\n stop();\n return Promise.resolve();\n },\n };\n}\n","import type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactsPlugin } from '../../../../../services/artifacts';\nimport type { ArtifactStorage } from '../../../../../services/artifacts/type';\nimport { createArtifactSession } from '../../../../../services/artifactSession';\n\nexport const createArtifactServerRoot = (context: WithRoot<PoServerPluginContext, ArtifactStorage>) => {\n const storage = context.root;\n const runtime = createArtifactSession(context, storage);\n // An outer level that runs this package built the global root there, so its services never ran in this session.\n const services = context.hosted('global') ? [createArtifactsPlugin(storage)] : [];\n return { value: { ...runtime, storage }, services, activities: runtime.activities, onDispose: runtime.onDispose };\n};\nexport type ArtifactServerScope = ReturnType<typeof createArtifactServerRoot>['value'];\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createArtifactServerRoot);\n","import type { PoHubChannel } from '@agimon-ai/po-core/hubChannel';\n\nimport { artifactsChannelType, type ArtifactSnapshot } from '../../types/artifacts';\nimport { artifactRoot, listArtifacts } from '../artifactFiles';\n\nfunction snapshotOf(value: unknown): value is ArtifactSnapshot {\n if (typeof value !== 'object' || value === null) return false;\n const snapshot = value as Partial<ArtifactSnapshot>;\n return (\n Array.isArray(snapshot.items) &&\n (snapshot.error === undefined || typeof snapshot.error === 'string') &&\n (snapshot.temporaryRoot === undefined || typeof snapshot.temporaryRoot === 'string') &&\n snapshot.items.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.path === 'string' &&\n typeof item.name === 'string' &&\n typeof item.size === 'number' &&\n Number.isFinite(item.size) &&\n typeof item.modifiedAt === 'number' &&\n Number.isFinite(item.modifiedAt),\n )\n );\n}\n\nexport function createArtifactsChannel(): PoHubChannel {\n return {\n frameType: artifactsChannelType,\n start(host) {\n const sessions = new Map<string, { snapshot?: ArtifactSnapshot; unsubscribe: () => void }>();\n return {\n payloadFor(scope) {\n return sessions.get(scope.sessionId)?.snapshot;\n },\n sessionAdded(scope) {\n sessions.get(scope.sessionId)?.unsubscribe();\n const state: { snapshot?: ArtifactSnapshot; unsubscribe: () => void } = { unsubscribe: () => undefined };\n sessions.set(scope.sessionId, state);\n state.unsubscribe = host.directEvents.subscribe(\n artifactsChannelType,\n scope.sessionId,\n (snapshot) => {\n if (!snapshotOf(snapshot) || sessions.get(scope.sessionId) !== state) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n },\n { replayLatest: true },\n );\n void (async () => {\n let snapshot: ArtifactSnapshot;\n try {\n snapshot = {\n ...(await listArtifacts(artifactRoot(scope.sessionId, scope.environment ?? {}))),\n ...(scope.environment?.PO_SESSION_TEMP_DIR\n ? { temporaryRoot: scope.environment.PO_SESSION_TEMP_DIR }\n : {}),\n };\n } catch (error) {\n snapshot = {\n items: [],\n error: error instanceof Error ? error.message : 'The artifact folder could not be read.',\n };\n }\n // A live session event wins over the earlier seed read.\n if (sessions.get(scope.sessionId) !== state || state.snapshot !== undefined) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n })();\n },\n sessionRemoved(sessionId) {\n sessions.get(sessionId)?.unsubscribe();\n sessions.delete(sessionId);\n },\n close() {\n for (const state of sessions.values()) state.unsubscribe();\n sessions.clear();\n },\n };\n },\n };\n}\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactsChannel } from '../../../services/artifactChannel';\n\nexport default defineChannel(createArtifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","import path from 'node:path';\n\nimport type { PoApi, PoApiContext } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { MAX_CONTENT_BYTES, MAX_PREVIEW_BYTES, MAX_RANGED_VIDEO_BYTES } from '../../constants/artifacts';\nimport routes from '../../types/apiRoutes';\nimport type { ArtifactPreview, ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, listArtifacts, openArtifact, readArtifactBytes } from '../artifactFiles';\nimport type { ArtifactStorage } from '../artifacts/type';\n\nexport function createArtifactsApi(\n root: string,\n options: { temporaryRoot?: string; workflowVisible?: ArtifactWorkflowVisibility } = {},\n): Hono {\n const app = new Hono();\n const selectedRoot = (scope: string | undefined): string => {\n if (scope === undefined || scope === 'artifacts') return root;\n if (scope !== 'temporary') throw new ArtifactAccessError('Invalid file scope.', 400);\n if (!options.temporaryRoot) throw new ArtifactAccessError('Temporary files are unavailable for this session.', 404);\n return options.temporaryRoot;\n };\n app.onError((error, context) =>\n context.json(\n { error: error instanceof ArtifactAccessError ? error.message : 'The artifact could not be read.' },\n error instanceof ArtifactAccessError ? error.status : 500,\n ),\n );\n app.get(routes.list.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const snapshot = await listArtifacts(selected, selected === root ? options.workflowVisible : () => true);\n return context.json(\n { ...snapshot, ...(options.temporaryRoot ? { temporaryRoot: options.temporaryRoot } : {}) },\n snapshot.error === undefined ? 200 : 500,\n );\n });\n app.get(routes.preview.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const preview: ArtifactPreview = { path: file.path, content: '', mimeType: file.mimeType };\n if (file.stat.size > MAX_PREVIEW_BYTES) {\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n }\n const bytes = await readArtifactBytes(file.handle, MAX_PREVIEW_BYTES + 1);\n if (bytes.byteLength > MAX_PREVIEW_BYTES)\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n if (bytes.subarray(0, 8192).includes(0))\n return context.json({ ...preview, unavailable: true, reason: 'This artifact is binary.' });\n return context.json({ ...preview, content: new TextDecoder().decode(bytes) });\n } finally {\n await file.handle.close();\n }\n });\n app.get(routes.content.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const range = context.req.header('range');\n // Videos past the download cap (computer-use recordings) are served only in bounded ranges.\n const ranged =\n file.stat.size > MAX_CONTENT_BYTES &&\n file.mimeType.startsWith('video/') &&\n file.stat.size <= MAX_RANGED_VIDEO_BYTES &&\n range !== undefined;\n if (file.stat.size > MAX_CONTENT_BYTES && !ranged)\n throw new ArtifactAccessError('This artifact is too large to download.', 413);\n const version = `\"${file.stat.dev}-${file.stat.ino}-${file.stat.size}-${file.stat.mtimeMs}-${file.stat.ctimeMs}\"`;\n const name = encodeURIComponent(path.basename(file.path)).replace(\n /[!'()*]/gu,\n (value) => `%${value.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n const headers = new Headers({\n 'content-type': file.mimeType,\n 'content-disposition': `attachment; filename*=UTF-8''${name}`,\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"default-src 'none'; sandbox\",\n 'accept-ranges': 'bytes',\n etag: version,\n });\n const expectedVersion = context.req.header('if-match');\n if (expectedVersion !== undefined && expectedVersion !== version)\n return new Response(null, { status: 412, headers });\n let start = 0;\n let end = file.stat.size - 1;\n if (range !== undefined) {\n const match = /^bytes=(\\d*)-(\\d*)$/u.exec(range);\n if (\n !match ||\n (!match[1] && !match[2]) ||\n file.stat.size === 0 ||\n [match[1], match[2]].some((value) => value !== '' && !Number.isSafeInteger(Number(value)))\n ) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (match[1] === '') {\n const suffix = Number(match[2]);\n start = suffix > 0 ? Math.max(0, file.stat.size - suffix) : file.stat.size;\n } else {\n start = Number(match[1]);\n end = match[2] === '' ? end : Math.min(end, Number(match[2]));\n }\n if (start > end || start >= file.stat.size) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (ranged) end = Math.min(end, start + MAX_CONTENT_BYTES - 1);\n headers.set('content-range', `bytes ${start}-${end}/${file.stat.size}`);\n }\n const bytes = await readArtifactBytes(file.handle, Math.max(0, end - start + 1), start);\n const after = await file.handle.stat();\n if (after.size !== file.stat.size || after.mtimeMs !== file.stat.mtimeMs || after.ctimeMs !== file.stat.ctimeMs)\n return new Response(null, { status: 412, headers });\n headers.set('content-length', String(bytes.byteLength));\n return new Response(bytes, { status: range === undefined ? 200 : 206, headers });\n } finally {\n await file.handle.close();\n }\n });\n return app;\n}\n\nexport function createArtifactApi(storage?: ArtifactStorage): PoApi {\n return {\n basePath: 'artifacts',\n start(context: PoApiContext) {\n if (!context.sessionId) throw new Error('Artifacts requires a session identity.');\n const app = createArtifactsApi(artifactRoot(context.sessionId, context.environment ?? {}), {\n temporaryRoot: context.environment?.PO_SESSION_TEMP_DIR,\n workflowVisible: storage?.workflowVisible,\n });\n return { fetch: (request) => app.fetch(request), close: () => undefined };\n },\n };\n}\n\nexport const api: PoApi = createArtifactApi();\n","import { defineRoute, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactApi } from '../../../../../../services/artifactsApi';\nimport type { ArtifactServerScope } from '../../_lib/serverRoot';\n\nexport default defineRoute(({ root }: WithRoot<PoServerPluginContext, ArtifactServerScope>) =>\n createArtifactApi(root.storage),\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.beforeAgentStart,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.toolExecutionEnd,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport channelArtifacts from '../src/extensions/(backend)/channel/artifacts.server';\nimport apiRoute from '../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-artifact',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return [() => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n const contextSession = { ...contextGlobal, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextSession)]; },\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n get hooks(): PoServerSessionPlugin['hooks'] { return [via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]; },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;AAQA,SAAgB,sBAAsB,aAA4E;CAChH,MAAM,2BAAW,IAAI,IAAwC;CAC7D,OAAO;EACL,MAAM,eAAe,WAAW,sBAAsB,aAAa;GACjE,MAAM,OAAOA,sBAAAA,aAAa,WAAW,mBAAmB;GACxD,IAAI;IACF,MAAMC,sBAAAA,mBAAmB,IAAI;IAC7B,OAAO;GACT,SAAS,OAAO;IACd,IAAI,iBAAiBC,sBAAAA,uBAAuB,MAAM,WAAW,KAAK,OAAO,KAAA;IACzE,MAAM;GACR;EACF;EACA,WAAW,sBAAsB,gBAAgBC,sBAAAA,qBAAqB,mBAAmB;EACzF,2BAA2B,QAAQ;GACjC,MAAM,QAAQ,OAAO,qBAAqB;GAC1C,SAAS,IAAI,OAAO,MAAM;GAC1B,aAAa;IACX,SAAS,OAAO,KAAK;GACvB;EACF;EACA,kBAAkB,cAAc,SAC9B,SAAS,OAAO,KAAK,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,WAAW,OAAO,cAAc,IAAI,CAAC;CAC5F;AACF;;AAGA,IAAa,mBAAb,cAAsCC,oBAAAA,QAAmC;CAGpD;CAFnB,YACE,SACA,SACA;EACA,MAAM,SAASC,kBAAAA,iBAAiB;EAFf,KAAA,UAAA;CAGnB;CACA,eAAe,WAAmB,aAA4D;EAC5F,OAAO,KAAK,QAAQ,eAAe,WAAW,WAAW;CAC3D;CACA,SAAS,aAA4D;EACnE,OAAO,KAAK,QAAQ,SAAS,WAAW;CAC1C;CACA,2BAA2B,QAAoC;EAC7D,OAAO,KAAK,QAAQ,2BAA2B,MAAM;CACvD;CACA,gBAAgB,cAAsB,MAA4B;EAChE,OAAO,KAAK,QAAQ,gBAAgB,cAAc,IAAI;CACxD;AACF;AAEA,SAAgB,sBAAsB,SAAsD;CAC1F,QAAQ,YAAY;EAClB,IAAI,iBAAiB,SAAS,OAAO;CACvC;AACF;;;ACvDA,IAAA,yBAAA,GAAeC,iCAAAA,WAAAA,EAAY,EAAE,WAAkC;CAC7D,MAAM,UAAU,sBAAsB,OAAO,OAAO,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC,CAAC;CACpF,OAAO;EAAE,OAAO;EAAS,UAAU,CAAC,sBAAsB,OAAO,CAAC;CAAE;AACtE,CAAC;;;ACoBD,MAAa,uBAAuB;;;;;;;ACZpC,eAAe,oBAAoB,MAAgC;CACjE,IAAI;EACF,MAAMC,sBAAAA,mBAAmB,IAAI;EAC7B,OAAO;CACT,SAAS,OAAO;EACd,IAAI,iBAAiBC,sBAAAA,uBAAuB,MAAM,WAAW,KAAK,OAAO;EACzE,MAAM;CACR;AACF;AAEA,SAAgB,sBAAsB,EAAE,MAAM,SAAS,QAA+B,SAA2B;CAC/G,MAAM,cAAc,OAAO,OAAO,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC;CACjE,MAAM,kBAAkB,WAAW,sBAAsB,WAAW;CAEpE,MAAM,cAAA,GAAaC,4BAAAA,iBAAAA,CAAiB,IAAI;CACxC,IAAI;CAUJ,IAAI;CACJ,IAAI,SAAS;CACb,MAAM,gBAA+B;EACnC,MAAM,UAAU;EAChB,IAAI,CAAC,WAAW,QAAQ,OAAO,QAAQ,QAAQ;EAC/C,IAAI,QAAQ,SAAS,OAAO,QAAQ;EACpC,MAAM,SAAS,QAAQ,KAAK;EAC5B,QAAQ,WAAW,YAAY;GAC7B,MAAM,WAAW;IACf,GAAI,MAAMC,sBAAAA,cAAc,QAAQ,MAAM,gBAAgB,iBAAiB,MAAM;IAC7E,GAAI,YAAY,sBAAsB,EAAE,eAAe,YAAY,oBAAoB,IAAI,CAAC;GAC9F;GACA,IAAI,UAAU,WAAW,SAAS;GAElC,MAAM,YAAY,YAAY,sBAC1B,MAAMA,sBAAAA,cAAc,YAAY,qBAAqB,KAAA,GAAW,MAAM,IACtE,KAAA;GACJ,IAAI,UAAU,WAAW,SAAS;GAClC,MAAM,cAAc,KAAK,UAAU,CAAC,UAAU,SAAS,CAAC;GACxD,IAAI,gBAAgB,QAAQ,aAAa;GACzC,QAAQ,cAAc;GACtB,KAAK,QAAQ,cAAc,QAAQ,sBAAsB,QAAQ,QAAQ,WAAW,QAAQ;EAC9F,EAAA,CAAG,CAAC,CACD,OAAO,UAAmB;GAEzB,IAAI,CAAC,OAAO,SACV,KAAK,QAAQ,SAAS,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;EAC9G,CAAC,CAAC,CACD,cAAc;GACb,QAAQ,UAAU,KAAA;EACpB,CAAC;EACH,OAAO,QAAQ;CACjB;CACA,MAAM,iBAAuB;EAC3B,MAAM,UAAU;EAChB,IAAI,CAAC,WAAW,QAAQ;EACxB,SAAA,GAAQC,YAAAA,WAAAA,OAAiB;GACvB,QAAQ,KAAA;GACR,QAAa,CAAC,CAAC,cAAc;IAC3B,IAAI,WAAW,SAAS,SAAS;GACnC,CAAC;EACH,GAAGC,kBAAAA,mBAAmB;CACxB;CACA,MAAM,aAAmB;EACvB,QAAQ,cAAc;EAEtB,QAAQ,KAAK,MAAM;EACnB,SAAS,KAAA;EACT,IAAI,UAAU,KAAA,GAAW,CAAA,GAAA,YAAA,aAAA,CAAa,KAAK;EAC3C,QAAQ,KAAA;CACV;CA4CA,OAAO;EACL,YAAY,CAAC;GA3Cb,MAAM;GACN,MAAM,MAAM,SAAS;IACnB,IAAI,QAAQ,MAAM,IAAI,MAAM,6BAA6B;IACzD,KAAK;IACL,MAAM,OAAOC,sBAAAA,aAAa,QAAQ,WAAW,WAAW;IACxD,IAAI,CAAE,MAAM,oBAAoB,IAAI,GAAI,OAAO;IAC/C,IAAI,QAAQ,MAAM,IAAI,MAAM,6BAA6B;IACzD,SAAS;KACP;KACA;KACA,MAAM,IAAI,gBAAgB;KAC1B,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,WAAW,SAAS,IAAI,EAAE;IAC/E;IACA,MAAM,UAAU;IAEhB,QAAa,CAAC,CAAC,cAAc;KAC3B,IAAI,CAAC,UAAU,WAAW,SAAS,SAAS;IAC9C,CAAC;IACD,OAAO;GACT;EAwBoB,CAAC;EACrB,kBAAA;GAtBA,OAAO;GACP,MAAM,OAAO,OAAO,SAAS;IAC3B,MAAM,OAAOA,sBAAAA,aAAa,QAAQ,WAAW,WAAW;IACxD,MAAM,eAAe,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe;IACnF,IAAI,CAAE,MAAM,oBAAoB,IAAI,GAAI,OAAO,EAAE,aAAa;IAC9D,MAAM,cAAc,4BAA4B;IAChD,IAAI,aAAa,SAAS,WAAW,GAAG,OAAO,EAAE,aAAa;IAC9D,OAAO,EACL,cACE,GAAG,aAAa,MAAM,YAAY,mZAAmZ,KAAK,EAC9b;GACF;EAWe;EACf,kBAAA;GATA,OAAO;GACP,OAAO,QAAQ,SAAS;IAEtB,IAAI,QAAQ,QAAQ,cAAc,QAAQ,WAAW,QAAa;GACpE;EAKe;EACf,iBAAiB;GACf,SAAS;GACT,KAAK;GACL,OAAO,QAAQ,QAAQ;EACzB;CACF;AACF;;;AC1IA,MAAa,4BAA4B,YAA8D;CACrG,MAAM,UAAU,QAAQ;CACxB,MAAM,UAAU,sBAAsB,SAAS,OAAO;CAEtD,MAAM,WAAW,QAAQ,OAAO,QAAQ,IAAI,CAAC,sBAAsB,OAAO,CAAC,IAAI,CAAC;CAChF,OAAO;EAAE,OAAO;GAAE,GAAG;GAAS;EAAQ;EAAG;EAAU,YAAY,QAAQ;EAAY,WAAW,QAAQ;CAAU;AAClH;;;ACTA,IAAA,uBAAA,GAAeC,iCAAAA,WAAAA,CAAW,wBAAwB;;;ACClD,SAAS,WAAW,OAA2C;CAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,WAAW;CACjB,OACE,MAAM,QAAQ,SAAS,KAAK,MAC3B,SAAS,UAAU,KAAA,KAAa,OAAO,SAAS,UAAU,cAC1D,SAAS,kBAAkB,KAAA,KAAa,OAAO,SAAS,kBAAkB,aAC3E,SAAS,MAAM,OACZ,SACC,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,KAAK,SAAS,YACrB,OAAO,KAAK,SAAS,YACrB,OAAO,KAAK,SAAS,YACrB,OAAO,SAAS,KAAK,IAAI,KACzB,OAAO,KAAK,eAAe,YAC3B,OAAO,SAAS,KAAK,UAAU,CACnC;AAEJ;AAEA,SAAgB,yBAAuC;CACrD,OAAO;EACL,WAAW;EACX,MAAM,MAAM;GACV,MAAM,2BAAW,IAAI,IAAsE;GAC3F,OAAO;IACL,WAAW,OAAO;KAChB,OAAO,SAAS,IAAI,MAAM,SAAS,CAAC,EAAE;IACxC;IACA,aAAa,OAAO;KAClB,SAAS,IAAI,MAAM,SAAS,CAAC,EAAE,YAAY;KAC3C,MAAM,QAAkE,EAAE,mBAAmB,KAAA,EAAU;KACvG,SAAS,IAAI,MAAM,WAAW,KAAK;KACnC,MAAM,cAAc,KAAK,aAAa,UACpC,sBACA,MAAM,YACL,aAAa;MACZ,IAAI,CAAC,WAAW,QAAQ,KAAK,SAAS,IAAI,MAAM,SAAS,MAAM,OAAO;MACtE,MAAM,WAAW;MACjB,KAAK,QAAQ,MAAM,WAAW,QAAQ;KACxC,GACA,EAAE,cAAc,KAAK,CACvB;KACA,CAAM,YAAY;MAChB,IAAI;MACJ,IAAI;OACF,WAAW;QACT,GAAI,MAAMC,sBAAAA,cAAcC,sBAAAA,aAAa,MAAM,WAAW,MAAM,eAAe,CAAC,CAAC,CAAC;QAC9E,GAAI,MAAM,aAAa,sBACnB,EAAE,eAAe,MAAM,YAAY,oBAAoB,IACvD,CAAC;OACP;MACF,SAAS,OAAO;OACd,WAAW;QACT,OAAO,CAAC;QACR,OAAO,iBAAiB,QAAQ,MAAM,UAAU;OAClD;MACF;MAEA,IAAI,SAAS,IAAI,MAAM,SAAS,MAAM,SAAS,MAAM,aAAa,KAAA,GAAW;MAC7E,MAAM,WAAW;MACjB,KAAK,QAAQ,MAAM,WAAW,QAAQ;KACxC,EAAA,CAAG;IACL;IACA,eAAe,WAAW;KACxB,SAAS,IAAI,SAAS,CAAC,EAAE,YAAY;KACrC,SAAS,OAAO,SAAS;IAC3B;IACA,QAAQ;KACN,KAAK,MAAM,SAAS,SAAS,OAAO,GAAG,MAAM,YAAY;KACzD,SAAS,MAAM;IACjB;GACF;EACF;CACF;AACF;;;AC7EA,IAAA,4BAAA,GAAeC,iCAAAA,cAAAA,CAAc,sBAAsB;;;ACAnD,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,OAAO;EACf,UAAU,KAAA;CACZ;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,QAAQ,OAAO;EACvB,UAAU,KAAA;CACZ;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,OAAO,CAAC,QAAQ,OAAO;EACvB,KAAK;CACP;AACF;;;ACZA,SAAgB,mBACd,MACA,UAAoF,CAAC,GAC/E;CACN,MAAM,MAAM,IAAIC,KAAAA,KAAK;CACrB,MAAM,gBAAgB,UAAsC;EAC1D,IAAI,UAAU,KAAA,KAAa,UAAU,aAAa,OAAO;EACzD,IAAI,UAAU,aAAa,MAAM,IAAIC,sBAAAA,oBAAoB,uBAAuB,GAAG;EACnF,IAAI,CAAC,QAAQ,eAAe,MAAM,IAAIA,sBAAAA,oBAAoB,qDAAqD,GAAG;EAClH,OAAO,QAAQ;CACjB;CACA,IAAI,SAAS,OAAO,YAClB,QAAQ,KACN,EAAE,OAAO,iBAAiBA,sBAAAA,sBAAsB,MAAM,UAAU,kCAAkC,GAClG,iBAAiBA,sBAAAA,sBAAsB,MAAM,SAAS,GACxD,CACF;CACA,IAAI,IAAI,OAAO,KAAK,MAAM,OAAO,YAAY;EAC3C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,WAAW,MAAMC,sBAAAA,cAAc,UAAU,aAAa,OAAO,QAAQ,wBAAwB,IAAI;EACvG,OAAO,QAAQ,KACb;GAAE,GAAG;GAAU,GAAI,QAAQ,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;EAAG,GAC1F,SAAS,UAAU,KAAA,IAAY,MAAM,GACvC;CACF,CAAC;CACD,IAAI,IAAI,OAAO,QAAQ,MAAM,OAAO,YAAY;EAC9C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,OAAO,MAAMC,sBAAAA,aACjB,UACA,QAAQ,IAAI,MAAM,MAAM,GACxB,aAAa,OAAO,QAAQ,wBAAwB,IACtD;EACA,IAAI;GACF,MAAM,UAA2B;IAAE,MAAM,KAAK;IAAM,SAAS;IAAI,UAAU,KAAK;GAAS;GACzF,IAAI,KAAK,KAAK,OAAA,SACZ,OAAO,QAAQ,KAAK;IAClB,GAAG;IACH,aAAa;IACb,QAAQ;GACV,CAAC;GAEH,MAAM,QAAQ,MAAMC,sBAAAA,kBAAkB,KAAK,QAAQC,kBAAAA,oBAAoB,CAAC;GACxE,IAAI,MAAM,aAAA,SACR,OAAO,QAAQ,KAAK;IAClB,GAAG;IACH,aAAa;IACb,QAAQ;GACV,CAAC;GACH,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC,GACpC,OAAO,QAAQ,KAAK;IAAE,GAAG;IAAS,aAAa;IAAM,QAAQ;GAA2B,CAAC;GAC3F,OAAO,QAAQ,KAAK;IAAE,GAAG;IAAS,SAAS,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;GAAE,CAAC;EAC9E,UAAU;GACR,MAAM,KAAK,OAAO,MAAM;EAC1B;CACF,CAAC;CACD,IAAI,IAAI,OAAO,QAAQ,MAAM,OAAO,YAAY;EAC9C,MAAM,WAAW,aAAa,QAAQ,IAAI,MAAM,OAAO,CAAC;EACxD,MAAM,OAAO,MAAMF,sBAAAA,aACjB,UACA,QAAQ,IAAI,MAAM,MAAM,GACxB,aAAa,OAAO,QAAQ,wBAAwB,IACtD;EACA,IAAI;GACF,MAAM,QAAQ,QAAQ,IAAI,OAAO,OAAO;GAExC,MAAM,SACJ,KAAK,KAAK,OAAA,YACV,KAAK,SAAS,WAAW,QAAQ,KACjC,KAAK,KAAK,QAAA,aACV,UAAU,KAAA;GACZ,IAAI,KAAK,KAAK,OAAA,YAA4B,CAAC,QACzC,MAAM,IAAIF,sBAAAA,oBAAoB,2CAA2C,GAAG;GAC9E,MAAM,UAAU,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK,QAAQ;GAC/G,MAAM,OAAO,mBAAmBK,UAAAA,QAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,QACxD,cACC,UAAU,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,GAC9D;GACA,MAAM,UAAU,IAAI,QAAQ;IAC1B,gBAAgB,KAAK;IACrB,uBAAuB,gCAAgC;IACvD,iBAAiB;IACjB,0BAA0B;IAC1B,2BAA2B;IAC3B,iBAAiB;IACjB,MAAM;GACR,CAAC;GACD,MAAM,kBAAkB,QAAQ,IAAI,OAAO,UAAU;GACrD,IAAI,oBAAoB,KAAA,KAAa,oBAAoB,SACvD,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK;GAAQ,CAAC;GACpD,IAAI,QAAQ;GACZ,IAAI,MAAM,KAAK,KAAK,OAAO;GAC3B,IAAI,UAAU,KAAA,GAAW;IACvB,MAAM,QAAQ,uBAAuB,KAAK,KAAK;IAC/C,IACE,CAAC,SACA,CAAC,MAAM,MAAM,CAAC,MAAM,MACrB,KAAK,KAAK,SAAS,KACnB,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,MAAM,UAAU,UAAU,MAAM,CAAC,OAAO,cAAc,OAAO,KAAK,CAAC,CAAC,GACzF;KACA,QAAQ,IAAI,iBAAiB,WAAW,KAAK,KAAK,MAAM;KACxD,OAAO,IAAI,SAAS,MAAM;MAAE,QAAQ;MAAK;KAAQ,CAAC;IACpD;IACA,IAAI,MAAM,OAAO,IAAI;KACnB,MAAM,SAAS,OAAO,MAAM,EAAE;KAC9B,QAAQ,SAAS,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,MAAM,IAAI,KAAK,KAAK;IACxE,OAAO;KACL,QAAQ,OAAO,MAAM,EAAE;KACvB,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,IAAI,KAAK,OAAO,MAAM,EAAE,CAAC;IAC9D;IACA,IAAI,QAAQ,OAAO,SAAS,KAAK,KAAK,MAAM;KAC1C,QAAQ,IAAI,iBAAiB,WAAW,KAAK,KAAK,MAAM;KACxD,OAAO,IAAI,SAAS,MAAM;MAAE,QAAQ;MAAK;KAAQ,CAAC;IACpD;IACA,IAAI,QAAQ,MAAM,KAAK,IAAI,KAAK,QAAQC,kBAAAA,oBAAoB,CAAC;IAC7D,QAAQ,IAAI,iBAAiB,SAAS,MAAM,GAAG,IAAI,GAAG,KAAK,KAAK,MAAM;GACxE;GACA,MAAM,QAAQ,MAAMH,sBAAAA,kBAAkB,KAAK,QAAQ,KAAK,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,KAAK;GACtF,MAAM,QAAQ,MAAM,KAAK,OAAO,KAAK;GACrC,IAAI,MAAM,SAAS,KAAK,KAAK,QAAQ,MAAM,YAAY,KAAK,KAAK,WAAW,MAAM,YAAY,KAAK,KAAK,SACtG,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK;GAAQ,CAAC;GACpD,QAAQ,IAAI,kBAAkB,OAAO,MAAM,UAAU,CAAC;GACtD,OAAO,IAAI,SAAS,OAAO;IAAE,QAAQ,UAAU,KAAA,IAAY,MAAM;IAAK;GAAQ,CAAC;EACjF,UAAU;GACR,MAAM,KAAK,OAAO,MAAM;EAC1B;CACF,CAAC;CACD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAkC;CAClE,OAAO;EACL,UAAU;EACV,MAAM,SAAuB;GAC3B,IAAI,CAAC,QAAQ,WAAW,MAAM,IAAI,MAAM,wCAAwC;GAChF,MAAM,MAAM,mBAAmBI,sBAAAA,aAAa,QAAQ,WAAW,QAAQ,eAAe,CAAC,CAAC,GAAG;IACzF,eAAe,QAAQ,aAAa;IACpC,iBAAiB,SAAS;GAC5B,CAAC;GACD,OAAO;IAAE,QAAQ,YAAY,IAAI,MAAM,OAAO;IAAG,aAAa,KAAA;GAAU;EAC1E;CACF;AACF;;;AClJA,IAAA,wBAAA,GAAeC,iCAAAA,YAAAA,EAAa,EAAE,WAC5B,kBAAkB,KAAK,OAAO,CAChC;;;ACHA,IAAA,qCAAA,GAAeC,iCAAAA,WAAAA,EACZ,YAAkE,QAAQ,KAAK,gBAClF;;;ACFA,IAAA,qCAAA,GAAeC,iCAAAA,WAAAA,EACZ,YAAkE,QAAQ,KAAK,gBAClF;;;ACMA,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;;AAEpE,MAAM,WAAc,WAClB,OAAO,QAAQ,UAAsB,UAAU,KAAA,CAAS;AAC1D,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,gBAAA,GAAeC,gCAAAA,mBAAAA,CAAmB;CAC7C,MAAM;CACN,oBAAA,GAAmBC,gCAAAA,+BAAAA,CAA+BC,uBAAYC,mBAAW;CACzE,UAAA,GAASC,iCAAAA,mBAAAA,CAAmB;EAAE,QAAQ,CAACF,qBAAU;EAAG,WAAW,CAACA,qBAAU;EAAG,SAAS,CAACA,uBAAYC,mBAAW;CAAE,CAAC;CACjH,QAAQ,OAAO,YAAY;EACzB,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUD,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,OAAO;GACL,IAAA,GAAGG,iCAAAA,iBAAAA,CAAiB,WAAW;GAC/B,IAAI,WAA8C;IAAE,OAAO,OAAO,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGC,0BAAkB,aAAa,CAAC,CAAC;GAAG;GACzI,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,CAAE;EAC5C;CACF;CACA,WAAW,OAAO,YAAY;EAC5B,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUJ,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,OAAO;GACL,IAAA,GAAGG,iCAAAA,iBAAAA,CAAiB,WAAW;GAC/B,IAAI,WAA8C;IAAE,OAAO,QAAQ,CAAC,QAAQ,OAAO,QAAQ,IAAI,KAAA,UAAkB,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGC,0BAAkB,aAAa,CAAC,CAAC,CAAC;GAAG;GACzL,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,CAAE;EAC5C;CACF;CACA,SAAS,OAAO,YAAY;EAC1B,MAAM,cAAc,MAAM,QAAQ,UAAU,UAAUJ,uBAAY,OAAO;EACzE,MAAM,gBAAgB;GAAE,GAAG;GAAS,MAAM,YAAY;EAAM;EAC5D,MAAM,eAAe,MAAM,QAAQ,UAAU,WAAWC,qBAAa,aAAa;EAClF,MAAM,iBAAiB;GAAE,GAAG;GAAe,MAAM,aAAa;EAAM;EACpE,OAAO;GACL,IAAA,GAAGE,iCAAAA,iBAAAA,CAAiB,aAAa,YAAY;GAC7C,IAAI,MAAoC;IAAE,OAAO,CAAC,GAAGE,sBAAU,cAAc,CAAC;GAAG;GACjF,IAAI,WAA8C;IAAE,OAAO,QAAQ,CAAC,QAAQ,OAAO,QAAQ,IAAI,KAAA,UAAkB,IAAI,EAAE,WAAW,YAAY,GAAG,GAAGD,0BAAkB,aAAa,CAAC,CAAC,CAAC;GAAG;GACzL,IAAI,QAAwC;IAAE,OAAO,CAAC,IAAI,EAAE,OAAO,qBAAqB,GAAG,GAAGE,mCAAsB,cAAc,CAAC,GAAG,IAAI,EAAE,OAAO,qBAAqB,GAAG,GAAGC,mCAAsB,cAAc,CAAC,CAAC;GAAG;GACvN,UAAU,CAAC,GAAI,YAAY,YAAY,CAAC,GAAI,GAAI,aAAa,YAAY,CAAC,CAAE;GAC5E,IAAI,aAAkD;IAAE,OAAO,CAAC,GAAI,YAAY,cAAc,CAAC,GAAI,GAAI,aAAa,cAAc,CAAC,CAAE;GAAG;EAC1I;CACF;AACF,CAAC"}
|
|
@@ -148,8 +148,10 @@ function createArtifactSession({ host, context: root }, storage) {
|
|
|
148
148
|
scan: new AbortController(),
|
|
149
149
|
...fileAccess === void 0 ? {} : { closeAccess: fileAccess.register(root) }
|
|
150
150
|
};
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
const runtime = active;
|
|
152
|
+
refresh().finally(() => {
|
|
153
|
+
if (!closed && active === runtime) schedule();
|
|
154
|
+
});
|
|
153
155
|
return stop;
|
|
154
156
|
}
|
|
155
157
|
}],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":["rootGlobal","rootSession","channelArtifacts","apiRoute","hookBeforeAgentStart","hookToolExecutionEnd"],"sources":["../../src/services/artifacts/index.ts","../../src/extensions/(backend)/root.server.ts","../../src/types/artifacts.ts","../../src/services/artifactSession/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/artifactChannel/index.ts","../../src/extensions/(backend)/channel/artifacts.server.ts","../../src/types/apiRoutes.ts","../../src/services/artifactsApi/index.ts","../../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../generated/server.ts"],"sourcesContent":["import { type Context, Service } from '@deepseek-ai/cordis';\n\nimport { ARTIFACTS_SERVICE } from '../../constants/artifacts';\nimport type { ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifactSessions } from '../artifactFiles';\nimport type { ArtifactStorage } from './type';\n\n/** Roots come only from admitted host configuration, never a file request. */\nexport function createArtifactStorage(environment: Readonly<Record<string, string | undefined>>): ArtifactStorage {\n const policies = new Map<symbol, ArtifactWorkflowVisibility>();\n return {\n async rootForSession(sessionId, admittedEnvironment = environment) {\n const root = artifactRoot(sessionId, admittedEnvironment);\n try {\n await ensureArtifactRoot(root);\n return root;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return undefined;\n throw error;\n }\n },\n sessions: (admittedEnvironment = environment) => listArtifactSessions(admittedEnvironment),\n registerWorkflowVisibility(policy) {\n const owner = Symbol('workflow visibility');\n policies.set(owner, policy);\n return () => {\n policies.delete(owner);\n };\n },\n workflowVisible: (relativePath, kind) =>\n policies.size > 0 && [...policies.values()].every((policy) => policy(relativePath, kind)),\n };\n}\n\n/** Publish the same storage instance used by this scope's artifact reader. */\nexport class ArtifactsService extends Service implements ArtifactStorage {\n constructor(\n context: Context,\n private readonly storage: ArtifactStorage,\n ) {\n super(context, ARTIFACTS_SERVICE);\n }\n rootForSession(sessionId: string, environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.rootForSession(sessionId, environment);\n }\n sessions(environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.sessions(environment);\n }\n registerWorkflowVisibility(policy: ArtifactWorkflowVisibility) {\n return this.storage.registerWorkflowVisibility(policy);\n }\n workflowVisible(relativePath: string, kind: 'file' | 'directory') {\n return this.storage.workflowVisible(relativePath, kind);\n }\n}\n\nexport function createArtifactsPlugin(storage: ArtifactStorage): (context: Context) => void {\n return (context) => {\n new ArtifactsService(context, storage);\n };\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/artifacts': ArtifactsService;\n }\n}\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactStorage, createArtifactsPlugin } from '../../services/artifacts';\n\nexport default defineRoot(({ host }: PoServerPluginContext) => {\n const storage = createArtifactStorage(Object.freeze({ ...host.context.environment }));\n return { value: storage, services: [createArtifactsPlugin(storage)] };\n});\n","export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { clearTimeout, setTimeout } from 'node:timers';\n\nimport type { PoHeadlessActivity, PoHeadlessExecutionContext, PoHeadlessHook } from '@agimon-ai/po-core/headless';\nimport { readPoFileAccess } from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { ARTIFACT_REFRESH_MS } from '../../constants/artifacts';\nimport { artifactsChannelType } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifacts } from '../artifactFiles';\nimport { createArtifactStorage } from '../artifacts';\nimport type { ArtifactStorage } from '../artifacts/type';\n\n/**\n * Creates the session artifact folder. Resolves false when the host has no artifact folder\n * (the edge build in M1 rejects with a 404); Node never rejects with that status here.\n */\nasync function prepareArtifactRoot(root: string): Promise<boolean> {\n try {\n await ensureArtifactRoot(root);\n return true;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return false;\n throw error;\n }\n}\n\nexport function createArtifactSession({ host, context: root }: PoServerPluginContext, storage?: ArtifactStorage) {\n const environment = Object.freeze({ ...host.context.environment });\n const artifactStorage = storage ?? createArtifactStorage(environment);\n // So a paired client can open what the agent saved here, as it can the session's own folder.\n const fileAccess = readPoFileAccess(root);\n let active:\n | {\n context: PoHeadlessExecutionContext;\n root: string;\n scan: AbortController;\n pending?: Promise<void>;\n fingerprint?: string;\n closeAccess?: () => void;\n }\n | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n const refresh = (): Promise<void> => {\n const runtime = active;\n if (!runtime || closed) return Promise.resolve();\n if (runtime.pending) return runtime.pending;\n const signal = runtime.scan.signal;\n runtime.pending = (async () => {\n const snapshot = {\n ...(await listArtifacts(runtime.root, artifactStorage.workflowVisible, signal)),\n ...(environment.PO_SESSION_TEMP_DIR ? { temporaryRoot: environment.PO_SESSION_TEMP_DIR } : {}),\n };\n if (closed || active !== runtime) return;\n // Temporary files share the channel's invalidation signal, but are fetched only while visible.\n const temporary = environment.PO_SESSION_TEMP_DIR\n ? await listArtifacts(environment.PO_SESSION_TEMP_DIR, undefined, signal)\n : undefined;\n if (closed || active !== runtime) return;\n const fingerprint = JSON.stringify([snapshot, temporary]);\n if (fingerprint === runtime.fingerprint) return;\n runtime.fingerprint = fingerprint;\n host.context.directEvents?.publish(artifactsChannelType, runtime.context.sessionId, snapshot);\n })()\n .catch((error: unknown) => {\n // Cancellation deliberately leaves the last snapshot alone.\n if (!signal.aborted)\n host.context.onNotice(`Artifact refresh failed: ${error instanceof Error ? error.message : String(error)}`);\n })\n .finally(() => {\n runtime.pending = undefined;\n });\n return runtime.pending;\n };\n const schedule = (): void => {\n const runtime = active;\n if (!runtime || closed) return;\n timer = setTimeout(() => {\n timer = undefined;\n void refresh().finally(() => {\n if (active === runtime) schedule();\n });\n }, ARTIFACT_REFRESH_MS);\n };\n const stop = (): void => {\n active?.closeAccess?.();\n // Scans only read. Cancel them, but never hold session teardown on filesystem I/O.\n active?.scan.abort();\n active = undefined;\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n };\n const activity: PoHeadlessActivity = {\n name: 'artifacts',\n async start(context) {\n if (closed) throw new Error('Artifact session is closed.');\n stop();\n const root = artifactRoot(context.sessionId, environment);\n if (!(await prepareArtifactRoot(root))) return stop;\n if (closed) throw new Error('Artifact session is closed.');\n active = {\n context,\n root,\n scan: new AbortController(),\n ...(fileAccess === undefined ? {} : { closeAccess: fileAccess.register(root) }),\n };\n await refresh();\n schedule();\n return stop;\n },\n };\n const beforeAgentStart: PoHeadlessHook = {\n event: 'before_agent_start',\n async handle(event, context) {\n const root = artifactRoot(context.sessionId, environment);\n const systemPrompt = typeof event.systemPrompt === 'string' ? event.systemPrompt : '';\n if (!(await prepareArtifactRoot(root))) return { systemPrompt };\n const declaration = `Session artifact folder: ${root}`;\n if (systemPrompt.includes(declaration)) return { systemPrompt };\n return {\n systemPrompt:\n `${systemPrompt}\\n\\n${declaration}\\nSave user-designated artifacts and important deliverable documents in this folder, using descriptive filenames. Keep ordinary repository source edits in their existing locations. Do not move existing documents or overwrite artifacts without the user's intent. This folder belongs only to the current session. When a message names \\`@artifact:<path>\\`, it means the file at <path> inside this folder.`.trim(),\n };\n },\n };\n const toolExecutionEnd: PoHeadlessHook = {\n event: 'tool_execution_end',\n handle(_event, context) {\n // Snapshot reads must not hold the runtime's event drain open during shutdown.\n if (active?.context.sessionId === context.sessionId) void refresh();\n },\n };\n return {\n activities: [activity],\n beforeAgentStart,\n toolExecutionEnd,\n onDispose: () => {\n closed = true;\n stop();\n return Promise.resolve();\n },\n };\n}\n","import type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactsPlugin } from '../../../../../services/artifacts';\nimport type { ArtifactStorage } from '../../../../../services/artifacts/type';\nimport { createArtifactSession } from '../../../../../services/artifactSession';\n\nexport const createArtifactServerRoot = (context: WithRoot<PoServerPluginContext, ArtifactStorage>) => {\n const storage = context.root;\n const runtime = createArtifactSession(context, storage);\n // An outer level that runs this package built the global root there, so its services never ran in this session.\n const services = context.hosted('global') ? [createArtifactsPlugin(storage)] : [];\n return { value: { ...runtime, storage }, services, activities: runtime.activities, onDispose: runtime.onDispose };\n};\nexport type ArtifactServerScope = ReturnType<typeof createArtifactServerRoot>['value'];\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createArtifactServerRoot);\n","import type { PoHubChannel } from '@agimon-ai/po-core/hubChannel';\n\nimport { artifactsChannelType, type ArtifactSnapshot } from '../../types/artifacts';\nimport { artifactRoot, listArtifacts } from '../artifactFiles';\n\nfunction snapshotOf(value: unknown): value is ArtifactSnapshot {\n if (typeof value !== 'object' || value === null) return false;\n const snapshot = value as Partial<ArtifactSnapshot>;\n return (\n Array.isArray(snapshot.items) &&\n (snapshot.error === undefined || typeof snapshot.error === 'string') &&\n (snapshot.temporaryRoot === undefined || typeof snapshot.temporaryRoot === 'string') &&\n snapshot.items.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.path === 'string' &&\n typeof item.name === 'string' &&\n typeof item.size === 'number' &&\n Number.isFinite(item.size) &&\n typeof item.modifiedAt === 'number' &&\n Number.isFinite(item.modifiedAt),\n )\n );\n}\n\nexport function createArtifactsChannel(): PoHubChannel {\n return {\n frameType: artifactsChannelType,\n start(host) {\n const sessions = new Map<string, { snapshot?: ArtifactSnapshot; unsubscribe: () => void }>();\n return {\n payloadFor(scope) {\n return sessions.get(scope.sessionId)?.snapshot;\n },\n sessionAdded(scope) {\n sessions.get(scope.sessionId)?.unsubscribe();\n const state: { snapshot?: ArtifactSnapshot; unsubscribe: () => void } = { unsubscribe: () => undefined };\n sessions.set(scope.sessionId, state);\n state.unsubscribe = host.directEvents.subscribe(\n artifactsChannelType,\n scope.sessionId,\n (snapshot) => {\n if (!snapshotOf(snapshot) || sessions.get(scope.sessionId) !== state) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n },\n { replayLatest: true },\n );\n void (async () => {\n let snapshot: ArtifactSnapshot;\n try {\n snapshot = {\n ...(await listArtifacts(artifactRoot(scope.sessionId, scope.environment ?? {}))),\n ...(scope.environment?.PO_SESSION_TEMP_DIR\n ? { temporaryRoot: scope.environment.PO_SESSION_TEMP_DIR }\n : {}),\n };\n } catch (error) {\n snapshot = {\n items: [],\n error: error instanceof Error ? error.message : 'The artifact folder could not be read.',\n };\n }\n // A live session event wins over the earlier seed read.\n if (sessions.get(scope.sessionId) !== state || state.snapshot !== undefined) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n })();\n },\n sessionRemoved(sessionId) {\n sessions.get(sessionId)?.unsubscribe();\n sessions.delete(sessionId);\n },\n close() {\n for (const state of sessions.values()) state.unsubscribe();\n sessions.clear();\n },\n };\n },\n };\n}\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactsChannel } from '../../../services/artifactChannel';\n\nexport default defineChannel(createArtifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","import path from 'node:path';\n\nimport type { PoApi, PoApiContext } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { MAX_CONTENT_BYTES, MAX_PREVIEW_BYTES, MAX_RANGED_VIDEO_BYTES } from '../../constants/artifacts';\nimport routes from '../../types/apiRoutes';\nimport type { ArtifactPreview, ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, listArtifacts, openArtifact, readArtifactBytes } from '../artifactFiles';\nimport type { ArtifactStorage } from '../artifacts/type';\n\nexport function createArtifactsApi(\n root: string,\n options: { temporaryRoot?: string; workflowVisible?: ArtifactWorkflowVisibility } = {},\n): Hono {\n const app = new Hono();\n const selectedRoot = (scope: string | undefined): string => {\n if (scope === undefined || scope === 'artifacts') return root;\n if (scope !== 'temporary') throw new ArtifactAccessError('Invalid file scope.', 400);\n if (!options.temporaryRoot) throw new ArtifactAccessError('Temporary files are unavailable for this session.', 404);\n return options.temporaryRoot;\n };\n app.onError((error, context) =>\n context.json(\n { error: error instanceof ArtifactAccessError ? error.message : 'The artifact could not be read.' },\n error instanceof ArtifactAccessError ? error.status : 500,\n ),\n );\n app.get(routes.list.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const snapshot = await listArtifacts(selected, selected === root ? options.workflowVisible : () => true);\n return context.json(\n { ...snapshot, ...(options.temporaryRoot ? { temporaryRoot: options.temporaryRoot } : {}) },\n snapshot.error === undefined ? 200 : 500,\n );\n });\n app.get(routes.preview.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const preview: ArtifactPreview = { path: file.path, content: '', mimeType: file.mimeType };\n if (file.stat.size > MAX_PREVIEW_BYTES) {\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n }\n const bytes = await readArtifactBytes(file.handle, MAX_PREVIEW_BYTES + 1);\n if (bytes.byteLength > MAX_PREVIEW_BYTES)\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n if (bytes.subarray(0, 8192).includes(0))\n return context.json({ ...preview, unavailable: true, reason: 'This artifact is binary.' });\n return context.json({ ...preview, content: new TextDecoder().decode(bytes) });\n } finally {\n await file.handle.close();\n }\n });\n app.get(routes.content.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const range = context.req.header('range');\n // Videos past the download cap (computer-use recordings) are served only in bounded ranges.\n const ranged =\n file.stat.size > MAX_CONTENT_BYTES &&\n file.mimeType.startsWith('video/') &&\n file.stat.size <= MAX_RANGED_VIDEO_BYTES &&\n range !== undefined;\n if (file.stat.size > MAX_CONTENT_BYTES && !ranged)\n throw new ArtifactAccessError('This artifact is too large to download.', 413);\n const version = `\"${file.stat.dev}-${file.stat.ino}-${file.stat.size}-${file.stat.mtimeMs}-${file.stat.ctimeMs}\"`;\n const name = encodeURIComponent(path.basename(file.path)).replace(\n /[!'()*]/gu,\n (value) => `%${value.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n const headers = new Headers({\n 'content-type': file.mimeType,\n 'content-disposition': `attachment; filename*=UTF-8''${name}`,\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"default-src 'none'; sandbox\",\n 'accept-ranges': 'bytes',\n etag: version,\n });\n const expectedVersion = context.req.header('if-match');\n if (expectedVersion !== undefined && expectedVersion !== version)\n return new Response(null, { status: 412, headers });\n let start = 0;\n let end = file.stat.size - 1;\n if (range !== undefined) {\n const match = /^bytes=(\\d*)-(\\d*)$/u.exec(range);\n if (\n !match ||\n (!match[1] && !match[2]) ||\n file.stat.size === 0 ||\n [match[1], match[2]].some((value) => value !== '' && !Number.isSafeInteger(Number(value)))\n ) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (match[1] === '') {\n const suffix = Number(match[2]);\n start = suffix > 0 ? Math.max(0, file.stat.size - suffix) : file.stat.size;\n } else {\n start = Number(match[1]);\n end = match[2] === '' ? end : Math.min(end, Number(match[2]));\n }\n if (start > end || start >= file.stat.size) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (ranged) end = Math.min(end, start + MAX_CONTENT_BYTES - 1);\n headers.set('content-range', `bytes ${start}-${end}/${file.stat.size}`);\n }\n const bytes = await readArtifactBytes(file.handle, Math.max(0, end - start + 1), start);\n const after = await file.handle.stat();\n if (after.size !== file.stat.size || after.mtimeMs !== file.stat.mtimeMs || after.ctimeMs !== file.stat.ctimeMs)\n return new Response(null, { status: 412, headers });\n headers.set('content-length', String(bytes.byteLength));\n return new Response(bytes, { status: range === undefined ? 200 : 206, headers });\n } finally {\n await file.handle.close();\n }\n });\n return app;\n}\n\nexport function createArtifactApi(storage?: ArtifactStorage): PoApi {\n return {\n basePath: 'artifacts',\n start(context: PoApiContext) {\n if (!context.sessionId) throw new Error('Artifacts requires a session identity.');\n const app = createArtifactsApi(artifactRoot(context.sessionId, context.environment ?? {}), {\n temporaryRoot: context.environment?.PO_SESSION_TEMP_DIR,\n workflowVisible: storage?.workflowVisible,\n });\n return { fetch: (request) => app.fetch(request), close: () => undefined };\n },\n };\n}\n\nexport const api: PoApi = createArtifactApi();\n","import { defineRoute, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactApi } from '../../../../../../services/artifactsApi';\nimport type { ArtifactServerScope } from '../../_lib/serverRoot';\n\nexport default defineRoute(({ root }: WithRoot<PoServerPluginContext, ArtifactServerScope>) =>\n createArtifactApi(root.storage),\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.beforeAgentStart,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.toolExecutionEnd,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport channelArtifacts from '../src/extensions/(backend)/channel/artifacts.server';\nimport apiRoute from '../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-artifact',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return [() => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n const contextSession = { ...contextGlobal, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextSession)]; },\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n get hooks(): PoServerSessionPlugin['hooks'] { return [via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]; },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["rootGlobal","rootSession","channelArtifacts","apiRoute","hookBeforeAgentStart","hookToolExecutionEnd"],"sources":["../../src/services/artifacts/index.ts","../../src/extensions/(backend)/root.server.ts","../../src/types/artifacts.ts","../../src/services/artifactSession/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/artifactChannel/index.ts","../../src/extensions/(backend)/channel/artifacts.server.ts","../../src/types/apiRoutes.ts","../../src/services/artifactsApi/index.ts","../../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../generated/server.ts"],"sourcesContent":["import { type Context, Service } from '@deepseek-ai/cordis';\n\nimport { ARTIFACTS_SERVICE } from '../../constants/artifacts';\nimport type { ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifactSessions } from '../artifactFiles';\nimport type { ArtifactStorage } from './type';\n\n/** Roots come only from admitted host configuration, never a file request. */\nexport function createArtifactStorage(environment: Readonly<Record<string, string | undefined>>): ArtifactStorage {\n const policies = new Map<symbol, ArtifactWorkflowVisibility>();\n return {\n async rootForSession(sessionId, admittedEnvironment = environment) {\n const root = artifactRoot(sessionId, admittedEnvironment);\n try {\n await ensureArtifactRoot(root);\n return root;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return undefined;\n throw error;\n }\n },\n sessions: (admittedEnvironment = environment) => listArtifactSessions(admittedEnvironment),\n registerWorkflowVisibility(policy) {\n const owner = Symbol('workflow visibility');\n policies.set(owner, policy);\n return () => {\n policies.delete(owner);\n };\n },\n workflowVisible: (relativePath, kind) =>\n policies.size > 0 && [...policies.values()].every((policy) => policy(relativePath, kind)),\n };\n}\n\n/** Publish the same storage instance used by this scope's artifact reader. */\nexport class ArtifactsService extends Service implements ArtifactStorage {\n constructor(\n context: Context,\n private readonly storage: ArtifactStorage,\n ) {\n super(context, ARTIFACTS_SERVICE);\n }\n rootForSession(sessionId: string, environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.rootForSession(sessionId, environment);\n }\n sessions(environment?: Readonly<Record<string, string | undefined>>) {\n return this.storage.sessions(environment);\n }\n registerWorkflowVisibility(policy: ArtifactWorkflowVisibility) {\n return this.storage.registerWorkflowVisibility(policy);\n }\n workflowVisible(relativePath: string, kind: 'file' | 'directory') {\n return this.storage.workflowVisible(relativePath, kind);\n }\n}\n\nexport function createArtifactsPlugin(storage: ArtifactStorage): (context: Context) => void {\n return (context) => {\n new ArtifactsService(context, storage);\n };\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/artifacts': ArtifactsService;\n }\n}\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactStorage, createArtifactsPlugin } from '../../services/artifacts';\n\nexport default defineRoot(({ host }: PoServerPluginContext) => {\n const storage = createArtifactStorage(Object.freeze({ ...host.context.environment }));\n return { value: storage, services: [createArtifactsPlugin(storage)] };\n});\n","export type ArtifactScope = 'artifacts' | 'temporary';\n\n/** Workflow owns the visibility of its reserved artifact subtree. */\nexport type ArtifactWorkflowVisibility = (relativePath: string, kind: 'file' | 'directory') => boolean;\n\nexport interface ArtifactItem {\n /** Relative to the current session's artifact directory. */\n path: string;\n name: string;\n size: number;\n modifiedAt: number;\n}\n\nexport interface ArtifactSnapshot {\n items: ArtifactItem[];\n /** Host-admitted root used only to recognize session temporary-file references. */\n temporaryRoot?: string;\n error?: string;\n}\n\nexport interface ArtifactPreview {\n path: string;\n content: string;\n mimeType: string;\n unavailable?: boolean;\n reason?: string;\n}\n\nexport const artifactsChannelType = 'artifacts';\n","import { clearTimeout, setTimeout } from 'node:timers';\n\nimport type { PoHeadlessActivity, PoHeadlessExecutionContext, PoHeadlessHook } from '@agimon-ai/po-core/headless';\nimport { readPoFileAccess } from '@agimon-ai/po-core/platform';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { ARTIFACT_REFRESH_MS } from '../../constants/artifacts';\nimport { artifactsChannelType } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, ensureArtifactRoot, listArtifacts } from '../artifactFiles';\nimport { createArtifactStorage } from '../artifacts';\nimport type { ArtifactStorage } from '../artifacts/type';\n\n/**\n * Creates the session artifact folder. Resolves false when the host has no artifact folder\n * (the edge build in M1 rejects with a 404); Node never rejects with that status here.\n */\nasync function prepareArtifactRoot(root: string): Promise<boolean> {\n try {\n await ensureArtifactRoot(root);\n return true;\n } catch (error) {\n if (error instanceof ArtifactAccessError && error.status === 404) return false;\n throw error;\n }\n}\n\nexport function createArtifactSession({ host, context: root }: PoServerPluginContext, storage?: ArtifactStorage) {\n const environment = Object.freeze({ ...host.context.environment });\n const artifactStorage = storage ?? createArtifactStorage(environment);\n // So a paired client can open what the agent saved here, as it can the session's own folder.\n const fileAccess = readPoFileAccess(root);\n let active:\n | {\n context: PoHeadlessExecutionContext;\n root: string;\n scan: AbortController;\n pending?: Promise<void>;\n fingerprint?: string;\n closeAccess?: () => void;\n }\n | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n const refresh = (): Promise<void> => {\n const runtime = active;\n if (!runtime || closed) return Promise.resolve();\n if (runtime.pending) return runtime.pending;\n const signal = runtime.scan.signal;\n runtime.pending = (async () => {\n const snapshot = {\n ...(await listArtifacts(runtime.root, artifactStorage.workflowVisible, signal)),\n ...(environment.PO_SESSION_TEMP_DIR ? { temporaryRoot: environment.PO_SESSION_TEMP_DIR } : {}),\n };\n if (closed || active !== runtime) return;\n // Temporary files share the channel's invalidation signal, but are fetched only while visible.\n const temporary = environment.PO_SESSION_TEMP_DIR\n ? await listArtifacts(environment.PO_SESSION_TEMP_DIR, undefined, signal)\n : undefined;\n if (closed || active !== runtime) return;\n const fingerprint = JSON.stringify([snapshot, temporary]);\n if (fingerprint === runtime.fingerprint) return;\n runtime.fingerprint = fingerprint;\n host.context.directEvents?.publish(artifactsChannelType, runtime.context.sessionId, snapshot);\n })()\n .catch((error: unknown) => {\n // Cancellation deliberately leaves the last snapshot alone.\n if (!signal.aborted)\n host.context.onNotice(`Artifact refresh failed: ${error instanceof Error ? error.message : String(error)}`);\n })\n .finally(() => {\n runtime.pending = undefined;\n });\n return runtime.pending;\n };\n const schedule = (): void => {\n const runtime = active;\n if (!runtime || closed) return;\n timer = setTimeout(() => {\n timer = undefined;\n void refresh().finally(() => {\n if (active === runtime) schedule();\n });\n }, ARTIFACT_REFRESH_MS);\n };\n const stop = (): void => {\n active?.closeAccess?.();\n // Scans only read. Cancel them, but never hold session teardown on filesystem I/O.\n active?.scan.abort();\n active = undefined;\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n };\n const activity: PoHeadlessActivity = {\n name: 'artifacts',\n async start(context) {\n if (closed) throw new Error('Artifact session is closed.');\n stop();\n const root = artifactRoot(context.sessionId, environment);\n if (!(await prepareArtifactRoot(root))) return stop;\n if (closed) throw new Error('Artifact session is closed.');\n active = {\n context,\n root,\n scan: new AbortController(),\n ...(fileAccess === undefined ? {} : { closeAccess: fileAccess.register(root) }),\n };\n const runtime = active;\n // Listing files is advisory; opening a session only needs its folder and access ready.\n void refresh().finally(() => {\n if (!closed && active === runtime) schedule();\n });\n return stop;\n },\n };\n const beforeAgentStart: PoHeadlessHook = {\n event: 'before_agent_start',\n async handle(event, context) {\n const root = artifactRoot(context.sessionId, environment);\n const systemPrompt = typeof event.systemPrompt === 'string' ? event.systemPrompt : '';\n if (!(await prepareArtifactRoot(root))) return { systemPrompt };\n const declaration = `Session artifact folder: ${root}`;\n if (systemPrompt.includes(declaration)) return { systemPrompt };\n return {\n systemPrompt:\n `${systemPrompt}\\n\\n${declaration}\\nSave user-designated artifacts and important deliverable documents in this folder, using descriptive filenames. Keep ordinary repository source edits in their existing locations. Do not move existing documents or overwrite artifacts without the user's intent. This folder belongs only to the current session. When a message names \\`@artifact:<path>\\`, it means the file at <path> inside this folder.`.trim(),\n };\n },\n };\n const toolExecutionEnd: PoHeadlessHook = {\n event: 'tool_execution_end',\n handle(_event, context) {\n // Snapshot reads must not hold the runtime's event drain open during shutdown.\n if (active?.context.sessionId === context.sessionId) void refresh();\n },\n };\n return {\n activities: [activity],\n beforeAgentStart,\n toolExecutionEnd,\n onDispose: () => {\n closed = true;\n stop();\n return Promise.resolve();\n },\n };\n}\n","import type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactsPlugin } from '../../../../../services/artifacts';\nimport type { ArtifactStorage } from '../../../../../services/artifacts/type';\nimport { createArtifactSession } from '../../../../../services/artifactSession';\n\nexport const createArtifactServerRoot = (context: WithRoot<PoServerPluginContext, ArtifactStorage>) => {\n const storage = context.root;\n const runtime = createArtifactSession(context, storage);\n // An outer level that runs this package built the global root there, so its services never ran in this session.\n const services = context.hosted('global') ? [createArtifactsPlugin(storage)] : [];\n return { value: { ...runtime, storage }, services, activities: runtime.activities, onDispose: runtime.onDispose };\n};\nexport type ArtifactServerScope = ReturnType<typeof createArtifactServerRoot>['value'];\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createArtifactServerRoot);\n","import type { PoHubChannel } from '@agimon-ai/po-core/hubChannel';\n\nimport { artifactsChannelType, type ArtifactSnapshot } from '../../types/artifacts';\nimport { artifactRoot, listArtifacts } from '../artifactFiles';\n\nfunction snapshotOf(value: unknown): value is ArtifactSnapshot {\n if (typeof value !== 'object' || value === null) return false;\n const snapshot = value as Partial<ArtifactSnapshot>;\n return (\n Array.isArray(snapshot.items) &&\n (snapshot.error === undefined || typeof snapshot.error === 'string') &&\n (snapshot.temporaryRoot === undefined || typeof snapshot.temporaryRoot === 'string') &&\n snapshot.items.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.path === 'string' &&\n typeof item.name === 'string' &&\n typeof item.size === 'number' &&\n Number.isFinite(item.size) &&\n typeof item.modifiedAt === 'number' &&\n Number.isFinite(item.modifiedAt),\n )\n );\n}\n\nexport function createArtifactsChannel(): PoHubChannel {\n return {\n frameType: artifactsChannelType,\n start(host) {\n const sessions = new Map<string, { snapshot?: ArtifactSnapshot; unsubscribe: () => void }>();\n return {\n payloadFor(scope) {\n return sessions.get(scope.sessionId)?.snapshot;\n },\n sessionAdded(scope) {\n sessions.get(scope.sessionId)?.unsubscribe();\n const state: { snapshot?: ArtifactSnapshot; unsubscribe: () => void } = { unsubscribe: () => undefined };\n sessions.set(scope.sessionId, state);\n state.unsubscribe = host.directEvents.subscribe(\n artifactsChannelType,\n scope.sessionId,\n (snapshot) => {\n if (!snapshotOf(snapshot) || sessions.get(scope.sessionId) !== state) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n },\n { replayLatest: true },\n );\n void (async () => {\n let snapshot: ArtifactSnapshot;\n try {\n snapshot = {\n ...(await listArtifacts(artifactRoot(scope.sessionId, scope.environment ?? {}))),\n ...(scope.environment?.PO_SESSION_TEMP_DIR\n ? { temporaryRoot: scope.environment.PO_SESSION_TEMP_DIR }\n : {}),\n };\n } catch (error) {\n snapshot = {\n items: [],\n error: error instanceof Error ? error.message : 'The artifact folder could not be read.',\n };\n }\n // A live session event wins over the earlier seed read.\n if (sessions.get(scope.sessionId) !== state || state.snapshot !== undefined) return;\n state.snapshot = snapshot;\n host.publish(scope.sessionId, snapshot);\n })();\n },\n sessionRemoved(sessionId) {\n sessions.get(sessionId)?.unsubscribe();\n sessions.delete(sessionId);\n },\n close() {\n for (const state of sessions.values()) state.unsubscribe();\n sessions.clear();\n },\n };\n },\n };\n}\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createArtifactsChannel } from '../../../services/artifactChannel';\n\nexport default defineChannel(createArtifactsChannel);\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { ArtifactPreview, ArtifactSnapshot } from './artifacts';\n\nconst routes = {\n list: {\n method: 'GET',\n path: '/',\n query: ['scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactSnapshot>,\n },\n preview: {\n method: 'GET',\n path: '/preview',\n query: ['path', 'scope'],\n response: undefined as unknown as ApiResponseOf<ArtifactPreview>,\n },\n content: {\n method: 'GET',\n path: '/content',\n query: ['path', 'scope'],\n raw: true,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","import path from 'node:path';\n\nimport type { PoApi, PoApiContext } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { MAX_CONTENT_BYTES, MAX_PREVIEW_BYTES, MAX_RANGED_VIDEO_BYTES } from '../../constants/artifacts';\nimport routes from '../../types/apiRoutes';\nimport type { ArtifactPreview, ArtifactWorkflowVisibility } from '../../types/artifacts';\nimport { ArtifactAccessError, artifactRoot, listArtifacts, openArtifact, readArtifactBytes } from '../artifactFiles';\nimport type { ArtifactStorage } from '../artifacts/type';\n\nexport function createArtifactsApi(\n root: string,\n options: { temporaryRoot?: string; workflowVisible?: ArtifactWorkflowVisibility } = {},\n): Hono {\n const app = new Hono();\n const selectedRoot = (scope: string | undefined): string => {\n if (scope === undefined || scope === 'artifacts') return root;\n if (scope !== 'temporary') throw new ArtifactAccessError('Invalid file scope.', 400);\n if (!options.temporaryRoot) throw new ArtifactAccessError('Temporary files are unavailable for this session.', 404);\n return options.temporaryRoot;\n };\n app.onError((error, context) =>\n context.json(\n { error: error instanceof ArtifactAccessError ? error.message : 'The artifact could not be read.' },\n error instanceof ArtifactAccessError ? error.status : 500,\n ),\n );\n app.get(routes.list.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const snapshot = await listArtifacts(selected, selected === root ? options.workflowVisible : () => true);\n return context.json(\n { ...snapshot, ...(options.temporaryRoot ? { temporaryRoot: options.temporaryRoot } : {}) },\n snapshot.error === undefined ? 200 : 500,\n );\n });\n app.get(routes.preview.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const preview: ArtifactPreview = { path: file.path, content: '', mimeType: file.mimeType };\n if (file.stat.size > MAX_PREVIEW_BYTES) {\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n }\n const bytes = await readArtifactBytes(file.handle, MAX_PREVIEW_BYTES + 1);\n if (bytes.byteLength > MAX_PREVIEW_BYTES)\n return context.json({\n ...preview,\n unavailable: true,\n reason: 'This artifact is too large for a text preview.',\n });\n if (bytes.subarray(0, 8192).includes(0))\n return context.json({ ...preview, unavailable: true, reason: 'This artifact is binary.' });\n return context.json({ ...preview, content: new TextDecoder().decode(bytes) });\n } finally {\n await file.handle.close();\n }\n });\n app.get(routes.content.path, async (context) => {\n const selected = selectedRoot(context.req.query('scope'));\n const file = await openArtifact(\n selected,\n context.req.query('path'),\n selected === root ? options.workflowVisible : () => true,\n );\n try {\n const range = context.req.header('range');\n // Videos past the download cap (computer-use recordings) are served only in bounded ranges.\n const ranged =\n file.stat.size > MAX_CONTENT_BYTES &&\n file.mimeType.startsWith('video/') &&\n file.stat.size <= MAX_RANGED_VIDEO_BYTES &&\n range !== undefined;\n if (file.stat.size > MAX_CONTENT_BYTES && !ranged)\n throw new ArtifactAccessError('This artifact is too large to download.', 413);\n const version = `\"${file.stat.dev}-${file.stat.ino}-${file.stat.size}-${file.stat.mtimeMs}-${file.stat.ctimeMs}\"`;\n const name = encodeURIComponent(path.basename(file.path)).replace(\n /[!'()*]/gu,\n (value) => `%${value.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n const headers = new Headers({\n 'content-type': file.mimeType,\n 'content-disposition': `attachment; filename*=UTF-8''${name}`,\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"default-src 'none'; sandbox\",\n 'accept-ranges': 'bytes',\n etag: version,\n });\n const expectedVersion = context.req.header('if-match');\n if (expectedVersion !== undefined && expectedVersion !== version)\n return new Response(null, { status: 412, headers });\n let start = 0;\n let end = file.stat.size - 1;\n if (range !== undefined) {\n const match = /^bytes=(\\d*)-(\\d*)$/u.exec(range);\n if (\n !match ||\n (!match[1] && !match[2]) ||\n file.stat.size === 0 ||\n [match[1], match[2]].some((value) => value !== '' && !Number.isSafeInteger(Number(value)))\n ) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (match[1] === '') {\n const suffix = Number(match[2]);\n start = suffix > 0 ? Math.max(0, file.stat.size - suffix) : file.stat.size;\n } else {\n start = Number(match[1]);\n end = match[2] === '' ? end : Math.min(end, Number(match[2]));\n }\n if (start > end || start >= file.stat.size) {\n headers.set('content-range', `bytes */${file.stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (ranged) end = Math.min(end, start + MAX_CONTENT_BYTES - 1);\n headers.set('content-range', `bytes ${start}-${end}/${file.stat.size}`);\n }\n const bytes = await readArtifactBytes(file.handle, Math.max(0, end - start + 1), start);\n const after = await file.handle.stat();\n if (after.size !== file.stat.size || after.mtimeMs !== file.stat.mtimeMs || after.ctimeMs !== file.stat.ctimeMs)\n return new Response(null, { status: 412, headers });\n headers.set('content-length', String(bytes.byteLength));\n return new Response(bytes, { status: range === undefined ? 200 : 206, headers });\n } finally {\n await file.handle.close();\n }\n });\n return app;\n}\n\nexport function createArtifactApi(storage?: ArtifactStorage): PoApi {\n return {\n basePath: 'artifacts',\n start(context: PoApiContext) {\n if (!context.sessionId) throw new Error('Artifacts requires a session identity.');\n const app = createArtifactsApi(artifactRoot(context.sessionId, context.environment ?? {}), {\n temporaryRoot: context.environment?.PO_SESSION_TEMP_DIR,\n workflowVisible: storage?.workflowVisible,\n });\n return { fetch: (request) => app.fetch(request), close: () => undefined };\n },\n };\n}\n\nexport const api: PoApi = createArtifactApi();\n","import { defineRoute, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport { createArtifactApi } from '../../../../../../services/artifactsApi';\nimport type { ArtifactServerScope } from '../../_lib/serverRoot';\n\nexport default defineRoute(({ root }: WithRoot<PoServerPluginContext, ArtifactServerScope>) =>\n createArtifactApi(root.storage),\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.beforeAgentStart,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { ArtifactServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(\n (context: WithRoot<PoServerPluginContext, ArtifactServerScope>) => context.root.toolExecutionEnd,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootGlobal from '../src/extensions/(backend)/root.server';\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport channelArtifacts from '../src/extensions/(backend)/channel/artifacts.server';\nimport apiRoute from '../src/extensions/workspaces/sessions/(backend)/api/artifacts/route.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-artifact',\n providerOverrides: composeServerProviderOverrides(rootGlobal, rootSession),\n injects: composeRootInjects({ global: [rootGlobal], workspace: [rootGlobal], session: [rootGlobal, rootSession] }),\n global: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return [() => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]; },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n workspace: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n return {\n ...composeRootHooks(scopeGlobal),\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n services: [...(scopeGlobal.services ?? [])],\n };\n },\n session: async (context) => {\n const scopeGlobal = await context.scopeRoot('global', rootGlobal, context);\n const contextGlobal = { ...context, root: scopeGlobal.value };\n const scopeSession = await context.scopeRoot('session', rootSession, contextGlobal);\n const contextSession = { ...contextGlobal, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeGlobal, scopeSession),\n get api(): PoServerSessionPlugin['api'] { return [at(apiRoute, contextSession)]; },\n get channels(): PoServerSessionPlugin['channels'] { return defined([context.hosted('global') ? undefined : () => via({ frameType: 'artifacts' }, at(channelArtifacts, contextGlobal))]); },\n get hooks(): PoServerSessionPlugin['hooks'] { return [via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]; },\n services: [...(scopeGlobal.services ?? []), ...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeGlobal.activities ?? []), ...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/po-artifact",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.73",
|
|
4
4
|
"description": "Durable session artifacts, prompt guidance, and web/native artifact views.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -65,17 +65,17 @@
|
|
|
65
65
|
"registry": "https://registry.npmjs.org/"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@agimon-ai/po-core": "0.0.0-alpha.
|
|
69
|
-
"@agimon-ai/po-web-components": "0.0.0-alpha.
|
|
70
|
-
"@agimon-ai/po-web-security": "0.0.0-alpha.
|
|
68
|
+
"@agimon-ai/po-core": "0.0.0-alpha.74",
|
|
69
|
+
"@agimon-ai/po-web-components": "0.0.0-alpha.74",
|
|
70
|
+
"@agimon-ai/po-web-security": "0.0.0-alpha.74",
|
|
71
71
|
"@deepseek-ai/cordis": "4.0.5",
|
|
72
72
|
"hono": "4.13.13",
|
|
73
73
|
"typebox": "1.4.2"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@agimon-ai/po-build": "0.0.0-alpha.
|
|
77
|
-
"@agimon-ai/po-native-components": "0.0.0-alpha.
|
|
78
|
-
"@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.
|
|
76
|
+
"@agimon-ai/po-build": "0.0.0-alpha.74",
|
|
77
|
+
"@agimon-ai/po-native-components": "0.0.0-alpha.74",
|
|
78
|
+
"@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.74",
|
|
79
79
|
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
80
80
|
"@tanstack/react-store": "0.11.2",
|
|
81
81
|
"@tanstack/store": "0.11.2",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"vitest": "5.0.4"
|
|
93
93
|
},
|
|
94
94
|
"peerDependencies": {
|
|
95
|
-
"@agimon-ai/po-native-components": "0.0.0-alpha.
|
|
95
|
+
"@agimon-ai/po-native-components": "0.0.0-alpha.74",
|
|
96
96
|
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
97
97
|
"react-native": "0.88.0",
|
|
98
98
|
"react-native-unistyles": "^3.5.3"
|