@ai-sdk/harness-pi 1.0.81 → 1.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/pi-remote-ops.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-sdk/harness-pi
|
|
2
2
|
|
|
3
|
+
## 1.0.83
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 00127df: fix(harness-pi): fix incorrect grep use
|
|
8
|
+
- Updated dependencies [7f50d28]
|
|
9
|
+
- @ai-sdk/harness@1.0.81
|
|
10
|
+
|
|
11
|
+
## 1.0.82
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- @ai-sdk/harness@1.0.80
|
|
16
|
+
|
|
3
17
|
## 1.0.81
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -128,7 +128,7 @@ import {
|
|
|
128
128
|
import { getAiGatewayAuthFromEnv } from "@ai-sdk/harness/utils";
|
|
129
129
|
|
|
130
130
|
// src/version.ts
|
|
131
|
-
var VERSION = true ? "1.0.
|
|
131
|
+
var VERSION = true ? "1.0.83" : "0.0.0-test";
|
|
132
132
|
|
|
133
133
|
// src/pi-auth.ts
|
|
134
134
|
var DEFAULT_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
|
|
@@ -878,7 +878,7 @@ function createPiRemoteOps(options) {
|
|
|
878
878
|
const relativeTarget = options.paths.toRelativePath(resolvedPath);
|
|
879
879
|
const targetPath = relativeTarget.startsWith("../") || path3.posix.isAbsolute(relativeTarget) ? resolvedPath : relativeTarget;
|
|
880
880
|
const flags = [
|
|
881
|
-
"-
|
|
881
|
+
"-r",
|
|
882
882
|
"-n",
|
|
883
883
|
"--binary-files=without-match",
|
|
884
884
|
...input.ignoreCase ? ["-i"] : [],
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pi-harness.ts","../src/pi-resume-state.ts","../src/pi-session.ts","../src/pi-auth.ts","../src/version.ts","../src/pi-events.ts","../src/pi-model-resolver.ts","../src/pi-paths.ts","../src/pi-remote-ops.ts","../src/pi-skills.ts","../src/pi-translate.ts","../src/pi-utils.ts","../src/pi-typebox-adapter.ts","../src/pi-workspace-vfs.ts","../src/pi-workspace-mirror.ts","../src/index.ts"],"sourcesContent":["import {\n commonTool,\n type HarnessV1,\n type HarnessV1BuiltinTool,\n} from '@ai-sdk/harness';\nimport { tool } from '@ai-sdk/provider-utils';\nimport type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\nimport { z } from 'zod/v4';\nimport type { PiAuthOptions } from './pi-auth';\nimport { piResumeStateSchema } from './pi-resume-state';\nimport { createPiSession, type PiThinkingLevel } from './pi-session';\nimport { VERSION } from './version';\n\n/**\n * Value to use in User-Agent and `x-client-app` headers.\n */\nconst PI_CLIENT_APP = `ai-sdk/harness-pi/${VERSION}`;\n\n/**\n * Configuration knobs for `createPi`. Pi runs as an in-process Node library\n * (no bridge), so there's no `port` or `startupTimeoutMs` to set.\n */\nexport type PiHarnessSettings = {\n /** Where Pi sources API keys / gateway credentials from. */\n readonly auth?: PiAuthOptions;\n /**\n * Pi model id (or name). Leaving this unset falls back to the AI Gateway\n * default when `AI_GATEWAY_API_KEY` / `VERCEL_OIDC_TOKEN` is set, and to\n * Pi's own resolution otherwise.\n */\n readonly model?: string;\n /**\n * Pi's extended-thinking budget level. Maps directly to the SDK's\n * `thinkingLevel` option on `createAgentSession`.\n */\n readonly thinkingLevel?: PiThinkingLevel;\n /**\n * Directory holding Pi's global agent config (auth.json, models.json,\n * settings.json). When omitted, a per-session temp dir is used. Pass the\n * user's agent dir (e.g. `~/.pi/agent/`) to reuse their CLI auth and\n * model settings.\n */\n readonly agentDir?: string;\n /**\n * MCP server definitions keyed by server name. Each definition uses the\n * underlying runtime's native MCP server configuration format.\n */\n readonly mcpServers?: Record<string, unknown>;\n /**\n * Trusted inline Pi extensions loaded for each harness session.\n *\n * Filesystem-discovered user and project extensions remain disabled.\n */\n readonly extensionFactories?: ReadonlyArray<ExtensionFactory>;\n};\n\nconst PI_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'read',\n toolUseKind: 'readonly',\n description: 'Read file contents.',\n inputSchema: z.object({\n file_path: z.string(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n description: 'Overwrite or create a file.',\n inputSchema: z.object({\n file_path: z.string(),\n content: z.string(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit',\n toolUseKind: 'edit',\n description: 'Edit a file by exact string replacement.',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'bash',\n toolUseKind: 'bash',\n description: 'Execute a shell command in the sandbox.',\n inputSchema: z.object({\n command: z.string(),\n timeout: z.number().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents with regex.',\n inputSchema: z.object({\n pattern: z.string(),\n path: z.string().optional(),\n glob: z.string().optional(),\n ignoreCase: z.boolean().optional(),\n literal: z.boolean().optional(),\n context: z.number().optional(),\n limit: z.number().optional(),\n }),\n }),\n glob: commonTool('glob', {\n nativeName: 'find',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern.',\n inputSchema: z.object({\n pattern: z.string(),\n path: z.string().optional(),\n limit: z.number().optional(),\n }),\n }),\n ls: {\n ...tool({\n description: 'List directory entries.',\n inputSchema: z.object({\n path: z.string().optional(),\n limit: z.number().optional(),\n }),\n outputSchema: z.unknown(),\n }),\n nativeName: 'ls',\n toolUseKind: 'readonly',\n } as HarnessV1BuiltinTool,\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nexport function createPi(\n settings: PiHarnessSettings = {},\n): HarnessV1<typeof PI_BUILTIN_TOOLS> {\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'pi',\n builtinTools: PI_BUILTIN_TOOLS,\n supportsBuiltinToolApprovals: true,\n supportsBuiltinToolFiltering: true,\n lifecycleStateSchema: piResumeStateSchema,\n doStart: async startOpts => {\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const resumeData = lifecycleState?.data as\n | { sessionFileName?: string }\n | undefined;\n\n return createPiSession({\n sessionId: startOpts.sessionId,\n sandboxSession: startOpts.sandboxSession,\n sessionWorkDir: startOpts.sessionWorkDir,\n skills: startOpts.skills ?? [],\n settings: {\n ...(settings.auth ? { auth: settings.auth } : {}),\n ...(settings.model ? { model: settings.model } : {}),\n ...(settings.thinkingLevel\n ? { thinkingLevel: settings.thinkingLevel }\n : {}),\n ...(settings.mcpServers ? { mcpServers: settings.mcpServers } : {}),\n ...(settings.extensionFactories\n ? { extensionFactories: settings.extensionFactories }\n : {}),\n },\n clientApp: PI_CLIENT_APP,\n isResume: lifecycleState != null,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n ...(resumeData?.sessionFileName\n ? { resumeSessionFileName: resumeData.sessionFileName }\n : {}),\n ...(startOpts.abortSignal\n ? { abortSignal: startOpts.abortSignal }\n : {}),\n ...(settings.agentDir ? { agentDir: settings.agentDir } : {}),\n });\n },\n };\n}\n","import { createHash } from 'node:crypto';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nconst PI_SESSION_FILE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*\\.jsonl?$/;\n\nexport function safePiSessionFileName(sessionFileName: string): string {\n if (!PI_SESSION_FILE_NAME_PATTERN.test(sessionFileName)) {\n throw new Error(`Invalid Pi session file name: ${sessionFileName}`);\n }\n return sessionFileName;\n}\n\nconst piSessionFileNameSchema = z\n .string()\n .refine(\n sessionFileName => PI_SESSION_FILE_NAME_PATTERN.test(sessionFileName),\n 'Pi sessionFileName must be a safe .jsonl or .json basename.',\n );\n\n/**\n * Schema for the adapter-specific portion of lifecycle state `data` produced\n * by Pi's resumable lifecycle methods. Carries the basename\n * (including extension) of the Pi session file. The actual session bytes live\n * in a private, session-scoped directory under sandbox HOME so they survive\n * cross-process resume without appearing in the agent workspace.\n */\nexport const piResumeStateSchema = z.looseObject({\n sessionFileName: piSessionFileNameSchema.optional(),\n});\n\nexport type PiResumeStateData = z.infer<typeof piResumeStateSchema>;\n\nexport function resolvePiPrivateSessionDirectory(input: {\n readonly sandboxHomeDir: string;\n readonly sessionWorkDir: string;\n readonly sessionId: string;\n}): string {\n const sessionKey = createHash('sha256').update(input.sessionId).digest('hex');\n const privateSessionDir = path.posix.join(\n input.sandboxHomeDir,\n '.ai-sdk',\n 'harness-pi',\n sessionKey,\n );\n const relativePath = path.posix.relative(\n input.sessionWorkDir,\n privateSessionDir,\n );\n if (\n relativePath === '' ||\n (!relativePath.startsWith('../') && !path.posix.isAbsolute(relativePath))\n ) {\n throw new Error(\n `Pi private session directory ${JSON.stringify(privateSessionDir)} must be outside sessionWorkDir ${JSON.stringify(input.sessionWorkDir)}.`,\n );\n }\n return privateSessionDir;\n}\n\nfunction resolveContainedHostPath(input: {\n readonly baseDir: string;\n readonly sessionFileName: string;\n}): string {\n const baseDir = path.resolve(input.baseDir);\n const filePath = path.resolve(\n baseDir,\n safePiSessionFileName(input.sessionFileName),\n );\n const relativePath = path.relative(baseDir, filePath);\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n path.isAbsolute(relativePath)\n ) {\n throw new Error(`Invalid Pi session file name: ${input.sessionFileName}`);\n }\n return filePath;\n}\n\nfunction resolveContainedSandboxPath(input: {\n readonly privateSessionDir: string;\n readonly sessionFileName: string;\n}): string {\n const sessionDir = path.posix.resolve(input.privateSessionDir);\n const filePath = path.posix.resolve(\n sessionDir,\n safePiSessionFileName(input.sessionFileName),\n );\n const relativePath = path.posix.relative(sessionDir, filePath);\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n path.posix.isAbsolute(relativePath)\n ) {\n throw new Error(`Invalid Pi session file name: ${input.sessionFileName}`);\n }\n return filePath;\n}\n\n/**\n * Copy the Pi session file from the host's local mirror to private sandbox\n * state. Called during resumable lifecycle methods so the session survives a\n * sandbox snapshot or a process handoff.\n */\nexport async function persistSessionFileToSandbox(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly privateSessionDir: string;\n readonly hostSessionDir: string;\n readonly sessionFileName: string;\n readonly abortSignal?: AbortSignal;\n}): Promise<void> {\n const hostPath = resolveContainedHostPath({\n baseDir: args.hostSessionDir,\n sessionFileName: args.sessionFileName,\n });\n const content = await readFile(hostPath);\n const remotePath = resolveContainedSandboxPath({\n privateSessionDir: args.privateSessionDir,\n sessionFileName: args.sessionFileName,\n });\n await args.sandbox.writeBinaryFile({\n path: remotePath,\n content,\n ...(args.abortSignal ? { abortSignal: args.abortSignal } : {}),\n });\n}\n\n/**\n * Pull a previously persisted Pi session file from the sandbox into a fresh\n * local mirror dir. Called during `doStart` on the resume path before Pi is\n * initialised. Returns the absolute path of the local session file or\n * `undefined` if the sandbox copy is missing.\n */\nexport async function pullSessionFileFromSandbox(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly privateSessionDir: string;\n readonly hostSessionDir: string;\n readonly sessionFileName: string;\n readonly abortSignal?: AbortSignal;\n}): Promise<string | undefined> {\n const remotePath = resolveContainedSandboxPath({\n privateSessionDir: args.privateSessionDir,\n sessionFileName: args.sessionFileName,\n });\n const bytes = await args.sandbox.readBinaryFile({\n path: remotePath,\n ...(args.abortSignal ? { abortSignal: args.abortSignal } : {}),\n });\n if (bytes == null) return undefined;\n await mkdir(args.hostSessionDir, { recursive: true });\n const hostPath = resolveContainedHostPath({\n baseDir: args.hostSessionDir,\n sessionFileName: args.sessionFileName,\n });\n await writeFile(hostPath, bytes);\n return hostPath;\n}\n","import {\n createAgentSession,\n DefaultResourceLoader,\n defineTool,\n ModelRegistry,\n ModelRuntime,\n SessionManager,\n SettingsManager,\n type AgentSession,\n type AgentToolResult,\n type ExtensionFactory,\n type Skill,\n type ToolDefinition,\n} from '@earendil-works/pi-coding-agent';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { Type } from 'typebox';\nimport {\n HarnessCapabilityUnsupportedError,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnOptions,\n type HarnessV1ContinueTurnState,\n type HarnessV1PromptControl,\n type HarnessV1PromptTurnOptions,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n type HarnessV1ToolSpec,\n} from '@ai-sdk/harness';\nimport {\n getRestrictedSandboxSession,\n resolveSandboxHomeDir,\n} from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport {\n registerPiProviders,\n resolvePiEnv,\n type PiAuthOptions,\n} from './pi-auth';\nimport { getPiTerminalError, parseNativeEvent } from './pi-events';\nimport { createPiModelResolver } from './pi-model-resolver';\nimport { createPiPathMapper } from './pi-paths';\nimport { createPiRemoteOps, type PiRemoteOps } from './pi-remote-ops';\nimport { writePiSkills } from './pi-skills';\nimport {\n persistSessionFileToSandbox,\n pullSessionFileFromSandbox,\n resolvePiPrivateSessionDirectory,\n safePiSessionFileName,\n} from './pi-resume-state';\nimport {\n createPiTranslatorState,\n finishPiApprovalStep,\n translatePiEvent,\n type PiTranslatorState,\n} from './pi-translate';\nimport { toolSpecToTypeBoxParameters } from './pi-typebox-adapter';\nimport {\n extractUserText,\n safePiMetadataSegment,\n serializeToolOutput,\n} from './pi-utils';\nimport { PiWorkspaceVfs } from './pi-workspace-vfs';\nimport { syncHostWorkspaceFromSandbox } from './pi-workspace-mirror';\n\nconst HARNESS_ID = 'pi';\n\n/*\n * pi-mcp-adapter publishes TypeScript source as its package entry point. A\n * non-literal specifier keeps the repository type-check focused on this\n * package's compatibility boundary instead of compiling dependency internals.\n */\nconst PI_MCP_ADAPTER_PACKAGE: string = 'pi-mcp-adapter';\n\ntype PiMcpAdapterModule = {\n createMcpAdapter(options: {\n config: {\n mcpServers: Record<string, unknown>;\n settings: {\n directTools: boolean;\n toolPrefix: string;\n disableProxyTool: boolean;\n };\n };\n }): ExtensionFactory;\n};\n\n/*\n * Pi runs in this Node process, not behind an attachable in-sandbox bridge.\n * During a tool approval pause the Pi turn is still alive and blocked on the\n * custom tool promise, so detach must park that live session for the next\n * same-process resume instead of stopping it and resolving the promise as an\n * error. Cross-process resume still falls back to the persisted session file.\n */\nconst parkedPiSessions = new Map<string, HarnessV1Session>();\n\n/**\n * Whether a discovered resource path belongs to a specific directory.\n */\nfunction isWithinDirectory(parent: string, child: string): boolean {\n const rel = path.relative(parent, child);\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n}\n\n/**\n * Whether a discovered resource path belongs to the session workspace — either\n * the sandbox-side working directory the model sees (`sessionWorkDir`) or its\n * host-side mirror (`hostWorkDir`).\n */\nfunction isWithinWorkspace(\n candidate: string,\n sessionWorkDir: string,\n hostWorkDir: string,\n): boolean {\n return (\n isWithinDirectory(sessionWorkDir, candidate) ||\n isWithinDirectory(hostWorkDir, candidate)\n );\n}\n\nfunction createHarnessPiSkills({\n skills,\n sandboxSkillRootDir,\n}: {\n skills: ReadonlyArray<HarnessV1Skill>;\n sandboxSkillRootDir: string;\n}): Skill[] {\n return skills.map(skill => {\n const name = safePiMetadataSegment(skill.name, 'skill');\n const baseDir = path.posix.join(sandboxSkillRootDir, name);\n const filePath = path.posix.join(baseDir, 'SKILL.md');\n return {\n name: skill.name,\n description: skill.description,\n filePath,\n baseDir,\n sourceInfo: {\n path: filePath,\n source: 'harness',\n scope: 'temporary',\n origin: 'top-level',\n baseDir,\n },\n disableModelInvocation: false,\n };\n });\n}\n\nconst PI_NATIVE_BUILTIN_NAMES = [\n 'read',\n 'write',\n 'edit',\n 'bash',\n 'grep',\n 'find',\n 'ls',\n] as const;\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n find: 'glob',\n};\n\nconst PUBLIC_TO_NATIVE: Readonly<\n Record<string, (typeof PI_NATIVE_BUILTIN_NAMES)[number]>\n> = {\n read: 'read',\n write: 'write',\n edit: 'edit',\n bash: 'bash',\n grep: 'grep',\n glob: 'find',\n ls: 'ls',\n};\n\nconst PI_NATIVE_TOOL_KINDS: Readonly<\n Record<(typeof PI_NATIVE_BUILTIN_NAMES)[number], 'readonly' | 'edit' | 'bash'>\n> = {\n read: 'readonly',\n write: 'edit',\n edit: 'edit',\n bash: 'bash',\n grep: 'readonly',\n find: 'readonly',\n ls: 'readonly',\n};\n\nfunction resolveActivePiBuiltinNames(\n toolFiltering: HarnessV1BuiltinToolFiltering | undefined,\n): ReadonlyArray<(typeof PI_NATIVE_BUILTIN_NAMES)[number]> {\n if (toolFiltering == null) return PI_NATIVE_BUILTIN_NAMES;\n if (toolFiltering.mode === 'allow') {\n return toolFiltering.toolNames\n .map(name => PUBLIC_TO_NATIVE[name])\n .filter(\n (name): name is (typeof PI_NATIVE_BUILTIN_NAMES)[number] =>\n name != null,\n );\n }\n return PI_NATIVE_BUILTIN_NAMES.filter(\n native =>\n !toolFiltering.toolNames.includes(NATIVE_TO_COMMON[native] ?? native),\n );\n}\n\nexport type PiThinkingLevel =\n | 'off'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh';\n\nexport interface PiSessionSettings {\n readonly auth?: PiAuthOptions;\n readonly model?: string;\n readonly thinkingLevel?: PiThinkingLevel;\n readonly mcpServers?: Record<string, unknown>;\n readonly extensionFactories?: ReadonlyArray<ExtensionFactory>;\n}\n\nexport interface CreatePiSessionInput {\n readonly sessionId: string;\n readonly sandboxSession: HarnessV1NetworkSandboxSession | SandboxSession;\n readonly sessionWorkDir: string;\n readonly skills: ReadonlyArray<HarnessV1Skill>;\n readonly settings: PiSessionSettings;\n readonly clientApp: string;\n readonly isResume: boolean;\n readonly permissionMode?: HarnessV1PermissionMode;\n readonly builtinToolFiltering?: HarnessV1BuiltinToolFiltering;\n readonly resumeSessionFileName?: string;\n readonly abortSignal?: AbortSignal;\n /**\n * Directory holding Pi's global agent config (auth.json, models.json,\n * settings.json). When omitted, a per-session temp dir is used (the\n * harness cannot reuse existing CLI logins). Pass the user's agent dir\n * (e.g. `~/.pi/agent/`) to reuse their CLI auth and model settings.\n */\n readonly agentDir?: string;\n}\n\ninterface PendingToolResult {\n resolve: (value: unknown) => void;\n}\n\ninterface PendingToolApproval {\n resolve: (value: { approved: boolean; reason?: string }) => void;\n}\n\ninterface ActivePiTurn {\n readonly token: object;\n readonly done: Promise<void>;\n readonly abort: (reason?: unknown) => Promise<void>;\n}\n\n/**\n * A host tool call recorded in the restored journal without a matching tool\n * result — it was awaiting host input (typically a tool approval) when the\n * process that owned the live turn went away.\n */\ninterface DanglingHostToolCall {\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\n/**\n * Barrier that holds a cross-process rerun until the framework has\n * re-delivered the results for every journal-pending host tool call.\n */\ninterface DeferredRerunBarrier {\n /** toolCallId -> toolName still awaiting a submitted result. */\n readonly awaiting: Map<string, string>;\n readonly startRerun: () => void;\n /** Settle the barrier without running: resolves `done` cleanly when no\n * reason is given, rejects it otherwise. No-op once the rerun started. */\n readonly cancel: (reason?: unknown) => void;\n}\n\nexport async function createPiSession(\n input: CreatePiSessionInput,\n): Promise<HarnessV1Session> {\n if (input.isResume) {\n const parkedSession = parkedPiSessions.get(input.sessionId);\n if (parkedSession) {\n parkedPiSessions.delete(input.sessionId);\n return {\n ...parkedSession,\n isResume: true,\n };\n }\n }\n\n // Host-side mirror layout under tmpdir. Replace path-separator characters\n // that would otherwise turn a session id like `2026-05-29T17:54:27` into a\n // sub-directory tree on disk.\n const safeSessionId = input.sessionId.replace(/[\\\\/: ]/g, '-');\n const hostRoot = path.join(tmpdir(), 'ai-sdk-harness', 'pi', safeSessionId);\n const hostWorkDir = path.join(hostRoot, 'workspace');\n const hostAgentDir = path.join(hostRoot, 'agent');\n const hostSessionDir = path.join(hostRoot, 'sessions');\n\n // Pi runs in this host process but must behave as though it lives in the\n // sandbox workspace: its working directory is the real `sessionWorkDir`\n // (where `setup()` clones and where the sandbox-backed tools operate), so the\n // paths Pi advertises to the model — most notably the \"Current working\n // directory\" line in its system prompt — resolve inside the sandbox. The\n // workspace VFS maps that sandbox path to the host-side mirror so Pi's own\n // `fs`-based resource loading (`.pi/`, `AGENTS.md`) still works on the host.\n // `sessionWorkDir` is a sandbox path (e.g. `/vercel/sandbox/...`) that does\n // not exist on the host, so it is a safe, collision-free VFS mount point.\n const sessionWorkDir = input.sessionWorkDir;\n\n await mkdir(hostWorkDir, { recursive: true });\n await mkdir(hostAgentDir, { recursive: true });\n await mkdir(hostSessionDir, { recursive: true });\n\n const toolSafeSandboxSession = getRestrictedSandboxSession(\n input.sandboxSession,\n );\n const sandboxHomeDir = await resolveSandboxHomeDir({\n sandbox: toolSafeSandboxSession,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n const privateSessionDir = resolvePiPrivateSessionDirectory({\n sandboxHomeDir,\n sessionWorkDir: input.sessionWorkDir,\n sessionId: input.sessionId,\n });\n const permissionMode = input.permissionMode ?? 'allow-all';\n let sandboxSkillRootDir: string | undefined;\n let harnessSkills: Skill[] = [];\n\n // Materialise harness-provided skills into sandbox HOME, not the workspace.\n if (input.skills.length > 0) {\n sandboxSkillRootDir = path.posix.join(sandboxHomeDir, '.agents', 'skills');\n harnessSkills = createHarnessPiSkills({\n skills: input.skills,\n sandboxSkillRootDir,\n });\n await writePiSkills({\n sandbox: toolSafeSandboxSession,\n sandboxHomeDir,\n skills: input.skills,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n }\n\n // On resume: pull the Pi session file out of the sandbox into the fresh\n // host mirror so SessionManager.open can read it.\n let resumeSessionFilePath: string | undefined;\n if (input.isResume && input.resumeSessionFileName) {\n const resumeSessionFileName = safePiSessionFileName(\n input.resumeSessionFileName,\n );\n resumeSessionFilePath = await pullSessionFileFromSandbox({\n sandbox: toolSafeSandboxSession,\n privateSessionDir,\n hostSessionDir,\n sessionFileName: resumeSessionFileName,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n }\n\n // Snapshot sandbox state into the host mirror BEFORE the VFS goes live so\n // Pi sees the workspace as soon as it boots.\n await syncHostWorkspaceFromSandbox({\n sandbox: toolSafeSandboxSession,\n sandboxWorkDir: input.sessionWorkDir,\n hostWorkDir,\n });\n\n // Mount only the workspace: the model's view of the workspace lives at\n // `sessionWorkDir` and is backed by `hostWorkDir`. The agent and session\n // directories stay on the real host filesystem (below) — they are host-only\n // Pi state (auth, model registry, session journal) that must never surface\n // in the sandbox or the workspace mirror.\n const workspaceVfs = new PiWorkspaceVfs();\n workspaceVfs.mount(hostWorkDir, sessionWorkDir);\n\n const paths = createPiPathMapper({\n hostWorkDir,\n sandboxWorkDir: sessionWorkDir,\n readableRoots: sandboxSkillRootDir\n ? [{ sandboxDir: sandboxSkillRootDir }]\n : [],\n });\n\n // Pi auth + model registry are global to this Pi session. These live on the\n // real host filesystem, never in the sandbox/workspace.\n // When `agentDir` is provided, use it instead so the harness can reuse\n // existing CLI logins and model/settings config.\n const agentDir = input.agentDir ?? hostAgentDir;\n const modelRuntime = await ModelRuntime.create({\n authPath: path.join(agentDir, 'auth.json'),\n modelsPath: path.join(agentDir, 'models.json'),\n allowModelNetwork: false,\n });\n const modelRegistry = new ModelRegistry(modelRuntime);\n const settingsManager =\n input.agentDir != null\n ? SettingsManager.create(hostWorkDir, agentDir)\n : SettingsManager.inMemory();\n\n // Run-scoped env (for the model resolver's gateway fallback heuristic).\n const resolverEnv = resolvePiEnv({\n options: input.settings.auth,\n env: process.env,\n });\n await registerPiProviders({\n options: input.settings.auth,\n resolvedEnv: resolverEnv,\n registries: {\n modelRegistry,\n modelRuntime,\n },\n clientApp: input.clientApp,\n });\n const resolveModel = createPiModelResolver({\n modelRegistry,\n env: resolverEnv,\n });\n // Resolve once: deterministic given the configured model. This is the Pi\n // `Model` object handed to `createAgentSession`.\n const resolvedModel = resolveModel(input.settings.model);\n const mcpServers = resolvePiMcpServers({\n mcpServers: input.settings.mcpServers,\n });\n const hasMcpServers = Object.keys(mcpServers).length > 0;\n\n let sessionInstructions: string | undefined;\n\n /*\n * Configured MCP servers are served by an inline Pi extension, so they share\n * the extension runtime with the caller-supplied factories: both are loaded\n * by the resource loader below and both are subject to the reload handling\n * that keeps the active runtime alive across resource-only reloads.\n */\n const extensionFactories: ExtensionFactory[] = [\n ...(input.settings.extensionFactories ?? []),\n ];\n if (hasMcpServers) {\n const { createMcpAdapter } = (await import(\n PI_MCP_ADAPTER_PACKAGE\n )) as PiMcpAdapterModule;\n extensionFactories.push(\n createMcpAdapter({\n config: {\n mcpServers,\n settings: {\n directTools: true,\n toolPrefix: 'mcp',\n disableProxyTool: true,\n },\n },\n }),\n );\n }\n const hasExtensionFactories = extensionFactories.length > 0;\n let preserveExtensionsResult = false;\n let currentExtensionsResult:\n | ReturnType<DefaultResourceLoader['getExtensions']>\n | undefined;\n\n const resourceLoader = new DefaultResourceLoader({\n cwd: sessionWorkDir,\n agentDir: hostAgentDir,\n settingsManager,\n appendSystemPromptOverride: () =>\n sessionInstructions ? [sessionInstructions] : [],\n extensionFactories,\n ...(hasExtensionFactories\n ? {\n // DefaultResourceLoader invokes inline factories on every reload.\n // Resource-only reloads retain the active extension runtime, while a\n // genuine Pi session rebuild is allowed to replace that runtime.\n extensionsOverride: extensions => {\n if (preserveExtensionsResult && currentExtensionsResult != null) {\n return currentExtensionsResult;\n }\n currentExtensionsResult = extensions;\n return extensions;\n },\n }\n : {}),\n // Pi runs in the host process, so its default resource discovery reaches\n // the host developer's personal config (`~/.pi/agent/*`, `~/.agents/*`).\n // The harness exposes only explicitly supplied inline extension factories;\n // disable filesystem extension discovery entirely to avoid loading and\n // executing a host developer's personal or project Pi extensions inside\n // the server process. Themes and prompt templates stay disabled. Skills\n // are kept but filtered to workspace project skills plus harness-provided\n // skills whose files live in sandbox HOME.\n noExtensions: true,\n noThemes: true,\n noPromptTemplates: true,\n skillsOverride: base => ({\n ...base,\n skills: [\n ...base.skills.filter(skill =>\n isWithinWorkspace(skill.filePath, sessionWorkDir, hostWorkDir),\n ),\n ...harnessSkills,\n ],\n }),\n });\n await resourceLoader.reload();\n\n async function reloadResourcesOnly(): Promise<void> {\n if (!hasExtensionFactories) {\n await resourceLoader.reload();\n return;\n }\n\n const factories = extensionFactories.splice(0);\n preserveExtensionsResult = true;\n try {\n await resourceLoader.reload();\n } finally {\n preserveExtensionsResult = false;\n extensionFactories.push(...factories);\n }\n }\n\n // Per-session mutable state we hold across prompts.\n let piSession: AgentSession | undefined;\n let unsubscribe: (() => void) | undefined;\n let lastToolsSignature: string | undefined;\n let sessionFileName: string | undefined;\n let stopped = false;\n /*\n * Set by `doSuspendTurn` before it aborts the in-flight host turn at a slice\n * boundary. The turn's catch settles silently when this is set, so the stream\n * closes cleanly (no spurious `error` chunk) — the next slice rerun-continues\n * from the persisted journal.\n */\n let suspending = false;\n const pendingToolResults = new Map<string, PendingToolResult>();\n const pendingToolApprovals = new Map<string, PendingToolApproval>();\n /*\n * Results the framework submitted for journal-pending (dangling) host tool\n * calls while no live turn held a promise for them — the cross-process\n * continuation path. They are written into the restored journal before the\n * rerun (or on suspend/stop, so a later resume still sees them).\n */\n const deliveredDanglingResults = new Map<\n string,\n { toolName: string; output: unknown; isError: boolean }\n >();\n let restoredSessionManager:\n | ReturnType<typeof SessionManager.open>\n | undefined;\n let deferredRerun: DeferredRerunBarrier | undefined;\n\n // Emit channel set at the start of every doPromptTurn and cleared on end.\n let currentEmit: ((part: HarnessV1StreamPart) => void) | undefined;\n let translatorState: PiTranslatorState | undefined;\n let activeTurn: ActivePiTurn | undefined;\n /*\n * Compaction parts produced while no turn is active. Pi's `compact()` aborts\n * the current turn before it summarizes, so a manually triggered compaction\n * (and any compaction that lands between turns) emits its `compaction_end`\n * after `currentEmit` has been cleared. Buffer those parts and flush them on\n * the next turn's stream so the observation is not lost. Auto-compaction that\n * runs mid-turn still emits inline via `currentEmit`.\n */\n const pendingCompactionParts: HarnessV1StreamPart[] = [];\n\n async function applySessionInstructions(\n instructions: string | undefined,\n ): Promise<void> {\n if (instructions === sessionInstructions) return;\n sessionInstructions = instructions;\n await reloadResourcesOnly();\n piSession?.setActiveToolsByName(piSession.getActiveToolNames());\n }\n\n const remoteOps = createPiRemoteOps({\n sandbox: toolSafeSandboxSession,\n paths,\n onFileChange: (event, relPath) => {\n currentEmit?.({ type: 'file-change', event, path: relPath });\n },\n });\n\n function settlePendingToolResults(reason: string): void {\n for (const pending of pendingToolResults.values()) {\n pending.resolve({ error: reason });\n }\n pendingToolResults.clear();\n }\n\n function settlePendingToolApprovals(reason: string): void {\n for (const pending of pendingToolApprovals.values()) {\n pending.resolve({ approved: false, reason });\n }\n pendingToolApprovals.clear();\n }\n\n async function persistSessionFile(): Promise<void> {\n if (!sessionFileName) return;\n await persistSessionFileToSandbox({\n sandbox: toolSafeSandboxSession,\n privateSessionDir,\n hostSessionDir,\n sessionFileName,\n });\n }\n\n function getRestoredSessionManager():\n | ReturnType<typeof SessionManager.open>\n | undefined {\n if (resumeSessionFilePath == null) return undefined;\n restoredSessionManager ??= SessionManager.open(\n resumeSessionFilePath,\n hostSessionDir,\n sessionWorkDir,\n );\n return restoredSessionManager;\n }\n\n /*\n * Host tool calls in the restored journal that never received a result on\n * the active branch. These are the calls that were blocked on host input\n * (typically a tool approval) when the process owning the live turn exited;\n * the framework re-delivers their results via `submitToolResult` right after\n * `doContinueTurn` returns. Only meaningful before the first rebuild of a\n * resumed session — once a Pi session is live, pending host input is held as\n * in-process promises instead.\n */\n function findDanglingHostToolCalls(\n userTools: ReadonlyArray<HarnessV1ToolSpec>,\n ): DanglingHostToolCall[] {\n if (piSession != null || resumeSessionFilePath == null) return [];\n const hostToolNames = new Set(userTools.map(tool => tool.name));\n if (hostToolNames.size === 0) return [];\n const journal = getRestoredSessionManager();\n if (journal == null) return [];\n const messages = journal.buildSessionContext().messages;\n /*\n * Results already delivered by a previous continuation of this session\n * count as resolved even though they are not in the journal yet — the\n * framework has marked them settled and will never re-deliver them, so a\n * new barrier must not wait on them (it would deadlock the turn). They\n * are injected into the journal before the rerun.\n */\n const resolvedToolCallIds = new Set<string>(\n deliveredDanglingResults.keys(),\n );\n for (const message of messages) {\n if (message.role === 'toolResult') {\n resolvedToolCallIds.add(message.toolCallId);\n }\n }\n const dangling: DanglingHostToolCall[] = [];\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n /*\n * Pi's message transform drops errored/aborted assistant messages from\n * the LLM context entirely, so their tool calls are not awaiting\n * results — the model retries from the last valid state instead.\n */\n if (message.stopReason === 'error' || message.stopReason === 'aborted') {\n continue;\n }\n for (const block of message.content) {\n if (\n block.type === 'toolCall' &&\n hostToolNames.has(block.name) &&\n !resolvedToolCallIds.has(block.id)\n ) {\n dangling.push({ toolCallId: block.id, toolName: block.name });\n }\n }\n }\n return dangling;\n }\n\n /*\n * A result submitted while no live turn holds a pending promise for its\n * toolCallId. On the cross-process continuation path this is the framework\n * re-delivering the caller's tool-approval/tool-result continuation for a\n * journal-pending call; stash it for injection and release the rerun once\n * every dangling call has its result. Results for ids that are neither live\n * nor journal-pending have nowhere to go and are dropped, as before.\n */\n function acceptDanglingHostToolResult(args: {\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }): void {\n const barrier = deferredRerun;\n const toolName = barrier?.awaiting.get(args.toolCallId);\n if (barrier == null || toolName == null) return;\n barrier.awaiting.delete(args.toolCallId);\n deliveredDanglingResults.set(args.toolCallId, {\n toolName,\n output: args.output,\n isError: args.isError ?? false,\n });\n if (barrier.awaiting.size === 0) {\n barrier.startRerun();\n }\n }\n\n /*\n * Write delivered dangling-call results into the restored journal so the\n * rerun's context carries the real outputs — without this, Pi's message\n * transform synthesizes an error result (\"No result provided\") for each\n * dangling call and the model continues as if the tool never answered. The\n * serialized text matches what a live turn would have produced\n * (`asPiToolResult(serializeToolOutput(...))`), so the model sees the same\n * bytes either way.\n */\n function appendDeliveredHostToolResults(): boolean {\n if (deliveredDanglingResults.size === 0 || resumeSessionFilePath == null) {\n return false;\n }\n const journal = getRestoredSessionManager();\n if (journal == null) return false;\n for (const [toolCallId, delivered] of deliveredDanglingResults) {\n journal.appendMessage({\n role: 'toolResult',\n toolCallId,\n toolName: delivered.toolName,\n content: [\n { type: 'text', text: serializeToolOutput(delivered.output) },\n ],\n isError: delivered.isError,\n timestamp: Date.now(),\n });\n }\n deliveredDanglingResults.clear();\n /*\n * The journal on disk now differs from the copy in the sandbox. Make sure\n * the lifecycle persistence knows which file to push back even when no\n * turn ever rebuilt the Pi session in this process (e.g. a suspend that\n * lands while the rerun is still held back).\n */\n if (!sessionFileName) {\n sessionFileName = safePiSessionFileName(\n path.basename(resumeSessionFilePath),\n );\n }\n return true;\n }\n\n /*\n * Cross-process continuation of a turn that paused on host input: the\n * restored journal ends with host tool calls that have no results, and the\n * framework re-delivers those results through `control.submitToolResult`\n * (with the original tool-call ids) immediately after this call returns.\n * Starting the rerun right away would race that delivery — the rerun's\n * context would resolve the dangling calls as synthetic empty results and\n * the submitted outputs would be dropped. Hold the rerun until every\n * dangling call's result has arrived, write the results into the journal,\n * and only then re-drive the turn.\n *\n * If the caller resumes without supplying all continuations, the turn stays\n * parked awaiting the remaining host input — the same behaviour as the\n * in-process path, where the live turn stays blocked on its tool promises.\n */\n function deferRerunUntilHostToolResults(\n danglingCalls: ReadonlyArray<DanglingHostToolCall>,\n continueOpts: HarnessV1ContinueTurnOptions,\n ): HarnessV1PromptControl {\n /*\n * A previous continuation may have ended while its rerun was still held\n * back (e.g. it paused again awaiting a tool-result continuation). Close\n * that turn's control cleanly before installing the new barrier.\n */\n deferredRerun?.cancel();\n\n let resolveDone!: () => void;\n let rejectDone!: (error: unknown) => void;\n const done = new Promise<void>((resolve, reject) => {\n resolveDone = resolve;\n rejectDone = reject;\n });\n let settled = false;\n\n const startRerun = () => {\n if (settled) return;\n settled = true;\n deferredRerun = undefined;\n void (async () => {\n try {\n // `runTurn` injects the delivered results into the journal before\n // rebuilding the Pi session from it.\n const control = await runTurn({\n text: '',\n tools: continueOpts.tools ?? [],\n instructions: continueOpts.instructions,\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n await control.done;\n resolveDone();\n } catch (error) {\n rejectDone(error);\n }\n })();\n };\n\n const cancel = (reason?: unknown) => {\n if (settled) return;\n settled = true;\n deferredRerun = undefined;\n if (reason == null) {\n resolveDone();\n } else {\n rejectDone(reason);\n }\n };\n\n deferredRerun = {\n awaiting: new Map(\n danglingCalls.map(call => [call.toolCallId, call.toolName]),\n ),\n startRerun,\n cancel,\n };\n\n const abortBarrier = () => {\n cancel(\n continueOpts.abortSignal?.reason ??\n new Error(\n 'Pi turn was aborted before its host tool results were delivered.',\n ),\n );\n };\n if (continueOpts.abortSignal?.aborted) {\n abortBarrier();\n } else {\n continueOpts.abortSignal?.addEventListener('abort', abortBarrier, {\n once: true,\n });\n }\n\n return createPromptControl({\n done,\n abortSignal: continueOpts.abortSignal,\n });\n }\n\n function createPromptControl(input: {\n done: Promise<void>;\n abortSignal?: AbortSignal;\n abort?: (reason?: unknown) => Promise<void>;\n }): HarnessV1PromptControl {\n const abortHandler = () => {\n void input.abort?.(input.abortSignal?.reason);\n };\n if (input.abortSignal) {\n if (input.abortSignal.aborted) {\n abortHandler();\n } else {\n input.abortSignal.addEventListener('abort', abortHandler, {\n once: true,\n });\n }\n void input.done.then(\n () => {\n input.abortSignal?.removeEventListener('abort', abortHandler);\n },\n () => {\n input.abortSignal?.removeEventListener('abort', abortHandler);\n },\n );\n }\n\n return {\n async submitToolResult(args) {\n const pending = pendingToolResults.get(args.toolCallId);\n if (!pending) {\n acceptDanglingHostToolResult(args);\n return;\n }\n pendingToolResults.delete(args.toolCallId);\n /*\n * Preserve the original output so the result projection can surface it\n * unchanged. The tool handler stringifies the output for the runtime\n * (so the model reads it), and Pi echoes that text back — without this\n * the consumer-facing result would be the serialized string instead of\n * the original object.\n */\n translatorState?.hostToolResults.set(args.toolCallId, args.output);\n pending.resolve(args.output);\n },\n async submitToolApproval(args) {\n const pending = pendingToolApprovals.get(args.approvalId);\n if (!pending) return;\n pendingToolApprovals.delete(args.approvalId);\n pending.resolve({\n approved: args.approved,\n reason: args.reason,\n });\n },\n async submitUserMessage(text) {\n if (piSession == null) {\n throw new Error('Pi has no active runtime session to steer.');\n }\n await piSession.steer(text);\n },\n done: input.done,\n };\n }\n\n async function requestBuiltinToolApproval(args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }): Promise<{ approved: boolean; reason?: string }> {\n if (\n !piBuiltinToolRequiresApproval({\n permissionMode,\n kind: PI_NATIVE_TOOL_KINDS[args.nativeName],\n })\n ) {\n return { approved: true };\n }\n currentEmit?.({\n type: 'tool-approval-request',\n approvalId: args.toolCallId,\n toolCallId: args.toolCallId,\n });\n if (translatorState) {\n for (const part of finishPiApprovalStep(\n translatorState,\n args.toolCallId,\n )) {\n currentEmit?.(part);\n }\n }\n return new Promise(resolve => {\n pendingToolApprovals.set(args.toolCallId, { resolve });\n });\n }\n\n function buildToolDefinitions(userTools: ReadonlyArray<HarnessV1ToolSpec>): {\n customTools: ToolDefinition[];\n builtinNames: string[];\n } {\n const builtinNames = resolveActivePiBuiltinNames(\n input.builtinToolFiltering,\n );\n const customTools: ToolDefinition[] = [\n ...builtinNames.map(native =>\n buildBuiltinToolDefinition({\n native,\n remoteOps,\n requestApproval: requestBuiltinToolApproval,\n }),\n ),\n ...userTools.map(spec =>\n buildUserToolDefinition(spec, pendingToolResults),\n ),\n ];\n return {\n customTools,\n builtinNames: [...builtinNames],\n };\n }\n\n async function disposePiSession(): Promise<void> {\n unsubscribe?.();\n unsubscribe = undefined;\n\n const session = piSession;\n piSession = undefined;\n if (!session) return;\n\n if (hasMcpServers) {\n await session.reload().catch(() => {});\n }\n session.dispose();\n }\n\n async function rebuildPiSession(\n userTools: ReadonlyArray<HarnessV1ToolSpec>,\n isFirstBuild: boolean,\n ): Promise<boolean> {\n let resourcesReloaded = false;\n if (piSession) {\n await disposePiSession();\n // Original adapter waits 25 ms here to let Pi's teardown microtasks\n // settle before the next createAgentSession. Port verbatim.\n // TODO(pi-0.77): verify the race still exists; original SDK had a\n // teardown microtask the host needed to wait on.\n await new Promise(resolve => setTimeout(resolve, 25));\n if (hasExtensionFactories) {\n // dispose() invalidates Pi's current extension runtime, so a replacement\n // AgentSession needs factories to create a fresh runtime before build.\n await resourceLoader.reload();\n resourcesReloaded = true;\n }\n }\n\n const { customTools, builtinNames } = buildToolDefinitions(userTools);\n const toolNames = customTools.map(t => t.name);\n\n // SessionManager: open the resumed file on the first build of a resumed\n // session; create fresh otherwise.\n const sessionManager =\n isFirstBuild && resumeSessionFilePath\n ? getRestoredSessionManager()!\n : SessionManager.create(sessionWorkDir, hostSessionDir);\n\n const { session } = await createAgentSession({\n cwd: sessionWorkDir,\n agentDir: hostAgentDir,\n modelRuntime,\n sessionManager,\n settingsManager,\n resourceLoader,\n customTools,\n ...(hasMcpServers\n ? { noTools: 'builtin' as const }\n : { tools: toolNames }),\n ...(input.settings.thinkingLevel\n ? { thinkingLevel: input.settings.thinkingLevel }\n : {}),\n ...(resolvedModel ? { model: resolvedModel } : {}),\n });\n piSession = session;\n if (hasMcpServers) {\n await piSession.bindExtensions({ mode: 'print' });\n }\n\n // Pick up the actual session file path so doStop can persist it. Pi\n // 0.77 emits `.jsonl` files; older builds used `.json`. Persist the\n // basename verbatim — including the extension — so the resume path can\n // round-trip it without guessing the extension.\n const candidatePath = sessionManager.getSessionFile();\n if (candidatePath) {\n sessionFileName = safePiSessionFileName(path.basename(candidatePath));\n }\n\n translatorState = createPiTranslatorState({\n builtinToolNames: builtinNames,\n hostToolNames: userTools.map(tool => tool.name),\n nativeToCommon: NATIVE_TO_COMMON,\n });\n\n unsubscribe = piSession.subscribe(rawEvent => {\n if (!translatorState) return;\n const event = parseNativeEvent(rawEvent);\n if (!event) return;\n for (const part of translatePiEvent(event, translatorState)) {\n if (currentEmit) {\n currentEmit(part);\n } else if (part.type === 'compaction') {\n // No active turn: defer compaction observations to the next turn.\n pendingCompactionParts.push(part);\n }\n // Other event types outside a turn have no consumer and are dropped.\n }\n });\n return resourcesReloaded;\n }\n\n /*\n * Drive one turn against the Pi session and return the control surface.\n * Shared by `doPromptTurn` (a fresh user prompt) and `doContinueTurn` (an empty\n * prompt that asks Pi to continue its own thread after a rerun resume).\n */\n async function runTurn(turnOpts: {\n text: string;\n tools: ReadonlyArray<HarnessV1ToolSpec>;\n instructions?: string;\n emit: (part: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): Promise<HarnessV1PromptControl> {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n\n const userTools = turnOpts.tools;\n currentEmit = turnOpts.emit;\n const turnAbortController = new AbortController();\n const abort = async (reason?: unknown): Promise<void> => {\n if (turnAbortController.signal.aborted) return;\n if (reason === undefined) {\n turnAbortController.abort();\n } else {\n turnAbortController.abort(reason);\n }\n await Promise.resolve(piSession?.abort()).catch(() => {});\n };\n\n const turnPromise = (async () => {\n try {\n await applySessionInstructions(turnOpts.instructions);\n turnAbortController.signal.throwIfAborted();\n\n /*\n * Any host tool results delivered while no turn was live must land in the\n * journal before the session (re)builds from it, whichever turn entry\n * point runs next. No-op when nothing was delivered.\n */\n const didAppendDeliveredHostToolResults =\n appendDeliveredHostToolResults();\n\n const signature = JSON.stringify(userTools.map(t => t.name).sort());\n const needsRebuild =\n piSession == null || signature !== lastToolsSignature;\n let resourcesReloaded = false;\n if (needsRebuild) {\n resourcesReloaded = await rebuildPiSession(\n userTools,\n piSession == null,\n );\n turnAbortController.signal.throwIfAborted();\n lastToolsSignature = signature;\n }\n\n if (!resourcesReloaded) {\n await reloadResourcesOnly();\n turnAbortController.signal.throwIfAborted();\n }\n await syncHostWorkspaceFromSandbox({\n sandbox: toolSafeSandboxSession,\n sandboxWorkDir: input.sessionWorkDir,\n hostWorkDir,\n });\n turnAbortController.signal.throwIfAborted();\n\n // Fresh translator state for the new turn — keep the tool sets the\n // session was built with.\n translatorState = createPiTranslatorState({\n builtinToolNames: [...PI_NATIVE_BUILTIN_NAMES],\n hostToolNames: userTools.map(tool => tool.name),\n nativeToCommon: NATIVE_TO_COMMON,\n });\n\n currentEmit?.({ type: 'stream-start' });\n\n /*\n * A live continuation reports the completed tool execution before the\n * next assistant message, which closes the resumed tool-call step. A\n * journal rerun starts after that result has already been persisted,\n * so Pi has no live tool event to emit. Recreate only the missing step\n * boundary; otherwise the continuation layer mistakes the next\n * assistant response for the resumed step and discards it.\n */\n if (didAppendDeliveredHostToolResults) {\n currentEmit?.({\n type: 'finish-step',\n finishReason: { unified: 'tool-calls', raw: undefined },\n usage: {\n inputTokens: {\n total: 0,\n noCache: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n outputTokens: {\n total: 0,\n text: 0,\n reasoning: 0,\n },\n },\n harnessMetadata: { pi: { inferredStep: true } },\n });\n }\n\n let terminalError: string | undefined;\n const session = piSession!;\n\n // We subscribed in rebuild, but the translator may need to detect\n // terminal errors too — wrap a second listener that records them.\n const unsubErr = session.subscribe(raw => {\n const ev = parseNativeEvent(raw);\n if (!ev) return;\n const err = getPiTerminalError(ev);\n if (err && !terminalError) {\n terminalError = err;\n }\n });\n\n try {\n await session.prompt(turnOpts.text);\n\n if (terminalError) {\n /*\n * A `doSuspendTurn` aborts the in-flight turn on purpose. Pi surfaces\n * that abort as a *resolved* prompt with a recorded terminal error\n * (\"This operation was aborted\") rather than a thrown exception, so the\n * `catch` guard below never sees it. Swallow it here too — but only if\n * it's actually the abort: the stream then closes cleanly (no spurious\n * `error` chunk) and the next slice rerun-continues from the journal.\n * Any other terminal error mid-suspend is unanticipated and must\n * surface.\n */\n if (suspending && isAbortError(terminalError)) return;\n currentEmit?.({ type: 'error', error: new Error(terminalError) });\n return;\n }\n\n const stats = session.getSessionStats();\n const finishReason = {\n unified: 'stop' as const,\n raw: undefined,\n };\n const usage = {\n inputTokens: {\n total: stats.tokens.input,\n noCache: undefined,\n cacheRead: stats.tokens.cacheRead,\n cacheWrite: stats.tokens.cacheWrite,\n },\n outputTokens: {\n total: stats.tokens.output,\n text: undefined,\n reasoning: undefined,\n },\n };\n currentEmit?.({\n type: 'finish',\n finishReason,\n totalUsage: usage,\n });\n } catch (err) {\n // A `doSuspendTurn` aborts the in-flight turn on purpose — settle silently\n // so the stream closes cleanly without a spurious `error` chunk; the\n // next slice rerun-continues from the persisted journal.\n // Same rule as the resolved-with-terminalError path: only swallow the\n // abort our own suspend caused; surface anything unanticipated.\n if (suspending && isAbortError(err)) return;\n currentEmit?.({ type: 'error', error: err });\n } finally {\n unsubErr();\n }\n } catch (err) {\n if (suspending && isAbortError(err)) return;\n throw err;\n }\n })();\n\n const activeTurnToken = {};\n const done = turnPromise.finally(() => {\n if (activeTurn?.token === activeTurnToken) {\n activeTurn = undefined;\n currentEmit = undefined;\n }\n });\n activeTurn = {\n token: activeTurnToken,\n done,\n abort,\n };\n\n return createPromptControl({\n done,\n abortSignal: turnOpts.abortSignal,\n abort,\n });\n }\n\n const doStop = async (): Promise<HarnessV1ResumeSessionState> => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n deferredRerun?.cancel();\n const turnToStop = activeTurn;\n const abortingTurn = turnToStop?.abort();\n settlePendingToolResults('Pi session stopped');\n settlePendingToolApprovals('Pi session stopped');\n await abortingTurn;\n await turnToStop?.done.catch(() => {});\n\n /*\n * Results the framework already delivered for journal-pending calls must\n * reach the journal before it is persisted — the framework has marked\n * them settled and will not re-deliver them on a later resume.\n */\n try {\n appendDeliveredHostToolResults();\n } catch {\n // Best-effort: an unwritable journal falls back to the pre-delivery copy.\n }\n\n // Persist the Pi session file into the sandbox so a future process\n // can pick it up after `provider.resumeSession({ sessionId })` reattaches.\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n // Best-effort: a missing session file means resume returns to a\n // fresh conversation rather than failing stop.\n }\n }\n\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n\n return {\n type: 'resume-session',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n };\n\n const sessionImpl: HarnessV1Session = {\n sessionId: input.sessionId,\n isResume: input.isResume,\n // The model Pi actually resolves to (the configured id, or its default when\n // unset) — `gen_ai.request.model`.\n ...(resolvedModel?.id ? { modelId: resolvedModel.id } : {}),\n\n // Pi has no bridge to attach to and no on-disk event log to replay; its\n // only resume path is restoring the session file on a fresh/snapshotted\n // sandbox, i.e. `rerun`.\n\n doPromptTurn: async (\n promptOpts: HarnessV1PromptTurnOptions,\n ): Promise<HarnessV1PromptControl> => {\n if (promptOpts.responseFormat?.type === 'json') {\n throw new HarnessCapabilityUnsupportedError({\n message: \"Harness 'pi' does not support structured output.\",\n harnessId: HARNESS_ID,\n });\n }\n return runTurn({\n text: extractUserText(promptOpts.prompt),\n tools: promptOpts.tools ?? [],\n instructions: promptOpts.instructions,\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n },\n\n doContinueTurn: async (\n continueOpts: HarnessV1ContinueTurnOptions,\n ): Promise<HarnessV1PromptControl> => {\n if (continueOpts.responseFormat?.type === 'json') {\n throw new HarnessCapabilityUnsupportedError({\n message: \"Harness 'pi' does not support structured output.\",\n harnessId: HARNESS_ID,\n });\n }\n if (activeTurn != null) {\n currentEmit = continueOpts.emit;\n return createPromptControl({\n done: activeTurn.done,\n abortSignal: continueOpts.abortSignal,\n abort: activeTurn.abort,\n });\n }\n\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n\n /*\n * The restored journal ends with host tool calls that never got their\n * results — the turn was paused on host input (e.g. a tool approval)\n * when the previous process exited. The framework re-delivers those\n * results via `submitToolResult` right after this call returns; hold\n * the rerun until they have all arrived so they reach the model.\n */\n const danglingHostToolCalls = findDanglingHostToolCalls(\n continueOpts.tools ?? [],\n );\n if (danglingHostToolCalls.length > 0) {\n return deferRerunUntilHostToolResults(\n danglingHostToolCalls,\n continueOpts,\n );\n }\n\n /*\n * Pi runs the model on the host, so there is no live turn in the sandbox\n * to attach to — the previous slice's turn died with its process.\n * Rerun-continue: re-drive the agent from the journal restored on resume.\n * An empty prompt asks Pi to continue its own thread. Lossy — any work in\n * flight at the slice boundary is recomputed because a host-resident\n * runtime cannot do a lossless attach.\n */\n return runTurn({\n text: '',\n tools: continueOpts.tools ?? [],\n instructions: continueOpts.instructions,\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n },\n\n doCompact: async (customInstructions?: string) => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n /*\n * Pi owns the compaction. We just request it; the resulting\n * `compaction_end` event is observed by the session subscription and\n * translated into a `compaction` stream part. The returned\n * `CompactionResult` is intentionally discarded here.\n */\n await piSession?.compact(customInstructions);\n },\n\n doDestroy: async () => {\n if (stopped) return;\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n deferredRerun?.cancel();\n const turnToDestroy = activeTurn;\n const abortingTurn = turnToDestroy?.abort();\n settlePendingToolResults('Pi session stopped');\n settlePendingToolApprovals('Pi session stopped');\n await abortingTurn;\n await turnToDestroy?.done.catch(() => {});\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n },\n\n doStop,\n\n doDetach: async (): Promise<HarnessV1ResumeSessionState> => {\n if (activeTurn != null || pendingToolResults.size > 0) {\n parkedPiSessions.set(input.sessionId, sessionImpl);\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n /*\n * The parked in-process session is the authoritative continuation\n * path while the live turn is waiting on host input. Persistence is\n * only a fallback for later non-live resumes.\n */\n }\n }\n return {\n type: 'resume-session',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n }\n return doStop();\n },\n\n doSuspendTurn: async (): Promise<HarnessV1ContinueTurnState> => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n if (\n activeTurn != null &&\n (pendingToolResults.size > 0 || pendingToolApprovals.size > 0)\n ) {\n parkedPiSessions.set(input.sessionId, sessionImpl);\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n /*\n * While waiting on host input, the live parked session is the\n * authoritative same-process continuation path. The sandbox copy\n * remains a best-effort fallback for a later cold resume.\n */\n }\n }\n return {\n type: 'continue-turn',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n }\n /*\n * Pi's model runs in this host process, which is about to be suspended at\n * the slice boundary — the in-flight turn cannot survive it. Abort it (the\n * turn settles silently via the `suspending` guard so the stream closes\n * cleanly), persist the journal into the sandbox, and tear down host-side\n * resources. The sandbox itself is left running; the next slice pulls the\n * journal after `provider.resumeSession({ sessionId })` and rerun-continues. The\n * tail in flight at the boundary is recomputed — Pi cannot freeze a live\n * turn the way a bridge adapter can.\n */\n suspending = true;\n const turnToSuspend = activeTurn;\n await turnToSuspend?.abort();\n deferredRerun?.cancel();\n await turnToSuspend?.done.catch(() => {});\n\n /*\n * A suspend can land while the rerun is still held back waiting for\n * host tool results. Whatever the framework already delivered must land\n * in the journal now — it will not be re-delivered — while calls still\n * awaiting results stay dangling for the next continuation to collect.\n */\n try {\n appendDeliveredHostToolResults();\n } catch {\n // Best-effort: an unwritable journal falls back to the pre-delivery copy.\n }\n\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n // Best-effort: a missing/failed copy leaves the previously persisted\n // journal in place, so the next slice resumes from a slightly older\n // (still valid) state.\n }\n }\n\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n settlePendingToolResults('Pi session suspended');\n settlePendingToolApprovals('Pi session suspended');\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n\n return {\n type: 'continue-turn',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n },\n };\n\n return sessionImpl;\n}\n\nfunction resolvePiMcpServers({\n mcpServers,\n}: {\n mcpServers: Record<string, unknown> | undefined;\n}): Record<string, unknown> {\n if (mcpServers == null) return {};\n for (const [name, value] of Object.entries(mcpServers)) {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(\n `Pi MCP server ${JSON.stringify(name)} must be configured with an object value.`,\n );\n }\n }\n return mcpServers;\n}\n\n/**\n * Whether a terminal error (string from Pi's event stream, or a thrown error)\n * is an abort — the expected result of `doSuspendTurn` aborting the in-flight\n * turn. Only these are safe to swallow while `suspending`; any other error is\n * unanticipated and must surface as an `error` chunk.\n */\nfunction isAbortError(value: unknown): boolean {\n if (value == null) return false;\n if (\n typeof value === 'object' &&\n (value as { name?: unknown }).name === 'AbortError'\n ) {\n return true;\n }\n const text =\n typeof value === 'string'\n ? value\n : value instanceof Error\n ? value.message\n : String(value);\n return /\\baborted\\b|AbortError|operation was aborted/i.test(text);\n}\n\nfunction asPiToolResult(text: string): AgentToolResult<unknown> {\n return {\n content: [{ type: 'text', text }],\n details: undefined,\n };\n}\n\nasync function maybeDenyPiBuiltinTool(input: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n requestApproval: (args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }) => Promise<{ approved: boolean; reason?: string }>;\n}): Promise<AgentToolResult<unknown> | undefined> {\n const decision = await input.requestApproval({\n toolCallId: input.toolCallId,\n nativeName: input.nativeName,\n });\n if (decision.approved) return undefined;\n return asPiToolResult(\n serializeToolOutput({\n type: 'execution-denied',\n reason: decision.reason,\n }),\n );\n}\n\nfunction piBuiltinToolRequiresApproval(input: {\n permissionMode: HarnessV1PermissionMode;\n kind: 'readonly' | 'edit' | 'bash';\n}): boolean {\n if (input.permissionMode === 'allow-all') return false;\n if (input.permissionMode === 'allow-edits') return input.kind === 'bash';\n return input.kind === 'edit' || input.kind === 'bash';\n}\n\nfunction buildBuiltinToolDefinition(input: {\n native: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n remoteOps: PiRemoteOps;\n requestApproval: (args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }) => Promise<{ approved: boolean; reason?: string }>;\n}): ToolDefinition {\n switch (input.native) {\n case 'read':\n return defineTool({\n name: 'read',\n label: 'read',\n description: 'Read file contents.',\n parameters: Type.Object({ file_path: Type.String() }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'read',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const buf = await input.remoteOps.readBuffer(params.file_path);\n return asPiToolResult(buf.toString('utf8'));\n },\n });\n case 'write':\n return defineTool({\n name: 'write',\n label: 'write',\n description: 'Write content to a file.',\n parameters: Type.Object({\n file_path: Type.String(),\n content: Type.String(),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'write',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n await input.remoteOps.writeFile(params.file_path, params.content);\n return asPiToolResult(`Wrote ${params.file_path}`);\n },\n });\n case 'edit':\n return defineTool({\n name: 'edit',\n label: 'edit',\n description: 'Edit a file by exact-string replacement.',\n parameters: Type.Object({\n file_path: Type.String(),\n old_string: Type.String(),\n new_string: Type.String(),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'edit',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n await input.remoteOps.editFile(\n params.file_path,\n params.old_string,\n params.new_string,\n );\n return asPiToolResult(`Edited ${params.file_path}`);\n },\n });\n case 'bash':\n return defineTool({\n name: 'bash',\n label: 'bash',\n description: 'Execute a shell command.',\n parameters: Type.Object({\n command: Type.String(),\n timeout: Type.Optional(\n Type.Number({ description: 'Timeout in seconds.' }),\n ),\n }),\n async execute(toolCallId, params, signal) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'bash',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const chunks: Buffer[] = [];\n const result = await input.remoteOps.exec(params.command, '.', {\n onData(data) {\n chunks.push(data);\n },\n ...(signal ? { signal } : {}),\n ...(typeof params.timeout === 'number'\n ? { timeout: params.timeout }\n : {}),\n });\n const out = Buffer.concat(chunks).toString('utf8');\n const text = `${out}${\n result.exitCode != null ? `\\n\\n(exit ${result.exitCode})` : ''\n }`.trim();\n return asPiToolResult(text);\n },\n });\n case 'grep':\n return defineTool({\n name: 'grep',\n label: 'grep',\n description: 'Search file contents with regex.',\n parameters: Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n ignoreCase: Type.Optional(Type.Boolean()),\n literal: Type.Optional(Type.Boolean()),\n context: Type.Optional(Type.Number()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'grep',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const out = await input.remoteOps.grepFiles(params.pattern, params);\n return asPiToolResult(out);\n },\n });\n case 'find':\n return defineTool({\n name: 'find',\n label: 'find',\n description: 'Find files matching a glob pattern.',\n parameters: Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'find',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const matches = await input.remoteOps.findFiles(\n params.pattern,\n params.path ?? '.',\n params.limit ?? 1_000,\n );\n return asPiToolResult(matches.join('\\n'));\n },\n });\n case 'ls':\n return defineTool({\n name: 'ls',\n label: 'ls',\n description: 'List directory entries.',\n parameters: Type.Object({\n path: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'ls',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const entries = await input.remoteOps.listDirectory(\n params.path ?? '.',\n params.limit ?? 500,\n );\n return asPiToolResult(entries.join('\\n'));\n },\n });\n }\n}\n\nfunction buildUserToolDefinition(\n spec: HarnessV1ToolSpec,\n pending: Map<string, PendingToolResult>,\n): ToolDefinition {\n const schema = spec.inputSchema ?? {\n type: 'object',\n properties: {},\n additionalProperties: true,\n };\n return defineTool({\n name: spec.name,\n label: spec.name,\n description: spec.description ?? `User-registered tool ${spec.name}`,\n parameters: toolSpecToTypeBoxParameters(schema),\n async execute(toolCallId) {\n return new Promise<unknown>(resolve => {\n pending.set(toolCallId, { resolve });\n }).then(output => asPiToolResult(serializeToolOutput(output)));\n },\n });\n}\n","import type {\n ModelRegistry,\n ModelRuntime,\n} from '@earendil-works/pi-coding-agent';\nimport { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\nimport { VERSION } from './version';\n\ntype ProviderConfigInput = Parameters<ModelRegistry['registerProvider']>[1];\n\n/**\n * Pi auth options. Choose an explicit mode or rely on 'auto' (precedence:\n * explicit gateway, then OpenAI / Anthropic / custom environment variables).\n */\nexport type PiAuthenticationMode =\n | 'auto'\n | 'openai'\n | 'anthropic'\n | 'custom'\n | 'ai-gateway';\n\n/**\n * @deprecated Passing an object to auth options is deprecated. Use a `PiAuthenticationMode` string value (\"auto\" | \"openai\" | \"anthropic\" | \"custom\" | \"ai-gateway\") instead, and pass credentials via environment variables.\n */\nexport type LegacyPiAuthOptions = {\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n /**\n * Resolved environment-variable pairs of the form `<PREFIX>_API_KEY` and\n * (optionally) `<PREFIX>_BASE_URL`. Special-cased prefixes:\n * - `AI_GATEWAY` → registers `vercel-ai-gateway`\n * - `OPENAI` → registers `openai`\n * - `ANTHROPIC` → registers `anthropic` (`ANTHROPIC_AUTH_TOKEN` adds a\n * bearer auth header)\n * Any other `<PREFIX>_API_KEY` with a matching `<PREFIX>_BASE_URL` is\n * registered as the lowercased, dash-separated prefix.\n */\n readonly customEnv?: Record<string, string>;\n};\n\nexport type PiAuthOptions = PiAuthenticationMode | LegacyPiAuthOptions;\n\nconst DEFAULT_GATEWAY_BASE_URL = 'https://ai-gateway.vercel.sh';\nconst DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';\nconst DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com';\nconst HARNESS_CLIENT_APP = `ai-sdk/harness-pi/${VERSION}`;\n\nfunction createGatewayProviderConfig({\n apiKey,\n baseUrl,\n clientApp,\n}: {\n apiKey: string;\n baseUrl: string;\n clientApp: string;\n}): ProviderConfigInput {\n return {\n apiKey,\n baseUrl,\n authHeader: true,\n headers: {\n 'User-Agent': clientApp,\n 'x-client-app': clientApp,\n },\n };\n}\n\ntype PiRegistries = {\n modelRegistry: ModelRegistry;\n modelRuntime: ModelRuntime;\n};\n\nasync function register({\n registries,\n provider,\n apiKey,\n config,\n}: {\n registries: PiRegistries;\n provider: string;\n apiKey: string;\n config: ProviderConfigInput;\n}): Promise<void> {\n registries.modelRegistry.registerProvider(provider, config);\n await registries.modelRuntime.setRuntimeApiKey(provider, apiKey);\n}\n\nfunction hasConfiguredValue(value: unknown): boolean {\n if (value == null) return false;\n if (typeof value === 'string') return value.length > 0;\n if (typeof value !== 'object') return true;\n return Object.values(value).some(hasConfiguredValue);\n}\n\nexport function resolvePiEnv({\n options,\n env,\n}: {\n options: PiAuthOptions | undefined;\n env: NodeJS.ProcessEnv;\n}): Record<string, string> {\n const normalizedOptions = normalizePiAuthToLegacyAuth(options);\n const customEnvConfigured = hasConfiguredValue(normalizedOptions?.customEnv);\n if (customEnvConfigured) {\n return resolveCustomEnv({ customEnv: normalizedOptions!.customEnv ?? {} });\n }\n\n const gatewayConfigured = hasConfiguredValue(normalizedOptions?.gateway);\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env });\n if (gatewayConfigured) {\n const apiKey =\n normalizedOptions!.gateway?.apiKey ?? gatewayAuthFromEnv.apiKey;\n const baseUrl =\n normalizedOptions!.gateway?.baseUrl ?? gatewayAuthFromEnv.baseUrl;\n if (apiKey) {\n return { AI_GATEWAY_API_KEY: apiKey, AI_GATEWAY_BASE_URL: baseUrl };\n }\n return {};\n }\n\n // Handle explicit string modes with process env\n if (typeof options === 'string') {\n switch (options) {\n case 'openai':\n if (env.OPENAI_API_KEY) {\n return {\n OPENAI_API_KEY: env.OPENAI_API_KEY,\n ...(env.OPENAI_BASE_URL\n ? { OPENAI_BASE_URL: env.OPENAI_BASE_URL }\n : {}),\n };\n }\n return {};\n case 'anthropic':\n if (env.ANTHROPIC_API_KEY) {\n return {\n ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,\n ...(env.ANTHROPIC_BASE_URL\n ? { ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL }\n : {}),\n ...(env.ANTHROPIC_AUTH_TOKEN\n ? { ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN }\n : {}),\n };\n }\n return {};\n case 'custom': {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n result[key] = value;\n }\n }\n return result;\n }\n case 'ai-gateway':\n if (gatewayAuthFromEnv.apiKey) {\n return {\n AI_GATEWAY_API_KEY: gatewayAuthFromEnv.apiKey,\n AI_GATEWAY_BASE_URL: gatewayAuthFromEnv.baseUrl,\n };\n }\n return {};\n case 'auto':\n default:\n break;\n }\n }\n\n // Ambient gateway fallback.\n if (gatewayAuthFromEnv.apiKey) {\n return {\n AI_GATEWAY_API_KEY: gatewayAuthFromEnv.apiKey,\n AI_GATEWAY_BASE_URL: gatewayAuthFromEnv.baseUrl,\n };\n }\n\n // 'auto' fallback: pick up any other provider credentials from the env.\n const ambient: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n ambient[key] = value;\n }\n }\n return ambient;\n}\n\nexport async function registerPiProviders({\n options,\n resolvedEnv,\n registries,\n clientApp = HARNESS_CLIENT_APP,\n}: {\n options: PiAuthOptions | undefined;\n resolvedEnv: Record<string, string>;\n registries: PiRegistries;\n clientApp?: string;\n}): Promise<void> {\n const normalizedOptions = normalizePiAuthToLegacyAuth(options);\n if (hasConfiguredValue(normalizedOptions?.customEnv)) {\n await registerCustomProviders({\n customEnv: normalizedOptions!.customEnv ?? {},\n registries,\n clientApp,\n });\n return;\n }\n\n // Legacy customEnv was handled above. Everything else reduces to a mode:\n // string modes pass through, `undefined` is 'auto', and legacy gateway\n // objects fall through to the trailing gateway-registration block.\n const mode =\n typeof options === 'string' ? options : options == null ? 'auto' : 'legacy';\n\n switch (mode) {\n case 'openai': {\n const env = pickOpenAIEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickOpenAIEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'anthropic': {\n const env = pickAnthropicEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickAnthropicEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'custom': {\n // 'custom' registers every provider with credentials in the env.\n const env = pickProviderEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickProviderEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'ai-gateway': {\n const gatewayAuth = getAiGatewayAuthFromEnv({ env: process.env });\n const gatewayApiKey =\n resolvedEnv.AI_GATEWAY_API_KEY ?? gatewayAuth.apiKey;\n const gatewayBaseUrl =\n resolvedEnv.AI_GATEWAY_BASE_URL ?? gatewayAuth.baseUrl;\n if (!gatewayApiKey) return;\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayApiKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayApiKey,\n baseUrl: gatewayBaseUrl,\n clientApp,\n }),\n });\n return;\n }\n case 'legacy':\n break; // handled below\n case 'auto':\n default: {\n // 'auto' (the default): prefer the AI Gateway; only when no gateway\n // credentials exist, fall back to other providers found in the env.\n const gatewayAuth = getAiGatewayAuthFromEnv({ env: process.env });\n const gatewayApiKey =\n resolvedEnv.AI_GATEWAY_API_KEY ?? gatewayAuth.apiKey;\n const gatewayBaseUrl =\n resolvedEnv.AI_GATEWAY_BASE_URL ?? gatewayAuth.baseUrl;\n if (gatewayApiKey) {\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayApiKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayApiKey,\n baseUrl: gatewayBaseUrl,\n clientApp,\n }),\n });\n return;\n }\n const env = pickProviderEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickProviderEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n }\n\n // Legacy explicit gateway object options.\n const apiKey = resolvedEnv.AI_GATEWAY_API_KEY;\n const baseUrl = resolvedEnv.AI_GATEWAY_BASE_URL;\n if (!apiKey || !baseUrl) return;\n\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey,\n config: createGatewayProviderConfig({ apiKey, baseUrl, clientApp }),\n });\n}\n\nfunction pickOpenAIEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n if (env.OPENAI_API_KEY) result.OPENAI_API_KEY = env.OPENAI_API_KEY;\n if (env.OPENAI_BASE_URL) result.OPENAI_BASE_URL = env.OPENAI_BASE_URL;\n return result;\n}\n\nfunction pickAnthropicEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n if (env.ANTHROPIC_API_KEY) result.ANTHROPIC_API_KEY = env.ANTHROPIC_API_KEY;\n if (env.ANTHROPIC_BASE_URL)\n result.ANTHROPIC_BASE_URL = env.ANTHROPIC_BASE_URL;\n if (env.ANTHROPIC_AUTH_TOKEN)\n result.ANTHROPIC_AUTH_TOKEN = env.ANTHROPIC_AUTH_TOKEN;\n return result;\n}\n\n/**\n * Filters an env object down to provider-credential keys (`*_API_KEY`,\n * `*_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`). Pi does not read provider\n * credentials from the environment itself — providers are only registered\n * through `registerProvider` / `setRuntimeApiKey` — so we must extract the\n * relevant entries before handing them to `registerCustomProviders`.\n */\nfunction pickProviderEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction normalizePiAuthToLegacyAuth(\n options: PiAuthOptions | undefined,\n): LegacyPiAuthOptions | undefined {\n if (options == null || options === 'auto') {\n return undefined;\n }\n if (typeof options === 'string') {\n switch (options) {\n case 'ai-gateway':\n return { gateway: {} };\n case 'custom':\n case 'openai':\n case 'anthropic':\n return { customEnv: {} };\n default:\n return undefined;\n }\n }\n\n console.warn(\n '[pi] Passing an object to auth options is deprecated. Use a string mode (\"auto\" | \"openai\" | \"anthropic\" | \"custom\" | \"ai-gateway\") instead, and pass credentials via environment variables.',\n );\n return options;\n}\n\nfunction resolveCustomEnv({\n customEnv,\n}: {\n customEnv: Record<string, string>;\n}): Record<string, string> {\n const apiKey = customEnv.AI_GATEWAY_API_KEY;\n if (!apiKey) return {};\n\n return {\n AI_GATEWAY_API_KEY: apiKey,\n AI_GATEWAY_BASE_URL:\n customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL,\n };\n}\n\nasync function registerCustomProviders({\n customEnv,\n registries,\n clientApp,\n}: {\n customEnv: Record<string, string>;\n registries: PiRegistries;\n clientApp: string;\n}): Promise<void> {\n const gatewayKey = customEnv.AI_GATEWAY_API_KEY;\n if (gatewayKey) {\n const baseUrl = customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL;\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayKey,\n baseUrl,\n clientApp,\n }),\n });\n }\n\n if (customEnv.OPENAI_API_KEY) {\n const baseUrl = customEnv.OPENAI_BASE_URL ?? DEFAULT_OPENAI_BASE_URL;\n await register({\n registries,\n provider: 'openai',\n apiKey: customEnv.OPENAI_API_KEY,\n config: {\n apiKey: customEnv.OPENAI_API_KEY,\n baseUrl,\n authHeader: true,\n },\n });\n }\n\n if (customEnv.ANTHROPIC_API_KEY) {\n const baseUrl = customEnv.ANTHROPIC_BASE_URL ?? DEFAULT_ANTHROPIC_BASE_URL;\n await register({\n registries,\n provider: 'anthropic',\n apiKey: customEnv.ANTHROPIC_API_KEY,\n config: {\n apiKey: customEnv.ANTHROPIC_API_KEY,\n baseUrl,\n ...(customEnv.ANTHROPIC_AUTH_TOKEN\n ? {\n headers: {\n authorization: `Bearer ${customEnv.ANTHROPIC_AUTH_TOKEN}`,\n },\n }\n : {}),\n },\n });\n }\n\n for (const [name, apiKey] of Object.entries(customEnv)) {\n if (!name.endsWith('_API_KEY') || !apiKey) {\n continue;\n }\n const prefix = name.slice(0, -'_API_KEY'.length);\n if (\n prefix === 'AI_GATEWAY' ||\n prefix === 'OPENAI' ||\n prefix === 'ANTHROPIC'\n ) {\n continue;\n }\n const provider = prefix.toLowerCase().replace(/_/g, '-');\n const baseUrl = customEnv[`${prefix}_BASE_URL`];\n if (!baseUrl) {\n continue;\n }\n await register({\n registries,\n provider,\n apiKey,\n config: {\n apiKey,\n baseUrl,\n authHeader: true,\n },\n });\n }\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { z } from 'zod/v4';\n\n/**\n * Pi `session.subscribe` emits a discriminated union of events. The exact\n * shape evolves with Pi versions; we accept loose objects and extract only\n * the fields we recognise. The `type` field is required and stringly-typed\n * because Pi may add new types we want to ignore.\n */\nexport const piSessionEventSchema = z.looseObject({\n type: z.string(),\n assistantMessageEvent: z\n .looseObject({\n type: z.string().optional(),\n delta: z.string().optional(),\n })\n .optional(),\n toolCallId: z.string().optional(),\n toolName: z.string().optional(),\n args: z.unknown().optional(),\n input: z.unknown().optional(),\n result: z.unknown().optional(),\n content: z.unknown().optional(),\n isError: z.boolean().optional(),\n // Compaction events (`compaction_start` / `compaction_end`). `result` (a\n // `CompactionResult`) rides the shared `result` field above; `reason`\n // distinguishes manual vs automatic (threshold/overflow) compaction.\n reason: z.string().optional(),\n aborted: z.boolean().optional(),\n error: z\n .union([\n z.string(),\n z.looseObject({\n errorMessage: z.string().optional(),\n stopReason: z.string().optional(),\n }),\n ])\n .optional(),\n message: z\n .looseObject({\n role: z.string().optional(),\n content: z.unknown().optional(),\n stopReason: z.string().optional(),\n errorMessage: z.string().optional(),\n })\n .optional(),\n});\n\nexport type PiSessionEvent = z.infer<typeof piSessionEventSchema>;\n\n/**\n * Decode an unknown raw event into a `PiSessionEvent` if it looks like one.\n * Returns `undefined` if it doesn't parse so the caller can skip it.\n */\nexport function parseNativeEvent(raw: unknown): PiSessionEvent | undefined {\n const parsed = piSessionEventSchema.safeParse(raw);\n return parsed.success ? parsed.data : undefined;\n}\n\n/**\n * Detect whether a Pi event signals a terminal error for the current turn.\n * Returns the error message if so. Mirrors the original adapter's\n * `getPiTerminalError`.\n */\nexport function getPiTerminalError(event: PiSessionEvent): string | undefined {\n const isTerminalStopReason = (value: string | undefined) =>\n value === 'error' || value === 'aborted';\n\n if (typeof event.error === 'string' && event.error.trim()) {\n return event.error.trim();\n }\n\n if (event.error && typeof event.error === 'object') {\n const errorMessage = event.error.errorMessage?.trim();\n if (errorMessage) {\n return errorMessage;\n }\n const stopReason = event.error.stopReason?.trim();\n if (isTerminalStopReason(stopReason)) {\n return stopReason;\n }\n }\n\n const messageError = event.message?.errorMessage?.trim();\n if (messageError) {\n return messageError;\n }\n\n const messageStopReason = event.message?.stopReason?.trim();\n if (isTerminalStopReason(messageStopReason)) {\n return messageStopReason;\n }\n\n if (\n event.isError &&\n typeof event.content === 'string' &&\n event.content.trim()\n ) {\n return event.content.trim();\n }\n\n return undefined;\n}\n\n/** Pull the assistant text from a `turn_end` / `message_end` event payload. */\nexport function extractAssistantText(\n message: PiSessionEvent['message'],\n): string {\n if (!message || message.role !== 'assistant') {\n return '';\n }\n\n if (typeof message.content === 'string') {\n return message.content;\n }\n\n if (!Array.isArray(message.content)) {\n return '';\n }\n\n return message.content\n .flatMap(part => {\n if (!part || typeof part !== 'object') {\n return [];\n }\n const contentPart = part as Record<string, unknown>;\n return contentPart.type === 'text' && typeof contentPart.text === 'string'\n ? [contentPart.text]\n : [];\n })\n .join('');\n}\n","import type { ModelRegistry } from '@earendil-works/pi-coding-agent';\nimport { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\ntype PiModel = ReturnType<ModelRegistry['getAll']>[number];\n\n/**\n * Default model id used when no `model` is configured AND gateway credentials\n * are available in the environment. Looked up from Pi's own model registry —\n * the entry must exist under the `vercel-ai-gateway` provider in\n * `@earendil-works/pi-ai`'s catalog.\n */\nexport const DEFAULT_PI_GATEWAY_MODEL_ID = 'anthropic/claude-sonnet-4.6';\n\n/*\n * A `\"<provider>/<id>\"` reference normally resolves under that provider, not\n * any entry whose flat `id` happens to equal the whole string. Routing proxies\n * (`vercel-ai-gateway`, `openrouter`) can carry another provider's id verbatim\n * as their own flat `id` (e.g. `id: \"xai/grok-4.3\"`), so this tier normally\n * wins over flat matching. An authenticated literal-id match remains usable\n * when the scoped provider is unauthenticated, matching Pi's own resolver.\n * Gateway preference stays first because gateway credentials explicitly opt\n * the harness into routing matching models through the gateway.\n */\nconst findScopedMatch = (\n effectiveId: string,\n models: PiModel[],\n): PiModel | undefined => {\n const slashIndex = effectiveId.indexOf('/');\n if (slashIndex === -1) return undefined;\n\n const prefix = effectiveId.slice(0, slashIndex);\n const bareId = effectiveId.slice(slashIndex + 1);\n return models.find(\n m => m.provider === prefix && (m.id === bareId || m.name === bareId),\n );\n};\n\nexport function createPiModelResolver({\n modelRegistry,\n env = process.env,\n}: {\n modelRegistry: ModelRegistry;\n env?: NodeJS.ProcessEnv;\n}) {\n let cachedModels: PiModel[] | undefined;\n\n const loadModels = (): PiModel[] => {\n if (cachedModels) {\n return cachedModels;\n }\n try {\n cachedModels = modelRegistry.getAll();\n } catch {\n cachedModels = [];\n }\n return cachedModels;\n };\n\n return (modelId: string | undefined): PiModel | undefined => {\n const useGateway = Boolean(getAiGatewayAuthFromEnv({ env }).apiKey);\n const effectiveId =\n modelId ?? (useGateway ? DEFAULT_PI_GATEWAY_MODEL_ID : undefined);\n if (!effectiveId) return undefined;\n\n const models = loadModels();\n const matches = (m: PiModel) =>\n m.id === effectiveId || m.name === effectiveId;\n\n // When gateway creds are present, prefer the gateway-routed entry for the\n // given id. Pi's catalog lists the same model id under multiple providers\n // (e.g. `anthropic/claude-sonnet-4.6` exists under both `openrouter` and\n // `vercel-ai-gateway`); without this preference Pi would dispatch through\n // a provider we didn't register, which fails with \"No API key found\".\n const gatewayMatch = useGateway\n ? models.find(m => m.provider === 'vercel-ai-gateway' && matches(m))\n : undefined;\n if (gatewayMatch) return gatewayMatch;\n\n const scopedMatch = findScopedMatch(effectiveId, models);\n if (scopedMatch && !modelRegistry.hasConfiguredAuth(scopedMatch)) {\n const authenticatedFlatMatches = models.filter(\n m => m.id === effectiveId && modelRegistry.hasConfiguredAuth(m),\n );\n if (authenticatedFlatMatches.length === 1) {\n return authenticatedFlatMatches[0];\n }\n }\n\n return scopedMatch ?? models.find(matches);\n };\n}\n","import { realpathSync } from 'node:fs';\nimport path from 'node:path';\n\nexport interface PiPathMapper {\n /** The host-side mirror directory Pi reads/writes through the workspace VFS. */\n readonly hostWorkDir: string;\n /** The sandbox-side working directory where tools actually operate. */\n readonly sandboxWorkDir: string;\n /**\n * Translate a path the host sees (relative to `hostWorkDir`, or absolute\n * inside it, or already a sandbox path) to the canonical sandbox path. Throws\n * if the path would escape the workspace.\n */\n toSandboxPath(inputPath: string): string;\n /**\n * Translate a path for read-only tools. In addition to the workspace, this\n * allows explicitly configured sandbox roots such as `$HOME/.agents/skills`.\n */\n toReadableSandboxPath(inputPath: string): string;\n /** Verify that a sandbox-side path is still inside `sandboxWorkDir`. */\n assertSandboxPath(inputPath: string): string;\n /**\n * Verify that a sandbox-side path is inside `sandboxWorkDir` or an\n * explicitly configured readable root.\n */\n assertReadableSandboxPath(inputPath: string): string;\n /** Translate any path to its POSIX-relative form under `sandboxWorkDir`. */\n toRelativePath(inputPath: string): string;\n}\n\nexport interface PiReadablePathRoot {\n readonly sandboxDir: string;\n}\n\nexport interface CreatePiPathMapperOptions {\n readonly hostWorkDir: string;\n readonly sandboxWorkDir: string;\n readonly readableRoots?: ReadonlyArray<PiReadablePathRoot>;\n}\n\nfunction isInsidePath(parent: string, candidate: string): boolean {\n const relative = path.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.isAbsolute(relative))\n );\n}\n\nfunction isInsidePosixPath(parent: string, candidate: string): boolean {\n const relative = path.posix.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.posix.isAbsolute(relative))\n );\n}\n\nfunction canonicalizeForContainment(inputPath: string): string {\n try {\n return realpathSync.native(inputPath);\n } catch {\n const parent = path.dirname(inputPath);\n if (parent === inputPath) {\n return inputPath;\n }\n return path.join(\n canonicalizeForContainment(parent),\n path.basename(inputPath),\n );\n }\n}\n\nexport function createPiPathMapper(\n options: CreatePiPathMapperOptions,\n): PiPathMapper {\n const normalizedHost = path.resolve(options.hostWorkDir);\n const normalizedSandbox = path.posix.normalize(options.sandboxWorkDir);\n const canonicalHost = canonicalizeForContainment(normalizedHost);\n const readableRoots =\n options.readableRoots?.map(root => ({\n sandboxDir: path.posix.normalize(root.sandboxDir),\n })) ?? [];\n\n const assertWorkspaceSandboxPath = (inputPath: string): string => {\n const normalizedInput = path.posix.normalize(inputPath);\n if (!isInsidePosixPath(normalizedSandbox, normalizedInput)) {\n throw new Error(`Pi path escapes the workspace: ${inputPath}`);\n }\n return normalizedInput;\n };\n\n const assertReadableSandboxPath = (inputPath: string): string => {\n const normalizedInput = path.posix.normalize(inputPath);\n if (\n !isInsidePosixPath(normalizedSandbox, normalizedInput) &&\n !readableRoots.some(root =>\n isInsidePosixPath(root.sandboxDir, normalizedInput),\n )\n ) {\n throw new Error(`Pi path escapes the readable roots: ${inputPath}`);\n }\n return normalizedInput;\n };\n\n const toWorkspaceSandboxPath = (inputPath: string): string => {\n if (path.posix.isAbsolute(inputPath)) {\n const normalizedInput = path.posix.normalize(inputPath);\n try {\n return assertWorkspaceSandboxPath(normalizedInput);\n } catch {\n // Absolute host paths are handled below.\n }\n }\n\n const resolvedHost = path.isAbsolute(inputPath)\n ? path.resolve(inputPath)\n : path.resolve(normalizedHost, inputPath);\n const canonicalResolvedHost = canonicalizeForContainment(resolvedHost);\n if (\n !isInsidePath(normalizedHost, resolvedHost) ||\n !isInsidePath(canonicalHost, canonicalResolvedHost)\n ) {\n throw new Error(`Pi path escapes the workspace: ${inputPath}`);\n }\n\n const relative = path\n .relative(normalizedHost, resolvedHost)\n .split(path.sep)\n .join('/');\n return relative\n ? path.posix.join(normalizedSandbox, relative)\n : normalizedSandbox;\n };\n\n return {\n hostWorkDir: normalizedHost,\n sandboxWorkDir: normalizedSandbox,\n toSandboxPath(inputPath: string) {\n return toWorkspaceSandboxPath(inputPath);\n },\n toReadableSandboxPath(inputPath: string) {\n if (path.posix.isAbsolute(inputPath)) {\n const normalizedInput = path.posix.normalize(inputPath);\n try {\n return assertReadableSandboxPath(normalizedInput);\n } catch {\n // Absolute host paths are handled by workspace mapping below.\n }\n }\n\n return toWorkspaceSandboxPath(inputPath);\n },\n assertSandboxPath(inputPath: string) {\n return assertWorkspaceSandboxPath(inputPath);\n },\n assertReadableSandboxPath(inputPath: string) {\n return assertReadableSandboxPath(inputPath);\n },\n toRelativePath(inputPath: string) {\n const sandboxPath = path.posix.isAbsolute(inputPath)\n ? path.posix.normalize(inputPath)\n : path.posix.join(\n normalizedSandbox,\n inputPath.split(path.sep).join('/'),\n );\n const relative = path.posix.relative(normalizedSandbox, sandboxPath);\n return relative || '.';\n },\n };\n}\n","import path from 'node:path';\nimport { shellQuote } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\nimport type { PiPathMapper } from './pi-paths';\n\nexport type PiRemoteFileChangeKind = 'create' | 'modify';\n\nexport interface PiRemoteOpsOptions {\n readonly sandbox: Experimental_SandboxSession;\n readonly paths: PiPathMapper;\n readonly env?: Record<string, string>;\n readonly onFileChange?: (\n event: PiRemoteFileChangeKind,\n relativePath: string,\n content: Buffer,\n ) => void;\n}\n\nexport interface PiRemoteOps {\n readonly paths: PiPathMapper;\n readBuffer(inputPath: string): Promise<Buffer>;\n writeFile(inputPath: string, content: string): Promise<void>;\n editFile(\n inputPath: string,\n oldText: string,\n newText: string,\n ): Promise<string>;\n listDirectory(inputPath?: string, limit?: number): Promise<string[]>;\n findFiles(\n pattern: string,\n inputPath?: string,\n limit?: number,\n ): Promise<string[]>;\n grepFiles(\n pattern: string,\n input: {\n path?: string;\n glob?: string;\n ignoreCase?: boolean;\n literal?: boolean;\n context?: number;\n limit?: number;\n },\n ): Promise<string>;\n access(inputPath: string): Promise<void>;\n exec(\n command: string,\n cwd: string,\n input: {\n onData: (data: Buffer) => void;\n signal?: AbortSignal;\n timeout?: number;\n },\n ): Promise<{ exitCode: number | null }>;\n}\n\ninterface RunShellInput {\n cwd?: string;\n signal?: AbortSignal;\n onData?: (data: Buffer) => void;\n}\n\ninterface RunShellResult {\n exitCode: number | null;\n output: Buffer;\n}\n\nfunction lastOutputLine(output: Buffer): string | undefined {\n return output.toString('utf8').trim().split('\\n').filter(Boolean).at(-1);\n}\n\nexport function createPiRemoteOps(options: PiRemoteOpsOptions): PiRemoteOps {\n const runShell = async (\n command: string,\n input: RunShellInput = {},\n ): Promise<RunShellResult> => {\n // `sandbox.run({ command })` already wraps in `bash -c`; we pass the\n // shell snippet directly. shellQuote is still used inside `command`\n // for path/value interpolation by the callers.\n const result = await options.sandbox.run({\n command,\n ...(input.cwd\n ? { workingDirectory: options.paths.toSandboxPath(input.cwd) }\n : {}),\n ...(options.env ? { env: options.env } : {}),\n ...(input.signal ? { abortSignal: input.signal } : {}),\n });\n\n const combined = `${result.stdout}${result.stderr}`;\n const output = Buffer.from(combined, 'utf8');\n if (output.length > 0) {\n input.onData?.(output);\n }\n\n return {\n exitCode: result.exitCode,\n output,\n };\n };\n\n const resolveExistingSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> => {\n const result = await runShell(\n [\n `target=${shellQuote(remotePath)}`,\n `if [ ! -e \"$target\" ]; then echo \"__PI_REALPATH_NOT_FOUND__\"; exit 2; fi`,\n `resolved=$(realpath \"$target\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }`,\n `printf '%s\\\\n' \"$resolved\"`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8');\n if (output.includes('__PI_REALPATH_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n if (output.includes('__PI_REALPATH_FAILED__') || result.exitCode !== 0) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n\n const resolvedPath = lastOutputLine(result.output);\n if (!resolvedPath) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n return resolvedPath;\n };\n\n const resolveReadableSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> =>\n options.paths.assertReadableSandboxPath(\n await resolveExistingSandboxPath(remotePath, inputPath),\n );\n\n const resolveWritableSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> => {\n const result = await runShell(\n [\n `target=${shellQuote(remotePath)}`,\n `if [ -e \"$target\" ] || [ -L \"$target\" ]; then resolved=$(realpath \"$target\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }; printf '%s\\\\n' \"$resolved\"; exit 0; fi`,\n `dir=$(dirname \"$target\")`,\n `base=$(basename \"$target\")`,\n `missing=\"$base\"`,\n `while [ ! -e \"$dir\" ] && [ ! -L \"$dir\" ]; do parent=$(dirname \"$dir\"); if [ \"$parent\" = \"$dir\" ]; then echo \"__PI_REALPATH_NOT_FOUND__\"; exit 2; fi; missing=\"$(basename \"$dir\")/$missing\"; dir=\"$parent\"; done`,\n `resolved_dir=$(realpath \"$dir\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }`,\n `printf '%s/%s\\\\n' \"$resolved_dir\" \"$missing\"`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8');\n if (\n output.includes('__PI_REALPATH_NOT_FOUND__') ||\n output.includes('__PI_REALPATH_FAILED__') ||\n result.exitCode !== 0\n ) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n\n const resolvedPath = lastOutputLine(result.output);\n if (!resolvedPath) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n return options.paths.assertSandboxPath(resolvedPath);\n };\n\n const readBuffer = async (inputPath: string): Promise<Buffer> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const bytes = await options.sandbox.readBinaryFile({\n path: resolvedPath,\n });\n if (!bytes) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n return Buffer.from(bytes);\n };\n\n const writeFile = async (\n inputPath: string,\n content: string,\n ): Promise<void> => {\n const remotePath = options.paths.toSandboxPath(inputPath);\n const resolvedPath = await resolveWritableSandboxPath(\n remotePath,\n inputPath,\n );\n const previous = await options.sandbox.readBinaryFile({\n path: resolvedPath,\n });\n await runShell(`mkdir -p ${shellQuote(path.posix.dirname(resolvedPath))}`);\n await options.sandbox.writeTextFile({ path: resolvedPath, content });\n options.onFileChange?.(\n previous ? 'modify' : 'create',\n options.paths.toRelativePath(resolvedPath),\n Buffer.from(content, 'utf8'),\n );\n };\n\n const editFile = async (\n inputPath: string,\n oldText: string,\n newText: string,\n ): Promise<string> => {\n const current = (await readBuffer(inputPath)).toString('utf8');\n const index = current.indexOf(oldText);\n if (index === -1) {\n throw new Error(`Text to replace was not found in ${inputPath}`);\n }\n const updated = `${current.slice(0, index)}${newText}${current.slice(\n index + oldText.length,\n )}`;\n await writeFile(inputPath, updated);\n return updated;\n };\n\n const listDirectory = async (\n inputPath: string = '.',\n limit: number = 500,\n ): Promise<string[]> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_LS_NOT_FOUND__\"; exit 2; fi`,\n `if [ ! -d ${shellQuote(resolvedPath)} ]; then echo \"__PI_LS_NOT_DIR__\"; exit 3; fi`,\n `cd ${shellQuote(resolvedPath)}`,\n 'ls -1Ap',\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_LS_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n if (output.includes('__PI_LS_NOT_DIR__')) {\n throw new Error(`Not a directory: ${inputPath}`);\n }\n\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => line.replace(/[*=@|]$/, ''))\n .sort((left, right) =>\n left.toLowerCase().localeCompare(right.toLowerCase()),\n )\n .slice(0, limit);\n };\n\n const findFiles = async (\n pattern: string,\n inputPath: string = '.',\n limit: number = 1_000,\n ): Promise<string[]> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_FIND_NOT_FOUND__\"; exit 2; fi`,\n `if [ -d ${shellQuote(resolvedPath)} ]; then find ${shellQuote(resolvedPath)} -type f -print; else printf '%s\\\\n' ${shellQuote(resolvedPath)}; fi`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_FIND_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n\n const searchRoot = resolvedPath;\n return output\n .split('\\n')\n .filter(Boolean)\n .map(absolutePath => {\n if (absolutePath === searchRoot) {\n return path.posix.basename(absolutePath);\n }\n return path.posix.relative(searchRoot, absolutePath);\n })\n .filter(\n candidate =>\n candidate.length > 0 && path.matchesGlob(candidate, pattern),\n )\n .sort((left, right) =>\n left.toLowerCase().localeCompare(right.toLowerCase()),\n )\n .slice(0, limit);\n };\n\n const grepFiles = async (\n pattern: string,\n input: {\n path?: string;\n glob?: string;\n ignoreCase?: boolean;\n literal?: boolean;\n context?: number;\n limit?: number;\n },\n ): Promise<string> => {\n const remotePath = options.paths.toReadableSandboxPath(input.path ?? '.');\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n input.path ?? '.',\n );\n const relativeTarget = options.paths.toRelativePath(resolvedPath);\n const targetPath =\n relativeTarget.startsWith('../') || path.posix.isAbsolute(relativeTarget)\n ? resolvedPath\n : relativeTarget;\n const flags = [\n '-R',\n '-n',\n '--binary-files=without-match',\n ...(input.ignoreCase ? ['-i'] : []),\n ...(input.literal ? ['-F'] : []),\n ...(typeof input.context === 'number' && input.context > 0\n ? ['-C', String(input.context)]\n : []),\n ...(input.glob ? ['--include', input.glob] : []),\n ];\n const limit = Math.max(1, input.limit ?? 100);\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_GREP_NOT_FOUND__\"; exit 2; fi`,\n `cd ${shellQuote(options.paths.sandboxWorkDir)}`,\n `grep ${flags.map(shellQuote).join(' ')} -- ${shellQuote(pattern)} ${shellQuote(targetPath)} 2>/dev/null | head -n ${limit}`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_GREP_NOT_FOUND__')) {\n throw new Error(`Path not found: ${input.path ?? '.'}`);\n }\n\n return output || 'No matches found';\n };\n\n return {\n paths: options.paths,\n readBuffer,\n writeFile,\n editFile,\n listDirectory,\n findFiles,\n grepFiles,\n async access(inputPath: string) {\n await readBuffer(inputPath);\n },\n async exec(command, cwd, input): Promise<{ exitCode: number | null }> {\n const controller = new AbortController();\n // `input.timeout` is expressed in seconds (Pi's `bash` tool contract),\n // so convert to milliseconds for `setTimeout`.\n const timeoutId =\n typeof input.timeout === 'number' && input.timeout > 0\n ? setTimeout(() => controller.abort(), input.timeout * 1000)\n : undefined;\n\n const forwardedSignal = input.signal;\n const onAbort = () => controller.abort();\n forwardedSignal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n const result = await runShell(command, {\n cwd,\n signal: controller.signal,\n onData: input.onData,\n });\n return { exitCode: result.exitCode };\n } finally {\n forwardedSignal?.removeEventListener('abort', onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n },\n };\n}\n","import path from 'node:path';\nimport type { HarnessV1Skill } from '@ai-sdk/harness';\nimport { writeSkills } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\n\n/**\n * Materialize Pi skills as files under\n * `$HOME/.agents/skills/<name>/SKILL.md` inside the sandbox.\n */\nexport async function writePiSkills(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly sandboxHomeDir: string;\n readonly skills: ReadonlyArray<HarnessV1Skill>;\n readonly abortSignal?: AbortSignal;\n}): Promise<void> {\n await writeSkills({\n sandbox: args.sandbox,\n rootDir: path.posix.join(args.sandboxHomeDir, '.agents', 'skills'),\n skills: args.skills,\n abortSignal: args.abortSignal,\n invalidSkillNameMessage: ({ name }) => `Invalid Pi skill name: ${name}`,\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid Pi skill file path for ${skillName}: ${filePath}`,\n });\n}\n","import { randomBytes } from 'node:crypto';\nimport type { HarnessV1StreamPart } from '@ai-sdk/harness';\nimport { secureJsonParse } from '@ai-sdk/provider-utils';\nimport { extractAssistantText, type PiSessionEvent } from './pi-events';\nimport { serializeToolOutput } from './pi-utils';\n\n/**\n * Translator state shared across all events of a single turn. Reset at the\n * start of every `doPromptTurn`. Callers update the same instance and read it to\n * decide when a turn has settled into a steady state (e.g. for gap-filling).\n */\nexport interface PiTranslatorState {\n /**\n * True once a `turn_start` or assistant `message_start` event has been\n * observed. Suppresses spurious deltas that arrive before the turn opens.\n */\n promptStarted: boolean;\n /** Accumulated assistant text from `text_delta` events. */\n streamedAssistantText: string;\n /** Stream-part id for the active text block; synthesized on first delta. */\n currentTextId: string | undefined;\n /**\n * Stream-part id for the active reasoning block; synthesized lazily on\n * first `thinking_delta`.\n */\n currentReasoningId: string | undefined;\n /** Whether a `reasoning-start` event has already been emitted. */\n reasoningStarted: boolean;\n /** Tool-call id → tool name (used to fill in `toolName` on results). */\n observedToolNames: Map<string, string>;\n /** Tool ids requested by the current assistant message but not yet completed. */\n pendingStepToolCallIds: Set<string>;\n /** Whether the current assistant message has opened a visible step. */\n stepOpen: boolean;\n /**\n * Tool-call id → the exact output value the host submitted for a\n * user-registered (host-executed) tool. Pi only echoes the tool result back\n * as serialized text (the tool handler stringifies the output before handing\n * it to the runtime so the model can read it), which would otherwise reach\n * consumers as a string and lose the original object structure. Keeping the\n * submitted value here lets the result projection surface the original object\n * — matching the other adapters — while the model still receives the text.\n * Populated by the session's `submitToolResult`; consumed (and cleared) when\n * the matching `tool_result`/`tool_execution_end` event is translated.\n */\n hostToolResults: Map<string, unknown>;\n dynamicToolCallIds: Set<string>;\n /**\n * Names of tools that Pi executes natively (read/write/edit/bash/grep/\n * find/ls). `tool-call` events for these get `providerExecuted: true`\n * so the harness host doesn't try to dispatch them. User-registered\n * tools are not in this set.\n */\n readonly builtinToolNames: ReadonlySet<string>;\n readonly hostToolNames: ReadonlySet<string>;\n /**\n * Map of native tool name → common name. `find` → `glob`, etc. Pi emits\n * native names on its events; the wire `toolName` is the common name when\n * one exists.\n */\n readonly nativeToCommonNameMap: ReadonlyMap<string, string>;\n}\n\nexport interface PiTranslatorStateOptions {\n readonly builtinToolNames?: ReadonlyArray<string>;\n readonly hostToolNames?: ReadonlyArray<string>;\n readonly nativeToCommon?:\n | ReadonlyMap<string, string>\n | Record<string, string>;\n}\n\nexport function createPiTranslatorState(\n options: PiTranslatorStateOptions = {},\n): PiTranslatorState {\n const map =\n options.nativeToCommon instanceof Map\n ? options.nativeToCommon\n : new Map(Object.entries(options.nativeToCommon ?? {}));\n return {\n promptStarted: false,\n streamedAssistantText: '',\n currentTextId: undefined,\n currentReasoningId: undefined,\n reasoningStarted: false,\n observedToolNames: new Map(),\n pendingStepToolCallIds: new Set(),\n stepOpen: false,\n hostToolResults: new Map(),\n dynamicToolCallIds: new Set(),\n builtinToolNames: new Set(options.builtinToolNames ?? []),\n hostToolNames: new Set(options.hostToolNames ?? []),\n nativeToCommonNameMap: map,\n };\n}\n\nfunction newId(): string {\n return randomBytes(8).toString('hex');\n}\n\n/**\n * Pi's `tool_execution_end` event payload (`result`) is a Pi `AgentToolResult`\n * envelope `{ content: (TextContent | ImageContent)[], details, terminate? }`.\n * The `tool_result` event uses a flat shape with `content` and `details` at\n * the top level. In both cases we extract just the text payload (joined when\n * multiple text parts are present) so the AI SDK consumer sees the raw\n * string the tool produced.\n */\nfunction unwrapPiToolResult(event: PiSessionEvent): never {\n const candidates: unknown[] = [];\n const result = event.result as unknown;\n if (result && typeof result === 'object') {\n const inner = (result as { content?: unknown }).content;\n if (Array.isArray(inner)) candidates.push(inner);\n }\n if (Array.isArray(event.content)) candidates.push(event.content);\n\n for (const content of candidates) {\n if (!Array.isArray(content)) continue;\n const text = content\n .filter(\n (p): p is { type: 'text'; text: string } =>\n !!p &&\n typeof p === 'object' &&\n (p as { type?: unknown }).type === 'text' &&\n typeof (p as { text?: unknown }).text === 'string',\n )\n .map(p => p.text)\n .join('');\n if (text) return text as never;\n }\n\n if (typeof event.result === 'string') return event.result as never;\n if (typeof event.content === 'string') return event.content as never;\n return (event.result ?? event.content ?? null) as never;\n}\n\nfunction parseMcpToolResult(content: unknown): unknown {\n if (typeof content !== 'string') return content;\n try {\n return secureJsonParse(content);\n } catch {\n return content;\n }\n}\n\nfunction resolveToolName(\n state: PiTranslatorState,\n nativeName: string,\n): { wire: string; native: string } {\n const common = state.nativeToCommonNameMap.get(nativeName);\n return { wire: common ?? nativeName, native: nativeName };\n}\n\nfunction finishStep(state: PiTranslatorState): HarnessV1StreamPart[] {\n if (!state.stepOpen || state.pendingStepToolCallIds.size > 0) return [];\n state.stepOpen = false;\n state.pendingStepToolCallIds.clear();\n return [\n {\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: {\n inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },\n outputTokens: { total: 0, text: 0, reasoning: 0 },\n },\n harnessMetadata: { pi: { inferredStep: true } },\n },\n ];\n}\n\nexport function finishPiApprovalStep(\n state: PiTranslatorState,\n toolCallId: string,\n): HarnessV1StreamPart[] {\n state.stepOpen = true;\n state.pendingStepToolCallIds.delete(toolCallId);\n return finishStep(state);\n}\n\nfunction extractPiToolCallIds(message: PiSessionEvent['message']): string[] {\n if (!message || message.role !== 'assistant') return [];\n if (!Array.isArray(message.content)) return [];\n return message.content.flatMap(part => {\n if (!part || typeof part !== 'object') return [];\n const block = part as Record<string, unknown>;\n if (block.type !== 'toolCall') return [];\n const id = block.id ?? block.toolCallId;\n return typeof id === 'string' && id.length > 0 ? [id] : [];\n });\n}\n\n/**\n * Translate a single Pi `session.subscribe` event into zero or more\n * `HarnessV1StreamPart`s, updating the translator state in place. Returns\n * an empty array for events that produce no output (e.g. events emitted\n * before `turn_start`).\n *\n * The translator does NOT emit `stream-start`/`finish` — those are\n * lifecycle signals owned by the session layer.\n */\nexport function translatePiEvent(\n event: PiSessionEvent,\n state: PiTranslatorState,\n): HarnessV1StreamPart[] {\n switch (event.type) {\n case 'turn_start':\n case 'message_start': {\n if (\n event.type === 'message_start' &&\n event.message?.role !== 'assistant'\n ) {\n return [];\n }\n state.promptStarted = true;\n if (event.type === 'message_start') {\n state.stepOpen = true;\n state.pendingStepToolCallIds.clear();\n }\n state.streamedAssistantText = '';\n state.currentTextId = undefined;\n state.currentReasoningId = undefined;\n state.reasoningStarted = false;\n return [];\n }\n\n case 'message_update': {\n if (!state.promptStarted) return [];\n const update = event.assistantMessageEvent;\n if (!update) return [];\n if (update.type === 'text_delta' && typeof update.delta === 'string') {\n const parts: HarnessV1StreamPart[] = [];\n // If reasoning was active, close it before opening the text block so\n // consumers can reset block-scoped formatting (ANSI colors, etc.)\n // between sections.\n if (state.reasoningStarted && state.currentReasoningId) {\n parts.push({\n type: 'reasoning-end',\n id: state.currentReasoningId,\n });\n state.reasoningStarted = false;\n state.currentReasoningId = undefined;\n }\n if (!state.currentTextId) {\n state.currentTextId = newId();\n parts.push({ type: 'text-start', id: state.currentTextId });\n }\n state.streamedAssistantText += update.delta;\n parts.push({\n type: 'text-delta',\n id: state.currentTextId,\n delta: update.delta,\n });\n return parts;\n }\n if (\n update.type === 'thinking_delta' &&\n typeof update.delta === 'string'\n ) {\n const parts: HarnessV1StreamPart[] = [];\n // Symmetric to the text branch: close any open text block before\n // starting a fresh reasoning block.\n if (state.currentTextId) {\n parts.push({ type: 'text-end', id: state.currentTextId });\n state.currentTextId = undefined;\n }\n if (!state.currentReasoningId) {\n state.currentReasoningId = newId();\n }\n if (!state.reasoningStarted) {\n state.reasoningStarted = true;\n parts.push({ type: 'reasoning-start', id: state.currentReasoningId });\n }\n parts.push({\n type: 'reasoning-delta',\n id: state.currentReasoningId,\n delta: update.delta,\n });\n return parts;\n }\n return [];\n }\n\n case 'message_end':\n case 'turn_end': {\n if (!state.promptStarted) return [];\n const parts: HarnessV1StreamPart[] = [];\n const fullText = extractAssistantText(event.message);\n if (\n state.currentTextId &&\n fullText.startsWith(state.streamedAssistantText) &&\n fullText.length > state.streamedAssistantText.length\n ) {\n const missing = fullText.slice(state.streamedAssistantText.length);\n state.streamedAssistantText = fullText;\n parts.push({\n type: 'text-delta',\n id: state.currentTextId,\n delta: missing,\n });\n }\n if (state.currentTextId) {\n parts.push({ type: 'text-end', id: state.currentTextId });\n state.currentTextId = undefined;\n }\n if (state.reasoningStarted && state.currentReasoningId) {\n parts.push({ type: 'reasoning-end', id: state.currentReasoningId });\n state.reasoningStarted = false;\n state.currentReasoningId = undefined;\n }\n if (event.type === 'message_end') {\n for (const toolCallId of extractPiToolCallIds(event.message)) {\n state.pendingStepToolCallIds.add(toolCallId);\n }\n } else {\n state.pendingStepToolCallIds.clear();\n parts.push(...finishStep(state));\n }\n return parts;\n }\n\n case 'tool_execution_start': {\n if (!event.toolCallId || !event.toolName) return [];\n const { wire, native } = resolveToolName(state, event.toolName);\n state.observedToolNames.set(event.toolCallId, wire);\n const isMcpTool =\n !state.hostToolNames.has(native) &&\n (native === 'mcp' || native.startsWith('mcp__'));\n const providerExecuted = state.builtinToolNames.has(native) || isMcpTool;\n if (isMcpTool) state.dynamicToolCallIds.add(event.toolCallId);\n const input = serializeToolOutput(event.args ?? event.input ?? {});\n return [\n {\n type: 'tool-call',\n toolCallId: event.toolCallId,\n toolName: wire,\n input,\n ...(wire !== native ? { nativeName: native } : {}),\n ...(providerExecuted ? { providerExecuted: true } : {}),\n ...(isMcpTool ? { dynamic: true } : {}),\n } as HarnessV1StreamPart,\n ];\n }\n\n case 'tool_execution_end':\n case 'tool_result': {\n if (!event.toolCallId) return [];\n const recordedName = state.observedToolNames.get(event.toolCallId);\n const nativeName = event.toolName;\n const wire =\n recordedName ??\n (nativeName ? resolveToolName(state, nativeName).wire : undefined);\n if (!wire) return [];\n const dynamic = state.dynamicToolCallIds.delete(event.toolCallId);\n /*\n * Prefer the exact value the host submitted for user-registered tools\n * (see `hostToolResults`). Built-in tools, whose results Pi produces and\n * reports as text, are not in the map and fall back to unwrapping the\n * event's text payload.\n */\n const result = state.hostToolResults.has(event.toolCallId)\n ? ((state.hostToolResults.get(event.toolCallId) ?? null) as Extract<\n HarnessV1StreamPart,\n { type: 'tool-result' }\n >['result'])\n : dynamic\n ? parseMcpToolResult(unwrapPiToolResult(event))\n : unwrapPiToolResult(event);\n state.hostToolResults.delete(event.toolCallId);\n state.pendingStepToolCallIds.delete(event.toolCallId);\n return [\n {\n type: 'tool-result',\n toolCallId: event.toolCallId,\n toolName: wire,\n result,\n ...(event.isError ? { isError: true } : {}),\n ...(dynamic ? { dynamic: true } : {}),\n } as HarnessV1StreamPart,\n ...finishStep(state),\n ];\n }\n\n case 'compaction_end': {\n /*\n * Pi performs the compaction itself; we observe its result. Skip aborted\n * or result-less compactions (nothing happened). A result with no summary\n * still represents a real compaction, so emit it with a placeholder\n * rather than dropping the event. `reason` is `'manual'` for an explicit\n * `session.compact()` call, `'threshold'`/`'overflow'` for Pi's automatic\n * compaction — both map to `'auto'` on the wire. Pi reports `tokensBefore`\n * but not `tokensAfter`.\n */\n if (event.aborted) return [];\n const result = event.result;\n if (!result || typeof result !== 'object') return [];\n const rawSummary = (result as { summary?: unknown }).summary;\n const summary =\n typeof rawSummary === 'string' ? rawSummary : '(no summary provided)';\n const tokensBefore = (result as { tokensBefore?: unknown }).tokensBefore;\n return [\n {\n type: 'compaction',\n trigger: event.reason === 'manual' ? 'manual' : 'auto',\n summary,\n ...(typeof tokensBefore === 'number' ? { tokensBefore } : {}),\n },\n ];\n }\n\n default:\n return [];\n }\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1Prompt,\n type HarnessV1Skill,\n} from '@ai-sdk/harness';\n\nconst HARNESS_ID = 'pi';\n\n/**\n * Extract a single user text string from a `HarnessV1Prompt`. Pi's\n * `session.prompt(text)` accepts a string; multimodal user content\n * is not supported in this foundational version.\n */\nexport function extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') {\n return prompt;\n }\n\n const { content } = prompt;\n if (typeof content === 'string') {\n return content;\n }\n\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n message: `pi: only text user-message parts are supported; got '${part.type}'.`,\n harnessId: HARNESS_ID,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n\n/*\n * Frame session instructions and the user's text so the runtime treats the\n * instructions as system-provided operating guidance, not something the user\n * wrote. Without the wrapper the agent can echo the prepended text back as if\n * the user had asked for it, which is confusing since the user never typed it.\n * Applied only to the first user message of a fresh session.\n */\nexport function frameInstructions(\n instructions: string,\n userText: string,\n): string {\n return (\n '<session-instructions>\\n' +\n 'The block below is operating guidance from the system, not a message from the user — follow it, but do not mention it or attribute it to the user.\\n\\n' +\n `${instructions}\\n` +\n '</session-instructions>\\n\\n' +\n `<user-message>\\n${userText}\\n</user-message>`\n );\n}\n\n/** Serialize a tool output to the string Pi feeds back to the model. */\nexport function serializeToolOutput(output: unknown): string {\n if (typeof output === 'string') {\n return output;\n }\n const serialized = JSON.stringify(output);\n return serialized ?? 'null';\n}\n\nexport function getErrorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Validate that a name is safe to use as a filesystem path segment under\n * `.pi/skills/<name>/` or `.pi/agents/<name>.md`. Refuses anything that\n * could be interpreted as a path traversal or contains shell-sensitive\n * characters.\n */\nexport function safePiMetadataSegment(name: string, label: string): string {\n if (!/^[A-Za-z0-9._-]+$/.test(name) || name === '.' || name === '..') {\n throw new Error(`Invalid Pi ${label} name: ${name}`);\n }\n return name;\n}\n\n/** Frontmatter renderer for `.pi/skills/<name>/SKILL.md`. */\nexport function renderPiSkillFile(skill: HarnessV1Skill): string {\n return `---\\nname: ${skill.name}\\ndescription: ${skill.description}\\n---\\n\\n${skill.content}`;\n}\n","import { Type, type TSchema } from 'typebox';\n\n/**\n * Wrap a JSON Schema 7 fragment so Pi's `defineTool({ parameters })` accepts\n * it. Pi v0.77 uses TypeBox at the type level but treats `parameters` as\n * opaque schema metadata at runtime, so `Type.Unsafe(jsonSchema)` is\n * sufficient — no per-property structural conversion is needed.\n */\nexport function toolSpecToTypeBoxParameters(jsonSchema: unknown): TSchema {\n return Type.Unsafe(jsonSchema as object);\n}\n","/**\n * Pi VFS — global Node `fs` monkey-patch that redirects reads/writes against a\n * mount point (the session's sandbox working directory, e.g.\n * `/vercel/sandbox/<harnessId>-<sessionId>/...`) to a real backing directory on\n * the host. The mount point is a sandbox path that does not exist on the host,\n * so the redirect never shadows real host files.\n *\n * The mapping is process-global because Pi's upstream runtime reads and\n * writes through the shared `fs` module. Concurrent mounts are supported as\n * long as each instance uses a distinct mount point (each session's sandbox\n * working directory is unique).\n *\n * Multi-instance invariants:\n * - Multiple `PiWorkspaceVfs` instances may stay mounted concurrently.\n * - Path routing uses longest-prefix matching, so mount points must not\n * overlap.\n * - Extra `fs` patches stay installed while `mountedRoots.size > 0` and are\n * restored only after the final unmount.\n * - Mount and unmount remain synchronous, so Node's single-threaded execution\n * preserves patch/install ordering.\n *\n * Supported logical-path APIs:\n * - Sync: `existsSync`, `readFileSync`, `writeFileSync`, `mkdirSync`,\n * `readdirSync`, `renameSync`, `rmSync`, `openSync`, `statSync`,\n * `realpathSync` (+ `.native`).\n * - Callback: `mkdir`, `realpath`, `stat`, `rmdir`, `utimes`, `writeFile`.\n * - Promises: `fs.promises.mkdir`, `fs.promises.readFile`,\n * `fs.promises.writeFile`.\n *\n * Anything else is intentionally unsupported. If Pi starts using additional\n * `fs` APIs against logical roots, those call sites must be added here\n * deliberately with tests.\n */\n\nimport fs from 'node:fs';\nimport { syncBuiltinESMExports } from 'node:module';\nimport path from 'node:path';\n\ntype MountedRoot = {\n backingRoot: string;\n mountPoint: string;\n};\n\ntype WrappedRealpathSync = typeof fs.realpathSync & {\n native?: typeof fs.realpathSync.native;\n};\n\ntype Mutable<T> = {\n -readonly [K in keyof T]: T[K];\n};\n\nconst mountedRoots = new Map<string, MountedRoot>();\nconst mutableFs = fs as Mutable<typeof fs>;\nconst mutableFsPromises = fs.promises as Mutable<typeof fs.promises>;\n\nconst originalFsSyncMethods = {\n existsSync: fs.existsSync,\n mkdirSync: fs.mkdirSync,\n openSync: fs.openSync,\n readFileSync: fs.readFileSync,\n readdirSync: fs.readdirSync,\n realpathSync: fs.realpathSync,\n renameSync: fs.renameSync,\n rmSync: fs.rmSync,\n statSync: fs.statSync,\n writeFileSync: fs.writeFileSync,\n};\n\nconst originalFsCallbackMethods = {\n mkdir: fs.mkdir,\n realpath: fs.realpath,\n rmdir: fs.rmdir,\n stat: fs.stat,\n utimes: fs.utimes,\n writeFile: fs.writeFile,\n};\n\nconst originalFsPromises = {\n mkdir: fs.promises.mkdir.bind(fs.promises),\n readFile: fs.promises.readFile.bind(fs.promises),\n writeFile: fs.promises.writeFile.bind(fs.promises),\n};\n\nfunction isInsidePath(parent: string, candidate: string): boolean {\n const relative = path.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.isAbsolute(relative))\n );\n}\n\nfunction resolveAbsolutePath(inputPath: string): string {\n return path.isAbsolute(inputPath)\n ? path.normalize(inputPath)\n : path.resolve(inputPath);\n}\n\nfunction findMountedRoot(inputPath: string): MountedRoot | undefined {\n const resolvedPath = resolveAbsolutePath(inputPath);\n let bestMatch: MountedRoot | undefined;\n\n for (const mountedRoot of mountedRoots.values()) {\n if (!isInsidePath(mountedRoot.mountPoint, resolvedPath)) {\n continue;\n }\n if (\n !bestMatch ||\n mountedRoot.mountPoint.length > bestMatch.mountPoint.length\n ) {\n bestMatch = mountedRoot;\n }\n }\n\n return bestMatch;\n}\n\nfunction mapToBackingPath(inputPath: string): string | null {\n const mountedRoot = findMountedRoot(inputPath);\n if (!mountedRoot) {\n return null;\n }\n\n const resolvedPath = resolveAbsolutePath(inputPath);\n const relativePath = path.relative(mountedRoot.mountPoint, resolvedPath);\n return relativePath\n ? path.join(mountedRoot.backingRoot, relativePath)\n : mountedRoot.backingRoot;\n}\n\nfunction mapRealpathResult(inputPath: string, result: string): string {\n const mountedRoot = findMountedRoot(inputPath);\n if (!mountedRoot) {\n return result;\n }\n\n let normalizedBackingRoot = path.resolve(mountedRoot.backingRoot);\n try {\n const realpath =\n originalFsSyncMethods.realpathSync.native ??\n originalFsSyncMethods.realpathSync;\n normalizedBackingRoot = path.resolve(realpath(mountedRoot.backingRoot));\n } catch {\n // Fall back to the configured backing root when canonicalization fails.\n }\n\n const normalizedResult = path.resolve(result);\n if (!isInsidePath(normalizedBackingRoot, normalizedResult)) {\n return result;\n }\n\n const relativePath = path.relative(normalizedBackingRoot, normalizedResult);\n return relativePath\n ? path.join(mountedRoot.mountPoint, relativePath)\n : mountedRoot.mountPoint;\n}\n\nfunction mapRenamePaths(\n sourcePath: string,\n destinationPath: string,\n): [string, string] | null {\n const sourceRoot = findMountedRoot(sourcePath);\n const destinationRoot = findMountedRoot(destinationPath);\n\n if (!sourceRoot && !destinationRoot) {\n return null;\n }\n\n if (\n !sourceRoot ||\n !destinationRoot ||\n sourceRoot.mountPoint !== destinationRoot.mountPoint\n ) {\n throw new Error(\n 'Pi logical VFS paths cannot rename across mount boundaries',\n );\n }\n\n return [\n mapToBackingPath(sourcePath) ?? sourcePath,\n mapToBackingPath(destinationPath) ?? destinationPath,\n ];\n}\n\nfunction wrapSinglePathSync<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n options: {\n mapResult?: (inputPath: string, result: ReturnType<Fn>) => ReturnType<Fn>;\n } = {},\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n const result = original(\n ...([mappedPath, ...args.slice(1)] as Parameters<Fn>),\n ) as ReturnType<Fn>;\n return options.mapResult\n ? options.mapResult(inputPath, result)\n : result;\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapRenameSync<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [sourcePath, destinationPath] = args;\n if (typeof sourcePath === 'string' && typeof destinationPath === 'string') {\n const mappedPaths = mapRenamePaths(sourcePath, destinationPath);\n if (mappedPaths) {\n return original(\n ...([\n mappedPaths[0],\n mappedPaths[1],\n ...args.slice(2),\n ] as Parameters<Fn>),\n );\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapSinglePathCallback<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n options: {\n mapCallbackResult?: (inputPath: string, result: unknown) => unknown;\n } = {},\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n const nextArgs = [mappedPath, ...args.slice(1)] as unknown[];\n const maybeCallback = nextArgs.at(-1);\n if (options.mapCallbackResult && typeof maybeCallback === 'function') {\n nextArgs[nextArgs.length - 1] = (\n error: NodeJS.ErrnoException | null,\n result: unknown,\n ...rest: unknown[]\n ) => {\n const mappedResult = error\n ? result\n : options.mapCallbackResult?.(inputPath, result);\n (maybeCallback as (...callbackArgs: unknown[]) => void)(\n error,\n mappedResult,\n ...rest,\n );\n };\n }\n return original(...(nextArgs as Parameters<Fn>));\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapSinglePathPromise<\n Fn extends (...args: never[]) => Promise<unknown>,\n>(original: Fn): Fn {\n return (async (...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n return await original(\n ...([mappedPath, ...args.slice(1)] as Parameters<Fn>),\n );\n }\n }\n return await original(...args);\n }) as Fn;\n}\n\nfunction createWrappedRealpathSync(): WrappedRealpathSync {\n const wrapped = wrapSinglePathSync(originalFsSyncMethods.realpathSync, {\n mapResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n }) as WrappedRealpathSync;\n\n if (originalFsSyncMethods.realpathSync.native) {\n wrapped.native = wrapSinglePathSync(\n originalFsSyncMethods.realpathSync.native,\n {\n mapResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n },\n ) as typeof fs.realpathSync.native;\n }\n\n return wrapped;\n}\n\nconst wrappedFsSyncMethods = {\n existsSync: wrapSinglePathSync(originalFsSyncMethods.existsSync),\n mkdirSync: wrapSinglePathSync(originalFsSyncMethods.mkdirSync),\n openSync: wrapSinglePathSync(originalFsSyncMethods.openSync),\n readFileSync: wrapSinglePathSync(originalFsSyncMethods.readFileSync),\n readdirSync: wrapSinglePathSync(originalFsSyncMethods.readdirSync),\n realpathSync: createWrappedRealpathSync(),\n renameSync: wrapRenameSync(originalFsSyncMethods.renameSync),\n rmSync: wrapSinglePathSync(originalFsSyncMethods.rmSync),\n statSync: wrapSinglePathSync(originalFsSyncMethods.statSync),\n writeFileSync: wrapSinglePathSync(originalFsSyncMethods.writeFileSync),\n};\n\nconst wrappedFsCallbackMethods = {\n mkdir: wrapSinglePathCallback(originalFsCallbackMethods.mkdir),\n realpath: wrapSinglePathCallback(originalFsCallbackMethods.realpath, {\n mapCallbackResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n }),\n rmdir: wrapSinglePathCallback(originalFsCallbackMethods.rmdir),\n stat: wrapSinglePathCallback(originalFsCallbackMethods.stat),\n utimes: wrapSinglePathCallback(originalFsCallbackMethods.utimes),\n writeFile: wrapSinglePathCallback(originalFsCallbackMethods.writeFile),\n};\n\nconst wrappedFsPromises = {\n mkdir: wrapSinglePathPromise(originalFsPromises.mkdir),\n readFile: wrapSinglePathPromise(originalFsPromises.readFile),\n writeFile: wrapSinglePathPromise(originalFsPromises.writeFile),\n};\n\nfunction areExtraFsPatchesInstalled(): boolean {\n return mutableFs.existsSync === wrappedFsSyncMethods.existsSync;\n}\n\nfunction installExtraFsPatches() {\n if (areExtraFsPatchesInstalled()) return;\n\n mutableFs.existsSync = wrappedFsSyncMethods.existsSync;\n mutableFs.mkdirSync = wrappedFsSyncMethods.mkdirSync;\n mutableFs.openSync = wrappedFsSyncMethods.openSync;\n mutableFs.readFileSync = wrappedFsSyncMethods.readFileSync;\n mutableFs.readdirSync = wrappedFsSyncMethods.readdirSync;\n mutableFs.realpathSync = wrappedFsSyncMethods.realpathSync;\n mutableFs.renameSync = wrappedFsSyncMethods.renameSync;\n mutableFs.rmSync = wrappedFsSyncMethods.rmSync;\n mutableFs.statSync = wrappedFsSyncMethods.statSync;\n mutableFs.writeFileSync = wrappedFsSyncMethods.writeFileSync;\n\n mutableFs.mkdir = wrappedFsCallbackMethods.mkdir;\n mutableFs.realpath = wrappedFsCallbackMethods.realpath;\n mutableFs.rmdir = wrappedFsCallbackMethods.rmdir;\n mutableFs.stat = wrappedFsCallbackMethods.stat;\n mutableFs.utimes = wrappedFsCallbackMethods.utimes;\n mutableFs.writeFile = wrappedFsCallbackMethods.writeFile;\n\n mutableFsPromises.mkdir = wrappedFsPromises.mkdir;\n mutableFsPromises.readFile = wrappedFsPromises.readFile;\n mutableFsPromises.writeFile = wrappedFsPromises.writeFile;\n\n syncBuiltinESMExports();\n}\n\nfunction restoreExtraFsPatches() {\n if (!areExtraFsPatchesInstalled()) return;\n\n mutableFs.existsSync = originalFsSyncMethods.existsSync;\n mutableFs.mkdirSync = originalFsSyncMethods.mkdirSync;\n mutableFs.openSync = originalFsSyncMethods.openSync;\n mutableFs.readFileSync = originalFsSyncMethods.readFileSync;\n mutableFs.readdirSync = originalFsSyncMethods.readdirSync;\n mutableFs.realpathSync = originalFsSyncMethods.realpathSync;\n mutableFs.renameSync = originalFsSyncMethods.renameSync;\n mutableFs.rmSync = originalFsSyncMethods.rmSync;\n mutableFs.statSync = originalFsSyncMethods.statSync;\n mutableFs.writeFileSync = originalFsSyncMethods.writeFileSync;\n\n mutableFs.mkdir = originalFsCallbackMethods.mkdir;\n mutableFs.realpath = originalFsCallbackMethods.realpath;\n mutableFs.rmdir = originalFsCallbackMethods.rmdir;\n mutableFs.stat = originalFsCallbackMethods.stat;\n mutableFs.utimes = originalFsCallbackMethods.utimes;\n mutableFs.writeFile = originalFsCallbackMethods.writeFile;\n\n mutableFsPromises.mkdir = originalFsPromises.mkdir;\n mutableFsPromises.readFile = originalFsPromises.readFile;\n mutableFsPromises.writeFile = originalFsPromises.writeFile;\n\n syncBuiltinESMExports();\n}\n\nexport class PiWorkspaceVfs {\n private backingRoot: string | null = null;\n private mountPoint: string | null = null;\n\n private disposeMount(): void {\n if (this.mountPoint) {\n mountedRoots.delete(this.mountPoint);\n }\n this.backingRoot = null;\n this.mountPoint = null;\n }\n\n mount(backingRoot: string, mountPoint: string): void {\n if (this.backingRoot === backingRoot && this.mountPoint === mountPoint) {\n return;\n }\n\n const resolvedBackingRoot = path.resolve(backingRoot);\n const resolvedMountPoint = path.resolve(mountPoint);\n if (this.mountPoint) {\n this.disposeMount();\n }\n\n mountedRoots.set(resolvedMountPoint, {\n backingRoot: resolvedBackingRoot,\n mountPoint: resolvedMountPoint,\n });\n installExtraFsPatches();\n\n this.backingRoot = resolvedBackingRoot;\n this.mountPoint = resolvedMountPoint;\n }\n\n unmount(): void {\n this.disposeMount();\n\n if (mountedRoots.size === 0) {\n restoreExtraFsPatches();\n }\n }\n}\n","import {\n mkdir,\n readFile,\n readdir,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises';\nimport path from 'node:path';\nimport { shellQuote } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\n\n/*\n * Pi runs on the host with its working directory pointed at the local mirror,\n * but the only thing it reads from that directory is its own resource\n * configuration: the `.pi` and `.agents` directories (skills, prompts, themes,\n * extensions) and the root-level agent context files (`AGENTS.md`). The model\n * never reads workspace source through the host — file reads, directory\n * listings, and greps all run as tools against the sandbox. Mirroring the whole\n * sandbox workspace to the host would therefore copy files Pi never looks at,\n * one `readBinaryFile` round-trip per file. For a real project that has been\n * cloned and had its dependencies installed (hundreds of thousands of files\n * under `node_modules`) that makes session startup take hours. The mirror is\n * consequently scoped to exactly the paths Pi's resource loader consults.\n *\n * Within those config directories, symlinks are resolved and their targets\n * copied as real files. `.agents/skills` is frequently a symlink to a `skills`\n * directory living elsewhere in the workspace; a mirrored symlink would dangle\n * because its target falls outside the scoped mirror, so the linked content is\n * walked and copied verbatim instead.\n */\nconst PI_CONFIG_DIRS = ['.pi', '.agents'] as const;\nconst PI_CONTEXT_FILENAMES = ['AGENTS.md', 'AGENTS.MD'] as const;\n\nfunction normalizeRelativePath(inputPath: string): string {\n const normalized = inputPath.split(path.posix.sep).join(path.sep);\n const relative = path.normalize(normalized);\n if (\n relative === '' ||\n relative === '.' ||\n path.isAbsolute(relative) ||\n relative === '..' ||\n relative.startsWith(`..${path.sep}`)\n ) {\n throw new Error(\n `Sandbox workspace mirror received an invalid relative path: ${inputPath}`,\n );\n }\n return relative;\n}\n\nasync function readCommandOutput(\n sandbox: Experimental_SandboxSession,\n command: string,\n): Promise<string> {\n const result = await sandbox.run({ command });\n if (result.exitCode != null && result.exitCode !== 0) {\n throw new Error(\n result.stderr ||\n result.stdout ||\n `Sandbox command failed with exit code ${result.exitCode}`,\n );\n }\n return result.stdout || result.stderr;\n}\n\nasync function listRemoteWorkspaceEntries(\n sandbox: Experimental_SandboxSession,\n sandboxWorkDir: string,\n): Promise<{\n directories: string[];\n files: Array<{ relativePath: string; sandboxPath: string }>;\n}> {\n // Enumerate only the `.pi`/`.agents` config subtrees plus the root-level\n // context files — never the rest of the workspace. Use shell glob traversal\n // instead of `find -L`, which is not supported by all sandbox shells.\n // Resolve each scoped root path component explicitly with `readlink`,\n // retaining both the scoped mirror path and the resolved sandbox path. Once\n // a root is resolved, queued descendants use physical parent paths and only\n // need resolution when the descendant itself is a symlink. This avoids\n // relying on shells that can inspect a symlinked directory but cannot\n // traverse paths below it, including when the symlink is an ancestor of the\n // sandbox work directory, without repeatedly resolving every component of\n // deep ordinary paths.\n const scopedPaths = [\n ...PI_CONFIG_DIRS.map(dir => `./${dir}`),\n ...PI_CONTEXT_FILENAMES.map(name => `./${name}`),\n ];\n const listCommand = [\n `pi_config_sources=(${scopedPaths\n .map(scopedPath =>\n shellQuote(path.posix.join(sandboxWorkDir, scopedPath.slice(2))),\n )\n .join(' ')})`,\n `pi_config_relatives=(${scopedPaths\n .map(scopedPath => shellQuote(scopedPath.slice(2)))\n .join(' ')})`,\n `pi_config_ancestors=(${scopedPaths.map(() => \"''\").join(' ')})`,\n `pi_config_resolve_ancestors=(${scopedPaths.map(() => '1').join(' ')})`,\n 'pi_config_index=0',\n 'while [ \"$pi_config_index\" -lt \"${#pi_config_sources[@]}\" ]; do',\n ' source=${pi_config_sources[$pi_config_index]}',\n ' relative=${pi_config_relatives[$pi_config_index]}',\n ' ancestors=${pi_config_ancestors[$pi_config_index]}',\n ' resolve_ancestors=${pi_config_resolve_ancestors[$pi_config_index]}',\n ' pi_config_index=$((pi_config_index + 1))',\n ' if [ \"$resolve_ancestors\" = 1 ] || [ -L \"$source\" ]; then',\n ' pending=$source',\n ' resolved=',\n ' seen_links=',\n ' case \"$pending\" in',\n ' /*) ;;',\n ' *) pending=$PWD/$pending ;;',\n ' esac',\n ' while [ -n \"$pending\" ]; do',\n ' pending=${pending#/}',\n ' [ -n \"$pending\" ] || break',\n ' component=${pending%%/*}',\n ' if [ \"$pending\" = \"$component\" ]; then',\n ' pending=',\n ' else',\n ' pending=${pending#*/}',\n ' fi',\n ' case \"$component\" in',\n ' \"\"|.) continue ;;',\n ' ..)',\n ' resolved=${resolved%/*}',\n ' continue',\n ' ;;',\n ' esac',\n ' candidate=$resolved/$component',\n ' if [ -L \"$candidate\" ]; then',\n ' case \"$seen_links\" in',\n ' *\"',\n '\"$candidate\"',\n '\"*)',\n ` printf 'Pi config traversal encountered a symlink cycle at %s\\\\n' \"$candidate\" >&2`,\n ' exit 1',\n ' ;;',\n ' esac',\n ' seen_links=$seen_links\"',\n '\"$candidate\"',\n '\"',\n ' target=$(readlink \"$candidate\") || exit $?',\n ' case \"$target\" in',\n ' /*) pending=$target${pending:+/$pending} ;;',\n ' *) pending=${candidate%/*}/$target${pending:+/$pending} ;;',\n ' esac',\n ' resolved=',\n ' else',\n ' resolved=$candidate',\n ' fi',\n ' done',\n ' if [ -z \"$resolved\" ]; then',\n ` printf 'Pi config traversal resolved %s to the filesystem root; skipping\\\\n' \"$relative\" >&2`,\n ' continue',\n ' fi',\n ' source=$resolved',\n ' fi',\n ' if [ -d \"$source\" ]; then',\n ' case \"$ancestors\" in',\n ' *\"',\n '\"$source\"',\n '\"*)',\n ` printf 'Pi config traversal encountered a symlink cycle at %s\\\\n' \"$relative\" >&2`,\n ' exit 1',\n ' ;;',\n ' esac',\n ' ancestors=$ancestors\"',\n '\"$source\"',\n '\"',\n ` printf 'd\\\\t%s\\\\n' \"$relative\"`,\n ' for child in \"$source\"/* \"$source\"/.[!.]* \"$source\"/..?*; do',\n ' if [ -L \"$child\" ] || [ -d \"$child\" ] || [ -f \"$child\" ]; then',\n ' child_name=${child##*/}',\n ' pi_config_sources+=(\"$child\")',\n ' pi_config_relatives+=(\"$relative/$child_name\")',\n ' pi_config_ancestors+=(\"$ancestors\")',\n ' pi_config_resolve_ancestors+=(0)',\n ' fi',\n ' done',\n ' elif [ -f \"$source\" ]; then',\n ` printf 'f\\\\t%s\\\\t%s\\\\n' \"$relative\" \"$source\"`,\n ' fi',\n ' true',\n 'done',\n 'true',\n ].join('\\n');\n\n const output = await readCommandOutput(\n sandbox,\n [`cd ${shellQuote(sandboxWorkDir)}`, listCommand].join(' && '),\n );\n\n const directories: string[] = [];\n const files: Array<{ relativePath: string; sandboxPath: string }> = [];\n\n for (const line of output.split('\\n').filter(Boolean)) {\n const [kind, rawPath, sandboxPath] = line.split('\\t', 3);\n if (!rawPath) continue;\n\n const relativePath = normalizeRelativePath(rawPath);\n if (kind === 'd') directories.push(relativePath);\n else if (kind === 'f' && sandboxPath) {\n files.push({ relativePath, sandboxPath });\n }\n }\n\n return { directories, files };\n}\n\nasync function pathKind(\n target: string,\n): Promise<'file' | 'directory' | undefined> {\n try {\n const stats = await stat(target);\n if (stats.isDirectory()) return 'directory';\n if (stats.isFile()) return 'file';\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function collectHostSubtree(\n rootDir: string,\n currentDir: string,\n directories: string[],\n files: string[],\n): Promise<void> {\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) continue;\n const absolutePath = path.join(currentDir, entry.name);\n const relativePath = path.relative(rootDir, absolutePath);\n if (entry.isDirectory()) {\n directories.push(relativePath);\n await collectHostSubtree(rootDir, absolutePath, directories, files);\n } else if (entry.isFile()) {\n files.push(relativePath);\n }\n }\n}\n\n/**\n * Enumerate the locally-mirrored entries that fall within Pi's scope: the\n * `.pi`/`.agents` config subtrees and the root-level context files. Anything\n * else on the local side (it should not normally exist) is intentionally\n * ignored so the reconcile below neither copies nor deletes it.\n */\nasync function collectHostScopedEntries(\n rootDir: string,\n): Promise<{ directories: string[]; files: string[] }> {\n const directories: string[] = [];\n const files: string[] = [];\n\n for (const dir of PI_CONFIG_DIRS) {\n const configDir = path.join(rootDir, dir);\n if ((await pathKind(configDir)) === 'directory') {\n directories.push(dir);\n await collectHostSubtree(rootDir, configDir, directories, files);\n }\n }\n\n for (const name of PI_CONTEXT_FILENAMES) {\n if ((await pathKind(path.join(rootDir, name))) === 'file') {\n files.push(name);\n }\n }\n\n return { directories, files };\n}\n\nfunction buildRequiredDirectories(\n remoteDirectories: string[],\n remoteFiles: Array<{ relativePath: string }>,\n): Set<string> {\n const directories = new Set<string>();\n for (const directory of remoteDirectories) {\n directories.add(normalizeRelativePath(directory));\n }\n for (const file of remoteFiles) {\n let current = path.dirname(normalizeRelativePath(file.relativePath));\n while (current !== '.' && current !== path.sep && current.length > 0) {\n directories.add(current);\n current = path.dirname(current);\n }\n }\n return directories;\n}\n\nexport async function syncHostWorkspaceFromSandbox(args: {\n sandbox: Experimental_SandboxSession;\n sandboxWorkDir: string;\n hostWorkDir: string;\n}): Promise<void> {\n const { sandbox, sandboxWorkDir, hostWorkDir } = args;\n const remoteEntries = await listRemoteWorkspaceEntries(\n sandbox,\n sandboxWorkDir,\n );\n const hostEntries = await collectHostScopedEntries(hostWorkDir);\n const remoteFiles = new Set(\n remoteEntries.files.map(file => file.relativePath),\n );\n const requiredDirectories = buildRequiredDirectories(\n remoteEntries.directories,\n remoteEntries.files,\n );\n\n for (const relativePath of hostEntries.files) {\n if (!remoteFiles.has(relativePath)) {\n await rm(path.join(hostWorkDir, relativePath), { force: true });\n }\n }\n\n const removableDirectories = [...hostEntries.directories]\n .filter(p => !requiredDirectories.has(p))\n .sort((a, b) => b.length - a.length);\n for (const relativePath of removableDirectories) {\n await rm(path.join(hostWorkDir, relativePath), {\n recursive: true,\n force: true,\n });\n }\n\n for (const relativePath of [...requiredDirectories].sort(\n (a, b) => a.length - b.length,\n )) {\n await mkdir(path.join(hostWorkDir, relativePath), { recursive: true });\n }\n\n for (const { relativePath, sandboxPath } of remoteEntries.files) {\n const bytes = await sandbox.readBinaryFile({ path: sandboxPath });\n if (!bytes) {\n throw new Error(\n `Sandbox workspace file disappeared during mirror sync: ${sandboxPath}`,\n );\n }\n const content = Buffer.from(bytes);\n\n const hostPath = path.join(hostWorkDir, relativePath);\n let shouldWrite = true;\n try {\n const existing = await readFile(hostPath);\n shouldWrite = !existing.equals(content);\n } catch {\n shouldWrite = true;\n }\n\n if (shouldWrite) {\n await mkdir(path.dirname(hostPath), { recursive: true });\n await writeFile(hostPath, content);\n }\n }\n}\n\nexport async function writeHostWorkspaceFile(\n hostWorkDir: string,\n relativePath: string,\n content: Buffer,\n): Promise<void> {\n const normalizedPath = normalizeRelativePath(relativePath);\n const hostPath = path.join(hostWorkDir, normalizedPath);\n await mkdir(path.dirname(hostPath), { recursive: true });\n await writeFile(hostPath, content);\n}\n","import { createPi } from './pi-harness';\n\n/**\n * Default `pi` harness instance with no overrides — suitable for the common\n * case where Pi's defaults are fine. Equivalent to `createPi()`.\n */\nexport const pi = createPi();\n\nexport { createPi } from './pi-harness';\nexport { VERSION } from './version';\nexport type { PiHarnessSettings } from './pi-harness';\nexport type { PiAuthenticationMode, PiAuthOptions } from './pi-auth';\n"],"mappings":"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","names":["z","mkdir","rm","path","Type","HarnessCapabilityUnsupportedError","z","getAiGatewayAuthFromEnv","path","path","writeFile","path","path","isInsidePath","mkdir","readFile","writeFile","path","shellQuote","HARNESS_ID","path","mkdir","tool","input","rm","HarnessCapabilityUnsupportedError","Type","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/pi-harness.ts","../src/pi-resume-state.ts","../src/pi-session.ts","../src/pi-auth.ts","../src/version.ts","../src/pi-events.ts","../src/pi-model-resolver.ts","../src/pi-paths.ts","../src/pi-remote-ops.ts","../src/pi-skills.ts","../src/pi-translate.ts","../src/pi-utils.ts","../src/pi-typebox-adapter.ts","../src/pi-workspace-vfs.ts","../src/pi-workspace-mirror.ts","../src/index.ts"],"sourcesContent":["import {\n commonTool,\n type HarnessV1,\n type HarnessV1BuiltinTool,\n} from '@ai-sdk/harness';\nimport { tool } from '@ai-sdk/provider-utils';\nimport type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\nimport { z } from 'zod/v4';\nimport type { PiAuthOptions } from './pi-auth';\nimport { piResumeStateSchema } from './pi-resume-state';\nimport { createPiSession, type PiThinkingLevel } from './pi-session';\nimport { VERSION } from './version';\n\n/**\n * Value to use in User-Agent and `x-client-app` headers.\n */\nconst PI_CLIENT_APP = `ai-sdk/harness-pi/${VERSION}`;\n\n/**\n * Configuration knobs for `createPi`. Pi runs as an in-process Node library\n * (no bridge), so there's no `port` or `startupTimeoutMs` to set.\n */\nexport type PiHarnessSettings = {\n /** Where Pi sources API keys / gateway credentials from. */\n readonly auth?: PiAuthOptions;\n /**\n * Pi model id (or name). Leaving this unset falls back to the AI Gateway\n * default when `AI_GATEWAY_API_KEY` / `VERCEL_OIDC_TOKEN` is set, and to\n * Pi's own resolution otherwise.\n */\n readonly model?: string;\n /**\n * Pi's extended-thinking budget level. Maps directly to the SDK's\n * `thinkingLevel` option on `createAgentSession`.\n */\n readonly thinkingLevel?: PiThinkingLevel;\n /**\n * Directory holding Pi's global agent config (auth.json, models.json,\n * settings.json). When omitted, a per-session temp dir is used. Pass the\n * user's agent dir (e.g. `~/.pi/agent/`) to reuse their CLI auth and\n * model settings.\n */\n readonly agentDir?: string;\n /**\n * MCP server definitions keyed by server name. Each definition uses the\n * underlying runtime's native MCP server configuration format.\n */\n readonly mcpServers?: Record<string, unknown>;\n /**\n * Trusted inline Pi extensions loaded for each harness session.\n *\n * Filesystem-discovered user and project extensions remain disabled.\n */\n readonly extensionFactories?: ReadonlyArray<ExtensionFactory>;\n};\n\nconst PI_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'read',\n toolUseKind: 'readonly',\n description: 'Read file contents.',\n inputSchema: z.object({\n file_path: z.string(),\n }),\n }),\n write: commonTool('write', {\n nativeName: 'write',\n toolUseKind: 'edit',\n description: 'Overwrite or create a file.',\n inputSchema: z.object({\n file_path: z.string(),\n content: z.string(),\n }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit',\n toolUseKind: 'edit',\n description: 'Edit a file by exact string replacement.',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'bash',\n toolUseKind: 'bash',\n description: 'Execute a shell command in the sandbox.',\n inputSchema: z.object({\n command: z.string(),\n timeout: z.number().optional(),\n }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents with regex.',\n inputSchema: z.object({\n pattern: z.string(),\n path: z.string().optional(),\n glob: z.string().optional(),\n ignoreCase: z.boolean().optional(),\n literal: z.boolean().optional(),\n context: z.number().optional(),\n limit: z.number().optional(),\n }),\n }),\n glob: commonTool('glob', {\n nativeName: 'find',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern.',\n inputSchema: z.object({\n pattern: z.string(),\n path: z.string().optional(),\n limit: z.number().optional(),\n }),\n }),\n ls: {\n ...tool({\n description: 'List directory entries.',\n inputSchema: z.object({\n path: z.string().optional(),\n limit: z.number().optional(),\n }),\n outputSchema: z.unknown(),\n }),\n nativeName: 'ls',\n toolUseKind: 'readonly',\n } as HarnessV1BuiltinTool,\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\nexport function createPi(\n settings: PiHarnessSettings = {},\n): HarnessV1<typeof PI_BUILTIN_TOOLS> {\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'pi',\n builtinTools: PI_BUILTIN_TOOLS,\n supportsBuiltinToolApprovals: true,\n supportsBuiltinToolFiltering: true,\n lifecycleStateSchema: piResumeStateSchema,\n doStart: async startOpts => {\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const resumeData = lifecycleState?.data as\n | { sessionFileName?: string }\n | undefined;\n\n return createPiSession({\n sessionId: startOpts.sessionId,\n sandboxSession: startOpts.sandboxSession,\n sessionWorkDir: startOpts.sessionWorkDir,\n skills: startOpts.skills ?? [],\n settings: {\n ...(settings.auth ? { auth: settings.auth } : {}),\n ...(settings.model ? { model: settings.model } : {}),\n ...(settings.thinkingLevel\n ? { thinkingLevel: settings.thinkingLevel }\n : {}),\n ...(settings.mcpServers ? { mcpServers: settings.mcpServers } : {}),\n ...(settings.extensionFactories\n ? { extensionFactories: settings.extensionFactories }\n : {}),\n },\n clientApp: PI_CLIENT_APP,\n isResume: lifecycleState != null,\n permissionMode: startOpts.permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n ...(resumeData?.sessionFileName\n ? { resumeSessionFileName: resumeData.sessionFileName }\n : {}),\n ...(startOpts.abortSignal\n ? { abortSignal: startOpts.abortSignal }\n : {}),\n ...(settings.agentDir ? { agentDir: settings.agentDir } : {}),\n });\n },\n };\n}\n","import { createHash } from 'node:crypto';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nconst PI_SESSION_FILE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*\\.jsonl?$/;\n\nexport function safePiSessionFileName(sessionFileName: string): string {\n if (!PI_SESSION_FILE_NAME_PATTERN.test(sessionFileName)) {\n throw new Error(`Invalid Pi session file name: ${sessionFileName}`);\n }\n return sessionFileName;\n}\n\nconst piSessionFileNameSchema = z\n .string()\n .refine(\n sessionFileName => PI_SESSION_FILE_NAME_PATTERN.test(sessionFileName),\n 'Pi sessionFileName must be a safe .jsonl or .json basename.',\n );\n\n/**\n * Schema for the adapter-specific portion of lifecycle state `data` produced\n * by Pi's resumable lifecycle methods. Carries the basename\n * (including extension) of the Pi session file. The actual session bytes live\n * in a private, session-scoped directory under sandbox HOME so they survive\n * cross-process resume without appearing in the agent workspace.\n */\nexport const piResumeStateSchema = z.looseObject({\n sessionFileName: piSessionFileNameSchema.optional(),\n});\n\nexport type PiResumeStateData = z.infer<typeof piResumeStateSchema>;\n\nexport function resolvePiPrivateSessionDirectory(input: {\n readonly sandboxHomeDir: string;\n readonly sessionWorkDir: string;\n readonly sessionId: string;\n}): string {\n const sessionKey = createHash('sha256').update(input.sessionId).digest('hex');\n const privateSessionDir = path.posix.join(\n input.sandboxHomeDir,\n '.ai-sdk',\n 'harness-pi',\n sessionKey,\n );\n const relativePath = path.posix.relative(\n input.sessionWorkDir,\n privateSessionDir,\n );\n if (\n relativePath === '' ||\n (!relativePath.startsWith('../') && !path.posix.isAbsolute(relativePath))\n ) {\n throw new Error(\n `Pi private session directory ${JSON.stringify(privateSessionDir)} must be outside sessionWorkDir ${JSON.stringify(input.sessionWorkDir)}.`,\n );\n }\n return privateSessionDir;\n}\n\nfunction resolveContainedHostPath(input: {\n readonly baseDir: string;\n readonly sessionFileName: string;\n}): string {\n const baseDir = path.resolve(input.baseDir);\n const filePath = path.resolve(\n baseDir,\n safePiSessionFileName(input.sessionFileName),\n );\n const relativePath = path.relative(baseDir, filePath);\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n path.isAbsolute(relativePath)\n ) {\n throw new Error(`Invalid Pi session file name: ${input.sessionFileName}`);\n }\n return filePath;\n}\n\nfunction resolveContainedSandboxPath(input: {\n readonly privateSessionDir: string;\n readonly sessionFileName: string;\n}): string {\n const sessionDir = path.posix.resolve(input.privateSessionDir);\n const filePath = path.posix.resolve(\n sessionDir,\n safePiSessionFileName(input.sessionFileName),\n );\n const relativePath = path.posix.relative(sessionDir, filePath);\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n path.posix.isAbsolute(relativePath)\n ) {\n throw new Error(`Invalid Pi session file name: ${input.sessionFileName}`);\n }\n return filePath;\n}\n\n/**\n * Copy the Pi session file from the host's local mirror to private sandbox\n * state. Called during resumable lifecycle methods so the session survives a\n * sandbox snapshot or a process handoff.\n */\nexport async function persistSessionFileToSandbox(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly privateSessionDir: string;\n readonly hostSessionDir: string;\n readonly sessionFileName: string;\n readonly abortSignal?: AbortSignal;\n}): Promise<void> {\n const hostPath = resolveContainedHostPath({\n baseDir: args.hostSessionDir,\n sessionFileName: args.sessionFileName,\n });\n const content = await readFile(hostPath);\n const remotePath = resolveContainedSandboxPath({\n privateSessionDir: args.privateSessionDir,\n sessionFileName: args.sessionFileName,\n });\n await args.sandbox.writeBinaryFile({\n path: remotePath,\n content,\n ...(args.abortSignal ? { abortSignal: args.abortSignal } : {}),\n });\n}\n\n/**\n * Pull a previously persisted Pi session file from the sandbox into a fresh\n * local mirror dir. Called during `doStart` on the resume path before Pi is\n * initialised. Returns the absolute path of the local session file or\n * `undefined` if the sandbox copy is missing.\n */\nexport async function pullSessionFileFromSandbox(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly privateSessionDir: string;\n readonly hostSessionDir: string;\n readonly sessionFileName: string;\n readonly abortSignal?: AbortSignal;\n}): Promise<string | undefined> {\n const remotePath = resolveContainedSandboxPath({\n privateSessionDir: args.privateSessionDir,\n sessionFileName: args.sessionFileName,\n });\n const bytes = await args.sandbox.readBinaryFile({\n path: remotePath,\n ...(args.abortSignal ? { abortSignal: args.abortSignal } : {}),\n });\n if (bytes == null) return undefined;\n await mkdir(args.hostSessionDir, { recursive: true });\n const hostPath = resolveContainedHostPath({\n baseDir: args.hostSessionDir,\n sessionFileName: args.sessionFileName,\n });\n await writeFile(hostPath, bytes);\n return hostPath;\n}\n","import {\n createAgentSession,\n DefaultResourceLoader,\n defineTool,\n ModelRegistry,\n ModelRuntime,\n SessionManager,\n SettingsManager,\n type AgentSession,\n type AgentToolResult,\n type ExtensionFactory,\n type Skill,\n type ToolDefinition,\n} from '@earendil-works/pi-coding-agent';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { Type } from 'typebox';\nimport {\n HarnessCapabilityUnsupportedError,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnOptions,\n type HarnessV1ContinueTurnState,\n type HarnessV1PromptControl,\n type HarnessV1PromptTurnOptions,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n type HarnessV1ToolSpec,\n} from '@ai-sdk/harness';\nimport {\n getRestrictedSandboxSession,\n resolveSandboxHomeDir,\n} from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport {\n registerPiProviders,\n resolvePiEnv,\n type PiAuthOptions,\n} from './pi-auth';\nimport { getPiTerminalError, parseNativeEvent } from './pi-events';\nimport { createPiModelResolver } from './pi-model-resolver';\nimport { createPiPathMapper } from './pi-paths';\nimport { createPiRemoteOps, type PiRemoteOps } from './pi-remote-ops';\nimport { writePiSkills } from './pi-skills';\nimport {\n persistSessionFileToSandbox,\n pullSessionFileFromSandbox,\n resolvePiPrivateSessionDirectory,\n safePiSessionFileName,\n} from './pi-resume-state';\nimport {\n createPiTranslatorState,\n finishPiApprovalStep,\n translatePiEvent,\n type PiTranslatorState,\n} from './pi-translate';\nimport { toolSpecToTypeBoxParameters } from './pi-typebox-adapter';\nimport {\n extractUserText,\n safePiMetadataSegment,\n serializeToolOutput,\n} from './pi-utils';\nimport { PiWorkspaceVfs } from './pi-workspace-vfs';\nimport { syncHostWorkspaceFromSandbox } from './pi-workspace-mirror';\n\nconst HARNESS_ID = 'pi';\n\n/*\n * pi-mcp-adapter publishes TypeScript source as its package entry point. A\n * non-literal specifier keeps the repository type-check focused on this\n * package's compatibility boundary instead of compiling dependency internals.\n */\nconst PI_MCP_ADAPTER_PACKAGE: string = 'pi-mcp-adapter';\n\ntype PiMcpAdapterModule = {\n createMcpAdapter(options: {\n config: {\n mcpServers: Record<string, unknown>;\n settings: {\n directTools: boolean;\n toolPrefix: string;\n disableProxyTool: boolean;\n };\n };\n }): ExtensionFactory;\n};\n\n/*\n * Pi runs in this Node process, not behind an attachable in-sandbox bridge.\n * During a tool approval pause the Pi turn is still alive and blocked on the\n * custom tool promise, so detach must park that live session for the next\n * same-process resume instead of stopping it and resolving the promise as an\n * error. Cross-process resume still falls back to the persisted session file.\n */\nconst parkedPiSessions = new Map<string, HarnessV1Session>();\n\n/**\n * Whether a discovered resource path belongs to a specific directory.\n */\nfunction isWithinDirectory(parent: string, child: string): boolean {\n const rel = path.relative(parent, child);\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n}\n\n/**\n * Whether a discovered resource path belongs to the session workspace — either\n * the sandbox-side working directory the model sees (`sessionWorkDir`) or its\n * host-side mirror (`hostWorkDir`).\n */\nfunction isWithinWorkspace(\n candidate: string,\n sessionWorkDir: string,\n hostWorkDir: string,\n): boolean {\n return (\n isWithinDirectory(sessionWorkDir, candidate) ||\n isWithinDirectory(hostWorkDir, candidate)\n );\n}\n\nfunction createHarnessPiSkills({\n skills,\n sandboxSkillRootDir,\n}: {\n skills: ReadonlyArray<HarnessV1Skill>;\n sandboxSkillRootDir: string;\n}): Skill[] {\n return skills.map(skill => {\n const name = safePiMetadataSegment(skill.name, 'skill');\n const baseDir = path.posix.join(sandboxSkillRootDir, name);\n const filePath = path.posix.join(baseDir, 'SKILL.md');\n return {\n name: skill.name,\n description: skill.description,\n filePath,\n baseDir,\n sourceInfo: {\n path: filePath,\n source: 'harness',\n scope: 'temporary',\n origin: 'top-level',\n baseDir,\n },\n disableModelInvocation: false,\n };\n });\n}\n\nconst PI_NATIVE_BUILTIN_NAMES = [\n 'read',\n 'write',\n 'edit',\n 'bash',\n 'grep',\n 'find',\n 'ls',\n] as const;\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n find: 'glob',\n};\n\nconst PUBLIC_TO_NATIVE: Readonly<\n Record<string, (typeof PI_NATIVE_BUILTIN_NAMES)[number]>\n> = {\n read: 'read',\n write: 'write',\n edit: 'edit',\n bash: 'bash',\n grep: 'grep',\n glob: 'find',\n ls: 'ls',\n};\n\nconst PI_NATIVE_TOOL_KINDS: Readonly<\n Record<(typeof PI_NATIVE_BUILTIN_NAMES)[number], 'readonly' | 'edit' | 'bash'>\n> = {\n read: 'readonly',\n write: 'edit',\n edit: 'edit',\n bash: 'bash',\n grep: 'readonly',\n find: 'readonly',\n ls: 'readonly',\n};\n\nfunction resolveActivePiBuiltinNames(\n toolFiltering: HarnessV1BuiltinToolFiltering | undefined,\n): ReadonlyArray<(typeof PI_NATIVE_BUILTIN_NAMES)[number]> {\n if (toolFiltering == null) return PI_NATIVE_BUILTIN_NAMES;\n if (toolFiltering.mode === 'allow') {\n return toolFiltering.toolNames\n .map(name => PUBLIC_TO_NATIVE[name])\n .filter(\n (name): name is (typeof PI_NATIVE_BUILTIN_NAMES)[number] =>\n name != null,\n );\n }\n return PI_NATIVE_BUILTIN_NAMES.filter(\n native =>\n !toolFiltering.toolNames.includes(NATIVE_TO_COMMON[native] ?? native),\n );\n}\n\nexport type PiThinkingLevel =\n | 'off'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh';\n\nexport interface PiSessionSettings {\n readonly auth?: PiAuthOptions;\n readonly model?: string;\n readonly thinkingLevel?: PiThinkingLevel;\n readonly mcpServers?: Record<string, unknown>;\n readonly extensionFactories?: ReadonlyArray<ExtensionFactory>;\n}\n\nexport interface CreatePiSessionInput {\n readonly sessionId: string;\n readonly sandboxSession: HarnessV1NetworkSandboxSession | SandboxSession;\n readonly sessionWorkDir: string;\n readonly skills: ReadonlyArray<HarnessV1Skill>;\n readonly settings: PiSessionSettings;\n readonly clientApp: string;\n readonly isResume: boolean;\n readonly permissionMode?: HarnessV1PermissionMode;\n readonly builtinToolFiltering?: HarnessV1BuiltinToolFiltering;\n readonly resumeSessionFileName?: string;\n readonly abortSignal?: AbortSignal;\n /**\n * Directory holding Pi's global agent config (auth.json, models.json,\n * settings.json). When omitted, a per-session temp dir is used (the\n * harness cannot reuse existing CLI logins). Pass the user's agent dir\n * (e.g. `~/.pi/agent/`) to reuse their CLI auth and model settings.\n */\n readonly agentDir?: string;\n}\n\ninterface PendingToolResult {\n resolve: (value: unknown) => void;\n}\n\ninterface PendingToolApproval {\n resolve: (value: { approved: boolean; reason?: string }) => void;\n}\n\ninterface ActivePiTurn {\n readonly token: object;\n readonly done: Promise<void>;\n readonly abort: (reason?: unknown) => Promise<void>;\n}\n\n/**\n * A host tool call recorded in the restored journal without a matching tool\n * result — it was awaiting host input (typically a tool approval) when the\n * process that owned the live turn went away.\n */\ninterface DanglingHostToolCall {\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\n/**\n * Barrier that holds a cross-process rerun until the framework has\n * re-delivered the results for every journal-pending host tool call.\n */\ninterface DeferredRerunBarrier {\n /** toolCallId -> toolName still awaiting a submitted result. */\n readonly awaiting: Map<string, string>;\n readonly startRerun: () => void;\n /** Settle the barrier without running: resolves `done` cleanly when no\n * reason is given, rejects it otherwise. No-op once the rerun started. */\n readonly cancel: (reason?: unknown) => void;\n}\n\nexport async function createPiSession(\n input: CreatePiSessionInput,\n): Promise<HarnessV1Session> {\n if (input.isResume) {\n const parkedSession = parkedPiSessions.get(input.sessionId);\n if (parkedSession) {\n parkedPiSessions.delete(input.sessionId);\n return {\n ...parkedSession,\n isResume: true,\n };\n }\n }\n\n // Host-side mirror layout under tmpdir. Replace path-separator characters\n // that would otherwise turn a session id like `2026-05-29T17:54:27` into a\n // sub-directory tree on disk.\n const safeSessionId = input.sessionId.replace(/[\\\\/: ]/g, '-');\n const hostRoot = path.join(tmpdir(), 'ai-sdk-harness', 'pi', safeSessionId);\n const hostWorkDir = path.join(hostRoot, 'workspace');\n const hostAgentDir = path.join(hostRoot, 'agent');\n const hostSessionDir = path.join(hostRoot, 'sessions');\n\n // Pi runs in this host process but must behave as though it lives in the\n // sandbox workspace: its working directory is the real `sessionWorkDir`\n // (where `setup()` clones and where the sandbox-backed tools operate), so the\n // paths Pi advertises to the model — most notably the \"Current working\n // directory\" line in its system prompt — resolve inside the sandbox. The\n // workspace VFS maps that sandbox path to the host-side mirror so Pi's own\n // `fs`-based resource loading (`.pi/`, `AGENTS.md`) still works on the host.\n // `sessionWorkDir` is a sandbox path (e.g. `/vercel/sandbox/...`) that does\n // not exist on the host, so it is a safe, collision-free VFS mount point.\n const sessionWorkDir = input.sessionWorkDir;\n\n await mkdir(hostWorkDir, { recursive: true });\n await mkdir(hostAgentDir, { recursive: true });\n await mkdir(hostSessionDir, { recursive: true });\n\n const toolSafeSandboxSession = getRestrictedSandboxSession(\n input.sandboxSession,\n );\n const sandboxHomeDir = await resolveSandboxHomeDir({\n sandbox: toolSafeSandboxSession,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n const privateSessionDir = resolvePiPrivateSessionDirectory({\n sandboxHomeDir,\n sessionWorkDir: input.sessionWorkDir,\n sessionId: input.sessionId,\n });\n const permissionMode = input.permissionMode ?? 'allow-all';\n let sandboxSkillRootDir: string | undefined;\n let harnessSkills: Skill[] = [];\n\n // Materialise harness-provided skills into sandbox HOME, not the workspace.\n if (input.skills.length > 0) {\n sandboxSkillRootDir = path.posix.join(sandboxHomeDir, '.agents', 'skills');\n harnessSkills = createHarnessPiSkills({\n skills: input.skills,\n sandboxSkillRootDir,\n });\n await writePiSkills({\n sandbox: toolSafeSandboxSession,\n sandboxHomeDir,\n skills: input.skills,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n }\n\n // On resume: pull the Pi session file out of the sandbox into the fresh\n // host mirror so SessionManager.open can read it.\n let resumeSessionFilePath: string | undefined;\n if (input.isResume && input.resumeSessionFileName) {\n const resumeSessionFileName = safePiSessionFileName(\n input.resumeSessionFileName,\n );\n resumeSessionFilePath = await pullSessionFileFromSandbox({\n sandbox: toolSafeSandboxSession,\n privateSessionDir,\n hostSessionDir,\n sessionFileName: resumeSessionFileName,\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n });\n }\n\n // Snapshot sandbox state into the host mirror BEFORE the VFS goes live so\n // Pi sees the workspace as soon as it boots.\n await syncHostWorkspaceFromSandbox({\n sandbox: toolSafeSandboxSession,\n sandboxWorkDir: input.sessionWorkDir,\n hostWorkDir,\n });\n\n // Mount only the workspace: the model's view of the workspace lives at\n // `sessionWorkDir` and is backed by `hostWorkDir`. The agent and session\n // directories stay on the real host filesystem (below) — they are host-only\n // Pi state (auth, model registry, session journal) that must never surface\n // in the sandbox or the workspace mirror.\n const workspaceVfs = new PiWorkspaceVfs();\n workspaceVfs.mount(hostWorkDir, sessionWorkDir);\n\n const paths = createPiPathMapper({\n hostWorkDir,\n sandboxWorkDir: sessionWorkDir,\n readableRoots: sandboxSkillRootDir\n ? [{ sandboxDir: sandboxSkillRootDir }]\n : [],\n });\n\n // Pi auth + model registry are global to this Pi session. These live on the\n // real host filesystem, never in the sandbox/workspace.\n // When `agentDir` is provided, use it instead so the harness can reuse\n // existing CLI logins and model/settings config.\n const agentDir = input.agentDir ?? hostAgentDir;\n const modelRuntime = await ModelRuntime.create({\n authPath: path.join(agentDir, 'auth.json'),\n modelsPath: path.join(agentDir, 'models.json'),\n allowModelNetwork: false,\n });\n const modelRegistry = new ModelRegistry(modelRuntime);\n const settingsManager =\n input.agentDir != null\n ? SettingsManager.create(hostWorkDir, agentDir)\n : SettingsManager.inMemory();\n\n // Run-scoped env (for the model resolver's gateway fallback heuristic).\n const resolverEnv = resolvePiEnv({\n options: input.settings.auth,\n env: process.env,\n });\n await registerPiProviders({\n options: input.settings.auth,\n resolvedEnv: resolverEnv,\n registries: {\n modelRegistry,\n modelRuntime,\n },\n clientApp: input.clientApp,\n });\n const resolveModel = createPiModelResolver({\n modelRegistry,\n env: resolverEnv,\n });\n // Resolve once: deterministic given the configured model. This is the Pi\n // `Model` object handed to `createAgentSession`.\n const resolvedModel = resolveModel(input.settings.model);\n const mcpServers = resolvePiMcpServers({\n mcpServers: input.settings.mcpServers,\n });\n const hasMcpServers = Object.keys(mcpServers).length > 0;\n\n let sessionInstructions: string | undefined;\n\n /*\n * Configured MCP servers are served by an inline Pi extension, so they share\n * the extension runtime with the caller-supplied factories: both are loaded\n * by the resource loader below and both are subject to the reload handling\n * that keeps the active runtime alive across resource-only reloads.\n */\n const extensionFactories: ExtensionFactory[] = [\n ...(input.settings.extensionFactories ?? []),\n ];\n if (hasMcpServers) {\n const { createMcpAdapter } = (await import(\n PI_MCP_ADAPTER_PACKAGE\n )) as PiMcpAdapterModule;\n extensionFactories.push(\n createMcpAdapter({\n config: {\n mcpServers,\n settings: {\n directTools: true,\n toolPrefix: 'mcp',\n disableProxyTool: true,\n },\n },\n }),\n );\n }\n const hasExtensionFactories = extensionFactories.length > 0;\n let preserveExtensionsResult = false;\n let currentExtensionsResult:\n | ReturnType<DefaultResourceLoader['getExtensions']>\n | undefined;\n\n const resourceLoader = new DefaultResourceLoader({\n cwd: sessionWorkDir,\n agentDir: hostAgentDir,\n settingsManager,\n appendSystemPromptOverride: () =>\n sessionInstructions ? [sessionInstructions] : [],\n extensionFactories,\n ...(hasExtensionFactories\n ? {\n // DefaultResourceLoader invokes inline factories on every reload.\n // Resource-only reloads retain the active extension runtime, while a\n // genuine Pi session rebuild is allowed to replace that runtime.\n extensionsOverride: extensions => {\n if (preserveExtensionsResult && currentExtensionsResult != null) {\n return currentExtensionsResult;\n }\n currentExtensionsResult = extensions;\n return extensions;\n },\n }\n : {}),\n // Pi runs in the host process, so its default resource discovery reaches\n // the host developer's personal config (`~/.pi/agent/*`, `~/.agents/*`).\n // The harness exposes only explicitly supplied inline extension factories;\n // disable filesystem extension discovery entirely to avoid loading and\n // executing a host developer's personal or project Pi extensions inside\n // the server process. Themes and prompt templates stay disabled. Skills\n // are kept but filtered to workspace project skills plus harness-provided\n // skills whose files live in sandbox HOME.\n noExtensions: true,\n noThemes: true,\n noPromptTemplates: true,\n skillsOverride: base => ({\n ...base,\n skills: [\n ...base.skills.filter(skill =>\n isWithinWorkspace(skill.filePath, sessionWorkDir, hostWorkDir),\n ),\n ...harnessSkills,\n ],\n }),\n });\n await resourceLoader.reload();\n\n async function reloadResourcesOnly(): Promise<void> {\n if (!hasExtensionFactories) {\n await resourceLoader.reload();\n return;\n }\n\n const factories = extensionFactories.splice(0);\n preserveExtensionsResult = true;\n try {\n await resourceLoader.reload();\n } finally {\n preserveExtensionsResult = false;\n extensionFactories.push(...factories);\n }\n }\n\n // Per-session mutable state we hold across prompts.\n let piSession: AgentSession | undefined;\n let unsubscribe: (() => void) | undefined;\n let lastToolsSignature: string | undefined;\n let sessionFileName: string | undefined;\n let stopped = false;\n /*\n * Set by `doSuspendTurn` before it aborts the in-flight host turn at a slice\n * boundary. The turn's catch settles silently when this is set, so the stream\n * closes cleanly (no spurious `error` chunk) — the next slice rerun-continues\n * from the persisted journal.\n */\n let suspending = false;\n const pendingToolResults = new Map<string, PendingToolResult>();\n const pendingToolApprovals = new Map<string, PendingToolApproval>();\n /*\n * Results the framework submitted for journal-pending (dangling) host tool\n * calls while no live turn held a promise for them — the cross-process\n * continuation path. They are written into the restored journal before the\n * rerun (or on suspend/stop, so a later resume still sees them).\n */\n const deliveredDanglingResults = new Map<\n string,\n { toolName: string; output: unknown; isError: boolean }\n >();\n let restoredSessionManager:\n | ReturnType<typeof SessionManager.open>\n | undefined;\n let deferredRerun: DeferredRerunBarrier | undefined;\n\n // Emit channel set at the start of every doPromptTurn and cleared on end.\n let currentEmit: ((part: HarnessV1StreamPart) => void) | undefined;\n let translatorState: PiTranslatorState | undefined;\n let activeTurn: ActivePiTurn | undefined;\n /*\n * Compaction parts produced while no turn is active. Pi's `compact()` aborts\n * the current turn before it summarizes, so a manually triggered compaction\n * (and any compaction that lands between turns) emits its `compaction_end`\n * after `currentEmit` has been cleared. Buffer those parts and flush them on\n * the next turn's stream so the observation is not lost. Auto-compaction that\n * runs mid-turn still emits inline via `currentEmit`.\n */\n const pendingCompactionParts: HarnessV1StreamPart[] = [];\n\n async function applySessionInstructions(\n instructions: string | undefined,\n ): Promise<void> {\n if (instructions === sessionInstructions) return;\n sessionInstructions = instructions;\n await reloadResourcesOnly();\n piSession?.setActiveToolsByName(piSession.getActiveToolNames());\n }\n\n const remoteOps = createPiRemoteOps({\n sandbox: toolSafeSandboxSession,\n paths,\n onFileChange: (event, relPath) => {\n currentEmit?.({ type: 'file-change', event, path: relPath });\n },\n });\n\n function settlePendingToolResults(reason: string): void {\n for (const pending of pendingToolResults.values()) {\n pending.resolve({ error: reason });\n }\n pendingToolResults.clear();\n }\n\n function settlePendingToolApprovals(reason: string): void {\n for (const pending of pendingToolApprovals.values()) {\n pending.resolve({ approved: false, reason });\n }\n pendingToolApprovals.clear();\n }\n\n async function persistSessionFile(): Promise<void> {\n if (!sessionFileName) return;\n await persistSessionFileToSandbox({\n sandbox: toolSafeSandboxSession,\n privateSessionDir,\n hostSessionDir,\n sessionFileName,\n });\n }\n\n function getRestoredSessionManager():\n | ReturnType<typeof SessionManager.open>\n | undefined {\n if (resumeSessionFilePath == null) return undefined;\n restoredSessionManager ??= SessionManager.open(\n resumeSessionFilePath,\n hostSessionDir,\n sessionWorkDir,\n );\n return restoredSessionManager;\n }\n\n /*\n * Host tool calls in the restored journal that never received a result on\n * the active branch. These are the calls that were blocked on host input\n * (typically a tool approval) when the process owning the live turn exited;\n * the framework re-delivers their results via `submitToolResult` right after\n * `doContinueTurn` returns. Only meaningful before the first rebuild of a\n * resumed session — once a Pi session is live, pending host input is held as\n * in-process promises instead.\n */\n function findDanglingHostToolCalls(\n userTools: ReadonlyArray<HarnessV1ToolSpec>,\n ): DanglingHostToolCall[] {\n if (piSession != null || resumeSessionFilePath == null) return [];\n const hostToolNames = new Set(userTools.map(tool => tool.name));\n if (hostToolNames.size === 0) return [];\n const journal = getRestoredSessionManager();\n if (journal == null) return [];\n const messages = journal.buildSessionContext().messages;\n /*\n * Results already delivered by a previous continuation of this session\n * count as resolved even though they are not in the journal yet — the\n * framework has marked them settled and will never re-deliver them, so a\n * new barrier must not wait on them (it would deadlock the turn). They\n * are injected into the journal before the rerun.\n */\n const resolvedToolCallIds = new Set<string>(\n deliveredDanglingResults.keys(),\n );\n for (const message of messages) {\n if (message.role === 'toolResult') {\n resolvedToolCallIds.add(message.toolCallId);\n }\n }\n const dangling: DanglingHostToolCall[] = [];\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n /*\n * Pi's message transform drops errored/aborted assistant messages from\n * the LLM context entirely, so their tool calls are not awaiting\n * results — the model retries from the last valid state instead.\n */\n if (message.stopReason === 'error' || message.stopReason === 'aborted') {\n continue;\n }\n for (const block of message.content) {\n if (\n block.type === 'toolCall' &&\n hostToolNames.has(block.name) &&\n !resolvedToolCallIds.has(block.id)\n ) {\n dangling.push({ toolCallId: block.id, toolName: block.name });\n }\n }\n }\n return dangling;\n }\n\n /*\n * A result submitted while no live turn holds a pending promise for its\n * toolCallId. On the cross-process continuation path this is the framework\n * re-delivering the caller's tool-approval/tool-result continuation for a\n * journal-pending call; stash it for injection and release the rerun once\n * every dangling call has its result. Results for ids that are neither live\n * nor journal-pending have nowhere to go and are dropped, as before.\n */\n function acceptDanglingHostToolResult(args: {\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }): void {\n const barrier = deferredRerun;\n const toolName = barrier?.awaiting.get(args.toolCallId);\n if (barrier == null || toolName == null) return;\n barrier.awaiting.delete(args.toolCallId);\n deliveredDanglingResults.set(args.toolCallId, {\n toolName,\n output: args.output,\n isError: args.isError ?? false,\n });\n if (barrier.awaiting.size === 0) {\n barrier.startRerun();\n }\n }\n\n /*\n * Write delivered dangling-call results into the restored journal so the\n * rerun's context carries the real outputs — without this, Pi's message\n * transform synthesizes an error result (\"No result provided\") for each\n * dangling call and the model continues as if the tool never answered. The\n * serialized text matches what a live turn would have produced\n * (`asPiToolResult(serializeToolOutput(...))`), so the model sees the same\n * bytes either way.\n */\n function appendDeliveredHostToolResults(): boolean {\n if (deliveredDanglingResults.size === 0 || resumeSessionFilePath == null) {\n return false;\n }\n const journal = getRestoredSessionManager();\n if (journal == null) return false;\n for (const [toolCallId, delivered] of deliveredDanglingResults) {\n journal.appendMessage({\n role: 'toolResult',\n toolCallId,\n toolName: delivered.toolName,\n content: [\n { type: 'text', text: serializeToolOutput(delivered.output) },\n ],\n isError: delivered.isError,\n timestamp: Date.now(),\n });\n }\n deliveredDanglingResults.clear();\n /*\n * The journal on disk now differs from the copy in the sandbox. Make sure\n * the lifecycle persistence knows which file to push back even when no\n * turn ever rebuilt the Pi session in this process (e.g. a suspend that\n * lands while the rerun is still held back).\n */\n if (!sessionFileName) {\n sessionFileName = safePiSessionFileName(\n path.basename(resumeSessionFilePath),\n );\n }\n return true;\n }\n\n /*\n * Cross-process continuation of a turn that paused on host input: the\n * restored journal ends with host tool calls that have no results, and the\n * framework re-delivers those results through `control.submitToolResult`\n * (with the original tool-call ids) immediately after this call returns.\n * Starting the rerun right away would race that delivery — the rerun's\n * context would resolve the dangling calls as synthetic empty results and\n * the submitted outputs would be dropped. Hold the rerun until every\n * dangling call's result has arrived, write the results into the journal,\n * and only then re-drive the turn.\n *\n * If the caller resumes without supplying all continuations, the turn stays\n * parked awaiting the remaining host input — the same behaviour as the\n * in-process path, where the live turn stays blocked on its tool promises.\n */\n function deferRerunUntilHostToolResults(\n danglingCalls: ReadonlyArray<DanglingHostToolCall>,\n continueOpts: HarnessV1ContinueTurnOptions,\n ): HarnessV1PromptControl {\n /*\n * A previous continuation may have ended while its rerun was still held\n * back (e.g. it paused again awaiting a tool-result continuation). Close\n * that turn's control cleanly before installing the new barrier.\n */\n deferredRerun?.cancel();\n\n let resolveDone!: () => void;\n let rejectDone!: (error: unknown) => void;\n const done = new Promise<void>((resolve, reject) => {\n resolveDone = resolve;\n rejectDone = reject;\n });\n let settled = false;\n\n const startRerun = () => {\n if (settled) return;\n settled = true;\n deferredRerun = undefined;\n void (async () => {\n try {\n // `runTurn` injects the delivered results into the journal before\n // rebuilding the Pi session from it.\n const control = await runTurn({\n text: '',\n tools: continueOpts.tools ?? [],\n instructions: continueOpts.instructions,\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n await control.done;\n resolveDone();\n } catch (error) {\n rejectDone(error);\n }\n })();\n };\n\n const cancel = (reason?: unknown) => {\n if (settled) return;\n settled = true;\n deferredRerun = undefined;\n if (reason == null) {\n resolveDone();\n } else {\n rejectDone(reason);\n }\n };\n\n deferredRerun = {\n awaiting: new Map(\n danglingCalls.map(call => [call.toolCallId, call.toolName]),\n ),\n startRerun,\n cancel,\n };\n\n const abortBarrier = () => {\n cancel(\n continueOpts.abortSignal?.reason ??\n new Error(\n 'Pi turn was aborted before its host tool results were delivered.',\n ),\n );\n };\n if (continueOpts.abortSignal?.aborted) {\n abortBarrier();\n } else {\n continueOpts.abortSignal?.addEventListener('abort', abortBarrier, {\n once: true,\n });\n }\n\n return createPromptControl({\n done,\n abortSignal: continueOpts.abortSignal,\n });\n }\n\n function createPromptControl(input: {\n done: Promise<void>;\n abortSignal?: AbortSignal;\n abort?: (reason?: unknown) => Promise<void>;\n }): HarnessV1PromptControl {\n const abortHandler = () => {\n void input.abort?.(input.abortSignal?.reason);\n };\n if (input.abortSignal) {\n if (input.abortSignal.aborted) {\n abortHandler();\n } else {\n input.abortSignal.addEventListener('abort', abortHandler, {\n once: true,\n });\n }\n void input.done.then(\n () => {\n input.abortSignal?.removeEventListener('abort', abortHandler);\n },\n () => {\n input.abortSignal?.removeEventListener('abort', abortHandler);\n },\n );\n }\n\n return {\n async submitToolResult(args) {\n const pending = pendingToolResults.get(args.toolCallId);\n if (!pending) {\n acceptDanglingHostToolResult(args);\n return;\n }\n pendingToolResults.delete(args.toolCallId);\n /*\n * Preserve the original output so the result projection can surface it\n * unchanged. The tool handler stringifies the output for the runtime\n * (so the model reads it), and Pi echoes that text back — without this\n * the consumer-facing result would be the serialized string instead of\n * the original object.\n */\n translatorState?.hostToolResults.set(args.toolCallId, args.output);\n pending.resolve(args.output);\n },\n async submitToolApproval(args) {\n const pending = pendingToolApprovals.get(args.approvalId);\n if (!pending) return;\n pendingToolApprovals.delete(args.approvalId);\n pending.resolve({\n approved: args.approved,\n reason: args.reason,\n });\n },\n async submitUserMessage(text) {\n if (piSession == null) {\n throw new Error('Pi has no active runtime session to steer.');\n }\n await piSession.steer(text);\n },\n done: input.done,\n };\n }\n\n async function requestBuiltinToolApproval(args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }): Promise<{ approved: boolean; reason?: string }> {\n if (\n !piBuiltinToolRequiresApproval({\n permissionMode,\n kind: PI_NATIVE_TOOL_KINDS[args.nativeName],\n })\n ) {\n return { approved: true };\n }\n currentEmit?.({\n type: 'tool-approval-request',\n approvalId: args.toolCallId,\n toolCallId: args.toolCallId,\n });\n if (translatorState) {\n for (const part of finishPiApprovalStep(\n translatorState,\n args.toolCallId,\n )) {\n currentEmit?.(part);\n }\n }\n return new Promise(resolve => {\n pendingToolApprovals.set(args.toolCallId, { resolve });\n });\n }\n\n function buildToolDefinitions(userTools: ReadonlyArray<HarnessV1ToolSpec>): {\n customTools: ToolDefinition[];\n builtinNames: string[];\n } {\n const builtinNames = resolveActivePiBuiltinNames(\n input.builtinToolFiltering,\n );\n const customTools: ToolDefinition[] = [\n ...builtinNames.map(native =>\n buildBuiltinToolDefinition({\n native,\n remoteOps,\n requestApproval: requestBuiltinToolApproval,\n }),\n ),\n ...userTools.map(spec =>\n buildUserToolDefinition(spec, pendingToolResults),\n ),\n ];\n return {\n customTools,\n builtinNames: [...builtinNames],\n };\n }\n\n async function disposePiSession(): Promise<void> {\n unsubscribe?.();\n unsubscribe = undefined;\n\n const session = piSession;\n piSession = undefined;\n if (!session) return;\n\n if (hasMcpServers) {\n await session.reload().catch(() => {});\n }\n session.dispose();\n }\n\n async function rebuildPiSession(\n userTools: ReadonlyArray<HarnessV1ToolSpec>,\n isFirstBuild: boolean,\n ): Promise<boolean> {\n let resourcesReloaded = false;\n if (piSession) {\n await disposePiSession();\n // Original adapter waits 25 ms here to let Pi's teardown microtasks\n // settle before the next createAgentSession. Port verbatim.\n // TODO(pi-0.77): verify the race still exists; original SDK had a\n // teardown microtask the host needed to wait on.\n await new Promise(resolve => setTimeout(resolve, 25));\n if (hasExtensionFactories) {\n // dispose() invalidates Pi's current extension runtime, so a replacement\n // AgentSession needs factories to create a fresh runtime before build.\n await resourceLoader.reload();\n resourcesReloaded = true;\n }\n }\n\n const { customTools, builtinNames } = buildToolDefinitions(userTools);\n const toolNames = customTools.map(t => t.name);\n\n // SessionManager: open the resumed file on the first build of a resumed\n // session; create fresh otherwise.\n const sessionManager =\n isFirstBuild && resumeSessionFilePath\n ? getRestoredSessionManager()!\n : SessionManager.create(sessionWorkDir, hostSessionDir);\n\n const { session } = await createAgentSession({\n cwd: sessionWorkDir,\n agentDir: hostAgentDir,\n modelRuntime,\n sessionManager,\n settingsManager,\n resourceLoader,\n customTools,\n ...(hasMcpServers\n ? { noTools: 'builtin' as const }\n : { tools: toolNames }),\n ...(input.settings.thinkingLevel\n ? { thinkingLevel: input.settings.thinkingLevel }\n : {}),\n ...(resolvedModel ? { model: resolvedModel } : {}),\n });\n piSession = session;\n if (hasMcpServers) {\n await piSession.bindExtensions({ mode: 'print' });\n }\n\n // Pick up the actual session file path so doStop can persist it. Pi\n // 0.77 emits `.jsonl` files; older builds used `.json`. Persist the\n // basename verbatim — including the extension — so the resume path can\n // round-trip it without guessing the extension.\n const candidatePath = sessionManager.getSessionFile();\n if (candidatePath) {\n sessionFileName = safePiSessionFileName(path.basename(candidatePath));\n }\n\n translatorState = createPiTranslatorState({\n builtinToolNames: builtinNames,\n hostToolNames: userTools.map(tool => tool.name),\n nativeToCommon: NATIVE_TO_COMMON,\n });\n\n unsubscribe = piSession.subscribe(rawEvent => {\n if (!translatorState) return;\n const event = parseNativeEvent(rawEvent);\n if (!event) return;\n for (const part of translatePiEvent(event, translatorState)) {\n if (currentEmit) {\n currentEmit(part);\n } else if (part.type === 'compaction') {\n // No active turn: defer compaction observations to the next turn.\n pendingCompactionParts.push(part);\n }\n // Other event types outside a turn have no consumer and are dropped.\n }\n });\n return resourcesReloaded;\n }\n\n /*\n * Drive one turn against the Pi session and return the control surface.\n * Shared by `doPromptTurn` (a fresh user prompt) and `doContinueTurn` (an empty\n * prompt that asks Pi to continue its own thread after a rerun resume).\n */\n async function runTurn(turnOpts: {\n text: string;\n tools: ReadonlyArray<HarnessV1ToolSpec>;\n instructions?: string;\n emit: (part: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): Promise<HarnessV1PromptControl> {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n\n const userTools = turnOpts.tools;\n currentEmit = turnOpts.emit;\n const turnAbortController = new AbortController();\n const abort = async (reason?: unknown): Promise<void> => {\n if (turnAbortController.signal.aborted) return;\n if (reason === undefined) {\n turnAbortController.abort();\n } else {\n turnAbortController.abort(reason);\n }\n await Promise.resolve(piSession?.abort()).catch(() => {});\n };\n\n const turnPromise = (async () => {\n try {\n await applySessionInstructions(turnOpts.instructions);\n turnAbortController.signal.throwIfAborted();\n\n /*\n * Any host tool results delivered while no turn was live must land in the\n * journal before the session (re)builds from it, whichever turn entry\n * point runs next. No-op when nothing was delivered.\n */\n const didAppendDeliveredHostToolResults =\n appendDeliveredHostToolResults();\n\n const signature = JSON.stringify(userTools.map(t => t.name).sort());\n const needsRebuild =\n piSession == null || signature !== lastToolsSignature;\n let resourcesReloaded = false;\n if (needsRebuild) {\n resourcesReloaded = await rebuildPiSession(\n userTools,\n piSession == null,\n );\n turnAbortController.signal.throwIfAborted();\n lastToolsSignature = signature;\n }\n\n if (!resourcesReloaded) {\n await reloadResourcesOnly();\n turnAbortController.signal.throwIfAborted();\n }\n await syncHostWorkspaceFromSandbox({\n sandbox: toolSafeSandboxSession,\n sandboxWorkDir: input.sessionWorkDir,\n hostWorkDir,\n });\n turnAbortController.signal.throwIfAborted();\n\n // Fresh translator state for the new turn — keep the tool sets the\n // session was built with.\n translatorState = createPiTranslatorState({\n builtinToolNames: [...PI_NATIVE_BUILTIN_NAMES],\n hostToolNames: userTools.map(tool => tool.name),\n nativeToCommon: NATIVE_TO_COMMON,\n });\n\n currentEmit?.({ type: 'stream-start' });\n\n /*\n * A live continuation reports the completed tool execution before the\n * next assistant message, which closes the resumed tool-call step. A\n * journal rerun starts after that result has already been persisted,\n * so Pi has no live tool event to emit. Recreate only the missing step\n * boundary; otherwise the continuation layer mistakes the next\n * assistant response for the resumed step and discards it.\n */\n if (didAppendDeliveredHostToolResults) {\n currentEmit?.({\n type: 'finish-step',\n finishReason: { unified: 'tool-calls', raw: undefined },\n usage: {\n inputTokens: {\n total: 0,\n noCache: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n outputTokens: {\n total: 0,\n text: 0,\n reasoning: 0,\n },\n },\n harnessMetadata: { pi: { inferredStep: true } },\n });\n }\n\n let terminalError: string | undefined;\n const session = piSession!;\n\n // We subscribed in rebuild, but the translator may need to detect\n // terminal errors too — wrap a second listener that records them.\n const unsubErr = session.subscribe(raw => {\n const ev = parseNativeEvent(raw);\n if (!ev) return;\n const err = getPiTerminalError(ev);\n if (err && !terminalError) {\n terminalError = err;\n }\n });\n\n try {\n await session.prompt(turnOpts.text);\n\n if (terminalError) {\n /*\n * A `doSuspendTurn` aborts the in-flight turn on purpose. Pi surfaces\n * that abort as a *resolved* prompt with a recorded terminal error\n * (\"This operation was aborted\") rather than a thrown exception, so the\n * `catch` guard below never sees it. Swallow it here too — but only if\n * it's actually the abort: the stream then closes cleanly (no spurious\n * `error` chunk) and the next slice rerun-continues from the journal.\n * Any other terminal error mid-suspend is unanticipated and must\n * surface.\n */\n if (suspending && isAbortError(terminalError)) return;\n currentEmit?.({ type: 'error', error: new Error(terminalError) });\n return;\n }\n\n const stats = session.getSessionStats();\n const finishReason = {\n unified: 'stop' as const,\n raw: undefined,\n };\n const usage = {\n inputTokens: {\n total: stats.tokens.input,\n noCache: undefined,\n cacheRead: stats.tokens.cacheRead,\n cacheWrite: stats.tokens.cacheWrite,\n },\n outputTokens: {\n total: stats.tokens.output,\n text: undefined,\n reasoning: undefined,\n },\n };\n currentEmit?.({\n type: 'finish',\n finishReason,\n totalUsage: usage,\n });\n } catch (err) {\n // A `doSuspendTurn` aborts the in-flight turn on purpose — settle silently\n // so the stream closes cleanly without a spurious `error` chunk; the\n // next slice rerun-continues from the persisted journal.\n // Same rule as the resolved-with-terminalError path: only swallow the\n // abort our own suspend caused; surface anything unanticipated.\n if (suspending && isAbortError(err)) return;\n currentEmit?.({ type: 'error', error: err });\n } finally {\n unsubErr();\n }\n } catch (err) {\n if (suspending && isAbortError(err)) return;\n throw err;\n }\n })();\n\n const activeTurnToken = {};\n const done = turnPromise.finally(() => {\n if (activeTurn?.token === activeTurnToken) {\n activeTurn = undefined;\n currentEmit = undefined;\n }\n });\n activeTurn = {\n token: activeTurnToken,\n done,\n abort,\n };\n\n return createPromptControl({\n done,\n abortSignal: turnOpts.abortSignal,\n abort,\n });\n }\n\n const doStop = async (): Promise<HarnessV1ResumeSessionState> => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n deferredRerun?.cancel();\n const turnToStop = activeTurn;\n const abortingTurn = turnToStop?.abort();\n settlePendingToolResults('Pi session stopped');\n settlePendingToolApprovals('Pi session stopped');\n await abortingTurn;\n await turnToStop?.done.catch(() => {});\n\n /*\n * Results the framework already delivered for journal-pending calls must\n * reach the journal before it is persisted — the framework has marked\n * them settled and will not re-deliver them on a later resume.\n */\n try {\n appendDeliveredHostToolResults();\n } catch {\n // Best-effort: an unwritable journal falls back to the pre-delivery copy.\n }\n\n // Persist the Pi session file into the sandbox so a future process\n // can pick it up after `provider.resumeSession({ sessionId })` reattaches.\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n // Best-effort: a missing session file means resume returns to a\n // fresh conversation rather than failing stop.\n }\n }\n\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n\n return {\n type: 'resume-session',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n };\n\n const sessionImpl: HarnessV1Session = {\n sessionId: input.sessionId,\n isResume: input.isResume,\n // The model Pi actually resolves to (the configured id, or its default when\n // unset) — `gen_ai.request.model`.\n ...(resolvedModel?.id ? { modelId: resolvedModel.id } : {}),\n\n // Pi has no bridge to attach to and no on-disk event log to replay; its\n // only resume path is restoring the session file on a fresh/snapshotted\n // sandbox, i.e. `rerun`.\n\n doPromptTurn: async (\n promptOpts: HarnessV1PromptTurnOptions,\n ): Promise<HarnessV1PromptControl> => {\n if (promptOpts.responseFormat?.type === 'json') {\n throw new HarnessCapabilityUnsupportedError({\n message: \"Harness 'pi' does not support structured output.\",\n harnessId: HARNESS_ID,\n });\n }\n return runTurn({\n text: extractUserText(promptOpts.prompt),\n tools: promptOpts.tools ?? [],\n instructions: promptOpts.instructions,\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n },\n\n doContinueTurn: async (\n continueOpts: HarnessV1ContinueTurnOptions,\n ): Promise<HarnessV1PromptControl> => {\n if (continueOpts.responseFormat?.type === 'json') {\n throw new HarnessCapabilityUnsupportedError({\n message: \"Harness 'pi' does not support structured output.\",\n harnessId: HARNESS_ID,\n });\n }\n if (activeTurn != null) {\n currentEmit = continueOpts.emit;\n return createPromptControl({\n done: activeTurn.done,\n abortSignal: continueOpts.abortSignal,\n abort: activeTurn.abort,\n });\n }\n\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n\n /*\n * The restored journal ends with host tool calls that never got their\n * results — the turn was paused on host input (e.g. a tool approval)\n * when the previous process exited. The framework re-delivers those\n * results via `submitToolResult` right after this call returns; hold\n * the rerun until they have all arrived so they reach the model.\n */\n const danglingHostToolCalls = findDanglingHostToolCalls(\n continueOpts.tools ?? [],\n );\n if (danglingHostToolCalls.length > 0) {\n return deferRerunUntilHostToolResults(\n danglingHostToolCalls,\n continueOpts,\n );\n }\n\n /*\n * Pi runs the model on the host, so there is no live turn in the sandbox\n * to attach to — the previous slice's turn died with its process.\n * Rerun-continue: re-drive the agent from the journal restored on resume.\n * An empty prompt asks Pi to continue its own thread. Lossy — any work in\n * flight at the slice boundary is recomputed because a host-resident\n * runtime cannot do a lossless attach.\n */\n return runTurn({\n text: '',\n tools: continueOpts.tools ?? [],\n instructions: continueOpts.instructions,\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n },\n\n doCompact: async (customInstructions?: string) => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n /*\n * Pi owns the compaction. We just request it; the resulting\n * `compaction_end` event is observed by the session subscription and\n * translated into a `compaction` stream part. The returned\n * `CompactionResult` is intentionally discarded here.\n */\n await piSession?.compact(customInstructions);\n },\n\n doDestroy: async () => {\n if (stopped) return;\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n deferredRerun?.cancel();\n const turnToDestroy = activeTurn;\n const abortingTurn = turnToDestroy?.abort();\n settlePendingToolResults('Pi session stopped');\n settlePendingToolApprovals('Pi session stopped');\n await abortingTurn;\n await turnToDestroy?.done.catch(() => {});\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n },\n\n doStop,\n\n doDetach: async (): Promise<HarnessV1ResumeSessionState> => {\n if (activeTurn != null || pendingToolResults.size > 0) {\n parkedPiSessions.set(input.sessionId, sessionImpl);\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n /*\n * The parked in-process session is the authoritative continuation\n * path while the live turn is waiting on host input. Persistence is\n * only a fallback for later non-live resumes.\n */\n }\n }\n return {\n type: 'resume-session',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n }\n return doStop();\n },\n\n doSuspendTurn: async (): Promise<HarnessV1ContinueTurnState> => {\n if (stopped) {\n throw new Error('Pi session has been stopped.');\n }\n if (\n activeTurn != null &&\n (pendingToolResults.size > 0 || pendingToolApprovals.size > 0)\n ) {\n parkedPiSessions.set(input.sessionId, sessionImpl);\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n /*\n * While waiting on host input, the live parked session is the\n * authoritative same-process continuation path. The sandbox copy\n * remains a best-effort fallback for a later cold resume.\n */\n }\n }\n return {\n type: 'continue-turn',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n }\n /*\n * Pi's model runs in this host process, which is about to be suspended at\n * the slice boundary — the in-flight turn cannot survive it. Abort it (the\n * turn settles silently via the `suspending` guard so the stream closes\n * cleanly), persist the journal into the sandbox, and tear down host-side\n * resources. The sandbox itself is left running; the next slice pulls the\n * journal after `provider.resumeSession({ sessionId })` and rerun-continues. The\n * tail in flight at the boundary is recomputed — Pi cannot freeze a live\n * turn the way a bridge adapter can.\n */\n suspending = true;\n const turnToSuspend = activeTurn;\n await turnToSuspend?.abort();\n deferredRerun?.cancel();\n await turnToSuspend?.done.catch(() => {});\n\n /*\n * A suspend can land while the rerun is still held back waiting for\n * host tool results. Whatever the framework already delivered must land\n * in the journal now — it will not be re-delivered — while calls still\n * awaiting results stay dangling for the next continuation to collect.\n */\n try {\n appendDeliveredHostToolResults();\n } catch {\n // Best-effort: an unwritable journal falls back to the pre-delivery copy.\n }\n\n if (sessionFileName) {\n try {\n await persistSessionFile();\n } catch {\n // Best-effort: a missing/failed copy leaves the previously persisted\n // journal in place, so the next slice resumes from a slightly older\n // (still valid) state.\n }\n }\n\n stopped = true;\n parkedPiSessions.delete(input.sessionId);\n settlePendingToolResults('Pi session suspended');\n settlePendingToolApprovals('Pi session suspended');\n await disposePiSession();\n workspaceVfs.unmount();\n await rm(hostRoot, { recursive: true, force: true });\n\n return {\n type: 'continue-turn',\n harnessId: HARNESS_ID,\n specificationVersion: 'harness-v1',\n data: sessionFileName ? { sessionFileName } : {},\n };\n },\n };\n\n return sessionImpl;\n}\n\nfunction resolvePiMcpServers({\n mcpServers,\n}: {\n mcpServers: Record<string, unknown> | undefined;\n}): Record<string, unknown> {\n if (mcpServers == null) return {};\n for (const [name, value] of Object.entries(mcpServers)) {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(\n `Pi MCP server ${JSON.stringify(name)} must be configured with an object value.`,\n );\n }\n }\n return mcpServers;\n}\n\n/**\n * Whether a terminal error (string from Pi's event stream, or a thrown error)\n * is an abort — the expected result of `doSuspendTurn` aborting the in-flight\n * turn. Only these are safe to swallow while `suspending`; any other error is\n * unanticipated and must surface as an `error` chunk.\n */\nfunction isAbortError(value: unknown): boolean {\n if (value == null) return false;\n if (\n typeof value === 'object' &&\n (value as { name?: unknown }).name === 'AbortError'\n ) {\n return true;\n }\n const text =\n typeof value === 'string'\n ? value\n : value instanceof Error\n ? value.message\n : String(value);\n return /\\baborted\\b|AbortError|operation was aborted/i.test(text);\n}\n\nfunction asPiToolResult(text: string): AgentToolResult<unknown> {\n return {\n content: [{ type: 'text', text }],\n details: undefined,\n };\n}\n\nasync function maybeDenyPiBuiltinTool(input: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n requestApproval: (args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }) => Promise<{ approved: boolean; reason?: string }>;\n}): Promise<AgentToolResult<unknown> | undefined> {\n const decision = await input.requestApproval({\n toolCallId: input.toolCallId,\n nativeName: input.nativeName,\n });\n if (decision.approved) return undefined;\n return asPiToolResult(\n serializeToolOutput({\n type: 'execution-denied',\n reason: decision.reason,\n }),\n );\n}\n\nfunction piBuiltinToolRequiresApproval(input: {\n permissionMode: HarnessV1PermissionMode;\n kind: 'readonly' | 'edit' | 'bash';\n}): boolean {\n if (input.permissionMode === 'allow-all') return false;\n if (input.permissionMode === 'allow-edits') return input.kind === 'bash';\n return input.kind === 'edit' || input.kind === 'bash';\n}\n\nfunction buildBuiltinToolDefinition(input: {\n native: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n remoteOps: PiRemoteOps;\n requestApproval: (args: {\n toolCallId: string;\n nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];\n }) => Promise<{ approved: boolean; reason?: string }>;\n}): ToolDefinition {\n switch (input.native) {\n case 'read':\n return defineTool({\n name: 'read',\n label: 'read',\n description: 'Read file contents.',\n parameters: Type.Object({ file_path: Type.String() }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'read',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const buf = await input.remoteOps.readBuffer(params.file_path);\n return asPiToolResult(buf.toString('utf8'));\n },\n });\n case 'write':\n return defineTool({\n name: 'write',\n label: 'write',\n description: 'Write content to a file.',\n parameters: Type.Object({\n file_path: Type.String(),\n content: Type.String(),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'write',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n await input.remoteOps.writeFile(params.file_path, params.content);\n return asPiToolResult(`Wrote ${params.file_path}`);\n },\n });\n case 'edit':\n return defineTool({\n name: 'edit',\n label: 'edit',\n description: 'Edit a file by exact-string replacement.',\n parameters: Type.Object({\n file_path: Type.String(),\n old_string: Type.String(),\n new_string: Type.String(),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'edit',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n await input.remoteOps.editFile(\n params.file_path,\n params.old_string,\n params.new_string,\n );\n return asPiToolResult(`Edited ${params.file_path}`);\n },\n });\n case 'bash':\n return defineTool({\n name: 'bash',\n label: 'bash',\n description: 'Execute a shell command.',\n parameters: Type.Object({\n command: Type.String(),\n timeout: Type.Optional(\n Type.Number({ description: 'Timeout in seconds.' }),\n ),\n }),\n async execute(toolCallId, params, signal) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'bash',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const chunks: Buffer[] = [];\n const result = await input.remoteOps.exec(params.command, '.', {\n onData(data) {\n chunks.push(data);\n },\n ...(signal ? { signal } : {}),\n ...(typeof params.timeout === 'number'\n ? { timeout: params.timeout }\n : {}),\n });\n const out = Buffer.concat(chunks).toString('utf8');\n const text = `${out}${\n result.exitCode != null ? `\\n\\n(exit ${result.exitCode})` : ''\n }`.trim();\n return asPiToolResult(text);\n },\n });\n case 'grep':\n return defineTool({\n name: 'grep',\n label: 'grep',\n description: 'Search file contents with regex.',\n parameters: Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n ignoreCase: Type.Optional(Type.Boolean()),\n literal: Type.Optional(Type.Boolean()),\n context: Type.Optional(Type.Number()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'grep',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const out = await input.remoteOps.grepFiles(params.pattern, params);\n return asPiToolResult(out);\n },\n });\n case 'find':\n return defineTool({\n name: 'find',\n label: 'find',\n description: 'Find files matching a glob pattern.',\n parameters: Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'find',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const matches = await input.remoteOps.findFiles(\n params.pattern,\n params.path ?? '.',\n params.limit ?? 1_000,\n );\n return asPiToolResult(matches.join('\\n'));\n },\n });\n case 'ls':\n return defineTool({\n name: 'ls',\n label: 'ls',\n description: 'List directory entries.',\n parameters: Type.Object({\n path: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number()),\n }),\n async execute(toolCallId, params) {\n const denied = await maybeDenyPiBuiltinTool({\n toolCallId,\n nativeName: 'ls',\n requestApproval: input.requestApproval,\n });\n if (denied) return denied;\n const entries = await input.remoteOps.listDirectory(\n params.path ?? '.',\n params.limit ?? 500,\n );\n return asPiToolResult(entries.join('\\n'));\n },\n });\n }\n}\n\nfunction buildUserToolDefinition(\n spec: HarnessV1ToolSpec,\n pending: Map<string, PendingToolResult>,\n): ToolDefinition {\n const schema = spec.inputSchema ?? {\n type: 'object',\n properties: {},\n additionalProperties: true,\n };\n return defineTool({\n name: spec.name,\n label: spec.name,\n description: spec.description ?? `User-registered tool ${spec.name}`,\n parameters: toolSpecToTypeBoxParameters(schema),\n async execute(toolCallId) {\n return new Promise<unknown>(resolve => {\n pending.set(toolCallId, { resolve });\n }).then(output => asPiToolResult(serializeToolOutput(output)));\n },\n });\n}\n","import type {\n ModelRegistry,\n ModelRuntime,\n} from '@earendil-works/pi-coding-agent';\nimport { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\nimport { VERSION } from './version';\n\ntype ProviderConfigInput = Parameters<ModelRegistry['registerProvider']>[1];\n\n/**\n * Pi auth options. Choose an explicit mode or rely on 'auto' (precedence:\n * explicit gateway, then OpenAI / Anthropic / custom environment variables).\n */\nexport type PiAuthenticationMode =\n | 'auto'\n | 'openai'\n | 'anthropic'\n | 'custom'\n | 'ai-gateway';\n\n/**\n * @deprecated Passing an object to auth options is deprecated. Use a `PiAuthenticationMode` string value (\"auto\" | \"openai\" | \"anthropic\" | \"custom\" | \"ai-gateway\") instead, and pass credentials via environment variables.\n */\nexport type LegacyPiAuthOptions = {\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n /**\n * Resolved environment-variable pairs of the form `<PREFIX>_API_KEY` and\n * (optionally) `<PREFIX>_BASE_URL`. Special-cased prefixes:\n * - `AI_GATEWAY` → registers `vercel-ai-gateway`\n * - `OPENAI` → registers `openai`\n * - `ANTHROPIC` → registers `anthropic` (`ANTHROPIC_AUTH_TOKEN` adds a\n * bearer auth header)\n * Any other `<PREFIX>_API_KEY` with a matching `<PREFIX>_BASE_URL` is\n * registered as the lowercased, dash-separated prefix.\n */\n readonly customEnv?: Record<string, string>;\n};\n\nexport type PiAuthOptions = PiAuthenticationMode | LegacyPiAuthOptions;\n\nconst DEFAULT_GATEWAY_BASE_URL = 'https://ai-gateway.vercel.sh';\nconst DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';\nconst DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com';\nconst HARNESS_CLIENT_APP = `ai-sdk/harness-pi/${VERSION}`;\n\nfunction createGatewayProviderConfig({\n apiKey,\n baseUrl,\n clientApp,\n}: {\n apiKey: string;\n baseUrl: string;\n clientApp: string;\n}): ProviderConfigInput {\n return {\n apiKey,\n baseUrl,\n authHeader: true,\n headers: {\n 'User-Agent': clientApp,\n 'x-client-app': clientApp,\n },\n };\n}\n\ntype PiRegistries = {\n modelRegistry: ModelRegistry;\n modelRuntime: ModelRuntime;\n};\n\nasync function register({\n registries,\n provider,\n apiKey,\n config,\n}: {\n registries: PiRegistries;\n provider: string;\n apiKey: string;\n config: ProviderConfigInput;\n}): Promise<void> {\n registries.modelRegistry.registerProvider(provider, config);\n await registries.modelRuntime.setRuntimeApiKey(provider, apiKey);\n}\n\nfunction hasConfiguredValue(value: unknown): boolean {\n if (value == null) return false;\n if (typeof value === 'string') return value.length > 0;\n if (typeof value !== 'object') return true;\n return Object.values(value).some(hasConfiguredValue);\n}\n\nexport function resolvePiEnv({\n options,\n env,\n}: {\n options: PiAuthOptions | undefined;\n env: NodeJS.ProcessEnv;\n}): Record<string, string> {\n const normalizedOptions = normalizePiAuthToLegacyAuth(options);\n const customEnvConfigured = hasConfiguredValue(normalizedOptions?.customEnv);\n if (customEnvConfigured) {\n return resolveCustomEnv({ customEnv: normalizedOptions!.customEnv ?? {} });\n }\n\n const gatewayConfigured = hasConfiguredValue(normalizedOptions?.gateway);\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env });\n if (gatewayConfigured) {\n const apiKey =\n normalizedOptions!.gateway?.apiKey ?? gatewayAuthFromEnv.apiKey;\n const baseUrl =\n normalizedOptions!.gateway?.baseUrl ?? gatewayAuthFromEnv.baseUrl;\n if (apiKey) {\n return { AI_GATEWAY_API_KEY: apiKey, AI_GATEWAY_BASE_URL: baseUrl };\n }\n return {};\n }\n\n // Handle explicit string modes with process env\n if (typeof options === 'string') {\n switch (options) {\n case 'openai':\n if (env.OPENAI_API_KEY) {\n return {\n OPENAI_API_KEY: env.OPENAI_API_KEY,\n ...(env.OPENAI_BASE_URL\n ? { OPENAI_BASE_URL: env.OPENAI_BASE_URL }\n : {}),\n };\n }\n return {};\n case 'anthropic':\n if (env.ANTHROPIC_API_KEY) {\n return {\n ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,\n ...(env.ANTHROPIC_BASE_URL\n ? { ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL }\n : {}),\n ...(env.ANTHROPIC_AUTH_TOKEN\n ? { ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN }\n : {}),\n };\n }\n return {};\n case 'custom': {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n result[key] = value;\n }\n }\n return result;\n }\n case 'ai-gateway':\n if (gatewayAuthFromEnv.apiKey) {\n return {\n AI_GATEWAY_API_KEY: gatewayAuthFromEnv.apiKey,\n AI_GATEWAY_BASE_URL: gatewayAuthFromEnv.baseUrl,\n };\n }\n return {};\n case 'auto':\n default:\n break;\n }\n }\n\n // Ambient gateway fallback.\n if (gatewayAuthFromEnv.apiKey) {\n return {\n AI_GATEWAY_API_KEY: gatewayAuthFromEnv.apiKey,\n AI_GATEWAY_BASE_URL: gatewayAuthFromEnv.baseUrl,\n };\n }\n\n // 'auto' fallback: pick up any other provider credentials from the env.\n const ambient: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n ambient[key] = value;\n }\n }\n return ambient;\n}\n\nexport async function registerPiProviders({\n options,\n resolvedEnv,\n registries,\n clientApp = HARNESS_CLIENT_APP,\n}: {\n options: PiAuthOptions | undefined;\n resolvedEnv: Record<string, string>;\n registries: PiRegistries;\n clientApp?: string;\n}): Promise<void> {\n const normalizedOptions = normalizePiAuthToLegacyAuth(options);\n if (hasConfiguredValue(normalizedOptions?.customEnv)) {\n await registerCustomProviders({\n customEnv: normalizedOptions!.customEnv ?? {},\n registries,\n clientApp,\n });\n return;\n }\n\n // Legacy customEnv was handled above. Everything else reduces to a mode:\n // string modes pass through, `undefined` is 'auto', and legacy gateway\n // objects fall through to the trailing gateway-registration block.\n const mode =\n typeof options === 'string' ? options : options == null ? 'auto' : 'legacy';\n\n switch (mode) {\n case 'openai': {\n const env = pickOpenAIEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickOpenAIEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'anthropic': {\n const env = pickAnthropicEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickAnthropicEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'custom': {\n // 'custom' registers every provider with credentials in the env.\n const env = pickProviderEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickProviderEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n case 'ai-gateway': {\n const gatewayAuth = getAiGatewayAuthFromEnv({ env: process.env });\n const gatewayApiKey =\n resolvedEnv.AI_GATEWAY_API_KEY ?? gatewayAuth.apiKey;\n const gatewayBaseUrl =\n resolvedEnv.AI_GATEWAY_BASE_URL ?? gatewayAuth.baseUrl;\n if (!gatewayApiKey) return;\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayApiKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayApiKey,\n baseUrl: gatewayBaseUrl,\n clientApp,\n }),\n });\n return;\n }\n case 'legacy':\n break; // handled below\n case 'auto':\n default: {\n // 'auto' (the default): prefer the AI Gateway; only when no gateway\n // credentials exist, fall back to other providers found in the env.\n const gatewayAuth = getAiGatewayAuthFromEnv({ env: process.env });\n const gatewayApiKey =\n resolvedEnv.AI_GATEWAY_API_KEY ?? gatewayAuth.apiKey;\n const gatewayBaseUrl =\n resolvedEnv.AI_GATEWAY_BASE_URL ?? gatewayAuth.baseUrl;\n if (gatewayApiKey) {\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayApiKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayApiKey,\n baseUrl: gatewayBaseUrl,\n clientApp,\n }),\n });\n return;\n }\n const env = pickProviderEnv(resolvedEnv);\n await registerCustomProviders({\n customEnv: { ...pickProviderEnv(process.env), ...env },\n registries,\n clientApp,\n });\n return;\n }\n }\n\n // Legacy explicit gateway object options.\n const apiKey = resolvedEnv.AI_GATEWAY_API_KEY;\n const baseUrl = resolvedEnv.AI_GATEWAY_BASE_URL;\n if (!apiKey || !baseUrl) return;\n\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey,\n config: createGatewayProviderConfig({ apiKey, baseUrl, clientApp }),\n });\n}\n\nfunction pickOpenAIEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n if (env.OPENAI_API_KEY) result.OPENAI_API_KEY = env.OPENAI_API_KEY;\n if (env.OPENAI_BASE_URL) result.OPENAI_BASE_URL = env.OPENAI_BASE_URL;\n return result;\n}\n\nfunction pickAnthropicEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n if (env.ANTHROPIC_API_KEY) result.ANTHROPIC_API_KEY = env.ANTHROPIC_API_KEY;\n if (env.ANTHROPIC_BASE_URL)\n result.ANTHROPIC_BASE_URL = env.ANTHROPIC_BASE_URL;\n if (env.ANTHROPIC_AUTH_TOKEN)\n result.ANTHROPIC_AUTH_TOKEN = env.ANTHROPIC_AUTH_TOKEN;\n return result;\n}\n\n/**\n * Filters an env object down to provider-credential keys (`*_API_KEY`,\n * `*_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`). Pi does not read provider\n * credentials from the environment itself — providers are only registered\n * through `registerProvider` / `setRuntimeApiKey` — so we must extract the\n * relevant entries before handing them to `registerCustomProviders`.\n */\nfunction pickProviderEnv(\n env: NodeJS.ProcessEnv | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (\n value &&\n (key.endsWith('_API_KEY') ||\n key.endsWith('_BASE_URL') ||\n key === 'ANTHROPIC_AUTH_TOKEN')\n ) {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction normalizePiAuthToLegacyAuth(\n options: PiAuthOptions | undefined,\n): LegacyPiAuthOptions | undefined {\n if (options == null || options === 'auto') {\n return undefined;\n }\n if (typeof options === 'string') {\n switch (options) {\n case 'ai-gateway':\n return { gateway: {} };\n case 'custom':\n case 'openai':\n case 'anthropic':\n return { customEnv: {} };\n default:\n return undefined;\n }\n }\n\n console.warn(\n '[pi] Passing an object to auth options is deprecated. Use a string mode (\"auto\" | \"openai\" | \"anthropic\" | \"custom\" | \"ai-gateway\") instead, and pass credentials via environment variables.',\n );\n return options;\n}\n\nfunction resolveCustomEnv({\n customEnv,\n}: {\n customEnv: Record<string, string>;\n}): Record<string, string> {\n const apiKey = customEnv.AI_GATEWAY_API_KEY;\n if (!apiKey) return {};\n\n return {\n AI_GATEWAY_API_KEY: apiKey,\n AI_GATEWAY_BASE_URL:\n customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL,\n };\n}\n\nasync function registerCustomProviders({\n customEnv,\n registries,\n clientApp,\n}: {\n customEnv: Record<string, string>;\n registries: PiRegistries;\n clientApp: string;\n}): Promise<void> {\n const gatewayKey = customEnv.AI_GATEWAY_API_KEY;\n if (gatewayKey) {\n const baseUrl = customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL;\n await register({\n registries,\n provider: 'vercel-ai-gateway',\n apiKey: gatewayKey,\n config: createGatewayProviderConfig({\n apiKey: gatewayKey,\n baseUrl,\n clientApp,\n }),\n });\n }\n\n if (customEnv.OPENAI_API_KEY) {\n const baseUrl = customEnv.OPENAI_BASE_URL ?? DEFAULT_OPENAI_BASE_URL;\n await register({\n registries,\n provider: 'openai',\n apiKey: customEnv.OPENAI_API_KEY,\n config: {\n apiKey: customEnv.OPENAI_API_KEY,\n baseUrl,\n authHeader: true,\n },\n });\n }\n\n if (customEnv.ANTHROPIC_API_KEY) {\n const baseUrl = customEnv.ANTHROPIC_BASE_URL ?? DEFAULT_ANTHROPIC_BASE_URL;\n await register({\n registries,\n provider: 'anthropic',\n apiKey: customEnv.ANTHROPIC_API_KEY,\n config: {\n apiKey: customEnv.ANTHROPIC_API_KEY,\n baseUrl,\n ...(customEnv.ANTHROPIC_AUTH_TOKEN\n ? {\n headers: {\n authorization: `Bearer ${customEnv.ANTHROPIC_AUTH_TOKEN}`,\n },\n }\n : {}),\n },\n });\n }\n\n for (const [name, apiKey] of Object.entries(customEnv)) {\n if (!name.endsWith('_API_KEY') || !apiKey) {\n continue;\n }\n const prefix = name.slice(0, -'_API_KEY'.length);\n if (\n prefix === 'AI_GATEWAY' ||\n prefix === 'OPENAI' ||\n prefix === 'ANTHROPIC'\n ) {\n continue;\n }\n const provider = prefix.toLowerCase().replace(/_/g, '-');\n const baseUrl = customEnv[`${prefix}_BASE_URL`];\n if (!baseUrl) {\n continue;\n }\n await register({\n registries,\n provider,\n apiKey,\n config: {\n apiKey,\n baseUrl,\n authHeader: true,\n },\n });\n }\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { z } from 'zod/v4';\n\n/**\n * Pi `session.subscribe` emits a discriminated union of events. The exact\n * shape evolves with Pi versions; we accept loose objects and extract only\n * the fields we recognise. The `type` field is required and stringly-typed\n * because Pi may add new types we want to ignore.\n */\nexport const piSessionEventSchema = z.looseObject({\n type: z.string(),\n assistantMessageEvent: z\n .looseObject({\n type: z.string().optional(),\n delta: z.string().optional(),\n })\n .optional(),\n toolCallId: z.string().optional(),\n toolName: z.string().optional(),\n args: z.unknown().optional(),\n input: z.unknown().optional(),\n result: z.unknown().optional(),\n content: z.unknown().optional(),\n isError: z.boolean().optional(),\n // Compaction events (`compaction_start` / `compaction_end`). `result` (a\n // `CompactionResult`) rides the shared `result` field above; `reason`\n // distinguishes manual vs automatic (threshold/overflow) compaction.\n reason: z.string().optional(),\n aborted: z.boolean().optional(),\n error: z\n .union([\n z.string(),\n z.looseObject({\n errorMessage: z.string().optional(),\n stopReason: z.string().optional(),\n }),\n ])\n .optional(),\n message: z\n .looseObject({\n role: z.string().optional(),\n content: z.unknown().optional(),\n stopReason: z.string().optional(),\n errorMessage: z.string().optional(),\n })\n .optional(),\n});\n\nexport type PiSessionEvent = z.infer<typeof piSessionEventSchema>;\n\n/**\n * Decode an unknown raw event into a `PiSessionEvent` if it looks like one.\n * Returns `undefined` if it doesn't parse so the caller can skip it.\n */\nexport function parseNativeEvent(raw: unknown): PiSessionEvent | undefined {\n const parsed = piSessionEventSchema.safeParse(raw);\n return parsed.success ? parsed.data : undefined;\n}\n\n/**\n * Detect whether a Pi event signals a terminal error for the current turn.\n * Returns the error message if so. Mirrors the original adapter's\n * `getPiTerminalError`.\n */\nexport function getPiTerminalError(event: PiSessionEvent): string | undefined {\n const isTerminalStopReason = (value: string | undefined) =>\n value === 'error' || value === 'aborted';\n\n if (typeof event.error === 'string' && event.error.trim()) {\n return event.error.trim();\n }\n\n if (event.error && typeof event.error === 'object') {\n const errorMessage = event.error.errorMessage?.trim();\n if (errorMessage) {\n return errorMessage;\n }\n const stopReason = event.error.stopReason?.trim();\n if (isTerminalStopReason(stopReason)) {\n return stopReason;\n }\n }\n\n const messageError = event.message?.errorMessage?.trim();\n if (messageError) {\n return messageError;\n }\n\n const messageStopReason = event.message?.stopReason?.trim();\n if (isTerminalStopReason(messageStopReason)) {\n return messageStopReason;\n }\n\n if (\n event.isError &&\n typeof event.content === 'string' &&\n event.content.trim()\n ) {\n return event.content.trim();\n }\n\n return undefined;\n}\n\n/** Pull the assistant text from a `turn_end` / `message_end` event payload. */\nexport function extractAssistantText(\n message: PiSessionEvent['message'],\n): string {\n if (!message || message.role !== 'assistant') {\n return '';\n }\n\n if (typeof message.content === 'string') {\n return message.content;\n }\n\n if (!Array.isArray(message.content)) {\n return '';\n }\n\n return message.content\n .flatMap(part => {\n if (!part || typeof part !== 'object') {\n return [];\n }\n const contentPart = part as Record<string, unknown>;\n return contentPart.type === 'text' && typeof contentPart.text === 'string'\n ? [contentPart.text]\n : [];\n })\n .join('');\n}\n","import type { ModelRegistry } from '@earendil-works/pi-coding-agent';\nimport { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\ntype PiModel = ReturnType<ModelRegistry['getAll']>[number];\n\n/**\n * Default model id used when no `model` is configured AND gateway credentials\n * are available in the environment. Looked up from Pi's own model registry —\n * the entry must exist under the `vercel-ai-gateway` provider in\n * `@earendil-works/pi-ai`'s catalog.\n */\nexport const DEFAULT_PI_GATEWAY_MODEL_ID = 'anthropic/claude-sonnet-4.6';\n\n/*\n * A `\"<provider>/<id>\"` reference normally resolves under that provider, not\n * any entry whose flat `id` happens to equal the whole string. Routing proxies\n * (`vercel-ai-gateway`, `openrouter`) can carry another provider's id verbatim\n * as their own flat `id` (e.g. `id: \"xai/grok-4.3\"`), so this tier normally\n * wins over flat matching. An authenticated literal-id match remains usable\n * when the scoped provider is unauthenticated, matching Pi's own resolver.\n * Gateway preference stays first because gateway credentials explicitly opt\n * the harness into routing matching models through the gateway.\n */\nconst findScopedMatch = (\n effectiveId: string,\n models: PiModel[],\n): PiModel | undefined => {\n const slashIndex = effectiveId.indexOf('/');\n if (slashIndex === -1) return undefined;\n\n const prefix = effectiveId.slice(0, slashIndex);\n const bareId = effectiveId.slice(slashIndex + 1);\n return models.find(\n m => m.provider === prefix && (m.id === bareId || m.name === bareId),\n );\n};\n\nexport function createPiModelResolver({\n modelRegistry,\n env = process.env,\n}: {\n modelRegistry: ModelRegistry;\n env?: NodeJS.ProcessEnv;\n}) {\n let cachedModels: PiModel[] | undefined;\n\n const loadModels = (): PiModel[] => {\n if (cachedModels) {\n return cachedModels;\n }\n try {\n cachedModels = modelRegistry.getAll();\n } catch {\n cachedModels = [];\n }\n return cachedModels;\n };\n\n return (modelId: string | undefined): PiModel | undefined => {\n const useGateway = Boolean(getAiGatewayAuthFromEnv({ env }).apiKey);\n const effectiveId =\n modelId ?? (useGateway ? DEFAULT_PI_GATEWAY_MODEL_ID : undefined);\n if (!effectiveId) return undefined;\n\n const models = loadModels();\n const matches = (m: PiModel) =>\n m.id === effectiveId || m.name === effectiveId;\n\n // When gateway creds are present, prefer the gateway-routed entry for the\n // given id. Pi's catalog lists the same model id under multiple providers\n // (e.g. `anthropic/claude-sonnet-4.6` exists under both `openrouter` and\n // `vercel-ai-gateway`); without this preference Pi would dispatch through\n // a provider we didn't register, which fails with \"No API key found\".\n const gatewayMatch = useGateway\n ? models.find(m => m.provider === 'vercel-ai-gateway' && matches(m))\n : undefined;\n if (gatewayMatch) return gatewayMatch;\n\n const scopedMatch = findScopedMatch(effectiveId, models);\n if (scopedMatch && !modelRegistry.hasConfiguredAuth(scopedMatch)) {\n const authenticatedFlatMatches = models.filter(\n m => m.id === effectiveId && modelRegistry.hasConfiguredAuth(m),\n );\n if (authenticatedFlatMatches.length === 1) {\n return authenticatedFlatMatches[0];\n }\n }\n\n return scopedMatch ?? models.find(matches);\n };\n}\n","import { realpathSync } from 'node:fs';\nimport path from 'node:path';\n\nexport interface PiPathMapper {\n /** The host-side mirror directory Pi reads/writes through the workspace VFS. */\n readonly hostWorkDir: string;\n /** The sandbox-side working directory where tools actually operate. */\n readonly sandboxWorkDir: string;\n /**\n * Translate a path the host sees (relative to `hostWorkDir`, or absolute\n * inside it, or already a sandbox path) to the canonical sandbox path. Throws\n * if the path would escape the workspace.\n */\n toSandboxPath(inputPath: string): string;\n /**\n * Translate a path for read-only tools. In addition to the workspace, this\n * allows explicitly configured sandbox roots such as `$HOME/.agents/skills`.\n */\n toReadableSandboxPath(inputPath: string): string;\n /** Verify that a sandbox-side path is still inside `sandboxWorkDir`. */\n assertSandboxPath(inputPath: string): string;\n /**\n * Verify that a sandbox-side path is inside `sandboxWorkDir` or an\n * explicitly configured readable root.\n */\n assertReadableSandboxPath(inputPath: string): string;\n /** Translate any path to its POSIX-relative form under `sandboxWorkDir`. */\n toRelativePath(inputPath: string): string;\n}\n\nexport interface PiReadablePathRoot {\n readonly sandboxDir: string;\n}\n\nexport interface CreatePiPathMapperOptions {\n readonly hostWorkDir: string;\n readonly sandboxWorkDir: string;\n readonly readableRoots?: ReadonlyArray<PiReadablePathRoot>;\n}\n\nfunction isInsidePath(parent: string, candidate: string): boolean {\n const relative = path.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.isAbsolute(relative))\n );\n}\n\nfunction isInsidePosixPath(parent: string, candidate: string): boolean {\n const relative = path.posix.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.posix.isAbsolute(relative))\n );\n}\n\nfunction canonicalizeForContainment(inputPath: string): string {\n try {\n return realpathSync.native(inputPath);\n } catch {\n const parent = path.dirname(inputPath);\n if (parent === inputPath) {\n return inputPath;\n }\n return path.join(\n canonicalizeForContainment(parent),\n path.basename(inputPath),\n );\n }\n}\n\nexport function createPiPathMapper(\n options: CreatePiPathMapperOptions,\n): PiPathMapper {\n const normalizedHost = path.resolve(options.hostWorkDir);\n const normalizedSandbox = path.posix.normalize(options.sandboxWorkDir);\n const canonicalHost = canonicalizeForContainment(normalizedHost);\n const readableRoots =\n options.readableRoots?.map(root => ({\n sandboxDir: path.posix.normalize(root.sandboxDir),\n })) ?? [];\n\n const assertWorkspaceSandboxPath = (inputPath: string): string => {\n const normalizedInput = path.posix.normalize(inputPath);\n if (!isInsidePosixPath(normalizedSandbox, normalizedInput)) {\n throw new Error(`Pi path escapes the workspace: ${inputPath}`);\n }\n return normalizedInput;\n };\n\n const assertReadableSandboxPath = (inputPath: string): string => {\n const normalizedInput = path.posix.normalize(inputPath);\n if (\n !isInsidePosixPath(normalizedSandbox, normalizedInput) &&\n !readableRoots.some(root =>\n isInsidePosixPath(root.sandboxDir, normalizedInput),\n )\n ) {\n throw new Error(`Pi path escapes the readable roots: ${inputPath}`);\n }\n return normalizedInput;\n };\n\n const toWorkspaceSandboxPath = (inputPath: string): string => {\n if (path.posix.isAbsolute(inputPath)) {\n const normalizedInput = path.posix.normalize(inputPath);\n try {\n return assertWorkspaceSandboxPath(normalizedInput);\n } catch {\n // Absolute host paths are handled below.\n }\n }\n\n const resolvedHost = path.isAbsolute(inputPath)\n ? path.resolve(inputPath)\n : path.resolve(normalizedHost, inputPath);\n const canonicalResolvedHost = canonicalizeForContainment(resolvedHost);\n if (\n !isInsidePath(normalizedHost, resolvedHost) ||\n !isInsidePath(canonicalHost, canonicalResolvedHost)\n ) {\n throw new Error(`Pi path escapes the workspace: ${inputPath}`);\n }\n\n const relative = path\n .relative(normalizedHost, resolvedHost)\n .split(path.sep)\n .join('/');\n return relative\n ? path.posix.join(normalizedSandbox, relative)\n : normalizedSandbox;\n };\n\n return {\n hostWorkDir: normalizedHost,\n sandboxWorkDir: normalizedSandbox,\n toSandboxPath(inputPath: string) {\n return toWorkspaceSandboxPath(inputPath);\n },\n toReadableSandboxPath(inputPath: string) {\n if (path.posix.isAbsolute(inputPath)) {\n const normalizedInput = path.posix.normalize(inputPath);\n try {\n return assertReadableSandboxPath(normalizedInput);\n } catch {\n // Absolute host paths are handled by workspace mapping below.\n }\n }\n\n return toWorkspaceSandboxPath(inputPath);\n },\n assertSandboxPath(inputPath: string) {\n return assertWorkspaceSandboxPath(inputPath);\n },\n assertReadableSandboxPath(inputPath: string) {\n return assertReadableSandboxPath(inputPath);\n },\n toRelativePath(inputPath: string) {\n const sandboxPath = path.posix.isAbsolute(inputPath)\n ? path.posix.normalize(inputPath)\n : path.posix.join(\n normalizedSandbox,\n inputPath.split(path.sep).join('/'),\n );\n const relative = path.posix.relative(normalizedSandbox, sandboxPath);\n return relative || '.';\n },\n };\n}\n","import path from 'node:path';\nimport { shellQuote } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\nimport type { PiPathMapper } from './pi-paths';\n\nexport type PiRemoteFileChangeKind = 'create' | 'modify';\n\nexport interface PiRemoteOpsOptions {\n readonly sandbox: Experimental_SandboxSession;\n readonly paths: PiPathMapper;\n readonly env?: Record<string, string>;\n readonly onFileChange?: (\n event: PiRemoteFileChangeKind,\n relativePath: string,\n content: Buffer,\n ) => void;\n}\n\nexport interface PiRemoteOps {\n readonly paths: PiPathMapper;\n readBuffer(inputPath: string): Promise<Buffer>;\n writeFile(inputPath: string, content: string): Promise<void>;\n editFile(\n inputPath: string,\n oldText: string,\n newText: string,\n ): Promise<string>;\n listDirectory(inputPath?: string, limit?: number): Promise<string[]>;\n findFiles(\n pattern: string,\n inputPath?: string,\n limit?: number,\n ): Promise<string[]>;\n grepFiles(\n pattern: string,\n input: {\n path?: string;\n glob?: string;\n ignoreCase?: boolean;\n literal?: boolean;\n context?: number;\n limit?: number;\n },\n ): Promise<string>;\n access(inputPath: string): Promise<void>;\n exec(\n command: string,\n cwd: string,\n input: {\n onData: (data: Buffer) => void;\n signal?: AbortSignal;\n timeout?: number;\n },\n ): Promise<{ exitCode: number | null }>;\n}\n\ninterface RunShellInput {\n cwd?: string;\n signal?: AbortSignal;\n onData?: (data: Buffer) => void;\n}\n\ninterface RunShellResult {\n exitCode: number | null;\n output: Buffer;\n}\n\nfunction lastOutputLine(output: Buffer): string | undefined {\n return output.toString('utf8').trim().split('\\n').filter(Boolean).at(-1);\n}\n\nexport function createPiRemoteOps(options: PiRemoteOpsOptions): PiRemoteOps {\n const runShell = async (\n command: string,\n input: RunShellInput = {},\n ): Promise<RunShellResult> => {\n // `sandbox.run({ command })` already wraps in `bash -c`; we pass the\n // shell snippet directly. shellQuote is still used inside `command`\n // for path/value interpolation by the callers.\n const result = await options.sandbox.run({\n command,\n ...(input.cwd\n ? { workingDirectory: options.paths.toSandboxPath(input.cwd) }\n : {}),\n ...(options.env ? { env: options.env } : {}),\n ...(input.signal ? { abortSignal: input.signal } : {}),\n });\n\n const combined = `${result.stdout}${result.stderr}`;\n const output = Buffer.from(combined, 'utf8');\n if (output.length > 0) {\n input.onData?.(output);\n }\n\n return {\n exitCode: result.exitCode,\n output,\n };\n };\n\n const resolveExistingSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> => {\n const result = await runShell(\n [\n `target=${shellQuote(remotePath)}`,\n `if [ ! -e \"$target\" ]; then echo \"__PI_REALPATH_NOT_FOUND__\"; exit 2; fi`,\n `resolved=$(realpath \"$target\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }`,\n `printf '%s\\\\n' \"$resolved\"`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8');\n if (output.includes('__PI_REALPATH_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n if (output.includes('__PI_REALPATH_FAILED__') || result.exitCode !== 0) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n\n const resolvedPath = lastOutputLine(result.output);\n if (!resolvedPath) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n return resolvedPath;\n };\n\n const resolveReadableSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> =>\n options.paths.assertReadableSandboxPath(\n await resolveExistingSandboxPath(remotePath, inputPath),\n );\n\n const resolveWritableSandboxPath = async (\n remotePath: string,\n inputPath: string,\n ): Promise<string> => {\n const result = await runShell(\n [\n `target=${shellQuote(remotePath)}`,\n `if [ -e \"$target\" ] || [ -L \"$target\" ]; then resolved=$(realpath \"$target\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }; printf '%s\\\\n' \"$resolved\"; exit 0; fi`,\n `dir=$(dirname \"$target\")`,\n `base=$(basename \"$target\")`,\n `missing=\"$base\"`,\n `while [ ! -e \"$dir\" ] && [ ! -L \"$dir\" ]; do parent=$(dirname \"$dir\"); if [ \"$parent\" = \"$dir\" ]; then echo \"__PI_REALPATH_NOT_FOUND__\"; exit 2; fi; missing=\"$(basename \"$dir\")/$missing\"; dir=\"$parent\"; done`,\n `resolved_dir=$(realpath \"$dir\" 2>/dev/null) || { echo \"__PI_REALPATH_FAILED__\"; exit 3; }`,\n `printf '%s/%s\\\\n' \"$resolved_dir\" \"$missing\"`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8');\n if (\n output.includes('__PI_REALPATH_NOT_FOUND__') ||\n output.includes('__PI_REALPATH_FAILED__') ||\n result.exitCode !== 0\n ) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n\n const resolvedPath = lastOutputLine(result.output);\n if (!resolvedPath) {\n throw new Error(`Unable to resolve path: ${inputPath}`);\n }\n return options.paths.assertSandboxPath(resolvedPath);\n };\n\n const readBuffer = async (inputPath: string): Promise<Buffer> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const bytes = await options.sandbox.readBinaryFile({\n path: resolvedPath,\n });\n if (!bytes) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n return Buffer.from(bytes);\n };\n\n const writeFile = async (\n inputPath: string,\n content: string,\n ): Promise<void> => {\n const remotePath = options.paths.toSandboxPath(inputPath);\n const resolvedPath = await resolveWritableSandboxPath(\n remotePath,\n inputPath,\n );\n const previous = await options.sandbox.readBinaryFile({\n path: resolvedPath,\n });\n await runShell(`mkdir -p ${shellQuote(path.posix.dirname(resolvedPath))}`);\n await options.sandbox.writeTextFile({ path: resolvedPath, content });\n options.onFileChange?.(\n previous ? 'modify' : 'create',\n options.paths.toRelativePath(resolvedPath),\n Buffer.from(content, 'utf8'),\n );\n };\n\n const editFile = async (\n inputPath: string,\n oldText: string,\n newText: string,\n ): Promise<string> => {\n const current = (await readBuffer(inputPath)).toString('utf8');\n const index = current.indexOf(oldText);\n if (index === -1) {\n throw new Error(`Text to replace was not found in ${inputPath}`);\n }\n const updated = `${current.slice(0, index)}${newText}${current.slice(\n index + oldText.length,\n )}`;\n await writeFile(inputPath, updated);\n return updated;\n };\n\n const listDirectory = async (\n inputPath: string = '.',\n limit: number = 500,\n ): Promise<string[]> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_LS_NOT_FOUND__\"; exit 2; fi`,\n `if [ ! -d ${shellQuote(resolvedPath)} ]; then echo \"__PI_LS_NOT_DIR__\"; exit 3; fi`,\n `cd ${shellQuote(resolvedPath)}`,\n 'ls -1Ap',\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_LS_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n if (output.includes('__PI_LS_NOT_DIR__')) {\n throw new Error(`Not a directory: ${inputPath}`);\n }\n\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => line.replace(/[*=@|]$/, ''))\n .sort((left, right) =>\n left.toLowerCase().localeCompare(right.toLowerCase()),\n )\n .slice(0, limit);\n };\n\n const findFiles = async (\n pattern: string,\n inputPath: string = '.',\n limit: number = 1_000,\n ): Promise<string[]> => {\n const remotePath = options.paths.toReadableSandboxPath(inputPath);\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n inputPath,\n );\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_FIND_NOT_FOUND__\"; exit 2; fi`,\n `if [ -d ${shellQuote(resolvedPath)} ]; then find ${shellQuote(resolvedPath)} -type f -print; else printf '%s\\\\n' ${shellQuote(resolvedPath)}; fi`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_FIND_NOT_FOUND__')) {\n throw new Error(`Path not found: ${inputPath}`);\n }\n\n const searchRoot = resolvedPath;\n return output\n .split('\\n')\n .filter(Boolean)\n .map(absolutePath => {\n if (absolutePath === searchRoot) {\n return path.posix.basename(absolutePath);\n }\n return path.posix.relative(searchRoot, absolutePath);\n })\n .filter(\n candidate =>\n candidate.length > 0 && path.matchesGlob(candidate, pattern),\n )\n .sort((left, right) =>\n left.toLowerCase().localeCompare(right.toLowerCase()),\n )\n .slice(0, limit);\n };\n\n const grepFiles = async (\n pattern: string,\n input: {\n path?: string;\n glob?: string;\n ignoreCase?: boolean;\n literal?: boolean;\n context?: number;\n limit?: number;\n },\n ): Promise<string> => {\n const remotePath = options.paths.toReadableSandboxPath(input.path ?? '.');\n const resolvedPath = await resolveReadableSandboxPath(\n remotePath,\n input.path ?? '.',\n );\n const relativeTarget = options.paths.toRelativePath(resolvedPath);\n const targetPath =\n relativeTarget.startsWith('../') || path.posix.isAbsolute(relativeTarget)\n ? resolvedPath\n : relativeTarget;\n const flags = [\n '-r',\n '-n',\n '--binary-files=without-match',\n ...(input.ignoreCase ? ['-i'] : []),\n ...(input.literal ? ['-F'] : []),\n ...(typeof input.context === 'number' && input.context > 0\n ? ['-C', String(input.context)]\n : []),\n ...(input.glob ? ['--include', input.glob] : []),\n ];\n const limit = Math.max(1, input.limit ?? 100);\n const result = await runShell(\n [\n `if [ ! -e ${shellQuote(resolvedPath)} ]; then echo \"__PI_GREP_NOT_FOUND__\"; exit 2; fi`,\n `cd ${shellQuote(options.paths.sandboxWorkDir)}`,\n `grep ${flags.map(shellQuote).join(' ')} -- ${shellQuote(pattern)} ${shellQuote(targetPath)} 2>/dev/null | head -n ${limit}`,\n ].join('; '),\n );\n\n const output = result.output.toString('utf8').trim();\n if (output.includes('__PI_GREP_NOT_FOUND__')) {\n throw new Error(`Path not found: ${input.path ?? '.'}`);\n }\n\n return output || 'No matches found';\n };\n\n return {\n paths: options.paths,\n readBuffer,\n writeFile,\n editFile,\n listDirectory,\n findFiles,\n grepFiles,\n async access(inputPath: string) {\n await readBuffer(inputPath);\n },\n async exec(command, cwd, input): Promise<{ exitCode: number | null }> {\n const controller = new AbortController();\n // `input.timeout` is expressed in seconds (Pi's `bash` tool contract),\n // so convert to milliseconds for `setTimeout`.\n const timeoutId =\n typeof input.timeout === 'number' && input.timeout > 0\n ? setTimeout(() => controller.abort(), input.timeout * 1000)\n : undefined;\n\n const forwardedSignal = input.signal;\n const onAbort = () => controller.abort();\n forwardedSignal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n const result = await runShell(command, {\n cwd,\n signal: controller.signal,\n onData: input.onData,\n });\n return { exitCode: result.exitCode };\n } finally {\n forwardedSignal?.removeEventListener('abort', onAbort);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n },\n };\n}\n","import path from 'node:path';\nimport type { HarnessV1Skill } from '@ai-sdk/harness';\nimport { writeSkills } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\n\n/**\n * Materialize Pi skills as files under\n * `$HOME/.agents/skills/<name>/SKILL.md` inside the sandbox.\n */\nexport async function writePiSkills(args: {\n readonly sandbox: Experimental_SandboxSession;\n readonly sandboxHomeDir: string;\n readonly skills: ReadonlyArray<HarnessV1Skill>;\n readonly abortSignal?: AbortSignal;\n}): Promise<void> {\n await writeSkills({\n sandbox: args.sandbox,\n rootDir: path.posix.join(args.sandboxHomeDir, '.agents', 'skills'),\n skills: args.skills,\n abortSignal: args.abortSignal,\n invalidSkillNameMessage: ({ name }) => `Invalid Pi skill name: ${name}`,\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid Pi skill file path for ${skillName}: ${filePath}`,\n });\n}\n","import { randomBytes } from 'node:crypto';\nimport type { HarnessV1StreamPart } from '@ai-sdk/harness';\nimport { secureJsonParse } from '@ai-sdk/provider-utils';\nimport { extractAssistantText, type PiSessionEvent } from './pi-events';\nimport { serializeToolOutput } from './pi-utils';\n\n/**\n * Translator state shared across all events of a single turn. Reset at the\n * start of every `doPromptTurn`. Callers update the same instance and read it to\n * decide when a turn has settled into a steady state (e.g. for gap-filling).\n */\nexport interface PiTranslatorState {\n /**\n * True once a `turn_start` or assistant `message_start` event has been\n * observed. Suppresses spurious deltas that arrive before the turn opens.\n */\n promptStarted: boolean;\n /** Accumulated assistant text from `text_delta` events. */\n streamedAssistantText: string;\n /** Stream-part id for the active text block; synthesized on first delta. */\n currentTextId: string | undefined;\n /**\n * Stream-part id for the active reasoning block; synthesized lazily on\n * first `thinking_delta`.\n */\n currentReasoningId: string | undefined;\n /** Whether a `reasoning-start` event has already been emitted. */\n reasoningStarted: boolean;\n /** Tool-call id → tool name (used to fill in `toolName` on results). */\n observedToolNames: Map<string, string>;\n /** Tool ids requested by the current assistant message but not yet completed. */\n pendingStepToolCallIds: Set<string>;\n /** Whether the current assistant message has opened a visible step. */\n stepOpen: boolean;\n /**\n * Tool-call id → the exact output value the host submitted for a\n * user-registered (host-executed) tool. Pi only echoes the tool result back\n * as serialized text (the tool handler stringifies the output before handing\n * it to the runtime so the model can read it), which would otherwise reach\n * consumers as a string and lose the original object structure. Keeping the\n * submitted value here lets the result projection surface the original object\n * — matching the other adapters — while the model still receives the text.\n * Populated by the session's `submitToolResult`; consumed (and cleared) when\n * the matching `tool_result`/`tool_execution_end` event is translated.\n */\n hostToolResults: Map<string, unknown>;\n dynamicToolCallIds: Set<string>;\n /**\n * Names of tools that Pi executes natively (read/write/edit/bash/grep/\n * find/ls). `tool-call` events for these get `providerExecuted: true`\n * so the harness host doesn't try to dispatch them. User-registered\n * tools are not in this set.\n */\n readonly builtinToolNames: ReadonlySet<string>;\n readonly hostToolNames: ReadonlySet<string>;\n /**\n * Map of native tool name → common name. `find` → `glob`, etc. Pi emits\n * native names on its events; the wire `toolName` is the common name when\n * one exists.\n */\n readonly nativeToCommonNameMap: ReadonlyMap<string, string>;\n}\n\nexport interface PiTranslatorStateOptions {\n readonly builtinToolNames?: ReadonlyArray<string>;\n readonly hostToolNames?: ReadonlyArray<string>;\n readonly nativeToCommon?:\n | ReadonlyMap<string, string>\n | Record<string, string>;\n}\n\nexport function createPiTranslatorState(\n options: PiTranslatorStateOptions = {},\n): PiTranslatorState {\n const map =\n options.nativeToCommon instanceof Map\n ? options.nativeToCommon\n : new Map(Object.entries(options.nativeToCommon ?? {}));\n return {\n promptStarted: false,\n streamedAssistantText: '',\n currentTextId: undefined,\n currentReasoningId: undefined,\n reasoningStarted: false,\n observedToolNames: new Map(),\n pendingStepToolCallIds: new Set(),\n stepOpen: false,\n hostToolResults: new Map(),\n dynamicToolCallIds: new Set(),\n builtinToolNames: new Set(options.builtinToolNames ?? []),\n hostToolNames: new Set(options.hostToolNames ?? []),\n nativeToCommonNameMap: map,\n };\n}\n\nfunction newId(): string {\n return randomBytes(8).toString('hex');\n}\n\n/**\n * Pi's `tool_execution_end` event payload (`result`) is a Pi `AgentToolResult`\n * envelope `{ content: (TextContent | ImageContent)[], details, terminate? }`.\n * The `tool_result` event uses a flat shape with `content` and `details` at\n * the top level. In both cases we extract just the text payload (joined when\n * multiple text parts are present) so the AI SDK consumer sees the raw\n * string the tool produced.\n */\nfunction unwrapPiToolResult(event: PiSessionEvent): never {\n const candidates: unknown[] = [];\n const result = event.result as unknown;\n if (result && typeof result === 'object') {\n const inner = (result as { content?: unknown }).content;\n if (Array.isArray(inner)) candidates.push(inner);\n }\n if (Array.isArray(event.content)) candidates.push(event.content);\n\n for (const content of candidates) {\n if (!Array.isArray(content)) continue;\n const text = content\n .filter(\n (p): p is { type: 'text'; text: string } =>\n !!p &&\n typeof p === 'object' &&\n (p as { type?: unknown }).type === 'text' &&\n typeof (p as { text?: unknown }).text === 'string',\n )\n .map(p => p.text)\n .join('');\n if (text) return text as never;\n }\n\n if (typeof event.result === 'string') return event.result as never;\n if (typeof event.content === 'string') return event.content as never;\n return (event.result ?? event.content ?? null) as never;\n}\n\nfunction parseMcpToolResult(content: unknown): unknown {\n if (typeof content !== 'string') return content;\n try {\n return secureJsonParse(content);\n } catch {\n return content;\n }\n}\n\nfunction resolveToolName(\n state: PiTranslatorState,\n nativeName: string,\n): { wire: string; native: string } {\n const common = state.nativeToCommonNameMap.get(nativeName);\n return { wire: common ?? nativeName, native: nativeName };\n}\n\nfunction finishStep(state: PiTranslatorState): HarnessV1StreamPart[] {\n if (!state.stepOpen || state.pendingStepToolCallIds.size > 0) return [];\n state.stepOpen = false;\n state.pendingStepToolCallIds.clear();\n return [\n {\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: {\n inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },\n outputTokens: { total: 0, text: 0, reasoning: 0 },\n },\n harnessMetadata: { pi: { inferredStep: true } },\n },\n ];\n}\n\nexport function finishPiApprovalStep(\n state: PiTranslatorState,\n toolCallId: string,\n): HarnessV1StreamPart[] {\n state.stepOpen = true;\n state.pendingStepToolCallIds.delete(toolCallId);\n return finishStep(state);\n}\n\nfunction extractPiToolCallIds(message: PiSessionEvent['message']): string[] {\n if (!message || message.role !== 'assistant') return [];\n if (!Array.isArray(message.content)) return [];\n return message.content.flatMap(part => {\n if (!part || typeof part !== 'object') return [];\n const block = part as Record<string, unknown>;\n if (block.type !== 'toolCall') return [];\n const id = block.id ?? block.toolCallId;\n return typeof id === 'string' && id.length > 0 ? [id] : [];\n });\n}\n\n/**\n * Translate a single Pi `session.subscribe` event into zero or more\n * `HarnessV1StreamPart`s, updating the translator state in place. Returns\n * an empty array for events that produce no output (e.g. events emitted\n * before `turn_start`).\n *\n * The translator does NOT emit `stream-start`/`finish` — those are\n * lifecycle signals owned by the session layer.\n */\nexport function translatePiEvent(\n event: PiSessionEvent,\n state: PiTranslatorState,\n): HarnessV1StreamPart[] {\n switch (event.type) {\n case 'turn_start':\n case 'message_start': {\n if (\n event.type === 'message_start' &&\n event.message?.role !== 'assistant'\n ) {\n return [];\n }\n state.promptStarted = true;\n if (event.type === 'message_start') {\n state.stepOpen = true;\n state.pendingStepToolCallIds.clear();\n }\n state.streamedAssistantText = '';\n state.currentTextId = undefined;\n state.currentReasoningId = undefined;\n state.reasoningStarted = false;\n return [];\n }\n\n case 'message_update': {\n if (!state.promptStarted) return [];\n const update = event.assistantMessageEvent;\n if (!update) return [];\n if (update.type === 'text_delta' && typeof update.delta === 'string') {\n const parts: HarnessV1StreamPart[] = [];\n // If reasoning was active, close it before opening the text block so\n // consumers can reset block-scoped formatting (ANSI colors, etc.)\n // between sections.\n if (state.reasoningStarted && state.currentReasoningId) {\n parts.push({\n type: 'reasoning-end',\n id: state.currentReasoningId,\n });\n state.reasoningStarted = false;\n state.currentReasoningId = undefined;\n }\n if (!state.currentTextId) {\n state.currentTextId = newId();\n parts.push({ type: 'text-start', id: state.currentTextId });\n }\n state.streamedAssistantText += update.delta;\n parts.push({\n type: 'text-delta',\n id: state.currentTextId,\n delta: update.delta,\n });\n return parts;\n }\n if (\n update.type === 'thinking_delta' &&\n typeof update.delta === 'string'\n ) {\n const parts: HarnessV1StreamPart[] = [];\n // Symmetric to the text branch: close any open text block before\n // starting a fresh reasoning block.\n if (state.currentTextId) {\n parts.push({ type: 'text-end', id: state.currentTextId });\n state.currentTextId = undefined;\n }\n if (!state.currentReasoningId) {\n state.currentReasoningId = newId();\n }\n if (!state.reasoningStarted) {\n state.reasoningStarted = true;\n parts.push({ type: 'reasoning-start', id: state.currentReasoningId });\n }\n parts.push({\n type: 'reasoning-delta',\n id: state.currentReasoningId,\n delta: update.delta,\n });\n return parts;\n }\n return [];\n }\n\n case 'message_end':\n case 'turn_end': {\n if (!state.promptStarted) return [];\n const parts: HarnessV1StreamPart[] = [];\n const fullText = extractAssistantText(event.message);\n if (\n state.currentTextId &&\n fullText.startsWith(state.streamedAssistantText) &&\n fullText.length > state.streamedAssistantText.length\n ) {\n const missing = fullText.slice(state.streamedAssistantText.length);\n state.streamedAssistantText = fullText;\n parts.push({\n type: 'text-delta',\n id: state.currentTextId,\n delta: missing,\n });\n }\n if (state.currentTextId) {\n parts.push({ type: 'text-end', id: state.currentTextId });\n state.currentTextId = undefined;\n }\n if (state.reasoningStarted && state.currentReasoningId) {\n parts.push({ type: 'reasoning-end', id: state.currentReasoningId });\n state.reasoningStarted = false;\n state.currentReasoningId = undefined;\n }\n if (event.type === 'message_end') {\n for (const toolCallId of extractPiToolCallIds(event.message)) {\n state.pendingStepToolCallIds.add(toolCallId);\n }\n } else {\n state.pendingStepToolCallIds.clear();\n parts.push(...finishStep(state));\n }\n return parts;\n }\n\n case 'tool_execution_start': {\n if (!event.toolCallId || !event.toolName) return [];\n const { wire, native } = resolveToolName(state, event.toolName);\n state.observedToolNames.set(event.toolCallId, wire);\n const isMcpTool =\n !state.hostToolNames.has(native) &&\n (native === 'mcp' || native.startsWith('mcp__'));\n const providerExecuted = state.builtinToolNames.has(native) || isMcpTool;\n if (isMcpTool) state.dynamicToolCallIds.add(event.toolCallId);\n const input = serializeToolOutput(event.args ?? event.input ?? {});\n return [\n {\n type: 'tool-call',\n toolCallId: event.toolCallId,\n toolName: wire,\n input,\n ...(wire !== native ? { nativeName: native } : {}),\n ...(providerExecuted ? { providerExecuted: true } : {}),\n ...(isMcpTool ? { dynamic: true } : {}),\n } as HarnessV1StreamPart,\n ];\n }\n\n case 'tool_execution_end':\n case 'tool_result': {\n if (!event.toolCallId) return [];\n const recordedName = state.observedToolNames.get(event.toolCallId);\n const nativeName = event.toolName;\n const wire =\n recordedName ??\n (nativeName ? resolveToolName(state, nativeName).wire : undefined);\n if (!wire) return [];\n const dynamic = state.dynamicToolCallIds.delete(event.toolCallId);\n /*\n * Prefer the exact value the host submitted for user-registered tools\n * (see `hostToolResults`). Built-in tools, whose results Pi produces and\n * reports as text, are not in the map and fall back to unwrapping the\n * event's text payload.\n */\n const result = state.hostToolResults.has(event.toolCallId)\n ? ((state.hostToolResults.get(event.toolCallId) ?? null) as Extract<\n HarnessV1StreamPart,\n { type: 'tool-result' }\n >['result'])\n : dynamic\n ? parseMcpToolResult(unwrapPiToolResult(event))\n : unwrapPiToolResult(event);\n state.hostToolResults.delete(event.toolCallId);\n state.pendingStepToolCallIds.delete(event.toolCallId);\n return [\n {\n type: 'tool-result',\n toolCallId: event.toolCallId,\n toolName: wire,\n result,\n ...(event.isError ? { isError: true } : {}),\n ...(dynamic ? { dynamic: true } : {}),\n } as HarnessV1StreamPart,\n ...finishStep(state),\n ];\n }\n\n case 'compaction_end': {\n /*\n * Pi performs the compaction itself; we observe its result. Skip aborted\n * or result-less compactions (nothing happened). A result with no summary\n * still represents a real compaction, so emit it with a placeholder\n * rather than dropping the event. `reason` is `'manual'` for an explicit\n * `session.compact()` call, `'threshold'`/`'overflow'` for Pi's automatic\n * compaction — both map to `'auto'` on the wire. Pi reports `tokensBefore`\n * but not `tokensAfter`.\n */\n if (event.aborted) return [];\n const result = event.result;\n if (!result || typeof result !== 'object') return [];\n const rawSummary = (result as { summary?: unknown }).summary;\n const summary =\n typeof rawSummary === 'string' ? rawSummary : '(no summary provided)';\n const tokensBefore = (result as { tokensBefore?: unknown }).tokensBefore;\n return [\n {\n type: 'compaction',\n trigger: event.reason === 'manual' ? 'manual' : 'auto',\n summary,\n ...(typeof tokensBefore === 'number' ? { tokensBefore } : {}),\n },\n ];\n }\n\n default:\n return [];\n }\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1Prompt,\n type HarnessV1Skill,\n} from '@ai-sdk/harness';\n\nconst HARNESS_ID = 'pi';\n\n/**\n * Extract a single user text string from a `HarnessV1Prompt`. Pi's\n * `session.prompt(text)` accepts a string; multimodal user content\n * is not supported in this foundational version.\n */\nexport function extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') {\n return prompt;\n }\n\n const { content } = prompt;\n if (typeof content === 'string') {\n return content;\n }\n\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n message: `pi: only text user-message parts are supported; got '${part.type}'.`,\n harnessId: HARNESS_ID,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n\n/*\n * Frame session instructions and the user's text so the runtime treats the\n * instructions as system-provided operating guidance, not something the user\n * wrote. Without the wrapper the agent can echo the prepended text back as if\n * the user had asked for it, which is confusing since the user never typed it.\n * Applied only to the first user message of a fresh session.\n */\nexport function frameInstructions(\n instructions: string,\n userText: string,\n): string {\n return (\n '<session-instructions>\\n' +\n 'The block below is operating guidance from the system, not a message from the user — follow it, but do not mention it or attribute it to the user.\\n\\n' +\n `${instructions}\\n` +\n '</session-instructions>\\n\\n' +\n `<user-message>\\n${userText}\\n</user-message>`\n );\n}\n\n/** Serialize a tool output to the string Pi feeds back to the model. */\nexport function serializeToolOutput(output: unknown): string {\n if (typeof output === 'string') {\n return output;\n }\n const serialized = JSON.stringify(output);\n return serialized ?? 'null';\n}\n\nexport function getErrorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Validate that a name is safe to use as a filesystem path segment under\n * `.pi/skills/<name>/` or `.pi/agents/<name>.md`. Refuses anything that\n * could be interpreted as a path traversal or contains shell-sensitive\n * characters.\n */\nexport function safePiMetadataSegment(name: string, label: string): string {\n if (!/^[A-Za-z0-9._-]+$/.test(name) || name === '.' || name === '..') {\n throw new Error(`Invalid Pi ${label} name: ${name}`);\n }\n return name;\n}\n\n/** Frontmatter renderer for `.pi/skills/<name>/SKILL.md`. */\nexport function renderPiSkillFile(skill: HarnessV1Skill): string {\n return `---\\nname: ${skill.name}\\ndescription: ${skill.description}\\n---\\n\\n${skill.content}`;\n}\n","import { Type, type TSchema } from 'typebox';\n\n/**\n * Wrap a JSON Schema 7 fragment so Pi's `defineTool({ parameters })` accepts\n * it. Pi v0.77 uses TypeBox at the type level but treats `parameters` as\n * opaque schema metadata at runtime, so `Type.Unsafe(jsonSchema)` is\n * sufficient — no per-property structural conversion is needed.\n */\nexport function toolSpecToTypeBoxParameters(jsonSchema: unknown): TSchema {\n return Type.Unsafe(jsonSchema as object);\n}\n","/**\n * Pi VFS — global Node `fs` monkey-patch that redirects reads/writes against a\n * mount point (the session's sandbox working directory, e.g.\n * `/vercel/sandbox/<harnessId>-<sessionId>/...`) to a real backing directory on\n * the host. The mount point is a sandbox path that does not exist on the host,\n * so the redirect never shadows real host files.\n *\n * The mapping is process-global because Pi's upstream runtime reads and\n * writes through the shared `fs` module. Concurrent mounts are supported as\n * long as each instance uses a distinct mount point (each session's sandbox\n * working directory is unique).\n *\n * Multi-instance invariants:\n * - Multiple `PiWorkspaceVfs` instances may stay mounted concurrently.\n * - Path routing uses longest-prefix matching, so mount points must not\n * overlap.\n * - Extra `fs` patches stay installed while `mountedRoots.size > 0` and are\n * restored only after the final unmount.\n * - Mount and unmount remain synchronous, so Node's single-threaded execution\n * preserves patch/install ordering.\n *\n * Supported logical-path APIs:\n * - Sync: `existsSync`, `readFileSync`, `writeFileSync`, `mkdirSync`,\n * `readdirSync`, `renameSync`, `rmSync`, `openSync`, `statSync`,\n * `realpathSync` (+ `.native`).\n * - Callback: `mkdir`, `realpath`, `stat`, `rmdir`, `utimes`, `writeFile`.\n * - Promises: `fs.promises.mkdir`, `fs.promises.readFile`,\n * `fs.promises.writeFile`.\n *\n * Anything else is intentionally unsupported. If Pi starts using additional\n * `fs` APIs against logical roots, those call sites must be added here\n * deliberately with tests.\n */\n\nimport fs from 'node:fs';\nimport { syncBuiltinESMExports } from 'node:module';\nimport path from 'node:path';\n\ntype MountedRoot = {\n backingRoot: string;\n mountPoint: string;\n};\n\ntype WrappedRealpathSync = typeof fs.realpathSync & {\n native?: typeof fs.realpathSync.native;\n};\n\ntype Mutable<T> = {\n -readonly [K in keyof T]: T[K];\n};\n\nconst mountedRoots = new Map<string, MountedRoot>();\nconst mutableFs = fs as Mutable<typeof fs>;\nconst mutableFsPromises = fs.promises as Mutable<typeof fs.promises>;\n\nconst originalFsSyncMethods = {\n existsSync: fs.existsSync,\n mkdirSync: fs.mkdirSync,\n openSync: fs.openSync,\n readFileSync: fs.readFileSync,\n readdirSync: fs.readdirSync,\n realpathSync: fs.realpathSync,\n renameSync: fs.renameSync,\n rmSync: fs.rmSync,\n statSync: fs.statSync,\n writeFileSync: fs.writeFileSync,\n};\n\nconst originalFsCallbackMethods = {\n mkdir: fs.mkdir,\n realpath: fs.realpath,\n rmdir: fs.rmdir,\n stat: fs.stat,\n utimes: fs.utimes,\n writeFile: fs.writeFile,\n};\n\nconst originalFsPromises = {\n mkdir: fs.promises.mkdir.bind(fs.promises),\n readFile: fs.promises.readFile.bind(fs.promises),\n writeFile: fs.promises.writeFile.bind(fs.promises),\n};\n\nfunction isInsidePath(parent: string, candidate: string): boolean {\n const relative = path.relative(parent, candidate);\n return (\n relative === '' ||\n (!relative.startsWith('..') && !path.isAbsolute(relative))\n );\n}\n\nfunction resolveAbsolutePath(inputPath: string): string {\n return path.isAbsolute(inputPath)\n ? path.normalize(inputPath)\n : path.resolve(inputPath);\n}\n\nfunction findMountedRoot(inputPath: string): MountedRoot | undefined {\n const resolvedPath = resolveAbsolutePath(inputPath);\n let bestMatch: MountedRoot | undefined;\n\n for (const mountedRoot of mountedRoots.values()) {\n if (!isInsidePath(mountedRoot.mountPoint, resolvedPath)) {\n continue;\n }\n if (\n !bestMatch ||\n mountedRoot.mountPoint.length > bestMatch.mountPoint.length\n ) {\n bestMatch = mountedRoot;\n }\n }\n\n return bestMatch;\n}\n\nfunction mapToBackingPath(inputPath: string): string | null {\n const mountedRoot = findMountedRoot(inputPath);\n if (!mountedRoot) {\n return null;\n }\n\n const resolvedPath = resolveAbsolutePath(inputPath);\n const relativePath = path.relative(mountedRoot.mountPoint, resolvedPath);\n return relativePath\n ? path.join(mountedRoot.backingRoot, relativePath)\n : mountedRoot.backingRoot;\n}\n\nfunction mapRealpathResult(inputPath: string, result: string): string {\n const mountedRoot = findMountedRoot(inputPath);\n if (!mountedRoot) {\n return result;\n }\n\n let normalizedBackingRoot = path.resolve(mountedRoot.backingRoot);\n try {\n const realpath =\n originalFsSyncMethods.realpathSync.native ??\n originalFsSyncMethods.realpathSync;\n normalizedBackingRoot = path.resolve(realpath(mountedRoot.backingRoot));\n } catch {\n // Fall back to the configured backing root when canonicalization fails.\n }\n\n const normalizedResult = path.resolve(result);\n if (!isInsidePath(normalizedBackingRoot, normalizedResult)) {\n return result;\n }\n\n const relativePath = path.relative(normalizedBackingRoot, normalizedResult);\n return relativePath\n ? path.join(mountedRoot.mountPoint, relativePath)\n : mountedRoot.mountPoint;\n}\n\nfunction mapRenamePaths(\n sourcePath: string,\n destinationPath: string,\n): [string, string] | null {\n const sourceRoot = findMountedRoot(sourcePath);\n const destinationRoot = findMountedRoot(destinationPath);\n\n if (!sourceRoot && !destinationRoot) {\n return null;\n }\n\n if (\n !sourceRoot ||\n !destinationRoot ||\n sourceRoot.mountPoint !== destinationRoot.mountPoint\n ) {\n throw new Error(\n 'Pi logical VFS paths cannot rename across mount boundaries',\n );\n }\n\n return [\n mapToBackingPath(sourcePath) ?? sourcePath,\n mapToBackingPath(destinationPath) ?? destinationPath,\n ];\n}\n\nfunction wrapSinglePathSync<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n options: {\n mapResult?: (inputPath: string, result: ReturnType<Fn>) => ReturnType<Fn>;\n } = {},\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n const result = original(\n ...([mappedPath, ...args.slice(1)] as Parameters<Fn>),\n ) as ReturnType<Fn>;\n return options.mapResult\n ? options.mapResult(inputPath, result)\n : result;\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapRenameSync<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [sourcePath, destinationPath] = args;\n if (typeof sourcePath === 'string' && typeof destinationPath === 'string') {\n const mappedPaths = mapRenamePaths(sourcePath, destinationPath);\n if (mappedPaths) {\n return original(\n ...([\n mappedPaths[0],\n mappedPaths[1],\n ...args.slice(2),\n ] as Parameters<Fn>),\n );\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapSinglePathCallback<Fn extends (...args: never[]) => unknown>(\n original: Fn,\n options: {\n mapCallbackResult?: (inputPath: string, result: unknown) => unknown;\n } = {},\n): Fn {\n return ((...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n const nextArgs = [mappedPath, ...args.slice(1)] as unknown[];\n const maybeCallback = nextArgs.at(-1);\n if (options.mapCallbackResult && typeof maybeCallback === 'function') {\n nextArgs[nextArgs.length - 1] = (\n error: NodeJS.ErrnoException | null,\n result: unknown,\n ...rest: unknown[]\n ) => {\n const mappedResult = error\n ? result\n : options.mapCallbackResult?.(inputPath, result);\n (maybeCallback as (...callbackArgs: unknown[]) => void)(\n error,\n mappedResult,\n ...rest,\n );\n };\n }\n return original(...(nextArgs as Parameters<Fn>));\n }\n }\n return original(...args);\n }) as Fn;\n}\n\nfunction wrapSinglePathPromise<\n Fn extends (...args: never[]) => Promise<unknown>,\n>(original: Fn): Fn {\n return (async (...args: Parameters<Fn>) => {\n const [inputPath] = args;\n if (typeof inputPath === 'string') {\n const mappedPath = mapToBackingPath(inputPath);\n if (mappedPath) {\n return await original(\n ...([mappedPath, ...args.slice(1)] as Parameters<Fn>),\n );\n }\n }\n return await original(...args);\n }) as Fn;\n}\n\nfunction createWrappedRealpathSync(): WrappedRealpathSync {\n const wrapped = wrapSinglePathSync(originalFsSyncMethods.realpathSync, {\n mapResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n }) as WrappedRealpathSync;\n\n if (originalFsSyncMethods.realpathSync.native) {\n wrapped.native = wrapSinglePathSync(\n originalFsSyncMethods.realpathSync.native,\n {\n mapResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n },\n ) as typeof fs.realpathSync.native;\n }\n\n return wrapped;\n}\n\nconst wrappedFsSyncMethods = {\n existsSync: wrapSinglePathSync(originalFsSyncMethods.existsSync),\n mkdirSync: wrapSinglePathSync(originalFsSyncMethods.mkdirSync),\n openSync: wrapSinglePathSync(originalFsSyncMethods.openSync),\n readFileSync: wrapSinglePathSync(originalFsSyncMethods.readFileSync),\n readdirSync: wrapSinglePathSync(originalFsSyncMethods.readdirSync),\n realpathSync: createWrappedRealpathSync(),\n renameSync: wrapRenameSync(originalFsSyncMethods.renameSync),\n rmSync: wrapSinglePathSync(originalFsSyncMethods.rmSync),\n statSync: wrapSinglePathSync(originalFsSyncMethods.statSync),\n writeFileSync: wrapSinglePathSync(originalFsSyncMethods.writeFileSync),\n};\n\nconst wrappedFsCallbackMethods = {\n mkdir: wrapSinglePathCallback(originalFsCallbackMethods.mkdir),\n realpath: wrapSinglePathCallback(originalFsCallbackMethods.realpath, {\n mapCallbackResult: (inputPath, result) =>\n typeof result === 'string'\n ? mapRealpathResult(inputPath, result)\n : result,\n }),\n rmdir: wrapSinglePathCallback(originalFsCallbackMethods.rmdir),\n stat: wrapSinglePathCallback(originalFsCallbackMethods.stat),\n utimes: wrapSinglePathCallback(originalFsCallbackMethods.utimes),\n writeFile: wrapSinglePathCallback(originalFsCallbackMethods.writeFile),\n};\n\nconst wrappedFsPromises = {\n mkdir: wrapSinglePathPromise(originalFsPromises.mkdir),\n readFile: wrapSinglePathPromise(originalFsPromises.readFile),\n writeFile: wrapSinglePathPromise(originalFsPromises.writeFile),\n};\n\nfunction areExtraFsPatchesInstalled(): boolean {\n return mutableFs.existsSync === wrappedFsSyncMethods.existsSync;\n}\n\nfunction installExtraFsPatches() {\n if (areExtraFsPatchesInstalled()) return;\n\n mutableFs.existsSync = wrappedFsSyncMethods.existsSync;\n mutableFs.mkdirSync = wrappedFsSyncMethods.mkdirSync;\n mutableFs.openSync = wrappedFsSyncMethods.openSync;\n mutableFs.readFileSync = wrappedFsSyncMethods.readFileSync;\n mutableFs.readdirSync = wrappedFsSyncMethods.readdirSync;\n mutableFs.realpathSync = wrappedFsSyncMethods.realpathSync;\n mutableFs.renameSync = wrappedFsSyncMethods.renameSync;\n mutableFs.rmSync = wrappedFsSyncMethods.rmSync;\n mutableFs.statSync = wrappedFsSyncMethods.statSync;\n mutableFs.writeFileSync = wrappedFsSyncMethods.writeFileSync;\n\n mutableFs.mkdir = wrappedFsCallbackMethods.mkdir;\n mutableFs.realpath = wrappedFsCallbackMethods.realpath;\n mutableFs.rmdir = wrappedFsCallbackMethods.rmdir;\n mutableFs.stat = wrappedFsCallbackMethods.stat;\n mutableFs.utimes = wrappedFsCallbackMethods.utimes;\n mutableFs.writeFile = wrappedFsCallbackMethods.writeFile;\n\n mutableFsPromises.mkdir = wrappedFsPromises.mkdir;\n mutableFsPromises.readFile = wrappedFsPromises.readFile;\n mutableFsPromises.writeFile = wrappedFsPromises.writeFile;\n\n syncBuiltinESMExports();\n}\n\nfunction restoreExtraFsPatches() {\n if (!areExtraFsPatchesInstalled()) return;\n\n mutableFs.existsSync = originalFsSyncMethods.existsSync;\n mutableFs.mkdirSync = originalFsSyncMethods.mkdirSync;\n mutableFs.openSync = originalFsSyncMethods.openSync;\n mutableFs.readFileSync = originalFsSyncMethods.readFileSync;\n mutableFs.readdirSync = originalFsSyncMethods.readdirSync;\n mutableFs.realpathSync = originalFsSyncMethods.realpathSync;\n mutableFs.renameSync = originalFsSyncMethods.renameSync;\n mutableFs.rmSync = originalFsSyncMethods.rmSync;\n mutableFs.statSync = originalFsSyncMethods.statSync;\n mutableFs.writeFileSync = originalFsSyncMethods.writeFileSync;\n\n mutableFs.mkdir = originalFsCallbackMethods.mkdir;\n mutableFs.realpath = originalFsCallbackMethods.realpath;\n mutableFs.rmdir = originalFsCallbackMethods.rmdir;\n mutableFs.stat = originalFsCallbackMethods.stat;\n mutableFs.utimes = originalFsCallbackMethods.utimes;\n mutableFs.writeFile = originalFsCallbackMethods.writeFile;\n\n mutableFsPromises.mkdir = originalFsPromises.mkdir;\n mutableFsPromises.readFile = originalFsPromises.readFile;\n mutableFsPromises.writeFile = originalFsPromises.writeFile;\n\n syncBuiltinESMExports();\n}\n\nexport class PiWorkspaceVfs {\n private backingRoot: string | null = null;\n private mountPoint: string | null = null;\n\n private disposeMount(): void {\n if (this.mountPoint) {\n mountedRoots.delete(this.mountPoint);\n }\n this.backingRoot = null;\n this.mountPoint = null;\n }\n\n mount(backingRoot: string, mountPoint: string): void {\n if (this.backingRoot === backingRoot && this.mountPoint === mountPoint) {\n return;\n }\n\n const resolvedBackingRoot = path.resolve(backingRoot);\n const resolvedMountPoint = path.resolve(mountPoint);\n if (this.mountPoint) {\n this.disposeMount();\n }\n\n mountedRoots.set(resolvedMountPoint, {\n backingRoot: resolvedBackingRoot,\n mountPoint: resolvedMountPoint,\n });\n installExtraFsPatches();\n\n this.backingRoot = resolvedBackingRoot;\n this.mountPoint = resolvedMountPoint;\n }\n\n unmount(): void {\n this.disposeMount();\n\n if (mountedRoots.size === 0) {\n restoreExtraFsPatches();\n }\n }\n}\n","import {\n mkdir,\n readFile,\n readdir,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises';\nimport path from 'node:path';\nimport { shellQuote } from '@ai-sdk/harness/utils';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\n\n/*\n * Pi runs on the host with its working directory pointed at the local mirror,\n * but the only thing it reads from that directory is its own resource\n * configuration: the `.pi` and `.agents` directories (skills, prompts, themes,\n * extensions) and the root-level agent context files (`AGENTS.md`). The model\n * never reads workspace source through the host — file reads, directory\n * listings, and greps all run as tools against the sandbox. Mirroring the whole\n * sandbox workspace to the host would therefore copy files Pi never looks at,\n * one `readBinaryFile` round-trip per file. For a real project that has been\n * cloned and had its dependencies installed (hundreds of thousands of files\n * under `node_modules`) that makes session startup take hours. The mirror is\n * consequently scoped to exactly the paths Pi's resource loader consults.\n *\n * Within those config directories, symlinks are resolved and their targets\n * copied as real files. `.agents/skills` is frequently a symlink to a `skills`\n * directory living elsewhere in the workspace; a mirrored symlink would dangle\n * because its target falls outside the scoped mirror, so the linked content is\n * walked and copied verbatim instead.\n */\nconst PI_CONFIG_DIRS = ['.pi', '.agents'] as const;\nconst PI_CONTEXT_FILENAMES = ['AGENTS.md', 'AGENTS.MD'] as const;\n\nfunction normalizeRelativePath(inputPath: string): string {\n const normalized = inputPath.split(path.posix.sep).join(path.sep);\n const relative = path.normalize(normalized);\n if (\n relative === '' ||\n relative === '.' ||\n path.isAbsolute(relative) ||\n relative === '..' ||\n relative.startsWith(`..${path.sep}`)\n ) {\n throw new Error(\n `Sandbox workspace mirror received an invalid relative path: ${inputPath}`,\n );\n }\n return relative;\n}\n\nasync function readCommandOutput(\n sandbox: Experimental_SandboxSession,\n command: string,\n): Promise<string> {\n const result = await sandbox.run({ command });\n if (result.exitCode != null && result.exitCode !== 0) {\n throw new Error(\n result.stderr ||\n result.stdout ||\n `Sandbox command failed with exit code ${result.exitCode}`,\n );\n }\n return result.stdout || result.stderr;\n}\n\nasync function listRemoteWorkspaceEntries(\n sandbox: Experimental_SandboxSession,\n sandboxWorkDir: string,\n): Promise<{\n directories: string[];\n files: Array<{ relativePath: string; sandboxPath: string }>;\n}> {\n // Enumerate only the `.pi`/`.agents` config subtrees plus the root-level\n // context files — never the rest of the workspace. Use shell glob traversal\n // instead of `find -L`, which is not supported by all sandbox shells.\n // Resolve each scoped root path component explicitly with `readlink`,\n // retaining both the scoped mirror path and the resolved sandbox path. Once\n // a root is resolved, queued descendants use physical parent paths and only\n // need resolution when the descendant itself is a symlink. This avoids\n // relying on shells that can inspect a symlinked directory but cannot\n // traverse paths below it, including when the symlink is an ancestor of the\n // sandbox work directory, without repeatedly resolving every component of\n // deep ordinary paths.\n const scopedPaths = [\n ...PI_CONFIG_DIRS.map(dir => `./${dir}`),\n ...PI_CONTEXT_FILENAMES.map(name => `./${name}`),\n ];\n const listCommand = [\n `pi_config_sources=(${scopedPaths\n .map(scopedPath =>\n shellQuote(path.posix.join(sandboxWorkDir, scopedPath.slice(2))),\n )\n .join(' ')})`,\n `pi_config_relatives=(${scopedPaths\n .map(scopedPath => shellQuote(scopedPath.slice(2)))\n .join(' ')})`,\n `pi_config_ancestors=(${scopedPaths.map(() => \"''\").join(' ')})`,\n `pi_config_resolve_ancestors=(${scopedPaths.map(() => '1').join(' ')})`,\n 'pi_config_index=0',\n 'while [ \"$pi_config_index\" -lt \"${#pi_config_sources[@]}\" ]; do',\n ' source=${pi_config_sources[$pi_config_index]}',\n ' relative=${pi_config_relatives[$pi_config_index]}',\n ' ancestors=${pi_config_ancestors[$pi_config_index]}',\n ' resolve_ancestors=${pi_config_resolve_ancestors[$pi_config_index]}',\n ' pi_config_index=$((pi_config_index + 1))',\n ' if [ \"$resolve_ancestors\" = 1 ] || [ -L \"$source\" ]; then',\n ' pending=$source',\n ' resolved=',\n ' seen_links=',\n ' case \"$pending\" in',\n ' /*) ;;',\n ' *) pending=$PWD/$pending ;;',\n ' esac',\n ' while [ -n \"$pending\" ]; do',\n ' pending=${pending#/}',\n ' [ -n \"$pending\" ] || break',\n ' component=${pending%%/*}',\n ' if [ \"$pending\" = \"$component\" ]; then',\n ' pending=',\n ' else',\n ' pending=${pending#*/}',\n ' fi',\n ' case \"$component\" in',\n ' \"\"|.) continue ;;',\n ' ..)',\n ' resolved=${resolved%/*}',\n ' continue',\n ' ;;',\n ' esac',\n ' candidate=$resolved/$component',\n ' if [ -L \"$candidate\" ]; then',\n ' case \"$seen_links\" in',\n ' *\"',\n '\"$candidate\"',\n '\"*)',\n ` printf 'Pi config traversal encountered a symlink cycle at %s\\\\n' \"$candidate\" >&2`,\n ' exit 1',\n ' ;;',\n ' esac',\n ' seen_links=$seen_links\"',\n '\"$candidate\"',\n '\"',\n ' target=$(readlink \"$candidate\") || exit $?',\n ' case \"$target\" in',\n ' /*) pending=$target${pending:+/$pending} ;;',\n ' *) pending=${candidate%/*}/$target${pending:+/$pending} ;;',\n ' esac',\n ' resolved=',\n ' else',\n ' resolved=$candidate',\n ' fi',\n ' done',\n ' if [ -z \"$resolved\" ]; then',\n ` printf 'Pi config traversal resolved %s to the filesystem root; skipping\\\\n' \"$relative\" >&2`,\n ' continue',\n ' fi',\n ' source=$resolved',\n ' fi',\n ' if [ -d \"$source\" ]; then',\n ' case \"$ancestors\" in',\n ' *\"',\n '\"$source\"',\n '\"*)',\n ` printf 'Pi config traversal encountered a symlink cycle at %s\\\\n' \"$relative\" >&2`,\n ' exit 1',\n ' ;;',\n ' esac',\n ' ancestors=$ancestors\"',\n '\"$source\"',\n '\"',\n ` printf 'd\\\\t%s\\\\n' \"$relative\"`,\n ' for child in \"$source\"/* \"$source\"/.[!.]* \"$source\"/..?*; do',\n ' if [ -L \"$child\" ] || [ -d \"$child\" ] || [ -f \"$child\" ]; then',\n ' child_name=${child##*/}',\n ' pi_config_sources+=(\"$child\")',\n ' pi_config_relatives+=(\"$relative/$child_name\")',\n ' pi_config_ancestors+=(\"$ancestors\")',\n ' pi_config_resolve_ancestors+=(0)',\n ' fi',\n ' done',\n ' elif [ -f \"$source\" ]; then',\n ` printf 'f\\\\t%s\\\\t%s\\\\n' \"$relative\" \"$source\"`,\n ' fi',\n ' true',\n 'done',\n 'true',\n ].join('\\n');\n\n const output = await readCommandOutput(\n sandbox,\n [`cd ${shellQuote(sandboxWorkDir)}`, listCommand].join(' && '),\n );\n\n const directories: string[] = [];\n const files: Array<{ relativePath: string; sandboxPath: string }> = [];\n\n for (const line of output.split('\\n').filter(Boolean)) {\n const [kind, rawPath, sandboxPath] = line.split('\\t', 3);\n if (!rawPath) continue;\n\n const relativePath = normalizeRelativePath(rawPath);\n if (kind === 'd') directories.push(relativePath);\n else if (kind === 'f' && sandboxPath) {\n files.push({ relativePath, sandboxPath });\n }\n }\n\n return { directories, files };\n}\n\nasync function pathKind(\n target: string,\n): Promise<'file' | 'directory' | undefined> {\n try {\n const stats = await stat(target);\n if (stats.isDirectory()) return 'directory';\n if (stats.isFile()) return 'file';\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function collectHostSubtree(\n rootDir: string,\n currentDir: string,\n directories: string[],\n files: string[],\n): Promise<void> {\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) continue;\n const absolutePath = path.join(currentDir, entry.name);\n const relativePath = path.relative(rootDir, absolutePath);\n if (entry.isDirectory()) {\n directories.push(relativePath);\n await collectHostSubtree(rootDir, absolutePath, directories, files);\n } else if (entry.isFile()) {\n files.push(relativePath);\n }\n }\n}\n\n/**\n * Enumerate the locally-mirrored entries that fall within Pi's scope: the\n * `.pi`/`.agents` config subtrees and the root-level context files. Anything\n * else on the local side (it should not normally exist) is intentionally\n * ignored so the reconcile below neither copies nor deletes it.\n */\nasync function collectHostScopedEntries(\n rootDir: string,\n): Promise<{ directories: string[]; files: string[] }> {\n const directories: string[] = [];\n const files: string[] = [];\n\n for (const dir of PI_CONFIG_DIRS) {\n const configDir = path.join(rootDir, dir);\n if ((await pathKind(configDir)) === 'directory') {\n directories.push(dir);\n await collectHostSubtree(rootDir, configDir, directories, files);\n }\n }\n\n for (const name of PI_CONTEXT_FILENAMES) {\n if ((await pathKind(path.join(rootDir, name))) === 'file') {\n files.push(name);\n }\n }\n\n return { directories, files };\n}\n\nfunction buildRequiredDirectories(\n remoteDirectories: string[],\n remoteFiles: Array<{ relativePath: string }>,\n): Set<string> {\n const directories = new Set<string>();\n for (const directory of remoteDirectories) {\n directories.add(normalizeRelativePath(directory));\n }\n for (const file of remoteFiles) {\n let current = path.dirname(normalizeRelativePath(file.relativePath));\n while (current !== '.' && current !== path.sep && current.length > 0) {\n directories.add(current);\n current = path.dirname(current);\n }\n }\n return directories;\n}\n\nexport async function syncHostWorkspaceFromSandbox(args: {\n sandbox: Experimental_SandboxSession;\n sandboxWorkDir: string;\n hostWorkDir: string;\n}): Promise<void> {\n const { sandbox, sandboxWorkDir, hostWorkDir } = args;\n const remoteEntries = await listRemoteWorkspaceEntries(\n sandbox,\n sandboxWorkDir,\n );\n const hostEntries = await collectHostScopedEntries(hostWorkDir);\n const remoteFiles = new Set(\n remoteEntries.files.map(file => file.relativePath),\n );\n const requiredDirectories = buildRequiredDirectories(\n remoteEntries.directories,\n remoteEntries.files,\n );\n\n for (const relativePath of hostEntries.files) {\n if (!remoteFiles.has(relativePath)) {\n await rm(path.join(hostWorkDir, relativePath), { force: true });\n }\n }\n\n const removableDirectories = [...hostEntries.directories]\n .filter(p => !requiredDirectories.has(p))\n .sort((a, b) => b.length - a.length);\n for (const relativePath of removableDirectories) {\n await rm(path.join(hostWorkDir, relativePath), {\n recursive: true,\n force: true,\n });\n }\n\n for (const relativePath of [...requiredDirectories].sort(\n (a, b) => a.length - b.length,\n )) {\n await mkdir(path.join(hostWorkDir, relativePath), { recursive: true });\n }\n\n for (const { relativePath, sandboxPath } of remoteEntries.files) {\n const bytes = await sandbox.readBinaryFile({ path: sandboxPath });\n if (!bytes) {\n throw new Error(\n `Sandbox workspace file disappeared during mirror sync: ${sandboxPath}`,\n );\n }\n const content = Buffer.from(bytes);\n\n const hostPath = path.join(hostWorkDir, relativePath);\n let shouldWrite = true;\n try {\n const existing = await readFile(hostPath);\n shouldWrite = !existing.equals(content);\n } catch {\n shouldWrite = true;\n }\n\n if (shouldWrite) {\n await mkdir(path.dirname(hostPath), { recursive: true });\n await writeFile(hostPath, content);\n }\n }\n}\n\nexport async function writeHostWorkspaceFile(\n hostWorkDir: string,\n relativePath: string,\n content: Buffer,\n): Promise<void> {\n const normalizedPath = normalizeRelativePath(relativePath);\n const hostPath = path.join(hostWorkDir, normalizedPath);\n await mkdir(path.dirname(hostPath), { recursive: true });\n await writeFile(hostPath, content);\n}\n","import { createPi } from './pi-harness';\n\n/**\n * Default `pi` harness instance with no overrides — suitable for the common\n * case where Pi's defaults are fine. Equivalent to `createPi()`.\n */\nexport const pi = createPi();\n\nexport { createPi } from './pi-harness';\nexport { VERSION } from './version';\nexport type { PiHarnessSettings } from './pi-harness';\nexport type { PiAuthenticationMode, PiAuthOptions } from './pi-auth';\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAGK;AACP,SAAS,YAAY;AAErB,SAAS,KAAAA,UAAS;;;ACPlB,SAAS,kBAAkB;AAC3B,SAAS,UAAU,WAAW,aAAa;AAC3C,OAAO,UAAU;AAEjB,SAAS,SAAS;AAElB,IAAM,+BAA+B;AAE9B,SAAS,sBAAsB,iBAAiC;AACrE,MAAI,CAAC,6BAA6B,KAAK,eAAe,GAAG;AACvD,UAAM,IAAI,MAAM,iCAAiC,eAAe,EAAE;AAAA,EACpE;AACA,SAAO;AACT;AAEA,IAAM,0BAA0B,EAC7B,OAAO,EACP;AAAA,EACC,qBAAmB,6BAA6B,KAAK,eAAe;AAAA,EACpE;AACF;AASK,IAAM,sBAAsB,EAAE,YAAY;AAAA,EAC/C,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAIM,SAAS,iCAAiC,OAItC;AACT,QAAM,aAAa,WAAW,QAAQ,EAAE,OAAO,MAAM,SAAS,EAAE,OAAO,KAAK;AAC5E,QAAM,oBAAoB,KAAK,MAAM;AAAA,IACnC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,eAAe,KAAK,MAAM;AAAA,IAC9B,MAAM;AAAA,IACN;AAAA,EACF;AACA,MACE,iBAAiB,MAChB,CAAC,aAAa,WAAW,KAAK,KAAK,CAAC,KAAK,MAAM,WAAW,YAAY,GACvE;AACA,UAAM,IAAI;AAAA,MACR,gCAAgC,KAAK,UAAU,iBAAiB,CAAC,mCAAmC,KAAK,UAAU,MAAM,cAAc,CAAC;AAAA,IAC1I;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAGvB;AACT,QAAM,UAAU,KAAK,QAAQ,MAAM,OAAO;AAC1C,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,IACA,sBAAsB,MAAM,eAAe;AAAA,EAC7C;AACA,QAAM,eAAe,KAAK,SAAS,SAAS,QAAQ;AACpD,MACE,iBAAiB,MACjB,aAAa,WAAW,IAAI,KAC5B,KAAK,WAAW,YAAY,GAC5B;AACA,UAAM,IAAI,MAAM,iCAAiC,MAAM,eAAe,EAAE;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,4BAA4B,OAG1B;AACT,QAAM,aAAa,KAAK,MAAM,QAAQ,MAAM,iBAAiB;AAC7D,QAAM,WAAW,KAAK,MAAM;AAAA,IAC1B;AAAA,IACA,sBAAsB,MAAM,eAAe;AAAA,EAC7C;AACA,QAAM,eAAe,KAAK,MAAM,SAAS,YAAY,QAAQ;AAC7D,MACE,iBAAiB,MACjB,aAAa,WAAW,IAAI,KAC5B,KAAK,MAAM,WAAW,YAAY,GAClC;AACA,UAAM,IAAI,MAAM,iCAAiC,MAAM,eAAe,EAAE;AAAA,EAC1E;AACA,SAAO;AACT;AAOA,eAAsB,4BAA4B,MAMhC;AAChB,QAAM,WAAW,yBAAyB;AAAA,IACxC,SAAS,KAAK;AAAA,IACd,iBAAiB,KAAK;AAAA,EACxB,CAAC;AACD,QAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,QAAM,aAAa,4BAA4B;AAAA,IAC7C,mBAAmB,KAAK;AAAA,IACxB,iBAAiB,KAAK;AAAA,EACxB,CAAC;AACD,QAAM,KAAK,QAAQ,gBAAgB;AAAA,IACjC,MAAM;AAAA,IACN;AAAA,IACA,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,EAC9D,CAAC;AACH;AAQA,eAAsB,2BAA2B,MAMjB;AAC9B,QAAM,aAAa,4BAA4B;AAAA,IAC7C,mBAAmB,KAAK;AAAA,IACxB,iBAAiB,KAAK;AAAA,EACxB,CAAC;AACD,QAAM,QAAQ,MAAM,KAAK,QAAQ,eAAe;AAAA,IAC9C,MAAM;AAAA,IACN,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,EAC9D,CAAC;AACD,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,MAAM,KAAK,gBAAgB,EAAE,WAAW,KAAK,CAAC;AACpD,QAAM,WAAW,yBAAyB;AAAA,IACxC,SAAS,KAAK;AAAA,IACd,iBAAiB,KAAK;AAAA,EACxB,CAAC;AACD,QAAM,UAAU,UAAU,KAAK;AAC/B,SAAO;AACT;;;AC/JA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP,SAAS,SAAAC,QAAO,MAAAC,WAAU;AAC1B,SAAS,cAAc;AACvB,OAAOC,WAAU;AACjB,SAAS,QAAAC,aAAY;AACrB;AAAA,EACE,qCAAAC;AAAA,OAaK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;AChCP,SAAS,+BAA+B;;;ACFjC,IAAM,UACX,OACI,WACA;;;ADsCN,IAAM,2BAA2B;AACjC,IAAM,0BAA0B;AAChC,IAAM,6BAA6B;AACnC,IAAM,qBAAqB,qBAAqB,OAAO;AAEvD,SAAS,4BAA4B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,GAIwB;AACtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,cAAc;AAAA,MACd,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAOA,eAAe,SAAS;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKkB;AAChB,aAAW,cAAc,iBAAiB,UAAU,MAAM;AAC1D,QAAM,WAAW,aAAa,iBAAiB,UAAU,MAAM;AACjE;AAEA,SAAS,mBAAmB,OAAyB;AACnD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,SAAS;AACrD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,OAAO,OAAO,KAAK,EAAE,KAAK,kBAAkB;AACrD;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AACF,GAG2B;AACzB,QAAM,oBAAoB,4BAA4B,OAAO;AAC7D,QAAM,sBAAsB,mBAAmB,mBAAmB,SAAS;AAC3E,MAAI,qBAAqB;AACvB,WAAO,iBAAiB,EAAE,WAAW,kBAAmB,aAAa,CAAC,EAAE,CAAC;AAAA,EAC3E;AAEA,QAAM,oBAAoB,mBAAmB,mBAAmB,OAAO;AACvE,QAAM,qBAAqB,wBAAwB,EAAE,IAAI,CAAC;AAC1D,MAAI,mBAAmB;AACrB,UAAM,SACJ,kBAAmB,SAAS,UAAU,mBAAmB;AAC3D,UAAM,UACJ,kBAAmB,SAAS,WAAW,mBAAmB;AAC5D,QAAI,QAAQ;AACV,aAAO,EAAE,oBAAoB,QAAQ,qBAAqB,QAAQ;AAAA,IACpE;AACA,WAAO,CAAC;AAAA,EACV;AAGA,MAAI,OAAO,YAAY,UAAU;AAC/B,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,YAAI,IAAI,gBAAgB;AACtB,iBAAO;AAAA,YACL,gBAAgB,IAAI;AAAA,YACpB,GAAI,IAAI,kBACJ,EAAE,iBAAiB,IAAI,gBAAgB,IACvC,CAAC;AAAA,UACP;AAAA,QACF;AACA,eAAO,CAAC;AAAA,MACV,KAAK;AACH,YAAI,IAAI,mBAAmB;AACzB,iBAAO;AAAA,YACL,mBAAmB,IAAI;AAAA,YACvB,GAAI,IAAI,qBACJ,EAAE,oBAAoB,IAAI,mBAAmB,IAC7C,CAAC;AAAA,YACL,GAAI,IAAI,uBACJ,EAAE,sBAAsB,IAAI,qBAAqB,IACjD,CAAC;AAAA,UACP;AAAA,QACF;AACA,eAAO,CAAC;AAAA,MACV,KAAK,UAAU;AACb,cAAM,SAAiC,CAAC;AACxC,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,cACE,UACC,IAAI,SAAS,UAAU,KACtB,IAAI,SAAS,WAAW,KACxB,QAAQ,yBACV;AACA,mBAAO,GAAG,IAAI;AAAA,UAChB;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK;AACH,YAAI,mBAAmB,QAAQ;AAC7B,iBAAO;AAAA,YACL,oBAAoB,mBAAmB;AAAA,YACvC,qBAAqB,mBAAmB;AAAA,UAC1C;AAAA,QACF;AACA,eAAO,CAAC;AAAA,MACV,KAAK;AAAA,MACL;AACE;AAAA,IACJ;AAAA,EACF;AAGA,MAAI,mBAAmB,QAAQ;AAC7B,WAAO;AAAA,MACL,oBAAoB,mBAAmB;AAAA,MACvC,qBAAqB,mBAAmB;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,QACE,UACC,IAAI,SAAS,UAAU,KACtB,IAAI,SAAS,WAAW,KACxB,QAAQ,yBACV;AACA,cAAQ,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,oBAAoB;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAKkB;AAChB,QAAM,oBAAoB,4BAA4B,OAAO;AAC7D,MAAI,mBAAmB,mBAAmB,SAAS,GAAG;AACpD,UAAM,wBAAwB;AAAA,MAC5B,WAAW,kBAAmB,aAAa,CAAC;AAAA,MAC5C;AAAA,MACA;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAKA,QAAM,OACJ,OAAO,YAAY,WAAW,UAAU,WAAW,OAAO,SAAS;AAErE,UAAQ,MAAM;AAAA,IACZ,KAAK,UAAU;AACb,YAAM,MAAM,cAAc,WAAW;AACrC,YAAM,wBAAwB;AAAA,QAC5B,WAAW,EAAE,GAAG,cAAc,QAAQ,GAAG,GAAG,GAAG,IAAI;AAAA,QACnD;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,MAAM,iBAAiB,WAAW;AACxC,YAAM,wBAAwB;AAAA,QAC5B,WAAW,EAAE,GAAG,iBAAiB,QAAQ,GAAG,GAAG,GAAG,IAAI;AAAA,QACtD;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAEb,YAAM,MAAM,gBAAgB,WAAW;AACvC,YAAM,wBAAwB;AAAA,QAC5B,WAAW,EAAE,GAAG,gBAAgB,QAAQ,GAAG,GAAG,GAAG,IAAI;AAAA,QACrD;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,cAAc,wBAAwB,EAAE,KAAK,QAAQ,IAAI,CAAC;AAChE,YAAM,gBACJ,YAAY,sBAAsB,YAAY;AAChD,YAAM,iBACJ,YAAY,uBAAuB,YAAY;AACjD,UAAI,CAAC,cAAe;AACpB,YAAM,SAAS;AAAA,QACb;AAAA,QACA,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ,4BAA4B;AAAA,UAClC,QAAQ;AAAA,UACR,SAAS;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK;AACH;AAAA;AAAA,IACF,KAAK;AAAA,IACL,SAAS;AAGP,YAAM,cAAc,wBAAwB,EAAE,KAAK,QAAQ,IAAI,CAAC;AAChE,YAAM,gBACJ,YAAY,sBAAsB,YAAY;AAChD,YAAM,iBACJ,YAAY,uBAAuB,YAAY;AACjD,UAAI,eAAe;AACjB,cAAM,SAAS;AAAA,UACb;AAAA,UACA,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,QAAQ,4BAA4B;AAAA,YAClC,QAAQ;AAAA,YACR,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AACD;AAAA,MACF;AACA,YAAM,MAAM,gBAAgB,WAAW;AACvC,YAAM,wBAAwB;AAAA,QAC5B,WAAW,EAAE,GAAG,gBAAgB,QAAQ,GAAG,GAAG,GAAG,IAAI;AAAA,QACrD;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,YAAY;AAC3B,QAAM,UAAU,YAAY;AAC5B,MAAI,CAAC,UAAU,CAAC,QAAS;AAEzB,QAAM,SAAS;AAAA,IACb;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,QAAQ,4BAA4B,EAAE,QAAQ,SAAS,UAAU,CAAC;AAAA,EACpE,CAAC;AACH;AAEA,SAAS,cACP,KACwB;AACxB,QAAM,SAAiC,CAAC;AACxC,MAAI,IAAI,eAAgB,QAAO,iBAAiB,IAAI;AACpD,MAAI,IAAI,gBAAiB,QAAO,kBAAkB,IAAI;AACtD,SAAO;AACT;AAEA,SAAS,iBACP,KACwB;AACxB,QAAM,SAAiC,CAAC;AACxC,MAAI,IAAI,kBAAmB,QAAO,oBAAoB,IAAI;AAC1D,MAAI,IAAI;AACN,WAAO,qBAAqB,IAAI;AAClC,MAAI,IAAI;AACN,WAAO,uBAAuB,IAAI;AACpC,SAAO;AACT;AASA,SAAS,gBACP,KACwB;AACxB,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,QACE,UACC,IAAI,SAAS,UAAU,KACtB,IAAI,SAAS,WAAW,KACxB,QAAQ,yBACV;AACA,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,4BACP,SACiC;AACjC,MAAI,WAAW,QAAQ,YAAY,QAAQ;AACzC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,YAAY,UAAU;AAC/B,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO,EAAE,SAAS,CAAC,EAAE;AAAA,MACvB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,EAAE,WAAW,CAAC,EAAE;AAAA,MACzB;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB;AAAA,EACxB;AACF,GAE2B;AACzB,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,SAAO;AAAA,IACL,oBAAoB;AAAA,IACpB,qBACE,UAAU,uBAAuB;AAAA,EACrC;AACF;AAEA,eAAe,wBAAwB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAIkB;AAChB,QAAM,aAAa,UAAU;AAC7B,MAAI,YAAY;AACd,UAAM,UAAU,UAAU,uBAAuB;AACjD,UAAM,SAAS;AAAA,MACb;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ,4BAA4B;AAAA,QAClC,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,gBAAgB;AAC5B,UAAM,UAAU,UAAU,mBAAmB;AAC7C,UAAM,SAAS;AAAA,MACb;AAAA,MACA,UAAU;AAAA,MACV,QAAQ,UAAU;AAAA,MAClB,QAAQ;AAAA,QACN,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,mBAAmB;AAC/B,UAAM,UAAU,UAAU,sBAAsB;AAChD,UAAM,SAAS;AAAA,MACb;AAAA,MACA,UAAU;AAAA,MACV,QAAQ,UAAU;AAAA,MAClB,QAAQ;AAAA,QACN,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA,GAAI,UAAU,uBACV;AAAA,UACE,SAAS;AAAA,YACP,eAAe,UAAU,UAAU,oBAAoB;AAAA,UACzD;AAAA,QACF,IACA,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,SAAS,GAAG;AACtD,QAAI,CAAC,KAAK,SAAS,UAAU,KAAK,CAAC,QAAQ;AACzC;AAAA,IACF;AACA,UAAM,SAAS,KAAK,MAAM,GAAG,CAAC,WAAW,MAAM;AAC/C,QACE,WAAW,gBACX,WAAW,YACX,WAAW,aACX;AACA;AAAA,IACF;AACA,UAAM,WAAW,OAAO,YAAY,EAAE,QAAQ,MAAM,GAAG;AACvD,UAAM,UAAU,UAAU,GAAG,MAAM,WAAW;AAC9C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AE3eA,SAAS,KAAAC,UAAS;AAQX,IAAM,uBAAuBA,GAAE,YAAY;AAAA,EAChD,MAAMA,GAAE,OAAO;AAAA,EACf,uBAAuBA,GACpB,YAAY;AAAA,IACX,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,EACA,SAAS;AAAA,EACZ,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAChC,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,MAAMA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC3B,OAAOA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC5B,QAAQA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAI9B,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,OAAOA,GACJ,MAAM;AAAA,IACLA,GAAE,OAAO;AAAA,IACTA,GAAE,YAAY;AAAA,MACZ,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,MAClC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,IAClC,CAAC;AAAA,EACH,CAAC,EACA,SAAS;AAAA,EACZ,SAASA,GACN,YAAY;AAAA,IACX,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,IAC9B,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,IAChC,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,EACpC,CAAC,EACA,SAAS;AACd,CAAC;AAQM,SAAS,iBAAiB,KAA0C;AACzE,QAAM,SAAS,qBAAqB,UAAU,GAAG;AACjD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AAOO,SAAS,mBAAmB,OAA2C;AAC5E,QAAM,uBAAuB,CAAC,UAC5B,UAAU,WAAW,UAAU;AAEjC,MAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,GAAG;AACzD,WAAO,MAAM,MAAM,KAAK;AAAA,EAC1B;AAEA,MAAI,MAAM,SAAS,OAAO,MAAM,UAAU,UAAU;AAClD,UAAM,eAAe,MAAM,MAAM,cAAc,KAAK;AACpD,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AACA,UAAM,aAAa,MAAM,MAAM,YAAY,KAAK;AAChD,QAAI,qBAAqB,UAAU,GAAG;AACpC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,SAAS,cAAc,KAAK;AACvD,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,MAAM,SAAS,YAAY,KAAK;AAC1D,MAAI,qBAAqB,iBAAiB,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,MACE,MAAM,WACN,OAAO,MAAM,YAAY,YACzB,MAAM,QAAQ,KAAK,GACnB;AACA,WAAO,MAAM,QAAQ,KAAK;AAAA,EAC5B;AAEA,SAAO;AACT;AAGO,SAAS,qBACd,SACQ;AACR,MAAI,CAAC,WAAW,QAAQ,SAAS,aAAa;AAC5C,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,QACZ,QAAQ,UAAQ;AACf,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,cAAc;AACpB,WAAO,YAAY,SAAS,UAAU,OAAO,YAAY,SAAS,WAC9D,CAAC,YAAY,IAAI,IACjB,CAAC;AAAA,EACP,CAAC,EACA,KAAK,EAAE;AACZ;;;ACjIA,SAAS,2BAAAC,gCAA+B;AAUjC,IAAM,8BAA8B;AAY3C,IAAM,kBAAkB,CACtB,aACA,WACwB;AACxB,QAAM,aAAa,YAAY,QAAQ,GAAG;AAC1C,MAAI,eAAe,GAAI,QAAO;AAE9B,QAAM,SAAS,YAAY,MAAM,GAAG,UAAU;AAC9C,QAAM,SAAS,YAAY,MAAM,aAAa,CAAC;AAC/C,SAAO,OAAO;AAAA,IACZ,OAAK,EAAE,aAAa,WAAW,EAAE,OAAO,UAAU,EAAE,SAAS;AAAA,EAC/D;AACF;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,MAAM,QAAQ;AAChB,GAGG;AACD,MAAI;AAEJ,QAAM,aAAa,MAAiB;AAClC,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AACA,QAAI;AACF,qBAAe,cAAc,OAAO;AAAA,IACtC,QAAQ;AACN,qBAAe,CAAC;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,YAAqD;AAC3D,UAAM,aAAa,QAAQA,yBAAwB,EAAE,IAAI,CAAC,EAAE,MAAM;AAClE,UAAM,cACJ,YAAY,aAAa,8BAA8B;AACzD,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,SAAS,WAAW;AAC1B,UAAM,UAAU,CAAC,MACf,EAAE,OAAO,eAAe,EAAE,SAAS;AAOrC,UAAM,eAAe,aACjB,OAAO,KAAK,OAAK,EAAE,aAAa,uBAAuB,QAAQ,CAAC,CAAC,IACjE;AACJ,QAAI,aAAc,QAAO;AAEzB,UAAM,cAAc,gBAAgB,aAAa,MAAM;AACvD,QAAI,eAAe,CAAC,cAAc,kBAAkB,WAAW,GAAG;AAChE,YAAM,2BAA2B,OAAO;AAAA,QACtC,OAAK,EAAE,OAAO,eAAe,cAAc,kBAAkB,CAAC;AAAA,MAChE;AACA,UAAI,yBAAyB,WAAW,GAAG;AACzC,eAAO,yBAAyB,CAAC;AAAA,MACnC;AAAA,IACF;AAEA,WAAO,eAAe,OAAO,KAAK,OAAO;AAAA,EAC3C;AACF;;;AC1FA,SAAS,oBAAoB;AAC7B,OAAOC,WAAU;AAuCjB,SAAS,aAAa,QAAgB,WAA4B;AAChE,QAAM,WAAWA,MAAK,SAAS,QAAQ,SAAS;AAChD,SACE,aAAa,MACZ,CAAC,SAAS,WAAW,IAAI,KAAK,CAACA,MAAK,WAAW,QAAQ;AAE5D;AAEA,SAAS,kBAAkB,QAAgB,WAA4B;AACrE,QAAM,WAAWA,MAAK,MAAM,SAAS,QAAQ,SAAS;AACtD,SACE,aAAa,MACZ,CAAC,SAAS,WAAW,IAAI,KAAK,CAACA,MAAK,MAAM,WAAW,QAAQ;AAElE;AAEA,SAAS,2BAA2B,WAA2B;AAC7D,MAAI;AACF,WAAO,aAAa,OAAO,SAAS;AAAA,EACtC,QAAQ;AACN,UAAM,SAASA,MAAK,QAAQ,SAAS;AACrC,QAAI,WAAW,WAAW;AACxB,aAAO;AAAA,IACT;AACA,WAAOA,MAAK;AAAA,MACV,2BAA2B,MAAM;AAAA,MACjCA,MAAK,SAAS,SAAS;AAAA,IACzB;AAAA,EACF;AACF;AAEO,SAAS,mBACd,SACc;AACd,QAAM,iBAAiBA,MAAK,QAAQ,QAAQ,WAAW;AACvD,QAAM,oBAAoBA,MAAK,MAAM,UAAU,QAAQ,cAAc;AACrE,QAAM,gBAAgB,2BAA2B,cAAc;AAC/D,QAAM,gBACJ,QAAQ,eAAe,IAAI,WAAS;AAAA,IAClC,YAAYA,MAAK,MAAM,UAAU,KAAK,UAAU;AAAA,EAClD,EAAE,KAAK,CAAC;AAEV,QAAM,6BAA6B,CAAC,cAA8B;AAChE,UAAM,kBAAkBA,MAAK,MAAM,UAAU,SAAS;AACtD,QAAI,CAAC,kBAAkB,mBAAmB,eAAe,GAAG;AAC1D,YAAM,IAAI,MAAM,kCAAkC,SAAS,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,EACT;AAEA,QAAM,4BAA4B,CAAC,cAA8B;AAC/D,UAAM,kBAAkBA,MAAK,MAAM,UAAU,SAAS;AACtD,QACE,CAAC,kBAAkB,mBAAmB,eAAe,KACrD,CAAC,cAAc;AAAA,MAAK,UAClB,kBAAkB,KAAK,YAAY,eAAe;AAAA,IACpD,GACA;AACA,YAAM,IAAI,MAAM,uCAAuC,SAAS,EAAE;AAAA,IACpE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,CAAC,cAA8B;AAC5D,QAAIA,MAAK,MAAM,WAAW,SAAS,GAAG;AACpC,YAAM,kBAAkBA,MAAK,MAAM,UAAU,SAAS;AACtD,UAAI;AACF,eAAO,2BAA2B,eAAe;AAAA,MACnD,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,eAAeA,MAAK,WAAW,SAAS,IAC1CA,MAAK,QAAQ,SAAS,IACtBA,MAAK,QAAQ,gBAAgB,SAAS;AAC1C,UAAM,wBAAwB,2BAA2B,YAAY;AACrE,QACE,CAAC,aAAa,gBAAgB,YAAY,KAC1C,CAAC,aAAa,eAAe,qBAAqB,GAClD;AACA,YAAM,IAAI,MAAM,kCAAkC,SAAS,EAAE;AAAA,IAC/D;AAEA,UAAM,WAAWA,MACd,SAAS,gBAAgB,YAAY,EACrC,MAAMA,MAAK,GAAG,EACd,KAAK,GAAG;AACX,WAAO,WACHA,MAAK,MAAM,KAAK,mBAAmB,QAAQ,IAC3C;AAAA,EACN;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,cAAc,WAAmB;AAC/B,aAAO,uBAAuB,SAAS;AAAA,IACzC;AAAA,IACA,sBAAsB,WAAmB;AACvC,UAAIA,MAAK,MAAM,WAAW,SAAS,GAAG;AACpC,cAAM,kBAAkBA,MAAK,MAAM,UAAU,SAAS;AACtD,YAAI;AACF,iBAAO,0BAA0B,eAAe;AAAA,QAClD,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,aAAO,uBAAuB,SAAS;AAAA,IACzC;AAAA,IACA,kBAAkB,WAAmB;AACnC,aAAO,2BAA2B,SAAS;AAAA,IAC7C;AAAA,IACA,0BAA0B,WAAmB;AAC3C,aAAO,0BAA0B,SAAS;AAAA,IAC5C;AAAA,IACA,eAAe,WAAmB;AAChC,YAAM,cAAcA,MAAK,MAAM,WAAW,SAAS,IAC/CA,MAAK,MAAM,UAAU,SAAS,IAC9BA,MAAK,MAAM;AAAA,QACT;AAAA,QACA,UAAU,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AAAA,MACpC;AACJ,YAAM,WAAWA,MAAK,MAAM,SAAS,mBAAmB,WAAW;AACnE,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AACF;;;ACxKA,OAAOC,WAAU;AACjB,SAAS,kBAAkB;AAkE3B,SAAS,eAAe,QAAoC;AAC1D,SAAO,OAAO,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE;AACzE;AAEO,SAAS,kBAAkB,SAA0C;AAC1E,QAAM,WAAW,OACf,SACA,QAAuB,CAAC,MACI;AAI5B,UAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI;AAAA,MACvC;AAAA,MACA,GAAI,MAAM,MACN,EAAE,kBAAkB,QAAQ,MAAM,cAAc,MAAM,GAAG,EAAE,IAC3D,CAAC;AAAA,MACL,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,MAC1C,GAAI,MAAM,SAAS,EAAE,aAAa,MAAM,OAAO,IAAI,CAAC;AAAA,IACtD,CAAC;AAED,UAAM,WAAW,GAAG,OAAO,MAAM,GAAG,OAAO,MAAM;AACjD,UAAM,SAAS,OAAO,KAAK,UAAU,MAAM;AAC3C,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,SAAS,MAAM;AAAA,IACvB;AAEA,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,6BAA6B,OACjC,YACA,cACoB;AACpB,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,UAAU,WAAW,UAAU,CAAC;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAEA,UAAM,SAAS,OAAO,OAAO,SAAS,MAAM;AAC5C,QAAI,OAAO,SAAS,2BAA2B,GAAG;AAChD,YAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE;AAAA,IAChD;AACA,QAAI,OAAO,SAAS,wBAAwB,KAAK,OAAO,aAAa,GAAG;AACtE,YAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,IACxD;AAEA,UAAM,eAAe,eAAe,OAAO,MAAM;AACjD,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,6BAA6B,OACjC,YACA,cAEA,QAAQ,MAAM;AAAA,IACZ,MAAM,2BAA2B,YAAY,SAAS;AAAA,EACxD;AAEF,QAAM,6BAA6B,OACjC,YACA,cACoB;AACpB,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,UAAU,WAAW,UAAU,CAAC;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAEA,UAAM,SAAS,OAAO,OAAO,SAAS,MAAM;AAC5C,QACE,OAAO,SAAS,2BAA2B,KAC3C,OAAO,SAAS,wBAAwB,KACxC,OAAO,aAAa,GACpB;AACA,YAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,IACxD;AAEA,UAAM,eAAe,eAAe,OAAO,MAAM;AACjD,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,IACxD;AACA,WAAO,QAAQ,MAAM,kBAAkB,YAAY;AAAA,EACrD;AAEA,QAAM,aAAa,OAAO,cAAuC;AAC/D,UAAM,aAAa,QAAQ,MAAM,sBAAsB,SAAS;AAChE,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,MAAM,QAAQ,QAAQ,eAAe;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AACD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE;AAAA,IAChD;AACA,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B;AAEA,QAAMC,aAAY,OAChB,WACA,YACkB;AAClB,UAAM,aAAa,QAAQ,MAAM,cAAc,SAAS;AACxD,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,UAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe;AAAA,MACpD,MAAM;AAAA,IACR,CAAC;AACD,UAAM,SAAS,YAAY,WAAWD,MAAK,MAAM,QAAQ,YAAY,CAAC,CAAC,EAAE;AACzE,UAAM,QAAQ,QAAQ,cAAc,EAAE,MAAM,cAAc,QAAQ,CAAC;AACnE,YAAQ;AAAA,MACN,WAAW,WAAW;AAAA,MACtB,QAAQ,MAAM,eAAe,YAAY;AAAA,MACzC,OAAO,KAAK,SAAS,MAAM;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,WAAW,OACf,WACA,SACA,YACoB;AACpB,UAAM,WAAW,MAAM,WAAW,SAAS,GAAG,SAAS,MAAM;AAC7D,UAAM,QAAQ,QAAQ,QAAQ,OAAO;AACrC,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,MAAM,oCAAoC,SAAS,EAAE;AAAA,IACjE;AACA,UAAM,UAAU,GAAG,QAAQ,MAAM,GAAG,KAAK,CAAC,GAAG,OAAO,GAAG,QAAQ;AAAA,MAC7D,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,UAAMC,WAAU,WAAW,OAAO;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,OACpB,YAAoB,KACpB,QAAgB,QACM;AACtB,UAAM,aAAa,QAAQ,MAAM,sBAAsB,SAAS;AAChE,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,aAAa,WAAW,YAAY,CAAC;AAAA,QACrC,aAAa,WAAW,YAAY,CAAC;AAAA,QACrC,MAAM,WAAW,YAAY,CAAC;AAAA,QAC9B;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAEA,UAAM,SAAS,OAAO,OAAO,SAAS,MAAM,EAAE,KAAK;AACnD,QAAI,OAAO,SAAS,qBAAqB,GAAG;AAC1C,YAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE;AAAA,IAChD;AACA,QAAI,OAAO,SAAS,mBAAmB,GAAG;AACxC,YAAM,IAAI,MAAM,oBAAoB,SAAS,EAAE;AAAA,IACjD;AAEA,WAAO,OACJ,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,UAAQ,KAAK,QAAQ,WAAW,EAAE,CAAC,EACvC;AAAA,MAAK,CAAC,MAAM,UACX,KAAK,YAAY,EAAE,cAAc,MAAM,YAAY,CAAC;AAAA,IACtD,EACC,MAAM,GAAG,KAAK;AAAA,EACnB;AAEA,QAAM,YAAY,OAChB,SACA,YAAoB,KACpB,QAAgB,QACM;AACtB,UAAM,aAAa,QAAQ,MAAM,sBAAsB,SAAS;AAChE,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,aAAa,WAAW,YAAY,CAAC;AAAA,QACrC,WAAW,WAAW,YAAY,CAAC,iBAAiB,WAAW,YAAY,CAAC,wCAAwC,WAAW,YAAY,CAAC;AAAA,MAC9I,EAAE,KAAK,IAAI;AAAA,IACb;AAEA,UAAM,SAAS,OAAO,OAAO,SAAS,MAAM,EAAE,KAAK;AACnD,QAAI,OAAO,SAAS,uBAAuB,GAAG;AAC5C,YAAM,IAAI,MAAM,mBAAmB,SAAS,EAAE;AAAA,IAChD;AAEA,UAAM,aAAa;AACnB,WAAO,OACJ,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,kBAAgB;AACnB,UAAI,iBAAiB,YAAY;AAC/B,eAAOD,MAAK,MAAM,SAAS,YAAY;AAAA,MACzC;AACA,aAAOA,MAAK,MAAM,SAAS,YAAY,YAAY;AAAA,IACrD,CAAC,EACA;AAAA,MACC,eACE,UAAU,SAAS,KAAKA,MAAK,YAAY,WAAW,OAAO;AAAA,IAC/D,EACC;AAAA,MAAK,CAAC,MAAM,UACX,KAAK,YAAY,EAAE,cAAc,MAAM,YAAY,CAAC;AAAA,IACtD,EACC,MAAM,GAAG,KAAK;AAAA,EACnB;AAEA,QAAM,YAAY,OAChB,SACA,UAQoB;AACpB,UAAM,aAAa,QAAQ,MAAM,sBAAsB,MAAM,QAAQ,GAAG;AACxE,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA,MAAM,QAAQ;AAAA,IAChB;AACA,UAAM,iBAAiB,QAAQ,MAAM,eAAe,YAAY;AAChE,UAAM,aACJ,eAAe,WAAW,KAAK,KAAKA,MAAK,MAAM,WAAW,cAAc,IACpE,eACA;AACN,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,MAAM,aAAa,CAAC,IAAI,IAAI,CAAC;AAAA,MACjC,GAAI,MAAM,UAAU,CAAC,IAAI,IAAI,CAAC;AAAA,MAC9B,GAAI,OAAO,MAAM,YAAY,YAAY,MAAM,UAAU,IACrD,CAAC,MAAM,OAAO,MAAM,OAAO,CAAC,IAC5B,CAAC;AAAA,MACL,GAAI,MAAM,OAAO,CAAC,aAAa,MAAM,IAAI,IAAI,CAAC;AAAA,IAChD;AACA,UAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,SAAS,GAAG;AAC5C,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,QACE,aAAa,WAAW,YAAY,CAAC;AAAA,QACrC,MAAM,WAAW,QAAQ,MAAM,cAAc,CAAC;AAAA,QAC9C,QAAQ,MAAM,IAAI,UAAU,EAAE,KAAK,GAAG,CAAC,OAAO,WAAW,OAAO,CAAC,IAAI,WAAW,UAAU,CAAC,0BAA0B,KAAK;AAAA,MAC5H,EAAE,KAAK,IAAI;AAAA,IACb;AAEA,UAAM,SAAS,OAAO,OAAO,SAAS,MAAM,EAAE,KAAK;AACnD,QAAI,OAAO,SAAS,uBAAuB,GAAG;AAC5C,YAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,GAAG,EAAE;AAAA,IACxD;AAEA,WAAO,UAAU;AAAA,EACnB;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf;AAAA,IACA,WAAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,OAAO,WAAmB;AAC9B,YAAM,WAAW,SAAS;AAAA,IAC5B;AAAA,IACA,MAAM,KAAK,SAAS,KAAK,OAA6C;AACpE,YAAM,aAAa,IAAI,gBAAgB;AAGvC,YAAM,YACJ,OAAO,MAAM,YAAY,YAAY,MAAM,UAAU,IACjD,WAAW,MAAM,WAAW,MAAM,GAAG,MAAM,UAAU,GAAI,IACzD;AAEN,YAAM,kBAAkB,MAAM;AAC9B,YAAM,UAAU,MAAM,WAAW,MAAM;AACvC,uBAAiB,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAElE,UAAI;AACF,cAAM,SAAS,MAAM,SAAS,SAAS;AAAA,UACrC;AAAA,UACA,QAAQ,WAAW;AAAA,UACnB,QAAQ,MAAM;AAAA,QAChB,CAAC;AACD,eAAO,EAAE,UAAU,OAAO,SAAS;AAAA,MACrC,UAAE;AACA,yBAAiB,oBAAoB,SAAS,OAAO;AACrD,YAAI,WAAW;AACb,uBAAa,SAAS;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACpYA,OAAOC,WAAU;AAEjB,SAAS,mBAAmB;AAO5B,eAAsB,cAAc,MAKlB;AAChB,QAAM,YAAY;AAAA,IAChB,SAAS,KAAK;AAAA,IACd,SAASA,MAAK,MAAM,KAAK,KAAK,gBAAgB,WAAW,QAAQ;AAAA,IACjE,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,yBAAyB,CAAC,EAAE,KAAK,MAAM,0BAA0B,IAAI;AAAA,IACrE,6BAA6B,CAAC,EAAE,WAAW,SAAS,MAClD,kCAAkC,SAAS,KAAK,QAAQ;AAAA,EAC5D,CAAC;AACH;;;ACxBA,SAAS,mBAAmB;AAE5B,SAAS,uBAAuB;;;ACFhC;AAAA,EACE;AAAA,OAGK;AAEP,IAAM,aAAa;AAOZ,SAAS,gBAAgB,QAAiC;AAC/D,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,aAAW,QAAQ,SAAS;AAC1B,QAAI,KAAK,SAAS,QAAQ;AACxB,YAAM,IAAI,kCAAkC;AAAA,QAC1C,SAAS,wDAAwD,KAAK,IAAI;AAAA,QAC1E,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,KAAK,KAAK,IAAI;AAAA,EACtB;AACA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAuBO,SAAS,oBAAoB,QAAyB;AAC3D,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,KAAK,UAAU,MAAM;AACxC,SAAO,cAAc;AACvB;AAYO,SAAS,sBAAsB,MAAc,OAAuB;AACzE,MAAI,CAAC,oBAAoB,KAAK,IAAI,KAAK,SAAS,OAAO,SAAS,MAAM;AACpE,UAAM,IAAI,MAAM,cAAc,KAAK,UAAU,IAAI,EAAE;AAAA,EACrD;AACA,SAAO;AACT;;;ADTO,SAAS,wBACd,UAAoC,CAAC,GAClB;AACnB,QAAM,MACJ,QAAQ,0BAA0B,MAC9B,QAAQ,iBACR,IAAI,IAAI,OAAO,QAAQ,QAAQ,kBAAkB,CAAC,CAAC,CAAC;AAC1D,SAAO;AAAA,IACL,eAAe;AAAA,IACf,uBAAuB;AAAA,IACvB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,mBAAmB,oBAAI,IAAI;AAAA,IAC3B,wBAAwB,oBAAI,IAAI;AAAA,IAChC,UAAU;AAAA,IACV,iBAAiB,oBAAI,IAAI;AAAA,IACzB,oBAAoB,oBAAI,IAAI;AAAA,IAC5B,kBAAkB,IAAI,IAAI,QAAQ,oBAAoB,CAAC,CAAC;AAAA,IACxD,eAAe,IAAI,IAAI,QAAQ,iBAAiB,CAAC,CAAC;AAAA,IAClD,uBAAuB;AAAA,EACzB;AACF;AAEA,SAAS,QAAgB;AACvB,SAAO,YAAY,CAAC,EAAE,SAAS,KAAK;AACtC;AAUA,SAAS,mBAAmB,OAA8B;AACxD,QAAM,aAAwB,CAAC;AAC/B,QAAM,SAAS,MAAM;AACrB,MAAI,UAAU,OAAO,WAAW,UAAU;AACxC,UAAM,QAAS,OAAiC;AAChD,QAAI,MAAM,QAAQ,KAAK,EAAG,YAAW,KAAK,KAAK;AAAA,EACjD;AACA,MAAI,MAAM,QAAQ,MAAM,OAAO,EAAG,YAAW,KAAK,MAAM,OAAO;AAE/D,aAAW,WAAW,YAAY;AAChC,QAAI,CAAC,MAAM,QAAQ,OAAO,EAAG;AAC7B,UAAM,OAAO,QACV;AAAA,MACC,CAAC,MACC,CAAC,CAAC,KACF,OAAO,MAAM,YACZ,EAAyB,SAAS,UACnC,OAAQ,EAAyB,SAAS;AAAA,IAC9C,EACC,IAAI,OAAK,EAAE,IAAI,EACf,KAAK,EAAE;AACV,QAAI,KAAM,QAAO;AAAA,EACnB;AAEA,MAAI,OAAO,MAAM,WAAW,SAAU,QAAO,MAAM;AACnD,MAAI,OAAO,MAAM,YAAY,SAAU,QAAO,MAAM;AACpD,SAAQ,MAAM,UAAU,MAAM,WAAW;AAC3C;AAEA,SAAS,mBAAmB,SAA2B;AACrD,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI;AACF,WAAO,gBAAgB,OAAO;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBACP,OACA,YACkC;AAClC,QAAM,SAAS,MAAM,sBAAsB,IAAI,UAAU;AACzD,SAAO,EAAE,MAAM,UAAU,YAAY,QAAQ,WAAW;AAC1D;AAEA,SAAS,WAAW,OAAiD;AACnE,MAAI,CAAC,MAAM,YAAY,MAAM,uBAAuB,OAAO,EAAG,QAAO,CAAC;AACtE,QAAM,WAAW;AACjB,QAAM,uBAAuB,MAAM;AACnC,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,cAAc,EAAE,SAAS,QAAQ,KAAK,OAAO;AAAA,MAC7C,OAAO;AAAA,QACL,aAAa,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,QACjE,cAAc,EAAE,OAAO,GAAG,MAAM,GAAG,WAAW,EAAE;AAAA,MAClD;AAAA,MACA,iBAAiB,EAAE,IAAI,EAAE,cAAc,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AACF;AAEO,SAAS,qBACd,OACA,YACuB;AACvB,QAAM,WAAW;AACjB,QAAM,uBAAuB,OAAO,UAAU;AAC9C,SAAO,WAAW,KAAK;AACzB;AAEA,SAAS,qBAAqB,SAA8C;AAC1E,MAAI,CAAC,WAAW,QAAQ,SAAS,YAAa,QAAO,CAAC;AACtD,MAAI,CAAC,MAAM,QAAQ,QAAQ,OAAO,EAAG,QAAO,CAAC;AAC7C,SAAO,QAAQ,QAAQ,QAAQ,UAAQ;AACrC,QAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO,CAAC;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,SAAS,WAAY,QAAO,CAAC;AACvC,UAAM,KAAK,MAAM,MAAM,MAAM;AAC7B,WAAO,OAAO,OAAO,YAAY,GAAG,SAAS,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC3D,CAAC;AACH;AAWO,SAAS,iBACd,OACA,OACuB;AACvB,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AAAA,IACL,KAAK,iBAAiB;AACpB,UACE,MAAM,SAAS,mBACf,MAAM,SAAS,SAAS,aACxB;AACA,eAAO,CAAC;AAAA,MACV;AACA,YAAM,gBAAgB;AACtB,UAAI,MAAM,SAAS,iBAAiB;AAClC,cAAM,WAAW;AACjB,cAAM,uBAAuB,MAAM;AAAA,MACrC;AACA,YAAM,wBAAwB;AAC9B,YAAM,gBAAgB;AACtB,YAAM,qBAAqB;AAC3B,YAAM,mBAAmB;AACzB,aAAO,CAAC;AAAA,IACV;AAAA,IAEA,KAAK,kBAAkB;AACrB,UAAI,CAAC,MAAM,cAAe,QAAO,CAAC;AAClC,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAI,OAAO,SAAS,gBAAgB,OAAO,OAAO,UAAU,UAAU;AACpE,cAAM,QAA+B,CAAC;AAItC,YAAI,MAAM,oBAAoB,MAAM,oBAAoB;AACtD,gBAAM,KAAK;AAAA,YACT,MAAM;AAAA,YACN,IAAI,MAAM;AAAA,UACZ,CAAC;AACD,gBAAM,mBAAmB;AACzB,gBAAM,qBAAqB;AAAA,QAC7B;AACA,YAAI,CAAC,MAAM,eAAe;AACxB,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,KAAK,EAAE,MAAM,cAAc,IAAI,MAAM,cAAc,CAAC;AAAA,QAC5D;AACA,cAAM,yBAAyB,OAAO;AACtC,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,MAAM;AAAA,UACV,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,MACT;AACA,UACE,OAAO,SAAS,oBAChB,OAAO,OAAO,UAAU,UACxB;AACA,cAAM,QAA+B,CAAC;AAGtC,YAAI,MAAM,eAAe;AACvB,gBAAM,KAAK,EAAE,MAAM,YAAY,IAAI,MAAM,cAAc,CAAC;AACxD,gBAAM,gBAAgB;AAAA,QACxB;AACA,YAAI,CAAC,MAAM,oBAAoB;AAC7B,gBAAM,qBAAqB,MAAM;AAAA,QACnC;AACA,YAAI,CAAC,MAAM,kBAAkB;AAC3B,gBAAM,mBAAmB;AACzB,gBAAM,KAAK,EAAE,MAAM,mBAAmB,IAAI,MAAM,mBAAmB,CAAC;AAAA,QACtE;AACA,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,MAAM;AAAA,UACV,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO,CAAC;AAAA,IACV;AAAA,IAEA,KAAK;AAAA,IACL,KAAK,YAAY;AACf,UAAI,CAAC,MAAM,cAAe,QAAO,CAAC;AAClC,YAAM,QAA+B,CAAC;AACtC,YAAM,WAAW,qBAAqB,MAAM,OAAO;AACnD,UACE,MAAM,iBACN,SAAS,WAAW,MAAM,qBAAqB,KAC/C,SAAS,SAAS,MAAM,sBAAsB,QAC9C;AACA,cAAM,UAAU,SAAS,MAAM,MAAM,sBAAsB,MAAM;AACjE,cAAM,wBAAwB;AAC9B,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,MAAM;AAAA,UACV,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,UAAI,MAAM,eAAe;AACvB,cAAM,KAAK,EAAE,MAAM,YAAY,IAAI,MAAM,cAAc,CAAC;AACxD,cAAM,gBAAgB;AAAA,MACxB;AACA,UAAI,MAAM,oBAAoB,MAAM,oBAAoB;AACtD,cAAM,KAAK,EAAE,MAAM,iBAAiB,IAAI,MAAM,mBAAmB,CAAC;AAClE,cAAM,mBAAmB;AACzB,cAAM,qBAAqB;AAAA,MAC7B;AACA,UAAI,MAAM,SAAS,eAAe;AAChC,mBAAW,cAAc,qBAAqB,MAAM,OAAO,GAAG;AAC5D,gBAAM,uBAAuB,IAAI,UAAU;AAAA,QAC7C;AAAA,MACF,OAAO;AACL,cAAM,uBAAuB,MAAM;AACnC,cAAM,KAAK,GAAG,WAAW,KAAK,CAAC;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,wBAAwB;AAC3B,UAAI,CAAC,MAAM,cAAc,CAAC,MAAM,SAAU,QAAO,CAAC;AAClD,YAAM,EAAE,MAAM,OAAO,IAAI,gBAAgB,OAAO,MAAM,QAAQ;AAC9D,YAAM,kBAAkB,IAAI,MAAM,YAAY,IAAI;AAClD,YAAM,YACJ,CAAC,MAAM,cAAc,IAAI,MAAM,MAC9B,WAAW,SAAS,OAAO,WAAW,OAAO;AAChD,YAAM,mBAAmB,MAAM,iBAAiB,IAAI,MAAM,KAAK;AAC/D,UAAI,UAAW,OAAM,mBAAmB,IAAI,MAAM,UAAU;AAC5D,YAAM,QAAQ,oBAAoB,MAAM,QAAQ,MAAM,SAAS,CAAC,CAAC;AACjE,aAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,YAAY,MAAM;AAAA,UAClB,UAAU;AAAA,UACV;AAAA,UACA,GAAI,SAAS,SAAS,EAAE,YAAY,OAAO,IAAI,CAAC;AAAA,UAChD,GAAI,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAAA,UACrD,GAAI,YAAY,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,IAEA,KAAK;AAAA,IACL,KAAK,eAAe;AAClB,UAAI,CAAC,MAAM,WAAY,QAAO,CAAC;AAC/B,YAAM,eAAe,MAAM,kBAAkB,IAAI,MAAM,UAAU;AACjE,YAAM,aAAa,MAAM;AACzB,YAAM,OACJ,iBACC,aAAa,gBAAgB,OAAO,UAAU,EAAE,OAAO;AAC1D,UAAI,CAAC,KAAM,QAAO,CAAC;AACnB,YAAM,UAAU,MAAM,mBAAmB,OAAO,MAAM,UAAU;AAOhE,YAAM,SAAS,MAAM,gBAAgB,IAAI,MAAM,UAAU,IACnD,MAAM,gBAAgB,IAAI,MAAM,UAAU,KAAK,OAIjD,UACE,mBAAmB,mBAAmB,KAAK,CAAC,IAC5C,mBAAmB,KAAK;AAC9B,YAAM,gBAAgB,OAAO,MAAM,UAAU;AAC7C,YAAM,uBAAuB,OAAO,MAAM,UAAU;AACpD,aAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,YAAY,MAAM;AAAA,UAClB,UAAU;AAAA,UACV;AAAA,UACA,GAAI,MAAM,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,UACzC,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,QACrC;AAAA,QACA,GAAG,WAAW,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,KAAK,kBAAkB;AAUrB,UAAI,MAAM,QAAS,QAAO,CAAC;AAC3B,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO,CAAC;AACnD,YAAM,aAAc,OAAiC;AACrD,YAAM,UACJ,OAAO,eAAe,WAAW,aAAa;AAChD,YAAM,eAAgB,OAAsC;AAC5D,aAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,SAAS,MAAM,WAAW,WAAW,WAAW;AAAA,UAChD;AAAA,UACA,GAAI,OAAO,iBAAiB,WAAW,EAAE,aAAa,IAAI,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AACE,aAAO,CAAC;AAAA,EACZ;AACF;;;AE5ZA,SAAS,YAA0B;AAQ5B,SAAS,4BAA4B,YAA8B;AACxE,SAAO,KAAK,OAAO,UAAoB;AACzC;;;ACwBA,OAAO,QAAQ;AACf,SAAS,6BAA6B;AACtC,OAAOC,WAAU;AAejB,IAAM,eAAe,oBAAI,IAAyB;AAClD,IAAM,YAAY;AAClB,IAAM,oBAAoB,GAAG;AAE7B,IAAM,wBAAwB;AAAA,EAC5B,YAAY,GAAG;AAAA,EACf,WAAW,GAAG;AAAA,EACd,UAAU,GAAG;AAAA,EACb,cAAc,GAAG;AAAA,EACjB,aAAa,GAAG;AAAA,EAChB,cAAc,GAAG;AAAA,EACjB,YAAY,GAAG;AAAA,EACf,QAAQ,GAAG;AAAA,EACX,UAAU,GAAG;AAAA,EACb,eAAe,GAAG;AACpB;AAEA,IAAM,4BAA4B;AAAA,EAChC,OAAO,GAAG;AAAA,EACV,UAAU,GAAG;AAAA,EACb,OAAO,GAAG;AAAA,EACV,MAAM,GAAG;AAAA,EACT,QAAQ,GAAG;AAAA,EACX,WAAW,GAAG;AAChB;AAEA,IAAM,qBAAqB;AAAA,EACzB,OAAO,GAAG,SAAS,MAAM,KAAK,GAAG,QAAQ;AAAA,EACzC,UAAU,GAAG,SAAS,SAAS,KAAK,GAAG,QAAQ;AAAA,EAC/C,WAAW,GAAG,SAAS,UAAU,KAAK,GAAG,QAAQ;AACnD;AAEA,SAASC,cAAa,QAAgB,WAA4B;AAChE,QAAM,WAAWD,MAAK,SAAS,QAAQ,SAAS;AAChD,SACE,aAAa,MACZ,CAAC,SAAS,WAAW,IAAI,KAAK,CAACA,MAAK,WAAW,QAAQ;AAE5D;AAEA,SAAS,oBAAoB,WAA2B;AACtD,SAAOA,MAAK,WAAW,SAAS,IAC5BA,MAAK,UAAU,SAAS,IACxBA,MAAK,QAAQ,SAAS;AAC5B;AAEA,SAAS,gBAAgB,WAA4C;AACnE,QAAM,eAAe,oBAAoB,SAAS;AAClD,MAAI;AAEJ,aAAW,eAAe,aAAa,OAAO,GAAG;AAC/C,QAAI,CAACC,cAAa,YAAY,YAAY,YAAY,GAAG;AACvD;AAAA,IACF;AACA,QACE,CAAC,aACD,YAAY,WAAW,SAAS,UAAU,WAAW,QACrD;AACA,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAkC;AAC1D,QAAM,cAAc,gBAAgB,SAAS;AAC7C,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,oBAAoB,SAAS;AAClD,QAAM,eAAeD,MAAK,SAAS,YAAY,YAAY,YAAY;AACvE,SAAO,eACHA,MAAK,KAAK,YAAY,aAAa,YAAY,IAC/C,YAAY;AAClB;AAEA,SAAS,kBAAkB,WAAmB,QAAwB;AACpE,QAAM,cAAc,gBAAgB,SAAS;AAC7C,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,wBAAwBA,MAAK,QAAQ,YAAY,WAAW;AAChE,MAAI;AACF,UAAM,WACJ,sBAAsB,aAAa,UACnC,sBAAsB;AACxB,4BAAwBA,MAAK,QAAQ,SAAS,YAAY,WAAW,CAAC;AAAA,EACxE,QAAQ;AAAA,EAER;AAEA,QAAM,mBAAmBA,MAAK,QAAQ,MAAM;AAC5C,MAAI,CAACC,cAAa,uBAAuB,gBAAgB,GAAG;AAC1D,WAAO;AAAA,EACT;AAEA,QAAM,eAAeD,MAAK,SAAS,uBAAuB,gBAAgB;AAC1E,SAAO,eACHA,MAAK,KAAK,YAAY,YAAY,YAAY,IAC9C,YAAY;AAClB;AAEA,SAAS,eACP,YACA,iBACyB;AACzB,QAAM,aAAa,gBAAgB,UAAU;AAC7C,QAAM,kBAAkB,gBAAgB,eAAe;AAEvD,MAAI,CAAC,cAAc,CAAC,iBAAiB;AACnC,WAAO;AAAA,EACT;AAEA,MACE,CAAC,cACD,CAAC,mBACD,WAAW,eAAe,gBAAgB,YAC1C;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,iBAAiB,UAAU,KAAK;AAAA,IAChC,iBAAiB,eAAe,KAAK;AAAA,EACvC;AACF;AAEA,SAAS,mBACP,UACA,UAEI,CAAC,GACD;AACJ,UAAQ,IAAI,SAAyB;AACnC,UAAM,CAAC,SAAS,IAAI;AACpB,QAAI,OAAO,cAAc,UAAU;AACjC,YAAM,aAAa,iBAAiB,SAAS;AAC7C,UAAI,YAAY;AACd,cAAM,SAAS;AAAA,UACb,GAAI,CAAC,YAAY,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,QACnC;AACA,eAAO,QAAQ,YACX,QAAQ,UAAU,WAAW,MAAM,IACnC;AAAA,MACN;AAAA,IACF;AACA,WAAO,SAAS,GAAG,IAAI;AAAA,EACzB;AACF;AAEA,SAAS,eACP,UACI;AACJ,UAAQ,IAAI,SAAyB;AACnC,UAAM,CAAC,YAAY,eAAe,IAAI;AACtC,QAAI,OAAO,eAAe,YAAY,OAAO,oBAAoB,UAAU;AACzE,YAAM,cAAc,eAAe,YAAY,eAAe;AAC9D,UAAI,aAAa;AACf,eAAO;AAAA,UACL,GAAI;AAAA,YACF,YAAY,CAAC;AAAA,YACb,YAAY,CAAC;AAAA,YACb,GAAG,KAAK,MAAM,CAAC;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,SAAS,GAAG,IAAI;AAAA,EACzB;AACF;AAEA,SAAS,uBACP,UACA,UAEI,CAAC,GACD;AACJ,UAAQ,IAAI,SAAyB;AACnC,UAAM,CAAC,SAAS,IAAI;AACpB,QAAI,OAAO,cAAc,UAAU;AACjC,YAAM,aAAa,iBAAiB,SAAS;AAC7C,UAAI,YAAY;AACd,cAAM,WAAW,CAAC,YAAY,GAAG,KAAK,MAAM,CAAC,CAAC;AAC9C,cAAM,gBAAgB,SAAS,GAAG,EAAE;AACpC,YAAI,QAAQ,qBAAqB,OAAO,kBAAkB,YAAY;AACpE,mBAAS,SAAS,SAAS,CAAC,IAAI,CAC9B,OACA,WACG,SACA;AACH,kBAAM,eAAe,QACjB,SACA,QAAQ,oBAAoB,WAAW,MAAM;AACjD,YAAC;AAAA,cACC;AAAA,cACA;AAAA,cACA,GAAG;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,eAAO,SAAS,GAAI,QAA2B;AAAA,MACjD;AAAA,IACF;AACA,WAAO,SAAS,GAAG,IAAI;AAAA,EACzB;AACF;AAEA,SAAS,sBAEP,UAAkB;AAClB,UAAQ,UAAU,SAAyB;AACzC,UAAM,CAAC,SAAS,IAAI;AACpB,QAAI,OAAO,cAAc,UAAU;AACjC,YAAM,aAAa,iBAAiB,SAAS;AAC7C,UAAI,YAAY;AACd,eAAO,MAAM;AAAA,UACX,GAAI,CAAC,YAAY,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM,SAAS,GAAG,IAAI;AAAA,EAC/B;AACF;AAEA,SAAS,4BAAiD;AACxD,QAAM,UAAU,mBAAmB,sBAAsB,cAAc;AAAA,IACrE,WAAW,CAAC,WAAW,WACrB,OAAO,WAAW,WACd,kBAAkB,WAAW,MAAM,IACnC;AAAA,EACR,CAAC;AAED,MAAI,sBAAsB,aAAa,QAAQ;AAC7C,YAAQ,SAAS;AAAA,MACf,sBAAsB,aAAa;AAAA,MACnC;AAAA,QACE,WAAW,CAAC,WAAW,WACrB,OAAO,WAAW,WACd,kBAAkB,WAAW,MAAM,IACnC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,uBAAuB;AAAA,EAC3B,YAAY,mBAAmB,sBAAsB,UAAU;AAAA,EAC/D,WAAW,mBAAmB,sBAAsB,SAAS;AAAA,EAC7D,UAAU,mBAAmB,sBAAsB,QAAQ;AAAA,EAC3D,cAAc,mBAAmB,sBAAsB,YAAY;AAAA,EACnE,aAAa,mBAAmB,sBAAsB,WAAW;AAAA,EACjE,cAAc,0BAA0B;AAAA,EACxC,YAAY,eAAe,sBAAsB,UAAU;AAAA,EAC3D,QAAQ,mBAAmB,sBAAsB,MAAM;AAAA,EACvD,UAAU,mBAAmB,sBAAsB,QAAQ;AAAA,EAC3D,eAAe,mBAAmB,sBAAsB,aAAa;AACvE;AAEA,IAAM,2BAA2B;AAAA,EAC/B,OAAO,uBAAuB,0BAA0B,KAAK;AAAA,EAC7D,UAAU,uBAAuB,0BAA0B,UAAU;AAAA,IACnE,mBAAmB,CAAC,WAAW,WAC7B,OAAO,WAAW,WACd,kBAAkB,WAAW,MAAM,IACnC;AAAA,EACR,CAAC;AAAA,EACD,OAAO,uBAAuB,0BAA0B,KAAK;AAAA,EAC7D,MAAM,uBAAuB,0BAA0B,IAAI;AAAA,EAC3D,QAAQ,uBAAuB,0BAA0B,MAAM;AAAA,EAC/D,WAAW,uBAAuB,0BAA0B,SAAS;AACvE;AAEA,IAAM,oBAAoB;AAAA,EACxB,OAAO,sBAAsB,mBAAmB,KAAK;AAAA,EACrD,UAAU,sBAAsB,mBAAmB,QAAQ;AAAA,EAC3D,WAAW,sBAAsB,mBAAmB,SAAS;AAC/D;AAEA,SAAS,6BAAsC;AAC7C,SAAO,UAAU,eAAe,qBAAqB;AACvD;AAEA,SAAS,wBAAwB;AAC/B,MAAI,2BAA2B,EAAG;AAElC,YAAU,aAAa,qBAAqB;AAC5C,YAAU,YAAY,qBAAqB;AAC3C,YAAU,WAAW,qBAAqB;AAC1C,YAAU,eAAe,qBAAqB;AAC9C,YAAU,cAAc,qBAAqB;AAC7C,YAAU,eAAe,qBAAqB;AAC9C,YAAU,aAAa,qBAAqB;AAC5C,YAAU,SAAS,qBAAqB;AACxC,YAAU,WAAW,qBAAqB;AAC1C,YAAU,gBAAgB,qBAAqB;AAE/C,YAAU,QAAQ,yBAAyB;AAC3C,YAAU,WAAW,yBAAyB;AAC9C,YAAU,QAAQ,yBAAyB;AAC3C,YAAU,OAAO,yBAAyB;AAC1C,YAAU,SAAS,yBAAyB;AAC5C,YAAU,YAAY,yBAAyB;AAE/C,oBAAkB,QAAQ,kBAAkB;AAC5C,oBAAkB,WAAW,kBAAkB;AAC/C,oBAAkB,YAAY,kBAAkB;AAEhD,wBAAsB;AACxB;AAEA,SAAS,wBAAwB;AAC/B,MAAI,CAAC,2BAA2B,EAAG;AAEnC,YAAU,aAAa,sBAAsB;AAC7C,YAAU,YAAY,sBAAsB;AAC5C,YAAU,WAAW,sBAAsB;AAC3C,YAAU,eAAe,sBAAsB;AAC/C,YAAU,cAAc,sBAAsB;AAC9C,YAAU,eAAe,sBAAsB;AAC/C,YAAU,aAAa,sBAAsB;AAC7C,YAAU,SAAS,sBAAsB;AACzC,YAAU,WAAW,sBAAsB;AAC3C,YAAU,gBAAgB,sBAAsB;AAEhD,YAAU,QAAQ,0BAA0B;AAC5C,YAAU,WAAW,0BAA0B;AAC/C,YAAU,QAAQ,0BAA0B;AAC5C,YAAU,OAAO,0BAA0B;AAC3C,YAAU,SAAS,0BAA0B;AAC7C,YAAU,YAAY,0BAA0B;AAEhD,oBAAkB,QAAQ,mBAAmB;AAC7C,oBAAkB,WAAW,mBAAmB;AAChD,oBAAkB,YAAY,mBAAmB;AAEjD,wBAAsB;AACxB;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAArB;AACL,SAAQ,cAA6B;AACrC,SAAQ,aAA4B;AAAA;AAAA,EAE5B,eAAqB;AAC3B,QAAI,KAAK,YAAY;AACnB,mBAAa,OAAO,KAAK,UAAU;AAAA,IACrC;AACA,SAAK,cAAc;AACnB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAqB,YAA0B;AACnD,QAAI,KAAK,gBAAgB,eAAe,KAAK,eAAe,YAAY;AACtE;AAAA,IACF;AAEA,UAAM,sBAAsBA,MAAK,QAAQ,WAAW;AACpD,UAAM,qBAAqBA,MAAK,QAAQ,UAAU;AAClD,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa;AAAA,IACpB;AAEA,iBAAa,IAAI,oBAAoB;AAAA,MACnC,aAAa;AAAA,MACb,YAAY;AAAA,IACd,CAAC;AACD,0BAAsB;AAEtB,SAAK,cAAc;AACnB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,UAAgB;AACd,SAAK,aAAa;AAElB,QAAI,aAAa,SAAS,GAAG;AAC3B,4BAAsB;AAAA,IACxB;AAAA,EACF;AACF;;;ACpbA;AAAA,EACE,SAAAE;AAAA,EACA,YAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAAC;AAAA,OACK;AACP,OAAOC,WAAU;AACjB,SAAS,cAAAC,mBAAkB;AAsB3B,IAAM,iBAAiB,CAAC,OAAO,SAAS;AACxC,IAAM,uBAAuB,CAAC,aAAa,WAAW;AAEtD,SAAS,sBAAsB,WAA2B;AACxD,QAAM,aAAa,UAAU,MAAMD,MAAK,MAAM,GAAG,EAAE,KAAKA,MAAK,GAAG;AAChE,QAAM,WAAWA,MAAK,UAAU,UAAU;AAC1C,MACE,aAAa,MACb,aAAa,OACbA,MAAK,WAAW,QAAQ,KACxB,aAAa,QACb,SAAS,WAAW,KAAKA,MAAK,GAAG,EAAE,GACnC;AACA,UAAM,IAAI;AAAA,MACR,+DAA+D,SAAS;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,kBACb,SACA,SACiB;AACjB,QAAM,SAAS,MAAM,QAAQ,IAAI,EAAE,QAAQ,CAAC;AAC5C,MAAI,OAAO,YAAY,QAAQ,OAAO,aAAa,GAAG;AACpD,UAAM,IAAI;AAAA,MACR,OAAO,UACL,OAAO,UACP,yCAAyC,OAAO,QAAQ;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,OAAO,UAAU,OAAO;AACjC;AAEA,eAAe,2BACb,SACA,gBAIC;AAYD,QAAM,cAAc;AAAA,IAClB,GAAG,eAAe,IAAI,SAAO,KAAK,GAAG,EAAE;AAAA,IACvC,GAAG,qBAAqB,IAAI,UAAQ,KAAK,IAAI,EAAE;AAAA,EACjD;AACA,QAAM,cAAc;AAAA,IAClB,sBAAsB,YACnB;AAAA,MAAI,gBACHC,YAAWD,MAAK,MAAM,KAAK,gBAAgB,WAAW,MAAM,CAAC,CAAC,CAAC;AAAA,IACjE,EACC,KAAK,GAAG,CAAC;AAAA,IACZ,wBAAwB,YACrB,IAAI,gBAAcC,YAAW,WAAW,MAAM,CAAC,CAAC,CAAC,EACjD,KAAK,GAAG,CAAC;AAAA,IACZ,wBAAwB,YAAY,IAAI,MAAM,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,IAC7D,gCAAgC,YAAY,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,CAAC,MAAMA,YAAW,cAAc,CAAC,IAAI,WAAW,EAAE,KAAK,MAAM;AAAA,EAC/D;AAEA,QAAM,cAAwB,CAAC;AAC/B,QAAM,QAA8D,CAAC;AAErE,aAAW,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACrD,UAAM,CAAC,MAAM,SAAS,WAAW,IAAI,KAAK,MAAM,KAAM,CAAC;AACvD,QAAI,CAAC,QAAS;AAEd,UAAM,eAAe,sBAAsB,OAAO;AAClD,QAAI,SAAS,IAAK,aAAY,KAAK,YAAY;AAAA,aACtC,SAAS,OAAO,aAAa;AACpC,YAAM,KAAK,EAAE,cAAc,YAAY,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,MAAM;AAC9B;AAEA,eAAe,SACb,QAC2C;AAC3C,MAAI;AACF,UAAM,QAAQ,MAAM,KAAK,MAAM;AAC/B,QAAI,MAAM,YAAY,EAAG,QAAO;AAChC,QAAI,MAAM,OAAO,EAAG,QAAO;AAC3B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,mBACb,SACA,YACA,aACA,OACe;AACf,QAAM,UAAU,MAAM,QAAQ,YAAY,EAAE,eAAe,KAAK,CAAC;AACjE,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,eAAe,EAAG;AAC5B,UAAM,eAAeD,MAAK,KAAK,YAAY,MAAM,IAAI;AACrD,UAAM,eAAeA,MAAK,SAAS,SAAS,YAAY;AACxD,QAAI,MAAM,YAAY,GAAG;AACvB,kBAAY,KAAK,YAAY;AAC7B,YAAM,mBAAmB,SAAS,cAAc,aAAa,KAAK;AAAA,IACpE,WAAW,MAAM,OAAO,GAAG;AACzB,YAAM,KAAK,YAAY;AAAA,IACzB;AAAA,EACF;AACF;AAQA,eAAe,yBACb,SACqD;AACrD,QAAM,cAAwB,CAAC;AAC/B,QAAM,QAAkB,CAAC;AAEzB,aAAW,OAAO,gBAAgB;AAChC,UAAM,YAAYA,MAAK,KAAK,SAAS,GAAG;AACxC,QAAK,MAAM,SAAS,SAAS,MAAO,aAAa;AAC/C,kBAAY,KAAK,GAAG;AACpB,YAAM,mBAAmB,SAAS,WAAW,aAAa,KAAK;AAAA,IACjE;AAAA,EACF;AAEA,aAAW,QAAQ,sBAAsB;AACvC,QAAK,MAAM,SAASA,MAAK,KAAK,SAAS,IAAI,CAAC,MAAO,QAAQ;AACzD,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,MAAM;AAC9B;AAEA,SAAS,yBACP,mBACA,aACa;AACb,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,aAAa,mBAAmB;AACzC,gBAAY,IAAI,sBAAsB,SAAS,CAAC;AAAA,EAClD;AACA,aAAW,QAAQ,aAAa;AAC9B,QAAI,UAAUA,MAAK,QAAQ,sBAAsB,KAAK,YAAY,CAAC;AACnE,WAAO,YAAY,OAAO,YAAYA,MAAK,OAAO,QAAQ,SAAS,GAAG;AACpE,kBAAY,IAAI,OAAO;AACvB,gBAAUA,MAAK,QAAQ,OAAO;AAAA,IAChC;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,6BAA6B,MAIjC;AAChB,QAAM,EAAE,SAAS,gBAAgB,YAAY,IAAI;AACjD,QAAM,gBAAgB,MAAM;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AACA,QAAM,cAAc,MAAM,yBAAyB,WAAW;AAC9D,QAAM,cAAc,IAAI;AAAA,IACtB,cAAc,MAAM,IAAI,UAAQ,KAAK,YAAY;AAAA,EACnD;AACA,QAAM,sBAAsB;AAAA,IAC1B,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AAEA,aAAW,gBAAgB,YAAY,OAAO;AAC5C,QAAI,CAAC,YAAY,IAAI,YAAY,GAAG;AAClC,YAAM,GAAGA,MAAK,KAAK,aAAa,YAAY,GAAG,EAAE,OAAO,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC,GAAG,YAAY,WAAW,EACrD,OAAO,OAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC,EACvC,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACrC,aAAW,gBAAgB,sBAAsB;AAC/C,UAAM,GAAGA,MAAK,KAAK,aAAa,YAAY,GAAG;AAAA,MAC7C,WAAW;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,aAAW,gBAAgB,CAAC,GAAG,mBAAmB,EAAE;AAAA,IAClD,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE;AAAA,EACzB,GAAG;AACD,UAAMH,OAAMG,MAAK,KAAK,aAAa,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACvE;AAEA,aAAW,EAAE,cAAc,YAAY,KAAK,cAAc,OAAO;AAC/D,UAAM,QAAQ,MAAM,QAAQ,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,0DAA0D,WAAW;AAAA,MACvE;AAAA,IACF;AACA,UAAM,UAAU,OAAO,KAAK,KAAK;AAEjC,UAAM,WAAWA,MAAK,KAAK,aAAa,YAAY;AACpD,QAAI,cAAc;AAClB,QAAI;AACF,YAAM,WAAW,MAAMF,UAAS,QAAQ;AACxC,oBAAc,CAAC,SAAS,OAAO,OAAO;AAAA,IACxC,QAAQ;AACN,oBAAc;AAAA,IAChB;AAEA,QAAI,aAAa;AACf,YAAMD,OAAMG,MAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,YAAMD,WAAU,UAAU,OAAO;AAAA,IACnC;AAAA,EACF;AACF;;;AZ9RA,IAAMG,cAAa;AAOnB,IAAM,yBAAiC;AAsBvC,IAAM,mBAAmB,oBAAI,IAA8B;AAK3D,SAAS,kBAAkB,QAAgB,OAAwB;AACjE,QAAM,MAAMC,MAAK,SAAS,QAAQ,KAAK;AACvC,SAAO,QAAQ,MAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAACA,MAAK,WAAW,GAAG;AACrE;AAOA,SAAS,kBACP,WACA,gBACA,aACS;AACT,SACE,kBAAkB,gBAAgB,SAAS,KAC3C,kBAAkB,aAAa,SAAS;AAE5C;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AACF,GAGY;AACV,SAAO,OAAO,IAAI,WAAS;AACzB,UAAM,OAAO,sBAAsB,MAAM,MAAM,OAAO;AACtD,UAAM,UAAUA,MAAK,MAAM,KAAK,qBAAqB,IAAI;AACzD,UAAM,WAAWA,MAAK,MAAM,KAAK,SAAS,UAAU;AACpD,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,YAAY;AAAA,QACV,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,MACA,wBAAwB;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AAEA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,mBAAqD;AAAA,EACzD,MAAM;AACR;AAEA,IAAM,mBAEF;AAAA,EACF,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AACN;AAEA,IAAM,uBAEF;AAAA,EACF,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AACN;AAEA,SAAS,4BACP,eACyD;AACzD,MAAI,iBAAiB,KAAM,QAAO;AAClC,MAAI,cAAc,SAAS,SAAS;AAClC,WAAO,cAAc,UAClB,IAAI,UAAQ,iBAAiB,IAAI,CAAC,EAClC;AAAA,MACC,CAAC,SACC,QAAQ;AAAA,IACZ;AAAA,EACJ;AACA,SAAO,wBAAwB;AAAA,IAC7B,YACE,CAAC,cAAc,UAAU,SAAS,iBAAiB,MAAM,KAAK,MAAM;AAAA,EACxE;AACF;AA4EA,eAAsB,gBACpB,OAC2B;AAC3B,MAAI,MAAM,UAAU;AAClB,UAAM,gBAAgB,iBAAiB,IAAI,MAAM,SAAS;AAC1D,QAAI,eAAe;AACjB,uBAAiB,OAAO,MAAM,SAAS;AACvC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAKA,QAAM,gBAAgB,MAAM,UAAU,QAAQ,YAAY,GAAG;AAC7D,QAAM,WAAWA,MAAK,KAAK,OAAO,GAAG,kBAAkB,MAAM,aAAa;AAC1E,QAAM,cAAcA,MAAK,KAAK,UAAU,WAAW;AACnD,QAAM,eAAeA,MAAK,KAAK,UAAU,OAAO;AAChD,QAAM,iBAAiBA,MAAK,KAAK,UAAU,UAAU;AAWrD,QAAM,iBAAiB,MAAM;AAE7B,QAAMC,OAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAMA,OAAM,cAAc,EAAE,WAAW,KAAK,CAAC;AAC7C,QAAMA,OAAM,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAE/C,QAAM,yBAAyB;AAAA,IAC7B,MAAM;AAAA,EACR;AACA,QAAM,iBAAiB,MAAM,sBAAsB;AAAA,IACjD,SAAS;AAAA,IACT,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,EAChE,CAAC;AACD,QAAM,oBAAoB,iCAAiC;AAAA,IACzD;AAAA,IACA,gBAAgB,MAAM;AAAA,IACtB,WAAW,MAAM;AAAA,EACnB,CAAC;AACD,QAAM,iBAAiB,MAAM,kBAAkB;AAC/C,MAAI;AACJ,MAAI,gBAAyB,CAAC;AAG9B,MAAI,MAAM,OAAO,SAAS,GAAG;AAC3B,0BAAsBD,MAAK,MAAM,KAAK,gBAAgB,WAAW,QAAQ;AACzE,oBAAgB,sBAAsB;AAAA,MACpC,QAAQ,MAAM;AAAA,MACd;AAAA,IACF,CAAC;AACD,UAAM,cAAc;AAAA,MAClB,SAAS;AAAA,MACT;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAChE,CAAC;AAAA,EACH;AAIA,MAAI;AACJ,MAAI,MAAM,YAAY,MAAM,uBAAuB;AACjD,UAAM,wBAAwB;AAAA,MAC5B,MAAM;AAAA,IACR;AACA,4BAAwB,MAAM,2BAA2B;AAAA,MACvD,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAChE,CAAC;AAAA,EACH;AAIA,QAAM,6BAA6B;AAAA,IACjC,SAAS;AAAA,IACT,gBAAgB,MAAM;AAAA,IACtB;AAAA,EACF,CAAC;AAOD,QAAM,eAAe,IAAI,eAAe;AACxC,eAAa,MAAM,aAAa,cAAc;AAE9C,QAAM,QAAQ,mBAAmB;AAAA,IAC/B;AAAA,IACA,gBAAgB;AAAA,IAChB,eAAe,sBACX,CAAC,EAAE,YAAY,oBAAoB,CAAC,IACpC,CAAC;AAAA,EACP,CAAC;AAMD,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,eAAe,MAAM,aAAa,OAAO;AAAA,IAC7C,UAAUA,MAAK,KAAK,UAAU,WAAW;AAAA,IACzC,YAAYA,MAAK,KAAK,UAAU,aAAa;AAAA,IAC7C,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,gBAAgB,IAAI,cAAc,YAAY;AACpD,QAAM,kBACJ,MAAM,YAAY,OACd,gBAAgB,OAAO,aAAa,QAAQ,IAC5C,gBAAgB,SAAS;AAG/B,QAAM,cAAc,aAAa;AAAA,IAC/B,SAAS,MAAM,SAAS;AAAA,IACxB,KAAK,QAAQ;AAAA,EACf,CAAC;AACD,QAAM,oBAAoB;AAAA,IACxB,SAAS,MAAM,SAAS;AAAA,IACxB,aAAa;AAAA,IACb,YAAY;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW,MAAM;AAAA,EACnB,CAAC;AACD,QAAM,eAAe,sBAAsB;AAAA,IACzC;AAAA,IACA,KAAK;AAAA,EACP,CAAC;AAGD,QAAM,gBAAgB,aAAa,MAAM,SAAS,KAAK;AACvD,QAAM,aAAa,oBAAoB;AAAA,IACrC,YAAY,MAAM,SAAS;AAAA,EAC7B,CAAC;AACD,QAAM,gBAAgB,OAAO,KAAK,UAAU,EAAE,SAAS;AAEvD,MAAI;AAQJ,QAAM,qBAAyC;AAAA,IAC7C,GAAI,MAAM,SAAS,sBAAsB,CAAC;AAAA,EAC5C;AACA,MAAI,eAAe;AACjB,UAAM,EAAE,iBAAiB,IAAK,MAAM,OAClC;AAEF,uBAAmB;AAAA,MACjB,iBAAiB;AAAA,QACf,QAAQ;AAAA,UACN;AAAA,UACA,UAAU;AAAA,YACR,aAAa;AAAA,YACb,YAAY;AAAA,YACZ,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,wBAAwB,mBAAmB,SAAS;AAC1D,MAAI,2BAA2B;AAC/B,MAAI;AAIJ,QAAM,iBAAiB,IAAI,sBAAsB;AAAA,IAC/C,KAAK;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,4BAA4B,MAC1B,sBAAsB,CAAC,mBAAmB,IAAI,CAAC;AAAA,IACjD;AAAA,IACA,GAAI,wBACA;AAAA;AAAA;AAAA;AAAA,MAIE,oBAAoB,gBAAc;AAChC,YAAI,4BAA4B,2BAA2B,MAAM;AAC/D,iBAAO;AAAA,QACT;AACA,kCAA0B;AAC1B,eAAO;AAAA,MACT;AAAA,IACF,IACA,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASL,cAAc;AAAA,IACd,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,gBAAgB,WAAS;AAAA,MACvB,GAAG;AAAA,MACH,QAAQ;AAAA,QACN,GAAG,KAAK,OAAO;AAAA,UAAO,WACpB,kBAAkB,MAAM,UAAU,gBAAgB,WAAW;AAAA,QAC/D;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,eAAe,OAAO;AAE5B,iBAAe,sBAAqC;AAClD,QAAI,CAAC,uBAAuB;AAC1B,YAAM,eAAe,OAAO;AAC5B;AAAA,IACF;AAEA,UAAM,YAAY,mBAAmB,OAAO,CAAC;AAC7C,+BAA2B;AAC3B,QAAI;AACF,YAAM,eAAe,OAAO;AAAA,IAC9B,UAAE;AACA,iCAA2B;AAC3B,yBAAmB,KAAK,GAAG,SAAS;AAAA,IACtC;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU;AAOd,MAAI,aAAa;AACjB,QAAM,qBAAqB,oBAAI,IAA+B;AAC9D,QAAM,uBAAuB,oBAAI,IAAiC;AAOlE,QAAM,2BAA2B,oBAAI,IAGnC;AACF,MAAI;AAGJ,MAAI;AAGJ,MAAI;AACJ,MAAI;AACJ,MAAI;AASJ,QAAM,yBAAgD,CAAC;AAEvD,iBAAe,yBACb,cACe;AACf,QAAI,iBAAiB,oBAAqB;AAC1C,0BAAsB;AACtB,UAAM,oBAAoB;AAC1B,eAAW,qBAAqB,UAAU,mBAAmB,CAAC;AAAA,EAChE;AAEA,QAAM,YAAY,kBAAkB;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,IACA,cAAc,CAAC,OAAO,YAAY;AAChC,oBAAc,EAAE,MAAM,eAAe,OAAO,MAAM,QAAQ,CAAC;AAAA,IAC7D;AAAA,EACF,CAAC;AAED,WAAS,yBAAyB,QAAsB;AACtD,eAAW,WAAW,mBAAmB,OAAO,GAAG;AACjD,cAAQ,QAAQ,EAAE,OAAO,OAAO,CAAC;AAAA,IACnC;AACA,uBAAmB,MAAM;AAAA,EAC3B;AAEA,WAAS,2BAA2B,QAAsB;AACxD,eAAW,WAAW,qBAAqB,OAAO,GAAG;AACnD,cAAQ,QAAQ,EAAE,UAAU,OAAO,OAAO,CAAC;AAAA,IAC7C;AACA,yBAAqB,MAAM;AAAA,EAC7B;AAEA,iBAAe,qBAAoC;AACjD,QAAI,CAAC,gBAAiB;AACtB,UAAM,4BAA4B;AAAA,MAChC,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,4BAEK;AACZ,QAAI,yBAAyB,KAAM,QAAO;AAC1C,+BAA2B,eAAe;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAWA,WAAS,0BACP,WACwB;AACxB,QAAI,aAAa,QAAQ,yBAAyB,KAAM,QAAO,CAAC;AAChE,UAAM,gBAAgB,IAAI,IAAI,UAAU,IAAI,CAAAE,UAAQA,MAAK,IAAI,CAAC;AAC9D,QAAI,cAAc,SAAS,EAAG,QAAO,CAAC;AACtC,UAAM,UAAU,0BAA0B;AAC1C,QAAI,WAAW,KAAM,QAAO,CAAC;AAC7B,UAAM,WAAW,QAAQ,oBAAoB,EAAE;AAQ/C,UAAM,sBAAsB,IAAI;AAAA,MAC9B,yBAAyB,KAAK;AAAA,IAChC;AACA,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,SAAS,cAAc;AACjC,4BAAoB,IAAI,QAAQ,UAAU;AAAA,MAC5C;AAAA,IACF;AACA,UAAM,WAAmC,CAAC;AAC1C,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,SAAS,YAAa;AAMlC,UAAI,QAAQ,eAAe,WAAW,QAAQ,eAAe,WAAW;AACtE;AAAA,MACF;AACA,iBAAW,SAAS,QAAQ,SAAS;AACnC,YACE,MAAM,SAAS,cACf,cAAc,IAAI,MAAM,IAAI,KAC5B,CAAC,oBAAoB,IAAI,MAAM,EAAE,GACjC;AACA,mBAAS,KAAK,EAAE,YAAY,MAAM,IAAI,UAAU,MAAM,KAAK,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAUA,WAAS,6BAA6B,MAI7B;AACP,UAAM,UAAU;AAChB,UAAM,WAAW,SAAS,SAAS,IAAI,KAAK,UAAU;AACtD,QAAI,WAAW,QAAQ,YAAY,KAAM;AACzC,YAAQ,SAAS,OAAO,KAAK,UAAU;AACvC,6BAAyB,IAAI,KAAK,YAAY;AAAA,MAC5C;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK,WAAW;AAAA,IAC3B,CAAC;AACD,QAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AAWA,WAAS,iCAA0C;AACjD,QAAI,yBAAyB,SAAS,KAAK,yBAAyB,MAAM;AACxE,aAAO;AAAA,IACT;AACA,UAAM,UAAU,0BAA0B;AAC1C,QAAI,WAAW,KAAM,QAAO;AAC5B,eAAW,CAAC,YAAY,SAAS,KAAK,0BAA0B;AAC9D,cAAQ,cAAc;AAAA,QACpB,MAAM;AAAA,QACN;AAAA,QACA,UAAU,UAAU;AAAA,QACpB,SAAS;AAAA,UACP,EAAE,MAAM,QAAQ,MAAM,oBAAoB,UAAU,MAAM,EAAE;AAAA,QAC9D;AAAA,QACA,SAAS,UAAU;AAAA,QACnB,WAAW,KAAK,IAAI;AAAA,MACtB,CAAC;AAAA,IACH;AACA,6BAAyB,MAAM;AAO/B,QAAI,CAAC,iBAAiB;AACpB,wBAAkB;AAAA,QAChBF,MAAK,SAAS,qBAAqB;AAAA,MACrC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAiBA,WAAS,+BACP,eACA,cACwB;AAMxB,mBAAe,OAAO;AAEtB,QAAI;AACJ,QAAI;AACJ,UAAM,OAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAClD,oBAAc;AACd,mBAAa;AAAA,IACf,CAAC;AACD,QAAI,UAAU;AAEd,UAAM,aAAa,MAAM;AACvB,UAAI,QAAS;AACb,gBAAU;AACV,sBAAgB;AAChB,YAAM,YAAY;AAChB,YAAI;AAGF,gBAAM,UAAU,MAAM,QAAQ;AAAA,YAC5B,MAAM;AAAA,YACN,OAAO,aAAa,SAAS,CAAC;AAAA,YAC9B,cAAc,aAAa;AAAA,YAC3B,MAAM,aAAa;AAAA,YACnB,aAAa,aAAa;AAAA,UAC5B,CAAC;AACD,gBAAM,QAAQ;AACd,sBAAY;AAAA,QACd,SAAS,OAAO;AACd,qBAAW,KAAK;AAAA,QAClB;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,SAAS,CAAC,WAAqB;AACnC,UAAI,QAAS;AACb,gBAAU;AACV,sBAAgB;AAChB,UAAI,UAAU,MAAM;AAClB,oBAAY;AAAA,MACd,OAAO;AACL,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAEA,oBAAgB;AAAA,MACd,UAAU,IAAI;AAAA,QACZ,cAAc,IAAI,UAAQ,CAAC,KAAK,YAAY,KAAK,QAAQ,CAAC;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,MAAM;AACzB;AAAA,QACE,aAAa,aAAa,UACxB,IAAI;AAAA,UACF;AAAA,QACF;AAAA,MACJ;AAAA,IACF;AACA,QAAI,aAAa,aAAa,SAAS;AACrC,mBAAa;AAAA,IACf,OAAO;AACL,mBAAa,aAAa,iBAAiB,SAAS,cAAc;AAAA,QAChE,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO,oBAAoB;AAAA,MACzB;AAAA,MACA,aAAa,aAAa;AAAA,IAC5B,CAAC;AAAA,EACH;AAEA,WAAS,oBAAoBG,QAIF;AACzB,UAAM,eAAe,MAAM;AACzB,WAAKA,OAAM,QAAQA,OAAM,aAAa,MAAM;AAAA,IAC9C;AACA,QAAIA,OAAM,aAAa;AACrB,UAAIA,OAAM,YAAY,SAAS;AAC7B,qBAAa;AAAA,MACf,OAAO;AACL,QAAAA,OAAM,YAAY,iBAAiB,SAAS,cAAc;AAAA,UACxD,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA,WAAKA,OAAM,KAAK;AAAA,QACd,MAAM;AACJ,UAAAA,OAAM,aAAa,oBAAoB,SAAS,YAAY;AAAA,QAC9D;AAAA,QACA,MAAM;AACJ,UAAAA,OAAM,aAAa,oBAAoB,SAAS,YAAY;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM,iBAAiB,MAAM;AAC3B,cAAM,UAAU,mBAAmB,IAAI,KAAK,UAAU;AACtD,YAAI,CAAC,SAAS;AACZ,uCAA6B,IAAI;AACjC;AAAA,QACF;AACA,2BAAmB,OAAO,KAAK,UAAU;AAQzC,yBAAiB,gBAAgB,IAAI,KAAK,YAAY,KAAK,MAAM;AACjE,gBAAQ,QAAQ,KAAK,MAAM;AAAA,MAC7B;AAAA,MACA,MAAM,mBAAmB,MAAM;AAC7B,cAAM,UAAU,qBAAqB,IAAI,KAAK,UAAU;AACxD,YAAI,CAAC,QAAS;AACd,6BAAqB,OAAO,KAAK,UAAU;AAC3C,gBAAQ,QAAQ;AAAA,UACd,UAAU,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH;AAAA,MACA,MAAM,kBAAkB,MAAM;AAC5B,YAAI,aAAa,MAAM;AACrB,gBAAM,IAAI,MAAM,4CAA4C;AAAA,QAC9D;AACA,cAAM,UAAU,MAAM,IAAI;AAAA,MAC5B;AAAA,MACA,MAAMA,OAAM;AAAA,IACd;AAAA,EACF;AAEA,iBAAe,2BAA2B,MAGU;AAClD,QACE,CAAC,8BAA8B;AAAA,MAC7B;AAAA,MACA,MAAM,qBAAqB,KAAK,UAAU;AAAA,IAC5C,CAAC,GACD;AACA,aAAO,EAAE,UAAU,KAAK;AAAA,IAC1B;AACA,kBAAc;AAAA,MACZ,MAAM;AAAA,MACN,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,IACnB,CAAC;AACD,QAAI,iBAAiB;AACnB,iBAAW,QAAQ;AAAA,QACjB;AAAA,QACA,KAAK;AAAA,MACP,GAAG;AACD,sBAAc,IAAI;AAAA,MACpB;AAAA,IACF;AACA,WAAO,IAAI,QAAQ,aAAW;AAC5B,2BAAqB,IAAI,KAAK,YAAY,EAAE,QAAQ,CAAC;AAAA,IACvD,CAAC;AAAA,EACH;AAEA,WAAS,qBAAqB,WAG5B;AACA,UAAM,eAAe;AAAA,MACnB,MAAM;AAAA,IACR;AACA,UAAM,cAAgC;AAAA,MACpC,GAAG,aAAa;AAAA,QAAI,YAClB,2BAA2B;AAAA,UACzB;AAAA,UACA;AAAA,UACA,iBAAiB;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,MACA,GAAG,UAAU;AAAA,QAAI,UACf,wBAAwB,MAAM,kBAAkB;AAAA,MAClD;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA,cAAc,CAAC,GAAG,YAAY;AAAA,IAChC;AAAA,EACF;AAEA,iBAAe,mBAAkC;AAC/C,kBAAc;AACd,kBAAc;AAEd,UAAM,UAAU;AAChB,gBAAY;AACZ,QAAI,CAAC,QAAS;AAEd,QAAI,eAAe;AACjB,YAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACvC;AACA,YAAQ,QAAQ;AAAA,EAClB;AAEA,iBAAe,iBACb,WACA,cACkB;AAClB,QAAI,oBAAoB;AACxB,QAAI,WAAW;AACb,YAAM,iBAAiB;AAKvB,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AACpD,UAAI,uBAAuB;AAGzB,cAAM,eAAe,OAAO;AAC5B,4BAAoB;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,EAAE,aAAa,aAAa,IAAI,qBAAqB,SAAS;AACpE,UAAM,YAAY,YAAY,IAAI,OAAK,EAAE,IAAI;AAI7C,UAAM,iBACJ,gBAAgB,wBACZ,0BAA0B,IAC1B,eAAe,OAAO,gBAAgB,cAAc;AAE1D,UAAM,EAAE,QAAQ,IAAI,MAAM,mBAAmB;AAAA,MAC3C,KAAK;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,gBACA,EAAE,SAAS,UAAmB,IAC9B,EAAE,OAAO,UAAU;AAAA,MACvB,GAAI,MAAM,SAAS,gBACf,EAAE,eAAe,MAAM,SAAS,cAAc,IAC9C,CAAC;AAAA,MACL,GAAI,gBAAgB,EAAE,OAAO,cAAc,IAAI,CAAC;AAAA,IAClD,CAAC;AACD,gBAAY;AACZ,QAAI,eAAe;AACjB,YAAM,UAAU,eAAe,EAAE,MAAM,QAAQ,CAAC;AAAA,IAClD;AAMA,UAAM,gBAAgB,eAAe,eAAe;AACpD,QAAI,eAAe;AACjB,wBAAkB,sBAAsBH,MAAK,SAAS,aAAa,CAAC;AAAA,IACtE;AAEA,sBAAkB,wBAAwB;AAAA,MACxC,kBAAkB;AAAA,MAClB,eAAe,UAAU,IAAI,CAAAE,UAAQA,MAAK,IAAI;AAAA,MAC9C,gBAAgB;AAAA,IAClB,CAAC;AAED,kBAAc,UAAU,UAAU,cAAY;AAC5C,UAAI,CAAC,gBAAiB;AACtB,YAAM,QAAQ,iBAAiB,QAAQ;AACvC,UAAI,CAAC,MAAO;AACZ,iBAAW,QAAQ,iBAAiB,OAAO,eAAe,GAAG;AAC3D,YAAI,aAAa;AACf,sBAAY,IAAI;AAAA,QAClB,WAAW,KAAK,SAAS,cAAc;AAErC,iCAAuB,KAAK,IAAI;AAAA,QAClC;AAAA,MAEF;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAOA,iBAAe,QAAQ,UAMa;AAClC,QAAI,SAAS;AACX,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAEA,UAAM,YAAY,SAAS;AAC3B,kBAAc,SAAS;AACvB,UAAM,sBAAsB,IAAI,gBAAgB;AAChD,UAAM,QAAQ,OAAO,WAAoC;AACvD,UAAI,oBAAoB,OAAO,QAAS;AACxC,UAAI,WAAW,QAAW;AACxB,4BAAoB,MAAM;AAAA,MAC5B,OAAO;AACL,4BAAoB,MAAM,MAAM;AAAA,MAClC;AACA,YAAM,QAAQ,QAAQ,WAAW,MAAM,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC1D;AAEA,UAAM,eAAe,YAAY;AAC/B,UAAI;AACF,cAAM,yBAAyB,SAAS,YAAY;AACpD,4BAAoB,OAAO,eAAe;AAO1C,cAAM,oCACJ,+BAA+B;AAEjC,cAAM,YAAY,KAAK,UAAU,UAAU,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,CAAC;AAClE,cAAM,eACJ,aAAa,QAAQ,cAAc;AACrC,YAAI,oBAAoB;AACxB,YAAI,cAAc;AAChB,8BAAoB,MAAM;AAAA,YACxB;AAAA,YACA,aAAa;AAAA,UACf;AACA,8BAAoB,OAAO,eAAe;AAC1C,+BAAqB;AAAA,QACvB;AAEA,YAAI,CAAC,mBAAmB;AACtB,gBAAM,oBAAoB;AAC1B,8BAAoB,OAAO,eAAe;AAAA,QAC5C;AACA,cAAM,6BAA6B;AAAA,UACjC,SAAS;AAAA,UACT,gBAAgB,MAAM;AAAA,UACtB;AAAA,QACF,CAAC;AACD,4BAAoB,OAAO,eAAe;AAI1C,0BAAkB,wBAAwB;AAAA,UACxC,kBAAkB,CAAC,GAAG,uBAAuB;AAAA,UAC7C,eAAe,UAAU,IAAI,CAAAA,UAAQA,MAAK,IAAI;AAAA,UAC9C,gBAAgB;AAAA,QAClB,CAAC;AAED,sBAAc,EAAE,MAAM,eAAe,CAAC;AAUtC,YAAI,mCAAmC;AACrC,wBAAc;AAAA,YACZ,MAAM;AAAA,YACN,cAAc,EAAE,SAAS,cAAc,KAAK,OAAU;AAAA,YACtD,OAAO;AAAA,cACL,aAAa;AAAA,gBACX,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,WAAW;AAAA,gBACX,YAAY;AAAA,cACd;AAAA,cACA,cAAc;AAAA,gBACZ,OAAO;AAAA,gBACP,MAAM;AAAA,gBACN,WAAW;AAAA,cACb;AAAA,YACF;AAAA,YACA,iBAAiB,EAAE,IAAI,EAAE,cAAc,KAAK,EAAE;AAAA,UAChD,CAAC;AAAA,QACH;AAEA,YAAI;AACJ,cAAM,UAAU;AAIhB,cAAM,WAAW,QAAQ,UAAU,SAAO;AACxC,gBAAM,KAAK,iBAAiB,GAAG;AAC/B,cAAI,CAAC,GAAI;AACT,gBAAM,MAAM,mBAAmB,EAAE;AACjC,cAAI,OAAO,CAAC,eAAe;AACzB,4BAAgB;AAAA,UAClB;AAAA,QACF,CAAC;AAED,YAAI;AACF,gBAAM,QAAQ,OAAO,SAAS,IAAI;AAElC,cAAI,eAAe;AAWjB,gBAAI,cAAc,aAAa,aAAa,EAAG;AAC/C,0BAAc,EAAE,MAAM,SAAS,OAAO,IAAI,MAAM,aAAa,EAAE,CAAC;AAChE;AAAA,UACF;AAEA,gBAAM,QAAQ,QAAQ,gBAAgB;AACtC,gBAAM,eAAe;AAAA,YACnB,SAAS;AAAA,YACT,KAAK;AAAA,UACP;AACA,gBAAM,QAAQ;AAAA,YACZ,aAAa;AAAA,cACX,OAAO,MAAM,OAAO;AAAA,cACpB,SAAS;AAAA,cACT,WAAW,MAAM,OAAO;AAAA,cACxB,YAAY,MAAM,OAAO;AAAA,YAC3B;AAAA,YACA,cAAc;AAAA,cACZ,OAAO,MAAM,OAAO;AAAA,cACpB,MAAM;AAAA,cACN,WAAW;AAAA,YACb;AAAA,UACF;AACA,wBAAc;AAAA,YACZ,MAAM;AAAA,YACN;AAAA,YACA,YAAY;AAAA,UACd,CAAC;AAAA,QACH,SAAS,KAAK;AAMZ,cAAI,cAAc,aAAa,GAAG,EAAG;AACrC,wBAAc,EAAE,MAAM,SAAS,OAAO,IAAI,CAAC;AAAA,QAC7C,UAAE;AACA,mBAAS;AAAA,QACX;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,cAAc,aAAa,GAAG,EAAG;AACrC,cAAM;AAAA,MACR;AAAA,IACF,GAAG;AAEH,UAAM,kBAAkB,CAAC;AACzB,UAAM,OAAO,YAAY,QAAQ,MAAM;AACrC,UAAI,YAAY,UAAU,iBAAiB;AACzC,qBAAa;AACb,sBAAc;AAAA,MAChB;AAAA,IACF,CAAC;AACD,iBAAa;AAAA,MACX,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAEA,WAAO,oBAAoB;AAAA,MACzB;AAAA,MACA,aAAa,SAAS;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,YAAkD;AAC/D,QAAI,SAAS;AACX,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,cAAU;AACV,qBAAiB,OAAO,MAAM,SAAS;AACvC,mBAAe,OAAO;AACtB,UAAM,aAAa;AACnB,UAAM,eAAe,YAAY,MAAM;AACvC,6BAAyB,oBAAoB;AAC7C,+BAA2B,oBAAoB;AAC/C,UAAM;AACN,UAAM,YAAY,KAAK,MAAM,MAAM;AAAA,IAAC,CAAC;AAOrC,QAAI;AACF,qCAA+B;AAAA,IACjC,QAAQ;AAAA,IAER;AAIA,QAAI,iBAAiB;AACnB,UAAI;AACF,cAAM,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MAGR;AAAA,IACF;AAEA,UAAM,iBAAiB;AACvB,iBAAa,QAAQ;AACrB,UAAME,IAAG,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAEnD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAWL;AAAA,MACX,sBAAsB;AAAA,MACtB,MAAM,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,cAAgC;AAAA,IACpC,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA;AAAA;AAAA,IAGhB,GAAI,eAAe,KAAK,EAAE,SAAS,cAAc,GAAG,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,IAMzD,cAAc,OACZ,eACoC;AACpC,UAAI,WAAW,gBAAgB,SAAS,QAAQ;AAC9C,cAAM,IAAIM,mCAAkC;AAAA,UAC1C,SAAS;AAAA,UACT,WAAWN;AAAA,QACb,CAAC;AAAA,MACH;AACA,aAAO,QAAQ;AAAA,QACb,MAAM,gBAAgB,WAAW,MAAM;AAAA,QACvC,OAAO,WAAW,SAAS,CAAC;AAAA,QAC5B,cAAc,WAAW;AAAA,QACzB,MAAM,WAAW;AAAA,QACjB,aAAa,WAAW;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,IAEA,gBAAgB,OACd,iBACoC;AACpC,UAAI,aAAa,gBAAgB,SAAS,QAAQ;AAChD,cAAM,IAAIM,mCAAkC;AAAA,UAC1C,SAAS;AAAA,UACT,WAAWN;AAAA,QACb,CAAC;AAAA,MACH;AACA,UAAI,cAAc,MAAM;AACtB,sBAAc,aAAa;AAC3B,eAAO,oBAAoB;AAAA,UACzB,MAAM,WAAW;AAAA,UACjB,aAAa,aAAa;AAAA,UAC1B,OAAO,WAAW;AAAA,QACpB,CAAC;AAAA,MACH;AAEA,UAAI,SAAS;AACX,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AASA,YAAM,wBAAwB;AAAA,QAC5B,aAAa,SAAS,CAAC;AAAA,MACzB;AACA,UAAI,sBAAsB,SAAS,GAAG;AACpC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAUA,aAAO,QAAQ;AAAA,QACb,MAAM;AAAA,QACN,OAAO,aAAa,SAAS,CAAC;AAAA,QAC9B,cAAc,aAAa;AAAA,QAC3B,MAAM,aAAa;AAAA,QACnB,aAAa,aAAa;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,IAEA,WAAW,OAAO,uBAAgC;AAChD,UAAI,SAAS;AACX,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AAOA,YAAM,WAAW,QAAQ,kBAAkB;AAAA,IAC7C;AAAA,IAEA,WAAW,YAAY;AACrB,UAAI,QAAS;AACb,gBAAU;AACV,uBAAiB,OAAO,MAAM,SAAS;AACvC,qBAAe,OAAO;AACtB,YAAM,gBAAgB;AACtB,YAAM,eAAe,eAAe,MAAM;AAC1C,+BAAyB,oBAAoB;AAC7C,iCAA2B,oBAAoB;AAC/C,YAAM;AACN,YAAM,eAAe,KAAK,MAAM,MAAM;AAAA,MAAC,CAAC;AACxC,YAAM,iBAAiB;AACvB,mBAAa,QAAQ;AACrB,YAAMK,IAAG,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACrD;AAAA,IAEA;AAAA,IAEA,UAAU,YAAkD;AAC1D,UAAI,cAAc,QAAQ,mBAAmB,OAAO,GAAG;AACrD,yBAAiB,IAAI,MAAM,WAAW,WAAW;AACjD,YAAI,iBAAiB;AACnB,cAAI;AACF,kBAAM,mBAAmB;AAAA,UAC3B,QAAQ;AAAA,UAMR;AAAA,QACF;AACA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,WAAWL;AAAA,UACX,sBAAsB;AAAA,UACtB,MAAM,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QACjD;AAAA,MACF;AACA,aAAO,OAAO;AAAA,IAChB;AAAA,IAEA,eAAe,YAAiD;AAC9D,UAAI,SAAS;AACX,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AACA,UACE,cAAc,SACb,mBAAmB,OAAO,KAAK,qBAAqB,OAAO,IAC5D;AACA,yBAAiB,IAAI,MAAM,WAAW,WAAW;AACjD,YAAI,iBAAiB;AACnB,cAAI;AACF,kBAAM,mBAAmB;AAAA,UAC3B,QAAQ;AAAA,UAMR;AAAA,QACF;AACA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,WAAWA;AAAA,UACX,sBAAsB;AAAA,UACtB,MAAM,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QACjD;AAAA,MACF;AAWA,mBAAa;AACb,YAAM,gBAAgB;AACtB,YAAM,eAAe,MAAM;AAC3B,qBAAe,OAAO;AACtB,YAAM,eAAe,KAAK,MAAM,MAAM;AAAA,MAAC,CAAC;AAQxC,UAAI;AACF,uCAA+B;AAAA,MACjC,QAAQ;AAAA,MAER;AAEA,UAAI,iBAAiB;AACnB,YAAI;AACF,gBAAM,mBAAmB;AAAA,QAC3B,QAAQ;AAAA,QAIR;AAAA,MACF;AAEA,gBAAU;AACV,uBAAiB,OAAO,MAAM,SAAS;AACvC,+BAAyB,sBAAsB;AAC/C,iCAA2B,sBAAsB;AACjD,YAAM,iBAAiB;AACvB,mBAAa,QAAQ;AACrB,YAAMK,IAAG,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAEnD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,WAAWL;AAAA,QACX,sBAAsB;AAAA,QACtB,MAAM,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AACF,GAE4B;AAC1B,MAAI,cAAc,KAAM,QAAO,CAAC;AAChC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACtD,QAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AACtE,YAAM,IAAI;AAAA,QACR,iBAAiB,KAAK,UAAU,IAAI,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,aAAa,OAAyB;AAC7C,MAAI,SAAS,KAAM,QAAO;AAC1B,MACE,OAAO,UAAU,YAChB,MAA6B,SAAS,cACvC;AACA,WAAO;AAAA,EACT;AACA,QAAM,OACJ,OAAO,UAAU,WACb,QACA,iBAAiB,QACf,MAAM,UACN,OAAO,KAAK;AACpB,SAAO,gDAAgD,KAAK,IAAI;AAClE;AAEA,SAAS,eAAe,MAAwC;AAC9D,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,IAChC,SAAS;AAAA,EACX;AACF;AAEA,eAAe,uBAAuB,OAOY;AAChD,QAAM,WAAW,MAAM,MAAM,gBAAgB;AAAA,IAC3C,YAAY,MAAM;AAAA,IAClB,YAAY,MAAM;AAAA,EACpB,CAAC;AACD,MAAI,SAAS,SAAU,QAAO;AAC9B,SAAO;AAAA,IACL,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,EACH;AACF;AAEA,SAAS,8BAA8B,OAG3B;AACV,MAAI,MAAM,mBAAmB,YAAa,QAAO;AACjD,MAAI,MAAM,mBAAmB,cAAe,QAAO,MAAM,SAAS;AAClE,SAAO,MAAM,SAAS,UAAU,MAAM,SAAS;AACjD;AAEA,SAAS,2BAA2B,OAOjB;AACjB,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYO,MAAK,OAAO,EAAE,WAAWA,MAAK,OAAO,EAAE,CAAC;AAAA,QACpD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,MAAM,MAAM,MAAM,UAAU,WAAW,OAAO,SAAS;AAC7D,iBAAO,eAAe,IAAI,SAAS,MAAM,CAAC;AAAA,QAC5C;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,WAAWA,MAAK,OAAO;AAAA,UACvB,SAASA,MAAK,OAAO;AAAA,QACvB,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,MAAM,UAAU,UAAU,OAAO,WAAW,OAAO,OAAO;AAChE,iBAAO,eAAe,SAAS,OAAO,SAAS,EAAE;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,WAAWA,MAAK,OAAO;AAAA,UACvB,YAAYA,MAAK,OAAO;AAAA,UACxB,YAAYA,MAAK,OAAO;AAAA,QAC1B,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,MAAM,UAAU;AAAA,YACpB,OAAO;AAAA,YACP,OAAO;AAAA,YACP,OAAO;AAAA,UACT;AACA,iBAAO,eAAe,UAAU,OAAO,SAAS,EAAE;AAAA,QACpD;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,SAASA,MAAK,OAAO;AAAA,UACrB,SAASA,MAAK;AAAA,YACZA,MAAK,OAAO,EAAE,aAAa,sBAAsB,CAAC;AAAA,UACpD;AAAA,QACF,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ,QAAQ;AACxC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,SAAmB,CAAC;AAC1B,gBAAM,SAAS,MAAM,MAAM,UAAU,KAAK,OAAO,SAAS,KAAK;AAAA,YAC7D,OAAO,MAAM;AACX,qBAAO,KAAK,IAAI;AAAA,YAClB;AAAA,YACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,YAC3B,GAAI,OAAO,OAAO,YAAY,WAC1B,EAAE,SAAS,OAAO,QAAQ,IAC1B,CAAC;AAAA,UACP,CAAC;AACD,gBAAM,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AACjD,gBAAM,OAAO,GAAG,GAAG,GACjB,OAAO,YAAY,OAAO;AAAA;AAAA,QAAa,OAAO,QAAQ,MAAM,EAC9D,GAAG,KAAK;AACR,iBAAO,eAAe,IAAI;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,SAASA,MAAK,OAAO;AAAA,UACrB,MAAMA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,UACjC,MAAMA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,UACjC,YAAYA,MAAK,SAASA,MAAK,QAAQ,CAAC;AAAA,UACxC,SAASA,MAAK,SAASA,MAAK,QAAQ,CAAC;AAAA,UACrC,SAASA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,UACpC,OAAOA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,QACpC,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,MAAM,MAAM,MAAM,UAAU,UAAU,OAAO,SAAS,MAAM;AAClE,iBAAO,eAAe,GAAG;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,SAASA,MAAK,OAAO;AAAA,UACrB,MAAMA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,UACjC,OAAOA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,QACpC,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,UAAU,MAAM,MAAM,UAAU;AAAA,YACpC,OAAO;AAAA,YACP,OAAO,QAAQ;AAAA,YACf,OAAO,SAAS;AAAA,UAClB;AACA,iBAAO,eAAe,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC1C;AAAA,MACF,CAAC;AAAA,IACH,KAAK;AACH,aAAO,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAYA,MAAK,OAAO;AAAA,UACtB,MAAMA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,UACjC,OAAOA,MAAK,SAASA,MAAK,OAAO,CAAC;AAAA,QACpC,CAAC;AAAA,QACD,MAAM,QAAQ,YAAY,QAAQ;AAChC,gBAAM,SAAS,MAAM,uBAAuB;AAAA,YAC1C;AAAA,YACA,YAAY;AAAA,YACZ,iBAAiB,MAAM;AAAA,UACzB,CAAC;AACD,cAAI,OAAQ,QAAO;AACnB,gBAAM,UAAU,MAAM,MAAM,UAAU;AAAA,YACpC,OAAO,QAAQ;AAAA,YACf,OAAO,SAAS;AAAA,UAClB;AACA,iBAAO,eAAe,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC1C;AAAA,MACF,CAAC;AAAA,EACL;AACF;AAEA,SAAS,wBACP,MACA,SACgB;AAChB,QAAM,SAAS,KAAK,eAAe;AAAA,IACjC,MAAM;AAAA,IACN,YAAY,CAAC;AAAA,IACb,sBAAsB;AAAA,EACxB;AACA,SAAO,WAAW;AAAA,IAChB,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK,eAAe,wBAAwB,KAAK,IAAI;AAAA,IAClE,YAAY,4BAA4B,MAAM;AAAA,IAC9C,MAAM,QAAQ,YAAY;AACxB,aAAO,IAAI,QAAiB,aAAW;AACrC,gBAAQ,IAAI,YAAY,EAAE,QAAQ,CAAC;AAAA,MACrC,CAAC,EAAE,KAAK,YAAU,eAAe,oBAAoB,MAAM,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AACH;;;AFpwDA,IAAM,gBAAgB,qBAAqB,OAAO;AAwClD,IAAM,mBAAmB;AAAA,EACvB,MAAM,WAAW,QAAQ;AAAA,IACvB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaC,GAAE,OAAO;AAAA,MACpB,WAAWA,GAAE,OAAO;AAAA,IACtB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,OAAO,WAAW,SAAS;AAAA,IACzB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GAAE,OAAO;AAAA,MACpB,SAASA,GAAE,OAAO;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,MAAM,WAAW,QAAQ;AAAA,IACvB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GAAE,OAAO;AAAA,MACpB,YAAYA,GAAE,OAAO;AAAA,MACrB,YAAYA,GAAE,OAAO;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAAA,EACD,MAAM,WAAW,QAAQ;AAAA,IACvB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,SAASA,GAAE,OAAO;AAAA,MAClB,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AAAA,EACD,MAAM,WAAW,QAAQ;AAAA,IACvB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,SAASA,GAAE,OAAO;AAAA,MAClB,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,YAAYA,GAAE,QAAQ,EAAE,SAAS;AAAA,MACjC,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,MAC9B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AAAA,EACD,MAAM,WAAW,QAAQ;AAAA,IACvB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,SAASA,GAAE,OAAO;AAAA,MAClB,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AAAA,EACD,IAAI;AAAA,IACF,GAAG,KAAK;AAAA,MACN,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC;AAAA,MACD,cAAcA,GAAE,QAAQ;AAAA,IAC1B,CAAC;AAAA,IACD,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AACF;AAEO,SAAS,SACd,WAA8B,CAAC,GACK;AACpC,SAAO;AAAA,IACL,sBAAsB;AAAA,IACtB,WAAW;AAAA,IACX,cAAc;AAAA,IACd,8BAA8B;AAAA,IAC9B,8BAA8B;AAAA,IAC9B,sBAAsB;AAAA,IACtB,SAAS,OAAM,cAAa;AAC1B,YAAM,iBAAiB,UAAU,gBAAgB,UAAU;AAC3D,YAAM,aAAa,gBAAgB;AAInC,aAAO,gBAAgB;AAAA,QACrB,WAAW,UAAU;AAAA,QACrB,gBAAgB,UAAU;AAAA,QAC1B,gBAAgB,UAAU;AAAA,QAC1B,QAAQ,UAAU,UAAU,CAAC;AAAA,QAC7B,UAAU;AAAA,UACR,GAAI,SAAS,OAAO,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,UAC/C,GAAI,SAAS,QAAQ,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC;AAAA,UAClD,GAAI,SAAS,gBACT,EAAE,eAAe,SAAS,cAAc,IACxC,CAAC;AAAA,UACL,GAAI,SAAS,aAAa,EAAE,YAAY,SAAS,WAAW,IAAI,CAAC;AAAA,UACjE,GAAI,SAAS,qBACT,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;AAAA,QACP;AAAA,QACA,WAAW;AAAA,QACX,UAAU,kBAAkB;AAAA,QAC5B,gBAAgB,UAAU;AAAA,QAC1B,sBAAsB,UAAU;AAAA,QAChC,GAAI,YAAY,kBACZ,EAAE,uBAAuB,WAAW,gBAAgB,IACpD,CAAC;AAAA,QACL,GAAI,UAAU,cACV,EAAE,aAAa,UAAU,YAAY,IACrC,CAAC;AAAA,QACL,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;AAAA,MAC7D,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;Ae3KO,IAAM,KAAK,SAAS;","names":["z","mkdir","rm","path","Type","HarnessCapabilityUnsupportedError","z","getAiGatewayAuthFromEnv","path","path","writeFile","path","path","isInsidePath","mkdir","readFile","writeFile","path","shellQuote","HARNESS_ID","path","mkdir","tool","input","rm","HarnessCapabilityUnsupportedError","Type","z"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness-pi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.83",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@earendil-works/pi-coding-agent": "^0.80.10",
|
|
31
31
|
"pi-mcp-adapter": "2.12.1",
|
|
32
32
|
"typebox": "^1.1.38",
|
|
33
|
-
"@ai-sdk/
|
|
34
|
-
"@ai-sdk/
|
|
33
|
+
"@ai-sdk/harness": "1.0.81",
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.28"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"zod": "^3.25.76 || ^4.1.8"
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"tsup": "^8.5.1",
|
|
42
42
|
"typescript": "5.8.3",
|
|
43
43
|
"zod": "3.25.76",
|
|
44
|
-
"@ai-sdk/sandbox-just-bash": "1.0.
|
|
44
|
+
"@ai-sdk/sandbox-just-bash": "1.0.81",
|
|
45
45
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
package/src/pi-remote-ops.ts
CHANGED