dsh-better-workspace 0.18.0 → 0.19.0
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/dsh.plugin.json +1 -1
- package/icon.svg +5 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +10 -3
- package/src/client.js +47 -14
- package/src/index.js +43 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-better-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);添加工作区由官方目录流承载。Workspace tree for the DSH sidebar workspace list, nested by official disk folders with optional \"/\"-name grouping.",
|
|
6
6
|
"engines": {
|
package/icon.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" fill="none">
|
|
2
|
+
<path d="M4 10.5A2.5 2.5 0 0 1 6.5 8h6l2.4 2.8H29.5A2.5 2.5 0 0 1 32 13.3V26a2.5 2.5 0 0 1-2.5 2.5h-23A2.5 2.5 0 0 1 4 26V10.5z" stroke="#4493f8" stroke-width="1.7" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M11 17.5h9M11 21.5h14" stroke="#4493f8" stroke-width="1.5" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="24.5" cy="17.5" r="1.3" fill="#f0883e"/>
|
|
5
|
+
</svg>
|
package/locale/en.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Better Workspace",
|
|
4
|
+
"description": "Upgrades the sidebar workspace list into a two-layer hierarchy tree (disk nesting by the official owningParentFolder semantics, optional name-slash grouping), explicit empty folders, appearance customization with live preview, and the official add-workspace flow for every backend."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-better-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);添加工作区走官方目录流。Workspace tree for the DSH sidebar: disk-path nesting (official workspace-tree semantics), with optional \"/\"-name grouping (off by default); add-workspace rides the official directory flow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"main": "src/index.js",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": "./src/index.js",
|
|
16
|
-
"./client": "./src/client.js"
|
|
16
|
+
"./client": "./src/client.js",
|
|
17
|
+
"./locale/*.json": "./locale/*.json"
|
|
17
18
|
},
|
|
18
19
|
"engines": {
|
|
19
20
|
"node": ">=18",
|
|
@@ -41,7 +42,9 @@
|
|
|
41
42
|
"dsh.plugin.json",
|
|
42
43
|
"README.md",
|
|
43
44
|
"README_EN.md",
|
|
44
|
-
"LICENSE"
|
|
45
|
+
"LICENSE",
|
|
46
|
+
"locale",
|
|
47
|
+
"icon.svg"
|
|
45
48
|
],
|
|
46
49
|
"scripts": {
|
|
47
50
|
"test": "node --test tests/smoke.mjs",
|
|
@@ -64,5 +67,9 @@
|
|
|
64
67
|
"homepage": "https://github.com/KannaKuron/dsh-better-workspace",
|
|
65
68
|
"bugs": {
|
|
66
69
|
"url": "https://github.com/KannaKuron/dsh-better-workspace/issues"
|
|
70
|
+
},
|
|
71
|
+
"icon": "./icon.svg",
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
67
74
|
}
|
|
68
75
|
}
|
package/src/client.js
CHANGED
|
@@ -3683,6 +3683,10 @@ window.__ModuleLoader__.load({
|
|
|
3683
3683
|
// simply never mirror and never sync, which is exactly the pre-0.9.5
|
|
3684
3684
|
// browser-local behavior.
|
|
3685
3685
|
let prefsScopeRef = null
|
|
3686
|
+
// 'settingsScope' (dsh <= 0.1.6, the shared ~/.dsh/settings.yaml home —
|
|
3687
|
+
// the only world where CROSS-DEVICE sync makes sense) or 'configForms'
|
|
3688
|
+
// (dsh >= 0.1.7, per-profile patch persistence). null = browser-local.
|
|
3689
|
+
let prefsScopeVia = null
|
|
3686
3690
|
const HOST_SNAP_UNAVAILABLE = { status: 'unavailable', value: undefined }
|
|
3687
3691
|
const hostPrefsOf = (snap) => (snap && snap.status === 'ready' && snap.value && typeof snap.value === 'object'
|
|
3688
3692
|
? snap.value
|
|
@@ -4864,19 +4868,24 @@ window.__ModuleLoader__.load({
|
|
|
4864
4868
|
E(BTN, { variant: 'outline', onClick: () => setAppearance(DEFAULT_APPEARANCE) }, t('settings.appearance.reset')),
|
|
4865
4869
|
),
|
|
4866
4870
|
),
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4871
|
+
// Manual cross-device sync exists only where a SHARED host home does
|
|
4872
|
+
// (dsh <= 0.1.6 settings.yaml; both surfaces read one file). On
|
|
4873
|
+
// dsh >= 0.1.7 settings persist per profile, so the section hides.
|
|
4874
|
+
prefsScopeVia === 'settingsScope' ? E(React.Fragment, null,
|
|
4875
|
+
E('div', { className: 'bw-setting-label', style: { marginTop: 16 } }, t('sync.title')),
|
|
4876
|
+
E('div', { className: 'bw-hint' }, t('sync.desc')),
|
|
4877
|
+
E('div', { className: 'bw-sync-modes' },
|
|
4878
|
+
modeButton('overwrite', t('sync.mode.overwrite')),
|
|
4879
|
+
modeButton('merge', t('sync.mode.merge')),
|
|
4880
|
+
),
|
|
4881
|
+
E('div', { className: 'bw-sync-actions' },
|
|
4882
|
+
syncActionButton(t(IS_DESKTOP_SURFACE ? 'sync.pull.web' : 'sync.pull.desktop'), onPull, true, !scopeLive || snap.status === 'loading'),
|
|
4883
|
+
syncActionButton(t('sync.push'), onPush, false, !scopeLive),
|
|
4884
|
+
),
|
|
4885
|
+
syncMsg !== null ? E('div', { className: 'bw-hint' }, syncMsg)
|
|
4886
|
+
: (scopeLive ? null : E('div', { className: 'bw-hint' }, t('sync.off'))),
|
|
4887
|
+
scopeLive && snap.status === 'loading' ? E('div', { className: 'bw-hint' }, t('sync.loading')) : null,
|
|
4888
|
+
) : null,
|
|
4880
4889
|
)
|
|
4881
4890
|
}
|
|
4882
4891
|
|
|
@@ -6788,14 +6797,38 @@ window.__ModuleLoader__.load({
|
|
|
6788
6797
|
// block). Binding is best-effort: a missing/failed bind leaves the
|
|
6789
6798
|
// plugin fully browser-local — the pre-0.9.5 behavior.
|
|
6790
6799
|
prefsScopeRef = null
|
|
6800
|
+
prefsScopeVia = null
|
|
6791
6801
|
try {
|
|
6792
6802
|
if (ctx.settingsScope && typeof ctx.settingsScope.bind === 'function') {
|
|
6793
6803
|
prefsScopeRef = ctx.settingsScope.bind({ namespace: 'better-workspace' })
|
|
6804
|
+
prefsScopeVia = 'settingsScope'
|
|
6794
6805
|
}
|
|
6795
6806
|
} catch (error) {
|
|
6796
6807
|
console.warn('[dsh-better-workspace] settings scope bind failed; sync stays local', error)
|
|
6797
6808
|
prefsScopeRef = null
|
|
6798
6809
|
}
|
|
6810
|
+
// dsh >= 0.1.7: the settings service is gone; one ConfigForm per live
|
|
6811
|
+
// profile entry replaces it (same getSnapshot/set/subscribe contract).
|
|
6812
|
+
// Values then persist in THIS profile's patch — there is no shared home
|
|
6813
|
+
// any more, so the manual cross-device sync section stays hidden.
|
|
6814
|
+
try {
|
|
6815
|
+
if (ctx.inject) {
|
|
6816
|
+
ctx.inject(['configForms'], (fctx) => {
|
|
6817
|
+
try {
|
|
6818
|
+
if (prefsScopeVia === 'settingsScope') return
|
|
6819
|
+
const forms = fctx && fctx.configForms
|
|
6820
|
+
if (forms && typeof forms.get === 'function') {
|
|
6821
|
+
prefsScopeRef = forms.get('better-workspace')
|
|
6822
|
+
prefsScopeVia = 'configForms'
|
|
6823
|
+
}
|
|
6824
|
+
} catch (error) {
|
|
6825
|
+
console.warn('[dsh-better-workspace] configForms acquisition failed', error)
|
|
6826
|
+
}
|
|
6827
|
+
})
|
|
6828
|
+
}
|
|
6829
|
+
} catch (error) {
|
|
6830
|
+
console.warn('[dsh-better-workspace] configForms wiring failed', error)
|
|
6831
|
+
}
|
|
6799
6832
|
|
|
6800
6833
|
// Settings → Plugins card only (the tab dispatches the intersection of
|
|
6801
6834
|
// served namespaces — registered host-side — and settings.plugin.item
|
|
@@ -6849,7 +6882,7 @@ window.__ModuleLoader__.load({
|
|
|
6849
6882
|
|
|
6850
6883
|
return {
|
|
6851
6884
|
name: 'dsh-better-workspace',
|
|
6852
|
-
inject: ['slots', 'sessions', 'workspaces', 'locale', 'uiWorkspace'
|
|
6885
|
+
inject: ['slots', 'sessions', 'workspaces', 'locale', 'uiWorkspace'],
|
|
6853
6886
|
apply,
|
|
6854
6887
|
}
|
|
6855
6888
|
},
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Schema from '@deepseek-ai/schemastery'
|
|
1
2
|
/**
|
|
2
3
|
* dsh-better-workspace — host half (plain JavaScript, no build step).
|
|
3
4
|
*
|
|
@@ -10,6 +11,36 @@
|
|
|
10
11
|
*/
|
|
11
12
|
export const name = 'dsh-better-workspace'
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* dsh >= 0.1.7 marks a Config field live-editable without remount; a
|
|
16
|
+
* 0.1.6-era schemastery predates the method and the guard keeps this module
|
|
17
|
+
* loadable there (values then behave as ordinary config, read through the
|
|
18
|
+
* registered settings namespace instead).
|
|
19
|
+
*/
|
|
20
|
+
function live(schema) {
|
|
21
|
+
return typeof schema.volatile === 'function' ? schema.volatile() : schema
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Row Config = the settings surface on dsh >= 0.1.7 (values persist under the
|
|
26
|
+
* row id 'better-workspace' — the same string as the old settings namespace,
|
|
27
|
+
* so the one-shot legacy settings.yaml import maps old user values onto the
|
|
28
|
+
* new home). Inert metadata on older hosts. NOTE: settings are per-profile
|
|
29
|
+
* on the new host; the client hides the manual cross-device sync section
|
|
30
|
+
* accordingly (the shared settings.yaml home no longer exists).
|
|
31
|
+
*/
|
|
32
|
+
export const Config = Schema.object({
|
|
33
|
+
compactChains: live(Schema.boolean().default(true)),
|
|
34
|
+
statusPulse: live(Schema.boolean().default(true)),
|
|
35
|
+
styling: live(Schema.dict(Schema.any()).default({})),
|
|
36
|
+
appearance: live(Schema.dict(Schema.any()).default({})),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
/** Read one Config value across eras: Volatile ref (>= 0.1.7) or plain value. */
|
|
40
|
+
export function valueOf(value) {
|
|
41
|
+
return value && typeof value.get === 'function' ? value.get() : value
|
|
42
|
+
}
|
|
43
|
+
|
|
13
44
|
export function apply(ctx) {
|
|
14
45
|
const log = ctx && ctx.logger && typeof ctx.logger.info === 'function'
|
|
15
46
|
? (msg) => ctx.logger.info(msg)
|
|
@@ -24,7 +55,18 @@ export function apply(ctx) {
|
|
|
24
55
|
// The dsh-settings and zod modules resolve only through the dsh Loader; the
|
|
25
56
|
// smoke test imports this file in plain Node with a logger-only ctx and
|
|
26
57
|
// never reaches this path.
|
|
27
|
-
|
|
58
|
+
// OLD-era namespace registration (dsh <= 0.1.6): the row Config above IS
|
|
59
|
+
// the surface on dsh >= 0.1.7 — register() no longer exists there and this
|
|
60
|
+
// block is skipped entirely.
|
|
61
|
+
const legacySettings = (() => {
|
|
62
|
+
try {
|
|
63
|
+
const settings = ctx.get('settings')
|
|
64
|
+
return !!(settings && typeof settings.register === 'function')
|
|
65
|
+
} catch {
|
|
66
|
+
return false
|
|
67
|
+
}
|
|
68
|
+
})()
|
|
69
|
+
if (legacySettings) ctx.inject(['settings'], (sctx) => {
|
|
28
70
|
log('[dsh-better-workspace] settings inject fired')
|
|
29
71
|
// The settings service calls the schema AS A FUNCTION to resolve a value
|
|
30
72
|
// (schema(mergeLayers(...))) — that is @deepseek-ai/schemastery's contract:
|