dsh-zen-remote 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/remote-access.md +2 -2
- package/lan-gate.mjs +15 -1
- package/lib/client.js +271 -30
- package/lib/fingerprint.js +4 -2
- package/lib/fingerprint.js.map +1 -1
- package/lib/intercept.js +161 -14
- package/lib/intercept.js.map +1 -1
- package/lib/merge-streams.js +11 -4
- package/lib/merge-streams.js.map +1 -1
- package/lib/relay-access.js.map +1 -1
- package/lib/relay-server.js +32 -11
- package/lib/relay-server.js.map +1 -1
- package/lib/types/client/effects/model-group-side.d.ts +13 -0
- package/lib/types/client/effects/model-group-side.d.ts.map +1 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/styles/compat.css.d.ts +1 -1
- package/lib/types/client/styles/compat.css.d.ts.map +1 -1
- package/lib/types/client/styles/composer.css.d.ts +1 -1
- package/lib/types/client/styles/composer.css.d.ts.map +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
- package/lib/types/client-data/model-group-side.d.ts +44 -0
- package/lib/types/client-data/model-group-side.d.ts.map +1 -0
- package/lib/types/fingerprint.d.ts +4 -2
- package/lib/types/fingerprint.d.ts.map +1 -1
- package/lib/types/intercept.d.ts +19 -9
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts +7 -2
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/relay-access.d.ts.map +1 -1
- package/lib/types/relay-server.d.ts.map +1 -1
- package/lib/types/virtual-id.d.ts +14 -0
- package/lib/types/virtual-id.d.ts.map +1 -1
- package/lib/virtual-id.js +14 -0
- package/lib/virtual-id.js.map +1 -1
- package/package.json +48 -49
- package/src/client/effects/model-group-side.ts +132 -0
- package/src/client/index.tsx +7 -0
- package/src/client/styles/compat.css.ts +14 -8
- package/src/client/styles/composer.css.ts +2 -1
- package/src/client/styles/remote-session.css.ts +43 -20
- package/src/client-data/model-group-side.ts +65 -0
- package/src/fingerprint.ts +4 -2
- package/src/intercept.ts +167 -12
- package/src/merge-streams.ts +11 -4
- package/src/relay-access.ts +6 -3
- package/src/relay-server.ts +49 -11
- package/src/virtual-id.ts +15 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const REMOTE_SESSION_CSS = "/* ---------- remote session: hide the open-on-the-server-machine entries ----------\n A remote session's files live on the relay SERVER; every \"open\" control here\n would act on the machine the DSH process runs on, not the one the browser is\n on. Hidden while the current session is remote (html[data-zr-remote-session]):\n - [data-open-target] is dsh-client-ui-open-in-app's own mount marker (RT\n dsh-client-ui-open-in-app lib/client.js ~325: the split-button anchor\n React renders with data-open-target={kind}) \u2014 one selector covers the\n session-header \"Open In...\" button, the document-preview actions, AND the\n \"Open / Show in Finder / Choose an application\" buttons of the changes\n panel and the deliverable cards (RT dsh-client-ui-deliverables\n lib/client.js ~1702, ~1963: those cards render the open-in-app package's\n FileRouteAction through the deliverables.file.actions and\n deliverables.review.file.actions slots, the same OpenTargetButton anchor).\n The attribute is the component's own contract, not a generated class. */\nhtml[data-zr-remote-session=\"1\"] [data-open-target] {\n display: none !important;\n}\n\n/* ---------- remote session: hide dsh-better-sidebar's file surfaces (T53) ----------\n dsh-better-sidebar 0.24.x is the second big \"open the machine's files\" UI.\n Every tab it registers (files/editor, git changes, subagent/tasks, side\n chat, the markdown/html/code file viewers) builds its requests from a\n {sessionId, cwd} scope and POSTs them to the plugin's own /sidebar/api/*\n routes on whichever machine answers \u2014 in a remote session that is the\n SUB-CLIENT's machine (client.js call() ~3111, fetchUpload ~3162,\n encodeHtmlUrl /sidebar/html/ ~3069-3414), so the tree would show same-named\n LOCAL files as if they were the session's and an edit would WRITE locally.\n Per the T53 decision the interfaces are hidden, not proxied: the relay\n carries no /sidebar routes and none are added.\n\n Anchors, all the plugin's or the host's own rendered contracts (no hashed\n class names; the one suffix selector, _chipIcon, is unique among the\n profile's packages \u2014 checked dsh-vision-router / dsh-auto-approve /\n dsh-mem0 / dsh-llm-verifier / dsh-plugin-subscriptions /\n @liustack/modsearch / @wxg-prc-cpg/browser-skill-dsh-plugin (modsearch /\n browser-skill) / dshmarket and every @deepseek-ai sidebar package for it):\n\n HONEST LIMITS (T53-fix): everything here is display:none ONLY. The plugin's\n components stay mounted and keep silently POSTing READ-ONLY /sidebar/api\n requests to the local machine (session.cwd, changes.ops, the tree reads a\n mounted tab refreshes with) \u2014 the data never leaves that machine, and no\n write can happen because every write control is inside the hidden surfaces.\n Known boundary: a dsh-resource://file/** address opened through\n sidebarRight.openResource in a remote session (file links in chat,\n deliverables, @-references, skills) is CLAIMED by the plugin's editor\n registration (client.js ~21377: patterns [\"dsh-resource://file/**\"]) before\n the host preview sees it \u2014 the right sidebar expands, the rules below hide\n the tab's body and chip, and an EMPTY panel remains. Root fix needs\n zen-remote's own remote file tree; separate discussion.\n\n - [data-dsh-bottom-toggle] \u2014 the header-utilities button that expands the\n bottom workbench (client.js BottomDockToggle ~20863; slot registration\n ~21492-21498, id dsh-better-sidebar:bottom-toggle). Our own phone header\n button drives the OFFICIAL right sidebar (MobileSessionHeader.tsx), so\n hiding this does not strand the phone.\n - [data-dsh-panel-host] \u2014 the fixed viewport layer the plugin appends to\n document.body (client.js ~20763); the bottom workbench panel\n ([data-dsh-bottom-panel]) is its only child, so hiding the layer hides\n the workbench whole (tab strip, + menu, tree, editor and all).\n - --dsh-sidebar-height \u2014 the plugin's layout push: written INLINE on <html>\n while the workbench is open (client.js writeGeometry ~20482-20488) and\n spent by its own layout.css as the center column's margin-bottom\n (client.js layout css ~23009: #root [data-dsh-center-col] { margin-bottom:\n var(--dsh-sidebar-height, 0px) }). Hiding the panel alone would leave\n that reserved band as a blank strip under the conversation, so the remote\n html zeroes the variable. A stylesheet !important beats a non-important\n inline style, and the plugin's JS state is never touched: the moment the\n attribute is removed (back on a local session) its own value applies\n again, transitions included.\n - [data-dsh-native-tab-host] \u2014 the wrapper the plugin renders around EVERY\n tab body it contributes to the host's native right Sidebar\n (client.js NativeTabBody ~21074, marker ~21110/21120). The host's pane\n chrome is untouched: the strip keeps the \"+\" (guide) button and the\n collapse/fullscreen controls, so a tab that was already open leaves no\n dead panel \u2014 an empty body behind a strip that still collapses, and the\n \"+\" re-opens the guide page (whose plugin capsules these rules hide, see\n below). React keeps mounting into the display:none node: no errors, and\n the restore on returning to a local session is instant.\n - [data-dockkit-tab]:has([class$=\"_chipIcon\"]) \u2014 the native tab STRIP's\n chips for plugin tabs, so an already-open tab does not survive as a\n clickable ghost. The chip button is dockkit's ([data-dockkit-tab], dsh-web\n frontend bundle: role=tab, renderTabTitle inside a\n span[data-dockkit-tab-title]); its content is the plugin's\n NativeTabTitle (~21172-21197), which always leads with a\n [class$=\"_chipIcon\"] glyph span because every built-in descriptor ships an\n icon \u2014 a chip with no glyph (an external tab registered through the\n plugin's viewer service without an icon) keeps its chip; its body is\n still hidden by the rule above. Host tabs' chips never contain a\n _chipIcon (checked all four @deepseek-ai sidebar packages), so the\n remote-aware host files page survives alongside.\n - [data-floating-window]:has([data-window-body]) \u2014 the plugin's\n body-PORTALED floating windows (client.js FloatingWindow ~15078-15120):\n the task edit window (teams.taskCreate/Update with rootSessionId via\n /sidebar/api, writeTask ~3124-3140) and the job-output window (host jobs\n kill). Both open from the subagent/tasks tab; portal escapes the tab\n body's display:none, so they need their own rule. Anchored on the\n window's own root attribute plus its own inner body marker, so a foreign\n [data-floating-window] without that shape never matches.\n - guide capsules \u2014 the empty-sidebar doorway buttons the HOST renders from\n the plugin's registrations ([data-sidebar-right-guide-entry=\"<kind>\"], RT\n dsh-client-ui-sidebar-right lib/client.js:466): kinds git / subagent /\n sidechat exist only while this plugin registers them, so those selectors\n are inert without it. The \"files\" capsule is the one ambiguous kind:\n dsh-client-ui-sidebar-files registers the SAME kind (its filesDefinition,\n lib/client.js:14-31) and that page is REMOTE-AWARE (it injects the host's\n remote.workspaceFiles service). T53-fix discriminates on the capsule's\n own rendered contract instead of plugin presence: the host's EntryBox\n renders aria-keyshortcuts from the shortcut matching entry.commandId (RT\n sidebar-right lib/client.js:461-467) \u2014 the host files guide row carries\n commandId \"workspace.files\" (dsh-client-ui-sidebar-files\n lib/client.js:30), while better-sidebar's guide rows carry NO commandId\n (client.js registerNativeSurface ~21385-21400), so its capsule never\n renders the attribute. :not([aria-keyshortcuts]) therefore hides the\n plugin's takeover capsule and spares the host's wherever the host has a\n default binding. Boundary: that \"wherever\" is not everywhere \u2014 the host\n registers workspace.files defaults for desktop:macos/windows/linux and\n web:macos/windows only (dsh-client-ui-sidebar-files lib/client.js:949-977),\n so on any other platform the OFFICIAL capsule also renders without the\n attribute and this rule hides it too (cosmetic; the page stays reachable\n through its shortcut command path and the plugin's takeover is the\n \"files\" implementation on every deployment this plugin pairs with\n better-sidebar anyway). */\nhtml[data-zr-remote-session=\"1\"] [data-dsh-bottom-toggle] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dsh-panel-host] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] {\n --dsh-sidebar-height: 0px !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dsh-native-tab-host] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dockkit-tab]:has([class$=\"_chipIcon\"]) {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-floating-window]:has([data-window-body]) {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"git\"],\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"subagent\"],\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"sidechat\"] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"files\"]:not([aria-keyshortcuts]) {\n display: none !important;\n}\n\n/* ---------- T52: model-menu groups follow the session's side ----------\n The model catalog is GLOBAL (one shared load per page), so the merged\n catalog shows the server's groups everywhere; but a selection is only\n runnable on the side the open session lives on \u2014 the interceptor refuses\n the other side with a clear message. Hide what cannot run, by the one\n stable mark the menu carries:\n - the model menu renders one section[role=\"group\"] per provider group\n with aria-labelledby=\"<useId>-<group.id>\" (RT dsh-client-ui-model-\n selection lib/client.js:830-835), so a VIRTUAL group's section carries\n the \"zr~\" prefix in that attribute \u2014 an attribute the component itself\n writes, like data-open-target above;\n - the menu is a portal under <body>, but <html> is still its ancestor,\n so the html-level session attribute scopes it with no host-depth\n assumption and no :has();\n - the [role=\"menu\"] scope keeps the rule inside dropdown menus (where the\n model picker lives); if DSH ever drops the aria mark the rule simply\n stops matching \u2014 the interceptor's refusals remain the backstop.\n In a remote session only the server's groups stay; otherwise only the\n local ones (the home page and dialogs read as local, which is right:\n the model picker only mounts inside a session, and a blank local\n session cannot run server models either). */\nhtml[data-zr-remote-session=\"1\"] [role=\"menu\"] section[role=\"group\"]:not([aria-labelledby*=\"zr~\"]) {\n display: none !important;\n}\nhtml:not([data-zr-remote-session]) [role=\"menu\"] section[role=\"group\"][aria-labelledby*=\"zr~\"] {\n display: none !important;\n}\n\n/* ---------- T52-fix: hide the virtual groups in NATIVE <option> pickers ----\n The model menu above is React DOM, but dsh-vision-router's settings render\n its vision-backend picker as a native <select> of <option value={group.id}>\n rows, and its filter (dsh-vision-router lib/client.js:661-670\n filterVisionBackendGroups) drops only vision-http / vision-chain / *-vision\n \u2014 a merged virtual group (\"zr~<id>~\u2026\") survives into that picker even\n though a server model can never be a LOCAL vision backend (the router calls\n providers from the machine it runs on). Native <option> rows honor\n display:none in the dropdown list, so this hides them wherever they appear:\n - no scoping attribute on purpose: a virtual group is not a runnable\n backend in ANY local context, and the option element itself carries the\n value \u2014 no host-depth assumption, no :has();\n - when the vision router (or any other <option>-rendering surface) is not\n installed, nothing matches \u2014 dead rule, zero cost;\n - zen-remote's own surfaces are checked: our settings forms render fixed\n enum options (\"web\" / \"desktop-client\" / role kinds /\n configForm enum strings, src/client/settings/SettingsSection.tsx:641,690-701)\n and none can start with \"zr~\" (virtual group ids only ever exist inside\n model-catalog payloads and model-selection arguments). */\noption[value^=\"zr~\"] {\n display: none !important;\n}\n\n/* ---------- remote session: hide the session-export menu item (T51, T51-fix) ----------\n A remote session's log lives on the relay server and the backend refuses\n /api/session.export for a virtual id with 403 remote-unsupported\n (fetch-route-intercept.ts) \u2014 the item would only ever end in the \"Export\n failed\" modal, so it is hidden IN THE MENU (T51-fix: the anchor button\n stays, because it also opens the \u53CD\u9988 entry, which a remote session can\n still use). The DOM, verified against RT:\n - the Menu renders its anchor and its list as SIBLINGS inside its own\n span root (RT dsh-client-ui-primitives lib/index.js ~4265-4273:\n children = [anchor, portal ? createPortal(list) : list]), and the\n export Menu passes no portal flag (default false, ~3923) \u2014 so the list\n is the anchor's next sibling, matched by the general-sibling\n combinator below;\n - the list surface carries role=\"menu\" (Menu passes it at ~4243;\n MenuSurface spreads ...props onto its root div, ~3778-3795) and the\n items viewport inside it is div[role=\"presentation\"] (~4249-4252);\n - every data item is ONE div (the itemWrap wrapper, ~4143), so\n :first-child of the viewport is the FIRST item \u2014 and the export\n package puts \u4E0B\u8F7D/\u5BFC\u51FA first by construction (RT dsh-session-log-export\n lib/client.js 202-206, the optional feedback entry appended after at\n 207-211).\n The anchor button class suffix is matched the way compat.css.ts matches\n module classes (the hash prefix is build-local, \"_moreButton\" is the\n source name; unique in this slot \u2014 the only other moreButton in the RT\n tree, dsh-client-ui-sidebar-documentpreview lib/client.excel.js, lives in\n the sidebar, never under conversation.session.header.utilities).\n Known costs, accepted: with the feedback UI absent the menu's only item\n is the export, so the opened menu is EMPTY; and keyboard navigation still\n steps into the hidden item (focusable but invisible) until activated or\n escaped \u2014 it cannot be triggered through the visibility, only tabbed\n past blindly. */\nhtml[data-zr-remote-session=\"1\"] [data-slot=\"conversation.session.header.utilities\"] [class$=\"_moreButton\"] ~ [role=\"menu\"] > [role=\"presentation\"] > :first-child {\n display: none !important;\n}\n";
|
|
1
|
+
export declare const REMOTE_SESSION_CSS = "/* ---------- remote session: hide the open-on-the-server-machine entries ----------\n A remote session's files live on the relay SERVER; every \"open\" control here\n would act on the machine the DSH process runs on, not the one the browser is\n on. Hidden while the current session is remote (html[data-zr-remote-session]):\n - [data-open-target] is dsh-client-ui-open-in-app's own mount marker (RT\n dsh-client-ui-open-in-app lib/client.js ~325: the split-button anchor\n React renders with data-open-target={kind}) \u2014 one selector covers the\n session-header \"Open In...\" button, the document-preview actions, AND the\n \"Open / Show in Finder / Choose an application\" buttons of the changes\n panel and the deliverable cards (RT dsh-client-ui-deliverables\n lib/client.js ~1702, ~1963: those cards render the open-in-app package's\n FileRouteAction through the deliverables.file.actions and\n deliverables.review.file.actions slots, the same OpenTargetButton anchor).\n The attribute is the component's own contract, not a generated class. */\nhtml[data-zr-remote-session=\"1\"] [data-open-target] {\n display: none !important;\n}\n\n/* ---------- remote session: hide dsh-better-sidebar's file surfaces (T53) ----------\n dsh-better-sidebar 0.24.x is the second big \"open the machine's files\" UI.\n Every tab it registers (files/editor, git changes, subagent/tasks, side\n chat, the markdown/html/code file viewers) builds its requests from a\n {sessionId, cwd} scope and POSTs them to the plugin's own /sidebar/api/*\n routes on whichever machine answers \u2014 in a remote session that is the\n SUB-CLIENT's machine (client.js call() ~3111, fetchUpload ~3162,\n encodeHtmlUrl /sidebar/html/ ~3069-3414), so the tree would show same-named\n LOCAL files as if they were the session's and an edit would WRITE locally.\n Per the T53 decision the interfaces are hidden, not proxied: the relay\n carries no /sidebar routes and none are added.\n\n Anchors, all the plugin's or the host's own rendered contracts (no hashed\n class names; the one suffix selector, _chipIcon, is unique among the\n profile's packages \u2014 checked dsh-vision-router / dsh-auto-approve /\n dsh-mem0 / dsh-llm-verifier / dsh-plugin-subscriptions /\n @liustack/modsearch / @wxg-prc-cpg/browser-skill-dsh-plugin (modsearch /\n browser-skill) / dshmarket and every @deepseek-ai sidebar package for it):\n\n HONEST LIMITS (T53-fix): everything here is display:none ONLY. The plugin's\n components stay mounted and keep silently POSTing READ-ONLY /sidebar/api\n requests to the local machine (session.cwd, changes.ops, the tree reads a\n mounted tab refreshes with) \u2014 the data never leaves that machine, and no\n write can happen because every write control is inside the hidden surfaces.\n Known boundary: a dsh-resource://file/** address opened through\n sidebarRight.openResource in a remote session (file links in chat,\n deliverables, @-references, skills) is CLAIMED by the plugin's editor\n registration (client.js ~21377: patterns [\"dsh-resource://file/**\"]) before\n the host preview sees it \u2014 the right sidebar expands, the rules below hide\n the tab's body and chip, and an EMPTY panel remains. Root fix needs\n zen-remote's own remote file tree; separate discussion.\n\n - [data-dsh-bottom-toggle] \u2014 the header-utilities button that expands the\n bottom workbench (client.js BottomDockToggle ~20863; slot registration\n ~21492-21498, id dsh-better-sidebar:bottom-toggle). Our own phone header\n button drives the OFFICIAL right sidebar (MobileSessionHeader.tsx), so\n hiding this does not strand the phone.\n - [data-dsh-panel-host] \u2014 the fixed viewport layer the plugin appends to\n document.body (client.js ~20763); the bottom workbench panel\n ([data-dsh-bottom-panel]) is its only child, so hiding the layer hides\n the workbench whole (tab strip, + menu, tree, editor and all).\n - --dsh-sidebar-height \u2014 the plugin's layout push: written INLINE on <html>\n while the workbench is open (client.js writeGeometry ~20482-20488) and\n spent by its own layout.css as the center column's margin-bottom\n (client.js layout css ~23009: #root [data-dsh-center-col] { margin-bottom:\n var(--dsh-sidebar-height, 0px) }). Hiding the panel alone would leave\n that reserved band as a blank strip under the conversation, so the remote\n html zeroes the variable. A stylesheet !important beats a non-important\n inline style, and the plugin's JS state is never touched: the moment the\n attribute is removed (back on a local session) its own value applies\n again, transitions included.\n - [data-dsh-native-tab-host] \u2014 the wrapper the plugin renders around EVERY\n tab body it contributes to the host's native right Sidebar\n (client.js NativeTabBody ~21074, marker ~21110/21120). The host's pane\n chrome is untouched: the strip keeps the \"+\" (guide) button and the\n collapse/fullscreen controls, so a tab that was already open leaves no\n dead panel \u2014 an empty body behind a strip that still collapses, and the\n \"+\" re-opens the guide page (whose plugin capsules these rules hide, see\n below). React keeps mounting into the display:none node: no errors, and\n the restore on returning to a local session is instant.\n - [data-dockkit-tab]:has([class$=\"_chipIcon\"]) \u2014 the native tab STRIP's\n chips for plugin tabs, so an already-open tab does not survive as a\n clickable ghost. The chip button is dockkit's ([data-dockkit-tab], dsh-web\n frontend bundle: role=tab, renderTabTitle inside a\n span[data-dockkit-tab-title]); its content is the plugin's\n NativeTabTitle (~21172-21197), which always leads with a\n [class$=\"_chipIcon\"] glyph span because every built-in descriptor ships an\n icon \u2014 a chip with no glyph (an external tab registered through the\n plugin's viewer service without an icon) keeps its chip; its body is\n still hidden by the rule above. Host tabs' chips never contain a\n _chipIcon (checked all four @deepseek-ai sidebar packages), so the\n remote-aware host files page survives alongside.\n - [data-floating-window]:has([data-window-body]) \u2014 the plugin's\n body-PORTALED floating windows (client.js FloatingWindow ~15078-15120):\n the task edit window (teams.taskCreate/Update with rootSessionId via\n /sidebar/api, writeTask ~3124-3140) and the job-output window (host jobs\n kill). Both open from the subagent/tasks tab; portal escapes the tab\n body's display:none, so they need their own rule. Anchored on the\n window's own root attribute plus its own inner body marker, so a foreign\n [data-floating-window] without that shape never matches.\n - guide capsules \u2014 the empty-sidebar doorway buttons the HOST renders from\n the plugin's registrations ([data-sidebar-right-guide-entry=\"<kind>\"], RT\n dsh-client-ui-sidebar-right lib/client.js:466): kinds git / subagent /\n sidechat exist only while this plugin registers them, so those selectors\n are inert without it. The \"files\" capsule is the one ambiguous kind:\n dsh-client-ui-sidebar-files registers the SAME kind (its filesDefinition,\n lib/client.js:14-31) and that page is REMOTE-AWARE (it injects the host's\n remote.workspaceFiles service). T53-fix discriminates on the capsule's\n own rendered contract instead of plugin presence: the host's EntryBox\n renders aria-keyshortcuts from the shortcut matching entry.commandId (RT\n sidebar-right lib/client.js:461-467) \u2014 the host files guide row carries\n commandId \"workspace.files\" (dsh-client-ui-sidebar-files\n lib/client.js:30), while better-sidebar's guide rows carry NO commandId\n (client.js registerNativeSurface ~21385-21400), so its capsule never\n renders the attribute. :not([aria-keyshortcuts]) therefore hides the\n plugin's takeover capsule and spares the host's wherever the host has a\n default binding. Boundary: that \"wherever\" is not everywhere \u2014 the host\n registers workspace.files defaults for desktop:macos/windows/linux and\n web:macos/windows only (dsh-client-ui-sidebar-files lib/client.js:949-977),\n so on any other platform the OFFICIAL capsule also renders without the\n attribute and this rule hides it too (cosmetic; the page stays reachable\n through its shortcut command path and the plugin's takeover is the\n \"files\" implementation on every deployment this plugin pairs with\n better-sidebar anyway). */\nhtml[data-zr-remote-session=\"1\"] [data-dsh-bottom-toggle] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dsh-panel-host] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] {\n --dsh-sidebar-height: 0px !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dsh-native-tab-host] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-dockkit-tab]:has([class$=\"_chipIcon\"]) {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-floating-window]:has([data-window-body]) {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"git\"],\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"subagent\"],\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"sidechat\"] {\n display: none !important;\n}\nhtml[data-zr-remote-session=\"1\"] [data-sidebar-right-guide-entry=\"files\"]:not([aria-keyshortcuts]) {\n display: none !important;\n}\n\n/* ---------- T52/T74: model-menu groups follow the session's side ----------\n The model catalog is GLOBAL (one shared load per page), so the merged\n catalog shows the server's groups everywhere; but a selection is only\n runnable on the side the open session lives on \u2014 the interceptor refuses\n the other side with a clear message. Hide what cannot run.\n\n What changed and why the mechanism is a STAMP now (T74): through 0.1.7\n each menu group rendered aria-labelledby=\"<useId>-<group.id>\" (RT017\n dsh-client-ui-model-selection lib/client.js ~824-830) \u2014 the group id was\n IN the attribute, and rules could key on a virtual group's \"zr~\" prefix\n directly. 0.2.0 renders the groups with the primitives' MenuGroup\n instead (RT dsh-client-ui-primitives lib/index.js ~4283-4304): the\n section's aria-labelledby carries ONLY the useId, the heading is a child\n div[data-menu-group-heading], and the menu container is a div whose id\n ends in \"-models\" with role=\"menu\" (RT dsh-client-ui-model-selection\n lib/client.js ~974-980). Two consequences killed the old rules: a group\n section no longer says anywhere in its markup which group it is, and the\n same MenuGroup renders OTHER menus' groups too \u2014 the old\n [role=\"menu\"] section[role=\"group\"] scope alone was too wide and would\n have hidden every unmarked group of every menu in a remote session\n (leaving just the search box), while missing the server's groups in\n local ones.\n\n The new keys on what EVERY version actually renders, the heading text:\n each virtual group's name is prefixed with the invisible WORD JOINER\n (VIRTUAL_GROUP_NAME_MARK, virtual-id.ts; written by mergeModelCatalogs).\n The browser effect (effects/model-group-side.ts) reads each group's\n heading and stamps data-zr-group=\"remote|local\" on the section \u2014 but\n only inside a CONTAINER (the sections' shared parent element) that holds\n at least one marked heading. That container rule is what scopes these\n rules to the model menu alone WITHOUT assuming menu structure: an\n unpaired client's model menu, every other menu, and the whole rest of\n the page hold no marked heading, receive no stamp, and match neither\n rule. And since the merged catalog only ever APPENDS virtual groups to\n the local list, within a decided container the unmarked groups are\n exactly the local ones \u2014 mixed containers (the norm) decide each group\n separately. The menu is a portal under <body>, but <html> is still its\n ancestor, so the html-level session attribute scopes both rules. If the\n effect is not running (uninstalled, or a host-role page that never had\n it), no stamp exists and both rules go inert \u2014 nothing stays hidden.\n\n KNOWN BOUNDARY (accepted, not fixed): in a remote session, searching the\n model menu and pressing Enter can commit a HIDDEN local model \u2014 the\n interceptor refuses it with its usual message. */\nhtml[data-zr-remote-session=\"1\"] section[role=\"group\"][data-zr-group=\"local\"] {\n display: none !important;\n}\nhtml:not([data-zr-remote-session]) section[role=\"group\"][data-zr-group=\"remote\"] {\n display: none !important;\n}\n\n/* ---------- T52-fix: hide the virtual groups in NATIVE <option> pickers ----\n The model menu above is React DOM, but dsh-vision-router's settings render\n its vision-backend picker as a native <select> of <option value={group.id}>\n rows, and its filter (dsh-vision-router lib/client.js:661-670\n filterVisionBackendGroups) drops only vision-http / vision-chain / *-vision\n \u2014 a merged virtual group (\"zr~<id>~\u2026\") survives into that picker even\n though a server model can never be a LOCAL vision backend (the router calls\n providers from the machine it runs on). Native <option> rows honor\n display:none in the dropdown list, so this hides them wherever they appear:\n - no scoping attribute on purpose: a virtual group is not a runnable\n backend in ANY local context, and the option element itself carries the\n value \u2014 no host-depth assumption, no :has();\n - when the vision router (or any other <option>-rendering surface) is not\n installed, nothing matches \u2014 dead rule, zero cost;\n - zen-remote's own surfaces are checked: our settings forms render fixed\n enum options (\"web\" / \"desktop-client\" / role kinds /\n configForm enum strings, src/client/settings/SettingsSection.tsx:641,690-701)\n and none can start with \"zr~\" (virtual group ids only ever exist inside\n model-catalog payloads and model-selection arguments). */\noption[value^=\"zr~\"] {\n display: none !important;\n}\n\n/* ---------- remote session: hide the session-export menu item (T51, T51-fix) ----------\n A remote session's log lives on the relay server and the backend refuses\n /api/session.export for a virtual id with 403 remote-unsupported\n (fetch-route-intercept.ts) \u2014 the item would only ever end in the \"Export\n failed\" modal, so it is hidden IN THE MENU (T51-fix: the anchor button\n stays, because it also opens the \u53CD\u9988 entry, which a remote session can\n still use). The DOM, verified against RT:\n - the Menu renders its anchor and its list as SIBLINGS inside its own\n span root (RT dsh-client-ui-primitives lib/index.js ~4265-4273:\n children = [anchor, portal ? createPortal(list) : list]), and the\n export Menu passes no portal flag (default false, ~3923) \u2014 so the list\n is the anchor's next sibling, matched by the general-sibling\n combinator below;\n - the list surface carries role=\"menu\" (Menu passes it at ~4243;\n MenuSurface spreads ...props onto its root div, ~3778-3795) and the\n items viewport inside it is div[role=\"presentation\"] (~4249-4252);\n - every data item is ONE div (the itemWrap wrapper, ~4143), so\n :first-child of the viewport is the FIRST item \u2014 and the export\n package puts \u4E0B\u8F7D/\u5BFC\u51FA first by construction (RT dsh-session-log-export\n lib/client.js 202-206, the optional feedback entry appended after at\n 207-211).\n The anchor button class suffix is matched the way compat.css.ts matches\n module classes (the hash prefix is build-local, \"_moreButton\" is the\n source name; unique in this slot \u2014 the only other moreButton in the RT\n tree, dsh-client-ui-sidebar-documentpreview lib/client.excel.js, lives in\n the sidebar, never under conversation.session.header.utilities).\n Known costs, accepted: with the feedback UI absent the menu's only item\n is the export, so the opened menu is EMPTY; and keyboard navigation still\n steps into the hidden item (focusable but invisible) until activated or\n escaped \u2014 it cannot be triggered through the visibility, only tabbed\n past blindly. */\nhtml[data-zr-remote-session=\"1\"] [data-slot=\"conversation.session.header.utilities\"] [class$=\"_moreButton\"] ~ [role=\"menu\"] > [role=\"presentation\"] > :first-child {\n display: none !important;\n}\n";
|
|
2
2
|
//# sourceMappingURL=remote-session.css.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-session.css.d.ts","sourceRoot":"","sources":["../../../../src/client/styles/remote-session.css.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"remote-session.css.d.ts","sourceRoot":"","sources":["../../../../src/client/styles/remote-session.css.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,kBAAkB,i9gBAiQ9B,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T74: which side of the pairing a model-menu GROUP belongs to, as pure
|
|
3
|
+
* functions — the readable core of the browser effect
|
|
4
|
+
* (src/client/effects/model-group-side.ts).
|
|
5
|
+
*
|
|
6
|
+
* WHY: the merged catalog (merge-streams.ts mergeModelCatalogs) appends the
|
|
7
|
+
* server's provider groups everywhere, but a selection only runs on the side
|
|
8
|
+
* the open session lives on — the interceptor refuses the other side. Through
|
|
9
|
+
* DSH 0.1.7 every menu group carried its id in `aria-labelledby`
|
|
10
|
+
* (`<useId>-<group.id>`), so CSS keyed the hiding on the `zr~` prefix (T52).
|
|
11
|
+
* DSH 0.2.0 renders the groups with the primitives' MenuGroup, whose
|
|
12
|
+
* `aria-labelledby` is a bare useId — the id is gone — and the same component
|
|
13
|
+
* renders OTHER menus' groups too, so attribute scoping misfires in both
|
|
14
|
+
* directions. Classification therefore moved to the one mark every version
|
|
15
|
+
* renders: virtual group NAMES start with VIRTUAL_GROUP_NAME_MARK
|
|
16
|
+
* (virtual-id.ts), read off each group's heading text.
|
|
17
|
+
*
|
|
18
|
+
* The container rule is what keeps the effect inert wherever it cannot be
|
|
19
|
+
* sure: a container with not ONE marked heading — the model menu of a
|
|
20
|
+
* sub-client with no shared models, every other menu on the page, the whole
|
|
21
|
+
* rest of the page — classifies as `undefined` for every group, which the
|
|
22
|
+
* effect reads as "leave the DOM alone". Only a container holding at least
|
|
23
|
+
* one marked heading is decided, and inside it the unmarked groups are
|
|
24
|
+
* exactly the LOCAL ones: the merged catalog only ever APPENDS virtual
|
|
25
|
+
* groups to the local list, never mixes them the other way.
|
|
26
|
+
*
|
|
27
|
+
* Defensive like the rest of client-data: an empty or missing heading never
|
|
28
|
+
* counts as a mark, so it can never decide a container by accident.
|
|
29
|
+
*/
|
|
30
|
+
/** One group's display description, as the DOM shows it. */
|
|
31
|
+
export interface ModelGroupHeading {
|
|
32
|
+
/** Groups sharing one container share one key (the effect numbers the
|
|
33
|
+
* parent elements it scans). */
|
|
34
|
+
containerKey: number;
|
|
35
|
+
/** The group's heading text ('' when no heading could be found). */
|
|
36
|
+
headingText: string;
|
|
37
|
+
}
|
|
38
|
+
/** Per-group verdict, in input order: `remote` for marked headings, `local`
|
|
39
|
+
* for the rest of a container that has at least one, and `undefined` —
|
|
40
|
+
* "stamp nothing" — for every group of a container that holds no mark at
|
|
41
|
+
* all. */
|
|
42
|
+
export type ModelGroupSide = 'remote' | 'local' | undefined;
|
|
43
|
+
export declare function classifyModelGroups(groups: readonly ModelGroupHeading[]): ModelGroupSide[];
|
|
44
|
+
//# sourceMappingURL=model-group-side.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-group-side.d.ts","sourceRoot":"","sources":["../../../src/client-data/model-group-side.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC;oCACgC;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;UAGU;AACV,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAE3D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,cAAc,EAAE,CAiB1F"}
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
* definitions, the server puts its map into the handshake, the client
|
|
9
9
|
* compares group by group, and the settings page lists the differing groups.
|
|
10
10
|
* Identical maps mean fully compatible — the DSH version numbers themselves
|
|
11
|
-
* are deliberately NOT compared (docs/spike-relay.md §2.3: 0.1.7 and
|
|
12
|
-
* share byte-identical remote interfaces, so a version gate would
|
|
11
|
+
* are deliberately NOT compared (docs/spike-relay.md §2.3: 0.1.7-rc.2 and
|
|
12
|
+
* 0.2.0-rc.1 share byte-identical remote interfaces, so a version gate would
|
|
13
|
+
* misreject; 0.2.0-rc.2 then changed the session group within one minor —
|
|
14
|
+
* an additive optional field — which a version gate would have missed).
|
|
13
15
|
*
|
|
14
16
|
* What is hashed, per group, in priority order:
|
|
15
17
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/fingerprint.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAQH,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,gBAAgB,CAAA;AAQpD,iFAAiF;AACjF,eAAO,MAAM,YAAY,WAAW,CAAA;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOvE,CAAA;AAKD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CACzC;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC5B;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,mEAAmE;IACnE,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB;;6BAEyB;IACzB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AA+CD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAqB9E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAE9E;AA0CD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK/F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAYlE;AAyDD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAShI;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAwBrF"}
|
package/lib/types/intercept.d.ts
CHANGED
|
@@ -57,11 +57,14 @@
|
|
|
57
57
|
* `agentId` and `eventId` become `zr~<serverId>~…` virtual ids (those are
|
|
58
58
|
* the ONLY session ids a forwarded waterfall carries — the request bodies
|
|
59
59
|
* are tool/question data, verified against dsh-tools/dsh-user-questions),
|
|
60
|
-
* and the remote `ready`/`emit` frames are DROPPED
|
|
60
|
+
* and the remote `ready`/`emit` frames are DROPPED — except, since T75, a
|
|
61
|
+
* shared session's `api-session/status` emit, which crosses with its
|
|
62
|
+
* session id virtualized (the one share-scoped emit; every other emit
|
|
63
|
+
* broadcasts server-wide state the UI must not mistake for local
|
|
64
|
+
* sessions). The client face of the
|
|
61
65
|
* gateway (dsh-api-gateway lib/client.js) accepts a ready frame only as
|
|
62
|
-
* the FIRST frame of the stream and would fail the stream on a second one
|
|
63
|
-
*
|
|
64
|
-
* local sessions. Prompts this leg showed are closed when the leg dies —
|
|
66
|
+
* the FIRST frame of the stream and would fail the stream on a second one.
|
|
67
|
+
* Prompts this leg showed are closed when the leg dies —
|
|
65
68
|
* each gets a synthesized `cancel` — so a disconnect cannot leave an
|
|
66
69
|
* approval on screen that no server can settle anymore (T32-fix).
|
|
67
70
|
* - `dispatchRpc('$events/result', …)` splits on the eventId: a virtual id
|
|
@@ -336,11 +339,18 @@ export declare function rewriteResult(endpoint: string, value: unknown, serverId
|
|
|
336
339
|
* whole thing in `zr~<serverId>~`.
|
|
337
340
|
* - `cancel`: `{type, eventId}` — the correlation id goes virtual so the UI
|
|
338
341
|
* can match it against the waterfall it showed and close the prompt.
|
|
339
|
-
* -
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
342
|
+
* - `emit`: dropped, with ONE exception (T75) — a well-formed
|
|
343
|
+
* `api-session/status` frame (the only emit the server forwards, and only
|
|
344
|
+
* for accessible sessions) has its `args[0]` session id virtualized and
|
|
345
|
+
* its `args[1]` running flag passed through, so the UI's
|
|
346
|
+
* `api-session/status` listener keeps the remote session's running state
|
|
347
|
+
* in step with the host's (RT dsh-api-session-controller lib/client.js
|
|
348
|
+
* `handleSessionStatus`).
|
|
349
|
+
* - everything else — `ready`, non-status emits, non-objects, unknown
|
|
350
|
+
* types, and any frame failing the client face's exact-keys shape — is
|
|
351
|
+
* DROPPED (T32-fix2 mirrors the server side). `ready` and the other emits
|
|
352
|
+
* carry facts the UI must never see (the local stream opened with ITS
|
|
353
|
+
* ready frame; emits broadcast server-wide state); a malformed frame that
|
|
344
354
|
* slipped through would fail `parseRemoteEventFrame` and take the UI's
|
|
345
355
|
* whole `$events` generation down with it, failing and reconnecting in a
|
|
346
356
|
* loop. Mirrors the server's own forwardable-shape gate, so the two ends
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intercept.d.ts","sourceRoot":"","sources":["../../src/intercept.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"intercept.d.ts","sourceRoot":"","sources":["../../src/intercept.ts"],"names":[],"mappings":"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"}
|
|
@@ -305,8 +305,13 @@ export declare function mergeSessionList(localResult: unknown, remoteResult: unk
|
|
|
305
305
|
* order, RT dsh-client-ui-model-selection lib/client.js:510 — appended
|
|
306
306
|
* groups render last); each group id becomes the virtual group id
|
|
307
307
|
* `zr~<serverId>~<original>` and its name is prefixed
|
|
308
|
-
* `${serverName} · ${name}` — the same workspace
|
|
309
|
-
* merger uses
|
|
308
|
+
* `${VIRTUAL_GROUP_NAME_MARK}${serverName} · ${name}` — the same workspace
|
|
309
|
+
* title discipline the merger uses, PLUS the invisible WORD JOINER (T74):
|
|
310
|
+
* the model menu's groups stopped carrying their id in the markup (0.2.0's
|
|
311
|
+
* MenuGroup renders `aria-labelledby={useId()}` only), so the browser
|
|
312
|
+
* classifies menu groups by this heading prefix instead
|
|
313
|
+
* (client-data/model-group-side.ts). The sidebar's workspace TITLES stay
|
|
314
|
+
* unmarked — those groups are keyed by their `zr~` row ids;
|
|
310
315
|
* - `default` and `failures` stay LOCAL untouched: the default drives what a
|
|
311
316
|
* blank LOCAL session would run (a remote session's current model comes
|
|
312
317
|
* from its projection instead), and the UI renders every failure as a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-streams.d.ts","sourceRoot":"","sources":["../../src/merge-streams.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"merge-streams.d.ts","sourceRoot":"","sources":["../../src/merge-streams.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-access.d.ts","sourceRoot":"","sources":["../../src/relay-access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoHG;AAyBH;;;2DAG2D;AAC3D,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,CAAA;AAElD;;;;;;;;6CAQ6C;AAC7C,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,8BAA8B,GAAG,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"relay-access.d.ts","sourceRoot":"","sources":["../../src/relay-access.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-server.d.ts","sourceRoot":"","sources":["../../src/relay-server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"relay-server.d.ts","sourceRoot":"","sources":["../../src/relay-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,20 @@
|
|
|
18
18
|
*/
|
|
19
19
|
/** The fixed prefix every virtual id starts with. */
|
|
20
20
|
export declare const VIRTUAL_ID_PREFIX = "zr~";
|
|
21
|
+
/**
|
|
22
|
+
* The invisible WORD JOINER (U+2060) every virtual GROUP NAME starts with
|
|
23
|
+
* (T74). DSH 0.2.0 renders the model menu's provider groups with the
|
|
24
|
+
* primitives' MenuGroup, whose `aria-labelledby` carries only a useId — the
|
|
25
|
+
* group id is gone from the markup — so the browser half can no longer tell
|
|
26
|
+
* a virtual group from a local one by attribute. The merged catalog's group
|
|
27
|
+
* NAME (merge-streams.ts mergeModelCatalogs) is the one mark that survives
|
|
28
|
+
* in both 0.1.7 and 0.2.0, and effects/model-group-side.ts classifies each
|
|
29
|
+
* group container by which headings start with it. Zero-width: headings
|
|
30
|
+
* read exactly as before. Sidebar workspace TITLES deliberately do NOT
|
|
31
|
+
* carry it — those groups are told apart by their `zr~` row ids, not by
|
|
32
|
+
* text.
|
|
33
|
+
*/
|
|
34
|
+
export declare const VIRTUAL_GROUP_NAME_MARK = "\u2060";
|
|
21
35
|
/** The two halves {@link fromVirtual} recovers from a virtual id. */
|
|
22
36
|
export interface VirtualIdParts {
|
|
23
37
|
serverId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-id.d.ts","sourceRoot":"","sources":["../../src/virtual-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"virtual-id.d.ts","sourceRoot":"","sources":["../../src/virtual-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,QAAQ,CAAA;AAEtC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,WAAW,CAAA;AAM/C,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;CACX;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CASnE;AAED,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAE9C"}
|
package/lib/virtual-id.js
CHANGED
|
@@ -18,6 +18,20 @@
|
|
|
18
18
|
*/
|
|
19
19
|
/** The fixed prefix every virtual id starts with. */
|
|
20
20
|
export const VIRTUAL_ID_PREFIX = 'zr~';
|
|
21
|
+
/**
|
|
22
|
+
* The invisible WORD JOINER (U+2060) every virtual GROUP NAME starts with
|
|
23
|
+
* (T74). DSH 0.2.0 renders the model menu's provider groups with the
|
|
24
|
+
* primitives' MenuGroup, whose `aria-labelledby` carries only a useId — the
|
|
25
|
+
* group id is gone from the markup — so the browser half can no longer tell
|
|
26
|
+
* a virtual group from a local one by attribute. The merged catalog's group
|
|
27
|
+
* NAME (merge-streams.ts mergeModelCatalogs) is the one mark that survives
|
|
28
|
+
* in both 0.1.7 and 0.2.0, and effects/model-group-side.ts classifies each
|
|
29
|
+
* group container by which headings start with it. Zero-width: headings
|
|
30
|
+
* read exactly as before. Sidebar workspace TITLES deliberately do NOT
|
|
31
|
+
* carry it — those groups are told apart by their `zr~` row ids, not by
|
|
32
|
+
* text.
|
|
33
|
+
*/
|
|
34
|
+
export const VIRTUAL_GROUP_NAME_MARK = '\u2060';
|
|
21
35
|
/** The server id half: exactly the 8 lowercase hex chars relay-server.ts
|
|
22
36
|
* mints (`randomBytes(4).toString('hex')`). */
|
|
23
37
|
const SERVER_ID_PATTERN = /^[0-9a-f]{8}$/;
|
package/lib/virtual-id.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-id.js","sourceRoot":"","sources":["../src/virtual-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAA;AAEtC;+CAC+C;AAC/C,MAAM,iBAAiB,GAAG,eAAe,CAAA;AAQzC,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,EAAU;IACpD,OAAO,GAAG,iBAAiB,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAA;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,SAAS,CAAA;IACjF,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;IAC/C,0EAA0E;IAC1E,yDAAyD;IACzD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,SAAS,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACjC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AACxC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,EAAW;IACnC,OAAO,WAAW,CAAC,EAAE,CAAC,KAAK,SAAS,CAAA;AACtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"virtual-id.js","sourceRoot":"","sources":["../src/virtual-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAA;AAEtC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,QAAQ,CAAA;AAE/C;+CAC+C;AAC/C,MAAM,iBAAiB,GAAG,eAAe,CAAA;AAQzC,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,EAAU;IACpD,OAAO,GAAG,iBAAiB,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAA;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,SAAS,CAAA;IACjF,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;IAC/C,0EAA0E;IAC1E,yDAAyD;IACzD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,SAAS,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACjC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AACxC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,EAAW;IACnC,OAAO,WAAW,CAAC,EAAE,CAAC,KAAK,SAAS,CAAA;AACtC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-zen-remote",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "一个插件、两种角色:主服务端把 DeepSeek Harness 变成手机能安全访问的 PWA(移动端界面、配对码网关、Web Push),并把选定会话共享给已配对的桌面端;子客户端在另一台 DSH 桌面端的侧边栏里远程使用这些会话。One DSH plugin, two roles: the host turns DeepSeek Harness into a phone-reachable PWA (mobile UI, pairing-code gateway behind your own reverse proxy, Web Push) and shares chosen sessions to paired desktops; the client uses those sessions remotely from another DSH desktop app's sidebar.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -82,18 +82,18 @@
|
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
84
|
"@deepseek-ai/cordis": "*",
|
|
85
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
86
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
87
|
-
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
88
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
89
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
90
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
91
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
92
|
-
"@deepseek-ai/dsh-session": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
93
|
-
"@deepseek-ai/dsh-session-log-export": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
94
|
-
"@deepseek-ai/dsh-session-query": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
95
|
-
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
96
|
-
"@deepseek-ai/dsh-workspace": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
87
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
90
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
91
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
92
|
+
"@deepseek-ai/dsh-session": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
93
|
+
"@deepseek-ai/dsh-session-log-export": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
94
|
+
"@deepseek-ai/dsh-session-query": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
95
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
96
|
+
"@deepseek-ai/dsh-workspace": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
|
|
97
97
|
"@deepseek-ai/schemastery": "*",
|
|
98
98
|
"react": "^18.2.0"
|
|
99
99
|
},
|
|
@@ -115,43 +115,42 @@
|
|
|
115
115
|
}
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
118
|
-
"@deepseek-ai/cordis": "4.0.
|
|
118
|
+
"@deepseek-ai/cordis": "4.0.5-alpha.1",
|
|
119
119
|
"@deepseek-ai/cosmokit": "1.8.5",
|
|
120
|
-
"@deepseek-ai/dsh-agent": "0.1
|
|
121
|
-
"@deepseek-ai/dsh-api-remotes": "0.1
|
|
122
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1
|
|
123
|
-
"@deepseek-ai/dsh-api-workspace-controller": "0.1
|
|
124
|
-
"@deepseek-ai/dsh-brand": "0.1
|
|
125
|
-
"@deepseek-ai/dsh-client-connection": "0.1
|
|
126
|
-
"@deepseek-ai/dsh-client-locale": "0.1
|
|
127
|
-
"@deepseek-ai/dsh-client-store": "0.1
|
|
128
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1
|
|
129
|
-
"@deepseek-ai/dsh-client-ui-layout": "0.1
|
|
130
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1
|
|
131
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1
|
|
132
|
-
"@deepseek-ai/dsh-client-ui-session": "0.1
|
|
133
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "0.1
|
|
134
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1
|
|
135
|
-
"@deepseek-ai/dsh-host-webserver": "0.1
|
|
136
|
-
"@deepseek-ai/dsh-
|
|
137
|
-
"@deepseek-ai/dsh-
|
|
138
|
-
"@deepseek-ai/dsh-
|
|
139
|
-
"@deepseek-ai/dsh-sandbox": "0.1
|
|
140
|
-
"@deepseek-ai/dsh-
|
|
141
|
-
"@deepseek-ai/dsh-
|
|
142
|
-
"@deepseek-ai/dsh-session": "0.1
|
|
143
|
-
"@deepseek-ai/dsh-session-
|
|
144
|
-
"@deepseek-ai/dsh-session-
|
|
145
|
-
"@deepseek-ai/dsh-session-
|
|
146
|
-
"@deepseek-ai/dsh-
|
|
147
|
-
"@deepseek-ai/dsh-
|
|
148
|
-
"@deepseek-ai/dsh-
|
|
149
|
-
"@deepseek-ai/dsh-
|
|
150
|
-
"@deepseek-ai/dsh-
|
|
151
|
-
"@deepseek-ai/dsh-
|
|
152
|
-
"@deepseek-ai/dsh-util-
|
|
153
|
-
"@deepseek-ai/dsh-
|
|
154
|
-
"@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
|
|
120
|
+
"@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
|
|
121
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-alpha.2",
|
|
122
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.1-alpha.2",
|
|
123
|
+
"@deepseek-ai/dsh-api-workspace-controller": "0.2.1-alpha.2",
|
|
124
|
+
"@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
|
|
125
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
|
|
126
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.2",
|
|
127
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.2",
|
|
128
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-alpha.2",
|
|
129
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-alpha.2",
|
|
130
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.2",
|
|
131
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.2",
|
|
132
|
+
"@deepseek-ai/dsh-client-ui-session": "0.2.1-alpha.2",
|
|
133
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-alpha.2",
|
|
134
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.2",
|
|
135
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.2",
|
|
136
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
137
|
+
"@deepseek-ai/dsh-ptc-runtime": "0.2.1-alpha.2",
|
|
138
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-alpha.2",
|
|
139
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.2.1-alpha.2",
|
|
140
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
|
|
141
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
142
|
+
"@deepseek-ai/dsh-session-log-export": "0.2.1-alpha.2",
|
|
143
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
|
|
144
|
+
"@deepseek-ai/dsh-session-query": "0.2.1-alpha.2",
|
|
145
|
+
"@deepseek-ai/dsh-session-stats": "0.2.1-alpha.2",
|
|
146
|
+
"@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
|
|
147
|
+
"@deepseek-ai/dsh-timeout": "0.2.1-alpha.2",
|
|
148
|
+
"@deepseek-ai/dsh-token-meter": "0.2.1-alpha.2",
|
|
149
|
+
"@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
|
|
150
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
|
|
151
|
+
"@deepseek-ai/dsh-util-crypto": "0.2.1-alpha.2",
|
|
152
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
|
|
153
|
+
"@deepseek-ai/dsh-workspace": "0.2.1-alpha.2",
|
|
155
154
|
"@deepseek-ai/schemastery": "3.18.4",
|
|
156
155
|
"@types/node": "^26.2.0",
|
|
157
156
|
"@types/react": "~18.3.1",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { ClientContext } from '../compat/types.ts'
|
|
2
|
+
import { classifyModelGroups, type ModelGroupHeading } from '../../client-data/model-group-side.ts'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* T74: stamp every model-menu group with the side of the pairing it belongs
|
|
6
|
+
* to, so remote-session.css.ts can hide the groups the open session cannot
|
|
7
|
+
* run. The stamps are `data-zr-group="remote|local"` on each
|
|
8
|
+
* `section[role="group"]`; which sections get one (and which get none) is
|
|
9
|
+
* the pure classifier's container rule (client-data/model-group-side.ts) —
|
|
10
|
+
* only a container holding at least one marked (WORD JOINER-prefixed, see
|
|
11
|
+
* virtual-id.ts) heading is decided at all, so every other menu and the
|
|
12
|
+
* whole rest of the page is never touched.
|
|
13
|
+
*
|
|
14
|
+
* Synchronous in the observer callback, never behind rAF: the callback is a
|
|
15
|
+
* microtask and runs before this frame paints, so a group that must be
|
|
16
|
+
* hidden is hidden the first time it is drawn. A rAF would land a frame late
|
|
17
|
+
* and show one frame of the groups the CSS is about to hide (AGENTS.md's
|
|
18
|
+
* "晚一帧" rule — the same shape the turn-fold and model-sheet-extras bugs
|
|
19
|
+
* shared). The cheap batch gate below keeps the full rescan off the hot
|
|
20
|
+
* path: most mutations (chat streaming, composer typing) touch no group.
|
|
21
|
+
*/
|
|
22
|
+
const GROUP_SELECTOR = 'section[role="group"]'
|
|
23
|
+
|
|
24
|
+
/** The stamp this effect writes; remote-session.css.ts hides
|
|
25
|
+
* `[data-zr-group="local"]` in a remote session and
|
|
26
|
+
* `[data-zr-group="remote"]` everywhere else. */
|
|
27
|
+
const STAMP = 'data-zr-group'
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The heading text a group section renders, across the two DSH layouts:
|
|
31
|
+
* 0.1.7 points `aria-labelledby` at a heading div (id `<useId>-<group.id>`);
|
|
32
|
+
* 0.2.0's MenuGroup points it at its own useId heading — which is also the
|
|
33
|
+
* first `[data-menu-group-heading]` child — and its first child is an
|
|
34
|
+
* id-less position sentinel span. Falls through in that order, then to the
|
|
35
|
+
* first id-bearing child (0.1.7's heading, should `aria-labelledby` ever be
|
|
36
|
+
* dropped), and gives up with `null`.
|
|
37
|
+
*/
|
|
38
|
+
export function headingTextOf(section: Element, getElementById: (id: string) => Element | null): string | null {
|
|
39
|
+
const labelledby = section.getAttribute('aria-labelledby')
|
|
40
|
+
if (labelledby !== null) {
|
|
41
|
+
const heading = getElementById(labelledby)
|
|
42
|
+
if (heading !== null) return heading.textContent
|
|
43
|
+
}
|
|
44
|
+
const own = section.querySelector(':scope > [data-menu-group-heading]')
|
|
45
|
+
if (own !== null) return own.textContent
|
|
46
|
+
for (const child of section.children) {
|
|
47
|
+
if (child.id !== '') return child.textContent
|
|
48
|
+
}
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Does this mutation involve a group section, inside or as a node? Groups
|
|
53
|
+
* are rare; everything else (streaming text, composer typing) bails here. */
|
|
54
|
+
function touchesGroup(mutation: MutationRecord): boolean {
|
|
55
|
+
if (mutation.type === 'childList') {
|
|
56
|
+
for (const node of mutation.addedNodes) if (isGroupish(node)) return true
|
|
57
|
+
for (const node of mutation.removedNodes) if (isGroupish(node)) return true
|
|
58
|
+
}
|
|
59
|
+
const target = mutation.target
|
|
60
|
+
const el = target.nodeType === 1 ? (target as Element) : target.parentElement
|
|
61
|
+
return el !== null && el.closest(GROUP_SELECTOR) !== null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isGroupish(node: Node): boolean {
|
|
65
|
+
if (node.nodeType !== 1) return false
|
|
66
|
+
const el = node as Element
|
|
67
|
+
return el.matches(GROUP_SELECTOR) || el.querySelector(GROUP_SELECTOR) !== null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function installModelGroupSide(ctx: ClientContext): void {
|
|
71
|
+
ctx.effect(() => {
|
|
72
|
+
const applyVerdict = (section: Element, verdict: 'remote' | 'local' | undefined): void => {
|
|
73
|
+
// Write only on change — the observer does not watch attributes (so a
|
|
74
|
+
// stamp cannot re-trigger it), but a removed section's container may
|
|
75
|
+
// be re-decided, and an unconditional set would still churn
|
|
76
|
+
// style/attribute machinery for no effect.
|
|
77
|
+
if (verdict === undefined) {
|
|
78
|
+
if (section.hasAttribute(STAMP)) section.removeAttribute(STAMP)
|
|
79
|
+
} else if (section.getAttribute(STAMP) !== verdict) {
|
|
80
|
+
section.setAttribute(STAMP, verdict)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const scan = (): void => {
|
|
85
|
+
const sections = document.querySelectorAll(GROUP_SELECTOR)
|
|
86
|
+
// Group by parent element, in document order: querySelectorAll walks
|
|
87
|
+
// the document, and one parent's children form a contiguous run of it,
|
|
88
|
+
// so a running number per distinct parent is a stable container key.
|
|
89
|
+
const containerKeys = new Map<Element, number>()
|
|
90
|
+
const rows: Array<ModelGroupHeading & { section: Element }> = []
|
|
91
|
+
for (const section of sections) {
|
|
92
|
+
const parent = section.parentElement
|
|
93
|
+
if (parent === null) continue
|
|
94
|
+
let key = containerKeys.get(parent)
|
|
95
|
+
if (key === undefined) {
|
|
96
|
+
key = containerKeys.size
|
|
97
|
+
containerKeys.set(parent, key)
|
|
98
|
+
}
|
|
99
|
+
const text = headingTextOf(section, (id) => document.getElementById(id))
|
|
100
|
+
rows.push({ section, containerKey: key, headingText: text ?? '' })
|
|
101
|
+
}
|
|
102
|
+
const verdicts = classifyModelGroups(rows)
|
|
103
|
+
rows.forEach((row, i) => applyVerdict(row.section, verdicts[i]))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// childList + subtree catches mounted/unmounted/re-parented groups,
|
|
107
|
+
// characterData catches heading texts changing in place. Attributes are
|
|
108
|
+
// deliberately unwatched: this effect is their only writer.
|
|
109
|
+
const observer = new MutationObserver((mutations) => {
|
|
110
|
+
for (const mutation of mutations) {
|
|
111
|
+
if (touchesGroup(mutation)) {
|
|
112
|
+
scan()
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
observer.observe(document.body, { childList: true, subtree: true, characterData: true })
|
|
118
|
+
// The initial paint may already hold groups (session restored under an
|
|
119
|
+
// open menu): stamp them synchronously at install, like every observer
|
|
120
|
+
// effect here does.
|
|
121
|
+
scan()
|
|
122
|
+
|
|
123
|
+
return () => {
|
|
124
|
+
observer.disconnect()
|
|
125
|
+
// Undo every stamp so the host DOM reads exactly as before the effect
|
|
126
|
+
// ran — the CSS rules key on the stamp, so this un-hides everything.
|
|
127
|
+
for (const section of document.querySelectorAll(`${GROUP_SELECTOR}[${STAMP}]`)) {
|
|
128
|
+
section.removeAttribute(STAMP)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}, 'dsh-zen-remote: model group side')
|
|
132
|
+
}
|