dsh-wsl-tool 1.10.4 → 1.10.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.
- package/PUBLISHING.md +30 -0
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/assets/market-preview.html +217 -0
- package/assets/screenshot-1.png +0 -0
- package/lib/client.js +46 -19
- package/package.json +1 -1
package/PUBLISHING.md
CHANGED
|
@@ -160,6 +160,36 @@ package. "Not published" verdicts are re-probed daily, so a freshly published
|
|
|
160
160
|
version can take a day to appear; when it does, `install` switches from the
|
|
161
161
|
tarball URL to `dsh plugin --profile web add dsh-wsl-tool`.
|
|
162
162
|
|
|
163
|
+
## Market screenshots
|
|
164
|
+
|
|
165
|
+
The catalog's `screenshots` array is **generated from this repository**, not written
|
|
166
|
+
by hand: `screenshots.json` lists repo-relative paths and the site turns each one
|
|
167
|
+
into `https://raw.githubusercontent.com/XINY11451/dsh-wsl/HEAD/<path>`. That has two
|
|
168
|
+
consequences worth remembering:
|
|
169
|
+
|
|
170
|
+
- **Changing a preview is a commit here, not a listing PR.** The listing file's
|
|
171
|
+
hand-written keys are `url`, `name`, `category`, `tarball` and `description`;
|
|
172
|
+
everything else (including `screenshots`) is generated and must not be written by
|
|
173
|
+
hand. Only the description needs a PR against `awesome-dsh-plugin`.
|
|
174
|
+
- **Replacing a file in place refreshes the preview at the same URL**, which is why
|
|
175
|
+
`assets/screenshot-1.png` keeps its name across redesigns. GitHub's raw endpoint
|
|
176
|
+
caches, so a stale image can survive a few minutes to a day.
|
|
177
|
+
|
|
178
|
+
The current preview is rendered from `assets/market-preview.html` (the editable
|
|
179
|
+
source of truth) with headless Edge:
|
|
180
|
+
|
|
181
|
+
```powershell
|
|
182
|
+
& 'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe' --headless=new `
|
|
183
|
+
--disable-gpu --hide-scrollbars --force-device-scale-factor=2 `
|
|
184
|
+
--window-size=1280,800 --virtual-time-budget=3000 `
|
|
185
|
+
--user-data-dir="$env:TEMP\edge-shot" `
|
|
186
|
+
--screenshot="assets\screenshot-1.png" "file:///$PWD/assets/market-preview.html"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
It renders 2560×1600 (1280×800 at 2×) in a few seconds with no browser window. The
|
|
190
|
+
`--user-data-dir` keeps it away from the user's real Edge profile. Edit the HTML,
|
|
191
|
+
re-run, and commit the PNG: no build step, no design tool.
|
|
192
|
+
|
|
163
193
|
## Things that bite
|
|
164
194
|
|
|
165
195
|
- **A tag event runs the workflow from the tag's commit.** To change the
|
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ project kept on a Windows drive keeps **Windows** filesystem semantics — no PO
|
|
|
15
15
|
permissions, case-insensitive names, no file-change notifications — at a fraction
|
|
16
16
|
of the speed (see [Notes](#notes)).
|
|
17
17
|
|
|
18
|
+

|
|
19
|
+
|
|
18
20
|
## Tools
|
|
19
21
|
|
|
20
22
|
The plugin registers three tools:
|
package/README.zh-CN.md
CHANGED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>dsh-wsl 功能介绍</title>
|
|
6
|
+
<style>
|
|
7
|
+
:root {
|
|
8
|
+
--bg: #0d1017;
|
|
9
|
+
--panel: #141922;
|
|
10
|
+
--panel-2: #1a212c;
|
|
11
|
+
--line: #263041;
|
|
12
|
+
--text: #e7ecf3;
|
|
13
|
+
--dim: #9aa7b8;
|
|
14
|
+
--dim-2: #6d7a8c;
|
|
15
|
+
--accent: #4f8cff;
|
|
16
|
+
--accent-2: #46d3a4;
|
|
17
|
+
--warn: #f0a33c;
|
|
18
|
+
}
|
|
19
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
20
|
+
html, body { width: 1280px; height: 800px; overflow: hidden; }
|
|
21
|
+
body {
|
|
22
|
+
background: radial-gradient(1100px 520px at 12% -12%, #1b2740 0%, var(--bg) 62%), var(--bg);
|
|
23
|
+
color: var(--text);
|
|
24
|
+
font-family: "Segoe UI", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
|
|
25
|
+
padding: 40px 44px;
|
|
26
|
+
display: flex; flex-direction: column; gap: 22px;
|
|
27
|
+
}
|
|
28
|
+
header { display: flex; align-items: flex-start; justify-content: space-between; }
|
|
29
|
+
.title { display: flex; align-items: center; gap: 14px; }
|
|
30
|
+
.mark {
|
|
31
|
+
width: 46px; height: 46px; border-radius: 12px;
|
|
32
|
+
background: linear-gradient(140deg, #2d6ae0, #46d3a4);
|
|
33
|
+
display: flex; align-items: center; justify-content: center;
|
|
34
|
+
font-size: 22px; font-weight: 700; color: #071018; letter-spacing: -1px;
|
|
35
|
+
}
|
|
36
|
+
h1 { font-size: 27px; letter-spacing: .3px; }
|
|
37
|
+
h1 span { color: var(--accent); }
|
|
38
|
+
.sub { color: var(--dim); font-size: 13.5px; margin-top: 5px; }
|
|
39
|
+
.badges { display: flex; gap: 8px; }
|
|
40
|
+
.badge {
|
|
41
|
+
border: 1px solid var(--line); background: var(--panel);
|
|
42
|
+
border-radius: 999px; padding: 5px 11px; font-size: 12px; color: var(--dim);
|
|
43
|
+
}
|
|
44
|
+
.badge.on { color: var(--accent-2); border-color: #2b5c4c; background: #10231d; }
|
|
45
|
+
main { display: grid; grid-template-columns: 1fr 430px; gap: 26px; flex: 1; min-height: 0; }
|
|
46
|
+
.col { display: flex; flex-direction: column; gap: 18px; min-height: 0; }
|
|
47
|
+
section .head {
|
|
48
|
+
font-size: 12px; letter-spacing: 2px; color: var(--dim-2);
|
|
49
|
+
text-transform: uppercase; margin-bottom: 9px;
|
|
50
|
+
}
|
|
51
|
+
.cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
|
52
|
+
.card {
|
|
53
|
+
background: linear-gradient(180deg, var(--panel), #121721);
|
|
54
|
+
border: 1px solid var(--line); border-radius: 10px; padding: 12px 13px;
|
|
55
|
+
}
|
|
56
|
+
.card b { font-size: 14px; display: block; }
|
|
57
|
+
.card code {
|
|
58
|
+
font-family: Consolas, "Cascadia Mono", monospace; font-size: 12.5px;
|
|
59
|
+
color: var(--accent-2); background: #0e1a18; border: 1px solid #1e3d36;
|
|
60
|
+
border-radius: 5px; padding: 1px 5px;
|
|
61
|
+
}
|
|
62
|
+
.card p { color: var(--dim); font-size: 12px; margin-top: 6px; line-height: 1.55; }
|
|
63
|
+
.card.wide { grid-column: 1 / -1; }
|
|
64
|
+
.limits { border-color: #3a2f1d; background: linear-gradient(180deg, #1b1710, #14120c); }
|
|
65
|
+
.limits b { color: var(--warn); }
|
|
66
|
+
.panel {
|
|
67
|
+
background: linear-gradient(180deg, #151b25, #10151d);
|
|
68
|
+
border: 1px solid var(--line); border-radius: 14px; padding: 15px 16px;
|
|
69
|
+
display: flex; flex-direction: column; gap: 11px; min-height: 0;
|
|
70
|
+
}
|
|
71
|
+
.panel .bar { display: flex; justify-content: space-between; align-items: center; }
|
|
72
|
+
.panel .bar .t { font-size: 15px; font-weight: 600; }
|
|
73
|
+
.panel .bar .r { font-size: 11.5px; color: var(--accent); border: 1px solid #24406e; background: #101b2e; border-radius: 6px; padding: 3px 8px; }
|
|
74
|
+
.panel .note { font-size: 11.5px; color: var(--dim-2); }
|
|
75
|
+
.row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
|
76
|
+
.row .l { min-width: 0; }
|
|
77
|
+
.row .l b { font-size: 13px; font-weight: 600; display: block; }
|
|
78
|
+
.row .l p { font-size: 11.5px; color: var(--dim); margin-top: 3px; line-height: 1.5; }
|
|
79
|
+
.sw {
|
|
80
|
+
flex: none; width: 34px; height: 19px; border-radius: 999px;
|
|
81
|
+
background: #263041; position: relative; margin-top: 2px;
|
|
82
|
+
}
|
|
83
|
+
.sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: #6d7a8c; }
|
|
84
|
+
.sw.on { background: #1d4ed8; }
|
|
85
|
+
.sw.on::after { left: 17px; background: #dce8ff; }
|
|
86
|
+
.sw.risk { background: #4a3416; }
|
|
87
|
+
.sw.risk::after { left: 17px; background: #f0c37a; }
|
|
88
|
+
.group { display: flex; flex-direction: column; gap: 9px; }
|
|
89
|
+
.group + .group { border-top: 1px dashed var(--line); padding-top: 10px; }
|
|
90
|
+
.reset { display: flex; justify-content: flex-end; align-items: center; gap: 8px; font-size: 11.5px; color: var(--dim); }
|
|
91
|
+
.reset .pill { border: 1px solid #24406e; background: #101b2e; color: #b9cdf5; border-radius: 6px; padding: 3px 8px; }
|
|
92
|
+
footer {
|
|
93
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
94
|
+
border-top: 1px solid var(--line); padding-top: 14px;
|
|
95
|
+
color: var(--dim-2); font-size: 12px;
|
|
96
|
+
}
|
|
97
|
+
footer code {
|
|
98
|
+
font-family: Consolas, "Cascadia Mono", monospace; color: var(--text);
|
|
99
|
+
background: #0b0f15; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px;
|
|
100
|
+
}
|
|
101
|
+
footer .right { text-align: right; }
|
|
102
|
+
</style>
|
|
103
|
+
</head>
|
|
104
|
+
<body>
|
|
105
|
+
<header>
|
|
106
|
+
<div class="title">
|
|
107
|
+
<div class="mark">W​SL</div>
|
|
108
|
+
<div>
|
|
109
|
+
<h1>DSH <span>×</span> WSL</h1>
|
|
110
|
+
<div class="sub">在 Windows 上执行 Linux 命令 —— 命令执行层基本对齐原生 Linux DSH</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="badges">
|
|
114
|
+
<div class="badge on">左侧栏开关面板</div>
|
|
115
|
+
<div class="badge">可选:侧边栏 WSL 终端</div>
|
|
116
|
+
<div class="badge">零依赖</div>
|
|
117
|
+
</div>
|
|
118
|
+
</header>
|
|
119
|
+
|
|
120
|
+
<main>
|
|
121
|
+
<div class="col">
|
|
122
|
+
<section>
|
|
123
|
+
<div class="head">三个工具</div>
|
|
124
|
+
<div class="cards">
|
|
125
|
+
<div class="card">
|
|
126
|
+
<b><code>wsl</code> 命令执行</b>
|
|
127
|
+
<p>每次调用一个全新 shell;可喂 stdin、可设超时;退出码 / 信号 / 截断都如实回传。</p>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="card">
|
|
130
|
+
<b><code>wsl-path</code> 路径互转</b>
|
|
131
|
+
<p>Windows 路径 ↔ <code>/mnt/...</code>、<code>\\wsl.localhost\</code> 双向转换。</p>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="card">
|
|
134
|
+
<b><code>wsl-env</code> 能力体检</b>
|
|
135
|
+
<p>发行版、内核、systemd、cgroup、GPU 直通、docker、挂载盘与两侧配置一次看清。</p>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="card">
|
|
138
|
+
<b>长任务后台跑</b>
|
|
139
|
+
<p><code>runInBackground</code> 交给内置 job 工具读回 / 中止,前台超时不再拖死。</p>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="card wide">
|
|
142
|
+
<b>安全与可观测</b>
|
|
143
|
+
<p>危险命令守卫(删除 / 分区 / 关机需显式放行);输出按流上限截断,超限会自动落盘完整文件并提供路径。</p>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</section>
|
|
147
|
+
|
|
148
|
+
<section>
|
|
149
|
+
<div class="head">如实说明的限制</div>
|
|
150
|
+
<div class="cards">
|
|
151
|
+
<div class="card wide limits">
|
|
152
|
+
<b>两条边界</b>
|
|
153
|
+
<p>① WSL 调用发生在 DSH 沙箱层之下,文件策略约束不到它;② 项目放在 Windows 盘时仍是 Windows 文件系统语义(9p:慢、无 inotify、权限位不生效)。</p>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
|
|
158
|
+
<section>
|
|
159
|
+
<div class="head">一次真实调用</div>
|
|
160
|
+
<div class="card wide">
|
|
161
|
+
<b><code>wsl</code> · <code>wsl "cd /mnt/d/proj && npm test"</code></b>
|
|
162
|
+
<p>返回 stdout / stderr / exitCode,并标记信号、超时与截断;长任务加 <code>runInBackground: true</code> 拿 jobId,用 <code>job_output</code> / <code>job_kill</code> 读回或中止。可选一条 patch 还能把桌面版「新建终端」指向 WSL(真 PTY,默认不开)。</p>
|
|
163
|
+
</div>
|
|
164
|
+
</section>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<div class="panel">
|
|
168
|
+
<div class="bar">
|
|
169
|
+
<div class="t">WSL</div>
|
|
170
|
+
<div class="r">全部恢复默认</div>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="note">工具开关下次启动生效;其余开关即时生效。</div>
|
|
173
|
+
|
|
174
|
+
<div class="group">
|
|
175
|
+
<div class="row">
|
|
176
|
+
<div class="l"><b>wsl 命令执行</b><p>注册 <code>wsl</code> 工具:在 WSL 里执行 Linux 命令</p></div>
|
|
177
|
+
<div class="sw on"></div>
|
|
178
|
+
</div>
|
|
179
|
+
<div class="row">
|
|
180
|
+
<div class="l"><b>wsl-path 路径转换</b><p>注册 <code>wsl-path</code> 工具:路径互转</p></div>
|
|
181
|
+
<div class="sw on"></div>
|
|
182
|
+
</div>
|
|
183
|
+
<div class="row">
|
|
184
|
+
<div class="l"><b>wsl-env 能力体检</b><p>注册 <code>wsl-env</code> 工具:汇总 WSL 能力</p></div>
|
|
185
|
+
<div class="sw on"></div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<div class="group">
|
|
190
|
+
<div class="row">
|
|
191
|
+
<div class="l"><b>后台任务</b><p>允许 <code>runInBackground</code>,由 job 工具读回</p></div>
|
|
192
|
+
<div class="sw on"></div>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="row">
|
|
195
|
+
<div class="l"><b>自动转换路径</b><p>命令里的 Windows 路径自动转成 <code>/mnt/...</code></p></div>
|
|
196
|
+
<div class="sw on"></div>
|
|
197
|
+
</div>
|
|
198
|
+
<div class="row">
|
|
199
|
+
<div class="l"><b>默认跟随会话工作区</b><p>未传 workdir 时从会话目录开始</p></div>
|
|
200
|
+
<div class="sw"></div>
|
|
201
|
+
</div>
|
|
202
|
+
<div class="row">
|
|
203
|
+
<div class="l"><b>危险命令守卫</b><p>删除、分区、关机等必须显式放行</p></div>
|
|
204
|
+
<div class="sw on risk"></div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
<div class="reset"><span>已覆盖项可一键清除</span><span class="pill">每行只留「已覆盖」标记</span></div>
|
|
209
|
+
</div>
|
|
210
|
+
</main>
|
|
211
|
+
|
|
212
|
+
<footer>
|
|
213
|
+
<div>安装:<code>dsh plugin --profile web add dsh-wsl-tool</code></div>
|
|
214
|
+
<div class="right">github.com/XINY11451/dsh-wsl · dsh-wsl-tool</div>
|
|
215
|
+
</footer>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
package/assets/screenshot-1.png
CHANGED
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -306,12 +306,17 @@ window.__ModuleLoader__.load({
|
|
|
306
306
|
* a refusal, so this panel does the same — `false` means "not saved", and
|
|
307
307
|
* the panel words it instead of pretending the switch moved.
|
|
308
308
|
*/
|
|
309
|
-
write: async (
|
|
309
|
+
write: async (ops) => {
|
|
310
310
|
const snapshot = read()
|
|
311
311
|
if (scope === undefined || typeof scope.mutate !== 'function') return false
|
|
312
312
|
if (snapshot.writable !== true) return false
|
|
313
|
+
// One op or an ordered batch: the service applies a batch in one
|
|
314
|
+
// revision-fenced write, which is what the panel's single "restore every
|
|
315
|
+
// default" control uses.
|
|
316
|
+
const batch = Array.isArray(ops) ? ops : [ops]
|
|
317
|
+
if (batch.length === 0) return true
|
|
313
318
|
try {
|
|
314
|
-
const landed = await scope.mutate(
|
|
319
|
+
const landed = await scope.mutate(batch, snapshot.revision)
|
|
315
320
|
return Boolean(landed)
|
|
316
321
|
} catch (error) {
|
|
317
322
|
console.error('dsh-wsl-tool: writing the configuration failed', error)
|
|
@@ -360,6 +365,14 @@ window.__ModuleLoader__.load({
|
|
|
360
365
|
const ROW_COPY_STYLE = { display: 'flex', flexDirection: 'column', gap: '2px', minWidth: 0 }
|
|
361
366
|
const ROW_LABEL_STYLE = { display: 'flex', alignItems: 'center', gap: '6px', fontWeight: 500 }
|
|
362
367
|
const ROW_ACTIONS_STYLE = { display: 'flex', alignItems: 'center', gap: '8px', flexShrink: 0 }
|
|
368
|
+
/** The panel's single override bar; `rowGap` keeps it readable above the rows. */
|
|
369
|
+
const OVERRIDE_BAR_STYLE = {
|
|
370
|
+
display: 'flex',
|
|
371
|
+
alignItems: 'center',
|
|
372
|
+
gap: '8px',
|
|
373
|
+
justifyContent: 'flex-end',
|
|
374
|
+
padding: '6px 0',
|
|
375
|
+
}
|
|
363
376
|
const HINT_STYLE = { margin: 0, color: LABEL_TERTIARY, fontSize: '12px', lineHeight: '18px', maxWidth: '66ch' }
|
|
364
377
|
const BADGE_STYLE = {
|
|
365
378
|
border: '0.5px solid ' + BORDER_BADGE,
|
|
@@ -497,8 +510,9 @@ window.__ModuleLoader__.load({
|
|
|
497
510
|
})
|
|
498
511
|
}
|
|
499
512
|
|
|
500
|
-
/** One switch row:
|
|
501
|
-
*
|
|
513
|
+
/** One switch row: copy on the left, an override badge and the switch on the
|
|
514
|
+
* right. Clearing overrides is NOT offered per row — the panel has one
|
|
515
|
+
* control for that, so eleven rows do not repeat the same button. */
|
|
502
516
|
const rowElement = (row) => {
|
|
503
517
|
const key = row.path.join('.')
|
|
504
518
|
const overridden = hasPath(snapshot.user, row.path)
|
|
@@ -523,21 +537,6 @@ window.__ModuleLoader__.load({
|
|
|
523
537
|
'div',
|
|
524
538
|
{ style: ROW_ACTIONS_STYLE },
|
|
525
539
|
overridden ? React.createElement('span', { style: BADGE_STYLE }, '已覆盖') : null,
|
|
526
|
-
overridden
|
|
527
|
-
? React.createElement(
|
|
528
|
-
'button',
|
|
529
|
-
{
|
|
530
|
-
type: 'button',
|
|
531
|
-
style: RESET_STYLE,
|
|
532
|
-
disabled,
|
|
533
|
-
// Returned as well as performed: React ignores a handler's
|
|
534
|
-
// return value, but awaiting it is how a test sees the write
|
|
535
|
-
// settle.
|
|
536
|
-
onClick: () => submit({ op: 'unset', path: row.path }, key),
|
|
537
|
-
},
|
|
538
|
-
'恢复默认',
|
|
539
|
-
)
|
|
540
|
-
: null,
|
|
541
540
|
React.createElement(primitives.Switch, {
|
|
542
541
|
checked,
|
|
543
542
|
label: row.label,
|
|
@@ -580,9 +579,37 @@ window.__ModuleLoader__.load({
|
|
|
580
579
|
React.createElement('p', { key: 'note-unavailable', style: NOTE_STYLE }, '此 DSH 未提供该插件的配置作用域'),
|
|
581
580
|
)
|
|
582
581
|
} else {
|
|
582
|
+
const overriddenPaths = SECTIONS
|
|
583
|
+
.flatMap((group) => group.rows)
|
|
584
|
+
.filter((row) => hasPath(snapshot.user, row.path))
|
|
585
|
+
.map((row) => row.path)
|
|
583
586
|
const blocks = SECTIONS.map((group) =>
|
|
584
587
|
section(group.id, group.title, React.createElement('div', { style: ROWS_STYLE }, group.rows.map(rowElement))),
|
|
585
588
|
)
|
|
589
|
+
// ONE place to clear every override, instead of the same button repeated on
|
|
590
|
+
// every row. "Put this panel back the way the composition had it" is one
|
|
591
|
+
// intention, and the settings service takes it as one revision-fenced write.
|
|
592
|
+
if (overriddenPaths.length > 0) {
|
|
593
|
+
blocks.unshift(
|
|
594
|
+
React.createElement(
|
|
595
|
+
'div',
|
|
596
|
+
{ key: 'overrides', style: OVERRIDE_BAR_STYLE },
|
|
597
|
+
React.createElement('span', { style: BADGE_STYLE }, '已覆盖 ' + overriddenPaths.length + ' 项'),
|
|
598
|
+
React.createElement(
|
|
599
|
+
'button',
|
|
600
|
+
{
|
|
601
|
+
type: 'button',
|
|
602
|
+
style: RESET_STYLE,
|
|
603
|
+
disabled: snapshot.writable !== true || busy !== undefined,
|
|
604
|
+
// Returned as well as performed: React ignores a handler's return
|
|
605
|
+
// value, but awaiting it is how a test sees the write settle.
|
|
606
|
+
onClick: () => submit(overriddenPaths.map((path) => ({ op: 'unset', path })), 'all-overrides'),
|
|
607
|
+
},
|
|
608
|
+
'全部恢复默认',
|
|
609
|
+
),
|
|
610
|
+
),
|
|
611
|
+
)
|
|
612
|
+
}
|
|
586
613
|
if (refused) {
|
|
587
614
|
blocks.unshift(
|
|
588
615
|
React.createElement('p', { key: 'note-refused', style: NOTE_STYLE }, '保存被拒绝:配置没有被写入,请重试'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-wsl-tool",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.6",
|
|
4
4
|
"description": "Run Linux commands from Windows through WSL, essentially matching a native Linux DSH for command execution: background jobs, stdin, path translation, a destructive-command guard and a WSL capability report. A left-sidebar panel switches each capability on or off, each with a one-line explanation, and an opt-in patch gives the desktop app's sidebar terminal a WSL shell. WSL calls run below the DSH sandbox, and a project on a Windows drive keeps Windows filesystem semantics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|