dsh-wsl-desktop 0.3.4 → 0.3.5
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/icon.svg +24 -0
- package/lib/wsl/preset.js +99 -9
- package/package.json +2 -1
package/lib/icon.svg
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-label="DSH WSL Desktop">
|
|
2
|
+
<!-- W monogram. The polyline's apex/valleys are chosen so the STROKED bounds
|
|
3
|
+
(8.5..55.5 x 13.5..50.5) center on (32,32): the mark is optically centered,
|
|
4
|
+
not merely its path data. Keep the 7px stroke when editing the path, and
|
|
5
|
+
re-center against those bounds rather than the raw vertices. -->
|
|
6
|
+
<defs>
|
|
7
|
+
<linearGradient id="wsl-base" x1="0" y1="0" x2="0" y2="1">
|
|
8
|
+
<stop offset="0" stop-color="#151D31"/>
|
|
9
|
+
<stop offset="1" stop-color="#0B111E"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<radialGradient id="wsl-glow" gradientUnits="userSpaceOnUse" cx="52" cy="4" r="44">
|
|
12
|
+
<stop offset="0" stop-color="#38BDF8" stop-opacity=".32"/>
|
|
13
|
+
<stop offset="1" stop-color="#38BDF8" stop-opacity="0"/>
|
|
14
|
+
</radialGradient>
|
|
15
|
+
<linearGradient id="wsl-mark" x1="12" y1="17" x2="52" y2="47" gradientUnits="userSpaceOnUse">
|
|
16
|
+
<stop offset="0" stop-color="#38BDF8"/>
|
|
17
|
+
<stop offset="1" stop-color="#4D6BFE"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
</defs>
|
|
20
|
+
<rect width="64" height="64" rx="15" fill="url(#wsl-base)"/>
|
|
21
|
+
<rect width="64" height="64" rx="15" fill="url(#wsl-glow)"/>
|
|
22
|
+
<path d="M12 17 L22.5 47 L32 25 L41.5 47 L52 17" fill="none" stroke="url(#wsl-mark)" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
|
23
|
+
<rect x=".75" y=".75" width="62.5" height="62.5" rx="14.25" fill="none" stroke="#7DD3FC" stroke-opacity=".22" stroke-width="1.5"/>
|
|
24
|
+
</svg>
|
package/lib/wsl/preset.js
CHANGED
|
@@ -49,6 +49,48 @@ export const WORLD_MODULE_NAMES = new Set([
|
|
|
49
49
|
'@deepseek-ai/dsh-terminal',
|
|
50
50
|
])
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Tool-family modules whose survival in a WSL preset is a RECORDED VERDICT.
|
|
54
|
+
*
|
|
55
|
+
* The complement of WORLD_MODULE_NAMES inside the tool family, and the reason it
|
|
56
|
+
* exists: the removal rule is a closed list, so a tool-family row this plugin had
|
|
57
|
+
* never seen was neither removed NOR reported — it was copied into the WSL variant
|
|
58
|
+
* in silence, which is the leak shape this transform exists to prevent. A future
|
|
59
|
+
* DSH release that adds a host-execution tool row would have leaked exactly there,
|
|
60
|
+
* with every suite still green.
|
|
61
|
+
*
|
|
62
|
+
* Every name here was read off a shipped preset and judged world-agnostic: it
|
|
63
|
+
* neither runs host commands nor reaches host files on the model's behalf. A row
|
|
64
|
+
* outside BOTH sets is kept — the transform must not guess a row away from a preset
|
|
65
|
+
* — but reported through `unclassified`, so the next upstream tool row is a
|
|
66
|
+
* decision somebody makes rather than a leak nobody sees.
|
|
67
|
+
*/
|
|
68
|
+
export const VERDICTED_KEPT_MODULES = new Set([
|
|
69
|
+
'@deepseek-ai/dsh-tool-jobs',
|
|
70
|
+
'@deepseek-ai/dsh-tool-schedule',
|
|
71
|
+
'@deepseek-ai/dsh-tool-skill',
|
|
72
|
+
'@deepseek-ai/dsh-skill-filesystem',
|
|
73
|
+
'@deepseek-ai/dsh-command-goal',
|
|
74
|
+
'@deepseek-ai/dsh-tool-goal',
|
|
75
|
+
'@deepseek-ai/dsh-tool-subagent-control',
|
|
76
|
+
'@deepseek-ai/dsh-tool-subagent',
|
|
77
|
+
'@deepseek-ai/dsh-tool-workflow',
|
|
78
|
+
'@deepseek-ai/dsh-tool-ask-user',
|
|
79
|
+
'@deepseek-ai/dsh-tool-todo',
|
|
80
|
+
'@deepseek-ai/dsh-tool-web',
|
|
81
|
+
'@deepseek-ai/dsh-tool-cordis',
|
|
82
|
+
'@deepseek-ai/dsh-tool-present',
|
|
83
|
+
])
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The tool / execution family, by package name.
|
|
87
|
+
*
|
|
88
|
+
* Narrow on purpose: it decides which rows need a VERDICT, and a family wide enough
|
|
89
|
+
* to catch the persona, instruction, plan-mode or compaction rows would redden the
|
|
90
|
+
* acceptance gate over rows whose survival was never in question.
|
|
91
|
+
*/
|
|
92
|
+
const TOOL_FAMILY = /^@deepseek-ai\/dsh-(?:tool-[a-z0-9-]+|terminal[a-z0-9-]*|skill-filesystem)$/u
|
|
93
|
+
|
|
52
94
|
/** Module extensions a specifier may carry where it names the package itself. */
|
|
53
95
|
const MODULE_SUFFIX = /\.(?:[cm]?js)$/u
|
|
54
96
|
|
|
@@ -76,6 +118,26 @@ function specifierSegments(specifier) {
|
|
|
76
118
|
return readings.flatMap((reading) => reading.split(/[\\/]/u))
|
|
77
119
|
}
|
|
78
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Every `@scope/name` package reading a specifier carries.
|
|
123
|
+
*
|
|
124
|
+
* The one place the package identity is derived, shared by the removal predicate
|
|
125
|
+
* and the verdict predicate so the two cannot disagree about which package a
|
|
126
|
+
* spelling names — the drift that made the earlier basename match miss a subpath.
|
|
127
|
+
* @param {unknown} specifier - the row's module name.
|
|
128
|
+
* @returns {string[]} each scoped pair the specifier carries, in path order.
|
|
129
|
+
*/
|
|
130
|
+
function scopedPackages(specifier) {
|
|
131
|
+
if (typeof specifier !== 'string' || specifier.length === 0) return []
|
|
132
|
+
const segments = specifierSegments(specifier)
|
|
133
|
+
const out = []
|
|
134
|
+
for (let index = 0; index + 1 < segments.length; index += 1) {
|
|
135
|
+
if (!segments[index].startsWith('@')) continue
|
|
136
|
+
out.push(`${segments[index]}/${segments[index + 1].replace(MODULE_SUFFIX, '')}`)
|
|
137
|
+
}
|
|
138
|
+
return out
|
|
139
|
+
}
|
|
140
|
+
|
|
79
141
|
/**
|
|
80
142
|
* Whether one row `name` loads a host-execution-world module.
|
|
81
143
|
*
|
|
@@ -100,13 +162,33 @@ function specifierSegments(specifier) {
|
|
|
100
162
|
export function isHostWorldModule(name) {
|
|
101
163
|
if (typeof name !== 'string' || name.length === 0) return false
|
|
102
164
|
if (WORLD_MODULE_NAMES.has(name)) return true
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
165
|
+
return scopedPackages(name).some((pkg) => WORLD_MODULE_NAMES.has(pkg))
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Whether a row's module belongs to the family that needs a verdict.
|
|
170
|
+
* @param {unknown} name - the row's module name.
|
|
171
|
+
* @returns {boolean} true when the module is a tool-family package.
|
|
172
|
+
*/
|
|
173
|
+
export function isToolFamilyModule(name) {
|
|
174
|
+
if (typeof name !== 'string' || name.length === 0) return false
|
|
175
|
+
return [name, ...scopedPackages(name)].some((candidate) => TOOL_FAMILY.test(candidate))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Whether this plugin holds an explicit verdict for a row's module.
|
|
180
|
+
*
|
|
181
|
+
* True for both verdicts — removed (WORLD_MODULE_NAMES) and deliberately kept
|
|
182
|
+
* (VERDICTED_KEPT_MODULES) — because the question it answers is "has this row been
|
|
183
|
+
* decided?", not "is it dropped?".
|
|
184
|
+
* @param {unknown} name - the row's module name.
|
|
185
|
+
* @returns {boolean} true when the module carries a verdict.
|
|
186
|
+
*/
|
|
187
|
+
export function hasClassifierVerdict(name) {
|
|
188
|
+
if (typeof name !== 'string' || name.length === 0) return false
|
|
189
|
+
return [name, ...scopedPackages(name)].some((candidate) => (
|
|
190
|
+
WORLD_MODULE_NAMES.has(candidate) || VERDICTED_KEPT_MODULES.has(candidate)
|
|
191
|
+
))
|
|
110
192
|
}
|
|
111
193
|
|
|
112
194
|
/**
|
|
@@ -224,12 +306,12 @@ function cloneRow(row) {
|
|
|
224
306
|
* @param {string} options.fsPath - module specifier of the WSL filesystem provider.
|
|
225
307
|
* @param {string | undefined} options.distro - distribution for paths that do not name one.
|
|
226
308
|
* @param {string | undefined} options.sourceDir - directory the source preset lives in.
|
|
227
|
-
* @returns {{ plugins: object[], removed: string[], unclassified: { id: string | null, name: unknown }[] }} the variant rows, what was dropped, and the rows kept without a classifier verdict.
|
|
309
|
+
* @returns {{ plugins: object[], removed: string[], unclassified: { id: string | null, name: unknown }[] }} the variant rows, what was dropped, and the rows kept without a classifier verdict — an unreadable specifier, or a tool-family module that is neither removed nor verdicted-kept.
|
|
228
310
|
*/
|
|
229
311
|
export function buildVariantPlugins(basePlugins, { subprocessPath, shellPath, fsPath, distro, sourceDir }) {
|
|
230
312
|
const kept = []
|
|
231
313
|
const removed = []
|
|
232
|
-
/** Rows kept without a classifier verdict —
|
|
314
|
+
/** Rows kept without a classifier verdict — both shapes the prune() branches record. */
|
|
233
315
|
const unclassified = []
|
|
234
316
|
let includeEditor = false
|
|
235
317
|
/** Config carried by the pruned host-world tool rows, keyed by row id. */
|
|
@@ -267,6 +349,14 @@ export function buildVariantPlugins(basePlugins, { subprocessPath, shellPath, fs
|
|
|
267
349
|
toolConfig.set('str-replace-editor', cloneRow({ config: row.config }).config)
|
|
268
350
|
}
|
|
269
351
|
return null
|
|
352
|
+
} else if (isToolFamilyModule(row.name) && !hasClassifierVerdict(row.name)) {
|
|
353
|
+
// Readable specifier, tool family, NO verdict: kept and reported. The removal
|
|
354
|
+
// rule is a closed list, so without this branch a tool row this plugin has
|
|
355
|
+
// never seen was copied into the WSL variant in silence — the leak shape this
|
|
356
|
+
// transform exists to prevent, and the one a new upstream tool row would have
|
|
357
|
+
// taken. Kept rather than removed for the same reason as the unreadable case
|
|
358
|
+
// above: the transform must not guess a row away from a preset.
|
|
359
|
+
unclassified.push({ id: row.id ?? null, name: row.name })
|
|
270
360
|
}
|
|
271
361
|
// The registry stores the caller's objects BY REFERENCE — mutating a row
|
|
272
362
|
// here would pollute the shared base definition. Clone per row;
|