Adds one test file per source file plus a shared fetch mock helper:
- test/constants.test.ts: OAuth scope/client_id/PROVIDER_ID/MODEL_ID pins,
rules 1, 6, 8.
- test/headers.test.ts: seven fingerprint header keys, UA/X-Msh-Version
track KIMI_CLI_VERSION, ASCII-only values, device-id format and
stability across calls (rules 1, 2).
- test/oauth.test.ts: form-encoded bodies for device-start/refresh,
authorization_pending/expired_token/unknown-error branches, non-OK and
non-JSON error shapes.
- test/plugin.test.ts: chat.params provider+model gating, full effort
matrix (rule 4), prompt_cache_key gating (rule 5), camelCase effort
input, loader Authorization ownership (rule 3), refresh-on-expiry with
persistAuth, 401 single-retry no-loop, device-flow authorize wiring.
- test/_util/fetchMock.ts: zero-dep global-fetch swap returning canned
Responses with call capture.
Notes:
- Tests use the real ~/.kimi/device_id; getDeviceId is idempotent and the
file is shared with kimi-cli by design (AGENTS.md rule 2), so no HOME
redirect is needed. Attempted monkey-patching os.homedir instead is
fragile under Bun's eager import-binding resolution.
- pollDeviceToken tests use interval=1 because `device.interval || 5`
treats 0 as the default 5s and would push each iteration past the
default bun-test timeout.
Total: 35 tests, ~5s to run.