Conversation
- OIDC 登录用 epoch 判定接管:服务端已按一设备一会话吊销旧会话,超时后 到达的响应照常采纳,避免客户端抱着被吊销的旧 token 死循环 401 - refresh 遇 401/403 清空本地会话,心跳/租约续期不再空转刷屏,待重新登录
- 主进程:start 省略 phase 时按授权环境自动选阶段;新增 disconnect (lark-cli auth logout 清本机凭据);verificationUrl 首次出现自动拉起浏览器 - 渲染层:数据源页飞书改走本地授权(连接宫格固定入口 + 已连接卡 + 抽屉 换绑/断开),存量 oo 飞书连接在数据源页隐藏;授权过程改弹居中对话框 - 浏览器 mock:agentAuth 状态机(__feishu.completeAuth/reset)+ AgentPanel.css 引入,mock 页可复现授权卡
- 网关新增 GET /v1/document-import/batches/active:按 provider+连接名 查最近一条 running 批次,无则 null;终态后不再返回 - 桌面主进程/preload/桥接透传 activeImportBatch - 导入面板打开或切换连接时找回后台仍在跑的批次:恢复进度条、续接轮询 到终态,完成/取消 toast 与列表刷新同样生效;runActiveRef 防与本地 新批次双写
docx/pdf/xlsx 真实接线(FilesService→parseVersion→统一理解引擎→ MemoryCore 子进程→mock LLM),断言解析文本真实到达记忆引擎出原子; xlsx 默认策略不进记忆。test 脚本单独隔离跑(与 memory-doc-pipeline 同法)
…tion # Conflicts: # apps/desktop/src/main/cloud/saas-client.ts # apps/desktop/src/renderer/src/components/pages/sources/SourceCard.tsx
合并 dev 后 initialize 记忆会在无账号时清空,status() 重跑会话恢复并拿 存量 token refresh;原 mock 对 /app/auth/refresh 回订阅形状导致恢复失败 进入 2 秒重试睡眠,假时钟下无人推进而挂起。refresh 改回登录形状(与登录 同会话族),4 用例恢复通过。
- 新增 lark-action-runner:把适配器发出的 OpenConnector action 翻译成 lark-cli 命令,CLI 信封归一化成 oo 形状(providers.ts 解析零改动), 错误统一分类成 ImportConnectorError - service:飞书不经 OpenConnector 连接解析;授权门禁(auth status 缓存 30s,缺失映射 422 引导授权);图片/媒体经 lark-cli 下载到本地文件; create-server 注入 larkCli 配置
- FeishuAuthCard 显示可见文档数/已导入数(列举缓存,未列举显示 —/0) - 导入面板新增 standalone 模式:不拉 OpenConnector 连接、不显示连接 缺失引导;飞书抽屉直接内嵌,授权态由数据源页维护 - SourcesPage:飞书已授权即拉导入统计;连接提示文案去掉「连接器」页 指引(飞书已不走该入口)
- 网关:slides 四工具从用户档工具面剔除(SLIDES_TOOL_NAMES 单一事实源), 新增 slides_draft(create/edit) 派发子代理并归一结构化结果; 注册 slides-writer 工具面(slides 四件套 + 素材自取只读面) - 子代理:新增 agents/slides-writer(六套风格 skills + 结构化输出契约), read 工具改为相对 revision 根解析路径 - 桌面:PPT「AI 修改」弹层与产物库新建 PPT 的指令改走 slides_draft
There was a problem hiding this comment.
总评
本 PR 体量较大(飞书导入换轨 lark-cli、PPT 四件套收归 slides-writer 子代理、SaaS 登录会话自愈、转录 409 防重排队),整体实现质量较高。已核实的安全面:lark-cli 执行层 spawn(shell:false) 无 shell 注入面;媒体下载 token 经 [A-Za-z0-9]+ 白名单提取后再拼路径,无路径穿越;openExternalUrl 仅放行 http/https,授权链接自动开浏览器不会执行任意协议;skill read 工具改为 root 相对解析后仍受 startsWith(root+sep) 约束;slides-writer 工具面 allowlist 与 SLIDES_TOOL_NAMES 有测试同步断言,主 Agent 用户档剔除逻辑覆盖 main/main-direct/main-lite。测试覆盖(lark-runner、batch active、slides-writer-tools、subagent-tools、session-recovery)扎实。
未发现安全/隐私阻塞项;以下按严重度列出建议关注的问题。
发现(按严重度)
-
【中·发布风险】引擎硬校验未随本 PR 落地,子模块指针悬空
agents/slides-writer/SYSTEM.md:26向子 Agent 承诺「引擎硬校验(emoji/文本重叠违规整页拒绝,报错回传后修正重试)」,该校验位于 genoffice 子模块的未推送分支(PR 备注自述当前账号推不上去),本 PR 中apps/desktop/vendor/genoffice指针无任何变化。指针 bump 跟进之前,防 emoji/防重叠只余模型自查,实际兜底弱于 SYSTEM.md 与主 Agent 工具描述的承诺。建议把指针跟进 PR 显式挂到本 PR 或 issue 上跟踪,避免两步之间的质量空窗被遗忘。 -
【中·运行风险】飞书换轨后的真实 CLI 输出契约未经真机验证
test plan 中「真机冒烟:飞书导入」未勾选。apps/gateway/src/modules/documents/import/lark-action-runner.ts:102-114对drive files list条目(type/token/name/url/modified_time/owner_display_name 等)原样透传给 providers.ts 的键名解析,:45-56的result_meta拍平同样依赖 CLI 实际输出形状——单测 fixture 是测试作者自证的,无法证明真实 lark-cli 契约一致。若字段名有出入,列举/搜索可能仍通但 owner/updatedAt 静默缺失。建议合并前完成一次真机冒烟(导出侧已在用的docs +search/+fetch契约可信度高,风险集中在drive files list/wiki系列与评论条目)。 -
【低】refresh 401/403 即清本地会话,瞬时故障会强制登出
apps/desktop/src/main/cloud/saas-client.ts:1622-1624:refresh 被拒(401/403)立即clearSession()删除本地 refresh token。线上事故背景可以理解,但若 401/403 来自网关瞬时故障/鉴权服务异常(token 实际仍有效),用户被强制登出且无法自愈。可考虑仅在响应体可判定「会话已被吊销/轮换」时才清,至少补一个可观测信号区分两种成因。 -
【低】blockedSources 以服务端错误文案正则为转移,且无清理路径
apps/desktop/src/main/transcription/private-transcription-sync.ts:418:/owned by another account/i匹配错误 message 决定永久拉黑,服务端文案一变即回到无限重排队(正是本 PR 要修的问题);且blockedSources无过期/清理机制(记录被原账号删除后也永不再试)。建议改用结构化判据(如 SaasRequestError 的 status===409 + 稳定错误码)。 -
【低·效率】授权状态轮询每 8s 双份 spawn 子进程且无缓存
apps/desktop/src/main/agent-auth/controller.ts:136-140的status()每次真实 spawnlark-cli --version+auth status(后者每次读系统钥匙串),叠加apps/desktop/src/renderer/src/components/agent/AgentAuthChallengeCard.tsx:20-38的 8s 轮询;SourcesPage 与 Agent 面板的 hook 同时挂载时为双份。建议 controller 侧对环境探测加短 TTL 缓存(网关侧ensureFeishuLarkAuth已有 30s 缓存可对齐)。 -
【低】找回批次轮询连续失败后本地标记语义不准
apps/desktop/src/renderer/src/components/pages/ConnectorDocumentImportPanel.tsx:288-290:找回(resume)路径连续 10 次状态查询失败后把批次在 UI 本地置为cancelled,而网关侧批次可能仍在跑(或已被recoverInterrupted置 failed)——与用户主动取消不可区分;对比 startBatch 路径(:369)是抛错中断。建议统一为「状态未知/失败」语义。 -
【提示】pageSize 非数字时会把
"NaN"传给 CLI
apps/gateway/src/modules/documents/import/lark-action-runner.ts:120:String(Math.min(Number(textValue(input.pageSize) ?? 20), 20))——pageSize 为非数字字符串时 Number→NaN,--page-size NaN直传 CLI。当前适配器恒传数字,仅防御性问题。 -
【提示·可读性】
apps/gateway/src/modules/documents/import/service.ts的materializeRemoteAssets中 try 块内replaceAsync调用未随 try 缩进(约 1259 行起),阅读时容易漏看 try/finally(临时媒体目录清理)边界。
结论
无阻塞发现:未发现可实证的安全/隐私问题、数据丢失、运行时回归或构建/发布失败,故仅以评论提出以上建议,重点跟进第 1、2 条。
此 PR 修改了高风险文件,需要人工批准,不会自动合并。
apps/gateway/package.json
Summary
Test plan