@inventec/dsh-copilot-auth 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +13 -7
  2. package/package.json +1 -1
  3. package/src/host.mjs +13 -3
package/README.md CHANGED
@@ -28,7 +28,13 @@
28
28
 
29
29
  - DSH `0.1.7-rc.2`(实测版本,v1.2.0 起的适配目标)
30
30
  - 版本矩阵:`0.1.2-rc.1` ~ `0.1.5-rc.2` 请用 **v1.1.x**(v1.2.0 移除了旧版必需的 authorization 挂载补丁,在旧版上无法激活)
31
- - v1.2.0 适配了 0.1.7 的 settings API 重塑(`settings.get` 移除),目录保护逻辑改走 `describe()`,对旧版 API 向后兼容
31
+ - v1.2.0 适配了 0.1.7 的 settings API 重塑(`settings.get` 移除),目录保护逻辑改走 `describe()`:**`describe()` 读取在 value 层缺失时回退 user 层,兼容旧版 describe 行形状**;DSH 版本支持矩阵见下表
32
+
33
+ | 本插件 | DSH 实测版本 | authorization 服务 | 说明 |
34
+ |---|---|---|---|
35
+ | v1.2.x | `0.1.7-rc.2`+ | runtime 内置,插件不挂载 | 适配 settings API 重塑后的 describe() 行形状 |
36
+ | v1.1.x | `0.1.2-rc.1` ~ `0.1.5-rc.2` | 由 cordis.patch.yml insert 挂载 | v1.2.0 起移除该补丁,旧版 DSH 上无法激活 |
37
+
32
38
  - 有效的 GitHub Copilot 订阅(公司分配的 github.com 组织账号,SSO 登录)
33
39
  - `pnpm` 可用(`dsh plugin` 是 pnpm 转发器)
34
40
 
@@ -78,10 +84,10 @@ pi-ai 的模型目录是打包时硬编码的 JSON:上游新增模型(如 ge
78
84
 
79
85
  ## 工作原理
80
86
 
81
- - 通过 `cordis.patch.yml` 三段生效:
82
- 1. 挂载 `@deepseek-ai/dsh-authorization` 服务(DSH 内置 bundle 未挂载,不挂则内置登录流不存在)
83
- 2. 注册本插件(host 侧在 webserver 上开 6 条本地路由:`/copilot-auth/start|state|status|logout|refresh/preview|refresh/apply`,跨站 Origin 拒绝)
84
- 3. 以 settings base 层预置 `github-copilot` 路由(用户 `settings.yaml` 可逐字段覆盖)
87
+ - 通过 `cordis.patch.yml` 两段生效:
88
+ 1. 挂载本插件 entry(host 侧在 webserver 上开 6 条本地路由:`/copilot-auth/start|state|status|logout|refresh/preview|refresh/apply`,跨站 Origin 拒绝)
89
+ 2. 以 settings base 层预置 `github-copilot` 路由(用户 `settings.yaml` 可逐字段覆盖)
90
+ - authorization 服务 **0.1.7+ 由 runtime 内置,无需也不得再挂载**(旧版 ≤0.1.5 请用 1.1.x,其依赖该 insert)
85
91
  - 登录走 GitHub 设备码流;凭据存 `~/.dsh/.credentials.yaml`(强制 600 权限)的 `llm-pi-ai/github-copilot` 记录,Copilot 临时 token 到期自动刷新
86
92
  - **模型目录兜底填充**:登录成功时,取「账号可用模型 ∩ pi-ai 内置目录」写入该路由的模型目录——仅当该路由尚未配置 `models` 且无 `modelOverrides` 时写入;目录已存在(含空列表)一律让路,插件启动/重启也绝不触碰用户 settings。同步失败经 `/copilot-auth/status` 的 `syncError` 字段暴露
87
93
 
@@ -89,14 +95,14 @@ pi-ai 的模型目录是打包时硬编码的 JSON:上游新增模型(如 ge
89
95
 
90
96
  ```bash
91
97
  npm install
92
- npm test # node:test:patch 结构 + host/目录/状态机/启动序列共 105 条
98
+ npm test # node:test:patch 结构 + host/目录/状态机/启动序列共 106 条
93
99
  npm run build # esbuild 打包 client 到 lib/client.js(__ModuleLoader__ 信封)
94
100
  npm pack --dry-run
95
101
  ```
96
102
 
97
103
  | 路径 | 职责 |
98
104
  |---|---|
99
- | `cordis.patch.yml` | 三段 patch(authorization 挂载 / 本插件 entry / 预置路由) |
105
+ | `cordis.patch.yml` | 两段 patch(本插件 entry / 预置路由;authorization 服务 0.1.7+ 由 runtime 内置,不再挂载) |
100
106
  | `src/host.mjs` · `src/shared.mjs` | host 半区:登录状态机、6 条本地路由、模型目录同步、刷新 preview/apply 与启动序列 |
101
107
  | `src/client.jsx` | client 半区:settings.section 插槽 + 设备码交互 + 双语文案 |
102
108
  | `scripts/build-client.mjs` | client 打包(`__ModuleLoader__` CJS 工厂信封) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inventec/dsh-copilot-auth",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "为内置 Copilot 提供方补设备码登录/注销设置页,预置开箱路由;凭据入内置凭据库,模型目录兜底不覆盖定制。适配 DSH 0.1.7+(settings API 重塑后;≤0.1.5 请用 1.1.x)。",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/host.mjs CHANGED
@@ -99,9 +99,13 @@ async function syncAvailableModels(ctx) {
99
99
  ids = available.filter((id) => served.has(id));
100
100
  }
101
101
  if (ids.length === 0) return;
102
+ // 真 CAS(与 boot 2a 同款,2026-09-28 审计补充):携带 expectedRevision 提交,
103
+ // 与用户在 Models 页的并发编辑互斥——冲突时 settings 抛 SETTINGS_CONFLICT,
104
+ // 由 sync() 的 catch 记入 syncError(失败不静默),不再有静默覆盖窗口。
105
+ const desc = ctx.settings?.describe?.()?.find?.((x) => x?.ns === "llm-pi-ai");
102
106
  await ctx.settings.mutate("llm-pi-ai", [
103
107
  { op: "set", path: ["providers", "github-copilot", "models"], value: ids.map((id) => ({ id })) },
104
- ]);
108
+ ], desc?.revision);
105
109
  }
106
110
 
107
111
  function sameOrigin(req) {
@@ -573,8 +577,14 @@ export function apply(ctx, opts = {}) {
573
577
  handler: async (req, res) => {
574
578
  if (!guard(req, res, "POST")) return;
575
579
  // 幂等契约:deleteRecord 对不存在记录是 no-op 且正常 resolve,
576
- // 真实删除与否由随后的 /status 反映。
577
- await ctx.credentials.deleteRecord(CREDENTIAL_KEY);
580
+ // 真实删除与否由随后的 /status 反映。异常兜底与其余路由对齐
581
+ // (2026-09-28 审计:无 try/catch 的 reject 会造成连接悬挂/未处理拒绝)。
582
+ try {
583
+ await ctx.credentials.deleteRecord(CREDENTIAL_KEY);
584
+ } catch (err) {
585
+ json(res, 500, { ok: false, error: String(err?.message ?? err) });
586
+ return;
587
+ }
578
588
  json(res, 200, { ok: true });
579
589
  },
580
590
  });