Commit 3fe456f0 authored by AI-甘富林's avatar AI-甘富林

docs(desktop): add expert integration handoff notes

parent e907e347
# 安装包旧 URL 残留与 `_greenlet` 运行时缺陷修复方案
## 1. 背景
当前安装包在 A 电脑上暴露出两类独立问题:
1. 运行时云端地址仍命中旧地址 `https://xuphfkscoptnjoaecbvn.supabase.co/functions/v1`,导致绑定失败。
2. 删除缓存后,应用可以启动,但在专家页触发小红书专家链路时,报错 `DLL load failed while importing _greenlet: 找不到指定的模块。`
结合项目代码与日志,两个问题不是同一个根因:
- 旧 URL 问题来自本地配置项残留,不是 `runtime-cloud-cache.json` 回退。
- `_greenlet` 问题发生在专家页触发的 Python + Playwright 自动化链,不是启动阶段本身失败。
## 2. 现状结论
### 2.1 旧 URL 问题
- 当前默认运行时云端地址已经是新地址:
- `apps/desktop/src/main/services/app-config.ts`
- 但只要本地 `app-config.json` 中存在 `runtimeCloudApiBaseUrl`,运行时就优先使用配置值。
- 启动日志已经明确显示:
- `baseUrl = https://xuphfkscoptnjoaecbvn.supabase.co/functions/v1`
- `baseUrlSource = config`
结论:
- A 电脑不是“删了缓存还在读缓存”,而是“本地配置还保留旧地址”。
- 仅删除 `runtime-cloud-cache.json` 不足以修复;还需要处理 `app-config.json` 中的旧值。
### 2.2 `_greenlet` 问题
- 第二份 startup log 显示应用最终进入 `ready`,说明启动链路本身已完成。
- 专家页小红书项目会进入 Python/Playwright 自动化链。
- 当前运行时探测和 installer smoke 只校验了顶层包能否导入,例如 `playwright`
- 但并没有显式验证:
- `greenlet`
- `from playwright.async_api import async_playwright`
- 专家页真实触发后的项目执行路径
结论:
- 当前安装包验证口径偏浅。
- 安装包即使通过现有 smoke,仍可能在真实专家执行链路里因 `_greenlet` 或其 DLL 依赖失败。
## 3. 修复目标
修复后需要满足以下结果:
1. 旧机器升级或重装后,不会继续使用废弃的 runtime cloud URL。
2. 新机器首次安装时,默认直接使用新地址,无需手工清缓存或改配置。
3. 安装包里的 Python 运行时必须能真实支持专家页小红书链路所需的 Playwright/greenlet 依赖。
4. installer 验证必须能在构建阶段拦截这类问题,而不是等到用户机器上暴露。
## 4. 修复方案
### 4.1 运行时云端地址迁移
`apps/desktop/src/main/services/app-config.ts` 增加已废弃 runtime cloud URL 的迁移逻辑:
- 定义废弃地址列表,至少包含:
- `https://xuphfkscoptnjoaecbvn.supabase.co/functions/v1`
- 在配置加载归一化时,如果 `runtimeCloudApiBaseUrl` 命中废弃地址,则自动替换为当前默认地址:
- `https://spb-bp1wv2oe0hvfvi98.supabase.opentrust.net/functions/v1`
- 替换后立即持久化写回 `app-config.json`
约束:
- 只迁移“已知废弃地址”
- 其他用户手工填写的非空自定义地址仍保留
- 不依赖用户手工删除配置文件
同时补充诊断:
- 启动日志中记录一次配置迁移事件
- diagnostics 中保留运行时云端地址的最终值,并在可能的情况下标记发生过迁移
### 4.2 打包 Python 运行时补齐 `greenlet`
在运行时 Python 依赖定义中显式纳入 `greenlet`,而不是只依赖 `playwright` 的间接依赖关系:
- 更新:
- `build/runtime/python/requirements.in`
- `build/runtime/python/runtime-requirements.lock.txt`
- 确认 `build/scripts/materialize-runtime-payload.ps1` 物化后的运行时 payload 中实际包含对应依赖
目标:
- 安装包中的 `resources/vendor/openclaw-runtime/python` 具备完整依赖
- 不把 `greenlet` 缺失问题留给最终用户机器
如果最终确认 Windows 下还依赖额外系统 DLL 或 VC runtime,则需要二选一:
1. 能随安装包自带则一并处理
2. 不能自带则在运行时探测和错误提示里明确报缺少系统依赖
### 4.3 提升 Python 运行时探测粒度
修改 `packages/runtime-manager/src/index.ts`
- 在运行时探测清单中加入 `greenlet`
- 对关键模块不再只用 `find_spec`
- 至少对以下内容做真实导入探测:
- `import greenlet`
- `from playwright.async_api import async_playwright`
判定规则调整为:
- 只有关键依赖真实可导入时,`pythonReady` 才能为 `true`
- 如导入失败,错误信息要直接反映缺失模块或 DLL 问题
这样可以避免:
- 顶层包存在,但底层二进制扩展无法加载
- 系统显示 `pythonReady = true`,专家页一执行就崩
### 4.4 补强 installer smoke
修改 `build/scripts/installer-smoke.ps1`,把当前浅层导入校验升级为真实关键依赖校验。
现有检查仅覆盖:
- `import playwright`
应至少追加:
- `import greenlet`
- `from playwright.async_api import async_playwright`
若其中任意一步失败,则直接将安装包判定为:
- `payload-validation-failure`
同时在 smoke 输出中增加以下字段,便于回溯:
- `greenletImportProbe`
- `playwrightAsyncImportProbe`
- 对应 stderr 或异常消息
### 4.5 增加专家页真实链路 smoke
在现有 smoke 基础上新增一条安装包级别的真实专家链路验证:
- 启动已安装应用
- 进入 experts 页
- 选择小红书专家
- 发送一条最小测试消息
- 至少验证流程能进入对应 Python 自动化入口,不在 `_greenlet` 处崩溃
该 smoke 不要求真的发布内容,但要覆盖真实调用路径。
目标:
- 防止“安装包通过了基本 smoke,但真实专家链路仍不可用”
### 4.6 优化用户可见错误
当专家页项目执行失败时,错误呈现需要区分:
1. 启动失败
2. 项目执行失败
3. Python 运行时依赖缺失
改进方向:
- 主进程保留完整 stderr 到日志
- UI 不直接暴露生硬 Python 原始异常
-`_greenlet` / DLL 类错误归类为:
- 打包运行时依赖缺失或损坏
- 页面提示用户导出 diagnostics,而不是只看 startup log
## 5. 测试与验收
### 5.1 旧 URL 迁移验证
1. 人工构造包含旧 `runtimeCloudApiBaseUrl``app-config.json`
2. 启动应用
3. 确认配置被自动改写为新地址
4. 确认启动日志记录了迁移行为
5. 确认 runtime-cloud 请求实际打到新地址
### 5.2 Python 运行时验证
1. 在物化后的打包 Python 环境中执行:
- `import greenlet`
- `from playwright.async_api import async_playwright`
2. 验证 `pythonReady` 只有在两者都通过时才为 `true`
3. 人为破坏依赖后,确认系统能明确报错而不是误判 ready
### 5.3 安装包验证
1. 新机器或全新用户目录安装
- 应默认使用新 runtime cloud 地址
2. 带旧配置目录启动
- 应自动迁移旧地址
3. 运行 installer smoke
- 必须通过 `greenlet``async_playwright` 检查
4. 运行专家页真实链路 smoke
- 不应再出现 `_greenlet` 导入失败
## 6. 风险与默认决策
默认决策:
- 旧地址采用自动迁移,不要求用户手工处理
- `greenlet` 作为打包运行时显式依赖维护
- installer smoke 必须覆盖关键二进制依赖的真实导入
- 专家页真实链路增加单独 smoke,不再只依赖浅层 import 检查
当前假设:
- 当前有效 runtime cloud 默认地址保持为 `https://spb-bp1wv2oe0hvfvi98.supabase.opentrust.net/functions/v1`
-`xuphfkscoptnjoaecbvn.supabase.co/functions/v1` 已视为废弃地址
- 小红书专家链路继续基于打包 Python + Playwright 运行
- 旧 URL 问题主要影响升级机或迁移机;`_greenlet` 问题则属于安装包本身质量缺口,新电脑也可能遇到
## 7. 后续执行顺序建议
建议按以下顺序落地:
1. 先修 `app-config` 的旧 URL 自动迁移
2. 再补齐 Python 打包依赖与运行时探测
3. 然后升级 installer smoke
4. 最后补上 experts 页真实链路 smoke 与错误提示优化
这样可以先消除旧机器必现问题,再封堵安装包在新机器上的真实运行风险。
# 桌面端专家工作台侧栏、设置页与窗口拖拽改造方案
## 1. 背景
当前桌面端专家工作台有三类明显体验问题:
1. 左侧栏仍存在空壳专家入口与占位标签,用户会误以为这些专家可用,降低完成度与可信度。
2. 设置页缺少面向内容生产场景的模型配置入口,无法分别配置生图、视频、文案三类模型的 `base_url``api_key`
3. 桌面端窗口存在“拖不动”的问题,影响基础可用性。当前主窗口为无边框窗口,拖拽能力依赖前端显式标记的 drag 区域;现状中仅局部区域设置了 `-webkit-app-region: drag`,而窗口控制按钮区域又被标记为 `no-drag`,导致可拖拽热区不足且不稳定。
本轮目标聚焦为**桌面端 UI 与交互改造**,先把入口、图标、设置页结构、配置保存体验以及窗口拖拽体验整理到位;**本轮不接入抖音专家与小红书专家对这些模型配置的实际消费逻辑**
## 2. 改造目标
改造完成后,应满足以下结果:
- 左侧栏只展示真实可用的专家入口,不再出现空壳项。
- 抖音专家不再使用红书书本语义图标,统一替换为音符风格图标。
- 设置页只保留当前需要暴露的能力:
- 更换龙虾密钥
- 三类专家模型配置
- 工作目录
- 导出诊断
- 生图模型、视频模型、文案模型均支持独立填写:
- `base_url`
- `api_key`
- 上述配置可保存、可回显、可区分“已配置 / 未配置”状态。
- 主窗口在顶部应存在稳定、连续、易命中的可拖拽区域;按钮、输入框、导航等交互控件不误触发拖拽。
- 保持现有底层兼容链路,不影响当前 runtime / cloud / 员工密钥能力。
## 3. 本轮范围
### 3.1 包含内容
#### A. 左侧栏专家区整理
- 删除当前硬编码的空壳专家占位入口。
- 左侧栏只保留真实项目型专家入口。
- 如果 `browser-ops` 仍在真实项目列表中,则继续按真实专家展示。
#### B. 抖音专家图标替换
- 保留小红书专家当前书本风格图标。
- 为抖音专家新增独立的音符 SVG 图标。
- 在左侧栏、专家卡片、专家详情 hero 等平台识别位置统一切换图标映射。
#### C. 设置页结构重做
设置页调整为三块:
1. **基础连接**
- 保留“更换龙虾密钥”入口
- 复用现有员工密钥链路,只改 UI 文案
2. **专家模型配置**
- 生图模型配置
- 视频模型配置
- 文案模型配置
- 每组字段统一为:`base_url``api_key`
- 每组显示独立配置状态与用途说明
3. **诊断与工作区**
- 工作目录
- 导出诊断
#### D. 配置保存与回显
- 前端可编辑三组模型配置。
- 保存后重新进入设置页可以回显:
- `base_url`
- `apiKeyConfigured` 状态
- 不重新输入 `api_key` 时,不应误清空已有 key。
#### E. 窗口拖拽热区修复
- 保证 frameless 主窗口存在稳定的顶部拖拽区域。
- 拖拽热区不能依赖过小或被内容挤压的局部容器。
- 窗口控制按钮、输入框、tab、导航按钮等交互元素明确标记为 `no-drag`
- 拖拽区域应覆盖主要页面共享头部,而不是只在个别页面生效。
### 3.2 明确不做
本轮**不做**以下内容:
- 不修改抖音专家、小红书专家的执行逻辑。
- 不让专家任务在本轮实际读取 `expertModelConfig`
- 不改 `project-skill-router.ts``project-intent-router.ts` 等执行链路来接入这些模型配置。
- 不扩展为新的专家调度策略或模型路由策略。
## 4. UI / UX 设计要求
`ui-ux-pro-max` 约束落地,确保整体偏“科技感、高级感、可操作”。
### 4.1 视觉要求
- 所有新增图标使用 SVG,不使用 emoji。
- 保持深色主题一致性,采用卡片式分区。
- 使用细描边、弱发光、轻层次阴影,避免花哨渐变泛滥。
- 保证文字、边框、状态标签在暗色背景下有足够对比度。
### 4.2 交互要求
- 所有输入框必须保留明确 label,不能仅依赖 placeholder。
- 所有可点击元素提供清晰 hover / focus 状态。
- 触控目标不小于 44px。
- 保存按钮需要明确 loading / disabled 状态,避免重复提交。
- hover 不做位移或缩放导致布局抖动,只做颜色、描边、阴影、透明度变化。
- 可拖拽区域与可交互区域边界明确,避免“想点击却拖动窗口”或“想拖动却无响应”。
### 4.3 信息结构要求
- 旧通用配置项在界面中隐藏:
- `Setup Mode`
- `Provider`
- 通用 `Base URL`
- `Default Model`
- 当前“员工密钥”相关对外文案统一改为“龙虾密钥”。
- 工作目录保留,但视觉优先级低于模型配置区。
## 5. 关键改造点
### 5.1 左侧栏专家入口
**目标文件:** `apps/ui/src/App.tsx`
复用现有真实项目数据链路,去掉现在写死的 placeholder 专家标签,例如:
- `知乎专家`
- `视频号专家`
- 重复的 `抖音专家` 占位项
保留并复用现有:
- `workspace.projects`
- `visibleProjects`
- `expertCards`
- `resolveExpertKey()`
### 5.2 抖音专家图标
**目标文件:** `apps/ui/src/App.tsx`
处理方式:
- `xiaohongshu` 继续使用 `RedBookIcon`
- `douyin` 新增 `DouyinNoteIcon`
- `browser` / `general` 保持现有中性图标
需要统一覆盖以下使用场景:
- 左侧栏专家快捷入口
- 专家卡片
- 专家页 hero / 标题区
- 其他按平台渲染图标的位置
### 5.3 设置页结构与表单
**目标文件:** `apps/ui/src/App.tsx`
建议结构:
- 顶部摘要说明当前页用途
- 中间三张模型配置卡片
- 下方诊断与工作区卡片
三组模型配置建议统一结构:
- 标题
- 简短用途描述
- 已配置 / 未配置状态
- `base_url` 输入框
- `api_key` 密码输入框
### 5.4 配置类型契约
**目标文件:** `packages/shared-types/src/index.ts`
在不破坏现有类型兼容的前提下新增:
- `ModelEndpointConfig`
- `ModelEndpointInput`
- `ExpertModelConfig`
建议结构:
```ts
interface ModelEndpointConfig {
baseUrl: string;
apiKeyConfigured: boolean;
}
interface ModelEndpointInput {
baseUrl: string;
apiKey?: string;
}
interface ExpertModelConfig {
image: ModelEndpointConfig;
video: ModelEndpointConfig;
copywriting: ModelEndpointConfig;
}
```
并扩展:
- `AppConfig.expertModelConfig`
- `SaveConfigInput.expertModelConfig?`
保留旧字段继续存在,避免影响当前其它链路。
### 5.5 配置持久化与密钥存储
**目标文件:**
- `apps/desktop/src/main/services/app-config.ts`
- `apps/desktop/src/main/services/secrets.ts`
- `apps/desktop/src/main/ipc.ts`
- `apps/desktop/src/preload/index.ts`
处理原则:
#### 普通配置
进入 `app-config.json`
- 三组模型配置中的 `baseUrl`
#### 密钥配置
进入 `SecretManager`
- `imageModelApiKey`
- `videoModelApiKey`
- `copywritingModelApiKey`
#### 返回给前端的内容
仅返回:
- `baseUrl`
- `apiKeyConfigured`
不向 renderer 返回明文 secret。
### 5.6 窗口拖拽热区修复
**目标文件:**
- `apps/ui/src/styles.css`
- `apps/ui/src/App.tsx`
- `apps/desktop/src/main/create-window.ts`
现状代码显示:
- 主窗口为 `frame: false`,并使用 `titleBarStyle: "hidden"`,属于需要前端自行提供拖拽热区的无边框窗口。
- 当前 `apps/ui/src/styles.css` 中窗口控制区为 `-webkit-app-region: no-drag`
- 当前仅 `apps/ui/src/styles.css``.page-topbar` 被标记为 `-webkit-app-region: drag`,拖拽区域过于局部。
改造要求:
- 在共享顶栏或稳定头部容器上提供连续 drag 区域。
- 交互控件所在容器统一补 `-webkit-app-region: no-drag`
- 避免 drag 区域被按钮组、表单、滚动容器完全挤占。
- 如现有布局难以保证稳定热区,可增加独立的顶层拖拽条,但必须保持视觉克制,不破坏科技感界面。
## 6. 关键文件
- `apps/ui/src/App.tsx`
- `apps/ui/src/styles.css`
- `apps/desktop/src/main/create-window.ts`
- `packages/shared-types/src/index.ts`
- `apps/desktop/src/main/services/app-config.ts`
- `apps/desktop/src/main/services/secrets.ts`
- `apps/desktop/src/main/ipc.ts`
- `apps/desktop/src/preload/index.ts`
## 7. 复用点
优先复用已有逻辑,避免重复造轮子:
- 专家识别:`apps/ui/src/App.tsx``resolveExpertKey()`
- 专家文案:`apps/ui/src/App.tsx``getExpertGuide()`
- 配置读写:`apps/desktop/src/main/services/app-config.ts``AppConfigService.load()` / `save()`
- 密钥存储:`apps/desktop/src/main/services/secrets.ts``SecretManager`
- 配置桥接:`apps/desktop/src/preload/index.ts``apps/desktop/src/main/ipc.ts` 中现有 `config.load/save`
- 诊断导出:现有 `diagnostics.exportSnapshot()` 链路
- 窗口创建:`apps/desktop/src/main/create-window.ts` 中现有 frameless window 配置
## 8. 验证项
### 8.1 左侧栏验证
- 左侧栏不再出现空壳专家 chip。
- 只展示真实专家入口。
- 抖音专家显示音符图标。
- 小红书专家继续显示书本图标。
### 8.2 设置页验证
- 页面只保留目标项:龙虾密钥、三类模型配置、工作目录、导出诊断。
- 三类模型都能填写 `base_url``api_key`
- 不重新输入 `api_key` 时不会清空已保存密钥。
- 保存后重新进入页面,状态能正确回显。
### 8.3 配置持久化验证
- 重启应用后,三组 `baseUrl` 仍存在。
- 三组 `apiKeyConfigured` 状态正确。
- 原有龙虾密钥链路不受影响。
- 原运行时与云端配置链路不受影响。
### 8.4 窗口拖拽验证
- 主窗口顶部存在稳定可拖拽区域。
- 在聊天页、专家页、设置页都能正常拖动窗口。
- 点击最小化、最大化、关闭按钮不会误触发拖拽。
- 点击输入框、按钮、导航项、专家卡片时不会因为 drag 区域覆盖而失去交互。
- Windows 下拖拽体验连续,不出现“只有局部像素能拖动”的情况。
### 8.5 交互与视觉验证
- 深色主题下文本、边框、状态标签清晰可读。
- 输入框 focus 态清楚。
- 按钮 hover / disabled / loading 态明确。
- 无布局抖动、无误导性占位入口。
## 9. 建议落地顺序
1. 先改 `shared-types`,补齐三类模型配置契约。
2. 再改 `app-config` / `secrets` / `ipc` / `preload`,打通保存与回显。
3. 处理窗口拖拽热区:
- 梳理共享头部结构
- 明确 drag / no-drag 分区
- 回归聊天页、专家页、设置页
4. 最后集中改 `apps/ui/src/App.tsx`
- 清理左侧栏空壳专家
- 替换抖音图标
- 重做设置页布局与交互
5. 最后做桌面端手动回归与 smoke 验证。
# 2026-04-16 桌面端专家入口问题交接
## 背景
本轮处理的是桌面端以下问题:
1. 小红书和抖音专家页不显示
2. 内容账号规划专家、知乎专家是否为独立专家要按项目事实核查
3. 左侧栏多数专家点不了,要求除独立专家外其余专家点击后跳首页对话
4. 左侧专家列表过长,挤占会话管理,需要独立滚动
5. 首页对话发送“你好”仍路由到抖音,且消息马上消失
## 已完成
### 1. 修复首页快捷专家不可点击
文件:
- `apps/desktop/src/main/services/expert-catalog.ts`
改动:
- `promptAvailable` 由“仅检查 promptFile 是否存在”改为:
-`starterPrompt` 即可用
-`promptFile` 文件存在也可用
影响:
- 公众号专家、X 专家、Tiktok 专家、海报专家、GEO 专家、平台精准线索专家恢复可点击
### 2. 修复首页对话串到抖音、消息消失
文件:
- `apps/ui/src/App.tsx`
改动:
- `chat` 视图发送时,优先使用 `home-chat``sessionScopeProjectId`
- 不再优先使用 `workspace.currentProjectId`
- 新增 `openHomeChat()`,保证切回首页对话时同步归一到 `home-chat`
- 左侧“对话”导航点击改为走 `openHomeChat()`
- 首页快捷专家点击也改为走 `openHomeChat(true)`
影响:
- 首页对话不再把消息建进抖音项目
- 消息不会因为会话作用域错位而“发送后消失”
### 3. 恢复专家页真实项目来源
文件:
- `apps/ui/src/App.tsx`
改动:
- 新增 `buildProjectExpertDefinition()`
- 新增 `projectExpertEntries`
- `expertPageProjects` 不再只取 `standaloneExpertEntries`
- 改为基于真实 `visibleProjects` 生成专家页项目
影响:
- 仓库里真实存在的 `xhs` / `douyin` 项目可以重新进入专家页
- 左侧专家栏也改为优先显示真实项目专家,再拼首页快捷专家
### 4. 修复左侧栏滚动布局
文件:
- `apps/ui/src/styles.css`
改动:
- `sidebar-bottom` 改为两段式布局
- 新增 `.sidebar-expert-scroll`
- 新增 `.sidebar-session-section`
- 让专家区和会话区分别滚动
影响:
- 专家列表过长时,不再把会话管理区整体挤没
### 5. 补齐 smoke 类型定义
文件:
- `apps/ui/src/App.tsx`
改动:
- `SmokeUiSnapshot` 新增 `sessionScopeProjectId`
目的:
- 修复 `typecheck` 因 smoke 快照字段缺失导致的编译错误
## 已验证
已通过:
- `corepack pnpm typecheck`
- `powershell -ExecutionPolicy Bypass -File build/scripts/default-chat-smoke.ps1`
- `powershell -ExecutionPolicy Bypass -File build/scripts/project-routing-smoke.ps1`
- `powershell -ExecutionPolicy Bypass -File build/scripts/desktop-expert-entry-smoke.ps1 -SkipMaterializeRuntime`
`desktop-expert-entry-smoke` 已覆盖:
- `content-account-planning`
- `zhihu`
- `wechat-official-account`
- `x-platform`
- `tiktok`
- `poster`
- `geo`
- `precision-leads`
## 关键事实结论
### 1. 小红书 / 抖音专家页消失的主因
不是项目没了,是前端把专家页数据源改成只看 `standalone` 专家定义,导致真实项目 `workspace/xhs``workspace/douyin` 被过滤掉。
### 2. 其他专家点不了的主因
不是按钮组件坏了,是可用性判定错了。首页快捷专家只有 `starterPrompt`,没有 `promptFile`,因此被错误判成不可用。
### 3. 内容账号规划专家 / 知乎专家当前状态
按仓库事实,它们当前仍不是“仓库内已落地的真实独立专家项目”。
说明:
- 当前仓库 `workspace/` 下没有它们对应真实项目目录
- 但 smoke 已经证明:当用户数据里存在对应项目时,UI 入口和会话隔离链路可以工作
结论:
- 现在更准确的说法是:入口机制和隔离路由已支持
- 但仓库内真实项目包还没补齐
## 当前未完成
### 1. 肉眼页面确认未完成
原因不是代码未生效,而是本机存在一个旧的 Electron 进程:
- `PID 20424`
表现:
- 我已执行 `corepack pnpm build`
- 新的 renderer 已成功输出到 `apps/desktop/dist/renderer`
- 但旧进程无法被我当前环境结束,导致用户看到的仍可能是旧界面
### 2. 旧进程状态
用户侧执行过:
```powershell
taskkill /PID 20424 /F /T
```
结果:
- 失败
- 提示该进程属于父进程 `23116` 的子进程
- 原因是 `拒绝访问`
结论:
- 最稳妥处理是重启机器
## 已完成但需要用户重启后确认的点
重启后需要肉眼确认:
1. 左侧或专家页是否能看到“小红书专家”“抖音专家”
2. 点击公众号/X/Tiktok/海报/GEO/平台精准线索,是否跳转首页对话,而不是进入专家页
3. 首页发送“你好”,是否仍会跑到抖音
4. 发送后的消息是否还会消失
5. 左侧专家区和会话区是否都可以独立滚动
## 重启后继续执行顺序
1. 先启动桌面端
2. 先看小红书 / 抖音专家是否出现
3. 再测首页快捷专家跳转是否正确
4. 再测首页发送“你好”
5. 若页面仍不对,先确认是否真的是新进程和新包
## 如果重启后仍异常,优先检查
### A. 是否加载了新 renderer
重点看:
- `apps/desktop/dist/renderer/index.html`
- `apps/desktop/dist/renderer/assets/index-*.js`
### B. 是否仍有旧 Electron 残留
命令:
```powershell
Get-Process | Where-Object { $_.ProcessName -match 'electron|QianjiangClaw' } | Select-Object Id,ProcessName,Path
```
### C. 如果页面还是没有小红书 / 抖音专家
继续检查:
- `workspace.getSummary()` 返回的 `workspace.projects`
- `visibleProjects`
- `projectExpertEntries`
- `expertPageProjects`
## 相关文件
- `apps/ui/src/App.tsx`
- `apps/ui/src/styles.css`
- `apps/desktop/src/main/services/expert-catalog.ts`
## 备注
本轮没有继续接“龙虾密钥真实绑定态页面验证”,因为用户当前首先反馈的是“小红书和抖音专家在页面上仍没看到”,而该现象与旧 Electron 残留更直接相关。后续等重启后再继续做真实页面 smoke。
# 2026-04-17 客户端模型配置打通进度
## 目标
让客户在桌面客户端自行配置项目所使用的模型信息,不依赖项目包内固定写死;项目从云端配置接口拉取 zip 并解压后,实际执行时由客户端把模型配置注入到项目运行时。
## 已完成
### 1. 客户端配置结构已支持 `modelId`
- 已扩展共享类型,`expertModelConfig.image/copywriting/video` 均支持 `modelId`
- 已扩展桌面端配置持久化与归一化逻辑,保存后不会丢失 `modelId`
- 已扩展 IPC 返回值,前端加载配置时可以拿到 `modelId`
涉及文件:
- [packages/shared-types/src/index.ts](D:/qjclaw/packages/shared-types/src/index.ts)
- [apps/desktop/src/main/services/app-config.ts](D:/qjclaw/apps/desktop/src/main/services/app-config.ts)
- [apps/desktop/src/main/ipc.ts](D:/qjclaw/apps/desktop/src/main/ipc.ts)
### 2. 客户端设置页已可配置项目模型
- 已在设置页增加图片模型 `model_id` 输入
- 已在设置页增加文案模型 `model_id` 输入
- 保存设置后,冒烟态和配置回显会校验 `modelId`
涉及文件:
- [apps/ui/src/App.tsx](D:/qjclaw/apps/ui/src/App.tsx)
### 3. 项目运行前注入逻辑已打通
- 新增项目运行时模型注入服务
- 在执行 `workspace_entry.py` 前,根据当前项目 ID 和客户端已保存配置生成 `memory/project.env`
- 同时把生成后的环境变量注入子进程,确保项目执行链路可直接读取
当前已支持:
- `xhs`
- `QWEN_BASE_URL`
- `QWEN_API_KEY`
- `QWEN_MODEL`
- `QWEN_VISION_MODEL`
- `XHS_IMAGE_PROVIDER=env:xhsImage`
- `XHS_IMAGE_BASE_URL`
- `XHS_IMAGE_API_KEY`
- `XHS_IMAGE_MODEL`
- `douyin`
- `DOUYIN_WRITER_LLM_BASE_URL`
- `DASHSCOPE_API_KEY`
- `QWEN_API_KEY`
- `DOUYIN_WRITER_LLM_MODEL`
- `SEEDREAM_ARK_BASE_URL`
- `SEEDREAM_ARK_API_KEY`
- `SEEDREAM_MODEL`
涉及文件:
- [apps/desktop/src/main/services/project-model-runtime.ts](D:/qjclaw/apps/desktop/src/main/services/project-model-runtime.ts)
- [apps/desktop/src/main/services/project-workspace-executor.ts](D:/qjclaw/apps/desktop/src/main/services/project-workspace-executor.ts)
- [apps/desktop/src/main/ipc.ts](D:/qjclaw/apps/desktop/src/main/ipc.ts)
### 4. 打包链路和端到端冒烟已验证通过
- `corepack pnpm typecheck` 通过
- `corepack pnpm package` 通过
- 安装器冒烟通过
- `xhs` 云端 zip -> 解压 -> 激活项目 -> workspace-entry -> `project.env` 注入 冒烟通过
- `douyin` 云端 zip -> 解压 -> 激活项目 -> workspace-entry -> `project.env` 注入 冒烟通过
结果文件:
- [installer-smoke-result.json](D:/qjclaw/.tmp/installer-smoke/20260416-221908/installer-smoke-result.json)
- [xhs result.json](D:/qjclaw/.tmp/xhs-expert-cloud-bundle-smoke/result.json)
- [douyin result.json](D:/qjclaw/.tmp/douyin-expert-cloud-bundle-smoke/result.json)
对应冒烟脚本:
- [build/scripts/installer-smoke.ps1](D:/qjclaw/build/scripts/installer-smoke.ps1)
- [build/scripts/xhs-expert-cloud-bundle-smoke.ps1](D:/qjclaw/build/scripts/xhs-expert-cloud-bundle-smoke.ps1)
- [build/scripts/douyin-expert-cloud-bundle-smoke.ps1](D:/qjclaw/build/scripts/douyin-expert-cloud-bundle-smoke.ps1)
- [apps/desktop/src/main/index.ts](D:/qjclaw/apps/desktop/src/main/index.ts)
## 当前未完成
### 1. 视频模型链路暂未纳入本次范围
- 当前只重点打通了图片模型和文案模型
- `video.modelId` 类型和配置持久化已预留
- 但视频模型的运行时注入、前端独立配置项联动、项目实际消费逻辑,本次未继续展开
### 2. 目前是“客户端本地配置生效”,不是“云端统一下发模型配置”
- 现在已经支持客户在本机客户端配置模型并立即作用于项目执行
- 但还没有把这份模型配置并入远端配置中心做统一下发
- 如果后续要做多端一致、换机继承、后台代运营配置,需要再单独设计云端配置存储和同步
### 3. 还没有单独补业务说明文档
- 当前代码和烟测已齐
- 但还没有补一份给实施/运维/客户的“字段含义、支持项目、配置示例、常见错误”操作文档
## 结论
当前“客户在客户端配置模型 -> 项目从云端拉 zip -> 客户端解压并执行 -> 执行前注入模型环境变量”主链路已经打通,并已通过打包后的端到端冒烟验证。
如果下一步继续推进,优先级建议是:
1. 补一份面向实施和客户的配置说明文档
2. 决定是否要把模型配置接入云端配置中心
3. 视业务需要再补视频模型链路
# 2026-04-13 代码事实完成度盘点
本文件基于当前仓库代码、workspace 产物和 `.tmp` 验收结果整理,不直接复述历史进度文档。
## 已完成
### 1. Python 运行时依赖与安装包校验链路已补齐
- `packages/runtime-manager/src/index.ts` 已把 `greenlet``playwright``edge-tts``python-dotenv``pillow` 纳入运行时导入校验。
- `build/scripts/installer-smoke.ps1` 已对上述依赖做模块探测。
- `.tmp/installer-smoke/20260410-162021/installer-smoke-result.json` 显示安装包冒烟为成功结果。
结论:
运行时缺依赖导致的新电脑安装后无法启动项目的问题,已经进入“有代码防线 + 有安装包验收”的状态。
### 2. XHS / Douyin 项目包标准化已基本落地
- `workspace/xhs/project.json``workspace/douyin/project.json` 都已存在,并声明 `workspaceAutomation``defaultEntry``boundSkillIds``bundlePackaging` 等关键字段。
- `apps/desktop/src/main/services/project-bundle.ts` 已要求项目必须带 `project.json`,并在打包时保留 `memory``sessions.json``session-messages` 等目录。
结论:
两套项目已经不是“散目录脚本集合”,而是进入标准项目包形态。
### 3. 项目级 skill 绑定与隔离逻辑已实现
- `apps/desktop/src/main/services/project-store.ts` 已按项目处理 `boundSkillIds`,并在 bundle 同步时核对声明与实际 materialized skill 的交集。
结论:
项目技能来源已经收敛到项目自身声明,不再是完全依赖 home 全局状态。
### 4. 客户端附件到项目执行器的主链路代码已打通
- `apps/ui/src/App.tsx` 已支持发送附件。
- `apps/desktop/src/preload/index.ts``apps/desktop/src/main/ipc.ts``apps/desktop/src/main/services/project-workspace-executor.ts` 已把附件传入项目执行层。
- 执行环境中已注入 `QJC_PROJECT_ATTACHMENTS_JSON``QJC_PROJECT_MAIN_IMAGE` 等变量。
- `workspace/douyin/workspace_entry.py``workspace/xhs/workspace_entry.py` 已读取附件信息。
结论:
附件链路的第一批最小闭环代码已经落地,至少从 UI 到 workspace entry 的传递关系在代码上成立。
### 5. 云端 bundle 冒烟链路已有成功结果
- `build/scripts/douyin-expert-cloud-bundle-smoke.ps1`
- `build/scripts/xhs-expert-cloud-bundle-smoke.ps1`
- `.tmp/douyin-expert-cloud-bundle-smoke/result.json`
- `.tmp/xhs-expert-cloud-bundle-smoke/result.json`
结论:
XHS / Douyin 专家项目包至少已经能被当前 smoke 链路拉起并完成基础校验。
### 6. Douyin 已有新的真实成功样例
- `workspace/douyin/memory/output/卖苹果宣传短视频/workflow_summary.json` 显示阶段为 `video_generated`
- `workspace/douyin/memory/output/卖苹果宣传短视频/video_generation_status.json` 显示状态为 `success`
- `workspace/douyin/memory/output/内裤推荐短视频/workflow_summary.json` 也显示成功完成出片。
结论:
Douyin 不是只完成了代码改动,当前仓库内已经有至少两条新的真实出片成功证据。
## 未完成或仍不能按“已验收完成”算
### 1. 还不能认定“新电脑安装后正式链路已最终封口”
虽然 `apps/desktop/src/main/services/cloud-api.ts` 已有员工配置接口和 `download_url` 处理逻辑,但当前仓库里能直接看到的主要是 smoke 成功结果,还不足以证明以下事项已经在正式链路下全部完成最终验收:
- 安装客户端
- 拉取正式员工配置
- 下载项目 zip
- XHS / Douyin 双项目都在最新标准下完成真实运行
结论:
相关代码存在,但“正式环境最终验收关闭”这件事不能仅凭当前仓库证据判定为完成。
### 2. 附件业务链缺少专项验收闭环
虽然附件透传代码已经齐了,但当前没有看到明确的“上传真实图片后,Douyin / XHS 业务任务成功完成”的专项 smoke 或端到端验收结果。
结论:
附件链路可以判定为“代码已落地”,还不能判定为“业务验收已完成”。
### 3. XHS 缺少基于最新标准包的最新 fresh 验收证据
当前能看到的较强 fresh-like 结果是 `.tmp/real-xhs-fresh-smoke-3/result.json`,时间是 2026-04-08,不是本轮 2026-04-10 标准化之后重新产出的结果。
结论:
XHS 仍建议在最新 runtime / bundle / smoke 标准下再做一次 fresh 验收。
### 4. 历史失败案例没有全部回归
- `workspace/douyin/memory/output/我们家的苹果/workflow_summary.json` 仍是失败记录。
结论:
当前状态可以证明“已有成功样例”,但不能证明“历史问题案例已全部清零”。
### 5. 工作区根目录历史遗留尚未清理完
`workspace/xhs``workspace/douyin` 根目录下仍有较多旧目录、脚本和历史运行产物。
结论:
标准项目包虽然已建立,但“源目录收尾清理完成”这件事还不能算结束。
## 当前判断
如果按“代码是否已经落地”看,本轮主要骨架已经完成:
- 运行时依赖补齐
- 项目包标准化
- 项目技能绑定
- 附件透传主链
- 云端 bundle smoke
- Douyin 成功样例产出
如果按“是否已经最终验收关闭”看,剩余重点仍然是:
1. 正式员工配置下载 zip 链路的最终验收
2. 附件业务链专项验收
3. XHS 在最新标准下的 fresh 复验
4. 历史失败案例回归
5. workspace 根目录历史遗留清理
一句话结论:
当前已经完成“能安装、能识别项目、能进入项目、能启动项目运行时,并且 Douyin 已有新的真实成功样例”,但还没有完成“新电脑安装客户端后,XHS 和 Douyin 从正式配置链路拉起后即可直接验收关闭”的最终封口。
## 2026-04-13 补充进展
### 本轮已完成
#### 1. Experts 附件 smoke 已从“只验证 launch”收紧到“验证附件进入项目执行层”
- `build/scripts/douyin-expert-cloud-bundle-smoke.ps1` 已补充真实图片夹具、附件透传和落盘校验。
- `build/scripts/xhs-expert-cloud-bundle-smoke.ps1` 已补充真实图片夹具、附件透传和落盘校验。
- `apps/ui/src/App.tsx``apps/desktop/src/main/index.ts` 的配套改动已经进入构建产物并完成重跑。
- 结果上,Douyin / XHS smoke 都已经能验证附件进入 `inputs/images/main/`,不再只是验证 `workspace-entry` 被拉起。
结论:
“客户端带图 -> 主进程项目目录落盘 -> workspace-entry 可感知附件” 这一层已经从“代码已落地”推进到“执行层 smoke 已补齐”。
#### 2. Douyin 已补齐一条带附件的真实 live-run 验收
- 新增 `build/scripts/douyin-expert-live-run.ps1`,并补充到 `build/scripts/README.md`
- live-run 已验证:
- 从 experts 页发起,而不是 skill fallback
- 附件先进入项目根目录 `inputs/images/main/`
- 业务工作流再把图片带入输出目录
- 产出 `_latest_workflow_summary.json``video_request.json``omnihuman_prompt.txt` 等预览产物
- `.tmp/douyin-expert-live-run/result.json` 已显示当前项目为 `douyin`,并且 `workspaceAttachmentPath``projectMainImagePath` 都存在。
结论:
Douyin 现在不只是“附件能传入执行层”,而是已经有“带附件的真实项目 live-run”证据。
#### 3. XHS 的真实卡点已缩小到“项目脚本与桌面运行时配置不兼容”
- `build/scripts/xhs-expert-live-run.ps1` 已补齐 live-run 脚本,并能稳定把请求推进到 `workspace-entry`
- `.tmp/xhs-expert-live-run-4321/result.json.trace.log` 说明 `workspace-launch-accepted` 已发生。
- `.tmp/xhs-expert-live-run-4321/user-data/projects/xhs/memory/xhs_profile``openclaw_runs/xhs_*.json` 已生成,说明项目脚本已经开始真实运行。
-`xhs_last_note.json` 未生成,`daily-reports/state.json` 里记录了 `chat_stream_failed`
- 对照 `apps/desktop/src/main/services/project-workspace-executor.ts``.tmp/xhs-expert-live-run-4321/user-data/runtime/state/openclaw.runtime.json` 可以确认:
- 桌面项目执行时会注入 `OPENCLAW_CONFIG_PATH`
- 当前注入的 runtime config 里有 `modelstudio``openclaw-cloud``custom-open-bigmodel-cn`
- 没有 `models.providers.qwen`
- 也没有 `models.providers.xhsImage`
-`workspace/xhs/scripts/qwen.py` / `workspace/xhs/scripts/run.py` 仍然硬编码依赖 `qwen``xhsImage`
结论:
XHS 当前不是“项目完全不可用”,而是“在新的桌面项目运行时链路下,模型配置适配没有完成”。这已经是定位清楚的实现问题,不再是模糊的 smoke 现象。
### 本轮未完成
#### 1. XHS live-run 还没有闭环成功
虽然 XHS 已经证明:
- experts 页命中正确
- workspace-entry 启动正确
- 项目脚本实际开始执行
- 附件进入项目上下文
但还没有做到:
- 成功写出 `xhs_last_note.json`
- 成功写出 `memory/generated_images`
- 成功返回完整 assistant 结果
结论:
XHS 仍处于“根因已定位,修复未完成”的阶段。
#### 2. 统一模型配置方案还没有落地
目前项目侧仍然存在较强的“项目私有 provider 名”假设,例如:
- XHS 依赖 `qwen`
- XHS 生图依赖 `xhsImage`
- Douyin 也存在自己的模型 / 供应商命名
而目标方向已经明确应该是:
- 文案模型
- 视觉分析模型
- 生图模型
- 视频模型
都逐步收口到客户端统一配置,再由执行器注入给项目。
结论:
当前只是进入了“发现并开始修这类兼容问题”的阶段,还没有完成统一模型角色抽象。
### 长期展望
#### 1. 项目不再直接读取 provider 名,而是读取统一模型角色
长期目标不应是继续让每个项目自己维护 `qwen``xhsImage``volces` 这类私有 provider 名,而应是:
- 项目只表达能力需求:文案、视觉分析、生图、视频
- 客户端设置决定这些能力最终映射到哪个 provider / model
- 执行器把统一结果注入给项目运行环境
这样做的好处是:
- 客户端设置可以统一收口
- 项目迁移成本更低
- XHS / Douyin / 后续项目都能复用一套模型配置协议
#### 2. 短期修复仍要兼容旧项目,避免一次性硬切
落地路径更适合分两步:
1. 先让现有项目“优先读统一注入,兼容旧字段”
2. 等客户端设置完成后,再逐步移除项目内私有 provider 假设
结论:
短期要以“先跑通 XHS 验收链路”为目标,长期要以“客户端统一模型配置,项目只读抽象角色”为目标。
## 2026-04-13 XHS live-run 最新代码事实
### 已完成
- `workspace/xhs/scripts/qwen.py`
- 已支持从桌面端执行器注入的 managed config 解析文本模型,不再要求项目内必须存在 `models.providers.qwen`
- `workspace/xhs/scripts/run.py`
- 已支持在视觉模型不具备图片输入能力时自动降级为纯文本参考分析。
- 已支持在缺少可用生图 provider 时,复用项目主图/附件图写入 `memory/generated_images`,避免桌面端 XHS 项目因 provider 命名不兼容而整条链路失败。
- `build/scripts/xhs-expert-live-run.ps1`
- 2026-04-13 已基于最新项目脚本重跑成功,输出目录为 `D:\qjclaw\.tmp\xhs-expert-live-run-4322`
- 本次 live-run 结果
- `latestNotePath = D:\qjclaw\.tmp\xhs-expert-live-run-4322\user-data\projects\xhs\memory\openclaw_runs\xhs_last_note.json`
- `generatedImageCount = 1`
- `generatedImages[0] = D:\qjclaw\.tmp\xhs-expert-live-run-4322\user-data\projects\xhs\memory\generated_images\xhs_attachment_1776060534_01.png`
- `workspaceAttachmentPath` 存在。
- `xhsProfilePath` 存在。
### 未完成
- 客户端统一生图模型配置尚未落地。
- 当前 XHS live-run 虽已闭环,但图片产物来自附件兜底复用,不是客户端统一生图模型真正产出。
- 项目侧仍然存在兼容层逻辑。
- 现在的方向是“优先读取客户端 managed config,同时兼容旧项目字段”,还没有进入“项目只读统一模型角色、彻底去掉私有 provider 名”阶段。
### 长期方向不变
- 所有项目的文案模型、视觉分析模型、生图模型、视频模型,最终都应由客户端设置统一配置。
- 项目侧只声明能力角色,不再硬编码 `qwen``xhsImage``volces` 这类 provider 名。
- 本次 XHS 修复方向与该长期目标一致,因为它是在去掉项目对私有 provider 名的强绑定,而不是继续加深这种耦合。
## 2026-04-13 云端 bundle / 安装包最新补充
### 已完成
- 已确认 `Project bundle freshness probe failed with HTTP status 400` 的根因不是当前云端最新 `xhs/douyin` zip 不可用,而是本地残留旧 bundle 记录仍指向历史 URL。
- 已直接验证:
- 新下发 `1776065005429-xhs_4_.zip``1776065250716-douyin_3_.zip``HEAD/GET` 均为 `200`
- 旧残留 `1775532407762-xhs.zip``1775788003542-xiaohongshu-writer.zip``HEAD/GET` 均为 `400`
- 已在 `apps/desktop/src/main/services/project-bundle.ts` 增加按 asset 维度的远端 bundle 容错:
- `freshness probe` / `download` 失败不再默认炸掉整轮 startup
- 已有本地项目缓存时允许复用本地项目
- 无本地缓存且远端失败时允许跳过坏 asset,避免阻断其他项目
- 上述修复已通过 `corepack pnpm typecheck`
- 已重新执行 `corepack pnpm package`,最新安装包已产出:
- `D:\qjclaw\dist\installer\QianjiangClaw-Setup-0.1.0.exe`
### 未完成
- 真实安装包验证仍未最终闭环。最新阻塞点已经从“旧 URL 400”切换为“本地目录被占用无法清理”:
- `Project bundle replacement target could not be cleared: C:\Users\EDY\AppData\Roaming\@qjclaw\desktop\projects\xhs`
- `C:\Users\EDY\AppData\Roaming\@qjclaw\desktop\projects\xhs` 当前已被清到空目录状态,但目录壳子本身仍被本地进程句柄占用,导致:
- `backup-rename` 持续 `EBUSY`
- `backup-copy``remove-path(requireMissing)` 仍失败
- 因此,“最新安装包 + 真实云端配置接口 + 本机已有脏缓存”这条最终验收链路目前还不能判定为完成。
### 当前判断
- 代码层面,旧 bundle URL 400 已完成根因定位并已补充容错,不再是主要阻塞。
- 运行层面,当前主要问题是本机 `AppData` 工作区目录锁,属于本地文件系统/进程占用问题,而不是云端最新 `douyin/xhs` zip 本身不可拉取。
- 只要本机先释放并清理 `C:\Users\EDY\AppData\Roaming\@qjclaw\desktop\projects\xhs` 这个空目录壳子,当前安装包即可继续验证最新云端 bundle。
### 下一步建议
1. 完全退出客户端并结束本机残留 `QianjiangClaw.exe` / 相关 `electron.exe` 进程。
2. 手动删除 `C:\Users\EDY\AppData\Roaming\@qjclaw\desktop\projects\xhs`;若仍删不掉,重启后优先删除。
3. 如需一次性清干净,可直接清理整个 `C:\Users\EDY\AppData\Roaming\@qjclaw\desktop` 工作区,再用最新安装包重新绑定验证。
4. 清理本地目录锁后,再继续验证“真实云端配置接口下发 zip -> 客户端同步 -> 抖音/小红书专家可用”这条最终链路。
宿主协议不一样。ing Claude's current work───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
──简短结论───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
E:\originzip\xiaohongshu-writer─是─本地 OpenClaw 插件形态,不是─桌面客户端 bundle/workspace 形态。─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
所以在本地 OpenClaw 里,它只要能加载插件和技能就能跑;但在客户端里,宿主需要的不只是技能目录,还需要一套可打包、可注入上下文、可隔离运行态、可稳定调度的工作区协议。
---
为什么本地能跑,客户端不行
1. 源项目是“插件”,不是“workspace automation project”
你这个源项目的形态很明确:
- E:\originzip\xiaohongshu-writer\package.json:4 用的是 openclaw.extensions
- E:\originzip\xiaohongshu-writer\openclaw.plugin.json:1 开始是插件描述
- E:\originzip\xiaohongshu-writer\openclaw.plugin.json:4-9 直接列 skills
也就是说,它的假设是:
- 宿主会按 插件机制 加载
- 宿主认识 openclaw.plugin.json
- 宿主会把 index.js 扩展跑起来
- skills 按插件规则注册
而工作区版 xhs 已经变成了另一套协议:
- D:\qjclaw\workspace\xhs\project.json:4 projectType: "automation-project"
- D:\qjclaw\workspace\xhs\project.json:7-18 workspaceAutomation.script: "workspace_entry.py"
- D:\qjclaw\workspace\xhs\project.json:82-89 boundSkillIds、workspaceEntryEnabled
客户端要的不是“有几个 skills 就行”,而是“这是一个我能托管的 automation project”。
---
2. 客户端需要一个统一入口,不是直接猜怎么跑脚本
源项目的脚本是 CLI 风格的:
- E:\originzip\xiaohongshu-writer\scripts\run.py:1-11 就是在定义命令行入口
- E:\originzip\xiaohongshu-writer\scripts\run.py:27-35 直接本地改 sys.path 并导入脚本模块
- E:\originzip\xiaohongshu-writer\scripts\run.py:134-137 还直接把 debug_search.jpg 写当前目录
这类脚本的前提是:
- 你知道从哪个命令启动
- 你知道传什么参数
- 你知道当前工作目录是什么
- 你知道输出文件落哪
桌面客户端不能靠“猜”这些事情,所以工作区版才会加:
- D:\qjclaw\workspace\xhs\workspace_entry.py:28-37 统一入口与运行脚本位置
- D:\qjclaw\workspace\xhs\project.json:7-18 明确告诉客户端入口脚本和参数模板
也就是说,客户端不是不能执行 scripts/run.py,而是它需要一个稳定入口层来把自然语言请求转换成可执行脚本调用。
---
3. 客户端需要上下文注入,源项目没有这层协议
工作区版 workspace_entry.py 明显承担了宿主桥接职责:
- D:\qjclaw\workspace\xhs\workspace_entry.py:28 QJC_WORKSPACE_EVENT
- D:\qjclaw\workspace\xhs\workspace_entry.py:77-103 load_project_identity() / render_context_prelude()
- D:\qjclaw\workspace\xhs\workspace_entry.py:116-126 load_project_attachments()
这说明客户端运行时不只是“执行脚本”,还要处理:
- 当前项目身份
- 当前 prompt 上下文
- 用户附件
- 宿主和项目之间的事件通信
本地 OpenClaw 插件模式里,这些能力可能是宿主内部直接提供的,或者根本不需要 project workspace 这层包装。
但桌面客户端 bundle 里,如果没有这层桥接,skills/scripts 并不知道:
- 当前用户是在让它“生成笔记”还是“直接发布”
- 当前会话带了哪些附件
- 当前项目应该把上下文隔离到哪里
---
4. 客户端必须做运行态隔离,源项目默认是“本地目录式”
工作区版 xhs 明确把运行态收口到 memory/:
- D:\qjclaw\workspace\xhs\workspace_entry.py:29-34
- MEMORY_ROOT
- RUNS_ROOT
- GENERATED_ROOT
- PROFILE_ROOT
还统一注入环境变量:
- D:\qjclaw\workspace\xhs\workspace_entry.py:129-137
- XHS_MEMORY_ROOT
- XHS_PROFILE_DIR
- XHS_ENV_PATH
而源项目脚本更像默认直接在项目目录跑:
- E:\originzip\xiaohongshu-writer\scripts\run.py:134-137 当前目录写 debug_search.jpg
这在“本地手动跑项目”时问题不大,但在桌面客户端里会有几个问题:
1. bundle 可能解压到临时目录
2. 客户端需要每个项目状态隔离
3. 浏览器 profile / 生成文件 / 缓存文件不能乱落
4. Windows 下路径、权限、清理策略更敏感
所以不是“多做了很多没必要的改动”,而是客户端要把一个原本“开发者自己跑的 repo”,变成“宿主可控的项目单元”。
---
5. 源项目里的插件声明本身就不适合直接打包搬进客户端
这个点很关键:
- E:\originzip\xiaohongshu-writer\openclaw.plugin.json:4-9 里的 skills 路径是绝对路径
指向 C:\Users\15153476162\.openclaw\workspace\projects\xiaohongshu-writer\skills\...
这说明原项目默认假设:
- 它运行在某个固定的本地 OpenClaw 目录结构下
- 宿主知道这个目录布局
- 这个用户路径存在
但客户端 bundle 不能依赖用户机器上有这套固定目录,更不能依赖某个绝对路径。
所以工作区版才改成相对项目根的协议化入口。
---
6. 客户端不仅要“能跑”,还要“能识别能力”
工作区版 project.json 还声明了:
- D:\qjclaw\workspace\xhs\project.json:44-80 defaultEntry / entries
- D:\qjclaw\workspace\xhs\project.json:47-59 intentAliases / capabilities
这对客户端很重要,因为客户端要知道:
- 用户说“写一篇小红书”时该路由到哪个项目
- 这个项目支持什么能力
- 默认入口是什么
而本地插件模式里,skills 可能只是注册后由 OpenClaw 自己管理;桌面客户端如果只“扫目录”,它不知道该怎么做稳定路由和展示。
---
所以“为什么不能直接跑”
因为客户端要解决的是这 4 件事,而源项目只覆盖了其中一部分:
1. 项目识别
源项目:插件识别
客户端:workspace/automation project 识别
2. 入口调度
源项目:人手动/插件机制启动
客户端:统一入口、统一参数、统一路由
3. 上下文与附件
源项目:弱约束或宿主内置
客户端:显式协议注入
4. 运行态治理
源项目:本地 repo 风格
客户端:隔离、可打包、可迁移、可清理
---
你可以把它理解成
E:\originzip\xiaohongshu-writer 更像:
▎ “一个能在本地 OpenClaw 环境里被插件机制加载的项目”
而 D:\qjclaw\workspace\xhs 更像:
▎ “一个能被桌面客户端当成独立工作区项目稳定托管的项目”
两者不是业务代码能不能跑的问题,主要是宿主集成层不一致。
---
哪些改动其实就是在补这个“宿主集成层”
最核心就是这几类:
- 插件形态 → workspace project 形态
- package.json/openclaw.plugin.json → project.json
- 无统一入口 → 有统一入口
- workspace_entry.py
- 脚本直跑 → 宿主桥接后再跑脚本
- prompt / attachment / event / env 注入
- 项目根目录落盘 → memory 隔离目录
- MEMORY_ROOT / RUNS_ROOT / PROFILE_ROOT
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment