Skip to content
Go back

Claude Island:给 Claude Code 加一块灵动岛

Edit page

最近我业余时间基本都砸在这个小玩具上了:ShuminFu/claude-island

一句话介绍:它把 MacBook 那块刘海变成了 Claude Code 的”指挥中心”,Claude 一有动静刘海就会胀开来告诉你,要你点头同意跑命令的时候直接按快捷键就行,不用切回终端。

Table of contents

Open Table of contents

起因:我受够了切窗口

用 Claude Code 有个特别烦的循环:你在浏览器看文档,Claude 在后台跑着,跑到一半它要权限跑 Bash 或者 Edit,就停下来等你。问题是它不会主动提醒你——你得自己切回终端,瞄一眼,按个 y,再切回来。

如果你像我一样习惯把终端最小化,或者干脆把 Claude 丢在 tmux 的某个角落 pane 里,那就更惨了:你压根不知道它在等你,回过神来一看,十分钟过去了一个字没动。

想了一下,既然 MacBook 都已经有刘海这么一块显眼的地方了,那就让它派上点用场吧——有事喊我,没事消失。就这么个朴素的想法,做着做着变成现在这个样子。

它能干嘛

简单列一下:

一些比较好玩的实现细节

这是我第一次认真写 Swift 和 macOS App,等于是从零开始边写边学。几个让我印象比较深的设计:

所有状态变更只走一个口子

App 里所有状态都走 SessionStore.shared 这一个 actor,别的地方都只能发事件进来,不能直接改状态。流程大概是这样:

Python hook 发 JSON 到 Unix socket
  → HookSocketServer 收到
    → SessionStore.process(.hookReceived(event))
      → 更新一个 immutable 的 SessionState
        → 通过 AsyncStream 广播出去
          → UI 层订阅后重绘

听起来挺复杂,但用起来爽在一个地方:调试的时候我只需要在 process(_:) 这一个函数里下个断点,所有事件都会从这里过一遍,再也不用满项目找”这个状态是谁改的”。

Hook 是一段 Python 脚本

Claude Code 的 hook 机制允许你在会话的关键节点跑脚本,比如”工具调用前”、“消息结束时”这种。Claude Island 第一次启动的时候会往 ~/.claude/hooks/ 里丢一个 Python 脚本,它负责把事件打包成 JSON,通过 Unix domain socket 发给 App。

为什么是 Python 不是 Swift?说起来有点反直觉——Swift 的 CLI 冷启动太重了。hook 是那种会被 Claude Code 频繁拉起又秒退的短命进程,每次启动都要几十毫秒的话,用起来一卡一卡的。Python 3.14 配 uv 冷启动飞快,所以就选它了。App 首次启动会自动找 uv / python3.14 / pyenv,找到哪个就把绝对路径写进 ~/.claude/settings.json,之后就不用再检测了。

JSONL 解析要小心

Claude Code 把每个会话都写成一个 JSONL 文件,长一点的动不动几十 MB。最开始我图省事直接 String(contentsOf:) 整个读,结果一个三小时的会话能让 App 卡半秒——这显然不行。

后来改成 tail-based 的增量解析,每次只读上次之后新增的字节。过程中又发现上游的遍历逻辑在碰到 attachment / system / snapshot 这种嵌套消息的时候会提前跳出,导致长会话被截断。这是我给这个项目修的第一个 bug,也是让我决定认真维护一个 fork 的原因。

权限审批其实是……模拟按键

说出来有点不体面:Claude Code 在终端里等你按 y/n 的时候,App 这边其实是通过 TmuxController 找到对应会话的那个 pane,然后把按键注入进去。

没办法,Claude Code 没有提供外部审批的接口,只能这么来。代价就是首次启动得授权 Accessibility——不是为了监控你,纯粹是因为”往别的应用注入按键”这个动作需要这个权限。

这个 fork 加了啥

上游 engels74/claude-island(再上游是 farouqaldori/claude-island)本身已经做得挺完整了,我这个 fork 主要加了这些东西:

技术栈

顺便记录一下,给未来查文档的自己:

怎么装

macOS 15.6 以上,去 Releases 下最新的 DMG,拖进 Applications。

第一次打开会让你授权 Accessibility 和 Keychain——Accessibility 是用来注入 y/n 按键的,Keychain 是读 Claude Code 的 OAuth token 查额度用的(这个可以跳过),具体步骤 README 里都有。

源代码 Apache 2.0:https://github.com/ShuminFu/claude-island

如果你用了之后有什么地方崩了或者觉得哪里别扭,欢迎来 issue 区找我吐槽 🫠


Edit page
Share this post on: