junhost 0.1.1 → 0.1.2

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 (92) hide show
  1. package/README.md +43 -1
  2. package/dist/index.js +51 -51
  3. package/dist/mcp-server.js +1 -1
  4. package/package.json +1 -1
  5. package/ui-dist/assets/{BrowserPage-CLwJOnA1.js → BrowserPage-Bw1kBIM_.js} +1 -1
  6. package/ui-dist/assets/{DashboardPage-DNlY12tH.js → DashboardPage-BvNlgB4B.js} +1 -1
  7. package/ui-dist/assets/{FilesPage-CfFJjtlo.js → FilesPage-C1IqnxpR.js} +1 -1
  8. package/ui-dist/assets/{McpPage-Ckmbp2T3.js → McpPage-BgXcKazm.js} +1 -1
  9. package/ui-dist/assets/{MemoriesPage-BgBe2rb6.js → MemoriesPage-DYOob4W0.js} +1 -1
  10. package/ui-dist/assets/{RunsPage-9w7iFG8N.js → RunsPage-BpBj82Ux.js} +4 -4
  11. package/ui-dist/assets/{SchedulesPage-B5FVZB0F.js → SchedulesPage-mIWaXymg.js} +1 -1
  12. package/ui-dist/assets/{SettingsPage-lNZmrgQF.js → SettingsPage-C5vG-RLn.js} +1 -1
  13. package/ui-dist/assets/{SkillsPage-BXcSp6ls.js → SkillsPage-DuFQfdSR.js} +1 -1
  14. package/ui-dist/assets/architecture-7EHR7CIX-BMNBOS2i.js +1 -0
  15. package/ui-dist/assets/{architectureDiagram-3BPJPVTR-CZU-I50b.js → architectureDiagram-3BPJPVTR-CQ1UyWn-.js} +1 -1
  16. package/ui-dist/assets/{blockDiagram-GPEHLZMM-CyBud8P5.js → blockDiagram-GPEHLZMM-DO2WH3yT.js} +1 -1
  17. package/ui-dist/assets/{c4Diagram-AAUBKEIU--J4ICgL4.js → c4Diagram-AAUBKEIU-CDcDkAFN.js} +1 -1
  18. package/ui-dist/assets/channel-BMSobhoT.js +1 -0
  19. package/ui-dist/assets/{checkbox-Dl42vHZu.js → checkbox-BO9cBKlP.js} +1 -1
  20. package/ui-dist/assets/{chunk-2J33WTMH-BDb1cFmy.js → chunk-2J33WTMH-CxE9IMxF.js} +1 -1
  21. package/ui-dist/assets/{chunk-3OPIFGDE-BlluxIcQ.js → chunk-3OPIFGDE-CWe0ghtO.js} +1 -1
  22. package/ui-dist/assets/{chunk-5ZQYHXKU-CKTcuPiD.js → chunk-5ZQYHXKU-D9lXR7-a.js} +1 -1
  23. package/ui-dist/assets/{chunk-727SXJPM-MZn2xvWx.js → chunk-727SXJPM-1INZms_u.js} +1 -1
  24. package/ui-dist/assets/{chunk-AQP2D5EJ-BJaTZvWO.js → chunk-AQP2D5EJ-Bo5P94jR.js} +1 -1
  25. package/ui-dist/assets/{chunk-BO2N2NFS-BnH2G-m5.js → chunk-BO2N2NFS-Bb9QKS7r.js} +4 -4
  26. package/ui-dist/assets/{chunk-CSCIHK7Q-CXkHF5UK.js → chunk-CSCIHK7Q-BXW0kTPy.js} +3 -3
  27. package/ui-dist/assets/{chunk-KSCS5N6A-BahjoFv5.js → chunk-KSCS5N6A-su0hRnFY.js} +1 -1
  28. package/ui-dist/assets/{chunk-L5ZTLDWV-Bx4WHt-z.js → chunk-L5ZTLDWV-CLjULdtO.js} +1 -1
  29. package/ui-dist/assets/{chunk-LZXEDZCA-CkFznL5l.js → chunk-LZXEDZCA-DSupe1kd.js} +2 -2
  30. package/ui-dist/assets/{chunk-ND2GUHAM-B8gmrqM9.js → chunk-ND2GUHAM-DVaKW6-I.js} +1 -1
  31. package/ui-dist/assets/{chunk-NZK2D7GU-C18DTyig.js → chunk-NZK2D7GU-DP_luiUT.js} +1 -1
  32. package/ui-dist/assets/{chunk-O5CBEL6O-DhXgjXO_.js → chunk-O5CBEL6O-DJ6oobwT.js} +1 -1
  33. package/ui-dist/assets/{chunk-WU5MYG2G-DakMffny.js → chunk-WU5MYG2G-BJCNi6Df.js} +1 -1
  34. package/ui-dist/assets/classDiagram-4FO5ZUOK-C8buBHXm.js +1 -0
  35. package/ui-dist/assets/classDiagram-v2-Q7XG4LA2-C8buBHXm.js +1 -0
  36. package/ui-dist/assets/{collapsible-BdLJt-lG.js → collapsible-0tqcZUWD.js} +1 -1
  37. package/ui-dist/assets/{dagre-BM42HDAG-CRPnH9-w.js → dagre-BM42HDAG-CRyL8hRI.js} +1 -1
  38. package/ui-dist/assets/{diagram-2AECGRRQ-BHmnvDJu.js → diagram-2AECGRRQ-DyjpW-BD.js} +1 -1
  39. package/ui-dist/assets/{diagram-5GNKFQAL-CnuSOf5i.js → diagram-5GNKFQAL-CBTUCxgf.js} +1 -1
  40. package/ui-dist/assets/{diagram-KO2AKTUF-DkD3Oyzq.js → diagram-KO2AKTUF-C7inOR0g.js} +1 -1
  41. package/ui-dist/assets/{diagram-LMA3HP47-qngr_ayi.js → diagram-LMA3HP47-CfCMRg_H.js} +1 -1
  42. package/ui-dist/assets/{diagram-OG6HWLK6-BUXAAFlB.js → diagram-OG6HWLK6-DLl3GKVl.js} +1 -1
  43. package/ui-dist/assets/{dialog-Bl8-9u35.js → dialog-gLEpdaG1.js} +1 -1
  44. package/ui-dist/assets/{erDiagram-TEJ5UH35-B7fmkd3a.js → erDiagram-TEJ5UH35-D3SsdlGo.js} +1 -1
  45. package/ui-dist/assets/eventmodeling-FCH6USID-Dl7jZkr1.js +1 -0
  46. package/ui-dist/assets/{flowDiagram-I6XJVG4X-D3K28Pdy.js → flowDiagram-I6XJVG4X-BIZoa3Ff.js} +1 -1
  47. package/ui-dist/assets/{ganttDiagram-6RSMTGT7-CXzmskXJ.js → ganttDiagram-6RSMTGT7-DoIzzrgl.js} +1 -1
  48. package/ui-dist/assets/{gitGraph-WXDBUCRP-CROsiysY.js → gitGraph-WXDBUCRP-tT7WczwY.js} +1 -1
  49. package/ui-dist/assets/{gitGraphDiagram-PVQCEYII-BBhICl9b.js → gitGraphDiagram-PVQCEYII-CwoMoyS1.js} +1 -1
  50. package/ui-dist/assets/{highlighted-body-OFNGDK62-woHDdMrg.js → highlighted-body-OFNGDK62-X8dg_vaO.js} +1 -1
  51. package/ui-dist/assets/{index-DmmH6oax.css → index-C_NJsn6Z.css} +1 -1
  52. package/ui-dist/assets/{index-j386AZTn.js → index-DXYsuK0q.js} +2 -2
  53. package/ui-dist/assets/{info-J43DQDTF-DHht6dOt.js → info-J43DQDTF-Da0djCPL.js} +1 -1
  54. package/ui-dist/assets/{infoDiagram-5YYISTIA-Df4LhnuE.js → infoDiagram-5YYISTIA-D-OHDMDH.js} +1 -1
  55. package/ui-dist/assets/{input-D4O22yGt.js → input-BPTmfk5i.js} +1 -1
  56. package/ui-dist/assets/{ishikawaDiagram-YF4QCWOH-B8KMc0In.js → ishikawaDiagram-YF4QCWOH-Bzg0E0Z1.js} +1 -1
  57. package/ui-dist/assets/{journeyDiagram-JHISSGLW-Bpr7eOEv.js → journeyDiagram-JHISSGLW-rmeE-f4I.js} +1 -1
  58. package/ui-dist/assets/{kanban-definition-UN3LZRKU-R8MXwX2D.js → kanban-definition-UN3LZRKU-DSy_xosI.js} +1 -1
  59. package/ui-dist/assets/katex-BNbsei-7.js +1 -0
  60. package/ui-dist/assets/{line-EyXPCaOi.js → line-6Sq5fd7W.js} +1 -1
  61. package/ui-dist/assets/mermaid-GHXKKRXX-eP_ygZe4.js +1 -0
  62. package/ui-dist/assets/{mermaid-parser.core-Bd2TX3li.js → mermaid-parser.core-C6nlL4jI.js} +2 -2
  63. package/ui-dist/assets/{mindmap-definition-RKZ34NQL-CCrZYYSm.js → mindmap-definition-RKZ34NQL-CSJ0pwqG.js} +1 -1
  64. package/ui-dist/assets/{packet-YPE3B663-BsRm1dxS.js → packet-YPE3B663-CJYSZVBB.js} +1 -1
  65. package/ui-dist/assets/{pie-LRSECV5Y-2jRO4jrF.js → pie-LRSECV5Y-B7FDQxHq.js} +1 -1
  66. package/ui-dist/assets/{pieDiagram-4H26LBE5-O21uLYd7.js → pieDiagram-4H26LBE5-BYco3Xpn.js} +1 -1
  67. package/ui-dist/assets/{quadrantDiagram-W4KKPZXB-PFuRo2tu.js → quadrantDiagram-W4KKPZXB-BSzj1BbK.js} +1 -1
  68. package/ui-dist/assets/{radar-GUYGQ44K-DrLd9hhi.js → radar-GUYGQ44K-CIqNKREz.js} +1 -1
  69. package/ui-dist/assets/{requirementDiagram-4Y6WPE33-CsP61d0X.js → requirementDiagram-4Y6WPE33-DTMmHobs.js} +1 -1
  70. package/ui-dist/assets/{sankeyDiagram-5OEKKPKP-OXRKlXwh.js → sankeyDiagram-5OEKKPKP-v48Pd1Sj.js} +1 -1
  71. package/ui-dist/assets/{select-CYgMxtlk.js → select-jBmyVjXL.js} +1 -1
  72. package/ui-dist/assets/{sequenceDiagram-3UESZ5HK-CGKNazDP.js → sequenceDiagram-3UESZ5HK-Cutc-QJ-.js} +1 -1
  73. package/ui-dist/assets/{stateDiagram-AJRCARHV-BBiaMVYA.js → stateDiagram-AJRCARHV-C9wjw5vE.js} +1 -1
  74. package/ui-dist/assets/stateDiagram-v2-BHNVJYJU-0qv-iPvr.js +1 -0
  75. package/ui-dist/assets/{tabs-DS9zR4V0.js → tabs-BUCI-mwA.js} +1 -1
  76. package/ui-dist/assets/{timeline-definition-PNZ67QCA-DCONMP8y.js → timeline-definition-PNZ67QCA-Be0sJR3F.js} +1 -1
  77. package/ui-dist/assets/{treeView-BLDUP644-DLNyeiHu.js → treeView-BLDUP644-BuO1c41a.js} +1 -1
  78. package/ui-dist/assets/{treemap-LRROVOQU-Cdld0366.js → treemap-LRROVOQU-DnqRpBrL.js} +1 -1
  79. package/ui-dist/assets/{useCompositeListItem-BQ4RLkNZ.js → useCompositeListItem-BMeUcGkY.js} +1 -1
  80. package/ui-dist/assets/{vennDiagram-CIIHVFJN-C21GUpuw.js → vennDiagram-CIIHVFJN-BU-tyhcP.js} +1 -1
  81. package/ui-dist/assets/{wardley-L42UT6IY-PuTi7B-8.js → wardley-L42UT6IY-C4lBe1D1.js} +1 -1
  82. package/ui-dist/assets/{wardleyDiagram-YWT4CUSO-BwV-yZO0.js → wardleyDiagram-YWT4CUSO-Ba4GgkxA.js} +1 -1
  83. package/ui-dist/assets/{xychartDiagram-2RQKCTM6-D-bOqUpK.js → xychartDiagram-2RQKCTM6-BZYGoMGR.js} +1 -1
  84. package/ui-dist/index.html +2 -2
  85. package/ui-dist/assets/architecture-7EHR7CIX-D8QwdCM4.js +0 -1
  86. package/ui-dist/assets/channel-CXOCC3Ms.js +0 -1
  87. package/ui-dist/assets/classDiagram-4FO5ZUOK-DMdoabn-.js +0 -1
  88. package/ui-dist/assets/classDiagram-v2-Q7XG4LA2-DMdoabn-.js +0 -1
  89. package/ui-dist/assets/eventmodeling-FCH6USID-DUPVuqbK.js +0 -1
  90. package/ui-dist/assets/katex-U6Climy7.js +0 -1
  91. package/ui-dist/assets/mermaid-GHXKKRXX-CDSYqrX3.js +0 -1
  92. package/ui-dist/assets/stateDiagram-v2-BHNVJYJU-C_bLdSQ9.js +0 -1
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  // @bun
2
- var bO=Object.create;var{getPrototypeOf:qO,defineProperty:KH,getOwnPropertyNames:IO}=Object;var jO=Object.prototype.hasOwnProperty;function gO(N){return this[N]}var vO,hO,gY=(N,H,O)=>{var W=N!=null&&typeof N==="object";if(W){var Y=H?vO??=new WeakMap:hO??=new WeakMap,G=Y.get(N);if(G)return G}O=N!=null?bO(qO(N)):{};let $=H||!N||!N.__esModule?KH(O,"default",{value:N,enumerable:!0}):O;for(let U of IO(N))if(!jO.call($,U))KH($,U,{get:gO.bind(N,U),enumerable:!0});if(W)Y.set(N,$);return $};var vY=(N,H)=>()=>(H||N((H={exports:{}}).exports,H),H.exports);var mO=(N)=>N;function cO(N,H){this[N]=mO.bind(null,H)}var hY=(N,H)=>{for(var O in H)KH(N,O,{get:H[O],enumerable:!0,configurable:!0,set:cO.bind(H,O)})};import{existsSync as xO,watch as kY}from"fs";import{stat as kO}from"fs/promises";import k from"path";import{promises as a}from"fs";import u from"path";import{existsSync as sH,renameSync as lO}from"fs";import tH from"os";import S from"path";function y(N){return process.env[`JUN_${N}`]??process.env[`AGENTHOST_${N}`]}function uO(){let N=y("HOME");if(N)return N;let H=S.join(tH.homedir(),".jun"),O=S.join(tH.homedir(),".agenthost");if(!sH(H)&&sH(O))try{lO(O,H),console.log("[paths] migrated data dir ~/.agenthost -> ~/.jun")}catch(W){return console.warn("[paths] could not migrate ~/.agenthost -> ~/.jun (files in use?) \u2014 using legacy dir:",W),O}return H}var b=uO(),z="default",AH=y("HOST")??"127.0.0.1",lN=Number(y("PORT")??8787);function UN(){return S.join(b,"projects")}function r(N=z){return S.join(UN(),N)}function n(){return S.join(b,"runs")}function J(N=z){return S.join(r(N),"workspace")}function DN(){return S.join(b,"schedules")}function q(N=z){return S.join(r(N),"codex-home")}function rH(N=z){return S.join(r(N),"widgets")}function CN(N=z){return S.join(r(N),"browser")}function uN(N){let H=S.resolve(UN()),O=S.relative(H,S.resolve(N));if(!O||O.startsWith("..")||S.isAbsolute(O))return null;return O.split(S.sep)[0]||null}function l(N){return N.split(S.sep).join("/")}function JH(N){return u.join(r(N),"project.json")}var iO=["files","reports","downloads","screenshots","artifacts",".agents/skills"],pO=["profile","downloads","screenshots","recordings"],nO={projectId:z,defaultModel:"gpt-5.4",defaultSandbox:"workspaceWrite",defaultApprovalPolicy:"onRequest",host:"127.0.0.1",port:8787,browserProvider:"agent-browser"},aO={version:1,pages:[{id:"home",title:"Home",widgets:[]}]},oO='# Jun workspace\n\nYou are running inside JunHost \u2014 a self-hosted dashboard that supervises you.\nThis directory is your workspace; write outputs here.\n\n## Browsing the web \u2014 use the `agent-browser` CLI\n\nA shared, visible browser session is already running and wired to your\nenvironment. The user can watch it live and take manual control. Drive it ONLY\nthrough the `agent-browser` command-line tool. Do NOT connect to Chrome via\nraw CDP/DevTools, scrape the `/json` debugger endpoint, or open your own\nWebSocket \u2014 that bypasses the shared session the user is watching.\n\nCommon commands (the session is preconfigured \u2014 no flags needed):\n- `agent-browser open <url>` \u2014 navigate\n- `agent-browser snapshot -i` \u2014 accessibility tree with @refs (best for deciding what to click)\n- `agent-browser click @ref` \u2014 click an element from the snapshot\n- `agent-browser fill @ref "text"` \u2014 fill an input\n- `agent-browser get text @ref` \u2014 read text (use `get url`, `get title` for page info)\n- `agent-browser scroll down 800` \u2014 scroll\n- `agent-browser screenshot screenshots/<name>.png` \u2014 capture to the workspace\n- `agent-browser eval "<js>"` \u2014 run JS in the page when no command fits\n\nPrefer snapshot \u2192 ref-based actions over guessing selectors. Save screenshots\nand extracted notes under `reports/` and `screenshots/`.\n\n## Output locations\n- `reports/` \u2014 summaries and findings\n- `screenshots/` \u2014 captured images\n- `downloads/` \u2014 downloaded files\n',dO=`# Codex configuration for this Jun project.
2
+ var vW=Object.create;var{getPrototypeOf:hW,defineProperty:KH,getOwnPropertyNames:mW}=Object;var cW=Object.prototype.hasOwnProperty;function lW(N){return this[N]}var uW,iW,oY=(N,H,W)=>{var O=N!=null&&typeof N==="object";if(O){var Y=H?uW??=new WeakMap:iW??=new WeakMap,G=Y.get(N);if(G)return G}W=N!=null?vW(hW(N)):{};let $=H||!N||!N.__esModule?KH(W,"default",{value:N,enumerable:!0}):W;for(let U of mW(N))if(!cW.call($,U))KH($,U,{get:lW.bind(N,U),enumerable:!0});if(O)Y.set(N,$);return $};var dY=(N,H)=>()=>(H||N((H={exports:{}}).exports,H),H.exports);var pW=(N)=>N;function nW(N,H){this[N]=pW.bind(null,H)}var sY=(N,H)=>{for(var W in H)KH(N,W,{get:H[W],enumerable:!0,configurable:!0,set:nW.bind(H,W)})};import{existsSync as IW,watch as lY}from"fs";import{stat as jW}from"fs/promises";import k from"path";import{promises as a}from"fs";import u from"path";import{existsSync as eH,renameSync as aW}from"fs";import N0 from"os";import S from"path";function y(N){return process.env[`JUN_${N}`]??process.env[`AGENTHOST_${N}`]}function oW(){let N=y("HOME");if(N)return N;let H=S.join(N0.homedir(),".jun"),W=S.join(N0.homedir(),".agenthost");if(!eH(H)&&eH(W))try{aW(W,H),console.log("[paths] migrated data dir ~/.agenthost -> ~/.jun")}catch(O){return console.warn("[paths] could not migrate ~/.agenthost -> ~/.jun (files in use?) \u2014 using legacy dir:",O),W}return H}var b=oW(),F="default",JH=y("HOST")??"127.0.0.1",uN=Number(y("PORT")??8787);function UN(){return S.join(b,"projects")}function r(N=F){return S.join(UN(),N)}function n(){return S.join(b,"runs")}function A(N=F){return S.join(r(N),"workspace")}function CN(){return S.join(b,"schedules")}function q(N=F){return S.join(r(N),"codex-home")}function H0(N=F){return S.join(r(N),"widgets")}function SN(N=F){return S.join(r(N),"browser")}function iN(N){let H=S.resolve(UN()),W=S.relative(H,S.resolve(N));if(!W||W.startsWith("..")||S.isAbsolute(W))return null;return W.split(S.sep)[0]||null}function l(N){return N.split(S.sep).join("/")}function AH(N){return u.join(r(N),"project.json")}var dW=["files","reports","downloads","screenshots","artifacts",".agents/skills"],sW=["profile","downloads","screenshots","recordings"],tW={projectId:F,defaultModel:"gpt-5.4",defaultSandbox:"workspaceWrite",defaultApprovalPolicy:"onRequest",host:"127.0.0.1",port:8787,browserProvider:"agent-browser"},rW={version:1,pages:[{id:"home",title:"Home",widgets:[]}]},eW='# Jun workspace\n\nYou are running inside JunHost \u2014 a self-hosted dashboard that supervises you.\nThis directory is your workspace; write outputs here.\n\n## Browsing the web \u2014 use the `agent-browser` CLI\n\nA shared, visible browser session is already running and wired to your\nenvironment. The user can watch it live and take manual control. Drive it ONLY\nthrough the `agent-browser` command-line tool. Do NOT connect to Chrome via\nraw CDP/DevTools, scrape the `/json` debugger endpoint, or open your own\nWebSocket \u2014 that bypasses the shared session the user is watching.\n\nCommon commands (the session is preconfigured \u2014 no flags needed):\n- `agent-browser open <url>` \u2014 navigate\n- `agent-browser snapshot -i` \u2014 accessibility tree with @refs (best for deciding what to click)\n- `agent-browser click @ref` \u2014 click an element from the snapshot\n- `agent-browser fill @ref "text"` \u2014 fill an input\n- `agent-browser get text @ref` \u2014 read text (use `get url`, `get title` for page info)\n- `agent-browser scroll down 800` \u2014 scroll\n- `agent-browser screenshot screenshots/<name>.png` \u2014 capture to the workspace\n- `agent-browser eval "<js>"` \u2014 run JS in the page when no command fits\n\nPrefer snapshot \u2192 ref-based actions over guessing selectors. Save screenshots\nand extracted notes under `reports/` and `screenshots/`.\n\n## Output locations\n- `reports/` \u2014 summaries and findings\n- `screenshots/` \u2014 captured images\n- `downloads/` \u2014 downloaded files\n',NO=`# Codex configuration for this Jun project.
3
3
  # MCP servers are configured here, e.g.:
4
4
  #
5
5
  # [mcp_servers.context7]
6
6
  # command = "npx"
7
7
  # args = ["-y", "@upstash/context7-mcp"]
8
- `;async function SN(N,H){try{await a.access(N)}catch{await a.mkdir(u.dirname(N),{recursive:!0}),await a.writeFile(N,H,"utf8")}}async function BH(N,H){let O=J(N);for(let W of iO)await a.mkdir(u.join(O,W),{recursive:!0});for(let W of pO)await a.mkdir(u.join(CN(N),W),{recursive:!0});await a.mkdir(rH(N),{recursive:!0}),await a.mkdir(u.join(q(N),"logs"),{recursive:!0}),await SN(JH(N),JSON.stringify({id:N,name:H??N,createdAt:new Date().toISOString()},null,2)+`
9
- `),await SN(u.join(r(N),"dashboard.json"),JSON.stringify(aO,null,2)+`
10
- `),await SN(u.join(q(N),"config.toml"),dO),await SN(u.join(O,"AGENTS.md"),oO)}async function eH(){await a.mkdir(n(),{recursive:!0}),await SN(u.join(b,"config.json"),JSON.stringify(nO,null,2)+`
11
- `),await BH(z,"Default")}import{promises as FN}from"fs";import pW from"path";/*!
8
+ `;async function RN(N,H){try{await a.access(N)}catch{await a.mkdir(u.dirname(N),{recursive:!0}),await a.writeFile(N,H,"utf8")}}async function BH(N,H){let W=A(N);for(let O of dW)await a.mkdir(u.join(W,O),{recursive:!0});for(let O of sW)await a.mkdir(u.join(SN(N),O),{recursive:!0});await a.mkdir(H0(N),{recursive:!0}),await a.mkdir(u.join(q(N),"logs"),{recursive:!0}),await RN(AH(N),JSON.stringify({id:N,name:H??N,createdAt:new Date().toISOString()},null,2)+`
9
+ `),await RN(u.join(r(N),"dashboard.json"),JSON.stringify(rW,null,2)+`
10
+ `),await RN(u.join(q(N),"config.toml"),NO),await RN(u.join(W,"AGENTS.md"),eW)}async function W0(){await a.mkdir(n(),{recursive:!0}),await RN(u.join(b,"config.json"),JSON.stringify(tW,null,2)+`
11
+ `),await BH(F,"Default")}import{promises as FN}from"fs";import sO from"path";/*!
12
12
  * Copyright (c) Squirrel Chat et al., All rights reserved.
13
13
  * SPDX-License-Identifier: BSD-3-Clause
14
14
  *
@@ -34,11 +34,11 @@ var bO=Object.create;var{getPrototypeOf:qO,defineProperty:KH,getOwnPropertyNames
34
34
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35
35
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36
36
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
- */function sO(N,H){let O=N.slice(0,H).split(/\r\n|\n|\r/g);return[O.length,O.pop().length+1]}function tO(N,H,O){let W=N.split(/\r\n|\n|\r/g),Y="",G=(Math.log10(H+1)|0)+1;for(let $=H-1;$<=H+1;$++){let U=W[$-1];if(!U)continue;if(Y+=$.toString().padEnd(G," "),Y+=": ",Y+=U,Y+=`
38
- `,$===H)Y+=" ".repeat(G+O+2),Y+=`^
39
- `}return Y}class V extends Error{line;column;codeblock;constructor(N,H){let[O,W]=sO(H.toml,H.ptr),Y=tO(H.toml,O,W);super(`Invalid TOML document: ${N}
37
+ */function HO(N,H){let W=N.slice(0,H).split(/\r\n|\n|\r/g);return[W.length,W.pop().length+1]}function WO(N,H,W){let O=N.split(/\r\n|\n|\r/g),Y="",G=(Math.log10(H+1)|0)+1;for(let $=H-1;$<=H+1;$++){let U=O[$-1];if(!U)continue;if(Y+=$.toString().padEnd(G," "),Y+=": ",Y+=U,Y+=`
38
+ `,$===H)Y+=" ".repeat(G+W+2),Y+=`^
39
+ `}return Y}class V extends Error{line;column;codeblock;constructor(N,H){let[W,O]=HO(H.toml,H.ptr),Y=WO(H.toml,W,O);super(`Invalid TOML document: ${N}
40
40
 
41
- ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
41
+ ${Y}`,H);this.line=W,this.column=O,this.codeblock=Y}}/*!
42
42
  * Copyright (c) Squirrel Chat et al., All rights reserved.
43
43
  * SPDX-License-Identifier: BSD-3-Clause
44
44
  *
@@ -64,14 +64,14 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
64
64
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
65
65
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
66
66
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67
- */function rO(N,H){let O=0;while(N[H-++O]==="\\");return--O&&O%2}function iN(N,H=0,O=N.length){let W=N.indexOf(`
68
- `,H);if(N[W-1]==="\r")W--;return W<=O?W:-1}function QN(N,H){for(let O=H;O<N.length;O++){let W=N[O];if(W===`
69
- `)return O;if(W==="\r"&&N[O+1]===`
70
- `)return O+1;if(W<" "&&W!=="\t"||W==="\x7F")throw new V("control characters are not allowed in comments",{toml:N,ptr:H})}return N.length}function _(N,H,O,W){let Y;while(!0){while((Y=N[H])===" "||Y==="\t"||!O&&(Y===`
67
+ */function OO(N,H){let W=0;while(N[H-++W]==="\\");return--W&&W%2}function pN(N,H=0,W=N.length){let O=N.indexOf(`
68
+ `,H);if(N[O-1]==="\r")O--;return O<=W?O:-1}function QN(N,H){for(let W=H;W<N.length;W++){let O=N[W];if(O===`
69
+ `)return W;if(O==="\r"&&N[W+1]===`
70
+ `)return W+1;if(O<" "&&O!=="\t"||O==="\x7F")throw new V("control characters are not allowed in comments",{toml:N,ptr:H})}return N.length}function _(N,H,W,O){let Y;while(!0){while((Y=N[H])===" "||Y==="\t"||!W&&(Y===`
71
71
  `||Y==="\r"&&N[H+1]===`
72
- `))H++;if(W||Y!=="#")break;H=QN(N,H)}return H}function N0(N,H,O,W,Y=!1){if(!W)return H=iN(N,H),H<0?N.length:H;for(let G=H;G<N.length;G++){let $=N[G];if($==="#")G=iN(N,G);else if($===O)return G+1;else if($===W||Y&&($===`
72
+ `))H++;if(O||Y!=="#")break;H=QN(N,H)}return H}function O0(N,H,W,O,Y=!1){if(!O)return H=pN(N,H),H<0?N.length:H;for(let G=H;G<N.length;G++){let $=N[G];if($==="#")G=pN(N,G);else if($===W)return G+1;else if($===O||Y&&($===`
73
73
  `||$==="\r"&&N[G+1]===`
74
- `))return G}throw new V("cannot find end of structure",{toml:N,ptr:H})}function pN(N,H){let O=N[H],W=O===N[H+1]&&N[H+1]===N[H+2]?N.slice(H,H+3):O;H+=W.length-1;do H=N.indexOf(W,++H);while(H>-1&&O!=="'"&&rO(N,H));if(H>-1){if(H+=W.length,W.length>1){if(N[H]===O)H++;if(N[H]===O)H++}}return H}/*!
74
+ `))return G}throw new V("cannot find end of structure",{toml:N,ptr:H})}function nN(N,H){let W=N[H],O=W===N[H+1]&&N[H+1]===N[H+2]?N.slice(H,H+3):W;H+=O.length-1;do H=N.indexOf(O,++H);while(H>-1&&W!=="'"&&OO(N,H));if(H>-1){if(H+=O.length,O.length>1){if(N[H]===W)H++;if(N[H]===W)H++}}return H}/*!
75
75
  * Copyright (c) Squirrel Chat et al., All rights reserved.
76
76
  * SPDX-License-Identifier: BSD-3-Clause
77
77
  *
@@ -97,7 +97,7 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
97
97
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
98
98
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
99
99
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100
- */var eO=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;class o extends Date{#H=!1;#O=!1;#N=null;constructor(N){let H=!0,O=!0,W="Z";if(typeof N==="string"){let Y=N.match(eO);if(Y){if(!Y[1])H=!1,N=`0000-01-01T${N}`;if(O=!!Y[2],O&&N[10]===" "&&(N=N.replace(" ","T")),Y[2]&&+Y[2]>23)N="";else if(W=Y[3]||null,N=N.toUpperCase(),!W&&O)N+="Z"}else N=""}super(N);if(!isNaN(this.getTime()))this.#H=H,this.#O=O,this.#N=W}isDateTime(){return this.#H&&this.#O}isLocal(){return!this.#H||!this.#O||!this.#N}isDate(){return this.#H&&!this.#O}isTime(){return this.#O&&!this.#H}isValid(){return this.#H||this.#O}toISOString(){let N=super.toISOString();if(this.isDate())return N.slice(0,10);if(this.isTime())return N.slice(11,23);if(this.#N===null)return N.slice(0,-1);if(this.#N==="Z")return N;let H=+this.#N.slice(1,3)*60+ +this.#N.slice(4,6);return H=this.#N[0]==="-"?H:-H,new Date(this.getTime()-H*60000).toISOString().slice(0,-1)+this.#N}static wrapAsOffsetDateTime(N,H="Z"){let O=new o(N);return O.#N=H,O}static wrapAsLocalDateTime(N){let H=new o(N);return H.#N=null,H}static wrapAsLocalDate(N){let H=new o(N);return H.#O=!1,H.#N=null,H}static wrapAsLocalTime(N){let H=new o(N);return H.#H=!1,H.#N=null,H}}/*!
100
+ */var YO=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;class o extends Date{#H=!1;#W=!1;#N=null;constructor(N){let H=!0,W=!0,O="Z";if(typeof N==="string"){let Y=N.match(YO);if(Y){if(!Y[1])H=!1,N=`0000-01-01T${N}`;if(W=!!Y[2],W&&N[10]===" "&&(N=N.replace(" ","T")),Y[2]&&+Y[2]>23)N="";else if(O=Y[3]||null,N=N.toUpperCase(),!O&&W)N+="Z"}else N=""}super(N);if(!isNaN(this.getTime()))this.#H=H,this.#W=W,this.#N=O}isDateTime(){return this.#H&&this.#W}isLocal(){return!this.#H||!this.#W||!this.#N}isDate(){return this.#H&&!this.#W}isTime(){return this.#W&&!this.#H}isValid(){return this.#H||this.#W}toISOString(){let N=super.toISOString();if(this.isDate())return N.slice(0,10);if(this.isTime())return N.slice(11,23);if(this.#N===null)return N.slice(0,-1);if(this.#N==="Z")return N;let H=+this.#N.slice(1,3)*60+ +this.#N.slice(4,6);return H=this.#N[0]==="-"?H:-H,new Date(this.getTime()-H*60000).toISOString().slice(0,-1)+this.#N}static wrapAsOffsetDateTime(N,H="Z"){let W=new o(N);return W.#N=H,W}static wrapAsLocalDateTime(N){let H=new o(N);return H.#N=null,H}static wrapAsLocalDate(N){let H=new o(N);return H.#W=!1,H.#N=null,H}static wrapAsLocalTime(N){let H=new o(N);return H.#H=!1,H.#N=null,H}}/*!
101
101
  * Copyright (c) Squirrel Chat et al., All rights reserved.
102
102
  * SPDX-License-Identifier: BSD-3-Clause
103
103
  *
@@ -123,13 +123,13 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
123
123
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
124
124
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
125
125
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126
- */var NW=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,HW=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,OW=/^[+-]?0[0-9_]/,WW=/^[0-9a-f]{2,8}$/i,H0={b:"\b",t:"\t",n:`
127
- `,f:"\f",r:"\r",e:"\x1B",'"':'"',"\\":"\\"};function nN(N,H=0,O=N.length){let W=N[H]==="'",Y=N[H++]===N[H]&&N[H]===N[H+1];if(Y){if(O-=2,N[H+=2]==="\r")H++;if(N[H]===`
128
- `)H++}let G=0,$,U="",Q=H;while(H<O-1){let X=N[H++];if(X===`
126
+ */var GO=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,$O=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,UO=/^[+-]?0[0-9_]/,QO=/^[0-9a-f]{2,8}$/i,Y0={b:"\b",t:"\t",n:`
127
+ `,f:"\f",r:"\r",e:"\x1B",'"':'"',"\\":"\\"};function aN(N,H=0,W=N.length){let O=N[H]==="'",Y=N[H++]===N[H]&&N[H]===N[H+1];if(Y){if(W-=2,N[H+=2]==="\r")H++;if(N[H]===`
128
+ `)H++}let G=0,$,U="",Q=H;while(H<W-1){let X=N[H++];if(X===`
129
129
  `||X==="\r"&&N[H]===`
130
- `){if(!Y)throw new V("newlines are not allowed in strings",{toml:N,ptr:H-1})}else if(X<" "&&X!=="\t"||X==="\x7F")throw new V("control characters are not allowed in strings",{toml:N,ptr:H-1});if($){if($=!1,X==="x"||X==="u"||X==="U"){let F=N.slice(H,H+=X==="x"?2:X==="u"?4:8);if(!WW.test(F))throw new V("invalid unicode escape",{toml:N,ptr:G});try{U+=String.fromCodePoint(parseInt(F,16))}catch{throw new V("invalid unicode escape",{toml:N,ptr:G})}}else if(Y&&(X===`
130
+ `){if(!Y)throw new V("newlines are not allowed in strings",{toml:N,ptr:H-1})}else if(X<" "&&X!=="\t"||X==="\x7F")throw new V("control characters are not allowed in strings",{toml:N,ptr:H-1});if($){if($=!1,X==="x"||X==="u"||X==="U"){let z=N.slice(H,H+=X==="x"?2:X==="u"?4:8);if(!QO.test(z))throw new V("invalid unicode escape",{toml:N,ptr:G});try{U+=String.fromCodePoint(parseInt(z,16))}catch{throw new V("invalid unicode escape",{toml:N,ptr:G})}}else if(Y&&(X===`
131
131
  `||X===" "||X==="\t"||X==="\r")){if(H=_(N,H-1,!0),N[H]!==`
132
- `&&N[H]!=="\r")throw new V("invalid escape: only line-ending whitespace may be escaped",{toml:N,ptr:G});H=_(N,H)}else if(X in H0)U+=H0[X];else throw new V("unrecognized escape sequence",{toml:N,ptr:G});Q=H}else if(!W&&X==="\\")G=H-1,$=!0,U+=N.slice(Q,G)}return U+N.slice(Q,O-1)}function O0(N,H,O,W){if(N==="true")return!0;if(N==="false")return!1;if(N==="-inf")return-1/0;if(N==="inf"||N==="+inf")return 1/0;if(N==="nan"||N==="+nan"||N==="-nan")return NaN;if(N==="-0")return W?0n:0;let Y=NW.test(N);if(Y||HW.test(N)){if(OW.test(N))throw new V("leading zeroes are not allowed",{toml:H,ptr:O});N=N.replace(/_/g,"");let $=+N;if(isNaN($))throw new V("invalid number",{toml:H,ptr:O});if(Y){if((Y=!Number.isSafeInteger($))&&!W)throw new V("integer value cannot be represented losslessly",{toml:H,ptr:O});if(Y||W===!0)$=BigInt(N)}return $}let G=new o(N);if(!G.isValid())throw new V("invalid value",{toml:H,ptr:O});return G}/*!
132
+ `&&N[H]!=="\r")throw new V("invalid escape: only line-ending whitespace may be escaped",{toml:N,ptr:G});H=_(N,H)}else if(X in Y0)U+=Y0[X];else throw new V("unrecognized escape sequence",{toml:N,ptr:G});Q=H}else if(!O&&X==="\\")G=H-1,$=!0,U+=N.slice(Q,G)}return U+N.slice(Q,W-1)}function G0(N,H,W,O){if(N==="true")return!0;if(N==="false")return!1;if(N==="-inf")return-1/0;if(N==="inf"||N==="+inf")return 1/0;if(N==="nan"||N==="+nan"||N==="-nan")return NaN;if(N==="-0")return O?0n:0;let Y=GO.test(N);if(Y||$O.test(N)){if(UO.test(N))throw new V("leading zeroes are not allowed",{toml:H,ptr:W});N=N.replace(/_/g,"");let $=+N;if(isNaN($))throw new V("invalid number",{toml:H,ptr:W});if(Y){if((Y=!Number.isSafeInteger($))&&!O)throw new V("integer value cannot be represented losslessly",{toml:H,ptr:W});if(Y||O===!0)$=BigInt(N)}return $}let G=new o(N);if(!G.isValid())throw new V("invalid value",{toml:H,ptr:W});return G}/*!
133
133
  * Copyright (c) Squirrel Chat et al., All rights reserved.
134
134
  * SPDX-License-Identifier: BSD-3-Clause
135
135
  *
@@ -155,8 +155,8 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
155
155
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
156
156
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
157
157
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
158
- */function YW(N,H,O){let W=N.slice(H,O),Y=W.indexOf("#");if(Y>-1)QN(N,Y),W=W.slice(0,Y);return[W.trimEnd(),Y]}function RN(N,H,O,W,Y){if(W===0)throw new V("document contains excessively nested structures. aborting.",{toml:N,ptr:H});let G=N[H];if(G==="["||G==="{"){let[Q,X]=G==="["?Y0(N,H,W,Y):W0(N,H,W,Y);if(O){if(X=_(N,X),N[X]===",")X++;else if(N[X]!==O)throw new V("expected comma or end of structure",{toml:N,ptr:X})}return[Q,X]}let $;if(G==='"'||G==="'"){$=pN(N,H);let Q=nN(N,H,$);if(O){if($=_(N,$),N[$]&&N[$]!==","&&N[$]!==O&&N[$]!==`
159
- `&&N[$]!=="\r")throw new V("unexpected character encountered",{toml:N,ptr:$});$+=+(N[$]===",")}return[Q,$]}$=N0(N,H,",",O);let U=YW(N,H,$-+(N[$-1]===","));if(!U[0])throw new V("incomplete key-value declaration: no value specified",{toml:N,ptr:H});if(O&&U[1]>-1)$=_(N,H+U[1]),$+=+(N[$]===",");return[O0(U[0],N,H,Y),$]}/*!
158
+ */function XO(N,H,W){let O=N.slice(H,W),Y=O.indexOf("#");if(Y>-1)QN(N,Y),O=O.slice(0,Y);return[O.trimEnd(),Y]}function EN(N,H,W,O,Y){if(O===0)throw new V("document contains excessively nested structures. aborting.",{toml:N,ptr:H});let G=N[H];if(G==="["||G==="{"){let[Q,X]=G==="["?U0(N,H,O,Y):$0(N,H,O,Y);if(W){if(X=_(N,X),N[X]===",")X++;else if(N[X]!==W)throw new V("expected comma or end of structure",{toml:N,ptr:X})}return[Q,X]}let $;if(G==='"'||G==="'"){$=nN(N,H);let Q=aN(N,H,$);if(W){if($=_(N,$),N[$]&&N[$]!==","&&N[$]!==W&&N[$]!==`
159
+ `&&N[$]!=="\r")throw new V("unexpected character encountered",{toml:N,ptr:$});$+=+(N[$]===",")}return[Q,$]}$=O0(N,H,",",W);let U=XO(N,H,$-+(N[$-1]===","));if(!U[0])throw new V("incomplete key-value declaration: no value specified",{toml:N,ptr:H});if(W&&U[1]>-1)$=_(N,H+U[1]),$+=+(N[$]===",");return[G0(U[0],N,H,Y),$]}/*!
160
160
  * Copyright (c) Squirrel Chat et al., All rights reserved.
161
161
  * SPDX-License-Identifier: BSD-3-Clause
162
162
  *
@@ -182,9 +182,9 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
182
182
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
183
183
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
184
184
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
185
- */var GW=/^[a-zA-Z0-9-_]+[ \t]*$/;function aN(N,H,O="="){let W=H-1,Y=[],G=N.indexOf(O,H);if(G<0)throw new V("incomplete key-value: cannot find end of key",{toml:N,ptr:H});do{let $=N[H=++W];if($!==" "&&$!=="\t")if($==='"'||$==="'"){if($===N[H+1]&&$===N[H+2])throw new V("multiline strings are not allowed in keys",{toml:N,ptr:H});let U=pN(N,H);if(U<0)throw new V("unfinished string encountered",{toml:N,ptr:H});W=N.indexOf(".",U);let Q=N.slice(U,W<0||W>G?G:W),X=iN(Q);if(X>-1)throw new V("newlines are not allowed in keys",{toml:N,ptr:H+W+X});if(Q.trimStart())throw new V("found extra tokens after the string part",{toml:N,ptr:U});if(G<U){if(G=N.indexOf(O,U),G<0)throw new V("incomplete key-value: cannot find end of key",{toml:N,ptr:H})}Y.push(nN(N,H,U))}else{W=N.indexOf(".",H);let U=N.slice(H,W<0||W>G?G:W);if(!GW.test(U))throw new V("only letter, numbers, dashes and underscores are allowed in keys",{toml:N,ptr:H});Y.push(U.trimEnd())}}while(W+1&&W<G);return[Y,_(N,G+1,!0,!0)]}function W0(N,H,O,W){let Y={},G=new Set,$;H++;while(($=N[H++])!=="}"&&$)if($===",")throw new V("expected value, found comma",{toml:N,ptr:H-1});else if($==="#")H=QN(N,H);else if($!==" "&&$!=="\t"&&$!==`
186
- `&&$!=="\r"){let U,Q=Y,X=!1,[F,K]=aN(N,H-1);for(let $N=0;$N<F.length;$N++){if($N)Q=X?Q[U]:Q[U]={};if(U=F[$N],(X=Object.hasOwn(Q,U))&&(typeof Q[U]!=="object"||G.has(Q[U])))throw new V("trying to redefine an already defined value",{toml:N,ptr:H});if(!X&&U==="__proto__")Object.defineProperty(Q,U,{enumerable:!0,configurable:!0,writable:!0})}if(X)throw new V("trying to redefine an already defined value",{toml:N,ptr:H});let[R,f]=RN(N,K,"}",O-1,W);G.add(R),Q[U]=R,H=f}if(!$)throw new V("unfinished table encountered",{toml:N,ptr:H});return[Y,H]}function Y0(N,H,O,W){let Y=[],G;H++;while((G=N[H++])!=="]"&&G)if(G===",")throw new V("expected value, found comma",{toml:N,ptr:H-1});else if(G==="#")H=QN(N,H);else if(G!==" "&&G!=="\t"&&G!==`
187
- `&&G!=="\r"){let $=RN(N,H-1,"]",O-1,W);Y.push($[0]),H=$[1]}if(!G)throw new V("unfinished array encountered",{toml:N,ptr:H});return[Y,H]}/*!
185
+ */var ZO=/^[a-zA-Z0-9-_]+[ \t]*$/;function oN(N,H,W="="){let O=H-1,Y=[],G=N.indexOf(W,H);if(G<0)throw new V("incomplete key-value: cannot find end of key",{toml:N,ptr:H});do{let $=N[H=++O];if($!==" "&&$!=="\t")if($==='"'||$==="'"){if($===N[H+1]&&$===N[H+2])throw new V("multiline strings are not allowed in keys",{toml:N,ptr:H});let U=nN(N,H);if(U<0)throw new V("unfinished string encountered",{toml:N,ptr:H});O=N.indexOf(".",U);let Q=N.slice(U,O<0||O>G?G:O),X=pN(Q);if(X>-1)throw new V("newlines are not allowed in keys",{toml:N,ptr:H+O+X});if(Q.trimStart())throw new V("found extra tokens after the string part",{toml:N,ptr:U});if(G<U){if(G=N.indexOf(W,U),G<0)throw new V("incomplete key-value: cannot find end of key",{toml:N,ptr:H})}Y.push(aN(N,H,U))}else{O=N.indexOf(".",H);let U=N.slice(H,O<0||O>G?G:O);if(!ZO.test(U))throw new V("only letter, numbers, dashes and underscores are allowed in keys",{toml:N,ptr:H});Y.push(U.trimEnd())}}while(O+1&&O<G);return[Y,_(N,G+1,!0,!0)]}function $0(N,H,W,O){let Y={},G=new Set,$;H++;while(($=N[H++])!=="}"&&$)if($===",")throw new V("expected value, found comma",{toml:N,ptr:H-1});else if($==="#")H=QN(N,H);else if($!==" "&&$!=="\t"&&$!==`
186
+ `&&$!=="\r"){let U,Q=Y,X=!1,[z,K]=oN(N,H-1);for(let $N=0;$N<z.length;$N++){if($N)Q=X?Q[U]:Q[U]={};if(U=z[$N],(X=Object.hasOwn(Q,U))&&(typeof Q[U]!=="object"||G.has(Q[U])))throw new V("trying to redefine an already defined value",{toml:N,ptr:H});if(!X&&U==="__proto__")Object.defineProperty(Q,U,{enumerable:!0,configurable:!0,writable:!0})}if(X)throw new V("trying to redefine an already defined value",{toml:N,ptr:H});let[R,f]=EN(N,K,"}",W-1,O);G.add(R),Q[U]=R,H=f}if(!$)throw new V("unfinished table encountered",{toml:N,ptr:H});return[Y,H]}function U0(N,H,W,O){let Y=[],G;H++;while((G=N[H++])!=="]"&&G)if(G===",")throw new V("expected value, found comma",{toml:N,ptr:H-1});else if(G==="#")H=QN(N,H);else if(G!==" "&&G!=="\t"&&G!==`
187
+ `&&G!=="\r"){let $=EN(N,H-1,"]",W-1,O);Y.push($[0]),H=$[1]}if(!G)throw new V("unfinished array encountered",{toml:N,ptr:H});return[Y,H]}/*!
188
188
  * Copyright (c) Squirrel Chat et al., All rights reserved.
189
189
  * SPDX-License-Identifier: BSD-3-Clause
190
190
  *
@@ -210,8 +210,8 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
210
210
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
211
211
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
212
212
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
213
- */function G0(N,H,O,W){let Y=H,G=O,$,U=!1,Q;for(let X=0;X<N.length;X++){if(X){if(Y=U?Y[$]:Y[$]={},G=(Q=G[$]).c,W===0&&(Q.t===1||Q.t===2))return null;if(Q.t===2){let F=Y.length-1;Y=Y[F],G=G[F].c}}if($=N[X],(U=Object.hasOwn(Y,$))&&G[$]?.t===0&&G[$]?.d)return null;if(!U){if($==="__proto__")Object.defineProperty(Y,$,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(G,$,{enumerable:!0,configurable:!0,writable:!0});G[$]={t:X<N.length-1&&W===2?3:W,d:!1,i:0,c:{}}}}if(Q=G[$],Q.t!==W&&!(W===1&&Q.t===3))return null;if(W===2){if(!Q.d)Q.d=!0,Y[$]=[];Y[$].push(Y={}),Q.c[Q.i++]=Q={t:1,d:!1,i:0,c:{}}}if(Q.d)return null;if(Q.d=!0,W===1)Y=U?Y[$]:Y[$]={};else if(W===0&&U)return null;return[$,Y,Q.c]}function c(N,{maxDepth:H=1000,integersAsBigInt:O}={}){let W={},Y={},G=W,$=Y;for(let U=_(N,0);U<N.length;){if(N[U]==="["){let Q=N[++U]==="[",X=aN(N,U+=+Q,"]");if(Q){if(N[X[1]-1]!=="]")throw new V("expected end of table declaration",{toml:N,ptr:X[1]-1});X[1]++}let F=G0(X[0],W,Y,Q?2:1);if(!F)throw new V("trying to redefine an already defined table or value",{toml:N,ptr:U});$=F[2],G=F[1],U=X[1]}else{let Q=aN(N,U),X=G0(Q[0],G,$,0);if(!X)throw new V("trying to redefine an already defined table or value",{toml:N,ptr:U});let F=RN(N,Q[1],void 0,H,O);X[1][X[0]]=F[0],U=F[1]}if(U=_(N,U,!0),N[U]&&N[U]!==`
214
- `&&N[U]!=="\r")throw new V("each key-value declaration must be followed by an end-of-line",{toml:N,ptr:U});U=_(N,U)}return W}/*!
213
+ */function Q0(N,H,W,O){let Y=H,G=W,$,U=!1,Q;for(let X=0;X<N.length;X++){if(X){if(Y=U?Y[$]:Y[$]={},G=(Q=G[$]).c,O===0&&(Q.t===1||Q.t===2))return null;if(Q.t===2){let z=Y.length-1;Y=Y[z],G=G[z].c}}if($=N[X],(U=Object.hasOwn(Y,$))&&G[$]?.t===0&&G[$]?.d)return null;if(!U){if($==="__proto__")Object.defineProperty(Y,$,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(G,$,{enumerable:!0,configurable:!0,writable:!0});G[$]={t:X<N.length-1&&O===2?3:O,d:!1,i:0,c:{}}}}if(Q=G[$],Q.t!==O&&!(O===1&&Q.t===3))return null;if(O===2){if(!Q.d)Q.d=!0,Y[$]=[];Y[$].push(Y={}),Q.c[Q.i++]=Q={t:1,d:!1,i:0,c:{}}}if(Q.d)return null;if(Q.d=!0,O===1)Y=U?Y[$]:Y[$]={};else if(O===0&&U)return null;return[$,Y,Q.c]}function c(N,{maxDepth:H=1000,integersAsBigInt:W}={}){let O={},Y={},G=O,$=Y;for(let U=_(N,0);U<N.length;){if(N[U]==="["){let Q=N[++U]==="[",X=oN(N,U+=+Q,"]");if(Q){if(N[X[1]-1]!=="]")throw new V("expected end of table declaration",{toml:N,ptr:X[1]-1});X[1]++}let z=Q0(X[0],O,Y,Q?2:1);if(!z)throw new V("trying to redefine an already defined table or value",{toml:N,ptr:U});$=z[2],G=z[1],U=X[1]}else{let Q=oN(N,U),X=Q0(Q[0],G,$,0);if(!X)throw new V("trying to redefine an already defined table or value",{toml:N,ptr:U});let z=EN(N,Q[1],void 0,H,W);X[1][X[0]]=z[0],U=z[1]}if(U=_(N,U,!0),N[U]&&N[U]!==`
214
+ `&&N[U]!=="\r")throw new V("each key-value declaration must be followed by an end-of-line",{toml:N,ptr:U});U=_(N,U)}return O}/*!
215
215
  * Copyright (c) Squirrel Chat et al., All rights reserved.
216
216
  * SPDX-License-Identifier: BSD-3-Clause
217
217
  *
@@ -237,16 +237,16 @@ ${Y}`,H);this.line=O,this.column=W,this.codeblock=Y}}/*!
237
237
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
238
238
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
239
239
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
240
- */var $0=/^[a-z0-9-_]+$/i;function TN(N){let H=typeof N;if(H==="object"){if(Array.isArray(N))return"array";if(N instanceof Date)return"date"}return H}function $W(N){for(let H=0;H<N.length;H++)if(TN(N[H])!=="object")return!1;return N.length!=0}function DH(N){return JSON.stringify(N).replace(/\x7f/g,"\\u007f")}function CH(N,H,O,W){if(O===0)throw Error("Could not stringify the object: maximum object depth exceeded");if(H==="number"){if(isNaN(N))return"nan";if(N===1/0)return"inf";if(N===-1/0)return"-inf";if(W&&Number.isInteger(N))return N.toFixed(1);return N.toString()}if(H==="bigint"||H==="boolean")return N.toString();if(H==="string")return DH(N);if(H==="date"){if(isNaN(N.getTime()))throw TypeError("cannot serialize invalid date");return N.toISOString()}if(H==="object")return UW(N,O,W);if(H==="array")return QW(N,O,W)}function UW(N,H,O){let W=Object.keys(N);if(W.length===0)return"{}";let Y="{ ";for(let G=0;G<W.length;G++){let $=W[G];if(G)Y+=", ";Y+=$0.test($)?$:DH($),Y+=" = ",Y+=CH(N[$],TN(N[$]),H-1,O)}return Y+" }"}function QW(N,H,O){if(N.length===0)return"[]";let W="[ ";for(let Y=0;Y<N.length;Y++){if(Y)W+=", ";if(N[Y]===null||N[Y]===void 0)throw TypeError("arrays cannot contain null or undefined values");W+=CH(N[Y],TN(N[Y]),H-1,O)}return W+" ]"}function XW(N,H,O,W){if(O===0)throw Error("Could not stringify the object: maximum object depth exceeded");let Y="";for(let G=0;G<N.length;G++)Y+=`${Y&&`
240
+ */var X0=/^[a-z0-9-_]+$/i;function TN(N){let H=typeof N;if(H==="object"){if(Array.isArray(N))return"array";if(N instanceof Date)return"date"}return H}function LO(N){for(let H=0;H<N.length;H++)if(TN(N[H])!=="object")return!1;return N.length!=0}function DH(N){return JSON.stringify(N).replace(/\x7f/g,"\\u007f")}function CH(N,H,W,O){if(W===0)throw Error("Could not stringify the object: maximum object depth exceeded");if(H==="number"){if(isNaN(N))return"nan";if(N===1/0)return"inf";if(N===-1/0)return"-inf";if(O&&Number.isInteger(N))return N.toFixed(1);return N.toString()}if(H==="bigint"||H==="boolean")return N.toString();if(H==="string")return DH(N);if(H==="date"){if(isNaN(N.getTime()))throw TypeError("cannot serialize invalid date");return N.toISOString()}if(H==="object")return zO(N,W,O);if(H==="array")return FO(N,W,O)}function zO(N,H,W){let O=Object.keys(N);if(O.length===0)return"{}";let Y="{ ";for(let G=0;G<O.length;G++){let $=O[G];if(G)Y+=", ";Y+=X0.test($)?$:DH($),Y+=" = ",Y+=CH(N[$],TN(N[$]),H-1,W)}return Y+" }"}function FO(N,H,W){if(N.length===0)return"[]";let O="[ ";for(let Y=0;Y<N.length;Y++){if(Y)O+=", ";if(N[Y]===null||N[Y]===void 0)throw TypeError("arrays cannot contain null or undefined values");O+=CH(N[Y],TN(N[Y]),H-1,W)}return O+" ]"}function VO(N,H,W,O){if(W===0)throw Error("Could not stringify the object: maximum object depth exceeded");let Y="";for(let G=0;G<N.length;G++)Y+=`${Y&&`
241
241
  `}[[${H}]]
242
- `,Y+=SH(0,N[G],H,O,W);return Y}function SH(N,H,O,W,Y){if(W===0)throw Error("Could not stringify the object: maximum object depth exceeded");let G="",$="",U=Object.keys(H);for(let Q=0;Q<U.length;Q++){let X=U[Q];if(H[X]!==null&&H[X]!==void 0){let F=TN(H[X]);if(F==="symbol"||F==="function")throw TypeError(`cannot serialize values of type '${F}'`);let K=$0.test(X)?X:DH(X);if(F==="array"&&$W(H[X]))$+=($&&`
243
- `)+XW(H[X],O?`${O}.${K}`:K,W-1,Y);else if(F==="object"){let R=O?`${O}.${K}`:K;$+=($&&`
244
- `)+SH(R,H[X],R,W-1,Y)}else G+=K,G+=" = ",G+=CH(H[X],F,W,Y),G+=`
242
+ `,Y+=SH(0,N[G],H,W,O);return Y}function SH(N,H,W,O,Y){if(O===0)throw Error("Could not stringify the object: maximum object depth exceeded");let G="",$="",U=Object.keys(H);for(let Q=0;Q<U.length;Q++){let X=U[Q];if(H[X]!==null&&H[X]!==void 0){let z=TN(H[X]);if(z==="symbol"||z==="function")throw TypeError(`cannot serialize values of type '${z}'`);let K=X0.test(X)?X:DH(X);if(z==="array"&&LO(H[X]))$+=($&&`
243
+ `)+VO(H[X],W?`${W}.${K}`:K,O-1,Y);else if(z==="object"){let R=W?`${W}.${K}`:K;$+=($&&`
244
+ `)+SH(R,H[X],R,O-1,Y)}else G+=K,G+=" = ",G+=CH(H[X],z,O,Y),G+=`
245
245
  `}}if(N&&(G||!$))G=G?`[${N}]
246
246
  ${G}`:`[${N}]`;return G&&$?`${G}
247
- ${$}`:G||$}function d(N,{maxDepth:H=1000,numbersAsFloat:O=!1}={}){if(TN(N)!=="object")throw TypeError("stringify can only be called with an object");let W=SH(0,N,"",H,O);if(W[W.length-1]!==`
248
- `)return W+`
249
- `;return W}/*!
247
+ ${$}`:G||$}function d(N,{maxDepth:H=1000,numbersAsFloat:W=!1}={}){if(TN(N)!=="object")throw TypeError("stringify can only be called with an object");let O=SH(0,N,"",H,W);if(O[O.length-1]!==`
248
+ `)return O+`
249
+ `;return O}/*!
250
250
  * Copyright (c) Squirrel Chat et al., All rights reserved.
251
251
  * SPDX-License-Identifier: BSD-3-Clause
252
252
  *
@@ -272,13 +272,13 @@ ${$}`:G||$}function d(N,{maxDepth:H=1000,numbersAsFloat:O=!1}={}){if(TN(N)!=="ob
272
272
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
273
273
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
274
274
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275
- */function L(N,H=200){return new Response(JSON.stringify(N),{status:H,headers:{"content-type":"application/json"}})}function Z(N,H,O){return L({error:H,detail:O},N)}async function M(N){try{return await N.json()}catch{throw new B("Invalid JSON body")}}function A(N,H){if(typeof N!=="string"||N.length===0)throw new B(`Missing or invalid field: ${H}`);return N}class B extends Error{constructor(N){super(N);this.name="BadRequestError"}}import{promises as j}from"fs";import I from"path";import RH from"path";function e(N,H){let O=RH.resolve(N),W=RH.resolve(O,H||".");if(W!==O&&!W.startsWith(O+RH.sep))throw new oN(H);return W}class oN extends Error{constructor(N){super(`Path escapes workspace: ${N}`);this.name="PathEscapeError"}}var ZW=2097152,LW=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".bmp",".ico",".avif"]),FW=new Set([".zip",".tar",".gz",".7z",".exe",".dll",".so",".dylib",".pdf",".woff",".woff2",".ttf",".mp3",".mp4",".mov",".webm",".sqlite",".db",".bin"]);function zW(N){let H=I.extname(N).toLowerCase();if(H===".md"||H===".markdown")return"markdown";if(H===".json"||H===".jsonl")return"json";if(LW.has(H))return"image";if(FW.has(H))return"binary";return"text"}function s(N,H){return e(J(H),N)}function TH(N,H){let O=I.relative(J(H),N);return O===""?".":l(O)}async function U0(N,H){let O=await j.stat(N),W={name:I.basename(N)||".",path:TH(N,H),type:O.isDirectory()?"dir":"file",modifiedAt:O.mtime.toISOString()};if(W.type==="file")return W.size=O.size,W;let Y=await j.readdir(N,{withFileTypes:!0}),G=await Promise.all(Y.map(($)=>U0(I.join(N,$.name),H)));return G.sort(($,U)=>$.type!==U.type?$.type==="dir"?-1:1:$.name.localeCompare(U.name)),W.children=G,W}async function Q0(N=".",H=z){return U0(s(N,H),H)}async function X0(N,H=z){let O=s(N,H),W=await j.stat(O);if(W.isDirectory())throw Error(`Not a file: ${N}`);let Y=zW(O),G={path:TH(O,H),kind:Y,size:W.size,modifiedAt:W.mtime.toISOString()};if(Y==="image"||Y==="binary")return G;if(W.size>ZW)throw Error(`File too large to open (${W.size} bytes): ${N}`);return G.content=await j.readFile(O,"utf8"),G}async function Z0(N,H,O=z){let W=s(N,O);await j.mkdir(I.dirname(W),{recursive:!0}),await j.writeFile(W,H,"utf8")}async function L0(N,H=z){await j.mkdir(s(N,H),{recursive:!0})}async function F0(N,H=z){let O=s(N,H);if(O===I.resolve(J(H)))throw Error("Cannot delete the workspace root");await j.rm(O,{recursive:!0,force:!0})}async function z0(N,H,O=z){let W=s(N,O),Y=s(H,O);if(W===I.resolve(J(O)))throw Error("Cannot rename the workspace root");await j.mkdir(I.dirname(Y),{recursive:!0}),await j.rename(W,Y)}async function V0(N,H,O,W=z){let Y=I.basename(H);if(!Y||Y==="."||Y==="..")throw Error(`Invalid file name: ${H}`);let G=e(J(W),I.join(N||".",Y));return await j.mkdir(I.dirname(G),{recursive:!0}),await Bun.write(G,O),TH(G,W)}function dN(N,H=z){return s(N,H)}import{randomBytes as VW}from"crypto";function sN(N){return`${N}_${VW(6).toString("hex")}`}var EH=null;function K0(N){EH=N}function i(N,H){EH?.publish(N,JSON.stringify(H))}function A0(N,H){EH?.publish(N,H)}import{promises as EN}from"fs";import MW from"os";import _H from"path";var t=new Map,J0=!1;function wH(N){return _H.join(n(),N,"meta.json")}var B0=_H.join(MW.homedir(),".agenthost");function D0(N){let H=JSON.parse(N);if(H.cwd?.startsWith(B0))H.cwd=b+H.cwd.slice(B0.length);return H}async function C0(N){await EN.mkdir(_H.join(n(),N.id),{recursive:!0}),await EN.writeFile(wH(N.id),JSON.stringify(N,null,2)+`
276
- `,"utf8")}async function KW(){if(J0)return;J0=!0;let N;try{N=await EN.readdir(n())}catch{return}for(let H of N){if(t.has(H))continue;try{let O=await EN.readFile(wH(H),"utf8"),W=D0(O);t.set(W.id,W)}catch{}}}async function S0(N){let H={id:sN("run"),projectId:N.projectId??z,prompt:N.prompt,status:"starting",startedAt:new Date().toISOString(),cwd:N.cwd,sandbox:N.sandbox,approvalPolicy:N.approvalPolicy,approvalsReviewer:N.approvalsReviewer,model:N.model,effort:N.effort,source:N.source,scheduleId:N.scheduleId,scheduleName:N.scheduleName};return t.set(H.id,H),await C0(H),H}async function NN(N,H){let O=await D(N);if(!O)return null;let W={...O,...H};return t.set(N,W),await C0(W),W}async function D(N){if(t.has(N))return t.get(N);try{let H=await EN.readFile(wH(N),"utf8"),O=D0(H);return t.set(N,O),O}catch{return null}}async function R0(N){await KW();let H=[...t.values()];return(N?H.filter((W)=>W.projectId===N):H).sort((W,Y)=>Y.startedAt.localeCompare(W.startedAt))}function g(N){return N==="queued"||N==="starting"||N==="running"||N==="waiting_approval"}import{promises as T0}from"fs";import AW from"path";function E0(N){return AW.join(n(),N,"events.jsonl")}async function _0(N){await T0.appendFile(E0(N.runId),JSON.stringify(N)+`
277
- `,"utf8")}var JW=/"type":\s*"run\.(started|resumed|steered)"/,BW=400;async function w0(N,H={}){let O;try{O=await T0.readFile(E0(N),"utf8")}catch{return{events:[],offset:0,total:0}}let W=O.split(`
278
- `);if(W.length>0&&W[W.length-1]==="")W.pop();let Y=W.length,G=Math.max(0,Math.min(H.before??Y,Y)),$=H.limit===void 0?0:Math.max(0,G-H.limit);if($>0){for(let Q=$;Q>=Math.max(0,$-BW);Q--)if(JW.test(W[Q])){$=Q;break}}let U=[];for(let Q=$;Q<G;Q++){let X=W[Q].trim();if(!X)continue;try{U.push(JSON.parse(X))}catch{}}return{events:U,offset:$,total:Y}}import{promises as O1}from"fs";import IW from"os";import W1 from"path";var f0={name:"junhost",version:"0.1.1",description:"Jun \u2014 a self-hosted dashboard that runs and supervises Codex as a 24/7 local/VPS agent: chat runs, workspace files, remote browser, skills, MCP, schedules.",type:"module",bin:{jun:"bin/jun.js"},files:["bin","dist","ui-dist","README.md"],engines:{bun:">=1.2.0"},keywords:["codex","agent","ai","dashboard","self-hosted","browser-automation","mcp"],license:"UNLICENSED",scripts:{dev:"bun --hot src/index.ts",start:"bun src/index.ts",build:"bun build src/index.ts src/mcp-server.ts --target=bun --minify --outdir=dist",typecheck:"bunx tsc --noEmit"},dependencies:{"agent-browser":"^0.27.1",cloakbrowser:"^0.3.31"},devDependencies:{"@junhost/shared":"workspace:*","@modelcontextprotocol/sdk":"^1.29.0","@types/bun":"^1.2.0","smol-toml":"^1.6.1",typescript:"^5.6.3",zod:"3"}};var tN=f0.version;import TW from"os";import w from"path";import{existsSync as PN,readdirSync as EW}from"fs";import{mkdir as v0}from"fs/promises";import{randomUUID as _W}from"crypto";import{readFileSync as CW}from"fs";import{promises as SW}from"fs";import RW from"path";var x0=["browserProxy","browserNoProxy"];function k0(){return RW.join(b,"config.json")}var rN=null;function eN(){if(rN)return rN;let N={};try{N=JSON.parse(CW(k0(),"utf8"))}catch{}let H={};for(let O of x0){let W=N[O];if(typeof W==="string"&&W.length>0)H[O]=W}return rN=H,H}async function y0(N){let H={...eN()};for(let O of x0){if(!(O in N))continue;let W=N[O];if(typeof W==="string"&&W.trim().length>0)H[O]=W.trim();else delete H[O]}return await SW.writeFile(k0(),JSON.stringify(H,null,2)+`
279
- `,"utf8"),rN=H,H}var wW="jun",b0=200,h0=process.platform==="win32"?"agent-browser.exe":"agent-browser";function m0(){let N=import.meta.dir;for(let H=0;H<8;H++){let O=w.join(N,"node_modules",".bin");if(PN(w.join(O,h0)))return O;let W=w.dirname(N);if(W===N)break;N=W}return null}function PW(N){let H=m0();if(H)return[w.join(H,h0),...N];return process.platform==="win32"?["cmd","/c","agent-browser",...N]:["agent-browser",...N]}var q0=Object.keys(process.env).find((N)=>N.toUpperCase()==="PATH")??"PATH",OH="agent",HH=null,NH=[];function c0(){let N=y("CLOAK_PATH");if(N&&PN(N))return N;let H=w.join(TW.homedir(),".cloakbrowser"),O;try{O=EW(H).filter((Y)=>Y.startsWith("chromium-"))}catch{return null}O.sort().reverse();let W=process.platform==="win32"?"chrome.exe":"chrome";for(let Y of O){let G=w.join(H,Y,W);if(PN(G))return G}return null}function fW(){let N=y("CHROME_PATH");if(N&&PN(N))return N;return(process.platform==="win32"?[`${process.env.ProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,`${process.env["ProgramFiles(x86)"]}\\Google\\Chrome\\Application\\chrome.exe`,`${process.env.LocalAppData}\\Google\\Chrome\\Application\\chrome.exe`]:process.platform==="darwin"?["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"]:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/opt/google/chrome/chrome"]).find((O)=>O&&PN(O))??null}function xH(){let N={AGENT_BROWSER_SESSION:wW,AGENT_BROWSER_PROFILE:w.join(CN(),"profile"),AGENT_BROWSER_DOWNLOAD_PATH:w.join(J(),"downloads"),AGENT_BROWSER_SCREENSHOT_DIR:w.join(J(),"screenshots"),AGENT_BROWSER_ARGS:"--disable-blink-features=AutomationControlled"},H=m0();if(H)N[q0]=`${H}${w.delimiter}${process.env[q0]??""}`;let O=c0();if(O)return N.AGENT_BROWSER_EXECUTABLE_PATH=O,N;let W=fW(),Y=process.platform!=="linux"||Boolean(process.env.DISPLAY),G=y("BROWSER_HEADED")!=="false"&&Y;if(process.platform==="linux"&&!process.env.DISPLAY&&y("BROWSER_HEADED")!=="false")console.warn("[browser] No cloakbrowser engine and no DISPLAY \u2014 running HEADLESS. Edge "+"WAFs (Reddit/Fastly) will block headless. Install cloakbrowser (works headless) or set up Xvfb + Google Chrome with DISPLAY for a VPS.");if(W&&G)N.AGENT_BROWSER_EXECUTABLE_PATH=W,N.AGENT_BROWSER_HEADED="true";else{if(W)N.AGENT_BROWSER_EXECUTABLE_PATH=W;N.AGENT_BROWSER_USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"}return N}function xW(){return{...process.env,...xH()}}function kW(){let N=kH().value;if(!N)return[];let H=["--proxy",N],O=yH().value;if(O)H.push("--proxy-bypass",O);return H}function kH(){let N=eN().browserProxy;if(N)return{value:N,source:"settings"};let H=y("BROWSER_PROXY")?.trim();if(H)return{value:H,source:"env"};return{value:null,source:"none"}}function yH(){let N=eN().browserNoProxy;if(N)return{value:N,source:"settings"};let H=y("BROWSER_NO_PROXY")?.trim();if(H)return{value:H,source:"env"};return{value:null,source:"none"}}var fH=!1;function l0(N){if(fH)return;if(y("NO_CLOAK_DOWNLOAD")==="true")return;if(c0())return;fH=!0,console.log("[browser] cloakbrowser Stealth Chromium not found \u2014 downloading in background\u2026"),Bun.spawn([process.execPath,"x","cloakbrowser","install"],{cwd:N,stdout:"inherit",stderr:"inherit"}).exited.then((O)=>{if(fH=!1,O===0)console.log("[browser] cloakbrowser Stealth Chromium ready.");else console.warn(`[browser] cloakbrowser download exited with code ${O}.`)})}async function I0(N,H,O){if(!N)return"";let W=N.getReader(),Y=new TextDecoder,G="",$=Date.now()+O;try{while(Date.now()<$){let U=Math.min(H,$-Date.now()),Q=await Promise.race([W.read(),new Promise((X)=>setTimeout(()=>X("timeout"),U))]);if(Q==="timeout"||Q.done)break;G+=Y.decode(Q.value,{stream:!0})}}finally{W.releaseLock()}return G}async function v(N,H={}){let O=[...kW(),...N],W=H.json?[...O,"--json"]:O,Y=Bun.spawn(PW(W),{env:xW(),stdout:"pipe",stderr:"pipe"}),G=setTimeout(()=>Y.kill(),H.timeoutMs??120000),$=await Y.exited;clearTimeout(G);let[U,Q]=await Promise.all([I0(Y.stdout,80,1500),I0(Y.stderr,60,300)]),X,F;if(H.json)try{let K=JSON.parse(U);if(X=K.data??K,K.success===!1)F=typeof K.error==="string"?K.error:"command failed"}catch{}return{ok:$===0&&!F,stdout:U,stderr:Q,data:X,error:F}}function XN(N,H){if(NH.unshift({id:_W(),ts:new Date().toISOString(),kind:N,detail:H}),NH.length>b0)NH.length=b0}function u0(){return NH}function i0(){return OH}function p0(N){OH=N,XN("control",N)}function n0(){return HH}var a0=(N)=>typeof N==="object"&&N!==null?N:{};function j0(N){if(typeof N==="string")return N;let H=a0(N);for(let O of["url","title","value","text","result"])if(typeof H[O]==="string")return H[O];return null}var yW=2500,wN=null,_N=null;function HN(){wN=null}async function fN(){if(wN&&Date.now()-wN.at<yW)return{...wN.status,controller:OH};if(_N)return _N;return _N=bW().then((N)=>{return wN={at:Date.now(),status:N},N}).finally(()=>{_N=null}),_N}async function bW(){let N=await v(["stream","status"],{json:!0,timeoutMs:30000}),H=a0(N.data),O=N.ok&&H.connected===!0,W=O&&H.enabled===!0;HH=W&&typeof H.port==="number"?H.port:null;let Y=null,G=null;if(O){let[$,U]=await Promise.all([v(["get","url"],{json:!0,timeoutMs:30000}),v(["get","title"],{json:!0,timeoutMs:30000})]);Y=$.ok?j0($.data):null,G=U.ok?j0(U.data):null}return{running:O,streaming:W,streamPort:HH,url:Y,title:G,controller:OH}}var g0={width:1280,height:720};async function bH(){await v(["set","viewport",String(g0.width),String(g0.height)],{timeoutMs:30000})}async function o0(){await Promise.all(["screenshots","downloads","reports"].map((N)=>v0(w.join(J(),N),{recursive:!0})))}async function d0(N){await o0(),await v0(w.join(CN(),"profile"),{recursive:!0});let H=await v(["open",N??"about:blank"],{timeoutMs:180000});if(!H.ok)throw Error(`agent-browser open failed: ${H.stderr||H.stdout}`);return await bH(),await v(["stream","enable"],{json:!0,timeoutMs:30000}),XN("start",N??"about:blank"),HN(),fN()}async function s0(){await v(["close"],{timeoutMs:30000}),HH=null,HN(),XN("stop")}async function t0(N){let H=await v(["open",N],{timeoutMs:120000});if(!H.ok)throw Error(`Navigation failed: ${H.stderr||H.stdout}`);await bH(),HN(),XN("navigate",N)}async function r0(N){let H=await v([N],{timeoutMs:60000});if(!H.ok)throw Error(`${N} failed: ${H.stderr||H.stdout}`);await bH(),HN(),XN(N)}async function e0(N){let H=await v(["press",N],{timeoutMs:30000});if(!H.ok)throw Error(`Key press failed: ${H.stderr||H.stdout}`);HN()}async function N1(){await o0();let N=`browser-${new Date().toISOString().replace(/[:.]/g,"-")}.png`,H=w.join(J(),"screenshots",N),O=await v(["screenshot",H],{timeoutMs:60000});if(!O.ok)throw Error(`Screenshot failed: ${O.stderr||O.stdout}`);return XN("screenshot",`screenshots/${N}`),`screenshots/${N}`}class qH{send;handlers;nextId=1;pending=new Map;constructor(N,H){this.send=N;this.handlers=H}request(N,H){let O=this.nextId++,W=new Promise((Y,G)=>{this.pending.set(O,{method:N,resolve:Y,reject:G})});return this.send(JSON.stringify({jsonrpc:"2.0",id:O,method:N,params:H})),W}notify(N,H){this.send(JSON.stringify({jsonrpc:"2.0",method:N,params:H}))}respond(N,H){this.send(JSON.stringify({jsonrpc:"2.0",id:N,result:H}))}respondError(N,H,O){this.send(JSON.stringify({jsonrpc:"2.0",id:N,error:{code:H,message:O}}))}handleLine(N){let H;try{H=JSON.parse(N)}catch{console.warn("[codex] non-JSON line on stdout:",N.slice(0,200));return}if(H.method!==void 0){if(H.id!==void 0)this.handlers.onServerRequest(H.id,H.method,H.params);else this.handlers.onNotification(H.method,H.params);return}if(H.id===void 0)return;let O=this.pending.get(Number(H.id));if(!O)return;if(this.pending.delete(Number(H.id)),H.error)O.reject(Error(`${O.method} failed: ${H.error.message} (${H.error.code})`));else O.resolve(H.result)}failAll(N){for(let H of this.pending.values())H.reject(Error(`${H.method} failed: ${N}`));this.pending.clear()}}function H1(N){let H="",O=new TextDecoder;return{push(W){H+=O.decode(W,{stream:!0});let Y;while((Y=H.indexOf(`
280
- `))!==-1){let G=H.slice(0,Y).replace(/\r$/,"");if(H=H.slice(Y+1),G.trim().length>0)N(G)}},flush(){let W=H.trim();if(H="",W.length>0)N(W)}}}class IH{handlers;proc=null;rpc=null;initialized=!1;constructor(N){this.handlers=N}get running(){return this.proc!==null}async start(){if(this.proc)return;await jW();let N=Bun.which("codex");if(!N)throw Error("codex binary not found in PATH. Install Codex CLI first.");let H=/\.(cmd|bat)$/i.test(N)?["cmd","/c",N,"app-server"]:[N,"app-server"],O=Bun.spawn(H,{cwd:J(),env:{...process.env,CODEX_HOME:q(),...xH()},stdin:"pipe",stdout:"pipe",stderr:"pipe",onExit:(Y,G)=>{console.log(`[codex] app-server exited (code ${G})`),this.rpc?.failAll(`codex app-server exited (code ${G})`),this.proc=null,this.rpc=null,this.initialized=!1,this.handlers.onExit(G)}});this.proc=O,this.rpc=new qH((Y)=>{O.stdin.write(Y+`
281
- `),O.stdin.flush()},{onNotification:(Y,G)=>this.handlers.onNotification(Y,G),onServerRequest:(Y,G,$)=>this.handlers.onServerRequest(Y,G,$)});let W=this.rpc;(async()=>{let Y=H1((G)=>W.handleLine(G));for await(let G of O.stdout)Y.push(G);Y.flush()})(),(async()=>{let Y=new TextDecoder;for await(let G of O.stderr){let $=Y.decode(G).trimEnd();if($)console.error("[codex:stderr]",$)}})()}async initializeOnce(){if(this.initialized)return;await this.requireRpc().request("initialize",{clientInfo:{name:"jun",title:"Jun",version:tN},capabilities:{experimentalApi:!0}}),this.requireRpc().notify("initialized",{}),this.initialized=!0}request(N,H){return this.requireRpc().request(N,H)}respond(N,H){this.requireRpc().respond(N,H)}respondError(N,H,O){this.requireRpc().respondError(N,H,O)}requireRpc(){if(!this.rpc)throw Error("codex app-server is not running");return this.rpc}}async function jW(){let N=W1.join(q(),"auth.json");try{await O1.access(N);return}catch{}let H=W1.join(IW.homedir(),".codex","auth.json");try{await O1.copyFile(H,N),console.log("[codex] copied auth.json from ~/.codex into project codex-home")}catch{console.warn("[codex] no auth.json found in ~/.codex \u2014 runs may fail until `codex login` is run")}}var xN=null,WH=null;function YH(){return xN}function Y1(){return WH}function G1(N){if(xN=N,N)WH=null}function GH(){xN=null,WH=null}function $1(N){let H=N??{};if(WH={success:H.success===!0,error:H.error??null,at:new Date().toISOString()},!H.loginId||xN?.loginId===H.loginId)xN=null}var gW={"thread/started":"codex.thread.started","turn/started":"codex.turn.started","turn/completed":"codex.turn.completed","item/started":"codex.item.started","item/completed":"codex.item.completed","item/agentMessage/delta":"codex.message.delta","item/reasoning/textDelta":"codex.reasoning.delta","item/reasoning/summaryTextDelta":"codex.reasoning.summary.delta","item/commandExecution/outputDelta":"codex.command.output","item/fileChange/patchUpdated":"codex.file_change.patch",error:"codex.error"},vW={"item/commandExecution/requestApproval":"codex.approval.command","item/fileChange/requestApproval":"codex.approval.file_change","item/permissions/requestApproval":"codex.approval.permissions","item/tool/requestUserInput":"codex.approval.user_input","mcpServer/elicitation/request":"codex.approval.elicitation"};function U1(N){return gW[N]??`codex.${N.split("/").join(".")}`}function Q1(N){return vW[N]??null}function X1(N){return N==="item/commandExecution/requestApproval"||N==="item/fileChange/requestApproval"||N==="item/permissions/requestApproval"}function kN(N){if(typeof N!=="object"||N===null)return null;let H=N;if(typeof H.threadId==="string")return H.threadId;let O=H.thread;if(typeof O==="object"&&O!==null){let W=O.id;if(typeof W==="string")return W}return null}var Z1={readOnly:"read-only",workspaceWrite:"workspace-write",dangerFullAccess:"danger-full-access"},L1={readOnly:{type:"readOnly"},workspaceWrite:{type:"workspaceWrite"},dangerFullAccess:{type:"dangerFullAccess"}},jH={never:"never",onRequest:"on-request",onFailure:"on-failure",untrusted:"untrusted"},$H=`# Who you are
275
+ */function L(N,H=200){return new Response(JSON.stringify(N),{status:H,headers:{"content-type":"application/json"}})}function Z(N,H,W){return L({error:H,detail:W},N)}async function M(N){try{return await N.json()}catch{throw new B("Invalid JSON body")}}function J(N,H){if(typeof N!=="string"||N.length===0)throw new B(`Missing or invalid field: ${H}`);return N}class B extends Error{constructor(N){super(N);this.name="BadRequestError"}}import{promises as j}from"fs";import I from"path";import RH from"path";function e(N,H){let W=RH.resolve(N),O=RH.resolve(W,H||".");if(O!==W&&!O.startsWith(W+RH.sep))throw new dN(H);return O}class dN extends Error{constructor(N){super(`Path escapes workspace: ${N}`);this.name="PathEscapeError"}}var MO=2097152,KO=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".bmp",".ico",".avif"]),JO=new Set([".zip",".tar",".gz",".7z",".exe",".dll",".so",".dylib",".pdf",".woff",".woff2",".ttf",".mp3",".mp4",".mov",".webm",".sqlite",".db",".bin"]);function AO(N){let H=I.extname(N).toLowerCase();if(H===".md"||H===".markdown")return"markdown";if(H===".json"||H===".jsonl")return"json";if(KO.has(H))return"image";if(JO.has(H))return"binary";return"text"}function s(N,H){return e(A(H),N)}function EH(N,H){let W=I.relative(A(H),N);return W===""?".":l(W)}async function Z0(N,H){let W=await j.stat(N),O={name:I.basename(N)||".",path:EH(N,H),type:W.isDirectory()?"dir":"file",modifiedAt:W.mtime.toISOString()};if(O.type==="file")return O.size=W.size,O;let Y=await j.readdir(N,{withFileTypes:!0}),G=await Promise.all(Y.map(($)=>Z0(I.join(N,$.name),H)));return G.sort(($,U)=>$.type!==U.type?$.type==="dir"?-1:1:$.name.localeCompare(U.name)),O.children=G,O}async function L0(N=".",H=F){return Z0(s(N,H),H)}async function z0(N,H=F){let W=s(N,H),O=await j.stat(W);if(O.isDirectory())throw Error(`Not a file: ${N}`);let Y=AO(W),G={path:EH(W,H),kind:Y,size:O.size,modifiedAt:O.mtime.toISOString()};if(Y==="image"||Y==="binary")return G;if(O.size>MO)throw Error(`File too large to open (${O.size} bytes): ${N}`);return G.content=await j.readFile(W,"utf8"),G}async function F0(N,H,W=F){let O=s(N,W);await j.mkdir(I.dirname(O),{recursive:!0}),await j.writeFile(O,H,"utf8")}async function V0(N,H=F){await j.mkdir(s(N,H),{recursive:!0})}async function M0(N,H=F){let W=s(N,H);if(W===I.resolve(A(H)))throw Error("Cannot delete the workspace root");await j.rm(W,{recursive:!0,force:!0})}async function K0(N,H,W=F){let O=s(N,W),Y=s(H,W);if(O===I.resolve(A(W)))throw Error("Cannot rename the workspace root");await j.mkdir(I.dirname(Y),{recursive:!0}),await j.rename(O,Y)}async function J0(N,H,W,O=F){let Y=I.basename(H);if(!Y||Y==="."||Y==="..")throw Error(`Invalid file name: ${H}`);let G=e(A(O),I.join(N||".",Y));return await j.mkdir(I.dirname(G),{recursive:!0}),await Bun.write(G,W),EH(G,O)}function sN(N,H=F){return s(N,H)}import{randomBytes as BO}from"crypto";function tN(N){return`${N}_${BO(6).toString("hex")}`}var TH=null;function B0(N){TH=N}function i(N,H){TH?.publish(N,JSON.stringify(H))}function D0(N,H){TH?.publish(N,H)}import{promises as _N}from"fs";import DO from"os";import _H from"path";var t=new Map,C0=!1;function wH(N){return _H.join(n(),N,"meta.json")}var S0=_H.join(DO.homedir(),".agenthost");function R0(N){let H=JSON.parse(N);if(H.cwd?.startsWith(S0))H.cwd=b+H.cwd.slice(S0.length);return H}async function E0(N){await _N.mkdir(_H.join(n(),N.id),{recursive:!0}),await _N.writeFile(wH(N.id),JSON.stringify(N,null,2)+`
276
+ `,"utf8")}async function CO(){if(C0)return;C0=!0;let N;try{N=await _N.readdir(n())}catch{return}for(let H of N){if(t.has(H))continue;try{let W=await _N.readFile(wH(H),"utf8"),O=R0(W);t.set(O.id,O)}catch{}}}async function T0(N){let H={id:tN("run"),projectId:N.projectId??F,prompt:N.prompt,status:"starting",startedAt:new Date().toISOString(),cwd:N.cwd,sandbox:N.sandbox,approvalPolicy:N.approvalPolicy,approvalsReviewer:N.approvalsReviewer,model:N.model,effort:N.effort,source:N.source,scheduleId:N.scheduleId,scheduleName:N.scheduleName};return t.set(H.id,H),await E0(H),H}async function NN(N,H){let W=await D(N);if(!W)return null;let O={...W,...H};return t.set(N,O),await E0(O),O}async function D(N){if(t.has(N))return t.get(N);try{let H=await _N.readFile(wH(N),"utf8"),W=R0(H);return t.set(N,W),W}catch{return null}}async function _0(N){await CO();let H=[...t.values()];return(N?H.filter((O)=>O.projectId===N):H).sort((O,Y)=>Y.startedAt.localeCompare(O.startedAt))}function g(N){return N==="queued"||N==="starting"||N==="running"||N==="waiting_approval"}import{promises as w0}from"fs";import SO from"path";function P0(N){return SO.join(n(),N,"events.jsonl")}async function f0(N){await w0.appendFile(P0(N.runId),JSON.stringify(N)+`
277
+ `,"utf8")}var RO=/"type":\s*"run\.(started|resumed|steered)"/,EO=400;async function x0(N,H={}){let W;try{W=await w0.readFile(P0(N),"utf8")}catch{return{events:[],offset:0,total:0}}let O=W.split(`
278
+ `);if(O.length>0&&O[O.length-1]==="")O.pop();let Y=O.length,G=Math.max(0,Math.min(H.before??Y,Y)),$=H.limit===void 0?0:Math.max(0,G-H.limit);if($>0){for(let Q=$;Q>=Math.max(0,$-EO);Q--)if(RO.test(O[Q])){$=Q;break}}let U=[];for(let Q=$;Q<G;Q++){let X=O[Q].trim();if(!X)continue;try{U.push(JSON.parse(X))}catch{}}return{events:U,offset:$,total:Y}}import{promises as G1}from"fs";import mO from"os";import $1 from"path";var y0={name:"junhost",version:"0.1.2",description:"Jun \u2014 a self-hosted dashboard that runs and supervises Codex as a 24/7 local/VPS agent: chat runs, workspace files, remote browser, skills, MCP, schedules.",type:"module",bin:{jun:"bin/jun.js"},files:["bin","dist","ui-dist","README.md"],engines:{bun:">=1.2.0"},keywords:["codex","agent","ai","dashboard","self-hosted","browser-automation","mcp"],license:"UNLICENSED",scripts:{dev:"bun --hot src/index.ts",start:"bun src/index.ts",build:"bun build src/index.ts src/mcp-server.ts --target=bun --minify --outdir=dist",typecheck:"bunx tsc --noEmit"},dependencies:{"agent-browser":"^0.27.1",cloakbrowser:"^0.3.31"},devDependencies:{"@junhost/shared":"workspace:*","@modelcontextprotocol/sdk":"^1.29.0","@types/bun":"^1.2.0","smol-toml":"^1.6.1",typescript:"^5.6.3",zod:"3"}};var XN=y0.version;import fO from"os";import w from"path";import{existsSync as fN,readdirSync as xO}from"fs";import{mkdir as c0}from"fs/promises";import{randomUUID as kO}from"crypto";import{readFileSync as _O}from"fs";import{promises as wO}from"fs";import PO from"path";var b0=["browserProxy","browserNoProxy"];function q0(){return PO.join(b,"config.json")}var rN=null;function eN(){if(rN)return rN;let N={};try{N=JSON.parse(_O(q0(),"utf8"))}catch{}let H={};for(let W of b0){let O=N[W];if(typeof O==="string"&&O.length>0)H[W]=O}return rN=H,H}async function I0(N){let H={...eN()};for(let W of b0){if(!(W in N))continue;let O=N[W];if(typeof O==="string"&&O.trim().length>0)H[W]=O.trim();else delete H[W]}return await wO.writeFile(q0(),JSON.stringify(H,null,2)+`
279
+ `,"utf8"),rN=H,H}var yO="jun",j0=200,l0=process.platform==="win32"?"agent-browser.exe":"agent-browser";function u0(){let N=import.meta.dir;for(let H=0;H<8;H++){let W=w.join(N,"node_modules",".bin");if(fN(w.join(W,l0)))return W;let O=w.dirname(N);if(O===N)break;N=O}return null}function bO(N){let H=u0();if(H)return[w.join(H,l0),...N];return process.platform==="win32"?["cmd","/c","agent-browser",...N]:["agent-browser",...N]}var g0=Object.keys(process.env).find((N)=>N.toUpperCase()==="PATH")??"PATH",WH="agent",HH=null,NH=[];function i0(){let N=y("CLOAK_PATH");if(N&&fN(N))return N;let H=w.join(fO.homedir(),".cloakbrowser"),W;try{W=xO(H).filter((Y)=>Y.startsWith("chromium-"))}catch{return null}W.sort().reverse();let O=process.platform==="win32"?"chrome.exe":"chrome";for(let Y of W){let G=w.join(H,Y,O);if(fN(G))return G}return null}function qO(){let N=y("CHROME_PATH");if(N&&fN(N))return N;return(process.platform==="win32"?[`${process.env.ProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,`${process.env["ProgramFiles(x86)"]}\\Google\\Chrome\\Application\\chrome.exe`,`${process.env.LocalAppData}\\Google\\Chrome\\Application\\chrome.exe`]:process.platform==="darwin"?["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"]:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/opt/google/chrome/chrome"]).find((W)=>W&&fN(W))??null}function xH(){let N={AGENT_BROWSER_SESSION:yO,AGENT_BROWSER_PROFILE:w.join(SN(),"profile"),AGENT_BROWSER_DOWNLOAD_PATH:w.join(A(),"downloads"),AGENT_BROWSER_SCREENSHOT_DIR:w.join(A(),"screenshots"),AGENT_BROWSER_ARGS:"--disable-blink-features=AutomationControlled"},H=u0();if(H)N[g0]=`${H}${w.delimiter}${process.env[g0]??""}`;let W=i0();if(W)return N.AGENT_BROWSER_EXECUTABLE_PATH=W,N;let O=qO(),Y=process.platform!=="linux"||Boolean(process.env.DISPLAY),G=y("BROWSER_HEADED")!=="false"&&Y;if(process.platform==="linux"&&!process.env.DISPLAY&&y("BROWSER_HEADED")!=="false")console.warn("[browser] No cloakbrowser engine and no DISPLAY \u2014 running HEADLESS. Edge "+"WAFs (Reddit/Fastly) will block headless. Install cloakbrowser (works headless) or set up Xvfb + Google Chrome with DISPLAY for a VPS.");if(O&&G)N.AGENT_BROWSER_EXECUTABLE_PATH=O,N.AGENT_BROWSER_HEADED="true";else{if(O)N.AGENT_BROWSER_EXECUTABLE_PATH=O;N.AGENT_BROWSER_USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"}return N}function IO(){return{...process.env,...xH()}}function jO(){let N=kH().value;if(!N)return[];let H=["--proxy",N],W=yH().value;if(W)H.push("--proxy-bypass",W);return H}function kH(){let N=eN().browserProxy;if(N)return{value:N,source:"settings"};let H=y("BROWSER_PROXY")?.trim();if(H)return{value:H,source:"env"};return{value:null,source:"none"}}function yH(){let N=eN().browserNoProxy;if(N)return{value:N,source:"settings"};let H=y("BROWSER_NO_PROXY")?.trim();if(H)return{value:H,source:"env"};return{value:null,source:"none"}}var fH=!1;function p0(N){if(fH)return;if(y("NO_CLOAK_DOWNLOAD")==="true")return;if(i0())return;fH=!0,console.log("[browser] cloakbrowser Stealth Chromium not found \u2014 downloading in background\u2026"),Bun.spawn([process.execPath,"x","cloakbrowser","install"],{cwd:N,stdout:"inherit",stderr:"inherit"}).exited.then((W)=>{if(fH=!1,W===0)console.log("[browser] cloakbrowser Stealth Chromium ready.");else console.warn(`[browser] cloakbrowser download exited with code ${W}.`)})}async function v0(N,H,W){if(!N)return"";let O=N.getReader(),Y=new TextDecoder,G="",$=Date.now()+W;try{while(Date.now()<$){let U=Math.min(H,$-Date.now()),Q=await Promise.race([O.read(),new Promise((X)=>setTimeout(()=>X("timeout"),U))]);if(Q==="timeout"||Q.done)break;G+=Y.decode(Q.value,{stream:!0})}}finally{O.releaseLock()}return G}async function v(N,H={}){let W=[...jO(),...N],O=H.json?[...W,"--json"]:W,Y=Bun.spawn(bO(O),{env:IO(),stdout:"pipe",stderr:"pipe"}),G=setTimeout(()=>Y.kill(),H.timeoutMs??120000),$=await Y.exited;clearTimeout(G);let[U,Q]=await Promise.all([v0(Y.stdout,80,1500),v0(Y.stderr,60,300)]),X,z;if(H.json)try{let K=JSON.parse(U);if(X=K.data??K,K.success===!1)z=typeof K.error==="string"?K.error:"command failed"}catch{}return{ok:$===0&&!z,stdout:U,stderr:Q,data:X,error:z}}function ZN(N,H){if(NH.unshift({id:kO(),ts:new Date().toISOString(),kind:N,detail:H}),NH.length>j0)NH.length=j0}function n0(){return NH}function a0(){return WH}function o0(N){WH=N,ZN("control",N)}function d0(){return HH}var s0=(N)=>typeof N==="object"&&N!==null?N:{};function h0(N){if(typeof N==="string")return N;let H=s0(N);for(let W of["url","title","value","text","result"])if(typeof H[W]==="string")return H[W];return null}var gO=2500,PN=null,wN=null;function HN(){PN=null}async function xN(){if(PN&&Date.now()-PN.at<gO)return{...PN.status,controller:WH};if(wN)return wN;return wN=vO().then((N)=>{return PN={at:Date.now(),status:N},N}).finally(()=>{wN=null}),wN}async function vO(){let N=await v(["stream","status"],{json:!0,timeoutMs:30000}),H=s0(N.data),W=N.ok&&H.connected===!0,O=W&&H.enabled===!0;HH=O&&typeof H.port==="number"?H.port:null;let Y=null,G=null;if(W){let[$,U]=await Promise.all([v(["get","url"],{json:!0,timeoutMs:30000}),v(["get","title"],{json:!0,timeoutMs:30000})]);Y=$.ok?h0($.data):null,G=U.ok?h0(U.data):null}return{running:W,streaming:O,streamPort:HH,url:Y,title:G,controller:WH}}var m0={width:1280,height:720};async function bH(){await v(["set","viewport",String(m0.width),String(m0.height)],{timeoutMs:30000})}async function t0(){await Promise.all(["screenshots","downloads","reports"].map((N)=>c0(w.join(A(),N),{recursive:!0})))}async function r0(N){await t0(),await c0(w.join(SN(),"profile"),{recursive:!0});let H=await v(["open",N??"about:blank"],{timeoutMs:180000});if(!H.ok)throw Error(`agent-browser open failed: ${H.stderr||H.stdout}`);return await bH(),await v(["stream","enable"],{json:!0,timeoutMs:30000}),ZN("start",N??"about:blank"),HN(),xN()}async function e0(){await v(["close"],{timeoutMs:30000}),HH=null,HN(),ZN("stop")}async function N1(N){let H=await v(["open",N],{timeoutMs:120000});if(!H.ok)throw Error(`Navigation failed: ${H.stderr||H.stdout}`);await bH(),HN(),ZN("navigate",N)}async function H1(N){let H=await v([N],{timeoutMs:60000});if(!H.ok)throw Error(`${N} failed: ${H.stderr||H.stdout}`);await bH(),HN(),ZN(N)}async function W1(N){let H=await v(["press",N],{timeoutMs:30000});if(!H.ok)throw Error(`Key press failed: ${H.stderr||H.stdout}`);HN()}async function O1(){await t0();let N=`browser-${new Date().toISOString().replace(/[:.]/g,"-")}.png`,H=w.join(A(),"screenshots",N),W=await v(["screenshot",H],{timeoutMs:60000});if(!W.ok)throw Error(`Screenshot failed: ${W.stderr||W.stdout}`);return ZN("screenshot",`screenshots/${N}`),`screenshots/${N}`}class qH{send;handlers;nextId=1;pending=new Map;constructor(N,H){this.send=N;this.handlers=H}request(N,H){let W=this.nextId++,O=new Promise((Y,G)=>{this.pending.set(W,{method:N,resolve:Y,reject:G})});return this.send(JSON.stringify({jsonrpc:"2.0",id:W,method:N,params:H})),O}notify(N,H){this.send(JSON.stringify({jsonrpc:"2.0",method:N,params:H}))}respond(N,H){this.send(JSON.stringify({jsonrpc:"2.0",id:N,result:H}))}respondError(N,H,W){this.send(JSON.stringify({jsonrpc:"2.0",id:N,error:{code:H,message:W}}))}handleLine(N){let H;try{H=JSON.parse(N)}catch{console.warn("[codex] non-JSON line on stdout:",N.slice(0,200));return}if(H.method!==void 0){if(H.id!==void 0)this.handlers.onServerRequest(H.id,H.method,H.params);else this.handlers.onNotification(H.method,H.params);return}if(H.id===void 0)return;let W=this.pending.get(Number(H.id));if(!W)return;if(this.pending.delete(Number(H.id)),H.error)W.reject(Error(`${W.method} failed: ${H.error.message} (${H.error.code})`));else W.resolve(H.result)}failAll(N){for(let H of this.pending.values())H.reject(Error(`${H.method} failed: ${N}`));this.pending.clear()}}function Y1(N){let H="",W=new TextDecoder;return{push(O){H+=W.decode(O,{stream:!0});let Y;while((Y=H.indexOf(`
280
+ `))!==-1){let G=H.slice(0,Y).replace(/\r$/,"");if(H=H.slice(Y+1),G.trim().length>0)N(G)}},flush(){let O=H.trim();if(H="",O.length>0)N(O)}}}class IH{handlers;proc=null;rpc=null;initialized=!1;constructor(N){this.handlers=N}get running(){return this.proc!==null}async start(){if(this.proc)return;await cO();let N=Bun.which("codex");if(!N)throw Error("codex binary not found in PATH. Install Codex CLI first.");let H=/\.(cmd|bat)$/i.test(N)?["cmd","/c",N,"app-server"]:[N,"app-server"],W=Bun.spawn(H,{cwd:A(),env:{...process.env,CODEX_HOME:q(),...xH()},stdin:"pipe",stdout:"pipe",stderr:"pipe",onExit:(Y,G)=>{console.log(`[codex] app-server exited (code ${G})`),this.rpc?.failAll(`codex app-server exited (code ${G})`),this.proc=null,this.rpc=null,this.initialized=!1,this.handlers.onExit(G)}});this.proc=W,this.rpc=new qH((Y)=>{W.stdin.write(Y+`
281
+ `),W.stdin.flush()},{onNotification:(Y,G)=>this.handlers.onNotification(Y,G),onServerRequest:(Y,G,$)=>this.handlers.onServerRequest(Y,G,$)});let O=this.rpc;(async()=>{let Y=Y1((G)=>O.handleLine(G));for await(let G of W.stdout)Y.push(G);Y.flush()})(),(async()=>{let Y=new TextDecoder;for await(let G of W.stderr){let $=Y.decode(G).trimEnd();if($)console.error("[codex:stderr]",$)}})()}async initializeOnce(){if(this.initialized)return;await this.requireRpc().request("initialize",{clientInfo:{name:"jun",title:"Jun",version:XN},capabilities:{experimentalApi:!0}}),this.requireRpc().notify("initialized",{}),this.initialized=!0}request(N,H){return this.requireRpc().request(N,H)}respond(N,H){this.requireRpc().respond(N,H)}respondError(N,H,W){this.requireRpc().respondError(N,H,W)}requireRpc(){if(!this.rpc)throw Error("codex app-server is not running");return this.rpc}}async function cO(){let N=$1.join(q(),"auth.json");try{await G1.access(N);return}catch{}let H=$1.join(mO.homedir(),".codex","auth.json");try{await G1.copyFile(H,N),console.log("[codex] copied auth.json from ~/.codex into project codex-home")}catch{console.warn("[codex] no auth.json found in ~/.codex \u2014 runs may fail until `codex login` is run")}}var kN=null,OH=null;function YH(){return kN}function U1(){return OH}function Q1(N){if(kN=N,N)OH=null}function GH(){kN=null,OH=null}function X1(N){let H=N??{};if(OH={success:H.success===!0,error:H.error??null,at:new Date().toISOString()},!H.loginId||kN?.loginId===H.loginId)kN=null}var lO={"thread/started":"codex.thread.started","turn/started":"codex.turn.started","turn/completed":"codex.turn.completed","item/started":"codex.item.started","item/completed":"codex.item.completed","item/agentMessage/delta":"codex.message.delta","item/reasoning/textDelta":"codex.reasoning.delta","item/reasoning/summaryTextDelta":"codex.reasoning.summary.delta","item/commandExecution/outputDelta":"codex.command.output","item/fileChange/patchUpdated":"codex.file_change.patch",error:"codex.error"},uO={"item/commandExecution/requestApproval":"codex.approval.command","item/fileChange/requestApproval":"codex.approval.file_change","item/permissions/requestApproval":"codex.approval.permissions","item/tool/requestUserInput":"codex.approval.user_input","mcpServer/elicitation/request":"codex.approval.elicitation"};function Z1(N){return lO[N]??`codex.${N.split("/").join(".")}`}function L1(N){return uO[N]??null}function z1(N){return N==="item/commandExecution/requestApproval"||N==="item/fileChange/requestApproval"||N==="item/permissions/requestApproval"}function yN(N){if(typeof N!=="object"||N===null)return null;let H=N;if(typeof H.threadId==="string")return H.threadId;let W=H.thread;if(typeof W==="object"&&W!==null){let O=W.id;if(typeof O==="string")return O}return null}var F1={readOnly:"read-only",workspaceWrite:"workspace-write",dangerFullAccess:"danger-full-access"},V1={readOnly:{type:"readOnly"},workspaceWrite:{type:"workspaceWrite"},dangerFullAccess:{type:"dangerFullAccess"}},jH={never:"never",onRequest:"on-request",onFailure:"on-failure",untrusted:"untrusted"},$H=`# Who you are
282
282
 
283
283
  You are Jun. That's your name, use it if anyone asks. You live inside JunHost,
284
284
  your own self-hosted dashboard that runs you as a long-running local/VPS assistant, and
@@ -319,20 +319,20 @@ model powers you; you're just Jun.
319
319
  - Report outcomes honestly. If something failed, say so plainly with the actual
320
320
  error; don't dress up a partial result as done.
321
321
  - Per-workspace guidance lives in each workspace's AGENTS.md and takes
322
- precedence over this general guidance when they differ.`,ON=new Map,WN=new Map,yN=new Map,F1=new Set,bN=new Map,ZN=new Map,gH="__default__";function hW(N){let H=N.error?.message;return typeof H==="string"&&H.includes("unsupported_parameter")&&H.includes("reasoning.summary")}async function z1(N,H,O){if(F1.has(H))O.summary="none";bN.set(N,O),await h().request("turn/start",O)}var IN=new Map,qN=null;function h(){if(!qN)qN=new IH({onNotification:mW,onServerRequest:cW,onExit:lW});return qN}async function T(N,H,O,W){let Y={id:sN("evt"),runId:N,ts:new Date().toISOString(),source:H,type:O,payload:W};return await _0(Y),i(`run:${N}`,Y),i("runs",{type:"run.event",runId:N,eventType:O}),Y}async function x(N,H){let O={status:H};if(H==="completed"||H==="failed"||H==="stopped")O.completedAt=new Date().toISOString();let W=await NN(N,O);if(W)i("runs",{type:"run.updated",run:W})}function mW(N,H){if(N==="account/login/completed"){$1(H);return}let O=kN(H),W=O?IN.get(O):void 0;if(W){if(N==="item/completed"){let G=H.item;if(G?.type==="agentMessage"&&typeof G.text==="string")W.text=G.text}else if(N==="turn/completed"||N==="error")W.done(W.text);return}let Y=O?ON.get(O):void 0;if(!Y)return;(async()=>{if(await T(Y,"codex",U1(N),H),N==="turn/started"){let G=H.turn?.id;if(typeof G==="string")yN.set(Y,G)}else if(N==="turn/completed"){let G=H.turn?.id;if(typeof G==="string"&&ZN.get(Y)===G){ZN.delete(Y);return}ZN.delete(Y),yN.delete(Y),bN.delete(Y);let $=await D(Y);if($&&g($.status))await x(Y,"completed");if(WN.delete(Y),$&&!$.title)iW(Y)}else if(N==="error"){let G=H.turnId;yN.delete(Y);let $=await D(Y),U=bN.get(Y);if($&&U&&U.summary&&U.summary!=="none"&&hW(H)){F1.add($.model??gH);let Q={...U,summary:"none"};console.warn(`[runs] ${$.model??"default model"} rejects reasoning.summary \u2014 retrying with summaries disabled`);try{if(typeof G==="string")ZN.set(Y,G);bN.set(Y,Q),await h().request("turn/start",Q);return}catch(X){ZN.delete(Y),console.warn(`[runs] summary-less retry failed for ${Y}:`,X)}}if($&&g($.status))await x(Y,"failed")}else if(N==="thread/name/updated"){let G=H.threadName;if(typeof G==="string"&&G.trim()){let $=await NN(Y,{title:G.trim()});if($)i("runs",{type:"run.updated",run:$})}}})()}function cW(N,H,O){let W=Q1(H),Y=kN(O),G=Y?ON.get(Y):void 0;if(!W||!G){if(console.warn(`[runs] auto-declining unroutable server request ${H} (id ${N})`),X1(H))h().respond(N,{decision:"decline"});else h().respondError(N,-32601,"Jun cannot handle this request yet");return}(async()=>{let $=WN.get(G)??[];$.push({requestId:N,method:H}),WN.set(G,$),await x(G,"waiting_approval"),await T(G,"codex",W,{requestId:N,method:H,params:O})})()}function lW(N){for(let O of IN.values())O.done(O.text);IN.clear();let H=[...ON.values()];ON.clear(),WN.clear(),yN.clear(),bN.clear(),ZN.clear();for(let O of H)(async()=>{let W=await D(O);if(!W||!g(W.status))return;await T(O,"daemon","run.failed",{reason:`codex app-server exited (code ${N})`}),await x(O,"failed")})()}function vH(N,H,O,W){let Y=(O??[]).filter((Q)=>Q.mediaType?.startsWith("image/")),G=(O??[]).filter((Q)=>!Q.mediaType?.startsWith("image/")),$=H;if(G.length>0)$+=`
322
+ precedence over this general guidance when they differ.`,WN=new Map,ON=new Map,bN=new Map,M1=new Set,qN=new Map,LN=new Map,gH="__default__";function iO(N){let H=N.error?.message;return typeof H==="string"&&H.includes("unsupported_parameter")&&H.includes("reasoning.summary")}async function K1(N,H,W){if(M1.has(H))W.summary="none";qN.set(N,W),await h().request("turn/start",W)}var jN=new Map,IN=null;function h(){if(!IN)IN=new IH({onNotification:pO,onServerRequest:nO,onExit:aO});return IN}async function E(N,H,W,O){let Y={id:tN("evt"),runId:N,ts:new Date().toISOString(),source:H,type:W,payload:O};return await f0(Y),i(`run:${N}`,Y),i("runs",{type:"run.event",runId:N,eventType:W}),Y}async function x(N,H){let W={status:H};if(H==="completed"||H==="failed"||H==="stopped")W.completedAt=new Date().toISOString();let O=await NN(N,W);if(O)i("runs",{type:"run.updated",run:O})}function pO(N,H){if(N==="account/login/completed"){X1(H);return}let W=yN(H),O=W?jN.get(W):void 0;if(O){if(N==="item/completed"){let G=H.item;if(G?.type==="agentMessage"&&typeof G.text==="string")O.text=G.text}else if(N==="turn/completed"||N==="error")O.done(O.text);return}let Y=W?WN.get(W):void 0;if(!Y)return;(async()=>{if(await E(Y,"codex",Z1(N),H),N==="turn/started"){let G=H.turn?.id;if(typeof G==="string")bN.set(Y,G)}else if(N==="turn/completed"){let G=H.turn?.id;if(typeof G==="string"&&LN.get(Y)===G){LN.delete(Y);return}LN.delete(Y),bN.delete(Y),qN.delete(Y);let $=await D(Y);if($&&g($.status))await x(Y,"completed");if(ON.delete(Y),$&&!$.title)dO(Y)}else if(N==="error"){let G=H.turnId;bN.delete(Y);let $=await D(Y),U=qN.get(Y);if($&&U&&U.summary&&U.summary!=="none"&&iO(H)){M1.add($.model??gH);let Q={...U,summary:"none"};console.warn(`[runs] ${$.model??"default model"} rejects reasoning.summary \u2014 retrying with summaries disabled`);try{if(typeof G==="string")LN.set(Y,G);qN.set(Y,Q),await h().request("turn/start",Q);return}catch(X){LN.delete(Y),console.warn(`[runs] summary-less retry failed for ${Y}:`,X)}}if($&&g($.status))await x(Y,"failed")}else if(N==="thread/name/updated"){let G=H.threadName;if(typeof G==="string"&&G.trim()){let $=await NN(Y,{title:G.trim()});if($)i("runs",{type:"run.updated",run:$})}}})()}function nO(N,H,W){let O=L1(H),Y=yN(W),G=Y?WN.get(Y):void 0;if(!O||!G){if(console.warn(`[runs] auto-declining unroutable server request ${H} (id ${N})`),z1(H))h().respond(N,{decision:"decline"});else h().respondError(N,-32601,"Jun cannot handle this request yet");return}(async()=>{let $=ON.get(G)??[];$.push({requestId:N,method:H}),ON.set(G,$),await x(G,"waiting_approval"),await E(G,"codex",O,{requestId:N,method:H,params:W})})()}function aO(N){for(let W of jN.values())W.done(W.text);jN.clear();let H=[...WN.values()];WN.clear(),ON.clear(),bN.clear(),qN.clear(),LN.clear();for(let W of H)(async()=>{let O=await D(W);if(!O||!g(O.status))return;await E(W,"daemon","run.failed",{reason:`codex app-server exited (code ${N})`}),await x(W,"failed")})()}function vH(N,H,W,O){let Y=(W??[]).filter((Q)=>Q.mediaType?.startsWith("image/")),G=(W??[]).filter((Q)=>!Q.mediaType?.startsWith("image/")),$=H;if(G.length>0)$+=`
323
323
 
324
324
  Attached workspace files:
325
325
  `+G.map((Q)=>`- ${Q.path}`).join(`
326
- `);let U=[{type:"text",text:$}];if(W)U.push({type:"skill",name:W.name,path:W.path});for(let Q of Y)U.push({type:"localImage",path:dN(Q.path,N)});return U}function uW(N){if(!N)return null;let H=N.split(`
327
- `)[0].replace(/^["'`#*\s]+|["'`*\s]+$/g,"").replace(/\s+/g," ").trim();if(!H)return null;return H.length>60?H.slice(0,57).trimEnd()+"\u2026":H}async function iW(N){let H=await D(N);if(!H||H.title||!H.codexThreadId)return;try{let O=h(),W=await O.request("thread/start",{cwd:H.cwd,ephemeral:!0,sandbox:"read-only",approvalPolicy:"never",serviceName:"jun"}),Y=kN(W);if(!Y)return;let G=await new Promise((Q)=>{let X=(K)=>{clearTimeout(F),IN.delete(Y),Q(K)},F=setTimeout(()=>X(null),30000);IN.set(Y,{text:null,done:X}),O.request("turn/start",{threadId:Y,input:[{type:"text",text:`Reply with ONLY a short title (3-6 words, no quotes, no punctuation at the end) summarizing this conversation opener:
326
+ `);let U=[{type:"text",text:$}];if(O)U.push({type:"skill",name:O.name,path:O.path});for(let Q of Y)U.push({type:"localImage",path:sN(Q.path,N)});return U}function oO(N){if(!N)return null;let H=N.split(`
327
+ `)[0].replace(/^["'`#*\s]+|["'`*\s]+$/g,"").replace(/\s+/g," ").trim();if(!H)return null;return H.length>60?H.slice(0,57).trimEnd()+"\u2026":H}async function dO(N){let H=await D(N);if(!H||H.title||!H.codexThreadId)return;try{let W=h(),O=await W.request("thread/start",{cwd:H.cwd,ephemeral:!0,sandbox:"read-only",approvalPolicy:"never",serviceName:"jun"}),Y=yN(O);if(!Y)return;let G=await new Promise((Q)=>{let X=(K)=>{clearTimeout(z),jN.delete(Y),Q(K)},z=setTimeout(()=>X(null),30000);jN.set(Y,{text:null,done:X}),W.request("turn/start",{threadId:Y,input:[{type:"text",text:`Reply with ONLY a short title (3-6 words, no quotes, no punctuation at the end) summarizing this conversation opener:
328
328
 
329
- `+H.prompt.slice(0,2000)}],effort:"low"}).catch(()=>X(null))}),$=uW(G);if(!$)return;await O.request("thread/name/set",{threadId:H.codexThreadId,name:$});let U=await NN(N,{title:$});if(U)i("runs",{type:"run.updated",run:U})}catch(O){console.warn(`[runs] title generation failed for ${N}:`,O)}}async function C(N,H){let O=h();return await O.start(),await O.initializeOnce(),O.request(N,H)}async function LN(N){let H=N.projectId??"default",O=N.cwd??J(H),W=await S0({prompt:N.prompt,cwd:O,projectId:H,sandbox:N.sandbox??"workspaceWrite",approvalPolicy:N.approvalPolicy??"onRequest",approvalsReviewer:N.approvalsReviewer??"user",model:N.model,effort:N.effort??"medium",source:N.source,scheduleId:N.scheduleId,scheduleName:N.scheduleName});return i("runs",{type:"run.updated",run:W}),await T(W.id,"daemon","run.started",{prompt:N.prompt,cwd:O,projectId:H,attachments:N.attachments??[]}),(async()=>{try{let Y=h();await Y.start(),await Y.initializeOnce();let G=await Y.request("thread/start",{cwd:O,model:N.model??null,sandbox:Z1[N.sandbox??"workspaceWrite"],approvalPolicy:jH[N.approvalPolicy??"onRequest"],...N.approvalsReviewer==="auto_review"?{approvalsReviewer:"auto_review"}:{},...$H?{developerInstructions:$H}:{},serviceName:"jun"}),$=kN(G)??(typeof G.threadId==="string"?G.threadId:null);if(!$)throw Error(`thread/start returned no thread id: ${JSON.stringify(G)}`);ON.set($,W.id),await NN(W.id,{codexThreadId:$}),await x(W.id,"running"),await z1(W.id,N.model??gH,{threadId:$,input:vH(H,N.prompt,N.attachments,N.skill),summary:"detailed",effort:N.effort??"medium",sandboxPolicy:L1[N.sandbox??"workspaceWrite"]})}catch(Y){let G=Y instanceof Error?Y.message:String(Y);await T(W.id,"daemon","run.failed",{reason:G}),await x(W.id,"failed")}})(),W}async function hH(N,H){let O=h();if(await O.start(),await O.initializeOnce(),ON.has(H))return{server:O,resumed:!1};let W=await D(N);return await O.request("thread/resume",{threadId:H,...W?.approvalPolicy?{approvalPolicy:jH[W.approvalPolicy]}:{},...W?.approvalsReviewer==="auto_review"?{approvalsReviewer:"auto_review"}:{},...W?.model?{model:W.model}:{},...W?.sandbox?{sandbox:Z1[W.sandbox]}:{},...$H?{developerInstructions:$H}:{}}),ON.set(H,N),{server:O,resumed:!0}}async function UH(N,H,O,W){let Y=await D(N);if(!Y)throw Error(`Run not found: ${N}`);if(g(Y.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let G=Y.codexThreadId;if(!G)throw Error("Run has no Codex thread to resume");let $={};if(W?.sandbox&&W.sandbox!==Y.sandbox)$.sandbox=W.sandbox;if(W?.approvalPolicy&&W.approvalPolicy!==Y.approvalPolicy)$.approvalPolicy=W.approvalPolicy;if(W?.approvalsReviewer&&W.approvalsReviewer!==Y.approvalsReviewer)$.approvalsReviewer=W.approvalsReviewer;if(W?.model&&W.model!==Y.model)$.model=W.model;if(W?.effort&&W.effort!==Y.effort)$.effort=W.effort;if(Object.keys($).length>0){let U=await NN(N,$);if(U)i("runs",{type:"run.updated",run:U})}return await T(N,"daemon","run.resumed",{prompt:H,attachments:O??[],...Object.keys($).length>0?{modeChanges:$}:{}}),await x(N,"running"),(async()=>{try{await hH(N,G);let U=$.sandbox??Y.sandbox??"workspaceWrite",Q=$.approvalPolicy??Y.approvalPolicy??"onRequest",X=$.approvalsReviewer??Y.approvalsReviewer,F=$.model??Y.model,K=(await D(N))?.serviceTier;await z1(N,F??gH,{threadId:G,input:vH(Y.projectId,H,O),summary:"detailed",effort:$.effort??Y.effort??"medium",sandboxPolicy:L1[U],approvalPolicy:jH[Q],...X==="auto_review"?{approvalsReviewer:X}:{},...F?{model:F}:{},...K?{serviceTier:K}:{}})}catch(U){let Q=U instanceof Error?U.message:String(U);await T(N,"daemon","run.failed",{reason:Q}),await x(N,"failed")}})(),await D(N)}async function V1(N,H,O){let W=await D(N);if(!W)throw Error(`Run not found: ${N}`);if(!g(W.status))throw Error("Run is not active \u2014 send a follow-up message instead");let Y=W.codexThreadId,G=yN.get(N);if(!Y||!G)throw Error("No active turn to steer");await T(N,"daemon","run.steered",{prompt:H,attachments:O??[]}),await h().request("turn/steer",{threadId:Y,expectedTurnId:G,input:vH(W.projectId,H,O)})}async function M1(N,H){let O=await D(N);if(!O)throw Error(`Run not found: ${N}`);if(H){let G=((await C("model/list",{})).data??[]).find(($)=>O.model?$.model===O.model:$.isDefault);if(!G?.serviceTiers?.some(($)=>$.id==="priority"))throw Error(`Model ${G?.model??O.model??"unknown"} does not support fast mode`)}let W=await NN(N,{serviceTier:H?"priority":"standard"});if(W)i("runs",{type:"run.updated",run:W});return await T(N,"daemon","run.fast",{enabled:H}),W}async function K1(N){let H=await D(N);if(!H)throw Error(`Run not found: ${N}`);if(g(H.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let O=H.codexThreadId;if(!O)throw Error("Run has no Codex thread");let{server:W}=await hH(N,O);await T(N,"daemon","run.compact.started",{}),await W.request("thread/compact/start",{threadId:O})}async function A1(N,H){let O=await D(N);if(!O)throw Error(`Run not found: ${N}`);if(g(O.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let W=O.codexThreadId;if(!W)throw Error("Run has no Codex thread");let{server:Y}=await hH(N,W),G=H?.trim();await T(N,"daemon","run.review.started",{instructions:G??null}),await x(N,"running");try{await Y.request("review/start",{threadId:W,target:G?{type:"custom",instructions:G}:{type:"uncommittedChanges"},delivery:"inline"})}catch($){let U=$ instanceof Error?$.message:String($);throw await T(N,"daemon","run.failed",{reason:U}),await x(N,"failed"),$}return await D(N)}async function J1(N){let H=await D(N);if(!H||!g(H.status))return!1;if(H.codexThreadId&&qN?.running)try{await qN.request("turn/interrupt",{threadId:H.codexThreadId})}catch(O){console.warn(`[runs] turn/interrupt failed for ${N}:`,O)}return WN.delete(N),await T(N,"daemon","run.stopped",{}),await x(N,"stopped"),!0}async function B1(N,H,O){let W=WN.get(N)??[],Y=W.findIndex(($)=>String($.requestId)===String(H));if(Y===-1)return!1;let[G]=W.splice(Y,1);if(W.length===0)WN.delete(N);if(G.method==="mcpServer/elicitation/request"){let $=O==="decline"||O==="cancel"?O:"accept";h().respond(G.requestId,{action:$})}else h().respond(G.requestId,{decision:O});if(await T(N,"daemon","approval.resolved",{requestId:G.requestId,decision:O}),W.length===0)await x(N,"running");return!0}function zN(){return pW.join(q(),"config.toml")}async function p(){try{return await FN.readFile(zN(),"utf8")}catch{return""}}async function C1(N){try{c(N)}catch(H){throw new B(`Invalid TOML: ${H instanceof Error?H.message:String(H)}`)}await FN.writeFile(zN(),N,"utf8")}function nW(N){if(!N.trim())return{};let O=c(N).mcp_servers;if(typeof O!=="object"||O===null)return{};return O}async function aW(){let N=new Map;try{let H=await C("mcpServerStatus/list",{detail:"full"});for(let O of H.data??[]){let W=Object.entries(O.tools??{}).map(([Y,G])=>({name:Y,description:G?.description}));N.set(O.name,{startupState:O.serverInfo?"ready":"starting",authStatus:O.authStatus??null,tools:W})}}catch(H){console.warn("[mcp] mcpServerStatus/list failed:",H)}return N}async function S1(){let N=await p(),H=nW(N),O=await aW();return{servers:Object.entries(H).map(([Y,G])=>{let $=O.get(Y);return{name:Y,command:G.command,args:G.args,envKeys:G.env?Object.keys(G.env):void 0,url:G.url,enabled:G.enabled!==!1,startupState:$?.startupState??null,authStatus:$?.authStatus??null,tools:$?.tools??[],error:$?.error}})}}var oW=/^[A-Za-z0-9_-]+$/;async function R1(N){if(!oW.test(N.name))throw new B(`Invalid server name "${N.name}" \u2014 letters, digits, _ and - only`);if(!N.command&&!N.url)throw new B("Server needs either a command or a url");let H=await p(),O=H.trim()?c(H):{},W=O.mcp_servers??{},Y={};if(N.command)Y.command=N.command;if(N.args&&N.args.length>0)Y.args=N.args;if(N.env&&Object.keys(N.env).length>0)Y.env=N.env;if(N.url)Y.url=N.url;if(N.enabled===!1)Y.enabled=!1;W[N.name]=Y,O.mcp_servers=W,await FN.writeFile(zN(),d(O),"utf8")}async function T1(N){let H=await p();if(!H.trim())return!1;let O=c(H),W=O.mcp_servers;if(!W||!(N in W))return!1;return delete W[N],await FN.writeFile(zN(),d(O),"utf8"),!0}async function E1(N,H){let O=await p(),W=c(O||""),Y=W.mcp_servers??{};if(!Y[N])throw new B(`Server not found: ${N}`);Y[N].enabled=H,W.mcp_servers=Y,await FN.writeFile(zN(),d(W),"utf8")}async function _1(){await C("config/mcpServer/reload",{})}async function w1(N,H){let O=await p(),W=O.trim()?c(O):{},Y=W.mcp_servers??{},G={command:process.execPath,args:[N],env:{JUN_PORT:String(H)}},$=Y.jun;if($&&!Y.agenthost&&$.command===G.command&&JSON.stringify($.args)===JSON.stringify(G.args)&&$.env?.JUN_PORT===String(H))return;delete Y.agenthost,Y.jun=G,W.mcp_servers=Y,await FN.writeFile(zN(),d(W),"utf8")}var sW=Date.now();function P1(){return L({ok:!0})}function f1(){let N={ok:!0,name:"jun",version:tN,projectId:z,dataRoot:b,workspaceRoot:J(),uptimeSeconds:Math.round((Date.now()-sW)/1000)};return L(N)}import tW from"path";var QH={ok:!0};async function x1(N,H){let O=H.pathname.slice(11),W=H.searchParams.get("path")??".",Y=H.searchParams.get("project")??z;switch(`${N.method} ${O}`){case"GET tree":return L(await Q0(W,Y));case"GET read":return L(await X0(W,Y));case"GET download":{let G=dN(W,Y),$=Bun.file(G);if(!await $.exists())return Z(404,`File not found: ${W}`);return new Response($,{headers:{"content-disposition":`attachment; filename="${encodeURIComponent(tW.basename(G))}"`}})}case"POST write":{let G=await M(N);return await Z0(A(G.path,"path"),typeof G.content==="string"?G.content:"",Y),L(QH)}case"POST mkdir":{let G=await M(N);return await L0(A(G.path,"path"),Y),L(QH)}case"POST delete":{let G=await M(N);return await F0(A(G.path,"path"),Y),L(QH)}case"POST rename":{let G=await M(N);return await z0(A(G.from,"from"),A(G.to,"to"),Y),L(QH)}case"POST upload":{let G;try{G=await N.formData()}catch{throw new B("Expected multipart/form-data body")}let $=String(G.get("path")??"."),U=G.getAll("file").filter((X)=>X instanceof File);if(U.length===0)throw new B("No files in upload (field name: file)");let Q=[];for(let X of U)Q.push(await V0($,X.name,X,Y));return L({ok:!0,saved:Q})}default:return Z(404,`Unknown files endpoint: ${N.method} /api/files/${O}`)}}import{promises as k1}from"fs";function rW(N){return N.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)}async function y1(N){try{let H=await k1.readFile(JH(N),"utf8"),O=JSON.parse(H);return{id:O.id??N,name:O.name??N,createdAt:O.createdAt??new Date(0).toISOString(),workspaceRoot:J(N)}}catch{return null}}async function b1(){let N;try{N=await k1.readdir(UN(),{withFileTypes:!0})}catch{return[]}let H=[];for(let O of N){if(!O.isDirectory())continue;let W=await y1(O.name);if(W)H.push(W)}return H.sort((O,W)=>{if(O.id===z)return-1;if(W.id===z)return 1;return W.createdAt.localeCompare(O.createdAt)}),H}async function jN(N){return y1(N)}async function q1(N){let H=N.trim();if(!H)throw Error("Project name is required");let O=rW(H);if(!O)throw Error("Project name must contain letters or numbers");if(await jN(O))throw Error(`A project named "${O}" already exists`);await BH(O,H);let W=await jN(O);if(!W)throw Error(`Failed to create project "${O}"`);return W}async function VN(N){return await jN(N)!==null}async function I1(N,H){let W=H.pathname.split("/").filter(Boolean)[2];if(!W){if(N.method==="GET"){let Y={projects:await b1()};return L(Y)}if(N.method==="POST"){let Y=await M(N);A(Y.name,"name");try{let $={project:await q1(Y.name)};return L($,201)}catch(G){let $=G instanceof Error?G.message:String(G),U=$.includes("already exists")?409:400;return Z(U,$)}}return Z(405,"Method not allowed")}if(N.method==="GET"){let Y=await jN(W);return Y?L({project:Y}):Z(404,`Project not found: ${W}`)}return Z(405,"Method not allowed")}var eW=new Set(["accept","acceptForSession","decline","cancel"]);async function j1(N,H,O){let W=H.pathname.split("/").filter(Boolean),Y=W[2],G=W[3];if(!Y){if(N.method==="GET"){let $=H.searchParams.get("project")??void 0,U={runs:await R0($)};return L(U)}if(N.method==="POST"){let $=await M(N);A($.prompt,"prompt");let Q={run:await LN($)};return L(Q,201)}return Z(405,"Method not allowed")}if(G==="events"){if(!await D(Y))return Z(404,`Run not found: ${Y}`);return O.upgrade(N,{data:{channel:`run:${Y}`}})?void 0:Z(400,"WebSocket upgrade required")}if(!G&&N.method==="GET"){let $=await D(Y);if(!$)return Z(404,`Run not found: ${Y}`);let U=Number(H.searchParams.get("tail")??NaN),Q=Number(H.searchParams.get("before")??NaN),X=await w0(Y,{limit:Number.isFinite(U)&&U>0?U:void 0,before:Number.isFinite(Q)&&Q>=0?Q:void 0}),F={run:$,events:X.events,eventsOffset:X.offset,totalEvents:X.total};return L(F)}if(N.method!=="POST")return Z(405,"Method not allowed");switch(G){case"stop":return await J1(Y)?L({ok:!0}):Z(409,"Run is not active");case"resume":{let $=await M(N);A($.prompt,"prompt");try{let U=await UH(Y,$.prompt,Array.isArray($.attachments)?$.attachments:void 0,{sandbox:$.sandbox,approvalPolicy:$.approvalPolicy,approvalsReviewer:$.approvalsReviewer,model:$.model,effort:$.effort});return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("still active")?409:400;return Z(X,Q)}}case"steer":{let $=await M(N);A($.prompt,"prompt");try{return await V1(Y,$.prompt,Array.isArray($.attachments)?$.attachments:void 0),L({ok:!0})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("not active")||Q.includes("No active turn")?409:400;return Z(X,Q)}}case"fast":{let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");try{let U=await M1(Y,$.enabled);return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("does not support")?400:500;return Z(X,Q)}}case"compact":try{return await K1(Y),L({ok:!0})}catch($){let U=$ instanceof Error?$.message:String($),Q=U.includes("not found")?404:U.includes("still active")?409:400;return Z(Q,U)}case"review":{let $=await M(N);try{let U=await A1(Y,$.instructions);return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("still active")?409:400;return Z(X,Q)}}case"approve":{let $=await M(N);if(!eW.has(String($.decision)))return Z(400,`Invalid decision: ${String($.decision)}`);if($.requestId===void 0||$.requestId===null)return Z(400,"Missing field: requestId");return await B1(Y,$.requestId,$.decision)?L({ok:!0}):Z(404,"No matching pending approval")}default:return Z(404,`Unknown runs endpoint: ${H.pathname}`)}}var YN="browser-stream",m=null,g1=null,MN=0,KN=null,cH=null;function NY(N){if(m&&g1===N&&m.readyState<=WebSocket.OPEN)return;m?.close(),g1=N;let H=new WebSocket(`ws://127.0.0.1:${N}`);m=H,H.onmessage=(O)=>{let W=String(O.data);if(W.includes('"type":"frame"'))cH=W;A0(YN,W)},H.onclose=()=>{if(m===H)m=null,cH=null,v1()},H.onerror=()=>{}}function v1(){if(KN||MN===0)return;KN=setTimeout(()=>{KN=null,gN(!0)},2000)}async function gN(N=!1){if(MN===0)return;let H=N?null:n0();if(H===null){if(N)HN();H=(await fN()).streamPort}if(H!==null)NY(H);else v1()}function h1(){MN+=1,gN()}function m1(){return cH}function c1(){if(MN=Math.max(0,MN-1),MN===0){if(m?.close(),m=null,KN)clearTimeout(KN),KN=null}}var HY=new Set(["input_mouse","input_keyboard","input_touch"]);function l1(N){if(i0()!=="user")return;if(!m||m.readyState!==WebSocket.OPEN)return;let H=typeof N==="string"?N:N.toString("utf8");try{let O=JSON.parse(H);if(typeof O.type==="string"&&HY.has(O.type))m.send(H)}catch{}}var OY=new Set(["user","agent","paused"]);async function u1(N,H,O){let Y=H.pathname.split("/").filter(Boolean)[2];if(Y==="stream")return O.upgrade(N,{data:{channel:YN}})?void 0:Z(400,"WebSocket upgrade required");if(N.method==="GET")switch(Y){case"status":{let G=await fN();if(G.streaming)gN();return L({status:G})}case"actions":{let G={actions:u0()};return L(G)}default:return Z(404,`Unknown browser endpoint: ${H.pathname}`)}if(N.method!=="POST")return Z(405,"Method not allowed");switch(Y){case"start":{let G=await M(N).catch(()=>({})),$=await d0(typeof G.url==="string"&&G.url.length>0?G.url:void 0);return gN(),L({status:$})}case"stop":return await s0(),L({ok:!0});case"navigate":{let G=await M(N);return A(G.url,"url"),await t0(G.url),L({ok:!0})}case"key":{let G=await M(N);return A(G.key,"key"),await e0(G.key),L({ok:!0})}case"back":case"forward":case"reload":return await r0(Y),L({ok:!0});case"screenshot":{let $={path:await N1()};return L($)}case"control":{let G=await M(N);if(!OY.has(String(G.controller)))return Z(400,`Invalid controller: ${String(G.controller)}`);return p0(G.controller),L({ok:!0})}default:return Z(404,`Unknown browser endpoint: ${H.pathname}`)}}import{promises as P}from"fs";import E from"path";var n1=".agents/skills";function AN(N){return E.join(J(N),n1)}var WY=/^[a-z0-9][a-z0-9-]*$/,YY=new Set(["registry","install"]);function JN(N,H){if(!WY.test(N))throw new B(`Invalid skill id "${N}" \u2014 use lowercase letters, digits and dashes`);return E.join(AN(H),N)}function i1(N){return N.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,"")}async function a1(N,H,O=120000){let W=Bun.spawn([process.execPath,"x","skills",...N],{cwd:H,env:{...process.env,DISABLE_TELEMETRY:"1",DO_NOT_TRACK:"1"},stdout:"pipe",stderr:"pipe"}),Y=setTimeout(()=>W.kill(),O);try{let[G,$,U]=await Promise.all([new Response(W.stdout).text(),new Response(W.stderr).text(),W.exited]);return{stdout:i1(G),stderr:i1($),code:U}}finally{clearTimeout(Y)}}function GY(N){let H=[],O=null;for(let W of N.split(/\r?\n/)){let Y=W.trim(),G=/^(\S+@\S+)\s+([\d.]+[KMB]?)\s+installs\b/.exec(Y);if(G){let U=G[1],Q=U.indexOf("@");O={source:U,repo:U.slice(0,Q),name:U.slice(Q+1),installs:G[2]},H.push(O);continue}let $=/^[\u2514\u2570]\s*(https?:\/\/\S+)/.exec(Y);if($&&O)O.url=$[1],O=null}return H}function $Y(N){let H=[],O=/^---\r?\n([\s\S]*?)\r?\n---/.exec(N.replace(/^\uFEFF/,""));if(!O)return{errors:["Missing YAML frontmatter (--- name/description ---)"]};let W={};for(let Y of O[1].split(/\r?\n/)){let G=/^([A-Za-z_][\w-]*):\s*(.*)$/.exec(Y);if(G)W[G[1].toLowerCase()]=G[2].trim().replace(/^["']|["']$/g,"")}if(!W.name)H.push("Frontmatter is missing required field: name");if(!W.description)H.push("Frontmatter is missing required field: description");return{name:W.name,description:W.description,errors:H}}var UY=15000,uH=new Map,lH=new Map;function vN(N){uH.delete(N)}async function QY(N){let H=uH.get(N);if(H&&Date.now()-H.at<UY)return H.view;let O=lH.get(N);if(O)return O;let W=XY(N).then((Y)=>{return uH.set(N,{at:Date.now(),view:Y}),Y}).finally(()=>{lH.delete(N)});return lH.set(N,W),W}async function XY(N){let H=new Map,O=[];try{let W=await C("skills/list",{cwds:[J(N)],forceReload:!0});for(let Y of W.data??[]){for(let G of Y.errors??[])O.push(G);for(let G of Y.skills??[]){let $=E.basename(E.dirname(G.path));H.set($,G)}}}catch(W){console.warn("[skills] skills/list failed:",W)}return{byDir:H,errors:O}}async function XH(N=z){await P.mkdir(AN(N),{recursive:!0});let O=(await P.readdir(AN(N),{withFileTypes:!0})).filter((U)=>U.isDirectory()).map((U)=>U.name),{byDir:W,errors:Y}=await QY(N),G=[];for(let U of O){let Q=E.join(AN(N),U,"SKILL.md"),X=null;try{X=await P.readFile(Q,"utf8")}catch{G.push({id:U,name:U,description:"",enabled:!1,errors:["Missing SKILL.md"]});continue}let F=$Y(X),K=W.get(U),R=Y.filter((f)=>l(f.path).includes(`/${U}/`)||E.basename(E.dirname(f.path))===U).map((f)=>f.message);G.push({id:U,name:K?.name??F.name??U,description:K?.description??F.description??"",enabled:K?.enabled??!0,errors:[...new Set([...F.errors,...R])]})}let $=Y.filter((U)=>!O.some((Q)=>l(U.path).includes(`/${Q}/`)));return{skills:G,errors:$}}async function hN(N,H=z){let O=JN(N,H),W;try{W=await P.readFile(E.join(O,"SKILL.md"),"utf8")}catch{return null}let{skills:Y}=await XH(H),G=Y.find((Q)=>Q.id===N)??{id:N,name:N,description:"",enabled:!0,errors:[]},$=[],U=async(Q)=>{let X=await P.readdir(E.join(O,Q),{withFileTypes:!0});for(let F of X){let K=Q?`${Q}/${F.name}`:F.name;if(F.isDirectory())await U(K);else if(K!=="SKILL.md")$.push(`${n1}/${N}/${K}`)}};return await U(""),{info:G,content:W,files:$}}async function o1(N,H=z){let O=N.name.trim().toLowerCase().replace(/\s+/g,"-");if(YY.has(O))throw new B(`"${O}" is a reserved name \u2014 pick another`);let W=JN(O,H);try{throw await P.access(E.join(W,"SKILL.md")),new B(`Skill "${O}" already exists`)}catch(G){if(G instanceof B)throw G}let Y=`---
330
- name: ${O}
329
+ `+H.prompt.slice(0,2000)}],effort:"low"}).catch(()=>X(null))}),$=oO(G);if(!$)return;await W.request("thread/name/set",{threadId:H.codexThreadId,name:$});let U=await NN(N,{title:$});if(U)i("runs",{type:"run.updated",run:U})}catch(W){console.warn(`[runs] title generation failed for ${N}:`,W)}}async function C(N,H){let W=h();return await W.start(),await W.initializeOnce(),W.request(N,H)}async function zN(N){let H=N.projectId??"default",W=N.cwd??A(H),O=await T0({prompt:N.prompt,cwd:W,projectId:H,sandbox:N.sandbox??"workspaceWrite",approvalPolicy:N.approvalPolicy??"onRequest",approvalsReviewer:N.approvalsReviewer??"user",model:N.model,effort:N.effort??"medium",source:N.source,scheduleId:N.scheduleId,scheduleName:N.scheduleName});return i("runs",{type:"run.updated",run:O}),await E(O.id,"daemon","run.started",{prompt:N.prompt,cwd:W,projectId:H,attachments:N.attachments??[]}),(async()=>{try{let Y=h();await Y.start(),await Y.initializeOnce();let G=await Y.request("thread/start",{cwd:W,model:N.model??null,sandbox:F1[N.sandbox??"workspaceWrite"],approvalPolicy:jH[N.approvalPolicy??"onRequest"],...N.approvalsReviewer==="auto_review"?{approvalsReviewer:"auto_review"}:{},...$H?{developerInstructions:$H}:{},serviceName:"jun"}),$=yN(G)??(typeof G.threadId==="string"?G.threadId:null);if(!$)throw Error(`thread/start returned no thread id: ${JSON.stringify(G)}`);WN.set($,O.id),await NN(O.id,{codexThreadId:$}),await x(O.id,"running"),await K1(O.id,N.model??gH,{threadId:$,input:vH(H,N.prompt,N.attachments,N.skill),summary:"detailed",effort:N.effort??"medium",sandboxPolicy:V1[N.sandbox??"workspaceWrite"]})}catch(Y){let G=Y instanceof Error?Y.message:String(Y);await E(O.id,"daemon","run.failed",{reason:G}),await x(O.id,"failed")}})(),O}async function hH(N,H){let W=h();if(await W.start(),await W.initializeOnce(),WN.has(H))return{server:W,resumed:!1};let O=await D(N);return await W.request("thread/resume",{threadId:H,...O?.approvalPolicy?{approvalPolicy:jH[O.approvalPolicy]}:{},...O?.approvalsReviewer==="auto_review"?{approvalsReviewer:"auto_review"}:{},...O?.model?{model:O.model}:{},...O?.sandbox?{sandbox:F1[O.sandbox]}:{},...$H?{developerInstructions:$H}:{}}),WN.set(H,N),{server:W,resumed:!0}}async function UH(N,H,W,O){let Y=await D(N);if(!Y)throw Error(`Run not found: ${N}`);if(g(Y.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let G=Y.codexThreadId;if(!G)throw Error("Run has no Codex thread to resume");let $={};if(O?.sandbox&&O.sandbox!==Y.sandbox)$.sandbox=O.sandbox;if(O?.approvalPolicy&&O.approvalPolicy!==Y.approvalPolicy)$.approvalPolicy=O.approvalPolicy;if(O?.approvalsReviewer&&O.approvalsReviewer!==Y.approvalsReviewer)$.approvalsReviewer=O.approvalsReviewer;if(O?.model&&O.model!==Y.model)$.model=O.model;if(O?.effort&&O.effort!==Y.effort)$.effort=O.effort;if(Object.keys($).length>0){let U=await NN(N,$);if(U)i("runs",{type:"run.updated",run:U})}return await E(N,"daemon","run.resumed",{prompt:H,attachments:W??[],...Object.keys($).length>0?{modeChanges:$}:{}}),await x(N,"running"),(async()=>{try{await hH(N,G);let U=$.sandbox??Y.sandbox??"workspaceWrite",Q=$.approvalPolicy??Y.approvalPolicy??"onRequest",X=$.approvalsReviewer??Y.approvalsReviewer,z=$.model??Y.model,K=(await D(N))?.serviceTier;await K1(N,z??gH,{threadId:G,input:vH(Y.projectId,H,W),summary:"detailed",effort:$.effort??Y.effort??"medium",sandboxPolicy:V1[U],approvalPolicy:jH[Q],...X==="auto_review"?{approvalsReviewer:X}:{},...z?{model:z}:{},...K?{serviceTier:K}:{}})}catch(U){let Q=U instanceof Error?U.message:String(U);await E(N,"daemon","run.failed",{reason:Q}),await x(N,"failed")}})(),await D(N)}async function J1(N,H,W){let O=await D(N);if(!O)throw Error(`Run not found: ${N}`);if(!g(O.status))throw Error("Run is not active \u2014 send a follow-up message instead");let Y=O.codexThreadId,G=bN.get(N);if(!Y||!G)throw Error("No active turn to steer");await E(N,"daemon","run.steered",{prompt:H,attachments:W??[]}),await h().request("turn/steer",{threadId:Y,expectedTurnId:G,input:vH(O.projectId,H,W)})}async function A1(N,H){let W=await D(N);if(!W)throw Error(`Run not found: ${N}`);if(H){let G=((await C("model/list",{})).data??[]).find(($)=>W.model?$.model===W.model:$.isDefault);if(!G?.serviceTiers?.some(($)=>$.id==="priority"))throw Error(`Model ${G?.model??W.model??"unknown"} does not support fast mode`)}let O=await NN(N,{serviceTier:H?"priority":"standard"});if(O)i("runs",{type:"run.updated",run:O});return await E(N,"daemon","run.fast",{enabled:H}),O}async function B1(N){let H=await D(N);if(!H)throw Error(`Run not found: ${N}`);if(g(H.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let W=H.codexThreadId;if(!W)throw Error("Run has no Codex thread");let{server:O}=await hH(N,W);await E(N,"daemon","run.compact.started",{}),await O.request("thread/compact/start",{threadId:W})}async function D1(N,H){let W=await D(N);if(!W)throw Error(`Run not found: ${N}`);if(g(W.status))throw Error("Run is still active \u2014 wait for the current turn to finish");let O=W.codexThreadId;if(!O)throw Error("Run has no Codex thread");let{server:Y}=await hH(N,O),G=H?.trim();await E(N,"daemon","run.review.started",{instructions:G??null}),await x(N,"running");try{await Y.request("review/start",{threadId:O,target:G?{type:"custom",instructions:G}:{type:"uncommittedChanges"},delivery:"inline"})}catch($){let U=$ instanceof Error?$.message:String($);throw await E(N,"daemon","run.failed",{reason:U}),await x(N,"failed"),$}return await D(N)}async function C1(N){let H=await D(N);if(!H||!g(H.status))return!1;if(H.codexThreadId&&IN?.running)try{await IN.request("turn/interrupt",{threadId:H.codexThreadId})}catch(W){console.warn(`[runs] turn/interrupt failed for ${N}:`,W)}return ON.delete(N),await E(N,"daemon","run.stopped",{}),await x(N,"stopped"),!0}async function S1(N,H,W){let O=ON.get(N)??[],Y=O.findIndex(($)=>String($.requestId)===String(H));if(Y===-1)return!1;let[G]=O.splice(Y,1);if(O.length===0)ON.delete(N);if(G.method==="mcpServer/elicitation/request"){let $=W==="decline"||W==="cancel"?W:"accept";h().respond(G.requestId,{action:$})}else h().respond(G.requestId,{decision:W});if(await E(N,"daemon","approval.resolved",{requestId:G.requestId,decision:W}),O.length===0)await x(N,"running");return!0}function VN(){return sO.join(q(),"config.toml")}async function p(){try{return await FN.readFile(VN(),"utf8")}catch{return""}}async function E1(N){try{c(N)}catch(H){throw new B(`Invalid TOML: ${H instanceof Error?H.message:String(H)}`)}await FN.writeFile(VN(),N,"utf8")}function tO(N){if(!N.trim())return{};let W=c(N).mcp_servers;if(typeof W!=="object"||W===null)return{};return W}async function rO(){let N=new Map;try{let H=await C("mcpServerStatus/list",{detail:"full"});for(let W of H.data??[]){let O=Object.entries(W.tools??{}).map(([Y,G])=>({name:Y,description:G?.description}));N.set(W.name,{startupState:W.serverInfo?"ready":"starting",authStatus:W.authStatus??null,tools:O})}}catch(H){console.warn("[mcp] mcpServerStatus/list failed:",H)}return N}async function T1(){let N=await p(),H=tO(N),W=await rO();return{servers:Object.entries(H).map(([Y,G])=>{let $=W.get(Y);return{name:Y,command:G.command,args:G.args,envKeys:G.env?Object.keys(G.env):void 0,url:G.url,enabled:G.enabled!==!1,startupState:$?.startupState??null,authStatus:$?.authStatus??null,tools:$?.tools??[],error:$?.error}})}}var eO=/^[A-Za-z0-9_-]+$/;async function _1(N){if(!eO.test(N.name))throw new B(`Invalid server name "${N.name}" \u2014 letters, digits, _ and - only`);if(!N.command&&!N.url)throw new B("Server needs either a command or a url");let H=await p(),W=H.trim()?c(H):{},O=W.mcp_servers??{},Y={};if(N.command)Y.command=N.command;if(N.args&&N.args.length>0)Y.args=N.args;if(N.env&&Object.keys(N.env).length>0)Y.env=N.env;if(N.url)Y.url=N.url;if(N.enabled===!1)Y.enabled=!1;O[N.name]=Y,W.mcp_servers=O,await FN.writeFile(VN(),d(W),"utf8")}async function w1(N){let H=await p();if(!H.trim())return!1;let W=c(H),O=W.mcp_servers;if(!O||!(N in O))return!1;return delete O[N],await FN.writeFile(VN(),d(W),"utf8"),!0}async function P1(N,H){let W=await p(),O=c(W||""),Y=O.mcp_servers??{};if(!Y[N])throw new B(`Server not found: ${N}`);Y[N].enabled=H,O.mcp_servers=Y,await FN.writeFile(VN(),d(O),"utf8")}async function f1(){await C("config/mcpServer/reload",{})}async function x1(N,H){let W=await p(),O=W.trim()?c(W):{},Y=O.mcp_servers??{},G={command:process.execPath,args:[N],env:{JUN_PORT:String(H)}},$=Y.jun;if($&&!Y.agenthost&&$.command===G.command&&JSON.stringify($.args)===JSON.stringify(G.args)&&$.env?.JUN_PORT===String(H))return;delete Y.agenthost,Y.jun=G,O.mcp_servers=Y,await FN.writeFile(VN(),d(O),"utf8")}var HY="https://registry.npmjs.org/junhost/latest",WY=86400000,OY=3600000,mH=null,k1=0,cH=!1,lH=null;async function YY(){try{let N=await fetch(HY,{signal:AbortSignal.timeout(5000)});if(!N.ok)throw Error(`registry ${N.status}`);let H=await N.json();mH=typeof H.version==="string"?H.version:null,cH=mH!==null}catch{cH=!1}finally{k1=Date.now(),lH=null}}function GY(){let N=cH?WY:OY;if(!lH&&Date.now()-k1>N)lH=YY();return mH}function $Y(N,H){let W=N.split(".").map((Y)=>parseInt(Y,10)||0),O=H.split(".").map((Y)=>parseInt(Y,10)||0);for(let Y=0;Y<Math.max(W.length,O.length);Y++){let G=W[Y]??0,$=O[Y]??0;if(G!==$)return G>$}return!1}function y1(){let N=GY();return{latestVersion:N,updateAvailable:N!==null&&$Y(N,XN)}}var UY=Date.now();function b1(){return L({ok:!0})}function q1(){let N={ok:!0,name:"jun",version:XN,...y1(),projectId:F,dataRoot:b,workspaceRoot:A(),uptimeSeconds:Math.round((Date.now()-UY)/1000)};return L(N)}import QY from"path";var QH={ok:!0};async function I1(N,H){let W=H.pathname.slice(11),O=H.searchParams.get("path")??".",Y=H.searchParams.get("project")??F;switch(`${N.method} ${W}`){case"GET tree":return L(await L0(O,Y));case"GET read":return L(await z0(O,Y));case"GET download":{let G=sN(O,Y),$=Bun.file(G);if(!await $.exists())return Z(404,`File not found: ${O}`);return new Response($,{headers:{"content-disposition":`attachment; filename="${encodeURIComponent(QY.basename(G))}"`}})}case"POST write":{let G=await M(N);return await F0(J(G.path,"path"),typeof G.content==="string"?G.content:"",Y),L(QH)}case"POST mkdir":{let G=await M(N);return await V0(J(G.path,"path"),Y),L(QH)}case"POST delete":{let G=await M(N);return await M0(J(G.path,"path"),Y),L(QH)}case"POST rename":{let G=await M(N);return await K0(J(G.from,"from"),J(G.to,"to"),Y),L(QH)}case"POST upload":{let G;try{G=await N.formData()}catch{throw new B("Expected multipart/form-data body")}let $=String(G.get("path")??"."),U=G.getAll("file").filter((X)=>X instanceof File);if(U.length===0)throw new B("No files in upload (field name: file)");let Q=[];for(let X of U)Q.push(await J0($,X.name,X,Y));return L({ok:!0,saved:Q})}default:return Z(404,`Unknown files endpoint: ${N.method} /api/files/${W}`)}}import{promises as j1}from"fs";function XY(N){return N.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)}async function g1(N){try{let H=await j1.readFile(AH(N),"utf8"),W=JSON.parse(H);return{id:W.id??N,name:W.name??N,createdAt:W.createdAt??new Date(0).toISOString(),workspaceRoot:A(N)}}catch{return null}}async function v1(){let N;try{N=await j1.readdir(UN(),{withFileTypes:!0})}catch{return[]}let H=[];for(let W of N){if(!W.isDirectory())continue;let O=await g1(W.name);if(O)H.push(O)}return H.sort((W,O)=>{if(W.id===F)return-1;if(O.id===F)return 1;return O.createdAt.localeCompare(W.createdAt)}),H}async function gN(N){return g1(N)}async function h1(N){let H=N.trim();if(!H)throw Error("Project name is required");let W=XY(H);if(!W)throw Error("Project name must contain letters or numbers");if(await gN(W))throw Error(`A project named "${W}" already exists`);await BH(W,H);let O=await gN(W);if(!O)throw Error(`Failed to create project "${W}"`);return O}async function MN(N){return await gN(N)!==null}async function m1(N,H){let O=H.pathname.split("/").filter(Boolean)[2];if(!O){if(N.method==="GET"){let Y={projects:await v1()};return L(Y)}if(N.method==="POST"){let Y=await M(N);J(Y.name,"name");try{let $={project:await h1(Y.name)};return L($,201)}catch(G){let $=G instanceof Error?G.message:String(G),U=$.includes("already exists")?409:400;return Z(U,$)}}return Z(405,"Method not allowed")}if(N.method==="GET"){let Y=await gN(O);return Y?L({project:Y}):Z(404,`Project not found: ${O}`)}return Z(405,"Method not allowed")}var ZY=new Set(["accept","acceptForSession","decline","cancel"]);async function c1(N,H,W){let O=H.pathname.split("/").filter(Boolean),Y=O[2],G=O[3];if(!Y){if(N.method==="GET"){let $=H.searchParams.get("project")??void 0,U={runs:await _0($)};return L(U)}if(N.method==="POST"){let $=await M(N);J($.prompt,"prompt");let Q={run:await zN($)};return L(Q,201)}return Z(405,"Method not allowed")}if(G==="events"){if(!await D(Y))return Z(404,`Run not found: ${Y}`);return W.upgrade(N,{data:{channel:`run:${Y}`}})?void 0:Z(400,"WebSocket upgrade required")}if(!G&&N.method==="GET"){let $=await D(Y);if(!$)return Z(404,`Run not found: ${Y}`);let U=Number(H.searchParams.get("tail")??NaN),Q=Number(H.searchParams.get("before")??NaN),X=await x0(Y,{limit:Number.isFinite(U)&&U>0?U:void 0,before:Number.isFinite(Q)&&Q>=0?Q:void 0}),z={run:$,events:X.events,eventsOffset:X.offset,totalEvents:X.total};return L(z)}if(N.method!=="POST")return Z(405,"Method not allowed");switch(G){case"stop":return await C1(Y)?L({ok:!0}):Z(409,"Run is not active");case"resume":{let $=await M(N);J($.prompt,"prompt");try{let U=await UH(Y,$.prompt,Array.isArray($.attachments)?$.attachments:void 0,{sandbox:$.sandbox,approvalPolicy:$.approvalPolicy,approvalsReviewer:$.approvalsReviewer,model:$.model,effort:$.effort});return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("still active")?409:400;return Z(X,Q)}}case"steer":{let $=await M(N);J($.prompt,"prompt");try{return await J1(Y,$.prompt,Array.isArray($.attachments)?$.attachments:void 0),L({ok:!0})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("not active")||Q.includes("No active turn")?409:400;return Z(X,Q)}}case"fast":{let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");try{let U=await A1(Y,$.enabled);return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("does not support")?400:500;return Z(X,Q)}}case"compact":try{return await B1(Y),L({ok:!0})}catch($){let U=$ instanceof Error?$.message:String($),Q=U.includes("not found")?404:U.includes("still active")?409:400;return Z(Q,U)}case"review":{let $=await M(N);try{let U=await D1(Y,$.instructions);return L({run:U})}catch(U){let Q=U instanceof Error?U.message:String(U),X=Q.includes("not found")?404:Q.includes("still active")?409:400;return Z(X,Q)}}case"approve":{let $=await M(N);if(!ZY.has(String($.decision)))return Z(400,`Invalid decision: ${String($.decision)}`);if($.requestId===void 0||$.requestId===null)return Z(400,"Missing field: requestId");return await S1(Y,$.requestId,$.decision)?L({ok:!0}):Z(404,"No matching pending approval")}default:return Z(404,`Unknown runs endpoint: ${H.pathname}`)}}var YN="browser-stream",m=null,l1=null,KN=0,JN=null,iH=null;function LY(N){if(m&&l1===N&&m.readyState<=WebSocket.OPEN)return;m?.close(),l1=N;let H=new WebSocket(`ws://127.0.0.1:${N}`);m=H,H.onmessage=(W)=>{let O=String(W.data);if(O.includes('"type":"frame"'))iH=O;D0(YN,O)},H.onclose=()=>{if(m===H)m=null,iH=null,u1()},H.onerror=()=>{}}function u1(){if(JN||KN===0)return;JN=setTimeout(()=>{JN=null,vN(!0)},2000)}async function vN(N=!1){if(KN===0)return;let H=N?null:d0();if(H===null){if(N)HN();H=(await xN()).streamPort}if(H!==null)LY(H);else u1()}function i1(){KN+=1,vN()}function p1(){return iH}function n1(){if(KN=Math.max(0,KN-1),KN===0){if(m?.close(),m=null,JN)clearTimeout(JN),JN=null}}var zY=new Set(["input_mouse","input_keyboard","input_touch"]);function a1(N){if(a0()!=="user")return;if(!m||m.readyState!==WebSocket.OPEN)return;let H=typeof N==="string"?N:N.toString("utf8");try{let W=JSON.parse(H);if(typeof W.type==="string"&&zY.has(W.type))m.send(H)}catch{}}var FY=new Set(["user","agent","paused"]);async function o1(N,H,W){let Y=H.pathname.split("/").filter(Boolean)[2];if(Y==="stream")return W.upgrade(N,{data:{channel:YN}})?void 0:Z(400,"WebSocket upgrade required");if(N.method==="GET")switch(Y){case"status":{let G=await xN();if(G.streaming)vN();return L({status:G})}case"actions":{let G={actions:n0()};return L(G)}default:return Z(404,`Unknown browser endpoint: ${H.pathname}`)}if(N.method!=="POST")return Z(405,"Method not allowed");switch(Y){case"start":{let G=await M(N).catch(()=>({})),$=await r0(typeof G.url==="string"&&G.url.length>0?G.url:void 0);return vN(),L({status:$})}case"stop":return await e0(),L({ok:!0});case"navigate":{let G=await M(N);return J(G.url,"url"),await N1(G.url),L({ok:!0})}case"key":{let G=await M(N);return J(G.key,"key"),await W1(G.key),L({ok:!0})}case"back":case"forward":case"reload":return await H1(Y),L({ok:!0});case"screenshot":{let $={path:await O1()};return L($)}case"control":{let G=await M(N);if(!FY.has(String(G.controller)))return Z(400,`Invalid controller: ${String(G.controller)}`);return o0(G.controller),L({ok:!0})}default:return Z(404,`Unknown browser endpoint: ${H.pathname}`)}}import{promises as P}from"fs";import T from"path";var t1=".agents/skills";function AN(N){return T.join(A(N),t1)}var VY=/^[a-z0-9][a-z0-9-]*$/,MY=new Set(["registry","install"]);function BN(N,H){if(!VY.test(N))throw new B(`Invalid skill id "${N}" \u2014 use lowercase letters, digits and dashes`);return T.join(AN(H),N)}function d1(N){return N.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,"")}async function r1(N,H,W=120000){let O=Bun.spawn([process.execPath,"x","skills",...N],{cwd:H,env:{...process.env,DISABLE_TELEMETRY:"1",DO_NOT_TRACK:"1"},stdout:"pipe",stderr:"pipe"}),Y=setTimeout(()=>O.kill(),W);try{let[G,$,U]=await Promise.all([new Response(O.stdout).text(),new Response(O.stderr).text(),O.exited]);return{stdout:d1(G),stderr:d1($),code:U}}finally{clearTimeout(Y)}}function KY(N){let H=[],W=null;for(let O of N.split(/\r?\n/)){let Y=O.trim(),G=/^(\S+@\S+)\s+([\d.]+[KMB]?)\s+installs\b/.exec(Y);if(G){let U=G[1],Q=U.indexOf("@");W={source:U,repo:U.slice(0,Q),name:U.slice(Q+1),installs:G[2]},H.push(W);continue}let $=/^[\u2514\u2570]\s*(https?:\/\/\S+)/.exec(Y);if($&&W)W.url=$[1],W=null}return H}function JY(N){let H=[],W=/^---\r?\n([\s\S]*?)\r?\n---/.exec(N.replace(/^\uFEFF/,""));if(!W)return{errors:["Missing YAML frontmatter (--- name/description ---)"]};let O={};for(let Y of W[1].split(/\r?\n/)){let G=/^([A-Za-z_][\w-]*):\s*(.*)$/.exec(Y);if(G)O[G[1].toLowerCase()]=G[2].trim().replace(/^["']|["']$/g,"")}if(!O.name)H.push("Frontmatter is missing required field: name");if(!O.description)H.push("Frontmatter is missing required field: description");return{name:O.name,description:O.description,errors:H}}var AY=15000,nH=new Map,pH=new Map;function hN(N){nH.delete(N)}async function BY(N){let H=nH.get(N);if(H&&Date.now()-H.at<AY)return H.view;let W=pH.get(N);if(W)return W;let O=DY(N).then((Y)=>{return nH.set(N,{at:Date.now(),view:Y}),Y}).finally(()=>{pH.delete(N)});return pH.set(N,O),O}async function DY(N){let H=new Map,W=[];try{let O=await C("skills/list",{cwds:[A(N)],forceReload:!0});for(let Y of O.data??[]){for(let G of Y.errors??[])W.push(G);for(let G of Y.skills??[]){let $=T.basename(T.dirname(G.path));H.set($,G)}}}catch(O){console.warn("[skills] skills/list failed:",O)}return{byDir:H,errors:W}}async function XH(N=F){await P.mkdir(AN(N),{recursive:!0});let W=(await P.readdir(AN(N),{withFileTypes:!0})).filter((U)=>U.isDirectory()).map((U)=>U.name),{byDir:O,errors:Y}=await BY(N),G=[];for(let U of W){let Q=T.join(AN(N),U,"SKILL.md"),X=null;try{X=await P.readFile(Q,"utf8")}catch{G.push({id:U,name:U,description:"",enabled:!1,errors:["Missing SKILL.md"]});continue}let z=JY(X),K=O.get(U),R=Y.filter((f)=>l(f.path).includes(`/${U}/`)||T.basename(T.dirname(f.path))===U).map((f)=>f.message);G.push({id:U,name:K?.name??z.name??U,description:K?.description??z.description??"",enabled:K?.enabled??!0,errors:[...new Set([...z.errors,...R])]})}let $=Y.filter((U)=>!W.some((Q)=>l(U.path).includes(`/${Q}/`)));return{skills:G,errors:$}}async function mN(N,H=F){let W=BN(N,H),O;try{O=await P.readFile(T.join(W,"SKILL.md"),"utf8")}catch{return null}let{skills:Y}=await XH(H),G=Y.find((Q)=>Q.id===N)??{id:N,name:N,description:"",enabled:!0,errors:[]},$=[],U=async(Q)=>{let X=await P.readdir(T.join(W,Q),{withFileTypes:!0});for(let z of X){let K=Q?`${Q}/${z.name}`:z.name;if(z.isDirectory())await U(K);else if(K!=="SKILL.md")$.push(`${t1}/${N}/${K}`)}};return await U(""),{info:G,content:O,files:$}}async function e1(N,H=F){let W=N.name.trim().toLowerCase().replace(/\s+/g,"-");if(MY.has(W))throw new B(`"${W}" is a reserved name \u2014 pick another`);let O=BN(W,H);try{throw await P.access(T.join(O,"SKILL.md")),new B(`Skill "${W}" already exists`)}catch(G){if(G instanceof B)throw G}let Y=`---
330
+ name: ${W}
331
331
  description: ${N.description.trim()}
332
332
  ---
333
333
 
334
334
  ${N.instructions?.trim()??"Describe when and how to use this skill."}
335
- `;return await P.mkdir(W,{recursive:!0}),await P.writeFile(E.join(W,"SKILL.md"),Y,"utf8"),vN(H),await hN(O,H)}async function d1(N,H,O=z){let W=JN(N,O);try{await P.access(W)}catch{throw new B(`Skill not found: ${N}`)}return await P.writeFile(E.join(W,"SKILL.md"),H,"utf8"),vN(O),await hN(N,O)}async function s1(N,H=z){let O=JN(N,H);try{return await P.rm(O,{recursive:!0,force:!1}),vN(H),!0}catch{return!1}}async function t1(N,H,O=z){let W=E.join(JN(N,O),"SKILL.md");await C("skills/config/write",{path:W,enabled:H,name:null}),vN(O)}async function r1(N){let H=N.trim();if(!H)return[];let{stdout:O}=await a1(["find",H],J(z),30000);return GY(O)}async function p1(N){await P.mkdir(AN(N),{recursive:!0});let H=await P.readdir(AN(N),{withFileTypes:!0});return new Set(H.filter((O)=>O.isDirectory()).map((O)=>O.name))}async function e1(N,H=z){let O=N.trim();if(!O)throw new B("Missing skill source");if(/[\s;&|`$(){}<>]/.test(O))throw new B("Invalid source \u2014 expected owner/repo[@skill] or a URL");let W=J(H),Y=await p1(H),{stdout:G,stderr:$}=await a1(["add",O,"-a","codex","--copy","-y"],W);vN(H);let Q=[...await p1(H)].filter((F)=>!Y.has(F));if(Q.length===0){let F=[G,$].filter(Boolean).join(`
336
- `).trim();throw new B(`No skill installed from "${O}".${F?`
337
- ${F}`:""}`)}let{skills:X}=await XH(H);return{installed:Q,skills:X,log:[G,$].filter(Boolean).join(`
338
- `).trim()}}async function NO(N,H,O=z){let W=await hN(N,O);if(!W)throw new B(`Skill not found: ${N}`);let Y={prompt:H?.trim()||`Use the "${W.info.name}" skill to demonstrate what it does. Follow its instructions and report the result.`,projectId:O,skill:{name:W.info.name,path:E.join(JN(N,O),"SKILL.md")}};return LN(Y)}async function LY(N){let H=N.searchParams.get("project");if(H)return H;let O=N.searchParams.get("cwd");if(O){let W=uN(O);if(W&&await VN(W))return W}return z}async function HO(N,H){let O=H.pathname.split("/").filter(Boolean),W=O[2],Y=O[3],G=await LY(H);if(W==="registry"){if(Y==="search"&&N.method==="GET"){let $=H.searchParams.get("q")??"",U=await r1($);return L({results:U})}if(Y==="install"&&N.method==="POST"){let $=await M(N);A($.source,"source");let U=await e1($.source,G);return L(U,201)}return Z(404,`Unknown skills endpoint: ${H.pathname}`)}if(!W){if(N.method==="GET")return L(await XH(G));if(N.method==="POST"){let $=await M(N);A($.name,"name"),A($.description,"description");let U=await o1($,G);return L({skill:U},201)}return Z(405,"Method not allowed")}if(!Y)switch(N.method){case"GET":{let $=await hN(W,G);return $?L({skill:$}):Z(404,`Skill not found: ${W}`)}case"PUT":{let $=await M(N);A($.content,"content");let U=await d1(W,$.content,G);return L({skill:U})}case"DELETE":return await s1(W,G)?L({ok:!0}):Z(404,`Skill not found: ${W}`);default:return Z(405,"Method not allowed")}if(N.method!=="POST")return Z(405,"Method not allowed");switch(Y){case"enable":{let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");return await t1(W,$.enabled,G),L({ok:!0})}case"test":{let $=await M(N).catch(()=>({})),U=await NO(W,$.prompt,G);return L({run:U},201)}default:return Z(404,`Unknown skills endpoint: ${H.pathname}`)}}async function OO(N,H){let O=H.pathname.split("/").filter(Boolean),W=O[2];if(!W){if(N.method==="GET")return L(await S1());return Z(405,"Method not allowed")}if(W==="config"){if(N.method==="GET"){let Y={toml:await p()};return L(Y)}if(N.method==="PUT"){let Y=await M(N);return A(Y.toml,"toml"),await C1(Y.toml),L({ok:!0})}return Z(405,"Method not allowed")}if(W==="reload"&&N.method==="POST")return await _1(),L({ok:!0});if(W==="servers"){let Y=O[3];if(!Y){if(N.method==="POST"){let $=await M(N);return A($.name,"name"),await R1($),L({ok:!0},201)}return Z(405,"Method not allowed")}let G=O[4];if(G==="enable"&&N.method==="POST"){let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");return await E1(Y,$.enabled),L({ok:!0})}if(!G&&N.method==="DELETE")return await T1(Y)?L({ok:!0}):Z(404,`Server not found: ${Y}`);return Z(405,"Method not allowed")}return Z(404,`Unknown MCP endpoint: ${H.pathname}`)}import{promises as GN}from"fs";import mN from"path";function FY(){return mN.join(q(),"config.toml")}function LH(){return mN.join(q(),"memories")}async function WO(){let N=await p();return N.trim()?c(N):{}}function ZH(N){return typeof N==="object"&&N!==null?N:{}}function zY(N){let H=ZH(N.memories),O={};if(typeof H.generate_memories==="boolean")O.generateMemories=H.generate_memories;if(typeof H.use_memories==="boolean")O.useMemories=H.use_memories;if(typeof H.disable_on_external_context==="boolean")O.disableOnExternalContext=H.disable_on_external_context;if(typeof H.min_rate_limit_remaining_percent==="number")O.minRateLimitRemainingPercent=H.min_rate_limit_remaining_percent;return O}async function VY(){let N=LH(),H=[];async function O(W){let Y;try{Y=await GN.readdir(W,{withFileTypes:!0})}catch{return}for(let G of Y){let $=mN.join(W,G.name);if(G.isDirectory()){if(G.name===".git")continue;await O($)}else if(G.isFile()){let U=await GN.stat($);H.push({path:l(mN.relative(N,$)),name:G.name,size:U.size,modifiedAt:U.mtime.toISOString()})}}}return await O(N),H.sort((W,Y)=>Y.modifiedAt.localeCompare(W.modifiedAt)),H}async function MY(){try{let H=((await C("experimentalFeature/list",{})).data??[]).find((O)=>O.name==="memories");return H?H.enabled:null}catch(N){return console.warn("[memories] experimentalFeature/list failed:",N),null}}async function YO(){let N=await WO();return{enabled:ZH(N.features).memories===!0,liveEnabled:await MY(),settings:zY(N),files:await VY()}}async function GO(N){let H=await WO();if(typeof N.enabled==="boolean"){let O=ZH(H.features);O.memories=N.enabled,H.features=O}if(N.settings){let O=ZH(H.memories),W=N.settings;if(typeof W.generateMemories==="boolean")O.generate_memories=W.generateMemories;if(typeof W.useMemories==="boolean")O.use_memories=W.useMemories;if(typeof W.disableOnExternalContext==="boolean")O.disable_on_external_context=W.disableOnExternalContext;if(typeof W.minRateLimitRemainingPercent==="number")O.min_rate_limit_remaining_percent=W.minRateLimitRemainingPercent;H.memories=O}if(await GN.writeFile(FY(),d(H),"utf8"),typeof N.enabled==="boolean")try{await C("experimentalFeature/enablement/set",{enablement:{memories:N.enabled}})}catch(O){console.warn("[memories] live enablement/set failed (applies on restart):",O)}}async function $O(N){let H=e(LH(),N);return GN.readFile(H,"utf8")}async function UO(N,H){let O=e(LH(),N);await GN.mkdir(mN.dirname(O),{recursive:!0}),await GN.writeFile(O,H,"utf8")}async function QO(N){let H=e(LH(),N);await GN.rm(H)}async function XO(N,H){let W=H.pathname.split("/").filter(Boolean)[2];if(!W){if(N.method==="GET")return L(await YO());return Z(405,"Method not allowed")}if(W==="config"){if(N.method==="PUT"){let Y=await M(N);if(typeof Y.enabled!=="boolean"&&!Y.settings)return Z(400,"Nothing to update: pass enabled and/or settings");return await GO(Y),L({ok:!0})}return Z(405,"Method not allowed")}if(W==="file"){if(N.method==="GET"){let Y=A(H.searchParams.get("path"),"path"),G={path:Y,content:await $O(Y)};return L(G)}if(N.method==="PUT"){let Y=await M(N);if(A(Y.path,"path"),typeof Y.content!=="string")return Z(400,"Missing or invalid field: content");return await UO(Y.path,Y.content),L({ok:!0})}if(N.method==="DELETE"){let Y=A(H.searchParams.get("path"),"path");return await QO(Y),L({ok:!0})}return Z(405,"Method not allowed")}return Z(404,`Unknown memories endpoint: ${H.pathname}`)}var AY=300000,FH=null;async function ZO(N){if(N.method!=="GET")return Z(405,"Method not allowed");if(FH&&Date.now()-FH.at<AY)return L({models:FH.models});let O=((await C("model/list",{})).data??[]).filter((Y)=>!Y.hidden).map((Y)=>({id:Y.id,model:Y.model,displayName:Y.displayName,description:Y.description,isDefault:Y.isDefault,defaultReasoningEffort:Y.defaultReasoningEffort,supportedReasoningEfforts:Y.supportedReasoningEfforts??[]}));return FH={at:Date.now(),models:O},L({models:O})}async function zH(){let N=await C("account/read",{});return{account:N.account??null,requiresOpenaiAuth:N.requiresOpenaiAuth,pendingLogin:YH(),lastLoginResult:Y1()}}async function LO(N,H){if(H.pathname==="/api/account"){if(N.method!=="GET")return Z(405,"Method not allowed");return L(await zH())}if(H.pathname==="/api/account/login"&&N.method==="POST"){let O=await M(N),W;if(O.type==="chatgpt"||O.type==="chatgptDeviceCode")W={type:O.type};else if(O.type==="apiKey")W={type:"apiKey",apiKey:A(O.apiKey,"apiKey")};else throw new B("type must be one of: chatgpt, chatgptDeviceCode, apiKey");let Y=YH();if(Y)await C("account/login/cancel",{loginId:Y.loginId}).catch(()=>{});GH();let G=await C("account/login/start",W);if((G.type==="chatgpt"||G.type==="chatgptDeviceCode")&&G.loginId){let $={loginId:G.loginId,type:G.type,authUrl:G.authUrl,userCode:G.userCode,verificationUrl:G.verificationUrl,startedAt:new Date().toISOString()};G1($)}return L(await zH())}if(H.pathname==="/api/account/login/cancel"&&N.method==="POST"){let O=YH();if(O)await C("account/login/cancel",{loginId:O.loginId}).catch(()=>{});return GH(),L(await zH())}if(H.pathname==="/api/account/logout"&&N.method==="POST")return await C("account/logout",{}),GH(),L(await zH());return Z(404,`Not found: ${H.pathname}`)}function JY(N){if(!N)return null;return N.replace(/^([a-z0-9+.-]+:\/\/[^:@/]+):[^@/]+@/i,"$1:\u2022\u2022\u2022\u2022@")}function FO(){let N=kH(),H=yH();return{browserProxy:{proxyUrl:JY(N.value),source:N.source,noProxy:H.value,noProxySource:H.source}}}async function zO(N,H){if(H.pathname==="/api/settings"&&N.method==="GET")return L(FO());if(H.pathname==="/api/settings/browser-proxy"&&N.method==="PUT"){let O=await M(N);if(O.proxyUrl!==void 0&&O.proxyUrl!==null&&O.proxyUrl.trim())try{if(!new URL(O.proxyUrl.trim()).hostname)throw Error("missing host")}catch{return Z(400,"Invalid proxy URL \u2014 expected e.g. http://user:pass@host:port")}return await y0({...O.proxyUrl!==void 0?{browserProxy:O.proxyUrl}:{},...O.noProxy!==void 0?{browserNoProxy:O.noProxy}:{}}),L(FO())}if(N.method!=="GET"&&N.method!=="PUT")return Z(405,"Method not allowed");return Z(404,`Unknown settings endpoint: ${H.pathname}`)}import{promises as BN}from"fs";import DO from"path";import{randomUUID as EY}from"crypto";function cN(N,H,O,W){let Y=new Set,G=N.trim()!=="*";for(let $ of N.split(",")){let U=$.trim();if(!U)throw Error(`Invalid ${W} field: empty term`);let Q=U,X=1,F=U.indexOf("/");if(F!==-1){if(Q=U.slice(0,F),X=Number(U.slice(F+1)),!Number.isInteger(X)||X<=0)throw Error(`Invalid step in ${W}: ${U}`)}let K,R;if(Q==="*")K=H,R=O;else if(Q.includes("-")){let[f,$N]=Q.split("-");K=Number(f),R=Number($N)}else K=Number(Q),R=K;if(!Number.isInteger(K)||!Number.isInteger(R))throw Error(`Invalid ${W} value: ${U}`);if(K<H||R>O||K>R)throw Error(`${W} out of range (${H}-${O}): ${U}`);for(let f=K;f<=R;f+=X)Y.add(f)}return{set:Y,restricted:G}}function KO(N){let H=N.trim().split(/\s+/);if(H.length!==5)throw Error(`Cron must have 5 fields (min hour dom month dow); got ${H.length}`);let O=cN(H[0],0,59,"minute"),W=cN(H[1],0,23,"hour"),Y=cN(H[2],1,31,"day-of-month"),G=cN(H[3],1,12,"month"),$=cN(H[4],0,7,"day-of-week"),U=new Set;for(let Q of $.set)U.add(Q===7?0:Q);return{minute:O.set,hour:W.set,dom:Y.set,month:G.set,dow:U,domRestricted:Y.restricted,dowRestricted:$.restricted}}function AO(N){try{return KO(N),null}catch(H){return H instanceof Error?H.message:"Invalid cron expression"}}function BY(N){return new Intl.DateTimeFormat("en-US",{timeZone:N,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"})}function JO(N,H){if(!H)return{year:N.getFullYear(),month:N.getMonth()+1,day:N.getDate(),hour:N.getHours(),minute:N.getMinutes(),second:N.getSeconds()};let O={};for(let W of BY(H).formatToParts(N))if(W.type!=="literal")O[W.type]=Number(W.value);return{year:O.year,month:O.month,day:O.day,hour:O.hour,minute:O.minute,second:O.second}}function DY(N,H){return new Date(Date.UTC(N,H,0)).getUTCDate()}function CY(N){return new Date(Date.UTC(N.year,N.month-1,N.day)).getUTCDay()}function VO(N){if(N.minute++,N.minute<60)return;if(N.minute=0,N.hour++,N.hour<24)return;if(N.hour=0,N.day++,N.day<=DY(N.year,N.month))return;if(N.day=1,N.month++,N.month<=12)return;N.month=1,N.year++}function SY(N,H){if(!N.minute.has(H.minute))return!1;if(!N.hour.has(H.hour))return!1;if(!N.month.has(H.month))return!1;let O=N.dom.has(H.day),W=N.dow.has(CY(H));if(N.domRestricted&&N.dowRestricted)return O||W;if(N.domRestricted)return O;if(N.dowRestricted)return W;return!0}function MO(N,H){let O=JO(N,H);return Date.UTC(O.year,O.month-1,O.day,O.hour,O.minute,O.second)-N.getTime()}function RY(N,H){if(!H)return new Date(N.year,N.month-1,N.day,N.hour,N.minute,0,0);let O=Date.UTC(N.year,N.month-1,N.day,N.hour,N.minute,0),W=MO(new Date(O),H),Y=O-W,G=MO(new Date(Y),H);if(G!==W)Y=O-G;return new Date(Y)}var TY=4216320;function BO(N,H,O){let W=KO(N),Y=JO(H,O),G={year:Y.year,month:Y.month,day:Y.day,hour:Y.hour,minute:Y.minute};VO(G);for(let $=0;$<TY;$++){if(SY(W,G))return RY(G,O);VO(G)}return null}var _Y={sandbox:"workspaceWrite",approvalPolicy:"onRequest",approvalsReviewer:"auto_review",effort:"medium"};function wY(N){return N.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40)}function pH(N){return DO.join(DN(),`${N}.json`)}async function CO(){await BN.mkdir(DN(),{recursive:!0})}async function nH(N){await CO(),await BN.writeFile(pH(N.id),JSON.stringify(N,null,2),"utf8")}function aH(N,H){if(!N.enabled)return null;if(N.kind==="once"){if(!N.runAt)return null;let W=new Date(N.runAt);if(Number.isNaN(W.getTime()))return null;if(N.lastRunAt)return null;return W.toISOString()}if(!N.cron)return null;let O=BO(N.cron,H,N.tz);return O?O.toISOString():null}function SO(N,H){if(H==="cron"){if(!N.cron)throw Error("cron expression is required for a cron schedule");let O=AO(N.cron);if(O)throw Error(`Invalid cron expression: ${O}`)}else{if(!N.runAt)throw Error("runAt is required for a one-off schedule");if(Number.isNaN(new Date(N.runAt).getTime()))throw Error("runAt is not a valid datetime")}if(N.tz)try{new Intl.DateTimeFormat("en-US",{timeZone:N.tz})}catch{throw Error(`Unknown timezone: ${N.tz}`)}}async function oH(N){await CO();let H;try{H=await BN.readdir(DN())}catch{return[]}let O=[];for(let W of H){if(!W.endsWith(".json"))continue;try{let Y=await BN.readFile(DO.join(DN(),W),"utf8"),G=JSON.parse(Y);if(N&&G.projectId!==N)continue;O.push(G)}catch{}}return O.sort((W,Y)=>Y.createdAt.localeCompare(W.createdAt)),O}async function VH(N){try{let H=await BN.readFile(pH(N),"utf8");return JSON.parse(H)}catch{return null}}async function RO(N){let H=N.name?.trim();if(!H)throw Error("Schedule name is required");if(!N.prompt?.trim())throw Error("Schedule prompt is required");let O=N.projectId??"default";if(!await VN(O))throw Error(`Unknown project: ${O}`);let W=N.kind??"cron";SO(N,W);let Y=`${wY(H)||"schedule"}-${EY().slice(0,8)}`,G=new Date,$={id:Y,name:H,projectId:O,prompt:N.prompt,kind:W,cron:W==="cron"?N.cron:void 0,runAt:W==="once"?new Date(N.runAt).toISOString():void 0,tz:N.tz,mode:{..._Y,...N.mode??{}},resume:N.resume??!1,threadRunId:null,enabled:N.enabled??!0,createdAt:G.toISOString(),lastRunAt:null,lastRunId:null,lastError:null,nextRunAt:null};return $.nextRunAt=aH($,G),await nH($),$}async function TO(N,H){let O=await VH(N);if(!O)return null;let W=H.kind??O.kind,Y={...O,name:H.name?.trim()||O.name,prompt:H.prompt??O.prompt,kind:W,cron:W==="cron"?H.cron??O.cron:void 0,runAt:W==="once"?H.runAt?new Date(H.runAt).toISOString():O.runAt:void 0,tz:H.tz!==void 0?H.tz||void 0:O.tz,mode:H.mode?{...O.mode,...H.mode}:O.mode,resume:H.resume??O.resume,enabled:H.enabled??O.enabled};if(SO(Y,W),W==="once"&&H.runAt&&Y.runAt!==O.runAt)Y.lastRunAt=null;return Y.nextRunAt=aH(Y,new Date),await nH(Y),Y}async function EO(N){try{return await BN.unlink(pH(N)),!0}catch{return!1}}function PY(N){return{sandbox:N.sandbox,approvalPolicy:N.approvalPolicy,approvalsReviewer:N.approvalsReviewer,model:N.model,effort:N.effort}}async function dH(N,H){let O=N.lastRunId??null,W=null,Y=N.threadRunId??null;try{let $=N.mode;if(N.resume&&Y&&await D(Y)){let U=await D(Y);if(U&&g(U.status))throw Error("previous run still active \u2014 skipped this fire");O=(await UH(Y,N.prompt,[],PY($))).id}else{let U=await LN({prompt:N.prompt,projectId:N.projectId,sandbox:$.sandbox,approvalPolicy:$.approvalPolicy,approvalsReviewer:$.approvalsReviewer,model:$.model,effort:$.effort,source:"schedule",scheduleId:N.id,scheduleName:N.name});if(O=U.id,N.resume)Y=U.id}}catch($){W=$ instanceof Error?$.message:String($)}let G={...N,lastRunAt:H.toISOString(),lastRunId:O,lastError:W,threadRunId:Y};return G.nextRunAt=aH(G,H),await nH(G),G}var iH=!1;async function _O(N=new Date){if(iH)return;iH=!0;try{let H=await oH();for(let O of H){if(!O.enabled||!O.nextRunAt)continue;let W=new Date(O.nextRunAt);if(Number.isNaN(W.getTime())||W.getTime()>N.getTime())continue;try{await dH(O,N)}catch(Y){console.error(`[schedules] fire failed for ${O.id}:`,Y)}}}catch(H){console.error("[schedules] tick failed:",H)}finally{iH=!1}}async function wO(N){let H=N.searchParams.get("project");if(H)return H;let O=N.searchParams.get("cwd");if(O){let W=uN(O);if(W&&await VN(W))return W;return z}return}async function PO(N,H){let O=H.pathname.split("/").filter(Boolean),W=O[2],Y=O[3];if(!W){if(N.method==="GET"){let G=await wO(H),$={schedules:await oH(G)};return L($)}if(N.method==="POST"){let G=await M(N);if(!G.projectId){let $=await wO(H);if($)G.projectId=$}try{let U={schedule:await RO(G)};return L(U,201)}catch($){return Z(400,$ instanceof Error?$.message:String($))}}return Z(405,"Method not allowed")}if(Y==="run"&&N.method==="POST"){let G=await VH(W);if(!G)return Z(404,`Schedule not found: ${W}`);let U={schedule:await dH(G,new Date)};return L(U)}if(Y)return Z(404,`Not found: ${H.pathname}`);if(N.method==="GET"){let G=await VH(W);return G?L({schedule:G}):Z(404,`Schedule not found: ${W}`)}if(N.method==="PUT"){let G=await M(N);try{let $=await TO(W,G);return $?L({schedule:$}):Z(404,`Schedule not found: ${W}`)}catch($){return Z(400,$ instanceof Error?$.message:String($))}}if(N.method==="DELETE")return await EO(W)?L({ok:!0}):Z(404,`Schedule not found: ${W}`);return Z(405,"Method not allowed")}async function fO(N,H){let O=new URL(N.url);try{if(O.pathname==="/api/health")return P1();if(O.pathname==="/api/status")return f1();if(O.pathname==="/api/files/watch")return H.upgrade(N,{data:{channel:"files"}})?void 0:Z(400,"WebSocket upgrade required");if(O.pathname.startsWith("/api/files/"))return await x1(N,O);if(O.pathname==="/api/projects"||O.pathname.startsWith("/api/projects/"))return await I1(N,O);if(O.pathname==="/api/runs"||O.pathname.startsWith("/api/runs/"))return await j1(N,O,H);if(O.pathname.startsWith("/api/browser/"))return await u1(N,O,H);if(O.pathname==="/api/skills"||O.pathname.startsWith("/api/skills/"))return await HO(N,O);if(O.pathname==="/api/mcp"||O.pathname.startsWith("/api/mcp/"))return await OO(N,O);if(O.pathname==="/api/memories"||O.pathname.startsWith("/api/memories/"))return await XO(N,O);if(O.pathname==="/api/models")return await ZO(N);if(O.pathname==="/api/account"||O.pathname.startsWith("/api/account/"))return await LO(N,O);if(O.pathname==="/api/settings"||O.pathname.startsWith("/api/settings/"))return await zO(N,O);if(O.pathname==="/api/schedules"||O.pathname.startsWith("/api/schedules/"))return await PO(N,O);return Z(404,`Not found: ${O.pathname}`)}catch(W){if(W instanceof oN)return Z(400,W.message);if(W instanceof B)return Z(400,W.message);if(xY(W))return Z(404,`Not found: ${O.searchParams.get("path")??O.pathname}`);return console.error(`[api] ${N.method} ${O.pathname} failed:`,W),Z(500,W instanceof Error?W.message:"Internal error")}}function xY(N){return typeof N==="object"&&N!==null&&"code"in N&&N.code==="ENOENT"}await eH();var MH=[k.resolve(import.meta.dir,"../ui-dist"),k.resolve(import.meta.dir,"../../ui/dist")].find((N)=>xO(k.join(N,"index.html")))??k.resolve(import.meta.dir,"../../ui/dist");try{let N=["mcp-server.ts","mcp-server.js"].map((H)=>k.join(import.meta.dir,H)).find((H)=>xO(H));if(N)await w1(N,lN);else console.warn("[daemon] mcp-server script not found next to daemon entry")}catch(N){console.warn("[daemon] could not register Jun MCP server:",N)}l0(k.join(import.meta.dir,".."));var yO=Bun.serve({hostname:AH,port:lN,async fetch(N,H){let O=new URL(N.url);if(O.pathname.startsWith("/api/"))return fO(N,H);let W=await bY(O.pathname);if(W)return W;return new Response("Jun daemon is running. Build the UI to enable the dashboard.",{status:200})},websocket:{idleTimeout:960,open(N){if(N.subscribe(N.data.channel),N.data.channel===YN){h1();let H=m1();if(H)N.send(H)}},message(N,H){if(N.data.channel===YN)l1(H)},close(N){if(N.unsubscribe(N.data.channel),N.data.channel===YN)c1()}}});K0(yO);try{kY(UN(),{recursive:!0},(N,H)=>{let O={type:"fs.changed",path:H?l(String(H)):null,ts:new Date().toISOString()};yO.publish("files",JSON.stringify(O))})}catch(N){console.warn("[daemon] workspace watcher unavailable:",N)}var yY=30000;setInterval(()=>{_O()},yY);console.log(`Jun daemon running at http://${AH}:${lN}`);console.log(`Workspace: ${k.resolve(J())}`);async function bY(N){let H=k.join(MH,"index.html");if(!await qY(H))return null;let O=k.normalize(decodeURIComponent(N)).replace(/^[/\\]+/,""),W=k.resolve(MH,O||"index.html"),Y=`${MH}${k.sep}`;if(W!==MH&&!W.startsWith(Y))return new Response("Not found",{status:404});if(await IY(W))return new Response(Bun.file(W),{headers:{"content-type":jY(W)}});return new Response(Bun.file(H),{headers:{"content-type":"text/html; charset=utf-8"}})}async function qY(N){try{return await kO(N),!0}catch{return!1}}async function IY(N){try{return(await kO(N)).isFile()}catch{return!1}}function jY(N){switch(k.extname(N)){case".css":return"text/css; charset=utf-8";case".html":return"text/html; charset=utf-8";case".js":return"text/javascript; charset=utf-8";case".json":return"application/json; charset=utf-8";case".svg":return"image/svg+xml";case".webp":return"image/webp";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".ico":return"image/x-icon";default:return"application/octet-stream"}}
335
+ `;return await P.mkdir(O,{recursive:!0}),await P.writeFile(T.join(O,"SKILL.md"),Y,"utf8"),hN(H),await mN(W,H)}async function NW(N,H,W=F){let O=BN(N,W);try{await P.access(O)}catch{throw new B(`Skill not found: ${N}`)}return await P.writeFile(T.join(O,"SKILL.md"),H,"utf8"),hN(W),await mN(N,W)}async function HW(N,H=F){let W=BN(N,H);try{return await P.rm(W,{recursive:!0,force:!1}),hN(H),!0}catch{return!1}}async function WW(N,H,W=F){let O=T.join(BN(N,W),"SKILL.md");await C("skills/config/write",{path:O,enabled:H,name:null}),hN(W)}async function OW(N){let H=N.trim();if(!H)return[];let{stdout:W}=await r1(["find",H],A(F),30000);return KY(W)}async function s1(N){await P.mkdir(AN(N),{recursive:!0});let H=await P.readdir(AN(N),{withFileTypes:!0});return new Set(H.filter((W)=>W.isDirectory()).map((W)=>W.name))}async function YW(N,H=F){let W=N.trim();if(!W)throw new B("Missing skill source");if(/[\s;&|`$(){}<>]/.test(W))throw new B("Invalid source \u2014 expected owner/repo[@skill] or a URL");let O=A(H),Y=await s1(H),{stdout:G,stderr:$}=await r1(["add",W,"-a","codex","--copy","-y"],O);hN(H);let Q=[...await s1(H)].filter((z)=>!Y.has(z));if(Q.length===0){let z=[G,$].filter(Boolean).join(`
336
+ `).trim();throw new B(`No skill installed from "${W}".${z?`
337
+ ${z}`:""}`)}let{skills:X}=await XH(H);return{installed:Q,skills:X,log:[G,$].filter(Boolean).join(`
338
+ `).trim()}}async function GW(N,H,W=F){let O=await mN(N,W);if(!O)throw new B(`Skill not found: ${N}`);let Y={prompt:H?.trim()||`Use the "${O.info.name}" skill to demonstrate what it does. Follow its instructions and report the result.`,projectId:W,skill:{name:O.info.name,path:T.join(BN(N,W),"SKILL.md")}};return zN(Y)}async function SY(N){let H=N.searchParams.get("project");if(H)return H;let W=N.searchParams.get("cwd");if(W){let O=iN(W);if(O&&await MN(O))return O}return F}async function $W(N,H){let W=H.pathname.split("/").filter(Boolean),O=W[2],Y=W[3],G=await SY(H);if(O==="registry"){if(Y==="search"&&N.method==="GET"){let $=H.searchParams.get("q")??"",U=await OW($);return L({results:U})}if(Y==="install"&&N.method==="POST"){let $=await M(N);J($.source,"source");let U=await YW($.source,G);return L(U,201)}return Z(404,`Unknown skills endpoint: ${H.pathname}`)}if(!O){if(N.method==="GET")return L(await XH(G));if(N.method==="POST"){let $=await M(N);J($.name,"name"),J($.description,"description");let U=await e1($,G);return L({skill:U},201)}return Z(405,"Method not allowed")}if(!Y)switch(N.method){case"GET":{let $=await mN(O,G);return $?L({skill:$}):Z(404,`Skill not found: ${O}`)}case"PUT":{let $=await M(N);J($.content,"content");let U=await NW(O,$.content,G);return L({skill:U})}case"DELETE":return await HW(O,G)?L({ok:!0}):Z(404,`Skill not found: ${O}`);default:return Z(405,"Method not allowed")}if(N.method!=="POST")return Z(405,"Method not allowed");switch(Y){case"enable":{let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");return await WW(O,$.enabled,G),L({ok:!0})}case"test":{let $=await M(N).catch(()=>({})),U=await GW(O,$.prompt,G);return L({run:U},201)}default:return Z(404,`Unknown skills endpoint: ${H.pathname}`)}}async function UW(N,H){let W=H.pathname.split("/").filter(Boolean),O=W[2];if(!O){if(N.method==="GET")return L(await T1());return Z(405,"Method not allowed")}if(O==="config"){if(N.method==="GET"){let Y={toml:await p()};return L(Y)}if(N.method==="PUT"){let Y=await M(N);return J(Y.toml,"toml"),await E1(Y.toml),L({ok:!0})}return Z(405,"Method not allowed")}if(O==="reload"&&N.method==="POST")return await f1(),L({ok:!0});if(O==="servers"){let Y=W[3];if(!Y){if(N.method==="POST"){let $=await M(N);return J($.name,"name"),await _1($),L({ok:!0},201)}return Z(405,"Method not allowed")}let G=W[4];if(G==="enable"&&N.method==="POST"){let $=await M(N);if(typeof $.enabled!=="boolean")return Z(400,"Missing or invalid field: enabled");return await P1(Y,$.enabled),L({ok:!0})}if(!G&&N.method==="DELETE")return await w1(Y)?L({ok:!0}):Z(404,`Server not found: ${Y}`);return Z(405,"Method not allowed")}return Z(404,`Unknown MCP endpoint: ${H.pathname}`)}import{promises as GN}from"fs";import cN from"path";function RY(){return cN.join(q(),"config.toml")}function LH(){return cN.join(q(),"memories")}async function QW(){let N=await p();return N.trim()?c(N):{}}function ZH(N){return typeof N==="object"&&N!==null?N:{}}function EY(N){let H=ZH(N.memories),W={};if(typeof H.generate_memories==="boolean")W.generateMemories=H.generate_memories;if(typeof H.use_memories==="boolean")W.useMemories=H.use_memories;if(typeof H.disable_on_external_context==="boolean")W.disableOnExternalContext=H.disable_on_external_context;if(typeof H.min_rate_limit_remaining_percent==="number")W.minRateLimitRemainingPercent=H.min_rate_limit_remaining_percent;return W}async function TY(){let N=LH(),H=[];async function W(O){let Y;try{Y=await GN.readdir(O,{withFileTypes:!0})}catch{return}for(let G of Y){let $=cN.join(O,G.name);if(G.isDirectory()){if(G.name===".git")continue;await W($)}else if(G.isFile()){let U=await GN.stat($);H.push({path:l(cN.relative(N,$)),name:G.name,size:U.size,modifiedAt:U.mtime.toISOString()})}}}return await W(N),H.sort((O,Y)=>Y.modifiedAt.localeCompare(O.modifiedAt)),H}async function _Y(){try{let H=((await C("experimentalFeature/list",{})).data??[]).find((W)=>W.name==="memories");return H?H.enabled:null}catch(N){return console.warn("[memories] experimentalFeature/list failed:",N),null}}async function XW(){let N=await QW();return{enabled:ZH(N.features).memories===!0,liveEnabled:await _Y(),settings:EY(N),files:await TY()}}async function ZW(N){let H=await QW();if(typeof N.enabled==="boolean"){let W=ZH(H.features);W.memories=N.enabled,H.features=W}if(N.settings){let W=ZH(H.memories),O=N.settings;if(typeof O.generateMemories==="boolean")W.generate_memories=O.generateMemories;if(typeof O.useMemories==="boolean")W.use_memories=O.useMemories;if(typeof O.disableOnExternalContext==="boolean")W.disable_on_external_context=O.disableOnExternalContext;if(typeof O.minRateLimitRemainingPercent==="number")W.min_rate_limit_remaining_percent=O.minRateLimitRemainingPercent;H.memories=W}if(await GN.writeFile(RY(),d(H),"utf8"),typeof N.enabled==="boolean")try{await C("experimentalFeature/enablement/set",{enablement:{memories:N.enabled}})}catch(W){console.warn("[memories] live enablement/set failed (applies on restart):",W)}}async function LW(N){let H=e(LH(),N);return GN.readFile(H,"utf8")}async function zW(N,H){let W=e(LH(),N);await GN.mkdir(cN.dirname(W),{recursive:!0}),await GN.writeFile(W,H,"utf8")}async function FW(N){let H=e(LH(),N);await GN.rm(H)}async function VW(N,H){let O=H.pathname.split("/").filter(Boolean)[2];if(!O){if(N.method==="GET")return L(await XW());return Z(405,"Method not allowed")}if(O==="config"){if(N.method==="PUT"){let Y=await M(N);if(typeof Y.enabled!=="boolean"&&!Y.settings)return Z(400,"Nothing to update: pass enabled and/or settings");return await ZW(Y),L({ok:!0})}return Z(405,"Method not allowed")}if(O==="file"){if(N.method==="GET"){let Y=J(H.searchParams.get("path"),"path"),G={path:Y,content:await LW(Y)};return L(G)}if(N.method==="PUT"){let Y=await M(N);if(J(Y.path,"path"),typeof Y.content!=="string")return Z(400,"Missing or invalid field: content");return await zW(Y.path,Y.content),L({ok:!0})}if(N.method==="DELETE"){let Y=J(H.searchParams.get("path"),"path");return await FW(Y),L({ok:!0})}return Z(405,"Method not allowed")}return Z(404,`Unknown memories endpoint: ${H.pathname}`)}var PY=300000,zH=null;async function MW(N){if(N.method!=="GET")return Z(405,"Method not allowed");if(zH&&Date.now()-zH.at<PY)return L({models:zH.models});let W=((await C("model/list",{})).data??[]).filter((Y)=>!Y.hidden).map((Y)=>({id:Y.id,model:Y.model,displayName:Y.displayName,description:Y.description,isDefault:Y.isDefault,defaultReasoningEffort:Y.defaultReasoningEffort,supportedReasoningEfforts:Y.supportedReasoningEfforts??[]}));return zH={at:Date.now(),models:W},L({models:W})}async function FH(){let N=await C("account/read",{});return{account:N.account??null,requiresOpenaiAuth:N.requiresOpenaiAuth,pendingLogin:YH(),lastLoginResult:U1()}}async function KW(N,H){if(H.pathname==="/api/account"){if(N.method!=="GET")return Z(405,"Method not allowed");return L(await FH())}if(H.pathname==="/api/account/login"&&N.method==="POST"){let W=await M(N),O;if(W.type==="chatgpt"||W.type==="chatgptDeviceCode")O={type:W.type};else if(W.type==="apiKey")O={type:"apiKey",apiKey:J(W.apiKey,"apiKey")};else throw new B("type must be one of: chatgpt, chatgptDeviceCode, apiKey");let Y=YH();if(Y)await C("account/login/cancel",{loginId:Y.loginId}).catch(()=>{});GH();let G=await C("account/login/start",O);if((G.type==="chatgpt"||G.type==="chatgptDeviceCode")&&G.loginId){let $={loginId:G.loginId,type:G.type,authUrl:G.authUrl,userCode:G.userCode,verificationUrl:G.verificationUrl,startedAt:new Date().toISOString()};Q1($)}return L(await FH())}if(H.pathname==="/api/account/login/cancel"&&N.method==="POST"){let W=YH();if(W)await C("account/login/cancel",{loginId:W.loginId}).catch(()=>{});return GH(),L(await FH())}if(H.pathname==="/api/account/logout"&&N.method==="POST")return await C("account/logout",{}),GH(),L(await FH());return Z(404,`Not found: ${H.pathname}`)}function fY(N){if(!N)return null;return N.replace(/^([a-z0-9+.-]+:\/\/[^:@/]+):[^@/]+@/i,"$1:\u2022\u2022\u2022\u2022@")}function JW(){let N=kH(),H=yH();return{browserProxy:{proxyUrl:fY(N.value),source:N.source,noProxy:H.value,noProxySource:H.source}}}async function AW(N,H){if(H.pathname==="/api/settings"&&N.method==="GET")return L(JW());if(H.pathname==="/api/settings/browser-proxy"&&N.method==="PUT"){let W=await M(N);if(W.proxyUrl!==void 0&&W.proxyUrl!==null&&W.proxyUrl.trim())try{if(!new URL(W.proxyUrl.trim()).hostname)throw Error("missing host")}catch{return Z(400,"Invalid proxy URL \u2014 expected e.g. http://user:pass@host:port")}return await I0({...W.proxyUrl!==void 0?{browserProxy:W.proxyUrl}:{},...W.noProxy!==void 0?{browserNoProxy:W.noProxy}:{}}),L(JW())}if(N.method!=="GET"&&N.method!=="PUT")return Z(405,"Method not allowed");return Z(404,`Unknown settings endpoint: ${H.pathname}`)}import{promises as DN}from"fs";import TW from"path";import{randomUUID as jY}from"crypto";function lN(N,H,W,O){let Y=new Set,G=N.trim()!=="*";for(let $ of N.split(",")){let U=$.trim();if(!U)throw Error(`Invalid ${O} field: empty term`);let Q=U,X=1,z=U.indexOf("/");if(z!==-1){if(Q=U.slice(0,z),X=Number(U.slice(z+1)),!Number.isInteger(X)||X<=0)throw Error(`Invalid step in ${O}: ${U}`)}let K,R;if(Q==="*")K=H,R=W;else if(Q.includes("-")){let[f,$N]=Q.split("-");K=Number(f),R=Number($N)}else K=Number(Q),R=K;if(!Number.isInteger(K)||!Number.isInteger(R))throw Error(`Invalid ${O} value: ${U}`);if(K<H||R>W||K>R)throw Error(`${O} out of range (${H}-${W}): ${U}`);for(let f=K;f<=R;f+=X)Y.add(f)}return{set:Y,restricted:G}}function CW(N){let H=N.trim().split(/\s+/);if(H.length!==5)throw Error(`Cron must have 5 fields (min hour dom month dow); got ${H.length}`);let W=lN(H[0],0,59,"minute"),O=lN(H[1],0,23,"hour"),Y=lN(H[2],1,31,"day-of-month"),G=lN(H[3],1,12,"month"),$=lN(H[4],0,7,"day-of-week"),U=new Set;for(let Q of $.set)U.add(Q===7?0:Q);return{minute:W.set,hour:O.set,dom:Y.set,month:G.set,dow:U,domRestricted:Y.restricted,dowRestricted:$.restricted}}function SW(N){try{return CW(N),null}catch(H){return H instanceof Error?H.message:"Invalid cron expression"}}function xY(N){return new Intl.DateTimeFormat("en-US",{timeZone:N,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"})}function RW(N,H){if(!H)return{year:N.getFullYear(),month:N.getMonth()+1,day:N.getDate(),hour:N.getHours(),minute:N.getMinutes(),second:N.getSeconds()};let W={};for(let O of xY(H).formatToParts(N))if(O.type!=="literal")W[O.type]=Number(O.value);return{year:W.year,month:W.month,day:W.day,hour:W.hour,minute:W.minute,second:W.second}}function kY(N,H){return new Date(Date.UTC(N,H,0)).getUTCDate()}function yY(N){return new Date(Date.UTC(N.year,N.month-1,N.day)).getUTCDay()}function BW(N){if(N.minute++,N.minute<60)return;if(N.minute=0,N.hour++,N.hour<24)return;if(N.hour=0,N.day++,N.day<=kY(N.year,N.month))return;if(N.day=1,N.month++,N.month<=12)return;N.month=1,N.year++}function bY(N,H){if(!N.minute.has(H.minute))return!1;if(!N.hour.has(H.hour))return!1;if(!N.month.has(H.month))return!1;let W=N.dom.has(H.day),O=N.dow.has(yY(H));if(N.domRestricted&&N.dowRestricted)return W||O;if(N.domRestricted)return W;if(N.dowRestricted)return O;return!0}function DW(N,H){let W=RW(N,H);return Date.UTC(W.year,W.month-1,W.day,W.hour,W.minute,W.second)-N.getTime()}function qY(N,H){if(!H)return new Date(N.year,N.month-1,N.day,N.hour,N.minute,0,0);let W=Date.UTC(N.year,N.month-1,N.day,N.hour,N.minute,0),O=DW(new Date(W),H),Y=W-O,G=DW(new Date(Y),H);if(G!==O)Y=W-G;return new Date(Y)}var IY=4216320;function EW(N,H,W){let O=CW(N),Y=RW(H,W),G={year:Y.year,month:Y.month,day:Y.day,hour:Y.hour,minute:Y.minute};BW(G);for(let $=0;$<IY;$++){if(bY(O,G))return qY(G,W);BW(G)}return null}var gY={sandbox:"workspaceWrite",approvalPolicy:"onRequest",approvalsReviewer:"auto_review",effort:"medium"};function vY(N){return N.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40)}function oH(N){return TW.join(CN(),`${N}.json`)}async function _W(){await DN.mkdir(CN(),{recursive:!0})}async function dH(N){await _W(),await DN.writeFile(oH(N.id),JSON.stringify(N,null,2),"utf8")}function sH(N,H){if(!N.enabled)return null;if(N.kind==="once"){if(!N.runAt)return null;let O=new Date(N.runAt);if(Number.isNaN(O.getTime()))return null;if(N.lastRunAt)return null;return O.toISOString()}if(!N.cron)return null;let W=EW(N.cron,H,N.tz);return W?W.toISOString():null}function wW(N,H){if(H==="cron"){if(!N.cron)throw Error("cron expression is required for a cron schedule");let W=SW(N.cron);if(W)throw Error(`Invalid cron expression: ${W}`)}else{if(!N.runAt)throw Error("runAt is required for a one-off schedule");if(Number.isNaN(new Date(N.runAt).getTime()))throw Error("runAt is not a valid datetime")}if(N.tz)try{new Intl.DateTimeFormat("en-US",{timeZone:N.tz})}catch{throw Error(`Unknown timezone: ${N.tz}`)}}async function tH(N){await _W();let H;try{H=await DN.readdir(CN())}catch{return[]}let W=[];for(let O of H){if(!O.endsWith(".json"))continue;try{let Y=await DN.readFile(TW.join(CN(),O),"utf8"),G=JSON.parse(Y);if(N&&G.projectId!==N)continue;W.push(G)}catch{}}return W.sort((O,Y)=>Y.createdAt.localeCompare(O.createdAt)),W}async function VH(N){try{let H=await DN.readFile(oH(N),"utf8");return JSON.parse(H)}catch{return null}}async function PW(N){let H=N.name?.trim();if(!H)throw Error("Schedule name is required");if(!N.prompt?.trim())throw Error("Schedule prompt is required");let W=N.projectId??"default";if(!await MN(W))throw Error(`Unknown project: ${W}`);let O=N.kind??"cron";wW(N,O);let Y=`${vY(H)||"schedule"}-${jY().slice(0,8)}`,G=new Date,$={id:Y,name:H,projectId:W,prompt:N.prompt,kind:O,cron:O==="cron"?N.cron:void 0,runAt:O==="once"?new Date(N.runAt).toISOString():void 0,tz:N.tz,mode:{...gY,...N.mode??{}},resume:N.resume??!1,threadRunId:null,enabled:N.enabled??!0,createdAt:G.toISOString(),lastRunAt:null,lastRunId:null,lastError:null,nextRunAt:null};return $.nextRunAt=sH($,G),await dH($),$}async function fW(N,H){let W=await VH(N);if(!W)return null;let O=H.kind??W.kind,Y={...W,name:H.name?.trim()||W.name,prompt:H.prompt??W.prompt,kind:O,cron:O==="cron"?H.cron??W.cron:void 0,runAt:O==="once"?H.runAt?new Date(H.runAt).toISOString():W.runAt:void 0,tz:H.tz!==void 0?H.tz||void 0:W.tz,mode:H.mode?{...W.mode,...H.mode}:W.mode,resume:H.resume??W.resume,enabled:H.enabled??W.enabled};if(wW(Y,O),O==="once"&&H.runAt&&Y.runAt!==W.runAt)Y.lastRunAt=null;return Y.nextRunAt=sH(Y,new Date),await dH(Y),Y}async function xW(N){try{return await DN.unlink(oH(N)),!0}catch{return!1}}function hY(N){return{sandbox:N.sandbox,approvalPolicy:N.approvalPolicy,approvalsReviewer:N.approvalsReviewer,model:N.model,effort:N.effort}}async function rH(N,H){let W=N.lastRunId??null,O=null,Y=N.threadRunId??null;try{let $=N.mode;if(N.resume&&Y&&await D(Y)){let U=await D(Y);if(U&&g(U.status))throw Error("previous run still active \u2014 skipped this fire");W=(await UH(Y,N.prompt,[],hY($))).id}else{let U=await zN({prompt:N.prompt,projectId:N.projectId,sandbox:$.sandbox,approvalPolicy:$.approvalPolicy,approvalsReviewer:$.approvalsReviewer,model:$.model,effort:$.effort,source:"schedule",scheduleId:N.id,scheduleName:N.name});if(W=U.id,N.resume)Y=U.id}}catch($){O=$ instanceof Error?$.message:String($)}let G={...N,lastRunAt:H.toISOString(),lastRunId:W,lastError:O,threadRunId:Y};return G.nextRunAt=sH(G,H),await dH(G),G}var aH=!1;async function kW(N=new Date){if(aH)return;aH=!0;try{let H=await tH();for(let W of H){if(!W.enabled||!W.nextRunAt)continue;let O=new Date(W.nextRunAt);if(Number.isNaN(O.getTime())||O.getTime()>N.getTime())continue;try{await rH(W,N)}catch(Y){console.error(`[schedules] fire failed for ${W.id}:`,Y)}}}catch(H){console.error("[schedules] tick failed:",H)}finally{aH=!1}}async function yW(N){let H=N.searchParams.get("project");if(H)return H;let W=N.searchParams.get("cwd");if(W){let O=iN(W);if(O&&await MN(O))return O;return F}return}async function bW(N,H){let W=H.pathname.split("/").filter(Boolean),O=W[2],Y=W[3];if(!O){if(N.method==="GET"){let G=await yW(H),$={schedules:await tH(G)};return L($)}if(N.method==="POST"){let G=await M(N);if(!G.projectId){let $=await yW(H);if($)G.projectId=$}try{let U={schedule:await PW(G)};return L(U,201)}catch($){return Z(400,$ instanceof Error?$.message:String($))}}return Z(405,"Method not allowed")}if(Y==="run"&&N.method==="POST"){let G=await VH(O);if(!G)return Z(404,`Schedule not found: ${O}`);let U={schedule:await rH(G,new Date)};return L(U)}if(Y)return Z(404,`Not found: ${H.pathname}`);if(N.method==="GET"){let G=await VH(O);return G?L({schedule:G}):Z(404,`Schedule not found: ${O}`)}if(N.method==="PUT"){let G=await M(N);try{let $=await fW(O,G);return $?L({schedule:$}):Z(404,`Schedule not found: ${O}`)}catch($){return Z(400,$ instanceof Error?$.message:String($))}}if(N.method==="DELETE")return await xW(O)?L({ok:!0}):Z(404,`Schedule not found: ${O}`);return Z(405,"Method not allowed")}async function qW(N,H){let W=new URL(N.url);try{if(W.pathname==="/api/health")return b1();if(W.pathname==="/api/status")return q1();if(W.pathname==="/api/files/watch")return H.upgrade(N,{data:{channel:"files"}})?void 0:Z(400,"WebSocket upgrade required");if(W.pathname.startsWith("/api/files/"))return await I1(N,W);if(W.pathname==="/api/projects"||W.pathname.startsWith("/api/projects/"))return await m1(N,W);if(W.pathname==="/api/runs"||W.pathname.startsWith("/api/runs/"))return await c1(N,W,H);if(W.pathname.startsWith("/api/browser/"))return await o1(N,W,H);if(W.pathname==="/api/skills"||W.pathname.startsWith("/api/skills/"))return await $W(N,W);if(W.pathname==="/api/mcp"||W.pathname.startsWith("/api/mcp/"))return await UW(N,W);if(W.pathname==="/api/memories"||W.pathname.startsWith("/api/memories/"))return await VW(N,W);if(W.pathname==="/api/models")return await MW(N);if(W.pathname==="/api/account"||W.pathname.startsWith("/api/account/"))return await KW(N,W);if(W.pathname==="/api/settings"||W.pathname.startsWith("/api/settings/"))return await AW(N,W);if(W.pathname==="/api/schedules"||W.pathname.startsWith("/api/schedules/"))return await bW(N,W);return Z(404,`Not found: ${W.pathname}`)}catch(O){if(O instanceof dN)return Z(400,O.message);if(O instanceof B)return Z(400,O.message);if(cY(O))return Z(404,`Not found: ${W.searchParams.get("path")??W.pathname}`);return console.error(`[api] ${N.method} ${W.pathname} failed:`,O),Z(500,O instanceof Error?O.message:"Internal error")}}function cY(N){return typeof N==="object"&&N!==null&&"code"in N&&N.code==="ENOENT"}await W0();var MH=[k.resolve(import.meta.dir,"../ui-dist"),k.resolve(import.meta.dir,"../../ui/dist")].find((N)=>IW(k.join(N,"index.html")))??k.resolve(import.meta.dir,"../../ui/dist");try{let N=["mcp-server.ts","mcp-server.js"].map((H)=>k.join(import.meta.dir,H)).find((H)=>IW(H));if(N)await x1(N,uN);else console.warn("[daemon] mcp-server script not found next to daemon entry")}catch(N){console.warn("[daemon] could not register Jun MCP server:",N)}p0(k.join(import.meta.dir,".."));var gW=Bun.serve({hostname:JH,port:uN,async fetch(N,H){let W=new URL(N.url);if(W.pathname.startsWith("/api/"))return qW(N,H);let O=await iY(W.pathname);if(O)return O;return new Response("Jun daemon is running. Build the UI to enable the dashboard.",{status:200})},websocket:{idleTimeout:960,open(N){if(N.subscribe(N.data.channel),N.data.channel===YN){i1();let H=p1();if(H)N.send(H)}},message(N,H){if(N.data.channel===YN)a1(H)},close(N){if(N.unsubscribe(N.data.channel),N.data.channel===YN)n1()}}});B0(gW);try{lY(UN(),{recursive:!0},(N,H)=>{let W={type:"fs.changed",path:H?l(String(H)):null,ts:new Date().toISOString()};gW.publish("files",JSON.stringify(W))})}catch(N){console.warn("[daemon] workspace watcher unavailable:",N)}var uY=30000;setInterval(()=>{kW()},uY);console.log(`Jun daemon running at http://${JH}:${uN}`);console.log(`Workspace: ${k.resolve(A())}`);async function iY(N){let H=k.join(MH,"index.html");if(!await pY(H))return null;let W=k.normalize(decodeURIComponent(N)).replace(/^[/\\]+/,""),O=k.resolve(MH,W||"index.html"),Y=`${MH}${k.sep}`;if(O!==MH&&!O.startsWith(Y))return new Response("Not found",{status:404});if(await nY(O))return new Response(Bun.file(O),{headers:{"content-type":aY(O)}});return new Response(Bun.file(H),{headers:{"content-type":"text/html; charset=utf-8"}})}async function pY(N){try{return await jW(N),!0}catch{return!1}}async function nY(N){try{return(await jW(N)).isFile()}catch{return!1}}function aY(N){switch(k.extname(N)){case".css":return"text/css; charset=utf-8";case".html":return"text/html; charset=utf-8";case".js":return"text/javascript; charset=utf-8";case".json":return"application/json; charset=utf-8";case".svg":return"image/svg+xml";case".webp":return"image/webp";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".ico":return"image/x-icon";default:return"application/octet-stream"}}