Skip to content

DeepPilot 0.8.0

Choose a tag to compare

@Mars-Sea Mars-Sea released this 22 Sep 10:18
· 127 commits to main since this release

English

Minor release on the 0.8.x line. The bridge protocol stays at v2 with one
optional, capability-gated addition; paired devices keep working and do not
pair again.

What changed since v0.7.1

  • Device self-revocation (new optional frame). Deleting a paired instance
    in the app used to remove only local credentials, so the host kept the
    device's APNs / WidgetKit / Live Activity tokens and the phone stayed a
    permanent offline-push target forever — there was no way back. The new
    optional c2s.device.revoke frame, advertised as
    welcome.capabilities.deviceRevoke, is the single stop-gap: before deleting
    its local instance the app sends the frame, the bridge revokes the device
    (tokens deleted, a revokedAt tombstone written, the device's other active
    sockets dropped), acks s2c.ack { revoked: true }, and then closes the
    connection with 4401 + reason device revoked. The frame requires an
    authenticated connection but no scope (device lifecycle must not be blocked
    by a narrowed scope), refuses clientRole: "widget" short connections with
    E_FORBIDDEN, validates an optional deviceId against the authenticated
    device, and is idempotent — an already-revoked record acks {revoked:true}
    the same way. Clients that predate the frame are unaffected; they simply
    keep the old behavior until the app is updated.
  • Compatibility with the DSH 0.1.7 settings rewrite. 0.1.7 removed
    installSection, SettingsSectionHooks, and the client settingsScope
    service, persists section values in the plugin's own profile config entry,
    and refuses settings writes to fields the schema does not declare
    .volatile(). The plugin adapts across both generations: live() in
    src/config.ts feature-detects the volatile method and, on schemastery
    3.18.2, writes the same metadata through extra('volatile', true) — an
    unconditional .volatile() throws at import on 0.1.6 and kills activation.
    Exactly the fields the settings surface writes (enabled, local,
    remote, read-time debug) are volatile; devicesPath,
    historyBufferMax, and push keep their remount semantics. The browser
    half gained src/client/settings-scope.ts, which adapts the 0.1.7
    configForms controller to the older scope shape so the settings page and
    its stores stay host-agnostic.
  • Peer ranges widened to the 0.1.7-alpha line. The declared range is
    ^0.1.5-rc.1 || >=0.1.6-alpha.1 <0.2.0-0 || >=0.1.7-alpha.1 <0.2.0-0,
    because npm's prerelease rule only lets a prerelease satisfy a range whose
    comparators carry a prerelease on the same tuple, so each new line needs
    its own disjunct.
  • Plugin Manager presentation. The package now ships a plugin icon
    (icon.svg, relative and size-checked) and localized Plugin Manager
    metadata (locale/en.json, locale/zh.json), so the manager shows a real
    icon and a localized title/description instead of the package name.
  • New release check. npm run check:config-schema composes
    cordis.patch.yml through the pinned DSH 0.1.7-alpha.1 CLI
    (dsh --dump-config-schema) and asserts the plugin imports, the schema
    projects, and the volatile annotations land. It runs in CI on every push.

Validation

  • 299 unit tests
  • TypeScript typecheck and production build after npm ci, with committed
    lib/ regenerated
  • Config-schema projection against @deepseek-ai/dsh@0.1.7-alpha.1
  • Go helper tests and helper checksums (all six targets)
  • GitHub CI

Requirements and install

DSH 0.1.5-rc.1 or newer within the 0.1.x line, with a web profile;
Node.js 22+.

dsh plugin --profile web add dsh-deeppilot

Restart DSH after installing or updating.

Installing 0.8.0 on release day. pnpm 11 and newer enable a
minimumReleaseAge cooldown of 1440 minutes (1 day) by default, so a
floating dsh plugin ... add dsh-deeppilot keeps resolving 0.7.1 until
0.8.0 is a day old. To install it immediately, pin the version —
dsh plugin --profile web add dsh-deeppilot@0.8.0 — or lower/allow-list the
cooldown in the profile's pnpm-workspace.yaml (minimumReleaseAge: 0,
or a minimumReleaseAgeExclude entry for dsh-deeppilot@0.8.0).

Note — unbind protection needs the app update. The host side stops a
deleted phone from remaining an offline-push target as soon as the plugin is
updated, but the app must actually send c2s.device.revoke before deleting
an instance. A phone whose app predates the frame still pairs and works; it
simply keeps the old remove-only-local-credentials behavior until the
DeepPilot app is updated.


简体中文

0.8.x 产品线的 minor 版本。桥接协议仍为 v2,仅新增一个可选的、受能力位控制的
帧;已配对设备无需重新配对,继续可用。

自 v0.7.1 以来的变更

  • 设备自撤销(新增可选帧)。 过去在 App 里删除一个已配对实例只会删掉本地
    凭据:主机侧仍保留该设备的 APNs / WidgetKit / Live Activity token,手机会
    永远留在离线推送目标集合里,且没有任何补救手段。新增的可选
    c2s.device.revoke 帧(通过 welcome.capabilities.deviceRevoke 通告)是
    这条链路的唯一止血入口:App 删除本地实例前先发该帧,Bridge 吊销该设备
    (删除 token、写入 revokedAt 墓碑、关闭该设备的其它活跃连接),先回
    s2c.ack { revoked: true },再以 4401 + reason device revoked 关闭连接。
    该帧要求连接已通过 c2s.auth.prove 认证但不要求任何 scope(设备生命周期
    操作不能因 scope 被收窄而无法解绑),clientRole: "widget" 的短连接一律
    回 E_FORBIDDEN,可选的 deviceId 必须与已认证设备一致,且幂等:记录已被
    撤销时同样回 {revoked:true}。早于该帧的客户端行为不变,升级 App 之前只是
    维持旧的「仅删本地凭据」行为。
  • 兼容 DSH 0.1.7 的设置系统重写。 0.1.7 移除了 installSection、
    SettingsSectionHooks 与客户端 settingsScope 服务,section 值改为持久化
    在插件自己的 profile config 条目里,并且拒绝写入 schema 未声明
    .volatile() 的字段。插件同时适配两代 Host:src/config.ts 的 live()
    对 volatile 方法做特性检测,在 schemastery 3.18.2 上通过
    extra('volatile', true) 写入同样的元数据 —— 无条件调用 .volatile() 在
    0.1.6 上导入即抛错,会直接中断插件激活。恰好设置界面会写的字段
    (enabled、local、remote,以及读取时的 debug)标记为 volatile;
    devicesPath、historyBufferMax、push 保持原有的重挂载语义。浏览器半边
    新增 src/client/settings-scope.ts,把 0.1.7 的 configForms 控制器适配成
    旧版 scope 形状,设置页及其 stores 因此与 Host 代际无关。
  • peer 范围放宽到 0.1.7-alpha 线。 声明的范围为
    ^0.1.5-rc.1 || >=0.1.6-alpha.1 <0.2.0-0 || >=0.1.7-alpha.1 <0.2.0-0:
    npm 的预发布规则只允许预发布版本满足「同一 major.minor.patch 元组上带预发布
    限定符」的范围,因此每条新的预发布线都需要自己的 disjunct。
  • Plugin Manager 展示。 包内新增插件图标(icon.svg,相对路径且有大小
    校验)与本地化的 Plugin Manager 元数据(locale/en.json、
    locale/zh.json),管理器将显示真实图标与本地化的标题/描述,而不是包名。
  • 新增发布检查。 npm run check:config-schema 通过固定的 DSH
    0.1.7-alpha.1 CLI(dsh --dump-config-schema)组合
    cordis.patch.yml,断言插件可导入、schema 可投影、volatile 注解到位;
    该检查已加入 CI。

验证

  • 299 个单元测试
  • 在 npm ci 之后执行 TypeScript 类型检查与生产构建,并重新生成提交的 lib/
  • 基于 @deepseek-ai/dsh@0.1.7-alpha.1 的 config-schema 投影校验
  • Go helper 测试与全部六个平台的 helper 校验和
  • GitHub CI

依赖要求与安装

需要 0.1.x 系列中 DSH 0.1.5-rc.1 或更新版本,并使用 web profile;
Node.js 22+。

dsh plugin --profile web add dsh-deeppilot

安装或更新后请重启 DSH。

发布当天安装 0.8.0。 pnpm 11 及更新版本默认启用 1440 分钟(1 天)的
minimumReleaseAge 冷却,因此浮动版本的
dsh plugin ... add dsh-deeppilot 在 0.8.0 满一天前会继续解析到
0.7.1。如需立即安装,请固定版本 ——
dsh plugin --profile web add dsh-deeppilot@0.8.0 —— 或在 profile 的
pnpm-workspace.yaml 中降低/白名单该冷却(minimumReleaseAge: 0,或
添加 dsh-deeppilot@0.8.0 的 minimumReleaseAgeExclude 条目)。

注意 —— 解除绑定保护需要 App 更新。 主机侧在插件更新后即可阻止被删除的
手机继续成为离线推送目标,但 App 必须先发送 c2s.device.revoke 再删除实例。
App 版本早于该帧的手机仍可正常配对与使用,只是会维持旧的「仅删本地凭据」
行为,直到 DeepPilot App 完成更新。