dsh-folder-sidebar 0.0.0-stage → 0.17.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/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +180 -3
- package/client.js +1766 -0
- package/cordis.patch.yml +4 -0
- package/icon.svg +6 -0
- package/index.js +93 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +66 -3
package/cordis.patch.yml
ADDED
package/icon.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Folder Sidebar">
|
|
2
|
+
<rect x="4" y="4" width="56" height="56" rx="14" fill="#3f6be0"/>
|
|
3
|
+
<path d="M14 22h13l4 5h19a3 3 0 0 1 3 3v14a3 3 0 0 1-3 3H14a3 3 0 0 1-3-3V25a3 3 0 0 1 3-3Z"
|
|
4
|
+
fill="none" stroke="#ffffff" stroke-width="4" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M24 36h16" stroke="#ffffff" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
6
|
+
</svg>
|
package/index.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host half of dsh-folder-sidebar.
|
|
3
|
+
*
|
|
4
|
+
* The sidebar replacement is Client-only except for one fact the Client cannot
|
|
5
|
+
* derive: whether a Session's most recent turn failed or was interrupted. A
|
|
6
|
+
* Session summary carries no failure field, so this projection folds
|
|
7
|
+
* `turn/start` and `turn/end` into a small client-visible state per Session.
|
|
8
|
+
*
|
|
9
|
+
* The Client reads it from the sessions list snapshot
|
|
10
|
+
* (`projectionsBySession[id].values['folder-sidebar/turn']`) — the value is
|
|
11
|
+
* computed here and streamed, never folded in the browser.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { z } from 'zod'
|
|
15
|
+
|
|
16
|
+
export const name = 'folder-sidebar'
|
|
17
|
+
export const inject = ['sessionProjections']
|
|
18
|
+
|
|
19
|
+
/** Must match the key the Client reads. */
|
|
20
|
+
const KEY = 'folder-sidebar/turn'
|
|
21
|
+
|
|
22
|
+
/** Bump when the folded state or its meaning changes; stale checkpoints drop. */
|
|
23
|
+
const STATE_VERSION = 3
|
|
24
|
+
|
|
25
|
+
const STATES = ['idle', 'running', 'completed', 'failed', 'interrupted', 'stopped']
|
|
26
|
+
|
|
27
|
+
const StateSchema = z.object({
|
|
28
|
+
state: z.enum(STATES),
|
|
29
|
+
turn: z.number(),
|
|
30
|
+
/** When the current state began (epoch ms); the folder status picks the oldest. */
|
|
31
|
+
since: z.number(),
|
|
32
|
+
reason: z.string().optional(),
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const ViewSchema = StateSchema
|
|
36
|
+
|
|
37
|
+
const IDLE = { state: 'idle', turn: 0, since: 0 }
|
|
38
|
+
|
|
39
|
+
/** Map one turn end onto the colour-relevant state. */
|
|
40
|
+
function endedState(reason, turn, since) {
|
|
41
|
+
if (reason === null || typeof reason !== 'object') return { state: 'idle', turn, since }
|
|
42
|
+
switch (reason.kind) {
|
|
43
|
+
case 'completed':
|
|
44
|
+
return { state: 'completed', turn, since }
|
|
45
|
+
case 'forked':
|
|
46
|
+
return { state: 'idle', turn, since }
|
|
47
|
+
case 'error':
|
|
48
|
+
return { state: 'failed', turn, since, reason: reason.error?.code ?? 'error' }
|
|
49
|
+
case 'blocked':
|
|
50
|
+
return { state: 'failed', turn, since, reason: 'blocked' }
|
|
51
|
+
case 'max-tokens':
|
|
52
|
+
return { state: 'failed', turn, since, reason: 'max-tokens' }
|
|
53
|
+
case 'interrupted':
|
|
54
|
+
return { state: 'interrupted', turn, since }
|
|
55
|
+
case 'aborted': {
|
|
56
|
+
// A user stop is not a failure: the sidebar shows it in the neutral tone.
|
|
57
|
+
const kind = reason.reason?.kind
|
|
58
|
+
if (kind === 'user') return { state: 'stopped', turn, since }
|
|
59
|
+
return { state: 'interrupted', turn, since, reason: kind ?? 'aborted' }
|
|
60
|
+
}
|
|
61
|
+
default:
|
|
62
|
+
return { state: 'idle', turn, since }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function apply(ctx) {
|
|
67
|
+
ctx.effect(() => ctx.sessionProjections.register({
|
|
68
|
+
key: KEY,
|
|
69
|
+
stateSchema: StateSchema,
|
|
70
|
+
stateVersion: STATE_VERSION,
|
|
71
|
+
init: () => IDLE,
|
|
72
|
+
apply(state, event) {
|
|
73
|
+
const time = typeof event.time === 'number' ? event.time : Date.now()
|
|
74
|
+
if (event.type === 'turn/start') {
|
|
75
|
+
const turn = event.data?.turn ?? state.turn
|
|
76
|
+
return { state: 'running', turn, since: time }
|
|
77
|
+
}
|
|
78
|
+
if (event.type !== 'turn/end') return state
|
|
79
|
+
return endedState(event.data?.reason, event.data?.turn ?? state.turn, time)
|
|
80
|
+
},
|
|
81
|
+
wire: {
|
|
82
|
+
viewSchema: ViewSchema,
|
|
83
|
+
view(state) {
|
|
84
|
+
return {
|
|
85
|
+
state: state.state,
|
|
86
|
+
turn: state.turn,
|
|
87
|
+
since: state.since,
|
|
88
|
+
...(typeof state.reason === 'string' && state.reason !== '' ? { reason: state.reason } : {}),
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}))
|
|
93
|
+
}
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-folder-sidebar",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"version": "0.17.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Folder-style sidebar for DeepSeek Harness: workspaces read as folders, and clicking one enters its session list instead of scrolling every workspace at once. · DSH 文件夹侧栏:工作区即文件夹,点进去只看该工作区的会话。",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Aliboder",
|
|
8
|
+
"homepage": "https://github.com/Aliboder/dsh-folder-sidebar#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Aliboder/dsh-folder-sidebar.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Aliboder/dsh-folder-sidebar/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"dsh",
|
|
18
|
+
"deepseek-harness",
|
|
19
|
+
"dsh-plugin",
|
|
20
|
+
"cordis",
|
|
21
|
+
"sidebar",
|
|
22
|
+
"workspace",
|
|
23
|
+
"sessions"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20",
|
|
27
|
+
"dsh": ">=0.2.0-rc.2 <0.2.1-0 || >=0.2.1-0 <0.3.0-0"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"zod": "^4.6.5"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"exports": {
|
|
36
|
+
".": "./index.js",
|
|
37
|
+
"./client": "./client.js",
|
|
38
|
+
"./locale/*.json": "./locale/*.json",
|
|
39
|
+
"./icon": "./icon.svg",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"index.js",
|
|
44
|
+
"client.js",
|
|
45
|
+
"cordis.patch.yml",
|
|
46
|
+
"locale/*.json",
|
|
47
|
+
"icon.svg",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"CHANGELOG.md"
|
|
51
|
+
],
|
|
52
|
+
"dsh": {
|
|
53
|
+
"bundle": {
|
|
54
|
+
"patch": "./cordis.patch.yml"
|
|
55
|
+
},
|
|
56
|
+
"client": {
|
|
57
|
+
"platform": "web",
|
|
58
|
+
"immediately": true,
|
|
59
|
+
"inject": [
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-conversation"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"test": "node test/smoke.test.mjs && node test/projection.test.mjs && node test/logic.test.mjs",
|
|
66
|
+
"check": "node --check index.js && node --check client.js",
|
|
67
|
+
"pack:check": "npm pack --dry-run"
|
|
68
|
+
}
|
|
6
69
|
}
|