<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tools on eatmoreduck&#39;s Blog</title>
    <link>https://blog.xiaohuangyu.space/tags/tools/</link>
    <description>Recent content in Tools on eatmoreduck&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 17 Sep 2026 11:54:26 +0800</lastBuildDate>
    <atom:link href="https://blog.xiaohuangyu.space/tags/tools/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>百个 PR 之后：我的多 Agent 开发工作流长成了完整体系</title>
      <link>https://blog.xiaohuangyu.space/p/multi-agent-quality-guardrails/</link>
      <pubDate>Tue, 15 Sep 2026 01:30:00 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/multi-agent-quality-guardrails/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://blog.xiaohuangyu.space/p/github-projects-orca-agent-workflow/&#34;&gt;上一篇&lt;/a&gt;写了用 GitHub Projects + Orca 把多 Agent 编程工作流跑通的第一天——那天只是「能跑」。这一篇是五天后的续集：它已经长成一个完整的体系。先放数字：122 次提交、111 个 PR 合并、127 张 issue，side project（panta-log，本地优先的语音复盘工具）V0.1 MVP 六个工作包全部收官。&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="/p/github-projects-orca-agent-workflow/">上一篇</a>写了用 GitHub Projects + Orca 把多 Agent 编程工作流跑通的第一天——那天只是「能跑」。这一篇是五天后的续集：它已经长成一个完整的体系。先放数字：122 次提交、111 个 PR 合并、127 张 issue，side project（panta-log，本地优先的语音复盘工具）V0.1 MVP 六个工作包全部收官。</p>
<p>这篇不讲过程，把这套工作流现在的功能点按层拆开。每一层都是踩坑踩出来的，坑也照写。</p>
<h3 id="看板层从能记任务到自动流转的任务系统">看板层：从「能记任务」到「自动流转的任务系统」</h3>
<p>上一篇的看板只能算记事本，这一轮它长出了四处自动化。地基是一条约定：一个 issue = 一个 worktree = 一个 PR，一张卡从开工到合并走完整闭环，下面的自动化都围着它转。</p>
<p><strong>主卡 + 子卡（官方 sub-issue）</strong>。一个专项一张主卡，拆出的子卡用 GitHub 官方 sub-issue API 挂接，父卡页面自动显示进度条，子卡关闭自动勾选。之前手写 <code>- [ ] #N</code> tasklist 的做法废弃——它没有任何联动，最后一个子卡关了父卡还傻开着（这个坑真踩过：两个专项主卡都手动收的尾）。后来干脆写了个 30 行的 Action：<strong>最后一个子卡关闭时自动关闭父卡</strong>，专项生命周期零手动维护。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-epic-subissue-progress.png" alt="主卡子卡进度条"  />
</p>
<p>这个 Action 上线前还撞了一堵测试永远测不出的墙：<code>issues</code> 事件的 workflow，GitHub 只认默认分支上的版本。PR 分支里写得再对、本地 dry-run 全过，事件就是不派发——静默的，连报错都没有。「关父卡」这个动作因此没法在 PR 里真实验证，只能合进 master，等第一张收官的专项卡来检验。改 CI 配置类的东西，验证闭环天生缺一半。</p>
<p><strong>建卡脚本</strong>。手工建 issue 的坑：14 张新卡全部漏挂看板、漏设字段——看板过滤直接失灵。现在建卡一律走脚本：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">scripts/new-issue.sh --title <span class="s2">&#34;xxx&#34;</span> --body-file card.md <span class="se">\
</span></span></span><span class="line"><span class="cl">  --type bug --phase <span class="m">1</span> --area backend --priority P1 --labels area/hotkey
</span></span></code></pre></div><p>一条命令完成：issue 创建（含类型标签 + @me 指派）→ 挂板 → Status=Todo → Phase/Area/Priority/Milestone。建卡即合规，不靠记性。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-projects-todolist.png" alt="建卡脚本效果：Todo 视图 9 张卡，状态/标签/优先级全部有值"  />
</p>
<p><strong>三条自动流转</strong>：PR squash 合并 → issue 自动关 → 卡片自动进 Done；master CI 变红 → 自动开一张「master CI 红」跟卡，恢复绿自动关；最后一个子卡关闭 → 父专项卡自动关闭。加上 master 红时其他 PR 的<strong>停线门禁</strong>（快速失败，修复类 PR 打 <code>area/ci</code> 标签放行），看板从「任务的墓志铭」变成了「活的调度器」——这句是合并当天写的，现在看依然成立。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-projects-board.png" alt="status_board 三列：Todo 14 / In Progress 1 / Done 89"  />
</p>
<p><strong>认领协议</strong>（防撞车）：开工前必须先把卡片置 In Progress 占坑 + 扫一眼有没有同卡的 open PR。这条是被撞出来的——两个会话同时开工一张卡，第二个的分支自动加了 <code>-2</code> 后缀：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-collision-branch-suffix.png" alt="同卡撞车，分支自动 -2 后缀"  />
</p>
<h3 id="执行层多实例隔离测试与正式互不打架">执行层：多实例隔离，测试与正式互不打架</h3>
<p>上一篇没解决的一个问题：正式实例在自测，另一个会话要起实例验证代码——单实例锁、端口、数据目录全绑死一份，只能互相杀。</p>
<p>解法是给实例一个身份：<code>PANTA_DATA_DIR</code> 环境变量把数据目录（锁、数据库、日志）整体搬走，<code>PANTA_PORT</code> 换端口：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">scripts/dev.sh                                                    <span class="c1"># 正式实例</span>
</span></span><span class="line"><span class="cl"><span class="nv">PANTA_DATA_DIR</span><span class="o">=</span>~/.pantalog-dev <span class="nv">PANTA_PORT</span><span class="o">=</span><span class="m">9787</span> scripts/dev.sh     <span class="c1"># 测试实例</span>
</span></span></code></pre></div><p>两个实例并行互不知道对方存在。不设环境变量时行为与原来完全一致，单实例防护不削弱。测试实例默认不注册全局热键（双实例抢系统热键没有赢家）。</p>
<h3 id="ci-层把review-跟不上交给机器">CI 层：把「review 跟不上」交给机器</h3>
<p>这是整个体系里最实的一层。先把丑话说在前面：多 agent 并行交付，PR 产生的速度远超我读 diff 的速度，很多 PR 我是扫一眼描述就合并的，并不确定测试是否存在、断言是否有效。解法不是更认真地 review（不可扩展），是把 review 里能机械化的部分全机械化。</p>
<p>还有一个前提得先交代：仓库在 GitHub 免费套餐上，分支保护配不了，API 实测 403。原生 required checks 用不了，「不让红的进 master」就没法交给平台，只能自己造两层：机器能硬卡的做进 CI（下面这些门禁全是）；机器管不了的，比如「合并前到底看没看 checks」，写成红线协议塞进 CONTRIBUTING.md，当每个会话的交通规则。</p>
<p><strong>覆盖率三件套</strong>：</p>
<ol>
<li>PR 自动评论覆盖率变化——数字可见本身就有约束力：</li>
</ol>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-coverage-pr-comment.png" alt="PR 覆盖率自动评论"  />
</p>
<ol start="2">
<li><strong>基线棘轮</strong>：<code>--cov-fail-under</code> 把全量覆盖率封底，只许升不许降（71.5 一路涨到 79，因为还债和带测试的修复在推高它）</li>
<li><strong>diff-cover 增量门禁</strong>：PR 改动/新增的行强制测试触达 ≥80%，否则红、无法合并——存量零覆盖不追缴，新代码没测试就物理上进不来</li>
</ol>
<p>覆盖率只回答「有没有测试」，回答不了「测试测的是什么」。最疼的一次来自旧库升级：测试套件每个用例都从 <code>create_all</code> 建新库开始，全绿；用户手里的旧库升级路径零覆盖，一启动就崩——新库永远测不出迁移 bug。此后立了铁律：动 schema 必须附「旧库就地升级」测试，用旧 schema 建库、跑迁移、断言结果，新库验证不算数。</p>
<p><strong>前端三道棘轮</strong>（思路同源：存量封顶、增量达标）：禁新增 ts-ignore、单文件行数封顶、i18n 双语 key 一致性。加上 oxlint+oxfmt 基线，前端从零约束追平了后端 Ruff 的治理水平。</p>
<p><strong>运维细节</strong>：每个 job 硬超时（默认 360 分钟，挂死一次烧穿私库按分钟计费的额度）、concurrency 取消旧 run、runner 只用 ubuntu（私库按分钟计费，macOS 十倍费率用不起）、master 红自动跟卡：</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-master-ci-alarm.png" alt="master CI 红自动跟卡"  />
</p>
<p><strong>红线协议：测试永远测不出的那部分</strong>。门禁管代码，管不住流程。五天里真正造成损失的坑，没有一个能被测试拦住：</p>
<ul>
<li><strong>带红合并</strong>：master 变红过两次，都是 PR 还红着就合造成的。其中一次特别迷惑——本地全绿、CI 红，最后查清是 pytest 撞了 UTC 边界，北京早 8 点前后才触发。此后第一条红线：<code>gh pr checks</code> 全绿才许合并；日期相关的测试失败，先怀疑时区再怀疑代码。</li>
<li><strong>重复修</strong>：master 红了一次，两个会话同时开工修同一个问题，先落地的合了，后落地的整个作废重做。此后修前必看板 + 最新 run，确认没有别人在修同一张卡。</li>
<li><strong>继承错误逐卡修</strong>：master 红时切出去的新分支，错误跟着进每个 worktree。正解是修完 master 后各自 rebase，继承的错误随 rebase 消失；在多张卡里各自修同一个 master 问题，等于把一个 bug 修 N 遍。</li>
<li><strong>网页绕行</strong>：PR 冲突必须在本地 rebase 解决、跑绿、<code>--force-with-lease</code> 推回。在 GitHub 网页上手改文件「绕过」冲突，等于跳过本地测试直接进 master。</li>
</ul>
<p>五条规则（还有一条「master 红就停线：不合并、不开新卡」）全写在 CONTRIBUTING.md 的「CI 红线规则」里，每个会话开工前必读。</p>
<h3 id="基建层崩溃教出来的基础设施">基建层：崩溃教出来的基础设施</h3>
<p><strong>日志落盘</strong>。起因是某天早上的一场三连崩：启动时 16 条积压任务批量补投，每条各起线程调本地转写模型，MLX 的 GPU stream 线程绑定、并发直接 Metal 层 C++ 异常 → 主进程当场死亡 → 不走任何清理逻辑 → 子进程 UI 窗口成孤儿还开着。排查时发现日志只在终端，崩了连现场都没留下。修完之后日志体系是三层：后端轮转落盘、前端错误上报落盘、测试进程隔离（不污染用户日志）。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/guardrails-crash-log.png" alt="三连崩日志现场"  />
</p>
<p>日志第一次派上用场就值回票价：排查「转写卡很久」——从日志实锤三个叠加原因（批量串行排队、同日期聚合被重复触发 N 次、GLM 偶发返回不合规 JSON），顺手各修各的卡。</p>
<p><strong>转写 worker 子进程</strong>。转写是 GPU 满载的重活，还持有 Python 全局锁把 API 线程饿死。挪进独立子进程后主进程永远响应，子进程退出连显存缓存一起释放。配套硬约束：父死子退（getppid 看门狗）——强退程序就是全停，转写中的任务重启后自动补投，不丢数据。</p>
<p><strong>导入内容校验</strong>。测试残留的 23 个假 WAV（内容是 2048 个字母 x）被当真导入，直到转写才报一坨错。现在文件头魔数 + ffprobe 可解码探测，垃圾在门口被拦。配套还有时长上限：超长录音入库标 <code>too_long</code> 待手动转写，不再占用队列。</p>
<h3 id="最有价值的一课ai-实现跑偏了产品意图">最有价值的一课：AI 实现跑偏了产品意图</h3>
<p>五天里最值得写的发现不是技术问题。复盘时我意识到：每条录音处理完都会调一次 LLM 生成「AI 回顾草稿」（评分、心情、下一步），还会触发一次当日汇总——而我的产品文档写的是：<strong>录音级只做转写和结构化提取；每日回顾是「当天多条语音的合并」，在复盘页看</strong>。文档白纸黑字，实现凭空多出一层。</p>
<p>代价清单：LLM 调用量翻倍（当天额度打爆）、时间线多了没人要的草稿块、状态机多了误导性的「转写中」、队列被拉长。它存在了好几天，写它的 agent 没发现，验收它的我也没发现。</p>
<p>教训：agent 写完不会自己拿产品文档对照，这个验收动作只能人做。修正卡当天开、当天关：录音级只留转写 + 提取（事实/计划/想法/问题，承诺闭环的数据源），AI 回顾回归日级聚合（带防抖），prompt 集中管理与评测联动。</p>
<h3 id="反思ai-时代的质量观">反思：AI 时代的质量观</h3>
<p>五天下来，对「AI 写代码，人干什么」有了具体得多的答案。「review 跟不上」的正确解法不是更认真地 review，认真不可扩展。能机械化的部分全机械化：覆盖率棘轮挡住没有测试的代码，diff-cover 挡住改了没测的行，lint 和 guards 挡住风格漂移。下限交给机器，人只管机器管不了的那部分——这个功能该不该有，做得好不好，是不是我想要的。</p>
<p>多 agent 并行同理：协调成本是真实的。五个会话同时开工时，撞车、抢号、互相污染工作区都会发生——规范和脚本不是官僚主义，是把协调成本从人肉记忆挪进脚本。</p>
<p>下一步：V0.1 的退出条件是连续 14 天真机自测（录音 → 次日勾选闭环）。护栏立完了，接下来该真用了。</p>
<hr>
<p>数据截至 2026-09-16 定稿：122 commits / 111 merged PRs / 127 issues；覆盖率 71.5% → 79.6% 且基线棘轮持续生效；全部工作由多个 Claude Code agent 在 Orca worktree 中并行完成。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Orca &#43; GitHub Projects：跑通 AI 编程工作流的第一天</title>
      <link>https://blog.xiaohuangyu.space/p/github-projects-orca-agent-workflow/</link>
      <pubDate>Fri, 11 Sep 2026 23:55:00 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/github-projects-orca-agent-workflow/</guid>
      <description>&lt;p&gt;记录下用 GitHub Projects + Orca 把 AI 编程工作流跑通的过程，踩的坑都在里面，以 macOS 为例。&lt;/p&gt;&#xA;&lt;p&gt;背景：手头有个 side project（panta-log，本地优先的语音复盘工具），之前 issue/PR 规范一直躺在另一个项目里没落地。这次目标很明确：看板管任务，Orca 跑 agent，一天之内把「领任务 → 开发 → 测试 → 合并 → 状态自动流转」整条链跑通。&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>记录下用 GitHub Projects + Orca 把 AI 编程工作流跑通的过程，踩的坑都在里面，以 macOS 为例。</p>
<p>背景：手头有个 side project（panta-log，本地优先的语音复盘工具），之前 issue/PR 规范一直躺在另一个项目里没落地。这次目标很明确：看板管任务，Orca 跑 agent，一天之内把「领任务 → 开发 → 测试 → 合并 → 状态自动流转」整条链跑通。</p>
<p>先看最终跑通后的闭环长什么样：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">看板挑卡(Todo) → Orca 从卡片开 worktree → agent 干活（自跑测试）
</span></span><span class="line"><span class="cl">→ PR 触发 CI → 审 diff → squash merge
</span></span><span class="line"><span class="cl">→ issue 自动关闭 → 看板卡片自动进 Done → 远端分支自动删除
</span></span></code></pre></div><h3 id="第一步规范落地">第一步：规范落地</h3>
<p>直接从自己的 boss-zhipin-scraper 项目抄了一套：issue 模板（bug/feature/question 三个 yml）、PR 模板、CONTRIBUTING.md，改成新项目的技术栈（uv、pytest、macOS 权限那些禁忌）。推上去之后仓库的 New issue 页面就有中文表单了，这步没什么好说的，五分钟的事。</p>
<h3 id="第二步用-gh-cli-批量建-backlog">第二步：用 gh CLI 批量建 backlog</h3>
<p>Roadmap 文档里本来就有六个工作包、带验收标准，照着拆就行。原则：</p>
<ul>
<li>只把「需改造」和「需新建」的任务建成 issue，已经能用的不建，别污染看板</li>
<li>标题带上任务编号（WP-A1 这种），看板上一眼能对回文档</li>
<li>正文直接引用 roadmap 的验收标准原文，再加一句建议批次（第几周做）</li>
<li>全部挂到 milestone 上，milestone 描述里写清退出条件</li>
</ul>
<p>18 个 issue，两个 for 循环的事。</p>
<h3 id="第三步踩坑重灾区gh-project-cli">第三步：踩坑重灾区——gh project CLI</h3>
<p>Projects 的操作大部分能用命令行做，但命令的坑一个接一个，全是实际踩出来的：</p>
<p><strong>坑 1：<code>gh auth refresh</code> 非交互执行必须加 <code>-h</code></strong></p>
<p>在 Claude Code 里用 <code>!</code> 前缀跑命令是非交互模式，直接报错：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">--hostname required when not running interactively
</span></span></code></pre></div><p>要写成 <code>gh auth refresh -h github.com -s read:project,project</code>。另外这个命令要设备授权，进程会卡在那等浏览器确认，放后台跑，从输出里把 one-time code 捞出来，去 github.com/login/device 输入就行。</p>
<p><strong>坑 2：field-create 的参数是 <code>--name</code>，不是 <code>--title</code></strong></p>
<p><code>gh project field-create --title &quot;Phase&quot;</code> 会直接 unknown flag。帮助文档里两种写法都出现过，以 <code>--name</code> 为准。</p>
<p><strong>坑 3：<code>-q</code> 必须配 <code>--format json</code></strong></p>
<p>这条最阴险。<code>gh project item-add &lt;n&gt; --owner me --url xxx -q '.id'</code> 会静默失败，报错是 <code>cannot use --jq without specifying --format json</code>。批量脚本里 18 个 item 全挂了还看不到原因（stderr 被吞了）。正确写法：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh project item-add <span class="m">2</span> --owner eatmoreduck --url <span class="s2">&#34;https://github.com/xxx/issues/1&#34;</span> --format json -q <span class="s1">&#39;.id&#39;</span>
</span></span></code></pre></div><p><strong>坑 4：item-edit 用的是 <code>--project-id</code>，不是 <code>--owner</code> + <code>--project-number</code></strong></p>
<p>前面 item-add 都是 number + owner 的组合，到 item-edit 突然变了，要用项目全局 ID（形如 <code>PVT_xxxx</code>，project list 里能看到）：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh project item-edit --id &lt;item-id&gt; --project-id PVT_xxxx <span class="se">\
</span></span></span><span class="line"><span class="cl">  --field-id &lt;field-id&gt; --single-select-option-id &lt;option-id&gt;
</span></span></code></pre></div><p><strong>坑 5：item-list 的 JSON 里 fieldValues 是 null</strong></p>
<p>挂完板想核对字段值，<code>gh project item-list --format json</code> 返回的 fieldValues 全是 null，不是没设置上，是这接口压根不返回。想验证只能上 GraphQL：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh api graphql -f <span class="nv">query</span><span class="o">=</span><span class="s1">&#39;query($login:String!,$number:Int!){
</span></span></span><span class="line"><span class="cl"><span class="s1">  user(login:$login){ projectV2(number:$number){
</span></span></span><span class="line"><span class="cl"><span class="s1">    items(first:30){ nodes{
</span></span></span><span class="line"><span class="cl"><span class="s1">      content{ ... on Issue { number } }
</span></span></span><span class="line"><span class="cl"><span class="s1">      fieldValues(first:20){ nodes{
</span></span></span><span class="line"><span class="cl"><span class="s1">        ... on ProjectV2ItemFieldSingleSelectValue { name field{ ... on ProjectV2FieldCommon { name } } }
</span></span></span><span class="line"><span class="cl"><span class="s1">      } }
</span></span></span><span class="line"><span class="cl"><span class="s1">    } } } }
</span></span></span><span class="line"><span class="cl"><span class="s1">}&#39;</span> -f <span class="nv">login</span><span class="o">=</span>eatmoreduck -F <span class="nv">number</span><span class="o">=</span><span class="m">2</span> --jq <span class="s1">&#39;...&#39;</span>
</span></span></code></pre></div><p>建两个单选字段（Phase 对应版本分期、Area 对应模块），18 张卡批量挂板、设 Status/Phase/Area，再建两个日期字段给时间线用。一次搞定。</p>
<h3 id="orca-接入比想象的省事">Orca 接入：比想象的省事</h3>
<p>本来以为要在 Orca 里走一遍 GitHub OAuth，结果打开集成页面发现 GitHub 已经是 Connected 状态。原因是 Orca 的 GitHub 集成直接读本机 gh CLI 的登录凭据，gh 登录过就算接好了，根本不存在「连接并授权」按钮。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/orca-github-connected.png" alt="Orca 集成页 GitHub 已显示 Connected"  />
</p>
<p>还有个小迷惑：想找看板找不到。Orca 的「任务」页面顶部有三个标签——议题、PR、项目。issue 列表在「议题」里，<strong>看板在「项目」标签里</strong>，从卡片右键就能创建 worktree，composer 会自动预填任务名并链接 issue。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/orca-issue-list.png" alt="Orca 任务页的三个标签"  />
</p>
<h3 id="看板自动化两条规则默认就是开的">看板自动化：两条规则，默认就是开的</h3>
<p>闭环的引擎是 Project 自带的两条工作流：</p>
<ul>
<li>Item added to project → Set Status = Todo（新卡自动入列）</li>
<li>When pull request merged → Set Status = Done（合并自动流转）</li>
</ul>
<p>有个反直觉的地方：这两条<strong>项目创建出来就是 On 的状态</strong>，什么都不用配。我一开始以为得去网页设置里手动开，还专门写进了待办清单，后来打开 Workflows 面板一看，人家早就在干活了。查了一圈才确认 gh CLI 压根没有管理 Workflows 的子命令（<code>gh project --help</code> 里只有增删改查 item 和 field），所以这东西既没法命令行关掉也没法命令行开，只能去项目页面的 Workflows 面板查看和调整。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/github-project-workflow-pr-merged.png" alt="Pull request merged 工作流配置"  />
</p>
<p>它们生效之后，merge PR 的瞬间：issue 自动关（commit 里写了 Closes #n）、卡片自动进 Done，全程无感。</p>
<h3 id="roadmap-时间线日期值可以命令行灌">Roadmap 时间线：日期值可以命令行灌</h3>
<p>时间线视图打开一片空白，因为每个 item 都没有日期。做法：</p>
<ol>
<li>建 <code>Start date</code> / <code>Target date</code> 两个日期字段</li>
<li>视图工具栏的 Date fields 里把起止指向这两个字段</li>
<li>日期值按 roadmap 的执行批次用命令灌：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh project item-edit --id &lt;item-id&gt; --project-id PVT_xxxx <span class="se">\
</span></span></span><span class="line"><span class="cl">  --field-id &lt;start-field-id&gt; --date <span class="s2">&#34;2026-09-14&#34;</span>
</span></span></code></pre></div><p>灌完时间线上就是一根根条了，之后直接拖拽调期，字段值会跟着变。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/github-project-roadmap-timeline.png" alt="Roadmap 时间线视图"  />
</p>
<h3 id="多开-agent可以但别贪">多开 agent：可以，但别贪</h3>
<p>Orca 的核心玩法就是一个任务一个独立 git worktree，几个 agent 并行互不踩分支。实测确实如此，两个任务同时跑，互不干扰。</p>
<p>但有几个实际经验：</p>
<ul>
<li><strong>挑卡要避开文件冲突</strong>。两个任务都改同一个文件，后合的必然冲突。同子系统的任务（比如都动转写模块的）别并行</li>
<li><strong>并行 2-3 张，merge 串行</strong>。瓶颈根本不在写代码，在 review。一口气开五个 agent，五个 PR 堆在那里你审不过来，盲合进核心管线等于裸奔</li>
<li>智能体仪表盘三列（需要你 / 工作中 / 已完成）就是多开时的管理面板，agent 停下来等确认会出现在「需要你」列</li>
</ul>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/orca-agents-dashboard.png" alt="智能体仪表盘"  />
</p>
<p>另外 Orca 不会自动从看板领卡派活，挑哪张卡什么时候开还是人说了算。这反而是好事。</p>
<h3 id="ci-也扔给-agent-建">CI 也扔给 agent 建</h3>
<p>仓库没有 CI，PR 级的自动测试就是空的。我的做法是先提一个 issue 把约束写死：私有仓库 Actions 分钟数计费、macOS runner 按 10 倍费率所以必须锁 ubuntu runner、只加一个 workflow 文件、不引入 ESLint/mypy。然后开个 worktree 交给 agent。</p>
<p>结果它把验收标准全打勾了：backend（ruff + 88 个测试）和 frontend build 双 job 全绿，合计 40 秒出头。中间还自己踩坑自己修——ubuntu 的 sounddevice 缺 PortAudio 依赖，它在 CI 里补了 <code>apt-get install libportaudio2</code>。更绝的是第一轮它故意看着 CI 红了一次才修，验证失败报警机制真的能响。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/orca-pr-checks-passed.png" alt="PR checks 全部通过"  />
</p>
<p>这里有个经验值得记：<strong>给 agent 的 issue 写得越具体（约束、边界、验收标准），产出越省心</strong>。模糊的「帮我加个 CI」和带计费约束、验收标准的 issue，产出质量差很远。</p>
<h3 id="审查和合并不用出-orca">审查和合并不用出 Orca</h3>
<p>审 diff、给 agent 提修改意见、合并，全程在 Orca 里：</p>
<ul>
<li>Diff viewer 逐行看，有问题直接在那个 worktree 的 agent 会话里说，改完 push 同一个 PR 自动更新</li>
<li>Checks 面板看 CI 状态，失败可以直接一键把失败的 check 交给 agent 修</li>
</ul>
<p>然后是这次最典型的一个误用：合并按钮找不着，右上角那个「提交」按钮还是灰的。</p>
<p>灰是对的——那是 <strong>git 推送按钮</strong>，没东西可推当然灰。合并入口在 <strong>PR 详情视图里</strong>（从 PR 列表点进去那一页），合并按钮带方式下拉，跟网页版一个逻辑。</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/orca-source-control-menu.png" alt="右侧菜单是 git 操作，不是合并入口"  />
</p>
<h3 id="merge-方式选-squash别犹豫">merge 方式：选 squash，别犹豫</h3>
<p>三种方式的区别一句话说清：</p>
<ul>
<li><strong>Squash</strong>：整个 PR 压成 master 上一个提交，中间提交全丢弃</li>
<li><strong>Rebase</strong>：每个提交逐个重放上来，中间提交全保留</li>
<li><strong>Merge commit</strong>：原样合并，再加一个合并节点，历史变分叉图</li>
</ul>
<p>AI agent 的产出场景，squash 是唯一解。agent 的中间提交全是「fix typo」「round 2」这种碎片，没有保留价值。squash 之后一张卡对应 master 上一个干净提交，回滚就是 revert 一条，<code>Closes #n</code> 写在 PR 描述里照样生效。另外两种只在多人协作保留分支拓扑、或你亲手精心整理过提交序列时才有意义。</p>
<h3 id="仓库设置两个开关分开看">仓库设置：两个开关分开看</h3>
<ul>
<li><strong>Automatically delete head branches</strong>：合并后自动删远端分支。开了立即受益，不然二十张卡的分支堆在远端没人清。本地 worktree 不受影响，用完在 Orca 里手动删</li>
<li><strong>Allow auto-merge</strong>：让 PR 可以设「checks 全绿自动合」。注意这只是解锁功能，不对具体 PR 启用就什么都不会发生。还有，<strong>没有 CI 的时候开了也是摆设</strong>——没有任何 checks 可等。所以顺序是：先开自动删分支，auto-merge 等 CI 上线再说</li>
</ul>
<h3 id="一天下来的小结">一天下来的小结</h3>
<table>
  <thead>
      <tr>
          <th>事项</th>
          <th>状态</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>issue/PR 模板 + 贡献指南</td>
          <td>已推送生效</td>
      </tr>
      <tr>
          <td>19 个 issue + milestone + 看板字段</td>
          <td>全部挂板，GraphQL 逐条核验过</td>
      </tr>
      <tr>
          <td>两条看板自动化</td>
          <td>默认开启，零配置</td>
      </tr>
      <tr>
          <td>Roadmap 时间线</td>
          <td>三批次日期已灌入</td>
      </tr>
      <tr>
          <td>CI（agent 自建）</td>
          <td>已合并生效，双 job 全绿</td>
      </tr>
      <tr>
          <td>完整闭环</td>
          <td>第一张卡从挑卡到 Done 全自动流转验证通过</td>
      </tr>
  </tbody>
</table>
<p>最大的感受：这套东西搭完之后，「管理任务」这个动作本身消失了——剩下的就是把卡一张张挪完。工具链各管一段：GitHub Projects 记状态，Orca 管 agent 和 worktree，gh CLI 补一切自动化的缝。</p>
<p>后面打算把「每天开工先看看板挑两张卡」养成习惯，看板不撒谎，进度不用记。</p>
]]></content:encoded>
    </item>
    <item>
      <title>2026 Mac 开发全栈工具｜淘汰 Alfred/iTerm/Docker Desktop，我的最终软件清单</title>
      <link>https://blog.xiaohuangyu.space/p/my-software-stack-2026/</link>
      <pubDate>Tue, 23 Jun 2026 20:00:00 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/my-software-stack-2026/</guid>
      <description>&lt;p&gt;距离上一篇 &lt;a href=&#34;https://blog.xiaohuangyu.space/p/mac-dev-software-list/&#34;&gt;Mac 开发常用软件清单&lt;/a&gt; 过去两年多了。翻出来看了一下，里面有些东西已经不在了，有些被更好的替代了，也有些我到现在还在用。&lt;/p&gt;&#xA;&lt;h2 id=&#34;先说哪些变了&#34;&gt;先说哪些变了&lt;/h2&gt;&#xA;&lt;p&gt;旧清单里这几个我现在已经不用了：&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>距离上一篇 <a href="https://blog.xiaohuangyu.space/p/mac-dev-software-list/">Mac 开发常用软件清单</a> 过去两年多了。翻出来看了一下，里面有些东西已经不在了，有些被更好的替代了，也有些我到现在还在用。</p>
<h2 id="先说哪些变了">先说哪些变了</h2>
<p>旧清单里这几个我现在已经不用了：</p>
<ul>
<li><strong>Alfred</strong> —— 被 Raycast 完全取代了。付费墙又高，免费版能干的事太少。</li>
<li><strong>Mos / Mac Mouse Fix 二选一</strong> —— 现在只留 Mac Mouse Fix，它新版本窗口管理也做了，比以前好用。</li>
<li><strong>Loop</strong> —— 留给 Mac Mouse Fix 的窗口管理之后撤了。</li>
<li><strong>EasyDevo</strong> —— DevToys 够用了。</li>
<li><strong>Termius</strong> —— SSH 直接交给 Ghostty + 系统 ssh 配置，多端同步的需求没了。</li>
<li><strong>lux（B 站下载）</strong> —— 不怎么下了。</li>
</ul>
<p>下文按我现在真实的用法重新整理。</p>
<h2 id="ai-编程">AI 编程</h2>
<p>这是这两年变化最大的部分，单独拎出来。</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Code</td>
          <td>主力，配合 GLM 和其他第三方模型用</td>
      </tr>
      <tr>
          <td>Codex</td>
          <td>OpenAI 的命令行 agent，写代码</td>
      </tr>
      <tr>
          <td>Cursor</td>
          <td>图形化的 AI 编辑器，需要看大文件、改前端的时候顺手</td>
      </tr>
      <tr>
          <td>Gemini / 豆包 / 通义 / 元宝</td>
          <td>桌面客户端，分别对应几家的模型，谁好用问谁</td>
      </tr>
  </tbody>
</table>
<p>说实话现在 AI 编程工具已经多到有点过剩了。我的实际状态是 Claude Code 当主力，剩下几个客户端拿来对比同一个问题不同模型的回答。没必要全装，挑一两个顺手的就行。</p>
<h2 id="编辑器和-ide">编辑器和 IDE</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GoLand</td>
          <td>写 Go 的主力，JetBrains 的索引还是最舒服</td>
      </tr>
      <tr>
          <td>WebStorm</td>
          <td>前端项目用</td>
      </tr>
      <tr>
          <td>PyCharm</td>
          <td>偶尔写 Python</td>
      </tr>
      <tr>
          <td>IntelliJ IDEA</td>
          <td>Java 项目</td>
      </tr>
      <tr>
          <td>Sublime Text</td>
          <td>快速打开大文件看代码，启动快</td>
      </tr>
      <tr>
          <td>ZCode</td>
          <td>另一个命令行 agent</td>
      </tr>
  </tbody>
</table>
<p>JetBrains 全家桶还是吃内存大户，但代码跳转和重构这块没什么能打的。Sublime 留着纯粹是因为它打开几万行的日志文件不卡。</p>
<h2 id="笔记">笔记</h2>
<p>笔记类我同时开着三个：Obsidian、语雀、Notion。不是因为选择困难，是它们在我这儿干的活不一样，谁也替代不了谁。</p>
<p>先给个速览：</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>我的定位</th>
          <th>数据在哪</th>
          <th>适合谁</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Obsidian</td>
          <td>私人第二大脑，给自己看</td>
          <td>全在本地</td>
          <td>长期沉淀、想要完全掌控的人</td>
      </tr>
      <tr>
          <td>语雀</td>
          <td>技术文档沉淀，结构化的知识库</td>
          <td>云端</td>
          <td>喜欢文档树、做团队/项目 Wiki 的人</td>
      </tr>
      <tr>
          <td>Notion</td>
          <td>公开分享和对外知识库</td>
          <td>云端</td>
          <td>需要对外展示、追求页面好看的人</td>
      </tr>
  </tbody>
</table>
<h3 id="obsidian我的主力">Obsidian：我的主力</h3>
<p>这篇博客就是 Obsidian 写的，平时记的笔记、写的 skill、攒的技术资料全在里面。它的核心好处是<strong>文件全在本地、纯 Markdown</strong>，不被任何一个云服务绑住，哪天想迁随时能迁。双链和图谱让笔记之间能连起来，越攒越有价值，不像传统笔记写到后面就成了一堆找不到的死文档。</p>
<p>它是个本地工具，发布得自己搭。我自己搭过两套，可以看看：</p>
<ul>
<li><a href="https://blog.xiaohuangyu.space/p/hugo-obsidian-static-blog1/">hugo+obsidian 打造最强博客（一）</a> 和 <a href="https://blog.xiaohuangyu.space/p/hugo-obsidian-static-blog2/">(二)</a> —— 怎么把 Obsidian 接到 Hugo 博客上</li>
<li><a href="https://blog.xiaohuangyu.space/p/obsidian-claude-code-ai-second-brain-guide/">Obsidian + Claude Code 构建 AI 第二大脑</a> —— 后来又把 AI 接进来，让笔记真正&quot;活&quot;起来</li>
</ul>
<h3 id="语雀技术文档沉淀">语雀：技术文档沉淀</h3>
<p>技术类的东西我往语雀放。它那套文档树结构很适合做知识库分层，一个项目从设计到实现拆成一块块挂上去，回头看一目了然。语雀的编辑器对代码块、公式、画板这些支持得比较细，写技术文档比 Markdown 裸写舒服。缺点是云端封闭，导出没那么自由，所以我只把&quot;需要结构化整理、长期维护&quot;的技术内容放这。</p>
<h3 id="notion对外分享">Notion：对外分享</h3>
<p>Notion 我其实用得不多，但留着有它的道理——<strong>公开分享和对外知识库这块，它最好用</strong>。Notion 的页面能直接发布成公开链接，排版好看、多媒体混排方便，拿来做个人主页、项目介绍、对外教程很合适，对 SEO 也友好。我自己不拿它记日常笔记，但要做给别人看的东西，会优先考虑它。</p>
<h3 id="我的实际分工">我的实际分工</h3>
<p>简单说就是：<strong>Obsidian 管输入和沉淀，语雀管技术整理，Notion 管对外输出</strong>。如果你只挑一个，长期沉淀选 Obsidian；要带团队做 Wiki 选语雀；要做对外内容选 Notion。三个都装也不是浪费，前提是给每个工具一个明确的角色，别什么都往一个里塞。</p>
<p>另外还有个 <strong>Anki</strong>，不在上面三个的赛道里。它是纯记忆工具，碎片时间拿来刷卡片，背单词和记技术知识点，配合 Easydict 存生词挺好用。</p>
<h2 id="终端和-shell">终端和 Shell</h2>
<p>这块这两年换得最彻底。</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ghostty</td>
          <td>现在的主力终端，GPU 渲染，配置极简</td>
      </tr>
      <tr>
          <td>Oh My Zsh</td>
          <td>还是它，配 powerlevel10k 主题</td>
      </tr>
      <tr>
          <td>powerlevel10k</td>
          <td>提示符主题，instant prompt 让启动快很多</td>
      </tr>
      <tr>
          <td>zsh-autosuggestions</td>
          <td>命令自动补全</td>
      </tr>
      <tr>
          <td>zsh-syntax-highlighting</td>
          <td>命令语法高亮</td>
      </tr>
  </tbody>
</table>
<p>以前用 iTerm2，换到 Ghostty 主要是图它快和干净。配置文件就一个，没有什么花里胡哨的设置面板，我反而更喜欢。</p>
<p>Shell 这套配置我没怎么折腾，就四样东西：Oh My Zsh、p10k、自动补全、语法高亮。够用了，再往上加插件启动会变慢。</p>
<h2 id="命令行工具">命令行工具</h2>
<p>这是旧清单里完全没覆盖的部分，但其实是我每天用得最多的。</p>
<h3 id="包管理和运行时">包管理和运行时</h3>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Homebrew</td>
          <td>Mac 上装一切的基础</td>
      </tr>
      <tr>
          <td>uv</td>
          <td>Python 的包管理和虚拟环境，比 pip + venv 快得多，现在基本不碰 pip 了</td>
      </tr>
      <tr>
          <td>bun</td>
          <td>JS 运行时和包管理，比 node 快</td>
      </tr>
      <tr>
          <td>nvm</td>
          <td>多版本 node 切换</td>
      </tr>
      <tr>
          <td>pyenv</td>
          <td>多版本 Python 切换</td>
      </tr>
  </tbody>
</table>
<p>uv 是这两年我最想安利的 Python 工具。装依赖、建虚拟环境、跑脚本，全用它一个，不用再记 <code>python -m venv</code> 那一串。配合 <code>uv run</code> 直接在临时环境里跑脚本特别舒服。</p>
<h3 id="日常高频">日常高频</h3>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>gh</td>
          <td>GitHub 官方命令行，开 PR、看 issue、clone 仓库都靠它</td>
      </tr>
      <tr>
          <td>git</td>
          <td>不用多说了</td>
      </tr>
      <tr>
          <td>task (go-task)</td>
          <td>像 make 但是用 YAML 写，跨平台，项目里的自动化我都用它</td>
      </tr>
      <tr>
          <td>ffmpeg</td>
          <td>处理音视频，转格式、剪片段、抽音频</td>
      </tr>
      <tr>
          <td>tree</td>
          <td>看目录结构</td>
      </tr>
      <tr>
          <td>telnet</td>
          <td>偶尔测端口用</td>
      </tr>
  </tbody>
</table>
<p><code>task</code> 这个我想多说一句。以前项目里一堆 <code>Makefile</code>，写起来不直观还容易写错。换成 task 之后，<code>taskfile.yml</code> 一眼能看懂在干什么，Windows 上也能跑，团队协作省心很多。</p>
<h3 id="系统监控">系统监控</h3>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>fastfetch</td>
          <td>neofetch 的替代，启动快，看系统信息用的</td>
      </tr>
      <tr>
          <td>mactop</td>
          <td>苹果芯片上的 top，比 htop 更懂 M 系列的架构</td>
      </tr>
      <tr>
          <td>kubectl</td>
          <td>偶尔连集群</td>
      </tr>
  </tbody>
</table>
<p>mactop 是 Apple Silicon 上我比较推荐的。它能显示 CPU 各个性能核和能效核的占用，还有 GPU、内存带宽这些，htop 看不到。</p>
<h2 id="容器和虚拟化">容器和虚拟化</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>OrbStack</td>
          <td>Docker Desktop 的替代，启动快、占内存少、还能跑 Linux 虚拟机</td>
      </tr>
      <tr>
          <td>Docker</td>
          <td>兼容性需要的时候还是会用</td>
      </tr>
  </tbody>
</table>
<p>从 Docker Desktop 换到 OrbStack 是另一个&quot;用完回不去&quot;的体验。同样的容器，OrbStack 启动快一截，内存占用也小，而且它内置的 Linux 虚拟机可以当轻量开发环境用。Docker 留着主要是有些 CI 本地复现的时候要保证环境一致。</p>
<h2 id="数据库和网络">数据库和网络</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Another Redis Desktop Manager</td>
          <td>Redis 客户端</td>
      </tr>
      <tr>
          <td>DataGrip</td>
          <td>数据库通用客户端，连啥都行</td>
      </tr>
      <tr>
          <td>SecureCRT / SecureFX</td>
          <td>老牌终端和文件传输，付费</td>
      </tr>
      <tr>
          <td>Wireshark</td>
          <td>抓包，排查网络问题</td>
      </tr>
      <tr>
          <td>ZeroTier</td>
          <td>虚拟局域网，组网用</td>
      </tr>
  </tbody>
</table>
<p>Navicat 我现在没装了，DataGrip 一个顶所有。Wireshark 不常用，但真要排查网络问题的时候它是唯一靠谱的。</p>
<h2 id="效率和启动器">效率和启动器</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Raycast</td>
          <td>启动器，免费版够用，Alfred 的平替</td>
      </tr>
      <tr>
          <td>Easydict</td>
          <td>划词翻译，开源免费</td>
      </tr>
      <tr>
          <td>Karabiner-Elements</td>
          <td>改键，把 Caps Lock 改成 Ctrl+Esc</td>
      </tr>
      <tr>
          <td>MonitorControl</td>
          <td>外接显示器调亮度</td>
      </tr>
      <tr>
          <td>Mac Mouse Fix</td>
          <td>鼠标平滑滚动 + 窗口管理</td>
      </tr>
      <tr>
          <td>Hidden Bar</td>
          <td>折叠菜单栏图标</td>
      </tr>
      <tr>
          <td>Macs Fan Control</td>
          <td>风扇转速</td>
      </tr>
      <tr>
          <td>BrightIntosh</td>
          <td>老款 MacBook 突破官方限制最高亮度</td>
      </tr>
      <tr>
          <td>PicList</td>
          <td>图床，博客图片都走它</td>
      </tr>
  </tbody>
</table>
<p>Raycast 我每天用得最多的几个功能：启动应用、剪贴板历史、窗口管理、简单计算。它比 Alfred 好的地方是免费版就把核心功能全给了，不用纠结要不要买 Powerpack。</p>
<p>Easydict 这个之前我专门写过一篇 <a href="https://blog.xiaohuangyu.space/p/feature-send-to-anki-in-easydict/">给 Easydict 加 Anki 功能</a>，是真好用，划词就能查、能发音、能存生词。</p>
<h2 id="浏览器和插件">浏览器和插件</h2>
<p>主力 Google Chrome。日常用的插件：</p>
<table>
  <thead>
      <tr>
          <th>插件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>沉浸式翻译</td>
          <td>网页双语对照，看英文文档神器</td>
      </tr>
      <tr>
          <td>简阅</td>
          <td>阅读模式，把乱七八糟的网页变清爽</td>
      </tr>
      <tr>
          <td>Simple Allow Copy</td>
          <td>绕过禁止复制的网站</td>
      </tr>
      <tr>
          <td>Save All Resources</td>
          <td>扒网站资源用</td>
      </tr>
  </tbody>
</table>
<h2 id="其它日常">其它日常</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>IINA</td>
          <td>视频播放器，Mac 上最好的选择</td>
      </tr>
      <tr>
          <td>Keka</td>
          <td>解压缩</td>
      </tr>
      <tr>
          <td>OBS</td>
          <td>录屏、直播</td>
      </tr>
      <tr>
          <td>Apifox</td>
          <td>API 调试，Postman 的替代</td>
      </tr>
      <tr>
          <td>OrbStack</td>
          <td>上面提过</td>
      </tr>
      <tr>
          <td>XMind</td>
          <td>思维导图</td>
      </tr>
  </tbody>
</table>
<p>IINA 没什么好说的，装就完了。</p>
<p>旧的那篇 <a href="https://blog.xiaohuangyu.space/p/mac-dev-software-list/">Mac 开发常用软件清单</a> 留个时间戳，也没删。这篇是 2026 年的版本，估计过两年又得再更新一次。</p>
]]></content:encoded>
    </item>
    <item>
      <title>Easydict 发送到 Anki 插件开发</title>
      <link>https://blog.xiaohuangyu.space/p/feature-send-to-anki-in-easydict/</link>
      <pubDate>Tue, 24 Mar 2026 19:56:54 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/feature-send-to-anki-in-easydict/</guid>
      <description>&lt;p&gt;一直都想做一个插件，来实现anki英语单词的制卡。去年年中就已经起了项目，想做谷歌插件，网页划词之后，直接发送到anki，包括读音、图片一类，但今年重新回看的时候，却发现那个方案有一定局限性。主要源自于插件无法捕获全局的事件，即为当我在其他见面时无法进行划词。&#xA;正好看到我一直在用的Easydict，实际已经实现了Mac OS下的全局快捷键捕获。一拍脑袋就想着花一点时间扩展一下功能，初步想法，直接查词之后，能够将查到的单词发送到我本地的anik制卡。&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>一直都想做一个插件，来实现anki英语单词的制卡。去年年中就已经起了项目，想做谷歌插件，网页划词之后，直接发送到anki，包括读音、图片一类，但今年重新回看的时候，却发现那个方案有一定局限性。主要源自于插件无法捕获全局的事件，即为当我在其他见面时无法进行划词。
正好看到我一直在用的Easydict，实际已经实现了Mac OS下的全局快捷键捕获。一拍脑袋就想着花一点时间扩展一下功能，初步想法，直接查词之后，能够将查到的单词发送到我本地的anik制卡。</p>
<p>初步想法，需要实现以下功能</p>
<ol>
<li>查询句子或单词时，中译音或音译中能直接制卡，将语句作为卡面，对应译文作为卡底</li>
<li>要将录音文件的TTS也发送到anki，无需依赖其他API</li>
<li>查单词时，卡底最好能有音标</li>
</ol>
<p>于是经过跟Claude Code的多轮对话之后，基本实现功能，但语音层面仍需优化，后续考虑替换为大模型的 tts 服务
<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260324213105089.png" alt="image.png"  />
</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260324213023228.png" alt="image.png"  />
</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260324213124973.png" alt="image.png"  />
</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260324233935621.png" alt="image.png"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>OpenClaw 从零到一</title>
      <link>https://blog.xiaohuangyu.space/p/openclaw-from-zero-to-one/</link>
      <pubDate>Thu, 26 Feb 2026 23:26:51 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/openclaw-from-zero-to-one/</guid>
      <description>&lt;p&gt;记录下openclaw安装流程，以macOS为例&lt;/p&gt;&#xA;&lt;h3 id=&#34;安装node&#34;&gt;安装node&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;安装brew install node 可指定版本，但openclaw 要求大于22&lt;/li&gt;&#xA;&lt;li&gt;验证 node &amp;ndash;version 出现版本号，版本号大于20即可&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;安装git&#34;&gt;安装git&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install git&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git --version   &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;输出有值即可                            &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git version 2.39.5 (Apple Git-154)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;安装并配置openclaw&#34;&gt;安装并配置openclaw&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;安装openclaw&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;n&#34;&gt;luna&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ppmac&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fsSL&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;openclaw&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bash&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;err&#34;&gt;🦞&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Installer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;Because&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;texting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;yourself&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reminders&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;so&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2024.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Detected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;macos&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Install&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ne&#34;&gt;OS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;macos&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Install&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;npm&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Requested&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;latest&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Preparing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Homebrew&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;already&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;js&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v25&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;6.1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;found&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Active&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;js&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v25&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;6.1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;homebrew&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Active&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;npm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;11.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;homebrew&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;npm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Installing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Git&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;already&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Installing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v2026&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2.26&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;npm&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Finalizing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Refreshing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loaded&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gateway&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Gateway&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;metadata&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;refreshed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Gateway&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;restarted&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✗&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Probing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gateway&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;failed&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;—&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;details&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;unknown&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;--probe&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Did&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;you&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;one&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;no&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;probe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;profile&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;🦞&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenClaw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;installed&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;successfully&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2026.2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;26&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;I&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;m in. Let&amp;#39;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cause&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;some&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;responsible&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chaos&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Config&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;already&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;present&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;running&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doctor&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Running&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doctor&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;migrate&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;✓&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Doctor&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Config&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;already&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;present&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;skipping&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;onboarding&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;·&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Starting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;配置openclaw&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>记录下openclaw安装流程，以macOS为例</p>
<h3 id="安装node">安装node</h3>
<ol>
<li>安装brew install node 可指定版本，但openclaw 要求大于22</li>
<li>验证 node &ndash;version 出现版本号，版本号大于20即可</li>
</ol>
<h3 id="安装git">安装git</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">brew install git
</span></span><span class="line"><span class="cl">git --version   
</span></span><span class="line"><span class="cl">输出有值即可                            
</span></span><span class="line"><span class="cl">git version 2.39.5 (Apple Git-154)
</span></span></code></pre></div><h3 id="安装并配置openclaw">安装并配置openclaw</h3>
<ol>
<li>安装openclaw</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"> <span class="n">luna</span><span class="err">@</span><span class="n">ppmac</span> <span class="err"></span> <span class="o">~</span> <span class="err"></span> <span class="n">curl</span> <span class="o">-</span><span class="n">fsSL</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">openclaw</span><span class="o">.</span><span class="n">ai</span><span class="o">/</span><span class="n">install</span><span class="o">.</span><span class="n">sh</span> <span class="o">|</span> <span class="n">bash</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="err">🦞</span> <span class="n">OpenClaw</span> <span class="n">Installer</span>
</span></span><span class="line"><span class="cl">  <span class="n">Because</span> <span class="n">texting</span> <span class="n">yourself</span> <span class="n">reminders</span> <span class="n">is</span> <span class="n">so</span> <span class="mf">2024.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Detected</span><span class="p">:</span> <span class="n">macos</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Install</span> <span class="n">plan</span>
</span></span><span class="line"><span class="cl"><span class="ne">OS</span><span class="p">:</span> <span class="n">macos</span>
</span></span><span class="line"><span class="cl"><span class="n">Install</span> <span class="n">method</span><span class="p">:</span> <span class="n">npm</span>
</span></span><span class="line"><span class="cl"><span class="n">Requested</span> <span class="n">version</span><span class="p">:</span> <span class="n">latest</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="mi">1</span><span class="o">/</span><span class="mi">3</span><span class="p">]</span> <span class="n">Preparing</span> <span class="n">environment</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Homebrew</span> <span class="n">already</span> <span class="n">installed</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="ne">Node</span><span class="o">.</span><span class="n">js</span> <span class="n">v25</span><span class="o">.</span><span class="mf">6.1</span> <span class="n">found</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Active</span> <span class="ne">Node</span><span class="o">.</span><span class="n">js</span><span class="p">:</span> <span class="n">v25</span><span class="o">.</span><span class="mf">6.1</span> <span class="p">(</span><span class="o">/</span><span class="n">opt</span><span class="o">/</span><span class="n">homebrew</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">node</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Active</span> <span class="n">npm</span><span class="p">:</span> <span class="mf">11.9</span><span class="o">.</span><span class="mi">0</span> <span class="p">(</span><span class="o">/</span><span class="n">opt</span><span class="o">/</span><span class="n">homebrew</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">npm</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="mi">2</span><span class="o">/</span><span class="mi">3</span><span class="p">]</span> <span class="n">Installing</span> <span class="n">OpenClaw</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Git</span> <span class="n">already</span> <span class="n">installed</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Installing</span> <span class="n">OpenClaw</span> <span class="n">v2026</span><span class="o">.</span><span class="mf">2.26</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">OpenClaw</span> <span class="n">npm</span> <span class="n">package</span> <span class="n">installed</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">OpenClaw</span> <span class="n">installed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="mi">3</span><span class="o">/</span><span class="mi">3</span><span class="p">]</span> <span class="n">Finalizing</span> <span class="n">setup</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Refreshing</span> <span class="n">loaded</span> <span class="n">gateway</span> <span class="n">service</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Gateway</span> <span class="n">service</span> <span class="n">metadata</span> <span class="n">refreshed</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Gateway</span> <span class="n">service</span> <span class="n">restarted</span>
</span></span><span class="line"><span class="cl"><span class="err">✗</span> <span class="n">Probing</span> <span class="n">gateway</span> <span class="n">service</span> <span class="n">failed</span> <span class="err">—</span> <span class="n">re</span><span class="o">-</span><span class="n">run</span> <span class="n">with</span> <span class="o">--</span><span class="n">verbose</span> <span class="k">for</span> <span class="n">details</span>
</span></span><span class="line"><span class="cl"><span class="n">error</span><span class="p">:</span> <span class="n">unknown</span> <span class="n">option</span> <span class="s1">&#39;--probe&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">Did</span> <span class="n">you</span> <span class="n">mean</span> <span class="n">one</span> <span class="n">of</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">probe</span><span class="p">,</span> <span class="o">--</span><span class="n">profile</span><span class="err">?</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">🦞</span> <span class="n">OpenClaw</span> <span class="n">installed</span> <span class="n">successfully</span> <span class="p">(</span><span class="mf">2026.2</span><span class="o">.</span><span class="mi">26</span><span class="p">)</span><span class="o">!</span>
</span></span><span class="line"><span class="cl"><span class="n">I</span><span class="s1">&#39;m in. Let&#39;</span><span class="n">s</span> <span class="n">cause</span> <span class="n">some</span> <span class="n">responsible</span> <span class="n">chaos</span><span class="o">.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Config</span> <span class="n">already</span> <span class="n">present</span><span class="p">;</span> <span class="n">running</span> <span class="n">doctor</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Running</span> <span class="n">doctor</span> <span class="n">to</span> <span class="n">migrate</span> <span class="n">settings</span>
</span></span><span class="line"><span class="cl"><span class="err">✓</span> <span class="n">Doctor</span> <span class="n">complete</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Config</span> <span class="n">already</span> <span class="n">present</span><span class="p">;</span> <span class="n">skipping</span> <span class="n">onboarding</span>
</span></span><span class="line"><span class="cl"><span class="err">·</span> <span class="n">Starting</span> <span class="n">setup</span>
</span></span></code></pre></div><ol start="2">
<li>
<p>配置openclaw</p>
<ol>
<li>安装好后会自动开始这步<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260226233356873.png" alt="image.png"  />
选yes</li>
<li>先quickstart 后面可配置 <img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260227094239665.png" alt="image.png"  />
</li>
<li>模型选择自己想要的模型即可，我这里选用z.ai 使用智谱模型（需要先去生成apikey 并且填入，其他模型也是一样）<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260227094530465.png" alt="image.png"  />
</li>
<li>channel官方推荐telegram 这里自行选择，需要准备上网工具增加proxy配置后，粘贴bot的token ，机器上需要加配置 &ldquo;proxy&rdquo;:&ldquo;http://127.0.0.1:7890&rdquo;, 给机器人发消息 ，/start 之后会收到回复的code 然后在终端使用。openclaw pairing approve telegram QRNT5UUY(code)<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260227094753872.png" alt="image.png"  />

至此已经配置完，可以开始使用了openclaw</li>
</ol>
</li>
</ol>
<h3 id="给openclaw操控浏览器的能力">给openclaw操控浏览器的能力</h3>
<p>macOS</p>
<ol>
<li>安装extension，命令执行后会自动下载extension包到对应文件夹下 /Users/{你的用户名}/.openclaw/browser/chrome-extension</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">openclaw browser extension install
</span></span></code></pre></div><ol start="2">
<li>
<p>在chrome里地址栏输入 chrome://extensions/ 打开开发者模式 <img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260227100923737.png" alt="image.png"  />
</p>
</li>
<li>
<p>点击加载未打包的扩展程序，然后选中extension文件夹即可 <img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository@master/blog/20260227100909783.png" alt="image.png"  />
</p>
</li>
</ol>
<p>linux 可参照 <a href="https://cloud.tencent.com/developer/article/2626186">https://cloud.tencent.com/developer/article/2626186</a></p>
<h3 id="遇到的坑">遇到的坑</h3>
<ol>
<li>最初用nvm 安装node ，node全局安装后总时不时出现闪退问题，后面直接采用brew install node，官方脚本安装的openclaw</li>
<li>nvm安装后，卸载时，重新运行openclaw gatway install的plist .nvm路径，导致openclaw doctor始终有问题 原因是清理了.zshr后当前终端没有source 导致读取的环境变量是旧的，要么source ，要么重连一下ssh</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>VScode进入报错code 9, signal null error</title>
      <link>https://blog.xiaohuangyu.space/p/vscode-code-9-error/</link>
      <pubDate>Fri, 16 Aug 2024 10:07:54 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/vscode-code-9-error/</guid>
      <description>&lt;p&gt;进入 Vscode 时，出现报错&lt;br&gt;&#xA;Unable to resolve your shell environment: Unexpected exit code from spawned shell (code 9, signal null)&lt;/p&gt;&#xA;&lt;p&gt;![image.png](&lt;a href=&#34;https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408161008789.png&#34;&gt;https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408161008789.png&lt;/a&gt; =600x)&lt;/p&gt;&#xA;&lt;p&gt;查证go 和 go env  之后发现都没问题，最后注意到 ~/.bash_profile 中有这部分，确定造成报错的行是 &lt;strong&gt;export NODE_OPTIONS=&amp;ndash;openssl-legacy-provider&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#node&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/opt/homebrew/opt/node@20/bin:$PATH&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LDFLAGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-L/opt/homebrew/opt/node@20/lib:$LDFLAGS&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPPFLAGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-I/opt/homebrew/opt/node@20/include:$CPPFLAGS&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;openssl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;legacy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;provider&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用vi编辑或者是使用其他文本编辑器打开 .bash_profile 文件&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>进入 Vscode 时，出现报错<br>
Unable to resolve your shell environment: Unexpected exit code from spawned shell (code 9, signal null)</p>
<p>![image.png](<a href="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408161008789.png">https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408161008789.png</a> =600x)</p>
<p>查证go 和 go env  之后发现都没问题，最后注意到 ~/.bash_profile 中有这部分，确定造成报错的行是 <strong>export NODE_OPTIONS=&ndash;openssl-legacy-provider</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1">#node</span>
</span></span><span class="line"><span class="cl"><span class="k">export</span> <span class="n">PATH</span><span class="o">=</span><span class="s2">&#34;/opt/homebrew/opt/node@20/bin:$PATH&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">export</span> <span class="n">LDFLAGS</span><span class="o">=</span><span class="s2">&#34;-L/opt/homebrew/opt/node@20/lib:$LDFLAGS&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">export</span> <span class="n">CPPFLAGS</span><span class="o">=</span><span class="s2">&#34;-I/opt/homebrew/opt/node@20/include:$CPPFLAGS&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">export</span> <span class="n">NODE_OPTIONS</span><span class="o">=--</span><span class="n">openssl</span><span class="o">-</span><span class="n">legacy</span><span class="o">-</span><span class="n">provider</span>
</span></span></code></pre></div><p>使用vi编辑或者是使用其他文本编辑器打开 .bash_profile 文件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">vi</span> <span class="o">~/.</span><span class="n">bash_profile</span>
</span></span><span class="line"><span class="cl"><span class="err">按</span><span class="n">i进入编辑模式</span>
</span></span><span class="line"><span class="cl"><span class="err">找到</span><span class="k">export</span> <span class="n">NODE_OPTIONS</span><span class="o">=--</span><span class="n">openssl</span><span class="o">-</span><span class="n">legacy</span><span class="o">-</span><span class="n">provider</span> <span class="err">所在行</span>
</span></span><span class="line"><span class="cl"><span class="err">在</span> <span class="k">export</span> <span class="n">NODE_OPTIONS</span><span class="o">=--</span><span class="n">openssl</span><span class="o">-</span><span class="n">legacy</span><span class="o">-</span><span class="n">provider</span> <span class="err">前加</span><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="err">最后那行变成</span>
</span></span><span class="line"><span class="cl"><span class="c1">#export NODE_OPTIONS=--openssl-legacy-provider</span>
</span></span><span class="line"><span class="cl"><span class="err">再按</span> <span class="n">esc</span> <span class="err">退出编辑模式</span>
</span></span><span class="line"><span class="cl"><span class="p">:</span><span class="n">wq</span><span class="o">!</span> 
</span></span><span class="line"><span class="cl"><span class="err">然后回车</span>
</span></span></code></pre></div><p>如果不会使用 vi 可以直接终端执行</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">cd $HOME &amp; open .
</span></span></code></pre></div><p>然后用喜欢的文本编辑器打开.bash_profile 更改所在行</p>
<p><img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202409101100157.png" alt="image.png"  />
</p>
<p>将NODE_OPTIONS 注释掉后，重新进入 VScode 解决</p>
]]></content:encoded>
    </item>
    <item>
      <title>大善人 AI 食用指南</title>
      <link>https://blog.xiaohuangyu.space/p/cloudflare-worker-ai/</link>
      <pubDate>Mon, 12 Aug 2024 14:24:33 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/cloudflare-worker-ai/</guid>
      <description>&lt;p&gt;大善人 AI 食用指南&lt;/p&gt;&#xA;&lt;p&gt;登录之后，打开&#xA;&lt;a href=&#34;https://dash.cloudflare.com/&#34;&gt;https://dash.cloudflare.com/&lt;/a&gt; ,保存/之后的字符串为 accountId&lt;/p&gt;&#xA;&lt;p&gt;再打开&#xA;&lt;a href=&#34;https://dash.cloudflare.com/profile/api-tokens&#34;&gt;https://dash.cloudflare.com/profile/api-tokens&lt;/a&gt;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121425957.png&#34; alt=&#34;image.png&#34;  /&gt;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121427156.png&#34; alt=&#34;image.png&#34;  /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;这一步完成后会看到如下图，保存好自己的 Workers AI API token&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 用户 API 令牌&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;#### Workers AI API 令牌已成功创建&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;复制此令牌以访问 Cloudflare API。为安全起见，将不再显示此令牌。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后去 one-api 添加新渠道&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121433758.png&#34; alt=&#34;image.png&#34;  /&gt;&#xA;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>大善人 AI 食用指南</p>
<p>登录之后，打开
<a href="https://dash.cloudflare.com/">https://dash.cloudflare.com/</a> ,保存/之后的字符串为 accountId</p>
<p>再打开
<a href="https://dash.cloudflare.com/profile/api-tokens">https://dash.cloudflare.com/profile/api-tokens</a>
<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121425957.png" alt="image.png"  />

<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121427156.png" alt="image.png"  />
</p>
<p>这一步完成后会看到如下图，保存好自己的 Workers AI API token</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># 用户 API 令牌
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">#### Workers AI API 令牌已成功创建
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">复制此令牌以访问 Cloudflare API。为安全起见，将不再显示此令牌。
</span></span></code></pre></div><p>然后去 one-api 添加新渠道
<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121433758.png" alt="image.png"  />
</p>
<p>添加完成后即可进行测试，后续可以再 next-chatgpt中直接使用
<img loading="lazy" src="https://cdn.jsdelivr.net/gh/eatmoreduck/picture-repository/blog/202408121436437.png" alt="image.png"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Mac 开发常用软件清单</title>
      <link>https://blog.xiaohuangyu.space/p/mac-dev-software-list/</link>
      <pubDate>Sun, 07 Apr 2024 15:46:48 +0800</pubDate>
      <guid>https://blog.xiaohuangyu.space/p/mac-dev-software-list/</guid>
      <description>&lt;p&gt;换了几次电脑，每次都要重新装软件，干脆整理一下。以下是我在日常开发中真的在用的工具，不搞虚的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;开发工具&#34;&gt;开发工具&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;软件&lt;/th&gt;&#xA;          &lt;th&gt;说明&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;JetBrains 全家桶&lt;/td&gt;&#xA;          &lt;td&gt;GoLand 用得最多，其他看项目需要&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;VSCode&lt;/td&gt;&#xA;          &lt;td&gt;轻量编辑，前端开发主力&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Cursor&lt;/td&gt;&#xA;          &lt;td&gt;最近在用，AI 辅助写代码确实省脑子&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Another Redis Desktop Manager&lt;/td&gt;&#xA;          &lt;td&gt;Redis 客户端，免费够用&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Navicat Premium Lite&lt;/td&gt;&#xA;          &lt;td&gt;官方免费版，不需要破解了&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Sublime Text&lt;/td&gt;&#xA;          &lt;td&gt;快速打开文件看代码&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Docker&lt;/td&gt;&#xA;          &lt;td&gt;容器开发必备&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;DevToys&lt;/td&gt;&#xA;          &lt;td&gt;开发者小工具集合，JSON 格式化、Base64 转换啥的&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;EasyDevo&lt;/td&gt;&#xA;          &lt;td&gt;和 DevToys 类似，二选一就行&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;实用工具&#34;&gt;实用工具&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;软件&lt;/th&gt;&#xA;          &lt;th&gt;说明&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Android File Transfer&lt;/td&gt;&#xA;          &lt;td&gt;传文件到手机，官方工具&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Neat Download Manager&lt;/td&gt;&#xA;          &lt;td&gt;下载器，比浏览器自带的快&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Mounty&lt;/td&gt;&#xA;          &lt;td&gt;读写 NTFS 格式硬盘&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Keka&lt;/td&gt;&#xA;          &lt;td&gt;解压缩，支持格式多&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Easydict&lt;/td&gt;&#xA;          &lt;td&gt;划词翻译，开源免费&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;IINA&lt;/td&gt;&#xA;          &lt;td&gt;视频播放器，Mac 上最好的选择&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Karabiner-Elements&lt;/td&gt;&#xA;          &lt;td&gt;改键位，比如把 Caps Lock 映射成 Ctrl&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;MonitorControl&lt;/td&gt;&#xA;          &lt;td&gt;外接显示器调节亮度，这个很有用&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Hidden Bar&lt;/td&gt;&#xA;          &lt;td&gt;折叠菜单栏图标，强迫症福音&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Mac Mouse Fix&lt;/td&gt;&#xA;          &lt;td&gt;鼠标滚动变平滑，用罗技鼠标的推荐&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Loop&lt;/td&gt;&#xA;          &lt;td&gt;窗口快捷缩放，类似 Windows 的 Aero Snap&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Mos&lt;/td&gt;&#xA;          &lt;td&gt;鼠标平滑滚动，二选一&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;PicList&lt;/td&gt;&#xA;          &lt;td&gt;图床工具，支持 PicGo 配置&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;ShortcutDetective&lt;/td&gt;&#xA;          &lt;td&gt;查看快捷键冲突，偶尔用到&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Macs Fan Control&lt;/td&gt;&#xA;          &lt;td&gt;风扇转速调节，笔记本发热时用&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;strong&gt;个人推荐&lt;/strong&gt;：MonitorControl 和 Mac Mouse Fix/Mos 是真心推荐，用完就回不去了。&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>换了几次电脑，每次都要重新装软件，干脆整理一下。以下是我在日常开发中真的在用的工具，不搞虚的。</p>
<h2 id="开发工具">开发工具</h2>
<table>
  <thead>
      <tr>
          <th>软件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>JetBrains 全家桶</td>
          <td>GoLand 用得最多，其他看项目需要</td>
      </tr>
      <tr>
          <td>VSCode</td>
          <td>轻量编辑，前端开发主力</td>
      </tr>
      <tr>
          <td>Cursor</td>
          <td>最近在用，AI 辅助写代码确实省脑子</td>
      </tr>
      <tr>
          <td>Another Redis Desktop Manager</td>
          <td>Redis 客户端，免费够用</td>
      </tr>
      <tr>
          <td>Navicat Premium Lite</td>
          <td>官方免费版，不需要破解了</td>
      </tr>
      <tr>
          <td>Sublime Text</td>
          <td>快速打开文件看代码</td>
      </tr>
      <tr>
          <td>Docker</td>
          <td>容器开发必备</td>
      </tr>
      <tr>
          <td>DevToys</td>
          <td>开发者小工具集合，JSON 格式化、Base64 转换啥的</td>
      </tr>
      <tr>
          <td>EasyDevo</td>
          <td>和 DevToys 类似，二选一就行</td>
      </tr>
  </tbody>
</table>
<h2 id="实用工具">实用工具</h2>
<table>
  <thead>
      <tr>
          <th>软件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Android File Transfer</td>
          <td>传文件到手机，官方工具</td>
      </tr>
      <tr>
          <td>Neat Download Manager</td>
          <td>下载器，比浏览器自带的快</td>
      </tr>
      <tr>
          <td>Mounty</td>
          <td>读写 NTFS 格式硬盘</td>
      </tr>
      <tr>
          <td>Keka</td>
          <td>解压缩，支持格式多</td>
      </tr>
      <tr>
          <td>Easydict</td>
          <td>划词翻译，开源免费</td>
      </tr>
      <tr>
          <td>IINA</td>
          <td>视频播放器，Mac 上最好的选择</td>
      </tr>
      <tr>
          <td>Karabiner-Elements</td>
          <td>改键位，比如把 Caps Lock 映射成 Ctrl</td>
      </tr>
      <tr>
          <td>MonitorControl</td>
          <td>外接显示器调节亮度，这个很有用</td>
      </tr>
      <tr>
          <td>Hidden Bar</td>
          <td>折叠菜单栏图标，强迫症福音</td>
      </tr>
      <tr>
          <td>Mac Mouse Fix</td>
          <td>鼠标滚动变平滑，用罗技鼠标的推荐</td>
      </tr>
      <tr>
          <td>Loop</td>
          <td>窗口快捷缩放，类似 Windows 的 Aero Snap</td>
      </tr>
      <tr>
          <td>Mos</td>
          <td>鼠标平滑滚动，二选一</td>
      </tr>
      <tr>
          <td>PicList</td>
          <td>图床工具，支持 PicGo 配置</td>
      </tr>
      <tr>
          <td>ShortcutDetective</td>
          <td>查看快捷键冲突，偶尔用到</td>
      </tr>
      <tr>
          <td>Macs Fan Control</td>
          <td>风扇转速调节，笔记本发热时用</td>
      </tr>
  </tbody>
</table>
<p><strong>个人推荐</strong>：MonitorControl 和 Mac Mouse Fix/Mos 是真心推荐，用完就回不去了。</p>
<h2 id="效率工具">效率工具</h2>
<table>
  <thead>
      <tr>
          <th>软件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Alfred</td>
          <td>老牌启动器，Powerpack 需要付费</td>
      </tr>
      <tr>
          <td>滴答清单</td>
          <td>GTD 待办事项，多端同步</td>
      </tr>
      <tr>
          <td>RayCast</td>
          <td><strong>强烈推荐</strong>，免费版已经够用，Alfred 的平替</td>
      </tr>
  </tbody>
</table>
<p>RayCast 真的好用，我主要是用来：</p>
<ul>
<li>快速启动应用</li>
<li>查剪贴板历史</li>
<li>简单的计算和转换</li>
<li>搜索文件</li>
</ul>
<h2 id="终端工具">终端工具</h2>
<table>
  <thead>
      <tr>
          <th>软件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>iTerm2</td>
          <td>终端替代品，配色和分屏都很方便</td>
      </tr>
      <tr>
          <td>SecureCRT</td>
          <td>商用终端，付费</td>
      </tr>
      <tr>
          <td>lux</td>
          <td>B 站视频下载，偶尔用</td>
      </tr>
      <tr>
          <td>Termius</td>
          <td>SSH 客户端，多设备同步</td>
      </tr>
      <tr>
          <td>htop</td>
          <td>top 的升级版，更好看</td>
      </tr>
  </tbody>
</table>
<h2 id="网络工具">网络工具</h2>
<table>
  <thead>
      <tr>
          <th>软件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Lulu</td>
          <td>开源防火墙，监控应用网络连接</td>
      </tr>
  </tbody>
</table>
<h2 id="chrome-插件">Chrome 插件</h2>
<table>
  <thead>
      <tr>
          <th>插件</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Proxy SwitchyOmega</td>
          <td>代理切换，老牌了</td>
      </tr>
      <tr>
          <td>ZeroOmega</td>
          <td>SwitchyOmega 的轻量版</td>
      </tr>
      <tr>
          <td>Adblock Plus</td>
          <td>广告拦截</td>
      </tr>
      <tr>
          <td>简阅</td>
          <td>阅读模式，网页变清爽</td>
      </tr>
      <tr>
          <td>Simple Allow Copy</td>
          <td>复制禁止复制的网站内容</td>
      </tr>
      <tr>
          <td>XSwitch</td>
          <td>代理管理</td>
      </tr>
      <tr>
          <td>Axure RP</td>
          <td>原型预览</td>
      </tr>
      <tr>
          <td>沉浸式翻译</td>
          <td>页面双语对照翻译</td>
      </tr>
      <tr>
          <td>Save All Resources</td>
          <td>下载网站资源，扒网站用</td>
      </tr>
  </tbody>
</table>
<h2 id="补充说明">补充说明</h2>
<p>上面的工具不是都要装，按需选择就行。如果你也在整理自己的工具清单，推荐看看 <a href="https://wangchujiang.com/awesome-mac/README-zh.html">awesome-mac</a>，那里更全。</p>
<hr>
<p><strong>最后更新</strong>：2024-04-07</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
