@hienlh/ppm 0.18.11 → 0.18.13

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 (571) hide show
  1. package/AGENTS.md +17 -5
  2. package/CHANGELOG.md +27 -0
  3. package/CLAUDE.md +3 -0
  4. package/README.md +87 -29
  5. package/assets/skills/ppm/SKILL.md +1 -1
  6. package/assets/skills/ppm/references/http-api.md +19 -1
  7. package/dist/web/assets/{adaptive-context-menu-DGCKKeTy.js → adaptive-context-menu-CbgPYQmj.js} +1 -1
  8. package/dist/web/assets/{ai-resource-editor-BOHHTTe7.js → ai-resource-editor-unM2HNmg.js} +1 -1
  9. package/dist/web/assets/{ai-settings-section-BigC_nZR.js → ai-settings-section-CdktdrwF.js} +1 -1
  10. package/dist/web/assets/{angular-html-BYPaydvh.js → angular-html-DcpbdcNG.js} +1 -1
  11. package/dist/web/assets/{angular-ts-Bb4AMKlk.js → angular-ts-Bv_WIk34.js} +1 -1
  12. package/dist/web/assets/api-client-BogqsFna.js +1 -0
  13. package/dist/web/assets/{api-settings-Bd3M4YpI.js → api-settings-BdCtex9i.js} +1 -1
  14. package/dist/web/assets/api-settings-DfXViPKz.js +1 -0
  15. package/dist/web/assets/{api-themes-Cpx419SL.js → api-themes-pRRoLvgD.js} +1 -1
  16. package/dist/web/assets/{apl-DB2VjFCS.js → apl-D5_lLszu.js} +1 -1
  17. package/dist/web/assets/architecture-PBZL5I3N-BzFm9ELu.js +1 -0
  18. package/dist/web/assets/{astro-BeoJdVpk.js → astro-CBHwddYL.js} +1 -1
  19. package/dist/web/assets/{audio-preview-BgFuTn-0.js → audio-preview-BD1iDovf.js} +1 -1
  20. package/dist/web/assets/{blade-Cf2q1sPf.js → blade-DGe1d2Pq.js} +1 -1
  21. package/dist/web/assets/{bsl-W1kOaNpu.js → bsl-2lyAzRJA.js} +1 -1
  22. package/dist/web/assets/{button-5zTrkEoN.js → button-2WCAS8dI.js} +1 -1
  23. package/dist/web/assets/{cairo-BoAZFcje.js → cairo-DjzZeJrq.js} +1 -1
  24. package/dist/web/assets/chat-tab-DzK8LGti.js +15 -0
  25. package/dist/web/assets/{cobol-B0Nm7RXj.js → cobol-cC3XIuAJ.js} +1 -1
  26. package/dist/web/assets/code-editor-CuMfPN9X.js +10 -0
  27. package/dist/web/assets/{coffee-BakMn3on.js → coffee-4eGboVoU.js} +1 -1
  28. package/dist/web/assets/{conflict-editor-BUs5k9q_.js → conflict-editor-DdJag4QK.js} +1 -1
  29. package/dist/web/assets/{context-menu-Bq92km4s.js → context-menu-BO1c9jKy.js} +1 -1
  30. package/dist/web/assets/{cpp-BRAJQHK2.js → cpp-DF9_G-OU.js} +1 -1
  31. package/dist/web/assets/{crystal-kqqO3zkK.js → crystal-OavZlzcm.js} +1 -1
  32. package/dist/web/assets/{csv-preview-ByoDgLAZ.js → csv-preview-DnXwouF3.js} +1 -1
  33. package/dist/web/assets/{data-grid-overlay-editor-Brkf9z41.js → data-grid-overlay-editor-B9Gpjm3l.js} +1 -1
  34. package/dist/web/assets/{database-viewer-Btc3h8Yu.js → database-viewer-Dk8oGyZx.js} +1 -1
  35. package/dist/web/assets/{dialog-DwtGlowE.js → dialog-B-l2ZxVm.js} +1 -1
  36. package/dist/web/assets/{diff-viewer-CZaDnR4w.js → diff-viewer-eaUBjLCH.js} +1 -1
  37. package/dist/web/assets/{docx-preview-DAD_vg59.js → docx-preview-DAdHPlhZ.js} +1 -1
  38. package/dist/web/assets/{edge-Cq1ZKZuE.js → edge-TzYh8OlN.js} +1 -1
  39. package/dist/web/assets/{edit-diff-preview-B_VE7ppQ.js → edit-diff-preview-DlwP3UIU.js} +1 -1
  40. package/dist/web/assets/{elixir-BM_JoJRk.js → elixir-Cy3RhKKH.js} +1 -1
  41. package/dist/web/assets/{elm-Dw7oO08Y.js → elm-BTBZdweK.js} +1 -1
  42. package/dist/web/assets/{erb-CfKOGAfk.js → erb-dv1mI0y4.js} +1 -1
  43. package/dist/web/assets/{erlang-DlDmGVeE.js → erlang-DjeiDrkl.js} +1 -1
  44. package/dist/web/assets/{esm-DGAP0GFh.js → esm-FRwvcesu.js} +1 -1
  45. package/dist/web/assets/explorer-body-DkCkSVrN.js +2 -0
  46. package/dist/web/assets/explorer-window-content-MsnTVngu.js +1 -0
  47. package/dist/web/assets/{extension-store-Cpfh2vMm.js → extension-store-DUaZINyC.js} +1 -1
  48. package/dist/web/assets/{extension-webview-B2OnjuCu.js → extension-webview-W0qRfaAU.js} +1 -1
  49. package/dist/web/assets/{file-store-aOERIEo-.js → file-store-yReVbR8q.js} +1 -1
  50. package/dist/web/assets/{fortran-fixed-form-XnAhQWxS.js → fortran-fixed-form-BCH9DAIJ.js} +1 -1
  51. package/dist/web/assets/{fsharp-CdNvy0PG.js → fsharp-C93NYKYD.js} +1 -1
  52. package/dist/web/assets/{gdresource-DxuG5i8i.js → gdresource-BcIEE2eX.js} +1 -1
  53. package/dist/web/assets/{git-commit-3lMonsur.js → git-commit-BVjlXEy8.js} +1 -1
  54. package/dist/web/assets/{git-log-panel-Co0PBPHC.js → git-log-panel-2_4HuP47.js} +1 -1
  55. package/dist/web/assets/{git-rebase-N8Z9kIMf.js → git-rebase-Bj_21B1V.js} +1 -1
  56. package/dist/web/assets/gitGraph-HDMCJU4V-B72vcb2r.js +1 -0
  57. package/dist/web/assets/glide-data-grid-B0IY6n_Q.js +138 -0
  58. package/dist/web/assets/{glimmer-js-Dp9OXiib.js → glimmer-js-C20yj4Zv.js} +1 -1
  59. package/dist/web/assets/{glimmer-ts-CDVKBcDj.js → glimmer-ts-ipbYC7kh.js} +1 -1
  60. package/dist/web/assets/{glsl-DPJxI4us.js → glsl-Dovazu3t.js} +1 -1
  61. package/dist/web/assets/{graphql-BrFhaQQl.js → graphql-DpMlM7hC.js} +1 -1
  62. package/dist/web/assets/{group-chat-tab-rOd8J8GC.js → group-chat-tab-DRLDHOp6.js} +1 -1
  63. package/dist/web/assets/{hack-BzXbDMlA.js → hack-gc7LCBuV.js} +1 -1
  64. package/dist/web/assets/{haml-CPpkX0s5.js → haml-vtlFm9gm.js} +1 -1
  65. package/dist/web/assets/{handlebars-BqrApy52.js → handlebars-DGKhpCji.js} +1 -1
  66. package/dist/web/assets/{html-DmjUl-OA.js → html-DvfhQbXb.js} +1 -1
  67. package/dist/web/assets/{html-derivative-Cnd6XFR5.js → html-derivative-C3oTSSCN.js} +1 -1
  68. package/dist/web/assets/{http-DMLWYun2.js → http-SG6zLTo7.js} +1 -1
  69. package/dist/web/assets/{hurl-CKkCVxbj.js → hurl-BWXsYlqW.js} +1 -1
  70. package/dist/web/assets/{hxml-CAx19TtQ.js → hxml-DUdMzaoh.js} +1 -1
  71. package/dist/web/assets/{image-preview-DHUoylQ1.js → image-preview-DxgFOV1T.js} +1 -1
  72. package/dist/web/assets/index-CBn4SOoT.js +52 -0
  73. package/dist/web/assets/index-DWpNR3nB.css +2 -0
  74. package/dist/web/assets/info-3K5VOQVL-3irPxRK_.js +1 -0
  75. package/dist/web/assets/{input-DcEk7mA3.js → input-DuAF-Stj.js} +1 -1
  76. package/dist/web/assets/{jinja-BmB9YN9l.js → jinja-955w9RKM.js} +1 -1
  77. package/dist/web/assets/{jison-BaVsKKpw.js → jison-WWfqPo50.js} +1 -1
  78. package/dist/web/assets/{julia-BgVBLveX.js → julia-BFrfnaNl.js} +1 -1
  79. package/dist/web/assets/{just-C2ENIbl9.js → just-BrZdyR_I.js} +1 -1
  80. package/dist/web/assets/{keybindings-store-BGIyqXHI.js → keybindings-store-0Wqfa7Qp.js} +1 -1
  81. package/dist/web/assets/keybindings-store-d54pv2NK.js +1 -0
  82. package/dist/web/assets/{latex-BiDIWxKL.js → latex-CwtPPASD.js} +1 -1
  83. package/dist/web/assets/{liquid-NxpapreE.js → liquid-CYZuvDDd.js} +1 -1
  84. package/dist/web/assets/{lua-DVepQvwH.js → lua-BV095ZyY.js} +1 -1
  85. package/dist/web/assets/markdown-renderer-BTS8ifdu.js +1 -0
  86. package/dist/web/assets/{markdown-renderer-DlcDhgrF.js → markdown-renderer-CnRcKK3d.js} +3 -3
  87. package/dist/web/assets/{marko-CJ2606Xl.js → marko-CNeljZ1C.js} +1 -1
  88. package/dist/web/assets/{mdc-D2bjqclE.js → mdc-JfGapShy.js} +1 -1
  89. package/dist/web/assets/{media-url-H17XJF-I.js → media-url-Bm4PsduE.js} +1 -1
  90. package/dist/web/assets/{mobile-bottom-sheet-g-r2hCFa.js → mobile-bottom-sheet-M5iZDX7y.js} +1 -1
  91. package/dist/web/assets/mobile-explorer-sheet-BqK2-WuN.js +1 -0
  92. package/dist/web/assets/{nextflow-BtJwUbfF.js → nextflow-DD5C8nqX.js} +1 -1
  93. package/dist/web/assets/{nginx-j4gyIhHE.js → nginx-Ca7B__x_.js} +1 -1
  94. package/dist/web/assets/{nim-ClH_gjP5.js → nim-B8FogsDw.js} +1 -1
  95. package/dist/web/assets/notification-store-Yvy1I8gd.js +1 -0
  96. package/dist/web/assets/{number-overlay-editor-C1EqJnWq.js → number-overlay-editor-DG9xJwEG.js} +1 -1
  97. package/dist/web/assets/{overview-panel-vTeeJYVZ.js → overview-panel-s53bnl0q.js} +1 -1
  98. package/dist/web/assets/packet-RMMSAZCW-Z5jWjFCV.js +1 -0
  99. package/dist/web/assets/{panel-store-BSnkjgHt.js → panel-store-B4rijFKN.js} +1 -1
  100. package/dist/web/assets/{pdf-preview-CqFGRY0Z.js → pdf-preview-DYt3aBzM.js} +1 -1
  101. package/dist/web/assets/{perl-C9H7X7CT.js → perl-BR78hS8R.js} +1 -1
  102. package/dist/web/assets/{php-Bx2U-cQ_.js → php-DXBOMC9z.js} +1 -1
  103. package/dist/web/assets/pie-UPGHQEXC-Bq7UMi8P.js +1 -0
  104. package/dist/web/assets/{postgres-viewer-DHwcQucn.js → postgres-viewer-BvoWSuoZ.js} +3 -3
  105. package/dist/web/assets/{process-table-BGRJNlpn.js → process-table-BYwKigiD.js} +1 -1
  106. package/dist/web/assets/{project-store--nvQiy75.js → project-store-BuY7rxn_.js} +1 -1
  107. package/dist/web/assets/{pug-Cw74sKsE.js → pug-CvTwVVKV.js} +1 -1
  108. package/dist/web/assets/{qml-BXD94Eqz.js → qml-CPSoZ1-B.js} +1 -1
  109. package/dist/web/assets/radar-KQ55EAFF-BLo4BOTD.js +1 -0
  110. package/dist/web/assets/{razor-DZ0-Ge0S.js → razor-BUA1YKtF.js} +1 -1
  111. package/dist/web/assets/{rst-Dtdh0QUj.js → rst-BJsq7ISz.js} +1 -1
  112. package/dist/web/assets/{ruby-BC51BW2Q.js → ruby-DSDMeYf5.js} +1 -1
  113. package/dist/web/assets/{run-in-terminal-Sd3KyjN4.js → run-in-terminal-C9xpskFn.js} +1 -1
  114. package/dist/web/assets/{sas-BN8i4qOU.js → sas-B1nJOjbN.js} +1 -1
  115. package/dist/web/assets/{scroll-area-0gljZ6lF.js → scroll-area-DBcG1fQo.js} +1 -1
  116. package/dist/web/assets/{scss-H-QtA7Rz.js → scss-BZFyRiQn.js} +1 -1
  117. package/dist/web/assets/{send-to-chat-u6m8l-rH.js → send-to-chat-BIg70MUZ.js} +1 -1
  118. package/dist/web/assets/{settings-store-CHY6Kzin.js → settings-store-GV5pkkke.js} +2 -2
  119. package/dist/web/assets/{settings-tab-IY6K1MiZ.js → settings-tab-BePvIcjd.js} +1 -1
  120. package/dist/web/assets/settings-tab-Br-lJSPa.js +1 -0
  121. package/dist/web/assets/{shaderlab-CalNsj_x.js → shaderlab-laINRXBo.js} +1 -1
  122. package/dist/web/assets/{shellsession-BFrcoR8x.js → shellsession-BpOOvWVR.js} +1 -1
  123. package/dist/web/assets/{soy-CNbku7vP.js → soy-BW4d91Sa.js} +1 -1
  124. package/dist/web/assets/{sparql-BN_orcVp.js → sparql-BsvvyoHn.js} +1 -1
  125. package/dist/web/assets/{sql-query-editor-C6pC3I8l.js → sql-query-editor-qQce5QJ6.js} +1 -1
  126. package/dist/web/assets/{sqlite-viewer-DTr5PzUb.js → sqlite-viewer-yhc0YNvu.js} +1 -1
  127. package/dist/web/assets/{stata-C6a5Ijzq.js → stata-K-dZInUt.js} +1 -1
  128. package/dist/web/assets/{surrealql-ClplI_HY.js → surrealql-CpNp2sgf.js} +1 -1
  129. package/dist/web/assets/{svelte-DNm-UNXB.js → svelte-BG6iBA8R.js} +1 -1
  130. package/dist/web/assets/{switch-DKvKya9y.js → switch-_NcrktLe.js} +1 -1
  131. package/dist/web/assets/system-monitor-body-D8Z5QXBB.js +2 -0
  132. package/dist/web/assets/system-monitor-tab-BclYXFTe.js +1 -0
  133. package/dist/web/assets/{system-monitor-window-content-BUqRsPK2.js → system-monitor-window-content-CaOhD0AU.js} +1 -1
  134. package/dist/web/assets/{tab-host-window-content-BnqGPu8a.js → tab-host-window-content-f_Rc5rJK.js} +1 -1
  135. package/dist/web/assets/{tab-store-CJuJRapl.js → tab-store-tFnyPmm4.js} +1 -1
  136. package/dist/web/assets/team-member-sheet-QDHoYCs0.js +2 -0
  137. package/dist/web/assets/{team-member-window-content-T4Q5JI-G.js → team-member-window-content-B1jkKkDi.js} +1 -1
  138. package/dist/web/assets/{templ-CSdqVobu.js → templ-gxNKXmt3.js} +1 -1
  139. package/dist/web/assets/{terminal-tab-Bb2rZegQ.js → terminal-tab-UvwM0sty.js} +3 -3
  140. package/dist/web/assets/{tex-DzSJ4kcZ.js → tex-C0ON27g5.js} +1 -1
  141. package/dist/web/assets/{tool-cards-lhqhrDTT.js → tool-cards-jB7GT-wj.js} +4 -4
  142. package/dist/web/assets/treemap-KZPCXAKY-dyrE6SW2.js +1 -0
  143. package/dist/web/assets/{ts-tags-C28w3bTg.js → ts-tags-BX_CTVgQ.js} +1 -1
  144. package/dist/web/assets/{twig-i5jY3QXB.js → twig-CwL7XnU0.js} +1 -1
  145. package/dist/web/assets/{use-blob-url-Dsq9OjTh.js → use-blob-url-DcRcjNTE.js} +1 -1
  146. package/dist/web/assets/use-coarse-long-press-BmI_GVW5.js +1 -0
  147. package/dist/web/assets/{use-monaco-theme-BZvlsoBv.js → use-monaco-theme--9tOOkDA.js} +1 -1
  148. package/dist/web/assets/{use-open-team-member-DkiEjFYE.js → use-open-team-member-1hRsHLKg.js} +1 -1
  149. package/dist/web/assets/{use-websocket-B8R50f7f.js → use-websocket-rxJLbFqy.js} +1 -1
  150. package/dist/web/assets/{vendor-mermaid-By4AVvJY.js → vendor-mermaid-CHTa6D69.js} +1 -1
  151. package/dist/web/assets/video-preview-DMhnf2Gi.js +1 -0
  152. package/dist/web/assets/{vue-Ceyet_lv.js → vue-Bykm6wSS.js} +1 -1
  153. package/dist/web/assets/{vue-html-GuU7g_hg.js → vue-html-CETdK_iV.js} +1 -1
  154. package/dist/web/assets/{vue-vine-CxXoaJr2.js → vue-vine-DiJb6fO5.js} +1 -1
  155. package/dist/web/assets/{window-store-CsEW6jiE.js → window-store-CQ1lghvv.js} +1 -1
  156. package/dist/web/assets/{xml-CbqOVhkP.js → xml-BNw8J5YW.js} +1 -1
  157. package/dist/web/assets/{xsl-KfAmCauy.js → xsl-CsG9L31b.js} +1 -1
  158. package/dist/web/index.html +46 -45
  159. package/dist/web/sw.js +1 -1
  160. package/docs/architecture/ai-chat-and-providers.md +309 -0
  161. package/docs/architecture/data-and-storage.md +356 -0
  162. package/docs/architecture/extensions.md +496 -0
  163. package/docs/architecture/integrations.md +214 -0
  164. package/docs/architecture/workspace-and-ui.md +391 -0
  165. package/docs/claude-agent-sdk-reference.md +1 -1
  166. package/docs/code-patterns.md +361 -0
  167. package/docs/code-standards.md +8 -358
  168. package/docs/codebase-subsystems.md +364 -0
  169. package/docs/codebase-summary.md +34 -379
  170. package/docs/deployment-guide.md +280 -490
  171. package/docs/design-guidelines.md +1 -1
  172. package/docs/lessons-learned.md +27 -10
  173. package/docs/project-changelog.md +18 -806
  174. package/docs/project-overview-pdr.md +117 -111
  175. package/docs/project-roadmap.md +89 -133
  176. package/docs/system-architecture.md +77 -1826
  177. package/package.json +2 -2
  178. package/src/cli/commands/autostart.ts +2 -2
  179. package/src/cli/commands/config-cmd.ts +12 -3
  180. package/src/cli/commands/status.ts +3 -2
  181. package/src/cli/commands/stop.ts +32 -4
  182. package/src/server/index.ts +17 -3
  183. package/src/server/routes/chat-unread.ts +36 -0
  184. package/src/server/routes/named-tunnel.ts +132 -0
  185. package/src/server/routes/tunnel.ts +13 -0
  186. package/src/server/ws/chat.ts +5 -2
  187. package/src/services/autostart-register.ts +47 -29
  188. package/src/services/cloud.service.ts +26 -1
  189. package/src/services/config-secret-keys.ts +48 -0
  190. package/src/services/config.service.ts +1 -1
  191. package/src/services/db.service.ts +62 -12
  192. package/src/services/extension-rpc-handlers.ts +9 -1
  193. package/src/services/file-watcher/watch-tree.ts +67 -33
  194. package/src/services/file-watcher.service.ts +28 -10
  195. package/src/services/fs-credential-path-guard.ts +103 -0
  196. package/src/services/fs-path-guard.service.ts +14 -66
  197. package/src/services/named-tunnel/cloudflare-dns-api.ts +40 -0
  198. package/src/services/named-tunnel/cloudflare-zone-api.ts +28 -0
  199. package/src/services/named-tunnel/cloudflared-cert.ts +95 -0
  200. package/src/services/named-tunnel/cloudflared-exec.ts +50 -0
  201. package/src/services/named-tunnel/cloudflared-login-helpers.ts +98 -0
  202. package/src/services/named-tunnel/cloudflared-login.service.ts +182 -0
  203. package/src/services/named-tunnel/hostname-rules.ts +58 -0
  204. package/src/services/named-tunnel/login-output-parser.ts +36 -0
  205. package/src/services/named-tunnel/named-tunnel-args.ts +110 -0
  206. package/src/services/named-tunnel/named-tunnel-config.ts +67 -0
  207. package/src/services/named-tunnel/named-tunnel-probe-state.ts +95 -0
  208. package/src/services/named-tunnel/named-tunnel-readiness.ts +59 -0
  209. package/src/services/named-tunnel/named-tunnel-runtime.ts +42 -0
  210. package/src/services/named-tunnel/named-tunnel-setup-confirm.ts +98 -0
  211. package/src/services/named-tunnel/named-tunnel-setup.service.ts +191 -0
  212. package/src/services/supervisor-state.ts +67 -2
  213. package/src/services/supervisor.ts +454 -157
  214. package/src/services/tunnel-registry-parse.ts +27 -0
  215. package/src/services/tunnel-registry.service.ts +2 -15
  216. package/src/services/tunnel.service.ts +12 -3
  217. package/src/types/config.ts +31 -0
  218. package/src/web/app.tsx +5 -0
  219. package/src/web/components/chat/chat-history-bar.tsx +95 -98
  220. package/src/web/components/chat/chat-toolbar-overflow-menu.tsx +57 -0
  221. package/src/web/components/chat/session-debug-dialog.tsx +35 -27
  222. package/src/web/components/layout/cloud-share-named-tunnel-row.tsx +111 -0
  223. package/src/web/components/layout/cloud-share-popover.tsx +56 -14
  224. package/src/web/components/shared/connection-lost-overlay.tsx +44 -5
  225. package/src/web/components/tunnels/named-tunnel/hostname-validation.ts +14 -0
  226. package/src/web/components/tunnels/named-tunnel/named-tunnel-copy.ts +96 -0
  227. package/src/web/components/tunnels/named-tunnel/named-tunnel-hostname-field.tsx +51 -0
  228. package/src/web/components/tunnels/named-tunnel/named-tunnel-login-step.tsx +105 -0
  229. package/src/web/components/tunnels/named-tunnel/named-tunnel-section.tsx +159 -0
  230. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +197 -0
  231. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-popup.tsx +57 -0
  232. package/src/web/components/tunnels/named-tunnel/named-tunnel-step-reducer.ts +191 -0
  233. package/src/web/components/tunnels/named-tunnel/use-named-tunnel-setup.ts +212 -0
  234. package/src/web/components/tunnels/tunnel-manager-tab.tsx +4 -0
  235. package/src/web/hooks/use-global-events.ts +3 -1
  236. package/src/web/lib/api-named-tunnel.ts +54 -0
  237. package/src/web/lib/last-known-local-url.ts +23 -0
  238. package/src/web/stores/notification-store.ts +20 -1
  239. package/.spike/cdp-client.ts +0 -116
  240. package/.spike/cleanup-ppm-workspace.mjs +0 -44
  241. package/.spike/group-protected-probe.ts +0 -21
  242. package/.spike/pip-eval.ts +0 -17
  243. package/.spike/pip-page-helpers.js +0 -119
  244. package/.spike/pip-results-editor-glue.json +0 -105
  245. package/.spike/pip-results-editor.json +0 -158
  246. package/.spike/pip-results-input-isolation.json +0 -28
  247. package/.spike/pip-results-key-probe.json +0 -58
  248. package/.spike/pip-results-listener-survival.json +0 -98
  249. package/.spike/pip-results-listeners.json +0 -36
  250. package/.spike/pip-results-pagehide.json +0 -92
  251. package/.spike/pip-results-resize.json +0 -104
  252. package/.spike/pip-results-terminal-debug.json +0 -99
  253. package/.spike/pip-results-terminal-v2.json +0 -191
  254. package/.spike/pip-results-terminal.json +0 -220
  255. package/.spike/pip-results-xterm-trace.json +0 -73
  256. package/.spike/pip-spike-common.ts +0 -83
  257. package/.spike/pip-spike-editor-glue.ts +0 -82
  258. package/.spike/pip-spike-editor.ts +0 -129
  259. package/.spike/pip-spike-input-isolation.ts +0 -38
  260. package/.spike/pip-spike-key-probe.ts +0 -34
  261. package/.spike/pip-spike-listener-survival.ts +0 -54
  262. package/.spike/pip-spike-listeners.ts +0 -19
  263. package/.spike/pip-spike-pagehide.ts +0 -59
  264. package/.spike/pip-spike-resize.ts +0 -42
  265. package/.spike/pip-spike-setup.ts +0 -63
  266. package/.spike/pip-spike-terminal-debug.ts +0 -81
  267. package/.spike/pip-spike-terminal-v2.ts +0 -139
  268. package/.spike/pip-spike-terminal.ts +0 -169
  269. package/.spike/pip-spike-xterm-trace.ts +0 -36
  270. package/.spike/probe-drag-memo-error.mjs +0 -67
  271. package/.spike/read-dev-db.ts +0 -15
  272. package/.spike/s.err +0 -63
  273. package/.spike/scratch-editor-target.ts +0 -7
  274. package/.spike/smoke-unified-chrome-pip.mjs +0 -353
  275. package/.spike/tunnel.err +0 -63
  276. package/.spike/vite-restart.err +0 -663
  277. package/.spike/w.err +0 -571
  278. package/dist/web/assets/api-client-DTZEgjBQ.js +0 -1
  279. package/dist/web/assets/api-settings-kd1j4iR8.js +0 -1
  280. package/dist/web/assets/architecture-PBZL5I3N-8dCMT9r7.js +0 -1
  281. package/dist/web/assets/chat-tab-E3bf_V8X.js +0 -15
  282. package/dist/web/assets/code-editor-BUlM2gXk.js +0 -10
  283. package/dist/web/assets/explorer-body-9aBmyVpZ.js +0 -2
  284. package/dist/web/assets/explorer-window-content-DRtqoSPA.js +0 -1
  285. package/dist/web/assets/gitGraph-HDMCJU4V-2e_8dfbs.js +0 -1
  286. package/dist/web/assets/glide-data-grid-C4_zIneN.js +0 -138
  287. package/dist/web/assets/index-BImUaigO.js +0 -52
  288. package/dist/web/assets/index-CSfi6DSU.css +0 -2
  289. package/dist/web/assets/info-3K5VOQVL-BZi1Gha1.js +0 -1
  290. package/dist/web/assets/keybindings-store-CzV2sPls.js +0 -1
  291. package/dist/web/assets/markdown-renderer-CcbR33VG.js +0 -1
  292. package/dist/web/assets/mobile-explorer-sheet-SIwQXlwA.js +0 -1
  293. package/dist/web/assets/notification-store-DV5QtUTg.js +0 -1
  294. package/dist/web/assets/packet-RMMSAZCW-o5htEcin.js +0 -1
  295. package/dist/web/assets/pie-UPGHQEXC-BXAIFSAD.js +0 -1
  296. package/dist/web/assets/radar-KQ55EAFF-Dbt2Aebl.js +0 -1
  297. package/dist/web/assets/settings-tab-Dic6TKkU.js +0 -1
  298. package/dist/web/assets/system-monitor-body-iwGiCns9.js +0 -2
  299. package/dist/web/assets/system-monitor-tab-DdXQhEel.js +0 -1
  300. package/dist/web/assets/team-member-sheet-LkAFSCvb.js +0 -2
  301. package/dist/web/assets/treemap-KZPCXAKY-DUbnl9dz.js +0 -1
  302. package/dist/web/assets/video-preview-m0-3p7QZ.js +0 -1
  303. /package/dist/web/assets/{abap-C6nB04tn.js → abap-DGlrX_8G.js} +0 -0
  304. /package/dist/web/assets/{actionscript-3-Vx4rw2sC.js → actionscript-3-CUqRtUJE.js} +0 -0
  305. /package/dist/web/assets/{ada-Ccd8vM20.js → ada-CY3Spa33.js} +0 -0
  306. /package/dist/web/assets/{andromeeda-DnBX5xMg.js → andromeeda-Lxs2TJn7.js} +0 -0
  307. /package/dist/web/assets/{apache-B-9_sx0g.js → apache-DfxgGdgM.js} +0 -0
  308. /package/dist/web/assets/{apex-_wPVBYoL.js → apex-QVDF1dnI.js} +0 -0
  309. /package/dist/web/assets/{api-client-aQb5hHE5.js → api-client-oY1tC3tM.js} +0 -0
  310. /package/dist/web/assets/{applescript-CcvD-qr0.js → applescript-pwJ8QXh-.js} +0 -0
  311. /package/dist/web/assets/{apply-theme-BeLRfsSu.js → apply-theme-B_bMVL6a.js} +0 -0
  312. /package/dist/web/assets/{ara-C40Ztoms.js → ara-mPjeX5YX.js} +0 -0
  313. /package/dist/web/assets/{asciidoc-CybYkJV4.js → asciidoc-Bf7LsDkI.js} +0 -0
  314. /package/dist/web/assets/{asm-9eOKwzR0.js → asm-rRKC1OUx.js} +0 -0
  315. /package/dist/web/assets/{aurora-x-B5ZH4t7t.js → aurora-x-DwQr0DkG.js} +0 -0
  316. /package/dist/web/assets/{awk-Dqilob-2.js → awk-Bpt768fN.js} +0 -0
  317. /package/dist/web/assets/{ayu-dark-CPgRhf5r.js → ayu-dark-D9lwQHMs.js} +0 -0
  318. /package/dist/web/assets/{ayu-light-Do06Q52f.js → ayu-light-B4-ptrU5.js} +0 -0
  319. /package/dist/web/assets/{ayu-mirage-_BhxcrxY.js → ayu-mirage-DAyRzH5Q.js} +0 -0
  320. /package/dist/web/assets/{ballerina-DDwK54QW.js → ballerina-Cgdpj1HC.js} +0 -0
  321. /package/dist/web/assets/{bat-BGyGlzGk.js → bat-4FrN36S2.js} +0 -0
  322. /package/dist/web/assets/{beancount-CRWBdapI.js → beancount-DkcxQER3.js} +0 -0
  323. /package/dist/web/assets/{berry-DbSFn2gO.js → berry-Dnuut-Ml.js} +0 -0
  324. /package/dist/web/assets/{bibtex-QpsV9gm9.js → bibtex-CCDwmbuA.js} +0 -0
  325. /package/dist/web/assets/{bicep-CxS8CUve.js → bicep-BC0ryoGM.js} +0 -0
  326. /package/dist/web/assets/{bird2-CuZhQzYR.js → bird2-C50V_A-0.js} +0 -0
  327. /package/dist/web/assets/{c-9bnDqE3g.js → c-Ddorhq0U.js} +0 -0
  328. /package/dist/web/assets/{c3-JMZTrOhA.js → c3-DdIf5r9E.js} +0 -0
  329. /package/dist/web/assets/{cadence-DsDNayJS.js → cadence-s9pd1Wng.js} +0 -0
  330. /package/dist/web/assets/{can-open-in-ppm-BJfpynya.js → can-open-in-ppm-C6hZV1OP.js} +0 -0
  331. /package/dist/web/assets/{catppuccin-frappe-DYIKXXBe.js → catppuccin-frappe-CzJNTyu-.js} +0 -0
  332. /package/dist/web/assets/{catppuccin-latte-IYYOnUJ8.js → catppuccin-latte-BNpt-m7s.js} +0 -0
  333. /package/dist/web/assets/{catppuccin-macchiato-BrJ_7mfS.js → catppuccin-macchiato-FYGkfsJ5.js} +0 -0
  334. /package/dist/web/assets/{catppuccin-mocha-gzSu7v7-.js → catppuccin-mocha-it2g5D1q.js} +0 -0
  335. /package/dist/web/assets/{clarity-DLzsC0Hb.js → clarity-BVFBTjMe.js} +0 -0
  336. /package/dist/web/assets/{clipboard-7fw0Shic.js → clipboard-BWznymz7.js} +0 -0
  337. /package/dist/web/assets/{clojure-DS1BvoTt.js → clojure-BSYvXMI8.js} +0 -0
  338. /package/dist/web/assets/{cmake-CDvsJwYp.js → cmake-DGEqH-Np.js} +0 -0
  339. /package/dist/web/assets/{codeowners-BjsYiflJ.js → codeowners-D8FCOxWg.js} +0 -0
  340. /package/dist/web/assets/{codeql-CG-7ARat.js → codeql-COV0eluG.js} +0 -0
  341. /package/dist/web/assets/{common-lisp-DSO1Lbh9.js → common-lisp-xHnZUlgt.js} +0 -0
  342. /package/dist/web/assets/{coq-DYdh3oP_.js → coq-Cs_2i3Xg.js} +0 -0
  343. /package/dist/web/assets/{csharp-DxEBz5s0.js → csharp-B1ONB4PT.js} +0 -0
  344. /package/dist/web/assets/{css-dal3Q-8C.js → css-BgGQbvrZ.js} +0 -0
  345. /package/dist/web/assets/{csv-CpqjMGiA.js → csv-CNHmQBzs.js} +0 -0
  346. /package/dist/web/assets/{csv-parser-3umBA4NY.js → csv-parser-DWR24J17.js} +0 -0
  347. /package/dist/web/assets/{cue-DinoJ_5k.js → cue-ZXAKzwIy.js} +0 -0
  348. /package/dist/web/assets/{cypher-DzxqmkUW.js → cypher-4PL5bmT5.js} +0 -0
  349. /package/dist/web/assets/{d-BxNwJuEC.js → d-CEsV3RT2.js} +0 -0
  350. /package/dist/web/assets/{dark-plus-Clmv3V-0.js → dark-plus-NtFnYSDz.js} +0 -0
  351. /package/dist/web/assets/{dart-BWVtXD35.js → dart-CKHn4mDf.js} +0 -0
  352. /package/dist/web/assets/{data-grid-types-B4n51Fck.js → data-grid-types-CxU8oo-j.js} +0 -0
  353. /package/dist/web/assets/{dax-DsImuWgJ.js → dax-Cmkj1I_M.js} +0 -0
  354. /package/dist/web/assets/{desktop-B0jJuG2r.js → desktop-DJLalvPQ.js} +0 -0
  355. /package/dist/web/assets/{diff-CWqAAxoE.js → diff-BnS2wpj6.js} +0 -0
  356. /package/dist/web/assets/{dist-C0eNNfbt.js → dist-CuIdRyUB.js} +0 -0
  357. /package/dist/web/assets/{dist-B-EXdSYE.js → dist-uYjs3Wv6.js} +0 -0
  358. /package/dist/web/assets/{docker-CYFCJdIL.js → docker-CovNy7ml.js} +0 -0
  359. /package/dist/web/assets/{dotenv-CKDUjURg.js → dotenv-Gh4w3I6B.js} +0 -0
  360. /package/dist/web/assets/{dracula-CSoPspHE.js → dracula-NF0tAHXl.js} +0 -0
  361. /package/dist/web/assets/{dracula-soft-BuFjw5L1.js → dracula-soft-Cj_qBurK.js} +0 -0
  362. /package/dist/web/assets/{dream-maker-B6PdDRZu.js → dream-maker-CRuZPcl7.js} +0 -0
  363. /package/dist/web/assets/{emacs-lisp-CMcXvD0G.js → emacs-lisp-BACmC9qj.js} +0 -0
  364. /package/dist/web/assets/{everforest-dark-cU8-wYzi.js → everforest-dark-Dd9av4QG.js} +0 -0
  365. /package/dist/web/assets/{everforest-light-KhorllqK.js → everforest-light-C-jsss-B.js} +0 -0
  366. /package/dist/web/assets/{external-link-B8BynhvY.js → external-link-B6Hl0U4X.js} +0 -0
  367. /package/dist/web/assets/{fennel-BCELZK87.js → fennel-BJA9XnL8.js} +0 -0
  368. /package/dist/web/assets/{file-exclamation-point-CZ4DiR75.js → file-exclamation-point-JzhTU2TX.js} +0 -0
  369. /package/dist/web/assets/{fish-BQc0y_jy.js → fish-CKlhNSc2.js} +0 -0
  370. /package/dist/web/assets/{fluent-BTINnwF6.js → fluent-wfglRk5D.js} +0 -0
  371. /package/dist/web/assets/{folder-symlink-B8XrtvQK.js → folder-symlink-Dx1hOk8X.js} +0 -0
  372. /package/dist/web/assets/{format-bytes-WVcFxJuT.js → format-bytes-utwHMTry.js} +0 -0
  373. /package/dist/web/assets/{fortran-free-form-BQim9wDz.js → fortran-free-form-BlXCdid3.js} +0 -0
  374. /package/dist/web/assets/{gdscript-03w5u8un.js → gdscript-BwAVG6Et.js} +0 -0
  375. /package/dist/web/assets/{gdshader-Dp2daNzU.js → gdshader-DPc_T7ib.js} +0 -0
  376. /package/dist/web/assets/{genie-CoNcjPiD.js → genie-B-zZSLCX.js} +0 -0
  377. /package/dist/web/assets/{gherkin-NrPOSPQL.js → gherkin-CJ0ajpGs.js} +0 -0
  378. /package/dist/web/assets/{github-dark-z4RE9ZqA.js → github-dark-Dz8ZkzSP.js} +0 -0
  379. /package/dist/web/assets/{github-dark-default-DOKw-1cI.js → github-dark-default-CNUYo_kp.js} +0 -0
  380. /package/dist/web/assets/{github-dark-dimmed-DJRNMkEA.js → github-dark-dimmed-241z_Ycx.js} +0 -0
  381. /package/dist/web/assets/{github-dark-high-contrast-Bj7jJ_Gs.js → github-dark-high-contrast-7r6yZZYH.js} +0 -0
  382. /package/dist/web/assets/{github-light-B4k_yMFu.js → github-light-C8gmZn-D.js} +0 -0
  383. /package/dist/web/assets/{github-light-default-BHc-Uzhs.js → github-light-default-GAEgq1eA.js} +0 -0
  384. /package/dist/web/assets/{github-light-high-contrast-CHisIywL.js → github-light-high-contrast-3z91352E.js} +0 -0
  385. /package/dist/web/assets/{gleam-CfbypZ4q.js → gleam-C7vxW5zd.js} +0 -0
  386. /package/dist/web/assets/{gn-YoAjyhJa.js → gn-CyJIXwHP.js} +0 -0
  387. /package/dist/web/assets/{gnuplot-xVkc1f1c.js → gnuplot-CqLbGgPd.js} +0 -0
  388. /package/dist/web/assets/{go-GPCwP3Gu.js → go-DdDcK9aX.js} +0 -0
  389. /package/dist/web/assets/{groovy-Crh4Yww9.js → groovy-UYHggEqH.js} +0 -0
  390. /package/dist/web/assets/{gruvbox-dark-hard-BluUFuDS.js → gruvbox-dark-hard-B4ierkJn.js} +0 -0
  391. /package/dist/web/assets/{gruvbox-dark-medium-Cxk1FWQp.js → gruvbox-dark-medium-DYwkDSZ6.js} +0 -0
  392. /package/dist/web/assets/{gruvbox-dark-soft-CHXMiFmj.js → gruvbox-dark-soft-CVL4P-Lz.js} +0 -0
  393. /package/dist/web/assets/{gruvbox-light-hard-B6eKPjAD.js → gruvbox-light-hard-BJ0LewUZ.js} +0 -0
  394. /package/dist/web/assets/{gruvbox-light-medium-pDwMm1ut.js → gruvbox-light-medium-CaqqjeGJ.js} +0 -0
  395. /package/dist/web/assets/{gruvbox-light-soft-Cxu6kHqK.js → gruvbox-light-soft-ByKMoVNr.js} +0 -0
  396. /package/dist/web/assets/{haskell-C6JKHjbK.js → haskell-BilYRVPp.js} +0 -0
  397. /package/dist/web/assets/{haxe-BuBNdF0a.js → haxe-Brs9Bj1s.js} +0 -0
  398. /package/dist/web/assets/{hcl-DZpDdGj2.js → hcl-ClrZpol-.js} +0 -0
  399. /package/dist/web/assets/{hjson-CBkhYRuo.js → hjson-9PvHnYMX.js} +0 -0
  400. /package/dist/web/assets/{hlsl-C5nMxnp9.js → hlsl-BbBk4vqV.js} +0 -0
  401. /package/dist/web/assets/{horizon-VAFvA6R6.js → horizon-E5Py0cny.js} +0 -0
  402. /package/dist/web/assets/{horizon-bright-BC0xn7T3.js → horizon-bright-DVCsNGEk.js} +0 -0
  403. /package/dist/web/assets/{houston-BxrUivmz.js → houston-JdFEax9Y.js} +0 -0
  404. /package/dist/web/assets/{hy-DLtOXoaH.js → hy-W_W3tLKT.js} +0 -0
  405. /package/dist/web/assets/{image-gallery-Gnf7TdCR.js → image-gallery-5IURd6db.js} +0 -0
  406. /package/dist/web/assets/{imba-BdpFXM2W.js → imba-CfAqJz7T.js} +0 -0
  407. /package/dist/web/assets/{ini-BInJO_T0.js → ini-C_3gvKWs.js} +0 -0
  408. /package/dist/web/assets/{java-Dxuddnkb.js → java-CKqtXZ-j.js} +0 -0
  409. /package/dist/web/assets/{javascript-CVamJfLY.js → javascript-C7gSEfae.js} +0 -0
  410. /package/dist/web/assets/{json-BLZ0ozYk.js → json-BoN6e11T.js} +0 -0
  411. /package/dist/web/assets/{json5-BnXzmMKs.js → json5-CgE7C8HW.js} +0 -0
  412. /package/dist/web/assets/{jsonc-CSgkSga7.js → jsonc-DjyoattY.js} +0 -0
  413. /package/dist/web/assets/{jsonl-CY5W2nF2.js → jsonl-lI82wGSw.js} +0 -0
  414. /package/dist/web/assets/{jsonnet-CEJYH3sF.js → jsonnet-CszEI8va.js} +0 -0
  415. /package/dist/web/assets/{jssm-CsJc7Uhk.js → jssm-CZXDlszb.js} +0 -0
  416. /package/dist/web/assets/{jsx-jCiRaHU7.js → jsx-BeRz0eEz.js} +0 -0
  417. /package/dist/web/assets/{kanagawa-dragon-DfoA_GxX.js → kanagawa-dragon-BOmnUiyd.js} +0 -0
  418. /package/dist/web/assets/{kanagawa-lotus-BOLYJpWd.js → kanagawa-lotus-ffU_P5w-.js} +0 -0
  419. /package/dist/web/assets/{kanagawa-wave-DfKlbT1G.js → kanagawa-wave-DKTJZrMu.js} +0 -0
  420. /package/dist/web/assets/{kdl-CmssIFTi.js → kdl-BWECJveH.js} +0 -0
  421. /package/dist/web/assets/{kotlin-BRsNgp6x.js → kotlin-DpVwBCSt.js} +0 -0
  422. /package/dist/web/assets/{kusto-T8X9jUab.js → kusto-BgVqjUZA.js} +0 -0
  423. /package/dist/web/assets/{laserwave-DkJMVJ8Z.js → laserwave-CEVCi8em.js} +0 -0
  424. /package/dist/web/assets/{lean-C65KGVPq.js → lean-CGyfRhLJ.js} +0 -0
  425. /package/dist/web/assets/{less-exIPdDlf.js → less-B0_H10Ku.js} +0 -0
  426. /package/dist/web/assets/{lib-mC1NZfuw.js → lib-hrC3bruJ.js} +0 -0
  427. /package/dist/web/assets/{libesm-DSutUtl1.js → libesm-DVpFmwJu.js} +0 -0
  428. /package/dist/web/assets/{light-plus-DiHUXAZt.js → light-plus-DqzMqPID.js} +0 -0
  429. /package/dist/web/assets/{llvm-CJBnEzFM.js → llvm-9ucnfNiF.js} +0 -0
  430. /package/dist/web/assets/{loader-circle-gSPVxfvH.js → loader-circle-Dpqcv0eS.js} +0 -0
  431. /package/dist/web/assets/{lock-Did-87UV.js → lock-DldbT31x.js} +0 -0
  432. /package/dist/web/assets/{log-DxMyUMuP.js → log-m6A2dOSj.js} +0 -0
  433. /package/dist/web/assets/{logo-CC9NKzca.js → logo-ByPcsC9P.js} +0 -0
  434. /package/dist/web/assets/{luau-Bw10I6zf.js → luau-DFCo8nBn.js} +0 -0
  435. /package/dist/web/assets/{make-C_6M90m6.js → make-C90w3MeA.js} +0 -0
  436. /package/dist/web/assets/{markdown-bR9_R-LF.js → markdown-DT0uywZG.js} +0 -0
  437. /package/dist/web/assets/{material-theme-BUx2Qujn.js → material-theme-BVUO93tJ.js} +0 -0
  438. /package/dist/web/assets/{material-theme-darker-CRJrPgKm.js → material-theme-darker-xXgGDwnF.js} +0 -0
  439. /package/dist/web/assets/{material-theme-lighter-CUAYppPa.js → material-theme-lighter-BjStPzWB.js} +0 -0
  440. /package/dist/web/assets/{material-theme-ocean-DuINF1fg.js → material-theme-ocean-wFmSiKjy.js} +0 -0
  441. /package/dist/web/assets/{material-theme-palenight-W6_icGCj.js → material-theme-palenight-e-0CtRoe.js} +0 -0
  442. /package/dist/web/assets/{matlab-rfqn_b3z.js → matlab-BNaNQAUH.js} +0 -0
  443. /package/dist/web/assets/{mdx-Bh1B_YOJ.js → mdx-DfpVWAqO.js} +0 -0
  444. /package/dist/web/assets/{mermaid-Dxf6Ya2k.js → mermaid-Bpq7wFCP.js} +0 -0
  445. /package/dist/web/assets/{min-dark-CivZ2L0h.js → min-dark-CL2Y0WH6.js} +0 -0
  446. /package/dist/web/assets/{min-light-B1Ykqtma.js → min-light-DOgr_IdP.js} +0 -0
  447. /package/dist/web/assets/{mipsasm-DynHaM0d.js → mipsasm-C9ie2zlB.js} +0 -0
  448. /package/dist/web/assets/{mojo-Clw5PbGH.js → mojo-Md2A2sJy.js} +0 -0
  449. /package/dist/web/assets/{monitor-Dv8vn_6O.js → monitor-4vWfqzuN.js} +0 -0
  450. /package/dist/web/assets/{monokai-DFIooFZT.js → monokai-nbXIEySB.js} +0 -0
  451. /package/dist/web/assets/{moonbit-DnBSZWGM.js → moonbit-CJ-T-s4A.js} +0 -0
  452. /package/dist/web/assets/{move-CCcL2PfL.js → move-DwEehLIK.js} +0 -0
  453. /package/dist/web/assets/{narrat-BDarg5Lk.js → narrat-CuF4sIKr.js} +0 -0
  454. /package/dist/web/assets/{nextflow-groovy-DrZOeCNW.js → nextflow-groovy-1dYhfPfq.js} +0 -0
  455. /package/dist/web/assets/{night-owl-BnZZCK7v.js → night-owl-gZS5mfzY.js} +0 -0
  456. /package/dist/web/assets/{night-owl-light-CEwBsVHS.js → night-owl-light-DDAster5.js} +0 -0
  457. /package/dist/web/assets/{nix-amCzOPMR.js → nix-BlbEYs2c.js} +0 -0
  458. /package/dist/web/assets/{nord-BIs2BC6q.js → nord-BRiPb8Vy.js} +0 -0
  459. /package/dist/web/assets/{nushell-Y02fo4yw.js → nushell-DgWicB1i.js} +0 -0
  460. /package/dist/web/assets/{objective-c-7xOZtWW1.js → objective-c-D8mPZ42Y.js} +0 -0
  461. /package/dist/web/assets/{objective-cpp-eVtjUvVB.js → objective-cpp-B0pNXzuj.js} +0 -0
  462. /package/dist/web/assets/{ocaml-Bi6ZwqG4.js → ocaml-lQd7aK5d.js} +0 -0
  463. /package/dist/web/assets/{odin-8xf1Y0S9.js → odin-CxtIOBjm.js} +0 -0
  464. /package/dist/web/assets/{one-dark-pro-hVv-_y_b.js → one-dark-pro-T_UFnWfe.js} +0 -0
  465. /package/dist/web/assets/{one-light-CJJ3MtHt.js → one-light-LBVqwyV-.js} +0 -0
  466. /package/dist/web/assets/{openscad-B2HcywLk.js → openscad-C5dnS6J7.js} +0 -0
  467. /package/dist/web/assets/{pascal-C7fllV_7.js → pascal-CmWCWQML.js} +0 -0
  468. /package/dist/web/assets/{pkl-qvLC1IWP.js → pkl-BWWOtDQk.js} +0 -0
  469. /package/dist/web/assets/{plastic-BT1wHZv2.js → plastic-ekhupckF.js} +0 -0
  470. /package/dist/web/assets/{play-4MZi1Axp.js → play-CpCAoQRZ.js} +0 -0
  471. /package/dist/web/assets/{plsql-1MsmdmJD.js → plsql-BPsDHXx4.js} +0 -0
  472. /package/dist/web/assets/{plus-BhMZqFsN.js → plus-BR0qewJI.js} +0 -0
  473. /package/dist/web/assets/{po-BigskytD.js → po-BX2FiuW2.js} +0 -0
  474. /package/dist/web/assets/{poimandres-DuklniF7.js → poimandres-DzXOdZcN.js} +0 -0
  475. /package/dist/web/assets/{polar-e2pjN_sp.js → polar-DDRXgJzG.js} +0 -0
  476. /package/dist/web/assets/{portal-container-context-Cm5HipFr.js → portal-container-context-a399Hd9F.js} +0 -0
  477. /package/dist/web/assets/{postcss-DtAeYjWw.js → postcss-BHW6XBhx.js} +0 -0
  478. /package/dist/web/assets/{powerquery-Cr2PtehI.js → powerquery-B89c2NBb.js} +0 -0
  479. /package/dist/web/assets/{powershell-BxFTGLJ4.js → powershell-Dvxrd3Tu.js} +0 -0
  480. /package/dist/web/assets/{prisma-COWJiwdZ.js → prisma-lMK8EFLU.js} +0 -0
  481. /package/dist/web/assets/{prolog-DFvGKRx6.js → prolog-D0YrtMG4.js} +0 -0
  482. /package/dist/web/assets/{proto-CcK80lFt.js → proto-J0mM25aw.js} +0 -0
  483. /package/dist/web/assets/{puppet-BF60bZ4F.js → puppet-CUT0xkhh.js} +0 -0
  484. /package/dist/web/assets/{purescript-zL_69MzU.js → purescript-CoJWSGRp.js} +0 -0
  485. /package/dist/web/assets/{python-CIwKhfb_.js → python-BBrmuz6P.js} +0 -0
  486. /package/dist/web/assets/{qmldir-CXNe04Lo.js → qmldir-CUtzs4Q7.js} +0 -0
  487. /package/dist/web/assets/{qss-C8lAWe6G.js → qss-Dm1RZ8aL.js} +0 -0
  488. /package/dist/web/assets/{r-CL5ZVL3_.js → r-BGP7qZTe.js} +0 -0
  489. /package/dist/web/assets/{racket-BBfh0uh0.js → racket-K_6U1lqJ.js} +0 -0
  490. /package/dist/web/assets/{raku-o6E8R5Q3.js → raku-bNSiZeW_.js} +0 -0
  491. /package/dist/web/assets/{react-CBTnT4sY.js → react-X4jUntEf.js} +0 -0
  492. /package/dist/web/assets/{red-GomRF2Xp.js → red-uVeIEF0f.js} +0 -0
  493. /package/dist/web/assets/{refresh-cw-B06yaBrW.js → refresh-cw-B9iv7csb.js} +0 -0
  494. /package/dist/web/assets/{reg-_ffDIvx9.js → reg-DSm9GWjh.js} +0 -0
  495. /package/dist/web/assets/{regexp-Bl5sF65W.js → regexp-CljRm_j_.js} +0 -0
  496. /package/dist/web/assets/{rel-DgMdqDuj.js → rel-d3JcopZg.js} +0 -0
  497. /package/dist/web/assets/{resolve-theme-CRt_7wpd.js → resolve-theme-DLKmm-lE.js} +0 -0
  498. /package/dist/web/assets/{riscv-8b3-Ye4X.js → riscv-CJmaELjT.js} +0 -0
  499. /package/dist/web/assets/{ron-DrmU1KHP.js → ron-D0g9B1rW.js} +0 -0
  500. /package/dist/web/assets/{rose-pine-C_-E2tF1.js → rose-pine-DOrD2BSH.js} +0 -0
  501. /package/dist/web/assets/{rose-pine-dawn-DEfhNlFH.js → rose-pine-dawn-CzZQ-LCF.js} +0 -0
  502. /package/dist/web/assets/{rose-pine-moon-BdvX3gdn.js → rose-pine-moon-CdmsYp7C.js} +0 -0
  503. /package/dist/web/assets/{rosmsg-B6GhGpd5.js → rosmsg-CmDth6pO.js} +0 -0
  504. /package/dist/web/assets/{rotate-ccw-COXu_9oj.js → rotate-ccw-DnuPzJRE.js} +0 -0
  505. /package/dist/web/assets/{rust-DmC97M1-.js → rust-DGdP6jiR.js} +0 -0
  506. /package/dist/web/assets/{sass-B0tJOHLM.js → sass-Dkgt2FKZ.js} +0 -0
  507. /package/dist/web/assets/{save-CtIGOjmx.js → save-DxonD4y1.js} +0 -0
  508. /package/dist/web/assets/{scala-n8zaFOXv.js → scala-BQLTON6C.js} +0 -0
  509. /package/dist/web/assets/{scheme-BKD9ztBU.js → scheme-DKlxUGCi.js} +0 -0
  510. /package/dist/web/assets/{sdbl-D8gB5-rS.js → sdbl-C3iZJQeZ.js} +0 -0
  511. /package/dist/web/assets/{send-BlyNJAzy.js → send-B-t5Mz26.js} +0 -0
  512. /package/dist/web/assets/{shallow-DYo6goJ4.js → shallow-jwPzEunk.js} +0 -0
  513. /package/dist/web/assets/{shellscript-BfXlf_Ao.js → shellscript-BRu-ZQAx.js} +0 -0
  514. /package/dist/web/assets/{shield-check-B0iGUiOK.js → shield-check-CdTiK1j2.js} +0 -0
  515. /package/dist/web/assets/{shield-off-BNLWBhcq.js → shield-off-DuetkXKM.js} +0 -0
  516. /package/dist/web/assets/{slack-dark-CylEddse.js → slack-dark-qkm_u2zz.js} +0 -0
  517. /package/dist/web/assets/{slack-ochin-w8wg8vuC.js → slack-ochin-BP8_8e4m.js} +0 -0
  518. /package/dist/web/assets/{smalltalk-hiAXA64u.js → smalltalk-Bnz4gt07.js} +0 -0
  519. /package/dist/web/assets/{snazzy-light-BwlV3Xty.js → snazzy-light-fbPZg5io.js} +0 -0
  520. /package/dist/web/assets/{solarized-dark-vmNGdykz.js → solarized-dark-CM0vTRoi.js} +0 -0
  521. /package/dist/web/assets/{solarized-light-DGv_0JXq.js → solarized-light-C4_W9mvs.js} +0 -0
  522. /package/dist/web/assets/{solidity-Y7QSH0B1.js → solidity-Bz6v1PoD.js} +0 -0
  523. /package/dist/web/assets/{splunk-BtgpLjHi.js → splunk-DyNxu-0i.js} +0 -0
  524. /package/dist/web/assets/{sql-CRHYhOia.js → sql-DXRL1gw1.js} +0 -0
  525. /package/dist/web/assets/{ssh-config-DOqSs3au.js → ssh-config-2z1QHuOG.js} +0 -0
  526. /package/dist/web/assets/{stylus-crCAEaBT.js → stylus-D4I-VaeY.js} +0 -0
  527. /package/dist/web/assets/{swift-eE3rT7TC.js → swift-C_2G-tIc.js} +0 -0
  528. /package/dist/web/assets/{synthwave-84-BWy14LBX.js → synthwave-84-osBjChRP.js} +0 -0
  529. /package/dist/web/assets/{system-verilog-DC0-DZM4.js → system-verilog-zQP2qPNU.js} +0 -0
  530. /package/dist/web/assets/{systemd-to5p6N8I.js → systemd-UGfjRSBM.js} +0 -0
  531. /package/dist/web/assets/{table-Bbc783ko.js → table-FLU8ei8b.js} +0 -0
  532. /package/dist/web/assets/{talonscript-DoTcU8wm.js → talonscript-C1XrFPwo.js} +0 -0
  533. /package/dist/web/assets/{tasl-cNZvUs95.js → tasl-B5raVn43.js} +0 -0
  534. /package/dist/web/assets/{tcl-mZE8sZH8.js → tcl-3-vbeMIc.js} +0 -0
  535. /package/dist/web/assets/{terraform-CqHPpIfu.js → terraform-a8VXZDm9.js} +0 -0
  536. /package/dist/web/assets/{text-wrap-CBT4Gxtg.js → text-wrap-B05VGRa-.js} +0 -0
  537. /package/dist/web/assets/{tokyo-night-Tp2rTIZd.js → tokyo-night-4SRhf-Hz.js} +0 -0
  538. /package/dist/web/assets/{toml-CU_vscgn.js → toml-B4N0i8wT.js} +0 -0
  539. /package/dist/web/assets/{trash-2-Bk4yYlck.js → trash-2-CTXlTflF.js} +0 -0
  540. /package/dist/web/assets/{triangle-alert-B8EYecpe.js → triangle-alert-BRq0VAfd.js} +0 -0
  541. /package/dist/web/assets/{tsv-ik7iFB9D.js → tsv-DA5k9Lvw.js} +0 -0
  542. /package/dist/web/assets/{tsx-BMvvMKiv.js → tsx-D9SZ8owC.js} +0 -0
  543. /package/dist/web/assets/{turtle-DBqKCq9o.js → turtle-BTHTvyY_.js} +0 -0
  544. /package/dist/web/assets/{typescript-DXJDmMZZ.js → typescript-DYzV9p5L.js} +0 -0
  545. /package/dist/web/assets/{typespec-CBseCMtZ.js → typespec-BC15eh7F.js} +0 -0
  546. /package/dist/web/assets/{typst-4oY25U9y.js → typst-BJUqzA6D.js} +0 -0
  547. /package/dist/web/assets/{use-is-mobile-D1weanbj.js → use-is-mobile-DFWViA4S.js} +0 -0
  548. /package/dist/web/assets/{utils-BNRH507E.js → utils-C9OjCrou.js} +0 -0
  549. /package/dist/web/assets/{v-BXaZ_1oy.js → v-50Lps6oA.js} +0 -0
  550. /package/dist/web/assets/{vala-BImWJE7z.js → vala-8wiUvvrD.js} +0 -0
  551. /package/dist/web/assets/{vb-CLfj2_sy.js → vb-BlgPLt6B.js} +0 -0
  552. /package/dist/web/assets/{vendor-xterm-_yyu5n32.js → vendor-xterm-BZOrwF_F.js} +0 -0
  553. /package/dist/web/assets/{verilog-BWa8Ed2b.js → verilog-CD9pVW5p.js} +0 -0
  554. /package/dist/web/assets/{vesper-BGj1cg6m.js → vesper-BrivW4PT.js} +0 -0
  555. /package/dist/web/assets/{vhdl-mByK7mlx.js → vhdl-Bunxfa7N.js} +0 -0
  556. /package/dist/web/assets/{viml-CugmlW5g.js → viml-DndUb2qM.js} +0 -0
  557. /package/dist/web/assets/{vitesse-black-vPdpy9TL.js → vitesse-black-BurZSkxW.js} +0 -0
  558. /package/dist/web/assets/{vitesse-dark-BuQK3dUh.js → vitesse-dark-8UShspzC.js} +0 -0
  559. /package/dist/web/assets/{vitesse-light-B3nz1XL9.js → vitesse-light-DghCAZ90.js} +0 -0
  560. /package/dist/web/assets/{vyper-DH_GTIHG.js → vyper-b-Clr-8u.js} +0 -0
  561. /package/dist/web/assets/{wasm-DfVbVJlW.js → wasm-C5v2T06Y.js} +0 -0
  562. /package/dist/web/assets/{wasm-C-LF9GjX.js → wasm-CpcKStkw.js} +0 -0
  563. /package/dist/web/assets/{wenyan-CzQkHyHx.js → wenyan-Dz2srLZR.js} +0 -0
  564. /package/dist/web/assets/{wgsl-Du_M1DW9.js → wgsl-CeD1-dRb.js} +0 -0
  565. /package/dist/web/assets/{wikitext-BWN_w5S7.js → wikitext-CyeS-9FH.js} +0 -0
  566. /package/dist/web/assets/{wit-BR13v5HD.js → wit-Kr-q-qBQ.js} +0 -0
  567. /package/dist/web/assets/{wolfram-BoXxp_Xl.js → wolfram-BKm8bmln.js} +0 -0
  568. /package/dist/web/assets/{x-nhriOX9o.js → x-YDu4m2Iq.js} +0 -0
  569. /package/dist/web/assets/{yaml-DpR_EF-d.js → yaml-2XSxomjM.js} +0 -0
  570. /package/dist/web/assets/{zenscript-C-EdUtUd.js → zenscript-CKIS34vf.js} +0 -0
  571. /package/dist/web/assets/{zig-BD4eA5nU.js → zig-DdHGNllX.js} +0 -0
@@ -1,83 +0,0 @@
1
- // Shared harness for the Document PiP spike stages (terminal / editor).
2
- import { join } from "node:path";
3
- import { CdpClient, sleep } from "./cdp-client";
4
-
5
- export const APP = "http://localhost:5173";
6
- export const SHOTS = "C:/Users/PC/ppm/plans/reports/screenshots";
7
- export { sleep };
8
-
9
- export async function connectApp() {
10
- const cdp = await CdpClient.connect(9333);
11
- const page = (await cdp.targets()).find((t) => t.type === "page" && t.url.startsWith(APP));
12
- if (!page) throw new Error("no app page target");
13
- const sid = await cdp.attach(page.targetId);
14
- await cdp.send("Page.enable", {}, sid);
15
- await cdp.send("Runtime.enable", {}, sid);
16
- const helpers = await Bun.file(join(import.meta.dir, "pip-page-helpers.js")).text();
17
- await cdp.eval(sid, helpers);
18
- const knownTargets = new Set((await cdp.targets()).map((t) => t.targetId));
19
-
20
- const ev = <T = unknown>(expr: string) => cdp.eval<T>(sid, expr);
21
- async function waitFor(expr: string, timeoutMs = 20000, label = expr) {
22
- const t0 = Date.now();
23
- while (Date.now() - t0 < timeoutMs) {
24
- if (await ev<boolean>(`!!(${expr})`)) return;
25
- await sleep(250);
26
- }
27
- throw new Error(`timeout waiting: ${label}`);
28
- }
29
- async function openViaUrl(path: string) {
30
- await ev(`history.pushState(null, '', ${JSON.stringify(path)}); dispatchEvent(new PopStateEvent('popstate')); 'ok'`);
31
- await sleep(600);
32
- }
33
- /** Click the injected trusted-gesture button and wait for its async work to settle. */
34
- async function runGesture(id: string, fnSource: string, timeoutMs = 20000) {
35
- const pt = await ev<{ x: number; y: number }>(`window.__spike.installButton(${JSON.stringify(id)}, ${fnSource})`);
36
- await cdp.click(sid, pt.x, pt.y);
37
- const t0 = Date.now();
38
- while (Date.now() - t0 < timeoutMs) {
39
- const r = await ev<any>(`window.__spike.results[${JSON.stringify(id)}]`);
40
- if (r && r.phase !== "running") return r;
41
- await sleep(200);
42
- }
43
- throw new Error(`gesture ${id} timed out`);
44
- }
45
- /** Any CDP target that appeared since connect (candidate PiP window). */
46
- async function newTargets() {
47
- return (await cdp.targets()).filter((t) => !knownTargets.has(t.targetId));
48
- }
49
- /** Whole-screen capture via PowerShell (PiP is a separate always-on-top OS window). */
50
- async function screenShot(name: string) {
51
- const out = `${SHOTS}/${name}`;
52
- const ps = `Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $b=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bmp=New-Object System.Drawing.Bitmap $b.Width,$b.Height; $g=[System.Drawing.Graphics]::FromImage($bmp); $g.CopyFromScreen($b.Location,[System.Drawing.Point]::Empty,$b.Size); $bmp.Save('${out}',[System.Drawing.Imaging.ImageFormat]::Png); $g.Dispose(); $bmp.Dispose(); 'saved'`;
53
- const p = Bun.spawn(["powershell", "-NoProfile", "-Command", ps], { stdout: "pipe", stderr: "pipe" });
54
- await p.exited;
55
- const err = await new Response(p.stderr).text();
56
- return p.exitCode === 0 && !err ? out : `FAILED (${err.split("\n")[0]?.trim()})`;
57
- }
58
- /** Attach to the PiP window (an about:blank page target created after connect). */
59
- async function attachPip(): Promise<string | null> {
60
- const cands = (await newTargets()).filter((t) => t.type === "page");
61
- for (const t of cands) {
62
- try { return await cdp.attach(t.targetId); } catch { /* try next */ }
63
- }
64
- return null;
65
- }
66
- /** Page.captureScreenshot of the PiP target — works even when the OS desktop is not capturable. */
67
- async function pipShot(pipSid: string | null, name: string) {
68
- if (!pipSid) return "no pip session";
69
- const out = `${SHOTS}/${name}`;
70
- await cdp.screenshot(pipSid, out);
71
- return out;
72
- }
73
- return { cdp, sid, ev, waitFor, openViaUrl, runGesture, newTargets, screenShot, attachPip, pipShot };
74
- }
75
-
76
- export type Harness = Awaited<ReturnType<typeof connectApp>>;
77
-
78
- export async function saveResults(name: string, data: unknown) {
79
- const path = join(import.meta.dir, name);
80
- await Bun.write(path, JSON.stringify(data, null, 2));
81
- console.log(JSON.stringify(data, null, 2));
82
- console.log("saved", path);
83
- }
@@ -1,82 +0,0 @@
1
- // Stage 3b: Monaco glue candidates — editContext:false for typing, explicit editor.layout() on pip resize, suggest widget placement.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const W = `window.__spike.ew`, E = `window.__spike.ed`;
5
- const R: Record<string, unknown> = {};
6
- const h = await connectApp();
7
- const { ev, cdp, sid } = h;
8
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
9
- await ev(`(() => { const S = window.__spike; if (S.pip && !S.pip.closed) { if (S.ew && S.ew.ownerDocument !== document) S.moveBack(S.ew); S.pip.close(); } S.pip = null; S.results = {}; return 'reset'; })()`);
10
- await h.openViaUrl("/project/ppm/editor/.spike/scratch-editor-target.ts");
11
- await sleep(800);
12
- await ev(`window.__spike.ew = document.querySelector('[data-tab-pool-id="editor:.spike/scratch-editor-target.ts"]'); window.__spike.ed = window.__spike.findEditor(window.__spike.ew); 'held'`);
13
- R.mainState = await ev(`({ layout: [${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height], slot: [${W}.offsetWidth, ${W}.offsetHeight], editContextOpt: ${E}.getOption(window.monaco.editor.EditorOption.editContext), nativeEditContextEl: !!${W}.querySelector('.native-edit-context'), editContextApi: 'EditContext' in window, minimapEnabled: ${E}.getOption(window.monaco.editor.EditorOption.minimap).enabled })`);
14
- R.layoutFixInMain = await ev(`(() => { ${E}.layout(); return [${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height]; })()`);
15
-
16
- R.move = await h.runGesture("pip-editor-glue", `async () => {
17
- const S = window.__spike; const w = ${W}; const ed = ${E};
18
- const pip = await documentPictureInPicture.requestWindow({ width: 900, height: 600 }); S.pip = pip; S.copyStyles(pip.document); S.moveToPip(pip, w); S.pinToPip(w);
19
- S.pipResizes = 0; pip.addEventListener('resize', () => { S.pipResizes++; ed.layout(); });
20
- await new Promise(r => setTimeout(r, 600));
21
- const before = [ed.getLayoutInfo().width, ed.getLayoutInfo().height]; ed.layout();
22
- return { pipSize: [pip.innerWidth, pip.innerHeight], layoutBeforeExplicit: before, layoutAfterExplicit: [ed.getLayoutInfo().width, ed.getLayoutInfo().height], wrapper: [w.offsetWidth, w.offsetHeight] };
23
- }`);
24
- const pipSid = await h.attachPip();
25
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, pipSid!);
26
- await sleep(400);
27
-
28
- // Typing with EditContext (default)
29
- await ev(`${E}.setPosition({ lineNumber: 2, column: 1 }); 'p'`);
30
- R.pipFocusTarget = await cdp.eval(pipSid!, `(() => { const nec = document.querySelector('.native-edit-context'); const ta = document.querySelector('.monaco-editor textarea'); (nec || ta).focus(); return { focused: document.activeElement.className, hasEditContext: !!(nec && nec.editContext) }; })()`);
31
- await cdp.typeText(pipSid!, "EC ");
32
- await sleep(300);
33
- R.typingEditContext = await ev(`({ line2: ${E}.getModel().getLineContent(2), pass: ${E}.getModel().getLineContent(2).startsWith('EC ') })`);
34
- // Also try Input.insertText (IME-style commit) with EditContext
35
- await cdp.send("Input.insertText", { text: "IT " }, pipSid!);
36
- await sleep(300);
37
- R.insertTextEditContext = await ev(`({ line2: ${E}.getModel().getLineContent(2), pass: ${E}.getModel().getLineContent(2).includes('IT ') })`);
38
-
39
- // Switch to textarea input and type again
40
- R.switchToTextarea = await ev(`(async () => { ${E}.updateOptions({ editContext: false }); await new Promise(r => setTimeout(r, 300)); return { editContextOpt: ${E}.getOption(window.monaco.editor.EditorOption.editContext), textarea: !!${W}.querySelector('.monaco-editor textarea'), nec: !!${W}.querySelector('.native-edit-context') }; })()`);
41
- await ev(`${E}.setPosition({ lineNumber: 2, column: 1 }); 'p'`);
42
- await cdp.eval(pipSid!, `document.querySelector('.monaco-editor textarea').focus(); document.activeElement.className`);
43
- await cdp.typeText(pipSid!, "TA ");
44
- await sleep(300);
45
- R.typingTextarea = await ev(`({ line2: ${E}.getModel().getLineContent(2), pass: ${E}.getModel().getLineContent(2).startsWith('TA ') })`);
46
- await h.pipShot(pipSid, "spike-02c-editor-in-pip-typed.png");
47
-
48
- // Suggest widget placement (textarea mode): type "spi" on a new line then Ctrl+Space
49
- await ev(`${E}.setPosition({ lineNumber: 8, column: 1 }); 'p'`);
50
- await cdp.eval(pipSid!, `document.querySelector('.monaco-editor textarea').focus(); 'f'`);
51
- await cdp.pressKey(pipSid!, "Enter", "Enter", 13, "\r");
52
- await cdp.typeText(pipSid!, "spi");
53
- await cdp.pressKey(pipSid!, " ", "Space", 32, undefined, 2); // Ctrl+Space
54
- await sleep(1200);
55
- R.suggestWidget = await ev(`(() => { const w = ${W}; const sw = w.querySelector('.suggest-widget'); return { inWrapper: !!sw, visible: sw ? sw.classList.contains('visible') : null, inMainDoc: !!document.querySelector('.suggest-widget'), items: sw ? sw.querySelectorAll('.monaco-list-row').length : 0 }; })()`);
56
- await h.pipShot(pipSid, "spike-02e-editor-in-pip-suggest.png");
57
- await cdp.pressKey(pipSid!, "Escape", "Escape", 27);
58
-
59
- // Resize via resizeTo with the pip 'resize' → editor.layout() glue
60
- R.resizeGlue = await (async () => {
61
- const pt = await cdp.eval<any>(pipSid!, `(() => { const b = document.createElement('button'); b.id = 'rz'; b.textContent = 'rz'; b.style.cssText = 'position:fixed;right:4px;bottom:4px;z-index:99999'; b.onclick = () => window.resizeTo(700, 450); document.body.append(b); const r = b.getBoundingClientRect(); return { x: r.x + r.width / 2, y: r.y + r.height / 2 }; })()`);
62
- await cdp.click(pipSid!, pt.x, pt.y);
63
- await sleep(600);
64
- const r = await ev(`({ pipResizes: window.__spike.pipResizes, layout: [${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height], pip: [window.__spike.pip.innerWidth, window.__spike.pip.innerHeight] })`);
65
- await cdp.eval(pipSid!, `document.getElementById('rz').remove(); 'x'`);
66
- return r;
67
- })();
68
- await h.pipShot(pipSid, "spike-02d-editor-in-pip-resized.png");
69
-
70
- // Return: explicit layout + undo of pip-typed text
71
- R.back = await ev(`(async () => { const S = window.__spike; const w = ${W}; const ed = ${E}; const r = S.moveBack(w); await new Promise(res => setTimeout(res, 800));
72
- const stale = [ed.getLayoutInfo().width, ed.getLayoutInfo().height]; ed.layout(); ed.updateOptions({ editContext: true });
73
- return { ...r, layoutStaleAfterReturn: stale, layoutAfterExplicit: [ed.getLayoutInfo().width, ed.getLayoutInfo().height], slot: [w.offsetWidth, w.offsetHeight] }; })()`);
74
- await ev(`window.__spike.pip.close(); 'c'`);
75
- await sleep(400);
76
- await ev(`${E}.focus(); 'f'`);
77
- const undoSteps: string[] = [];
78
- for (let i = 0; i < 6; i++) { await cdp.pressKey(sid, "z", "KeyZ", 90, undefined, 2); await sleep(150); undoSteps.push(await ev(`${E}.getModel().getLineContent(2) + ' || L8=' + (${E}.getModel().getLineCount() >= 9 ? ${E}.getModel().getLineContent(9) : '')`)); }
79
- R.undoAfterReturn = { steps: undoSteps, line2Restored: await ev(`${E}.getModel().getLineContent(2) === 'export const spikeLine1 = "one";'`) };
80
- await cdp.screenshot(sid, "C:/Users/PC/ppm/plans/reports/screenshots/spike-04-editor-after-return.png");
81
- await saveResults("pip-results-editor-glue.json", R);
82
- cdp.close();
@@ -1,129 +0,0 @@
1
- // Stage 3: move the live Monaco editor tab wrapper into a Document PiP window and test it.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const TAB = "editor:.spike/scratch-editor-target.ts";
5
- const Q = `document.querySelector('[data-tab-pool-id="${TAB}"]')`;
6
- const W = `window.__spike.ew`;
7
- const E = `window.__spike.ed`;
8
- const R: Record<string, unknown> = {};
9
- const h = await connectApp();
10
- const { ev, cdp, sid } = h;
11
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
12
-
13
- await ev(`(() => { const S = window.__spike; if (S.pip && !S.pip.closed) { if (S.ew && S.ew.ownerDocument !== document) S.moveBack(S.ew); S.pip.close(); } S.pip = null; S.results = {}; return 'reset'; })()`);
14
- await h.openViaUrl("/project/ppm/editor/.spike/scratch-editor-target.ts");
15
- await h.waitFor(`${Q} && ${Q}.style.display !== 'none' && ${Q}.querySelector('.monaco-editor .view-lines') && window.__spike.findEditor(${Q})`, 30000, "editor visible");
16
- await ev(`window.__spike.ew = ${Q}; window.__spike.ed = window.__spike.findEditor(window.__spike.ew); 'held'`);
17
- const wordWrapExpr = `${E}.getOption(window.monaco.editor.EditorOption.wordWrap)`;
18
-
19
- async function typeAt(targetSid: string, text: string) {
20
- await cdp.typeText(targetSid, text);
21
- await sleep(300);
22
- }
23
- // Baseline in main: put cursor at 1:1, type marker (trusted)
24
- await ev(`${E}.setPosition({ lineNumber: 1, column: 1 }); ${E}.focus(); 'f'`);
25
- await typeAt(sid, "MAIN1 ");
26
- await sleep(2000); // let the 1s autosave + dirty-title re-render settle before the move
27
- R.baseline = await ev(`({ line1: ${E}.getModel().getLineContent(1), layoutW: ${E}.getLayoutInfo().width, layoutH: ${E}.getLayoutInfo().height, wordWrap: ${wordWrapExpr}, minimapCanvases: ${W}.querySelectorAll('.minimap canvas').length })`);
28
-
29
- R.move = await h.runGesture("pip-editor", `async () => {
30
- const S = window.__spike; const w = ${W}; const ed = ${E};
31
- const pip = await documentPictureInPicture.requestWindow({ width: 900, height: 600 }); S.pip = pip;
32
- const styles = S.copyStyles(pip.document); const moved = S.moveToPip(pip, w); S.pinToPip(w); S.installClickProbes(pip, w);
33
- await new Promise(r => setTimeout(r, 800));
34
- const vl = w.querySelector('.view-lines'); const mm = w.querySelector('.minimap canvas');
35
- return { styles, moved, pipSize: [pip.innerWidth, pip.innerHeight], viewLines: vl.children.length, firstLineText: vl.children[0]?.textContent, layout: [ed.getLayoutInfo().width, ed.getLayoutInfo().height],
36
- minimap: mm ? { w: mm.width, h: mm.height } : null, editorRect: (() => { const r = ed.getDomNode().getBoundingClientRect(); return [r.width, r.height]; })(), monacoTheme: pip.getComputedStyle(w.querySelector('.monaco-editor')).backgroundColor, mainBg: getComputedStyle(document.body).backgroundColor };
37
- }`);
38
- const pipSid = await h.attachPip();
39
- R.pipAttached = !!pipSid;
40
- if (!pipSid) throw new Error("no pip target");
41
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, pipSid);
42
- await sleep(600);
43
- R.shotInPip = await h.pipShot(pipSid, "spike-02-editor-in-pip.png");
44
-
45
- // Mouse: trusted click at line 3 in the PiP → cursor moves? then drag-select on line 2
46
- R.mouseInPip = await (async () => {
47
- const geo = await cdp.eval<any>(pipSid, `(() => { const lines = [...document.querySelectorAll('.view-line')]; const l3 = lines.find(l => l.textContent.includes('spikeLine3')) || lines[2]; if (!l3) return null; const r = l3.getBoundingClientRect(); return { x: r.x + 40, y: r.y + r.height / 2, text: l3.textContent }; })()`);
48
- if (!geo) return { error: "no .view-line in pip doc", inPip: await ev(`${W}.ownerDocument !== document`) };
49
- await cdp.click(pipSid, geo.x, geo.y);
50
- await sleep(300);
51
- const pos = await ev<any>(`(() => { const p = ${E}.getPosition(); return [p.lineNumber, p.column]; })()`);
52
- const g2 = await cdp.eval<any>(pipSid, `(() => { const l = [...document.querySelectorAll('.view-line')].find(l => l.textContent.includes('spikeLine2')); const r = l.getBoundingClientRect(); return { x: r.x + 4, y: r.y + r.height / 2 }; })()`);
53
- await cdp.send("Input.dispatchMouseEvent", { type: "mousePressed", x: g2.x, y: g2.y, button: "left", clickCount: 1 }, pipSid);
54
- for (let i = 1; i <= 8; i++) await cdp.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: g2.x + i * 20, y: g2.y, button: "left", buttons: 1 }, pipSid);
55
- await cdp.send("Input.dispatchMouseEvent", { type: "mouseReleased", x: g2.x + 160, y: g2.y, button: "left", clickCount: 1 }, pipSid);
56
- await sleep(300);
57
- const sel = await ev<string>(`${E}.getModel().getValueInRange(${E}.getSelection())`);
58
- await h.pipShot(pipSid, "spike-02b-editor-in-pip-selection.png");
59
- return { clickedLineText: geo.text, positionAfterClick: pos, dragSelection: sel, dragPass: sel.length > 0 };
60
- })();
61
-
62
- // Keyboard: trusted typing in PiP at 1:1
63
- await ev(`${E}.setPosition({ lineNumber: 1, column: 1 }); 'p'`);
64
- await cdp.eval(pipSid, `document.querySelector('.monaco-editor textarea').focus(); document.activeElement.className`);
65
- await typeAt(pipSid, "PIP2 ");
66
- R.typingInPip = await ev(`({ line1: ${E}.getModel().getLineContent(1), pass: ${E}.getModel().getLineContent(1).startsWith('PIP2 MAIN1 ') })`);
67
- R.shotTyped = await h.pipShot(pipSid, "spike-02c-editor-in-pip-typed.png");
68
-
69
- // Resize: wrapper style (automaticLayout RO path) + pip resizeTo via trusted click
70
- R.resizeViaStyle = await ev(`(async () => { const w = ${W}; const ed = ${E}; const before = [ed.getLayoutInfo().width, ed.getLayoutInfo().height]; w.style.height = '50%'; w.style.width = '70%';
71
- await new Promise(r => setTimeout(r, 800)); const after = [ed.getLayoutInfo().width, ed.getLayoutInfo().height]; w.style.height = '100%'; w.style.width = '100%'; await new Promise(r => setTimeout(r, 800));
72
- return { before, after, restored: [ed.getLayoutInfo().width, ed.getLayoutInfo().height], relayout: before[0] !== after[0] }; })()`);
73
- R.resizeViaWindow = await (async () => {
74
- const pt = await cdp.eval<any>(pipSid, `(() => { const b = document.createElement('button'); b.id = 'rz'; b.textContent = 'rz'; b.style.cssText = 'position:fixed;right:4px;bottom:4px;z-index:99999'; b.onclick = () => window.resizeTo(700, 450); document.body.append(b); const r = b.getBoundingClientRect(); return { x: r.x + r.width / 2, y: r.y + r.height / 2 }; })()`);
75
- const before = await ev<any>(`[${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height]`);
76
- await cdp.click(pipSid, pt.x, pt.y);
77
- const s: unknown[] = [];
78
- for (const ms of [300, 1000, 3000]) { await sleep(ms); s.push(await ev(`({ afterMs: ${ms}, layout: [${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height], pip: [window.__spike.pip.innerWidth, window.__spike.pip.innerHeight] })`)); }
79
- await cdp.eval(pipSid, `document.getElementById('rz').remove(); 'x'`);
80
- return { before, samples: s };
81
- })();
82
- R.shotResized = await h.pipShot(pipSid, "spike-02d-editor-in-pip-resized.png");
83
-
84
- // React onClick in PiP: the toolbar "Wrap" button toggles wordWrap through a zustand store → Monaco option
85
- R.reactClickInPip = await (async () => {
86
- const pt = await cdp.eval<any>(pipSid, `(() => { const b = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Wrap'); if (!b) return null; const r = b.getBoundingClientRect(); return { x: r.x + r.width / 2, y: r.y + r.height / 2 }; })()`);
87
- if (!pt) return "no Wrap button in pip";
88
- const before = await ev(wordWrapExpr);
89
- await ev(`window.__spike.probe = { mainDocClick: 0, pipDocClick: 0, wrapperClick: 0, reactRootClick: 0 }; 'r'`);
90
- await cdp.click(pipSid, pt.x, pt.y);
91
- await sleep(600);
92
- return { wordWrapBefore: before, wordWrapAfter: await ev(wordWrapExpr), probe: await ev(`({ ...window.__spike.probe })`) };
93
- })();
94
-
95
- // Widgets: trigger suggest (Ctrl+Space) in PiP and see where the widget renders
96
- R.suggestWidget = await (async () => {
97
- await ev(`${E}.setPosition({ lineNumber: 7, column: 1 }); 'p'`);
98
- await cdp.eval(pipSid, `document.querySelector('.monaco-editor textarea').focus(); 'f'`);
99
- await cdp.typeText(pipSid, "spi");
100
- await sleep(1200);
101
- const r = await ev(`(() => { const w = ${W}; const sw = w.querySelector('.suggest-widget'); const mainSw = document.querySelector('.suggest-widget');
102
- return { inWrapper: !!sw, visible: sw ? sw.classList.contains('visible') : null, inMainDoc: !!mainSw, overflowContainer: !!w.querySelector('.overflowingContentWidgets'), fixedOverflow: ${E}.getOption(window.monaco.editor.EditorOption.fixedOverflowWidgets) }; })()`);
103
- await h.pipShot(pipSid, "spike-02e-editor-in-pip-suggest.png");
104
- await cdp.pressKey(pipSid, "Escape", "Escape", 27);
105
- for (let i = 0; i < 3; i++) await cdp.pressKey(pipSid, "Backspace", "Backspace", 8);
106
- return r;
107
- })();
108
-
109
- // Move back, then undo history: Ctrl+Z x2 should remove "PIP2 " then "MAIN1 "
110
- R.pullbackAttemptsWhileInPip = await ev(`({ attempts: window.__spike.pullbackAttempts, stillInPip: ${W}.ownerDocument !== document })`);
111
- R.back = await ev(`(async () => { const S = window.__spike; const w = ${W}; const r = S.moveBack(w); await new Promise(res => setTimeout(res, 800)); return { ...r, layout: [${E}.getLayoutInfo().width, ${E}.getLayoutInfo().height], line1: ${E}.getModel().getLineContent(1) }; })()`);
112
- await ev(`window.__spike.pip.close(); 'c'`);
113
- await sleep(500);
114
- await ev(`${E}.focus(); 'f'`);
115
- await cdp.pressKey(sid, "z", "KeyZ", 90, undefined, 2); // Ctrl+Z
116
- await sleep(300);
117
- const afterUndo1 = await ev(`${E}.getModel().getLineContent(1)`);
118
- await cdp.pressKey(sid, "z", "KeyZ", 90, undefined, 2);
119
- await sleep(300);
120
- const afterUndo2 = await ev(`${E}.getModel().getLineContent(1)`);
121
- await ev(`${E}.setPosition({ lineNumber: 1, column: 1 }); ${E}.focus(); 'f'`);
122
- await typeAt(sid, "BACK3 ");
123
- R.afterReturn = await ev(`(async () => { const S = window.__spike; const w = ${W}; const ed = ${E}; const btn = [...w.querySelectorAll('button')].find(b => b.textContent.trim() === 'Wrap'); const ww0 = ${wordWrapExpr}; btn && btn.click(); await new Promise(r => setTimeout(r, 500));
124
- return { afterUndo1: ${JSON.stringify(afterUndo1)}, afterUndo2: ${JSON.stringify(afterUndo2)}, undoPass: ${JSON.stringify(afterUndo2)}.startsWith('export const spikeLine1'), line1AfterTyping: ed.getModel().getLineContent(1), typingPass: ed.getModel().getLineContent(1).startsWith('BACK3 '), reactWrapToggle: { before: ww0, after: ${wordWrapExpr} } }; })()`);
125
- // restore wordWrap + undo the BACK3 edit so the scratch file autosaves clean-ish
126
- await ev(`(async () => { const w = ${W}; const btn = [...w.querySelectorAll('button')].find(b => b.textContent.trim() === 'Wrap'); if (${wordWrapExpr} !== 'off' && btn) btn.click(); ${E}.trigger('spike', 'undo', null); return 'ok'; })()`);
127
- await cdp.screenshot(sid, "C:/Users/PC/ppm/plans/reports/screenshots/spike-04-editor-after-return.png");
128
- await saveResults("pip-results-editor.json", R);
129
- cdp.close();
@@ -1,38 +0,0 @@
1
- // Debug: isolate "keys ignored" — round-tripped terminal vs fresh terminal, term.input() vs keyboard.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const R: Record<string, unknown> = {};
5
- const h = await connectApp();
6
- const { ev, cdp, sid } = h;
7
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
8
-
9
- const T1 = `window.__spike.findTerminal(window.__spike.tw)`;
10
- // 1. term.input on the round-tripped terminal
11
- await h.openViaUrl("/project/ppm/terminal/1");
12
- await sleep(500);
13
- R.inputApiRoundTripped = await ev(`(async () => { const S = window.__spike; const t = ${T1}; S.dataLog = []; t.input('echo VIA-INPUT-API\\r', true);
14
- await new Promise(r => setTimeout(r, 1500)); return { dataLog: S.dataLog, echoed: S.termText(t, 80).includes('VIA-INPUT-API'), tail: S.termText(t, 3), rows: t.rows, cols: t.cols, visible: t.element.getBoundingClientRect().height }; })()`);
15
-
16
- // 2. Fresh terminal tab (never moved): trusted keys
17
- await h.openViaUrl("/project/ppm/terminal/2");
18
- const Q2 = `document.querySelector('[data-tab-pool-id^="terminal:2"]')`;
19
- await h.waitFor(`${Q2} && ${Q2}.querySelector('.xterm-helper-textarea')`, 15000, "terminal 2");
20
- await sleep(3000); // shell boot
21
- await ev(`window.__spike.tw2 = ${Q2}; window.__spike.t2 = window.__spike.findTerminal(window.__spike.tw2); window.__spike.dataLog2 = []; window.__spike.t2.onData(d => window.__spike.dataLog2.push(d)); 'ok'`);
22
- await ev(`window.__spike.tw2.querySelector('.xterm-helper-textarea').focus(); 'f'`);
23
- await cdp.typeText(sid, "echo FRESH-TERM");
24
- await cdp.pressKey(sid, "Enter", "Enter", 13, "\r");
25
- await sleep(1500);
26
- R.freshTerminalTrustedKeys = await ev(`(() => { const S = window.__spike; const t = S.t2; return { id: S.tw2.dataset.tabPoolId, dataLog: S.dataLog2.join(''), echoed: S.termText(t, 80).includes('FRESH-TERM'), tail: S.termText(t, 3), rows: t.rows, cols: t.cols }; })()`);
27
-
28
- // 3. Back to the round-tripped terminal: trusted keys with focus emulation on
29
- await h.openViaUrl("/project/ppm/terminal/1");
30
- await sleep(500);
31
- await ev(`window.__spike.dataLog = []; window.__spike.tw.querySelector('.xterm-helper-textarea').focus(); 'f'`);
32
- await cdp.typeText(sid, "echo RT-KEYS");
33
- await cdp.pressKey(sid, "Enter", "Enter", 13, "\r");
34
- await sleep(1500);
35
- R.roundTrippedTrustedKeys = await ev(`(() => { const S = window.__spike; const t = ${T1}; return { dataLog: S.dataLog.join(''), echoed: S.termText(t, 80).includes('RT-KEYS'), tail: S.termText(t, 3),
36
- textareaIsTermTextarea: t.textarea === S.tw.querySelector('.xterm-helper-textarea'), textareaDoc: t.textarea.ownerDocument === document, elementDoc: t.element.ownerDocument === document }; })()`);
37
- await saveResults("pip-results-input-isolation.json", R);
38
- cdp.close();
@@ -1,34 +0,0 @@
1
- // Debug: which keyboard events reach the xterm textarea (main doc) under CDP input; effect of focus emulation.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const TAB = "terminal:1@panel-8281c2e3";
5
- const Q = `document.querySelector('[data-tab-pool-id="${TAB}"]')`;
6
- const R: Record<string, unknown> = {};
7
- const h = await connectApp();
8
- const { ev, cdp, sid } = h;
9
-
10
- await ev(`(() => { const S = window.__spike; if (S.pip && !S.pip.closed) { if (S.tw && S.tw.ownerDocument !== document) S.moveBack(S.tw); S.pip.close(); } S.pip = null; return 'reset'; })()`);
11
- await h.openViaUrl("/project/ppm/terminal/1");
12
- await h.waitFor(`${Q} && ${Q}.style.display !== 'none'`, 15000, "terminal visible");
13
- await ev(`window.__spike.tw = ${Q}; (() => { const S = window.__spike; const ta = S.tw.querySelector('.xterm-helper-textarea'); S.keyLog = [];
14
- if (!S.keyProbe) { for (const t of ['keydown','keypress','input','beforeinput','keyup']) ta.addEventListener(t, e => S.keyLog.push(t + ':' + (e.key ?? e.data ?? '') + ':' + e.isTrusted)); S.keyProbe = true; }
15
- return 'probe'; })()`);
16
-
17
- async function probe(label: string) {
18
- await ev(`window.__spike.keyLog = []; window.__spike.dataLog = []; window.__spike.tw.querySelector('.xterm-helper-textarea').focus(); 'f'`);
19
- await cdp.typeText(sid, "ab");
20
- await sleep(300);
21
- R[label] = await ev(`({ hasFocus: document.hasFocus(), vis: document.visibilityState, active: document.activeElement && document.activeElement.className, keyLog: window.__spike.keyLog, dataLog: window.__spike.dataLog })`);
22
- }
23
- await probe("noEmulation");
24
- await cdp.send("Page.bringToFront", {}, sid);
25
- await sleep(300);
26
- await probe("afterBringToFront");
27
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
28
- await sleep(300);
29
- await probe("withFocusEmulation");
30
- // Clean the typed junk from the shell line
31
- await cdp.pressKey(sid, "Escape", "Escape", 27);
32
- for (let i = 0; i < 8; i++) await cdp.pressKey(sid, "Backspace", "Backspace", 8);
33
- await saveResults("pip-results-key-probe.json", R);
34
- cdp.close();
@@ -1,54 +0,0 @@
1
- // Verify: do node-level event listeners survive adoption into a Document PiP window? Minimal, controlled.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const R: Record<string, unknown> = {};
5
- const h = await connectApp();
6
- const { ev, cdp, sid } = h;
7
-
8
- async function listenersOf(expr: string) {
9
- const r = await cdp.send("Runtime.evaluate", { expression: expr }, sid);
10
- if (!r.result?.objectId) return "no object";
11
- const l = await cdp.send("DOMDebugger.getEventListeners", { objectId: r.result.objectId }, sid);
12
- return (l.listeners as any[]).map((x) => `${x.type}${x.useCapture ? "(c)" : ""}`).sort();
13
- }
14
-
15
- // Fresh probe nodes in the main doc with listeners; a plain iframe-less popup for comparison is not possible w/o gesture, so PiP only.
16
- await ev(`(() => { const S = window.__spike; S.probeDiv = document.createElement('div'); S.probeTa = document.createElement('textarea'); S.probeDiv.append(S.probeTa);
17
- S.probeHits = { div: 0, ta: 0 }; S.probeDiv.addEventListener('click', () => S.probeHits.div++, true); S.probeTa.addEventListener('keydown', () => S.probeHits.ta++); S.probeTa.addEventListener('input', () => S.probeHits.ta++, true);
18
- document.body.append(S.probeDiv); return 'ok'; })()`);
19
- R.before = { div: await listenersOf("window.__spike.probeDiv"), ta: await listenersOf("window.__spike.probeTa") };
20
-
21
- // Also take the fresh terminal wrapper (tw2) along, checking its listeners right after adoption while PiP is open
22
- R.tw2Before = { ta: await listenersOf("window.__spike.tw2.querySelector('.xterm-helper-textarea')"), xterm: await listenersOf("window.__spike.tw2.querySelector('.xterm')") };
23
-
24
- R.move = await h.runGesture("pip-listener-test", `async () => {
25
- const S = window.__spike; if (S.pip && !S.pip.closed) S.pip.close();
26
- const pip = await documentPictureInPicture.requestWindow({ width: 800, height: 500 }); S.pip = pip; S.copyStyles(pip.document);
27
- pip.document.body.append(S.probeDiv);
28
- const moved = S.moveToPip(pip, S.tw2);
29
- await new Promise(r => setTimeout(r, 300));
30
- // Fire synthetic events on the adopted probe nodes: do the listeners run?
31
- S.probeHits = { div: 0, ta: 0 }; S.probeDiv.dispatchEvent(new MouseEvent('click', { bubbles: true })); S.probeTa.dispatchEvent(new KeyboardEvent('keydown', { key: 'a', bubbles: true })); S.probeTa.dispatchEvent(new InputEvent('input', { data: 'a', inputType: 'insertText', bubbles: true }));
32
- return { moved, probeDivDoc: S.probeDiv.ownerDocument === pip.document, hitsAfterAdoption: { ...S.probeHits } };
33
- }`);
34
- R.afterAdoption = { div: await listenersOf("window.__spike.probeDiv"), ta: await listenersOf("window.__spike.probeTa") };
35
- R.tw2AfterAdoption = { ta: await listenersOf("window.__spike.tw2.querySelector('.xterm-helper-textarea')"), xterm: await listenersOf("window.__spike.tw2.querySelector('.xterm')") };
36
-
37
- // Type into the adopted fresh terminal via its PiP target (trusted)
38
- const pipSid = await h.attachPip();
39
- if (pipSid) {
40
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, pipSid);
41
- await cdp.eval(pipSid, `document.querySelector('.xterm-helper-textarea').focus(); 'f'`);
42
- await ev(`window.__spike.dataLog2 = []; 'r'`);
43
- await cdp.typeText(pipSid, "echo PIP-FRESH");
44
- await cdp.pressKey(pipSid, "Enter", "Enter", 13, "\r");
45
- await sleep(1200);
46
- R.tw2TypingInPip = await ev(`({ dataLog: window.__spike.dataLog2.join(''), echoed: window.__spike.termText(window.__spike.t2, 60).includes('PIP-FRESH') })`);
47
- }
48
- // Move back while the PiP is still open, then check listeners again
49
- R.back = await ev(`(() => { const S = window.__spike; const r = S.moveBack(S.tw2); document.body.append(S.probeDiv); S.probeHits = { div: 0, ta: 0 }; S.probeDiv.dispatchEvent(new MouseEvent('click', { bubbles: true })); S.probeTa.dispatchEvent(new KeyboardEvent('keydown', { key: 'a', bubbles: true })); return { ...r, hitsAfterReturn: { ...S.probeHits } }; })()`);
50
- R.afterReturn = { div: await listenersOf("window.__spike.probeDiv"), ta: await listenersOf("window.__spike.probeTa") };
51
- R.tw2AfterReturn = { ta: await listenersOf("window.__spike.tw2.querySelector('.xterm-helper-textarea')") };
52
- await ev(`window.__spike.pip.close(); 'c'`);
53
- await saveResults("pip-results-listener-survival.json", R);
54
- cdp.close();
@@ -1,19 +0,0 @@
1
- // Debug: compare registered DOM listeners on the round-tripped vs fresh xterm textarea (DOMDebugger.getEventListeners).
2
- import { connectApp, saveResults } from "./pip-spike-common";
3
-
4
- const R: Record<string, unknown> = {};
5
- const h = await connectApp();
6
- const { cdp, sid } = h;
7
-
8
- async function listeners(label: string, expr: string) {
9
- const r = await cdp.send("Runtime.evaluate", { expression: expr }, sid);
10
- if (!r.result?.objectId) { R[label] = "no object: " + JSON.stringify(r.result); return; }
11
- const l = await cdp.send("DOMDebugger.getEventListeners", { objectId: r.result.objectId }, sid);
12
- R[label] = (l.listeners as any[]).map((x) => `${x.type}${x.useCapture ? "(capture)" : ""}${x.passive ? "(passive)" : ""} @${x.lineNumber}:${x.columnNumber}`).sort();
13
- }
14
- await listeners("roundTrippedTextarea", `window.__spike.tw.querySelector('.xterm-helper-textarea')`);
15
- await listeners("freshTextarea", `window.__spike.tw2.querySelector('.xterm-helper-textarea')`);
16
- await listeners("roundTrippedXtermEl", `window.__spike.tw.querySelector('.xterm')`);
17
- await listeners("freshXtermEl", `window.__spike.tw2.querySelector('.xterm')`);
18
- await saveResults("pip-results-listeners.json", R);
19
- cdp.close();
@@ -1,59 +0,0 @@
1
- // Debug: does a synchronous moveBack inside the PiP 'pagehide' handler preserve listeners? Plus canvas inventory.
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const R: Record<string, unknown> = {};
5
- const h = await connectApp();
6
- const { ev, cdp, sid } = h;
7
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
8
-
9
- async function listenersOf(expr: string) {
10
- const r = await cdp.send("Runtime.evaluate", { expression: expr }, sid);
11
- if (!r.result?.objectId) return "no object";
12
- const l = await cdp.send("DOMDebugger.getEventListeners", { objectId: r.result.objectId }, sid);
13
- return (l.listeners as any[]).map((x) => `${x.type}${x.useCapture ? "(c)" : ""}`).sort();
14
- }
15
- R.t2TextareaListenersNow = await listenersOf("window.__spike.tw2.querySelector('.xterm-helper-textarea')");
16
- R.t2Canvases = await ev(`[...window.__spike.tw2.querySelectorAll('canvas')].map(c => ({ cls: c.className, parent: c.parentElement.className, w: c.width, h: c.height, gl: !!c.getContext('webgl2') }))`);
17
-
18
- // Fresh terminal 3 for a clean pagehide test
19
- await h.openViaUrl("/project/ppm/terminal/3");
20
- const Q3 = `document.querySelector('[data-tab-pool-id^="terminal:3"]')`;
21
- await h.waitFor(`${Q3} && ${Q3}.style.display !== 'none' && ${Q3}.querySelector('.xterm-helper-textarea')`, 15000, "terminal 3");
22
- await sleep(2500);
23
- await ev(`window.__spike.tw3 = ${Q3}; window.__spike.t3 = window.__spike.findTerminal(window.__spike.tw3); 'ok'`);
24
- R.t3Before = await listenersOf("window.__spike.tw3.querySelector('.xterm-helper-textarea')");
25
- async function typeMarker(marker: string) {
26
- await ev(`window.__spike.tw3.querySelector('.xterm-helper-textarea').focus(); 'f'`);
27
- await cdp.typeText(sid, `echo ${marker}`);
28
- await cdp.pressKey(sid, "Enter", "Enter", 13, "\r");
29
- await sleep(1300);
30
- return ev(`window.__spike.termText(window.__spike.t3, 60).includes(${JSON.stringify(marker)})`);
31
- }
32
- R.t3Baseline = await typeMarker("T3-BASE");
33
-
34
- // A: pagehide handler moves back synchronously, then pip.close()
35
- R.pagehideA = await h.runGesture("pip-pagehide-a", `async () => {
36
- const S = window.__spike; const w = S.tw3; S.phLog = [];
37
- const pip = await documentPictureInPicture.requestWindow({ width: 800, height: 500 }); S.pip = pip; S.copyStyles(pip.document); S.moveToPip(pip, w);
38
- pip.addEventListener('pagehide', (e) => { S.phLog.push('pagehide owner=' + (w.ownerDocument === pip.document ? 'pip' : 'other') + ' persisted=' + e.persisted); S.moveBack(w); S.phLog.push('moved back, owner main=' + (w.ownerDocument === document)); });
39
- pip.addEventListener('unload', () => S.phLog.push('unload'));
40
- await new Promise(r => setTimeout(r, 400));
41
- const beforeClose = { owner: w.ownerDocument === pip.document ? 'pip' : 'main' };
42
- pip.close();
43
- await new Promise(r => setTimeout(r, 400));
44
- return { beforeClose, phLog: S.phLog, ownerAfter: w.ownerDocument === document ? 'main' : 'other', closed: pip.closed };
45
- }`);
46
- R.t3AfterA = await listenersOf("window.__spike.tw3.querySelector('.xterm-helper-textarea')");
47
- R.t3TypingAfterA = await typeMarker("T3-AFTER-A");
48
-
49
- // B: explicit moveBack BEFORE close (the known-good path) as control
50
- R.controlB = await h.runGesture("pip-pagehide-b", `async () => {
51
- const S = window.__spike; const w = S.tw3;
52
- const pip = await documentPictureInPicture.requestWindow({ width: 800, height: 500 }); S.pip = pip; S.copyStyles(pip.document); S.moveToPip(pip, w);
53
- await new Promise(r => setTimeout(r, 400)); S.moveBack(w); pip.close(); await new Promise(r => setTimeout(r, 400));
54
- return { ownerAfter: w.ownerDocument === document ? 'main' : 'other' };
55
- }`);
56
- R.t3AfterB = await listenersOf("window.__spike.tw3.querySelector('.xterm-helper-textarea')");
57
- R.t3TypingAfterB = await typeMarker("T3-AFTER-B");
58
- await saveResults("pip-results-pagehide.json", R);
59
- cdp.close();
@@ -1,42 +0,0 @@
1
- // Debug: ResizeObserver (created in main window) vs PiP window resizes; does pip 'resize' + manual fit() work?
2
- import { connectApp, saveResults, sleep } from "./pip-spike-common";
3
-
4
- const R: Record<string, unknown> = {};
5
- const h = await connectApp();
6
- const { ev, cdp, sid } = h;
7
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, sid);
8
- await h.openViaUrl("/project/ppm/terminal/3");
9
- await sleep(500);
10
- const W = `window.__spike.tw3`, T = `window.__spike.t3`;
11
-
12
- R.move = await h.runGesture("pip-resize", `async () => {
13
- const S = window.__spike; const w = ${W}; const t = ${T};
14
- const pip = await documentPictureInPicture.requestWindow({ width: 900, height: 600 }); S.pip = pip; S.copyStyles(pip.document); S.moveToPip(pip, w);
15
- S.roLog = []; const ro = new ResizeObserver(es => S.roLog.push('main-RO ' + Math.round(es[0].contentRect.width) + 'x' + Math.round(es[0].contentRect.height))); ro.observe(w);
16
- const pipRo = new pip.ResizeObserver(es => S.roLog.push('pip-RO ' + Math.round(es[0].contentRect.width) + 'x' + Math.round(es[0].contentRect.height))); pipRo.observe(w);
17
- pip.addEventListener('resize', () => S.roLog.push('pip-resize-event ' + pip.innerWidth + 'x' + pip.innerHeight));
18
- await new Promise(r => setTimeout(r, 500));
19
- return { pipSize: [pip.innerWidth, pip.innerHeight], rowsCols: [t.rows, t.cols], roLog: S.roLog.slice() };
20
- }`);
21
- const pipSid = await h.attachPip();
22
- await cdp.send("Emulation.setFocusEmulationEnabled", { enabled: true }, pipSid!);
23
- // resizeTo inside a trusted click in the PiP
24
- const pt = await cdp.eval<any>(pipSid!, `(() => { const b = document.createElement('button'); b.id = 'rz'; b.textContent = 'rz'; b.style.cssText = 'position:fixed;right:4px;bottom:4px;z-index:99999'; b.onclick = () => window.resizeTo(700, 450); document.body.append(b); const r = b.getBoundingClientRect(); return { x: r.x + r.width / 2, y: r.y + r.height / 2 }; })()`);
25
- await ev(`window.__spike.roLog = []; 'r'`);
26
- await cdp.click(pipSid!, pt.x, pt.y);
27
- const samples: unknown[] = [];
28
- for (const ms of [300, 1000, 3000]) {
29
- await sleep(ms);
30
- samples.push(await ev(`({ afterMs: ${ms}, pip: [window.__spike.pip.innerWidth, window.__spike.pip.innerHeight], wrapper: [${W}.offsetWidth, ${W}.offsetHeight], rowsCols: [${T}.rows, ${T}.cols], roLog: window.__spike.roLog.slice() })`));
31
- }
32
- R.afterResizeTo = samples;
33
- // Nudge: force a main-document rendering update; does the main RO now deliver?
34
- R.afterMainNudge = await ev(`(async () => { document.body.style.outline = '1px solid transparent'; document.body.offsetWidth; await new Promise(r => setTimeout(r, 600)); document.body.style.outline = ''; return { rowsCols: [${T}.rows, ${T}.cols], roLog: window.__spike.roLog.slice() }; })()`);
35
- // Glue candidate: manual fit via the FitAddon reached through the fiber (fitRef) — or xterm's proposeDimensions
36
- R.manualFit = await ev(`(() => { const S = window.__spike; const t = ${T}; const w = ${W}; let fit = null; let f = S.fiberOf(w.querySelector('.xterm').parentElement);
37
- for (let d = 0; f && d < 40 && !fit; d++, f = f.return) { let hk = f.memoizedState; for (let i = 0; hk && i < 200; i++, hk = hk.next) { const c = hk.memoizedState && hk.memoizedState.current; if (c && typeof c.fit === 'function' && typeof c.proposeDimensions === 'function') { fit = c; break; } } }
38
- if (!fit) return 'no fitAddon'; const before = [t.rows, t.cols]; const proposed = fit.proposeDimensions(); fit.fit(); return { before, proposed, after: [t.rows, t.cols] }; })()`);
39
- await h.pipShot(pipSid, "spike-01e-terminal-in-pip-after-manual-fit.png");
40
- await ev(`(() => { const S = window.__spike; S.moveBack(${W}); S.pip.close(); return 'done'; })()`);
41
- await saveResults("pip-results-resize.json", R);
42
- cdp.close();
@@ -1,63 +0,0 @@
1
- // Stage 1: authenticate the spike Chrome, open terminal + editor tabs, verify instances reachable.
2
- import { Database } from "bun:sqlite";
3
- import { homedir } from "node:os";
4
- import { join } from "node:path";
5
- import { CdpClient, sleep } from "./cdp-client";
6
-
7
- const PORT = 9333;
8
- const APP = "http://localhost:5173";
9
- const helpers = await Bun.file(join(import.meta.dir, "pip-page-helpers.js")).text();
10
-
11
- const db = new Database(join(homedir(), ".ppm", "ppm.dev.db"), { readonly: true });
12
- const token = JSON.parse((db.query("SELECT value FROM config WHERE key='auth'").get() as any).value).token as string;
13
-
14
- const cdp = await CdpClient.connect(PORT);
15
- const page = (await cdp.targets()).find((t) => t.type === "page" && t.url.startsWith(APP));
16
- if (!page) throw new Error("no app page target: " + JSON.stringify(await cdp.targets()));
17
- const sid = await cdp.attach(page.targetId);
18
- await cdp.send("Page.enable", {}, sid);
19
- await cdp.send("Runtime.enable", {}, sid);
20
-
21
- async function waitFor(expr: string, timeoutMs = 20000, label = expr) {
22
- const t0 = Date.now();
23
- while (Date.now() - t0 < timeoutMs) {
24
- if (await cdp.eval<boolean>(sid, `!!(${expr})`)) return;
25
- await sleep(250);
26
- }
27
- throw new Error(`timeout waiting: ${label}`);
28
- }
29
-
30
- // Auth
31
- const hasToken = await cdp.eval<boolean>(sid, `localStorage.getItem('ppm-auth-token') === ${JSON.stringify(token)}`);
32
- if (!hasToken) {
33
- await cdp.eval(sid, `localStorage.setItem('ppm-auth-token', ${JSON.stringify(token)}); 'set'`);
34
- await cdp.send("Page.navigate", { url: `${APP}/project/ppm` }, sid);
35
- await sleep(1500);
36
- }
37
- await waitFor(`document.querySelector('[data-panel-drop-zone]')`, 30000, "app shell");
38
- console.log("app shell ready, url:", await cdp.eval(sid, "location.href"));
39
-
40
- // Open terminal via URL routing (pushState + popstate → autoOpenFromUrl)
41
- async function openViaUrl(path: string) {
42
- await cdp.eval(sid, `history.pushState(null, '', ${JSON.stringify(path)}); dispatchEvent(new PopStateEvent('popstate')); 'ok'`);
43
- }
44
- await openViaUrl("/project/ppm/terminal/1");
45
- await waitFor(`document.querySelector('[data-tab-pool-id^="terminal"] .xterm-helper-textarea')`, 20000, "xterm");
46
- await openViaUrl("/project/ppm/editor/.spike/scratch-editor-target.ts");
47
- await waitFor(`document.querySelector('[data-tab-pool-id^="editor"] .monaco-editor .view-lines')`, 30000, "monaco");
48
-
49
- await cdp.eval(sid, helpers);
50
- const info = await cdp.eval(sid, `(() => {
51
- const S = window.__spike;
52
- const tw = document.querySelector('[data-tab-pool-id^="terminal"]');
53
- const ew = document.querySelector('[data-tab-pool-id^="editor"]');
54
- const term = S.findTerminal(tw); const ed = S.findEditor(ew);
55
- return {
56
- wrappers: [...document.querySelectorAll('[data-tab-pool-id]')].map(w => ({ id: w.dataset.tabPoolId, display: w.style.display, parent: w.parentElement?.className })),
57
- termFound: !!term, termSize: term && { rows: term.rows, cols: term.cols }, termTail: term && S.termText(term, 5),
58
- editorFound: !!ed, editorLine1: ed && ed.getModel().getLineContent(1), layout: ed && ed.getLayoutInfo().width,
59
- htmlClass: document.documentElement.className, sheets: document.styleSheets.length, monacoGlobal: !!window.monaco,
60
- };
61
- })()`);
62
- console.log(JSON.stringify(info, null, 2));
63
- cdp.close();