@guowenzhang/dsh-whiteboard 0.2.0 → 0.2.1

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/README.md CHANGED
@@ -1,29 +1,37 @@
1
- # dsh-whiteboard
2
-
3
- A DeepSeek Harness Web plugin: the main panel keeps the whiteboard card gallery while drawioedit edits the selected board in the right Sidebar, so the list and the editor stay side by side. Diagrams live in this plugin's `files/` directory; no workspace selection is needed. A dedicated session grants write access to this directory.
4
-
5
- ## Install
6
-
7
- Install and enable [`@guowenzhang/dsh-drawioedit`](../dsh-drawioedit) first, then this plugin:
8
-
9
- ```sh
10
- npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-drawioedit
11
- npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-whiteboard
12
- ```
13
-
14
- From the npm registry: <https://www.npmjs.com/package/@guowenzhang/dsh-whiteboard> — restart the host afterwards; local checkouts, git sources and troubleshooting are in [AGENTS.md](AGENTS.md).
15
-
16
- Restart DSH Web and open **Whiteboards** in the left navigation. **New whiteboard** first opens a dialog with an editable timestamp-based name. Only **Create** writes the `.drawio` file under the plugin's `files/` directory and opens it in drawioedit. Drawioedit autosaves changes. Each card shows its name, a first-page preview, and last modification time. Click the card to edit, or click the top-right X and confirm to delete the file. The persistent search box in the toolbar filters the loaded cards by name and shows an empty-result hint when nothing matches. Returning to the **Whiteboards** page goes straight back to the board whose editor tab is still open — collapsing the Sidebar or switching pages keeps it — and only an explicit tab close, a deleted board or a replaced file leaves you on the gallery. Oversized or unreadable diagrams show a preview placeholder. On desktop, opening a board expands the editor column to fullscreen so draw.io can show its own left shapes palette and right format panel; collapse the Sidebar or leave fullscreen to get back to the gallery and click a card to continue editing.
17
-
18
- New whiteboards have a single `.drawio` file. Legacy UUID files and their sidecars remain visible. Back up `files/` before replacing or uninstalling the plugin.
19
-
20
- ## Development
21
-
22
- ```sh
23
- npm ci --legacy-peer-deps
24
- npm run typecheck
25
- npm run build
26
- npm test
27
- ```
28
-
29
- Commit the generated `lib/` with source changes. `dsh-drawioedit` supplies the editor assets at runtime.
1
+ # dsh-whiteboard
2
+
3
+ Whiteboards for DeepSeek Harness: a board gallery in the main panel and draw.io editing in the Sidebar, with boards stored inside the plugin. No workspace selection is needed: a dedicated session grants write access to the plugin's `files/` directory.
4
+
5
+ ## Screenshots
6
+
7
+ ![Whiteboard gallery with name search](docs/images/gallery.png)
8
+
9
+ ![New whiteboard dialog](docs/images/new-board.png)
10
+
11
+ ![Editing a board in draw.io](docs/images/editor.png)
12
+
13
+ ## Install
14
+
15
+ Install and enable [`@guowenzhang/dsh-drawioedit`](../dsh-drawioedit) first, then this plugin:
16
+
17
+ ```sh
18
+ npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-drawioedit
19
+ npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-whiteboard
20
+ ```
21
+
22
+ From the npm registry: <https://www.npmjs.com/package/@guowenzhang/dsh-whiteboard> — restart the host afterwards; local checkouts, git sources and troubleshooting are in [AGENTS.md](AGENTS.md).
23
+
24
+ Restart DSH Web and open **Whiteboards** in the left navigation. **New whiteboard** first opens a dialog with an editable timestamp-based name. Only **Create** writes the `.drawio` file under the plugin's `files/` directory and opens it in drawioedit. Drawioedit autosaves changes. Each card shows its name, a first-page preview, and last modification time. Click the card to edit, or click the top-right X and confirm to delete the file. The persistent search box in the toolbar filters the loaded cards by name and shows an empty-result hint when nothing matches. Returning to the **Whiteboards** page goes straight back to the board whose editor tab is still open — collapsing the Sidebar or switching pages keeps it — and only an explicit tab close, a deleted board or a replaced file leaves you on the gallery. Oversized or unreadable diagrams show a preview placeholder. On desktop, opening a board expands the editor column to fullscreen so draw.io can show its own left shapes palette and right format panel; leaving fullscreen shows the board gallery on the left and keeps the current editor on the right, rather than exposing a blank Conversation. Collapsing the editor also keeps the gallery available; click a card to continue editing.
25
+
26
+ New whiteboards have a single `.drawio` file. Legacy UUID files and their sidecars remain visible. Back up `files/` before replacing or uninstalling the plugin.
27
+
28
+ ## Development
29
+
30
+ ```sh
31
+ npm ci --legacy-peer-deps
32
+ npm run typecheck
33
+ npm run build
34
+ npm test
35
+ ```
36
+
37
+ Commit the generated `lib/` with source changes. `dsh-drawioedit` supplies the editor assets at runtime.
package/README.zh.md CHANGED
@@ -1,29 +1,37 @@
1
- # dsh-whiteboard
2
-
3
- DeepSeek Harness Web 白板插件:主面板常驻白板卡片列表,打开白板后列表仍留在左侧,drawioedit 在右侧侧边栏编辑。图文件保存在本插件的 `files/` 目录;无需选择工作区。白板为该目录创建专用会话并授予写入权限。
4
-
5
- ## 安装
6
-
7
- 先安装并启用 [`@guowenzhang/dsh-drawioedit`](../dsh-drawioedit),再安装本插件:
8
-
9
- ```sh
10
- npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-drawioedit
11
- npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-whiteboard
12
- ```
13
-
14
- 来自 npm 官方源:<https://www.npmjs.com/package/@guowenzhang/dsh-whiteboard>。装完重启宿主;本地目录开发安装、git 源与排查见 [AGENTS.md](AGENTS.md)。
15
-
16
- 重启 DSH Web 后,打开左侧导航中的“白板”。点击“新建白板”会先显示命名对话框,默认填入时间名称,可直接修改;只有点击“确认创建”才会在插件 `files/` 目录创建 `.drawio` 文件并交给 drawioedit 打开。绘图内容由 drawioedit 自动保存。卡片显示名称、第一页缩略图和最近修改时间;点击卡片可继续编辑,点击右上角叉号并确认可删除文件。工具条上的搜索框按名称筛选当前卡片列表,不匹配时显示空结果提示。再次进入“白板”页时,如果上一块白板的编辑标签仍开着(只是收起过侧边栏或切到过别的页面),会直接回到那块白板;只有主动关闭标签、或该文件已被删除或替换,才会停在白板列表。过大或无法解析的图表显示预览占位内容。桌面端打开白板时右侧编辑列展开为全屏,编辑器可以完整显示自己的左侧形状面板和右侧格式面板;收起侧边栏或退出全屏即可回到白板列表,再点卡片可继续编辑。
17
-
18
- 新白板只有一个 `.drawio` 文件;旧版 UUID 文件和元数据仍可显示。替换或卸载插件前请备份 `files/` 目录。
19
-
20
- ## 开发
21
-
22
- ```sh
23
- npm ci --legacy-peer-deps
24
- npm run typecheck
25
- npm run build
26
- npm test
27
- ```
28
-
29
- 修改源码后须重新构建并提交 `lib/`。`dsh-drawioedit` 在运行时提供编辑器资源。
1
+ # dsh-whiteboard
2
+
3
+ 为 DeepSeek Harness 提供白板:主面板是白板卡片列表,右侧边栏用 draw.io 编辑,白板文件保存在插件内。无需选择工作区:白板为该目录创建专用会话并授予写入权限。
4
+
5
+ ## 界面截图
6
+
7
+ ![白板列表与名称搜索](docs/images/gallery.png)
8
+
9
+ ![新建白板对话框](docs/images/new-board.png)
10
+
11
+ ![在 draw.io 中编辑白板](docs/images/editor.png)
12
+
13
+ ## 安装
14
+
15
+ 先安装并启用 [`@guowenzhang/dsh-drawioedit`](../dsh-drawioedit),再安装本插件:
16
+
17
+ ```sh
18
+ npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-drawioedit
19
+ npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-whiteboard
20
+ ```
21
+
22
+ 来自 npm 官方源:<https://www.npmjs.com/package/@guowenzhang/dsh-whiteboard>。装完重启宿主;本地目录开发安装、git 源与排查见 [AGENTS.md](AGENTS.md)。
23
+
24
+ 重启 DSH Web 后,打开左侧导航中的“白板”。点击“新建白板”会先显示命名对话框,默认填入时间名称,可直接修改;只有点击“确认创建”才会在插件 `files/` 目录创建 `.drawio` 文件并交给 drawioedit 打开。绘图内容由 drawioedit 自动保存。卡片显示名称、第一页缩略图和最近修改时间;点击卡片可继续编辑,点击右上角叉号并确认可删除文件。工具条上的搜索框按名称筛选当前卡片列表,不匹配时显示空结果提示。再次进入“白板”页时,如果上一块白板的编辑标签仍开着(只是收起过侧边栏或切到过别的页面),会直接回到那块白板;只有主动关闭标签、或该文件已被删除或替换,才会停在白板列表。过大或无法解析的图表显示预览占位内容。桌面端打开白板时右侧编辑列展开为全屏,编辑器可以完整显示自己的左侧形状面板和右侧格式面板;取消全屏后,左侧显示白板列表、右侧保留当前编辑器,不会露出“新建会话”页面;收起编辑列时也保留白板列表,再点卡片可继续编辑。
25
+
26
+ 新白板只有一个 `.drawio` 文件;旧版 UUID 文件和元数据仍可显示。替换或卸载插件前请备份 `files/` 目录。
27
+
28
+ ## 开发
29
+
30
+ ```sh
31
+ npm ci --legacy-peer-deps
32
+ npm run typecheck
33
+ npm run build
34
+ npm test
35
+ ```
36
+
37
+ 修改源码后须重新构建并提交 `lib/`。`dsh-drawioedit` 在运行时提供编辑器资源。
Binary file
Binary file
Binary file
package/lib/client.js CHANGED
@@ -187,7 +187,7 @@ window.__ModuleLoader__.load({
187
187
  };
188
188
  //#endregion
189
189
  //#region src/client/last-board.ts
190
- const STORAGE_KEY = "dsh.whiteboard.v1.last-board";
190
+ const STORAGE_KEY$1 = "dsh.whiteboard.v1.last-board";
191
191
  function storage() {
192
192
  try {
193
193
  return typeof window === "undefined" ? void 0 : window.localStorage;
@@ -200,7 +200,7 @@ window.__ModuleLoader__.load({
200
200
  const store = storage();
201
201
  if (!store) return void 0;
202
202
  try {
203
- const raw = store.getItem(STORAGE_KEY);
203
+ const raw = store.getItem(STORAGE_KEY$1);
204
204
  if (raw === null) return void 0;
205
205
  const value = JSON.parse(raw);
206
206
  if (typeof value !== "object" || value === null) return void 0;
@@ -220,7 +220,7 @@ window.__ModuleLoader__.load({
220
220
  const store = storage();
221
221
  if (!store) return;
222
222
  try {
223
- store.setItem(STORAGE_KEY, JSON.stringify({
223
+ store.setItem(STORAGE_KEY$1, JSON.stringify({
224
224
  id: board.id,
225
225
  title: board.title,
226
226
  updatedAt: board.updatedAt
@@ -232,7 +232,7 @@ window.__ModuleLoader__.load({
232
232
  const store = storage();
233
233
  if (!store) return;
234
234
  try {
235
- store.removeItem(STORAGE_KEY);
235
+ store.removeItem(STORAGE_KEY$1);
236
236
  } catch {}
237
237
  }
238
238
  /**
@@ -30894,6 +30894,60 @@ segment: 30 };
30894
30894
  });
30895
30895
  }
30896
30896
  //#endregion
30897
+ //#region src/client/board-session.ts
30898
+ const STORAGE_KEY = "dsh.whiteboard.v1.session";
30899
+ /** The dedicated editor Session survives reloads; it is not a chat destination. */
30900
+ function readBoardSession() {
30901
+ try {
30902
+ return window.localStorage?.getItem(STORAGE_KEY) || void 0;
30903
+ } catch {
30904
+ return;
30905
+ }
30906
+ }
30907
+ function writeBoardSession(sessionId) {
30908
+ try {
30909
+ window.localStorage?.setItem(STORAGE_KEY, sessionId);
30910
+ } catch {}
30911
+ }
30912
+ /**
30913
+ * Replace only a known whiteboard Session's central occupant, not its navigation
30914
+ * or rightbar binding. Selecting the global whiteboard panel here would hide the
30915
+ * rightbar: the Host only exposes it while the Conversation main key is selected.
30916
+ * The normal Conversation registration stays installed underneath this shadow.
30917
+ */
30918
+ function installBoardSessionPanel(ctx, owned, face) {
30919
+ let reconcile = () => {};
30920
+ ctx.slots.inject("main", () => {
30921
+ let release;
30922
+ reconcile = () => {
30923
+ const sessionId = ctx.sidebarRight.mounted.getSnapshot();
30924
+ const showList = sessionId !== void 0 && owned(sessionId);
30925
+ if (showList && !release) release = ctx.slots.register({
30926
+ name: "main",
30927
+ key: "conversation",
30928
+ priority: -1,
30929
+ locale: NS,
30930
+ inject: () => ({
30931
+ ...face,
30932
+ restore: async () => "none"
30933
+ })
30934
+ }, WhiteboardPanel);
30935
+ else if (!showList && release) {
30936
+ release();
30937
+ release = void 0;
30938
+ }
30939
+ };
30940
+ const unsubscribe = ctx.sidebarRight.mounted.subscribe(() => reconcile());
30941
+ reconcile();
30942
+ return () => {
30943
+ unsubscribe();
30944
+ release?.();
30945
+ reconcile = () => {};
30946
+ };
30947
+ });
30948
+ return () => reconcile();
30949
+ }
30950
+ //#endregion
30897
30951
  //#region src/client/index.tsx
30898
30952
  async function unwrap(call) {
30899
30953
  const result = await call;
@@ -30941,7 +30995,8 @@ segment: 30 };
30941
30995
  return service;
30942
30996
  };
30943
30997
  const sessions = ctx.sessions;
30944
- let lastSessionId;
30998
+ let lastSessionId = readBoardSession();
30999
+ let syncBoardPanel = () => {};
30945
31000
  /** The drawio editor tab open for the mounted session: the active tab or a background one. */
30946
31001
  const openEditorTab = (sessionId) => {
30947
31002
  const known = ctx.sidebarRight.openTabs.getSnapshot().find((tab) => tab.sessionId === sessionId && tab.kind === "drawio-edit");
@@ -30968,6 +31023,8 @@ segment: 30 };
30968
31023
  if (!sessionId) sessionId = await sessions.create({ cwd: board.directory });
30969
31024
  await unwrap(remote().grantBoardSession({ sessionId }));
30970
31025
  lastSessionId = sessionId;
31026
+ writeBoardSession(sessionId);
31027
+ syncBoardPanel();
30971
31028
  writeLastBoard(board);
30972
31029
  if (ctx.sidebarRight.mounted.getSnapshot() !== sessionId) {
30973
31030
  ctx.uiWorkspace.openSession(sessionId);
@@ -30995,6 +31052,7 @@ segment: 30 };
30995
31052
  return "reopened";
30996
31053
  }
30997
31054
  };
31055
+ syncBoardPanel = installBoardSessionPanel(ctx, (id) => id === lastSessionId, face);
30998
31056
  ctx.slots.inject("main", () => ctx.slots.register({
30999
31057
  name: "main",
31000
31058
  key: "whiteboard",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guowenzhang/dsh-whiteboard",
3
- "version": "0.2.0",
4
- "description": "Plugin-owned whiteboards with a card gallery and fullscreen draw.io editing for DeepSeek Harness",
3
+ "version": "0.2.1",
4
+ "description": "Whiteboards for DeepSeek Harness: a board gallery in the main panel and draw.io editing in the Sidebar, with boards stored inside the plugin",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "main": "lib/index.mjs",
@@ -11,9 +11,14 @@
11
11
  "./package.json": "./package.json",
12
12
  "./cordis.patch.yml": "./cordis.patch.yml"
13
13
  },
14
- "engines": { "node": "^22.19.0 || >=24.0.0", "dsh": ">=0.2.0-rc.1" },
14
+ "engines": {
15
+ "node": "^22.19.0 || >=24.0.0",
16
+ "dsh": ">=0.2.0-rc.1"
17
+ },
15
18
  "dsh": {
16
- "bundle": { "patch": "./cordis.patch.yml" },
19
+ "bundle": {
20
+ "patch": "./cordis.patch.yml"
21
+ },
17
22
  "client": {
18
23
  "inject": [
19
24
  "@deepseek-ai/dsh-api-remotes",
@@ -29,7 +34,16 @@
29
34
  "platform": "web"
30
35
  }
31
36
  },
32
- "files": ["lib", "files/README.md", "cordis.patch.yml", "README.md", "README.zh.md", "LICENSE", "NOTICE"],
37
+ "files": [
38
+ "lib",
39
+ "docs",
40
+ "files/README.md",
41
+ "cordis.patch.yml",
42
+ "README.md",
43
+ "README.zh.md",
44
+ "LICENSE",
45
+ "NOTICE"
46
+ ],
33
47
  "scripts": {
34
48
  "build": "tsdown -c tsdown.config.ts && node build-client.mjs",
35
49
  "typecheck": "tsc --noEmit -p tsconfig.json",
@@ -54,21 +68,51 @@
54
68
  "react": "*"
55
69
  },
56
70
  "peerDependenciesMeta": {
57
- "@deepseek-ai/cordis": { "optional": true },
58
- "@deepseek-ai/dsh-api-remotes": { "optional": true },
59
- "@deepseek-ai/dsh-api-session-controller": { "optional": true },
60
- "@deepseek-ai/dsh-client-locale": { "optional": true },
61
- "@deepseek-ai/dsh-client-ui-renderer": { "optional": true },
62
- "@deepseek-ai/dsh-client-ui-slots": { "optional": true },
63
- "@deepseek-ai/dsh-client-ui-layout": { "optional": true },
64
- "@deepseek-ai/dsh-client-ui-sidebar": { "optional": true },
65
- "@deepseek-ai/dsh-client-ui-sidebar-right": { "optional": true },
66
- "@deepseek-ai/dsh-client-ui-workspace": { "optional": true },
67
- "@deepseek-ai/dsh-sandbox-policy": { "optional": true },
68
- "@deepseek-ai/dsh-session": { "optional": true },
69
- "@deepseek-ai/dsh-util-workspace-path": { "optional": true },
70
- "@deepseek-ai/dsh-typert-protocol": { "optional": true },
71
- "react": { "optional": true }
71
+ "@deepseek-ai/cordis": {
72
+ "optional": true
73
+ },
74
+ "@deepseek-ai/dsh-api-remotes": {
75
+ "optional": true
76
+ },
77
+ "@deepseek-ai/dsh-api-session-controller": {
78
+ "optional": true
79
+ },
80
+ "@deepseek-ai/dsh-client-locale": {
81
+ "optional": true
82
+ },
83
+ "@deepseek-ai/dsh-client-ui-renderer": {
84
+ "optional": true
85
+ },
86
+ "@deepseek-ai/dsh-client-ui-slots": {
87
+ "optional": true
88
+ },
89
+ "@deepseek-ai/dsh-client-ui-layout": {
90
+ "optional": true
91
+ },
92
+ "@deepseek-ai/dsh-client-ui-sidebar": {
93
+ "optional": true
94
+ },
95
+ "@deepseek-ai/dsh-client-ui-sidebar-right": {
96
+ "optional": true
97
+ },
98
+ "@deepseek-ai/dsh-client-ui-workspace": {
99
+ "optional": true
100
+ },
101
+ "@deepseek-ai/dsh-sandbox-policy": {
102
+ "optional": true
103
+ },
104
+ "@deepseek-ai/dsh-session": {
105
+ "optional": true
106
+ },
107
+ "@deepseek-ai/dsh-util-workspace-path": {
108
+ "optional": true
109
+ },
110
+ "@deepseek-ai/dsh-typert-protocol": {
111
+ "optional": true
112
+ },
113
+ "react": {
114
+ "optional": true
115
+ }
72
116
  },
73
117
  "devDependencies": {
74
118
  "@deepseek-ai/cordis": "^4.0.4",