# Claude Code v2.1.81 Compatibility Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add native `rate_limits` JSON support (v2.1.80+), `worktree.branch` field, and update docs/version for full v2.1.81 compatibility.

**Architecture:** The `usage_limits` component currently fetches rate limit data via OAuth API (with caching, retry, backoff). CC v2.1.80 now sends this data natively in the JSON input as `rate_limits.five_hour/seven_day`. We add native JSON as the primary source (zero-latency, no network), keeping OAuth as fallback for older CC versions. The `resets_at` field changes from ISO 8601 (OAuth) to Unix epoch (native JSON) — time formatters must handle both.

**Tech Stack:** Bash 4+, jq, BATS testing framework

---

### Task 1: Add epoch timestamp support to reset time formatters

**Files:**
- Modify: `lib/components/usage_limits.sh:35-99` (format_reset_time)
- Modify: `lib/components/usage_limits.sh:101-133` (get_reset_clock_time)
- Modify: `lib/components/usage_limits.sh:136-187` (format_reset_time_long)
- Modify: `lib/components/usage_limits.sh:189-224` (get_remaining_minutes)
- Test: `tests/unit/test_usage_limits_native.bats` (new)

The v2.1.80 `rate_limits.*.resets_at` is Unix epoch seconds (integer), not ISO 8601. All four time formatting functions currently only parse ISO. Add epoch detection at the top of each function.

- [ ] **Step 1: Write failing tests for epoch timestamp handling**

```bash
# tests/unit/test_usage_limits_native.bats
# Test that format_reset_time handles Unix epoch timestamps
# Test that get_reset_clock_time handles Unix epoch timestamps
# Test that format_reset_time_long handles Unix epoch timestamps
# Test that get_remaining_minutes handles Unix epoch timestamps
```

- [ ] **Step 2: Run tests to verify they fail**

Run: `bats tests/unit/test_usage_limits_native.bats`
Expected: FAIL — epoch timestamps not handled

- [ ] **Step 3: Add epoch detection to all four time functions**

Pattern for each function — add before ISO parsing:
```bash
# Detect epoch timestamp (pure digits = Unix epoch seconds from CC v2.1.80+)
if [[ "$iso_timestamp" =~ ^[0-9]+$ ]]; then
    reset_epoch="$iso_timestamp"
else
    # existing ISO parsing...
fi
```

Apply to: `format_reset_time`, `get_reset_clock_time`, `format_reset_time_long`, `get_remaining_minutes`

- [ ] **Step 4: Run tests to verify they pass**

Run: `bats tests/unit/test_usage_limits_native.bats`
Expected: PASS

- [ ] **Step 5: Commit**

```bash
git add lib/components/usage_limits.sh tests/unit/test_usage_limits_native.bats
git commit -m "feat: add epoch timestamp support to usage limit time formatters (CC v2.1.80+)"
```

---

### Task 2: Add native `rate_limits` JSON reading to `collect_usage_limits_data()`

**Files:**
- Modify: `lib/components/usage_limits.sh:473-533` (collect_usage_limits_data)
- Test: `tests/unit/test_usage_limits_native.bats` (append)

The current Priority 1 checks `.five_hour.utilization` (OAuth format at root level). Replace with check for `.rate_limits.five_hour.used_percentage` (CC v2.1.80 native format). Keep OAuth as Priority 2 fallback.

- [ ] **Step 1: Write failing tests for native rate_limits JSON**

```bash
# Test collect_usage_limits_data reads from rate_limits.five_hour.used_percentage
# Test collect_usage_limits_data reads from rate_limits.seven_day.used_percentage
# Test collect_usage_limits_data reads epoch resets_at from rate_limits
# Test collect_usage_limits_data falls back to OAuth when rate_limits absent
```

- [ ] **Step 2: Run tests to verify they fail**

Run: `bats tests/unit/test_usage_limits_native.bats`
Expected: FAIL — rate_limits path not checked

- [ ] **Step 3: Rewrite Priority 1 block in collect_usage_limits_data()**

Replace lines 483-491 with:
```bash
# Priority 1: Native rate_limits from CC v2.1.80+ (zero-latency, no network)
if [[ -n "${STATUSLINE_INPUT_JSON:-}" ]]; then
    local rl_five_pct rl_seven_pct
    rl_five_pct=$(echo "$STATUSLINE_INPUT_JSON" | jq -r '.rate_limits.five_hour.used_percentage // empty' 2>/dev/null)
    rl_seven_pct=$(echo "$STATUSLINE_INPUT_JSON" | jq -r '.rate_limits.seven_day.used_percentage // empty' 2>/dev/null)
    if [[ -n "$rl_five_pct" || -n "$rl_seven_pct" ]]; then
        # Build OAuth-compatible structure for downstream extraction
        usage_data=$(echo "$STATUSLINE_INPUT_JSON" | jq '{
            five_hour: {
                utilization: .rate_limits.five_hour.used_percentage,
                resets_at: (if .rate_limits.five_hour.resets_at then (.rate_limits.five_hour.resets_at | tostring) else null end)
            },
            seven_day: {
                utilization: .rate_limits.seven_day.used_percentage,
                resets_at: (if .rate_limits.seven_day.resets_at then (.rate_limits.seven_day.resets_at | tostring) else null end)
            }
        }' 2>/dev/null)
        debug_log "Using native rate_limits from CC v2.1.80+ JSON" "INFO"
    fi
fi
```

This normalizes the native format to match the OAuth format so downstream extraction (lines 502-508) works unchanged. The `resets_at` stays as epoch string — Task 1's epoch support handles it.

- [ ] **Step 4: Run tests to verify they pass**

Run: `bats tests/unit/test_usage_limits_native.bats`
Expected: PASS

- [ ] **Step 5: Commit**

```bash
git add lib/components/usage_limits.sh tests/unit/test_usage_limits_native.bats
git commit -m "feat: read native rate_limits from CC v2.1.80+ JSON input"
```

---

### Task 3: Update `api_live.sh` to check `rate_limits.*.resets_at`

**Files:**
- Modify: `lib/cost/api_live.sh:126-132` (get_api_window_start native fallback)
- Modify: `lib/cost/api_live.sh:424-430` (get_native_reset_info native fallback)
- Test: `tests/unit/test_usage_limits_native.bats` (append)

Two places in `api_live.sh` read `.five_hour.resets_at` from native JSON. Add `.rate_limits.five_hour.resets_at` as primary path, keep legacy as fallback.

- [ ] **Step 1: Write failing test for api_live resets_at native path**

Test that `get_api_window_start` reads `rate_limits.five_hour.resets_at` epoch from JSON.

- [ ] **Step 2: Update get_api_window_start (line ~128)**

Replace:
```bash
resets_at=$(echo "$STATUSLINE_INPUT_JSON" | jq -r '.five_hour.resets_at // empty' 2>/dev/null)
```
With:
```bash
resets_at=$(echo "$STATUSLINE_INPUT_JSON" | jq -r '.rate_limits.five_hour.resets_at // .five_hour.resets_at // empty' 2>/dev/null)
```

- [ ] **Step 3: Update get_native_reset_info (line ~426)**

Same pattern — add `.rate_limits.five_hour.resets_at` as primary path.

- [ ] **Step 4: Add epoch-to-epoch passthrough in ISO parser**

In `get_api_window_start`, the ISO→epoch parser must also handle epoch input (pure digits). Add:
```bash
if [[ "$resets_at" =~ ^[0-9]+$ ]]; then
    reset_epoch="$resets_at"
else
    # existing ISO parsing...
fi
```

- [ ] **Step 5: Run tests and verify**

Run: `bats tests/unit/test_usage_limits_native.bats`
Expected: PASS

- [ ] **Step 6: Commit**

```bash
git add lib/cost/api_live.sh tests/unit/test_usage_limits_native.bats
git commit -m "feat: read rate_limits.resets_at from CC v2.1.80+ JSON in api_live"
```

---

### Task 4: Add `worktree.branch` field support

**Files:**
- Modify: `lib/json_fields.sh:15-16` (docs comment)
- Modify: `lib/components/repo_info.sh:55-60` (worktree data collection)
- Test: `tests/unit/test_usage_limits_native.bats` (append — or separate test)

CC v2.1.80 adds `worktree.branch` alongside existing `worktree.name/path/original_cwd/original_branch`. Use it as a fallback branch source when in a worktree.

- [ ] **Step 1: Update json_fields.sh doc comment**

Add `worktree.branch` to the v2.1.69 additions comment.

- [ ] **Step 2: Read `worktree.branch` in repo_info collection**

In `collect_repo_info_data()`, after the existing worktree check, also store the JSON-provided branch:
```bash
# Use worktree.branch from JSON if available (CC v2.1.80+)
if [[ -n "$COMPONENT_REPO_INFO_WORKTREE" ]]; then
    local wt_branch
    wt_branch=$(get_json_field "worktree.branch" "")
    if [[ -n "$wt_branch" ]]; then
        COMPONENT_REPO_INFO_BRANCH="$wt_branch"
    fi
fi
```

- [ ] **Step 3: Run full test suite to verify no regression**

Run: `npm test`
Expected: 940+ tests pass

- [ ] **Step 4: Commit**

```bash
git add lib/json_fields.sh lib/components/repo_info.sh
git commit -m "feat: add worktree.branch field support (CC v2.1.80+)"
```

---

### Task 5: Update CLAUDE.md, version, and docs

**Files:**
- Modify: `CLAUDE.md` (version range, JSON schema, rate_limits docs)
- Modify: `version.txt` (2.21.5 → 2.21.6)

- [ ] **Step 1: Update CLAUDE.md**

1. Change `v2.1.6–v2.1.76` to `v2.1.6–v2.1.81` everywhere
2. Add `rate_limits` to JSON schema section
3. Add `worktree.branch` to worktree fields
4. Update manual test command version string
5. Add v2.1.77-v2.1.81 notes section

- [ ] **Step 2: Bump version.txt**

```
2.21.6
```

- [ ] **Step 3: Run full test suite**

Run: `npm test`
Expected: All tests pass

- [ ] **Step 4: Commit**

```bash
git add CLAUDE.md version.txt
git commit -m "chore: bump version to 2.21.6, update docs for CC v2.1.81 compat"
```

---

### Task 6: Update memory

- [ ] **Step 1: Update MEMORY.md with v2.1.81 compatibility notes**

Add rate_limits native JSON info, worktree.branch, and the key pattern that epoch timestamps are now supported in time formatters.

---

## Summary

| Task | Description | Files | Est. Tests |
|------|-------------|-------|-----------|
| 1 | Epoch timestamp support | usage_limits.sh | 4-6 |
| 2 | Native rate_limits reading | usage_limits.sh | 4-6 |
| 3 | api_live.sh rate_limits path | api_live.sh | 2-3 |
| 4 | worktree.branch support | repo_info.sh, json_fields.sh | 0 (regression) |
| 5 | CLAUDE.md + version bump | CLAUDE.md, version.txt | 0 (regression) |
| 6 | Memory update | MEMORY.md | 0 |
