Skip to content

Claude/amazing hawking l nqgk#2292

Open
Srimi1 wants to merge 6 commits into
ruvnet:mainfrom
Srimi1:claude/amazing-hawking-lNqgk
Open

Claude/amazing hawking l nqgk#2292
Srimi1 wants to merge 6 commits into
ruvnet:mainfrom
Srimi1:claude/amazing-hawking-lNqgk

Conversation

@Srimi1

@Srimi1 Srimi1 commented Jun 4, 2026

Copy link
Copy Markdown

No description provided.

claude added 6 commits June 4, 2026 08:23
Adds `ruflo usage` (also `claude-flow usage`) which surfaces Claude's
"Plan usage limits" in the terminal: current 5-hour session utilization
with time-to-reset, plus weekly all-models / Sonnet-only windows — the
same data Claude Code's `/usage` shows.

Auth reuses Claude Code's existing login (no separate sign-in): the OAuth
token is resolved from CLAUDE_CODE_OAUTH_TOKEN, the macOS Keychain
("Claude Code-credentials"), or ~/.claude/.credentials.json (honoring
CLAUDE_CONFIG_DIR). The token is never logged, printed, or cached.

Data comes from the undocumented GET /api/oauth/usage endpoint, which
rate-limits aggressively, so results are cached for ~180s under
.claude-flow/usage/cache.json and a 429/network failure falls back to the
last-good cached value flagged stale. Friendly messages cover the
not-logged-in and expired-token cases.

- src/usage/credentials.ts — OAuth token resolution (env/keychain/file)
- src/usage/client.ts       — fetch + cache + error mapping
- src/commands/usage.ts      — usageCommand + pure render helpers
- commands/index.ts          — register lazy loader + help category
- __tests__/usage.test.ts    — 16 unit tests (mocked fetch + creds)

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
Adds a "Plan usage limits" section to the generated statusline
(.claude/helpers/statusline.cjs) — current 5-hour session + weekly
windows rendered as colored bars with % used and time-to-reset,
appended after the AgentDB line:

  Current session [███████░░░░░░░░░░░░░] 33% used · resets in 1h 59m
  Weekly (all)    [████████░░░░░░░░░░░░] 41% used · resets in 3d 23h

  Updated just now

Data source (no token, no network — the statusline re-renders often):
  1. Claude Code's documented `rate_limits` stdin field (v2.1.80+):
     used_percentage + resets_at (epoch seconds) → footer "Updated just now"
  2. fallback to the cache written by `ruflo usage`
     (.claude-flow/usage/cache.json) → footer "Updated Xm ago (cached)"

Bars are color-coded (green <50%, yellow 50-75%, red >=75%) and the
Sonnet/Opus weekly windows render when present. The section is hidden
when no usage data is available, or via RUFLO_STATUSLINE_HIDE_USAGE
(mirrors the existing RUFLO_STATUSLINE_HIDE_COST toggle).

- src/init/statusline-generator.ts — usage readers + bar renderer + CONFIG toggle
- .claude/helpers/statusline.cjs    — regenerated artifact (drift guard byte-match)
- __tests__/statusline-usage-display.test.ts — 8 tests (live/cache/hidden/absent)

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
…count, test env

- client.ts: getUsage() now only falls back to cache for transient failures
  (network / rate_limited). Unauthenticated and other HTTP/parse errors rethrow
  so a revoked/expired token surfaces instead of showing stale usage. Matches
  the documented "fallback on network/429" contract.
- credentials.ts: omit the `-a` account filter in the macOS Keychain lookup when
  $USER/$LOGNAME are unset, so `security` still matches in sanitized envs
  (launchd, some CI shells) instead of querying `-a ""`.
- usage.test.ts: restore process.env by mutating keys (delete added + Object.assign
  snapshot) instead of replacing the object; add a test asserting 401 rethrows
  rather than serving stale cache.

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
… nits)

- client.ts / commands/usage.ts: add JSDoc to the remaining undocumented
  helpers, types, and the UsageError class to clear CodeRabbit's docstring
  coverage check (was 60.61%, threshold 80%).
- statusline-generator.ts: extract the seconds/ms heuristic (RESET_MS_THRESHOLD)
  and bar constants (USAGE_BAR_WIDTH, USAGE_PCT_HIGH/MED) from magic numbers,
  with a comment explaining the epoch heuristic. Behavior unchanged.
- regenerate .claude/helpers/statusline.cjs artifact (drift-guard byte-match).

The credentials.ts "empty account" nit was already handled in 6d73481 by
omitting the `-a` filter when the username is unavailable (keeps the keychain
lookup working) rather than early-returning null.

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
A project skill that runs a disciplined find → triage → fix → verify →
report loop:
- scripts/scan.sh: read-only diagnostics collector (tests, tsc, lint, smells)
- SKILL.md: severity rubric + rules (don't weaken tests, no scope creep,
  report env/pre-existing failures honestly)
- resources/templates/bug-report-template.md: structured report saved to docs/

Auto-triggers on "find and fix bugs", "clean up the failing build", or
"generate a bug report".

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
- usage.test.ts: add 4 tests driving usageCommand.action — not-logged-in and
  expired-token paths (exitCode 1), and the authenticated success + --json
  paths served from a fresh seeded cache (no network). Closes the wiring gap
  from the code review.
- bug-hunter/scripts/scan.sh: replace `ls *.py **/*.py` (relied on globstar,
  which is off by default so `**` only matched one level) with a `find`-based
  check so Python projects are detected reliably.

https://claude.ai/code/session_01U9qENP4GeE5Fx8LUzGKziC
Copilot AI review requested due to automatic review settings June 4, 2026 15:35
@Srimi1 Srimi1 requested a review from ruvnet as a code owner June 4, 2026 15:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new V3 CLI usage feature that reuses Claude Code authentication to fetch and cache subscription “plan usage limits”, and surfaces that data both in the terminal and the statusline (via stdin rate_limits or a local cache). Also introduces a “bug-hunter” diagnostic helper script + templates.

Changes:

  • Added OAuth token resolution that reuses Claude Code login (env/keychain/file) and expiry detection.
  • Added a usage client with caching + stale fallback behavior, and a new usage command that renders a usage panel or JSON.
  • Updated statusline generator / helper to render usage bars and added Vitest coverage.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
v3/@claude-flow/cli/src/usage/credentials.ts New Claude Code OAuth token resolution (env/keychain/file) + expiry helper
v3/@claude-flow/cli/src/usage/client.ts New usage fetcher with error mapping, caching, and stale fallback logic
v3/@claude-flow/cli/src/commands/usage.ts New usage CLI command and rendering helpers (panel/JSON)
v3/@claude-flow/cli/src/commands/index.ts Registers new usage command in loader + category list
v3/@claude-flow/cli/src/init/statusline-generator.ts Adds plan-usage bars display sourced from stdin rate_limits or local cache
v3/@claude-flow/cli/tests/usage.test.ts Tests for token resolution, usage client caching, and command rendering
v3/@claude-flow/cli/tests/statusline-usage-display.test.ts Tests statusline plan-usage rendering (stdin + cache + hide toggle)
.claude/helpers/statusline.cjs Mirrors statusline usage rendering logic in checked-in helper
.claude/skills/bug-hunter/scripts/scan.sh Adds read-only diagnostics collector script
.claude/skills/bug-hunter/resources/templates/bug-report-template.md Adds structured bug report template
.claude/skills/bug-hunter/SKILL.md Documents the “bug hunter” workflow and usage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +100 to +103
export function isTokenExpired(resolved: ResolvedToken, now: number = Date.now()): boolean {
if (!resolved.expiresAt) return false;
return resolved.expiresAt <= now;
}
// CI shells); otherwise `-a ""` fails to match the real stored account.
if (account) args.push('-a', account);
args.push('-w');
const out = execFileSync('security', args, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
* Resolve a Claude Code OAuth token, or null if the user is not logged in.
* Precedence: env override → macOS Keychain → credentials file.
*/
export async function resolveClaudeOAuthToken(): Promise<ResolvedToken | null> {
Comment on lines +375 to +380
// Unix timestamps in seconds are ~1.7e9; in milliseconds ~1.7e12. Values below
// this threshold are treated as seconds and scaled up to milliseconds.
const RESET_MS_THRESHOLD = 1e12;
const USAGE_BAR_WIDTH = 20; // characters per usage bar
const USAGE_PCT_HIGH = 75; // >= this => red
const USAGE_PCT_MED = 50; // >= this => yellow (else green)
Comment on lines +202 to +218
} catch (err) {
const e = err as UsageError;
if (asJson) {
output.printJson({ error: e.code ?? 'error', message: e.message });
return { success: false, exitCode: 1 };
}
output.writeln();
if (e.code === 'unauthenticated') {
output.printError('Claude rejected the stored token.', 'Re-authenticate in Claude Code (`claude`).');
} else if (e.code === 'rate_limited') {
output.printWarning('Claude usage endpoint is rate-limited and no cached data is available.');
output.writeln(output.dim('Wait a few minutes and try again.'));
} else {
output.printError('Could not retrieve usage data.', e.message);
}
return { success: false, exitCode: 1 };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants