dsh-cliworker-now 0.7.7 → 0.7.8

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 (87) hide show
  1. package/README.en.md +29 -7
  2. package/README.md +30 -7
  3. package/lib/account-models.mjs +33 -5
  4. package/lib/client.js +575 -102
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +7573 -6269
  7. package/lib/index.js.map +1 -1
  8. package/lib/pi-native-catalog.mjs +15 -5
  9. package/lib/pi-omp-refresh.mjs +3 -3
  10. package/lib/typert.host.js +194 -26
  11. package/lib/typert.remote-client.d.ts +6 -0
  12. package/lib/typert.remote-client.d.ts.map +1 -1
  13. package/lib/typert.remote-client.js +176 -26
  14. package/lib/types/client/cli-executable-settings.d.ts +13 -0
  15. package/lib/types/client/cli-executable-settings.js +128 -0
  16. package/lib/types/client/cli-executable-settings.js.map +1 -0
  17. package/lib/types/client/management-styles.d.ts +1 -1
  18. package/lib/types/client/management-styles.js +4 -0
  19. package/lib/types/client/management-styles.js.map +1 -1
  20. package/lib/types/client/settings-dialog.js +134 -45
  21. package/lib/types/client/settings-dialog.js.map +1 -1
  22. package/lib/types/client/styles.d.ts +1 -1
  23. package/lib/types/client/styles.js +18 -16
  24. package/lib/types/client/styles.js.map +1 -1
  25. package/lib/types/host/account-models.d.mts +7 -1
  26. package/lib/types/host/account-models.mjs +33 -5
  27. package/lib/types/host/accounts.js +51 -19
  28. package/lib/types/host/accounts.js.map +1 -1
  29. package/lib/types/host/adapters.d.ts +2 -0
  30. package/lib/types/host/adapters.js +93 -15
  31. package/lib/types/host/adapters.js.map +1 -1
  32. package/lib/types/host/agy-background-environment.d.ts +2 -0
  33. package/lib/types/host/agy-background-environment.js +7 -0
  34. package/lib/types/host/agy-background-environment.js.map +1 -0
  35. package/lib/types/host/claude-native-oauth.js +2 -0
  36. package/lib/types/host/claude-native-oauth.js.map +1 -1
  37. package/lib/types/host/claude-own-route.d.ts +15 -3
  38. package/lib/types/host/claude-own-route.js +158 -33
  39. package/lib/types/host/claude-own-route.js.map +1 -1
  40. package/lib/types/host/cli-account-binding.js +9 -4
  41. package/lib/types/host/cli-account-binding.js.map +1 -1
  42. package/lib/types/host/cli-executable-paths.d.ts +30 -0
  43. package/lib/types/host/cli-executable-paths.js +272 -0
  44. package/lib/types/host/cli-executable-paths.js.map +1 -0
  45. package/lib/types/host/codex-models.d.ts +3 -1
  46. package/lib/types/host/codex-models.js +37 -4
  47. package/lib/types/host/codex-models.js.map +1 -1
  48. package/lib/types/host/first-party-models.d.ts +4 -0
  49. package/lib/types/host/first-party-models.js +43 -9
  50. package/lib/types/host/first-party-models.js.map +1 -1
  51. package/lib/types/host/hermes-accounts.js +54 -9
  52. package/lib/types/host/hermes-accounts.js.map +1 -1
  53. package/lib/types/host/hermes-models.js +21 -2
  54. package/lib/types/host/hermes-models.js.map +1 -1
  55. package/lib/types/host/index.d.ts +10 -0
  56. package/lib/types/host/index.js +121 -6
  57. package/lib/types/host/index.js.map +1 -1
  58. package/lib/types/host/native-process.js +14 -4
  59. package/lib/types/host/native-process.js.map +1 -1
  60. package/lib/types/host/opencode-native.js +13 -0
  61. package/lib/types/host/opencode-native.js.map +1 -1
  62. package/lib/types/host/pi-omp-adapter.js +2 -2
  63. package/lib/types/host/pi-omp-adapter.js.map +1 -1
  64. package/lib/types/host/pi-omp-native.js +5 -3
  65. package/lib/types/host/pi-omp-native.js.map +1 -1
  66. package/lib/types/host/pi-omp-refresh.mjs +3 -3
  67. package/lib/types/host/process.d.ts +3 -0
  68. package/lib/types/host/process.js +3 -1
  69. package/lib/types/host/process.js.map +1 -1
  70. package/lib/types/host/runtime.js +5 -1
  71. package/lib/types/host/runtime.js.map +1 -1
  72. package/lib/types/host/settings-catalog-cache.d.ts +28 -0
  73. package/lib/types/host/settings-catalog-cache.js +189 -0
  74. package/lib/types/host/settings-catalog-cache.js.map +1 -0
  75. package/lib/types/host/windows-cli-installation.d.ts +4 -0
  76. package/lib/types/host/windows-cli-installation.js +7 -0
  77. package/lib/types/host/windows-cli-installation.js.map +1 -1
  78. package/lib/types/host/windows-codex-launch.d.ts +9 -0
  79. package/lib/types/host/windows-codex-launch.js +216 -0
  80. package/lib/types/host/windows-codex-launch.js.map +1 -0
  81. package/lib/types/host/windows-desktop-cli-installation.d.ts +20 -0
  82. package/lib/types/host/windows-desktop-cli-installation.js +420 -0
  83. package/lib/types/host/windows-desktop-cli-installation.js.map +1 -0
  84. package/lib/types/host/windows-hidden-launch.mjs +3 -1
  85. package/lib/types/shared/cli-settings.d.ts +8 -0
  86. package/lib/windows-hidden-launch.mjs +3 -1
  87. package/package.json +2 -2
@@ -0,0 +1,420 @@
1
+ import * as nodeFs from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { homedir } from 'node:os';
4
+ import { win32 } from 'node:path';
5
+ import { WindowsCliInstallationError } from "./windows-cli-installation.js";
6
+ import { ProcessCleanupUnconfirmedError } from "./process.js";
7
+ const label = (cli) => (cli === 'zcode' ? 'ZCode' : 'OpenCode');
8
+ const failure = (cli, message = '桌面安装信息探测失败') => new WindowsCliInstallationError(`${label(cli)} ${message},请配置 ${cli}Executable`);
9
+ /** Fixed OS metadata query only. No installer, shortcut target, or user command is executed. */
10
+ export const WINDOWS_DESKTOP_INSTALL_QUERY = String.raw `
11
+ $ErrorActionPreference='Stop'
12
+ [Console]::OutputEncoding=[Text.UTF8Encoding]::new($false)
13
+ $watch=[Diagnostics.Stopwatch]::StartNew()
14
+ $rows=[Collections.Generic.List[object]]::new()
15
+ $complete=$true
16
+ $seen=0
17
+ function Bound {
18
+ $script:seen++
19
+ if($watch.ElapsedMilliseconds -gt 8000 -or $script:seen -gt 4096 -or $rows.Count -ge 128){throw 'Metadata limit'}
20
+ }
21
+ function Product([string]$name) {
22
+ if($name -match '^ZCode(?:\s.*)?$'){return 'zcode'}
23
+ if($name -match '^OpenCode(?:\s.*)?$'){return 'opencode'}
24
+ return $null
25
+ }
26
+ function CleanFile([string]$value,[bool]$icon) {
27
+ if([string]::IsNullOrWhiteSpace($value)){return $null}
28
+ $p=$value.Trim()
29
+ if($icon){$p=$p -replace ',\s*-?\d+\s*$',''}
30
+ if($p.StartsWith('"') -and $p.EndsWith('"')){$p=$p.Substring(1,$p.Length-2)}
31
+ if($p -match '[\x00-\x1f\x7f"]' -or $p -notmatch '^[A-Za-z]:[\\/]' -or $p -notmatch '\.(?:exe|ico)$'){return $null}
32
+ return $p
33
+ }
34
+ function AddRoot([string]$cli,[string]$source,[string]$value) {
35
+ if([string]::IsNullOrWhiteSpace($value)){return}
36
+ Bound
37
+ $p=$value.Trim().Trim('"')
38
+ if($p -match '[\x00-\x1f\x7f"]' -or $p -notmatch '^[A-Za-z]:[\\/]'){return}
39
+ $rows.Add([ordered]@{cli=$cli;source=$source;root=$p})
40
+ }
41
+ function AddTarget([string]$cli,[string]$source,[string]$value,[bool]$icon) {
42
+ $p=CleanFile $value $icon
43
+ if(!$p){return}
44
+ Bound
45
+ $rows.Add([ordered]@{cli=$cli;source=$source;target=$p})
46
+ }
47
+ $shell=$null
48
+ try {
49
+ # Defaults are independent hints: deleting shortcuts/registration does not
50
+ # hide a complete installation left at a known vendor location.
51
+ if($env:LOCALAPPDATA) {
52
+ foreach($leaf in @('Programs\ZCode')){AddRoot 'zcode' 'default-location' (Join-Path $env:LOCALAPPDATA $leaf)}
53
+ foreach($leaf in @('Programs\@opencodedesktop','Programs\OpenCode','OpenCode')){AddRoot 'opencode' 'default-location' (Join-Path $env:LOCALAPPDATA $leaf)}
54
+ }
55
+ foreach($baseDir in @($env:ProgramFiles,[Environment]::GetEnvironmentVariable('ProgramFiles(x86)'))) {
56
+ if($baseDir){AddRoot 'zcode' 'default-location' (Join-Path $baseDir 'ZCode');AddRoot 'opencode' 'default-location' (Join-Path $baseDir 'OpenCode')}
57
+ }
58
+ foreach($hive in @([Microsoft.Win32.RegistryHive]::CurrentUser,[Microsoft.Win32.RegistryHive]::LocalMachine)) {
59
+ foreach($view in @([Microsoft.Win32.RegistryView]::Registry64,[Microsoft.Win32.RegistryView]::Registry32)) {
60
+ Bound
61
+ $base=[Microsoft.Win32.RegistryKey]::OpenBaseKey($hive,$view)
62
+ try {
63
+ $uninstall=$base.OpenSubKey('Software\Microsoft\Windows\CurrentVersion\Uninstall')
64
+ if($uninstall) {
65
+ try {
66
+ foreach($name in $uninstall.GetSubKeyNames()) {
67
+ Bound
68
+ $key=$uninstall.OpenSubKey($name)
69
+ if(!$key){continue}
70
+ try {
71
+ $cli=Product ([string]$key.GetValue('DisplayName'))
72
+ if(!$cli){continue}
73
+ AddRoot $cli 'uninstall-location' ([string]$key.GetValue('InstallLocation'))
74
+ AddTarget $cli 'uninstall-icon' ([string]$key.GetValue('DisplayIcon')) $true
75
+ } finally {$key.Dispose()}
76
+ }
77
+ } finally {$uninstall.Dispose()}
78
+ }
79
+ foreach($entry in @(@('zcode','ZCode.exe'),@('opencode','OpenCode.exe'),@('opencode','opencode-cli.exe'))) {
80
+ Bound
81
+ $key=$base.OpenSubKey('Software\Microsoft\Windows\CurrentVersion\App Paths\'+$entry[1])
82
+ if(!$key){continue}
83
+ try {AddTarget $entry[0] 'app-path' ([string]$key.GetValue('')) $false} finally {$key.Dispose()}
84
+ }
85
+ } finally {$base.Dispose()}
86
+ }
87
+ }
88
+ # Read only image paths of exact product names, never arguments or accounts.
89
+ foreach($process in @(Get-Process -Name 'ZCode','OpenCode','OpenCode Beta','OpenCode Dev','OpenCode Desktop','OpenCode-Beta','OpenCode-Dev','OpenCode-Desktop' -ErrorAction SilentlyContinue)) {
90
+ Bound
91
+ $target=[string]$process.Path
92
+ if($target){AddTarget $(if($process.ProcessName -ieq 'ZCode'){'zcode'}else{'opencode'}) 'running-process' $target $false}
93
+ }
94
+ $shell=New-Object -ComObject Shell.Application
95
+ $queue=[Collections.Generic.Queue[object]]::new()
96
+ $visited=[Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
97
+ foreach($folder in @('StartMenu','CommonStartMenu','DesktopDirectory','CommonDesktopDirectory')) {
98
+ $path=[Environment]::GetFolderPath([Environment+SpecialFolder]::$folder)
99
+ $maxDepth=if($folder -match 'StartMenu'){4}else{0}
100
+ if($path -and $visited.Add($path)){$queue.Enqueue(@($path,0,$maxDepth))}
101
+ }
102
+ while($queue.Count -gt 0) {
103
+ Bound
104
+ if($visited.Count -gt 256){throw 'Directory limit'}
105
+ $entry=$queue.Dequeue();$directory=[IO.DirectoryInfo]::new([string]$entry[0]);$depth=[int]$entry[1];$maxDepth=[int]$entry[2]
106
+ if(!$directory.Exists -or ($directory.Attributes -band [IO.FileAttributes]::ReparsePoint)){continue}
107
+ foreach($item in $directory.GetFileSystemInfos()) {
108
+ Bound
109
+ if($item.Attributes -band [IO.FileAttributes]::ReparsePoint){continue}
110
+ if($item -is [IO.DirectoryInfo]) {
111
+ if($depth -lt $maxDepth -and $visited.Add($item.FullName)){$queue.Enqueue(@($item.FullName,$depth+1,$maxDepth))}
112
+ # Only known shell folders and their bounded descendants are searched.
113
+ continue
114
+ }
115
+ if($item.Extension -ine '.lnk'){continue}
116
+ $cli=Product $item.BaseName
117
+ if(!$cli){continue}
118
+ $folder=$null;$linkItem=$null;$link=$null
119
+ try {
120
+ $folder=$shell.Namespace($directory.FullName)
121
+ if(!$folder){throw 'Shortcut metadata unavailable'}
122
+ $linkItem=$folder.ParseName($item.Name)
123
+ if(!$linkItem -or !$linkItem.IsLink){throw 'Shortcut metadata unavailable'}
124
+ $link=$linkItem.GetLink
125
+ $target=CleanFile ([string]$link.Path) $false
126
+ $name=if($target){[IO.Path]::GetFileName($target)}else{''}
127
+ if(($cli -eq 'zcode' -and $name -ieq 'ZCode.exe') -or ($cli -eq 'opencode' -and $name -match '^(?:OpenCode(?:[ -](?:Beta|Dev|Desktop))?|opencode-cli)\.exe$')) {
128
+ AddTarget $cli 'shortcut' $target $false
129
+ }
130
+ } finally {
131
+ foreach($com in @($link,$linkItem,$folder)){if($com -and [Runtime.InteropServices.Marshal]::IsComObject($com)){[void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($com)}}
132
+ }
133
+ }
134
+ }
135
+ } catch {$complete=$false}
136
+ finally {if($shell -and [Runtime.InteropServices.Marshal]::IsComObject($shell)){[void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($shell)}}
137
+ $json=[ordered]@{schema=1;complete=$complete;records=@($rows.ToArray())}|ConvertTo-Json -Depth 5 -Compress
138
+ if([Text.Encoding]::UTF8.GetByteCount($json) -gt 65536){$json='{"schema":1,"complete":false,"records":[]}'}
139
+ [Console]::WriteLine($json)
140
+ `;
141
+ let physicalFiles;
142
+ /** Installation identity is about disk files, not Electron's virtual ASAR tree. */
143
+ function physicalFs() {
144
+ return (physicalFiles ??= process.versions.electron
145
+ ? createRequire(import.meta.url)('original-fs')
146
+ : nodeFs);
147
+ }
148
+ function ordinary(path) {
149
+ const { statSync, accessSync, constants, realpathSync } = physicalFs();
150
+ try {
151
+ const info = statSync(path);
152
+ if (!info.isFile() || !info.size)
153
+ throw new Error('Invalid file');
154
+ accessSync(path, constants.R_OK);
155
+ return realpathSync(path);
156
+ }
157
+ catch (error) {
158
+ if (['ENOENT', 'ENOTDIR'].includes(error.code))
159
+ return undefined;
160
+ throw error;
161
+ }
162
+ }
163
+ function directory(path) {
164
+ const { statSync, realpathSync } = physicalFs();
165
+ try {
166
+ return statSync(path).isDirectory() ? realpathSync(path) : undefined;
167
+ }
168
+ catch (error) {
169
+ if (['ENOENT', 'ENOTDIR'].includes(error.code))
170
+ return undefined;
171
+ throw error;
172
+ }
173
+ }
174
+ function pe(path) {
175
+ const canonical = ordinary(path);
176
+ if (!canonical)
177
+ return undefined;
178
+ const { openSync, fstatSync, readSync, closeSync } = physicalFs();
179
+ const fd = openSync(canonical, 'r');
180
+ try {
181
+ const info = fstatSync(fd), head = Buffer.alloc(64), signature = Buffer.alloc(4);
182
+ if (readSync(fd, head, 0, 64, 0) !== 64 || head.toString('ascii', 0, 2) !== 'MZ')
183
+ throw new Error('Invalid PE');
184
+ const offset = head.readUInt32LE(0x3c);
185
+ if (offset < 64 ||
186
+ offset + 4 > info.size ||
187
+ readSync(fd, signature, 0, 4, offset) !== 4 ||
188
+ signature.toString('hex') !== '50450000')
189
+ throw new Error('Invalid PE');
190
+ return canonical;
191
+ }
192
+ finally {
193
+ closeSync(fd);
194
+ }
195
+ }
196
+ const files = { ordinaryFile: ordinary, directory, peFile: pe };
197
+ const contained = (root, entry, path) => {
198
+ const relative = path.relative(root.toLowerCase(), entry.toLowerCase());
199
+ return (!!relative && !path.isAbsolute(relative) && relative !== '..' && !relative.startsWith('..' + path.sep));
200
+ };
201
+ function safePath(value, path) {
202
+ if (typeof value !== 'string' ||
203
+ !value ||
204
+ value.length > 2048 ||
205
+ /[\x00-\x1f\x7f"]/.test(value) ||
206
+ !path.isAbsolute(value) ||
207
+ (path === win32 && (!/^[A-Za-z]:[\\/]/.test(value) || /^[\\/]{2}/.test(value))) ||
208
+ value.split(/[\\/]/).includes('..'))
209
+ throw new Error('Invalid path');
210
+ return path.normalize(value);
211
+ }
212
+ function iconPath(value, path) {
213
+ if (typeof value !== 'string')
214
+ throw new Error('Invalid path');
215
+ let target = value.trim().replace(/,\s*-?\d+\s*$/, '');
216
+ if (target.startsWith('"') && target.endsWith('"'))
217
+ target = target.slice(1, -1);
218
+ return safePath(target, path);
219
+ }
220
+ function installationEntries(cli, root, fs, path) {
221
+ const foundRoot = fs.directory(root);
222
+ if (!foundRoot)
223
+ return [];
224
+ const canonicalRoot = safePath(foundRoot, path);
225
+ const entries = [];
226
+ if (cli === 'zcode') {
227
+ const entry = fs.ordinaryFile(path.join(root, 'resources', 'glm', 'zcode.cjs'));
228
+ const provider = fs.ordinaryFile(path.join(root, 'resources', 'config', 'provider', 'zcode-builtin.json'));
229
+ if (entry &&
230
+ provider &&
231
+ contained(canonicalRoot, entry, path) &&
232
+ contained(canonicalRoot, provider, path))
233
+ entries.push(entry);
234
+ else if (entry || provider)
235
+ throw failure(cli, '桌面 CLI 配套文件不可用');
236
+ }
237
+ else {
238
+ for (const candidate of [
239
+ path.join(root, 'resources', 'opencode-cli.exe'),
240
+ path.join(root, 'opencode-cli.exe'),
241
+ ]) {
242
+ const entry = fs.peFile(candidate);
243
+ if (entry) {
244
+ if (!contained(canonicalRoot, entry, path))
245
+ throw failure(cli, '桌面 CLI 入口被重定向');
246
+ entries.push(entry);
247
+ }
248
+ }
249
+ }
250
+ const desktopNames = cli === 'zcode'
251
+ ? ['ZCode.exe']
252
+ : [
253
+ 'OpenCode.exe',
254
+ 'OpenCode Beta.exe',
255
+ 'OpenCode Dev.exe',
256
+ 'OpenCode Desktop.exe',
257
+ 'OpenCode-Beta.exe',
258
+ 'OpenCode-Dev.exe',
259
+ 'OpenCode-Desktop.exe',
260
+ ];
261
+ if (!entries.length && desktopNames.some((name) => fs.ordinaryFile(path.join(root, name))))
262
+ throw failure(cli, '桌面已存在,但没有可用独立 CLI');
263
+ return entries;
264
+ }
265
+ /** Metadata is a bounded hint, never a command or an account source. */
266
+ export function windowsDesktopCliFromMetadata(cli, raw, options = {}) {
267
+ const path = options.path ?? win32, fs = options.files ?? files;
268
+ try {
269
+ if (Buffer.byteLength(raw, 'utf8') > 65536)
270
+ throw new Error('Metadata limit');
271
+ const value = JSON.parse(raw.replace(/^\uFEFF/, '').trim());
272
+ if (!value ||
273
+ value.schema !== 1 ||
274
+ value.complete !== true ||
275
+ !Array.isArray(value.records) ||
276
+ value.records.length > 128)
277
+ throw new Error('Invalid metadata');
278
+ const roots = new Map();
279
+ for (const record of value.records) {
280
+ if (!record ||
281
+ typeof record !== 'object' ||
282
+ Array.isArray(record) ||
283
+ !['zcode', 'opencode'].includes(record.cli) ||
284
+ ![
285
+ 'uninstall-location',
286
+ 'uninstall-icon',
287
+ 'app-path',
288
+ 'shortcut',
289
+ 'default-location',
290
+ 'running-process',
291
+ ].includes(record.source) ||
292
+ Object.keys(record).some((key) => !['cli', 'source', 'root', 'target'].includes(key)))
293
+ throw new Error('Invalid metadata');
294
+ if (record.cli !== cli)
295
+ continue;
296
+ let root;
297
+ if (record.root !== undefined &&
298
+ record.target === undefined &&
299
+ ['uninstall-location', 'default-location'].includes(record.source))
300
+ root = safePath(record.root, path);
301
+ else if (record.target !== undefined &&
302
+ record.root === undefined &&
303
+ !['uninstall-location', 'default-location'].includes(record.source)) {
304
+ const target = iconPath(record.target, path), name = path.basename(target).toLowerCase();
305
+ if (record.source === 'uninstall-icon') {
306
+ if (!/\.(?:exe|ico)$/i.test(name))
307
+ throw new Error('Invalid icon');
308
+ }
309
+ else if (cli === 'zcode'
310
+ ? name !== 'zcode.exe'
311
+ : !/^(?:opencode(?:[ -](?:beta|dev|desktop))?|opencode-cli)\.exe$/.test(name))
312
+ throw new Error('Invalid target');
313
+ root = path.dirname(target);
314
+ if (cli === 'opencode' && name === 'opencode-cli.exe') {
315
+ if (path.basename(root).toLowerCase() === 'resources')
316
+ root = path.dirname(root);
317
+ }
318
+ }
319
+ else
320
+ throw new Error('Invalid metadata');
321
+ roots.set(root.toLowerCase(), root);
322
+ }
323
+ const candidates = [];
324
+ let incomplete;
325
+ for (const root of roots.values()) {
326
+ try {
327
+ candidates.push(...installationEntries(cli, root, fs, path));
328
+ }
329
+ catch (error) {
330
+ // An old desktop missing its companion CLI must not hide a complete
331
+ // installation. Read/access errors still fail the overall discovery.
332
+ if (!(error instanceof WindowsCliInstallationError))
333
+ throw error;
334
+ incomplete ??= error;
335
+ }
336
+ }
337
+ const unique = new Map(candidates.map((entry) => [entry.toLowerCase(), entry]));
338
+ if (unique.size > 1)
339
+ throw failure(cli, '发现多个可用安装');
340
+ if (!unique.size && incomplete)
341
+ throw incomplete;
342
+ return [...unique.values()][0];
343
+ }
344
+ catch (error) {
345
+ if (error instanceof WindowsCliInstallationError)
346
+ throw error;
347
+ throw failure(cli);
348
+ }
349
+ }
350
+ export async function findWindowsDesktopCli(cli, capture, signal, env = process.env) {
351
+ signal.throwIfAborted();
352
+ const root = env.SystemRoot || env.WINDIR || 'C:\\Windows';
353
+ let raw;
354
+ try {
355
+ const command = win32.join(safePath(root, win32), 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
356
+ raw = await capture([
357
+ command,
358
+ '-NoLogo',
359
+ '-NoProfile',
360
+ '-NonInteractive',
361
+ '-EncodedCommand',
362
+ Buffer.from(WINDOWS_DESKTOP_INSTALL_QUERY, 'utf16le').toString('base64'),
363
+ ], homedir());
364
+ }
365
+ catch (error) {
366
+ if (error instanceof ProcessCleanupUnconfirmedError)
367
+ throw error;
368
+ signal.throwIfAborted();
369
+ throw failure(cli);
370
+ }
371
+ signal.throwIfAborted();
372
+ return windowsDesktopCliFromMetadata(cli, raw);
373
+ }
374
+ /** Do not treat a PATH/explicit Desktop GUI as the command-line binary. */
375
+ export function windowsOpenCodeDesktopCli(executable, explicit = false, options = {}) {
376
+ const path = options.path ?? win32, fs = options.files ?? files;
377
+ if (!/^opencode(?:[ -](?:beta|dev|desktop))?\.exe$/i.test(path.basename(executable)))
378
+ return undefined;
379
+ const root = path.dirname(executable);
380
+ try {
381
+ const marker = fs.ordinaryFile(path.join(root, 'resources', 'app.asar'));
382
+ // Old Tauri bundles place a CLI alongside their GUI. The GUI PE subsystem
383
+ // must confirm that case; a standalone console opencode.exe is unchanged.
384
+ let legacyGui = false;
385
+ if (!marker && fs.ordinaryFile(executable)) {
386
+ const { openSync, readSync, closeSync } = physicalFs();
387
+ const fd = openSync(executable, 'r');
388
+ try {
389
+ const head = Buffer.alloc(64), kind = Buffer.alloc(2), signature = Buffer.alloc(4);
390
+ if (readSync(fd, head, 0, 64, 0) === 64 && head.toString('ascii', 0, 2) === 'MZ') {
391
+ const peOffset = head.readUInt32LE(0x3c), offset = peOffset + 24 + 68;
392
+ legacyGui =
393
+ peOffset >= 64 &&
394
+ readSync(fd, signature, 0, 4, peOffset) === 4 &&
395
+ signature.toString('hex') === '50450000' &&
396
+ readSync(fd, kind, 0, 2, offset) === 2 &&
397
+ kind.readUInt16LE(0) === 2;
398
+ }
399
+ }
400
+ finally {
401
+ closeSync(fd);
402
+ }
403
+ }
404
+ if (!marker && !legacyGui)
405
+ return undefined;
406
+ if (explicit)
407
+ throw failure('opencode', '执行路径指向桌面主程序');
408
+ const entries = installationEntries('opencode', root, fs, path);
409
+ const unique = new Map(entries.map((entry) => [entry.toLowerCase(), entry]));
410
+ if (unique.size !== 1)
411
+ throw failure('opencode', unique.size ? '发现多个可用安装' : '桌面已存在,但没有可用独立 CLI');
412
+ return [...unique.values()][0];
413
+ }
414
+ catch (error) {
415
+ if (error instanceof WindowsCliInstallationError)
416
+ throw error;
417
+ throw failure('opencode', '桌面 CLI 入口不可用');
418
+ }
419
+ }
420
+ //# sourceMappingURL=windows-desktop-cli-installation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-desktop-cli-installation.js","sourceRoot":"","sources":["../../../src/host/windows-desktop-cli-installation.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,9 @@ import { forwardNativeStdio, spawnNativeProcess } from './native-spawn.mjs'
8
8
  const marker = process.env.DSH_SUBPROCESS_CONTROL
9
9
  delete process.env.DSH_SUBPROCESS_CONTROL
10
10
  if (marker !== 'pipe') throw new Error('Windows background control channel is unavailable')
11
- const control = new Socket({ fd: 7, readable: true, writable: true, allowHalfOpen: true })
11
+ // Receipts are write-only. Reading this inherited Windows pipe keeps a read
12
+ // operation alive after the receipt flush and prevents the relay from exiting.
13
+ const control = new Socket({ fd: 7, readable: false, writable: true, allowHalfOpen: true })
12
14
  let child, sent = false
13
15
  function receipt(value) {
14
16
  if (sent) return
@@ -3,3 +3,11 @@ import type { CliId } from './types.ts';
3
3
  export interface CliSettings {
4
4
  enabled: Record<CliId, boolean>;
5
5
  }
6
+ /** Machine-local executable selection; separate from project model preferences. */
7
+ export interface CliExecutablePathStatus {
8
+ cli: CliId;
9
+ path: string;
10
+ source: 'auto' | 'manual' | 'configured' | 'none';
11
+ available: boolean;
12
+ error?: string;
13
+ }
@@ -8,7 +8,9 @@ import { forwardNativeStdio, spawnNativeProcess } from './native-spawn.mjs'
8
8
  const marker = process.env.DSH_SUBPROCESS_CONTROL
9
9
  delete process.env.DSH_SUBPROCESS_CONTROL
10
10
  if (marker !== 'pipe') throw new Error('Windows background control channel is unavailable')
11
- const control = new Socket({ fd: 7, readable: true, writable: true, allowHalfOpen: true })
11
+ // Receipts are write-only. Reading this inherited Windows pipe keeps a read
12
+ // operation alive after the receipt flush and prevents the relay from exiting.
13
+ const control = new Socket({ fd: 7, readable: false, writable: true, allowHalfOpen: true })
12
14
  let child, sent = false
13
15
  function receipt(value) {
14
16
  if (sent) return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-cliworker-now",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "description": "Multiple agent CLI conversations in the DeepSeek Harness sidebar",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -108,4 +108,4 @@
108
108
  "access": "public",
109
109
  "registry": "https://registry.npmjs.org/"
110
110
  }
111
- }
111
+ }