dsh-auto-open-web 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +19 -4
- package/README.md +14 -4
- package/host-publish/DshAppWindow.deps.json +2 -2
- package/host-publish/DshAppWindow.dll +0 -0
- package/host-publish/DshAppWindow.exe +0 -0
- package/host-publish/DshAppWindow.pdb +0 -0
- package/lib/platform.js +6 -6
- package/lib/win32.js +47 -11
- package/lib/worker.cjs +24 -1
- package/package.json +2 -3
package/README.en.md
CHANGED
|
@@ -86,14 +86,14 @@ whole config; fields not listed fall back to defaults):
|
|
|
86
86
|
|
|
87
87
|
This package is a **bundle**: an npm package carrying a configuration layer — `dsh.bundle` in
|
|
88
88
|
`package.json` declares the patch file (`cordis.patch.yml`), and a profile activates the plugin row
|
|
89
|
-
by package name when installed. Published to the **npm registry** (`dsh-auto-open-web@0.1.
|
|
89
|
+
by package name when installed. Published to the **npm registry** (`dsh-auto-open-web@0.1.3`) and
|
|
90
90
|
**GitHub** (https://github.com/jinsiyu/dsh-auto-open-web, `main` branch).
|
|
91
91
|
|
|
92
92
|
### Packaging
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
95
|
cd dsh-auto-open-web
|
|
96
|
-
pnpm pack # the prepack hook compiles the WebView2 host first (dotnet publish), producing dsh-auto-open-web-0.1.
|
|
96
|
+
pnpm pack # the prepack hook compiles the WebView2 host first (dotnet publish), producing dsh-auto-open-web-0.1.3.tgz
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
### Installation (pick one)
|
|
@@ -108,7 +108,7 @@ dsh plugin --profile web add C:\path\to\dsh-auto-open-web
|
|
|
108
108
|
**Option 2: tarball (published artifact, recommended for delivery; no build permission needed)**
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
dsh plugin --profile web add ./dsh-auto-open-web-0.1.
|
|
111
|
+
dsh plugin --profile web add ./dsh-auto-open-web-0.1.3.tgz
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
**Option 3: npm registry (after publishing)**
|
|
@@ -150,9 +150,24 @@ without touching the package.
|
|
|
150
150
|
`host-publish/` (build artifacts are .gitignore'd): for webview2 mode, run
|
|
151
151
|
`pnpm run build:host` inside `node_modules/dsh-auto-open-web` first (requires the .NET SDK);
|
|
152
152
|
browser mode needs no build.
|
|
153
|
+
- This package does not depend on `@deepseek-ai/cordis` (zero code references; the plugin identity
|
|
154
|
+
comes from the `dsh.bundle` / `dsh.client` fields, and Cordis is provided by the DSH deployment
|
|
155
|
+
at runtime), so installation produces no peer warnings.
|
|
156
|
+
- **Zero koffi dependency declared**: koffi (driving Windows Job Object / process verification /
|
|
157
|
+
native file dialog) ships with the **DSH deployment itself** (the official native picker
|
|
158
|
+
`@deepseek-ai/dsh-host-directory-picker-native` depends on koffi, so the deployment always has
|
|
159
|
+
it). The plugin resolves it at runtime: normal resolution (profile-installed or manual
|
|
160
|
+
`pnpm add koffi`) first, then the DSH deployment copy under the Windows global npm layout; if
|
|
161
|
+
resolution fails, capabilities only degrade (Job Object unavailable → exit / pre-launch cleanup
|
|
162
|
+
still apply; process verification skipped; native dialog unavailable) with a log entry.
|
|
163
|
+
**Therefore no platform ever hits koffi build-script blocking** — HarmonyOS and other
|
|
164
|
+
environments without koffi prebuilds install out of the box, with no `pnpm-workspace.yaml` or
|
|
165
|
+
other configuration needed; posix platforms use the posix fallback adapter (browser mode works;
|
|
166
|
+
webview2 / native dialog unavailable), and the platform adapter is loaded conditionally so
|
|
167
|
+
win32.js is never evaluated on posix.
|
|
153
168
|
- If installing by editing `package.json` manually (not via the `dsh plugin` command), you must add
|
|
154
169
|
both the `dependencies` entry and `dsh.profile.bundles`; when using a local `file:` dependency,
|
|
155
|
-
`dsh web` normalizes `file:` to `^0.1.
|
|
170
|
+
`dsh web` normalizes `file:` to `^0.1.3` at startup, which does not affect runtime.
|
|
156
171
|
|
|
157
172
|
## Icons
|
|
158
173
|
|
package/README.md
CHANGED
|
@@ -79,14 +79,14 @@ Job Object(强杀也生效)+ 退出清理结束进程树。
|
|
|
79
79
|
|
|
80
80
|
本包是**组合包(bundle)**:一个附带配置层的 npm 包——`package.json` 的
|
|
81
81
|
`dsh.bundle` 声明配置层文件(`cordis.patch.yml`),profile 安装它时按包名激活
|
|
82
|
-
插件行。已发布到 **npm registry**(`dsh-auto-open-web@0.1.
|
|
82
|
+
插件行。已发布到 **npm registry**(`dsh-auto-open-web@0.1.3`)与 **GitHub**
|
|
83
83
|
(https://github.com/jinsiyu/dsh-auto-open-web,main 分支)。
|
|
84
84
|
|
|
85
85
|
### 打包
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
88
|
cd dsh-auto-open-web
|
|
89
|
-
pnpm pack # prepack 钩子自动先编译 WebView2 宿主(dotnet publish),产出 dsh-auto-open-web-0.1.
|
|
89
|
+
pnpm pack # prepack 钩子自动先编译 WebView2 宿主(dotnet publish),产出 dsh-auto-open-web-0.1.3.tgz
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
### 安装方式(任选其一)
|
|
@@ -101,7 +101,7 @@ dsh plugin --profile web add C:\path\to\dsh-auto-open-web
|
|
|
101
101
|
**方式二:tarball(发布产物,推荐交付;无需构建授权)**
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
dsh plugin --profile web add ./dsh-auto-open-web-0.1.
|
|
104
|
+
dsh plugin --profile web add ./dsh-auto-open-web-0.1.3.tgz
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
**方式三:npm 注册表(发布后)**
|
|
@@ -141,9 +141,19 @@ dsh plugin --profile web remove dsh-auto-open-web # 同时移除依赖与对
|
|
|
141
141
|
main 分支与源码 checkout 方式不含** `host-publish/`(构建产物被
|
|
142
142
|
.gitignore 忽略):webview2 模式需先在 `node_modules/dsh-auto-open-web`
|
|
143
143
|
下执行 `pnpm run build:host` 生成(需 .NET SDK);browser 模式无需构建。
|
|
144
|
+
- **本包零 koffi 依赖声明**:koffi(驱动 Windows 的 Job Object / 进程校验 /
|
|
145
|
+
原生对话框)由 **DSH 部署自带**(官方原生选择器
|
|
146
|
+
`@deepseek-ai/dsh-host-directory-picker-native` 依赖 koffi,部署必带),
|
|
147
|
+
插件运行时解析:常规解析(profile 已装/手动 `pnpm add koffi`)优先,
|
|
148
|
+
其次 Windows 全局 npm 布局下的 DSH 部署副本;解析失败仅降级(Job
|
|
149
|
+
Object 不可用 → 退出/预清理兜底;进程校验跳过;对话框不可用)并记录
|
|
150
|
+
日志。**因此任何平台安装都无 koffi 构建拦截**——鸿蒙等无 koffi
|
|
151
|
+
预编译的环境开箱即装,无需 `pnpm-workspace.yaml` 等额外配置;posix
|
|
152
|
+
平台走 posix 降级适配器(browser 模式可用;webview2 / 原生对话框
|
|
153
|
+
不可用),且平台适配器按平台条件加载,posix 上完全不求值 win32.js。
|
|
144
154
|
- 若手动编辑 `package.json` 安装(不经 dsh plugin 命令),需同时追加
|
|
145
155
|
`dependencies` 与 `dsh.profile.bundles` 两项;使用本地 `file:` 依赖时
|
|
146
|
-
`dsh web` 启动会把 `file:` 规范化成 `^0.1.
|
|
156
|
+
`dsh web` 启动会把 `file:` 规范化成 `^0.1.3`,运行时不受影响。
|
|
147
157
|
|
|
148
158
|
## 图标
|
|
149
159
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"compilationOptions": {},
|
|
7
7
|
"targets": {
|
|
8
8
|
".NETCoreApp,Version=v10.0": {
|
|
9
|
-
"DshAppWindow/0.1.
|
|
9
|
+
"DshAppWindow/0.1.3": {
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"Microsoft.Web.WebView2": "1.0.3124.44",
|
|
12
12
|
"Microsoft.Web.WebView2.Core": "1.0.3124.44",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"libraries": {
|
|
66
|
-
"DshAppWindow/0.1.
|
|
66
|
+
"DshAppWindow/0.1.3": {
|
|
67
67
|
"type": "project",
|
|
68
68
|
"serviceable": false,
|
|
69
69
|
"sha512": ""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/platform.js
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
// pickBrowserExe() → Promise<string | null>
|
|
11
11
|
// resolveHostExe() → string | null
|
|
12
12
|
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const impl = process.platform === 'win32' ? win32 : posix;
|
|
13
|
+
// 按平台**条件加载**适配器(ESM 顶层 await):
|
|
14
|
+
// - Windows:加载 win32.js(koffi 驱动 Job Object / 进程校验 / 原生对话框)
|
|
15
|
+
// - 其他平台(含鸿蒙等无 koffi 预编译的环境):加载 posix.js 降级实现,
|
|
16
|
+
// 完全不求值 win32.js——koffi 仅 Windows 需要(optionalDependencies),
|
|
17
|
+
// posix 平台不安装、不加载、不依赖。
|
|
18
|
+
const impl = process.platform === 'win32' ? await import('./win32.js') : await import('./posix.js');
|
|
19
19
|
|
|
20
20
|
export const isWindows = impl.isWindows;
|
|
21
21
|
export const resolveBrowserExe = impl.resolveBrowserExe;
|
package/lib/win32.js
CHANGED
|
@@ -11,30 +11,65 @@
|
|
|
11
11
|
//
|
|
12
12
|
// 平台选择由 platform.js 完成;本文件顶层无平台副作用,非 Windows 上
|
|
13
13
|
// 静态 import 也安全,各函数在 process.platform !== 'win32' 时自行降级。
|
|
14
|
+
//
|
|
15
|
+
// koffi 依赖策略:本包**不声明任何 koffi 依赖**(鸿蒙等无 koffi 的环境
|
|
16
|
+
// 因此安装零拦截),koffi 由 DSH 部署自带(官方原生选择器
|
|
17
|
+
// @deepseek-ai/dsh-host-directory-picker-native 依赖 koffi),运行时经
|
|
18
|
+
// getKoffi() 解析:常规解析(profile 已装/手动安装)优先,其次 Windows
|
|
19
|
+
// 全局 npm 布局下的 DSH 部署副本;解析失败仅降级(Job Object 不可用、
|
|
20
|
+
// 进程校验跳过、对话框不可用),不崩溃。
|
|
14
21
|
import { spawn, spawnSync } from 'node:child_process';
|
|
15
22
|
import { existsSync, readFileSync, rmSync } from 'node:fs';
|
|
23
|
+
import { createRequire } from 'node:module';
|
|
16
24
|
import { join, basename } from 'node:path';
|
|
17
25
|
import { fileURLToPath } from 'node:url';
|
|
18
26
|
import { instanceStateFile } from './paths.js';
|
|
19
27
|
|
|
20
28
|
export const isWindows = process.platform === 'win32';
|
|
21
29
|
|
|
30
|
+
/**
|
|
31
|
+
* 解析 koffi(异步):常规 import → Windows 全局 npm 布局的 DSH 部署副本。
|
|
32
|
+
* 返回 koffi 模块对象(含 .default 时返回 .default),失败返回 null。
|
|
33
|
+
*/
|
|
34
|
+
async function getKoffi() {
|
|
35
|
+
try {
|
|
36
|
+
const mod = await import('koffi');
|
|
37
|
+
return mod && mod.default !== undefined ? mod.default : mod;
|
|
38
|
+
} catch {
|
|
39
|
+
/* 常规解析失败,尝试部署副本 */
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const globalRoot = process.env.APPDATA ? join(process.env.APPDATA, 'npm', 'node_modules') : '';
|
|
43
|
+
const dshEntry = join(globalRoot, '@deepseek-ai', 'dsh', 'package.json');
|
|
44
|
+
if (existsSync(dshEntry)) {
|
|
45
|
+
const koffi = createRequire(dshEntry)('koffi');
|
|
46
|
+
if (koffi !== null && koffi !== undefined) return koffi;
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
/* 部署解析失败 */
|
|
50
|
+
}
|
|
51
|
+
console.warn('[auto-open-web] koffi not found (neither local nor DSH deployment); win32 capabilities degraded');
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
22
55
|
// koffi 在模块求值时预载(ESM 顶层 await):后续所有函数——包括
|
|
23
56
|
// process 'exit' 处理器——都能同步使用,无需异步 import。
|
|
24
57
|
// 加载失败不致命:进程身份校验降级为保守跳过(见 verifyInstancePid)。
|
|
25
58
|
let koffiLib = null;
|
|
26
59
|
let procApi = null;
|
|
27
60
|
try {
|
|
28
|
-
koffiLib =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
koffiLib = await getKoffi();
|
|
62
|
+
if (koffiLib !== null) {
|
|
63
|
+
const kernel32 = koffiLib.load('kernel32.dll');
|
|
64
|
+
const psapi = koffiLib.load('psapi.dll');
|
|
65
|
+
procApi = {
|
|
66
|
+
openProcess: kernel32.func('__stdcall', 'OpenProcess', 'void *', ['uint32', 'int', 'uint32']),
|
|
67
|
+
getImageName: psapi.func('__stdcall', 'GetProcessImageFileNameW', 'uint32', ['void *', 'void *', 'uint32']),
|
|
68
|
+
getProcessTimes: kernel32.func('__stdcall', 'GetProcessTimes', 'int', ['void *', 'void *', 'void *', 'void *', 'void *']),
|
|
69
|
+
closeHandle: kernel32.func('__stdcall', 'CloseHandle', 'int', ['void *']),
|
|
70
|
+
fileTime: koffiLib.struct('DshFileTime', { dwLowDateTime: 'uint32', dwHighDateTime: 'uint32' }),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
38
73
|
} catch {
|
|
39
74
|
procApi = null;
|
|
40
75
|
}
|
|
@@ -103,7 +138,8 @@ let jobExtType = null;
|
|
|
103
138
|
export async function ensureBrowserJob() {
|
|
104
139
|
if (browserJob !== null) return browserJob;
|
|
105
140
|
try {
|
|
106
|
-
const koffi =
|
|
141
|
+
const koffi = await getKoffi();
|
|
142
|
+
if (koffi === null) throw new Error('koffi unavailable');
|
|
107
143
|
const kernel32 = koffi.load('kernel32.dll');
|
|
108
144
|
const createJob = kernel32.func('__stdcall', 'CreateJobObjectW', 'void *', ['void *', 'void *']);
|
|
109
145
|
const setInfo = kernel32.func('__stdcall', 'SetInformationJobObject', 'int', ['void *', 'uint32', 'void *', 'uint32']);
|
package/lib/worker.cjs
CHANGED
|
@@ -46,8 +46,31 @@ function guidBytes(text) {
|
|
|
46
46
|
const CLSID_FILE_OPEN_DIALOG = guidBytes('dc1c5a9c-e88a-4dde-a5a1-60f82a20aef7');
|
|
47
47
|
const IID_IFILE_OPEN_DIALOG = guidBytes('d57c7288-d4ad-4768-be02-9d969532d960');
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* 解析 koffi(与 win32.js getKoffi 同一策略):常规 import → Windows 全局
|
|
51
|
+
* npm 布局下的 DSH 部署副本(官方原生选择器依赖 koffi,部署必带)。
|
|
52
|
+
* 本包不声明 koffi 依赖,失败即抛出(由调用方转为错误消息)。
|
|
53
|
+
*/
|
|
54
|
+
async function loadKoffi() {
|
|
55
|
+
try {
|
|
56
|
+
const mod = await import('koffi');
|
|
57
|
+
if (mod && mod.default !== undefined) return mod.default;
|
|
58
|
+
return mod;
|
|
59
|
+
} catch {
|
|
60
|
+
/* 常规解析失败,尝试部署副本 */
|
|
61
|
+
}
|
|
62
|
+
const path = require('node:path');
|
|
63
|
+
const fs = require('node:fs');
|
|
64
|
+
const globalRoot = process.env.APPDATA ? path.join(process.env.APPDATA, 'npm', 'node_modules') : '';
|
|
65
|
+
const koffiDir = path.join(globalRoot, '@deepseek-ai', 'dsh', 'node_modules', 'koffi');
|
|
66
|
+
if (fs.existsSync(path.join(koffiDir, 'package.json'))) {
|
|
67
|
+
return require(koffiDir);
|
|
68
|
+
}
|
|
69
|
+
throw new Error('koffi not found (neither local nor DSH deployment)');
|
|
70
|
+
}
|
|
71
|
+
|
|
49
72
|
async function loadWin32DialogBindings() {
|
|
50
|
-
const koffi =
|
|
73
|
+
const koffi = await loadKoffi();
|
|
51
74
|
const ole32 = koffi.load('ole32.dll');
|
|
52
75
|
const user32 = koffi.load('user32.dll');
|
|
53
76
|
const kernel32 = koffi.load('kernel32.dll');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-auto-open-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Open the DSH Web GUI in an app-style WebView2 window on profile start, with a settings card for browser paths",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -40,8 +40,7 @@
|
|
|
40
40
|
"README.en.md"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@deepseek-ai/schemastery": "^3.18.1"
|
|
44
|
-
"koffi": "^3.1.4"
|
|
43
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
45
44
|
},
|
|
46
45
|
"license": "MIT"
|
|
47
46
|
}
|