dsh-wsl-tool 1.10.4 → 1.10.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/client.js +46 -19
- package/package.json +1 -1
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.5",
|
|
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",
|