@morlay/dsh-desktop-shell 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +4 -4
  2. package/dist/{appconfig-BZ9wPROk.mjs → appconfig-CSZh3JG7.mjs} +2 -2
  3. package/dist/appconfig.d.mts +21 -0
  4. package/dist/appconfig.mjs +1 -2
  5. package/dist/{dshhome-Dp89FOr-.mjs → dshhome-DAJ9dkn2.mjs} +2 -2
  6. package/dist/dshhome.d.mts +6 -0
  7. package/dist/dshhome.mjs +1 -2
  8. package/dist/index.d.mts +6 -0
  9. package/dist/index.mjs +1050 -139
  10. package/dist/inline-packages.d.mts +14 -0
  11. package/dist/inline-packages.mjs +21 -0
  12. package/dist/official-BmgBsdhq.mjs +5 -0
  13. package/dist/official.d.mts +4 -0
  14. package/dist/official.mjs +1 -2
  15. package/dist/preload-app.cjs +5 -1
  16. package/dist/profile-project.d.mts +20 -0
  17. package/dist/profile-project.mjs +1 -2
  18. package/dist/{seed-BF71UAuI.mjs → seed-Bxr0BsCk.mjs} +52 -5
  19. package/dist/seed.d.mts +21 -0
  20. package/dist/seed.mjs +1 -2
  21. package/package.json +42 -21
  22. package/src/__tests__/developer-endpoint.spec.ts +17 -0
  23. package/src/__tests__/document-marks.spec.ts +42 -0
  24. package/src/__tests__/dshhome.spec.ts +108 -0
  25. package/src/__tests__/host-process.spec.ts +205 -0
  26. package/src/__tests__/ipc.spec.ts +39 -0
  27. package/src/__tests__/profile-project.spec.ts +204 -0
  28. package/src/__tests__/seed-profile.spec.ts +189 -0
  29. package/src/__tests__/shell-env.spec.ts +131 -0
  30. package/src/__tests__/shell-import-boundary.spec.ts +69 -0
  31. package/src/__tests__/stream-uplink.spec.ts +49 -0
  32. package/src/appconfig.ts +79 -0
  33. package/src/developer-endpoint.ts +30 -0
  34. package/src/developer-menu.ts +198 -0
  35. package/src/directory-picker.ts +37 -0
  36. package/src/document-marks.ts +58 -0
  37. package/src/dshhome.ts +29 -0
  38. package/src/electron.ts +33 -0
  39. package/src/host-process.ts +533 -0
  40. package/src/index.ts +716 -0
  41. package/src/inline-packages.ts +18 -0
  42. package/src/ipc.ts +58 -0
  43. package/src/keybindings.ts +35 -0
  44. package/src/official.ts +8 -0
  45. package/src/preload-app.ts +147 -0
  46. package/src/profile-project.ts +138 -0
  47. package/src/seed.ts +183 -0
  48. package/src/shell-env.ts +31 -0
  49. package/src/shortcuts.ts +236 -0
  50. package/src/stream-uplink.ts +41 -0
  51. package/dist/official-Cz9Mry1n.mjs +0 -167
@@ -0,0 +1,236 @@
1
+ // 桌面快捷键的原生侧:设备偏好持久化 + 原生按键转发 + 关闭窗口动作。
2
+ //
3
+ // 上游 `@deepseek-ai/dsh-client-shortcuts` 在 desktop 运行时**要求** `window.dshDesktop.keyboard`
4
+ // 存在(缺了就构造失败);这里就是那份契约的实现——主进程按已绑定键过滤物理按键,把命中的手势经
5
+ // IPC 交给渲染进程派发。
6
+ import { ipcMain } from "./electron.ts";
7
+ import type { BrowserWindow as BrowserWindowType, Input } from "electron";
8
+ import {
9
+ bindingKey,
10
+ effectiveShortcuts,
11
+ parseShortcutDefinitions,
12
+ parseShortcutEdit,
13
+ } from "@deepseek-ai/dsh-client-shortcuts/protocol";
14
+ import type {
15
+ NormalizedBinding,
16
+ ShortcutConfigSnapshot,
17
+ ShortcutDefinition,
18
+ ShortcutPlatform,
19
+ ShortcutRevision,
20
+ } from "@deepseek-ai/dsh-client-shortcuts/protocol";
21
+ import { DESKTOP_IPC, assertDesktopSender } from "./ipc.ts";
22
+ import { desktopKeybindings } from "./keybindings.ts";
23
+
24
+ export interface DesktopShortcuts {
25
+ // 把一个窗口接进原生按键转发(每个新建的窗口都要接一次)。
26
+ attach(window: BrowserWindowType): void;
27
+ // 释放 IPC 与持久化(退出时调用)。
28
+ dispose(): void;
29
+ }
30
+
31
+ // 装上桌面快捷键的原生侧,返回窗口接入与释放操作;`scheme` 用于校验 IPC 来源。
32
+ export function installDesktopShortcuts(
33
+ getWindow: () => BrowserWindowType | undefined,
34
+ userData: string,
35
+ platform: ShortcutPlatform,
36
+ scheme: string,
37
+ ): DesktopShortcuts {
38
+ let definitions: readonly ShortcutDefinition[] = [];
39
+ let recording = false;
40
+ let revision: ShortcutRevision | undefined;
41
+ let keys = new Set<string>();
42
+
43
+ // 只有「已绑定、无冲突、无问题」的键才拦:其余一律放行给页面自己的处理。
44
+ const publish = (snapshot: ShortcutConfigSnapshot): void => {
45
+ revision =
46
+ definitions.length === 0 || snapshot.status === "loading" ? undefined : snapshot.revision;
47
+ const rows =
48
+ snapshot.status === "loading"
49
+ ? []
50
+ : effectiveShortcuts(definitions, snapshot.document, "desktop", platform);
51
+ keys = new Set(
52
+ rows.flatMap((row) =>
53
+ row.binding !== null && row.issue === null && row.conflicts.length === 0
54
+ ? [bindingKey(row.binding)]
55
+ : [],
56
+ ),
57
+ );
58
+ const window = getWindow();
59
+ if (window !== undefined && !window.isDestroyed())
60
+ window.webContents.send(DESKTOP_IPC.shortcutsChanged, snapshot);
61
+ };
62
+
63
+ const persistence = desktopKeybindings(userData, platform, publish);
64
+
65
+ const windowOf = (event: Electron.IpcMainInvokeEvent): BrowserWindowType => {
66
+ assertDesktopSender(event, scheme, ["app"]);
67
+ const window = getWindow();
68
+ if (window === undefined || window.isDestroyed() || event.sender !== window.webContents)
69
+ throw new Error("desktop shortcuts: rejected sender");
70
+ return window;
71
+ };
72
+
73
+ ipcMain.handle(DESKTOP_IPC.shortcutsGet, (event, input: unknown) => {
74
+ windowOf(event);
75
+ definitions = parseShortcutDefinitions(input);
76
+ persistence.setDefinitions(definitions);
77
+ return persistence.readCurrent();
78
+ });
79
+ ipcMain.handle(DESKTOP_IPC.shortcutsEdit, (event, input: unknown, expected: unknown) => {
80
+ windowOf(event);
81
+ if (typeof expected !== "string") throw new Error("desktop shortcuts: invalid revision");
82
+ return persistence.edit(parseShortcutEdit(input), expected as ShortcutRevision);
83
+ });
84
+ ipcMain.handle(DESKTOP_IPC.shortcutsRecording, (event, active: unknown) => {
85
+ const window = windowOf(event);
86
+ if (typeof active !== "boolean") throw new Error("desktop shortcuts: invalid recording state");
87
+ recording = active;
88
+ window.webContents.setIgnoreMenuShortcuts(active);
89
+ });
90
+ ipcMain.handle(DESKTOP_IPC.shortcutsCloseWindow, (event, expected: unknown) => {
91
+ const window = windowOf(event);
92
+ if (expected !== revision || revision === undefined || recording) return;
93
+ if (!window.isFocused() || !window.isEnabled()) return;
94
+ window.close();
95
+ });
96
+
97
+ const attach = (window: BrowserWindowType): void => {
98
+ const contents = window.webContents;
99
+ let deadKey = false;
100
+ const held = new Set<string>();
101
+ const consumed = new Map<string, "press" | "repeat">();
102
+ const resetInput = (): void => {
103
+ deadKey = false;
104
+ held.clear();
105
+ consumed.clear();
106
+ if (!contents.isDestroyed()) contents.setIgnoreMenuShortcuts(false);
107
+ };
108
+ const clear = (): void => {
109
+ resetInput();
110
+ definitions = [];
111
+ keys.clear();
112
+ recording = false;
113
+ persistence.setDefinitions(null);
114
+ };
115
+ const beforeInput = (event: Electron.Event, input: Input): void => {
116
+ if (event.defaultPrevented) {
117
+ resetInput();
118
+ return;
119
+ }
120
+ if (
121
+ window !== getWindow() ||
122
+ !window.isFocused() ||
123
+ !window.isEnabled() ||
124
+ revision === undefined
125
+ ) {
126
+ contents.setIgnoreMenuShortcuts(false);
127
+ held.clear();
128
+ consumed.clear();
129
+ return;
130
+ }
131
+ const modifiers = (["control", "alt", "shift", "meta"] as const).filter(
132
+ (modifier) => input[modifier],
133
+ );
134
+ const key = bindingKey({ code: input.code, modifiers });
135
+ const match = keys.has(key);
136
+ contents.setIgnoreMenuShortcuts(recording || match);
137
+ const composing =
138
+ input.isComposing || input.key === "Dead" || deadKey || input.modifiers.includes("altgr");
139
+ if (input.type === "keyDown") deadKey = input.key === "Dead";
140
+ if (recording || composing) {
141
+ held.clear();
142
+ consumed.clear();
143
+ return;
144
+ }
145
+ let binding: NormalizedBinding = { code: input.code, modifiers };
146
+ let priority = false;
147
+ const modifierKey = /^(Control|Alt|Shift|Meta)(Left|Right)$/u.test(input.code);
148
+ if (input.type === "keyUp") {
149
+ // 组合键的第一个键到达过渲染进程,它的抬起也必须到达同一批输入处理。
150
+ if (consumed.get(input.code) === "press") event.preventDefault();
151
+ consumed.delete(input.code);
152
+ held.delete(input.code);
153
+ if (modifierKey) held.clear();
154
+ return;
155
+ }
156
+ if (!input.isAutoRepeat) consumed.delete(input.code);
157
+ if (modifierKey) {
158
+ held.clear();
159
+ return;
160
+ }
161
+ if (input.isAutoRepeat && consumed.has(input.code) && !match) {
162
+ event.preventDefault();
163
+ return;
164
+ }
165
+ if (input.isAutoRepeat && !held.has(input.code) && !match) return;
166
+ held.add(input.code);
167
+ const codes: [string, ...string[]] = [
168
+ input.code,
169
+ ...[...held].filter((value) => value !== input.code),
170
+ ];
171
+ codes.sort();
172
+ const pair = {
173
+ code: codes[0],
174
+ ...(codes[1] === undefined ? {} : { secondCode: codes[1] }),
175
+ modifiers,
176
+ };
177
+ priority = keys.has(key);
178
+ if (codes.length === 2 && keys.has(bindingKey(pair))) {
179
+ binding = pair;
180
+ priority = true;
181
+ }
182
+ if (!priority) return;
183
+ event.preventDefault();
184
+ if (!input.isAutoRepeat) {
185
+ if (binding.secondCode !== undefined) {
186
+ consumed.set(binding.code, "repeat");
187
+ consumed.set(binding.secondCode, "repeat");
188
+ }
189
+ consumed.set(input.code, "press");
190
+ }
191
+ // Electron 可能两个 keyup 都不再送来:已完成的按键不能拿来接下一个组合键。
192
+ held.clear();
193
+ contents.send(DESKTOP_IPC.shortcutsInput, {
194
+ kind: "keyboard",
195
+ revision,
196
+ code: binding.code,
197
+ ...(binding.secondCode === undefined ? {} : { secondCode: binding.secondCode }),
198
+ repeat: input.isAutoRepeat,
199
+ control: input.control,
200
+ alt: input.alt,
201
+ shift: input.shift,
202
+ meta: input.meta,
203
+ });
204
+ };
205
+ const navigation = (
206
+ event: Electron.Event<Electron.WebContentsDidStartNavigationEventParams>,
207
+ ): void => {
208
+ if (event.isMainFrame && !event.isSameDocument) clear();
209
+ };
210
+ const disposeInput = (): void => {
211
+ contents.off("did-start-navigation", navigation);
212
+ contents.off("before-input-event", beforeInput);
213
+ contents.off("blur", resetInput);
214
+ resetInput();
215
+ };
216
+ contents.on("did-start-navigation", navigation);
217
+ contents.on("before-input-event", beforeInput);
218
+ contents.on("blur", resetInput);
219
+ contents.once("destroyed", disposeInput);
220
+ window.once("closed", clear);
221
+ };
222
+
223
+ return {
224
+ attach,
225
+ dispose() {
226
+ for (const channel of [
227
+ DESKTOP_IPC.shortcutsGet,
228
+ DESKTOP_IPC.shortcutsEdit,
229
+ DESKTOP_IPC.shortcutsRecording,
230
+ DESKTOP_IPC.shortcutsCloseWindow,
231
+ ])
232
+ ipcMain.removeHandler(channel);
233
+ persistence.dispose();
234
+ },
235
+ };
236
+ }
@@ -0,0 +1,41 @@
1
+ // 页面侧 Gateway 流的上行通道:`open` 的 IPC 往返未回来时先把上行项排队,流 id 到位后按序发
2
+ // 给主进程。
3
+ //
4
+ // 上行项是逻辑流的输入值(序列化成请求体的行由主进程做);格式的 home 是 `@morlay/dsh-desktop-host/wire`。
5
+ export interface StreamUplink {
6
+ // 绑定宿主侧的流 id;把排队中的项发出去。同一通道只绑一次。
7
+ bind(streamId: number): void;
8
+ // 一道上行项(Gateway 逻辑流的输入值)。
9
+ push(item: unknown): void;
10
+ // 上行结束:主进程据此结束宿主请求体(宿主侧的 uplink 迭代随之结束)。
11
+ close(): void;
12
+ }
13
+
14
+ // 造一条上行通道;`send` / `end` 是主进程方向的投递函数。
15
+ export function createStreamUplink(
16
+ send: (streamId: number, item: unknown) => void,
17
+ end: (streamId: number) => void,
18
+ ): StreamUplink {
19
+ let streamId: number | undefined;
20
+ let closed = false;
21
+ const queued: unknown[] = [];
22
+ return {
23
+ bind(id) {
24
+ if (streamId !== undefined) throw new Error("dsh desktop: stream uplink is already bound");
25
+ streamId = id;
26
+ for (const item of queued) send(id, item);
27
+ queued.length = 0;
28
+ if (closed) end(id);
29
+ },
30
+ push(item) {
31
+ if (closed) return;
32
+ if (streamId === undefined) queued.push(item);
33
+ else send(streamId, item);
34
+ },
35
+ close() {
36
+ if (closed) return;
37
+ closed = true;
38
+ if (streamId !== undefined) end(streamId);
39
+ },
40
+ };
41
+ }
@@ -1,167 +0,0 @@
1
- //#region src/official-packages.generated.ts
2
- const OFFICIAL_PROFILE_PACKAGES = [
3
- "@deepseek-ai/cordis-plugin-timer",
4
- "@deepseek-ai/dsh-agent",
5
- "@deepseek-ai/dsh-agent-default-model",
6
- "@deepseek-ai/dsh-agent-loop",
7
- "@deepseek-ai/dsh-agent-preset-registry",
8
- "@deepseek-ai/dsh-api-account-controller",
9
- "@deepseek-ai/dsh-api-gateway",
10
- "@deepseek-ai/dsh-api-job-controller",
11
- "@deepseek-ai/dsh-api-remotes",
12
- "@deepseek-ai/dsh-api-session-controller",
13
- "@deepseek-ai/dsh-api-settings-controller",
14
- "@deepseek-ai/dsh-api-terminal-controller",
15
- "@deepseek-ai/dsh-api-workspace-controller",
16
- "@deepseek-ai/dsh-api-workspace-files",
17
- "@deepseek-ai/dsh-attachment-local",
18
- "@deepseek-ai/dsh-authorization",
19
- "@deepseek-ai/dsh-bash-sandbox",
20
- "@deepseek-ai/dsh-client-connection",
21
- "@deepseek-ai/dsh-client-file-upload",
22
- "@deepseek-ai/dsh-client-hmr",
23
- "@deepseek-ai/dsh-client-locale",
24
- "@deepseek-ai/dsh-client-modules",
25
- "@deepseek-ai/dsh-client-product-analytics",
26
- "@deepseek-ai/dsh-client-resources",
27
- "@deepseek-ai/dsh-client-shortcuts",
28
- "@deepseek-ai/dsh-client-ui-agent-preset",
29
- "@deepseek-ai/dsh-client-ui-approval",
30
- "@deepseek-ai/dsh-client-ui-attachment",
31
- "@deepseek-ai/dsh-client-ui-brand-official",
32
- "@deepseek-ai/dsh-client-ui-chat",
33
- "@deepseek-ai/dsh-client-ui-commands",
34
- "@deepseek-ai/dsh-client-ui-conversation",
35
- "@deepseek-ai/dsh-client-ui-cordis",
36
- "@deepseek-ai/dsh-client-ui-deliverables",
37
- "@deepseek-ai/dsh-client-ui-goal",
38
- "@deepseek-ai/dsh-client-ui-input-trigger",
39
- "@deepseek-ai/dsh-client-ui-jobs",
40
- "@deepseek-ai/dsh-client-ui-layout",
41
- "@deepseek-ai/dsh-client-ui-message-feedback",
42
- "@deepseek-ai/dsh-client-ui-model-selection",
43
- "@deepseek-ai/dsh-client-ui-open-in-app",
44
- "@deepseek-ai/dsh-client-ui-permission-presets",
45
- "@deepseek-ai/dsh-client-ui-plan",
46
- "@deepseek-ai/dsh-client-ui-plugin-manager",
47
- "@deepseek-ai/dsh-client-ui-reference",
48
- "@deepseek-ai/dsh-client-ui-renderer",
49
- "@deepseek-ai/dsh-client-ui-session",
50
- "@deepseek-ai/dsh-client-ui-settings",
51
- "@deepseek-ai/dsh-client-ui-settings-account",
52
- "@deepseek-ai/dsh-client-ui-settings-agent-loop",
53
- "@deepseek-ai/dsh-client-ui-settings-general",
54
- "@deepseek-ai/dsh-client-ui-settings-models",
55
- "@deepseek-ai/dsh-client-ui-settings-plugin-inventory",
56
- "@deepseek-ai/dsh-client-ui-settings-plugins",
57
- "@deepseek-ai/dsh-client-ui-settings-session-log",
58
- "@deepseek-ai/dsh-client-ui-settings-shell",
59
- "@deepseek-ai/dsh-client-ui-settings-subagent",
60
- "@deepseek-ai/dsh-client-ui-settings-web-search",
61
- "@deepseek-ai/dsh-client-ui-shortcuts",
62
- "@deepseek-ai/dsh-client-ui-sidebar",
63
- "@deepseek-ai/dsh-client-ui-sidebar-browser",
64
- "@deepseek-ai/dsh-client-ui-sidebar-documentpreview",
65
- "@deepseek-ai/dsh-client-ui-sidebar-files",
66
- "@deepseek-ai/dsh-client-ui-sidebar-right",
67
- "@deepseek-ai/dsh-client-ui-sidebar-terminal",
68
- "@deepseek-ai/dsh-client-ui-skill",
69
- "@deepseek-ai/dsh-client-ui-subagent",
70
- "@deepseek-ai/dsh-client-ui-theme",
71
- "@deepseek-ai/dsh-client-ui-tool",
72
- "@deepseek-ai/dsh-client-ui-trajectory",
73
- "@deepseek-ai/dsh-client-ui-user-questions",
74
- "@deepseek-ai/dsh-client-ui-workflow-run",
75
- "@deepseek-ai/dsh-client-ui-workspace",
76
- "@deepseek-ai/dsh-command-feedback",
77
- "@deepseek-ai/dsh-commands",
78
- "@deepseek-ai/dsh-compaction-image-offload",
79
- "@deepseek-ai/dsh-config-editor",
80
- "@deepseek-ai/dsh-cordis-client-runner",
81
- "@deepseek-ai/dsh-cordis-host-runner",
82
- "@deepseek-ai/dsh-credentials-local",
83
- "@deepseek-ai/dsh-deepseek-account-platform",
84
- "@deepseek-ai/dsh-deepseek-llm-api-extensions",
85
- "@deepseek-ai/dsh-file-reference-local",
86
- "@deepseek-ai/dsh-fs-observation-policy",
87
- "@deepseek-ai/dsh-fs-sandbox",
88
- "@deepseek-ai/dsh-goal",
89
- "@deepseek-ai/dsh-goal-round-driver",
90
- "@deepseek-ai/dsh-hmr",
91
- "@deepseek-ai/dsh-host-directory-picker-auto",
92
- "@deepseek-ai/dsh-host-open-in-app",
93
- "@deepseek-ai/dsh-host-plugin-inventory",
94
- "@deepseek-ai/dsh-host-product-telemetry-otel",
95
- "@deepseek-ai/dsh-host-webserver",
96
- "@deepseek-ai/dsh-jobs-local",
97
- "@deepseek-ai/dsh-llm",
98
- "@deepseek-ai/dsh-llm-deepseek-account",
99
- "@deepseek-ai/dsh-llm-deepseek-api-key",
100
- "@deepseek-ai/dsh-llm-pi-ai",
101
- "@deepseek-ai/dsh-llm-retry",
102
- "@deepseek-ai/dsh-mcp-resources",
103
- "@deepseek-ai/dsh-message-feedback",
104
- "@deepseek-ai/dsh-office-to-pdf",
105
- "@deepseek-ai/dsh-otel",
106
- "@deepseek-ai/dsh-permission-presets",
107
- "@deepseek-ai/dsh-plugin-manager",
108
- "@deepseek-ai/dsh-plugin-package-inventory-deepseek",
109
- "@deepseek-ai/dsh-ptc-runtime-node",
110
- "@deepseek-ai/dsh-pwsh-sandbox",
111
- "@deepseek-ai/dsh-repeat-tool-reminder",
112
- "@deepseek-ai/dsh-sandbox-local",
113
- "@deepseek-ai/dsh-sandbox-policy",
114
- "@deepseek-ai/dsh-session",
115
- "@deepseek-ai/dsh-session-checkpoint-policy",
116
- "@deepseek-ai/dsh-session-log-deepseek",
117
- "@deepseek-ai/dsh-session-log-export",
118
- "@deepseek-ai/dsh-session-persistence-jsonl",
119
- "@deepseek-ai/dsh-session-projection",
120
- "@deepseek-ai/dsh-session-projection-cache",
121
- "@deepseek-ai/dsh-session-query-sqlite",
122
- "@deepseek-ai/dsh-session-reference",
123
- "@deepseek-ai/dsh-session-stats",
124
- "@deepseek-ai/dsh-session-telemetry-otel",
125
- "@deepseek-ai/dsh-session-title",
126
- "@deepseek-ai/dsh-session-title-first-prompt-llm",
127
- "@deepseek-ai/dsh-session-turn-outline",
128
- "@deepseek-ai/dsh-settings",
129
- "@deepseek-ai/dsh-shell-env",
130
- "@deepseek-ai/dsh-skill",
131
- "@deepseek-ai/dsh-spill-local",
132
- "@deepseek-ai/dsh-spill-policy",
133
- "@deepseek-ai/dsh-storage",
134
- "@deepseek-ai/dsh-storage-domain",
135
- "@deepseek-ai/dsh-storage-json",
136
- "@deepseek-ai/dsh-subagent",
137
- "@deepseek-ai/dsh-subagent-fork-in-process",
138
- "@deepseek-ai/dsh-subagent-spawn-in-process",
139
- "@deepseek-ai/dsh-subprocess-local",
140
- "@deepseek-ai/dsh-system-prompt",
141
- "@deepseek-ai/dsh-token-meter",
142
- "@deepseek-ai/dsh-tool-call-timeout-policy",
143
- "@deepseek-ai/dsh-tool-cordis",
144
- "@deepseek-ai/dsh-tool-subagent",
145
- "@deepseek-ai/dsh-tools",
146
- "@deepseek-ai/dsh-typert-loader",
147
- "@deepseek-ai/dsh-typert-registry",
148
- "@deepseek-ai/dsh-user-approval",
149
- "@deepseek-ai/dsh-user-questions",
150
- "@deepseek-ai/dsh-web",
151
- "@deepseek-ai/dsh-web-app",
152
- "@deepseek-ai/dsh-web-fetch-http",
153
- "@deepseek-ai/dsh-web-search-deepseek",
154
- "@deepseek-ai/dsh-workspace",
155
- "@deepseek-ai/dsh-workspace-changes"
156
- ];
157
- //#endregion
158
- //#region src/official.ts
159
- const DESKTOP_HOST_PACKAGE = "@morlay/dsh-desktop-host";
160
- const OFFICIAL_RUNTIME_PACKAGES = [
161
- "@deepseek-ai/dsh",
162
- DESKTOP_HOST_PACKAGE,
163
- ...OFFICIAL_PROFILE_PACKAGES
164
- ];
165
- const OFFICIAL_PROFILE_BUNDLES = ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app"];
166
- //#endregion
167
- export { OFFICIAL_PROFILE_PACKAGES as i, OFFICIAL_PROFILE_BUNDLES as n, OFFICIAL_RUNTIME_PACKAGES as r, DESKTOP_HOST_PACKAGE as t };