pi2dsh 0.3.4 → 0.3.5

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-coding-agent-DuqSaquA.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","truncateToVisualLines","getBinDir","joinBinDir","getAgentDirForBin","getShellConfig","nodeResolvePath","replaceTabs","Type.Object","Type.String","Type.Optional","Type.Number","getShellConfig","fsAccess","truncateToVisualLines","Type.Object","Type.String","Type.Optional","Type.Number","fsReadFile","fsAccess","constants","trimTrailingEmptyLines","resolvePath","replaceTabs","renderDiff","access","constants","readFile","Type.Object","Type.String","Type.Array","fsReadFile","fsWriteFile","fsAccess","constants","renderDiff","Type.Object","Type.String","fsWriteFile","fsMkdir","replaceTabs","dirname","Type.Object","Type.String","Type.Optional","Type.Boolean","Type.Number","DEFAULT_LIMIT","fsStat","fsReadFile","createInterface","Type.Object","Type.String","Type.Optional","Type.Number","DEFAULT_LIMIT","createInterface","Type.Object","Type.Optional","Type.String","Type.Number","fsStat","fsReaddir","path","nodePath","agentDirOf","#options","#provider"],"sources":["../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-skills-format.ts","../src/compat/pi-coding-agent.ts"],"sourcesContent":["// @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 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","// 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// file-mutation queue) — byte-level Pi semantics, see ./vendor/PI-LICENSE.\n// 2. Headless reimplementations (Theme, settings, shell/clipboard/image\n// helpers) — same signatures, no terminal or Pi-global state.\n// 3. Explicit-failure stubs (AgentSession runtime, resource loaders) —\n// importable and constructible so packages load, but running them\n// requires a native DSH port and fails with a clear message instead of\n// silently faking success.\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\nfunction contentChars(content: unknown): number {\n if (typeof content === 'string') return content.length\n if (!Array.isArray(content)) return 0\n let chars = 0\n for (const block of content) {\n if (typeof block !== 'object' || block === null) continue\n const record = block as Record<string, unknown>\n if (typeof record.text === 'string') chars += record.text.length\n else if (typeof record.thinking === 'string') chars += record.thinking.length\n else if (record.type === 'image') chars += 1600\n else if (record.arguments !== undefined) chars += JSON.stringify(record.arguments ?? {}).length\n }\n return chars\n}\n\n// chars/4 heuristic, matching Pi's estimateTokens semantics.\nexport function estimateTokens(message: AgentMessage): number {\n const record = message as Record<string, unknown>\n let chars = contentChars(record.content)\n if (typeof record.summary === 'string') chars += (record.summary as string).length\n if (record.role === 'bashExecution') {\n chars += String(record.command ?? '').length + String(record.output ?? '').length\n }\n return Math.ceil(chars / 4)\n}\n\nexport function calculateContextTokens(messages: AgentMessage[]): number {\n return messages.reduce((total, message) => total + estimateTokens(message), 0)\n}\n\nexport const DEFAULT_COMPACTION_SETTINGS = Object.freeze({\n enabled: true,\n reserveTokens: 30_000,\n keepRecentTokens: 20_000,\n})\n\nexport function shouldCompact(..._args: unknown[]): boolean {\n return false\n}\n\nexport function compact(..._args: unknown[]): never {\n return unsupportedRuntime('compact()')\n}\n\nexport function findCutPoint(..._args: unknown[]): never {\n return unsupportedRuntime('findCutPoint()')\n}\n\nexport function generateSummary(..._args: unknown[]): never {\n return unsupportedRuntime('generateSummary()')\n}\n\nexport function generateSummaryWithUsage(..._args: unknown[]): never {\n return unsupportedRuntime('generateSummaryWithUsage()')\n}\n\nexport function generateBranchSummary(..._args: unknown[]): never {\n return unsupportedRuntime('generateBranchSummary()')\n}\n\nexport function serializeConversation(messages: AgentMessage[]): string {\n return JSON.stringify(messages)\n}\n\n// ---------------------------------------------------------------------------\n// Frontmatter\n// ---------------------------------------------------------------------------\n\nexport function parseFrontmatter(text: string): { attributes: Record<string, string>; body: string } {\n const normalized = text.replace(/\\r\\n?/gu, '\\n')\n if (!normalized.startsWith('---')) return { attributes: {}, body: normalized }\n const endIndex = normalized.indexOf('\\n---', 3)\n if (endIndex === -1) return { attributes: {}, body: normalized }\n const attributes: Record<string, string> = {}\n for (const line of normalized.slice(4, endIndex).split('\\n')) {\n const separator = line.indexOf(':')\n if (separator === -1) continue\n const key = line.slice(0, separator).trim()\n let value = line.slice(separator + 1).trim()\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n if (key.length > 0) attributes[key] = value\n }\n return { attributes, body: normalized.slice(endIndex + 4).replace(/^\\n/u, '') }\n}\n\nexport function stripFrontmatter(text: string): string {\n return parseFrontmatter(text).body\n}\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 maxWidth?: number\n maxHeight?: number\n [key: string]: unknown\n}\n\nexport interface ResizedImage {\n data: string\n mimeType: string\n width?: number\n height?: number\n [key: string]: unknown\n}\n\n// Headless degradation: images pass through un-resized. Pi resizes only to\n// save tokens, so returning the original preserves correctness.\nexport async function resizeImage(\n data: string,\n mimeType: string,\n _options: ImageResizeOptions = {},\n): Promise<ResizedImage> {\n return { data, mimeType }\n}\n\nexport async function convertToPng(data: string, mimeType: string): Promise<ResizedImage> {\n if (mimeType === 'image/png') return { data, mimeType }\n return unsupportedRuntime('convertToPng() for non-PNG input')\n}\n\nexport interface ShellConfig {\n shell: string\n args: string[]\n}\n\nexport function getShellConfig(): ShellConfig {\n if (process.platform === 'win32') {\n return { shell: process.env.COMSPEC ?? 'cmd.exe', args: ['/d', '/s', '/c'] }\n }\n const preferred = process.env.SHELL\n if (preferred !== undefined && preferred.length > 0 && existsSync(preferred)) {\n return { shell: preferred, args: ['-c'] }\n }\n for (const candidate of ['/bin/bash', '/bin/zsh', '/bin/sh']) {\n if (existsSync(candidate)) return { shell: candidate, args: ['-c'] }\n }\n return { shell: 'sh', args: ['-c'] }\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\nexport function wrapRegisteredTool(..._args: unknown[]): never {\n return unsupportedRuntime('wrapRegisteredTool()')\n}\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 interface CompactionSettings {\n enabled: boolean\n reserveTokens: number\n keepRecentTokens: 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// Explicit-failure stubs for Pi's internal agent runtime\n// ---------------------------------------------------------------------------\n\nfunction runtimeStubClass(name: string): new (...args: unknown[]) => never {\n return class {\n constructor() {\n return unsupportedRuntime(`new ${name}()`)\n }\n } as never\n}\n\nexport const ProjectTrustStore = runtimeStubClass('ProjectTrustStore')\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\nexport const DefaultPackageManager = runtimeStubClass('DefaultPackageManager')\nexport const ModelRuntime = runtimeStubClass('ModelRuntime')\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\n\nexport function __setSubagentSessionFactory(factory: SubagentSessionFactory | undefined): void {\n subagentSessionFactory = factory\n}\n\nexport async function createAgentSession(options: Record<string, unknown> = {}): Promise<{ session: unknown }> {\n if (subagentSessionFactory === undefined) {\n return unsupportedRuntime('createAgentSession() outside a mounted pi2dsh runtime')\n }\n return subagentSessionFactory(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\nexport function loadSkills(..._args: unknown[]): never {\n return unsupportedRuntime('loadSkills()')\n}\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\nexport function loadSkillsFromDir(..._args: unknown[]): never {\n return unsupportedRuntime('loadSkillsFromDir()')\n}\n\nexport { formatSkillsForPrompt } from './vendor/pi-skills-format.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\nexport function renderDiff(oldText: string, newText: string, _options: RenderDiffOptions = {}): string[] {\n const removed = oldText.split('\\n').map(line => `- ${line}`)\n const added = newText.split('\\n').map(line => `+ ${line}`)\n return [...removed, ...added]\n}\n\nexport interface VisualTruncateResult {\n visualLines: string[]\n skippedCount: number\n}\n\nexport function truncateToVisualLines(\n text: string,\n maxVisualLines: number,\n width: number,\n paddingX = 0,\n): VisualTruncateResult {\n const inner = Math.max(1, width - paddingX * 2)\n const lines = text.split('\\n').map(line =>\n visibleWidth(line) > inner ? truncateToWidth(line, inner) : line)\n return {\n visualLines: lines.slice(0, Math.max(0, maxVisualLines)),\n skippedCount: Math.max(0, lines.length - maxVisualLines),\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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"}