从 0 到 1 开发一个 Claude Code 状态栏工具,并发布到 npm

前言

最近在折腾 Claude Code、CCSwitch 以及 AI API 聚合平台相关的工具链时,发现一个很有意思的需求:

用户已经通过 CCSwitch 配置好了自己的 AI 平台地址、API Key 和模型,那么能不能再做一个状态栏工具,让 Claude Code 底部直接显示平台余额、今日消费、模型、上下文占用等信息?

最后我实现了一个 npm 工具:

npm install -g @axisapi/statusline
axisapi-statusline init

用户安装并初始化后,打开 Claude Code,就能在底部看到类似这样的状态栏:

AxisAPI ¥23.80 · 今日 ¥1.24 · Claude-A · VIP · Sonnet 4.5 · 32%

本文记录一下这个工具从 0 到 1 的开发、调试、发布到 npm 的完整过程,以及中间遇到的一些坑。


一、为什么要做这个工具?

Claude Code 本身支持自定义 statusLine,也就是底部状态栏。

而现在很多开发者使用 Claude Code 时,并不是直接配置官方 API,而是通过:

  • CCSwitch
  • API 中转平台
  • 企业内部 AI 网关
  • 多模型聚合平台

来统一管理模型、Key、Base URL 和价格倍率。

这种情况下,用户经常会关心几个问题:

  • 当前用的是哪个模型?
  • 当前 Key 还有多少余额?
  • 今天已经消耗了多少?
  • 当前走的是哪个渠道?
  • Claude Code 上下文用了多少?
  • 当前是否是通过 CCSwitch 本地代理调用?

所以我想做一个小工具,把这些信息直接显示到 Claude Code 底部。

最终目标是:

npm install -g @axisapi/statusline
axisapi-statusline init

然后用户就能直接用。


二、整体实现思路

整体架构其实很简单:

Claude Code
   ↓
调用 statusLine.command
   ↓
axisapi-statusline 命令
   ↓
读取 Claude Code stdin 会话信息
   ↓
读取本地 ~/.axisapi/statusline.json 配置
   ↓
请求后端 /api/statusline/me
   ↓
输出一行状态栏文本

其中 CCSwitch 负责模型调用配置:

ANTHROPIC_BASE_URL
ANTHROPIC_AUTH_TOKEN
ANTHROPIC_MODEL

而我的状态栏工具负责展示平台信息:

余额
今日消费
渠道
套餐
模型
上下文占用

这两块逻辑最好不要混在一起。


三、项目初始化

我使用 Node.js 开发 CLI 工具,因为最终要发布到 npm,用户安装比较方便。

项目结构大致如下:

axisapi-statusline
├─ bin
│  └─ axisapi-statusline.js
├─ src
│  ├─ api.js
│  ├─ claude.js
│  ├─ commands.js
│  ├─ config.js
│  ├─ detect.js
│  ├─ paths.js
│  ├─ render.js
│  └─ utils.js
├─ scripts
│  └─ check.cjs
├─ package.json
├─ README.md
└─ LICENSE

package.json 核心配置如下:

{
  "name": "@axisapi/statusline",
  "version": "0.1.0",
  "description": "AxisAPI statusline for Claude Code, with CCSwitch provider detection.",
  "type": "module",
  "bin": {
    "axisapi-statusline": "./bin/axisapi-statusline.js"
  },
  "files": [
    "bin",
    "src",
    "README.md",
    "LICENSE"
  ],
  "scripts": {
    "start": "node ./bin/axisapi-statusline.js",
    "init": "node ./bin/axisapi-statusline.js init",
    "doctor": "node ./bin/axisapi-statusline.js doctor",
    "sync": "node ./bin/axisapi-statusline.js sync",
    "check": "node ./scripts/check.cjs",
    "pack:dry": "npm pack --dry-run"
  },
  "engines": {
    "node": ">=18.0.0"
  },
  "publishConfig": {
    "access": "public"
  },
  "dependencies": {
    "commander": "^12.1.0",
    "sql.js": "^1.13.0"
  }
}

这里最重要的是 bin

"bin": {
  "axisapi-statusline": "./bin/axisapi-statusline.js"
}

它表示用户全局安装后,可以直接执行:

axisapi-statusline

四、CLI 命令设计

工具提供了几个命令:

axisapi-statusline init
axisapi-statusline sync
axisapi-statusline doctor
axisapi-statusline config
axisapi-statusline --version

默认直接执行:

axisapi-statusline

时,就是输出 Claude Code 状态栏内容。

命令含义如下:

命令 作用
init 初始化状态栏,自动检测 CCSwitch / Claude Code 配置
sync 重新同步 API 平台配置
doctor 检查配置是否正常
config 查看当前状态栏配置
默认命令 给 Claude Code 输出状态栏文本

五、初始化时做了什么?

用户执行:

axisapi-statusline init

工具会尝试自动检测用户是否已经通过 CCSwitch 配置了 AxisAPI Provider。

检测顺序大致是:

1. 当前环境变量
2. ~/.claude/settings.json
3. ~/.cc-switch/settings.json
4. ~/.cc-switch/config.json
5. ~/.cc-switch/cc-switch.db

如果自动识别到了平台配置,就会写入:

~/.axisapi/statusline.json

示例:

{
  "platform": "AxisAPI",
  "baseUrl": "https://api.axisapi.cn",
  "apiKey": "sk-xxxx",
  "model": "claude-sonnet-4-5",
  "providerSource": "ccswitch-db:providers",
  "cacheSeconds": 30,
  "timeoutMs": 1200,
  "endpointPath": "/api/statusline/me",
  "updatedAt": "2026-05-17T06:40:00.000Z"
}

同时会修改 Claude Code 的配置文件:

~/.claude/settings.json

加入:

{
  "statusLine": {
    "type": "command",
    "command": "axisapi-statusline",
    "padding": 0,
    "refreshInterval": 30
  }
}

这样 Claude Code 启动后,就会自动调用我的状态栏命令。


六、状态栏输出逻辑

Claude Code 会把当前会话信息通过 stdin 传给 statusLine 命令。

状态栏工具读取后,会解析:

模型名称
上下文窗口占用百分比
当前工作目录
其他 Claude Code 会话信息

然后再请求自己的后端接口:

GET /api/statusline/me
Authorization: Bearer sk-xxxx

后端返回:

{
  "platform": "AxisAPI",
  "balance": 23.8,
  "currency": "CNY",
  "todayCost": 1.24,
  "channel": "Claude-A",
  "plan": "VIP",
  "modelDisplayName": "Sonnet 4.5"
}

最终输出:

AxisAPI ¥23.80 · 今日 ¥1.24 · Claude-A · VIP · Sonnet 4.5 · 32%

如果后端接口还没实现,或者请求失败,就降级显示:

AxisAPI · gpt5.5 · 32%

这样不会影响用户正常使用 Claude Code。


七、后端接口设计

我的后端是基于 new-api 做的二次开发。

新增接口:

GET /api/statusline/me
Authorization: Bearer sk-用户key

返回:

{
  "platform": "AxisAPI",
  "balance": 23.8,
  "currency": "CNY",
  "todayCost": 1.24,
  "channel": "Claude-A",
  "plan": "VIP",
  "modelDisplayName": "Sonnet 4.5"
}

字段说明:

字段 说明
platform 平台名称
balance 用户余额
currency 货币单位
todayCost 今日消费
channel 当前渠道或分组
plan 用户套餐或等级
modelDisplayName 模型显示名

在 Apipost 里测试时,请求头这样填:

Key Value
Authorization Bearer sk-你的key

注意不是写 curl 里的:

-H "Authorization: Bearer sk-你的key"

Apipost 里只需要填 Header。


八、本地开发和测试

安装依赖:

npm install

检查语法:

npm run check

本地全局链接:

npm link

查看版本:

axisapi-statusline --version

检查配置:

axisapi-statusline doctor

初始化:

axisapi-statusline init

如果自动检测不到,也可以手动指定:

axisapi-statusline init --base-url https://api.axisapi.cn --api-key sk-xxxx --model claude-sonnet-4-5

九、遇到的坑 1:Windows 下 npm run check 通配符不生效

一开始我在 package.json 里写的是:

"check": "node --check ./bin/axisapi-statusline.js && node --check ./src/*.js"

在 Linux/macOS 下问题不大,因为 shell 会自动展开:

src/*.js

但是 Windows 的 cmd 不会展开通配符,结果 Node 会把它当成真实路径:

D:\Github\axisapi-statusline\src\*.js

然后报错:

Error: Cannot find module 'D:\Github\axisapi-statusline\src\*.js'

解决办法是写一个跨平台脚本:

// scripts/check.cjs
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');

const root = path.resolve(__dirname, '..');

const targets = [
  path.join(root, 'bin', 'axisapi-statusline.js'),
  ...fs
    .readdirSync(path.join(root, 'src'))
    .filter((name) => name.endsWith('.js'))
    .sort()
    .map((name) => path.join(root, 'src', name)),
];

for (const file of targets) {
  const relative = path.relative(root, file);
  console.log(`Checking ${relative}`);
  execFileSync(process.execPath, ['--check', file], { stdio: 'inherit' });
}

然后改成:

"check": "node ./scripts/check.cjs"

这样 Windows、macOS、Linux 都能跑。


十、遇到的坑 2:CNPM 不能发布公共包

一开始我执行 npm login,结果出现:

Sign up to CNPM
Public registration is not allowed

原因是当前 npm registry 指向了国内镜像或 CNPM。

查看当前 registry:

npm config get registry

如果看到类似:

https://registry.npmmirror.com
https://r.cnpmjs.org

说明不是官方 npm 源。

发布 npm 包需要切换到官方源:

npm config set registry https://registry.npmjs.org/

然后重新登录:

npm login --registry=https://registry.npmjs.org/

确认登录账号:

npm whoami --registry=https://registry.npmjs.org/

十一、遇到的坑 3:scoped package 首次发布要加 --access public

我的包名是:

"name": "@axisapi/statusline"

这种属于 scoped package。

发布时要执行:

npm publish --access public --registry=https://registry.npmjs.org/

如果不加 --access public,很容易遇到发布权限或私有包相关问题。

发布前先预览:

npm pack --dry-run

输出大概是:

npm notice 📦  @axisapi/statusline@0.1.0
npm notice Tarball Contents
npm notice 1.1kB LICENSE
npm notice 1.8kB README.md
npm notice 1.7kB bin/axisapi-statusline.js
npm notice 930B package.json
npm notice 1.7kB src/api.js
npm notice ...
npm notice total files: 12

这个步骤很重要,可以防止把 .env、测试 Key、缓存文件、日志等敏感文件发布出去。


十二、遇到的坑 4:npm 发布要求二次验证

发布时遇到了这个错误:

npm error 403 Forbidden
Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages.

说明 npm 账号或组织策略要求发布时进行二次验证。

后来 CLI 给了一个认证链接:

Authenticate your account at:
https://www.npmjs.com/auth/cli/xxxx
Press ENTER to open in the browser...

在浏览器完成认证后,发布成功:

+ @axisapi/statusline@0.1.0

也可以用 OTP 发布:

npm publish --access public --registry=https://registry.npmjs.org/ --otp=你的6位验证码

十三、遇到的坑 5:bin 路径建议加 ./

发布时 npm 提示:

npm warn publish "bin[axisapi-statusline]" script name was cleaned

后来检查 package.json,发现 bin 写成了:

"bin": {
  "axisapi-statusline": "bin/axisapi-statusline.js"
}

建议改成:

"bin": {
  "axisapi-statusline": "./bin/axisapi-statusline.js"
}

同时 bin/axisapi-statusline.js 第一行要有:

#!/usr/bin/env node

这样 npm 全局安装后才能正确识别为命令行工具。


十四、遇到的坑 6:通过 CCSwitch 本地代理时未显示 via CCSwitch

我希望用户通过 CCSwitch 本地代理时,状态栏显示:

via CCSwitch

最开始只判断:

process.env.ANTHROPIC_BASE_URL

但实际 Claude Code 调用 statusLine 命令时,不一定会把这个环境变量传进来。

所以后来增加了更多判断:

1. process.env.ANTHROPIC_BASE_URL 是否是 localhost / 127.0.0.1
2. ~/.claude/settings.json 里的 ANTHROPIC_BASE_URL 是否是本地代理
3. ~/.axisapi/statusline.json 的 providerSource 是否包含 ccswitch

这样更稳。


十五、发布成功

最终发布成功:

+ @axisapi/statusline@0.1.0

用户可以直接安装:

npm install -g @axisapi/statusline

如果国内镜像暂时还没同步,可以先指定官方源:

npm install -g @axisapi/statusline --registry=https://registry.npmjs.org/

等国内镜像同步后,也可以用:

npm install -g @axisapi/statusline --registry=https://registry.npmmirror.com

安装后:

axisapi-statusline --version
axisapi-statusline init
axisapi-statusline doctor

十六、用户使用流程

推荐给用户的流程是:

# 1. 先在 CCSwitch 中配置 AxisAPI Provider
# Base URL: https://api.axisapi.cn
# API Key: sk-xxxx
# Model: claude-sonnet-4-5

# 2. 安装状态栏工具
npm install -g @axisapi/statusline

# 3. 初始化
axisapi-statusline init

# 4. 检查
axisapi-statusline doctor

# 5. 打开 Claude Code
claude

如果自动识别失败:

axisapi-statusline init --base-url https://api.axisapi.cn --api-key sk-xxxx --model claude-sonnet-4-5

十七、doctor 检查效果

初始化前:

✗ AxisAPI 配置文件 C:\Users\18236\.axisapi\statusline.json
✓ Claude settings.json C:\Users\18236\.claude\settings.json
✗ Claude statusLine 指向 axisapi-statusline
✓ CCSwitch 数据库存在 C:\Users\18236\.cc-switch\cc-switch.db

如果 Claude Code 中未显示状态栏,请执行:axisapi-statusline init

初始化后:

✓ AxisAPI 配置文件 C:\Users\18236\.axisapi\statusline.json
✓ Claude settings.json C:\Users\18236\.claude\settings.json
✓ Claude statusLine 指向 axisapi-statusline
✓ CCSwitch 数据库存在 C:\Users\18236\.cc-switch\cc-switch.db

这个命令对排查用户环境问题非常有用。


十八、关于平台推广的小心思

这个工具表面上只是一个 Claude Code 状态栏,但它其实解决了 AI 中转平台用户的几个真实痛点:

  • 不用打开后台也能看到余额
  • 不用猜今天消耗多少
  • 不用问客服当前 Key 有没有生效
  • 不用担心模型名看不懂
  • 通过 CCSwitch 配置后还能自动识别

对于平台来说,它不是一个硬广工具,而是一个用户体验增强工具。

当用户每天都在 Claude Code 底部看到:

AxisAPI ¥23.80 · 今日 ¥1.24 · Claude-A · Sonnet 4.5

平台品牌自然就留在了用户的开发环境里。

这种方式比单纯发广告更自然,也更适合技术用户。


十九、后续优化方向

后续还可以继续加:

  1. 显示本月消费
  2. 显示当前 Key 名称
  3. 显示模型倍率
  4. 显示分组倍率
  5. 显示请求延迟
  6. 显示平台公告
  7. 显示限流/维护状态
  8. 支持多平台 Provider 自动识别
  9. 支持状态栏主题颜色
  10. 支持一键修复 Claude Code 配置

例如:

AxisAPI ¥23.80 · 今日 ¥1.24 · 本月 ¥18.66 · Claude-A · Sonnet 4.5 · 32%

或者当平台维护时:

AxisAPI ¥23.80 · Claude-A · 部分渠道维护中 · Sonnet 4.5

总结

这次从 0 到 1 做了一个 Claude Code 状态栏工具,完整经历了:

需求设计
CLI 开发
CCSwitch 配置识别
Claude Code statusLine 接入
后端接口设计
Windows 兼容问题修复
npm 发布
二次验证
最终上线

最终用户只需要:

npm install -g @axisapi/statusline
axisapi-statusline init

就能在 Claude Code 底部看到平台状态。

对于做 AI 聚合平台或 API 中转平台的人来说,这类小工具很值得做。它不一定复杂,但可以明显提升用户体验,也能让平台更像一个完整的开发者生态,而不是单纯的 API 地址。

我个人觉得,好的中转平台不只是提供一个 Base URL 和 API Key,更应该围绕开发者的真实使用场景,把工具链体验补齐。

状态栏只是第一步。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐