feat: add Feishu user authorization flow documentation and update frontend guidelines
- Added new documentation for the Feishu user authorization flow, detailing the backend protocol, authorization initiation, callback handling, and token management. - Updated frontend index to link to the new authorization flow documentation for better accessibility and guidance on UI design consistency.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
---
|
||||
id: 20260824-composed-slot-before-dom-seam
|
||||
title: 先查宿主组合包 SlotMap,再退回 DOM seam
|
||||
created: 2026-08-24
|
||||
updated: 2026-08-24
|
||||
status: candidate
|
||||
scope: global
|
||||
category: api-discovery
|
||||
confidence: high
|
||||
last_verified: 2026-08-24
|
||||
promotion_target: pattern
|
||||
projects:
|
||||
- dsh-lark-cli
|
||||
tags:
|
||||
- host-extension
|
||||
- slotmap
|
||||
- declaration-merging
|
||||
- native-tab
|
||||
- api-discovery
|
||||
- dsh
|
||||
---
|
||||
|
||||
# 先查宿主组合包 SlotMap,再退回 DOM seam
|
||||
|
||||
## Trigger
|
||||
|
||||
需要判断一个模块化 Web 宿主的插件能否原生增加页面、Tab、导航项或面板,但当前插件仓库和它直接依赖的 runtime 类型里没有找到对应扩展 API。
|
||||
|
||||
## Context
|
||||
|
||||
调研 DeepSeek Harness(DSH)插件能否增加与 Chat、Trajectory 并列的 Session 顶部 Tab 时,先检索当前插件仓库和直接安装的 `@deepseek-ai/dsh-client-runtime`,只看到了 `root`、`shell.overlay` 以及仓库已有的 DOM Portal 路径,一度推断“没有原生 Tab API”。
|
||||
|
||||
继续检查实际 DSH Web Host 组合的 UI packages 后,`@deepseek-ai/dsh-client-ui-conversation` 的 TypeScript declaration merging 明确补充了 `conversation.view`:这是 `kind: 'list'`、`scope: 'session'` 的视图环,一个注册项就是一个顶部 Tab。第一方 `ui-trajectory` 插件正是通过同一 slot 注册 Trajectory。
|
||||
|
||||
这次有意义的复利点不是记住一个 slot 名,而是:扩展契约可能由“视觉表面的所有者包”声明,不在核心 runtime,也不一定出现在业务插件的直接依赖树中。否定一个扩展能力前,必须检查宿主最终组合和第一方同类贡献者。
|
||||
|
||||
## Evidence
|
||||
|
||||
- 2026-08-24,本机 `dsh --version` 返回 `0.1.0-rc.7`;Web UI packages 为 `0.1.0-rc.8`。
|
||||
- 官方 `ui-conversation` SlotMap 在 [`packages/client/ui-conversation/src/client/contract/slots.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-conversation/src/client/contract/slots.ts) 声明 `conversation.view`,注释说明它是 “one list entry per view tab”。
|
||||
- 官方会话组装在 [`packages/client/ui-conversation/src/client/apply.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-conversation/src/client/apply.ts) 遍历 `slots.entries('conversation.view')`,从 entry 的 `id` 和 `label` 生成 Tab;Chat 以 `id: 'chat'`、`order: 0` 注册。
|
||||
- 第一方 [`packages/client/ui-trajectory/src/client/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-trajectory/src/client/index.ts) 使用 `ctx.slots.inject('conversation.view', ...)` 注册 `id: 'trajectory'`、`order: 10` 的 Trajectory Tab。
|
||||
- 当前 `dsh-lark-cli` 只注册 `sidebar.footer.action` 和 `shell.overlay`,再通过 React Portal 使用 Conversation DOM seam;它证明了另一种布局扩展方式,但不能证明原生 Tab slot 不存在。
|
||||
- 本次同时核对了已安装包的 `.d.ts`、编译后 `client.js`、官方中文 README、Context7 官方库 `/deepseek-ai/deepseek-harness` 和 GitHub `master` 原始源码。
|
||||
- 项目内完整调研记录:`dsh-lark-cli/.scratch/research/dsh-plugin-custom-tab.md`。
|
||||
|
||||
## Root cause
|
||||
|
||||
已验证:DSH 的 `SlotMap` 使用 TypeScript declaration merging,由各 UI owner package 分散声明。`dsh-client-runtime` 只声明内建 `root` slot;`conversation.view` 由 `dsh-client-ui-conversation` 声明,因此只查 runtime 会得到不完整的扩展面。
|
||||
|
||||
已验证:宿主最终装配包含的包可以多于业务插件的直接依赖。当前项目没有直接安装 `dsh-client-ui-conversation`,但全局 DSH Web bundle 已组合该包及 `ui-trajectory`,所以项目局部 `node_modules` 不是宿主能力全集。
|
||||
|
||||
已验证:slot 类型声明只能证明 seat 存在;宿主如何把 seat 投影为 UI,需要继续核对 owner 实现。`ui-conversation` 的 header/render 代码证明 `id`、`order`、`label` 会形成 Tab,active id 会选择唯一视图。
|
||||
|
||||
推断:在其他可组合插件宿主中,同类误判也容易发生:核心 SDK 暴露注册机制,具体贡献点由 feature package 增补;从业务仓库向内搜索会漏掉最终装配才拥有的契约。
|
||||
|
||||
## Preferred action
|
||||
|
||||
1. 先确定目标 UI 的所有者:Tab 属于 Conversation、Settings、Sidebar 还是根 Layout;不要默认所有扩展点都由 runtime 声明。
|
||||
2. 枚举实际宿主装配的 feature/client packages。优先读取 bundle manifest、profile dump、全局安装目录或已发布 package metadata,而不是只看业务插件的直接依赖。
|
||||
3. 搜索所有 `SlotMap` declaration merging、slot declaration 和 `slots.register` 调用,区分:
|
||||
- `single`:替换整个表面;
|
||||
- `list`:可追加贡献;
|
||||
- `keyed` / `chain`:按 key 或选择器扩展;
|
||||
- slot 的 `root` / `session` scope。
|
||||
4. 用三类一手证据闭环:
|
||||
- owner package 的契约声明;
|
||||
- owner 如何把注册项投影为实际 UI;
|
||||
- 第一方同类插件的最小注册示例。
|
||||
5. 分别核对“当前部署版本”和“上游当前版本”。前者回答现在能否工作,后者回答接口是否仍存在;不要用其中一个替代另一个。
|
||||
6. 只有确认没有满足需求的 additive slot 后,才评估 DOM seam、Portal、CSS 重排或宿主 fork。若已有原生 slot,用它承担生命周期、排序、卸载和 active state。
|
||||
7. 实现时把 owner package 加入插件的 client inject,并按宿主版本固定 peer/dev dependency;RC API 必须做真实 Web profile smoke test。
|
||||
|
||||
## Boundaries
|
||||
|
||||
- 该方法适用于由多个包组合、扩展契约分散声明的插件宿主。单体应用或拥有集中式完整 schema 的 SDK 不需要扫描全部 feature packages。
|
||||
- 发现内部 slot 不等于它是稳定公共 API。至少需要 package 导出、类型声明、owner 文档或第一方插件用例之一;仅从 minified DOM、私有类名或未导出符号推断时仍按内部实现处理。
|
||||
- `conversation.view` 适合“切换到插件拥有的整页视图”。若需求是文件树、编辑器与官方 Chat 同时可见,原生 Tab 会隐藏非 active view,仍应评估 [[20260822-extension-slot-portal-three-column-grid|生命周期 slot + 稳定布局 seam + Portal]]。
|
||||
- `conversation.view`、`dsh.client.inject` 和具体 order 值是 DSH 当前契约,不应推广成其他宿主的通用命名。
|
||||
- 当前只完成源码、类型、包版本和上游 master 核验,没有为 `dsh-lark-cli` 实际注册新 Tab,也没有运行浏览器集成测试。实现层面的兼容性结论仍需 smoke test。
|
||||
|
||||
## Failed approaches
|
||||
|
||||
- 只检索业务仓库和直接依赖的 runtime:会把“当前项目没有导入 owner package”误判成“宿主没有扩展点”。
|
||||
- 从 `root` 或 `conversation.session` 是 `single` slot 推导不能新增 Tab:这混淆了“替换整棵表面”和其内部声明的 additive child slot。
|
||||
- 看到当前项目已经使用 DOM Portal,就把它当作该视觉需求的唯一方案:既有实现只能证明一条可行路径,不能穷举宿主扩展面。
|
||||
- 只搜 `tab`、`route`、`router`:slot 系统可能把 Tab 表达成抽象的 `view` contribution,应同时沿 UI owner、slot ledger 和第一方插件反向定位。
|
||||
|
||||
## Examples
|
||||
|
||||
DSH 当前原生 Session Tab 的最小形态:
|
||||
|
||||
```tsx
|
||||
ctx.slots.inject('conversation.view', () => ctx.slots.register({
|
||||
name: 'conversation.view',
|
||||
id: 'plugin-view',
|
||||
order: -10,
|
||||
label: () => 'Plugin View',
|
||||
}, PluginView))
|
||||
```
|
||||
|
||||
验证顺序应是:`SlotMap declaration` → `host tab projection` → `first-party trajectory registration` → `target version smoke test`。
|
||||
|
||||
## Promotion record
|
||||
|
||||
- Not promoted. 当前已有一次高置信度纠错和一套可复用调查流程;待在另一个分包式宿主扩展调研中独立复用后,再考虑提升为通用 host-extension discovery pattern。
|
||||
Reference in New Issue
Block a user