/** * dsh-ui-tweaks — session-row delete row (browser half). * * One entry of the host's session "..." menu in the left sidebar, the * `sidebar.workspaces.session.menu.item` slot declared by * `@deepseek-ai/dsh-client-ui-workspace`. The slot is a `list` whose owner * passes `{ sessionId, displayTitle }` and whose declared hooks bind * `useMenuOpenState`; the shipped rows (pin 100, rename 200, fork 300, * archive 400) are ordinary entries of the same list, so this row lands after * them by its own `order` and joins the menu's DOM-driven keyboard walk as a * plain `role="menuitem"` button. * * The action is the SAME permanent delete the Archive settings section * exposes: the host has no session-delete API at any layer (client services, * RPC, the persistence seam), so the row posts to the plugin's own same-origin * archive route (`/_dsh/ui-tweaks/archive`, `{ action: 'delete' }`). * * Two clicks, no dialog: the first arms the row ("确认删除?"), the second one * deletes. The armed state expires after {@link CONFIRM_TIMEOUT_MS}, mirroring * the Archive panel's own two-step delete. A running session is refused by the * server (`session-live`) — the menu then stays OPEN and the reason is printed * under the row, because a closed menu could not show it. * * The row reproduces `ui-primitives`' `MenuItemButton` markup and styling * (that package is outside this plugin's `dsh.client.inject` whitelist, so the * recipe is re-implemented from `Menu.module.css` with the same theme tokens). * @module dsh-ui-tweaks/client/session-menu */ import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'; import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'; import type { SettingsClient } from './index.tsx'; /** Registration id: package-namespaced, so it never shadows a shipped row. */ export declare const SESSION_DELETE_MENU_ID = "dsh-ui-tweaks/session-delete"; /** Order after the shipped rows (pin 100 / rename 200 / fork 300 / archive 400). */ export declare const SESSION_DELETE_MENU_ORDER = 500; /** Business share this entry's own inject face hands the component. */ export interface SessionDeleteInjected { /** Injected: the ui-tweaks settings store (reads `archiveManagerEnabled`). */ controller: SettingsClient; /** Injected: the client sessions service, re-pulled after a delete. */ sessionsService: ISessions; } /** Slot props: owner share + the bound menu hook + this entry's inject share + locale. */ export type SessionDeleteMenuProps = PropsRuntime<'sidebar.workspaces.session.menu.item'> & InjectFace & PropsLocale<'ui-tweaks'>; export declare const SESSION_MENU_CSS = "\n/* One row of the host's session \"...\" menu, matching ui-primitives'\n * MenuItemButton markup (Menu.module.css .itemWrap/.item/.itemIcon/.itemLabel)\n * so this row is indistinguishable from the shipped pin / rename / fork /\n * archive rows around it. */\n.dut-sdm-wrap{position:relative}\n.dut-sdm-item{display:flex;align-items:center;gap:6px;width:100%;min-height:34px;padding:6px 8px;border:none;border-radius:var(--dsw-radius-md);background:transparent;cursor:pointer;font:inherit;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary);text-align:left}\n.dut-sdm-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dut-sdm-item:focus-visible:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);outline:none}\n.dut-sdm-item:disabled{opacity:.4;cursor:not-allowed}\n.dut-sdm-icon{display:inline-flex;flex:none;width:14px;height:14px;align-items:center;justify-content:center;color:var(--dsw-alias-menu-icon)}\n.dut-sdm-icon svg{width:14px;height:14px}\n.dut-sdm-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dut-sdm-sep{height:.5px;margin:3px 2px;background:var(--dsw-alias-border-l2)}\n/* Destructive row: the host's own danger recipe (Menu.module.css .danger). */\n.dut-sdm-danger{color:var(--dsw-alias-state-error-primary)}\n.dut-sdm-danger .dut-sdm-icon{color:var(--dsw-alias-state-error-primary)}\n.dut-sdm-danger:hover:not(:disabled),.dut-sdm-danger:focus-visible:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}\n/* Inline refusal: the menu stays open when the delete is rejected, so the\n * reason has to live in the row that was clicked (the icon column's width plus\n * the row's padding indents it under the label). */\n.dut-sdm-note{padding:0 8px 6px 28px;font-size:11px;line-height:15px;color:var(--dsw-alias-state-error-primary)}\n"; /** Install the session-menu stylesheet once (idempotent); returns the disposer. */ export declare function installSessionMenuStyles(): () => void; /** * One "删除会话" row: first click arms the confirmation, the second deletes. * A rejection keeps the menu open and prints the reason under the row. * @param props - owner share, the bound menu-open hook, the injected share and the translator. * @returns the menu row (plus a hairline before it and the refusal note when present). */ export declare function SessionDeleteMenuItem({ sessionId, useMenuOpenState, sessionsService, t }: SessionDeleteMenuProps): import("react").JSX.Element; //# sourceMappingURL=session-menu.d.ts.map