better-dsh 0.2.5-e → 0.3.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.
Files changed (42) hide show
  1. package/README.md +27 -3
  2. package/cordis.patch.yml +44 -0
  3. package/docs/50_test-reports/2026-10-06-authentication-only-web-admission-4999.md +63 -0
  4. package/docs/50_test-reports/2026-10-07-better-dsh-welcome-self-contained-4999.md +52 -0
  5. package/docs/specs/welcome-self-contained/spec.md +13 -0
  6. package/lib/LaunchOptions-B874eBu2.js +4 -0
  7. package/lib/{LaunchOptions-DXdeJis3.js → LaunchOptions-kGXcZOe0.js} +1 -1
  8. package/lib/{bidi-CwtLGgcA.js → bidi-BalpKaJc.js} +1 -1
  9. package/lib/bundle-delivery.d.ts +20 -0
  10. package/lib/bundle-delivery.js +209 -0
  11. package/lib/client/index.js +2 -2
  12. package/lib/failover/index.js +1 -1
  13. package/lib/fs-aware/sandbox-plugin.js +4 -4
  14. package/lib/hmr.d.ts +32 -0
  15. package/lib/hmr.js +49 -0
  16. package/lib/{index-browser-Bp3vxHC3.js → index-browser-CysrjMyM.js} +4 -4
  17. package/lib/index.js +5 -5
  18. package/lib/{kernel-env-BLPZE-I3.js → kernel-env-D8UOWeji.js} +2 -2
  19. package/lib/kernel-env.js +1 -1
  20. package/lib/{lsp-server-registry-BcdkHROD.js → lsp-server-registry-BXvUTBY7.js} +1 -1
  21. package/lib/{lsp-server-registry-D4VLs1Sm.js → lsp-server-registry-CH9WNFFt.js} +1 -1
  22. package/lib/{main-BXwPLuYr.js → main-BQeFrBM1.js} +1 -1
  23. package/lib/{main-CKFNYpqT.js → main-CupOhMp5.js} +4 -4
  24. package/lib/mobile/plugin.d.ts +1 -1
  25. package/lib/mobile/plugin.js +1 -1
  26. package/lib/{puppeteer-core-Bliv_vNf.js → puppeteer-core-CSk2PtSm.js} +8 -8
  27. package/lib/remote/plugin.js +3 -3
  28. package/lib/url-schemes/index.d.ts +11 -11
  29. package/lib/url-schemes/index.js +14 -14
  30. package/lib/web-password.d.ts +7 -7
  31. package/lib/{web-trust-jR0o70JS.js → web-trust-D6gJpUMf.js} +5 -5
  32. package/lib/{web-trust-D9jFaQbH.d.ts → web-trust-Dej_RI2B.d.ts} +15 -15
  33. package/lib/web-trust.d.ts +2 -1
  34. package/lib/web-trust.js +1 -1
  35. package/lib/webserver.d.ts +10 -0
  36. package/lib/webserver.js +19 -0
  37. package/lib/welcome-notice.d.ts +18 -0
  38. package/lib/welcome-notice.js +59 -0
  39. package/lib/{wrap-kTohEeis.js → wrap-T4I0nfPM.js} +116 -116
  40. package/package.json +47 -5
  41. package/scripts/register-bundle.mjs +80 -0
  42. package/lib/LaunchOptions-3peHoOAx.js +0 -4
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ > Part of [Super D](../README.md). This is the independently installable `better-dsh` package. Super Dash embeds the same local build and registers it as a separate native Plugin Manager row, with its own enable/disable switch; both versions advance together toward 0.3.0. Active source is this directory, with shared specifications and references under root `docs/`.
2
+
1
3
  # Better Dsh — Dashr
2
4
 
3
5
  DASHR is a persistent-kernel REPL for the DeepSeek Harness (dsh): a
@@ -45,6 +47,30 @@ dsh runtime package dependencies**: only `@deepseek-ai/cordis` (peer),
45
47
  dependency imports external (`dts: { resolve: false }`): bundled copies
46
48
  would create duplicate type identities in a consumer's program.
47
49
 
50
+ ## Native Web defaults
51
+
52
+ The bundle owns native DSH Web policies as independently toggleable components.
53
+ `dashr-web-trust` accepts authenticated serving Host/Origin values while retaining
54
+ native cookie authentication. `dashr-webserver` inherits the native server and
55
+ waits for welcome confirmation before listening; its default address is
56
+ `0.0.0.0`, with the native port and CLI override behavior preserved.
57
+ Automatic credential onboarding is disabled; users can still configure models.
58
+
59
+ `dashr-welcome-notice` reads the current `WELCOME_NOTICE_VERSION` from the Models
60
+ client belonging to the actual DSH installation and acknowledges it through the
61
+ original General settings namespace before the first HTTP read. No version is
62
+ pinned in the plugin. Ordinary version bumps adapt at startup; changed private
63
+ symbols or build layouts fail explicitly. Restore native welcome behavior with:
64
+
65
+ ```yaml
66
+ - id: dashr-welcome-notice
67
+ disabled: true
68
+ ```
69
+
70
+ The sibling Super Dash pack builds this repository locally and embeds its actual
71
+ tarball. Better Dash remains independently installable. `../dev-webmcp` is an
72
+ unshipped development-only bundle owned by this repository.
73
+
48
74
  ## Install
49
75
 
50
76
  ```sh
@@ -204,9 +230,7 @@ the host runtime's business, not the REPL's).
204
230
 
205
231
  ## Install
206
232
 
207
- The canonical path is the repo-root one-click installer (`install.sh`): it
208
- installs the plugin from the npm registry and notes the restart. The
209
- equivalent manual steps, for reference:
233
+ Install this package independently with the native plugin command. Use Super Dash instead when you also want the Foreign Agent Hub:
210
234
 
211
235
  ```sh
212
236
  # 1. plugin — the pnpm registry-metadata cache can lag a fresh npm publish
package/cordis.patch.yml CHANGED
@@ -17,6 +17,10 @@
17
17
  # `python` is only a hint: the runtime OWNS the kernel environment. An
18
18
  # explicit interpreter (DASHR_KERNEL_PYTHON) is verified; the bare
19
19
  - insert:
20
+ # No-op standalone; keeps a containing pack's local companion delivery current.
21
+ - id: dashr-bundle-delivery
22
+ name: 'better-dsh/bundle-delivery'
23
+
20
24
  - id: dashr-repl
21
25
  name: 'better-dsh'
22
26
  config:
@@ -42,6 +46,8 @@
42
46
  # config — they survive every overlay layer; an explicit value still wins).
43
47
  - id: dashr-web-trust
44
48
  name: 'better-dsh/web-trust'
49
+ config:
50
+ trustAllHosts: true
45
51
 
46
52
  # Mobile responsiveness leg of the boot script (gestures payload +
47
53
  # zoomGuard section). All knobs default ON; `enabled: false` opts out.
@@ -66,6 +72,11 @@
66
72
  - id: dashr-web-password
67
73
  name: 'better-dsh/web-password'
68
74
 
75
+ # Automatically acknowledge the installed Host's current welcome version.
76
+ # Single-row opt-out: dashr-welcome-notice: disabled.
77
+ - id: dashr-welcome-notice
78
+ name: 'better-dsh/welcome-notice'
79
+
69
80
  # Native compaction at the host plane: the base bundle ships the engine, the
70
81
  # `/compact` command, and the tool-result pruner as host rows; dsh-web-app
71
82
  # disables them to move compaction behind per-session presets. DASHR is
@@ -93,3 +104,36 @@
93
104
  inject: [webRuntime]
94
105
  config:
95
106
  trustedHosts: !!js (process.env.DSH_TRUSTED_HOSTS ?? '').split(/\s+/).filter(Boolean).concat(ctx.webRuntime.trustedHosts)
107
+
108
+ # Replacement uses the public patch mechanism: disable the native provider,
109
+ # then insert a distinct row providing the same native webServer service.
110
+ - id: webserver
111
+ name: '@deepseek-ai/dsh-host-webserver'
112
+ disabled: true
113
+ - insert:
114
+ - id: dashr-webserver
115
+ name: 'better-dsh/webserver'
116
+ inject: [webStartup]
117
+ config:
118
+ host: !!js ctx.webStartup.host ?? '0.0.0.0'
119
+ port: !!js ctx.webStartup.port ?? 3080
120
+ compression: gzip
121
+ compressionLevel: 1
122
+ compressionThresholdBytes: 1024
123
+
124
+ - id: ui-settings-models
125
+ name: '@deepseek-ai/dsh-client-ui-settings-models'
126
+ config:
127
+ credentialOnboarding: false
128
+
129
+ # Native watcher/queue with scoped transaction context across listener replacement.
130
+ # Distinct row preserves whole-bundle disablement in the native manager.
131
+ - id: hmr
132
+ name: '@deepseek-ai/dsh-hmr'
133
+ disabled: true
134
+ - insert:
135
+ - id: dashr-hmr
136
+ name: 'better-dsh/hmr'
137
+ disabled: !!js "!ctx.get('profileContext')"
138
+ config:
139
+ root: []
@@ -0,0 +1,63 @@
1
+ # 2026-10-06 authentication-only Web admission — 4999 实测
2
+
3
+ ## 结果与范围
4
+
5
+ 本地测试包 `better-dsh@0.2.5-e` 已通过 tarball 的 `dsh plugin add` 安装到
6
+ `.test/home/compat/profiles/web`。运行实例为 `dsh-4999-test123`,原测试 home、
7
+ 会话和共享 credential seed 保留,未触碰生产 3080/3081 或 Caddy 配置。
8
+ 未发布 npm;user 于 2026-10-06 确认测试「looks good」并授权在本地 main 提交。
9
+
10
+ 测试开启 `dashr-web-trust.config.trustAllHosts: true`。该模式仅包装原生
11
+ Connection 实例的 `requestRejection`,通过公开 `authorizeIndex` 接口委托
12
+ cookie 校验,不复制认证实现、不访问 private 字段、不修改上游。传入真实
13
+ Host/Cookie 与固定无 query 的 index 路径,API 准入不会执行 token 铸 cookie。
14
+
15
+ 浏览器初始化脚本在任意 hostname 设置 `ownsHost: true`,已有 transport 保留。
16
+ 默认仍为 `trustAllHosts: false`。关闭/卸载模式恢复原生地址检查,页面能力需刷新。
17
+
18
+ ## 网络与登录
19
+
20
+ - 原生服务器监听 `127.0.0.1:4999`;现有 socat 中继监听 `192.168.31.130:4999`。
21
+ - 实际运行 argv 无 `--trusted-host`,没有给测试进程传入 `DSH_TRUSTED_HOSTS`。
22
+ - HTTPS 入口为 `https://test.pc.randomhash.app/`,沿用已有 Caddy。
23
+ - 本 test profile 禁用 `dashr-web-password`,以验证原生 token URL 登录;生产未变。
24
+ - launcher 允许 `TRUSTED_HOSTS=''` 显式省略 CLI 名单。原生/clean rig 默认仍由
25
+ CLI 放行 loopback、LAN 与测试域名。
26
+
27
+ ## 运行时验证
28
+
29
+ 每个入口先以本次 launch token 完成原生 303 cookie 交换,再读取 HTML 与 RPC。
30
+ 额外的 unlisted Host 通过 loopback 连接模拟,未修改 DNS、服务器名单或代理。
31
+
32
+ | 入口 | 页面 | 模型列表/可配置 provider | 插件列表 | 设置描述 |
33
+ |---|---|---|---|---|
34
+ | loopback | 200 | 通过 | 通过 | 通过 |
35
+ | LAN | 200 | 通过 | 通过 | 通过 |
36
+ | unlisted | 200 | 通过 | 通过 | 通过 |
37
+ | HTTPS | 200 | 通过 | 通过 | 通过 |
38
+
39
+ - 各入口 HTML 均有 all-host `ownsHost` 初始化脚本。
40
+ - 未列入名单的请求携带不匹配 Origin 与 cross-site Fetch-Metadata,认证后仍成功。
41
+ - LAN 与 unlisted 请求分别验证:缺失、篡改、其他 authority 的 cookie 均为 401。
42
+ - 真实 `/api/remote.mux` WebSocket upgrade:unlisted Host + 跨域 Origin,认证后 101,
43
+ 未认证 401。
44
+ - HTTPS `settings/mutate` 将测试字体 17 改为 18,描述接口读回 18 且 profile 文件
45
+ 持久化;之后按 revision 恢复 17 并复验。未改模型凭据。
46
+
47
+ ## 静态与自动测试
48
+
49
+ - LSP 核实 Connection capability 定义、web-trust 的引用;TypeScript AST 核实脚本
50
+ 生成与插件 apply 结构。
51
+ - TDD:新增准入测试先复现 403,页面全地址测试先复现缺失 ownsHost;实现后通过。
52
+ - 定向测试 16/16;包含原生 Connection 的认证、native cookie lifetime 与卸载恢复。
53
+ - 全量 66 个测试文件通过:709 passed、1 skipped。
54
+ - host/client typecheck 通过,构建与 pack 通过,launcher `bash -n` 通过。
55
+ - 构建保留既有 puppeteer 相关 `eval` / 可选 `yauzl` 警告;不在本次准入改动范围。
56
+
57
+ ## 验收与交接
58
+
59
+ 当前 Computer Use 没有可用浏览器,接口验证不等于 UI 操作验收。
60
+ user 已确认测试效果可接受。4999 实例保持运行,测试 tarball 是 profile 的本地依赖来源,
61
+ 交接时保留但不入库。仅提交本次代码、测试、rig 指引与文档,不发布 npm。
62
+ 生产 profile 仅移除旧 `dashr-repl` trustedPageAuthorities 覆盖,Python 配置继承 bundle,
63
+ 不安装测试包、不重启生产。备份保存在 `/tmp/dashr-prod-cordis.patch.before-cleanup-20261006.yml`。
@@ -0,0 +1,52 @@
1
+ # 2026-10-07 Super Dash 自包含 Better Dash / 动态 welcome 验收
2
+
3
+ 本轮为本地 4999 消费者验收,不是 npm 发布或 dev3 放行。两仓物理独立,Better Dash 本地源码始终参与构建。
4
+
5
+ ## 交付物
6
+
7
+ | 包 | 本地版本 | SHA256 |
8
+ |---|---|---|
9
+ | Super Dash | 0.1.12-e | `243951a2ed5bfbaa6139aa045bd4314ac96f91bf6420159b940c34b2da6ab52d` |
10
+ | Better Dash | 0.2.5-h | `3ab52507f738e3c74fb1142cc41aae9544e1f78453e80d573baa686d0885af8d` |
11
+
12
+ 路径为Super Dash 仓 `.scratch/superd-pack/`;完整来源、绝对路径与时间见 `pair.json`。pack 从 `/home/u1/workspaces/dashr/better-dsh` 清理并构建 lib,统一普通 npm pack,再物理展开该 tarball 供 bundledDependencies 打包。不存在 registry Better Dash 回退。每次 pack 自动对独立与内嵌 Better Dash 的 **741 个文件逐字节核验**,缺失或陈旧内容不能写入成功记录。
13
+
14
+ 消费者 profile 直接依赖只有 Super Dash tarball 与开发附加 WebMCP;没有 Better Dash 直接依赖/bundle、没有 pnpm Better Dash override、没有 profile-root Better Dash。实际安装的 `super-dsh/node_modules/better-dsh` 与独立本地 tarball 逐文件一致。有序 patch 文件先读内嵌 Better Dash YAML,再读 Super Dash YAML;无组件清单复制。
15
+
16
+ ## 用户可见行为
17
+
18
+ - WebTrust 与 WebServer/default bind、credential onboarding、welcome 均归 Better Dash。Super Dash 删除重复 WebTrust 源码、导出和行。dev WebMCP 移到兄弟仓 `dev-webmcp/`,不进入两包正式 tarball。
19
+ - `dashr-welcome-notice` 从**实际运行宿主**的 WebApp → Models client 路径读当前版本;本次读到 `2026-09-28.1`,实际 settings/describe 的 General value 相同。没有在 profile patch 写死 welcome 值;组件用 Loader 的公共 internal/config/Entry.update 对原 namespace 做可逆投影。`disabled: true` 恢复原生确认行为。
20
+ - 发现并修复真正的首次 HTTP 竞态:原生 Models 页面 settings mirror 的 unary HTTP 不受 WebSocket appReady 门约束。Better Dash 禁用原 webserver 行,插入 `dashr-webserver` 继承原生 Service,等待 welcome settle 后才执行原生 init/bind。延迟 General 激活的真实 Loader/HTTP fixture 先复现首读 null,修复后首个 200 快照含当前版本。禁用/重启组件恢复原值且不重建 General fiber;曾复现双挂载后已修复为只在 fiber 不存在时 init。
21
+ - 普通版本 bump 自动适配下一次启动。私有常量重命名、布局变化或多匹配时明确报错;不承诺任意未来上游结构变化也无需维护。没有直接 Settings.update 等自身 root reconciliation、没有替换 Models UI、没有本地 localStorage 假确认。
22
+ - 默认监听实际为 `0.0.0.0:4999`,由 Better Dash YAML 提供。测试 profile 只补共用 credentials 路径,端口走原生 CLI `--port 4999`。保留压缩与显式 loopback CLI override。
23
+ - 真页面发现异步模块挂载能颠倒 FIFO 排序。Better Dash 的 ownership 脚本现 prepend 公共 injection table;实际认证后 HTML 中 trust 先于 fusion,credentialOnboarding 为 false。公开 client graph 的 67 个 id 无重复,Better Dash 与 Super Dash client 各一份。
24
+
25
+ ## 实际运行验收
26
+
27
+ - `bash super-dsh/test/start-4999.sh` 完整双源码构建、tarball 安装、原生 CLI 启动 exit 0;`superd-4999-test` active。使用 Node26.10.0、npm12.2.0、pnpm12.9.1。安装期脚本保持禁用,没有 approve-builds。
28
+ - 新客户端密码页 POST 登录303、cookie签发;认证后原生 app 与 API 正常。WAN 与 LAN 匿名首页为密码表单,受保护 API 均401。共用 seed 与测试用户会话保留;生产3080/3081和上游源码未修改。
29
+ - roster = native、agy、claude、codex、hermes、omp、pi,**7个均 ready:true、failed:false**。本轮没有重跑六个未改动 foreign adapter 的真实模型会话,不把 roster 代称其 prompt 验收。
30
+ - 最终产物新建 standard native 会话 `session-a601281b-2ce2-42bc-86c4-7e3753609b57`:DeepSeek真实模型看到并实际调用 Better Dash `eval`,v4日志 tool/call seq17、tool/result seq18 得到 `SELF-CONTAINED-EVAL-42: 42`,turn/end completed。没有用注入探针冒充模型工具调用。
31
+ - 服务重启及最终新产物重启后,既有会话 `session-3f8564c9-e846-4506-ac54-95bb0599dd2e` 实际续接,读取上一轮工具输出并正确回复 `LOCAL-BETTER-FOREVER`,第三轮 turn/end completed;验证了持久会话 resume。
32
+ - CUA inventory 为 apps[]/browsers[],无法完成视觉/交互浏览器验收;首个 HTTP fixture、真实 settings 与 client graph 是已验证范围,用户视觉复核仍需访问下面 URL。dev3 未实施,本报告不作其通过声明。
33
+
34
+ ## 检查
35
+
36
+ - Better Dash welcome/WebTrust/connection:19 tests通过;host/client typecheck通过。
37
+ - Super Dash fusion-transport/fusion-flag/world-mount-patches:38 tests通过。
38
+ - Super Dash composition/login/pack-contract:7 tests通过。
39
+ - 实际 npm pack fixture与内嵌缺失/陈旧拒绝:2 tests通过。
40
+ - 迁移 dev WebMCP build与script测试:2 tests通过。
41
+ - 独立审查无 Important/Critical 遗留;修正了异步脚本顺序与文档旧结论。git diff --check、launcher shell syntax通过。
42
+ - LSP:检查上游配置更新关系、定义/引用;最后针对 Better Dash trust builder 返回真实定义及引用。TypeScript AST确认唯一注入push调用后改为prepend;无假类型/上游修改。
43
+
44
+ 证据保留在 `.scratch/self-contained-install-proof.json`、`self-contained-live-proof.json`、`self-contained-session-proof.json`、`self-contained-roster-proof.json`、`self-contained-client-graph-proof.json` 与 `self-contained-launch-delivery.log`。不记录 cookie、密码签名密钥或 provider keys。
45
+
46
+ ## 留运行线
47
+
48
+ - WAN: https://test.pc.randomhash.app/
49
+ - LAN: http://192.168.31.130:4999/
50
+ - local: http://127.0.0.1:4999/
51
+
52
+ 未 npm publish,未 commit/tag/push;4999 保持运行,供 user 实际页面复核。
@@ -0,0 +1,13 @@
1
+ # Super Dash 自包含 Better Dash 与 DSH 默认策略
2
+
3
+ 2026-10-07 user 裁决:两仓物理独立;Super Dash 每次打包都构建兄弟仓当前 Better Dash 源码,内嵌本地实际产物,不从 registry 取 Better Dash;WebTrust、dev WebMCP、webserver 默认监听及 onboarding/welcome 策略归 Better Dash。
4
+
5
+ - Better Dash 独立 build/pack;Super Dash 用 npm bundledDependencies 内嵌该本地 tarball 展开的物理包。依赖版本 exact-pin 与源包一致。
6
+ - Super Dash bundle 的有序 patch 文件先读取内嵌 Better Dash YAML,再读取自己的 YAML;消费者 profile 只声明 Super Dash,不单独声明 Better Dash。
7
+ - Better Dash 的 WebTrust 默认组合启用 authentication-only,保留 native cookie 校验;Super Dash 删除重复实现及相关覆盖。
8
+ - Better Dash 禁用原生 webserver 行、以独立 dashr-webserver 行继承原生 Service,并在监听前等待 welcome entry;默认 host 0.0.0.0,保留原生 port/压缩/CLI 配置机制;测试 launcher 默认仅覆盖 4999 端口,不再提供消费包未有的默认 host。
9
+ - Better Dash 关闭 credentialOnboarding,人工模型配置保持可用。
10
+ - `dashr-welcome-notice` 是可单行 disabled 的 Host entry:从实际安装锚的 Models 客户端读取当前 WELCOME_NOTICE_VERSION,经官方 internal/config 与 Entry.update 将确认同步投到原 ui-settings-general,不替换 Models UI,不写死版本,不用客户端 localStorage 假确认。
11
+ - 静态私有常量没有公开 API;普通版本 bump 自动生效,符号/产物结构变化必须显式报错,不能静默保留旧版本。
12
+ - dev WebMCP 移归 Better Dash 仓的开发测试目录,不进入正式插件 tarball;联合 launcher 仅将其作为开发附加 bundle。
13
+ - 真实 tarball 安装、登录、native eval/create/prompt/resume、roster、首次 settings 快照、热禁用恢复为本轮验收;浏览器连接与 dev3 按可用环境如实记录。4999 保持运行。无 npm publish、commit/tag/push、上游或生产修改。
@@ -0,0 +1,4 @@
1
+ import "./main-CupOhMp5.js";
2
+ import { t as convertPuppeteerChannelToBrowsersChannel } from "./LaunchOptions-kGXcZOe0.js";
3
+
4
+ export { convertPuppeteerChannelToBrowsersChannel };
@@ -1,4 +1,4 @@
1
- import { b as ChromeReleaseChannel } from "./main-CKFNYpqT.js";
1
+ import { b as ChromeReleaseChannel } from "./main-CupOhMp5.js";
2
2
 
3
3
  //#region node_modules/puppeteer-core/lib/puppeteer/node/LaunchOptions.js
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "./chunk-DQxbwPpZ.js";
2
2
  import { A as stringToTypedArray, G as first, H as delayWhen, K as firstValueFrom, L as combineLatest, M as assert, Q as map, S as timeout, St as debug, Tt as environment, V as defer, W as filter, at as race, b as isString, bt as TouchError, c as evaluationString, d as fromEmitterEvent, g as isDate, gt as ProtocolError, h as getSourceUrlComment, ht as ConnectionClosedError, i as SOURCE_URL_REGEX, k as stringToBase64, lt as switchMap, m as getSourcePuppeteerURLIfAvailable, o as debugCatchError, ot as raceWith, q as from, r as PuppeteerURL, rt as of, s as debugError, u as fromAbortSignal, v as isPlainObject, vt as TargetCloseError, x as parsePDFOptions, xt as UnsupportedOperation, y as isRegExp, yt as TimeoutError } from "./util-BHL_dfV_.js";
3
- import { $n as Deferred, $t as scriptInjector, Bt as throwIfDetached, Ct as WebWorkerEvent, Dn as DeviceRequestPrompt, Dt as normalizeHeaderValue, Fn as Browser, Hn as DisposableStack, Ht as bindIsolatedHandle, In as WEB_PERMISSION_TO_PROTOCOL_PERMISSION, It as Dialog, Jn as CallbackRegistry, Kn as disposeSymbol, Ln as CDPSession, Lt as Accessibility, Mn as invokeAtMostOnceForArguments, Mt as InterceptResolutionAction, Nn as throwIfDisposed, Nt as STATUS_TEXTS, On as BrowserContext, Ot as SecurityDetails, Pt as handleError, Rt as Frame, St as WebWorker, Ut as JSHandle, Vt as ElementHandle, Zn as isErrorLike, _t as Mouse, an as stringifyFunction, cn as Tracing, dt as ConsoleMessage, en as ARIAQueryHandler, fn as Coverage, gt as Keyboard, ht as TargetType, in as interpolateFunction, jn as inertIfDisposed, jt as HTTPRequest, kn as bubble, kt as HTTPResponse, mn as Page, mt as Target, nn as LazyArg, on as AsyncIterableUtil, sn as FileChooser, un as EmulationManager, vt as MouseButton, wt as Realm, yt as Touchscreen, zn as EventEmitter } from "./index-browser-Bp3vxHC3.js";
3
+ import { $n as Deferred, $t as scriptInjector, Bt as throwIfDetached, Ct as WebWorkerEvent, Dn as DeviceRequestPrompt, Dt as normalizeHeaderValue, Fn as Browser, Hn as DisposableStack, Ht as bindIsolatedHandle, In as WEB_PERMISSION_TO_PROTOCOL_PERMISSION, It as Dialog, Jn as CallbackRegistry, Kn as disposeSymbol, Ln as CDPSession, Lt as Accessibility, Mn as invokeAtMostOnceForArguments, Mt as InterceptResolutionAction, Nn as throwIfDisposed, Nt as STATUS_TEXTS, On as BrowserContext, Ot as SecurityDetails, Pt as handleError, Rt as Frame, St as WebWorker, Ut as JSHandle, Vt as ElementHandle, Zn as isErrorLike, _t as Mouse, an as stringifyFunction, cn as Tracing, dt as ConsoleMessage, en as ARIAQueryHandler, fn as Coverage, gt as Keyboard, ht as TargetType, in as interpolateFunction, jn as inertIfDisposed, jt as HTTPRequest, kn as bubble, kt as HTTPResponse, mn as Page, mt as Target, nn as LazyArg, on as AsyncIterableUtil, sn as FileChooser, un as EmulationManager, vt as MouseButton, wt as Realm, yt as Touchscreen, zn as EventEmitter } from "./index-browser-CysrjMyM.js";
4
4
  import "./BrowserWebSocketTransport-wm99h94r.js";
5
5
 
6
6
  //#region node_modules/mitt/dist/mitt.mjs
@@ -0,0 +1,20 @@
1
+ import { Context } from "@deepseek-ai/cordis";
2
+ import { ProfileContext } from "@deepseek-ai/dsh-app-boot";
3
+
4
+ //#region src/bundle-delivery.d.ts
5
+ declare const name = "dashr-bundle-delivery";
6
+ declare const inject: string[];
7
+ interface DeliveryResult {
8
+ installed: string[];
9
+ restartRequired: boolean;
10
+ }
11
+ /** First registration enables a companion; native reconciliation preserves retained disablement. */
12
+ declare function reconcileBundledDelivery(profile: ProfileContext, signal?: AbortSignal): Promise<DeliveryResult>;
13
+ declare function apply(ctx: Context): void;
14
+ declare const _default: {
15
+ name: string;
16
+ inject: string[];
17
+ apply: typeof apply;
18
+ };
19
+ //#endregion
20
+ export { apply, _default as default, inject, name, reconcileBundledDelivery };
@@ -0,0 +1,209 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { spawn } from "node:child_process";
3
+ import { mkdir, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
4
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
7
+
8
+ //#region src/bundle-delivery.ts
9
+ const name = "dashr-bundle-delivery";
10
+ const inject = ["profileContext", "appReady"];
11
+ const hash = (bytes) => createHash("sha256").update(bytes).digest("hex");
12
+ const json = async (path$1) => JSON.parse(await readFile(path$1, "utf8"));
13
+ async function optionalJson(path$1) {
14
+ try {
15
+ return await json(path$1);
16
+ } catch (error) {
17
+ if (error.code === "ENOENT") return void 0;
18
+ throw error;
19
+ }
20
+ }
21
+ async function contained(root, path$1) {
22
+ if (isAbsolute(path$1)) throw new Error("Pack delivery path must be relative");
23
+ const base = await realpath(root), file = await realpath(resolve(base, path$1));
24
+ const rel = relative(base, file);
25
+ if (rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute(rel)) throw new Error("Pack delivery path escapes its owner");
26
+ return file;
27
+ }
28
+ /** A child process avoids inheriting a running HMR transaction's AsyncLocalStorage. */
29
+ async function installNative(profile, archive, expected, signal) {
30
+ signal?.throwIfAborted();
31
+ const childScript = fileURLToPath(new URL("../scripts/register-bundle.mjs", import.meta.url));
32
+ return new Promise((done, fail) => {
33
+ const child = spawn(process.execPath, [childScript], {
34
+ stdio: [
35
+ "pipe",
36
+ "pipe",
37
+ "pipe"
38
+ ],
39
+ cwd: profile.dir
40
+ });
41
+ let output = "", diagnostic = "";
42
+ const abort = () => {
43
+ child.kill("SIGTERM");
44
+ };
45
+ const timeout = setTimeout(abort, 36e4);
46
+ signal?.addEventListener("abort", abort, { once: true });
47
+ child.stdout.setEncoding("utf8").on("data", (chunk) => {
48
+ output = (output + chunk).slice(-32768);
49
+ });
50
+ child.stderr.setEncoding("utf8").on("data", (chunk) => {
51
+ diagnostic = (diagnostic + chunk).slice(-4096);
52
+ });
53
+ child.on("error", fail);
54
+ child.on("close", (code) => {
55
+ clearTimeout(timeout);
56
+ signal?.removeEventListener("abort", abort);
57
+ if (signal?.aborted) {
58
+ fail(signal.reason);
59
+ return;
60
+ }
61
+ if (code !== 0) {
62
+ fail(/* @__PURE__ */ new Error(`Native companion registration failed (${code}): ${diagnostic.trim() || output.trim()}`));
63
+ return;
64
+ }
65
+ try {
66
+ const result = JSON.parse(output);
67
+ if (result.exitCode !== 0) fail(/* @__PURE__ */ new Error(`Native companion registration failed (${result.exitCode}); diagnostics: ${result.logPath ?? "unavailable"}`));
68
+ else if (![
69
+ "installed",
70
+ "owner-changed",
71
+ "companion-changed",
72
+ "companion-removed"
73
+ ].includes(result.disposition)) fail(/* @__PURE__ */ new Error("Native companion registration returned an invalid disposition"));
74
+ else done(result.disposition);
75
+ } catch (error) {
76
+ fail(error);
77
+ }
78
+ });
79
+ child.stdin.on("error", () => {});
80
+ child.stdin.end(JSON.stringify({
81
+ profile,
82
+ archive,
83
+ expected
84
+ }));
85
+ });
86
+ }
87
+ /** First registration enables a companion; native reconciliation preserves retained disablement. */
88
+ async function reconcileBundledDelivery(profile, signal) {
89
+ const directory = join(profile.home, "bundle-artifacts");
90
+ await mkdir(directory, {
91
+ recursive: true,
92
+ mode: 448
93
+ });
94
+ const key = hash(profile.dir);
95
+ return withFileLock(join(directory, key + ".delivery"), async () => {
96
+ signal?.throwIfAborted();
97
+ const receiptPath = join(directory, key + ".json");
98
+ const receipts = await optionalJson(receiptPath) ?? {};
99
+ const manifest = await json(join(profile.dir, "package.json"));
100
+ const result = {
101
+ installed: [],
102
+ restartRequired: false
103
+ };
104
+ for (const owner of Object.keys(manifest.dependencies ?? {})) {
105
+ const ownerDir = join(profile.dir, "node_modules", owner);
106
+ const ownerManifest = await optionalJson(join(ownerDir, "package.json"));
107
+ if (ownerManifest?.superd?.delivery === void 0) continue;
108
+ const descriptorPath = await contained(ownerDir, ownerManifest.superd.delivery);
109
+ const descriptor = await json(descriptorPath);
110
+ if (!Array.isArray(descriptor.companions)) throw new Error("Invalid pack delivery descriptor");
111
+ for (const item of descriptor.companions) {
112
+ if (item.name !== "better-dsh" || item.version !== ownerManifest.dependencies?.[item.name] || !/^[a-f0-9]{64}$/.test(item.sha256)) throw new Error("Invalid companion identity/version/digest");
113
+ const bytes = await readFile(await contained(dirname(descriptorPath), item.tarball));
114
+ if (hash(bytes) !== item.sha256) throw new Error(`Pack companion SHA256 mismatch: ${item.name}`);
115
+ const archive = join(directory, `${item.name}-${item.sha256}.tgz`);
116
+ const cached = await optionalJson(join(profile.dir, "node_modules", item.name, "package.json"));
117
+ const current = await json(join(profile.dir, "package.json"));
118
+ const ownerSpec = current.dependencies?.[owner];
119
+ if (ownerSpec === void 0) continue;
120
+ const priorSpec = current.dependencies?.[item.name];
121
+ const receiptKey = `${owner}:${item.name}`;
122
+ if (priorSpec === void 0 && receipts[receiptKey] === item.sha256) continue;
123
+ if (priorSpec === "file:" + archive && cached?.name === item.name && cached.version === item.version) {
124
+ receipts[receiptKey] = item.sha256;
125
+ await writeFileAtomic(receiptPath, JSON.stringify(receipts) + "\n", { mode: 384 });
126
+ continue;
127
+ }
128
+ try {
129
+ if (hash(await readFile(archive)) !== item.sha256) throw new Error(`Cached companion SHA256 mismatch: ${item.name}`);
130
+ } catch (error) {
131
+ if (error.code !== "ENOENT") throw error;
132
+ const temporary = archive + "." + randomUUID() + ".tmp";
133
+ try {
134
+ await writeFile(temporary, bytes, {
135
+ flag: "wx",
136
+ mode: 384
137
+ });
138
+ await rename(temporary, archive);
139
+ } finally {
140
+ await rm(temporary, { force: true });
141
+ }
142
+ }
143
+ signal?.throwIfAborted();
144
+ const disposition = await installNative(profile, archive, {
145
+ owner,
146
+ ownerSpec,
147
+ companion: item,
148
+ ...priorSpec === void 0 ? {} : { priorSpec }
149
+ }, signal);
150
+ if (disposition === "owner-changed" || disposition === "companion-changed") continue;
151
+ receipts[receiptKey] = item.sha256;
152
+ await writeFileAtomic(receiptPath, JSON.stringify(receipts) + "\n", { mode: 384 });
153
+ if (disposition === "companion-removed") continue;
154
+ result.installed.push(`${item.name}@${item.version}`);
155
+ result.restartRequired ||= priorSpec !== void 0;
156
+ }
157
+ }
158
+ return result;
159
+ }, { waitMs: 12e4 });
160
+ }
161
+ function apply(ctx) {
162
+ const signal = new AbortController();
163
+ let started = false, running = false, again = false;
164
+ const reconcile = async () => {
165
+ if (!started || signal.signal.aborted) return;
166
+ if (running) {
167
+ again = true;
168
+ return;
169
+ }
170
+ running = true;
171
+ try {
172
+ const result = await reconcileBundledDelivery(ctx.profileContext, signal.signal);
173
+ if (result.installed.length) {
174
+ ctx.logger.info(`Registered ${result.installed.join(", ")} from its containing local pack${result.restartRequired ? "; restart DSH to use the updated code" : ""}`);
175
+ ctx.emit("plugin-manager/changed", { reason: "install" });
176
+ }
177
+ } catch (error) {
178
+ if (!signal.signal.aborted) ctx.logger.error("Local pack companion registration failed; retry by re-enabling the bundle", error);
179
+ } finally {
180
+ running = false;
181
+ if (again && !signal.signal.aborted) {
182
+ again = false;
183
+ reconcile();
184
+ }
185
+ }
186
+ };
187
+ ctx.effect(() => {
188
+ const offReady = ctx.appReady.onReady(() => {
189
+ started = true;
190
+ reconcile();
191
+ });
192
+ const offChange = ctx.on("plugin-manager/changed", () => {
193
+ reconcile();
194
+ });
195
+ return () => {
196
+ offReady();
197
+ offChange();
198
+ signal.abort();
199
+ };
200
+ }, "bundle-delivery: native registration");
201
+ }
202
+ var bundle_delivery_default = {
203
+ name,
204
+ inject,
205
+ apply
206
+ };
207
+
208
+ //#endregion
209
+ export { apply, bundle_delivery_default as default, inject, name, reconcileBundledDelivery };
@@ -64,7 +64,7 @@ const zh = {
64
64
  };
65
65
 
66
66
  //#endregion
67
- //#region \0dsh-css:/home/u1/workspaces/dashr/better-dsh/src/failover/client/FailoverRow.module.css.mjs
67
+ //#region \0dsh-css:/home/u1/workspaces/superd/better-dsh/src/failover/client/FailoverRow.module.css.mjs
68
68
  const css$1 = "\n._440e1d7b_row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 0;\n}\n\n._a4f2ceec_rowText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n._9865b509_title {\n font-weight: 600;\n font-size: 14px;\n}\n\n\n._3cfec826_slots {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 6px;\n}\n\n._11c2662d_select {\n width: 280px;\n max-width: 100%;\n min-width: 0;\n}\n\n._b7c358f9_alert {\n color: var(--dsw-alias-danger, #c0392b);\n font-size: 12px;\n}\n";
69
69
  const tagId$1 = "better-dsh/FailoverRow.module.css";
70
70
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
@@ -463,7 +463,7 @@ const zh$1 = {
463
463
  };
464
464
 
465
465
  //#endregion
466
- //#region \0dsh-css:/home/u1/workspaces/dashr/better-dsh/src/compaction/client/CompactionRow.module.css.mjs
466
+ //#region \0dsh-css:/home/u1/workspaces/superd/better-dsh/src/compaction/client/CompactionRow.module.css.mjs
467
467
  const css = "\n\n\n._13e3747c_thresholdRow {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 0;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._8ad3ff3f_thresholdText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-right: 48px;\n}\n\n._9ffb627e_thresholdTitle {\n font-size: 14px;\n font-weight: 400;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n}\n\n._01bea389_thresholdDesc {\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._7f9578de_thresholdError {\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n color: var(--dsw-alias-danger, #c0392b);\n}\n\n\n._cddd78cd_thresholdControl {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n\n._6058fea9_thresholdStepper {\n position: relative; \n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 72px;\n height: 36px;\n border-radius: 18px;\n background: var(--dsw-alias-bg-module-platform);\n}\n\n._39d30469_thresholdValue {\n min-width: 18px;\n text-align: center;\n font-size: 14px;\n line-height: 22px;\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-primary);\n}\n\n._68bd35c6_thresholdUnit {\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-secondary);\n}\n\n\n._904da366_thresholdArrows {\n position: absolute;\n right: 8px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n opacity: 0;\n}\n\n._6058fea9_thresholdStepper:hover ._904da366_thresholdArrows,\n._6058fea9_thresholdStepper:focus-within ._904da366_thresholdArrows {\n opacity: 1;\n}\n\n\n._ae9106b1_thresholdArrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 17px;\n height: 12px;\n padding: 0;\n border: none;\n border-radius: 3px;\n background: color-mix(in srgb, var(--dsw-alias-bg-layer-1) 75%, transparent);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._ae9106b1_thresholdArrow:hover:not(:disabled) {\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._ae9106b1_thresholdArrow:disabled {\n color: var(--dsw-alias-label-caption);\n cursor: default;\n}\n";
468
468
  const tagId = "better-dsh/CompactionRow.module.css";
469
469
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
@@ -1,6 +1,6 @@
1
1
  import { t as Schema } from "../lib-C8_jXvwA.js";
2
- import { Context } from "@deepseek-ai/cordis";
3
2
  import { randomUUID } from "node:crypto";
3
+ import { Context } from "@deepseek-ai/cordis";
4
4
  import { RetryId } from "@deepseek-ai/dsh-llm-retry";
5
5
 
6
6
  //#region src/failover/config.ts
@@ -1,10 +1,10 @@
1
- import { f as UrlSchemesError, t as buildFsLayerResolver } from "../wrap-kTohEeis.js";
2
- import { Context } from "@deepseek-ai/cordis";
3
- import { dirname, sep } from "node:path";
1
+ import { f as UrlSchemesError, t as buildFsLayerResolver } from "../wrap-T4I0nfPM.js";
4
2
  import { stat } from "node:fs/promises";
3
+ import { dirname, sep } from "node:path";
4
+ import { Context } from "@deepseek-ai/cordis";
5
+ import { LocalFileSystem } from "@deepseek-ai/dsh-fs-local";
5
6
  import { FsError } from "@deepseek-ai/dsh-fs";
6
7
  import { writableRoots } from "@deepseek-ai/dsh-sandbox";
7
- import { LocalFileSystem } from "@deepseek-ai/dsh-fs-local";
8
8
 
9
9
  //#region ../upstream/deepseek-harness/packages/fs/fs-sandbox/lib/index.js
10
10
  /**
package/lib/hmr.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import Hmr, { HmrConfig } from "@deepseek-ai/dsh-hmr";
2
+ import { Context } from "@deepseek-ai/cordis";
3
+
4
+ //#region src/hmr.d.ts
5
+
6
+ /**
7
+ * Native runExclusive keeps a boolean in ALS. HTTP servers created while
8
+ * replacing webServer inherit that boolean after the transaction finishes,
9
+ * so subsequent native Plugin Manager requests are refused as nested.
10
+ *
11
+ * The public runExclusive/watchConfig APIs expose no selective context reset.
12
+ * AsyncLocalStorage.snapshot() also resets AgentRegistry initiator attribution
13
+ * and its teardown lineage, so it cannot safely repair this host transaction.
14
+ * This compatibility bridge reads the native TS-private `executing` storage
15
+ * after checking its runtime shape. It never replaces that storage or changes
16
+ * upstream files: only exit() clears its inherited value while the unchanged
17
+ * native method establishes the next transaction. Native queue, closing,
18
+ * exact watchers, module reload and disposal retain their original semantics.
19
+ *
20
+ * The mutable token rejects nesting only while its operation is still active;
21
+ * resources created by that operation can initiate later transactions.
22
+ * A native implementation change fails initialization explicitly instead of
23
+ * silently dropping queue or lifecycle guarantees.
24
+ */
25
+ declare class BetterHmr extends Hmr {
26
+ private readonly nativeTransactions;
27
+ private readonly liveTransactions;
28
+ constructor(ctx: Context, config: HmrConfig);
29
+ runExclusive<T>(operation: () => Promise<T>): Promise<T>;
30
+ }
31
+ //#endregion
32
+ export { BetterHmr as default };
package/lib/hmr.js ADDED
@@ -0,0 +1,49 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import Hmr from "@deepseek-ai/dsh-hmr";
3
+
4
+ //#region src/hmr.ts
5
+ /**
6
+ * Native runExclusive keeps a boolean in ALS. HTTP servers created while
7
+ * replacing webServer inherit that boolean after the transaction finishes,
8
+ * so subsequent native Plugin Manager requests are refused as nested.
9
+ *
10
+ * The public runExclusive/watchConfig APIs expose no selective context reset.
11
+ * AsyncLocalStorage.snapshot() also resets AgentRegistry initiator attribution
12
+ * and its teardown lineage, so it cannot safely repair this host transaction.
13
+ * This compatibility bridge reads the native TS-private `executing` storage
14
+ * after checking its runtime shape. It never replaces that storage or changes
15
+ * upstream files: only exit() clears its inherited value while the unchanged
16
+ * native method establishes the next transaction. Native queue, closing,
17
+ * exact watchers, module reload and disposal retain their original semantics.
18
+ *
19
+ * The mutable token rejects nesting only while its operation is still active;
20
+ * resources created by that operation can initiate later transactions.
21
+ * A native implementation change fails initialization explicitly instead of
22
+ * silently dropping queue or lifecycle guarantees.
23
+ */
24
+ var BetterHmr = class extends Hmr {
25
+ nativeTransactions;
26
+ liveTransactions = new AsyncLocalStorage();
27
+ constructor(ctx, config) {
28
+ super(ctx, config);
29
+ const storage = this.executing;
30
+ if (!(storage instanceof AsyncLocalStorage) || typeof storage.getStore !== "function" || typeof storage.exit !== "function" || typeof storage.run !== "function") throw new Error("Better Dash HMR cannot reset this native HMR transaction context: expected executing AsyncLocalStorage");
31
+ this.nativeTransactions = storage;
32
+ }
33
+ runExclusive(operation) {
34
+ if (this.liveTransactions.getStore()?.active) return Promise.reject(/* @__PURE__ */ new Error("HMR transactions cannot be nested"));
35
+ return this.nativeTransactions.exit(() => super.runExclusive(() => {
36
+ const token = { active: true };
37
+ return this.liveTransactions.run(token, async () => {
38
+ try {
39
+ return await operation();
40
+ } finally {
41
+ token.active = false;
42
+ }
43
+ });
44
+ }));
45
+ }
46
+ };
47
+
48
+ //#endregion
49
+ export { BetterHmr as default };