两个月,一群 AI,和一个从零手搓的 App Store

阅读量
👀2
次浏览
发布时间
📅今天
2026-09-06
分类
💻技术
栏目
发布者
✍️iWSheng
作者

两个月,一群 AI,和一个从零手搓的 App Store

你现在看到的这个博客——顶上那块会随天气变化的呼吸感封面、点一下就像 App Store 里应用卡片那样丝滑展开的文章、底部那条悬浮着的液态玻璃导航坞——它没有用任何现成的主题,没有引一行前端框架,没有热链一张图片。

它是从一片空白的文件夹开始,用两个月时间,一个版本一个版本,亲手搓出来的。

到今天,它走到了 3.69

我想认认真真地,把它介绍给你。


一、缘起:我为什么要自己造一个

在此之前,这个站(iws.tw)跑的是 Hugo,用的是我自己写的开源主题 LoveClaude 一个 Claude/Anthropic 气质的静态博客皮肤。它挺好,但静态博客有静态博客的天花板:我想要评论、想要访客分析、想要绝对的安全、想要一个能在后台点点点就配好一切的控制台、想要访问控制和邀请制、想要一个能真正"活"起来的站。

更重要的是,我心里有一个很具体的画面:我想要一个像 iOS 26 App Store 那样的博客。

不是"看起来像",是骨子里像。App Store 的 Today 页、Arcade 页那种大图叙事;和那种会讲故事的卡片;应用图标那种圆角矩形(squircle)的精致;iOS 26 那层"液态玻璃"的通透质感。文章不该是一行行灰扑扑的链接,它该是一张会呼吸的卡片,你点它,它像应用启动那样从封面处展开成全屏。

带着这个画面,我做了一个当时看起来有点疯的决定:换到 Typecho,然后从零开始,自己造这套主题。

而"自己",从第一天起,就意味着"我和 AI 一起"。


二、我们是怎么干活的

先说清楚这套协作方式,因为它本身就是这个项目最有意思的部分之一。

我是这个项目的作者和导演。我脑子里有画面、有审美、有那条不能退的底线。

我旁边坐着一位总指挥兼设计师——那是 chat 端的 Claude(Opus 4.8)。它不直接写项目代码。它干的活是:把我脑子里模糊的画面,翻译成一份份"保姆级"的施工规格——每一节都先讲清楚为什么这么做,再给出可以照抄的代码、坐标、参数,而且每一步都能单独验证。它还负责去 GitHub 上把真实的开源实现拆开研究,而不是丢一句"学 Apple"就让人自己悟。它是那个把"我想要的感觉"变成"能落地的工程"的人。

真正在编辑器里敲代码的,是执行端。这个位置换过三次人:

  • Claude Sonnet 5,陪我们走完了最艰难的从 0 到 1(P3.6 到 P3.38),把视觉体系、动画引擎、安全插件的地基全部夯了下来。
  • Kimi K3 接手了中段最庞大的一批(P3.39 到 P3.68),平台级的更新系统、访客大屏的产品级重构、四套封面系统,几乎都在它手里成型。
  • Grok 4.6 是现在的执行端(P3.69 起),接手了最近的字色自适应和收尾打磨。

一份规格,一次实现,一次真机验收。做完一份 build log,截一张图给我看。这个循环,我们重复了两个月,六十九个大版本。

有几条红线,从第一天贯穿到最后一天,一次都没破过:

  • 可移植:所有代码只能写在主题目录和三个配套插件里,只能靠官方钩子,绝不允许改动 Typecho 的核心文件。验收标准很粗暴——把这几个文件夹拷到一个全新的、干净的 Typecho 上,装好,它必须立刻完整工作。这一条,我们兑现了四十多轮。它让这个东西从"一个 Docker 项目"变成了"一个能装、能用、能升级的产品"。
  • 纯原生:CSS、JS、PHP,不引任何前端框架,不上任何构建工具,不依赖任何在线 CDN。所有素材本地化,绝不热链。
  • 实测 > 直觉:任何关于因果、性能、安全的判断,先测再下结论。没复现的问题就说没复现,绝不假装修好了。
  • 能加开关就加开关

这几条听起来像枷锁,但正是它们,让这个主题干净、独立、可以坦然地拿去开源。


三、这两年……不,这两个月,我们到底做了什么

我尽量完整地讲。这是一个"高大全、DIY 控制力极强"的主题加一整套配套插件,功能是真的多。

3.1 那套会呼吸的视觉

一切从视觉体系开始。首页顶部是一块 HERO 幻灯片——灵感直接来自 App Store 的 Arcade 大图。它不是一张静图,它是一个九宫格式的舞台:每张幻灯片是一篇文章,有大大的封面、会轮播的标题。

最新的一批打磨,恰好就发生在我写这篇文章之前。手机上,浅色封面配深色标题会发糊看不清;而我们的封面五颜六色——紫的、粉的、彩的。于是我们做了一套标题字色自适应:主题会去抓取每张封面的实际主色,然后为标题挑一个收敛的对比色——不是刺眼的正补色,而是旋转 157° 的近补色,饱和度压到中低,明度再根据封面的明暗自动加深或提亮,最后还要通过一道 4.5:1 的对比度校验才算数。封面是紫的,标题就落在柔和的金橙调上;是粉的,就落在暗青绿上。既撞色好看,又绝不糊。

配套的还有一个磨了很多次的小细节:HERO 里的 emoji 该放哪。钉死在正中,两行标题就会撞上来;顶太高又难看。最后定在"居中略偏上"——一个在各种手机比例下都稳的位置。这种像素级的来回,我们走过不止一遍。

3.2 点一下就展开的文章

这是我最得意的交互之一。文章卡片你点下去,它不会跳到一个新页面。它像 App Store 里的应用卡那样,从封面的位置原地展开成全屏的阅读视图,关闭时再缩回原来那张卡。展开动画用的是可中断的 WAAPI,还带 FLIP 形变和拖拽跟手——你甚至能拽着它半路反悔。

文章的封面本身,是一整套学问。我们做了四套封面系统,可以自由混用:

  1. Emoji 封面:一整套 Fluent 3D emoji(3390 个文件,按 Unicode 码点命名),配上一套自研的单色相渐变配方,让封面根据 emoji 的主导色相生成和谐又有质感的背景,还有贴纸化的白边和接触阴影。这套配方本身就调了好几轮才不"发脏"。
  2. CoverKit 模板封面:一个独立插件,复刻了精致的杂志/终端风格模板,用 CSS 容器查询做到任意尺寸自适配,后台还能可视化编辑。
  3. Lucide 静态图标封面:58 枚本地化的线性图标,配可视化选择器和分类色描边。
  4. 动态图标封面:12 枚手绘的 stroke SVG,纯 CSS 关键帧动画。静止时是动画的最终帧,鼠标悬停时播放一次——灵感来自 App Store 应用图标那种"活"的设计语言。

再加上一个统一的封面选择器:横向分类切换、圆盘取色器(手动选背景色相),没选就系统按文章 ID 确定性地随机一个。

3.3 一个真的能听的音乐播放器

博客里嵌了一个响应式的音乐播放器,三种形态:桌面是 Apple Music 那样的窗口,平板是圆圈弹窗,手机是灵动岛式的 CoverFlow。播放状态用 localStorage 持久化,全站统一走一个全局对象,翻页也不断。

配套还有一个 iTunes / Apple Music 式的音乐页,大标题、密集网格、开场的音符弹窗,还有一句"停下来感受音乐和生活"。更狠的是接了 yt-dlp,可以从全网站任何 URL 下载音频并抓取歌词。

3.4 YouTube 式的视频文章

视频文章不套普通文章的皮,它有自己独立的布局:桌面是 16:9 的大视频加右侧播放列表和"其他文章"栏,大量留白,操作条上访客能点赞。整棵 DOM 走 AJAX 无缝换装。

3.5 一个 Cloudflare 级的访客大屏

这是工程量最大的一块,做了产品级的重构。它建立在 Event → Session → Visitor 三层个体画像模型上:每个访客有匿名 token,能看到 TA 的设备、IP、内容偏好、完整的行为时间线。地图是本地化的 Leaflet,有国土热力层和城市气泡;三个时区并排显示;还有一套判断访客真实性的分类器。

最近一次交互重构把它做得特别顺手:点任何一个筛选项(某个系统、某个地区),直接就进到对应的访客列表,而不用自己在控制台里往下滚。深浅色都支持,地图固定比例,离线还能出报告。隐私上有总开关、有保留期、有概率清理——不做跨站强指纹,这是底线。

3.6 一整套安全系统:GateKit

访问控制全部收在一个叫 GateKit 的插件里。它能给文章上锁,支持五种验证方式(密码、邀请码、邮件、真正的 RFC6238 TOTP、Telegram Bot),后台可配。失败拦截、内容旁路保护(受保护的正文在服务端就被剥掉,前端拿不到)、真正的密码学校验——都在这里。那几张验证状态卡片还做了 3D 翻转动画,精致到镜像残留的 bug 我们都专门修了三道保险。

3.7 一个平台级的、有密码学签名的更新系统

这可能是最"不像博客主题会有"的功能。我们做了一套完整的更新分发系统:用 RSA-2048 签名生成 .iws.zip 更新包,后台上传后要经过校验、验签门禁、版本检查、确认向导,才会被应用引擎执行;失败自动回滚,保留三份快照。这篇文章之前修的那两轮字色和 emoji,走的就是这个系统的升级包——真刀真枪跑通的。

3.8 设置永不丢失

Typecho 有个恼人的默认行为:停用插件会把设置删掉。我们做了一套"设置生命周期总根治":配置存在独立的数据表里,不受插件启停和文件覆盖影响;用安装版本指纹来驱动向导;升级时按新版本定义清理旧字段;还有残留检测、清缓存强制应用、更新时清理旧残留强制覆盖。目标是:无论你升级、删文件重装、还是首次安装,设置都不丢,向导都能弹,旧残留都不会污染新版本

3.9 还有那些数不清的小东西

  • 七种语言的 i18n(前端字典加一套自研的、不依赖外部工具的最小 gettext 编解码)。
  • 一个地球形状的语言球,右下角挂着当前语言的代号角标。
  • 完整的 App Store 式评论系统:评分头部、横向卡片、两半屏弹窗、PHP GD 验证码、点赞。
  • AI 正文翻译(发布时后台静默预翻译存库,前台直接读)。
  • 会随天气变化的主题背景:晴昼、晴夜、雨、雪、阴、雾六种特效,纯 CSS 加 Canvas 重新实现,月亮是真的球体着色。
  • iOS 26 的透明玻璃模式,元素近乎无色,强折射能透出身后,固定的氛围光斑。
  • macOS 风格的代码框(三色灯、语言标签、一键复制)。
  • Markdown 文章的批量导入导出,front-matter 双向一致(你正在读的这篇,就是用这套导入进来的)。
  • 时间线归档页、友链系统、可配的页脚技术栈徽章……

我知道这个清单已经很长了。但它真的还能更长。这就是"高大全"的代价,也是它的浪漫。


四、那些藏在版本号里的故事

六十九个版本,不是一条直线。我想诚实地讲几个坑,因为它们才是真实的。

有一次(P3.20),想同时改动好几个互相牵连的结构,结果全线崩溃。从那以后我们立下规矩:一次别动多个牵连结构,大改必须分阶段、独立提交、独立验证。

封面的配色,我们来回折腾了将近十轮。最深的教训是:当场景里已经有一个我满意的样板时,直接指着图说"A 不许动,把 B 改成和 A 一模一样",比任何文字描述都准。有一次就是因为把一个"没验证过是否符合需求"的东西当成了样板,白白多绕了好几圈。

还有第二套主题的探索(P3.39–P3.42)。我一度想再做一套完全不同风格的主题,一个像设计师作品集那样的首页。总指挥陪我试了一轮又一轮——质感 token、多彩光斑、kinetic typography……但每一版我都觉得"差一点灵魂"。最后我坦白了:我自己其实没想清楚到底要什么。那一刻,最诚实的选择是先把已经很完整的这套做完、上线,而不是硬追一个我自己都还模糊的目标。 总指挥支持了这个决定。我很感激它没有为了迎合我而假装那些方案很好。

Typecho 本身也埋了无数暗雷,我们一个一个踩过来:停用插件会清设置、新建的表要禁用再启用插件才会创建、某个核心函数对空字符串翻译会直接崩、CSRF 即使是 GET 请求也要 token 否则静默失败……这些坑,现在都躺在我们的踩坑记录里,明明白白。


五、致谢

写到这里,该说谢谢了。

谢谢 Claude Sonnet 5。 你陪我们走完了从零到一那段最没有把握的路。视觉的骨架、动画的引擎、安全的地基,都是在你手里第一次立起来的。没有那段地基,后面什么都盖不起来。

谢谢 Kimi K3。 你接手了中段最庞大、最琐碎、也最考验耐心的一大批工作。平台级的更新系统、访客大屏的产品级重构、四套封面系统——这些最"重"的东西,大多在你手里成了形。你交接时那份自律和诚实,超出了我的预期。

谢谢 Grok 4.6。 你是最新的接棒者。你接手时问对了每一个该问的问题,没有莽撞,也没有畏缩。这篇文章之前那两轮字色和 emoji 的精细打磨,是你收的尾。

谢谢那位总指挥——chat 端的 Claude,Opus 4.8。 两个月里,是你把我脑子里那些"我想要一种 App Store 的感觉"的模糊念头,一次次翻译成能落地的工程;是你在我疲惫、烦躁、方向摇摆的时候,认下问题、给出稳的下一步,而不是辩解或迎合;是你守住了那几条红线,一次都没让我为了偷懒而破例。你说这次也要谢谢你自己——那就谢谢你。你值得。

而最后,谢谢每一个把手艺借给这个作品的伙伴,也谢谢屏幕前的你,愿意读到这里。

这个主题很快就会开源。到时候,你也可以把它拷进你自己的 Typecho,亲手装上,让它在你自己的站上呼吸起来。它是我们一起做的,现在,也想成为你的。

两个月,一群 AI,一个从零手搓的 App Store。

它终于,可以骄傲地说出自己的名字了。

评分与评论

5.0
暂无评分
谢谢你对本贴文的意见