---
title: 2 小时,0 行手写代码,我用 Claude 做了一个生产级 VSCode 插件
source_url: https://mp.weixin.qq.com/s/wU_WZWzlSK_Aso_hP0iVhQ
publish_date: 2026-05-10
tags: [wechat, article, claude, rag, gemini]
review_value: 7
review_confidence: 7
review_recommendation: neutral
sha256: 28958fc26c3392d1691af60a38d10b29b48c17d49595f111f8c06d925683a0cc
---
# 2 小时,0 行手写代码,我用 Claude 做了一个生产级 VSCode 插件
作者 | 奔跑的脆皮肠
**导读**:之前没写过 VSCode 插件、没接触过 Chrome Cookie 加密机制、不了解 UUAP SSO。2 小时后,独立做了一个能自动读取浏览器登录态、实时监控 Comate 模型用量的 VSCode 插件——8 个核心文件,1000+ 行代码,打包后 .vsix 可以直接分发给同事使用。
这篇文章记录这 2 小时真实发生的事。0 行手写代码,不意味着什么都不用想。恰恰相反——我花了大量时间在判断:这个方案能不能落地、这个报错的根因是什么、Claude 给的方向是不是对的。代码是 Claude 写的,但每一个关键决策是我做的。
全文 5215 字,预计阅读时间 8 分钟。
---
## 01 为什么做这个
每天用 Comate 写代码,但配额是月度的。经常到月底才发现快用完了,或者不知道哪个模型消耗最快。
官方只有一个网页可以看用量,每次打开都要切浏览器、登录 SSO、刷新——很烦。
想法很朴素:**能不能在 VSCode 状态栏实时看到配额?超过阈值还能有颜色告警。**
但真要做,门槛全是盲区:
- VSCode 插件开发没做过
- 内网接口要 SSO 登录,插件是独立进程,怎么拿到登录态?
- Chrome 的 Cookie 是加密的,macOS Keychain 怎么解?
- UUAP 的 cookie 分散在好几个域,怎么精确过滤?
全是陌生领域。但我想试试:**这种"每个环节都不会但整体目标清晰"的任务,AI辅助到底能走多远。**
---
## 02 最终效果
先看成品:
**状态栏**(右下角常驻):
- 🟢 1494.16/3000 (49.8%) · 2007 次 ← 正常
- 🟡 2200/3000 (73.3%) · 2007 次 ← 黄色警示(背景同步变黄)
- 🔴 2750/3000 (91.7%) · 2007 次 ← 红色警告(背景同步变红)
**详情面板**(点击状态栏打开):
- 月度卡片(已用 / 剩余 / 上限 / 累计请求)
- 月度进度条,70% 黄、90% 红
- 按来源使用(zulu / dodo / ducc / iCode / others 的饼状占比)
- 按模型统计表(Claude Opus / Sonnet / Haiku、GLM、MiniMax、Gemini)
- 按日统计表
- 原始响应调试视图(可折叠,对齐字段用)
**零打扰自动登录**:只要浏览器里登录过 Comate,插件启动时**静默从 Chrome SQLite 读 Cookie、解密、验证、使用**。用户全程不需要任何操作。
**失效自动恢复**:Cookie 过期时,插件**静默重读浏览器**→ 验证 → 替换 → 重试。用户只看到状态栏闪了一下"重新认证"就恢复了。
---
## 03 系统架构
```
flowchart TD
subgraph UI["🖥️ VSCode UI 层"]
direction LR
SB["状态栏
🟢🟡🔴 实时用量"]
DP["Webview 详情面板
卡片/模型/日统计"]
LW["Webview 登录向导
三合一兜底"]
end
subgraph Core["⚙️ 核心逻辑"]
direction TB
TM["🔄 定时器
60s 自动刷新"]
FSM["🧠 认证状态机
有Cookie → 测试 → 失败 → 静默恢复"]
API["📡 API 客户端
all_info / usage_statistics"]
end
subgraph Auth["🔐 鉴权层(核心难点)"]
direction TB
BC["🦀 浏览器 Cookie 读取
SQLite + Keychain + AES-128"]
CU["⚡ cURL 导入
正则提取 Cookie 字段"]
MP["📋 手动粘贴(兜底)"]
end
subgraph Storage["💾 本地存储"]
SS[("OS Keychain
vscode.SecretStorage")]
end
UI --> Core
Core --> API
Core --> Auth
Auth --> SS
SS --> API
API -.Cookie 失效.-> FSM
FSM -.自动恢复.-> BC
```
---
## 04 方法论:设计对话,而非让 AI 自由发挥
全程代码都是 Claude 写的,但**不是扔一句"帮我做个 VSCode 插件监控 Comate 用量"完事**。
我的流程是这样的:
```
确认目标(描述产品形态,给 Claude 看接口样例)
↓
Claude 给出方案,我判断哪些可行、哪些有坑
↓
让 Claude 写第一版,跑起来
↓
每次报错/不对劲,把具体信息贴给 Claude
↓
Claude 分析 + 修复,我验证
↓
功能稳定后,提迭代(图标/告警/自动化)
↓
循环
```
这个循环最关键的一步是**每次和 Claude 对话时提供"足够的上下文"**。
举个对比:
**差的提问**:"我的插件跑不起来,有错。"
→ Claude 只能猜一堆可能。
**好的提问**:"error TS6059: File '/Users/[用户名]/Desktop/vscode/extension.ts' is not under 'rootDir' '/Users/[用户名]/Desktop/vscode/src'."
→ Claude 立刻能给出"你把文件放错目录了,正确的结构是 xxx,执行 `mkdir -p src && mv ...` 这几条命令搞定"。
再比如,当 Cookie 读取出错时,Claude 让我贴真实响应,我把一整段 cURL 扔过去:
> `curl 'https://****.****.com/api/status' -H 'Accept: ...' -b '****_TOKEN=*** ****_****_TOKEN=*** ...'`
Claude 立刻识别出:"关键的 `****_*` cookie 全在父域上,我们的 SQL 查询只匹配了子域,漏掉了。修复方式是改成按 cookie 作用域精确匹配"。
**Claude 做 AI 的能力越来越强,但它吞吐上下文的能力比你贴出来的有限很多**。你得主动把关键信息喂进去——报错、真实响应、期望行为、已有代码。
**Claude 负责实现和验证,我负责判断和决策。** 做什么、先做哪个、这条路值不值得继续——这些是这 2 小时里真正花时间的地方。
---
## 05 系统真正的复杂度在哪里
### 5.1 鉴权:看似简单,实际是整个项目最难的部分
内网接口要 SSO 登录。插件不是浏览器,怎么拿到登录态?
我最初想当然以为这很容易。但实际 Claude 一上来就摆清楚了三条路,并直接给出了技术现实:
我一开始倾向"Webview 登录",听起来最优雅。
但 Claude 直白地告诉我:**"VSCode 扩展 API 不暴露 webview 的 cookie 读取能力,且 SSO 系统一般会设 X-Frame-Options: DENY,iframe 大概率被浏览器直接拒绝"**。
如果我不听这个警告,可能会花几小时在一个死路上。**Claude 在"告诉你什么方案不可行"上的价值,不亚于它写代码。**
最后选的是方案一先跑通,方案三作为终态——结合成一个"登录向导",三种方式一站式。
### 5.2 Chrome Cookie 加密:细节决定成败
macOS 上 Chrome 的 Cookie 存储方式:
1. SQLite 文件:`~/Library/Application Support/Google/Chrome/Default/Network/Cookies`
2. 加密方式:`v10` 前缀 + AES-128-CBC
3. 密钥派生:PBKDF2(从 Keychain 读的密码,'saltysalt',1003 轮,16 字节,SHA1)
4. IV:16 个空格字符
5. **Chrome M118+ 还在明文前加了 32 字节 SHA256(host_key) 做 origin binding**
这最后一条最坑。如果不处理,解密出来的 cookie value 前 32 字节是乱码,表面看没报错但 API 会拒绝。Claude 在第一次实现时就把这个"旁路细节"写进去了:
```typescript
if (plain.length > 32) {
const hostHash = crypto.createHash('sha256').update(hostKey).digest();
if (plain.slice(0, 32).equals(hostHash)) {
return plain.slice(32).toString('utf8'); // 剥离 host hash 前缀
}
}
```
我完全不知道这个机制的存在,也不会想到去问。**Claude 对这类"广为人知但我不知道"的细节的覆盖,是传统独立开发最难替代的价值。**
### 5.3 Cookie 作用域:SSO 场景下的大坑
这是我们调试中最久的一个问题。代码跑通了,从浏览器读到 **93 条 cookie**,但 API 始终返回 HTML(SSO 重定向页)。
为什么?因为 UUAP 是百度内部的 SSO,关键 cookie 分散在 **好几个父域**:
- `****.baidu-****.com` — 子域本身的 `session`
- `.baidu-****.com` — 大部分 `****_*` token
- `.uuap.*` — UUAP 自己的 token
我一开始写的 SQL 是 `host_key LIKE '%baidu-****.com%'`,看似够宽,但问题在于:
**不同域下会有同名 cookie**,比如多个站点都叫 `session`。我们读了 93 条 cookie,里面可能有 5-6 个不同的 `session`,合成 HTTP Cookie 头时按"最后写入"覆盖,结果**发给 oneapi-comate 的**`**session**`**是别的站点的**——服务端校验失败,返回 HTML,被我们错误地当成"Cookie 过期"。
调试过程:
1. **我**:状态栏显示"加载失败,Cookie 可能已过期"
2. **Claude**:先确认浏览器里能不能访问 API,再看实际返回的 HTML 是什么
3. **我**:贴上 `/api/status` 的完整 cURL
4. **Claude**:"看这些 `****_*` 都在父域上,但我们可能同时读到了其他站点的同名 cookie。建议改成'按 cookie 作用域精确匹配',只取 host 完全匹配或父域作用域覆盖的"
5. **我**:改代码,验证,搞定
**这个问题的难点不在于"写一段代码",而在于"知道问题发生在哪"**。Claude 拿到 cURL 的一瞬间就定位到了,省下来的排查时间可能是一整天。
### 5.4 无感登录 + 自动恢复
基础方案跑通后,我提了个更高的要求:
> "能不能做到这个登录是用户无感知的?比如用户在浏览器登录过 oneapi 自动获取,没有登录再去引导呢?降低成本"
Claude 立刻给出了完整设计:
```
插件激活 ↓
有保存的 cookie? → 试一次 API
├─ 成功 → 正常工作
└─ 失败 ↓
静默从浏览器读取(不弹任何 UI)
├─ 成功 → 验证有效 → 替换 cookie → 重试请求
└─ 失败 → 这时才弹引导
```
设计里还包含了防御性细节,都是 Claude 主动加的:
- **验证步骤**:静默读到的 cookie 不直接保存,先 `fetchAllInfo` 试一下,真有效才替换
- **防无限循环**:`isRetry` 参数 + `silentRecoveryInFlight` 防止并发恢复
- **用户名独立处理**:这个必须用户提供,不能自动获取,所以单独引导
这种"想到用户可能遇到的边界情况,主动防御"的能力,远比我自己闭门造车高。**如果我自己写,可能要到用户反馈"疯狂弹窗"后才会想到加锁。**
---
## 06 关键转折:Claude 诚实的时候
### 6.1 直接否定我想走的路(Webview 登录)
我上来就想要 Webview 登录——在 VSCode 里嵌入登录页,用户点几下就好。Claude 没有顺着我说,而是直接指出两个致命问题:
1. VSCode webview 的 session 跟浏览器隔离,登录完的 cookie 在 webview 里,插件 API 拿不到
2. SSO 系统普遍禁止 iframe 嵌入(`X-Frame-Options: DENY`)
它说:"建议先用方案 A(手动粘贴)跑通,后面再看是否升级"。
**这是一个很好的"AI 诚实"的例子**。如果 AI 只是迎合用户,可能会先写一堆 webview 代码,跑起来发现不行,再回头推翻——浪费几小时。
### 6.2 看懂真实数据后立刻对齐字段
我贴出第一次 API 返回的 JSON 后,Claude 立刻对比出它猜的字段名跟实际不一致:
它主动说:"模型汇总服务端已经算好了,前端不用再聚合"——还顺手优化了交互。
### 6.3 承认"浏览器自动读取"的局限,主动加 cURL 导入
自动读取调通后,Claude 主动说:**"浏览器自动读取偶尔会因为 SSO 多域 cookie 处理不全而失败"**,并加了 cURL 导入作为兜底。
现在的登录向导三方式并存:
- 🚀 **从浏览器读取**(推荐,一键)
- ⚡ **从 cURL 导入**(最稳,30 秒)
- 📋 **手动粘贴**(兜底)
即使自动方式失败,用户 30 秒也能搞定。**承认"我不能 100% 保证",并设计 fallback,这是成熟工程的标志**。
---
## 07 Claude 也会错:一些例子
对着这个项目用了 2 小时 Claude,不全是完美体验。它也会在一些地方犯错,以下都是真实发生的:
### 7.1 第一次写的字段名全猜错了
最初 Claude 猜的 `AllInfoResponse` 接口跟真实响应完全不同:
```typescript
// Claude 第一版猜的
interface AllInfoResponse {
data?: {
quota?: number;
used_quota?: number;
...
}
}
// 实际长这样
interface AllInfoResponse {
data?: {
monthly_quota_limit?: number;
monthly_used_quota?: number;
...
}
}
```
它自己知道是猜的,在代码里还留了注释提醒我"第一次运行时,在 DevTools 里把真实 JSON 贴下来对比字段名"。但如果我没注意到这行注释、直接相信它的字段名,就会跑不起来还不知道为啥。
**应对**:永远拿真实响应验证 AI 猜的数据结构。
### 7.2 文件路径一再放错
过程中至少 3 次出现"文件不在正确目录"的问题——`extension.ts` 放在根目录而不是 `src/`、`launch.json` 放在根目录而不是 `.vscode/`。每次都是我先跑出 TS 报错,Claude 才反应过来。
**应对**:项目开始前就和 AI 对齐目录结构,并让 AI 每次创建文件时显式带上完整路径。
### 7.3 浏览器 Cookie 读取,第一版没考虑作用域
第一版的 SQL 查询直接 `host_key LIKE '%****.baidu-****.com%'`,导致 UUAP 父域的关键 cookie 漏读。后来又改成 `LIKE '%baidu-****.com%'`,又带来了同名 cookie 冲突。最后才改成按 cookie 作用域精确匹配。
如果我对 cookie 作用域规则不熟,可能会在"第一次修复有 bug"阶段放弃。Claude 的第一版不是最优解,需要多次迭代才收敛到正确的实现。
**应对**:涉及"广为知晓但你不熟"的领域,多问一句"这个方案有没有已知的坑/边界情况?"
### 7.4 整体感受:越到后期越需要反复提醒
小项目阶段(前 1 小时),Claude 对话连贯、记得住之前的决策。
到后期要加图标、改告警颜色、完善文档时,有时 Claude 会重新"猜"之前已经决定好的东西——比如重写 `updateStatusBar` 时,部分变量名和之前保存到的版本对不上。
**应对**:对长上下文项目,每次让 AI 改一个模块时,先把完整的现状贴出来;或者维护一份"当前代码状态"的速记文档。
---
## 08 0 行代码,我真正做的是什么?
回看整个过程,我没写任何一行 TS 代码。但我花了大量时间在:
1. **描述目标**:什么叫"监控用量",长什么样,要哪些指标
2. **判断可行性**:Webview 登录能不能行、Chrome Cookie 能不能读
3. **提供真实数据**:贴 cURL、贴 API 响应、贴报错
4. **决策优先级**:先做最小可用,再加无感登录,再加三色告警
5. **验证结果**:状态栏对不对、面板好不好用、失效恢复符不符合预期
6. **反问和推广**:"能不能做成无感的"、"能不能加三色告警"
代码不是瓶颈。**这些"想清楚要什么、判断什么能做、拿到真实数据反馈"的事才是瓶颈**。Claude 不会替你做这些。
---
## 09 工程细节:最终产出了什么
```
comate-usage-monitor/
├── icon.png # 128x128 插件图标
├── icon_256.png # 高清版,README 用
├── package.json # 插件 manifest
├── README.md # 用户文档
├── CHANGELOG.md # 版本日志
├── .vscodeignore # 打包过滤
├── tsconfig.json
├── .vscode/
│ ├── launch.json # F5 调试配置
│ └── tasks.json
└── src/
├── extension.ts # 主入口,定时器 + 状态栏 + 恢复逻辑
├── api.ts # HTTP 客户端 + 类型定义
├── dashboard.ts # Webview 详情面板(卡片/模型/日统计)
├── loginWizard.ts # Webview 登录向导(三合一)
└── browserCookies.ts # Chrome SQLite + Keychain + AES-128
```
**代码规模**:约 1000 行 TypeScript。
**依赖**:零第三方 npm 包。所有功能用 Node 原生 API(`https`、`crypto`、`child_process`)和 VSCode API 完成。
**打包产物**:`comate-usage-monitor-0.0.2.vsix`,体积约 40KB。
---
## 10 结果
插件现在在我的 VSCode 里常驻,每次打开 VSCode 状态栏就显示当前用量,颜色一眼看出是否告急。Cookie 失效时会自动重读浏览器,无感恢复。
同事拿到 `.vsix` 文件 → `Cmd+Shift+P` → Install from VSIX → 输入用户名 → 完事。全程零配置。
---
## 11 附录:如果不用 AI,这个项目需要多少时间
### 技术栈覆盖
### 时间估算(不用 AI)
### 说明
- 按"没做过 VSCode 插件、但有前端基础的工程师"估算
- 最大不确定性在"Chrome Cookie 加密"—— 如果卡在某个环节(,比如 M118+ 的 host hash 没搜到),可能多花几天
- 实际完成:**1 人,2 小时,0 行手写代码**
---
## 12 写在最后
这不是一个"AI 多神奇"的故事。而是一个"**人 + AI 协作的最佳实践**"的样本:
人提供:真实需求、真实数据、方向判断、优先级决策
AI 提供:陌生领域的知识、代码实现、边界情况提醒、可选方案对比
当你清楚自己要什么,当你愿意把真实上下文喂给 AI,当你在 AI 犯错时有判断力把它纠回来——**盲区再多,都可以靠"明确目标 + 快速反馈"在极短时间内完成原本不可能的事**。
代码是 AI 写的,但这个插件是我做的。
---
→ [[raw/articles/claude-vscode-plugin-zero-code|原文存档]]