dsh-remote-agent 0.9.6 → 0.9.7

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 (3) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/lib/e2e.js +42 -1
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,6 +9,57 @@
9
9
 
10
10
  ---
11
11
 
12
+ ## [0.9.7] - 2026-10-20
13
+
14
+ > **0.9.6 的 CI 回归修复。** 0.9.6 在本地全绿,但 GitHub Actions 的
15
+ > `ubuntu-latest / node 24.x` 上 E2E 握手全部超时。
16
+
17
+ ### 修复:X25519 私钥重建改用 DER,不再依赖 JWK 的 `x` 校验
18
+
19
+ **现象**(CI run `39384173448`,只有 ubuntu/node24 失败):
20
+
21
+ Error: timeout waiting for e2e session on test-worker
22
+ code: 'ERR_CRYPTO_INVALID_JWK'
23
+
24
+ **根因**:`lib/e2e.js` 用 JWK 重建私钥:
25
+
26
+ ```js
27
+ createPrivateKey({ key: { kty: 'OKP', crv: 'X25519', d: b64, x: '' }, format: 'jwk' })
28
+ ```
29
+
30
+ 本地 Node 24.18 接受 `x: ''`,但 CI 那个 Node 24 小版本**不接受**
31
+ (空串不是合法 base64url;省略 `x` 同样被拒)。
32
+
33
+ **这个 bug 为什么藏了这么久**:失败表现为
34
+ `timeout waiting for e2e session` —— **真因(ERR_CRYPTO_INVALID_JWK)被
35
+ 完全掩盖**,看起来像时序抖动,而本地又复现不了。
36
+
37
+ **修法**:直接用 DER 构造 —— X25519 私钥的 PKCS#8 就是
38
+ 固定 16 字节前缀 + 32 字节标量。这条路径**不经过 JWK 校验**,跨 Node
39
+ 小版本稳定。
40
+
41
+ 实测验证:DER 构造出的私钥导出的公钥 `x` 与原始 JWK 完全一致,
42
+ DH 协商结果与正常生成的密钥对一致。
43
+
44
+ **测试**:`test/e2e.test.js` 新增 2 条 ——
45
+ 双方派生会话密钥必须一致(E2E 握手的核心数学)、非法长度必须明确抛错。
46
+
47
+ ### 0.9.6 的五项体验提升(本版包含)
48
+
49
+ - **④ 统一错误翻译层** —— errno + 17 个协议码 + HTTP + 文案特征,每条带"下一步"
50
+ - **① 副机连接状态可见** —— 记录每次连接尝试,空态显示原因与修法
51
+ - **② 一键复制修法** —— 体检项旁的「复制修法」按钮(只复制,不代改文件)
52
+ - **③ 首次使用向导** —— 编号步骤 + 每步"应该看到什么"
53
+ - **⑤ 任务进度摘要** —— 任务行直接显示"最近:调用工具 Write · 共 23 步"
54
+
55
+ ```
56
+ packaging 4 项
57
+ doc-drift 126/126
58
+ diag:inject 11 项
59
+ tests 1009(1007 pass / 0 fail / 2 skip)
60
+ lint 干净
61
+ ```
62
+
12
63
  ## [0.9.6] - 2026-10-20
13
64
 
14
65
  ### 用户体验:五项提升("出了问题不知道原因"的正面回应)
package/lib/e2e.js CHANGED
@@ -97,8 +97,49 @@ export function normalizeE2EPub(raw) {
97
97
  return raw
98
98
  }
99
99
 
100
+ /**
101
+ * X25519 PKCS#8 私钥的 DER 前缀(16 字节)。
102
+ *
103
+ * 结构:SEQUENCE { INTEGER 0, SEQUENCE { OID 1.3.101.110 (X25519) },
104
+ * OCTET STRING { OCTET STRING(32 字节原始标量) } }
105
+ * 后接 32 字节标量即完整私钥。
106
+ */
107
+ const X25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b656e04220420', 'hex')
108
+
109
+ /**
110
+ * 由 base64url 的 32 字节标量构造 X25519 私钥。
111
+ *
112
+ * ═══════════════════════════════════════════════════════════════════════════
113
+ * ⚠ 为什么用 DER 而不是 JWK(2026-10-20 CI 抓到的真实缺陷)
114
+ * ═══════════════════════════════════════════════════════════════════════════
115
+ *
116
+ * 原实现:`createPrivateKey({ key: { kty:'OKP', crv:'X25519', d: b64, x: '' }, format:'jwk' })`
117
+ *
118
+ * 在本地 Node 24.18 上能过,但在 GitHub Actions 的 `ubuntu-latest / node 24.x`
119
+ * 上抛 **`ERR_CRYPTO_INVALID_JWK`** —— 那个版本对 JWK 的 `x` 校验更严
120
+ * (空串不是合法 base64url;省略 `x` 同样被拒)。
121
+ *
122
+ * 后果很隐蔽:E2E 握手失败 → 测试只看到
123
+ * `timeout waiting for e2e session on test-worker`,**真因被完全掩盖**。
124
+ *
125
+ * ── 修法 ────────────────────────────────────────────────────────────────
126
+ *
127
+ * 直接用 **DER** 构造:X25519 私钥的 PKCS#8 就是固定 16 字节前缀 + 32 字节
128
+ * 标量。这条路径**不经过 JWK 校验**,跨 Node 小版本稳定。
129
+ *
130
+ * 实测验证:DER 构造出的私钥导出的公钥 `x` 与原始 JWK 完全一致,
131
+ * 且 DH 协商结果与正常生成的密钥对一致。
132
+ */
100
133
  function x2PrivateKeyFromB64(b64) {
101
- return createPrivateKey({ key: { kty: 'OKP', crv: 'X25519', d: b64, x: '' }, format: 'jwk' })
134
+ const raw = Buffer.from(String(b64), 'base64url')
135
+ if (raw.length !== X2_PUB_BYTES) {
136
+ throw new Error(`bad x25519 private key length: ${raw.length} (expect ${X2_PUB_BYTES})`)
137
+ }
138
+ return createPrivateKey({
139
+ key: Buffer.concat([X25519_PKCS8_PREFIX, raw]),
140
+ format: 'der',
141
+ type: 'pkcs8',
142
+ })
102
143
  }
103
144
 
104
145
  function x2PublicKeyFromB64(b64) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-remote-agent",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "type": "module",
5
5
  "description": "把另一台电脑变成你 DSH 的远程 Agent 同事:副机本地持久跑任务、独立 Agent 循环,只回传 handoff 摘要与产物清单,成品按需拉取。",
6
6
  "license": "MIT",