dsh-zen-remote 1.0.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/AGENTS.md +51 -0
- package/LICENSE +38 -0
- package/README.md +237 -0
- package/assets/home.png +0 -0
- package/assets/info.png +0 -0
- package/assets/pairing.png +0 -0
- package/assets/session.png +0 -0
- package/assets/sheet.png +0 -0
- package/cordis.patch.yml +17 -0
- package/cordis.patch.yml.example +16 -0
- package/docs/interface.md +200 -0
- package/docs/remote-access.en.md +335 -0
- package/docs/remote-access.md +422 -0
- package/dsh-push.mjs +213 -0
- package/lan-gate.mjs +78 -0
- package/lib/client.js +6615 -0
- package/lib/index.js +310 -0
- package/lib/index.js.map +1 -0
- package/lib/lan-gate-server.cjs +626 -0
- package/lib/types/client/MobileAttachButton.d.ts +25 -0
- package/lib/types/client/MobileAttachButton.d.ts.map +1 -0
- package/lib/types/client/MobileAttachChips.d.ts +32 -0
- package/lib/types/client/MobileAttachChips.d.ts.map +1 -0
- package/lib/types/client/MobileDrawerFooter.d.ts +21 -0
- package/lib/types/client/MobileDrawerFooter.d.ts.map +1 -0
- package/lib/types/client/MobileHome.d.ts +24 -0
- package/lib/types/client/MobileHome.d.ts.map +1 -0
- package/lib/types/client/MobileHomeChips.d.ts +76 -0
- package/lib/types/client/MobileHomeChips.d.ts.map +1 -0
- package/lib/types/client/MobileNavOverlay.d.ts +15 -0
- package/lib/types/client/MobileNavOverlay.d.ts.map +1 -0
- package/lib/types/client/MobileNavToggle.d.ts +18 -0
- package/lib/types/client/MobileNavToggle.d.ts.map +1 -0
- package/lib/types/client/MobileSessionHeader.d.ts +58 -0
- package/lib/types/client/MobileSessionHeader.d.ts.map +1 -0
- package/lib/types/client/MobileSessionInfo.d.ts +41 -0
- package/lib/types/client/MobileSessionInfo.d.ts.map +1 -0
- package/lib/types/client/attach-upload.d.ts +78 -0
- package/lib/types/client/attach-upload.d.ts.map +1 -0
- package/lib/types/client/chips-store.d.ts +13 -0
- package/lib/types/client/chips-store.d.ts.map +1 -0
- package/lib/types/client/debug.d.ts +9 -0
- package/lib/types/client/debug.d.ts.map +1 -0
- package/lib/types/client/effects/aionui-compat.d.ts +4 -0
- package/lib/types/client/effects/aionui-compat.d.ts.map +1 -0
- package/lib/types/client/effects/gestures.d.ts +7 -0
- package/lib/types/client/effects/gestures.d.ts.map +1 -0
- package/lib/types/client/effects/header-status.d.ts +15 -0
- package/lib/types/client/effects/header-status.d.ts.map +1 -0
- package/lib/types/client/effects/phone-chrome.d.ts +106 -0
- package/lib/types/client/effects/phone-chrome.d.ts.map +1 -0
- package/lib/types/client/effects/turn-fold.d.ts +25 -0
- package/lib/types/client/effects/turn-fold.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +58 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/nav-store.d.ts +73 -0
- package/lib/types/client/nav-store.d.ts.map +1 -0
- package/lib/types/client/session-dot.d.ts +12 -0
- package/lib/types/client/session-dot.d.ts.map +1 -0
- package/lib/types/client/styles/base.css.d.ts +2 -0
- package/lib/types/client/styles/base.css.d.ts.map +1 -0
- package/lib/types/client/styles/chips.css.d.ts +2 -0
- package/lib/types/client/styles/chips.css.d.ts.map +1 -0
- package/lib/types/client/styles/compat.css.d.ts +2 -0
- package/lib/types/client/styles/compat.css.d.ts.map +1 -0
- package/lib/types/client/styles/composer.css.d.ts +2 -0
- package/lib/types/client/styles/composer.css.d.ts.map +1 -0
- package/lib/types/client/styles/header.css.d.ts +2 -0
- package/lib/types/client/styles/header.css.d.ts.map +1 -0
- package/lib/types/client/styles/home.css.d.ts +2 -0
- package/lib/types/client/styles/home.css.d.ts.map +1 -0
- package/lib/types/client/styles/index.d.ts +15 -0
- package/lib/types/client/styles/index.d.ts.map +1 -0
- package/lib/types/client/styles/info.css.d.ts +2 -0
- package/lib/types/client/styles/info.css.d.ts.map +1 -0
- package/lib/types/client/styles/layout.css.d.ts +2 -0
- package/lib/types/client/styles/layout.css.d.ts.map +1 -0
- package/lib/types/client/styles/misc.css.d.ts +2 -0
- package/lib/types/client/styles/misc.css.d.ts.map +1 -0
- package/lib/types/client/styles/turn-fold.css.d.ts +2 -0
- package/lib/types/client/styles/turn-fold.css.d.ts.map +1 -0
- package/lib/types/index.d.ts +83 -0
- package/lib/types/index.d.ts.map +1 -0
- package/llms.txt +20 -0
- package/package.json +128 -0
- package/pwa/app.css +95 -0
- package/pwa/icons/icon-192.png +0 -0
- package/pwa/icons/icon-512.png +0 -0
- package/pwa/icons/icon-maskable-512.png +0 -0
- package/pwa/icons/icon-maskable.svg +1 -0
- package/pwa/icons/icon.svg +1 -0
- package/pwa/inject.js +190 -0
- package/pwa/manifest.json +29 -0
- package/pwa/offline.html +38 -0
- package/pwa/sw.js +176 -0
- package/pwa/touch-gestures.js +94 -0
- package/scripts/build-client.mjs +101 -0
- package/scripts/cdp-probe.mjs +64 -0
- package/scripts/check-attach-upload.mjs +99 -0
- package/scripts/check-sunk-viewport.mjs +33 -0
- package/scripts/check-upload-endpoint.mjs +168 -0
- package/src/client/MobileAttachButton.tsx +125 -0
- package/src/client/MobileAttachChips.tsx +85 -0
- package/src/client/MobileDrawerFooter.tsx +56 -0
- package/src/client/MobileHome.tsx +348 -0
- package/src/client/MobileHomeChips.tsx +426 -0
- package/src/client/MobileNavOverlay.tsx +279 -0
- package/src/client/MobileNavToggle.tsx +52 -0
- package/src/client/MobileSessionHeader.tsx +242 -0
- package/src/client/MobileSessionInfo.tsx +303 -0
- package/src/client/attach-upload.ts +140 -0
- package/src/client/chips-store.ts +41 -0
- package/src/client/debug.ts +253 -0
- package/src/client/effects/aionui-compat.ts +183 -0
- package/src/client/effects/gestures.ts +265 -0
- package/src/client/effects/header-status.ts +30 -0
- package/src/client/effects/phone-chrome.ts +265 -0
- package/src/client/effects/turn-fold.ts +258 -0
- package/src/client/index.tsx +227 -0
- package/src/client/locales.ts +109 -0
- package/src/client/nav-store.ts +78 -0
- package/src/client/session-dot.ts +17 -0
- package/src/client/styles/base.css.ts +167 -0
- package/src/client/styles/chips.css.ts +224 -0
- package/src/client/styles/compat.css.ts +681 -0
- package/src/client/styles/composer.css.ts +504 -0
- package/src/client/styles/header.css.ts +368 -0
- package/src/client/styles/home.css.ts +477 -0
- package/src/client/styles/index.ts +25 -0
- package/src/client/styles/info.css.ts +238 -0
- package/src/client/styles/layout.css.ts +501 -0
- package/src/client/styles/misc.css.ts +128 -0
- package/src/client/styles/turn-fold.css.ts +106 -0
- package/src/index.ts +343 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the composer attachment seat. */
|
|
4
|
+
export type MobileAttachButtonProps = PropsRuntime<'conversation.input.left'> & PropsLocale<typeof NS>;
|
|
5
|
+
/**
|
|
6
|
+
* Composer attachment button (S7).
|
|
7
|
+
*
|
|
8
|
+
* Renders into `conversation.input.left`, which CSS orders to the leftmost
|
|
9
|
+
* seat of the phone composer's bottom row (and hides at >= 768px, where the
|
|
10
|
+
* official picker on the host machine is the right answer). Tapping it opens
|
|
11
|
+
* the CLIENT's picker — no `accept` attribute on purpose, so iOS offers the
|
|
12
|
+
* full 相册 / 拍照 / 选取文件 sheet rather than one of them.
|
|
13
|
+
*
|
|
14
|
+
* Every picked file takes the SAME path: upload to the node half, then append
|
|
15
|
+
* `@.dsh-uploads/name` to the draft through `inputActions.setDraft` (the
|
|
16
|
+
* official write path — no DOM value poking). S7.1 removed the split that used
|
|
17
|
+
* to send inlineable images straight into the session with `session.prompt`:
|
|
18
|
+
* one behaviour for every attachment, and the user always presses send.
|
|
19
|
+
* MobileAttachChips renders the preview row off those same draft tokens.
|
|
20
|
+
*
|
|
21
|
+
* Files upload one at a time: a phone uplink gains nothing from parallelism
|
|
22
|
+
* and a serial loop keeps the mentions in pick order.
|
|
23
|
+
*/
|
|
24
|
+
export declare function MobileAttachButton({ t, sessionId, useInput, inputActions }: MobileAttachButtonProps): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=MobileAttachButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileAttachButton.d.ts","sourceRoot":"","sources":["../../../src/client/MobileAttachButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,mDAAmD;AACnD,MAAM,MAAM,uBAAuB,GAC/B,YAAY,CAAC,yBAAyB,CAAC,GACvC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAsB1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,uBAAuB,+BAwEnG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the attachment preview row. */
|
|
4
|
+
export type MobileAttachChipsProps = PropsRuntime<'conversation.input.dock'> & PropsLocale<typeof NS>;
|
|
5
|
+
/**
|
|
6
|
+
* Attachment preview row (S7.1), in `conversation.input.dock` — the official
|
|
7
|
+
* full-width row above the composer card, which composer.css.ts already lays
|
|
8
|
+
* out as one horizontally scrollable chip line shared with whatever else docks
|
|
9
|
+
* there (the git branch chip, a todo strip). No DOM injection into the
|
|
10
|
+
* official card.
|
|
11
|
+
*
|
|
12
|
+
* **This component owns no state.** It renders whatever
|
|
13
|
+
* `@.dsh-uploads/...` tokens the draft currently holds, so:
|
|
14
|
+
*
|
|
15
|
+
* - uploading appends a token -> a chip appears;
|
|
16
|
+
* - the × removes the token -> the chip disappears;
|
|
17
|
+
* - the user hand-deleting the text -> the chip disappears;
|
|
18
|
+
* - the official send clearing the draft -> every chip disappears.
|
|
19
|
+
*
|
|
20
|
+
* There is no list to keep in sync and nothing to reconcile on session switch.
|
|
21
|
+
* The only side state is the preview-URL map in attach-upload.ts, and the
|
|
22
|
+
* effect below is what keeps it honest: anything no longer mentioned gets its
|
|
23
|
+
* object URL revoked.
|
|
24
|
+
*
|
|
25
|
+
* An image chip is a 48px tile; anything else (and any image whose preview did
|
|
26
|
+
* not survive, see below) is a name pill. The `<img>` is stacked ON TOP of the
|
|
27
|
+
* paperclip rather than swapped for it, so a format the engine cannot decode —
|
|
28
|
+
* HEIC everywhere except WebKit — just fails to paint and reveals the icon,
|
|
29
|
+
* with no error state to track.
|
|
30
|
+
*/
|
|
31
|
+
export declare function MobileAttachChips({ t, useInput, inputActions }: MobileAttachChipsProps): import("react").JSX.Element | null;
|
|
32
|
+
//# sourceMappingURL=MobileAttachChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileAttachChips.d.ts","sourceRoot":"","sources":["../../../src/client/MobileAttachChips.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAUjC,iDAAiD;AACjD,MAAM,MAAM,sBAAsB,GAC9B,YAAY,CAAC,yBAAyB,CAAC,GACvC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,sBAAsB,sCAwCtF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the sidebar footer action entry. */
|
|
4
|
+
export interface MobileDrawerFooterProps extends PropsRuntime<'sidebar.footer.action'>, PropsLocale<typeof NS> {
|
|
5
|
+
/** Bound ctx.sessionLogDownload.download() for the current session. */
|
|
6
|
+
downloadSessionLog: (sessionId: string) => void;
|
|
7
|
+
/** Bound ctx.layout.toggleSidebar(): the Files sheet closes the drawer. */
|
|
8
|
+
toggleSidebar: () => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Mobile-only drawer footer actions, relocated from the session header to the
|
|
12
|
+
* drawer footer (beside Settings):
|
|
13
|
+
* - Files: opens the dsh-web-ui aionui explorer as a floating bottom sheet
|
|
14
|
+
* (the explorer column is hidden on mobile until this marker is set, so
|
|
15
|
+
* the suite's own persisted-expanded state can never cover the UI on load).
|
|
16
|
+
* - Session log: the official session-log-export controller, so the
|
|
17
|
+
* progress/result dialog is shared with the desktop flow.
|
|
18
|
+
* Hidden entirely on wide screens (CSS media query).
|
|
19
|
+
*/
|
|
20
|
+
export declare function MobileDrawerFooter({ useSessions, downloadSessionLog, toggleSidebar, t }: MobileDrawerFooterProps): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=MobileDrawerFooter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileDrawerFooter.d.ts","sourceRoot":"","sources":["../../../src/client/MobileDrawerFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,sDAAsD;AACtD,MAAM,WAAW,uBAAwB,SAAQ,YAAY,CAAC,uBAAuB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IAC5G,uEAAuE;IACvE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,2EAA2E;IAC3E,aAAa,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,uBAAuB,+BAiChH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { SessionId, WorkspaceId } from '@deepseek-ai/dsh-client-runtime/client';
|
|
3
|
+
import { NS } from './locales.ts';
|
|
4
|
+
import type { createNavStore } from './nav-store.ts';
|
|
5
|
+
/** Full props for the phone home screen (shell.overlay entry). */
|
|
6
|
+
export type MobileHomeProps = PropsRuntime<'shell.overlay'> & PropsStore<ReturnType<typeof createNavStore>> & PropsLocale<typeof NS> & {
|
|
7
|
+
/** Bound ctx.sessions.open(id). */
|
|
8
|
+
openSession: (id: SessionId) => void;
|
|
9
|
+
/** Bound ctx.workspaces.startSession(workspaceId?). */
|
|
10
|
+
startSession: (workspaceId?: WorkspaceId) => void;
|
|
11
|
+
/** Bound ctx.sessionLogDownload.download() — the session-log chip (S5). */
|
|
12
|
+
downloadSessionLog: (id: SessionId) => void;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Phone home screen: the full-screen session list that owns the first level
|
|
16
|
+
* of the page stack. Renders nothing at or above 768px — the tablet drawer
|
|
17
|
+
* and the desktop layout stay exactly as they were.
|
|
18
|
+
*
|
|
19
|
+
* All data comes from the standard kit (`useSessions` / `useWorkspaces`) and
|
|
20
|
+
* all navigation from the injected official actions; nothing here reads the
|
|
21
|
+
* official DOM.
|
|
22
|
+
*/
|
|
23
|
+
export declare function MobileHome({ useSessions, useWorkspaces, useStore, actions, openSession, startSession, downloadSessionLog, t, }: MobileHomeProps): import("react").JSX.Element | null;
|
|
24
|
+
//# sourceMappingURL=MobileHome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileHome.d.ts","sourceRoot":"","sources":["../../../src/client/MobileHome.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAS7F,OAAO,KAAK,EAAE,SAAS,EAAkB,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpG,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAMpD,kEAAkE;AAClE,MAAM,MAAM,eAAe,GACvB,YAAY,CAAC,eAAe,CAAC,GAC7B,UAAU,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,GAC7C,WAAW,CAAC,OAAO,EAAE,CAAC,GACtB;IACA,mCAAmC;IACnC,WAAW,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACpC,uDAAuD;IACvD,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACjD,2EAA2E;IAC3E,kBAAkB,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;CAC5C,CAAA;AAuEH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,OAAO,EACP,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,CAAC,GACF,EAAE,eAAe,sCAmOjB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Translate } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { MobileNavKey } from './locales.ts';
|
|
3
|
+
/** One icon component's minimal shared shape (every `@deepseek-ai/dsh-client-ui-primitives` icon accepts `size`, regardless of the fixed number in its own name — see e.g. IconDownloadOutline16 used at size 14 elsewhere in this codebase). */
|
|
4
|
+
type IconFC = (props: {
|
|
5
|
+
size?: number;
|
|
6
|
+
}) => React.JSX.Element;
|
|
7
|
+
/**
|
|
8
|
+
* One home-screen chip's static registration (S5). `selector` is the
|
|
9
|
+
* stable, non-hashed DOM anchor for the plugin's REAL entry button — the
|
|
10
|
+
* chip never reimplements the target feature, it just "代点" (synthetic
|
|
11
|
+
* `.click()`, bypasses hit-testing per the S2.1 precedent in AGENTS.md) the
|
|
12
|
+
* button the plugin itself already renders elsewhere in the tree, exactly
|
|
13
|
+
* like MobileSessionHeader's Chat/Trajectory tab click and the workbench
|
|
14
|
+
* button's `[data-dsh-better-sidebar] button[class$="_toggleButton"]`.
|
|
15
|
+
* `selector: null` marks the one chip (session log) whose availability and
|
|
16
|
+
* action come from injected props instead of a DOM probe — it is a
|
|
17
|
+
* first-party dsh-session-log-export service call, not a third-party
|
|
18
|
+
* plugin's button.
|
|
19
|
+
*/
|
|
20
|
+
export interface ChipDef {
|
|
21
|
+
id: string;
|
|
22
|
+
label: MobileNavKey;
|
|
23
|
+
Icon: IconFC;
|
|
24
|
+
selector: string | null;
|
|
25
|
+
}
|
|
26
|
+
/** Static chip registry (S5). Order here is the default row order. */
|
|
27
|
+
export declare const CHIP_DEFS: readonly ChipDef[];
|
|
28
|
+
/** Full props for the chip row. */
|
|
29
|
+
export interface MobileHomeChipsProps {
|
|
30
|
+
t: Translate<MobileNavKey>;
|
|
31
|
+
sessionId: string | undefined;
|
|
32
|
+
downloadSessionLog: (id: string) => void;
|
|
33
|
+
onCustomize: () => void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Plugin-entry chips row (S5): a horizontally-scrolling line of 34px pills
|
|
37
|
+
* between the workspace title and the session list, plus a trailing "···"
|
|
38
|
+
* that opens the customize sheet (MobileHomeChipsSheetBody below, rendered
|
|
39
|
+
* by MobileHome inside its existing home-sheet chrome). Every chip renders
|
|
40
|
+
* only when both true: the user has not hidden it (useChipsPrefs) AND its
|
|
41
|
+
* target actually exists right now (useDetectedIds / sessionId) — an
|
|
42
|
+
* uninstalled plugin's chip never appears, matching the plan's "按用户实装
|
|
43
|
+
* 插件逐个接入口". Chips beyond {@link CHIP_DEFS} (S5.1: any OTHER plugin's
|
|
44
|
+
* own sidebar-footer-action entry) are auto-discovered by
|
|
45
|
+
* {@link useHarvestedChips} and appended after the hand-registered ones —
|
|
46
|
+
* "装了新插件、chips 行零代码长出对应入口".
|
|
47
|
+
*/
|
|
48
|
+
export declare function MobileHomeChips({ t, sessionId, downloadSessionLog, onCustomize }: MobileHomeChipsProps): import("react").JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* Customize-sheet body (S5, existence filter added 2026-08-17 real-device
|
|
51
|
+
* follow-up): one toggle row per chip whose target actually exists —
|
|
52
|
+
* `useDetectedIds()`, the SAME live probe `MobileHomeChips` uses for the row
|
|
53
|
+
* itself. Originally listed every `CHIP_DEFS` entry unconditionally, on the
|
|
54
|
+
* theory that a not-yet-installed plugin's toggle should still be
|
|
55
|
+
* pre-settable; real-device feedback was that this instead surfaces dead
|
|
56
|
+
* switches for plugins the user never installed (taskboard/ssh). Detection
|
|
57
|
+
* is a live MutationObserver subscription, so installing the plugin later
|
|
58
|
+
* still makes its toggle appear with no reload needed — "将来装了自动出现"
|
|
59
|
+
* survives the change, it just also stops showing before that. `sessionLog`
|
|
60
|
+
* (selector: null) is exempt: its existence is a runtime session-scope
|
|
61
|
+
* question, not a plugin-install question, so it always lists regardless of
|
|
62
|
+
* whether a session happens to be open right now. Stale prefs entries for a
|
|
63
|
+
* chip that no longer renders (e.g. an uninstalled plugin's old toggle
|
|
64
|
+
* value) are simply never read — `isChipEnabled`/`toggleChip`
|
|
65
|
+
* (chips-store.ts) key off `CHIP_DEFS` ids already, so leftover keys in the
|
|
66
|
+
* persisted object are inert, not an error. Rendered by MobileHome inside
|
|
67
|
+
* the SAME home-sheet-layer/mask/sheet chrome the workspace switcher uses
|
|
68
|
+
* (S6's drag-to-close and mask-click-close already bind generically to
|
|
69
|
+
* `[data-mobile-nav="home-sheet"]`, so this second use needs no new gesture
|
|
70
|
+
* wiring — see styles/chips.css.ts).
|
|
71
|
+
*/
|
|
72
|
+
export declare function MobileHomeChipsSheetBody({ t }: {
|
|
73
|
+
t: Translate<MobileNavKey>;
|
|
74
|
+
}): import("react").JSX.Element;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=MobileHomeChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileHomeChips.d.ts","sourceRoot":"","sources":["../../../src/client/MobileHomeChips.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGhD,iPAAiP;AACjP,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,CAAA;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AA0CD,sEAAsE;AACtE,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EAMvC,CAAA;AAoND,mCAAmC;AACnC,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,oBAAoB,+BAuCtG;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE;IAAE,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;CAAE,+BA4C7E"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the shell overlay entry. */
|
|
4
|
+
export interface MobileNavOverlayProps extends PropsRuntime<'shell.overlay'>, PropsLocale<typeof NS> {
|
|
5
|
+
/** Bound ctx.layout.toggleSidebar(). */
|
|
6
|
+
toggleSidebar: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Mobile shell overlay: owns the `data-mobile-nav` marker on the AppFrame
|
|
10
|
+
* element (the CSS restructure keys off it), mirrors the frame's collapsed
|
|
11
|
+
* state into React state, and renders the dimmed backdrop plus a floating
|
|
12
|
+
* directory button for the hero/blank phases that have no session header.
|
|
13
|
+
*/
|
|
14
|
+
export declare function MobileNavOverlay({ toggleSidebar, t }: MobileNavOverlayProps): import("react").JSX.Element | null;
|
|
15
|
+
//# sourceMappingURL=MobileNavOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileNavOverlay.d.ts","sourceRoot":"","sources":["../../../src/client/MobileNavOverlay.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,8CAA8C;AAC9C,MAAM,WAAW,qBAAsB,SAAQ,YAAY,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IAClG,wCAAwC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAA;CAC1B;AAmCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,qBAAqB,sCAoO3E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the session-header directory toggle. */
|
|
4
|
+
export interface MobileNavToggleProps extends PropsRuntime<'conversation.session.header.actions'>, PropsLocale<typeof NS> {
|
|
5
|
+
/** Bound ctx.layout.toggleSidebar(). */
|
|
6
|
+
toggleSidebar: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Mobile-only icon buttons next to the session title:
|
|
10
|
+
* - toggle: opens the directory drawer on narrow screens.
|
|
11
|
+
* - files: toggles the dsh-web-ui explorer sheet directly — one tap opens,
|
|
12
|
+
* a second tap closes it, no drawer round-trip. (The drawer footer keeps
|
|
13
|
+
* a Files entry for the hero/blank phases where this header does not
|
|
14
|
+
* exist.)
|
|
15
|
+
* Hidden entirely on wide screens (CSS media query).
|
|
16
|
+
*/
|
|
17
|
+
export declare function MobileNavToggle({ toggleSidebar, t }: MobileNavToggleProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=MobileNavToggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileNavToggle.d.ts","sourceRoot":"","sources":["../../../src/client/MobileNavToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,0DAA0D;AAC1D,MAAM,WAAW,oBAAqB,SAAQ,YAAY,CAAC,qCAAqC,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IACvH,wCAAwC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,oBAAoB,+BAgCzE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** Full props for the session header's back button + view-switch row. */
|
|
4
|
+
export type MobileHeaderActionsProps = PropsRuntime<'conversation.session.header.actions'> & PropsLocale<typeof NS>;
|
|
5
|
+
/** One tab read off the official (now visually hidden) Chat/Trajectory tablist. */
|
|
6
|
+
export interface ViewTabInfo {
|
|
7
|
+
label: string;
|
|
8
|
+
active: boolean;
|
|
9
|
+
el: HTMLButtonElement;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Reads the official session-header tablist by role/aria only (no hashed
|
|
13
|
+
* classes) — the plan's one sanctioned official-DOM read: ChatStore's view
|
|
14
|
+
* selection has no public setter (design doc Appendix C), so switching
|
|
15
|
+
* views means clicking the official tab button ourselves.
|
|
16
|
+
*
|
|
17
|
+
* Exported: effects/gestures.ts (S6) reuses this exact read for the
|
|
18
|
+
* content-area swipe gesture instead of re-querying the tablist a second
|
|
19
|
+
* way — it runs outside React (a document-level touch listener), so it
|
|
20
|
+
* needs the plain function, not the {@link useViewTabs} hook below.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readViewTabs(): ViewTabInfo[];
|
|
23
|
+
/**
|
|
24
|
+
* Live view-tab mirror. The tablist mounts/unmounts with the session header
|
|
25
|
+
* and its `aria-selected` flips on every view switch (ours or the suite's
|
|
26
|
+
* own), so a MutationObserver — not a one-time read — keeps the mirror
|
|
27
|
+
* current. Scoped to `document.body` like the existing aionui-compat
|
|
28
|
+
* effects (styles/aionui-compat.ts): the tablist itself may not exist yet
|
|
29
|
+
* at mount time.
|
|
30
|
+
*
|
|
31
|
+
* Exported: MobileSessionInfo.tsx (S4) reuses this exact hook for the info
|
|
32
|
+
* sheet's Chat/Trajectory segmented control instead of re-reading the
|
|
33
|
+
* tablist a second way.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useViewTabs(): ViewTabInfo[];
|
|
36
|
+
/**
|
|
37
|
+
* Session header, left lane: the back button (returns the phone page stack
|
|
38
|
+
* to the session list) plus the "current view + dots" row that mirrors the
|
|
39
|
+
* hidden official tablist. Both render unconditionally; CSS
|
|
40
|
+
* (styles/header.css.ts) keeps them hidden at >= 768px so the tablet drawer
|
|
41
|
+
* and the desktop layout stay exactly as they were.
|
|
42
|
+
*/
|
|
43
|
+
export declare function MobileHeaderActions({ t }: MobileHeaderActionsProps): import("react").JSX.Element;
|
|
44
|
+
/** Full props for the session header's right-edge utility buttons. */
|
|
45
|
+
export type MobileHeaderUtilitiesProps = PropsRuntime<'conversation.session.header.utilities'> & PropsLocale<typeof NS>;
|
|
46
|
+
/**
|
|
47
|
+
* Session header, right lane: the session-info entry (S4 owns the actual
|
|
48
|
+
* sheet — this fires a hook event for it to pick up) and the workbench
|
|
49
|
+
* entry, which triggers dsh-better-sidebar's own toggle. There is no public
|
|
50
|
+
* API for "open the panel" (BetterSidebarService.openTab only auto-expands
|
|
51
|
+
* for a content open, not a bare type-only open), so this clicks the
|
|
52
|
+
* plugin's real toggle button through a stable, non-hashed anchor: its root
|
|
53
|
+
* mount marker `[data-dsh-better-sidebar]` plus the `_toggleButton` class
|
|
54
|
+
* suffix (verified live: 2026-08-17). Safe no-op when the plugin, or any
|
|
55
|
+
* other workbench-style plugin sharing that convention, is not installed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function MobileHeaderUtilities({ t }: MobileHeaderUtilitiesProps): import("react").JSX.Element;
|
|
58
|
+
//# sourceMappingURL=MobileSessionHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileSessionHeader.d.ts","sourceRoot":"","sources":["../../../src/client/MobileSessionHeader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAsBjC,yEAAyE;AACzE,MAAM,MAAM,wBAAwB,GAChC,YAAY,CAAC,qCAAqC,CAAC,GACnD,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAE1B,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,EAAE,EAAE,iBAAiB,CAAA;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAQ5C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,IAAI,WAAW,EAAE,CAe3C;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,wBAAwB,+BA+BlE;AAED,sEAAsE;AACtE,MAAM,MAAM,0BAA0B,GAClC,YAAY,CAAC,uCAAuC,CAAC,GACrD,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAE1B;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,CAAC,EAAE,EAAE,0BAA0B,+BAkGtE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { SessionFace, SessionId } from '@deepseek-ai/dsh-client-runtime/client';
|
|
3
|
+
import { NS } from './locales.ts';
|
|
4
|
+
/** Full props for the session-info sheet (header.utilities, second entry). */
|
|
5
|
+
export type MobileSessionInfoProps = PropsRuntime<'conversation.session.header.utilities'> & PropsLocale<typeof NS> & {
|
|
6
|
+
/** Bound ctx.sessions.fork({sessionId}). */
|
|
7
|
+
forkSession: (sessionId: SessionId) => Promise<SessionId>;
|
|
8
|
+
/** Bound ctx.sessions.open(id) — lands on the freshly forked session. */
|
|
9
|
+
openSession: (id: SessionId) => void;
|
|
10
|
+
/** Bound ctx.sessions.binding(id)?.session.rename(title); undefined when the binding is gone. */
|
|
11
|
+
renameSession: (sessionId: SessionId, title: string) => ReturnType<SessionFace['rename']> | undefined;
|
|
12
|
+
/** Bound ctx.workspaces.archiveSession(sessionId). */
|
|
13
|
+
archiveSession: (sessionId: SessionId) => Promise<void>;
|
|
14
|
+
/** Bound ctx.sessionLogDownload.download(sessionId) — owns its own progress/result modal. */
|
|
15
|
+
downloadSessionLog: (sessionId: SessionId) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Session-info sheet: the bottom sheet that gathers everything S3 pulled off
|
|
19
|
+
* the composer (the official stats strip) and everything S2 left out of the
|
|
20
|
+
* header (Chat/Trajectory as a real control, badges, session actions).
|
|
21
|
+
*
|
|
22
|
+
* Registered as a SECOND entry on `conversation.session.header.utilities` —
|
|
23
|
+
* session scope, sibling to the ⓘ button that opens it
|
|
24
|
+
* (MobileSessionHeader.tsx dispatches {@link SESSION_INFO_EVENT}).
|
|
25
|
+
*
|
|
26
|
+
* Mount-point choice (the plan's own tradeoff to weigh): this needs
|
|
27
|
+
* `useProjection`/`sessionId` for the stats grid, and those are
|
|
28
|
+
* session-scope-only standard props — `header.utilities` has them,
|
|
29
|
+
* `shell.overlay` (S1's other option) does not. `shell.overlay` would have
|
|
30
|
+
* gained nothing in exchange (GlobalStandardProps — `useSessions` for the
|
|
31
|
+
* badges/subagent-count — is unconditional on every slot per
|
|
32
|
+
* `PropsRuntime`, so this component gets it here for free too) while
|
|
33
|
+
* running into a real problem: shell.overlay content renders inside the
|
|
34
|
+
* `pI_x6G_overlayLayer`, a z-index:20 stacking context (AGENTS.md), and the
|
|
35
|
+
* composer's own permission/model bottom sheets sit at z:60 — a
|
|
36
|
+
* shell.overlay-hosted info sheet would render BEHIND an open composer
|
|
37
|
+
* menu. Mounting inside the header's own DOM (outside that capped layer)
|
|
38
|
+
* lets this sheet's z-index clear every other phone-shell float.
|
|
39
|
+
*/
|
|
40
|
+
export declare function MobileSessionInfo({ sessionId, useSessions, useProjection, forkSession, openSession, renameSession, archiveSession, downloadSessionLog, t, }: MobileSessionInfoProps): import("react").JSX.Element | null;
|
|
41
|
+
//# sourceMappingURL=MobileSessionInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileSessionInfo.d.ts","sourceRoot":"","sources":["../../../src/client/MobileSessionInfo.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AASjF,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AACpF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAajC,8EAA8E;AAC9E,MAAM,MAAM,sBAAsB,GAC9B,YAAY,CAAC,uCAAuC,CAAC,GACrD,WAAW,CAAC,OAAO,EAAE,CAAC,GACtB;IACA,4CAA4C;IAC5C,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACzD,yEAAyE;IACzE,WAAW,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACpC,iGAAiG;IACjG,aAAa,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAA;IACrG,sDAAsD;IACtD,cAAc,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,6FAA6F;IAC7F,kBAAkB,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5D,CAAA;AAsCH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,CAAC,GACF,EAAE,sBAAsB,sCAgMxB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S7 attachment plumbing: the string math plus the thumbnail registry.
|
|
3
|
+
*
|
|
4
|
+
* Kept free of React so `scripts/check-attach-upload.mjs` can import it
|
|
5
|
+
* directly under Node's type stripping.
|
|
6
|
+
*
|
|
7
|
+
* The one idea worth stating up front: **the composer draft is the only state
|
|
8
|
+
* this feature has.** Every attachment is an `@.dsh-uploads/name` token in the
|
|
9
|
+
* draft text, and the chip row is a pure function of that text. Nothing to
|
|
10
|
+
* keep in sync — the user deleting the token by hand, or the official send
|
|
11
|
+
* clearing the draft, makes the chips disappear on their own.
|
|
12
|
+
*/
|
|
13
|
+
/** Exact host route registered by the node half (src/index.ts). */
|
|
14
|
+
export declare const UPLOAD_ROUTE = "/_dsh/mobile-nav/upload";
|
|
15
|
+
/** Workspace-relative directory uploads land in; also the `@` mention prefix. */
|
|
16
|
+
export declare const UPLOAD_DIR = ".dsh-uploads";
|
|
17
|
+
/**
|
|
18
|
+
* The upload URL for one file. Root-relative on purpose: through the
|
|
19
|
+
* gateway half the pairing cookie only rides along same-origin.
|
|
20
|
+
* @param sessionId - target session (its workspace receives the file).
|
|
21
|
+
* @param name - the browser filename; the host sanitizes it again.
|
|
22
|
+
* @returns a root-relative URL.
|
|
23
|
+
*/
|
|
24
|
+
export declare function uploadUrl(sessionId: string, name: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Every attachment mentioned in a draft, in reading order, without repeats.
|
|
27
|
+
* @param draft - the composer draft text.
|
|
28
|
+
* @returns workspace-relative paths (no leading `@`).
|
|
29
|
+
*/
|
|
30
|
+
export declare function mentionsIn(draft: string): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Append one `@path` mention to the draft.
|
|
33
|
+
*
|
|
34
|
+
* Separated from whatever came before by a space (or a newline when the draft
|
|
35
|
+
* already ends in one), and trailed by a space so the next mention does not
|
|
36
|
+
* fuse onto this one — and so {@link draftWithoutMention} can lift it back out
|
|
37
|
+
* without leaving a double space behind.
|
|
38
|
+
* @param draft - the current draft text.
|
|
39
|
+
* @param relPath - workspace-relative path returned by the upload route.
|
|
40
|
+
* @returns the next draft.
|
|
41
|
+
*/
|
|
42
|
+
export declare function draftWithMention(draft: string, relPath: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Remove one `@path` mention from the draft — what a chip's × does.
|
|
45
|
+
*
|
|
46
|
+
* The file itself stays on disk: it is a few KB in a directory the user can
|
|
47
|
+
* clear whenever, and deleting it would need a second host route whose only
|
|
48
|
+
* job is destruction.
|
|
49
|
+
* @param draft - the current draft text.
|
|
50
|
+
* @param relPath - the attachment to drop.
|
|
51
|
+
* @returns the next draft; whitespace-only collapses to empty.
|
|
52
|
+
*/
|
|
53
|
+
export declare function draftWithoutMention(draft: string, relPath: string): string;
|
|
54
|
+
/** The filename part of a workspace-relative path. */
|
|
55
|
+
export declare function leafOf(relPath: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Shorten a filename from the MIDDLE, so both the stem and the extension stay
|
|
58
|
+
* readable (CSS `text-overflow` can only cut one end).
|
|
59
|
+
* @param text - the filename.
|
|
60
|
+
* @param max - budget in characters, including the ellipsis.
|
|
61
|
+
* @returns the original when it fits, else head + `…` + tail.
|
|
62
|
+
*/
|
|
63
|
+
export declare function middleEllipsis(text: string, max?: number): string;
|
|
64
|
+
/**
|
|
65
|
+
* Register a preview for an uploaded image.
|
|
66
|
+
* @param relPath - workspace-relative path the file landed on.
|
|
67
|
+
* @param blob - the browser-owned file.
|
|
68
|
+
*/
|
|
69
|
+
export declare function rememberThumbnail(relPath: string, blob: Blob): void;
|
|
70
|
+
/** The preview URL for one attachment, or undefined when there is none. */
|
|
71
|
+
export declare function thumbnailFor(relPath: string): string | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Revoke and forget every preview whose attachment is no longer in the draft.
|
|
74
|
+
* Called whenever the chip row re-renders, so a removed chip frees its blob.
|
|
75
|
+
* @param keep - the attachments still mentioned.
|
|
76
|
+
*/
|
|
77
|
+
export declare function releaseThumbnailsExcept(keep: readonly string[]): void;
|
|
78
|
+
//# sourceMappingURL=attach-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-upload.d.ts","sourceRoot":"","sources":["../../../src/client/attach-upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mEAAmE;AACnE,eAAO,MAAM,YAAY,4BAA4B,CAAA;AAErD,iFAAiF;AACjF,eAAO,MAAM,UAAU,iBAAiB,CAAA;AAWxC;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAI1E;AAED,sDAAsD;AACtD,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,CAI7D;AAaD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAKnE;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAOrE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Home-screen chip visibility, keyed by {@link ChipDef.id} (MobileHomeChips.tsx).
|
|
3
|
+
* A missing key means "shown" — new chip ids need no migration step, they
|
|
4
|
+
* just default enabled the first time they exist.
|
|
5
|
+
*/
|
|
6
|
+
export type ChipPrefs = Record<string, boolean>;
|
|
7
|
+
/** @param prefs - current snapshot. @param id - chip id. @returns whether the chip should render (default true). */
|
|
8
|
+
export declare function isChipEnabled(prefs: ChipPrefs, id: string): boolean;
|
|
9
|
+
/** Flip one chip's visibility and persist it. @param id - chip id. */
|
|
10
|
+
export declare function toggleChip(id: string): void;
|
|
11
|
+
/** Live chip-prefs mirror (React 18 tearing-safe external store read). */
|
|
12
|
+
export declare function useChipsPrefs(): ChipPrefs;
|
|
13
|
+
//# sourceMappingURL=chips-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chips-store.d.ts","sourceRoot":"","sources":["../../../src/client/chips-store.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAiB/C,oHAAoH;AACpH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAI3C;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,IAAI,SAAS,CAEzC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
+
/**
|
|
3
|
+
* Debug badge — ?mobile-nav-debug=1
|
|
4
|
+
* Renders a live state overlay (URL, viewport, media queries, shell chrome,
|
|
5
|
+
* aionui columns, genui cards, captured errors) so a phone-side repro can be
|
|
6
|
+
* diagnosed without guessing. No-op unless the query param is present.
|
|
7
|
+
*/
|
|
8
|
+
export declare function installDebugBadge(ctx: ClientContext): void;
|
|
9
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/client/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAC3E;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAqP1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aionui-compat.d.ts","sourceRoot":"","sources":["../../../../src/client/effects/aionui-compat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAE3E,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAmL5D"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
+
/** S6: the two-gesture set — left-edge swipe-back and sheet drag-to-close.
|
|
3
|
+
* Both install/uninstall their own document listeners on the phone
|
|
4
|
+
* breakpoint's matchMedia change, so at >= 768px this is a true no-op (no
|
|
5
|
+
* listeners attached at all), matching every other effect in this file. */
|
|
6
|
+
export declare function installGestures(ctx: ClientContext): void;
|
|
7
|
+
//# sourceMappingURL=gestures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gestures.d.ts","sourceRoot":"","sources":["../../../../src/client/effects/gestures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAiQ3E;;;2EAG2E;AAC3E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAGxD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
+
/**
|
|
3
|
+
* Session header running-status dot (S2). No official element exists to
|
|
4
|
+
* reposition (ConversationSessionHeader renders only the crumb title, the
|
|
5
|
+
* actions/utilities slots, and the tablist — dsh-client-ui-conversation
|
|
6
|
+
* lib/client.js:6949-7009), so this reads `ctx.sessions.list` directly
|
|
7
|
+
* (the same feed `useSessions` wraps) and stamps a data attribute the
|
|
8
|
+
* mobile stylesheet turns into a `::after` dot on the title crumb —
|
|
9
|
+
* "read data, self-draw" is the plan's documented fallback for this piece.
|
|
10
|
+
* Kept outside React: the dot must track the CURRENT session regardless of
|
|
11
|
+
* which component the header happens to mount, and a plain attribute +
|
|
12
|
+
* CSS avoids reaching into the official crumb's own DOM subtree.
|
|
13
|
+
*/
|
|
14
|
+
export declare function installHeaderStatusDot(ctx: ClientContext): void;
|
|
15
|
+
//# sourceMappingURL=header-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-status.d.ts","sourceRoot":"","sources":["../../../../src/client/effects/header-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAG3E;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAc/D"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
+
/**
|
|
3
|
+
* Phone chrome: KEEP the system status bar (no fullscreen) and make it
|
|
4
|
+
* blend into the page. On narrow screens:
|
|
5
|
+
* - The viewport meta gains viewport-fit=cover, so env(safe-area-inset-top)
|
|
6
|
+
* is the real status-bar / notch height and the stylesheet can push every
|
|
7
|
+
* surface below it (off notched phones, or in a browser tab where the
|
|
8
|
+
* layout viewport already sits below the status bar, the inset is 0 and
|
|
9
|
+
* nothing shifts).
|
|
10
|
+
* - A theme-color meta tracks the shell background (the official theme is
|
|
11
|
+
* toggled by body[data-ds-dark-theme], which flips --dsw-alias-bg-base):
|
|
12
|
+
* Android then paints the status bar / URL bar with the page's own base
|
|
13
|
+
* color, so the status bar reads as part of the UI instead of a foreign
|
|
14
|
+
* strip. The drawer paints the same strip on iOS / notch displays.
|
|
15
|
+
* - gesturestart is suppressed as the legacy-iOS fallback for double-tap
|
|
16
|
+
* zoom; modern browsers are covered by the stylesheet's
|
|
17
|
+
* touch-action: manipulation (which keeps pan and pinch zoom).
|
|
18
|
+
*/
|
|
19
|
+
export declare function installPhoneChrome(ctx: ClientContext): void;
|
|
20
|
+
/**
|
|
21
|
+
* Does the layout viewport sit shorter than the screen by at least the top
|
|
22
|
+
* inset env() still claims? (S1.2 predicate, wired in S1.3.)
|
|
23
|
+
*
|
|
24
|
+
* Device numbers (iPhone, iOS 26.5, standalone PWA, 393x852): innerHeight
|
|
25
|
+
* 793, env top 59 (= 852 - 793), env bottom 34, frame bottom 793 flush.
|
|
26
|
+
* The same device in a Safari TAB reads innerHeight 695 with every surface
|
|
27
|
+
* flush and every design value correct, which is what rules our own CSS out.
|
|
28
|
+
*
|
|
29
|
+
* What the true-branch means, settled by S1.2 + S1.3 device evidence: the
|
|
30
|
+
* viewport is anchored at screen y=0 and merely cut 59px short at the BOTTOM
|
|
31
|
+
* — not pushed down below the status bar. So the top inset is paid exactly
|
|
32
|
+
* once and must be left alone, while the bottom inset is a lie: the home
|
|
33
|
+
* indicator lives in the dead strip below the page. installSunkInset() acts
|
|
34
|
+
* on that, and only on --mnav-sab.
|
|
35
|
+
*
|
|
36
|
+
* The `envTop > 0` guard is what keeps every other standalone install out:
|
|
37
|
+
* landscape iPhone (top inset 0, the notch moves to left/right), iPad, and
|
|
38
|
+
* Android — where standalone also loses status-bar height off innerHeight but
|
|
39
|
+
* reports env top 0 — all fall through to false. Kept pure so the boundaries
|
|
40
|
+
* are checkable off-device: scripts/check-sunk-viewport.mjs.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isViewportSunkBelowStatusBar(input: {
|
|
43
|
+
standalone: boolean;
|
|
44
|
+
screenHeight: number;
|
|
45
|
+
innerHeight: number;
|
|
46
|
+
envTop: number;
|
|
47
|
+
}): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* iOS standalone-PWA keyboard shrink (S1.2, 2026-08-17) — the ~60px white
|
|
50
|
+
* band under the composer AND under the session list.
|
|
51
|
+
*
|
|
52
|
+
* Documented WebKit defect: the first time the software keyboard opens inside
|
|
53
|
+
* a home-screen (standalone) PWA, the layout viewport permanently loses the
|
|
54
|
+
* status-bar height for the rest of the app session. innerHeight,
|
|
55
|
+
* visualViewport.height and 100dvh all report the shrunken value together, so
|
|
56
|
+
* nothing inside the page can see anything wrong — the page simply ends early
|
|
57
|
+
* and the strip below it is system background that no CSS can reach. Reported
|
|
58
|
+
* as 932 -> 873 on an iPhone Pro Max; the user's device reads 852 -> 793.
|
|
59
|
+
* Both are exactly one status bar. See
|
|
60
|
+
* https://dev.to/cederhook/fixing-the-ios-standalone-pwa-keyboard-bug-that-shrinks-your-viewport-for-good-63d
|
|
61
|
+
*
|
|
62
|
+
* This is why the reported symptom is asymmetric and why the earlier
|
|
63
|
+
* "double-counted top inset" reading was wrong: the top edge is genuinely
|
|
64
|
+
* correct (env top 59 is paid once, the viewport starts at screen y=0), the
|
|
65
|
+
* bottom is simply 59px short. It also explains a chat client being hit
|
|
66
|
+
* hardest — the trigger is typing, which happens on the first message.
|
|
67
|
+
*
|
|
68
|
+
* The only known cure is to make WebKit re-measure: drop a full-viewport
|
|
69
|
+
* element out of the box tree and force a synchronous reflow. Two departures
|
|
70
|
+
* from the published recipe:
|
|
71
|
+
* - scrollTop is saved and restored around the toggle. Un-boxing an ancestor
|
|
72
|
+
* resets every descendant scroller to 0, which in a chat client means the
|
|
73
|
+
* conversation jumps to its first message. Both happen inside one task, so
|
|
74
|
+
* no frame is ever painted in between and nothing flickers.
|
|
75
|
+
* - the baseline is the tallest innerHeight this session has actually seen,
|
|
76
|
+
* not the screen height. On any device where the viewport is legitimately
|
|
77
|
+
* short, the baseline equals the current height and this never fires.
|
|
78
|
+
*
|
|
79
|
+
* Standalone-gated, so a browser tab (and every desktop, CDP included) is a
|
|
80
|
+
* strict no-op — which is also why the fix cannot be regression-tested here
|
|
81
|
+
* and has to be confirmed on the device.
|
|
82
|
+
*/
|
|
83
|
+
export declare function installViewportHeal(ctx: ClientContext): void;
|
|
84
|
+
/**
|
|
85
|
+
* Sunk-viewport compensation (S1.3, 2026-08-17) — zeroes --mnav-sab ONLY.
|
|
86
|
+
*
|
|
87
|
+
* When isViewportSunkBelowStatusBar() holds, the layout viewport is 59px
|
|
88
|
+
* shorter than the screen while env() still reports the full pair of insets.
|
|
89
|
+
* The bottom one is then a lie with a cost: the home indicator sits in the
|
|
90
|
+
* dead strip BELOW the page, so the 34px we reserve for it is 34px of blank
|
|
91
|
+
* page stacked on top of an already-blank system band. Zeroing it does not
|
|
92
|
+
* fix the band (nothing in the page can) but stops us widening it.
|
|
93
|
+
*
|
|
94
|
+
* --mnav-sat is deliberately left alone: the top edge is measured correct on
|
|
95
|
+
* the device (header sits right under the notch), and the S1.2 round already
|
|
96
|
+
* burned a cycle on the theory that it was double-counted.
|
|
97
|
+
*
|
|
98
|
+
* Reversible by design. The predicate is re-evaluated on every resize, so a
|
|
99
|
+
* viewport that comes back to full height — the heal above winning, or Apple
|
|
100
|
+
* shipping the fix — drops the override and the normal env() compensation
|
|
101
|
+
* returns without a reload. `data-mnav-sunk` on <html> is what the debug
|
|
102
|
+
* badge reads, so the badge reports the state that is actually in force
|
|
103
|
+
* rather than re-deriving it.
|
|
104
|
+
*/
|
|
105
|
+
export declare function installSunkInset(ctx: ClientContext): void;
|
|
106
|
+
//# sourceMappingURL=phone-chrome.d.ts.map
|