@deepseek-insight/dsi 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/.agents/skills/{dsi-gb-verifier → glass-dsi}/SKILL.md +57 -5
  2. package/.agents/skills/glass-dsi/references/cdp-verification.md +132 -0
  3. package/.agents/skills/glass-dsi/scripts/_connect.mjs +81 -0
  4. package/.agents/skills/glass-dsi/scripts/glass-url.mjs +48 -0
  5. package/.agents/skills/glass-dsi/scripts/glass.mjs +84 -0
  6. package/.agents/skills/glass-url/SKILL.md +117 -0
  7. package/.agents/skills/glass-url/scripts/_args.mjs +49 -0
  8. package/.agents/skills/glass-url/scripts/_connect.mjs +99 -0
  9. package/.agents/skills/glass-url/scripts/glass-url.mjs +114 -0
  10. package/bin/dsi.mjs +23 -74
  11. package/bin/lib/zai-patch.mjs +115 -0
  12. package/build/client/_app/immutable/assets/0.Ch5VtsKp.css +2 -0
  13. package/build/client/_app/immutable/assets/2.D0QOh44D.css +1 -0
  14. package/build/client/_app/immutable/chunks/{DwcY-69G.js → 02Wfo2G3.js} +1 -1
  15. package/build/client/_app/immutable/chunks/0Tfhif1V.js +3 -0
  16. package/build/client/_app/immutable/chunks/0ruuBBbh.js +2 -0
  17. package/build/client/_app/immutable/chunks/{DUCaFYlx.js → 4bHE1npv.js} +1 -1
  18. package/build/client/_app/immutable/chunks/{4cwyag_I.js → B4hDUAJl.js} +1 -1
  19. package/build/client/_app/immutable/chunks/{Cr2ck_ss.js → BIPXB-2I.js} +1 -1
  20. package/build/client/_app/immutable/chunks/{CeLBjOd9.js → BIgv-kQR.js} +1 -1
  21. package/build/client/_app/immutable/chunks/BK6k1nBs.js +1 -0
  22. package/build/client/_app/immutable/chunks/{SN3Efo-Q.js → BKwmKcDY.js} +1 -1
  23. package/build/client/_app/immutable/chunks/{CRFuOqJI.js → BORjuqef.js} +1 -1
  24. package/build/client/_app/immutable/chunks/{CH_bR_0j.js → BPmZB0-N.js} +1 -1
  25. package/build/client/_app/immutable/chunks/BROtno1Y.js +1 -0
  26. package/build/client/_app/immutable/chunks/{DEVxi5CK.js → BT5Iel00.js} +1 -1
  27. package/build/client/_app/immutable/chunks/{DdI16loP.js → BX3y_1Hh.js} +1 -1
  28. package/build/client/_app/immutable/chunks/{DuiFyTVb.js → Bea1gxLq.js} +1 -1
  29. package/build/client/_app/immutable/chunks/{D0uxHECr.js → BpkpgvVw.js} +1 -1
  30. package/build/client/_app/immutable/chunks/{CB55Rp7-.js → BreZS7EW.js} +1 -1
  31. package/build/client/_app/immutable/chunks/{BmDADyfH.js → BsS_byzk.js} +1 -1
  32. package/build/client/_app/immutable/chunks/{BWRXzjmQ.js → Bslg-dr5.js} +1 -1
  33. package/build/client/_app/immutable/chunks/{BkYT72a1.js → C-YczRN1.js} +1 -1
  34. package/build/client/_app/immutable/chunks/{DBKMIEwD.js → C2aW4lzo.js} +1 -1
  35. package/build/client/_app/immutable/chunks/{C4gs6zoI.js → C2qFXaz5.js} +1 -1
  36. package/build/client/_app/immutable/chunks/{BBd0nTHG.js → C5RyRpOh.js} +1 -1
  37. package/build/client/_app/immutable/chunks/{DJQr4efH.js → C5iHDVU_.js} +1 -1
  38. package/build/client/_app/immutable/chunks/{B4F5liKq.js → C7opVlLF.js} +1 -1
  39. package/build/client/_app/immutable/chunks/{DIxy2USu.js → CAuEkmZ4.js} +1 -1
  40. package/build/client/_app/immutable/chunks/{BO99LSSA.js → CIkiqgtA.js} +1 -1
  41. package/build/client/_app/immutable/chunks/{Bpd0I3U7.js → CJesWaZn.js} +1 -1
  42. package/build/client/_app/immutable/chunks/{at6PQqQ4.js → CRsoS5Y9.js} +1 -1
  43. package/build/client/_app/immutable/chunks/CTWtsoJD.js +6 -0
  44. package/build/client/_app/immutable/chunks/CWk5gmU2.js +1 -0
  45. package/build/client/_app/immutable/chunks/{lF8CNVOA.js → CXkrluSK.js} +1 -1
  46. package/build/client/_app/immutable/chunks/{DmRY6FWm.js → C_8kFZ_X.js} +4 -4
  47. package/build/client/_app/immutable/chunks/{D6KenyiF.js → Ch7hUoAH.js} +1 -1
  48. package/build/client/_app/immutable/chunks/{b4-Ro8NH.js → ChmmHPdM.js} +1 -1
  49. package/build/client/_app/immutable/chunks/{DfUgh5E_.js → CjajmcJs.js} +1 -1
  50. package/build/client/_app/immutable/chunks/{q5PRaRZk.js → Ck6GS6Vb.js} +1 -1
  51. package/build/client/_app/immutable/chunks/{eFcFJ9Ld.js → ClGoDr_f.js} +1 -1
  52. package/build/client/_app/immutable/chunks/{BQC6O_RV.js → ClqGHlec.js} +1 -1
  53. package/build/client/_app/immutable/chunks/{zypfUZYM.js → CnW6hje6.js} +1 -1
  54. package/build/client/_app/immutable/chunks/{OW5Q7tGb.js → CpI6VYCH.js} +1 -1
  55. package/build/client/_app/immutable/chunks/{BXKc4uuX.js → CygwwaiE.js} +1 -1
  56. package/build/client/_app/immutable/chunks/{Bqwvv7Vf.js → CyhZtsZO.js} +35 -35
  57. package/build/client/_app/immutable/chunks/{BenkQ_4r.js → D-E2Noqq.js} +1 -1
  58. package/build/client/_app/immutable/chunks/{DuRZnRVw.js → D4Btzp_A.js} +1 -1
  59. package/build/client/_app/immutable/chunks/{CdaJvl_A.js → D4C3Jijv.js} +1 -1
  60. package/build/client/_app/immutable/chunks/D9jhmf3I.js +1 -0
  61. package/build/client/_app/immutable/chunks/{Cf0aMC4n.js → DCw0gAtv.js} +1 -1
  62. package/build/client/_app/immutable/chunks/{B6bTO8_7.js → DEW3KpiC.js} +1 -1
  63. package/build/client/_app/immutable/chunks/{O6xxeEm8.js → DYLFbKJe.js} +1 -1
  64. package/build/client/_app/immutable/chunks/{BsBBq-Qk.js → DYu7kgVa.js} +1 -1
  65. package/build/client/_app/immutable/chunks/Dfexc5qV.js +1 -0
  66. package/build/client/_app/immutable/chunks/{kzciT-3i.js → DhmUE8Ri.js} +1 -1
  67. package/build/client/_app/immutable/chunks/{DdJNsJBH.js → DjwX3rAC.js} +1 -1
  68. package/build/client/_app/immutable/chunks/{CajOZJDl.js → DlOfy8Sx.js} +1 -1
  69. package/build/client/_app/immutable/chunks/{CK5vhXvt.js → Do7Y1_MQ.js} +1 -1
  70. package/build/client/_app/immutable/chunks/{ap4GAVq-.js → Dq2XIb1m.js} +1 -1
  71. package/build/client/_app/immutable/chunks/{Czey8tDK.js → DuT_Qr5k.js} +1 -1
  72. package/build/client/_app/immutable/chunks/{4B6J_kM2.js → DyGggFea.js} +1 -1
  73. package/build/client/_app/immutable/chunks/{D0ChUnpi.js → Dym4i64U.js} +1 -1
  74. package/build/client/_app/immutable/chunks/FPsIAiN_.js +1 -0
  75. package/build/client/_app/immutable/chunks/{CevKuuic.js → GIczpP_D.js} +1 -1
  76. package/build/client/_app/immutable/chunks/{B2jrDnt8.js → LjOLSmU7.js} +1 -1
  77. package/build/client/_app/immutable/chunks/VtK73aN-.js +8 -0
  78. package/build/client/_app/immutable/chunks/{AcmOeh2U.js → ZqoQH_jm.js} +1 -1
  79. package/build/client/_app/immutable/chunks/{BlwWx85l.js → aXn6rE_7.js} +1 -1
  80. package/build/client/_app/immutable/chunks/{Czc4_W7v.js → dUOeoGwg.js} +1 -1
  81. package/build/client/_app/immutable/chunks/f50lp1rr.js +1 -0
  82. package/build/client/_app/immutable/chunks/{7FnrqGK9.js → lvLrv1cG.js} +1 -1
  83. package/build/client/_app/immutable/chunks/{CZoElI5B.js → pt3_jHwh.js} +1 -1
  84. package/build/client/_app/immutable/chunks/{Byu_teLA.js → q8irUX-p.js} +1 -1
  85. package/build/client/_app/immutable/chunks/{CnxoqrkQ.js → qmOgUo3c.js} +1 -1
  86. package/build/client/_app/immutable/chunks/vpNeypNM.js +1 -0
  87. package/build/client/_app/immutable/chunks/{DU8C5thd.js → xvTPLhcB.js} +1 -1
  88. package/build/client/_app/immutable/chunks/{DFBKiA2Z.js → zp7hrpsC.js} +1 -1
  89. package/build/client/_app/immutable/entry/app.D4oc_iez.js +2 -0
  90. package/build/client/_app/immutable/entry/start.Xkr2MCWg.js +1 -0
  91. package/build/client/_app/immutable/nodes/0.fsrqKU9i.js +1 -0
  92. package/build/client/_app/immutable/nodes/1.3F37GwcO.js +1 -0
  93. package/build/client/_app/immutable/nodes/2.DsWNNw0K.js +340 -0
  94. package/build/client/_app/version.json +1 -1
  95. package/build/handler.js +6 -6
  96. package/build/index.js +6 -6
  97. package/build/server/chunks/chunks/{app-config.svelte.js-DCc9d7A4.js → app-config.svelte.js-BXjvTmJu.js} +4 -3
  98. package/build/server/chunks/chunks/{config.js-s6iKwHD7.js → config.js-r_jw_bQQ.js} +53 -2
  99. package/build/server/chunks/chunks/{db.js-CxxWK5sn.js → db.js-f2PmBjyD.js} +2 -2
  100. package/build/server/chunks/chunks/{db2.js-DwJ9lySe.js → db2.js-DkwY64WO.js} +2 -2
  101. package/build/server/chunks/chunks/{dsh-connection.js-Chtudg1p.js → dsh-connection.js-BW07Aicl.js} +18 -10
  102. package/build/server/chunks/chunks/{dsh-events.js-BUdvZQmd.js → dsh-events.js-BHf0lLZ5.js} +11 -1
  103. package/build/server/chunks/chunks/{git-probe.js-BX9FPnet.js → git-probe.js-CQqTV7XX.js} +3 -3
  104. package/build/server/chunks/chunks/{index-server.js-DmIEbDVz.js → index-server.js-CPkVoRxB.js} +2 -2
  105. package/build/server/chunks/chunks/{insight-config.js-Db5fe5Df.js → insight-config.js-C5-Rhh5A.js} +13 -4
  106. package/build/server/chunks/chunks/{internal2.js-CaZaz-a9.js → internal2.js-DbC8VGqD.js} +4 -4
  107. package/build/server/chunks/chunks/{registry.js-syaTZ_-A.js → registry.js-CWnRQ4vx.js} +430 -52
  108. package/build/server/chunks/chunks/{registry2.js-D3Pr1Rv9.js → registry2.js-CFzpvj9c.js} +17 -1
  109. package/build/server/chunks/chunks/{server.js-B1bDXhHu.js → server.js-Dijo7DtV.js} +2 -2
  110. package/build/server/chunks/chunks/{settings-document.js-BHESJ7im.js → settings-document.js-DxKURfc_.js} +2 -2
  111. package/build/server/chunks/chunks/{state.js-oYjf745s.js → state.js-DR4xiIVw.js} +5 -5
  112. package/build/server/chunks/chunks/{watcher.js-Ci9jsM5l.js → watcher.js-DvlNn8X0.js} +5 -5
  113. package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-CHaYhzjy.js → _server.ts.js-DItDXV23.js} +5 -5
  114. package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-CdyqA85c.js → _server.ts.js-Hor8QZb1.js} +8 -8
  115. package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-DO_FS5b4.js → _server.ts.js-CEvvsa8B.js} +8 -8
  116. package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/{_server.ts.js-D7Be4JUf.js → _server.ts.js-sXqf-okw.js} +5 -5
  117. package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-CGkm2H-U.js → _server.ts.js-Byj9ApJh.js} +5 -5
  118. package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/{_server.ts.js-D7SLUfOo.js → _server.ts.js-DOIsrzvg.js} +16 -9
  119. package/build/server/chunks/entries/endpoints/api/browser/_id_/element/{_server.ts.js-C3d_JV-q.js → _server.ts.js-Cq3gmRfE.js} +5 -5
  120. package/build/server/chunks/entries/endpoints/api/browser/_id_/history/_server.ts.js-BGSLIV0t.js +61 -0
  121. package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-DW0hyVML.js → _server.ts.js-8slca75-.js} +5 -5
  122. package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-Ev-hdBlf.js → _server.ts.js-CpbdTYds.js} +5 -5
  123. package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-DZ8-wocV.js → _server.ts.js-Bls9LtLY.js} +5 -5
  124. package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/{_server.ts.js-aapPrIQK.js → _server.ts.js-DqNi_iW_.js} +5 -5
  125. package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-DANA_hMd.js → _server.ts.js-DuXWwo7i.js} +5 -5
  126. package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-BqfseXFy.js → _server.ts.js-DXfqBDEw.js} +17 -5
  127. package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/{_server.ts.js-DFFF9qe-.js → _server.ts.js-Bgnl8lYs.js} +5 -5
  128. package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-ek6-D4Zm.js → _server.ts.js-FHmQVbrv.js} +5 -5
  129. package/build/server/chunks/entries/endpoints/api/browser/_id_/zoom/_server.ts.js-BV4cBtSA.js +62 -0
  130. package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-CPjKy3ma.js → _server.ts.js-4vgkwh7v.js} +9 -6
  131. package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-CWE9NP6g.js → _server.ts.js-C_9kwANR.js} +9 -6
  132. package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-D-raYQon.js → _server.ts.js-h1OTHcL4.js} +5 -5
  133. package/build/server/chunks/entries/endpoints/api/dsh/jobs/{_server.ts.js-CI4dEHFY.js → _server.ts.js-B6nih9Sd.js} +5 -5
  134. package/build/server/chunks/entries/endpoints/api/dsh/jobs/follow/{_server.ts.js-cnjoSLtY.js → _server.ts.js-Cf17SVmD.js} +5 -5
  135. package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-0UUtapX5.js → _server.ts.js-DjNwMbdS.js} +5 -5
  136. package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-MK5ezU8u.js → _server.ts.js-Cz5aaEhC.js} +5 -5
  137. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-BFBy5O9Y.js +78 -0
  138. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-wGEl1fuF.js → _server.ts.js-CgEdCo3T.js} +5 -5
  139. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-Bz7u2BlD.js → _server.ts.js-Bo_aEnHh.js} +5 -5
  140. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-yue5aEjr.js → _server.ts.js-Bd2G_GaH.js} +5 -5
  141. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-BFSs5T2m.js → _server.ts.js-DL64FyRw.js} +5 -5
  142. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-C2i85wQy.js → _server.ts.js-MhOGB66D.js} +6 -6
  143. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-_toO4f4W.js → _server.ts.js-MjPgXgGO.js} +5 -5
  144. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-BGJnDV85.js → _server.ts.js-BUjDae5H.js} +5 -5
  145. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-CQCJg8U8.js → _server.ts.js-dTKd7Hsv.js} +6 -6
  146. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-0ADvdE79.js → _server.ts.js-B82rvKoI.js} +5 -5
  147. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-DyO4T1Ro.js → _server.ts.js-Cqijsi-c.js} +4 -4
  148. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-CIY7oimw.js → _server.ts.js-CL_vVv2p.js} +29 -6
  149. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-B-9faNHX.js → _server.ts.js-WS4W9Ly4.js} +5 -5
  150. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-E7-0zfiH.js → _server.ts.js-B72KGRGh.js} +5 -5
  151. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-CODtLQ3Q.js → _server.ts.js-DK5xb2b5.js} +5 -5
  152. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-BiSxsU-j.js → _server.ts.js-lhT87EQu.js} +5 -5
  153. package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-C0WJnv2b.js → _server.ts.js-CMhfhbkN.js} +5 -5
  154. package/build/server/chunks/entries/endpoints/api/dsh/subagents/{_server.ts.js-D5bc4xg4.js → _server.ts.js-BLvcFsg6.js} +5 -5
  155. package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-23ycAyUg.js → _server.ts.js-D_rw2Uq6.js} +5 -5
  156. package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-B4w5Jh7f.js → _server.ts.js-DfXpMMpw.js} +5 -5
  157. package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-VQLxDbFE.js → _server.ts.js-2mJCJVxk.js} +5 -5
  158. package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-vs5N5Cya.js → _server.ts.js-BCx0Lzjf.js} +5 -5
  159. package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-BOWhoBHV.js → _server.ts.js-DECaSjwp.js} +5 -5
  160. package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-aDEAGfJe.js → _server.ts.js-i_ciJzlb.js} +5 -5
  161. package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-BZ-nRrTp.js → _server.ts.js-BO1pScn7.js} +5 -5
  162. package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-CkDY1PQ7.js → _server.ts.js-Buhpf7WE.js} +5 -5
  163. package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-CHvgF47Y.js → _server.ts.js-DngUQzcT.js} +4 -4
  164. package/build/server/chunks/entries/endpoints/api/terminal/_id_/output/{_server.ts.js-BNBxebgG.js → _server.ts.js-DLETP4yQ.js} +2 -2
  165. package/build/server/chunks/entries/endpoints/api/terminal/_id_/reattach/{_server.ts.js-DDRJBGIr.js → _server.ts.js-uWl6oxPS.js} +2 -2
  166. package/build/server/chunks/entries/endpoints/api/terminal/_id_/send/{_server.ts.js-CA0vc_Cm.js → _server.ts.js-DYNmXaAd.js} +9 -2
  167. package/build/server/chunks/entries/endpoints/api/terminal/_id_/stream/{_server.ts.js-D6L8Gd_f.js → _server.ts.js-C5m3Ktho.js} +2 -2
  168. package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-CbRT4vBo.js → _server.ts.js-DoTNvcOa.js} +5 -5
  169. package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-BwD0KaXy.js → _server.ts.js-BzYOJSkI.js} +7 -7
  170. package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-DgbMRh3d.js → _server.ts.js-xcNesei9.js} +7 -7
  171. package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-DRqZawic.js → _server.ts.js-DsJWYdxt.js} +7 -7
  172. package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-CTXwwwB1.js → _server.ts.js-CNCku9BR.js} +7 -7
  173. package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-B4aJBY2w.js → _server.ts.js-nLsNjOxj.js} +7 -7
  174. package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-CDJJA18L.js → _server.ts.js-urQk2-ds.js} +7 -7
  175. package/build/server/chunks/entries/{hooks.server.js-Iel6oE7w.js → hooks.server.js-CU2RE5vs.js} +3 -3
  176. package/build/server/chunks/entries/pages/{_error.svelte.js-B-wdFjVG.js → _error.svelte.js-e018KpwE.js} +6 -6
  177. package/build/server/chunks/entries/pages/{_page.server.ts.js-CaoeQzem.js → _page.server.ts.js-BK3Y6eff.js} +3 -3
  178. package/build/server/chunks/entries/pages/{_page.svelte.js-CY7zcWr4.js → _page.svelte.js-DQWBiRk1.js} +2681 -648
  179. package/build/server/chunks/{handler-DYk4NJto.js → handler-DsD7I1_u.js} +3 -3
  180. package/build/server/chunks/{index.js-kL9MZ99b.js → index.js-C_WAkwJs.js} +4 -4
  181. package/build/server/chunks/{manifest.js-BrMLQqec.js → manifest.js-DUy52VaP.js} +79 -65
  182. package/build/server/chunks/nodes/{0.js-BembYTTr.js → 0.js-CuV3dXVD.js} +3 -3
  183. package/build/server/chunks/nodes/1.js-Dc5QC-NJ.js +9 -0
  184. package/build/server/chunks/nodes/{2.js-BezA2RPm.js → 2.js-PwcF4_kT.js} +10 -10
  185. package/package.json +2 -2
  186. package/template/.dsi/prompts.sqlite +0 -0
  187. package/template/.dsi/prompts.sqlite-shm +0 -0
  188. package/template/.dsi/prompts.sqlite-wal +0 -0
  189. package/template/.dsi/settings.yaml +7 -2
  190. package/build/client/_app/immutable/assets/0.C6AGVUc8.css +0 -2
  191. package/build/client/_app/immutable/assets/2.gXzZuuwh.css +0 -1
  192. package/build/client/_app/immutable/chunks/BFOY8uwF.js +0 -1
  193. package/build/client/_app/immutable/chunks/BHDqH9nE.js +0 -1
  194. package/build/client/_app/immutable/chunks/CAneZX4t.js +0 -8
  195. package/build/client/_app/immutable/chunks/CrTRqozz.js +0 -1
  196. package/build/client/_app/immutable/chunks/DQXo7qdJ.js +0 -1
  197. package/build/client/_app/immutable/chunks/DxGYLnDH.js +0 -1
  198. package/build/client/_app/immutable/chunks/HD-mJtOS.js +0 -6
  199. package/build/client/_app/immutable/chunks/K3xyLTzZ.js +0 -1
  200. package/build/client/_app/immutable/chunks/cHj8EuyS.js +0 -3
  201. package/build/client/_app/immutable/chunks/hC0DBYN6.js +0 -2
  202. package/build/client/_app/immutable/chunks/o7DVZODA.js +0 -1
  203. package/build/client/_app/immutable/chunks/pdYhlwhf.js +0 -1
  204. package/build/client/_app/immutable/entry/app.DHewwbUQ.js +0 -2
  205. package/build/client/_app/immutable/entry/start.C0PcwkeZ.js +0 -1
  206. package/build/client/_app/immutable/nodes/0.CP10wY64.js +0 -1
  207. package/build/client/_app/immutable/nodes/1.qWvE0DiU.js +0 -1
  208. package/build/client/_app/immutable/nodes/2.Nw7iFtoh.js +0 -341
  209. package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-CEiMgzjC.js +0 -46
  210. package/build/server/chunks/nodes/1.js-CKJjyWGZ.js +0 -9
@@ -1,4 +1,4 @@
1
- import { d as readBrowserConfig } from './insight-config.js-Db5fe5Df.js';
1
+ import { d as readBrowserConfig } from './insight-config.js-C5-Rhh5A.js';
2
2
  import { mkdirSync, rmSync, readdirSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { spawn, spawnSync } from 'node:child_process';
@@ -157,6 +157,29 @@ var BrowserRelay = class {
157
157
  }
158
158
  };
159
159
  Number(process.env.DSI_MCP_PORT ?? 9515);
160
+ /** Layout-scale zoom (ADR-0041 amendment, 2026-10-31): the zoom knob is
161
+ * LAYOUT SCALE — the emulated viewport is the panel box divided by the
162
+ * zoom, and the mirror's contain-fit does the visual shrinking. The page
163
+ * keeps ONE coordinate space (no CSS zoom), so every consumer's own
164
+ * geometry math — YouTube's seek preview included — stays truthful.
165
+ * Rejected: documentElement CSS zoom (the 2026-10-28..31 implementation) —
166
+ * Chromium hit-testing stayed correct but the PAGE's own width perception
167
+ * split in two, and YouTube's player computed seek previews at exactly
168
+ * the zoom factor off (54:58 vs 1:08:44 at 0.8). */
169
+ function layoutViewport(width, height, zoom) {
170
+ const z = zoom > 0 ? zoom : 1;
171
+ return {
172
+ width: Math.max(200, Math.min(8192, Math.round(width / z))),
173
+ height: Math.max(120, Math.min(8192, Math.round(height / z)))
174
+ };
175
+ }
176
+ /** Live zoom slider (2026-10-28): the slider's wire bounds — null when the
177
+ * value is not a finite number in 0.5..1.25 (the route answers 400). */
178
+ function clampZoom(z) {
179
+ if (typeof z !== "number" || !Number.isFinite(z)) return null;
180
+ if (z < .5 || z > 1.25) return null;
181
+ return z;
182
+ }
160
183
  /** The reaper's ONLY test — pure: a session is reaper-eligible when nobody
161
184
  * watches its stream AND its last MCP tool traffic is older than idleMs.
162
185
  * An active agent (traffic younger than idleMs) is NEVER eligible (D2). */
@@ -164,6 +187,100 @@ function reaperEligible(e, idleMs, now) {
164
187
  if (e.streamSubscribers > 0) return false;
165
188
  return now - e.lastMcpActivity >= idleMs;
166
189
  }
190
+ /** Mint the next ordinal for targetId (idempotent: an already-minted
191
+ * targetId returns its existing ordinal — lazy attach and heal re-enter). */
192
+ function mintTabId(entry, targetId) {
193
+ const tabIds = entry.tabIds ??= /* @__PURE__ */ new Map();
194
+ for (const [ord, tid] of tabIds) if (tid === targetId) return ord;
195
+ entry.nextTabId ??= 1;
196
+ const ord = entry.nextTabId;
197
+ entry.nextTabId = ord + 1;
198
+ entry.tabIds.set(ord, targetId);
199
+ return ord;
200
+ }
201
+ /** ADR-0040 Amendment 4 (D-A5): the OWNER hand claims a newborn. Called
202
+ * from the entry's own context 'page' listener — a claimed targetId is
203
+ * owner-born no matter what the browser-level watcher saw first. Pure. */
204
+ function claimOwnerBirth(entry, targetId) {
205
+ (entry.ownBirths ??= /* @__PURE__ */ new Set()).add(targetId);
206
+ }
207
+ /** ADR-0040 Amendment 4 (D-A6): a GUEST birth is a citizen without the
208
+ * throne — mint an ordinal, append tabOrder (lands LAST), and NEVER move
209
+ * the active pointer (appear without stealing focus). Guards: closed
210
+ * sessions refuse; a target the entry already knows (or the owner hand
211
+ * claimed) is a no-op. Pure. Returns true when the guest was admitted. */
212
+ function admitGuestBirth(e, targetId) {
213
+ if (e.closed) return false;
214
+ if (e.ownBirths?.has(targetId)) return false;
215
+ if (e.tabOrder.includes(targetId) || e.tabs.has(targetId)) return false;
216
+ e.tabOrder.push(targetId);
217
+ mintTabId(e, targetId);
218
+ return true;
219
+ }
220
+ /** Retire a closed tab: drop both map sides. The ordinal itself is gone —
221
+ * mintTabId never hands it out again. */
222
+ function retireTabId(entry, targetId) {
223
+ if (!entry.tabIds) return;
224
+ for (const [ord, tid] of entry.tabIds) if (tid === targetId) {
225
+ entry.tabIds.delete(ord);
226
+ return;
227
+ }
228
+ }
229
+ /** HEAL PRESERVES ORDINALS: healHandles swaps a dead CDP handle for a
230
+ * fresh session — the tab's ordinal must survive with its value
231
+ * rewritten to the new targetId. An unknown page (first sight during
232
+ * heal) falls back to a fresh mint. */
233
+ function healPreserveOrdinal(entry, oldTargetId, newTargetId) {
234
+ const tabIds = entry.tabIds ??= /* @__PURE__ */ new Map();
235
+ for (const [ord, tid] of tabIds) if (tid === oldTargetId) {
236
+ entry.tabIds.set(ord, newTargetId);
237
+ return ord;
238
+ }
239
+ return mintTabId(entry, newTargetId);
240
+ }
241
+ /** Resolve a tab reference — ordinal (number / numeric string), the
242
+ * 'active' pointer, or a raw targetId — to { targetId, tabId }. A
243
+ * retired or unknown ordinal is an EXPLICIT error: no silent
244
+ * nearest-match (glass-tab-ids global constraint). */
245
+ function resolveTab(entry, ref) {
246
+ if (ref === "active") {
247
+ if (!entry.activeTargetId) return {
248
+ ok: false,
249
+ error: "no active tab"
250
+ };
251
+ for (const [ord, tid] of entry.tabIds ?? []) if (tid === entry.activeTargetId) return {
252
+ ok: true,
253
+ targetId: tid,
254
+ tabId: ord
255
+ };
256
+ return {
257
+ ok: false,
258
+ error: "active tab has no ordinal: " + entry.activeTargetId
259
+ };
260
+ }
261
+ if (typeof ref === "number" || /^\d+$/.test(ref)) {
262
+ const ord = Number(ref);
263
+ const tid = entry.tabIds?.get(ord);
264
+ if (tid === void 0) return {
265
+ ok: false,
266
+ error: "unknown or retired tab ordinal: " + ord
267
+ };
268
+ return {
269
+ ok: true,
270
+ targetId: tid,
271
+ tabId: ord
272
+ };
273
+ }
274
+ for (const [ord, tid] of entry.tabIds ?? []) if (tid === ref) return {
275
+ ok: true,
276
+ targetId: tid,
277
+ tabId: ord
278
+ };
279
+ return {
280
+ ok: false,
281
+ error: "unknown tab: " + ref
282
+ };
283
+ }
167
284
  var BrowserRegistryRefusal = class extends Error {
168
285
  code;
169
286
  constructor(code, message) {
@@ -190,10 +307,52 @@ function state() {
190
307
  function sweepOrphanProfiles(keep) {
191
308
  try {
192
309
  const root = readBrowserConfig().profileRoot;
193
- for (const name of readdirSync(root)) if (!keep.has(name)) rmSync(join(root, name), {
194
- recursive: true,
195
- force: true
196
- });
310
+ for (const name of readdirSync(root)) {
311
+ if (keep.has(name)) continue;
312
+ if (!process.env.VITEST) killOrphanChrome(name, {
313
+ listPids: () => spawnSync("ps", ["axo", "pid=,command="], {
314
+ encoding: "utf8",
315
+ timeout: 5e3
316
+ }).stdout ?? "",
317
+ killPid: (pid, sig) => process.kill(pid, sig)
318
+ });
319
+ rmSync(join(root, name), {
320
+ recursive: true,
321
+ force: true
322
+ });
323
+ }
324
+ } catch {}
325
+ }
326
+ /** Ghost Glass Fix 3 (RCA 2026-10-31 Bug 3): PURE matcher — which process
327
+ * rows hold a Chrome --user-data-dir that ENDS at the swept profile name?
328
+ * The name must terminate the dir (path separator before it, end/space
329
+ * after it), so a PREFIX-sharing sibling profile never matches. */
330
+ function orphanChromePids(psOutput, profileName) {
331
+ const needle = "--user-data-dir=";
332
+ const pids = [];
333
+ for (const line of psOutput.split("\n")) {
334
+ const at = line.indexOf(needle);
335
+ if (at === -1) continue;
336
+ const rest = line.slice(at + 16);
337
+ const end = rest.search(/[\s"']/);
338
+ if (!(end === -1 ? rest : rest.slice(0, end)).replace(/\/+$/, "").endsWith("/" + profileName)) continue;
339
+ const pid = Number.parseInt(line.trimStart(), 10);
340
+ if (Number.isFinite(pid)) pids.push(pid);
341
+ }
342
+ return pids;
343
+ }
344
+ /** Ghost Glass Fix 3: the sweep kill arm with the OS injected — SIGKILL
345
+ * every holder of the profile dir. Best-effort both ways: a failed ps
346
+ * listing or an already-dead pid (ESRCH) never blocks the dir sweep. */
347
+ function killOrphanChrome(profileName, deps) {
348
+ let out;
349
+ try {
350
+ out = deps.listPids();
351
+ } catch {
352
+ return;
353
+ }
354
+ for (const pid of orphanChromePids(out, profileName)) try {
355
+ deps.killPid(pid, "SIGKILL");
197
356
  } catch {}
198
357
  }
199
358
  /** Brain re-homing (BUGFIX 2026-10-25): release the stable brain port
@@ -313,6 +472,7 @@ var BrowserRegistry = class {
313
472
  pid: e.pid,
314
473
  profileDir: e.profileDir,
315
474
  createdAt: e.createdAt,
475
+ ownerSessionId: e.ownerSessionId ?? null,
316
476
  mcp: e.mcpChild ? "child" : e.mcpInProcess ? "in-process" : "none",
317
477
  mcpHealth: e.mcpHealth,
318
478
  mcpError: e.mcpError
@@ -366,7 +526,7 @@ var BrowserRegistry = class {
366
526
  const now = Date.now();
367
527
  for (const e of state().entries.values()) {
368
528
  if (!reaperEligible(e, idleMs, now)) continue;
369
- this.close(e.id).catch(() => void 0);
529
+ this.close(e.id, "reaped").catch(() => void 0);
370
530
  }
371
531
  }, Math.min(idleMs / 2, 3e4));
372
532
  s.reaperTimer.unref?.();
@@ -381,6 +541,21 @@ var BrowserRegistry = class {
381
541
  /** D5 amendment 2026-10-27: watch the active pointer. The stream route
382
542
  * re-binds its relay on every fire so a brain-driven activate (creation
383
543
  * auto-focus) repoints the MIRROR, not just the strip highlight. */
544
+ /** Ghost Glass Fix 2 (RCA 2026-10-31): the death handshake's registry
545
+ * side. Subscribers hear ONE reason ('closed' human, 'reaped' reaper);
546
+ * subscribing to an already-dead id hears the truth immediately instead
547
+ * of polling a ghost. Same shape as onActiveChange. */
548
+ onDeath(id, cb) {
549
+ const e = state().entries.get(id);
550
+ if (!e || e.closed) {
551
+ cb("closed");
552
+ return () => void 0;
553
+ }
554
+ (e.deathListeners ??= /* @__PURE__ */ new Set()).add(cb);
555
+ return () => {
556
+ e.deathListeners?.delete(cb);
557
+ };
558
+ }
384
559
  onActiveChange(id, cb) {
385
560
  const e = this.peek(id);
386
561
  (e.activeListeners ??= /* @__PURE__ */ new Set()).add(cb);
@@ -423,7 +598,11 @@ var BrowserRegistry = class {
423
598
  relay: handle.relay,
424
599
  page
425
600
  }).catch(() => void 0);
426
- e.tabs.set(tid, handle);
601
+ const ord = mintTabId(e, tid);
602
+ e.tabs.set(tid, {
603
+ ...handle,
604
+ tabId: ord
605
+ });
427
606
  (e.tabOrder ??= []).push(tid);
428
607
  if (tid === key) break;
429
608
  }
@@ -463,8 +642,10 @@ var BrowserRegistry = class {
463
642
  old.relay.stop();
464
643
  await old.cdp.detach().catch(() => void 0);
465
644
  const cfg = readBrowserConfig();
645
+ const ord = healPreserveOrdinal(e, tid, tid);
466
646
  e.tabs.set(tid, {
467
647
  targetId: tid,
648
+ tabId: ord,
468
649
  cdp: scdp,
469
650
  relay: new BrowserRelay(scdp, cfg.screencastQuality, cfg.screencastMaxFps),
470
651
  page
@@ -476,17 +657,73 @@ var BrowserRegistry = class {
476
657
  }
477
658
  /** Enumerate the context's page targets (ADR-0040 D5 feed) — type:page
478
659
  * only; iframes/omnibox/service workers are chrome noise (wire capture
479
- * 2026-10-24). Read-only: never attaches, never streams (D1). */
660
+ * 2026-10-24). Mirror-lifecycle (ADR "The Mirror Must Face a Living
661
+ * Tab", D1/D2): enumeration ADOPTS unknown live pages (mint + lazy
662
+ * seam — survivors' ordinals never move) and RE-POINTS the active
663
+ * pointer when its target is gone, re-seeding the mirror through
664
+ * activate's idiom — the panel never faces a corpse (the 2026-10-28
665
+ * frozen-frame bug). */
480
666
  async listTabs(id) {
481
667
  const e = this.peek(id);
482
- const src = (e.activeTargetId ? e.tabs.get(e.activeTargetId) : null)?.cdp ?? [...e.tabs.values()][0]?.cdp;
483
- if (!src) return [];
484
- let infos = ((await src.send("Target.getTargets").catch(() => null))?.targetInfos ?? []).filter((t) => t.type === "page");
485
- if (infos.length === 0 && e.context.pages().length > 0) {
668
+ const pickSrc = () => (e.activeTargetId ? e.tabs.get(e.activeTargetId) : null)?.cdp ?? [...e.tabs.values()][0]?.cdp ?? null;
669
+ const readTargets = async (h) => {
670
+ return (await h.send("Target.getTargets").catch(() => null))?.targetInfos ?? null;
671
+ };
672
+ let src = pickSrc();
673
+ let infos = (src ? await readTargets(src) : null) ?? [];
674
+ if (infos === null || infos.length === 0 && e.context.pages().length > 0) {
486
675
  await this.healHandles(e);
487
- infos = ((await ((e.activeTargetId ? e.tabs.get(e.activeTargetId) : null)?.cdp ?? [...e.tabs.values()][0]?.cdp)?.send("Target.getTargets").catch(() => null))?.targetInfos ?? []).filter((t) => t.type === "page");
676
+ src = pickSrc();
677
+ infos = (src ? await readTargets(src) : null) ?? [];
488
678
  }
489
- return infos.map((t) => ({
679
+ let pages = infos.filter((t) => t.type === "page");
680
+ if (pages.length === 0 && e.context.pages().length > 0) {
681
+ const probed = [];
682
+ for (const page of e.context.pages()) try {
683
+ const scdp = await e.context.newCDPSession(page);
684
+ const info = await scdp.send("Target.getTargetInfo");
685
+ await scdp.detach().catch(() => void 0);
686
+ if (info.targetInfo?.targetId) probed.push({
687
+ targetId: info.targetInfo.targetId,
688
+ type: "page",
689
+ url: info.targetInfo.url ?? page.url(),
690
+ title: info.targetInfo.title ?? ""
691
+ });
692
+ } catch {
693
+ continue;
694
+ }
695
+ pages = probed;
696
+ }
697
+ const known = new Set(e.tabs.keys());
698
+ const unknown = pages.filter((t) => !known.has(t.targetId));
699
+ if (unknown.length > 0) {
700
+ const cfg = readBrowserConfig();
701
+ for (const page of e.context.pages()) {
702
+ let tid = null;
703
+ let scdp = null;
704
+ try {
705
+ scdp = await e.context.newCDPSession(page);
706
+ tid = (await scdp.send("Target.getTargetInfo")).targetInfo?.targetId ?? null;
707
+ } catch {
708
+ continue;
709
+ }
710
+ if (!tid || !unknown.some((u) => u.targetId === tid)) {
711
+ await scdp.detach().catch(() => void 0);
712
+ continue;
713
+ }
714
+ const ord = mintTabId(e, tid);
715
+ if (!e.tabOrder.includes(tid)) e.tabOrder.push(tid);
716
+ e.tabs.set(tid, {
717
+ targetId: tid,
718
+ tabId: ord,
719
+ cdp: scdp,
720
+ relay: new BrowserRelay(scdp, cfg.screencastQuality, cfg.screencastMaxFps),
721
+ page
722
+ });
723
+ }
724
+ }
725
+ const out = pages.map((t) => ({
726
+ tabId: mintTabId(e, t.targetId),
490
727
  targetId: t.targetId,
491
728
  url: t.url,
492
729
  title: t.title,
@@ -497,6 +734,14 @@ var BrowserRegistry = class {
497
734
  const ib = order.indexOf(b.targetId);
498
735
  return (ia === -1 ? Infinity : ia) - (ib === -1 ? Infinity : ib);
499
736
  });
737
+ if (e.activeTargetId && !out.some((r) => r.targetId === e.activeTargetId)) {
738
+ const survivor = out[0]?.targetId ?? null;
739
+ if (survivor) {
740
+ await this.activate(id, survivor).catch(() => void 0);
741
+ for (const r of out) r.active = r.targetId === e.activeTargetId;
742
+ } else e.activeTargetId = null;
743
+ }
744
+ return out;
500
745
  }
501
746
  /** Attach (lazily), seed the first frame, re-apply the viewport, and move
502
747
  * the active pointer (ADR-0040 D1/D2/D4). The OLD active relay pauses —
@@ -549,22 +794,25 @@ var BrowserRegistry = class {
549
794
  const port = freePort(options.port);
550
795
  const profileDir = join(cfg.profileRoot, id.slice(0, 8));
551
796
  mkdirSync(profileDir, { recursive: true });
552
- const ignoreDefaultArgs = ["--enable-automation", "--mute-audio"];
797
+ const ignoreDefaultArgs = [
798
+ "--enable-automation",
799
+ "--mute-audio",
800
+ "--hide-scrollbars"
801
+ ];
553
802
  const launch = (useChrome) => chromium.launchPersistentContext(profileDir, {
554
803
  ...useChrome ? { channel: "chrome" } : {},
555
804
  headless: options.headless ?? cfg.headless,
556
805
  ignoreDefaultArgs,
557
806
  args: [
558
- "--remote-debugging-port=" + port,
559
807
  "--no-first-run",
560
- "--disable-blink-features=AutomationControlled",
561
- "--disable-features=IsolateOrigins,site-per-process",
808
+ "--remote-debugging-port=" + port,
562
809
  "--disable-dev-shm-usage",
563
- "--disable-backgrounding-occluded-windows",
564
810
  "--disable-renderer-backgrounding",
565
811
  "--disable-background-timer-throttling",
812
+ "--disable-backgrounding-occluded-windows",
813
+ "--disable-blink-features=AutomationControlled",
814
+ "--disable-features=IsolateOrigins,site-per-process",
566
815
  "--autoplay-policy=no-user-gesture-required",
567
- "--window-position=-32000,-32000",
568
816
  "--window-size=" + (Math.max(200, Math.min(1920, options.width ?? 730)) + 6) + "," + (Math.max(120, Math.min(1080, options.height ?? 830)) + 70)
569
817
  ],
570
818
  viewport: options.headless ?? cfg.headless ? {
@@ -590,12 +838,19 @@ var BrowserRegistry = class {
590
838
  try {
591
839
  activeTargetId = (await cdp.send("Target.getTargetInfo")).targetInfo?.targetId ?? null;
592
840
  } catch {}
593
- if (activeTargetId) tabs.set(activeTargetId, {
594
- targetId: activeTargetId,
595
- cdp,
596
- relay,
597
- page: context.pages()[0]
598
- });
841
+ const tabIds = /* @__PURE__ */ new Map();
842
+ let nextTabId = 1;
843
+ if (activeTargetId) {
844
+ tabIds.set(1, activeTargetId);
845
+ nextTabId = 2;
846
+ tabs.set(activeTargetId, {
847
+ targetId: activeTargetId,
848
+ tabId: 1,
849
+ cdp,
850
+ relay,
851
+ page: context.pages()[0]
852
+ });
853
+ }
599
854
  await relay.start();
600
855
  const start = options.url ?? "data:text/html,<title>Glass Browser</title><body style=\"font-family:system-ui;color:gray;display:grid;place-items:center;height:100vh;margin:0\">Glass Browser — waiting for the agent</body>";
601
856
  await cdp.send("Page.enable").catch(() => void 0);
@@ -613,6 +868,20 @@ var BrowserRegistry = class {
613
868
  metadata: { seeded: true }
614
869
  });
615
870
  }
871
+ if (options.headless ?? cfg.headless) {
872
+ const birth = context.pages()[0];
873
+ if (birth && typeof birth.evaluate === "function") {
874
+ if (await birth.evaluate(() => {
875
+ const d = document.createElement("div");
876
+ d.style.cssText = "position:fixed;left:-100px;top:0;width:50px;height:50px;overflow:auto";
877
+ d.innerHTML = "<div style=\"width:200px;height:200px\"></div>";
878
+ document.body.appendChild(d);
879
+ const f = d.offsetHeight - d.clientHeight;
880
+ d.remove();
881
+ return f;
882
+ }).catch(() => null) === 0) throw new Error("glass scrollbar gate: bar footprint is 0 in a headless launch — --hide-scrollbars leaked past ignoreDefaultArgs (RCA 2026-10-28)");
883
+ }
884
+ }
616
885
  const brainPort = Number(process.env.DSI_MCP_PORT ?? cfg.brainPort);
617
886
  if (cfg.enabled) this.ensureReaper(cfg.idleMs);
618
887
  const entry = {
@@ -621,10 +890,13 @@ var BrowserRegistry = class {
621
890
  tabs,
622
891
  activeTargetId,
623
892
  tabOrder: activeTargetId ? [activeTargetId] : [],
893
+ tabIds,
894
+ nextTabId,
624
895
  viewport: {
625
896
  width: Math.max(200, Math.min(1920, options.width ?? 730)),
626
897
  height: Math.max(120, Math.min(1080, options.height ?? 830))
627
898
  },
899
+ zoom: cfg.contentZoom,
628
900
  headless: options.headless ?? cfg.headless,
629
901
  port,
630
902
  pid,
@@ -637,6 +909,8 @@ var BrowserRegistry = class {
637
909
  mcpHealth: "up",
638
910
  mcpError: null,
639
911
  closed: false,
912
+ ownerSessionId: options.ownerSessionId ?? null,
913
+ ownBirths: /* @__PURE__ */ new Set(),
640
914
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
641
915
  };
642
916
  state().entries.set(id, entry);
@@ -651,12 +925,36 @@ var BrowserRegistry = class {
651
925
  const tid = info?.targetInfo?.targetId;
652
926
  if (!tid) continue;
653
927
  if (!entry.tabOrder.includes(tid)) entry.tabOrder.push(tid);
654
- if (entry.activeTargetId !== tid && !entry.closed) await this.activate(id, tid);
928
+ mintTabId(entry, tid);
929
+ claimOwnerBirth(entry, tid);
930
+ if (entry.activeTargetId !== tid && !entry.closed && !entry.tabs.has(tid)) await this.activate(id, tid);
655
931
  return;
656
932
  } catch {}
657
933
  }
658
934
  })();
659
935
  });
936
+ try {
937
+ const browser = context.browser?.();
938
+ if (browser && typeof browser.newBrowserCDPSession === "function") {
939
+ const bcdp = await browser.newBrowserCDPSession();
940
+ entry.browserCdp = bcdp;
941
+ await bcdp.send("Target.setDiscoverTargets", { discover: true }).catch(() => void 0);
942
+ bcdp.on("Target.targetCreated", (evt) => {
943
+ const tid = evt?.targetInfo?.targetId;
944
+ if (!tid || evt.targetInfo?.type !== "page") return;
945
+ if (entry.tabOrder.includes(tid) || entry.tabs.has(tid)) return;
946
+ (async () => {
947
+ for (let g = 0; g < 10; g += 1) {
948
+ await new Promise((r) => setTimeout(r, 300));
949
+ if (entry.closed) return;
950
+ if (entry.ownBirths?.has(tid)) return;
951
+ if (entry.tabOrder.includes(tid) || entry.tabs.has(tid)) return;
952
+ }
953
+ admitGuestBirth(entry, tid);
954
+ })();
955
+ });
956
+ }
957
+ } catch {}
660
958
  if (!entry.headless) {
661
959
  await this.applyPanelViewport(entry, {
662
960
  cdp,
@@ -694,6 +992,7 @@ var BrowserRegistry = class {
694
992
  pid,
695
993
  profileDir,
696
994
  createdAt: entry.createdAt,
995
+ ownerSessionId: entry.ownerSessionId,
697
996
  mcp: entry.mcpChild ? "child" : entry.mcpInProcess ? "in-process" : "none",
698
997
  mcpHealth: entry.mcpHealth,
699
998
  mcpError: entry.mcpError
@@ -723,7 +1022,7 @@ var BrowserRegistry = class {
723
1022
  });
724
1023
  }
725
1024
  /** D8 owner-release. Idempotent: closing a closed id resolves cleanly. */
726
- async close(id) {
1025
+ async close(id, reason = "closed") {
727
1026
  const entry = state().entries.get(id);
728
1027
  if (!entry) return {
729
1028
  ok: true,
@@ -738,6 +1037,10 @@ var BrowserRegistry = class {
738
1037
  }
739
1038
  entry.closed = true;
740
1039
  state().closed.add(id);
1040
+ for (const cb of entry.deathListeners ?? []) try {
1041
+ cb(reason);
1042
+ } catch {}
1043
+ await entry.browserCdp?.detach().catch(() => void 0);
741
1044
  if (state().closed.size > 256) state().closed.delete(state().closed.values().next().value);
742
1045
  const errs = [];
743
1046
  if (entry.mcpInProcess) try {
@@ -835,6 +1138,20 @@ var BrowserRegistry = class {
835
1138
  await this.applyPanelViewport(e, handle);
836
1139
  await this.repairSurfaceAfterResize(e, handle, prevSeq).catch(() => void 0);
837
1140
  }
1141
+ /** Layout-scale zoom (ADR-0041 amendment, 2026-10-31): store the session
1142
+ * scale and re-apply the panel viewport — the emulation is box/zoom, so
1143
+ * the slider's LIVE effect rides the resize. Bad input (clampZoom null)
1144
+ * KEEPS the current zoom and returns silently: unreachable from the wire
1145
+ * (the route's clampZoom already answered 400) — documented keep. */
1146
+ async setZoom(id, zoom) {
1147
+ const e = this.peek(id);
1148
+ if (e.closed) throw new BrowserRegistryRefusal("CLOSED", "session is closing");
1149
+ const clamped = clampZoom(zoom);
1150
+ if (clamped === null) return;
1151
+ e.zoom = clamped;
1152
+ const handle = await this.handleOf(e);
1153
+ await this.applyPanelViewport(e, handle);
1154
+ }
838
1155
  /** The window id, retried — Target.getWindowForTarget on a Playwright
839
1156
  * page session races out on a COLD headed launch (measured in the
840
1157
  * surface-lag test: both resizes skipped, the birth window kept its
@@ -869,10 +1186,15 @@ var BrowserRegistry = class {
869
1186
  * the ring, and seed() refuses to cover one). Capped throughout —
870
1187
  * nothing here may hang the verb (the 2.5s rule). */
871
1188
  async repairSurfaceAfterResize(e, handle, prevSeq) {
872
- const want = {
1189
+ const want0 = {
873
1190
  w: e.viewport.width,
874
1191
  h: e.viewport.height
875
1192
  };
1193
+ const lvw = layoutViewport(want0.w, want0.h, e.zoom ?? readBrowserConfig().contentZoom);
1194
+ const want = {
1195
+ w: lvw.width,
1196
+ h: lvw.height
1197
+ };
876
1198
  const dimsOf = (f) => {
877
1199
  if (!f) return null;
878
1200
  const md = f.metadata;
@@ -911,13 +1233,10 @@ var BrowserRegistry = class {
911
1233
  const timeout = new Promise((res) => setTimeout(() => res(fb), 2500));
912
1234
  return await Promise.race([p.catch(() => fb), timeout]);
913
1235
  };
914
- const anyCdpH = handle.cdp;
915
- await raceH(anyCdpH.send("Emulation.setDeviceMetricsOverride", {
1236
+ if (handle.page) await raceH(handle.page.setViewportSize({
916
1237
  width: want.w,
917
- height: want.h,
918
- deviceScaleFactor: 1,
919
- mobile: false
920
- }).then(() => null), null);
1238
+ height: want.h
1239
+ }).catch(() => void 0).then(() => null), null);
921
1240
  await new Promise((r) => setTimeout(r, 400));
922
1241
  const shotH = await raceH(handle.cdp.send("Page.captureScreenshot", {
923
1242
  format: "jpeg",
@@ -958,10 +1277,11 @@ var BrowserRegistry = class {
958
1277
  format: "jpeg",
959
1278
  quality: 60
960
1279
  }), null);
961
- const d = shot?.data ? dimsOf({
1280
+ let d = shot?.data ? dimsOf({
962
1281
  jpeg: shot.data,
963
1282
  metadata: {}
964
1283
  }) : null;
1284
+ if (!d) d = dimsOf(handle.relay.latestFrame());
965
1285
  if (d && Math.abs(d.w - want.w) < 3 && Math.abs(d.h - want.h) < 3) {
966
1286
  console.log("[surface] iter", i, "converged: capture", d.w + "x" + d.h, "chrome", cw + "/" + ch);
967
1287
  e.chrome = {
@@ -1095,6 +1415,44 @@ var BrowserRegistry = class {
1095
1415
  entryCount: hist.entries.length
1096
1416
  };
1097
1417
  }
1418
+ /** The FULL navigation history of one tab (long-press dropdown,
1419
+ * operator-approved 2026-10-28): the attached CDP session's
1420
+ * Page.getNavigationHistory, entries as { index, url, title } — index
1421
+ * is the LIST position the UI filters by, id is the CDP entryId the
1422
+ * travel verb needs. Read-only; the same handleOf refusals as navInfo. */
1423
+ async navEntries(id, targetId) {
1424
+ const e = this.peek(id);
1425
+ const h = await this.handleOf(e, targetId);
1426
+ await h.cdp.send("Page.enable").catch(() => void 0);
1427
+ const hist = await h.cdp.send("Page.getNavigationHistory", {});
1428
+ return {
1429
+ currentIndex: hist.currentIndex,
1430
+ entries: hist.entries.map((en, index) => ({
1431
+ index,
1432
+ url: en.url,
1433
+ title: en.title
1434
+ }))
1435
+ };
1436
+ }
1437
+ /** TRUE history travel (long-press dropdown, operator-approved
1438
+ * 2026-10-28): Page.navigateToHistoryEntry to the entry AT the list
1439
+ * position — never a fresh navigate, which would append a new entry
1440
+ * and desync the dropdown from Chrome's own back/forward list. A
1441
+ * position outside the list is an explicit refusal. */
1442
+ async historyTravel(id, index, targetId) {
1443
+ const e = this.peek(id);
1444
+ const h = await this.handleOf(e, targetId);
1445
+ await h.cdp.send("Page.enable").catch(() => void 0);
1446
+ const hist = await h.cdp.send("Page.getNavigationHistory", {});
1447
+ if (!Number.isInteger(index) || index < 0 || index >= hist.entries.length) throw new BrowserRegistryRefusal("NO_TARGET", "HISTORY_INDEX — no entry at index " + index + " of " + hist.entries.length);
1448
+ const loaded = this.waitLoad(h);
1449
+ await h.cdp.send("Page.navigateToHistoryEntry", { entryId: hist.entries[index].id });
1450
+ await loaded;
1451
+ return {
1452
+ currentIndex: index,
1453
+ entryCount: hist.entries.length
1454
+ };
1455
+ }
1098
1456
  /** Reload the session's active page (ADR-0031 D4): Page.reload keeps
1099
1457
  * the history entry, unlike re-navigating the current URL. */
1100
1458
  async reload(id, targetId) {
@@ -1206,12 +1564,15 @@ var BrowserRegistry = class {
1206
1564
  waitLoad: true,
1207
1565
  targetId
1208
1566
  });
1567
+ const tabId = mintTabId(e, targetId);
1209
1568
  if (opts?.activate ?? true) return {
1210
1569
  ...await this.activate(id, targetId),
1211
- targetId
1570
+ targetId,
1571
+ tabId
1212
1572
  };
1213
1573
  const h = e.tabs.get(targetId);
1214
1574
  return {
1575
+ tabId,
1215
1576
  targetId,
1216
1577
  seq: h?.relay.latestFrame()?.seq ?? 0,
1217
1578
  jpeg: h?.relay.latestFrame()?.jpeg ?? null,
@@ -1235,16 +1596,23 @@ var BrowserRegistry = class {
1235
1596
  async applyPanelViewport(e, handle) {
1236
1597
  await handle.cdp.send("Page.enable").catch(() => void 0);
1237
1598
  if (e.headless && handle.page) {
1238
- await Promise.race([handle.page.setViewportSize({
1239
- width: e.viewport.width,
1240
- height: e.viewport.height
1241
- }).catch(() => void 0), new Promise((res) => setTimeout(res, 2500))]);
1242
- await handle.cdp.send("Emulation.setDeviceMetricsOverride", {
1243
- width: e.viewport.width,
1244
- height: e.viewport.height,
1245
- deviceScaleFactor: 1,
1246
- mobile: false
1599
+ const lv = layoutViewport(e.viewport.width, e.viewport.height, e.zoom ?? readBrowserConfig().contentZoom);
1600
+ const resized = handle.page.setViewportSize({
1601
+ width: lv.width,
1602
+ height: lv.height
1247
1603
  }).catch(() => void 0);
1604
+ await Promise.race([resized, new Promise((res) => setTimeout(res, 2500))]);
1605
+ await Promise.race([resized, new Promise((res) => setTimeout(res, 5e3))]);
1606
+ try {
1607
+ const cdp = await handle.page.context().newCDPSession(handle.page);
1608
+ const dprEval = await Promise.race([handle.page.evaluate("devicePixelRatio").catch(() => 1), new Promise((res) => setTimeout(() => res(1), 500))]);
1609
+ await cdp.send("Emulation.setDeviceMetricsOverride", {
1610
+ width: lv.width,
1611
+ height: lv.height,
1612
+ deviceScaleFactor: typeof dprEval === "number" && dprEval > 0 ? dprEval : 1,
1613
+ mobile: false
1614
+ }).catch(() => void 0);
1615
+ } catch {}
1248
1616
  return;
1249
1617
  }
1250
1618
  const race = async (p, fb) => await Promise.race([p.catch(() => fb), new Promise((res) => setTimeout(() => res(fb), 2500))]);
@@ -1267,11 +1635,12 @@ var BrowserRegistry = class {
1267
1635
  const anyCdp2 = handle.cdp;
1268
1636
  const win = await this.windowIdOf(anyCdp2, race);
1269
1637
  if (win && win.windowId) {
1638
+ const lv = layoutViewport(e.viewport.width, e.viewport.height, e.zoom ?? readBrowserConfig().contentZoom);
1270
1639
  await race(anyCdp2.send("Browser.setWindowBounds", {
1271
1640
  windowId: win.windowId,
1272
1641
  bounds: {
1273
- width: Math.max(200, e.viewport.width + chromeW),
1274
- height: Math.max(120, e.viewport.height + chromeH),
1642
+ width: Math.max(200, lv.width + chromeW),
1643
+ height: Math.max(120, lv.height + chromeH),
1275
1644
  windowState: "normal"
1276
1645
  }
1277
1646
  }), null);
@@ -1280,7 +1649,7 @@ var BrowserRegistry = class {
1280
1649
  h: chromeH
1281
1650
  };
1282
1651
  const check = await race(anyCdp2.send("Browser.getWindowForTarget", { targetId: e.activeTargetId }), null);
1283
- console.log("[window] resized ->", JSON.stringify(check && check.bounds ? check.bounds : check), "want", e.viewport.width + chromeW, "x", e.viewport.height + chromeH);
1652
+ console.log("[window] resized ->", JSON.stringify(check && check.bounds ? check.bounds : check), "want", lv.width + chromeW, "x", lv.height + chromeH);
1284
1653
  } else console.log("[window] no windowId — resize skipped (raced out)");
1285
1654
  await race(anyCdp2.send("Emulation.clearDeviceMetricsOverride"), null);
1286
1655
  }
@@ -1289,14 +1658,23 @@ var BrowserRegistry = class {
1289
1658
  * to the first surviving tab (re-activated, first-frame contract
1290
1659
  * re-fired). Closing the LAST tab is refused: the kill ladder owns
1291
1660
  * session death (the trash is the operator-facing kill). */
1292
- async closeTab(id, targetId) {
1661
+ async closeTab(id, ref) {
1293
1662
  const e = this.peek(id);
1294
1663
  if (e.closed) throw new BrowserRegistryRefusal("CLOSED", "session is closing");
1664
+ let targetId = ref;
1665
+ if (typeof ref === "number" || /^\d+$/.test(ref)) {
1666
+ const r = resolveTab(e, ref);
1667
+ if (!r.ok) throw new BrowserRegistryRefusal("NO_TARGET", r.error);
1668
+ targetId = r.targetId;
1669
+ }
1295
1670
  if (e.tabs.size <= 1) throw new BrowserRegistryRefusal("NO_TARGET", "cannot close the last tab — use the trash to close the glass");
1296
1671
  const victim = e.tabs.get(targetId);
1297
1672
  if (!victim) throw new BrowserRegistryRefusal("NO_TARGET", "no such tab: " + targetId);
1298
1673
  victim.relay.stop();
1299
1674
  e.tabs.delete(targetId);
1675
+ retireTabId(e, targetId);
1676
+ const ordIdx = (e.tabOrder ?? []).indexOf(targetId);
1677
+ if (ordIdx !== -1) e.tabOrder.splice(ordIdx, 1);
1300
1678
  await victim.cdp.send("Target.closeTarget", { targetId }).catch(() => void 0);
1301
1679
  await victim.cdp.detach().catch(() => void 0);
1302
1680
  if (e.activeTargetId === targetId) {
@@ -1319,5 +1697,5 @@ var BrowserRegistry = class {
1319
1697
  };
1320
1698
  var browserRegistry = new BrowserRegistry();
1321
1699
 
1322
- export { BrowserRegistryRefusal as B, browserRegistry as b };
1323
- //# sourceMappingURL=registry.js-syaTZ_-A.js.map
1700
+ export { BrowserRegistryRefusal as B, browserRegistry as b, clampZoom as c };
1701
+ //# sourceMappingURL=registry.js-CWnRQ4vx.js.map