@agimon-ai/po-artifact 0.0.0-alpha.71 → 0.0.0-alpha.72

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.
@@ -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
- await refresh();
157
- schedule();
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":"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"}
@@ -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
- await refresh();
152
- schedule();
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.71",
3
+ "version": "0.0.0-alpha.72",
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.72",
69
- "@agimon-ai/po-web-components": "0.0.0-alpha.72",
70
- "@agimon-ai/po-web-security": "0.0.0-alpha.72",
68
+ "@agimon-ai/po-core": "0.0.0-alpha.73",
69
+ "@agimon-ai/po-web-components": "0.0.0-alpha.73",
70
+ "@agimon-ai/po-web-security": "0.0.0-alpha.73",
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.72",
77
- "@agimon-ai/po-native-components": "0.0.0-alpha.72",
78
- "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.72",
76
+ "@agimon-ai/po-build": "0.0.0-alpha.73",
77
+ "@agimon-ai/po-native-components": "0.0.0-alpha.73",
78
+ "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.73",
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.72",
95
+ "@agimon-ai/po-native-components": "0.0.0-alpha.73",
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"