@mariozechner/pi-coding-agent 0.43.0 → 0.44.0

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +3 -0
  3. package/dist/core/agent-session.d.ts +5 -2
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +6 -3
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/extensions/index.d.ts +1 -1
  8. package/dist/core/extensions/index.d.ts.map +1 -1
  9. package/dist/core/extensions/index.js.map +1 -1
  10. package/dist/core/extensions/loader.d.ts.map +1 -1
  11. package/dist/core/extensions/loader.js +8 -0
  12. package/dist/core/extensions/loader.js.map +1 -1
  13. package/dist/core/extensions/runner.d.ts.map +1 -1
  14. package/dist/core/extensions/runner.js +2 -0
  15. package/dist/core/extensions/runner.js.map +1 -1
  16. package/dist/core/extensions/types.d.ts +13 -3
  17. package/dist/core/extensions/types.d.ts.map +1 -1
  18. package/dist/core/extensions/types.js.map +1 -1
  19. package/dist/core/session-manager.d.ts +13 -2
  20. package/dist/core/session-manager.d.ts.map +1 -1
  21. package/dist/core/session-manager.js +37 -2
  22. package/dist/core/session-manager.js.map +1 -1
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  27. package/dist/modes/interactive/components/session-selector.js +30 -9
  28. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  29. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  30. package/dist/modes/interactive/components/settings-selector.js +1 -1
  31. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  32. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  33. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  34. package/dist/modes/interactive/interactive-mode.js +41 -2
  35. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  36. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  37. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  38. package/dist/modes/interactive/theme/theme.js +22 -8
  39. package/dist/modes/interactive/theme/theme.js.map +1 -1
  40. package/dist/modes/print-mode.d.ts.map +1 -1
  41. package/dist/modes/print-mode.js +7 -1
  42. package/dist/modes/print-mode.js.map +1 -1
  43. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  44. package/dist/modes/rpc/rpc-mode.js +7 -1
  45. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  46. package/docs/extensions.md +21 -0
  47. package/docs/session.md +12 -0
  48. package/docs/tui.md +1 -0
  49. package/examples/extensions/README.md +1 -0
  50. package/examples/extensions/notify.ts +25 -0
  51. package/examples/extensions/preset.ts +3 -3
  52. package/examples/extensions/tools.ts +7 -6
  53. package/examples/extensions/with-deps/package-lock.json +2 -2
  54. package/examples/extensions/with-deps/package.json +1 -1
  55. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { ImageContent, Message, TextContent } from \"@mariozechner/pi-ai\";\nimport { randomUUID } from \"crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadFileSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, readFile, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir } from \"../config.js\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CustomMessage,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"./messages.js\";\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\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/** 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/** 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/**\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\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}\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\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| \"getHeader\"\n\t| \"getEntries\"\n\t| \"getTree\"\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\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\t// Build uuid index if not available\n\tif (!byId) {\n\t\tbyId = new Map<string, SessionEntry>();\n\t\tfor (const entry of entries) {\n\t\t\tbyId.set(entry.id, entry);\n\t\t}\n\t}\n\n\t// Find leaf\n\tlet leaf: SessionEntry | undefined;\n\tif (leafId === null) {\n\t\t// Explicitly null - return no messages (navigated to before first entry)\n\t\treturn { messages: [], thinkingLevel: \"off\", model: null };\n\t}\n\tif (leafId) {\n\t\tleaf = byId.get(leafId);\n\t}\n\tif (!leaf) {\n\t\t// Fallback to last entry (when leafId is undefined)\n\t\tleaf = entries[entries.length - 1];\n\t}\n\n\tif (!leaf) {\n\t\treturn { messages: [], thinkingLevel: \"off\", model: null };\n\t}\n\n\t// Walk from leaf to root, collecting path\n\tconst path: SessionEntry[] = [];\n\tlet current: SessionEntry | undefined = leaf;\n\twhile (current) {\n\t\tpath.unshift(current);\n\t\tcurrent = current.parentId ? byId.get(current.parentId) : undefined;\n\t}\n\n\t// Extract settings and find compaction\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\tlet compaction: CompactionEntry | 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} else if (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\n\t// Build messages and collect corresponding entries\n\t// When there's a compaction, we need to:\n\t// 1. Emit summary first (entry = compaction)\n\t// 2. Emit kept messages (from firstKeptEntryId up to compaction)\n\t// 3. Emit messages after compaction\n\tconst messages: AgentMessage[] = [];\n\n\tconst appendMessage = (entry: SessionEntry) => {\n\t\tif (entry.type === \"message\") {\n\t\t\tmessages.push(entry.message);\n\t\t} else if (entry.type === \"custom_message\") {\n\t\t\tmessages.push(\n\t\t\t\tcreateCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp),\n\t\t\t);\n\t\t} else if (entry.type === \"branch_summary\" && entry.summary) {\n\t\t\tmessages.push(createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));\n\t\t}\n\t};\n\n\tif (compaction) {\n\t\t// Emit summary first\n\t\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\n\t\t// Find compaction index in path\n\t\tconst compactionIdx = path.findIndex((e) => e.type === \"compaction\" && e.id === compaction.id);\n\n\t\t// Emit kept messages (before compaction, starting from firstKeptEntryId)\n\t\tlet foundFirstKept = false;\n\t\tfor (let i = 0; i < compactionIdx; i++) {\n\t\t\tconst entry = path[i];\n\t\t\tif (entry.id === compaction.firstKeptEntryId) {\n\t\t\t\tfoundFirstKept = true;\n\t\t\t}\n\t\t\tif (foundFirstKept) {\n\t\t\t\tappendMessage(entry);\n\t\t\t}\n\t\t}\n\n\t\t// Emit messages after compaction\n\t\tfor (let i = compactionIdx + 1; i < path.length; i++) {\n\t\t\tconst entry = path[i];\n\t\t\tappendMessage(entry);\n\t\t}\n\t} else {\n\t\t// No compaction - emit all messages, handle branch summaries and custom messages\n\t\tfor (const entry of path) {\n\t\t\tappendMessage(entry);\n\t\t}\n\t}\n\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 getDefaultSessionDir(cwd: string): string {\n\tconst safePath = `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\tconst sessionDir = join(getDefaultAgentDir(), \"sessions\", safePath);\n\tif (!existsSync(sessionDir)) {\n\t\tmkdirSync(sessionDir, { recursive: true });\n\t}\n\treturn sessionDir;\n}\n\n/** Exported for testing */\nexport function loadEntriesFromFile(filePath: string): FileEntry[] {\n\tif (!existsSync(filePath)) return [];\n\n\tconst content = readFileSync(filePath, \"utf8\");\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\t// Validate session header\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as any).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\nfunction isValidSessionFile(filePath: string): boolean {\n\ttry {\n\t\tconst fd = openSync(filePath, \"r\");\n\t\tconst buffer = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buffer, 0, 512, 0);\n\t\tcloseSync(fd);\n\t\tconst firstLine = buffer.toString(\"utf8\", 0, bytesRead).split(\"\\n\")[0];\n\t\tif (!firstLine) return false;\n\t\tconst header = JSON.parse(firstLine);\n\t\treturn header.type === \"session\" && typeof header.id === \"string\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Exported for testing */\nexport function findMostRecentSession(sessionDir: string): string | null {\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(sessionDir, f))\n\t\t\t.filter(isValidSessionFile)\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\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\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst content = await readFile(filePath, \"utf8\");\n\t\tconst entries: FileEntry[] = [];\n\t\tconst lines = content.trim().split(\"\\n\");\n\n\t\tfor (const line of lines) {\n\t\t\tif (!line.trim()) continue;\n\t\t\ttry {\n\t\t\t\tentries.push(JSON.parse(line) as FileEntry);\n\t\t\t} catch {\n\t\t\t\t// Skip malformed lines\n\t\t\t}\n\t\t}\n\n\t\tif (entries.length === 0) return null;\n\t\tconst header = entries[0];\n\t\tif (header.type !== \"session\") return null;\n\n\t\tconst stats = await stat(filePath);\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst message = (entry as SessionMessageEntry).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\tconst cwd = typeof (header as SessionHeader).cwd === \"string\" ? (header as SessionHeader).cwd : \"\";\n\n\t\treturn {\n\t\t\tpath: filePath,\n\t\t\tid: (header as SessionHeader).id,\n\t\t\tcwd,\n\t\t\tcreated: new Date((header as SessionHeader).timestamp),\n\t\t\tmodified: stats.mtime,\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\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 Promise.all(\n\t\t\tfiles.map(async (file) => {\n\t\t\t\tconst info = await buildSessionInfo(file);\n\t\t\t\tloaded++;\n\t\t\t\tonProgress?.(progressOffset + loaded, total);\n\t\t\t\treturn info;\n\t\t\t}),\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 leafId: string | null = null;\n\n\tprivate constructor(cwd: string, sessionDir: string, sessionFile: string | undefined, persist: boolean) {\n\t\tthis.cwd = cwd;\n\t\tthis.sessionDir = sessionDir;\n\t\tthis.persist = persist;\n\t\tif (persist && sessionDir && !existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tif (sessionFile) {\n\t\t\tthis.setSessionFile(sessionFile);\n\t\t} else {\n\t\t\tthis.newSession();\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.sessionFile = resolve(sessionFile);\n\t\tif (existsSync(this.sessionFile)) {\n\t\t\tthis.fileEntries = loadEntriesFromFile(this.sessionFile);\n\t\t\tconst header = this.fileEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\t\tthis.sessionId = header?.id ?? randomUUID();\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\tthis.newSession();\n\t\t}\n\t}\n\n\tnewSession(options?: NewSessionOptions): string | undefined {\n\t\tthis.sessionId = randomUUID();\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.leafId = null;\n\t\tthis.flushed = false;\n\n\t\t// Only generate filename if persisting and not already set (e.g., via --session flag)\n\t\tif (this.persist && !this.sessionFile) {\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.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} else {\n\t\t\t\t\tthis.labelsById.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 content = `${this.fileEntries.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`;\n\t\twriteFileSync(this.sessionFile, content);\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\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) return;\n\n\t\tif (!this.flushed) {\n\t\t\tfor (const e of this.fileEntries) {\n\t\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(e)}\\n`);\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): 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\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/**\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} else {\n\t\t\tthis.labelsById.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.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\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\tnodeMap.set(entry.id, { entry, children: [], label });\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(branchFromId: string | null, summary: string, details?: unknown, fromHook?: boolean): 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\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 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\tconst pathWithoutLabels = path.filter((e) => e.type !== \"label\");\n\n\t\tconst newSessionId = randomUUID();\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 ? this.sessionFile : 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 }> = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (pathEntryIds.has(targetId)) {\n\t\t\t\tlabelsToWrite.push({ targetId, label });\n\t\t\t}\n\t\t}\n\n\t\tif (this.persist) {\n\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(header)}\\n`);\n\t\t\tfor (const entry of pathWithoutLabels) {\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t\t// Write fresh label entries at the end\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 } 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: new Date().toISOString(),\n\t\t\t\t\ttargetId,\n\t\t\t\t\tlabel,\n\t\t\t\t};\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(labelEntry)}\\n`);\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\t\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\t\tthis.sessionId = newSessionId;\n\t\t\tthis._buildIndex();\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 } 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: new Date().toISOString(),\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): SessionManager {\n\t\tconst dir = sessionDir ?? getDefaultSessionDir(cwd);\n\t\treturn new SessionManager(cwd, dir, undefined, true);\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 */\n\tstatic open(path: string, sessionDir?: string): SessionManager {\n\t\t// Extract cwd from session header if possible, otherwise use process.cwd()\n\t\tconst entries = loadEntriesFromFile(path);\n\t\tconst header = entries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\tconst cwd = header?.cwd ?? process.cwd();\n\t\t// If no sessionDir provided, derive from file's parent directory\n\t\tconst dir = sessionDir ?? resolve(path, \"..\");\n\t\treturn new SessionManager(cwd, dir, path, true);\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 ?? getDefaultSessionDir(cwd);\n\t\tconst mostRecent = findMostRecentSession(dir);\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()): SessionManager {\n\t\treturn new SessionManager(cwd, \"\", undefined, false);\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 ?? getDefaultSessionDir(cwd);\n\t\tconst sessions = await listSessionsFromDir(dir, onProgress);\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\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.filter((e) => e.isDirectory()).map((e) => join(sessionsDir, e.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 Promise.all(\n\t\t\t\tallFiles.map(async (file) => {\n\t\t\t\t\tconst info = await buildSessionInfo(file);\n\t\t\t\t\tloaded++;\n\t\t\t\t\tonProgress?.(loaded, totalFiles);\n\t\t\t\t\treturn info;\n\t\t\t\t}),\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"]}
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { ImageContent, Message, TextContent } from \"@mariozechner/pi-ai\";\nimport { randomUUID } from \"crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadFileSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, readFile, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir } from \"../config.js\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CustomMessage,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"./messages.js\";\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\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/** 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/** 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}\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\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| \"getHeader\"\n\t| \"getEntries\"\n\t| \"getTree\"\n\t| \"getSessionName\"\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\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\t// Build uuid index if not available\n\tif (!byId) {\n\t\tbyId = new Map<string, SessionEntry>();\n\t\tfor (const entry of entries) {\n\t\t\tbyId.set(entry.id, entry);\n\t\t}\n\t}\n\n\t// Find leaf\n\tlet leaf: SessionEntry | undefined;\n\tif (leafId === null) {\n\t\t// Explicitly null - return no messages (navigated to before first entry)\n\t\treturn { messages: [], thinkingLevel: \"off\", model: null };\n\t}\n\tif (leafId) {\n\t\tleaf = byId.get(leafId);\n\t}\n\tif (!leaf) {\n\t\t// Fallback to last entry (when leafId is undefined)\n\t\tleaf = entries[entries.length - 1];\n\t}\n\n\tif (!leaf) {\n\t\treturn { messages: [], thinkingLevel: \"off\", model: null };\n\t}\n\n\t// Walk from leaf to root, collecting path\n\tconst path: SessionEntry[] = [];\n\tlet current: SessionEntry | undefined = leaf;\n\twhile (current) {\n\t\tpath.unshift(current);\n\t\tcurrent = current.parentId ? byId.get(current.parentId) : undefined;\n\t}\n\n\t// Extract settings and find compaction\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\tlet compaction: CompactionEntry | 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} else if (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\n\t// Build messages and collect corresponding entries\n\t// When there's a compaction, we need to:\n\t// 1. Emit summary first (entry = compaction)\n\t// 2. Emit kept messages (from firstKeptEntryId up to compaction)\n\t// 3. Emit messages after compaction\n\tconst messages: AgentMessage[] = [];\n\n\tconst appendMessage = (entry: SessionEntry) => {\n\t\tif (entry.type === \"message\") {\n\t\t\tmessages.push(entry.message);\n\t\t} else if (entry.type === \"custom_message\") {\n\t\t\tmessages.push(\n\t\t\t\tcreateCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp),\n\t\t\t);\n\t\t} else if (entry.type === \"branch_summary\" && entry.summary) {\n\t\t\tmessages.push(createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));\n\t\t}\n\t};\n\n\tif (compaction) {\n\t\t// Emit summary first\n\t\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\n\t\t// Find compaction index in path\n\t\tconst compactionIdx = path.findIndex((e) => e.type === \"compaction\" && e.id === compaction.id);\n\n\t\t// Emit kept messages (before compaction, starting from firstKeptEntryId)\n\t\tlet foundFirstKept = false;\n\t\tfor (let i = 0; i < compactionIdx; i++) {\n\t\t\tconst entry = path[i];\n\t\t\tif (entry.id === compaction.firstKeptEntryId) {\n\t\t\t\tfoundFirstKept = true;\n\t\t\t}\n\t\t\tif (foundFirstKept) {\n\t\t\t\tappendMessage(entry);\n\t\t\t}\n\t\t}\n\n\t\t// Emit messages after compaction\n\t\tfor (let i = compactionIdx + 1; i < path.length; i++) {\n\t\t\tconst entry = path[i];\n\t\t\tappendMessage(entry);\n\t\t}\n\t} else {\n\t\t// No compaction - emit all messages, handle branch summaries and custom messages\n\t\tfor (const entry of path) {\n\t\t\tappendMessage(entry);\n\t\t}\n\t}\n\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 getDefaultSessionDir(cwd: string): string {\n\tconst safePath = `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\tconst sessionDir = join(getDefaultAgentDir(), \"sessions\", safePath);\n\tif (!existsSync(sessionDir)) {\n\t\tmkdirSync(sessionDir, { recursive: true });\n\t}\n\treturn sessionDir;\n}\n\n/** Exported for testing */\nexport function loadEntriesFromFile(filePath: string): FileEntry[] {\n\tif (!existsSync(filePath)) return [];\n\n\tconst content = readFileSync(filePath, \"utf8\");\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\t// Validate session header\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as any).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\nfunction isValidSessionFile(filePath: string): boolean {\n\ttry {\n\t\tconst fd = openSync(filePath, \"r\");\n\t\tconst buffer = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buffer, 0, 512, 0);\n\t\tcloseSync(fd);\n\t\tconst firstLine = buffer.toString(\"utf8\", 0, bytesRead).split(\"\\n\")[0];\n\t\tif (!firstLine) return false;\n\t\tconst header = JSON.parse(firstLine);\n\t\treturn header.type === \"session\" && typeof header.id === \"string\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Exported for testing */\nexport function findMostRecentSession(sessionDir: string): string | null {\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(sessionDir, f))\n\t\t\t.filter(isValidSessionFile)\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\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\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst content = await readFile(filePath, \"utf8\");\n\t\tconst entries: FileEntry[] = [];\n\t\tconst lines = content.trim().split(\"\\n\");\n\n\t\tfor (const line of lines) {\n\t\t\tif (!line.trim()) continue;\n\t\t\ttry {\n\t\t\t\tentries.push(JSON.parse(line) as FileEntry);\n\t\t\t} catch {\n\t\t\t\t// Skip malformed lines\n\t\t\t}\n\t\t}\n\n\t\tif (entries.length === 0) return null;\n\t\tconst header = entries[0];\n\t\tif (header.type !== \"session\") return null;\n\n\t\tconst stats = await stat(filePath);\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\t\tlet name: string | undefined;\n\n\t\tfor (const entry of entries) {\n\t\t\t// Extract session name (use latest)\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\tconst infoEntry = entry as SessionInfoEntry;\n\t\t\t\tif (infoEntry.name) {\n\t\t\t\t\tname = infoEntry.name.trim();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst message = (entry as SessionMessageEntry).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\tconst cwd = typeof (header as SessionHeader).cwd === \"string\" ? (header as SessionHeader).cwd : \"\";\n\n\t\treturn {\n\t\t\tpath: filePath,\n\t\t\tid: (header as SessionHeader).id,\n\t\t\tcwd,\n\t\t\tname,\n\t\t\tcreated: new Date((header as SessionHeader).timestamp),\n\t\t\tmodified: stats.mtime,\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\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 Promise.all(\n\t\t\tfiles.map(async (file) => {\n\t\t\t\tconst info = await buildSessionInfo(file);\n\t\t\t\tloaded++;\n\t\t\t\tonProgress?.(progressOffset + loaded, total);\n\t\t\t\treturn info;\n\t\t\t}),\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 leafId: string | null = null;\n\n\tprivate constructor(cwd: string, sessionDir: string, sessionFile: string | undefined, persist: boolean) {\n\t\tthis.cwd = cwd;\n\t\tthis.sessionDir = sessionDir;\n\t\tthis.persist = persist;\n\t\tif (persist && sessionDir && !existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tif (sessionFile) {\n\t\t\tthis.setSessionFile(sessionFile);\n\t\t} else {\n\t\t\tthis.newSession();\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.sessionFile = resolve(sessionFile);\n\t\tif (existsSync(this.sessionFile)) {\n\t\t\tthis.fileEntries = loadEntriesFromFile(this.sessionFile);\n\t\t\tconst header = this.fileEntries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\t\tthis.sessionId = header?.id ?? randomUUID();\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\tthis.sessionId = randomUUID();\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.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.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} else {\n\t\t\t\t\tthis.labelsById.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 content = `${this.fileEntries.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`;\n\t\twriteFileSync(this.sessionFile, content);\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\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) return;\n\n\t\tif (!this.flushed) {\n\t\t\tfor (const e of this.fileEntries) {\n\t\t\t\tappendFileSync(this.sessionFile, `${JSON.stringify(e)}\\n`);\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): 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\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 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: name.trim(),\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 with a name\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\" && entry.name) {\n\t\t\t\treturn entry.name;\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} else {\n\t\t\tthis.labelsById.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.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\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\tnodeMap.set(entry.id, { entry, children: [], label });\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(branchFromId: string | null, summary: string, details?: unknown, fromHook?: boolean): 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\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 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\tconst pathWithoutLabels = path.filter((e) => e.type !== \"label\");\n\n\t\tconst newSessionId = randomUUID();\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 ? this.sessionFile : 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 }> = [];\n\t\tfor (const [targetId, label] of this.labelsById) {\n\t\t\tif (pathEntryIds.has(targetId)) {\n\t\t\t\tlabelsToWrite.push({ targetId, label });\n\t\t\t}\n\t\t}\n\n\t\tif (this.persist) {\n\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(header)}\\n`);\n\t\t\tfor (const entry of pathWithoutLabels) {\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(entry)}\\n`);\n\t\t\t}\n\t\t\t// Write fresh label entries at the end\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 } 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: new Date().toISOString(),\n\t\t\t\t\ttargetId,\n\t\t\t\t\tlabel,\n\t\t\t\t};\n\t\t\t\tappendFileSync(newSessionFile, `${JSON.stringify(labelEntry)}\\n`);\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\t\t\tthis.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];\n\t\t\tthis.sessionId = newSessionId;\n\t\t\tthis._buildIndex();\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 } 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: new Date().toISOString(),\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): SessionManager {\n\t\tconst dir = sessionDir ?? getDefaultSessionDir(cwd);\n\t\treturn new SessionManager(cwd, dir, undefined, true);\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 */\n\tstatic open(path: string, sessionDir?: string): SessionManager {\n\t\t// Extract cwd from session header if possible, otherwise use process.cwd()\n\t\tconst entries = loadEntriesFromFile(path);\n\t\tconst header = entries.find((e) => e.type === \"session\") as SessionHeader | undefined;\n\t\tconst cwd = header?.cwd ?? process.cwd();\n\t\t// If no sessionDir provided, derive from file's parent directory\n\t\tconst dir = sessionDir ?? resolve(path, \"..\");\n\t\treturn new SessionManager(cwd, dir, path, true);\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 ?? getDefaultSessionDir(cwd);\n\t\tconst mostRecent = findMostRecentSession(dir);\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()): SessionManager {\n\t\treturn new SessionManager(cwd, \"\", undefined, false);\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 ?? getDefaultSessionDir(cwd);\n\t\tconst sessions = await listSessionsFromDir(dir, onProgress);\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\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.filter((e) => e.isDirectory()).map((e) => join(sessionsDir, e.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 Promise.all(\n\t\t\t\tallFiles.map(async (file) => {\n\t\t\t\t\tconst info = await buildSessionInfo(file);\n\t\t\t\t\tloaded++;\n\t\t\t\t\tonProgress?.(loaded, totalFiles);\n\t\t\t\t\treturn info;\n\t\t\t\t}),\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"]}
package/dist/index.d.ts CHANGED
@@ -2,13 +2,13 @@ export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type Age
2
2
  export { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from "./core/auth-storage.js";
3
3
  export { type BranchPreparation, type BranchSummaryResult, type CollectEntriesResult, type CompactionResult, type CutPointResult, calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, type FileOperations, findCutPoint, findTurnStartIndex, type GenerateBranchSummaryOptions, generateBranchSummary, generateSummary, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.js";
4
4
  export { createEventBus, type EventBus, type EventBusController } from "./core/event-bus.js";
5
- export type { AgentEndEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppAction, BeforeAgentStartEvent, ContextEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, KeybindingsManager, LoadExtensionsResult, MessageRenderer, MessageRenderOptions, RegisteredCommand, RegisteredTool, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionForkEvent, SessionShutdownEvent, SessionStartEvent, SessionSwitchEvent, SessionTreeEvent, ToolCallEvent, ToolDefinition, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, } from "./core/extensions/index.js";
5
+ export type { AgentEndEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppAction, BeforeAgentStartEvent, ContextEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, KeybindingsManager, LoadExtensionsResult, MessageRenderer, MessageRenderOptions, RegisteredCommand, RegisteredTool, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionForkEvent, SessionShutdownEvent, SessionStartEvent, SessionSwitchEvent, SessionTreeEvent, ToolCallEvent, ToolDefinition, ToolInfo, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, } from "./core/extensions/index.js";
6
6
  export { createExtensionRuntime, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isWriteToolResult, loadExtensions, wrapRegisteredTool, wrapRegisteredTools, wrapToolsWithExtensions, wrapToolWithExtensions, } from "./core/extensions/index.js";
7
7
  export type { ReadonlyFooterDataProvider } from "./core/footer-data-provider.js";
8
8
  export { convertToLlm } from "./core/messages.js";
9
9
  export { ModelRegistry } from "./core/model-registry.js";
10
10
  export { type BuildSystemPromptOptions, buildSystemPrompt, type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, discoverAuthStorage, discoverContextFiles, discoverExtensions, discoverModels, discoverPromptTemplates, discoverSkills, loadSettings, type PromptTemplate, readOnlyTools, } from "./core/sdk.js";
11
- export { type BranchSummaryEntry, buildSessionContext, type CompactionEntry, CURRENT_SESSION_VERSION, type CustomEntry, type CustomMessageEntry, type FileEntry, getLatestCompactionEntry, type ModelChangeEntry, migrateSessionEntries, type NewSessionOptions, parseSessionEntries, type SessionContext, type SessionEntry, type SessionEntryBase, type SessionHeader, type SessionInfo, SessionManager, type SessionMessageEntry, type ThinkingLevelChangeEntry, } from "./core/session-manager.js";
11
+ export { type BranchSummaryEntry, buildSessionContext, type CompactionEntry, CURRENT_SESSION_VERSION, type CustomEntry, type CustomMessageEntry, type FileEntry, getLatestCompactionEntry, type ModelChangeEntry, migrateSessionEntries, type NewSessionOptions, parseSessionEntries, type SessionContext, type SessionEntry, type SessionEntryBase, type SessionHeader, type SessionInfo, type SessionInfoEntry, SessionManager, type SessionMessageEntry, type ThinkingLevelChangeEntry, } from "./core/session-manager.js";
12
12
  export { type CompactionSettings, type ImageSettings, type RetrySettings, type Settings, SettingsManager, type SkillsSettings, } from "./core/settings-manager.js";
13
13
  export { formatSkillsForPrompt, type LoadSkillsFromDirOptions, type LoadSkillsResult, loadSkills, loadSkillsFromDir, type Skill, type SkillFrontmatter, type SkillWarning, } from "./core/skills.js";
14
14
  export { type BashOperations, type BashToolDetails, type BashToolOptions, bashTool, codingTools, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type EditOperations, type EditToolDetails, type EditToolOptions, editTool, type FindOperations, type FindToolDetails, type FindToolOptions, findTool, formatSize, type GrepOperations, type GrepToolDetails, type GrepToolOptions, grepTool, type LsOperations, type LsToolDetails, type LsToolOptions, lsTool, type ReadOperations, type ReadToolDetails, type ReadToolOptions, readTool, type ToolsOptions, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, type WriteOperations, type WriteToolOptions, writeTool, } from "./core/tools/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Core session management\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.js\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppAction,\n\tBeforeAgentStartEvent,\n\tContextEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionForkEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tToolCallEvent,\n\tToolDefinition,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n} from \"./core/extensions/index.js\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisWriteToolResult,\n\tloadExtensions,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n\twrapToolsWithExtensions,\n\twrapToolWithExtensions,\n} from \"./core/extensions/index.js\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\n// SDK for programmatic usage\nexport {\n\ttype BuildSystemPromptOptions,\n\tbuildSystemPrompt,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\t// Factory\n\tcreateAgentSession,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\t// Discovery\n\tdiscoverAuthStorage,\n\tdiscoverContextFiles,\n\tdiscoverExtensions,\n\tdiscoverModels,\n\tdiscoverPromptTemplates,\n\tdiscoverSkills,\n\tloadSettings,\n\ttype PromptTemplate,\n\t// Pre-built tools (use process.cwd())\n\treadOnlyTools,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype RetrySettings,\n\ttype Settings,\n\tSettingsManager,\n\ttype SkillsSettings,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n\ttype SkillWarning,\n} from \"./core/skills.js\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashToolDetails,\n\ttype BashToolOptions,\n\tbashTool,\n\tcodingTools,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolOptions,\n\teditTool,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolOptions,\n\tfindTool,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolOptions,\n\tgrepTool,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolOptions,\n\tlsTool,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolOptions,\n\treadTool,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolOptions,\n\twriteTool,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { main } from \"./main.js\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype PrintModeOptions,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.js\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.js\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.js\";\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Core session management\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.js\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppAction,\n\tBeforeAgentStartEvent,\n\tContextEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionForkEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tToolCallEvent,\n\tToolDefinition,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n} from \"./core/extensions/index.js\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisWriteToolResult,\n\tloadExtensions,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n\twrapToolsWithExtensions,\n\twrapToolWithExtensions,\n} from \"./core/extensions/index.js\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\n// SDK for programmatic usage\nexport {\n\ttype BuildSystemPromptOptions,\n\tbuildSystemPrompt,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\t// Factory\n\tcreateAgentSession,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\t// Discovery\n\tdiscoverAuthStorage,\n\tdiscoverContextFiles,\n\tdiscoverExtensions,\n\tdiscoverModels,\n\tdiscoverPromptTemplates,\n\tdiscoverSkills,\n\tloadSettings,\n\ttype PromptTemplate,\n\t// Pre-built tools (use process.cwd())\n\treadOnlyTools,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\ttype SessionInfoEntry,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype RetrySettings,\n\ttype Settings,\n\tSettingsManager,\n\ttype SkillsSettings,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n\ttype SkillWarning,\n} from \"./core/skills.js\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashToolDetails,\n\ttype BashToolOptions,\n\tbashTool,\n\tcodingTools,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolOptions,\n\teditTool,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolOptions,\n\tfindTool,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolOptions,\n\tgrepTool,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolOptions,\n\tlsTool,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolOptions,\n\treadTool,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolOptions,\n\twriteTool,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { main } from \"./main.js\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype PrintModeOptions,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.js\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.js\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.js\";\n"]}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EACN,YAAY,GAOZ,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAA8C,WAAW,EAAwB,MAAM,wBAAwB,CAAC;AACvH,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAA0C,MAAM,qBAAqB,CAAC;AAqD7F,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,6BAA6B;AAC7B,OAAO,EAEN,iBAAiB;AAGjB,UAAU;AACV,kBAAkB,EAClB,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,YAAY;AAEZ,sCAAsC;AACtC,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAMnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GAEf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,QAAQ;AACR,OAAO,EAIN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EAIjB,QAAQ,EAIR,QAAQ,EACR,UAAU,EAIV,QAAQ,EAIR,MAAM,EAIN,QAAQ,EAIR,YAAY,EACZ,YAAY,EACZ,YAAY,EAGZ,SAAS,GACT,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,uCAAuC;AACvC,OAAO,EACN,eAAe,EAGf,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC;AAC1B,+BAA+B;AAC/B,OAAO,EACN,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,6BAA6B,EAC7B,iCAAiC,EACjC,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAEtB,UAAU,EACV,wBAAwB,EAGxB,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EAEtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,GAE5B,MAAM,yCAAyC,CAAC;AACjD,kDAAkD;AAClD,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,KAAK,GAEL,MAAM,oCAAoC,CAAC","sourcesContent":["// Core session management\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.js\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppAction,\n\tBeforeAgentStartEvent,\n\tContextEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionForkEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tToolCallEvent,\n\tToolDefinition,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n} from \"./core/extensions/index.js\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisWriteToolResult,\n\tloadExtensions,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n\twrapToolsWithExtensions,\n\twrapToolWithExtensions,\n} from \"./core/extensions/index.js\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\n// SDK for programmatic usage\nexport {\n\ttype BuildSystemPromptOptions,\n\tbuildSystemPrompt,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\t// Factory\n\tcreateAgentSession,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\t// Discovery\n\tdiscoverAuthStorage,\n\tdiscoverContextFiles,\n\tdiscoverExtensions,\n\tdiscoverModels,\n\tdiscoverPromptTemplates,\n\tdiscoverSkills,\n\tloadSettings,\n\ttype PromptTemplate,\n\t// Pre-built tools (use process.cwd())\n\treadOnlyTools,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype RetrySettings,\n\ttype Settings,\n\tSettingsManager,\n\ttype SkillsSettings,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n\ttype SkillWarning,\n} from \"./core/skills.js\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashToolDetails,\n\ttype BashToolOptions,\n\tbashTool,\n\tcodingTools,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolOptions,\n\teditTool,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolOptions,\n\tfindTool,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolOptions,\n\tgrepTool,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolOptions,\n\tlsTool,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolOptions,\n\treadTool,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolOptions,\n\twriteTool,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { main } from \"./main.js\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype PrintModeOptions,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.js\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.js\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EACN,YAAY,GAOZ,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAA8C,WAAW,EAAwB,MAAM,wBAAwB,CAAC;AACvH,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAA0C,MAAM,qBAAqB,CAAC;AAsD7F,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,6BAA6B;AAC7B,OAAO,EAEN,iBAAiB;AAGjB,UAAU;AACV,kBAAkB,EAClB,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,YAAY;AAEZ,sCAAsC;AACtC,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAOnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GAEf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,QAAQ;AACR,OAAO,EAIN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EAIjB,QAAQ,EAIR,QAAQ,EACR,UAAU,EAIV,QAAQ,EAIR,MAAM,EAIN,QAAQ,EAIR,YAAY,EACZ,YAAY,EACZ,YAAY,EAGZ,SAAS,GACT,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,uCAAuC;AACvC,OAAO,EACN,eAAe,EAGf,YAAY,EACZ,UAAU,GACV,MAAM,kBAAkB,CAAC;AAC1B,+BAA+B;AAC/B,OAAO,EACN,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,6BAA6B,EAC7B,iCAAiC,EACjC,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAEtB,UAAU,EACV,wBAAwB,EAGxB,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EAEtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,GAE5B,MAAM,yCAAyC,CAAC;AACjD,kDAAkD;AAClD,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,KAAK,GAEL,MAAM,oCAAoC,CAAC","sourcesContent":["// Core session management\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./core/event-bus.js\";\n// Extension system\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppAction,\n\tBeforeAgentStartEvent,\n\tContextEvent,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionRuntime,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tRegisteredCommand,\n\tRegisteredTool,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeForkEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeTreeEvent,\n\tSessionCompactEvent,\n\tSessionForkEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tToolCallEvent,\n\tToolDefinition,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\tUserBashEvent,\n\tUserBashEventResult,\n} from \"./core/extensions/index.js\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tExtensionRunner,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisWriteToolResult,\n\tloadExtensions,\n\twrapRegisteredTool,\n\twrapRegisteredTools,\n\twrapToolsWithExtensions,\n\twrapToolWithExtensions,\n} from \"./core/extensions/index.js\";\n// Footer data provider (git branch + extension statuses - data not otherwise available to extensions)\nexport type { ReadonlyFooterDataProvider } from \"./core/footer-data-provider.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\n// SDK for programmatic usage\nexport {\n\ttype BuildSystemPromptOptions,\n\tbuildSystemPrompt,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\t// Factory\n\tcreateAgentSession,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\t// Discovery\n\tdiscoverAuthStorage,\n\tdiscoverContextFiles,\n\tdiscoverExtensions,\n\tdiscoverModels,\n\tdiscoverPromptTemplates,\n\tdiscoverSkills,\n\tloadSettings,\n\ttype PromptTemplate,\n\t// Pre-built tools (use process.cwd())\n\treadOnlyTools,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\ttype SessionInfoEntry,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype RetrySettings,\n\ttype Settings,\n\tSettingsManager,\n\ttype SkillsSettings,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n\ttype SkillWarning,\n} from \"./core/skills.js\";\n// Tools\nexport {\n\ttype BashOperations,\n\ttype BashToolDetails,\n\ttype BashToolOptions,\n\tbashTool,\n\tcodingTools,\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolOptions,\n\teditTool,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolOptions,\n\tfindTool,\n\tformatSize,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolOptions,\n\tgrepTool,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolOptions,\n\tlsTool,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolOptions,\n\treadTool,\n\ttype ToolsOptions,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n\ttype WriteOperations,\n\ttype WriteToolOptions,\n\twriteTool,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { main } from \"./main.js\";\n// Run modes for programmatic SDK usage\nexport {\n\tInteractiveMode,\n\ttype InteractiveModeOptions,\n\ttype PrintModeOptions,\n\trunPrintMode,\n\trunRpcMode,\n} from \"./modes/index.js\";\n// UI components for extensions\nexport {\n\tArminComponent,\n\tAssistantMessageComponent,\n\tBashExecutionComponent,\n\tBorderedLoader,\n\tBranchSummaryMessageComponent,\n\tCompactionSummaryMessageComponent,\n\tCustomEditor,\n\tCustomMessageComponent,\n\tDynamicBorder,\n\tExtensionEditorComponent,\n\tExtensionInputComponent,\n\tExtensionSelectorComponent,\n\tFooterComponent,\n\tLoginDialogComponent,\n\tModelSelectorComponent,\n\tOAuthSelectorComponent,\n\ttype RenderDiffOptions,\n\trenderDiff,\n\tSessionSelectorComponent,\n\ttype SettingsCallbacks,\n\ttype SettingsConfig,\n\tSettingsSelectorComponent,\n\tShowImagesSelectorComponent,\n\tThemeSelectorComponent,\n\tThinkingSelectorComponent,\n\tToolExecutionComponent,\n\ttype ToolExecutionOptions,\n\tTreeSelectorComponent,\n\ttruncateToVisualLines,\n\tUserMessageComponent,\n\tUserMessageSelectorComponent,\n\ttype VisualTruncateResult,\n} from \"./modes/interactive/components/index.js\";\n// Theme utilities for custom tools and extensions\nexport {\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\tinitTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"session-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/session-selector.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EAOT,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AA+EzF;;GAEG;AACH,cAAM,WAAY,YAAW,SAAS;IACrC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAS;IACjB,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,IAAI,CAAY;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,OAAO,CAAC,UAAU,CAAa;IAE/B,YAAY,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,EAepD;IAED,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAI3D;IAED,OAAO,CAAC,cAAc;IAStB,UAAU,IAAI,IAAI,CAAG;IAErB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwD9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkCjC;CACD;AAED,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEnF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,SAAS;IACtD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;IAElC,YACC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,EACjC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,QAAQ,EAAE,MAAM,IAAI,EACpB,MAAM,EAAE,MAAM,IAAI,EAClB,aAAa,EAAE,MAAM,IAAI,EA+BzB;IAED,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,WAAW;IAoCnB,cAAc,IAAI,WAAW,CAE5B;CACD","sourcesContent":["import * as os from \"node:os\";\nimport {\n\ttype Component,\n\tContainer,\n\tfuzzyFilter,\n\tgetEditorKeybindings,\n\tInput,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@mariozechner/pi-tui\";\nimport type { SessionInfo, SessionListProgress } from \"../../../core/session-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\n\ntype SessionScope = \"current\" | \"all\";\n\nfunction shortenPath(path: string): string {\n\tconst home = os.homedir();\n\tif (!path) return path;\n\tif (path.startsWith(home)) {\n\t\treturn `~${path.slice(home.length)}`;\n\t}\n\treturn path;\n}\n\nfunction formatSessionDate(date: Date): string {\n\tconst now = new Date();\n\tconst diffMs = now.getTime() - date.getTime();\n\tconst diffMins = Math.floor(diffMs / 60000);\n\tconst diffHours = Math.floor(diffMs / 3600000);\n\tconst diffDays = Math.floor(diffMs / 86400000);\n\n\tif (diffMins < 1) return \"just now\";\n\tif (diffMins < 60) return `${diffMins} minute${diffMins !== 1 ? \"s\" : \"\"} ago`;\n\tif (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? \"s\" : \"\"} ago`;\n\tif (diffDays === 1) return \"1 day ago\";\n\tif (diffDays < 7) return `${diffDays} days ago`;\n\n\treturn date.toLocaleDateString();\n}\n\nclass SessionSelectorHeader implements Component {\n\tprivate scope: SessionScope;\n\tprivate loading = false;\n\tprivate loadProgress: { loaded: number; total: number } | null = null;\n\n\tconstructor(scope: SessionScope) {\n\t\tthis.scope = scope;\n\t}\n\n\tsetScope(scope: SessionScope): void {\n\t\tthis.scope = scope;\n\t}\n\n\tsetLoading(loading: boolean): void {\n\t\tthis.loading = loading;\n\t\tif (!loading) {\n\t\t\tthis.loadProgress = null;\n\t\t}\n\t}\n\n\tsetProgress(loaded: number, total: number): void {\n\t\tthis.loadProgress = { loaded, total };\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = this.scope === \"current\" ? \"Resume Session (Current Folder)\" : \"Resume Session (All)\";\n\t\tconst leftText = theme.bold(title);\n\t\tlet scopeText: string;\n\t\tif (this.loading) {\n\t\t\tconst progressText = this.loadProgress ? `${this.loadProgress.loaded}/${this.loadProgress.total}` : \"...\";\n\t\t\tscopeText = `${theme.fg(\"muted\", \"○ Current Folder | \")}${theme.fg(\"accent\", `Loading ${progressText}`)}`;\n\t\t} else {\n\t\t\tscopeText =\n\t\t\t\tthis.scope === \"current\"\n\t\t\t\t\t? `${theme.fg(\"accent\", \"◉ Current Folder\")}${theme.fg(\"muted\", \" | ○ All\")}`\n\t\t\t\t\t: `${theme.fg(\"muted\", \"○ Current Folder | \")}${theme.fg(\"accent\", \"◉ All\")}`;\n\t\t}\n\t\tconst rightText = truncateToWidth(scopeText, width, \"\");\n\t\tconst availableLeft = Math.max(0, width - visibleWidth(rightText) - 1);\n\t\tconst left = truncateToWidth(leftText, availableLeft, \"\");\n\t\tconst spacing = Math.max(0, width - visibleWidth(left) - visibleWidth(rightText));\n\t\tconst hint = theme.fg(\"muted\", \"Tab to toggle scope\");\n\t\treturn [`${left}${\" \".repeat(spacing)}${rightText}`, hint];\n\t}\n}\n\n/**\n * Custom session list component with multi-line items and search\n */\nclass SessionList implements Component {\n\tprivate allSessions: SessionInfo[] = [];\n\tprivate filteredSessions: SessionInfo[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate searchInput: Input;\n\tprivate showCwd = false;\n\tpublic onSelect?: (sessionPath: string) => void;\n\tpublic onCancel?: () => void;\n\tpublic onExit: () => void = () => {};\n\tpublic onToggleScope?: () => void;\n\tprivate maxVisible: number = 5; // Max sessions visible (each session is 3 lines: msg + metadata + blank)\n\n\tconstructor(sessions: SessionInfo[], showCwd: boolean) {\n\t\tthis.allSessions = sessions;\n\t\tthis.filteredSessions = sessions;\n\t\tthis.searchInput = new Input();\n\t\tthis.showCwd = showCwd;\n\n\t\t// Handle Enter in search input - select current item\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\tif (this.filteredSessions[this.selectedIndex]) {\n\t\t\t\tconst selected = this.filteredSessions[this.selectedIndex];\n\t\t\t\tif (this.onSelect) {\n\t\t\t\t\tthis.onSelect(selected.path);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tsetSessions(sessions: SessionInfo[], showCwd: boolean): void {\n\t\tthis.allSessions = sessions;\n\t\tthis.showCwd = showCwd;\n\t\tthis.filterSessions(this.searchInput.getValue());\n\t}\n\n\tprivate filterSessions(query: string): void {\n\t\tthis.filteredSessions = fuzzyFilter(\n\t\t\tthis.allSessions,\n\t\t\tquery,\n\t\t\t(session) => `${session.id} ${session.allMessagesText} ${session.cwd}`,\n\t\t);\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredSessions.length - 1));\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Render search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\"); // Blank line after search\n\n\t\tif (this.filteredSessions.length === 0) {\n\t\t\tlines.push(theme.fg(\"muted\", \" No sessions found\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range with scrolling\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredSessions.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredSessions.length);\n\n\t\t// Render visible sessions (2 lines per session + blank line)\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst session = this.filteredSessions[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\t// Normalize first message to single line\n\t\t\tconst normalizedMessage = session.firstMessage.replace(/\\n/g, \" \").trim();\n\n\t\t\t// First line: cursor + message (truncate to visible width)\n\t\t\tconst cursor = isSelected ? theme.fg(\"accent\", \"› \") : \" \";\n\t\t\tconst maxMsgWidth = width - 2; // Account for cursor (2 visible chars)\n\t\t\tconst truncatedMsg = truncateToWidth(normalizedMessage, maxMsgWidth, \"...\");\n\t\t\tconst messageLine = cursor + (isSelected ? theme.bold(truncatedMsg) : truncatedMsg);\n\n\t\t\t// Second line: metadata (dimmed) - also truncate for safety\n\t\t\tconst modified = formatSessionDate(session.modified);\n\t\t\tconst msgCount = `${session.messageCount} message${session.messageCount !== 1 ? \"s\" : \"\"}`;\n\t\t\tconst metadataParts = [modified, msgCount];\n\t\t\tif (this.showCwd && session.cwd) {\n\t\t\t\tmetadataParts.push(shortenPath(session.cwd));\n\t\t\t}\n\t\t\tconst metadata = ` ${metadataParts.join(\" · \")}`;\n\t\t\tconst metadataLine = theme.fg(\"dim\", truncateToWidth(metadata, width, \"\"));\n\n\t\t\tlines.push(messageLine);\n\t\t\tlines.push(metadataLine);\n\t\t\tlines.push(\"\"); // Blank line between sessions\n\t\t}\n\n\t\t// Add scroll indicator if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredSessions.length) {\n\t\t\tconst scrollText = ` (${this.selectedIndex + 1}/${this.filteredSessions.length})`;\n\t\t\tconst scrollInfo = theme.fg(\"muted\", truncateToWidth(scrollText, width, \"\"));\n\t\t\tlines.push(scrollInfo);\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"tab\")) {\n\t\t\tif (this.onToggleScope) {\n\t\t\t\tthis.onToggleScope();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Up arrow\n\t\tif (kb.matches(keyData, \"selectUp\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t}\n\t\t// Down arrow\n\t\telse if (kb.matches(keyData, \"selectDown\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filteredSessions.length - 1, this.selectedIndex + 1);\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"selectConfirm\")) {\n\t\t\tconst selected = this.filteredSessions[this.selectedIndex];\n\t\t\tif (selected && this.onSelect) {\n\t\t\t\tthis.onSelect(selected.path);\n\t\t\t}\n\t\t}\n\t\t// Escape - cancel\n\t\telse if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tif (this.onCancel) {\n\t\t\t\tthis.onCancel();\n\t\t\t}\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterSessions(this.searchInput.getValue());\n\t\t}\n\t}\n}\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/**\n * Component that renders a session selector\n */\nexport class SessionSelectorComponent extends Container {\n\tprivate sessionList: SessionList;\n\tprivate header: SessionSelectorHeader;\n\tprivate scope: SessionScope = \"current\";\n\tprivate currentSessions: SessionInfo[] | null = null;\n\tprivate allSessions: SessionInfo[] | null = null;\n\tprivate currentSessionsLoader: SessionsLoader;\n\tprivate allSessionsLoader: SessionsLoader;\n\tprivate onCancel: () => void;\n\tprivate requestRender: () => void;\n\n\tconstructor(\n\t\tcurrentSessionsLoader: SessionsLoader,\n\t\tallSessionsLoader: SessionsLoader,\n\t\tonSelect: (sessionPath: string) => void,\n\t\tonCancel: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\t\tthis.currentSessionsLoader = currentSessionsLoader;\n\t\tthis.allSessionsLoader = allSessionsLoader;\n\t\tthis.onCancel = onCancel;\n\t\tthis.requestRender = requestRender;\n\t\tthis.header = new SessionSelectorHeader(this.scope);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(this.header);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create session list (starts empty, will be populated after load)\n\t\tthis.sessionList = new SessionList([], false);\n\t\tthis.sessionList.onSelect = onSelect;\n\t\tthis.sessionList.onCancel = onCancel;\n\t\tthis.sessionList.onExit = onExit;\n\t\tthis.sessionList.onToggleScope = () => this.toggleScope();\n\n\t\tthis.addChild(this.sessionList);\n\n\t\t// Add bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Start loading current sessions immediately\n\t\tthis.loadCurrentSessions();\n\t}\n\n\tprivate loadCurrentSessions(): void {\n\t\tthis.header.setLoading(true);\n\t\tthis.requestRender();\n\t\tthis.currentSessionsLoader((loaded, total) => {\n\t\t\tthis.header.setProgress(loaded, total);\n\t\t\tthis.requestRender();\n\t\t}).then((sessions) => {\n\t\t\tthis.currentSessions = sessions;\n\t\t\tthis.header.setLoading(false);\n\t\t\tthis.sessionList.setSessions(sessions, false);\n\t\t\tthis.requestRender();\n\t\t\t// If no sessions found, cancel\n\t\t\tif (sessions.length === 0) {\n\t\t\t\tthis.onCancel();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate toggleScope(): void {\n\t\tif (this.scope === \"current\") {\n\t\t\t// Switching to \"all\" - load if not already loaded\n\t\t\tif (this.allSessions === null) {\n\t\t\t\tthis.header.setLoading(true);\n\t\t\t\tthis.header.setScope(\"all\");\n\t\t\t\tthis.sessionList.setSessions([], true); // Clear list while loading\n\t\t\t\tthis.requestRender();\n\t\t\t\t// Load asynchronously with progress updates\n\t\t\t\tthis.allSessionsLoader((loaded, total) => {\n\t\t\t\t\tthis.header.setProgress(loaded, total);\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t}).then((sessions) => {\n\t\t\t\t\tthis.allSessions = sessions;\n\t\t\t\t\tthis.header.setLoading(false);\n\t\t\t\t\tthis.scope = \"all\";\n\t\t\t\t\tthis.sessionList.setSessions(this.allSessions, true);\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t\t// If no sessions in All scope either, cancel\n\t\t\t\t\tif (this.allSessions.length === 0 && (this.currentSessions?.length ?? 0) === 0) {\n\t\t\t\t\t\tthis.onCancel();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.scope = \"all\";\n\t\t\t\tthis.sessionList.setSessions(this.allSessions, true);\n\t\t\t\tthis.header.setScope(this.scope);\n\t\t\t}\n\t\t} else {\n\t\t\t// Switching back to \"current\"\n\t\t\tthis.scope = \"current\";\n\t\t\tthis.sessionList.setSessions(this.currentSessions ?? [], false);\n\t\t\tthis.header.setScope(this.scope);\n\t\t}\n\t}\n\n\tgetSessionList(): SessionList {\n\t\treturn this.sessionList;\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/session-selector.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EAOT,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AA+EzF;;GAEG;AACH,cAAM,WAAY,YAAW,SAAS;IACrC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAS;IACjB,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,IAAI,CAAY;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,OAAO,CAAC,UAAU,CAAa;IAE/B,YAAY,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,EAepD;IAED,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAI3D;IAED,OAAO,CAAC,cAAc;IAStB,UAAU,IAAI,IAAI,CAAG;IAErB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwE9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA0CjC;CACD;AAED,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEnF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,SAAS;IACtD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;IAElC,YACC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,EACjC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,EACvC,QAAQ,EAAE,MAAM,IAAI,EACpB,MAAM,EAAE,MAAM,IAAI,EAClB,aAAa,EAAE,MAAM,IAAI,EA+BzB;IAED,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,WAAW;IAoCnB,cAAc,IAAI,WAAW,CAE5B;CACD","sourcesContent":["import * as os from \"node:os\";\nimport {\n\ttype Component,\n\tContainer,\n\tfuzzyFilter,\n\tgetEditorKeybindings,\n\tInput,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@mariozechner/pi-tui\";\nimport type { SessionInfo, SessionListProgress } from \"../../../core/session-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\n\ntype SessionScope = \"current\" | \"all\";\n\nfunction shortenPath(path: string): string {\n\tconst home = os.homedir();\n\tif (!path) return path;\n\tif (path.startsWith(home)) {\n\t\treturn `~${path.slice(home.length)}`;\n\t}\n\treturn path;\n}\n\nfunction formatSessionDate(date: Date): string {\n\tconst now = new Date();\n\tconst diffMs = now.getTime() - date.getTime();\n\tconst diffMins = Math.floor(diffMs / 60000);\n\tconst diffHours = Math.floor(diffMs / 3600000);\n\tconst diffDays = Math.floor(diffMs / 86400000);\n\n\tif (diffMins < 1) return \"just now\";\n\tif (diffMins < 60) return `${diffMins} minute${diffMins !== 1 ? \"s\" : \"\"} ago`;\n\tif (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? \"s\" : \"\"} ago`;\n\tif (diffDays === 1) return \"1 day ago\";\n\tif (diffDays < 7) return `${diffDays} days ago`;\n\n\treturn date.toLocaleDateString();\n}\n\nclass SessionSelectorHeader implements Component {\n\tprivate scope: SessionScope;\n\tprivate loading = false;\n\tprivate loadProgress: { loaded: number; total: number } | null = null;\n\n\tconstructor(scope: SessionScope) {\n\t\tthis.scope = scope;\n\t}\n\n\tsetScope(scope: SessionScope): void {\n\t\tthis.scope = scope;\n\t}\n\n\tsetLoading(loading: boolean): void {\n\t\tthis.loading = loading;\n\t\tif (!loading) {\n\t\t\tthis.loadProgress = null;\n\t\t}\n\t}\n\n\tsetProgress(loaded: number, total: number): void {\n\t\tthis.loadProgress = { loaded, total };\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = this.scope === \"current\" ? \"Resume Session (Current Folder)\" : \"Resume Session (All)\";\n\t\tconst leftText = theme.bold(title);\n\t\tlet scopeText: string;\n\t\tif (this.loading) {\n\t\t\tconst progressText = this.loadProgress ? `${this.loadProgress.loaded}/${this.loadProgress.total}` : \"...\";\n\t\t\tscopeText = `${theme.fg(\"muted\", \"○ Current Folder | \")}${theme.fg(\"accent\", `Loading ${progressText}`)}`;\n\t\t} else {\n\t\t\tscopeText =\n\t\t\t\tthis.scope === \"current\"\n\t\t\t\t\t? `${theme.fg(\"accent\", \"◉ Current Folder\")}${theme.fg(\"muted\", \" | ○ All\")}`\n\t\t\t\t\t: `${theme.fg(\"muted\", \"○ Current Folder | \")}${theme.fg(\"accent\", \"◉ All\")}`;\n\t\t}\n\t\tconst rightText = truncateToWidth(scopeText, width, \"\");\n\t\tconst availableLeft = Math.max(0, width - visibleWidth(rightText) - 1);\n\t\tconst left = truncateToWidth(leftText, availableLeft, \"\");\n\t\tconst spacing = Math.max(0, width - visibleWidth(left) - visibleWidth(rightText));\n\t\tconst hint = theme.fg(\"muted\", \"Tab to toggle scope\");\n\t\treturn [`${left}${\" \".repeat(spacing)}${rightText}`, hint];\n\t}\n}\n\n/**\n * Custom session list component with multi-line items and search\n */\nclass SessionList implements Component {\n\tprivate allSessions: SessionInfo[] = [];\n\tprivate filteredSessions: SessionInfo[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate searchInput: Input;\n\tprivate showCwd = false;\n\tpublic onSelect?: (sessionPath: string) => void;\n\tpublic onCancel?: () => void;\n\tpublic onExit: () => void = () => {};\n\tpublic onToggleScope?: () => void;\n\tprivate maxVisible: number = 5; // Max sessions visible (each session is 3 lines: msg + metadata + blank)\n\n\tconstructor(sessions: SessionInfo[], showCwd: boolean) {\n\t\tthis.allSessions = sessions;\n\t\tthis.filteredSessions = sessions;\n\t\tthis.searchInput = new Input();\n\t\tthis.showCwd = showCwd;\n\n\t\t// Handle Enter in search input - select current item\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\tif (this.filteredSessions[this.selectedIndex]) {\n\t\t\t\tconst selected = this.filteredSessions[this.selectedIndex];\n\t\t\t\tif (this.onSelect) {\n\t\t\t\t\tthis.onSelect(selected.path);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tsetSessions(sessions: SessionInfo[], showCwd: boolean): void {\n\t\tthis.allSessions = sessions;\n\t\tthis.showCwd = showCwd;\n\t\tthis.filterSessions(this.searchInput.getValue());\n\t}\n\n\tprivate filterSessions(query: string): void {\n\t\tthis.filteredSessions = fuzzyFilter(\n\t\t\tthis.allSessions,\n\t\t\tquery,\n\t\t\t(session) => `${session.id} ${session.name ?? \"\"} ${session.allMessagesText} ${session.cwd}`,\n\t\t);\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredSessions.length - 1));\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Render search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\"); // Blank line after search\n\n\t\tif (this.filteredSessions.length === 0) {\n\t\t\tif (this.showCwd) {\n\t\t\t\t// \"All\" scope - no sessions anywhere that match filter\n\t\t\t\tlines.push(theme.fg(\"muted\", \" No sessions found\"));\n\t\t\t} else {\n\t\t\t\t// \"Current folder\" scope - hint to try \"all\"\n\t\t\t\tlines.push(theme.fg(\"muted\", \" No sessions in current folder. Press Tab to view all.\"));\n\t\t\t}\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range with scrolling\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredSessions.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredSessions.length);\n\n\t\t// Render visible sessions (2 lines per session + blank line)\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst session = this.filteredSessions[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\t// Use session name if set, otherwise first message\n\t\t\tconst hasName = !!session.name;\n\t\t\tconst displayText = session.name ?? session.firstMessage;\n\t\t\tconst normalizedMessage = displayText.replace(/\\n/g, \" \").trim();\n\n\t\t\t// First line: cursor + message (truncate to visible width)\n\t\t\t// Use warning color for custom names to distinguish from first message\n\t\t\tconst cursor = isSelected ? theme.fg(\"accent\", \"› \") : \" \";\n\t\t\tconst maxMsgWidth = width - 2; // Account for cursor (2 visible chars)\n\t\t\tconst truncatedMsg = truncateToWidth(normalizedMessage, maxMsgWidth, \"...\");\n\t\t\tlet styledMsg = truncatedMsg;\n\t\t\tif (hasName) {\n\t\t\t\tstyledMsg = theme.fg(\"warning\", truncatedMsg);\n\t\t\t}\n\t\t\tif (isSelected) {\n\t\t\t\tstyledMsg = theme.bold(styledMsg);\n\t\t\t}\n\t\t\tconst messageLine = cursor + styledMsg;\n\n\t\t\t// Second line: metadata (dimmed) - also truncate for safety\n\t\t\tconst modified = formatSessionDate(session.modified);\n\t\t\tconst msgCount = `${session.messageCount} message${session.messageCount !== 1 ? \"s\" : \"\"}`;\n\t\t\tconst metadataParts = [modified, msgCount];\n\t\t\tif (this.showCwd && session.cwd) {\n\t\t\t\tmetadataParts.push(shortenPath(session.cwd));\n\t\t\t}\n\t\t\tconst metadata = ` ${metadataParts.join(\" · \")}`;\n\t\t\tconst metadataLine = theme.fg(\"dim\", truncateToWidth(metadata, width, \"\"));\n\n\t\t\tlines.push(messageLine);\n\t\t\tlines.push(metadataLine);\n\t\t\tlines.push(\"\"); // Blank line between sessions\n\t\t}\n\n\t\t// Add scroll indicator if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredSessions.length) {\n\t\t\tconst scrollText = ` (${this.selectedIndex + 1}/${this.filteredSessions.length})`;\n\t\t\tconst scrollInfo = theme.fg(\"muted\", truncateToWidth(scrollText, width, \"\"));\n\t\t\tlines.push(scrollInfo);\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"tab\")) {\n\t\t\tif (this.onToggleScope) {\n\t\t\t\tthis.onToggleScope();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Up arrow\n\t\tif (kb.matches(keyData, \"selectUp\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t}\n\t\t// Down arrow\n\t\telse if (kb.matches(keyData, \"selectDown\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filteredSessions.length - 1, this.selectedIndex + 1);\n\t\t}\n\t\t// Page up - jump up by maxVisible items\n\t\telse if (kb.matches(keyData, \"selectPageUp\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - this.maxVisible);\n\t\t}\n\t\t// Page down - jump down by maxVisible items\n\t\telse if (kb.matches(keyData, \"selectPageDown\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filteredSessions.length - 1, this.selectedIndex + this.maxVisible);\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"selectConfirm\")) {\n\t\t\tconst selected = this.filteredSessions[this.selectedIndex];\n\t\t\tif (selected && this.onSelect) {\n\t\t\t\tthis.onSelect(selected.path);\n\t\t\t}\n\t\t}\n\t\t// Escape - cancel\n\t\telse if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tif (this.onCancel) {\n\t\t\t\tthis.onCancel();\n\t\t\t}\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterSessions(this.searchInput.getValue());\n\t\t}\n\t}\n}\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/**\n * Component that renders a session selector\n */\nexport class SessionSelectorComponent extends Container {\n\tprivate sessionList: SessionList;\n\tprivate header: SessionSelectorHeader;\n\tprivate scope: SessionScope = \"current\";\n\tprivate currentSessions: SessionInfo[] | null = null;\n\tprivate allSessions: SessionInfo[] | null = null;\n\tprivate currentSessionsLoader: SessionsLoader;\n\tprivate allSessionsLoader: SessionsLoader;\n\tprivate onCancel: () => void;\n\tprivate requestRender: () => void;\n\n\tconstructor(\n\t\tcurrentSessionsLoader: SessionsLoader,\n\t\tallSessionsLoader: SessionsLoader,\n\t\tonSelect: (sessionPath: string) => void,\n\t\tonCancel: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\t\tthis.currentSessionsLoader = currentSessionsLoader;\n\t\tthis.allSessionsLoader = allSessionsLoader;\n\t\tthis.onCancel = onCancel;\n\t\tthis.requestRender = requestRender;\n\t\tthis.header = new SessionSelectorHeader(this.scope);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(this.header);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create session list (starts empty, will be populated after load)\n\t\tthis.sessionList = new SessionList([], false);\n\t\tthis.sessionList.onSelect = onSelect;\n\t\tthis.sessionList.onCancel = onCancel;\n\t\tthis.sessionList.onExit = onExit;\n\t\tthis.sessionList.onToggleScope = () => this.toggleScope();\n\n\t\tthis.addChild(this.sessionList);\n\n\t\t// Add bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Start loading current sessions immediately\n\t\tthis.loadCurrentSessions();\n\t}\n\n\tprivate loadCurrentSessions(): void {\n\t\tthis.header.setLoading(true);\n\t\tthis.requestRender();\n\t\tthis.currentSessionsLoader((loaded, total) => {\n\t\t\tthis.header.setProgress(loaded, total);\n\t\t\tthis.requestRender();\n\t\t}).then((sessions) => {\n\t\t\tthis.currentSessions = sessions;\n\t\t\tthis.header.setLoading(false);\n\t\t\tthis.sessionList.setSessions(sessions, false);\n\t\t\tthis.requestRender();\n\t\t});\n\t}\n\n\tprivate toggleScope(): void {\n\t\tif (this.scope === \"current\") {\n\t\t\t// Switching to \"all\" - load if not already loaded\n\t\t\tif (this.allSessions === null) {\n\t\t\t\tthis.header.setLoading(true);\n\t\t\t\tthis.header.setScope(\"all\");\n\t\t\t\tthis.sessionList.setSessions([], true); // Clear list while loading\n\t\t\t\tthis.requestRender();\n\t\t\t\t// Load asynchronously with progress updates\n\t\t\t\tthis.allSessionsLoader((loaded, total) => {\n\t\t\t\t\tthis.header.setProgress(loaded, total);\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t}).then((sessions) => {\n\t\t\t\t\tthis.allSessions = sessions;\n\t\t\t\t\tthis.header.setLoading(false);\n\t\t\t\t\tthis.scope = \"all\";\n\t\t\t\t\tthis.sessionList.setSessions(this.allSessions, true);\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t\t// If no sessions in All scope either, cancel\n\t\t\t\t\tif (this.allSessions.length === 0 && (this.currentSessions?.length ?? 0) === 0) {\n\t\t\t\t\t\tthis.onCancel();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.scope = \"all\";\n\t\t\t\tthis.sessionList.setSessions(this.allSessions, true);\n\t\t\t\tthis.header.setScope(this.scope);\n\t\t\t}\n\t\t} else {\n\t\t\t// Switching back to \"current\"\n\t\t\tthis.scope = \"current\";\n\t\t\tthis.sessionList.setSessions(this.currentSessions ?? [], false);\n\t\t\tthis.header.setScope(this.scope);\n\t\t}\n\t}\n\n\tgetSessionList(): SessionList {\n\t\treturn this.sessionList;\n\t}\n}\n"]}