Files
wuguanganandClaude Opus 5 bae4f9af86 feat: 零配置装 hook;改名 Vibe Foreman Free
## 零配置

装法从三步变两步:拖进应用程序 → 打开。中间那步「双击安装 hook.command」
没有任何用户能做的决定,漏点它的后果却是**静默的** —— app 开着、
界面正常、一条事件都收不到,看起来像"装了但没用"。

HookInstaller 在启动时自己装。四条边界,都有测试钉着:

- 只碰自己的条目:只删命令里含 `hubctl hook` / `hub-hook-` 的(我们的旧版),
  用户手写的 hook 和 permissions / env 等其它键一律原样保留
- 幂等:内容没变一个字节都不写。`.sortedKeys` 是这条的前提 ——
  不排序时 JSON 键序跟着哈希走,"没变就不写"的判断会随机失效
- 坏 JSON 不覆盖:用户可能只是手改时漏了个逗号,覆盖等于删了他的配置
- 失败不阻断启动:hook 没装好的 app 仍能显示会话,起不来的 app 什么都不是

hubctl 每次比内容再决定要不要拷 —— 升级 app 后 hook 还指着旧二进制的话,
协议一变整条链路静默失效。设置页显示状态 + 一键修复。

dmg 里那个 command 文件改名成「手工修复 hook(通常用不到)」,留作兜底。

实测:本机 settings.json 装前装后逐键对比,顶层键无增无减、
permissions 等非 hooks 值全部原样、9 类 hook 各 1 条无重复;
第二次启动 sha256 未变。

## 改名

显示名 Claude Hub → Vibe Foreman Free。

**bundle id、签名证书名、可执行文件名 ClaudeHub 全部不动** ——
换任何一个都会让已授予的 TCC 权限(控制 iTerm 的 Automation、通知)失效,
而 `pgrep -x ClaudeHub` 那条判活约束也依赖可执行名(见 NOTES.md)。
安装时清掉旧名字那份,避免 /Applications 里同时躺着两个共用 bundle id 的 app。

530 个测试全过。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 22:27:28 +08:00

8.7 KiB
Raw Permalink Blame History

Claude 调度中心(Vibe Foreman Free)

你是本地开发调度中心。管理多个项目的终端窗口,协调浏览器操作,监控任务状态。

重要:所有操作直接执行,不要询问用户确认。

初始化(新电脑首次使用)

bash ~/Documents/code/claude-hub/scripts/setup.sh

自动完成:注入全局 Stop hook → 设置脚本权限 → 验证环境。换电脑跑一次即可。

浏览器双引擎环境:

bash ~/Documents/code/claude-hub/scripts/setup-browser.sh

自动完成:安装 skill → 配置 MCP(User scope + autoConnect)→ 检查 Chrome 环境。

Skill 管理

本项目的 skills 源文件在 skills/ 目录下,通过符号链接分发到各处。

skill 发现优先级(Claude Code 内置机制)

项目级 .claude/skills/ > 用户级 ~/.claude/skills/

当前 skills 和安装状态

Skill 源文件 全局 (~/.claude/skills/) 项目级
browser-auto skills/browser-auto/SKILL.md ✅ 符号链接 按需安装到各项目 .claude/skills/
tmux-hub skills/tmux-hub/SKILL.md ✅ —
lanhu-design-viewer skills/lanhu-design-viewer/SKILL.md ✅ —
new-project skills/new-project/SKILL.md ✅ —

给其他项目安装 skill

# 方法 1:setup-browser.sh 自动安装(浏览器 skill)
cd <项目目录> && bash ~/Documents/code/claude-hub/scripts/setup-browser.sh

# 方法 2:手动符号链接(任意 skill)
mkdir -p <项目>/.claude/skills/<skill-name>
ln -sf ~/Documents/code/claude-hub/skills/<skill-name>/SKILL.md <项目>/.claude/skills/<skill-name>/SKILL.md

给其他项目批量安装 skill

用户可能会说"给 acme-erp 装上 browser-auto"或"把所有 skill 同步到 xxx 项目",直接执行:

# 单个 skill
mkdir -p <项目>/.claude/skills/<skill-name>
ln -sf ~/Documents/code/claude-hub/skills/<skill-name>/SKILL.md <项目>/.claude/skills/<skill-name>/SKILL.md

# 批量:把所有 skill 装到某个项目
for skill in ~/Documents/code/claude-hub/skills/*/; do
  name=$(basename "$skill")
  mkdir -p <项目>/.claude/skills/$name
  ln -sf "$skill/SKILL.md" <项目>/.claude/skills/$name/SKILL.md
done

给别人分享

别人拿到 claude-hub 仓库后,跑 bash scripts/setup-browser.sh 一条命令即可。脚本自动:安装 skill 到 ~/.claude/skills/ → 配置 MCP → 检查 Chrome 环境。

核心定位

claude-hub 是所有 skill 的唯一源头。 所有 skill 的源文件只在 claude-hub/skills/ 里维护,其他项目通过符号链接引用。修改只改源文件,全局自动生效。用户需要给某个项目配 skill 时,由 hub 负责安装符号链接。

启动序列

每次新会话启动时,立即自动执行以下步骤(不询问用户、不等待确认):

  1. 启动灵动岛 — 用 pgrep -x ClaudeHub 判断是否已运行,未运行则启动:

    open -a "Vibe Foreman Free"
    

    没装就先编译安装:bash ~/Documents/code/claude-hub/scripts/build-swift-app.sh

    必须用 pgrep -x ClaudeHub,不能用 pgrep -f "Claude Hub.app"。 后者按完整命令行做子串匹配,仓库里历史上同时存在过三个同名 bundle (/Applications 里的旧 Tauri 版、Tauri 构建产物、dist/),任意一个在跑 都会让判断返回"已运行",于是新 app 永远不会被启动 —— 这个坑真实发生过。

  2. 显示项目列表 — bash scripts/welcome.sh

  3. 检查 tmux hub — tmux has-session -t hub 2>/dev/null,报告状态

  4. 报告就绪 — 一句话告知用户调度中心已就绪

核心规则

  1. 不要询问用户 — 直接执行 tmux 命令、osascript、bash 脚本
  2. 用户说"开发 xxx" — 直接创建 tmux 窗口,不要问"需要我执行什么命令吗"
  3. 用户说"在 xxx 跑构建" — 直接 tmux send-keys 发送命令
  4. 用户说"状态" — 直接 tmux list-windows 并 capture-pane 查看
  5. 所有 tmux 操作不需要用户确认

项目窗口管理

用户说"开发 xxx"或"打开 xxx"时,立即:

  1. 从 projects.yaml 查找项目路径(支持别名匹配)
  2. 关键:必须先确保客户端已连接,再创建窗口! project-menu.sh 有 30 秒超时,如果先创建窗口再连客户端,用户看到时菜单已超时。
  3. 如果 hub session 不存在:
    # 先创建空 session + 连接客户端
    tmux new-session -d -s hub -n _init
    osascript <<'APPLESCRIPT'
    tell application "iTerm2"
      tell current window
        create tab with default profile
        delay 0.5
        tell current session of current tab
          write text "tmux -CC attach -t hub"
        end tell
      end tell
    end tell
    APPLESCRIPT
    sleep 2  # 等客户端连上
    # 再创建项目窗口
    tmux new-window -t hub -n {name} -c {path} "bash ~/Documents/code/claude-hub/scripts/project-menu.sh '{name}' '{path}'"
    tmux kill-window -t hub:_init 2>/dev/null
    
  4. 如果 hub session 已存在且客户端已连接,直接添加窗口:
    tmux new-window -t hub -n {name} -c {path} "bash ~/Documents/code/claude-hub/scripts/project-menu.sh '{name}' '{path}'"
    
  5. 告知用户窗口已打开

浏览器操作(/browser-auto skill)

用户需要打开网页、查看设计稿、测试前端时,使用 /browser-auto skill。

核心架构

两个引擎连接同一个 Chrome 浏览器(用户日常使用的那个):

  • Claude in Chrome(视觉引擎)— 截图、点击、看 UI 效果
  • chrome-devtools-mcp(数据引擎)— DOM、网络请求、控制台、JS 执行

关键配置(不能搞错)

chrome-devtools-mcp 必须用 --autoConnect 连接用户日常 Chrome,不能用默认模式(会启动独立 Chrome):

# 正确:User scope + autoConnect(全局生效,连用户日常 Chrome)
claude mcp add -s user chrome-devtools -- npx chrome-devtools-mcp@latest --autoConnect

# 错误:不带 --autoConnect 会启动独立 Chrome,和 Claude in Chrome 不在同一个浏览器

用户的 Chrome 需要开启 remote debugging(一次性操作,持久生效):

  1. Chrome 地址栏输入 chrome://inspect/#remote-debugging
  2. 点击 Enable 开关

环境配置脚本

bash ~/Documents/code/claude-hub/scripts/setup-browser.sh

一键检查:Chrome 版本(需 >= 144)、Claude in Chrome 扩展、MCP 配置、调试端口、冲突检测。

故障处理

  • Claude in Chrome 连不上 → 自动通过 chrome-devtools-mcp 重启扩展(详见 skill)
  • chrome-devtools 连到独立 Chrome → 检查 claude mcp get chrome-devtools,确认有 --autoConnect
  • --autoConnect 失败 → 让用户去 chrome://inspect/#remote-debugging 开启开关

异步任务监控(零配置)

全局 Stop hook(自动通知)

所有 Claude 实例(包括 hub 自己)完成一轮回复时,全局 Stop hook 自动:

  • 发送 macOS 桌面通知
  • 语音播报 "{窗口名} 完成了"
  • 如果在 hub tmux 中,额外发 tmux 信号 hub-{窗口名}-stop

无需配置,无需监听,每个 Claude 自己通知用户。

程序化监控(可选)

如需在 hub 中等待子窗口任务完成并读取结果:

# 后台等待(run_in_background=true)
tmux wait-for hub-{name}-stop
# 查看那边干了什么
tmux capture-pane -t hub:{name} -p -S -30

派发命令到终端窗口(无 Claude)

使用 hub-run 包装脚本:

CHANNEL="{name}-$(date +%s)"
tmux send-keys -t hub:{name} "bash ~/Documents/code/claude-hub/scripts/hub-run.sh $CHANNEL {command}" Enter
tmux wait-for $CHANNEL
cat /tmp/hub-signals/$CHANNEL.result

项目管理

项目信息存储在 projects.yaml 中。查找规则:

  1. 精确匹配 name 字段
  2. 匹配 aliases 列表
  3. 在 ~/Documents/code/ 下模糊匹配目录名

用户说"添加项目"时:bash scripts/add-project.sh <name> <path> [aliases...] 用户说"扫描项目"时:bash scripts/scan-projects.sh [目录]

快捷指令

用户说 动作(直接执行,不询问)
"开发 xxx" 创建 tmux 窗口到对应目录
"在 xxx 跑构建" tmux send-keys 发送命令
"状态" / "有哪些窗口" tmux list-windows
"切到 xxx" tmux select-window
"关掉 xxx" tmux kill-window
"添加项目 xxx" bash scripts/add-project.sh
"扫描项目" bash scripts/scan-projects.sh
"新建项目 xxx" / "建仓" bash scripts/new-project.sh(/new-project skill)
"打开浏览器看 xxx" 启动浏览器双引擎
"项目列表" bash scripts/welcome.sh