name: tashan-workbench-dev description: 他山工作台(tashan-workbench)开发专属 Skill。接手/开发/调试工作台时激活:启动命令、架构速查、历史踩坑、测试方法。触发词:「他山工作台」「openwork-local」「tashan-workbench 开发」「工作台怎么启动」「接手工作台」「工作台调试」。
他山工作台 · 开发 Skill
他山工作台(tashan-workbench)是基于 OpenWork fork 的本地 AI 桌面应用,内嵌 opencode 执行引擎,搭载 Tashan Cognitive Pack 认知内核。 代码位置:
项目群/tashan-workbench/
激活后立即执行
Step 1 Read: 项目群/openwork-local/产品经理/产品定义.md(v0.7)→ 了解产品边界
Step 2 Read: 项目群/openwork-local/技术架构师/技术架构_v0.2_正式版.md → 架构契约
Step 3 Read: 项目群/tashan-workbench/DEPLOY_ARCH.md → 部署状态和端口信息
Step 4 本次任务的具体需求 → 按「五类测试维度」执行
核心架构速查
tashan-workbench/(monorepo)
├── packages/app/ ← 前端(React 18 + Tailwind + Noto Serif SC)
│ └── src/
│ ├── App.tsx ← 三栏布局(左:对话 / 中:预览 / 右:搜索+记忆)
│ ├── api/client.ts ← openwork-server API 封装(含4优先级 token 解析)
│ └── types/ ← 共享类型
│
├── packages/server/ ← openwork-server(Bun TypeScript,端口 4897)
│ └── src/
│ ├── server.ts ← 所有 API 路由(含 /brain/* /workspace/:id/search)
│ ├── workspace-search.ts ← BM25 全文检索(16单测)
│ └── brain-bridge.ts ← 他山Brain HTTP 封装(17单测)
│
├── packages/tashan-mcp/ ← tashan-mcp MCP 服务器(stdio)
│ └── src/
│ ├── server.ts ← brain_ask / spawn_task / list_tasks / cancel_task
│ ├── task-manager.ts ← 子任务生命周期(支持 SQLite 持久化)
│ └── task-store.ts ← SQLite 持久化层(7单测)
│
├── packages/desktop/ ← Tauri 桌面应用壳层(Rust)
│ └── src-tauri/
│ └── sidecars/ ← 预编译 opencode/openwork-server/mcp 二进制
│
├── opencode.json ← AI 模型配置(DashScope + tashan-mcp 注册)
└── .opencode/skills/ ← Tashan Cognitive Pack(系统提示词注入)
├── tashan-cognitive-pack/SKILL.md ← 认知工作流
└── tashan-brand-guard/SKILL.md ← 前端品牌规范
本地开发启动(推荐:不打包直接验证)
# 终端1:启动 AI 执行引擎(opencode)
# (通常已在后台,检查:lsof -i:4900)
# 终端2:启动 openwork-server
export PATH="$HOME/.bun/bin:$PATH"
cd 项目群/tashan-workbench/packages/server
bun src/cli.ts \
--workspace ~/aiwork/0310_huaxiang/项目群/tashan-workbench \
--opencode-base-url http://127.0.0.1:4900 \
--port 4897
# ⚠️ 记录输出的 Client token,每次重启都会变
# 终端3:更新前端 token 并启动 Vite
TOKEN="从终端2复制"
echo "VITE_OPENWORK_URL=http://127.0.0.1:4897
VITE_OPENWORK_TOKEN=$TOKEN" > packages/app/.env
cd packages/app && pnpm exec vite --port 5200
# 浏览器打开 http://localhost:5200
完整 Tauri 桌面模式(用于最终验收/打包):
cd packages/desktop
env -u CI pnpm tauri dev
快速健康检查
# 服务状态
curl http://127.0.0.1:4897/health
# 工作区
TOKEN="xxx"
curl http://127.0.0.1:4897/workspaces -H "Authorization: Bearer $TOKEN"
# BM25 搜索
curl "http://127.0.0.1:4897/workspace/ws_e5fb359b2060/search?q=产品定义&limit=3" \
-H "Authorization: Bearer $TOKEN"
# 全部单测
cd packages/server && bun test src/
cd packages/tashan-mcp && bun test src/
已实现功能清单(Phase A~E + 遗留修复)
| 功能 | 关键文件 | 单测 |
|---|---|---|
| LLM 对话(DashScope qwen3.5-plus) | opencode session API | — |
| BM25 工作区文件搜索 | workspace-search.ts | 16✅ |
| 子智能体编排(spawn/list/cancel) | task-manager.ts + task-store.ts | 16✅ |
| 分身代理提问(brain_ask) | brain-bridge.ts + server.ts | 17✅ |
| Tashan Cognitive Pack | .opencode/skills/ | API✅ |
| token 持久化(4优先级) | api/client.ts | — |
| TaskManager SQLite 持久化 | task-store.ts | 7✅ |
| spawn_task 并发上限(默认5) | task-manager.ts | — |
历史踩坑速查(必读)
W-01 点击发送按钮无反应
症状:输入文字后点「↑」按钮,页面无反应。
根因:wsId 为 null,handleSend 第一行静默 return。
原因:getWorkspaces() 用旧 token 返回 401 → 初始化失败 → wsId=null。
修复:每次重启 server 后更新 .env 的 VITE_OPENWORK_TOKEN。若已修复但仍无反应,检查浏览器 DevTools Console。
W-02 BrainConfirmModal 一直弹出
症状:「以你的名义向专家分身提问」弹窗不停出现。
根因:brain_ask_requests 表里有 pending_confirm 状态的测试数据,前端每 5 秒轮询一次就触发弹窗。
修复:清除测试数据:
bun -e "
const {Database}=require('bun:sqlite');
const {homedir}=require('os');
const {join}=require('path');
const db=new Database(join(homedir(),'.tashan-workbench','brain.db'));
db.run(\"DELETE FROM brain_ask_requests WHERE question_draft LIKE '%test%'\");
db.run('DELETE FROM brain_rate_limit');
db.close();
"
W-03 Tauri sidecar token 与 dev server token 不匹配
症状:pnpm tauri dev 启动后 wsId=null,页面无法使用。
根因:Tauri sidecar 有自己的 token 管理,与手动启动的 dev server token 不同。
修复:浏览器直接访问 http://localhost:5200(不走 Tauri 窗口),或在 Tauri 窗口中按 Cmd+Option+I 打开 DevTools 查看实际 token。
W-04 openclaw 插件 SDK 与 openwork-server 不兼容
症状:想接入 openclaw memory-core / subagents,发现无法注册。
根因:openclaw 使用 openclaw/plugin-sdk,openwork-server 使用 opencode 生态,两套体系完全不兼容。
修复:自建等效功能(BM25 搜索、tashan-mcp MCP 工具),见 opencode-plugin-compatibility Rule。
W-05 BM25 单字 CJK 误触发
症状:搜索明显不相关的词,也返回结果。 根因:CJK 单字("在"、"的")太常见,bigram 化不够时会误触发。 修复:分词器已修复为「只产出 bigram,不产出单字」(workspace-search.ts)。
W-06 pnpm tauri build bundle_dmg.sh 失败
症状:pnpm tauri build 编译成功但报 bundle_dmg.sh 错误,无 .dmg 产出。
根因:Tauri 0.11.169 在 macOS 26(Darwin 25.3.0)上 bundle_dmg.sh 调用参数缺失。
修复:手动用 hdiutil create 打包:
hdiutil create -volname "他山工作台" \
-srcfolder target/release/bundle/macos/他山工作台.app \
-ov -format UDZO \
target/release/bundle/dmg/他山工作台_0.11.169_aarch64.dmg
W-07 API 命名风格数据契约不一致
症状:前端读到 undefined 字段。
根因:server 返回 camelCase(questionDraft),前端类型定义 snake_case(question_draft)。
修复:统一约定所有 API 使用 camelCase,types/index.ts 已修复。
关键配置文件
| 文件 | 用途 |
|---|---|
opencode.json | LLM 模型 + tashan-mcp 注册;修改后需重启 openwork-server |
packages/app/.env | 前端 token 配置;每次重启 server 后更新 VITE_OPENWORK_TOKEN |
~/.tashan-workbench/brain.db | brain_ask 请求状态(SQLite) |
~/.tashan-workbench/task-manager.db | spawn_task 任务状态(SQLite) |
~/.config/openwork/tokens.json | openwork-server token 持久化 |
前端品牌规范速查
- 字体:
font-serif(Noto Serif SC),禁止 Inter/Roboto/Arial - 主色:
bg-black text-white(按钮),text-gray-600/700(内容) - 圆角:
rounded-lg(卡片/按钮),rounded-xl(模态框),rounded-full(头像) - 禁止:渐变背景、紫色配色、CSS-in-JS
产品边界(Phase A~E 已实现)
详见:项目群/openwork-local/产品经理/产品定义.md(v0.7)
未实现(待后续迭代):
- E2:分享任务结果到他山Brain(需他山Brain发帖API)
- E3:多人协作工作台(工程量大)
- brain_ask 真实分身对话(需设置
BRAIN_JWT_DEV)
变更记录
v1.0 — 2026-03-21 — 初始创建
触发事件:tashan-workbench Phase A~E 完整开发完成,project-closeout 通过,用户要求沉淀开发经验为 Skill。
经验核心:
- opencode/openclaw 两套生态不兼容,必须先验证 plugin SDK 再设计方案
- Tauri sidecar token 与 dev server token 不同,浏览器直接访问是更好的迭代方式
- BM25 + CJK bigram 分词是纯本地工作区搜索的有效方案
- brain_ask 的 SOUL.md 人格化:必须用结构化字段提取,防 Prompt Injection
验证状态:✅ 已验证(本次完整项目开发实测)