@sqdr2/dsh-fusion 0.3.0 → 0.3.2

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.en.md CHANGED
@@ -186,6 +186,8 @@ For Windows development, put PowerShell 7 (`pwsh`), Node and Python on the test
186
186
 
187
187
  The plugin uses only DSH's public plugin APIs and never modifies DSH itself. How to adapt it to a new DSH release: [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md).
188
188
 
189
+ How to cut a release (bump the version, rebuild `lib/`, push a tag, let CI publish over OIDC): [RELEASING.md](RELEASING.md).
190
+
189
191
  ## License
190
192
 
191
193
  Apache-2.0. Forked from [`aa2246740/dsh-model-fusion`](https://github.com/aa2246740/dsh-model-fusion), also under Apache-2.0.
package/README.md CHANGED
@@ -176,6 +176,8 @@ Windows 开发环境需将 PowerShell 7(`pwsh`)、Node 和 Python 加入运
176
176
 
177
177
  插件只使用 DSH 公开的插件接口,不修改 DSH 源码。适配新版本 DSH 的做法见 [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md)。
178
178
 
179
+ 发版流程(改版本号、重建 `lib/`、打 tag、CI 经 OIDC 发到 npm)见 [RELEASING.zh.md](RELEASING.zh.md)。
180
+
179
181
  ## 许可
180
182
 
181
183
  Apache-2.0。上游 fork 自 [`aa2246740/dsh-model-fusion`](https://github.com/aa2246740/dsh-model-fusion),同样以 Apache-2.0 发布。
package/RELEASING.md ADDED
@@ -0,0 +1,123 @@
1
+ # Releasing
2
+
3
+ [中文](RELEASING.zh.md) · [Install](INSTALL.md) · [README](README.en.md)
4
+
5
+ Maintainer notes. Users do not need this page.
6
+
7
+ `@sqdr2/dsh-fusion` publishes to npm from GitHub Actions over OIDC, so no long-lived token exists anywhere. This page
8
+ covers the one-time setup that makes that work, and the loop for each release afterwards.
9
+
10
+ ## What triggers a publish
11
+
12
+ Only two events:
13
+
14
+ | Event | Result |
15
+ |---|---|
16
+ | Push a tag matching `v*` | build, test, publish |
17
+ | `workflow_dispatch` | same; `dry_run=true` stops before publishing |
18
+
19
+ **Pushing to `main` never publishes.** A merge, a docs fix or a version bump sitting on `main` has no effect on npm
20
+ until a tag exists.
21
+
22
+ The workflow skips a version that is already on npm, so re-running a tag is safe: it rebuilds and retests, then exits
23
+ without touching the registry.
24
+
25
+ ## One-time setup
26
+
27
+ Both steps are already done for this repository. They are recorded here because a fork that renames the package has to
28
+ repeat them, and because a misconfigured trusted publisher fails in a way that looks like a broken workflow.
29
+
30
+ ### 1. Enable Actions
31
+
32
+ This repository is a fork, and GitHub disables Actions on forks by default. Without this step a tag push is silently
33
+ ignored: no run is created, no failure appears, and the Actions tab reports `0 workflow runs`.
34
+
35
+ Open the **Actions** tab and accept the "I understand my workflows, go ahead and enable them" prompt.
36
+
37
+ ### 2. Add a trusted publisher on npm
38
+
39
+ OIDC publishing is authorised per package, on the package's own settings page, which a name that has never been
40
+ published does not have. So the very first release of a name can only be done by hand:
41
+
42
+ 1. Publish once with a granular token that bypasses 2FA (`bypass_2fa: true`, `package: write` on the right scope).
43
+ A token without 2FA bypass is rejected with `E403 Two-factor authentication ... is required to publish packages`,
44
+ and a token scoped to `@sqdr2` cannot publish an unscoped name at all.
45
+ 2. On **npmjs.com → the package → Settings → Trusted publishing**, add:
46
+
47
+ | Field | Value |
48
+ | --- | --- |
49
+ | Provider | GitHub Actions |
50
+ | Repository | `SQDR2/dsh-fusion` |
51
+ | Workflow | `publish.yml` |
52
+ | Permission | allow npm publish |
53
+
54
+ The account needs 2FA of its own first. The package page only says "2FA has been enabled for this package. It is
55
+ recommended that you configure 2FA for your npm account", and submitting the form bounces to
56
+ `/settings/<user>/tfa` asking for a security key or authenticator. Configure account-level 2FA before starting, or
57
+ the form silently turns into a 2FA enrolment page and nothing is created.
58
+
59
+ 3. Publish a version within **2 days**. A new trust configuration is only validated by a first successful publish;
60
+ unvalidated ones expire and cannot be edited afterwards, only deleted and recreated.
61
+
62
+ Once the trusted publisher is validated, recommend **Settings → Publishing access → Require two-factor authentication
63
+ and disallow tokens** on the package. Tokens stop being usable for publishing; only the workflow can publish.
64
+
65
+ The npm CLI cannot create a trusted publisher: `npm trust github` needs an interactive 2FA credential, and the API
66
+ rejects a 2FA-bypass token with `Granular access tokens that bypass two-factor authentication may not perform this
67
+ action`. This step is browser-only by design.
68
+
69
+ ## Cutting a release
70
+
71
+ `package.json` is the single source of truth for the version. The tag must match it exactly or the workflow stops at its
72
+ first step.
73
+
74
+ ```sh
75
+ # 1. Bump the version in package.json (and nowhere else).
76
+ # 2. Rebuild lib/ — it is tracked in git and shipped in the tarball, so a stale
77
+ # lib/ publishes code that does not match the tagged source.
78
+ DSHX_HARNESS=/path/to/deepseek-harness-0.2.0-rc.2 pnpm build
79
+ pnpm typecheck && pnpm test
80
+ # 3. Commit the source and the rebuilt lib/ together.
81
+ git add -A && git commit -m "chore(release): 0.3.1"
82
+ # 4. Tag and push both.
83
+ git tag v0.3.1 && git push origin main v0.3.1
84
+ ```
85
+
86
+ The workflow then runs `pnpm install`, `pnpm build`, `pnpm test` and, on a tag, `npm publish --access public`.
87
+ A published version also gets a provenance attestation, so `npm view` can point at the commit it was built from.
88
+
89
+ ### Two things the build is pinned to
90
+
91
+ `scripts/build.mjs` accepts only the Host versions in `engines.dsh` (`0.2.0-rc.2` and `0.2.1-rc.2`) and fails
92
+ otherwise. CI checks out `dsh-v0.2.0-rc.2` for that reason.
93
+
94
+ The bundler version in the workflow is pinned to exactly `tsdown@0.22.2`. `lib/` is committed, so a different bundler
95
+ would commit a bundle that does not match what was tested; `0.22.14`, for instance, reformats several hundred lines.
96
+
97
+ ## Checking a release
98
+
99
+ ```sh
100
+ npm view @sqdr2/dsh-fusion version dist-tags
101
+ npm view @sqdr2/dsh-fusion@0.3.0 dist.attestations # present means it came from CI
102
+ ```
103
+
104
+ To check the artefact rather than the metadata:
105
+
106
+ ```sh
107
+ npm install @sqdr2/dsh-fusion@0.3.0
108
+ node -e "import('@sqdr2/dsh-fusion').then(m => console.log(m.name, m.inject.length))"
109
+ grep -o 'id: \"[^\"]*\"' node_modules/@sqdr2/dsh-fusion/lib/client.js | head -1
110
+ ```
111
+
112
+ The host bundle must export `dsh-fusion`, and the client bundle's registration id must be the package name
113
+ `@sqdr2/dsh-fusion`. They differ on purpose: see [INSTALL.md](INSTALL.md) for why, and `src/identity.ts` for how.
114
+
115
+ ## If a publish fails
116
+
117
+ | Symptom | Cause |
118
+ | --- | --- |
119
+ | Tag pushed, `0 workflow runs` | Actions not enabled on the fork |
120
+ | `404` or `ENEEDAUTH` from `npm publish` | No trusted publisher on npm, or it expired unvalidated |
121
+ | `tag vX != package.json Y` | Version bumped in one place only |
122
+ | `Unsupported Host package version` | `HARNESS_REF` drifted from `engines.dsh` |
123
+ | Bundle rebuild differs from committed `lib/` | Bundler version not pinned to `0.22.2` |
@@ -0,0 +1,115 @@
1
+ # 发版
2
+
3
+ [English](RELEASING.md) · [安装](INSTALL.zh.md) · [README](README.md)
4
+
5
+ 维护者用。普通用户不需要看这一页。
6
+
7
+ `@sqdr2/dsh-fusion` 由 GitHub Actions 通过 OIDC 发到 npm,任何地方都不存在长期 token。本页说明让它跑起来的一次性配置,以及之后每一版的流程。
8
+
9
+ ## 什么会触发发布
10
+
11
+ 只有两种事件:
12
+
13
+ | 事件 | 结果 |
14
+ | --- | --- |
15
+ | 推送匹配 `v*` 的 tag | 构建、测试、发布 |
16
+ | `workflow_dispatch` | 同上;`dry_run=true` 在发布前停下 |
17
+
18
+ **往 `main` 推永远不会发布。** 合一个 PR、改一处文档、或者把版本号改好放在 `main` 上,在有 tag 之前都不会影响 npm。
19
+
20
+ workflow 会跳过 npm 上已存在的版本,所以同一个 tag 重跑是安全的:重新构建、重新测试,然后不碰 registry 直接退出。
21
+
22
+ ## 一次性配置
23
+
24
+ 两步本仓库都已完成。之所以记在这里,是因为 fork 后改名要重做一遍,而且信任配置配错时的失败现象很像「workflow 坏了」。
25
+
26
+ ### 1. 启用 Actions
27
+
28
+ 本仓库是 fork,GitHub 默认禁用 fork 的 Actions。这一步不做,推 tag 会被静默忽略:不建运行、不报错,Actions 页面显示 `0 workflow runs`。
29
+
30
+ 打开 **Actions** 标签页,接受 “I understand my workflows, go ahead and enable them” 提示。
31
+
32
+ ### 2. 在 npm 上加信任配置
33
+
34
+ OIDC 发布是按包授权的,配置在包自己的设置页上,而一个从未发布过的包名没有这个页面。所以某个包名的第一版只能手发:
35
+
36
+ 1. 用一个勾了 2FA bypass 的 granular token 手动发一次(`bypass_2fa: true`,`package: write`,作用域要对)。
37
+ 不勾 bypass 会被拒:`E403 Two-factor authentication ... is required to publish packages`;
38
+ 而作用域是 `@sqdr2` 的 token 根本无法发布无 scope 的包名。
39
+ 2. 在 **npmjs.com → 该包 → Settings → Trusted publishing** 添加:
40
+
41
+ | 字段 | 值 |
42
+ | --- | --- |
43
+ | Provider | GitHub Actions |
44
+ | Repository | `SQDR2/dsh-fusion` |
45
+ | Workflow | `publish.yml` |
46
+ | Permission | allow npm publish |
47
+
48
+ **账号自己得先有 2FA。** 包页面上只会写一句 “2FA has been enabled for this package. It is recommended that you
49
+ configure 2FA for your npm account”,而提交表单会跳到 `/settings/<user>/tfa` 要求录入安全密钥或认证器。
50
+ 动手之前先把账号级 2FA 配好,否则表单会静默变成 2FA 注册页,什么都不会创建。
51
+
52
+ 3. 在 **2 天内**发一个版本。新的信任配置只有首次成功发布才算验证通过;未验证的会过期,
53
+ 之后不能编辑,只能删掉重建。
54
+
55
+ 信任配置验证通过后,建议在包上开 **Settings → Publishing access → Require two-factor authentication and disallow tokens**。
56
+ 此后 token 不能再发布,只有 workflow 能发。
57
+
58
+ npm CLI 建不了信任配置:`npm trust github` 需要交互式 2FA 凭据,而 API 会拒绝 bypass 2FA 的 token,
59
+ 返回 `Granular access tokens that bypass two-factor authentication may not perform this action`。
60
+ 这一步在设计上只能走浏览器。
61
+
62
+ ## 发一版
63
+
64
+ 版本号的唯一真源是 `package.json`。tag 必须与它完全一致,否则 workflow 会在第一步退出。
65
+
66
+ ```sh
67
+ # 1. 改 package.json 里的版本号(别处不要改)。
68
+ # 2. 重建 lib/ —— 它纳入版本库并随包发布,lib/ 陈旧等于发布了
69
+ # 与 tag 源码不一致的代码。
70
+ DSHX_HARNESS=/path/to/deepseek-harness-0.2.0-rc.2 pnpm build
71
+ pnpm typecheck && pnpm test
72
+ # 3. 源码和重建后的 lib/ 一起提交。
73
+ git add -A && git commit -m "chore(release): 0.3.1"
74
+ # 4. 打 tag 并一起推。
75
+ git tag v0.3.1 && git push origin main v0.3.1
76
+ ```
77
+
78
+ workflow 随后依次执行 `pnpm install`、`pnpm build`、`pnpm test`,在 tag 上再执行 `npm publish --access public`。
79
+ 发布出来的版本还带 provenance 证明,可以用 `npm view` 追溯它是从哪个 commit 构建的。
80
+
81
+ ### 构建被钉死的两处
82
+
83
+ `scripts/build.mjs` 只接受 `engines.dsh` 里列出的 Host 版本(`0.2.0-rc.2` 和 `0.2.1-rc.2`),其余直接报错。
84
+ CI 因此 checkout `dsh-v0.2.0-rc.2`。
85
+
86
+ workflow 里的打包器版本精确钉在 `tsdown@0.22.2`。`lib/` 是提交进仓库的,换个打包器就会提交一份与测试结果不一致的产物;
87
+ 比如 `0.22.14` 会重写几百行格式。
88
+
89
+ ## 检查一次发布
90
+
91
+ ```sh
92
+ npm view @sqdr2/dsh-fusion version dist-tags
93
+ npm view @sqdr2/dsh-fusion@0.3.0 dist.attestations # 有值说明出自 CI
94
+ ```
95
+
96
+ 想验证产物本身而不是元数据:
97
+
98
+ ```sh
99
+ npm install @sqdr2/dsh-fusion@0.3.0
100
+ node -e "import('@sqdr2/dsh-fusion').then(m => console.log(m.name, m.inject.length))"
101
+ grep -o 'id: "[^"]*"' node_modules/@sqdr2/dsh-fusion/lib/client.js | head -1
102
+ ```
103
+
104
+ 宿主 bundle 必须导出 `dsh-fusion`,客户端 bundle 的注册 id 必须是包名 `@sqdr2/dsh-fusion`。
105
+ 两者不同是刻意的:原因见 [INSTALL.zh.md](INSTALL.zh.md),实现见 `src/identity.ts`。
106
+
107
+ ## 发布失败时
108
+
109
+ | 现象 | 原因 |
110
+ | --- | --- |
111
+ | 推了 tag,`0 workflow runs` | fork 上没有启用 Actions |
112
+ | `npm publish` 报 `404` 或 `ENEEDAUTH` | npm 上没有信任配置,或它过期未验证 |
113
+ | `tag vX != package.json Y` | 版本号只改了一处 |
114
+ | `Unsupported Host package version` | `HARNESS_REF` 与 `engines.dsh` 不一致 |
115
+ | 重建后的 bundle 与已提交的 `lib/` 不同 | 打包器没钉在 `0.22.2` |
package/lib/client.js CHANGED
@@ -1247,7 +1247,7 @@ window.__ModuleLoader__.load({
1247
1247
  //#region src/client/status-polling.ts
1248
1248
  const entries = /* @__PURE__ */ new Map();
1249
1249
  const visible = () => document.visibilityState !== "hidden";
1250
- const running = new Set([
1250
+ const running = /* @__PURE__ */ new Set([
1251
1251
  "分析",
1252
1252
  "执行",
1253
1253
  "修改",