2026-06-04 18:43:00
![]()
一次性的小坑记录,面向人阅读。结论先放这:APlayer 歌词某些行不显示,十有八九是时间戳格式不对,不是歌词内容缺了。
给博客的 APlayer 播放器挂歌词(.lrc)后,有些歌一切正常,有些歌却有几行死活不显示 / 不滚动——可歌词文件里那几行明明在。控制台也不报错,就是静悄悄地少了几句。
APlayer 的 LRC 解析器对时间戳挑食:它只稳定接受 [mm:ss.xx] 或 [mm:ss.xxx](两位或三位毫秒)这种"规整"写法。遇到下面这些松散写法,它会直接跳过整行:
[02:54.4] —— 只有一位小数[2:54.40] —— 分钟只有一位[02:54] 之外各种位数不齐的组合而很多歌词来源(网易云导出、第三方站点、手抄)恰恰就是这种松散格式。于是同一份歌单里,规整的歌好好的,松散的歌就缺行——表现得很"随机",其实规律就是时间戳。
思路很简单:把每个时间戳重算成总秒数,再补零、把毫秒补齐到两/三位。核心就一段正则替换:
|
|
[02:54.4] → [02:54.400],[2:5] → [02:05],APlayer 就都认了。
这一步已经接进 lihan3238/music 仓库的 CI——lrc_compat.py 里的 normalize_lrc_file 被 test.py 调用,music-sync.yml 在 lrc/** 变更时自动跑,发布前自动规范化。所以现在往歌单里丢任意来源的 .lrc,流水线会自己把时间戳修好,前端再也不会缺行。
APlayer 歌词不显示,先查时间戳是不是
[mm:ss.xx]/[mm:ss.xxx],别先怀疑歌词内容或播放器本身。
2026-06-03 00:00:00
![]()
本文是一次真实迁移的完整走查记录(一次性、面向人阅读)。可被 AI 直接调用、 带可复用 verify 的精简版,见知识卡片
hugo-stack-v4-migration-map(/ai/cards/hugo-stack-v4-migration-map.md)。
把本博客从 Stack v3 升级到 v4。验证于 2026-06-03 UTC(北京时间 2026-06-04), 环境为 WSL。适用场景:升级本博客或其他基于 Stack 主题的 Hugo 站点到 v4,尤其 当出现 CI 卡住、自定义 partial 消失、link-card 页面在构建期抓取远程图片、或旧 frontmatter 不再影响页面可见性时。
>=0.157.0;本博客 CI 使用
0.162.1。github.com/CaiJimmy/hugo-theme-stack/v4,并在 go.mod
中 require github.com/CaiJimmy/hugo-theme-stack/v4 v4.x。layouts/_partials/**,而非
layouts/partials/**。把自定义 partial 移到那里。zh,不是 zh-cn;使用 locale = "zh" 与
defaultContentLanguage = "zh"。favicon = "favicon.ico" 并把文件放到 assets/ 下;
仅为了向后兼容旧 URL 才保留 static/favicon.ico。[sidebar] avatar = "img/avatar.jpg",而非 v3 的
[sidebar.avatar] enabled/local/src 对象。imageProcessing.cover 改名为
imageProcessing.thumbnail;内容图片处理仍保留 [imageProcessing.content]。hidden frontmatter 行为。对必须不出现在
列表中的页面,改用 Hugo 构建选项,例如 build.list = "never"。params.icon;不要再依赖 .Pre。[defaultImage.opengraph]。SortBy = "lastmod"。为了 CI 行为稳定,配合
enableGitInfo = true、完整的 checkout 历史,以及
[frontmatter].lastmod = ["lastmod", "modified", ":git", "date", "publishDate"]。article/components/links.html,直接渲染 <img src="...">,
让浏览器加载 favicon,CI 不依赖远程站点。[article.alertIcon] 原生支持;普通 note/tip/warning
块不再需要自定义 admonition shortcode。[article.mermaid] 原生支持;图表不再需要自定义 Mermaid
shortcode 或页面级加载器。SortBy = "lastmod" 可替换本地的列表 hack。go.mod、go.sum、语言键、favicon、头像、图片处理,
以及被移除的配置块。layouts/partials/** 移到 layouts/_partials/**;
同步更新任何 workflow 路径(例如 music sync)。hidden: true、imageProcessing.cover、
layouts/partials/、.Pre,以及被误写成 Markdown 图片的普通链接。
|
|
期望:Hugo >=0.157 无警告构建;workflow 通过 lint;diff 无空白错误;合并前
PR 的 Pages 构建通过。若失败,检查模块路径、partial 覆盖位置、
avatar/favicon/imageProcessing 键、隐藏 frontmatter,以及构建期远程资源抓取。
2026-06-02 20:00:00
![]()
用一台有公网入口的 Rocky Linux VPS 做 WireGuard Hub,把宿舍 OpenWrt、工位 Linux、工位 Windows 等设备接入同一个私有网段,并通过宿舍 OpenWrt 远程唤醒宿舍 Windows PC。
本文不是 WireGuard 原理课,而是一份部署和维护手册。以后忘了命令、要新增 peer、要排查握手和路由问题时,优先按本文检查。
当前策略:
192.168.1.0/24。/32 地址。386.14_2 上强行部署 WireGuard 主链路。注意:本文是公开博客版本,所有私钥、公钥、MAC 地址、VPS 公网 IP 都用占位符表示。真实值只应保存在对应设备本机配置中,不要放进 GitHub、截图或聊天记录。
|
|
推荐访问方式:
|
|
当前网段:
|
|
后续如果有条件统一调整 LAN,建议改成不容易冲突的编号:
|
|
但当前阶段不强行修改 LAN。远程组网最怕“边调边失联”,先把 WireGuard 跑稳,再做地址治理。
本方案采用:
|
|
理由:
WireGuard 的 AllowedIPs 同时承担两件事:
|
|
因此它既像访问控制列表,又像路由表。配置错误时,经常表现为“有 handshake,但 ping 不通”。
规则:
10.77.0.2/32 和 192.168.1.0/24。10.77.0.x/32。192.168.50.0/24,除非它真的是工位网关。AllowedIPs 写“远端目标”,不要把自己的本地 LAN 写进去。错误示例:
|
|
这里两个 peer 同时宣告 192.168.1.0/24,会造成路由冲突。
正确示例:
|
|
|
|
正常应看到:
|
|
|
|
查看公钥:
|
|
注意:
|
|
/etc/wireguard/wg0.conf
|
|
推荐模板:
|
|
建议固定:
|
|
原因是配置文件才是真源。否则运行时的临时变更可能被 wg-quick 写回文件,长期维护时容易混乱。
|
|
期望:
|
|
放行 WireGuard 端口:
|
|
建议把 wg0 放入 trusted zone,减少 VPN 内部转发被 firewalld 拦截的概率:
|
|
如果 VPS 还有云厂商安全组,也要放行:
|
|
启动:
|
|
重启:
|
|
停止:
|
|
查看状态:
|
|
查看关键路由:
|
|
正常状态应至少包含:
|
|
如果旧 OpenVPN 仍在,可能还会看到:
|
|
宿舍 OpenWrt 当前 LAN:
|
|
后续 WOL 必须从 br-lan 发,不要从 wg0 或 pppoe-wan 发。
|
|
|
|
将输出的 DORM_OPENWRT_PUBLIC_KEY 填到 VPS 的 dorm-openwrt peer 中。
先设置变量:
|
|
配置接口和 peer:
|
|
关键点:
|
|
查看:
|
|
只保留 WireGuard 网段:
|
|
如果将来某远端子网也通过 VPS 可达,再按需添加,例如:
|
|
当前不建议把工位 192.168.50.0/24 交给 WireGuard,除非工位网关也接入 WireGuard。
创建 vpn zone,并允许 lan <-> vpn:
|
|
检查:
|
|
在 OpenWrt 上:
|
|
从 VPS 测:
|
|
如果 10.77.0.2 通,但 192.168.1.1 不通,优先查:
|
|
Ubuntu / Debian:
|
|
Rocky / RHEL / Fedora:
|
|
|
|
查看公钥:
|
|
把输出的 OFFICE_LINUX_PUBLIC_KEY 加到 VPS。
/etc/wireguard/wg0.conf
|
|
配置:
|
|
说明:
10.77.0.0/24 用于访问 WireGuard 内所有 peer。192.168.1.0/24 用于访问宿舍 LAN。192.168.1.0/24。Endpoint 写成 VPS 当前内网可达 IP;长期使用应改成 VPS 公网 IP 或稳定域名。权限:
|
|
启动:
|
|
重启:
|
|
检查:
|
|
测试:
|
|
安装 Windows 官方 WireGuard 客户端后:
|
|
客户端会自动生成 PrivateKey 和 PublicKey。
Windows 配置模板:
|
|
VPS 上添加:
|
|
应用 VPS 配置:
|
|
PowerShell:
|
|
注意:
|
|
TUN 模式代理可能截获 WireGuard 外层 UDP 流量:
|
|
如果这条流量被代理接管,常见现象:
|
|
必须 DIRECT:
|
|
Clash 规则示例:
|
|
建议 WireGuard Endpoint 用 IP,不用域名:
|
|
这样可以避免 DNS 查询被 TUN 代理影响。若必须用域名,则 DNS 也要确认不被代理规则错误接管。
推荐链路:
|
|
不要优先尝试远端直接向 192.168.1.255 广播。WireGuard 是三层隧道,广播不一定穿透。最稳的是让 OpenWrt 在宿舍 LAN 本地发 WOL。
BIOS / UEFI:
|
|
MSI 主板进 BIOS:
|
|
Windows 网卡设置:
|
|
如果要从关机状态唤醒,建议关闭 Fast Startup:
|
|
如果只从睡眠唤醒,可以先不关 Fast Startup,先把最小链路测通。
|
|
只用命令行:
|
|
Windows:
|
|
找有线网卡:
|
|
OpenWrt 上也可以查:
|
|
MAC 格式统一写成:
|
|
OpenWrt 上执行:
|
|
宿舍 LAN 接口是:
|
|
不要从 wg0 或 pppoe-wan 发 WOL。
如果使用 LuCI:
|
|
建议开启 Send to broadcast address。
理由:
|
|
不要做:
|
|
|
|
远程唤醒:
|
|
宿舍内网唤醒:
|
|
先测试睡眠唤醒:
|
|
再测试关机唤醒。
如果睡眠能醒、关机不能醒,优先检查:
|
|
如果完全不能醒,优先检查:
|
|
|
|
重点看:
|
|
典型问题:
|
|
|
|
日志:
|
|
应用配置:
|
|
|
|
重载网络:
|
|
重启防火墙:
|
|
|
|
重启:
|
|
从工位 Linux 测:
|
|
从 VPS 测:
|
|
从宿舍 OpenWrt 测:
|
|
判断顺序:
|
|
不要一开始就测 RDP、SSH 或 WOL。先把三层连通性验证完。
建议:
|
|
Linux:
|
|
Windows / macOS / 手机:
|
|
|
|
重启 VPS:
|
|
单设备客户端模板:
|
|
如果只想访问 WireGuard peer,不访问宿舍 LAN:
|
|
如果想全局代理,才写:
|
|
当前不建议默认全局代理。这个方案的目标是远程组网和运维,不是替代所有代理流量。
|
|
VPS 只需要暴露:
|
|
不要为了 WOL 暴露:
|
|
WOL 只从 OpenWrt 的 br-lan 本地发。公网只允许进入 WireGuard。
宿舍 192.168.1.0/24 下的普通设备不需要安装 WireGuard,也可以访问 10.77.0.0/24,前提是:
|
|
如果普通设备自己也安装 WireGuard,可以,但它只能宣告自己的 /32,不能宣告整个 LAN。
工位 Linux/Windows 如果只是单设备 peer,就只写:
|
|
不要写:
|
|
除非这台设备真的是工位 LAN 的默认网关,并且已经配置好 IP 转发、防火墙和回程路由。
应保持:
|
|
不要做:
|
|
VPS:
|
|
OpenWrt:
|
|
Linux peer:
|
|
WOL:
|
|
如果只记一个排障原则:
|
|
2026-05-29 06:45:00
![]()
敲下了标题,已是凌晨 6:47,一夜未眠,先去吃个早饭。
忘了拍照,雪菜粉丝包和豆腐脑还是比北京的好吃多了,倒是鸡蛋灌饼没冬天热乎好吃了,应该是换了厨子。
经典睡不着红温,索性下床学习通宵算了。好吧,倒也没有那么经典,上次还是大三吧,不过这次不能下床就趴在桌前敲笔记本,得跑去工位了。
其实说实话有点傻逼真的,自以为摆脱思想桎梏的人现在天天晚上为世俗的前途焦虑地睡不着觉,最喜欢玩的人迷上了 Vibe Coding 后一个月没打开过游戏。归根结底,还是被困在了这个毫无希望的学校里。
回归正题,敲完这篇就回去睡觉了。
对大模型的接触自然要追溯到 2022 年末的 ChatGPT 了,它从 11 月 30 日发布到突破 100 万用户只用了短短五天。我的第一个账号也是在当时注册的,一篇知乎让我花了一个半小时从接码到注册用上了大模型。


用上 GPT 后的第一个“工程实践”就震惊了我,它不仅能够根据 Java 老师的作业要求给出能跑的代码,甚至还会授人以渔和代码纠错,这对当时只会机械执行一行行代码的机器人般的我来说简直是个奇迹!

说实话,后面的一年里,GPT 和其他大模型于我只有一个作用:水掉作业。于是在疫情宅家的日子里,我不是在打游戏就是在打游戏,与此同时 DaleChu 同学似乎在那段时间深耕了键政和计算机技术。
时间一晃来到了 2023 年的九月开学,在 lihan 开始模仿 DaleChu 的博客时,对大模型的使用也慢吞吞地进入了下一个阶段——代码补全。申请了 GitHub Copilot 的学生会员后,代码补全 + ChatGPT 的组合一方面让刚准备开始发奋学习技术的我得以更快上手,另一方面也让我第一次意识到似乎手搓代码就跟提笔写字一样要被淘汰了。

自此之后,一直到研一,我对大模型的使用与研究便停滞于此了,从 GPT-4 到 GPT-5,对我而言不过是一次次版本号的迭代,以及模型能力的日常提升。除了越来越多人开始使用大模型,越来越多的垂类产品也开始涌现之外,并没有什么特别的感觉。当然,这也源于我对当时那些所谓的“Prompt 工程”的不屑一顾了。如今再看,真的很难想象自己居然纯靠网页 ChatGPT 完成我的 DSSE 毕业设计。
AI 的热情再度被点燃是在研一的十月份了,在 lyx 的教导下,我开始试着接触科研和实验。第一次看到他用 Copilot Vibe Coding 写代码时我简直像极了面对流水线鲜花饼产线的老手艺人——还能这样?
现在说什么都来不及了,Vibe Coding 沾上了就戒不掉了,纵使一开始对失去项目与代码掌控权的疑虑到现在还没完全打消,我已然是无法回到最开始的手搓代码了。
lemoncchi 说,大模型害惨了我们这些没跟上这趟科研快车的程序员。诚然,倘若没有大模型的出现,我们仍然能够凭借编程的技术,在刷 LeetCode、背面经后,一路实习、面试,最终找到一份凭借着剩余价值转移得以维持高薪的码农工作。但现在,可见的未来,简历上的“熟悉 C++”几乎和“熟悉 WPS”要画上等号了,更可恶的是,精心(也许精心吧嘿嘿)维护的博客里的技术贴已经完全失去意义了,也再不会有无知美少女抱着电脑一脸崇拜地请教你某个小技术问题了(说实话感觉主要是 DaleChu 和 lemoncchi 在经历这个,我只能给壮汉讲呜呜呜)。
但倘若不从功利的角度出发,大模型的出现几乎是一个让人美梦成真的奇迹!今年初开始让老程序员们重燃青春的 OpenClaw 和 Hermes,让无数像家父和我导师这样的老程序员们上头了几个月还没退烧,纵使一个月几千的 Token 账单贴在脸前,一个真的能把你的想法实现的魔法机器摆在面前,谁能不心动呢?是啊,记得小时候,看着网上所谓“脚本小子”为游戏制作外挂,听起来好像得学好多年才能到这个地步,现如今十几分钟就能让大模型给我用 YOLOv8 跑起来挂机脚本了;困扰了我两年的博客音乐列表全自动更新功能,也不过是一杯咖啡的功夫就能给我完美实现了。大模型的出现对于不考虑以此谋生的程序员来说,真的是原神了。
导师其实早就紧跟时代了,给我们发模型让我们用 ClaudeCode 做横向项目了,从他的 GitLab 记录来看,过年期间他也上了 OpenClaw 这趟车,直到今天还在兴致满满地安排着他的 Agents 用 Vibe Coding 做各种项目。相比之下,我这个老古董学生倒是在 Copilot 报废后,才勉强开始把他发的 GLM 接入 ClaudeCode 使用。
用 ClaudeCode 的第一天就把卡了我几周的 Bug 轻松秒掉了。
今年三月左右开始,让我白嫖了多年的 Copilot 开始抠搜了,先是旗舰模型被移入更高价位的套餐,然后是使用次数被一次又一次限制,月限、周限、五小时限,一直不想“自费打工”的我总算在四月尾巴坚持不住,开始转向 Codex 和 ClaudeCode 了。
2026 年 4 月 27 日,面对额度耗尽的 GLM,lihan 打开了当年偷瞄 DaleChu 屏幕看到的那个神奇论坛——LinuxDO,在通宵达旦地高强度刷了一天帖子后,终于跟上了这波“中转站 - Vibe Coding - AI Workflow”浪潮。在几个中转站里摸爬滚打了一两天后,从“福利羊毛”区的大善人们的投喂和“跳蚤市场”区的低价 GPT Team 车开始,走上了一趟狂热的 Vibe Coding 之旅。

在牺牲了原本备考数学期末的时间、用 Vibe Coding 给开源项目提交 PR 后,我很快意识到不能把精力砸在抠搜上——强大先进的生产力应当不计代价地立刻投入使用!于是在考完后的当天,我就开始通宵搭建我这个基于 New API + CliProxyAPI 的中转站 lihan API 了。
一扫以往买域名、买服务器、买节点的犹豫,花了五天时间,我便部署好中转站投入使用了。从一开始三天报销掉三个 GPT Plus 的周限,到现在后台额度波澜不惊,即便小小地给周围同学朋友推广使用、企图回血,也很少再出现额度不足的情况了,我这才开始缓慢地真正掌握 Coder Agent 这把尚方宝剑。

在 Vibe Coding 中的摸爬滚打难以言喻,总结下来,不过是以下几点:
希望年末我能笑着去香港喜提 MacBook Pro M6 Pro 和 iPhone 18 Pro Max!
2026-05-21 00:00:00
![]()
本文是一次真实配置的完整走查记录(一次性、面向人阅读)。这套环境配好一次就长期 复用,我大概率不会再从头踩坑,所以收成博文而不是知识卡片。
想用 Codex 的 remote-connect 功能从 Mac 驱动一台 Windows 机器。连上之后,Codex
在远端跑 bootstrap 一上来就失败:报 pwsh 看不懂的 token、&&、$(...) 之类的
错误,或者客户端报远端 shell 没返回预期的握手。
根因是 shell 不匹配:
适用场景:用 Mac 通过 Codex remote-connect(或其他假定 sh 的远程开发工具,比如 JetBrains Gateway、bootstrap 脚本只认 sh 的 VS Code Remote-SSH)去驱动一台装了 WSL 的 Windows 机器,且连接在 bootstrap 阶段挂在 shell 不兼容 / pwsh / command-not-found 上。
不适用:远端本身就是原生 Linux(没有 shell 不匹配)、远程工具明确支持 Windows 侧 pwsh、或者那台 Windows 上压根没装 WSL 发行版。
第 1–3 步每台 Windows 主机一次性;第 4 步每台 Mac 一次性。
在 Windows 上打开 WSL Ubuntu:
|
|
确认:
|
|
在 Mac 上:
|
|
复制整行。进到 WSL 里:
|
|
在 Windows 上以管理员 PowerShell 执行:
|
|
编辑 Mac 上的 ~/.ssh/config:
|
|
然后在 Codex 里把 remote-connect 指向 Host 别名 lihan_pc_02_wsl——Codex 看到
的是一个 POSIX 远端,bootstrap 就能干净跑通。
$wslIp 当成一个快照写死了。一旦
wsl --shutdown 或 Windows 重启,要重跑 netsh interface portproxy add
(先用 netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=2222 删掉旧的)。可以把它写成一个开机自动跑的计划任务。10.88.0.6:10808)跟这条 SSH 路径无关,别混在一起。在 Mac 上:
|
|
返回一个 Linux 内核串(形如 Linux ... microsoft-standard-WSL2)且退出码为
0,就说明这台 Host 上的 Codex remote-connect 能用了。
连不上时按顺序排查:
sudo service ssh status;netsh interface portproxy show v4tov4 与 wsl hostname -I
(每次 WSL 重启 IP 都会漂);WSL SSH 2222 是否存在;~/.ssh/authorized_keys 里有没有 Mac 公钥,且权限是 600。2026-05-13 20:50:00
![]()
这个博客现在进入 V4:AI 时代人机协作工作流博客。
听上去有点大。核心很朴素:过去这里是赛博日记、技术学习笔记、灵感收纳盒;现在 AI 已经能帮我查资料、写代码、跑命令、改项目,旧式"把技术步骤写成长教程以备下次翻"的价值断崖式下降——我自己都不再回去翻那些教程,模型一句话就把活干了。
所以 V4 起,博客分两条线:
不是把"小窝"装修成企业文档站。更像是在小窝里加了一个工具间,里面放着扳手、标签、清单和一点点家规——给我自己和与我合作的模型。
旧博文全保留,不迁移、不重写、不批量整理 frontmatter。
旧文章里有前 AI 时代的学习痕迹,有当时看起来笨但很真实的记录。它们不是脏数据,不需要被 AI 打扫得光滑如新。
以后写生活、旅行、随想、计划,仍然是传统博客文章。AI 帮我润色、排版、检查链接 OK,但文章本身是给人读的。
说实话,V4 刚开局时我画的图比现在大得多。
我最初想了一堆东西:4 种资产格式(tip / playbook / skill / session),一套 GitHub dispatch 自动管道,几类 hook 在敏感时刻插手,甚至给本地 MCP server 留好了位置——准备把博客做成一个能查能写能复盘的"小型知识库平台”。
V4 上线 5 天,一边用一边改。这一周下来,最初设想里一大半工程没保留下来:
type 字段。curl + jq 还够用。砍到最后,剩下一个 静态 JSON 索引(registry) + 一种 markdown 格式(card) + 一个跨工具的薄 skill。
这种"塌缩"不是失败。是发现 大多数工程感强的设计其实在替我加包袱,而真正起作用的是那条很短的链路:
|
|
整套工程在原仓库里有一份对应的"宪法"和几条硬底线在背书——不允许 always-on infrastructure,不允许 agent sprawl(一项功能两套实现并存),不允许批量加载,等等。每次我想"再加一个守护进程"或"再加一种资产格式",那几条底线把我拍回去。结果就是越用越简单。
卡片现在就是一个 markdown 文件,写在 ai/cards/<id>.md,frontmatter + 紧凑正文。
frontmatter 里固定写:id、type、summary、status(valid/stale/retired)、context_cost、last_verified,最关键一项是 verify 块——三段:执行什么 / 期望看到什么 / 看不到怎么办。这一段直接决定一张卡的可复用性。
正文必填三段:
|
|
整张卡片故意写得"对人不友好"——bullet、表格、key-value,没有起承转合。它的读者是模型,不是访客。完整模板与契约见 /ai/ 页面。
模型查经验只有一个入口:
|
|
不需要 clone 仓库,不需要装 SDK,不需要登录。一个静态 JSON 暴露在公网上,谁来都能查。
URL 就是协议。如果某天有更好的模型,它能用;如果某天我换了主力工具,它也能用。这种"少依赖"是这个层目标活久一点的唯一办法。
回过头看,V4 砍掉那些花活之后,剩下的东西不太像"我自创的工作流"——更像是 AI 工具圈这两年慢慢涌现的标配:
我把这些写下来不是因为它们是我发明的。是因为我经过砍掉自己一堆"工程感很强的设计"之后,终于看清这条主流路径的轮廓。接下来这一年大概会越来越像这样。
content/post/** 里的历史文章不要被批量迁移、重写、整理。只有当我明确点名某篇要改时,AI 才动。这几条会写进项目指令和质量门里,防止"改完功能丢一句’完成了’就跑路"。
我觉得这一版最大的变化,不是多了几个目录、多了几个自动化脚本。
真正的变化是:博客不再只是"我写给未来的我看",而是变成"我和未来的 AI 一起工作的接口"。
过去把知识写下来是怕忘。现在把流程固化下来是为了让人和 AI 都能更稳一点地进化。
而且——这套接口已经把我自己以前画的复杂版砍掉了大半。如果半年后我回头再看,可能还会再砍一些。没关系,越简单越像主路。
当然,小窝还是小窝。技术层长出了一套机器骨架,门口仍然可以放歌、写随想、贴旅行照片、偶尔吐槽人生。这样就挺好。
V4 上线一个月,又砍了一轮、也长了一轮。上面正文保持原样,这里记录变化。
当初说"真东西在卡片里"。用了一个月发现不完全对:真东西在工作流里,卡片只是它的公开切片。所以这次重构把日常运行时彻底搬回本地——
repo-modes.yaml),AI 不再每次会话重新猜。博客仓库永远是工程模式,研究仓库永远是科研模式,说一次就够。lihan-cards 的 references,按任务只加载一片。“一个入口"的家规扛住了第一次真正的膨胀压力。go),之后 CI 全绿 + 改动严格限制在卡片 allowlist 内,PR 自动合并。点头从"每一步"变成"每一件事一次”,底线(非卡片变更必须人合)没动。回头看正文里那句"如果半年后我回头再看,可能还会再砍一些”——只用了一个月。砍掉的是"每次都重新解释我是谁、在哪个仓库、干哪类活"的摩擦;留下来的还是那条短链路,只是链路的起点从公网 URL 挪到了本地 skill,公网那份变成了展示窗和异地备份。
越用越像一个运行时,越不像一个文档站。 大概这就是对的方向。