pi2dsh 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"pi-coding-agent-f3_hNCpd.mjs","names":["randomUUID","getDefaultAgentDir","resolvePath","join","existsSync","normalizePath","stat","readdir","resolve","DEFAULT_MAX_LINES","DEFAULT_MAX_BYTES","GREP_MAX_LINE_LENGTH","splitLinesForCounting","formatSize","truncateHead","truncateTail","truncateStringToBytesFromEnd","truncateLine","fileMutationQueues","registrationQueue","isMissingPathError","getMutationQueueKey","withFileMutationQueue","getBinDir","joinBinDir","getAgentDirForBin","isLegacyWslBashPath","getBashShellConfig","findBashOnPath","getShellConfig","DEFAULT_MAX_BYTES","UNICODE_SPACES","normalizeWindowsShellPath","normalizePath","resolvePath","nodeResolvePath","resolvePath","replaceTabs","wrapToolDefinition","getShellConfig","fsAccess","spawn","DEFAULT_MAX_BYTES","wrapToolDefinition","resolvePath","fsReadFile","fsAccess","constants","trimTrailingEmptyLines","toPosixPath","resolvePath","replaceTabs","DEFAULT_MAX_BYTES","wrapToolDefinition","access","constants","readFile","fsReadFile","fsWriteFile","fsAccess","constants","wrapToolDefinition","fsWriteFile","fsMkdir","replaceTabs","dirname","wrapToolDefinition","DEFAULT_LIMIT","fsStat","fsReadFile","DEFAULT_MAX_BYTES","spawn","createInterface","wrapToolDefinition","DEFAULT_LIMIT","DEFAULT_MAX_BYTES","spawn","createInterface","wrapToolDefinition","fsStat","fsReaddir","DEFAULT_MAX_BYTES","path","nodePath","wrapToolDefinition","generateSummary","generateSummaryWithUsage","compact","generateBranchSummary","nodeResolvePath","CONFIG_DIR_NAME","sep","relative","join","existsSync","readFileSync","dirname","basename","resolve","vendoredCompact","vendoredGenerateSummary","vendoredGenerateSummaryWithUsage","vendoredGenerateBranchSummary","agentDirOf","#options","#provider"],"sources":["../src/capability.ts","../src/compat/vendor/pi-image-dimensions.ts","../src/compat/vendor/pi-messages.ts","../src/compat/vendor/pi-session-manager.ts","../src/compat/vendor/pi-truncate.ts","../src/compat/vendor/pi-file-mutation-queue.ts","../src/compat/vendor/pi-extension-runtime.ts","../src/compat/vendor/pi-tools/visual-truncate.ts","../src/compat/vendor/pi-tools/child-process.ts","../src/compat/vendor/pi-tools/shell.ts","../src/compat/vendor/pi-tools/truncate.ts","../src/compat/vendor/pi-tools/output-accumulator.ts","../src/compat/vendor/pi-tools/ansi.ts","../src/compat/vendor/pi-tools/paths.ts","../src/compat/vendor/pi-tools/render-utils.ts","../src/compat/vendor/pi-tools/tool-definition-wrapper.ts","../src/compat/vendor/pi-tools/bash.ts","../src/compat/vendor/pi-tools/mime.ts","../src/compat/vendor/pi-tools/path-utils.ts","../src/compat/vendor/pi-tools/read.ts","../src/compat/vendor/pi-tools/diff-component.ts","../src/compat/vendor/pi-tools/edit-diff.ts","../src/compat/vendor/pi-tools/file-mutation-queue.ts","../src/compat/vendor/pi-tools/edit.ts","../src/compat/vendor/pi-tools/write.ts","../src/compat/vendor/pi-tools/grep.ts","../src/compat/vendor/pi-tools/find.ts","../src/compat/vendor/pi-tools/ls.ts","../src/compat/vendor/pi-compaction.ts","../src/compat/vendor/pi-frontmatter.ts","../src/compat/vendor/pi-tool-wrapper.ts","../src/compat/vendor/pi-paths.ts","../src/compat/vendor/pi-trust-store.ts","../src/compat/vendor/pi-skills-load.ts","../src/compat/vendor/pi-skills-format.ts","../src/compat/vendor/pi-shell-config.ts","../src/compat/pi-coding-agent.ts"],"sourcesContent":["// Capability-gap handling: what happens when a migrated Pi package reaches a\n// Pi capability that has no DSH mapping.\n//\n// The rules (docs/STANDARDS.md \"能力缺口分级处置\"):\n// 1. Whatever Pi's own protocol can express honestly, use Pi's channel — a\n// host refusal (`{ cancelled: true }`), a host-defined no-op (shutdown) —\n// never a bare throw and never a fabricated success.\n// 2. When only an error is honest (the return value cannot be faked), throw\n// a structured PiCapabilityError the package can catch like any Pi error.\n// 3. Every gap hit is recorded per package in the host-level ledger and\n// reported to the USER once per (package, capability): what stopped\n// working, that the rest of the plugin keeps working, and how to remove\n// the plugin if the gap is its main purpose. The middle layer cannot know\n// which feature is \"core\" to a plugin — the ledger gives the user the\n// facts to decide.\n// 4. A gap hit while the package's entry code is still mounting means the\n// package cannot start at all: it is marked unusable and reported as such.\n\nexport type PackageHealthStatus = 'ok' | 'degraded' | 'unusable'\n\nexport interface PackageHealth {\n status: PackageHealthStatus\n /** Pi capability names this package has hit, in first-hit order. */\n gaps: readonly string[]\n}\n\nexport interface CapabilityGapOptions {\n /** The Pi capability, as the package sees it (e.g. \"ctx.fork\"). */\n capability: string\n /** Why DSH has no mapping, in one sentence. */\n reason: string\n /** What the caller can do about it, in one sentence. */\n guidance: string\n /** The migrated package that hit the gap, when known. */\n packageName?: string\n}\n\n/**\n * The structured error for capability gaps where only failing is honest.\n * A plain Error subclass on purpose: Pi packages catch it exactly like any\n * error a real Pi host throws.\n */\nexport class PiCapabilityError extends Error {\n readonly capability: string\n readonly packageName: string | undefined\n\n constructor(options: CapabilityGapOptions) {\n super(`pi2dsh: ${options.capability} is not available on DSH — ${options.reason} ${options.guidance}`)\n this.name = 'PiCapabilityError'\n this.capability = options.capability\n this.packageName = options.packageName\n }\n}\n\ninterface LedgerEntry {\n status: PackageHealthStatus\n gaps: string[]\n}\n\nconst HEALTHY: PackageHealth = Object.freeze({ status: 'ok', gaps: Object.freeze([]) as readonly string[] })\n\n/**\n * Host-level record of capability gaps, one instance per DSH host (it lives in\n * SharedHostState). Emits ONE user-facing notice per (package, capability):\n * repeated hits of the same gap change nothing the user needs to hear again.\n */\nexport class CapabilityLedger {\n private readonly noticed = new Set<string>()\n private readonly packages = new Map<string, LedgerEntry>()\n\n constructor(private readonly emit: (message: string) => void) {}\n\n /**\n * Record a degraded capability: this feature of the package does not work on\n * DSH, the rest of the package keeps working. Reported to the user once.\n */\n reportDegraded(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.mark(packageName, options.capability, 'degraded')\n this.notice(packageName, options.capability, () =>\n `[pi2dsh] plugin \"${packageName}\": the Pi capability ${options.capability} is not available on DSH `\n + `(${options.reason}) That feature will not work; the plugin's other features keep working. `\n + `${options.guidance} If this capability is the plugin's main purpose, remove it: dsh plugin remove ${packageName}`)\n }\n\n /**\n * Record a host-owned decision (e.g. shutdown): the host refused or absorbed\n * the request through a channel Pi itself defines. Not a package defect, so\n * package health stays untouched; the user still learns what happened, once.\n */\n reportHostDecision(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.notice(packageName, options.capability, () =>\n `[pi2dsh] plugin \"${packageName}\": ${options.capability} — ${options.reason} ${options.guidance}`)\n }\n\n /**\n * Startup-time reference detection: the package's source imports a\n * host-owned symbol that cannot work on DSH. Reported at mount so the user\n * learns BEFORE any code path runs into it; health is untouched because an\n * import alone proves nothing about usage — construction still fails\n * structurally and marks the package then.\n */\n reportStartupReference(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.notice(packageName, `${options.capability}#startup-reference`, () =>\n `[pi2dsh] startup check: plugin \"${packageName}\" imports ${options.capability}, which is not available on DSH `\n + `(${options.reason}) If the plugin's main purpose depends on it, it will not work here — `\n + `consider removing it: dsh plugin remove ${packageName}`)\n }\n\n /**\n * Record that a package could not even mount because its entry code needs a\n * missing capability. The package is marked unusable for this run.\n */\n reportUnusable(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.mark(packageName, options.capability, 'unusable')\n this.notice(packageName, `${options.capability}#mount`, () =>\n `[pi2dsh] plugin \"${packageName}\" could not start: its startup code needs the Pi capability `\n + `${options.capability}, which is not available on DSH (${options.reason}) `\n + `The plugin is unusable in this composition — remove it: dsh plugin remove ${packageName}`)\n }\n\n healthOf(packageName: string): PackageHealth {\n const entry = this.packages.get(packageName)\n if (entry === undefined) return HEALTHY\n return { status: entry.status, gaps: [...entry.gaps] }\n }\n\n /** Every package with a recorded gap, for surfacing in mount summaries. */\n snapshot(): ReadonlyMap<string, PackageHealth> {\n const view = new Map<string, PackageHealth>()\n for (const [name, entry] of this.packages) {\n view.set(name, { status: entry.status, gaps: [...entry.gaps] })\n }\n return view\n }\n\n private mark(packageName: string, capability: string, status: 'degraded' | 'unusable'): void {\n const entry = this.packages.get(packageName) ?? { status: 'ok' as PackageHealthStatus, gaps: [] }\n if (!entry.gaps.includes(capability)) entry.gaps.push(capability)\n // unusable outranks degraded; degraded never downgrades unusable.\n entry.status = entry.status === 'unusable' ? 'unusable' : status\n this.packages.set(packageName, entry)\n }\n\n private notice(packageName: string, capability: string, build: () => string): void {\n const key = `${packageName}\u0000${capability}`\n if (this.noticed.has(key)) return\n this.noticed.add(key)\n this.emit(build())\n }\n}\n","// Image dimensions read straight from the file header, for the four inline\n// formats Pi accepts. Pi gets these from its resize worker; this bridge does\n// not resize, but the caller is still owed the real numbers — Pi's\n// `ResizedImage` contract has four dimension fields, and inventing zeros\n// there would be a lie a package cannot detect.\n//\n// Header offsets only: no decoding, no dependency.\n\n/** Width and height in pixels, or undefined when the header is not one we can read. */\nexport interface ImageDimensions {\n width: number\n height: number\n}\n\n/**\n * Read the pixel dimensions out of an image header.\n * @param bytes - the complete image file.\n * @param mimeType - the declared type, used to pick the header layout.\n * @returns the dimensions, or undefined when the header is absent or malformed.\n */\nexport function readImageDimensions(bytes: Uint8Array, mimeType: string): ImageDimensions | undefined {\n const type = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (type === 'image/png') return pngDimensions(bytes)\n if (type === 'image/jpeg') return jpegDimensions(bytes)\n if (type === 'image/gif') return gifDimensions(bytes)\n if (type === 'image/webp') return webpDimensions(bytes)\n return undefined\n}\n\nconst view = (bytes: Uint8Array): DataView => new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\n/** PNG: an 8-byte signature, then an IHDR chunk whose first two fields are the size. */\nfunction pngDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 24) return undefined\n if (bytes[0] !== 0x89 || bytes[1] !== 0x50 || bytes[2] !== 0x4E || bytes[3] !== 0x47) return undefined\n const data = view(bytes)\n return { width: data.getUint32(16, false), height: data.getUint32(20, false) }\n}\n\n/** GIF: dimensions sit at a fixed offset, little-endian. */\nfunction gifDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 10) return undefined\n if (bytes[0] !== 0x47 || bytes[1] !== 0x49 || bytes[2] !== 0x46) return undefined\n const data = view(bytes)\n return { width: data.getUint16(6, true), height: data.getUint16(8, true) }\n}\n\n/**\n * JPEG: walk the marker segments to the frame header (SOF0…SOF15, skipping\n * the four that are not frames), which carries the size.\n */\nfunction jpegDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 4 || bytes[0] !== 0xFF || bytes[1] !== 0xD8) return undefined\n const data = view(bytes)\n let offset = 2\n while (offset + 9 < bytes.length) {\n if (bytes[offset] !== 0xFF) { offset += 1; continue }\n const marker = bytes[offset + 1] ?? 0\n // Standalone markers carry no length payload.\n if (marker === 0xD8 || marker === 0x01 || (marker >= 0xD0 && marker <= 0xD7)) { offset += 2; continue }\n const length = data.getUint16(offset + 2, false)\n const isFrame = marker >= 0xC0 && marker <= 0xCF\n && marker !== 0xC4 && marker !== 0xC8 && marker !== 0xCC\n if (isFrame) return { height: data.getUint16(offset + 5, false), width: data.getUint16(offset + 7, false) }\n if (length < 2) return undefined\n offset += 2 + length\n }\n return undefined\n}\n\n/** WebP: three container variants (lossy, lossless, extended), each with its own size layout. */\nfunction webpDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 30) return undefined\n const tag = String.fromCharCode(...bytes.slice(0, 4)) + String.fromCharCode(...bytes.slice(8, 12))\n if (tag !== 'RIFFWEBP') return undefined\n const data = view(bytes)\n const format = String.fromCharCode(...bytes.slice(12, 16))\n if (format === 'VP8 ') {\n return { width: data.getUint16(26, true) & 0x3FFF, height: data.getUint16(28, true) & 0x3FFF }\n }\n if (format === 'VP8L') {\n const bits = data.getUint32(21, true)\n return { width: (bits & 0x3FFF) + 1, height: ((bits >> 14) & 0x3FFF) + 1 }\n }\n if (format === 'VP8X') {\n const width = 1 + ((bytes[24] ?? 0) | ((bytes[25] ?? 0) << 8) | ((bytes[26] ?? 0) << 16))\n const height = 1 + ((bytes[27] ?? 0) | ((bytes[28] ?? 0) << 8) | ((bytes[29] ?? 0) << 16))\n return { width, height }\n }\n return undefined\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\n/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage, ImageContent, Message, TextContent } from \"./pi-types.ts\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\ttokensBefore: number;\n\ttimestamp: number;\n}\n\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\tlet text = `Ran \\`${msg.command}\\`\\n`;\n\tif (msg.output) {\n\t\ttext += `\\`\\`\\`\\n${msg.output}\\n\\`\\`\\``;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated && msg.fullOutputPath) {\n\t\ttext += `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`;\n\t}\n\treturn text;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number,\n\ttimestamp: string,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary: summary,\n\t\ttokensBefore,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\t// Skip messages excluded from context (!! prefix)\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"assistant\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\nimport type { AgentMessage } from \"./pi-types.ts\";\nimport type { ImageContent, Message, TextContent, Usage } from \"./pi-types.ts\";\nimport { uuidv7 } from \"./pi-uuid.ts\";\nimport { randomUUID } from \"crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\tcreateReadStream,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { createInterface } from \"readline\";\nimport { StringDecoder } from \"string_decoder\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir, normalizePath, resolvePath } from \"./pi-config-shim.ts\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CustomMessage,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"./pi-messages.ts\";\n\nexport const CURRENT_SESSION_VERSION = 3;\n\nexport interface SessionHeader {\n\ttype: \"session\";\n\tversion?: number; // v1 sessions don't have this\n\tid: string;\n\ttimestamp: string;\n\tcwd: string;\n\tparentSession?: string;\n}\n\nexport interface NewSessionOptions {\n\tid?: string;\n\tparentSession?: string;\n}\n\nexport interface SessionEntryBase {\n\ttype: string;\n\tid: string;\n\tparentId: string | null;\n\ttimestamp: string;\n}\n\nexport interface SessionMessageEntry extends SessionEntryBase {\n\ttype: \"message\";\n\tmessage: AgentMessage;\n}\n\nexport interface ThinkingLevelChangeEntry extends SessionEntryBase {\n\ttype: \"thinking_level_change\";\n\tthinkingLevel: string;\n}\n\nexport interface ModelChangeEntry extends SessionEntryBase {\n\ttype: \"model_change\";\n\tprovider: string;\n\tmodelId: string;\n}\n\nexport interface CompactionEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"compaction\";\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\t/** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */\n\tdetails?: T;\n\t/** Usage from the LLM call(s) that generated this summary, if available */\n\tusage?: Usage;\n\t/** True if generated by an extension, undefined/false if pi-generated (backward compatible) */\n\tfromHook?: boolean;\n}\n\nexport interface BranchSummaryEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"branch_summary\";\n\tfromId: string;\n\tsummary: string;\n\t/** Extension-specific data (not sent to LLM) */\n\tdetails?: T;\n\t/** Usage from the LLM call that generated this summary, if available */\n\tusage?: Usage;\n\t/** True if generated by an extension, false if pi-generated */\n\tfromHook?: boolean;\n}\n\n/**\n * Custom entry for extensions to store extension-specific data in the session.\n * Use customType to identify your extension's entries.\n *\n * Purpose: Persist extension state across session reloads. On reload, extensions can\n * scan entries for their customType and reconstruct internal state.\n *\n * Does NOT participate in LLM context (ignored by buildSessionContext).\n * For injecting content into context, see CustomMessageEntry.\n */\nexport interface CustomEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"custom\";\n\tcustomType: string;\n\tdata?: T;\n}\n\n/** Label entry for user-defined bookmarks/markers on entries. */\nexport interface LabelEntry extends SessionEntryBase {\n\ttype: \"label\";\n\ttargetId: string;\n\tlabel: string | undefined;\n}\n\n/** Session metadata entry (e.g., user-defined display name). */\nexport interface SessionInfoEntry extends SessionEntryBase {\n\ttype: \"session_info\";\n\tname?: string;\n}\n\n/**\n * Custom message entry for extensions to inject messages into LLM context.\n * Use customType to identify your extension's entries.\n *\n * Unlike CustomEntry, this DOES participate in LLM context.\n * The content is converted to a user message in buildSessionContext().\n * Use details for extension-specific metadata (not sent to LLM).\n *\n * display controls TUI rendering:\n * - false: hidden entirely\n * - true: rendered with distinct styling (different from user messages)\n */\nexport interface CustomMessageEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"custom_message\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: T;\n\tdisplay: boolean;\n}\n\n/** Session entry - has id/parentId for tree structure (returned by \"read\" methods in SessionManager) */\nexport type SessionEntry =\n\t| SessionMessageEntry\n\t| ThinkingLevelChangeEntry\n\t| ModelChangeEntry\n\t| CompactionEntry\n\t| BranchSummaryEntry\n\t| CustomEntry\n\t| CustomMessageEntry\n\t| LabelEntry\n\t| SessionInfoEntry;\n\n/** Raw file entry (includes header) */\nexport type FileEntry = SessionHeader | SessionEntry;\n\n/** Tree node for getTree() - defensive copy of session structure */\nexport interface SessionTreeNode {\n\tentry: SessionEntry;\n\tchildren: SessionTreeNode[];\n\t/** Resolved label for this entry, if any */\n\tlabel?: string;\n\t/** Timestamp of the latest label change for this entry, if any */\n\tlabelTimestamp?: string;\n}\n\nexport interface SessionContext {\n\tmessages: AgentMessage[];\n\tthinkingLevel: string;\n\tmodel: { provider: string; modelId: string } | null;\n}\n\nexport interface SessionInfo {\n\tpath: string;\n\tid: string;\n\t/** Working directory where the session was started. Empty string for old sessions. */\n\tcwd: string;\n\t/** User-defined display name from session_info entries. */\n\tname?: string;\n\t/** Path to the parent session (if this session was forked). */\n\tparentSessionPath?: string;\n\tcreated: Date;\n\tmodified: Date;\n\tmessageCount: number;\n\tfirstMessage: string;\n\tallMessagesText: string;\n}\n\nexport type ReadonlySessionManager = Pick<\n\tSessionManager,\n\t| \"getCwd\"\n\t| \"getSessionDir\"\n\t| \"getSessionId\"\n\t| \"getSessionFile\"\n\t| \"getLeafId\"\n\t| \"getLeafEntry\"\n\t| \"getEntry\"\n\t| \"getLabel\"\n\t| \"getBranch\"\n\t| \"buildContextEntries\"\n\t| \"getHeader\"\n\t| \"getEntries\"\n\t| \"getTree\"\n\t| \"getSessionName\"\n>;\n\nfunction createSessionId(): string {\n\treturn uuidv7();\n}\n\nexport function assertValidSessionId(id: string): void {\n\tif (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id)) {\n\t\tthrow new Error(\n\t\t\t\"Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t}\n}\n\n/** Generate a unique short ID (8 hex chars, collision-checked) */\nfunction generateId(byId: { has(id: string): boolean }): string {\n\tfor (let i = 0; i < 100; i++) {\n\t\tconst id = randomUUID().slice(0, 8);\n\t\tif (!byId.has(id)) return id;\n\t}\n\t// Fallback to full UUID if somehow we have collisions\n\treturn randomUUID();\n}\n\n/** Migrate v1 → v2: add id/parentId tree structure. Mutates in place. */\nfunction migrateV1ToV2(entries: FileEntry[]): void {\n\tconst ids = new Set<string>();\n\tlet prevId: string | null = null;\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session\") {\n\t\t\tentry.version = 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tentry.id = generateId(ids);\n\t\tentry.parentId = prevId;\n\t\tprevId = entry.id;\n\n\t\t// Convert firstKeptEntryIndex to firstKeptEntryId for compaction\n\t\tif (entry.type === \"compaction\") {\n\t\t\tconst comp = entry as CompactionEntry & { firstKeptEntryIndex?: number };\n\t\t\tif (typeof comp.firstKeptEntryIndex === \"number\") {\n\t\t\t\tconst targetEntry = entries[comp.firstKeptEntryIndex];\n\t\t\t\tif (targetEntry && targetEntry.type !== \"session\") {\n\t\t\t\t\tcomp.firstKeptEntryId = targetEntry.id;\n\t\t\t\t}\n\t\t\t\tdelete comp.firstKeptEntryIndex;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Migrate v2 → v3: rename hookMessage role to custom. Mutates in place. */\nfunction migrateV2ToV3(entries: FileEntry[]): void {\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session\") {\n\t\t\tentry.version = 3;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Update message entries with hookMessage role\n\t\tif (entry.type === \"message\") {\n\t\t\tconst msgEntry = entry as SessionMessageEntry;\n\t\t\tif (msgEntry.message && (msgEntry.message as { role: string }).role === \"hookMessage\") {\n\t\t\t\t(msgEntry.message as { role: string }).role = \"custom\";\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Run all necessary migrations to bring entries to current version.\n * Mutates entries in place. Returns true if any migration was applied.\n */\nfunction migrateToCurrentVersion(entries: FileEntry[]): boolean {\n\tconst header = entries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\tconst version = header?.version ?? 1;\n\n\tif (version >= CURRENT_SESSION_VERSION) return false;\n\n\tif (version < 2) migrateV1ToV2(entries);\n\tif (version < 3) migrateV2ToV3(entries);\n\n\treturn true;\n}\n\n/** Exported for testing */\nexport function migrateSessionEntries(entries: FileEntry[]): void {\n\tmigrateToCurrentVersion(entries);\n}\n\n/** Exported for compaction.test.ts */\nexport function parseSessionEntries(content: string): FileEntry[] {\n\tconst entries: FileEntry[] = [];\n\tconst lines = content.trim().split(\"\\n\");\n\n\tfor (const line of lines) {\n\t\tif (!line.trim()) continue;\n\t\ttry {\n\t\t\tconst entry = JSON.parse(line) as FileEntry;\n\t\t\tentries.push(entry);\n\t\t} catch {\n\t\t\t// Skip malformed lines\n\t\t}\n\t}\n\n\treturn entries;\n}\n\nexport function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tif (entries[i].type === \"compaction\") {\n\t\t\treturn entries[i] as CompactionEntry;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction buildEntryIndex(entries: SessionEntry[], byId?: Map<string, SessionEntry>): Map<string, SessionEntry> {\n\tif (byId) return byId;\n\tconst index = new Map<string, SessionEntry>();\n\tfor (const entry of entries) {\n\t\tindex.set(entry.id, entry);\n\t}\n\treturn index;\n}\n\nfunction buildSessionPath(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionEntry[] {\n\tconst index = buildEntryIndex(entries, byId);\n\tlet leaf: SessionEntry | undefined;\n\tif (leafId === null) {\n\t\treturn [];\n\t}\n\tif (leafId) {\n\t\tleaf = index.get(leafId);\n\t}\n\tleaf ??= entries[entries.length - 1];\n\tif (!leaf) {\n\t\treturn [];\n\t}\n\n\tconst path: SessionEntry[] = [];\n\tlet current: SessionEntry | undefined = leaf;\n\twhile (current) {\n\t\tpath.push(current);\n\t\tcurrent = current.parentId ? index.get(current.parentId) : undefined;\n\t}\n\tpath.reverse();\n\treturn path;\n}\n\nfunction getSessionContextSettings(path: SessionEntry[]): Pick<SessionContext, \"thinkingLevel\" | \"model\"> {\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\n\tfor (const entry of path) {\n\t\tif (entry.type === \"thinking_level_change\") {\n\t\t\tthinkingLevel = entry.thinkingLevel;\n\t\t} else if (entry.type === \"model_change\") {\n\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tmodel = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t}\n\t}\n\n\treturn { thinkingLevel, model };\n}\n\n/**\n * Project one selected session entry into LLM/runtime messages.\n * Plain custom entries are display/state entries and do not participate in context.\n */\nexport function sessionEntryToContextMessages(entry: SessionEntry): AgentMessage[] {\n\tif (entry.type === \"message\") {\n\t\tconst message = entry.message;\n\t\t// Session files are parsed without validation; old versions, forks, or\n\t\t// hand-edited files can contain messages with null/missing content.\n\t\tif (\n\t\t\t(message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") &&\n\t\t\tmessage.content == null\n\t\t) {\n\t\t\treturn [{ ...message, content: [] }];\n\t\t}\n\t\treturn [message];\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn [\n\t\t\tcreateCustomMessage(entry.customType, entry.content ?? [], entry.display, entry.details, entry.timestamp),\n\t\t];\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)];\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn [createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)];\n\t}\n\treturn [];\n}\n\n/**\n * Build the active, compaction-aware session entry list.\n *\n * This follows the current leaf path. If the path contains compaction entries,\n * the latest compaction is represented by the compaction entry itself, followed\n * by the kept entries starting at firstKeptEntryId and all entries after the\n * compaction entry. Older summarized entries are omitted.\n */\nexport function buildContextEntries(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionEntry[] {\n\tconst path = buildSessionPath(entries, leafId, byId);\n\tlet compaction: CompactionEntry | null = null;\n\n\tfor (const entry of path) {\n\t\tif (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\n\tif (!compaction) {\n\t\treturn path;\n\t}\n\n\tconst compactionIdx = path.findIndex((entry) => entry.id === compaction.id);\n\tif (compactionIdx < 0) {\n\t\treturn path;\n\t}\n\n\tconst contextEntries: SessionEntry[] = [compaction];\n\tlet foundFirstKept = false;\n\tfor (let i = 0; i < compactionIdx; i++) {\n\t\tconst entry = path[i];\n\t\tif (entry.id === compaction.firstKeptEntryId) {\n\t\t\tfoundFirstKept = true;\n\t\t}\n\t\tif (foundFirstKept) {\n\t\t\tcontextEntries.push(entry);\n\t\t}\n\t}\n\tcontextEntries.push(...path.slice(compactionIdx + 1));\n\treturn contextEntries;\n}\n\n/**\n * Build the session context from entries using tree traversal.\n * If leafId is provided, walks from that entry to root.\n * Handles compaction and branch summaries along the path.\n */\nexport function buildSessionContext(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionContext {\n\tconst path = buildSessionPath(entries, leafId, byId);\n\tconst { thinkingLevel, model } = getSessionContextSettings(path);\n\tconst messages = buildContextEntries(entries, leafId, byId).flatMap(sessionEntryToContextMessages);\n\treturn { messages, thinkingLevel, model };\n}\n\n/**\n * Compute the default session directory for a cwd.\n * Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.\n */\nfunction getDefaultSessionDirPath(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst resolvedCwd = resolvePath(cwd);\n\tconst resolvedAgentDir = resolvePath(agentDir);\n\tconst safePath = `--${resolvedCwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\treturn join(resolvedAgentDir, \"sessions\", safePath);\n}\n\nexport function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst sessionDir = getDefaultSessionDirPath(cwd, agentDir);\n\tif (!existsSync(sessionDir)) {\n\t\tmkdirSync(sessionDir, { recursive: true });\n\t}\n\treturn sessionDir;\n}\n\nconst SESSION_READ_BUFFER_SIZE = 1024 * 1024;\nconst SESSION_HEADER_READ_BUFFER_SIZE = 4096;\n/** Bound synchronous header discovery while allowing large cwd and custom metadata fields. */\nconst MAX_SESSION_HEADER_SCAN_BYTES = 1024 * 1024;\n\nclass SessionHeaderScanLimitError extends Error {\n\tconstructor(filePath: string) {\n\t\tsuper(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`);\n\t\tthis.name = \"SessionHeaderScanLimitError\";\n\t}\n}\n\nfunction parseSessionEntryLine(line: string): FileEntry | null {\n\tif (!line.trim()) return null;\n\ttry {\n\t\treturn JSON.parse(line) as FileEntry;\n\t} catch {\n\t\t// Skip malformed lines\n\t\treturn null;\n\t}\n}\n\n/** Exported for testing */\nexport function loadEntriesFromFile(filePath: string): FileEntry[] {\n\tconst resolvedFilePath = normalizePath(filePath);\n\tif (!existsSync(resolvedFilePath)) return [];\n\n\tconst entries: FileEntry[] = [];\n\tconst fd = openSync(resolvedFilePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);\n\t\tlet pending = \"\";\n\n\t\twhile (true) {\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, buffer.length, null);\n\t\t\tif (bytesRead === 0) break;\n\n\t\t\tpending += decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tconst entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));\n\t\t\t\tif (entry) entries.push(entry);\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tpending = pending.slice(lineStart);\n\t\t}\n\n\t\tpending += decoder.end();\n\t\tconst finalEntry = parseSessionEntryLine(pending);\n\t\tif (finalEntry) entries.push(finalEntry);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\t// Validate session header\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as { id?: unknown }).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\n/**\n * Inspect a physical line while searching for the first parsed session entry.\n * Blank and malformed lines are skipped to match loadEntriesFromFile().\n * Returns undefined to keep scanning, null for a parsed non-header entry, or the header.\n */\nfunction parseSessionHeaderCandidate(line: string): SessionHeader | null | undefined {\n\tif (!line.trim()) return undefined;\n\tconst entry = parseSessionEntryLine(line);\n\tif (!entry) return undefined;\n\tif (entry.type !== \"session\" || typeof (entry as { id?: unknown }).id !== \"string\") return null;\n\treturn entry;\n}\n\nfunction readSessionHeader(filePath: string): SessionHeader | null {\n\tconst fd = openSync(filePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE);\n\t\tconst lineChunks: string[] = [];\n\t\tlet scannedBytes = 0;\n\n\t\twhile (scannedBytes < MAX_SESSION_HEADER_SCAN_BYTES) {\n\t\t\tconst readLength = Math.min(buffer.length, MAX_SESSION_HEADER_SCAN_BYTES - scannedBytes);\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, readLength, null);\n\t\t\tif (bytesRead === 0) {\n\t\t\t\tlineChunks.push(decoder.end());\n\t\t\t\treturn parseSessionHeaderCandidate(lineChunks.join(\"\")) ?? null;\n\t\t\t}\n\t\t\tscannedBytes += bytesRead;\n\n\t\t\tconst chunk = decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = chunk.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tlineChunks.push(chunk.slice(lineStart, newlineIndex));\n\t\t\t\tconst header = parseSessionHeaderCandidate(lineChunks.join(\"\"));\n\t\t\t\tif (header !== undefined) return header;\n\t\t\t\tlineChunks.length = 0;\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = chunk.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tlineChunks.push(chunk.slice(lineStart));\n\t\t}\n\n\t\t// Probe for EOF so a final header without a newline is allowed when it ends\n\t\t// exactly at the scan limit. Any additional byte exceeds the bounded scan.\n\t\tconst probe = Buffer.allocUnsafe(1);\n\t\tif (readSync(fd, probe, 0, probe.length, null) === 0) {\n\t\t\tlineChunks.push(decoder.end());\n\t\t\treturn parseSessionHeaderCandidate(lineChunks.join(\"\")) ?? null;\n\t\t}\n\t\tthrow new SessionHeaderScanLimitError(filePath);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n}\n\nfunction readSessionHeaderForDiscovery(filePath: string): SessionHeader | null {\n\ttry {\n\t\treturn readSessionHeader(filePath);\n\t} catch {\n\t\t// Discovery is best-effort: unreadable or oversized files are not sessions,\n\t\t// and one corrupt file must not prevent other sessions from being found.\n\t\treturn null;\n\t}\n}\n\nfunction getSessionHeaderCwd(header: SessionHeader): string | undefined {\n\tconst cwd = (header as { cwd?: unknown }).cwd;\n\treturn typeof cwd === \"string\" ? cwd : undefined;\n}\n\nfunction sessionCwdMatches(cwd: string | undefined, resolvedCwd: string): boolean {\n\treturn cwd !== undefined && cwd !== \"\" && resolvePath(cwd) === resolvedCwd;\n}\n\n/** Exported for testing */\nexport function findMostRecentSession(sessionDir: string, cwd?: string): string | null {\n\tconst resolvedSessionDir = normalizePath(sessionDir);\n\tconst resolvedCwd = cwd ? resolvePath(cwd) : undefined;\n\ttry {\n\t\tconst files = readdirSync(resolvedSessionDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(resolvedSessionDir, f))\n\t\t\t.map((path) => ({ path, header: readSessionHeaderForDiscovery(path) }))\n\t\t\t.filter(\n\t\t\t\t(file): file is { path: string; header: SessionHeader } =>\n\t\t\t\t\tfile.header !== null &&\n\t\t\t\t\t(!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd)),\n\t\t\t)\n\t\t\t.map(({ path }) => ({ path, mtime: statSync(path).mtime }))\n\t\t\t.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n\t\treturn files[0]?.path || null;\n\t} catch {\n\t\t// Directory access and stat races make recent-session discovery unavailable.\n\t\treturn null;\n\t}\n}\n\nfunction isMessageWithContent(message: AgentMessage): message is Message {\n\treturn typeof (message as Message).role === \"string\" && \"content\" in message;\n}\n\nfunction extractTextContent(message: Message): string {\n\tconst content = message.content;\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\" \");\n}\n\nfunction getMessageActivityTime(entry: SessionMessageEntry): number | undefined {\n\tconst message = entry.message;\n\tif (!isMessageWithContent(message)) return undefined;\n\tif (message.role !== \"user\" && message.role !== \"assistant\") return undefined;\n\n\tconst msgTimestamp = (message as { timestamp?: number }).timestamp;\n\tif (typeof msgTimestamp === \"number\") {\n\t\treturn msgTimestamp;\n\t}\n\n\tconst t = new Date(entry.timestamp).getTime();\n\treturn Number.isNaN(t) ? undefined : t;\n}\n\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst stats = await stat(filePath);\n\t\tlet header: SessionHeader | null = null;\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\t\tlet name: string | undefined;\n\t\tlet lastActivityTime: number | undefined;\n\n\t\tconst rl = createInterface({\n\t\t\tinput: createReadStream(filePath, { encoding: \"utf8\" }),\n\t\t\tcrlfDelay: Infinity,\n\t\t});\n\n\t\tfor await (const line of rl) {\n\t\t\tconst entry = parseSessionEntryLine(line);\n\t\t\tif (!entry) continue;\n\n\t\t\tif (!header) {\n\t\t\t\tif (entry.type !== \"session\") return null;\n\t\t\t\theader = entry;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Extract session name (use latest, including explicit clears)\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\tname = entry.name?.trim() || undefined;\n\t\t\t}\n\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst activityTime = getMessageActivityTime(entry);\n\t\t\tif (typeof activityTime === \"number\") {\n\t\t\t\tlastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);\n\t\t\t}\n\n\t\t\tconst message = entry.message;\n\t\t\tif (!isMessageWithContent(message)) continue;\n\t\t\tif (message.role !== \"user\" && message.role !== \"assistant\") continue;\n\n\t\t\tconst textContent = extractTextContent(message);\n\t\t\tif (!textContent) continue;\n\n\t\t\tallMessages.push(textContent);\n\t\t\tif (!firstMessage && message.role === \"user\") {\n\t\t\t\tfirstMessage = textContent;\n\t\t\t}\n\t\t}\n\n\t\tif (!header) return null;\n\n\t\tconst cwd = typeof header.cwd === \"string\" ? header.cwd : \"\";\n\t\tconst parentSessionPath = header.parentSession;\n\t\tconst headerTime = typeof header.timestamp === \"string\" ? new Date(header.timestamp).getTime() : NaN;\n\t\tconst modified =\n\t\t\ttypeof lastActivityTime === \"number\" && lastActivityTime > 0\n\t\t\t\t? new Date(lastActivityTime)\n\t\t\t\t: !Number.isNaN(headerTime)\n\t\t\t\t\t? new Date(headerTime)\n\t\t\t\t\t: stats.mtime;\n\n\t\treturn {\n\t\t\tpath: filePath,\n\t\t\tid: header.id,\n\t\t\tcwd,\n\t\t\tname,\n\t\t\tparentSessionPath,\n\t\t\tcreated: new Date(header.timestamp),\n\t\t\tmodified,\n\t\t\tmessageCount,\n\t\t\tfirstMessage: firstMessage || \"(no messages)\",\n\t\t\tallMessagesText: allMessages.join(\" \"),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport type SessionListProgress = (loaded: number, total: number) => void;\n\nconst MAX_CONCURRENT_SESSION_INFO_LOADS = 10;\n\nasync function buildSessionInfosWithConcurrency(\n\tfiles: string[],\n\tonLoaded: () => void,\n): Promise<(SessionInfo | null)[]> {\n\tconst results: (SessionInfo | null)[] = new Array(files.length).fill(null);\n\tconst inFlight = new Set<Promise<void>>();\n\tlet nextIndex = 0;\n\n\tconst startNext = (): void => {\n\t\tconst index = nextIndex++;\n\t\tconst file = files[index];\n\t\tif (!file) return;\n\n\t\tlet task: Promise<void>;\n\t\ttask = buildSessionInfo(file)\n\t\t\t.then((info) => {\n\t\t\t\tresults[index] = info;\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tresults[index] = null;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(task);\n\t\t\t\tonLoaded();\n\t\t\t});\n\t\tinFlight.add(task);\n\t};\n\n\twhile (nextIndex < files.length || inFlight.size > 0) {\n\t\twhile (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {\n\t\t\tstartNext();\n\t\t}\n\t\tif (inFlight.size > 0) {\n\t\t\tawait Promise.race(inFlight);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nasync function listSessionsFromDir(\n\tdir: string,\n\tonProgress?: SessionListProgress,\n\tprogressOffset = 0,\n\tprogressTotal?: number,\n): Promise<SessionInfo[]> {\n\tconst sessions: SessionInfo[] = [];\n\tif (!existsSync(dir)) {\n\t\treturn sessions;\n\t}\n\n\ttry {\n\t\tconst dirEntries = await readdir(dir);\n\t\tconst files = dirEntries.filter((f) => f.endsWith(\".jsonl\")).map((f) => join(dir, f));\n\t\tconst total = progressTotal ?? files.length;\n\n\t\tlet loaded = 0;\n\t\tconst results = await buildSessionInfosWithConcurrency(files, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(progressOffset + loaded, total);\n\t\t});\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Return empty list on error\n\t}\n\n\treturn sessions;\n}\n\n/**\n * Manages conversation sessions as append-only trees stored in JSONL files.\n *\n * Each session entry has an id and parentId forming a tree structure. The \"leaf\"\n * pointer tracks the current position. Appending creates a child of the current leaf.\n * Branching moves the leaf to an earlier entry, allowing new branches without\n * modifying history.\n *\n * Use buildSessionContext() to get the resolved message list for the LLM, which\n * handles compaction summaries and follows the path from root to current leaf.\n */\nexport class SessionManager {\n\tprivate sessionId: string = \"\";\n\tprivate sessionFile: string | undefined;\n\tprivate sessionDir: string;\n\tprivate cwd: string;\n\tprivate persist: boolean;\n\tprivate flushed: boolean = false;\n\tprivate fileEntries: FileEntry[] = [];\n\tprivate byId: Map<string, SessionEntry> = new Map();\n\tprivate labelsById: Map<string, string> = new Map();\n\tprivate labelTimestampsById: Map<string, string> = new Map();\n\tprivate leafId: string | null = null;\n\n\tprivate constructor(\n\t\tcwd: string,\n\t\tsessionDir: string,\n\t\tsessionFile: string | undefined,\n\t\tpersist: boolean,\n\t\tnewSessionOptions?: NewSessionOptions,\n\t\tpreloadedFileEntries?: FileEntry[],\n\t) {\n\t\tthis.cwd = resolvePath(cwd);\n\t\tthis.sessionDir = normalizePath(sessionDir);\n\t\tthis.persist = persist;\n\t\tif (persist && this.sessionDir && !existsSync(this.sessionDir)) {\n\t\t\tmkdirSync(this.sessionDir, { recursive: true });\n\t\t}\n\n\t\tif (sessionFile) {\n\t\t\tthis._setSessionFile(sessionFile, preloadedFileEntries);\n\t\t} else {\n\t\t\tthis.newSession(newSessionOptions);\n\t\t}\n\t}\n\n\t/** Switch to a different session file (used for resume and branching) */\n\tsetSessionFile(sessionFile: string): void {\n\t\tthis._setSessionFile(sessionFile);\n\t}\n\n\tprivate _setSessionFile(sessionFile: string, preloadedFileEntries?: FileEntry[]): void {\n\t\tthis.sessionFile = resolvePath(sessionFile);\n\t\tif (existsSync(this.sessionFile)) {\n\t\t\tthis.fileEntries = preloadedFileEntries ?? loadEntriesFromFile(this.sessionFile);\n\n\t\t\t// If file was empty, initialize it with a valid session header. If it was\n\t\t\t// non-empty but did not parse as a pi session, fail without modifying it.\n\t\t\tif (this.fileEntries.length === 0) {\n\t\t\t\tconst explicitPath = this.sessionFile;\n\t\t\t\tif (statSync(explicitPath).size > 0) {\n\t\t\t\t\tthrow new Error(`Session file is not a valid pi session: ${explicitPath}`);\n\t\t\t\t}\n\t\t\t\tthis.newSession();\n\t\t\t\tthis.sessionFile = explicitPath;\n\t\t\t\tthis._rewriteFile();\n\t\t\t\tthis.flushed = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst header = this.fileEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\t\tthis.sessionId = header?.id ?? createSessionId();\n\n\t\t\tif (migrateToCurrentVersion(this.fileEntries)) {\n\t\t\t\tthis._rewriteFile();\n\t\t\t}\n\n\t\t\tthis._buildIndex();\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tconst explicitPath = this.sessionFile;\n\t\t\tthis.newSession();\n\t\t\tthis.sessionFile = explicitPath; // preserve explicit path from --session flag\n\t\t}\n\t}\n\n\tnewSession(options?: NewSessionOptions): string | undefined {\n\t\tif (options?.id !== undefined) {\n\t\t\tassertValidSessionId(options.id);\n\t\t}\n\t\tthis.sessionId = options?.id ?? createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: this.sessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession: options?.parentSession,\n\t\t};\n\t\tthis.fileEntries = [header];\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tthis.flushed = false;\n\n\t\tif (this.persist) {\n\t\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\t\tthis.sessionFile = join(this.getSessionDir(), `${fileTimestamp}_${this.sessionId}.jsonl`);\n\t\t}\n\t\treturn this.sessionFile;\n\t}\n\n\tprivate _buildIndex(): void {\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tfor (const entry of this.fileEntries) {\n\t\t\tif (entry.type === \"session\") continue;\n\t\t\tthis.byId.set(entry.id, entry);\n\t\t\tthis.leafId = entry.id;\n\t\t\tif (entry.type === \"label\") {\n\t\t\t\tif (entry.label) {\n\t\t\t\t\tthis.labelsById.set(entry.targetId, entry.label);\n\t\t\t\t\tthis.labelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t\t\t} else {\n\t\t\t\t\tthis.labelsById.delete(entry.targetId);\n\t\t\t\t\tthis.labelTimestampsById.delete(entry.targetId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rewriteFile(): void {\n\t\tif (!this.persist || !this.sessionFile) return;\n\t\tconst fd = openSync(this.sessionFile, \"w\");\n\t\ttry {\n\t\t\tfor (const entry of this.fileEntries) {\n\t\t\t\twriteFileSync(fd, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t} finally {\n\t\t\tcloseSync(fd);\n\t\t}\n\t}\n\n\tisPersisted(): boolean {\n\t\treturn this.persist;\n\t}\n\n\tgetCwd(): string {\n\t\treturn this.cwd;\n\t}\n\n\tgetSessionDir(): string {\n\t\treturn this.sessionDir;\n\t}\n\n\tusesDefaultSessionDir(): boolean {\n\t\treturn this.sessionDir === getDefaultSessionDirPath(this.cwd);\n\t}\n\n\tgetSessionId(): string {\n\t\treturn this.sessionId;\n\t}\n\n\tgetSessionFile(): string | undefined {\n\t\treturn this.sessionFile;\n\t}\n\n\t_persist(entry: SessionEntry): void {\n\t\tif (!this.persist || !this.sessionFile) return;\n\n\t\tconst hasAssistant = this.fileEntries.some((e) => e.type === \"message\" && e.message.role === \"assistant\");\n\t\tif (!hasAssistant) {\n\t\t\tif (this.flushed) {\n\t\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t} else {\n\t\t\t\t// Mark as not flushed so when assistant arrives, all entries get written\n\t\t\t\tthis.flushed = false;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.flushed) {\n\t\t\tconst fd = openSync(this.sessionFile, \"wx\");\n\t\t\ttry {\n\t\t\t\tfor (const e of this.fileEntries) {\n\t\t\t\t\twriteFileSync(fd, `${JSON.stringify(e)}\\n`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tcloseSync(fd);\n\t\t\t}\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t}\n\t}\n\n\tprivate _appendEntry(entry: SessionEntry): void {\n\t\tthis.fileEntries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tthis.leafId = entry.id;\n\t\tthis._persist(entry);\n\t}\n\n\t/** Append a message as child of current leaf, then advance leaf. Returns entry id.\n\t * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.\n\t * Reason: we want these to be top-level entries in the session, not message session entries,\n\t * so it is easier to find them.\n\t * These need to be appended via appendCompaction() and appendBranchSummary() methods.\n\t */\n\tappendMessage(message: Message | CustomMessage | BashExecutionMessage): string {\n\t\tconst entry: SessionMessageEntry = {\n\t\t\ttype: \"message\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmessage,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendThinkingLevelChange(thinkingLevel: string): string {\n\t\tconst entry: ThinkingLevelChangeEntry = {\n\t\t\ttype: \"thinking_level_change\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tthinkingLevel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a model change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendModelChange(provider: string, modelId: string): string {\n\t\tconst entry: ModelChangeEntry = {\n\t\t\ttype: \"model_change\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t): string {\n\t\tconst entry: CompactionEntry<T> = {\n\t\t\ttype: \"compaction\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId,\n\t\t\ttokensBefore,\n\t\t\tdetails,\n\t\t\tusage,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCustomEntry(customType: string, data?: unknown): string {\n\t\tconst entry: CustomEntry = {\n\t\t\ttype: \"custom\",\n\t\t\tcustomType,\n\t\t\tdata,\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a session info entry (e.g., display name). Returns entry id. */\n\tappendSessionInfo(name: string): string {\n\t\tconst sanitizedName = name.replace(/[\\r\\n]+/g, \" \").trim();\n\t\tconst entry: SessionInfoEntry = {\n\t\t\ttype: \"session_info\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tname: sanitizedName,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Get the current session name from the latest session_info entry, if any. */\n\tgetSessionName(): string | undefined {\n\t\t// Walk entries in reverse to find the latest session_info entry.\n\t\t// Empty names explicitly clear the session title.\n\t\tconst entries = this.getEntries();\n\t\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\t\tconst entry = entries[i];\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\treturn entry.name?.trim() || undefined;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Append a custom message entry (for extensions) that participates in LLM context.\n\t * @param customType Extension identifier for filtering on reload\n\t * @param content Message content (string or TextContent/ImageContent array)\n\t * @param display Whether to show in TUI (true = styled display, false = hidden)\n\t * @param details Optional extension-specific metadata (not sent to LLM)\n\t * @returns Entry id\n\t */\n\tappendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): string {\n\t\tconst entry: CustomMessageEntry<T> = {\n\t\t\ttype: \"custom_message\",\n\t\t\tcustomType,\n\t\t\tcontent,\n\t\t\tdisplay,\n\t\t\tdetails,\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t// =========================================================================\n\t// Tree Traversal\n\t// =========================================================================\n\n\tgetLeafId(): string | null {\n\t\treturn this.leafId;\n\t}\n\n\tgetLeafEntry(): SessionEntry | undefined {\n\t\treturn this.leafId ? this.byId.get(this.leafId) : undefined;\n\t}\n\n\tgetEntry(id: string): SessionEntry | undefined {\n\t\treturn this.byId.get(id);\n\t}\n\n\t/**\n\t * Get all direct children of an entry.\n\t */\n\tgetChildren(parentId: string): SessionEntry[] {\n\t\tconst children: SessionEntry[] = [];\n\t\tfor (const entry of this.byId.values()) {\n\t\t\tif (entry.parentId === parentId) {\n\t\t\t\tchildren.push(entry);\n\t\t\t}\n\t\t}\n\t\treturn children;\n\t}\n\n\t/**\n\t * Get the label for an entry, if any.\n\t */\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\t/**\n\t * Set or clear a label on an entry.\n\t * Labels are user-defined markers for bookmarking/navigation.\n\t * Pass undefined or empty string to clear the label.\n\t */\n\tappendLabelChange(targetId: string, label: string | undefined): string {\n\t\tif (!this.byId.has(targetId)) {\n\t\t\tthrow new Error(`Entry ${targetId} not found`);\n\t\t}\n\t\tconst entry: LabelEntry = {\n\t\t\ttype: \"label\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttargetId,\n\t\t\tlabel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\tif (label) {\n\t\t\tthis.labelsById.set(targetId, label);\n\t\t\tthis.labelTimestampsById.set(targetId, entry.timestamp);\n\t\t} else {\n\t\t\tthis.labelsById.delete(targetId);\n\t\t\tthis.labelTimestampsById.delete(targetId);\n\t\t}\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Walk from entry to root, returning all entries in path order.\n\t * Includes all entry types (messages, compaction, model changes, etc.).\n\t * Use buildSessionContext() to get the resolved messages for the LLM.\n\t */\n\tgetBranch(fromId?: string): SessionEntry[] {\n\t\tconst path: SessionEntry[] = [];\n\t\tconst startId = fromId ?? this.leafId;\n\t\tlet current = startId ? this.byId.get(startId) : undefined;\n\t\twhile (current) {\n\t\t\tpath.push(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\tpath.reverse();\n\t\treturn path;\n\t}\n\n\t/**\n\t * Build the active, compaction-aware entry list for context/rendering.\n\t * Uses tree traversal from current leaf.\n\t */\n\tbuildContextEntries(): SessionEntry[] {\n\t\treturn buildContextEntries(this.getEntries(), this.leafId, this.byId);\n\t}\n\n\t/**\n\t * Build the session context (what gets sent to the LLM).\n\t * Uses tree traversal from current leaf.\n\t */\n\tbuildSessionContext(): SessionContext {\n\t\treturn buildSessionContext(this.getEntries(), this.leafId, this.byId);\n\t}\n\n\t/**\n\t * Get session header.\n\t */\n\tgetHeader(): SessionHeader | null {\n\t\tconst h = this.fileEntries.find((e) => e.type === \"session\");\n\t\treturn h ? (h as SessionHeader) : null;\n\t}\n\n\t/**\n\t * Get all session entries (excludes header). Returns a shallow copy.\n\t * The session is append-only: use appendXXX() to add entries, branch() to\n\t * change the leaf pointer. Entries cannot be modified or deleted.\n\t */\n\tgetEntries(): SessionEntry[] {\n\t\treturn this.fileEntries.filter((e): e is SessionEntry => e.type !== \"session\");\n\t}\n\n\t/**\n\t * Get the session as a tree structure. Returns a shallow defensive copy of all entries.\n\t * A well-formed session has exactly one root (first entry with parentId === null).\n\t * Orphaned entries (broken parent chain) are also returned as roots.\n\t */\n\tgetTree(): SessionTreeNode[] {\n\t\tconst entries = this.getEntries();\n\t\tconst nodeMap = new Map<string, SessionTreeNode>();\n\t\tconst roots: SessionTreeNode[] = [];\n\n\t\t// Create nodes with resolved labels\n\t\tfor (const entry of entries) {\n\t\t\tconst label = this.labelsById.get(entry.id);\n\t\t\tconst labelTimestamp = this.labelTimestampsById.get(entry.id);\n\t\t\tnodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });\n\t\t}\n\n\t\t// Build tree\n\t\tfor (const entry of entries) {\n\t\t\tconst node = nodeMap.get(entry.id)!;\n\t\t\tif (entry.parentId === null || entry.parentId === entry.id) {\n\t\t\t\troots.push(node);\n\t\t\t} else {\n\t\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\t\tif (parent) {\n\t\t\t\t\tparent.children.push(node);\n\t\t\t\t} else {\n\t\t\t\t\t// Orphan - treat as root\n\t\t\t\t\troots.push(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Sort children by timestamp (oldest first, newest at bottom)\n\t\t// Use iterative approach to avoid stack overflow on deep trees\n\t\tconst stack: SessionTreeNode[] = [...roots];\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\t\tstack.push(...node.children);\n\t\t}\n\n\t\treturn roots;\n\t}\n\n\t// =========================================================================\n\t// Branching\n\t// =========================================================================\n\n\t/**\n\t * Start a new branch from an earlier entry.\n\t * Moves the leaf pointer to the specified entry. The next appendXXX() call\n\t * will create a child of that entry, forming a new branch. Existing entries\n\t * are not modified or deleted.\n\t */\n\tbranch(branchFromId: string): void {\n\t\tif (!this.byId.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.leafId = branchFromId;\n\t}\n\n\t/**\n\t * Reset the leaf pointer to null (before any entries).\n\t * The next appendXXX() call will create a new root entry (parentId = null).\n\t * Use this when navigating to re-edit the first user message.\n\t */\n\tresetLeaf(): void {\n\t\tthis.leafId = null;\n\t}\n\n\t/**\n\t * Start a new branch with a summary of the abandoned path.\n\t * Same as branch(), but also appends a branch_summary entry that captures\n\t * context from the abandoned conversation path.\n\t */\n\tbranchWithSummary(\n\t\tbranchFromId: string | null,\n\t\tsummary: string,\n\t\tdetails?: unknown,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t): string {\n\t\tif (branchFromId !== null && !this.byId.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.leafId = branchFromId;\n\t\tconst entry: BranchSummaryEntry = {\n\t\t\ttype: \"branch_summary\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: branchFromId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tfromId: branchFromId ?? \"root\",\n\t\t\tsummary,\n\t\t\tdetails,\n\t\t\tusage,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Create a new session file containing only the path from root to the specified leaf.\n\t * Useful for extracting a single conversation path from a branched session.\n\t * Returns the new session file path, or undefined if not persisting.\n\t */\n\tcreateBranchedSession(leafId: string): string | undefined {\n\t\tconst previousSessionFile = this.sessionFile;\n\t\tconst path = this.getBranch(leafId);\n\t\tif (path.length === 0) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\n\t\t// Filter out LabelEntry from path - we'll recreate them from the resolved map.\n\t\t// Because labels are real tree entries, later entries can be children of labels;\n\t\t// removing labels requires re-chaining the retained path to avoid orphaned subtrees.\n\t\tconst pathWithoutLabels: SessionEntry[] = [];\n\t\tlet pathParentId: string | null = null;\n\t\tfor (const entry of path) {\n\t\t\tif (entry.type === \"label\") continue;\n\t\t\tpathWithoutLabels.push({ ...entry, parentId: pathParentId });\n\t\t\tpathParentId = entry.id;\n\t\t}\n\n\t\tconst newSessionId = createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\tconst newSessionFile = join(this.getSessionDir(), `${fileTimestamp}_${newSessionId}.jsonl`);\n\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: newSessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession: this.persist ? previousSessionFile : undefined,\n\t\t};\n\n\t\t// Collect labels for entries in the path\n\t\tconst pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id));\n\t\tconst labelsToWrite: Array<{ targetId: string; label: string; timestamp: string }> = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (pathEntryIds.has(targetId)) {\n\t\t\t\tlabelsToWrite.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId)! });\n\t\t\t}\n\t\t}\n\n\t\tif (this.persist) {\n\t\t\t// Build label entries\n\t\t\tconst lastEntryId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;\n\t\t\tlet parentId = lastEntryId;\n\t\t\tconst labelEntries: LabelEntry[] = [];\n\t\t\tfor (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {\n\t\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\t\ttype: \"label\",\n\t\t\t\t\tid: generateId(new Set(pathEntryIds)),\n\t\t\t\t\tparentId,\n\t\t\t\t\ttimestamp: labelTimestamp,\n\t\t\t\t\ttargetId,\n\t\t\t\t\tlabel,\n\t\t\t\t};\n\t\t\t\tpathEntryIds.add(labelEntry.id);\n\t\t\t\tlabelEntries.push(labelEntry);\n\t\t\t\tparentId = labelEntry.id;\n\t\t\t}\n\n\t\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\t\tthis.sessionId = newSessionId;\n\t\t\tthis.sessionFile = newSessionFile;\n\t\t\tthis._buildIndex();\n\n\t\t\t// Only write the file now if it contains an assistant message.\n\t\t\t// Otherwise defer to _persist(), which creates the file on the\n\t\t\t// first assistant response, matching the newSession() contract\n\t\t\t// and avoiding the duplicate-header bug when _persist()'s\n\t\t\t// no-assistant guard later resets flushed to false.\n\t\t\tconst hasAssistant = this.fileEntries.some((e) => e.type === \"message\" && e.message.role === \"assistant\");\n\t\t\tif (hasAssistant) {\n\t\t\t\tthis._rewriteFile();\n\t\t\t\tthis.flushed = true;\n\t\t\t} else {\n\t\t\t\tthis.flushed = false;\n\t\t\t}\n\n\t\t\treturn newSessionFile;\n\t\t}\n\n\t\t// In-memory mode: replace current session with the path + labels\n\t\tconst labelEntries: LabelEntry[] = [];\n\t\tlet parentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;\n\t\tfor (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {\n\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\ttype: \"label\",\n\t\t\t\tid: generateId(new Set([...pathEntryIds, ...labelEntries.map((e) => e.id)])),\n\t\t\t\tparentId,\n\t\t\t\ttimestamp: labelTimestamp,\n\t\t\t\ttargetId,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t\tlabelEntries.push(labelEntry);\n\t\t\tparentId = labelEntry.id;\n\t\t}\n\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\tthis.sessionId = newSessionId;\n\t\tthis._buildIndex();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a new session.\n\t * @param cwd Working directory (stored in session header)\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t */\n\tstatic create(cwd: string, sessionDir?: string, options?: NewSessionOptions): SessionManager {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\treturn new SessionManager(cwd, dir, undefined, true, options);\n\t}\n\n\t/**\n\t * Open a specific session file.\n\t * @param path Path to session file\n\t * @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.\n\t * @param cwdOverride Optional cwd override instead of the session header cwd.\n\t */\n\tstatic open(path: string, sessionDir?: string, cwdOverride?: string): SessionManager {\n\t\tconst resolvedPath = resolvePath(path);\n\t\tlet header: SessionHeader | null = null;\n\t\tlet preloadedFileEntries: FileEntry[] | undefined;\n\t\tif (cwdOverride === undefined && existsSync(resolvedPath)) {\n\t\t\ttry {\n\t\t\t\theader = readSessionHeader(resolvedPath);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof SessionHeaderScanLimitError)) throw error;\n\t\t\t\t// The bounded scan is only a discovery optimization. A full load remains\n\t\t\t\t// authoritative for legacy files with very large headers or prefixes.\n\t\t\t\tpreloadedFileEntries = loadEntriesFromFile(resolvedPath);\n\t\t\t\tconst firstEntry = preloadedFileEntries[0];\n\t\t\t\theader = firstEntry?.type === \"session\" ? firstEntry : null;\n\t\t\t}\n\t\t}\n\t\tconst cwd = cwdOverride ?? (header ? getSessionHeaderCwd(header) : undefined) ?? process.cwd();\n\t\t// If no sessionDir provided, derive from file's parent directory\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, \"..\");\n\t\treturn new SessionManager(cwd, dir, resolvedPath, true, undefined, preloadedFileEntries);\n\t}\n\n\t/**\n\t * Continue the most recent session, or create new if none.\n\t * @param cwd Working directory\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t */\n\tstatic continueRecent(cwd: string, sessionDir?: string): SessionManager {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\tconst filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);\n\t\tconst mostRecent = findMostRecentSession(dir, filterCwd ? cwd : undefined);\n\t\tif (mostRecent) {\n\t\t\treturn new SessionManager(cwd, dir, mostRecent, true);\n\t\t}\n\t\treturn new SessionManager(cwd, dir, undefined, true);\n\t}\n\n\t/** Create an in-memory session (no file persistence) */\n\tstatic inMemory(cwd: string = process.cwd(), options?: NewSessionOptions): SessionManager {\n\t\treturn new SessionManager(cwd, \"\", undefined, false, options);\n\t}\n\n\t/**\n\t * Fork a session from another project directory into the current project.\n\t * Creates a new session in the target cwd with the full history from the source session.\n\t * @param sourcePath Path to the source session file\n\t * @param targetCwd Target working directory (where the new session will be stored)\n\t * @param sessionDir Optional session directory. If omitted, uses default for targetCwd.\n\t */\n\tstatic forkFrom(\n\t\tsourcePath: string,\n\t\ttargetCwd: string,\n\t\tsessionDir?: string,\n\t\toptions?: NewSessionOptions,\n\t): SessionManager {\n\t\tconst resolvedSourcePath = resolvePath(sourcePath);\n\t\tconst resolvedTargetCwd = resolvePath(targetCwd);\n\t\tconst sourceEntries = loadEntriesFromFile(resolvedSourcePath);\n\t\tif (sourceEntries.length === 0) {\n\t\t\tthrow new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);\n\t\t}\n\n\t\tconst sourceHeader = sourceEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\tif (!sourceHeader) {\n\t\t\tthrow new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);\n\t\t}\n\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(resolvedTargetCwd);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\n\t\t// Create new session file with new ID but forked content\n\t\tif (options?.id !== undefined) {\n\t\t\tassertValidSessionId(options.id);\n\t\t}\n\t\tconst newSessionId = options?.id ?? createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\tconst newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);\n\n\t\t// Write new header pointing to source as parent, with updated cwd\n\t\tconst newHeader: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: newSessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: resolvedTargetCwd,\n\t\t\tparentSession: resolvedSourcePath,\n\t\t};\n\t\twriteFileSync(newSessionFile, `${JSON.stringify(newHeader)}\\n`, { flag: \"wx\" });\n\n\t\t// Copy all non-header entries from source\n\t\tfor (const entry of sourceEntries) {\n\t\t\tif (entry.type !== \"session\") {\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\treturn new SessionManager(resolvedTargetCwd, dir, newSessionFile, true);\n\t}\n\n\t/**\n\t * List all sessions for a directory.\n\t * @param cwd Working directory (used to compute default session directory)\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t * @param onProgress Optional callback for progress updates (loaded, total)\n\t */\n\tstatic async list(cwd: string, sessionDir?: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\tconst filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);\n\t\tconst resolvedCwd = resolvePath(cwd);\n\t\tconst sessions = (await listSessionsFromDir(dir, onProgress)).filter(\n\t\t\t(session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd),\n\t\t);\n\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\treturn sessions;\n\t}\n\n\t/**\n\t * List all sessions across all project directories.\n\t * @param onProgress Optional callback for progress updates (loaded, total)\n\t */\n\tstatic async listAll(onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tstatic async listAll(sessionDir?: string, onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tstatic async listAll(\n\t\tsessionDirOrOnProgress?: string | SessionListProgress,\n\t\tonProgress?: SessionListProgress,\n\t): Promise<SessionInfo[]> {\n\t\tconst customSessionDir =\n\t\t\ttypeof sessionDirOrOnProgress === \"string\" ? normalizePath(sessionDirOrOnProgress) : undefined;\n\t\tconst progress = typeof sessionDirOrOnProgress === \"function\" ? sessionDirOrOnProgress : onProgress;\n\t\tif (customSessionDir) {\n\t\t\tconst sessions = await listSessionsFromDir(customSessionDir, progress);\n\t\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\treturn sessions;\n\t\t}\n\n\t\tconst sessionsDir = getSessionsDir();\n\n\t\ttry {\n\t\t\tif (!existsSync(sessionsDir)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tconst entries = await readdir(sessionsDir, { withFileTypes: true });\n\t\t\tconst dirs = entries\n\t\t\t\t.filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n\t\t\t\t.map((entry) => join(sessionsDir, entry.name));\n\n\t\t\t// Count total files first for accurate progress\n\t\t\tlet totalFiles = 0;\n\t\t\tconst dirFiles: string[][] = [];\n\t\t\tfor (const dir of dirs) {\n\t\t\t\ttry {\n\t\t\t\t\tconst files = (await readdir(dir)).filter((f) => f.endsWith(\".jsonl\"));\n\t\t\t\t\tdirFiles.push(files.map((f) => join(dir, f)));\n\t\t\t\t\ttotalFiles += files.length;\n\t\t\t\t} catch {\n\t\t\t\t\tdirFiles.push([]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process all files with progress tracking\n\t\t\tlet loaded = 0;\n\t\t\tconst sessions: SessionInfo[] = [];\n\t\t\tconst allFiles = dirFiles.flat();\n\n\t\t\tconst results = await buildSessionInfosWithConcurrency(allFiles, () => {\n\t\t\t\tloaded++;\n\t\t\t\tprogress?.(loaded, totalFiles);\n\t\t\t});\n\n\t\t\tfor (const info of results) {\n\t\t\t\tif (info) {\n\t\t\t\t\tsessions.push(info);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\treturn sessions;\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\n/**\n * Shared truncation utilities for tool outputs.\n *\n * Truncation is based on two independent limits - whichever is hit first wins:\n * - Line limit (default: 2000 lines)\n * - Byte limit (default: 50KB)\n *\n * Never returns partial lines (except bash tail truncation edge case).\n */\n\nexport const DEFAULT_MAX_LINES = 2000;\nexport const DEFAULT_MAX_BYTES = 50 * 1024; // 50KB\nexport const GREP_MAX_LINE_LENGTH = 500; // Max chars per grep match line\n\nexport interface TruncationResult {\n\t/** The truncated content */\n\tcontent: string;\n\t/** Whether truncation occurred */\n\ttruncated: boolean;\n\t/** Which limit was hit: \"lines\", \"bytes\", or null if not truncated */\n\ttruncatedBy: \"lines\" | \"bytes\" | null;\n\t/** Total number of lines in the original content */\n\ttotalLines: number;\n\t/** Total number of bytes in the original content */\n\ttotalBytes: number;\n\t/** Number of complete lines in the truncated output */\n\toutputLines: number;\n\t/** Number of bytes in the truncated output */\n\toutputBytes: number;\n\t/** Whether the last line was partially truncated (only for tail truncation edge case) */\n\tlastLinePartial: boolean;\n\t/** Whether the first line exceeded the byte limit (for head truncation) */\n\tfirstLineExceedsLimit: boolean;\n\t/** The max lines limit that was applied */\n\tmaxLines: number;\n\t/** The max bytes limit that was applied */\n\tmaxBytes: number;\n}\n\nexport interface TruncationOptions {\n\t/** Maximum number of lines (default: 2000) */\n\tmaxLines?: number;\n\t/** Maximum number of bytes (default: 50KB) */\n\tmaxBytes?: number;\n}\n\nfunction splitLinesForCounting(content: string): string[] {\n\tif (content.length === 0) {\n\t\treturn [];\n\t}\n\tconst lines = content.split(\"\\n\");\n\tif (content.endsWith(\"\\n\")) {\n\t\tlines.pop();\n\t}\n\treturn lines;\n}\n\n/**\n * Format bytes as human-readable size.\n */\nexport function formatSize(bytes: number): string {\n\tif (bytes < 1024) {\n\t\treturn `${bytes}B`;\n\t} else if (bytes < 1024 * 1024) {\n\t\treturn `${(bytes / 1024).toFixed(1)}KB`;\n\t} else {\n\t\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n\t}\n}\n\n/**\n * Truncate content from the head (keep first N lines/bytes).\n * Suitable for file reads where you want to see the beginning.\n *\n * Never returns partial lines. If first line exceeds byte limit,\n * returns empty content with firstLineExceedsLimit=true.\n */\nexport function truncateHead(content: string, options: TruncationOptions = {}): TruncationResult {\n\tconst maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\tconst maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\n\tconst totalBytes = Buffer.byteLength(content, \"utf-8\");\n\tconst lines = splitLinesForCounting(content);\n\tconst totalLines = lines.length;\n\n\t// Check if no truncation needed\n\tif (totalLines <= maxLines && totalBytes <= maxBytes) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\ttruncated: false,\n\t\t\ttruncatedBy: null,\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: totalLines,\n\t\t\toutputBytes: totalBytes,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: false,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Check if first line alone exceeds byte limit\n\tconst firstLineBytes = Buffer.byteLength(lines[0], \"utf-8\");\n\tif (firstLineBytes > maxBytes) {\n\t\treturn {\n\t\t\tcontent: \"\",\n\t\t\ttruncated: true,\n\t\t\ttruncatedBy: \"bytes\",\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: 0,\n\t\t\toutputBytes: 0,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: true,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Collect complete lines that fit\n\tconst outputLinesArr: string[] = [];\n\tlet outputBytesCount = 0;\n\tlet truncatedBy: \"lines\" | \"bytes\" = \"lines\";\n\n\tfor (let i = 0; i < lines.length && i < maxLines; i++) {\n\t\tconst line = lines[i];\n\t\tconst lineBytes = Buffer.byteLength(line, \"utf-8\") + (i > 0 ? 1 : 0); // +1 for newline\n\n\t\tif (outputBytesCount + lineBytes > maxBytes) {\n\t\t\ttruncatedBy = \"bytes\";\n\t\t\tbreak;\n\t\t}\n\n\t\toutputLinesArr.push(line);\n\t\toutputBytesCount += lineBytes;\n\t}\n\n\t// If we exited due to line limit\n\tif (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n\t\ttruncatedBy = \"lines\";\n\t}\n\n\tconst outputContent = outputLinesArr.join(\"\\n\");\n\tconst finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n\n\treturn {\n\t\tcontent: outputContent,\n\t\ttruncated: true,\n\t\ttruncatedBy,\n\t\ttotalLines,\n\t\ttotalBytes,\n\t\toutputLines: outputLinesArr.length,\n\t\toutputBytes: finalOutputBytes,\n\t\tlastLinePartial: false,\n\t\tfirstLineExceedsLimit: false,\n\t\tmaxLines,\n\t\tmaxBytes,\n\t};\n}\n\n/**\n * Truncate content from the tail (keep last N lines/bytes).\n * Suitable for bash output where you want to see the end (errors, final results).\n *\n * May return partial first line if the last line of original content exceeds byte limit.\n */\nexport function truncateTail(content: string, options: TruncationOptions = {}): TruncationResult {\n\tconst maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\tconst maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\n\tconst totalBytes = Buffer.byteLength(content, \"utf-8\");\n\tconst lines = splitLinesForCounting(content);\n\tconst totalLines = lines.length;\n\n\t// Check if no truncation needed\n\tif (totalLines <= maxLines && totalBytes <= maxBytes) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\ttruncated: false,\n\t\t\ttruncatedBy: null,\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: totalLines,\n\t\t\toutputBytes: totalBytes,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: false,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Work backwards from the end\n\tconst outputLinesArr: string[] = [];\n\tlet outputBytesCount = 0;\n\tlet truncatedBy: \"lines\" | \"bytes\" = \"lines\";\n\tlet lastLinePartial = false;\n\n\tfor (let i = lines.length - 1; i >= 0 && outputLinesArr.length < maxLines; i--) {\n\t\tconst line = lines[i];\n\t\tconst lineBytes = Buffer.byteLength(line, \"utf-8\") + (outputLinesArr.length > 0 ? 1 : 0); // +1 for newline\n\n\t\tif (outputBytesCount + lineBytes > maxBytes) {\n\t\t\ttruncatedBy = \"bytes\";\n\t\t\t// Edge case: if we haven't added ANY lines yet and this line exceeds maxBytes,\n\t\t\t// take the end of the line (partial)\n\t\t\tif (outputLinesArr.length === 0) {\n\t\t\t\tconst truncatedLine = truncateStringToBytesFromEnd(line, maxBytes);\n\t\t\t\toutputLinesArr.unshift(truncatedLine);\n\t\t\t\toutputBytesCount = Buffer.byteLength(truncatedLine, \"utf-8\");\n\t\t\t\tlastLinePartial = true;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\toutputLinesArr.unshift(line);\n\t\toutputBytesCount += lineBytes;\n\t}\n\n\t// If we exited due to line limit\n\tif (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n\t\ttruncatedBy = \"lines\";\n\t}\n\n\tconst outputContent = outputLinesArr.join(\"\\n\");\n\tconst finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n\n\treturn {\n\t\tcontent: outputContent,\n\t\ttruncated: true,\n\t\ttruncatedBy,\n\t\ttotalLines,\n\t\ttotalBytes,\n\t\toutputLines: outputLinesArr.length,\n\t\toutputBytes: finalOutputBytes,\n\t\tlastLinePartial,\n\t\tfirstLineExceedsLimit: false,\n\t\tmaxLines,\n\t\tmaxBytes,\n\t};\n}\n\n/**\n * Truncate a string to fit within a byte limit (from the end).\n * Handles multi-byte UTF-8 characters correctly.\n */\nfunction truncateStringToBytesFromEnd(str: string, maxBytes: number): string {\n\tconst buf = Buffer.from(str, \"utf-8\");\n\tif (buf.length <= maxBytes) {\n\t\treturn str;\n\t}\n\n\t// Start from the end, skip maxBytes back\n\tlet start = buf.length - maxBytes;\n\n\t// Find a valid UTF-8 boundary (start of a character)\n\twhile (start < buf.length && (buf[start] & 0xc0) === 0x80) {\n\t\tstart++;\n\t}\n\n\treturn buf.slice(start).toString(\"utf-8\");\n}\n\n/**\n * Truncate a single line to max characters, adding [truncated] suffix.\n * Used for grep match lines.\n */\nexport function truncateLine(\n\tline: string,\n\tmaxChars: number = GREP_MAX_LINE_LENGTH,\n): { text: string; wasTruncated: boolean } {\n\tif (line.length <= maxChars) {\n\t\treturn { text: line, wasTruncated: false };\n\t}\n\treturn { text: `${line.slice(0, maxChars)}... [truncated]`, wasTruncated: true };\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\nlet registrationQueue = Promise.resolve();\n\nfunction isMissingPathError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error.code === \"ENOENT\" || error.code === \"ENOTDIR\")\n\t);\n}\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch (error) {\n\t\tif (isMissingPathError(error)) {\n\t\t\treturn resolvedPath;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst registration = registrationQueue.then(async () => {\n\t\tconst key = await getMutationQueueKey(filePath);\n\t\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\t\tlet releaseNext!: () => void;\n\t\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\t\treleaseNext = resolveQueue;\n\t\t});\n\t\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\t\tfileMutationQueues.set(key, chainedQueue);\n\n\t\treturn { key, currentQueue, chainedQueue, releaseNext };\n\t});\n\tregistrationQueue = registration.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\n\tconst { key, currentQueue, chainedQueue, releaseNext } = await registration;\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n","/**\n * Vendored verbatim from `@earendil-works/pi-coding-agent@0.84.2`\n * (`dist/core/extensions/loader.js` `createExtensionRuntime`).\n *\n * A pure state-container factory with no host dependency. Action methods start\n * as `notInitialized` stubs that the host runner replaces on bind; the pre-bind\n * logic (stale guard, event-bus subscription tracking, queued provider\n * registrations) is real. Extensions such as pi-btw construct one when they\n * assemble a ResourceLoader-shaped `getExtensions()` result, so the symbol must\n * exist and behave exactly as Pi's — an absent export throws\n * \"createExtensionRuntime is not a function\" the moment such an extension runs.\n */\n\ntype Unsubscribe = () => void\n\ninterface RuntimeState {\n staleMessage?: string\n}\n\n/** The extension runtime Pi hands to loaded extensions in its pre-bind shape. */\nexport interface ExtensionRuntime {\n [key: string]: unknown\n flagValues: Map<string, boolean | string>\n pendingProviderRegistrations: Array<{ name: string, config: unknown, extensionPath: string }>\n pendingNativeProviderRegistrations: Array<{ provider: { id: string }, extensionPath: string }>\n}\n\n/**\n * Build a fresh pre-bind extension runtime. Registration methods\n * (`registerProvider`, `trackEventBusSubscription`) work immediately; action\n * methods (`sendMessage`, `getActiveTools`, …) throw until the host runner\n * binds real implementations.\n * @returns the runtime state container consumed by Pi's extension loader.\n */\nexport function createExtensionRuntime(): ExtensionRuntime {\n const notInitialized = (): never => {\n throw new Error('Extension runtime not initialized. Action methods cannot be called during extension loading.')\n }\n const state: RuntimeState = {}\n const eventBusUnsubscribers = new Set<Unsubscribe>()\n const assertActive = (): void => {\n if (state.staleMessage) {\n throw new Error(state.staleMessage)\n }\n }\n const runtime: ExtensionRuntime = {\n sendMessage: notInitialized,\n sendUserMessage: notInitialized,\n appendEntry: notInitialized,\n setSessionName: notInitialized,\n getSessionName: notInitialized,\n setLabel: notInitialized,\n getActiveTools: notInitialized,\n getAllTools: notInitialized,\n setActiveTools: notInitialized,\n // registerTool() is valid during extension load; refresh is only needed post-bind.\n refreshTools: () => {},\n getCommands: notInitialized,\n setModel: () => Promise.reject(new Error('Extension runtime not initialized')),\n getThinkingLevel: notInitialized,\n setThinkingLevel: notInitialized,\n flagValues: new Map<string, boolean | string>(),\n pendingProviderRegistrations: [],\n pendingNativeProviderRegistrations: [],\n assertActive,\n invalidate: (message?: string) => {\n if (state.staleMessage) return\n state.staleMessage = message\n ?? 'This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().'\n for (const unsubscribe of eventBusUnsubscribers) unsubscribe()\n eventBusUnsubscribers.clear()\n },\n trackEventBusSubscription: (unsubscribe: Unsubscribe): Unsubscribe => {\n let active = true\n const trackedUnsubscribe = (): void => {\n if (!active) return\n active = false\n eventBusUnsubscribers.delete(trackedUnsubscribe)\n unsubscribe()\n }\n eventBusUnsubscribers.add(trackedUnsubscribe)\n return trackedUnsubscribe\n },\n // Pre-bind: queue registrations so the host runner can flush them once the\n // model registry is available; a bound runner replaces both with direct calls.\n registerProvider: (name: string, config: unknown, extensionPath = '<unknown>') => {\n runtime.pendingProviderRegistrations.push({ name, config, extensionPath })\n },\n registerNativeProvider: (provider: { id: string }, extensionPath = '<unknown>') => {\n runtime.pendingNativeProviderRegistrations.push({ provider, extensionPath })\n },\n unregisterProvider: (name: string) => {\n runtime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter(r => r.name !== name)\n runtime.pendingNativeProviderRegistrations = runtime.pendingNativeProviderRegistrations.filter(r => r.provider.id !== name)\n },\n }\n return runtime\n}\n","// @ts-nocheck — vendored Pi source (modes/interactive/components/visual-truncate.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared utility for truncating text to visual lines (accounting for line wrapping).\n * Used by both tool-execution.ts and bash-execution.ts for consistent behavior.\n */\nimport { Text } from '../../pi-tui.js';\n/**\n * Truncate text to a maximum number of visual lines (from the end).\n * This accounts for line wrapping based on terminal width.\n *\n * @param text - The text content (may contain newlines)\n * @param maxVisualLines - Maximum number of visual lines to show\n * @param width - Terminal/render width\n * @param paddingX - Horizontal padding for Text component (default 0).\n * Use 0 when result will be placed in a Box (Box adds its own padding).\n * Use 1 when result will be placed in a plain Container.\n * @returns The truncated visual lines and count of skipped lines\n */\nexport function truncateToVisualLines(text, maxVisualLines, width, paddingX = 0) {\n if (!text) {\n return { visualLines: [], skippedCount: 0 };\n }\n // Create a temporary Text component to render and get visual lines\n const tempText = new Text(text, paddingX, 0);\n const allVisualLines = tempText.render(width);\n if (allVisualLines.length <= maxVisualLines) {\n return { visualLines: allVisualLines, skippedCount: 0 };\n }\n // Take the last N visual lines\n const truncatedLines = allVisualLines.slice(-maxVisualLines);\n const skippedCount = allVisualLines.length - maxVisualLines;\n return { visualLines: truncatedLines, skippedCount };\n}\n//# sourceMappingURL=visual-truncate.js.map","// @ts-nocheck — vendored Pi source (utils/child-process.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { spawn as nodeSpawn, spawnSync as nodeSpawnSync, } from \"node:child_process\";\nimport crossSpawn from \"cross-spawn\";\nconst EXIT_STDIO_GRACE_MS = 100;\nexport function spawnProcess(command, args, options) {\n return process.platform === \"win32\" ? crossSpawn(command, args, options) : nodeSpawn(command, args, options);\n}\nexport function spawnProcessSync(command, args, options) {\n return process.platform === \"win32\"\n ? crossSpawn.sync(command, args, options)\n : nodeSpawnSync(command, args, options);\n}\n/**\n * Wait for a child process to terminate without hanging on inherited stdio handles.\n *\n * A short-lived child can `exit` while a detached descendant keeps its stdout/stderr\n * pipe open. We must not resolve and destroy the streams on a fixed deadline measured\n * from `exit`, or output still being written past that deadline is silently lost\n * (earendil-works/pi#5303). Instead, after `exit` we wait for the pipes to fall idle:\n * the grace timer is re-armed on every chunk, so an actively writing descendant keeps\n * us reading, while a quiet inherited handle (e.g. a Windows daemonized descendant\n * that never lets `close` fire) still releases us after the grace elapses.\n */\nexport function waitForChildProcess(child) {\n return new Promise((resolve, reject) => {\n let settled = false;\n let exited = false;\n let exitCode = null;\n let postExitTimer;\n let stdoutEnded = child.stdout === null;\n let stderrEnded = child.stderr === null;\n const cleanup = () => {\n if (postExitTimer) {\n clearTimeout(postExitTimer);\n postExitTimer = undefined;\n }\n child.removeListener(\"error\", onError);\n child.removeListener(\"exit\", onExit);\n child.removeListener(\"close\", onClose);\n child.stdout?.removeListener(\"end\", onStdoutEnd);\n child.stderr?.removeListener(\"end\", onStderrEnd);\n child.stdout?.removeListener(\"data\", onData);\n child.stderr?.removeListener(\"data\", onData);\n };\n const finalize = (code) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n child.stdout?.destroy();\n child.stderr?.destroy();\n resolve(code);\n };\n const maybeFinalizeAfterExit = () => {\n if (!exited || settled)\n return;\n if (stdoutEnded && stderrEnded) {\n finalize(exitCode);\n }\n };\n const armIdleTimer = () => {\n if (postExitTimer)\n clearTimeout(postExitTimer);\n postExitTimer = setTimeout(() => finalize(exitCode), EXIT_STDIO_GRACE_MS);\n };\n const onData = () => {\n // Output is still arriving after exit; defer finalizing so we don't\n // destroy the stream mid-write and truncate the tail.\n if (exited && !settled)\n armIdleTimer();\n };\n const onStdoutEnd = () => {\n stdoutEnded = true;\n maybeFinalizeAfterExit();\n };\n const onStderrEnd = () => {\n stderrEnded = true;\n maybeFinalizeAfterExit();\n };\n const onError = (err) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n reject(err);\n };\n const onExit = (code) => {\n exited = true;\n exitCode = code;\n maybeFinalizeAfterExit();\n if (!settled) {\n armIdleTimer();\n }\n };\n const onClose = (code) => {\n finalize(code);\n };\n child.stdout?.once(\"end\", onStdoutEnd);\n child.stderr?.once(\"end\", onStderrEnd);\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n child.once(\"error\", onError);\n child.once(\"exit\", onExit);\n child.once(\"close\", onClose);\n });\n}\n//# sourceMappingURL=child-process.js.map","// @ts-nocheck — vendored Pi source (utils/shell.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims; getBinDir inlined over the shim getAgentDir\n// (byte-identical to Pi: join(getAgentDir(), \"bin\")). Logic otherwise unchanged.\nimport { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { join as joinBinDir } from \"node:path\";\nimport { getAgentDir as getAgentDirForBin } from '../../pi-coding-agent.js';\nfunction getBinDir() { return joinBinDir(getAgentDirForBin(), \"bin\"); }\n/**\n * Find bash executable on PATH (cross-platform)\n */\nfunction isLegacyWslBashPath(path) {\n const normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n return /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\nfunction getBashShellConfig(shell) {\n return isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\nfunction findBashOnPath() {\n if (process.platform === \"win32\") {\n // Windows: Use 'where' and verify file exists (where can return non-existent paths)\n try {\n const result = spawnSync(\"where\", [\"bash.exe\"], {\n encoding: \"utf-8\",\n timeout: 5000,\n windowsHide: true,\n });\n if (result.status === 0 && result.stdout) {\n const firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n if (firstMatch && existsSync(firstMatch)) {\n return firstMatch;\n }\n }\n }\n catch {\n // Ignore errors\n }\n return null;\n }\n // Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n try {\n const result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n if (result.status === 0 && result.stdout) {\n const firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n if (firstMatch) {\n return firstMatch;\n }\n }\n }\n catch {\n // Ignore errors\n }\n return null;\n}\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath) {\n // 1. Check user-specified shell path\n if (customShellPath) {\n if (existsSync(customShellPath)) {\n return getBashShellConfig(customShellPath);\n }\n throw new Error(`Custom shell path not found: ${customShellPath}`);\n }\n if (process.platform === \"win32\") {\n // 2. Try Git Bash in known locations\n const paths = [];\n const programFiles = process.env.ProgramFiles;\n if (programFiles) {\n paths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n }\n const programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n if (programFilesX86) {\n paths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n }\n for (const path of paths) {\n if (existsSync(path)) {\n return getBashShellConfig(path);\n }\n }\n // 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n const bashOnPath = findBashOnPath();\n if (bashOnPath) {\n return getBashShellConfig(bashOnPath);\n }\n throw new Error(`No bash shell found. Options:\\n` +\n ` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n ` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n \" 3. Set shellPath in settings.json\\n\\n\" +\n `Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`);\n }\n // Unix: try /bin/bash, then bash on PATH, then fallback to sh\n if (existsSync(\"/bin/bash\")) {\n return getBashShellConfig(\"/bin/bash\");\n }\n const bashOnPath = findBashOnPath();\n if (bashOnPath) {\n return getBashShellConfig(bashOnPath);\n }\n return { shell: \"sh\", args: [\"-c\"] };\n}\nexport function getShellEnv() {\n const binDir = getBinDir();\n const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n const currentPath = process.env[pathKey] ?? \"\";\n const pathEntries = currentPath.split(delimiter).filter(Boolean);\n const hasBinDir = pathEntries.includes(binDir);\n const updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n return {\n ...process.env,\n [pathKey]: updatedPath,\n };\n}\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str) {\n // Use Array.from to properly iterate over code points (not code units)\n // This handles surrogate pairs correctly and catches edge cases where\n // codePointAt() might return undefined\n return Array.from(str)\n .filter((char) => {\n // Filter out characters that cause string-width to crash\n // This includes:\n // - Unicode format characters\n // - Lone surrogates (already filtered by Array.from)\n // - Control chars except \\t \\n \\r\n // - Characters with undefined code points\n const code = char.codePointAt(0);\n // Skip if code point is undefined (edge case with invalid strings)\n if (code === undefined)\n return false;\n // Allow tab, newline, carriage return\n if (code === 0x09 || code === 0x0a || code === 0x0d)\n return true;\n // Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0x0d)\n if (code <= 0x1f)\n return false;\n // Filter out Unicode format characters\n if (code >= 0xfff9 && code <= 0xfffb)\n return false;\n return true;\n })\n .join(\"\");\n}\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set();\nexport function trackDetachedChildPid(pid) {\n trackedDetachedChildPids.add(pid);\n}\nexport function untrackDetachedChildPid(pid) {\n trackedDetachedChildPids.delete(pid);\n}\nexport function killTrackedDetachedChildren() {\n for (const pid of trackedDetachedChildPids) {\n killProcessTree(pid);\n }\n trackedDetachedChildPids.clear();\n}\n/**\n * Kill a process and all its children (cross-platform)\n */\nexport function killProcessTree(pid) {\n if (process.platform === \"win32\") {\n // Use taskkill on Windows to kill process tree\n try {\n spawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n stdio: \"ignore\",\n detached: true,\n windowsHide: true,\n });\n }\n catch {\n // Ignore errors if taskkill fails\n }\n }\n else {\n // Use SIGKILL on Unix/Linux/Mac\n try {\n process.kill(-pid, \"SIGKILL\");\n }\n catch {\n // Fallback to killing just the child if process group kill fails\n try {\n process.kill(pid, \"SIGKILL\");\n }\n catch {\n // Process already dead\n }\n }\n }\n}\n//# sourceMappingURL=shell.js.map","// @ts-nocheck — vendored Pi source (core/tools/truncate.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared truncation utilities for tool outputs.\n *\n * Truncation is based on two independent limits - whichever is hit first wins:\n * - Line limit (default: 2000 lines)\n * - Byte limit (default: 50KB)\n *\n * Never returns partial lines (except bash tail truncation edge case).\n */\nexport const DEFAULT_MAX_LINES = 2000;\nexport const DEFAULT_MAX_BYTES = 50 * 1024; // 50KB\nexport const GREP_MAX_LINE_LENGTH = 500; // Max chars per grep match line\nfunction splitLinesForCounting(content) {\n if (content.length === 0) {\n return [];\n }\n const lines = content.split(\"\\n\");\n if (content.endsWith(\"\\n\")) {\n lines.pop();\n }\n return lines;\n}\n/**\n * Format bytes as human-readable size.\n */\nexport function formatSize(bytes) {\n if (bytes < 1024) {\n return `${bytes}B`;\n }\n else if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)}KB`;\n }\n else {\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n }\n}\n/**\n * Truncate content from the head (keep first N lines/bytes).\n * Suitable for file reads where you want to see the beginning.\n *\n * Never returns partial lines. If first line exceeds byte limit,\n * returns empty content with firstLineExceedsLimit=true.\n */\nexport function truncateHead(content, options = {}) {\n const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n const totalBytes = Buffer.byteLength(content, \"utf-8\");\n const lines = splitLinesForCounting(content);\n const totalLines = lines.length;\n // Check if no truncation needed\n if (totalLines <= maxLines && totalBytes <= maxBytes) {\n return {\n content,\n truncated: false,\n truncatedBy: null,\n totalLines,\n totalBytes,\n outputLines: totalLines,\n outputBytes: totalBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n }\n // Check if first line alone exceeds byte limit\n const firstLineBytes = Buffer.byteLength(lines[0], \"utf-8\");\n if (firstLineBytes > maxBytes) {\n return {\n content: \"\",\n truncated: true,\n truncatedBy: \"bytes\",\n totalLines,\n totalBytes,\n outputLines: 0,\n outputBytes: 0,\n lastLinePartial: false,\n firstLineExceedsLimit: true,\n maxLines,\n maxBytes,\n };\n }\n // Collect complete lines that fit\n const outputLinesArr = [];\n let outputBytesCount = 0;\n let truncatedBy = \"lines\";\n for (let i = 0; i < lines.length && i < maxLines; i++) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, \"utf-8\") + (i > 0 ? 1 : 0); // +1 for newline\n if (outputBytesCount + lineBytes > maxBytes) {\n truncatedBy = \"bytes\";\n break;\n }\n outputLinesArr.push(line);\n outputBytesCount += lineBytes;\n }\n // If we exited due to line limit\n if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n truncatedBy = \"lines\";\n }\n const outputContent = outputLinesArr.join(\"\\n\");\n const finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n return {\n content: outputContent,\n truncated: true,\n truncatedBy,\n totalLines,\n totalBytes,\n outputLines: outputLinesArr.length,\n outputBytes: finalOutputBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n}\n/**\n * Truncate content from the tail (keep last N lines/bytes).\n * Suitable for bash output where you want to see the end (errors, final results).\n *\n * May return partial first line if the last line of original content exceeds byte limit.\n */\nexport function truncateTail(content, options = {}) {\n const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n const totalBytes = Buffer.byteLength(content, \"utf-8\");\n const lines = splitLinesForCounting(content);\n const totalLines = lines.length;\n // Check if no truncation needed\n if (totalLines <= maxLines && totalBytes <= maxBytes) {\n return {\n content,\n truncated: false,\n truncatedBy: null,\n totalLines,\n totalBytes,\n outputLines: totalLines,\n outputBytes: totalBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n }\n // Work backwards from the end\n const outputLinesArr = [];\n let outputBytesCount = 0;\n let truncatedBy = \"lines\";\n let lastLinePartial = false;\n for (let i = lines.length - 1; i >= 0 && outputLinesArr.length < maxLines; i--) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, \"utf-8\") + (outputLinesArr.length > 0 ? 1 : 0); // +1 for newline\n if (outputBytesCount + lineBytes > maxBytes) {\n truncatedBy = \"bytes\";\n // Edge case: if we haven't added ANY lines yet and this line exceeds maxBytes,\n // take the end of the line (partial)\n if (outputLinesArr.length === 0) {\n const truncatedLine = truncateStringToBytesFromEnd(line, maxBytes);\n outputLinesArr.unshift(truncatedLine);\n outputBytesCount = Buffer.byteLength(truncatedLine, \"utf-8\");\n lastLinePartial = true;\n }\n break;\n }\n outputLinesArr.unshift(line);\n outputBytesCount += lineBytes;\n }\n // If we exited due to line limit\n if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n truncatedBy = \"lines\";\n }\n const outputContent = outputLinesArr.join(\"\\n\");\n const finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n return {\n content: outputContent,\n truncated: true,\n truncatedBy,\n totalLines,\n totalBytes,\n outputLines: outputLinesArr.length,\n outputBytes: finalOutputBytes,\n lastLinePartial,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n}\n/**\n * Truncate a string to fit within a byte limit (from the end).\n * Handles multi-byte UTF-8 characters correctly.\n */\nfunction truncateStringToBytesFromEnd(str, maxBytes) {\n const buf = Buffer.from(str, \"utf-8\");\n if (buf.length <= maxBytes) {\n return str;\n }\n // Start from the end, skip maxBytes back\n let start = buf.length - maxBytes;\n // Find a valid UTF-8 boundary (start of a character)\n while (start < buf.length && (buf[start] & 0xc0) === 0x80) {\n start++;\n }\n return buf.slice(start).toString(\"utf-8\");\n}\n/**\n * Truncate a single line to max characters, adding [truncated] suffix.\n * Used for grep match lines.\n */\nexport function truncateLine(line, maxChars = GREP_MAX_LINE_LENGTH) {\n if (line.length <= maxChars) {\n return { text: line, wasTruncated: false };\n }\n return { text: `${line.slice(0, maxChars)}... [truncated]`, wasTruncated: true };\n}\n//# sourceMappingURL=truncate.js.map","// @ts-nocheck — vendored Pi source (core/tools/output-accumulator.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from \"./truncate.js\";\nfunction defaultTempFilePath(prefix) {\n const id = randomBytes(8).toString(\"hex\");\n return join(tmpdir(), `${prefix}-${id}.log`);\n}\nfunction byteLength(text) {\n return Buffer.byteLength(text, \"utf-8\");\n}\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n maxLines;\n maxBytes;\n maxRollingBytes;\n tempFilePrefix;\n decoder = new TextDecoder();\n rawChunks = [];\n tailText = \"\";\n tailBytes = 0;\n tailStartsAtLineBoundary = true;\n totalRawBytes = 0;\n totalDecodedBytes = 0;\n completedLines = 0;\n totalLines = 0;\n currentLineBytes = 0;\n hasOpenLine = false;\n finished = false;\n tempFilePath;\n tempFileStream;\n constructor(options = {}) {\n this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n this.maxRollingBytes = Math.max(this.maxBytes * 2, 1);\n this.tempFilePrefix = options.tempFilePrefix ?? \"pi-output\";\n }\n append(data) {\n if (this.finished) {\n throw new Error(\"Cannot append to a finished output accumulator\");\n }\n this.totalRawBytes += data.length;\n this.appendDecodedText(this.decoder.decode(data, { stream: true }));\n if (this.tempFileStream || this.shouldUseTempFile()) {\n this.ensureTempFile();\n this.tempFileStream?.write(data);\n }\n else if (data.length > 0) {\n this.rawChunks.push(data);\n }\n }\n finish() {\n if (this.finished) {\n return;\n }\n this.finished = true;\n this.appendDecodedText(this.decoder.decode());\n if (this.shouldUseTempFile()) {\n this.ensureTempFile();\n }\n }\n snapshot(options = {}) {\n const tailTruncation = truncateTail(this.getSnapshotText(), {\n maxLines: this.maxLines,\n maxBytes: this.maxBytes,\n });\n const truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n const truncatedBy = truncated\n ? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n : null;\n const truncation = {\n ...tailTruncation,\n truncated,\n truncatedBy,\n totalLines: this.totalLines,\n totalBytes: this.totalDecodedBytes,\n maxLines: this.maxLines,\n maxBytes: this.maxBytes,\n };\n if (options.persistIfTruncated && truncation.truncated) {\n this.ensureTempFile();\n }\n return {\n content: truncation.content,\n truncation,\n fullOutputPath: this.tempFilePath,\n };\n }\n async closeTempFile() {\n if (!this.tempFileStream) {\n return;\n }\n const stream = this.tempFileStream;\n this.tempFileStream = undefined;\n await new Promise((resolve, reject) => {\n const onError = (error) => {\n stream.off(\"finish\", onFinish);\n reject(error);\n };\n const onFinish = () => {\n stream.off(\"error\", onError);\n resolve();\n };\n stream.once(\"error\", onError);\n stream.once(\"finish\", onFinish);\n stream.end();\n });\n }\n getLastLineBytes() {\n return this.currentLineBytes;\n }\n appendDecodedText(text) {\n if (text.length === 0) {\n return;\n }\n const bytes = byteLength(text);\n this.totalDecodedBytes += bytes;\n this.tailText += text;\n this.tailBytes += bytes;\n if (this.tailBytes > this.maxRollingBytes * 2) {\n this.trimTail();\n }\n let newlines = 0;\n let lastNewline = -1;\n for (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n newlines++;\n lastNewline = i;\n }\n if (newlines === 0) {\n this.currentLineBytes += bytes;\n this.hasOpenLine = true;\n }\n else {\n this.completedLines += newlines;\n const tail = text.slice(lastNewline + 1);\n this.currentLineBytes = byteLength(tail);\n this.hasOpenLine = tail.length > 0;\n }\n this.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n }\n trimTail() {\n const buffer = Buffer.from(this.tailText, \"utf-8\");\n if (buffer.length <= this.maxRollingBytes) {\n this.tailBytes = buffer.length;\n return;\n }\n let start = buffer.length - this.maxRollingBytes;\n while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n start++;\n }\n this.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;\n this.tailText = buffer.subarray(start).toString(\"utf-8\");\n this.tailBytes = byteLength(this.tailText);\n }\n getSnapshotText() {\n if (this.tailStartsAtLineBoundary) {\n return this.tailText;\n }\n const firstNewline = this.tailText.indexOf(\"\\n\");\n return firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);\n }\n shouldUseTempFile() {\n return (this.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines);\n }\n ensureTempFile() {\n if (this.tempFilePath) {\n return;\n }\n this.tempFilePath = defaultTempFilePath(this.tempFilePrefix);\n this.tempFileStream = createWriteStream(this.tempFilePath);\n for (const chunk of this.rawChunks) {\n this.tempFileStream.write(chunk);\n }\n this.rawChunks = [];\n }\n}\n//# sourceMappingURL=output-accumulator.js.map","// @ts-nocheck — vendored Pi source (utils/ansi.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/*\n * Portions of this file are derived from:\n * - ansi-regex (https://github.com/chalk/ansi-regex)\n * - strip-ansi (https://github.com/chalk/strip-ansi)\n *\n * MIT License\n *\n * Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nfunction ansiRegex({ onlyFirst = false } = {}) {\n // Valid string terminator sequences are BEL, ESC\\, and 0x9c\n const ST = \"(?:\\\\u0007|\\\\u001B\\\\u005C|\\\\u009C)\";\n // OSC sequences only: ESC ] ... ST (non-greedy until the first ST)\n const osc = `(?:\\\\u001B\\\\][\\\\s\\\\S]*?${ST})`;\n // CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte\n const csi = \"[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:\\\\d{1,4}(?:[;:]\\\\d{0,4})*)?[\\\\dA-PR-TZcf-nq-uy=><~]\";\n const pattern = `${osc}|${csi}`;\n return new RegExp(pattern, onlyFirst ? undefined : \"g\");\n}\nconst regex = ansiRegex();\nexport function stripAnsi(value) {\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected a \\`string\\`, got \\`${typeof value}\\``);\n }\n // Fast path: ANSI codes require ESC (7-bit) or CSI (8-bit) introducer\n if (!value.includes(\"\\u001B\") && !value.includes(\"\\u009B\")) {\n return value;\n }\n // Even though the regex is global, we don't need to reset the `.lastIndex`\n // because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n // and doing it manually has a performance penalty.\n return value.replace(regex, \"\");\n}\n//# sourceMappingURL=ansi.js.map","// @ts-nocheck — vendored Pi source (utils/paths.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve as nodeResolvePath, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnProcessSync } from \"./child-process.js\";\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n/**\n * Resolve a path to its canonical (real) form, following symlinks.\n * Falls back to the raw path if resolution fails (e.g. the target does\n * not exist yet), so that callers never crash on missing filesystem\n * entries.\n */\nexport function canonicalizePath(path) {\n try {\n return realpathSync(path);\n }\n catch {\n return path;\n }\n}\nexport function getFileRevision(path) {\n try {\n const stats = statSync(path, { bigint: true });\n return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeNs}:${stats.ctimeNs}`;\n }\n catch {\n return undefined;\n }\n}\n/**\n * Returns true if the value is NOT a package source (npm:, git:, etc.)\n * or a remote URL protocol. Bare names, relative paths, and file: URLs\n * are considered local.\n */\nexport function isLocalPath(value) {\n const trimmed = value.trim();\n // Known non-local prefixes. file: URLs are local paths and are intentionally resolved by resolvePath().\n if (trimmed.startsWith(\"npm:\") ||\n trimmed.startsWith(\"git:\") ||\n trimmed.startsWith(\"github:\") ||\n trimmed.startsWith(\"http:\") ||\n trimmed.startsWith(\"https:\") ||\n trimmed.startsWith(\"ssh:\")) {\n return false;\n }\n return true;\n}\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath) {\n if (!filePath.startsWith(\"/\") || filePath.startsWith(\"//\") || filePath.includes(\"\\\\\"))\n return filePath;\n const match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i);\n if (!match)\n return filePath;\n const suffix = match[2]?.replaceAll(\"/\", \"\\\\\");\n return `${match[1].toUpperCase()}:\\\\${suffix ?? \"\"}`;\n}\nexport function normalizePath(input, options = {}) {\n let normalized = options.trim ? input.trim() : input;\n if (options.normalizeUnicodeSpaces) {\n normalized = normalized.replace(UNICODE_SPACES, \" \");\n }\n if (options.stripAtPrefix && normalized.startsWith(\"@\")) {\n normalized = normalized.slice(1);\n }\n if (process.platform === \"win32\") {\n normalized = normalizeWindowsShellPath(normalized);\n }\n if (options.expandTilde ?? true) {\n const home = options.homeDir ?? homedir();\n if (normalized === \"~\")\n return home;\n if (normalized.startsWith(\"~/\") || (process.platform === \"win32\" && normalized.startsWith(\"~\\\\\"))) {\n return join(home, normalized.slice(2));\n }\n }\n if (/^file:\\/\\//.test(normalized)) {\n return fileURLToPath(normalized);\n }\n return normalized;\n}\nexport function resolvePath(input, baseDir = process.cwd(), options = {}) {\n const normalized = normalizePath(input, options);\n const normalizedBaseDir = normalizePath(baseDir);\n return isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized);\n}\nexport function getCwdRelativePath(filePath, cwd) {\n const resolvedCwd = resolvePath(cwd);\n const resolvedPath = resolvePath(filePath, resolvedCwd);\n const relativePath = relative(resolvedCwd, resolvedPath);\n const isInsideCwd = relativePath === \"\" ||\n (relativePath !== \"..\" && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath));\n return isInsideCwd ? relativePath || \".\" : undefined;\n}\nexport function formatPathRelativeToCwdOrAbsolute(filePath, cwd) {\n const absolutePath = resolvePath(filePath, cwd);\n return (getCwdRelativePath(absolutePath, cwd) ?? absolutePath).split(sep).join(\"/\");\n}\nexport function markPathIgnoredByCloudSync(path) {\n const attrs = process.platform === \"darwin\"\n ? [\"com.dropbox.ignored\", \"com.apple.fileprovider.ignore#P\"]\n : process.platform === \"linux\"\n ? [\"user.com.dropbox.ignored\"]\n : [];\n for (const attr of attrs) {\n if (process.platform === \"darwin\") {\n spawnProcessSync(\"xattr\", [\"-w\", attr, \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n }\n else {\n spawnProcessSync(\"setfattr\", [\"-n\", attr, \"-v\", \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n }\n }\n}\n//# sourceMappingURL=paths.js.map","// @ts-nocheck — vendored Pi source (core/tools/render-utils.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport * as os from \"node:os\";\nimport { pathToFileURL } from \"node:url\";\nimport { getCapabilities, getImageDimensions, hyperlink, imageFallback } from '../../pi-tui.js';\nimport { stripAnsi } from './ansi.js';\nimport { resolvePath } from './paths.js';\nimport { sanitizeBinaryOutput } from './shell.js';\nexport function shortenPath(path) {\n if (typeof path !== \"string\")\n return \"\";\n const home = os.homedir();\n if (path.startsWith(home)) {\n return `~${path.slice(home.length)}`;\n }\n return path;\n}\nexport function linkPath(styledText, rawPath, cwd) {\n if (!getCapabilities().hyperlinks)\n return styledText;\n const absolutePath = resolvePath(rawPath, cwd);\n return hyperlink(styledText, pathToFileURL(absolutePath).href);\n}\nexport function str(value) {\n if (typeof value === \"string\")\n return value;\n if (value == null)\n return \"\";\n return null;\n}\nexport function replaceTabs(text) {\n return text.replace(/\\t/g, \" \");\n}\nexport function normalizeDisplayText(text) {\n return text.replace(/\\r/g, \"\");\n}\nexport function getTextOutput(result, showImages) {\n if (!result)\n return \"\";\n const textBlocks = result.content.filter((c) => c.type === \"text\");\n const imageBlocks = result.content.filter((c) => c.type === \"image\");\n let output = textBlocks.map((c) => sanitizeBinaryOutput(stripAnsi(c.text || \"\")).replace(/\\r/g, \"\")).join(\"\\n\");\n const caps = getCapabilities();\n if (imageBlocks.length > 0 && (!caps.images || !showImages)) {\n const imageIndicators = imageBlocks\n .map((img) => {\n const mimeType = img.mimeType ?? \"image/unknown\";\n const dims = img.data && img.mimeType ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;\n return imageFallback(mimeType, dims);\n })\n .join(\"\\n\");\n output = output ? `${output}\\n${imageIndicators}` : imageIndicators;\n }\n return output;\n}\nexport function invalidArgText(theme) {\n return theme.fg(\"error\", \"[invalid arg]\");\n}\nexport function renderToolPath(rawPath, theme, cwd, options) {\n if (rawPath === null)\n return invalidArgText(theme);\n const value = rawPath || options?.emptyFallback;\n if (!value)\n return theme.fg(\"toolOutput\", \"...\");\n return linkPath(theme.fg(\"accent\", shortenPath(value)), value, cwd);\n}\n//# sourceMappingURL=render-utils.js.map","// @ts-nocheck — vendored Pi source (core/tools/tool-definition-wrapper.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition(definition, ctxFactory) {\n return {\n name: definition.name,\n label: definition.label,\n description: definition.description,\n parameters: definition.parameters,\n constrainedSampling: definition.constrainedSampling,\n prepareArguments: definition.prepareArguments,\n executionMode: definition.executionMode,\n execute: (toolCallId, params, signal, onUpdate, ctx) => definition.execute(toolCallId, params, signal, onUpdate, ctx ?? ctxFactory?.()),\n };\n}\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(definitions, ctxFactory) {\n return definitions.map((definition) => wrapToolDefinition(definition, ctxFactory));\n}\n/**\n * Synthesize a minimal ToolDefinition from an AgentTool.\n *\n * This keeps AgentSession's internal registry definition-first even when a caller\n * provides plain AgentTool overrides that do not include prompt metadata or renderers.\n */\nexport function createToolDefinitionFromAgentTool(tool) {\n return {\n name: tool.name,\n label: tool.label,\n description: tool.description,\n parameters: tool.parameters,\n constrainedSampling: tool.constrainedSampling,\n prepareArguments: tool.prepareArguments,\n executionMode: tool.executionMode,\n execute: async (toolCallId, params, signal, onUpdate) => tool.execute(toolCallId, params, signal, onUpdate),\n };\n}\n//# sourceMappingURL=tool-definition-wrapper.js.map","// @ts-nocheck — vendored Pi source (core/tools/bash.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { constants } from \"node:fs\";\nimport { access as fsAccess } from \"node:fs/promises\";\nimport { Container, Text, truncateToWidth } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { truncateToVisualLines } from './visual-truncate.js';\nimport { theme } from '../../pi-coding-agent.js';\nimport { waitForChildProcess } from './child-process.js';\nimport { getShellConfig, getShellEnv, killProcessTree, trackDetachedChildPid, untrackDetachedChildPid, } from './shell.js';\nimport { OutputAccumulator } from \"./output-accumulator.js\";\nimport { getTextOutput, invalidArgText, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from \"./truncate.js\";\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;\nfunction resolveTimeoutMs(timeout) {\n if (timeout === undefined)\n return undefined;\n if (!Number.isFinite(timeout) || timeout <= 0) {\n throw new Error(\"Invalid timeout: must be a finite number of seconds\");\n }\n const timeoutMs = timeout * 1000;\n if (timeoutMs > MAX_TIMEOUT_MS) {\n throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);\n }\n return timeoutMs;\n}\nconst bashSchema = Type.Object({\n command: Type.String({ description: \"Bash command to execute\" }),\n timeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\nexport const bashToolSystemPromptContribution = {\n snippet: \"Execute bash commands (ls, grep, find, etc.)\",\n guidelines: [\"You can inspect PI_* environment variables for current model and session details.\"],\n};\n/**\n * Create bash operations using pi's built-in local shell execution backend.\n *\n * This is useful for extensions that intercept user_bash and still want pi's\n * standard local shell behavior while wrapping or rewriting commands.\n */\nexport function createLocalBashOperations(options) {\n return {\n exec: async (command, cwd, { onData, signal, timeout, env }) => {\n const timeoutMs = resolveTimeoutMs(timeout);\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n const shellConfig = getShellConfig(options?.shellPath);\n try {\n await fsAccess(cwd, constants.F_OK);\n }\n catch {\n throw new Error(`Working directory does not exist: ${cwd}\\nCannot execute bash commands.`);\n }\n const commandFromStdin = shellConfig.commandTransport === \"stdin\";\n const child = spawn(shellConfig.shell, commandFromStdin ? shellConfig.args : [...shellConfig.args, command], {\n cwd,\n detached: process.platform !== \"win32\",\n env: env ?? getShellEnv(),\n stdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n });\n if (commandFromStdin) {\n child.stdin?.on(\"error\", () => { });\n child.stdin?.end(command);\n }\n if (child.pid)\n trackDetachedChildPid(child.pid);\n let timedOut = false;\n let timeoutHandle;\n const onAbort = () => {\n if (child.pid)\n killProcessTree(child.pid);\n };\n try {\n // Set timeout if provided.\n if (timeoutMs !== undefined) {\n timeoutHandle = setTimeout(() => {\n timedOut = true;\n if (child.pid)\n killProcessTree(child.pid);\n }, timeoutMs);\n }\n // Stream stdout and stderr.\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n // Handle abort signal by killing the entire process tree.\n if (signal) {\n if (signal.aborted)\n onAbort();\n else\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n // Handle shell spawn errors and wait for the process to terminate without hanging\n // on inherited stdio handles held by detached descendants.\n const exitCode = await waitForChildProcess(child);\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n if (timedOut) {\n throw new Error(`timeout:${timeout}`);\n }\n return { exitCode };\n }\n finally {\n if (child.pid)\n untrackDetachedChildPid(child.pid);\n if (timeoutHandle)\n clearTimeout(timeoutHandle);\n if (signal)\n signal.removeEventListener(\"abort\", onAbort);\n }\n },\n };\n}\nfunction resolveSpawnContext(command, cwd, spawnHook, exposeSessionEnvironment, ctx) {\n const env = { ...getShellEnv() };\n delete env.PI_SESSION_ID;\n delete env.PI_SESSION_FILE;\n delete env.PI_PROVIDER;\n delete env.PI_MODEL;\n delete env.PI_REASONING_LEVEL;\n if (exposeSessionEnvironment && ctx) {\n const model = ctx.model;\n env.PI_SESSION_ID = ctx.sessionManager.getSessionId();\n const sessionFile = ctx.sessionManager.getSessionFile();\n if (sessionFile)\n env.PI_SESSION_FILE = sessionFile;\n if (model) {\n env.PI_PROVIDER = model.provider;\n env.PI_MODEL = model.id;\n }\n if (ctx.thinkingLevel)\n env.PI_REASONING_LEVEL = ctx.thinkingLevel;\n }\n const baseContext = { command, cwd, env };\n return spawnHook ? spawnHook(baseContext) : baseContext;\n}\nconst BASH_PREVIEW_LINES = 5;\nconst BASH_UPDATE_THROTTLE_MS = 100;\nclass BashResultRenderComponent extends Container {\n state = {\n cachedWidth: undefined,\n cachedLines: undefined,\n cachedSkipped: undefined,\n };\n}\nfunction formatDuration(ms) {\n return `${(ms / 1000).toFixed(1)}s`;\n}\nfunction formatBashCall(args) {\n const command = str(args?.command);\n const timeout = args?.timeout;\n const timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n const commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n return theme.fg(\"toolTitle\", theme.bold(`$ ${commandDisplay}`)) + timeoutSuffix;\n}\nfunction rebuildBashResultRenderComponent(component, result, options, showImages, startedAt, endedAt) {\n const state = component.state;\n component.clear();\n let output = getTextOutput(result, showImages).trim();\n const truncation = result.details?.truncation;\n const fullOutputPath = result.details?.fullOutputPath;\n if (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n const footerStart = output.lastIndexOf(\"\\n\\n[\");\n if (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n output = output.slice(0, footerStart).trimEnd();\n }\n }\n if (output) {\n const styledOutput = output\n .split(\"\\n\")\n .map((line) => theme.fg(\"toolOutput\", line))\n .join(\"\\n\");\n if (options.expanded) {\n component.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n }\n else {\n component.addChild({\n render: (width) => {\n if (state.cachedLines === undefined || state.cachedWidth !== width) {\n const preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);\n state.cachedLines = preview.visualLines;\n state.cachedSkipped = preview.skippedCount;\n state.cachedWidth = width;\n }\n if (state.cachedSkipped && state.cachedSkipped > 0) {\n const hint = theme.fg(\"muted\", `... (${state.cachedSkipped} earlier lines,`) +\n ` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n return [\"\", truncateToWidth(hint, width, \"...\"), ...(state.cachedLines ?? [])];\n }\n return [\"\", ...(state.cachedLines ?? [])];\n },\n invalidate: () => {\n state.cachedWidth = undefined;\n state.cachedLines = undefined;\n state.cachedSkipped = undefined;\n },\n });\n }\n }\n if (truncation?.truncated || fullOutputPath) {\n const warnings = [];\n if (fullOutputPath) {\n warnings.push(`Full output: ${fullOutputPath}`);\n }\n if (truncation?.truncated) {\n if (truncation.truncatedBy === \"lines\") {\n warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n }\n else {\n warnings.push(`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`);\n }\n }\n component.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n }\n if (startedAt !== undefined) {\n const label = options.isPartial ? \"Elapsed\" : \"Took\";\n const endTime = endedAt ?? Date.now();\n component.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n }\n}\nexport function createBashToolDefinition(cwd, options) {\n const ops = options?.operations ?? createLocalBashOperations({ shellPath: options?.shellPath });\n const commandPrefix = options?.commandPrefix;\n const exposeSessionEnvironment = options?.exposeSessionEnvironment ?? true;\n const spawnHook = options?.spawnHook;\n return {\n name: \"bash\",\n label: \"bash\",\n description: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n promptSnippet: bashToolSystemPromptContribution.snippet,\n promptGuidelines: exposeSessionEnvironment ? [...bashToolSystemPromptContribution.guidelines] : undefined,\n parameters: bashSchema,\n async execute(_toolCallId, { command, timeout }, signal, onUpdate, ctx) {\n const resolvedCommand = commandPrefix ? `${commandPrefix}\\n${command}` : command;\n const spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook, exposeSessionEnvironment, ctx);\n const output = new OutputAccumulator({ tempFilePrefix: \"pi-bash\" });\n let acceptingOutput = true;\n let updateTimer;\n let updateDirty = false;\n let lastUpdateAt = 0;\n const emitOutputUpdate = () => {\n if (!onUpdate || !updateDirty)\n return;\n updateDirty = false;\n lastUpdateAt = Date.now();\n const snapshot = output.snapshot({ persistIfTruncated: true });\n onUpdate({\n content: [{ type: \"text\", text: snapshot.content || \"\" }],\n details: {\n truncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,\n fullOutputPath: snapshot.fullOutputPath,\n },\n });\n };\n const clearUpdateTimer = () => {\n if (updateTimer) {\n clearTimeout(updateTimer);\n updateTimer = undefined;\n }\n };\n const scheduleOutputUpdate = () => {\n if (!onUpdate)\n return;\n updateDirty = true;\n const delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);\n if (delay <= 0) {\n clearUpdateTimer();\n emitOutputUpdate();\n return;\n }\n updateTimer ??= setTimeout(() => {\n updateTimer = undefined;\n emitOutputUpdate();\n }, delay);\n };\n if (onUpdate) {\n onUpdate({ content: [], details: undefined });\n }\n const handleData = (data) => {\n if (!acceptingOutput)\n return;\n output.append(data);\n scheduleOutputUpdate();\n };\n const finishOutput = async () => {\n acceptingOutput = false;\n output.finish();\n clearUpdateTimer();\n emitOutputUpdate();\n const snapshot = output.snapshot({ persistIfTruncated: true });\n await output.closeTempFile();\n return snapshot;\n };\n const formatOutput = (snapshot, emptyText = \"(no output)\") => {\n const truncation = snapshot.truncation;\n let text = snapshot.content || emptyText;\n let details;\n if (truncation.truncated) {\n details = { truncation, fullOutputPath: snapshot.fullOutputPath };\n const startLine = truncation.totalLines - truncation.outputLines + 1;\n const endLine = truncation.totalLines;\n if (truncation.lastLinePartial) {\n const lastLineSize = formatSize(output.getLastLineBytes());\n text += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;\n }\n else if (truncation.truncatedBy === \"lines\") {\n text += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;\n }\n else {\n text += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;\n }\n }\n return { text, details };\n };\n const appendStatus = (text, status) => `${text ? `${text}\\n\\n` : \"\"}${status}`;\n try {\n let exitCode;\n try {\n const result = await ops.exec(spawnContext.command, spawnContext.cwd, {\n onData: handleData,\n signal,\n timeout,\n env: spawnContext.env,\n });\n exitCode = result.exitCode;\n }\n catch (err) {\n const snapshot = await finishOutput();\n const { text } = formatOutput(snapshot, \"\");\n if (err instanceof Error && err.message === \"aborted\") {\n throw new Error(appendStatus(text, \"Command aborted\"));\n }\n if (err instanceof Error && err.message.startsWith(\"timeout:\")) {\n const timeoutSecs = err.message.split(\":\")[1];\n throw new Error(appendStatus(text, `Command timed out after ${timeoutSecs} seconds`));\n }\n throw err;\n }\n const snapshot = await finishOutput();\n const { text: outputText, details } = formatOutput(snapshot);\n if (exitCode !== 0 && exitCode !== null) {\n throw new Error(appendStatus(outputText, `Command exited with code ${exitCode}`));\n }\n return { content: [{ type: \"text\", text: outputText }], details };\n }\n finally {\n clearUpdateTimer();\n }\n },\n renderCall(args, _theme, context) {\n const state = context.state;\n if (context.executionStarted && state.startedAt === undefined) {\n state.startedAt = Date.now();\n state.endedAt = undefined;\n }\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatBashCall(args));\n return text;\n },\n renderResult(result, options, _theme, context) {\n const state = context.state;\n if (state.startedAt !== undefined && options.isPartial && !state.interval) {\n state.interval = setInterval(() => context.invalidate(), 1000);\n }\n if (!options.isPartial || context.isError) {\n state.endedAt ??= Date.now();\n if (state.interval) {\n clearInterval(state.interval);\n state.interval = undefined;\n }\n }\n const component = context.lastComponent ?? new BashResultRenderComponent();\n rebuildBashResultRenderComponent(component, result, options, context.showImages, state.startedAt, state.endedAt);\n component.invalidate();\n return component;\n },\n };\n}\nexport function createBashTool(cwd, options) {\n const definition = createBashToolDefinition(cwd, options);\n const tool = wrapToolDefinition(definition);\n Object.assign(tool, {\n promptSnippet: definition.promptSnippet,\n promptGuidelines: definition.promptGuidelines,\n });\n return tool;\n}\n//# sourceMappingURL=bash.js.map","// @ts-nocheck — vendored Pi source (utils/mime.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { open } from \"node:fs/promises\";\nconst IMAGE_TYPE_SNIFF_BYTES = 4100;\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\nexport function detectSupportedImageMimeType(buffer) {\n if (startsWith(buffer, [0xff, 0xd8, 0xff])) {\n return buffer[3] === 0xf7 ? null : \"image/jpeg\";\n }\n if (startsWith(buffer, PNG_SIGNATURE)) {\n return isPng(buffer) && !isAnimatedPng(buffer) ? \"image/png\" : null;\n }\n if (startsWithAscii(buffer, 0, \"GIF\")) {\n return \"image/gif\";\n }\n if (startsWithAscii(buffer, 0, \"RIFF\") && startsWithAscii(buffer, 8, \"WEBP\")) {\n return \"image/webp\";\n }\n if (startsWithAscii(buffer, 0, \"BM\") && isBmp(buffer)) {\n return \"image/bmp\";\n }\n return null;\n}\nexport async function detectSupportedImageMimeTypeFromFile(filePath) {\n const fileHandle = await open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(IMAGE_TYPE_SNIFF_BYTES);\n const { bytesRead } = await fileHandle.read(buffer, 0, IMAGE_TYPE_SNIFF_BYTES, 0);\n return detectSupportedImageMimeType(buffer.subarray(0, bytesRead));\n }\n finally {\n await fileHandle.close();\n }\n}\nfunction isPng(buffer) {\n return (buffer.length >= 16 && readUint32BE(buffer, PNG_SIGNATURE.length) === 13 && startsWithAscii(buffer, 12, \"IHDR\"));\n}\nfunction isAnimatedPng(buffer) {\n let offset = PNG_SIGNATURE.length;\n while (offset + 8 <= buffer.length) {\n const chunkLength = readUint32BE(buffer, offset);\n const chunkTypeOffset = offset + 4;\n if (startsWithAscii(buffer, chunkTypeOffset, \"acTL\"))\n return true;\n if (startsWithAscii(buffer, chunkTypeOffset, \"IDAT\"))\n return false;\n const nextOffset = offset + 8 + chunkLength + 4;\n if (nextOffset <= offset || nextOffset > buffer.length)\n return false;\n offset = nextOffset;\n }\n return false;\n}\nfunction isBmp(buffer) {\n if (buffer.length < 26)\n return false;\n const declaredFileSize = readUint32LE(buffer, 2);\n const pixelDataOffset = readUint32LE(buffer, 10);\n const dibHeaderSize = readUint32LE(buffer, 14);\n if (declaredFileSize !== 0 && declaredFileSize < 26)\n return false;\n if (pixelDataOffset < 14 + dibHeaderSize)\n return false;\n if (declaredFileSize !== 0 && pixelDataOffset >= declaredFileSize)\n return false;\n let colorPlanes;\n let bitsPerPixel;\n if (dibHeaderSize === 12) {\n colorPlanes = readUint16LE(buffer, 22);\n bitsPerPixel = readUint16LE(buffer, 24);\n }\n else if (dibHeaderSize >= 40 && dibHeaderSize <= 124) {\n if (buffer.length < 30)\n return false;\n colorPlanes = readUint16LE(buffer, 26);\n bitsPerPixel = readUint16LE(buffer, 28);\n }\n else {\n return false;\n }\n return colorPlanes === 1 && [1, 4, 8, 16, 24, 32].includes(bitsPerPixel);\n}\nfunction readUint16LE(buffer, offset) {\n return (buffer[offset] ?? 0) + ((buffer[offset + 1] ?? 0) << 8);\n}\nfunction readUint32BE(buffer, offset) {\n return ((buffer[offset] ?? 0) * 0x1000000 +\n ((buffer[offset + 1] ?? 0) << 16) +\n ((buffer[offset + 2] ?? 0) << 8) +\n (buffer[offset + 3] ?? 0));\n}\nfunction readUint32LE(buffer, offset) {\n return ((buffer[offset] ?? 0) +\n ((buffer[offset + 1] ?? 0) << 8) +\n ((buffer[offset + 2] ?? 0) << 16) +\n (buffer[offset + 3] ?? 0) * 0x1000000);\n}\nfunction startsWith(buffer, bytes) {\n if (buffer.length < bytes.length)\n return false;\n return bytes.every((byte, index) => buffer[index] === byte);\n}\nfunction startsWithAscii(buffer, offset, text) {\n if (buffer.length < offset + text.length)\n return false;\n for (let index = 0; index < text.length; index++) {\n if (buffer[offset + index] !== text.charCodeAt(index))\n return false;\n }\n return true;\n}\n//# sourceMappingURL=mime.js.map","// @ts-nocheck — vendored Pi source (core/tools/path-utils.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { accessSync, constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { normalizePath, resolvePath } from './paths.js';\nconst NARROW_NO_BREAK_SPACE = \"\\u202F\";\nfunction tryMacOSScreenshotPath(filePath) {\n return filePath.replace(/ (AM|PM)\\./gi, `${NARROW_NO_BREAK_SPACE}$1.`);\n}\nfunction tryNFDVariant(filePath) {\n // macOS stores filenames in NFD (decomposed) form, try converting user input to NFD\n return filePath.normalize(\"NFD\");\n}\nfunction tryCurlyQuoteVariant(filePath) {\n // macOS uses U+2019 (right single quotation mark) in screenshot names like \"Capture d'écran\"\n // Users typically type U+0027 (straight apostrophe)\n return filePath.replace(/'/g, \"\\u2019\");\n}\nfunction fileExists(filePath) {\n try {\n accessSync(filePath, constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nexport async function pathExists(filePath) {\n try {\n await access(filePath, constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nexport function expandPath(filePath) {\n return normalizePath(filePath, { normalizeUnicodeSpaces: true, stripAtPrefix: true });\n}\n/**\n * Resolve a path relative to the given cwd.\n * Handles ~ expansion and absolute paths.\n */\nexport function resolveToCwd(filePath, cwd) {\n return resolvePath(filePath, cwd, { normalizeUnicodeSpaces: true, stripAtPrefix: true });\n}\nexport function resolveReadPath(filePath, cwd) {\n const resolved = resolveToCwd(filePath, cwd);\n if (fileExists(resolved)) {\n return resolved;\n }\n // Try macOS AM/PM variant (narrow no-break space before AM/PM)\n const amPmVariant = tryMacOSScreenshotPath(resolved);\n if (amPmVariant !== resolved && fileExists(amPmVariant)) {\n return amPmVariant;\n }\n // Try NFD variant (macOS stores filenames in NFD form)\n const nfdVariant = tryNFDVariant(resolved);\n if (nfdVariant !== resolved && fileExists(nfdVariant)) {\n return nfdVariant;\n }\n // Try curly quote variant (macOS uses U+2019 in screenshot names)\n const curlyVariant = tryCurlyQuoteVariant(resolved);\n if (curlyVariant !== resolved && fileExists(curlyVariant)) {\n return curlyVariant;\n }\n // Try combined NFD + curly quote (for French macOS screenshots like \"Capture d'écran\")\n const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant);\n if (nfdCurlyVariant !== resolved && fileExists(nfdCurlyVariant)) {\n return nfdCurlyVariant;\n }\n return resolved;\n}\nexport async function resolveReadPathAsync(filePath, cwd) {\n const resolved = resolveToCwd(filePath, cwd);\n if (await pathExists(resolved)) {\n return resolved;\n }\n // Try macOS AM/PM variant (narrow no-break space before AM/PM)\n const amPmVariant = tryMacOSScreenshotPath(resolved);\n if (amPmVariant !== resolved && (await pathExists(amPmVariant))) {\n return amPmVariant;\n }\n // Try NFD variant (macOS stores filenames in NFD form)\n const nfdVariant = tryNFDVariant(resolved);\n if (nfdVariant !== resolved && (await pathExists(nfdVariant))) {\n return nfdVariant;\n }\n // Try curly quote variant (macOS uses U+2019 in screenshot names)\n const curlyVariant = tryCurlyQuoteVariant(resolved);\n if (curlyVariant !== resolved && (await pathExists(curlyVariant))) {\n return curlyVariant;\n }\n // Try combined NFD + curly quote (for French macOS screenshots like \"Capture d'écran\")\n const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant);\n if (nfdCurlyVariant !== resolved && (await pathExists(nfdCurlyVariant))) {\n return nfdCurlyVariant;\n }\n return resolved;\n}\n//# sourceMappingURL=path-utils.js.map","// @ts-nocheck — vendored Pi source (core/tools/read.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport { Text } from '../../pi-tui.js';\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile } from \"fs/promises\";\nimport { Type } from \"typebox\";\nimport { getReadmePath } from '../../pi-coding-agent.js';\nimport { keyHint, keyText } from '../../pi-coding-agent.js';\nimport { getLanguageFromPath, highlightCode } from '../../pi-coding-agent.js';\nimport { processImage } from '../../pi-coding-agent.js';\nimport { detectSupportedImageMimeTypeFromFile } from './mime.js';\nimport { formatPathRelativeToCwdOrAbsolute } from './paths.js';\nimport { resolveReadPathAsync, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, renderToolPath, replaceTabs, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from \"./truncate.js\";\nconst readSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n offset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\nexport const readToolSystemPromptContribution = {\n snippet: \"Read file contents\",\n guidelines: [\"Use read to examine files instead of cat or sed.\"],\n};\nconst COMPACT_RESOURCE_FILE_NAMES = new Set([\"AGENTS.override.md\", \"AGENTS.md\", \"AGENTS.MD\", \"CLAUDE.md\", \"CLAUDE.MD\"]);\nconst defaultReadOperations = {\n readFile: (path) => fsReadFile(path),\n access: (path) => fsAccess(path, constants.R_OK),\n detectImageMimeType: detectSupportedImageMimeTypeFromFile,\n};\nfunction formatReadLineRange(args, theme) {\n if (args?.offset === undefined && args?.limit === undefined)\n return \"\";\n const startLine = args.offset ?? 1;\n const endLine = args.limit !== undefined ? startLine + args.limit - 1 : \"\";\n return theme.fg(\"warning\", `:${startLine}${endLine ? `-${endLine}` : \"\"}`);\n}\nfunction formatReadCall(args, theme, cwd) {\n const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n return `${theme.fg(\"toolTitle\", theme.bold(\"read\"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;\n}\nfunction trimTrailingEmptyLines(lines) {\n let end = lines.length;\n while (end > 0 && lines[end - 1] === \"\") {\n end--;\n }\n return lines.slice(0, end);\n}\nfunction getNonVisionImageNote(model) {\n if (!model || model.input.includes(\"image\")) {\n return undefined;\n }\n return \"[Current model does not support images. The image will be omitted from this request.]\";\n}\nfunction toPosixPath(filePath) {\n return filePath.split(sep).join(\"/\");\n}\nfunction getPiDocsClassification(absolutePath) {\n const packageRoot = dirname(getReadmePath());\n const relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));\n if (relativePath === \"\" ||\n relativePath === \"..\" ||\n relativePath.startsWith(`..${sep}`) ||\n isAbsolute(relativePath)) {\n return undefined;\n }\n const label = toPosixPath(relativePath);\n if (label === \"README.md\" || label.startsWith(\"docs/\") || label.startsWith(\"examples/\")) {\n return { kind: \"docs\", label };\n }\n return undefined;\n}\nfunction getCompactReadClassification(args, cwd) {\n const rawPath = str(args?.file_path ?? args?.path);\n if (!rawPath)\n return undefined;\n const absolutePath = resolveToCwd(rawPath, cwd);\n const fileName = basename(absolutePath);\n if (fileName === \"SKILL.md\") {\n return { kind: \"skill\", label: basename(dirname(absolutePath)) || fileName };\n }\n const docsClassification = getPiDocsClassification(absolutePath);\n if (docsClassification)\n return docsClassification;\n if (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {\n return { kind: \"resource\", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };\n }\n return undefined;\n}\nfunction formatCompactReadCall(classification, args, theme) {\n const expandHint = theme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n if (classification.kind === \"skill\") {\n return (theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n theme.fg(\"customMessageText\", classification.label) +\n formatReadLineRange(args, theme) +\n expandHint);\n }\n return (theme.fg(\"toolTitle\", theme.bold(`read ${classification.kind}`)) +\n \" \" +\n theme.fg(\"accent\", classification.label) +\n formatReadLineRange(args, theme) +\n expandHint);\n}\nfunction formatReadResult(args, result, options, theme, showImages, _cwd, isError) {\n if (!options.expanded && !isError) {\n return \"\";\n }\n const rawPath = str(args?.file_path ?? args?.path);\n const output = getTextOutput(result, showImages);\n const lang = !isError && rawPath ? getLanguageFromPath(rawPath) : undefined;\n const renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split(\"\\n\");\n const lines = trimTrailingEmptyLines(renderedLines);\n const maxLines = options.expanded ? lines.length : 10;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n let text = `\\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n const truncation = result.details?.truncation;\n if (truncation?.truncated) {\n if (truncation.firstLineExceedsLimit) {\n text += `\\n${theme.fg(\"warning\", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;\n }\n else if (truncation.truncatedBy === \"lines\") {\n text += `\\n${theme.fg(\"warning\", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;\n }\n else {\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;\n }\n }\n return text;\n}\nexport function createReadToolDefinition(cwd, options) {\n const autoResizeImages = options?.autoResizeImages ?? true;\n const ops = options?.operations ?? defaultReadOperations;\n return {\n name: \"read\",\n label: \"read\",\n description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n promptSnippet: readToolSystemPromptContribution.snippet,\n promptGuidelines: [...readToolSystemPromptContribution.guidelines],\n parameters: readSchema,\n async execute(_toolCallId, { path, offset, limit }, signal, _onUpdate, ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let aborted = false;\n const onAbort = () => {\n aborted = true;\n reject(new Error(\"Operation aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const absolutePath = await resolveReadPathAsync(path, cwd);\n if (aborted)\n return;\n // Check if file exists and is readable.\n await ops.access(absolutePath);\n if (aborted)\n return;\n const mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n let content;\n let details;\n const nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n if (mimeType) {\n // Read image as binary.\n const buffer = await ops.readFile(absolutePath);\n const processed = await processImage(buffer, mimeType, { autoResizeImages });\n if (!processed.ok) {\n let textNote = `Read image file [${mimeType}]\\n${processed.message}`;\n if (nonVisionImageNote)\n textNote += `\\n${nonVisionImageNote}`;\n content = [{ type: \"text\", text: textNote }];\n }\n else {\n let textNote = `Read image file [${processed.mimeType}]`;\n if (processed.hints.length > 0)\n textNote += `\\n${processed.hints.join(\"\\n\")}`;\n if (nonVisionImageNote)\n textNote += `\\n${nonVisionImageNote}`;\n content = [\n { type: \"text\", text: textNote },\n { type: \"image\", data: processed.data, mimeType: processed.mimeType },\n ];\n }\n }\n else {\n // Read text content.\n const buffer = await ops.readFile(absolutePath);\n const textContent = buffer.toString(\"utf-8\");\n const allLines = textContent.split(\"\\n\");\n const totalFileLines = allLines.length;\n // Apply offset if specified. Convert from 1-indexed input to 0-indexed array access.\n const startLine = offset ? Math.max(0, offset - 1) : 0;\n const startLineDisplay = startLine + 1;\n // Check if offset is out of bounds.\n if (startLine >= allLines.length) {\n throw new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);\n }\n let selectedContent;\n let userLimitedLines;\n // If limit is specified by the user, honor it first. Otherwise truncateHead decides.\n if (limit !== undefined) {\n const endLine = Math.min(startLine + limit, allLines.length);\n selectedContent = allLines.slice(startLine, endLine).join(\"\\n\");\n userLimitedLines = endLine - startLine;\n }\n else {\n selectedContent = allLines.slice(startLine).join(\"\\n\");\n }\n // Apply truncation, respecting both line and byte limits.\n const truncation = truncateHead(selectedContent);\n let outputText;\n if (truncation.firstLineExceedsLimit) {\n // First line alone exceeds the byte limit. Point the model at a bash fallback.\n const firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], \"utf-8\"));\n outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n details = { truncation };\n }\n else if (truncation.truncated) {\n // Truncation occurred. Build an actionable continuation notice.\n const endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n const nextOffset = endLineDisplay + 1;\n outputText = truncation.content;\n if (truncation.truncatedBy === \"lines\") {\n outputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;\n }\n else {\n outputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n }\n details = { truncation };\n }\n else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {\n // User-specified limit stopped early, but the file still has more content.\n const remaining = allLines.length - (startLine + userLimitedLines);\n const nextOffset = startLine + userLimitedLines + 1;\n outputText = `${truncation.content}\\n\\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;\n }\n else {\n // No truncation and no remaining user-limited content.\n outputText = truncation.content;\n }\n content = [{ type: \"text\", text: outputText }];\n }\n if (aborted)\n return;\n signal?.removeEventListener(\"abort\", onAbort);\n resolve({ content, details });\n }\n catch (error) {\n signal?.removeEventListener(\"abort\", onAbort);\n if (!aborted)\n reject(error);\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n const classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;\n text.setText(classification\n ? formatCompactReadCall(classification, args, theme)\n : formatReadCall(args, theme, context.cwd));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError));\n return text;\n },\n };\n}\nexport function createReadTool(cwd, options) {\n return wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n//# sourceMappingURL=read.js.map","// @ts-nocheck — vendored Pi source (modes/interactive/components/diff.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport * as Diff from \"diff\";\nimport { theme } from '../../pi-coding-agent.js';\n/**\n * Parse diff line to extract prefix, line number, and content.\n * Format: \"+123 content\" or \"-123 content\" or \" 123 content\" or \" ...\"\n */\nfunction parseDiffLine(line) {\n const match = line.match(/^([+-\\s])(\\s*\\d*)\\s(.*)$/);\n if (!match)\n return null;\n return { prefix: match[1], lineNum: match[2], content: match[3] };\n}\n/**\n * Replace tabs with spaces for consistent rendering.\n */\nfunction replaceTabs(text) {\n return text.replace(/\\t/g, \" \");\n}\n/**\n * Compute word-level diff and render with inverse on changed parts.\n * Uses diffWords which groups whitespace with adjacent words for cleaner highlighting.\n * Strips leading whitespace from inverse to avoid highlighting indentation.\n */\nfunction renderIntraLineDiff(oldContent, newContent) {\n const wordDiff = Diff.diffWords(oldContent, newContent);\n let removedLine = \"\";\n let addedLine = \"\";\n let isFirstRemoved = true;\n let isFirstAdded = true;\n for (const part of wordDiff) {\n if (part.removed) {\n let value = part.value;\n // Strip leading whitespace from the first removed part\n if (isFirstRemoved) {\n const leadingWs = value.match(/^(\\s*)/)?.[1] || \"\";\n value = value.slice(leadingWs.length);\n removedLine += leadingWs;\n isFirstRemoved = false;\n }\n if (value) {\n removedLine += theme.inverse(value);\n }\n }\n else if (part.added) {\n let value = part.value;\n // Strip leading whitespace from the first added part\n if (isFirstAdded) {\n const leadingWs = value.match(/^(\\s*)/)?.[1] || \"\";\n value = value.slice(leadingWs.length);\n addedLine += leadingWs;\n isFirstAdded = false;\n }\n if (value) {\n addedLine += theme.inverse(value);\n }\n }\n else {\n removedLine += part.value;\n addedLine += part.value;\n }\n }\n return { removedLine, addedLine };\n}\n/**\n * Render a diff string with colored lines and intra-line change highlighting.\n * - Context lines: dim/gray\n * - Removed lines: red, with inverse on changed tokens\n * - Added lines: green, with inverse on changed tokens\n */\nexport function renderDiff(diffText, _options = {}) {\n const lines = diffText.split(\"\\n\");\n const result = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const parsed = parseDiffLine(line);\n if (!parsed) {\n result.push(theme.fg(\"toolDiffContext\", line));\n i++;\n continue;\n }\n if (parsed.prefix === \"-\") {\n // Collect consecutive removed lines\n const removedLines = [];\n while (i < lines.length) {\n const p = parseDiffLine(lines[i]);\n if (!p || p.prefix !== \"-\")\n break;\n removedLines.push({ lineNum: p.lineNum, content: p.content });\n i++;\n }\n // Collect consecutive added lines\n const addedLines = [];\n while (i < lines.length) {\n const p = parseDiffLine(lines[i]);\n if (!p || p.prefix !== \"+\")\n break;\n addedLines.push({ lineNum: p.lineNum, content: p.content });\n i++;\n }\n // Only do intra-line diffing when there's exactly one removed and one added line\n // (indicating a single line modification). Otherwise, show lines as-is.\n if (removedLines.length === 1 && addedLines.length === 1) {\n const removed = removedLines[0];\n const added = addedLines[0];\n const { removedLine, addedLine } = renderIntraLineDiff(replaceTabs(removed.content), replaceTabs(added.content));\n result.push(theme.fg(\"toolDiffRemoved\", `-${removed.lineNum} ${removedLine}`));\n result.push(theme.fg(\"toolDiffAdded\", `+${added.lineNum} ${addedLine}`));\n }\n else {\n // Show all removed lines first, then all added lines\n for (const removed of removedLines) {\n result.push(theme.fg(\"toolDiffRemoved\", `-${removed.lineNum} ${replaceTabs(removed.content)}`));\n }\n for (const added of addedLines) {\n result.push(theme.fg(\"toolDiffAdded\", `+${added.lineNum} ${replaceTabs(added.content)}`));\n }\n }\n }\n else if (parsed.prefix === \"+\") {\n // Standalone added line\n result.push(theme.fg(\"toolDiffAdded\", `+${parsed.lineNum} ${replaceTabs(parsed.content)}`));\n i++;\n }\n else {\n // Context line\n result.push(theme.fg(\"toolDiffContext\", ` ${parsed.lineNum} ${replaceTabs(parsed.content)}`));\n i++;\n }\n }\n return result.join(\"\\n\");\n}\n//# sourceMappingURL=diff.js.map","// @ts-nocheck — vendored Pi source (core/tools/edit-diff.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared diff computation utilities for the edit and similar tools.\n */\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\nexport function detectLineEnding(content) {\n const crlfIdx = content.indexOf(\"\\r\\n\");\n const lfIdx = content.indexOf(\"\\n\");\n if (lfIdx === -1)\n return \"\\n\";\n if (crlfIdx === -1)\n return \"\\n\";\n return crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\nexport function normalizeToLF(text) {\n return text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\nexport function restoreLineEndings(text, ending) {\n return ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text) {\n return (text\n .normalize(\"NFKC\")\n // Strip trailing whitespace per line\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\")\n // Smart single quotes → '\n .replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n // Smart double quotes → \"\n .replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n // Various dashes/hyphens → -\n // U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n // U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n .replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n // Special spaces → regular space\n // U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n // U+205F medium math space, U+3000 ideographic space\n .replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \"));\n}\nfunction splitLinesWithEndings(content) {\n return content.match(/[^\\n]*\\n|[^\\n]+/g) ?? [];\n}\nfunction getLineSpans(content) {\n let offset = 0;\n return splitLinesWithEndings(content).map((line) => {\n const span = { start: offset, end: offset + line.length };\n offset = span.end;\n return span;\n });\n}\nfunction getReplacementLineRange(lines, replacement) {\n const replacementStart = replacement.matchIndex;\n const replacementEnd = replacement.matchIndex + replacement.matchLength;\n let startLine = -1;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (replacementStart >= line.start && replacementStart < line.end) {\n startLine = i;\n break;\n }\n }\n if (startLine === -1) {\n throw new Error(\"Replacement range is outside the base content.\");\n }\n let endLine = startLine;\n while (endLine < lines.length && lines[endLine].end < replacementEnd) {\n endLine++;\n }\n if (endLine >= lines.length) {\n throw new Error(\"Replacement range is outside the base content.\");\n }\n return { startLine, endLine: endLine + 1 };\n}\nfunction applyReplacements(content, replacements, offset = 0) {\n let result = content;\n for (let i = replacements.length - 1; i >= 0; i--) {\n const replacement = replacements[i];\n const matchIndex = replacement.matchIndex - offset;\n result =\n result.substring(0, matchIndex) + replacement.newText + result.substring(matchIndex + replacement.matchLength);\n }\n return result;\n}\n/**\n * Apply replacements matched against `baseContent` to `originalContent` while\n * preserving unchanged line blocks from the original.\n *\n * This is useful when `baseContent` is a normalized view of the original. Each\n * replacement is widened to the lines it actually touches, those touched lines\n * are rewritten from the normalized base, and all other lines are copied back\n * from `originalContent`. The actual replacement ranges drive preservation so\n * duplicate normalized lines cannot be aligned to the wrong occurrence.\n */\nexport function applyReplacementsPreservingUnchangedLines(originalContent, baseContent, replacements) {\n const originalLines = splitLinesWithEndings(originalContent);\n const baseLines = getLineSpans(baseContent);\n if (originalLines.length !== baseLines.length) {\n throw new Error(\"Cannot preserve unchanged lines because the base content has a different line count.\");\n }\n const groups = [];\n const sortedReplacements = [...replacements].sort((a, b) => a.matchIndex - b.matchIndex);\n for (const replacement of sortedReplacements) {\n const range = getReplacementLineRange(baseLines, replacement);\n const current = groups[groups.length - 1];\n if (current && range.startLine < current.endLine) {\n current.endLine = Math.max(current.endLine, range.endLine);\n current.replacements.push(replacement);\n continue;\n }\n groups.push({ ...range, replacements: [replacement] });\n }\n let originalLineIndex = 0;\n let result = \"\";\n for (const group of groups) {\n result += originalLines.slice(originalLineIndex, group.startLine).join(\"\");\n const groupStartOffset = baseLines[group.startLine].start;\n const groupEndOffset = baseLines[group.endLine - 1].end;\n result += applyReplacements(baseContent.slice(groupStartOffset, groupEndOffset), group.replacements, groupStartOffset);\n originalLineIndex = group.endLine;\n }\n result += originalLines.slice(originalLineIndex).join(\"\");\n return result;\n}\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * When fuzzy matching is used, the returned contentForReplacement is the\n * fuzzy-normalized version of the content (trailing whitespace stripped,\n * Unicode quotes/dashes normalized to ASCII).\n */\nexport function fuzzyFindText(content, oldText) {\n // Try exact match first\n const exactIndex = content.indexOf(oldText);\n if (exactIndex !== -1) {\n return {\n found: true,\n index: exactIndex,\n matchLength: oldText.length,\n usedFuzzyMatch: false,\n contentForReplacement: content,\n };\n }\n // Try fuzzy match - work entirely in normalized space\n const fuzzyContent = normalizeForFuzzyMatch(content);\n const fuzzyOldText = normalizeForFuzzyMatch(oldText);\n const fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n if (fuzzyIndex === -1) {\n return {\n found: false,\n index: -1,\n matchLength: 0,\n usedFuzzyMatch: false,\n contentForReplacement: content,\n };\n }\n // When fuzzy matching, return offsets in normalized space. Callers can use\n // the normalized content to compute replacements, then decide how much of\n // that normalized output should be written back.\n return {\n found: true,\n index: fuzzyIndex,\n matchLength: fuzzyOldText.length,\n usedFuzzyMatch: true,\n contentForReplacement: fuzzyContent,\n };\n}\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content) {\n return content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\nfunction countOccurrences(content, oldText) {\n const fuzzyContent = normalizeForFuzzyMatch(content);\n const fuzzyOldText = normalizeForFuzzyMatch(oldText);\n return fuzzyContent.split(fuzzyOldText).length - 1;\n}\nfunction getNotFoundError(path, editIndex, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`);\n }\n return new Error(`Could not find edits[${editIndex}] in ${path}. The oldText must match exactly including all whitespace and newlines.`);\n}\nfunction getDuplicateError(path, editIndex, totalEdits, occurrences) {\n if (totalEdits === 1) {\n return new Error(`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`);\n }\n return new Error(`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`);\n}\nfunction getEmptyOldTextError(path, editIndex, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`oldText must not be empty in ${path}.`);\n }\n return new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\nfunction getNoChangeError(path, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`);\n }\n return new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n/**\n * Apply one or more exact-text replacements to LF-normalized content.\n *\n * All edits are matched against the same original content. Replacements are\n * then applied in reverse order so offsets remain stable. If any edit needs\n * fuzzy matching, the operation runs in fuzzy-normalized content space and then\n * overlays those line-level changes onto the original content so unchanged line\n * blocks keep their original bytes.\n */\nexport function applyEditsToNormalizedContent(normalizedContent, edits, path) {\n const normalizedEdits = edits.map((edit) => ({\n oldText: normalizeToLF(edit.oldText),\n newText: normalizeToLF(edit.newText),\n }));\n for (let i = 0; i < normalizedEdits.length; i++) {\n if (normalizedEdits[i].oldText.length === 0) {\n throw getEmptyOldTextError(path, i, normalizedEdits.length);\n }\n }\n const initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));\n const usedFuzzyMatch = initialMatches.some((match) => match.usedFuzzyMatch);\n const replacementBaseContent = usedFuzzyMatch ? normalizeForFuzzyMatch(normalizedContent) : normalizedContent;\n const matchedEdits = [];\n for (let i = 0; i < normalizedEdits.length; i++) {\n const edit = normalizedEdits[i];\n const matchResult = fuzzyFindText(replacementBaseContent, edit.oldText);\n if (!matchResult.found) {\n throw getNotFoundError(path, i, normalizedEdits.length);\n }\n const occurrences = countOccurrences(replacementBaseContent, edit.oldText);\n if (occurrences > 1) {\n throw getDuplicateError(path, i, normalizedEdits.length, occurrences);\n }\n matchedEdits.push({\n editIndex: i,\n matchIndex: matchResult.index,\n matchLength: matchResult.matchLength,\n newText: edit.newText,\n });\n }\n matchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n for (let i = 1; i < matchedEdits.length; i++) {\n const previous = matchedEdits[i - 1];\n const current = matchedEdits[i];\n if (previous.matchIndex + previous.matchLength > current.matchIndex) {\n throw new Error(`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`);\n }\n }\n const baseContent = normalizedContent;\n const newContent = usedFuzzyMatch\n ? applyReplacementsPreservingUnchangedLines(normalizedContent, replacementBaseContent, matchedEdits)\n : applyReplacements(replacementBaseContent, matchedEdits);\n if (baseContent === newContent) {\n throw getNoChangeError(path, normalizedEdits.length);\n }\n return { baseContent, newContent };\n}\n/** Generate a standard unified patch. */\nexport function generateUnifiedPatch(path, oldContent, newContent, contextLines = 4) {\n return Diff.createTwoFilesPatch(path, path, oldContent, newContent, undefined, undefined, {\n context: contextLines,\n headerOptions: Diff.FILE_HEADERS_ONLY,\n });\n}\n/**\n * Generate a display-oriented diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(oldContent, newContent, contextLines = 4) {\n const parts = Diff.diffLines(oldContent, newContent);\n const output = [];\n const oldLines = oldContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const maxLineNum = Math.max(oldLines.length, newLines.length);\n const lineNumWidth = String(maxLineNum).length;\n let oldLineNum = 1;\n let newLineNum = 1;\n let lastWasChange = false;\n let firstChangedLine;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const raw = part.value.split(\"\\n\");\n if (raw[raw.length - 1] === \"\") {\n raw.pop();\n }\n if (part.added || part.removed) {\n // Capture the first changed line (in the new file)\n if (firstChangedLine === undefined) {\n firstChangedLine = newLineNum;\n }\n // Show the change\n for (const line of raw) {\n if (part.added) {\n const lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n output.push(`+${lineNum} ${line}`);\n newLineNum++;\n }\n else {\n // removed\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(`-${lineNum} ${line}`);\n oldLineNum++;\n }\n }\n lastWasChange = true;\n }\n else {\n // Context lines - only show a few before/after changes\n const nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n const hasLeadingChange = lastWasChange;\n const hasTrailingChange = nextPartIsChange;\n if (hasLeadingChange && hasTrailingChange) {\n if (raw.length <= contextLines * 2) {\n for (const line of raw) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n else {\n const leadingLines = raw.slice(0, contextLines);\n const trailingLines = raw.slice(raw.length - contextLines);\n const skippedLines = raw.length - leadingLines.length - trailingLines.length;\n for (const line of leadingLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n for (const line of trailingLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n }\n else if (hasLeadingChange) {\n const shownLines = raw.slice(0, contextLines);\n const skippedLines = raw.length - shownLines.length;\n for (const line of shownLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n if (skippedLines > 0) {\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n }\n }\n else if (hasTrailingChange) {\n const skippedLines = Math.max(0, raw.length - contextLines);\n if (skippedLines > 0) {\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n }\n for (const line of raw.slice(skippedLines)) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n else {\n // Skip these context lines entirely\n oldLineNum += raw.length;\n newLineNum += raw.length;\n }\n lastWasChange = false;\n }\n }\n return { diff: output.join(\"\\n\"), firstChangedLine };\n}\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsDiff(path, edits, cwd) {\n const absolutePath = resolveToCwd(path, cwd);\n try {\n // Check if file exists and is readable\n try {\n await access(absolutePath, constants.R_OK);\n }\n catch (error) {\n const errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n return { error: `Could not edit file: ${path}. ${errorMessage}.` };\n }\n // Read the file\n const rawContent = await readFile(absolutePath, \"utf-8\");\n // Strip BOM before matching (LLM won't include invisible BOM in oldText)\n const { text: content } = stripBom(rawContent);\n const normalizedContent = normalizeToLF(content);\n const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n // Generate the diff\n return generateDiffString(baseContent, newContent);\n }\n catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n}\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(path, oldText, newText, cwd) {\n return computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n//# sourceMappingURL=edit-diff.js.map","// @ts-nocheck — vendored Pi source (core/tools/file-mutation-queue.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nconst fileMutationQueues = new Map();\nlet registrationQueue = Promise.resolve();\nfunction isMissingPathError(error) {\n return (typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error.code === \"ENOENT\" || error.code === \"ENOTDIR\"));\n}\nasync function getMutationQueueKey(filePath) {\n const resolvedPath = resolve(filePath);\n try {\n return await realpath(resolvedPath);\n }\n catch (error) {\n if (isMissingPathError(error)) {\n return resolvedPath;\n }\n throw error;\n }\n}\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue(filePath, fn) {\n const registration = registrationQueue.then(async () => {\n const key = await getMutationQueueKey(filePath);\n const currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n let releaseNext;\n const nextQueue = new Promise((resolveQueue) => {\n releaseNext = resolveQueue;\n });\n const chainedQueue = currentQueue.then(() => nextQueue);\n fileMutationQueues.set(key, chainedQueue);\n return { key, currentQueue, chainedQueue, releaseNext };\n });\n registrationQueue = registration.then(() => undefined, () => undefined);\n const { key, currentQueue, chainedQueue, releaseNext } = await registration;\n await currentQueue;\n try {\n return await fn();\n }\n finally {\n releaseNext();\n if (fileMutationQueues.get(key) === chainedQueue) {\n fileMutationQueues.delete(key);\n }\n }\n}\n//# sourceMappingURL=file-mutation-queue.js.map","// @ts-nocheck — vendored Pi source (core/tools/edit.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { Box, Container, Spacer, Text } from '../../pi-tui.js';\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { Type } from \"typebox\";\nimport { renderDiff } from './diff-component.js';\nimport { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { renderToolPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nconst replaceEditSchema = Type.Object({\n oldText: Type.String({\n description: \"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n }),\n newText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n}, {});\nconst editSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n edits: Type.Array(replaceEditSchema, {\n description: \"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n }),\n}, {});\nexport const editToolSystemPromptContribution = {\n snippet: \"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n guidelines: [\n \"Use edit for precise changes (edits[].oldText must match exactly)\",\n \"When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls\",\n \"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n \"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n ],\n};\nconst defaultEditOperations = {\n readFile: (path) => fsReadFile(path),\n writeFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n access: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\nfunction prepareEditArguments(input) {\n if (!input || typeof input !== \"object\") {\n return input;\n }\n const args = input;\n // Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n if (typeof args.edits === \"string\") {\n try {\n const parsed = JSON.parse(args.edits);\n if (Array.isArray(parsed))\n args.edits = parsed;\n }\n catch { }\n }\n const legacy = args;\n if (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n return args;\n }\n const edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n edits.push({ oldText: legacy.oldText, newText: legacy.newText });\n const { oldText: _oldText, newText: _newText, ...rest } = legacy;\n return { ...rest, edits };\n}\nfunction validateEditInput(input) {\n if (!Array.isArray(input.edits) || input.edits.length === 0) {\n throw new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n }\n return { path: input.path, edits: input.edits };\n}\nfunction createEditCallRenderComponent() {\n return Object.assign(new Box(1, 1, (text) => text), {\n preview: undefined,\n previewArgsKey: undefined,\n previewPending: false,\n settledError: false,\n });\n}\nfunction getEditCallRenderComponent(state, lastComponent) {\n if (lastComponent instanceof Box) {\n const component = lastComponent;\n state.callComponent = component;\n return component;\n }\n if (state.callComponent) {\n return state.callComponent;\n }\n const component = createEditCallRenderComponent();\n state.callComponent = component;\n return component;\n}\nfunction getRenderablePreviewInput(args) {\n if (!args) {\n return null;\n }\n const path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n if (!path) {\n return null;\n }\n if (Array.isArray(args.edits) &&\n args.edits.length > 0 &&\n args.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")) {\n return { path, edits: args.edits };\n }\n if (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n return { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n }\n return null;\n}\nfunction formatEditCall(args, theme, cwd) {\n const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n return `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\nfunction formatEditResult(args, preview, result, theme, isError) {\n const rawPath = str(args?.file_path ?? args?.path);\n const previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n const previewError = preview && \"error\" in preview ? preview.error : undefined;\n if (isError) {\n const errorText = result.content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text || \"\")\n .join(\"\\n\");\n if (!errorText || errorText === previewError) {\n return undefined;\n }\n return theme.fg(\"error\", errorText);\n }\n const resultDiff = result.details?.diff;\n if (resultDiff && resultDiff !== previewDiff) {\n return renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n }\n return undefined;\n}\nfunction getEditHeaderBg(preview, settledError, theme) {\n if (preview) {\n if (\"error\" in preview) {\n return (text) => theme.bg(\"toolErrorBg\", text);\n }\n return (text) => theme.bg(\"toolSuccessBg\", text);\n }\n if (settledError) {\n return (text) => theme.bg(\"toolErrorBg\", text);\n }\n return (text) => theme.bg(\"toolPendingBg\", text);\n}\nfunction buildEditCallComponent(component, args, theme, cwd) {\n component.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n component.clear();\n component.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));\n if (!component.preview) {\n return component;\n }\n const body = \"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n component.addChild(new Spacer(1));\n component.addChild(new Text(body, 0, 0));\n return component;\n}\nfunction setEditPreview(component, preview, argsKey) {\n const current = component.preview;\n const changed = current === undefined ||\n (\"error\" in current && \"error\" in preview\n ? current.error !== preview.error\n : \"error\" in current !== \"error\" in preview) ||\n (!(\"error\" in current) &&\n !(\"error\" in preview) &&\n (current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n component.preview = preview;\n component.previewArgsKey = argsKey;\n component.previewPending = false;\n return changed;\n}\nexport function createEditToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultEditOperations;\n return {\n name: \"edit\",\n label: \"edit\",\n description: \"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n promptSnippet: editToolSystemPromptContribution.snippet,\n promptGuidelines: [...editToolSystemPromptContribution.guidelines],\n parameters: editSchema,\n renderShell: \"self\",\n prepareArguments: prepareEditArguments,\n async execute(_toolCallId, input, signal, _onUpdate, _ctx) {\n const { path, edits } = validateEditInput(input);\n const absolutePath = resolveToCwd(path, cwd);\n return withFileMutationQueue(absolutePath, async () => {\n // Do not reject from an abort event listener here: that would release the\n // mutation queue while an in-flight filesystem operation may still finish.\n // Checking signal.aborted after each await observes the same aborts while\n // keeping the queue locked until the current operation has settled.\n const throwIfAborted = () => {\n if (signal?.aborted)\n throw new Error(\"Operation aborted\");\n };\n throwIfAborted();\n // Check if file exists.\n try {\n await ops.access(absolutePath);\n }\n catch (error) {\n throwIfAborted();\n const errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n throw new Error(`Could not edit file: ${path}. ${errorMessage}.`);\n }\n throwIfAborted();\n // Read the file.\n const buffer = await ops.readFile(absolutePath);\n const rawContent = buffer.toString(\"utf-8\");\n throwIfAborted();\n // Strip BOM before matching. The model will not include an invisible BOM in oldText.\n const { bom, text: content } = stripBom(rawContent);\n const originalEnding = detectLineEnding(content);\n const normalizedContent = normalizeToLF(content);\n const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n throwIfAborted();\n const finalContent = bom + restoreLineEndings(newContent, originalEnding);\n await ops.writeFile(absolutePath, finalContent);\n throwIfAborted();\n const diffResult = generateDiffString(baseContent, newContent);\n const patch = generateUnifiedPatch(path, baseContent, newContent);\n return {\n content: [\n {\n type: \"text\",\n text: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n },\n ],\n details: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine },\n };\n });\n },\n renderCall(args, theme, context) {\n const component = getEditCallRenderComponent(context.state, context.lastComponent);\n const previewInput = getRenderablePreviewInput(args);\n const argsKey = previewInput\n ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n : undefined;\n if (component.previewArgsKey !== argsKey) {\n component.preview = undefined;\n component.previewArgsKey = argsKey;\n component.previewPending = false;\n component.settledError = false;\n }\n if (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n component.previewPending = true;\n const requestKey = argsKey;\n void computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n if (component.previewArgsKey === requestKey) {\n setEditPreview(component, preview, requestKey);\n context.invalidate();\n }\n });\n }\n return buildEditCallComponent(component, args, theme, context.cwd);\n },\n renderResult(result, _options, theme, context) {\n const callComponent = context.state.callComponent;\n const previewInput = getRenderablePreviewInput(context.args);\n const argsKey = previewInput\n ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n : undefined;\n const typedResult = result;\n const resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n let changed = false;\n if (callComponent) {\n if (typeof resultDiff === \"string\") {\n changed =\n setEditPreview(callComponent, { diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine }, argsKey) || changed;\n }\n if (callComponent.settledError !== context.isError) {\n callComponent.settledError = context.isError;\n changed = true;\n }\n if (changed) {\n buildEditCallComponent(callComponent, context.args, theme, context.cwd);\n }\n }\n const output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n const component = context.lastComponent ?? new Container();\n component.clear();\n if (!output) {\n return component;\n }\n component.addChild(new Spacer(1));\n component.addChild(new Text(output, 1, 0));\n return component;\n },\n };\n}\nexport function createEditTool(cwd, options) {\n return wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n//# sourceMappingURL=edit.js.map","// @ts-nocheck — vendored Pi source (core/tools/write.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { Container, Text } from '../../pi-tui.js';\nimport { mkdir as fsMkdir, writeFile as fsWriteFile } from \"fs/promises\";\nimport { dirname } from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { getLanguageFromPath, highlightCode } from '../../pi-coding-agent.js';\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { normalizeDisplayText, renderToolPath, replaceTabs, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nconst writeSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to write (relative or absolute)\" }),\n content: Type.String({ description: \"Content to write to the file\" }),\n});\nexport const writeToolSystemPromptContribution = {\n snippet: \"Create or overwrite files\",\n guidelines: [\"Use write only for new files or complete rewrites.\"],\n};\nconst defaultWriteOperations = {\n writeFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n mkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => { }),\n};\nclass WriteCallRenderComponent extends Text {\n cache;\n constructor() {\n super(\"\", 0, 0);\n }\n}\nconst WRITE_PARTIAL_FULL_HIGHLIGHT_LINES = 50;\nfunction highlightSingleLine(line, lang) {\n const highlighted = highlightCode(line, lang);\n return highlighted[0] ?? \"\";\n}\nfunction refreshWriteHighlightPrefix(cache) {\n const prefixCount = Math.min(WRITE_PARTIAL_FULL_HIGHLIGHT_LINES, cache.normalizedLines.length);\n if (prefixCount === 0)\n return;\n const prefixSource = cache.normalizedLines.slice(0, prefixCount).join(\"\\n\");\n const prefixHighlighted = highlightCode(prefixSource, cache.lang);\n for (let i = 0; i < prefixCount; i++) {\n cache.highlightedLines[i] =\n prefixHighlighted[i] ?? highlightSingleLine(cache.normalizedLines[i] ?? \"\", cache.lang);\n }\n}\nfunction rebuildWriteHighlightCacheFull(rawPath, fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n if (!lang)\n return undefined;\n const displayContent = normalizeDisplayText(fileContent);\n const normalized = replaceTabs(displayContent);\n return {\n rawPath,\n lang,\n rawContent: fileContent,\n normalizedLines: normalized.split(\"\\n\"),\n highlightedLines: highlightCode(normalized, lang),\n };\n}\nfunction updateWriteHighlightCacheIncremental(cache, rawPath, fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n if (!lang)\n return undefined;\n if (!cache)\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (cache.lang !== lang || cache.rawPath !== rawPath)\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (!fileContent.startsWith(cache.rawContent))\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (fileContent.length === cache.rawContent.length)\n return cache;\n const deltaRaw = fileContent.slice(cache.rawContent.length);\n const deltaDisplay = normalizeDisplayText(deltaRaw);\n const deltaNormalized = replaceTabs(deltaDisplay);\n cache.rawContent = fileContent;\n if (cache.normalizedLines.length === 0) {\n cache.normalizedLines.push(\"\");\n cache.highlightedLines.push(\"\");\n }\n const segments = deltaNormalized.split(\"\\n\");\n const lastIndex = cache.normalizedLines.length - 1;\n cache.normalizedLines[lastIndex] += segments[0];\n cache.highlightedLines[lastIndex] = highlightSingleLine(cache.normalizedLines[lastIndex], cache.lang);\n for (let i = 1; i < segments.length; i++) {\n cache.normalizedLines.push(segments[i]);\n cache.highlightedLines.push(highlightSingleLine(segments[i], cache.lang));\n }\n refreshWriteHighlightPrefix(cache);\n return cache;\n}\nfunction trimTrailingEmptyLines(lines) {\n let end = lines.length;\n while (end > 0 && lines[end - 1] === \"\") {\n end--;\n }\n return lines.slice(0, end);\n}\nfunction formatWriteCall(args, options, theme, cache, cwd) {\n const rawPath = str(args?.file_path ?? args?.path);\n const fileContent = str(args?.content);\n const pathDisplay = renderToolPath(rawPath, theme, cwd);\n let text = `${theme.fg(\"toolTitle\", theme.bold(\"write\"))} ${pathDisplay}`;\n if (fileContent === null) {\n text += `\\n\\n${theme.fg(\"error\", \"[invalid content arg - expected string]\")}`;\n }\n else if (fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n const renderedLines = lang\n ? (cache?.highlightedLines ?? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang))\n : normalizeDisplayText(fileContent).split(\"\\n\");\n const lines = trimTrailingEmptyLines(renderedLines);\n const totalLines = lines.length;\n const maxLines = options.expanded ? lines.length : 10;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n\\n${displayLines.map((line) => (lang ? line : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines, ${totalLines} total,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n return text;\n}\nfunction formatWriteResult(result, theme) {\n if (!result.isError) {\n return undefined;\n }\n const output = result.content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text || \"\")\n .join(\"\\n\");\n if (!output) {\n return undefined;\n }\n return `\\n${theme.fg(\"error\", output)}`;\n}\nexport function createWriteToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultWriteOperations;\n return {\n name: \"write\",\n label: \"write\",\n description: \"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.\",\n promptSnippet: writeToolSystemPromptContribution.snippet,\n promptGuidelines: [...writeToolSystemPromptContribution.guidelines],\n parameters: writeSchema,\n async execute(_toolCallId, { path, content }, signal, _onUpdate, _ctx) {\n const absolutePath = resolveToCwd(path, cwd);\n const dir = dirname(absolutePath);\n return withFileMutationQueue(absolutePath, async () => {\n // Do not reject from an abort event listener here: that would release the\n // mutation queue while an in-flight filesystem operation may still finish.\n // Checking signal.aborted after each await observes the same aborts while\n // keeping the queue locked until the current operation has settled.\n const throwIfAborted = () => {\n if (signal?.aborted)\n throw new Error(\"Operation aborted\");\n };\n throwIfAborted();\n // Create parent directories if needed.\n await ops.mkdir(dir);\n throwIfAborted();\n // Write the file contents.\n await ops.writeFile(absolutePath, content);\n throwIfAborted();\n return {\n content: [{ type: \"text\", text: `Successfully wrote ${content.length} bytes to ${path}` }],\n details: undefined,\n };\n });\n },\n renderCall(args, theme, context) {\n const renderArgs = args;\n const rawPath = str(renderArgs?.file_path ?? renderArgs?.path);\n const fileContent = str(renderArgs?.content);\n const component = context.lastComponent ?? new WriteCallRenderComponent();\n if (fileContent !== null) {\n component.cache = context.argsComplete\n ? rebuildWriteHighlightCacheFull(rawPath, fileContent)\n : updateWriteHighlightCacheIncremental(component.cache, rawPath, fileContent);\n }\n else {\n component.cache = undefined;\n }\n component.setText(formatWriteCall(renderArgs, { expanded: context.expanded, isPartial: context.isPartial }, theme, component.cache, context.cwd));\n return component;\n },\n renderResult(result, _options, theme, context) {\n const output = formatWriteResult({ ...result, isError: context.isError }, theme);\n if (!output) {\n const component = context.lastComponent ?? new Container();\n component.clear();\n return component;\n }\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(output);\n return text;\n },\n };\n}\nexport function createWriteTool(cwd, options) {\n return wrapToolDefinition(createWriteToolDefinition(cwd, options));\n}\n//# sourceMappingURL=write.js.map","// @ts-nocheck — vendored Pi source (core/tools/grep.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport { Text } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { ensureTool } from '../../pi-coding-agent.js';\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, GREP_MAX_LINE_LENGTH, truncateHead, truncateLine, } from \"./truncate.js\";\nconst grepSchema = Type.Object({\n pattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n path: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n glob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n ignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n literal: Type.Optional(Type.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" })),\n context: Type.Optional(Type.Number({ description: \"Number of lines to show before and after each match (default: 0)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\nexport const grepToolSystemPromptContribution = {\n snippet: \"Search file contents for patterns (respects .gitignore)\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 100;\nconst defaultGrepOperations = {\n isDirectory: async (p) => (await fsStat(p)).isDirectory(),\n readFile: (p) => fsReadFile(p, \"utf-8\"),\n};\nfunction formatGrepCall(args, theme) {\n const pattern = str(args?.pattern);\n const rawPath = str(args?.path);\n const path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n const glob = str(args?.glob);\n const limit = args?.limit;\n const invalidArg = invalidArgText(theme);\n let text = theme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n \" \" +\n (pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n theme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n if (glob)\n text += theme.fg(\"toolOutput\", ` (${glob})`);\n if (limit !== undefined)\n text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n return text;\n}\nfunction formatGrepResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 15;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const matchLimit = result.details?.matchLimitReached;\n const truncation = result.details?.truncation;\n const linesTruncated = result.details?.linesTruncated;\n if (matchLimit || truncation?.truncated || linesTruncated) {\n const warnings = [];\n if (matchLimit)\n warnings.push(`${matchLimit} matches limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n if (linesTruncated)\n warnings.push(\"some lines truncated\");\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createGrepToolDefinition(cwd, options) {\n const customOps = options?.operations;\n return {\n name: \"grep\",\n label: \"grep\",\n description: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n promptSnippet: grepToolSystemPromptContribution.snippet,\n parameters: grepSchema,\n async execute(_toolCallId, { pattern, path: searchDir, glob, ignoreCase, literal, context, limit, }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let settled = false;\n const settle = (fn) => {\n if (!settled) {\n settled = true;\n fn();\n }\n };\n (async () => {\n try {\n const rgPath = await ensureTool(\"rg\", true);\n if (!rgPath) {\n settle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n return;\n }\n const searchPath = resolveToCwd(searchDir || \".\", cwd);\n const ops = customOps ?? defaultGrepOperations;\n let isDirectory;\n try {\n isDirectory = await ops.isDirectory(searchPath);\n }\n catch {\n settle(() => reject(new Error(`Path not found: ${searchPath}`)));\n return;\n }\n const contextValue = context && context > 0 ? context : 0;\n const effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n const formatPath = (filePath) => {\n if (isDirectory) {\n const relative = path.relative(searchPath, filePath);\n if (relative && !relative.startsWith(\"..\")) {\n return relative.replace(/\\\\/g, \"/\");\n }\n }\n return path.basename(filePath);\n };\n const fileCache = new Map();\n const getFileLines = async (filePath) => {\n let lines = fileCache.get(filePath);\n if (!lines) {\n try {\n const content = await ops.readFile(filePath);\n lines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n }\n catch {\n lines = [];\n }\n fileCache.set(filePath, lines);\n }\n return lines;\n };\n const args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n if (ignoreCase)\n args.push(\"--ignore-case\");\n if (literal)\n args.push(\"--fixed-strings\");\n if (glob)\n args.push(\"--glob\", glob);\n args.push(\"--\", pattern, searchPath);\n const child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const rl = createInterface({ input: child.stdout });\n let stderr = \"\";\n let matchCount = 0;\n let matchLimitReached = false;\n let linesTruncated = false;\n let aborted = false;\n let killedDueToLimit = false;\n const outputLines = [];\n const cleanup = () => {\n rl.close();\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const stopChild = (dueToLimit = false) => {\n if (!child.killed) {\n killedDueToLimit = dueToLimit;\n child.kill();\n }\n };\n const onAbort = () => {\n aborted = true;\n stopChild();\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n const formatBlock = async (filePath, lineNumber) => {\n const relativePath = formatPath(filePath);\n const lines = await getFileLines(filePath);\n if (!lines.length)\n return [`${relativePath}:${lineNumber}: (unable to read file)`];\n const block = [];\n const start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n const end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n for (let current = start; current <= end; current++) {\n const lineText = lines[current - 1] ?? \"\";\n const sanitized = lineText.replace(/\\r/g, \"\");\n const isMatchLine = current === lineNumber;\n // Truncate long lines so grep output stays compact.\n const { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n if (wasTruncated)\n linesTruncated = true;\n if (isMatchLine)\n block.push(`${relativePath}:${current}: ${truncatedText}`);\n else\n block.push(`${relativePath}-${current}- ${truncatedText}`);\n }\n return block;\n };\n // Collect matches during streaming, then format them after rg exits.\n const matches = [];\n rl.on(\"line\", (line) => {\n if (!line.trim() || matchCount >= effectiveLimit)\n return;\n let event;\n try {\n event = JSON.parse(line);\n }\n catch {\n return;\n }\n if (event.type === \"match\") {\n matchCount++;\n const filePath = event.data?.path?.text;\n const lineNumber = event.data?.line_number;\n const lineText = event.data?.lines?.text;\n if (filePath && typeof lineNumber === \"number\")\n matches.push({ filePath, lineNumber, lineText });\n if (matchCount >= effectiveLimit) {\n matchLimitReached = true;\n stopChild(true);\n }\n }\n });\n child.on(\"error\", (error) => {\n cleanup();\n settle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n });\n child.on(\"close\", async (code) => {\n cleanup();\n if (aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (!killedDueToLimit && code !== 0 && code !== 1) {\n const errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n settle(() => reject(new Error(errorMsg)));\n return;\n }\n if (matchCount === 0) {\n settle(() => resolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }));\n return;\n }\n // Format matches after streaming finishes so custom readFile() backends can be async.\n for (const match of matches) {\n if (contextValue === 0 && match.lineText !== undefined) {\n const relativePath = formatPath(match.filePath);\n const sanitized = match.lineText\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\")\n .replace(/\\n$/, \"\");\n const { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n if (wasTruncated)\n linesTruncated = true;\n outputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n }\n else {\n const block = await formatBlock(match.filePath, match.lineNumber);\n outputLines.push(...block);\n }\n }\n const rawOutput = outputLines.join(\"\\n\");\n // Apply byte truncation. There is no line limit here because the match limit already capped rows.\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let output = truncation.content;\n const details = {};\n // Build actionable notices for truncation and match limits.\n const notices = [];\n if (matchLimitReached) {\n notices.push(`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);\n details.matchLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (linesTruncated) {\n notices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n details.linesTruncated = true;\n }\n if (notices.length > 0)\n output += `\\n\\n[${notices.join(\". \")}]`;\n settle(() => resolve({\n content: [{ type: \"text\", text: output }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n });\n }\n catch (err) {\n settle(() => reject(err));\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatGrepCall(args, theme));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatGrepResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createGrepTool(cwd, options) {\n return wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n//# sourceMappingURL=grep.js.map","// @ts-nocheck — vendored Pi source (core/tools/find.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { createInterface } from \"node:readline\";\nimport { Text } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { ensureTool } from '../../pi-coding-agent.js';\nimport { pathExists, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, truncateHead } from \"./truncate.js\";\n/** Relativize a find result against the search root and normalize it to posix separators. */\nexport function relativizeFindResultPath(resultPath, searchPath, pathModule = path) {\n const hadTrailingSeparator = resultPath.endsWith(pathModule.sep) || (pathModule.sep === \"\\\\\" && resultPath.endsWith(\"/\"));\n const relativePath = pathModule.isAbsolute(resultPath) ? pathModule.relative(searchPath, resultPath) : resultPath;\n const posixPath = relativePath.split(pathModule.sep).join(\"/\");\n return hadTrailingSeparator && !posixPath.endsWith(\"/\") ? `${posixPath}/` : posixPath;\n}\nconst findSchema = Type.Object({\n pattern: Type.String({\n description: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n }),\n path: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\nexport const findToolSystemPromptContribution = {\n snippet: \"Find files by glob pattern (respects .gitignore)\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 1000;\nconst defaultFindOperations = {\n exists: pathExists,\n // This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n glob: () => [],\n};\nfunction formatFindCall(args, theme) {\n const pattern = str(args?.pattern);\n const rawPath = str(args?.path);\n const path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n const limit = args?.limit;\n const invalidArg = invalidArgText(theme);\n let text = theme.fg(\"toolTitle\", theme.bold(\"find\")) +\n \" \" +\n (pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n theme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n if (limit !== undefined) {\n text += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n }\n return text;\n}\nfunction formatFindResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 20;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const resultLimit = result.details?.resultLimitReached;\n const truncation = result.details?.truncation;\n if (resultLimit || truncation?.truncated) {\n const warnings = [];\n if (resultLimit)\n warnings.push(`${resultLimit} results limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createFindToolDefinition(cwd, options) {\n const customOps = options?.operations;\n return {\n name: \"find\",\n label: \"find\",\n description: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n promptSnippet: findToolSystemPromptContribution.snippet,\n parameters: findSchema,\n async execute(_toolCallId, { pattern, path: searchDir, limit }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let settled = false;\n let stopChild;\n const settle = (fn) => {\n if (settled)\n return;\n settled = true;\n signal?.removeEventListener(\"abort\", onAbort);\n stopChild = undefined;\n fn();\n };\n const onAbort = () => {\n stopChild?.();\n settle(() => reject(new Error(\"Operation aborted\")));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const searchPath = resolveToCwd(searchDir || \".\", cwd);\n const effectiveLimit = limit ?? DEFAULT_LIMIT;\n const ops = customOps ?? defaultFindOperations;\n // If custom operations provide glob(), use that instead of fd.\n if (customOps?.glob) {\n if (!(await ops.exists(searchPath))) {\n settle(() => reject(new Error(`Path not found: ${searchPath}`)));\n return;\n }\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const results = await ops.glob(pattern, searchPath, {\n ignore: [\"**/node_modules/**\", \"**/.git/**\"],\n limit: effectiveLimit,\n });\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (results.length === 0) {\n settle(() => resolve({\n content: [{ type: \"text\", text: \"No files found matching pattern\" }],\n details: undefined,\n }));\n return;\n }\n // Relativize paths against the search root for stable output.\n const relativized = results.map((p) => relativizeFindResultPath(p, searchPath));\n const resultLimitReached = relativized.length >= effectiveLimit;\n const rawOutput = relativized.join(\"\\n\");\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let resultOutput = truncation.content;\n const details = {};\n const notices = [];\n if (resultLimitReached) {\n notices.push(`${effectiveLimit} results limit reached`);\n details.resultLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n resultOutput += `\\n\\n[${notices.join(\". \")}]`;\n }\n settle(() => resolve({\n content: [{ type: \"text\", text: resultOutput }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n return;\n }\n // Default implementation uses fd.\n const fdPath = await ensureTool(\"fd\", true);\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (!fdPath) {\n settle(() => reject(new Error(\"fd is not available and could not be downloaded\")));\n return;\n }\n const args = [\"--glob\", \"--color=never\", \"--hidden\"];\n // fd normally ignores .gitignore outside git repos, so keep --no-require-git\n // there. Inside repos, use fd's default git-aware behavior so parent\n // .gitignore rules stop at nested repo boundaries:\n // https://github.com/earendil-works/pi/issues/5960\n let insideGitRepo = false;\n for (let current = searchPath;;) {\n if (await pathExists(path.join(current, \".git\"))) {\n insideGitRepo = true;\n break;\n }\n const parent = path.dirname(current);\n if (parent === current)\n break;\n current = parent;\n }\n if (!insideGitRepo)\n args.push(\"--no-require-git\");\n args.push(\"--max-results\", String(effectiveLimit));\n // fd --glob matches against the basename unless --full-path is set; in --full-path\n // mode it matches against the absolute candidate path, so a path-containing\n // pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.\n let effectivePattern = pattern;\n if (pattern.includes(\"/\")) {\n args.push(\"--full-path\");\n if (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n effectivePattern = `**/${pattern}`;\n }\n // fd matches full paths using native separators on Windows.\n if (process.platform === \"win32\")\n effectivePattern = effectivePattern.replaceAll(\"/\", String.raw `[/\\\\]`);\n }\n args.push(\"--\", effectivePattern, searchPath);\n const child = spawn(fdPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const rl = createInterface({ input: child.stdout });\n let stderr = \"\";\n const lines = [];\n stopChild = () => {\n if (!child.killed) {\n child.kill();\n }\n };\n const cleanup = () => {\n rl.close();\n };\n child.stderr?.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n rl.on(\"line\", (line) => {\n lines.push(line);\n });\n child.on(\"error\", (error) => {\n cleanup();\n settle(() => reject(new Error(`Failed to run fd: ${error.message}`)));\n });\n child.on(\"close\", (code) => {\n cleanup();\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const output = lines.join(\"\\n\");\n if (code !== 0) {\n const errorMsg = stderr.trim() || `fd exited with code ${code}`;\n if (!output) {\n settle(() => reject(new Error(errorMsg)));\n return;\n }\n }\n if (!output) {\n settle(() => resolve({\n content: [{ type: \"text\", text: \"No files found matching pattern\" }],\n details: undefined,\n }));\n return;\n }\n const relativized = [];\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\r$/, \"\").trim();\n if (!line)\n continue;\n relativized.push(relativizeFindResultPath(line, searchPath));\n }\n const resultLimitReached = relativized.length >= effectiveLimit;\n const rawOutput = relativized.join(\"\\n\");\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let resultOutput = truncation.content;\n const details = {};\n const notices = [];\n if (resultLimitReached) {\n notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);\n details.resultLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n resultOutput += `\\n\\n[${notices.join(\". \")}]`;\n }\n settle(() => resolve({\n content: [{ type: \"text\", text: resultOutput }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n });\n }\n catch (e) {\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const error = e instanceof Error ? e : new Error(String(e));\n settle(() => reject(error));\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatFindCall(args, theme));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatFindResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createFindTool(cwd, options) {\n return wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n//# sourceMappingURL=find.js.map","// @ts-nocheck — vendored Pi source (core/tools/ls.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport { Text } from '../../pi-tui.js';\nimport nodePath from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { pathExists, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, renderToolPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, truncateHead } from \"./truncate.js\";\nconst lsSchema = Type.Object({\n path: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n});\nexport const lsToolSystemPromptContribution = {\n snippet: \"List directory contents\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 500;\nconst defaultLsOperations = {\n exists: pathExists,\n stat: fsStat,\n readdir: fsReaddir,\n};\nfunction formatLsCall(args, theme, cwd) {\n const limit = args?.limit;\n const pathDisplay = renderToolPath(str(args?.path), theme, cwd, { emptyFallback: \".\" });\n let text = `${theme.fg(\"toolTitle\", theme.bold(\"ls\"))} ${pathDisplay}`;\n if (limit !== undefined) {\n text += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n }\n return text;\n}\nfunction formatLsResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 20;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const entryLimit = result.details?.entryLimitReached;\n const truncation = result.details?.truncation;\n if (entryLimit || truncation?.truncated) {\n const warnings = [];\n if (entryLimit)\n warnings.push(`${entryLimit} entries limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createLsToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultLsOperations;\n return {\n name: \"ls\",\n label: \"ls\",\n description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n promptSnippet: lsToolSystemPromptContribution.snippet,\n parameters: lsSchema,\n async execute(_toolCallId, { path, limit }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n const onAbort = () => reject(new Error(\"Operation aborted\"));\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const dirPath = resolveToCwd(path || \".\", cwd);\n const effectiveLimit = limit ?? DEFAULT_LIMIT;\n // Check if path exists.\n if (!(await ops.exists(dirPath))) {\n reject(new Error(`Path not found: ${dirPath}`));\n return;\n }\n // Check if path is a directory.\n const stat = await ops.stat(dirPath);\n if (!stat.isDirectory()) {\n reject(new Error(`Not a directory: ${dirPath}`));\n return;\n }\n // Read directory entries.\n let entries;\n try {\n entries = await ops.readdir(dirPath);\n }\n catch (e) {\n reject(new Error(`Cannot read directory: ${e.message}`));\n return;\n }\n // Sort alphabetically, case-insensitive.\n entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n // Format entries with directory indicators.\n const results = [];\n let entryLimitReached = false;\n for (const entry of entries) {\n if (results.length >= effectiveLimit) {\n entryLimitReached = true;\n break;\n }\n const fullPath = nodePath.join(dirPath, entry);\n let suffix = \"\";\n try {\n const entryStat = await ops.stat(fullPath);\n if (entryStat.isDirectory())\n suffix = \"/\";\n }\n catch {\n // Skip entries we cannot stat.\n continue;\n }\n results.push(entry + suffix);\n }\n signal?.removeEventListener(\"abort\", onAbort);\n if (results.length === 0) {\n resolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n return;\n }\n const rawOutput = results.join(\"\\n\");\n // Apply byte truncation. There is no separate line limit because entry count is already capped.\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let output = truncation.content;\n const details = {};\n // Build actionable notices for truncation and entry limits.\n const notices = [];\n if (entryLimitReached) {\n notices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n details.entryLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n output += `\\n\\n[${notices.join(\". \")}]`;\n }\n resolve({\n content: [{ type: \"text\", text: output }],\n details: Object.keys(details).length > 0 ? details : undefined,\n });\n }\n catch (e) {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(e);\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatLsCall(args, theme, context.cwd));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatLsResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createLsTool(cwd, options) {\n return wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n//# sourceMappingURL=ls.js.map","// @ts-nocheck — vendored Pi source (MIT, see ./PI-LICENSE); logic unchanged.\n// Sources @6f707eb36064e82af9c1320a7634f4dfad21049b:\n// coding-agent src/core/compaction/utils.ts (file-op tracking, serialization, system prompt)\n// coding-agent src/core/compaction/compaction.ts (token estimation, cut points, summarization)\n// coding-agent src/core/compaction/branch-summarization.ts (branch summaries)\n// pi-ai 0.84.1 dist/utils/text.js (contentText)\n// One deliberate seam, marked below: Pi's completeSummarization falls back to the\n// provider-SDK completeSimple() when no streamFn is given. In pi2dsh every model\n// call goes through the host llm bridge, so the pi2dsh export layer always\n// injects a bridge streamFn; reaching the fallback without one fails loud.\nimport { retryAssistantCall } from './pi-ai-retry.js'\nimport { uuidv7 } from './pi-uuid.js'\nimport {\n createBranchSummaryMessage,\n createCompactionSummaryMessage,\n createCustomMessage,\n convertToLlm,\n} from './pi-messages.js'\nimport { buildSessionContext, sessionEntryToContextMessages } from './pi-session-manager.js'\n\n// ---- pi-ai utils/text.js ---------------------------------------------------\n\nexport function contentText(content, separator = '\\n') {\n if (typeof content === 'string') return content\n return content\n .filter(block => block.type === 'text')\n .map(block => block.text)\n .join(separator)\n}\n\n// ---- compaction/utils.ts ---------------------------------------------------\n\nexport interface FileOperations {\n read: Set<string>\n written: Set<string>\n edited: Set<string>\n}\n\nexport function createFileOps(): FileOperations {\n return {\n read: new Set(),\n written: new Set(),\n edited: new Set(),\n }\n}\n\n/**\n * Extract file operations from tool calls in an assistant message.\n */\nexport function extractFileOpsFromMessage(message, fileOps: FileOperations): void {\n if (message.role !== 'assistant') return\n if (!('content' in message) || !Array.isArray(message.content)) return\n\n for (const block of message.content) {\n if (typeof block !== 'object' || block === null) continue\n if (!('type' in block) || block.type !== 'toolCall') continue\n if (!('arguments' in block) || !('name' in block)) continue\n\n const args = block.arguments\n if (!args) continue\n\n const path = typeof args.path === 'string' ? args.path : undefined\n if (!path) continue\n\n switch (block.name) {\n case 'read':\n fileOps.read.add(path)\n break\n case 'write':\n fileOps.written.add(path)\n break\n case 'edit':\n fileOps.edited.add(path)\n break\n }\n }\n}\n\n/**\n * Compute final file lists from file operations.\n * Returns readFiles (files only read, not modified) and modifiedFiles.\n */\nexport function computeFileLists(fileOps: FileOperations): { readFiles: string[]; modifiedFiles: string[] } {\n const modified = new Set([...fileOps.edited, ...fileOps.written])\n const readOnly = [...fileOps.read].filter(f => !modified.has(f)).sort()\n const modifiedFiles = [...modified].sort()\n return { readFiles: readOnly, modifiedFiles }\n}\n\n/**\n * Format file operations as XML tags for summary.\n */\nexport function formatFileOperations(readFiles: string[], modifiedFiles: string[]): string {\n const sections: string[] = []\n if (readFiles.length > 0) {\n sections.push(`<read-files>\\n${readFiles.join('\\n')}\\n</read-files>`)\n }\n if (modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${modifiedFiles.join('\\n')}\\n</modified-files>`)\n }\n if (sections.length === 0) return ''\n return `\\n\\n${sections.join('\\n\\n')}`\n}\n\n/** Maximum characters for a tool result in serialized summaries. */\nconst TOOL_RESULT_MAX_CHARS = 2000\n\n/**\n * Truncate text to a maximum character length for summarization.\n * Keeps the beginning and appends a truncation marker.\n */\nfunction truncateForSummary(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n const truncatedChars = text.length - maxChars\n return `${text.slice(0, maxChars)}\\n\\n[... ${truncatedChars} more characters truncated]`\n}\n\n/**\n * Serialize LLM messages to text for summarization.\n * This prevents the model from treating it as a conversation to continue.\n * Call convertToLlm() first to handle custom message types.\n *\n * Tool results are truncated to keep the summarization request within\n * reasonable token budgets. Full content is not needed for summarization.\n */\nexport function serializeConversation(messages): string {\n const parts: string[] = []\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n const content = contentText(msg.content, '')\n if (content) parts.push(`[User]: ${content}`)\n } else if (msg.role === 'assistant') {\n const thinkingParts: string[] = []\n const toolCalls: string[] = []\n\n for (const block of msg.content) {\n if (block.type === 'thinking') {\n thinkingParts.push(block.thinking)\n } else if (block.type === 'toolCall') {\n const args = block.arguments\n const argsStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(', ')\n toolCalls.push(`${block.name}(${argsStr})`)\n }\n }\n\n if (thinkingParts.length > 0) {\n parts.push(`[Assistant thinking]: ${thinkingParts.join('\\n')}`)\n }\n if (msg.content.some(block => block.type === 'text')) {\n parts.push(`[Assistant]: ${contentText(msg.content)}`)\n }\n if (toolCalls.length > 0) {\n parts.push(`[Assistant tool calls]: ${toolCalls.join('; ')}`)\n }\n } else if (msg.role === 'toolResult') {\n const content = contentText(msg.content, '')\n if (content) {\n parts.push(`[Tool result]: ${truncateForSummary(content, TOOL_RESULT_MAX_CHARS)}`)\n }\n }\n }\n\n return parts.join('\\n\\n')\n}\n\nexport const SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`\n\n// ---- compaction/compaction.ts ----------------------------------------------\n\nconst ESTIMATED_IMAGE_CHARS = 4800\n\nfunction estimateTextAndImageContentChars(content): number {\n if (typeof content === 'string') {\n return content.length\n }\n\n let chars = 0\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length\n } else if (block.type === 'image') {\n chars += ESTIMATED_IMAGE_CHARS\n }\n }\n return chars\n}\n\n/**\n * Estimate token count for a message using chars/4 heuristic.\n * This is conservative (overestimates tokens).\n */\nexport function estimateTokens(message): number {\n let chars = 0\n\n switch (message.role) {\n case 'user': {\n chars = estimateTextAndImageContentChars(message.content)\n return Math.ceil(chars / 4)\n }\n case 'assistant': {\n const assistant = message\n for (const block of assistant.content) {\n if (block.type === 'text') {\n chars += block.text.length\n } else if (block.type === 'thinking') {\n chars += block.thinking.length\n } else if (block.type === 'toolCall') {\n chars += block.name.length + JSON.stringify(block.arguments).length\n }\n }\n return Math.ceil(chars / 4)\n }\n case 'custom':\n case 'toolResult': {\n chars = estimateTextAndImageContentChars(message.content)\n return Math.ceil(chars / 4)\n }\n case 'bashExecution': {\n chars = message.command.length + message.output.length\n return Math.ceil(chars / 4)\n }\n case 'branchSummary':\n case 'compactionSummary': {\n chars = message.summary.length\n return Math.ceil(chars / 4)\n }\n }\n\n return 0\n}\n\nfunction isCutPointMessage(message): boolean {\n switch (message.role) {\n case 'user':\n case 'assistant':\n case 'bashExecution':\n case 'custom':\n case 'branchSummary':\n case 'compactionSummary':\n return true\n case 'toolResult':\n return false\n }\n return false\n}\n\nfunction isTurnStartMessage(message): boolean {\n switch (message.role) {\n case 'user':\n case 'bashExecution':\n case 'custom':\n case 'branchSummary':\n case 'compactionSummary':\n return true\n case 'assistant':\n case 'toolResult':\n return false\n }\n return false\n}\n\nfunction isTurnStartEntry(entry): boolean {\n if (entry.type === 'compaction') {\n return false\n }\n return sessionEntryToContextMessages(entry).some(isTurnStartMessage)\n}\n\n/**\n * Find valid cut points: indices of context-visible user-like or assistant messages.\n * Never cut at tool results (they must follow their tool call).\n * When we cut at an assistant message with tool calls, its tool results follow it\n * and will be kept.\n */\nfunction findValidCutPoints(entries, startIndex: number, endIndex: number): number[] {\n const cutPoints: number[] = []\n for (let i = startIndex; i < endIndex; i++) {\n const entry = entries[i]\n if (entry.type === 'compaction') {\n continue\n }\n if (sessionEntryToContextMessages(entry).some(isCutPointMessage)) {\n cutPoints.push(i)\n }\n }\n return cutPoints\n}\n\n/**\n * Find the context-visible user-role message that starts the turn containing the given entry index.\n * Returns -1 if no turn start found before the index.\n */\nexport function findTurnStartIndex(entries, entryIndex: number, startIndex: number): number {\n for (let i = entryIndex; i >= startIndex; i--) {\n if (isTurnStartEntry(entries[i])) {\n return i\n }\n }\n return -1\n}\n\nexport interface CutPointResult {\n /** Index of first entry to keep */\n firstKeptEntryIndex: number\n /** Index of user message that starts the turn being split, or -1 if not splitting */\n turnStartIndex: number\n /** Whether this cut splits a turn (cut point is not a user message) */\n isSplitTurn: boolean\n}\n\n/**\n * Find the cut point in session entries that keeps approximately `keepRecentTokens`.\n *\n * Algorithm: Walk backwards from newest, accumulating estimated message sizes.\n * Stop when we've accumulated >= keepRecentTokens. Cut at that point.\n *\n * Can cut at user OR assistant messages (never tool results). When cutting at an\n * assistant message with tool calls, its tool results come after and will be kept.\n *\n * Returns CutPointResult with:\n * - firstKeptEntryIndex: the entry index to start keeping from\n * - turnStartIndex: if cutting mid-turn, the user message that started that turn\n * - isSplitTurn: whether we're cutting in the middle of a turn\n *\n * Only considers entries between `startIndex` and `endIndex` (exclusive).\n */\nexport function findCutPoint(\n entries,\n startIndex: number,\n endIndex: number,\n keepRecentTokens: number,\n): CutPointResult {\n const cutPoints = findValidCutPoints(entries, startIndex, endIndex)\n\n if (cutPoints.length === 0) {\n return { firstKeptEntryIndex: startIndex, turnStartIndex: -1, isSplitTurn: false }\n }\n\n // Walk backwards from newest, accumulating estimated message sizes\n let accumulatedTokens = 0\n let cutIndex = cutPoints[0] // Default: keep from first message (not header)\n\n for (let i = endIndex - 1; i >= startIndex; i--) {\n const entry = entries[i]\n const messageTokens = sessionEntryToContextMessages(entry).reduce(\n (sum, message) => sum + estimateTokens(message),\n 0,\n )\n if (messageTokens === 0) continue\n accumulatedTokens += messageTokens\n\n // Check if we've exceeded the budget\n if (accumulatedTokens >= keepRecentTokens) {\n // Find the closest valid cut point at or after this entry\n for (let c = 0; c < cutPoints.length; c++) {\n if (cutPoints[c] >= i) {\n cutIndex = cutPoints[c]\n break\n }\n }\n break\n }\n }\n\n // Scan backwards from cutIndex to include adjacent metadata entries that do not affect context.\n while (cutIndex > startIndex) {\n const prevEntry = entries[cutIndex - 1]\n // Stop at compaction boundaries or context-visible entries.\n if (prevEntry.type === 'compaction' || sessionEntryToContextMessages(prevEntry).length > 0) {\n break\n }\n cutIndex--\n }\n\n // Determine if this is a split turn\n const cutEntry = entries[cutIndex]\n const startsTurn = isTurnStartEntry(cutEntry)\n const turnStartIndex = startsTurn ? -1 : findTurnStartIndex(entries, cutIndex, startIndex)\n\n return {\n firstKeptEntryIndex: cutIndex,\n turnStartIndex,\n isSplitTurn: !startsTurn && turnStartIndex !== -1,\n }\n}\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\nconst UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, and context from the new messages\n- UPDATE the Progress section: move items from \"In Progress\" to \"Done\" when completed\n- UPDATE \"Next Steps\" based on what was accomplished\n- PRESERVE exact file paths, function names, and error messages\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Goal\n[Preserve existing goals, add new ones if the task expanded]\n\n## Constraints & Preferences\n- [Preserve existing, add new ones discovered]\n\n## Progress\n### Done\n- [x] [Include previously done items AND newly completed items]\n\n### In Progress\n- [ ] [Current work - update based on progress]\n\n### Blocked\n- [Current blockers - remove if resolved]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale] (preserve all previous, add new)\n\n## Next Steps\n1. [Update based on current state]\n\n## Critical Context\n- [Preserve important context, add new if needed]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\nfunction createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel) {\n const options = { maxTokens, signal, apiKey, headers, env }\n if (model.reasoning && thinkingLevel && thinkingLevel !== 'off') {\n options.reasoning = thinkingLevel\n }\n return options\n}\n\n// pi2dsh seam (see file header): Pi calls the provider-SDK completeSimple() here.\n// The pi2dsh export layer always injects a host-llm-bridge streamFn, so this\n// fallback is unreachable through the shims; a direct vendored call without a\n// streamFn fails loud instead of pretending to reach a provider.\nfunction completeSimple(_model, _context, _options): never {\n throw new Error(\n 'pi2dsh: summarization without a streamFn would call a Pi provider SDK directly; '\n + 'model calls run through the DSH llm bridge (the pi2dsh exports inject it automatically)',\n )\n}\n\n/**\n * Shared choke point for every compaction/branch-summary summarization call. Wraps the\n * single LLM call in retryAssistantCall so transient stream drops (e.g.\n * `terminated`, socket close) honor the configured retry policy instead of failing\n * the whole compaction on the first attempt. Deterministic errors and aborts return\n * immediately (see retryAssistantCall).\n */\nexport async function completeSummarization(model, context, options, streamFn, retry, callbacks) {\n // Summaries are standalone requests, so isolate routing and avoid cache writes that cannot be reused.\n const requestOptions = {\n ...options,\n cacheRetention: 'none',\n sessionId: uuidv7(),\n }\n const produce = async () =>\n streamFn\n ? (await streamFn(model, context, requestOptions)).result()\n : completeSimple(model, context, requestOptions)\n return retryAssistantCall(produce, retry, requestOptions.signal, callbacks)\n}\n\nexport async function generateSummary(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n) {\n return (\n await generateSummaryWithUsage(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n ).text\n}\n\n/** Generate or update a conversation summary and return its provider usage. */\nexport async function generateSummaryWithUsage(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n) {\n const maxTokens = Math.min(\n Math.floor(0.8 * reserveTokens),\n model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n )\n\n // Use update prompt if we have a previous summary, otherwise initial prompt\n let basePrompt = previousSummary ? UPDATE_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT\n if (customInstructions) {\n basePrompt = `${basePrompt}\\n\\nAdditional focus: ${customInstructions}`\n }\n\n // Serialize conversation to text so model doesn't try to continue it\n // Convert to LLM messages first (handles custom types like bashExecution, custom, etc.)\n const llmMessages = convertToLlm(currentMessages)\n const conversationText = serializeConversation(llmMessages)\n\n // Build the prompt with conversation wrapped in tags\n let promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n`\n if (previousSummary) {\n promptText += `<previous-summary>\\n${previousSummary}\\n</previous-summary>\\n\\n`\n }\n promptText += basePrompt\n\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n const completionOptions = createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel)\n\n const response = await completeSummarization(\n model,\n { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n completionOptions,\n streamFn,\n retry,\n callbacks,\n )\n\n if (response.stopReason === 'error') {\n throw new Error(`Summarization failed: ${response.errorMessage || 'Unknown error'}`)\n }\n\n const textContent = contentText(response.content)\n\n return { text: textContent, usage: response.usage }\n}\n\n// ---- compaction/compaction.ts: usage math, preparation, full compaction ----\n\n/** Result from compact() - SessionManager adds uuid/parentUuid when saving */\nexport interface CompactionResult<T = unknown> {\n summary: string\n firstKeptEntryId: string\n tokensBefore: number\n estimatedTokensAfter?: number\n /** Usage from the LLM call(s) that generated this summary, if available */\n usage?\n /** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */\n details?: T\n}\n\nfunction combineUsage(first, second) {\n return {\n input: first.input + second.input,\n output: first.output + second.output,\n cacheRead: first.cacheRead + second.cacheRead,\n cacheWrite: first.cacheWrite + second.cacheWrite,\n ...(first.cacheWrite1h !== undefined || second.cacheWrite1h !== undefined\n ? { cacheWrite1h: (first.cacheWrite1h ?? 0) + (second.cacheWrite1h ?? 0) }\n : {}),\n ...(first.reasoning !== undefined || second.reasoning !== undefined\n ? { reasoning: (first.reasoning ?? 0) + (second.reasoning ?? 0) }\n : {}),\n totalTokens: first.totalTokens + second.totalTokens,\n cost: {\n input: first.cost.input + second.cost.input,\n output: first.cost.output + second.cost.output,\n cacheRead: first.cost.cacheRead + second.cost.cacheRead,\n cacheWrite: first.cost.cacheWrite + second.cost.cacheWrite,\n total: first.cost.total + second.cost.total,\n },\n }\n}\n\nexport interface CompactionSettings {\n enabled: boolean\n reserveTokens: number\n keepRecentTokens: number\n}\n\nexport const DEFAULT_COMPACTION_SETTINGS: CompactionSettings = {\n enabled: true,\n reserveTokens: 16384,\n keepRecentTokens: 20000,\n}\n\n/**\n * Calculate total context tokens from usage.\n * Uses the native totalTokens field when available, falls back to computing from components.\n */\nexport function calculateContextTokens(usage): number {\n return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite\n}\n\n/**\n * Get usage from an assistant message if available.\n * Skips aborted, error, and all-zero usage messages as they don't have valid usage data.\n */\nfunction getAssistantUsage(msg) {\n if (msg.role === 'assistant' && 'usage' in msg) {\n const assistantMsg = msg\n if (\n assistantMsg.stopReason !== 'aborted'\n && assistantMsg.stopReason !== 'error'\n && assistantMsg.usage\n && calculateContextTokens(assistantMsg.usage) > 0\n ) {\n return assistantMsg.usage\n }\n }\n return undefined\n}\n\n/**\n * Find the last valid assistant message usage from session entries.\n */\nexport function getLastAssistantUsage(entries) {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i]\n if (entry.type === 'message') {\n const usage = getAssistantUsage(entry.message)\n if (usage) return usage\n }\n }\n return undefined\n}\n\nexport interface ContextUsageEstimate {\n tokens: number\n usageTokens: number\n trailingTokens: number\n lastUsageIndex: number | null\n}\n\nfunction getLastAssistantUsageInfo(messages) {\n for (let i = messages.length - 1; i >= 0; i--) {\n const usage = getAssistantUsage(messages[i])\n if (usage) return { usage, index: i }\n }\n return undefined\n}\n\n/**\n * Estimate context tokens from messages, using the last assistant usage when available.\n * If there are messages after the last usage, estimate their tokens with estimateTokens.\n */\nexport function estimateContextTokens(messages): ContextUsageEstimate {\n const usageInfo = getLastAssistantUsageInfo(messages)\n\n if (!usageInfo) {\n let estimated = 0\n for (const message of messages) {\n estimated += estimateTokens(message)\n }\n return {\n tokens: estimated,\n usageTokens: 0,\n trailingTokens: estimated,\n lastUsageIndex: null,\n }\n }\n\n const usageTokens = calculateContextTokens(usageInfo.usage)\n let trailingTokens = 0\n for (let i = usageInfo.index + 1; i < messages.length; i++) {\n trailingTokens += estimateTokens(messages[i])\n }\n\n return {\n tokens: usageTokens + trailingTokens,\n usageTokens,\n trailingTokens,\n lastUsageIndex: usageInfo.index,\n }\n}\n\n/**\n * Check if compaction should trigger based on context usage.\n */\nexport function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean {\n if (!settings.enabled) return false\n return contextTokens > contextWindow - settings.reserveTokens\n}\n\nfunction extractFileOperations(messages, entries, prevCompactionIndex: number): FileOperations {\n const fileOps = createFileOps()\n\n // Collect from previous compaction's details (if pi-generated)\n if (prevCompactionIndex >= 0) {\n const prevCompaction = entries[prevCompactionIndex]\n if (!prevCompaction.fromHook && prevCompaction.details) {\n // fromHook field kept for session file compatibility\n const details = prevCompaction.details\n if (Array.isArray(details.readFiles)) {\n for (const f of details.readFiles) fileOps.read.add(f)\n }\n if (Array.isArray(details.modifiedFiles)) {\n for (const f of details.modifiedFiles) fileOps.edited.add(f)\n }\n }\n }\n\n // Extract from tool calls in messages\n for (const msg of messages) {\n extractFileOpsFromMessage(msg, fileOps)\n }\n\n return fileOps\n}\n\n/**\n * Extract AgentMessage from an entry if it produces one.\n * Returns undefined for entries that don't contribute to LLM context.\n */\nfunction getMessageFromEntryForCompaction(entry) {\n if (entry.type === 'compaction') {\n return undefined\n }\n return sessionEntryToContextMessages(entry)[0]\n}\n\nexport interface CompactionPreparation {\n /** UUID of first entry to keep */\n firstKeptEntryId: string\n /** Messages that will be summarized and discarded */\n messagesToSummarize\n /** Messages that will be turned into turn prefix summary (if splitting) */\n turnPrefixMessages\n /** Whether this is a split turn (cut point in middle of turn) */\n isSplitTurn: boolean\n tokensBefore: number\n /** Summary from previous compaction, for iterative update */\n previousSummary?: string\n /** File operations extracted from messagesToSummarize */\n fileOps: FileOperations\n /** Compaction settions from settings.jsonl\t*/\n settings: CompactionSettings\n}\n\nexport function prepareCompaction(pathEntries, settings: CompactionSettings): CompactionPreparation | undefined {\n if (pathEntries.length > 0 && pathEntries[pathEntries.length - 1].type === 'compaction') {\n return undefined\n }\n\n let prevCompactionIndex = -1\n for (let i = pathEntries.length - 1; i >= 0; i--) {\n if (pathEntries[i].type === 'compaction') {\n prevCompactionIndex = i\n break\n }\n }\n\n let previousSummary: string | undefined\n let boundaryStart = 0\n if (prevCompactionIndex >= 0) {\n const prevCompaction = pathEntries[prevCompactionIndex]\n previousSummary = prevCompaction.summary\n const firstKeptEntryIndex = pathEntries.findIndex(entry => entry.id === prevCompaction.firstKeptEntryId)\n boundaryStart = firstKeptEntryIndex >= 0 ? firstKeptEntryIndex : prevCompactionIndex + 1\n }\n const boundaryEnd = pathEntries.length\n\n const tokensBefore = estimateContextTokens(buildSessionContext(pathEntries).messages).tokens\n\n const cutPoint = findCutPoint(pathEntries, boundaryStart, boundaryEnd, settings.keepRecentTokens)\n\n // Get UUID of first kept entry\n const firstKeptEntry = pathEntries[cutPoint.firstKeptEntryIndex]\n if (!firstKeptEntry?.id) {\n return undefined // Session needs migration\n }\n const firstKeptEntryId = firstKeptEntry.id\n\n const historyEnd = cutPoint.isSplitTurn ? cutPoint.turnStartIndex : cutPoint.firstKeptEntryIndex\n\n // Messages to summarize (will be discarded after summary)\n const messagesToSummarize = []\n for (let i = boundaryStart; i < historyEnd; i++) {\n const msg = getMessageFromEntryForCompaction(pathEntries[i])\n if (msg) messagesToSummarize.push(msg)\n }\n\n // Messages for turn prefix summary (if splitting a turn)\n const turnPrefixMessages = []\n if (cutPoint.isSplitTurn) {\n for (let i = cutPoint.turnStartIndex; i < cutPoint.firstKeptEntryIndex; i++) {\n const msg = getMessageFromEntryForCompaction(pathEntries[i])\n if (msg) turnPrefixMessages.push(msg)\n }\n }\n\n if (messagesToSummarize.length === 0 && turnPrefixMessages.length === 0) {\n return undefined\n }\n\n // Extract file operations from messages and previous compaction\n const fileOps = extractFileOperations(messagesToSummarize, pathEntries, prevCompactionIndex)\n\n // Also extract file ops from turn prefix if splitting\n if (cutPoint.isSplitTurn) {\n for (const msg of turnPrefixMessages) {\n extractFileOpsFromMessage(msg, fileOps)\n }\n }\n\n return {\n firstKeptEntryId,\n messagesToSummarize,\n turnPrefixMessages,\n isSplitTurn: cutPoint.isSplitTurn,\n tokensBefore,\n previousSummary,\n fileOps,\n settings,\n }\n}\n\nconst TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.`\n\n/**\n * Generate summaries for compaction using prepared data.\n * Returns CompactionResult - SessionManager adds uuid/parentUuid when saving.\n */\nexport async function compact(\n preparation: CompactionPreparation,\n model,\n apiKey,\n headers,\n customInstructions,\n signal,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n): Promise<CompactionResult> {\n const {\n firstKeptEntryId,\n messagesToSummarize,\n turnPrefixMessages,\n isSplitTurn,\n tokensBefore,\n previousSummary,\n fileOps,\n settings,\n } = preparation\n\n // Generate summaries and merge into one\n let summary: string\n let summaryUsage\n\n if (isSplitTurn && turnPrefixMessages.length > 0) {\n let historyText = 'No prior history.'\n let historyUsage\n if (messagesToSummarize.length > 0) {\n const historyResult = await generateSummaryWithUsage(\n messagesToSummarize,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n historyText = historyResult.text\n historyUsage = historyResult.usage\n }\n const turnPrefixResult = await generateTurnPrefixSummary(\n turnPrefixMessages,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n env,\n signal,\n thinkingLevel,\n streamFn,\n retry,\n callbacks,\n )\n // Merge into single summary\n summary = `${historyText}\\n\\n---\\n\\n**Turn Context (split turn):**\\n\\n${turnPrefixResult.text}`\n summaryUsage = historyUsage ? combineUsage(historyUsage, turnPrefixResult.usage) : turnPrefixResult.usage\n } else {\n // Just generate history summary\n const result = await generateSummaryWithUsage(\n messagesToSummarize,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n summary = result.text\n summaryUsage = result.usage\n }\n\n // Compute file lists and append to summary\n const { readFiles, modifiedFiles } = computeFileLists(fileOps)\n summary += formatFileOperations(readFiles, modifiedFiles)\n\n if (!firstKeptEntryId) {\n throw new Error('First kept entry has no UUID - session may need migration')\n }\n\n return {\n summary,\n firstKeptEntryId,\n tokensBefore,\n usage: summaryUsage,\n details: { readFiles, modifiedFiles },\n }\n}\n\n/**\n * Generate a summary for a turn prefix (when splitting a turn).\n */\nasync function generateTurnPrefixSummary(\n messages,\n model,\n reserveTokens,\n apiKey,\n headers,\n env,\n signal,\n thinkingLevel,\n streamFn,\n retry,\n callbacks,\n) {\n const maxTokens = Math.min(\n Math.floor(0.5 * reserveTokens),\n model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n ) // Smaller budget for turn prefix\n const llmMessages = convertToLlm(messages)\n const conversationText = serializeConversation(llmMessages)\n const promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n const response = await completeSummarization(\n model,\n { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel),\n streamFn,\n retry,\n callbacks,\n )\n\n if (response.stopReason === 'error') {\n throw new Error(`Turn prefix summarization failed: ${response.errorMessage || 'Unknown error'}`)\n }\n\n return {\n text: contentText(response.content),\n usage: response.usage,\n }\n}\n\n// ---- compaction/branch-summarization.ts ------------------------------------\n\nexport interface BranchSummaryResult {\n summary?: string\n usage?\n readFiles?: string[]\n modifiedFiles?: string[]\n aborted?: boolean\n error?: string\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n readFiles: string[]\n modifiedFiles: string[]\n}\n\nexport interface BranchPreparation {\n /** Messages extracted for summarization, in chronological order */\n messages\n /** File operations extracted from tool calls */\n fileOps: FileOperations\n /** Total estimated tokens in messages */\n totalTokens: number\n}\n\nexport interface CollectEntriesResult {\n /** Entries to summarize, in chronological order */\n entries\n /** Common ancestor between old and new position, if any */\n commonAncestorId: string | null\n}\n\nexport interface GenerateBranchSummaryOptions {\n model\n apiKey?: string\n headers?: Record<string, string>\n env?: Record<string, string>\n signal: AbortSignal\n customInstructions?: string\n replaceInstructions?: boolean\n reserveTokens?: number\n streamFn?\n retry?\n callbacks?\n}\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n */\nexport function collectEntriesForBranchSummary(session, oldLeafId, targetId): CollectEntriesResult {\n // If no old position, nothing to summarize\n if (!oldLeafId) {\n return { entries: [], commonAncestorId: null }\n }\n\n // Find common ancestor (deepest node that's on both paths)\n const oldPath = new Set(session.getBranch(oldLeafId).map(e => e.id))\n const targetPath = session.getBranch(targetId)\n\n // targetPath is root-first, so iterate backwards to find deepest common ancestor\n let commonAncestorId: string | null = null\n for (let i = targetPath.length - 1; i >= 0; i--) {\n if (oldPath.has(targetPath[i].id)) {\n commonAncestorId = targetPath[i].id\n break\n }\n }\n\n // Collect entries from old leaf back to common ancestor\n const entries = []\n let current = oldLeafId\n\n while (current && current !== commonAncestorId) {\n const entry = session.getEntry(current)\n if (!entry) break\n entries.push(entry)\n current = entry.parentId\n }\n\n // Reverse to get chronological order\n entries.reverse()\n\n return { entries, commonAncestorId }\n}\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry) {\n switch (entry.type) {\n case 'message':\n // Skip tool results - context is in assistant's tool call\n if (entry.message.role === 'toolResult') return undefined\n return entry.message\n\n case 'custom_message':\n return createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp)\n\n case 'branch_summary':\n return createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)\n\n case 'compaction':\n return createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)\n\n // These don't contribute to conversation content\n case 'thinking_level_change':\n case 'model_change':\n case 'custom':\n case 'label':\n case 'session_info':\n return undefined\n }\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n */\nexport function prepareBranchEntries(entries, tokenBudget: number = 0): BranchPreparation {\n const messages = []\n const fileOps = createFileOps()\n let totalTokens = 0\n\n // First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n // This ensures we capture cumulative file tracking from nested branch summaries\n // Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n for (const entry of entries) {\n if (entry.type === 'branch_summary' && !entry.fromHook && entry.details) {\n const details = entry.details\n if (Array.isArray(details.readFiles)) {\n for (const f of details.readFiles) fileOps.read.add(f)\n }\n if (Array.isArray(details.modifiedFiles)) {\n // Modified files go into both edited and written for proper deduplication\n for (const f of details.modifiedFiles) {\n fileOps.edited.add(f)\n }\n }\n }\n }\n\n // Second pass: walk from newest to oldest, adding messages until token budget\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i]\n const message = getMessageFromEntry(entry)\n if (!message) continue\n\n // Extract file ops from assistant messages (tool calls)\n extractFileOpsFromMessage(message, fileOps)\n\n const tokens = estimateTokens(message)\n\n // Check budget before adding\n if (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n // If this is a summary entry, try to fit it anyway as it's important context\n if (entry.type === 'compaction' || entry.type === 'branch_summary') {\n if (totalTokens < tokenBudget * 0.9) {\n messages.unshift(message)\n totalTokens += tokens\n }\n }\n // Stop - we've hit the budget\n break\n }\n\n messages.unshift(message)\n totalTokens += tokens\n }\n\n return { messages, fileOps, totalTokens }\n}\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`\n\nconst BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.\n\nUse this EXACT format:\n\n## Goal\n[What was the user trying to accomplish in this branch?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Work that was started but not finished]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [What should happen next to continue this work]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\n/**\n * Generate a summary of abandoned branch entries.\n */\nexport async function generateBranchSummary(entries, options: GenerateBranchSummaryOptions): Promise<BranchSummaryResult> {\n const {\n model,\n apiKey,\n headers,\n env,\n signal,\n customInstructions,\n replaceInstructions,\n reserveTokens = 16384,\n streamFn,\n retry,\n callbacks,\n } = options\n\n // Token budget = context window minus reserved space for prompt + response\n const contextWindow = model.contextWindow || 128000\n const tokenBudget = contextWindow - reserveTokens\n\n const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget)\n\n if (messages.length === 0) {\n return { summary: 'No content to summarize' }\n }\n\n // Transform to LLM-compatible messages, then serialize to text\n // Serialization prevents the model from treating it as a conversation to continue\n const llmMessages = convertToLlm(messages)\n const conversationText = serializeConversation(llmMessages)\n\n // Build prompt\n let instructions: string\n if (replaceInstructions && customInstructions) {\n instructions = customInstructions\n } else if (customInstructions) {\n instructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`\n } else {\n instructions = BRANCH_SUMMARY_PROMPT\n }\n const promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`\n\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n // Call LLM for summarization. Prefer the session stream function so SDK\n // request behavior (timeouts, retries, attribution headers) stays consistent\n // without running through agent state/events. Retried via completeSummarization\n // so transient stream drops reuse the configured retry policy.\n const context = { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }\n const requestOptions = { apiKey, headers, env, signal, maxTokens: 2048 }\n const response = await completeSummarization(model, context, requestOptions, streamFn, retry, callbacks)\n\n // Check if aborted or errored\n if (response.stopReason === 'aborted') {\n return { aborted: true }\n }\n if (response.stopReason === 'error') {\n return { error: response.errorMessage || 'Summarization failed' }\n }\n\n let summary = contentText(response.content)\n\n // Prepend preamble to provide context about the branch summary\n summary = BRANCH_SUMMARY_PREAMBLE + summary\n\n // Compute file lists and append to summary\n const { readFiles, modifiedFiles } = computeFileLists(fileOps)\n summary += formatFileOperations(readFiles, modifiedFiles)\n\n return {\n summary: summary || 'No summary generated',\n usage: response.usage,\n readFiles,\n modifiedFiles,\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/frontmatter.ts @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); unchanged.\nimport { parse } from 'yaml'\n\ntype ParsedFrontmatter<T extends Record<string, unknown>> = {\n frontmatter: T\n body: string\n}\n\nconst normalizeNewlines = (value: string): string => value.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst extractFrontmatter = (content: string): { yamlString: string | null; body: string } => {\n const normalized = normalizeNewlines(content)\n\n if (!normalized.startsWith('---')) {\n return { yamlString: null, body: normalized }\n }\n\n const endIndex = normalized.indexOf('\\n---', 3)\n if (endIndex === -1) {\n return { yamlString: null, body: normalized }\n }\n\n return {\n yamlString: normalized.slice(4, endIndex),\n body: normalized.slice(endIndex + 4).trim(),\n }\n}\n\nexport const parseFrontmatter = <T extends Record<string, unknown> = Record<string, unknown>>(\n content: string,\n): ParsedFrontmatter<T> => {\n const { yamlString, body } = extractFrontmatter(content)\n if (!yamlString) {\n return { frontmatter: {} as T, body }\n }\n const parsed = parse(yamlString)\n return { frontmatter: (parsed ?? {}) as T, body }\n}\n\nexport const stripFrontmatter = (content: string): string => parseFrontmatter(content).body\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/tools/tool-definition-wrapper.ts +\n// src/core/extensions/wrapper.ts @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE);\n// logic unchanged. The `runner` parameter is typed structurally: Pi's own code uses exactly\n// createContext() and getActiveTools() from ExtensionRunner, which the pi2dsh projection provides.\n\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition(definition, ctxFactory) {\n return {\n name: definition.name,\n label: definition.label,\n description: definition.description,\n parameters: definition.parameters,\n constrainedSampling: definition.constrainedSampling,\n prepareArguments: definition.prepareArguments,\n executionMode: definition.executionMode,\n execute: (toolCallId, params, signal, onUpdate, ctx) =>\n definition.execute(toolCallId, params, signal, onUpdate, ctx ?? ctxFactory?.()),\n }\n}\n\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(definitions, ctxFactory) {\n return definitions.map(definition => wrapToolDefinition(definition, ctxFactory))\n}\n\n/**\n * Wrap a RegisteredTool into an AgentTool.\n * Uses the runner's createContext() for consistent context across tools and event handlers.\n */\nexport function wrapRegisteredTool(registeredTool, runner) {\n const tool = wrapToolDefinition(registeredTool.definition, () => runner.createContext())\n const execute = tool.execute\n return {\n ...tool,\n execute: async (toolCallId, params, signal, onUpdate) => {\n const activeBefore = runner.getActiveTools()\n const result = await execute(toolCallId, params, signal, onUpdate)\n const activeAfter = runner.getActiveTools()\n if (!activeBefore.every(name => activeAfter.includes(name))) return result\n\n const beforeNames = new Set(activeBefore)\n const addedToolNames = activeAfter.filter(name => !beforeNames.has(name))\n if (addedToolNames.length === 0) return result\n return {\n ...result,\n addedToolNames: [...new Set([...(result.addedToolNames ?? []), ...addedToolNames])],\n }\n },\n }\n}\n\n/**\n * Wrap all registered tools into AgentTools.\n * Uses the runner's createContext() for consistent context across tools and event handlers.\n */\nexport function wrapRegisteredTools(registeredTools, runner) {\n return registeredTools.map(tool => wrapRegisteredTool(tool, runner))\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/paths.ts subset\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// The subset the vendored skills loader and trust store reach: normalizePath,\n// resolvePath, canonicalizePath, and their helpers.\nimport { realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, resolve as nodeResolvePath } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g\n\nexport interface PathInputOptions {\n trim?: boolean\n normalizeUnicodeSpaces?: boolean\n stripAtPrefix?: boolean\n expandTilde?: boolean\n homeDir?: string\n}\n\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath: string): string {\n if (!filePath.startsWith('/') || filePath.startsWith('//') || filePath.includes('\\\\')) return filePath\n const match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i)\n if (!match) return filePath\n const suffix = match[2]?.replaceAll('/', '\\\\')\n return `${match[1].toUpperCase()}:\\\\${suffix ?? ''}`\n}\n\nexport function normalizePath(input: string, options: PathInputOptions = {}): string {\n let normalized = options.trim ? input.trim() : input\n if (options.normalizeUnicodeSpaces) {\n normalized = normalized.replace(UNICODE_SPACES, ' ')\n }\n if (options.stripAtPrefix && normalized.startsWith('@')) {\n normalized = normalized.slice(1)\n }\n if (process.platform === 'win32') {\n normalized = normalizeWindowsShellPath(normalized)\n }\n\n if (options.expandTilde ?? true) {\n const home = options.homeDir ?? homedir()\n if (normalized === '~') return home\n if (normalized.startsWith('~/') || (process.platform === 'win32' && normalized.startsWith('~\\\\'))) {\n return join(home, normalized.slice(2))\n }\n }\n\n if (/^file:\\/\\//.test(normalized)) {\n return fileURLToPath(normalized)\n }\n\n return normalized\n}\n\nexport function resolvePath(input: string, baseDir: string = process.cwd(), options: PathInputOptions = {}): string {\n const normalized = normalizePath(input, options)\n const normalizedBaseDir = normalizePath(baseDir)\n return isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized)\n}\n\nexport function canonicalizePath(path: string): string {\n try {\n return realpathSync(path)\n } catch {\n return path\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/trust-manager.ts store surface\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// The store operates wherever the caller points it: under pi2dsh the conventional\n// agentDir already resolves inside the DSH-owned pi2dsh directory, so a package's\n// trust decisions are package-visible state that the DSH host never consumes.\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport lockfile from 'proper-lockfile'\nimport { canonicalizePath, resolvePath } from './pi-paths.js'\n\nexport type ProjectTrustDecision = boolean | null\n\nexport interface ProjectTrustStoreEntry {\n path: string\n decision: boolean\n}\n\nexport interface ProjectTrustUpdate {\n path: string\n decision: ProjectTrustDecision\n}\n\ntype TrustFile = Record<string, boolean | null | undefined>\n\nfunction normalizeCwd(cwd: string): string {\n return canonicalizePath(resolvePath(cwd))\n}\n\nfunction findNearestTrustEntry(data: TrustFile, cwd: string): ProjectTrustStoreEntry | null {\n let currentDir = normalizeCwd(cwd)\n while (true) {\n const value = data[currentDir]\n if (value === true || value === false) {\n return { path: currentDir, decision: value }\n }\n\n const parentDir = dirname(currentDir)\n if (parentDir === currentDir) {\n return null\n }\n currentDir = parentDir\n }\n}\n\nfunction readTrustFile(path: string): TrustFile {\n if (!existsSync(path)) {\n return {}\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(readFileSync(path, 'utf-8'))\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to read trust store ${path}: ${message}`)\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(`Invalid trust store ${path}: expected an object`)\n }\n\n const data: TrustFile = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (value !== true && value !== false && value !== null) {\n throw new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`)\n }\n data[key] = value\n }\n return data\n}\n\nfunction writeTrustFile(path: string, data: TrustFile): void {\n const sorted: TrustFile = {}\n for (const key of Object.keys(data).sort()) {\n const value = data[key]\n if (value === true || value === false || value === null) {\n sorted[key] = value\n }\n }\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, `${JSON.stringify(sorted, null, 2)}\\n`, 'utf-8')\n}\n\nfunction acquireTrustLockSync(path: string): () => void {\n const trustDir = dirname(path)\n mkdirSync(trustDir, { recursive: true })\n const maxAttempts = 10\n const delayMs = 20\n let lastError: unknown\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return lockfile.lockSync(trustDir, { realpath: false, lockfilePath: `${path}.lock` })\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error\n ? String((error as { code?: unknown }).code)\n : undefined\n if (code !== 'ELOCKED' || attempt === maxAttempts) {\n throw error\n }\n lastError = error\n const start = Date.now()\n while (Date.now() - start < delayMs) {\n // Sleep synchronously to avoid changing trust store callers to async.\n }\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError\n }\n throw new Error('Failed to acquire trust store lock')\n}\n\nfunction withTrustFileLock<T>(path: string, fn: () => T): T {\n const release = acquireTrustLockSync(path)\n try {\n return fn()\n } finally {\n release()\n }\n}\n\nexport class ProjectTrustStore {\n private trustPath: string\n\n constructor(agentDir: string) {\n this.trustPath = resolvePath(agentDir) + '/trust.json'\n }\n\n get(cwd: string): ProjectTrustDecision {\n return this.getEntry(cwd)?.decision ?? null\n }\n\n getEntry(cwd: string): ProjectTrustStoreEntry | null {\n return withTrustFileLock(this.trustPath, () => {\n const data = readTrustFile(this.trustPath)\n return findNearestTrustEntry(data, cwd)\n })\n }\n\n set(cwd: string, decision: ProjectTrustDecision): void {\n this.setMany([{ path: cwd, decision }])\n }\n\n setMany(decisions: ProjectTrustUpdate[]): void {\n withTrustFileLock(this.trustPath, () => {\n const data = readTrustFile(this.trustPath)\n for (const { path, decision } of decisions) {\n const key = normalizeCwd(path)\n if (decision === null) {\n delete data[key]\n } else {\n data[key] = decision\n }\n }\n writeTrustFile(this.trustPath, data)\n })\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/skills.ts\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// createSyntheticSourceInfo is inlined from src/core/source-info.ts (same commit).\n// getAgentDir resolves through the pi2dsh config shim, so default skill\n// locations land inside the DSH-owned pi2dsh agent directory — the same\n// redirection every other conventional-path API already follows.\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs'\nimport ignore from 'ignore'\nimport { basename, dirname, join, relative, resolve, sep } from 'path'\nimport { getAgentDir } from './pi-config-shim.js'\nimport { parseFrontmatter } from './pi-frontmatter.js'\nimport { canonicalizePath, resolvePath } from './pi-paths.js'\n\n// coding-agent src/config.ts: the conventional Pi config directory name.\nconst CONFIG_DIR_NAME = '.pi'\n\n/** Max name length per spec */\nconst MAX_NAME_LENGTH = 64\n\n/** Max description length per spec */\nconst MAX_DESCRIPTION_LENGTH = 1024\n\nconst IGNORE_FILE_NAMES = ['.gitignore', '.ignore', '.fdignore']\n\nfunction toPosixPath(p: string): string {\n return p.split(sep).join('/')\n}\n\nfunction prefixIgnorePattern(line: string, prefix: string): string | null {\n const trimmed = line.trim()\n if (!trimmed) return null\n if (trimmed.startsWith('#') && !trimmed.startsWith('\\\\#')) return null\n\n let pattern = line\n let negated = false\n\n if (pattern.startsWith('!')) {\n negated = true\n pattern = pattern.slice(1)\n } else if (pattern.startsWith('\\\\!')) {\n pattern = pattern.slice(1)\n }\n\n if (pattern.startsWith('/')) {\n pattern = pattern.slice(1)\n }\n\n const prefixed = prefix ? `${prefix}${pattern}` : pattern\n return negated ? `!${prefixed}` : prefixed\n}\n\nfunction addIgnoreRules(ig, dir: string, rootDir: string): void {\n const relativeDir = relative(rootDir, dir)\n const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : ''\n\n for (const filename of IGNORE_FILE_NAMES) {\n const ignorePath = join(dir, filename)\n if (!existsSync(ignorePath)) continue\n try {\n const content = readFileSync(ignorePath, 'utf-8')\n const patterns = content\n .split(/\\r?\\n/)\n .map(line => prefixIgnorePattern(line, prefix))\n .filter(line => Boolean(line))\n if (patterns.length > 0) {\n ig.add(patterns)\n }\n } catch {}\n }\n}\n\n// source-info.ts (same commit): synthesize SourceInfo for resources that do not\n// come from a resolved package source.\nfunction createSyntheticSourceInfo(path, options) {\n return {\n path,\n source: options.source,\n scope: options.scope ?? 'temporary',\n origin: options.origin ?? 'top-level',\n baseDir: options.baseDir,\n }\n}\n\nexport interface SkillFrontmatter {\n name?: string\n description?: string\n 'disable-model-invocation'?: boolean\n [key: string]: unknown\n}\n\nexport interface Skill {\n name: string\n description: string\n filePath: string\n baseDir: string\n sourceInfo\n disableModelInvocation: boolean\n}\n\nexport interface LoadSkillsResult {\n skills: Skill[]\n diagnostics\n}\n\n/**\n * Validate skill name per Agent Skills spec.\n * Returns array of validation error messages (empty if valid).\n */\nfunction validateName(name: string): string[] {\n const errors: string[] = []\n\n if (name.length > MAX_NAME_LENGTH) {\n errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`)\n }\n\n if (!/^[a-z0-9-]+$/.test(name)) {\n errors.push(`name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)`)\n }\n\n if (name.startsWith('-') || name.endsWith('-')) {\n errors.push(`name must not start or end with a hyphen`)\n }\n\n if (name.includes('--')) {\n errors.push(`name must not contain consecutive hyphens`)\n }\n\n return errors\n}\n\n/**\n * Validate description per Agent Skills spec.\n */\nfunction validateDescription(description: string | undefined): string[] {\n const errors: string[] = []\n\n if (!description || description.trim() === '') {\n errors.push('description is required')\n } else if (description.length > MAX_DESCRIPTION_LENGTH) {\n errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`)\n }\n\n return errors\n}\n\nexport interface LoadSkillsFromDirOptions {\n /** Directory to scan for skills */\n dir: string\n /** Source identifier for these skills */\n source: string\n}\n\nfunction createSkillSourceInfo(filePath: string, baseDir: string, source: string) {\n switch (source) {\n case 'user':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n scope: 'user',\n baseDir,\n })\n case 'project':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n scope: 'project',\n baseDir,\n })\n case 'path':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n baseDir,\n })\n default:\n return createSyntheticSourceInfo(filePath, { source, baseDir })\n }\n}\n\n/**\n * Load skills from a directory.\n *\n * Discovery rules:\n * - if a directory contains SKILL.md, treat it as a skill root and do not recurse further\n * - otherwise, load direct .md children in the root\n * - recurse into subdirectories to find SKILL.md\n */\nexport function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkillsResult {\n const { dir, source } = options\n return loadSkillsFromDirInternal(dir, source, true)\n}\n\nfunction loadSkillsFromDirInternal(\n dir: string,\n source: string,\n includeRootFiles: boolean,\n ignoreMatcher?,\n rootDir?: string,\n): LoadSkillsResult {\n const skills: Skill[] = []\n const diagnostics = []\n\n if (!existsSync(dir)) {\n return { skills, diagnostics }\n }\n\n const root = rootDir ?? dir\n const ig = ignoreMatcher ?? ignore()\n addIgnoreRules(ig, dir, root)\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (entry.name !== 'SKILL.md') {\n continue\n }\n\n const fullPath = join(dir, entry.name)\n\n let isFile = entry.isFile()\n if (entry.isSymbolicLink()) {\n try {\n isFile = statSync(fullPath).isFile()\n } catch {\n continue\n }\n }\n\n const relPath = toPosixPath(relative(root, fullPath))\n if (!isFile || ig.ignores(relPath)) {\n continue\n }\n\n const result = loadSkillFromFile(fullPath, source)\n if (result.skill) {\n skills.push(result.skill)\n }\n diagnostics.push(...result.diagnostics)\n return { skills, diagnostics }\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) {\n continue\n }\n\n // Skip node_modules to avoid scanning dependencies\n if (entry.name === 'node_modules') {\n continue\n }\n\n const fullPath = join(dir, entry.name)\n\n // For symlinks, check if they point to a directory and follow them\n let isDirectory = entry.isDirectory()\n let isFile = entry.isFile()\n if (entry.isSymbolicLink()) {\n try {\n const stats = statSync(fullPath)\n isDirectory = stats.isDirectory()\n isFile = stats.isFile()\n } catch {\n // Broken symlink, skip it\n continue\n }\n }\n\n const relPath = toPosixPath(relative(root, fullPath))\n const ignorePath = isDirectory ? `${relPath}/` : relPath\n if (ig.ignores(ignorePath)) {\n continue\n }\n\n if (isDirectory) {\n const subResult = loadSkillsFromDirInternal(fullPath, source, false, ig, root)\n skills.push(...subResult.skills)\n diagnostics.push(...subResult.diagnostics)\n continue\n }\n\n if (!isFile || !includeRootFiles || !entry.name.endsWith('.md')) {\n continue\n }\n\n const result = loadSkillFromFile(fullPath, source)\n if (result.skill) {\n skills.push(result.skill)\n }\n diagnostics.push(...result.diagnostics)\n }\n } catch {}\n\n return { skills, diagnostics }\n}\n\nfunction loadSkillFromFile(filePath: string, source: string): { skill: Skill | null; diagnostics } {\n const diagnostics = []\n\n try {\n const rawContent = readFileSync(filePath, 'utf-8')\n const { frontmatter } = parseFrontmatter(rawContent)\n const skillDir = dirname(filePath)\n const parentDirName = basename(skillDir)\n\n // Validate description\n const descErrors = validateDescription(frontmatter.description)\n for (const error of descErrors) {\n diagnostics.push({ type: 'warning', message: error, path: filePath })\n }\n\n // Use name from frontmatter, or fall back to parent directory name\n const name = frontmatter.name || parentDirName\n\n // Validate name\n const nameErrors = validateName(name)\n for (const error of nameErrors) {\n diagnostics.push({ type: 'warning', message: error, path: filePath })\n }\n\n // Still load the skill even with warnings (unless description is completely missing)\n if (!frontmatter.description || frontmatter.description.trim() === '') {\n return { skill: null, diagnostics }\n }\n\n return {\n skill: {\n name,\n description: frontmatter.description,\n filePath,\n baseDir: skillDir,\n sourceInfo: createSkillSourceInfo(filePath, skillDir, source),\n disableModelInvocation: frontmatter['disable-model-invocation'] === true,\n },\n diagnostics,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'failed to parse skill file'\n diagnostics.push({ type: 'warning', message, path: filePath })\n return { skill: null, diagnostics }\n }\n}\n\nexport interface LoadSkillsOptions {\n /** Working directory for project-local skills. */\n cwd: string\n /** Agent config directory for global skills. */\n agentDir: string\n /** Explicit skill paths (files or directories) */\n skillPaths: string[]\n /** Include default skills directories. */\n includeDefaults: boolean\n}\n\n/**\n * Load skills from all configured locations.\n * Returns skills and any validation diagnostics.\n */\nexport function loadSkills(options: LoadSkillsOptions): LoadSkillsResult {\n const { agentDir, skillPaths, includeDefaults } = options\n\n // Resolve agentDir - if not provided, use default from config\n const resolvedCwd = resolvePath(options.cwd)\n const resolvedAgentDir = resolvePath(agentDir ?? getAgentDir())\n\n const skillMap = new Map<string, Skill>()\n const realPathSet = new Set<string>()\n const allDiagnostics = []\n const collisionDiagnostics = []\n\n function addSkills(result: LoadSkillsResult) {\n allDiagnostics.push(...result.diagnostics)\n for (const skill of result.skills) {\n // Resolve symlinks to detect duplicate files\n const realPath = canonicalizePath(skill.filePath)\n\n // Skip silently if we've already loaded this exact file (via symlink)\n if (realPathSet.has(realPath)) {\n continue\n }\n\n const existing = skillMap.get(skill.name)\n if (existing) {\n collisionDiagnostics.push({\n type: 'collision',\n message: `name \"${skill.name}\" collision`,\n path: skill.filePath,\n collision: {\n resourceType: 'skill',\n name: skill.name,\n winnerPath: existing.filePath,\n loserPath: skill.filePath,\n },\n })\n } else {\n skillMap.set(skill.name, skill)\n realPathSet.add(realPath)\n }\n }\n }\n\n if (includeDefaults) {\n addSkills(loadSkillsFromDirInternal(join(resolvedAgentDir, 'skills'), 'user', true))\n addSkills(loadSkillsFromDirInternal(resolve(resolvedCwd, CONFIG_DIR_NAME, 'skills'), 'project', true))\n }\n\n const userSkillsDir = join(resolvedAgentDir, 'skills')\n const projectSkillsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, 'skills')\n\n const isUnderPath = (target: string, root: string): boolean => {\n const normalizedRoot = resolve(root)\n if (target === normalizedRoot) {\n return true\n }\n const prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`\n return target.startsWith(prefix)\n }\n\n const getSource = (resolvedPath: string): 'user' | 'project' | 'path' => {\n if (!includeDefaults) {\n if (isUnderPath(resolvedPath, userSkillsDir)) return 'user'\n if (isUnderPath(resolvedPath, projectSkillsDir)) return 'project'\n }\n return 'path'\n }\n\n for (const rawPath of skillPaths) {\n const resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true })\n if (!existsSync(resolvedPath)) {\n allDiagnostics.push({ type: 'warning', message: 'skill path does not exist', path: resolvedPath })\n continue\n }\n\n try {\n const stats = statSync(resolvedPath)\n const source = getSource(resolvedPath)\n if (stats.isDirectory()) {\n addSkills(loadSkillsFromDirInternal(resolvedPath, source, true))\n } else if (stats.isFile() && resolvedPath.endsWith('.md')) {\n const result = loadSkillFromFile(resolvedPath, source)\n if (result.skill) {\n addSkills({ skills: [result.skill], diagnostics: result.diagnostics })\n } else {\n allDiagnostics.push(...result.diagnostics)\n }\n } else {\n allDiagnostics.push({ type: 'warning', message: 'skill path is not a markdown file', path: resolvedPath })\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'failed to read skill path'\n allDiagnostics.push({ type: 'warning', message, path: resolvedPath })\n }\n }\n\n return {\n skills: Array.from(skillMap.values()),\n diagnostics: [...allDiagnostics, ...collisionDiagnostics],\n }\n}\n","// @ts-nocheck — vendored Pi source excerpt (core/skills.js formatSkillsForPrompt + escapeXml @0.84.1, MIT, see ./PI-LICENSE); logic unchanged.\n/**\n * Format skills for inclusion in a system prompt.\n * Uses XML format per Agent Skills standard.\n * See: https://agentskills.io/integrate-skills\n *\n * Skills with disableModelInvocation=true are excluded from the prompt\n * (they can only be invoked explicitly via /skill:name commands).\n */\nexport function formatSkillsForPrompt(skills) {\n const visibleSkills = skills.filter((s) => !s.disableModelInvocation);\n if (visibleSkills.length === 0) {\n return \"\";\n }\n const lines = [\n \"\\n\\nThe following skills provide specialized instructions for specific tasks.\",\n \"Use the read tool to load a skill's file when the task matches its description.\",\n \"When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\",\n \"\",\n \"<available_skills>\",\n ];\n for (const skill of visibleSkills) {\n lines.push(\" <skill>\");\n lines.push(` <name>${escapeXml(skill.name)}</name>`);\n lines.push(` <description>${escapeXml(skill.description)}</description>`);\n lines.push(` <location>${escapeXml(skill.filePath)}</location>`);\n lines.push(\" </skill>\");\n }\n lines.push(\"</available_skills>\");\n return lines.join(\"\\n\");\n}\nfunction escapeXml(str) {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/shell.ts @47f9438, MIT, see ./PI-LICENSE);\n// excerpt: the getShellConfig closure consumed by resolve-config-value's `!command`\n// execution path. The full module's other exports depend on getBinDir and are not\n// used by the vendored resolver; logic of the excerpted functions is unchanged.\nimport { existsSync } from \"node:fs\";\nimport { spawnSync } from \"child_process\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n\tcommandTransport?: \"argv\" | \"stdin\";\n}\n\nfunction isLegacyWslBashPath(path: string): boolean {\n\tconst normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n\treturn /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\n\nfunction getBashShellConfig(shell: string): ShellConfig {\n\treturn isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\n\nfunction findBashOnPath(): string | null {\n\tif (process.platform === \"win32\") {\n\t\t// Windows: Use 'where' and verify file exists (where can return non-existent paths)\n\t\ttry {\n\t\t\tconst result = spawnSync(\"where\", [\"bash.exe\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5000,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tif (result.status === 0 && result.stdout) {\n\t\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\t\tif (firstMatch && existsSync(firstMatch)) {\n\t\t\t\t\treturn firstMatch;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n\ttry {\n\t\tconst result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch) {\n\t\t\t\treturn firstMatch;\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore errors\n\t}\n\treturn null;\n}\n\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath?: string): ShellConfig {\n\t// 1. Check user-specified shell path\n\tif (customShellPath) {\n\t\tif (existsSync(customShellPath)) {\n\t\t\treturn getBashShellConfig(customShellPath);\n\t\t}\n\t\tthrow new Error(`Custom shell path not found: ${customShellPath}`);\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\t// 2. Try Git Bash in known locations\n\t\tconst paths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) {\n\t\t\tpaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) {\n\t\t\tpaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\n\t\tfor (const path of paths) {\n\t\t\tif (existsSync(path)) {\n\t\t\t\treturn getBashShellConfig(path);\n\t\t\t}\n\t\t}\n\n\t\t// 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n\t\tconst bashOnPath = findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn getBashShellConfig(bashOnPath);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`No bash shell found. Options:\\n` +\n\t\t\t\t` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n\t\t\t\t` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n\t\t\t\t\" 3. Set shellPath in settings.json\\n\\n\" +\n\t\t\t\t`Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`,\n\t\t);\n\t}\n\n\t// Unix: try /bin/bash, then bash on PATH, then fallback to sh\n\tif (existsSync(\"/bin/bash\")) {\n\t\treturn getBashShellConfig(\"/bin/bash\");\n\t}\n\n\tconst bashOnPath = findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn getBashShellConfig(bashOnPath);\n\t}\n\n\treturn { shell: \"sh\", args: [\"-c\"] };\n}\n","// Headless @earendil-works/pi-coding-agent compatibility surface.\n//\n// Three tiers, all package-agnostic:\n// 1. Vendored Pi source (SessionManager, message transforms, truncation,\n// compaction/summarization, skills loading, trust store, tool wrappers,\n// file-mutation queue) — byte-level Pi semantics, see ./vendor/PI-LICENSE.\n// Summarization model calls fill Pi's own streamFn injection point with\n// the DSH llm bridge: one model path, no provider SDKs.\n// 2. Headless reimplementations (Theme, settings, shell/clipboard/image\n// helpers) — same signatures, no terminal or Pi-global state.\n// 3. Host-owned capabilities (package install, standalone model stacks) —\n// importable so packages load, but constructing them throws a structured\n// PiCapabilityError naming the DSH-owned replacement, never a silent fake.\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { readImageDimensions } from './vendor/pi-image-dimensions.js'\nimport { PiCapabilityError } from '../capability.js'\n\nexport {\n SessionManager,\n CURRENT_SESSION_VERSION,\n parseSessionEntries,\n migrateSessionEntries,\n getLatestCompactionEntry,\n sessionEntryToContextMessages,\n buildContextEntries,\n buildSessionContext,\n loadEntriesFromFile,\n findMostRecentSession,\n getDefaultSessionDir,\n assertValidSessionId,\n} from './vendor/pi-session-manager.js'\nexport type {\n SessionEntry,\n SessionHeader,\n SessionTreeNode,\n SessionContext,\n SessionInfo,\n SessionMessageEntry,\n CompactionEntry,\n BranchSummaryEntry,\n CustomEntry,\n CustomMessageEntry,\n LabelEntry,\n SessionInfoEntry,\n ThinkingLevelChangeEntry,\n ModelChangeEntry,\n} from './vendor/pi-session-manager.js'\nexport {\n convertToLlm,\n createBranchSummaryMessage,\n createCompactionSummaryMessage,\n createCustomMessage,\n bashExecutionToText,\n COMPACTION_SUMMARY_PREFIX,\n COMPACTION_SUMMARY_SUFFIX,\n BRANCH_SUMMARY_PREFIX,\n BRANCH_SUMMARY_SUFFIX,\n} from './vendor/pi-messages.js'\nexport type {\n BashExecutionMessage,\n CustomMessage,\n BranchSummaryMessage,\n CompactionSummaryMessage,\n} from './vendor/pi-messages.js'\nexport {\n DEFAULT_MAX_BYTES,\n DEFAULT_MAX_LINES,\n formatSize,\n truncateHead,\n truncateLine,\n truncateTail,\n} from './vendor/pi-truncate.js'\nexport type { TruncationOptions, TruncationResult } from './vendor/pi-truncate.js'\nexport { withFileMutationQueue } from './vendor/pi-file-mutation-queue.js'\nexport { getAgentDir } from './vendor/pi-config-shim.js'\n// Pre-bind extension-runtime factory, vendored byte-identical. Extensions that\n// assemble their own ResourceLoader-shaped getExtensions() result (pi-btw's\n// BTW overlay) construct one; an absent export throws at command execution.\nexport { createExtensionRuntime } from './vendor/pi-extension-runtime.js'\nexport type { ExtensionRuntime } from './vendor/pi-extension-runtime.js'\n// Pi's built-in tool constructors, vendored byte-identical (spawn semantics,\n// output accumulation, truncation, kill-tree, mutation queue, diff rendering)\n// — the constructor surface packages like pi-landstrip and pi-fabric build\n// their own sandboxed/filtered variants on.\nexport {\n createBashTool,\n createBashToolDefinition,\n createLocalBashOperations,\n bashToolSystemPromptContribution,\n} from './vendor/pi-tools/bash.js'\nexport { createReadTool, createReadToolDefinition } from './vendor/pi-tools/read.js'\nexport { createEditTool, createEditToolDefinition } from './vendor/pi-tools/edit.js'\nexport { createWriteTool, createWriteToolDefinition } from './vendor/pi-tools/write.js'\nexport { createGrepTool, createGrepToolDefinition } from './vendor/pi-tools/grep.js'\nexport { createFindTool, createFindToolDefinition } from './vendor/pi-tools/find.js'\nexport { createLsTool, createLsToolDefinition } from './vendor/pi-tools/ls.js'\n\n// Pi's one-line tool-event guards (core/extensions/types.js), verbatim.\ninterface ToolNamedEvent { toolName?: unknown }\nexport function isToolCallEventType(toolName: string, event: ToolNamedEvent): boolean {\n return event.toolName === toolName\n}\nexport function isBashToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'bash' }\nexport function isReadToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'read' }\nexport function isEditToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'edit' }\nexport function isWriteToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'write' }\nexport function isGrepToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'grep' }\nexport function isFindToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'find' }\nexport function isLsToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'ls' }\n\nimport { homedir } from 'node:os'\nimport { join, delimiter } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createBashTool } from './vendor/pi-tools/bash.js'\nimport { createReadTool } from './vendor/pi-tools/read.js'\nimport { createEditTool } from './vendor/pi-tools/edit.js'\nimport { createWriteTool } from './vendor/pi-tools/write.js'\nimport { createGrepTool } from './vendor/pi-tools/grep.js'\nimport { createFindTool } from './vendor/pi-tools/find.js'\nimport { createLsTool } from './vendor/pi-tools/ls.js'\nimport { execFile } from 'node:child_process'\nimport type { AgentMessage } from './vendor/pi-types.js'\nimport type { Component, SettingsListTheme, SelectListTheme } from './pi-tui.js'\nimport { visibleWidth, truncateToWidth } from './vendor/pi-tui-utils.js'\nimport { getAgentDir as agentDirOf } from './vendor/pi-config-shim.js'\n\nexport const CONFIG_DIR_NAME = '.pi'\nexport const VERSION = 'pi2dsh-compat'\n\nexport function defineTool<T>(tool: T): T {\n return tool\n}\n\nfunction unsupportedRuntime(name: string): never {\n throw new Error(\n `pi2dsh: ${name} belongs to Pi's internal agent runtime and has no verified DSH mapping; `\n + 'use the DSH-native service instead (see the pi2dsh compatibility report)',\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme system (headless)\n// ---------------------------------------------------------------------------\n\nconst identity = (text: string): string => text\n\nexport type ThemeColor = string\nexport type ThemeBg = string\nexport type ColorMode = 'truecolor' | '256' | '16' | 'none'\n\nexport class Theme {\n constructor(public name = 'pi2dsh-headless') {}\n fg(_color: ThemeColor, text: string): string {\n return text\n }\n bg(_color: ThemeBg, text: string): string {\n return text\n }\n bold(text: string): string {\n return text\n }\n italic(text: string): string {\n return text\n }\n underline(text: string): string {\n return text\n }\n inverse(text: string): string {\n return text\n }\n strikethrough(text: string): string {\n return text\n }\n getFgAnsi(_color: ThemeColor): string {\n return ''\n }\n getBgAnsi(_color: ThemeBg): string {\n return ''\n }\n getColorMode(): ColorMode {\n return 'none'\n }\n getThinkingBorderColor(_level: unknown): (str: string) => string {\n return identity\n }\n getBashModeBorderColor(): (str: string) => string {\n return identity\n }\n}\n\nexport const theme = new Theme()\n\nexport function initTheme(_themeName?: string, _enableWatcher = false): void {}\n\nexport function getSettingsListTheme(): SettingsListTheme {\n return {\n label: (text: string, _selected: boolean) => text,\n value: (text: string, _selected: boolean) => text,\n description: (text: string) => text,\n cursor: '→ ',\n hint: (text: string) => text,\n }\n}\n\nexport function getSelectListTheme(): SelectListTheme {\n return {\n selectedPrefix: '→ ',\n selectedText: identity,\n description: identity,\n scrollInfo: identity,\n noMatch: identity,\n }\n}\n\nexport function getMarkdownTheme(): Record<string, unknown> {\n return {\n heading: identity, link: identity, linkUrl: identity, code: identity, codeBlock: identity,\n codeBlockBorder: identity, quote: identity, quoteBorder: identity, hr: identity,\n listBullet: identity, bold: identity, italic: identity, underline: identity,\n strikethrough: identity, highlightCode: (code: string) => code.split('\\n'),\n }\n}\n\nconst LANGUAGE_BY_EXTENSION: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript', '.js': 'javascript', '.jsx': 'javascript',\n '.mjs': 'javascript', '.cjs': 'javascript', '.py': 'python', '.rb': 'ruby', '.go': 'go',\n '.rs': 'rust', '.java': 'java', '.c': 'c', '.h': 'c', '.cpp': 'cpp', '.hpp': 'cpp',\n '.cs': 'csharp', '.sh': 'bash', '.bash': 'bash', '.zsh': 'bash', '.json': 'json',\n '.yaml': 'yaml', '.yml': 'yaml', '.toml': 'ini', '.md': 'markdown', '.html': 'xml',\n '.xml': 'xml', '.css': 'css', '.scss': 'scss', '.sql': 'sql', '.php': 'php',\n '.swift': 'swift', '.kt': 'kotlin', '.scala': 'scala', '.lua': 'lua', '.r': 'r',\n}\n\nexport function getLanguageFromPath(filePath: string): string | undefined {\n const dot = filePath.lastIndexOf('.')\n if (dot === -1) return undefined\n return LANGUAGE_BY_EXTENSION[filePath.slice(dot).toLowerCase()]\n}\n\nexport function highlightCode(code: string, _lang?: string): string[] {\n return code.split('\\n')\n}\n\nexport class DynamicBorder implements Component {\n constructor(private color: (str: string) => string = identity) {}\n render(width: number): string[] {\n return [this.color('─'.repeat(Math.max(1, width)))]\n }\n invalidate(): void {}\n}\n\n// ---------------------------------------------------------------------------\n// Message / compaction helpers\n// ---------------------------------------------------------------------------\n\n// Pi's compaction surface, vendored (vendor/pi-compaction.ts): the pure logic\n// is byte-aligned with Pi, and the ONE seam is the model call — Pi's own\n// streamFn injection point, which these wrappers fill with the DSH llm bridge\n// when the caller does not pass a streamFn. Every summarization model call\n// therefore runs on the single DSH llm path.\nexport {\n estimateTokens,\n calculateContextTokens,\n DEFAULT_COMPACTION_SETTINGS,\n shouldCompact,\n findCutPoint,\n findTurnStartIndex,\n serializeConversation,\n prepareCompaction,\n getLastAssistantUsage,\n collectEntriesForBranchSummary,\n prepareBranchEntries,\n type CompactionResult,\n type CompactionSettings,\n type CompactionPreparation,\n type CutPointResult,\n type FileOperations,\n type BranchPreparation,\n type BranchSummaryResult,\n type CollectEntriesResult,\n type GenerateBranchSummaryOptions,\n} from './vendor/pi-compaction.js'\nimport {\n compact as vendoredCompact,\n generateSummary as vendoredGenerateSummary,\n generateSummaryWithUsage as vendoredGenerateSummaryWithUsage,\n generateBranchSummary as vendoredGenerateBranchSummary,\n DEFAULT_COMPACTION_SETTINGS,\n type CompactionSettings,\n} from './vendor/pi-compaction.js'\nimport { __getPiAiLlmBridge } from './pi-ai.js'\n\nexport function compact(\n preparation: unknown,\n model: unknown,\n apiKey?: unknown,\n headers?: unknown,\n customInstructions?: unknown,\n signal?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<unknown> {\n return vendoredCompact(\n preparation as never, model, apiKey, headers, customInstructions, signal, thinkingLevel,\n streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateSummary(\n currentMessages: unknown,\n model: unknown,\n reserveTokens: unknown,\n apiKey?: unknown,\n headers?: unknown,\n signal?: unknown,\n customInstructions?: unknown,\n previousSummary?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<string> {\n return vendoredGenerateSummary(\n currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions,\n previousSummary, thinkingLevel, streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateSummaryWithUsage(\n currentMessages: unknown,\n model: unknown,\n reserveTokens: unknown,\n apiKey?: unknown,\n headers?: unknown,\n signal?: unknown,\n customInstructions?: unknown,\n previousSummary?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<unknown> {\n return vendoredGenerateSummaryWithUsage(\n currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions,\n previousSummary, thinkingLevel, streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateBranchSummary(entries: unknown, options: Record<string, unknown>): Promise<unknown> {\n return vendoredGenerateBranchSummary(entries, {\n ...options,\n streamFn: options.streamFn ?? __getPiAiLlmBridge(),\n } as never)\n}\n\n// ---------------------------------------------------------------------------\n// Frontmatter\n// ---------------------------------------------------------------------------\n\n// Vendored Pi frontmatter (vendor/pi-frontmatter.ts): Pi's public API returns\n// { frontmatter, body } with YAML-parsed values. An earlier reimplementation\n// here returned { attributes } with string values — same name, wrong shape.\nexport { parseFrontmatter, stripFrontmatter } from './vendor/pi-frontmatter.js'\n\n// ---------------------------------------------------------------------------\n// Clipboard / image / shell helpers\n// ---------------------------------------------------------------------------\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const attempt = (command: string, args: string[]): Promise<boolean> =>\n new Promise(resolve => {\n const child = execFile(command, args, error => resolve(error === null))\n child.stdin?.write(text)\n child.stdin?.end()\n })\n if (process.platform === 'darwin') return attempt('pbcopy', [])\n if (process.platform === 'win32') return attempt('clip', [])\n if (await attempt('wl-copy', [])) return true\n return attempt('xclip', ['-selection', 'clipboard'])\n}\n\nexport interface ImageResizeOptions {\n /** Pi's default: 2000. */\n maxWidth?: number\n /** Pi's default: 2000. */\n maxHeight?: number\n /** Pi's default: 4.5MB of base64 payload. */\n maxBytes?: number\n /** Pi's default: 80. */\n jpegQuality?: number\n}\n\n/** Pi's exact result shape: base64 payload plus both the original and final size. */\nexport interface ResizedImage {\n data: string\n mimeType: string\n originalWidth: number\n originalHeight: number\n width: number\n height: number\n wasResized: boolean\n}\n\n/** Pi's defaults, so a caller passing nothing gets Pi's limits. */\nconst DEFAULT_MAX_BYTES = 4.5 * 1024 * 1024\n\n/**\n * Encode an image for inline use, reporting its true dimensions.\n *\n * Pi resizes here, using a worker and an image codec. This bridge has no\n * codec, so it does not resize — but it must not lie about the rest: the\n * payload really is base64 (packages feed this straight to a model), the\n * dimensions are read from the file header, and `wasResized` is honestly\n * false. When the image exceeds the caller's byte budget it cannot be made to\n * fit, so this returns `null` — Pi's own \"cannot produce a usable image\"\n * answer — rather than handing back something over the limit.\n * @param inputBytes - the complete image file.\n * @param mimeType - the declared image type.\n * @param options - Pi's resize budget; only `maxBytes` can be honoured here.\n */\nexport async function resizeImage(\n inputBytes: Uint8Array,\n mimeType: string,\n options: ImageResizeOptions = {},\n): Promise<ResizedImage | null> {\n const type = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (!INLINE_IMAGE_MIME_TYPES.has(type)) return null\n const data = Buffer.from(inputBytes).toString('base64')\n if (data.length > (options.maxBytes ?? DEFAULT_MAX_BYTES)) return null\n const size = readImageDimensions(inputBytes, type)\n if (size === undefined) return null\n return {\n data,\n mimeType: type,\n originalWidth: size.width,\n originalHeight: size.height,\n width: size.width,\n height: size.height,\n wasResized: false,\n }\n}\n\n/**\n * Pi's PNG conversion. Already-PNG input passes through; anything else needs\n * an image codec this bridge does not carry, so it answers `null` — the same\n * answer Pi gives when its own conversion fails, and one every caller already\n * handles.\n * @param base64Data - the image payload, base64 encoded.\n * @param mimeType - its declared type.\n */\nexport async function convertToPng(\n base64Data: string,\n mimeType: string,\n): Promise<{ data: string, mimeType: string } | null> {\n if (mimeType === 'image/png') return { data: base64Data, mimeType }\n return null\n}\n\n\n\n\n// Pi's install-directory locator: PI_PACKAGE_DIR override, else a stable\n// bridge-owned location (Pi itself falls back to its executable's directory,\n// which has no meaningful equivalent inside DSH).\nexport function getPackageDir(): string {\n const override = process.env.PI_PACKAGE_DIR\n if (override !== undefined && override.length > 0) return override\n return join(agentDirOf(), 'package')\n}\n\nexport interface StoredCredential {\n type?: string\n [key: string]: unknown\n}\n\n// Pi's one-off synchronous auth.json read, against the pi2dsh-owned agent\n// directory. DSH credentials stay authoritative for DSH model calls; this\n// serves packages that manage their own provider credentials Pi-style.\nexport function readStoredCredential(\n providerId: string,\n authPath: string = join(agentDirOf(), 'auth.json'),\n): StoredCredential | undefined {\n try {\n const data = JSON.parse(readFileSync(authPath, 'utf8')) as Record<string, StoredCredential>\n return data[providerId]\n } catch {\n return undefined\n }\n}\n\nexport interface ParsedSkillBlock {\n name: string\n content: string\n [key: string]: unknown\n}\n\n// Pi's <skill_content name=\"...\"> block parser, reimplemented over the same\n// wire shape.\nexport function parseSkillBlock(text: string): ParsedSkillBlock | null {\n const match = /<skill_content\\b[^>]*\\bname=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/skill_content>/u.exec(text)\n if (match === null) return null\n return { name: match[1]!, content: match[2]!.trim() }\n}\n\n// Vendored Pi tool wrappers (vendor/pi-tool-wrapper.ts): pure adapters from a\n// RegisteredTool/ToolDefinition to the AgentTool shape. Pi's `runner` argument\n// is used for exactly createContext() and getActiveTools(), which the pi2dsh\n// projection provides — packages composing their own agent loops get Pi's real\n// wrapping behavior.\nexport { wrapRegisteredTool, wrapRegisteredTools, wrapToolDefinition, wrapToolDefinitions } from './vendor/pi-tool-wrapper.js'\n\nexport function getBinDir(): string {\n const parts = (process.env.PATH ?? '').split(delimiter)\n return parts[0] ?? join(homedir(), '.local', 'bin')\n}\n\n// ---------------------------------------------------------------------------\n// Settings (in-memory, layered global/project like Pi)\n// ---------------------------------------------------------------------------\n\ntype SettingsRecord = Record<string, unknown>\n\nexport interface SettingsManagerCreateOptions {\n [key: string]: unknown\n}\n\nexport interface RetrySettings {\n enabled: boolean\n maxRetries: number\n baseDelayMs: number\n}\n\nexport type DefaultProjectTrust = 'ask' | 'always' | 'never'\nexport type TuiMode = 'regular' | 'fullscreen'\nexport type PackageSource = string | Record<string, unknown>\n\nexport class SettingsManager {\n private constructor(\n private globalSettings: SettingsRecord,\n private projectSettings: SettingsRecord,\n ) {}\n\n static create(_cwd?: string, _agentDir?: string, options: SettingsManagerCreateOptions = {}): SettingsManager {\n return SettingsManager.inMemory({}, options)\n }\n\n static fromStorage(_storage: unknown, options: SettingsManagerCreateOptions = {}): SettingsManager {\n return SettingsManager.inMemory({}, options)\n }\n\n static inMemory(settings: SettingsRecord = {}, _options: SettingsManagerCreateOptions = {}): SettingsManager {\n return new SettingsManager({ ...settings }, {})\n }\n\n private get merged(): SettingsRecord {\n return { ...this.globalSettings, ...this.projectSettings }\n }\n\n private read<T>(key: string, fallback: T): T {\n const value = this.merged[key]\n return value === undefined ? fallback : value as T\n }\n\n async reload(): Promise<void> {}\n async flush(): Promise<void> {}\n drainErrors(): unknown[] {\n return []\n }\n applyOverrides(overrides: SettingsRecord): void {\n Object.assign(this.globalSettings, overrides)\n }\n getGlobalSettings(): SettingsRecord {\n return { ...this.globalSettings }\n }\n getProjectSettings(): SettingsRecord {\n return { ...this.projectSettings }\n }\n isProjectTrusted(): boolean {\n return this.read('projectTrusted', false)\n }\n setProjectTrusted(trusted: boolean): void {\n this.projectSettings.projectTrusted = trusted\n }\n getDefaultProjectTrust(): DefaultProjectTrust {\n return this.read('defaultProjectTrust', 'ask')\n }\n getDefaultProvider(): string | undefined {\n return this.read('defaultProvider', undefined)\n }\n getDefaultModel(): string | undefined {\n return this.read('defaultModel', undefined)\n }\n setDefaultProvider(provider: string): void {\n this.globalSettings.defaultProvider = provider\n }\n setDefaultModel(model: string): void {\n this.globalSettings.defaultModel = model\n }\n setDefaultModelAndProvider(model: string, provider: string): void {\n this.setDefaultModel(model)\n this.setDefaultProvider(provider)\n }\n getDefaultThinkingLevel(): string | undefined {\n return this.read('defaultThinkingLevel', undefined)\n }\n getThemeSetting(): string | undefined {\n return this.read('theme', undefined)\n }\n getTheme(): string | undefined {\n return this.getThemeSetting()\n }\n setTheme(themeName: string): void {\n this.globalSettings.theme = themeName\n }\n getCompactionSettings(): CompactionSettings {\n return this.read('compaction', { ...DEFAULT_COMPACTION_SETTINGS })\n }\n getBranchSummarySettings(): { reserveTokens: number; skipPrompt: boolean } {\n return this.read('branchSummary', { reserveTokens: 8000, skipPrompt: false })\n }\n getRetrySettings(): RetrySettings {\n return this.read('retry', { enabled: true, maxRetries: 3, baseDelayMs: 1000 })\n }\n getProviderRetrySettings(): RetrySettings {\n return this.getRetrySettings()\n }\n getHttpIdleTimeoutMs(): number {\n return this.read('httpIdleTimeoutMs', 120_000)\n }\n getWebSocketConnectTimeoutMs(): number {\n return this.read('webSocketConnectTimeoutMs', 30_000)\n }\n getPackages(): PackageSource[] {\n return this.read('packages', [])\n }\n getExtensionPaths(): string[] {\n return this.read('extensions', [])\n }\n getSkillPaths(): string[] {\n return this.read('skills', [])\n }\n getPromptTemplatePaths(): string[] {\n return this.read('prompts', [])\n }\n getThemePaths(): string[] {\n return this.read('themes', [])\n }\n getTuiMode(): TuiMode {\n return this.read('tuiMode', 'regular')\n }\n getShowImages(): boolean {\n return this.read('showImages', false)\n }\n getImageWidthCells(): number {\n return this.read('imageWidthCells', 40)\n }\n getClearOnShrink(): boolean {\n return this.read('clearOnShrink', false)\n }\n getShowTerminalProgress(): boolean {\n return this.read('showTerminalProgress', false)\n }\n getHideThinkingBlock(): boolean {\n return this.read('hideThinkingBlock', false)\n }\n getExternalEditorCommand(): string | undefined {\n return this.read('externalEditorCommand', undefined)\n }\n getSteeringMode(): 'all' | 'one-at-a-time' {\n return this.read('steeringMode', 'all')\n }\n getFollowUpMode(): string {\n return this.read('followUpMode', 'queue')\n }\n getShellPath(): string | undefined {\n return this.read('shellPath', undefined)\n }\n getShellCommandPrefix(): string | undefined {\n return this.read('shellCommandPrefix', undefined)\n }\n getNpmCommand(): string[] | undefined {\n return this.read('npmCommand', undefined)\n }\n getEnableSkillCommands(): boolean {\n return this.read('enableSkillCommands', true)\n }\n getEnableAnalytics(): boolean {\n return false\n }\n getTrackingId(): string | undefined {\n return undefined\n }\n}\n\nexport class InMemorySettingsStorage {\n constructor(public settings: SettingsRecord = {}) {}\n async withLock<T>(_scope: string, fn: () => Promise<T> | T): Promise<T> {\n return fn()\n }\n}\n\nexport class FileSettingsStorage extends InMemorySettingsStorage {}\n\n\n// Vendored Pi trust store (vendor/pi-trust-store.ts): a real locked trust.json\n// under whatever agentDir the caller passes — with the redirected getAgentDir\n// convention that is package-visible state inside the DSH-owned pi2dsh\n// directory. The DSH host never consults this file; ctx.isProjectTrusted\n// stays fail-closed because host trust is a DSH decision.\nexport { ProjectTrustStore } from './vendor/pi-trust-store.js'\n\n// Pi's resource loader, headless: subagent packages construct one to control\n// a child session's resources (extensions/skills off, a system-prompt\n// override on). In the pi2dsh host the child shares the DSH composition's\n// registrations, so the loader carries the overrides and empty resource sets\n// — the exact result Pi produces under noExtensions/noSkills/noThemes.\nexport class DefaultResourceLoader {\n readonly #options: SettingsRecord\n\n constructor(options: SettingsRecord = {}) {\n this.#options = options\n }\n\n getExtensions(): { extensions: unknown[], errors: unknown[] } {\n const base = { extensions: [], errors: [] }\n const override = this.#options.extensionsOverride\n return typeof override === 'function' ? (override as (b: unknown) => never)(base) : base\n }\n\n getSkills(): { skills: unknown[], diagnostics: unknown[] } {\n return { skills: [], diagnostics: [] }\n }\n\n getPrompts(): { prompts: unknown[], diagnostics: unknown[] } {\n return { prompts: [], diagnostics: [] }\n }\n\n getThemes(): { themes: unknown[], diagnostics: unknown[] } {\n return { themes: [], diagnostics: [] }\n }\n\n getAgentsFiles(): { files: unknown[], diagnostics: unknown[] } {\n return { files: [], diagnostics: [] }\n }\n\n getSystemPrompt(): string | undefined {\n const override = this.#options.systemPromptOverride\n return typeof override === 'function' ? (override as (b: undefined) => string | undefined)(undefined) : undefined\n }\n\n getSystemPromptSource(): { kind: string } {\n return { kind: 'default' }\n }\n\n getAppendSystemPrompt(): string[] {\n const override = this.#options.appendSystemPromptOverride\n return typeof override === 'function' ? (override as (b: string[]) => string[])([]) : []\n }\n\n getAppendSystemPromptSources(): unknown[] {\n return []\n }\n\n extendResources(_paths: unknown): void {}\n\n async reload(_options?: unknown): Promise<void> {}\n}\n\n// Host-infrastructure classes stay unavailable BY DESIGN, as structured\n// capability errors a package can catch:\n// - DefaultPackageManager installs/removes packages — on DSH that is the\n// user's `dsh plugin add/remove`, behind pnpm's build-script security gate.\n// - ModelRuntime composes a full standalone model stack (credentials +\n// providers + models.json) — on DSH the ONE model directory is the host llm\n// configuration, projected through ctx.modelRegistry.\nfunction hostInfrastructureClass(name: string, reason: string, guidance: string): new (...args: unknown[]) => never {\n return class {\n constructor() {\n throw new PiCapabilityError({ capability: `new ${name}()`, reason, guidance })\n }\n } as never\n}\n\nexport const DefaultPackageManager = hostInfrastructureClass(\n 'DefaultPackageManager',\n 'installing packages is owned by the DSH host and its security gates.',\n 'Add or remove plugins with: dsh plugin add/remove <package>.',\n)\nexport const ModelRuntime = hostInfrastructureClass(\n 'ModelRuntime',\n 'the model directory is owned by the DSH host llm configuration.',\n \"Configure gateways in the host's llm settings; packages read the directory through ctx.modelRegistry.\",\n)\n\nexport class ModelRegistry {\n private models = new Map<string, unknown>()\n register(id: string, model: unknown): void {\n this.models.set(id, model)\n }\n get(id: string): unknown {\n return this.models.get(id)\n }\n list(): unknown[] {\n return [...this.models.values()]\n }\n}\n\nexport interface RegisteredToolRecord {\n definition: unknown\n sourceInfo: { path: string, source?: string, scope?: string, origin?: string }\n}\n\n// Pi's runner class, reduced to the surface tool-catalog packages actually\n// hook: pi-fabric patches `prototype.getAllRegisteredTools` to observe and\n// filter every registered tool. The pi2dsh runtime constructs one instance\n// whose provider yields the live Pi tool registrations (original definition\n// object references, so symbol-anchored detection works), and routes its own\n// tool enumeration through it — a patched prototype really filters the\n// catalog, exactly as under Pi.\nexport class ExtensionRunner {\n #provider: () => RegisteredToolRecord[]\n\n constructor(provider?: () => RegisteredToolRecord[]) {\n this.#provider = provider ?? (() => [])\n }\n\n getAllRegisteredTools(): RegisteredToolRecord[] {\n return this.#provider()\n }\n}\n\n// The mounted pi2dsh runtime installs the real factory: createAgentSession\n// builds a genuine DSH child agent through ctx.agents (the host loop's\n// factory) with Pi's public AgentSession surface bridged over it. Outside a\n// mounted runtime the call keeps its explicit failure.\ntype SubagentSessionFactory = (options: Record<string, unknown>) => Promise<{ session: unknown }>\nlet subagentSessionFactory: SubagentSessionFactory | undefined\nconst scopedSubagentSessionFactory = new AsyncLocalStorage<SubagentSessionFactory | undefined>()\n\nexport function __setSubagentSessionFactory(factory: SubagentSessionFactory | undefined): void {\n subagentSessionFactory = factory\n}\n\n/** Run extension-owned work with the exact Agent runtime's child-session factory. */\nexport function __runWithSubagentSessionFactory<T>(\n factory: SubagentSessionFactory | undefined,\n callback: () => T,\n): T {\n return scopedSubagentSessionFactory.run(factory, callback)\n}\n\nexport async function createAgentSession(options: Record<string, unknown> = {}): Promise<{ session: unknown }> {\n const factory = scopedSubagentSessionFactory.getStore() ?? subagentSessionFactory\n if (factory === undefined) {\n return unsupportedRuntime('createAgentSession() outside a mounted pi2dsh runtime')\n }\n return factory(options)\n}\n\n// Byte-identical to Pi's own composition of its built-in tool constructors\n// (core/tools/index.js): coding = read+bash+edit+write, read-only =\n// read+grep+find+ls.\nexport function createCodingTools(cwd: string, options?: Record<string, { [key: string]: unknown } | undefined>): unknown[] {\n return [\n createReadTool(cwd, options?.read),\n createBashTool(cwd, options?.bash),\n createEditTool(cwd, options?.edit),\n createWriteTool(cwd, options?.write),\n ]\n}\n\nexport function createReadOnlyTools(cwd: string, options?: Record<string, { [key: string]: unknown } | undefined>): unknown[] {\n return [\n createReadTool(cwd, options?.read),\n createGrepTool(cwd, options?.grep),\n createFindTool(cwd, options?.find),\n createLsTool(cwd, options?.ls),\n ]\n}\n\n// Vendored Pi skills loader (vendor/pi-skills-load.ts): real directory\n// discovery with Pi's exact rules (SKILL.md roots, ignore files, symlink\n// dedup, name/description validation). Default locations resolve through the\n// redirected getAgentDir, i.e. inside the DSH-owned pi2dsh directory.\nexport { loadSkills, loadSkillsFromDir } from './vendor/pi-skills-load.js'\n\n// ---------------------------------------------------------------------------\n// Headless host services backing the vendored built-in tools. Each mirrors a\n// documented Pi behavior for environments without the full interactive host:\n// ensureTool matches Pi's own offline mode (find on PATH, never download);\n// highlightCode matches Pi's no-language branch (plain lines — the headless\n// theme applies no styling anyway); processImage passes supported formats\n// through un-resized (Pi's resize/convert path runs a WASM codec that has no\n// place in a headless bridge; oversized or exotic images degrade with Pi's\n// own omission message).\n// ---------------------------------------------------------------------------\n\nexport function getReadmePath(): string {\n return join(getPackageDir(), 'README.md')\n}\n\nconst MANAGED_HOST_TOOLS = new Set(['rg', 'fd'])\n\nexport function getToolPath(tool: string): string | undefined {\n const pathKey = Object.keys(process.env).find(key => key.toLowerCase() === 'path') ?? 'PATH'\n for (const dir of (process.env[pathKey] ?? '').split(delimiter)) {\n if (dir.length === 0) continue\n const candidate = join(dir, process.platform === 'win32' ? `${tool}.exe` : tool)\n if (existsSync(candidate)) return candidate\n }\n return undefined\n}\n\nexport async function ensureTool(tool: string, _silent = false): Promise<string | undefined> {\n const existing = getToolPath(tool)\n if (existing !== undefined) return existing\n // Pi's offline mode semantics: a managed tool that is not on PATH is\n // reported unavailable instead of downloaded.\n return MANAGED_HOST_TOOLS.has(tool) ? undefined : undefined\n}\n\nconst INLINE_IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/gif', 'image/webp'])\n\nexport async function processImage(\n bytes: Uint8Array,\n mimeType: string,\n _options?: { autoResizeImages?: boolean },\n): Promise<\n | { ok: true, data: string, mimeType: string, hints: string[] }\n | { ok: false, message: string }\n> {\n const base = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (!INLINE_IMAGE_MIME_TYPES.has(base)) {\n return { ok: false, message: '[Image omitted: could not be converted to a supported inline image format.]' }\n }\n return {\n ok: true,\n data: Buffer.from(bytes).toString('base64'),\n mimeType: base,\n hints: ['[Image passed through unresized by pi2dsh.]'],\n }\n}\n\n\n\nexport { formatSkillsForPrompt } from './vendor/pi-skills-format.js'\n\n// Pi's own implementations, vendored. Hand-written stand-ins for these three\n// diverged from Pi in ways a package cannot see: a shell picked from $SHELL\n// where Pi is bash-only, head-truncation where Pi keeps the tail, and a diff\n// renderer with a different signature entirely.\nexport { getShellConfig, type ShellConfig } from './vendor/pi-shell-config.js'\nexport { truncateToVisualLines } from './vendor/pi-tools/visual-truncate.js'\nexport { renderDiff } from './vendor/pi-tools/diff-component.js'\n\nexport function createEventBus(): {\n emit(channel: string, data: unknown): void\n on(channel: string, handler: (data: unknown) => void): () => void\n clear(): void\n} {\n const handlers = new Map<string, Set<(data: unknown) => void>>()\n return {\n emit(channel, data) {\n for (const handler of handlers.get(channel) ?? []) {\n Promise.resolve().then(() => handler(data)).catch(error => console.error(error))\n }\n },\n on(channel, handler) {\n const set = handlers.get(channel) ?? new Set()\n set.add(handler)\n handlers.set(channel, set)\n return () => {\n set.delete(handler)\n }\n },\n clear() {\n handlers.clear()\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Interactive-mode UI components (headless)\n// ---------------------------------------------------------------------------\n\nclass HeadlessComponent implements Component {\n render(_width: number): string[] {\n return []\n }\n invalidate(): void {}\n}\n\nexport class ToolExecutionComponent extends HeadlessComponent {}\nexport class FooterComponent extends HeadlessComponent {}\nexport class BorderedLoader extends HeadlessComponent {\n start(): void {}\n stop(): void {}\n dispose(): void {}\n}\nexport class CustomMessageComponent extends HeadlessComponent {}\nexport class AssistantMessageComponent extends HeadlessComponent {}\nexport class UserMessageComponent extends HeadlessComponent {}\nexport class ExtensionSelectorComponent extends HeadlessComponent {}\nexport class ExtensionInputComponent extends HeadlessComponent {}\nexport class ExtensionEditorComponent extends HeadlessComponent {}\nexport class SettingsSelectorComponent extends HeadlessComponent {}\n\nexport class CustomEditor extends HeadlessComponent {\n private text = ''\n onSubmit?: (text: string) => void\n onChange?: (text: string) => void\n getText(): string {\n return this.text\n }\n setText(text: string): void {\n this.text = text\n this.onChange?.(text)\n }\n handleInput(data: string): void {\n if (data === '\\r' || data === '\\n') {\n this.onSubmit?.(this.text)\n return\n }\n if (data >= ' ') this.setText(this.text + data)\n }\n}\n\nexport interface ToolExecutionOptions {\n [key: string]: unknown\n}\nexport interface SettingsConfig {\n [key: string]: unknown\n}\nexport interface SettingsCallbacks {\n [key: string]: unknown\n}\nexport interface RenderDiffOptions {\n [key: string]: unknown\n}\n\n\n\nexport interface VisualTruncateResult {\n visualLines: string[]\n skippedCount: number\n}\n\n\n\nexport function keyHint(keybinding: string, description: string): string {\n return `${keybinding} ${description}`\n}\n\nexport function keyText(keybinding: string): string {\n return keybinding\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n return `${key} ${description}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pi-coding-agent-DXJ_Jzo0.mjs","names":["randomUUID","getDefaultAgentDir","resolvePath","join","existsSync","normalizePath","stat","readdir","resolve","DEFAULT_MAX_LINES","DEFAULT_MAX_BYTES","GREP_MAX_LINE_LENGTH","splitLinesForCounting","formatSize","truncateHead","truncateTail","truncateStringToBytesFromEnd","truncateLine","fileMutationQueues","registrationQueue","isMissingPathError","getMutationQueueKey","withFileMutationQueue","getBinDir","joinBinDir","getAgentDirForBin","isLegacyWslBashPath","getBashShellConfig","findBashOnPath","getShellConfig","DEFAULT_MAX_BYTES","UNICODE_SPACES","normalizeWindowsShellPath","normalizePath","resolvePath","nodeResolvePath","resolvePath","replaceTabs","wrapToolDefinition","getShellConfig","fsAccess","spawn","DEFAULT_MAX_BYTES","wrapToolDefinition","resolvePath","fsReadFile","fsAccess","constants","trimTrailingEmptyLines","toPosixPath","resolvePath","replaceTabs","DEFAULT_MAX_BYTES","wrapToolDefinition","access","constants","readFile","fsReadFile","fsWriteFile","fsAccess","constants","wrapToolDefinition","fsWriteFile","fsMkdir","replaceTabs","dirname","wrapToolDefinition","DEFAULT_LIMIT","fsStat","fsReadFile","DEFAULT_MAX_BYTES","spawn","createInterface","wrapToolDefinition","DEFAULT_LIMIT","DEFAULT_MAX_BYTES","spawn","createInterface","wrapToolDefinition","fsStat","fsReaddir","DEFAULT_MAX_BYTES","path","nodePath","wrapToolDefinition","generateSummary","generateSummaryWithUsage","compact","generateBranchSummary","nodeResolvePath","CONFIG_DIR_NAME","sep","relative","join","existsSync","readFileSync","dirname","basename","resolve","vendoredCompact","vendoredGenerateSummary","vendoredGenerateSummaryWithUsage","vendoredGenerateBranchSummary","agentDirOf","#options","#provider"],"sources":["../src/capability.ts","../src/compat/vendor/pi-image-dimensions.ts","../src/compat/vendor/pi-messages.ts","../src/compat/vendor/pi-session-manager.ts","../src/compat/vendor/pi-truncate.ts","../src/compat/vendor/pi-file-mutation-queue.ts","../src/compat/vendor/pi-extension-runtime.ts","../src/compat/vendor/pi-tools/visual-truncate.ts","../src/compat/vendor/pi-tools/child-process.ts","../src/compat/vendor/pi-tools/shell.ts","../src/compat/vendor/pi-tools/truncate.ts","../src/compat/vendor/pi-tools/output-accumulator.ts","../src/compat/vendor/pi-tools/ansi.ts","../src/compat/vendor/pi-tools/paths.ts","../src/compat/vendor/pi-tools/render-utils.ts","../src/compat/vendor/pi-tools/tool-definition-wrapper.ts","../src/compat/vendor/pi-tools/bash.ts","../src/compat/vendor/pi-tools/mime.ts","../src/compat/vendor/pi-tools/path-utils.ts","../src/compat/vendor/pi-tools/read.ts","../src/compat/vendor/pi-tools/diff-component.ts","../src/compat/vendor/pi-tools/edit-diff.ts","../src/compat/vendor/pi-tools/file-mutation-queue.ts","../src/compat/vendor/pi-tools/edit.ts","../src/compat/vendor/pi-tools/write.ts","../src/compat/vendor/pi-tools/grep.ts","../src/compat/vendor/pi-tools/find.ts","../src/compat/vendor/pi-tools/ls.ts","../src/compat/vendor/pi-compaction.ts","../src/compat/vendor/pi-frontmatter.ts","../src/compat/vendor/pi-tool-wrapper.ts","../src/compat/vendor/pi-paths.ts","../src/compat/vendor/pi-trust-store.ts","../src/compat/vendor/pi-skills-load.ts","../src/compat/vendor/pi-skills-format.ts","../src/compat/vendor/pi-shell-config.ts","../src/compat/pi-coding-agent.ts"],"sourcesContent":["// Capability-gap handling: what happens when a migrated Pi package reaches a\n// Pi capability that has no DSH mapping.\n//\n// The rules (docs/STANDARDS.md \"能力缺口分级处置\"):\n// 1. Whatever Pi's own protocol can express honestly, use Pi's channel — a\n// host refusal (`{ cancelled: true }`), a host-defined no-op (shutdown) —\n// never a bare throw and never a fabricated success.\n// 2. When only an error is honest (the return value cannot be faked), throw\n// a structured PiCapabilityError the package can catch like any Pi error.\n// 3. Every gap hit is recorded per package in the host-level ledger and\n// reported to the USER once per (package, capability): what stopped\n// working, that the rest of the plugin keeps working, and how to remove\n// the plugin if the gap is its main purpose. The middle layer cannot know\n// which feature is \"core\" to a plugin — the ledger gives the user the\n// facts to decide.\n// 4. A gap hit while the package's entry code is still mounting means the\n// package cannot start at all: it is marked unusable and reported as such.\n\nexport type PackageHealthStatus = 'ok' | 'degraded' | 'unusable'\n\nexport interface PackageHealth {\n status: PackageHealthStatus\n /** Pi capability names this package has hit, in first-hit order. */\n gaps: readonly string[]\n}\n\nexport interface CapabilityGapOptions {\n /** The Pi capability, as the package sees it (e.g. \"ctx.fork\"). */\n capability: string\n /** Why DSH has no mapping, in one sentence. */\n reason: string\n /** What the caller can do about it, in one sentence. */\n guidance: string\n /** The migrated package that hit the gap, when known. */\n packageName?: string\n}\n\n/**\n * The structured error for capability gaps where only failing is honest.\n * A plain Error subclass on purpose: Pi packages catch it exactly like any\n * error a real Pi host throws.\n */\nexport class PiCapabilityError extends Error {\n readonly capability: string\n readonly packageName: string | undefined\n\n constructor(options: CapabilityGapOptions) {\n super(`pi2dsh: ${options.capability} is not available on DSH — ${options.reason} ${options.guidance}`)\n this.name = 'PiCapabilityError'\n this.capability = options.capability\n this.packageName = options.packageName\n }\n}\n\ninterface LedgerEntry {\n status: PackageHealthStatus\n gaps: string[]\n}\n\nconst HEALTHY: PackageHealth = Object.freeze({ status: 'ok', gaps: Object.freeze([]) as readonly string[] })\n\n/**\n * Host-level record of capability gaps, one instance per DSH host (it lives in\n * SharedHostState). Emits ONE user-facing notice per (package, capability):\n * repeated hits of the same gap change nothing the user needs to hear again.\n */\nexport class CapabilityLedger {\n private readonly noticed = new Set<string>()\n private readonly packages = new Map<string, LedgerEntry>()\n\n constructor(private readonly emit: (message: string) => void) {}\n\n /**\n * Record a degraded capability: this feature of the package does not work on\n * DSH, the rest of the package keeps working. Reported to the user once.\n */\n reportDegraded(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.mark(packageName, options.capability, 'degraded')\n this.notice(packageName, options.capability, () =>\n `[pi2dsh] plugin \"${packageName}\": the Pi capability ${options.capability} is not available on DSH `\n + `(${options.reason}) That feature will not work; the plugin's other features keep working. `\n + `${options.guidance} If this capability is the plugin's main purpose, remove it: dsh plugin remove ${packageName}`)\n }\n\n /**\n * Record a host-owned decision (e.g. shutdown): the host refused or absorbed\n * the request through a channel Pi itself defines. Not a package defect, so\n * package health stays untouched; the user still learns what happened, once.\n */\n reportHostDecision(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.notice(packageName, options.capability, () =>\n `[pi2dsh] plugin \"${packageName}\": ${options.capability} — ${options.reason} ${options.guidance}`)\n }\n\n /**\n * Startup-time reference detection: the package's source imports a\n * host-owned symbol that cannot work on DSH. Reported at mount so the user\n * learns BEFORE any code path runs into it; health is untouched because an\n * import alone proves nothing about usage — construction still fails\n * structurally and marks the package then.\n */\n reportStartupReference(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.notice(packageName, `${options.capability}#startup-reference`, () =>\n `[pi2dsh] startup check: plugin \"${packageName}\" imports ${options.capability}, which is not available on DSH `\n + `(${options.reason}) If the plugin's main purpose depends on it, it will not work here — `\n + `consider removing it: dsh plugin remove ${packageName}`)\n }\n\n /**\n * Record that a package could not even mount because its entry code needs a\n * missing capability. The package is marked unusable for this run.\n */\n reportUnusable(options: CapabilityGapOptions): void {\n const packageName = options.packageName ?? '(unknown package)'\n this.mark(packageName, options.capability, 'unusable')\n this.notice(packageName, `${options.capability}#mount`, () =>\n `[pi2dsh] plugin \"${packageName}\" could not start: its startup code needs the Pi capability `\n + `${options.capability}, which is not available on DSH (${options.reason}) `\n + `The plugin is unusable in this composition — remove it: dsh plugin remove ${packageName}`)\n }\n\n healthOf(packageName: string): PackageHealth {\n const entry = this.packages.get(packageName)\n if (entry === undefined) return HEALTHY\n return { status: entry.status, gaps: [...entry.gaps] }\n }\n\n /** Every package with a recorded gap, for surfacing in mount summaries. */\n snapshot(): ReadonlyMap<string, PackageHealth> {\n const view = new Map<string, PackageHealth>()\n for (const [name, entry] of this.packages) {\n view.set(name, { status: entry.status, gaps: [...entry.gaps] })\n }\n return view\n }\n\n private mark(packageName: string, capability: string, status: 'degraded' | 'unusable'): void {\n const entry = this.packages.get(packageName) ?? { status: 'ok' as PackageHealthStatus, gaps: [] }\n if (!entry.gaps.includes(capability)) entry.gaps.push(capability)\n // unusable outranks degraded; degraded never downgrades unusable.\n entry.status = entry.status === 'unusable' ? 'unusable' : status\n this.packages.set(packageName, entry)\n }\n\n private notice(packageName: string, capability: string, build: () => string): void {\n const key = `${packageName}\u0000${capability}`\n if (this.noticed.has(key)) return\n this.noticed.add(key)\n this.emit(build())\n }\n}\n","// Image dimensions read straight from the file header, for the four inline\n// formats Pi accepts. Pi gets these from its resize worker; this bridge does\n// not resize, but the caller is still owed the real numbers — Pi's\n// `ResizedImage` contract has four dimension fields, and inventing zeros\n// there would be a lie a package cannot detect.\n//\n// Header offsets only: no decoding, no dependency.\n\n/** Width and height in pixels, or undefined when the header is not one we can read. */\nexport interface ImageDimensions {\n width: number\n height: number\n}\n\n/**\n * Read the pixel dimensions out of an image header.\n * @param bytes - the complete image file.\n * @param mimeType - the declared type, used to pick the header layout.\n * @returns the dimensions, or undefined when the header is absent or malformed.\n */\nexport function readImageDimensions(bytes: Uint8Array, mimeType: string): ImageDimensions | undefined {\n const type = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (type === 'image/png') return pngDimensions(bytes)\n if (type === 'image/jpeg') return jpegDimensions(bytes)\n if (type === 'image/gif') return gifDimensions(bytes)\n if (type === 'image/webp') return webpDimensions(bytes)\n return undefined\n}\n\nconst view = (bytes: Uint8Array): DataView => new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\n/** PNG: an 8-byte signature, then an IHDR chunk whose first two fields are the size. */\nfunction pngDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 24) return undefined\n if (bytes[0] !== 0x89 || bytes[1] !== 0x50 || bytes[2] !== 0x4E || bytes[3] !== 0x47) return undefined\n const data = view(bytes)\n return { width: data.getUint32(16, false), height: data.getUint32(20, false) }\n}\n\n/** GIF: dimensions sit at a fixed offset, little-endian. */\nfunction gifDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 10) return undefined\n if (bytes[0] !== 0x47 || bytes[1] !== 0x49 || bytes[2] !== 0x46) return undefined\n const data = view(bytes)\n return { width: data.getUint16(6, true), height: data.getUint16(8, true) }\n}\n\n/**\n * JPEG: walk the marker segments to the frame header (SOF0…SOF15, skipping\n * the four that are not frames), which carries the size.\n */\nfunction jpegDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 4 || bytes[0] !== 0xFF || bytes[1] !== 0xD8) return undefined\n const data = view(bytes)\n let offset = 2\n while (offset + 9 < bytes.length) {\n if (bytes[offset] !== 0xFF) { offset += 1; continue }\n const marker = bytes[offset + 1] ?? 0\n // Standalone markers carry no length payload.\n if (marker === 0xD8 || marker === 0x01 || (marker >= 0xD0 && marker <= 0xD7)) { offset += 2; continue }\n const length = data.getUint16(offset + 2, false)\n const isFrame = marker >= 0xC0 && marker <= 0xCF\n && marker !== 0xC4 && marker !== 0xC8 && marker !== 0xCC\n if (isFrame) return { height: data.getUint16(offset + 5, false), width: data.getUint16(offset + 7, false) }\n if (length < 2) return undefined\n offset += 2 + length\n }\n return undefined\n}\n\n/** WebP: three container variants (lossy, lossless, extended), each with its own size layout. */\nfunction webpDimensions(bytes: Uint8Array): ImageDimensions | undefined {\n if (bytes.length < 30) return undefined\n const tag = String.fromCharCode(...bytes.slice(0, 4)) + String.fromCharCode(...bytes.slice(8, 12))\n if (tag !== 'RIFFWEBP') return undefined\n const data = view(bytes)\n const format = String.fromCharCode(...bytes.slice(12, 16))\n if (format === 'VP8 ') {\n return { width: data.getUint16(26, true) & 0x3FFF, height: data.getUint16(28, true) & 0x3FFF }\n }\n if (format === 'VP8L') {\n const bits = data.getUint32(21, true)\n return { width: (bits & 0x3FFF) + 1, height: ((bits >> 14) & 0x3FFF) + 1 }\n }\n if (format === 'VP8X') {\n const width = 1 + ((bytes[24] ?? 0) | ((bytes[25] ?? 0) << 8) | ((bytes[26] ?? 0) << 16))\n const height = 1 + ((bytes[27] ?? 0) | ((bytes[28] ?? 0) << 8) | ((bytes[29] ?? 0) << 16))\n return { width, height }\n }\n return undefined\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\n/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage, ImageContent, Message, TextContent } from \"./pi-types.ts\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\ttokensBefore: number;\n\ttimestamp: number;\n}\n\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\tlet text = `Ran \\`${msg.command}\\`\\n`;\n\tif (msg.output) {\n\t\ttext += `\\`\\`\\`\\n${msg.output}\\n\\`\\`\\``;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated && msg.fullOutputPath) {\n\t\ttext += `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`;\n\t}\n\treturn text;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number,\n\ttimestamp: string,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary: summary,\n\t\ttokensBefore,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\t// Skip messages excluded from context (!! prefix)\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"assistant\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\nimport type { AgentMessage } from \"./pi-types.ts\";\nimport type { ImageContent, Message, TextContent, Usage } from \"./pi-types.ts\";\nimport { uuidv7 } from \"./pi-uuid.ts\";\nimport { randomUUID } from \"crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\tcreateReadStream,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { createInterface } from \"readline\";\nimport { StringDecoder } from \"string_decoder\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir, normalizePath, resolvePath } from \"./pi-config-shim.ts\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CustomMessage,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"./pi-messages.ts\";\n\nexport const CURRENT_SESSION_VERSION = 3;\n\nexport interface SessionHeader {\n\ttype: \"session\";\n\tversion?: number; // v1 sessions don't have this\n\tid: string;\n\ttimestamp: string;\n\tcwd: string;\n\tparentSession?: string;\n}\n\nexport interface NewSessionOptions {\n\tid?: string;\n\tparentSession?: string;\n}\n\nexport interface SessionEntryBase {\n\ttype: string;\n\tid: string;\n\tparentId: string | null;\n\ttimestamp: string;\n}\n\nexport interface SessionMessageEntry extends SessionEntryBase {\n\ttype: \"message\";\n\tmessage: AgentMessage;\n}\n\nexport interface ThinkingLevelChangeEntry extends SessionEntryBase {\n\ttype: \"thinking_level_change\";\n\tthinkingLevel: string;\n}\n\nexport interface ModelChangeEntry extends SessionEntryBase {\n\ttype: \"model_change\";\n\tprovider: string;\n\tmodelId: string;\n}\n\nexport interface CompactionEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"compaction\";\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\t/** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */\n\tdetails?: T;\n\t/** Usage from the LLM call(s) that generated this summary, if available */\n\tusage?: Usage;\n\t/** True if generated by an extension, undefined/false if pi-generated (backward compatible) */\n\tfromHook?: boolean;\n}\n\nexport interface BranchSummaryEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"branch_summary\";\n\tfromId: string;\n\tsummary: string;\n\t/** Extension-specific data (not sent to LLM) */\n\tdetails?: T;\n\t/** Usage from the LLM call that generated this summary, if available */\n\tusage?: Usage;\n\t/** True if generated by an extension, false if pi-generated */\n\tfromHook?: boolean;\n}\n\n/**\n * Custom entry for extensions to store extension-specific data in the session.\n * Use customType to identify your extension's entries.\n *\n * Purpose: Persist extension state across session reloads. On reload, extensions can\n * scan entries for their customType and reconstruct internal state.\n *\n * Does NOT participate in LLM context (ignored by buildSessionContext).\n * For injecting content into context, see CustomMessageEntry.\n */\nexport interface CustomEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"custom\";\n\tcustomType: string;\n\tdata?: T;\n}\n\n/** Label entry for user-defined bookmarks/markers on entries. */\nexport interface LabelEntry extends SessionEntryBase {\n\ttype: \"label\";\n\ttargetId: string;\n\tlabel: string | undefined;\n}\n\n/** Session metadata entry (e.g., user-defined display name). */\nexport interface SessionInfoEntry extends SessionEntryBase {\n\ttype: \"session_info\";\n\tname?: string;\n}\n\n/**\n * Custom message entry for extensions to inject messages into LLM context.\n * Use customType to identify your extension's entries.\n *\n * Unlike CustomEntry, this DOES participate in LLM context.\n * The content is converted to a user message in buildSessionContext().\n * Use details for extension-specific metadata (not sent to LLM).\n *\n * display controls TUI rendering:\n * - false: hidden entirely\n * - true: rendered with distinct styling (different from user messages)\n */\nexport interface CustomMessageEntry<T = unknown> extends SessionEntryBase {\n\ttype: \"custom_message\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: T;\n\tdisplay: boolean;\n}\n\n/** Session entry - has id/parentId for tree structure (returned by \"read\" methods in SessionManager) */\nexport type SessionEntry =\n\t| SessionMessageEntry\n\t| ThinkingLevelChangeEntry\n\t| ModelChangeEntry\n\t| CompactionEntry\n\t| BranchSummaryEntry\n\t| CustomEntry\n\t| CustomMessageEntry\n\t| LabelEntry\n\t| SessionInfoEntry;\n\n/** Raw file entry (includes header) */\nexport type FileEntry = SessionHeader | SessionEntry;\n\n/** Tree node for getTree() - defensive copy of session structure */\nexport interface SessionTreeNode {\n\tentry: SessionEntry;\n\tchildren: SessionTreeNode[];\n\t/** Resolved label for this entry, if any */\n\tlabel?: string;\n\t/** Timestamp of the latest label change for this entry, if any */\n\tlabelTimestamp?: string;\n}\n\nexport interface SessionContext {\n\tmessages: AgentMessage[];\n\tthinkingLevel: string;\n\tmodel: { provider: string; modelId: string } | null;\n}\n\nexport interface SessionInfo {\n\tpath: string;\n\tid: string;\n\t/** Working directory where the session was started. Empty string for old sessions. */\n\tcwd: string;\n\t/** User-defined display name from session_info entries. */\n\tname?: string;\n\t/** Path to the parent session (if this session was forked). */\n\tparentSessionPath?: string;\n\tcreated: Date;\n\tmodified: Date;\n\tmessageCount: number;\n\tfirstMessage: string;\n\tallMessagesText: string;\n}\n\nexport type ReadonlySessionManager = Pick<\n\tSessionManager,\n\t| \"getCwd\"\n\t| \"getSessionDir\"\n\t| \"getSessionId\"\n\t| \"getSessionFile\"\n\t| \"getLeafId\"\n\t| \"getLeafEntry\"\n\t| \"getEntry\"\n\t| \"getLabel\"\n\t| \"getBranch\"\n\t| \"buildContextEntries\"\n\t| \"getHeader\"\n\t| \"getEntries\"\n\t| \"getTree\"\n\t| \"getSessionName\"\n>;\n\nfunction createSessionId(): string {\n\treturn uuidv7();\n}\n\nexport function assertValidSessionId(id: string): void {\n\tif (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id)) {\n\t\tthrow new Error(\n\t\t\t\"Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t}\n}\n\n/** Generate a unique short ID (8 hex chars, collision-checked) */\nfunction generateId(byId: { has(id: string): boolean }): string {\n\tfor (let i = 0; i < 100; i++) {\n\t\tconst id = randomUUID().slice(0, 8);\n\t\tif (!byId.has(id)) return id;\n\t}\n\t// Fallback to full UUID if somehow we have collisions\n\treturn randomUUID();\n}\n\n/** Migrate v1 → v2: add id/parentId tree structure. Mutates in place. */\nfunction migrateV1ToV2(entries: FileEntry[]): void {\n\tconst ids = new Set<string>();\n\tlet prevId: string | null = null;\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session\") {\n\t\t\tentry.version = 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tentry.id = generateId(ids);\n\t\tentry.parentId = prevId;\n\t\tprevId = entry.id;\n\n\t\t// Convert firstKeptEntryIndex to firstKeptEntryId for compaction\n\t\tif (entry.type === \"compaction\") {\n\t\t\tconst comp = entry as CompactionEntry & { firstKeptEntryIndex?: number };\n\t\t\tif (typeof comp.firstKeptEntryIndex === \"number\") {\n\t\t\t\tconst targetEntry = entries[comp.firstKeptEntryIndex];\n\t\t\t\tif (targetEntry && targetEntry.type !== \"session\") {\n\t\t\t\t\tcomp.firstKeptEntryId = targetEntry.id;\n\t\t\t\t}\n\t\t\t\tdelete comp.firstKeptEntryIndex;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Migrate v2 → v3: rename hookMessage role to custom. Mutates in place. */\nfunction migrateV2ToV3(entries: FileEntry[]): void {\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session\") {\n\t\t\tentry.version = 3;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Update message entries with hookMessage role\n\t\tif (entry.type === \"message\") {\n\t\t\tconst msgEntry = entry as SessionMessageEntry;\n\t\t\tif (msgEntry.message && (msgEntry.message as { role: string }).role === \"hookMessage\") {\n\t\t\t\t(msgEntry.message as { role: string }).role = \"custom\";\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Run all necessary migrations to bring entries to current version.\n * Mutates entries in place. Returns true if any migration was applied.\n */\nfunction migrateToCurrentVersion(entries: FileEntry[]): boolean {\n\tconst header = entries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\tconst version = header?.version ?? 1;\n\n\tif (version >= CURRENT_SESSION_VERSION) return false;\n\n\tif (version < 2) migrateV1ToV2(entries);\n\tif (version < 3) migrateV2ToV3(entries);\n\n\treturn true;\n}\n\n/** Exported for testing */\nexport function migrateSessionEntries(entries: FileEntry[]): void {\n\tmigrateToCurrentVersion(entries);\n}\n\n/** Exported for compaction.test.ts */\nexport function parseSessionEntries(content: string): FileEntry[] {\n\tconst entries: FileEntry[] = [];\n\tconst lines = content.trim().split(\"\\n\");\n\n\tfor (const line of lines) {\n\t\tif (!line.trim()) continue;\n\t\ttry {\n\t\t\tconst entry = JSON.parse(line) as FileEntry;\n\t\t\tentries.push(entry);\n\t\t} catch {\n\t\t\t// Skip malformed lines\n\t\t}\n\t}\n\n\treturn entries;\n}\n\nexport function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tif (entries[i].type === \"compaction\") {\n\t\t\treturn entries[i] as CompactionEntry;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction buildEntryIndex(entries: SessionEntry[], byId?: Map<string, SessionEntry>): Map<string, SessionEntry> {\n\tif (byId) return byId;\n\tconst index = new Map<string, SessionEntry>();\n\tfor (const entry of entries) {\n\t\tindex.set(entry.id, entry);\n\t}\n\treturn index;\n}\n\nfunction buildSessionPath(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionEntry[] {\n\tconst index = buildEntryIndex(entries, byId);\n\tlet leaf: SessionEntry | undefined;\n\tif (leafId === null) {\n\t\treturn [];\n\t}\n\tif (leafId) {\n\t\tleaf = index.get(leafId);\n\t}\n\tleaf ??= entries[entries.length - 1];\n\tif (!leaf) {\n\t\treturn [];\n\t}\n\n\tconst path: SessionEntry[] = [];\n\tlet current: SessionEntry | undefined = leaf;\n\twhile (current) {\n\t\tpath.push(current);\n\t\tcurrent = current.parentId ? index.get(current.parentId) : undefined;\n\t}\n\tpath.reverse();\n\treturn path;\n}\n\nfunction getSessionContextSettings(path: SessionEntry[]): Pick<SessionContext, \"thinkingLevel\" | \"model\"> {\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\n\tfor (const entry of path) {\n\t\tif (entry.type === \"thinking_level_change\") {\n\t\t\tthinkingLevel = entry.thinkingLevel;\n\t\t} else if (entry.type === \"model_change\") {\n\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tmodel = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t}\n\t}\n\n\treturn { thinkingLevel, model };\n}\n\n/**\n * Project one selected session entry into LLM/runtime messages.\n * Plain custom entries are display/state entries and do not participate in context.\n */\nexport function sessionEntryToContextMessages(entry: SessionEntry): AgentMessage[] {\n\tif (entry.type === \"message\") {\n\t\tconst message = entry.message;\n\t\t// Session files are parsed without validation; old versions, forks, or\n\t\t// hand-edited files can contain messages with null/missing content.\n\t\tif (\n\t\t\t(message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") &&\n\t\t\tmessage.content == null\n\t\t) {\n\t\t\treturn [{ ...message, content: [] }];\n\t\t}\n\t\treturn [message];\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn [\n\t\t\tcreateCustomMessage(entry.customType, entry.content ?? [], entry.display, entry.details, entry.timestamp),\n\t\t];\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)];\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn [createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)];\n\t}\n\treturn [];\n}\n\n/**\n * Build the active, compaction-aware session entry list.\n *\n * This follows the current leaf path. If the path contains compaction entries,\n * the latest compaction is represented by the compaction entry itself, followed\n * by the kept entries starting at firstKeptEntryId and all entries after the\n * compaction entry. Older summarized entries are omitted.\n */\nexport function buildContextEntries(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionEntry[] {\n\tconst path = buildSessionPath(entries, leafId, byId);\n\tlet compaction: CompactionEntry | null = null;\n\n\tfor (const entry of path) {\n\t\tif (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\n\tif (!compaction) {\n\t\treturn path;\n\t}\n\n\tconst compactionIdx = path.findIndex((entry) => entry.id === compaction.id);\n\tif (compactionIdx < 0) {\n\t\treturn path;\n\t}\n\n\tconst contextEntries: SessionEntry[] = [compaction];\n\tlet foundFirstKept = false;\n\tfor (let i = 0; i < compactionIdx; i++) {\n\t\tconst entry = path[i];\n\t\tif (entry.id === compaction.firstKeptEntryId) {\n\t\t\tfoundFirstKept = true;\n\t\t}\n\t\tif (foundFirstKept) {\n\t\t\tcontextEntries.push(entry);\n\t\t}\n\t}\n\tcontextEntries.push(...path.slice(compactionIdx + 1));\n\treturn contextEntries;\n}\n\n/**\n * Build the session context from entries using tree traversal.\n * If leafId is provided, walks from that entry to root.\n * Handles compaction and branch summaries along the path.\n */\nexport function buildSessionContext(\n\tentries: SessionEntry[],\n\tleafId?: string | null,\n\tbyId?: Map<string, SessionEntry>,\n): SessionContext {\n\tconst path = buildSessionPath(entries, leafId, byId);\n\tconst { thinkingLevel, model } = getSessionContextSettings(path);\n\tconst messages = buildContextEntries(entries, leafId, byId).flatMap(sessionEntryToContextMessages);\n\treturn { messages, thinkingLevel, model };\n}\n\n/**\n * Compute the default session directory for a cwd.\n * Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.\n */\nfunction getDefaultSessionDirPath(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst resolvedCwd = resolvePath(cwd);\n\tconst resolvedAgentDir = resolvePath(agentDir);\n\tconst safePath = `--${resolvedCwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\treturn join(resolvedAgentDir, \"sessions\", safePath);\n}\n\nexport function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst sessionDir = getDefaultSessionDirPath(cwd, agentDir);\n\tif (!existsSync(sessionDir)) {\n\t\tmkdirSync(sessionDir, { recursive: true });\n\t}\n\treturn sessionDir;\n}\n\nconst SESSION_READ_BUFFER_SIZE = 1024 * 1024;\nconst SESSION_HEADER_READ_BUFFER_SIZE = 4096;\n/** Bound synchronous header discovery while allowing large cwd and custom metadata fields. */\nconst MAX_SESSION_HEADER_SCAN_BYTES = 1024 * 1024;\n\nclass SessionHeaderScanLimitError extends Error {\n\tconstructor(filePath: string) {\n\t\tsuper(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`);\n\t\tthis.name = \"SessionHeaderScanLimitError\";\n\t}\n}\n\nfunction parseSessionEntryLine(line: string): FileEntry | null {\n\tif (!line.trim()) return null;\n\ttry {\n\t\treturn JSON.parse(line) as FileEntry;\n\t} catch {\n\t\t// Skip malformed lines\n\t\treturn null;\n\t}\n}\n\n/** Exported for testing */\nexport function loadEntriesFromFile(filePath: string): FileEntry[] {\n\tconst resolvedFilePath = normalizePath(filePath);\n\tif (!existsSync(resolvedFilePath)) return [];\n\n\tconst entries: FileEntry[] = [];\n\tconst fd = openSync(resolvedFilePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);\n\t\tlet pending = \"\";\n\n\t\twhile (true) {\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, buffer.length, null);\n\t\t\tif (bytesRead === 0) break;\n\n\t\t\tpending += decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tconst entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));\n\t\t\t\tif (entry) entries.push(entry);\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tpending = pending.slice(lineStart);\n\t\t}\n\n\t\tpending += decoder.end();\n\t\tconst finalEntry = parseSessionEntryLine(pending);\n\t\tif (finalEntry) entries.push(finalEntry);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\t// Validate session header\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as { id?: unknown }).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\n/**\n * Inspect a physical line while searching for the first parsed session entry.\n * Blank and malformed lines are skipped to match loadEntriesFromFile().\n * Returns undefined to keep scanning, null for a parsed non-header entry, or the header.\n */\nfunction parseSessionHeaderCandidate(line: string): SessionHeader | null | undefined {\n\tif (!line.trim()) return undefined;\n\tconst entry = parseSessionEntryLine(line);\n\tif (!entry) return undefined;\n\tif (entry.type !== \"session\" || typeof (entry as { id?: unknown }).id !== \"string\") return null;\n\treturn entry;\n}\n\nfunction readSessionHeader(filePath: string): SessionHeader | null {\n\tconst fd = openSync(filePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE);\n\t\tconst lineChunks: string[] = [];\n\t\tlet scannedBytes = 0;\n\n\t\twhile (scannedBytes < MAX_SESSION_HEADER_SCAN_BYTES) {\n\t\t\tconst readLength = Math.min(buffer.length, MAX_SESSION_HEADER_SCAN_BYTES - scannedBytes);\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, readLength, null);\n\t\t\tif (bytesRead === 0) {\n\t\t\t\tlineChunks.push(decoder.end());\n\t\t\t\treturn parseSessionHeaderCandidate(lineChunks.join(\"\")) ?? null;\n\t\t\t}\n\t\t\tscannedBytes += bytesRead;\n\n\t\t\tconst chunk = decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = chunk.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tlineChunks.push(chunk.slice(lineStart, newlineIndex));\n\t\t\t\tconst header = parseSessionHeaderCandidate(lineChunks.join(\"\"));\n\t\t\t\tif (header !== undefined) return header;\n\t\t\t\tlineChunks.length = 0;\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = chunk.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tlineChunks.push(chunk.slice(lineStart));\n\t\t}\n\n\t\t// Probe for EOF so a final header without a newline is allowed when it ends\n\t\t// exactly at the scan limit. Any additional byte exceeds the bounded scan.\n\t\tconst probe = Buffer.allocUnsafe(1);\n\t\tif (readSync(fd, probe, 0, probe.length, null) === 0) {\n\t\t\tlineChunks.push(decoder.end());\n\t\t\treturn parseSessionHeaderCandidate(lineChunks.join(\"\")) ?? null;\n\t\t}\n\t\tthrow new SessionHeaderScanLimitError(filePath);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n}\n\nfunction readSessionHeaderForDiscovery(filePath: string): SessionHeader | null {\n\ttry {\n\t\treturn readSessionHeader(filePath);\n\t} catch {\n\t\t// Discovery is best-effort: unreadable or oversized files are not sessions,\n\t\t// and one corrupt file must not prevent other sessions from being found.\n\t\treturn null;\n\t}\n}\n\nfunction getSessionHeaderCwd(header: SessionHeader): string | undefined {\n\tconst cwd = (header as { cwd?: unknown }).cwd;\n\treturn typeof cwd === \"string\" ? cwd : undefined;\n}\n\nfunction sessionCwdMatches(cwd: string | undefined, resolvedCwd: string): boolean {\n\treturn cwd !== undefined && cwd !== \"\" && resolvePath(cwd) === resolvedCwd;\n}\n\n/** Exported for testing */\nexport function findMostRecentSession(sessionDir: string, cwd?: string): string | null {\n\tconst resolvedSessionDir = normalizePath(sessionDir);\n\tconst resolvedCwd = cwd ? resolvePath(cwd) : undefined;\n\ttry {\n\t\tconst files = readdirSync(resolvedSessionDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(resolvedSessionDir, f))\n\t\t\t.map((path) => ({ path, header: readSessionHeaderForDiscovery(path) }))\n\t\t\t.filter(\n\t\t\t\t(file): file is { path: string; header: SessionHeader } =>\n\t\t\t\t\tfile.header !== null &&\n\t\t\t\t\t(!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd)),\n\t\t\t)\n\t\t\t.map(({ path }) => ({ path, mtime: statSync(path).mtime }))\n\t\t\t.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n\t\treturn files[0]?.path || null;\n\t} catch {\n\t\t// Directory access and stat races make recent-session discovery unavailable.\n\t\treturn null;\n\t}\n}\n\nfunction isMessageWithContent(message: AgentMessage): message is Message {\n\treturn typeof (message as Message).role === \"string\" && \"content\" in message;\n}\n\nfunction extractTextContent(message: Message): string {\n\tconst content = message.content;\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\" \");\n}\n\nfunction getMessageActivityTime(entry: SessionMessageEntry): number | undefined {\n\tconst message = entry.message;\n\tif (!isMessageWithContent(message)) return undefined;\n\tif (message.role !== \"user\" && message.role !== \"assistant\") return undefined;\n\n\tconst msgTimestamp = (message as { timestamp?: number }).timestamp;\n\tif (typeof msgTimestamp === \"number\") {\n\t\treturn msgTimestamp;\n\t}\n\n\tconst t = new Date(entry.timestamp).getTime();\n\treturn Number.isNaN(t) ? undefined : t;\n}\n\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst stats = await stat(filePath);\n\t\tlet header: SessionHeader | null = null;\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\t\tlet name: string | undefined;\n\t\tlet lastActivityTime: number | undefined;\n\n\t\tconst rl = createInterface({\n\t\t\tinput: createReadStream(filePath, { encoding: \"utf8\" }),\n\t\t\tcrlfDelay: Infinity,\n\t\t});\n\n\t\tfor await (const line of rl) {\n\t\t\tconst entry = parseSessionEntryLine(line);\n\t\t\tif (!entry) continue;\n\n\t\t\tif (!header) {\n\t\t\t\tif (entry.type !== \"session\") return null;\n\t\t\t\theader = entry;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Extract session name (use latest, including explicit clears)\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\tname = entry.name?.trim() || undefined;\n\t\t\t}\n\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst activityTime = getMessageActivityTime(entry);\n\t\t\tif (typeof activityTime === \"number\") {\n\t\t\t\tlastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);\n\t\t\t}\n\n\t\t\tconst message = entry.message;\n\t\t\tif (!isMessageWithContent(message)) continue;\n\t\t\tif (message.role !== \"user\" && message.role !== \"assistant\") continue;\n\n\t\t\tconst textContent = extractTextContent(message);\n\t\t\tif (!textContent) continue;\n\n\t\t\tallMessages.push(textContent);\n\t\t\tif (!firstMessage && message.role === \"user\") {\n\t\t\t\tfirstMessage = textContent;\n\t\t\t}\n\t\t}\n\n\t\tif (!header) return null;\n\n\t\tconst cwd = typeof header.cwd === \"string\" ? header.cwd : \"\";\n\t\tconst parentSessionPath = header.parentSession;\n\t\tconst headerTime = typeof header.timestamp === \"string\" ? new Date(header.timestamp).getTime() : NaN;\n\t\tconst modified =\n\t\t\ttypeof lastActivityTime === \"number\" && lastActivityTime > 0\n\t\t\t\t? new Date(lastActivityTime)\n\t\t\t\t: !Number.isNaN(headerTime)\n\t\t\t\t\t? new Date(headerTime)\n\t\t\t\t\t: stats.mtime;\n\n\t\treturn {\n\t\t\tpath: filePath,\n\t\t\tid: header.id,\n\t\t\tcwd,\n\t\t\tname,\n\t\t\tparentSessionPath,\n\t\t\tcreated: new Date(header.timestamp),\n\t\t\tmodified,\n\t\t\tmessageCount,\n\t\t\tfirstMessage: firstMessage || \"(no messages)\",\n\t\t\tallMessagesText: allMessages.join(\" \"),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport type SessionListProgress = (loaded: number, total: number) => void;\n\nconst MAX_CONCURRENT_SESSION_INFO_LOADS = 10;\n\nasync function buildSessionInfosWithConcurrency(\n\tfiles: string[],\n\tonLoaded: () => void,\n): Promise<(SessionInfo | null)[]> {\n\tconst results: (SessionInfo | null)[] = new Array(files.length).fill(null);\n\tconst inFlight = new Set<Promise<void>>();\n\tlet nextIndex = 0;\n\n\tconst startNext = (): void => {\n\t\tconst index = nextIndex++;\n\t\tconst file = files[index];\n\t\tif (!file) return;\n\n\t\tlet task: Promise<void>;\n\t\ttask = buildSessionInfo(file)\n\t\t\t.then((info) => {\n\t\t\t\tresults[index] = info;\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tresults[index] = null;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(task);\n\t\t\t\tonLoaded();\n\t\t\t});\n\t\tinFlight.add(task);\n\t};\n\n\twhile (nextIndex < files.length || inFlight.size > 0) {\n\t\twhile (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {\n\t\t\tstartNext();\n\t\t}\n\t\tif (inFlight.size > 0) {\n\t\t\tawait Promise.race(inFlight);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nasync function listSessionsFromDir(\n\tdir: string,\n\tonProgress?: SessionListProgress,\n\tprogressOffset = 0,\n\tprogressTotal?: number,\n): Promise<SessionInfo[]> {\n\tconst sessions: SessionInfo[] = [];\n\tif (!existsSync(dir)) {\n\t\treturn sessions;\n\t}\n\n\ttry {\n\t\tconst dirEntries = await readdir(dir);\n\t\tconst files = dirEntries.filter((f) => f.endsWith(\".jsonl\")).map((f) => join(dir, f));\n\t\tconst total = progressTotal ?? files.length;\n\n\t\tlet loaded = 0;\n\t\tconst results = await buildSessionInfosWithConcurrency(files, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(progressOffset + loaded, total);\n\t\t});\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Return empty list on error\n\t}\n\n\treturn sessions;\n}\n\n/**\n * Manages conversation sessions as append-only trees stored in JSONL files.\n *\n * Each session entry has an id and parentId forming a tree structure. The \"leaf\"\n * pointer tracks the current position. Appending creates a child of the current leaf.\n * Branching moves the leaf to an earlier entry, allowing new branches without\n * modifying history.\n *\n * Use buildSessionContext() to get the resolved message list for the LLM, which\n * handles compaction summaries and follows the path from root to current leaf.\n */\nexport class SessionManager {\n\tprivate sessionId: string = \"\";\n\tprivate sessionFile: string | undefined;\n\tprivate sessionDir: string;\n\tprivate cwd: string;\n\tprivate persist: boolean;\n\tprivate flushed: boolean = false;\n\tprivate fileEntries: FileEntry[] = [];\n\tprivate byId: Map<string, SessionEntry> = new Map();\n\tprivate labelsById: Map<string, string> = new Map();\n\tprivate labelTimestampsById: Map<string, string> = new Map();\n\tprivate leafId: string | null = null;\n\n\tprivate constructor(\n\t\tcwd: string,\n\t\tsessionDir: string,\n\t\tsessionFile: string | undefined,\n\t\tpersist: boolean,\n\t\tnewSessionOptions?: NewSessionOptions,\n\t\tpreloadedFileEntries?: FileEntry[],\n\t) {\n\t\tthis.cwd = resolvePath(cwd);\n\t\tthis.sessionDir = normalizePath(sessionDir);\n\t\tthis.persist = persist;\n\t\tif (persist && this.sessionDir && !existsSync(this.sessionDir)) {\n\t\t\tmkdirSync(this.sessionDir, { recursive: true });\n\t\t}\n\n\t\tif (sessionFile) {\n\t\t\tthis._setSessionFile(sessionFile, preloadedFileEntries);\n\t\t} else {\n\t\t\tthis.newSession(newSessionOptions);\n\t\t}\n\t}\n\n\t/** Switch to a different session file (used for resume and branching) */\n\tsetSessionFile(sessionFile: string): void {\n\t\tthis._setSessionFile(sessionFile);\n\t}\n\n\tprivate _setSessionFile(sessionFile: string, preloadedFileEntries?: FileEntry[]): void {\n\t\tthis.sessionFile = resolvePath(sessionFile);\n\t\tif (existsSync(this.sessionFile)) {\n\t\t\tthis.fileEntries = preloadedFileEntries ?? loadEntriesFromFile(this.sessionFile);\n\n\t\t\t// If file was empty, initialize it with a valid session header. If it was\n\t\t\t// non-empty but did not parse as a pi session, fail without modifying it.\n\t\t\tif (this.fileEntries.length === 0) {\n\t\t\t\tconst explicitPath = this.sessionFile;\n\t\t\t\tif (statSync(explicitPath).size > 0) {\n\t\t\t\t\tthrow new Error(`Session file is not a valid pi session: ${explicitPath}`);\n\t\t\t\t}\n\t\t\t\tthis.newSession();\n\t\t\t\tthis.sessionFile = explicitPath;\n\t\t\t\tthis._rewriteFile();\n\t\t\t\tthis.flushed = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst header = this.fileEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\t\tthis.sessionId = header?.id ?? createSessionId();\n\n\t\t\tif (migrateToCurrentVersion(this.fileEntries)) {\n\t\t\t\tthis._rewriteFile();\n\t\t\t}\n\n\t\t\tthis._buildIndex();\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tconst explicitPath = this.sessionFile;\n\t\t\tthis.newSession();\n\t\t\tthis.sessionFile = explicitPath; // preserve explicit path from --session flag\n\t\t}\n\t}\n\n\tnewSession(options?: NewSessionOptions): string | undefined {\n\t\tif (options?.id !== undefined) {\n\t\t\tassertValidSessionId(options.id);\n\t\t}\n\t\tthis.sessionId = options?.id ?? createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: this.sessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession: options?.parentSession,\n\t\t};\n\t\tthis.fileEntries = [header];\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tthis.flushed = false;\n\n\t\tif (this.persist) {\n\t\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\t\tthis.sessionFile = join(this.getSessionDir(), `${fileTimestamp}_${this.sessionId}.jsonl`);\n\t\t}\n\t\treturn this.sessionFile;\n\t}\n\n\tprivate _buildIndex(): void {\n\t\tthis.byId.clear();\n\t\tthis.labelsById.clear();\n\t\tthis.labelTimestampsById.clear();\n\t\tthis.leafId = null;\n\t\tfor (const entry of this.fileEntries) {\n\t\t\tif (entry.type === \"session\") continue;\n\t\t\tthis.byId.set(entry.id, entry);\n\t\t\tthis.leafId = entry.id;\n\t\t\tif (entry.type === \"label\") {\n\t\t\t\tif (entry.label) {\n\t\t\t\t\tthis.labelsById.set(entry.targetId, entry.label);\n\t\t\t\t\tthis.labelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t\t\t} else {\n\t\t\t\t\tthis.labelsById.delete(entry.targetId);\n\t\t\t\t\tthis.labelTimestampsById.delete(entry.targetId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rewriteFile(): void {\n\t\tif (!this.persist || !this.sessionFile) return;\n\t\tconst fd = openSync(this.sessionFile, \"w\");\n\t\ttry {\n\t\t\tfor (const entry of this.fileEntries) {\n\t\t\t\twriteFileSync(fd, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t} finally {\n\t\t\tcloseSync(fd);\n\t\t}\n\t}\n\n\tisPersisted(): boolean {\n\t\treturn this.persist;\n\t}\n\n\tgetCwd(): string {\n\t\treturn this.cwd;\n\t}\n\n\tgetSessionDir(): string {\n\t\treturn this.sessionDir;\n\t}\n\n\tusesDefaultSessionDir(): boolean {\n\t\treturn this.sessionDir === getDefaultSessionDirPath(this.cwd);\n\t}\n\n\tgetSessionId(): string {\n\t\treturn this.sessionId;\n\t}\n\n\tgetSessionFile(): string | undefined {\n\t\treturn this.sessionFile;\n\t}\n\n\t_persist(entry: SessionEntry): void {\n\t\tif (!this.persist || !this.sessionFile) return;\n\n\t\tconst hasAssistant = this.fileEntries.some((e) => e.type === \"message\" && e.message.role === \"assistant\");\n\t\tif (!hasAssistant) {\n\t\t\tif (this.flushed) {\n\t\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t} else {\n\t\t\t\t// Mark as not flushed so when assistant arrives, all entries get written\n\t\t\t\tthis.flushed = false;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.flushed) {\n\t\t\tconst fd = openSync(this.sessionFile, \"wx\");\n\t\t\ttry {\n\t\t\t\tfor (const e of this.fileEntries) {\n\t\t\t\t\twriteFileSync(fd, `${JSON.stringify(e)}\\n`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tcloseSync(fd);\n\t\t\t}\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t}\n\t}\n\n\tprivate _appendEntry(entry: SessionEntry): void {\n\t\tthis.fileEntries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tthis.leafId = entry.id;\n\t\tthis._persist(entry);\n\t}\n\n\t/** Append a message as child of current leaf, then advance leaf. Returns entry id.\n\t * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.\n\t * Reason: we want these to be top-level entries in the session, not message session entries,\n\t * so it is easier to find them.\n\t * These need to be appended via appendCompaction() and appendBranchSummary() methods.\n\t */\n\tappendMessage(message: Message | CustomMessage | BashExecutionMessage): string {\n\t\tconst entry: SessionMessageEntry = {\n\t\t\ttype: \"message\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmessage,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendThinkingLevelChange(thinkingLevel: string): string {\n\t\tconst entry: ThinkingLevelChangeEntry = {\n\t\t\ttype: \"thinking_level_change\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tthinkingLevel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a model change as child of current leaf, then advance leaf. Returns entry id. */\n\tappendModelChange(provider: string, modelId: string): string {\n\t\tconst entry: ModelChangeEntry = {\n\t\t\ttype: \"model_change\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t): string {\n\t\tconst entry: CompactionEntry<T> = {\n\t\t\ttype: \"compaction\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId,\n\t\t\ttokensBefore,\n\t\t\tdetails,\n\t\t\tusage,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */\n\tappendCustomEntry(customType: string, data?: unknown): string {\n\t\tconst entry: CustomEntry = {\n\t\t\ttype: \"custom\",\n\t\t\tcustomType,\n\t\t\tdata,\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Append a session info entry (e.g., display name). Returns entry id. */\n\tappendSessionInfo(name: string): string {\n\t\tconst sanitizedName = name.replace(/[\\r\\n]+/g, \" \").trim();\n\t\tconst entry: SessionInfoEntry = {\n\t\t\ttype: \"session_info\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tname: sanitizedName,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/** Get the current session name from the latest session_info entry, if any. */\n\tgetSessionName(): string | undefined {\n\t\t// Walk entries in reverse to find the latest session_info entry.\n\t\t// Empty names explicitly clear the session title.\n\t\tconst entries = this.getEntries();\n\t\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\t\tconst entry = entries[i];\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\treturn entry.name?.trim() || undefined;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Append a custom message entry (for extensions) that participates in LLM context.\n\t * @param customType Extension identifier for filtering on reload\n\t * @param content Message content (string or TextContent/ImageContent array)\n\t * @param display Whether to show in TUI (true = styled display, false = hidden)\n\t * @param details Optional extension-specific metadata (not sent to LLM)\n\t * @returns Entry id\n\t */\n\tappendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): string {\n\t\tconst entry: CustomMessageEntry<T> = {\n\t\t\ttype: \"custom_message\",\n\t\t\tcustomType,\n\t\t\tcontent,\n\t\t\tdisplay,\n\t\t\tdetails,\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t// =========================================================================\n\t// Tree Traversal\n\t// =========================================================================\n\n\tgetLeafId(): string | null {\n\t\treturn this.leafId;\n\t}\n\n\tgetLeafEntry(): SessionEntry | undefined {\n\t\treturn this.leafId ? this.byId.get(this.leafId) : undefined;\n\t}\n\n\tgetEntry(id: string): SessionEntry | undefined {\n\t\treturn this.byId.get(id);\n\t}\n\n\t/**\n\t * Get all direct children of an entry.\n\t */\n\tgetChildren(parentId: string): SessionEntry[] {\n\t\tconst children: SessionEntry[] = [];\n\t\tfor (const entry of this.byId.values()) {\n\t\t\tif (entry.parentId === parentId) {\n\t\t\t\tchildren.push(entry);\n\t\t\t}\n\t\t}\n\t\treturn children;\n\t}\n\n\t/**\n\t * Get the label for an entry, if any.\n\t */\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\t/**\n\t * Set or clear a label on an entry.\n\t * Labels are user-defined markers for bookmarking/navigation.\n\t * Pass undefined or empty string to clear the label.\n\t */\n\tappendLabelChange(targetId: string, label: string | undefined): string {\n\t\tif (!this.byId.has(targetId)) {\n\t\t\tthrow new Error(`Entry ${targetId} not found`);\n\t\t}\n\t\tconst entry: LabelEntry = {\n\t\t\ttype: \"label\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: this.leafId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttargetId,\n\t\t\tlabel,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\tif (label) {\n\t\t\tthis.labelsById.set(targetId, label);\n\t\t\tthis.labelTimestampsById.set(targetId, entry.timestamp);\n\t\t} else {\n\t\t\tthis.labelsById.delete(targetId);\n\t\t\tthis.labelTimestampsById.delete(targetId);\n\t\t}\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Walk from entry to root, returning all entries in path order.\n\t * Includes all entry types (messages, compaction, model changes, etc.).\n\t * Use buildSessionContext() to get the resolved messages for the LLM.\n\t */\n\tgetBranch(fromId?: string): SessionEntry[] {\n\t\tconst path: SessionEntry[] = [];\n\t\tconst startId = fromId ?? this.leafId;\n\t\tlet current = startId ? this.byId.get(startId) : undefined;\n\t\twhile (current) {\n\t\t\tpath.push(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\tpath.reverse();\n\t\treturn path;\n\t}\n\n\t/**\n\t * Build the active, compaction-aware entry list for context/rendering.\n\t * Uses tree traversal from current leaf.\n\t */\n\tbuildContextEntries(): SessionEntry[] {\n\t\treturn buildContextEntries(this.getEntries(), this.leafId, this.byId);\n\t}\n\n\t/**\n\t * Build the session context (what gets sent to the LLM).\n\t * Uses tree traversal from current leaf.\n\t */\n\tbuildSessionContext(): SessionContext {\n\t\treturn buildSessionContext(this.getEntries(), this.leafId, this.byId);\n\t}\n\n\t/**\n\t * Get session header.\n\t */\n\tgetHeader(): SessionHeader | null {\n\t\tconst h = this.fileEntries.find((e) => e.type === \"session\");\n\t\treturn h ? (h as SessionHeader) : null;\n\t}\n\n\t/**\n\t * Get all session entries (excludes header). Returns a shallow copy.\n\t * The session is append-only: use appendXXX() to add entries, branch() to\n\t * change the leaf pointer. Entries cannot be modified or deleted.\n\t */\n\tgetEntries(): SessionEntry[] {\n\t\treturn this.fileEntries.filter((e): e is SessionEntry => e.type !== \"session\");\n\t}\n\n\t/**\n\t * Get the session as a tree structure. Returns a shallow defensive copy of all entries.\n\t * A well-formed session has exactly one root (first entry with parentId === null).\n\t * Orphaned entries (broken parent chain) are also returned as roots.\n\t */\n\tgetTree(): SessionTreeNode[] {\n\t\tconst entries = this.getEntries();\n\t\tconst nodeMap = new Map<string, SessionTreeNode>();\n\t\tconst roots: SessionTreeNode[] = [];\n\n\t\t// Create nodes with resolved labels\n\t\tfor (const entry of entries) {\n\t\t\tconst label = this.labelsById.get(entry.id);\n\t\t\tconst labelTimestamp = this.labelTimestampsById.get(entry.id);\n\t\t\tnodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });\n\t\t}\n\n\t\t// Build tree\n\t\tfor (const entry of entries) {\n\t\t\tconst node = nodeMap.get(entry.id)!;\n\t\t\tif (entry.parentId === null || entry.parentId === entry.id) {\n\t\t\t\troots.push(node);\n\t\t\t} else {\n\t\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\t\tif (parent) {\n\t\t\t\t\tparent.children.push(node);\n\t\t\t\t} else {\n\t\t\t\t\t// Orphan - treat as root\n\t\t\t\t\troots.push(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Sort children by timestamp (oldest first, newest at bottom)\n\t\t// Use iterative approach to avoid stack overflow on deep trees\n\t\tconst stack: SessionTreeNode[] = [...roots];\n\t\twhile (stack.length > 0) {\n\t\t\tconst node = stack.pop()!;\n\t\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\t\tstack.push(...node.children);\n\t\t}\n\n\t\treturn roots;\n\t}\n\n\t// =========================================================================\n\t// Branching\n\t// =========================================================================\n\n\t/**\n\t * Start a new branch from an earlier entry.\n\t * Moves the leaf pointer to the specified entry. The next appendXXX() call\n\t * will create a child of that entry, forming a new branch. Existing entries\n\t * are not modified or deleted.\n\t */\n\tbranch(branchFromId: string): void {\n\t\tif (!this.byId.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.leafId = branchFromId;\n\t}\n\n\t/**\n\t * Reset the leaf pointer to null (before any entries).\n\t * The next appendXXX() call will create a new root entry (parentId = null).\n\t * Use this when navigating to re-edit the first user message.\n\t */\n\tresetLeaf(): void {\n\t\tthis.leafId = null;\n\t}\n\n\t/**\n\t * Start a new branch with a summary of the abandoned path.\n\t * Same as branch(), but also appends a branch_summary entry that captures\n\t * context from the abandoned conversation path.\n\t */\n\tbranchWithSummary(\n\t\tbranchFromId: string | null,\n\t\tsummary: string,\n\t\tdetails?: unknown,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t): string {\n\t\tif (branchFromId !== null && !this.byId.has(branchFromId)) {\n\t\t\tthrow new Error(`Entry ${branchFromId} not found`);\n\t\t}\n\t\tthis.leafId = branchFromId;\n\t\tconst entry: BranchSummaryEntry = {\n\t\t\ttype: \"branch_summary\",\n\t\t\tid: generateId(this.byId),\n\t\t\tparentId: branchFromId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tfromId: branchFromId ?? \"root\",\n\t\t\tsummary,\n\t\t\tdetails,\n\t\t\tusage,\n\t\t\tfromHook,\n\t\t};\n\t\tthis._appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\t/**\n\t * Create a new session file containing only the path from root to the specified leaf.\n\t * Useful for extracting a single conversation path from a branched session.\n\t * Returns the new session file path, or undefined if not persisting.\n\t */\n\tcreateBranchedSession(leafId: string): string | undefined {\n\t\tconst previousSessionFile = this.sessionFile;\n\t\tconst path = this.getBranch(leafId);\n\t\tif (path.length === 0) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\n\t\t// Filter out LabelEntry from path - we'll recreate them from the resolved map.\n\t\t// Because labels are real tree entries, later entries can be children of labels;\n\t\t// removing labels requires re-chaining the retained path to avoid orphaned subtrees.\n\t\tconst pathWithoutLabels: SessionEntry[] = [];\n\t\tlet pathParentId: string | null = null;\n\t\tfor (const entry of path) {\n\t\t\tif (entry.type === \"label\") continue;\n\t\t\tpathWithoutLabels.push({ ...entry, parentId: pathParentId });\n\t\t\tpathParentId = entry.id;\n\t\t}\n\n\t\tconst newSessionId = createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\tconst newSessionFile = join(this.getSessionDir(), `${fileTimestamp}_${newSessionId}.jsonl`);\n\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: newSessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: this.cwd,\n\t\t\tparentSession: this.persist ? previousSessionFile : undefined,\n\t\t};\n\n\t\t// Collect labels for entries in the path\n\t\tconst pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id));\n\t\tconst labelsToWrite: Array<{ targetId: string; label: string; timestamp: string }> = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (pathEntryIds.has(targetId)) {\n\t\t\t\tlabelsToWrite.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId)! });\n\t\t\t}\n\t\t}\n\n\t\tif (this.persist) {\n\t\t\t// Build label entries\n\t\t\tconst lastEntryId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;\n\t\t\tlet parentId = lastEntryId;\n\t\t\tconst labelEntries: LabelEntry[] = [];\n\t\t\tfor (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {\n\t\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\t\ttype: \"label\",\n\t\t\t\t\tid: generateId(new Set(pathEntryIds)),\n\t\t\t\t\tparentId,\n\t\t\t\t\ttimestamp: labelTimestamp,\n\t\t\t\t\ttargetId,\n\t\t\t\t\tlabel,\n\t\t\t\t};\n\t\t\t\tpathEntryIds.add(labelEntry.id);\n\t\t\t\tlabelEntries.push(labelEntry);\n\t\t\t\tparentId = labelEntry.id;\n\t\t\t}\n\n\t\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\t\tthis.sessionId = newSessionId;\n\t\t\tthis.sessionFile = newSessionFile;\n\t\t\tthis._buildIndex();\n\n\t\t\t// Only write the file now if it contains an assistant message.\n\t\t\t// Otherwise defer to _persist(), which creates the file on the\n\t\t\t// first assistant response, matching the newSession() contract\n\t\t\t// and avoiding the duplicate-header bug when _persist()'s\n\t\t\t// no-assistant guard later resets flushed to false.\n\t\t\tconst hasAssistant = this.fileEntries.some((e) => e.type === \"message\" && e.message.role === \"assistant\");\n\t\t\tif (hasAssistant) {\n\t\t\t\tthis._rewriteFile();\n\t\t\t\tthis.flushed = true;\n\t\t\t} else {\n\t\t\t\tthis.flushed = false;\n\t\t\t}\n\n\t\t\treturn newSessionFile;\n\t\t}\n\n\t\t// In-memory mode: replace current session with the path + labels\n\t\tconst labelEntries: LabelEntry[] = [];\n\t\tlet parentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;\n\t\tfor (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {\n\t\t\tconst labelEntry: LabelEntry = {\n\t\t\t\ttype: \"label\",\n\t\t\t\tid: generateId(new Set([...pathEntryIds, ...labelEntries.map((e) => e.id)])),\n\t\t\t\tparentId,\n\t\t\t\ttimestamp: labelTimestamp,\n\t\t\t\ttargetId,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t\tlabelEntries.push(labelEntry);\n\t\t\tparentId = labelEntry.id;\n\t\t}\n\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\tthis.sessionId = newSessionId;\n\t\tthis._buildIndex();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a new session.\n\t * @param cwd Working directory (stored in session header)\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t */\n\tstatic create(cwd: string, sessionDir?: string, options?: NewSessionOptions): SessionManager {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\treturn new SessionManager(cwd, dir, undefined, true, options);\n\t}\n\n\t/**\n\t * Open a specific session file.\n\t * @param path Path to session file\n\t * @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.\n\t * @param cwdOverride Optional cwd override instead of the session header cwd.\n\t */\n\tstatic open(path: string, sessionDir?: string, cwdOverride?: string): SessionManager {\n\t\tconst resolvedPath = resolvePath(path);\n\t\tlet header: SessionHeader | null = null;\n\t\tlet preloadedFileEntries: FileEntry[] | undefined;\n\t\tif (cwdOverride === undefined && existsSync(resolvedPath)) {\n\t\t\ttry {\n\t\t\t\theader = readSessionHeader(resolvedPath);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof SessionHeaderScanLimitError)) throw error;\n\t\t\t\t// The bounded scan is only a discovery optimization. A full load remains\n\t\t\t\t// authoritative for legacy files with very large headers or prefixes.\n\t\t\t\tpreloadedFileEntries = loadEntriesFromFile(resolvedPath);\n\t\t\t\tconst firstEntry = preloadedFileEntries[0];\n\t\t\t\theader = firstEntry?.type === \"session\" ? firstEntry : null;\n\t\t\t}\n\t\t}\n\t\tconst cwd = cwdOverride ?? (header ? getSessionHeaderCwd(header) : undefined) ?? process.cwd();\n\t\t// If no sessionDir provided, derive from file's parent directory\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, \"..\");\n\t\treturn new SessionManager(cwd, dir, resolvedPath, true, undefined, preloadedFileEntries);\n\t}\n\n\t/**\n\t * Continue the most recent session, or create new if none.\n\t * @param cwd Working directory\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t */\n\tstatic continueRecent(cwd: string, sessionDir?: string): SessionManager {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\tconst filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);\n\t\tconst mostRecent = findMostRecentSession(dir, filterCwd ? cwd : undefined);\n\t\tif (mostRecent) {\n\t\t\treturn new SessionManager(cwd, dir, mostRecent, true);\n\t\t}\n\t\treturn new SessionManager(cwd, dir, undefined, true);\n\t}\n\n\t/** Create an in-memory session (no file persistence) */\n\tstatic inMemory(cwd: string = process.cwd(), options?: NewSessionOptions): SessionManager {\n\t\treturn new SessionManager(cwd, \"\", undefined, false, options);\n\t}\n\n\t/**\n\t * Fork a session from another project directory into the current project.\n\t * Creates a new session in the target cwd with the full history from the source session.\n\t * @param sourcePath Path to the source session file\n\t * @param targetCwd Target working directory (where the new session will be stored)\n\t * @param sessionDir Optional session directory. If omitted, uses default for targetCwd.\n\t */\n\tstatic forkFrom(\n\t\tsourcePath: string,\n\t\ttargetCwd: string,\n\t\tsessionDir?: string,\n\t\toptions?: NewSessionOptions,\n\t): SessionManager {\n\t\tconst resolvedSourcePath = resolvePath(sourcePath);\n\t\tconst resolvedTargetCwd = resolvePath(targetCwd);\n\t\tconst sourceEntries = loadEntriesFromFile(resolvedSourcePath);\n\t\tif (sourceEntries.length === 0) {\n\t\t\tthrow new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);\n\t\t}\n\n\t\tconst sourceHeader = sourceEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\tif (!sourceHeader) {\n\t\t\tthrow new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);\n\t\t}\n\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(resolvedTargetCwd);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\n\t\t// Create new session file with new ID but forked content\n\t\tif (options?.id !== undefined) {\n\t\t\tassertValidSessionId(options.id);\n\t\t}\n\t\tconst newSessionId = options?.id ?? createSessionId();\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\t\tconst newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);\n\n\t\t// Write new header pointing to source as parent, with updated cwd\n\t\tconst newHeader: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: CURRENT_SESSION_VERSION,\n\t\t\tid: newSessionId,\n\t\t\ttimestamp,\n\t\t\tcwd: resolvedTargetCwd,\n\t\t\tparentSession: resolvedSourcePath,\n\t\t};\n\t\twriteFileSync(newSessionFile, `${JSON.stringify(newHeader)}\\n`, { flag: \"wx\" });\n\n\t\t// Copy all non-header entries from source\n\t\tfor (const entry of sourceEntries) {\n\t\t\tif (entry.type !== \"session\") {\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\treturn new SessionManager(resolvedTargetCwd, dir, newSessionFile, true);\n\t}\n\n\t/**\n\t * List all sessions for a directory.\n\t * @param cwd Working directory (used to compute default session directory)\n\t * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).\n\t * @param onProgress Optional callback for progress updates (loaded, total)\n\t */\n\tstatic async list(cwd: string, sessionDir?: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\t\tconst dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);\n\t\tconst filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);\n\t\tconst resolvedCwd = resolvePath(cwd);\n\t\tconst sessions = (await listSessionsFromDir(dir, onProgress)).filter(\n\t\t\t(session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd),\n\t\t);\n\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\treturn sessions;\n\t}\n\n\t/**\n\t * List all sessions across all project directories.\n\t * @param onProgress Optional callback for progress updates (loaded, total)\n\t */\n\tstatic async listAll(onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tstatic async listAll(sessionDir?: string, onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tstatic async listAll(\n\t\tsessionDirOrOnProgress?: string | SessionListProgress,\n\t\tonProgress?: SessionListProgress,\n\t): Promise<SessionInfo[]> {\n\t\tconst customSessionDir =\n\t\t\ttypeof sessionDirOrOnProgress === \"string\" ? normalizePath(sessionDirOrOnProgress) : undefined;\n\t\tconst progress = typeof sessionDirOrOnProgress === \"function\" ? sessionDirOrOnProgress : onProgress;\n\t\tif (customSessionDir) {\n\t\t\tconst sessions = await listSessionsFromDir(customSessionDir, progress);\n\t\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\treturn sessions;\n\t\t}\n\n\t\tconst sessionsDir = getSessionsDir();\n\n\t\ttry {\n\t\t\tif (!existsSync(sessionsDir)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tconst entries = await readdir(sessionsDir, { withFileTypes: true });\n\t\t\tconst dirs = entries\n\t\t\t\t.filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n\t\t\t\t.map((entry) => join(sessionsDir, entry.name));\n\n\t\t\t// Count total files first for accurate progress\n\t\t\tlet totalFiles = 0;\n\t\t\tconst dirFiles: string[][] = [];\n\t\t\tfor (const dir of dirs) {\n\t\t\t\ttry {\n\t\t\t\t\tconst files = (await readdir(dir)).filter((f) => f.endsWith(\".jsonl\"));\n\t\t\t\t\tdirFiles.push(files.map((f) => join(dir, f)));\n\t\t\t\t\ttotalFiles += files.length;\n\t\t\t\t} catch {\n\t\t\t\t\tdirFiles.push([]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process all files with progress tracking\n\t\t\tlet loaded = 0;\n\t\t\tconst sessions: SessionInfo[] = [];\n\t\t\tconst allFiles = dirFiles.flat();\n\n\t\t\tconst results = await buildSessionInfosWithConcurrency(allFiles, () => {\n\t\t\t\tloaded++;\n\t\t\t\tprogress?.(loaded, totalFiles);\n\t\t\t});\n\n\t\t\tfor (const info of results) {\n\t\t\t\tif (info) {\n\t\t\t\t\tsessions.push(info);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\t\treturn sessions;\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\n/**\n * Shared truncation utilities for tool outputs.\n *\n * Truncation is based on two independent limits - whichever is hit first wins:\n * - Line limit (default: 2000 lines)\n * - Byte limit (default: 50KB)\n *\n * Never returns partial lines (except bash tail truncation edge case).\n */\n\nexport const DEFAULT_MAX_LINES = 2000;\nexport const DEFAULT_MAX_BYTES = 50 * 1024; // 50KB\nexport const GREP_MAX_LINE_LENGTH = 500; // Max chars per grep match line\n\nexport interface TruncationResult {\n\t/** The truncated content */\n\tcontent: string;\n\t/** Whether truncation occurred */\n\ttruncated: boolean;\n\t/** Which limit was hit: \"lines\", \"bytes\", or null if not truncated */\n\ttruncatedBy: \"lines\" | \"bytes\" | null;\n\t/** Total number of lines in the original content */\n\ttotalLines: number;\n\t/** Total number of bytes in the original content */\n\ttotalBytes: number;\n\t/** Number of complete lines in the truncated output */\n\toutputLines: number;\n\t/** Number of bytes in the truncated output */\n\toutputBytes: number;\n\t/** Whether the last line was partially truncated (only for tail truncation edge case) */\n\tlastLinePartial: boolean;\n\t/** Whether the first line exceeded the byte limit (for head truncation) */\n\tfirstLineExceedsLimit: boolean;\n\t/** The max lines limit that was applied */\n\tmaxLines: number;\n\t/** The max bytes limit that was applied */\n\tmaxBytes: number;\n}\n\nexport interface TruncationOptions {\n\t/** Maximum number of lines (default: 2000) */\n\tmaxLines?: number;\n\t/** Maximum number of bytes (default: 50KB) */\n\tmaxBytes?: number;\n}\n\nfunction splitLinesForCounting(content: string): string[] {\n\tif (content.length === 0) {\n\t\treturn [];\n\t}\n\tconst lines = content.split(\"\\n\");\n\tif (content.endsWith(\"\\n\")) {\n\t\tlines.pop();\n\t}\n\treturn lines;\n}\n\n/**\n * Format bytes as human-readable size.\n */\nexport function formatSize(bytes: number): string {\n\tif (bytes < 1024) {\n\t\treturn `${bytes}B`;\n\t} else if (bytes < 1024 * 1024) {\n\t\treturn `${(bytes / 1024).toFixed(1)}KB`;\n\t} else {\n\t\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n\t}\n}\n\n/**\n * Truncate content from the head (keep first N lines/bytes).\n * Suitable for file reads where you want to see the beginning.\n *\n * Never returns partial lines. If first line exceeds byte limit,\n * returns empty content with firstLineExceedsLimit=true.\n */\nexport function truncateHead(content: string, options: TruncationOptions = {}): TruncationResult {\n\tconst maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\tconst maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\n\tconst totalBytes = Buffer.byteLength(content, \"utf-8\");\n\tconst lines = splitLinesForCounting(content);\n\tconst totalLines = lines.length;\n\n\t// Check if no truncation needed\n\tif (totalLines <= maxLines && totalBytes <= maxBytes) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\ttruncated: false,\n\t\t\ttruncatedBy: null,\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: totalLines,\n\t\t\toutputBytes: totalBytes,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: false,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Check if first line alone exceeds byte limit\n\tconst firstLineBytes = Buffer.byteLength(lines[0], \"utf-8\");\n\tif (firstLineBytes > maxBytes) {\n\t\treturn {\n\t\t\tcontent: \"\",\n\t\t\ttruncated: true,\n\t\t\ttruncatedBy: \"bytes\",\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: 0,\n\t\t\toutputBytes: 0,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: true,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Collect complete lines that fit\n\tconst outputLinesArr: string[] = [];\n\tlet outputBytesCount = 0;\n\tlet truncatedBy: \"lines\" | \"bytes\" = \"lines\";\n\n\tfor (let i = 0; i < lines.length && i < maxLines; i++) {\n\t\tconst line = lines[i];\n\t\tconst lineBytes = Buffer.byteLength(line, \"utf-8\") + (i > 0 ? 1 : 0); // +1 for newline\n\n\t\tif (outputBytesCount + lineBytes > maxBytes) {\n\t\t\ttruncatedBy = \"bytes\";\n\t\t\tbreak;\n\t\t}\n\n\t\toutputLinesArr.push(line);\n\t\toutputBytesCount += lineBytes;\n\t}\n\n\t// If we exited due to line limit\n\tif (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n\t\ttruncatedBy = \"lines\";\n\t}\n\n\tconst outputContent = outputLinesArr.join(\"\\n\");\n\tconst finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n\n\treturn {\n\t\tcontent: outputContent,\n\t\ttruncated: true,\n\t\ttruncatedBy,\n\t\ttotalLines,\n\t\ttotalBytes,\n\t\toutputLines: outputLinesArr.length,\n\t\toutputBytes: finalOutputBytes,\n\t\tlastLinePartial: false,\n\t\tfirstLineExceedsLimit: false,\n\t\tmaxLines,\n\t\tmaxBytes,\n\t};\n}\n\n/**\n * Truncate content from the tail (keep last N lines/bytes).\n * Suitable for bash output where you want to see the end (errors, final results).\n *\n * May return partial first line if the last line of original content exceeds byte limit.\n */\nexport function truncateTail(content: string, options: TruncationOptions = {}): TruncationResult {\n\tconst maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\tconst maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\n\tconst totalBytes = Buffer.byteLength(content, \"utf-8\");\n\tconst lines = splitLinesForCounting(content);\n\tconst totalLines = lines.length;\n\n\t// Check if no truncation needed\n\tif (totalLines <= maxLines && totalBytes <= maxBytes) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\ttruncated: false,\n\t\t\ttruncatedBy: null,\n\t\t\ttotalLines,\n\t\t\ttotalBytes,\n\t\t\toutputLines: totalLines,\n\t\t\toutputBytes: totalBytes,\n\t\t\tlastLinePartial: false,\n\t\t\tfirstLineExceedsLimit: false,\n\t\t\tmaxLines,\n\t\t\tmaxBytes,\n\t\t};\n\t}\n\n\t// Work backwards from the end\n\tconst outputLinesArr: string[] = [];\n\tlet outputBytesCount = 0;\n\tlet truncatedBy: \"lines\" | \"bytes\" = \"lines\";\n\tlet lastLinePartial = false;\n\n\tfor (let i = lines.length - 1; i >= 0 && outputLinesArr.length < maxLines; i--) {\n\t\tconst line = lines[i];\n\t\tconst lineBytes = Buffer.byteLength(line, \"utf-8\") + (outputLinesArr.length > 0 ? 1 : 0); // +1 for newline\n\n\t\tif (outputBytesCount + lineBytes > maxBytes) {\n\t\t\ttruncatedBy = \"bytes\";\n\t\t\t// Edge case: if we haven't added ANY lines yet and this line exceeds maxBytes,\n\t\t\t// take the end of the line (partial)\n\t\t\tif (outputLinesArr.length === 0) {\n\t\t\t\tconst truncatedLine = truncateStringToBytesFromEnd(line, maxBytes);\n\t\t\t\toutputLinesArr.unshift(truncatedLine);\n\t\t\t\toutputBytesCount = Buffer.byteLength(truncatedLine, \"utf-8\");\n\t\t\t\tlastLinePartial = true;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\toutputLinesArr.unshift(line);\n\t\toutputBytesCount += lineBytes;\n\t}\n\n\t// If we exited due to line limit\n\tif (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n\t\ttruncatedBy = \"lines\";\n\t}\n\n\tconst outputContent = outputLinesArr.join(\"\\n\");\n\tconst finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n\n\treturn {\n\t\tcontent: outputContent,\n\t\ttruncated: true,\n\t\ttruncatedBy,\n\t\ttotalLines,\n\t\ttotalBytes,\n\t\toutputLines: outputLinesArr.length,\n\t\toutputBytes: finalOutputBytes,\n\t\tlastLinePartial,\n\t\tfirstLineExceedsLimit: false,\n\t\tmaxLines,\n\t\tmaxBytes,\n\t};\n}\n\n/**\n * Truncate a string to fit within a byte limit (from the end).\n * Handles multi-byte UTF-8 characters correctly.\n */\nfunction truncateStringToBytesFromEnd(str: string, maxBytes: number): string {\n\tconst buf = Buffer.from(str, \"utf-8\");\n\tif (buf.length <= maxBytes) {\n\t\treturn str;\n\t}\n\n\t// Start from the end, skip maxBytes back\n\tlet start = buf.length - maxBytes;\n\n\t// Find a valid UTF-8 boundary (start of a character)\n\twhile (start < buf.length && (buf[start] & 0xc0) === 0x80) {\n\t\tstart++;\n\t}\n\n\treturn buf.slice(start).toString(\"utf-8\");\n}\n\n/**\n * Truncate a single line to max characters, adding [truncated] suffix.\n * Used for grep match lines.\n */\nexport function truncateLine(\n\tline: string,\n\tmaxChars: number = GREP_MAX_LINE_LENGTH,\n): { text: string; wasTruncated: boolean } {\n\tif (line.length <= maxChars) {\n\t\treturn { text: line, wasTruncated: false };\n\t}\n\treturn { text: `${line.slice(0, maxChars)}... [truncated]`, wasTruncated: true };\n}\n","// @ts-nocheck — vendored Pi source; checked upstream under Pi's own tsconfig.\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nconst fileMutationQueues = new Map<string, Promise<void>>();\nlet registrationQueue = Promise.resolve();\n\nfunction isMissingPathError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error.code === \"ENOENT\" || error.code === \"ENOTDIR\")\n\t);\n}\n\nasync function getMutationQueueKey(filePath: string): Promise<string> {\n\tconst resolvedPath = resolve(filePath);\n\ttry {\n\t\treturn await realpath(resolvedPath);\n\t} catch (error) {\n\t\tif (isMissingPathError(error)) {\n\t\t\treturn resolvedPath;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n\tconst registration = registrationQueue.then(async () => {\n\t\tconst key = await getMutationQueueKey(filePath);\n\t\tconst currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n\n\t\tlet releaseNext!: () => void;\n\t\tconst nextQueue = new Promise<void>((resolveQueue) => {\n\t\t\treleaseNext = resolveQueue;\n\t\t});\n\t\tconst chainedQueue = currentQueue.then(() => nextQueue);\n\t\tfileMutationQueues.set(key, chainedQueue);\n\n\t\treturn { key, currentQueue, chainedQueue, releaseNext };\n\t});\n\tregistrationQueue = registration.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\n\tconst { key, currentQueue, chainedQueue, releaseNext } = await registration;\n\tawait currentQueue;\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\treleaseNext();\n\t\tif (fileMutationQueues.get(key) === chainedQueue) {\n\t\t\tfileMutationQueues.delete(key);\n\t\t}\n\t}\n}\n","/**\n * Vendored verbatim from `@earendil-works/pi-coding-agent@0.84.2`\n * (`dist/core/extensions/loader.js` `createExtensionRuntime`).\n *\n * A pure state-container factory with no host dependency. Action methods start\n * as `notInitialized` stubs that the host runner replaces on bind; the pre-bind\n * logic (stale guard, event-bus subscription tracking, queued provider\n * registrations) is real. Extensions such as pi-btw construct one when they\n * assemble a ResourceLoader-shaped `getExtensions()` result, so the symbol must\n * exist and behave exactly as Pi's — an absent export throws\n * \"createExtensionRuntime is not a function\" the moment such an extension runs.\n */\n\ntype Unsubscribe = () => void\n\ninterface RuntimeState {\n staleMessage?: string\n}\n\n/** The extension runtime Pi hands to loaded extensions in its pre-bind shape. */\nexport interface ExtensionRuntime {\n [key: string]: unknown\n flagValues: Map<string, boolean | string>\n pendingProviderRegistrations: Array<{ name: string, config: unknown, extensionPath: string }>\n pendingNativeProviderRegistrations: Array<{ provider: { id: string }, extensionPath: string }>\n}\n\n/**\n * Build a fresh pre-bind extension runtime. Registration methods\n * (`registerProvider`, `trackEventBusSubscription`) work immediately; action\n * methods (`sendMessage`, `getActiveTools`, …) throw until the host runner\n * binds real implementations.\n * @returns the runtime state container consumed by Pi's extension loader.\n */\nexport function createExtensionRuntime(): ExtensionRuntime {\n const notInitialized = (): never => {\n throw new Error('Extension runtime not initialized. Action methods cannot be called during extension loading.')\n }\n const state: RuntimeState = {}\n const eventBusUnsubscribers = new Set<Unsubscribe>()\n const assertActive = (): void => {\n if (state.staleMessage) {\n throw new Error(state.staleMessage)\n }\n }\n const runtime: ExtensionRuntime = {\n sendMessage: notInitialized,\n sendUserMessage: notInitialized,\n appendEntry: notInitialized,\n setSessionName: notInitialized,\n getSessionName: notInitialized,\n setLabel: notInitialized,\n getActiveTools: notInitialized,\n getAllTools: notInitialized,\n setActiveTools: notInitialized,\n // registerTool() is valid during extension load; refresh is only needed post-bind.\n refreshTools: () => {},\n getCommands: notInitialized,\n setModel: () => Promise.reject(new Error('Extension runtime not initialized')),\n getThinkingLevel: notInitialized,\n setThinkingLevel: notInitialized,\n flagValues: new Map<string, boolean | string>(),\n pendingProviderRegistrations: [],\n pendingNativeProviderRegistrations: [],\n assertActive,\n invalidate: (message?: string) => {\n if (state.staleMessage) return\n state.staleMessage = message\n ?? 'This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().'\n for (const unsubscribe of eventBusUnsubscribers) unsubscribe()\n eventBusUnsubscribers.clear()\n },\n trackEventBusSubscription: (unsubscribe: Unsubscribe): Unsubscribe => {\n let active = true\n const trackedUnsubscribe = (): void => {\n if (!active) return\n active = false\n eventBusUnsubscribers.delete(trackedUnsubscribe)\n unsubscribe()\n }\n eventBusUnsubscribers.add(trackedUnsubscribe)\n return trackedUnsubscribe\n },\n // Pre-bind: queue registrations so the host runner can flush them once the\n // model registry is available; a bound runner replaces both with direct calls.\n registerProvider: (name: string, config: unknown, extensionPath = '<unknown>') => {\n runtime.pendingProviderRegistrations.push({ name, config, extensionPath })\n },\n registerNativeProvider: (provider: { id: string }, extensionPath = '<unknown>') => {\n runtime.pendingNativeProviderRegistrations.push({ provider, extensionPath })\n },\n unregisterProvider: (name: string) => {\n runtime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter(r => r.name !== name)\n runtime.pendingNativeProviderRegistrations = runtime.pendingNativeProviderRegistrations.filter(r => r.provider.id !== name)\n },\n }\n return runtime\n}\n","// @ts-nocheck — vendored Pi source (modes/interactive/components/visual-truncate.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared utility for truncating text to visual lines (accounting for line wrapping).\n * Used by both tool-execution.ts and bash-execution.ts for consistent behavior.\n */\nimport { Text } from '../../pi-tui.js';\n/**\n * Truncate text to a maximum number of visual lines (from the end).\n * This accounts for line wrapping based on terminal width.\n *\n * @param text - The text content (may contain newlines)\n * @param maxVisualLines - Maximum number of visual lines to show\n * @param width - Terminal/render width\n * @param paddingX - Horizontal padding for Text component (default 0).\n * Use 0 when result will be placed in a Box (Box adds its own padding).\n * Use 1 when result will be placed in a plain Container.\n * @returns The truncated visual lines and count of skipped lines\n */\nexport function truncateToVisualLines(text, maxVisualLines, width, paddingX = 0) {\n if (!text) {\n return { visualLines: [], skippedCount: 0 };\n }\n // Create a temporary Text component to render and get visual lines\n const tempText = new Text(text, paddingX, 0);\n const allVisualLines = tempText.render(width);\n if (allVisualLines.length <= maxVisualLines) {\n return { visualLines: allVisualLines, skippedCount: 0 };\n }\n // Take the last N visual lines\n const truncatedLines = allVisualLines.slice(-maxVisualLines);\n const skippedCount = allVisualLines.length - maxVisualLines;\n return { visualLines: truncatedLines, skippedCount };\n}\n//# sourceMappingURL=visual-truncate.js.map","// @ts-nocheck — vendored Pi source (utils/child-process.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { spawn as nodeSpawn, spawnSync as nodeSpawnSync, } from \"node:child_process\";\nimport crossSpawn from \"cross-spawn\";\nconst EXIT_STDIO_GRACE_MS = 100;\nexport function spawnProcess(command, args, options) {\n return process.platform === \"win32\" ? crossSpawn(command, args, options) : nodeSpawn(command, args, options);\n}\nexport function spawnProcessSync(command, args, options) {\n return process.platform === \"win32\"\n ? crossSpawn.sync(command, args, options)\n : nodeSpawnSync(command, args, options);\n}\n/**\n * Wait for a child process to terminate without hanging on inherited stdio handles.\n *\n * A short-lived child can `exit` while a detached descendant keeps its stdout/stderr\n * pipe open. We must not resolve and destroy the streams on a fixed deadline measured\n * from `exit`, or output still being written past that deadline is silently lost\n * (earendil-works/pi#5303). Instead, after `exit` we wait for the pipes to fall idle:\n * the grace timer is re-armed on every chunk, so an actively writing descendant keeps\n * us reading, while a quiet inherited handle (e.g. a Windows daemonized descendant\n * that never lets `close` fire) still releases us after the grace elapses.\n */\nexport function waitForChildProcess(child) {\n return new Promise((resolve, reject) => {\n let settled = false;\n let exited = false;\n let exitCode = null;\n let postExitTimer;\n let stdoutEnded = child.stdout === null;\n let stderrEnded = child.stderr === null;\n const cleanup = () => {\n if (postExitTimer) {\n clearTimeout(postExitTimer);\n postExitTimer = undefined;\n }\n child.removeListener(\"error\", onError);\n child.removeListener(\"exit\", onExit);\n child.removeListener(\"close\", onClose);\n child.stdout?.removeListener(\"end\", onStdoutEnd);\n child.stderr?.removeListener(\"end\", onStderrEnd);\n child.stdout?.removeListener(\"data\", onData);\n child.stderr?.removeListener(\"data\", onData);\n };\n const finalize = (code) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n child.stdout?.destroy();\n child.stderr?.destroy();\n resolve(code);\n };\n const maybeFinalizeAfterExit = () => {\n if (!exited || settled)\n return;\n if (stdoutEnded && stderrEnded) {\n finalize(exitCode);\n }\n };\n const armIdleTimer = () => {\n if (postExitTimer)\n clearTimeout(postExitTimer);\n postExitTimer = setTimeout(() => finalize(exitCode), EXIT_STDIO_GRACE_MS);\n };\n const onData = () => {\n // Output is still arriving after exit; defer finalizing so we don't\n // destroy the stream mid-write and truncate the tail.\n if (exited && !settled)\n armIdleTimer();\n };\n const onStdoutEnd = () => {\n stdoutEnded = true;\n maybeFinalizeAfterExit();\n };\n const onStderrEnd = () => {\n stderrEnded = true;\n maybeFinalizeAfterExit();\n };\n const onError = (err) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n reject(err);\n };\n const onExit = (code) => {\n exited = true;\n exitCode = code;\n maybeFinalizeAfterExit();\n if (!settled) {\n armIdleTimer();\n }\n };\n const onClose = (code) => {\n finalize(code);\n };\n child.stdout?.once(\"end\", onStdoutEnd);\n child.stderr?.once(\"end\", onStderrEnd);\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n child.once(\"error\", onError);\n child.once(\"exit\", onExit);\n child.once(\"close\", onClose);\n });\n}\n//# sourceMappingURL=child-process.js.map","// @ts-nocheck — vendored Pi source (utils/shell.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims; getBinDir inlined over the shim getAgentDir\n// (byte-identical to Pi: join(getAgentDir(), \"bin\")). Logic otherwise unchanged.\nimport { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { join as joinBinDir } from \"node:path\";\nimport { getAgentDir as getAgentDirForBin } from '../../pi-coding-agent.js';\nfunction getBinDir() { return joinBinDir(getAgentDirForBin(), \"bin\"); }\n/**\n * Find bash executable on PATH (cross-platform)\n */\nfunction isLegacyWslBashPath(path) {\n const normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n return /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\nfunction getBashShellConfig(shell) {\n return isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\nfunction findBashOnPath() {\n if (process.platform === \"win32\") {\n // Windows: Use 'where' and verify file exists (where can return non-existent paths)\n try {\n const result = spawnSync(\"where\", [\"bash.exe\"], {\n encoding: \"utf-8\",\n timeout: 5000,\n windowsHide: true,\n });\n if (result.status === 0 && result.stdout) {\n const firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n if (firstMatch && existsSync(firstMatch)) {\n return firstMatch;\n }\n }\n }\n catch {\n // Ignore errors\n }\n return null;\n }\n // Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n try {\n const result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n if (result.status === 0 && result.stdout) {\n const firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n if (firstMatch) {\n return firstMatch;\n }\n }\n }\n catch {\n // Ignore errors\n }\n return null;\n}\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath) {\n // 1. Check user-specified shell path\n if (customShellPath) {\n if (existsSync(customShellPath)) {\n return getBashShellConfig(customShellPath);\n }\n throw new Error(`Custom shell path not found: ${customShellPath}`);\n }\n if (process.platform === \"win32\") {\n // 2. Try Git Bash in known locations\n const paths = [];\n const programFiles = process.env.ProgramFiles;\n if (programFiles) {\n paths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n }\n const programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n if (programFilesX86) {\n paths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n }\n for (const path of paths) {\n if (existsSync(path)) {\n return getBashShellConfig(path);\n }\n }\n // 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n const bashOnPath = findBashOnPath();\n if (bashOnPath) {\n return getBashShellConfig(bashOnPath);\n }\n throw new Error(`No bash shell found. Options:\\n` +\n ` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n ` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n \" 3. Set shellPath in settings.json\\n\\n\" +\n `Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`);\n }\n // Unix: try /bin/bash, then bash on PATH, then fallback to sh\n if (existsSync(\"/bin/bash\")) {\n return getBashShellConfig(\"/bin/bash\");\n }\n const bashOnPath = findBashOnPath();\n if (bashOnPath) {\n return getBashShellConfig(bashOnPath);\n }\n return { shell: \"sh\", args: [\"-c\"] };\n}\nexport function getShellEnv() {\n const binDir = getBinDir();\n const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n const currentPath = process.env[pathKey] ?? \"\";\n const pathEntries = currentPath.split(delimiter).filter(Boolean);\n const hasBinDir = pathEntries.includes(binDir);\n const updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n return {\n ...process.env,\n [pathKey]: updatedPath,\n };\n}\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str) {\n // Use Array.from to properly iterate over code points (not code units)\n // This handles surrogate pairs correctly and catches edge cases where\n // codePointAt() might return undefined\n return Array.from(str)\n .filter((char) => {\n // Filter out characters that cause string-width to crash\n // This includes:\n // - Unicode format characters\n // - Lone surrogates (already filtered by Array.from)\n // - Control chars except \\t \\n \\r\n // - Characters with undefined code points\n const code = char.codePointAt(0);\n // Skip if code point is undefined (edge case with invalid strings)\n if (code === undefined)\n return false;\n // Allow tab, newline, carriage return\n if (code === 0x09 || code === 0x0a || code === 0x0d)\n return true;\n // Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0x0d)\n if (code <= 0x1f)\n return false;\n // Filter out Unicode format characters\n if (code >= 0xfff9 && code <= 0xfffb)\n return false;\n return true;\n })\n .join(\"\");\n}\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set();\nexport function trackDetachedChildPid(pid) {\n trackedDetachedChildPids.add(pid);\n}\nexport function untrackDetachedChildPid(pid) {\n trackedDetachedChildPids.delete(pid);\n}\nexport function killTrackedDetachedChildren() {\n for (const pid of trackedDetachedChildPids) {\n killProcessTree(pid);\n }\n trackedDetachedChildPids.clear();\n}\n/**\n * Kill a process and all its children (cross-platform)\n */\nexport function killProcessTree(pid) {\n if (process.platform === \"win32\") {\n // Use taskkill on Windows to kill process tree\n try {\n spawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n stdio: \"ignore\",\n detached: true,\n windowsHide: true,\n });\n }\n catch {\n // Ignore errors if taskkill fails\n }\n }\n else {\n // Use SIGKILL on Unix/Linux/Mac\n try {\n process.kill(-pid, \"SIGKILL\");\n }\n catch {\n // Fallback to killing just the child if process group kill fails\n try {\n process.kill(pid, \"SIGKILL\");\n }\n catch {\n // Process already dead\n }\n }\n }\n}\n//# sourceMappingURL=shell.js.map","// @ts-nocheck — vendored Pi source (core/tools/truncate.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared truncation utilities for tool outputs.\n *\n * Truncation is based on two independent limits - whichever is hit first wins:\n * - Line limit (default: 2000 lines)\n * - Byte limit (default: 50KB)\n *\n * Never returns partial lines (except bash tail truncation edge case).\n */\nexport const DEFAULT_MAX_LINES = 2000;\nexport const DEFAULT_MAX_BYTES = 50 * 1024; // 50KB\nexport const GREP_MAX_LINE_LENGTH = 500; // Max chars per grep match line\nfunction splitLinesForCounting(content) {\n if (content.length === 0) {\n return [];\n }\n const lines = content.split(\"\\n\");\n if (content.endsWith(\"\\n\")) {\n lines.pop();\n }\n return lines;\n}\n/**\n * Format bytes as human-readable size.\n */\nexport function formatSize(bytes) {\n if (bytes < 1024) {\n return `${bytes}B`;\n }\n else if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)}KB`;\n }\n else {\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n }\n}\n/**\n * Truncate content from the head (keep first N lines/bytes).\n * Suitable for file reads where you want to see the beginning.\n *\n * Never returns partial lines. If first line exceeds byte limit,\n * returns empty content with firstLineExceedsLimit=true.\n */\nexport function truncateHead(content, options = {}) {\n const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n const totalBytes = Buffer.byteLength(content, \"utf-8\");\n const lines = splitLinesForCounting(content);\n const totalLines = lines.length;\n // Check if no truncation needed\n if (totalLines <= maxLines && totalBytes <= maxBytes) {\n return {\n content,\n truncated: false,\n truncatedBy: null,\n totalLines,\n totalBytes,\n outputLines: totalLines,\n outputBytes: totalBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n }\n // Check if first line alone exceeds byte limit\n const firstLineBytes = Buffer.byteLength(lines[0], \"utf-8\");\n if (firstLineBytes > maxBytes) {\n return {\n content: \"\",\n truncated: true,\n truncatedBy: \"bytes\",\n totalLines,\n totalBytes,\n outputLines: 0,\n outputBytes: 0,\n lastLinePartial: false,\n firstLineExceedsLimit: true,\n maxLines,\n maxBytes,\n };\n }\n // Collect complete lines that fit\n const outputLinesArr = [];\n let outputBytesCount = 0;\n let truncatedBy = \"lines\";\n for (let i = 0; i < lines.length && i < maxLines; i++) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, \"utf-8\") + (i > 0 ? 1 : 0); // +1 for newline\n if (outputBytesCount + lineBytes > maxBytes) {\n truncatedBy = \"bytes\";\n break;\n }\n outputLinesArr.push(line);\n outputBytesCount += lineBytes;\n }\n // If we exited due to line limit\n if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n truncatedBy = \"lines\";\n }\n const outputContent = outputLinesArr.join(\"\\n\");\n const finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n return {\n content: outputContent,\n truncated: true,\n truncatedBy,\n totalLines,\n totalBytes,\n outputLines: outputLinesArr.length,\n outputBytes: finalOutputBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n}\n/**\n * Truncate content from the tail (keep last N lines/bytes).\n * Suitable for bash output where you want to see the end (errors, final results).\n *\n * May return partial first line if the last line of original content exceeds byte limit.\n */\nexport function truncateTail(content, options = {}) {\n const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n const totalBytes = Buffer.byteLength(content, \"utf-8\");\n const lines = splitLinesForCounting(content);\n const totalLines = lines.length;\n // Check if no truncation needed\n if (totalLines <= maxLines && totalBytes <= maxBytes) {\n return {\n content,\n truncated: false,\n truncatedBy: null,\n totalLines,\n totalBytes,\n outputLines: totalLines,\n outputBytes: totalBytes,\n lastLinePartial: false,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n }\n // Work backwards from the end\n const outputLinesArr = [];\n let outputBytesCount = 0;\n let truncatedBy = \"lines\";\n let lastLinePartial = false;\n for (let i = lines.length - 1; i >= 0 && outputLinesArr.length < maxLines; i--) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, \"utf-8\") + (outputLinesArr.length > 0 ? 1 : 0); // +1 for newline\n if (outputBytesCount + lineBytes > maxBytes) {\n truncatedBy = \"bytes\";\n // Edge case: if we haven't added ANY lines yet and this line exceeds maxBytes,\n // take the end of the line (partial)\n if (outputLinesArr.length === 0) {\n const truncatedLine = truncateStringToBytesFromEnd(line, maxBytes);\n outputLinesArr.unshift(truncatedLine);\n outputBytesCount = Buffer.byteLength(truncatedLine, \"utf-8\");\n lastLinePartial = true;\n }\n break;\n }\n outputLinesArr.unshift(line);\n outputBytesCount += lineBytes;\n }\n // If we exited due to line limit\n if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {\n truncatedBy = \"lines\";\n }\n const outputContent = outputLinesArr.join(\"\\n\");\n const finalOutputBytes = Buffer.byteLength(outputContent, \"utf-8\");\n return {\n content: outputContent,\n truncated: true,\n truncatedBy,\n totalLines,\n totalBytes,\n outputLines: outputLinesArr.length,\n outputBytes: finalOutputBytes,\n lastLinePartial,\n firstLineExceedsLimit: false,\n maxLines,\n maxBytes,\n };\n}\n/**\n * Truncate a string to fit within a byte limit (from the end).\n * Handles multi-byte UTF-8 characters correctly.\n */\nfunction truncateStringToBytesFromEnd(str, maxBytes) {\n const buf = Buffer.from(str, \"utf-8\");\n if (buf.length <= maxBytes) {\n return str;\n }\n // Start from the end, skip maxBytes back\n let start = buf.length - maxBytes;\n // Find a valid UTF-8 boundary (start of a character)\n while (start < buf.length && (buf[start] & 0xc0) === 0x80) {\n start++;\n }\n return buf.slice(start).toString(\"utf-8\");\n}\n/**\n * Truncate a single line to max characters, adding [truncated] suffix.\n * Used for grep match lines.\n */\nexport function truncateLine(line, maxChars = GREP_MAX_LINE_LENGTH) {\n if (line.length <= maxChars) {\n return { text: line, wasTruncated: false };\n }\n return { text: `${line.slice(0, maxChars)}... [truncated]`, wasTruncated: true };\n}\n//# sourceMappingURL=truncate.js.map","// @ts-nocheck — vendored Pi source (core/tools/output-accumulator.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from \"./truncate.js\";\nfunction defaultTempFilePath(prefix) {\n const id = randomBytes(8).toString(\"hex\");\n return join(tmpdir(), `${prefix}-${id}.log`);\n}\nfunction byteLength(text) {\n return Buffer.byteLength(text, \"utf-8\");\n}\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n maxLines;\n maxBytes;\n maxRollingBytes;\n tempFilePrefix;\n decoder = new TextDecoder();\n rawChunks = [];\n tailText = \"\";\n tailBytes = 0;\n tailStartsAtLineBoundary = true;\n totalRawBytes = 0;\n totalDecodedBytes = 0;\n completedLines = 0;\n totalLines = 0;\n currentLineBytes = 0;\n hasOpenLine = false;\n finished = false;\n tempFilePath;\n tempFileStream;\n constructor(options = {}) {\n this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n this.maxRollingBytes = Math.max(this.maxBytes * 2, 1);\n this.tempFilePrefix = options.tempFilePrefix ?? \"pi-output\";\n }\n append(data) {\n if (this.finished) {\n throw new Error(\"Cannot append to a finished output accumulator\");\n }\n this.totalRawBytes += data.length;\n this.appendDecodedText(this.decoder.decode(data, { stream: true }));\n if (this.tempFileStream || this.shouldUseTempFile()) {\n this.ensureTempFile();\n this.tempFileStream?.write(data);\n }\n else if (data.length > 0) {\n this.rawChunks.push(data);\n }\n }\n finish() {\n if (this.finished) {\n return;\n }\n this.finished = true;\n this.appendDecodedText(this.decoder.decode());\n if (this.shouldUseTempFile()) {\n this.ensureTempFile();\n }\n }\n snapshot(options = {}) {\n const tailTruncation = truncateTail(this.getSnapshotText(), {\n maxLines: this.maxLines,\n maxBytes: this.maxBytes,\n });\n const truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n const truncatedBy = truncated\n ? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n : null;\n const truncation = {\n ...tailTruncation,\n truncated,\n truncatedBy,\n totalLines: this.totalLines,\n totalBytes: this.totalDecodedBytes,\n maxLines: this.maxLines,\n maxBytes: this.maxBytes,\n };\n if (options.persistIfTruncated && truncation.truncated) {\n this.ensureTempFile();\n }\n return {\n content: truncation.content,\n truncation,\n fullOutputPath: this.tempFilePath,\n };\n }\n async closeTempFile() {\n if (!this.tempFileStream) {\n return;\n }\n const stream = this.tempFileStream;\n this.tempFileStream = undefined;\n await new Promise((resolve, reject) => {\n const onError = (error) => {\n stream.off(\"finish\", onFinish);\n reject(error);\n };\n const onFinish = () => {\n stream.off(\"error\", onError);\n resolve();\n };\n stream.once(\"error\", onError);\n stream.once(\"finish\", onFinish);\n stream.end();\n });\n }\n getLastLineBytes() {\n return this.currentLineBytes;\n }\n appendDecodedText(text) {\n if (text.length === 0) {\n return;\n }\n const bytes = byteLength(text);\n this.totalDecodedBytes += bytes;\n this.tailText += text;\n this.tailBytes += bytes;\n if (this.tailBytes > this.maxRollingBytes * 2) {\n this.trimTail();\n }\n let newlines = 0;\n let lastNewline = -1;\n for (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n newlines++;\n lastNewline = i;\n }\n if (newlines === 0) {\n this.currentLineBytes += bytes;\n this.hasOpenLine = true;\n }\n else {\n this.completedLines += newlines;\n const tail = text.slice(lastNewline + 1);\n this.currentLineBytes = byteLength(tail);\n this.hasOpenLine = tail.length > 0;\n }\n this.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n }\n trimTail() {\n const buffer = Buffer.from(this.tailText, \"utf-8\");\n if (buffer.length <= this.maxRollingBytes) {\n this.tailBytes = buffer.length;\n return;\n }\n let start = buffer.length - this.maxRollingBytes;\n while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n start++;\n }\n this.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;\n this.tailText = buffer.subarray(start).toString(\"utf-8\");\n this.tailBytes = byteLength(this.tailText);\n }\n getSnapshotText() {\n if (this.tailStartsAtLineBoundary) {\n return this.tailText;\n }\n const firstNewline = this.tailText.indexOf(\"\\n\");\n return firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);\n }\n shouldUseTempFile() {\n return (this.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines);\n }\n ensureTempFile() {\n if (this.tempFilePath) {\n return;\n }\n this.tempFilePath = defaultTempFilePath(this.tempFilePrefix);\n this.tempFileStream = createWriteStream(this.tempFilePath);\n for (const chunk of this.rawChunks) {\n this.tempFileStream.write(chunk);\n }\n this.rawChunks = [];\n }\n}\n//# sourceMappingURL=output-accumulator.js.map","// @ts-nocheck — vendored Pi source (utils/ansi.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/*\n * Portions of this file are derived from:\n * - ansi-regex (https://github.com/chalk/ansi-regex)\n * - strip-ansi (https://github.com/chalk/strip-ansi)\n *\n * MIT License\n *\n * Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nfunction ansiRegex({ onlyFirst = false } = {}) {\n // Valid string terminator sequences are BEL, ESC\\, and 0x9c\n const ST = \"(?:\\\\u0007|\\\\u001B\\\\u005C|\\\\u009C)\";\n // OSC sequences only: ESC ] ... ST (non-greedy until the first ST)\n const osc = `(?:\\\\u001B\\\\][\\\\s\\\\S]*?${ST})`;\n // CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte\n const csi = \"[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:\\\\d{1,4}(?:[;:]\\\\d{0,4})*)?[\\\\dA-PR-TZcf-nq-uy=><~]\";\n const pattern = `${osc}|${csi}`;\n return new RegExp(pattern, onlyFirst ? undefined : \"g\");\n}\nconst regex = ansiRegex();\nexport function stripAnsi(value) {\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected a \\`string\\`, got \\`${typeof value}\\``);\n }\n // Fast path: ANSI codes require ESC (7-bit) or CSI (8-bit) introducer\n if (!value.includes(\"\\u001B\") && !value.includes(\"\\u009B\")) {\n return value;\n }\n // Even though the regex is global, we don't need to reset the `.lastIndex`\n // because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n // and doing it manually has a performance penalty.\n return value.replace(regex, \"\");\n}\n//# sourceMappingURL=ansi.js.map","// @ts-nocheck — vendored Pi source (utils/paths.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve as nodeResolvePath, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnProcessSync } from \"./child-process.js\";\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n/**\n * Resolve a path to its canonical (real) form, following symlinks.\n * Falls back to the raw path if resolution fails (e.g. the target does\n * not exist yet), so that callers never crash on missing filesystem\n * entries.\n */\nexport function canonicalizePath(path) {\n try {\n return realpathSync(path);\n }\n catch {\n return path;\n }\n}\nexport function getFileRevision(path) {\n try {\n const stats = statSync(path, { bigint: true });\n return `${stats.dev}:${stats.ino}:${stats.size}:${stats.mtimeNs}:${stats.ctimeNs}`;\n }\n catch {\n return undefined;\n }\n}\n/**\n * Returns true if the value is NOT a package source (npm:, git:, etc.)\n * or a remote URL protocol. Bare names, relative paths, and file: URLs\n * are considered local.\n */\nexport function isLocalPath(value) {\n const trimmed = value.trim();\n // Known non-local prefixes. file: URLs are local paths and are intentionally resolved by resolvePath().\n if (trimmed.startsWith(\"npm:\") ||\n trimmed.startsWith(\"git:\") ||\n trimmed.startsWith(\"github:\") ||\n trimmed.startsWith(\"http:\") ||\n trimmed.startsWith(\"https:\") ||\n trimmed.startsWith(\"ssh:\")) {\n return false;\n }\n return true;\n}\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath) {\n if (!filePath.startsWith(\"/\") || filePath.startsWith(\"//\") || filePath.includes(\"\\\\\"))\n return filePath;\n const match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i);\n if (!match)\n return filePath;\n const suffix = match[2]?.replaceAll(\"/\", \"\\\\\");\n return `${match[1].toUpperCase()}:\\\\${suffix ?? \"\"}`;\n}\nexport function normalizePath(input, options = {}) {\n let normalized = options.trim ? input.trim() : input;\n if (options.normalizeUnicodeSpaces) {\n normalized = normalized.replace(UNICODE_SPACES, \" \");\n }\n if (options.stripAtPrefix && normalized.startsWith(\"@\")) {\n normalized = normalized.slice(1);\n }\n if (process.platform === \"win32\") {\n normalized = normalizeWindowsShellPath(normalized);\n }\n if (options.expandTilde ?? true) {\n const home = options.homeDir ?? homedir();\n if (normalized === \"~\")\n return home;\n if (normalized.startsWith(\"~/\") || (process.platform === \"win32\" && normalized.startsWith(\"~\\\\\"))) {\n return join(home, normalized.slice(2));\n }\n }\n if (/^file:\\/\\//.test(normalized)) {\n return fileURLToPath(normalized);\n }\n return normalized;\n}\nexport function resolvePath(input, baseDir = process.cwd(), options = {}) {\n const normalized = normalizePath(input, options);\n const normalizedBaseDir = normalizePath(baseDir);\n return isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized);\n}\nexport function getCwdRelativePath(filePath, cwd) {\n const resolvedCwd = resolvePath(cwd);\n const resolvedPath = resolvePath(filePath, resolvedCwd);\n const relativePath = relative(resolvedCwd, resolvedPath);\n const isInsideCwd = relativePath === \"\" ||\n (relativePath !== \"..\" && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath));\n return isInsideCwd ? relativePath || \".\" : undefined;\n}\nexport function formatPathRelativeToCwdOrAbsolute(filePath, cwd) {\n const absolutePath = resolvePath(filePath, cwd);\n return (getCwdRelativePath(absolutePath, cwd) ?? absolutePath).split(sep).join(\"/\");\n}\nexport function markPathIgnoredByCloudSync(path) {\n const attrs = process.platform === \"darwin\"\n ? [\"com.dropbox.ignored\", \"com.apple.fileprovider.ignore#P\"]\n : process.platform === \"linux\"\n ? [\"user.com.dropbox.ignored\"]\n : [];\n for (const attr of attrs) {\n if (process.platform === \"darwin\") {\n spawnProcessSync(\"xattr\", [\"-w\", attr, \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n }\n else {\n spawnProcessSync(\"setfattr\", [\"-n\", attr, \"-v\", \"1\", path], { encoding: \"utf-8\", stdio: \"ignore\" });\n }\n }\n}\n//# sourceMappingURL=paths.js.map","// @ts-nocheck — vendored Pi source (core/tools/render-utils.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport * as os from \"node:os\";\nimport { pathToFileURL } from \"node:url\";\nimport { getCapabilities, getImageDimensions, hyperlink, imageFallback } from '../../pi-tui.js';\nimport { stripAnsi } from './ansi.js';\nimport { resolvePath } from './paths.js';\nimport { sanitizeBinaryOutput } from './shell.js';\nexport function shortenPath(path) {\n if (typeof path !== \"string\")\n return \"\";\n const home = os.homedir();\n if (path.startsWith(home)) {\n return `~${path.slice(home.length)}`;\n }\n return path;\n}\nexport function linkPath(styledText, rawPath, cwd) {\n if (!getCapabilities().hyperlinks)\n return styledText;\n const absolutePath = resolvePath(rawPath, cwd);\n return hyperlink(styledText, pathToFileURL(absolutePath).href);\n}\nexport function str(value) {\n if (typeof value === \"string\")\n return value;\n if (value == null)\n return \"\";\n return null;\n}\nexport function replaceTabs(text) {\n return text.replace(/\\t/g, \" \");\n}\nexport function normalizeDisplayText(text) {\n return text.replace(/\\r/g, \"\");\n}\nexport function getTextOutput(result, showImages) {\n if (!result)\n return \"\";\n const textBlocks = result.content.filter((c) => c.type === \"text\");\n const imageBlocks = result.content.filter((c) => c.type === \"image\");\n let output = textBlocks.map((c) => sanitizeBinaryOutput(stripAnsi(c.text || \"\")).replace(/\\r/g, \"\")).join(\"\\n\");\n const caps = getCapabilities();\n if (imageBlocks.length > 0 && (!caps.images || !showImages)) {\n const imageIndicators = imageBlocks\n .map((img) => {\n const mimeType = img.mimeType ?? \"image/unknown\";\n const dims = img.data && img.mimeType ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;\n return imageFallback(mimeType, dims);\n })\n .join(\"\\n\");\n output = output ? `${output}\\n${imageIndicators}` : imageIndicators;\n }\n return output;\n}\nexport function invalidArgText(theme) {\n return theme.fg(\"error\", \"[invalid arg]\");\n}\nexport function renderToolPath(rawPath, theme, cwd, options) {\n if (rawPath === null)\n return invalidArgText(theme);\n const value = rawPath || options?.emptyFallback;\n if (!value)\n return theme.fg(\"toolOutput\", \"...\");\n return linkPath(theme.fg(\"accent\", shortenPath(value)), value, cwd);\n}\n//# sourceMappingURL=render-utils.js.map","// @ts-nocheck — vendored Pi source (core/tools/tool-definition-wrapper.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition(definition, ctxFactory) {\n return {\n name: definition.name,\n label: definition.label,\n description: definition.description,\n parameters: definition.parameters,\n constrainedSampling: definition.constrainedSampling,\n prepareArguments: definition.prepareArguments,\n executionMode: definition.executionMode,\n execute: (toolCallId, params, signal, onUpdate, ctx) => definition.execute(toolCallId, params, signal, onUpdate, ctx ?? ctxFactory?.()),\n };\n}\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(definitions, ctxFactory) {\n return definitions.map((definition) => wrapToolDefinition(definition, ctxFactory));\n}\n/**\n * Synthesize a minimal ToolDefinition from an AgentTool.\n *\n * This keeps AgentSession's internal registry definition-first even when a caller\n * provides plain AgentTool overrides that do not include prompt metadata or renderers.\n */\nexport function createToolDefinitionFromAgentTool(tool) {\n return {\n name: tool.name,\n label: tool.label,\n description: tool.description,\n parameters: tool.parameters,\n constrainedSampling: tool.constrainedSampling,\n prepareArguments: tool.prepareArguments,\n executionMode: tool.executionMode,\n execute: async (toolCallId, params, signal, onUpdate) => tool.execute(toolCallId, params, signal, onUpdate),\n };\n}\n//# sourceMappingURL=tool-definition-wrapper.js.map","// @ts-nocheck — vendored Pi source (core/tools/bash.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { constants } from \"node:fs\";\nimport { access as fsAccess } from \"node:fs/promises\";\nimport { Container, Text, truncateToWidth } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { truncateToVisualLines } from './visual-truncate.js';\nimport { theme } from '../../pi-coding-agent.js';\nimport { waitForChildProcess } from './child-process.js';\nimport { getShellConfig, getShellEnv, killProcessTree, trackDetachedChildPid, untrackDetachedChildPid, } from './shell.js';\nimport { OutputAccumulator } from \"./output-accumulator.js\";\nimport { getTextOutput, invalidArgText, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from \"./truncate.js\";\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;\nfunction resolveTimeoutMs(timeout) {\n if (timeout === undefined)\n return undefined;\n if (!Number.isFinite(timeout) || timeout <= 0) {\n throw new Error(\"Invalid timeout: must be a finite number of seconds\");\n }\n const timeoutMs = timeout * 1000;\n if (timeoutMs > MAX_TIMEOUT_MS) {\n throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);\n }\n return timeoutMs;\n}\nconst bashSchema = Type.Object({\n command: Type.String({ description: \"Bash command to execute\" }),\n timeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\nexport const bashToolSystemPromptContribution = {\n snippet: \"Execute bash commands (ls, grep, find, etc.)\",\n guidelines: [\"You can inspect PI_* environment variables for current model and session details.\"],\n};\n/**\n * Create bash operations using pi's built-in local shell execution backend.\n *\n * This is useful for extensions that intercept user_bash and still want pi's\n * standard local shell behavior while wrapping or rewriting commands.\n */\nexport function createLocalBashOperations(options) {\n return {\n exec: async (command, cwd, { onData, signal, timeout, env }) => {\n const timeoutMs = resolveTimeoutMs(timeout);\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n const shellConfig = getShellConfig(options?.shellPath);\n try {\n await fsAccess(cwd, constants.F_OK);\n }\n catch {\n throw new Error(`Working directory does not exist: ${cwd}\\nCannot execute bash commands.`);\n }\n const commandFromStdin = shellConfig.commandTransport === \"stdin\";\n const child = spawn(shellConfig.shell, commandFromStdin ? shellConfig.args : [...shellConfig.args, command], {\n cwd,\n detached: process.platform !== \"win32\",\n env: env ?? getShellEnv(),\n stdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n });\n if (commandFromStdin) {\n child.stdin?.on(\"error\", () => { });\n child.stdin?.end(command);\n }\n if (child.pid)\n trackDetachedChildPid(child.pid);\n let timedOut = false;\n let timeoutHandle;\n const onAbort = () => {\n if (child.pid)\n killProcessTree(child.pid);\n };\n try {\n // Set timeout if provided.\n if (timeoutMs !== undefined) {\n timeoutHandle = setTimeout(() => {\n timedOut = true;\n if (child.pid)\n killProcessTree(child.pid);\n }, timeoutMs);\n }\n // Stream stdout and stderr.\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n // Handle abort signal by killing the entire process tree.\n if (signal) {\n if (signal.aborted)\n onAbort();\n else\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n // Handle shell spawn errors and wait for the process to terminate without hanging\n // on inherited stdio handles held by detached descendants.\n const exitCode = await waitForChildProcess(child);\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n if (timedOut) {\n throw new Error(`timeout:${timeout}`);\n }\n return { exitCode };\n }\n finally {\n if (child.pid)\n untrackDetachedChildPid(child.pid);\n if (timeoutHandle)\n clearTimeout(timeoutHandle);\n if (signal)\n signal.removeEventListener(\"abort\", onAbort);\n }\n },\n };\n}\nfunction resolveSpawnContext(command, cwd, spawnHook, exposeSessionEnvironment, ctx) {\n const env = { ...getShellEnv() };\n delete env.PI_SESSION_ID;\n delete env.PI_SESSION_FILE;\n delete env.PI_PROVIDER;\n delete env.PI_MODEL;\n delete env.PI_REASONING_LEVEL;\n if (exposeSessionEnvironment && ctx) {\n const model = ctx.model;\n env.PI_SESSION_ID = ctx.sessionManager.getSessionId();\n const sessionFile = ctx.sessionManager.getSessionFile();\n if (sessionFile)\n env.PI_SESSION_FILE = sessionFile;\n if (model) {\n env.PI_PROVIDER = model.provider;\n env.PI_MODEL = model.id;\n }\n if (ctx.thinkingLevel)\n env.PI_REASONING_LEVEL = ctx.thinkingLevel;\n }\n const baseContext = { command, cwd, env };\n return spawnHook ? spawnHook(baseContext) : baseContext;\n}\nconst BASH_PREVIEW_LINES = 5;\nconst BASH_UPDATE_THROTTLE_MS = 100;\nclass BashResultRenderComponent extends Container {\n state = {\n cachedWidth: undefined,\n cachedLines: undefined,\n cachedSkipped: undefined,\n };\n}\nfunction formatDuration(ms) {\n return `${(ms / 1000).toFixed(1)}s`;\n}\nfunction formatBashCall(args) {\n const command = str(args?.command);\n const timeout = args?.timeout;\n const timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n const commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n return theme.fg(\"toolTitle\", theme.bold(`$ ${commandDisplay}`)) + timeoutSuffix;\n}\nfunction rebuildBashResultRenderComponent(component, result, options, showImages, startedAt, endedAt) {\n const state = component.state;\n component.clear();\n let output = getTextOutput(result, showImages).trim();\n const truncation = result.details?.truncation;\n const fullOutputPath = result.details?.fullOutputPath;\n if (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n const footerStart = output.lastIndexOf(\"\\n\\n[\");\n if (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n output = output.slice(0, footerStart).trimEnd();\n }\n }\n if (output) {\n const styledOutput = output\n .split(\"\\n\")\n .map((line) => theme.fg(\"toolOutput\", line))\n .join(\"\\n\");\n if (options.expanded) {\n component.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n }\n else {\n component.addChild({\n render: (width) => {\n if (state.cachedLines === undefined || state.cachedWidth !== width) {\n const preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);\n state.cachedLines = preview.visualLines;\n state.cachedSkipped = preview.skippedCount;\n state.cachedWidth = width;\n }\n if (state.cachedSkipped && state.cachedSkipped > 0) {\n const hint = theme.fg(\"muted\", `... (${state.cachedSkipped} earlier lines,`) +\n ` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n return [\"\", truncateToWidth(hint, width, \"...\"), ...(state.cachedLines ?? [])];\n }\n return [\"\", ...(state.cachedLines ?? [])];\n },\n invalidate: () => {\n state.cachedWidth = undefined;\n state.cachedLines = undefined;\n state.cachedSkipped = undefined;\n },\n });\n }\n }\n if (truncation?.truncated || fullOutputPath) {\n const warnings = [];\n if (fullOutputPath) {\n warnings.push(`Full output: ${fullOutputPath}`);\n }\n if (truncation?.truncated) {\n if (truncation.truncatedBy === \"lines\") {\n warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n }\n else {\n warnings.push(`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`);\n }\n }\n component.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n }\n if (startedAt !== undefined) {\n const label = options.isPartial ? \"Elapsed\" : \"Took\";\n const endTime = endedAt ?? Date.now();\n component.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n }\n}\nexport function createBashToolDefinition(cwd, options) {\n const ops = options?.operations ?? createLocalBashOperations({ shellPath: options?.shellPath });\n const commandPrefix = options?.commandPrefix;\n const exposeSessionEnvironment = options?.exposeSessionEnvironment ?? true;\n const spawnHook = options?.spawnHook;\n return {\n name: \"bash\",\n label: \"bash\",\n description: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n promptSnippet: bashToolSystemPromptContribution.snippet,\n promptGuidelines: exposeSessionEnvironment ? [...bashToolSystemPromptContribution.guidelines] : undefined,\n parameters: bashSchema,\n async execute(_toolCallId, { command, timeout }, signal, onUpdate, ctx) {\n const resolvedCommand = commandPrefix ? `${commandPrefix}\\n${command}` : command;\n const spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook, exposeSessionEnvironment, ctx);\n const output = new OutputAccumulator({ tempFilePrefix: \"pi-bash\" });\n let acceptingOutput = true;\n let updateTimer;\n let updateDirty = false;\n let lastUpdateAt = 0;\n const emitOutputUpdate = () => {\n if (!onUpdate || !updateDirty)\n return;\n updateDirty = false;\n lastUpdateAt = Date.now();\n const snapshot = output.snapshot({ persistIfTruncated: true });\n onUpdate({\n content: [{ type: \"text\", text: snapshot.content || \"\" }],\n details: {\n truncation: snapshot.truncation.truncated ? snapshot.truncation : undefined,\n fullOutputPath: snapshot.fullOutputPath,\n },\n });\n };\n const clearUpdateTimer = () => {\n if (updateTimer) {\n clearTimeout(updateTimer);\n updateTimer = undefined;\n }\n };\n const scheduleOutputUpdate = () => {\n if (!onUpdate)\n return;\n updateDirty = true;\n const delay = BASH_UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);\n if (delay <= 0) {\n clearUpdateTimer();\n emitOutputUpdate();\n return;\n }\n updateTimer ??= setTimeout(() => {\n updateTimer = undefined;\n emitOutputUpdate();\n }, delay);\n };\n if (onUpdate) {\n onUpdate({ content: [], details: undefined });\n }\n const handleData = (data) => {\n if (!acceptingOutput)\n return;\n output.append(data);\n scheduleOutputUpdate();\n };\n const finishOutput = async () => {\n acceptingOutput = false;\n output.finish();\n clearUpdateTimer();\n emitOutputUpdate();\n const snapshot = output.snapshot({ persistIfTruncated: true });\n await output.closeTempFile();\n return snapshot;\n };\n const formatOutput = (snapshot, emptyText = \"(no output)\") => {\n const truncation = snapshot.truncation;\n let text = snapshot.content || emptyText;\n let details;\n if (truncation.truncated) {\n details = { truncation, fullOutputPath: snapshot.fullOutputPath };\n const startLine = truncation.totalLines - truncation.outputLines + 1;\n const endLine = truncation.totalLines;\n if (truncation.lastLinePartial) {\n const lastLineSize = formatSize(output.getLastLineBytes());\n text += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;\n }\n else if (truncation.truncatedBy === \"lines\") {\n text += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;\n }\n else {\n text += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;\n }\n }\n return { text, details };\n };\n const appendStatus = (text, status) => `${text ? `${text}\\n\\n` : \"\"}${status}`;\n try {\n let exitCode;\n try {\n const result = await ops.exec(spawnContext.command, spawnContext.cwd, {\n onData: handleData,\n signal,\n timeout,\n env: spawnContext.env,\n });\n exitCode = result.exitCode;\n }\n catch (err) {\n const snapshot = await finishOutput();\n const { text } = formatOutput(snapshot, \"\");\n if (err instanceof Error && err.message === \"aborted\") {\n throw new Error(appendStatus(text, \"Command aborted\"));\n }\n if (err instanceof Error && err.message.startsWith(\"timeout:\")) {\n const timeoutSecs = err.message.split(\":\")[1];\n throw new Error(appendStatus(text, `Command timed out after ${timeoutSecs} seconds`));\n }\n throw err;\n }\n const snapshot = await finishOutput();\n const { text: outputText, details } = formatOutput(snapshot);\n if (exitCode !== 0 && exitCode !== null) {\n throw new Error(appendStatus(outputText, `Command exited with code ${exitCode}`));\n }\n return { content: [{ type: \"text\", text: outputText }], details };\n }\n finally {\n clearUpdateTimer();\n }\n },\n renderCall(args, _theme, context) {\n const state = context.state;\n if (context.executionStarted && state.startedAt === undefined) {\n state.startedAt = Date.now();\n state.endedAt = undefined;\n }\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatBashCall(args));\n return text;\n },\n renderResult(result, options, _theme, context) {\n const state = context.state;\n if (state.startedAt !== undefined && options.isPartial && !state.interval) {\n state.interval = setInterval(() => context.invalidate(), 1000);\n }\n if (!options.isPartial || context.isError) {\n state.endedAt ??= Date.now();\n if (state.interval) {\n clearInterval(state.interval);\n state.interval = undefined;\n }\n }\n const component = context.lastComponent ?? new BashResultRenderComponent();\n rebuildBashResultRenderComponent(component, result, options, context.showImages, state.startedAt, state.endedAt);\n component.invalidate();\n return component;\n },\n };\n}\nexport function createBashTool(cwd, options) {\n const definition = createBashToolDefinition(cwd, options);\n const tool = wrapToolDefinition(definition);\n Object.assign(tool, {\n promptSnippet: definition.promptSnippet,\n promptGuidelines: definition.promptGuidelines,\n });\n return tool;\n}\n//# sourceMappingURL=bash.js.map","// @ts-nocheck — vendored Pi source (utils/mime.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { open } from \"node:fs/promises\";\nconst IMAGE_TYPE_SNIFF_BYTES = 4100;\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\nexport function detectSupportedImageMimeType(buffer) {\n if (startsWith(buffer, [0xff, 0xd8, 0xff])) {\n return buffer[3] === 0xf7 ? null : \"image/jpeg\";\n }\n if (startsWith(buffer, PNG_SIGNATURE)) {\n return isPng(buffer) && !isAnimatedPng(buffer) ? \"image/png\" : null;\n }\n if (startsWithAscii(buffer, 0, \"GIF\")) {\n return \"image/gif\";\n }\n if (startsWithAscii(buffer, 0, \"RIFF\") && startsWithAscii(buffer, 8, \"WEBP\")) {\n return \"image/webp\";\n }\n if (startsWithAscii(buffer, 0, \"BM\") && isBmp(buffer)) {\n return \"image/bmp\";\n }\n return null;\n}\nexport async function detectSupportedImageMimeTypeFromFile(filePath) {\n const fileHandle = await open(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(IMAGE_TYPE_SNIFF_BYTES);\n const { bytesRead } = await fileHandle.read(buffer, 0, IMAGE_TYPE_SNIFF_BYTES, 0);\n return detectSupportedImageMimeType(buffer.subarray(0, bytesRead));\n }\n finally {\n await fileHandle.close();\n }\n}\nfunction isPng(buffer) {\n return (buffer.length >= 16 && readUint32BE(buffer, PNG_SIGNATURE.length) === 13 && startsWithAscii(buffer, 12, \"IHDR\"));\n}\nfunction isAnimatedPng(buffer) {\n let offset = PNG_SIGNATURE.length;\n while (offset + 8 <= buffer.length) {\n const chunkLength = readUint32BE(buffer, offset);\n const chunkTypeOffset = offset + 4;\n if (startsWithAscii(buffer, chunkTypeOffset, \"acTL\"))\n return true;\n if (startsWithAscii(buffer, chunkTypeOffset, \"IDAT\"))\n return false;\n const nextOffset = offset + 8 + chunkLength + 4;\n if (nextOffset <= offset || nextOffset > buffer.length)\n return false;\n offset = nextOffset;\n }\n return false;\n}\nfunction isBmp(buffer) {\n if (buffer.length < 26)\n return false;\n const declaredFileSize = readUint32LE(buffer, 2);\n const pixelDataOffset = readUint32LE(buffer, 10);\n const dibHeaderSize = readUint32LE(buffer, 14);\n if (declaredFileSize !== 0 && declaredFileSize < 26)\n return false;\n if (pixelDataOffset < 14 + dibHeaderSize)\n return false;\n if (declaredFileSize !== 0 && pixelDataOffset >= declaredFileSize)\n return false;\n let colorPlanes;\n let bitsPerPixel;\n if (dibHeaderSize === 12) {\n colorPlanes = readUint16LE(buffer, 22);\n bitsPerPixel = readUint16LE(buffer, 24);\n }\n else if (dibHeaderSize >= 40 && dibHeaderSize <= 124) {\n if (buffer.length < 30)\n return false;\n colorPlanes = readUint16LE(buffer, 26);\n bitsPerPixel = readUint16LE(buffer, 28);\n }\n else {\n return false;\n }\n return colorPlanes === 1 && [1, 4, 8, 16, 24, 32].includes(bitsPerPixel);\n}\nfunction readUint16LE(buffer, offset) {\n return (buffer[offset] ?? 0) + ((buffer[offset + 1] ?? 0) << 8);\n}\nfunction readUint32BE(buffer, offset) {\n return ((buffer[offset] ?? 0) * 0x1000000 +\n ((buffer[offset + 1] ?? 0) << 16) +\n ((buffer[offset + 2] ?? 0) << 8) +\n (buffer[offset + 3] ?? 0));\n}\nfunction readUint32LE(buffer, offset) {\n return ((buffer[offset] ?? 0) +\n ((buffer[offset + 1] ?? 0) << 8) +\n ((buffer[offset + 2] ?? 0) << 16) +\n (buffer[offset + 3] ?? 0) * 0x1000000);\n}\nfunction startsWith(buffer, bytes) {\n if (buffer.length < bytes.length)\n return false;\n return bytes.every((byte, index) => buffer[index] === byte);\n}\nfunction startsWithAscii(buffer, offset, text) {\n if (buffer.length < offset + text.length)\n return false;\n for (let index = 0; index < text.length; index++) {\n if (buffer[offset + index] !== text.charCodeAt(index))\n return false;\n }\n return true;\n}\n//# sourceMappingURL=mime.js.map","// @ts-nocheck — vendored Pi source (core/tools/path-utils.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { accessSync, constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { normalizePath, resolvePath } from './paths.js';\nconst NARROW_NO_BREAK_SPACE = \"\\u202F\";\nfunction tryMacOSScreenshotPath(filePath) {\n return filePath.replace(/ (AM|PM)\\./gi, `${NARROW_NO_BREAK_SPACE}$1.`);\n}\nfunction tryNFDVariant(filePath) {\n // macOS stores filenames in NFD (decomposed) form, try converting user input to NFD\n return filePath.normalize(\"NFD\");\n}\nfunction tryCurlyQuoteVariant(filePath) {\n // macOS uses U+2019 (right single quotation mark) in screenshot names like \"Capture d'écran\"\n // Users typically type U+0027 (straight apostrophe)\n return filePath.replace(/'/g, \"\\u2019\");\n}\nfunction fileExists(filePath) {\n try {\n accessSync(filePath, constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nexport async function pathExists(filePath) {\n try {\n await access(filePath, constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nexport function expandPath(filePath) {\n return normalizePath(filePath, { normalizeUnicodeSpaces: true, stripAtPrefix: true });\n}\n/**\n * Resolve a path relative to the given cwd.\n * Handles ~ expansion and absolute paths.\n */\nexport function resolveToCwd(filePath, cwd) {\n return resolvePath(filePath, cwd, { normalizeUnicodeSpaces: true, stripAtPrefix: true });\n}\nexport function resolveReadPath(filePath, cwd) {\n const resolved = resolveToCwd(filePath, cwd);\n if (fileExists(resolved)) {\n return resolved;\n }\n // Try macOS AM/PM variant (narrow no-break space before AM/PM)\n const amPmVariant = tryMacOSScreenshotPath(resolved);\n if (amPmVariant !== resolved && fileExists(amPmVariant)) {\n return amPmVariant;\n }\n // Try NFD variant (macOS stores filenames in NFD form)\n const nfdVariant = tryNFDVariant(resolved);\n if (nfdVariant !== resolved && fileExists(nfdVariant)) {\n return nfdVariant;\n }\n // Try curly quote variant (macOS uses U+2019 in screenshot names)\n const curlyVariant = tryCurlyQuoteVariant(resolved);\n if (curlyVariant !== resolved && fileExists(curlyVariant)) {\n return curlyVariant;\n }\n // Try combined NFD + curly quote (for French macOS screenshots like \"Capture d'écran\")\n const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant);\n if (nfdCurlyVariant !== resolved && fileExists(nfdCurlyVariant)) {\n return nfdCurlyVariant;\n }\n return resolved;\n}\nexport async function resolveReadPathAsync(filePath, cwd) {\n const resolved = resolveToCwd(filePath, cwd);\n if (await pathExists(resolved)) {\n return resolved;\n }\n // Try macOS AM/PM variant (narrow no-break space before AM/PM)\n const amPmVariant = tryMacOSScreenshotPath(resolved);\n if (amPmVariant !== resolved && (await pathExists(amPmVariant))) {\n return amPmVariant;\n }\n // Try NFD variant (macOS stores filenames in NFD form)\n const nfdVariant = tryNFDVariant(resolved);\n if (nfdVariant !== resolved && (await pathExists(nfdVariant))) {\n return nfdVariant;\n }\n // Try curly quote variant (macOS uses U+2019 in screenshot names)\n const curlyVariant = tryCurlyQuoteVariant(resolved);\n if (curlyVariant !== resolved && (await pathExists(curlyVariant))) {\n return curlyVariant;\n }\n // Try combined NFD + curly quote (for French macOS screenshots like \"Capture d'écran\")\n const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant);\n if (nfdCurlyVariant !== resolved && (await pathExists(nfdCurlyVariant))) {\n return nfdCurlyVariant;\n }\n return resolved;\n}\n//# sourceMappingURL=path-utils.js.map","// @ts-nocheck — vendored Pi source (core/tools/read.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport { Text } from '../../pi-tui.js';\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile } from \"fs/promises\";\nimport { Type } from \"typebox\";\nimport { getReadmePath } from '../../pi-coding-agent.js';\nimport { keyHint, keyText } from '../../pi-coding-agent.js';\nimport { getLanguageFromPath, highlightCode } from '../../pi-coding-agent.js';\nimport { processImage } from '../../pi-coding-agent.js';\nimport { detectSupportedImageMimeTypeFromFile } from './mime.js';\nimport { formatPathRelativeToCwdOrAbsolute } from './paths.js';\nimport { resolveReadPathAsync, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, renderToolPath, replaceTabs, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from \"./truncate.js\";\nconst readSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n offset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\nexport const readToolSystemPromptContribution = {\n snippet: \"Read file contents\",\n guidelines: [\"Use read to examine files instead of cat or sed.\"],\n};\nconst COMPACT_RESOURCE_FILE_NAMES = new Set([\"AGENTS.override.md\", \"AGENTS.md\", \"AGENTS.MD\", \"CLAUDE.md\", \"CLAUDE.MD\"]);\nconst defaultReadOperations = {\n readFile: (path) => fsReadFile(path),\n access: (path) => fsAccess(path, constants.R_OK),\n detectImageMimeType: detectSupportedImageMimeTypeFromFile,\n};\nfunction formatReadLineRange(args, theme) {\n if (args?.offset === undefined && args?.limit === undefined)\n return \"\";\n const startLine = args.offset ?? 1;\n const endLine = args.limit !== undefined ? startLine + args.limit - 1 : \"\";\n return theme.fg(\"warning\", `:${startLine}${endLine ? `-${endLine}` : \"\"}`);\n}\nfunction formatReadCall(args, theme, cwd) {\n const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n return `${theme.fg(\"toolTitle\", theme.bold(\"read\"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;\n}\nfunction trimTrailingEmptyLines(lines) {\n let end = lines.length;\n while (end > 0 && lines[end - 1] === \"\") {\n end--;\n }\n return lines.slice(0, end);\n}\nfunction getNonVisionImageNote(model) {\n if (!model || model.input.includes(\"image\")) {\n return undefined;\n }\n return \"[Current model does not support images. The image will be omitted from this request.]\";\n}\nfunction toPosixPath(filePath) {\n return filePath.split(sep).join(\"/\");\n}\nfunction getPiDocsClassification(absolutePath) {\n const packageRoot = dirname(getReadmePath());\n const relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));\n if (relativePath === \"\" ||\n relativePath === \"..\" ||\n relativePath.startsWith(`..${sep}`) ||\n isAbsolute(relativePath)) {\n return undefined;\n }\n const label = toPosixPath(relativePath);\n if (label === \"README.md\" || label.startsWith(\"docs/\") || label.startsWith(\"examples/\")) {\n return { kind: \"docs\", label };\n }\n return undefined;\n}\nfunction getCompactReadClassification(args, cwd) {\n const rawPath = str(args?.file_path ?? args?.path);\n if (!rawPath)\n return undefined;\n const absolutePath = resolveToCwd(rawPath, cwd);\n const fileName = basename(absolutePath);\n if (fileName === \"SKILL.md\") {\n return { kind: \"skill\", label: basename(dirname(absolutePath)) || fileName };\n }\n const docsClassification = getPiDocsClassification(absolutePath);\n if (docsClassification)\n return docsClassification;\n if (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {\n return { kind: \"resource\", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };\n }\n return undefined;\n}\nfunction formatCompactReadCall(classification, args, theme) {\n const expandHint = theme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n if (classification.kind === \"skill\") {\n return (theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n theme.fg(\"customMessageText\", classification.label) +\n formatReadLineRange(args, theme) +\n expandHint);\n }\n return (theme.fg(\"toolTitle\", theme.bold(`read ${classification.kind}`)) +\n \" \" +\n theme.fg(\"accent\", classification.label) +\n formatReadLineRange(args, theme) +\n expandHint);\n}\nfunction formatReadResult(args, result, options, theme, showImages, _cwd, isError) {\n if (!options.expanded && !isError) {\n return \"\";\n }\n const rawPath = str(args?.file_path ?? args?.path);\n const output = getTextOutput(result, showImages);\n const lang = !isError && rawPath ? getLanguageFromPath(rawPath) : undefined;\n const renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split(\"\\n\");\n const lines = trimTrailingEmptyLines(renderedLines);\n const maxLines = options.expanded ? lines.length : 10;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n let text = `\\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n const truncation = result.details?.truncation;\n if (truncation?.truncated) {\n if (truncation.firstLineExceedsLimit) {\n text += `\\n${theme.fg(\"warning\", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;\n }\n else if (truncation.truncatedBy === \"lines\") {\n text += `\\n${theme.fg(\"warning\", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;\n }\n else {\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;\n }\n }\n return text;\n}\nexport function createReadToolDefinition(cwd, options) {\n const autoResizeImages = options?.autoResizeImages ?? true;\n const ops = options?.operations ?? defaultReadOperations;\n return {\n name: \"read\",\n label: \"read\",\n description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n promptSnippet: readToolSystemPromptContribution.snippet,\n promptGuidelines: [...readToolSystemPromptContribution.guidelines],\n parameters: readSchema,\n async execute(_toolCallId, { path, offset, limit }, signal, _onUpdate, ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let aborted = false;\n const onAbort = () => {\n aborted = true;\n reject(new Error(\"Operation aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const absolutePath = await resolveReadPathAsync(path, cwd);\n if (aborted)\n return;\n // Check if file exists and is readable.\n await ops.access(absolutePath);\n if (aborted)\n return;\n const mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n let content;\n let details;\n const nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n if (mimeType) {\n // Read image as binary.\n const buffer = await ops.readFile(absolutePath);\n const processed = await processImage(buffer, mimeType, { autoResizeImages });\n if (!processed.ok) {\n let textNote = `Read image file [${mimeType}]\\n${processed.message}`;\n if (nonVisionImageNote)\n textNote += `\\n${nonVisionImageNote}`;\n content = [{ type: \"text\", text: textNote }];\n }\n else {\n let textNote = `Read image file [${processed.mimeType}]`;\n if (processed.hints.length > 0)\n textNote += `\\n${processed.hints.join(\"\\n\")}`;\n if (nonVisionImageNote)\n textNote += `\\n${nonVisionImageNote}`;\n content = [\n { type: \"text\", text: textNote },\n { type: \"image\", data: processed.data, mimeType: processed.mimeType },\n ];\n }\n }\n else {\n // Read text content.\n const buffer = await ops.readFile(absolutePath);\n const textContent = buffer.toString(\"utf-8\");\n const allLines = textContent.split(\"\\n\");\n const totalFileLines = allLines.length;\n // Apply offset if specified. Convert from 1-indexed input to 0-indexed array access.\n const startLine = offset ? Math.max(0, offset - 1) : 0;\n const startLineDisplay = startLine + 1;\n // Check if offset is out of bounds.\n if (startLine >= allLines.length) {\n throw new Error(`Offset ${offset} is beyond end of file (${allLines.length} lines total)`);\n }\n let selectedContent;\n let userLimitedLines;\n // If limit is specified by the user, honor it first. Otherwise truncateHead decides.\n if (limit !== undefined) {\n const endLine = Math.min(startLine + limit, allLines.length);\n selectedContent = allLines.slice(startLine, endLine).join(\"\\n\");\n userLimitedLines = endLine - startLine;\n }\n else {\n selectedContent = allLines.slice(startLine).join(\"\\n\");\n }\n // Apply truncation, respecting both line and byte limits.\n const truncation = truncateHead(selectedContent);\n let outputText;\n if (truncation.firstLineExceedsLimit) {\n // First line alone exceeds the byte limit. Point the model at a bash fallback.\n const firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], \"utf-8\"));\n outputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n details = { truncation };\n }\n else if (truncation.truncated) {\n // Truncation occurred. Build an actionable continuation notice.\n const endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n const nextOffset = endLineDisplay + 1;\n outputText = truncation.content;\n if (truncation.truncatedBy === \"lines\") {\n outputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;\n }\n else {\n outputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n }\n details = { truncation };\n }\n else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {\n // User-specified limit stopped early, but the file still has more content.\n const remaining = allLines.length - (startLine + userLimitedLines);\n const nextOffset = startLine + userLimitedLines + 1;\n outputText = `${truncation.content}\\n\\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;\n }\n else {\n // No truncation and no remaining user-limited content.\n outputText = truncation.content;\n }\n content = [{ type: \"text\", text: outputText }];\n }\n if (aborted)\n return;\n signal?.removeEventListener(\"abort\", onAbort);\n resolve({ content, details });\n }\n catch (error) {\n signal?.removeEventListener(\"abort\", onAbort);\n if (!aborted)\n reject(error);\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n const classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;\n text.setText(classification\n ? formatCompactReadCall(classification, args, theme)\n : formatReadCall(args, theme, context.cwd));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError));\n return text;\n },\n };\n}\nexport function createReadTool(cwd, options) {\n return wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n//# sourceMappingURL=read.js.map","// @ts-nocheck — vendored Pi source (modes/interactive/components/diff.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport * as Diff from \"diff\";\nimport { theme } from '../../pi-coding-agent.js';\n/**\n * Parse diff line to extract prefix, line number, and content.\n * Format: \"+123 content\" or \"-123 content\" or \" 123 content\" or \" ...\"\n */\nfunction parseDiffLine(line) {\n const match = line.match(/^([+-\\s])(\\s*\\d*)\\s(.*)$/);\n if (!match)\n return null;\n return { prefix: match[1], lineNum: match[2], content: match[3] };\n}\n/**\n * Replace tabs with spaces for consistent rendering.\n */\nfunction replaceTabs(text) {\n return text.replace(/\\t/g, \" \");\n}\n/**\n * Compute word-level diff and render with inverse on changed parts.\n * Uses diffWords which groups whitespace with adjacent words for cleaner highlighting.\n * Strips leading whitespace from inverse to avoid highlighting indentation.\n */\nfunction renderIntraLineDiff(oldContent, newContent) {\n const wordDiff = Diff.diffWords(oldContent, newContent);\n let removedLine = \"\";\n let addedLine = \"\";\n let isFirstRemoved = true;\n let isFirstAdded = true;\n for (const part of wordDiff) {\n if (part.removed) {\n let value = part.value;\n // Strip leading whitespace from the first removed part\n if (isFirstRemoved) {\n const leadingWs = value.match(/^(\\s*)/)?.[1] || \"\";\n value = value.slice(leadingWs.length);\n removedLine += leadingWs;\n isFirstRemoved = false;\n }\n if (value) {\n removedLine += theme.inverse(value);\n }\n }\n else if (part.added) {\n let value = part.value;\n // Strip leading whitespace from the first added part\n if (isFirstAdded) {\n const leadingWs = value.match(/^(\\s*)/)?.[1] || \"\";\n value = value.slice(leadingWs.length);\n addedLine += leadingWs;\n isFirstAdded = false;\n }\n if (value) {\n addedLine += theme.inverse(value);\n }\n }\n else {\n removedLine += part.value;\n addedLine += part.value;\n }\n }\n return { removedLine, addedLine };\n}\n/**\n * Render a diff string with colored lines and intra-line change highlighting.\n * - Context lines: dim/gray\n * - Removed lines: red, with inverse on changed tokens\n * - Added lines: green, with inverse on changed tokens\n */\nexport function renderDiff(diffText, _options = {}) {\n const lines = diffText.split(\"\\n\");\n const result = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const parsed = parseDiffLine(line);\n if (!parsed) {\n result.push(theme.fg(\"toolDiffContext\", line));\n i++;\n continue;\n }\n if (parsed.prefix === \"-\") {\n // Collect consecutive removed lines\n const removedLines = [];\n while (i < lines.length) {\n const p = parseDiffLine(lines[i]);\n if (!p || p.prefix !== \"-\")\n break;\n removedLines.push({ lineNum: p.lineNum, content: p.content });\n i++;\n }\n // Collect consecutive added lines\n const addedLines = [];\n while (i < lines.length) {\n const p = parseDiffLine(lines[i]);\n if (!p || p.prefix !== \"+\")\n break;\n addedLines.push({ lineNum: p.lineNum, content: p.content });\n i++;\n }\n // Only do intra-line diffing when there's exactly one removed and one added line\n // (indicating a single line modification). Otherwise, show lines as-is.\n if (removedLines.length === 1 && addedLines.length === 1) {\n const removed = removedLines[0];\n const added = addedLines[0];\n const { removedLine, addedLine } = renderIntraLineDiff(replaceTabs(removed.content), replaceTabs(added.content));\n result.push(theme.fg(\"toolDiffRemoved\", `-${removed.lineNum} ${removedLine}`));\n result.push(theme.fg(\"toolDiffAdded\", `+${added.lineNum} ${addedLine}`));\n }\n else {\n // Show all removed lines first, then all added lines\n for (const removed of removedLines) {\n result.push(theme.fg(\"toolDiffRemoved\", `-${removed.lineNum} ${replaceTabs(removed.content)}`));\n }\n for (const added of addedLines) {\n result.push(theme.fg(\"toolDiffAdded\", `+${added.lineNum} ${replaceTabs(added.content)}`));\n }\n }\n }\n else if (parsed.prefix === \"+\") {\n // Standalone added line\n result.push(theme.fg(\"toolDiffAdded\", `+${parsed.lineNum} ${replaceTabs(parsed.content)}`));\n i++;\n }\n else {\n // Context line\n result.push(theme.fg(\"toolDiffContext\", ` ${parsed.lineNum} ${replaceTabs(parsed.content)}`));\n i++;\n }\n }\n return result.join(\"\\n\");\n}\n//# sourceMappingURL=diff.js.map","// @ts-nocheck — vendored Pi source (core/tools/edit-diff.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\n/**\n * Shared diff computation utilities for the edit and similar tools.\n */\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\nexport function detectLineEnding(content) {\n const crlfIdx = content.indexOf(\"\\r\\n\");\n const lfIdx = content.indexOf(\"\\n\");\n if (lfIdx === -1)\n return \"\\n\";\n if (crlfIdx === -1)\n return \"\\n\";\n return crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\nexport function normalizeToLF(text) {\n return text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\nexport function restoreLineEndings(text, ending) {\n return ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n/**\n * Normalize text for fuzzy matching. Applies progressive transformations:\n * - Strip trailing whitespace from each line\n * - Normalize smart quotes to ASCII equivalents\n * - Normalize Unicode dashes/hyphens to ASCII hyphen\n * - Normalize special Unicode spaces to regular space\n */\nexport function normalizeForFuzzyMatch(text) {\n return (text\n .normalize(\"NFKC\")\n // Strip trailing whitespace per line\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\")\n // Smart single quotes → '\n .replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n // Smart double quotes → \"\n .replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n // Various dashes/hyphens → -\n // U+2010 hyphen, U+2011 non-breaking hyphen, U+2012 figure dash,\n // U+2013 en-dash, U+2014 em-dash, U+2015 horizontal bar, U+2212 minus\n .replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n // Special spaces → regular space\n // U+00A0 NBSP, U+2002-U+200A various spaces, U+202F narrow NBSP,\n // U+205F medium math space, U+3000 ideographic space\n .replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \"));\n}\nfunction splitLinesWithEndings(content) {\n return content.match(/[^\\n]*\\n|[^\\n]+/g) ?? [];\n}\nfunction getLineSpans(content) {\n let offset = 0;\n return splitLinesWithEndings(content).map((line) => {\n const span = { start: offset, end: offset + line.length };\n offset = span.end;\n return span;\n });\n}\nfunction getReplacementLineRange(lines, replacement) {\n const replacementStart = replacement.matchIndex;\n const replacementEnd = replacement.matchIndex + replacement.matchLength;\n let startLine = -1;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (replacementStart >= line.start && replacementStart < line.end) {\n startLine = i;\n break;\n }\n }\n if (startLine === -1) {\n throw new Error(\"Replacement range is outside the base content.\");\n }\n let endLine = startLine;\n while (endLine < lines.length && lines[endLine].end < replacementEnd) {\n endLine++;\n }\n if (endLine >= lines.length) {\n throw new Error(\"Replacement range is outside the base content.\");\n }\n return { startLine, endLine: endLine + 1 };\n}\nfunction applyReplacements(content, replacements, offset = 0) {\n let result = content;\n for (let i = replacements.length - 1; i >= 0; i--) {\n const replacement = replacements[i];\n const matchIndex = replacement.matchIndex - offset;\n result =\n result.substring(0, matchIndex) + replacement.newText + result.substring(matchIndex + replacement.matchLength);\n }\n return result;\n}\n/**\n * Apply replacements matched against `baseContent` to `originalContent` while\n * preserving unchanged line blocks from the original.\n *\n * This is useful when `baseContent` is a normalized view of the original. Each\n * replacement is widened to the lines it actually touches, those touched lines\n * are rewritten from the normalized base, and all other lines are copied back\n * from `originalContent`. The actual replacement ranges drive preservation so\n * duplicate normalized lines cannot be aligned to the wrong occurrence.\n */\nexport function applyReplacementsPreservingUnchangedLines(originalContent, baseContent, replacements) {\n const originalLines = splitLinesWithEndings(originalContent);\n const baseLines = getLineSpans(baseContent);\n if (originalLines.length !== baseLines.length) {\n throw new Error(\"Cannot preserve unchanged lines because the base content has a different line count.\");\n }\n const groups = [];\n const sortedReplacements = [...replacements].sort((a, b) => a.matchIndex - b.matchIndex);\n for (const replacement of sortedReplacements) {\n const range = getReplacementLineRange(baseLines, replacement);\n const current = groups[groups.length - 1];\n if (current && range.startLine < current.endLine) {\n current.endLine = Math.max(current.endLine, range.endLine);\n current.replacements.push(replacement);\n continue;\n }\n groups.push({ ...range, replacements: [replacement] });\n }\n let originalLineIndex = 0;\n let result = \"\";\n for (const group of groups) {\n result += originalLines.slice(originalLineIndex, group.startLine).join(\"\");\n const groupStartOffset = baseLines[group.startLine].start;\n const groupEndOffset = baseLines[group.endLine - 1].end;\n result += applyReplacements(baseContent.slice(groupStartOffset, groupEndOffset), group.replacements, groupStartOffset);\n originalLineIndex = group.endLine;\n }\n result += originalLines.slice(originalLineIndex).join(\"\");\n return result;\n}\n/**\n * Find oldText in content, trying exact match first, then fuzzy match.\n * When fuzzy matching is used, the returned contentForReplacement is the\n * fuzzy-normalized version of the content (trailing whitespace stripped,\n * Unicode quotes/dashes normalized to ASCII).\n */\nexport function fuzzyFindText(content, oldText) {\n // Try exact match first\n const exactIndex = content.indexOf(oldText);\n if (exactIndex !== -1) {\n return {\n found: true,\n index: exactIndex,\n matchLength: oldText.length,\n usedFuzzyMatch: false,\n contentForReplacement: content,\n };\n }\n // Try fuzzy match - work entirely in normalized space\n const fuzzyContent = normalizeForFuzzyMatch(content);\n const fuzzyOldText = normalizeForFuzzyMatch(oldText);\n const fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n if (fuzzyIndex === -1) {\n return {\n found: false,\n index: -1,\n matchLength: 0,\n usedFuzzyMatch: false,\n contentForReplacement: content,\n };\n }\n // When fuzzy matching, return offsets in normalized space. Callers can use\n // the normalized content to compute replacements, then decide how much of\n // that normalized output should be written back.\n return {\n found: true,\n index: fuzzyIndex,\n matchLength: fuzzyOldText.length,\n usedFuzzyMatch: true,\n contentForReplacement: fuzzyContent,\n };\n}\n/** Strip UTF-8 BOM if present, return both the BOM (if any) and the text without it */\nexport function stripBom(content) {\n return content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\nfunction countOccurrences(content, oldText) {\n const fuzzyContent = normalizeForFuzzyMatch(content);\n const fuzzyOldText = normalizeForFuzzyMatch(oldText);\n return fuzzyContent.split(fuzzyOldText).length - 1;\n}\nfunction getNotFoundError(path, editIndex, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`);\n }\n return new Error(`Could not find edits[${editIndex}] in ${path}. The oldText must match exactly including all whitespace and newlines.`);\n}\nfunction getDuplicateError(path, editIndex, totalEdits, occurrences) {\n if (totalEdits === 1) {\n return new Error(`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`);\n }\n return new Error(`Found ${occurrences} occurrences of edits[${editIndex}] in ${path}. Each oldText must be unique. Please provide more context to make it unique.`);\n}\nfunction getEmptyOldTextError(path, editIndex, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`oldText must not be empty in ${path}.`);\n }\n return new Error(`edits[${editIndex}].oldText must not be empty in ${path}.`);\n}\nfunction getNoChangeError(path, totalEdits) {\n if (totalEdits === 1) {\n return new Error(`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`);\n }\n return new Error(`No changes made to ${path}. The replacements produced identical content.`);\n}\n/**\n * Apply one or more exact-text replacements to LF-normalized content.\n *\n * All edits are matched against the same original content. Replacements are\n * then applied in reverse order so offsets remain stable. If any edit needs\n * fuzzy matching, the operation runs in fuzzy-normalized content space and then\n * overlays those line-level changes onto the original content so unchanged line\n * blocks keep their original bytes.\n */\nexport function applyEditsToNormalizedContent(normalizedContent, edits, path) {\n const normalizedEdits = edits.map((edit) => ({\n oldText: normalizeToLF(edit.oldText),\n newText: normalizeToLF(edit.newText),\n }));\n for (let i = 0; i < normalizedEdits.length; i++) {\n if (normalizedEdits[i].oldText.length === 0) {\n throw getEmptyOldTextError(path, i, normalizedEdits.length);\n }\n }\n const initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));\n const usedFuzzyMatch = initialMatches.some((match) => match.usedFuzzyMatch);\n const replacementBaseContent = usedFuzzyMatch ? normalizeForFuzzyMatch(normalizedContent) : normalizedContent;\n const matchedEdits = [];\n for (let i = 0; i < normalizedEdits.length; i++) {\n const edit = normalizedEdits[i];\n const matchResult = fuzzyFindText(replacementBaseContent, edit.oldText);\n if (!matchResult.found) {\n throw getNotFoundError(path, i, normalizedEdits.length);\n }\n const occurrences = countOccurrences(replacementBaseContent, edit.oldText);\n if (occurrences > 1) {\n throw getDuplicateError(path, i, normalizedEdits.length, occurrences);\n }\n matchedEdits.push({\n editIndex: i,\n matchIndex: matchResult.index,\n matchLength: matchResult.matchLength,\n newText: edit.newText,\n });\n }\n matchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);\n for (let i = 1; i < matchedEdits.length; i++) {\n const previous = matchedEdits[i - 1];\n const current = matchedEdits[i];\n if (previous.matchIndex + previous.matchLength > current.matchIndex) {\n throw new Error(`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`);\n }\n }\n const baseContent = normalizedContent;\n const newContent = usedFuzzyMatch\n ? applyReplacementsPreservingUnchangedLines(normalizedContent, replacementBaseContent, matchedEdits)\n : applyReplacements(replacementBaseContent, matchedEdits);\n if (baseContent === newContent) {\n throw getNoChangeError(path, normalizedEdits.length);\n }\n return { baseContent, newContent };\n}\n/** Generate a standard unified patch. */\nexport function generateUnifiedPatch(path, oldContent, newContent, contextLines = 4) {\n return Diff.createTwoFilesPatch(path, path, oldContent, newContent, undefined, undefined, {\n context: contextLines,\n headerOptions: Diff.FILE_HEADERS_ONLY,\n });\n}\n/**\n * Generate a display-oriented diff string with line numbers and context.\n * Returns both the diff string and the first changed line number (in the new file).\n */\nexport function generateDiffString(oldContent, newContent, contextLines = 4) {\n const parts = Diff.diffLines(oldContent, newContent);\n const output = [];\n const oldLines = oldContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const maxLineNum = Math.max(oldLines.length, newLines.length);\n const lineNumWidth = String(maxLineNum).length;\n let oldLineNum = 1;\n let newLineNum = 1;\n let lastWasChange = false;\n let firstChangedLine;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const raw = part.value.split(\"\\n\");\n if (raw[raw.length - 1] === \"\") {\n raw.pop();\n }\n if (part.added || part.removed) {\n // Capture the first changed line (in the new file)\n if (firstChangedLine === undefined) {\n firstChangedLine = newLineNum;\n }\n // Show the change\n for (const line of raw) {\n if (part.added) {\n const lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n output.push(`+${lineNum} ${line}`);\n newLineNum++;\n }\n else {\n // removed\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(`-${lineNum} ${line}`);\n oldLineNum++;\n }\n }\n lastWasChange = true;\n }\n else {\n // Context lines - only show a few before/after changes\n const nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n const hasLeadingChange = lastWasChange;\n const hasTrailingChange = nextPartIsChange;\n if (hasLeadingChange && hasTrailingChange) {\n if (raw.length <= contextLines * 2) {\n for (const line of raw) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n else {\n const leadingLines = raw.slice(0, contextLines);\n const trailingLines = raw.slice(raw.length - contextLines);\n const skippedLines = raw.length - leadingLines.length - trailingLines.length;\n for (const line of leadingLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n for (const line of trailingLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n }\n else if (hasLeadingChange) {\n const shownLines = raw.slice(0, contextLines);\n const skippedLines = raw.length - shownLines.length;\n for (const line of shownLines) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n if (skippedLines > 0) {\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n }\n }\n else if (hasTrailingChange) {\n const skippedLines = Math.max(0, raw.length - contextLines);\n if (skippedLines > 0) {\n output.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n oldLineNum += skippedLines;\n newLineNum += skippedLines;\n }\n for (const line of raw.slice(skippedLines)) {\n const lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n output.push(` ${lineNum} ${line}`);\n oldLineNum++;\n newLineNum++;\n }\n }\n else {\n // Skip these context lines entirely\n oldLineNum += raw.length;\n newLineNum += raw.length;\n }\n lastWasChange = false;\n }\n }\n return { diff: output.join(\"\\n\"), firstChangedLine };\n}\n/**\n * Compute the diff for one or more edit operations without applying them.\n * Used for preview rendering in the TUI before the tool executes.\n */\nexport async function computeEditsDiff(path, edits, cwd) {\n const absolutePath = resolveToCwd(path, cwd);\n try {\n // Check if file exists and is readable\n try {\n await access(absolutePath, constants.R_OK);\n }\n catch (error) {\n const errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n return { error: `Could not edit file: ${path}. ${errorMessage}.` };\n }\n // Read the file\n const rawContent = await readFile(absolutePath, \"utf-8\");\n // Strip BOM before matching (LLM won't include invisible BOM in oldText)\n const { text: content } = stripBom(rawContent);\n const normalizedContent = normalizeToLF(content);\n const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n // Generate the diff\n return generateDiffString(baseContent, newContent);\n }\n catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n}\n/**\n * Compute the diff for a single edit operation without applying it.\n * Kept as a convenience wrapper for single-edit callers.\n */\nexport async function computeEditDiff(path, oldText, newText, cwd) {\n return computeEditsDiff(path, [{ oldText, newText }], cwd);\n}\n//# sourceMappingURL=edit-diff.js.map","// @ts-nocheck — vendored Pi source (core/tools/file-mutation-queue.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { realpath } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nconst fileMutationQueues = new Map();\nlet registrationQueue = Promise.resolve();\nfunction isMissingPathError(error) {\n return (typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error.code === \"ENOENT\" || error.code === \"ENOTDIR\"));\n}\nasync function getMutationQueueKey(filePath) {\n const resolvedPath = resolve(filePath);\n try {\n return await realpath(resolvedPath);\n }\n catch (error) {\n if (isMissingPathError(error)) {\n return resolvedPath;\n }\n throw error;\n }\n}\n/**\n * Serialize file mutation operations targeting the same file.\n * Operations for different files still run in parallel.\n */\nexport async function withFileMutationQueue(filePath, fn) {\n const registration = registrationQueue.then(async () => {\n const key = await getMutationQueueKey(filePath);\n const currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();\n let releaseNext;\n const nextQueue = new Promise((resolveQueue) => {\n releaseNext = resolveQueue;\n });\n const chainedQueue = currentQueue.then(() => nextQueue);\n fileMutationQueues.set(key, chainedQueue);\n return { key, currentQueue, chainedQueue, releaseNext };\n });\n registrationQueue = registration.then(() => undefined, () => undefined);\n const { key, currentQueue, chainedQueue, releaseNext } = await registration;\n await currentQueue;\n try {\n return await fn();\n }\n finally {\n releaseNext();\n if (fileMutationQueues.get(key) === chainedQueue) {\n fileMutationQueues.delete(key);\n }\n }\n}\n//# sourceMappingURL=file-mutation-queue.js.map","// @ts-nocheck — vendored Pi source (core/tools/edit.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { Box, Container, Spacer, Text } from '../../pi-tui.js';\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from \"fs/promises\";\nimport { Type } from \"typebox\";\nimport { renderDiff } from './diff-component.js';\nimport { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from \"./edit-diff.js\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { renderToolPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nconst replaceEditSchema = Type.Object({\n oldText: Type.String({\n description: \"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n }),\n newText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n}, {});\nconst editSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n edits: Type.Array(replaceEditSchema, {\n description: \"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n }),\n}, {});\nexport const editToolSystemPromptContribution = {\n snippet: \"Make precise file edits with exact text replacement, including multiple disjoint edits in one call\",\n guidelines: [\n \"Use edit for precise changes (edits[].oldText must match exactly)\",\n \"When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls\",\n \"Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.\",\n \"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.\",\n ],\n};\nconst defaultEditOperations = {\n readFile: (path) => fsReadFile(path),\n writeFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n access: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\nfunction prepareEditArguments(input) {\n if (!input || typeof input !== \"object\") {\n return input;\n }\n const args = input;\n // Some models (Opus 4.6, GLM-5.1) send edits as a JSON string instead of an array\n if (typeof args.edits === \"string\") {\n try {\n const parsed = JSON.parse(args.edits);\n if (Array.isArray(parsed))\n args.edits = parsed;\n }\n catch { }\n }\n const legacy = args;\n if (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") {\n return args;\n }\n const edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n edits.push({ oldText: legacy.oldText, newText: legacy.newText });\n const { oldText: _oldText, newText: _newText, ...rest } = legacy;\n return { ...rest, edits };\n}\nfunction validateEditInput(input) {\n if (!Array.isArray(input.edits) || input.edits.length === 0) {\n throw new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n }\n return { path: input.path, edits: input.edits };\n}\nfunction createEditCallRenderComponent() {\n return Object.assign(new Box(1, 1, (text) => text), {\n preview: undefined,\n previewArgsKey: undefined,\n previewPending: false,\n settledError: false,\n });\n}\nfunction getEditCallRenderComponent(state, lastComponent) {\n if (lastComponent instanceof Box) {\n const component = lastComponent;\n state.callComponent = component;\n return component;\n }\n if (state.callComponent) {\n return state.callComponent;\n }\n const component = createEditCallRenderComponent();\n state.callComponent = component;\n return component;\n}\nfunction getRenderablePreviewInput(args) {\n if (!args) {\n return null;\n }\n const path = typeof args.path === \"string\" ? args.path : typeof args.file_path === \"string\" ? args.file_path : null;\n if (!path) {\n return null;\n }\n if (Array.isArray(args.edits) &&\n args.edits.length > 0 &&\n args.edits.every((edit) => typeof edit?.oldText === \"string\" && typeof edit?.newText === \"string\")) {\n return { path, edits: args.edits };\n }\n if (typeof args.oldText === \"string\" && typeof args.newText === \"string\") {\n return { path, edits: [{ oldText: args.oldText, newText: args.newText }] };\n }\n return null;\n}\nfunction formatEditCall(args, theme, cwd) {\n const pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n return `${theme.fg(\"toolTitle\", theme.bold(\"edit\"))} ${pathDisplay}`;\n}\nfunction formatEditResult(args, preview, result, theme, isError) {\n const rawPath = str(args?.file_path ?? args?.path);\n const previewDiff = preview && !(\"error\" in preview) ? preview.diff : undefined;\n const previewError = preview && \"error\" in preview ? preview.error : undefined;\n if (isError) {\n const errorText = result.content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text || \"\")\n .join(\"\\n\");\n if (!errorText || errorText === previewError) {\n return undefined;\n }\n return theme.fg(\"error\", errorText);\n }\n const resultDiff = result.details?.diff;\n if (resultDiff && resultDiff !== previewDiff) {\n return renderDiff(resultDiff, { filePath: rawPath ?? undefined });\n }\n return undefined;\n}\nfunction getEditHeaderBg(preview, settledError, theme) {\n if (preview) {\n if (\"error\" in preview) {\n return (text) => theme.bg(\"toolErrorBg\", text);\n }\n return (text) => theme.bg(\"toolSuccessBg\", text);\n }\n if (settledError) {\n return (text) => theme.bg(\"toolErrorBg\", text);\n }\n return (text) => theme.bg(\"toolPendingBg\", text);\n}\nfunction buildEditCallComponent(component, args, theme, cwd) {\n component.setBgFn(getEditHeaderBg(component.preview, component.settledError, theme));\n component.clear();\n component.addChild(new Text(formatEditCall(args, theme, cwd), 0, 0));\n if (!component.preview) {\n return component;\n }\n const body = \"error\" in component.preview ? theme.fg(\"error\", component.preview.error) : renderDiff(component.preview.diff);\n component.addChild(new Spacer(1));\n component.addChild(new Text(body, 0, 0));\n return component;\n}\nfunction setEditPreview(component, preview, argsKey) {\n const current = component.preview;\n const changed = current === undefined ||\n (\"error\" in current && \"error\" in preview\n ? current.error !== preview.error\n : \"error\" in current !== \"error\" in preview) ||\n (!(\"error\" in current) &&\n !(\"error\" in preview) &&\n (current.diff !== preview.diff || current.firstChangedLine !== preview.firstChangedLine));\n component.preview = preview;\n component.previewArgsKey = argsKey;\n component.previewPending = false;\n return changed;\n}\nexport function createEditToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultEditOperations;\n return {\n name: \"edit\",\n label: \"edit\",\n description: \"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n promptSnippet: editToolSystemPromptContribution.snippet,\n promptGuidelines: [...editToolSystemPromptContribution.guidelines],\n parameters: editSchema,\n renderShell: \"self\",\n prepareArguments: prepareEditArguments,\n async execute(_toolCallId, input, signal, _onUpdate, _ctx) {\n const { path, edits } = validateEditInput(input);\n const absolutePath = resolveToCwd(path, cwd);\n return withFileMutationQueue(absolutePath, async () => {\n // Do not reject from an abort event listener here: that would release the\n // mutation queue while an in-flight filesystem operation may still finish.\n // Checking signal.aborted after each await observes the same aborts while\n // keeping the queue locked until the current operation has settled.\n const throwIfAborted = () => {\n if (signal?.aborted)\n throw new Error(\"Operation aborted\");\n };\n throwIfAborted();\n // Check if file exists.\n try {\n await ops.access(absolutePath);\n }\n catch (error) {\n throwIfAborted();\n const errorMessage = error instanceof Error && \"code\" in error ? `Error code: ${error.code}` : String(error);\n throw new Error(`Could not edit file: ${path}. ${errorMessage}.`);\n }\n throwIfAborted();\n // Read the file.\n const buffer = await ops.readFile(absolutePath);\n const rawContent = buffer.toString(\"utf-8\");\n throwIfAborted();\n // Strip BOM before matching. The model will not include an invisible BOM in oldText.\n const { bom, text: content } = stripBom(rawContent);\n const originalEnding = detectLineEnding(content);\n const normalizedContent = normalizeToLF(content);\n const { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n throwIfAborted();\n const finalContent = bom + restoreLineEndings(newContent, originalEnding);\n await ops.writeFile(absolutePath, finalContent);\n throwIfAborted();\n const diffResult = generateDiffString(baseContent, newContent);\n const patch = generateUnifiedPatch(path, baseContent, newContent);\n return {\n content: [\n {\n type: \"text\",\n text: `Successfully replaced ${edits.length} block(s) in ${path}.`,\n },\n ],\n details: { diff: diffResult.diff, patch, firstChangedLine: diffResult.firstChangedLine },\n };\n });\n },\n renderCall(args, theme, context) {\n const component = getEditCallRenderComponent(context.state, context.lastComponent);\n const previewInput = getRenderablePreviewInput(args);\n const argsKey = previewInput\n ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n : undefined;\n if (component.previewArgsKey !== argsKey) {\n component.preview = undefined;\n component.previewArgsKey = argsKey;\n component.previewPending = false;\n component.settledError = false;\n }\n if (context.argsComplete && previewInput && !component.preview && !component.previewPending) {\n component.previewPending = true;\n const requestKey = argsKey;\n void computeEditsDiff(previewInput.path, previewInput.edits, context.cwd).then((preview) => {\n if (component.previewArgsKey === requestKey) {\n setEditPreview(component, preview, requestKey);\n context.invalidate();\n }\n });\n }\n return buildEditCallComponent(component, args, theme, context.cwd);\n },\n renderResult(result, _options, theme, context) {\n const callComponent = context.state.callComponent;\n const previewInput = getRenderablePreviewInput(context.args);\n const argsKey = previewInput\n ? JSON.stringify({ path: previewInput.path, edits: previewInput.edits })\n : undefined;\n const typedResult = result;\n const resultDiff = !context.isError ? typedResult.details?.diff : undefined;\n let changed = false;\n if (callComponent) {\n if (typeof resultDiff === \"string\") {\n changed =\n setEditPreview(callComponent, { diff: resultDiff, firstChangedLine: typedResult.details?.firstChangedLine }, argsKey) || changed;\n }\n if (callComponent.settledError !== context.isError) {\n callComponent.settledError = context.isError;\n changed = true;\n }\n if (changed) {\n buildEditCallComponent(callComponent, context.args, theme, context.cwd);\n }\n }\n const output = formatEditResult(context.args, callComponent?.preview, typedResult, theme, context.isError);\n const component = context.lastComponent ?? new Container();\n component.clear();\n if (!output) {\n return component;\n }\n component.addChild(new Spacer(1));\n component.addChild(new Text(output, 1, 0));\n return component;\n },\n };\n}\nexport function createEditTool(cwd, options) {\n return wrapToolDefinition(createEditToolDefinition(cwd, options));\n}\n//# sourceMappingURL=edit.js.map","// @ts-nocheck — vendored Pi source (core/tools/write.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { Container, Text } from '../../pi-tui.js';\nimport { mkdir as fsMkdir, writeFile as fsWriteFile } from \"fs/promises\";\nimport { dirname } from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { getLanguageFromPath, highlightCode } from '../../pi-coding-agent.js';\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { normalizeDisplayText, renderToolPath, replaceTabs, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nconst writeSchema = Type.Object({\n path: Type.String({ description: \"Path to the file to write (relative or absolute)\" }),\n content: Type.String({ description: \"Content to write to the file\" }),\n});\nexport const writeToolSystemPromptContribution = {\n snippet: \"Create or overwrite files\",\n guidelines: [\"Use write only for new files or complete rewrites.\"],\n};\nconst defaultWriteOperations = {\n writeFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n mkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => { }),\n};\nclass WriteCallRenderComponent extends Text {\n cache;\n constructor() {\n super(\"\", 0, 0);\n }\n}\nconst WRITE_PARTIAL_FULL_HIGHLIGHT_LINES = 50;\nfunction highlightSingleLine(line, lang) {\n const highlighted = highlightCode(line, lang);\n return highlighted[0] ?? \"\";\n}\nfunction refreshWriteHighlightPrefix(cache) {\n const prefixCount = Math.min(WRITE_PARTIAL_FULL_HIGHLIGHT_LINES, cache.normalizedLines.length);\n if (prefixCount === 0)\n return;\n const prefixSource = cache.normalizedLines.slice(0, prefixCount).join(\"\\n\");\n const prefixHighlighted = highlightCode(prefixSource, cache.lang);\n for (let i = 0; i < prefixCount; i++) {\n cache.highlightedLines[i] =\n prefixHighlighted[i] ?? highlightSingleLine(cache.normalizedLines[i] ?? \"\", cache.lang);\n }\n}\nfunction rebuildWriteHighlightCacheFull(rawPath, fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n if (!lang)\n return undefined;\n const displayContent = normalizeDisplayText(fileContent);\n const normalized = replaceTabs(displayContent);\n return {\n rawPath,\n lang,\n rawContent: fileContent,\n normalizedLines: normalized.split(\"\\n\"),\n highlightedLines: highlightCode(normalized, lang),\n };\n}\nfunction updateWriteHighlightCacheIncremental(cache, rawPath, fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n if (!lang)\n return undefined;\n if (!cache)\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (cache.lang !== lang || cache.rawPath !== rawPath)\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (!fileContent.startsWith(cache.rawContent))\n return rebuildWriteHighlightCacheFull(rawPath, fileContent);\n if (fileContent.length === cache.rawContent.length)\n return cache;\n const deltaRaw = fileContent.slice(cache.rawContent.length);\n const deltaDisplay = normalizeDisplayText(deltaRaw);\n const deltaNormalized = replaceTabs(deltaDisplay);\n cache.rawContent = fileContent;\n if (cache.normalizedLines.length === 0) {\n cache.normalizedLines.push(\"\");\n cache.highlightedLines.push(\"\");\n }\n const segments = deltaNormalized.split(\"\\n\");\n const lastIndex = cache.normalizedLines.length - 1;\n cache.normalizedLines[lastIndex] += segments[0];\n cache.highlightedLines[lastIndex] = highlightSingleLine(cache.normalizedLines[lastIndex], cache.lang);\n for (let i = 1; i < segments.length; i++) {\n cache.normalizedLines.push(segments[i]);\n cache.highlightedLines.push(highlightSingleLine(segments[i], cache.lang));\n }\n refreshWriteHighlightPrefix(cache);\n return cache;\n}\nfunction trimTrailingEmptyLines(lines) {\n let end = lines.length;\n while (end > 0 && lines[end - 1] === \"\") {\n end--;\n }\n return lines.slice(0, end);\n}\nfunction formatWriteCall(args, options, theme, cache, cwd) {\n const rawPath = str(args?.file_path ?? args?.path);\n const fileContent = str(args?.content);\n const pathDisplay = renderToolPath(rawPath, theme, cwd);\n let text = `${theme.fg(\"toolTitle\", theme.bold(\"write\"))} ${pathDisplay}`;\n if (fileContent === null) {\n text += `\\n\\n${theme.fg(\"error\", \"[invalid content arg - expected string]\")}`;\n }\n else if (fileContent) {\n const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n const renderedLines = lang\n ? (cache?.highlightedLines ?? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang))\n : normalizeDisplayText(fileContent).split(\"\\n\");\n const lines = trimTrailingEmptyLines(renderedLines);\n const totalLines = lines.length;\n const maxLines = options.expanded ? lines.length : 10;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n\\n${displayLines.map((line) => (lang ? line : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines, ${totalLines} total,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n return text;\n}\nfunction formatWriteResult(result, theme) {\n if (!result.isError) {\n return undefined;\n }\n const output = result.content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text || \"\")\n .join(\"\\n\");\n if (!output) {\n return undefined;\n }\n return `\\n${theme.fg(\"error\", output)}`;\n}\nexport function createWriteToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultWriteOperations;\n return {\n name: \"write\",\n label: \"write\",\n description: \"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.\",\n promptSnippet: writeToolSystemPromptContribution.snippet,\n promptGuidelines: [...writeToolSystemPromptContribution.guidelines],\n parameters: writeSchema,\n async execute(_toolCallId, { path, content }, signal, _onUpdate, _ctx) {\n const absolutePath = resolveToCwd(path, cwd);\n const dir = dirname(absolutePath);\n return withFileMutationQueue(absolutePath, async () => {\n // Do not reject from an abort event listener here: that would release the\n // mutation queue while an in-flight filesystem operation may still finish.\n // Checking signal.aborted after each await observes the same aborts while\n // keeping the queue locked until the current operation has settled.\n const throwIfAborted = () => {\n if (signal?.aborted)\n throw new Error(\"Operation aborted\");\n };\n throwIfAborted();\n // Create parent directories if needed.\n await ops.mkdir(dir);\n throwIfAborted();\n // Write the file contents.\n await ops.writeFile(absolutePath, content);\n throwIfAborted();\n return {\n content: [{ type: \"text\", text: `Successfully wrote ${content.length} bytes to ${path}` }],\n details: undefined,\n };\n });\n },\n renderCall(args, theme, context) {\n const renderArgs = args;\n const rawPath = str(renderArgs?.file_path ?? renderArgs?.path);\n const fileContent = str(renderArgs?.content);\n const component = context.lastComponent ?? new WriteCallRenderComponent();\n if (fileContent !== null) {\n component.cache = context.argsComplete\n ? rebuildWriteHighlightCacheFull(rawPath, fileContent)\n : updateWriteHighlightCacheIncremental(component.cache, rawPath, fileContent);\n }\n else {\n component.cache = undefined;\n }\n component.setText(formatWriteCall(renderArgs, { expanded: context.expanded, isPartial: context.isPartial }, theme, component.cache, context.cwd));\n return component;\n },\n renderResult(result, _options, theme, context) {\n const output = formatWriteResult({ ...result, isError: context.isError }, theme);\n if (!output) {\n const component = context.lastComponent ?? new Container();\n component.clear();\n return component;\n }\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(output);\n return text;\n },\n };\n}\nexport function createWriteTool(cwd, options) {\n return wrapToolDefinition(createWriteToolDefinition(cwd, options));\n}\n//# sourceMappingURL=write.js.map","// @ts-nocheck — vendored Pi source (core/tools/grep.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport { Text } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { ensureTool } from '../../pi-coding-agent.js';\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, GREP_MAX_LINE_LENGTH, truncateHead, truncateLine, } from \"./truncate.js\";\nconst grepSchema = Type.Object({\n pattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n path: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n glob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n ignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n literal: Type.Optional(Type.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" })),\n context: Type.Optional(Type.Number({ description: \"Number of lines to show before and after each match (default: 0)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\nexport const grepToolSystemPromptContribution = {\n snippet: \"Search file contents for patterns (respects .gitignore)\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 100;\nconst defaultGrepOperations = {\n isDirectory: async (p) => (await fsStat(p)).isDirectory(),\n readFile: (p) => fsReadFile(p, \"utf-8\"),\n};\nfunction formatGrepCall(args, theme) {\n const pattern = str(args?.pattern);\n const rawPath = str(args?.path);\n const path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n const glob = str(args?.glob);\n const limit = args?.limit;\n const invalidArg = invalidArgText(theme);\n let text = theme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n \" \" +\n (pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n theme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n if (glob)\n text += theme.fg(\"toolOutput\", ` (${glob})`);\n if (limit !== undefined)\n text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n return text;\n}\nfunction formatGrepResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 15;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const matchLimit = result.details?.matchLimitReached;\n const truncation = result.details?.truncation;\n const linesTruncated = result.details?.linesTruncated;\n if (matchLimit || truncation?.truncated || linesTruncated) {\n const warnings = [];\n if (matchLimit)\n warnings.push(`${matchLimit} matches limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n if (linesTruncated)\n warnings.push(\"some lines truncated\");\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createGrepToolDefinition(cwd, options) {\n const customOps = options?.operations;\n return {\n name: \"grep\",\n label: \"grep\",\n description: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n promptSnippet: grepToolSystemPromptContribution.snippet,\n parameters: grepSchema,\n async execute(_toolCallId, { pattern, path: searchDir, glob, ignoreCase, literal, context, limit, }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let settled = false;\n const settle = (fn) => {\n if (!settled) {\n settled = true;\n fn();\n }\n };\n (async () => {\n try {\n const rgPath = await ensureTool(\"rg\", true);\n if (!rgPath) {\n settle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n return;\n }\n const searchPath = resolveToCwd(searchDir || \".\", cwd);\n const ops = customOps ?? defaultGrepOperations;\n let isDirectory;\n try {\n isDirectory = await ops.isDirectory(searchPath);\n }\n catch {\n settle(() => reject(new Error(`Path not found: ${searchPath}`)));\n return;\n }\n const contextValue = context && context > 0 ? context : 0;\n const effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n const formatPath = (filePath) => {\n if (isDirectory) {\n const relative = path.relative(searchPath, filePath);\n if (relative && !relative.startsWith(\"..\")) {\n return relative.replace(/\\\\/g, \"/\");\n }\n }\n return path.basename(filePath);\n };\n const fileCache = new Map();\n const getFileLines = async (filePath) => {\n let lines = fileCache.get(filePath);\n if (!lines) {\n try {\n const content = await ops.readFile(filePath);\n lines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n }\n catch {\n lines = [];\n }\n fileCache.set(filePath, lines);\n }\n return lines;\n };\n const args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n if (ignoreCase)\n args.push(\"--ignore-case\");\n if (literal)\n args.push(\"--fixed-strings\");\n if (glob)\n args.push(\"--glob\", glob);\n args.push(\"--\", pattern, searchPath);\n const child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const rl = createInterface({ input: child.stdout });\n let stderr = \"\";\n let matchCount = 0;\n let matchLimitReached = false;\n let linesTruncated = false;\n let aborted = false;\n let killedDueToLimit = false;\n const outputLines = [];\n const cleanup = () => {\n rl.close();\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const stopChild = (dueToLimit = false) => {\n if (!child.killed) {\n killedDueToLimit = dueToLimit;\n child.kill();\n }\n };\n const onAbort = () => {\n aborted = true;\n stopChild();\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n const formatBlock = async (filePath, lineNumber) => {\n const relativePath = formatPath(filePath);\n const lines = await getFileLines(filePath);\n if (!lines.length)\n return [`${relativePath}:${lineNumber}: (unable to read file)`];\n const block = [];\n const start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n const end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n for (let current = start; current <= end; current++) {\n const lineText = lines[current - 1] ?? \"\";\n const sanitized = lineText.replace(/\\r/g, \"\");\n const isMatchLine = current === lineNumber;\n // Truncate long lines so grep output stays compact.\n const { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n if (wasTruncated)\n linesTruncated = true;\n if (isMatchLine)\n block.push(`${relativePath}:${current}: ${truncatedText}`);\n else\n block.push(`${relativePath}-${current}- ${truncatedText}`);\n }\n return block;\n };\n // Collect matches during streaming, then format them after rg exits.\n const matches = [];\n rl.on(\"line\", (line) => {\n if (!line.trim() || matchCount >= effectiveLimit)\n return;\n let event;\n try {\n event = JSON.parse(line);\n }\n catch {\n return;\n }\n if (event.type === \"match\") {\n matchCount++;\n const filePath = event.data?.path?.text;\n const lineNumber = event.data?.line_number;\n const lineText = event.data?.lines?.text;\n if (filePath && typeof lineNumber === \"number\")\n matches.push({ filePath, lineNumber, lineText });\n if (matchCount >= effectiveLimit) {\n matchLimitReached = true;\n stopChild(true);\n }\n }\n });\n child.on(\"error\", (error) => {\n cleanup();\n settle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n });\n child.on(\"close\", async (code) => {\n cleanup();\n if (aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (!killedDueToLimit && code !== 0 && code !== 1) {\n const errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n settle(() => reject(new Error(errorMsg)));\n return;\n }\n if (matchCount === 0) {\n settle(() => resolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }));\n return;\n }\n // Format matches after streaming finishes so custom readFile() backends can be async.\n for (const match of matches) {\n if (contextValue === 0 && match.lineText !== undefined) {\n const relativePath = formatPath(match.filePath);\n const sanitized = match.lineText\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\")\n .replace(/\\n$/, \"\");\n const { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n if (wasTruncated)\n linesTruncated = true;\n outputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n }\n else {\n const block = await formatBlock(match.filePath, match.lineNumber);\n outputLines.push(...block);\n }\n }\n const rawOutput = outputLines.join(\"\\n\");\n // Apply byte truncation. There is no line limit here because the match limit already capped rows.\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let output = truncation.content;\n const details = {};\n // Build actionable notices for truncation and match limits.\n const notices = [];\n if (matchLimitReached) {\n notices.push(`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);\n details.matchLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (linesTruncated) {\n notices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n details.linesTruncated = true;\n }\n if (notices.length > 0)\n output += `\\n\\n[${notices.join(\". \")}]`;\n settle(() => resolve({\n content: [{ type: \"text\", text: output }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n });\n }\n catch (err) {\n settle(() => reject(err));\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatGrepCall(args, theme));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatGrepResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createGrepTool(cwd, options) {\n return wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n//# sourceMappingURL=grep.js.map","// @ts-nocheck — vendored Pi source (core/tools/find.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { createInterface } from \"node:readline\";\nimport { Text } from '../../pi-tui.js';\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { ensureTool } from '../../pi-coding-agent.js';\nimport { pathExists, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, truncateHead } from \"./truncate.js\";\n/** Relativize a find result against the search root and normalize it to posix separators. */\nexport function relativizeFindResultPath(resultPath, searchPath, pathModule = path) {\n const hadTrailingSeparator = resultPath.endsWith(pathModule.sep) || (pathModule.sep === \"\\\\\" && resultPath.endsWith(\"/\"));\n const relativePath = pathModule.isAbsolute(resultPath) ? pathModule.relative(searchPath, resultPath) : resultPath;\n const posixPath = relativePath.split(pathModule.sep).join(\"/\");\n return hadTrailingSeparator && !posixPath.endsWith(\"/\") ? `${posixPath}/` : posixPath;\n}\nconst findSchema = Type.Object({\n pattern: Type.String({\n description: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n }),\n path: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\nexport const findToolSystemPromptContribution = {\n snippet: \"Find files by glob pattern (respects .gitignore)\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 1000;\nconst defaultFindOperations = {\n exists: pathExists,\n // This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.\n glob: () => [],\n};\nfunction formatFindCall(args, theme) {\n const pattern = str(args?.pattern);\n const rawPath = str(args?.path);\n const path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n const limit = args?.limit;\n const invalidArg = invalidArgText(theme);\n let text = theme.fg(\"toolTitle\", theme.bold(\"find\")) +\n \" \" +\n (pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n theme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n if (limit !== undefined) {\n text += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n }\n return text;\n}\nfunction formatFindResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 20;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const resultLimit = result.details?.resultLimitReached;\n const truncation = result.details?.truncation;\n if (resultLimit || truncation?.truncated) {\n const warnings = [];\n if (resultLimit)\n warnings.push(`${resultLimit} results limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createFindToolDefinition(cwd, options) {\n const customOps = options?.operations;\n return {\n name: \"find\",\n label: \"find\",\n description: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n promptSnippet: findToolSystemPromptContribution.snippet,\n parameters: findSchema,\n async execute(_toolCallId, { pattern, path: searchDir, limit }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n let settled = false;\n let stopChild;\n const settle = (fn) => {\n if (settled)\n return;\n settled = true;\n signal?.removeEventListener(\"abort\", onAbort);\n stopChild = undefined;\n fn();\n };\n const onAbort = () => {\n stopChild?.();\n settle(() => reject(new Error(\"Operation aborted\")));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const searchPath = resolveToCwd(searchDir || \".\", cwd);\n const effectiveLimit = limit ?? DEFAULT_LIMIT;\n const ops = customOps ?? defaultFindOperations;\n // If custom operations provide glob(), use that instead of fd.\n if (customOps?.glob) {\n if (!(await ops.exists(searchPath))) {\n settle(() => reject(new Error(`Path not found: ${searchPath}`)));\n return;\n }\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const results = await ops.glob(pattern, searchPath, {\n ignore: [\"**/node_modules/**\", \"**/.git/**\"],\n limit: effectiveLimit,\n });\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (results.length === 0) {\n settle(() => resolve({\n content: [{ type: \"text\", text: \"No files found matching pattern\" }],\n details: undefined,\n }));\n return;\n }\n // Relativize paths against the search root for stable output.\n const relativized = results.map((p) => relativizeFindResultPath(p, searchPath));\n const resultLimitReached = relativized.length >= effectiveLimit;\n const rawOutput = relativized.join(\"\\n\");\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let resultOutput = truncation.content;\n const details = {};\n const notices = [];\n if (resultLimitReached) {\n notices.push(`${effectiveLimit} results limit reached`);\n details.resultLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n resultOutput += `\\n\\n[${notices.join(\". \")}]`;\n }\n settle(() => resolve({\n content: [{ type: \"text\", text: resultOutput }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n return;\n }\n // Default implementation uses fd.\n const fdPath = await ensureTool(\"fd\", true);\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n if (!fdPath) {\n settle(() => reject(new Error(\"fd is not available and could not be downloaded\")));\n return;\n }\n const args = [\"--glob\", \"--color=never\", \"--hidden\"];\n // fd normally ignores .gitignore outside git repos, so keep --no-require-git\n // there. Inside repos, use fd's default git-aware behavior so parent\n // .gitignore rules stop at nested repo boundaries:\n // https://github.com/earendil-works/pi/issues/5960\n let insideGitRepo = false;\n for (let current = searchPath;;) {\n if (await pathExists(path.join(current, \".git\"))) {\n insideGitRepo = true;\n break;\n }\n const parent = path.dirname(current);\n if (parent === current)\n break;\n current = parent;\n }\n if (!insideGitRepo)\n args.push(\"--no-require-git\");\n args.push(\"--max-results\", String(effectiveLimit));\n // fd --glob matches against the basename unless --full-path is set; in --full-path\n // mode it matches against the absolute candidate path, so a path-containing\n // pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.\n let effectivePattern = pattern;\n if (pattern.includes(\"/\")) {\n args.push(\"--full-path\");\n if (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n effectivePattern = `**/${pattern}`;\n }\n // fd matches full paths using native separators on Windows.\n if (process.platform === \"win32\")\n effectivePattern = effectivePattern.replaceAll(\"/\", String.raw `[/\\\\]`);\n }\n args.push(\"--\", effectivePattern, searchPath);\n const child = spawn(fdPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const rl = createInterface({ input: child.stdout });\n let stderr = \"\";\n const lines = [];\n stopChild = () => {\n if (!child.killed) {\n child.kill();\n }\n };\n const cleanup = () => {\n rl.close();\n };\n child.stderr?.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n rl.on(\"line\", (line) => {\n lines.push(line);\n });\n child.on(\"error\", (error) => {\n cleanup();\n settle(() => reject(new Error(`Failed to run fd: ${error.message}`)));\n });\n child.on(\"close\", (code) => {\n cleanup();\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const output = lines.join(\"\\n\");\n if (code !== 0) {\n const errorMsg = stderr.trim() || `fd exited with code ${code}`;\n if (!output) {\n settle(() => reject(new Error(errorMsg)));\n return;\n }\n }\n if (!output) {\n settle(() => resolve({\n content: [{ type: \"text\", text: \"No files found matching pattern\" }],\n details: undefined,\n }));\n return;\n }\n const relativized = [];\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\r$/, \"\").trim();\n if (!line)\n continue;\n relativized.push(relativizeFindResultPath(line, searchPath));\n }\n const resultLimitReached = relativized.length >= effectiveLimit;\n const rawOutput = relativized.join(\"\\n\");\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let resultOutput = truncation.content;\n const details = {};\n const notices = [];\n if (resultLimitReached) {\n notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);\n details.resultLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n resultOutput += `\\n\\n[${notices.join(\". \")}]`;\n }\n settle(() => resolve({\n content: [{ type: \"text\", text: resultOutput }],\n details: Object.keys(details).length > 0 ? details : undefined,\n }));\n });\n }\n catch (e) {\n if (signal?.aborted) {\n settle(() => reject(new Error(\"Operation aborted\")));\n return;\n }\n const error = e instanceof Error ? e : new Error(String(e));\n settle(() => reject(error));\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatFindCall(args, theme));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatFindResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createFindTool(cwd, options) {\n return wrapToolDefinition(createFindToolDefinition(cwd, options));\n}\n//# sourceMappingURL=find.js.map","// @ts-nocheck — vendored Pi source (core/tools/ls.js @0.84.1, MIT, see ../PI-LICENSE);\n// imports remapped to pi2dsh shims, logic byte-identical.\nimport { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport { Text } from '../../pi-tui.js';\nimport nodePath from \"path\";\nimport { Type } from \"typebox\";\nimport { keyHint } from '../../pi-coding-agent.js';\nimport { pathExists, resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, renderToolPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport { DEFAULT_MAX_BYTES, formatSize, truncateHead } from \"./truncate.js\";\nconst lsSchema = Type.Object({\n path: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n limit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n});\nexport const lsToolSystemPromptContribution = {\n snippet: \"List directory contents\",\n guidelines: [],\n};\nconst DEFAULT_LIMIT = 500;\nconst defaultLsOperations = {\n exists: pathExists,\n stat: fsStat,\n readdir: fsReaddir,\n};\nfunction formatLsCall(args, theme, cwd) {\n const limit = args?.limit;\n const pathDisplay = renderToolPath(str(args?.path), theme, cwd, { emptyFallback: \".\" });\n let text = `${theme.fg(\"toolTitle\", theme.bold(\"ls\"))} ${pathDisplay}`;\n if (limit !== undefined) {\n text += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n }\n return text;\n}\nfunction formatLsResult(result, options, theme, showImages) {\n const output = getTextOutput(result, showImages).trim();\n let text = \"\";\n if (output) {\n const lines = output.split(\"\\n\");\n const maxLines = options.expanded ? lines.length : 20;\n const displayLines = lines.slice(0, maxLines);\n const remaining = lines.length - maxLines;\n text += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n if (remaining > 0) {\n text += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n }\n }\n const entryLimit = result.details?.entryLimitReached;\n const truncation = result.details?.truncation;\n if (entryLimit || truncation?.truncated) {\n const warnings = [];\n if (entryLimit)\n warnings.push(`${entryLimit} entries limit`);\n if (truncation?.truncated)\n warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n text += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n }\n return text;\n}\nexport function createLsToolDefinition(cwd, options) {\n const ops = options?.operations ?? defaultLsOperations;\n return {\n name: \"ls\",\n label: \"ls\",\n description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n promptSnippet: lsToolSystemPromptContribution.snippet,\n parameters: lsSchema,\n async execute(_toolCallId, { path, limit }, signal, _onUpdate, _ctx) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error(\"Operation aborted\"));\n return;\n }\n const onAbort = () => reject(new Error(\"Operation aborted\"));\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n (async () => {\n try {\n const dirPath = resolveToCwd(path || \".\", cwd);\n const effectiveLimit = limit ?? DEFAULT_LIMIT;\n // Check if path exists.\n if (!(await ops.exists(dirPath))) {\n reject(new Error(`Path not found: ${dirPath}`));\n return;\n }\n // Check if path is a directory.\n const stat = await ops.stat(dirPath);\n if (!stat.isDirectory()) {\n reject(new Error(`Not a directory: ${dirPath}`));\n return;\n }\n // Read directory entries.\n let entries;\n try {\n entries = await ops.readdir(dirPath);\n }\n catch (e) {\n reject(new Error(`Cannot read directory: ${e.message}`));\n return;\n }\n // Sort alphabetically, case-insensitive.\n entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n // Format entries with directory indicators.\n const results = [];\n let entryLimitReached = false;\n for (const entry of entries) {\n if (results.length >= effectiveLimit) {\n entryLimitReached = true;\n break;\n }\n const fullPath = nodePath.join(dirPath, entry);\n let suffix = \"\";\n try {\n const entryStat = await ops.stat(fullPath);\n if (entryStat.isDirectory())\n suffix = \"/\";\n }\n catch {\n // Skip entries we cannot stat.\n continue;\n }\n results.push(entry + suffix);\n }\n signal?.removeEventListener(\"abort\", onAbort);\n if (results.length === 0) {\n resolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n return;\n }\n const rawOutput = results.join(\"\\n\");\n // Apply byte truncation. There is no separate line limit because entry count is already capped.\n const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n let output = truncation.content;\n const details = {};\n // Build actionable notices for truncation and entry limits.\n const notices = [];\n if (entryLimitReached) {\n notices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n details.entryLimitReached = effectiveLimit;\n }\n if (truncation.truncated) {\n notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n details.truncation = truncation;\n }\n if (notices.length > 0) {\n output += `\\n\\n[${notices.join(\". \")}]`;\n }\n resolve({\n content: [{ type: \"text\", text: output }],\n details: Object.keys(details).length > 0 ? details : undefined,\n });\n }\n catch (e) {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(e);\n }\n })();\n });\n },\n renderCall(args, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatLsCall(args, theme, context.cwd));\n return text;\n },\n renderResult(result, options, theme, context) {\n const text = context.lastComponent ?? new Text(\"\", 0, 0);\n text.setText(formatLsResult(result, options, theme, context.showImages));\n return text;\n },\n };\n}\nexport function createLsTool(cwd, options) {\n return wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n//# sourceMappingURL=ls.js.map","// @ts-nocheck — vendored Pi source (MIT, see ./PI-LICENSE); logic unchanged.\n// Sources @6f707eb36064e82af9c1320a7634f4dfad21049b:\n// coding-agent src/core/compaction/utils.ts (file-op tracking, serialization, system prompt)\n// coding-agent src/core/compaction/compaction.ts (token estimation, cut points, summarization)\n// coding-agent src/core/compaction/branch-summarization.ts (branch summaries)\n// pi-ai 0.84.1 dist/utils/text.js (contentText)\n// One deliberate seam, marked below: Pi's completeSummarization falls back to the\n// provider-SDK completeSimple() when no streamFn is given. In pi2dsh every model\n// call goes through the host llm bridge, so the pi2dsh export layer always\n// injects a bridge streamFn; reaching the fallback without one fails loud.\nimport { retryAssistantCall } from './pi-ai-retry.js'\nimport { uuidv7 } from './pi-uuid.js'\nimport {\n createBranchSummaryMessage,\n createCompactionSummaryMessage,\n createCustomMessage,\n convertToLlm,\n} from './pi-messages.js'\nimport { buildSessionContext, sessionEntryToContextMessages } from './pi-session-manager.js'\n\n// ---- pi-ai utils/text.js ---------------------------------------------------\n\nexport function contentText(content, separator = '\\n') {\n if (typeof content === 'string') return content\n return content\n .filter(block => block.type === 'text')\n .map(block => block.text)\n .join(separator)\n}\n\n// ---- compaction/utils.ts ---------------------------------------------------\n\nexport interface FileOperations {\n read: Set<string>\n written: Set<string>\n edited: Set<string>\n}\n\nexport function createFileOps(): FileOperations {\n return {\n read: new Set(),\n written: new Set(),\n edited: new Set(),\n }\n}\n\n/**\n * Extract file operations from tool calls in an assistant message.\n */\nexport function extractFileOpsFromMessage(message, fileOps: FileOperations): void {\n if (message.role !== 'assistant') return\n if (!('content' in message) || !Array.isArray(message.content)) return\n\n for (const block of message.content) {\n if (typeof block !== 'object' || block === null) continue\n if (!('type' in block) || block.type !== 'toolCall') continue\n if (!('arguments' in block) || !('name' in block)) continue\n\n const args = block.arguments\n if (!args) continue\n\n const path = typeof args.path === 'string' ? args.path : undefined\n if (!path) continue\n\n switch (block.name) {\n case 'read':\n fileOps.read.add(path)\n break\n case 'write':\n fileOps.written.add(path)\n break\n case 'edit':\n fileOps.edited.add(path)\n break\n }\n }\n}\n\n/**\n * Compute final file lists from file operations.\n * Returns readFiles (files only read, not modified) and modifiedFiles.\n */\nexport function computeFileLists(fileOps: FileOperations): { readFiles: string[]; modifiedFiles: string[] } {\n const modified = new Set([...fileOps.edited, ...fileOps.written])\n const readOnly = [...fileOps.read].filter(f => !modified.has(f)).sort()\n const modifiedFiles = [...modified].sort()\n return { readFiles: readOnly, modifiedFiles }\n}\n\n/**\n * Format file operations as XML tags for summary.\n */\nexport function formatFileOperations(readFiles: string[], modifiedFiles: string[]): string {\n const sections: string[] = []\n if (readFiles.length > 0) {\n sections.push(`<read-files>\\n${readFiles.join('\\n')}\\n</read-files>`)\n }\n if (modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${modifiedFiles.join('\\n')}\\n</modified-files>`)\n }\n if (sections.length === 0) return ''\n return `\\n\\n${sections.join('\\n\\n')}`\n}\n\n/** Maximum characters for a tool result in serialized summaries. */\nconst TOOL_RESULT_MAX_CHARS = 2000\n\n/**\n * Truncate text to a maximum character length for summarization.\n * Keeps the beginning and appends a truncation marker.\n */\nfunction truncateForSummary(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n const truncatedChars = text.length - maxChars\n return `${text.slice(0, maxChars)}\\n\\n[... ${truncatedChars} more characters truncated]`\n}\n\n/**\n * Serialize LLM messages to text for summarization.\n * This prevents the model from treating it as a conversation to continue.\n * Call convertToLlm() first to handle custom message types.\n *\n * Tool results are truncated to keep the summarization request within\n * reasonable token budgets. Full content is not needed for summarization.\n */\nexport function serializeConversation(messages): string {\n const parts: string[] = []\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n const content = contentText(msg.content, '')\n if (content) parts.push(`[User]: ${content}`)\n } else if (msg.role === 'assistant') {\n const thinkingParts: string[] = []\n const toolCalls: string[] = []\n\n for (const block of msg.content) {\n if (block.type === 'thinking') {\n thinkingParts.push(block.thinking)\n } else if (block.type === 'toolCall') {\n const args = block.arguments\n const argsStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(', ')\n toolCalls.push(`${block.name}(${argsStr})`)\n }\n }\n\n if (thinkingParts.length > 0) {\n parts.push(`[Assistant thinking]: ${thinkingParts.join('\\n')}`)\n }\n if (msg.content.some(block => block.type === 'text')) {\n parts.push(`[Assistant]: ${contentText(msg.content)}`)\n }\n if (toolCalls.length > 0) {\n parts.push(`[Assistant tool calls]: ${toolCalls.join('; ')}`)\n }\n } else if (msg.role === 'toolResult') {\n const content = contentText(msg.content, '')\n if (content) {\n parts.push(`[Tool result]: ${truncateForSummary(content, TOOL_RESULT_MAX_CHARS)}`)\n }\n }\n }\n\n return parts.join('\\n\\n')\n}\n\nexport const SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`\n\n// ---- compaction/compaction.ts ----------------------------------------------\n\nconst ESTIMATED_IMAGE_CHARS = 4800\n\nfunction estimateTextAndImageContentChars(content): number {\n if (typeof content === 'string') {\n return content.length\n }\n\n let chars = 0\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length\n } else if (block.type === 'image') {\n chars += ESTIMATED_IMAGE_CHARS\n }\n }\n return chars\n}\n\n/**\n * Estimate token count for a message using chars/4 heuristic.\n * This is conservative (overestimates tokens).\n */\nexport function estimateTokens(message): number {\n let chars = 0\n\n switch (message.role) {\n case 'user': {\n chars = estimateTextAndImageContentChars(message.content)\n return Math.ceil(chars / 4)\n }\n case 'assistant': {\n const assistant = message\n for (const block of assistant.content) {\n if (block.type === 'text') {\n chars += block.text.length\n } else if (block.type === 'thinking') {\n chars += block.thinking.length\n } else if (block.type === 'toolCall') {\n chars += block.name.length + JSON.stringify(block.arguments).length\n }\n }\n return Math.ceil(chars / 4)\n }\n case 'custom':\n case 'toolResult': {\n chars = estimateTextAndImageContentChars(message.content)\n return Math.ceil(chars / 4)\n }\n case 'bashExecution': {\n chars = message.command.length + message.output.length\n return Math.ceil(chars / 4)\n }\n case 'branchSummary':\n case 'compactionSummary': {\n chars = message.summary.length\n return Math.ceil(chars / 4)\n }\n }\n\n return 0\n}\n\nfunction isCutPointMessage(message): boolean {\n switch (message.role) {\n case 'user':\n case 'assistant':\n case 'bashExecution':\n case 'custom':\n case 'branchSummary':\n case 'compactionSummary':\n return true\n case 'toolResult':\n return false\n }\n return false\n}\n\nfunction isTurnStartMessage(message): boolean {\n switch (message.role) {\n case 'user':\n case 'bashExecution':\n case 'custom':\n case 'branchSummary':\n case 'compactionSummary':\n return true\n case 'assistant':\n case 'toolResult':\n return false\n }\n return false\n}\n\nfunction isTurnStartEntry(entry): boolean {\n if (entry.type === 'compaction') {\n return false\n }\n return sessionEntryToContextMessages(entry).some(isTurnStartMessage)\n}\n\n/**\n * Find valid cut points: indices of context-visible user-like or assistant messages.\n * Never cut at tool results (they must follow their tool call).\n * When we cut at an assistant message with tool calls, its tool results follow it\n * and will be kept.\n */\nfunction findValidCutPoints(entries, startIndex: number, endIndex: number): number[] {\n const cutPoints: number[] = []\n for (let i = startIndex; i < endIndex; i++) {\n const entry = entries[i]\n if (entry.type === 'compaction') {\n continue\n }\n if (sessionEntryToContextMessages(entry).some(isCutPointMessage)) {\n cutPoints.push(i)\n }\n }\n return cutPoints\n}\n\n/**\n * Find the context-visible user-role message that starts the turn containing the given entry index.\n * Returns -1 if no turn start found before the index.\n */\nexport function findTurnStartIndex(entries, entryIndex: number, startIndex: number): number {\n for (let i = entryIndex; i >= startIndex; i--) {\n if (isTurnStartEntry(entries[i])) {\n return i\n }\n }\n return -1\n}\n\nexport interface CutPointResult {\n /** Index of first entry to keep */\n firstKeptEntryIndex: number\n /** Index of user message that starts the turn being split, or -1 if not splitting */\n turnStartIndex: number\n /** Whether this cut splits a turn (cut point is not a user message) */\n isSplitTurn: boolean\n}\n\n/**\n * Find the cut point in session entries that keeps approximately `keepRecentTokens`.\n *\n * Algorithm: Walk backwards from newest, accumulating estimated message sizes.\n * Stop when we've accumulated >= keepRecentTokens. Cut at that point.\n *\n * Can cut at user OR assistant messages (never tool results). When cutting at an\n * assistant message with tool calls, its tool results come after and will be kept.\n *\n * Returns CutPointResult with:\n * - firstKeptEntryIndex: the entry index to start keeping from\n * - turnStartIndex: if cutting mid-turn, the user message that started that turn\n * - isSplitTurn: whether we're cutting in the middle of a turn\n *\n * Only considers entries between `startIndex` and `endIndex` (exclusive).\n */\nexport function findCutPoint(\n entries,\n startIndex: number,\n endIndex: number,\n keepRecentTokens: number,\n): CutPointResult {\n const cutPoints = findValidCutPoints(entries, startIndex, endIndex)\n\n if (cutPoints.length === 0) {\n return { firstKeptEntryIndex: startIndex, turnStartIndex: -1, isSplitTurn: false }\n }\n\n // Walk backwards from newest, accumulating estimated message sizes\n let accumulatedTokens = 0\n let cutIndex = cutPoints[0] // Default: keep from first message (not header)\n\n for (let i = endIndex - 1; i >= startIndex; i--) {\n const entry = entries[i]\n const messageTokens = sessionEntryToContextMessages(entry).reduce(\n (sum, message) => sum + estimateTokens(message),\n 0,\n )\n if (messageTokens === 0) continue\n accumulatedTokens += messageTokens\n\n // Check if we've exceeded the budget\n if (accumulatedTokens >= keepRecentTokens) {\n // Find the closest valid cut point at or after this entry\n for (let c = 0; c < cutPoints.length; c++) {\n if (cutPoints[c] >= i) {\n cutIndex = cutPoints[c]\n break\n }\n }\n break\n }\n }\n\n // Scan backwards from cutIndex to include adjacent metadata entries that do not affect context.\n while (cutIndex > startIndex) {\n const prevEntry = entries[cutIndex - 1]\n // Stop at compaction boundaries or context-visible entries.\n if (prevEntry.type === 'compaction' || sessionEntryToContextMessages(prevEntry).length > 0) {\n break\n }\n cutIndex--\n }\n\n // Determine if this is a split turn\n const cutEntry = entries[cutIndex]\n const startsTurn = isTurnStartEntry(cutEntry)\n const turnStartIndex = startsTurn ? -1 : findTurnStartIndex(entries, cutIndex, startIndex)\n\n return {\n firstKeptEntryIndex: cutIndex,\n turnStartIndex,\n isSplitTurn: !startsTurn && turnStartIndex !== -1,\n }\n}\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\nconst UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, and context from the new messages\n- UPDATE the Progress section: move items from \"In Progress\" to \"Done\" when completed\n- UPDATE \"Next Steps\" based on what was accomplished\n- PRESERVE exact file paths, function names, and error messages\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Goal\n[Preserve existing goals, add new ones if the task expanded]\n\n## Constraints & Preferences\n- [Preserve existing, add new ones discovered]\n\n## Progress\n### Done\n- [x] [Include previously done items AND newly completed items]\n\n### In Progress\n- [ ] [Current work - update based on progress]\n\n### Blocked\n- [Current blockers - remove if resolved]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale] (preserve all previous, add new)\n\n## Next Steps\n1. [Update based on current state]\n\n## Critical Context\n- [Preserve important context, add new if needed]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\nfunction createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel) {\n const options = { maxTokens, signal, apiKey, headers, env }\n if (model.reasoning && thinkingLevel && thinkingLevel !== 'off') {\n options.reasoning = thinkingLevel\n }\n return options\n}\n\n// pi2dsh seam (see file header): Pi calls the provider-SDK completeSimple() here.\n// The pi2dsh export layer always injects a host-llm-bridge streamFn, so this\n// fallback is unreachable through the shims; a direct vendored call without a\n// streamFn fails loud instead of pretending to reach a provider.\nfunction completeSimple(_model, _context, _options): never {\n throw new Error(\n 'pi2dsh: summarization without a streamFn would call a Pi provider SDK directly; '\n + 'model calls run through the DSH llm bridge (the pi2dsh exports inject it automatically)',\n )\n}\n\n/**\n * Shared choke point for every compaction/branch-summary summarization call. Wraps the\n * single LLM call in retryAssistantCall so transient stream drops (e.g.\n * `terminated`, socket close) honor the configured retry policy instead of failing\n * the whole compaction on the first attempt. Deterministic errors and aborts return\n * immediately (see retryAssistantCall).\n */\nexport async function completeSummarization(model, context, options, streamFn, retry, callbacks) {\n // Summaries are standalone requests, so isolate routing and avoid cache writes that cannot be reused.\n const requestOptions = {\n ...options,\n cacheRetention: 'none',\n sessionId: uuidv7(),\n }\n const produce = async () =>\n streamFn\n ? (await streamFn(model, context, requestOptions)).result()\n : completeSimple(model, context, requestOptions)\n return retryAssistantCall(produce, retry, requestOptions.signal, callbacks)\n}\n\nexport async function generateSummary(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n) {\n return (\n await generateSummaryWithUsage(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n ).text\n}\n\n/** Generate or update a conversation summary and return its provider usage. */\nexport async function generateSummaryWithUsage(\n currentMessages,\n model,\n reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n) {\n const maxTokens = Math.min(\n Math.floor(0.8 * reserveTokens),\n model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n )\n\n // Use update prompt if we have a previous summary, otherwise initial prompt\n let basePrompt = previousSummary ? UPDATE_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT\n if (customInstructions) {\n basePrompt = `${basePrompt}\\n\\nAdditional focus: ${customInstructions}`\n }\n\n // Serialize conversation to text so model doesn't try to continue it\n // Convert to LLM messages first (handles custom types like bashExecution, custom, etc.)\n const llmMessages = convertToLlm(currentMessages)\n const conversationText = serializeConversation(llmMessages)\n\n // Build the prompt with conversation wrapped in tags\n let promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n`\n if (previousSummary) {\n promptText += `<previous-summary>\\n${previousSummary}\\n</previous-summary>\\n\\n`\n }\n promptText += basePrompt\n\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n const completionOptions = createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel)\n\n const response = await completeSummarization(\n model,\n { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n completionOptions,\n streamFn,\n retry,\n callbacks,\n )\n\n if (response.stopReason === 'error') {\n throw new Error(`Summarization failed: ${response.errorMessage || 'Unknown error'}`)\n }\n\n const textContent = contentText(response.content)\n\n return { text: textContent, usage: response.usage }\n}\n\n// ---- compaction/compaction.ts: usage math, preparation, full compaction ----\n\n/** Result from compact() - SessionManager adds uuid/parentUuid when saving */\nexport interface CompactionResult<T = unknown> {\n summary: string\n firstKeptEntryId: string\n tokensBefore: number\n estimatedTokensAfter?: number\n /** Usage from the LLM call(s) that generated this summary, if available */\n usage?\n /** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */\n details?: T\n}\n\nfunction combineUsage(first, second) {\n return {\n input: first.input + second.input,\n output: first.output + second.output,\n cacheRead: first.cacheRead + second.cacheRead,\n cacheWrite: first.cacheWrite + second.cacheWrite,\n ...(first.cacheWrite1h !== undefined || second.cacheWrite1h !== undefined\n ? { cacheWrite1h: (first.cacheWrite1h ?? 0) + (second.cacheWrite1h ?? 0) }\n : {}),\n ...(first.reasoning !== undefined || second.reasoning !== undefined\n ? { reasoning: (first.reasoning ?? 0) + (second.reasoning ?? 0) }\n : {}),\n totalTokens: first.totalTokens + second.totalTokens,\n cost: {\n input: first.cost.input + second.cost.input,\n output: first.cost.output + second.cost.output,\n cacheRead: first.cost.cacheRead + second.cost.cacheRead,\n cacheWrite: first.cost.cacheWrite + second.cost.cacheWrite,\n total: first.cost.total + second.cost.total,\n },\n }\n}\n\nexport interface CompactionSettings {\n enabled: boolean\n reserveTokens: number\n keepRecentTokens: number\n}\n\nexport const DEFAULT_COMPACTION_SETTINGS: CompactionSettings = {\n enabled: true,\n reserveTokens: 16384,\n keepRecentTokens: 20000,\n}\n\n/**\n * Calculate total context tokens from usage.\n * Uses the native totalTokens field when available, falls back to computing from components.\n */\nexport function calculateContextTokens(usage): number {\n return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite\n}\n\n/**\n * Get usage from an assistant message if available.\n * Skips aborted, error, and all-zero usage messages as they don't have valid usage data.\n */\nfunction getAssistantUsage(msg) {\n if (msg.role === 'assistant' && 'usage' in msg) {\n const assistantMsg = msg\n if (\n assistantMsg.stopReason !== 'aborted'\n && assistantMsg.stopReason !== 'error'\n && assistantMsg.usage\n && calculateContextTokens(assistantMsg.usage) > 0\n ) {\n return assistantMsg.usage\n }\n }\n return undefined\n}\n\n/**\n * Find the last valid assistant message usage from session entries.\n */\nexport function getLastAssistantUsage(entries) {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i]\n if (entry.type === 'message') {\n const usage = getAssistantUsage(entry.message)\n if (usage) return usage\n }\n }\n return undefined\n}\n\nexport interface ContextUsageEstimate {\n tokens: number\n usageTokens: number\n trailingTokens: number\n lastUsageIndex: number | null\n}\n\nfunction getLastAssistantUsageInfo(messages) {\n for (let i = messages.length - 1; i >= 0; i--) {\n const usage = getAssistantUsage(messages[i])\n if (usage) return { usage, index: i }\n }\n return undefined\n}\n\n/**\n * Estimate context tokens from messages, using the last assistant usage when available.\n * If there are messages after the last usage, estimate their tokens with estimateTokens.\n */\nexport function estimateContextTokens(messages): ContextUsageEstimate {\n const usageInfo = getLastAssistantUsageInfo(messages)\n\n if (!usageInfo) {\n let estimated = 0\n for (const message of messages) {\n estimated += estimateTokens(message)\n }\n return {\n tokens: estimated,\n usageTokens: 0,\n trailingTokens: estimated,\n lastUsageIndex: null,\n }\n }\n\n const usageTokens = calculateContextTokens(usageInfo.usage)\n let trailingTokens = 0\n for (let i = usageInfo.index + 1; i < messages.length; i++) {\n trailingTokens += estimateTokens(messages[i])\n }\n\n return {\n tokens: usageTokens + trailingTokens,\n usageTokens,\n trailingTokens,\n lastUsageIndex: usageInfo.index,\n }\n}\n\n/**\n * Check if compaction should trigger based on context usage.\n */\nexport function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean {\n if (!settings.enabled) return false\n return contextTokens > contextWindow - settings.reserveTokens\n}\n\nfunction extractFileOperations(messages, entries, prevCompactionIndex: number): FileOperations {\n const fileOps = createFileOps()\n\n // Collect from previous compaction's details (if pi-generated)\n if (prevCompactionIndex >= 0) {\n const prevCompaction = entries[prevCompactionIndex]\n if (!prevCompaction.fromHook && prevCompaction.details) {\n // fromHook field kept for session file compatibility\n const details = prevCompaction.details\n if (Array.isArray(details.readFiles)) {\n for (const f of details.readFiles) fileOps.read.add(f)\n }\n if (Array.isArray(details.modifiedFiles)) {\n for (const f of details.modifiedFiles) fileOps.edited.add(f)\n }\n }\n }\n\n // Extract from tool calls in messages\n for (const msg of messages) {\n extractFileOpsFromMessage(msg, fileOps)\n }\n\n return fileOps\n}\n\n/**\n * Extract AgentMessage from an entry if it produces one.\n * Returns undefined for entries that don't contribute to LLM context.\n */\nfunction getMessageFromEntryForCompaction(entry) {\n if (entry.type === 'compaction') {\n return undefined\n }\n return sessionEntryToContextMessages(entry)[0]\n}\n\nexport interface CompactionPreparation {\n /** UUID of first entry to keep */\n firstKeptEntryId: string\n /** Messages that will be summarized and discarded */\n messagesToSummarize\n /** Messages that will be turned into turn prefix summary (if splitting) */\n turnPrefixMessages\n /** Whether this is a split turn (cut point in middle of turn) */\n isSplitTurn: boolean\n tokensBefore: number\n /** Summary from previous compaction, for iterative update */\n previousSummary?: string\n /** File operations extracted from messagesToSummarize */\n fileOps: FileOperations\n /** Compaction settions from settings.jsonl\t*/\n settings: CompactionSettings\n}\n\nexport function prepareCompaction(pathEntries, settings: CompactionSettings): CompactionPreparation | undefined {\n if (pathEntries.length > 0 && pathEntries[pathEntries.length - 1].type === 'compaction') {\n return undefined\n }\n\n let prevCompactionIndex = -1\n for (let i = pathEntries.length - 1; i >= 0; i--) {\n if (pathEntries[i].type === 'compaction') {\n prevCompactionIndex = i\n break\n }\n }\n\n let previousSummary: string | undefined\n let boundaryStart = 0\n if (prevCompactionIndex >= 0) {\n const prevCompaction = pathEntries[prevCompactionIndex]\n previousSummary = prevCompaction.summary\n const firstKeptEntryIndex = pathEntries.findIndex(entry => entry.id === prevCompaction.firstKeptEntryId)\n boundaryStart = firstKeptEntryIndex >= 0 ? firstKeptEntryIndex : prevCompactionIndex + 1\n }\n const boundaryEnd = pathEntries.length\n\n const tokensBefore = estimateContextTokens(buildSessionContext(pathEntries).messages).tokens\n\n const cutPoint = findCutPoint(pathEntries, boundaryStart, boundaryEnd, settings.keepRecentTokens)\n\n // Get UUID of first kept entry\n const firstKeptEntry = pathEntries[cutPoint.firstKeptEntryIndex]\n if (!firstKeptEntry?.id) {\n return undefined // Session needs migration\n }\n const firstKeptEntryId = firstKeptEntry.id\n\n const historyEnd = cutPoint.isSplitTurn ? cutPoint.turnStartIndex : cutPoint.firstKeptEntryIndex\n\n // Messages to summarize (will be discarded after summary)\n const messagesToSummarize = []\n for (let i = boundaryStart; i < historyEnd; i++) {\n const msg = getMessageFromEntryForCompaction(pathEntries[i])\n if (msg) messagesToSummarize.push(msg)\n }\n\n // Messages for turn prefix summary (if splitting a turn)\n const turnPrefixMessages = []\n if (cutPoint.isSplitTurn) {\n for (let i = cutPoint.turnStartIndex; i < cutPoint.firstKeptEntryIndex; i++) {\n const msg = getMessageFromEntryForCompaction(pathEntries[i])\n if (msg) turnPrefixMessages.push(msg)\n }\n }\n\n if (messagesToSummarize.length === 0 && turnPrefixMessages.length === 0) {\n return undefined\n }\n\n // Extract file operations from messages and previous compaction\n const fileOps = extractFileOperations(messagesToSummarize, pathEntries, prevCompactionIndex)\n\n // Also extract file ops from turn prefix if splitting\n if (cutPoint.isSplitTurn) {\n for (const msg of turnPrefixMessages) {\n extractFileOpsFromMessage(msg, fileOps)\n }\n }\n\n return {\n firstKeptEntryId,\n messagesToSummarize,\n turnPrefixMessages,\n isSplitTurn: cutPoint.isSplitTurn,\n tokensBefore,\n previousSummary,\n fileOps,\n settings,\n }\n}\n\nconst TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.`\n\n/**\n * Generate summaries for compaction using prepared data.\n * Returns CompactionResult - SessionManager adds uuid/parentUuid when saving.\n */\nexport async function compact(\n preparation: CompactionPreparation,\n model,\n apiKey,\n headers,\n customInstructions,\n signal,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n): Promise<CompactionResult> {\n const {\n firstKeptEntryId,\n messagesToSummarize,\n turnPrefixMessages,\n isSplitTurn,\n tokensBefore,\n previousSummary,\n fileOps,\n settings,\n } = preparation\n\n // Generate summaries and merge into one\n let summary: string\n let summaryUsage\n\n if (isSplitTurn && turnPrefixMessages.length > 0) {\n let historyText = 'No prior history.'\n let historyUsage\n if (messagesToSummarize.length > 0) {\n const historyResult = await generateSummaryWithUsage(\n messagesToSummarize,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n historyText = historyResult.text\n historyUsage = historyResult.usage\n }\n const turnPrefixResult = await generateTurnPrefixSummary(\n turnPrefixMessages,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n env,\n signal,\n thinkingLevel,\n streamFn,\n retry,\n callbacks,\n )\n // Merge into single summary\n summary = `${historyText}\\n\\n---\\n\\n**Turn Context (split turn):**\\n\\n${turnPrefixResult.text}`\n summaryUsage = historyUsage ? combineUsage(historyUsage, turnPrefixResult.usage) : turnPrefixResult.usage\n } else {\n // Just generate history summary\n const result = await generateSummaryWithUsage(\n messagesToSummarize,\n model,\n settings.reserveTokens,\n apiKey,\n headers,\n signal,\n customInstructions,\n previousSummary,\n thinkingLevel,\n streamFn,\n env,\n retry,\n callbacks,\n )\n summary = result.text\n summaryUsage = result.usage\n }\n\n // Compute file lists and append to summary\n const { readFiles, modifiedFiles } = computeFileLists(fileOps)\n summary += formatFileOperations(readFiles, modifiedFiles)\n\n if (!firstKeptEntryId) {\n throw new Error('First kept entry has no UUID - session may need migration')\n }\n\n return {\n summary,\n firstKeptEntryId,\n tokensBefore,\n usage: summaryUsage,\n details: { readFiles, modifiedFiles },\n }\n}\n\n/**\n * Generate a summary for a turn prefix (when splitting a turn).\n */\nasync function generateTurnPrefixSummary(\n messages,\n model,\n reserveTokens,\n apiKey,\n headers,\n env,\n signal,\n thinkingLevel,\n streamFn,\n retry,\n callbacks,\n) {\n const maxTokens = Math.min(\n Math.floor(0.5 * reserveTokens),\n model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n ) // Smaller budget for turn prefix\n const llmMessages = convertToLlm(messages)\n const conversationText = serializeConversation(llmMessages)\n const promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n const response = await completeSummarization(\n model,\n { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel),\n streamFn,\n retry,\n callbacks,\n )\n\n if (response.stopReason === 'error') {\n throw new Error(`Turn prefix summarization failed: ${response.errorMessage || 'Unknown error'}`)\n }\n\n return {\n text: contentText(response.content),\n usage: response.usage,\n }\n}\n\n// ---- compaction/branch-summarization.ts ------------------------------------\n\nexport interface BranchSummaryResult {\n summary?: string\n usage?\n readFiles?: string[]\n modifiedFiles?: string[]\n aborted?: boolean\n error?: string\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n readFiles: string[]\n modifiedFiles: string[]\n}\n\nexport interface BranchPreparation {\n /** Messages extracted for summarization, in chronological order */\n messages\n /** File operations extracted from tool calls */\n fileOps: FileOperations\n /** Total estimated tokens in messages */\n totalTokens: number\n}\n\nexport interface CollectEntriesResult {\n /** Entries to summarize, in chronological order */\n entries\n /** Common ancestor between old and new position, if any */\n commonAncestorId: string | null\n}\n\nexport interface GenerateBranchSummaryOptions {\n model\n apiKey?: string\n headers?: Record<string, string>\n env?: Record<string, string>\n signal: AbortSignal\n customInstructions?: string\n replaceInstructions?: boolean\n reserveTokens?: number\n streamFn?\n retry?\n callbacks?\n}\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n */\nexport function collectEntriesForBranchSummary(session, oldLeafId, targetId): CollectEntriesResult {\n // If no old position, nothing to summarize\n if (!oldLeafId) {\n return { entries: [], commonAncestorId: null }\n }\n\n // Find common ancestor (deepest node that's on both paths)\n const oldPath = new Set(session.getBranch(oldLeafId).map(e => e.id))\n const targetPath = session.getBranch(targetId)\n\n // targetPath is root-first, so iterate backwards to find deepest common ancestor\n let commonAncestorId: string | null = null\n for (let i = targetPath.length - 1; i >= 0; i--) {\n if (oldPath.has(targetPath[i].id)) {\n commonAncestorId = targetPath[i].id\n break\n }\n }\n\n // Collect entries from old leaf back to common ancestor\n const entries = []\n let current = oldLeafId\n\n while (current && current !== commonAncestorId) {\n const entry = session.getEntry(current)\n if (!entry) break\n entries.push(entry)\n current = entry.parentId\n }\n\n // Reverse to get chronological order\n entries.reverse()\n\n return { entries, commonAncestorId }\n}\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry) {\n switch (entry.type) {\n case 'message':\n // Skip tool results - context is in assistant's tool call\n if (entry.message.role === 'toolResult') return undefined\n return entry.message\n\n case 'custom_message':\n return createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp)\n\n case 'branch_summary':\n return createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)\n\n case 'compaction':\n return createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)\n\n // These don't contribute to conversation content\n case 'thinking_level_change':\n case 'model_change':\n case 'custom':\n case 'label':\n case 'session_info':\n return undefined\n }\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n */\nexport function prepareBranchEntries(entries, tokenBudget: number = 0): BranchPreparation {\n const messages = []\n const fileOps = createFileOps()\n let totalTokens = 0\n\n // First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n // This ensures we capture cumulative file tracking from nested branch summaries\n // Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n for (const entry of entries) {\n if (entry.type === 'branch_summary' && !entry.fromHook && entry.details) {\n const details = entry.details\n if (Array.isArray(details.readFiles)) {\n for (const f of details.readFiles) fileOps.read.add(f)\n }\n if (Array.isArray(details.modifiedFiles)) {\n // Modified files go into both edited and written for proper deduplication\n for (const f of details.modifiedFiles) {\n fileOps.edited.add(f)\n }\n }\n }\n }\n\n // Second pass: walk from newest to oldest, adding messages until token budget\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i]\n const message = getMessageFromEntry(entry)\n if (!message) continue\n\n // Extract file ops from assistant messages (tool calls)\n extractFileOpsFromMessage(message, fileOps)\n\n const tokens = estimateTokens(message)\n\n // Check budget before adding\n if (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n // If this is a summary entry, try to fit it anyway as it's important context\n if (entry.type === 'compaction' || entry.type === 'branch_summary') {\n if (totalTokens < tokenBudget * 0.9) {\n messages.unshift(message)\n totalTokens += tokens\n }\n }\n // Stop - we've hit the budget\n break\n }\n\n messages.unshift(message)\n totalTokens += tokens\n }\n\n return { messages, fileOps, totalTokens }\n}\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`\n\nconst BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.\n\nUse this EXACT format:\n\n## Goal\n[What was the user trying to accomplish in this branch?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Work that was started but not finished]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [What should happen next to continue this work]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`\n\n/**\n * Generate a summary of abandoned branch entries.\n */\nexport async function generateBranchSummary(entries, options: GenerateBranchSummaryOptions): Promise<BranchSummaryResult> {\n const {\n model,\n apiKey,\n headers,\n env,\n signal,\n customInstructions,\n replaceInstructions,\n reserveTokens = 16384,\n streamFn,\n retry,\n callbacks,\n } = options\n\n // Token budget = context window minus reserved space for prompt + response\n const contextWindow = model.contextWindow || 128000\n const tokenBudget = contextWindow - reserveTokens\n\n const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget)\n\n if (messages.length === 0) {\n return { summary: 'No content to summarize' }\n }\n\n // Transform to LLM-compatible messages, then serialize to text\n // Serialization prevents the model from treating it as a conversation to continue\n const llmMessages = convertToLlm(messages)\n const conversationText = serializeConversation(llmMessages)\n\n // Build prompt\n let instructions: string\n if (replaceInstructions && customInstructions) {\n instructions = customInstructions\n } else if (customInstructions) {\n instructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`\n } else {\n instructions = BRANCH_SUMMARY_PROMPT\n }\n const promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`\n\n const summarizationMessages = [\n {\n role: 'user',\n content: [{ type: 'text', text: promptText }],\n timestamp: Date.now(),\n },\n ]\n\n // Call LLM for summarization. Prefer the session stream function so SDK\n // request behavior (timeouts, retries, attribution headers) stays consistent\n // without running through agent state/events. Retried via completeSummarization\n // so transient stream drops reuse the configured retry policy.\n const context = { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }\n const requestOptions = { apiKey, headers, env, signal, maxTokens: 2048 }\n const response = await completeSummarization(model, context, requestOptions, streamFn, retry, callbacks)\n\n // Check if aborted or errored\n if (response.stopReason === 'aborted') {\n return { aborted: true }\n }\n if (response.stopReason === 'error') {\n return { error: response.errorMessage || 'Summarization failed' }\n }\n\n let summary = contentText(response.content)\n\n // Prepend preamble to provide context about the branch summary\n summary = BRANCH_SUMMARY_PREAMBLE + summary\n\n // Compute file lists and append to summary\n const { readFiles, modifiedFiles } = computeFileLists(fileOps)\n summary += formatFileOperations(readFiles, modifiedFiles)\n\n return {\n summary: summary || 'No summary generated',\n usage: response.usage,\n readFiles,\n modifiedFiles,\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/frontmatter.ts @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); unchanged.\nimport { parse } from 'yaml'\n\ntype ParsedFrontmatter<T extends Record<string, unknown>> = {\n frontmatter: T\n body: string\n}\n\nconst normalizeNewlines = (value: string): string => value.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst extractFrontmatter = (content: string): { yamlString: string | null; body: string } => {\n const normalized = normalizeNewlines(content)\n\n if (!normalized.startsWith('---')) {\n return { yamlString: null, body: normalized }\n }\n\n const endIndex = normalized.indexOf('\\n---', 3)\n if (endIndex === -1) {\n return { yamlString: null, body: normalized }\n }\n\n return {\n yamlString: normalized.slice(4, endIndex),\n body: normalized.slice(endIndex + 4).trim(),\n }\n}\n\nexport const parseFrontmatter = <T extends Record<string, unknown> = Record<string, unknown>>(\n content: string,\n): ParsedFrontmatter<T> => {\n const { yamlString, body } = extractFrontmatter(content)\n if (!yamlString) {\n return { frontmatter: {} as T, body }\n }\n const parsed = parse(yamlString)\n return { frontmatter: (parsed ?? {}) as T, body }\n}\n\nexport const stripFrontmatter = (content: string): string => parseFrontmatter(content).body\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/tools/tool-definition-wrapper.ts +\n// src/core/extensions/wrapper.ts @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE);\n// logic unchanged. The `runner` parameter is typed structurally: Pi's own code uses exactly\n// createContext() and getActiveTools() from ExtensionRunner, which the pi2dsh projection provides.\n\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition(definition, ctxFactory) {\n return {\n name: definition.name,\n label: definition.label,\n description: definition.description,\n parameters: definition.parameters,\n constrainedSampling: definition.constrainedSampling,\n prepareArguments: definition.prepareArguments,\n executionMode: definition.executionMode,\n execute: (toolCallId, params, signal, onUpdate, ctx) =>\n definition.execute(toolCallId, params, signal, onUpdate, ctx ?? ctxFactory?.()),\n }\n}\n\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(definitions, ctxFactory) {\n return definitions.map(definition => wrapToolDefinition(definition, ctxFactory))\n}\n\n/**\n * Wrap a RegisteredTool into an AgentTool.\n * Uses the runner's createContext() for consistent context across tools and event handlers.\n */\nexport function wrapRegisteredTool(registeredTool, runner) {\n const tool = wrapToolDefinition(registeredTool.definition, () => runner.createContext())\n const execute = tool.execute\n return {\n ...tool,\n execute: async (toolCallId, params, signal, onUpdate) => {\n const activeBefore = runner.getActiveTools()\n const result = await execute(toolCallId, params, signal, onUpdate)\n const activeAfter = runner.getActiveTools()\n if (!activeBefore.every(name => activeAfter.includes(name))) return result\n\n const beforeNames = new Set(activeBefore)\n const addedToolNames = activeAfter.filter(name => !beforeNames.has(name))\n if (addedToolNames.length === 0) return result\n return {\n ...result,\n addedToolNames: [...new Set([...(result.addedToolNames ?? []), ...addedToolNames])],\n }\n },\n }\n}\n\n/**\n * Wrap all registered tools into AgentTools.\n * Uses the runner's createContext() for consistent context across tools and event handlers.\n */\nexport function wrapRegisteredTools(registeredTools, runner) {\n return registeredTools.map(tool => wrapRegisteredTool(tool, runner))\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/paths.ts subset\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// The subset the vendored skills loader and trust store reach: normalizePath,\n// resolvePath, canonicalizePath, and their helpers.\nimport { realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, resolve as nodeResolvePath } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst UNICODE_SPACES = /[\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]/g\n\nexport interface PathInputOptions {\n trim?: boolean\n normalizeUnicodeSpaces?: boolean\n stripAtPrefix?: boolean\n expandTilde?: boolean\n homeDir?: string\n}\n\n/** Convert Git Bash, MSYS, Cygwin, and WSL drive paths to a form native Windows APIs accept. */\nexport function normalizeWindowsShellPath(filePath: string): string {\n if (!filePath.startsWith('/') || filePath.startsWith('//') || filePath.includes('\\\\')) return filePath\n const match = filePath.match(/^\\/(?:mnt\\/|cygdrive\\/)?([a-z])(?:\\/(.*))?$/i)\n if (!match) return filePath\n const suffix = match[2]?.replaceAll('/', '\\\\')\n return `${match[1].toUpperCase()}:\\\\${suffix ?? ''}`\n}\n\nexport function normalizePath(input: string, options: PathInputOptions = {}): string {\n let normalized = options.trim ? input.trim() : input\n if (options.normalizeUnicodeSpaces) {\n normalized = normalized.replace(UNICODE_SPACES, ' ')\n }\n if (options.stripAtPrefix && normalized.startsWith('@')) {\n normalized = normalized.slice(1)\n }\n if (process.platform === 'win32') {\n normalized = normalizeWindowsShellPath(normalized)\n }\n\n if (options.expandTilde ?? true) {\n const home = options.homeDir ?? homedir()\n if (normalized === '~') return home\n if (normalized.startsWith('~/') || (process.platform === 'win32' && normalized.startsWith('~\\\\'))) {\n return join(home, normalized.slice(2))\n }\n }\n\n if (/^file:\\/\\//.test(normalized)) {\n return fileURLToPath(normalized)\n }\n\n return normalized\n}\n\nexport function resolvePath(input: string, baseDir: string = process.cwd(), options: PathInputOptions = {}): string {\n const normalized = normalizePath(input, options)\n const normalizedBaseDir = normalizePath(baseDir)\n return isAbsolute(normalized) ? nodeResolvePath(normalized) : nodeResolvePath(normalizedBaseDir, normalized)\n}\n\nexport function canonicalizePath(path: string): string {\n try {\n return realpathSync(path)\n } catch {\n return path\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/trust-manager.ts store surface\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// The store operates wherever the caller points it: under pi2dsh the conventional\n// agentDir already resolves inside the DSH-owned pi2dsh directory, so a package's\n// trust decisions are package-visible state that the DSH host never consumes.\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport lockfile from 'proper-lockfile'\nimport { canonicalizePath, resolvePath } from './pi-paths.js'\n\nexport type ProjectTrustDecision = boolean | null\n\nexport interface ProjectTrustStoreEntry {\n path: string\n decision: boolean\n}\n\nexport interface ProjectTrustUpdate {\n path: string\n decision: ProjectTrustDecision\n}\n\ntype TrustFile = Record<string, boolean | null | undefined>\n\nfunction normalizeCwd(cwd: string): string {\n return canonicalizePath(resolvePath(cwd))\n}\n\nfunction findNearestTrustEntry(data: TrustFile, cwd: string): ProjectTrustStoreEntry | null {\n let currentDir = normalizeCwd(cwd)\n while (true) {\n const value = data[currentDir]\n if (value === true || value === false) {\n return { path: currentDir, decision: value }\n }\n\n const parentDir = dirname(currentDir)\n if (parentDir === currentDir) {\n return null\n }\n currentDir = parentDir\n }\n}\n\nfunction readTrustFile(path: string): TrustFile {\n if (!existsSync(path)) {\n return {}\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(readFileSync(path, 'utf-8'))\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to read trust store ${path}: ${message}`)\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(`Invalid trust store ${path}: expected an object`)\n }\n\n const data: TrustFile = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (value !== true && value !== false && value !== null) {\n throw new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`)\n }\n data[key] = value\n }\n return data\n}\n\nfunction writeTrustFile(path: string, data: TrustFile): void {\n const sorted: TrustFile = {}\n for (const key of Object.keys(data).sort()) {\n const value = data[key]\n if (value === true || value === false || value === null) {\n sorted[key] = value\n }\n }\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, `${JSON.stringify(sorted, null, 2)}\\n`, 'utf-8')\n}\n\nfunction acquireTrustLockSync(path: string): () => void {\n const trustDir = dirname(path)\n mkdirSync(trustDir, { recursive: true })\n const maxAttempts = 10\n const delayMs = 20\n let lastError: unknown\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return lockfile.lockSync(trustDir, { realpath: false, lockfilePath: `${path}.lock` })\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error\n ? String((error as { code?: unknown }).code)\n : undefined\n if (code !== 'ELOCKED' || attempt === maxAttempts) {\n throw error\n }\n lastError = error\n const start = Date.now()\n while (Date.now() - start < delayMs) {\n // Sleep synchronously to avoid changing trust store callers to async.\n }\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError\n }\n throw new Error('Failed to acquire trust store lock')\n}\n\nfunction withTrustFileLock<T>(path: string, fn: () => T): T {\n const release = acquireTrustLockSync(path)\n try {\n return fn()\n } finally {\n release()\n }\n}\n\nexport class ProjectTrustStore {\n private trustPath: string\n\n constructor(agentDir: string) {\n this.trustPath = resolvePath(agentDir) + '/trust.json'\n }\n\n get(cwd: string): ProjectTrustDecision {\n return this.getEntry(cwd)?.decision ?? null\n }\n\n getEntry(cwd: string): ProjectTrustStoreEntry | null {\n return withTrustFileLock(this.trustPath, () => {\n const data = readTrustFile(this.trustPath)\n return findNearestTrustEntry(data, cwd)\n })\n }\n\n set(cwd: string, decision: ProjectTrustDecision): void {\n this.setMany([{ path: cwd, decision }])\n }\n\n setMany(decisions: ProjectTrustUpdate[]): void {\n withTrustFileLock(this.trustPath, () => {\n const data = readTrustFile(this.trustPath)\n for (const { path, decision } of decisions) {\n const key = normalizeCwd(path)\n if (decision === null) {\n delete data[key]\n } else {\n data[key] = decision\n }\n }\n writeTrustFile(this.trustPath, data)\n })\n }\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/core/skills.ts\n// @6f707eb36064e82af9c1320a7634f4dfad21049b, MIT, see ./PI-LICENSE); logic unchanged.\n// createSyntheticSourceInfo is inlined from src/core/source-info.ts (same commit).\n// getAgentDir resolves through the pi2dsh config shim, so default skill\n// locations land inside the DSH-owned pi2dsh agent directory — the same\n// redirection every other conventional-path API already follows.\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs'\nimport ignore from 'ignore'\nimport { basename, dirname, join, relative, resolve, sep } from 'path'\nimport { getAgentDir } from './pi-config-shim.js'\nimport { parseFrontmatter } from './pi-frontmatter.js'\nimport { canonicalizePath, resolvePath } from './pi-paths.js'\n\n// coding-agent src/config.ts: the conventional Pi config directory name.\nconst CONFIG_DIR_NAME = '.pi'\n\n/** Max name length per spec */\nconst MAX_NAME_LENGTH = 64\n\n/** Max description length per spec */\nconst MAX_DESCRIPTION_LENGTH = 1024\n\nconst IGNORE_FILE_NAMES = ['.gitignore', '.ignore', '.fdignore']\n\nfunction toPosixPath(p: string): string {\n return p.split(sep).join('/')\n}\n\nfunction prefixIgnorePattern(line: string, prefix: string): string | null {\n const trimmed = line.trim()\n if (!trimmed) return null\n if (trimmed.startsWith('#') && !trimmed.startsWith('\\\\#')) return null\n\n let pattern = line\n let negated = false\n\n if (pattern.startsWith('!')) {\n negated = true\n pattern = pattern.slice(1)\n } else if (pattern.startsWith('\\\\!')) {\n pattern = pattern.slice(1)\n }\n\n if (pattern.startsWith('/')) {\n pattern = pattern.slice(1)\n }\n\n const prefixed = prefix ? `${prefix}${pattern}` : pattern\n return negated ? `!${prefixed}` : prefixed\n}\n\nfunction addIgnoreRules(ig, dir: string, rootDir: string): void {\n const relativeDir = relative(rootDir, dir)\n const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : ''\n\n for (const filename of IGNORE_FILE_NAMES) {\n const ignorePath = join(dir, filename)\n if (!existsSync(ignorePath)) continue\n try {\n const content = readFileSync(ignorePath, 'utf-8')\n const patterns = content\n .split(/\\r?\\n/)\n .map(line => prefixIgnorePattern(line, prefix))\n .filter(line => Boolean(line))\n if (patterns.length > 0) {\n ig.add(patterns)\n }\n } catch {}\n }\n}\n\n// source-info.ts (same commit): synthesize SourceInfo for resources that do not\n// come from a resolved package source.\nfunction createSyntheticSourceInfo(path, options) {\n return {\n path,\n source: options.source,\n scope: options.scope ?? 'temporary',\n origin: options.origin ?? 'top-level',\n baseDir: options.baseDir,\n }\n}\n\nexport interface SkillFrontmatter {\n name?: string\n description?: string\n 'disable-model-invocation'?: boolean\n [key: string]: unknown\n}\n\nexport interface Skill {\n name: string\n description: string\n filePath: string\n baseDir: string\n sourceInfo\n disableModelInvocation: boolean\n}\n\nexport interface LoadSkillsResult {\n skills: Skill[]\n diagnostics\n}\n\n/**\n * Validate skill name per Agent Skills spec.\n * Returns array of validation error messages (empty if valid).\n */\nfunction validateName(name: string): string[] {\n const errors: string[] = []\n\n if (name.length > MAX_NAME_LENGTH) {\n errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`)\n }\n\n if (!/^[a-z0-9-]+$/.test(name)) {\n errors.push(`name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)`)\n }\n\n if (name.startsWith('-') || name.endsWith('-')) {\n errors.push(`name must not start or end with a hyphen`)\n }\n\n if (name.includes('--')) {\n errors.push(`name must not contain consecutive hyphens`)\n }\n\n return errors\n}\n\n/**\n * Validate description per Agent Skills spec.\n */\nfunction validateDescription(description: string | undefined): string[] {\n const errors: string[] = []\n\n if (!description || description.trim() === '') {\n errors.push('description is required')\n } else if (description.length > MAX_DESCRIPTION_LENGTH) {\n errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`)\n }\n\n return errors\n}\n\nexport interface LoadSkillsFromDirOptions {\n /** Directory to scan for skills */\n dir: string\n /** Source identifier for these skills */\n source: string\n}\n\nfunction createSkillSourceInfo(filePath: string, baseDir: string, source: string) {\n switch (source) {\n case 'user':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n scope: 'user',\n baseDir,\n })\n case 'project':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n scope: 'project',\n baseDir,\n })\n case 'path':\n return createSyntheticSourceInfo(filePath, {\n source: 'local',\n baseDir,\n })\n default:\n return createSyntheticSourceInfo(filePath, { source, baseDir })\n }\n}\n\n/**\n * Load skills from a directory.\n *\n * Discovery rules:\n * - if a directory contains SKILL.md, treat it as a skill root and do not recurse further\n * - otherwise, load direct .md children in the root\n * - recurse into subdirectories to find SKILL.md\n */\nexport function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkillsResult {\n const { dir, source } = options\n return loadSkillsFromDirInternal(dir, source, true)\n}\n\nfunction loadSkillsFromDirInternal(\n dir: string,\n source: string,\n includeRootFiles: boolean,\n ignoreMatcher?,\n rootDir?: string,\n): LoadSkillsResult {\n const skills: Skill[] = []\n const diagnostics = []\n\n if (!existsSync(dir)) {\n return { skills, diagnostics }\n }\n\n const root = rootDir ?? dir\n const ig = ignoreMatcher ?? ignore()\n addIgnoreRules(ig, dir, root)\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (entry.name !== 'SKILL.md') {\n continue\n }\n\n const fullPath = join(dir, entry.name)\n\n let isFile = entry.isFile()\n if (entry.isSymbolicLink()) {\n try {\n isFile = statSync(fullPath).isFile()\n } catch {\n continue\n }\n }\n\n const relPath = toPosixPath(relative(root, fullPath))\n if (!isFile || ig.ignores(relPath)) {\n continue\n }\n\n const result = loadSkillFromFile(fullPath, source)\n if (result.skill) {\n skills.push(result.skill)\n }\n diagnostics.push(...result.diagnostics)\n return { skills, diagnostics }\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) {\n continue\n }\n\n // Skip node_modules to avoid scanning dependencies\n if (entry.name === 'node_modules') {\n continue\n }\n\n const fullPath = join(dir, entry.name)\n\n // For symlinks, check if they point to a directory and follow them\n let isDirectory = entry.isDirectory()\n let isFile = entry.isFile()\n if (entry.isSymbolicLink()) {\n try {\n const stats = statSync(fullPath)\n isDirectory = stats.isDirectory()\n isFile = stats.isFile()\n } catch {\n // Broken symlink, skip it\n continue\n }\n }\n\n const relPath = toPosixPath(relative(root, fullPath))\n const ignorePath = isDirectory ? `${relPath}/` : relPath\n if (ig.ignores(ignorePath)) {\n continue\n }\n\n if (isDirectory) {\n const subResult = loadSkillsFromDirInternal(fullPath, source, false, ig, root)\n skills.push(...subResult.skills)\n diagnostics.push(...subResult.diagnostics)\n continue\n }\n\n if (!isFile || !includeRootFiles || !entry.name.endsWith('.md')) {\n continue\n }\n\n const result = loadSkillFromFile(fullPath, source)\n if (result.skill) {\n skills.push(result.skill)\n }\n diagnostics.push(...result.diagnostics)\n }\n } catch {}\n\n return { skills, diagnostics }\n}\n\nfunction loadSkillFromFile(filePath: string, source: string): { skill: Skill | null; diagnostics } {\n const diagnostics = []\n\n try {\n const rawContent = readFileSync(filePath, 'utf-8')\n const { frontmatter } = parseFrontmatter(rawContent)\n const skillDir = dirname(filePath)\n const parentDirName = basename(skillDir)\n\n // Validate description\n const descErrors = validateDescription(frontmatter.description)\n for (const error of descErrors) {\n diagnostics.push({ type: 'warning', message: error, path: filePath })\n }\n\n // Use name from frontmatter, or fall back to parent directory name\n const name = frontmatter.name || parentDirName\n\n // Validate name\n const nameErrors = validateName(name)\n for (const error of nameErrors) {\n diagnostics.push({ type: 'warning', message: error, path: filePath })\n }\n\n // Still load the skill even with warnings (unless description is completely missing)\n if (!frontmatter.description || frontmatter.description.trim() === '') {\n return { skill: null, diagnostics }\n }\n\n return {\n skill: {\n name,\n description: frontmatter.description,\n filePath,\n baseDir: skillDir,\n sourceInfo: createSkillSourceInfo(filePath, skillDir, source),\n disableModelInvocation: frontmatter['disable-model-invocation'] === true,\n },\n diagnostics,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'failed to parse skill file'\n diagnostics.push({ type: 'warning', message, path: filePath })\n return { skill: null, diagnostics }\n }\n}\n\nexport interface LoadSkillsOptions {\n /** Working directory for project-local skills. */\n cwd: string\n /** Agent config directory for global skills. */\n agentDir: string\n /** Explicit skill paths (files or directories) */\n skillPaths: string[]\n /** Include default skills directories. */\n includeDefaults: boolean\n}\n\n/**\n * Load skills from all configured locations.\n * Returns skills and any validation diagnostics.\n */\nexport function loadSkills(options: LoadSkillsOptions): LoadSkillsResult {\n const { agentDir, skillPaths, includeDefaults } = options\n\n // Resolve agentDir - if not provided, use default from config\n const resolvedCwd = resolvePath(options.cwd)\n const resolvedAgentDir = resolvePath(agentDir ?? getAgentDir())\n\n const skillMap = new Map<string, Skill>()\n const realPathSet = new Set<string>()\n const allDiagnostics = []\n const collisionDiagnostics = []\n\n function addSkills(result: LoadSkillsResult) {\n allDiagnostics.push(...result.diagnostics)\n for (const skill of result.skills) {\n // Resolve symlinks to detect duplicate files\n const realPath = canonicalizePath(skill.filePath)\n\n // Skip silently if we've already loaded this exact file (via symlink)\n if (realPathSet.has(realPath)) {\n continue\n }\n\n const existing = skillMap.get(skill.name)\n if (existing) {\n collisionDiagnostics.push({\n type: 'collision',\n message: `name \"${skill.name}\" collision`,\n path: skill.filePath,\n collision: {\n resourceType: 'skill',\n name: skill.name,\n winnerPath: existing.filePath,\n loserPath: skill.filePath,\n },\n })\n } else {\n skillMap.set(skill.name, skill)\n realPathSet.add(realPath)\n }\n }\n }\n\n if (includeDefaults) {\n addSkills(loadSkillsFromDirInternal(join(resolvedAgentDir, 'skills'), 'user', true))\n addSkills(loadSkillsFromDirInternal(resolve(resolvedCwd, CONFIG_DIR_NAME, 'skills'), 'project', true))\n }\n\n const userSkillsDir = join(resolvedAgentDir, 'skills')\n const projectSkillsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, 'skills')\n\n const isUnderPath = (target: string, root: string): boolean => {\n const normalizedRoot = resolve(root)\n if (target === normalizedRoot) {\n return true\n }\n const prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`\n return target.startsWith(prefix)\n }\n\n const getSource = (resolvedPath: string): 'user' | 'project' | 'path' => {\n if (!includeDefaults) {\n if (isUnderPath(resolvedPath, userSkillsDir)) return 'user'\n if (isUnderPath(resolvedPath, projectSkillsDir)) return 'project'\n }\n return 'path'\n }\n\n for (const rawPath of skillPaths) {\n const resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true })\n if (!existsSync(resolvedPath)) {\n allDiagnostics.push({ type: 'warning', message: 'skill path does not exist', path: resolvedPath })\n continue\n }\n\n try {\n const stats = statSync(resolvedPath)\n const source = getSource(resolvedPath)\n if (stats.isDirectory()) {\n addSkills(loadSkillsFromDirInternal(resolvedPath, source, true))\n } else if (stats.isFile() && resolvedPath.endsWith('.md')) {\n const result = loadSkillFromFile(resolvedPath, source)\n if (result.skill) {\n addSkills({ skills: [result.skill], diagnostics: result.diagnostics })\n } else {\n allDiagnostics.push(...result.diagnostics)\n }\n } else {\n allDiagnostics.push({ type: 'warning', message: 'skill path is not a markdown file', path: resolvedPath })\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'failed to read skill path'\n allDiagnostics.push({ type: 'warning', message, path: resolvedPath })\n }\n }\n\n return {\n skills: Array.from(skillMap.values()),\n diagnostics: [...allDiagnostics, ...collisionDiagnostics],\n }\n}\n","// @ts-nocheck — vendored Pi source excerpt (core/skills.js formatSkillsForPrompt + escapeXml @0.84.1, MIT, see ./PI-LICENSE); logic unchanged.\n/**\n * Format skills for inclusion in a system prompt.\n * Uses XML format per Agent Skills standard.\n * See: https://agentskills.io/integrate-skills\n *\n * Skills with disableModelInvocation=true are excluded from the prompt\n * (they can only be invoked explicitly via /skill:name commands).\n */\nexport function formatSkillsForPrompt(skills) {\n const visibleSkills = skills.filter((s) => !s.disableModelInvocation);\n if (visibleSkills.length === 0) {\n return \"\";\n }\n const lines = [\n \"\\n\\nThe following skills provide specialized instructions for specific tasks.\",\n \"Use the read tool to load a skill's file when the task matches its description.\",\n \"When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\",\n \"\",\n \"<available_skills>\",\n ];\n for (const skill of visibleSkills) {\n lines.push(\" <skill>\");\n lines.push(` <name>${escapeXml(skill.name)}</name>`);\n lines.push(` <description>${escapeXml(skill.description)}</description>`);\n lines.push(` <location>${escapeXml(skill.filePath)}</location>`);\n lines.push(\" </skill>\");\n }\n lines.push(\"</available_skills>\");\n return lines.join(\"\\n\");\n}\nfunction escapeXml(str) {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n","// @ts-nocheck — vendored Pi source (coding-agent src/utils/shell.ts @47f9438, MIT, see ./PI-LICENSE);\n// excerpt: the getShellConfig closure consumed by resolve-config-value's `!command`\n// execution path. The full module's other exports depend on getBinDir and are not\n// used by the vendored resolver; logic of the excerpted functions is unchanged.\nimport { existsSync } from \"node:fs\";\nimport { spawnSync } from \"child_process\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n\tcommandTransport?: \"argv\" | \"stdin\";\n}\n\nfunction isLegacyWslBashPath(path: string): boolean {\n\tconst normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n\treturn /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\n\nfunction getBashShellConfig(shell: string): ShellConfig {\n\treturn isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\n\nfunction findBashOnPath(): string | null {\n\tif (process.platform === \"win32\") {\n\t\t// Windows: Use 'where' and verify file exists (where can return non-existent paths)\n\t\ttry {\n\t\t\tconst result = spawnSync(\"where\", [\"bash.exe\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5000,\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tif (result.status === 0 && result.stdout) {\n\t\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\t\tif (firstMatch && existsSync(firstMatch)) {\n\t\t\t\t\treturn firstMatch;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n\ttry {\n\t\tconst result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch) {\n\t\t\t\treturn firstMatch;\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore errors\n\t}\n\treturn null;\n}\n\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath?: string): ShellConfig {\n\t// 1. Check user-specified shell path\n\tif (customShellPath) {\n\t\tif (existsSync(customShellPath)) {\n\t\t\treturn getBashShellConfig(customShellPath);\n\t\t}\n\t\tthrow new Error(`Custom shell path not found: ${customShellPath}`);\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\t// 2. Try Git Bash in known locations\n\t\tconst paths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) {\n\t\t\tpaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) {\n\t\t\tpaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\n\t\tfor (const path of paths) {\n\t\t\tif (existsSync(path)) {\n\t\t\t\treturn getBashShellConfig(path);\n\t\t\t}\n\t\t}\n\n\t\t// 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n\t\tconst bashOnPath = findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn getBashShellConfig(bashOnPath);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`No bash shell found. Options:\\n` +\n\t\t\t\t` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n\t\t\t\t` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n\t\t\t\t\" 3. Set shellPath in settings.json\\n\\n\" +\n\t\t\t\t`Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`,\n\t\t);\n\t}\n\n\t// Unix: try /bin/bash, then bash on PATH, then fallback to sh\n\tif (existsSync(\"/bin/bash\")) {\n\t\treturn getBashShellConfig(\"/bin/bash\");\n\t}\n\n\tconst bashOnPath = findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn getBashShellConfig(bashOnPath);\n\t}\n\n\treturn { shell: \"sh\", args: [\"-c\"] };\n}\n","// Headless @earendil-works/pi-coding-agent compatibility surface.\n//\n// Three tiers, all package-agnostic:\n// 1. Vendored Pi source (SessionManager, message transforms, truncation,\n// compaction/summarization, skills loading, trust store, tool wrappers,\n// file-mutation queue) — byte-level Pi semantics, see ./vendor/PI-LICENSE.\n// Summarization model calls fill Pi's own streamFn injection point with\n// the DSH llm bridge: one model path, no provider SDKs.\n// 2. Headless reimplementations (Theme, settings, shell/clipboard/image\n// helpers) — same signatures, no terminal or Pi-global state.\n// 3. Host-owned capabilities (package install, standalone model stacks) —\n// importable so packages load, but constructing them throws a structured\n// PiCapabilityError naming the DSH-owned replacement, never a silent fake.\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { readImageDimensions } from './vendor/pi-image-dimensions.js'\nimport { PiCapabilityError } from '../capability.js'\n\nexport {\n SessionManager,\n CURRENT_SESSION_VERSION,\n parseSessionEntries,\n migrateSessionEntries,\n getLatestCompactionEntry,\n sessionEntryToContextMessages,\n buildContextEntries,\n buildSessionContext,\n loadEntriesFromFile,\n findMostRecentSession,\n getDefaultSessionDir,\n assertValidSessionId,\n} from './vendor/pi-session-manager.js'\nexport type {\n SessionEntry,\n SessionHeader,\n SessionTreeNode,\n SessionContext,\n SessionInfo,\n SessionMessageEntry,\n CompactionEntry,\n BranchSummaryEntry,\n CustomEntry,\n CustomMessageEntry,\n LabelEntry,\n SessionInfoEntry,\n ThinkingLevelChangeEntry,\n ModelChangeEntry,\n} from './vendor/pi-session-manager.js'\nexport {\n convertToLlm,\n createBranchSummaryMessage,\n createCompactionSummaryMessage,\n createCustomMessage,\n bashExecutionToText,\n COMPACTION_SUMMARY_PREFIX,\n COMPACTION_SUMMARY_SUFFIX,\n BRANCH_SUMMARY_PREFIX,\n BRANCH_SUMMARY_SUFFIX,\n} from './vendor/pi-messages.js'\nexport type {\n BashExecutionMessage,\n CustomMessage,\n BranchSummaryMessage,\n CompactionSummaryMessage,\n} from './vendor/pi-messages.js'\nexport {\n DEFAULT_MAX_BYTES,\n DEFAULT_MAX_LINES,\n formatSize,\n truncateHead,\n truncateLine,\n truncateTail,\n} from './vendor/pi-truncate.js'\nexport type { TruncationOptions, TruncationResult } from './vendor/pi-truncate.js'\nexport { withFileMutationQueue } from './vendor/pi-file-mutation-queue.js'\nexport { getAgentDir } from './vendor/pi-config-shim.js'\n// Pre-bind extension-runtime factory, vendored byte-identical. Extensions that\n// assemble their own ResourceLoader-shaped getExtensions() result (pi-btw's\n// BTW overlay) construct one; an absent export throws at command execution.\nexport { createExtensionRuntime } from './vendor/pi-extension-runtime.js'\nexport type { ExtensionRuntime } from './vendor/pi-extension-runtime.js'\n// Pi's built-in tool constructors, vendored byte-identical (spawn semantics,\n// output accumulation, truncation, kill-tree, mutation queue, diff rendering)\n// — the constructor surface packages like pi-landstrip and pi-fabric build\n// their own sandboxed/filtered variants on.\nexport {\n createBashTool,\n createBashToolDefinition,\n createLocalBashOperations,\n bashToolSystemPromptContribution,\n} from './vendor/pi-tools/bash.js'\nexport { createReadTool, createReadToolDefinition } from './vendor/pi-tools/read.js'\nexport { createEditTool, createEditToolDefinition } from './vendor/pi-tools/edit.js'\nexport { createWriteTool, createWriteToolDefinition } from './vendor/pi-tools/write.js'\nexport { createGrepTool, createGrepToolDefinition } from './vendor/pi-tools/grep.js'\nexport { createFindTool, createFindToolDefinition } from './vendor/pi-tools/find.js'\nexport { createLsTool, createLsToolDefinition } from './vendor/pi-tools/ls.js'\n\n// Pi's one-line tool-event guards (core/extensions/types.js), verbatim.\ninterface ToolNamedEvent { toolName?: unknown }\nexport function isToolCallEventType(toolName: string, event: ToolNamedEvent): boolean {\n return event.toolName === toolName\n}\nexport function isBashToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'bash' }\nexport function isReadToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'read' }\nexport function isEditToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'edit' }\nexport function isWriteToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'write' }\nexport function isGrepToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'grep' }\nexport function isFindToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'find' }\nexport function isLsToolResult(event: ToolNamedEvent): boolean { return event.toolName === 'ls' }\n\nimport { homedir } from 'node:os'\nimport { join, delimiter } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createBashTool } from './vendor/pi-tools/bash.js'\nimport { createReadTool } from './vendor/pi-tools/read.js'\nimport { createEditTool } from './vendor/pi-tools/edit.js'\nimport { createWriteTool } from './vendor/pi-tools/write.js'\nimport { createGrepTool } from './vendor/pi-tools/grep.js'\nimport { createFindTool } from './vendor/pi-tools/find.js'\nimport { createLsTool } from './vendor/pi-tools/ls.js'\nimport { execFile } from 'node:child_process'\nimport type { AgentMessage } from './vendor/pi-types.js'\nimport type { Component, SettingsListTheme, SelectListTheme } from './pi-tui.js'\nimport { visibleWidth, truncateToWidth } from './vendor/pi-tui-utils.js'\nimport { getAgentDir as agentDirOf } from './vendor/pi-config-shim.js'\n\nexport const CONFIG_DIR_NAME = '.pi'\nexport const VERSION = 'pi2dsh-compat'\n\nexport function defineTool<T>(tool: T): T {\n return tool\n}\n\nfunction unsupportedRuntime(name: string): never {\n throw new Error(\n `pi2dsh: ${name} belongs to Pi's internal agent runtime and has no verified DSH mapping; `\n + 'use the DSH-native service instead (see the pi2dsh compatibility report)',\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme system (headless)\n// ---------------------------------------------------------------------------\n\nconst identity = (text: string): string => text\n\nexport type ThemeColor = string\nexport type ThemeBg = string\nexport type ColorMode = 'truecolor' | '256' | '16' | 'none'\n\nexport class Theme {\n constructor(public name = 'pi2dsh-headless') {}\n fg(_color: ThemeColor, text: string): string {\n return text\n }\n bg(_color: ThemeBg, text: string): string {\n return text\n }\n bold(text: string): string {\n return text\n }\n italic(text: string): string {\n return text\n }\n underline(text: string): string {\n return text\n }\n inverse(text: string): string {\n return text\n }\n strikethrough(text: string): string {\n return text\n }\n getFgAnsi(_color: ThemeColor): string {\n return ''\n }\n getBgAnsi(_color: ThemeBg): string {\n return ''\n }\n getColorMode(): ColorMode {\n return 'none'\n }\n getThinkingBorderColor(_level: unknown): (str: string) => string {\n return identity\n }\n getBashModeBorderColor(): (str: string) => string {\n return identity\n }\n}\n\nexport const theme = new Theme()\n\nexport function initTheme(_themeName?: string, _enableWatcher = false): void {}\n\nexport function getSettingsListTheme(): SettingsListTheme {\n return {\n label: (text: string, _selected: boolean) => text,\n value: (text: string, _selected: boolean) => text,\n description: (text: string) => text,\n cursor: '→ ',\n hint: (text: string) => text,\n }\n}\n\nexport function getSelectListTheme(): SelectListTheme {\n return {\n selectedPrefix: '→ ',\n selectedText: identity,\n description: identity,\n scrollInfo: identity,\n noMatch: identity,\n }\n}\n\nexport function getMarkdownTheme(): Record<string, unknown> {\n return {\n heading: identity, link: identity, linkUrl: identity, code: identity, codeBlock: identity,\n codeBlockBorder: identity, quote: identity, quoteBorder: identity, hr: identity,\n listBullet: identity, bold: identity, italic: identity, underline: identity,\n strikethrough: identity, highlightCode: (code: string) => code.split('\\n'),\n }\n}\n\nconst LANGUAGE_BY_EXTENSION: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript', '.js': 'javascript', '.jsx': 'javascript',\n '.mjs': 'javascript', '.cjs': 'javascript', '.py': 'python', '.rb': 'ruby', '.go': 'go',\n '.rs': 'rust', '.java': 'java', '.c': 'c', '.h': 'c', '.cpp': 'cpp', '.hpp': 'cpp',\n '.cs': 'csharp', '.sh': 'bash', '.bash': 'bash', '.zsh': 'bash', '.json': 'json',\n '.yaml': 'yaml', '.yml': 'yaml', '.toml': 'ini', '.md': 'markdown', '.html': 'xml',\n '.xml': 'xml', '.css': 'css', '.scss': 'scss', '.sql': 'sql', '.php': 'php',\n '.swift': 'swift', '.kt': 'kotlin', '.scala': 'scala', '.lua': 'lua', '.r': 'r',\n}\n\nexport function getLanguageFromPath(filePath: string): string | undefined {\n const dot = filePath.lastIndexOf('.')\n if (dot === -1) return undefined\n return LANGUAGE_BY_EXTENSION[filePath.slice(dot).toLowerCase()]\n}\n\nexport function highlightCode(code: string, _lang?: string): string[] {\n return code.split('\\n')\n}\n\nexport class DynamicBorder implements Component {\n constructor(private color: (str: string) => string = identity) {}\n render(width: number): string[] {\n return [this.color('─'.repeat(Math.max(1, width)))]\n }\n invalidate(): void {}\n}\n\n// ---------------------------------------------------------------------------\n// Message / compaction helpers\n// ---------------------------------------------------------------------------\n\n// Pi's compaction surface, vendored (vendor/pi-compaction.ts): the pure logic\n// is byte-aligned with Pi, and the ONE seam is the model call — Pi's own\n// streamFn injection point, which these wrappers fill with the DSH llm bridge\n// when the caller does not pass a streamFn. Every summarization model call\n// therefore runs on the single DSH llm path.\nexport {\n estimateTokens,\n calculateContextTokens,\n DEFAULT_COMPACTION_SETTINGS,\n shouldCompact,\n findCutPoint,\n findTurnStartIndex,\n serializeConversation,\n prepareCompaction,\n getLastAssistantUsage,\n collectEntriesForBranchSummary,\n prepareBranchEntries,\n type CompactionResult,\n type CompactionSettings,\n type CompactionPreparation,\n type CutPointResult,\n type FileOperations,\n type BranchPreparation,\n type BranchSummaryResult,\n type CollectEntriesResult,\n type GenerateBranchSummaryOptions,\n} from './vendor/pi-compaction.js'\nimport {\n compact as vendoredCompact,\n generateSummary as vendoredGenerateSummary,\n generateSummaryWithUsage as vendoredGenerateSummaryWithUsage,\n generateBranchSummary as vendoredGenerateBranchSummary,\n DEFAULT_COMPACTION_SETTINGS,\n type CompactionSettings,\n} from './vendor/pi-compaction.js'\nimport { __getPiAiLlmBridge } from './pi-ai.js'\n\nexport function compact(\n preparation: unknown,\n model: unknown,\n apiKey?: unknown,\n headers?: unknown,\n customInstructions?: unknown,\n signal?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<unknown> {\n return vendoredCompact(\n preparation as never, model, apiKey, headers, customInstructions, signal, thinkingLevel,\n streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateSummary(\n currentMessages: unknown,\n model: unknown,\n reserveTokens: unknown,\n apiKey?: unknown,\n headers?: unknown,\n signal?: unknown,\n customInstructions?: unknown,\n previousSummary?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<string> {\n return vendoredGenerateSummary(\n currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions,\n previousSummary, thinkingLevel, streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateSummaryWithUsage(\n currentMessages: unknown,\n model: unknown,\n reserveTokens: unknown,\n apiKey?: unknown,\n headers?: unknown,\n signal?: unknown,\n customInstructions?: unknown,\n previousSummary?: unknown,\n thinkingLevel?: unknown,\n streamFn?: unknown,\n env?: unknown,\n retry?: unknown,\n callbacks?: unknown,\n): Promise<unknown> {\n return vendoredGenerateSummaryWithUsage(\n currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions,\n previousSummary, thinkingLevel, streamFn ?? __getPiAiLlmBridge(), env, retry, callbacks,\n )\n}\n\nexport function generateBranchSummary(entries: unknown, options: Record<string, unknown>): Promise<unknown> {\n return vendoredGenerateBranchSummary(entries, {\n ...options,\n streamFn: options.streamFn ?? __getPiAiLlmBridge(),\n } as never)\n}\n\n// ---------------------------------------------------------------------------\n// Frontmatter\n// ---------------------------------------------------------------------------\n\n// Vendored Pi frontmatter (vendor/pi-frontmatter.ts): Pi's public API returns\n// { frontmatter, body } with YAML-parsed values. An earlier reimplementation\n// here returned { attributes } with string values — same name, wrong shape.\nexport { parseFrontmatter, stripFrontmatter } from './vendor/pi-frontmatter.js'\n\n// ---------------------------------------------------------------------------\n// Clipboard / image / shell helpers\n// ---------------------------------------------------------------------------\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const attempt = (command: string, args: string[]): Promise<boolean> =>\n new Promise(resolve => {\n const child = execFile(command, args, error => resolve(error === null))\n child.stdin?.write(text)\n child.stdin?.end()\n })\n if (process.platform === 'darwin') return attempt('pbcopy', [])\n if (process.platform === 'win32') return attempt('clip', [])\n if (await attempt('wl-copy', [])) return true\n return attempt('xclip', ['-selection', 'clipboard'])\n}\n\nexport interface ImageResizeOptions {\n /** Pi's default: 2000. */\n maxWidth?: number\n /** Pi's default: 2000. */\n maxHeight?: number\n /** Pi's default: 4.5MB of base64 payload. */\n maxBytes?: number\n /** Pi's default: 80. */\n jpegQuality?: number\n}\n\n/** Pi's exact result shape: base64 payload plus both the original and final size. */\nexport interface ResizedImage {\n data: string\n mimeType: string\n originalWidth: number\n originalHeight: number\n width: number\n height: number\n wasResized: boolean\n}\n\n/** Pi's defaults, so a caller passing nothing gets Pi's limits. */\nconst DEFAULT_MAX_BYTES = 4.5 * 1024 * 1024\n\n/**\n * Encode an image for inline use, reporting its true dimensions.\n *\n * Pi resizes here, using a worker and an image codec. This bridge has no\n * codec, so it does not resize — but it must not lie about the rest: the\n * payload really is base64 (packages feed this straight to a model), the\n * dimensions are read from the file header, and `wasResized` is honestly\n * false. When the image exceeds the caller's byte budget it cannot be made to\n * fit, so this returns `null` — Pi's own \"cannot produce a usable image\"\n * answer — rather than handing back something over the limit.\n * @param inputBytes - the complete image file.\n * @param mimeType - the declared image type.\n * @param options - Pi's resize budget; only `maxBytes` can be honoured here.\n */\nexport async function resizeImage(\n inputBytes: Uint8Array,\n mimeType: string,\n options: ImageResizeOptions = {},\n): Promise<ResizedImage | null> {\n const type = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (!INLINE_IMAGE_MIME_TYPES.has(type)) return null\n const data = Buffer.from(inputBytes).toString('base64')\n if (data.length > (options.maxBytes ?? DEFAULT_MAX_BYTES)) return null\n const size = readImageDimensions(inputBytes, type)\n if (size === undefined) return null\n return {\n data,\n mimeType: type,\n originalWidth: size.width,\n originalHeight: size.height,\n width: size.width,\n height: size.height,\n wasResized: false,\n }\n}\n\n/**\n * Pi's PNG conversion. Already-PNG input passes through; anything else needs\n * an image codec this bridge does not carry, so it answers `null` — the same\n * answer Pi gives when its own conversion fails, and one every caller already\n * handles.\n * @param base64Data - the image payload, base64 encoded.\n * @param mimeType - its declared type.\n */\nexport async function convertToPng(\n base64Data: string,\n mimeType: string,\n): Promise<{ data: string, mimeType: string } | null> {\n if (mimeType === 'image/png') return { data: base64Data, mimeType }\n return null\n}\n\n\n\n\n// Pi's install-directory locator: PI_PACKAGE_DIR override, else a stable\n// bridge-owned location (Pi itself falls back to its executable's directory,\n// which has no meaningful equivalent inside DSH).\nexport function getPackageDir(): string {\n const override = process.env.PI_PACKAGE_DIR\n if (override !== undefined && override.length > 0) return override\n return join(agentDirOf(), 'package')\n}\n\nexport interface StoredCredential {\n type?: string\n [key: string]: unknown\n}\n\n// Pi's one-off synchronous auth.json read, against the pi2dsh-owned agent\n// directory. DSH credentials stay authoritative for DSH model calls; this\n// serves packages that manage their own provider credentials Pi-style.\nexport function readStoredCredential(\n providerId: string,\n authPath: string = join(agentDirOf(), 'auth.json'),\n): StoredCredential | undefined {\n try {\n const data = JSON.parse(readFileSync(authPath, 'utf8')) as Record<string, StoredCredential>\n return data[providerId]\n } catch {\n return undefined\n }\n}\n\nexport interface ParsedSkillBlock {\n name: string\n content: string\n [key: string]: unknown\n}\n\n// Pi's <skill_content name=\"...\"> block parser, reimplemented over the same\n// wire shape.\nexport function parseSkillBlock(text: string): ParsedSkillBlock | null {\n const match = /<skill_content\\b[^>]*\\bname=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/skill_content>/u.exec(text)\n if (match === null) return null\n return { name: match[1]!, content: match[2]!.trim() }\n}\n\n// Vendored Pi tool wrappers (vendor/pi-tool-wrapper.ts): pure adapters from a\n// RegisteredTool/ToolDefinition to the AgentTool shape. Pi's `runner` argument\n// is used for exactly createContext() and getActiveTools(), which the pi2dsh\n// projection provides — packages composing their own agent loops get Pi's real\n// wrapping behavior.\nexport { wrapRegisteredTool, wrapRegisteredTools, wrapToolDefinition, wrapToolDefinitions } from './vendor/pi-tool-wrapper.js'\n\nexport function getBinDir(): string {\n const parts = (process.env.PATH ?? '').split(delimiter)\n return parts[0] ?? join(homedir(), '.local', 'bin')\n}\n\n// ---------------------------------------------------------------------------\n// Settings (in-memory, layered global/project like Pi)\n// ---------------------------------------------------------------------------\n\ntype SettingsRecord = Record<string, unknown>\n\nexport interface SettingsManagerCreateOptions {\n [key: string]: unknown\n}\n\nexport interface RetrySettings {\n enabled: boolean\n maxRetries: number\n baseDelayMs: number\n}\n\nexport type DefaultProjectTrust = 'ask' | 'always' | 'never'\nexport type TuiMode = 'regular' | 'fullscreen'\nexport type PackageSource = string | Record<string, unknown>\n\nexport class SettingsManager {\n private constructor(\n private globalSettings: SettingsRecord,\n private projectSettings: SettingsRecord,\n ) {}\n\n static create(_cwd?: string, _agentDir?: string, options: SettingsManagerCreateOptions = {}): SettingsManager {\n return SettingsManager.inMemory({}, options)\n }\n\n static fromStorage(_storage: unknown, options: SettingsManagerCreateOptions = {}): SettingsManager {\n return SettingsManager.inMemory({}, options)\n }\n\n static inMemory(settings: SettingsRecord = {}, _options: SettingsManagerCreateOptions = {}): SettingsManager {\n return new SettingsManager({ ...settings }, {})\n }\n\n private get merged(): SettingsRecord {\n return { ...this.globalSettings, ...this.projectSettings }\n }\n\n private read<T>(key: string, fallback: T): T {\n const value = this.merged[key]\n return value === undefined ? fallback : value as T\n }\n\n async reload(): Promise<void> {}\n async flush(): Promise<void> {}\n drainErrors(): unknown[] {\n return []\n }\n applyOverrides(overrides: SettingsRecord): void {\n Object.assign(this.globalSettings, overrides)\n }\n getGlobalSettings(): SettingsRecord {\n return { ...this.globalSettings }\n }\n getProjectSettings(): SettingsRecord {\n return { ...this.projectSettings }\n }\n isProjectTrusted(): boolean {\n return this.read('projectTrusted', false)\n }\n setProjectTrusted(trusted: boolean): void {\n this.projectSettings.projectTrusted = trusted\n }\n getDefaultProjectTrust(): DefaultProjectTrust {\n return this.read('defaultProjectTrust', 'ask')\n }\n getDefaultProvider(): string | undefined {\n return this.read('defaultProvider', undefined)\n }\n getDefaultModel(): string | undefined {\n return this.read('defaultModel', undefined)\n }\n setDefaultProvider(provider: string): void {\n this.globalSettings.defaultProvider = provider\n }\n setDefaultModel(model: string): void {\n this.globalSettings.defaultModel = model\n }\n setDefaultModelAndProvider(model: string, provider: string): void {\n this.setDefaultModel(model)\n this.setDefaultProvider(provider)\n }\n getDefaultThinkingLevel(): string | undefined {\n return this.read('defaultThinkingLevel', undefined)\n }\n getThemeSetting(): string | undefined {\n return this.read('theme', undefined)\n }\n getTheme(): string | undefined {\n return this.getThemeSetting()\n }\n setTheme(themeName: string): void {\n this.globalSettings.theme = themeName\n }\n getCompactionSettings(): CompactionSettings {\n return this.read('compaction', { ...DEFAULT_COMPACTION_SETTINGS })\n }\n getBranchSummarySettings(): { reserveTokens: number; skipPrompt: boolean } {\n return this.read('branchSummary', { reserveTokens: 8000, skipPrompt: false })\n }\n getRetrySettings(): RetrySettings {\n return this.read('retry', { enabled: true, maxRetries: 3, baseDelayMs: 1000 })\n }\n getProviderRetrySettings(): RetrySettings {\n return this.getRetrySettings()\n }\n getHttpIdleTimeoutMs(): number {\n return this.read('httpIdleTimeoutMs', 120_000)\n }\n getWebSocketConnectTimeoutMs(): number {\n return this.read('webSocketConnectTimeoutMs', 30_000)\n }\n getPackages(): PackageSource[] {\n return this.read('packages', [])\n }\n getExtensionPaths(): string[] {\n return this.read('extensions', [])\n }\n getSkillPaths(): string[] {\n return this.read('skills', [])\n }\n getPromptTemplatePaths(): string[] {\n return this.read('prompts', [])\n }\n getThemePaths(): string[] {\n return this.read('themes', [])\n }\n getTuiMode(): TuiMode {\n return this.read('tuiMode', 'regular')\n }\n getShowImages(): boolean {\n return this.read('showImages', false)\n }\n getImageWidthCells(): number {\n return this.read('imageWidthCells', 40)\n }\n getClearOnShrink(): boolean {\n return this.read('clearOnShrink', false)\n }\n getShowTerminalProgress(): boolean {\n return this.read('showTerminalProgress', false)\n }\n getHideThinkingBlock(): boolean {\n return this.read('hideThinkingBlock', false)\n }\n getExternalEditorCommand(): string | undefined {\n return this.read('externalEditorCommand', undefined)\n }\n getSteeringMode(): 'all' | 'one-at-a-time' {\n return this.read('steeringMode', 'all')\n }\n getFollowUpMode(): string {\n return this.read('followUpMode', 'queue')\n }\n getShellPath(): string | undefined {\n return this.read('shellPath', undefined)\n }\n getShellCommandPrefix(): string | undefined {\n return this.read('shellCommandPrefix', undefined)\n }\n getNpmCommand(): string[] | undefined {\n return this.read('npmCommand', undefined)\n }\n getEnableSkillCommands(): boolean {\n return this.read('enableSkillCommands', true)\n }\n getEnableAnalytics(): boolean {\n return false\n }\n getTrackingId(): string | undefined {\n return undefined\n }\n}\n\nexport class InMemorySettingsStorage {\n constructor(public settings: SettingsRecord = {}) {}\n async withLock<T>(_scope: string, fn: () => Promise<T> | T): Promise<T> {\n return fn()\n }\n}\n\nexport class FileSettingsStorage extends InMemorySettingsStorage {}\n\n\n// Vendored Pi trust store (vendor/pi-trust-store.ts): a real locked trust.json\n// under whatever agentDir the caller passes — with the redirected getAgentDir\n// convention that is package-visible state inside the DSH-owned pi2dsh\n// directory. The DSH host never consults this file; ctx.isProjectTrusted\n// stays fail-closed because host trust is a DSH decision.\nexport { ProjectTrustStore } from './vendor/pi-trust-store.js'\n\n// Pi's resource loader, headless: subagent packages construct one to control\n// a child session's resources (extensions/skills off, a system-prompt\n// override on). In the pi2dsh host the child shares the DSH composition's\n// registrations, so the loader carries the overrides and empty resource sets\n// — the exact result Pi produces under noExtensions/noSkills/noThemes.\nexport class DefaultResourceLoader {\n readonly #options: SettingsRecord\n\n constructor(options: SettingsRecord = {}) {\n this.#options = options\n }\n\n getExtensions(): { extensions: unknown[], errors: unknown[] } {\n const base = { extensions: [], errors: [] }\n const override = this.#options.extensionsOverride\n return typeof override === 'function' ? (override as (b: unknown) => never)(base) : base\n }\n\n getSkills(): { skills: unknown[], diagnostics: unknown[] } {\n return { skills: [], diagnostics: [] }\n }\n\n getPrompts(): { prompts: unknown[], diagnostics: unknown[] } {\n return { prompts: [], diagnostics: [] }\n }\n\n getThemes(): { themes: unknown[], diagnostics: unknown[] } {\n return { themes: [], diagnostics: [] }\n }\n\n getAgentsFiles(): { files: unknown[], diagnostics: unknown[] } {\n return { files: [], diagnostics: [] }\n }\n\n getSystemPrompt(): string | undefined {\n const override = this.#options.systemPromptOverride\n return typeof override === 'function' ? (override as (b: undefined) => string | undefined)(undefined) : undefined\n }\n\n getSystemPromptSource(): { kind: string } {\n return { kind: 'default' }\n }\n\n getAppendSystemPrompt(): string[] {\n const override = this.#options.appendSystemPromptOverride\n return typeof override === 'function' ? (override as (b: string[]) => string[])([]) : []\n }\n\n getAppendSystemPromptSources(): unknown[] {\n return []\n }\n\n extendResources(_paths: unknown): void {}\n\n async reload(_options?: unknown): Promise<void> {}\n}\n\n// Host-infrastructure classes stay unavailable BY DESIGN, as structured\n// capability errors a package can catch:\n// - DefaultPackageManager installs/removes packages — on DSH that is the\n// user's `dsh plugin add/remove`, behind pnpm's build-script security gate.\n// - ModelRuntime composes a full standalone model stack (credentials +\n// providers + models.json) — on DSH the ONE model directory is the host llm\n// configuration, projected through ctx.modelRegistry.\nfunction hostInfrastructureClass(name: string, reason: string, guidance: string): new (...args: unknown[]) => never {\n return class {\n constructor() {\n throw new PiCapabilityError({ capability: `new ${name}()`, reason, guidance })\n }\n } as never\n}\n\nexport const DefaultPackageManager = hostInfrastructureClass(\n 'DefaultPackageManager',\n 'installing packages is owned by the DSH host and its security gates.',\n 'Add or remove plugins with: dsh plugin add/remove <package>.',\n)\nexport const ModelRuntime = hostInfrastructureClass(\n 'ModelRuntime',\n 'the model directory is owned by the DSH host llm configuration.',\n \"Configure gateways in the host's llm settings; packages read the directory through ctx.modelRegistry.\",\n)\n\nexport class ModelRegistry {\n private models = new Map<string, unknown>()\n register(id: string, model: unknown): void {\n this.models.set(id, model)\n }\n get(id: string): unknown {\n return this.models.get(id)\n }\n list(): unknown[] {\n return [...this.models.values()]\n }\n}\n\nexport interface RegisteredToolRecord {\n definition: unknown\n sourceInfo: { path: string, source?: string, scope?: string, origin?: string }\n}\n\n// Pi's runner class, reduced to the surface tool-catalog packages actually\n// hook: pi-fabric patches `prototype.getAllRegisteredTools` to observe and\n// filter every registered tool. The pi2dsh runtime constructs one instance\n// whose provider yields the live Pi tool registrations (original definition\n// object references, so symbol-anchored detection works), and routes its own\n// tool enumeration through it — a patched prototype really filters the\n// catalog, exactly as under Pi.\nexport class ExtensionRunner {\n #provider: () => RegisteredToolRecord[]\n\n constructor(provider?: () => RegisteredToolRecord[]) {\n this.#provider = provider ?? (() => [])\n }\n\n getAllRegisteredTools(): RegisteredToolRecord[] {\n return this.#provider()\n }\n}\n\n// The mounted pi2dsh runtime installs the real factory: createAgentSession\n// builds a genuine DSH child agent through ctx.agents (the host loop's\n// factory) with Pi's public AgentSession surface bridged over it. Outside a\n// mounted runtime the call keeps its explicit failure.\ntype SubagentSessionFactory = (options: Record<string, unknown>) => Promise<{ session: unknown }>\n// Anchored on globalThis (Symbol.for), NOT module state: the shim can be\n// alive twice in one process — the engine's own chunk plus the jiti-loaded\n// copy extensions import — and a factory installed by one copy must be\n// visible to createAgentSession() in the other. Same state-splitting class\n// the shared host state guards against (\"one bridge, not per-copy silos\").\nconst FACTORY_STORE = globalThis as unknown as Record<symbol, unknown>\nconst FACTORY_KEY = Symbol.for('pi2dsh.subagentSessionFactory')\nconst SCOPED_FACTORY_KEY = Symbol.for('pi2dsh.scopedSubagentSessionFactory')\nFACTORY_STORE[SCOPED_FACTORY_KEY] ??= new AsyncLocalStorage<SubagentSessionFactory | undefined>()\nconst scopedSubagentSessionFactory = FACTORY_STORE[SCOPED_FACTORY_KEY] as AsyncLocalStorage<SubagentSessionFactory | undefined>\nconst subagentSessionFactory = (): SubagentSessionFactory | undefined =>\n FACTORY_STORE[FACTORY_KEY] as SubagentSessionFactory | undefined\n\nexport function __setSubagentSessionFactory(factory: SubagentSessionFactory | undefined): void {\n FACTORY_STORE[FACTORY_KEY] = factory\n}\n\n/** Run extension-owned work with the exact Agent runtime's child-session factory. */\nexport function __runWithSubagentSessionFactory<T>(\n factory: SubagentSessionFactory | undefined,\n callback: () => T,\n): T {\n return scopedSubagentSessionFactory.run(factory, callback)\n}\n\nexport async function createAgentSession(options: Record<string, unknown> = {}): Promise<{ session: unknown }> {\n const factory = scopedSubagentSessionFactory.getStore() ?? subagentSessionFactory()\n if (factory === undefined) {\n return unsupportedRuntime('createAgentSession() outside a mounted pi2dsh runtime')\n }\n return factory(options)\n}\n\n// Byte-identical to Pi's own composition of its built-in tool constructors\n// (core/tools/index.js): coding = read+bash+edit+write, read-only =\n// read+grep+find+ls.\nexport function createCodingTools(cwd: string, options?: Record<string, { [key: string]: unknown } | undefined>): unknown[] {\n return [\n createReadTool(cwd, options?.read),\n createBashTool(cwd, options?.bash),\n createEditTool(cwd, options?.edit),\n createWriteTool(cwd, options?.write),\n ]\n}\n\nexport function createReadOnlyTools(cwd: string, options?: Record<string, { [key: string]: unknown } | undefined>): unknown[] {\n return [\n createReadTool(cwd, options?.read),\n createGrepTool(cwd, options?.grep),\n createFindTool(cwd, options?.find),\n createLsTool(cwd, options?.ls),\n ]\n}\n\n// Vendored Pi skills loader (vendor/pi-skills-load.ts): real directory\n// discovery with Pi's exact rules (SKILL.md roots, ignore files, symlink\n// dedup, name/description validation). Default locations resolve through the\n// redirected getAgentDir, i.e. inside the DSH-owned pi2dsh directory.\nexport { loadSkills, loadSkillsFromDir } from './vendor/pi-skills-load.js'\n\n// ---------------------------------------------------------------------------\n// Headless host services backing the vendored built-in tools. Each mirrors a\n// documented Pi behavior for environments without the full interactive host:\n// ensureTool matches Pi's own offline mode (find on PATH, never download);\n// highlightCode matches Pi's no-language branch (plain lines — the headless\n// theme applies no styling anyway); processImage passes supported formats\n// through un-resized (Pi's resize/convert path runs a WASM codec that has no\n// place in a headless bridge; oversized or exotic images degrade with Pi's\n// own omission message).\n// ---------------------------------------------------------------------------\n\nexport function getReadmePath(): string {\n return join(getPackageDir(), 'README.md')\n}\n\nconst MANAGED_HOST_TOOLS = new Set(['rg', 'fd'])\n\nexport function getToolPath(tool: string): string | undefined {\n const pathKey = Object.keys(process.env).find(key => key.toLowerCase() === 'path') ?? 'PATH'\n for (const dir of (process.env[pathKey] ?? '').split(delimiter)) {\n if (dir.length === 0) continue\n const candidate = join(dir, process.platform === 'win32' ? `${tool}.exe` : tool)\n if (existsSync(candidate)) return candidate\n }\n return undefined\n}\n\nexport async function ensureTool(tool: string, _silent = false): Promise<string | undefined> {\n const existing = getToolPath(tool)\n if (existing !== undefined) return existing\n // Pi's offline mode semantics: a managed tool that is not on PATH is\n // reported unavailable instead of downloaded.\n return MANAGED_HOST_TOOLS.has(tool) ? undefined : undefined\n}\n\nconst INLINE_IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/gif', 'image/webp'])\n\nexport async function processImage(\n bytes: Uint8Array,\n mimeType: string,\n _options?: { autoResizeImages?: boolean },\n): Promise<\n | { ok: true, data: string, mimeType: string, hints: string[] }\n | { ok: false, message: string }\n> {\n const base = mimeType.split(';')[0]?.trim().toLowerCase() ?? ''\n if (!INLINE_IMAGE_MIME_TYPES.has(base)) {\n return { ok: false, message: '[Image omitted: could not be converted to a supported inline image format.]' }\n }\n return {\n ok: true,\n data: Buffer.from(bytes).toString('base64'),\n mimeType: base,\n hints: ['[Image passed through unresized by pi2dsh.]'],\n }\n}\n\n\n\nexport { formatSkillsForPrompt } from './vendor/pi-skills-format.js'\n\n// Pi's own implementations, vendored. Hand-written stand-ins for these three\n// diverged from Pi in ways a package cannot see: a shell picked from $SHELL\n// where Pi is bash-only, head-truncation where Pi keeps the tail, and a diff\n// renderer with a different signature entirely.\nexport { getShellConfig, type ShellConfig } from './vendor/pi-shell-config.js'\nexport { truncateToVisualLines } from './vendor/pi-tools/visual-truncate.js'\nexport { renderDiff } from './vendor/pi-tools/diff-component.js'\n\nexport function createEventBus(): {\n emit(channel: string, data: unknown): void\n on(channel: string, handler: (data: unknown) => void): () => void\n clear(): void\n} {\n const handlers = new Map<string, Set<(data: unknown) => void>>()\n return {\n emit(channel, data) {\n for (const handler of handlers.get(channel) ?? []) {\n Promise.resolve().then(() => handler(data)).catch(error => console.error(error))\n }\n },\n on(channel, handler) {\n const set = handlers.get(channel) ?? new Set()\n set.add(handler)\n handlers.set(channel, set)\n return () => {\n set.delete(handler)\n }\n },\n clear() {\n handlers.clear()\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Interactive-mode UI components (headless)\n// ---------------------------------------------------------------------------\n\nclass HeadlessComponent implements Component {\n render(_width: number): string[] {\n return []\n }\n invalidate(): void {}\n}\n\nexport class ToolExecutionComponent extends HeadlessComponent {}\nexport class FooterComponent extends HeadlessComponent {}\nexport class BorderedLoader extends HeadlessComponent {\n start(): void {}\n stop(): void {}\n dispose(): void {}\n}\nexport class CustomMessageComponent extends HeadlessComponent {}\nexport class AssistantMessageComponent extends HeadlessComponent {}\nexport class UserMessageComponent extends HeadlessComponent {}\nexport class ExtensionSelectorComponent extends HeadlessComponent {}\nexport class ExtensionInputComponent extends HeadlessComponent {}\nexport class ExtensionEditorComponent extends HeadlessComponent {}\nexport class SettingsSelectorComponent extends HeadlessComponent {}\n\nexport class CustomEditor extends HeadlessComponent {\n private text = ''\n onSubmit?: (text: string) => void\n onChange?: (text: string) => void\n getText(): string {\n return this.text\n }\n setText(text: string): void {\n this.text = text\n this.onChange?.(text)\n }\n handleInput(data: string): void {\n if (data === '\\r' || data === '\\n') {\n this.onSubmit?.(this.text)\n return\n }\n if (data >= ' ') this.setText(this.text + data)\n }\n}\n\nexport interface ToolExecutionOptions {\n [key: string]: unknown\n}\nexport interface SettingsConfig {\n [key: string]: unknown\n}\nexport interface SettingsCallbacks {\n [key: string]: unknown\n}\nexport interface RenderDiffOptions {\n [key: string]: unknown\n}\n\n\n\nexport interface VisualTruncateResult {\n visualLines: string[]\n skippedCount: number\n}\n\n\n\nexport function keyHint(keybinding: string, description: string): string {\n return `${keybinding} ${description}`\n}\n\nexport function keyText(keybinding: string): string {\n return keybinding\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n return `${key} ${description}`\n}\n"],"mappings":"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"}