dsh-deeppilot 0.8.3 → 0.9.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.
- package/COMPATIBILITY.md +48 -4
- package/README.md +6 -6
- package/README.zh-CN.md +6 -6
- package/docs/DSH_RELEASE_MEMORY.md +177 -1
- package/lib/index.js +26 -5
- package/lib/index.js.map +1 -1
- package/package.json +17 -16
package/COMPATIBILITY.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Compatibility
|
|
2
2
|
|
|
3
|
-
This branch targets **DSH 0.
|
|
3
|
+
This branch targets **DSH 0.2.0-rc.1**. The DSH peer dependencies and the development packages are pinned to that exact release. Earlier DSH builds and later release candidates are outside this branch's support scope.
|
|
4
4
|
|
|
5
5
|
| Component | Current contract | Evidence |
|
|
6
6
|
|---|---|---|
|
|
7
7
|
| Node.js | 22 or newer | Package engine and CI |
|
|
8
|
-
| DSH CLI and Host API | `0.
|
|
8
|
+
| DSH CLI and Host API | `0.2.0-rc.1` | Peer metadata, source typecheck, unit tests, bundle build, and config schema projection against a real 0.2.0-rc.1 CLI |
|
|
9
9
|
| iOS bridge | DeepPilot protocol v2 | Bridge protocol tests; device behavior must be checked with the running Host and app |
|
|
10
10
|
| Remote access | Tailscale Funnel on ports 443, 8443, or 10000 | Helper and supervisor tests |
|
|
11
11
|
|
|
@@ -24,9 +24,53 @@ This branch targets **DSH 0.1.7-rc.2**. The DSH peer dependencies and the develo
|
|
|
24
24
|
- The plugin's persisted device and Funnel state migration remains separate from DSH API version support. Session logs written by earlier DSH builds are readable only when the current Host's own history reader accepts them; this plugin does not rewrite those logs.
|
|
25
25
|
- An unavailable optional OS facility, transport, or controller disables its dependent capability without crashing the Host.
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Schedules require an optional DSH bundle
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
DSH 0.2.0 moved automation out of the shipped Web composition. The shipped
|
|
30
|
+
`packages/bundle/web-app/cordis.patch.yml` no longer carries the `time-context`,
|
|
31
|
+
`schedule`, or `ui-schedule` rows; they are supplied by the optional
|
|
32
|
+
`@deepseek-ai/dsh-experimental-schedule-bundle`, which ships switched off and is
|
|
33
|
+
enabled by the user through **Automation tasks** in the plugin manager.
|
|
34
|
+
|
|
35
|
+
The plugin needs no change for this. It still resolves the service through
|
|
36
|
+
`ctx.get('schedule')`, never declares `schedule` in `inject`, and reports
|
|
37
|
+
`welcome.capabilities.schedules = false` with a stable `E_UNSUPPORTED` for every
|
|
38
|
+
schedule frame when the service is absent. What changes is that a stock 0.2.0
|
|
39
|
+
Host now always takes that degraded path, so the phone tells the user to enable
|
|
40
|
+
Automation tasks instead of reporting a generic capability gap.
|
|
41
|
+
|
|
42
|
+
The capability is resolved lazily rather than captured when the bridge is
|
|
43
|
+
built. The bridge mounts on `sessionController` / `connection` /
|
|
44
|
+
`typertGateway`, all of which become ready before the optional Schedule service
|
|
45
|
+
finishes its own initialization, so a probe taken at that moment would report
|
|
46
|
+
`false` for the bridge's whole lifetime. With the bundle enabled, a live
|
|
47
|
+
0.2.0-rc.1 host advertises `schedules=true` and the schedule
|
|
48
|
+
list/create/history/delete flow passes.
|
|
49
|
+
|
|
50
|
+
## 0.2.0-rc.1 audit outcome
|
|
51
|
+
|
|
52
|
+
The source-level audit of `dsh-v0.2.0-rc.1` against the previous baseline
|
|
53
|
+
`dsh-v0.1.7-rc.2` found no breaking change in the DSH service surfaces the
|
|
54
|
+
plugin calls. Of the 78 service-surface files compared, 75 are byte-identical
|
|
55
|
+
and the three that changed are additive: `fork()` gained an optional
|
|
56
|
+
`onCreated` callback, and a `run()` helper call gained an internal `'hidden'`
|
|
57
|
+
argument. The `api/gateway` package, including the `wireStream.open` argument
|
|
58
|
+
order, is unchanged, as are the Typert protocol exports, `configForms`, and
|
|
59
|
+
every `schedule` source file.
|
|
60
|
+
|
|
61
|
+
The exact 0.2.0-rc.1 package pins, the regenerated registry lockfile (228
|
|
62
|
+
packages, all carrying `resolved` and `integrity`), the compatibility
|
|
63
|
+
assertions, generated output, unit tests, typecheck, build, Go helper tests,
|
|
64
|
+
helper checksums, and a config-schema check against a real 0.2.0-rc.1 CLI all
|
|
65
|
+
pass locally. A real 0.2.0-rc.1 `web` profile smoke test also passes: 25 checks,
|
|
66
|
+
0 failures, driven by `scripts/smoke-live.mts` in the source repository (it is
|
|
67
|
+
a maintainer tool and is not part of the published package) against a booted
|
|
68
|
+
profile. Approval and question round trips are the one gap —
|
|
69
|
+
the stock profile auto-approves tool calls, so those paths need a profile with
|
|
70
|
+
a restrictive tool policy. The planned phone additions for durable schedules
|
|
71
|
+
and session forking are specified in
|
|
72
|
+
[`docs/DEEPPILOT_FEATURE_PLAN.md`](./docs/DEEPPILOT_FEATURE_PLAN.md); they are
|
|
73
|
+
not advertised until the protocol, iOS mirror, and integration tests land.
|
|
30
74
|
|
|
31
75
|
The complete audit evidence and re-audit procedure remain in [`docs/DSH_RELEASE_MEMORY.md`](./docs/DSH_RELEASE_MEMORY.md).
|
|
32
76
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
The open-source DSH companion plugin for **DeepPilot**, a native iPhone client
|
|
11
11
|
for using DeepSeek Harness remotely. It connects the app directly to the DSH
|
|
12
|
-
Host on your own
|
|
12
|
+
Host on your own computer and does not replace or modify the DSH Web UI.
|
|
13
13
|
|
|
14
14
|
> DeepPilot is currently in TestFlight review. The invitation link will accept
|
|
15
15
|
> testers after Apple approves the build.
|
|
@@ -32,12 +32,12 @@ Host on your own Mac 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 **DSH 0.
|
|
35
|
+
This source checkout targets Node.js 22+ and **DSH 0.2.0-rc.1** with a `web` profile. The package includes
|
|
36
36
|
Funnel helpers for macOS, Linux, and Windows on amd64/arm64; trusted-LAN mode
|
|
37
37
|
does not require the helper.
|
|
38
38
|
|
|
39
39
|
The current working tree pins its DSH packages and compatibility checks to
|
|
40
|
-
`0.
|
|
40
|
+
`0.2.0-rc.1`. A previously published plugin package may still carry its own
|
|
41
41
|
older compatibility declaration until a release is made from this tree.
|
|
42
42
|
|
|
43
43
|
```sh
|
|
@@ -80,12 +80,12 @@ DeepPilot state under `$DSH_HOME/deeppilot/`.
|
|
|
80
80
|
|
|
81
81
|
## Publishing (maintainers)
|
|
82
82
|
|
|
83
|
-
Release from this branch only after validating against DSH `0.
|
|
83
|
+
Release from this branch only after validating against DSH `0.2.0-rc.1`:
|
|
84
84
|
|
|
85
85
|
1. Bump `version` in `package.json` and in the root `""` entry of
|
|
86
86
|
`package-lock.json`, then run `npm test && npm run typecheck && npm run build`
|
|
87
87
|
and inspect `npm pack --dry-run --json`. The compatibility metadata test
|
|
88
|
-
enforces the exact
|
|
88
|
+
enforces the exact audited peer and development dependency versions.
|
|
89
89
|
2. Commit the release and push it. `npm publish` runs `prepack` (build) and
|
|
90
90
|
`prepublishOnly` (test + typecheck) automatically.
|
|
91
91
|
3. Publish pre-releases without touching `latest`:
|
|
@@ -95,7 +95,7 @@ Release from this branch only after validating against DSH `0.1.7-rc.2`:
|
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
After a successful publish, verify the dist tag and install the package in
|
|
98
|
-
a DSH `0.
|
|
98
|
+
a DSH `0.2.0-rc.1` profile before pointing users at it.
|
|
99
99
|
4. Tag the release commit `vX.Y.Z` and prepare a GitHub Release
|
|
100
100
|
(English + 简体中文 notes) that links this README section.
|
|
101
101
|
5. Publish stable releases with `npm publish --tag latest`, which moves
|
package/README.zh-CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
|
|
10
10
|
**DeepPilot** 的开源 DSH 配套插件。DeepPilot 是一款原生 iPhone 客户端,
|
|
11
|
-
可远程使用 DeepSeek Harness;插件让 App
|
|
11
|
+
可远程使用 DeepSeek Harness;插件让 App 直接连接用户自己电脑上的 DSH Host,
|
|
12
12
|
不会替换或修改 DSH Web UI。
|
|
13
13
|
|
|
14
14
|
> DeepPilot 目前正在等待 TestFlight 审核。Apple 审核通过后,邀请链接即可加入测试。
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
|
|
31
31
|
## 从 npm 安装
|
|
32
32
|
|
|
33
|
-
当前源码仅面向 Node.js 22+ 与带 `web` profile 的 **DSH 0.
|
|
33
|
+
当前源码仅面向 Node.js 22+ 与带 `web` profile 的 **DSH 0.2.0-rc.1**。npm 包内置 macOS、Linux、Windows
|
|
34
34
|
的 amd64/arm64 Funnel helper;可信局域网模式不依赖 helper。
|
|
35
35
|
|
|
36
|
-
当前工作树的 DSH 包和兼容性检查均固定为 `0.
|
|
36
|
+
当前工作树的 DSH 包和兼容性检查均固定为 `0.2.0-rc.1`。从此工作树发布新版本前,
|
|
37
37
|
已发布的旧插件包仍可能带有各自的旧兼容声明。
|
|
38
38
|
|
|
39
39
|
```sh
|
|
@@ -68,12 +68,12 @@ dsh plugin --profile web remove dsh-deeppilot
|
|
|
68
68
|
|
|
69
69
|
## 发布说明(维护者)
|
|
70
70
|
|
|
71
|
-
此分支仅在 DSH `0.
|
|
71
|
+
此分支仅在 DSH `0.2.0-rc.1` 下完成验证后发布:
|
|
72
72
|
|
|
73
73
|
1. 同步修改 `package.json` 与 `package-lock.json` 根 `""` 条目中的
|
|
74
74
|
`version`,然后运行 `npm test && npm run typecheck && npm run build`,
|
|
75
75
|
并检查 `npm pack --dry-run --json`。兼容性元数据测试会校验 peer 与开发依赖
|
|
76
|
-
|
|
76
|
+
均固定为当前审计基线。
|
|
77
77
|
2. 提交发布并推送。`npm publish` 会自动执行 `prepack`(构建)与
|
|
78
78
|
`prepublishOnly`(测试 + 类型检查)。
|
|
79
79
|
3. 发布预发布版本,不要动 `latest`:
|
|
@@ -82,7 +82,7 @@ dsh plugin --profile web remove dsh-deeppilot
|
|
|
82
82
|
npm publish --tag alpha
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
发布成功后检查 dist tag,并在 DSH `0.
|
|
85
|
+
发布成功后检查 dist tag,并在 DSH `0.2.0-rc.1` profile 中安装验证发布的包。
|
|
86
86
|
4. 为发布提交打 `vX.Y.Z` tag,并准备包含英文与简体中文说明的
|
|
87
87
|
GitHub Release,链接本 README 的发布说明。
|
|
88
88
|
5. 稳定版用 `npm publish --tag latest` 发布,使 `latest` 切换到新版本。
|
|
@@ -5,8 +5,176 @@
|
|
|
5
5
|
|
|
6
6
|
## Current decision
|
|
7
7
|
|
|
8
|
+
- **Audited release:** `dsh-v0.2.0-rc.1` (published 2026-09-28; official release
|
|
9
|
+
page: <https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.2.0-rc.1>).
|
|
10
|
+
- **Comparison baseline:** `dsh-v0.1.7-rc.2` (the previous plugin baseline).
|
|
11
|
+
- **Plugin runtime verdict:** **no breaking change in the DSH APIs that DeepPilot
|
|
12
|
+
currently calls**. 75 of 78 compared service-surface files are byte-identical;
|
|
13
|
+
the three that changed are additive.
|
|
14
|
+
- **Install/deployment verdict:** the exact peer/dev pins, the registry lockfile
|
|
15
|
+
(228 packages, all carrying `resolved` and `integrity`), the compatibility
|
|
16
|
+
assertions, generated `lib/`, 303 unit tests, typecheck, build, Go helper
|
|
17
|
+
tests, helper checksums, and a config-schema check against a **real
|
|
18
|
+
`0.2.0-rc.1` CLI** all pass locally. A real `0.2.0-rc.1` `web` profile smoke
|
|
19
|
+
test now also passes — 25 checks, 0 failures — via
|
|
20
|
+
`scripts/smoke-live.mts`. Two behaviours remain unverified there and are
|
|
21
|
+
listed under the 2026-09-29 findings: approval/question round trips (the
|
|
22
|
+
stock profile auto-approves tools) and the immediate consistency of the
|
|
23
|
+
archived list.
|
|
24
|
+
- **Protocol verdict:** no required DeepPilot phone-protocol break. Protocol v2,
|
|
25
|
+
pairing state, and device records are unchanged; already-paired phones need no
|
|
26
|
+
action.
|
|
27
|
+
- **One behavioural change:** DSH 0.2.0 moved automation out of the shipped Web
|
|
28
|
+
composition. See "Automation is now an optional bundle" below. The plugin needs
|
|
29
|
+
no code change; the phone's copy now points at the bundle.
|
|
30
|
+
|
|
31
|
+
## 2026-09-28 — audit of `dsh-v0.2.0-rc.1`
|
|
32
|
+
|
|
33
|
+
### Scope and method
|
|
34
|
+
|
|
35
|
+
Compared `dsh-v0.1.7-rc.2...dsh-v0.2.0-rc.1` (261 commits, 1109 files). Rather
|
|
36
|
+
than read release notes, every DSH package the plugin actually imports was
|
|
37
|
+
compared file by file: `api/session-controller` (34 files),
|
|
38
|
+
`api/workspace-controller` (10), `schedule/schedule` (10), `api/gateway` (11),
|
|
39
|
+
and `typert/protocol` + `settings/settings` (13). Release notes were treated as
|
|
40
|
+
a hint, never as evidence.
|
|
41
|
+
|
|
42
|
+
### Findings by risk class
|
|
43
|
+
|
|
44
|
+
| Area | Finding | DeepPilot impact |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| Install | All ten peer and five dev packages publish `0.2.0-rc.1` on npm. `cordis` stays `4.0.4`, `schemastery` stays `3.18.4`, Node `engines` and pnpm `11.7.0` are unchanged. The lockfile had to be regenerated from the registry: the old one still pinned `0.1.7-rc.2` and made both `npm ci` and `npm install` fail with ERESOLVE. | Resolved. `npm ci`, typecheck, build, and the real-CLI config-schema check all pass. |
|
|
47
|
+
| Session / Workspace controllers | `client/contract/sessions.ts` and `client/sessions/service.ts` changed only to add an **optional** `onCreated?: (childId: SessionId) => void` to `fork()`. `workspace-controller/src/default-directory.ts` changed only to pass an extra internal `'hidden'` argument to its own `run()` helper. | Additive. The plugin's hand-written `SessionControllerLike` / `WorkspaceControllerLike` mirrors still match. |
|
|
48
|
+
| Schedule service | **All ten `schedule/schedule/src` files are byte-identical to rc.2.** The change is packaging, not API: see below. | The existing facade needs no change. |
|
|
49
|
+
| Gateway / Remote Events | **All eleven `api/gateway/src` files are byte-identical**, including `stream-protocol.ts` and `stream-server.ts`. `typertGateway.wireStream.open(endpoint, payload, uplink, peer, signal)` keeps its argument order — the order DSH changed once in 0.1.7. | The highest-risk integration seam is unchanged. Approval and question delivery re-run clean on the new baseline. |
|
|
50
|
+
| Typert / settings | `typert/protocol` and `settings/settings` sources are byte-identical, so `TypertRemoteService`, `InvocationDescriptor`, `TypertCodec`, `TypertRemoteContribution`, `TypertSchema`, and `configForms.get` are all unaffected. | No change. |
|
|
51
|
+
| Phone protocol | No DSH-facing wire change. Protocol v2, `schedule.manage` scope, and the mutation journal are untouched. | Paired phones keep working. |
|
|
52
|
+
|
|
53
|
+
### Automation is now an optional bundle
|
|
54
|
+
|
|
55
|
+
The shipped `packages/bundle/web-app/cordis.patch.yml` in rc.2 carried
|
|
56
|
+
`time-context`, `schedule`, and `ui-schedule` at lines 118–126 and 370–371. In
|
|
57
|
+
0.2.0-rc.1 that file contains no schedule rows at all. Those three rows are now
|
|
58
|
+
inserted by `packages/experimental/schedule-bundle`
|
|
59
|
+
(`@deepseek-ai/dsh-experimental-schedule-bundle`), which `OPTIONAL_BUNDLES` in
|
|
60
|
+
`packages/boot/app-boot/src/profile.ts` ships **switched off**; the user enables
|
|
61
|
+
it as **Automation tasks** in the plugin manager.
|
|
62
|
+
|
|
63
|
+
This is the only substantive product change in the release. The plugin's
|
|
64
|
+
existing design is already correct: it resolves the service via
|
|
65
|
+
`ctx.get('schedule')`, never puts `schedule` in `inject`, and degrades to a
|
|
66
|
+
stable `E_UNSUPPORTED` with `welcome.capabilities.schedules = false`. What
|
|
67
|
+
changed is that a stock host now always takes that degraded path, so the iOS
|
|
68
|
+
copy for the two schedule errors now names the bundle instead of reporting a
|
|
69
|
+
generic capability gap. `PROTOCOL.md` records that the capability bit reflects
|
|
70
|
+
actual mounting, not the host version.
|
|
71
|
+
|
|
72
|
+
### Re-audit procedure used
|
|
73
|
+
|
|
74
|
+
To redo this comparison: `git clone --filter=blob:none --no-checkout
|
|
75
|
+
https://github.com/deepseek-ai/deepseek-harness.git`, fetch both tags, list each
|
|
76
|
+
package's `src/**/*.ts` from `git/trees/<sha>?recursive=1` at both commits, and
|
|
77
|
+
diff the two file sets file by file. Avoid `git grep` on a blob-filtered clone —
|
|
78
|
+
it re-fetches blobs and times out. Record which files are byte-identical, not
|
|
79
|
+
merely which packages still exist.
|
|
80
|
+
|
|
81
|
+
## 2026-09-29 — live smoke test on a real `web` profile (0.2.0-rc.1)
|
|
82
|
+
|
|
83
|
+
### How it was run
|
|
84
|
+
|
|
85
|
+
`scripts/smoke-live.mts` drives the phone protocol against a real
|
|
86
|
+
`dsh --profile <name> web` host that has this working copy linked in. It
|
|
87
|
+
asserts the seams unit tests fake out: the LAN TLS listener, the
|
|
88
|
+
challenge/prove handshake, and every Host RPC the bridge forwards through
|
|
89
|
+
`ctx.apiProxy`. It is repeatable, so the next DSH release can re-run it instead
|
|
90
|
+
of trusting a source diff.
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
npx tsx scripts/smoke-live.mts register # pre-authorize a device, then restart the host
|
|
94
|
+
npx tsx scripts/smoke-live.mts run [--prompt] [--interactions]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The pairing-code happy path is intentionally not driven: the code only exists
|
|
98
|
+
inside the host process and can only be minted through the plugin's own
|
|
99
|
+
`deeppilot/beginPairing` Host RPC, i.e. from a DSH client session. The script
|
|
100
|
+
asserts instead that `/phone/pair` is mounted and refuses a bogus code, and
|
|
101
|
+
covers the real challenge/prove handshake with a pre-authorized device.
|
|
102
|
+
|
|
103
|
+
### Result: 25 checks pass, 0 fail
|
|
104
|
+
|
|
105
|
+
Verified on a real 0.2.0-rc.1 `web` profile: `/phone/health`, the WSS upgrade,
|
|
106
|
+
challenge/prove → welcome with all six scopes, session list/create/open/tail,
|
|
107
|
+
history paging, the model catalog and a live model switch, workspace
|
|
108
|
+
list/create, archive → archived list → unarchive, the pending approval/question
|
|
109
|
+
snapshot, a real model turn (`clientSendId` receipt `accepted`,
|
|
110
|
+
`message.final` + `turn.end` observed), disconnect/reconnect replay
|
|
111
|
+
(`resumed=true`, `s2c.resume.done` received), and — with the Automation tasks
|
|
112
|
+
bundle mounted — the schedule list/create/history/delete flow.
|
|
113
|
+
|
|
114
|
+
The TLS pin check is worth keeping: the bridge pins the **SPKI** digest
|
|
115
|
+
(`src/lan-tls.ts:35`), not the certificate DER, and the script's independently
|
|
116
|
+
computed pin matched the one the plugin logged on a live host.
|
|
117
|
+
|
|
118
|
+
### Finding 1 — `--patch` does not install the plugin
|
|
119
|
+
|
|
120
|
+
Composing the plugin through `dsh --profile X --patch ./cordis.patch.yml`
|
|
121
|
+
leaves the profile with `deeppilot: failed to import` and no reason logged.
|
|
122
|
+
`dsh-app-boot/lib/index.js:3904` shows why: a bare specifier in a patch layer is
|
|
123
|
+
never resolved into a package, so the loader never creates a fiber for it. The
|
|
124
|
+
plugin only mounts after `dsh plugin --profile X add dsh-deeppilot@link:<path>`.
|
|
125
|
+
The install docs should say so; the silent failure looks exactly like a broken
|
|
126
|
+
plugin.
|
|
127
|
+
|
|
128
|
+
### Finding 2 — `capabilities.schedules` stayed false even with the bundle enabled (fixed)
|
|
129
|
+
|
|
130
|
+
The optimistic reading of "Automation is now an optional bundle" above did not
|
|
131
|
+
hold on a real host. With
|
|
132
|
+
`@deepseek-ai/dsh-experimental-schedule-bundle` **installed and mounted** — the
|
|
133
|
+
bundle's three rows (`time-context`, `schedule`, `ui-schedule`) do reach the
|
|
134
|
+
composed profile, and `ScheduleService` still exposes
|
|
135
|
+
`create/list/catalog/history/delete/update` — welcome advertised
|
|
136
|
+
`schedules=false` and every `c2s.schedule.*` request took the `E_UNSUPPORTED`
|
|
137
|
+
path.
|
|
138
|
+
|
|
139
|
+
Root cause: the bridge is constructed from a `ctx.inject` on
|
|
140
|
+
`sessionController` / `connection` / `typertGateway` (`src/index.ts:1212`), and
|
|
141
|
+
`schedule` is deliberately **not** in that list. `DshApiProxy` then resolved
|
|
142
|
+
`ctx.get('schedule')` once in its constructor and cached it in a `readonly`
|
|
143
|
+
field. On DSH 0.2.0 those three services become ready well before
|
|
144
|
+
`ScheduleService` finishes its own async init, so the cached value was
|
|
145
|
+
`undefined` for the bridge's entire lifetime. Reordering `dsh.profile.bundles`
|
|
146
|
+
to mount the schedule bundle first did not help, which is what ruled out a
|
|
147
|
+
pure composition-order cause.
|
|
148
|
+
|
|
149
|
+
Fix: resolve the optional service lazily on every read and keep it once found
|
|
150
|
+
(`src/dsh-api-proxy.ts`). `capabilities` is already a getter, so a device that
|
|
151
|
+
connects after the service is up now gets `schedules=true`, and the full
|
|
152
|
+
create/list/history/delete flow passes on a live host. Covered by
|
|
153
|
+
`tests/dsh-api-proxy.test.ts`.
|
|
154
|
+
|
|
155
|
+
A profile that has not enabled the bundle still reports `schedules=false` and
|
|
156
|
+
still degrades to `E_UNSUPPORTED` — that path is unchanged.
|
|
157
|
+
|
|
158
|
+
### Finding 3 — approvals are auto-approved on a default profile
|
|
159
|
+
|
|
160
|
+
`--interactions` produced a real `tool.start`/`tool.end` pair for a "create
|
|
161
|
+
this file" instruction but no `s2c.pending.approval`, so the stock profile
|
|
162
|
+
auto-approves and the approval round trip stays unverified. The question round
|
|
163
|
+
trip is also unverified: dispatching a second prompt into the same session
|
|
164
|
+
timed out on the delivery ack. Both need a profile with a restrictive tool
|
|
165
|
+
policy before they can be called verified.
|
|
166
|
+
|
|
167
|
+
### Finding 4 — the archived mirror is stale right after archiving
|
|
168
|
+
|
|
169
|
+
`archiveSession` updates `archivedSessionIds` but does not call
|
|
170
|
+
`refreshSummaries()`, so `c2s.sessions.archived` can omit the session that was
|
|
171
|
+
just archived until an unrelated event triggers a refresh (it converged within
|
|
172
|
+
10 s in practice). Pre-existing behaviour, not a 0.2.0 regression, but the app
|
|
173
|
+
must not assume the archived list is immediately consistent.
|
|
174
|
+
|
|
175
|
+
## Previous decision — `dsh-v0.1.7-rc.2`
|
|
176
|
+
|
|
8
177
|
- **Audited release:** `dsh-v0.1.7-rc.2` (official release page: <https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.7-rc.2>).
|
|
9
|
-
- **Comparison baseline:** `dsh-v0.1.7-rc.1` (the previous plugin baseline).
|
|
10
178
|
- **Plugin runtime verdict:** **no confirmed breaking change in the DSH APIs
|
|
11
179
|
that DeepPilot currently calls**.
|
|
12
180
|
- **Install/deployment verdict:** the exact peer/dev pins and lockfile are now
|
|
@@ -48,6 +216,9 @@ Prioritized for DeepPilot, in this order:
|
|
|
48
216
|
or edit a task, delete it, and show delivery history. Keep all operations
|
|
49
217
|
behind `sessions.manage` plus a dedicated schedule scope; never log reminder
|
|
50
218
|
prompts. A reminder must remain bound to its original Host Session.
|
|
219
|
+
*(Implemented in 0.8.3. As of DSH 0.2.0 this capability is no longer
|
|
220
|
+
bundled by default — see "Automation is now an optional bundle" above, and
|
|
221
|
+
any real-host verification must enable Automation tasks first.)*
|
|
51
222
|
2. **Host Session search.** `sessionController.search(query)` returns bounded
|
|
52
223
|
snippets without activating an Agent. This maps naturally to a phone search
|
|
53
224
|
screen and can reduce the amount of history transferred over a mobile link.
|
|
@@ -73,6 +244,11 @@ they solve a mobile-specific need.
|
|
|
73
244
|
|
|
74
245
|
## Required rc.2 upgrade gate
|
|
75
246
|
|
|
247
|
+
> Superseded by the 2026-09-28 `0.2.0-rc.1` audit at the top of this file. The
|
|
248
|
+
> gate below still applies to that release with one change: a schedule smoke
|
|
249
|
+
> test additionally requires the user to enable the **Automation tasks** bundle,
|
|
250
|
+
> because a stock 0.2.0 Host does not mount the Schedule service.
|
|
251
|
+
|
|
76
252
|
Do not call the rc.2 baseline fully supported until all of these are true:
|
|
77
253
|
|
|
78
254
|
1. The exact DSH peer/dev pins and lockfile remain on `0.1.7-rc.2`.
|
package/lib/index.js
CHANGED
|
@@ -4142,27 +4142,48 @@ var DshApiProxy = class {
|
|
|
4142
4142
|
session;
|
|
4143
4143
|
workspaceController;
|
|
4144
4144
|
scheduleController;
|
|
4145
|
+
scheduleApi;
|
|
4145
4146
|
directoryPicker;
|
|
4146
4147
|
interactions = /* @__PURE__ */ new Map();
|
|
4147
4148
|
shouldSurfaceInteraction;
|
|
4148
|
-
scheduleApi;
|
|
4149
4149
|
constructor(ctx, options = {}) {
|
|
4150
4150
|
this.ctx = ctx;
|
|
4151
4151
|
const session = ctx.get("sessionController");
|
|
4152
4152
|
if (session === void 0) throw new Error("DSH sessionController is unavailable");
|
|
4153
4153
|
this.session = session;
|
|
4154
4154
|
this.workspaceController = ctx.get("workspaceController");
|
|
4155
|
-
this.scheduleController = ctx.get("schedule");
|
|
4156
4155
|
if (this.workspaceController === void 0) delete this.workspace?.unarchiveSession;
|
|
4157
4156
|
this.directoryPicker = ctx.get("directoryPickerController");
|
|
4158
4157
|
this.shouldSurfaceInteraction = options.shouldSurfaceInteraction ?? (() => true);
|
|
4159
|
-
this.
|
|
4158
|
+
this.resolveSchedule();
|
|
4159
|
+
}
|
|
4160
|
+
/**
|
|
4161
|
+
* Resolve the optional Schedule service lazily, on every read.
|
|
4162
|
+
*
|
|
4163
|
+
* The bridge is built from a `ctx.inject` on sessionController / connection
|
|
4164
|
+
* / typertGateway, and `schedule` is deliberately NOT in that list: it only
|
|
4165
|
+
* exists when the user enables the optional Automation tasks bundle. On a
|
|
4166
|
+
* DSH 0.2.0 host those three services become ready well before
|
|
4167
|
+
* ScheduleService finishes its own async init, so a value captured here in
|
|
4168
|
+
* the constructor stayed `undefined` for the bridge's whole lifetime and
|
|
4169
|
+
* welcome advertised `schedules=false` even with the bundle mounted.
|
|
4170
|
+
*
|
|
4171
|
+
* Once resolved the controller is kept: services are not torn down and
|
|
4172
|
+
* rebuilt underneath a live bridge, so re-resolving per call would be pure
|
|
4173
|
+
* overhead.
|
|
4174
|
+
*/
|
|
4175
|
+
resolveSchedule() {
|
|
4176
|
+
if (this.scheduleController !== void 0) return;
|
|
4177
|
+
const controller = this.ctx.get("schedule");
|
|
4178
|
+
if (controller === void 0) return;
|
|
4179
|
+
this.scheduleController = controller;
|
|
4180
|
+
this.scheduleApi = this.createScheduleApi(controller);
|
|
4160
4181
|
}
|
|
4161
4182
|
get schedule() {
|
|
4183
|
+
this.resolveSchedule();
|
|
4162
4184
|
return this.scheduleApi;
|
|
4163
4185
|
}
|
|
4164
|
-
createScheduleApi() {
|
|
4165
|
-
const controller = this.scheduleController;
|
|
4186
|
+
createScheduleApi(controller) {
|
|
4166
4187
|
return {
|
|
4167
4188
|
list: async (request) => this.call(async () => ({
|
|
4168
4189
|
sessionId: request.payload.sessionId,
|