@eduwork/dsh-oidc 0.1.0 → 0.2.1
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/CHANGELOG.en.md +40 -1
- package/CHANGELOG.md +40 -1
- package/README.en.md +23 -21
- package/README.md +17 -15
- package/THIRD_PARTY_NOTICES.en.md +7 -5
- package/THIRD_PARTY_NOTICES.md +7 -5
- package/cordis.patch.yml +2 -1
- package/docs/EDUWORK-MIGRATION.en.md +14 -2
- package/docs/EDUWORK-MIGRATION.md +14 -2
- package/docs/account-extensions.en.md +40 -0
- package/docs/account-extensions.md +42 -0
- package/docs/architecture.en.md +9 -9
- package/docs/architecture.md +11 -10
- package/docs/compatibility.en.md +11 -2
- package/docs/compatibility.md +11 -2
- package/docs/desktop-host.en.md +69 -0
- package/docs/desktop-host.md +79 -0
- package/docs/development.en.md +42 -0
- package/docs/development.md +42 -0
- package/docs/dsh-integration.en.md +23 -7
- package/docs/dsh-integration.md +23 -7
- package/docs/ecnu-reference.en.md +3 -3
- package/docs/ecnu-reference.md +3 -3
- package/docs/enterprise-profile.en.md +19 -11
- package/docs/enterprise-profile.md +18 -10
- package/docs/getting-started.en.md +12 -12
- package/docs/getting-started.md +16 -14
- package/docs/key-binding-protocol.en.md +2 -2
- package/docs/key-binding-protocol.md +2 -2
- package/docs/oidc-interoperability.en.md +3 -3
- package/docs/oidc-interoperability.md +2 -2
- package/docs/public-resource-protocol.en.md +51 -0
- package/docs/public-resource-protocol.md +50 -0
- package/docs/release-checklist.en.md +4 -2
- package/docs/release-checklist.md +4 -2
- package/docs/server-integration-contract.en.md +124 -8
- package/docs/server-integration-contract.md +136 -8
- package/examples/ecnu.enterprise-profile.example.json +2 -2
- package/examples/enterprise-profile.example.json +78 -77
- package/examples/identity-only.example.json +10 -0
- package/examples/resources-discovery.example.json +20 -0
- package/lib/callback-page.js +42 -0
- package/lib/client.js +935 -295
- package/lib/desktop-oidc.js +205 -0
- package/lib/index.js +148 -18
- package/lib/oidc.js +314 -58
- package/lib/profile.js +53 -24
- package/lib/provider/core.js +76 -15
- package/lib/provider/index.js +33 -20
- package/lib/provider/transform-adapter.js +31 -10
- package/lib/resources.js +23 -0
- package/lib/typert-schemas.js +34 -3
- package/lib/typert.host.js +42 -36
- package/lib/typert.remote-client.js +41 -35
- package/package.json +100 -29
- package/protocol/openapi.yaml +2 -2
- package/protocol/resources.openapi.yaml +51 -0
- package/schema/enterprise-profile.v1alpha1.schema.json +193 -188
package/docs/architecture.en.md
CHANGED
|
@@ -10,7 +10,7 @@ The design follows five rules:
|
|
|
10
10
|
|
|
11
11
|
1. **DSH owns the runtime.** The plugin uses official DSH services and `PiAiAdapter`; it does not implement a parallel conversation or model transport stack.
|
|
12
12
|
2. **Standards own identity.** Authentication uses OIDC Discovery, Authorization Code + PKCE, ID Tokens, UserInfo, refresh, and optional revocation.
|
|
13
|
-
3. **The institutional service is one complete delivery boundary.**
|
|
13
|
+
3. **The institutional service is one complete delivery boundary.** Managed models require one accountable owner to jointly deliver OIDC, fixed Key Binding and the model gateway; identity-only mode requires only OIDC. a Profile declares only their public endpoints and facts.
|
|
14
14
|
4. **Configuration is data, not code.** A profile cannot select executable adapters, arbitrary endpoint paths, scripts, stylesheets, tools, or skills.
|
|
15
15
|
5. **Product-specific capabilities compose around the core.** The common enterprise-model settings surface belongs to `dsh-oidc`; desktop shells, quota views, model transforms, or institutional pages remain separate plugins/services.
|
|
16
16
|
|
|
@@ -56,12 +56,12 @@ sequenceDiagram
|
|
|
56
56
|
L->>M: OpenAI-compatible streaming request
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
The OIDC Provider, Key Binding, and model gateway in the diagram are three interface groups in one [server API specification](server-integration-contract.en.md). They may route to different internal systems or origins,
|
|
59
|
+
The OIDC Provider, Key Binding, and model gateway in the diagram are three interface groups in one [server API specification](server-integration-contract.en.md). They may route to different internal systems or origins, managed-model mode needs all three groups, while identity-only mode omits the two model-resource groups. The Web callback always returns to local `127.0.0.1`, not a public institutional DSH address.
|
|
60
60
|
|
|
61
61
|
## Code layout
|
|
62
62
|
|
|
63
63
|
- `src/host/index.js`: DSH service entry and Typert remote methods.
|
|
64
|
-
- `src/host/oidc.js`: Web and native
|
|
64
|
+
- `src/host/oidc.js`: Shared Web/desktop OIDC implementation and the legacy native adapter.
|
|
65
65
|
- `src/host/profile.js`: validation, imports, public projection, Provider projection.
|
|
66
66
|
- `src/host/provider/`: local DSH/PiAi Provider adapter and transform seam.
|
|
67
67
|
- `src/client/`: DSH browser bundle, account surfaces, and remote descriptors.
|
|
@@ -83,13 +83,13 @@ OIDC is the only authentication and identity source in the Web backend, which st
|
|
|
83
83
|
|
|
84
84
|
## Credential boundary
|
|
85
85
|
|
|
86
|
-
The Key Binding service returns the model API key exactly once per resolve/provision/renew response. `dsh-oidc` writes it under the normalized Enterprise Profile credential reference. The default
|
|
86
|
+
The Key Binding service returns the model API key exactly once per resolve/provision/renew response. `dsh-oidc` writes it under the normalized Enterprise Profile credential reference. The default is a single institution-neutral reference:
|
|
87
87
|
|
|
88
88
|
```text
|
|
89
|
-
|
|
89
|
+
EDUWORK_API_KEY
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
Legacy automatic names normalize to `EDUWORK_API_KEY`; other explicit references remain unchanged. A credential fingerprint is stored alongside verified identity and the complete resource binding in the Host session. Network use and logout cleanup require the current key to belong to that session. The fingerprint is never projected into RPC, logs or conversation text. See the [Profile specification](enterprise-profile.en.md) for migration boundaries.
|
|
93
93
|
|
|
94
94
|
The Provider adapter resolves that reference at request time. It never reads an ambient pi-ai credential store and never places the key in the Enterprise Profile, UI payload, logs, or DSH transcript. Web and native backends follow the same Profile rule. Native `enterpriseAccounts` is only a host capability adapter; it does not own credential naming, and a conflicting reference is rejected.
|
|
95
95
|
|
|
@@ -107,11 +107,11 @@ Optional feature plugins register a transform through the Cordis service `enterp
|
|
|
107
107
|
|
|
108
108
|
It must not mutate the durable transcript or register a competing adapter for the same route. Native multimodal routes can therefore bypass a text-only image-understanding fallback, while text-only routes can opt into it.
|
|
109
109
|
|
|
110
|
-
##
|
|
110
|
+
## Desktop and legacy native boundary
|
|
111
111
|
|
|
112
|
-
`backend:
|
|
112
|
+
New desktop products use `backend: desktop`: a temporary loopback callback and official browser service share the OIDC/Key/model implementation across Wails and Electron. The host supplies credential storage. Legacy `backend: native` delegates to `enterpriseAccounts` only for existing bridges; see [desktop integration](desktop-host.en.md).
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
The shared UI uses official `settings.models.footer`, onboarding, sidebar and general-settings slots. Institution configuration is read-only trusted data. Legacy bridge mutation methods are compatibility APIs, not a requirement or default UI for new institutions. `models-only` mounts the shared model-settings surface; `external` disables plugin UI. Quota and heartbeat remain in explicitly installed institution extensions.
|
|
115
115
|
|
|
116
116
|
## Deliberate exclusions
|
|
117
117
|
|
package/docs/architecture.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
1. **DSH 负责运行时。** 插件使用 DSH 官方服务和 `PiAiAdapter`,不另建对话或模型传输栈。
|
|
12
12
|
2. **身份遵循标准。** 认证使用 OIDC Discovery、Authorization Code + PKCE、ID Token、UserInfo、刷新和可选撤销。
|
|
13
|
-
3. **机构服务是一个完整交付边界。**
|
|
13
|
+
3. **机构服务是一个完整交付边界。** 托管模型模式要求服务所有者共同交付 OIDC、固定 Key Binding 和模型网关;纯身份模式只需 OIDC。Profile 只能声明这些协议表面的公开地址与事实。
|
|
14
14
|
4. **配置是数据,不是代码。** Profile 不能选择可执行 adapter、任意接口路径、脚本、样式表、工具或 Skill。
|
|
15
15
|
5. **产品特有能力围绕核心组合。** 通用企业模型设置界面属于 `dsh-oidc`;桌面外壳、配额视图、模型转换或机构业务页面仍由独立插件或服务承担。
|
|
16
16
|
|
|
@@ -56,12 +56,13 @@ sequenceDiagram
|
|
|
56
56
|
L->>M: OpenAI-compatible 流式请求
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
图中 OIDC Provider、Key Binding 和模型网关是同一份[服务端接口规范](server-integration-contract.md)
|
|
59
|
+
图中 OIDC Provider、Key Binding 和模型网关是同一份[服务端接口规范](server-integration-contract.md)的三个接口组。它们可以在机构内部拆成不同系统或域名,托管模型模式需要三组完整服务;纯身份模式可以省略两个模型资源组。Web 回调始终返回本机 `127.0.0.1`,不经过机构公网 DSH 地址。
|
|
60
60
|
|
|
61
61
|
## 代码布局
|
|
62
62
|
|
|
63
63
|
- `src/host/index.js`:DSH 服务入口和 Typert 远程方法。
|
|
64
|
-
- `src/host/oidc.js`:Web
|
|
64
|
+
- `src/host/oidc.js`:Web/desktop 共用 OIDC 实现及旧 native adapter。
|
|
65
|
+
- `src/host/desktop-oidc.js`:临时 loopback 登录与取消。
|
|
65
66
|
- `src/host/profile.js`:校验、导入、公共投影和 Provider 投影。
|
|
66
67
|
- `src/host/provider/`:本地 DSH/PiAi Provider adapter 和转换扩展点。
|
|
67
68
|
- `src/client/`:DSH 浏览器 bundle、账号界面和远程描述符。
|
|
@@ -83,13 +84,13 @@ Web 后端只以 OIDC 作为认证和身份来源,并只在 DSH WebServer 精
|
|
|
83
84
|
|
|
84
85
|
## 凭据边界
|
|
85
86
|
|
|
86
|
-
Key Binding 服务在每次 resolve/provision/renew 响应中返回模型 API Key。`dsh-oidc` 将其写入 Enterprise Profile 解析后的 DSH
|
|
87
|
+
Key Binding 服务在每次 resolve/provision/renew 响应中返回模型 API Key。`dsh-oidc` 将其写入 Enterprise Profile 解析后的 DSH 凭据引用。默认值统一为机构无关的公共引用:
|
|
87
88
|
|
|
88
89
|
```text
|
|
89
|
-
|
|
90
|
+
EDUWORK_API_KEY
|
|
90
91
|
```
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
旧自动引用按 Profile 规则兼容到 `EDUWORK_API_KEY`,其他显式引用保持不变。模型 Key 指纹与已验证身份及完整资源绑定一起保存在 Host 会话中;任何网络使用和登出清理都要求当前值仍归属于该会话。指纹不通过 RPC、日志或对话输出。迁移范围见 [Profile 规范](enterprise-profile.md)。
|
|
93
94
|
|
|
94
95
|
Provider adapter 在请求时解析该引用。它不会读取环境中的 pi-ai 凭据存储,也不会把密钥放入 Enterprise Profile、UI payload、日志或 DSH 对话记录。Web 后端和 native 后端使用同一 Profile 规则;native `enterpriseAccounts` 只是宿主能力适配器,不拥有凭据命名策略,若返回不一致的引用会被拒绝。
|
|
95
96
|
|
|
@@ -97,7 +98,7 @@ Provider adapter 在请求时解析该引用。它不会读取环境中的 pi-ai
|
|
|
97
98
|
|
|
98
99
|
## Provider 所有权与扩展
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
托管资源 Profile 声明 Provider ID,以及本地模型或发现模式;纯身份 Profile 不声明 Provider。`dsh-oidc` 通过 DSH 官方 `PiAiAdapter` 和 `@earendil-works/pi-ai` 的 OpenAI Completions 实现拥有这些路由。
|
|
101
102
|
|
|
102
103
|
可选功能插件可通过 Cordis 服务 `enterpriseTransforms` 注册转换。转换可以:
|
|
103
104
|
|
|
@@ -107,11 +108,11 @@ Provider adapter 在请求时解析该引用。它不会读取环境中的 pi-ai
|
|
|
107
108
|
|
|
108
109
|
转换不得修改持久对话记录,也不得为同一路由注册竞争 adapter。因此,原生多模态路由可绕过仅面向文本模型的图像理解回退,而纯文本路由可以选择接入该能力。
|
|
109
110
|
|
|
110
|
-
##
|
|
111
|
+
## Desktop 与旧 native 边界
|
|
111
112
|
|
|
112
|
-
`backend:
|
|
113
|
+
新桌面使用 `backend: desktop`:临时 loopback 回调和官方浏览器服务在 Wails/Electron 间共享 OIDC/Key/模型实现,凭据存储仍由宿主提供。旧 `backend: native` 仅为已有桥接委托 `enterpriseAccounts`。见[桌面集成](desktop-host.md)。
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
共用 UI 使用官方 `settings.models.footer`、onboarding、侧栏和通用设置插槽。机构配置是只读可信数据;旧桥的可变管理方法只是兼容 API,不是新机构的默认 UI 或必需接口。`models-only` 只挂共用模型设置,`external` 关闭插件 UI。配额和心跳由显式安装的机构扩展提供。
|
|
115
116
|
|
|
116
117
|
## 明确排除
|
|
117
118
|
|
package/docs/compatibility.en.md
CHANGED
|
@@ -6,6 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
| dsh-oidc | Node.js | DSH | pi-ai | Status |
|
|
8
8
|
| --- | --- | --- | --- | --- |
|
|
9
|
+
| `0.2.0` stable-version freeze | Windows 24 | registry `0.1.5-rc.1` | `0.85.1` | `npm ci`, complete checks, 93 tests and 6 compiled-browser regressions pass; audit reports 0 vulnerabilities. Runtime sources match dev.7. Consult the registry for publication status; Linux/Node 22 and macOS acceptance are recorded separately. |
|
|
10
|
+
| dev.7 source preparation (historical validation) | Windows 24 | registry `0.1.5-rc.1` | `0.85.1` | Clean `npm ci` from the committed 61-package DSH test closure; 93 tests. This is separate from historical full-product closures; Linux/Node 22 matrix pending. |
|
|
11
|
+
| Frozen `0.2.0-dev.20260910.7` (unpublished) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 265-package product closure, 93 tests including 15 credential ownership/migration regressions and 6 tarball Host tests. Frozen artifact unchanged. |
|
|
12
|
+
| `0.2.0-dev.20260910.6` (unpublished) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 264 coherent DSH packages; 78 tests and 6 compiled-browser checks. Public identity/key/models with no quota HTTP/schema/UI. Host-only account extension transport, official child slot and logout/read races. |
|
|
13
|
+
| `0.2.0-dev.20260910.5` (unpublished) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 264 coherent DSH packages; 75 tests and 7 compiled-browser checks. Real HTTP PKCE/key/model streams, future-session default, avatar quota/keyboard/logout races, and branded callbacks. Adapts PiAi `modelErrors`; existing APIs/events/model selection remain compatible. |
|
|
14
|
+
| `0.2.0-dev.20260909.1` (unpublished) | 24 | `0.1.5-alpha.1` / `5dda764e…` | `0.85.1` | 257 coherent packages; 40 tests including real Host + HTTP OIDC callback, managed-key model discovery, quota, LLM SSE, host-only authorized requests and account events. Browser UI acceptance belongs to the integrating product. |
|
|
15
|
+
| `0.1.0-dev.20260908.1` (local candidate only) | 24 | `0.1.2-rc.1` / `0.1.3-alpha.1` / `0.1.3-alpha.2` | `^0.84.2` | All three isolated dependency trees pass the complete check and 33 tests, including 19 real PiAi HTTP requests verifying thinking-only behavior without a wire effort. Unpublished. |
|
|
16
|
+
| `0.1.0-dev.20260907.3` (local candidate only) | 24 | `0.1.3-alpha.2` / `82a5fd61…` | `^0.84.2` | Real module resolution across 250 coherent DSH packages; TypeScript, 32 plugin tests, Host/Provider/Client contracts, all 13 Typert Remote markers, and real pi-ai reasoning HTTP regression pass. Unpublished. |
|
|
17
|
+
| `0.1.0-dev.20260907.1` (local candidate only) | 24 | `0.1.3-alpha.1` / `d347e703…` | `^0.84.2` | Real module resolution across 247 coherent DSH packages; TypeScript, 29 plugin tests, Host/Provider/Client contracts, and 13 Typert Remote markers pass. Unpublished. |
|
|
9
18
|
| `0.1.0` | 22, 24 | `0.1.2-rc.1` / `a66e4702…` | `^0.84.2` (locked at `0.84.4`) | Exact peer closure, Host/Client contract checks, clean npm installation, and isolated Web/RPC acceptance. |
|
|
10
19
|
| `0.1.0-alpha.11` | 22, 24 | Declared baseline remains `0.1.2-alpha.2`; separate mainline `0.1.2-rc.1` configuration RPC probe | `^0.84.2` | npm scope migration with persistent contracts retained; the rc.1 probe is not full compatibility acceptance. |
|
|
11
20
|
| `0.1.0-alpha.10` | 22, 24 | `0.1.2-alpha.2` / `0a53fb55…` | `^0.84.2` (`0.84.4` in npm/source Runtimes) | Migrated to `SettingsProvider.installSection()`; full checks pass through both npm and source release-pack paths. |
|
|
@@ -19,12 +28,12 @@
|
|
|
19
28
|
| `0.1.0-alpha.2` | 22, 24 (development) | `0.1.1-rc.2` / `b150a551…` | `0.82.1` | Standard UserInfo name presentation unified across Web and native adapters; real deployment acceptance pending. |
|
|
20
29
|
| `0.1.0-alpha.1` | 22, 24 (development) | `0.1.1-rc.2` / `b150a551…` | `0.82.1` | Unit/build/package baseline; real deployment acceptance still required. |
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
Historical stable `0.1.0` targets exact DSH `0.1.2-rc.1`. Current `0.2.0` keeps dev.7 runtime sources and pins DSH `0.1.5-rc.1` throughout the required development/CI closure. Its version is independent of the product version. Historical rows record their original evidence; they do not imply all old runtimes were retested in the current pass or that quota remains in the public API. See [development preparation](development.en.md).
|
|
23
32
|
|
|
24
33
|
## Contract versions
|
|
25
34
|
|
|
26
35
|
- Enterprise Profile: `dsh-oidc/v1alpha1`
|
|
27
|
-
- Key Binding: `worker-user-center-v1`
|
|
36
|
+
- Key Binding Profile selector: `worker-user-center-v1` or `eduwork-resources-v1`; accepted Bootstrap wire aliases: `worker.user-center.v1`, `worker-user-center/v1`, `eduwork-resources/v1`
|
|
28
37
|
- Typert package/namespace: `@eduwork/dsh-oidc` / `oidcAccounts`
|
|
29
38
|
- Browser management projection: `dsh-oidc/management/v1alpha1`
|
|
30
39
|
- Callback path: `/oauth/callback`
|
package/docs/compatibility.md
CHANGED
|
@@ -6,6 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
| dsh-oidc | Node.js | DSH | pi-ai | 状态 |
|
|
8
8
|
| --- | --- | --- | --- | --- |
|
|
9
|
+
| `0.2.0` 稳定版本冻结 | Windows 24 | registry `0.1.5-rc.1` | `0.85.1` | `npm ci`、完整检查、93 项测试、6 项编译浏览器回归通过,audit 为 0。运行源码与 dev.7 相同;发布状态以 registry 为准,Linux/Node 22 与 macOS 验收单独记录。 |
|
|
10
|
+
| dev.7 源码准备(历史验证) | Windows 24 | registry `0.1.5-rc.1` | `0.85.1` | 已提交锁的 61 包 DSH 测试闭包,干净 `npm ci`、93 项测试;与历史完整产品闭包分别记录,Linux/Node 22 矩阵待执行。 |
|
|
11
|
+
| 已冻结 `0.2.0-dev.20260910.7`(未发布) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 265 包产品闭包、93 项测试(含 15 项凭据迁移/归属回归)与 6 项 tarball Host 验证;冻结产物未替换。 |
|
|
12
|
+
| `0.2.0-dev.20260910.6`(未发布) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 264 个一致 DSH 包;78 项测试及 6 项编译浏览器检查。公版身份/Key/模型不含配额请求/类型/UI;Host 专属扩展运输、官方子插槽与注销读取竞态。 |
|
|
13
|
+
| `0.2.0-dev.20260910.5`(未发布) | 24 | `0.1.5-rc.1` / `183f08e9…` | `0.85.1` | 264 个一致 DSH 包;75 项测试及 7 项编译浏览器检查。覆盖真实 HTTP PKCE/Key/模型流、无会话默认值、头像菜单/配额/键盘/注销竞态与品牌回调;本轮适配 PiAi `modelErrors`,原有 API/事件/选模契约保持兼容。 |
|
|
14
|
+
| `0.2.0-dev.20260909.1`(未发布) | 24 | `0.1.5-alpha.1` / `5dda764e…` | `0.85.1` | 257 个一致包;40 项测试含官方 Host+HTTP 登录回调、托管 Key 自动模型目录/配额、LLM SSE、Host 专属授权请求与账号事件。产品浏览器 UI 由主线联合验收。 |
|
|
15
|
+
| `0.1.0-dev.20260908.1`(仅本地候选) | 24 | `0.1.2-rc.1` / `0.1.3-alpha.1` / `0.1.3-alpha.2` | `^0.84.2` | 三套隔离依赖树均通过完整检查及 33 项测试。新增 thinking-only 的 19 次真实 PiAi HTTP 请求回归,保留 thinking 且不发送 effort。未发布。 |
|
|
16
|
+
| `0.1.0-dev.20260907.3`(仅本地候选) | 24 | `0.1.3-alpha.2` / `82a5fd61…` | `^0.84.2` | 250 个一致的 DSH 包通过真实模块解析;TypeScript、32 个插件测试、Host/Provider/Client 契约、13 个 Typert Remote 标记和真实 pi-ai reasoning HTTP 回归通过。未发布。 |
|
|
17
|
+
| `0.1.0-dev.20260907.1`(仅本地候选) | 24 | `0.1.3-alpha.1` / `d347e703…` | `^0.84.2` | 247 个一致的 DSH 包通过真实模块解析;TypeScript、29 个插件测试、Host/Provider/Client 契约和 13 个 Typert Remote 标记通过。未发布。 |
|
|
9
18
|
| `0.1.0` | 22、24 | `0.1.2-rc.1` / `a66e4702…` | `^0.84.2`(锁定为 `0.84.4`) | 精确 peer 闭包、Host/Client 契约检查、干净 npm 安装和隔离 Web/RPC 验收。 |
|
|
10
19
|
| `0.1.0-alpha.11` | 22、24 | 声明基线仍为 `0.1.2-alpha.2`;另有主线 `0.1.2-rc.1` 隔离配置 RPC 探针 | `^0.84.2` | npm 作用域迁移;保留数据协议;不将 rc.1 探针视为完整版本兼容验收。 |
|
|
11
20
|
| `0.1.0-alpha.10` | 22、24 | `0.1.2-alpha.2` / `0a53fb55…` | `^0.84.2`(npm/源码 Runtime 中为 `0.84.4`) | 迁移到 `SettingsProvider.installSection()`;npm 与源码 release-pack 双路径通过完整检查。 |
|
|
@@ -19,12 +28,12 @@
|
|
|
19
28
|
| `0.1.0-alpha.2` | 22、24(开发) | `0.1.1-rc.2` / `b150a551…` | `0.82.1` | Web 与 native adapter 统一使用标准 UserInfo 姓名显示;尚待真实部署验收。 |
|
|
20
29
|
| `0.1.0-alpha.1` | 22、24(开发) | `0.1.1-rc.2` / `b150a551…` | `0.82.1` | 单元测试、构建和打包基线;仍需真实部署验收。 |
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
历史稳定版 `0.1.0` 对应精确 DSH `0.1.2-rc.1`。当前 `0.2.0` 冻结保持 dev.7 运行源码,开发/CI 基线在所需测试闭包内统一锁定 `0.1.5-rc.1`,不跟随产品号。表中旧行是当时的验收事实,不表示本轮重测全部旧 Runtime,也不表示公版仍含配额。见[开发准备](development.md)。
|
|
23
32
|
|
|
24
33
|
## 契约版本
|
|
25
34
|
|
|
26
35
|
- Enterprise Profile:`dsh-oidc/v1alpha1`
|
|
27
|
-
- Key Binding
|
|
36
|
+
- Key Binding Profile 配置名称:`worker-user-center-v1` 或 `eduwork-resources-v1`;Bootstrap wire 兼容名称:`worker.user-center.v1`、`worker-user-center/v1`、`eduwork-resources/v1`
|
|
28
37
|
- Typert 包/命名空间:`@eduwork/dsh-oidc` / `oidcAccounts`
|
|
29
38
|
- 浏览器管理投影:`dsh-oidc/management/v1alpha1`
|
|
30
39
|
- 回调路径:`/oauth/callback`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Desktop hosts without a persistent Web server
|
|
2
|
+
|
|
3
|
+
[简体中文](desktop-host.md)
|
|
4
|
+
|
|
5
|
+
Local candidate `0.2.0-dev.20260910.1` adds `backend: desktop`. OIDC validation, host credentials, Key Binding, model discovery and `authorizedFetch()` reuse the Web implementation; existing `web` and legacy native bridge modes remain supported.
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
- id: enterprise-oidc
|
|
9
|
+
name: '@eduwork/dsh-oidc'
|
|
10
|
+
config:
|
|
11
|
+
backend: desktop
|
|
12
|
+
allowEmptyProfiles: true
|
|
13
|
+
profilePathEnv: EDUWORK_OIDC_PROFILE
|
|
14
|
+
desktop:
|
|
15
|
+
callbackPort: 0
|
|
16
|
+
flowTimeoutMs: 600000
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The host supplies a Cordis `desktopServices` service with `openExternal(url: string): Promise<void>`. OIDC builds the authorization URL from reviewed Profile discovery; the renderer cannot submit an arbitrary URL. The shell opens the system browser, rejects non-HTTP(S) and userinfo URLs, and never logs authorization query parameters. The plugin does not execute shell commands or import Electron/Wails. The service can arrive later; removing it cancels pending sign-ins.
|
|
20
|
+
|
|
21
|
+
When the distribution provides `configFile: {path, examplesPath}`, organization settings stay read-only and are loaded again on restart. The optional Host method `openConfiguration(target: 'config' | 'examples'): Promise<void>` enables configuration-file and example-folder buttons. The RPC accepts these two fixed targets only; the host resolves its own paths, and the renderer cannot send a path or command. `configuration().configFile.canOpen` reports availability. Web hosts without this capability show the configuration-file location instead. Personal models and configured organization sign-in remain available.
|
|
22
|
+
|
|
23
|
+
Resource binding accepts the original `worker.user-center.v1`, the transitional `worker-user-center/v1`, and `eduwork-resources/v1`. Unknown versions and mismatched Provider IDs are rejected before creating a model credential. Completed identity sign-in is retained, with an error identifying the separate resource/configuration problem.
|
|
24
|
+
|
|
25
|
+
The host must implement `credentials.resolve/set/unset`, backed by its operating-system vault. The plugin has no plaintext credential file or fallback on storage failure. OAuth tokens remain Host-only. Personal API keys remain independent of the organization's managed credential. The public `oidcAccounts.authorizedFetch()` capability remains Host-only.
|
|
26
|
+
|
|
27
|
+
Only an explicit sign-in starts an IPv4 `127.0.0.1` listener. The callback is `http://127.0.0.1:<port>/oauth/callback`, using a random port by default. Register a public PKCE client supporting dynamic loopback ports with the IdP. For providers requiring an exact registered URI, a trusted `callbackPort` can pin the port; a conflict fails explicitly instead of switching to an unregistered port. Other bind addresses are not configurable. Cancellation, expiry, success, a valid failed callback, service disposal and host shutdown close the listener. Invalid Host, Origin, state, method or path cannot consume the legitimate attempt.
|
|
28
|
+
|
|
29
|
+
Shared Host/Client RPC additions:
|
|
30
|
+
|
|
31
|
+
- `begin(profileID)` returns `{mode:'external', loginID, expiresAt}` for desktop. Existing Web `redirect` and legacy `completed` variants remain supported.
|
|
32
|
+
- `loginStatus(loginID)` returns `{loginID, profileID, state, expiresAt, status?, errorCode?}`. State is pending/completed/cancelled/expired/failed.
|
|
33
|
+
- `cancelLogin(loginID)` returns the same safe projection and waits for an in-flight credential write to roll back.
|
|
34
|
+
- `openConfiguration(target)` returns `{opened:true}` in file-managed mode; the only targets are `config` and `examples`. System-opening failures produce a concise message.
|
|
35
|
+
- `selectEnterpriseModel(profileID, {onlyIfMissing?})` returns `{changed, selection?}` on DSH 0.1.5 and persists the default through `agentDefaultModel.saveSelection()`.
|
|
36
|
+
|
|
37
|
+
Sign-in, sidebar and organization settings share one account snapshot. Credential Providers should emit the official `credentials/reference-updated` event after set/unset. The client listens to that forwarded Remote event and `connection/reset`; it does not depend on a custom account event that the official Remote transport does not forward.
|
|
38
|
+
|
|
39
|
+
Explicit sign-in with a connected key, or confirmed key provisioning, selects the first resolvable enterprise model. A default is saved even when no session exists. For a current main session, the client also uses the official `modelDirectories.directoryFor(sessionID).select()` API; addressed subagents are left alone. Load the official `agentDefaultModel` and writable `settings` services. Older hosts without this capability show a message asking the user to choose from the model menu.
|
|
40
|
+
|
|
41
|
+
Initial upgrade recovery uses `onlyIfMissing:true`: it preserves an existing resolvable default and repairs only an absent or unavailable one. A valid personal selection in the current session is also preserved. Credential events, connection checks and subsequent status refreshes never select a model. Personal credentials and unrelated settings remain unchanged.
|
|
42
|
+
|
|
43
|
+
For desktop acceptance run `node scripts/serve-desktop-oidc-fixture.mjs --config <new test configuration file>`. It binds a random loopback port, serves synthetic HTTP PKCE/Key/models/quota and writes a public JSONC profile. The file must not exist; user configuration is never overwritten. Use isolated data directories for each shell and Ctrl+C to stop. No real accounts or model credits are used.
|
|
44
|
+
|
|
45
|
+
The independent random login handle is not OAuth state. Results never carry an authorization URL, code, nonce, verifier or token. The client polls once per second, displays browser completion instructions and a cancel button, and cancels on unmount. Sign-in expires within ten minutes. Closing a system browser cannot reliably be detected across platforms; the app cancel action and expiry bound the listener lifetime.
|
|
46
|
+
|
|
47
|
+
An empty Profile list is valid: no listener or organization login is needed. Identity-only profiles need no resource endpoints. Logout preserves personal keys. A resource outage after successful identity verification keeps the identity connected so resource access can be retried.
|
|
48
|
+
|
|
49
|
+
Run `node --test test/desktop.test.js test/desktop-host.test.js`. To test a frozen installation, set `DSH_OIDC_PACKAGE_ROOT` to its package directory and `DSH_OIDC_EXPECT_DSH=0.1.5-rc.1`. The latter test uses the installed package's actual Host dependencies without WebServer, optional browser-service lifecycle and HTTP PKCE. All credentials and identities are synthetic. Shell vault, window and system-browser integration still require product acceptance.
|
|
50
|
+
|
|
51
|
+
The `.20260910.6` public avatar menu provides account refresh and sign-out; quota UI requires an institution extension. A portal supports narrow sidebars; arrows, Home/End, Escape and outside click/focus are supported. Logout clears this profile's local identity, managed key and cached model metadata, serializes vault writes and rejects late writes. Personal keys remain untouched.
|
|
52
|
+
|
|
53
|
+
The temporary HTTP callback page reads `brand.productName/organizationName/logoURL/mark/primaryColor` from this attempt's Profile and chooses Chinese or English from Accept-Language. It has no external fonts, scripts or raw error reflection and directs the user back to the app. Ordinary Web validation still redirects into its local app; model keys never enter the browser.
|
|
54
|
+
|
|
55
|
+
Run `npm run check` from an isolated dependency tree coherent with the exact target DSH. Do not relabel a bundle built using old root dependencies. `npm run check:browser` additionally uses that Runtime's `playwright-core` and locally installed headless Edge (or Chrome through `DSH_OIDC_BROWSER_CHANNEL`) to load the compiled client, verify menu/shared state/logout and capture branded callback pages. It does not replace native vault/system-browser acceptance.
|
|
56
|
+
|
|
57
|
+
## macOS handoff acceptance
|
|
58
|
+
|
|
59
|
+
The OIDC npm package is platform-independent JavaScript. It bundles no Electron, Wails, Keychain or Windows credential binary; macOS consumes the same exact version and integrity. The plugin has no platform branch: the Host interfaces above own shell differences. Windows validation does not establish macOS readiness.
|
|
60
|
+
|
|
61
|
+
Start with `npm ci` and `npm run check`. With Chrome installed, run `npm run check:browser` using `DSH_OIDC_BROWSER_CHANNEL=chrome`. The product owner must also validate a real macOS client:
|
|
62
|
+
|
|
63
|
+
- `desktopServices.openExternal` opens authorization in the system default browser; `openConfiguration` respects system file associations rather than forcing an editor.
|
|
64
|
+
- The Credential Provider stores, restores after restart, rotates and deletes credentials through system protection in the signed app. If the product uses Electron `safeStorage`, its Keychain behavior, unavailable encryption and denied access require main-process acceptance. The plugin never falls back to a plaintext file.
|
|
65
|
+
- Dynamic loopback ports, cancellation, timeout and app exit clean up correctly. The IdP registration cannot assume only the single port used in a Windows test.
|
|
66
|
+
- Login with and without an existing session updates shared account state and enterprise models. Restart preserves valid personal model selections.
|
|
67
|
+
- Validate the host, external browser and credentials separately on actual Apple Silicon and targeted Intel systems. Cross-OS history migration requires sign-in again; another machine's encrypted credential files are not portable credentials.
|
|
68
|
+
|
|
69
|
+
Signing, notarization, DMG/ZIP packaging and app/data-directory layout belong to the desktop distribution repository. This plugin adds no macOS-specific packaging branch.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# 无常驻 Web 服务的桌面宿主
|
|
2
|
+
|
|
3
|
+
[English](desktop-host.en.md)
|
|
4
|
+
|
|
5
|
+
本地候选 `0.2.0-dev.20260910.1` 新增 `backend: desktop`。它复用 Web 后端的 OIDC 校验、Host credentials、Key Binding、模型发现协议,只替换登录回调传输。既有 `web` 和 Go 桥 `native` 配置继续可用。
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
- id: enterprise-oidc
|
|
9
|
+
name: '@eduwork/dsh-oidc'
|
|
10
|
+
config:
|
|
11
|
+
backend: desktop
|
|
12
|
+
allowEmptyProfiles: true
|
|
13
|
+
profilePathEnv: EDUWORK_OIDC_PROFILE
|
|
14
|
+
desktop:
|
|
15
|
+
callbackPort: 0
|
|
16
|
+
flowTimeoutMs: 600000
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
宿主应注册 Cordis `desktopServices` 服务,提供 Host-only 方法:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
openExternal(url: string): Promise<void>
|
|
23
|
+
// 可选:仅打开宿主预先确定的配置文件或示例目录。
|
|
24
|
+
openConfiguration(target: 'config' | 'examples'): Promise<void>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OIDC 从受信 Profile 对应的 Discovery 构造 HTTP(S) 授权 URL。此 URL 只交给 Host 服务;浏览器侧不能传入自选 URL。外壳负责用系统浏览器打开,拒绝非 HTTP(S)、userinfo URL,并且不得记录授权查询参数。插件不自行执行系统命令,不依赖 Electron/Wails 的 JavaScript 包。服务可以稍后加载;移除服务会取消尚未完成的登录。
|
|
28
|
+
|
|
29
|
+
发行方提供 `configFile: {path, examplesPath}` 时,企业服务保持只读,由用户编辑文件后重启应用。若宿主提供 `openConfiguration`,设置显示“打开配置文件”和“查看示例”;RPC 只接收 `config` / `examples`,由宿主解析固定路径,不允许 renderer 传路径或命令。`configuration().configFile.canOpen` 声明是否可直接打开;Web 或未提供该能力的宿主显示配置文件位置作为备用。个人 API Key 设置和已配置企业的身份登录继续可用。
|
|
30
|
+
|
|
31
|
+
资源绑定兼容既有 `worker.user-center.v1`、过渡写法 `worker-user-center/v1` 与 `eduwork-resources/v1`。未知版本或不匹配的 Provider ID 在创建模型凭据前拒绝,保留已完成的身份登录,并提示检查模型资源服务或企业配置;它们不是身份验证失败。
|
|
32
|
+
|
|
33
|
+
宿主必须提供 `credentials.resolve/set/unset`。本插件没有明文凭据文件或存储失败后的备用路径;桌面发行方负责接入操作系统保险库。模型调用仍使用独立运行 Key,OAuth token 不经 RPC 返回 renderer。`oidcAccounts.authorizedFetch()` 仍是 Host-only 公共授权请求入口。
|
|
34
|
+
|
|
35
|
+
只有用户点击登录时才监听 `127.0.0.1`。默认随机端口,回调为 `http://127.0.0.1:<port>/oauth/callback`;需在身份提供方注册支持动态 loopback 端口的公共 PKCE 客户端。若身份提供方只接受精确回调端口,可在受信配置固定 `callbackPort`(端口占用时明确失败,不改用未注册端口)。不支持配置其他监听地址。取消、失效、成功、合法回调失败、服务卸载和 Host 退出均清理监听。错误路径、Host、Origin、state 或 HTTP 方法不会消费合法的待登录状态。
|
|
36
|
+
|
|
37
|
+
RPC 扩展(共用 Host/Client Typert schema):
|
|
38
|
+
|
|
39
|
+
| 方法 | 返回 |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `begin(profileID)` | 桌面返回 `{mode:'external', loginID, expiresAt}`;Web 仍返回 `redirect`,旧 native 仍可返回 `completed`。 |
|
|
42
|
+
| `loginStatus(loginID)` | `{loginID, profileID, state, expiresAt, status?, errorCode?}`。state 为 pending/completed/cancelled/expired/failed。 |
|
|
43
|
+
| `cancelLogin(loginID)` | 同上;等待正在写入的登录撤回,避免取消后重新出现凭据。 |
|
|
44
|
+
| `openConfiguration(target)` | 文件管理模式下返回 `{opened:true}`;目标仅为 `config` / `examples`。系统打开失败时返回简短提示。 |
|
|
45
|
+
| `selectEnterpriseModel(profileID, {onlyIfMissing?})` | DSH 0.1.5 上返回 `{changed, selection?}`,通过官方 `agentDefaultModel.saveSelection()` 保存企业默认模型。 |
|
|
46
|
+
|
|
47
|
+
客户端账号快照由登录页、侧栏和企业设置共享。宿主凭据 Provider 应在 set/unset 后按官方契约发出 `credentials/reference-updated`;客户端监听该标准 Remote 事件及 `connection/reset`,不依赖不会由官方 Remote 转发的自定义账号事件。
|
|
48
|
+
|
|
49
|
+
明确登录并连接 Key 或确认创建 Key 后,自动选择企业目录中第一个可解析模型。还没有会话时也会保存未来会话的默认值;存在主会话时通过官方 `modelDirectories.directoryFor(sessionID).select()` 同步当前选择,不改子代理。宿主应加载官方 `agentDefaultModel` 和可写 `settings` 服务。旧宿主缺少此能力时明确提示从模型菜单选择。
|
|
50
|
+
|
|
51
|
+
升级后的首次加载使用 `onlyIfMissing:true`:已有有效默认值则保留,缺失或已不能解析才修复;当前会话中可用的个人选择也保留。凭据事件、检查连接和后续状态刷新不会切模型,个人 Key 与其他设置不受影响。
|
|
52
|
+
|
|
53
|
+
双桌面联调可运行 `node scripts/serve-desktop-oidc-fixture.mjs --config <新的测试配置文件>`。脚本只绑定本机随机端口,生成合成身份、完整 HTTP PKCE/Key/模型/配额服务及公开 JSONC 配置;配置文件必须不存在,不覆盖用户配置。每套外壳使用独立测试数据目录;用 Ctrl+C 关闭服务。服务不接触真实账号,也不消耗模型额度。
|
|
54
|
+
|
|
55
|
+
`loginID` 是独立随机句柄,不是 OAuth state。响应不包含授权 URL、code、nonce、PKCE verifier 或 token。前端以一秒间隔轮询,显示在浏览器中完成登录与取消按钮;登录最长十分钟,页面卸载取消尚未完成的尝试。关闭外部浏览器无法被跨平台可靠检测,用户可在应用中取消,或等待短时监听过期。
|
|
56
|
+
|
|
57
|
+
空 Profile 是有效配置,不会监听端口,也不要求机构登录。纯身份 Profile 不要求资源端点;登出仅移除该机构的身份/托管 Key,个人 API Key 保留。身份登录成功后资源接口暂不可用时保留已登录身份,后续可以重试资源连接。
|
|
58
|
+
|
|
59
|
+
验证入口:`node --test test/desktop.test.js test/desktop-host.test.js`。后者可通过 `DSH_OIDC_PACKAGE_ROOT` 指向安装的冻结包目录,并设置 `DSH_OIDC_EXPECT_DSH=0.1.5-rc.1`,使用该安装目录的真实 DSH 依赖运行无 WebServer 的 Host、可选浏览器服务和 loopback PKCE 验证。所有凭据与用户均为测试合成值;产品主进程保险库、窗口和操作系统浏览器行为仍由发行方联合验收。
|
|
60
|
+
|
|
61
|
+
`.20260910.6` 的公共侧栏头像显示账户刷新和注销;配额内容由可选机构扩展提供。菜单通过 portal 支持收窄侧栏;支持方向键、Home/End、Escape、外部点击/失焦关闭。注销清理该机构本地身份、模型 Key、模型元数据缓存,序列化保险库写操作并拒绝旧请求写回;个人 Key 不受影响。
|
|
62
|
+
|
|
63
|
+
临时 HTTP 回调页读取本次 Profile 的 `brand.productName/organizationName/logoURL/mark/primaryColor`,按浏览器 Accept-Language 选择中英文。没有外部字体、脚本或原始错误回显,清楚提示返回应用。普通 Web 验证仍跳回本地应用;不会把生产模型 Key 交给浏览器。
|
|
64
|
+
|
|
65
|
+
在与目标 DSH 完全一致的隔离依赖树运行 `npm run check`,不要从旧版本根依赖构建后标为新基线。可再运行 `npm run check:browser`:使用该 Runtime 的 `playwright-core` 和本机 Edge 无头浏览器(可用 `DSH_OIDC_BROWSER_CHANNEL` 指定 Chrome),直接加载编译客户端,验证菜单/多个组件共享状态/注销,并生成品牌回调截图。本检查不替代主进程保险库与真实操作系统浏览器联验。
|
|
66
|
+
|
|
67
|
+
## macOS 接手验收
|
|
68
|
+
|
|
69
|
+
OIDC npm 包是平台无关的 JavaScript,不捆绑 Electron、Wails、Keychain 或 Windows 凭据二进制;macOS 使用同一个精确版本和 integrity。插件内部没有平台分支,外壳差异由上述 Host 接口承担。Windows 验证不能作为 macOS 已可用的结论。
|
|
70
|
+
|
|
71
|
+
接手者先运行 `npm ci`、`npm run check`,安装 Chrome 后可设置 `DSH_OIDC_BROWSER_CHANNEL=chrome` 运行 `npm run check:browser`。产品方还需在真实 macOS 客户端验证:
|
|
72
|
+
|
|
73
|
+
- `desktopServices.openExternal` 用系统默认浏览器打开授权页;`openConfiguration` 遵从系统文件关联,不能固定为某个编辑器。
|
|
74
|
+
- Credential Provider 在签名后的应用中通过系统保护机制保存、重启恢复、轮换和删除凭据。若产品使用 Electron `safeStorage`,其 Keychain 行为、密钥不可用和拒绝访问场景由产品主进程验收;本插件不会回退到明文文件。
|
|
75
|
+
- 临时 loopback 回调的动态端口、取消、超时和应用退出均正确清理;身份提供方的登记不能仅支持 Windows 测试时的单个端口。
|
|
76
|
+
- 在没有会话时登录,及在已有会话中登录,均更新共享头像状态、配置企业模型;重启不覆盖有效的个人模型选择。
|
|
77
|
+
- 真实 Apple Silicon 与目标 Intel 架构的宿主、外部浏览器和凭据机制分别验收。跨操作系统迁移历史数据时重新登录,不复制另一台机器加密的凭据文件作为凭据迁移。
|
|
78
|
+
|
|
79
|
+
应用签名、公证、DMG/ZIP、安装目录与数据目录布局由桌面发行仓库负责;本插件不增加 macOS 专用打包分支。
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Development and release preparation
|
|
2
|
+
|
|
3
|
+
[简体中文](development.md) | **English**
|
|
4
|
+
|
|
5
|
+
The plugin version is `0.2.0`. Its development baseline is DSH `0.1.5-rc.1`, Cordis `4.0.2`, and pi-ai `0.85.1`. Product versions do not determine plugin versions; consult the registry for npm publication status. This stable-version freeze does not change dev.7 runtime sources or replace earlier frozen artifacts.
|
|
6
|
+
|
|
7
|
+
## Verify a clean checkout
|
|
8
|
+
|
|
9
|
+
Use Node.js 22 or 24 in this repository:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm ci
|
|
13
|
+
npm run check
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The manifest declares exact development dependencies for the required DSH test closure, and the lock records public-registry URLs and integrity. Upstream prerelease carets may select a later RC, so pinning only direct peers is insufficient. `check:lock` rejects mixed versions, machine paths and missing integrity; `check:dsh` verifies the actually loaded baseline. Do not substitute junctions into a running desktop for a clean installation, or suppress conflicts with `--force` or `--legacy-peer-deps`.
|
|
17
|
+
|
|
18
|
+
This is the plugin's development/CI closure, not a full desktop product. Consumers still reuse the host through peerDependencies. The [compatibility matrix](compatibility.en.md) distinguishes historical evidence; a historical peer declaration does not mean every old combination was rerun for each commit.
|
|
19
|
+
|
|
20
|
+
The complete check covers TypeScript, the dependency lock and official contracts, Host/Client builds and loading, Node tests, schemas/examples, document links, sensitive-data/license scans, and package inspection. Optional `npm run check:browser` uses Playwright Core with a locally installed Edge/Chrome; `DSH_OIDC_BROWSER_CHANNEL` selects the installed channel (default `msedge`). It downloads no browser and does not replace real distribution login acceptance.
|
|
21
|
+
|
|
22
|
+
## Source map
|
|
23
|
+
|
|
24
|
+
| Path | Responsibility |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `src/host/profile.js` | Trusted Profile, bounded branding/models and common credential reference |
|
|
27
|
+
| `src/host/oidc.js` | PKCE, Token/UserInfo, Key Binding, sessions and credential ownership |
|
|
28
|
+
| `src/host/desktop-oidc.js` | Temporary loopback login shared by both desktop shells |
|
|
29
|
+
| `src/host/resources.js` | Conservative model-catalog normalization |
|
|
30
|
+
| `src/host/provider/` | Official PiAi Provider and explicit image-transform boundary |
|
|
31
|
+
| `src/host/index.js`, `typert.*.js` | Host service, official lifecycle and public RPC |
|
|
32
|
+
| `src/client/` | Official settings slots, account/login UI and bounded branding |
|
|
33
|
+
| `test/` | Synthetic IdP/gateway, HTTP, Host, migration and race regressions |
|
|
34
|
+
| `schema/`, `protocol/` | Profile Schema and implemented resource HTTP contracts |
|
|
35
|
+
|
|
36
|
+
`scripts/build-host.mjs` copies native Host ESM to `lib`; tsdown bundles the Client. Do not edit `lib` by hand. New wire fields require corresponding implementation, Schema/OpenAPI, bilingual documentation and contract tests. Avoid mechanical tests for simple presentation/documentation changes.
|
|
37
|
+
|
|
38
|
+
## Public scope and remaining release work
|
|
39
|
+
|
|
40
|
+
The public package owns identity, managed keys, model discovery/inference and their account UI. Quota, heartbeat, campus search and speech business services belong in institution/product plugins. [Account extensions](account-extensions.en.md) are Host transport and slot contracts, not hidden institution-feature switches. Examples contain placeholder domains, public client IDs and no secrets.
|
|
41
|
+
|
|
42
|
+
CI defines Windows/Linux × Node 22/24. A local Windows result does not cover unexecuted matrix cells. Before joint publication, complete the matrix, deployment acceptance and history/supply-chain review on the selected commit, then freeze the stable version, tag and tarball using the [release checklist](release-checklist.en.md). Existing npm versions and frozen artifacts are not rewritten. Local preparation does not push, release or publish.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# 开发与发布准备
|
|
2
|
+
|
|
3
|
+
**简体中文** | [English](development.en.md)
|
|
4
|
+
|
|
5
|
+
当前插件版本为 `0.2.0`,开发基线是 DSH `0.1.5-rc.1`、Cordis `4.0.2`、pi-ai `0.85.1`。产品版本不决定插件版本;npm 发布状态以 registry 为准。本次稳定版本冻结不改动 dev.7 的运行源码,也不替换既有冻结 tarball。
|
|
6
|
+
|
|
7
|
+
## 从干净 checkout 验证
|
|
8
|
+
|
|
9
|
+
使用 Node.js 22 或 24,在本仓库执行:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm ci
|
|
13
|
+
npm run check
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`package.json` 为所需 DSH 测试闭包声明精确 devDependency;`package-lock.json` 记录 npm registry URL 和 integrity。上游预发布包的 caret 可能选择下一条 RC,因此只固定直接 peer 不够。`check:lock` 同时拒绝混装、机器路径和缺失完整性信息,`check:dsh` 校验实际加载版本。不要用运行中桌面安装目录或 junction 来替代干净安装结果,也不要使用 `--force` 或 `--legacy-peer-deps` 掩盖版本冲突。
|
|
17
|
+
|
|
18
|
+
此依赖闭包仅供本插件开发/CI;它不是整个桌面产品。发布给使用方的插件仍通过 peerDependencies 复用宿主能力。历史已验收组合见[兼容性矩阵](compatibility.md),历史 peer 声明不代表每次提交都重测全部旧版。
|
|
19
|
+
|
|
20
|
+
完整检查包含 TypeScript、依赖锁/官方接口、Host/Client 构建、编译产物加载、Node 测试、Schema/示例、文档链接、敏感信息/许可证扫描和 npm pack 内容检查。可选 `npm run check:browser` 使用 Playwright Core 与本机 Edge/Chrome;设置 `DSH_OIDC_BROWSER_CHANNEL` 可选择已安装的浏览器渠道(默认 `msedge`)。它不下载浏览器,也不代替发行客户端的实际登录验收。
|
|
21
|
+
|
|
22
|
+
## 代码入口
|
|
23
|
+
|
|
24
|
+
| 路径 | 职责 |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `src/host/profile.js` | 可信 Profile、受限品牌/模型配置、统一凭据引用 |
|
|
27
|
+
| `src/host/oidc.js` | PKCE、Token/UserInfo、Key Binding、会话与凭据归属 |
|
|
28
|
+
| `src/host/desktop-oidc.js` | 两种桌面外壳共用的临时 loopback 登录 |
|
|
29
|
+
| `src/host/resources.js` | 模型目录的保守归一化 |
|
|
30
|
+
| `src/host/provider/` | 官方 PiAi Provider 和显式图像转换边界 |
|
|
31
|
+
| `src/host/index.js`、`typert.*.js` | Host 服务、官方生命周期与公开 RPC |
|
|
32
|
+
| `src/client/` | 官方设置插槽、登录/账号展示、有限品牌覆盖 |
|
|
33
|
+
| `test/` | 合成 IdP/网关、HTTP、Host、迁移与竞态回归 |
|
|
34
|
+
| `schema/`、`protocol/` | Profile Schema 与当前资源 HTTP 契约 |
|
|
35
|
+
|
|
36
|
+
Host ESM 由 `scripts/build-host.mjs` 复制至 `lib`,Client 由 tsdown 打包;不要手改 `lib`。新增网络字段时应同步实现、Schema/OpenAPI、中英文规范与合约测试。UI/文档调整不需要添加机械重复实现的测试。
|
|
37
|
+
|
|
38
|
+
## 开源边界与发布待办
|
|
39
|
+
|
|
40
|
+
公共包只拥有身份、托管 Key、模型目录/调用及对应账号 UI。配额、心跳、校内检索和语音业务由机构/产品插件负责;[账户扩展](account-extensions.md)是 Host 运输与插槽边界,不是暗中启用机构功能的开关。所有示例均使用占位域名、Public Client ID 与无秘密配置。
|
|
41
|
+
|
|
42
|
+
CI 声明 Windows/Linux × Node 22/24;本机 Windows 的结果不能代替尚未执行的矩阵单元。下一次共同发行前,应在目标提交上完成矩阵、实际部署联调、历史与供应链审查,再按[发布检查表](release-checklist.md)冻结正式版本、tag 与 tarball。既有 npm 版本和本地冻结包不改写;本地准备不执行 push、release 或 publish。
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Supported host baseline
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Current `0.2.0` uses the registry-published DSH `0.1.5-rc.1` development/CI closure. Historical stable `0.1.0` targets `0.1.2-rc.1`; older candidate evidence is recorded separately in the [compatibility matrix](compatibility.en.md). Never mix DSH lines. See [development preparation](development.en.md) for clean installation.
|
|
8
8
|
|
|
9
9
|
The plugin uses public package exports rather than copied DSH source:
|
|
10
10
|
|
|
@@ -43,8 +43,12 @@ The default export is `OidcAccountService`, a `TypertRemoteService` named `oidcA
|
|
|
43
43
|
| Method | Result |
|
|
44
44
|
| --- | --- |
|
|
45
45
|
| `configuration()` | Public profiles with secrets and endpoint bases removed. |
|
|
46
|
+
| `openConfiguration(target)` | Host-backed configuration/example opening; no file contents or secrets returned. |
|
|
46
47
|
| `status(profileID)` | Local session/credential state. |
|
|
47
|
-
| `begin(profileID)` |
|
|
48
|
+
| `begin(profileID)` | Web redirect, temporary desktop login ID, or legacy native completion. |
|
|
49
|
+
| `loginStatus(loginID)` / `cancelLogin(loginID)` | Poll or cancel the current desktop attempt. |
|
|
50
|
+
| `resources(profileID)` | Model metadata and issues, without quota or secrets. |
|
|
51
|
+
| `selectEnterpriseModel(profileID, options)` | Select a verified connected model through official defaults; no arbitrary Provider destination. |
|
|
48
52
|
| `reconcile(profileID, {allowProvision})` | Bootstrap and resolve/provision/renew. |
|
|
49
53
|
| `logout(profileID)` | Local cleanup and best-effort OIDC revocation. |
|
|
50
54
|
| `management()` | Capability-aware projection consumed by the shared enterprise-model settings UI. |
|
|
@@ -56,10 +60,12 @@ The client descriptor uses strict Zod codecs. Configuration sent to the browser
|
|
|
56
60
|
|
|
57
61
|
### Direct installation
|
|
58
62
|
|
|
59
|
-
`dsh-oidc` declares its own default Web
|
|
63
|
+
`dsh-oidc` declares its own default local-Web Bundle patch. Install it directly from npm into the official Web profile without authoring a wrapper Bundle:
|
|
64
|
+
|
|
65
|
+
Install exact `0.2.0` with a coherent DSH `0.1.5-rc.1` host. If the registry does not yet provide this version during release preparation, use the reviewed source/frozen artifact below.
|
|
60
66
|
|
|
61
67
|
```bash
|
|
62
|
-
dsh plugin --profile web add @eduwork/dsh-oidc@0.
|
|
68
|
+
dsh plugin --profile web add @eduwork/dsh-oidc@0.2.0
|
|
63
69
|
```
|
|
64
70
|
|
|
65
71
|
For auditing, development, or validating unpublished changes, install a reviewed local checkout instead:
|
|
@@ -74,7 +80,7 @@ dsh plugin --profile web add .
|
|
|
74
80
|
|
|
75
81
|
The local-path install links the checkout into the Profile, so the source directory must remain available. It does not scan the current workspace. Team deployments should pin a reviewed, exact npm version and must not mix another DSH prerelease line into the same Profile.
|
|
76
82
|
|
|
77
|
-
The shipped patch mounts exactly one `enterprise-oidc` instance using `
|
|
83
|
+
The shipped patch mounts exactly one `enterprise-oidc` instance using `EDUWORK_OIDC_PROFILE`. The Web backend requires the DSH WebServer to listen exactly on `127.0.0.1` and builds the fixed `/oauth/callback` from its actual port; no public callback-origin setting is accepted. The patch does not hard-code `agent-default-model`; after explicit login/key binding, the Client selects the connected organization model through official APIs. Restart recovery only repairs an unusable default and preserves personal selections. `DSH_OIDC_ENTERPRISE_PROFILE` remains a fallback.
|
|
78
84
|
|
|
79
85
|
### Product-owned Bundle
|
|
80
86
|
|
|
@@ -88,7 +94,7 @@ The shipped patch mounts exactly one `enterprise-oidc` instance using `DSH_OIDC_
|
|
|
88
94
|
- id: enterprise-oidc
|
|
89
95
|
name: '@eduwork/dsh-oidc'
|
|
90
96
|
config:
|
|
91
|
-
profilePathEnv:
|
|
97
|
+
profilePathEnv: EDUWORK_OIDC_PROFILE
|
|
92
98
|
web:
|
|
93
99
|
returnPath: /
|
|
94
100
|
```
|
|
@@ -97,7 +103,13 @@ The containing DSH profile/bundle must also include the ordinary Web app, creden
|
|
|
97
103
|
|
|
98
104
|
See the [getting-started guide](getting-started.en.md) for OIDC registration, Key Binding implementation, environment variables, acceptance, and troubleshooting.
|
|
99
105
|
|
|
100
|
-
## Desktop
|
|
106
|
+
## Desktop composition
|
|
107
|
+
|
|
108
|
+
New Wails/Electron products use `backend: desktop`: the plugin owns a temporary loopback callback and opens the browser through official `nativeCommand`. Both shells share identity, Key Binding and model behavior. The host still provides credential storage; no new `enterpriseAccounts` bridge is required. See [desktop host integration](desktop-host.en.md).
|
|
109
|
+
|
|
110
|
+
## Legacy native bridge
|
|
111
|
+
|
|
112
|
+
The following adapter interface is only for existing integrations. It is not required for a new desktop:
|
|
101
113
|
|
|
102
114
|
```yaml
|
|
103
115
|
- insert:
|
|
@@ -169,3 +181,7 @@ For every DSH release candidate or stable upgrade:
|
|
|
169
181
|
8. record results in `docs/compatibility.en.md` before release.
|
|
170
182
|
|
|
171
183
|
No semver range should silently opt this security-sensitive plugin into an untested DSH release while DSH remains pre-1.0.
|
|
184
|
+
|
|
185
|
+
## Credential reads for institution adapters
|
|
186
|
+
|
|
187
|
+
Explicitly installed local adapters may call `ctx.oidcAccounts.resolveBoundCredential(profileID, { credentialRef: "EDUWORK_API_KEY", runtimeBaseURL })`. The runtime URL must exactly match the reviewed Profile model-service URL. The result is a DSH credential record verified against the session, issuer/client ID, complete resource binding and credential fingerprint, or `undefined`. Use this same snapshot rather than checking status and resolving the name separately, which can race with a login change. This is Host-only, with no Typert/RPC registration and no addition to the server protocol. Adapters remain responsible for restricting request destinations. Desktop/Web support the method; the legacy native bridge does not fall back to an unverified key.
|