@maxmo74/pi-coding-agent 0.0.0-stage → 1.4.0-max.1

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 (1293) hide show
  1. package/CHANGELOG.md +6397 -0
  2. package/LICENSE +21 -0
  3. package/README.md +116 -2
  4. package/dist/bun/cli.d.ts +5 -0
  5. package/dist/bun/cli.d.ts.map +1 -0
  6. package/dist/bun/cli.js +5 -0
  7. package/dist/bun/cli.js.map +1 -0
  8. package/dist/bun/restore-sandbox-env.d.ts +17 -0
  9. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  10. package/dist/bun/restore-sandbox-env.js +36 -0
  11. package/dist/bun/restore-sandbox-env.js.map +1 -0
  12. package/dist/bun/runtime-setup.d.ts +2 -0
  13. package/dist/bun/runtime-setup.d.ts.map +1 -0
  14. package/dist/bun/runtime-setup.js +12 -0
  15. package/dist/bun/runtime-setup.js.map +1 -0
  16. package/dist/bun/sandbox-env-setup.d.ts +2 -0
  17. package/dist/bun/sandbox-env-setup.d.ts.map +1 -0
  18. package/dist/bun/sandbox-env-setup.js +4 -0
  19. package/dist/bun/sandbox-env-setup.js.map +1 -0
  20. package/dist/bundle/chunks/anthropic-messages-KRX3GRGV.js +6 -0
  21. package/dist/bundle/chunks/anthropic.js +75 -0
  22. package/dist/bundle/chunks/azure-openai-responses-YWTDZRIJ.js +2 -0
  23. package/dist/bundle/chunks/bedrock-converse-stream.js +89 -0
  24. package/dist/bundle/chunks/chunk-4UNN5OGR.js +4 -0
  25. package/dist/bundle/chunks/chunk-5AGIVGSV.js +6 -0
  26. package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
  27. package/dist/bundle/chunks/chunk-7CBJINYJ.js +20 -0
  28. package/dist/bundle/chunks/chunk-7DDKXS2Q.js +2 -0
  29. package/dist/bundle/chunks/chunk-7ZC4UXSL.js +2 -0
  30. package/dist/bundle/chunks/chunk-AFNTYPTW.js +65 -0
  31. package/dist/bundle/chunks/chunk-BPHHHEET.js +9 -0
  32. package/dist/bundle/chunks/chunk-BSS6T6KQ.js +2 -0
  33. package/dist/bundle/chunks/chunk-CF5GWZHW.js +31 -0
  34. package/dist/bundle/chunks/chunk-CPKYLLPC.js +2 -0
  35. package/dist/bundle/chunks/chunk-FFMDRXC4.js +10 -0
  36. package/dist/bundle/chunks/chunk-G2WC5ETL.js +2 -0
  37. package/dist/bundle/chunks/chunk-HODJBMOY.js +9 -0
  38. package/dist/bundle/chunks/chunk-HQBQWHLD.js +7 -0
  39. package/dist/bundle/chunks/chunk-HQJBN2MC.js +2 -0
  40. package/dist/bundle/chunks/chunk-JXWJOIH4.js +2 -0
  41. package/dist/bundle/chunks/chunk-KFM2CJ7Q.js +4 -0
  42. package/dist/bundle/chunks/chunk-L2ZPNLYD.js +2 -0
  43. package/dist/bundle/chunks/chunk-LAMEVJ4W.js +132 -0
  44. package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
  45. package/dist/bundle/chunks/chunk-LVVZS2NO.js +12 -0
  46. package/dist/bundle/chunks/chunk-M3LEVT3X.js +2 -0
  47. package/dist/bundle/chunks/chunk-P7FPUEYA.js +2 -0
  48. package/dist/bundle/chunks/chunk-PGXDEOVV.js +2 -0
  49. package/dist/bundle/chunks/chunk-PJACZCIR.js +2 -0
  50. package/dist/bundle/chunks/chunk-PMRZO46Y.js +2 -0
  51. package/dist/bundle/chunks/chunk-PRRNXB7S.js +2 -0
  52. package/dist/bundle/chunks/chunk-QTM7S6TH.js +2 -0
  53. package/dist/bundle/chunks/chunk-QVAQV2RJ.js +1237 -0
  54. package/dist/bundle/chunks/chunk-RDZVAGPR.js +2 -0
  55. package/dist/bundle/chunks/chunk-RFUP4YGP.js +82 -0
  56. package/dist/bundle/chunks/chunk-TMTOQ7H7.js +2 -0
  57. package/dist/bundle/chunks/chunk-UKVNB6C4.js +2 -0
  58. package/dist/bundle/chunks/chunk-USJZMAIR.js +2 -0
  59. package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
  60. package/dist/bundle/chunks/chunk-V4LJ5IY6.js +44 -0
  61. package/dist/bundle/chunks/chunk-XPUTTZLN.js +16 -0
  62. package/dist/bundle/chunks/chunk-ZN2R65UF.js +2 -0
  63. package/dist/bundle/chunks/cli-QUXYJ5RR.js +51 -0
  64. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-QPZQRBK5.js +2 -0
  65. package/dist/bundle/chunks/codemode-worker.js +478 -0
  66. package/dist/bundle/chunks/easter-egg-3d-RD5RBYI2.js +2 -0
  67. package/dist/bundle/chunks/execute-XTJDRV75.js +505 -0
  68. package/dist/bundle/chunks/github-copilot.js +2 -0
  69. package/dist/bundle/chunks/google-generative-ai-J3K3YPN3.js +2 -0
  70. package/dist/bundle/chunks/google-vertex-VFXOTBVP.js +2 -0
  71. package/dist/bundle/chunks/https-proxy-agent-LVOO5TPL.js +13 -0
  72. package/dist/bundle/chunks/image-resize-worker.js +2 -0
  73. package/dist/bundle/chunks/jiti-loader-GL4HJFAD.js +21 -0
  74. package/dist/bundle/chunks/jiti-static-loader-2RCDI6B4.js +2 -0
  75. package/dist/bundle/chunks/kimi-coding.js +2 -0
  76. package/dist/bundle/chunks/lib-4AVRLBHM.js +9 -0
  77. package/dist/bundle/chunks/llama-cpp-classify-4KFSGAMH.js +22 -0
  78. package/dist/bundle/chunks/meta.js +2 -0
  79. package/dist/bundle/chunks/mistral-conversations-C2QQGYVC.js +5 -0
  80. package/dist/bundle/chunks/multipart-parser-FMGQ7342.js +3 -0
  81. package/dist/bundle/chunks/node-AUOGOBCN.js +2 -0
  82. package/dist/bundle/chunks/node-KCMANYC2.js +16 -0
  83. package/dist/bundle/chunks/openai-chatgpt.js +75 -0
  84. package/dist/bundle/chunks/openai-codex-responses-H2UJSVV3.js +10 -0
  85. package/dist/bundle/chunks/openai-codex.js +75 -0
  86. package/dist/bundle/chunks/openai-completions-QPD4B26I.js +7 -0
  87. package/dist/bundle/chunks/openai-decisions-O6PHBSCB.js +5 -0
  88. package/dist/bundle/chunks/openai-responses-JOYMWKMB.js +4 -0
  89. package/dist/bundle/chunks/openrouter-images-4WG6OOLH.js +2 -0
  90. package/dist/bundle/chunks/openrouter.js +75 -0
  91. package/dist/bundle/chunks/pi-messages-EZXKVRR6.js +8 -0
  92. package/dist/bundle/chunks/radius.js +75 -0
  93. package/dist/bundle/chunks/runtime-YKR6KZPS.js +2 -0
  94. package/dist/bundle/chunks/src-QKGKDFSU.js +4 -0
  95. package/dist/bundle/chunks/typesafe-system-one-X3JT6ECA.js +2 -0
  96. package/dist/bundle/chunks/virtual-modules-KVDFV7IC.js +2 -0
  97. package/dist/bundle/chunks/xai.js +2 -0
  98. package/dist/bundle/cli-runtime.js +3 -0
  99. package/dist/bundle/cli.js +5 -0
  100. package/dist/bundle/index.js +2 -0
  101. package/dist/bundle/rpc-entry.js +3 -0
  102. package/dist/cli/args.d.ts +62 -0
  103. package/dist/cli/args.d.ts.map +1 -0
  104. package/dist/cli/args.js +473 -0
  105. package/dist/cli/args.js.map +1 -0
  106. package/dist/cli/auth-check.d.ts +19 -0
  107. package/dist/cli/auth-check.d.ts.map +1 -0
  108. package/dist/cli/auth-check.js +50 -0
  109. package/dist/cli/auth-check.js.map +1 -0
  110. package/dist/cli/auth-command.d.ts +24 -0
  111. package/dist/cli/auth-command.d.ts.map +1 -0
  112. package/dist/cli/auth-command.js +103 -0
  113. package/dist/cli/auth-command.js.map +1 -0
  114. package/dist/cli/config-selector.d.ts +16 -0
  115. package/dist/cli/config-selector.d.ts.map +1 -0
  116. package/dist/cli/config-selector.js +32 -0
  117. package/dist/cli/config-selector.js.map +1 -0
  118. package/dist/cli/credential-print.d.ts +13 -0
  119. package/dist/cli/credential-print.d.ts.map +1 -0
  120. package/dist/cli/credential-print.js +76 -0
  121. package/dist/cli/credential-print.js.map +1 -0
  122. package/dist/cli/file-processor.d.ts +15 -0
  123. package/dist/cli/file-processor.d.ts.map +1 -0
  124. package/dist/cli/file-processor.js +71 -0
  125. package/dist/cli/file-processor.js.map +1 -0
  126. package/dist/cli/initial-message.d.ts +18 -0
  127. package/dist/cli/initial-message.d.ts.map +1 -0
  128. package/dist/cli/initial-message.js +22 -0
  129. package/dist/cli/initial-message.js.map +1 -0
  130. package/dist/cli/list-models.d.ts +9 -0
  131. package/dist/cli/list-models.d.ts.map +1 -0
  132. package/dist/cli/list-models.js +98 -0
  133. package/dist/cli/list-models.js.map +1 -0
  134. package/dist/cli/project-trust.d.ts +10 -0
  135. package/dist/cli/project-trust.d.ts.map +1 -0
  136. package/dist/cli/project-trust.js +48 -0
  137. package/dist/cli/project-trust.js.map +1 -0
  138. package/dist/cli/session-picker.d.ts +10 -0
  139. package/dist/cli/session-picker.d.ts.map +1 -0
  140. package/dist/cli/session-picker.js +36 -0
  141. package/dist/cli/session-picker.js.map +1 -0
  142. package/dist/cli/setup.d.ts +2 -0
  143. package/dist/cli/setup.d.ts.map +1 -0
  144. package/dist/cli/setup.js +12 -0
  145. package/dist/cli/setup.js.map +1 -0
  146. package/dist/cli/startup-ui.d.ts +20 -0
  147. package/dist/cli/startup-ui.d.ts.map +1 -0
  148. package/dist/cli/startup-ui.js +193 -0
  149. package/dist/cli/startup-ui.js.map +1 -0
  150. package/dist/cli.d.ts +3 -0
  151. package/dist/cli.d.ts.map +1 -0
  152. package/dist/cli.js +6 -0
  153. package/dist/cli.js.map +1 -0
  154. package/dist/config.d.ts +126 -0
  155. package/dist/config.d.ts.map +1 -0
  156. package/dist/config.js +534 -0
  157. package/dist/config.js.map +1 -0
  158. package/dist/core/agent-session-runtime.d.ts +120 -0
  159. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  160. package/dist/core/agent-session-runtime.js +307 -0
  161. package/dist/core/agent-session-runtime.js.map +1 -0
  162. package/dist/core/agent-session-services.d.ts +86 -0
  163. package/dist/core/agent-session-services.d.ts.map +1 -0
  164. package/dist/core/agent-session-services.js +147 -0
  165. package/dist/core/agent-session-services.js.map +1 -0
  166. package/dist/core/agent-session.d.ts +940 -0
  167. package/dist/core/agent-session.d.ts.map +1 -0
  168. package/dist/core/agent-session.js +3654 -0
  169. package/dist/core/agent-session.js.map +1 -0
  170. package/dist/core/auth-guidance.d.ts +5 -0
  171. package/dist/core/auth-guidance.d.ts.map +1 -0
  172. package/dist/core/auth-guidance.js +21 -0
  173. package/dist/core/auth-guidance.js.map +1 -0
  174. package/dist/core/auth-storage.d.ts +72 -0
  175. package/dist/core/auth-storage.d.ts.map +1 -0
  176. package/dist/core/auth-storage.js +433 -0
  177. package/dist/core/auth-storage.js.map +1 -0
  178. package/dist/core/bash-executor.d.ts +32 -0
  179. package/dist/core/bash-executor.d.ts.map +1 -0
  180. package/dist/core/bash-executor.js +101 -0
  181. package/dist/core/bash-executor.js.map +1 -0
  182. package/dist/core/bug-report-upload.d.ts +12 -0
  183. package/dist/core/bug-report-upload.d.ts.map +1 -0
  184. package/dist/core/bug-report-upload.js +22 -0
  185. package/dist/core/bug-report-upload.js.map +1 -0
  186. package/dist/core/bug-report.d.ts +184 -0
  187. package/dist/core/bug-report.d.ts.map +1 -0
  188. package/dist/core/bug-report.js +292 -0
  189. package/dist/core/bug-report.js.map +1 -0
  190. package/dist/core/cache-stats.d.ts +49 -0
  191. package/dist/core/cache-stats.d.ts.map +1 -0
  192. package/dist/core/cache-stats.js +112 -0
  193. package/dist/core/cache-stats.js.map +1 -0
  194. package/dist/core/cache-warmer.d.ts +103 -0
  195. package/dist/core/cache-warmer.d.ts.map +1 -0
  196. package/dist/core/cache-warmer.js +356 -0
  197. package/dist/core/cache-warmer.js.map +1 -0
  198. package/dist/core/client-identity.d.ts +8 -0
  199. package/dist/core/client-identity.d.ts.map +1 -0
  200. package/dist/core/client-identity.js +15 -0
  201. package/dist/core/client-identity.js.map +1 -0
  202. package/dist/core/compaction/branch-summarization.d.ts +100 -0
  203. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  204. package/dist/core/compaction/branch-summarization.js +253 -0
  205. package/dist/core/compaction/branch-summarization.js.map +1 -0
  206. package/dist/core/compaction/compaction.d.ts +145 -0
  207. package/dist/core/compaction/compaction.d.ts.map +1 -0
  208. package/dist/core/compaction/compaction.js +749 -0
  209. package/dist/core/compaction/compaction.js.map +1 -0
  210. package/dist/core/compaction/index.d.ts +7 -0
  211. package/dist/core/compaction/index.d.ts.map +1 -0
  212. package/dist/core/compaction/index.js +7 -0
  213. package/dist/core/compaction/index.js.map +1 -0
  214. package/dist/core/compaction/utils.d.ts +45 -0
  215. package/dist/core/compaction/utils.d.ts.map +1 -0
  216. package/dist/core/compaction/utils.js +148 -0
  217. package/dist/core/compaction/utils.js.map +1 -0
  218. package/dist/core/crash-log.d.ts +27 -0
  219. package/dist/core/crash-log.d.ts.map +1 -0
  220. package/dist/core/crash-log.js +140 -0
  221. package/dist/core/crash-log.js.map +1 -0
  222. package/dist/core/defaults.d.ts +4 -0
  223. package/dist/core/defaults.d.ts.map +1 -0
  224. package/dist/core/defaults.js +11 -0
  225. package/dist/core/defaults.js.map +1 -0
  226. package/dist/core/diagnostics.d.ts +15 -0
  227. package/dist/core/diagnostics.d.ts.map +1 -0
  228. package/dist/core/diagnostics.js +2 -0
  229. package/dist/core/diagnostics.js.map +1 -0
  230. package/dist/core/event-bus.d.ts +9 -0
  231. package/dist/core/event-bus.d.ts.map +1 -0
  232. package/dist/core/event-bus.js +25 -0
  233. package/dist/core/event-bus.js.map +1 -0
  234. package/dist/core/exec.d.ts +37 -0
  235. package/dist/core/exec.d.ts.map +1 -0
  236. package/dist/core/exec.js +119 -0
  237. package/dist/core/exec.js.map +1 -0
  238. package/dist/core/experimental.d.ts +2 -0
  239. package/dist/core/experimental.d.ts.map +1 -0
  240. package/dist/core/experimental.js +4 -0
  241. package/dist/core/experimental.js.map +1 -0
  242. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  243. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  244. package/dist/core/export-html/ansi-to-html.js +249 -0
  245. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  246. package/dist/core/export-html/index.d.ts +37 -0
  247. package/dist/core/export-html/index.d.ts.map +1 -0
  248. package/dist/core/export-html/index.js +236 -0
  249. package/dist/core/export-html/index.js.map +1 -0
  250. package/dist/core/export-html/template.css +1085 -0
  251. package/dist/core/export-html/template.html +56 -0
  252. package/dist/core/export-html/template.js +2044 -0
  253. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  254. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  255. package/dist/core/export-html/tool-renderer.js +110 -0
  256. package/dist/core/export-html/tool-renderer.js.map +1 -0
  257. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  258. package/dist/core/export-html/vendor/marked-cjk-friendly.min.js +6 -0
  259. package/dist/core/export-html/vendor/marked.min.js +79 -0
  260. package/dist/core/extensions/index.d.ts +12 -0
  261. package/dist/core/extensions/index.d.ts.map +1 -0
  262. package/dist/core/extensions/index.js +9 -0
  263. package/dist/core/extensions/index.js.map +1 -0
  264. package/dist/core/extensions/jiti-loader.d.ts +2 -0
  265. package/dist/core/extensions/jiti-loader.d.ts.map +1 -0
  266. package/dist/core/extensions/jiti-loader.js +4 -0
  267. package/dist/core/extensions/jiti-loader.js.map +1 -0
  268. package/dist/core/extensions/jiti-static-loader.d.ts +2 -0
  269. package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -0
  270. package/dist/core/extensions/jiti-static-loader.js +4 -0
  271. package/dist/core/extensions/jiti-static-loader.js.map +1 -0
  272. package/dist/core/extensions/loader.d.ts +23 -0
  273. package/dist/core/extensions/loader.d.ts.map +1 -0
  274. package/dist/core/extensions/loader.js +704 -0
  275. package/dist/core/extensions/loader.js.map +1 -0
  276. package/dist/core/extensions/runner.d.ts +215 -0
  277. package/dist/core/extensions/runner.d.ts.map +1 -0
  278. package/dist/core/extensions/runner.js +1238 -0
  279. package/dist/core/extensions/runner.js.map +1 -0
  280. package/dist/core/extensions/types.d.ts +1769 -0
  281. package/dist/core/extensions/types.d.ts.map +1 -0
  282. package/dist/core/extensions/types.js +48 -0
  283. package/dist/core/extensions/types.js.map +1 -0
  284. package/dist/core/extensions/virtual-modules.d.ts +3 -0
  285. package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
  286. package/dist/core/extensions/virtual-modules.js +41 -0
  287. package/dist/core/extensions/virtual-modules.js.map +1 -0
  288. package/dist/core/extensions/wrapper.d.ts +20 -0
  289. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  290. package/dist/core/extensions/wrapper.js +22 -0
  291. package/dist/core/extensions/wrapper.js.map +1 -0
  292. package/dist/core/footer-data-provider.d.ts +64 -0
  293. package/dist/core/footer-data-provider.d.ts.map +1 -0
  294. package/dist/core/footer-data-provider.js +338 -0
  295. package/dist/core/footer-data-provider.js.map +1 -0
  296. package/dist/core/http-dispatcher.d.ts +22 -0
  297. package/dist/core/http-dispatcher.d.ts.map +1 -0
  298. package/dist/core/http-dispatcher.js +98 -0
  299. package/dist/core/http-dispatcher.js.map +1 -0
  300. package/dist/core/index.d.ts +14 -0
  301. package/dist/core/index.d.ts.map +1 -0
  302. package/dist/core/index.js +13 -0
  303. package/dist/core/index.js.map +1 -0
  304. package/dist/core/key-id-schema.d.ts +6 -0
  305. package/dist/core/key-id-schema.d.ts.map +1 -0
  306. package/dist/core/key-id-schema.js +16 -0
  307. package/dist/core/key-id-schema.js.map +1 -0
  308. package/dist/core/keybindings-schema.d.ts +4 -0
  309. package/dist/core/keybindings-schema.d.ts.map +1 -0
  310. package/dist/core/keybindings-schema.js +16 -0
  311. package/dist/core/keybindings-schema.js.map +1 -0
  312. package/dist/core/keybindings.d.ts +568 -0
  313. package/dist/core/keybindings.d.ts.map +1 -0
  314. package/dist/core/keybindings.js +328 -0
  315. package/dist/core/keybindings.js.map +1 -0
  316. package/dist/core/mcp-servers.d.ts +139 -0
  317. package/dist/core/mcp-servers.d.ts.map +1 -0
  318. package/dist/core/mcp-servers.js +232 -0
  319. package/dist/core/mcp-servers.js.map +1 -0
  320. package/dist/core/messages.d.ts +77 -0
  321. package/dist/core/messages.d.ts.map +1 -0
  322. package/dist/core/messages.js +124 -0
  323. package/dist/core/messages.js.map +1 -0
  324. package/dist/core/model-config.d.ts +2312 -0
  325. package/dist/core/model-config.d.ts.map +1 -0
  326. package/dist/core/model-config.js +168 -0
  327. package/dist/core/model-config.js.map +1 -0
  328. package/dist/core/model-registry.d.ts +63 -0
  329. package/dist/core/model-registry.d.ts.map +1 -0
  330. package/dist/core/model-registry.js +144 -0
  331. package/dist/core/model-registry.js.map +1 -0
  332. package/dist/core/model-resolver.d.ts +137 -0
  333. package/dist/core/model-resolver.d.ts.map +1 -0
  334. package/dist/core/model-resolver.js +491 -0
  335. package/dist/core/model-resolver.js.map +1 -0
  336. package/dist/core/model-runtime.d.ts +145 -0
  337. package/dist/core/model-runtime.d.ts.map +1 -0
  338. package/dist/core/model-runtime.js +767 -0
  339. package/dist/core/model-runtime.js.map +1 -0
  340. package/dist/core/models-store.d.ts +22 -0
  341. package/dist/core/models-store.d.ts.map +1 -0
  342. package/dist/core/models-store.js +115 -0
  343. package/dist/core/models-store.js.map +1 -0
  344. package/dist/core/nested-tool-calls.d.ts +103 -0
  345. package/dist/core/nested-tool-calls.d.ts.map +1 -0
  346. package/dist/core/nested-tool-calls.js +179 -0
  347. package/dist/core/nested-tool-calls.js.map +1 -0
  348. package/dist/core/output-guard.d.ts +7 -0
  349. package/dist/core/output-guard.d.ts.map +1 -0
  350. package/dist/core/output-guard.js +89 -0
  351. package/dist/core/output-guard.js.map +1 -0
  352. package/dist/core/package-manager.d.ts +226 -0
  353. package/dist/core/package-manager.d.ts.map +1 -0
  354. package/dist/core/package-manager.js +2275 -0
  355. package/dist/core/package-manager.js.map +1 -0
  356. package/dist/core/pi-manifest.d.ts +9 -0
  357. package/dist/core/pi-manifest.d.ts.map +1 -0
  358. package/dist/core/pi-manifest.js +30 -0
  359. package/dist/core/pi-manifest.js.map +1 -0
  360. package/dist/core/project-trust.d.ts +15 -0
  361. package/dist/core/project-trust.d.ts.map +1 -0
  362. package/dist/core/project-trust.js +60 -0
  363. package/dist/core/project-trust.js.map +1 -0
  364. package/dist/core/prompt-templates.d.ts +59 -0
  365. package/dist/core/prompt-templates.d.ts.map +1 -0
  366. package/dist/core/prompt-templates.js +267 -0
  367. package/dist/core/prompt-templates.js.map +1 -0
  368. package/dist/core/provider-composer.d.ts +81 -0
  369. package/dist/core/provider-composer.d.ts.map +1 -0
  370. package/dist/core/provider-composer.js +492 -0
  371. package/dist/core/provider-composer.js.map +1 -0
  372. package/dist/core/radius.d.ts +7 -0
  373. package/dist/core/radius.d.ts.map +1 -0
  374. package/dist/core/radius.js +10 -0
  375. package/dist/core/radius.js.map +1 -0
  376. package/dist/core/remote-catalog-provider.d.ts +23 -0
  377. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  378. package/dist/core/remote-catalog-provider.js +190 -0
  379. package/dist/core/remote-catalog-provider.js.map +1 -0
  380. package/dist/core/resolve-config-value.d.ts +30 -0
  381. package/dist/core/resolve-config-value.d.ts.map +1 -0
  382. package/dist/core/resolve-config-value.js +247 -0
  383. package/dist/core/resolve-config-value.js.map +1 -0
  384. package/dist/core/resource-loader.d.ts +232 -0
  385. package/dist/core/resource-loader.d.ts.map +1 -0
  386. package/dist/core/resource-loader.js +1026 -0
  387. package/dist/core/resource-loader.js.map +1 -0
  388. package/dist/core/runtime-credentials.d.ts +15 -0
  389. package/dist/core/runtime-credentials.d.ts.map +1 -0
  390. package/dist/core/runtime-credentials.js +39 -0
  391. package/dist/core/runtime-credentials.js.map +1 -0
  392. package/dist/core/sdk.d.ts +117 -0
  393. package/dist/core/sdk.d.ts.map +1 -0
  394. package/dist/core/sdk.js +329 -0
  395. package/dist/core/sdk.js.map +1 -0
  396. package/dist/core/session-cwd.d.ts +19 -0
  397. package/dist/core/session-cwd.d.ts.map +1 -0
  398. package/dist/core/session-cwd.js +38 -0
  399. package/dist/core/session-cwd.js.map +1 -0
  400. package/dist/core/session-delete.d.ts +8 -0
  401. package/dist/core/session-delete.d.ts.map +1 -0
  402. package/dist/core/session-delete.js +37 -0
  403. package/dist/core/session-delete.js.map +1 -0
  404. package/dist/core/session-export.d.ts +8 -0
  405. package/dist/core/session-export.d.ts.map +1 -0
  406. package/dist/core/session-export.js +33 -0
  407. package/dist/core/session-export.js.map +1 -0
  408. package/dist/core/session-manager.d.ts +422 -0
  409. package/dist/core/session-manager.d.ts.map +1 -0
  410. package/dist/core/session-manager.js +1568 -0
  411. package/dist/core/session-manager.js.map +1 -0
  412. package/dist/core/session-move.d.ts +3 -0
  413. package/dist/core/session-move.d.ts.map +1 -0
  414. package/dist/core/session-move.js +133 -0
  415. package/dist/core/session-move.js.map +1 -0
  416. package/dist/core/session-ownership.d.ts +13 -0
  417. package/dist/core/session-ownership.d.ts.map +1 -0
  418. package/dist/core/session-ownership.js +205 -0
  419. package/dist/core/session-ownership.js.map +1 -0
  420. package/dist/core/settings-defaults.d.ts +66 -0
  421. package/dist/core/settings-defaults.d.ts.map +1 -0
  422. package/dist/core/settings-defaults.js +67 -0
  423. package/dist/core/settings-defaults.js.map +1 -0
  424. package/dist/core/settings-diagnostics.d.ts +9 -0
  425. package/dist/core/settings-diagnostics.d.ts.map +1 -0
  426. package/dist/core/settings-diagnostics.js +21 -0
  427. package/dist/core/settings-diagnostics.js.map +1 -0
  428. package/dist/core/settings-manager.d.ts +253 -0
  429. package/dist/core/settings-manager.d.ts.map +1 -0
  430. package/dist/core/settings-manager.js +1154 -0
  431. package/dist/core/settings-manager.js.map +1 -0
  432. package/dist/core/settings-schema.d.ts +231 -0
  433. package/dist/core/settings-schema.d.ts.map +1 -0
  434. package/dist/core/settings-schema.js +294 -0
  435. package/dist/core/settings-schema.js.map +1 -0
  436. package/dist/core/skills.d.ts +63 -0
  437. package/dist/core/skills.d.ts.map +1 -0
  438. package/dist/core/skills.js +412 -0
  439. package/dist/core/skills.js.map +1 -0
  440. package/dist/core/slash-commands.d.ts +15 -0
  441. package/dist/core/slash-commands.d.ts.map +1 -0
  442. package/dist/core/slash-commands.js +28 -0
  443. package/dist/core/slash-commands.js.map +1 -0
  444. package/dist/core/source-info.d.ts +33 -0
  445. package/dist/core/source-info.d.ts.map +1 -0
  446. package/dist/core/source-info.js +43 -0
  447. package/dist/core/source-info.js.map +1 -0
  448. package/dist/core/system-prompt.d.ts +77 -0
  449. package/dist/core/system-prompt.d.ts.map +1 -0
  450. package/dist/core/system-prompt.js +152 -0
  451. package/dist/core/system-prompt.js.map +1 -0
  452. package/dist/core/telemetry.d.ts +3 -0
  453. package/dist/core/telemetry.d.ts.map +1 -0
  454. package/dist/core/telemetry.js +9 -0
  455. package/dist/core/telemetry.js.map +1 -0
  456. package/dist/core/timings.d.ts +10 -0
  457. package/dist/core/timings.d.ts.map +1 -0
  458. package/dist/core/timings.js +41 -0
  459. package/dist/core/timings.js.map +1 -0
  460. package/dist/core/tools/bash.d.ts +100 -0
  461. package/dist/core/tools/bash.d.ts.map +1 -0
  462. package/dist/core/tools/bash.js +333 -0
  463. package/dist/core/tools/bash.js.map +1 -0
  464. package/dist/core/tools/edit-diff.d.ts +101 -0
  465. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  466. package/dist/core/tools/edit-diff.js +421 -0
  467. package/dist/core/tools/edit-diff.js.map +1 -0
  468. package/dist/core/tools/edit.d.ts +44 -0
  469. package/dist/core/tools/edit.d.ts.map +1 -0
  470. package/dist/core/tools/edit.js +147 -0
  471. package/dist/core/tools/edit.js.map +1 -0
  472. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  473. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  474. package/dist/core/tools/file-mutation-queue.js +52 -0
  475. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  476. package/dist/core/tools/find.d.ts +42 -0
  477. package/dist/core/tools/find.d.ts.map +1 -0
  478. package/dist/core/tools/find.js +251 -0
  479. package/dist/core/tools/find.js.map +1 -0
  480. package/dist/core/tools/grep.d.ts +41 -0
  481. package/dist/core/tools/grep.d.ts.map +1 -0
  482. package/dist/core/tools/grep.js +254 -0
  483. package/dist/core/tools/grep.js.map +1 -0
  484. package/dist/core/tools/index.d.ts +43 -0
  485. package/dist/core/tools/index.d.ts.map +1 -0
  486. package/dist/core/tools/index.js +129 -0
  487. package/dist/core/tools/index.js.map +1 -0
  488. package/dist/core/tools/ls.d.ts +41 -0
  489. package/dist/core/tools/ls.d.ts.map +1 -0
  490. package/dist/core/tools/ls.js +126 -0
  491. package/dist/core/tools/ls.js.map +1 -0
  492. package/dist/core/tools/output-accumulator.d.ts +63 -0
  493. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  494. package/dist/core/tools/output-accumulator.js +214 -0
  495. package/dist/core/tools/output-accumulator.js.map +1 -0
  496. package/dist/core/tools/path-utils.d.ts +10 -0
  497. package/dist/core/tools/path-utils.d.ts.map +1 -0
  498. package/dist/core/tools/path-utils.js +99 -0
  499. package/dist/core/tools/path-utils.js.map +1 -0
  500. package/dist/core/tools/powershell.d.ts +16 -0
  501. package/dist/core/tools/powershell.d.ts.map +1 -0
  502. package/dist/core/tools/powershell.js +39 -0
  503. package/dist/core/tools/powershell.js.map +1 -0
  504. package/dist/core/tools/read.d.ts +55 -0
  505. package/dist/core/tools/read.d.ts.map +1 -0
  506. package/dist/core/tools/read.js +186 -0
  507. package/dist/core/tools/read.js.map +1 -0
  508. package/dist/core/tools/render-utils.d.ts +50 -0
  509. package/dist/core/tools/render-utils.d.ts.map +1 -0
  510. package/dist/core/tools/render-utils.js +158 -0
  511. package/dist/core/tools/render-utils.js.map +1 -0
  512. package/dist/core/tools/renderers/bash.d.ts +12 -0
  513. package/dist/core/tools/renderers/bash.d.ts.map +1 -0
  514. package/dist/core/tools/renderers/bash.js +89 -0
  515. package/dist/core/tools/renderers/bash.js.map +1 -0
  516. package/dist/core/tools/renderers/edit.d.ts +23 -0
  517. package/dist/core/tools/renderers/edit.d.ts.map +1 -0
  518. package/dist/core/tools/renderers/edit.js +168 -0
  519. package/dist/core/tools/renderers/edit.js.map +1 -0
  520. package/dist/core/tools/renderers/find.d.ts +10 -0
  521. package/dist/core/tools/renderers/find.d.ts.map +1 -0
  522. package/dist/core/tools/renderers/find.js +64 -0
  523. package/dist/core/tools/renderers/find.js.map +1 -0
  524. package/dist/core/tools/renderers/grep.d.ts +10 -0
  525. package/dist/core/tools/renderers/grep.d.ts.map +1 -0
  526. package/dist/core/tools/renderers/grep.js +69 -0
  527. package/dist/core/tools/renderers/grep.js.map +1 -0
  528. package/dist/core/tools/renderers/index.d.ts +28 -0
  529. package/dist/core/tools/renderers/index.d.ts.map +1 -0
  530. package/dist/core/tools/renderers/index.js +47 -0
  531. package/dist/core/tools/renderers/index.js.map +1 -0
  532. package/dist/core/tools/renderers/ls.d.ts +10 -0
  533. package/dist/core/tools/renderers/ls.d.ts.map +1 -0
  534. package/dist/core/tools/renderers/ls.js +58 -0
  535. package/dist/core/tools/renderers/ls.js.map +1 -0
  536. package/dist/core/tools/renderers/read.d.ts +11 -0
  537. package/dist/core/tools/renderers/read.d.ts.map +1 -0
  538. package/dist/core/tools/renderers/read.js +126 -0
  539. package/dist/core/tools/renderers/read.js.map +1 -0
  540. package/dist/core/tools/renderers/write.d.ts +10 -0
  541. package/dist/core/tools/renderers/write.d.ts.map +1 -0
  542. package/dist/core/tools/renderers/write.js +153 -0
  543. package/dist/core/tools/renderers/write.js.map +1 -0
  544. package/dist/core/tools/tool-definition-wrapper.d.ts +16 -0
  545. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  546. package/dist/core/tools/tool-definition-wrapper.js +38 -0
  547. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  548. package/dist/core/tools/truncate.d.ts +84 -0
  549. package/dist/core/tools/truncate.d.ts.map +1 -0
  550. package/dist/core/tools/truncate.js +244 -0
  551. package/dist/core/tools/truncate.js.map +1 -0
  552. package/dist/core/tools/write.d.ts +30 -0
  553. package/dist/core/tools/write.d.ts.map +1 -0
  554. package/dist/core/tools/write.js +61 -0
  555. package/dist/core/tools/write.js.map +1 -0
  556. package/dist/core/trust-manager.d.ts +36 -0
  557. package/dist/core/trust-manager.d.ts.map +1 -0
  558. package/dist/core/trust-manager.js +204 -0
  559. package/dist/core/trust-manager.js.map +1 -0
  560. package/dist/core/usage-totals.d.ts +21 -0
  561. package/dist/core/usage-totals.d.ts.map +1 -0
  562. package/dist/core/usage-totals.js +81 -0
  563. package/dist/core/usage-totals.js.map +1 -0
  564. package/dist/core/virtual-models.d.ts +117 -0
  565. package/dist/core/virtual-models.d.ts.map +1 -0
  566. package/dist/core/virtual-models.js +124 -0
  567. package/dist/core/virtual-models.js.map +1 -0
  568. package/dist/extensions/codemode/execute.d.ts +16 -0
  569. package/dist/extensions/codemode/execute.d.ts.map +1 -0
  570. package/dist/extensions/codemode/execute.js +740 -0
  571. package/dist/extensions/codemode/execute.js.map +1 -0
  572. package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
  573. package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
  574. package/dist/extensions/codemode/execute.lazy.js +3 -0
  575. package/dist/extensions/codemode/execute.lazy.js.map +1 -0
  576. package/dist/extensions/codemode/index.d.ts +21 -0
  577. package/dist/extensions/codemode/index.d.ts.map +1 -0
  578. package/dist/extensions/codemode/index.js +33 -0
  579. package/dist/extensions/codemode/index.js.map +1 -0
  580. package/dist/extensions/codemode/renderer.d.ts +12 -0
  581. package/dist/extensions/codemode/renderer.d.ts.map +1 -0
  582. package/dist/extensions/codemode/renderer.js +143 -0
  583. package/dist/extensions/codemode/renderer.js.map +1 -0
  584. package/dist/extensions/codemode/tool.d.ts +124 -0
  585. package/dist/extensions/codemode/tool.d.ts.map +1 -0
  586. package/dist/extensions/codemode/tool.js +313 -0
  587. package/dist/extensions/codemode/tool.js.map +1 -0
  588. package/dist/extensions/codemode/worker.d.ts +7 -0
  589. package/dist/extensions/codemode/worker.d.ts.map +1 -0
  590. package/dist/extensions/codemode/worker.js +7 -0
  591. package/dist/extensions/codemode/worker.js.map +1 -0
  592. package/dist/extensions/index.d.ts +3 -0
  593. package/dist/extensions/index.d.ts.map +1 -0
  594. package/dist/extensions/index.js +13 -0
  595. package/dist/extensions/index.js.map +1 -0
  596. package/dist/extensions/llama/client.d.ts +69 -0
  597. package/dist/extensions/llama/client.d.ts.map +1 -0
  598. package/dist/extensions/llama/client.js +313 -0
  599. package/dist/extensions/llama/client.js.map +1 -0
  600. package/dist/extensions/llama/huggingface.d.ts +23 -0
  601. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  602. package/dist/extensions/llama/huggingface.js +141 -0
  603. package/dist/extensions/llama/huggingface.js.map +1 -0
  604. package/dist/extensions/llama/index.d.ts +3 -0
  605. package/dist/extensions/llama/index.d.ts.map +1 -0
  606. package/dist/extensions/llama/index.js +219 -0
  607. package/dist/extensions/llama/index.js.map +1 -0
  608. package/dist/extensions/llama/provider.d.ts +12 -0
  609. package/dist/extensions/llama/provider.d.ts.map +1 -0
  610. package/dist/extensions/llama/provider.js +236 -0
  611. package/dist/extensions/llama/provider.js.map +1 -0
  612. package/dist/extensions/llama/ui.d.ts +42 -0
  613. package/dist/extensions/llama/ui.d.ts.map +1 -0
  614. package/dist/extensions/llama/ui.js +428 -0
  615. package/dist/extensions/llama/ui.js.map +1 -0
  616. package/dist/extensions/mcp/cli.d.ts +21 -0
  617. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  618. package/dist/extensions/mcp/cli.js +494 -0
  619. package/dist/extensions/mcp/cli.js.map +1 -0
  620. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  621. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  622. package/dist/extensions/mcp/cli.lazy.js +3 -0
  623. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  624. package/dist/extensions/mcp/config.d.ts +84 -0
  625. package/dist/extensions/mcp/config.d.ts.map +1 -0
  626. package/dist/extensions/mcp/config.js +195 -0
  627. package/dist/extensions/mcp/config.js.map +1 -0
  628. package/dist/extensions/mcp/index.d.ts +79 -0
  629. package/dist/extensions/mcp/index.d.ts.map +1 -0
  630. package/dist/extensions/mcp/index.js +1205 -0
  631. package/dist/extensions/mcp/index.js.map +1 -0
  632. package/dist/extensions/mcp/log.d.ts +16 -0
  633. package/dist/extensions/mcp/log.d.ts.map +1 -0
  634. package/dist/extensions/mcp/log.js +66 -0
  635. package/dist/extensions/mcp/log.js.map +1 -0
  636. package/dist/extensions/mcp/oauth.d.ts +102 -0
  637. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  638. package/dist/extensions/mcp/oauth.js +428 -0
  639. package/dist/extensions/mcp/oauth.js.map +1 -0
  640. package/dist/extensions/mcp/resources.d.ts +36 -0
  641. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  642. package/dist/extensions/mcp/resources.js +261 -0
  643. package/dist/extensions/mcp/resources.js.map +1 -0
  644. package/dist/extensions/mcp/runtime.d.ts +98 -0
  645. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  646. package/dist/extensions/mcp/runtime.js +378 -0
  647. package/dist/extensions/mcp/runtime.js.map +1 -0
  648. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  649. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  650. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  651. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  652. package/dist/extensions/mcp/tools.d.ts +86 -0
  653. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  654. package/dist/extensions/mcp/tools.js +309 -0
  655. package/dist/extensions/mcp/tools.js.map +1 -0
  656. package/dist/extensions/mcp/ui.d.ts +61 -0
  657. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  658. package/dist/extensions/mcp/ui.js +195 -0
  659. package/dist/extensions/mcp/ui.js.map +1 -0
  660. package/dist/extensions/tool-search/index.d.ts +12 -0
  661. package/dist/extensions/tool-search/index.d.ts.map +1 -0
  662. package/dist/extensions/tool-search/index.js +15 -0
  663. package/dist/extensions/tool-search/index.js.map +1 -0
  664. package/dist/extensions/tool-search/tool.d.ts +75 -0
  665. package/dist/extensions/tool-search/tool.d.ts.map +1 -0
  666. package/dist/extensions/tool-search/tool.js +210 -0
  667. package/dist/extensions/tool-search/tool.js.map +1 -0
  668. package/dist/index.d.ts +45 -0
  669. package/dist/index.d.ts.map +1 -0
  670. package/dist/index.js +54 -0
  671. package/dist/index.js.map +1 -0
  672. package/dist/main.d.ts +16 -0
  673. package/dist/main.d.ts.map +1 -0
  674. package/dist/main.js +836 -0
  675. package/dist/main.js.map +1 -0
  676. package/dist/migrations.d.ts +33 -0
  677. package/dist/migrations.d.ts.map +1 -0
  678. package/dist/migrations.js +282 -0
  679. package/dist/migrations.js.map +1 -0
  680. package/dist/modes/index.d.ts +10 -0
  681. package/dist/modes/index.d.ts.map +1 -0
  682. package/dist/modes/index.js +8 -0
  683. package/dist/modes/index.js.map +1 -0
  684. package/dist/modes/interactive/assets/clankolas.png +0 -0
  685. package/dist/modes/interactive/bug-report.d.ts +16 -0
  686. package/dist/modes/interactive/bug-report.d.ts.map +1 -0
  687. package/dist/modes/interactive/bug-report.js +210 -0
  688. package/dist/modes/interactive/bug-report.js.map +1 -0
  689. package/dist/modes/interactive/chat-viewport.d.ts +20 -0
  690. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -0
  691. package/dist/modes/interactive/chat-viewport.js +28 -0
  692. package/dist/modes/interactive/chat-viewport.js.map +1 -0
  693. package/dist/modes/interactive/components/armin.d.ts +37 -0
  694. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  695. package/dist/modes/interactive/components/armin.js +335 -0
  696. package/dist/modes/interactive/components/armin.js.map +1 -0
  697. package/dist/modes/interactive/components/assistant-message.d.ts +28 -0
  698. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  699. package/dist/modes/interactive/components/assistant-message.js +168 -0
  700. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  701. package/dist/modes/interactive/components/auth-url.d.ts +14 -0
  702. package/dist/modes/interactive/components/auth-url.d.ts.map +1 -0
  703. package/dist/modes/interactive/components/auth-url.js +37 -0
  704. package/dist/modes/interactive/components/auth-url.js.map +1 -0
  705. package/dist/modes/interactive/components/bash-execution.d.ts +38 -0
  706. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  707. package/dist/modes/interactive/components/bash-execution.js +178 -0
  708. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  709. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  710. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  711. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  712. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  713. package/dist/modes/interactive/components/branch-summary-message.d.ts +17 -0
  714. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  715. package/dist/modes/interactive/components/branch-summary-message.js +54 -0
  716. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  717. package/dist/modes/interactive/components/compaction-summary-message.d.ts +17 -0
  718. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  719. package/dist/modes/interactive/components/compaction-summary-message.js +55 -0
  720. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  721. package/dist/modes/interactive/components/config-selector.d.ts +102 -0
  722. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  723. package/dist/modes/interactive/components/config-selector.js +771 -0
  724. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  725. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  726. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  727. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  728. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  729. package/dist/modes/interactive/components/custom-editor.d.ts +30 -0
  730. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  731. package/dist/modes/interactive/components/custom-editor.js +122 -0
  732. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  733. package/dist/modes/interactive/components/custom-entry.d.ts +21 -0
  734. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
  735. package/dist/modes/interactive/components/custom-entry.js +58 -0
  736. package/dist/modes/interactive/components/custom-entry.js.map +1 -0
  737. package/dist/modes/interactive/components/custom-message.d.ts +22 -0
  738. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  739. package/dist/modes/interactive/components/custom-message.js +88 -0
  740. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  741. package/dist/modes/interactive/components/diff.d.ts +12 -0
  742. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  743. package/dist/modes/interactive/components/diff.js +133 -0
  744. package/dist/modes/interactive/components/diff.js.map +1 -0
  745. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  746. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  747. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  748. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  749. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  750. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  751. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  752. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  753. package/dist/modes/interactive/components/easter-egg-3d.d.ts +104 -0
  754. package/dist/modes/interactive/components/easter-egg-3d.d.ts.map +1 -0
  755. package/dist/modes/interactive/components/easter-egg-3d.js +1139 -0
  756. package/dist/modes/interactive/components/easter-egg-3d.js.map +1 -0
  757. package/dist/modes/interactive/components/easter-egg-3d.lazy.d.ts +6 -0
  758. package/dist/modes/interactive/components/easter-egg-3d.lazy.d.ts.map +1 -0
  759. package/dist/modes/interactive/components/easter-egg-3d.lazy.js +23 -0
  760. package/dist/modes/interactive/components/easter-egg-3d.lazy.js.map +1 -0
  761. package/dist/modes/interactive/components/extension-editor.d.ts +24 -0
  762. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  763. package/dist/modes/interactive/components/extension-editor.js +103 -0
  764. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  765. package/dist/modes/interactive/components/extension-input.d.ts +25 -0
  766. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  767. package/dist/modes/interactive/components/extension-input.js +67 -0
  768. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  769. package/dist/modes/interactive/components/extension-selector.d.ts +27 -0
  770. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  771. package/dist/modes/interactive/components/extension-selector.js +87 -0
  772. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  773. package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  774. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  775. package/dist/modes/interactive/components/first-time-setup.js +109 -0
  776. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  777. package/dist/modes/interactive/components/footer.d.ts +39 -0
  778. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  779. package/dist/modes/interactive/components/footer.js +265 -0
  780. package/dist/modes/interactive/components/footer.js.map +1 -0
  781. package/dist/modes/interactive/components/index.d.ts +33 -0
  782. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  783. package/dist/modes/interactive/components/index.js +34 -0
  784. package/dist/modes/interactive/components/index.js.map +1 -0
  785. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  786. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  787. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  788. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  789. package/dist/modes/interactive/components/login-dialog.d.ts +59 -0
  790. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  791. package/dist/modes/interactive/components/login-dialog.js +289 -0
  792. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  793. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  794. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  795. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  796. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  797. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  798. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  799. package/dist/modes/interactive/components/mermaid.js +75 -0
  800. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  801. package/dist/modes/interactive/components/model-selector.d.ts +61 -0
  802. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  803. package/dist/modes/interactive/components/model-selector.js +372 -0
  804. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  805. package/dist/modes/interactive/components/oauth-selector.d.ts +40 -0
  806. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  807. package/dist/modes/interactive/components/oauth-selector.js +175 -0
  808. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  809. package/dist/modes/interactive/components/pi-logo.d.ts +19 -0
  810. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
  811. package/dist/modes/interactive/components/pi-logo.js +37 -0
  812. package/dist/modes/interactive/components/pi-logo.js.map +1 -0
  813. package/dist/modes/interactive/components/radius-login-selector.d.ts +15 -0
  814. package/dist/modes/interactive/components/radius-login-selector.d.ts.map +1 -0
  815. package/dist/modes/interactive/components/radius-login-selector.js +85 -0
  816. package/dist/modes/interactive/components/radius-login-selector.js.map +1 -0
  817. package/dist/modes/interactive/components/scoped-models-selector.d.ts +47 -0
  818. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  819. package/dist/modes/interactive/components/scoped-models-selector.js +337 -0
  820. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  821. package/dist/modes/interactive/components/session-selector-search.d.ts +27 -0
  822. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  823. package/dist/modes/interactive/components/session-selector-search.js +219 -0
  824. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  825. package/dist/modes/interactive/components/session-selector.d.ts +104 -0
  826. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  827. package/dist/modes/interactive/components/session-selector.js +932 -0
  828. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  829. package/dist/modes/interactive/components/settings-selector.d.ts +98 -0
  830. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  831. package/dist/modes/interactive/components/settings-selector.js +753 -0
  832. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  833. package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
  834. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
  835. package/dist/modes/interactive/components/settings-submenu.js +167 -0
  836. package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
  837. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  838. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  839. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  840. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  841. package/dist/modes/interactive/components/skill-invocation-message.d.ts +18 -0
  842. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  843. package/dist/modes/interactive/components/skill-invocation-message.js +57 -0
  844. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  845. package/dist/modes/interactive/components/status-indicator.d.ts +30 -0
  846. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -0
  847. package/dist/modes/interactive/components/status-indicator.js +67 -0
  848. package/dist/modes/interactive/components/status-indicator.js.map +1 -0
  849. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  850. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  851. package/dist/modes/interactive/components/theme-selector.js +50 -0
  852. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  853. package/dist/modes/interactive/components/themed-text.d.ts +17 -0
  854. package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
  855. package/dist/modes/interactive/components/themed-text.js +29 -0
  856. package/dist/modes/interactive/components/themed-text.js.map +1 -0
  857. package/dist/modes/interactive/components/thinking-selector.d.ts +23 -0
  858. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  859. package/dist/modes/interactive/components/thinking-selector.js +109 -0
  860. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  861. package/dist/modes/interactive/components/tool-execution.d.ts +79 -0
  862. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  863. package/dist/modes/interactive/components/tool-execution.js +334 -0
  864. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  865. package/dist/modes/interactive/components/tree-selector.d.ts +95 -0
  866. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  867. package/dist/modes/interactive/components/tree-selector.js +1250 -0
  868. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  869. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  870. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  871. package/dist/modes/interactive/components/trust-selector.js +91 -0
  872. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  873. package/dist/modes/interactive/components/user-message-selector.d.ts +31 -0
  874. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  875. package/dist/modes/interactive/components/user-message-selector.js +122 -0
  876. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  877. package/dist/modes/interactive/components/user-message.d.ts +18 -0
  878. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  879. package/dist/modes/interactive/components/user-message.js +54 -0
  880. package/dist/modes/interactive/components/user-message.js.map +1 -0
  881. package/dist/modes/interactive/components/visual-truncate.d.ts +48 -0
  882. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  883. package/dist/modes/interactive/components/visual-truncate.js +66 -0
  884. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  885. package/dist/modes/interactive/external-editor.d.ts +12 -0
  886. package/dist/modes/interactive/external-editor.d.ts.map +1 -0
  887. package/dist/modes/interactive/external-editor.js +38 -0
  888. package/dist/modes/interactive/external-editor.js.map +1 -0
  889. package/dist/modes/interactive/interactive-mode.d.ts +491 -0
  890. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  891. package/dist/modes/interactive/interactive-mode.js +6060 -0
  892. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  893. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  894. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  895. package/dist/modes/interactive/model-catalog-refresh.js +34 -0
  896. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  897. package/dist/modes/interactive/model-search.d.ts +22 -0
  898. package/dist/modes/interactive/model-search.d.ts.map +1 -0
  899. package/dist/modes/interactive/model-search.js +36 -0
  900. package/dist/modes/interactive/model-search.js.map +1 -0
  901. package/dist/modes/interactive/program-status-reporter.d.ts +34 -0
  902. package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
  903. package/dist/modes/interactive/program-status-reporter.js +110 -0
  904. package/dist/modes/interactive/program-status-reporter.js.map +1 -0
  905. package/dist/modes/interactive/session-share.d.ts +18 -0
  906. package/dist/modes/interactive/session-share.d.ts.map +1 -0
  907. package/dist/modes/interactive/session-share.js +195 -0
  908. package/dist/modes/interactive/session-share.js.map +1 -0
  909. package/dist/modes/interactive/theme/dark.json +78 -0
  910. package/dist/modes/interactive/theme/light.json +78 -0
  911. package/dist/modes/interactive/theme/system-theme.d.ts +55 -0
  912. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  913. package/dist/modes/interactive/theme/system-theme.js +546 -0
  914. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  915. package/dist/modes/interactive/theme/theme-controller.d.ts +81 -0
  916. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
  917. package/dist/modes/interactive/theme/theme-controller.js +210 -0
  918. package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
  919. package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
  920. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  921. package/dist/modes/interactive/theme/theme-schema.js +105 -0
  922. package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  923. package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
  924. package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
  925. package/dist/modes/interactive/theme/theme-tokens.js +94 -0
  926. package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
  927. package/dist/modes/interactive/theme/theme.d.ts +155 -0
  928. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  929. package/dist/modes/interactive/theme/theme.js +905 -0
  930. package/dist/modes/interactive/theme/theme.js.map +1 -0
  931. package/dist/modes/interactive/tui-renderer.d.ts +22 -0
  932. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -0
  933. package/dist/modes/interactive/tui-renderer.js +67 -0
  934. package/dist/modes/interactive/tui-renderer.js.map +1 -0
  935. package/dist/modes/json-event.d.ts +34 -0
  936. package/dist/modes/json-event.d.ts.map +1 -0
  937. package/dist/modes/json-event.js +29 -0
  938. package/dist/modes/json-event.js.map +1 -0
  939. package/dist/modes/print-mode.d.ts +28 -0
  940. package/dist/modes/print-mode.d.ts.map +1 -0
  941. package/dist/modes/print-mode.js +146 -0
  942. package/dist/modes/print-mode.js.map +1 -0
  943. package/dist/modes/rpc/jsonl.d.ts +17 -0
  944. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  945. package/dist/modes/rpc/jsonl.js +49 -0
  946. package/dist/modes/rpc/jsonl.js.map +1 -0
  947. package/dist/modes/rpc/rpc-client.d.ts +254 -0
  948. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  949. package/dist/modes/rpc/rpc-client.js +499 -0
  950. package/dist/modes/rpc/rpc-client.js.map +1 -0
  951. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  952. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  953. package/dist/modes/rpc/rpc-mode.js +655 -0
  954. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  955. package/dist/modes/rpc/rpc-types.d.ts +478 -0
  956. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  957. package/dist/modes/rpc/rpc-types.js +8 -0
  958. package/dist/modes/rpc/rpc-types.js.map +1 -0
  959. package/dist/package-manager-cli.d.ts +9 -0
  960. package/dist/package-manager-cli.d.ts.map +1 -0
  961. package/dist/package-manager-cli.js +1015 -0
  962. package/dist/package-manager-cli.js.map +1 -0
  963. package/dist/rpc-entry.d.ts +3 -0
  964. package/dist/rpc-entry.d.ts.map +1 -0
  965. package/dist/rpc-entry.js +11 -0
  966. package/dist/rpc-entry.js.map +1 -0
  967. package/dist/utils/abort.d.ts +5 -0
  968. package/dist/utils/abort.d.ts.map +1 -0
  969. package/dist/utils/abort.js +48 -0
  970. package/dist/utils/abort.js.map +1 -0
  971. package/dist/utils/ansi.d.ts +10 -0
  972. package/dist/utils/ansi.d.ts.map +1 -0
  973. package/dist/utils/ansi.js +74 -0
  974. package/dist/utils/ansi.js.map +1 -0
  975. package/dist/utils/changelog.d.ts +22 -0
  976. package/dist/utils/changelog.d.ts.map +1 -0
  977. package/dist/utils/changelog.js +165 -0
  978. package/dist/utils/changelog.js.map +1 -0
  979. package/dist/utils/child-process.d.ts +18 -0
  980. package/dist/utils/child-process.d.ts.map +1 -0
  981. package/dist/utils/child-process.js +106 -0
  982. package/dist/utils/child-process.js.map +1 -0
  983. package/dist/utils/clipboard-command.d.ts +7 -0
  984. package/dist/utils/clipboard-command.d.ts.map +1 -0
  985. package/dist/utils/clipboard-command.js +48 -0
  986. package/dist/utils/clipboard-command.js.map +1 -0
  987. package/dist/utils/clipboard-image.d.ts +11 -0
  988. package/dist/utils/clipboard-image.d.ts.map +1 -0
  989. package/dist/utils/clipboard-image.js +214 -0
  990. package/dist/utils/clipboard-image.js.map +1 -0
  991. package/dist/utils/clipboard.d.ts +6 -0
  992. package/dist/utils/clipboard.d.ts.map +1 -0
  993. package/dist/utils/clipboard.js +162 -0
  994. package/dist/utils/clipboard.js.map +1 -0
  995. package/dist/utils/deprecation.d.ts +4 -0
  996. package/dist/utils/deprecation.d.ts.map +1 -0
  997. package/dist/utils/deprecation.js +13 -0
  998. package/dist/utils/deprecation.js.map +1 -0
  999. package/dist/utils/exif-orientation.d.ts +5 -0
  1000. package/dist/utils/exif-orientation.d.ts.map +1 -0
  1001. package/dist/utils/exif-orientation.js +157 -0
  1002. package/dist/utils/exif-orientation.js.map +1 -0
  1003. package/dist/utils/frontmatter.d.ts +8 -0
  1004. package/dist/utils/frontmatter.d.ts.map +1 -0
  1005. package/dist/utils/frontmatter.js +27 -0
  1006. package/dist/utils/frontmatter.js.map +1 -0
  1007. package/dist/utils/fs-watch.d.ts +5 -0
  1008. package/dist/utils/fs-watch.d.ts.map +1 -0
  1009. package/dist/utils/fs-watch.js +25 -0
  1010. package/dist/utils/fs-watch.js.map +1 -0
  1011. package/dist/utils/git.d.ts +26 -0
  1012. package/dist/utils/git.d.ts.map +1 -0
  1013. package/dist/utils/git.js +195 -0
  1014. package/dist/utils/git.js.map +1 -0
  1015. package/dist/utils/html.d.ts +7 -0
  1016. package/dist/utils/html.d.ts.map +1 -0
  1017. package/dist/utils/html.js +40 -0
  1018. package/dist/utils/html.js.map +1 -0
  1019. package/dist/utils/image-convert.d.ts +22 -0
  1020. package/dist/utils/image-convert.d.ts.map +1 -0
  1021. package/dist/utils/image-convert.js +84 -0
  1022. package/dist/utils/image-convert.js.map +1 -0
  1023. package/dist/utils/image-process.d.ts +18 -0
  1024. package/dist/utils/image-process.d.ts.map +1 -0
  1025. package/dist/utils/image-process.js +83 -0
  1026. package/dist/utils/image-process.js.map +1 -0
  1027. package/dist/utils/image-resize-core.d.ts +42 -0
  1028. package/dist/utils/image-resize-core.d.ts.map +1 -0
  1029. package/dist/utils/image-resize-core.js +129 -0
  1030. package/dist/utils/image-resize-core.js.map +1 -0
  1031. package/dist/utils/image-resize-worker.d.ts +2 -0
  1032. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  1033. package/dist/utils/image-resize-worker.js +32 -0
  1034. package/dist/utils/image-resize-worker.js.map +1 -0
  1035. package/dist/utils/image-resize.d.ts +16 -0
  1036. package/dist/utils/image-resize.d.ts.map +1 -0
  1037. package/dist/utils/image-resize.js +96 -0
  1038. package/dist/utils/image-resize.js.map +1 -0
  1039. package/dist/utils/json.d.ts +3 -0
  1040. package/dist/utils/json.d.ts.map +1 -0
  1041. package/dist/utils/json.js +7 -0
  1042. package/dist/utils/json.js.map +1 -0
  1043. package/dist/utils/management-http.d.ts +25 -0
  1044. package/dist/utils/management-http.d.ts.map +1 -0
  1045. package/dist/utils/management-http.js +54 -0
  1046. package/dist/utils/management-http.js.map +1 -0
  1047. package/dist/utils/mime.d.ts +3 -0
  1048. package/dist/utils/mime.d.ts.map +1 -0
  1049. package/dist/utils/mime.js +110 -0
  1050. package/dist/utils/mime.js.map +1 -0
  1051. package/dist/utils/open-browser.d.ts +9 -0
  1052. package/dist/utils/open-browser.d.ts.map +1 -0
  1053. package/dist/utils/open-browser.js +22 -0
  1054. package/dist/utils/open-browser.js.map +1 -0
  1055. package/dist/utils/output-files.d.ts +15 -0
  1056. package/dist/utils/output-files.d.ts.map +1 -0
  1057. package/dist/utils/output-files.js +30 -0
  1058. package/dist/utils/output-files.js.map +1 -0
  1059. package/dist/utils/paths.d.ts +34 -0
  1060. package/dist/utils/paths.d.ts.map +1 -0
  1061. package/dist/utils/paths.js +115 -0
  1062. package/dist/utils/paths.js.map +1 -0
  1063. package/dist/utils/photon.d.ts +21 -0
  1064. package/dist/utils/photon.d.ts.map +1 -0
  1065. package/dist/utils/photon.js +121 -0
  1066. package/dist/utils/photon.js.map +1 -0
  1067. package/dist/utils/pi-user-agent.d.ts +3 -0
  1068. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  1069. package/dist/utils/pi-user-agent.js +6 -0
  1070. package/dist/utils/pi-user-agent.js.map +1 -0
  1071. package/dist/utils/shell.d.ts +32 -0
  1072. package/dist/utils/shell.d.ts.map +1 -0
  1073. package/dist/utils/shell.js +235 -0
  1074. package/dist/utils/shell.js.map +1 -0
  1075. package/dist/utils/sleep.d.ts +5 -0
  1076. package/dist/utils/sleep.d.ts.map +1 -0
  1077. package/dist/utils/sleep.js +17 -0
  1078. package/dist/utils/sleep.js.map +1 -0
  1079. package/dist/utils/syntax-highlight.d.ts +13 -0
  1080. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  1081. package/dist/utils/syntax-highlight.js +184 -0
  1082. package/dist/utils/syntax-highlight.js.map +1 -0
  1083. package/dist/utils/text.d.ts +8 -0
  1084. package/dist/utils/text.d.ts.map +1 -0
  1085. package/dist/utils/text.js +9 -0
  1086. package/dist/utils/text.js.map +1 -0
  1087. package/dist/utils/tool-result-images.d.ts +21 -0
  1088. package/dist/utils/tool-result-images.d.ts.map +1 -0
  1089. package/dist/utils/tool-result-images.js +48 -0
  1090. package/dist/utils/tool-result-images.js.map +1 -0
  1091. package/dist/utils/tools-manager.d.ts +13 -0
  1092. package/dist/utils/tools-manager.d.ts.map +1 -0
  1093. package/dist/utils/tools-manager.js +339 -0
  1094. package/dist/utils/tools-manager.js.map +1 -0
  1095. package/dist/utils/version-check.d.ts +55 -0
  1096. package/dist/utils/version-check.d.ts.map +1 -0
  1097. package/dist/utils/version-check.js +143 -0
  1098. package/dist/utils/version-check.js.map +1 -0
  1099. package/dist/utils/windows-self-update.d.ts +3 -0
  1100. package/dist/utils/windows-self-update.d.ts.map +1 -0
  1101. package/dist/utils/windows-self-update.js +77 -0
  1102. package/dist/utils/windows-self-update.js.map +1 -0
  1103. package/dist/utils/wsl.d.ts +3 -0
  1104. package/dist/utils/wsl.d.ts.map +1 -0
  1105. package/dist/utils/wsl.js +15 -0
  1106. package/dist/utils/wsl.js.map +1 -0
  1107. package/dist/utils/zip.d.ts +7 -0
  1108. package/dist/utils/zip.d.ts.map +1 -0
  1109. package/dist/utils/zip.js +60 -0
  1110. package/dist/utils/zip.js.map +1 -0
  1111. package/docs/cli-integration.md +106 -0
  1112. package/docs/cli.md +333 -0
  1113. package/docs/codemode.md +230 -0
  1114. package/docs/compaction.md +463 -0
  1115. package/docs/configuration.md +47 -0
  1116. package/docs/containerization.md +183 -0
  1117. package/docs/custom-provider.md +227 -0
  1118. package/docs/docs.json +220 -0
  1119. package/docs/environment-variables.md +102 -0
  1120. package/docs/extensions.md +3333 -0
  1121. package/docs/how-pi-works.md +49 -0
  1122. package/docs/images/doom-extension.png +0 -0
  1123. package/docs/images/exy.png +0 -0
  1124. package/docs/images/interactive-mode.png +0 -0
  1125. package/docs/images/tree-view.png +0 -0
  1126. package/docs/index.md +39 -0
  1127. package/docs/json.md +226 -0
  1128. package/docs/keybindings.md +195 -0
  1129. package/docs/llama-cpp.md +132 -0
  1130. package/docs/mcp.md +272 -0
  1131. package/docs/message-types.md +279 -0
  1132. package/docs/models-configuration.md +196 -0
  1133. package/docs/models.md +225 -0
  1134. package/docs/nvidia-rtx-llama-cpp.md +96 -0
  1135. package/docs/packages.md +151 -0
  1136. package/docs/prompt-templates.md +59 -0
  1137. package/docs/providers.md +247 -0
  1138. package/docs/quickstart.md +140 -0
  1139. package/docs/rpc-commands.md +860 -0
  1140. package/docs/rpc-extension-ui.md +200 -0
  1141. package/docs/rpc.md +193 -0
  1142. package/docs/sdk.md +147 -0
  1143. package/docs/security.md +99 -0
  1144. package/docs/session-format.md +293 -0
  1145. package/docs/sessions.md +66 -0
  1146. package/docs/settings.md +172 -0
  1147. package/docs/shell-aliases.md +93 -0
  1148. package/docs/skills.md +93 -0
  1149. package/docs/slash-commands.md +61 -0
  1150. package/docs/terminal-setup.md +233 -0
  1151. package/docs/termux.md +117 -0
  1152. package/docs/themes.md +138 -0
  1153. package/docs/tmux.md +55 -0
  1154. package/docs/tui.md +197 -0
  1155. package/docs/usage.md +94 -0
  1156. package/docs/virtual-models.md +114 -0
  1157. package/docs/windows.md +81 -0
  1158. package/examples/README.md +36 -0
  1159. package/examples/extensions/README.md +214 -0
  1160. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  1161. package/examples/extensions/bash-spawn-hook.ts +30 -0
  1162. package/examples/extensions/bookmark.ts +50 -0
  1163. package/examples/extensions/border-status-editor.ts +150 -0
  1164. package/examples/extensions/built-in-tool-renderer.ts +225 -0
  1165. package/examples/extensions/claude-rules.ts +86 -0
  1166. package/examples/extensions/commands.ts +72 -0
  1167. package/examples/extensions/confirm-destructive.ts +59 -0
  1168. package/examples/extensions/custom-compaction.ts +117 -0
  1169. package/examples/extensions/custom-footer.ts +64 -0
  1170. package/examples/extensions/custom-header.ts +73 -0
  1171. package/examples/extensions/custom-provider-anthropic/index.ts +613 -0
  1172. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  1173. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  1174. package/examples/extensions/custom-provider-gitlab-duo/index.ts +405 -0
  1175. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  1176. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  1177. package/examples/extensions/debug-provider.ts +90 -0
  1178. package/examples/extensions/dirty-repo-guard.ts +56 -0
  1179. package/examples/extensions/doom-overlay/README.md +46 -0
  1180. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  1181. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  1182. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  1183. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  1184. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  1185. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  1186. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  1187. package/examples/extensions/doom-overlay/index.ts +74 -0
  1188. package/examples/extensions/doom-overlay/wad-finder.ts +55 -0
  1189. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  1190. package/examples/extensions/dynamic-resources/dynamic.json +81 -0
  1191. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  1192. package/examples/extensions/dynamic-resources/index.ts +15 -0
  1193. package/examples/extensions/dynamic-tools.ts +74 -0
  1194. package/examples/extensions/entry-renderer.ts +41 -0
  1195. package/examples/extensions/event-bus.ts +43 -0
  1196. package/examples/extensions/file-trigger.ts +41 -0
  1197. package/examples/extensions/git-checkpoint.ts +53 -0
  1198. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  1199. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  1200. package/examples/extensions/gondolin/index.ts +531 -0
  1201. package/examples/extensions/gondolin/package-lock.json +175 -0
  1202. package/examples/extensions/gondolin/package.json +19 -0
  1203. package/examples/extensions/handoff.ts +190 -0
  1204. package/examples/extensions/hello.ts +26 -0
  1205. package/examples/extensions/hidden-thinking-label.ts +53 -0
  1206. package/examples/extensions/inline-bash.ts +94 -0
  1207. package/examples/extensions/input-transform-streaming.ts +39 -0
  1208. package/examples/extensions/input-transform.ts +43 -0
  1209. package/examples/extensions/interactive-shell.ts +196 -0
  1210. package/examples/extensions/jev-router.ts +113 -0
  1211. package/examples/extensions/mac-system-theme.ts +47 -0
  1212. package/examples/extensions/message-renderer.ts +59 -0
  1213. package/examples/extensions/minimal-mode.ts +353 -0
  1214. package/examples/extensions/modal-editor.ts +85 -0
  1215. package/examples/extensions/model-status.ts +31 -0
  1216. package/examples/extensions/notify.ts +57 -0
  1217. package/examples/extensions/overlay-qa-tests.ts +1450 -0
  1218. package/examples/extensions/overlay-test.ts +153 -0
  1219. package/examples/extensions/permission-gate.ts +34 -0
  1220. package/examples/extensions/pirate.ts +47 -0
  1221. package/examples/extensions/plan-mode/README.md +66 -0
  1222. package/examples/extensions/plan-mode/index.ts +394 -0
  1223. package/examples/extensions/plan-mode/utils.ts +168 -0
  1224. package/examples/extensions/preset.ts +438 -0
  1225. package/examples/extensions/project-trust.ts +64 -0
  1226. package/examples/extensions/prompt-customizer.ts +49 -0
  1227. package/examples/extensions/protected-paths.ts +30 -0
  1228. package/examples/extensions/provider-payload.ts +18 -0
  1229. package/examples/extensions/qna.ts +118 -0
  1230. package/examples/extensions/question.ts +286 -0
  1231. package/examples/extensions/questionnaire.ts +448 -0
  1232. package/examples/extensions/rainbow-editor.ts +88 -0
  1233. package/examples/extensions/reload-runtime.ts +49 -0
  1234. package/examples/extensions/rpc-demo.ts +118 -0
  1235. package/examples/extensions/sandbox/index.ts +321 -0
  1236. package/examples/extensions/sandbox/package-lock.json +92 -0
  1237. package/examples/extensions/sandbox/package.json +19 -0
  1238. package/examples/extensions/send-user-message.ts +97 -0
  1239. package/examples/extensions/session-name.ts +27 -0
  1240. package/examples/extensions/shutdown-command.ts +63 -0
  1241. package/examples/extensions/snake.ts +343 -0
  1242. package/examples/extensions/space-invaders.ts +560 -0
  1243. package/examples/extensions/ssh.ts +220 -0
  1244. package/examples/extensions/status-line.ts +32 -0
  1245. package/examples/extensions/structured-output.ts +65 -0
  1246. package/examples/extensions/subagent/README.md +177 -0
  1247. package/examples/extensions/subagent/agents/planner.md +37 -0
  1248. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  1249. package/examples/extensions/subagent/agents/scout.md +50 -0
  1250. package/examples/extensions/subagent/agents/worker.md +24 -0
  1251. package/examples/extensions/subagent/agents.ts +157 -0
  1252. package/examples/extensions/subagent/index.ts +1036 -0
  1253. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  1254. package/examples/extensions/subagent/prompts/implement.md +10 -0
  1255. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  1256. package/examples/extensions/summarize.ts +199 -0
  1257. package/examples/extensions/system-prompt-header.ts +17 -0
  1258. package/examples/extensions/tic-tac-toe.ts +1008 -0
  1259. package/examples/extensions/timed-confirm.ts +70 -0
  1260. package/examples/extensions/titlebar-spinner.ts +58 -0
  1261. package/examples/extensions/todo.ts +304 -0
  1262. package/examples/extensions/tool-override.ts +144 -0
  1263. package/examples/extensions/tools.ts +148 -0
  1264. package/examples/extensions/trigger-compact.ts +50 -0
  1265. package/examples/extensions/truncated-tool.ts +195 -0
  1266. package/examples/extensions/widget-placement.ts +9 -0
  1267. package/examples/extensions/with-deps/index.ts +32 -0
  1268. package/examples/extensions/with-deps/package-lock.json +31 -0
  1269. package/examples/extensions/with-deps/package.json +22 -0
  1270. package/examples/extensions/working-indicator.ts +123 -0
  1271. package/examples/extensions/working-message-test.ts +25 -0
  1272. package/examples/rpc-client.ts +35 -0
  1273. package/examples/rpc-extension-ui.ts +661 -0
  1274. package/examples/sdk/01-minimal.ts +26 -0
  1275. package/examples/sdk/02-custom-model.ts +49 -0
  1276. package/examples/sdk/03-custom-prompt.ts +75 -0
  1277. package/examples/sdk/04-skills.ts +55 -0
  1278. package/examples/sdk/05-tools.ts +48 -0
  1279. package/examples/sdk/06-extensions.ts +99 -0
  1280. package/examples/sdk/07-context-files.ts +47 -0
  1281. package/examples/sdk/08-prompt-templates.ts +51 -0
  1282. package/examples/sdk/09-api-keys-and-oauth.ts +34 -0
  1283. package/examples/sdk/10-settings.ts +53 -0
  1284. package/examples/sdk/11-sessions.ts +52 -0
  1285. package/examples/sdk/12-full-control.ts +74 -0
  1286. package/examples/sdk/13-session-runtime.ts +67 -0
  1287. package/examples/sdk/14-codemode-mcp.ts +61 -0
  1288. package/examples/sdk/README.md +141 -0
  1289. package/package.json +94 -5
  1290. package/schemas/keybindings.schema.json +397 -0
  1291. package/schemas/models.schema.json +1211 -0
  1292. package/schemas/settings.schema.json +792 -0
  1293. package/schemas/theme.schema.json +365 -0
@@ -0,0 +1,2044 @@
1
+ (function() {
2
+ 'use strict';
3
+
4
+ // ============================================================
5
+ // DATA LOADING
6
+ // ============================================================
7
+
8
+ const base64 = document.getElementById('session-data').textContent;
9
+ const binary = atob(base64);
10
+ const bytes = new Uint8Array(binary.length);
11
+ for (let i = 0; i < binary.length; i++) {
12
+ bytes[i] = binary.charCodeAt(i);
13
+ }
14
+ const data = JSON.parse(new TextDecoder('utf-8').decode(bytes));
15
+ const { header, entries, leafId: defaultLeafId, systemPrompt, tools, renderedTools } = data;
16
+
17
+ // ============================================================
18
+ // URL PARAMETER HANDLING
19
+ // ============================================================
20
+
21
+ // Parse URL parameters for deep linking: leafId and targetId
22
+ // Check for injected params (when loaded in iframe via srcdoc) or use window.location
23
+ const injectedParams = document.querySelector('meta[name="pi-url-params"]');
24
+ const searchString = injectedParams ? injectedParams.content : window.location.search.substring(1);
25
+ const urlParams = new URLSearchParams(searchString);
26
+ const urlLeafId = urlParams.get('leafId');
27
+ const urlTargetId = urlParams.get('targetId');
28
+ // Use URL leafId if provided, otherwise fall back to session default
29
+ const leafId = urlLeafId || defaultLeafId;
30
+
31
+ // ============================================================
32
+ // DATA STRUCTURES
33
+ // ============================================================
34
+
35
+ // Entry lookup by ID
36
+ const byId = new Map();
37
+ for (const entry of entries) {
38
+ byId.set(entry.id, entry);
39
+ }
40
+
41
+ // Tool call lookup (toolCallId -> {name, arguments})
42
+ const toolCallMap = new Map();
43
+ for (const entry of entries) {
44
+ if (entry.type === 'message' && entry.message.role === 'assistant') {
45
+ const content = entry.message.content;
46
+ if (Array.isArray(content)) {
47
+ for (const block of content) {
48
+ if (block.type === 'toolCall') {
49
+ toolCallMap.set(block.id, { name: block.name, arguments: block.arguments });
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ // Label lookup (entryId -> label string)
57
+ // Labels are stored in 'label' entries that reference their target via targetId
58
+ const labelMap = new Map();
59
+ for (const entry of entries) {
60
+ if (entry.type === 'label' && entry.targetId && entry.label) {
61
+ labelMap.set(entry.targetId, entry.label);
62
+ }
63
+ }
64
+
65
+ // ============================================================
66
+ // TREE DATA PREPARATION (no DOM, pure data)
67
+ // ============================================================
68
+
69
+ /**
70
+ * Build tree structure from flat entries.
71
+ * Returns array of root nodes, each with { entry, children, label }.
72
+ */
73
+ function buildTree() {
74
+ const nodeMap = new Map();
75
+ const roots = [];
76
+
77
+ // Create nodes
78
+ for (const entry of entries) {
79
+ nodeMap.set(entry.id, {
80
+ entry,
81
+ children: [],
82
+ label: labelMap.get(entry.id)
83
+ });
84
+ }
85
+
86
+ // Build parent-child relationships
87
+ for (const entry of entries) {
88
+ const node = nodeMap.get(entry.id);
89
+ if (entry.parentId === null || entry.parentId === undefined || entry.parentId === entry.id) {
90
+ roots.push(node);
91
+ } else {
92
+ const parent = nodeMap.get(entry.parentId);
93
+ if (parent) {
94
+ parent.children.push(node);
95
+ } else {
96
+ roots.push(node);
97
+ }
98
+ }
99
+ }
100
+
101
+ // Sort children by timestamp. Iterative: long sessions form chains deeper than the JS call stack.
102
+ for (const node of nodeMap.values()) {
103
+ node.children.sort((a, b) =>
104
+ new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime()
105
+ );
106
+ }
107
+
108
+ return roots;
109
+ }
110
+
111
+ /**
112
+ * Build set of entry IDs on path from root to target.
113
+ */
114
+ function buildActivePathIds(targetId) {
115
+ const ids = new Set();
116
+ let current = byId.get(targetId);
117
+ while (current) {
118
+ ids.add(current.id);
119
+ // Stop if no parent or self-referencing (root)
120
+ if (!current.parentId || current.parentId === current.id) {
121
+ break;
122
+ }
123
+ current = byId.get(current.parentId);
124
+ }
125
+ return ids;
126
+ }
127
+
128
+ /**
129
+ * Get array of entries from root to target (the conversation path).
130
+ */
131
+ function getPath(targetId) {
132
+ const path = [];
133
+ let current = byId.get(targetId);
134
+ while (current) {
135
+ path.push(current);
136
+ // Stop if no parent or self-referencing (root)
137
+ if (!current.parentId || current.parentId === current.id) {
138
+ break;
139
+ }
140
+ current = byId.get(current.parentId);
141
+ }
142
+ return path.reverse();
143
+ }
144
+
145
+ // Tree node lookup for finding leaves
146
+ let treeNodeMap = null;
147
+
148
+ /**
149
+ * Find the newest leaf node reachable from a given node.
150
+ * This allows clicking any node in a branch to show the full branch.
151
+ * Children are sorted by timestamp, so the newest is always last.
152
+ */
153
+ function findNewestLeaf(nodeId) {
154
+ // Build tree node map lazily
155
+ if (!treeNodeMap) {
156
+ treeNodeMap = new Map();
157
+ const stack = [...buildTree()];
158
+ while (stack.length > 0) {
159
+ const node = stack.pop();
160
+ treeNodeMap.set(node.entry.id, node);
161
+ for (const child of node.children) stack.push(child);
162
+ }
163
+ }
164
+
165
+ const node = treeNodeMap.get(nodeId);
166
+ if (!node) return nodeId;
167
+
168
+ // Follow the newest (last) child at each level
169
+ let current = node;
170
+ while (current.children.length > 0) {
171
+ current = current.children[current.children.length - 1];
172
+ }
173
+ return current.entry.id;
174
+ }
175
+
176
+ /**
177
+ * Flatten tree into list with indentation and connector info.
178
+ * Returns array of { node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots }.
179
+ * Matches tree-selector.ts logic exactly.
180
+ */
181
+ function flattenTree(roots, activePathIds) {
182
+ const result = [];
183
+ const multipleRoots = roots.length > 1;
184
+
185
+ // Mark which subtrees contain the active leaf
186
+ // Iterative post-order: long sessions form chains deeper than the JS call stack.
187
+ const containsActive = new Map();
188
+ const postOrder = [];
189
+ const pending = [...roots];
190
+ while (pending.length > 0) {
191
+ const node = pending.pop();
192
+ postOrder.push(node);
193
+ for (const child of node.children) pending.push(child);
194
+ }
195
+ for (let i = postOrder.length - 1; i >= 0; i--) {
196
+ const node = postOrder[i];
197
+ containsActive.set(
198
+ node,
199
+ activePathIds.has(node.entry.id) || node.children.some(child => containsActive.get(child))
200
+ );
201
+ }
202
+
203
+ // Stack: [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
204
+ const stack = [];
205
+
206
+ // Add roots (prioritize branch containing active leaf)
207
+ const orderedRoots = [...roots].sort((a, b) =>
208
+ Number(containsActive.get(b)) - Number(containsActive.get(a))
209
+ );
210
+ for (let i = orderedRoots.length - 1; i >= 0; i--) {
211
+ const isLast = i === orderedRoots.length - 1;
212
+ stack.push([orderedRoots[i], multipleRoots ? 1 : 0, multipleRoots, multipleRoots, isLast, [], multipleRoots]);
213
+ }
214
+
215
+ while (stack.length > 0) {
216
+ const [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
217
+
218
+ result.push({ node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots });
219
+
220
+ const children = node.children;
221
+ const multipleChildren = children.length > 1;
222
+
223
+ // Order children (active branch first)
224
+ const orderedChildren = [...children].sort((a, b) =>
225
+ Number(containsActive.get(b)) - Number(containsActive.get(a))
226
+ );
227
+
228
+ // Calculate child indent (matches tree-selector.ts)
229
+ let childIndent;
230
+ if (multipleChildren) {
231
+ // Parent branches: children get +1
232
+ childIndent = indent + 1;
233
+ } else if (justBranched && indent > 0) {
234
+ // First generation after a branch: +1 for visual grouping
235
+ childIndent = indent + 1;
236
+ } else {
237
+ // Single-child chain: stay flat
238
+ childIndent = indent;
239
+ }
240
+
241
+ // Build gutters for children
242
+ const connectorDisplayed = showConnector && !isVirtualRootChild;
243
+ const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
244
+ const connectorPosition = Math.max(0, currentDisplayIndent - 1);
245
+ const childGutters = connectorDisplayed
246
+ ? [...gutters, { position: connectorPosition, show: !isLast }]
247
+ : gutters;
248
+
249
+ // Add children in reverse order for stack
250
+ for (let i = orderedChildren.length - 1; i >= 0; i--) {
251
+ const childIsLast = i === orderedChildren.length - 1;
252
+ stack.push([orderedChildren[i], childIndent, multipleChildren, multipleChildren, childIsLast, childGutters, false]);
253
+ }
254
+ }
255
+
256
+ return result;
257
+ }
258
+
259
+ /**
260
+ * Build ASCII prefix string for tree node.
261
+ */
262
+ function buildTreePrefix(flatNode) {
263
+ const { indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots } = flatNode;
264
+ const displayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
265
+ const connector = showConnector && !isVirtualRootChild ? (isLast ? '└─ ' : '├─ ') : '';
266
+ const connectorPosition = connector ? displayIndent - 1 : -1;
267
+
268
+ const totalChars = displayIndent * 3;
269
+ const prefixChars = [];
270
+ for (let i = 0; i < totalChars; i++) {
271
+ const level = Math.floor(i / 3);
272
+ const posInLevel = i % 3;
273
+
274
+ const gutter = gutters.find(g => g.position === level);
275
+ if (gutter) {
276
+ prefixChars.push(posInLevel === 0 ? (gutter.show ? '│' : ' ') : ' ');
277
+ } else if (connector && level === connectorPosition) {
278
+ if (posInLevel === 0) {
279
+ prefixChars.push(isLast ? '└' : '├');
280
+ } else if (posInLevel === 1) {
281
+ prefixChars.push('─');
282
+ } else {
283
+ prefixChars.push(' ');
284
+ }
285
+ } else {
286
+ prefixChars.push(' ');
287
+ }
288
+ }
289
+ return prefixChars.join('');
290
+ }
291
+
292
+ // ============================================================
293
+ // FILTERING (pure data)
294
+ // ============================================================
295
+
296
+ let filterMode = 'default';
297
+ let searchQuery = '';
298
+
299
+ function hasTextContent(content) {
300
+ if (typeof content === 'string') return content.trim().length > 0;
301
+ if (Array.isArray(content)) {
302
+ for (const c of content) {
303
+ if (c.type === 'text' && c.text && c.text.trim().length > 0) return true;
304
+ }
305
+ }
306
+ return false;
307
+ }
308
+
309
+ function extractContent(content) {
310
+ if (typeof content === 'string') return content;
311
+ if (Array.isArray(content)) {
312
+ return content
313
+ .filter(c => c.type === 'text' && c.text)
314
+ .map(c => c.text)
315
+ .join('');
316
+ }
317
+ return '';
318
+ }
319
+
320
+ // ============================================================
321
+ // SYSTEM MESSAGES (pure data)
322
+ // ============================================================
323
+
324
+ function systemContentText(content) {
325
+ if (typeof content === 'string') return content;
326
+ if (Array.isArray(content)) {
327
+ return content.filter(c => c.type === 'text' && c.text).map(c => c.text).join('\n');
328
+ }
329
+ return '';
330
+ }
331
+
332
+ /** Full prompt text of a system message, mirroring getSystemMessageText() in pi-ai. */
333
+ function getSystemMessageText(msg) {
334
+ const parts = [systemContentText(msg.content)];
335
+ for (const value of Object.values(msg.sections || {})) {
336
+ if (value !== null) parts.push(value);
337
+ }
338
+ return parts.filter(part => part.length > 0).join('\n\n');
339
+ }
340
+
341
+ /** Text of a later system message, mirroring renderSystemMessageUpdate() in pi-ai. */
342
+ function renderSystemMessageUpdate(msg) {
343
+ const parts = [];
344
+ const text = systemContentText(msg.content);
345
+ if (text.length > 0) parts.push(text);
346
+ for (const [name, value] of Object.entries(msg.sections || {})) {
347
+ parts.push(value === null
348
+ ? `Removed system prompt section "${name}".`
349
+ : `Updated system prompt section "${name}":\n\n${value}`);
350
+ }
351
+ return parts.join('\n\n');
352
+ }
353
+
354
+ function carriesSystemState(entry) {
355
+ return (entry.type === 'message' && entry.message.role === 'system') ||
356
+ (entry.type === 'compaction' && entry.systemMessage);
357
+ }
358
+
359
+ /**
360
+ * Whether a system entry starts the prompt on its branch. Later system entries
361
+ * patch the prompt, so they render as updates instead of a full prompt.
362
+ */
363
+ function isLeadingSystemEntry(entry) {
364
+ let current = entry.parentId && entry.parentId !== entry.id ? byId.get(entry.parentId) : undefined;
365
+ while (current) {
366
+ if (carriesSystemState(current)) return false;
367
+ if (!current.parentId || current.parentId === current.id) break;
368
+ current = byId.get(current.parentId);
369
+ }
370
+ return true;
371
+ }
372
+
373
+ /** Short description of what a later system message changes, e.g. "project_context, -rules, tools +bash". */
374
+ function describeSystemUpdate(msg) {
375
+ const parts = [];
376
+ if (systemContentText(msg.content).length > 0) parts.push('instructions');
377
+ for (const [name, value] of Object.entries(msg.sections || {})) {
378
+ parts.push(value === null ? `-${name}` : name);
379
+ }
380
+ const toolChanges = [
381
+ ...(msg.toolsAdded || []).map(t => `+${t.name}`),
382
+ ...(msg.toolsRemoved || []).map(t => `-${t.name}`),
383
+ ];
384
+ if (toolChanges.length > 0) parts.push(`tools ${toolChanges.join(' ')}`);
385
+ return parts.join(', ');
386
+ }
387
+
388
+ const hasSystemEntries = entries.some(entry => entry.type === 'message' && entry.message.role === 'system');
389
+
390
+ /**
391
+ * Parse a skill block from message text.
392
+ * Returns null if the text doesn't contain a skill block.
393
+ * Matches the format: <skill name="..." location="...">\n...\n</skill>\n\nuser message
394
+ */
395
+ function parseSkillBlock(text) {
396
+ const match = text.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);
397
+ if (!match) return null;
398
+ return {
399
+ name: match[1],
400
+ location: match[2],
401
+ content: match[3],
402
+ userMessage: match[4]?.trim() || undefined,
403
+ };
404
+ }
405
+
406
+ function getSearchableText(entry, label) {
407
+ const parts = [];
408
+ if (label) parts.push(label);
409
+
410
+ switch (entry.type) {
411
+ case 'message': {
412
+ const msg = entry.message;
413
+ parts.push(msg.role);
414
+ if (msg.role === 'system') {
415
+ parts.push(isLeadingSystemEntry(entry) ? 'system prompt' : 'system update');
416
+ parts.push(getSystemMessageText(msg));
417
+ for (const name of Object.keys(msg.sections || {})) parts.push(name);
418
+ for (const tool of [...(msg.toolsAdded || []), ...(msg.toolsRemoved || [])]) parts.push(tool.name);
419
+ break;
420
+ }
421
+ if (msg.content) parts.push(extractContent(msg.content));
422
+ if (msg.role === 'bashExecution' && msg.command) parts.push(msg.command);
423
+ break;
424
+ }
425
+ case 'custom_message':
426
+ parts.push(entry.customType);
427
+ parts.push(typeof entry.content === 'string' ? entry.content : extractContent(entry.content));
428
+ break;
429
+ case 'compaction':
430
+ parts.push('compaction');
431
+ break;
432
+ case 'branch_summary':
433
+ parts.push('branch summary', entry.summary);
434
+ break;
435
+ case 'model_change':
436
+ parts.push('model', entry.modelId);
437
+ break;
438
+ case 'thinking_level_change':
439
+ parts.push('thinking', entry.thinkingLevel);
440
+ break;
441
+ case 'context_edit':
442
+ parts.push('context edit', entry.replacement === null ? 'omit' : 'replace', entry.targetId);
443
+ break;
444
+ }
445
+
446
+ return parts.join(' ').toLowerCase();
447
+ }
448
+
449
+ /**
450
+ * Filter flat nodes based on current filterMode and searchQuery.
451
+ */
452
+ function filterNodes(flatNodes, currentLeafId) {
453
+ const searchTokens = searchQuery.toLowerCase().split(/\s+/).filter(Boolean);
454
+
455
+ const filtered = flatNodes.filter(flatNode => {
456
+ const entry = flatNode.node.entry;
457
+ const label = flatNode.node.label;
458
+ const isCurrentLeaf = entry.id === currentLeafId;
459
+
460
+ // Always show current leaf
461
+ if (isCurrentLeaf) return true;
462
+
463
+ // Hide assistant messages with only tool calls (no text) unless error/aborted
464
+ if (entry.type === 'message' && entry.message.role === 'assistant') {
465
+ const msg = entry.message;
466
+ const hasText = hasTextContent(msg.content);
467
+ const isErrorOrAborted = msg.stopReason && msg.stopReason !== 'stop' && msg.stopReason !== 'toolUse';
468
+ if (!hasText && !isErrorOrAborted) return false;
469
+ }
470
+
471
+ // Apply filter mode
472
+ const isSettingsEntry = ['label', 'custom', 'context_edit', 'model_change', 'thinking_level_change'].includes(entry.type);
473
+ let passesFilter = true;
474
+
475
+ switch (filterMode) {
476
+ case 'user-only':
477
+ passesFilter = entry.type === 'message' && entry.message.role === 'user';
478
+ break;
479
+ case 'no-tools':
480
+ passesFilter = !isSettingsEntry && !(entry.type === 'message' && entry.message.role === 'toolResult');
481
+ break;
482
+ case 'labeled-only':
483
+ passesFilter = label !== undefined;
484
+ break;
485
+ case 'all':
486
+ passesFilter = true;
487
+ break;
488
+ default: // 'default'
489
+ passesFilter = !isSettingsEntry;
490
+ break;
491
+ }
492
+
493
+ if (!passesFilter) return false;
494
+
495
+ // Apply search filter
496
+ if (searchTokens.length > 0) {
497
+ const nodeText = getSearchableText(entry, label);
498
+ if (!searchTokens.every(t => nodeText.includes(t))) return false;
499
+ }
500
+
501
+ return true;
502
+ });
503
+
504
+ // Recalculate visual structure based on visible tree
505
+ recalculateVisualStructure(filtered, flatNodes);
506
+
507
+ return filtered;
508
+ }
509
+
510
+ /**
511
+ * Recompute indentation/connectors for the filtered view
512
+ *
513
+ * Filtering can hide intermediate entries; descendants attach to the nearest visible ancestor.
514
+ * Keep indentation semantics aligned with flattenTree() so single-child chains don't drift right.
515
+ */
516
+ function recalculateVisualStructure(filteredNodes, allFlatNodes) {
517
+ if (filteredNodes.length === 0) return;
518
+
519
+ const visibleIds = new Set(filteredNodes.map(n => n.node.entry.id));
520
+
521
+ // Build entry map for parent lookup (using full tree)
522
+ const entryMap = new Map();
523
+ for (const flatNode of allFlatNodes) {
524
+ entryMap.set(flatNode.node.entry.id, flatNode);
525
+ }
526
+
527
+ // Find nearest visible ancestor for a node
528
+ function findVisibleAncestor(nodeId) {
529
+ let currentId = entryMap.get(nodeId)?.node.entry.parentId;
530
+ while (currentId != null) {
531
+ if (visibleIds.has(currentId)) {
532
+ return currentId;
533
+ }
534
+ currentId = entryMap.get(currentId)?.node.entry.parentId;
535
+ }
536
+ return null;
537
+ }
538
+
539
+ // Build visible tree structure
540
+ const visibleParent = new Map();
541
+ const visibleChildren = new Map();
542
+ visibleChildren.set(null, []); // root-level nodes
543
+
544
+ for (const flatNode of filteredNodes) {
545
+ const nodeId = flatNode.node.entry.id;
546
+ const ancestorId = findVisibleAncestor(nodeId);
547
+ visibleParent.set(nodeId, ancestorId);
548
+
549
+ if (!visibleChildren.has(ancestorId)) {
550
+ visibleChildren.set(ancestorId, []);
551
+ }
552
+ visibleChildren.get(ancestorId).push(nodeId);
553
+ }
554
+
555
+ // Update multipleRoots based on visible roots
556
+ const visibleRootIds = visibleChildren.get(null);
557
+ const multipleRoots = visibleRootIds.length > 1;
558
+
559
+ // Build a map for quick lookup: nodeId → FlatNode
560
+ const filteredNodeMap = new Map();
561
+ for (const flatNode of filteredNodes) {
562
+ filteredNodeMap.set(flatNode.node.entry.id, flatNode);
563
+ }
564
+
565
+ // DFS traversal of visible tree, applying same indentation rules as flattenTree()
566
+ // Stack items: [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
567
+ const stack = [];
568
+
569
+ // Add visible roots in reverse order (to process in forward order via stack)
570
+ for (let i = visibleRootIds.length - 1; i >= 0; i--) {
571
+ const isLast = i === visibleRootIds.length - 1;
572
+ stack.push([
573
+ visibleRootIds[i],
574
+ multipleRoots ? 1 : 0,
575
+ multipleRoots,
576
+ multipleRoots,
577
+ isLast,
578
+ [],
579
+ multipleRoots
580
+ ]);
581
+ }
582
+
583
+ while (stack.length > 0) {
584
+ const [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
585
+
586
+ const flatNode = filteredNodeMap.get(nodeId);
587
+ if (!flatNode) continue;
588
+
589
+ // Update this node's visual properties
590
+ flatNode.indent = indent;
591
+ flatNode.showConnector = showConnector;
592
+ flatNode.isLast = isLast;
593
+ flatNode.gutters = gutters;
594
+ flatNode.isVirtualRootChild = isVirtualRootChild;
595
+ flatNode.multipleRoots = multipleRoots;
596
+
597
+ // Get visible children of this node
598
+ const children = visibleChildren.get(nodeId) || [];
599
+ const multipleChildren = children.length > 1;
600
+
601
+ // Calculate child indent using same rules as flattenTree():
602
+ // - Parent branches (multiple children): children get +1
603
+ // - Just branched and indent > 0: children get +1 for visual grouping
604
+ // - Single-child chain: stay flat
605
+ let childIndent;
606
+ if (multipleChildren) {
607
+ childIndent = indent + 1;
608
+ } else if (justBranched && indent > 0) {
609
+ childIndent = indent + 1;
610
+ } else {
611
+ childIndent = indent;
612
+ }
613
+
614
+ // Build gutters for children (same logic as flattenTree)
615
+ const connectorDisplayed = showConnector && !isVirtualRootChild;
616
+ const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
617
+ const connectorPosition = Math.max(0, currentDisplayIndent - 1);
618
+ const childGutters = connectorDisplayed
619
+ ? [...gutters, { position: connectorPosition, show: !isLast }]
620
+ : gutters;
621
+
622
+ // Add children in reverse order (to process in forward order via stack)
623
+ for (let i = children.length - 1; i >= 0; i--) {
624
+ const childIsLast = i === children.length - 1;
625
+ stack.push([
626
+ children[i],
627
+ childIndent,
628
+ multipleChildren,
629
+ multipleChildren,
630
+ childIsLast,
631
+ childGutters,
632
+ false
633
+ ]);
634
+ }
635
+ }
636
+ }
637
+
638
+ // ============================================================
639
+ // TREE DISPLAY TEXT (pure data -> string)
640
+ // ============================================================
641
+
642
+ function shortenPath(p) {
643
+ if (typeof p !== 'string') return '';
644
+ if (p.startsWith('/Users/')) {
645
+ const parts = p.split('/');
646
+ if (parts.length > 2) return '~' + p.slice(('/Users/' + parts[2]).length);
647
+ }
648
+ if (p.startsWith('/home/')) {
649
+ const parts = p.split('/');
650
+ if (parts.length > 2) return '~' + p.slice(('/home/' + parts[2]).length);
651
+ }
652
+ return p;
653
+ }
654
+
655
+ function formatToolCall(name, args) {
656
+ switch (name) {
657
+ case 'read': {
658
+ const path = shortenPath(String(args.path || args.file_path || ''));
659
+ return `[read: ${path}${formatReadLineRange(args.offset, args.limit)}]`;
660
+ }
661
+ case 'write':
662
+ return `[write: ${shortenPath(String(args.path || args.file_path || ''))}]`;
663
+ case 'edit':
664
+ return `[edit: ${shortenPath(String(args.path || args.file_path || ''))}]`;
665
+ case 'bash': {
666
+ const rawCmd = String(args.command || '');
667
+ const cmd = rawCmd.replace(/[\n\t]/g, ' ').trim().slice(0, 50);
668
+ return `[bash: ${cmd}${rawCmd.length > 50 ? '...' : ''}]`;
669
+ }
670
+ case 'grep':
671
+ return `[grep: /${args.pattern || ''}/ in ${shortenPath(String(args.path || '.'))}]`;
672
+ case 'find':
673
+ return `[find: ${args.pattern || ''} in ${shortenPath(String(args.path || '.'))}]`;
674
+ case 'ls':
675
+ return `[ls: ${shortenPath(String(args.path || '.'))}]`;
676
+ default: {
677
+ const argsStr = JSON.stringify(args).slice(0, 40);
678
+ return `[${name}: ${argsStr}${JSON.stringify(args).length > 40 ? '...' : ''}]`;
679
+ }
680
+ }
681
+ }
682
+
683
+ function escapeHtml(text) {
684
+ return String(text)
685
+ .replace(/&/g, '&amp;')
686
+ .replace(/</g, '&lt;')
687
+ .replace(/>/g, '&gt;')
688
+ .replace(/"/g, '&quot;')
689
+ .replace(/'/g, '&#39;');
690
+ }
691
+
692
+ function sanitizeMarkdownUrl(value) {
693
+ const href = String(value || '').trim().replace(/[\x00-\x1f\x7f]/g, '');
694
+ if (!href) return href;
695
+
696
+ const scheme = href.match(/^([A-Za-z][A-Za-z0-9+.-]*):/);
697
+ if (scheme && !/^(https?|mailto|tel|ftp)$/i.test(scheme[1])) {
698
+ return null;
699
+ }
700
+
701
+ return href;
702
+ }
703
+
704
+ /**
705
+ * Truncate string to maxLen chars, append "..." if truncated.
706
+ */
707
+ function truncate(s, maxLen = 100) {
708
+ if (s.length <= maxLen) return s;
709
+ return s.slice(0, maxLen) + '...';
710
+ }
711
+
712
+ /**
713
+ * Get display text for tree node (returns HTML string).
714
+ */
715
+ function getTreeNodeDisplayHtml(entry, label) {
716
+ const normalize = s => s.replace(/[\n\t]/g, ' ').trim();
717
+ const labelHtml = label ? `<span class="tree-label">[${escapeHtml(label)}]</span> ` : '';
718
+
719
+ switch (entry.type) {
720
+ case 'message': {
721
+ const msg = entry.message;
722
+ if (msg.role === 'user') {
723
+ const rawContent = extractContent(msg.content);
724
+ const skillBlock = parseSkillBlock(rawContent);
725
+ if (skillBlock) {
726
+ let treeHtml = labelHtml + `<span class="tree-role-skill">skill:</span> ${escapeHtml(skillBlock.name)}`;
727
+ if (skillBlock.userMessage) {
728
+ treeHtml += ` · <span class="tree-role-user">user:</span> ${escapeHtml(truncate(normalize(skillBlock.userMessage)))}`;
729
+ }
730
+ return treeHtml;
731
+ }
732
+ const content = truncate(normalize(rawContent));
733
+ return labelHtml + `<span class="tree-role-user">user:</span> ${escapeHtml(content)}`;
734
+ }
735
+ if (msg.role === 'assistant') {
736
+ const textContent = truncate(normalize(extractContent(msg.content)));
737
+ if (textContent) {
738
+ return labelHtml + `<span class="tree-role-assistant">assistant:</span> ${escapeHtml(textContent)}`;
739
+ }
740
+ if (msg.stopReason === 'aborted') {
741
+ return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(aborted)</span>`;
742
+ }
743
+ if (msg.errorMessage) {
744
+ return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-error">${escapeHtml(truncate(msg.errorMessage))}</span>`;
745
+ }
746
+ return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(no text)</span>`;
747
+ }
748
+ if (msg.role === 'toolResult') {
749
+ const toolCall = msg.toolCallId ? toolCallMap.get(msg.toolCallId) : null;
750
+ if (toolCall) {
751
+ return labelHtml + `<span class="tree-role-tool">${escapeHtml(formatToolCall(toolCall.name, toolCall.arguments))}</span>`;
752
+ }
753
+ return labelHtml + `<span class="tree-role-tool">[${escapeHtml(msg.toolName || 'tool')}]</span>`;
754
+ }
755
+ if (msg.role === 'bashExecution') {
756
+ const cmd = truncate(normalize(msg.command || ''));
757
+ return labelHtml + `<span class="tree-role-tool">[bash]:</span> ${escapeHtml(cmd)}`;
758
+ }
759
+ if (msg.role === 'system') {
760
+ if (isLeadingSystemEntry(entry)) {
761
+ return labelHtml + `<span class="tree-muted">[system prompt]</span>`;
762
+ }
763
+ const changes = describeSystemUpdate(msg);
764
+ return labelHtml + `<span class="tree-muted">[system update${changes ? ': ' + escapeHtml(truncate(changes)) : ''}]</span>`;
765
+ }
766
+ return labelHtml + `<span class="tree-muted">[${escapeHtml(msg.role)}]</span>`;
767
+ }
768
+ case 'compaction':
769
+ return labelHtml + `<span class="tree-compaction">[compaction: ${Math.round(entry.tokensBefore/1000)}k tokens]</span>`;
770
+ case 'branch_summary': {
771
+ const summary = truncate(normalize(entry.summary || ''));
772
+ return labelHtml + `<span class="tree-branch-summary">[branch summary]:</span> ${escapeHtml(summary)}`;
773
+ }
774
+ case 'custom_message': {
775
+ const content = typeof entry.content === 'string' ? entry.content : extractContent(entry.content);
776
+ return labelHtml + `<span class="tree-custom">[${escapeHtml(entry.customType)}]:</span> ${escapeHtml(truncate(normalize(content)))}`;
777
+ }
778
+ case 'model_change':
779
+ return labelHtml + `<span class="tree-muted">[model: ${escapeHtml(entry.modelId)}]</span>`;
780
+ case 'thinking_level_change':
781
+ return labelHtml + `<span class="tree-muted">[thinking: ${escapeHtml(entry.thinkingLevel)}]</span>`;
782
+ case 'context_edit':
783
+ return labelHtml + `<span class="tree-muted">[context ${entry.replacement === null ? 'omit' : 'replace'}: ${escapeHtml(entry.targetId)}]</span>`;
784
+ default:
785
+ return labelHtml + `<span class="tree-muted">[${escapeHtml(entry.type)}]</span>`;
786
+ }
787
+ }
788
+
789
+ // ============================================================
790
+ // TREE RENDERING (DOM manipulation)
791
+ // ============================================================
792
+
793
+ let currentLeafId = leafId;
794
+ let currentTargetId = urlTargetId || leafId;
795
+ let treeRendered = false;
796
+
797
+ function renderTree() {
798
+ const tree = buildTree();
799
+ const activePathIds = buildActivePathIds(currentLeafId);
800
+ const flatNodes = flattenTree(tree, activePathIds);
801
+ const filtered = filterNodes(flatNodes, currentLeafId);
802
+ const container = document.getElementById('tree-container');
803
+
804
+ // Full render only on first call or when filter/search changes
805
+ if (!treeRendered) {
806
+ container.innerHTML = '';
807
+
808
+ for (const flatNode of filtered) {
809
+ const entry = flatNode.node.entry;
810
+ const isOnPath = activePathIds.has(entry.id);
811
+ const isTarget = entry.id === currentTargetId;
812
+
813
+ const div = document.createElement('div');
814
+ div.className = 'tree-node';
815
+ if (isOnPath) div.classList.add('in-path');
816
+ if (isTarget) div.classList.add('active');
817
+ div.dataset.id = entry.id;
818
+
819
+ const prefix = buildTreePrefix(flatNode);
820
+ const prefixSpan = document.createElement('span');
821
+ prefixSpan.className = 'tree-prefix';
822
+ prefixSpan.textContent = prefix;
823
+
824
+ const marker = document.createElement('span');
825
+ marker.className = 'tree-marker';
826
+ marker.textContent = isOnPath ? '•' : ' ';
827
+
828
+ const content = document.createElement('span');
829
+ content.className = 'tree-content';
830
+ content.innerHTML = getTreeNodeDisplayHtml(entry, flatNode.node.label);
831
+
832
+ div.appendChild(prefixSpan);
833
+ div.appendChild(marker);
834
+ div.appendChild(content);
835
+ // Navigate to the newest leaf through this node, but scroll to the clicked node
836
+ div.addEventListener('click', () => {
837
+ if (window.getSelection().toString()) return;
838
+ const leafId = findNewestLeaf(entry.id);
839
+ navigateTo(leafId, 'target', entry.id);
840
+ });
841
+
842
+ container.appendChild(div);
843
+ }
844
+
845
+ treeRendered = true;
846
+ } else {
847
+ // Just update markers and classes
848
+ const nodes = container.querySelectorAll('.tree-node');
849
+ for (const node of nodes) {
850
+ const id = node.dataset.id;
851
+ const isOnPath = activePathIds.has(id);
852
+ const isTarget = id === currentTargetId;
853
+
854
+ node.classList.toggle('in-path', isOnPath);
855
+ node.classList.toggle('active', isTarget);
856
+
857
+ const marker = node.querySelector('.tree-marker');
858
+ if (marker) {
859
+ marker.textContent = isOnPath ? '•' : ' ';
860
+ }
861
+ }
862
+ }
863
+
864
+ document.getElementById('tree-status').textContent = `${filtered.length} / ${flatNodes.length} entries`;
865
+
866
+ // Scroll active node into view after layout
867
+ setTimeout(() => {
868
+ const activeNode = container.querySelector('.tree-node.active');
869
+ if (activeNode) {
870
+ activeNode.scrollIntoView({ block: 'nearest' });
871
+ }
872
+ }, 0);
873
+ }
874
+
875
+ function forceTreeRerender() {
876
+ treeRendered = false;
877
+ renderTree();
878
+ }
879
+
880
+ // ============================================================
881
+ // MESSAGE RENDERING
882
+ // ============================================================
883
+
884
+ function formatTokens(count) {
885
+ if (count < 1000) return count.toString();
886
+ if (count < 10000) return (count / 1000).toFixed(1) + 'k';
887
+ if (count < 1000000) return Math.round(count / 1000) + 'k';
888
+ return (count / 1000000).toFixed(1) + 'M';
889
+ }
890
+
891
+ function formatTimestamp(ts) {
892
+ if (!ts) return '';
893
+ const date = new Date(ts);
894
+ return date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });
895
+ }
896
+
897
+ function replaceTabs(text) {
898
+ return text.replace(/\t/g, ' ');
899
+ }
900
+
901
+ /** Safely coerce value to string for display. Returns null if invalid type. */
902
+ function str(value) {
903
+ if (typeof value === 'string') return value;
904
+ if (value == null) return '';
905
+ return null;
906
+ }
907
+
908
+ // Mirrors ../tools/render-utils.ts.
909
+ function parseLineNumber(value) {
910
+ if (typeof value === 'string' && value.trim() !== '') value = Number(value);
911
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
912
+ }
913
+
914
+ function formatReadLineRange(offset, limit) {
915
+ if (offset == null && limit == null) return '';
916
+ const start = offset == null ? 1 : parseLineNumber(offset);
917
+ if (start === undefined) return '';
918
+ if (limit == null) return `:${start}`;
919
+ const count = parseLineNumber(limit);
920
+ if (count === undefined) return '';
921
+ const end = start + count - 1;
922
+ return `:${start}${end ? `-${end}` : ''}`;
923
+ }
924
+
925
+ function getLanguageFromPath(filePath) {
926
+ const ext = filePath.split('.').pop()?.toLowerCase();
927
+ const extToLang = {
928
+ ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
929
+ py: 'python', rb: 'ruby', rs: 'rust', go: 'go', java: 'java',
930
+ c: 'c', cpp: 'cpp', h: 'c', hpp: 'cpp', cs: 'csharp',
931
+ php: 'php', sh: 'bash', bash: 'bash', zsh: 'bash',
932
+ sql: 'sql', html: 'html', css: 'css', scss: 'scss',
933
+ json: 'json', yaml: 'yaml', yml: 'yaml', xml: 'xml',
934
+ md: 'markdown', dockerfile: 'dockerfile'
935
+ };
936
+ return extToLang[ext];
937
+ }
938
+
939
+ function findToolResult(toolCallId) {
940
+ for (const entry of entries) {
941
+ if (entry.type === 'message' && entry.message.role === 'toolResult') {
942
+ if (entry.message.toolCallId === toolCallId) {
943
+ return entry.message;
944
+ }
945
+ }
946
+ }
947
+ return null;
948
+ }
949
+
950
+ function formatExpandableOutput(text, maxLines, lang) {
951
+ text = replaceTabs(text);
952
+ const lines = text.split('\n');
953
+ const displayLines = lines.slice(0, maxLines);
954
+ const remaining = lines.length - maxLines;
955
+
956
+ if (lang) {
957
+ let highlighted;
958
+ try {
959
+ highlighted = hljs.highlight(text, { language: lang }).value;
960
+ } catch {
961
+ highlighted = escapeHtml(text);
962
+ }
963
+
964
+ if (remaining > 0) {
965
+ const previewCode = displayLines.join('\n');
966
+ let previewHighlighted;
967
+ try {
968
+ previewHighlighted = hljs.highlight(previewCode, { language: lang }).value;
969
+ } catch {
970
+ previewHighlighted = escapeHtml(previewCode);
971
+ }
972
+
973
+ return `<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
974
+ <div class="output-preview"><pre><code class="hljs">${previewHighlighted}</code></pre>
975
+ <div class="expand-hint">... (${remaining} more lines)</div></div>
976
+ <div class="output-full"><pre><code class="hljs">${highlighted}</code></pre></div></div>`;
977
+ }
978
+
979
+ return `<div class="tool-output"><pre><code class="hljs">${highlighted}</code></pre></div>`;
980
+ }
981
+
982
+ // Plain text output
983
+ if (remaining > 0) {
984
+ let out = '<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle(\'expanded\')">';
985
+ out += '<div class="output-preview">';
986
+ for (const line of displayLines) {
987
+ out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
988
+ }
989
+ out += `<div class="expand-hint">... (${remaining} more lines)</div></div>`;
990
+ out += '<div class="output-full">';
991
+ for (const line of lines) {
992
+ out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
993
+ }
994
+ out += '</div></div>';
995
+ return out;
996
+ }
997
+
998
+ let out = '<div class="tool-output">';
999
+ for (const line of displayLines) {
1000
+ out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
1001
+ }
1002
+ out += '</div>';
1003
+ return out;
1004
+ }
1005
+
1006
+ function renderToolCall(call) {
1007
+ const result = findToolResult(call.id);
1008
+ const isError = result?.isError || false;
1009
+ const statusClass = result ? (isError ? 'error' : 'success') : 'pending';
1010
+
1011
+ const getResultText = () => {
1012
+ if (!result) return '';
1013
+ const textBlocks = result.content.filter(c => c.type === 'text');
1014
+ return textBlocks.map(c => c.text).join('\n');
1015
+ };
1016
+
1017
+ const getResultImages = () => {
1018
+ if (!result) return [];
1019
+ return result.content.filter(c => c.type === 'image');
1020
+ };
1021
+
1022
+ const renderResultImages = () => {
1023
+ const images = getResultImages();
1024
+ if (images.length === 0) return '';
1025
+ return '<div class="tool-images">' +
1026
+ images.map(img => `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="tool-image" />`).join('') +
1027
+ '</div>';
1028
+ };
1029
+
1030
+ // Calls this tool made to other tools (for example from a codemode script), recorded without results.
1031
+ const renderNestedCalls = () => {
1032
+ const nested = result?.nestedCalls;
1033
+ if (!nested || !Array.isArray(nested.calls) || nested.calls.length === 0) return '';
1034
+ const icons = { ok: '✓', error: '✗', unfinished: '…' };
1035
+ const lines = nested.calls.map(c => {
1036
+ const args = c.arguments ? JSON.stringify(c.arguments) : `[arguments omitted, ${c.argumentsBytes} bytes]`;
1037
+ const duration = c.durationMs !== undefined ? ` ${c.durationMs}ms` : '';
1038
+ const error = c.error ? `\n ${c.error.split('\n').join('\n ')}` : '';
1039
+ return `${icons[c.status] || '?'} ${c.name} ${args}${duration}${error}`;
1040
+ });
1041
+ const title = `Nested calls: ${nested.calls.length}${nested.complete ? '' : ' (incomplete record)'}`;
1042
+ return formatExpandableOutput([title, ...lines].join('\n'), 1);
1043
+ };
1044
+
1045
+ const toolDomId = `tool-call-${escapeHtml(call.id)}`;
1046
+ let html = `<div class="tool-execution ${statusClass}" id="${toolDomId}">`;
1047
+ const args = call.arguments || {};
1048
+ const name = call.name;
1049
+
1050
+ const invalidArg = '<span class="tool-error">[invalid arg]</span>';
1051
+
1052
+ switch (name) {
1053
+ case 'bash': {
1054
+ const command = str(args.command);
1055
+ const cmdDisplay = command === null ? invalidArg : escapeHtml(command || '...');
1056
+ html += `<div class="tool-command">$ ${cmdDisplay}</div>`;
1057
+ if (result) {
1058
+ const output = getResultText().trim();
1059
+ if (output) html += formatExpandableOutput(output, 5);
1060
+ }
1061
+ break;
1062
+ }
1063
+ case 'read': {
1064
+ const filePath = str(args.file_path ?? args.path);
1065
+ const readLineRange = formatReadLineRange(args.offset, args.limit);
1066
+ let pathHtml = filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''));
1067
+ if (filePath !== null && readLineRange) {
1068
+ pathHtml += `<span class="line-numbers">${escapeHtml(readLineRange)}</span>`;
1069
+ }
1070
+
1071
+ html += `<div class="tool-header"><span class="tool-name">read</span> <span class="tool-path">${pathHtml}</span></div>`;
1072
+ if (result) {
1073
+ html += renderResultImages();
1074
+ const output = getResultText();
1075
+ const lang = filePath ? getLanguageFromPath(filePath) : null;
1076
+ if (output) html += formatExpandableOutput(output, 10, lang);
1077
+ }
1078
+ break;
1079
+ }
1080
+ case 'write': {
1081
+ const filePath = str(args.file_path ?? args.path);
1082
+ const content = str(args.content);
1083
+
1084
+ html += `<div class="tool-header"><span class="tool-name">write</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span>`;
1085
+ if (content !== null && content) {
1086
+ const lines = content.split('\n');
1087
+ if (lines.length > 10) html += ` <span class="line-count">(${lines.length} lines)</span>`;
1088
+ }
1089
+ html += '</div>';
1090
+
1091
+ if (content === null) {
1092
+ html += `<div class="tool-error">[invalid content arg - expected string]</div>`;
1093
+ } else if (content) {
1094
+ const lang = filePath ? getLanguageFromPath(filePath) : null;
1095
+ html += formatExpandableOutput(content, 10, lang);
1096
+ }
1097
+ if (result) {
1098
+ const output = getResultText().trim();
1099
+ if (output) html += `<div class="tool-output"><div>${escapeHtml(output)}</div></div>`;
1100
+ }
1101
+ break;
1102
+ }
1103
+ case 'edit': {
1104
+ const filePath = str(args.file_path ?? args.path);
1105
+ html += `<div class="tool-header"><span class="tool-name">edit</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span></div>`;
1106
+
1107
+ if (result?.details?.diff) {
1108
+ const diffLines = result.details.diff.split('\n');
1109
+ html += '<div class="tool-diff">';
1110
+ for (const line of diffLines) {
1111
+ const cls = line.match(/^\+/) ? 'diff-added' : line.match(/^-/) ? 'diff-removed' : 'diff-context';
1112
+ html += `<div class="${cls}">${escapeHtml(replaceTabs(line))}</div>`;
1113
+ }
1114
+ html += '</div>';
1115
+ } else if (result) {
1116
+ const output = getResultText().trim();
1117
+ if (output) html += `<div class="tool-output"><pre>${escapeHtml(output)}</pre></div>`;
1118
+ }
1119
+ break;
1120
+ }
1121
+ case 'ls': {
1122
+ const dirPath = str(args.path);
1123
+ const limit = args.limit;
1124
+
1125
+ let pathHtml = dirPath === null ? invalidArg : escapeHtml(shortenPath(dirPath || '.'));
1126
+ if (limit !== undefined) {
1127
+ pathHtml += ` <span class="line-count">(limit ${escapeHtml(String(limit))})</span>`;
1128
+ }
1129
+
1130
+ html += `<div class="tool-header"><span class="tool-name">ls</span> <span class="tool-path">${pathHtml}</span></div>`;
1131
+ if (result) {
1132
+ const output = getResultText().trim();
1133
+ if (output) html += formatExpandableOutput(output, 20);
1134
+ }
1135
+ break;
1136
+ }
1137
+ default: {
1138
+ // Check for pre-rendered custom tool HTML
1139
+ const rendered = renderedTools?.[call.id];
1140
+ if (rendered?.callHtml || rendered?.resultHtmlCollapsed || rendered?.resultHtmlExpanded) {
1141
+ // Custom tool with pre-rendered HTML from TUI renderer
1142
+ if (rendered.callHtml) {
1143
+ html += `<div class="tool-header ansi-rendered">${rendered.callHtml}</div>`;
1144
+ } else {
1145
+ html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
1146
+ }
1147
+
1148
+ if (rendered.resultHtmlCollapsed && rendered.resultHtmlExpanded && rendered.resultHtmlCollapsed !== rendered.resultHtmlExpanded) {
1149
+ // Both collapsed and expanded differ - render expandable section
1150
+ html += `<div class="tool-output expandable ansi-rendered" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1151
+ <div class="output-preview">${rendered.resultHtmlCollapsed}</div>
1152
+ <div class="output-full">${rendered.resultHtmlExpanded}</div>
1153
+ </div>`;
1154
+ } else if (rendered.resultHtmlExpanded) {
1155
+ // Only expanded exists (or collapsed is identical) - show directly
1156
+ html += `<div class="tool-output ansi-rendered">${rendered.resultHtmlExpanded}</div>`;
1157
+ } else if (result) {
1158
+ // No pre-rendered result HTML - fallback to JSON
1159
+ const output = getResultText();
1160
+ if (output) html += formatExpandableOutput(output, 10);
1161
+ }
1162
+ } else {
1163
+ // Fallback to JSON display (existing behavior)
1164
+ html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
1165
+ html += `<div class="tool-output"><pre>${escapeHtml(JSON.stringify(args, null, 2))}</pre></div>`;
1166
+ if (result) {
1167
+ const output = getResultText();
1168
+ if (output) html += formatExpandableOutput(output, 10);
1169
+ }
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+ html += renderNestedCalls();
1175
+ html += '</div>';
1176
+ return html;
1177
+ }
1178
+
1179
+ /**
1180
+ * Download the session data as a JSONL file.
1181
+ * Reconstructs the original format: header line + entry lines.
1182
+ */
1183
+ window.downloadSessionJson = function() {
1184
+ // Build JSONL content: header first, then all entries
1185
+ const lines = [];
1186
+ if (header) {
1187
+ lines.push(JSON.stringify({ type: 'header', ...header }));
1188
+ }
1189
+ for (const entry of entries) {
1190
+ lines.push(JSON.stringify(entry));
1191
+ }
1192
+ const jsonlContent = lines.join('\n');
1193
+
1194
+ // Create download
1195
+ const blob = new Blob([jsonlContent], { type: 'application/x-ndjson' });
1196
+ const url = URL.createObjectURL(blob);
1197
+ const a = document.createElement('a');
1198
+ a.href = url;
1199
+ a.download = `${header?.id || 'session'}.jsonl`;
1200
+ document.body.appendChild(a);
1201
+ a.click();
1202
+ document.body.removeChild(a);
1203
+ URL.revokeObjectURL(url);
1204
+ }
1205
+
1206
+ /**
1207
+ * Build a shareable URL for a specific message.
1208
+ * URL format: base?gistId&leafId=<leafId>&targetId=<entryId>
1209
+ */
1210
+ function buildShareUrl(entryId) {
1211
+ // Check for injected base URL (used when loaded in iframe via srcdoc)
1212
+ const baseUrlMeta = document.querySelector('meta[name="pi-share-base-url"]');
1213
+ const baseUrl = baseUrlMeta ? baseUrlMeta.content : window.location.href.split('?')[0];
1214
+
1215
+ const url = new URL(window.location.href);
1216
+ // Find the gist ID (first query param without value, e.g., ?abc123)
1217
+ const gistId = Array.from(url.searchParams.keys()).find(k => !url.searchParams.get(k));
1218
+
1219
+ // Build the share URL
1220
+ const params = new URLSearchParams();
1221
+ params.set('leafId', currentLeafId);
1222
+ params.set('targetId', entryId);
1223
+
1224
+ // If we have an injected base URL (iframe context), use it directly
1225
+ if (baseUrlMeta) {
1226
+ return `${baseUrl}&${params.toString()}`;
1227
+ }
1228
+
1229
+ // Otherwise build from current location (direct file access)
1230
+ url.search = gistId ? `?${gistId}&${params.toString()}` : `?${params.toString()}`;
1231
+ return url.toString();
1232
+ }
1233
+
1234
+ /**
1235
+ * Copy text to clipboard with visual feedback.
1236
+ * Uses navigator.clipboard with fallback to execCommand for HTTP contexts.
1237
+ */
1238
+ async function copyToClipboard(text, button) {
1239
+ let success = false;
1240
+ try {
1241
+ if (navigator.clipboard && navigator.clipboard.writeText) {
1242
+ await navigator.clipboard.writeText(text);
1243
+ success = true;
1244
+ }
1245
+ } catch (err) {
1246
+ // Clipboard API failed, try fallback
1247
+ }
1248
+
1249
+ // Fallback for HTTP or when Clipboard API is unavailable
1250
+ if (!success) {
1251
+ try {
1252
+ const textarea = document.createElement('textarea');
1253
+ textarea.value = text;
1254
+ textarea.style.position = 'fixed';
1255
+ textarea.style.opacity = '0';
1256
+ document.body.appendChild(textarea);
1257
+ textarea.select();
1258
+ success = document.execCommand('copy');
1259
+ document.body.removeChild(textarea);
1260
+ } catch (err) {
1261
+ console.error('Failed to copy:', err);
1262
+ }
1263
+ }
1264
+
1265
+ if (success && button) {
1266
+ const originalHtml = button.innerHTML;
1267
+ button.innerHTML = '✓';
1268
+ button.classList.add('copied');
1269
+ setTimeout(() => {
1270
+ button.innerHTML = originalHtml;
1271
+ button.classList.remove('copied');
1272
+ }, 1500);
1273
+ }
1274
+ }
1275
+
1276
+ /**
1277
+ * Render the copy-link button HTML for a message.
1278
+ */
1279
+ function renderCopyLinkButton(entryId) {
1280
+ return `<button class="copy-link-btn" data-entry-id="${escapeHtml(entryId)}" title="Copy link to this message">
1281
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1282
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
1283
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
1284
+ </svg>
1285
+ </button>`;
1286
+ }
1287
+
1288
+ function renderEntry(entry) {
1289
+ const ts = formatTimestamp(entry.timestamp);
1290
+ const tsHtml = ts ? `<div class="message-timestamp">${ts}</div>` : '';
1291
+ const entryDomId = `entry-${escapeHtml(entry.id)}`;
1292
+ const copyBtnHtml = renderCopyLinkButton(entry.id);
1293
+
1294
+ if (entry.type === 'message') {
1295
+ const msg = entry.message;
1296
+
1297
+ if (msg.role === 'user') {
1298
+ const content = msg.content;
1299
+ const text = typeof content === 'string' ? content :
1300
+ content.filter(c => c.type === 'text').map(c => c.text).join('\n');
1301
+ const skillBlock = parseSkillBlock(text);
1302
+
1303
+ if (skillBlock) {
1304
+ // Collect images from content array
1305
+ const images = Array.isArray(content) ? content.filter(c => c.type === 'image') : [];
1306
+ const hasUserContent = skillBlock.userMessage || images.length > 0;
1307
+ let html = `<div class="skill-user-entry" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
1308
+
1309
+ // Skill invocation (collapsed by default, click to expand)
1310
+ html += `<div class="skill-invocation" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1311
+ <div class="skill-invocation-label">[skill] ${escapeHtml(skillBlock.name)}</div>
1312
+ <div class="skill-invocation-collapsed">${escapeHtml(skillBlock.name)} (click to expand)</div>
1313
+ <div class="skill-invocation-content markdown-content">${safeMarkedParse(skillBlock.content)}</div>
1314
+ </div>`;
1315
+
1316
+ // User message (separate block if present)
1317
+ if (hasUserContent) {
1318
+ html += '<div class="user-message">';
1319
+ if (images.length > 0) {
1320
+ html += '<div class="message-images">';
1321
+ for (const img of images) {
1322
+ html += `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="message-image" />`;
1323
+ }
1324
+ html += '</div>';
1325
+ }
1326
+ if (skillBlock.userMessage) {
1327
+ html += `<div class="markdown-content">${safeMarkedParse(skillBlock.userMessage)}</div>`;
1328
+ }
1329
+ html += '</div>';
1330
+ }
1331
+
1332
+ html += '</div>';
1333
+ return html;
1334
+ }
1335
+
1336
+ // No skill block - normal user message
1337
+ let html = `<div class="user-message" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
1338
+
1339
+ if (Array.isArray(content)) {
1340
+ const images = content.filter(c => c.type === 'image');
1341
+ if (images.length > 0) {
1342
+ html += '<div class="message-images">';
1343
+ for (const img of images) {
1344
+ html += `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${escapeHtml(img.data || '')}" class="message-image" />`;
1345
+ }
1346
+ html += '</div>';
1347
+ }
1348
+ }
1349
+
1350
+ if (text.trim()) {
1351
+ html += `<div class="markdown-content">${safeMarkedParse(text)}</div>`;
1352
+ }
1353
+ html += '</div>';
1354
+ return html;
1355
+ }
1356
+
1357
+ if (msg.role === 'assistant') {
1358
+ let html = `<div class="assistant-message" id="${entryDomId}">${copyBtnHtml}${tsHtml}`;
1359
+
1360
+ for (const block of msg.content) {
1361
+ if (block.type === 'text' && block.text.trim()) {
1362
+ html += `<div class="assistant-text markdown-content">${safeMarkedParse(block.text)}</div>`;
1363
+ } else if (block.type === 'thinking' && block.thinking.trim()) {
1364
+ html += `<div class="thinking-block">
1365
+ <div class="thinking-text">${escapeHtml(block.thinking)}</div>
1366
+ <div class="thinking-collapsed">Thinking ...</div>
1367
+ </div>`;
1368
+ }
1369
+ }
1370
+
1371
+ for (const block of msg.content) {
1372
+ if (block.type === 'toolCall') {
1373
+ html += renderToolCall(block);
1374
+ }
1375
+ }
1376
+
1377
+ if (msg.stopReason === 'aborted') {
1378
+ html += '<div class="error-text">Aborted</div>';
1379
+ } else if (msg.stopReason === 'error') {
1380
+ html += `<div class="error-text">Error: ${escapeHtml(msg.errorMessage || 'Unknown error')}</div>`;
1381
+ }
1382
+
1383
+ html += '</div>';
1384
+ return html;
1385
+ }
1386
+
1387
+ if (msg.role === 'bashExecution') {
1388
+ const isError = msg.cancelled || (msg.exitCode !== 0 && msg.exitCode !== null);
1389
+ let html = `<div class="tool-execution ${isError ? 'error' : 'success'}" id="${entryDomId}">${tsHtml}`;
1390
+ html += `<div class="tool-command">$ ${escapeHtml(msg.command)}</div>`;
1391
+ if (msg.output) html += formatExpandableOutput(msg.output, 10);
1392
+ if (msg.cancelled) {
1393
+ html += '<div style="color: var(--warning)">(cancelled)</div>';
1394
+ } else if (msg.exitCode !== 0 && msg.exitCode !== null) {
1395
+ html += `<div style="color: var(--error)">(exit ${msg.exitCode})</div>`;
1396
+ }
1397
+ html += '</div>';
1398
+ return html;
1399
+ }
1400
+
1401
+ if (msg.role === 'toolResult') return '';
1402
+
1403
+ if (msg.role === 'system') {
1404
+ let html = '';
1405
+ if (isLeadingSystemEntry(entry)) {
1406
+ const text = getSystemMessageText(msg);
1407
+ if (text) html += renderSystemPromptBlock('System Prompt', text);
1408
+ html += renderToolsList('Available Tools', msg.toolsAdded);
1409
+ } else {
1410
+ const text = renderSystemMessageUpdate(msg);
1411
+ const changes = describeSystemUpdate(msg);
1412
+ if (text) html += renderSystemPromptBlock(`System Prompt Update${changes ? ': ' + changes : ''}`, text);
1413
+ html += renderToolsList('Tools Added', msg.toolsAdded);
1414
+ if (msg.toolsRemoved && msg.toolsRemoved.length > 0) {
1415
+ html += `<div class="tools-list"><div class="tools-header">Tools Removed</div><div class="tools-content">${msg.toolsRemoved.map(t => `<div class="tool-item"><span class="tool-item-name">${escapeHtml(t.name)}</span></div>`).join('')}</div></div>`;
1416
+ }
1417
+ }
1418
+ return html ? `<div class="system-entry" id="${entryDomId}">${tsHtml}${html}</div>` : '';
1419
+ }
1420
+ }
1421
+
1422
+ if (entry.type === 'model_change') {
1423
+ return `<div class="model-change" id="${entryDomId}">${tsHtml}Switched to model: <span class="model-name">${escapeHtml(entry.provider)}/${escapeHtml(entry.modelId)}</span></div>`;
1424
+ }
1425
+
1426
+ if (entry.type === 'compaction') {
1427
+ return `<div class="compaction" id="${entryDomId}" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1428
+ <div class="compaction-label">[compaction]</div>
1429
+ <div class="compaction-collapsed">Compacted from ${entry.tokensBefore.toLocaleString()} tokens</div>
1430
+ <div class="compaction-content"><strong>Compacted from ${entry.tokensBefore.toLocaleString()} tokens</strong>\n\n${escapeHtml(entry.summary)}</div>
1431
+ </div>`;
1432
+ }
1433
+
1434
+ if (entry.type === 'branch_summary') {
1435
+ return `<div class="branch-summary" id="${entryDomId}">${tsHtml}
1436
+ <div class="branch-summary-header">Branch Summary</div>
1437
+ <div class="markdown-content">${safeMarkedParse(entry.summary)}</div>
1438
+ </div>`;
1439
+ }
1440
+
1441
+ if (entry.type === 'custom_message') {
1442
+ const hidden = entry.display === false;
1443
+ return `<div class="hook-message${hidden ? ' hook-message-hidden' : ''}" id="${entryDomId}">${tsHtml}
1444
+ <div class="hook-type">[${escapeHtml(entry.customType)}]${hidden ? ' · Hidden in terminal' : ''}</div>
1445
+ <div class="markdown-content">${safeMarkedParse(typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content))}</div>
1446
+ </div>`;
1447
+ }
1448
+
1449
+ return '';
1450
+ }
1451
+
1452
+ // ============================================================
1453
+ // HEADER / STATS
1454
+ // ============================================================
1455
+
1456
+ function computeStats(entryList) {
1457
+ let userMessages = 0, assistantMessages = 0, toolResults = 0;
1458
+ let customMessages = 0, compactions = 0, branchSummaries = 0, toolCalls = 0;
1459
+ const tokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
1460
+ const cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 };
1461
+ const models = new Set();
1462
+
1463
+ for (const entry of entryList) {
1464
+ if (entry.type === 'message') {
1465
+ const msg = entry.message;
1466
+ if (msg.role === 'user') userMessages++;
1467
+ if (msg.role === 'assistant') {
1468
+ assistantMessages++;
1469
+ if (msg.model) models.add(msg.provider ? `${msg.provider}/${msg.model}` : msg.model);
1470
+ if (msg.usage) {
1471
+ tokens.input += msg.usage.input || 0;
1472
+ tokens.output += msg.usage.output || 0;
1473
+ tokens.cacheRead += msg.usage.cacheRead || 0;
1474
+ tokens.cacheWrite += msg.usage.cacheWrite || 0;
1475
+ if (msg.usage.cost) {
1476
+ const componentTotal =
1477
+ (msg.usage.cost.input || 0) +
1478
+ (msg.usage.cost.output || 0) +
1479
+ (msg.usage.cost.cacheRead || 0) +
1480
+ (msg.usage.cost.cacheWrite || 0);
1481
+ cost.input += msg.usage.cost.input || 0;
1482
+ cost.output += msg.usage.cost.output || 0;
1483
+ cost.cacheRead += msg.usage.cost.cacheRead || 0;
1484
+ cost.cacheWrite += msg.usage.cost.cacheWrite || 0;
1485
+ // Provider-reported totals can intentionally differ from catalog-estimated components.
1486
+ // Fall back to the component sum for sessions written before cost.total was recorded.
1487
+ cost.total += typeof msg.usage.cost.total === 'number' ? msg.usage.cost.total : componentTotal;
1488
+ }
1489
+ }
1490
+ toolCalls += msg.content.filter(c => c.type === 'toolCall').length;
1491
+ }
1492
+ if (msg.role === 'toolResult') toolResults++;
1493
+ } else if (entry.type === 'compaction') {
1494
+ compactions++;
1495
+ } else if (entry.type === 'branch_summary') {
1496
+ branchSummaries++;
1497
+ } else if (entry.type === 'custom_message') {
1498
+ customMessages++;
1499
+ }
1500
+ }
1501
+
1502
+ return { userMessages, assistantMessages, toolResults, customMessages, compactions, branchSummaries, toolCalls, tokens, cost, models: Array.from(models) };
1503
+ }
1504
+
1505
+ const globalStats = computeStats(entries);
1506
+
1507
+ function renderHeader() {
1508
+ const totalCost = globalStats.cost.total;
1509
+
1510
+ const tokenParts = [];
1511
+ if (globalStats.tokens.input) tokenParts.push(`↑${formatTokens(globalStats.tokens.input)}`);
1512
+ if (globalStats.tokens.output) tokenParts.push(`↓${formatTokens(globalStats.tokens.output)}`);
1513
+ if (globalStats.tokens.cacheRead) tokenParts.push(`R${formatTokens(globalStats.tokens.cacheRead)}`);
1514
+ if (globalStats.tokens.cacheWrite) tokenParts.push(`W${formatTokens(globalStats.tokens.cacheWrite)}`);
1515
+
1516
+ const msgParts = [];
1517
+ if (globalStats.userMessages) msgParts.push(`${globalStats.userMessages} user`);
1518
+ if (globalStats.assistantMessages) msgParts.push(`${globalStats.assistantMessages} assistant`);
1519
+ if (globalStats.toolResults) msgParts.push(`${globalStats.toolResults} tool results`);
1520
+ if (globalStats.customMessages) msgParts.push(`${globalStats.customMessages} custom`);
1521
+ if (globalStats.compactions) msgParts.push(`${globalStats.compactions} compactions`);
1522
+ if (globalStats.branchSummaries) msgParts.push(`${globalStats.branchSummaries} branch summaries`);
1523
+
1524
+ let html = `
1525
+ <div class="header">
1526
+ <h1>Session: ${escapeHtml(header?.id || 'unknown')}</h1>
1527
+ <div class="help-bar">
1528
+ <span class="help-hint">T toggle thinking · O toggle tools · H toggle hidden messages</span>
1529
+ <div class="help-actions">
1530
+ <button type="button" class="header-toggle-btn" data-action="toggle-thinking" aria-pressed="${thinkingExpanded}" title="Toggle thinking (T)">Toggle thinking</button>
1531
+ <button type="button" class="header-toggle-btn" data-action="toggle-tools" aria-pressed="${toolOutputsExpanded}" title="Toggle tools (O)">Toggle tools</button>
1532
+ <button type="button" class="header-toggle-btn" data-action="toggle-hidden-messages" aria-pressed="${showHiddenMessages}" title="Show custom messages marked as hidden in the terminal (H).">${showHiddenMessages ? 'Hide hidden messages' : 'Show hidden messages'}</button>
1533
+ <button type="button" class="download-json-btn" onclick="downloadSessionJson()" title="Download session as JSONL">↓ JSONL</button>
1534
+ </div>
1535
+ </div>
1536
+ <div class="header-info">
1537
+ <div class="info-item"><span class="info-label">Date:</span><span class="info-value">${header?.timestamp ? new Date(header.timestamp).toLocaleString() : 'unknown'}</span></div>
1538
+ <div class="info-item"><span class="info-label">Models:</span><span class="info-value">${escapeHtml(globalStats.models.join(', ') || 'unknown')}</span></div>
1539
+ <div class="info-item"><span class="info-label">Messages:</span><span class="info-value">${msgParts.join(', ') || '0'}</span></div>
1540
+ <div class="info-item"><span class="info-label">Tool Calls:</span><span class="info-value">${globalStats.toolCalls}</span></div>
1541
+ <div class="info-item"><span class="info-label">Tokens:</span><span class="info-value">${tokenParts.join(' ') || '0'}</span></div>
1542
+ <div class="info-item"><span class="info-label">Cost:</span><span class="info-value">$${totalCost.toFixed(3)}</span></div>
1543
+ </div>
1544
+ </div>`;
1545
+
1546
+ // Sessions with system entries render the prompt and tools in the transcript, where they
1547
+ // occur. Older sessions have none, so fall back to the exporting agent's current state.
1548
+ if (!hasSystemEntries) {
1549
+ if (systemPrompt) html += renderSystemPromptBlock('System Prompt', systemPrompt);
1550
+ html += renderToolsList('Available Tools', tools);
1551
+ }
1552
+
1553
+ return html;
1554
+ }
1555
+
1556
+ function renderSystemPromptBlock(title, text) {
1557
+ const lines = text.split('\n');
1558
+ const previewLines = 10;
1559
+ if (lines.length > previewLines) {
1560
+ const preview = lines.slice(0, previewLines).join('\n');
1561
+ const remaining = lines.length - previewLines;
1562
+ return `<div class="system-prompt expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1563
+ <div class="system-prompt-header">${escapeHtml(title)}</div>
1564
+ <div class="system-prompt-preview">${escapeHtml(preview)}</div>
1565
+ <div class="system-prompt-expand-hint">... (${remaining} more lines, click to expand)</div>
1566
+ <div class="system-prompt-full">${escapeHtml(text)}</div>
1567
+ </div>`;
1568
+ }
1569
+ return `<div class="system-prompt">
1570
+ <div class="system-prompt-header">${escapeHtml(title)}</div>
1571
+ <div class="system-prompt-full" style="display: block">${escapeHtml(text)}</div>
1572
+ </div>`;
1573
+ }
1574
+
1575
+ function renderToolsList(title, tools) {
1576
+ if (!tools || tools.length === 0) return '';
1577
+ return `<div class="tools-list">
1578
+ <div class="tools-header">${escapeHtml(title)}</div>
1579
+ <div class="tools-content">
1580
+ ${tools.map(t => {
1581
+ const hasParams = t.parameters && typeof t.parameters === 'object' && t.parameters.properties && Object.keys(t.parameters.properties).length > 0;
1582
+ if (!hasParams) {
1583
+ return `<div class="tool-item"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span></div>`;
1584
+ }
1585
+ const params = t.parameters;
1586
+ const properties = params.properties;
1587
+ const required = params.required || [];
1588
+ let paramsHtml = '';
1589
+ for (const [name, prop] of Object.entries(properties)) {
1590
+ const isRequired = required.includes(name);
1591
+ const typeStr = prop.type || 'any';
1592
+ const reqLabel = isRequired ? '<span class="tool-param-required">required</span>' : '<span class="tool-param-optional">optional</span>';
1593
+ paramsHtml += `<div class="tool-param"><span class="tool-param-name">${escapeHtml(name)}</span> <span class="tool-param-type">${escapeHtml(typeStr)}</span> ${reqLabel}`;
1594
+ if (prop.description) {
1595
+ paramsHtml += `<div class="tool-param-desc">${escapeHtml(prop.description)}</div>`;
1596
+ }
1597
+ paramsHtml += `</div>`;
1598
+ }
1599
+ return `<div class="tool-item" onclick="if(window.getSelection().toString())return;this.classList.toggle('params-expanded')"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span> <span class="tool-params-hint"></span><div class="tool-params-content">${paramsHtml}</div></div>`;
1600
+ }).join('')}
1601
+ </div>
1602
+ </div>`;
1603
+ }
1604
+
1605
+ // ============================================================
1606
+ // NAVIGATION
1607
+ // ============================================================
1608
+
1609
+ // Cache for rendered entry DOM nodes
1610
+ const entryCache = new Map();
1611
+
1612
+ function getScrollTargetElementId(entryId) {
1613
+ const entry = byId.get(entryId);
1614
+ if (entry?.type === 'message' && entry.message.role === 'toolResult' && entry.message.toolCallId) {
1615
+ // getElementById() matches the parsed DOM id attribute, whose HTML entities
1616
+ // were already resolved from the escaped id rendered by renderToolCall().
1617
+ return `tool-call-${entry.message.toolCallId}`;
1618
+ }
1619
+ return `entry-${entryId}`;
1620
+ }
1621
+
1622
+ function renderEntryToNode(entry) {
1623
+ // Check cache first
1624
+ if (entryCache.has(entry.id)) {
1625
+ return entryCache.get(entry.id).cloneNode(true);
1626
+ }
1627
+
1628
+ // Render to HTML string, then parse to node
1629
+ const html = renderEntry(entry);
1630
+ if (!html) return null;
1631
+
1632
+ const template = document.createElement('template');
1633
+ template.innerHTML = html;
1634
+ const node = template.content.firstElementChild;
1635
+
1636
+ // Cache the node
1637
+ if (node) {
1638
+ entryCache.set(entry.id, node.cloneNode(true));
1639
+ }
1640
+ return node;
1641
+ }
1642
+
1643
+ function navigateTo(targetId, scrollMode = 'target', scrollToEntryId = null) {
1644
+ currentLeafId = targetId;
1645
+ currentTargetId = scrollToEntryId || targetId;
1646
+ const targetEntry = byId.get(currentTargetId);
1647
+ if (scrollMode === 'target' && targetEntry?.type === 'custom_message' && targetEntry.display === false) {
1648
+ setHiddenMessagesVisible(true);
1649
+ }
1650
+ const path = getPath(targetId);
1651
+
1652
+ renderTree();
1653
+
1654
+ document.getElementById('header-container').innerHTML = renderHeader();
1655
+ attachHeaderHandlers();
1656
+
1657
+ // Build messages using cached DOM nodes
1658
+ const messagesEl = document.getElementById('messages');
1659
+ const fragment = document.createDocumentFragment();
1660
+
1661
+ for (const entry of path) {
1662
+ const node = renderEntryToNode(entry);
1663
+ if (node) {
1664
+ fragment.appendChild(node);
1665
+ }
1666
+ }
1667
+
1668
+ messagesEl.innerHTML = '';
1669
+ messagesEl.appendChild(fragment);
1670
+
1671
+ // Cached nodes contain their initial presentation; reapply the viewer's toggle states.
1672
+ setThinkingExpanded(thinkingExpanded);
1673
+ setToolOutputsExpanded(toolOutputsExpanded);
1674
+
1675
+ // Attach click handlers for copy-link buttons
1676
+ messagesEl.querySelectorAll('.copy-link-btn').forEach(btn => {
1677
+ btn.addEventListener('click', (e) => {
1678
+ e.stopPropagation();
1679
+ const entryId = btn.dataset.entryId;
1680
+ const shareUrl = buildShareUrl(entryId);
1681
+ copyToClipboard(shareUrl, btn);
1682
+ });
1683
+ });
1684
+
1685
+ // Use setTimeout(0) to ensure DOM is fully laid out before scrolling
1686
+ setTimeout(() => {
1687
+ const content = document.getElementById('content');
1688
+ if (scrollMode === 'bottom') {
1689
+ content.scrollTop = content.scrollHeight;
1690
+ } else if (scrollMode === 'target') {
1691
+ // If scrollToEntryId is provided, scroll to that specific entry.
1692
+ // Tool result entries are rendered inside their assistant tool-call block,
1693
+ // so route them to the visible tool-call element instead.
1694
+ const scrollTargetId = scrollToEntryId || targetId;
1695
+ const targetEl = document.getElementById(getScrollTargetElementId(scrollTargetId)) ||
1696
+ document.getElementById(`entry-${scrollTargetId}`);
1697
+ if (targetEl) {
1698
+ targetEl.scrollIntoView({ block: 'center' });
1699
+ // Briefly highlight the target message
1700
+ if (scrollToEntryId) {
1701
+ targetEl.classList.add('highlight');
1702
+ setTimeout(() => targetEl.classList.remove('highlight'), 2000);
1703
+ }
1704
+ }
1705
+ }
1706
+ }, 0);
1707
+ }
1708
+
1709
+ // ============================================================
1710
+ // INITIALIZATION
1711
+ // ============================================================
1712
+
1713
+ // Configure marked with syntax highlighting and TUI-compatible HTML handling
1714
+ const strictStrikethroughRegex = /^(~~)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/;
1715
+
1716
+ marked.use({
1717
+ breaks: true,
1718
+ gfm: true,
1719
+ tokenizer: {
1720
+ // Treat HTML-like input as plain text so tags are shown verbatim,
1721
+ // matching the TUI markdown renderer.
1722
+ html() {
1723
+ return undefined;
1724
+ },
1725
+ tag() {
1726
+ return undefined;
1727
+ },
1728
+ del(src) {
1729
+ const match = strictStrikethroughRegex.exec(src);
1730
+ if (!match) return undefined;
1731
+ return {
1732
+ type: 'del',
1733
+ raw: match[0],
1734
+ text: match[2],
1735
+ tokens: this.lexer.inlineTokens(match[2])
1736
+ };
1737
+ },
1738
+ emStrong: markedCjkFriendly().tokenizer.emStrong
1739
+ },
1740
+ renderer: {
1741
+ // Sanitize link URLs with a scheme allow-list. Browsers strip C0
1742
+ // controls from schemes, so strip them before checking and emitting.
1743
+ link(token) {
1744
+ const href = sanitizeMarkdownUrl(token.href);
1745
+ if (href === null) {
1746
+ return this.parser.parseInline(token.tokens);
1747
+ }
1748
+ let out = '<a href="' + escapeHtml(href) + '"';
1749
+ if (token.title) {
1750
+ out += ' title="' + escapeHtml(token.title) + '"';
1751
+ }
1752
+ out += '>' + this.parser.parseInline(token.tokens) + '</a>';
1753
+ return out;
1754
+ },
1755
+ // Sanitize image src URLs with the same scheme allow-list.
1756
+ image(token) {
1757
+ const href = sanitizeMarkdownUrl(token.href);
1758
+ if (href === null) {
1759
+ return escapeHtml(token.text || '');
1760
+ }
1761
+ let out = '<img src="' + escapeHtml(href) + '" alt="' + escapeHtml(token.text || '') + '"';
1762
+ if (token.title) {
1763
+ out += ' title="' + escapeHtml(token.title) + '"';
1764
+ }
1765
+ out += '>';
1766
+ return out;
1767
+ },
1768
+ // Code blocks: syntax highlight, no HTML escaping
1769
+ code(token) {
1770
+ const code = token.text;
1771
+ const lang = token.lang;
1772
+ let highlighted;
1773
+ if (lang && hljs.getLanguage(lang)) {
1774
+ try {
1775
+ highlighted = hljs.highlight(code, { language: lang }).value;
1776
+ } catch {
1777
+ highlighted = escapeHtml(code);
1778
+ }
1779
+ } else {
1780
+ // Auto-detect language if not specified
1781
+ try {
1782
+ highlighted = hljs.highlightAuto(code).value;
1783
+ } catch {
1784
+ highlighted = escapeHtml(code);
1785
+ }
1786
+ }
1787
+ return `<pre><code class="hljs">${highlighted}</code></pre>`;
1788
+ },
1789
+ // Inline code: escape HTML
1790
+ codespan(token) {
1791
+ return `<code>${escapeHtml(token.text)}</code>`;
1792
+ }
1793
+ }
1794
+ });
1795
+
1796
+ // Simple marked parse (escaping handled in renderers)
1797
+ function safeMarkedParse(text) {
1798
+ return marked.parse(text);
1799
+ }
1800
+
1801
+ // Search input
1802
+ const searchInput = document.getElementById('tree-search');
1803
+ searchInput.addEventListener('input', (e) => {
1804
+ searchQuery = e.target.value;
1805
+ forceTreeRerender();
1806
+ });
1807
+
1808
+ // Filter buttons
1809
+ document.querySelectorAll('.filter-btn').forEach(btn => {
1810
+ btn.addEventListener('click', () => {
1811
+ document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
1812
+ btn.classList.add('active');
1813
+ filterMode = btn.dataset.filter;
1814
+ forceTreeRerender();
1815
+ });
1816
+ });
1817
+
1818
+ // Sidebar toggle
1819
+ const sidebar = document.getElementById('sidebar');
1820
+ const overlay = document.getElementById('sidebar-overlay');
1821
+ const hamburger = document.getElementById('hamburger');
1822
+ const sidebarResizer = document.getElementById('sidebar-resizer');
1823
+ const SIDEBAR_WIDTH_STORAGE_KEY = 'pi-share:v1:sidebar-width';
1824
+ const MIN_CONTENT_WIDTH = 320;
1825
+
1826
+ function isMobileLayout() {
1827
+ return window.matchMedia('(max-width: 900px)').matches;
1828
+ }
1829
+
1830
+ function getSidebarBounds() {
1831
+ const rootStyles = getComputedStyle(document.documentElement);
1832
+ const minWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-min-width')) || 240;
1833
+ const maxWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-max-width')) || 720;
1834
+ const viewportMaxWidth = window.innerWidth - MIN_CONTENT_WIDTH;
1835
+ return {
1836
+ minWidth,
1837
+ maxWidth: Math.max(minWidth, Math.min(maxWidth, viewportMaxWidth))
1838
+ };
1839
+ }
1840
+
1841
+ function clampSidebarWidth(width) {
1842
+ const { minWidth, maxWidth } = getSidebarBounds();
1843
+ return Math.max(minWidth, Math.min(maxWidth, width));
1844
+ }
1845
+
1846
+ function applySidebarWidth(width) {
1847
+ document.documentElement.style.setProperty('--sidebar-width', `${Math.round(clampSidebarWidth(width))}px`);
1848
+ }
1849
+
1850
+ function loadSidebarWidth() {
1851
+ try {
1852
+ const raw = localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY);
1853
+ if (raw === null) return null;
1854
+ const width = Number(raw);
1855
+ return Number.isFinite(width) ? width : null;
1856
+ } catch {
1857
+ return null;
1858
+ }
1859
+ }
1860
+
1861
+ function saveSidebarWidth(width) {
1862
+ try {
1863
+ localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(clampSidebarWidth(width))));
1864
+ } catch {
1865
+ // Ignore storage failures (e.g. private browsing restrictions)
1866
+ }
1867
+ }
1868
+
1869
+ function setupSidebarResize() {
1870
+ const savedWidth = loadSidebarWidth();
1871
+ if (savedWidth !== null) {
1872
+ applySidebarWidth(savedWidth);
1873
+ }
1874
+
1875
+ if (!sidebarResizer) return;
1876
+
1877
+ let cleanupDrag = null;
1878
+
1879
+ const stopDrag = (pointerId) => {
1880
+ if (cleanupDrag) {
1881
+ cleanupDrag(pointerId);
1882
+ cleanupDrag = null;
1883
+ }
1884
+ };
1885
+
1886
+ sidebarResizer.addEventListener('pointerdown', (e) => {
1887
+ if (isMobileLayout()) return;
1888
+
1889
+ e.preventDefault();
1890
+ const startX = e.clientX;
1891
+ const startWidth = sidebar.getBoundingClientRect().width;
1892
+ document.body.classList.add('sidebar-resizing');
1893
+ sidebarResizer.setPointerCapture?.(e.pointerId);
1894
+
1895
+ const onPointerMove = (event) => {
1896
+ applySidebarWidth(startWidth + (event.clientX - startX));
1897
+ };
1898
+
1899
+ cleanupDrag = (pointerIdToRelease) => {
1900
+ document.body.classList.remove('sidebar-resizing');
1901
+ sidebarResizer.releasePointerCapture?.(pointerIdToRelease);
1902
+ window.removeEventListener('pointermove', onPointerMove);
1903
+ window.removeEventListener('pointerup', onPointerUp);
1904
+ window.removeEventListener('pointercancel', onPointerCancel);
1905
+ saveSidebarWidth(sidebar.getBoundingClientRect().width);
1906
+ };
1907
+
1908
+ const onPointerUp = (event) => stopDrag(event.pointerId);
1909
+ const onPointerCancel = (event) => stopDrag(event.pointerId);
1910
+
1911
+ window.addEventListener('pointermove', onPointerMove);
1912
+ window.addEventListener('pointerup', onPointerUp);
1913
+ window.addEventListener('pointercancel', onPointerCancel);
1914
+ });
1915
+
1916
+ sidebarResizer.addEventListener('dblclick', () => {
1917
+ if (isMobileLayout()) return;
1918
+ applySidebarWidth(400);
1919
+ saveSidebarWidth(400);
1920
+ });
1921
+
1922
+ window.addEventListener('resize', () => {
1923
+ if (isMobileLayout()) return;
1924
+ applySidebarWidth(sidebar.getBoundingClientRect().width);
1925
+ });
1926
+ }
1927
+
1928
+ setupSidebarResize();
1929
+
1930
+ hamburger.addEventListener('click', () => {
1931
+ sidebar.classList.add('open');
1932
+ overlay.classList.add('open');
1933
+ hamburger.style.display = 'none';
1934
+ });
1935
+
1936
+ const closeSidebar = () => {
1937
+ sidebar.classList.remove('open');
1938
+ overlay.classList.remove('open');
1939
+ hamburger.style.display = '';
1940
+ };
1941
+
1942
+ overlay.addEventListener('click', closeSidebar);
1943
+ document.getElementById('sidebar-close').addEventListener('click', closeSidebar);
1944
+
1945
+ // Toggle states
1946
+ let thinkingExpanded = true;
1947
+ let toolOutputsExpanded = false;
1948
+ let showHiddenMessages = false;
1949
+
1950
+ function setHiddenMessagesVisible(visible) {
1951
+ showHiddenMessages = visible;
1952
+ document.body.classList.toggle('show-hidden-messages', visible);
1953
+ const button = document.querySelector('[data-action="toggle-hidden-messages"]');
1954
+ if (button) {
1955
+ button.setAttribute('aria-pressed', String(visible));
1956
+ button.textContent = visible ? 'Hide hidden messages' : 'Show hidden messages';
1957
+ }
1958
+ }
1959
+
1960
+ function setThinkingExpanded(expanded) {
1961
+ thinkingExpanded = expanded;
1962
+ document.querySelector('[data-action="toggle-thinking"]')?.setAttribute('aria-pressed', String(expanded));
1963
+ document.querySelectorAll('.thinking-text').forEach(el => {
1964
+ el.style.display = thinkingExpanded ? '' : 'none';
1965
+ });
1966
+ document.querySelectorAll('.thinking-collapsed').forEach(el => {
1967
+ el.style.display = thinkingExpanded ? 'none' : 'block';
1968
+ });
1969
+ }
1970
+
1971
+ function setToolOutputsExpanded(expanded) {
1972
+ toolOutputsExpanded = expanded;
1973
+ document.querySelector('[data-action="toggle-tools"]')?.setAttribute('aria-pressed', String(expanded));
1974
+ document.querySelectorAll('.tool-output.expandable').forEach(el => {
1975
+ el.classList.toggle('expanded', toolOutputsExpanded);
1976
+ });
1977
+ document.querySelectorAll('.compaction').forEach(el => {
1978
+ el.classList.toggle('expanded', toolOutputsExpanded);
1979
+ });
1980
+ document.querySelectorAll('.skill-invocation').forEach(el => {
1981
+ el.classList.toggle('expanded', toolOutputsExpanded);
1982
+ });
1983
+ }
1984
+
1985
+ const attachHeaderHandlers = () => {
1986
+ document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click', () => {
1987
+ setThinkingExpanded(!thinkingExpanded);
1988
+ });
1989
+ document.querySelector('[data-action="toggle-tools"]')?.addEventListener('click', () => {
1990
+ setToolOutputsExpanded(!toolOutputsExpanded);
1991
+ });
1992
+ document.querySelector('[data-action="toggle-hidden-messages"]')?.addEventListener('click', () => {
1993
+ setHiddenMessagesVisible(!showHiddenMessages);
1994
+ });
1995
+ };
1996
+
1997
+ const isEditableTarget = (element) => {
1998
+ if (!element) return false;
1999
+ const tagName = element.tagName;
2000
+ if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || tagName === 'BUTTON') {
2001
+ return true;
2002
+ }
2003
+ return element.isContentEditable || Boolean(element.closest?.('[contenteditable="true"]'));
2004
+ };
2005
+
2006
+ // Keyboard shortcuts
2007
+ document.addEventListener('keydown', (e) => {
2008
+ if (e.key === 'Escape') {
2009
+ searchInput.value = '';
2010
+ searchQuery = '';
2011
+ navigateTo(leafId, 'bottom');
2012
+ }
2013
+
2014
+ if (e.ctrlKey || e.metaKey || e.altKey || isEditableTarget(document.activeElement)) {
2015
+ return;
2016
+ }
2017
+
2018
+ const key = e.key.toLowerCase();
2019
+ if (key === 't') {
2020
+ e.preventDefault();
2021
+ setThinkingExpanded(!thinkingExpanded);
2022
+ } else if (key === 'o') {
2023
+ e.preventDefault();
2024
+ setToolOutputsExpanded(!toolOutputsExpanded);
2025
+ } else if (key === 'h') {
2026
+ e.preventDefault();
2027
+ setHiddenMessagesVisible(!showHiddenMessages);
2028
+ }
2029
+ });
2030
+
2031
+ // Initial render
2032
+ // If URL has targetId, scroll to that specific message; otherwise stay at top
2033
+ if (leafId) {
2034
+ if (urlTargetId && byId.has(urlTargetId)) {
2035
+ // Deep link: navigate to leaf and scroll to target message
2036
+ navigateTo(leafId, 'target', urlTargetId);
2037
+ } else {
2038
+ navigateTo(leafId, 'none');
2039
+ }
2040
+ } else if (entries.length > 0) {
2041
+ // Fallback: use last entry if no leafId
2042
+ navigateTo(entries[entries.length - 1].id, 'none');
2043
+ }
2044
+ })();