dsh-deeppilot 0.9.9 → 0.9.11
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/COMPATIBILITY.md +78 -5
- package/README.md +11 -7
- package/README.zh-CN.md +9 -6
- package/bin/SHA256SUMS +6 -6
- package/bin/darwin-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/darwin-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/windows-amd64/dsh-deeppilot-tunnel.exe +0 -0
- package/bin/windows-arm64/dsh-deeppilot-tunnel.exe +0 -0
- package/docs/DSH_RELEASE_MEMORY.md +118 -1
- package/docs/NPM_PUBLISHING.md +19 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +56 -6
- package/lib/index.js.map +1 -1
- package/package.json +13 -12
package/COMPATIBILITY.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Compatibility
|
|
2
2
|
|
|
3
|
-
This branch targets exactly **
|
|
4
|
-
|
|
5
|
-
`0.2.1-
|
|
6
|
-
`0.2.1-rc.2`,
|
|
3
|
+
This branch targets exactly **six DSH releases**: `0.2.0-rc.2`; the `alpha`
|
|
4
|
+
channel releases `0.2.1-alpha.3`, `0.2.1-alpha.4`, and `0.2.1-alpha.5`; and the
|
|
5
|
+
`next` channel releases `0.2.1-rc.2` and `0.2.1-rc.3`. The npm channels have
|
|
6
|
+
moved since: `latest` now points at `0.2.1-rc.2`, promoted from `next`, and
|
|
7
|
+
`next` at `0.2.1-rc.3`. All six are
|
|
7
8
|
named in both `engines.dsh` and `peerDependencies`; no other version is accepted.
|
|
8
9
|
DSH evaluates that declaration before composing a profile — on every start, not
|
|
9
10
|
only on install — so a newly published DSH release deactivates this plugin until
|
|
@@ -21,9 +22,10 @@ recorded in the release memory.
|
|
|
21
22
|
| Component | Current contract | Evidence |
|
|
22
23
|
|---|---|---|
|
|
23
24
|
| Node.js | 22 or newer | Package engine and CI |
|
|
24
|
-
| DSH CLI and Host API | `engines.dsh` and `peerDependencies` both name `0.2.0-rc.2 \|\| 0.2.1-alpha.3 \|\| 0.2.1-alpha.4 \|\| 0.2.1-alpha.5 \|\| 0.2.1-rc.2` (dev pins `0.2.0-rc.2`) | Peer metadata, source typecheck, unit tests, bundle build, and config schema projection against a real 0.2.0-rc.2 CLI, plus isolated composes and live phone-protocol runs with the published 0.2.1-alpha.2, 0.2.1-alpha.3, and 0.2.1-alpha.4 CLIs, an isolated 0.2.1-alpha.5 host where this plugin now composes, starts, and answers `/phone/health` with 200 on its own LAN listener,
|
|
25
|
+
| DSH CLI and Host API | `engines.dsh` and `peerDependencies` both name `0.2.0-rc.2 \|\| 0.2.1-alpha.3 \|\| 0.2.1-alpha.4 \|\| 0.2.1-alpha.5 \|\| 0.2.1-rc.2 \|\| 0.2.1-rc.3` (dev pins `0.2.0-rc.2`) | Peer metadata, source typecheck, unit tests, bundle build, and config schema projection against a real 0.2.0-rc.2 CLI, plus isolated composes and live phone-protocol runs with the published 0.2.1-alpha.2, 0.2.1-alpha.3, and 0.2.1-alpha.4 CLIs, an isolated 0.2.1-alpha.5 host where this plugin now composes, starts, and answers `/phone/health` with 200 on its own LAN listener, a pre-widening 0.2.1-rc.2 host run where the unchanged declaration is refused at compose time, and an isolated 0.2.1-rc.3 host where the widened declaration composes, starts, and answers `/phone/health` with 200 (audits below) |
|
|
25
26
|
| iOS bridge | DeepPilot protocol v2 | Bridge protocol tests; device behavior must be checked with the running Host and app |
|
|
26
27
|
| Remote access | Tailscale Funnel on ports 443, 8443, or 10000 | Helper and supervisor tests |
|
|
28
|
+
| Funnel helper platforms | macOS 13 Ventura or later, Linux, and Windows, each on amd64/arm64; built with Go 1.27, which dropped macOS 12 | CI starts the committed helper on a native runner for each of the six targets (`helper-smoke`); no runner covers macOS 13 itself |
|
|
27
29
|
|
|
28
30
|
## DSH interfaces used here
|
|
29
31
|
|
|
@@ -73,6 +75,77 @@ carries the old top-level `debug: true` is accepted but that value is ignored:
|
|
|
73
75
|
verbose logging must be turned on again from the settings page. No other config
|
|
74
76
|
field changed shape, and the old key is not read anywhere in this version.
|
|
75
77
|
|
|
78
|
+
## 0.2.1-rc.3 audit outcome
|
|
79
|
+
|
|
80
|
+
The artifact-level audit of `dsh-v0.2.1-rc.3` (published to the npm registry
|
|
81
|
+
2026-10-23T07:54:30Z, the `next` channel release; `latest` points at `0.2.1-rc.2`)
|
|
82
|
+
against `dsh-v0.2.1-rc.2` found **no change that reaches this plugin's call
|
|
83
|
+
surface**. Nineteen packages were compared as whole trees rather than by `lib/`
|
|
84
|
+
alone — eighteen from the two installed trees plus
|
|
85
|
+
`@deepseek-ai/dsh-client-ui-slots` (the seventh declared `dsh-*` peer, absent from
|
|
86
|
+
both trees) through its registry tarball:
|
|
87
|
+
|
|
88
|
+
- **Fourteen packages differ only in `package.json`** — version and dependency
|
|
89
|
+
specs — so every file those hosts read at runtime is byte-identical.
|
|
90
|
+
- **Three packages carry one non-`package.json` change each** — `dsh-api-remotes`,
|
|
91
|
+
`dsh-api-session-controller`, and `dsh-web-app` — detailed below.
|
|
92
|
+
- **`cordis 4.0.5` and `schemastery 3.18.5` are byte-identical including
|
|
93
|
+
`package.json`**, so the vendor peer ranges need no widening again.
|
|
94
|
+
- **The tree gains one package**: `rc.2` ships 306 packages and `rc.3` 307; the
|
|
95
|
+
addition is `@deepseek-ai/dsh-client-ui-entry-customization@0.2.1-rc.3`, the
|
|
96
|
+
bundle behind the More menus. This plugin neither references it nor depends on
|
|
97
|
+
it through its own patch.
|
|
98
|
+
|
|
99
|
+
Of 3,302 shared files, 3,275 are byte-identical and 20 differ: 16 `package.json`
|
|
100
|
+
files, the three code/config files above, and the `dsh-client-ui-slots`
|
|
101
|
+
`package.json`. Across 274 analysed modules **no export symbol is added or
|
|
102
|
+
removed** (18 entry modules compared), so every earlier fix still holds
|
|
103
|
+
unchanged. The manifest delta over 19 packages covers 585 paths — 17 version
|
|
104
|
+
bumps and 568 dependency-spec moves, **zero structural differences** — with no
|
|
105
|
+
package added or removed by dependency resolution.
|
|
106
|
+
|
|
107
|
+
**The one file outside `package.json` that could reach this plugin's patch layer
|
|
108
|
+
is additive.** `@deepseek-ai/dsh-web-app/cordis.patch.yml` gained one hunk that
|
|
109
|
+
inserts the `ui-entry-customization` bundle (the More menus named in the rc.3
|
|
110
|
+
release notes). The patch anchor this plugin targets, `id: directory-picker`, is
|
|
111
|
+
byte-identical on both sides at the same offsets, and neither the new package
|
|
112
|
+
name nor `entry-customization` appears in this plugin's `cordis.patch.yml` or
|
|
113
|
+
`package.json`, so the change cannot reach any patch this plugin applies.
|
|
114
|
+
|
|
115
|
+
The other two non-`package.json` files are equally out of reach:
|
|
116
|
+
`@deepseek-ai/dsh-api-remotes/lib/client.js` only widens the client telemetry
|
|
117
|
+
event schema (`is_new_session`, `agent_preset`, and the More-menu and
|
|
118
|
+
agent-preset switch events), which this plugin neither emits nor validates, and
|
|
119
|
+
`@deepseek-ai/dsh-api-session-controller`'s
|
|
120
|
+
`lib/types/client/sessions/service.d.ts` changes a doc comment only.
|
|
121
|
+
|
|
122
|
+
The activation verdict repeats the rc.2 shape: rc.3 also reads `engines.dsh`
|
|
123
|
+
alone. Before the widening, the published rc.3 evaluator refused `0.2.1-rc.3`
|
|
124
|
+
with a single `engines.dsh` requirement and `exempted: false`, and a real rc.3
|
|
125
|
+
CLI reproduced the refusal at compose time (`skipping profile bundle
|
|
126
|
+
"dsh-deeppilot"`) while the host itself still booted and served its web port.
|
|
127
|
+
After the widening, the same evaluator admits exactly `0.2.1-rc.3` and adds no
|
|
128
|
+
other acceptance: the five earlier hosts stay admitted, and `0.2.1-rc.1`,
|
|
129
|
+
`0.2.1-rc.3.1`, `0.2.1-rc.30`, `0.2.1-RC.3`, `0.2.1`, `0.2.1-rc.2.1`, `0.2.0`,
|
|
130
|
+
`0.3.0`, and `1.0.0` remain refused. Deleting `engines.dsh` from a copy of the
|
|
131
|
+
manifest falls back to the ten peers and still admits the same six hosts, so the
|
|
132
|
+
short-circuit is unchanged.
|
|
133
|
+
|
|
134
|
+
**The positive half is complete this time.** An isolated `0.2.1-rc.3` host — its
|
|
135
|
+
own `DSH_HOME`, the plugin linked from this working tree, and no other plugin —
|
|
136
|
+
composes the plugin into the tree, starts it, and answers `/phone/health` with
|
|
137
|
+
200 on the plugin's own LAN listener (`serverVersion` `0.9.10`, protocol v2),
|
|
138
|
+
while the isolated home gains the plugin's data directory. The same profile run
|
|
139
|
+
with the declaration unchanged shows the skip line instead and no listener,
|
|
140
|
+
which is what makes the pair discriminative.
|
|
141
|
+
|
|
142
|
+
Evidence: `.rc3-verify/AUDIT.md` and `.rc3-verify/CHANGE_SURFACE.md` with the raw
|
|
143
|
+
logs under `.rc3-verify/logs/`, the evaluator reproduction in
|
|
144
|
+
`.rc3-verify/evaluator-repro.out.json`, the acceptance matrix in
|
|
145
|
+
`.rc3-verify/matrix.out.json`, the export-symbol diff in
|
|
146
|
+
`.rc3-verify/export-symbol-diff.out.json`, and the host run in
|
|
147
|
+
`.rc3-verify/HOST-BOOT.md`.
|
|
148
|
+
|
|
76
149
|
## 0.2.1-rc.2 audit outcome
|
|
77
150
|
|
|
78
151
|
The artifact-level audit of `dsh-v0.2.1-rc.2` against `dsh-v0.2.1-alpha.5` found
|
package/README.md
CHANGED
|
@@ -32,19 +32,23 @@ Host on your own computer and does not replace or modify the DSH Web UI.
|
|
|
32
32
|
|
|
33
33
|
## Install from npm
|
|
34
34
|
|
|
35
|
-
This source checkout targets Node.js 22+ and the
|
|
36
|
-
audited against — `0.2.0-rc.2
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
This source checkout targets Node.js 22+ and the six DSH releases it has been
|
|
36
|
+
audited against — `0.2.0-rc.2`, the `alpha` channel releases `0.2.1-alpha.3`,
|
|
37
|
+
`0.2.1-alpha.4`, and `0.2.1-alpha.5`, and the two `next` channel releases it has
|
|
38
|
+
admitted in turn, `0.2.1-rc.2` and `0.2.1-rc.3` — with a `web` profile. (The
|
|
39
|
+
npm channels move: `latest` now points at `0.2.1-rc.2`, which was promoted
|
|
40
|
+
from `next`, and `next` at `0.2.1-rc.3`.) DSH checks a plugin's declared
|
|
39
41
|
requirements before composing a profile, on every start rather than only on
|
|
40
42
|
install, so any other host version refuses to activate this plugin. From DSH
|
|
41
43
|
`0.2.1-alpha.4` on, that check reads `engines.dsh` and ignores
|
|
42
44
|
`peerDependencies`; older hosts know only the peer range, so both name the same
|
|
43
|
-
|
|
45
|
+
six releases. The package includes Funnel helpers
|
|
44
46
|
for macOS, Linux, and Windows on amd64/arm64; trusted-LAN mode does not require
|
|
45
|
-
the helper.
|
|
47
|
+
the helper. The helper is built with Go 1.27, which requires **macOS 13 Ventura
|
|
48
|
+
or later**: on macOS 12 and earlier, Funnel mode cannot start, while
|
|
49
|
+
trusted-LAN mode keeps working.
|
|
46
50
|
|
|
47
|
-
The current working tree names exactly those
|
|
51
|
+
The current working tree names exactly those six versions in `engines.dsh` and
|
|
48
52
|
`peerDependencies` and is built/typechecked against `0.2.0-rc.2`. A previously
|
|
49
53
|
published plugin package may still carry its own older compatibility
|
|
50
54
|
declaration until a release is made from this tree.
|
package/README.zh-CN.md
CHANGED
|
@@ -30,17 +30,20 @@
|
|
|
30
30
|
|
|
31
31
|
## 从 npm 安装
|
|
32
32
|
|
|
33
|
-
当前源码面向 Node.js 22+ 与带 `web` profile
|
|
34
|
-
`0.2.0-rc.2
|
|
35
|
-
`0.2.1-alpha.4` 与 `0.2.1-alpha.5
|
|
33
|
+
当前源码面向 Node.js 22+ 与带 `web` profile 的**六个已审计 DSH 版本**:
|
|
34
|
+
`0.2.0-rc.2`、`alpha` 通道的 `0.2.1-alpha.3`、
|
|
35
|
+
`0.2.1-alpha.4` 与 `0.2.1-alpha.5`,以及先后两版 `next` 通道的
|
|
36
|
+
`0.2.1-rc.2` 与 `0.2.1-rc.3`(npm 通道会移动:`latest` 现指向由 `next` 转正的
|
|
37
|
+
`0.2.1-rc.2`,`next` 指向 `0.2.1-rc.3`)。
|
|
36
38
|
DSH 在组合 profile 前会校验插件声明的
|
|
37
39
|
兼容要求,且**每次启动都会校验**(不只是安装时),因此其他宿主版本会拒绝
|
|
38
40
|
激活本插件。从 DSH `0.2.1-alpha.4` 起,该校验只读 `engines.dsh` 并忽略
|
|
39
|
-
`peerDependencies`;更早的宿主只认 peer
|
|
41
|
+
`peerDependencies`;更早的宿主只认 peer 范围,因此两处列出同一组六个版本。
|
|
40
42
|
npm 包内置 macOS、Linux、Windows 的 amd64/arm64 Funnel helper;可信局域网
|
|
41
|
-
模式不依赖 helper。
|
|
43
|
+
模式不依赖 helper。helper 用 Go 1.27 编译,要求 **macOS 13 Ventura 或更高版本**:
|
|
44
|
+
macOS 12 及更早版本无法启动 Funnel 模式,可信局域网模式不受影响。
|
|
42
45
|
|
|
43
|
-
当前工作树的 `engines.dsh` 与 `peerDependencies`
|
|
46
|
+
当前工作树的 `engines.dsh` 与 `peerDependencies` 精确列出这六个版本,构建与
|
|
44
47
|
类型检查针对 `0.2.0-rc.2`。从此工作树发布新版本前,已发布的旧插件包仍可能
|
|
45
48
|
带有各自旧的兼容声明。
|
|
46
49
|
|
package/bin/SHA256SUMS
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
0e49860ffd7b6fd9ba5918481cbfa2fc0a788f0c16d500de69a162d31451d526 ./darwin-amd64/dsh-deeppilot-tunnel
|
|
2
|
+
16e0b6235cb097401dc52840f11c0dcf405925d23449934cdfea93ec89c071e9 ./darwin-arm64/dsh-deeppilot-tunnel
|
|
3
|
+
ed3d60db2da2f3c17a5f7d04834faf4623a955ecc48a3aa0497c3903df8a2bce ./linux-amd64/dsh-deeppilot-tunnel
|
|
4
|
+
b5e85cd9f9f928f4204cfc15067588d1c3dcdc683a5f5b85759d5454bce2110e ./linux-arm64/dsh-deeppilot-tunnel
|
|
5
|
+
836126376d0da12abc6bafb3ed163138436f812b201bd254eb1c7cae3f8a34c7 ./windows-amd64/dsh-deeppilot-tunnel.exe
|
|
6
|
+
6b74d0f4b73f9f53b01829a84abd178c17a64950c1e9949b8fae15ef274fb99f ./windows-arm64/dsh-deeppilot-tunnel.exe
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,97 @@
|
|
|
3
3
|
> This is the durable audit record for DeepPilot's public DSH plugin. Re-audit
|
|
4
4
|
> the next DSH release instead of assuming that an rc upgrade is runtime-safe.
|
|
5
5
|
|
|
6
|
-
## Current decision — `dsh-v0.2.1-rc.
|
|
6
|
+
## Current decision — `dsh-v0.2.1-rc.3`
|
|
7
|
+
|
|
8
|
+
- **Audited release:** `dsh-v0.2.1-rc.3`, published to the npm registry
|
|
9
|
+
2026-10-23T07:54:30Z (GitHub Release 2026-10-23T15:26:39Z), and the **`next`**
|
|
10
|
+
channel release — `next` moved from `0.2.1-rc.2` to it, so this is the second
|
|
11
|
+
consecutive rc on that line to enter the supported list, each on its own audit.
|
|
12
|
+
It is **not** `latest`: the registry currently reads `latest = 0.2.1-rc.2`
|
|
13
|
+
(rc.2, promoted from `next`) and `alpha = 0.2.1-alpha.5`. This audit therefore also
|
|
14
|
+
corrected the older channel attribution that called `0.2.0-rc.2` the `latest`
|
|
15
|
+
channel in `AGENTS.md` and both READMEs — the list of six admitted hosts is
|
|
16
|
+
unchanged by that correction, only its description.
|
|
17
|
+
- **Comparison baseline:** `dsh-v0.2.1-rc.2` (the previous audited tag).
|
|
18
|
+
- **Plugin runtime verdict: no break, and no `src/` change was needed.**
|
|
19
|
+
Nineteen packages were compared **as whole trees, not by `lib/` alone** —
|
|
20
|
+
eighteen from the two installed trees plus `dsh-client-ui-slots` (the seventh
|
|
21
|
+
declared `dsh-*` peer, absent from both) through its registry tarball. Fourteen
|
|
22
|
+
differ only in `package.json`, three carry one further file each, and
|
|
23
|
+
`cordis 4.0.5` / `schemastery 3.18.5` are byte-identical including
|
|
24
|
+
`package.json`. Of 3,302 shared files, 3,275 are byte-identical and 20 differ.
|
|
25
|
+
The tree count moves 306 → 307 with the new
|
|
26
|
+
`@deepseek-ai/dsh-client-ui-entry-customization@0.2.1-rc.3`, the More-menu bundle
|
|
27
|
+
the web-app patch now references; this plugin neither references it nor depends
|
|
28
|
+
on it. Across 274 modules **no export symbol is added or removed** (18 entry
|
|
29
|
+
modules compared), so every earlier fix still holds unchanged. The manifest
|
|
30
|
+
delta over 19 packages covers 585 paths — 17 version bumps and 568
|
|
31
|
+
dependency-spec moves — with **zero structural differences**.
|
|
32
|
+
- **The three non-`package.json` files are additive or comment-only.**
|
|
33
|
+
`@deepseek-ai/dsh-api-remotes/lib/client.js` widens the client telemetry event
|
|
34
|
+
schema (`is_new_session`, `agent_preset`, and the More-menu / agent-preset
|
|
35
|
+
switch events), data this plugin neither emits nor validates.
|
|
36
|
+
`@deepseek-ai/dsh-api-session-controller`'s
|
|
37
|
+
`lib/types/client/sessions/service.d.ts` changes a doc comment only.
|
|
38
|
+
`@deepseek-ai/dsh-web-app/cordis.patch.yml` gains one hunk inserting the
|
|
39
|
+
`ui-entry-customization` bundle (the More menus named in the rc.3 release
|
|
40
|
+
notes); the patch anchor this plugin targets, `id: directory-picker`, is
|
|
41
|
+
byte-identical on both sides at the same offsets, and neither the new package
|
|
42
|
+
name nor `entry-customization` appears in this plugin's `cordis.patch.yml` or
|
|
43
|
+
`package.json`.
|
|
44
|
+
- **Activation verdict: the new release is admitted by both declarations, and the
|
|
45
|
+
earlier rc stays out.** rc.3, like rc.2, reads a declared `engines.dsh` alone,
|
|
46
|
+
so before the widening its refusal reported a **single** `engines.dsh`
|
|
47
|
+
requirement and `exempted: false` — no profile exemption file exists on this
|
|
48
|
+
machine — and a real rc.3 CLI reproduced it (`skipping profile bundle
|
|
49
|
+
"dsh-deeppilot"`) while the host itself still booted and served its web port.
|
|
50
|
+
Widening admits `0.2.1-rc.3` and nothing else: `0.2.1-rc.1` was never audited as
|
|
51
|
+
its own host, so it stays refused, as do `0.2.1-rc.3.1`, `0.2.1-rc.30`,
|
|
52
|
+
`0.2.1-RC.3`, `0.2.1`, `0.2.1-rc.2.1`, `0.2.0`, `0.3.0`, and `1.0.0`. Deleting
|
|
53
|
+
`engines.dsh` from a copy of the manifest falls back to the ten peers and admits
|
|
54
|
+
the same six hosts, so the short-circuit is unchanged.
|
|
55
|
+
- **Evidence: the published artifacts, the published evaluator, and a real rc.3
|
|
56
|
+
CLI run — all taken before any declaration changed.**
|
|
57
|
+
- **Change surface:** `.rc3-verify/CHANGE_SURFACE.md` and
|
|
58
|
+
`.rc3-verify/AUDIT.md`, with raw logs under `.rc3-verify/logs/`
|
|
59
|
+
(`master-table.txt`, `file-hash-compare.txt`, `diff-rq.all.txt`,
|
|
60
|
+
`patch-anchor-check.stdout.txt`), plus `tree-compare.out.json` (the
|
|
61
|
+
16-package whole-tree comparison), `export-symbol-diff.out.json` (274
|
|
62
|
+
modules, zero surface deltas), `pkg-manifest-delta.out.json` (585 paths, all
|
|
63
|
+
version or dependency-spec values) and `patch-anchor-check.out.json` (the one
|
|
64
|
+
patch-file change and its anchor).
|
|
65
|
+
- **Activation decision, reproduced against rc.3's own published evaluator
|
|
66
|
+
before any edit:** `.rc3-verify/evaluator-repro.out.json` shows the unchanged
|
|
67
|
+
manifest refused with one `engines.dsh` requirement and `exempted: false`, and
|
|
68
|
+
the worktree manifest admitted; `.rc3-verify/matrix.out.json` projects the
|
|
69
|
+
widening over 15 candidates — before accepted 5, after accepted 6, **newly
|
|
70
|
+
accepted exactly `0.2.1-rc.3`, newly rejected 0**.
|
|
71
|
+
- **Real CLI refusal and real CLI load.** The refusal was captured from the
|
|
72
|
+
installed rc.3 CLI before the declaration changed; after the widening the same
|
|
73
|
+
CLI composes the plugin (`--dump-config`, exit 0, no skip line).
|
|
74
|
+
- **Positive load verified this time.** An isolated `0.2.1-rc.3` host — its own
|
|
75
|
+
`DSH_HOME` in a one-off scratch directory (since deleted), the plugin linked
|
|
76
|
+
from this working tree, and no other plugin — composed the plugin into the
|
|
77
|
+
tree, started it, and answered `https://127.0.0.1:3098/phone/health` with `200`:
|
|
78
|
+
`{"ok":true,"enabled":true,"protocolVersion":2,"serverVersion":"0.9.10","dataPlane":true}`
|
|
79
|
+
while the isolated home gained `deeppilot/host-id` and `deeppilot/lan-tls/`.
|
|
80
|
+
Evidence: `.rc3-verify/HOST-BOOT.md` (written after the audit directory was
|
|
81
|
+
handed over) with the raw log and probe output beside it.
|
|
82
|
+
- **Check set run (nothing published).** `npm test` (609 pass, 0 fail),
|
|
83
|
+
`typecheck`, `build` (committed `lib/` unchanged), `check:config-schema`, and
|
|
84
|
+
`smoke:helper` (darwin-arm64). One environment note carries forward: the
|
|
85
|
+
default npm cache on this machine holds root-owned files, so the
|
|
86
|
+
`check:config-schema` script's `npx` invocation fails with `EPERM` until
|
|
87
|
+
`npm_config_cache` points at a writable directory; with that variable set the
|
|
88
|
+
check passes. No `npm ci`, no commit, no push, no tag, and no npm publish: the
|
|
89
|
+
release is prepared but not shipped.
|
|
90
|
+
- **Not covered / limits.** No real iPhone run, no Funnel end-to-end, no
|
|
91
|
+
model-backed turn against this host. `npm ci` and the helper-matrix rebuild
|
|
92
|
+
steps were skipped because no helper, dependency, or source input changed; CI
|
|
93
|
+
rebuilds the matrix and fails on any `bin/` drift. The widening is a metadata
|
|
94
|
+
and documentation change only.
|
|
95
|
+
|
|
96
|
+
### Previous decision — `dsh-v0.2.1-rc.2`
|
|
7
97
|
|
|
8
98
|
- **Audited release:** `dsh-v0.2.1-rc.2`, published 2026-10-17T08:36:31.655Z. It is
|
|
9
99
|
**not** `latest`: `latest` still points at `0.2.0-rc.2`, and `alpha` still points
|
|
@@ -115,6 +205,33 @@
|
|
|
115
205
|
`200` and `serverVersion: "0.9.8"`; the GitHub Release was made public only after
|
|
116
206
|
that install verification. The same release shipped the mobile skills, host
|
|
117
207
|
commands, and catalog-cache work recorded below.
|
|
208
|
+
- **Published as 0.9.9 on 2026-10-21.** The annotated tag `v0.9.9` dereferences to
|
|
209
|
+
`feee5c5854cd598af7b7827c53ddffdec3199573` on `main`, with CI and CodeQL green on
|
|
210
|
+
that commit. The DSH compatibility declaration did not change (the same five
|
|
211
|
+
audited hosts). The first CI run on the release commit failed in the helper job:
|
|
212
|
+
`govulncheck` reported GO-2026-6809 in Go 1.26.9's `crypto/x509`, reachable
|
|
213
|
+
through `http.Server.Serve`; the helper moved to Go 1.26.10 and the
|
|
214
|
+
`build-helpers` workflow refreshed all six binaries (PR #30, six `go1.26.10`
|
|
215
|
+
binaries, `bin/SHA256SUMS` 6/6) before the tag was cut. `publish.yml` ran on the
|
|
216
|
+
tag (run `39612245054`): the upload and provenance steps succeeded, but its last
|
|
217
|
+
step (registry verification) exhausted its 24 retries with `HTTP 404` — the
|
|
218
|
+
registry-visibility delay already seen in 0.9.5 and 0.9.6, not an upload failure.
|
|
219
|
+
Checked by hand instead: `npm view --prefer-online` gives `latest: 0.9.9` with a
|
|
220
|
+
`https://slsa.dev/provenance/v1` attestation whose `gitCommit` is that commit and
|
|
221
|
+
whose workflow ref is `refs/tags/v0.9.9`; the published tarball's SHA1
|
|
222
|
+
`bfea9ade6be9eb07f209e0e76f5ea20326dc0ddb` and its SHA512 match the registry and
|
|
223
|
+
the attestation subject; it holds 68 entries (the pre-publication pack count) and
|
|
224
|
+
every packaged file compared byte-identically with the verified tree. A clean
|
|
225
|
+
isolated `DSH_HOME` then installed `dsh-deeppilot@0.9.9` from npm on a real
|
|
226
|
+
`0.2.1-rc.2` host (`dsh web --no-open --port 0`) and `/phone/health` answered `200`
|
|
227
|
+
with `serverVersion: "0.9.9"`, `protocolVersion: 2` and the data plane active.
|
|
228
|
+
The first start attempt failed because DSH's own web server could not bind
|
|
229
|
+
`127.0.0.1:3080`, which another running DSH instance held; that is an environment
|
|
230
|
+
conflict, not a plugin fault, and the plugin's own listener had come up. The
|
|
231
|
+
GitHub Release was made public only after that install verification. The release
|
|
232
|
+
ships connection-failure diagnostics, the `failed` Live Activity phase, the
|
|
233
|
+
optional `toolName` / `detail` approval fields and `mutable-content`; it must run
|
|
234
|
+
against a Relay that already accepts them.
|
|
118
235
|
|
|
119
236
|
### Previous decision — `dsh-v0.2.1-alpha.5`
|
|
120
237
|
|
package/docs/NPM_PUBLISHING.md
CHANGED
|
@@ -117,6 +117,25 @@
|
|
|
117
117
|
3098 的 `/phone/health` 返回 200 且 `serverVersion` 为 `0.9.8`;GitHub Release
|
|
118
118
|
在这一步通过后才公开并标记 Latest。
|
|
119
119
|
|
|
120
|
+
9. `0.9.9` 的实际发布结果(2026-10-21):附注标签 `v0.9.9` 指向
|
|
121
|
+
`feee5c5854cd598af7b7827c53ddffdec3199573`,该提交的 CI 与 CodeQL 均为绿。发布
|
|
122
|
+
提交的首次 CI 曾因 helper 的 `govulncheck` 报 GO-2026-6809(Go 1.26.9 的
|
|
123
|
+
`crypto/x509`,调用链可达)而失败,处理方式是 helper 升到 Go 1.26.10,由
|
|
124
|
+
`build-helpers` 工作流重建六个二进制并合并刷新 PR(#30),之后才打标签。
|
|
125
|
+
`publish.yml` 在该标签上运行(运行号 `39612245054`):**上传与来源证明步骤成功,
|
|
126
|
+
但最后的核对步骤在 24 次重试后仍抛 `读取 npm 发布信息失败(HTTP 404)`,整次运行
|
|
127
|
+
结论为失败**——与 `0.9.5`、`0.9.6` 同一形态,说明 `0.9.7` 放宽的约 7 分钟窗口并非
|
|
128
|
+
总是足够,注册表元数据的可见性延迟仍会超出它。事后人工核验:
|
|
129
|
+
`npm view --prefer-online` 得到 `latest = 0.9.9`;来源证明类型为
|
|
130
|
+
`https://slsa.dev/provenance/v1`,`gitCommit` 正是该提交,工作流引用为
|
|
131
|
+
`refs/tags/v0.9.9`;压缩包 SHA1 `bfea9ade6be9eb07f209e0e76f5ea20326dc0ddb` 与 SHA512
|
|
132
|
+
同注册表和来源证明主体一致,共 68 个条目,包内每个文件与已验证的工作树逐字节相同。
|
|
133
|
+
随后在全新隔离 `DSH_HOME` 中从 npm 安装 `dsh-deeppilot@0.9.9`,在真实
|
|
134
|
+
`0.2.1-rc.2` 宿主上用 `dsh web --no-open --port 0` 启动,`/phone/health` 返回 200,
|
|
135
|
+
`serverVersion` 为 `0.9.9`;首次启动因另一个正在运行的 DSH 占用了宿主自己的 3080
|
|
136
|
+
端口而失败,属环境冲突,不是插件问题。GitHub Release 在这一步通过后才公开并标记
|
|
137
|
+
Latest。是否再放宽核对窗口,留待下次发布前决定,本次未改工作流。
|
|
138
|
+
|
|
120
139
|
## 五、官方资料
|
|
121
140
|
|
|
122
141
|
1. [npm 可信发布配置与限制](https://docs.npmjs.com/trusted-publishers/)
|
package/lib/index.d.ts
CHANGED
|
@@ -971,7 +971,11 @@ declare class HostBridge {
|
|
|
971
971
|
* push failures must never block or break the WS data plane.
|
|
972
972
|
*/
|
|
973
973
|
private fanOutPush;
|
|
974
|
-
/**
|
|
974
|
+
/**
|
|
975
|
+
* Remember the latest assistant text so notifications can quote it. 存完整原文:
|
|
976
|
+
* 按字符数截尾会从链接地址中间切开(横幅只剩 URL 编码的路径),段落选择与
|
|
977
|
+
* Markdown 清洗统一留到 emitNotify。条目随 sessions.list / 归档清理。
|
|
978
|
+
*/
|
|
975
979
|
private captureAssistantText;
|
|
976
980
|
/**
|
|
977
981
|
* Replay buffered pushes after the given cursor; false when the gap is
|
package/lib/index.js
CHANGED
|
@@ -5838,6 +5838,50 @@ function scheduleMutationCodec(persistValues) {
|
|
|
5838
5838
|
};
|
|
5839
5839
|
}
|
|
5840
5840
|
//#endregion
|
|
5841
|
+
//#region src/notification-text.ts
|
|
5842
|
+
/**
|
|
5843
|
+
* 通知正文的纯文本投影。
|
|
5844
|
+
*
|
|
5845
|
+
* 为什么需要:s2c.notify 与 APNs 的 body 是"可直接展示"的文本(PROTOCOL §6),
|
|
5846
|
+
* 客户端不得改写;而来源(助手回复、审批原因、提问)都是 Host 给的 Markdown。
|
|
5847
|
+
* 直接截原文会把链接地址、URL 编码的中文路径、代码块符号带进锁屏横幅,
|
|
5848
|
+
* 所以 Bridge 出站前在这里统一转成纯文本。
|
|
5849
|
+
*
|
|
5850
|
+
* 只做"去标记、留可读文字",不追求完整 Markdown 语义;任何无法识别的写法原样保留。
|
|
5851
|
+
*/
|
|
5852
|
+
/** 把 Markdown 拆成段落并逐段转为单行纯文本;清洗后为空的段落被丢弃。 */
|
|
5853
|
+
function notificationParagraphs(markdown) {
|
|
5854
|
+
return stripCodeFences(markdown.replace(/\r\n?/g, "\n")).split(/\n[ \t]*\n/).map(plainParagraph).filter((paragraph) => paragraph.length > 0);
|
|
5855
|
+
}
|
|
5856
|
+
/**
|
|
5857
|
+
* 通知正文:`last` 取最后一个非空段落(任务完成 / 异常结束——回复结尾通常是结论),
|
|
5858
|
+
* `all` 把全部段落合成一行(审批原因、提问原文)。长度上限由调用方负责。
|
|
5859
|
+
*/
|
|
5860
|
+
function notificationPlainText(markdown, pick) {
|
|
5861
|
+
const paragraphs = notificationParagraphs(markdown);
|
|
5862
|
+
return pick === "last" ? paragraphs.at(-1) ?? "" : paragraphs.join(" ");
|
|
5863
|
+
}
|
|
5864
|
+
/** 围栏代码块整体丢弃:横幅里放不下代码,留一半反而更难读。未闭合的围栏丢到文末。 */
|
|
5865
|
+
function stripCodeFences(text) {
|
|
5866
|
+
return text.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?(?:^[ \t]*\1[ \t]*$|(?![\s\S]))/gm, "\n");
|
|
5867
|
+
}
|
|
5868
|
+
function plainParagraph(paragraph) {
|
|
5869
|
+
return decodePercentRuns(stripInline(paragraph.split("\n").filter((line) => !(line.includes("|") && line.includes("-") && /^[\s|:-]+$/.test(line))).filter((line) => !/^\s*([*_-])(\s*\1){2,}\s*$/.test(line)).map((line) => line.replace(/^\s*(>\s?)+/, "").replace(/^\s*#{1,6}\s+/, "").replace(/^\s*([-*+]|\d+[.)])\s+(\[[ xX]\]\s+)?/, "").replace(/^\s*\|(.*?)\|?\s*$/, (_row, cells) => cells.replace(/\s*\|\s*/g, " "))).join(" "))).replace(/\s+/g, " ").trim();
|
|
5870
|
+
}
|
|
5871
|
+
function stripInline(text) {
|
|
5872
|
+
return text.replace(/!\[[^\]]*\]\((?:[^()]|\([^()]*\))*\)/g, "").replace(/\[([^\]]+)\]\((?:[^()]|\([^()]*\))*\)/g, "$1").replace(/\[([^\]]+)\]\[[^\]]*\]/g, "$1").replace(/<((?:https?|mailto):[^>\s]+)>/g, "$1").replace(/<\/?[A-Za-z][^>]*>/g, "").replace(/(`+)([^`]+?)\1/g, "$2").replace(/(\*\*|__|~~)(?=\S)([\s\S]*?\S)\1/g, "$2").replace(/(^|[^\w*])\*(?=\S)([^*\n]*?\S)\*(?![\w*])/g, "$1$2").replace(/(^|[^\w])_(?=\S)([^_\n]*?\S)_(?!\w)/g, "$1$2");
|
|
5873
|
+
}
|
|
5874
|
+
/** 正文里残留的 %E6%8F%90 这类编码串解码成原字符;解不开(非法 UTF-8)就保持原样。 */
|
|
5875
|
+
function decodePercentRuns(text) {
|
|
5876
|
+
return text.replace(/(?:%[0-9A-Fa-f]{2})+/g, (run) => {
|
|
5877
|
+
try {
|
|
5878
|
+
return decodeURIComponent(run);
|
|
5879
|
+
} catch {
|
|
5880
|
+
return run;
|
|
5881
|
+
}
|
|
5882
|
+
});
|
|
5883
|
+
}
|
|
5884
|
+
//#endregion
|
|
5841
5885
|
//#region src/host-api.ts
|
|
5842
5886
|
/**
|
|
5843
5887
|
* Subagent sessions are host-internal workers of a parent conversation.
|
|
@@ -6020,8 +6064,10 @@ var HostBridge = class {
|
|
|
6020
6064
|
* PROTOCOL §6 + §7), then fan the same payload out to offline devices
|
|
6021
6065
|
* holding an APNs token. */
|
|
6022
6066
|
emitNotify(args) {
|
|
6023
|
-
|
|
6024
|
-
|
|
6067
|
+
const turnEnd = args.category === "turn.completed" || args.category === "session.error";
|
|
6068
|
+
if (turnEnd && this.subagentSessionIds.has(args.sessionId)) return;
|
|
6069
|
+
const plain = notificationPlainText(args.body, turnEnd ? "last" : "all") || (args.fallbackBody ?? "");
|
|
6070
|
+
const body = plain.length > 120 ? plain.slice(0, 119) + "…" : plain;
|
|
6025
6071
|
const approvalExtras = args.category === "approval.required" && args.toolName ? {
|
|
6026
6072
|
toolName: args.toolName.slice(0, 80),
|
|
6027
6073
|
...args.detail ? { detail: args.detail.slice(0, 600) } : {}
|
|
@@ -6049,12 +6095,12 @@ var HostBridge = class {
|
|
|
6049
6095
|
if (this.subagentSessionIds.has(sessionId)) return;
|
|
6050
6096
|
const row = this.summaries.get(sessionId);
|
|
6051
6097
|
const title = ok ? "任务完成" : "任务异常结束";
|
|
6052
|
-
const body = this.lastAssistantText.get(sessionId) ?? row?.title ?? "";
|
|
6053
6098
|
this.emitNotify({
|
|
6054
6099
|
sessionId,
|
|
6055
6100
|
category: ok ? "turn.completed" : "session.error",
|
|
6056
6101
|
title,
|
|
6057
|
-
body,
|
|
6102
|
+
body: this.lastAssistantText.get(sessionId) ?? "",
|
|
6103
|
+
fallbackBody: row?.title ?? "",
|
|
6058
6104
|
notificationId: "n-" + (this.cursor + 1)
|
|
6059
6105
|
});
|
|
6060
6106
|
}
|
|
@@ -6067,11 +6113,15 @@ var HostBridge = class {
|
|
|
6067
6113
|
this.pushOutlet?.fanOut(notification);
|
|
6068
6114
|
} catch {}
|
|
6069
6115
|
}
|
|
6070
|
-
/**
|
|
6116
|
+
/**
|
|
6117
|
+
* Remember the latest assistant text so notifications can quote it. 存完整原文:
|
|
6118
|
+
* 按字符数截尾会从链接地址中间切开(横幅只剩 URL 编码的路径),段落选择与
|
|
6119
|
+
* Markdown 清洗统一留到 emitNotify。条目随 sessions.list / 归档清理。
|
|
6120
|
+
*/
|
|
6071
6121
|
captureAssistantText(sessionId, event) {
|
|
6072
6122
|
if (event.type !== "assistant/message") return;
|
|
6073
6123
|
const text = messageText(event.data).trim();
|
|
6074
|
-
if (text.length > 0) this.lastAssistantText.set(sessionId, text
|
|
6124
|
+
if (text.length > 0) this.lastAssistantText.set(sessionId, text);
|
|
6075
6125
|
}
|
|
6076
6126
|
/**
|
|
6077
6127
|
* Replay buffered pushes after the given cursor; false when the gap is
|