feat(web): route onboarding to Models settings
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-30-deepseek-onboarding-credential-setup.md
|
||||
2026-07-30-deepseek-onboarding-credential-setup.md: e715b3ee9bf4b082f52cf1229b0488799cb2dab6
|
||||
2026-07-30-deepseek-onboarding-credential-setup.zh.md: 0b81182ab074c2a41cae1290e6e3f2c7e43891fa
|
||||
2026-07-30-deepseek-onboarding-credential-setup.md: 9249b173f8f6da5dc2abf2fb147a3c9aba99c00f
|
||||
2026-07-30-deepseek-onboarding-credential-setup.zh.md: f3c647669bd9e0974b2c9f0c407eba0c600bc656
|
||||
|
||||
@@ -14,7 +14,7 @@ The [web configuration plane](../architecture/2026-07-30-web-config-plane.md) ma
|
||||
|
||||
**The settings shell contributes navigation state, not provider policy.** `ui-settings` declares a root-scoped `settings.onboarding` list slot and tells registrants whether the current surface is the empty Hero. Its private `openSection(id)` callback opens the settings panel on one registered section. `ui-models` registers the DeepSeek overlay through the same declaration-aware deferred-registration path as its Models section, so plugin load order does not become a contract.
|
||||
|
||||
**The prompt is a credential-only write path.** A mounted, active adapter with a resolved, writable, unconfigured reference presents a password input. Submit calls only `credentials.set({ref, value})`, clears the React draft after success, refetches the shared join, and closes only when the new descriptor reports `configured: true`. Business failures and transport rejections keep the dialog open, restore its busy state in `finally`, and redact the submitted value from rendered error text. The prompt never writes `apiKey`, `baseURL`, or a redacted settings section; advanced configuration opens Models instead.
|
||||
**The prompt routes to the one credential editor.** A mounted, active adapter with a resolved, writable, unconfigured reference presents one action that opens Settings on Models. The existing DeepSeek setup card there exclusively owns the password input, `credentials.set({ref, value})`, write failures, and post-write refresh; the onboarding overlay never holds or submits a secret. An unavailable settings or credential capability keeps its deployment diagnostic and routes to the same page, while an absent adapter remains skipped because navigation cannot mount a Cordis plugin.
|
||||
|
||||
**Unavailable capability states stay honest.** An absent configurable-provider entry suppresses the form because it cannot repair the composition. A present provider whose settings or credential capability cannot be resolved renders an actionable deployment diagnostic. Cancel dismisses the overlay for the current mounted surface and writes no completion fact. Settings, credential, provider-topology, and connection invalidations all refresh the shared join, so an external credential update closes an open prompt without a reload.
|
||||
|
||||
@@ -22,10 +22,12 @@ The [web configuration plane](../architecture/2026-07-30-web-config-plane.md) ma
|
||||
|
||||
**A separate onboarding store and readiness RPC sequence** — rejected because it would create a second client-side interpretation of provider identity, settings paths, secret sidecars, credential references, and invalidation ordering beside the Models page.
|
||||
|
||||
**A second API-key editor inside onboarding** — rejected because the Models page already renders its DeepSeek setup card for exactly this state. Duplicating its secret draft, write errors, and configured-state convergence would add a second security-sensitive UI without another user capability.
|
||||
|
||||
**Writing the API key into provider settings** — rejected because a literal secret would enter the settings mutation path and whole-section replacement cannot safely reconstruct redacted values. Credential storage is already the product seam and supplies immediate invalidation.
|
||||
|
||||
**Showing the same key form when `llm-deepseek` is absent** — rejected because success would only store an unused environment reference; the browser has no supported operation that mounts the missing Cordis plugin.
|
||||
|
||||
## Consequences
|
||||
|
||||
The first-run flow now repairs the shipped adapter without restarting: a keyless browser test boots the real Web composition under an isolated harness home, observes the dialog, stores a generated key into that home's `.env`, verifies no key reaches DOM, ARIA, or browser console output, and confirms the running Models page reports configured. Pure readiness and React tests pin literal, file, process-environment, missing-provider, missing-capability, business-error, transport-error, cancellation, and external-invalidation behavior. The flow deliberately inherits the configuration plane's documented base limitations rather than adding local secret storage, redaction, or settings replacement workarounds.
|
||||
The first-run flow now leads to the shipped adapter's existing editor without restarting: a keyless browser test boots the real Web composition under an isolated harness home, follows the prompt to Models, stores a generated key through that page into the home's `.env`, verifies no key reaches DOM, ARIA, or browser console output, and confirms the running page reports configured. Pure readiness and React tests pin literal, file, process-environment, missing-provider, missing-capability, navigation, cancellation, and external-invalidation behavior. The flow deliberately inherits the configuration plane's documented base limitations rather than adding local secret storage, redaction, or settings replacement workarounds.
|
||||
|
||||
@@ -14,7 +14,7 @@ Status: implemented
|
||||
|
||||
**设置外壳只贡献导航状态,不持有提供方策略。**`ui-settings` 声明一个根作用域的 `settings.onboarding` list slot,并告知注册方当前界面是否为空白 Hero。其私有 `openSection(id)` 回调会打开设置面板并切换到一个已注册分区。`ui-models` 沿用 Models 分区所使用、感知 slot 声明的延迟注册路径来注册 DeepSeek 浮层,因此插件加载顺序不会成为契约。
|
||||
|
||||
**浮层只通过凭据写入路径提交。**适配器已挂载且处于活跃状态,其引用可解析、可写但尚未配置时,界面会显示密码输入框。提交时只调用 `credentials.set({ref, value})`;成功后清空 React 草稿、重新拉取共享联接,并且仅在新描述符报告 `configured: true` 时关闭浮层。业务失败与传输层拒绝都会让对话框保持打开,在 `finally` 中解除忙碌状态,并从渲染的错误文本中脱敏已提交的值。该浮层绝不写入 `apiKey`、`baseURL` 或经过脱敏的设置分节;高级配置会转到 Models。
|
||||
**浮层只负责跳转到唯一的凭据编辑器。**适配器已挂载且处于活跃状态,其引用可解析、可写但尚未配置时,界面会显示一个操作按钮,用于打开「设置」的 Models 分区。该分区已有的 DeepSeek 设置卡片全权负责密码输入框、`credentials.set({ref, value})`、写入失败处理和写入后刷新;首次使用浮层绝不持有或提交 secret。设置或凭据能力不可用时会保留部署诊断,并提供前往同一页面的入口;适配器缺失时仍直接跳过,因为导航无法挂载 Cordis 插件。
|
||||
|
||||
**能力不可用时如实呈现。**可配置提供方条目缺失时不显示表单,因为它无法修复当前组合。提供方存在,但设置或凭据能力无法解析时,界面会显示可采取操作的部署诊断。取消只会在当前已挂载界面中关闭浮层,不写入任何完成状态。设置、凭据、提供方拓扑和连接失效事件都会刷新共享联接,因此外部凭据更新无需重新加载页面即可关闭已打开的浮层。
|
||||
|
||||
@@ -22,10 +22,12 @@ Status: implemented
|
||||
|
||||
**为首次使用引导单设 store 与就绪状态 RPC 调用序列**:不予采用,因为这会在 Models 页之外,再建立一套客户端解释,用于判定提供方身份、设置路径、secret 槽位的伴随信息、凭据引用及失效事件顺序。
|
||||
|
||||
**在首次使用引导中增设第二个 API key 编辑器**:不予采用,因为 Models 页已为这一状态渲染 DeepSeek 设置卡片。复制其中的 secret 草稿、写入错误处理和已配置状态收敛会增加第二个安全敏感的 UI,却不会带来新的用户能力。
|
||||
|
||||
**把 API key 写入提供方设置**:不予采用,因为字面量 secret 会进入设置变更路径,而整个分节替换无法安全重建脱敏值。凭据存储已经是产品 seam,并能立即发出失效事件。
|
||||
|
||||
**`llm-deepseek` 缺失时仍显示同一个密钥表单**:不予采用,因为提交成功也只会存储一个无人使用的环境引用;浏览器没有任何受支持的操作可以挂载缺失的 Cordis 插件。
|
||||
|
||||
## 后果
|
||||
|
||||
首次使用流程无需重启即可修复随产品提供的适配器:无密钥浏览器测试在隔离的 harness 家目录下启动真实 Web 组合,确认对话框出现,把生成的密钥存入该目录的 `.env`,验证密钥未进入 DOM、ARIA 或浏览器控制台输出,并确认运行中的 Models 页报告已配置。纯就绪状态测试与 React 测试固化了字面量凭据、文件凭据、进程环境凭据、提供方缺失、能力缺失、业务错误、传输错误、取消和外部失效行为。该流程直接继承配置平面已记录的基础限制,不会另加局部的机密存储、脱敏或设置替换变通方案。
|
||||
首次使用流程现在无需重启即可引导用户前往随产品提供的适配器已有的编辑器:无密钥浏览器测试在隔离的 harness 家目录下启动真实 Web 组合,依照浮层操作前往 Models,通过该页面把生成的密钥存入该目录的 `.env`,验证密钥未进入 DOM、ARIA 或浏览器控制台输出,并确认运行中的页面报告已配置。纯就绪状态测试与 React 测试固化了字面量凭据、文件凭据、进程环境凭据、提供方缺失、能力缺失、导航、取消和外部失效行为。该流程直接继承配置平面已记录的基础限制,不会另加局部的机密存储、脱敏或设置替换变通方案。
|
||||
|
||||
Reference in New Issue
Block a user