dsh-ui-fortifier 0.1.2 → 0.5.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/lib/index.js CHANGED
@@ -1,15 +1,175 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
+ import { Remote, RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
3
+ import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
4
+ import { canOpenNativePath, openNativePath, runNativeCommand } from "@deepseek-ai/dsh-native-command";
5
+ //#region lib/types/open-dsh-folder.js
6
+ var __runInitializers = function(thisArg, initializers, value) {
7
+ var useValue = arguments.length > 2;
8
+ for (var i = 0; i < initializers.length; i++) value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
9
+ return useValue ? value : void 0;
10
+ };
11
+ var __esDecorate = function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
12
+ function accept(f) {
13
+ if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected");
14
+ return f;
15
+ }
16
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
17
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
18
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
19
+ var _, done = false;
20
+ for (var i = decorators.length - 1; i >= 0; i--) {
21
+ var context = {};
22
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
23
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
24
+ context.addInitializer = function(f) {
25
+ if (done) throw new TypeError("Cannot add initializers after decoration has completed");
26
+ extraInitializers.push(accept(f || null));
27
+ };
28
+ var result = (0, decorators[i])(kind === "accessor" ? {
29
+ get: descriptor.get,
30
+ set: descriptor.set
31
+ } : descriptor[key], context);
32
+ if (kind === "accessor") {
33
+ if (result === void 0) continue;
34
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
35
+ if (_ = accept(result.get)) descriptor.get = _;
36
+ if (_ = accept(result.set)) descriptor.set = _;
37
+ if (_ = accept(result.init)) initializers.unshift(_);
38
+ } else if (_ = accept(result)) if (kind === "field") initializers.unshift(_);
39
+ else descriptor[key] = _;
40
+ }
41
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
42
+ done = true;
43
+ };
44
+ /** SetForegroundWindow / keybd_event 的 P/Invoke 声明(成员定义内无单引号,可直接单引号包裹)。 */
45
+ const WIN32_FOREGROUND_MEMBERS = "[DllImport(\"user32.dll\")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, System.UIntPtr dwExtraInfo); [DllImport(\"user32.dll\")] public static extern bool SetForegroundWindow(System.IntPtr hWnd);";
46
+ /** PowerShell 单引号字面量(内部单引号翻倍)。 */
47
+ function powershellLiteral(value) {
48
+ return `'${value.replace(/'/g, "''")}'`;
49
+ }
50
+ /**
51
+ * 构造 Windows 打开脚本:`Invoke-Item` 打开文件夹,轮询定位该文件夹的资源管理器
52
+ * 窗口,再解锁前台并把该窗口置顶;未定位到窗口时按成功退出(文件夹已经打开)。
53
+ * @param path - 要打开的绝对路径。
54
+ * @returns 传给 `powershell.exe -Command` 的完整脚本。
55
+ */
56
+ function windowsOpenScript(path) {
57
+ return [
58
+ "$ErrorActionPreference = 'Stop'",
59
+ `$target = ${powershellLiteral(path)}`,
60
+ "Invoke-Item -LiteralPath $target",
61
+ "$want = ([Uri]$target).AbsoluteUri.TrimEnd('/')",
62
+ "$shell = New-Object -ComObject Shell.Application",
63
+ "$hwnd = [int64]0",
64
+ "for ($i = 0; $i -lt 30 -and $hwnd -eq 0; $i++) {",
65
+ " Start-Sleep -Milliseconds 100",
66
+ " foreach ($window in $shell.Windows()) {",
67
+ " try { $url = $window.LocationURL } catch { continue }",
68
+ " if ($url -ne $null -and $url.TrimEnd('/') -eq $want) { $hwnd = [int64]$window.HWND; break }",
69
+ " }",
70
+ "}",
71
+ "if ($hwnd -eq 0) { exit 0 }",
72
+ `Add-Type -Namespace DshUiFortifier -Name Foreground -MemberDefinition ${powershellLiteral(WIN32_FOREGROUND_MEMBERS)}`,
73
+ "[DshUiFortifier.Foreground]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero)",
74
+ "[DshUiFortifier.Foreground]::keybd_event(0x12, 0, 2, [UIntPtr]::Zero)",
75
+ "[void][DshUiFortifier.Foreground]::SetForegroundWindow([IntPtr]$hwnd)"
76
+ ].join("\n");
77
+ }
78
+ /**
79
+ * 打开文件夹并把它的资源管理器窗口提到前台(Windows)。
80
+ *
81
+ * explorer 创建的窗口不属于本进程,而 Windows 只允许前台进程、它启动的进程、
82
+ * 或刚接收过输入的进程执行激活,因此新窗口会压在其他窗口之下(harness 共享的
83
+ * `openNativePath` 未处理这一点)。这里先合成 Alt 让本进程取得激活资格,再显式
84
+ * 对目标窗口调用 SetForegroundWindow——与 harness 原生文件夹对话框同一思路,
85
+ * 区别是该窗口归 explorer 所有,必须显式置顶。
86
+ * @param path - 要打开的绝对路径。
87
+ * @param signal - 调用方/连接生命周期;中止会终止该子进程。
88
+ */
89
+ async function openWindowsFolderInForeground(path, signal) {
90
+ await runNativeCommand("powershell.exe", [
91
+ "-NoProfile",
92
+ "-Command",
93
+ windowsOpenScript(path)
94
+ ], signal);
95
+ }
96
+ /** 用系统默认方式打开 .dsh 文件夹;无原生打开器时返回路径让 UI 展示。 */
97
+ let OpenDshFolderService = (() => {
98
+ let _classSuper = TypertRemoteService;
99
+ let _instanceExtraInitializers = [];
100
+ let _openDshFolder_decorators;
101
+ return class OpenDshFolderService extends _classSuper {
102
+ static {
103
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
104
+ _openDshFolder_decorators = [Remote];
105
+ __esDecorate(this, null, _openDshFolder_decorators, {
106
+ kind: "method",
107
+ name: "openDshFolder",
108
+ static: false,
109
+ private: false,
110
+ access: {
111
+ has: (obj) => "openDshFolder" in obj,
112
+ get: (obj) => obj.openDshFolder
113
+ },
114
+ metadata: _metadata
115
+ }, null, _instanceExtraInitializers);
116
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, {
117
+ enumerable: true,
118
+ configurable: true,
119
+ writable: true,
120
+ value: _metadata
121
+ });
122
+ }
123
+ constructor(ctx) {
124
+ super(ctx, "uiFortifierRemote", { namespace: "uiFortifier" });
125
+ __runInitializers(this, _instanceExtraInitializers);
126
+ }
127
+ /**
128
+ * 打开 .dsh 文件夹。
129
+ * @param signal - 调用方可取消信号。
130
+ * @returns opened 为 false 时 path 为 .dsh 文件夹路径。
131
+ */
132
+ async openDshFolder(signal) {
133
+ const home = resolveDshHome();
134
+ if (!canOpenNativePath()) return {
135
+ opened: false,
136
+ path: home
137
+ };
138
+ try {
139
+ if (process.platform === "win32") await openWindowsFolderInForeground(home, signal);
140
+ else await openNativePath(home, signal);
141
+ return {
142
+ opened: true,
143
+ path: home
144
+ };
145
+ } catch (error) {
146
+ if (signal.aborted) throw new RemoteError("gateway/cancelled", "dsh folder open was aborted", {});
147
+ throw new RemoteError("gateway/internal", `path open failed: ${messageOf(error)}`, {}, { cause: error });
148
+ }
149
+ }
150
+ };
151
+ })();
152
+ function messageOf(error) {
153
+ return error instanceof Error ? error.message : String(error);
154
+ }
155
+ //#endregion
2
156
  //#region lib/types/index.js
3
157
  /** 功能开关的 settings 命名空间。 */
4
158
  const UI_FORTIFIER_SETTINGS_NAMESPACE = "ui-fortifier";
5
159
  /** 插件配置 schema。 */
6
- const Config = z.object({ "provider-label": z.boolean().default(true) });
160
+ const Config = z.object({
161
+ "provider-label": z.boolean().default(true),
162
+ "open-dsh-folder": z.boolean().default(true),
163
+ "settings-frame": z.boolean().default(true),
164
+ "model-picker": z.boolean().default(true)
165
+ });
7
166
  /**
8
- * 注册功能开关的 settings 命名空间。
167
+ * 注册功能开关的 settings 命名空间并暴露打开 .dsh 文件夹的 Remote 服务。
9
168
  * @param ctx - 需已挂载 settings 服务的 Cordis 上下文。
10
169
  * @param config - 插件配置,作为 base 层。
11
170
  */
12
171
  function apply(ctx, config) {
172
+ new OpenDshFolderService(ctx);
13
173
  ctx.inject(["settings"], (settingsCtx) => {
14
174
  settingsCtx.settings.installSection(ctx, UI_FORTIFIER_SETTINGS_NAMESPACE, Config, config, {
15
175
  setSource: () => {},
@@ -1,5 +1,5 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
- import type { Config } from '../index';
2
+ import type { Config } from '../types.ts';
3
3
  import type { UiFortifierLocaleKey } from './locales.ts';
4
4
  /** 一个功能模块的安装面。 */
5
5
  interface ModuleEntry {
@@ -10,10 +10,12 @@ interface ModuleEntry {
10
10
  }
11
11
  /** 功能模块清单:字段名(settings 开关 key) → 模块安装面。 */
12
12
  export declare const modules: Record<keyof Config, ModuleEntry>;
13
+ /** 设置页开关行的显示顺序(按位置排序);不在表中的字段排在其后。 */
14
+ export declare const MODULE_ORDER: readonly (keyof Config)[];
13
15
  export declare const inject: string[];
14
16
  /**
15
17
  * 客户端插件体:注册设置页并据开关状态挂载各功能模块。
16
- * @param ctx - 需已提供 slots/locale/settingsScope/modelDirectories 的客户端上下文。
18
+ * @param ctx - 需已提供 slots/locale/settingsScope/modelDirectories/connection/sessions/remote 的客户端上下文。
17
19
  */
18
20
  export declare function apply(ctx: Context): void;
19
21
  declare module '@deepseek-ai/dsh-client-ui-slots' {
@@ -1,6 +1,6 @@
1
1
  /** dsh-ui-fortifier 的文案。 */
2
2
  /** locale key。 */
3
- export type UiFortifierLocaleKey = 'nav' | 'empty' | 'config.provider-label';
3
+ export type UiFortifierLocaleKey = 'nav' | 'empty' | 'config.provider-label' | 'config.open-dsh-folder' | 'config.settings-frame' | 'config.model-picker' | 'openDshFolder' | 'openDshFolder.error' | 'openDshFolder.pathLabel' | 'settingsFrame.drag' | 'settingsFrame.resize' | 'modelPicker.trigger' | 'modelPicker.searchPlaceholder' | 'modelPicker.providers' | 'modelPicker.models' | 'modelPicker.emptyProviders' | 'modelPicker.emptySearch' | 'modelPicker.emptyModels' | 'modelPicker.loading' | 'modelPicker.loadError' | 'modelPicker.retry' | 'modelPicker.provider' | 'modelPicker.model';
4
4
  /** 英文文案。 */
5
5
  export declare const en: Record<UiFortifierLocaleKey, string>;
6
6
  /** 中文文案。 */
@@ -0,0 +1,23 @@
1
+ import type { ModelSelection } from '@deepseek-ai/dsh-api-session-controller/types';
2
+ import type { HostObservable, InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client';
4
+ /** 注入面:响应式目录快照 + load/select 回写动作。 */
5
+ export interface ModelPickerInjected {
6
+ hooks: {
7
+ /** 会话共享的模型目录快照(与官方选择器同一 store)。 */
8
+ directory: HostObservable<ModelDirectoryState>;
9
+ };
10
+ /** 确保共享目录已加载。 */
11
+ load: () => void;
12
+ /** 提交一次提供方/模型选择。 */
13
+ select: (selection: ModelSelection) => Promise<boolean>;
14
+ }
15
+ /** 槽位 owner 参数与本地化文案。 */
16
+ export type ModelPickerProps = PropsRuntime<'conversation.input.right'> & PropsLocale<'ui-fortifier'> & InjectFace<ModelPickerInjected>;
17
+ /**
18
+ * 渲染级联模型选择器(左列提供商、右列模型)。
19
+ * @param props - owner 参数、文案与注入面。
20
+ * @returns 图标触发器按钮与展开时的两列面板。
21
+ */
22
+ export declare function ModelPicker(props: ModelPickerProps): import("react").JSX.Element;
23
+ //# sourceMappingURL=ModelPicker.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * model-picker 功能:在提供商标签右侧注册级联模型选择器。
3
+ */
4
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
5
+ /**
6
+ * 注册模型选择器到 conversation.input.right(provider-label 右侧)。
7
+ * @param ctx - 需已提供 modelDirectories 服务的客户端上下文。
8
+ * @returns 停止注入并卸载注册的 disposer。
9
+ */
10
+ export declare function installModelPicker(ctx: ClientContext): () => void;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { ReactNode } from 'react';
3
+ import type { ConnectionRpcResult } from '@deepseek-ai/dsh-client-connection/client';
4
+ import type { DshFolderOpenValue } from '../../types.ts';
5
+ /** 打开 .dsh 文件夹的注入面。 */
6
+ export interface OpenDshFolderInjected {
7
+ /** 请求 Host 打开 .dsh 文件夹。 */
8
+ openDshFolder: () => Promise<ConnectionRpcResult<DshFolderOpenValue>>;
9
+ }
10
+ /** header 操作区的 owner 参数、本地化文案与注入回调。 */
11
+ export type OpenDshFolderActionProps = PropsRuntime<'settings.action'> & PropsLocale<'ui-fortifier'> & InjectFace<OpenDshFolderInjected>;
12
+ /**
13
+ * 渲染「打开 .dsh 文件夹」操作,点击后请求 Host 打开 .dsh 目录。
14
+ * @param props - header owner 参数、本地化文案与注入的打开回调。
15
+ * @returns 操作按钮及其结果提示。
16
+ */
17
+ export declare function OpenDshFolderAction(props: OpenDshFolderActionProps): ReactNode;
18
+ //# sourceMappingURL=OpenDshFolderAction.d.ts.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * open-dsh-folder 功能:在设置页右上角「打开配置文件」旁增加「打开 .dsh 文件夹」。
3
+ */
4
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
5
+ export type { OpenDshFolderActionProps, OpenDshFolderInjected } from './OpenDshFolderAction.tsx';
6
+ /**
7
+ * 注册「打开 .dsh 文件夹」到设置页右上角操作区,仅在回环连接下注册。
8
+ * @param ctx - 需已提供 slots/connection 的客户端上下文。
9
+ * @returns 停止注入并卸载注册的 disposer。
10
+ */
11
+ export declare function installOpenDshFolder(ctx: ClientContext): () => void;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -17,6 +17,6 @@ export interface FortifierPageInjected {
17
17
  }
18
18
  /** 设置页 props。 */
19
19
  export type FortifierSettingsPageProps = PropsRuntime<'settings.section'> & PropsLocale<'ui-fortifier'> & InjectFace<FortifierPageInjected>;
20
- /** 设置页:读取配置项自动生成开关行。 */
20
+ /** 设置页:读取配置项自动生成切换按钮行。 */
21
21
  export declare function FortifierSettingsPage(props: FortifierSettingsPageProps): import("react").JSX.Element;
22
22
  //# sourceMappingURL=FortifierSettingsPage.d.ts.map
@@ -1,14 +1,14 @@
1
1
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
2
  import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
3
- import type { Config } from '../../index';
3
+ import type { Config } from '../../types.ts';
4
4
  export type { FortifierPageInjected, FortifierSettingsPageProps } from './FortifierSettingsPage.tsx';
5
5
  /** 本插件设置命名空间(与 host 侧一致)。 */
6
6
  export declare const UI_FORTIFIER = "ui-fortifier";
7
7
  /**
8
8
  * 注册设置页并绑定功能开关的 settings 作用域。
9
9
  * @param ctx - 需已提供 slots/locale/settingsScope 的客户端上下文。
10
- * @param moduleFields - 功能模块字段列表(settings 开关 key),由调用方传入。
10
+ * @param moduleOrder - 功能模块字段的显示顺序(settings 开关 key)。
11
11
  * @returns 功能开关的 settings 绑定,供调用方控制子模块注册。
12
12
  */
13
- export declare function installSettings(ctx: ClientContext, moduleFields: readonly string[]): SettingsScope<Config>;
13
+ export declare function installSettings(ctx: ClientContext, moduleOrder: readonly string[]): SettingsScope<Config>;
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ /** 注入面:本功能无需 Host 数据。 */
4
+ export interface SettingsFrameInjected {
5
+ }
6
+ /** 槽位 owner 参数与本地化文案。 */
7
+ export type SettingsFrameEnhancerProps = PropsRuntime<'settings.action'> & PropsLocale<'ui-fortifier'> & InjectFace<SettingsFrameInjected>;
8
+ /**
9
+ * 渲染「拖动位置/大小」手柄。
10
+ * @param props - header owner 参数与本地化文案。
11
+ * @returns 挂入标题行的拖动手柄与挂入面板右下角的缩放柄。
12
+ */
13
+ export declare function SettingsFrameEnhancer(props: SettingsFrameEnhancerProps): ReactNode;
14
+ //# sourceMappingURL=SettingsFrameEnhancer.d.ts.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * settings-frame 功能:让设置面板可拖动位置与缩放大小。
3
+ */
4
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
5
+ export type { SettingsFrameEnhancerProps, SettingsFrameInjected } from './SettingsFrameEnhancer.tsx';
6
+ /**
7
+ * 注册「拖动位置/大小」增强到设置页右上角操作区。
8
+ * @param ctx - 需已提供 slots 的客户端上下文。
9
+ * @returns 停止注入并卸载注册的 disposer。
10
+ */
11
+ export declare function installSettingsFrame(ctx: ClientContext): () => void;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -1,18 +1,17 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import z from '@deepseek-ai/schemastery';
3
+ import type { Config as FortifierConfig } from './types.ts';
4
+ /** 插件配置类型(定义见 `./types.ts`,与 Client 面共享)。 */
5
+ export type Config = FortifierConfig;
6
+ export type { DshFolderOpenValue } from './types.ts';
3
7
  /** 功能开关的 settings 命名空间。 */
4
8
  export declare const UI_FORTIFIER_SETTINGS_NAMESPACE = "ui-fortifier";
5
- /** 插件配置:功能开关状态(配置默认值)。 */
6
- export interface Config {
7
- /** 输入框显示当前提供商。 */
8
- 'provider-label': boolean;
9
- }
10
9
  /** 插件配置 schema。 */
11
- export declare const Config: z<Config>;
10
+ export declare const Config: z<FortifierConfig>;
12
11
  /**
13
- * 注册功能开关的 settings 命名空间。
12
+ * 注册功能开关的 settings 命名空间并暴露打开 .dsh 文件夹的 Remote 服务。
14
13
  * @param ctx - 需已挂载 settings 服务的 Cordis 上下文。
15
14
  * @param config - 插件配置,作为 base 层。
16
15
  */
17
- export declare function apply(ctx: Context, config: Config): void;
16
+ export declare function apply(ctx: Context, config: FortifierConfig): void;
18
17
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 打开本机 .dsh 文件夹的 Host Remote 服务。
3
+ * 端点 `uiFortifier/openDshFolder` 由网关的 SRC 反射发现,无需 typert 生成器产物。
4
+ */
5
+ import { Context } from '@deepseek-ai/cordis';
6
+ import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
7
+ import type { DshFolderOpenValue } from './types.ts';
8
+ export type { DshFolderOpenValue };
9
+ /** 用系统默认方式打开 .dsh 文件夹;无原生打开器时返回路径让 UI 展示。 */
10
+ export declare class OpenDshFolderService extends TypertRemoteService {
11
+ constructor(ctx: Context);
12
+ /**
13
+ * 打开 .dsh 文件夹。
14
+ * @param signal - 调用方可取消信号。
15
+ * @returns opened 为 false 时 path 为 .dsh 文件夹路径。
16
+ */
17
+ openDshFolder(signal: AbortSignal): Promise<DshFolderOpenValue>;
18
+ }
19
+ //# sourceMappingURL=open-dsh-folder.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 本包 Host/Client 两面共享的类型。
3
+ * 仅类型、无运行时代码:双面工程各自编译本文件,无需跨面引用。
4
+ */
5
+ /** 插件配置:功能开关状态(配置默认值)。 */
6
+ export interface Config {
7
+ /** 输入框显示当前提供商。 */
8
+ 'provider-label': boolean;
9
+ /** 设置页右上角显示打开 .dsh 文件夹按钮。 */
10
+ 'open-dsh-folder': boolean;
11
+ /** 设置面板可拖动位置与大小。 */
12
+ 'settings-frame': boolean;
13
+ /** 输入框右侧显示级联模型选择器(先选提供商、再选模型)。 */
14
+ 'model-picker': boolean;
15
+ }
16
+ /** 打开 .dsh 文件夹的返回值。 */
17
+ export interface DshFolderOpenValue {
18
+ /** 是否已发起系统打开。 */
19
+ readonly opened: boolean;
20
+ /** .dsh 文件夹绝对路径(未打开时供 UI 展示)。 */
21
+ readonly path: string;
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-ui-fortifier",
3
3
  "description": "UI 强化",
4
- "version": "0.1.2",
4
+ "version": "0.5.2",
5
5
  "license": "MIT",
6
6
  "contributors": [
7
7
  "pgnqukezrdxmhjso"
@@ -15,8 +15,10 @@
15
15
  "url": "https://github.com/pgnqukezrdxmhjso/dsh-ui-fortifier/issues"
16
16
  },
17
17
  "keywords": [
18
- "dsh",
19
- "plugin",
18
+ "deepseek-harness",
19
+ "dsh-plugin",
20
+ "cordis",
21
+ "web",
20
22
  "ui",
21
23
  "fortifier"
22
24
  ],
@@ -28,10 +30,6 @@
28
30
  "types": "./lib/types/index.d.ts",
29
31
  "default": "./lib/index.js"
30
32
  },
31
- "./invariant": {
32
- "types": "./lib/types/invariant.d.ts",
33
- "default": "./lib/invariant.js"
34
- },
35
33
  "./client": {
36
34
  "types": "./lib/types/client/index.d.ts",
37
35
  "default": "./lib/client.js"
@@ -42,40 +40,38 @@
42
40
  "files": [
43
41
  "cordis.patch.yml",
44
42
  "lib/index.js",
45
- "lib/invariant.js",
46
43
  "lib/client.js",
47
44
  "lib/types/**/*.d.ts"
48
45
  ],
49
- "scripts": {
50
- "bundle": "tsc -b && tsdown",
51
- "watch": "tsdown --watch",
52
- "pub": "npm login --registry=https://registry.npmjs.org && npm publish --registry=https://registry.npmjs.org"
53
- },
54
46
  "peerDependencies": {
55
- "@deepseek-ai/cordis": "workspace:^",
56
- "@deepseek-ai/dsh-api-session-controller": "workspace:^",
57
- "@deepseek-ai/dsh-client-ui-conversation": "workspace:^",
58
- "@deepseek-ai/dsh-client-ui-model-selection": "workspace:^",
59
- "@deepseek-ai/dsh-client-ui-renderer": "workspace:^",
60
- "@deepseek-ai/dsh-invariants": "workspace:^",
61
- "@deepseek-ai/dsh-settings": "workspace:^",
62
- "@deepseek-ai/schemastery": "workspace:^"
47
+ "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2",
48
+ "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2",
49
+ "@deepseek-ai/cordis": "^4.0.2",
50
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2",
51
+ "@deepseek-ai/schemastery": "^3.18.2"
63
52
  },
64
53
  "devDependencies": {
65
- "@deepseek-ai/cordis": "workspace:^",
66
- "@deepseek-ai/dsh-api-session-controller": "workspace:^",
67
- "@deepseek-ai/dsh-client-ui-conversation": "workspace:^",
68
- "@deepseek-ai/dsh-client-ui-model-selection": "workspace:^",
69
- "@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
70
- "@deepseek-ai/dsh-client-ui-renderer": "workspace:^",
71
- "@deepseek-ai/dsh-client-ui-slots": "workspace:^",
72
- "@deepseek-ai/dsh-client-ui-settings": "workspace:^",
73
- "@deepseek-ai/dsh-client-locale": "workspace:^",
74
- "@deepseek-ai/dsh-invariants": "workspace:^",
75
- "@deepseek-ai/dsh-settings": "workspace:^",
76
- "@deepseek-ai/schemastery": "workspace:^",
77
54
  "@types/react": "~18.3.1",
78
- "react": "^18.2.0"
55
+ "@types/react-dom": "~18.3.0",
56
+ "react": "^18.2.0",
57
+ "react-dom": "^18.2.0",
58
+ "@deepseek-ai/cordis": "^4.0.2",
59
+ "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2",
60
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.2",
61
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
62
+ "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.5-rc.2",
63
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.2",
64
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-rc.2",
65
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.2",
66
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.2",
67
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.2",
68
+ "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2",
69
+ "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2",
70
+ "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
71
+ "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2",
72
+ "@deepseek-ai/dsh-settings": "^0.1.5-rc.2",
73
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2",
74
+ "@deepseek-ai/schemastery": "^3.18.2"
79
75
  },
80
76
  "dsh": {
81
77
  "bundle": {
@@ -83,7 +79,9 @@
83
79
  },
84
80
  "client": {
85
81
  "inject": [
82
+ "@deepseek-ai/dsh-api-remotes",
86
83
  "@deepseek-ai/dsh-api-session-controller",
84
+ "@deepseek-ai/dsh-client-connection",
87
85
  "@deepseek-ai/dsh-client-ui-conversation",
88
86
  "@deepseek-ai/dsh-client-ui-model-selection",
89
87
  "@deepseek-ai/dsh-client-ui-renderer",
@@ -92,5 +90,16 @@
92
90
  ],
93
91
  "platform": "web"
94
92
  }
93
+ },
94
+ "scripts": {
95
+ "build": "tsc -b && tsdown",
96
+ "watch": "tsdown --watch",
97
+ "verify": "node ../dsh-pgnqukezrdxmhjso-base/verify.mjs",
98
+ "pub": "pnpm run build && pnpm login --registry=https://registry.npmjs.org && pnpm publish --registry=https://registry.npmjs.org --no-git-checks",
99
+ "pack": "pnpm run build && pnpm pack --pack-destination lib",
100
+ "pack-test-i": "pnpm run pack && (pnpm dsh plugin --profile pkgtest remove %npm_package_name% & pnpm dsh plugin --profile pkgtest add ./lib/%npm_package_name%-%npm_package_version%.tgz)",
101
+ "npm-test-i": "pnpm dsh plugin --profile pkgtest remove %npm_package_name% & pnpm dsh plugin --profile pkgtest add %npm_package_name%@%npm_package_version%",
102
+ "test-create": "pnpm dsh --profile pkgtest --from-default-profile web",
103
+ "test-start": "pnpm dsh --profile pkgtest --port 3081 --no-open"
95
104
  }
96
105
  }
package/lib/invariant.js DELETED
@@ -1,12 +0,0 @@
1
- //#region lib/types/invariant.js
2
- const PACKAGE_NAME = "dsh-ui-fortifier";
3
- const name = "ui-fortifier-invariant";
4
- const inject = ["invariants"];
5
- /**
6
- * No runtime invariant: 本包是纯插槽表面,注册/卸载由 slots 系统的
7
- * effect 语义保证,无自有事件流或可变数据可断言。
8
- */
9
- const install = () => {};
10
- const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
11
- //#endregion
12
- export { apply, inject, name };
@@ -1,4 +0,0 @@
1
- import type { ProviderBadgeProps } from './index.ts';
2
- /** 渲染当前会话的 provider 文本;无选择时不渲染。 */
3
- export declare function ProviderBadge({ directory }: ProviderBadgeProps): import("react").JSX.Element | null;
4
- //# sourceMappingURL=ProviderBadge.d.ts.map
@@ -1,23 +0,0 @@
1
- /**
2
- * provider-badge 功能:在模型选择按钮左侧显示当前会话的模型提供方。
3
- * 注册位置:conversation.input.right(渲染在 conversation.input.model 左侧)。
4
- * 数据源:ModelDirectory(ctx.modelDirectories),current.provider 是 host 报告的当前选择。
5
- */
6
- import type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client';
7
- import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
8
- import type { ModelDirectoryResolver } from '@deepseek-ai/dsh-client-ui-model-selection/client';
9
- /** 本功能注入面:按会话解析 ModelDirectory。 */
10
- export interface ProviderBadgeInjected {
11
- directoryFor: (sessionId: SessionId) => ReturnType<ModelDirectoryResolver['directoryFor']>;
12
- }
13
- /**
14
- * 注册 provider 标签到 conversation.input.right。
15
- * @param ctx - 客户端根上下文。
16
- * @param injected - 本功能注入面。
17
- */
18
- export declare function installProviderBadge(ctx: ClientContext, injected: ProviderBadgeInjected): void;
19
- /** ProviderBadge 组件 props。 */
20
- export type ProviderBadgeProps = PropsRuntime<'conversation.input.right'> & {
21
- directory: ReturnType<ModelDirectoryResolver['directoryFor']>;
22
- };
23
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +0,0 @@
1
- import type { Context } from '@deepseek-ai/cordis';
2
- export declare const name = "ui-fortifier-invariant";
3
- export declare const inject: string[];
4
- export declare const apply: (ctx: Context) => Promise<() => void>;
5
- //# sourceMappingURL=invariant.d.ts.map