feat: scratchpad tool + fix Claude auth token expiry warning

- Add cortex/tools/scratch.py with scratch_read/write/append/clear tools
- Register all four scratch tools in the orchestrator tool registry
- Create inara/SCRATCH.md as the backing file (never distilled/archived)
- Fix auth.py: expiresAt reflects short-lived access token (~8h) not the
  1-year refresh token — suppress expiry warning when refreshToken is present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-20 21:10:03 -04:00
parent 31a5ef0541
commit 1b32667872
4 changed files with 169 additions and 4 deletions

View File

@@ -27,15 +27,22 @@ def _claude_status() -> dict:
try:
data = json.loads(CLAUDE_CREDS.read_text())
oauth = data["claudeAiOauth"]
has_refresh = bool(oauth.get("refreshToken"))
expires_dt = datetime.fromtimestamp(oauth["expiresAt"] / 1000, tz=timezone.utc)
now = datetime.now(tz=timezone.utc)
hours_remaining = (expires_dt - now).total_seconds() / 3600
# If a refresh token is present the session is long-lived (~1 year).
# expiresAt only reflects the current access token window (~8 h) and
# rotates automatically — do not warn based on it when a refresh token exists.
warning = not has_refresh and hours_remaining < WARN_HOURS
expired = hours_remaining <= 0 and not has_refresh
return {
"ok": True,
"expires_at": expires_dt.isoformat(),
"hours_remaining": round(hours_remaining, 1),
"warning": hours_remaining < WARN_HOURS,
"expired": hours_remaining <= 0,
"has_refresh_token": has_refresh,
"access_token_expires_at": expires_dt.isoformat(),
"access_token_hours_remaining": round(hours_remaining, 1),
"warning": warning,
"expired": expired,
}
except Exception as e:
logger.warning("claude auth check failed: %s", e)