tashan-workbench-dev

他山工作台(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.ts16✅
子智能体编排(spawn/list/cancel)task-manager.ts + task-store.ts16✅
分身代理提问(brain_ask)brain-bridge.ts + server.ts17✅
Tashan Cognitive Pack.opencode/skills/API✅
token 持久化(4优先级)api/client.ts
TaskManager SQLite 持久化task-store.ts7✅
spawn_task 并发上限(默认5)task-manager.ts

历史踩坑速查(必读)

W-01 点击发送按钮无反应

症状:输入文字后点「↑」按钮,页面无反应。 根因wsId 为 null,handleSend 第一行静默 return。 原因getWorkspaces() 用旧 token 返回 401 → 初始化失败 → wsId=null。 修复:每次重启 server 后更新 .envVITE_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.jsonLLM 模型 + tashan-mcp 注册;修改后需重启 openwork-server
packages/app/.env前端 token 配置;每次重启 server 后更新 VITE_OPENWORK_TOKEN
~/.tashan-workbench/brain.dbbrain_ask 请求状态(SQLite)
~/.tashan-workbench/task-manager.dbspawn_task 任务状态(SQLite)
~/.config/openwork/tokens.jsonopenwork-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。

经验核心

  1. opencode/openclaw 两套生态不兼容,必须先验证 plugin SDK 再设计方案
  2. Tauri sidecar token 与 dev server token 不同,浏览器直接访问是更好的迭代方式
  3. BM25 + CJK bigram 分词是纯本地工作区搜索的有效方案
  4. brain_ask 的 SOUL.md 人格化:必须用结构化字段提取,防 Prompt Injection

验证状态:✅ 已验证(本次完整项目开发实测)