cc-api-statusline 0.2.1 β†’ 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # cc-api-statusline
2
2
 
3
- > Claude Code statusline widget for monitoring API usage from third-party proxy backends
4
-
5
3
  A high-performance TUI statusline tool that polls API usage data from Claude API proxy services (sub2api, claude-relay-service, or custom providers) and renders a configurable one-line status display.
6
4
 
7
5
  ## Features
@@ -12,47 +10,46 @@ A high-performance TUI statusline tool that polls API usage data from Claude API
12
10
  - πŸ’Ύ **Smart caching** β€” Disk cache with atomic writes, TTL validation, automatic garbage collection
13
11
  - 🎯 **Claude Code integration** β€” Auto-setup with `--install` command
14
12
  - πŸ“Š **Multiple components** β€” Daily/weekly/monthly quotas, balance, tokens, rate limits
15
- - πŸ› **Debug logging** β€” Detailed execution logs for troubleshooting
13
+ - πŸ” **Hot switching** β€” Auto-detects API endpoint and credential changes at runtime
16
14
  - πŸ”’ **Reliability** β€” No stale data display, race-condition-free writes, auto cache cleanup
17
15
 
18
- ## Installation
16
+ ## Quick Start
19
17
 
20
- ```bash
21
- # Using npm
22
- npm install -g cc-api-statusline
18
+ ### 1. Set up your API endpoint
23
19
 
24
- # Using bun
25
- bun add -g cc-api-statusline
20
+ You need `ANTHROPIC_BASE_URL` (your proxy URL) and `ANTHROPIC_AUTH_TOKEN` (your API key).
26
21
 
27
- # From source
28
- git clone https://github.com/liafonx/cc-api-statusline
29
- cd cc-api-statusline
30
- bun install
31
- bun run build
32
- ```
22
+ **Recommended: via `~/.claude/settings.json` env overlay** (automatically passed to the widget):
33
23
 
34
- ## Quick Start
35
-
36
- ### Claude Code Integration (Recommended)
24
+ ```json
25
+ {
26
+ "env": {
27
+ "ANTHROPIC_BASE_URL": "https://your-proxy.example.com",
28
+ "ANTHROPIC_AUTH_TOKEN": "your-api-token"
29
+ }
30
+ }
31
+ ```
37
32
 
38
- The easiest way to use cc-api-statusline is with auto-setup:
33
+ Or export them in your shell:
39
34
 
40
35
  ```bash
41
- # Set required environment variables first
42
36
  export ANTHROPIC_BASE_URL="https://your-proxy.example.com"
43
37
  export ANTHROPIC_AUTH_TOKEN="your-api-token"
38
+ ```
44
39
 
45
- # Install as Claude Code statusline widget
46
- npx cc-api-statusline --install
40
+ ### 2. Preview
41
+
42
+ ```bash
43
+ bunx cc-api-statusline@latest --once
44
+ ```
47
45
 
48
- # Or with bunx (auto-detects if available)
49
- bunx cc-api-statusline --install --runner bunx
46
+ ### 3. Install as Claude Code widget (optional)
50
47
 
51
- # Uninstall
52
- npx cc-api-statusline --uninstall
48
+ ```bash
49
+ bunx cc-api-statusline@latest --install
53
50
  ```
54
51
 
55
- This automatically adds to `~/.claude/settings.json`:
52
+ This adds to `~/.claude/settings.json`:
56
53
 
57
54
  ```json
58
55
  {
@@ -64,89 +61,37 @@ This automatically adds to `~/.claude/settings.json`:
64
61
  }
65
62
  ```
66
63
 
67
- ### Standalone Mode
64
+ Using `bunx` ensures you always run the latest version without a global install. To uninstall:
68
65
 
69
66
  ```bash
70
- # Set required environment variables
71
- export ANTHROPIC_BASE_URL="https://your-proxy.example.com"
72
- export ANTHROPIC_AUTH_TOKEN="your-api-token"
73
-
74
- # Run once and exit
75
- cc-api-statusline --once
76
-
77
- # Run with custom config
78
- cc-api-statusline --config ./my-config.json
67
+ bunx cc-api-statusline --uninstall
79
68
  ```
80
69
 
81
- ### ccstatusline Custom Command (Legacy)
82
-
83
- Add to your `~/.claude/ccstatusline/config.json`:
84
-
85
- ```json
86
- {
87
- "customCommands": {
88
- "usage": {
89
- "command": "cc-api-statusline",
90
- "description": "API usage statusline",
91
- "type": "piped"
92
- }
93
- },
94
- "widgets": [
95
- {
96
- "type": "customCommand",
97
- "command": "usage",
98
- "refreshIntervalMs": 30000,
99
- "maxWidth": 80,
100
- "preserveColors": true
101
- }
102
- ]
103
- }
104
- ```
105
-
106
- ## Configuration
107
-
108
- Configuration file: `~/.claude/cc-api-statusline/config.json`
109
-
110
- ### User-Agent Spoofing (Optional)
70
+ Optional global install:
111
71
 
112
- Some API providers restrict requests to only come from Claude Code clients. Enable User-Agent spoofing to bypass these restrictions:
113
-
114
- ```json
115
- {
116
- "spoofClaudeCodeUA": true
117
- }
72
+ ```bash
73
+ bun add -g cc-api-statusline
74
+ # or
75
+ npm install -g cc-api-statusline
118
76
  ```
119
77
 
120
- **Options:**
121
- - `false` / `undefined` β€” No User-Agent header (default)
122
- - `true` β€” Auto-detect Claude Code version, fallback to `claude-cli/2.1.56 (external, cli)`
123
- - `"string"` β€” Use custom User-Agent string
78
+ ## Hot Switching
124
79
 
125
- **Per-provider override (custom providers only):**
80
+ cc-api-statusline automatically detects when `ANTHROPIC_BASE_URL` or `ANTHROPIC_AUTH_TOKEN` changes (e.g. when you switch Claude Code profiles or rotate tokens). On detection it shows a brief transition indicator (`⟳ Switching provider...`) and refreshes from the new endpoint β€” no restart required.
126
81
 
127
- ```json
128
- {
129
- "spoofClaudeCodeUA": true,
130
- "customProviders": {
131
- "my-provider": {
132
- "spoofClaudeCodeUA": "custom-client/1.0.0"
133
- }
134
- }
135
- }
136
- ```
82
+ ## Configuration
137
83
 
138
- ### Example Configuration
84
+ ### Style Config (`~/.claude/cc-api-statusline/config.json`)
139
85
 
140
86
  ```json
141
87
  {
142
88
  "display": {
143
89
  "layout": "standard",
144
- "displayMode": "bar",
145
- "barSize": "medium",
146
- "barStyle": "classic",
147
- "separator": " | ",
148
- "maxWidth": 80,
149
- "clockFormat": "24h"
90
+ "displayMode": "text",
91
+ "progressStyle": "icon",
92
+ "barStyle": "block",
93
+ "divider": { "text": "|", "margin": 1, "color": "#555753" },
94
+ "maxWidth": 100
150
95
  },
151
96
  "components": {
152
97
  "daily": true,
@@ -154,313 +99,102 @@ Some API providers restrict requests to only come from Claude Code clients. Enab
154
99
  "monthly": true,
155
100
  "balance": true,
156
101
  "tokens": false,
157
- "rateLimit": false,
158
- "plan": false
159
- },
160
- "colors": {
161
- "auto": {
162
- "low": "green",
163
- "medium": "yellow",
164
- "high": "red",
165
- "lowThreshold": 50,
166
- "highThreshold": 80
167
- }
168
- },
169
- "pollIntervalSeconds": 30,
170
- "pipedRequestTimeoutMs": 800
102
+ "rateLimit": false
103
+ }
171
104
  }
172
105
  ```
173
106
 
174
- ### Display Options
175
-
176
- #### Layouts
177
-
178
- - `standard` β€” Full labels (e.g., "Daily 24%")
179
- - `compact` β€” Single-letter labels (e.g., "D 24%")
180
- - `minimal` β€” No labels (e.g., "24%")
181
- - `percent-first` β€” Percentage before bar (e.g., "Daily 24% ━━──")
182
-
183
- #### Display Modes
184
-
185
- - `bar` β€” Progress bar visualization
186
- - `percentage` β€” Percentage only (no bar)
187
- - `icon-pct` β€” Nerd-font icon + percentage
107
+ Key options:
188
108
 
189
- #### Bar Styles
109
+ | Key | Values | Default | Description |
110
+ |-----|--------|---------|-------------|
111
+ | `layout` | `standard` / `percent-first` | `standard` | Assembly order of label, bar, value |
112
+ | `displayMode` | `text` / `compact` / `emoji` / `nerd` / `hidden` | `text` | Label style. `nerd` requires a [Nerd Font](https://www.nerdfonts.com/font-downloads). |
113
+ | `progressStyle` | `bar` / `icon` / `hidden` | `icon` | Usage fraction visualization. `icon` requires a [Nerd Font](https://www.nerdfonts.com/font-downloads). |
114
+ | `barStyle` | `block` / `classic` / `dot` / `shade` / `pipe` / `braille` / `square` / `star` | `block` | Bar character style |
115
+ | `barSize` | `small` / `small-medium` / `medium` / `medium-large` / `large` | `medium` | Bar width (4–12 chars) |
116
+ | `divider` | `DividerConfig` or `false` | `{ text: "\|", margin: 1, color: "#555753" }` | Separator between components; `false` disables |
117
+ | `maxWidth` | 20–100 | `100` | Max % of terminal width |
190
118
 
191
- - `classic` β€” `━━━━────` (default)
192
- - `block` β€” `β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘`
193
- - `shade` β€” `β–“β–“β–“β–“β–‘β–‘β–‘β–‘`
194
- - `pipe` β€” `||||Β·Β·Β·Β·`
195
- - `dot` β€” `●●●●○○○○`
196
- - `braille` β€” `β£Ώβ£Ώβ£Ώβ£Ώβ €β €β €β €` (smooth gradients)
197
- - `square` β€” `β– β– β– β– β–‘β–‘β–‘β–‘`
198
- - `star` β€” `β˜…β˜…β˜…β˜…β˜†β˜†β˜†β˜†`
199
- - Custom β€” `{"fill": "β–°", "empty": "β–±"}`
119
+ For the full style reference including per-component overrides, color aliases, and countdown config see [docs/spec-tui-style.md](docs/spec-tui-style.md).
200
120
 
201
- #### Bar Sizes
121
+ #### User-Agent Spoofing
202
122
 
203
- - `small` β€” 4 chars
204
- - `small-medium` β€” 6 chars
205
- - `medium` β€” 8 chars (default)
206
- - `medium-large` β€” 10 chars
207
- - `large` β€” 12 chars
208
-
209
- ### Per-Component Configuration
210
-
211
- Override global settings per component:
123
+ Some providers restrict requests to Claude Code clients. Enable to bypass:
212
124
 
213
125
  ```json
214
126
  {
215
- "components": {
216
- "daily": {
217
- "barStyle": "dot",
218
- "color": "chill",
219
- "countdown": {
220
- "format": "duration",
221
- "divider": " Β· ",
222
- "prefix": "⏱ "
223
- }
224
- },
225
- "weekly": {
226
- "layout": "compact",
227
- "displayMode": "icon-pct"
228
- },
229
- "balance": {
230
- "label": "Credits"
231
- }
232
- }
127
+ "spoofClaudeCodeUA": true
233
128
  }
234
129
  ```
235
130
 
236
- **Note:** Countdown divider defaults to ` Β· ` (space-dot-space) for clean spacing.
237
-
238
- ### Color Configuration
239
-
240
- #### Named Colors
131
+ - `false` / `undefined` β€” No User-Agent header (default)
132
+ - `true` β€” Auto-detect Claude Code version, fallback to `claude-cli/2.1.56 (external, cli)`
133
+ - `"string"` β€” Use a custom User-Agent string
241
134
 
242
- `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `dim`, `bright-red`, `bright-green`, etc.
135
+ ### API Config (`~/.claude/cc-api-statusline/api-config/`)
243
136
 
244
- #### Hex Colors
137
+ Define custom providers as JSON files in this directory. After adding or modifying provider files, run:
245
138
 
246
- ```json
247
- {
248
- "components": {
249
- "daily": {
250
- "color": "#00ff00"
251
- }
252
- }
253
- }
139
+ ```bash
140
+ cc-api-statusline --apply-config
254
141
  ```
255
142
 
256
- #### Dynamic Color Aliases
143
+ See [docs/api-config-reference.md](docs/api-config-reference.md) for the full schema.
257
144
 
258
- ```json
259
- {
260
- "colors": {
261
- "auto": {
262
- "low": "green",
263
- "medium": "yellow",
264
- "high": "red",
265
- "lowThreshold": 50,
266
- "highThreshold": 80
267
- },
268
- "chill": {
269
- "low": "cyan",
270
- "medium": "blue",
271
- "high": "magenta",
272
- "lowThreshold": 60,
273
- "highThreshold": 90
274
- }
275
- }
276
- }
277
- ```
145
+ ## [ccstatusline](https://github.com/anthropics/claude-code) Custom Command
278
146
 
279
- #### Per-Part Coloring
147
+ Add to `~/.claude/ccstatusline/config.json`:
280
148
 
281
149
  ```json
282
150
  {
283
- "components": {
284
- "daily": {
285
- "colors": {
286
- "label": "#8a8a8a",
287
- "bar": "auto",
288
- "value": "white",
289
- "countdown": "#666666"
290
- }
151
+ "customCommands": {
152
+ "usage": {
153
+ "command": "cc-api-statusline",
154
+ "description": "API usage statusline",
155
+ "type": "piped"
291
156
  }
292
- }
157
+ },
158
+ "widgets": [
159
+ {
160
+ "type": "customCommand",
161
+ "command": "usage",
162
+ "refreshIntervalMs": 30000,
163
+ "maxWidth": 100,
164
+ "preserveColors": true
165
+ }
166
+ ]
293
167
  }
294
168
  ```
295
169
 
296
170
  ## Environment Variables
297
171
 
298
- | Variable | Required | Description |
172
+ All variables are optional at the shell level β€” `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN` can be set via `settings.json` env overlay instead of shell exports (see [Quick Start](#quick-start)).
173
+
174
+ | Variable | Optional | Description |
299
175
  |----------|----------|-------------|
300
176
  | `ANTHROPIC_BASE_URL` | Yes | API endpoint (e.g., `https://api.sub2api.com`) |
301
177
  | `ANTHROPIC_AUTH_TOKEN` | Yes | API key or token |
302
- | `CC_STATUSLINE_PROVIDER` | No | Override provider detection (`sub2api`, `claude-relay-service`, or custom) |
303
- | `CC_STATUSLINE_POLL` | No | Override poll interval (seconds, min 5) |
304
- | `CC_STATUSLINE_TIMEOUT` | No | Piped mode timeout (milliseconds, default 1000) |
305
- | `DEBUG` or `CC_STATUSLINE_DEBUG` | No | Enable debug logging to `~/.claude/cc-api-statusline/debug.log` |
306
-
307
- ## Provider Setup
308
-
309
- ### sub2api
310
-
311
- ```bash
312
- export ANTHROPIC_BASE_URL="https://api.sub2api.com"
313
- export ANTHROPIC_AUTH_TOKEN="sk-sub2api-..."
314
- ```
315
-
316
- ### claude-relay-service
317
-
318
- ```bash
319
- export ANTHROPIC_BASE_URL="https://relay.example.com"
320
- export ANTHROPIC_AUTH_TOKEN="your-relay-token"
321
- ```
322
-
323
- ### Custom Providers
324
-
325
- Define custom providers in config.json:
326
-
327
- ```json
328
- {
329
- "customProviders": {
330
- "my-provider": {
331
- "urlPatterns": ["my-proxy.example.com"],
332
- "endpoint": "/api/usage",
333
- "method": "GET",
334
- "authMode": "bearer",
335
- "responseMapping": {
336
- "billingMode": "$.mode",
337
- "daily.used": "$.usage.daily",
338
- "daily.limit": "$.limits.daily"
339
- }
340
- }
341
- }
342
- }
343
- ```
344
-
345
- ## CLI Usage
346
-
347
- ```bash
348
- # Show help
349
- cc-api-statusline --help
350
-
351
- # Show version
352
- cc-api-statusline --version
353
-
354
- # Fetch once and exit
355
- cc-api-statusline --once
356
-
357
- # Use custom config file
358
- cc-api-statusline --config /path/to/config.json
359
-
360
- # Install as Claude Code statusline widget
361
- cc-api-statusline --install
362
- cc-api-statusline --install --runner bunx
363
- cc-api-statusline --install --force # Overwrite existing
364
-
365
- # Uninstall from Claude Code
366
- cc-api-statusline --uninstall
367
- ```
368
-
369
- ## Debug Logging
370
-
371
- Enable detailed execution logs for troubleshooting:
372
-
373
- ```bash
374
- # Enable debug logging
375
- DEBUG=1 cc-api-statusline --once
376
-
377
- # For Claude Code widget, add to settings.json:
378
- {
379
- "statusLine": {
380
- "type": "command",
381
- "command": "DEBUG=1 bunx -y cc-api-statusline@latest",
382
- "padding": 0
383
- }
384
- }
385
-
386
- # View logs in real-time
387
- tail -f ~/.claude/cc-api-statusline/debug.log
388
-
389
- # View recent logs
390
- tail -20 ~/.claude/cc-api-statusline/debug.log
391
-
392
- # Search for errors
393
- grep "ERROR" ~/.claude/cc-api-statusline/debug.log
394
- ```
395
-
396
- Debug logs include:
397
- - Execution start/finish timestamps
398
- - Mode detection (piped vs TTY)
399
- - Environment variables (sanitized)
400
- - Config and cache status
401
- - Execution paths taken (A/B/C/D)
402
- - Fetch timing and performance metrics
403
- - Cache operations
404
- - Error details with fallback behavior
405
-
406
- ## Performance
407
-
408
- Piped mode performance targets (1000ms timeout):
409
-
410
- - **Path A (warm cache)**: ≀25ms (p95 ≀100ms)
411
- - **Path B (re-render)**: ≀55ms (p95 ≀100ms)
412
- - **Path C (fetch)**: ≀840ms worst case
413
- - **Path D (fallback)**: ≀25ms
414
-
415
- Cache validation:
416
- - TTL check
417
- - Provider match
418
- - Base URL match
419
- - Version match
420
- - Token hash match
421
-
422
- Cache garbage collection:
423
- - Automatic cleanup after successful cache writes
424
- - Deletes cache files older than 7 days
425
- - Maintains maximum of 20 cache files (deletes oldest)
426
- - Removes orphaned temporary files older than 1 hour
427
- - Best-effort operation (never blocks or throws)
428
-
429
- Exit code behavior:
430
- - Returns `0` for all error states (stale data is never shown, only error messages)
431
- - Ensures clean widget display without `[Exit: 1]` indicators
178
+ | `CC_STATUSLINE_PROVIDER` | Yes | Override provider detection (`sub2api`, `claude-relay-service`, or custom) |
179
+ | `CC_STATUSLINE_POLL` | Yes | Override poll interval (seconds, min 5) |
180
+ | `CC_STATUSLINE_TIMEOUT` | Yes | Piped mode timeout (milliseconds, default 1000) |
181
+ | `DEBUG` or `CC_STATUSLINE_DEBUG` | Yes | Enable debug logging to `~/.claude/cc-api-statusline/debug.log` |
432
182
 
433
183
  ## Troubleshooting
434
184
 
435
185
  ### "Missing required environment variable"
436
186
 
437
- Set `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN`:
438
-
439
- ```bash
440
- export ANTHROPIC_BASE_URL="https://your-proxy.example.com"
441
- export ANTHROPIC_AUTH_TOKEN="your-token"
442
- ```
443
-
444
- Or add to `~/.claude/settings.json`:
445
-
446
- ```json
447
- {
448
- "env": {
449
- "ANTHROPIC_BASE_URL": "https://your-proxy.example.com",
450
- "ANTHROPIC_AUTH_TOKEN": "your-token"
451
- }
452
- }
453
- ```
187
+ Set `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN` via shell exports or the `settings.json` env overlay (see [Quick Start](#quick-start)).
454
188
 
455
189
  ### "Unknown provider"
456
190
 
457
- Provider autodetection failed. Explicitly set provider:
191
+ Provider autodetection failed. Explicitly set the provider:
458
192
 
459
193
  ```bash
460
194
  export CC_STATUSLINE_PROVIDER="sub2api"
461
195
  ```
462
196
 
463
- Or define a custom provider in config.json.
197
+ Or define a custom provider in `api-config/`.
464
198
 
465
199
  ### "[offline]" or "[stale]" indicator
466
200
 
@@ -478,15 +212,18 @@ Check:
478
212
 
479
213
  ### Slow performance in piped mode
480
214
 
481
- Check cache validity:
482
- - Run `cc-api-statusline --once` standalone to warm cache
483
- - Verify `~/.claude/cc-api-statusline/cache-*.json` exists
484
- - Check `pipedRequestTimeoutMs` config (default 800ms)
485
- - Enable debug logging to see fetch timing
215
+ ```bash
216
+ # Warm the cache standalone
217
+ cc-api-statusline --once
218
+ # Check debug timing
219
+ DEBUG=1 cc-api-statusline --once
220
+ ```
221
+
222
+ Verify `pipedRequestTimeoutMs` in config (default 800ms) and check `~/.claude/cc-api-statusline/cache-*.json` exists.
486
223
 
487
224
  ### Widget shows `[Exit: 1]` in Claude Code
488
225
 
489
- This indicates the statusline command failed. Enable debug logging:
226
+ Enable debug logging in `~/.claude/settings.json`:
490
227
 
491
228
  ```json
492
229
  {
@@ -502,82 +239,44 @@ Then check logs: `tail -f ~/.claude/cc-api-statusline/debug.log`
502
239
 
503
240
  ## Development
504
241
 
505
- ```bash
506
- # Install dependencies
507
- bun install
242
+ | Command | Description |
243
+ |---------|-------------|
244
+ | `bun install` | Install dependencies |
245
+ | `bun run start` | Quick dev fetch (--once mode) |
246
+ | `bun run example` | Simulate piped mode |
247
+ | `bun run test` | Run tests |
248
+ | `bun run lint` | Lint |
249
+ | `bun run build` | Build |
250
+ | `bun run check` | Run all checks |
508
251
 
509
- # Quick dev fetch (--once mode)
510
- bun run start
252
+ ### Debug Logging
511
253
 
512
- # Simulate piped mode
513
- bun run example
254
+ Enable detailed execution logs for troubleshooting:
514
255
 
515
- # Run tests
516
- bun run test
256
+ ```bash
257
+ # Enable debug logging
258
+ DEBUG=1 cc-api-statusline --once
517
259
 
518
- # Lint
519
- bun run lint
260
+ # For Claude Code widget, add to settings.json:
261
+ # "command": "DEBUG=1 bunx -y cc-api-statusline@latest"
520
262
 
521
- # Build
522
- bun run build
263
+ # View logs in real-time
264
+ tail -f ~/.claude/cc-api-statusline/debug.log
523
265
 
524
- # Run all checks
525
- bun run check
266
+ # Search for errors
267
+ grep "ERROR" ~/.claude/cc-api-statusline/debug.log
526
268
  ```
527
269
 
528
- ## Architecture
270
+ Debug logs include execution timestamps, mode detection, config/cache status, execution paths (A/B/C/D), fetch timing, and error details.
529
271
 
530
- ```
531
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
532
- β”‚ main.ts β”‚ ← Thin router: parse args β†’ dispatch
533
- β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
534
- β”‚
535
- β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
536
- β”‚ src/cli/ β”‚ ← Argument parsing, install/uninstall, piped-mode
537
- β”‚ - args.ts β”‚
538
- β”‚ - commands.tsβ”‚
539
- β”‚ - piped-mode β”‚
540
- β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
541
- β”‚
542
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
543
- β”‚ β”‚
544
- β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
545
- β”‚ services/ β”‚ β”‚ providers/ β”‚
546
- β”‚ - env β”‚ β”‚ - sub2api β”‚
547
- β”‚ - cache β”‚ β”‚ - relay β”‚
548
- β”‚ - config β”‚ β”‚ - custom β”‚
549
- β”‚ - settings β”‚ ← settings.json β”‚ - autodetect β”‚
550
- β”‚ - logger β”‚ ← debug logging β”‚ - quota-window β”‚
551
- β”‚ - atomic-write│← atomic writes β”‚ - custom-mappingβ”‚
552
- β”‚ - cache-gc β”‚ ← auto cleanup β”‚ β”‚
553
- β”‚ - ensure-dir │← dir creation β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
554
- β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
555
- β”‚ β”‚
556
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
557
- β”‚
558
- β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
559
- β”‚ src/core/ β”‚
560
- β”‚ execute-cycle β”‚ ← Unified execution (Path A/B/C/D)
561
- β”‚ constants.ts β”‚ ← Shared constants
562
- β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
563
- β”‚
564
- β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
565
- β”‚ renderer/ β”‚
566
- β”‚ - component β”‚ ← Per-component rendering (RenderContext)
567
- β”‚ - bar β”‚ ← Progress bars
568
- β”‚ - colors β”‚ ← ANSI color system
569
- β”‚ - countdown β”‚ ← Time-to-reset
570
- β”‚ - error β”‚ ← Error states
571
- β”‚ - transition β”‚ ← Transition state detection
572
- β”‚ - icons β”‚ ← Nerd-font glyphs
573
- β”‚ - truncate β”‚ ← Terminal width
574
- β”‚ - index β”‚ ← Main pipeline
575
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
576
- ```
272
+ Log files are automatically rotated (1-in-20 invocations):
273
+ - `debug.log` β‰₯ 500 KB β†’ archived as `debug.YYYY-MM-DDTHH-MM.log`
274
+ - Archives older than 24h β†’ compressed with gzip
275
+ - Compressed archives older than 3 days β†’ deleted
577
276
 
578
277
  ## Testing
579
278
 
580
- - **578 tests** across **34 test files**
279
+ - **691 tests** across **39 test files**
581
280
  - Unit tests for all services, renderers, and shared utilities
582
281
  - Core execution path tests (A/B/C/D)
583
282
  - E2E smoke tests with isolated environments
@@ -598,4 +297,3 @@ MIT
598
297
  - [TUI Style Spec](docs/spec-tui-style.md)
599
298
  - [API Polling Spec](docs/spec-api-polling.md)
600
299
  - [Custom Providers Spec](docs/spec-custom-providers.md)
601
- - [AGENTS.md](AGENTS.md) - Development handoff guide