subswap AGENTS.md

Project instructions for Subswap, a tool whose purpose is not fully explained in the supplied text. The rules cover releases, code changes, account switching, and secure handling of credentials.

In plain words
What is it for?
Tracing code changes, running tests and release builds, reinstalling and checking the daemon, publishing releases, and enforcing account-switching and macOS keychain rules.
Why use it?
They reduce the risk of shipping unverified builds, overwriting unrelated work, or mishandling authentication data.

Instructions file for CodexOpenCode

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/x0c/subswap/agents-md
Clone the repo
git clone --depth 1 https://github.com/x0c/subswap

Made for: Codex, OpenCode.

Per session 4,675 This file is loaded in full into every session.
When invoked 4,675 The same file — it is already loaded in full.
Security scan A 1 finding. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.04675 $0.04675
Opus 5 $0.02337 $0.02337
Sonnet 5 $0.00935 $0.00935
Haiku 4.5 $0.00468 $0.00468

Measured 2d ago against content hash 876011e5ed50, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

subswap AGENTS.md scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

Anthropic usage 端点限流极严(~每账号每分钟 1 次),**禁止手动 `curl` 连发去"复现"**——会打爆桶、
AGENTS.md · 181 lines

How it starts

The opening of the file, as written. The whole thing — 181 lines — stays where its author put it; the contents beside it link to each section on GitHub.

subswap · Agent 快速规则

全局规范仍适用;本文件只保留本项目最容易漏掉、最影响安全性的规则。文档索引见下方「文档导航」。

最高优先级

  1. 功能新增或缺陷修复后,默认执行完整发布流程(通用约束见全局规范「改动即发布新版本」)。 本项目的具体落地步骤:
    • 按语义化版本提升 workspace 版本并同步 Cargo.lock
    • 跑测试 / 构建 / release 构建。
    • 先覆盖安装本机 subswap / subswapd
    • 重启 daemon,并验证版本与构建产物哈希。
    • 再提交 Git、创建并推送版本 tag、确认 GitHub Release 发布成功。
    • GitHub Release publish 后 update-homebrew.yml自动更新 x0c/homebrew-tap 的 formula,无需手动操作。 详见 docs/OPERATIONS_GUIDE.md §「Homebrew Tap 自动更新」。
  2. 修改代码前先查调用链。 编辑函数 / 方法 / 类型前用 codebase-memory-mcp 的 trace_path 查清调用者 / 被调用者,评估影响面后再动手。
  3. 工作区可能是脏的。 不回滚、不覆盖无关本地改动;提交时只 stage 本次相关文件。
  4. 改完必须验证。 代码、配置、构建脚本、依赖改动后,自己跑对应测试 / build / smoke,不把验证交给用户。 默认入口 / 自动切换这类必须对着真实列表才能确认的行为:覆盖安装后再自己跑一次无参 subswap; 只跑 cargo test 不够——没装上的二进制用户还是旧逻辑。

项目不变量

  • 手动 subswap swap 永远不依赖 quota 查询;网络坏、quota API 坏、token 过期时也要能切走。
  • Claude 自定义 API 账号必须标记 manual_only:只能手动切入,active 时禁用自动换号,也不能成为自动候选; 切回 OAuth 时必须恢复进入 API 模式前的 settings.json.env 受管字段。
  • macOS 上读写 Claude Code 的 Claude Code-credentials、以及 Cursor 命令行的 cursor-access-token / cursor-refresh-token keychain item 只能 fork /usr/bin/security, 禁止用 keyring crate(security-framework 原生 API):keyring 写会把 item ACL 重置成「仅 subswap」, 导致官方客户端(也用 security 读)每次切换后反复弹授权框。详见 docs/troubleshooting/2026-06-11-claude-code-keychain-acl-poisoning.md。 Cursor 官方钥匙串已有条目只改内容、禁止 delete 后再 add:删建会把解密权限收成「仅 security」, 桌面版界面邮箱对了、请求却报未登录。新建时才把 /usr/bin/security 和 Cursor.app 写入信任名单。
    • 测试隔离:集成测试禁止触碰真实登录钥匙串(否则 cargo test 在 macOS 弹授权框并改写本机凭证)。 Claude 认 SUBSWAP_CLAUDE_KEYCHAIN_PATH,Cursor 命令行认 SUBSWAP_CURSOR_KEYCHAIN_PATHcli_surface.rs::isolated_subswap 已把两者都指到同一份一次性 keychain。 新写的会激活 Claude OAuth 或 Cursor 命令行钥匙串的集成测试也必须经它隔离。
  • Cursor 命令行的令牌与身份必须成套读写:切换时同时写令牌后端和 cli-config.jsonauthInfo。 live 主人只认令牌 JWT,不得用过期邮箱去对号;仓库里令牌 JWT 与账号身份不一致时显示 needs re-login禁止拿这份令牌查额度或刷新(会把真正主人的一次性 refresh token 刷废)。 详见 docs/PROVIDER_KNOWLEDGE_BASE.md 的「Cursor」与 docs/troubleshooting/2026-08-14-cursor-quota-cloned-across-accounts.md
  • subswap run claude 的隔离 .claude.json 必须包含 hasCompletedOnboarding: true, 否则 claude 无论钥匙串里有无有效凭证都会弹「Select login method」首次引导—— 由 materialize_isolatedmark_onboarding_complete 写入;改隔离物化流程时不得删除该调用。 详见 docs/design/ACCOUNT_ISOLATION_DESIGN.md §2.3。
  • Provider::activate 必须先写快照,任一目标写失败要回滚。
  • refresh token 是一次性轮换,active 账号默认只读不刷;允许自愈的唯一例外是复用原生客户端官方协调机制, 绝不能由 subswap 自创一套互不相认的锁或并行抢刷:Codex 通过官方 app-server 查询/刷新,Kimi 只在能 识别并持有当前版本官方跨进程锁时刷新,Cursor active 账号只重读 live、不刷新。 activate 覆盖 live 文件前先 capture-on-leave 回灌 live 凭证进 owner 账号 store; parked 账号按各 Provider 的串行化边界刷新;Cursor 必须使用 subswap 跨进程锁。daemon 每轮还做 capture-on-arrival (reconcile_active_from_live,只 live→store) 补「绕过 swap 离开」的缺口;refresh 被上游拒绝时必须有 死 token 守卫止住反复刷的风暴并显示 needs re-login,Kimi/Cursor 的跨进程守卫只保存 refresh token SHA-256 指纹、不保存 secret。细节见 docs/PROVIDER_KNOWLEDGE_BASE.md 的「Refresh token 轮换」。 capture_live_into_store 绝不能用缺 access / refresh 的 live 快照覆盖 store 里对应凭据完整的副本 (会把账号静默写死),各 Provider 都必须保留守卫,改此逻辑前见 docs/troubleshooting/2026-06-18-live-capture-clobbers-refresh-token.md
  • 新 Provider 只能放在 crates/providers/<id>,再到 AppContext::build() 注册,并在默认入口同步本地 active。 Cursor 这类凭证位于 SQLite、切换还要协调 GUI 生命周期的 Provider 必须独立实现 Provider,不能硬塞进 文件型 JSON 共享引擎;Cursor 也不支持 subswap run/shell/env 隔离运行。细节见 docs/PROVIDER_KNOWLEDGE_BASE.md 的「Cursor」与 docs/design/ARCHITECTURE.md 的「扩展新 Provider」。
  • 文件型(凭证是本地一个 JSON blob、靠覆盖文件切换)provider 的切换机制统一在 crates/providers/commonFileBlobProvider<A> 引擎)。新增此类 provider(如未来第三个)只写一个 FileBlobRuntime 实现 (路径、元数据解析、刷新、usage 查询等差异点),在 AppContext::build() 的 provider 列表注册一行, 若要支持 subswap run/shell/env 隔离运行再把它塞进 isolated: HashMap<&str, Arc<dyn IsolatedProvider>> 表(FileBlobRuntime 有隔离能力时自动获得 IsolatedProvider blanket impl)——隔离分发run.rs 内的 materialize/absorb/env_vars/native_cli 查表逻辑)因此不用改。但 run.rsnormalize_provider 仍需加一行别名匹配(把用户输入的 provider 名解析成规范 id,纯文本解析, 查表机制吸收不了);login.rs 必须新增一个该 provider 专属的 match 分支——登录流程从未做成 通用查表(Codex 走 codex login 子进程、Claude 走 claude auth login --claudeai、Kimi 是纯导入 已登录凭证,语义各不相同),每个新 provider 都要写自己的登录分支。历史数据兼容用两个可选 hook: store_field()(凭证仓库里存 blob 的字段名,默认 "blob")与 dedup_extra_key()registry.toml extra 里去重键的字段名,默认 "dedup_key")——仅当迁移一个已有存量账号数据、且旧字段名与默认值 不同的 provider(如 Codex 分别覆盖成 "auth_json"/"chatgpt_account_id")时才需要覆盖,全新 provider(如 Kimi)用默认值即可。Claude 因 macOS 钥匙串 + API 账号特殊逻辑,不在此引擎上,run.rs 保留其专用分支。
  • AutoSwap 默认阈值只改 crates/core/src/defaults.rs::AUTO_SWAP_THRESHOLD,并同步 docs/design/AUTO_SWAP_DESIGN.md
  • async fn 内不得直接做阻塞 IO;文件锁、std::fs、keyring 等必须包进 tokio::task::spawn_blocking
  • 写入 registry.tomlOption<T> 字段必须加 #[serde(skip_serializing_if = "Option::is_none")],避免 TOML null 报错。
  • CLI 子命令、Rust 标识符、英文文案统一用 swap,不要用 switch
  • swap / rm 的数字编号必须与默认入口显示顺序一致,统一走 AppContext::list_ordered()
  • 跨模块调优参数走 crates/core/src/settings.rs::current(),不要在 provider / cli 里硬编码阈值、窗口、百分比。
  • 不得用高频 quota / usage 请求模拟限流触发;必须保守退避,避免请求风暴和风控风险。 Anthropic usage 端点限流极严(~每账号每分钟 1 次),禁止手动 curl 连发去"复现"——会打爆桶、 污染判断。查询前先走缓存节流:缓存比 settings.quota.min_refresh_interval_ms(默认 90s) 新就复用、 不打端点;daemon 与 CLI 共用 quota_cache.json,两条路径都要尊重。429 ≠ token 失效,三种「查不出」 的区分与处理见 docs/PROVIDER_KNOWLEDGE_BASE.md 的「Usage 接口异常状态码」; 根因与修复历史见 docs/troubleshooting/TROUBLESHOOTING_INDEX.md

Read the full file on GitHub · 181 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 181 lines · 4,675 tokens per session scan A 876011e5ed50

Subscribe to this mod's changes

subswap AGENTS.md is an instructions file published in the GitHub repository x0c/subswap (2 stars, last pushed 2d ago), licensed MIT. It adds 4,675 tokens to every session, about $0.0234 per session on Opus 5. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.