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 与错误提示优化
这样可以先消除旧机器必现问题,再封堵安装包在新机器上的真实运行风险。
This diff is collapsed.
# 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. 视业务需要再补视频模型链路
宿主协议不一样。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