dsh-github-copilot 0.4.0-alpha.19 → 0.4.0-alpha.21

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/AGENTS.md CHANGED
@@ -31,7 +31,7 @@ Use native DSH tools for goals, background jobs and scoped subagents. Use local
31
31
 
32
32
  `dsh-github-copilot` is a companion to official DSH `0.1.6-alpha.1`, DSH `0.1.5-rc.2`, DSH `0.1.5-rc.1`, DSH `0.1.5-alpha.2`, DSH `0.1.5-alpha.1`, DSH `0.1.3-alpha.1`, DSH `0.1.2-rc.1`, and the controlled DSH Desktop `0.1.1-rc.2` Core baseline. It does not own a general Copilot chat adapter. DSH's built-in `llm-pi-ai` mount owns the GitHub Copilot provider, catalog, OAuth method and grant format, token exchange, refresh, and normal model transport.
33
33
 
34
- This repository owns eight narrow surfaces:
34
+ This repository owns nine narrow surfaces:
35
35
 
36
36
  1. A conditional authorization-service bootstrap plus Host controller that joins DSH authorization, credentials, and settings.
37
37
  2. A Client Models provider-card contribution with one shared account-state owner and Client-safe Remote descriptors; embed in an existing configured canonical row, suppress its separate footer controller, and retain footer/old-Core section fallback when no such row is mounted.
@@ -41,6 +41,11 @@ This repository owns eight narrow surfaces:
41
41
  6. Provider-scoped tool-schema compatibility for Copilot payload behaviors; Core remains the tool and execution owner.
42
42
  7. A bounded account-discovery route that supplies validated endpoint/capability metadata to the published native adapter, without maintaining model-ID routing rules or changing Core's catalog.
43
43
  8. Optional, provider-scoped Chat presentation for completed empty reasoning disclosures; durable content and encrypted replay metadata remain Core-owned.
44
+ 9. Opt-in model-role settings and dedicated new planner/executor sessions, using public Agent/Session/subagent APIs without changing existing sessions, global defaults or native Subagent model-selection settings.
45
+
46
+ ## Dedicated model-role boundary (#127)
47
+
48
+ `src/dual-model-host.ts`, `dual-model-types.ts`, `dual-model-remote.ts`, `dual-model-card.ts` and `dual-model-ui.ts` own this optional flow; see `docs/dual-model.md`. The three role Remotes use a separate namespace and strict codecs; the eight existing authorization/migration descriptors retain their original contracts. Policy is captured once per explicitly created root and restored through a namespaced projection. Account discovery and the native adapter remain the only model/auth owners. Dedicated tool restrictions are workflow controls, not a sandbox against shell code. Missing public seams must disable only this feature, never require a Core patch. A failed recovery of an existing create is uncertain: keep its request UUID unless Host evidence explicitly establishes not-created. Do not use `session.selectModel` to initialize roles because it also changes the future global default; the creation seed uses the existing session-local event format. Ordinary user model-picker actions remain Core-owned.
44
49
 
45
50
  ## File map
46
51
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0-alpha.21 (prepared)
4
+
5
+ - Move Desktop-owned `@deepseek-ai/dsh-authorization` and `@deepseek-ai/schemastery` from private runtime dependencies to required compatible peers while retaining development copies for standalone build and test verification.
6
+ - Audit every declared dependency and peer against the hash-pinned actual Desktop 0.1.5 runtime descriptor and generated Desktop 0.1.6 package-set input.
7
+ - Make packed-tarball verification reject bundled, optional, incompatible, or newly unaudited shared-package ownership without weakening Desktop validation or changing Copilot lifecycle, image-offload, Models, or authorization behavior.
8
+
9
+ ## 0.4.0-alpha.20 (prepared)
10
+
11
+ - Add opt-in, bilingual **Model roles** settings with account-discovered planning and execution models, revision-checked save, and an explicit new-session entry.
12
+ - Capture the two roles only for dedicated new sessions; preserve existing conversations, global defaults, OAuth ownership and ordinary Subagent settings.
13
+ - Delegate implementation through native continuable executors with an exact route, scoped workflow controls, durable policy replay and explicit model-unavailable errors rather than fallback.
14
+ - Preserve create-request identity across uncertain results, and distinguish a confirmed not-created result from failed recovery of an existing session.
15
+ - Add real React DOM, actual Client Gateway, and Core Session/projection/tool primitive regressions, plus an isolated built-component browser fixture. These tests do not imply a live model call or production Desktop activation.
16
+
3
17
  ## 0.4.0-alpha.19
4
18
 
5
19
  - Adapt the plugin compatibility contract to DSH `0.1.6-alpha.1` at
package/README.md CHANGED
@@ -42,9 +42,13 @@ The bundle routes search through a plugin-owned Models-page policy: `auto` prefe
42
42
 
43
43
  The exact `dsh-v0.1.6-alpha.1` source fixture now awaits serialized `agent/created` initialization before reading live Session projections. Static and runtime gates also verify the retained request-header/projection path instead of adding synchronous history reads; MCP SDK v2 resource cursors; the `dsh-ptc-runtime` and `dsh-workflow-ptc` contracts; empty model environment for isolated Node PTC; asynchronous cancellable Sandbox/Shell preparation; consumer-owned optional-plugin startup failures; attachment request caches under DSH cache while normalized attachment paths remain stable; and provider-owned Team task pagination. For image-budget recovery, the adapter's first `IMAGE_OFFLOAD_REQUIRED` result remains an error; the fixture records the Core `image/offload` projection and proves the retried Copilot request sends the mapped read-only normalized path as placeholder text without image bytes. The plugin does not import or own MCP, PTC, Workflow, Sandbox, Shell, or Team services. Upstream exposes no generic `HostGrant`/`hostGrants` API in this tag, and the plugin registers no such coupling. Copilot schema compatibility continues to remove unsupported escalation controls from `pwsh`, filesystem, and `run_code` schemas while preserving Team pagination fields. This compatibility version is prepared as a Draft and is not a release claim.
44
44
 
45
+ ### Alpha.21 Desktop shared-package ownership fix (#125)
46
+
47
+ The candidate manifest treats `@deepseek-ai/dsh-authorization` and `@deepseek-ai/schemastery` as required Host peers instead of private runtime dependencies. Development copies remain pinned for standalone build, unit, Host import, Client loader, and Remote codec verification. The packed-tarball gate audits every declared dependency and peer against a hash-pinned actual Desktop 0.1.5 runtime descriptor and the generated Desktop 0.1.6 package-set input; it rejects bundled, optional, incompatible, or newly unaudited shared ownership. The 0.1.6 package-set is authoritative input to descriptor generation but is not a materialized Desktop descriptor, live activation, OAuth, or model-call result. This change preserves the existing Settings → Models provider card, authentication flow, lifecycle adaptation, and image-offload behavior, and does not weaken Desktop validation.
48
+
45
49
  ## Install and sign in
46
50
 
47
- The commands below target the package version `0.4.0-alpha.19`. Versioned URLs describe the intended release artifacts, not proof that publication or local activation has completed; use them only once that Release and its checksums are available. Install into the profile you use (replace `web` when targeting another profile):
51
+ The commands below target the package version `0.4.0-alpha.21`. Versioned URLs describe the intended release artifacts, not proof that publication or local activation has completed; use them only once that Release and its checksums are available. Install into the profile you use (replace `web` when targeting another profile):
48
52
 
49
53
  Before installing/updating, unpack the **checksum-verified** archive into a temporary directory and run its read-only composition preflight (replace all paths with absolute paths for the intended profile):
50
54
 
@@ -54,10 +58,14 @@ node package/scripts/check-search-composition.mjs --profile-dir /absolute/profil
54
58
 
55
59
  Include any launcher patch files with repeated `--patch /absolute/file` arguments. Require `supported: true`; otherwise do not install the routing bundle. The preflight rejects custom, disabled, nested or already-isolated web-service layouts and reserved routing collisions before any mutation. It parses through public Core APIs and never boots plugins, resolves credentials or rewrites configuration. **`dsh plugin add` does not automatically run this preflight.** It is a required installer/operator step, not a universal compatibility guarantee.
56
60
 
61
+ For approved online installation, the supported CLI command is:
62
+
57
63
  ```sh
58
- dsh plugin --profile web add https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/dsh-github-copilot-0.4.0-alpha.19.tgz
64
+ dsh plugin --profile web add https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/dsh-github-copilot-0.4.0-alpha.21.tgz
59
65
  ```
60
66
 
67
+ If registry access is blocked or unavailable, do not retry it through another network. Desktop-managed profiles may instead use the [controlled offline CLI procedure](./docs/npm-distribution.md#controlled-offline-cli-maintenance), with an approved, checksum-verified local Release and existing dependency cache (`--offline --ignore-scripts`). All preflight and approval requirements still apply.
68
+
61
69
  Then open the Models UI listed above, find **GitHub Copilot**, select **Sign in**, and complete the GitHub device-code flow. Plugin installation changes the selected profile; activation follows that profile's normal reload/restart policy.
62
70
 
63
71
  ### User authorization flow
@@ -118,7 +126,7 @@ Agents should treat the browser authorization as a human handoff, not as a token
118
126
  5. Confirm **Signed in** and inspect the automatic discovery result before asking the user to choose a model. Already-signed-in Models opening ensures missing/stale metadata automatically; fresh ready cache makes no request. Use visible **Retry** for errors or **Manage → Refresh models** for an intentional forced update, not routine setup. Status alone does not discover, and login, metadata and successful model calls remain separate evidence.
119
127
  6. Use **Sign out** only when the user explicitly asks to disconnect the account. It deletes the Copilot credential record but preserves route settings.
120
128
 
121
- GitHub Releases and npm are the default distribution channels for each new version, using the same verified tarball. Pin the version and verify the Release `SHA256SUMS` and npm `dist.integrity`; package preparation is not proof of publication. After npm publication is verified, the official Desktop package manager can use `dsh-github-copilot@0.4.0-alpha.19` rather than a URL or file. The required search-composition preflight below still applies before installation; do not use the CLI to modify a Desktop-managed profile. See [npm distribution and first-package prerequisites](./docs/npm-distribution.md).
129
+ GitHub Releases and npm are the default distribution channels for each new version, using the same verified tarball. Pin the version and verify the evidence for the channel used: Release `SHA256SUMS`, and npm `dist.integrity` when installing from npm. The native Desktop package manager is preferred when permitted registry access is available; after npm publication is verified it accepts `dsh-github-copilot@0.4.0-alpha.21`, not a URL or file. Desktop-managed profiles also support explicitly approved [controlled offline CLI maintenance](./docs/npm-distribution.md#controlled-offline-cli-maintenance) with a verified local Release and `--offline --ignore-scripts`. Follow the mandatory search-composition preflight, backup, single-writer and post-install checks; do not bypass a corporate registry ban, disable TLS verification or restart without separate approval. Offline installation is not proof that npm networking/publication was repaired. See [distribution and publication requirements](./docs/npm-distribution.md).
122
130
 
123
131
  No `copilot2api` process, external gateway, placeholder API key, pasted GitHub token, or separate `dsh-web-search-provider` installation is required.
124
132
 
@@ -133,6 +141,12 @@ No `copilot2api` process, external gateway, placeholder API key, pasted GitHub t
133
141
 
134
142
  DSH Core continues to own model selection, sandboxing, tools, attachments, and other providers. `@deepseek-ai/dsh-llm-pi-ai` owns the Copilot adapter, catalog, OAuth method and grant format, token exchange, refresh, and normal model transport. Credentials remain Host-only.
135
143
 
144
+ ## Optional planner / executor model roles
145
+
146
+ Under **Settings → Models → Model roles**, enable dedicated dual-model sessions, select two available account models, save, and choose **Create session with this configuration** for an existing workspace. The planner handles planning and acceptance; `copilot_execute` delegates implementation to a native continuable child with a fixed execution model. Configuration is off by default and affects only sessions created through this entry. It does not change the global default, existing sessions, credentials or the ordinary Subagent model-selection setting.
147
+
148
+ Unavailable models are not substituted. Uncertain creation retries keep the same request identity. The feature requires public role/session/subagent capabilities and is visibly unavailable when they are absent; historical package compatibility is not blanket certification of this optional flow. See [setup, lifecycle, limitations and evidence](./docs/dual-model.md). The feature is included in the `0.4.0-alpha.21` candidate; source and fixture tests are not proof of publication or Desktop activation.
149
+
136
150
  ## Shared account, independent sessions (V3)
137
151
 
138
152
  One Host-owned Copilot account supplies many account-discovered models. Each explicitly selected or history-backed Session keeps its own model context: search for Session A uses the captured effective request-header/config of initiating Session A (or explicit request `GenerateOptions`), not Session B's choice or a future global default C. Search plans are cached per owner so different-model A/B requests do not reuse or cancel each other's plans. Account metadata remains shared; capability/probe and credential checks still apply.
@@ -354,8 +368,8 @@ Report the published Release URL, version, tag/commit and verified asset SHA-256
354
368
  `package.json` declares public npm distribution. A release tag must equal `v${package.json.version}`. Versions use standard SemVer prerelease labels (`alpha`, `beta`, or `rc`), each with its matching npm dist-tag; only stable versions use `latest`. The Release workflow performs the frozen install and complete verification gate, packs once (or recovers the original archive on retry), verifies `SHA256SUMS`, publishes the immutable GitHub Release and then publishes those same bytes to npm through OIDC. Either channel failing means delivery is incomplete. First package creation needs an authorized maintainer; staging requires an existing package and is not a first-package bootstrap. Historical releases are not republished.
355
369
 
356
370
  ```sh
357
- curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/dsh-github-copilot-0.4.0-alpha.19.tgz
358
- curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/SHA256SUMS
371
+ curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/dsh-github-copilot-0.4.0-alpha.21.tgz
372
+ curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/SHA256SUMS
359
373
  sha256sum --check SHA256SUMS
360
374
  ```
361
375
 
@@ -363,7 +377,7 @@ PowerShell can verify the same two downloaded files with:
363
377
 
364
378
  ```powershell
365
379
  $expected = (Get-Content .\SHA256SUMS).Split()[0]
366
- $actual = (Get-FileHash .\dsh-github-copilot-0.4.0-alpha.19.tgz -Algorithm SHA256).Hash.ToLowerInvariant()
380
+ $actual = (Get-FileHash .\dsh-github-copilot-0.4.0-alpha.21.tgz -Algorithm SHA256).Hash.ToLowerInvariant()
367
381
  if ($actual -cne $expected) { throw 'Release checksum mismatch' }
368
382
  ```
369
383
 
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  一个聚焦 GitHub Copilot 登录、通用账号模型发现、Copilot 专用 Tool 兼容与供应方托管搜索的 DSH companion。插件根据供应方返回的端点和能力元数据组装模型,复用公开的 `@deepseek-ai/dsh-llm-pi-ai` adapter 与 pi-ai SDK,不另写一套通用传输/序列化器,也不维护需要逐个添加新模型 ID 的静态目录。
11
11
 
12
- > 下文自动维护账号模型元数据与 provider 集成控件描述目标版本 `0.4.0-alpha.19`;这不代表已有的两条真实路由被合并或移除。版本化 URL 不表示 Release 已发布或本机已加载;仅在该 Release 与校验和可用后使用安装命令。源码、发布制品、已安装版本和实际加载运行时需分别确认,本地升级和中断会话的重启仍需用户批准。
12
+ > 下文自动维护账号模型元数据与 provider 集成控件描述目标版本 `0.4.0-alpha.21`;这不代表已有的两条真实路由被合并或移除。版本化 URL 不表示 Release 已发布或本机已加载;仅在该 Release 与校验和可用后使用安装命令。源码、发布制品、已安装版本和实际加载运行时需分别确认,本地升级和中断会话的重启仍需用户批准。
13
13
 
14
14
  ## 已测试基线
15
15
 
@@ -44,6 +44,10 @@ bundle 通过插件自有的 Models 页策略分流搜索:`auto` 优先合格
44
44
 
45
45
  精确固定的 `dsh-v0.1.6-alpha.1` 源码 fixture 现在会等待串行 `agent/created` 初始化完成后,再读取 live Session projection。静态与运行时 gate 同时核对:继续通过 request-header/projection 取状态而不新增同步历史读取;MCP SDK v2 resource cursor;`dsh-ptc-runtime` 与 `dsh-workflow-ptc` 名称;隔离 Node PTC 的空模型环境;异步可取消的 Sandbox/Shell 准备;由应用消费者决定的可选插件启动失败;请求图片缓存移入 DSH cache 但 normalized attachment 路径保持独立;以及 Team task 的 provider-owned 分页。图片预算恢复不会把首个 `IMAGE_OFFLOAD_REQUIRED` 当作成功;fixture 会记录 Core `image/offload` projection,并证明重试后的 Copilot 请求仅发送带映射只读 normalized 路径的占位文本,不再发送图片字节。插件不导入或接管 MCP、PTC、Workflow、Sandbox、Shell、Team 服务。该 tag 没有通用 `HostGrant`/`hostGrants` API,插件也不注册此类耦合。Copilot tool schema 过滤继续移除 `pwsh`、文件与 `run_code` 的不可用提权参数,同时保留 Team 分页字段。本版本仅准备 Draft 兼容 PR,不表示已发布。
46
46
 
47
+ ### Alpha.21 Desktop 共享包所有权修复(#125)
48
+
49
+ Candidate manifest 将 `@deepseek-ai/dsh-authorization` 与 `@deepseek-ai/schemastery` 声明为必需 Host peer,不再作为插件私有 runtime dependency。开发环境仍保留固定依赖,用于 standalone build、单元测试、Host import、Client loader 与 Remote codec 验证。真实 packed-tarball gate 会将全部 dependency/peer 与 hash 固定的 Desktop 0.1.5 实际 runtime descriptor、Desktop 0.1.6 生成 package-set 输入逐项审计,并拒绝打包 Host 共享包、把必需 peer 标为 optional、版本不兼容或新增但未审计的依赖。0.1.6 package-set 是 descriptor 生成的权威输入,但不是已经物化的 Desktop descriptor、live 激活、OAuth 或模型调用证据。本修复保留现有 Settings → Models provider card、认证入口、生命周期适配与图片卸载行为,也不弱化 Desktop validator。
50
+
47
51
  ## 安装与登录
48
52
 
49
53
  将当前 release 安装到你实际使用的 profile(其它 profile 请替换 `web`):
@@ -56,10 +60,14 @@ node package/scripts/check-search-composition.mjs --profile-dir /absolute/profil
56
60
 
57
61
  若启动时还有额外 patch,用重复的 `--patch /absolute/file` 参数一并提供。必须得到 `supported: true` 才继续安装;自定义、已禁用、嵌套、已有隔离映射的 web 服务或路由保留名称冲突会在修改前拒绝。预检只用 Core 公开解析接口,不启动插件、不读取认证凭据、不改配置。**`dsh plugin add` 不会自动执行这项预检**;这是安装者必做步骤,不是对任意第三方组合的兼容保证。
58
62
 
63
+ 获准且网络可用时,可通过受支持的 CLI 命令安装:
64
+
59
65
  ```sh
60
- dsh plugin --profile web add https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/dsh-github-copilot-0.4.0-alpha.19.tgz
66
+ dsh plugin --profile web add https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/dsh-github-copilot-0.4.0-alpha.21.tgz
61
67
  ```
62
68
 
69
+ 若 registry 被公司封禁或不可用,不要更换网络绕行。Desktop 管理的 profile 可以改用[受控离线 CLI 流程](./docs/npm-distribution.md#controlled-offline-cli-maintenance):使用来源获准、校验通过的本地 Release 和已有依赖缓存(`--offline --ignore-scripts`)。预检、备份和授权要求仍然适用。
70
+
63
71
  随后打开上表对应的 Models UI,找到 **GitHub Copilot**,点击 **Sign in** 并完成 GitHub device-code 流程。安装会修改指定 profile;是否立即激活取决于该 profile 的常规 reload/restart 策略。
64
72
 
65
73
  ### 用户授权流程
@@ -120,7 +128,7 @@ Agent 应把浏览器授权视为需要用户完成的 handoff,而不是自行
120
128
  5. 确认 **Signed in** 并检查自动发现结果,再请用户选择模型。已登录时打开 Models 会自动确保缺失/过期元数据,新鲜 ready 缓存不发请求。错误可使用 **Retry**,有意强制更新时使用 **Manage → Refresh models**,不作为常规设置步骤。状态读取本身不发现;登录、元数据与真实调用成功是独立证据。
121
129
  6. 只有用户明确要求断开账号时才使用 **Sign out**;它会删除 Copilot credential record,但保留 route settings。
122
130
 
123
- 每个新版本默认同时分发到 GitHub Releases 和 npm,两个渠道使用同一份已验证 tarball。应固定版本并核对 Release 的 `SHA256SUMS` npm `dist.integrity`;准备好包不表示已发布。确认 npm 发布后,官方 Desktop 包管理器使用 `dsh-github-copilot@0.4.0-alpha.19`,不是 URL 或本地文件。安装前仍须完成下述 search-composition 预检;不要使用 CLI 修改 Desktop 管理的 profile。首次建包及后续 OIDC 前置条件见 [npm 分发说明](./docs/npm-distribution.md)
131
+ 每个新版本默认同时分发到 GitHub Releases 和 npm,两个渠道使用同一份已验证 tarball。应固定版本并核对所用渠道的证据:Release 的 `SHA256SUMS`;从 npm 安装时另核对 `dist.integrity`。在获准且可用的 registry 网络环境中,优先使用原生 Desktop 包管理器;确认 npm 发布后,它接受 `dsh-github-copilot@0.4.0-alpha.21`,不是 URL 或本地文件。Desktop 管理的 profile 也允许经明确授权的[受控离线 CLI 维护](./docs/npm-distribution.md#controlled-offline-cli-maintenance):使用已验证的本地 Release `--offline --ignore-scripts`,执行必需的组合预检、私密元数据备份、单写入者控制及安装后差异核验。缓存不足或出现权限拒绝时停止,不绕过公司 registry 封禁,不关闭 TLS 校验;重启仍需单独授权。离线安装成功不表示 npm 联网或发布问题已修好。[双渠道发布与 OIDC 要求](./docs/npm-distribution.md)保持不变。
124
132
 
125
133
  不需要运行 `copilot2api`,不需要外部 gateway、placeholder API key、原始 GitHub token 或单独安装 `dsh-web-search-provider`。
126
134
 
@@ -137,6 +145,12 @@ Agent 应把浏览器授权视为需要用户完成的 handoff,而不是自行
137
145
 
138
146
  DSH Core 继续负责模型选择、sandbox、工具、附件与其它 provider。原生 `github-copilot` 的模型目录和 profile 仍属于 Core/用户;插件不拿自己的 pi 依赖副本改写它们。托管账号路由复用公开 adapter 类、SDK 序列化、OAuth method/grant format、token exchange 和 refresh。普通模型请求使用 SDK `streamSimple`,支持供应方明确公布的 Responses、Chat Completions 和 Anthropic Messages 三种协议。跨 SDK 的高级协议专用 `stream` 接口会明确报 `COPILOT_MANAGED_ADVANCED_STREAM_UNSUPPORTED`,不假装不兼容的底层客户端可互换;这不等于普通流式聊天被禁用。
139
147
 
148
+ ## 可选的规划/执行模型分工
149
+
150
+ 在 **设置 → 模型 → 模型分工** 中启用双模型会话,选择账号下可用的主模型和执行模型,保存后选工作区,再点 **用此配置新建会话**。主模型负责规划与验收;`copilot_execute` 创建原生可继续执行的子代理,并固定其执行模型。默认关闭,仅专用入口创建的新会话采用此策略;不修改全局默认、已有会话、登录凭据或原生 Subagent 授权开关。
151
+
152
+ 模型不可用时明确报错,不自动替换。创建结果不明时重试同一个请求,不为绕过未知结果另建会话。功能依赖公开的会话、策略和子代理能力;缺少接口时显示不可用,不把历史版本的包兼容范围当成此功能的全面验收。详见[配置、生命周期、限制与验证范围](./docs/dual-model.md)。本功能包含在 `0.4.0-alpha.21` candidate 中,源码和合成测试不代表已发布或当前 Desktop 已生效。
153
+
140
154
  ## 全局账号,多模型与独立会话(V3)
141
155
 
142
156
  一个 Host 所有的 Copilot 账号提供多个账号发现模型。已显式选择或有历史选择的 Session 保持自己的模型上下文:Session A 的搜索使用捕获的发起 Session A 的有效 request-header/config(或请求显式 `GenerateOptions`),不采用 Session B 的选择或未来全局默认 C。搜索 plan 按 owner 缓存,A/B 使用不同模型时不会互相复用或取消 plan;账号元数据仍共享,能力/probe 与凭据检查继续生效。
@@ -365,8 +379,8 @@ node scripts/agent.mjs attribution "DeepSeek Harness (DSH)"
365
379
  `package.json` 声明公开 npm 分发。Release tag 必须严格等于 `v${package.json.version}`。预发布使用 `alpha`、`beta` 或 `rc` 及对应 npm dist-tag,只有稳定版使用 `latest`。Release workflow 执行 frozen install 和完整门禁,只打包一次(重试恢复原始归档),验证 `SHA256SUMS`,发布不可变 GitHub Release,再通过 OIDC 将同一份字节发布到 npm。任一渠道失败都表示交付未完成。首次建包须由获准环境中的维护者完成;staging 要求包已存在,不能代替首次建包。不会批量补发历史版本。
366
380
 
367
381
  ```sh
368
- curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/dsh-github-copilot-0.4.0-alpha.19.tgz
369
- curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.19/SHA256SUMS
382
+ curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/dsh-github-copilot-0.4.0-alpha.21.tgz
383
+ curl -LO https://github.com/cloga/dsh-github-copilot/releases/download/v0.4.0-alpha.21/SHA256SUMS
370
384
  sha256sum --check SHA256SUMS
371
385
  ```
372
386
 
@@ -374,7 +388,7 @@ PowerShell 可以对已下载的同一组文件执行:
374
388
 
375
389
  ```powershell
376
390
  $expected = (Get-Content .\SHA256SUMS).Split()[0]
377
- $actual = (Get-FileHash .\dsh-github-copilot-0.4.0-alpha.19.tgz -Algorithm SHA256).Hash.ToLowerInvariant()
391
+ $actual = (Get-FileHash .\dsh-github-copilot-0.4.0-alpha.21.tgz -Algorithm SHA256).Hash.ToLowerInvariant()
378
392
  if ($actual -cne $expected) { throw 'Release checksum mismatch' }
379
393
  ```
380
394
 
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "package": {
10
10
  "name": "dsh-github-copilot",
11
- "version": "0.4.0-alpha.19"
11
+ "version": "0.4.0-alpha.21"
12
12
  },
13
13
  "evidence": {
14
14
  "kind": "source-and-synthetic-test-inventory",
@@ -159,6 +159,7 @@
159
159
  "@deepseek-ai/dsh-launch-environment",
160
160
  "@deepseek-ai/dsh-llm",
161
161
  "@deepseek-ai/dsh-llm-pi-ai",
162
+ "@deepseek-ai/dsh-scope",
162
163
  "@deepseek-ai/dsh-settings",
163
164
  "@deepseek-ai/dsh-typert-protocol",
164
165
  "@deepseek-ai/dsh-web",
@@ -167,13 +168,42 @@
167
168
  },
168
169
  "piAi": "0.85.1",
169
170
  "runtimeDependencies": {
170
- "@deepseek-ai/dsh-authorization": "0.1.2-rc.1",
171
- "@deepseek-ai/schemastery": "^3.18.2",
172
171
  "@earendil-works/pi-ai": "0.85.1",
173
172
  "zod": "^4.4.3"
174
- }
173
+ },
174
+ "sharedPeerDependencies": {
175
+ "@deepseek-ai/dsh-authorization": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.3-alpha.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
176
+ "@deepseek-ai/schemastery": "^3.18.2"
177
+ },
178
+ "desktopSharedPackageContracts": [
179
+ {
180
+ "id": "desktop-0.1.5-rc.2-installed-runtime",
181
+ "sourceSha256": "210cacaf3842643ef6c124fd23cb3b67caf7008e97868c733550b56ba7a1e836",
182
+ "packageCount": 241
183
+ },
184
+ {
185
+ "id": "desktop-0.1.6-alpha.1-generated-package-set",
186
+ "sourceSha256": "51b25ad67e6b0198edca0ec9baf8ebd06d26217dd33d1a2a4cce7e881382e6ea",
187
+ "packageCount": 246,
188
+ "descriptorStatus": "not-materialized"
189
+ }
190
+ ]
175
191
  },
176
192
  "capabilities": [
193
+ {
194
+ "id": "desktop-shared-package-ownership",
195
+ "required": true,
196
+ "evidenceScope": "packed-manifest-against-actual-0.1.5-and-generated-0.1.6-shared-package-contracts",
197
+ "sourceMarkers": [
198
+ {"file": "scripts/verify-desktop-package-graph.mjs", "marker": "verifyDesktopPackageGraph"},
199
+ {"file": "scripts/verify-tarball.mjs", "marker": "desktopSharedGraphs"},
200
+ {"file": "tests/fixtures/desktop-shared-package-contracts.json", "marker": "desktop-0.1.6-alpha.1-generated-package-set"}
201
+ ],
202
+ "tests": [
203
+ {"file": "tests/scripts/desktop-package-graph.test.mjs", "name": "packed manifest composes with the actual 0.1.5 and generated 0.1.6 Desktop shared graphs"},
204
+ {"file": "tests/scripts/desktop-package-graph.test.mjs", "name": "shared graph gate rejects bundled, optional, incompatible, or unaudited host ownership"}
205
+ ]
206
+ },
177
207
  {
178
208
  "id": "readonly-search-composition-preflight",
179
209
  "required": true,
@@ -20,6 +20,7 @@ The existing project already has useful architecture boundaries, strict Remote c
20
20
  | Vacuous assertion | Cordis DisposableList was indexed as an array, allowing undefined UID comparisons | Use iterable conversion and assert defined identity before equality in loader tests |
21
21
  | Build evidence | verify:package checked Host existence, then claimed built Host verified | Import real built Host without the Vitest Typert alias; assert exported contract and label the evidence as import-only |
22
22
  | Archive delivery | Pack/checksum did not check actual exported files or README media; images were omitted | `verify:tarball` inspects bounded tar data without extraction; rejects paths/links/duplicates/unexpected files/trailing payload; compares the full normalized manifest and every packed file to the checkout/build; checks exports and README media; CI/release run it after packing |
23
+ | Desktop shared-package ownership | Alpha.18-alpha.20 tarballs privately declared Host-owned authorization and schema packages, so native Desktop profile validation rejected the graph | Alpha.21 makes both required peers with development-only copies; the packed-manifest gate audits every runtime/peer declaration against hash-pinned 0.1.5 actual descriptor and 0.1.6 generated package-set projections |
23
24
  | External verifier safety | Fixed fixture path could overwrite then delete a pre-existing upstream file | Exclusive create, pinned clean tracked sources, physical-path containment, identity/byte-guarded cleanup and bounded child; twelve synthetic failure/sentinel tests including a Windows junction |
24
25
  | Release prerequisite | Tag workflow could run independently of complete platform/Core matrix | Reuse CI through workflow_call; publish job needs matrix success on tag revision; contract verifier checks the dependency |
25
26
  | Session model correctness | Inline preflight checked provider but plan sends default-route candidate.model | Historical guard matched provider AND model and delegated mismatches; alpha.8 replaces default-derived planning with initiating-owner/request identity (see #99 below) |
@@ -0,0 +1,63 @@
1
+ # Copilot model roles
2
+
3
+ Issue [#127](https://github.com/cloga/dsh-github-copilot/issues/127). This is an opt-in plugin feature, not a second model adapter, a replacement permission system, or a claim that the running Desktop has been upgraded.
4
+
5
+ ## Use
6
+
7
+ 1. Open **Settings → Models → Model roles** (Chinese: **模型分工**). Older supported Clients use the **Copilot · Model roles** settings section.
8
+ 2. Enable dual-model sessions and select a **Planning model** and an **Execution model** from this account's available Copilot models. Model names and IDs come from the existing account-discovery service, never an implementation table.
9
+ 3. Save the configuration. The revision-checked save affects only this plugin's `github-copilot-dual-model` namespace. No global model default, credential, other provider or existing session is changed.
10
+ 4. Select an existing workspace and choose **Create session with this configuration**. Return to the application if the host's settings surface remains open, then enter the task in the new conversation.
11
+ 5. The planner clarifies the task, reads evidence and performs acceptance review. `copilot_execute` creates a native continuable execution child using the captured execution route. Its result shows the actual delegated provider/model and child ID; acceptance of the prompt is not completion. The original `send_message`, `list_agents` and `interrupt_agent` capabilities continue the child and expose its status.
12
+
13
+ For example, if the account advertises them, choose GPT 6 for planning and GPT-5.6 Sol Fast for execution. These are examples, not hard-coded defaults or promises of account entitlement. Acceptance uses the planning model. Both roles share the existing Host-only Copilot OAuth lifecycle.
14
+
15
+ The ordinary **Subagent → Allow agents to choose models for subagents** setting is a different feature: it authorizes optional model selection, and omission can still inherit a parent model. This dedicated entry captures and enforces a fixed route for its execution children instead. It does not silently enable that global setting.
16
+
17
+ ## Scope and safety
18
+
19
+ - Disabled by default. Saving an enabled configuration requires two currently available models; a saved unavailable ID is kept visibly unavailable rather than silently replaced.
20
+ - Only sessions created through this entry receive the role policy. Saving different defaults, disabling new dual-model sessions, or editing unrelated sessions does not rewrite an existing role policy. Forked histories are not silently enrolled as new dedicated roots.
21
+ - Planner write/shell and alternative delegation tools are unavailable in the dedicated flow. Executors receive an explicit implementation-tool allowlist and cannot recursively delegate through the normal agent tools. These are model-workflow controls, **not a malicious-code sandbox**: an authorized shell can itself execute programs. Core sandbox and approval enforcement remain the authority.
22
+ - No fallback model is selected on account/model failure. The existing native adapter continues to validate account proof and real model requests; merely seeing an ID or passing metadata validation is not proof of a successful model call.
23
+ - The new root carries a session-local initial model selection, not a global-default write. Do not use the ordinary model picker to change a dedicated role: a different effective route is rejected with `DUAL_MODEL_SELECTION_LOCKED`. Create a new dedicated session for another role pair. Core's ordinary picker remains user/Core-owned and can itself save a future global default; this plugin does not intercept or promise to prevent that separate user action.
24
+ - Role declarations are captured in an immutable, namespaced, ignorable seed event before publication, and replayed by a plugin-owned projection. The policy includes its exact root ID so an inherited fork seed cannot impersonate a new role owner. The ordinary model-selection event uses Core's published per-session format.
25
+ - The plugin must remain mounted to enforce and resume the dedicated policy. Removal/update disposes plugin-owned overlays and stops their active work; an ignorable extension is not an enduring security barrier after uninstall. Unsupported public service contracts disable this feature visibly without turning normal account sign-in into a hard dependency failure.
26
+
27
+ ## Create, retry and recovery
28
+
29
+ The browser generates a request UUID and keeps the original workspace and settings revision after an uncertain create. It never automatically replays creation. A user retry reuses that identity; the Host derives the same session ID, checks the stored operation before mutable settings, and either returns the original session or reports a conflict. It does not create a second root to work around an unknown result. Workspace attachment and session flush use public APIs; partial creation remains explicit and recoverable.
30
+
31
+ After a confirmed save conflict, reload settings and review the current configuration. During an uncertain creation the original input is held until confirmation. Reloading the whole browser can lose its in-memory pending receipt; inspect the session list before issuing a fresh creation request. The same supplied request UUID remains idempotent on the Host across process restart.
32
+
33
+ ## UI verification captures
34
+
35
+ These are the actual built component with **synthetic** account/workspace responses, not the production Desktop. [Capture provenance and artifact hashes](./images/dual-model-provenance.json) identify the exact evidence.
36
+
37
+ ![Dark desktop: saved planner/executor configuration](./images/dual-model-desktop.png)
38
+
39
+ ![Light narrow screen: one synthetic session created](./images/dual-model-mobile.png)
40
+
41
+ ## Public integration and evidence
42
+
43
+ The feature reuses public settings, account discovery, scope, Agent creation, Session projection/persistence, workspace attachment, tool restrictions/guards and native continuable subagents. It does not access Core private registries, edit prototypes, patch deployed packages, copy grants, install another wire adapter or require a Core change.
44
+
45
+ Missing public capabilities yield an unavailable card. The package's broad compatibility range covers its existing account/search features; it is **not** a promise that this optional flow works on every historical baseline.
46
+
47
+ Regression evidence is separated deliberately:
48
+
49
+ - `dual-model-card.spec.ts`: real React DOM/jsdom interaction, bilingual copy, CAS, unavailable models, stale responses and uncertain-create receipt handling.
50
+ - `dual-model-ui.spec.ts`: optional Slot registration, fallback and cleanup.
51
+ - `dual-model-remote.spec.ts` / `dual-model-gateway.spec.ts`: strict owned codecs and the actual installed Client Gateway with synthetic RPC. Older Client Gateways do not sanitize successful values or arbitrary nested error details; the Host builds bounded DTOs, and the UI renders only its diagnostic allowlist.
52
+ - `dual-model-host.spec.ts`: actual Core Session/projection/scope/tool primitives combined with synthetic Agent, model, persistence and workspace edges. This is not a paid live model run or a full installed Desktop certification.
53
+ - `tests/browser/serve-dual-model.mjs`: serves the actual built Client component on a separate loopback fixture using synthetic account/workspace responses. Run after `pnpm build`; the printed URL is explicitly **not** the production DSH GUI.
54
+
55
+ Publication, Desktop installation, runtime activation and successful real model calls remain separate checks. Never restart active sessions or claim the installed UI changed merely because the repository build passed.
56
+
57
+ ## 中文摘要
58
+
59
+ 在设置的「模型分工」卡中启用功能,选择主模型和执行模型,保存后选择工作区,再点「用此配置新建会话」。主模型负责规划、读取证据和验收;执行子代理使用创建时固定的模型修改代码、运行测试。不是在同一会话里自动来回切换模型,也不是只靠提示词建议执行者换模型。
60
+
61
+ 仅专用入口创建的新会话采用此策略;不修改已有会话、全局默认模型、登录凭据或原生 Subagent 授权开关。模型不可用时明确报错,不自动换模型。需要换角色模型时请另建会话,不要用普通模型选择器改专用角色。插件卸载后不再提供该策略保障;这是协作流程约束,不代替 Core 的沙箱或审批。
62
+
63
+ 创建结果不明时重试同一请求,避免重复会话;不要凭下载、构建或合成测试成功就宣称已安装、已生效或真实模型调用成功。
@@ -0,0 +1,35 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "kind": "built-component-synthetic-fixture",
4
+ "packageVersion": "0.4.0-alpha.20",
5
+ "sourceBranch": "feature/copilot-dual-model",
6
+ "baselineCommit": "f44fd1b15ba93dad3bea0c498648dab3392788d5",
7
+ "component": "src/dual-model-card.ts",
8
+ "fixture": "tests/browser/dual-model.html",
9
+ "server": "tests/browser/serve-dual-model.mjs",
10
+ "clientArtifact": "lib/client.js",
11
+ "clientArtifactSha256": "65fa84f960e9facdc4ca8c72292c2a136c6e9b5bcf22271d899fb10eba5e12ab",
12
+ "browser": "Playwright-managed Microsoft Edge",
13
+ "locale": "zh",
14
+ "productionServices": false,
15
+ "modelCalls": false,
16
+ "accountAndWorkspaceData": "synthetic",
17
+ "images": [
18
+ {
19
+ "path": "docs/images/dual-model-desktop.png",
20
+ "viewport": { "width": 1440, "height": 1000 },
21
+ "theme": "dark",
22
+ "state": "configuration saved; selected workspace; create enabled",
23
+ "sha256": "0911486f93ff120b85c1d7e97c83f35b742cd912b10ab046b05a3be505790107"
24
+ },
25
+ {
26
+ "path": "docs/images/dual-model-mobile.png",
27
+ "viewport": { "width": 390, "height": 1000 },
28
+ "theme": "light",
29
+ "state": "one synthetic session created and opened through fixture callback",
30
+ "sha256": "5e6342c844047e9872f3b48eeaeec72036b1453754b1e7e5011d87f1ec1f6d04"
31
+ }
32
+ ],
33
+ "observations": { "horizontalOverflow": false, "syntheticCreatedSessions": 1 },
34
+ "limits": ["not a production Desktop screenshot", "not a live Copilot model request", "not complete Settings-shell integration proof"]
35
+ }
@@ -118,15 +118,71 @@ There is no historical bulk backfill and no silent npm opt-out.
118
118
 
119
119
  ## Installation preflight still applies
120
120
 
121
- After both channels are verified, official Desktop accepts the exact
122
- `dsh-github-copilot@<version>` npm spec in its package manager. It does not accept
123
- the Release URL or local tarball in that UI. Follow the existing README
124
- `scripts/check-search-composition.mjs` preflight before changing configuration;
125
- the script remains in the package. A successful package lookup or install does
126
- not prove runtime activation or a successful Copilot request.
127
-
128
- For separately managed CLI profiles only, retain the required `--profile` on
129
- `dsh plugin` commands. Never use the CLI to write a reserved Desktop-managed
130
- profile, copy into node_modules, patch Core or restart active Sessions without
131
- their separate approvals. Installed-on-disk and loaded-runtime evidence remain
132
- distinct.
121
+ The native Desktop package manager remains the preferred interactive entry
122
+ point when its registry access is permitted and available. After npm publication
123
+ is verified, it accepts the exact `dsh-github-copilot@<version>` npm spec, not a
124
+ Release URL or local tarball in that UI. This UI input restriction is not a
125
+ blanket prohibition on maintaining the same profile through the supported CLI.
126
+ Controlled CLI maintenance is also supported for Desktop-managed profiles under
127
+ the checklist below. Neither entry point replaces the package's required
128
+ `scripts/check-search-composition.mjs` preflight. A package lookup, preflight or
129
+ successful installation is not proof of runtime activation or a model call.
130
+
131
+ ## Controlled offline CLI maintenance
132
+
133
+ This path installs this package's prebuilt, verified Release without requiring
134
+ access to a blocked npm registry. It is not permission to bypass organizational registry restrictions:
135
+ use only artifacts obtained through organizationally approved sources and
136
+ already available dependency caches. A registry ban remains in force; offline
137
+ installation does not repair TLS or prove that npm publication is healthy. The
138
+ dual-channel **publication** policy above is unchanged.
139
+
140
+ 1. Obtain explicit installation approval for the exact version and profile.
141
+ Resolve the actual DSH CLI, install anchor, `DSH_HOME` and profile directory;
142
+ do not assume a shell shim points to the Desktop's current installation.
143
+ 2. Verify the original Release tarball with an independently trusted SHA-256,
144
+ its package name/version and safe archive layout. Do not substitute a local
145
+ build or repack an existing immutable Release. Extract only the verified
146
+ artifact before executing its packaged preflight.
147
+ 3. Run `scripts/check-search-composition.mjs` against that exact profile, home
148
+ and install anchor, including any extra startup patches. Require
149
+ `supported: true`; unknown, conflicting or unsupported composition is a stop,
150
+ not permission to remove guards or rewrite the profile.
151
+ 4. Keep one writer: do not run Desktop package updates and CLI installation
152
+ concurrently. Take a private backup of installation metadata (package.json,
153
+ lockfile, bundle/patch configuration and relevant package-manager settings),
154
+ record the current version, and retain a verified rollback artifact.
155
+ Do not copy credential stores, `.env` files or browser storage. If ensuring
156
+ exclusive maintenance requires stopping the Host, obtain separate approval.
157
+ 5. Invoke the supported DSH CLI with an absolute path to the verified archive:
158
+
159
+ ```sh
160
+ dsh plugin --profile web add /absolute/path/to/verified-release.tgz --offline --ignore-scripts
161
+ ```
162
+
163
+ Replace `web` and the archive path with the approved targets. `--offline`
164
+ requires the existing cache; `--ignore-scripts` prevents package lifecycle
165
+ scripts from creating a second, uncontrolled installation/network path. If
166
+ the cache is incomplete or a dependency requires a new build, stop and report
167
+ the missing requirement. Do not silently remove these flags, change registry,
168
+ add a VPN/proxy/mirror, or fetch blocked dependencies through another channel.
169
+ Keep TLS verification enabled. Actual platform permission/approval refusals
170
+ remain authoritative; this procedure does not override them.
171
+ 6. Check the exit result and read back the installed version, lock entry and
172
+ package files against the verified archive. Re-run the composition preflight
173
+ and an appropriate import-only smoke check without activating the plugin.
174
+ Inspect all metadata differences: the CLI reconciles `dsh.profile.bundles`
175
+ and may add unrelated installed bundles. Preserve unrelated settings; stop
176
+ for review on unexpected changes and revert only changes proven to belong
177
+ to this operation, never overwrite later user edits with a whole backup.
178
+ Use the package manager, not manual copying into node_modules or Core patches.
179
+ 7. Report the installed version, checksum, backup and evidence limits. Obtain
180
+ separate restart approval before interrupting the Host or active Sessions.
181
+ Installed-on-disk and loaded-runtime are separate states: after an approved
182
+ restart, verify the loaded build and the intended behavior independently.
183
+
184
+ If installation fails, inspect the actual installed state before retrying or
185
+ rolling back; a failed command is not proof that nothing changed. A rollback
186
+ also needs reviewed, narrowly scoped metadata/dependency restoration. This
187
+ documentation change does not rewrite installed or published historical docs,
188
+ change machine-wide registry policy, or grant blanket approval for future updates.