dsh-sidebar-row-menu 1.10.0 → 1.11.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/AGENTS.md ADDED
@@ -0,0 +1,77 @@
1
+ # 仓库约定(AGENTS.md)
2
+
3
+ 本仓库是 [DeepSeek Harness](https://github.com/deepseek-ai) 的插件
4
+ `dsh-sidebar-row-menu`:宿主半边在 `lib/`,客户端半边是 **`src/client/**` 的源码 +
5
+ esbuild 打包出的单文件 `lib/client.js`**。
6
+
7
+ ## 硬性约束
8
+
9
+ 1. **不要手改 `lib/client.js`。** 它是构建产物,任何手工修改都会在下次构建时丢失。
10
+ 客户端改动只写 `src/client/**`,然后运行 `npm run build:client`。
11
+ 2. **客户端只有一个产物文件。** DSH 的客户端模块系统直接执行
12
+ `window.__ModuleLoader__.load({ factory })`,没有打包步骤的旧版插件靠单文件分发;
13
+ 所以源码可以拆多文件,但必须打包回一个 `lib/client.js`,且 `package.json` 的
14
+ `exports["./client"]` 指向它。
15
+ 3. **平台模块只能从 `src/client/platform.js` 引入。** react / react-dom / ui-primitives
16
+ 由 DSH 的静态模块表提供,构建脚本把它们标成 external;分散 import 会让
17
+ 「插件依赖了平台哪些导出」不可见,也容易漏配 external。
18
+ 4. **不新增运行时依赖。** 运行时只有宿主平台模块;`esbuild` 是唯一的 devDependency。
19
+ 5. **对外导出的名字保持稳定**(`apply` / `inject` / `name` / `closeMenu` / `closeToast`),
20
+ 测试与宿主都按这些名字取值。
21
+
22
+ ## 目录与分层
23
+
24
+ ```
25
+ src/client/
26
+ index.js 入口:apply(ctx)、slot 注册、样式安装、生命周期清理
27
+ platform.js 平台模块的唯一入口(react / react-dom / ui-primitives)
28
+ constants.js 存储键、路由前缀、菜单 order、slot 名等常量
29
+ i18n.js zh / en 词条(全部文案都要走 t())
30
+ styles.js 全部 CSS(一次注入,类名前缀 dsrm-)
31
+ apps-catalog.js 应用 id → 名称 / 图标
32
+ dom.js fiber 解析、行/工作区/会话定位
33
+ runtime.js 运行期单例:rootCtx、菜单挂载(beginMenu / closeMenu)、服务查找
34
+ toast.js Toast 宿主
35
+ host-api.js 调宿主 HTTP 路由、剪贴板、cwd 解析
36
+ slot-ownership.js slot 条目归属判断(避免与内置条目重复)
37
+ lib/create-store.js 持久化 store 工厂(localStorage + useSyncExternalStore 样板)
38
+ store/*.js 9 个小状态:items / placements / blank-menu / children / pinned /
39
+ apps / permission / archived / delete-request
40
+ ui/*.js jsx 辅助、菜单定位、子菜单关闭、右键手势标记
41
+ features/*.js 功能块:工作区菜单、会话菜单、空白正文菜单、打开方式、设置页、
42
+ 删除确认框、归档可见性、行右键入口
43
+ ```
44
+
45
+ ## 编码约定
46
+
47
+ - 文件名 kebab-case;React hook 以 `use` 开头,工厂函数以 `create` 开头。
48
+ - 新增持久化状态:用 `lib/create-store.js` 的 `createStore`,不要再手写
49
+ `publish / subscribe / snapshot` 三件套。
50
+ - 菜单挂载:统一用 `runtime.js` 的 `beginMenu(slotName).render(...)`,由 `closeMenu()`
51
+ 统一卸载;不要各自 `createRoot` 挂 `menuHost`。
52
+ - 菜单关闭:菜单级用 `ui/dismiss.js` 的 `useDismissOnOutside`,悬浮子菜单用
53
+ `useSubmenuDismiss` + `useHoverSubmenu`;不要再逐个组件写 mousedown / keydown。
54
+ - i18n:所有用户可见文案进 `i18n.js`,中英各一条,键名用 `域.名字`。
55
+ - 样式:只写 `styles.js`,类名 `dsrm-` 前缀,跟随宿主 CSS 变量(不要硬编码颜色)。
56
+ - 容错:`catch` 不允许完全留空,至少 `console.warn` 或注释说明为什么可以忽略。
57
+ - 宿主服务可能晚于插件就绪:用 `serviceOf(ctx, name)`,缺失时降级而不是抛错。
58
+
59
+ ## 构建与校验
60
+
61
+ ```bash
62
+ npm install # 只装 esbuild
63
+ npm run build:client # src/client/** → lib/client.js
64
+ npm test # pretest 会先构建;然后跑 host / manifest / client 测试
65
+ npm run check # 语法检查 + 构建产物与源码一致性(不一致即失败)
66
+ npm pack # prepack 会构建 + check,产出 .tgz
67
+ ```
68
+
69
+ 改完客户端代码务必 `npm run build:client && npm test`;只改 `lib/host/**` 时也跑一遍
70
+ `npm test`。提交前 `git status` 应包含 `lib/client.js`(产物)与源码改动。
71
+
72
+ ## 发布
73
+
74
+ 1. 升 `package.json` 版本,CHANGELOG 按现有双语格式加一节;
75
+ 2. `npm test` / `npm run check` 全绿;
76
+ 3. 在真实 DSH GUI 里用 CDP 验证受影响的菜单(右键、权限切换、删除确认、设置页);
77
+ 4. 打 tag(`vX.Y.Z`)由 release workflow 打包发布;`lib/client.js` 必须已被构建并提交。
package/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.11.1 — 2026-11-08
4
+
5
+ ### 中文摘要
6
+
7
+ - **修好与新版 dsh-sidebar-organizer 的联动:被它收进「更多操作」的头部按钮,现在也出现在
8
+ 本插件自绘的「更多操作」二级菜单里。** 新版 organizer 的收纳行是直接插进宿主弹层的 DOM,
9
+ 不在宿主 Menu 的 `items` 里,所以之前只读 `items` 的子菜单会少掉这些行(例如
10
+ 「IP 防护」)。现在按 organizer 记在 `dsh.sidebar-organizer.layout.v1` 的收纳顺序补行,
11
+ 排在宿主条目之前(与它在原生弹层里的位置一致),点击时再点一次被收起来的原按钮。
12
+
13
+ ### Changed
14
+
15
+ - **Restored the dsh-sidebar-organizer link: header buttons it tucks into the native
16
+ "More actions" popup now show up in this plugin's own "More actions" submenu.** The
17
+ organizer injects those rows straight into the host popup's DOM, so they never appear
18
+ in the host Menu's `items` and a submenu built from `items` alone (e.g. "IP guard")
19
+ lost them. They are now re-derived from the marked header buttons, ordered by
20
+ `dsh.sidebar-organizer.layout.v1`, placed before the host items (matching their position
21
+ in the native popup), and clicking one clicks the tucked original button.
22
+
23
+ ## 1.11.0 — 2026-11-06
24
+
25
+ ### 中文摘要
26
+
27
+ - **切换「新会话默认权限」失败时不再假装成功。** 网络或宿主出错时,菜单会回滚到原来
28
+ 的勾选项并弹出失败提示;之前乐观更新会留在界面上、实际没写盘,也没有任何反馈。
29
+ 同时修掉了「读设置」晚于「写设置」返回时用旧值覆盖新值的竞态。
30
+ - **一次网络抖动不再让「打开方式 / 置顶应用」条目消失。** 应用列表加载失败时保留上次
31
+ 成功的结果,而不是清空(旧行为会空白 10 秒)。
32
+ - **批量删除会话更快、计数更准。** 一次批量(含删除工作区)只解析一次会话索引,不再
33
+ 每个会话扫一遍全部会话(O(N²)),并改为 4 路并发执行;若目标会话已全部不存在,
34
+ 提示改为「会话已不存在,无需删除」,不再报「已删除 0 个」。
35
+ - **Windows 上从 `.cmd` / `.bat` 启动编辑器时路径不再被拆词。** 含空格或 `& ^ ( )` 的
36
+ 目录不会再传错,也堵掉了命令注入面。
37
+ - **权限设置文件更安全。** 写入加文件锁(避免并发读-改-写丢更新),读到损坏的 JSON 时
38
+ 报错而不是整表覆盖;从工作区子目录启动的会话也能命中该工作区的默认权限。
39
+ - **内部重构:客户端拆模块 + 打包。** `lib/client.js` 改为由 `src/client/**` 经 esbuild
40
+ 打包的产物,9 套重复的 localStorage store、5 处子菜单关闭逻辑、菜单挂载外壳都收敛
41
+ 成共用实现;仓库约定见 `AGENTS.md`。行为与 UI 不变。
42
+
43
+ ### Changed
44
+
45
+ - **A failed "default permission for new sessions" change no longer pretends to
46
+ succeed.** On a network or host error the menu rolls back to the previous checkmark
47
+ and shows a failure toast; the optimistic update used to stay on screen even though
48
+ nothing was persisted, with no feedback at all. A read that resolves after a write
49
+ can no longer overwrite the newer value either.
50
+ - **One network hiccup no longer empties the "Open with / pinned apps" entries.** The
51
+ app list keeps its last successful result on failure instead of clearing for 10
52
+ seconds.
53
+ - **Batch session deletion is faster and counts correctly.** A batch (including
54
+ deleting a whole workspace) resolves the session index once instead of listing every
55
+ session per id (O(N²)) and runs with 4-way concurrency; when all targets were already
56
+ gone the toast says "the sessions were already gone" instead of "deleted 0".
57
+ - **Windows `.cmd` / `.bat` editor launchers no longer split paths.** Directories with
58
+ spaces or `& ^ ( )` are quoted correctly, closing the command-injection surface.
59
+ - **Safer permission store.** Writes take a file lock (no lost updates on concurrent
60
+ read-modify-write) and a corrupt JSON file now fails loudly instead of being
61
+ overwritten; sessions started from a workspace subdirectory resolve that workspace's
62
+ default permission too.
63
+ - **Internal refactor: the client is now split into modules and bundled.**
64
+ `lib/client.js` is a build artifact of `src/client/**` via esbuild; nine duplicated
65
+ localStorage stores, five copies of submenu dismissal and the menu-mount shell now
66
+ share one implementation. Conventions live in `AGENTS.md`; behaviour and UI are
67
+ unchanged.
68
+
3
69
  ## 1.10.0 — 2026-11-06
4
70
 
5
71
  ### 中文摘要
package/README.en.md CHANGED
@@ -366,11 +366,19 @@ pnpm install (npm or GitHub)" transition.
366
366
  ## Development
367
367
 
368
368
  ```powershell
369
- npm run test # normal: node --test, one child process per file
370
- npm run test:local # restricted terminals / sandboxes: --test-isolation=none
371
- npm run build # npm pack (prepack runs check first), writes the .tgz
369
+ npm install # installs esbuild, the only devDependency
370
+ npm run build:client # src/client/** → lib/client.js (build artifact)
371
+ npm run test # builds first, then node --test, one process per file
372
+ npm run test:local # restricted terminals / sandboxes: --test-isolation=none
373
+ npm run check # syntax check + artifact freshness
374
+ npm run build # npm pack (prepack builds and checks first), writes the .tgz
372
375
  ```
373
376
 
377
+ The client half lives in `src/client/**` (ESM, multiple files) and is bundled into the
378
+ single file `lib/client.js` by esbuild. **Do not edit `lib/client.js` by hand** — change
379
+ the sources and rebuild. Layout rules, naming and the release checklist are in
380
+ [AGENTS.md](AGENTS.md).
381
+
374
382
  The suite covers host pure functions (path validation, `vscode://file` encoding,
375
383
  loopback checks, route status codes) and the client module (module id, exports,
376
384
  dependency whitelist, listener install/uninstall, slot registry). Integration
@@ -389,7 +397,10 @@ lib/host/launch.js VS Code / Explorer launching
389
397
  lib/host/route.js /open, /session/delete and /workspace/delete routes, HTTP status codes
390
398
  lib/host/session-delete.js transcript verification and deletion (detach / rm / re-check)
391
399
  lib/host/workspace-delete.js workspace + all sessions deletion, workspace kept on failure
392
- lib/client.js browser half: fiber lookup, slot registration, menu mount
400
+ lib/client.js browser half build artifact (bundled from src/client/**, do not edit)
401
+ src/client/ browser sources: i18n, constants, styles, stores, ui, features
402
+ scripts/build-client.mjs esbuild bundler (--check verifies the artifact is fresh)
403
+ AGENTS.md repository conventions: layering, naming, build and release
393
404
  cordis.patch.yml bundle patch inserting the plugin into the profile tree
394
405
  scripts/install.ps1 pnpm-free install / uninstall
395
406
  test/*.test.mjs node:test
package/README.md CHANGED
@@ -313,11 +313,18 @@ cmd /c rmdir "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-sidebar-ro
313
313
  ## 开发
314
314
 
315
315
  ```powershell
316
- npm run test # 常规:node --test,逐文件子进程
317
- npm run test:local # 受限终端 / 沙箱:--test-isolation=none,同进程跑
318
- npm run build # npm pack(prepack 会先跑 check),产出 .tgz
316
+ npm install # 只装 esbuild(唯一的 devDependency)
317
+ npm run build:client # src/client/** → lib/client.js(构建产物)
318
+ npm run test # 先构建再跑 node --test,逐文件子进程
319
+ npm run test:local # 受限终端 / 沙箱:--test-isolation=none,同进程跑
320
+ npm run check # 语法检查 + 产物与源码是否一致
321
+ npm run build # npm pack(prepack 会先构建 + check),产出 .tgz
319
322
  ```
320
323
 
324
+ 客户端源码在 `src/client/**`(ESM,多文件),由 esbuild 打包成单文件 `lib/client.js`;
325
+ **不要手改 `lib/client.js`**,改完源码要重新构建。目录分层、命名、构建与发布约定见
326
+ [AGENTS.md](AGENTS.md)。
327
+
321
328
  测试覆盖宿主侧纯函数(路径校验、`vscode://file` 编码、loopback 判定、路由状态码)
322
329
  和客户端模块(模块 id、导出、依赖白名单、监听器安装/卸载、slot 注册表),并用伪造的
323
330
  `__reactFiber$`、DOM 与 `Menu` 宿主做集成测试:工作区右键的菜单项顺序、会话右键是否
@@ -335,7 +342,10 @@ lib/host/launch.js VS Code / 资源管理器启动
335
342
  lib/host/route.js /open、/session/delete 与 /workspace/delete 路由、HTTP 状态码
336
343
  lib/host/session-delete.js 会话日志目录的校验与删除(detach / rm / 复查)
337
344
  lib/host/workspace-delete.js 删除工作区及其所有会话;会话失败时保留工作区
338
- lib/client.js 客户端半边:fiber 解析、slot 注册、菜单挂载
345
+ lib/client.js 客户端半边构建产物(由 src/client/** 打包,勿手改)
346
+ src/client/ 客户端源码:i18n、常量、样式、store、ui、features
347
+ scripts/build-client.mjs esbuild 打包脚本(--check 校验产物是否最新)
348
+ AGENTS.md 仓库约定:分层、命名、构建与发布
339
349
  cordis.patch.yml bundle patch:把插件插进 profile 插件树
340
350
  scripts/install.ps1 无 pnpm 的安装 / 卸载脚本
341
351
  test/*.test.mjs node:test