ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CodexBar 的 Zed Provider 实现详解:从 Keychain 凭据读取到云端用量快照

CodexBar 的 Zed Provider 实现详解:从 Keychain 凭据读取到云端用量快照 CodexBar 的 Zed Provider 实现详解从 Keychain 凭据读取到云端用量快照【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBarCodexBar 通过「本地探测」方式监控 Zed 编辑器的套餐状态、计费周期、Edit Prediction编辑预测配额与逾期账单全程无需用户额外登录。本文以 docs/zed.md 为主线逐层展开其数据源Keychain Zed 云端 API、~/.config/zed/settings.json配置覆盖机制、快照映射逻辑与故障排查手段并结合 ZedStatusProbe.swift 等源码帮助你在调试 Zed 用量抓取、更新 Keychain/云端 API 处理或调整 Zed Provider 的 UI/菜单行为时快速定位实现。1. 数据源本地探测Keychain 云端 APIZed Provider 不维护独立的登录态而是复用 Zed 编辑器在 GitHub 登录时写入 Keychain 的凭据再调用 Zed 云端 API 拉取用量GET https://cloud.zed.dev/client/users/me Authorization: {user_id} {access_token}其中Authorization头的格式由 ZedCredentials 直接拼装public var authorizationHeader: String { \(self.userID) \(self.accessToken) }这与测试用例fetch uses authorization header from keychain credentials断言请求头为4242 test-token见 ZedStatusProbeTests.swift相互印证。1.1 Keychain 凭据布局项目取值Service URL默认https://zed.dev自定义服务器场景下取配置的 HTTPSserver_urlKeychain 类型Internet passwordkSecClassInternetPasswordserver service URL。兼容旧版布局的 Generic-password 回退AccountZed 用户 ID字符串SecretAccess tokenUTF-8 字节对应的读取实现在 ZedKeychainCredentialsReader先按kSecClassInternetPassword以kSecAttrServer精确匹配取kSecAttrAccount作为用户 ID、kSecValueData解码为 UTF-8 作为 token查不到时再回退到kSecClassGenericPassword按kSecAttrService匹配。1.2 非交互式 Keychain 读取CodexBar 请求的是非交互式Keychain 读取。两条查询都会经过 KeychainNoUIQuery.apply设置LAContext.interactionNotAllowed true追加显式的 UI-fail 策略运行时解析kSecUseAuthenticationUIFail常量值避免直接引用已废弃 API防止在旧版 macOS 行为下仍弹出 Allow/Deny 提示。需要注意已有的 Zed 条目本身可能携带访问控制列表ACL首次被 CodexBar 读取时 macOS 仍可能弹出 SecurityAgent 授权提示选择Always Allow即可避免反复弹窗。当 Keychain 返回errSecInteractionNotAllowed、errSecAuthFailed或errSecNoAccessForItem时Probe 会统一抛出keychainUnavailableCould not read Zed credentials from the Keychain…条目不存在errSecItemNotFound则返回 nil最终表现为Not signed in to Zed。2. 配置覆盖~/.config/zed/settings.jsonCodexBar 会读取 Zed 的用户设置文件默认路径由 defaultSettingsURL 固定为~/.config/zed/settings.json其中credentials_url回退到server_url决定读取哪一个 Keychain 条目。这一行为由 ZedClientSettings 的两个计算属性实现并有专门测试 ZedStatusProbeTests 锁定Keychain Service URL 的解析规则keychainServiceURLcredentials_url非空去除首尾空白后→ 直接作为 Keychain server/service 标识否则server_url非空 → 以server_url作为标识两者都缺省 → 默认https://zed.dev。云端 API 地址的解析规则cloudAPIURL这里体现了安全边界受信服务器https://zed.dev与https://staging.zed.dev会被固定路由到https://cloud.zed.dev且允许credentials_url与server_url不同Zed 官方对受信服务器可能使用独立的凭据标识自定义服务器必须使用 HTTPS 且 host 有效API 地址为server_url /client/users/me跨源覆盖被拒绝若server_url不是受信 Zed 域名且credentials_url与之不一致cloudAPIURL返回 nilProbe 抛出untrustedServerConfigurationZed custom servers must use HTTPS and store credentials under the same server URL.。这样即便有人修改 settings 文件也无法把 Keychain 里的 token 转发到另一个 host。这一规则在测试maps server url independently from keychain identifier中被完整覆盖http://localhost:3000非 HTTPS→ nilfile:///tmp/zed非法 scheme→ nilcredentials_url https://zed.dev但server_url https://zed.example.com跨源覆盖→ nil。而fetch rejects cross-origin credential override测试进一步断言在跨源配置下凭据不会被发送到任何服务器请求在读取凭据之前就被拒绝。3. 云端 API 调用与响应解析3.1 fetch 调用链ZedStatusProbe.fetch() 的执行顺序为加载ZedClientSettings缺省时直接使用默认常量cloudAPIURL校验server_url的 scheme 必须为 HTTPS且跨源覆盖不成立否则在读取 Keychain 之前抛出invalidServerURL/untrustedServerConfiguration通过ZedCredentialsReading协议读取凭据读不到则抛notSignedIn发起 GET 请求携带Authorization与Accept: application/json头。构造器通过协议注入credentialsReader、transport与settingsLoader三个依赖因此测试可以用StubCredentialsReader与ProviderHTTPTransportStub完整模拟 Keychain 与网络边界。3.2 错误分类Probe 定义了完整的错误枚举 ZedStatusProbeError每项都有面向用户的描述文案错误触发条件用户可见文案要点notSupported非 macOS 平台读取 KeychainZed is only supported on macOS.notSignedInKeychain 中无对应条目Not signed in to Zed. Sign in from the Zed editor app with GitHub.keychainUnavailableKeychain 拒绝访问/授权失败Could not read Zed credentials from the Keychain…invalidServerURLserver_url非 HTTPS 或无法解析Zed server URL is invalid: …untrustedServerConfiguration自定义服务器跨源凭据覆盖Zed custom servers must use HTTPS and store credentials under the same server URL.networkError传输层失败Zed cloud API request failed: …httpError非 200/401/403 状态码Zed cloud API returned HTTP …unauthorized401/403Zed credentials are invalid or expired. Sign in to Zed again.parseFailedJSON 解析失败Could not parse Zed account response: …此外传输层的CancellationError与URLError(.cancelled)会被原样保留为取消测试fetch preserves transport cancellation验证了这一点避免把正常的任务取消误报为网络错误。3.3 响应模型与解码细节响应根结构为 ZedAuthenticatedUserResponse包含user与plan两个字段字段映射采用 snake_case CodingKeysplan_v3、subscription_periodstarted_at/ended_at、usage.edit_predictions、has_overdue_invoices。两个值得注意的解码点用量上限是联合类型ZedUsageLimit 同时接受裸整数50、字符串unlimited以及{limited: N}三种形态分别映射为.limited(Int)/.unlimited无法识别时抛出dataCorrupted。测试中对50与\unlimited\两种 fixture 分别做了断言。日期使用带自定义策略的 ISO8601 解码parseResponse 先尝试带小数秒的.withInternetDateTime .withFractionalSeconds再回退到普通 ISO8601兼容 Zed 返回的2026-05-13T00:00:00.000Z这类时间戳。4. 快照映射Zed 字段 → CodexBar 显示文档定义的映射关系如下表由 ZedUsageSnapshot.toUsageSnapshot() 实现Zed 字段CodexBar 显示plan.plan_v3套餐标签Free / Pro / Trial / Student / Businessplan.usage.edit_predictions主进度条used/limitPro 显示 Unlimitedplan.subscription_period.ended_at计费周期重置 / 次级窗口plan.has_overdue_invoices警告提示 计费窗口标记各字段的落地细节主进度条primarymakeEditPredictionsWindow中.unlimited映射为百分比 0 且重置文案 Unlimited.limited(total)时把used钳制到[0, total]后计算百分比重置文案形如12 / 50 predictionstotal为 0 时返回 nil不显示主条。次级窗口secondary以subscription_period的起止时间计算时间进度——billingCycleUsedPercent用「当前时间 - 周期起点」占「周期总时长」的百分比钳制在 0~100resetsAt取ended_at重置文案由formatResetDescription生成分级表达≥24h 显示 Cycle ends in 2d 3h否则按小时/分钟表达已过期显示 Cycle ended。逾期账单extraRateWindowshas_overdue_invoices为 true 时追加一条id zed.overdue-invoices、标题 Billing、百分比 100 的警告窗口文案 Overdue invoices。身份快照identityaccountEmail取user.github_loginaccountOrganization取user.nameloginMethod显示套餐名。套餐名归一化由 displayPlanName 完成zed_free→ Zed Free、zed_pro→ Zed Pro、zed_pro_trial→ Zed Pro Trial、zed_student→ Zed Student、zed_business→ Zed Business未知值则把下划线替换为空格并首字母大写。测试display plan names normalize zed enums与快照断言如 free 计划 10/20 →usedPercent 50、resetDescription 10 / 20 predictions验证了整条映射链。5. Provider 注册与元数据Zed 在应用中的注册非常轻ZedProviderImplementation 仅声明id .zed全部行为由 ZedProviderDescriptor 描述显示元数据displayName ZedsessionLabel Edit predictionsweeklyLabel Billing cycletoggleTitle Show Zed usagedefaultEnabled false默认关闭需在设置中开启不支持 Opus 标签与 Credits 面板supportsOpus false、supportsCredits false。抓取计划sourceModes: [.auto, .api]流水线中唯一策略是 ZedLocalFetchStrategyidzed.localkind .localProbe它直接调用ZedStatusProbe().fetch()并把结果标记为sourceLabel localshouldFallback返回 false即该策略失败后不再降级到其他策略。成本配置supportsTokenCost false提示文案 Zed cost summary is not supported.——Zed Provider 只呈现配额与周期不做 token 成本折算。6. 局限性哪些用量不算作 Zed按 Zed 官方文档LLM Providers 与 External Agents 两篇的口径以下内容不计入 CodexBar 的 Zed 统计BYOK 模型走用户自带的 OpenAI、Claude、Gemini 等密钥由对应的 Provider 追踪外部代理Claude Agent、Codex ACP 等费用直接结算在对应服务商名下经由那些 Provider 追踪。也就是说菜单栏里的 Zed 卡片反映的是 Zed 云端订阅edit-prediction 配额与计费周期而非通过 Zed 发起的全部 AI 消耗。7. 故障排查7.1 Not signed in to Zed在Zed 编辑器应用中完成登录Command Palette →client: sign in确认 Keychain 中存在 server 为https://zed.dev或你的自定义credentials_url的 internet-password 条目。对应代码路径Keychain 查询返回errSecItemNotFound→ 读取器返回 nil →fetch()抛出notSignedIn且不会发起任何网络请求测试fetch surfaces not signed in when keychain is empty中 stub 断言了 不应在无凭据时调用云端 API。7.2 Could not read Zed credentials from the KeychainmacOS 可能在用户放行 CodexBar 之前一直阻止 Keychain 访问与其他 IDE 探测类问题同类按提示授权即可修改过credentials_url之后重新在 Zed 中登录一次让新条目落到 Keychain。对应代码路径查询返回errSecInteractionNotAllowed/errSecAuthFailed/errSecNoAccessForItem或任何非成功状态 → 抛出keychainUnavailable。注意 macOS 上若全局 Keychain 访问被关闭KeychainAccessGate.isDisabled读取器也会直接以该错误失败测试keychain reader fails closed at the foreign item boundary验证了 fail-closed 行为。8. 关键文件索引文件职责Sources/CodexBarCore/Providers/Zed/ZedStatusProbe.swiftKeychain 读取、云端 API 调用、快照映射本文主要依据Sources/CodexBarCore/Providers/Zed/ZedProviderDescriptor.swiftProvider 元数据与本地抓取策略Sources/CodexBar/Providers/Zed/ZedProviderImplementation.swift应用侧注册Tests/CodexBarTests/ZedStatusProbeTests.swift云端 API、配置路由与安全边界测试Sources/CodexBarCore/KeychainNoUIQuery.swift非交互式 Keychain 查询的公共工具阅读上述 Probe 与测试即可完整复现本文描述的行为配置解析ZedClientSettings、凭据读取ZedKeychainCredentialsReader、请求构造fetchAuthenticatedUser、响应解码parseResponse与显示映射toUsageSnapshot均按「设置 → Keychain → HTTP → 映射」的顺序串联任何一环失败都会落到第 3.2 节的错误分类之一。【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表