termdock 1.4.350 → 1.4.352

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 (448) hide show
  1. package/dist/client/assets/AndroidMirrorView-DkOZxYLg.js +3 -0
  2. package/dist/client/assets/AndroidMirrorView-DkOZxYLg.js.br +0 -0
  3. package/dist/client/assets/AndroidMirrorView-DkOZxYLg.js.gz +0 -0
  4. package/dist/client/assets/App-DqRkfVSm.js +178 -0
  5. package/dist/client/assets/App-DqRkfVSm.js.br +0 -0
  6. package/dist/client/assets/App-DqRkfVSm.js.gz +0 -0
  7. package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js +9 -0
  8. package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js.br +0 -0
  9. package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js.gz +0 -0
  10. package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js +2 -0
  11. package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js.br +0 -0
  12. package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js.gz +0 -0
  13. package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js +1 -0
  14. package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js.br +0 -0
  15. package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js.gz +0 -0
  16. package/dist/client/assets/CollaborationTaskContent-Cbg3iH6E.js +2 -0
  17. package/dist/client/assets/ComputerControlView-CSs54lf0.js +6 -0
  18. package/dist/client/assets/ComputerControlView-CSs54lf0.js.br +0 -0
  19. package/dist/client/assets/ComputerControlView-CSs54lf0.js.gz +0 -0
  20. package/dist/client/assets/DagPlayground-yoS2llnB.js +1 -0
  21. package/dist/client/assets/DagPlayground-yoS2llnB.js.br +0 -0
  22. package/dist/client/assets/DagPlayground-yoS2llnB.js.gz +0 -0
  23. package/dist/client/assets/{DiffLab-DEw4y4Hk.js → DiffLab-Dj1MT9pY.js} +2 -2
  24. package/dist/client/assets/DiffLab-Dj1MT9pY.js.br +0 -0
  25. package/dist/client/assets/DiffLab-Dj1MT9pY.js.gz +0 -0
  26. package/dist/client/assets/DiffReview-BX2S9hNp.js +1 -0
  27. package/dist/client/assets/DiffReview-BX2S9hNp.js.br +0 -0
  28. package/dist/client/assets/DiffReview-BX2S9hNp.js.gz +0 -0
  29. package/dist/client/assets/{DiffReviewLab-CDXsy0jE.js → DiffReviewLab-DqI14GEk.js} +2 -2
  30. package/dist/client/assets/DiffReviewLab-DqI14GEk.js.br +0 -0
  31. package/dist/client/assets/DiffReviewLab-DqI14GEk.js.gz +0 -0
  32. package/dist/client/assets/DiffViewer-AZvdDGfH.js +34 -0
  33. package/dist/client/assets/DiffViewer-AZvdDGfH.js.br +0 -0
  34. package/dist/client/assets/DiffViewer-AZvdDGfH.js.gz +0 -0
  35. package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js +1 -0
  36. package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js.br +0 -0
  37. package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js.gz +0 -0
  38. package/dist/client/assets/MarkdownPreview-DpvTnKkj.js +19 -0
  39. package/dist/client/assets/MarkdownPreview-DpvTnKkj.js.br +0 -0
  40. package/dist/client/assets/MarkdownPreview-DpvTnKkj.js.gz +0 -0
  41. package/dist/client/assets/{ModelPreview-BEiOgE0G.js → ModelPreview-Du_AyPr9.js} +166 -166
  42. package/dist/client/assets/ModelPreview-Du_AyPr9.js.br +0 -0
  43. package/dist/client/assets/ModelPreview-Du_AyPr9.js.gz +0 -0
  44. package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js +1 -0
  45. package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js.br +0 -0
  46. package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js.gz +0 -0
  47. package/dist/client/assets/RightSidebar-DU3gwdzg.js +1662 -0
  48. package/dist/client/assets/RightSidebar-DU3gwdzg.js.br +0 -0
  49. package/dist/client/assets/RightSidebar-DU3gwdzg.js.gz +0 -0
  50. package/dist/client/assets/SessionChatView-CxfwJMuK.js +13 -0
  51. package/dist/client/assets/SessionChatView-CxfwJMuK.js.br +0 -0
  52. package/dist/client/assets/SessionChatView-CxfwJMuK.js.gz +0 -0
  53. package/dist/client/assets/SessionChatView-D8GoESjb.css +1 -0
  54. package/dist/client/assets/SessionChatView-D8GoESjb.css.br +0 -0
  55. package/dist/client/assets/SessionChatView-D8GoESjb.css.gz +0 -0
  56. package/dist/client/assets/SessionResourceSidebar-B31PU57J.js +2 -0
  57. package/dist/client/assets/SessionResourceSidebar-B31PU57J.js.br +0 -0
  58. package/dist/client/assets/SessionResourceSidebar-B31PU57J.js.gz +0 -0
  59. package/dist/client/assets/TodoWorkspace-j9BLgk94.js +1 -0
  60. package/dist/client/assets/TodoWorkspace-j9BLgk94.js.br +0 -0
  61. package/dist/client/assets/TodoWorkspace-j9BLgk94.js.gz +0 -0
  62. package/dist/client/assets/{abnfDiagram-VCTEODGH-ByzlUu_B.js → abnfDiagram-VCTEODGH-LfmMIpPX.js} +1 -1
  63. package/dist/client/assets/abnfDiagram-VCTEODGH-LfmMIpPX.js.br +0 -0
  64. package/dist/client/assets/abnfDiagram-VCTEODGH-LfmMIpPX.js.gz +0 -0
  65. package/dist/client/assets/app-BMJesFDU.js +36 -0
  66. package/dist/client/assets/app-BMJesFDU.js.br +0 -0
  67. package/dist/client/assets/app-BMJesFDU.js.gz +0 -0
  68. package/dist/client/assets/{arc-BA6JM6vl.js → arc-DMzcmH2U.js} +1 -1
  69. package/dist/client/assets/arc-DMzcmH2U.js.br +0 -0
  70. package/dist/client/assets/arc-DMzcmH2U.js.gz +0 -0
  71. package/dist/client/assets/{architectureDiagram-5GKGNRK7-hCHxOfKw.js → architectureDiagram-5GKGNRK7-CphS_S5Q.js} +1 -1
  72. package/dist/client/assets/architectureDiagram-5GKGNRK7-CphS_S5Q.js.br +0 -0
  73. package/dist/client/assets/{architectureDiagram-5GKGNRK7-hCHxOfKw.js.gz → architectureDiagram-5GKGNRK7-CphS_S5Q.js.gz} +0 -0
  74. package/dist/client/assets/arrow-down-D-WZS308.js +1 -0
  75. package/dist/client/assets/arrow-up-CelbB9FE.js +1 -0
  76. package/dist/client/assets/{blockDiagram-I7D4REHJ-OmEN9hUB.js → blockDiagram-I7D4REHJ-Dx_4qkcL.js} +1 -1
  77. package/dist/client/assets/blockDiagram-I7D4REHJ-Dx_4qkcL.js.br +0 -0
  78. package/dist/client/assets/blockDiagram-I7D4REHJ-Dx_4qkcL.js.gz +0 -0
  79. package/dist/client/assets/{c4Diagram-7LVT6UL2-DfLTv8zh.js → c4Diagram-7LVT6UL2-DiGdnPo4.js} +1 -1
  80. package/dist/client/assets/c4Diagram-7LVT6UL2-DiGdnPo4.js.br +0 -0
  81. package/dist/client/assets/c4Diagram-7LVT6UL2-DiGdnPo4.js.gz +0 -0
  82. package/dist/client/assets/channel-BxAJ9Qmh.js +1 -0
  83. package/dist/client/assets/chevron-left-5sk7gL3u.js +1 -0
  84. package/dist/client/assets/{chunk-2Q5K7J3B-C3O76PNZ.js → chunk-2Q5K7J3B-M50KNmR8.js} +1 -1
  85. package/dist/client/assets/{chunk-5VM5RSS4-CsWZd30k.js → chunk-5VM5RSS4-wXVM-Max.js} +1 -1
  86. package/dist/client/assets/{chunk-F27PBJKO-yxCv2Uqk.js → chunk-F27PBJKO-BfQILS9u.js} +1 -1
  87. package/dist/client/assets/chunk-F27PBJKO-BfQILS9u.js.br +0 -0
  88. package/dist/client/assets/chunk-F27PBJKO-BfQILS9u.js.gz +0 -0
  89. package/dist/client/assets/{chunk-IMKFNOWR-CdPjlb9f.js → chunk-IMKFNOWR-D111Jpl3.js} +1 -1
  90. package/dist/client/assets/chunk-IMKFNOWR-D111Jpl3.js.br +0 -0
  91. package/dist/client/assets/chunk-IMKFNOWR-D111Jpl3.js.gz +0 -0
  92. package/dist/client/assets/{chunk-JWPE2WC7-BiiOLq2R.js → chunk-JWPE2WC7-BBDyly5c.js} +1 -1
  93. package/dist/client/assets/{chunk-POPQ4Y6H-BOu_1Brt.js → chunk-POPQ4Y6H-BaI-_yc7.js} +1 -1
  94. package/dist/client/assets/{chunk-SVP7TREG-D1tOJung.js → chunk-SVP7TREG-BvQafCMJ.js} +1 -1
  95. package/dist/client/assets/chunk-SVP7TREG-BvQafCMJ.js.br +0 -0
  96. package/dist/client/assets/chunk-SVP7TREG-BvQafCMJ.js.gz +0 -0
  97. package/dist/client/assets/{chunk-TICWLB2K-DZjDfYNw.js → chunk-TICWLB2K-CQXPwGBz.js} +1 -1
  98. package/dist/client/assets/chunk-TICWLB2K-CQXPwGBz.js.br +0 -0
  99. package/dist/client/assets/chunk-TICWLB2K-CQXPwGBz.js.gz +0 -0
  100. package/dist/client/assets/{chunk-XXDRQBXY-CtGPyXWh.js → chunk-XXDRQBXY-CmwZc4xV.js} +1 -1
  101. package/dist/client/assets/classDiagram-ZZMXUADV-D0oXVFxd.js +1 -0
  102. package/dist/client/assets/classDiagram-v2-VYDZK3BY-D0oXVFxd.js +1 -0
  103. package/dist/client/assets/clipboard-uSv3AiJM.js +1 -0
  104. package/dist/client/assets/clipboardText-5puxqqm_.js +1 -0
  105. package/dist/client/assets/clipboardText-5puxqqm_.js.br +0 -0
  106. package/dist/client/assets/clipboardText-5puxqqm_.js.gz +0 -0
  107. package/dist/client/assets/{cose-bilkent-JH36ORCC-C4Wb5lqD.js → cose-bilkent-JH36ORCC-CqWarkUj.js} +1 -1
  108. package/dist/client/assets/cose-bilkent-JH36ORCC-CqWarkUj.js.br +0 -0
  109. package/dist/client/assets/cose-bilkent-JH36ORCC-CqWarkUj.js.gz +0 -0
  110. package/dist/client/assets/{cynefin-OW5HDTMX-BvWKB1Xk.js → cynefin-OW5HDTMX-CFW2ifig.js} +1 -1
  111. package/dist/client/assets/cynefin-OW5HDTMX-CFW2ifig.js.br +0 -0
  112. package/dist/client/assets/cynefin-OW5HDTMX-CFW2ifig.js.gz +0 -0
  113. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-7tAkHD2P.js → cynefinDiagram-5FMLGOSQ-yggxM55S.js} +1 -1
  114. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-yggxM55S.js.br +0 -0
  115. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-yggxM55S.js.gz +0 -0
  116. package/dist/client/assets/{dagre-GXQ25YYZ-Bs6IPwks.js → dagre-GXQ25YYZ-inq7o--x.js} +1 -1
  117. package/dist/client/assets/dagre-GXQ25YYZ-inq7o--x.js.br +0 -0
  118. package/dist/client/assets/dagre-GXQ25YYZ-inq7o--x.js.gz +0 -0
  119. package/dist/client/assets/{diagram-S7CK7UJ4-CmYXaTya.js → diagram-S7CK7UJ4-BUXMnyQN.js} +1 -1
  120. package/dist/client/assets/diagram-S7CK7UJ4-BUXMnyQN.js.br +0 -0
  121. package/dist/client/assets/diagram-S7CK7UJ4-BUXMnyQN.js.gz +0 -0
  122. package/dist/client/assets/{diagram-UQ7AKVKN-CqxoefB7.js → diagram-UQ7AKVKN-BJbw-Imf.js} +1 -1
  123. package/dist/client/assets/diagram-UQ7AKVKN-BJbw-Imf.js.br +0 -0
  124. package/dist/client/assets/diagram-UQ7AKVKN-BJbw-Imf.js.gz +0 -0
  125. package/dist/client/assets/{diagram-VSXAHHWV-Dxp1MKPT.js → diagram-VSXAHHWV-CSfl8yS7.js} +1 -1
  126. package/dist/client/assets/diagram-VSXAHHWV-CSfl8yS7.js.br +0 -0
  127. package/dist/client/assets/diagram-VSXAHHWV-CSfl8yS7.js.gz +0 -0
  128. package/dist/client/assets/{diagram-VX7I27RA-BKbWvvEr.js → diagram-VX7I27RA-zV-Vrv89.js} +1 -1
  129. package/dist/client/assets/diagram-VX7I27RA-zV-Vrv89.js.br +0 -0
  130. package/dist/client/assets/{diagram-VX7I27RA-BKbWvvEr.js.gz → diagram-VX7I27RA-zV-Vrv89.js.gz} +0 -0
  131. package/dist/client/assets/{diagram-Z3DM3KII-BZnNaP7F.js → diagram-Z3DM3KII-CRnE-snw.js} +1 -1
  132. package/dist/client/assets/diagram-Z3DM3KII-CRnE-snw.js.br +0 -0
  133. package/dist/client/assets/diagram-Z3DM3KII-CRnE-snw.js.gz +0 -0
  134. package/dist/client/assets/{ebnfDiagram-PWID7BFC-BXVlN_P7.js → ebnfDiagram-PWID7BFC-CE30oImc.js} +1 -1
  135. package/dist/client/assets/ebnfDiagram-PWID7BFC-CE30oImc.js.br +0 -0
  136. package/dist/client/assets/ebnfDiagram-PWID7BFC-CE30oImc.js.gz +0 -0
  137. package/dist/client/assets/{erDiagram-RLTQ6QDP-CEdYDZU7.js → erDiagram-RLTQ6QDP-D-5bIySI.js} +1 -1
  138. package/dist/client/assets/erDiagram-RLTQ6QDP-D-5bIySI.js.br +0 -0
  139. package/dist/client/assets/erDiagram-RLTQ6QDP-D-5bIySI.js.gz +0 -0
  140. package/dist/client/assets/{flowDiagram-HODETNUW-Bbw8GPCZ.js → flowDiagram-HODETNUW-E_jPKtQR.js} +1 -1
  141. package/dist/client/assets/flowDiagram-HODETNUW-E_jPKtQR.js.br +0 -0
  142. package/dist/client/assets/flowDiagram-HODETNUW-E_jPKtQR.js.gz +0 -0
  143. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-CcFbtP2y.js → ganttDiagram-EL5Y4UJY-BWvLOUzC.js} +1 -1
  144. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BWvLOUzC.js.br +0 -0
  145. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BWvLOUzC.js.gz +0 -0
  146. package/dist/client/assets/gestureArbiter-DszagC-d.js +1 -0
  147. package/dist/client/assets/gestureArbiter-DszagC-d.js.br +0 -0
  148. package/dist/client/assets/gestureArbiter-DszagC-d.js.gz +0 -0
  149. package/dist/client/assets/git-compare-BlcHEuBI.js +1 -0
  150. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-Eiust154.js → gitGraphDiagram-WWUBYQGX-nOlVCBmL.js} +1 -1
  151. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-nOlVCBmL.js.br +0 -0
  152. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-nOlVCBmL.js.gz +0 -0
  153. package/dist/client/assets/index-CA1fR_jI.css +1 -0
  154. package/dist/client/assets/index-CA1fR_jI.css.br +0 -0
  155. package/dist/client/assets/index-CA1fR_jI.css.gz +0 -0
  156. package/dist/client/assets/{infoDiagram-27XIBGKW-DUmaNZJW.js → infoDiagram-27XIBGKW-CjVm9Lzz.js} +1 -1
  157. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-qTwgXfx_.js → ishikawaDiagram-5VMMS53U-DmVMaGVp.js} +1 -1
  158. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-qTwgXfx_.js.br → ishikawaDiagram-5VMMS53U-DmVMaGVp.js.br} +0 -0
  159. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DmVMaGVp.js.gz +0 -0
  160. package/dist/client/assets/{journeyDiagram-3NMN7TZE-DKy1msWo.js → journeyDiagram-3NMN7TZE-DLwkoAy9.js} +1 -1
  161. package/dist/client/assets/journeyDiagram-3NMN7TZE-DLwkoAy9.js.br +0 -0
  162. package/dist/client/assets/journeyDiagram-3NMN7TZE-DLwkoAy9.js.gz +0 -0
  163. package/dist/client/assets/{kanban-definition-UXKFOSKX-BxibybDd.js → kanban-definition-UXKFOSKX-GWkp_QiO.js} +1 -1
  164. package/dist/client/assets/kanban-definition-UXKFOSKX-GWkp_QiO.js.br +0 -0
  165. package/dist/client/assets/kanban-definition-UXKFOSKX-GWkp_QiO.js.gz +0 -0
  166. package/dist/client/assets/{layout-Bh6fKHRM.js → layout-DFg5a61y.js} +1 -1
  167. package/dist/client/assets/layout-DFg5a61y.js.br +0 -0
  168. package/dist/client/assets/layout-DFg5a61y.js.gz +0 -0
  169. package/dist/client/assets/{linear-SRlL3VWX.js → linear-B0OdJLe1.js} +1 -1
  170. package/dist/client/assets/{linear-SRlL3VWX.js.br → linear-B0OdJLe1.js.br} +0 -0
  171. package/dist/client/assets/linear-B0OdJLe1.js.gz +0 -0
  172. package/dist/client/assets/link-BnxdKJ7b.js +8 -0
  173. package/dist/client/assets/link-BnxdKJ7b.js.br +0 -0
  174. package/dist/client/assets/link-BnxdKJ7b.js.gz +0 -0
  175. package/dist/client/assets/list-tree-Bou8VSzi.js +1 -0
  176. package/dist/client/assets/loader-circle-q7h8uwFI.js +1 -0
  177. package/dist/client/assets/maximize-2-BGTBw-Ku.js +1 -0
  178. package/dist/client/assets/{mermaid.core-D0bcNdw3.js → mermaid.core-DQA3ykXv.js} +5 -5
  179. package/dist/client/assets/mermaid.core-DQA3ykXv.js.br +0 -0
  180. package/dist/client/assets/mermaid.core-DQA3ykXv.js.gz +0 -0
  181. package/dist/client/assets/{mindmap-definition-YA3MSWOX-CImZ_aI0.js → mindmap-definition-YA3MSWOX-DsZAVAGP.js} +2 -2
  182. package/dist/client/assets/mindmap-definition-YA3MSWOX-DsZAVAGP.js.br +0 -0
  183. package/dist/client/assets/mindmap-definition-YA3MSWOX-DsZAVAGP.js.gz +0 -0
  184. package/dist/client/assets/passwordBootstrap-CEZSL94g.js +2 -0
  185. package/dist/client/assets/passwordBootstrap-CEZSL94g.js.br +0 -0
  186. package/dist/client/assets/passwordBootstrap-CEZSL94g.js.gz +0 -0
  187. package/dist/client/assets/{pegDiagram-XKGWAZYB-BT4pTf8O.js → pegDiagram-XKGWAZYB-C3ar01Lf.js} +1 -1
  188. package/dist/client/assets/pegDiagram-XKGWAZYB-C3ar01Lf.js.br +0 -0
  189. package/dist/client/assets/pegDiagram-XKGWAZYB-C3ar01Lf.js.gz +0 -0
  190. package/dist/client/assets/{pieDiagram-E7YTZNPT-C5K58ien.js → pieDiagram-E7YTZNPT-C8LIa9gE.js} +1 -1
  191. package/dist/client/assets/pieDiagram-E7YTZNPT-C8LIa9gE.js.br +0 -0
  192. package/dist/client/assets/pieDiagram-E7YTZNPT-C8LIa9gE.js.gz +0 -0
  193. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-DzSugYXz.js → quadrantDiagram-AXDQQJYC-BuRJ1f9F.js} +1 -1
  194. package/dist/client/assets/quadrantDiagram-AXDQQJYC-BuRJ1f9F.js.br +0 -0
  195. package/dist/client/assets/quadrantDiagram-AXDQQJYC-BuRJ1f9F.js.gz +0 -0
  196. package/dist/client/assets/quote-qXNI_NTi.js +1 -0
  197. package/dist/client/assets/{railroadDiagram-O6MQD6OU-BY07SouQ.js → railroadDiagram-O6MQD6OU-D7iZy3dO.js} +1 -1
  198. package/dist/client/assets/railroadDiagram-O6MQD6OU-D7iZy3dO.js.br +0 -0
  199. package/dist/client/assets/railroadDiagram-O6MQD6OU-D7iZy3dO.js.gz +0 -0
  200. package/dist/client/assets/rdpSession-DUBlG26K.js +1 -0
  201. package/dist/client/assets/rdpSession-DUBlG26K.js.br +0 -0
  202. package/dist/client/assets/rdpSession-DUBlG26K.js.gz +0 -0
  203. package/dist/client/assets/{requirementDiagram-BXWQKSXE-C7WieVuE.js → requirementDiagram-BXWQKSXE-DhY8g8qK.js} +1 -1
  204. package/dist/client/assets/requirementDiagram-BXWQKSXE-DhY8g8qK.js.br +0 -0
  205. package/dist/client/assets/requirementDiagram-BXWQKSXE-DhY8g8qK.js.gz +0 -0
  206. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-BJsDWNs4.js → sankeyDiagram-P5KCCOFB-DDA_LQcg.js} +1 -1
  207. package/dist/client/assets/sankeyDiagram-P5KCCOFB-DDA_LQcg.js.br +0 -0
  208. package/dist/client/assets/sankeyDiagram-P5KCCOFB-DDA_LQcg.js.gz +0 -0
  209. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BeJ_7853.js → sequenceDiagram-WJ2MYXX4-bWgfdfwY.js} +1 -1
  210. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BeJ_7853.js.br → sequenceDiagram-WJ2MYXX4-bWgfdfwY.js.br} +0 -0
  211. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-bWgfdfwY.js.gz +0 -0
  212. package/dist/client/assets/settings-2-B-sr3wQM.js +1 -0
  213. package/dist/client/assets/{sizeCapture-INFHLROL-DOsjXKPV.js → sizeCapture-INFHLROL-BYxi7e0R.js} +1 -1
  214. package/dist/client/assets/sizeCapture-INFHLROL-BYxi7e0R.js.br +0 -0
  215. package/dist/client/assets/sizeCapture-INFHLROL-BYxi7e0R.js.gz +0 -0
  216. package/dist/client/assets/{sparkles-e9SkpP7a.js → sparkles-CCLflSFy.js} +1 -1
  217. package/dist/client/assets/{stateDiagram-D77RDMKH-6s709_RT.js → stateDiagram-D77RDMKH-6vqC2h36.js} +1 -1
  218. package/dist/client/assets/stateDiagram-D77RDMKH-6vqC2h36.js.br +0 -0
  219. package/dist/client/assets/stateDiagram-D77RDMKH-6vqC2h36.js.gz +0 -0
  220. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Bb23lB9W.js +1 -0
  221. package/dist/client/assets/sun-B9_TfxlA.js +1 -0
  222. package/dist/client/assets/{swimlanes-42K2YHIH-5R5dw9_R.js → swimlanes-42K2YHIH-B4qrXam7.js} +1 -1
  223. package/dist/client/assets/swimlanes-42K2YHIH-B4qrXam7.js.br +0 -0
  224. package/dist/client/assets/swimlanes-42K2YHIH-B4qrXam7.js.gz +0 -0
  225. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-CQ1XJUVU.js +8 -0
  226. package/dist/client/assets/swiper-DJjq1TYT.js +1 -0
  227. package/dist/client/assets/swiper-DJjq1TYT.js.br +0 -0
  228. package/dist/client/assets/swiper-DJjq1TYT.js.gz +0 -0
  229. package/dist/client/assets/syntaxHighlight-bcOB6oww.js +4 -0
  230. package/dist/client/assets/syntaxHighlight-bcOB6oww.js.br +0 -0
  231. package/dist/client/assets/syntaxHighlight-bcOB6oww.js.gz +0 -0
  232. package/dist/client/assets/{timeline-definition-24CTP7MA-B4YN0lsx.js → timeline-definition-24CTP7MA-D0_004MF.js} +1 -1
  233. package/dist/client/assets/timeline-definition-24CTP7MA-D0_004MF.js.br +0 -0
  234. package/dist/client/assets/timeline-definition-24CTP7MA-D0_004MF.js.gz +0 -0
  235. package/dist/client/assets/triangle-alert-D3w7mA17.js +1 -0
  236. package/dist/client/assets/unplug-BSblgecr.js +1 -0
  237. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js +1 -0
  238. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.br +0 -0
  239. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.gz +0 -0
  240. package/dist/client/assets/v4-EwEgHOG0.js +1 -0
  241. package/dist/client/assets/{vennDiagram-4TSXK5OY-Wd83SmWI.js → vennDiagram-4TSXK5OY-Bqrx-47p.js} +1 -1
  242. package/dist/client/assets/vennDiagram-4TSXK5OY-Bqrx-47p.js.br +0 -0
  243. package/dist/client/assets/vennDiagram-4TSXK5OY-Bqrx-47p.js.gz +0 -0
  244. package/dist/client/assets/videoCompression-df1Ej3AR.js +3 -0
  245. package/dist/client/assets/videoCompression-df1Ej3AR.js.br +0 -0
  246. package/dist/client/assets/videoCompression-df1Ej3AR.js.gz +0 -0
  247. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-CGsYvqWN.js → wardleyDiagram-VM6X3IG4-C4LCUdfd.js} +1 -1
  248. package/dist/client/assets/wardleyDiagram-VM6X3IG4-C4LCUdfd.js.br +0 -0
  249. package/dist/client/assets/wardleyDiagram-VM6X3IG4-C4LCUdfd.js.gz +0 -0
  250. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-ednJq1_u.js → xychartDiagram-S5SC5T6Z-E5AQcZVI.js} +1 -1
  251. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-ednJq1_u.js.br → xychartDiagram-S5SC5T6Z-E5AQcZVI.js.br} +0 -0
  252. package/dist/client/assets/xychartDiagram-S5SC5T6Z-E5AQcZVI.js.gz +0 -0
  253. package/dist/client/index.html +2 -2
  254. package/dist/client/index.html.br +0 -0
  255. package/dist/client/index.html.gz +0 -0
  256. package/dist/client/sw-encrypted-background.js +1 -1
  257. package/dist/client/sw-encrypted-background.js.br +0 -0
  258. package/dist/client/sw-encrypted-background.js.gz +0 -0
  259. package/dist/client/sw.js +1 -1
  260. package/dist/client/sw.js.br +0 -0
  261. package/dist/client/sw.js.gz +0 -0
  262. package/dist/server/agent/collaborationDeliveryWorker.js +11 -0
  263. package/dist/server/agent/collaborationPrompt.js +4 -2
  264. package/dist/server/agent/collaborationRoutes.js +2 -0
  265. package/dist/server/agent/collaborationStore.js +7 -1
  266. package/dist/server/agent/sessionAttachmentRoutes.js +39 -0
  267. package/dist/server/agent/sessionChatRoutes.js +64 -0
  268. package/dist/server/agent/sessionViewModeRoutes.js +72 -0
  269. package/dist/server/android/recording.js +19 -17
  270. package/dist/server/cli.js +34 -0
  271. package/dist/server/entry.js +26 -17
  272. package/dist/server/federation/accessPolicy.js +8 -3
  273. package/dist/server/federation/authorization.js +26 -3
  274. package/dist/server/federation/invitations.js +27 -6
  275. package/dist/server/federation/relay.js +21 -3
  276. package/dist/server/federation/requestContext.js +5 -1
  277. package/dist/server/federation/resourceAccess.js +63 -0
  278. package/dist/server/federation/runtime.js +67 -18
  279. package/dist/server/federation/sessionSharing.js +39 -0
  280. package/dist/server/federation/socketDuplex.js +3 -3
  281. package/dist/server/routes/android.js +36 -7
  282. package/dist/server/routes/computer.js +14 -4
  283. package/dist/server/routes/filesystem.js +6 -3
  284. package/dist/server/routes/rdp.js +4 -3
  285. package/dist/server/routes/sharedFiles.js +51 -0
  286. package/dist/server/routes/terminal.js +83 -14
  287. package/dist/server/routes/vncReadOnly.js +134 -0
  288. package/dist/server/shared/shareResources.js +37 -0
  289. package/dist/server/todos/cli.js +91 -0
  290. package/dist/server/todos/routes.js +73 -0
  291. package/dist/server/todos/store.js +240 -0
  292. package/dist/server/todos/types.js +1 -0
  293. package/dist/server/utils/autoUpdate.js +7 -2
  294. package/dist/server/utils/clientSnapshotMaintenance.js +200 -0
  295. package/dist/server/utils/runtimeClient.js +79 -0
  296. package/dist/server/utils/serverCleanup.js +24 -0
  297. package/dist/server/utils/storageMaintenance.js +60 -0
  298. package/dist/server/utils/version.js +2 -0
  299. package/dist/server/utils/workspaceCacheMaintenance.js +158 -0
  300. package/docs/integrations.md +23 -0
  301. package/package.json +1 -1
  302. package/runtime-manifest.json +3 -3
  303. package/dist/client/assets/App-TPJoJbGD.js +0 -187
  304. package/dist/client/assets/App-TPJoJbGD.js.br +0 -0
  305. package/dist/client/assets/App-TPJoJbGD.js.gz +0 -0
  306. package/dist/client/assets/ArchitecturePanel-DzVy71gM.js +0 -9
  307. package/dist/client/assets/ArchitecturePanel-DzVy71gM.js.br +0 -0
  308. package/dist/client/assets/ArchitecturePanel-DzVy71gM.js.gz +0 -0
  309. package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js +0 -2
  310. package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js.br +0 -0
  311. package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js.gz +0 -0
  312. package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js +0 -1
  313. package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js.br +0 -0
  314. package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js.gz +0 -0
  315. package/dist/client/assets/CollaborationTaskContent-CG7g1LMH.js +0 -2
  316. package/dist/client/assets/ComputerControlView-BlI9Ai_k.js +0 -6
  317. package/dist/client/assets/ComputerControlView-BlI9Ai_k.js.br +0 -0
  318. package/dist/client/assets/ComputerControlView-BlI9Ai_k.js.gz +0 -0
  319. package/dist/client/assets/DagPlayground-V0hTKB-S.js +0 -1
  320. package/dist/client/assets/DagPlayground-V0hTKB-S.js.br +0 -0
  321. package/dist/client/assets/DagPlayground-V0hTKB-S.js.gz +0 -0
  322. package/dist/client/assets/DiffLab-DEw4y4Hk.js.br +0 -0
  323. package/dist/client/assets/DiffLab-DEw4y4Hk.js.gz +0 -0
  324. package/dist/client/assets/DiffReview-Cnnt3TMK.js +0 -1
  325. package/dist/client/assets/DiffReview-Cnnt3TMK.js.br +0 -0
  326. package/dist/client/assets/DiffReview-Cnnt3TMK.js.gz +0 -0
  327. package/dist/client/assets/DiffReviewLab-CDXsy0jE.js.br +0 -0
  328. package/dist/client/assets/DiffReviewLab-CDXsy0jE.js.gz +0 -0
  329. package/dist/client/assets/DiffViewer-Dh40XiCM.js +0 -37
  330. package/dist/client/assets/DiffViewer-Dh40XiCM.js.br +0 -0
  331. package/dist/client/assets/DiffViewer-Dh40XiCM.js.gz +0 -0
  332. package/dist/client/assets/ModelPreview-BEiOgE0G.js.br +0 -0
  333. package/dist/client/assets/ModelPreview-BEiOgE0G.js.gz +0 -0
  334. package/dist/client/assets/RightSidebar-DiECnX5D.js +0 -1679
  335. package/dist/client/assets/RightSidebar-DiECnX5D.js.br +0 -0
  336. package/dist/client/assets/RightSidebar-DiECnX5D.js.gz +0 -0
  337. package/dist/client/assets/abnfDiagram-VCTEODGH-ByzlUu_B.js.br +0 -0
  338. package/dist/client/assets/abnfDiagram-VCTEODGH-ByzlUu_B.js.gz +0 -0
  339. package/dist/client/assets/app-CKAFlgMD.js +0 -35
  340. package/dist/client/assets/app-CKAFlgMD.js.br +0 -0
  341. package/dist/client/assets/app-CKAFlgMD.js.gz +0 -0
  342. package/dist/client/assets/arc-BA6JM6vl.js.br +0 -0
  343. package/dist/client/assets/arc-BA6JM6vl.js.gz +0 -0
  344. package/dist/client/assets/architectureDiagram-5GKGNRK7-hCHxOfKw.js.br +0 -0
  345. package/dist/client/assets/blockDiagram-I7D4REHJ-OmEN9hUB.js.br +0 -0
  346. package/dist/client/assets/blockDiagram-I7D4REHJ-OmEN9hUB.js.gz +0 -0
  347. package/dist/client/assets/c4Diagram-7LVT6UL2-DfLTv8zh.js.br +0 -0
  348. package/dist/client/assets/c4Diagram-7LVT6UL2-DfLTv8zh.js.gz +0 -0
  349. package/dist/client/assets/channel-gcmN0N0m.js +0 -1
  350. package/dist/client/assets/chunk-F27PBJKO-yxCv2Uqk.js.br +0 -0
  351. package/dist/client/assets/chunk-F27PBJKO-yxCv2Uqk.js.gz +0 -0
  352. package/dist/client/assets/chunk-IMKFNOWR-CdPjlb9f.js.br +0 -0
  353. package/dist/client/assets/chunk-IMKFNOWR-CdPjlb9f.js.gz +0 -0
  354. package/dist/client/assets/chunk-SVP7TREG-D1tOJung.js.br +0 -0
  355. package/dist/client/assets/chunk-SVP7TREG-D1tOJung.js.gz +0 -0
  356. package/dist/client/assets/chunk-TICWLB2K-DZjDfYNw.js.br +0 -0
  357. package/dist/client/assets/chunk-TICWLB2K-DZjDfYNw.js.gz +0 -0
  358. package/dist/client/assets/classDiagram-ZZMXUADV-k4BRymfG.js +0 -1
  359. package/dist/client/assets/classDiagram-v2-VYDZK3BY-k4BRymfG.js +0 -1
  360. package/dist/client/assets/cose-bilkent-JH36ORCC-C4Wb5lqD.js.br +0 -0
  361. package/dist/client/assets/cose-bilkent-JH36ORCC-C4Wb5lqD.js.gz +0 -0
  362. package/dist/client/assets/cynefin-OW5HDTMX-BvWKB1Xk.js.br +0 -0
  363. package/dist/client/assets/cynefin-OW5HDTMX-BvWKB1Xk.js.gz +0 -0
  364. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-7tAkHD2P.js.br +0 -0
  365. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-7tAkHD2P.js.gz +0 -0
  366. package/dist/client/assets/dagre-GXQ25YYZ-Bs6IPwks.js.br +0 -0
  367. package/dist/client/assets/dagre-GXQ25YYZ-Bs6IPwks.js.gz +0 -0
  368. package/dist/client/assets/diagram-S7CK7UJ4-CmYXaTya.js.br +0 -0
  369. package/dist/client/assets/diagram-S7CK7UJ4-CmYXaTya.js.gz +0 -0
  370. package/dist/client/assets/diagram-UQ7AKVKN-CqxoefB7.js.br +0 -0
  371. package/dist/client/assets/diagram-UQ7AKVKN-CqxoefB7.js.gz +0 -0
  372. package/dist/client/assets/diagram-VSXAHHWV-Dxp1MKPT.js.br +0 -0
  373. package/dist/client/assets/diagram-VSXAHHWV-Dxp1MKPT.js.gz +0 -0
  374. package/dist/client/assets/diagram-VX7I27RA-BKbWvvEr.js.br +0 -0
  375. package/dist/client/assets/diagram-Z3DM3KII-BZnNaP7F.js.br +0 -0
  376. package/dist/client/assets/diagram-Z3DM3KII-BZnNaP7F.js.gz +0 -0
  377. package/dist/client/assets/ebnfDiagram-PWID7BFC-BXVlN_P7.js.br +0 -0
  378. package/dist/client/assets/ebnfDiagram-PWID7BFC-BXVlN_P7.js.gz +0 -0
  379. package/dist/client/assets/erDiagram-RLTQ6QDP-CEdYDZU7.js.br +0 -0
  380. package/dist/client/assets/erDiagram-RLTQ6QDP-CEdYDZU7.js.gz +0 -0
  381. package/dist/client/assets/flowDiagram-HODETNUW-Bbw8GPCZ.js.br +0 -0
  382. package/dist/client/assets/flowDiagram-HODETNUW-Bbw8GPCZ.js.gz +0 -0
  383. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CcFbtP2y.js.br +0 -0
  384. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CcFbtP2y.js.gz +0 -0
  385. package/dist/client/assets/gestureArbiter-sdzs-66-.js +0 -1
  386. package/dist/client/assets/gestureArbiter-sdzs-66-.js.br +0 -0
  387. package/dist/client/assets/gestureArbiter-sdzs-66-.js.gz +0 -0
  388. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Eiust154.js.br +0 -0
  389. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Eiust154.js.gz +0 -0
  390. package/dist/client/assets/index-DtPsPZ7W.css +0 -1
  391. package/dist/client/assets/index-DtPsPZ7W.css.br +0 -0
  392. package/dist/client/assets/index-DtPsPZ7W.css.gz +0 -0
  393. package/dist/client/assets/ishikawaDiagram-5VMMS53U-qTwgXfx_.js.gz +0 -0
  394. package/dist/client/assets/journeyDiagram-3NMN7TZE-DKy1msWo.js.br +0 -0
  395. package/dist/client/assets/journeyDiagram-3NMN7TZE-DKy1msWo.js.gz +0 -0
  396. package/dist/client/assets/kanban-definition-UXKFOSKX-BxibybDd.js.br +0 -0
  397. package/dist/client/assets/kanban-definition-UXKFOSKX-BxibybDd.js.gz +0 -0
  398. package/dist/client/assets/layout-Bh6fKHRM.js.br +0 -0
  399. package/dist/client/assets/layout-Bh6fKHRM.js.gz +0 -0
  400. package/dist/client/assets/linear-SRlL3VWX.js.gz +0 -0
  401. package/dist/client/assets/mermaid.core-D0bcNdw3.js.br +0 -0
  402. package/dist/client/assets/mermaid.core-D0bcNdw3.js.gz +0 -0
  403. package/dist/client/assets/mindmap-definition-YA3MSWOX-CImZ_aI0.js.br +0 -0
  404. package/dist/client/assets/mindmap-definition-YA3MSWOX-CImZ_aI0.js.gz +0 -0
  405. package/dist/client/assets/passwordBootstrap-f7-mFb1b.js +0 -2
  406. package/dist/client/assets/passwordBootstrap-f7-mFb1b.js.br +0 -0
  407. package/dist/client/assets/passwordBootstrap-f7-mFb1b.js.gz +0 -0
  408. package/dist/client/assets/pegDiagram-XKGWAZYB-BT4pTf8O.js.br +0 -0
  409. package/dist/client/assets/pegDiagram-XKGWAZYB-BT4pTf8O.js.gz +0 -0
  410. package/dist/client/assets/pieDiagram-E7YTZNPT-C5K58ien.js.br +0 -0
  411. package/dist/client/assets/pieDiagram-E7YTZNPT-C5K58ien.js.gz +0 -0
  412. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DzSugYXz.js.br +0 -0
  413. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DzSugYXz.js.gz +0 -0
  414. package/dist/client/assets/railroadDiagram-O6MQD6OU-BY07SouQ.js.br +0 -0
  415. package/dist/client/assets/railroadDiagram-O6MQD6OU-BY07SouQ.js.gz +0 -0
  416. package/dist/client/assets/rdpSession-RNjO6yLw.js +0 -1
  417. package/dist/client/assets/rdpSession-RNjO6yLw.js.br +0 -0
  418. package/dist/client/assets/rdpSession-RNjO6yLw.js.gz +0 -0
  419. package/dist/client/assets/referenceLongPress-B9K9yPKR.js +0 -1
  420. package/dist/client/assets/referenceLongPress-B9K9yPKR.js.br +0 -0
  421. package/dist/client/assets/referenceLongPress-B9K9yPKR.js.gz +0 -0
  422. package/dist/client/assets/requirementDiagram-BXWQKSXE-C7WieVuE.js.br +0 -0
  423. package/dist/client/assets/requirementDiagram-BXWQKSXE-C7WieVuE.js.gz +0 -0
  424. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BJsDWNs4.js.br +0 -0
  425. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BJsDWNs4.js.gz +0 -0
  426. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BeJ_7853.js.gz +0 -0
  427. package/dist/client/assets/sizeCapture-INFHLROL-DOsjXKPV.js.br +0 -0
  428. package/dist/client/assets/sizeCapture-INFHLROL-DOsjXKPV.js.gz +0 -0
  429. package/dist/client/assets/stateDiagram-D77RDMKH-6s709_RT.js.br +0 -0
  430. package/dist/client/assets/stateDiagram-D77RDMKH-6s709_RT.js.gz +0 -0
  431. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-B43A9Hsz.js +0 -1
  432. package/dist/client/assets/swimlanes-42K2YHIH-5R5dw9_R.js.br +0 -0
  433. package/dist/client/assets/swimlanes-42K2YHIH-5R5dw9_R.js.gz +0 -0
  434. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoFbqN_4.js +0 -8
  435. package/dist/client/assets/timeline-definition-24CTP7MA-B4YN0lsx.js.br +0 -0
  436. package/dist/client/assets/timeline-definition-24CTP7MA-B4YN0lsx.js.gz +0 -0
  437. package/dist/client/assets/triangle-alert-BzBDJvJX.js +0 -1
  438. package/dist/client/assets/vennDiagram-4TSXK5OY-Wd83SmWI.js.br +0 -0
  439. package/dist/client/assets/vennDiagram-4TSXK5OY-Wd83SmWI.js.gz +0 -0
  440. package/dist/client/assets/videoCompression-Bsw--tMn.js +0 -3
  441. package/dist/client/assets/videoCompression-Bsw--tMn.js.br +0 -0
  442. package/dist/client/assets/videoCompression-Bsw--tMn.js.gz +0 -0
  443. package/dist/client/assets/wardleyDiagram-VM6X3IG4-CGsYvqWN.js.br +0 -0
  444. package/dist/client/assets/wardleyDiagram-VM6X3IG4-CGsYvqWN.js.gz +0 -0
  445. package/dist/client/assets/xychartDiagram-S5SC5T6Z-ednJq1_u.js.gz +0 -0
  446. /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css → swiper-C2J0D0kV.css} +0 -0
  447. /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css.br → swiper-C2J0D0kV.css.br} +0 -0
  448. /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css.gz → swiper-C2J0D0kV.css.gz} +0 -0
package/dist/client/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let c={};const r=e=>n(e,o),d={module:{uri:o},exports:c,require:r};s[o]=Promise.all(i.map(e=>d[e]||r(e))).then(e=>(a(...e),c))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"3168c3a96b6b28066432b083cbf3a4ef"},{url:"assets/app-CKAFlgMD.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-Dea8wJF3.js",revision:null},{url:"assets/index-DtPsPZ7W.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
1
+ if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let r={};const c=e=>n(e,o),d={module:{uri:o},exports:r,require:c};s[o]=Promise.all(i.map(e=>d[e]||c(e))).then(e=>(a(...e),r))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"d9f1254be198520fd331492bd81d83ec"},{url:"assets/app-BMJesFDU.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-Dea8wJF3.js",revision:null},{url:"assets/index-CA1fR_jI.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
Binary file
Binary file
@@ -120,6 +120,17 @@ export class CollaborationDeliveryWorker {
120
120
  const pending = store.inbox(id, { pendingOnly: true, limit: 1 });
121
121
  if (!pending.length)
122
122
  return;
123
+ // Removal is an observed inventory fact, so this recipient cannot recover
124
+ // through a network retry. Preserve the message as a failed delivery.
125
+ if (route.state === 'offline' && (route.reason === 'SESSION_REMOVED' || route.reason === 'SESSION_REMOVED_DURING_RECOVERY')) {
126
+ const message = pending[0];
127
+ store.recordTransport(message.id, { ...store.diagnostic(message.id), relay_online: null, peer_reachable: false,
128
+ attempt_count: store.diagnostic(message.id)?.attempt_count ?? 0, next_retry_at: null,
129
+ last_error: route.reason, checked_at: Date.now(), route_state: route.state, route_diagnostics: route.diagnostics });
130
+ store.fail(message.id, route.reason);
131
+ this.failures.delete(id);
132
+ return;
133
+ }
123
134
  if (route.state !== 'ready' || !route.write) {
124
135
  this.retry(id, pending, route.reason ?? route.state, false, route);
125
136
  return;
@@ -89,7 +89,7 @@ export function formatCollaborationDelivery(input) {
89
89
  const sourceSession = message.fromSessionId ? sessionsById.get(message.fromSessionId) : null;
90
90
  const source = message.fromSessionId
91
91
  ? sanitizeCollaborationName(sourceSession?.name ?? message.fromSessionId)
92
- : message.integrationOrigin ? `后台接入 ${sanitizeCollaborationName(message.integrationOrigin.integrationId, 80)}` : '用户';
92
+ : message.integrationOrigin ? message.integrationOrigin.source === 'session-chat' ? '网页对话用户' : `后台接入 ${sanitizeCollaborationName(message.integrationOrigin.integrationId, 80)}` : '用户';
93
93
  const token = tokens.get(message.id) ?? message.id;
94
94
  const bytes = Buffer.byteLength(message.content);
95
95
  // A remote recipient's CLI cannot detect its identity (the session is not
@@ -103,7 +103,9 @@ export function formatCollaborationDelivery(input) {
103
103
  const fannedNames = (message.fanOutIds ?? [])
104
104
  .map((sessionId) => sanitizeCollaborationName(sessionsById.get(sessionId)?.name ?? sessionId));
105
105
  blocks.push(formatCollaborationMessage({ ...message, content: body }, source, fannedNames, fence, token));
106
- if (message.integrationOrigin)
106
+ if (message.integrationOrigin?.source === 'session-chat')
107
+ blocks.push(`此消息来自用户的普通对话界面。请自然地与用户交流,并用 td collab --session ${input.targetSessionId} reply ${token} \"答复正文\" --response-kind result --idempotency-key <稳定唯一key> --text 将面向用户的答复写回对话。终端中的普通输出不会成为聊天回复。需要补充问题时也使用 reply;不要仅在终端打印答案。`);
108
+ else if (message.integrationOrigin)
107
109
  blocks.push(`此消息来自后台程序,使用原消息 id 回复:td collab --session ${input.targetSessionId} reply ${token} "答复正文" --response-kind result --idempotency-key <稳定唯一key> --text\n需要时用 --response-kind ack|progress 明确回复收到或进展;result 提交结果。回复持久保存为 stored 并主动推送给后台,不创建看板任务,不代表用户验收。`);
108
110
  }
109
111
  // The shell header names the group only when every block belongs to one;
@@ -162,6 +162,8 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, di
162
162
  };
163
163
  router.get('/capabilities', run((_req, res) => {
164
164
  res.json({ protocol_version: 2, server_version: getTermdockVersion(), limits: COLLAB_LIMITS,
165
+ relay_authorization_errors: true, relay_authorization_errors_min_version: '1.4.351',
166
+ relay_self_target_guard: true, relay_self_target_guard_min_version: '1.4.351',
165
167
  route_diagnostics: !!diagnoseRoute, route_identity_recovery: !!diagnoseRoute, route_identity_recovery_min_version: '1.4.321',
166
168
  agent_launch_generation_consistency: true, agent_launch_generation_consistency_min_version: '1.4.322',
167
169
  terminal_input_check_diagnostics: true,
@@ -727,10 +727,16 @@ export class CollaborationStore {
727
727
  this.applyContext(incoming, this.context(group.id));
728
728
  if (existing && stableJson(existing) === stableJson(incoming))
729
729
  return;
730
+ // Remote directory snapshots contain output/observation timestamps that
731
+ // change on every poll. Keep them current for readers without rewriting
732
+ // the complete message journal or notifying durable-change subscribers.
733
+ const metadataChanged = !existing
734
+ || stableJson({ ...existing, remoteSessions: undefined }) !== stableJson({ ...incoming, remoteSessions: undefined });
730
735
  this.document.groups = [...this.document.groups.filter((item) => item.id !== group.id), incoming];
731
736
  if (group.deleted)
732
737
  this.document.messages = this.document.messages.filter((item) => item.groupId !== group.id);
733
- this.persist();
738
+ if (metadataChanged)
739
+ this.persist();
734
740
  }
735
741
  /** Promote the source group and its complete history in one atomic file replacement. */
736
742
  promoteGroup(id, group, expectedUpdatedAt) {
@@ -0,0 +1,39 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { promises as fs } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { Router } from 'express';
5
+ import { encryptedRequestSubject } from '../federation/requestContext.js';
6
+ import { handleFileUpload } from '../routes/filesystem.js';
7
+ /** A Session input capability may add new attachments, never choose a server path. */
8
+ export function sessionAttachmentRoutes(directory, resolve) {
9
+ const router = Router();
10
+ router.post('/:sessionId/chat/attachments', async (req, res) => {
11
+ const subject = encryptedRequestSubject(req), session = subject && resolve(req.params.sessionId);
12
+ if (!session) {
13
+ res.status(404).json({ error: '会话不可用' });
14
+ return;
15
+ }
16
+ if (Object.keys(req.query).some(key => key !== 'fileCount')) {
17
+ res.status(400).json({ error: '附件不能指定服务端保存目录' });
18
+ return;
19
+ }
20
+ let destination;
21
+ try {
22
+ const root = path.resolve(directory, createHash('sha256').update(session).digest('hex'));
23
+ await fs.mkdir(root, { recursive: true, mode: 0o700 });
24
+ if (await fs.realpath(root) !== root)
25
+ throw new Error('附件目录不可用');
26
+ destination = await fs.mkdtemp(path.join(root, 'upload-'));
27
+ await handleFileUpload(req, res, destination);
28
+ }
29
+ catch {
30
+ if (!res.headersSent && !res.destroyed)
31
+ res.status(500).json({ error: '附件上传失败,请重试' });
32
+ }
33
+ finally {
34
+ if (destination)
35
+ await fs.rmdir(destination).catch(() => { });
36
+ }
37
+ });
38
+ return router;
39
+ }
@@ -0,0 +1,64 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { Router } from 'express';
3
+ import { encryptedRequestSubject } from '../federation/requestContext.js';
4
+ /** Clients authorized to view this Session share its durable chat history.
5
+ * Per-device delivery addresses remain stable for retries and explicit replies. */
6
+ export function sessionChatRoutes(options) {
7
+ const router = Router();
8
+ const context = (req) => {
9
+ const session = options.resolve(String(req.params.sessionId));
10
+ const subject = encryptedRequestSubject(req);
11
+ if (!session || !subject)
12
+ return null;
13
+ const principal = `webchat-${createHash('sha256').update(subject).digest('hex').slice(0, 48)}`;
14
+ const groupName = `Session 对话 ${session.sessionId}`;
15
+ return { session, principal, groupName };
16
+ };
17
+ router.get('/:sessionId/chat', (req, res) => {
18
+ const ctx = context(req);
19
+ if (!ctx) {
20
+ res.status(404).json({ error: '会话不可用,请刷新连接' });
21
+ return;
22
+ }
23
+ const group = options.store.list().find(g => g.name === ctx.groupName && !g.federated && g.sessionIds.length === 1 && g.sessionIds[0] === ctx.session.sessionId);
24
+ const canSeeRequest = (message) => message?.integrationOrigin?.source === 'session-chat';
25
+ const messages = group ? options.store.listMessages(group.id, 500).filter(message => {
26
+ if (canSeeRequest(message))
27
+ return true;
28
+ const original = message.toPrincipalId && message.replyTo ? options.store.getMessage(message.replyTo) : null;
29
+ return original?.groupId === group.id && message.toPrincipalId === original.integrationOrigin?.integrationId && canSeeRequest(original);
30
+ }).map(m => ({ id: m.id, role: m.toPrincipalId ? 'assistant' : 'user', content: m.content, createdAt: m.createdAt, status: m.status === 'read' ? 'delivered' : m.status, replyTo: m.replyTo, requestId: m.idempotencyKey, responseKind: m.responseKind })) : [];
31
+ res.setHeader('Cache-Control', 'no-store');
32
+ res.json({ messages, agentAvailable: !!ctx.session.agent, agent: ctx.session.agent ? { slug: ctx.session.agent.slug, displayName: ctx.session.agent.displayName || ctx.session.agent.slug } : null });
33
+ });
34
+ router.post('/:sessionId/chat', (req, res) => {
35
+ const ctx = context(req);
36
+ if (!ctx) {
37
+ res.status(404).json({ error: '会话不可用,请刷新连接' });
38
+ return;
39
+ }
40
+ if (!ctx.session.agent) {
41
+ res.status(409).json({ error: '当前会话未识别到 Agent,请切换终端确认 Agent 已启动' });
42
+ return;
43
+ }
44
+ const body = req.body;
45
+ if (!body || Object.keys(body).some(k => !['content', 'requestId'].includes(k)) || typeof body.content !== 'string' || !body.content.trim() || Buffer.byteLength(body.content) > 32000 || typeof body.requestId !== 'string' || !/^[a-zA-Z0-9_-]{16,100}$/.test(body.requestId)) {
46
+ res.status(400).json({ error: '消息为空、过长或请求无效' });
47
+ return;
48
+ }
49
+ try {
50
+ let group = options.store.list().find(g => g.name === ctx.groupName && !g.federated && g.sessionIds.length === 1 && g.sessionIds[0] === ctx.session.sessionId);
51
+ if (!group) {
52
+ group = options.store.save({ name: ctx.groupName, sessionIds: [ctx.session.sessionId] });
53
+ options.store.setLocalGroupArchived(group.id, true, group.updatedAt, `chat-${group.id}`);
54
+ }
55
+ const [message] = options.store.send({ groupId: group.id, fromSessionId: null, toSessionIds: [ctx.session.sessionId], kind: 'ask', content: body.content.trim(), integrationOrigin: { integrationId: ctx.principal, source: 'session-chat' }, idempotencyKey: body.requestId, threadId: ctx.principal });
56
+ options.deliver(ctx.session.sessionId);
57
+ res.json({ id: message.id, status: message.status, createdAt: message.createdAt });
58
+ }
59
+ catch (error) {
60
+ res.status(409).json({ error: error instanceof Error ? error.message : '发送失败,草稿已保留' });
61
+ }
62
+ });
63
+ return router;
64
+ }
@@ -0,0 +1,72 @@
1
+ import { Router } from 'express';
2
+ import { readFileSync, mkdirSync, writeFileSync, renameSync, unlinkSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { encryptedRequestSubject } from '../federation/requestContext.js';
6
+ export class SessionViewModeStore {
7
+ filePath;
8
+ constructor(filePath) {
9
+ this.filePath = filePath;
10
+ }
11
+ read() {
12
+ try {
13
+ const data = JSON.parse(readFileSync(this.filePath, 'utf8'));
14
+ if (data.version !== 1 || !data.sessions || typeof data.sessions !== 'object' || Array.isArray(data.sessions))
15
+ throw new Error('Invalid session view preferences');
16
+ for (const value of Object.values(data.sessions))
17
+ if (!value || !['terminal', 'chat'].includes(value.mode) || !Number.isSafeInteger(value.updatedAt))
18
+ throw new Error('Invalid session view preference');
19
+ return data.sessions;
20
+ }
21
+ catch (error) {
22
+ if (error.code === 'ENOENT')
23
+ return {};
24
+ throw error;
25
+ }
26
+ }
27
+ get(id) { const records = this.read(); return Object.prototype.hasOwnProperty.call(records, id) ? records[id] : null; }
28
+ set(id, mode) {
29
+ const records = this.read(), previous = Object.prototype.hasOwnProperty.call(records, id) ? records[id] : null;
30
+ const next = { mode, updatedAt: Math.max(Date.now(), (previous?.updatedAt || 0) + 1) };
31
+ mkdirSync(dirname(this.filePath), { recursive: true, mode: 0o700 });
32
+ const temporary = `${this.filePath}.${randomUUID()}.tmp`;
33
+ try {
34
+ writeFileSync(temporary, JSON.stringify({ version: 1, sessions: { ...records, [id]: next } }), { mode: 0o600, flag: 'wx' });
35
+ renameSync(temporary, this.filePath);
36
+ }
37
+ finally {
38
+ try {
39
+ unlinkSync(temporary);
40
+ }
41
+ catch (error) {
42
+ if (error.code !== 'ENOENT')
43
+ throw error;
44
+ }
45
+ }
46
+ return next;
47
+ }
48
+ }
49
+ export function sessionViewModeRoutes(store, resolve) {
50
+ const router = Router();
51
+ router.route('/:sessionId/view-mode').get((req, res) => {
52
+ const id = encryptedRequestSubject(req) && resolve(req.params.sessionId);
53
+ if (!id) {
54
+ res.status(404).json({ error: '会话不可用' });
55
+ return;
56
+ }
57
+ res.setHeader('Cache-Control', 'no-store');
58
+ res.json(store.get(id) || { mode: null, updatedAt: 0 });
59
+ }).put((req, res) => {
60
+ const id = encryptedRequestSubject(req) && resolve(req.params.sessionId);
61
+ if (!id) {
62
+ res.status(404).json({ error: '会话不可用' });
63
+ return;
64
+ }
65
+ if (!req.body || Object.keys(req.body).some(key => key !== 'mode') || !['chat', 'terminal'].includes(req.body.mode)) {
66
+ res.status(400).json({ error: '显示模式无效' });
67
+ return;
68
+ }
69
+ res.json(store.set(id, req.body.mode));
70
+ });
71
+ return router;
72
+ }
@@ -43,28 +43,29 @@ export class AndroidRecordings {
43
43
  }
44
44
  })();
45
45
  }
46
- async list(serial) {
46
+ async list(serial, ownerId) {
47
47
  await this.load();
48
- return [...this.jobs.values()].filter(job => job.info.serial === serial && !job.info.savedPath).map(job => ({ ...job.info }));
48
+ return [...this.jobs.values()].filter(job => job.info.serial === serial && !job.info.savedPath && job.info.ownerId === ownerId).map(job => ({ ...job.info }));
49
49
  }
50
- start(serial) {
51
- const pending = this.starts.get(serial);
50
+ start(serial, ownerId) {
51
+ const key = JSON.stringify([serial, ownerId]);
52
+ const pending = this.starts.get(key);
52
53
  if (pending)
53
54
  return pending;
54
- const promise = this.startNew(serial).finally(() => this.starts.delete(serial));
55
- this.starts.set(serial, promise);
55
+ const promise = this.startNew(serial, ownerId).finally(() => this.starts.delete(key));
56
+ this.starts.set(key, promise);
56
57
  return promise;
57
58
  }
58
- async startNew(serial) {
59
+ async startNew(serial, ownerId) {
59
60
  await this.load();
60
- const active = [...this.jobs.values()].find(job => job.info.serial === serial && job.child);
61
+ const active = [...this.jobs.values()].find(job => job.info.serial === serial && job.info.ownerId === ownerId && job.child);
61
62
  if (active)
62
63
  return { ...active.info };
63
64
  const { bin, serverJar } = await resolveScrcpyBinaries();
64
65
  if ([...this.jobs.values()].filter(job => ['starting', 'recording', 'stopping'].includes(job.info.status)).length >= 3)
65
66
  throw new Error('同时最多录制三个设备');
66
67
  const id = randomUUID();
67
- const job = { info: { id, serial, name: `termdock-recording-${id}.mp4`, size: 0, startedAt: Date.now(), status: 'starting' } };
68
+ const job = { info: { id, serial, name: `termdock-recording-${id}.mp4`, size: 0, startedAt: Date.now(), status: 'starting', ...(ownerId ? { ownerId } : {}) } };
68
69
  this.jobs.set(id, job);
69
70
  await this.persist(job);
70
71
  const child = spawn(bin, [
@@ -120,15 +121,16 @@ export class AndroidRecordings {
120
121
  await this.persist(job);
121
122
  return { ...job.info };
122
123
  }
123
- async get(id) {
124
+ async get(id, ownerId) {
124
125
  await this.load();
125
126
  const job = this.jobs.get(id);
126
- if (!job)
127
+ if (!job || ownerId && job.info.ownerId !== ownerId)
127
128
  throw new Error('录像不存在');
128
129
  return job;
129
130
  }
130
- async stop(id) {
131
- const job = await this.get(id);
131
+ async info(id, ownerId) { return { ...(await this.get(id, ownerId)).info }; }
132
+ async stop(id, ownerId) {
133
+ const job = await this.get(id, ownerId);
132
134
  if (job.child && job.info.status !== 'stopping') {
133
135
  job.info.status = 'stopping';
134
136
  job.child.kill('SIGINT');
@@ -139,8 +141,8 @@ export class AndroidRecordings {
139
141
  await job.done;
140
142
  return { ...job.info };
141
143
  }
142
- async save(id, directory) {
143
- const job = await this.get(id);
144
+ async save(id, directory, ownerId) {
145
+ const job = await this.get(id, ownerId);
144
146
  if (job.info.savedPath) {
145
147
  if (directory && join(directory, job.info.name) !== job.info.savedPath)
146
148
  throw new Error(`录像已保存到 ${job.info.savedPath}`);
@@ -158,11 +160,11 @@ export class AndroidRecordings {
158
160
  await fs.rm(source, { force: true }).catch(() => { });
159
161
  return destination;
160
162
  }
161
- async discard(id) {
163
+ async discard(id, ownerId) {
162
164
  await this.load();
163
165
  if (!this.jobs.has(id))
164
166
  return;
165
- const job = await this.get(id);
167
+ const job = await this.get(id, ownerId);
166
168
  if (job.info.savedPath) {
167
169
  await fs.rm(join(this.directory, `${id}.json`), { force: true });
168
170
  this.jobs.delete(id);
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { parseTodoCommand, executeTodoCommand, TODO_HELP } from './todos/cli.js';
2
3
  // libuv 线程池默认只有 4 个线程,慢/挂起的异步 IO(fs.promises、crypto 等)
3
4
  // 会把池耗尽,表现为整个服务的 IO 全部卡死。必须在任何异步 fs 调用之前
4
5
  // 设置(同步 fs 不占线程池,所以放在文件体顶部仍然足够早)。
@@ -213,6 +214,7 @@ Short commands:
213
214
  pi Same as agent-plugin
214
215
  n [message] Progress reminder; run td n for help and Agent instructions
215
216
  notify [message] Same as n (see td n --prompt)
217
+ todo Manage todos (see td todo --help)
216
218
  automation Manage scheduled tasks (see td automation --help)
217
219
  integration Manage local scoped integrations (see integration help)
218
220
  collab status Show this Session's collaboration groups and peers
@@ -669,6 +671,7 @@ function parseArgs(argv) {
669
671
  let integration;
670
672
  let collab;
671
673
  let automation;
674
+ let todo;
672
675
  let notify;
673
676
  // Short command aliases for the common path. Keep these positional-only so
674
677
  // long-form flags remain the single source of truth for option semantics.
@@ -796,6 +799,16 @@ function parseArgs(argv) {
796
799
  }
797
800
  argv = [];
798
801
  }
802
+ else if (command === 'todo') {
803
+ try {
804
+ todo = parseTodoCommand(argv.slice(1));
805
+ }
806
+ catch (error) {
807
+ console.error(JSON.stringify({ ok: false, error: getMessage(error) }));
808
+ process.exit(1);
809
+ }
810
+ argv = [];
811
+ }
799
812
  else if (command === 'automation') {
800
813
  try {
801
814
  automation = parseAutomationCommand(argv.slice(1));
@@ -1199,6 +1212,7 @@ function parseArgs(argv) {
1199
1212
  integration,
1200
1213
  collab,
1201
1214
  automation,
1215
+ todo,
1202
1216
  notify,
1203
1217
  };
1204
1218
  }
@@ -3489,6 +3503,26 @@ async function main() {
3489
3503
  await runNotify(options.notify);
3490
3504
  return;
3491
3505
  }
3506
+ if (options.todo) {
3507
+ if (options.todo.action === 'help') {
3508
+ console.log(TODO_HELP);
3509
+ return;
3510
+ }
3511
+ const state = getRunningState();
3512
+ if (!state?.localApiToken) {
3513
+ console.error(JSON.stringify({ ok: false, error: 'Termdock is not running' }));
3514
+ process.exitCode = 1;
3515
+ return;
3516
+ }
3517
+ const baseUrl = state.localUrl ?? `${state.scheme ?? 'http'}://${state.host === '0.0.0.0' ? 'localhost' : state.host}:${state.port}`;
3518
+ process.exitCode = await executeTodoCommand(options.todo, {
3519
+ request: (method, endpoint, body) => method === 'POST'
3520
+ ? postLocalJson(baseUrl, state.localApiToken, endpoint, body)
3521
+ : getLocalJson(baseUrl, state.localApiToken, endpoint),
3522
+ stdin: readStdinText, write: line => console.log(line),
3523
+ });
3524
+ return;
3525
+ }
3492
3526
  if (options.automation) {
3493
3527
  await runAutomation(options.automation);
3494
3528
  return;
@@ -52,10 +52,12 @@ import { isAllowedHost, isUpgradeOriginAllowed, validateHostMiddleware, validate
52
52
  import { getCookieSecurityOptions, setSecureCookieMode } from './utils/cookieSecurity.js';
53
53
  import { requestDeadlineMiddleware } from './utils/requestDeadline.js';
54
54
  import { RuntimeMonitor } from './utils/runtimeMonitor.js';
55
+ import { serverCleanup } from './utils/serverCleanup.js';
55
56
  import { startOnboardingServer, stopOnboardingServer, getOnboardingServerUrl } from './onboardingServer.js';
56
57
  import { CertificateWatcher } from './certificateWatcher.js';
57
58
  import { startTermdockLogMaintenance, writeDiffTraceLog, writeErrorLog, writeJsonLog, writeTextLog, } from './utils/serverLogger.js';
58
- import { indexRetainedClientModules, pinBundledRuntimeClientDist } from './utils/runtimeClient.js';
59
+ import { indexRetainedClientModules, pinBundledRuntimeClientDist, resolveRetainedClientModule } from './utils/runtimeClient.js';
60
+ import { startGeneratedStorageMaintenance } from './utils/storageMaintenance.js';
59
61
  import { installCrashForensics } from './utils/crashForensics.js';
60
62
  import { getTermdockVersion, TERMDOCK_CAPABILITIES, TERMDOCK_PROTOCOL_VERSION, } from './utils/version.js';
61
63
  import { PORT, DEFAULT_HOST } from './config.js';
@@ -363,6 +365,7 @@ export function createApp(options = {}) {
363
365
  app.use('/api/computer', computerRoutes);
364
366
  if (fs.existsSync(bundledClientIndexPath)) {
365
367
  const clientPath = pinBundledRuntimeClientDist(bundledClientDistPath);
368
+ app.locals.runtimeClientPath = clientPath;
366
369
  const compression = createStaticCompressionMiddleware(clientPath);
367
370
  const staticFiles = express.static(clientPath, {
368
371
  setHeaders: (res, filePath, stat) => {
@@ -395,7 +398,7 @@ export function createApp(options = {}) {
395
398
  });
396
399
  const retainedModules = indexRetainedClientModules();
397
400
  app.get(/^\/assets\//, (req, res, next) => {
398
- const retainedPath = retainedModules.get(req.path);
401
+ const retainedPath = resolveRetainedClientModule(retainedModules, req.path);
399
402
  if (!retainedPath) {
400
403
  // Never cache a missing module or return the SPA HTML as JavaScript.
401
404
  res.setHeader('Cache-Control', 'no-store');
@@ -403,7 +406,7 @@ export function createApp(options = {}) {
403
406
  return;
404
407
  }
405
408
  setStaticCacheHeaders(req, res);
406
- res.sendFile(retainedPath, error => {
409
+ res.sendFile(path.basename(retainedPath), { root: path.dirname(retainedPath) }, error => {
407
410
  if (!error)
408
411
  return;
409
412
  if (res.headersSent)
@@ -414,7 +417,7 @@ export function createApp(options = {}) {
414
417
  });
415
418
  app.get(/^(?!\/api(?:\/|$)|\/health$|\/onboarding(?:\/|$)|\/ca(?:\/|$)).*/, (req, res) => {
416
419
  setStaticCacheHeaders(req, res);
417
- res.sendFile(path.join(clientPath, 'index.html'));
420
+ res.sendFile('index.html', { root: clientPath });
418
421
  });
419
422
  }
420
423
  // Never expose parser errors, submitted passwords, or stack traces to callers.
@@ -471,9 +474,14 @@ export function startServer(options = {}) {
471
474
  runtimeMonitor,
472
475
  });
473
476
  const { server, scheme } = createServerForApp(app, options);
477
+ const onServerClose = serverCleanup(server);
478
+ if (typeof app.locals.runtimeClientPath === 'string')
479
+ onServerClose(startGeneratedStorageMaintenance({
480
+ stateDirectory: path.join(homedir(), '.termdock'), clientDirectory: app.locals.runtimeClientPath,
481
+ }));
474
482
  let webTransport;
475
483
  const webTransportDescriptor = () => webTransport?.descriptor();
476
- server.once('close', () => webTransport?.close());
484
+ onServerClose(() => webTransport?.close());
477
485
  const collaborationChannels = new Map();
478
486
  const reverseCollaboration = (id) => [...(collaborationChannels.get(id) ?? [])].find(rpc => !rpc.closed);
479
487
  let collaborationService;
@@ -485,6 +493,7 @@ export function startServer(options = {}) {
485
493
  const desktopTargets = () => desktopDirectTargets(path.join(homedir(), '.termdock', 'desktop.json'), federationServiceId);
486
494
  const routeAccess = new RouteAccess(path.join(homedir(), '.termdock', 'federation', 'routes.json'), Date.now, (subjectId, targetServiceId) => routeInvitations?.allows(subjectId, targetServiceId) === true || collaborationTransport?.canRoute(subjectId, targetServiceId) === true, desktopTargets, () => activeRouteIds());
487
495
  const relayRouter = new RelayRouter({
496
+ isLocalTarget: id => id === federationServiceId,
488
497
  authenticate: context => context,
489
498
  allowRegister: (principal, serviceId) => routeAccess.allowRegister(principal, serviceId),
490
499
  allowRoute: (principal, serviceId) => routeAccess.allowRoute(principal, serviceId),
@@ -511,11 +520,11 @@ export function startServer(options = {}) {
511
520
  refreshDirectTargets();
512
521
  const desktopRoutesTimer = setInterval(refreshDirectTargets, 2000);
513
522
  desktopRoutesTimer.unref();
514
- server.once('close', () => { clearInterval(desktopRoutesTimer); for (const target of dynamicDirectTargets.values())
523
+ onServerClose(() => { clearInterval(desktopRoutesTimer); for (const target of dynamicDirectTargets.values())
515
524
  target.close(); });
516
- server.once('close', () => relayRouter.close());
517
- server.once('close', () => { void stopAllScrcpySessions(); void androidRecordings.stopAll(); });
518
- server.once('close', stopComputerBridges);
525
+ onServerClose(() => relayRouter.close());
526
+ onServerClose(() => { void stopAllScrcpySessions(); void androidRecordings.stopAll(); });
527
+ onServerClose(stopComputerBridges);
519
528
  const federation = createFederationRuntime(app, path.join(homedir(), '.termdock', 'federation'), {
520
529
  terminal: handleTerminalWebSocket, control: handleControlWebSocket, android: handleAndroidWebSocket, computer: handleComputerWebSocket,
521
530
  }, {
@@ -654,7 +663,7 @@ export function startServer(options = {}) {
654
663
  messages: collaborationStore, taskStore: collaborationTaskStore, tasks: collaborationTasks, peers: collaborationService, sessions: integrationSessionAdapter });
655
664
  await integration.listen();
656
665
  app.locals.integrationRuntime = integration;
657
- server.once('close', () => { void integration?.close(); });
666
+ onServerClose(() => { void integration?.close(); });
658
667
  }
659
668
  catch {
660
669
  await integration?.close();
@@ -662,11 +671,11 @@ export function startServer(options = {}) {
662
671
  }
663
672
  }
664
673
  collaborationTasks.start();
665
- server.once('close', () => collaborationTasks.close());
674
+ onServerClose(() => collaborationTasks.close());
666
675
  collaborationService.start();
667
- server.once('close', () => collaborationService?.close());
676
+ onServerClose(() => collaborationService?.close());
668
677
  collaborationTransport.start();
669
- server.once('close', () => collaborationTransport?.close());
678
+ onServerClose(() => collaborationTransport?.close());
670
679
  entrySubjectAllowed = subjectId => runtime.store.authorize({ subjectId, serviceId: runtime.serviceId, action: 'authorization.manage' }).allowed;
671
680
  routeInvitations = new RouteInvitationStore({
672
681
  filePath: path.join(homedir(), '.termdock', 'federation', 'route-invitations.json'), serviceId: runtime.serviceId,
@@ -687,10 +696,10 @@ export function startServer(options = {}) {
687
696
  localOrigin: `${scheme}://${localAuthority}:${port}`, ...(localCa ? { localCa } : {}),
688
697
  });
689
698
  selfRelay.start();
690
- server.once('close', () => selfRelay.close());
699
+ onServerClose(() => selfRelay.close());
691
700
  }).catch(() => console.error('Route invitations unavailable; uninitialized route grants remain denied.'));
692
701
  void federation.catch(() => console.error('Encrypted access initialization failed; business access remains closed.'));
693
- server.once('close', () => { void federation.then(runtime => runtime.close()).catch(() => { }); });
702
+ onServerClose(() => { void federation.then(runtime => runtime.close()).catch(() => { }); });
694
703
  server.headersTimeout = 10_000;
695
704
  server.requestTimeout = 120_000;
696
705
  server.keepAliveTimeout = 5_000;
@@ -698,7 +707,7 @@ export function startServer(options = {}) {
698
707
  server.maxRequestsPerSocket = 1000;
699
708
  server.maxConnections = 1024;
700
709
  server.on('connection', (socket) => runtimeMonitor.trackSocket(socket));
701
- server.once('close', () => runtimeMonitor.stop());
710
+ onServerClose(() => runtimeMonitor.stop());
702
711
  setSecureCookieMode(scheme === 'https');
703
712
  const certWatcher = new CertificateWatcher({
704
713
  enabled: scheme === 'https' && Boolean(options.httpsCertPath && options.httpsKeyPath),
@@ -864,7 +873,7 @@ export function startServer(options = {}) {
864
873
  console.error('Server error:', error);
865
874
  process.exit(1);
866
875
  });
867
- server.on('close', () => {
876
+ onServerClose(() => {
868
877
  stopLogMaintenance();
869
878
  crashForensics.dispose();
870
879
  certWatcher.stop();
@@ -90,13 +90,18 @@ export function resolveAccessRequest(method, path) {
90
90
  return { action: 'file.read' };
91
91
  if (method === 'POST' && route === 'create')
92
92
  return { action: 'service.create-session' };
93
- const session = /^([^/]+)(?:\/(health|attach|stream|input|resize|tmux|restart|agent-resume))?$/.exec(route);
93
+ const attachment = /^([^/]+)\/chat\/attachments$/.exec(route);
94
+ if (method === 'POST' && attachment && !reservedSessionIds.has(attachment[1].toLowerCase()))
95
+ return { action: 'session.input', sessionId: attachment[1] };
96
+ const session = /^([^/]+)(?:\/(health|attach|stream|input|resize|tmux|restart|agent-resume|chat|view-mode))?$/.exec(route);
94
97
  if (session && !reservedSessionIds.has(session[1].toLowerCase())) {
95
98
  const sessionId = session[1];
96
99
  const op = session[2];
97
- if (read && ['health', 'attach', 'stream', 'agent-resume'].includes(op))
100
+ if (read && ['health', 'attach', 'stream', 'agent-resume', 'chat', 'view-mode'].includes(op))
98
101
  return { action: 'session.view', sessionId };
99
- if (method === 'POST' && op === 'input')
102
+ if (method === 'PUT' && op === 'view-mode')
103
+ return { action: 'session.view', sessionId };
104
+ if (method === 'POST' && (op === 'input' || op === 'chat'))
100
105
  return { action: 'session.input', sessionId };
101
106
  if (method === 'POST' && op === 'resize')
102
107
  return { action: 'session.resize', sessionId };