dsh-better-workspace 0.32.0 → 0.32.2
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/package.json +3 -2
- package/src/client.js +107 -45
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-better-workspace",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.2",
|
|
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; the New Session workspace picker shows the same tree.",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-better-workspace",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.2",
|
|
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), and the same tree in the New Session workspace picker; add-workspace rides the official directory flow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"@deepseek-ai/dsh-client-locale",
|
|
31
31
|
"@deepseek-ai/dsh-client-ui-slots",
|
|
32
32
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
33
|
-
"@deepseek-ai/dsh-client-modules"
|
|
33
|
+
"@deepseek-ai/dsh-client-modules",
|
|
34
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
34
35
|
],
|
|
35
36
|
"platform": "web"
|
|
36
37
|
}
|
package/src/client.js
CHANGED
|
@@ -6937,9 +6937,14 @@ window.__ModuleLoader__.load({
|
|
|
6937
6937
|
sidebarFlowEntry,
|
|
6938
6938
|
shippedBrowserFace, scheduleSeatReader,
|
|
6939
6939
|
officialT,
|
|
6940
|
-
|
|
6940
|
+
presetFaceOf,
|
|
6941
6941
|
t,
|
|
6942
6942
|
} = props
|
|
6943
|
+
// v0.32.2: resolve the stable getter ONCE per render (see
|
|
6944
|
+
// browserInjected for why this is a function and not a value prop).
|
|
6945
|
+
// Every consumer below keeps reading this local, so a late-arriving
|
|
6946
|
+
// agent-preset service is picked up by the next render's menu build.
|
|
6947
|
+
const presetFace = typeof presetFaceOf === 'function' ? presetFaceOf() : null
|
|
6943
6948
|
|
|
6944
6949
|
if (typeof useWorkspaces !== 'function' || typeof useSessions !== 'function') {
|
|
6945
6950
|
console.error('[dsh-better-workspace] standard snapshot hooks missing; browser renders nothing')
|
|
@@ -9360,53 +9365,99 @@ window.__ModuleLoader__.load({
|
|
|
9360
9365
|
let officialT = null
|
|
9361
9366
|
try { officialT = ctx.locale.bind('workspace') } catch { officialT = null }
|
|
9362
9367
|
|
|
9363
|
-
// v0.32.
|
|
9364
|
-
// channels the official hero preset chip uses.
|
|
9365
|
-
//
|
|
9366
|
-
//
|
|
9368
|
+
// v0.32.2: the agent-preset face — {list, select} over the same remote
|
|
9369
|
+
// channels the official hero preset chip uses. Root cause of the hidden
|
|
9370
|
+
// menu row, straight from the dsh 0.2.1 source (cordis 4.0.5): 'remote'
|
|
9371
|
+
// is a fiber service provided by the api-gateway bundle, and
|
|
9372
|
+
// 'remote.agentPresets' is a NAMESPACE service installed by api-remotes
|
|
9373
|
+
// ($mount) on its own child fiber. `ctx.remote` resolves through the
|
|
9374
|
+
// property chain only along the reading fiber's ancestry — v0.32.1
|
|
9375
|
+
// probed it from a fiber outside that subtree, the chain threw, and the
|
|
9376
|
+
// row hid; v0.32.0's strict ctx.get ran before the gateway went ACTIVE
|
|
9377
|
+
// and read undefined. The fix keeps NO hard inject (the settingsScope
|
|
9378
|
+
// lesson: a service the host lacks would pend this bundle forever):
|
|
9379
|
+
// probe synchronously for the common case, then WAIT with a soft
|
|
9380
|
+
// ctx.inject child fiber that fires once the two services go ACTIVE —
|
|
9381
|
+
// or pends harmlessly forever on hosts without them. The face reaches
|
|
9382
|
+
// the sidebar as a stable GETTER prop (see browserInjected) because the
|
|
9383
|
+
// slot renderer caches the inject result per entry and would otherwise
|
|
9384
|
+
// bake in a null until the entry re-registers.
|
|
9367
9385
|
let presetFace = null
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
} catch (error) {
|
|
9401
|
-
return { ok: false, refusal: error instanceof Error ? error.message : String(error) }
|
|
9402
|
-
}
|
|
9403
|
-
},
|
|
9386
|
+
const presetFaceReady = (candidate) => candidate
|
|
9387
|
+
&& typeof candidate.list === 'function' && typeof candidate.select === 'function'
|
|
9388
|
+
const buildPresetFace = (agentPresets) => ({
|
|
9389
|
+
// readRoster mirror: a gateway hiccup
|
|
9390
|
+
// ('gateway/invocation-unavailable') maps to an EMPTY roster,
|
|
9391
|
+
// exactly like the official selector does; every other failure
|
|
9392
|
+
// surfaces with its message.
|
|
9393
|
+
list: async () => {
|
|
9394
|
+
try {
|
|
9395
|
+
const result = await agentPresets.list()
|
|
9396
|
+
if (result && result.ok) return { ok: true, presets: (result.value && result.value.presets) || [] }
|
|
9397
|
+
const code = result && result.error ? result.error.code : undefined
|
|
9398
|
+
if (code === 'gateway/invocation-unavailable') return { ok: true, presets: [] }
|
|
9399
|
+
return { ok: false, error: result && result.error ? result.error.message : 'preset roster read failed' }
|
|
9400
|
+
} catch (error) {
|
|
9401
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) }
|
|
9402
|
+
}
|
|
9403
|
+
},
|
|
9404
|
+
// seat-store apply() mirror: a refusal carries the host's reason
|
|
9405
|
+
// (error.details.reason when present); the outer call can throw,
|
|
9406
|
+
// so a throw folds into the same {ok:false} shape.
|
|
9407
|
+
select: async (sessionId, presetId) => {
|
|
9408
|
+
try {
|
|
9409
|
+
const result = await agentPresets.select(sessionId, presetId)
|
|
9410
|
+
if (result && result.ok) return { ok: true }
|
|
9411
|
+
const details = result && result.error ? result.error.details : undefined
|
|
9412
|
+
const reason = details && typeof details.reason === 'string'
|
|
9413
|
+
? details.reason
|
|
9414
|
+
: (result && result.error ? result.error.message : 'preset select failed')
|
|
9415
|
+
return { ok: false, refusal: reason }
|
|
9416
|
+
} catch (error) {
|
|
9417
|
+
return { ok: false, refusal: error instanceof Error ? error.message : String(error) }
|
|
9404
9418
|
}
|
|
9419
|
+
},
|
|
9420
|
+
})
|
|
9421
|
+
try {
|
|
9422
|
+
let agentPresets = null
|
|
9423
|
+
try {
|
|
9424
|
+
const remote = ctx.remote
|
|
9425
|
+
agentPresets = remote && remote.agentPresets
|
|
9426
|
+
} catch { /* the property chain needs the service on this fiber's path */ }
|
|
9427
|
+
if (!presetFaceReady(agentPresets)) {
|
|
9428
|
+
try {
|
|
9429
|
+
const remote = ctx.get('remote')
|
|
9430
|
+
agentPresets = remote && remote.agentPresets
|
|
9431
|
+
} catch { /* strict get yields nothing while the provider pends */ }
|
|
9405
9432
|
}
|
|
9433
|
+
if (presetFaceReady(agentPresets)) presetFace = buildPresetFace(agentPresets)
|
|
9406
9434
|
} catch (presetFaceError) {
|
|
9407
9435
|
console.warn('[dsh-better-workspace] agent-preset face unavailable', presetFaceError)
|
|
9408
9436
|
presetFace = null
|
|
9409
9437
|
}
|
|
9438
|
+
if (!presetFace && ctx && typeof ctx.inject === 'function') {
|
|
9439
|
+
// Late arrival: a soft child fiber that fires when the 'remote' +
|
|
9440
|
+
// 'remote.agentPresets' services go ACTIVE (the official
|
|
9441
|
+
// ui-agent-preset declares exactly these two). On hosts that never
|
|
9442
|
+
// mount them the fiber just pends — no effect, no error. The
|
|
9443
|
+
// namespace reads by its strict service name off the child fiber,
|
|
9444
|
+
// where the inject mechanism has cached it.
|
|
9445
|
+
try {
|
|
9446
|
+
ctx.inject(['remote', 'remote.agentPresets'], (fctx) => {
|
|
9447
|
+
try {
|
|
9448
|
+
const agentPresets = fctx && fctx['remote.agentPresets']
|
|
9449
|
+
if (presetFaceReady(agentPresets)) {
|
|
9450
|
+
presetFace = buildPresetFace(agentPresets)
|
|
9451
|
+
console.info('[dsh-better-workspace] agent-preset face ready (late arrival)')
|
|
9452
|
+
}
|
|
9453
|
+
} catch (lateError) {
|
|
9454
|
+
console.warn('[dsh-better-workspace] agent-preset late face failed', lateError)
|
|
9455
|
+
}
|
|
9456
|
+
})
|
|
9457
|
+
} catch (injectError) {
|
|
9458
|
+
console.warn('[dsh-better-workspace] agent-preset soft inject failed', injectError)
|
|
9459
|
+
}
|
|
9460
|
+
}
|
|
9410
9461
|
|
|
9411
9462
|
if (ctx.locale && typeof ctx.locale.register === 'function') {
|
|
9412
9463
|
ctx.effect(() => {
|
|
@@ -9461,10 +9512,15 @@ window.__ModuleLoader__.load({
|
|
|
9461
9512
|
// Official 'workspace' dictionary translate (menu copy follows upstream);
|
|
9462
9513
|
// null when the bind failed — the menu then uses the aligned bw copy.
|
|
9463
9514
|
officialT,
|
|
9464
|
-
// v0.32.
|
|
9465
|
-
//
|
|
9466
|
-
//
|
|
9467
|
-
presetFace
|
|
9515
|
+
// v0.32.2: the agent-preset face rides a stable GETTER, not a value.
|
|
9516
|
+
// The slot renderer caches the inject result per StoredEntry
|
|
9517
|
+
// (ui-renderer scoped-slots rootInjectCache), so a value prop would
|
|
9518
|
+
// bake in whatever presetFace was at first render — null whenever the
|
|
9519
|
+
// remote services arrived after this face was cached, permanently
|
|
9520
|
+
// hiding the workspace-preset menu row. The getter reads the apply
|
|
9521
|
+
// closure live, so every render and every menu build re-asks; hosts
|
|
9522
|
+
// without the service keep returning null, which simply hides the row.
|
|
9523
|
+
presetFaceOf: () => presetFace,
|
|
9468
9524
|
// The shipped sidebar's OWN face (dsh 0.1.7-rc.2): the shortcut request
|
|
9469
9525
|
// channel and the catalog of effective keybindings. Both belong to the
|
|
9470
9526
|
// entry this seat shadows, so they are read off the ledger and consumed
|
|
@@ -9701,6 +9757,12 @@ window.__ModuleLoader__.load({
|
|
|
9701
9757
|
|
|
9702
9758
|
return {
|
|
9703
9759
|
name: 'dsh-better-workspace',
|
|
9760
|
+
// v0.32.2: the list stays at the five era-guaranteed services (the
|
|
9761
|
+
// settingsScope lesson — a hard inject of anything a host may lack
|
|
9762
|
+
// pends this whole bundle forever). 'remote' + 'remote.agentPresets'
|
|
9763
|
+
// are acquired SOFTLY inside apply: a synchronous probe plus a
|
|
9764
|
+
// ctx.inject child fiber that waits for their ACTIVE transition
|
|
9765
|
+
// (see the agent-preset face block above).
|
|
9704
9766
|
inject: ['slots', 'sessions', 'workspaces', 'locale', 'uiWorkspace'],
|
|
9705
9767
|
apply,
|
|
9706
9768
|
}
|