速评:9 月 3 号,devpub 收了上线以来第一个外部 PR。
开源圈的标准读法已经准备好了——"社区的力量""陌生人的善意",配上两句感动。我不这么读。这个 PR 值钱的地方不在它做成了什么,在它不得不怎么做。
devpub 想干的事很朴素:把 Dev.to 的网页编辑器挪进终端,本地写完一条命令推上去。0.3.0 加了上传图片。问题来了——Forem API V1 根本没有上传接口,API 只认已经存在的图片 URL,不负责给你造一个新的。作者早先为这事开过 issue #11,在里头写了一句实话:要做,得逆向网页编辑器的上传机制。然后搁置了数周。
搁置的那几周,Forem 当然不会自己长出接口来。然后 Harish 出现,fork、翻 issue 列表、挑中那个没人接的,交了一份带 29 个测试和设计说明的实现。
剧情到此为止。接下来我要拆的是另外一件事。
看上传接口的鉴权方式。网页端走 POST /image_uploads,multipart 表单,但不认 API key——认浏览器会话。得凑齐三样:_Devto_Forem_Session 那个登录 cookie、CSRF token,再加一个 Origin 匹配 dev.to。也就是说装完这个 CLI,光有 API key 不够,还得回 Chrome 开发者工具里把 cookie 和页面 meta 标签里的 token 抠出来,塞进 .devpub/.env。
作者写了一句我觉得比整篇博客都重的话:这两项不是受限 token,是完整登录凭证。还特意强调 .env 默认已进 gitignore,过期了重新复制一遍就行。
我知道这里很多人会顺手夸一句坦诚。是,比起含糊过去,这态度是好的。但别把"把这件事写清楚"当成"这件事本身没问题"。一个要你把完整登录凭证拷进本地文件的工具,无论 gitignore 加得多细、文档写得多耐心,它的性质已经变了——它从 API 客户端变成了把浏览器会话桥进终端的适配器。这个定性不是我下的,是作者自己给的,我只是复述。
而且这不是 devpub 一家的处境。评论区 Reid Marlow 说他也走过同一条路,为自动化评论回复折腾过一遍,原话的意思是 Forem V1 发文章够用,但上传和评论都缺鉴权接口,逼着人把会话状态塞进命令行脚本。一个人这么干叫 hack,一群人各自这么干,那叫官方 API 欠了一笔债,大家在用不同的方式替它还。
再说这个 PR 本身。做得是真好,好到有点讽刺。
它遵循先校验再联网:文件在不在、扩展名合不合法、有没有超 25 MB,全在本地判完,才发出第一个 HTTP 请求。文件名打错不会产生任何网络往返。凭证缺失时不抛一个含糊异常,而是打印分步指引,告诉你 cookie 去哪复制、CSRF token 在哪个 meta 标签里。作者在评论区补的那条我认为是全文信息量最大的细节——401/403 提示重抄 cookie,422 单独映射到"你的 CSRF token 可能过期了",他说这一点是调试里最难判断的部分。
难判断,因为它不是设计出来的,是试出来的。
响应结构没有公开文档,所以 _extract_url 得同时兼容 links.url、image.url、images[0] 和纯字符串四种形状,全都不匹配就带着完整响应体抛错——这最后半句是防着错误 URL 被静默写进文章。这种防御姿态,是吃过亏的人才写得出来的。
这是一份在地基不属于自己的地上盖起来的精装房,越精装,越说明地基不是你的。
29 个测试用 respx 把 HTTP 全 mock 掉,而被 mock 掉的那一层,恰恰是唯一不受你控制的那一层。这句话值得念两遍。
作者有句判断我同意:Harish 先交付原语、再在其上构建别的,节奏是对的。PR 里主动排除的两个功能——push 时自动识别本地图片路径并就地重写、一步完成封面上传和 frontmatter 写入——等上传这个原语站稳了,确实顺手。工程上是清醒的。
但清醒解决不了上游。作者在评论区预告下一步做评论功能,理由和上传一模一样:评论同样没有鉴权的 V1 接口,还得回会话方案。然后他补了一句担心——会话中途 CSRF token 轮换怎么办。
这里立个 flag。我赌下一步先上线的不是评论功能,是凭证刷新机制被迫提上台面;而且我赌它做不出真正的解法。没有官方接口,token 什么时候被换、旧的还能撑多久,全靠撞。能做到的上限,是在失效那一刻给一个足够体面的报错,让用户知道该回 Chrome 里再抠一遍。作者自己已经说了:提示优雅,续期不优雅。这句话比任何功能清单都诚实。
那 9 条评论里,有人建议加个剪贴板 flag,上传完直接把 Markdown 图片语法写进剪贴板,作者说这想法比现有方案好,收了。挺好的,这是开源正常的体温。
我只是希望多几个人抬头看一眼:这个工具做得越顺手,就越说明有一件事被长期搁在那边没人干。催 CLI 作者没有意义,他已经在用他能用的全部办法把活干了,连"这不是受限 token"这种话都愿意写出来。该被问的是另一边——上传和评论这两块,到底什么时候能不必往 .env 里塞一份完整的登录凭证。
在那之前,devpub 会一直很好用,也一直很脆。
