sliccy 6.130.0 → 6.131.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/node-server/_shared/agent-wire-types.d.ts +54 -0
- package/dist/node-server/_shared/agent-wire-types.d.ts.map +1 -1
- package/dist/node-server/_shared/cdp-target-info.d.ts +19 -0
- package/dist/node-server/_shared/cdp-target-info.d.ts.map +1 -0
- package/dist/node-server/_shared/cdp-target-info.js +9 -0
- package/dist/node-server/_shared/cdp-target-info.js.map +1 -0
- package/dist/node-server/_shared/discovery-link.d.ts +76 -0
- package/dist/node-server/_shared/discovery-link.d.ts.map +1 -0
- package/dist/node-server/_shared/discovery-link.js +76 -0
- package/dist/node-server/_shared/discovery-link.js.map +1 -0
- package/dist/node-server/_shared/extension-bridge-protocol.d.ts +165 -0
- package/dist/node-server/_shared/extension-bridge-protocol.d.ts.map +1 -0
- package/dist/node-server/_shared/extension-bridge-protocol.js +65 -0
- package/dist/node-server/_shared/extension-bridge-protocol.js.map +1 -0
- package/dist/node-server/_shared/handoff-link.d.ts +90 -0
- package/dist/node-server/_shared/handoff-link.d.ts.map +1 -0
- package/dist/node-server/_shared/handoff-link.js +192 -0
- package/dist/node-server/_shared/handoff-link.js.map +1 -0
- package/dist/node-server/_shared/iframe-repaint.d.ts +51 -0
- package/dist/node-server/_shared/iframe-repaint.d.ts.map +1 -0
- package/dist/node-server/_shared/iframe-repaint.js +118 -0
- package/dist/node-server/_shared/iframe-repaint.js.map +1 -0
- package/dist/node-server/_shared/index.d.ts +9 -0
- package/dist/node-server/_shared/index.d.ts.map +1 -1
- package/dist/node-server/_shared/index.js +9 -0
- package/dist/node-server/_shared/index.js.map +1 -1
- package/dist/node-server/_shared/leader-ext-id.d.ts +16 -0
- package/dist/node-server/_shared/leader-ext-id.d.ts.map +1 -0
- package/dist/node-server/_shared/leader-ext-id.js +16 -0
- package/dist/node-server/_shared/leader-ext-id.js.map +1 -0
- package/dist/node-server/_shared/link-header.d.ts +98 -0
- package/dist/node-server/_shared/link-header.d.ts.map +1 -0
- package/dist/node-server/_shared/link-header.js +441 -0
- package/dist/node-server/_shared/link-header.js.map +1 -0
- package/dist/node-server/_shared/proxy-headers.d.ts +46 -0
- package/dist/node-server/_shared/proxy-headers.d.ts.map +1 -0
- package/dist/node-server/_shared/proxy-headers.js +133 -0
- package/dist/node-server/_shared/proxy-headers.js.map +1 -0
- package/dist/node-server/_shared/well-known-probe.d.ts +63 -0
- package/dist/node-server/_shared/well-known-probe.d.ts.map +1 -0
- package/dist/node-server/_shared/well-known-probe.js +104 -0
- package/dist/node-server/_shared/well-known-probe.js.map +1 -0
- package/dist/node-server/electron-controller.d.ts +51 -0
- package/dist/node-server/electron-controller.js +88 -5
- package/dist/ui/.vite/manifest.json +414 -488
- package/dist/ui/assets/CLAUDE-CWMPcWVI.js +34 -0
- package/dist/ui/assets/{CLAUDE-BG8Wfdn_.js → CLAUDE-DM1onrcU.js} +1 -1
- package/dist/ui/assets/SKILL--AFE5RE3.js +1 -0
- package/dist/ui/assets/{SKILL-DT72j81i.js → SKILL-cpVS35My.js} +1 -1
- package/dist/ui/assets/__vite-browser-external-B6A3FtA_.js +1 -0
- package/dist/ui/assets/{account-store-EaBcIxhN.js → account-store-DsMvFZgS.js} +3 -3
- package/dist/ui/assets/account-store-naVgJKHe.js +1 -0
- package/dist/ui/assets/{adobe-B0U_BLCy.js → adobe-BhZB46bT.js} +1 -1
- package/dist/ui/assets/{adobe-DSoEAq_f.js → adobe-sRIQnDEl.js} +2 -2
- package/dist/ui/assets/{agent-bridge-sbs3wiia.js → agent-bridge-DVqU5-sn.js} +1 -1
- package/dist/ui/assets/{agent-message-to-chat-Cnv4uh07.js → agent-message-to-chat-Df4an5Ei.js} +1 -1
- package/dist/ui/assets/{agent-message-to-chat-DW2ZZk9R.js → agent-message-to-chat-xGeYopQz.js} +1 -1
- package/dist/ui/assets/api-endpoint-DGxXvrur.js +1 -0
- package/dist/ui/assets/api-endpoint-Lx_FU5cP.js +1 -0
- package/dist/ui/assets/{apply-layout-DvwSioYn.js → apply-layout-dNkV0TEv.js} +1 -1
- package/dist/ui/assets/{apps-DFIoDcds.js → apps-tzFQ7_KO.js} +1 -1
- package/dist/ui/assets/{auto-mount-table-CEBCZFRF.js → auto-mount-table-0jMTi9rV.js} +1 -1
- package/dist/ui/assets/{azure-openai-C_J_i_Uv.js → azure-openai-B9ZeZZ0T.js} +1 -1
- package/dist/ui/assets/{azure-openai-DUJebq5R.js → azure-openai-DsmgiFlX.js} +1 -1
- package/dist/ui/assets/{backend-hostfs-t651gkrP.js → backend-hostfs-BH8uwRZG.js} +1 -1
- package/dist/ui/assets/{backend-hostfs-BQYf7TAS.js → backend-hostfs-BxfjZHzO.js} +1 -1
- package/dist/ui/assets/bridge-protocol-06nbmp2X.js +1 -0
- package/dist/ui/assets/bridge-protocol-DdqxTTSu.js +1 -0
- package/dist/ui/assets/{bsh-watchdog-D97yX3sQ.js → bsh-watchdog-CxyhQHy5.js} +1 -1
- package/dist/ui/assets/{capability-Btlr4Wc-.js → capability-Bxl0SE1s.js} +2 -2
- package/dist/ui/assets/{cdp-DHIp_AO9.js → cdp-CmXwwigc.js} +1 -1
- package/dist/ui/assets/{cerebras-4vCJGBUt.js → cerebras-CsdnfQnc.js} +1 -1
- package/dist/ui/assets/{cerebras-CBjabVSb.js → cerebras-Mux-1Uqj.js} +1 -1
- package/dist/ui/assets/{client-CjV_9a9h.js → client-C6Cmi9c4.js} +1 -1
- package/dist/ui/assets/composer-speech-CElQJ4q_.js +1 -0
- package/dist/ui/assets/{connect-surface-DrBGja7c.js → connect-surface-DgrjdeR5.js} +1 -1
- package/dist/ui/assets/{context-compaction-huebTevb.js → context-compaction-DRymamfD.js} +3 -3
- package/dist/ui/assets/{core-CdPvxBo3.js → core-B8y1Kyh_.js} +2 -2
- package/dist/ui/assets/{derive-C_gfjwp6.js → derive-TWFNEJkb.js} +1 -1
- package/dist/ui/assets/dip-1TiuHkUR.js +233 -0
- package/dist/ui/assets/{directed-approval-cJrhWrrr.js → directed-approval-BDO2wdC5.js} +1 -1
- package/dist/ui/assets/{discovery-preference-DFkmIHQo.js → discovery-preference-B9KlkVuR.js} +1 -1
- package/dist/ui/assets/ensure-speech-assets-DasC7jBA.js +1 -0
- package/dist/ui/assets/{esbuild-wasm-CSKOA492.js → esbuild-wasm-Ew76Vf_V.js} +2 -2
- package/dist/ui/assets/export-provider-CqI0pk50.js +1 -0
- package/dist/ui/assets/export-spool-CuNzzI8a.js +1 -0
- package/dist/ui/assets/{extension-bridge-transport-D3PItLFo.js → extension-bridge-transport-DfRNjx8c.js} +1 -1
- package/dist/ui/assets/extension-media-capture-2FcAdcuB.js +1 -0
- package/dist/ui/assets/extension-ops-owOXVncP.js +1 -0
- package/dist/ui/assets/float-topology-hfgMx1Yq.js +1 -0
- package/dist/ui/assets/{follower-navigate-watcher-B9ZostUJ.js → follower-navigate-watcher-JQ0b_cW8.js} +1 -1
- package/dist/ui/assets/{fs-C9SJY4sJ.js → fs-CBaQR8Xc.js} +2 -2
- package/dist/ui/assets/{fs-n6R6QZv0.js → fs-CDaCMxrL.js} +1 -1
- package/dist/ui/assets/github-B7uOq9Q1.js +1 -0
- package/dist/ui/assets/{github-copilot-COZvaCzG.js → github-copilot-BeWJoZwD.js} +1 -1
- package/dist/ui/assets/{github-copilot-Cai-dPyZ.js → github-copilot-DwKSI23j.js} +1 -1
- package/dist/ui/assets/{github-install-DfhMDFC9.js → github-install-DE7dF6r8.js} +1 -1
- package/dist/ui/assets/{github-D-fdkiMQ.js → github-qhOhjD2Q.js} +2 -2
- package/dist/ui/assets/{github-zip-ZEV5pLGZ.js → github-zip-CuwUOO-U.js} +1 -1
- package/dist/ui/assets/{guest-tool-gate-CG9Yw8Kq.js → guest-tool-gate-BxRAm4CU.js} +1 -1
- package/dist/ui/assets/{hear-D7MO-jTh.js → hear-CNQSuR1y.js} +1 -1
- package/dist/ui/assets/{help-CQHZfeL3.js → help-D66VHlYj.js} +8 -4
- package/dist/ui/assets/hid-picker-sFJ8vzUj.js +1 -0
- package/dist/ui/assets/host-command-29ain4NA.js +1 -0
- package/dist/ui/assets/idle-compaction-B9i1duyd.js +1 -0
- package/dist/ui/assets/idle-compaction-settings-1yyApSsQ.js +1 -0
- package/dist/ui/assets/image-markers-BFDmhPy4.js +1 -0
- package/dist/ui/assets/image-markers-DuyWsic3.js +1 -0
- package/dist/ui/assets/{installer-7BWtTgd6.js → installer-C6TqZaGO.js} +3 -3
- package/dist/ui/assets/{js-realm-worker-CXI-Ngjy.js → js-realm-worker-Bsb6rmK5.js} +4 -4
- package/dist/ui/assets/{jsh-runtime-extensions-Bf9eAUzp.js → jsh-runtime-extensions-Dkujbplu.js} +1 -1
- package/dist/ui/assets/kernel-worker-CkZd8Enf.js +4991 -0
- package/dist/ui/assets/lick-manager-ULemXDKa.js +2 -0
- package/dist/ui/assets/lick-urls-BX4Jyu_T.js +1 -0
- package/dist/ui/assets/{lick-ws-bridge-Jk_oJNDM.js → lick-ws-bridge-Bo5sH7lf.js} +1 -1
- package/dist/ui/assets/{lick-ws-bridge-ct0HLNad.js → lick-ws-bridge-RFOSPq0w.js} +1 -1
- package/dist/ui/assets/{live-session-snapshot-DnNBHXrk.js → live-session-snapshot-BTnyrQCU.js} +1 -1
- package/dist/ui/assets/{loader-B90Xxi7L.js → loader-Dw-TPPKt.js} +1 -1
- package/dist/ui/assets/{local-llm-Dm5mp8ES.js → local-llm-B-qS5oNT.js} +1 -1
- package/dist/ui/assets/{local-llm-CXD-Qof4.js → local-llm-COCS88AU.js} +1 -1
- package/dist/ui/assets/{magick-wasm-BEYfJbAX.js → magick-wasm-C7OGcZrJ.js} +2 -2
- package/dist/ui/assets/main-CAXbdHY8.js +22 -0
- package/dist/ui/assets/main-cherry-DSNvH0CD.js +1 -0
- package/dist/ui/assets/{mount-DD8rKTRS.js → mount-BbUBqN71.js} +2 -2
- package/dist/ui/assets/{mount-bridge-client-CUPodVo6.js → mount-bridge-client-BejrWSrL.js} +1 -1
- package/dist/ui/assets/{mount-bridge-client-BrMqFu_x.js → mount-bridge-client-DGJyqEPG.js} +1 -1
- package/dist/ui/assets/{mount-picker-popup-CVvcLs1V.js → mount-picker-popup--ijSfN8u.js} +1 -1
- package/dist/ui/assets/{mount-recovery-D6g3iniZ.js → mount-recovery-OxgGejDC.js} +1 -1
- package/dist/ui/assets/{mount-C1nMn8bL.js → mount-ysOnJBjr.js} +3 -3
- package/dist/ui/assets/navigation-watcher-C8xRyQBd.js +1 -0
- package/dist/ui/assets/new-session-JIL4tJ1I.js +2 -0
- package/dist/ui/assets/oauth-bootstrap-DP5y5Dy8.js +2 -0
- package/dist/ui/assets/oauth-service-Bconf2Pz.js +1 -0
- package/dist/ui/assets/oauth-service-t2taQm3p.js +1 -0
- package/dist/ui/assets/{openai-codex-BveJezys.js → openai-codex-BZDYkVh6.js} +1 -1
- package/dist/ui/assets/{openai-codex-WPOtL2Mf.js → openai-codex-DlFMWNVB.js} +1 -1
- package/dist/ui/assets/{openrouter-98Q9mrw8.js → openrouter-BrS9XpJS.js} +1 -1
- package/dist/ui/assets/{openrouter-6nEYTdxI.js → openrouter-Dn_iX45f.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-C7w8rKLa.js → openrouter-oauth-CioQlp0x.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-BCNSNHpM.js → openrouter-oauth-D9gZVt7e.js} +1 -1
- package/dist/ui/assets/{page-approval-service-DnWfuBVQ.js → page-approval-service-IZdlRu-_.js} +1 -1
- package/dist/ui/assets/panel-rpc-handlers-DUN0E_f8.js +2 -0
- package/dist/ui/assets/{panelize-shell-C7Ptpa69.js → panelize-shell-KNX1XTnq.js} +1 -1
- package/dist/ui/assets/picker-popup-sQtXmfAo.js +1 -0
- package/dist/ui/assets/{port-bridge-client-wFmUGeZa.js → port-bridge-client-C1tBBqwu.js} +1 -1
- package/dist/ui/assets/{port-bridge-client-BTnhFM03.js → port-bridge-client-CN1cFP4D.js} +1 -1
- package/dist/ui/assets/preview-url-r19H6zH1.js +1 -0
- package/dist/ui/assets/{provider-1nSAXh4b.js → provider-BfGyOQHs.js} +2 -2
- package/dist/ui/assets/{provider-RrpO6cEr.js → provider-DnIZJQjl.js} +1 -1
- package/dist/ui/assets/provider-settings-C6uIHjd4.js +1 -0
- package/dist/ui/assets/provider-settings-DrWv51sQ.js +2 -0
- package/dist/ui/assets/{provider-store-access-kKnmyJjr.js → provider-store-access-BqErJhmB.js} +2 -2
- package/dist/ui/assets/provider-store-access-BuQzycZu.js +1 -0
- package/dist/ui/assets/{providers-CvD7PECK.js → providers-CF2FF0H2.js} +1 -1
- package/dist/ui/assets/providers-CqZKx9qW.js +2 -0
- package/dist/ui/assets/proxied-fetch-CiijUcSt.js +2 -0
- package/dist/ui/assets/proxied-fetch-DUC7X0GS.js +1 -0
- package/dist/ui/assets/{py-realm-worker-DGFMfg27.js → py-realm-worker-BYQkpReo.js} +2 -2
- package/dist/ui/assets/{pyodide-BDRAQKP6.js → pyodide-BwD0AtZB.js} +2 -2
- package/dist/ui/assets/{quick-llm-I3oLGgvo.js → quick-llm-B9NubAhJ.js} +1 -1
- package/dist/ui/assets/{recovery-screen-CBwlz3Qo.js → recovery-screen-cHPORxsj.js} +1 -1
- package/dist/ui/assets/{redirect-uri-DZXyVwvI.js → redirect-uri-BKkf61lT.js} +1 -1
- package/dist/ui/assets/{remote-terminal-view-Db-9V2n9.js → remote-terminal-view-BHs39pzZ.js} +1 -1
- package/dist/ui/assets/request-body-DWn6QJ_H.js +1 -0
- package/dist/ui/assets/rest-ops-CLpS_ilI.js +1 -0
- package/dist/ui/assets/rest-ops-D2ig8qfG.js +1 -0
- package/dist/ui/assets/{run-BBAgk3Ml.js → run-03JeZZol.js} +1 -1
- package/dist/ui/assets/{run-COi81T_1.js → run-B5YOTTPD.js} +1 -1
- package/dist/ui/assets/run-BOu4zIOZ.js +29 -0
- package/dist/ui/assets/{run-DZMSwK6o.js → run-CUXVFhoI.js} +1 -1
- package/dist/ui/assets/run-D5Va_gO8.js +81 -0
- package/dist/ui/assets/{run-DCeEfqcT.js → run-DZh-18uA.js} +3 -3
- package/dist/ui/assets/{secret-env-Cp2Eduxg.js → secret-env-CtpVPUh5.js} +1 -1
- package/dist/ui/assets/secret-topology-Yt0aO4Gz.js +1 -0
- package/dist/ui/assets/{secrets-bridge-client-CHMeCH4_.js → secrets-bridge-client-BVl0YuB2.js} +1 -1
- package/dist/ui/assets/{secrets-bridge-client-CNOtgwnq.js → secrets-bridge-client-C3MaYf_O.js} +1 -1
- package/dist/ui/assets/serial-picker-BQF_Eitc.js +1 -0
- package/dist/ui/assets/{session-freezer-DVh0_BPO.js → session-freezer-Bltt6zUt.js} +3 -3
- package/dist/ui/assets/{setup-feature-flags-remote-DBcwYFl-.js → setup-feature-flags-remote-BkP-HRZt.js} +1 -1
- package/dist/ui/assets/setup-standalone-prelude-C2tPUGcI.js +2 -0
- package/dist/ui/assets/setup-sudo-BSw__xoN.js +2 -0
- package/dist/ui/assets/shared-Djytys1b.js +1 -0
- package/dist/ui/assets/shared-Dq_aaG_m.js +4 -0
- package/dist/ui/assets/silent-renew-backoff-DIMz5UqB.js +1 -0
- package/dist/ui/assets/silent-renew-backoff-SSzHR-oP.js +1 -0
- package/dist/ui/assets/{skills-BEEjU5I5.js → skills-wzno5Tj5.js} +1 -1
- package/dist/ui/assets/slicc-app-url-B9OxaBDe.js +1 -0
- package/dist/ui/assets/slicc-version-HwuyIZfW.js +1 -0
- package/dist/ui/assets/{snapshot-CPjJBR4Z.js → snapshot-Bi6QabWh.js} +1 -1
- package/dist/ui/assets/{snapshot-features-BZbgnon7.js → snapshot-features-BEPdcWF6.js} +3 -3
- package/dist/ui/assets/{speak-Dx2FEQBZ.js → speak-BxNdNjKi.js} +1 -1
- package/dist/ui/assets/{sprinkle-bridge-BVfyHi8X.js → sprinkle-bridge-BNzhEsPj.js} +1 -1
- package/dist/ui/assets/{sprinkle-manager-Dxc8U2h1.js → sprinkle-manager-CflRWcbq.js} +1 -1
- package/dist/ui/assets/{sprinkle-renderer-1C1DNVyK.js → sprinkle-renderer-BnSqYzuY.js} +1 -1
- package/dist/ui/assets/{src-kInvzkEg.js → src-Bex_z_yH.js} +583 -148
- package/dist/ui/assets/state-DIwkpIaB.js +42 -0
- package/dist/ui/assets/{store-BHLq6CyB.js → store-CFx1fIZL.js} +1 -1
- package/dist/ui/assets/{store-Dd0aJqlJ.js → store-i7XHN1Er.js} +1 -1
- package/dist/ui/assets/{sudo-DBeYNsAF.js → sudo-r7OrTMGT.js} +1 -1
- package/dist/ui/assets/sync-dialog-D7Wg49Up.js +1 -0
- package/dist/ui/assets/tab-teleport-PAaKnGkm.js +1 -0
- package/dist/ui/assets/transcript-export-DP-r8eDz.js +1 -0
- package/dist/ui/assets/transformers-env-BmBEKck6.js +1 -0
- package/dist/ui/assets/{tray-leader-DTpZEm3l.js → tray-leader-DabyaEs-.js} +1 -1
- package/dist/ui/assets/{tray-leave-runtime-BrGJs1g5.js → tray-leave-runtime-VfTj-MHR.js} +1 -1
- package/dist/ui/assets/tray-runtime-config-BQL-GPqt.js +1 -0
- package/dist/ui/assets/tray-runtime-config-C3Ti4Pik.js +1 -0
- package/dist/ui/assets/tray-sidecar-Zx9F34-1.js +2 -0
- package/dist/ui/assets/tray-sync-protocol-jKTx-dCF.js +1 -0
- package/dist/ui/assets/tray-webrtc-uW6sTyIA.js +1 -0
- package/dist/ui/assets/{upgrade-detection-BwiYpjuO.js → upgrade-detection-Cz0eOMYf.js} +1 -1
- package/dist/ui/assets/usb-picker-Cbm0jfjl.js +1 -0
- package/dist/ui/assets/{voice-reply-BGR2cNZ_.js → voice-reply-B43Nr1Xr.js} +1 -1
- package/dist/ui/assets/{wc-attach-BLZapYO1.js → wc-attach-BbT2famN.js} +3 -3
- package/dist/ui/assets/wc-browser-Ctsf5Y23.js +1 -0
- package/dist/ui/assets/{wc-extension-B_OX4AT5.js → wc-extension-CJ6cvLnw.js} +2 -2
- package/dist/ui/assets/{wc-float-label-Ck2cAgp3.js → wc-float-label-CnFnKVLC.js} +1 -1
- package/dist/ui/assets/wc-follower-CkrdiOKN.js +17 -0
- package/dist/ui/assets/wc-follower-oauth-B6m2XpVI.js +5 -0
- package/dist/ui/assets/wc-live-CxoqWHpR.js +8 -0
- package/dist/ui/assets/wc-nav-Bnd_bEYw.js +2 -0
- package/dist/ui/assets/wc-onboarding-FeHr2fj5.js +2 -0
- package/dist/ui/assets/{wc-permissions-iZXqGvtf.js → wc-permissions-CppSymRx.js} +3 -3
- package/dist/ui/assets/wc-permissions-providers-BjqCnuQT.js +2 -0
- package/dist/ui/assets/wc-placeholder-C79lmtig.js +4 -0
- package/dist/ui/assets/wc-settings-DdAeaZhQ.js +59 -0
- package/dist/ui/assets/wc-shell-BP3biEU1.js +125 -0
- package/dist/ui/assets/{wc-shortcut-config--IseG9bJ.js → wc-shortcut-config-CjOJXjsp.js} +2 -2
- package/dist/ui/assets/wc-shortcuts-BDQiHczD.js +41 -0
- package/dist/ui/assets/wc-sprinkles-ChlcnDD2.js +2 -0
- package/dist/ui/assets/wc-transcript-export-DdEuCfi6.js +2 -0
- package/dist/ui/assets/wc-tray-BfoqEbBg.js +5 -0
- package/dist/ui/assets/whisper-session-DW7HkDu2.js +2 -0
- package/dist/ui/assets/{xai-grok-OLNPEXTT.js → xai-grok-3L0LL1R8.js} +1 -1
- package/dist/ui/assets/{xai-grok-C-iHnNxi.js → xai-grok-CKevFY8L.js} +1 -1
- package/dist/ui/index.html +15 -17
- package/dist/ui/llm-proxy-sw.js +1 -1
- package/dist/ui/packages/webapp/index.html +15 -17
- package/package.json +5 -4
- package/dist/ui/assets/CLAUDE-DhkULx_E.js +0 -1
- package/dist/ui/assets/SKILL-DJAvKejL.js +0 -1
- package/dist/ui/assets/__vite-browser-external-B19j3y2v.js +0 -1
- package/dist/ui/assets/account-store-CCqSr710.js +0 -1
- package/dist/ui/assets/api-endpoint-BB41u1PK.js +0 -1
- package/dist/ui/assets/api-endpoint-DRYP1Kfj.js +0 -1
- package/dist/ui/assets/composer-speech-C8OcijP-.js +0 -1
- package/dist/ui/assets/dip-Co-Ga2Ny.js +0 -233
- package/dist/ui/assets/ensure-speech-assets-Csum3_gw.js +0 -1
- package/dist/ui/assets/export-provider-BunpOA08.js +0 -1
- package/dist/ui/assets/export-spool-Bvpvkbul.js +0 -1
- package/dist/ui/assets/extension-media-capture-DiCJSgES.js +0 -1
- package/dist/ui/assets/extension-ops-CsNT8YjX.js +0 -1
- package/dist/ui/assets/float-topology-ey0oewfq.js +0 -1
- package/dist/ui/assets/github-BXAKydA_.js +0 -1
- package/dist/ui/assets/handoff-link-CGs8AaQW.js +0 -1
- package/dist/ui/assets/hid-picker-C4WMZ0dN.js +0 -1
- package/dist/ui/assets/host-command-PnmJLRej.js +0 -1
- package/dist/ui/assets/idle-compaction-CACtwRU_.js +0 -1
- package/dist/ui/assets/idle-compaction-settings-wK6JTbJh.js +0 -1
- package/dist/ui/assets/image-markers-DXh8szCT.js +0 -1
- package/dist/ui/assets/image-markers-Gur55AOh.js +0 -1
- package/dist/ui/assets/kernel-worker-Da1sBAJS.js +0 -4940
- package/dist/ui/assets/lick-manager-DtpJc-rA.js +0 -2
- package/dist/ui/assets/lick-urls-f41PW9LN.js +0 -1
- package/dist/ui/assets/main-BwL0siqZ.js +0 -22
- package/dist/ui/assets/main-cherry-D1l6FfCM.js +0 -1
- package/dist/ui/assets/navigation-watcher-C3S1JDXr.js +0 -1
- package/dist/ui/assets/new-session-DyvxhZfj.js +0 -2
- package/dist/ui/assets/oauth-bootstrap-KB9SK_o_.js +0 -2
- package/dist/ui/assets/oauth-service-CT-Lvflt.js +0 -1
- package/dist/ui/assets/oauth-service-nBlvta_T.js +0 -1
- package/dist/ui/assets/panel-rpc-handlers-BPA7Umeo.js +0 -2
- package/dist/ui/assets/picker-popup-BjCTzsQH.js +0 -1
- package/dist/ui/assets/picker-popup-CFr7T4TJ.js +0 -1
- package/dist/ui/assets/preview-url-BvtKejEp.js +0 -1
- package/dist/ui/assets/provider-settings-CHQp2onM.js +0 -1
- package/dist/ui/assets/provider-settings-Dp2FBrlU.js +0 -2
- package/dist/ui/assets/provider-store-access-8IJH8x4u.js +0 -1
- package/dist/ui/assets/providers-DuO7vxZy.js +0 -2
- package/dist/ui/assets/proxied-fetch-B0SF_J0b.js +0 -1
- package/dist/ui/assets/proxied-fetch-CNztWUVW.js +0 -2
- package/dist/ui/assets/remote-cdp-transport-BZuQZZe1.js +0 -1
- package/dist/ui/assets/request-body-CsruB58l.js +0 -1
- package/dist/ui/assets/rest-ops-31ZkM4IG.js +0 -1
- package/dist/ui/assets/rest-ops-D6OyHX5S.js +0 -1
- package/dist/ui/assets/run-b1PI_1dP.js +0 -81
- package/dist/ui/assets/runtime-env-BFnohVwN.js +0 -1
- package/dist/ui/assets/runtime-env-Dc36nUmg.js +0 -1
- package/dist/ui/assets/runtime-env-NCI8LQob.js +0 -1
- package/dist/ui/assets/runtime-env-a_l4ilH_.js +0 -1
- package/dist/ui/assets/secret-topology-B8MYKYm6.js +0 -1
- package/dist/ui/assets/serial-picker-fzg2DxKj.js +0 -1
- package/dist/ui/assets/setup-standalone-prelude-C2jWAIl4.js +0 -2
- package/dist/ui/assets/setup-sudo-BK3Rz-OI.js +0 -2
- package/dist/ui/assets/shared-BpOmrBY4.js +0 -1
- package/dist/ui/assets/shared-CTdWt5ZU.js +0 -4
- package/dist/ui/assets/silent-renew-backoff-B8p8Ja1t.js +0 -1
- package/dist/ui/assets/silent-renew-backoff-BjF-rXLR.js +0 -1
- package/dist/ui/assets/slicc-app-url-DnN_aesz.js +0 -1
- package/dist/ui/assets/slicc-version-CUqwa07v.js +0 -1
- package/dist/ui/assets/src-DXa5EsFV.js +0 -1
- package/dist/ui/assets/src-XLzS9HFL.js +0 -1
- package/dist/ui/assets/state-C7WiY9TK.js +0 -42
- package/dist/ui/assets/sync-dialog-BZ2j4xTg.js +0 -1
- package/dist/ui/assets/tab-teleport-D1Xeuund.js +0 -1
- package/dist/ui/assets/transformers-env-DnkszgHP.js +0 -1
- package/dist/ui/assets/tray-runtime-config-D9gR_d0I.js +0 -1
- package/dist/ui/assets/tray-runtime-config-DCaFjGSS.js +0 -1
- package/dist/ui/assets/tray-sidecar-CWqVyj-w.js +0 -2
- package/dist/ui/assets/tray-sync-protocol-BNw4_0UD.js +0 -1
- package/dist/ui/assets/tray-sync-protocol-BZ5yhJH9.js +0 -1
- package/dist/ui/assets/tray-webrtc-De2SkVvZ.js +0 -1
- package/dist/ui/assets/usb-picker-B8B4LJT7.js +0 -1
- package/dist/ui/assets/wc-browser-AyZY1PPl.js +0 -1
- package/dist/ui/assets/wc-follower-CYLEd4rs.js +0 -17
- package/dist/ui/assets/wc-follower-oauth-CTgC7D7W.js +0 -5
- package/dist/ui/assets/wc-live-s5MA_zAo.js +0 -8
- package/dist/ui/assets/wc-nav-DHUiLdz3.js +0 -2
- package/dist/ui/assets/wc-onboarding-CX3HBRTZ.js +0 -2
- package/dist/ui/assets/wc-permissions-providers-BzoJwkWd.js +0 -2
- package/dist/ui/assets/wc-placeholder-BPLzZhYP.js +0 -4
- package/dist/ui/assets/wc-settings-tszLzSGm.js +0 -59
- package/dist/ui/assets/wc-shell-BBDMmI8N.js +0 -122
- package/dist/ui/assets/wc-shortcuts-BWBA9QlD.js +0 -11
- package/dist/ui/assets/wc-sprinkles-Cx9Zvx6r.js +0 -2
- package/dist/ui/assets/wc-transcript-export-B6x5VMbH.js +0 -2
- package/dist/ui/assets/wc-tray-DEV2i60z.js +0 -5
- package/dist/ui/assets/whisper-session-i96-W77q.js +0 -2
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* proxy-headers — pure helpers for the `/api/fetch-proxy` forbidden-header
|
|
3
|
+
* transport.
|
|
4
|
+
*
|
|
5
|
+
* The browser silently strips a small set of "forbidden" request headers
|
|
6
|
+
* (Cookie, Origin, Referer, Proxy-*) when calling `fetch()` from page code.
|
|
7
|
+
* The proxy server restores them by reading `X-Proxy-*` headers we send in
|
|
8
|
+
* their place. Likewise, `Set-Cookie` is stripped from response headers,
|
|
9
|
+
* so the proxy bundles all `Set-Cookie` values into a JSON-encoded
|
|
10
|
+
* `X-Proxy-Set-Cookie` header that the browser can read.
|
|
11
|
+
*
|
|
12
|
+
* Extracted from `proxied-fetch.ts` so the LLM-proxy service worker can
|
|
13
|
+
* reuse them — the SW build is a standalone IIFE bundle and can't import
|
|
14
|
+
* the shell-side `proxied-fetch` module which pulls in a much larger graph.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Encode request headers that browsers silently strip (forbidden headers).
|
|
18
|
+
* Cookie → X-Proxy-Cookie, Origin → X-Proxy-Origin, Referer → X-Proxy-Referer, Proxy-* → X-Proxy-Proxy-*
|
|
19
|
+
*/
|
|
20
|
+
export function encodeForbiddenRequestHeaders(headers) {
|
|
21
|
+
if (!headers)
|
|
22
|
+
return {};
|
|
23
|
+
const result = {};
|
|
24
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
25
|
+
const lower = key.toLowerCase();
|
|
26
|
+
if (lower === 'cookie') {
|
|
27
|
+
result['X-Proxy-Cookie'] = value;
|
|
28
|
+
}
|
|
29
|
+
else if (lower === 'origin') {
|
|
30
|
+
result['X-Proxy-Origin'] = value;
|
|
31
|
+
}
|
|
32
|
+
else if (lower === 'referer') {
|
|
33
|
+
result['X-Proxy-Referer'] = value;
|
|
34
|
+
}
|
|
35
|
+
else if (lower.startsWith('proxy-')) {
|
|
36
|
+
result[`X-Proxy-${key}`] = value;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
result[key] = value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Decode request headers from the X-Proxy-* transport back to their real names.
|
|
46
|
+
* X-Proxy-Cookie → cookie, X-Proxy-Origin → origin, X-Proxy-Referer → referer,
|
|
47
|
+
* X-Proxy-Proxy-* → proxy-*. Inverse of `encodeForbiddenRequestHeaders` —
|
|
48
|
+
* used by the proxy server side (CLI Express handler, extension SW) before
|
|
49
|
+
* calling upstream `fetch()`. Match is case-insensitive on the `X-Proxy-`
|
|
50
|
+
* prefix; the decoded key is always lowercase.
|
|
51
|
+
*/
|
|
52
|
+
export function decodeForbiddenRequestHeaders(headers) {
|
|
53
|
+
const result = {};
|
|
54
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
55
|
+
const lower = key.toLowerCase();
|
|
56
|
+
if (lower === 'x-proxy-cookie') {
|
|
57
|
+
result['cookie'] = value;
|
|
58
|
+
}
|
|
59
|
+
else if (lower === 'x-proxy-origin') {
|
|
60
|
+
result['origin'] = value;
|
|
61
|
+
}
|
|
62
|
+
else if (lower === 'x-proxy-referer') {
|
|
63
|
+
result['referer'] = value;
|
|
64
|
+
}
|
|
65
|
+
else if (lower.startsWith('x-proxy-proxy-')) {
|
|
66
|
+
result[lower.replace(/^x-proxy-/, '')] = value;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
result[key] = value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Decode response headers that the proxy transported under non-forbidden names.
|
|
76
|
+
* X-Proxy-Set-Cookie (JSON array) → set-cookie (JSON array string)
|
|
77
|
+
*/
|
|
78
|
+
export function decodeForbiddenResponseHeaders(headers) {
|
|
79
|
+
const result = {};
|
|
80
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
81
|
+
const lower = key.toLowerCase();
|
|
82
|
+
if (lower === 'x-proxy-set-cookie') {
|
|
83
|
+
// Value is a JSON array of Set-Cookie strings from the proxy.
|
|
84
|
+
// Keep as JSON array string since Record<string,string> can only hold one value.
|
|
85
|
+
result['set-cookie'] = value;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
result[key] = value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/** Convert Headers or Record<string, string> to a plain Record<string, string>. */
|
|
94
|
+
export function headersToRecord(headers) {
|
|
95
|
+
if (!headers)
|
|
96
|
+
return undefined;
|
|
97
|
+
if (headers instanceof Headers) {
|
|
98
|
+
const rec = {};
|
|
99
|
+
headers.forEach((v, k) => {
|
|
100
|
+
rec[k] = v;
|
|
101
|
+
});
|
|
102
|
+
return rec;
|
|
103
|
+
}
|
|
104
|
+
return headers;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Coerce any `HeadersInit` shape (Headers / record / [k,v][] array) to a
|
|
108
|
+
* plain record so it can ride on `SecureFetchOptions.headers`. Returns
|
|
109
|
+
* `undefined` when no headers are present (or the result would be empty)
|
|
110
|
+
* so callers can omit the field entirely — preserving the "no empty
|
|
111
|
+
* object leak" contract verified by the `asWebFetch` Origin-propagation
|
|
112
|
+
* tests.
|
|
113
|
+
*/
|
|
114
|
+
export function normalizeHeadersInit(headers) {
|
|
115
|
+
if (!headers)
|
|
116
|
+
return undefined;
|
|
117
|
+
if (headers instanceof Headers) {
|
|
118
|
+
const rec = {};
|
|
119
|
+
headers.forEach((v, k) => {
|
|
120
|
+
rec[k] = v;
|
|
121
|
+
});
|
|
122
|
+
return Object.keys(rec).length === 0 ? undefined : rec;
|
|
123
|
+
}
|
|
124
|
+
if (Array.isArray(headers)) {
|
|
125
|
+
const rec = {};
|
|
126
|
+
for (const [k, v] of headers)
|
|
127
|
+
rec[k] = v;
|
|
128
|
+
return Object.keys(rec).length === 0 ? undefined : rec;
|
|
129
|
+
}
|
|
130
|
+
const rec = { ...headers };
|
|
131
|
+
return Object.keys(rec).length === 0 ? undefined : rec;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=proxy-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-headers.js","sourceRoot":"","sources":["../src/proxy-headers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Well-known probe for Agentic Resource Discovery (ARD) artifacts.
|
|
3
|
+
*
|
|
4
|
+
* When a response carries no `ai-catalog` `Link` header (see
|
|
5
|
+
* `discovery-link.ts`), an origin can still publish discovery artifacts at
|
|
6
|
+
* their standardized well-known locations:
|
|
7
|
+
*
|
|
8
|
+
* - `/.well-known/ai-catalog.json` — the ARD capability manifest
|
|
9
|
+
* - `/llms.txt` — the llmstxt.org digest for LLMs
|
|
10
|
+
*
|
|
11
|
+
* `probeWellKnown` issues a bounded GET to each location and returns the ones
|
|
12
|
+
* that answer `200` with a plausible content-type. It is pure core: the fetch
|
|
13
|
+
* implementation is injected and every network failure / timeout is caught and
|
|
14
|
+
* treated as "no match" (never thrown). No float wiring lives here.
|
|
15
|
+
*
|
|
16
|
+
* Probes are credential-free (`credentials: 'omit'`) and never follow
|
|
17
|
+
* redirects (`redirect: 'manual'`): the extension float runs them through the
|
|
18
|
+
* SW's `host_permissions`-privileged fetch while the user's tab may be in the
|
|
19
|
+
* middle of an SSO login on the very same origin — a credentialed probe that
|
|
20
|
+
* chases the auth-bounce chain poisons the IdP's pending return-URL state and
|
|
21
|
+
* hijacks the tab to `<origin>/llms.txt` (see probeOne).
|
|
22
|
+
*
|
|
23
|
+
* Content-type is lenient by design — a missing header is accepted (some static
|
|
24
|
+
* hosts omit it), but an HTML response is always rejected: a manifest / digest
|
|
25
|
+
* served as HTML is a misconfiguration, not the artifact.
|
|
26
|
+
*/
|
|
27
|
+
import type { DiscoveryKind } from './agent-wire-types.js';
|
|
28
|
+
/** Structural subset of a `fetch` Response the probe needs (no DOM lib dep). */
|
|
29
|
+
export interface ProbeResponse {
|
|
30
|
+
ok: boolean;
|
|
31
|
+
status: number;
|
|
32
|
+
headers: {
|
|
33
|
+
get(name: string): string | null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Injected fetch. Compatible with the global `fetch`. */
|
|
37
|
+
export type ProbeFetch = (url: string, init?: {
|
|
38
|
+
method?: string;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
redirect?: string;
|
|
41
|
+
credentials?: string;
|
|
42
|
+
}) => Promise<ProbeResponse>;
|
|
43
|
+
export interface DiscoveryProbeMatch {
|
|
44
|
+
kind: DiscoveryKind;
|
|
45
|
+
/** Absolute URL of the artifact that answered. */
|
|
46
|
+
url: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ProbeOptions {
|
|
49
|
+
/** Per-request timeout in milliseconds. Defaults to 3000. */
|
|
50
|
+
timeoutMs?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Probe an origin's well-known discovery locations. Returns one match per
|
|
54
|
+
* artifact that answered `200` with a plausible content-type. Both probes run
|
|
55
|
+
* concurrently; a failure of one never affects the other.
|
|
56
|
+
*/
|
|
57
|
+
export declare function probeWellKnown(origin: string, fetchImpl: ProbeFetch, options?: ProbeOptions): Promise<DiscoveryProbeMatch[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Decide whether a response content-type is plausible for the given artifact.
|
|
60
|
+
* HTML is always rejected; a missing/empty header is accepted (lenient).
|
|
61
|
+
*/
|
|
62
|
+
export declare function contentTypeOk(raw: string | null, kind: DiscoveryKind): boolean;
|
|
63
|
+
//# sourceMappingURL=well-known-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known-probe.d.ts","sourceRoot":"","sources":["../src/well-known-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAED,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,KACtF,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAahC;AAyCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAU9E"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Well-known probe for Agentic Resource Discovery (ARD) artifacts.
|
|
3
|
+
*
|
|
4
|
+
* When a response carries no `ai-catalog` `Link` header (see
|
|
5
|
+
* `discovery-link.ts`), an origin can still publish discovery artifacts at
|
|
6
|
+
* their standardized well-known locations:
|
|
7
|
+
*
|
|
8
|
+
* - `/.well-known/ai-catalog.json` — the ARD capability manifest
|
|
9
|
+
* - `/llms.txt` — the llmstxt.org digest for LLMs
|
|
10
|
+
*
|
|
11
|
+
* `probeWellKnown` issues a bounded GET to each location and returns the ones
|
|
12
|
+
* that answer `200` with a plausible content-type. It is pure core: the fetch
|
|
13
|
+
* implementation is injected and every network failure / timeout is caught and
|
|
14
|
+
* treated as "no match" (never thrown). No float wiring lives here.
|
|
15
|
+
*
|
|
16
|
+
* Probes are credential-free (`credentials: 'omit'`) and never follow
|
|
17
|
+
* redirects (`redirect: 'manual'`): the extension float runs them through the
|
|
18
|
+
* SW's `host_permissions`-privileged fetch while the user's tab may be in the
|
|
19
|
+
* middle of an SSO login on the very same origin — a credentialed probe that
|
|
20
|
+
* chases the auth-bounce chain poisons the IdP's pending return-URL state and
|
|
21
|
+
* hijacks the tab to `<origin>/llms.txt` (see probeOne).
|
|
22
|
+
*
|
|
23
|
+
* Content-type is lenient by design — a missing header is accepted (some static
|
|
24
|
+
* hosts omit it), but an HTML response is always rejected: a manifest / digest
|
|
25
|
+
* served as HTML is a misconfiguration, not the artifact.
|
|
26
|
+
*/
|
|
27
|
+
const TARGETS = [
|
|
28
|
+
{ kind: 'ai-catalog', path: '/.well-known/ai-catalog.json' },
|
|
29
|
+
{ kind: 'llms-txt', path: '/llms.txt' },
|
|
30
|
+
];
|
|
31
|
+
const DEFAULT_TIMEOUT_MS = 3000;
|
|
32
|
+
/**
|
|
33
|
+
* Probe an origin's well-known discovery locations. Returns one match per
|
|
34
|
+
* artifact that answered `200` with a plausible content-type. Both probes run
|
|
35
|
+
* concurrently; a failure of one never affects the other.
|
|
36
|
+
*/
|
|
37
|
+
export async function probeWellKnown(origin, fetchImpl, options = {}) {
|
|
38
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
39
|
+
let base;
|
|
40
|
+
try {
|
|
41
|
+
base = new URL(origin).origin;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const settled = await Promise.all(TARGETS.map((target) => probeOne(base, target, fetchImpl, timeoutMs)));
|
|
47
|
+
return settled.filter((m) => m !== null);
|
|
48
|
+
}
|
|
49
|
+
async function probeOne(base, target, fetchImpl, timeoutMs) {
|
|
50
|
+
const url = base + target.path;
|
|
51
|
+
const ctrl = new AbortController();
|
|
52
|
+
const timer = setTimeout(() => ctrl.abort(new Error('timeout')), timeoutMs);
|
|
53
|
+
try {
|
|
54
|
+
// The probe fires while the user's tab may be mid-SSO on the same origin.
|
|
55
|
+
// It must be side-effect-free on auth state: `credentials: 'omit'` keeps
|
|
56
|
+
// profile cookies out of the request AND ignores Set-Cookie on the
|
|
57
|
+
// response, and `redirect: 'manual'` refuses to chase an auth-bounce
|
|
58
|
+
// chain. A credentialed, redirect-following probe joins the in-flight
|
|
59
|
+
// login and can overwrite the IdP's cookie-keyed return-URL slot — the
|
|
60
|
+
// user's tab then lands on `<origin>/llms.txt` after completing Okta/SSO.
|
|
61
|
+
// An artifact that doesn't answer 200 anonymously at its canonical
|
|
62
|
+
// location is not a published advertisement, so a redirect is "no match"
|
|
63
|
+
// (browser fetch surfaces it as an opaqueredirect, status 0).
|
|
64
|
+
const res = await fetchImpl(url, {
|
|
65
|
+
method: 'GET',
|
|
66
|
+
signal: ctrl.signal,
|
|
67
|
+
redirect: 'manual',
|
|
68
|
+
credentials: 'omit',
|
|
69
|
+
});
|
|
70
|
+
// Require an exact 200. `res.ok` also accepts 204 No Content / 206 Partial
|
|
71
|
+
// Content, which would surface a discovery lick for an empty / no-body
|
|
72
|
+
// artifact (especially when the server omits a content-type).
|
|
73
|
+
if (res.status !== 200)
|
|
74
|
+
return null;
|
|
75
|
+
if (!contentTypeOk(res.headers.get('content-type'), target.kind))
|
|
76
|
+
return null;
|
|
77
|
+
return { kind: target.kind, url };
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Decide whether a response content-type is plausible for the given artifact.
|
|
88
|
+
* HTML is always rejected; a missing/empty header is accepted (lenient).
|
|
89
|
+
*/
|
|
90
|
+
export function contentTypeOk(raw, kind) {
|
|
91
|
+
if (raw == null)
|
|
92
|
+
return true;
|
|
93
|
+
const ct = raw.toLowerCase();
|
|
94
|
+
if (ct.length === 0)
|
|
95
|
+
return true;
|
|
96
|
+
if (ct.includes('text/html') || ct.includes('application/xhtml'))
|
|
97
|
+
return false;
|
|
98
|
+
if (kind === 'ai-catalog') {
|
|
99
|
+
return ct.includes('json') || ct.includes('text/plain') || ct.includes('octet-stream');
|
|
100
|
+
}
|
|
101
|
+
// llms-txt
|
|
102
|
+
return ct.includes('text/plain') || ct.includes('markdown') || ct.includes('octet-stream');
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=well-known-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known-probe.js","sourceRoot":"","sources":["../src/well-known-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -72,6 +72,16 @@ interface RunningProcessInfo {
|
|
|
72
72
|
commandLine: string;
|
|
73
73
|
executablePath: string | null;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* One element of a CDP `Network.Request.postDataEntries` array. `bytes` is the
|
|
77
|
+
* protocol `binary` type — base64 in the JSON wire form, so it survives bodies
|
|
78
|
+
* that are not valid UTF-8. Entries backed by a file or blob (a `<input
|
|
79
|
+
* type=file>` part) carry NO `bytes`: Chrome does not expose those bytes over
|
|
80
|
+
* CDP at all.
|
|
81
|
+
*/
|
|
82
|
+
export interface CdpPostDataEntry {
|
|
83
|
+
bytes?: string;
|
|
84
|
+
}
|
|
75
85
|
export declare function findMatchingElectronAppPids(runningProcesses: RunningProcessInfo[], processMatchPatterns: string[], currentPid?: number): number[];
|
|
76
86
|
export declare class ElectronAppAlreadyRunningError extends Error {
|
|
77
87
|
constructor(message: string);
|
|
@@ -108,6 +118,47 @@ export declare function computeAverageLuminance(pixels: Buffer, width: number, h
|
|
|
108
118
|
* actually needs unblocking when the parent is a local file.
|
|
109
119
|
*/
|
|
110
120
|
export declare function resolveFetchProxyOrigin(targetUrl: string, servePort: number): string;
|
|
121
|
+
/**
|
|
122
|
+
* Outcome of reconstructing an intercepted request's POST body from the CDP
|
|
123
|
+
* `Fetch.requestPaused` payload.
|
|
124
|
+
*
|
|
125
|
+
* - `none` — the request has no body (a GET/HEAD navigation).
|
|
126
|
+
* - `bytes` — the exact body bytes, recovered losslessly.
|
|
127
|
+
* - `unrecoverable` — the request HAS a body but CDP did not hand us its bytes.
|
|
128
|
+
* The caller must fail the request; forwarding a guess would silently corrupt
|
|
129
|
+
* the origin's copy of the upload.
|
|
130
|
+
*/
|
|
131
|
+
export type CdpPostBody = {
|
|
132
|
+
kind: 'none';
|
|
133
|
+
} | {
|
|
134
|
+
kind: 'bytes';
|
|
135
|
+
bytes: Buffer;
|
|
136
|
+
} | {
|
|
137
|
+
kind: 'unrecoverable';
|
|
138
|
+
reason: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Recover the byte-exact POST body of an intercepted `Fetch.requestPaused`
|
|
142
|
+
* request. A document POST is a byte pipe: multipart boundaries wrapping a JPEG
|
|
143
|
+
* are not UTF-8, so `Buffer.from(request.postData)` (Node's implicit UTF-8) or
|
|
144
|
+
* `String.data(using: .utf8)` expands every byte ≥0x80 (`80` → `C2 80`) and the
|
|
145
|
+
* origin receives a corrupt body behind a successful fulfill (#2886).
|
|
146
|
+
*
|
|
147
|
+
* Order of trust:
|
|
148
|
+
* 1. `postDataEntries[].bytes` — base64 over the wire, so byte-exact for any
|
|
149
|
+
* body. This is the CDP-recommended source (`postData` is deprecated).
|
|
150
|
+
* 2. `postData` **only when it is pure ASCII** — then UTF-8, latin1 and the raw
|
|
151
|
+
* bytes all coincide, so the string cannot be lossy. Covers the ordinary
|
|
152
|
+
* `application/x-www-form-urlencoded` form post, which percent-encodes.
|
|
153
|
+
* 3. Anything else (a file/blob entry Chrome never exposes, `hasPostData` with
|
|
154
|
+
* the body dropped for length, or a non-ASCII `postData` string with no
|
|
155
|
+
* entries) is unrecoverable. We fail rather than substitute bytes.
|
|
156
|
+
*/
|
|
157
|
+
export declare function decodeCdpRequestPostBody(request: {
|
|
158
|
+
postData?: string;
|
|
159
|
+
hasPostData?: boolean;
|
|
160
|
+
postDataEntries?: CdpPostDataEntry[];
|
|
161
|
+
}): CdpPostBody;
|
|
111
162
|
/**
|
|
112
163
|
* Pre-built bootstrap scripts for thin-mode injection — one per overlay
|
|
113
164
|
* role. The injector picks `leader` for the first injected target and
|
|
@@ -442,6 +442,81 @@ export function resolveFetchProxyOrigin(targetUrl, servePort) {
|
|
|
442
442
|
}
|
|
443
443
|
return `http://localhost:${servePort}`;
|
|
444
444
|
}
|
|
445
|
+
/** True when every code unit of `value` is ASCII (0x00-0x7F). */
|
|
446
|
+
function isPureAscii(value) {
|
|
447
|
+
for (let i = 0; i < value.length; i++) {
|
|
448
|
+
if (value.charCodeAt(i) > 0x7f)
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Recover the byte-exact POST body of an intercepted `Fetch.requestPaused`
|
|
455
|
+
* request. A document POST is a byte pipe: multipart boundaries wrapping a JPEG
|
|
456
|
+
* are not UTF-8, so `Buffer.from(request.postData)` (Node's implicit UTF-8) or
|
|
457
|
+
* `String.data(using: .utf8)` expands every byte ≥0x80 (`80` → `C2 80`) and the
|
|
458
|
+
* origin receives a corrupt body behind a successful fulfill (#2886).
|
|
459
|
+
*
|
|
460
|
+
* Order of trust:
|
|
461
|
+
* 1. `postDataEntries[].bytes` — base64 over the wire, so byte-exact for any
|
|
462
|
+
* body. This is the CDP-recommended source (`postData` is deprecated).
|
|
463
|
+
* 2. `postData` **only when it is pure ASCII** — then UTF-8, latin1 and the raw
|
|
464
|
+
* bytes all coincide, so the string cannot be lossy. Covers the ordinary
|
|
465
|
+
* `application/x-www-form-urlencoded` form post, which percent-encodes.
|
|
466
|
+
* 3. Anything else (a file/blob entry Chrome never exposes, `hasPostData` with
|
|
467
|
+
* the body dropped for length, or a non-ASCII `postData` string with no
|
|
468
|
+
* entries) is unrecoverable. We fail rather than substitute bytes.
|
|
469
|
+
*/
|
|
470
|
+
export function decodeCdpRequestPostBody(request) {
|
|
471
|
+
const entries = request.postDataEntries;
|
|
472
|
+
if (entries && entries.length > 0) {
|
|
473
|
+
const chunks = [];
|
|
474
|
+
for (const entry of entries) {
|
|
475
|
+
if (typeof entry.bytes !== 'string') {
|
|
476
|
+
return {
|
|
477
|
+
kind: 'unrecoverable',
|
|
478
|
+
reason: 'postDataEntries contains a file/blob element with no bytes',
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
chunks.push(Buffer.from(entry.bytes, 'base64'));
|
|
482
|
+
}
|
|
483
|
+
return { kind: 'bytes', bytes: Buffer.concat(chunks) };
|
|
484
|
+
}
|
|
485
|
+
const postData = request.postData;
|
|
486
|
+
if (typeof postData === 'string' && postData.length > 0) {
|
|
487
|
+
if (isPureAscii(postData)) {
|
|
488
|
+
// ASCII: UTF-8, latin1 and the raw bytes all agree, so no codec can lose.
|
|
489
|
+
return { kind: 'bytes', bytes: Buffer.from(postData, 'latin1') };
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
kind: 'unrecoverable',
|
|
493
|
+
reason: 'postData is not pure ASCII and no postDataEntries were provided',
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
if (request.hasPostData) {
|
|
497
|
+
return { kind: 'unrecoverable', reason: 'hasPostData is set but CDP provided no body' };
|
|
498
|
+
}
|
|
499
|
+
return { kind: 'none' };
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Build the outgoing proxy request's headers from the intercepted ones: drop the
|
|
503
|
+
* browser's `content-length` and re-derive it from the body we are actually
|
|
504
|
+
* forwarding (`null` = no body). The intercepted value counts the ORIGINAL bytes,
|
|
505
|
+
* so any body-length drift — like the UTF-8 expansion this hop used to do —
|
|
506
|
+
* turned into a mismatched `Content-Length` the origin read the wrong way.
|
|
507
|
+
*/
|
|
508
|
+
function buildProxyRequestHeaders(requestHeaders, bodyLength) {
|
|
509
|
+
const headers = {};
|
|
510
|
+
for (const [name, value] of Object.entries(requestHeaders)) {
|
|
511
|
+
if (name.toLowerCase() === 'content-length')
|
|
512
|
+
continue;
|
|
513
|
+
headers[name] = value;
|
|
514
|
+
}
|
|
515
|
+
if (bodyLength !== null) {
|
|
516
|
+
headers['Content-Length'] = String(bodyLength);
|
|
517
|
+
}
|
|
518
|
+
return headers;
|
|
519
|
+
}
|
|
445
520
|
/**
|
|
446
521
|
* Translate a Node http(s) response's headers into the array shape required by
|
|
447
522
|
* `Fetch.fulfillRequest`, stripping CSP and other hop-by-hop headers that are
|
|
@@ -1094,13 +1169,20 @@ export class ElectronOverlayInjector {
|
|
|
1094
1169
|
const url = request.url || '';
|
|
1095
1170
|
const method = request.method || 'GET';
|
|
1096
1171
|
const requestHeaders = request.headers || {};
|
|
1097
|
-
const postData = request.postData;
|
|
1098
1172
|
// Only proxy HTML document requests (Accept header contains text/html)
|
|
1099
1173
|
const acceptHeader = requestHeaders['Accept'] || requestHeaders['accept'] || '';
|
|
1100
1174
|
if (!acceptHeader.includes('text/html')) {
|
|
1101
1175
|
send('Fetch.continueRequest', { requestId });
|
|
1102
1176
|
return;
|
|
1103
1177
|
}
|
|
1178
|
+
// A document POST (a navigating <form>, including multipart with a file) is
|
|
1179
|
+
// a byte pipe. Recover the exact bytes or fail — never forward a guess.
|
|
1180
|
+
const postBody = decodeCdpRequestPostBody(request);
|
|
1181
|
+
if (postBody.kind === 'unrecoverable') {
|
|
1182
|
+
console.error(`[electron-float] Cannot recover POST body byte-exactly (${postBody.reason}); failing instead of forwarding corrupt bytes: ${url.substring(0, 60)}`);
|
|
1183
|
+
send('Fetch.failRequest', { requestId, errorReason: 'Failed' });
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1104
1186
|
console.log(`[electron-float] Proxying request to strip CSP: ${url.substring(0, 60)}`);
|
|
1105
1187
|
// Make the request ourselves using Node.js http/https
|
|
1106
1188
|
const parsedUrl = new URL(url);
|
|
@@ -1110,7 +1192,7 @@ export class ElectronOverlayInjector {
|
|
|
1110
1192
|
port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
|
|
1111
1193
|
path: parsedUrl.pathname + parsedUrl.search,
|
|
1112
1194
|
method: method,
|
|
1113
|
-
headers: requestHeaders,
|
|
1195
|
+
headers: buildProxyRequestHeaders(requestHeaders, postBody.kind === 'bytes' ? postBody.bytes.length : null),
|
|
1114
1196
|
};
|
|
1115
1197
|
const proxyReq = transport.request(options, (proxyRes) => {
|
|
1116
1198
|
const bodyChunks = [];
|
|
@@ -1137,9 +1219,10 @@ export class ElectronOverlayInjector {
|
|
|
1137
1219
|
send('Fetch.failRequest', { requestId, errorReason: 'Failed' });
|
|
1138
1220
|
}
|
|
1139
1221
|
});
|
|
1140
|
-
// Forward request body if present (for POST/PUT requests)
|
|
1141
|
-
|
|
1142
|
-
|
|
1222
|
+
// Forward request body if present (for POST/PUT requests) as raw bytes —
|
|
1223
|
+
// writing the CDP `postData` string here is what UTF-8-expanded it (#2886).
|
|
1224
|
+
if (postBody.kind === 'bytes') {
|
|
1225
|
+
proxyReq.write(postBody.bytes);
|
|
1143
1226
|
}
|
|
1144
1227
|
proxyReq.end();
|
|
1145
1228
|
}
|