better-dsh 0.2.3-b → 0.2.3-c

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.
Files changed (77) hide show
  1. package/docs/50_test-reports/upstream-dsh-0.1.5-rc.2-local-test-report.md +79 -0
  2. package/docs/upstream-dsh-0.1.5-rc.2-report.md +156 -0
  3. package/lib/client/index.js +60 -51
  4. package/lib/index.d.ts +2 -3
  5. package/lib/index.js +29 -25
  6. package/package.json +2 -2
  7. package/docs/50_test-reports/v0.1.8d_artifacts/README.md +0 -138
  8. package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
  9. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
  10. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
  11. package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +0 -592
  12. package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
  13. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
  14. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
  15. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
  16. package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
  17. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
  18. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
  19. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
  20. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
  21. package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +0 -5
  22. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
  23. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
  24. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
  25. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
  26. package/docs/60_exploration-and-research/01-cordis-runtime/bun-compile-cordis-runtime-bootstrap-research.md +0 -536
  27. package/docs/60_exploration-and-research/01-cordis-runtime/cordis-customization-and-override-mechanics.md +0 -418
  28. package/docs/60_exploration-and-research/01-cordis-runtime/cordis-engineering-feasibility.md +0 -155
  29. package/docs/60_exploration-and-research/01-cordis-runtime/cordis-research.md +0 -583
  30. package/docs/60_exploration-and-research/01-cordis-runtime/dsh-cordis-hotplug-mcp-patch-research.md +0 -265
  31. package/docs/60_exploration-and-research/01-cordis-runtime/js-ts-language-fundamentals.md +0 -628
  32. package/docs/60_exploration-and-research/02-dsh/dash-research.md +0 -592
  33. package/docs/60_exploration-and-research/02-dsh/dsh-web-profile-package-map.md +0 -186
  34. package/docs/60_exploration-and-research/02-dsh/dsh-web-ui-slot-system-research.md +0 -310
  35. package/docs/60_exploration-and-research/02-dsh/dsh-webui-backend-data-inventory.md +0 -633
  36. package/docs/60_exploration-and-research/02-dsh/dsh-webui-strip-boundary-research.md +0 -300
  37. package/docs/60_exploration-and-research/02-dsh/dsh-webui-wire-appendix.md +0 -3729
  38. package/docs/60_exploration-and-research/02-dsh/web-frontend-composability-research.md +0 -191
  39. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/capture-live-turn.json +0 -1
  40. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/observed-endpoints.json +0 -224
  41. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/remote-inventory.json +0 -110954
  42. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/served-index-sample.html +0 -47
  43. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/session-events.json +0 -9411
  44. package/docs/60_exploration-and-research/02-dsh/webui-wire-data/ws-frame-examples.json +0 -20
  45. package/docs/60_exploration-and-research/02-dsh-webui/dsh-web-profile-package-map.md +0 -186
  46. package/docs/60_exploration-and-research/02-dsh-webui/dsh-web-ui-slot-system-research.md +0 -310
  47. package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-backend-data-inventory.md +0 -633
  48. package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-strip-boundary-research.md +0 -300
  49. package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-wire-appendix.md +0 -3729
  50. package/docs/60_exploration-and-research/02-dsh-webui/web-frontend-composability-research.md +0 -191
  51. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/capture-live-turn.json +0 -1
  52. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/observed-endpoints.json +0 -224
  53. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/remote-inventory.json +0 -110954
  54. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/served-index-sample.html +0 -47
  55. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/session-events.json +0 -9411
  56. package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/ws-frame-examples.json +0 -20
  57. package/docs/60_exploration-and-research/03-mobile-ios/dsh-mobile-spa-ios-input-experience-research.md +0 -160
  58. package/docs/60_exploration-and-research/03-mobile-ios/ios-chat-app-bridge-research.md +0 -324
  59. package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-jsonl-mapping.md +0 -1532
  60. package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode-failed.json +0 -46
  61. package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode1.json +0 -1124
  62. package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode2.json +0 -1240
  63. package/docs/60_exploration-and-research/05-dashr-dev/plugin-development.md +0 -148
  64. package/docs/60_exploration-and-research/05-dashr-dev/upstream-alignment.md +0 -102
  65. package/docs/60_exploration-and-research/README.md +0 -87
  66. package/docs/60_exploration-and-research/bun-compile-cordis-runtime-bootstrap-research.md +0 -348
  67. package/docs/60_exploration-and-research/cordis-research.md +0 -350
  68. package/docs/60_exploration-and-research/dsh-mobile-spa-ios-input-experience-research.md +0 -160
  69. package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +0 -186
  70. package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +0 -310
  71. package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +0 -300
  72. package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +0 -324
  73. package/docs/60_exploration-and-research/web-frontend-composability-research.md +0 -191
  74. package/docs/superd/00-blueprint.md +0 -331
  75. package/docs/superd/01-component-boundaries.md +0 -261
  76. package/docs/superd/02-dsh-embed-modes.md +0 -151
  77. package/docs/superd/image.png +0 -0
@@ -0,0 +1,79 @@
1
+ # upstream dsh 0.1.5-rc.2 本地对齐实测报告(Dev/Test 1 · 4988 实例)
2
+
3
+ > 日期:2026-09-11(HKT)
4
+ > 执行:对齐轮 S1–S7(runbook:`docs/60_exploration-and-research/05-dashr-dev/upstream-alignment.md`)
5
+ > 目标 tag:`dsh-v0.1.5-rc.2`(npm dist-tag `next`,最高版本;`latest` 停在 rc.1)
6
+ > 前置版本对账报告:`docs/upstream-dsh-0.1.5-rc.2-report.md`(846 commits / 3170 files / ~104k 行)
7
+
8
+ ---
9
+
10
+ ## 一、实测范围与结果表
11
+
12
+ | # | 步骤 | 结果 |
13
+ |---|---|---|
14
+ | S1 | patch 载体 tag 间 diff + dashr 56 个 `@deepseek-ai/*` 引用名对新 tag 包集全数命中 | ✅ |
15
+ | S2 | checkout `dsh-v0.1.5-rc.2` + 三 patch 手工重放(pnpm-workspace.yaml 冲突按新 allowBuilds 手解) | ✅ |
16
+ | S3 | rsync 副本 + stale peerDep 复查(absent)+ **新增 devDeps 手术**(见瑕疵 F2) | ✅ |
17
+ | S4 | `pnpm install`(36s,供应链策略 1543 entries 过)+ `pnpm run build`(234 client artifacts)+ 副本 tsdown/client 半 | ✅ |
18
+ | S5 | 插件契约对齐:**4 处真实语义漂移移植**(见 §三) | ✅ |
19
+ | S6 | `tsc --noEmit` **0 errors**;`vitest --run` **493/493**(37 files,128s) | ✅ |
20
+ | S7 | 4998 实例 systemd-run 冒烟 **8/8 探针全绿**(见 §四) | ✅ |
21
+
22
+ 红线遵守:未 npm publish、未动 prod 3080、未动 Caddyfile。
23
+
24
+ ## 二、环境事实
25
+
26
+ - monorepo:`upstream/deepseek-harness` @ `dsh-v0.1.5-rc.2`(detached),本地 patch 三件套在场(unrun devDep / storeDir+verifyDepsBeforeRun+zeromq / tsdown resolveRepositoryRoot)。
27
+ - allowBuilds 冲突解:采纳上游新集(**fs-ext 移除**——flock 改走 node-addon-system 预编译;新增 `electron-winstaller: false`、`msgpackr-extract: false`),保留本地 `zeromq: true` 与两条 `dsh-subprocess-local`。
28
+ - 副本 `packages/better-dsh/better-dsh/` = canonical 0.2.3-b + devDeps 手术(14 个 `workspace:*`)。
29
+ - 实例:unit `dsh-4988-test`,`DSH_HOME=~/.dsh-test`,`DSH_TRUSTED_HOSTS=test.pc.randomhash.app pc.randomhash.app 192.168.31.130`,`UnsetEnvironment=DISPLAY WAYLAND_DISPLAY`,**端口 4988**(4997–4999 被 superd PoC 占用,见瑕疵 F4)。
30
+ - 残留实验文件未动:`packages/boot/app-boot/bun-registry/`、`bun-internal-bridge.ts`(2026-09-06 bun compile 实验,构建容忍,untracked 不碍 checkout)。
31
+
32
+ ## 三、契约漂移与移植(本轮核心工作)
33
+
34
+ 对 0.1.5-rc.2 的 **4 处真实漂移**全部移植,canonical 已同步(src/test 与副本 diff = 空):
35
+
36
+ 1. **会话事件改名**(Session V3「PTC durable vocabulary」):`tool/code-dispatch(-start)` → `tool/ptc-dispatch(-start)`。`src/index.ts` 2 处 append + 3 处注释;测试 3 文件的字符串断言同步。
37
+ 2. **subagents 统一消息缝**:`followup`/`reportFrom` 两方法合并为 `sendMessage(sender, targetId, content, {signal})`(上行 = targetId 命中 sender 的 `parentSession` 自动走 send-to-parent;`source`/`delivery` 选项 knobs 已删,runtime 自盖章)。移植面:`src/subagents-surface.ts` 接口重述、`src/bridges/index.ts` 两调用点(parent 方向新增 root-agent 本地护栏,语义等价旧 UNAUTHORIZED)、`delegation.spec`/`bridges.spec`/`helpers.ts` 全部 fake 与断言。
38
+ 3. **持久化读路径**:`SessionPersistence.inspect` 消失(接口只剩 create/open/flush/stat/list);读 = `open(id,'read')` → `handle.read(offset?,length?,opts)` + `close()`,元数据 = `stat(id).header.createdAt`。移植面:`src/url-schema/handlers/agent.ts` 的 surface 接口重述 + 3 调用点收敛为 `persistedEventsOf` helper。
39
+ 4. **SessionSeq 品牌化**:裸 `number` 不再可赋值,需 `SessionSeq(n)` 构造(`dsh-session` 导出);`assistant/message` 事件 data 新增必填 `stream: AssistantStreamRecord[]`(V3 in-history stream 内嵌)——测试 fixture 两处补 `stream: []`。
40
+
41
+ 另有两处**行形状查表结论**(runbook S7.5/S7.8,全绿):
42
+ - `connection` 行(web-app cordis.patch.yml)tag 间**逐字节同形**(仅注释位移)——fence 腿整行重述继续有效;
43
+ - `__DSH_TRANSPORT__`/ownsHost 消费点、`data-sidebar-collapsed`(AppFrame.tsx:210 仍在)、`conversation.session.header` 与 `settings.general.item` slot、`apps/web/index.html` viewport meta、`webserver injections.ts` head splice——**全部原样存活**。
44
+
45
+ ## 四、S7 冒烟明细(unit dsh-4988-test)
46
+
47
+ | 探针 | 结果 |
48
+ |---|---|
49
+ | `web --dump-config` → dashr-repl 行 + `DASHR_KERNEL_PYTHON` 注入 | ✅ |
50
+ | fence:trusted Host `/api` = **401**(过栅栏卡认证);evil Host = **403** | ✅ |
51
+ | token 鉴权根页 200 + `__DSH_TRANSPORT__` boot script 在页 | ✅ |
52
+ | boot graph `"id":"better-dsh"` + `/plugins/??better-dsh/client.js&rev=…` | ✅ |
53
+ | client bundle:200,**17824B 与本地逐字节一致**(+84B = 服务端 sourceMappingURL 追加,符合已知行为) | ✅ |
54
+ | mobile 锚点:layout 模块含 `data-sidebar-collapsed` + `SIDEBAR_AUTO_COLLAPSE = 1024` | ✅ |
55
+ | hashline 中央库 `$DSH_HOME/storages/dsh-better-edit/hash-store.sqlite` 在位 | ✅ |
56
+ | 0.1.5 新组合在场:ui-sidebar-right/documentpreview/files、client-resources、api-workspace-files、ui-deliverables 均入 module batch | ✅ |
57
+
58
+ 实例**保持运行**供 user 验收:`http://127.0.0.1:4988/?token=<redacted>`(token 每次重启轮换)。
59
+
60
+ ## 五、发现的瑕疵(定性 + 去向)
61
+
62
+ - **F1(流程/runbook 漂移)**:`packages/node_modules` 在新 tag 安装布局下不再生成 → runbook 的 `../../node_modules/.bin/tsx`(build-client)失效,正确为 `../../../node_modules/.bin/tsx`。→ 已回写 AGENTS.md §二。
63
+ - **F2(工具链坑,重要)**:canonical 的 npm-range optional peerDeps(`>=0.1.2-alpha.1 <0.2.0-0`)在 pnpm 11 严格预发布 semver 下**不匹配 workspace `0.1.5-rc.2`**(元组规则),autoInstallPeers 落到 registry **0.1.2-rc.1**(唯一满足该 range 的 registry 版本)→ 副本 node_modules 双身份,tsc 品牌类型互斥报错。**解法(S3 新增手术)**:副本 package.json devDependencies 注入 14 个 `workspace:*`(dashr 实际 import 的 dsh-* 名单),每次 rsync 后重打。→ 已回写 AGENTS.md §二;canonical 不动(npm 发布语义保持)。
64
+ - **F3(上游观察,非阻塞)**:rc.2 的 `test`/`build:bench` scripts 前置 `build:native-system`;主 `build` 已含(scripts/build.ts:44),无额外步骤。`native/system/packages/linux-x64/bin/glibc/system.node` 已产出。
65
+ - **F4(环境冲突)**:4997(127.0.0.1)、4998、4999(0.0.0.0)被 superd multi-context PoC 占用(`~/workspaces/superd/.scratch/multi-context-poc/poc4-v3-e2e.mjs`,pid 2233871 + 1393092,Sep 10 19:41 起,独立 DSH_HOME)——不可杀(user 的在跑实验),本轮实例改 **4988**。**注意:若 Caddy test.pc.randomhash.app 后端指 4999,域名叫到的将是 superd 实例**——user 域名验收前需先对齐端口或等 PoC 结束(Caddyfile 红线未动)。
66
+ - **F5(上游观察)**:`pnpm peers check` 有 WARN(副本 npm-range peers vs workspace 版本)——F2 的同一根源,运行期无影响(profile symlink 直连 monorepo)。
67
+
68
+ ## 六、流程化产出
69
+
70
+ - 本报告 + AGENTS.md §二 write-back(tag 对齐记录、tsx 路径、devDeps 手术、端口事实)。
71
+ - `.scratch/dsh-v0.1.3-alpha.2-local-patches-backup.patch`(旧 patch 备份,切换前快照)。
72
+
73
+ ## 七、Open items
74
+
75
+ 1. **user 验收**(第一人称):127.0.0.1:4988 实例(域名词见 F4 注意);重点 = dashr-repl 真跑一轮(kernel 三级供给在新 runtime 下)、better-edit 读改写、mobile 手势/zoomGuard 真机。
76
+ 2. canonical 改动(4 文件 src + 6 文件 test)**未 commit**——等 user 指令(上轮有 commit 前 "Wait" 先例)。
77
+ 3. Caddy test.pc → 4999 端口归属与 superd PoC 的冲突排查(user 裁决)。
78
+ 4. 既有遗留:v0.2.5 zoomGuard standalone 双形态 CDP 复验(AGENTS.md 已记)。
79
+ 5. prod(3080)**维持 0.1.3-alpha.2 不动**;升 0.1.5 需另行裁决(对账报告 §六建议先行)。
@@ -0,0 +1,156 @@
1
+ # upstream dsh npm 版本对账:prod 0.1.3-alpha.2 → 0.1.5-rc.2
2
+
3
+ > 生成时间:2026-09-10(本地时区)
4
+ > 数据源:npm registry(`@deepseek-ai/dsh`)元数据 + `upstream/deepseek-harness` git tag 对账
5
+ > 目标:回答「npm 上比 prod 更高的版本是什么、diff 有多大、对 prod 意味着什么」
6
+
7
+ ---
8
+
9
+ ## 〇、一句话结论
10
+
11
+ prod 当前跑 **`@deepseek-ai/dsh@0.1.3-alpha.2`**。npm 上比它高的版本是整条 **0.1.5 线**(`alpha.1 / alpha.2 / rc.1 / rc.2`,**0.1.4 从未发布,直接跳号**)。最高版本是 **`0.1.5-rc.2`**(挂在 `next` dist-tag,而 `latest` 还停在 `0.1.5-rc.1`)。
12
+
13
+ 这条 0.1.5 线是**大版本级聚合**:846 commits、3170 文件、约 10.4 万行新增。核心是 **Session 格式 v3 重写**(会话持久化契约变更,对 prod 是**破坏性升级,不可 drop-in**),外加 Electron 桌面打包、Sidebar/dockkit 重构、文件交付「present」工具、图渲染预览、模型默认值切换(DeepSeek V41 Flash)等一批功能。**升级 prod 前必须按 AGENTS.md §一/§二 走对齐轮,不能只换版本号。**
14
+
15
+ ---
16
+
17
+ ## 一、版本全景
18
+
19
+ npm registry 当前 dist-tags:
20
+
21
+ | dist-tag | 指向版本 |
22
+ |---|---|
23
+ | `latest` | 0.1.5-rc.1 |
24
+ | `next` | **0.1.5-rc.2**(最高) |
25
+ | `alpha` | 0.1.5-alpha.2 |
26
+
27
+ 比 prod(0.1.3-alpha.2)更高的版本,按发布顺序:
28
+
29
+ | 版本 | npm 发布时间 (UTC) | dist-tag |
30
+ |---|---|---|
31
+ | 0.1.5-alpha.1 | 2026-09-08 15:57 | — |
32
+ | 0.1.5-alpha.2 | 2026-09-09 14:41 | `alpha` |
33
+ | 0.1.5-rc.1 | 2026-09-10 03:12 | `latest` |
34
+ | **0.1.5-rc.2** | **2026-09-10 14:57** | `next` |
35
+
36
+ > 注意点:`latest` 并不指向最高版本(rc.1 vs rc.2);「最高版本」= `next` 上的 **0.1.5-rc.2**。0.1.4 未在 npm 出现过。
37
+
38
+ 对应 git tag(本地 `upstream/deepseek-harness`,已 fetch):
39
+
40
+ ```
41
+ dsh-v0.1.3-alpha.2 2026-09-07 19:45 +0800 ← prod 当前
42
+ dsh-v0.1.5-alpha.1 2026-09-08 23:25 +0800
43
+ dsh-v0.1.5-alpha.2 2026-09-09 22:13 +0800
44
+ dsh-v0.1.5-rc.1 2026-09-10 09:36 +0800
45
+ dsh-v0.1.5-rc.2 2026-09-10 21:50 +0800
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 二、diff 规模
51
+
52
+ `dsh-v0.1.3-alpha.2 .. dsh-v0.1.5-rc.2`:
53
+
54
+ | 指标 | 值 |
55
+ |---|---|
56
+ | commits | **846** |
57
+ | 文件 | 3170 changed |
58
+ | 行 | +103,990 / −17,687 |
59
+ | 源码侧(排除 snapshots/tests) | 2474 文件,+68,818 / −13,973 |
60
+
61
+ 分段 commit 分布:
62
+
63
+ | 区间 | commits |
64
+ |---|---|
65
+ | 0.1.3-alpha.2 → 0.1.5-alpha.1 | 563(大头,聚合了 Session V3 与一堆 feature) |
66
+ | 0.1.5-alpha.1 → 0.1.5-alpha.2 | 262 |
67
+ | 0.1.5-alpha.2 → 0.1.5-rc.1 | 17 |
68
+ | 0.1.5-rc.1 → 0.1.5-rc.2 | 4(收尾/backport) |
69
+
70
+ ---
71
+
72
+ ## 三、依赖面变化(对 prod 直接可见)
73
+
74
+ prod 0.1.3-alpha.2 有 **71 个 dependencies**,0.1.5-rc.2 有 **72 个**。差异:
75
+
76
+ 1. **新增运行期包 `@deepseek-ai/dsh-tool-present`**(`packages/fs/tool-present`)——新「present」工具:把 agent 产出的文件以不可变交付卡片(download card)呈现,是文件交付特性的宿主半。
77
+ 2. `apps/cli` devDeps 新增 `@deepseek-ai/dsh-agent-loop`、`@deepseek-ai/dsh-agent-loop-testkit`(内部,不影响 prod 运行面)。
78
+ 3. 新增 client 包 `ui-deliverables`(`PresentRow` / `PresentedFileCard` / `present-open`),属 web shell 交付卡片 UI。
79
+ 4. 其余全部 `@deepseek-ai/*` 依赖整体从 `^0.1.3-alpha.2` 抬到 `^0.1.5-rc.2`(同版本号齐步,无个别漂移)。
80
+ 5. 底层 `cordis` / `schemastery` / `commander` / `js-yaml` 等版本**未变**(`cordis ^4.0.2`、`schemastery ^3.18.2` 等,与 0.1.3-alpha.2 相同)。
81
+
82
+ ---
83
+
84
+ ## 四、主要变更主题(按 prod 相关度排序)
85
+
86
+ ### 1. Session 格式 v3 重写(⚠ 破坏性,最高风险)
87
+ `session-log-v3` 工作线,是本次最大的变更块。要点:
88
+
89
+ - 会话身份 **V2 → V3 迁移**(`feat(session): add identity V2-to-V3 migration and writer skeleton`)。
90
+ - system prompt 表示为 **surface node zero**(`refactor(session): represent the system prompt as surface node zero`)。
91
+ - **canonical envelopes**、PTC durable vocabulary、in-history system prompt 表示、JSONL 跨进程写所有权(lease)。
92
+ - 大量 `session.v3.jsonl` 快照与 V2/V3 迁移覆盖面单测。
93
+
94
+ > **对 prod 的含义**:会话持久化契约改变。上一轮(0.1.3-alpha.2 对齐)已实测:上游 tag diff 会打到 `session-persistence-omp.ts` / `replay.ts` / store 的 handle+lease 契约(见 2026-09-08 对齐报告)。**0.1.5 的 V3 比 0.1.3 的 V2 更进一步,破坏面更大**,`better-dsh` / `omp-web` 这类桥接会话数据的插件必须重新对齐,不能 drop-in。
95
+
96
+ ### 2. Electron 桌面打包(对 3080 web 无直接作用)
97
+ Windows/macOS/Linux 构建、mac 签名+公证、Windows 签名、auto-update、IPC 性能优化。纯桌面宿主线,与本机 `dsh web`(3080)部署无关,但意味着上游发布面从此多一个桌面产物。
98
+
99
+ ### 3. Sidebar / dockkit 重构
100
+ - `dockkit` 可逆停靠引擎、pointer 交互。
101
+ - 全局 sidebar panel、tab 导航、live tab 标题 + 文件类型图标、末 tab 关闭规则、响应式右栏、全屏 shell。
102
+ - session-log 控制移入 header「更多」菜单。
103
+
104
+ ### 4. 文件交付「present」工具 + 文档预览
105
+ - 新 `dsh-tool-present` 包:不可变文件交付下载卡片、artifact 卡原生文件动作、workspace 文件操作。
106
+ - 可扩展文档预览、文本预览分页 tab、文件类型图标集、`ui-deliverables` client 卡。
107
+ - `feat(fs)`:bounded byte-range reads(fs-local / fs-e2b)、dual-face 文件 API。
108
+
109
+ ### 5. 图表 / Markdown 预览
110
+ Chat 代码块内预览 Mermaid / Graphviz / SVG / HTML fence,适配应用主题。
111
+
112
+ ### 6. LLM 模型默认值切换(⚠ 影响 prod 行为)
113
+ - Chat Completions 默认切到 **DeepSeek V41 Flash**(`feat(llm): default Chat Completions to DeepSeek V41 Flash`)。
114
+ - 保留 V4 模型、恢复 V4 Flash Vision Exp catalog 条目。
115
+ > prod 若升级,默认模型会跟着变;需确认是否期望。
116
+
117
+ ### 7. Feedback 对话框
118
+ `/feedback` 与 Dislike 统一为一个带分类的对话框 + toast。
119
+
120
+ ### 8. Subagent catalog
121
+ 记录并观察 parent-owned child catalog(子代理目录)。
122
+
123
+ ### 9. native system / node-addon-system
124
+ 包族改名 `node-addon-system`,预编译 Node-API flock、Landlock capability 子路径。**新增原生依赖面,升级安装需留意 prod 机上的原生构建/预编译匹配**(本机已有一处 zeromq allowBuilds 特例,见 AGENTS.md §二)。
125
+
126
+ ### 10. minimal profile 行为调整
127
+ - `str_replace_editor` 从 minimal profiles 移除。
128
+ - persistent bash 输出与 one-shot shell 契约对齐。
129
+ > 只影响 minimal profile,不影响 prod `web` profile 的默认工具集。
130
+
131
+ ### 11. 其它
132
+ - CLI:从 shipped 模板创建 profile。
133
+ - skills:Playwright 视频录制 GIF。
134
+ - 内部 CI/审查自动化(weighted PR approval、review owner 排名等)——与 prod 运行无关。
135
+
136
+ ---
137
+
138
+ ## 五、对 prod 升级的风险评估(简要)
139
+
140
+ | 风险项 | 级别 | 说明 |
141
+ |---|---|---|
142
+ | Session V3 格式迁移 | 🔴 高 | 会话持久化契约变更;`better-dsh`/`omp-web` 会话桥接面需重新对齐,先例(0.1.3 V2)已证实非 drop-in |
143
+ | 模型默认切 V41 Flash | 🟠 中 | 默认行为变化,需 user 确认是否接受 |
144
+ | 新原生依赖(node-addon-system) | 🟡 中低 | 安装面原生构建/预编译匹配;本机 pnpm strictDepBuilds/allowBuilds 需复核 |
145
+ | 新工具 `dsh-tool-present` | 🟡 中低 | 新工具进入 agent 运行时,需确认与现有工具/插件无 id 冲突 |
146
+ | Sidebar/dockkit UI 重构 | 🟢 低(功能面) | 纯增量 UI,但 better-dsh 的 mobile 手势/侧栏 patch 需复测是否仍对齐 |
147
+ | Electron 桌面 | ⚪ 无关 | 不影响 web 部署 |
148
+
149
+ ---
150
+
151
+ ## 六、建议
152
+
153
+ 1. 本次**只做对账、不做升级**:0.1.5 是聚合大版本,且含 Session V3 破坏性契约变更,不能当「换版本号」处理。
154
+ 2. 若后续要升级,按 AGENTS.md §一/§二走 **Dev/Test 1(4999 源码级)对齐轮**:切 `dsh-v0.1.5-rc.2` → 重放三处本地 patch(storeDir / unrun devDep / resolveRepositoryRoot)→ install/build → 插件契约对齐(重点 `session-persistence-omp.ts`/`replay.ts`/store 的 V3 handle+lease)→ tsc/单测 → 4999 第一人称实测 → 报告落 `docs/50_test-reports/` → user 确认 → 才动 prod 3080。
155
+ 3. 升级目标版本**首选 `0.1.5-rc.2`(`next`)而非 `latest`(rc.1)**,因为 rc.2 才是最高版本;但 rc 阶段仍建议等上游正式 stable 后再定。
156
+ 4. 升级前单独确认模型默认值(V41 Flash)是否要在 prod 生效。
@@ -69,7 +69,7 @@ const zh = {
69
69
  };
70
70
 
71
71
  //#endregion
72
- //#region \0dsh-css:/home/u1/workspaces/dashr/dashr/src/failover/client/FailoverRow.module.css.mjs
72
+ //#region \0dsh-css:/home/u1/workspaces/dashr/upstream/deepseek-harness/packages/better-dsh/better-dsh/src/failover/client/FailoverRow.module.css.mjs
73
73
  const css = "._440e1d7b_row {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px 0;\n}\n\n._9865b509_title {\n font-weight: 600;\n font-size: 14px;\n}\n\n._3cfec826_slots {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n._70954771_slot {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n._ba1fd839_slotLabel {\n min-width: 88px;\n flex-shrink: 0;\n font-size: 13px;\n color: var(--dsw-alias-text-secondary, #666);\n}\n\n._11c2662d_select {\n flex: 1;\n max-width: 280px;\n min-width: 0;\n}\n\n._b7c358f9_alert {\n color: var(--dsw-alias-danger, #c0392b);\n font-size: 12px;\n}\n";
74
74
  const tagId = "better-dsh/FailoverRow.module.css";
75
75
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
@@ -185,14 +185,12 @@ function FailoverRow({ catalog, loadConfig, save, t }) {
185
185
 
186
186
  //#endregion
187
187
  //#region src/mobile/gesture.ts
188
- /**
189
- * Resolved defaults — the `1706b81` constants (120 / viewport÷4 / 40 / 1.3 /
190
- * 768) plus the one addition, the velocity gate. A slow text-selection drag
191
- * runs ~0.13 px/ms; 0.15 px/ms filters those while any comfortable sweep
192
- * (0.4 px/ms and up) passes.
188
+ /** Resolved defaults — the `1706b81` constants (120 / viewport÷4 / 40 / 1.3)
189
+ * plus the one addition, the velocity gate. A slow text-selection drag runs
190
+ * ~0.13 px/ms; 0.15 px/ms filters those while any comfortable sweep (0.4
191
+ * px/ms and up) passes.
193
192
  */
194
193
  const DEFAULT_SWIPE_THRESHOLDS = {
195
- breakpoint: 768,
196
194
  swipeDistancePx: 40,
197
195
  dominanceRatio: 1.3,
198
196
  leftEdgeBandPx: 120,
@@ -200,16 +198,6 @@ const DEFAULT_SWIPE_THRESHOLDS = {
200
198
  swipeVelocityPxPerMs: .15
201
199
  };
202
200
  /**
203
- * Whether one completed gesture's viewport is in the gesture band.
204
- *
205
- * @param viewportWidth - viewport width at gesture time (px).
206
- * @param thresholds - resolved recognition thresholds (`.breakpoint`).
207
- * @returns `true` when `viewportWidth` is strictly below the breakpoint.
208
- */
209
- function isNarrowViewport(viewportWidth, thresholds) {
210
- return viewportWidth < thresholds.breakpoint;
211
- }
212
- /**
213
201
  * Whether a pointerdown may START a gesture — the source's pointerdown
214
202
  * gate, verbatim: with both panels closed, only the left band (X120) or
215
203
  * the right three quarters of the screen admit; with a panel open, any
@@ -275,7 +263,6 @@ function resolveMobileConfig(pageConfig) {
275
263
  const v = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
276
264
  return {
277
265
  enabled: true,
278
- breakpoint: n(pageConfig.breakpoint, DEFAULT_SWIPE_THRESHOLDS.breakpoint),
279
266
  swipeDistancePx: n(pageConfig.swipeDistancePx, DEFAULT_SWIPE_THRESHOLDS.swipeDistancePx),
280
267
  dominanceRatio: n(pageConfig.dominanceRatio, DEFAULT_SWIPE_THRESHOLDS.dominanceRatio),
281
268
  leftEdgeBandPx: n(pageConfig.leftEdgeBandPx, DEFAULT_SWIPE_THRESHOLDS.leftEdgeBandPx),
@@ -291,19 +278,32 @@ function readLeftCollapsed() {
291
278
  return document.querySelector("[data-sidebar-collapsed]") !== null;
292
279
  }
293
280
  /**
294
- * Better Sidebar's right-panel state, live off the body attribute the
295
- * plugin itself publishes (collapsed = closed). Read SYNCHRONOUSLY in the
296
- * handlers — a cached mirror lags the panel's own DOM write by a render,
297
- * and a close-swipe issued right after an open-swipe would misroute.
281
+ * The OFFICIAL right sidebar's state (0.1.5 ui-sidebar-right), read from
282
+ * AppFrame's TWO presentation facets, synchronously (a cached mirror lags
283
+ * the panel's own DOM write by a render, and a close-swipe issued right
284
+ * after an open-swipe would misroute):
285
+ *
286
+ * - `[data-rightbar-collapsed]` — the reserved GRID TRACK facet (present =
287
+ * zero-width right column). On phones (<768) the panel presents FULLSCREEN
288
+ * WITHOUT a track (`autoFullscreen` in SidebarRight), so this attribute
289
+ * alone misreads a panel that covers the whole frame as "closed" — the
290
+ * 2026-09-11 field bug: every close-swipe misrouted to open-left.
291
+ * - `[data-rightbar-fullscreen]` — the overlay facet (present = fullscreen
292
+ * presentation active, open by definition).
293
+ *
294
+ * Open = track reserved OR fullscreen overlay. On hosts before 0.1.5 both
295
+ * attributes never appear: closed, permanently — left gestures unaffected.
298
296
  */
299
297
  function readRightOpen() {
300
- return !document.body.hasAttribute("data-dsh-sidebar-collapsed");
298
+ const fullscreen = document.querySelector("[data-rightbar-fullscreen]") !== null;
299
+ const trackless = document.querySelector("[data-rightbar-collapsed]") !== null;
300
+ return fullscreen || !trackless;
301
301
  }
302
302
  /**
303
303
  * Whether a session is current — the plugin-side stand-in for the source's
304
- * `detailsSession !== undefined` guard (the right panel opens in a session
305
- * only). Better Sidebar's own shipped CSS keys off the same slot selector,
306
- * so it is load-bearing beyond this feature.
304
+ * `detailsSession !== undefined` guard (the right panel is a
305
+ * session-scoped surface; without a session its expand button is not
306
+ * rendered, so opening would be a no-op anyway).
307
307
  */
308
308
  function readSessionLive() {
309
309
  return document.querySelector("[data-slot=\"conversation.session.header\"]") !== null;
@@ -316,32 +316,38 @@ function readPanelState() {
316
316
  };
317
317
  }
318
318
  /**
319
- * Toggle Better Sidebar's right panel through its persistent DOM: the
320
- * plugin exposes no JS toggle on its client service (its open/close
321
- * reducer is store-internal), so the swipe reaches it the same way the
322
- * source did — clicking the LAST button of its always-rendered
323
- * `[data-dsh-toggle-cluster]` (the bottom-panel button precedes it and is
324
- * absent below the plugin's 768px narrow breakpoint). Absent cluster or
325
- * buttons: a no-op, never a crash.
319
+ * Drive the OFFICIAL right sidebar through its own controls (0.1.5
320
+ * ui-sidebar-right): opening clicks `[data-sidebar-right-expand]` (the
321
+ * conversation header corner button — the panel's own documented "way
322
+ * into a hidden panel", rendered exactly while collapsed with a session);
323
+ * closing clicks `[data-sidebar-right-toggle]` (the dock chrome toggle).
324
+ * The store action behind them (`setExpanded`/`toggleExpanded`) is
325
+ * slot-store-internal — cross-plugin imports are the hard boundary, so
326
+ * the native buttons ARE the sanctioned entry. Absent button (pre-0.1.5
327
+ * host, no session, or already in the target state): a no-op, never a
328
+ * crash.
326
329
  */
327
- function toggleBetterSidebar() {
328
- const buttons = document.querySelector("[data-dsh-toggle-cluster]")?.querySelectorAll("button");
329
- (buttons?.[buttons.length - 1])?.click();
330
+ function openRightPanel() {
331
+ document.querySelector("[data-sidebar-right-expand]")?.click();
332
+ }
333
+ function closeRightPanel() {
334
+ document.querySelector("[data-sidebar-right-toggle]")?.click();
330
335
  }
331
336
  /**
332
- * The narrow-viewport CSS: zero-width sidebar track under the breakpoint,
333
- * keyed to AppFrame's semantic attribute (survives class-hash churn).
334
- * Rendered with the breakpoint baked in (media queries cannot read JS
335
- * config); the tag carries the plugin-owned dataset so the loader's
336
- * style-claim machinery removes it on unload, like module CSS.
337
+ * The responsive CSS: zero-width sidebar track whenever upstream's layout
338
+ * has collapsed the sidebar, keyed PURELY to AppFrame's semantic
339
+ * attribute (survives class-hash churn). No width media query of our own
340
+ * (2026-09-11 ruling): upstream owns the auto-collapse threshold (1024
341
+ * today), and this rule simply takes the 56px rail they leave behind to
342
+ * zero. If upstream renames the attribute the rule stops matching and
343
+ * their native rail renders (benign degradation). The tag carries the
344
+ * plugin-owned dataset so the loader's style-claim machinery removes it
345
+ * on unload, like module CSS.
337
346
  */
338
- function mobileCss(breakpointPx) {
339
- const wide = Math.max(1, Math.floor(breakpointPx) - .02);
347
+ function mobileCss() {
340
348
  return [
341
- `@media (max-width: ${String(wide)}px) {`,
342
- ` [data-sidebar-collapsed] {`,
343
- ` grid-template-columns: 0px minmax(0, 1fr) 0px !important;`,
344
- ` }`,
349
+ `[data-sidebar-collapsed] {`,
350
+ ` grid-template-columns: 0px minmax(0, 1fr) 0px !important;`,
345
351
  `}`
346
352
  ].join("\n");
347
353
  }
@@ -361,7 +367,7 @@ function setupMobileLayout(ctx) {
361
367
  const tag = document.createElement("style");
362
368
  tag.dataset.plugin = "better-dsh";
363
369
  tag.dataset.pluginCss = styleTagId;
364
- tag.textContent = mobileCss(config.breakpoint);
370
+ tag.textContent = mobileCss();
365
371
  document.head.append(tag);
366
372
  const offLayout = ctx.inject(["layout"], (layoutCtx) => {
367
373
  const layout = layoutCtx.get("layout");
@@ -370,8 +376,10 @@ function setupMobileLayout(ctx) {
370
376
  const onPointerDown = (event) => {
371
377
  start = void 0;
372
378
  const viewport = window.innerWidth;
373
- if (!isNarrowViewport(viewport, config)) return;
374
- if (!admitsSwipeStart(event.clientX, viewport, readPanelState(), config)) return;
379
+ const coarsePointer = window.matchMedia?.("(pointer: coarse)").matches === true;
380
+ const panels = readPanelState();
381
+ if (!coarsePointer && !panels.leftCollapsed && !panels.rightOpen) return;
382
+ if (!admitsSwipeStart(event.clientX, viewport, panels, config)) return;
375
383
  start = {
376
384
  x: event.clientX,
377
385
  y: event.clientY,
@@ -389,7 +397,8 @@ function setupMobileLayout(ctx) {
389
397
  if (action === null) return;
390
398
  start = void 0;
391
399
  if (action === "open-left" || action === "close-left") layout.toggleSidebar();
392
- else toggleBetterSidebar();
400
+ else if (action === "open-right") openRightPanel();
401
+ else closeRightPanel();
393
402
  };
394
403
  const onPointerEnd = () => {
395
404
  start = void 0;
package/lib/index.d.ts CHANGED
@@ -549,7 +549,6 @@ interface WebTrustConfig {
549
549
  trustedPageAuthorities?: readonly string[];
550
550
  mobile?: {
551
551
  enabled?: boolean;
552
- breakpoint?: number;
553
552
  swipeDistancePx?: number;
554
553
  dominanceRatio?: number;
555
554
  leftEdgeBandPx?: number;
@@ -671,7 +670,7 @@ declare module '@deepseek-ai/cordis' {
671
670
  /**
672
671
  * Allow a listener to replace content in the DURABLE LOG COPY of one
673
672
  * `eval` sub-dispatch outcome before the bridge appends its
674
- * `tool/code-dispatch` event. `next()` keeps the content unchanged; a
673
+ * `tool/ptc-dispatch` event. `next()` keeps the content unchanged; a
675
674
  * listener may return replacement blocks (e.g. the spill policy's preview
676
675
  * + locator for an oversized text result). Scope-filtered dispatch
677
676
  * (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that
@@ -714,7 +713,7 @@ interface RunCellBridgeOptions {
714
713
  * in the module doc. Sub-calls ride the registry's exported staged scheduler
715
714
  * (`prepare`/`dispatch`/`finalize`/`finish`) under the native concurrency
716
715
  * contract; each sub-dispatch is logged for reconstruction
717
- * (`tool/code-dispatch-start` / `tool/code-dispatch`) while only the outer
716
+ * (`tool/ptc-dispatch-start` / `tool/ptc-dispatch`) while only the outer
718
717
  * curated result enters model history.
719
718
  * @param registry - the host tool registry (sub-calls go through its staged
720
719
  * scheduler, bindings cover its registered tools).
package/lib/index.js CHANGED
@@ -5121,7 +5121,21 @@ async function newestByCreation(entries, family) {
5121
5121
  async function createdAtOf(entry, family) {
5122
5122
  const live = family.sessions.get(entry.id);
5123
5123
  if (live !== void 0) return live.header.createdAt;
5124
- return (await family.sessionPersistence.inspect(entry.id))?.meta.createdAt ?? 0;
5124
+ return (await family.sessionPersistence.stat(entry.id))?.header.createdAt ?? 0;
5125
+ }
5126
+ /**
5127
+ * The persisted log's events for one settled session, or `undefined` when the
5128
+ * session was never materialized (0.1.5 seam: `stat` guards materialization,
5129
+ * then a read-mode `open` handle slices the validated contiguous log).
5130
+ */
5131
+ async function persistedEventsOf(id, family) {
5132
+ if (await family.sessionPersistence.stat(id) === void 0) return void 0;
5133
+ const handle = await family.sessionPersistence.open(id, "read");
5134
+ try {
5135
+ return (await handle.read()).events;
5136
+ } finally {
5137
+ await handle.close();
5138
+ }
5125
5139
  }
5126
5140
  /**
5127
5141
  * The output artifact for one resolved address: the live session's last
@@ -5131,9 +5145,9 @@ async function createdAtOf(entry, family) {
5131
5145
  async function outputFor(target, family) {
5132
5146
  const live = family.sessions.get(SessionId(target.rawId));
5133
5147
  if (live !== void 0) return outputArtifact(live);
5134
- const inspection = await family.sessionPersistence.inspect(SessionId(target.rawId));
5135
- if (inspection === void 0) throw unknownId(target, `agent "${target.rawId}" has no live session and no persisted log`);
5136
- return persistedOutput(inspection.events);
5148
+ const events = await persistedEventsOf(SessionId(target.rawId), family);
5149
+ if (events === void 0) throw unknownId(target, `agent "${target.rawId}" has no live session and no persisted log`);
5150
+ return persistedOutput(events);
5137
5151
  }
5138
5152
  /** The live session for one resolved address, or a structured error. */
5139
5153
  function requireLiveSession(target, family) {
@@ -5167,8 +5181,8 @@ async function renderRoster(family, descendants, agents) {
5167
5181
  async function lastActivityOf(rawId, family) {
5168
5182
  const live = family.sessions.get(SessionId(rawId));
5169
5183
  if (live !== void 0) return lastEventTime(live.snapshotEvents());
5170
- const inspection = await family.sessionPersistence.inspect(SessionId(rawId));
5171
- return inspection === void 0 ? "-" : lastEventTime(inspection.events);
5184
+ const events = await persistedEventsOf(SessionId(rawId), family);
5185
+ return events === void 0 ? "-" : lastEventTime(events);
5172
5186
  }
5173
5187
  /** The last event's time as ISO 8601, `-` for an empty log. */
5174
5188
  function lastEventTime(events) {
@@ -10113,17 +10127,10 @@ const agentMessageExecutor = async (rawArgs, exec, deps) => {
10113
10127
  const subagents = deps.requireSubagents?.();
10114
10128
  if (!subagents) return { error: "agent_message(receiver='child') is unavailable: no ctx.subagents service is mounted in this composition" };
10115
10129
  try {
10116
- return { messageId: await subagents.followup(exec.agent, subagentId, [{
10130
+ return { messageId: await subagents.sendMessage(exec.agent, subagentId, [{
10117
10131
  type: "text",
10118
10132
  text: message
10119
- }], {
10120
- source: {
10121
- kind: "coordinator",
10122
- form: "relay",
10123
- senderSessionId: exec.agent.id
10124
- },
10125
- signal: exec.signal
10126
- }) };
10133
+ }], { signal: exec.signal }) };
10127
10134
  } catch (error) {
10128
10135
  return { error: `agent_message(receiver='child') failed: ${error instanceof Error ? error.message : String(error)}` };
10129
10136
  }
@@ -10134,15 +10141,14 @@ const agentMessageExecutor = async (rawArgs, exec, deps) => {
10134
10141
  const subagents = deps.requireSubagents?.();
10135
10142
  if (!subagents) return { error: "agent_message(receiver='parent') is unavailable: no ctx.subagents service is mounted in this composition" };
10136
10143
  try {
10144
+ const parentId = exec.agent.session.header.parentSession;
10145
+ if (parentId === void 0) return { error: "agent_message(receiver='parent') rejected: only a live continuable child agent can report to its parent (a root agent has none)" };
10137
10146
  return {
10138
10147
  delivered: true,
10139
- message_id: await subagents.reportFrom(exec.agent, [{
10148
+ message_id: await subagents.sendMessage(exec.agent, parentId, [{
10140
10149
  type: "text",
10141
10150
  text: message
10142
- }], {
10143
- delivery: "next-step",
10144
- signal: exec.signal
10145
- })
10151
+ }], { signal: exec.signal })
10146
10152
  };
10147
10153
  } catch (error) {
10148
10154
  if (error.code === "UNAUTHORIZED") return { error: `agent_message(receiver='parent') rejected: only a live continuable child agent can report to its parent (a root agent has none) — ${error instanceof Error ? error.message : String(error)}` };
@@ -10915,7 +10921,6 @@ function buildBootScript(config) {
10915
10921
  const mobile = config.mobile;
10916
10922
  const mobilePayload = mobile?.enabled !== false ? {
10917
10923
  enabled: true,
10918
- ...mobile?.breakpoint !== void 0 ? { breakpoint: mobile.breakpoint } : {},
10919
10924
  ...mobile?.swipeDistancePx !== void 0 ? { swipeDistancePx: mobile.swipeDistancePx } : {},
10920
10925
  ...mobile?.dominanceRatio !== void 0 ? { dominanceRatio: mobile.dominanceRatio } : {},
10921
10926
  ...mobile?.leftEdgeBandPx !== void 0 ? { leftEdgeBandPx: mobile.leftEdgeBandPx } : {},
@@ -10969,7 +10974,6 @@ const inject = ["tools"];
10969
10974
  /** Runtime schema. */
10970
10975
  const MOBILE_CONFIG = z.object({
10971
10976
  enabled: z.boolean().default(true),
10972
- breakpoint: z.natural().min(200).default(768),
10973
10977
  swipeDistancePx: z.natural().min(8).default(40),
10974
10978
  dominanceRatio: z.number().min(1).default(1.3),
10975
10979
  leftEdgeBandPx: z.natural().min(8).default(120),
@@ -11195,7 +11199,7 @@ function renderValue(value) {
11195
11199
  * in the module doc. Sub-calls ride the registry's exported staged scheduler
11196
11200
  * (`prepare`/`dispatch`/`finalize`/`finish`) under the native concurrency
11197
11201
  * contract; each sub-dispatch is logged for reconstruction
11198
- * (`tool/code-dispatch-start` / `tool/code-dispatch`) while only the outer
11202
+ * (`tool/ptc-dispatch-start` / `tool/ptc-dispatch`) while only the outer
11199
11203
  * curated result enters model history.
11200
11204
  * @param registry - the host tool registry (sub-calls go through its staged
11201
11205
  * scheduler, bindings cover its registered tools).
@@ -11378,7 +11382,7 @@ function createRunCellTool(registry, options) {
11378
11382
  isError: result.isError,
11379
11383
  content: result.content
11380
11384
  });
11381
- agent.session.append("tool/code-dispatch", {
11385
+ agent.session.append("tool/ptc-dispatch", {
11382
11386
  rootCallId: exec.rootCallId,
11383
11387
  parentCallId: exec.callId,
11384
11388
  subCallId,
@@ -11412,7 +11416,7 @@ function createRunCellTool(registry, options) {
11412
11416
  settleError(error);
11413
11417
  },
11414
11418
  async start() {
11415
- exec.agent?.session.append("tool/code-dispatch-start", {
11419
+ exec.agent?.session.append("tool/ptc-dispatch-start", {
11416
11420
  rootCallId: exec.rootCallId,
11417
11421
  parentCallId: exec.callId,
11418
11422
  subCallId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-dsh",
3
- "version": "0.2.3-b",
3
+ "version": "0.2.3-c",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "scripts/kernel-provision.mjs"
29
29
  ],
30
30
  "scripts": {
31
- "prebuild": "node -e \"fs.cpSync('../docs','docs',{recursive:true})\"",
31
+ "prebuild": "node scripts/copy-docs.mjs",
32
32
  "build": "tsdown && npm run build-client",
33
33
  "typecheck": "tsc --noEmit",
34
34
  "test": "vitest --run",