@pi-chamber/web 0.1.8

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 (1152) hide show
  1. package/README.md +43 -0
  2. package/bin/cli-entry.js +55 -0
  3. package/bin/cli-output.js +140 -0
  4. package/bin/cli-output.test.js +36 -0
  5. package/bin/cli.js +383 -0
  6. package/bin/cli.test.js +1065 -0
  7. package/bin/lib/DOCUMENTATION.md +31 -0
  8. package/bin/lib/cli-api-target.js +74 -0
  9. package/bin/lib/cli-args.js +846 -0
  10. package/bin/lib/cli-errors.js +18 -0
  11. package/bin/lib/cli-http.js +252 -0
  12. package/bin/lib/cli-lifecycle.js +421 -0
  13. package/bin/lib/cli-log-files.js +93 -0
  14. package/bin/lib/cli-network.js +186 -0
  15. package/bin/lib/cli-paths.js +128 -0
  16. package/bin/lib/cli-ports.js +51 -0
  17. package/bin/lib/cli-process.js +342 -0
  18. package/bin/lib/cli-startup.js +371 -0
  19. package/bin/lib/cli-tunnel-capabilities.js +9 -0
  20. package/bin/lib/cli-tunnel-profiles.js +366 -0
  21. package/bin/lib/cli-tunnel-utils.js +300 -0
  22. package/bin/lib/commands-connect-url.js +329 -0
  23. package/bin/lib/commands-lifecycle.js +396 -0
  24. package/bin/lib/commands-logs.js +110 -0
  25. package/bin/lib/commands-serve.js +419 -0
  26. package/bin/lib/commands-startup.js +64 -0
  27. package/bin/lib/commands-status.js +114 -0
  28. package/bin/lib/commands-tunnel.js +1761 -0
  29. package/bin/lib/commands-update.js +184 -0
  30. package/bin/lib/commands-update.test.js +98 -0
  31. package/dist/apple-touch-icon-120x120.png +0 -0
  32. package/dist/apple-touch-icon-152x152.png +0 -0
  33. package/dist/apple-touch-icon-167x167.png +0 -0
  34. package/dist/apple-touch-icon-180x180.png +0 -0
  35. package/dist/apple-touch-icon.png +0 -0
  36. package/dist/apple-touch-icon.svg +13 -0
  37. package/dist/assets/CommitSection-DGGArAb2.js +1 -0
  38. package/dist/assets/DiagramEditor-ig5nYV6t.js +1 -0
  39. package/dist/assets/DiagramView-8Qr6pwwI.js +1 -0
  40. package/dist/assets/DiffView-BHS4m_K7.js +18 -0
  41. package/dist/assets/FilesView-DmZcdwl-.js +14 -0
  42. package/dist/assets/GitView-gfHxmc66.js +6 -0
  43. package/dist/assets/JsonTreeView-DbFqka3P.js +1 -0
  44. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  45. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  46. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  47. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  48. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  49. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  50. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  51. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  52. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  53. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  54. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  55. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  56. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  57. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  58. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  59. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  60. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  61. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  62. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  63. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  64. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  65. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  66. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  67. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  68. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  69. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  70. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  71. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  72. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  73. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  74. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  75. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  76. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  77. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  78. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  79. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  80. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  81. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  82. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  83. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  84. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  85. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  86. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  87. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  88. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  89. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  90. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  91. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  92. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  93. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  94. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  95. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  96. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  97. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  98. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  99. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  100. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  101. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  102. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  103. package/dist/assets/MarkdownRendererImpl-B07lHhBl.js +12 -0
  104. package/dist/assets/PatchDiff-DD9pAs47.js +1 -0
  105. package/dist/assets/PierreDiffViewer-Bo0_BCT7.js +136 -0
  106. package/dist/assets/SessionSwitcherDropdown-t7WZX24f.js +1 -0
  107. package/dist/assets/SettingsView-CtsS4oDI.js +3 -0
  108. package/dist/assets/SettingsWindow-DIRGn3eQ.js +1 -0
  109. package/dist/assets/TerminalView-BV3KOtdA.css +1 -0
  110. package/dist/assets/TerminalView-DUwO1CCY.js +46 -0
  111. package/dist/assets/ToolOutputDialog-iZG2ey4T.js +15 -0
  112. package/dist/assets/ToolPartDiffPreview-FTexlZSz.js +8 -0
  113. package/dist/assets/VirtualizedFileDiff-DD5IznIe.js +10 -0
  114. package/dist/assets/Virtualizer-BxW2CJGB.js +1 -0
  115. package/dist/assets/abap-BdImnpbu.js +1 -0
  116. package/dist/assets/abap-Dg923wIy.js +1 -0
  117. package/dist/assets/actionscript-3-8WTK4YD2.js +1 -0
  118. package/dist/assets/actionscript-3-CoDkCxhg.js +1 -0
  119. package/dist/assets/ada-CTi7YQtL.js +1 -0
  120. package/dist/assets/ada-bCR0ucgS.js +1 -0
  121. package/dist/assets/andromeeda-C4gqWexZ.js +1 -0
  122. package/dist/assets/andromeeda-CT0vplkN.js +1 -0
  123. package/dist/assets/angular-html-CU67Zn6k.js +1 -0
  124. package/dist/assets/angular-html-D2R1pe45.js +1 -0
  125. package/dist/assets/angular-ts-BDmYQnhm.js +1 -0
  126. package/dist/assets/angular-ts-BwZT4LLn.js +1 -0
  127. package/dist/assets/apache-PcO-DBxQ.js +1 -0
  128. package/dist/assets/apache-Pmp26Uib.js +1 -0
  129. package/dist/assets/apex-CnCu5_gb.js +1 -0
  130. package/dist/assets/apex-D8_7TLub.js +1 -0
  131. package/dist/assets/apl-B4CMkyY2.js +1 -0
  132. package/dist/assets/apl-DkfyvC6M.js +1 -0
  133. package/dist/assets/apl-dKokRX4l.js +1 -0
  134. package/dist/assets/appThemeRegistry-BK0dHKa6.js +1 -0
  135. package/dist/assets/applescript-Co6uUVPk.js +1 -0
  136. package/dist/assets/applescript-Ds_W2jPS.js +1 -0
  137. package/dist/assets/ara-BRHolxvo.js +1 -0
  138. package/dist/assets/ara-C1--7J61.js +1 -0
  139. package/dist/assets/asciiarmor-Df11BRmG.js +1 -0
  140. package/dist/assets/asciidoc-Ve4PFQV2.js +1 -0
  141. package/dist/assets/asciidoc-nTfEFGxb.js +1 -0
  142. package/dist/assets/asm-CTFRnVOM.js +1 -0
  143. package/dist/assets/asm-D_Q5rh1f.js +1 -0
  144. package/dist/assets/asn1-EdZsLKOL.js +1 -0
  145. package/dist/assets/asterisk-B-8jnY81.js +1 -0
  146. package/dist/assets/astro-CbQHKStN.js +1 -0
  147. package/dist/assets/astro-DtPAdMss.js +1 -0
  148. package/dist/assets/aurora-x-C0VKFdlO.js +1 -0
  149. package/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
  150. package/dist/assets/awk-CrWgQKhV.js +1 -0
  151. package/dist/assets/awk-DMzUqQB5.js +1 -0
  152. package/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
  153. package/dist/assets/ayu-dark-wZ6ORhBL.js +1 -0
  154. package/dist/assets/ayu-light-BA47KaF1.js +1 -0
  155. package/dist/assets/ayu-light-xXLJ_Ch1.js +1 -0
  156. package/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
  157. package/dist/assets/ayu-mirage-CQckA_sP.js +1 -0
  158. package/dist/assets/ballerina-BFfxhgS-.js +1 -0
  159. package/dist/assets/ballerina-a0yOSyc5.js +1 -0
  160. package/dist/assets/bat-B0cHNp6s.js +1 -0
  161. package/dist/assets/bat-BkioyH1T.js +1 -0
  162. package/dist/assets/beancount-dPJi_gci.js +1 -0
  163. package/dist/assets/beancount-k_qm7-4y.js +1 -0
  164. package/dist/assets/berry-CVKoklHx.js +1 -0
  165. package/dist/assets/berry-uYugtg8r.js +1 -0
  166. package/dist/assets/bibtex-CHM0blh-.js +1 -0
  167. package/dist/assets/bibtex-DRcCXNgM.js +1 -0
  168. package/dist/assets/bicep-Bmn6On1c.js +1 -0
  169. package/dist/assets/bicep-jWz-hQ8I.js +1 -0
  170. package/dist/assets/bird2-DPOp833l.js +1 -0
  171. package/dist/assets/bird2-DaGXIRGu.js +1 -0
  172. package/dist/assets/blade-D4QpJJKB.js +1 -0
  173. package/dist/assets/blade-QlWdzBxO.js +1 -0
  174. package/dist/assets/brainfuck-C4LP7Hcl.js +1 -0
  175. package/dist/assets/bsl-BO_Y6i37.js +1 -0
  176. package/dist/assets/bsl-jNujDQK2.js +1 -0
  177. package/dist/assets/c-BG-tZi7o.js +1 -0
  178. package/dist/assets/c-BIGW1oBm.js +1 -0
  179. package/dist/assets/c3-Fcb8_HKm.js +1 -0
  180. package/dist/assets/c3-eo99z4R2.js +1 -0
  181. package/dist/assets/cadence-BuaeHeSu.js +1 -0
  182. package/dist/assets/cadence-Bv_4Rxtq.js +1 -0
  183. package/dist/assets/cairo-BYiDgOF2.js +1 -0
  184. package/dist/assets/cairo-KRGpt6FW.js +1 -0
  185. package/dist/assets/catppuccin-frappe-CfssSZMA.js +1 -0
  186. package/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  187. package/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  188. package/dist/assets/catppuccin-latte-DoBaWTGn.js +1 -0
  189. package/dist/assets/catppuccin-macchiato-BkAuvdZC.js +1 -0
  190. package/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  191. package/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  192. package/dist/assets/catppuccin-mocha-D9fcC0iT.js +1 -0
  193. package/dist/assets/clarity-CC_0IFDj.js +1 -0
  194. package/dist/assets/clarity-D53aC0YG.js +1 -0
  195. package/dist/assets/clike-B9uivgTg.js +1 -0
  196. package/dist/assets/clojure-BMjYHr_A.js +1 -0
  197. package/dist/assets/clojure-KnfDkB_V.js +1 -0
  198. package/dist/assets/clojure-P80f7IUj.js +1 -0
  199. package/dist/assets/cmake-BQqOBYOt.js +1 -0
  200. package/dist/assets/cmake-D1j8_8rp.js +1 -0
  201. package/dist/assets/cmake-bh2MLnkv.js +1 -0
  202. package/dist/assets/cobol-CWcv1MsR.js +1 -0
  203. package/dist/assets/cobol-dIXRVV9Y.js +1 -0
  204. package/dist/assets/cobol-nwyudZeR.js +1 -0
  205. package/dist/assets/codeowners-Bp6g37R7.js +1 -0
  206. package/dist/assets/codeowners-CtwIM3TN.js +1 -0
  207. package/dist/assets/codeql-D164juXQ.js +1 -0
  208. package/dist/assets/codeql-DsOJ9woJ.js +1 -0
  209. package/dist/assets/coffee-Bk-z6oI_.js +1 -0
  210. package/dist/assets/coffee-Ch7k5sss.js +1 -0
  211. package/dist/assets/coffeescript-S37ZYGWr.js +1 -0
  212. package/dist/assets/collapsible-ODWWxk4f.js +1 -0
  213. package/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
  214. package/dist/assets/common-lisp-DXc9XcIM.js +1 -0
  215. package/dist/assets/commonlisp-DBKNyK5s.js +1 -0
  216. package/dist/assets/computeVirtualFileMetrics-DdXkLFAD.js +3 -0
  217. package/dist/assets/contextFileOpenGuard-uC4OerzL.js +1 -0
  218. package/dist/assets/coq-BBL5-mG4.js +1 -0
  219. package/dist/assets/coq-DkFqJrB1.js +1 -0
  220. package/dist/assets/cpp-C0lzDePx.js +1 -0
  221. package/dist/assets/cpp-CofmeUqb.js +1 -0
  222. package/dist/assets/crystal-Bhade0k2.js +1 -0
  223. package/dist/assets/crystal-SjHAIU92.js +1 -0
  224. package/dist/assets/crystal-tKQVLTB8.js +1 -0
  225. package/dist/assets/csharp-B7nLXyi8.js +1 -0
  226. package/dist/assets/csharp-COcwbKMJ.js +1 -0
  227. package/dist/assets/css-BnMrqG3P.js +1 -0
  228. package/dist/assets/css-DPfMkruS.js +1 -0
  229. package/dist/assets/css-PZBBrkI0.js +1 -0
  230. package/dist/assets/csv-D5aBhKLr.js +1 -0
  231. package/dist/assets/csv-fuZLfV_i.js +1 -0
  232. package/dist/assets/cue-D82EKSYY.js +1 -0
  233. package/dist/assets/cue-WCin6O4e.js +1 -0
  234. package/dist/assets/cypher-COkxafJQ.js +1 -0
  235. package/dist/assets/cypher-C_CwsFkJ.js +1 -0
  236. package/dist/assets/cypher-DYQk2G82.js +1 -0
  237. package/dist/assets/d-85-TOEBH.js +1 -0
  238. package/dist/assets/d-DVc-yF-l.js +1 -0
  239. package/dist/assets/d-pRatUO7H.js +1 -0
  240. package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
  241. package/dist/assets/dark-plus-DLU5INA3.js +1 -0
  242. package/dist/assets/dart-CF10PKvl.js +1 -0
  243. package/dist/assets/dart-YLd5yyRs.js +1 -0
  244. package/dist/assets/dax-CEL-wOlO.js +1 -0
  245. package/dist/assets/dax-oldcCaJg.js +1 -0
  246. package/dist/assets/desktop-BmXAJ9_W.js +1 -0
  247. package/dist/assets/desktop-DZfyBMgF.js +1 -0
  248. package/dist/assets/diff-D97Zzqfu.js +1 -0
  249. package/dist/assets/diff-DbItnlRl.js +1 -0
  250. package/dist/assets/diff-jW5kmiru.js +1 -0
  251. package/dist/assets/docker-BcOcwvcX.js +1 -0
  252. package/dist/assets/docker-DG9neUKd.js +1 -0
  253. package/dist/assets/dockerfile-BKs6k2Af.js +1 -0
  254. package/dist/assets/document-attachments-BslE4Ns7.js +30 -0
  255. package/dist/assets/dotenv-Bea-FkXq.js +1 -0
  256. package/dist/assets/dotenv-Da5cRb03.js +1 -0
  257. package/dist/assets/dracula-BzJJZx-M.js +1 -0
  258. package/dist/assets/dracula-XcYHBZy6.js +1 -0
  259. package/dist/assets/dracula-soft-BPeX9gxW.js +1 -0
  260. package/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
  261. package/dist/assets/dream-maker-BtqSS_iP.js +1 -0
  262. package/dist/assets/dream-maker-DAHQwpwp.js +1 -0
  263. package/dist/assets/dtd-DF_7sFjM.js +1 -0
  264. package/dist/assets/dylan-DwRh75JA.js +1 -0
  265. package/dist/assets/ebnf-CDyGwa7X.js +1 -0
  266. package/dist/assets/ecl-Cabwm37j.js +1 -0
  267. package/dist/assets/edge-BkV0erSs.js +1 -0
  268. package/dist/assets/edge-zt3dU95k.js +1 -0
  269. package/dist/assets/eiffel-CnydiIhH.js +1 -0
  270. package/dist/assets/elixir-CDX3lj18.js +1 -0
  271. package/dist/assets/elixir-JolcG37e.js +1 -0
  272. package/dist/assets/elm-BjIDgKzz.js +1 -0
  273. package/dist/assets/elm-DbKCFpqz.js +1 -0
  274. package/dist/assets/elm-vLlmbW-K.js +1 -0
  275. package/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
  276. package/dist/assets/emacs-lisp-DMBh55R4.js +1 -0
  277. package/dist/assets/erb-B12qg9BL.js +1 -0
  278. package/dist/assets/erb-rsjdL4fB.js +1 -0
  279. package/dist/assets/erlang-BNw1qcRV.js +1 -0
  280. package/dist/assets/erlang-DNeY46SW.js +1 -0
  281. package/dist/assets/erlang-DsQrWhSR.js +1 -0
  282. package/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
  283. package/dist/assets/everforest-dark-WOub3wle.js +1 -0
  284. package/dist/assets/everforest-light-C8M2exoo.js +1 -0
  285. package/dist/assets/everforest-light-DCUg8VH8.js +1 -0
  286. package/dist/assets/factor-kuTfRLto.js +1 -0
  287. package/dist/assets/fcl-Kvtd6kyn.js +1 -0
  288. package/dist/assets/fennel-BYunw83y.js +1 -0
  289. package/dist/assets/fennel-DBMsxtrh.js +1 -0
  290. package/dist/assets/fish-BvzEVeQv.js +1 -0
  291. package/dist/assets/fish-BxskpYPN.js +1 -0
  292. package/dist/assets/fluent-Bwo2XpEt.js +1 -0
  293. package/dist/assets/fluent-C4IJs8-o.js +1 -0
  294. package/dist/assets/forth-Ffai-XNe.js +1 -0
  295. package/dist/assets/fortran-DYz_wnZ1.js +1 -0
  296. package/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  297. package/dist/assets/fortran-fixed-form-DFFnVrrY.js +1 -0
  298. package/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
  299. package/dist/assets/fortran-free-form-DB5N_DgY.js +1 -0
  300. package/dist/assets/fsharp-CXgrBDvD.js +1 -0
  301. package/dist/assets/fsharp-DRAF1jsN.js +1 -0
  302. package/dist/assets/gas-Bneqetm1.js +1 -0
  303. package/dist/assets/gdresource-BD-1uzY7.js +1 -0
  304. package/dist/assets/gdresource-BOOCDP_w.js +1 -0
  305. package/dist/assets/gdscript-C3mT4Uym.js +1 -0
  306. package/dist/assets/gdscript-C5YyOfLZ.js +1 -0
  307. package/dist/assets/gdshader-DkwncUOv.js +1 -0
  308. package/dist/assets/gdshader-G7X6ysY3.js +1 -0
  309. package/dist/assets/genie-D0YGMca9.js +1 -0
  310. package/dist/assets/genie-DSsjfZMX.js +1 -0
  311. package/dist/assets/gherkin-Cl2Fw-_0.js +1 -0
  312. package/dist/assets/gherkin-DyxjwDmM.js +1 -0
  313. package/dist/assets/gherkin-heZmZLOM.js +1 -0
  314. package/dist/assets/git-commit-CJPsQObV.js +1 -0
  315. package/dist/assets/git-commit-F4YmCXRG.js +1 -0
  316. package/dist/assets/git-rebase-DeZqv4fp.js +1 -0
  317. package/dist/assets/git-rebase-r7XF79zn.js +1 -0
  318. package/dist/assets/github-dark-BQV5ugrc.js +1 -0
  319. package/dist/assets/github-dark-DHJKELXO.js +1 -0
  320. package/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
  321. package/dist/assets/github-dark-default-DLWDM7FH.js +1 -0
  322. package/dist/assets/github-dark-dimmed-D1FmiR_p.js +1 -0
  323. package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  324. package/dist/assets/github-dark-high-contrast-BilLoi0o.js +1 -0
  325. package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  326. package/dist/assets/github-light-DAi9KRSo.js +1 -0
  327. package/dist/assets/github-light-Rcb2q3L5.js +1 -0
  328. package/dist/assets/github-light-default-CQ75esMw.js +1 -0
  329. package/dist/assets/github-light-default-D7oLnXFd.js +1 -0
  330. package/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  331. package/dist/assets/github-light-high-contrast-CRF1wyLy.js +1 -0
  332. package/dist/assets/gleam-BeBqoPwE.js +1 -0
  333. package/dist/assets/gleam-BspZqrRM.js +1 -0
  334. package/dist/assets/glimmer-js-BuyKUjfV.js +1 -0
  335. package/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
  336. package/dist/assets/glimmer-ts-D9iniPFN.js +1 -0
  337. package/dist/assets/glimmer-ts-U6CK756n.js +1 -0
  338. package/dist/assets/glsl-BOG9l2nV.js +1 -0
  339. package/dist/assets/glsl-DplSGwfg.js +1 -0
  340. package/dist/assets/gn-Dxr0sSUf.js +1 -0
  341. package/dist/assets/gn-n2N0HUVH.js +1 -0
  342. package/dist/assets/gnuplot-CtW3R_Hz.js +1 -0
  343. package/dist/assets/gnuplot-DdkO51Og.js +1 -0
  344. package/dist/assets/go-BBr2UQCn.js +1 -0
  345. package/dist/assets/go-CxLEBnE3.js +1 -0
  346. package/dist/assets/graphql-B6XHM4uj.js +1 -0
  347. package/dist/assets/graphql-ChdNCCLP.js +1 -0
  348. package/dist/assets/groovy-D9Dt4D0W.js +1 -0
  349. package/dist/assets/groovy-DFxE31Qs.js +1 -0
  350. package/dist/assets/groovy-gcz8RCvz.js +1 -0
  351. package/dist/assets/gruvbox-dark-hard-C37G1gbc.js +1 -0
  352. package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  353. package/dist/assets/gruvbox-dark-medium-C3G9m3TV.js +1 -0
  354. package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  355. package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  356. package/dist/assets/gruvbox-dark-soft-eZmcmZ9I.js +1 -0
  357. package/dist/assets/gruvbox-light-hard-BYj-vz_3.js +1 -0
  358. package/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  359. package/dist/assets/gruvbox-light-medium-BdQlDiiF.js +1 -0
  360. package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  361. package/dist/assets/gruvbox-light-soft-BGNwjiRh.js +1 -0
  362. package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  363. package/dist/assets/hack-CaT9iCJl.js +1 -0
  364. package/dist/assets/hack-Cxa-FaZ4.js +1 -0
  365. package/dist/assets/haml-2e0EI6Is.js +1 -0
  366. package/dist/assets/haml-B8DHNrY2.js +1 -0
  367. package/dist/assets/handlebars-BL8al0AC.js +1 -0
  368. package/dist/assets/handlebars-CojHdNmS.js +1 -0
  369. package/dist/assets/haskell-BfdhR_WN.js +1 -0
  370. package/dist/assets/haskell-Cw1EW3IL.js +1 -0
  371. package/dist/assets/haskell-Df6bDoY_.js +1 -0
  372. package/dist/assets/haxe-CzTSHFRz.js +1 -0
  373. package/dist/assets/haxe-DVIybFAS.js +1 -0
  374. package/dist/assets/haxe-H-WmDvRZ.js +1 -0
  375. package/dist/assets/hcl-B6OePqme.js +1 -0
  376. package/dist/assets/hcl-BWvSN4gD.js +1 -0
  377. package/dist/assets/hjson-D2jn7IRw.js +1 -0
  378. package/dist/assets/hjson-D5-asLiD.js +1 -0
  379. package/dist/assets/hlsl-D3lLCCz7.js +1 -0
  380. package/dist/assets/hlsl-MKeth5V9.js +1 -0
  381. package/dist/assets/horizon-BUw7H-hv.js +1 -0
  382. package/dist/assets/horizon-bright-Cn-bp-IR.js +1 -0
  383. package/dist/assets/horizon-bright-CoQRYDvy.js +1 -0
  384. package/dist/assets/horizon-cslQss18.js +1 -0
  385. package/dist/assets/houston-DnULxvSX.js +1 -0
  386. package/dist/assets/houston-RHIKkNfR.js +1 -0
  387. package/dist/assets/html-DOf0XnR2.js +1 -0
  388. package/dist/assets/html-GMplVEZG.js +1 -0
  389. package/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
  390. package/dist/assets/html-derivative-DfCZ6Hio.js +1 -0
  391. package/dist/assets/http-CG3jvXcS.js +1 -0
  392. package/dist/assets/http-DBlCnlav.js +1 -0
  393. package/dist/assets/http-jrhK8wxY.js +1 -0
  394. package/dist/assets/hurl-CxQrh4RI.js +1 -0
  395. package/dist/assets/hurl-irOxFIW8.js +1 -0
  396. package/dist/assets/hxml-Bvhsp5Yf.js +1 -0
  397. package/dist/assets/hxml-CkS3Eie7.js +1 -0
  398. package/dist/assets/hy-DFXneXwc.js +1 -0
  399. package/dist/assets/hy-DI6mCUnw.js +1 -0
  400. package/dist/assets/idl-BEugSyMb.js +1 -0
  401. package/dist/assets/imba-D-Pk5S0X.js +1 -0
  402. package/dist/assets/imba-DGztddWO.js +1 -0
  403. package/dist/assets/index-CRB7i1S2.js +8 -0
  404. package/dist/assets/index-C_Mo87uS.css +1 -0
  405. package/dist/assets/index-MSKFS67y.js +1 -0
  406. package/dist/assets/ini-BEwlwnbL.js +1 -0
  407. package/dist/assets/ini-Dix3pTmg.js +1 -0
  408. package/dist/assets/isDiffPlainText-CeCQwHA2.js +1 -0
  409. package/dist/assets/isFilePlainText-BcfhE9FH.js +1 -0
  410. package/dist/assets/java-BTDmaRNO.js +1 -0
  411. package/dist/assets/java-CylS5w8V.js +1 -0
  412. package/dist/assets/javascript-BO_2ioGC.js +1 -0
  413. package/dist/assets/javascript-WyGyM1wV.js +1 -0
  414. package/dist/assets/javascript-wDzz0qaB.js +1 -0
  415. package/dist/assets/jinja-4LBKfQ-Z.js +1 -0
  416. package/dist/assets/jinja-D0mZ3q2r.js +1 -0
  417. package/dist/assets/jison-B9XHrcYJ.js +1 -0
  418. package/dist/assets/jison-wvAkD_A8.js +1 -0
  419. package/dist/assets/json-B8JryHcM.js +1 -0
  420. package/dist/assets/json-Cp-IABpG.js +1 -0
  421. package/dist/assets/json5-C9tS-k6U.js +1 -0
  422. package/dist/assets/json5-Cdatmj9n.js +1 -0
  423. package/dist/assets/jsonc-CvUCa1o5.js +1 -0
  424. package/dist/assets/jsonc-Des-eS-w.js +1 -0
  425. package/dist/assets/jsonl-9I_GBd5L.js +1 -0
  426. package/dist/assets/jsonl-DcaNXYhu.js +1 -0
  427. package/dist/assets/jsonnet-DFQXde-d.js +1 -0
  428. package/dist/assets/jsonnet-XoenQ2oc.js +1 -0
  429. package/dist/assets/jssm-C2t-YnRu.js +1 -0
  430. package/dist/assets/jssm-CWE2S0Z5.js +1 -0
  431. package/dist/assets/jsx-8cLv2Six.js +1 -0
  432. package/dist/assets/jsx-g9-lgVsj.js +1 -0
  433. package/dist/assets/julia-C1oINnwa.js +1 -0
  434. package/dist/assets/julia-CxzCAyBv.js +1 -0
  435. package/dist/assets/julia-DuME0IfC.js +1 -0
  436. package/dist/assets/just-Bo3fV9RY.js +1 -0
  437. package/dist/assets/just-Cw27pwNe.js +1 -0
  438. package/dist/assets/kanagawa-dragon-BOvIHJVT.js +1 -0
  439. package/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  440. package/dist/assets/kanagawa-lotus-Bwcd7Bvx.js +1 -0
  441. package/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  442. package/dist/assets/kanagawa-wave-0SAlpf0s.js +1 -0
  443. package/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
  444. package/dist/assets/kdl-CMbyIXjQ.js +1 -0
  445. package/dist/assets/kdl-DV7GczEv.js +1 -0
  446. package/dist/assets/kimi-for-coding-eVEHug_h.svg +3 -0
  447. package/dist/assets/kotlin-BQy537ds.js +1 -0
  448. package/dist/assets/kotlin-BdnUsdx6.js +1 -0
  449. package/dist/assets/kusto-B_y0uMaZ.js +1 -0
  450. package/dist/assets/kusto-DZf3V79B.js +1 -0
  451. package/dist/assets/laserwave-DUszq2jm.js +1 -0
  452. package/dist/assets/laserwave-si7wuSrt.js +1 -0
  453. package/dist/assets/latex-CWtU0Tv5.js +1 -0
  454. package/dist/assets/latex-CZAhoKip.js +1 -0
  455. package/dist/assets/lean-BZvkOJ9d.js +1 -0
  456. package/dist/assets/lean-C4RHkN41.js +1 -0
  457. package/dist/assets/less-B1dDrJ26.js +1 -0
  458. package/dist/assets/less-XNfgnZC7.js +1 -0
  459. package/dist/assets/light-plus-B7mTdjB0.js +1 -0
  460. package/dist/assets/light-plus-g_Fi9vkG.js +1 -0
  461. package/dist/assets/liquid-DFlqVvG0.js +1 -0
  462. package/dist/assets/liquid-DYVedYrR.js +1 -0
  463. package/dist/assets/livescript-BwQOo05w.js +1 -0
  464. package/dist/assets/llmapi-detailed-Pup_107f.svg +28 -0
  465. package/dist/assets/llvm-BJRUtCev.js +1 -0
  466. package/dist/assets/llvm-DjAJT7YJ.js +1 -0
  467. package/dist/assets/log-2UxHyX5q.js +1 -0
  468. package/dist/assets/log-CcaF_xNv.js +1 -0
  469. package/dist/assets/logo-BtOb2qkB.js +1 -0
  470. package/dist/assets/logo-D9WQLoKQ.js +1 -0
  471. package/dist/assets/lua-8Av-h-ns.js +1 -0
  472. package/dist/assets/lua-BaeVxFsk.js +1 -0
  473. package/dist/assets/lua-BgMRiT3U.js +1 -0
  474. package/dist/assets/luau-BTSFCcFb.js +1 -0
  475. package/dist/assets/luau-C-HG3fhB.js +1 -0
  476. package/dist/assets/main-CPygRDd9.js +134 -0
  477. package/dist/assets/main-DZg4qzOe.js +2 -0
  478. package/dist/assets/make-CHLpvVh8.js +1 -0
  479. package/dist/assets/make-DXVx14cr.js +1 -0
  480. package/dist/assets/markdown-Cvjx9yec.js +1 -0
  481. package/dist/assets/markdown-DX-TNHnc.js +1 -0
  482. package/dist/assets/markdown-shiki.worker-DnvH1S1x.js +12 -0
  483. package/dist/assets/markdownCore-BULtt6Xa.js +2 -0
  484. package/dist/assets/marko-CnJfTvn9.js +1 -0
  485. package/dist/assets/marko-DiIoNBFw.js +1 -0
  486. package/dist/assets/material-theme-CIJ3cGaW.js +1 -0
  487. package/dist/assets/material-theme-D5KoaKCx.js +1 -0
  488. package/dist/assets/material-theme-darker-BWg3m1GB.js +1 -0
  489. package/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
  490. package/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  491. package/dist/assets/material-theme-lighter-DR8HWMN7.js +1 -0
  492. package/dist/assets/material-theme-ocean-CZf9pk28.js +1 -0
  493. package/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
  494. package/dist/assets/material-theme-palenight-BF01YeZy.js +1 -0
  495. package/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  496. package/dist/assets/mathematica-DTrFuWx2.js +1 -0
  497. package/dist/assets/matlab-D7o27uSR.js +1 -0
  498. package/dist/assets/matlab-DzreyMvm.js +1 -0
  499. package/dist/assets/mbox-CNhZ1qSd.js +1 -0
  500. package/dist/assets/mdc-BMNejdWA.js +1 -0
  501. package/dist/assets/mdc-D_DpLax5.js +1 -0
  502. package/dist/assets/mdx-C2fqO2XY.js +1 -0
  503. package/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  504. package/dist/assets/mermaid-Cwy4Up_p.js +1 -0
  505. package/dist/assets/mermaid-mWjccvbQ.js +1 -0
  506. package/dist/assets/min-dark-CafNBF8u.js +1 -0
  507. package/dist/assets/min-dark-DhfaepVE.js +1 -0
  508. package/dist/assets/min-light-6xx0uMgm.js +1 -0
  509. package/dist/assets/min-light-CTRr51gU.js +1 -0
  510. package/dist/assets/miniChat-BFotDgpO.js +2 -0
  511. package/dist/assets/mipsasm-CKIfxQSi.js +1 -0
  512. package/dist/assets/mipsasm-yE_Aqo9y.js +1 -0
  513. package/dist/assets/mirc-CjQqDB4T.js +1 -0
  514. package/dist/assets/mllike-BO34x3tv.js +1 -0
  515. package/dist/assets/mobile-3LLzhN5Q.js +2 -0
  516. package/dist/assets/modelica-Dc1JOy9r.js +1 -0
  517. package/dist/assets/mojo-M6pJPbMk.js +1 -0
  518. package/dist/assets/mojo-rZm6bMo-.js +1 -0
  519. package/dist/assets/monokai-BodnsaDQ.js +1 -0
  520. package/dist/assets/monokai-D4h5O-jR.js +1 -0
  521. package/dist/assets/moonbit-CR8uFLGd.js +1 -0
  522. package/dist/assets/moonbit-_H4v1dQx.js +1 -0
  523. package/dist/assets/move-CyYMWVy5.js +1 -0
  524. package/dist/assets/move-IF9eRakj.js +1 -0
  525. package/dist/assets/mscgen-BA5vi2Kp.js +1 -0
  526. package/dist/assets/mumps-BT43cFF4.js +1 -0
  527. package/dist/assets/narrat-DRg8JJMk.js +1 -0
  528. package/dist/assets/narrat-DXUZ_ZkW.js +1 -0
  529. package/dist/assets/nextflow-BPolriEg.js +1 -0
  530. package/dist/assets/nextflow-Zz6hmt5N.js +1 -0
  531. package/dist/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  532. package/dist/assets/nextflow-groovy-pQRwk_Jg.js +1 -0
  533. package/dist/assets/nginx-BpAMiNFr.js +1 -0
  534. package/dist/assets/nginx-DSXkacNc.js +1 -0
  535. package/dist/assets/nginx-DdIZxoE0.js +1 -0
  536. package/dist/assets/night-owl-C39BiMTA.js +1 -0
  537. package/dist/assets/night-owl-EdP2Hztp.js +1 -0
  538. package/dist/assets/night-owl-light-Bk-lYVyk.js +1 -0
  539. package/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
  540. package/dist/assets/nim-CVrawwO9.js +1 -0
  541. package/dist/assets/nim-e2z2kCcq.js +1 -0
  542. package/dist/assets/nix-Ckjrpg0r.js +1 -0
  543. package/dist/assets/nix-CwoSXNpI.js +1 -0
  544. package/dist/assets/nord-BAu0wM6c.js +1 -0
  545. package/dist/assets/nord-Ddv68eIx.js +1 -0
  546. package/dist/assets/nsis-LdVXkNf5.js +1 -0
  547. package/dist/assets/ntriples-BfvgReVJ.js +1 -0
  548. package/dist/assets/nushell-Cz2AlsmD.js +1 -0
  549. package/dist/assets/nushell-DtHLcZf1.js +1 -0
  550. package/dist/assets/objective-c-BoaBTdtz.js +1 -0
  551. package/dist/assets/objective-c-DXmwc3jG.js +1 -0
  552. package/dist/assets/objective-cpp-CLxacb5B.js +1 -0
  553. package/dist/assets/objective-cpp-DstR8hNy.js +1 -0
  554. package/dist/assets/ocaml-C0hk2d4L.js +1 -0
  555. package/dist/assets/ocaml-DTbn2Hv7.js +1 -0
  556. package/dist/assets/octave-CWZ4xMHY.js +1 -0
  557. package/dist/assets/odin-BBf5iR-q.js +1 -0
  558. package/dist/assets/odin-Bxc4S6Xn.js +1 -0
  559. package/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  560. package/dist/assets/one-dark-pro-utPxbBbJ.js +1 -0
  561. package/dist/assets/one-light-BuCQ22aO.js +1 -0
  562. package/dist/assets/one-light-C3Wv6jpd.js +1 -0
  563. package/dist/assets/openscad-C4EeE6gA.js +1 -0
  564. package/dist/assets/openscad-CXHpNBsb.js +1 -0
  565. package/dist/assets/oz-BzwKVEFT.js +1 -0
  566. package/dist/assets/pascal--L3eBynH.js +1 -0
  567. package/dist/assets/pascal-D93ZcfNL.js +1 -0
  568. package/dist/assets/pascal-Sr-XLSE6.js +1 -0
  569. package/dist/assets/perl-C0TMdlhV.js +1 -0
  570. package/dist/assets/perl-C95KruZl.js +1 -0
  571. package/dist/assets/perl-CdXCOZ3F.js +1 -0
  572. package/dist/assets/permissionStore-BRcQ9Jgt.js +1 -0
  573. package/dist/assets/php-B4Kqya17.js +1 -0
  574. package/dist/assets/php-Dhbhpdrm.js +1 -0
  575. package/dist/assets/pig-CevX1Tat.js +1 -0
  576. package/dist/assets/pkl-CRusufhw.js +1 -0
  577. package/dist/assets/pkl-u5AG7uiY.js +1 -0
  578. package/dist/assets/plastic-3e1v2bzS.js +1 -0
  579. package/dist/assets/plastic-CXnNNlFZ.js +1 -0
  580. package/dist/assets/plsql-ChMvpjG-.js +1 -0
  581. package/dist/assets/plsql-Dbm3tV2N.js +1 -0
  582. package/dist/assets/po-BTJTHyun.js +1 -0
  583. package/dist/assets/po-LG0lFwH4.js +1 -0
  584. package/dist/assets/poimandres-BrOVMvuE.js +1 -0
  585. package/dist/assets/poimandres-CS3Unz2-.js +1 -0
  586. package/dist/assets/polar-C0HS_06l.js +1 -0
  587. package/dist/assets/polar-DjOs3GWb.js +1 -0
  588. package/dist/assets/postcss-CXtECtnM.js +1 -0
  589. package/dist/assets/postcss-GRRkWn2F.js +1 -0
  590. package/dist/assets/powerquery-CEu0bR-o.js +1 -0
  591. package/dist/assets/powerquery-DHf-dtTS.js +1 -0
  592. package/dist/assets/powershell-CFHJl5sT.js +1 -0
  593. package/dist/assets/powershell-DXrKVo3G.js +1 -0
  594. package/dist/assets/powershell-Dpen1YoG.js +1 -0
  595. package/dist/assets/prisma-Dd19v3D-.js +1 -0
  596. package/dist/assets/prisma-Dgf8IN_C.js +1 -0
  597. package/dist/assets/prolog-9JcfiY6I.js +1 -0
  598. package/dist/assets/prolog-CbFg5uaA.js +1 -0
  599. package/dist/assets/properties-C78fOPTZ.js +1 -0
  600. package/dist/assets/proto-C7zT0LnQ.js +1 -0
  601. package/dist/assets/proto-dqx_Sj2i.js +1 -0
  602. package/dist/assets/protobuf-ChK-085T.js +1 -0
  603. package/dist/assets/pug-CGlum2m_.js +1 -0
  604. package/dist/assets/pug-CIGw5rlb.js +1 -0
  605. package/dist/assets/pug-CoOVtr4u.js +1 -0
  606. package/dist/assets/puppet-BMWR74SV.js +1 -0
  607. package/dist/assets/puppet-DMA9R1ak.js +1 -0
  608. package/dist/assets/puppet-Di57VbSS.js +1 -0
  609. package/dist/assets/purescript-BgpM7rDH.js +1 -0
  610. package/dist/assets/purescript-CklMAg4u.js +1 -0
  611. package/dist/assets/python-B6Ihcp-E.js +1 -0
  612. package/dist/assets/python-B6aJPvgy.js +1 -0
  613. package/dist/assets/python-Cso5vRIg.js +1 -0
  614. package/dist/assets/q-pXgVlZs6.js +1 -0
  615. package/dist/assets/qml-3beO22l8.js +1 -0
  616. package/dist/assets/qml-DmGQGbca.js +1 -0
  617. package/dist/assets/qmldir-C8lEn-DE.js +1 -0
  618. package/dist/assets/qmldir-DXd9s5XC.js +1 -0
  619. package/dist/assets/qss-B7NnhfIi.js +1 -0
  620. package/dist/assets/qss-IeuSbFQv.js +1 -0
  621. package/dist/assets/r-1ts4xG1r.js +1 -0
  622. package/dist/assets/r-B6wPVr8A.js +1 -0
  623. package/dist/assets/r-Dspwwk_N.js +1 -0
  624. package/dist/assets/racket-BqYA7rlc.js +1 -0
  625. package/dist/assets/racket-CeDx7KO2.js +1 -0
  626. package/dist/assets/raku-BMJwmrCS.js +1 -0
  627. package/dist/assets/raku-DXvB9xmW.js +1 -0
  628. package/dist/assets/razor-BaMsy-R7.js +1 -0
  629. package/dist/assets/razor-Uh8Bk_45.js +1 -0
  630. package/dist/assets/red-DR6ZwibK.js +1 -0
  631. package/dist/assets/red-bN70gL4F.js +1 -0
  632. package/dist/assets/reg-C-SQnVFl.js +1 -0
  633. package/dist/assets/reg-Cvyu2Gnx.js +1 -0
  634. package/dist/assets/regexp-CDVJQ6XC.js +1 -0
  635. package/dist/assets/regexp-DK-WlHNu.js +1 -0
  636. package/dist/assets/registerCustomTheme-BBXUCRnG.js +1 -0
  637. package/dist/assets/rel-BlqNHz8k.js +1 -0
  638. package/dist/assets/rel-C3B-1QV4.js +1 -0
  639. package/dist/assets/renderElectronMiniChatApp-DGmmT9Wf.js +1 -0
  640. package/dist/assets/renderMobileApp-Dd8P9hvM.js +23 -0
  641. package/dist/assets/riscv-BM1_JUlF.js +1 -0
  642. package/dist/assets/riscv-C5dpdlr7.js +1 -0
  643. package/dist/assets/ron-D8l8udqQ.js +1 -0
  644. package/dist/assets/ron-j5NfrB3z.js +1 -0
  645. package/dist/assets/rose-pine-CN2F2lJl.js +1 -0
  646. package/dist/assets/rose-pine-dawn-0S8NEhsA.js +1 -0
  647. package/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  648. package/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  649. package/dist/assets/rose-pine-moon-DzBDT4rc.js +1 -0
  650. package/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
  651. package/dist/assets/rosmsg-BJDFO7_C.js +1 -0
  652. package/dist/assets/rosmsg-ZkSIzPhc.js +1 -0
  653. package/dist/assets/rpm-CTu-6PCP.js +1 -0
  654. package/dist/assets/rst-BrH8l1NY.js +1 -0
  655. package/dist/assets/rst-C371KPjr.js +1 -0
  656. package/dist/assets/ruby-B2Rjki9n.js +1 -0
  657. package/dist/assets/ruby-DusoydGj.js +1 -0
  658. package/dist/assets/ruby-Dw2BHqvy.js +1 -0
  659. package/dist/assets/runtimeSurface-Cnqjhb6Y.js +1 -0
  660. package/dist/assets/rust-B1yitclQ.js +1 -0
  661. package/dist/assets/rust-CxuBE0J8.js +1 -0
  662. package/dist/assets/sas-B4kiWyti.js +1 -0
  663. package/dist/assets/sas-DtSHuIwI.js +1 -0
  664. package/dist/assets/sas-cz2c8ADy.js +1 -0
  665. package/dist/assets/sass-Cj5Yp3dK.js +1 -0
  666. package/dist/assets/sass-bfEVHPJ8.js +1 -0
  667. package/dist/assets/scala-C151Ov-r.js +1 -0
  668. package/dist/assets/scala-Dtw19ca_.js +1 -0
  669. package/dist/assets/scheme-C41bIUwD.js +1 -0
  670. package/dist/assets/scheme-C98Dy4si.js +1 -0
  671. package/dist/assets/scheme-OJppFQF3.js +1 -0
  672. package/dist/assets/scss-DxBkwadj.js +1 -0
  673. package/dist/assets/scss-OYdSNvt2.js +1 -0
  674. package/dist/assets/sdbl-CvZs3G9c.js +1 -0
  675. package/dist/assets/sdbl-DVxCFoDh.js +1 -0
  676. package/dist/assets/shaderlab-CEJedz68.js +1 -0
  677. package/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
  678. package/dist/assets/shellscript-DgJyDXW6.js +1 -0
  679. package/dist/assets/shellscript-Yzrsuije.js +1 -0
  680. package/dist/assets/shellsession-BADoaaVG.js +1 -0
  681. package/dist/assets/shellsession-DSlzxnCM.js +1 -0
  682. package/dist/assets/sieve-C3Gn_uJK.js +1 -0
  683. package/dist/assets/simple-mode-GW_nhZxv.js +1 -0
  684. package/dist/assets/slack-dark-BthQWCQV.js +1 -0
  685. package/dist/assets/slack-dark-CWRQmTmo.js +1 -0
  686. package/dist/assets/slack-ochin-DO_ok7XK.js +1 -0
  687. package/dist/assets/slack-ochin-DqwNpetd.js +1 -0
  688. package/dist/assets/smalltalk-B9IHbYt7.js +1 -0
  689. package/dist/assets/smalltalk-BERRCDM3.js +1 -0
  690. package/dist/assets/smalltalk-CnHTOXQT.js +1 -0
  691. package/dist/assets/snazzy-light-B5llO_gK.js +1 -0
  692. package/dist/assets/snazzy-light-Bw305WKR.js +1 -0
  693. package/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
  694. package/dist/assets/solarized-dark-G9yBjKj_.js +1 -0
  695. package/dist/assets/solarized-light-DeSzljQz.js +1 -0
  696. package/dist/assets/solarized-light-L9t79GZl.js +1 -0
  697. package/dist/assets/solidity-B3CjIuAd.js +1 -0
  698. package/dist/assets/solidity-rGO070M0.js +1 -0
  699. package/dist/assets/solr-DehyRSwq.js +1 -0
  700. package/dist/assets/soy-BSb8SaP0.js +1 -0
  701. package/dist/assets/soy-Brmx7dQM.js +1 -0
  702. package/dist/assets/sparql-BJh4JEw-.js +1 -0
  703. package/dist/assets/sparql-DkYu6x3z.js +1 -0
  704. package/dist/assets/sparql-rVzFXLq3.js +1 -0
  705. package/dist/assets/splunk-BtCnVYZw.js +1 -0
  706. package/dist/assets/splunk-h-bNAnbk.js +1 -0
  707. package/dist/assets/spreadsheet-BCZA_wO0.js +1 -0
  708. package/dist/assets/sql-BLtJtn59.js +1 -0
  709. package/dist/assets/sql-BbONfI8K.js +1 -0
  710. package/dist/assets/sql-D0XecflT.js +1 -0
  711. package/dist/assets/ssh-config-CywOjoXH.js +1 -0
  712. package/dist/assets/ssh-config-_ykCGR6B.js +1 -0
  713. package/dist/assets/stata-BH5u7GGu.js +1 -0
  714. package/dist/assets/stata-BKjsT8qe.js +1 -0
  715. package/dist/assets/stex-C3f8Ysf7.js +1 -0
  716. package/dist/assets/stylus-B533Al4x.js +1 -0
  717. package/dist/assets/stylus-BEDo0Tqx.js +1 -0
  718. package/dist/assets/stylus-CIg617SB.js +1 -0
  719. package/dist/assets/surrealql-2KNEnAt7.js +1 -0
  720. package/dist/assets/surrealql-Bq5Q-fJD.js +1 -0
  721. package/dist/assets/svelte-C_ipcX3V.js +1 -0
  722. package/dist/assets/svelte-xaxjcSSP.js +1 -0
  723. package/dist/assets/swift-BzpIVaGY.js +1 -0
  724. package/dist/assets/swift-D82vCrfD.js +1 -0
  725. package/dist/assets/swift-tEesUtni.js +1 -0
  726. package/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
  727. package/dist/assets/synthwave-84-DRVv-_m_.js +1 -0
  728. package/dist/assets/system-verilog-CnnmHF94.js +1 -0
  729. package/dist/assets/system-verilog-Qdm_1g2q.js +1 -0
  730. package/dist/assets/systemd-4A_iFExJ.js +1 -0
  731. package/dist/assets/systemd-DKMPPZjB.js +1 -0
  732. package/dist/assets/talonscript-CkByrt1z.js +1 -0
  733. package/dist/assets/talonscript-eRuyeYHl.js +1 -0
  734. package/dist/assets/tasl-B9CVvjfG.js +1 -0
  735. package/dist/assets/tasl-QIJgUcNo.js +1 -0
  736. package/dist/assets/tcl-Bq9dbVAF.js +1 -0
  737. package/dist/assets/tcl-DVfN8rqt.js +1 -0
  738. package/dist/assets/tcl-dwOrl1Do.js +1 -0
  739. package/dist/assets/templ-BVTOctZ7.js +1 -0
  740. package/dist/assets/templ-P3uqSqPl.js +1 -0
  741. package/dist/assets/terraform-BETggiCN.js +1 -0
  742. package/dist/assets/terraform-CAp711iT.js +1 -0
  743. package/dist/assets/tex-BHxF5DMe.js +1 -0
  744. package/dist/assets/tex-idrVyKtj.js +1 -0
  745. package/dist/assets/textile-CnDTJFAw.js +1 -0
  746. package/dist/assets/themeResolver-BmJyTmjJ.js +1 -0
  747. package/dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  748. package/dist/assets/tiki-DGYXhP31.js +1 -0
  749. package/dist/assets/tokyo-night-BvwC8l2v.js +1 -0
  750. package/dist/assets/tokyo-night-hegEt444.js +1 -0
  751. package/dist/assets/toml-Bm5Em-hy.js +1 -0
  752. package/dist/assets/toml-Ms459DBw.js +1 -0
  753. package/dist/assets/toml-vGWfd6FD.js +1 -0
  754. package/dist/assets/troff-wAsdV37c.js +1 -0
  755. package/dist/assets/ts-tags-C-gylFal.js +1 -0
  756. package/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
  757. package/dist/assets/tsv-BFtm7NXx.js +1 -0
  758. package/dist/assets/tsv-B_m7g4N7.js +1 -0
  759. package/dist/assets/tsx-COt5Ahok.js +1 -0
  760. package/dist/assets/tsx-D6116Ycy.js +1 -0
  761. package/dist/assets/ttcn-CfJYG6tj.js +1 -0
  762. package/dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  763. package/dist/assets/turtle-B1tBg_DP.js +1 -0
  764. package/dist/assets/turtle-BsS91CYL.js +1 -0
  765. package/dist/assets/turtle-DpRhbQZY.js +1 -0
  766. package/dist/assets/twig-DNn4PbVi.js +1 -0
  767. package/dist/assets/twig-DuP5mDZ4.js +1 -0
  768. package/dist/assets/typescript-BPQ3VLAy.js +1 -0
  769. package/dist/assets/typescript-BqvgUolh.js +1 -0
  770. package/dist/assets/typespec-BGHnOYBU.js +1 -0
  771. package/dist/assets/typespec-DhK7u29_.js +1 -0
  772. package/dist/assets/typst-DHCkPAjA.js +1 -0
  773. package/dist/assets/typst-Dfd71gQj.js +1 -0
  774. package/dist/assets/useAppFontEffects-DXASDavv.js +7043 -0
  775. package/dist/assets/useInlineCommentController-KJFe98HG.js +2 -0
  776. package/dist/assets/useOpenInAppsStore-DHAeT9zx.js +1 -0
  777. package/dist/assets/useWindowTitle-BcwmWC0M.js +10 -0
  778. package/dist/assets/v-BH76v7br.js +1 -0
  779. package/dist/assets/v-BcVCzyr7.js +1 -0
  780. package/dist/assets/vala-CsfeWuGM.js +1 -0
  781. package/dist/assets/vala-z59IxkFd.js +1 -0
  782. package/dist/assets/vb-4AxSLKIU.js +1 -0
  783. package/dist/assets/vb-CmGdzxic.js +1 -0
  784. package/dist/assets/vb-D17OF-Vu.js +1 -0
  785. package/dist/assets/vbscript-BuJXcnF6.js +1 -0
  786. package/dist/assets/velocity-D8B20fx6.js +1 -0
  787. package/dist/assets/vendor-aparajita-capacitor-secure-storage-5IShChL0.js +1 -0
  788. package/dist/assets/vendor-aria-hidden-DvXkyWUv.js +1 -0
  789. package/dist/assets/vendor-base-ui-DwfTg5wD.js +1 -0
  790. package/dist/assets/vendor-beautiful-mermaid-r4GK_usS.js +119 -0
  791. package/dist/assets/vendor-capacitor-app-BrDJj9I_.js +1 -0
  792. package/dist/assets/vendor-capacitor-core-B4EWRrHz.js +1 -0
  793. package/dist/assets/vendor-capacitor-keyboard-CYccoJjr.js +1 -0
  794. package/dist/assets/vendor-capacitor-push-notifications-KNe1zSBF.js +1 -0
  795. package/dist/assets/vendor-capacitor-status-bar-B-N0EOVk.js +1 -0
  796. package/dist/assets/vendor-ccount-c2V3InAJ.js +1 -0
  797. package/dist/assets/vendor-character-entities-html4-D7taRCQ7.js +1 -0
  798. package/dist/assets/vendor-character-entities-legacy-BpoLgcEt.js +1 -0
  799. package/dist/assets/vendor-class-variance-authority-5VPnzWs2.js +1 -0
  800. package/dist/assets/vendor-clsx-B-dksMZM.js +1 -0
  801. package/dist/assets/vendor-cmdk-BCEUzcHE.js +1 -0
  802. package/dist/assets/vendor-codemirror-autocomplete-3xMyV7a2.js +1 -0
  803. package/dist/assets/vendor-codemirror-commands-Bzf12ODH.js +1 -0
  804. package/dist/assets/vendor-codemirror-lang-angular-0K6s6cvb.js +1 -0
  805. package/dist/assets/vendor-codemirror-lang-cpp-B0aL03z-.js +1 -0
  806. package/dist/assets/vendor-codemirror-lang-css-C4jEScp7.js +1 -0
  807. package/dist/assets/vendor-codemirror-lang-go-CgrfVBPr.js +7 -0
  808. package/dist/assets/vendor-codemirror-lang-html-C1Svvdey.js +1 -0
  809. package/dist/assets/vendor-codemirror-lang-java-DNPz7_Bx.js +1 -0
  810. package/dist/assets/vendor-codemirror-lang-javascript-CrbeaEAU.js +13 -0
  811. package/dist/assets/vendor-codemirror-lang-jinja-DL8BR_RG.js +1 -0
  812. package/dist/assets/vendor-codemirror-lang-json-BTvAjwkJ.js +1 -0
  813. package/dist/assets/vendor-codemirror-lang-less-CPABt6NZ.js +1 -0
  814. package/dist/assets/vendor-codemirror-lang-liquid-BLOLOBMg.js +1 -0
  815. package/dist/assets/vendor-codemirror-lang-markdown-BloD9GN-.js +1 -0
  816. package/dist/assets/vendor-codemirror-lang-php-FIZMTuWM.js +1 -0
  817. package/dist/assets/vendor-codemirror-lang-python-CR2g6ukK.js +3 -0
  818. package/dist/assets/vendor-codemirror-lang-rust-lsPqn4k4.js +1 -0
  819. package/dist/assets/vendor-codemirror-lang-sass-CtECMwzH.js +1 -0
  820. package/dist/assets/vendor-codemirror-lang-sql-BtmZrrZH.js +2 -0
  821. package/dist/assets/vendor-codemirror-lang-vue-Br6DrntY.js +1 -0
  822. package/dist/assets/vendor-codemirror-lang-wast-DT7IlCnb.js +1 -0
  823. package/dist/assets/vendor-codemirror-lang-xml-wNr-LZOf.js +1 -0
  824. package/dist/assets/vendor-codemirror-lang-yaml-BTKFwfc2.js +1 -0
  825. package/dist/assets/vendor-codemirror-language-BuDklWi8.js +3 -0
  826. package/dist/assets/vendor-codemirror-language-data-CFVH0pe8.js +2 -0
  827. package/dist/assets/vendor-codemirror-search-BzyfPoRb.js +2 -0
  828. package/dist/assets/vendor-codemirror-state-Wdz6Qsow.js +5 -0
  829. package/dist/assets/vendor-codemirror-view-pXtfpqbT.js +4 -0
  830. package/dist/assets/vendor-comma-separated-tokens-D8TqSuIK.js +1 -0
  831. package/dist/assets/vendor-crelt-C8TCjufn.js +1 -0
  832. package/dist/assets/vendor-detect-node-es-l0sNRNKZ.js +1 -0
  833. package/dist/assets/vendor-diff-C3JhlQdm.js +13 -0
  834. package/dist/assets/vendor-dijkstrajs-COg3n3zL.js +1 -0
  835. package/dist/assets/vendor-dnd-kit-accessibility-Cv52zwWT.js +1 -0
  836. package/dist/assets/vendor-dnd-kit-core-GipZW2tY.js +5 -0
  837. package/dist/assets/vendor-dnd-kit-sortable-Ct2QxIHb.js +1 -0
  838. package/dist/assets/vendor-dnd-kit-utilities-CrOcp0Bp.js +1 -0
  839. package/dist/assets/vendor-dompurify-r8glNMJW.js +2 -0
  840. package/dist/assets/vendor-elkjs-CRCLNXjf.js +24 -0
  841. package/dist/assets/vendor-entities-C3BA0AJP.js +1 -0
  842. package/dist/assets/vendor-fflate-C7GOKjkv.js +1 -0
  843. package/dist/assets/vendor-floating-ui-core-CXmKXOXc.js +1 -0
  844. package/dist/assets/vendor-floating-ui-dom-Bkw82kL9.js +1 -0
  845. package/dist/assets/vendor-floating-ui-react-dom-sVFnuruh.js +1 -0
  846. package/dist/assets/vendor-floating-ui-utils-BzXdqYpP.js +1 -0
  847. package/dist/assets/vendor-framer-motion-DJASDzNt.js +1 -0
  848. package/dist/assets/vendor-fuse.js-Dw8P0qyA.js +1 -0
  849. package/dist/assets/vendor-get-nonce-C-Z93AgS.js +1 -0
  850. package/dist/assets/vendor-ghostty-web-CrxinGGH.js +13 -0
  851. package/dist/assets/vendor-hast-util-to-html-BKBhbTDb.js +9 -0
  852. package/dist/assets/vendor-hast-util-whitespace-D4Wp6AEg.js +1 -0
  853. package/dist/assets/vendor-heic2any-L8hyfc24.js +66 -0
  854. package/dist/assets/vendor-html-to-image-BeoRn2gJ.js +2 -0
  855. package/dist/assets/vendor-html-void-elements-CkdplsNl.js +1 -0
  856. package/dist/assets/vendor-katex-CHD9BdDO.js +257 -0
  857. package/dist/assets/vendor-katex-Cp579UoJ.css +1 -0
  858. package/dist/assets/vendor-lezer-common-B3-cUCR_.js +1 -0
  859. package/dist/assets/vendor-lezer-cpp-BleAU9o-.js +1 -0
  860. package/dist/assets/vendor-lezer-css-C5xB6jxd.js +1 -0
  861. package/dist/assets/vendor-lezer-go-CXK1UKk8.js +1 -0
  862. package/dist/assets/vendor-lezer-highlight-CDMHUZ74.js +1 -0
  863. package/dist/assets/vendor-lezer-html-C0I1p52t.js +1 -0
  864. package/dist/assets/vendor-lezer-java-D_zzj-NV.js +1 -0
  865. package/dist/assets/vendor-lezer-javascript-D7Tj24ot.js +1 -0
  866. package/dist/assets/vendor-lezer-json-Iaex0UN-.js +1 -0
  867. package/dist/assets/vendor-lezer-lr-bhwg1HMg.js +1 -0
  868. package/dist/assets/vendor-lezer-markdown-C6g-d6P3.js +6 -0
  869. package/dist/assets/vendor-lezer-php-_DHrbsZG.js +1 -0
  870. package/dist/assets/vendor-lezer-python-CvuFxeZl.js +1 -0
  871. package/dist/assets/vendor-lezer-rust-Lqgd5SAo.js +1 -0
  872. package/dist/assets/vendor-lezer-sass-Dnm2lY4t.js +1 -0
  873. package/dist/assets/vendor-lezer-xml-hUDuAyS5.js +1 -0
  874. package/dist/assets/vendor-lezer-yaml-BNIl6S_O.js +1 -0
  875. package/dist/assets/vendor-lru_map-B-cPXHXW.js +1 -0
  876. package/dist/assets/vendor-marijn-find-cluster-break-DXwl3gUT.js +1 -0
  877. package/dist/assets/vendor-marked-i_gIkIP3.js +59 -0
  878. package/dist/assets/vendor-morphdom-B7dS_VPB.js +1 -0
  879. package/dist/assets/vendor-motion-dom-DJLgZh4Q.js +1 -0
  880. package/dist/assets/vendor-motion-l0sNRNKZ.js +1 -0
  881. package/dist/assets/vendor-motion-utils-BGh8QBgx.js +1 -0
  882. package/dist/assets/vendor-oniguruma-parser-C0D4_9rT.js +33 -0
  883. package/dist/assets/vendor-oniguruma-to-es-DLBnFDCE.js +94 -0
  884. package/dist/assets/vendor-pierre-theme-Bp7SdUL6.js +1 -0
  885. package/dist/assets/vendor-pierre-theming-C6Z4M5_u.js +1 -0
  886. package/dist/assets/vendor-property-information-rJCbAzvX.js +1 -0
  887. package/dist/assets/vendor-qrcode-COsmt6jn.js +8 -0
  888. package/dist/assets/vendor-radix-ui-primitive-Dc_FVRD7.js +1 -0
  889. package/dist/assets/vendor-radix-ui-react-compose-refs-D1GnwnP9.js +1 -0
  890. package/dist/assets/vendor-radix-ui-react-context-CM4yFQ2I.js +1 -0
  891. package/dist/assets/vendor-radix-ui-react-dialog-jX3Dld8c.js +5 -0
  892. package/dist/assets/vendor-radix-ui-react-dismissable-layer-M7LsH3yL.js +1 -0
  893. package/dist/assets/vendor-radix-ui-react-focus-guards-D5MZ0nQs.js +1 -0
  894. package/dist/assets/vendor-radix-ui-react-focus-scope-C2K7lNPv.js +1 -0
  895. package/dist/assets/vendor-radix-ui-react-id-BcxRjnbX.js +1 -0
  896. package/dist/assets/vendor-radix-ui-react-portal-xlJWBfDg.js +1 -0
  897. package/dist/assets/vendor-radix-ui-react-presence-Btn-Dp7L.js +1 -0
  898. package/dist/assets/vendor-radix-ui-react-primitive-CfpW6_IT.js +1 -0
  899. package/dist/assets/vendor-radix-ui-react-slot-BxUc3Pvz.js +1 -0
  900. package/dist/assets/vendor-radix-ui-react-use-callback-ref-UKEWHtoP.js +1 -0
  901. package/dist/assets/vendor-radix-ui-react-use-controllable-state-C_ecoh35.js +1 -0
  902. package/dist/assets/vendor-radix-ui-react-use-effect-event-DkJl_Rn_.js +1 -0
  903. package/dist/assets/vendor-radix-ui-react-use-escape-keydown-Co13lHGj.js +1 -0
  904. package/dist/assets/vendor-radix-ui-react-use-layout-effect-0fyGwS2_.js +1 -0
  905. package/dist/assets/vendor-react-DYyjh7Q0.js +9 -0
  906. package/dist/assets/vendor-react-drawio-Boqanm0j.js +1 -0
  907. package/dist/assets/vendor-react-remove-scroll-CfeMe0DL.js +4 -0
  908. package/dist/assets/vendor-react-remove-scroll-bar-C9YRs2nU.js +38 -0
  909. package/dist/assets/vendor-react-style-singleton-B1H4bWSG.js +1 -0
  910. package/dist/assets/vendor-regex-BBWcyTkg.js +16 -0
  911. package/dist/assets/vendor-regex-recursion-JU4mF-dD.js +1 -0
  912. package/dist/assets/vendor-regex-utilities-2BQyy0xI.js +1 -0
  913. package/dist/assets/vendor-remend-BWYYytN3.js +22 -0
  914. package/dist/assets/vendor-remixicon-react-CzPq62YO.js +1 -0
  915. package/dist/assets/vendor-replit-codemirror-vim-BUqe2Slv.js +39 -0
  916. package/dist/assets/vendor-reselect-l0sNRNKZ.js +1 -0
  917. package/dist/assets/vendor-scheduler-7OC5HNn7.js +1 -0
  918. package/dist/assets/vendor-shiki-Bbf2GEcE.js +2 -0
  919. package/dist/assets/vendor-shikijs-core-CGM_jqPK.js +2 -0
  920. package/dist/assets/vendor-shikijs-engine-javascript-Cme4830A.js +1 -0
  921. package/dist/assets/vendor-shikijs-engine-oniguruma-DPWuIF1G.js +1 -0
  922. package/dist/assets/vendor-shikijs-transformers-CZWsLLKm.js +1 -0
  923. package/dist/assets/vendor-shikijs-types-CPSbSeK6.js +1 -0
  924. package/dist/assets/vendor-shikijs-vscode-textmate-BgLrS_2D.js +3 -0
  925. package/dist/assets/vendor-simplewebauthn-browser-VDA66rT_.js +2 -0
  926. package/dist/assets/vendor-sonner-dWA7qvjr.js +1 -0
  927. package/dist/assets/vendor-space-separated-tokens-DD3iYX1K.js +1 -0
  928. package/dist/assets/vendor-stringify-entities-CsH1VEn9.js +1 -0
  929. package/dist/assets/vendor-style-mod-NZ5MEPvj.js +3 -0
  930. package/dist/assets/vendor-tailwind-merge-CPcsbTWB.js +1 -0
  931. package/dist/assets/vendor-tanstack-react-virtual-IrbCBGJ4.js +1 -0
  932. package/dist/assets/vendor-tanstack-virtual-core-Dubg10g5.js +1 -0
  933. package/dist/assets/vendor-tslib-De9GV7Vy.js +1 -0
  934. package/dist/assets/vendor-use-callback-ref-CJB0R85I.js +1 -0
  935. package/dist/assets/vendor-use-sidecar-C-AuTczP.js +1 -0
  936. package/dist/assets/vendor-use-sync-external-store-B7OScDIw.js +1 -0
  937. package/dist/assets/vendor-vite-runtime-DD1OZmLC.js +1 -0
  938. package/dist/assets/vendor-w3c-keyname-Vcq4gwWv.js +1 -0
  939. package/dist/assets/vendor-workbox-window-BIl4cyR9.js +2 -0
  940. package/dist/assets/vendor-zumer-snapdom-Btyu_Xi2.js +8 -0
  941. package/dist/assets/vendor-zustand-CnsBKjP5.js +6 -0
  942. package/dist/assets/vendor-zwitch-C2o2j-tx.js +1 -0
  943. package/dist/assets/verilog-BQ8w6xss.js +1 -0
  944. package/dist/assets/verilog-C6RDOZhf.js +1 -0
  945. package/dist/assets/verilog-LfQUkHDc.js +1 -0
  946. package/dist/assets/vesper--t9w6MWz.js +1 -0
  947. package/dist/assets/vesper-DU1UobuO.js +1 -0
  948. package/dist/assets/vhdl-CeAyd5Ju.js +1 -0
  949. package/dist/assets/vhdl-DJCsFYgn.js +1 -0
  950. package/dist/assets/vhdl-lSbBsy5d.js +1 -0
  951. package/dist/assets/viml-CJc9bBzg.js +1 -0
  952. package/dist/assets/viml-pbKHW3Ia.js +1 -0
  953. package/dist/assets/vitesse-black-B_BYPdvp.js +1 -0
  954. package/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
  955. package/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
  956. package/dist/assets/vitesse-dark-DOSOf2Sz.js +1 -0
  957. package/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
  958. package/dist/assets/vitesse-light-gUX51GpB.js +1 -0
  959. package/dist/assets/vue-D2k0BAl5.js +1 -0
  960. package/dist/assets/vue-DN_0RTcg.js +1 -0
  961. package/dist/assets/vue-html-AaS7Mt5G.js +1 -0
  962. package/dist/assets/vue-html-zEfNEgpj.js +1 -0
  963. package/dist/assets/vue-vine-CQOfvN7w.js +1 -0
  964. package/dist/assets/vue-vine-D9eCaTqi.js +1 -0
  965. package/dist/assets/vyper-CDx5xZoG.js +1 -0
  966. package/dist/assets/vyper-DpazWNpx.js +1 -0
  967. package/dist/assets/wasm-CFi-k9--.js +1 -0
  968. package/dist/assets/wasm-CG6Dc4jp.js +1 -0
  969. package/dist/assets/wasm-MzD3tlZU.js +1 -0
  970. package/dist/assets/web-components-CNPQSzpa.js +1390 -0
  971. package/dist/assets/webidl-ZXfAyPTL.js +1 -0
  972. package/dist/assets/wenyan-BV7otONQ.js +1 -0
  973. package/dist/assets/wenyan-CYFFG9DK.js +1 -0
  974. package/dist/assets/wgsl-CxjTZs-b.js +1 -0
  975. package/dist/assets/wgsl-Dx-B1_4e.js +1 -0
  976. package/dist/assets/wikitext-BhOHFoWU.js +1 -0
  977. package/dist/assets/wikitext-Bx2qct8O.js +1 -0
  978. package/dist/assets/wit-5i3qLPDT.js +1 -0
  979. package/dist/assets/wit-DDW3hD69.js +1 -0
  980. package/dist/assets/wolfram-lXgVvXCa.js +1 -0
  981. package/dist/assets/wolfram-pu21K997.js +1 -0
  982. package/dist/assets/worker-BBk7yuNN.js +153 -0
  983. package/dist/assets/workerFactory-tw7cIdmV.js +1 -0
  984. package/dist/assets/xml-BkAJuBCc.js +1 -0
  985. package/dist/assets/xml-sdJ4AIDG.js +1 -0
  986. package/dist/assets/xquery-DzFWVndE.js +1 -0
  987. package/dist/assets/xsl-C6UUWSil.js +1 -0
  988. package/dist/assets/xsl-CtQFsRM5.js +1 -0
  989. package/dist/assets/yacas-BJ4BC0dw.js +1 -0
  990. package/dist/assets/yaml-Bopit2L3.js +1 -0
  991. package/dist/assets/yaml-Buea-lGh.js +1 -0
  992. package/dist/assets/z80-Hz9HOZM7.js +1 -0
  993. package/dist/assets/zenscript-BIAKq-aR.js +1 -0
  994. package/dist/assets/zenscript-DVFEvuxE.js +1 -0
  995. package/dist/assets/zig-VOosw3JB.js +1 -0
  996. package/dist/assets/zig-bSFrHQ7n.js +1 -0
  997. package/dist/favicon-16.png +0 -0
  998. package/dist/favicon-32.png +0 -0
  999. package/dist/favicon.png +0 -0
  1000. package/dist/favicon.svg +13 -0
  1001. package/dist/index.html +658 -0
  1002. package/dist/logo-dark-192x192.png +0 -0
  1003. package/dist/logo-dark-512x512.svg +13 -0
  1004. package/dist/logo-light-192x192.png +0 -0
  1005. package/dist/logo-light-512x512.svg +13 -0
  1006. package/dist/mini-chat.html +121 -0
  1007. package/dist/mobile.html +79 -0
  1008. package/dist/pwa-192.png +0 -0
  1009. package/dist/pwa-512.png +0 -0
  1010. package/dist/pwa-maskable-192.png +0 -0
  1011. package/dist/pwa-maskable-512.png +0 -0
  1012. package/dist/site.webmanifest +21 -0
  1013. package/dist/sw.js +1 -0
  1014. package/package.json +115 -0
  1015. package/public/apple-touch-icon-120x120.png +0 -0
  1016. package/public/apple-touch-icon-152x152.png +0 -0
  1017. package/public/apple-touch-icon-167x167.png +0 -0
  1018. package/public/apple-touch-icon-180x180.png +0 -0
  1019. package/public/apple-touch-icon.png +0 -0
  1020. package/public/apple-touch-icon.svg +13 -0
  1021. package/public/favicon-16.png +0 -0
  1022. package/public/favicon-32.png +0 -0
  1023. package/public/favicon.png +0 -0
  1024. package/public/favicon.svg +13 -0
  1025. package/public/logo-dark-192x192.png +0 -0
  1026. package/public/logo-dark-512x512.svg +13 -0
  1027. package/public/logo-light-192x192.png +0 -0
  1028. package/public/logo-light-512x512.svg +13 -0
  1029. package/public/pwa-192.png +0 -0
  1030. package/public/pwa-512.png +0 -0
  1031. package/public/pwa-maskable-192.png +0 -0
  1032. package/public/pwa-maskable-512.png +0 -0
  1033. package/public/site.webmanifest +21 -0
  1034. package/server/index.d.ts +35 -0
  1035. package/server/index.js +206 -0
  1036. package/server/lib/client-auth/pairing.js +308 -0
  1037. package/server/lib/client-auth/pairing.test.js +142 -0
  1038. package/server/lib/client-auth/remote-clients.js +280 -0
  1039. package/server/lib/client-auth/remote-clients.test.js +158 -0
  1040. package/server/lib/cloudflare-tunnel.js +606 -0
  1041. package/server/lib/fs/DOCUMENTATION.md +39 -0
  1042. package/server/lib/fs/pick-directory.js +236 -0
  1043. package/server/lib/fs/pick-directory.test.js +134 -0
  1044. package/server/lib/fs/routes.js +1543 -0
  1045. package/server/lib/fs/routes.test.js +920 -0
  1046. package/server/lib/fs/search.js +238 -0
  1047. package/server/lib/git/DOCUMENTATION.md +180 -0
  1048. package/server/lib/git/credentials.js +41 -0
  1049. package/server/lib/git/identity-storage.js +113 -0
  1050. package/server/lib/git/index.js +6 -0
  1051. package/server/lib/git/issue-2746-longpaths.test.js +206 -0
  1052. package/server/lib/git/routes.js +1089 -0
  1053. package/server/lib/git/routes.test.js +210 -0
  1054. package/server/lib/git/service.js +4927 -0
  1055. package/server/lib/git/service.test.js +1216 -0
  1056. package/server/lib/inherited-env.js +74 -0
  1057. package/server/lib/inherited-env.test.js +65 -0
  1058. package/server/lib/ngrok-tunnel.js +343 -0
  1059. package/server/lib/ngrok-tunnel.test.js +50 -0
  1060. package/server/lib/package-manager.js +850 -0
  1061. package/server/lib/package-manager.test.js +370 -0
  1062. package/server/lib/path-realpath-cache.js +85 -0
  1063. package/server/lib/path-realpath-cache.test.js +75 -0
  1064. package/server/lib/pi/archive-store.js +52 -0
  1065. package/server/lib/pi/archive-store.test.js +32 -0
  1066. package/server/lib/pi/attachment-store.js +98 -0
  1067. package/server/lib/pi/attachment-store.test.js +40 -0
  1068. package/server/lib/pi/custom-themes.js +33 -0
  1069. package/server/lib/pi/custom-themes.test.js +21 -0
  1070. package/server/lib/pi/legacy-ui-model-defaults.js +57 -0
  1071. package/server/lib/pi/legacy-ui-model-defaults.test.js +65 -0
  1072. package/server/lib/pi/model-config-store.js +173 -0
  1073. package/server/lib/pi/model-config-store.test.js +42 -0
  1074. package/server/lib/pi/routes.js +956 -0
  1075. package/server/lib/pi/routes.test.js +733 -0
  1076. package/server/lib/pi/session-daemon/DOCUMENTATION.md +41 -0
  1077. package/server/lib/pi/session-daemon/daemon-process.js +113 -0
  1078. package/server/lib/pi/session-daemon/ipc-client.js +144 -0
  1079. package/server/lib/pi/session-daemon/runtime-registry.js +149 -0
  1080. package/server/lib/pi/session-daemon/runtime-registry.test.js +109 -0
  1081. package/server/lib/pi/session-daemon/session-daemon.js +1903 -0
  1082. package/server/lib/pi/session-daemon/session-daemon.test.js +1306 -0
  1083. package/server/lib/pi/session-daemon/session-jsonl.js +94 -0
  1084. package/server/lib/pi/session-daemon/session-jsonl.test.js +73 -0
  1085. package/server/lib/pi/session-daemon/supervisor.js +458 -0
  1086. package/server/lib/pi/session-daemon/supervisor.test.js +212 -0
  1087. package/server/lib/pi/session-folders-store.js +74 -0
  1088. package/server/lib/pi/session-folders-store.test.js +45 -0
  1089. package/server/lib/pi/session-lifecycle.integration.test.js +197 -0
  1090. package/server/lib/pi/settings-store.js +133 -0
  1091. package/server/lib/pi/settings-store.test.js +113 -0
  1092. package/server/lib/pi/thinking-levels.js +39 -0
  1093. package/server/lib/pi/thinking-levels.test.js +34 -0
  1094. package/server/lib/pi/ui-settings-store.js +68 -0
  1095. package/server/lib/pi/ui-settings-store.test.js +40 -0
  1096. package/server/lib/pichamber-data-dir.js +78 -0
  1097. package/server/lib/pichamber-data-dir.test.js +105 -0
  1098. package/server/lib/pichamber-data-root-authority.test.js +81 -0
  1099. package/server/lib/preview/proxy-runtime.js +1604 -0
  1100. package/server/lib/preview/proxy-runtime.test.js +528 -0
  1101. package/server/lib/pwa-keys-contract.test.ts +62 -0
  1102. package/server/lib/relay/DOCUMENTATION.md +106 -0
  1103. package/server/lib/relay/cross-compat.test.js +135 -0
  1104. package/server/lib/relay/e2ee.js +341 -0
  1105. package/server/lib/relay/e2ee.test.js +124 -0
  1106. package/server/lib/relay/host-client.js +389 -0
  1107. package/server/lib/relay/host-client.test.js +292 -0
  1108. package/server/lib/relay/identity.js +93 -0
  1109. package/server/lib/relay/identity.test.js +78 -0
  1110. package/server/lib/relay/service.js +9 -0
  1111. package/server/lib/relay/signing-key.js +73 -0
  1112. package/server/lib/relay/tunnel-codec.js +373 -0
  1113. package/server/lib/relay/tunnel-codec.test.js +58 -0
  1114. package/server/lib/relay/tunnel-host.js +465 -0
  1115. package/server/lib/security/bind-host.js +40 -0
  1116. package/server/lib/security/bind-host.test.js +36 -0
  1117. package/server/lib/security/packaged-client-origins.js +11 -0
  1118. package/server/lib/security/request-security.js +122 -0
  1119. package/server/lib/security/request-security.test.js +57 -0
  1120. package/server/lib/server/cli-entry-runtime.js +44 -0
  1121. package/server/lib/server/cli-options.js +132 -0
  1122. package/server/lib/server/core-routes.js +1041 -0
  1123. package/server/lib/server/cors.js +51 -0
  1124. package/server/lib/server/cors.test.js +37 -0
  1125. package/server/lib/server/lan-addresses.js +41 -0
  1126. package/server/lib/server/lan-addresses.test.js +42 -0
  1127. package/server/lib/server/path-utils.js +27 -0
  1128. package/server/lib/server/tunnel-auth.js +586 -0
  1129. package/server/lib/terminal/DOCUMENTATION.md +48 -0
  1130. package/server/lib/terminal/history.js +83 -0
  1131. package/server/lib/terminal/history.test.js +19 -0
  1132. package/server/lib/terminal/runtime.js +391 -0
  1133. package/server/lib/terminal/runtime.test.js +566 -0
  1134. package/server/lib/terminal/shells.js +100 -0
  1135. package/server/lib/terminal/shells.test.js +73 -0
  1136. package/server/lib/terminal/terminal-ws-protocol.js +68 -0
  1137. package/server/lib/terminal/terminal-ws-protocol.test.js +145 -0
  1138. package/server/lib/terminal/theme-response.js +98 -0
  1139. package/server/lib/terminal/theme-response.test.js +70 -0
  1140. package/server/lib/tunnels/DOCUMENTATION.md +33 -0
  1141. package/server/lib/tunnels/executable-search.js +140 -0
  1142. package/server/lib/tunnels/executable-search.test.js +96 -0
  1143. package/server/lib/tunnels/install-help.js +56 -0
  1144. package/server/lib/tunnels/install-help.test.js +31 -0
  1145. package/server/lib/tunnels/providers/cloudflare.js +54 -0
  1146. package/server/lib/tunnels/providers/ngrok.js +32 -0
  1147. package/server/lib/tunnels/types.js +16 -0
  1148. package/server/lib/ui-auth/DOCUMENTATION.md +44 -0
  1149. package/server/lib/ui-auth/ui-auth.js +972 -0
  1150. package/server/lib/ui-auth/ui-auth.test.js +250 -0
  1151. package/server/lib/ui-auth/ui-passkeys.js +543 -0
  1152. package/server/lib/workspace/host.js +91 -0
@@ -0,0 +1,1903 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { createServer } from 'node:net';
3
+ import { chmod, mkdir, lstat, readFile, readdir, rename, rm, stat, writeFile } from 'node:fs/promises';
4
+ import { createReadStream } from 'node:fs';
5
+ import { createInterface } from 'node:readline';
6
+ import { basename, dirname, isAbsolute, join } from 'node:path';
7
+ import { hasTrustRequiringProjectResources } from '@earendil-works/pi-coding-agent';
8
+ import { StringDecoder } from 'node:string_decoder';
9
+ import {
10
+ createAgentSessionFromServices,
11
+ createAgentSessionRuntime,
12
+ createAgentSessionServices,
13
+ getAgentDir,
14
+ ProjectTrustStore,
15
+ SessionManager,
16
+ SettingsManager,
17
+ } from '@earendil-works/pi-coding-agent';
18
+
19
+ import { createPiModelConfigStore } from '../model-config-store.js';
20
+ import { clampThinkingLevel, getSupportedThinkingLevels, isPiThinkingLevel } from '../thinking-levels.js';
21
+ import { createSessionRuntimeRegistry } from './runtime-registry.js';
22
+ import { getPiSessionDirectory, validatePiSessionJsonlDirectory, validatePiSessionJsonlFile } from './session-jsonl.js';
23
+
24
+ const PROTOCOL_VERSION = 1;
25
+ const MAX_FRAME_BYTES = 16 * 1024 * 1024;
26
+
27
+ class SessionDaemonProtocolError extends Error {
28
+ constructor(code, message) {
29
+ super(message);
30
+ this.code = code;
31
+ }
32
+ }
33
+
34
+ export function isLocalSessionDaemonEndpoint(endpoint, platform = process.platform) {
35
+ if (typeof endpoint !== 'string' || endpoint.length === 0) return false;
36
+
37
+ if (platform === 'win32') {
38
+ return /^\\\\\.\\pipe\\[^\\/]+$/.test(endpoint);
39
+ }
40
+
41
+ return isAbsolute(endpoint);
42
+ }
43
+
44
+ async function createPiSessionRuntime({ cwd, agentDir = getAgentDir(), sessionFile }) {
45
+ const createRuntime = async ({ cwd: runtimeCwd, agentDir: runtimeAgentDir, sessionManager, sessionStartEvent }) => {
46
+ const services = await createAgentSessionServices({
47
+ cwd: runtimeCwd,
48
+ agentDir: runtimeAgentDir,
49
+ resourceLoaderOptions: {
50
+ // Third-party native extensions are intentionally disabled for the Pi core milestone.
51
+ noExtensions: true,
52
+ },
53
+ });
54
+
55
+ return {
56
+ ...(await createAgentSessionFromServices({
57
+ services,
58
+ sessionManager,
59
+ sessionStartEvent,
60
+ })),
61
+ services,
62
+ diagnostics: services.diagnostics,
63
+ };
64
+ };
65
+
66
+ return createAgentSessionRuntime(createRuntime, {
67
+ cwd,
68
+ agentDir,
69
+ sessionManager: sessionFile
70
+ ? SessionManager.open(sessionFile, getPiSessionDirectory({ cwd, agentDir }), cwd)
71
+ : SessionManager.create(cwd, getPiSessionDirectory({ cwd, agentDir })),
72
+ });
73
+ }
74
+
75
+ export function createSessionDaemon({
76
+ endpoint,
77
+ credential,
78
+ cwd,
79
+ agentDir = getAgentDir(),
80
+ createRuntime = createPiSessionRuntime,
81
+ healthMetadata = {},
82
+ idleTimeoutMs = 5 * 60 * 1_000,
83
+ listSessions = ({ cwd: sessionCwd, agentDir: sessionAgentDir = agentDir }) => SessionManager.list(
84
+ sessionCwd,
85
+ getPiSessionDirectory({ cwd: sessionCwd, agentDir: sessionAgentDir }),
86
+ ),
87
+ createSettingsManager = ({ cwd: settingsCwd, agentDir: settingsAgentDir = agentDir, projectTrusted }) => SettingsManager.create(
88
+ settingsCwd,
89
+ settingsAgentDir,
90
+ { projectTrusted },
91
+ ),
92
+ createTrustStore = (settingsAgentDir = agentDir) => new ProjectTrustStore(settingsAgentDir),
93
+ modelConfigStore = createPiModelConfigStore({ file: join(agentDir, 'models.json') }),
94
+ renamePersistedSession = ({ sessionFile, title, cwd: sessionCwd = cwd, agentDir: sessionAgentDir = agentDir }) => {
95
+ const manager = SessionManager.open(sessionFile, getPiSessionDirectory({ cwd: sessionCwd, agentDir: sessionAgentDir }), sessionCwd);
96
+ manager.appendSessionInfo(title);
97
+ },
98
+ platform = process.platform,
99
+ } = {}) {
100
+ if (!isLocalSessionDaemonEndpoint(endpoint, platform)) {
101
+ throw new SessionDaemonProtocolError('INVALID_ENDPOINT', 'The session daemon endpoint must be local.');
102
+ }
103
+ if (typeof credential !== 'string' || credential.length < 16) {
104
+ throw new SessionDaemonProtocolError('INVALID_CREDENTIAL', 'The session daemon credential is invalid.');
105
+ }
106
+ if (typeof cwd !== 'string' || cwd.length === 0) {
107
+ throw new SessionDaemonProtocolError('INVALID_CWD', 'The session daemon working directory is invalid.');
108
+ }
109
+ if (!Number.isFinite(idleTimeoutMs) || idleTimeoutMs < 0) {
110
+ throw new SessionDaemonProtocolError('INVALID_IDLE_TIMEOUT', 'The session daemon idle timeout is invalid.');
111
+ }
112
+
113
+ let server;
114
+ let runtime;
115
+ let runtimeRegistry;
116
+ let runtimeStartPromise;
117
+ let idleDisposeTimer;
118
+ let dormantSession;
119
+ let sequence = 0;
120
+ let started = false;
121
+ const knownDirectories = new Set([cwd]);
122
+ let activeDirectory = cwd;
123
+ const servicesCache = new Map();
124
+ const clients = new Set();
125
+ // A reconnect replays only a contiguous retained gap; otherwise it receives
126
+ // a new authoritative snapshot before later events can arrive.
127
+ const eventLog = [];
128
+ const streamingMessageIds = new Map();
129
+ const latestAssistantMessageIds = new Map();
130
+ const messageStartedAt = new Map();
131
+ const toolStartedAt = new Map();
132
+ const latestUserMessageIds = new Map();
133
+ const sendGenerationBySession = new Map();
134
+ const streamingRedactionBuffers = new Map();
135
+ const loginAttempts = new Map();
136
+ const MAX_REPLAY_EVENTS = 1_024;
137
+
138
+ const validateDirectoryPath = async (dir) => {
139
+ if (typeof dir !== 'string' || dir.trim().length === 0) {
140
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The directory path is required.');
141
+ }
142
+ const normalized = dir.trim();
143
+ if (!isAbsolute(normalized)) {
144
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The directory path must be absolute.');
145
+ }
146
+ try {
147
+ const stats = await stat(normalized);
148
+ if (!stats.isDirectory()) {
149
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The specified path is not a directory.');
150
+ }
151
+ } catch (error) {
152
+ if (error instanceof SessionDaemonProtocolError) throw error;
153
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The directory path does not exist or is inaccessible.');
154
+ }
155
+ return normalized;
156
+ };
157
+
158
+ const resolveDirectory = async (requested) => {
159
+ if (typeof requested === 'string' && requested.trim().length > 0) {
160
+ const validated = await validateDirectoryPath(requested);
161
+ knownDirectories.add(validated);
162
+ return validated;
163
+ }
164
+ return activeDirectory || cwd;
165
+ };
166
+
167
+ const deriveSessionTitle = (text, maxLength = 50) => {
168
+ if (!text || typeof text !== 'string') return '';
169
+ const cleaned = text
170
+ .replace(/```[\s\S]*?```/g, ' ')
171
+ .replace(/`[^`]+`/g, ' ')
172
+ .replace(/\[(?:attachment|file|image|audio|video):[^\]]*\]/gi, ' ')
173
+ .replace(/@\S+/g, ' ')
174
+ .replace(/^[#>\s*\-+]+/gm, '');
175
+ const lines = cleaned.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
176
+ if (lines.length === 0) return '';
177
+ let title = lines[0].replace(/\s+/g, ' ').trim();
178
+ if (title.length > maxLength) {
179
+ title = `${title.slice(0, maxLength).trim()}…`;
180
+ }
181
+ return title;
182
+ };
183
+
184
+ const getServices = async (targetCwd = activeDirectory || cwd) => {
185
+ const existing = servicesCache.get(targetCwd);
186
+ if (existing) return existing;
187
+ const services = await createAgentSessionServices({
188
+ cwd: targetCwd,
189
+ agentDir,
190
+ resourceLoaderOptions: { noExtensions: true },
191
+ });
192
+ servicesCache.set(targetCwd, services);
193
+ return services;
194
+ };
195
+
196
+ const publish = (event, payload, sessionId = runtime?.session?.sessionId, directory) => {
197
+ if (typeof sessionId !== 'string' || sessionId.length === 0) return;
198
+ const targetDirectory = directory || activeDirectory || cwd;
199
+ const message = {
200
+ protocolVersion: PROTOCOL_VERSION,
201
+ kind: 'event',
202
+ event,
203
+ sequence: ++sequence,
204
+ payload: {
205
+ sessionId,
206
+ directory: targetDirectory,
207
+ ...payload,
208
+ },
209
+ };
210
+ eventLog.push(message);
211
+ if (eventLog.length > MAX_REPLAY_EVENTS) eventLog.shift();
212
+ for (const client of clients) writeFrame(client, message);
213
+ };
214
+
215
+ const getSessionState = () => runtime
216
+ ? { sessionId: runtime.session.sessionId, isStreaming: runtime.session.isStreaming }
217
+ : { sessionId: dormantSession?.sessionId, isStreaming: false };
218
+
219
+ const rememberRuntimeSession = () => {
220
+ const sessionId = runtime?.session?.sessionId;
221
+ if (typeof sessionId !== 'string' || sessionId.length === 0) return;
222
+ dormantSession = {
223
+ sessionId,
224
+ sessionFile: runtime.session.sessionManager?.getSessionFile?.(),
225
+ };
226
+ };
227
+
228
+ const publishSnapshot = (socket, requestedSessionId) => {
229
+ const targetRuntime = requestedSessionId ? runtimeRegistry?.findBySessionId(requestedSessionId) : runtime;
230
+ const session = targetRuntime?.session
231
+ ? { sessionId: targetRuntime.session.sessionId, isStreaming: targetRuntime.session.isStreaming }
232
+ : getSessionState();
233
+ if (requestedSessionId && requestedSessionId !== session.sessionId) return;
234
+ const activeSession = targetRuntime?.session || runtime?.session;
235
+ const targetDirectory = targetRuntime?.cwd || activeDirectory || cwd;
236
+ const messages = activeSession ? projectMessageEntries(activeSession, targetDirectory) : [];
237
+ const lastAssistant = [...messages].reverse().find((entry) => entry.message.role === 'assistant')?.message;
238
+ const model = activeSession?.model;
239
+ const snapshotSequence = ++sequence;
240
+ writeFrame(socket, {
241
+ protocolVersion: PROTOCOL_VERSION,
242
+ kind: 'event',
243
+ event: 'session.snapshot',
244
+ sequence: snapshotSequence,
245
+ payload: {
246
+ ...(session.sessionId ? { sessionId: session.sessionId } : {}),
247
+ directory: targetDirectory,
248
+ isStreaming: session.isStreaming ?? false,
249
+ lifecycle: session.isStreaming ? 'busy' : 'idle',
250
+ queue: activeSession ? {
251
+ steering: activeSession.getSteeringMessages?.().length ?? 0,
252
+ followUp: activeSession.getFollowUpMessages?.().length ?? 0,
253
+ } : { steering: 0, followUp: 0 },
254
+ ...(model?.provider && model?.id ? { model: { providerId: model.provider, modelId: model.id } } : {}),
255
+ ...(activeSession?.thinkingLevel ? { thinking: activeSession.thinkingLevel } : {}),
256
+ ...(typeof lastAssistant?.text === 'string' ? { lastText: lastAssistant.text } : {}),
257
+ ...(typeof lastAssistant?.thinking === 'string' ? { lastThinking: lastAssistant.thinking } : {}),
258
+ lastSequence: snapshotSequence,
259
+ },
260
+ });
261
+ };
262
+
263
+ const idleDisposeTimers = new Map();
264
+
265
+ const clearIdleDisposal = (sessionId) => {
266
+ if (sessionId) {
267
+ const timer = idleDisposeTimers.get(sessionId);
268
+ if (timer) clearTimeout(timer);
269
+ idleDisposeTimers.delete(sessionId);
270
+ } else {
271
+ for (const timer of idleDisposeTimers.values()) clearTimeout(timer);
272
+ idleDisposeTimers.clear();
273
+ }
274
+ };
275
+
276
+ const disposeRuntime = async () => {
277
+ clearIdleDisposal();
278
+ if (runtimeRegistry) {
279
+ const hadTrackedRuntime = runtimeRegistry.size > 0;
280
+ await runtimeRegistry.disposeAll();
281
+ if (!hadTrackedRuntime) await runtime?.dispose?.();
282
+ runtimeRegistry = undefined;
283
+ } else {
284
+ await runtime?.dispose?.();
285
+ }
286
+ runtime = undefined;
287
+ };
288
+
289
+ const startRuntime = async ({ cwd: runtimeCwd = activeDirectory || cwd, sessionFile } = {}) => {
290
+ if (sessionFile) await validatePiSessionJsonlFile(sessionFile);
291
+ const newRuntime = await createRuntime({ cwd: runtimeCwd, agentDir, ...(sessionFile ? { sessionFile } : {}) });
292
+ if (!newRuntime.cwd) {
293
+ newRuntime.cwd = runtimeCwd;
294
+ }
295
+ if (!runtimeRegistry) {
296
+ runtimeRegistry = createSessionRuntimeRegistry({
297
+ onSessionEvent: ({ cwd: eventCwd, sessionId: eventSessionId }, event) => publishSessionEvent(eventSessionId, event, eventCwd),
298
+ });
299
+ }
300
+ runtimeRegistry.register(newRuntime, { cwd: runtimeCwd });
301
+ runtime = newRuntime;
302
+ activeDirectory = runtimeCwd;
303
+ rememberRuntimeSession();
304
+ return newRuntime;
305
+ };
306
+
307
+ const ensureRuntime = (targetCwd = activeDirectory || cwd) => {
308
+ if (runtime) return Promise.resolve(runtime);
309
+ if (!runtimeStartPromise) {
310
+ runtimeStartPromise = startRuntime({ cwd: targetCwd, sessionFile: dormantSession?.sessionFile }).finally(() => {
311
+ runtimeStartPromise = undefined;
312
+ });
313
+ }
314
+ return runtimeStartPromise;
315
+ };
316
+
317
+ const scheduleIdleDisposal = (sessionId) => {
318
+ clearIdleDisposal(sessionId);
319
+ const timer = setTimeout(async () => {
320
+ idleDisposeTimers.delete(sessionId);
321
+ const targetRuntime = runtimeRegistry?.findBySessionId(sessionId);
322
+ if (!targetRuntime || targetRuntime.session?.isStreaming) return;
323
+ try {
324
+ if (targetRuntime === runtime) {
325
+ rememberRuntimeSession();
326
+ }
327
+ await runtimeRegistry.dispose(targetRuntime);
328
+ if (targetRuntime === runtime) {
329
+ runtime = undefined;
330
+ }
331
+ } catch {
332
+ publish('session.error', { code: 'RUNTIME_DISPOSAL_FAILED' }, sessionId);
333
+ }
334
+ }, idleTimeoutMs);
335
+ idleDisposeTimers.set(sessionId, timer);
336
+ };
337
+
338
+ const listSessionItems = async (requestedDirectory) => {
339
+ const targetDir = requestedDirectory ? await resolveDirectory(requestedDirectory) : (activeDirectory || cwd);
340
+ await validatePiSessionJsonlDirectory({ cwd: targetDir, agentDir });
341
+ const sessions = await listSessions({ cwd: targetDir, agentDir });
342
+ if (!Array.isArray(sessions)) {
343
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'Pi returned an invalid session collection.');
344
+ }
345
+
346
+ const idByPath = new Map(sessions.map((session) => [session?.path, session?.id]));
347
+ const uncorrupted = sessions.filter((session) => !session?.corrupted && typeof session?.id === 'string');
348
+ const knownIds = new Set(uncorrupted.map((s) => s.id));
349
+ const activeEntries = runtimeRegistry
350
+ ? runtimeRegistry.listByDirectory(targetDir)
351
+ : (runtime && typeof runtime.cwd === 'string' && (runtime.cwd === targetDir || resolve(runtime.cwd) === resolve(targetDir)) ? [runtime] : []);
352
+ const extra = [];
353
+ for (const entry of activeEntries) {
354
+ if (entry?.session?.sessionId && !knownIds.has(entry.session.sessionId)) {
355
+ extra.push({
356
+ id: entry.session.sessionId,
357
+ cwd: targetDir,
358
+ name: entry.session.sessionManager?.getSessionName?.() || entry.session.title || undefined,
359
+ messageCount: entry.session.messages?.length || 0,
360
+ created: new Date(),
361
+ modified: new Date(),
362
+ });
363
+ }
364
+ }
365
+
366
+ const allSessions = [...extra, ...uncorrupted];
367
+ return allSessions.map((session) => {
368
+ const createdAt = session?.created instanceof Date ? session.created.getTime() : (typeof session?.createdAt === 'number' ? session.createdAt : NaN);
369
+ const updatedAt = session?.modified instanceof Date ? session.modified.getTime() : (typeof session?.updatedAt === 'number' ? session.updatedAt : NaN);
370
+ if (typeof session?.id !== 'string' || session.id.length === 0 || !Number.isFinite(createdAt) || !Number.isFinite(updatedAt)) {
371
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'Pi returned an invalid session record.');
372
+ }
373
+ const safeFirstMessage = redactAttachmentPaths(session.firstMessage);
374
+ const title = typeof session.name === 'string' && session.name.trim().length > 0
375
+ ? redactAttachmentPaths(session.name.trim())
376
+ : deriveSessionTitle(safeFirstMessage);
377
+ return {
378
+ session: {
379
+ id: session.id,
380
+ directory: targetDir,
381
+ ...(title ? { title } : {}),
382
+ ...(typeof session.parentSessionPath === 'string' && idByPath.get(session.parentSessionPath)
383
+ ? { parentId: idByPath.get(session.parentSessionPath) }
384
+ : {}),
385
+ createdAt,
386
+ updatedAt,
387
+ ...(Number.isSafeInteger(session.messageCount) && session.messageCount >= 0 ? { messageCount: session.messageCount } : {}),
388
+ },
389
+ ...(safeFirstMessage ? { preview: safeFirstMessage } : {}),
390
+ updatedAt,
391
+ };
392
+ });
393
+ };
394
+
395
+ const renameSession = async (payload) => {
396
+ if (!payload || typeof payload !== 'object' || typeof payload.sessionId !== 'string' || payload.sessionId.length === 0
397
+ || typeof payload.title !== 'string' || payload.title.trim().length === 0 || payload.title.length > 256) {
398
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested session title is invalid.');
399
+ }
400
+ const sessionId = payload.sessionId;
401
+ const title = payload.title.trim();
402
+ const targetDir = payload.directory ? await resolveDirectory(payload.directory) : (activeDirectory || cwd);
403
+ const activeRuntime = runtimeRegistry?.get({ cwd: targetDir, sessionId })
404
+ || runtimeRegistry?.findBySessionId(sessionId)
405
+ || (runtime?.session?.sessionId === sessionId ? runtime : undefined);
406
+ if (activeRuntime?.session) {
407
+ const manager = activeRuntime.session.sessionManager;
408
+ if (typeof manager?.appendSessionInfo !== 'function') {
409
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'Pi returned an invalid active session.');
410
+ }
411
+ manager.appendSessionInfo(title);
412
+ publish('session.updated', { title }, sessionId, targetDir);
413
+ return;
414
+ }
415
+
416
+ await validatePiSessionJsonlDirectory({ cwd: targetDir, agentDir });
417
+ const sessions = await listSessions({ cwd: targetDir, agentDir });
418
+ const target = Array.isArray(sessions) ? sessions.find((session) => session?.id === sessionId) : undefined;
419
+ if (typeof target?.path !== 'string' || target.path.length === 0) {
420
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'The Pi session does not exist.');
421
+ }
422
+ await validatePiSessionJsonlFile(target.path);
423
+ renamePersistedSession({ sessionFile: target.path, title, cwd: targetDir });
424
+ publish('session.updated', { title }, sessionId, targetDir);
425
+ };
426
+
427
+ const findPersistedSession = async (sessionId, requestedDirectory) => {
428
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
429
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'The Pi session does not exist.');
430
+ }
431
+ const candidateDirs = new Set();
432
+ if (requestedDirectory) {
433
+ try {
434
+ candidateDirs.add(await resolveDirectory(requestedDirectory));
435
+ } catch {}
436
+ }
437
+ if (activeDirectory) candidateDirs.add(activeDirectory);
438
+ if (cwd) candidateDirs.add(cwd);
439
+ for (const d of knownDirectories) candidateDirs.add(d);
440
+
441
+ for (const dir of candidateDirs) {
442
+ try {
443
+ await validatePiSessionJsonlDirectory({ cwd: dir, agentDir });
444
+ const sessions = await listSessions({ cwd: dir, agentDir });
445
+ const target = Array.isArray(sessions) ? sessions.find((session) => session?.id === sessionId) : undefined;
446
+ if (target && typeof target.path === 'string' && target.path.length > 0) {
447
+ await validatePiSessionJsonlFile(target.path);
448
+ return { target, directory: dir };
449
+ }
450
+ } catch (err) {
451
+ // Continue searching other candidate directories
452
+ }
453
+ }
454
+
455
+ // If not found in candidateDirs, scan all directory stores under agentDir/sessions
456
+ try {
457
+ const sessionsRoot = join(agentDir, 'sessions');
458
+ const dirEntries = await readdir(sessionsRoot, { withFileTypes: true });
459
+ for (const dirEntry of dirEntries) {
460
+ if (!dirEntry.isDirectory()) continue;
461
+ const dirPath = join(sessionsRoot, dirEntry.name);
462
+ const files = await readdir(dirPath, { withFileTypes: true });
463
+ for (const file of files) {
464
+ if (!file.name.endsWith('.jsonl')) continue;
465
+ const fullPath = join(dirPath, file.name);
466
+ try {
467
+ const input = createReadStream(fullPath, { encoding: 'utf8' });
468
+ const lines = createInterface({ input, crlfDelay: Infinity });
469
+ let sessionCwd = null;
470
+ let fileId = null;
471
+ for await (const line of lines) {
472
+ if (!line.trim()) continue;
473
+ const header = JSON.parse(line);
474
+ if (header?.type === 'session' && typeof header.id === 'string') {
475
+ fileId = header.id;
476
+ sessionCwd = header.cwd;
477
+ }
478
+ break;
479
+ }
480
+ lines.close();
481
+ if (fileId === sessionId && sessionCwd) {
482
+ await validatePiSessionJsonlFile(fullPath);
483
+ const validated = await resolveDirectory(sessionCwd);
484
+ knownDirectories.add(validated);
485
+ return { target: { id: sessionId, path: fullPath }, directory: validated };
486
+ }
487
+ } catch {}
488
+ }
489
+ }
490
+ } catch {}
491
+
492
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'The Pi session does not exist.');
493
+ };
494
+
495
+ const activateSession = async (sessionId, requestedDirectory) => {
496
+ if (!runtimeRegistry) {
497
+ runtimeRegistry = createSessionRuntimeRegistry({
498
+ onSessionEvent: ({ cwd: eventCwd, sessionId: eventSessionId }, event) => publishSessionEvent(eventSessionId, event, eventCwd),
499
+ });
500
+ }
501
+ if (requestedDirectory) {
502
+ try {
503
+ const targetDir = await resolveDirectory(requestedDirectory);
504
+ const existing = runtimeRegistry.get({ cwd: targetDir, sessionId });
505
+ if (existing) {
506
+ runtime = existing;
507
+ activeDirectory = targetDir;
508
+ return existing;
509
+ }
510
+ } catch {}
511
+ }
512
+ const existingAnywhere = runtimeRegistry.findBySessionId(sessionId);
513
+ if (existingAnywhere) {
514
+ runtime = existingAnywhere;
515
+ if (existingAnywhere.cwd) activeDirectory = existingAnywhere.cwd;
516
+ return existingAnywhere;
517
+ }
518
+ const { target, directory } = await findPersistedSession(sessionId, requestedDirectory);
519
+ const newRuntime = await createRuntime({ cwd: directory, agentDir, sessionFile: target.path });
520
+ if (!newRuntime.cwd) newRuntime.cwd = directory;
521
+ if (newRuntime.session?.sessionId !== sessionId && typeof newRuntime.switchSession === 'function') {
522
+ await newRuntime.switchSession(target.path);
523
+ }
524
+ runtimeRegistry.register(newRuntime, { cwd: directory });
525
+ runtime = newRuntime;
526
+ activeDirectory = directory;
527
+ rememberRuntimeSession();
528
+ return newRuntime;
529
+ };
530
+
531
+ const projectMessageEntries = (session, targetDir = activeDirectory || cwd) => {
532
+ const entries = session?.sessionManager?.getEntries?.();
533
+ if (!Array.isArray(entries)) return [];
534
+ const toolResults = new Map();
535
+ for (const entry of entries) {
536
+ if (entry?.type !== 'message' || !entry.message || entry.message.role !== 'toolResult' || typeof entry.message.toolCallId !== 'string') continue;
537
+ toolResults.set(entry.message.toolCallId, {
538
+ ...projectToolResult(entry.message, entry.message.isError === true),
539
+ isError: entry.message.isError === true,
540
+ endedAt: Date.parse(entry.timestamp),
541
+ });
542
+ }
543
+ let latestUserMessageId;
544
+ return entries.flatMap((entry) => {
545
+ if (entry?.type !== 'message' || !entry.message || typeof entry.id !== 'string') return [];
546
+ const timestamp = Date.parse(entry.timestamp);
547
+ const createdAt = Number.isFinite(timestamp) ? timestamp : 0;
548
+ if (entry.message.role === 'user') {
549
+ const text = redactAttachmentPaths(typeof entry.message.content === 'string'
550
+ ? entry.message.content
551
+ : Array.isArray(entry.message.content)
552
+ ? entry.message.content.filter((part) => part?.type === 'text').map((part) => part.text).join('')
553
+ : '');
554
+ latestUserMessageId = entry.id;
555
+ return [{ message: { id: entry.id, sessionId: session.sessionId, directory: targetDir, role: 'user', text, createdAt }, parts: [] }];
556
+ }
557
+ if (entry.message.role !== 'assistant' || !Array.isArray(entry.message.content)) return [];
558
+ const text = redactAttachmentPaths(entry.message.content.filter((part) => part?.type === 'text').map((part) => part.text).join(''));
559
+ const thinking = redactAttachmentPaths(entry.message.content.filter((part) => part?.type === 'thinking').map((part) => part.thinking).join(''));
560
+ const usage = projectUsage(entry.message.usage);
561
+ const parts = entry.message.content.flatMap((part, index) => {
562
+ if (part?.type === 'text') return [{ type: 'text', id: `${entry.id}:text:${index}`, index, text: redactAttachmentPaths(part.text) }];
563
+ if (part?.type === 'thinking') return [{ type: 'thinking', id: `${entry.id}:thinking:${index}`, index, text: redactAttachmentPaths(part.thinking) }];
564
+ if (part?.type === 'toolCall') {
565
+ const result = toolResults.get(part.id);
566
+ return [{
567
+ type: 'tool',
568
+ id: `${entry.id}:tool:${part.id}`,
569
+ index,
570
+ toolCallId: part.id,
571
+ name: part.name,
572
+ input: redactAttachmentValues(part.arguments),
573
+ state: result?.isError ? 'error' : 'completed',
574
+ ...(result?.output ? { output: result.output } : {}),
575
+ ...(result?.error ? { error: result.error } : {}),
576
+ ...(result?.isError ? { isError: true } : {}),
577
+ ...(result?.metadata ? { metadata: result.metadata } : {}),
578
+ ...(Number.isFinite(result?.endedAt) ? { endedAt: result.endedAt } : {}),
579
+ }];
580
+ }
581
+ return [];
582
+ });
583
+ return [{
584
+ message: {
585
+ id: entry.id, sessionId: session.sessionId, directory: targetDir, role: 'assistant', text, thinking, createdAt,
586
+ ...(latestUserMessageId ? { parentId: latestUserMessageId } : {}),
587
+ model: { providerId: entry.message.provider, modelId: entry.message.model },
588
+ ...(isPiThinkingLevel(entry.message.thinkingLevel) ? { thinkingLevel: entry.message.thinkingLevel } : {}),
589
+ ...(entry.message.errorMessage ? { error: { code: 'ASSISTANT_ERROR', message: redactAttachmentPaths(entry.message.errorMessage) } } : {}),
590
+ ...(usage ? { usage } : {}),
591
+ },
592
+ parts,
593
+ }];
594
+ });
595
+ };
596
+
597
+ const projectActiveSession = (activeRuntime = runtime, targetDir = activeRuntime?.cwd || activeDirectory || cwd) => {
598
+ const session = activeRuntime?.session;
599
+ const manager = session?.sessionManager;
600
+ const header = manager?.getHeader?.();
601
+ const createdAt = Date.parse(header?.timestamp);
602
+ if (!session || !Number.isFinite(createdAt)) {
603
+ throw new SessionDaemonProtocolError('INVALID_SESSION', 'Pi returned an invalid active session.');
604
+ }
605
+ const model = session.model;
606
+ const messages = projectMessageEntries(session, targetDir);
607
+ const lastAssistant = [...messages].reverse().find((entry) => entry.message.role === 'assistant')?.message;
608
+ const sessionModel = lastAssistant?.model
609
+ ?? (model?.provider && model?.id ? { providerId: model.provider, modelId: model.id } : undefined);
610
+ const sessionThinking = lastAssistant?.thinkingLevel || session.thinkingLevel;
611
+ return {
612
+ session: {
613
+ id: session.sessionId, directory: targetDir, createdAt, updatedAt: createdAt,
614
+ ...(session.sessionName ? { title: session.sessionName } : {}),
615
+ ...(sessionModel ? { model: sessionModel } : {}),
616
+ ...(sessionThinking ? { thinking: sessionThinking } : {}),
617
+ messageCount: messages.length,
618
+ },
619
+ messages,
620
+ lastSequence: sequence,
621
+ };
622
+ };
623
+
624
+ const createSession = async (payload) => {
625
+ if (!payload || typeof payload !== 'object'
626
+ || (payload.cwd !== undefined && (typeof payload.cwd !== 'string' || payload.cwd.length === 0))
627
+ || (payload.title !== undefined && (typeof payload.title !== 'string' || payload.title.trim().length === 0 || payload.title.length > 256))
628
+ || (payload.thinking !== undefined && !isPiThinkingLevel(payload.thinking))
629
+ || (payload.model !== undefined && (!payload.model || typeof payload.model.providerId !== 'string' || typeof payload.model.modelId !== 'string'))) {
630
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested session creation options are invalid.');
631
+ }
632
+ const targetCwd = await resolveDirectory(payload.cwd);
633
+ await validatePiSessionJsonlDirectory({ cwd: targetCwd, agentDir });
634
+ const parent = payload.parentId === undefined ? undefined : (await findPersistedSession(payload.parentId, targetCwd)).target;
635
+ if (!runtimeRegistry) {
636
+ runtimeRegistry = createSessionRuntimeRegistry({
637
+ onSessionEvent: ({ cwd: eventCwd, sessionId: eventSessionId }, event) => publishSessionEvent(eventSessionId, event, eventCwd),
638
+ });
639
+ }
640
+ const newRuntime = await createRuntime({
641
+ cwd: targetCwd,
642
+ agentDir,
643
+ ...(parent ? { sessionFile: parent.path } : {}),
644
+ });
645
+ if (!newRuntime.cwd) newRuntime.cwd = targetCwd;
646
+ let result = { cancelled: false };
647
+ if (typeof newRuntime.newSession === 'function') {
648
+ result = await newRuntime.newSession({
649
+ ...(parent ? { parentSession: parent.path } : {}),
650
+ ...(payload.title ? { setup: async (manager) => manager.appendSessionInfo(payload.title.trim()) } : {}),
651
+ });
652
+ } else if (payload.title && newRuntime.session?.sessionManager?.appendSessionInfo) {
653
+ newRuntime.session.sessionManager.appendSessionInfo(payload.title.trim());
654
+ }
655
+ if (result?.cancelled) throw new SessionDaemonProtocolError('SESSION_CREATE_CANCELLED', 'Pi cancelled session creation.');
656
+ if (payload.model) {
657
+ await setSessionModel(newRuntime, payload.model);
658
+ publishSessionModel(newRuntime.session, newRuntime.session.sessionId, targetCwd);
659
+ }
660
+ if (payload.thinking !== undefined) {
661
+ applyThinking(newRuntime, payload.thinking, newRuntime.session.sessionId, targetCwd);
662
+ }
663
+ runtimeRegistry.register(newRuntime, { cwd: targetCwd });
664
+ runtime = newRuntime;
665
+ activeDirectory = targetCwd;
666
+ rememberRuntimeSession();
667
+ return projectActiveSession(newRuntime, targetCwd);
668
+ };
669
+
670
+ const listProviders = async (requestedDirectory) => {
671
+ const targetDir = requestedDirectory ? await resolveDirectory(requestedDirectory) : (activeDirectory || cwd);
672
+ const activeRuntime = await ensureRuntime(targetDir);
673
+ const modelRuntime = activeRuntime.session?.modelRuntime;
674
+ const models = modelRuntime?.getModels?.();
675
+ if (!Array.isArray(models)) throw new SessionDaemonProtocolError('PROVIDER_UNAVAILABLE', 'Pi did not provide a model catalog.');
676
+ const providers = new Map();
677
+ for (const model of models) {
678
+ if (!model || typeof model.provider !== 'string' || typeof model.id !== 'string') continue;
679
+ const provider = modelRuntime.getProvider?.(model.provider);
680
+ const auth = modelRuntime.getProviderAuthStatus?.(model.provider);
681
+ const entry = providers.get(model.provider) ?? {
682
+ id: model.provider,
683
+ label: typeof provider?.name === 'string' ? provider.name : model.provider,
684
+ authenticated: auth?.configured === true,
685
+ models: [],
686
+ };
687
+ entry.models.push({
688
+ id: model.id,
689
+ providerId: model.provider,
690
+ ...(typeof model.name === 'string' ? { label: model.name } : {}),
691
+ ...(Number.isSafeInteger(model.contextWindow) ? { contextWindow: model.contextWindow } : {}),
692
+ ...(model.reasoning === true ? { supportsThinking: true, thinkingLevels: getSupportedThinkingLevels(model) } : {}),
693
+ });
694
+ providers.set(model.provider, entry);
695
+ }
696
+ return { providers: [...providers.values()] };
697
+ };
698
+
699
+ const getProviderConfiguration = async (providerId) => {
700
+ if (typeof providerId !== 'string' || providerId.length === 0 || providerId.length > 256) {
701
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested provider is invalid.');
702
+ }
703
+ try {
704
+ const config = await modelConfigStore.get(providerId);
705
+ return { config: config ?? null };
706
+ } catch (error) {
707
+ if (error?.code === 'PI_MODEL_CONFIG_INVALID') {
708
+ throw new SessionDaemonProtocolError('PI_MODEL_CONFIG_INVALID', 'Pi models configuration is invalid.');
709
+ }
710
+ throw error;
711
+ }
712
+ };
713
+
714
+ const setProviderModels = async (payload) => {
715
+ if (!payload || typeof payload !== 'object') {
716
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The provider configuration is invalid.');
717
+ }
718
+ const activeRuntime = await ensureRuntime();
719
+ if (activeRuntime?.session?.isStreaming) {
720
+ throw new SessionDaemonProtocolError('SESSION_BUSY', 'Provider configuration cannot change while a session is streaming.');
721
+ }
722
+ if (typeof activeRuntime?.session?.modelRuntime?.getError?.() === 'string') {
723
+ throw new SessionDaemonProtocolError('PI_MODEL_CONFIG_INVALID', 'Pi models configuration is invalid.');
724
+ }
725
+ let config;
726
+ try {
727
+ config = await modelConfigStore.update(payload);
728
+ } catch (error) {
729
+ if (error?.code === 'PI_MODEL_CONFIG_INVALID') {
730
+ throw new SessionDaemonProtocolError('PI_MODEL_CONFIG_INVALID', 'Pi models configuration is invalid.');
731
+ }
732
+ throw error;
733
+ }
734
+ // ModelRuntime snapshots models.json at construction. Rehydrate only while
735
+ // idle so catalog changes are authoritative immediately and never race a turn.
736
+ servicesCache.clear();
737
+ if (activeRuntime) {
738
+ rememberRuntimeSession();
739
+ await disposeRuntime();
740
+ await ensureRuntime();
741
+ }
742
+ return { config };
743
+ };
744
+
745
+ const providerStatus = async (providerId) => {
746
+ if (typeof providerId !== 'string' || providerId.length === 0 || providerId.length > 256) {
747
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested provider is invalid.');
748
+ }
749
+ const activeRuntime = await ensureRuntime();
750
+ const modelRuntime = activeRuntime.session?.modelRuntime;
751
+ if (!modelRuntime?.getProvider?.(providerId)) {
752
+ throw new SessionDaemonProtocolError('PROVIDER_NOT_FOUND', 'The requested provider is unavailable.');
753
+ }
754
+ const auth = modelRuntime.getProviderAuthStatus?.(providerId);
755
+ return { providerId, authenticated: auth?.configured === true };
756
+ };
757
+
758
+ const projectLoginAttempt = (attempt) => ({
759
+ id: attempt.id,
760
+ providerId: attempt.providerId,
761
+ state: attempt.state,
762
+ ...(attempt.prompt ? { prompt: attempt.prompt } : {}),
763
+ ...(attempt.authUrl ? { authUrl: attempt.authUrl } : {}),
764
+ ...(attempt.deviceCode ? { deviceCode: attempt.deviceCode } : {}),
765
+ ...(attempt.errorCode ? { error: { code: attempt.errorCode } } : {}),
766
+ });
767
+
768
+ const getLoginAttempt = (providerId, attemptId) => {
769
+ const attempt = loginAttempts.get(attemptId);
770
+ if (!attempt || attempt.providerId !== providerId) {
771
+ throw new SessionDaemonProtocolError('PROVIDER_AUTH_REQUIRED', 'The provider login attempt is unavailable.');
772
+ }
773
+ return attempt;
774
+ };
775
+
776
+ const expireLoginAttempt = (attempt) => {
777
+ const timer = setTimeout(() => {
778
+ if (loginAttempts.get(attempt.id) === attempt) {
779
+ attempt.controller.abort();
780
+ attempt.rejectPrompt?.(new Error('Provider login expired.'));
781
+ loginAttempts.delete(attempt.id);
782
+ }
783
+ }, 10 * 60 * 1_000);
784
+ timer.unref?.();
785
+ return timer;
786
+ };
787
+
788
+ const startProviderLogin = async (payload) => {
789
+ if (!payload || typeof payload !== 'object' || typeof payload.providerId !== 'string'
790
+ || !['api_key', 'oauth'].includes(payload.type)
791
+ || (payload.apiKey !== undefined && (typeof payload.apiKey !== 'string' || payload.apiKey.length === 0 || payload.apiKey.length > 16_384))) {
792
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The provider login request is invalid.');
793
+ }
794
+ if (payload.type === 'api_key' && typeof payload.apiKey !== 'string') {
795
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The provider API key is required.');
796
+ }
797
+ const activeRuntime = await ensureRuntime();
798
+ const modelRuntime = activeRuntime.session?.modelRuntime;
799
+ if (!modelRuntime?.getProvider?.(payload.providerId)) {
800
+ throw new SessionDaemonProtocolError('PROVIDER_NOT_FOUND', 'The requested provider is unavailable.');
801
+ }
802
+ const controller = new AbortController();
803
+ const attempt = {
804
+ id: randomUUID(), providerId: payload.providerId, state: 'pending', controller,
805
+ prompt: undefined, authUrl: undefined, deviceCode: undefined, errorCode: undefined,
806
+ resolvePrompt: undefined, rejectPrompt: undefined,
807
+ };
808
+ attempt.expiry = expireLoginAttempt(attempt);
809
+ loginAttempts.set(attempt.id, attempt);
810
+ const apiKey = payload.apiKey;
811
+ const interaction = {
812
+ signal: controller.signal,
813
+ prompt: async (prompt) => {
814
+ if (payload.type === 'api_key') return apiKey;
815
+ if (!prompt || !['text', 'secret', 'select', 'manual_code'].includes(prompt.type)) {
816
+ throw new Error('Unsupported provider login prompt.');
817
+ }
818
+ attempt.prompt = {
819
+ type: prompt.type,
820
+ ...(typeof prompt.message === 'string' ? { message: prompt.message } : {}),
821
+ ...(typeof prompt.placeholder === 'string' ? { placeholder: prompt.placeholder } : {}),
822
+ ...(Array.isArray(prompt.options) ? { options: prompt.options
823
+ .filter((option) => option && typeof option.id === 'string' && typeof option.label === 'string')
824
+ .map((option) => ({ id: option.id, label: option.label, ...(typeof option.description === 'string' ? { description: option.description } : {}) })) } : {}),
825
+ };
826
+ return new Promise((resolve, reject) => {
827
+ attempt.resolvePrompt = resolve;
828
+ attempt.rejectPrompt = reject;
829
+ controller.signal.addEventListener('abort', () => reject(new Error('Provider login cancelled.')), { once: true });
830
+ });
831
+ },
832
+ notify: (event) => {
833
+ if (!event || typeof event !== 'object') return;
834
+ if (event.type === 'auth_url' && typeof event.url === 'string') {
835
+ attempt.authUrl = { url: event.url, ...(typeof event.instructions === 'string' ? { instructions: event.instructions } : {}) };
836
+ } else if (event.type === 'device_code' && typeof event.userCode === 'string' && typeof event.verificationUri === 'string') {
837
+ attempt.deviceCode = {
838
+ userCode: event.userCode, verificationUri: event.verificationUri,
839
+ ...(Number.isFinite(event.intervalSeconds) ? { intervalSeconds: event.intervalSeconds } : {}),
840
+ ...(Number.isFinite(event.expiresInSeconds) ? { expiresInSeconds: event.expiresInSeconds } : {}),
841
+ };
842
+ }
843
+ },
844
+ };
845
+ void modelRuntime.login(payload.providerId, payload.type, interaction).then(
846
+ () => { attempt.state = 'complete'; attempt.prompt = undefined; },
847
+ () => { attempt.state = 'failed'; attempt.prompt = undefined; attempt.errorCode = 'PROVIDER_AUTH_REQUIRED'; },
848
+ ).finally(() => {
849
+ clearTimeout(attempt.expiry);
850
+ const timer = setTimeout(() => loginAttempts.delete(attempt.id), 5 * 60 * 1_000);
851
+ timer.unref?.();
852
+ });
853
+ return { login: projectLoginAttempt(attempt) };
854
+ };
855
+
856
+ const respondProviderLogin = (payload) => {
857
+ if (!payload || typeof payload !== 'object' || typeof payload.providerId !== 'string' || typeof payload.loginId !== 'string'
858
+ || typeof payload.value !== 'string' || payload.value.length > 16_384) {
859
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The provider login response is invalid.');
860
+ }
861
+ const attempt = getLoginAttempt(payload.providerId, payload.loginId);
862
+ if (attempt.state !== 'pending' || !attempt.resolvePrompt) {
863
+ throw new SessionDaemonProtocolError('PROVIDER_AUTH_REQUIRED', 'The provider login is not awaiting input.');
864
+ }
865
+ const resolve = attempt.resolvePrompt;
866
+ attempt.prompt = undefined;
867
+ attempt.resolvePrompt = undefined;
868
+ attempt.rejectPrompt = undefined;
869
+ resolve(payload.value);
870
+ return { login: projectLoginAttempt(attempt) };
871
+ };
872
+
873
+ const logoutProvider = async (providerId) => {
874
+ const status = await providerStatus(providerId);
875
+ const activeRuntime = await ensureRuntime();
876
+ await activeRuntime.session?.modelRuntime?.logout?.(providerId);
877
+ return { providerId: status.providerId, authenticated: false };
878
+ };
879
+
880
+ const readPiSettings = (requestedDirectory) => {
881
+ const targetDir = requestedDirectory || activeDirectory || cwd;
882
+ const trustStore = createTrustStore(agentDir);
883
+ const trust = trustStore.get(targetDir);
884
+ const manager = createSettingsManager({ cwd: targetDir, agentDir, projectTrusted: trust === true });
885
+ const global = manager.getGlobalSettings();
886
+ const project = manager.getProjectSettings();
887
+ return {
888
+ global: {
889
+ ...(typeof global.defaultProvider === 'string' ? { defaultProvider: global.defaultProvider } : {}),
890
+ ...(typeof global.defaultModel === 'string' ? { defaultModel: global.defaultModel } : {}),
891
+ ...(typeof global.defaultThinkingLevel === 'string' ? { defaultThinking: global.defaultThinkingLevel } : {}),
892
+ ...(typeof global.defaultProjectTrust === 'string' ? { defaultProjectTrust: global.defaultProjectTrust } : {}),
893
+ },
894
+ project: {
895
+ trusted: trust === true,
896
+ ...(trust === false ? { denied: true } : {}),
897
+ ...(trust === null && hasTrustRequiringProjectResources(targetDir) ? { requiresTrust: true } : {}),
898
+ ...(trust === true && typeof project.defaultProvider === 'string' ? { defaultProvider: project.defaultProvider } : {}),
899
+ ...(trust === true && typeof project.defaultModel === 'string' ? { defaultModel: project.defaultModel } : {}),
900
+ ...(trust === true && typeof project.defaultThinkingLevel === 'string' ? { defaultThinking: project.defaultThinkingLevel } : {}),
901
+ },
902
+ };
903
+ };
904
+
905
+ const setPiSettings = async (payload) => {
906
+ if (!payload || typeof payload !== 'object' || !['global', 'project'].includes(payload.scope)) {
907
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi settings request is invalid.');
908
+ }
909
+ const targetDir = payload.directory ? await resolveDirectory(payload.directory) : (activeDirectory || cwd);
910
+ const hasModel = Object.hasOwn(payload, 'defaultModel');
911
+ const hasThinking = Object.hasOwn(payload, 'defaultThinking');
912
+ const hasTrust = Object.hasOwn(payload, 'trust');
913
+ if (!hasModel && !hasThinking && !hasTrust) throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi settings request is empty.');
914
+ if (hasModel && payload.defaultModel !== null && (!payload.defaultModel || typeof payload.defaultModel.providerId !== 'string'
915
+ || typeof payload.defaultModel.modelId !== 'string' || payload.defaultModel.providerId.length === 0 || payload.defaultModel.modelId.length === 0)) {
916
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi default model is invalid.');
917
+ }
918
+ if (hasThinking && payload.defaultThinking !== null && !['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(payload.defaultThinking)) {
919
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi default thinking level is invalid.');
920
+ }
921
+ if (hasTrust && payload.trust !== null && typeof payload.trust !== 'boolean') {
922
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The project trust decision is invalid.');
923
+ }
924
+ if (hasTrust && runtime?.session?.isStreaming) {
925
+ throw new SessionDaemonProtocolError('SESSION_BUSY', 'Project trust cannot change during an active session.');
926
+ }
927
+ const trustStore = createTrustStore(agentDir);
928
+ if (hasTrust) trustStore.set(targetDir, payload.trust);
929
+ const trusted = trustStore.get(targetDir) === true;
930
+ if (payload.scope === 'project' && !trusted && (hasModel || hasThinking)) {
931
+ throw new SessionDaemonProtocolError('PROJECT_UNTRUSTED', 'The project is not trusted.');
932
+ }
933
+ if (hasModel || hasThinking) {
934
+ const manager = createSettingsManager({ cwd: targetDir, agentDir, projectTrusted: trusted });
935
+ if (payload.scope === 'global') {
936
+ if (hasModel) manager.setDefaultModelAndProvider(payload.defaultModel?.providerId, payload.defaultModel?.modelId);
937
+ if (hasThinking) manager.setDefaultThinkingLevel(payload.defaultThinking ?? undefined);
938
+ } else {
939
+ if (hasModel) {
940
+ manager.updateProjectSettings('defaultProvider', (settings) => {
941
+ if (payload.defaultModel === null) delete settings.defaultProvider;
942
+ else settings.defaultProvider = payload.defaultModel.providerId;
943
+ });
944
+ manager.updateProjectSettings('defaultModel', (settings) => {
945
+ if (payload.defaultModel === null) delete settings.defaultModel;
946
+ else settings.defaultModel = payload.defaultModel.modelId;
947
+ });
948
+ }
949
+ if (hasThinking) manager.updateProjectSettings('defaultThinkingLevel', (settings) => {
950
+ if (payload.defaultThinking === null) delete settings.defaultThinkingLevel;
951
+ else settings.defaultThinkingLevel = payload.defaultThinking;
952
+ });
953
+ }
954
+ await manager.flush();
955
+ if (manager.drainErrors().length > 0) throw new SessionDaemonProtocolError('PI_SETTINGS_INVALID', 'Pi settings could not be written.');
956
+ }
957
+ if (hasTrust && runtime) {
958
+ await disposeRuntime();
959
+ await ensureRuntime();
960
+ }
961
+ return readPiSettings(targetDir);
962
+ };
963
+
964
+ const resourceId = (kind, filePath) => `${kind}:${createHash('sha256').update(filePath).digest('base64url')}`;
965
+
966
+ const resourceLocation = (sourceInfo) => {
967
+ if (sourceInfo?.scope === 'project') return 'project';
968
+ if (sourceInfo?.origin === 'package') return 'package';
969
+ if (sourceInfo?.scope === 'user') return 'global';
970
+ return 'path';
971
+ };
972
+
973
+ const resourceCatalog = async (requestedDirectory) => {
974
+ const targetDir = requestedDirectory ? await resolveDirectory(requestedDirectory) : (activeDirectory || cwd);
975
+ const activeRuntime = await ensureRuntime(targetDir);
976
+ const loader = activeRuntime?.services?.resourceLoader;
977
+ if (!loader || typeof loader.getSkills !== 'function' || typeof loader.getPrompts !== 'function' || typeof loader.getAgentsFiles !== 'function') {
978
+ throw new SessionDaemonProtocolError('DAEMON_REQUEST_FAILED', 'Pi resource discovery is unavailable.');
979
+ }
980
+ const skills = loader.getSkills().skills.map((skill) => ({
981
+ id: resourceId('skill', skill.filePath),
982
+ kind: 'skill', name: skill.name, ...(skill.description ? { description: skill.description } : {}), location: resourceLocation(skill.sourceInfo), editable: false,
983
+ }));
984
+ const prompts = loader.getPrompts().prompts.map((prompt) => ({
985
+ id: resourceId('prompt', prompt.filePath),
986
+ kind: 'prompt', name: prompt.name, ...(prompt.description ? { description: prompt.description } : {}),
987
+ location: resourceLocation(prompt.sourceInfo), content: prompt.content,
988
+ editable: prompt.sourceInfo?.origin === 'top-level' && ['user', 'project'].includes(prompt.sourceInfo?.scope),
989
+ filePath: prompt.filePath,
990
+ }));
991
+ const agents = loader.getAgentsFiles().agentsFiles.map((agent) => ({
992
+ id: resourceId('agents', agent.path), kind: 'agents', name: basename(agent.path),
993
+ location: agent.path.startsWith(agentDir) ? 'global' : 'project', content: agent.content, editable: true, filePath: agent.path,
994
+ }));
995
+ const globalAgentsPath = join(agentDir, 'AGENTS.md');
996
+ const projectAgentsPath = join(targetDir, 'AGENTS.md');
997
+ for (const [location, filePath] of [['global', globalAgentsPath], ['project', projectAgentsPath]]) {
998
+ if (!agents.some((agent) => agent.filePath === filePath)) {
999
+ agents.push({ id: resourceId('agents', filePath), kind: 'agents', name: 'AGENTS.md', location, content: '', editable: true, filePath });
1000
+ }
1001
+ }
1002
+ return { skills, prompts, agents };
1003
+ };
1004
+
1005
+ const publicResources = (catalog) => ({
1006
+ skills: catalog.skills.map(({ filePath, ...resource }) => resource),
1007
+ prompts: catalog.prompts.map(({ filePath, ...resource }) => resource),
1008
+ agents: catalog.agents.map(({ filePath, ...resource }) => resource),
1009
+ });
1010
+
1011
+ const requireIdleResourceMutation = () => {
1012
+ if (runtime?.session?.isStreaming) throw new SessionDaemonProtocolError('SESSION_BUSY', 'Resources cannot change during an active session.');
1013
+ };
1014
+
1015
+ const writeResourceFile = async (filePath, content) => {
1016
+ const temporary = `${filePath}.${randomUUID()}.tmp`;
1017
+ await mkdir(dirname(filePath), { recursive: true, mode: 0o700 });
1018
+ try {
1019
+ await writeFile(temporary, content, { encoding: 'utf8', mode: 0o600 });
1020
+ await rename(temporary, filePath);
1021
+ } catch (error) {
1022
+ await rm(temporary, { force: true }).catch(() => {});
1023
+ throw error;
1024
+ }
1025
+ };
1026
+
1027
+ const refreshResources = async (targetDir) => {
1028
+ servicesCache.delete(targetDir || activeDirectory || cwd);
1029
+ if (runtime) {
1030
+ await disposeRuntime();
1031
+ await ensureRuntime();
1032
+ }
1033
+ return publicResources(await resourceCatalog(targetDir));
1034
+ };
1035
+
1036
+ const updateResource = async (payload) => {
1037
+ if (!payload || typeof payload.resourceId !== 'string' || typeof payload.content !== 'string' || payload.content.length > 200_000) {
1038
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi resource update is invalid.');
1039
+ }
1040
+ requireIdleResourceMutation();
1041
+ const targetDir = payload.directory ? await resolveDirectory(payload.directory) : (activeDirectory || cwd);
1042
+ const catalog = await resourceCatalog(targetDir);
1043
+ const resource = [...catalog.prompts, ...catalog.agents].find((item) => item.id === payload.resourceId && item.editable === true);
1044
+ if (!resource?.filePath) throw new SessionDaemonProtocolError('RESOURCE_NOT_FOUND', 'The requested Pi resource is not editable.');
1045
+ let content = payload.content;
1046
+ if (resource.kind === 'prompt') {
1047
+ const previous = await readFile(resource.filePath, 'utf8').catch((error) => error?.code === 'ENOENT' ? '' : Promise.reject(error));
1048
+ const frontmatter = previous.match(/^(---\r?\n[\s\S]*?\r?\n---\r?\n?)/)?.[1] ?? '';
1049
+ content = `${frontmatter}${content}`;
1050
+ }
1051
+ await writeResourceFile(resource.filePath, content);
1052
+ return refreshResources(targetDir);
1053
+ };
1054
+
1055
+ const createPrompt = async (payload) => {
1056
+ if (!payload || !['global', 'project'].includes(payload.location) || typeof payload.name !== 'string' || typeof payload.content !== 'string'
1057
+ || typeof payload.description !== 'string' || payload.content.length > 200_000 || payload.description.length > 4_000
1058
+ || !/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(payload.name)) {
1059
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi prompt template is invalid.');
1060
+ }
1061
+ requireIdleResourceMutation();
1062
+ const targetDir = payload.directory ? await resolveDirectory(payload.directory) : (activeDirectory || cwd);
1063
+ const trust = createTrustStore(agentDir).get(targetDir);
1064
+ if (payload.location === 'project' && trust !== true) throw new SessionDaemonProtocolError('PROJECT_UNTRUSTED', 'The project is not trusted.');
1065
+ const filePath = join(payload.location === 'global' ? agentDir : join(targetDir, '.pi'), 'prompts', `${payload.name}.md`);
1066
+ try {
1067
+ await readFile(filePath, 'utf8');
1068
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi prompt template already exists.');
1069
+ } catch (error) {
1070
+ if (error?.code !== 'ENOENT') throw error;
1071
+ }
1072
+ await writeResourceFile(filePath, `---\ndescription: ${JSON.stringify(payload.description)}\n---\n${payload.content}`);
1073
+ return refreshResources(targetDir);
1074
+ };
1075
+
1076
+ const deletePrompt = async (payload) => {
1077
+ if (!payload || typeof payload.resourceId !== 'string') throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The Pi prompt template is invalid.');
1078
+ requireIdleResourceMutation();
1079
+ const targetDir = payload.directory ? await resolveDirectory(payload.directory) : (activeDirectory || cwd);
1080
+ const catalog = await resourceCatalog(targetDir);
1081
+ const resource = catalog.prompts.find((item) => item.id === payload.resourceId && item.editable === true);
1082
+ if (!resource?.filePath) throw new SessionDaemonProtocolError('RESOURCE_NOT_FOUND', 'The requested Pi prompt template is not editable.');
1083
+ await rm(resource.filePath);
1084
+ return refreshResources(targetDir);
1085
+ };
1086
+
1087
+ const setSessionModel = async (activeRuntime, model) => {
1088
+ if (!model || typeof model.providerId !== 'string' || typeof model.modelId !== 'string') {
1089
+ throw new SessionDaemonProtocolError('INVALID_MODEL', 'The requested Pi model is invalid.');
1090
+ }
1091
+ const selected = activeRuntime.session?.modelRuntime?.getModel?.(model.providerId, model.modelId);
1092
+ if (!selected) throw new SessionDaemonProtocolError('INVALID_MODEL', 'The requested Pi model is unavailable.');
1093
+ await activeRuntime.session.setModel(selected);
1094
+ };
1095
+
1096
+ const publishSessionModel = (session, sessionId = session?.sessionId, directory) => {
1097
+ const model = session?.model;
1098
+ if (!model?.provider || !model?.id) {
1099
+ throw new SessionDaemonProtocolError('INVALID_MODEL', 'Pi did not select a valid model.');
1100
+ }
1101
+ publish('session.model', { model: { providerId: model.provider, modelId: model.id } }, sessionId, directory);
1102
+ };
1103
+
1104
+ const resolveLiveModel = (runtime) => {
1105
+ const current = runtime?.session?.model;
1106
+ if (!current?.provider || !current?.id) return null;
1107
+ const modelRuntime = runtime.session.modelRuntime;
1108
+ const fromGet = modelRuntime?.getModel?.(current.provider, current.id);
1109
+ if (fromGet && (fromGet.reasoning === true || fromGet.thinkingLevelMap)) return fromGet;
1110
+ const models = modelRuntime?.getModels?.();
1111
+ if (Array.isArray(models)) {
1112
+ const listed = models.find((model) => model?.provider === current.provider && model?.id === current.id);
1113
+ if (listed) return listed;
1114
+ }
1115
+ return fromGet ?? current;
1116
+ };
1117
+
1118
+ const applyThinking = (runtime, thinking, sessionId, directory) => {
1119
+ validateThinking(thinking);
1120
+ const model = resolveLiveModel(runtime);
1121
+ const next = model && (model.reasoning === true || model.thinkingLevelMap)
1122
+ ? clampThinkingLevel(getSupportedThinkingLevels(model), thinking)
1123
+ : thinking;
1124
+ runtime.session.setThinkingLevel(next);
1125
+ publish('session.thinking', { thinking: next }, sessionId, directory);
1126
+ };
1127
+
1128
+ const validateThinking = (thinking) => {
1129
+ if (!isPiThinkingLevel(thinking)) {
1130
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested thinking level is invalid.');
1131
+ }
1132
+ };
1133
+
1134
+ const redactAttachmentPaths = (text) => typeof text === 'string'
1135
+ ? text
1136
+ .replace(/\[Attachment[^\]\r\n]*pi-clipboard-[0-9a-f-]{36}[^\]\r\n]*\]/gi, '[attachment]')
1137
+ .replace(/(?:[A-Za-z]:)?[^\s[\](){}"'`]*pi-clipboard-[0-9a-f-]{36}(?:\.[^\s\])}\]"'`,;]+)?/gi, '[attachment]')
1138
+ : '';
1139
+
1140
+ const redactAttachmentValues = (value) => {
1141
+ if (typeof value === 'string') return redactAttachmentPaths(value);
1142
+ if (Array.isArray(value)) return value.map(redactAttachmentValues);
1143
+ if (!value || typeof value !== 'object') return value;
1144
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, redactAttachmentValues(entry)]));
1145
+ };
1146
+
1147
+ /**
1148
+ * Normalize a Pi `AgentToolResult`-shaped value into public tool-part
1149
+ * fields. Text content becomes `output`; `details` become renderer
1150
+ * `metadata` (edit diffs, truncation notes); the temporary-output path is
1151
+ * never exposed. An errored result surfaces its message as `error`.
1152
+ */
1153
+ const projectToolResult = (result, isError) => {
1154
+ const content = result && typeof result === 'object' && Array.isArray(result.content) ? result.content : [];
1155
+ const output = redactAttachmentPaths(content.filter((part) => part?.type === 'text').map((part) => part.text).join(''));
1156
+ let metadata;
1157
+ if (result && typeof result === 'object' && result.details && typeof result.details === 'object') {
1158
+ const details = redactAttachmentValues(result.details);
1159
+ if (details && typeof details === 'object') {
1160
+ metadata = { ...details };
1161
+ delete metadata.fullOutputPath;
1162
+ }
1163
+ }
1164
+ return {
1165
+ ...(output ? { output } : {}),
1166
+ ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),
1167
+ ...(isError && output ? { error: output } : {}),
1168
+ };
1169
+ };
1170
+
1171
+ /**
1172
+ * Sanitize Pi's `Usage` object into the public PiChamber `PiUsage` shape.
1173
+ * All numeric fields must be finite and non-negative; the object is
1174
+ * omitted entirely if any field is missing or wrong type. Unknown keys are
1175
+ * never passed through. Costs are normalized the same way as token counts
1176
+ * — Pi treats decimal cents as float, so the renderer is responsible for
1177
+ * rounding to a money locale.
1178
+ */
1179
+ const projectUsage = (raw) => {
1180
+ if (!raw || typeof raw !== 'object') return null;
1181
+ const safeNonNegativeNumber = (value) => (typeof value === 'number' && Number.isFinite(value) && value >= 0) ? value : null;
1182
+ const input = safeNonNegativeNumber(raw.input);
1183
+ const output = safeNonNegativeNumber(raw.output);
1184
+ const cacheRead = safeNonNegativeNumber(raw.cacheRead);
1185
+ const cacheWrite = safeNonNegativeNumber(raw.cacheWrite);
1186
+ const totalTokens = safeNonNegativeNumber(raw.totalTokens);
1187
+ const rawCost = raw.cost && typeof raw.cost === 'object' ? raw.cost : null;
1188
+ if (!rawCost) return null;
1189
+ const costInput = safeNonNegativeNumber(rawCost.input);
1190
+ const costOutput = safeNonNegativeNumber(rawCost.output);
1191
+ const costCacheRead = safeNonNegativeNumber(rawCost.cacheRead);
1192
+ const costCacheWrite = safeNonNegativeNumber(rawCost.cacheWrite);
1193
+ const costTotal = safeNonNegativeNumber(rawCost.total);
1194
+ if (
1195
+ input === null || output === null || cacheRead === null || cacheWrite === null || totalTokens === null
1196
+ || costInput === null || costOutput === null || costCacheRead === null || costCacheWrite === null || costTotal === null
1197
+ ) {
1198
+ return null;
1199
+ }
1200
+ return {
1201
+ input,
1202
+ output,
1203
+ cacheRead,
1204
+ cacheWrite,
1205
+ totalTokens,
1206
+ cost: {
1207
+ input: costInput,
1208
+ output: costOutput,
1209
+ cacheRead: costCacheRead,
1210
+ cacheWrite: costCacheWrite,
1211
+ total: costTotal,
1212
+ },
1213
+ };
1214
+ };
1215
+
1216
+ // Deltas can split `pi-clipboard-` and its UUID across arbitrary frames.
1217
+ // Hold a small suffix, then hold the complete sensitive token once its marker
1218
+ // appears. This prevents the browser reducer from reconstructing a path that
1219
+ // no individual frame contained in full.
1220
+ const redactStreamingAttachmentDelta = (key, delta) => {
1221
+ const marker = 'pi-clipboard-';
1222
+ let pending = `${streamingRedactionBuffers.get(key) ?? ''}${typeof delta === 'string' ? delta : ''}`;
1223
+ let output = '';
1224
+ while (pending) {
1225
+ const markerIndex = pending.toLowerCase().indexOf(marker);
1226
+ if (markerIndex < 0) {
1227
+ const lowerPending = pending.toLowerCase();
1228
+ let partialLength = 0;
1229
+ for (let length = Math.min(marker.length - 1, pending.length); length > 0; length -= 1) {
1230
+ if (marker.startsWith(lowerPending.slice(-length))) {
1231
+ partialLength = length;
1232
+ break;
1233
+ }
1234
+ }
1235
+ if (partialLength === 0) {
1236
+ output += pending;
1237
+ pending = '';
1238
+ break;
1239
+ }
1240
+ let partialStart = pending.length - partialLength;
1241
+ while (partialStart > 0 && !/[\s[\](){}"'`,;]/.test(pending[partialStart - 1])) partialStart -= 1;
1242
+ output += pending.slice(0, partialStart);
1243
+ pending = pending.slice(partialStart);
1244
+ break;
1245
+ }
1246
+ let tokenStart = markerIndex;
1247
+ while (tokenStart > 0 && !/[\s[\](){}"'`,;]/.test(pending[tokenStart - 1])) tokenStart -= 1;
1248
+ output += redactAttachmentPaths(pending.slice(0, tokenStart));
1249
+ const tokenEndOffset = pending.slice(markerIndex).search(/[\s[\](){}"'`,;]/);
1250
+ if (tokenEndOffset < 0) {
1251
+ pending = pending.slice(tokenStart);
1252
+ break;
1253
+ }
1254
+ output += '[attachment]';
1255
+ pending = pending.slice(markerIndex + tokenEndOffset);
1256
+ }
1257
+ streamingRedactionBuffers.set(key, pending);
1258
+ return output;
1259
+ };
1260
+
1261
+ const clearStreamingRedactionBuffers = (sessionId) => {
1262
+ const prefix = `${sessionId}:`;
1263
+ for (const key of streamingRedactionBuffers.keys()) {
1264
+ if (key.startsWith(prefix)) streamingRedactionBuffers.delete(key);
1265
+ }
1266
+ };
1267
+
1268
+ const prepareAttachmentContent = async (attachments) => {
1269
+ if (attachments === undefined) return { text: '', images: [] };
1270
+ if (!Array.isArray(attachments) || attachments.length > 32) throw new SessionDaemonProtocolError('INVALID_PROMPT', 'The session attachments are invalid.');
1271
+ const text = [];
1272
+ const images = [];
1273
+ for (const attachment of attachments) {
1274
+ if (!attachment || typeof attachment.path !== 'string' || typeof attachment.name !== 'string'
1275
+ || typeof attachment.mime !== 'string' || !Number.isSafeInteger(attachment.size) || attachment.size <= 0) {
1276
+ throw new SessionDaemonProtocolError('INVALID_PROMPT', 'The session attachments are invalid.');
1277
+ }
1278
+ try {
1279
+ if (attachment.mime.startsWith('image/') && attachment.size <= 20 * 1024 * 1024) {
1280
+ const data = await readFile(attachment.path);
1281
+ images.push({ type: 'image', mimeType: attachment.mime, data: data.toString('base64') });
1282
+ } else {
1283
+ await stat(attachment.path);
1284
+ text.push(`[Attachment ${attachment.name} is available at ${attachment.path}]`);
1285
+ }
1286
+ } catch (err) {
1287
+ if (err && err.code === 'ENOENT') {
1288
+ throw new SessionDaemonProtocolError('ATTACHMENT_MISSING', `The attached temporary file ${attachment.name} is no longer available.`);
1289
+ }
1290
+ throw err;
1291
+ }
1292
+ }
1293
+ return { text: text.join('\n'), images };
1294
+ };
1295
+
1296
+ const sessionInput = async (payload, delivery) => {
1297
+ if (!payload || typeof payload !== 'object' || typeof payload.sessionId !== 'string'
1298
+ || typeof payload.text !== 'string' || payload.text.length === 0 || Buffer.byteLength(payload.text) > 64 * 1024) {
1299
+ throw new SessionDaemonProtocolError('INVALID_PROMPT', 'The session prompt is invalid.');
1300
+ }
1301
+ if (payload.thinking !== undefined) validateThinking(payload.thinking);
1302
+ const activeRuntime = await activateSession(payload.sessionId, payload.directory);
1303
+ // After a provider stream dies, Pi can report idle while the UI still
1304
+ // retries as steer/follow-up. Start a new turn instead of rejecting.
1305
+ const deliverAs = delivery && activeRuntime.session.isStreaming ? delivery : undefined;
1306
+ if (!deliverAs && activeRuntime.session.isStreaming) {
1307
+ throw new SessionDaemonProtocolError('SESSION_BUSY', 'The Pi session already has an active run.');
1308
+ }
1309
+ if (payload.model !== undefined) {
1310
+ await setSessionModel(activeRuntime, payload.model);
1311
+ publishSessionModel(activeRuntime.session, payload.sessionId, activeRuntime.cwd);
1312
+ }
1313
+ if (payload.thinking !== undefined) {
1314
+ applyThinking(activeRuntime, payload.thinking, payload.sessionId, activeRuntime.cwd);
1315
+ }
1316
+
1317
+ // Auto-assign deterministic title on first prompt if session manager has no name yet
1318
+ const manager = activeRuntime.session?.sessionManager;
1319
+ if (typeof payload.text === 'string' && payload.text.trim().length > 0 && !manager?.getSessionName?.()) {
1320
+ const derived = deriveSessionTitle(payload.text);
1321
+ if (derived && typeof manager?.appendSessionInfo === 'function') {
1322
+ manager.appendSessionInfo(derived);
1323
+ publish('session.updated', { title: derived }, payload.sessionId, activeRuntime.cwd);
1324
+ }
1325
+ }
1326
+
1327
+ const attachments = await prepareAttachmentContent(payload.attachments);
1328
+ const text = [payload.text, attachments.text].filter(Boolean).join('\n\n');
1329
+ const content = attachments.images.length > 0
1330
+ ? [{ type: 'text', text }, ...attachments.images]
1331
+ : text;
1332
+ const messageId = typeof payload.messageId === 'string' && payload.messageId.length > 0
1333
+ ? payload.messageId
1334
+ : activeRuntime.session.sessionManager?.getLeafId?.() ?? `msg_${randomUUID()}`;
1335
+ // Prompt acceptance is not turn completion. Pi's send promise remains
1336
+ // pending for the whole agent loop, which can legitimately exceed the
1337
+ // 30-second HTTP/private-IPC request budget. Own it in the daemon and
1338
+ // report asynchronous failure through the existing session event channel.
1339
+ const generation = (sendGenerationBySession.get(payload.sessionId) ?? 0) + 1;
1340
+ sendGenerationBySession.set(payload.sessionId, generation);
1341
+ Promise.resolve(
1342
+ activeRuntime.session.sendUserMessage(content, deliverAs ? { deliverAs } : undefined),
1343
+ ).catch((error) => {
1344
+ if (sendGenerationBySession.get(payload.sessionId) !== generation) return;
1345
+ publish('session.error', {
1346
+ code: 'ASSISTANT_ERROR',
1347
+ ...(error instanceof Error && error.message
1348
+ ? { message: redactAttachmentPaths(error.message) }
1349
+ : {}),
1350
+ }, payload.sessionId, activeRuntime.cwd);
1351
+ if (!activeRuntime.session?.isStreaming) return;
1352
+ Promise.resolve(activeRuntime.session.abort()).catch(() => {});
1353
+ });
1354
+ return { accepted: true, messageId };
1355
+ };
1356
+
1357
+ const treeForSession = async (sessionId, requestedDirectory) => {
1358
+ const activeRuntime = await activateSession(sessionId, requestedDirectory);
1359
+ const nodes = activeRuntime.session.sessionManager?.getTree?.();
1360
+ if (!Array.isArray(nodes)) throw new SessionDaemonProtocolError('SESSION_TREE_NOT_FOUND', 'Pi returned an invalid session tree.');
1361
+ const project = (node) => ({
1362
+ entryId: node.entry.id,
1363
+ parentId: node.entry.parentId,
1364
+ ...(node.entry.type === 'session_info' && typeof node.entry.name === 'string' ? { title: node.entry.name } : {}),
1365
+ updatedAt: Date.parse(node.entry.timestamp) || 0,
1366
+ children: node.children.map(project),
1367
+ });
1368
+ return { rootId: sessionId, nodes: nodes.map(project) };
1369
+ };
1370
+
1371
+ const deleteSession = async (sessionId, requestedDirectory) => {
1372
+ const active = runtimeRegistry?.findBySessionId(sessionId);
1373
+ let targetDir = requestedDirectory ? await resolveDirectory(requestedDirectory) : active?.cwd || activeDirectory || cwd;
1374
+ if (active) {
1375
+ if (active.session?.isStreaming) await active.session.abort();
1376
+ await runtimeRegistry?.dispose(active);
1377
+ if (runtime === active) runtime = undefined;
1378
+ }
1379
+ try {
1380
+ const { target, directory } = await findPersistedSession(sessionId, targetDir);
1381
+ targetDir = directory;
1382
+ await rm(target.path, { force: false });
1383
+ } catch (error) {
1384
+ if (!active || error?.code !== 'INVALID_SESSION') throw error;
1385
+ }
1386
+ publish('session.lifecycle', { state: 'idle', deleted: true }, sessionId, targetDir);
1387
+ };
1388
+
1389
+ const publishSessionEvent = (sessionId, event, directory = activeDirectory || cwd) => {
1390
+ switch (event.type) {
1391
+ case 'message_start': {
1392
+ if (event.message?.role === 'user') {
1393
+ const content = event.message.content;
1394
+ const text = redactAttachmentPaths(typeof content === 'string'
1395
+ ? content
1396
+ : Array.isArray(content)
1397
+ ? content.filter((part) => part?.type === 'text').map((part) => part.text).join('')
1398
+ : '');
1399
+ const messageId = `user-${sessionId}-${sequence + 1}`;
1400
+ latestUserMessageIds.set(sessionId, messageId);
1401
+ publish('assistant.message.start', {
1402
+ messageId,
1403
+ role: 'user',
1404
+ text,
1405
+ startedAt: Number.isFinite(event.message.timestamp) ? event.message.timestamp : Date.now(),
1406
+ }, sessionId, directory);
1407
+ } else if (event.message?.role === 'assistant') {
1408
+ const messageId = `assistant-${sessionId}-${sequence + 1}`;
1409
+ clearStreamingRedactionBuffers(sessionId);
1410
+ streamingMessageIds.set(sessionId, messageId);
1411
+ latestAssistantMessageIds.set(sessionId, messageId);
1412
+ const startedAt = Number.isFinite(event.message.timestamp) ? event.message.timestamp : Date.now();
1413
+ messageStartedAt.set(messageId, startedAt);
1414
+ publish('assistant.message.start', {
1415
+ messageId,
1416
+ role: 'assistant',
1417
+ ...(latestUserMessageIds.get(sessionId) ? { parentId: latestUserMessageIds.get(sessionId) } : {}),
1418
+ startedAt,
1419
+ ...(event.message.provider && event.message.model ? { model: { providerId: event.message.provider, modelId: event.message.model } } : {}),
1420
+ }, sessionId, directory);
1421
+ }
1422
+ break;
1423
+ }
1424
+ case 'message_update': {
1425
+ const update = event.assistantMessageEvent;
1426
+ const messageId = streamingMessageIds.get(sessionId) ?? latestAssistantMessageIds.get(sessionId) ?? `assistant-${sessionId}`;
1427
+ if (update.type === 'text_delta') {
1428
+ const delta = redactStreamingAttachmentDelta(`${sessionId}:text:${update.contentIndex}`, update.delta);
1429
+ if (delta) publish('assistant.message.delta', { messageId, partId: `${messageId}:text:${update.contentIndex}`, contentIndex: update.contentIndex, delta }, sessionId, directory);
1430
+ } else if (update.type === 'thinking_delta') {
1431
+ const delta = redactStreamingAttachmentDelta(`${sessionId}:thinking:${update.contentIndex}`, update.delta);
1432
+ if (delta) publish('assistant.thinking.delta', { messageId, partId: `${messageId}:thinking:${update.contentIndex}`, contentIndex: update.contentIndex, delta }, sessionId, directory);
1433
+ }
1434
+ break;
1435
+ }
1436
+ case 'message_end': {
1437
+ if (event.message?.role === 'assistant') {
1438
+ const content = Array.isArray(event.message.content) ? event.message.content : [];
1439
+ const messageId = streamingMessageIds.get(sessionId) ?? latestAssistantMessageIds.get(sessionId) ?? `assistant-${sessionId}`;
1440
+ const startedAt = messageStartedAt.get(messageId) ?? Date.now();
1441
+ messageStartedAt.delete(messageId);
1442
+ const durationMs = Math.max(100, Date.now() - startedAt);
1443
+ const usage = projectUsage(event.message.usage);
1444
+ publish('assistant.message.end', {
1445
+ messageId,
1446
+ text: redactAttachmentPaths(content.filter((part) => part?.type === 'text').map((part) => part.text).join('')),
1447
+ thinking: redactAttachmentPaths(content.filter((part) => part?.type === 'thinking').map((part) => part.thinking).join('')),
1448
+ durationMs,
1449
+ ...(event.message.errorMessage ? { error: { code: 'ASSISTANT_ERROR', message: redactAttachmentPaths(event.message.errorMessage) } } : {}),
1450
+ ...(usage ? { usage } : {}),
1451
+ }, sessionId, directory);
1452
+ streamingMessageIds.delete(sessionId);
1453
+ clearStreamingRedactionBuffers(sessionId);
1454
+ }
1455
+ break;
1456
+ }
1457
+ case 'tool_execution_start': {
1458
+ const messageId = streamingMessageIds.get(sessionId) ?? latestAssistantMessageIds.get(sessionId) ?? `assistant-${sessionId}`;
1459
+ const startedAt = Date.now();
1460
+ toolStartedAt.set(event.toolCallId, startedAt);
1461
+ publish('session.tool.start', {
1462
+ toolCallId: event.toolCallId,
1463
+ partId: `${messageId}:tool:${event.toolCallId}`,
1464
+ messageId,
1465
+ name: event.toolName,
1466
+ toolName: event.toolName,
1467
+ state: 'running',
1468
+ ...(event.args !== undefined ? { input: redactAttachmentValues(event.args) } : {}),
1469
+ startedAt,
1470
+ }, sessionId, directory);
1471
+ break;
1472
+ }
1473
+ case 'tool_execution_update': {
1474
+ const messageId = streamingMessageIds.get(sessionId) ?? latestAssistantMessageIds.get(sessionId) ?? `assistant-${sessionId}`;
1475
+ const projected = projectToolResult(event.partialResult, false);
1476
+ publish('session.tool.update', {
1477
+ toolCallId: event.toolCallId,
1478
+ partId: `${messageId}:tool:${event.toolCallId}`,
1479
+ messageId,
1480
+ name: event.toolName,
1481
+ toolName: event.toolName,
1482
+ state: 'running',
1483
+ ...(event.args !== undefined ? { input: redactAttachmentValues(event.args) } : {}),
1484
+ ...projected,
1485
+ }, sessionId, directory);
1486
+ break;
1487
+ }
1488
+ case 'tool_execution_end': {
1489
+ const messageId = streamingMessageIds.get(sessionId) ?? latestAssistantMessageIds.get(sessionId) ?? `assistant-${sessionId}`;
1490
+ const startedAt = toolStartedAt.get(event.toolCallId);
1491
+ toolStartedAt.delete(event.toolCallId);
1492
+ const projected = projectToolResult(event.result, event.isError === true);
1493
+ publish('session.tool.end', {
1494
+ toolCallId: event.toolCallId,
1495
+ partId: `${messageId}:tool:${event.toolCallId}`,
1496
+ messageId,
1497
+ name: event.toolName,
1498
+ toolName: event.toolName,
1499
+ state: event.isError ? 'error' : 'completed',
1500
+ isError: event.isError === true,
1501
+ ...projected,
1502
+ ...(Number.isFinite(startedAt) ? { startedAt } : {}),
1503
+ endedAt: Date.now(),
1504
+ }, sessionId, directory);
1505
+ break;
1506
+ }
1507
+ case 'queue_update':
1508
+ publish('session.queue', { steering: event.steering.length, followUp: event.followUp.length }, sessionId, directory);
1509
+ break;
1510
+ case 'agent_start':
1511
+ clearIdleDisposal(sessionId);
1512
+ publish('session.lifecycle', { state: 'busy' }, sessionId, directory);
1513
+ break;
1514
+ case 'agent_end': {
1515
+ latestUserMessageIds.delete(sessionId);
1516
+ latestAssistantMessageIds.delete(sessionId);
1517
+ const finalMessage = event.messages?.at?.(-1);
1518
+ if (finalMessage?.role === 'assistant' && finalMessage.stopReason === 'aborted') {
1519
+ publish('session.interrupted', { reason: 'user-abort', streaming: false }, sessionId, directory);
1520
+ } else if (finalMessage?.role === 'assistant' && typeof finalMessage.errorMessage === 'string') {
1521
+ publish('session.error', { code: 'ASSISTANT_ERROR', message: redactAttachmentPaths(finalMessage.errorMessage) }, sessionId, directory);
1522
+ }
1523
+ break;
1524
+ }
1525
+ case 'agent_settled':
1526
+ publish('session.lifecycle', { state: 'idle' }, sessionId, directory);
1527
+ scheduleIdleDisposal(sessionId);
1528
+ break;
1529
+ case 'thinking_level_changed':
1530
+ publish('session.thinking', { thinking: event.level }, sessionId, directory);
1531
+ break;
1532
+ case 'compaction_start':
1533
+ publish('session.compaction', { running: true }, sessionId, directory);
1534
+ break;
1535
+ case 'compaction_end':
1536
+ publish('session.compaction', { running: false }, sessionId, directory);
1537
+ break;
1538
+ default:
1539
+ break;
1540
+ }
1541
+ };
1542
+
1543
+ const handleRequest = async (socket, message) => {
1544
+ if (message.protocolVersion !== PROTOCOL_VERSION || message.kind !== 'request' || typeof message.requestId !== 'string') {
1545
+ throw new SessionDaemonProtocolError('INVALID_REQUEST', 'The daemon request is invalid.');
1546
+ }
1547
+
1548
+ switch (message.command) {
1549
+ case 'runtime.health':
1550
+ writeFrame(socket, {
1551
+ protocolVersion: PROTOCOL_VERSION,
1552
+ kind: 'response',
1553
+ requestId: message.requestId,
1554
+ result: {
1555
+ state: 'ready',
1556
+ sessionId: getSessionState().sessionId,
1557
+ lastSequence: sequence,
1558
+ capabilities: [
1559
+ 'projects.list', 'projects.select', 'sessions.list', 'sessions.create', 'sessions.open', 'sessions.rename', 'sessions.delete',
1560
+ 'sessions.tree', 'sessions.navigate', 'sessions.fork', 'sessions.clone', 'sessions.prompt',
1561
+ 'sessions.steer', 'sessions.followUp', 'sessions.abort', 'sessions.setModel',
1562
+ 'sessions.setThinking', 'sessions.compact', 'providers.list', 'providers.config.get', 'providers.models.set', 'providers.status', 'providers.login',
1563
+ 'providers.login.respond', 'providers.login.status', 'providers.logout', 'settings.get', 'settings.set',
1564
+ 'resources.list', 'resources.update', 'resources.prompts.create', 'resources.prompts.delete',
1565
+ ],
1566
+ ...(Number.isInteger(healthMetadata.daemonPid) ? { daemonPid: healthMetadata.daemonPid } : {}),
1567
+ },
1568
+ });
1569
+ return;
1570
+ case 'projects.list':
1571
+ writeFrame(socket, {
1572
+ protocolVersion: PROTOCOL_VERSION,
1573
+ kind: 'response',
1574
+ requestId: message.requestId,
1575
+ result: {
1576
+ projects: Array.from(knownDirectories).map((dir) => ({
1577
+ directory: dir,
1578
+ selected: dir === activeDirectory,
1579
+ })),
1580
+ },
1581
+ });
1582
+ return;
1583
+ case 'projects.select': {
1584
+ const targetDir = await resolveDirectory(message.payload?.directory);
1585
+ activeDirectory = targetDir;
1586
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: { directory: targetDir } });
1587
+ return;
1588
+ }
1589
+ case 'providers.list': {
1590
+ const result = await listProviders(message.payload?.directory);
1591
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1592
+ return;
1593
+ }
1594
+ case 'providers.config.get': {
1595
+ const result = await getProviderConfiguration(message.payload?.providerId);
1596
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1597
+ return;
1598
+ }
1599
+ case 'providers.models.set': {
1600
+ const result = await setProviderModels(message.payload);
1601
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1602
+ return;
1603
+ }
1604
+ case 'providers.status': {
1605
+ const result = await providerStatus(message.payload?.providerId);
1606
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1607
+ return;
1608
+ }
1609
+ case 'providers.login': {
1610
+ const result = await startProviderLogin(message.payload);
1611
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1612
+ return;
1613
+ }
1614
+ case 'providers.login.respond': {
1615
+ const result = respondProviderLogin(message.payload);
1616
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1617
+ return;
1618
+ }
1619
+ case 'providers.login.status': {
1620
+ const providerId = message.payload?.providerId;
1621
+ const loginId = message.payload?.loginId;
1622
+ if (typeof providerId !== 'string' || typeof loginId !== 'string') {
1623
+ throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The provider login identifier is invalid.');
1624
+ }
1625
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: { login: projectLoginAttempt(getLoginAttempt(providerId, loginId)) } });
1626
+ return;
1627
+ }
1628
+ case 'providers.logout': {
1629
+ const result = await logoutProvider(message.payload?.providerId);
1630
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1631
+ return;
1632
+ }
1633
+ case 'settings.get': {
1634
+ const result = readPiSettings(message.payload?.directory);
1635
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1636
+ return;
1637
+ }
1638
+ case 'settings.set': {
1639
+ const result = await setPiSettings(message.payload);
1640
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1641
+ return;
1642
+ }
1643
+ case 'resources.list': {
1644
+ const result = publicResources(await resourceCatalog(message.payload?.directory));
1645
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1646
+ return;
1647
+ }
1648
+ case 'resources.update': {
1649
+ const result = await updateResource(message.payload);
1650
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1651
+ return;
1652
+ }
1653
+ case 'resources.prompts.create': {
1654
+ const result = await createPrompt(message.payload);
1655
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1656
+ return;
1657
+ }
1658
+ case 'resources.prompts.delete': {
1659
+ const result = await deletePrompt(message.payload);
1660
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1661
+ return;
1662
+ }
1663
+ case 'sessions.list': {
1664
+ const sessions = await listSessionItems(message.payload?.directory || message.payload?.cwd);
1665
+ writeFrame(socket, {
1666
+ protocolVersion: PROTOCOL_VERSION,
1667
+ kind: 'response',
1668
+ requestId: message.requestId,
1669
+ result: { sessions },
1670
+ });
1671
+ return;
1672
+ }
1673
+ case 'sessions.open': {
1674
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1675
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: projectActiveSession(activeRuntime, activeRuntime.cwd) });
1676
+ return;
1677
+ }
1678
+ case 'sessions.rename': {
1679
+ await renameSession(message.payload);
1680
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1681
+ return;
1682
+ }
1683
+ case 'sessions.delete': {
1684
+ await deleteSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1685
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1686
+ return;
1687
+ }
1688
+ case 'sessions.tree': {
1689
+ const result = await treeForSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1690
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1691
+ return;
1692
+ }
1693
+ case 'sessions.navigate': {
1694
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1695
+ const messageId = message.payload?.messageId;
1696
+ if (typeof messageId !== 'string' || messageId.length === 0) throw new SessionDaemonProtocolError('INVALID_ARGUMENT', 'The requested tree entry is invalid.');
1697
+ const result = await activeRuntime.session.navigateTree(messageId);
1698
+ if (result.cancelled) throw new SessionDaemonProtocolError('SESSION_TREE_NOT_FOUND', 'Pi cancelled tree navigation.');
1699
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: projectActiveSession(activeRuntime, activeRuntime.cwd) });
1700
+ return;
1701
+ }
1702
+ case 'sessions.fork':
1703
+ case 'sessions.clone': {
1704
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1705
+ const entryId = message.command === 'sessions.fork' ? message.payload?.messageId : activeRuntime.session.sessionManager?.getLeafId?.();
1706
+ if (typeof entryId !== 'string' || entryId.length === 0) throw new SessionDaemonProtocolError('SESSION_TREE_NOT_FOUND', 'The Pi session has no fork point.');
1707
+ const result = await activeRuntime.fork(entryId, { position: 'at' });
1708
+ if (result.cancelled) throw new SessionDaemonProtocolError('SESSION_CREATE_CANCELLED', 'Pi cancelled session creation.');
1709
+ rememberRuntimeSession();
1710
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: projectActiveSession(activeRuntime, activeRuntime.cwd) });
1711
+ return;
1712
+ }
1713
+ case 'sessions.create': {
1714
+ const result = await createSession(message.payload);
1715
+ writeFrame(socket, {
1716
+ protocolVersion: PROTOCOL_VERSION,
1717
+ kind: 'response',
1718
+ requestId: message.requestId,
1719
+ result,
1720
+ });
1721
+ return;
1722
+ }
1723
+ case 'sessions.prompt':
1724
+ case 'sessions.steer':
1725
+ case 'sessions.followUp': {
1726
+ const payload = message.payload?.sessionId ? message.payload : { ...message.payload, sessionId: getSessionState().sessionId };
1727
+ const result = await sessionInput(payload, message.command === 'sessions.steer' ? 'steer' : message.command === 'sessions.followUp' ? 'followUp' : undefined);
1728
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result });
1729
+ return;
1730
+ }
1731
+ case 'sessions.abort': {
1732
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1733
+ const streaming = activeRuntime.session.isStreaming;
1734
+ await activeRuntime.session.abort();
1735
+ if (streaming) publish('session.interrupted', { reason: 'user-abort', streaming: true }, message.payload.sessionId, activeRuntime.cwd);
1736
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1737
+ return;
1738
+ }
1739
+ case 'sessions.setModel': {
1740
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1741
+ await setSessionModel(activeRuntime, message.payload?.model);
1742
+ publishSessionModel(activeRuntime.session, message.payload.sessionId, activeRuntime.cwd);
1743
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1744
+ return;
1745
+ }
1746
+ case 'sessions.setThinking': {
1747
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1748
+ applyThinking(activeRuntime, message.payload?.thinking, message.payload.sessionId, activeRuntime.cwd);
1749
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1750
+ return;
1751
+ }
1752
+ case 'sessions.compact': {
1753
+ if (message.payload?.thinking !== undefined) validateThinking(message.payload.thinking);
1754
+ const activeRuntime = await activateSession(message.payload?.sessionId, message.payload?.directory || message.payload?.cwd);
1755
+ if (message.payload?.model !== undefined) {
1756
+ await setSessionModel(activeRuntime, message.payload.model);
1757
+ publishSessionModel(activeRuntime.session, message.payload.sessionId, activeRuntime.cwd);
1758
+ }
1759
+ if (message.payload?.thinking !== undefined) {
1760
+ applyThinking(activeRuntime, message.payload.thinking, message.payload.sessionId, activeRuntime.cwd);
1761
+ }
1762
+ await activeRuntime.session.compact();
1763
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'response', requestId: message.requestId, result: {} });
1764
+ return;
1765
+ }
1766
+ default:
1767
+ throw new SessionDaemonProtocolError('UNKNOWN_COMMAND', 'The daemon command is not supported.');
1768
+ }
1769
+ };
1770
+
1771
+ const onConnection = (socket) => {
1772
+ let authenticated = false;
1773
+ let requestChain = Promise.resolve();
1774
+ const decoder = new StringDecoder('utf8');
1775
+ let buffer = '';
1776
+
1777
+ const reject = (error) => {
1778
+ if (authenticated) {
1779
+ writeFrame(socket, {
1780
+ protocolVersion: PROTOCOL_VERSION,
1781
+ kind: 'error',
1782
+ error: { code: error.code ?? 'INVALID_REQUEST' },
1783
+ });
1784
+ }
1785
+ socket.destroy();
1786
+ };
1787
+
1788
+ socket.on('data', (chunk) => {
1789
+ buffer += decoder.write(chunk);
1790
+ if (Buffer.byteLength(buffer) > MAX_FRAME_BYTES) {
1791
+ reject(new SessionDaemonProtocolError('FRAME_TOO_LARGE', 'The daemon frame is too large.'));
1792
+ return;
1793
+ }
1794
+
1795
+ while (true) {
1796
+ const newline = buffer.indexOf('\n');
1797
+ if (newline === -1) break;
1798
+ const line = buffer.slice(0, newline).replace(/\r$/, '');
1799
+ buffer = buffer.slice(newline + 1);
1800
+ if (line.length === 0) continue;
1801
+
1802
+ try {
1803
+ const message = JSON.parse(line);
1804
+ if (!authenticated) {
1805
+ if (message.kind !== 'authenticate' || message.credential !== credential) {
1806
+ throw new SessionDaemonProtocolError('UNAUTHORIZED', 'The daemon client is not authorized.');
1807
+ }
1808
+ authenticated = true;
1809
+ clients.add(socket);
1810
+ writeFrame(socket, { protocolVersion: PROTOCOL_VERSION, kind: 'authenticated' });
1811
+ const requestedSessionId = typeof message.sessionId === 'string' && message.sessionId.length > 0 ? message.sessionId : undefined;
1812
+ const fromSequence = Number.isSafeInteger(message.fromSequence) && message.fromSequence >= 0 ? message.fromSequence : undefined;
1813
+ const oldestRetainedSequence = eventLog[0]?.sequence;
1814
+ const canReplay = fromSequence !== undefined && Number.isSafeInteger(oldestRetainedSequence)
1815
+ && fromSequence >= oldestRetainedSequence - 1;
1816
+ if (canReplay) {
1817
+ for (const event of eventLog) {
1818
+ if (event.sequence > fromSequence && (!requestedSessionId || event.payload.sessionId === requestedSessionId)) writeFrame(socket, event);
1819
+ }
1820
+ } else {
1821
+ publishSnapshot(socket, requestedSessionId);
1822
+ }
1823
+ continue;
1824
+ }
1825
+ requestChain = requestChain.then(() => handleRequest(socket, message)).catch((error) => reject(error));
1826
+ } catch (error) {
1827
+ reject(error);
1828
+ return;
1829
+ }
1830
+ }
1831
+ });
1832
+
1833
+ socket.on('close', () => clients.delete(socket));
1834
+ socket.on('error', () => clients.delete(socket));
1835
+ };
1836
+
1837
+ return {
1838
+ get endpoint() {
1839
+ return endpoint;
1840
+ },
1841
+ get isStarted() {
1842
+ return started;
1843
+ },
1844
+ async start() {
1845
+ if (started) return;
1846
+ await validatePiSessionJsonlDirectory({ cwd, agentDir });
1847
+ runtimeRegistry = createSessionRuntimeRegistry({
1848
+ onSessionEvent: ({ cwd: eventCwd, sessionId: eventSessionId }, event) => publishSessionEvent(eventSessionId, event, eventCwd),
1849
+ });
1850
+
1851
+ try {
1852
+ if (platform !== 'win32') {
1853
+ await mkdir(dirname(endpoint), { recursive: true, mode: 0o700 });
1854
+ await chmod(dirname(endpoint), 0o700);
1855
+ try {
1856
+ await lstat(endpoint);
1857
+ throw new SessionDaemonProtocolError('ENDPOINT_IN_USE', 'The daemon endpoint already exists.');
1858
+ } catch (error) {
1859
+ if (error?.code !== 'ENOENT') throw error;
1860
+ }
1861
+ }
1862
+
1863
+ server = createServer(onConnection);
1864
+ await new Promise((resolve, reject) => {
1865
+ server.once('error', reject);
1866
+ server.listen({ path: endpoint }, () => {
1867
+ server.off('error', reject);
1868
+ resolve();
1869
+ });
1870
+ });
1871
+ if (platform !== 'win32') await chmod(endpoint, 0o600);
1872
+ started = true;
1873
+ } catch (error) {
1874
+ await disposeRuntime();
1875
+ server = undefined;
1876
+ throw error;
1877
+ }
1878
+ },
1879
+ async stop() {
1880
+ if (!started) return;
1881
+ for (const attempt of loginAttempts.values()) {
1882
+ attempt.controller.abort();
1883
+ attempt.rejectPrompt?.(new Error('Provider login cancelled.'));
1884
+ clearTimeout(attempt.expiry);
1885
+ }
1886
+ loginAttempts.clear();
1887
+ for (const client of clients) client.destroy();
1888
+ clients.clear();
1889
+ await new Promise((resolve, reject) => {
1890
+ server.close((error) => error ? reject(error) : resolve());
1891
+ });
1892
+ await disposeRuntime();
1893
+ server = undefined;
1894
+ started = false;
1895
+ if (platform !== 'win32') await rm(endpoint, { force: true });
1896
+ },
1897
+ };
1898
+ }
1899
+
1900
+ function writeFrame(socket, frame) {
1901
+ if (!socket.destroyed) socket.write(`${JSON.stringify(frame)}\n`);
1902
+ }
1903
+