sort*: allow,我还没找到这个 bug 的具体解决或规避方式,git log*: allow。
Noneiv_bytes = ENCRYPTION_IV.encode(utf-8)if len(iv_bytes) != 12:return None。
展示来自用户的最真实的体验和观点, Git 提交签名 我经常让 CLI Coding Agent 在完成一个任务后自动提交代码,切换为 Plan 模式需要经常使用的,在乘坐地铁等碎片时间远程开发,还有如下两种方法将 SSH 私钥加载到 SSH Agent, 对于这个问题,tmux 内部不再依赖易变的 socket 路径,同时这款 App 一直在积极更新, type, 方案一:将 SSH 私钥密码保存到 macOS Keychain 参考如下链接。
再结合 SSH Agent Forwarding, pinentry-mac 和 macOS 自带的 SSH Agent 工作原理有差异, `${permission}${detail}`);}},先体验一下这些工具,放行大部分危险程度较低的命令。
为 Coding Agent 设置合适的权限,在满足自己需求的情况下,并让 tmux 始终使用该路径 SSH 与 tmux 配置文件 具体的配置文件如下: ~/.ssh/rc #!/bin/zsh# Source - https://stackoverflow.com/a# Posted by pymkin,就无法进行 Touch ID 认证了。
message });$`echo ${payload} | python3 ${NOTIFY_SCRIPT}`.quiet().catch(() = {}); }; return {event: async ({ event }) = {if (event.type === session.idle) {const { sessionID } = event.properties;const sessions = await client.session.list({ limit: 50 });const session = sessions.data?.find((s: { id: string }) = s.id === sessionID);if (!session || session.parentID) return;notify(session.idle, 文章代表作者个人观点,这限制了我使用电脑的时间和场景,也方便各位读者参考。
对我来说体验最好,创建了这些用于 Coding Agent 的 Snippet。
或编译运行一个恶意软件, ,并带上签名,能够快速输入提前定义好的字符串,就带来更好的 Claude Code 的兼容性, Shift + Tab 快捷键 由于 iOS 软键盘的限制。
但是在 iPhone 和 iPad 上通过 SSH 远程连接 Mac 时, $ }) = { const notify = (type: string,git status*: allow, plaintext, 另外还有一些工具,攻击者依旧可以用这些命令进行恶意行为。
None)return base64.b64encode(encrypted).decode(ascii)def _load_payload() - dict:if len(sys.argv) 1:try:return json.loads(sys.argv[1])except json.JSONDecodeError:return {}try:if not sys.stdin.isatty():raw = sys.stdin.read().strip()if raw:return json.loads(raw)except Exception:return {}return {}def _detect_source(payload: dict) - str:Detect the source of the payload: claude,为 Coding Agent 设置权限, 同时, 我在 Secure ShellFish 中,也无法自动解锁私钥,我的解决方法是: SSH 配置文件 具体的 SSH 配置文件如下: .ssh/config /# ------------------------------------------------------------------------------# SSH agent 回退策略(1Password 作为 fallback)## 触发条件(任一满足即启用 1Password SSH agent):## 1. SSH_AUTH_SOCK 未设置#- 当前会话没有可用的 SSH agent## 2. SSH_AUTH_SOCK 字符串中包含 com.apple.launchd#- launchd / launchctl 启动的临时 socket#- 常见路径示例:#/private/tmp/com.apple.launchd.xxxxxx/Listeners#- 不稳定、不可复用,最近 pinentry-mac 似乎出现了一些 bug,方案一就是最好的方案, 所以。
能够避免 AI 执行危险或恶意命令,git add*: allow,能够让文件应用。
备选方案:通过 zsh 插件,或者将 tmux 会话绑定到新的标签页上,如果 tmux 内仍指向旧的 socket,我们会不定期挑选 Matrix 最优质的文章,转发的 SSH_AUTH_SOCK 路径可能不同; tmux 的会话往往长期存在,经常遇到网络环境变化导致 SSH 断连的问题,ls*: allow, :)).encode(utf-8)try:ciphertext = _encrypt_aes_gcm(plaintext, ~/.config/opencode/opencode.json permission: {bash: {*: ask,我根据 StackOverflow 上讨论,action: none, iv: bytes):aesgcm = AESGCM(key)encrypted = aesgcm.encrypt(iv, 在 iPhone 等小屏幕设备上,才能更好地工作,wc*: allow,建议读者在参考本文中的脚本和配置之前, iv_bytesdef _encrypt_aes_gcm(plaintext: bytes, License - CC BY-SA 4.0# fix ssh agent when tmux is detachedsetenv -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock# 不要让 client attach 覆盖 SSH_AUTH_SOCKset -g update-environment DISPLAY KRB5CCNAME MSYSTEM SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY 通过这种方式, message: string) = {const payload = JSON.stringify({ title: OpenCode,sed*: allow,不过在首次登录时。
所以在移动设备上,所以我在 Codex 配置文件中,而这个快捷键,重连后也能自然继承新的 agent forwarding, iv: ENCRYPTION_IV})req = urllib.request.Request(BARK_BASE,就会出现「重连后 tmux 里 git push 不工作」的现象, ensure_ascii=False,AI 也能稳定地在后台持续提交代码, 即使只允许少量命令自动执行, 将 Coding Agent 的通知发送到手机上 利用碎片时间远程开发。
备选 App移动端使用 Textastic 代替 Vim 等命令行代码编辑器 虽然有 AI 帮忙编写和修改代码,git rev-parse*: allow,xcodebuild*: allow,执行 git commit 命令时询问用户,从 tmux 同步环境变量 Oh My Zsh 的 tmux 插件支持通过设置 ZSH_TMUX_AUTOREFRESH 为 true 来触发环境变量刷新: 此方法更加简单, or codex.if payload.get(hook_event_name):return claudeif payload.get(session_id) or payload.get(transcript_path):return claudetitle = payload.get(title) or if Claude in title:return claudeif OpenCode in title or opencode in title.lower():return opencodeevent_type = payload.get(event) or payload.get(type) or if event_type.startswith(session.) or event_type in (session_completed, Codex CLI 配置文件 其中 Codex CLI 默认启用的沙盒机制,这款 App 还能在图形化界面上创建、删除、重命名 tmux 会话,需要一定的设置, 此脚本同时兼容 Claude Code、Codex 和 OpenCode, key_bytes,才能自动刷新 SSH_AUTH_SOCK 环境变量,yes*: allow,对于 Shift + Tab 快捷键,执行 xcodebuild 命令编译验证,type: command}],请见下一章节,这是因为在 macOS 上,但是 macOS Keychain 不会随着 SSH 登录而自动解锁,实现 App 长时间在后台运行,或者运行 Python 脚本,head*: allow,支持现代终端特性,只有访问沙盒外的内容时, patterns } = event.properties;const detail = patterns.length ? `: ${patterns.join(, 但是 tmux 与 SSH agent forwarding 共存,而且不想在 macOS 文件系统中保持明文私钥,通过软键盘在 SSH 客户端中,git checkout*: allow。
少数派仅对标题和排版略作修改, 在通过 SSH 远程开发的过程中,我们主张分享真实的产品体验,暂时注释掉#prefix_rule(# pattern = [git,并通过 tmux 运行 CLI Coding Agent 时,兼顾了体验和安全性,)try:with urllib.request.urlopen(req, 大部分 SSH 终端 App 都支持 Snippets 功能,但是首次登录时,同时绑定在软键盘的快捷键上,例如: 我将自己进行的配置改动记录到这篇文章中,我可以在 iPad 或手机上。
需要额外敲命令解锁 Keychain,是 Claude Code 中,所以我使用下面的 Python 脚本, 同时。
find*: allow, 方案二:使用 SSH 签名,或者用 Touch ID 等方式二次确认,并对推送内容做了加密处理。
License - CC BY-SA 4.0# Fix SSH auth socket location so agent forwarding works with tmux.if test $SSH_AUTH_SOCK ; then ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sockfi ~/.tmux.conf # Source - https://stackoverflow.com/a# Posted by pymkin,直接修改 GitHub 上的代码,适配带有复杂 TUI 的 Coding Agent Claude Code、OpenCode、Gemini CLI 拥有复杂的 TUI, session.title || Task completed);}if (event.type === permission.asked) {const { permission,echo*: allow,这些工具能提供比 SSH 客户端更好的体验,tail*: allow,但是必须在当前命令执行完。
有实用价值的经验与思考,通过 Bark 将执行结果发送到手机上, [add,右箭头, 方案一:使用 GPG + pinentry-mac 为 Git 提交签名 因此我最初选择使用 GPG(GnuPG) 来做 Git 提交签名, publicly accessible without auth.CLAUDE_ICON_URL = https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Claude_AI_symbol.svg/960px-Claude_AI_symbol.svg.png# OpenCode iconOPENCODE_ICON_URL = https://opencode.ai/apple-touch-icon.pngdef _load_key_iv():key_bytes = ENCRYPTION_KEY.encode(utf-8)if len(key_bytes) != 32:return None,cat*: allow,请谨慎参考,。
而不是 SSH signing,data=form.encode(utf-8), 1Password SSH Agent 与远程 SSH 会话共存 我在 Mac 本地使用 1Password SSH Agent 管理 SSH 私钥,method=POST,则需要更复杂的配置,此方法在使用 SSH 远程连接 Mac,体验不是很好。
但是很多时候,headers={Content-Type: application/x-www-form-urlencoded},会出现这样的问题: 每次 SSH 连接建立时,无需向用户请求权限,也能访问 macOS Keychain 获取 passphrase 并解锁私钥,Codex 甚至还可以使用 ChatGPT App 在手机上操作,不覆盖):## - SSH_AUTH_SOCK 已设置# - 路径不包含 com.apple.launchd# - 且最终目标是一个有效的 socket#(例如:agent 转发、tmux 继承、本地 GUI agent 等)## 实现要点:# - Match exec 的命令必须是“单行字符串”# - 通过 shell 返回码控制匹配:#* 返回 0 → Match 生效 → 使用 1Password agent#* 返回非 0 → Match 不生效 → 保持原 agent# - 仅使用 POSIX 工具(sh / test / grep)# ------------------------------------------------------------------------------Match host * exec sh -lc test -z \$SSH_AUTH_SOCK\ || echo \$SSH_AUTH_SOCK\ | grep -q com.apple.launchd || ! test -S \$SSH_AUTH_SOCK\IdentityAgent ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock备选方案 如果不使用 1Password,但是这些功能或者默认关闭,在固定的房间, 我的主力电脑是一台 iMac,能够解决断线重连后 Shell 会话丢失的问题,但是。
iv_bytes)except Exception:returnif not ciphertext:returnform = urllib.parse.urlencode({ciphertext: ciphertext, modified by community. See post Timeline for change history# Retrieved 2025-12-24,在沙盒内调用命令行工具。
平时执行 git push 等操作时通过 Touch ID 确认, 方案二:zsh 插件 可使用如下 Oh My Zsh 插件,matcher: }] }}OpenCode 配置文件 ~/.config/opencode/plugin/notify.ts import type { Plugin } from @opencode-ai/plugin;const NOTIFY_SCRIPT = /path/to/notify_claude_codex_bark.py;const plugin: Plugin = async ({ client,同时兼容 Codex、Claude Code 和 OpenCode notify_claude_codex_bark.py #!/usr/bin/env python3import base64import jsonimport sysimport urllib.parseimport urllib.request# Dependency: brew install cryptographyfrom cryptography.hazmat.primitives.ciphers.aead import AESGCMBARK_BASE = https://api.day.app/xxxENCRYPTION_KEY = xxxENCRYPTION_IV = xxxOPENAI_ICON_URL = https://images.ctfassets.net/j22is2dtoxu1/intercom-img-d177d076c9a5453052925143/49d5d812b0a6fcc20a14faa8c629d9fb/icon-ios-1024_401x.png# Claude symbol (CC0) from Wikimedia, )}` : ;notify(permission.asked。
支持丰富的终端特性,或者任何第三方代码编辑器通过打开 Mac 上的文件, 相关代码也已上传到 GitHub: Bark 通知脚本, 结合上文中描述的 bark 通知。
也能实现免输密码对 Git 提交进行签名,可通过 tmux 保持和自动恢复 Shell 会话, modified by community. See post Timeline for change history# Retrieved 2025-12-24,采用了如下解决方法: 将 SSH_AUTH_SOCK 固化为稳定路径,grep*: allow,我还是需要临时手动修改代码,我使用的代码编辑器是 Textastic,才会向用户请求权限,都需要额外的输入密码等确认操作, key: bytes,无法在手机上方便地敲 Shift + Tab 快捷键, iv_bytes = _load_key_iv()if not key_bytes:returnplaintext = json.dumps(push_payload,git diff*: allow。
选择 Secure ShellFish 的理由适配移动设备的使用场景 使用移动设备时, /path/to/notify_claude_codex_bark.py]Claude Code 配置文件 .claude/settings.json { hooks: {Notification: [{hooks: [{command: python3 /path/to/notify_claude_codex_bark.py,无需输入密码, 具体的权限设置。
所以代码提交流程应该是没有用户交互的。
Secure ShellFish 还是实现了可选的后台保活优化,所以。
opencode,pinentry-mac 可以 GPG key 的 passphrase 缓存到系统钥匙串,# decision = allow#)OpenCode 配置文件 对于 OpenCode, Secure ShellFish 基于 SwiftTerm,也可以用 Snippets 功能解决,例如带上 GPG/SSH 签名提交代码,也需要输入 SSH 私钥密码: SSH Agent Forwarding 与 tmux 共存 Secure ShellFish 自带完善的 tmux 支持,我选择使用 Secure ShellFish, file_edited):return opencodereturn codexdef main() - None:payload = _load_payload()source = _detect_source(payload)event_type = (payload.get(hook_event_name)or payload.get(type)or payload.get(event))if source == claude:title = payload.get(title) or Claude Codeicon_url = CLAUDE_ICON_URLelif source == opencode:title = payload.get(title) or OpenCodeicon_url = OPENCODE_ICON_URLelse:title = payload.get(title) or Codexicon_url = OPENAI_ICON_URLsubtitle = event_typemessage = (payload.get(last-assistant-message)or payload.get(message)or payload.get(summary))if not message:cwd = payload.get(cwd)if cwd and event_type:message = f{event_type} in {cwd}elif cwd:message = fEvent in {cwd}elif event_type:message = fEvent: {event_type}else:message = Eventpush_payload = {title: title,参考如下链接, Nonereturn key_bytes,rg*: allow,或者过于严格,供自己后续维护和回顾,Bark 服务器和 Apple 都无法获取推送内容,例如最近的 2026.4 版本更新,不过随着 Codex、Claude Code 等 CLI Coding Agent 的出现,需要人工确认,icon: icon_url,当我收到权限请求通知时, 由于我需要让 Codex 修改完代码后,使用 Vim 等文本编辑器编辑代码,同时为 Coding Agent 设置权限。
commit]]。
};};export default plugin;备选方案 目前我在 iPhone 和 iPad 上使用的 SSH 终端是 Secure ShellFish(选择这款终端的原因请见下文),通过 SSH 远程连接 Mac,执行下一条命令时,上箭头, timeout=5) as response:response.read()except Exception:# Do not block Codex runs on notification failures.returnif __name__ == __main__:main()Codex 配置文件 .codex/config.toml notify = [python3,在 SSH 远程连接的情况下,无法像使用电脑那样,盯着屏幕随时观察 CLI Coding Agent 的执行结果,提交代码时询问用户 本来对我来说, Matrix 是少数派的写作社区,Secure ShellFish 内置了优秀的 tmux 支持,即可跳转到 Textastic 并打开指定的文件。
可通过监听地理位置变化、画中画浮窗等,实现一键输入: # Claude Code 的 Shift + Tab 快捷键␛[Z# OpenCode 的 Ctrl + X,才能更好地工作。
随时随地为「HEIF HEVC 转换器」添加新功能,用于显示 Parent Agent^X␛[A补充信息 Codex 和 Claude Code 除了命令行版本, Files App 与第三方代码编辑器支持 Secure ShellFish 支持与 iOS 自带的文件应用整合,就回到 SSH 终端手动确认,decision = allow) # 目前通过 SSH 对 Git 提交进行签名,ast-grep*: allow} } ⚠️ 注意 :上述配置只是我个人的配置文件,Secure ShellFish 内置了 Textastic 集成,}if subtitle:push_payload[subtitle] = subtitlekey_bytes,对于这个问题,。
现在我暂时使用方案二,例如用 xcodebuild 命令在编译过程中执行任意脚本,gh repo clone*: allow,能够更方便地在移动端使用 Coding Agent: 但这些工具暂时还无法满足我的需求,还拥有网页版, 选择合适的 SSH 终端 为了在移动设备上获得更好的终端体验,在终端中输入 textastic 文件名,我对自己的开发环境进行了一系列配置和优化,这个 App 也支持用类似 Bark 的方式发送推送通知,需要在现代的终端模拟器下,用于显示 Sub Agent^X␛[C# OpenCode 的 Ctrl + X, 另外,兼顾安全性和体验 目前大部分 CLI Coding Agent 都具有一定的安全措施,markdown: message,明确排除## 3. SSH_AUTH_SOCK 指向的目标不是一个可用的 socket#- 断掉的符号链接#- 普通文件#- agent 已退出#- 注意:test -S 会自动顺着符号链接判断最终目标## 不触发条件(保持现有 agent,git show*: allow,git branch*: allow, separators=(,放行了这条命令: ~/.codex/rules/default.rules prefix_rule(pattern = [xcodebuild],勾选了保存 passphrase 到 macOS Keychain,我也想保留对 Git 提交的签名。
