@prismshadow/penguin-server 0.2.2 → 0.2.3

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 (299) hide show
  1. package/README.md +1 -0
  2. package/dist/api/types.d.ts +311 -22
  3. package/dist/chunk-3QINBW3W.js +565 -0
  4. package/dist/chunk-3QINBW3W.js.map +1 -0
  5. package/dist/hmr/manifest.d.ts +44 -0
  6. package/dist/hmr/manifest.js +27 -0
  7. package/dist/hmr/manifest.js.map +1 -0
  8. package/dist/index.js +1995 -796
  9. package/dist/index.js.map +1 -1
  10. package/dist/reset-admin-password.d.ts +28 -0
  11. package/dist/reset-admin-password.js +39 -0
  12. package/dist/reset-admin-password.js.map +1 -0
  13. package/package.json +11 -3
  14. package/web-dist/assets/cpp-DIPi6g--.js +1 -0
  15. package/web-dist/assets/highlighter-Nvj8c0Yw.js +152 -0
  16. package/web-dist/assets/index--uKtXcEB.js +183 -0
  17. package/web-dist/assets/index-BqF51KT4.css +1 -0
  18. package/web-dist/assets/ruby-B13GW9FM.js +1 -0
  19. package/web-dist/index.html +2 -2
  20. package/web-dist/assets/abap-BdImnpbu.js +0 -1
  21. package/web-dist/assets/actionscript-3-CoDkCxhg.js +0 -1
  22. package/web-dist/assets/ada-bCR0ucgS.js +0 -1
  23. package/web-dist/assets/andromeeda-C4gqWexZ.js +0 -1
  24. package/web-dist/assets/angular-html-DA-rfuFy.js +0 -1
  25. package/web-dist/assets/angular-ts-BrjP3tb8.js +0 -1
  26. package/web-dist/assets/apache-Pmp26Uib.js +0 -1
  27. package/web-dist/assets/apex-Dqspr-GT.js +0 -1
  28. package/web-dist/assets/apl-CORt7UWP.js +0 -1
  29. package/web-dist/assets/applescript-Co6uUVPk.js +0 -1
  30. package/web-dist/assets/ara-BRHolxvo.js +0 -1
  31. package/web-dist/assets/asciidoc-Ve4PFQV2.js +0 -1
  32. package/web-dist/assets/asm-D_Q5rh1f.js +0 -1
  33. package/web-dist/assets/astro-HNnZUWAn.js +0 -1
  34. package/web-dist/assets/aurora-x-D-2ljcwZ.js +0 -1
  35. package/web-dist/assets/awk-DMzUqQB5.js +0 -1
  36. package/web-dist/assets/ayu-dark-DYE7WIF3.js +0 -1
  37. package/web-dist/assets/ayu-light-BA47KaF1.js +0 -1
  38. package/web-dist/assets/ayu-mirage-32ctXXKs.js +0 -1
  39. package/web-dist/assets/ballerina-BFfxhgS-.js +0 -1
  40. package/web-dist/assets/bat-BkioyH1T.js +0 -1
  41. package/web-dist/assets/beancount-k_qm7-4y.js +0 -1
  42. package/web-dist/assets/berry-uYugtg8r.js +0 -1
  43. package/web-dist/assets/bibtex-CHM0blh-.js +0 -1
  44. package/web-dist/assets/bicep-Bmn6On1c.js +0 -1
  45. package/web-dist/assets/bird2-BIv1doCn.js +0 -1
  46. package/web-dist/assets/blade-2xfisSek.js +0 -1
  47. package/web-dist/assets/bsl-BO_Y6i37.js +0 -1
  48. package/web-dist/assets/c3-MRO5bC_T.js +0 -1
  49. package/web-dist/assets/cadence-Bv_4Rxtq.js +0 -1
  50. package/web-dist/assets/cairo-KRGpt6FW.js +0 -1
  51. package/web-dist/assets/catppuccin-frappe-DFWUc33u.js +0 -1
  52. package/web-dist/assets/catppuccin-latte-C9dUb6Cb.js +0 -1
  53. package/web-dist/assets/catppuccin-macchiato-DQyhUUbL.js +0 -1
  54. package/web-dist/assets/catppuccin-mocha-D87Tk5Gz.js +0 -1
  55. package/web-dist/assets/clarity-D53aC0YG.js +0 -1
  56. package/web-dist/assets/clojure-P80f7IUj.js +0 -1
  57. package/web-dist/assets/cmake-D1j8_8rp.js +0 -1
  58. package/web-dist/assets/cobol-nBiQ_Alo.js +0 -1
  59. package/web-dist/assets/codeowners-Bp6g37R7.js +0 -1
  60. package/web-dist/assets/codeql-DsOJ9woJ.js +0 -1
  61. package/web-dist/assets/coffee-Ch7k5sss.js +0 -1
  62. package/web-dist/assets/common-lisp-Cg-RD9OK.js +0 -1
  63. package/web-dist/assets/coq-DkFqJrB1.js +0 -1
  64. package/web-dist/assets/cpp-UfJy6YNI.js +0 -1
  65. package/web-dist/assets/crystal-DGywbUpC.js +0 -1
  66. package/web-dist/assets/csharp-DSvCPggb.js +0 -1
  67. package/web-dist/assets/csv-fuZLfV_i.js +0 -1
  68. package/web-dist/assets/cue-D82EKSYY.js +0 -1
  69. package/web-dist/assets/cypher-COkxafJQ.js +0 -1
  70. package/web-dist/assets/d-85-TOEBH.js +0 -1
  71. package/web-dist/assets/dark-plus-C3mMm8J8.js +0 -1
  72. package/web-dist/assets/dart-bE4Kk8sk.js +0 -1
  73. package/web-dist/assets/dax-CEL-wOlO.js +0 -1
  74. package/web-dist/assets/desktop-BmXAJ9_W.js +0 -1
  75. package/web-dist/assets/docker-BcOcwvcX.js +0 -1
  76. package/web-dist/assets/dotenv-Da5cRb03.js +0 -1
  77. package/web-dist/assets/dracula-BzJJZx-M.js +0 -1
  78. package/web-dist/assets/dracula-soft-BXkSAIEj.js +0 -1
  79. package/web-dist/assets/dream-maker-BtqSS_iP.js +0 -1
  80. package/web-dist/assets/edge-FbVlp4U3.js +0 -1
  81. package/web-dist/assets/elixir-CkH2-t6x.js +0 -1
  82. package/web-dist/assets/elm-DbKCFpqz.js +0 -1
  83. package/web-dist/assets/emacs-lisp-CXvaQtF9.js +0 -1
  84. package/web-dist/assets/erb-Dm6A9KJ5.js +0 -1
  85. package/web-dist/assets/erlang-DsQrWhSR.js +0 -1
  86. package/web-dist/assets/everforest-dark-BgDCqdQA.js +0 -1
  87. package/web-dist/assets/everforest-light-C8M2exoo.js +0 -1
  88. package/web-dist/assets/fennel-BYunw83y.js +0 -1
  89. package/web-dist/assets/fish-BvzEVeQv.js +0 -1
  90. package/web-dist/assets/fluent-C4IJs8-o.js +0 -1
  91. package/web-dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
  92. package/web-dist/assets/fortran-free-form-BxgE0vQu.js +0 -1
  93. package/web-dist/assets/fsharp-CXgrBDvD.js +0 -1
  94. package/web-dist/assets/gdresource-BOOCDP_w.js +0 -1
  95. package/web-dist/assets/gdscript-C5YyOfLZ.js +0 -1
  96. package/web-dist/assets/gdshader-DkwncUOv.js +0 -1
  97. package/web-dist/assets/genie-D0YGMca9.js +0 -1
  98. package/web-dist/assets/gherkin-DyxjwDmM.js +0 -1
  99. package/web-dist/assets/git-commit-F4YmCXRG.js +0 -1
  100. package/web-dist/assets/git-rebase-r7XF79zn.js +0 -1
  101. package/web-dist/assets/github-dark-default-Cuk6v7N8.js +0 -1
  102. package/web-dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
  103. package/web-dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
  104. package/web-dist/assets/github-light-default-D7oLnXFd.js +0 -1
  105. package/web-dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
  106. package/web-dist/assets/gleam-BspZqrRM.js +0 -1
  107. package/web-dist/assets/glimmer-js-ByusRIyA.js +0 -1
  108. package/web-dist/assets/glimmer-ts-BfAWNZQY.js +0 -1
  109. package/web-dist/assets/glsl-DplSGwfg.js +0 -1
  110. package/web-dist/assets/gn-n2N0HUVH.js +0 -1
  111. package/web-dist/assets/gnuplot-DdkO51Og.js +0 -1
  112. package/web-dist/assets/graphql-ChdNCCLP.js +0 -1
  113. package/web-dist/assets/groovy-gcz8RCvz.js +0 -1
  114. package/web-dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
  115. package/web-dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
  116. package/web-dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
  117. package/web-dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
  118. package/web-dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
  119. package/web-dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
  120. package/web-dist/assets/hack-DbPARsA_.js +0 -1
  121. package/web-dist/assets/haml-D5jkg6IW.js +0 -1
  122. package/web-dist/assets/handlebars-BpdQsYii.js +0 -1
  123. package/web-dist/assets/haskell-Df6bDoY_.js +0 -1
  124. package/web-dist/assets/haxe-CzTSHFRz.js +0 -1
  125. package/web-dist/assets/hcl-BWvSN4gD.js +0 -1
  126. package/web-dist/assets/hjson-D5-asLiD.js +0 -1
  127. package/web-dist/assets/hlsl-D3lLCCz7.js +0 -1
  128. package/web-dist/assets/horizon-BUw7H-hv.js +0 -1
  129. package/web-dist/assets/horizon-bright-CUuTKBJd.js +0 -1
  130. package/web-dist/assets/houston-DnULxvSX.js +0 -1
  131. package/web-dist/assets/html-derivative-DlHx6ybY.js +0 -1
  132. package/web-dist/assets/http-jrhK8wxY.js +0 -1
  133. package/web-dist/assets/hurl-irOxFIW8.js +0 -1
  134. package/web-dist/assets/hxml-Bvhsp5Yf.js +0 -1
  135. package/web-dist/assets/hy-DFXneXwc.js +0 -1
  136. package/web-dist/assets/imba-DGztddWO.js +0 -1
  137. package/web-dist/assets/index-B3puu-Hr.js +0 -153
  138. package/web-dist/assets/index-CaDuyrN0.css +0 -1
  139. package/web-dist/assets/index-rgHg3m6g.js +0 -181
  140. package/web-dist/assets/jinja-f2NsQr07.js +0 -1
  141. package/web-dist/assets/jison-wvAkD_A8.js +0 -1
  142. package/web-dist/assets/json5-C9tS-k6U.js +0 -1
  143. package/web-dist/assets/jsonc-Des-eS-w.js +0 -1
  144. package/web-dist/assets/jsonl-DcaNXYhu.js +0 -1
  145. package/web-dist/assets/jsonnet-DFQXde-d.js +0 -1
  146. package/web-dist/assets/jssm-C2t-YnRu.js +0 -1
  147. package/web-dist/assets/julia-D7OTSIA_.js +0 -1
  148. package/web-dist/assets/just-CUsbIsdP.js +0 -1
  149. package/web-dist/assets/kanagawa-dragon-CkXjmgJE.js +0 -1
  150. package/web-dist/assets/kanagawa-lotus-CfQXZHmo.js +0 -1
  151. package/web-dist/assets/kanagawa-wave-DWedfzmr.js +0 -1
  152. package/web-dist/assets/kdl-DV7GczEv.js +0 -1
  153. package/web-dist/assets/kotlin-BdnUsdx6.js +0 -1
  154. package/web-dist/assets/kusto-wEQ09or8.js +0 -1
  155. package/web-dist/assets/laserwave-DUszq2jm.js +0 -1
  156. package/web-dist/assets/latex-CaSxy8MP.js +0 -1
  157. package/web-dist/assets/lean-BZvkOJ9d.js +0 -1
  158. package/web-dist/assets/less-B1dDrJ26.js +0 -1
  159. package/web-dist/assets/light-plus-B7mTdjB0.js +0 -1
  160. package/web-dist/assets/liquid-C0sCDyMI.js +0 -1
  161. package/web-dist/assets/llvm-DjAJT7YJ.js +0 -1
  162. package/web-dist/assets/logo-BtOb2qkB.js +0 -1
  163. package/web-dist/assets/lua-BaeVxFsk.js +0 -1
  164. package/web-dist/assets/luau-KW6xsasC.js +0 -1
  165. package/web-dist/assets/make-CHLpvVh8.js +0 -1
  166. package/web-dist/assets/marko-DjSrsDqO.js +0 -1
  167. package/web-dist/assets/material-theme-D5KoaKCx.js +0 -1
  168. package/web-dist/assets/material-theme-darker-BfHTSMKl.js +0 -1
  169. package/web-dist/assets/material-theme-lighter-B0m2ddpp.js +0 -1
  170. package/web-dist/assets/material-theme-ocean-CyktbL80.js +0 -1
  171. package/web-dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
  172. package/web-dist/assets/matlab-D7o27uSR.js +0 -1
  173. package/web-dist/assets/mdc-DTYItulj.js +0 -1
  174. package/web-dist/assets/mdx-Cmh6b_Ma.js +0 -1
  175. package/web-dist/assets/mermaid-mWjccvbQ.js +0 -1
  176. package/web-dist/assets/min-dark-CafNBF8u.js +0 -1
  177. package/web-dist/assets/min-light-CTRr51gU.js +0 -1
  178. package/web-dist/assets/mipsasm-CKIfxQSi.js +0 -1
  179. package/web-dist/assets/mojo-rZm6bMo-.js +0 -1
  180. package/web-dist/assets/monokai-D4h5O-jR.js +0 -1
  181. package/web-dist/assets/moonbit-_H4v1dQx.js +0 -1
  182. package/web-dist/assets/move-IF9eRakj.js +0 -1
  183. package/web-dist/assets/narrat-DRg8JJMk.js +0 -1
  184. package/web-dist/assets/nextflow-C-mBbutL.js +0 -1
  185. package/web-dist/assets/nextflow-groovy-vE_lwT2v.js +0 -1
  186. package/web-dist/assets/nginx-BpAMiNFr.js +0 -1
  187. package/web-dist/assets/night-owl-C39BiMTA.js +0 -1
  188. package/web-dist/assets/night-owl-light-CMTm3GFP.js +0 -1
  189. package/web-dist/assets/nim-BIad80T-.js +0 -1
  190. package/web-dist/assets/nix-CwoSXNpI.js +0 -1
  191. package/web-dist/assets/nord-Ddv68eIx.js +0 -1
  192. package/web-dist/assets/nushell-Cz2AlsmD.js +0 -1
  193. package/web-dist/assets/objective-c-DXmwc3jG.js +0 -1
  194. package/web-dist/assets/objective-cpp-CLxacb5B.js +0 -1
  195. package/web-dist/assets/ocaml-C0hk2d4L.js +0 -1
  196. package/web-dist/assets/odin-BBf5iR-q.js +0 -1
  197. package/web-dist/assets/one-dark-pro-DVMEJ2y_.js +0 -1
  198. package/web-dist/assets/one-light-C3Wv6jpd.js +0 -1
  199. package/web-dist/assets/openscad-C4EeE6gA.js +0 -1
  200. package/web-dist/assets/pascal-D93ZcfNL.js +0 -1
  201. package/web-dist/assets/perl-B9cMNwum.js +0 -1
  202. package/web-dist/assets/pkl-u5AG7uiY.js +0 -1
  203. package/web-dist/assets/plastic-3e1v2bzS.js +0 -1
  204. package/web-dist/assets/plsql-ChMvpjG-.js +0 -1
  205. package/web-dist/assets/po-BTJTHyun.js +0 -1
  206. package/web-dist/assets/poimandres-CS3Unz2-.js +0 -1
  207. package/web-dist/assets/polar-C0HS_06l.js +0 -1
  208. package/web-dist/assets/postcss-CXtECtnM.js +0 -1
  209. package/web-dist/assets/powerquery-CEu0bR-o.js +0 -1
  210. package/web-dist/assets/powershell-Dpen1YoG.js +0 -1
  211. package/web-dist/assets/prisma-Dd19v3D-.js +0 -1
  212. package/web-dist/assets/prolog-CbFg5uaA.js +0 -1
  213. package/web-dist/assets/proto-C7zT0LnQ.js +0 -1
  214. package/web-dist/assets/pug-DKIMFp6K.js +0 -1
  215. package/web-dist/assets/puppet-BMWR74SV.js +0 -1
  216. package/web-dist/assets/purescript-CklMAg4u.js +0 -1
  217. package/web-dist/assets/qml-3beO22l8.js +0 -1
  218. package/web-dist/assets/qmldir-C8lEn-DE.js +0 -1
  219. package/web-dist/assets/qss-IeuSbFQv.js +0 -1
  220. package/web-dist/assets/r-Dspwwk_N.js +0 -1
  221. package/web-dist/assets/racket-BqYA7rlc.js +0 -1
  222. package/web-dist/assets/raku-DXvB9xmW.js +0 -1
  223. package/web-dist/assets/razor-BjBPvh-w.js +0 -1
  224. package/web-dist/assets/red-bN70gL4F.js +0 -1
  225. package/web-dist/assets/reg-C-SQnVFl.js +0 -1
  226. package/web-dist/assets/regexp-CDVJQ6XC.js +0 -1
  227. package/web-dist/assets/rel-C3B-1QV4.js +0 -1
  228. package/web-dist/assets/riscv-BM1_JUlF.js +0 -1
  229. package/web-dist/assets/ron-D8l8udqQ.js +0 -1
  230. package/web-dist/assets/rose-pine-dawn-DHQR4-dF.js +0 -1
  231. package/web-dist/assets/rose-pine-moon-D4_iv3hh.js +0 -1
  232. package/web-dist/assets/rose-pine-qdsjHGoJ.js +0 -1
  233. package/web-dist/assets/rosmsg-BJDFO7_C.js +0 -1
  234. package/web-dist/assets/rst-CpCqk9r5.js +0 -1
  235. package/web-dist/assets/ruby-DyJCeAvU.js +0 -1
  236. package/web-dist/assets/sas-DEy46yEz.js +0 -1
  237. package/web-dist/assets/sass-Cj5Yp3dK.js +0 -1
  238. package/web-dist/assets/scala-C151Ov-r.js +0 -1
  239. package/web-dist/assets/scheme-C98Dy4si.js +0 -1
  240. package/web-dist/assets/scss-D5BDwBP9.js +0 -1
  241. package/web-dist/assets/sdbl-DVxCFoDh.js +0 -1
  242. package/web-dist/assets/shaderlab-Dg9Lc6iA.js +0 -1
  243. package/web-dist/assets/shellsession-BADoaaVG.js +0 -1
  244. package/web-dist/assets/slack-dark-BthQWCQV.js +0 -1
  245. package/web-dist/assets/slack-ochin-DqwNpetd.js +0 -1
  246. package/web-dist/assets/smalltalk-BERRCDM3.js +0 -1
  247. package/web-dist/assets/snazzy-light-Bw305WKR.js +0 -1
  248. package/web-dist/assets/solarized-dark-DXbdFlpD.js +0 -1
  249. package/web-dist/assets/solarized-light-L9t79GZl.js +0 -1
  250. package/web-dist/assets/solidity-rGO070M0.js +0 -1
  251. package/web-dist/assets/soy-8wufbnw4.js +0 -1
  252. package/web-dist/assets/sparql-rVzFXLq3.js +0 -1
  253. package/web-dist/assets/splunk-BtCnVYZw.js +0 -1
  254. package/web-dist/assets/ssh-config-_ykCGR6B.js +0 -1
  255. package/web-dist/assets/stata-DI20mbqo.js +0 -1
  256. package/web-dist/assets/stylus-BEDo0Tqx.js +0 -1
  257. package/web-dist/assets/surrealql-Bq5Q-fJD.js +0 -1
  258. package/web-dist/assets/svelte-Cy7k_4gC.js +0 -1
  259. package/web-dist/assets/swift-D82vCrfD.js +0 -1
  260. package/web-dist/assets/synthwave-84-CbfX1IO0.js +0 -1
  261. package/web-dist/assets/system-verilog-CnnmHF94.js +0 -1
  262. package/web-dist/assets/systemd-4A_iFExJ.js +0 -1
  263. package/web-dist/assets/talonscript-CkByrt1z.js +0 -1
  264. package/web-dist/assets/tasl-QIJgUcNo.js +0 -1
  265. package/web-dist/assets/tcl-dwOrl1Do.js +0 -1
  266. package/web-dist/assets/templ-DhtptRzy.js +0 -1
  267. package/web-dist/assets/terraform-BETggiCN.js +0 -1
  268. package/web-dist/assets/tex-idrVyKtj.js +0 -1
  269. package/web-dist/assets/tokyo-night-hegEt444.js +0 -1
  270. package/web-dist/assets/ts-tags-D351s5mN.js +0 -1
  271. package/web-dist/assets/tsv-B_m7g4N7.js +0 -1
  272. package/web-dist/assets/turtle-BsS91CYL.js +0 -1
  273. package/web-dist/assets/twig-CW1WmMYd.js +0 -1
  274. package/web-dist/assets/typespec-CAFt9gP4.js +0 -1
  275. package/web-dist/assets/typst-DHCkPAjA.js +0 -1
  276. package/web-dist/assets/v-BcVCzyr7.js +0 -1
  277. package/web-dist/assets/vala-CsfeWuGM.js +0 -1
  278. package/web-dist/assets/vb-D17OF-Vu.js +0 -1
  279. package/web-dist/assets/verilog-BQ8w6xss.js +0 -1
  280. package/web-dist/assets/vesper-DRje8inN.js +0 -1
  281. package/web-dist/assets/vhdl-CeAyd5Ju.js +0 -1
  282. package/web-dist/assets/viml-CJc9bBzg.js +0 -1
  283. package/web-dist/assets/vitesse-black-Bkuqu6BP.js +0 -1
  284. package/web-dist/assets/vitesse-dark-D0r3Knsf.js +0 -1
  285. package/web-dist/assets/vitesse-light-CVO1_9PV.js +0 -1
  286. package/web-dist/assets/vue-D2xRrEX4.js +0 -1
  287. package/web-dist/assets/vue-html-AaS7Mt5G.js +0 -1
  288. package/web-dist/assets/vue-vine-BoDAl6tE.js +0 -1
  289. package/web-dist/assets/vyper-CDx5xZoG.js +0 -1
  290. package/web-dist/assets/wasm-CG6Dc4jp.js +0 -1
  291. package/web-dist/assets/wasm-MzD3tlZU.js +0 -1
  292. package/web-dist/assets/wenyan-BV7otONQ.js +0 -1
  293. package/web-dist/assets/wgsl-Dx-B1_4e.js +0 -1
  294. package/web-dist/assets/wikitext-BhOHFoWU.js +0 -1
  295. package/web-dist/assets/wit-5i3qLPDT.js +0 -1
  296. package/web-dist/assets/wolfram-lXgVvXCa.js +0 -1
  297. package/web-dist/assets/xsl-CtQFsRM5.js +0 -1
  298. package/web-dist/assets/zenscript-DVFEvuxE.js +0 -1
  299. package/web-dist/assets/zig-VOosw3JB.js +0 -1
package/README.md CHANGED
@@ -20,6 +20,7 @@ The full route tables and the SSE protocol are documented in the [Server API ref
20
20
  | `PENGUIN_HOME` | Data root (shared with SDK/CLI) | `~/.penguin/data` |
21
21
  | `PENGUIN_WEB_DB` | SQLite file path | `<root>/web.db` |
22
22
  | `PENGUIN_WEB_DIST` | Front-end build dir (static hosting + SPA fallback when present) | `../web/dist`, or the bundled `web-dist/` in the npm package |
23
+ | `PENGUIN_TRUST_PROXY` | Trust `x-forwarded-proto` for the hot-update network gate (`1` to enable) — only behind a reverse proxy that sets/strips the header itself | unset (untrusted) |
23
24
 
24
25
  `.env` in the process cwd is loaded automatically.
25
26
 
@@ -1,4 +1,4 @@
1
- import { OmniMessage, ToolCallPayload } from '@prismshadow/penguin-core/omnimessage';
1
+ import { OmniMessage, ToolCallPayload, CompactionMode } from '@prismshadow/penguin-core/omnimessage';
2
2
  import { ThinkingLevelName, ToolDefinitionConfig, MCPServerConfig } from '@prismshadow/penguin-core/interfaces';
3
3
 
4
4
  /**
@@ -72,6 +72,38 @@ interface MeResponse {
72
72
  * token) may omit it.
73
73
  */
74
74
  sessionVia: "password" | "desktop";
75
+ /**
76
+ * The upload limits currently in force, so the composer can refuse an oversize pick before
77
+ * reading it and can name the real number in the message. They are admin-settable and ride
78
+ * `/api/me` rather than `/api/admin/settings` because every user's composer needs them, not
79
+ * just an admin's.
80
+ */
81
+ uploadLimits: UploadLimits;
82
+ }
83
+ /**
84
+ * Upload limits as the web app sees them: whole MB, the same unit the admin form uses, so the
85
+ * number in the error message is the number the admin typed.
86
+ */
87
+ interface UploadLimits {
88
+ /** Per-file cap for composer file attachments. */
89
+ attachmentMaxMb: number;
90
+ /** Per-message total of decoded attachment bytes. */
91
+ attachmentTotalMb: number;
92
+ /** Per-message file count. Fixed server-side, not admin-settable. */
93
+ attachmentMaxCount: number;
94
+ /**
95
+ * Per-image cap for images that ride the conversation inline. Fixed server-side and
96
+ * deliberately far below the attachment cap — an inline image enters the conversation and the
97
+ * Trace, where its size is paid again on every history page and every resume.
98
+ */
99
+ imageMaxMb: number;
100
+ /**
101
+ * The range the two admin-settable limits may be set to. Carried here so the admin form states
102
+ * the real bounds without compiling its own copy of them — the server is the only place that
103
+ * decides how large an upload it can survive.
104
+ */
105
+ attachmentLimitMinMb: number;
106
+ attachmentLimitMaxMb: number;
75
107
  }
76
108
  interface PasswordChangeRequest {
77
109
  /** Omitted only by desktop-established sessions (desktop mode); required otherwise. */
@@ -119,11 +151,23 @@ interface ServerSettings {
119
151
  */
120
152
  proxyForAgent: boolean;
121
153
  /**
122
- * The shared explicit proxy address (canonical `http(s)://host[:port]`), or null =
123
- * follow the proxy environment variables. When set it takes precedence over
124
- * HTTP_PROXY / HTTPS_PROXY wherever the owning switch is on.
154
+ * The shared explicit proxy address (a canonical URL — http(s):// or socks5:// /
155
+ * socks://), or null = follow the proxy environment variables. When set it takes
156
+ * precedence over HTTP_PROXY / HTTPS_PROXY wherever the owning switch is on.
125
157
  */
126
158
  proxyUrl: string | null;
159
+ /**
160
+ * Per-file cap for composer file attachments, in whole MB (default 100). Applies to the very
161
+ * next upload — the validators read it per request, nothing is snapshotted at boot.
162
+ */
163
+ attachmentMaxMb: number;
164
+ /**
165
+ * Per-message total of decoded attachment bytes, in whole MB (default 120). Never below
166
+ * `attachmentMaxMb`, so a message may always carry one full-size attachment. The global request
167
+ * body cap is derived from this value (base64 inflates it by 4/3, plus headroom for one inline
168
+ * image and the JSON framing), which is why raising it needs no separate setting.
169
+ */
170
+ attachmentTotalMb: number;
127
171
  }
128
172
  interface ServerSettingsResponse {
129
173
  settings: ServerSettings;
@@ -133,12 +177,26 @@ interface ServerSettingsUpdateRequest {
133
177
  proxyForApp?: boolean;
134
178
  proxyForAgent?: boolean;
135
179
  /**
136
- * New proxy address. Accepted forms: `http://host[:port]`, `https://host[:port]`, or
137
- * bare `host[:port]` (normalized to `http://…` — only normalized values are stored,
138
- * and the response echoes the stored form). Empty/whitespace-only or null clears the
139
- * address (follow the environment variables); anything else is 400 `invalid_proxy_url`.
180
+ * New proxy address. Accepted forms: any proxy URL undici's dispatcher takes —
181
+ * `http://`, `https://`, `socks5://` / `socks://`, credentials allowed — or bare
182
+ * `host[:port]` (normalized to `http://…`; only normalized values are stored, and the
183
+ * response echoes the stored form). Empty/whitespace-only or null clears the address
184
+ * (follow the environment variables); anything else is 400 `invalid_proxy_url`.
140
185
  */
141
186
  proxyUrl?: string | null;
187
+ /**
188
+ * New per-file attachment cap in whole MB. Must be an integer between 1 and 200; anything else
189
+ * — a fraction, a string, 102400 for "100GB" — is 400 `invalid_attachment_limit` and writes
190
+ * nothing.
191
+ */
192
+ attachmentMaxMb?: number;
193
+ /**
194
+ * New per-message total attachment cap in whole MB. Same 1..200 integer range, and additionally
195
+ * must not be below the *effective* per-file cap (the value in the same PUT, or the stored one
196
+ * when this PUT does not change it) — a total below the per-file cap would make a legal single
197
+ * attachment unsendable. Violations are 400 `invalid_attachment_limit`.
198
+ */
199
+ attachmentTotalMb?: number;
142
200
  }
143
201
  /** User UI preferences (SQLite ui_prefs, free-form JSON; known keys declared here). */
144
202
  interface UiPrefs {
@@ -236,7 +294,7 @@ interface ModelInfo {
236
294
  /** Display name: explicit TOML field (user-edited) takes priority, then the built-in catalog; falls back to unset (frontend shows modelId). */
237
295
  displayName?: string;
238
296
  contextWindow?: number;
239
- /** AgentHub client protocol (`openai`, etc.); defaults to AgentHub inferring it from modelId. */
297
+ /** AgentHub client protocol (`openai-chat`, `openai-responses`, etc.); defaults to AgentHub inferring it from modelId. */
240
298
  clientType?: string;
241
299
  /**
242
300
  * Whether image input (vision/multimodal) is supported: the TOML `vision` annotation takes
@@ -251,6 +309,13 @@ interface ModelInfo {
251
309
  * seeded per-Agent default (32000), which cannot fit into e.g. a 32k context window.
252
310
  */
253
311
  maxTokens?: number;
312
+ /**
313
+ * Per-model fast mode (TOML `fast_mode` annotation; user-only, never preset by the
314
+ * built-in catalog): when true, session requests opt into the provider's faster serving
315
+ * tier at premium pricing (AgentHub UniConfig `fast_mode`). Only `true` is reported;
316
+ * unset = off. Models without a fast tier reject requests carrying it.
317
+ */
318
+ fastMode?: boolean;
254
319
  pricing?: ModelPricingDto;
255
320
  /** Environment variable name to fall back to when api_key is empty (e.g. ANTHROPIC_API_KEY); unset if no known fallback. */
256
321
  envKey?: string;
@@ -293,6 +358,8 @@ interface ModelUpdateEntry {
293
358
  vision?: boolean;
294
359
  /** Per-model max output tokens, a positive integer (wins over the Agent config); omitted = inherit the Agent value (the annotation is cleared). */
295
360
  maxTokens?: number;
361
+ /** Per-model fast mode: only `true` is persisted; omitted or `false` clears the annotation (absent = off). */
362
+ fastMode?: boolean;
296
363
  pricing?: ModelPricingDto;
297
364
  /** Providing it overwrites and updates createdAt; omitting it keeps the existing value. */
298
365
  apiKey?: string;
@@ -333,6 +400,45 @@ interface ModelTestRequest {
333
400
  baseUrl?: string | null;
334
401
  /** AgentHub client protocol; required for unsaved custom models (otherwise the id can't be auto-routed). */
335
402
  clientType?: string;
403
+ /**
404
+ * Test with fast mode (the frontend always sends the form's current value, so an unsaved
405
+ * toggle — either direction — is what gets tested); omitted falls back to the stored
406
+ * annotation. Lets "Test connection" surface a fast-mode rejection before saving.
407
+ */
408
+ fastMode?: boolean;
409
+ }
410
+ /**
411
+ * Vision capability probe: sends one 1x1 image and a one-word prompt on this model's
412
+ * credential, to decide whether the models dialog's "supports vision" switch should be
413
+ * turned on. The body mirrors the connectivity test (same paired reference and same
414
+ * not-yet-saved overrides), so an unsaved model can be probed before it exists on disk.
415
+ *
416
+ * Unlike protocol detection this is a real, billed completion — an image request cannot be
417
+ * shaped to cost nothing — so it only ever runs when the user presses the control.
418
+ */
419
+ interface ModelVisionDetectRequest {
420
+ provider: string;
421
+ modelId: string;
422
+ /** Newly entered API key (plaintext); the stored one backs the probe when omitted. */
423
+ apiKey?: string;
424
+ /** "Clear saved API key" is checked: do not fall back to the stored key. */
425
+ clearApiKey?: boolean;
426
+ /** Form's current base URL; null means "explicitly none" (as in the connectivity test). */
427
+ baseUrl?: string | null;
428
+ /** Protocol to speak, when the form has one; otherwise the stored/auto-routed client. */
429
+ clientType?: string;
430
+ }
431
+ /**
432
+ * Vision probe verdict. `supported` = the model took the image and answered; `unsupported`
433
+ * = it answered specifically that it will not take an image (a definitive negative, not an
434
+ * error); `failed` = the probe never got a usable answer (auth, network, an unrelated
435
+ * error), so nothing about the capability was learned and the setting is left alone.
436
+ */
437
+ type ModelVisionOutcome = "supported" | "unsupported" | "failed";
438
+ /** Vision probe result; `message` carries the truncated provider error for the failed case. */
439
+ interface ModelVisionDetectResponse {
440
+ outcome: ModelVisionOutcome;
441
+ message?: string;
336
442
  }
337
443
  /**
338
444
  * Connectivity test result: carries round-trip latency when ok, and a reason on failure
@@ -353,6 +459,48 @@ interface ModelTestResponse {
353
459
  tps?: number;
354
460
  message?: string;
355
461
  }
462
+ /**
463
+ * Protocol auto-detection (POST /api/projects/:p/models/detect, owner): probes which of
464
+ * AgentHub's generic protocol clients a custom base URL serves — `openai-responses` first,
465
+ * then `ant-messages`, then `openai-chat` — and reports the first hit. Used by the custom
466
+ * model dialog to fill `clientType` from the endpoint itself; costs no tokens (each probe
467
+ * is a minimal invalid request whose error reveals the protocol shape).
468
+ */
469
+ interface ModelProtocolDetectRequest {
470
+ /** Base URL to probe (as typed in the form); each probe appends its protocol path. */
471
+ baseUrl: string;
472
+ /** Newly entered API key (plaintext); used for probe auth if provided. Detection also works keyless: a protocol-shaped 401/403 still proves the route. */
473
+ apiKey?: string;
474
+ /** "Clear saved API key" is checked: do not fall back to the stored key (probe the current draft). */
475
+ clearApiKey?: boolean;
476
+ /** Optional paired reference: when it names a stored entry and no apiKey is given, that entry's saved key backs the probes (mirrors the connectivity test). */
477
+ provider?: string;
478
+ modelId?: string;
479
+ }
480
+ /**
481
+ * One probe's outcome: `served` = the route answered in an API shape (including auth
482
+ * failures — 401/403 with a protocol-shaped body proves the route exists);
483
+ * `route_missing` = 404/405; `server_error` = 5xx (proves nothing about the path);
484
+ * `junk` = HTML / non-JSON / JSON matching no API shape; `timeout` / `network_error` =
485
+ * the request itself failed.
486
+ */
487
+ type ProtocolProbeOutcome = "served" | "route_missing" | "server_error" | "junk" | "timeout" | "network_error";
488
+ /** One probe, for debugging display: the probed URL derives from baseUrl only (never contains the key). */
489
+ interface ModelProtocolProbeDto {
490
+ /** AgentHub client type this probe stands for (`openai-responses` / `ant-messages` / `openai-chat`). */
491
+ clientType: string;
492
+ /** Full URL probed (base URL + the protocol's path). */
493
+ url: string;
494
+ outcome: ProtocolProbeOutcome;
495
+ /** HTTP status, when a response arrived at all. */
496
+ status?: number;
497
+ }
498
+ /** Detection result: probes run sequentially and stop at the first served protocol, so `probes` lists only the ones actually run, in order. */
499
+ interface ModelProtocolDetectResponse {
500
+ /** The first protocol the endpoint serves (an AgentHub client type); absent when none of the three matched. */
501
+ detected?: string;
502
+ probes: ModelProtocolProbeDto[];
503
+ }
356
504
  /**
357
505
  * PUT /api/projects/:p/models/default (owner): narrow default-model switch — flips the same
358
506
  * top-level `default_model` the models page's whole-table PUT writes, without resending the
@@ -385,7 +533,7 @@ interface ChatDefaultsDto {
385
533
  /**
386
534
  * Fallback thinking level for Agents whose config has no explicit `model.thinking_level`
387
535
  * (resolution chain: Agent explicit > this project default > built-in "medium"). Never
388
- * "none" — only the four selectable tiers.
536
+ * "none" — only the selectable tiers.
389
537
  */
390
538
  thinkingLevel?: Exclude<ThinkingLevelName, "none">;
391
539
  }
@@ -645,11 +793,35 @@ interface SessionInfo {
645
793
  modelId: string;
646
794
  workspace: string;
647
795
  approvalMode: ApprovalMode;
796
+ /**
797
+ * Thinking level pinned for this Session (set via PATCH; the Web App's in-chat picker).
798
+ * Unset = never pinned: runs that carry no level of their own fall back to the Agent
799
+ * config's `model.thinking_level`, so config edits keep taking effect. Once pinned it
800
+ * survives reloads and applies to every later run of this Session, and an Agent-config
801
+ * change no longer moves it.
802
+ */
803
+ thinkingLevel?: ThinkingLevelName;
648
804
  /** Short title auto-generated by the model after the first turn; unset until generated (frontend shows "New Chat"). */
649
805
  title?: string;
650
806
  /** Session source (for list badges/folders), derived from core session_meta — the single source of truth (not stored in the DB); unset for user-created sessions. */
651
807
  source?: SessionSource;
652
808
  createdAt: string;
809
+ /**
810
+ * Last activity the server drove for this Session (ISO 8601, same convention as
811
+ * createdAt), monotonic — it never moves backwards. Set to createdAt at creation, then
812
+ * stamped when a run starts and again when it ends; a run here is one Task, one
813
+ * compaction, or one whole goal loop (every round of a goal belongs to a single run, so
814
+ * an N-round goal stamps twice, not 2N times).
815
+ *
816
+ * Two kinds of row therefore stay at createdAt no matter how busy they look: Sessions
817
+ * adopted from a CLI Trace (this server drives none of their runs) and subagent rows
818
+ * (their work is driven through the parent Session's entry). Reading real activity for
819
+ * those would mean consulting the Trace tree, which this field deliberately does not do.
820
+ *
821
+ * Rows that predate the field are backfilled once at startup from the Session's most
822
+ * recent request timestamp, falling back to createdAt.
823
+ */
824
+ lastActiveAt: string;
653
825
  status: SessionStatus;
654
826
  /** Number of approvals awaiting human decision (a persisted count outside server events, for list badges). */
655
827
  pendingApprovalCount: number;
@@ -719,11 +891,36 @@ interface SessionCreateRequest {
719
891
  interface SessionCreateResponse {
720
892
  session: SessionInfo;
721
893
  }
894
+ /** Immutable location of one record in a Session's append-only Trace. */
895
+ interface TracePosition {
896
+ /** Trace shard index (`001` on disk becomes `1`). */
897
+ fileIndex: number;
898
+ /** Zero-based record ordinal within the parsed shard. */
899
+ ordinal: number;
900
+ }
901
+ /** History-only transport metadata; `tracePosition` is never persisted into Trace JSONL. */
902
+ type HistoryMessage = OmniMessage & {
903
+ tracePosition?: TracePosition;
904
+ };
905
+ interface SessionForkRequest {
906
+ /** The final root assistant text record of the completed Task to keep. */
907
+ position: TracePosition;
908
+ }
909
+ interface SessionForkResponse {
910
+ session: SessionInfo;
911
+ }
722
912
  interface SessionResponse {
723
913
  session: SessionInfo;
724
914
  }
725
915
  interface SessionPatchRequest {
726
916
  approvalMode?: ApprovalMode;
917
+ /**
918
+ * Pin this Session's thinking level (`none | low | medium | high | xhigh | max`, anything else
919
+ * is a 400). It applies to every later run of the Session that doesn't carry its own
920
+ * level, and replaces the Agent-config fallback for this Session. There is no unpin:
921
+ * the picker only offers concrete levels.
922
+ */
923
+ thinkingLevel?: ThinkingLevelName;
727
924
  /** Archive / unarchive (default list hides archived). */
728
925
  archived?: boolean;
729
926
  /** Manual rename; non-empty string, overrides the auto-generated title. */
@@ -791,7 +988,7 @@ interface MessagesPageInfo {
791
988
  }
792
989
  /** Message history: the full messages and events from concatenating all of this Session's Trace files in order (excludes partial_*). */
793
990
  interface MessagesResponse {
794
- messages: OmniMessage[];
991
+ messages: HistoryMessage[];
795
992
  /**
796
993
  * Present only while the Session is running/compacting: the in-progress stream tail
797
994
  * (open streaming fragments + the channel cursor they cover), so a client joining
@@ -814,17 +1011,26 @@ interface MessagesResponse {
814
1011
  type TaskInputPart = {
815
1012
  type: "text";
816
1013
  text: string;
817
- } | {
1014
+ }
1015
+ /**
1016
+ * An image that rides the conversation inline, as a base64 `data:` URL or an http(s) URL.
1017
+ * A data URL is capped at 20MB (413 `image_too_large`) — a fixed limit that does NOT follow
1018
+ * the admin-settable attachment cap, because an inline image is written into the Trace and
1019
+ * read back on every history page and every resume.
1020
+ */
1021
+ | {
818
1022
  type: "image_url";
819
1023
  imageUrl: string;
820
1024
  }
821
1025
  /**
822
1026
  * File attachment (the composer's "+" menu): `dataUrl` is a base64 `data:` URL of the
823
- * file's bytes, capped at 10MB each (413 `file_too_large` beyond that; the request as a
824
- * whole still has to fit the global 20MB body limit). The server writes it into the
825
- * Session scratchpad under a sanitized name and appends an `[attached file: <path>]` line
826
- * to the message text — the bytes never enter the conversation, the model opens the file
827
- * by path. `fileName` is the original name (no path separators, no `..`).
1027
+ * file's bytes, capped per file and per message by the admin-settable upload limits
1028
+ * (defaults 100MB / 120MB; 413 `file_too_large` / `payload_too_large` / `too_many_files`,
1029
+ * and the request as a whole still has to fit the body cap those limits derive). The
1030
+ * server writes it into the Session scratchpad under a sanitized name and appends an
1031
+ * `[attached file: <path>]` line to the message text — the bytes never enter the
1032
+ * conversation, the model opens the file by path. `fileName` is the original name (no path
1033
+ * separators, no `..`).
828
1034
  */
829
1035
  | {
830
1036
  type: "file";
@@ -835,9 +1041,10 @@ interface TaskCreateRequest {
835
1041
  input: TaskInputPart[];
836
1042
  /**
837
1043
  * Thinking level for this Task's LLM requests (a per-turn parameter; one of
838
- * `none | low | medium | high | xhigh`, anything else is a 400). Omitted = falls back to
839
- * the session's default (the Agent config's `model.thinking_level`). A queued follow-up
840
- * (`queueIfBusy`) keeps its level and applies it when it auto-starts.
1044
+ * `none | low | medium | high | xhigh | max`, anything else is a 400). Omitted = falls back to
1045
+ * the Session's pinned level (`SessionInfo.thinkingLevel`) and, when that is unset too,
1046
+ * to the Agent config's `model.thinking_level`. A queued follow-up (`queueIfBusy`) keeps
1047
+ * its level and applies it when it auto-starts.
841
1048
  */
842
1049
  thinkingLevel?: ThinkingLevelName;
843
1050
  /**
@@ -912,6 +1119,8 @@ interface SteerRequest {
912
1119
  * stream, and the whole list drops when the run exits (core discards undelivered steering).
913
1120
  */
914
1121
  interface PendingSteeringInfo {
1122
+ /** Server-assigned id, stable for the entry's queued lifetime: the handle DELETE /steer/:steerId recalls it by. */
1123
+ id: string;
915
1124
  /** The message text as accepted (trimmed); may be empty when images/files carry the message. */
916
1125
  text: string;
917
1126
  /** Number of images that rode along. */
@@ -919,6 +1128,43 @@ interface PendingSteeringInfo {
919
1128
  /** Number of file attachments that rode along. */
920
1129
  files: number;
921
1130
  }
1131
+ /**
1132
+ * One follow-up task queued with `queueIfBusy` but not yet auto-started. Carried on
1133
+ * `task_state` events and the SSE subscribe snapshot (like `pendingSteering`) so the
1134
+ * composer can show each queued message's content with a recall affordance; entries leave
1135
+ * the list when they auto-start on idle — or when DELETE /follow-ups/:followUpId recalls one.
1136
+ */
1137
+ interface PendingFollowUpInfo {
1138
+ /** Server-assigned id, stable for the entry's queued lifetime: the handle DELETE /follow-ups/:followUpId recalls it by. */
1139
+ id: string;
1140
+ /** The queued input's text parts, joined; may be empty when images/files carry the message. */
1141
+ text: string;
1142
+ /** Number of images in the queued input. */
1143
+ images: number;
1144
+ /** Number of file attachments in the queued input. */
1145
+ files: number;
1146
+ }
1147
+ /**
1148
+ * Response of the two recall endpoints — DELETE /api/sessions/:id/steer/:steerId and
1149
+ * DELETE /api/sessions/:id/follow-ups/:followUpId: the withdrawn message's original content,
1150
+ * for the composer to restore into the input box for editing and resending (#287). File
1151
+ * attachments are read back from the Session scratchpad (then deleted from it); one that
1152
+ * disappeared meanwhile is omitted rather than failing the recall. 409 `not_pending` when
1153
+ * the entry is no longer queued — steering already delivered to the model, or a follow-up
1154
+ * already auto-started (or unknown id either way).
1155
+ */
1156
+ interface RecalledMessageResponse {
1157
+ text: string;
1158
+ /** The images as submitted (`data:` / http(s) URLs). */
1159
+ images: string[];
1160
+ /** The file attachments, re-encoded as base64 data URLs (the shape the composer submits them in). */
1161
+ files: {
1162
+ fileName: string;
1163
+ dataUrl: string;
1164
+ }[];
1165
+ /** Follow-up recall only: the per-turn thinking level the entry was queued with, when one was. */
1166
+ thinkingLevel?: ThinkingLevelName;
1167
+ }
922
1168
  interface ApprovalDecisionRequest {
923
1169
  decision: "allow" | "deny";
924
1170
  }
@@ -966,6 +1212,8 @@ type ServerEvent =
966
1212
  queued?: number;
967
1213
  /** Steering messages queued but not yet delivered (absent = none): lets the composer's hint and its content survive reloads. */
968
1214
  pendingSteering?: PendingSteeringInfo[];
1215
+ /** Queued follow-up tasks awaiting auto-start (absent = none): per-entry content + recall handle, alongside the `queued` count. */
1216
+ pendingFollowUps?: PendingFollowUpInfo[];
969
1217
  }
970
1218
  /** The model-generated title after the first turn has been persisted (for in-place list updates). */
971
1219
  | {
@@ -973,6 +1221,32 @@ type ServerEvent =
973
1221
  sessionId: string;
974
1222
  title: string;
975
1223
  }
1224
+ /**
1225
+ * The user-channel counterpart of `task_state`: the same run-state flip, named by
1226
+ * `sessionId`, delivered on GET /api/events.
1227
+ *
1228
+ * `task_state` is session-scoped and deliberately carries no id, so it only ever reaches the
1229
+ * one conversation a tab has subscribed to — every OTHER row in that tab's Session list would
1230
+ * otherwise keep whatever status its last list fetch returned. This event exists so the list
1231
+ * can stay live without polling; the per-Session contract is unchanged.
1232
+ *
1233
+ * `lastActiveAt` and `hasTrace` are the row's own fields as they stand after the flip, both
1234
+ * written just before publishing (`markDriven` at run start sets has_trace and stamps
1235
+ * last_active_at; `touchLastActive` stamps again at run end). They are what let a list act on
1236
+ * the flip without refetching: the stamp separates "this finished while I was looking
1237
+ * elsewhere" from "this finished before I last looked", and `hasTrace` separates a Session
1238
+ * that has now run from one that never has — a first run would otherwise settle back into the
1239
+ * blank "never ran" row the client still believes in.
1240
+ *
1241
+ * Published only to the user channels of the Project's owner and members.
1242
+ */
1243
+ | {
1244
+ type: "session_state";
1245
+ sessionId: string;
1246
+ state: SessionStatus;
1247
+ lastActiveAt: string;
1248
+ hasTrace: boolean;
1249
+ }
976
1250
  /** Last-Event-ID has been evicted from the buffer: the frontend should re-fetch the history endpoint before continuing to consume this connection. */
977
1251
  | {
978
1252
  type: "resync_required";
@@ -991,6 +1265,11 @@ type ServerEvent =
991
1265
  | {
992
1266
  type: "hello";
993
1267
  }
1268
+ /** The served web assets were hot-swapped by a platform upgrade: clients reload to pick them up. */
1269
+ | {
1270
+ type: "web_updated";
1271
+ rev: string;
1272
+ }
994
1273
  /** New session registered (pushed over the parent session's channel for subagent sessions): frontend refreshes the list in place. */
995
1274
  | {
996
1275
  type: "session_created";
@@ -1093,12 +1372,22 @@ interface TraceTaskStats {
1093
1372
  taskIndex: number;
1094
1373
  /**
1095
1374
  * This turn is a **compaction turn** (compaction forms its own turn); the UI marks it with
1096
- * a "Compaction" badge accordingly. It's treated the same as a user turn: it has Token /
1375
+ * a badge accordingly. It's treated the same as a user turn: it has Token /
1097
1376
  * cost / duration / TPS, and **counts normally toward global stats** — the global totals are
1098
1377
  * just the sum of the per-turn cards below, the two scopes match, so adding up the per-turn
1099
1378
  * numbers must equal the total.
1100
1379
  */
1101
1380
  compaction?: boolean;
1381
+ /**
1382
+ * Which kind of compaction turn it is, from the turn's `compaction_begin`. Additive beside
1383
+ * the flag rather than folded into it: `compaction` stays the sole gate on "is this a
1384
+ * compaction turn", so a client that only knows the boolean keeps working unchanged, and one
1385
+ * that reads this can name the turn for what it did — the two modes are different operations,
1386
+ * and only `summarize` actually compacts anything (`discard` drops the old context outright).
1387
+ * Absent on a turn analyzed before this field existed, or whose `compaction_begin` carried no
1388
+ * mode; treat an absent value as `summarize`, which is what the badge said before the split.
1389
+ */
1390
+ compactionMode?: CompactionMode;
1102
1391
  /**
1103
1392
  * This turn's message index range within the **entire file** (inclusive). A single
1104
1393
  * sequential scan on the server tells which turn each message belongs to; the frontend
@@ -1678,4 +1967,4 @@ interface UpdateRunResponse {
1678
1967
  needsRestart: boolean;
1679
1968
  }
1680
1969
 
1681
- export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DirEntryInfo, DirListResponse, ErrorBody, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryOverviewResponse, MemoryScopeInfo, MessagesLiveTail, MessagesPageInfo, MessagesResponse, ModelInfo, ModelPricingDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionCreateRequest, SessionCreateResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SteerRequest, TaskCreateRequest, TaskCreateResponse, TaskInputPart, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UsageAgentCount, UsageBucket, UsageErrorCount, UsageErrorItem, UsageErrors, UsageErrorsPage, UsageGroupBy, UsageGroupRow, UsageResponse, UsageSuccessRate, UsageTrendPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };
1970
+ export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DirEntryInfo, DirListResponse, ErrorBody, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryOverviewResponse, MemoryScopeInfo, MessagesLiveTail, MessagesPageInfo, MessagesResponse, ModelInfo, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SteerRequest, TaskCreateRequest, TaskCreateResponse, TaskInputPart, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentCount, UsageBucket, UsageErrorCount, UsageErrorItem, UsageErrors, UsageErrorsPage, UsageGroupBy, UsageGroupRow, UsageResponse, UsageSuccessRate, UsageTrendPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };