Commit Graph
677 Commits
Author SHA1 Message Date
Tam Nhu Tran 0a8adb22fc fix(cliproxy): harden composite variant routing and validation 2026-02-12 15:18:33 +07:00
Tam Nhu Tran e914fe9778 fix(cliproxy): fix thinking off regression and composite error handling
- P1: Thinking "off" now fully disables all tier thinking
  When thinkingValue === 'off' AND no per-tier config, return early
  Preserves behavior for "off" with per-tier config (skips main, processes tiers)
  Fixes regression where tier defaults were applied despite explicit off setting

- P2: Handle composite-create thrown errors in POST route
  Wrap createCompositeVariant() in try/catch
  Returns 400 instead of generic 500 when function throws (e.g., legacy mode)
2026-02-12 13:34:17 +07:00
Tam Nhu Tran 8e6b67bf99 fix(cliproxy): fix edit dialog empty model and composite guidance
- P2: Edit dialog no longer seeds empty model string
  Changed `variant.model || ''` to `variant.model ?? undefined`
  Added payload filtering to exclude undefined/empty values before API call
  Prevents unintended model overwrites when user only changes other fields

- P3: Composite --config guidance now uses variant name
  Added profileName to ExecutorConfig interface
  Error message now shows correct variant name instead of default tier provider
  e.g., "ccs cliproxy edit my-mix" instead of "ccs cliproxy edit gemini"
2026-02-12 12:56:57 +07:00
Tam Nhu Tran 399d7e163a fix(cliproxy): address 3 code review issues in composite variants
- P1: Remove premature variant deletion in --force mode
  Fix destructive overwrite path - old variant preserved if user
  cancels auth or creation fails (createVariant handles overwrite)

- P2: Validate all composite tier providers at runtime
  Backend gating now checks all providers in composite, not just
  default tier. Prevents kiro/ghcp on non-default tiers bypassing
  Plus backend requirement.

- P2: Preserve tier thinking when default tier is off
  Early return skipped tier processing when default thinking was
  "off". Now uses flag-based approach - only main model skipped,
  tier loop continues with per-tier thinking config.
2026-02-12 12:29:43 +07:00
Tam Nhu Tran 27d22e836f fix(cliproxy): address 4 functional regressions in composite variants
- P1: Remote composite env now uses remote endpoint/auth
  Add CompositeRemoteConfig parameter to getCompositeEnvVars()
  Pass remote config when useRemoteProxy is true

- P2: Tier thinking uses tier-specific provider
  Extract tier provider from compositeTiers for supportsThinking()
  Fix mixed-provider composite thinking config

- P2: Force variant removal checks result
  Fail fast if removeVariant fails in --force mode

- P2: Guard composite validation against missing tiers
  Add null check before Object.entries(variant.tiers)
2026-02-12 12:08:20 +07:00
Tam Nhu Tran a99180fa22 fix(cliproxy): restore POST tier validation and guard null payloads
- Add requireAllTiers parameter to validateCompositeTiers (default false)
- POST/create passes true to enforce all 3 tiers required
- PUT/update passes false (default) to allow partial updates
- Guard against null tier values that would throw at runtime
2026-02-12 11:45:20 +07:00
Tam Nhu Tran 61f46e738d fix(cliproxy): address 3 functional regressions in composite variants
P1 (Critical): Remote composite execution now correctly uses remote endpoint
- Reorder condition to check useRemoteProxy before isComposite
- Composite variants now work with remote CLIProxy instances

P2a (Medium): Tier deep-merge preserves optional fields during updates
- Use spread merge instead of ?? to preserve fallback/thinking/account

P2b (Medium): API accepts partial tier updates in PUT endpoint
- Skip validation for tiers not present in request
- Aligns with updateCompositeVariant's merge behavior
2026-02-12 11:22:43 +07:00
Tam Nhu Tran c35de7ec9a test(cliproxy): add thinking suffix test and document exit 0 behavior
- Add test case for comma-separated thinking params (32768,extended)
- Add clarifying comment to isProviderError() about exit 0 handling
2026-02-12 11:04:37 +07:00
Tam Nhu Tran ef77607c41 fix(cliproxy): add circular fallback and empty model validation in API
- Validate fallback doesn't point to same provider+model (circular)
- Reject empty/whitespace model strings in composite tiers
- Add TODO comment for concurrent modification race condition
2026-02-12 11:02:11 +07:00
Tam Nhu Tran 74868972dd fix(cliproxy): add session check on delete and atomic settings writes
- Block variant deletion when CLIProxy has active sessions
- Use temp file + rename pattern for atomic settings writes
- Prevents partial writes on crash/interruption
2026-02-12 11:01:49 +07:00
Tam Nhu Tran 6ff17d8480 fix(cliproxy): improve multi-provider auth with continue-on-error pattern
- Continue to remaining providers on auth failure instead of throwing
- Aggregate failures and show summary of succeeded/failed providers
- Improves UX when one provider fails in composite variant
2026-02-12 11:01:27 +07:00
Tam Nhu Tran 0c7dc398f7 fix(cliproxy): add defensive null checks for composite tier config
- Add optional chaining for tier access in env-resolver
- Throw error if default tier model missing in env-builder
- Add null checks for composite.tiers in profile-detector
2026-02-12 11:01:00 +07:00
Tam Nhu Tran 4c002caee1 fix(cliproxy): address code review feedback (attempt 4/5)
- Add default_tier and provider validation in POST/PUT routes
- Extract shared validateCompositeTiers() helper for DRY
- Validate providers against CLIPROXY_SUPPORTED_PROVIDERS
2026-02-12 08:46:38 +07:00
Tam Nhu Tran 6cfbdd649b fix(cliproxy): address code review feedback (attempt 3/5)
- Allow partial composite updates in PUT endpoint (|| -> &&)
- Map service validation errors to 400 status, not 404
- Widen 4xx regex to cover full 400-499 range
2026-02-12 08:39:46 +07:00
Tam Nhu Tran ac574e0baf fix(cliproxy): address code review feedback (attempt 2/5)
- Add tiers shape validation in variant-routes POST/PUT endpoints
- Use process.exit(1) for blocked --config on composite variants
2026-02-12 08:26:03 +07:00
Tam Nhu Tran 854b198b64 fix(cliproxy): address code review feedback (attempt 1/5)
- Add composite fields to UpdateVariant type (default_tier, tiers)
- Handle forceAuth (--auth) for composite multi-provider variants
2026-02-12 08:15:27 +07:00
Tam Nhu Tran efd3f21e29 fix(cliproxy): strip thinking suffix in detectFailedTier matching
Model names with thinking suffixes like "model(high)" now match stderr
that contains the base model name without the suffix.
2026-02-12 07:40:15 +07:00
Tam Nhu Tran 1ebd9f43d6 feat(cliproxy): add dashboard CRUD for composite variants
- Extend create dialog with composite mode toggle and per-tier config tabs
- Add cliproxy-edit-dialog for modifying existing single and composite variants
- Add Edit action and composite type badge to variant table
- Extend API types with composite variant fields
- Update variant routes: GET (composite fields), POST (composite create), PUT (composite update)
2026-02-12 04:25:12 +07:00
Tam Nhu Tran ed22c1aa1e feat(cliproxy): add per-tier thinking config for composite variants
- Extend applyThinkingConfig() with compositeTierThinking parameter
- Priority chain: CLI --thinking > per-tier config > global config > defaults
- thinking: 'off' skips suffix for that tier
- Wire compositeTierThinking extraction in buildClaudeEnvironment()
- Add applyFallback() helper for tier-level env var modification
2026-02-12 04:24:50 +07:00
Tam Nhu Tran 478e9e8f73 feat(cliproxy): add provider error detection for composite fallback
- Add PROVIDER_ERROR_PATTERNS for HTTP 4xx/5xx, overloaded, quota, rate limit
- Add detectFailedTier() to identify which composite tier failed from stderr
- Add isProviderError() to distinguish provider failures from normal exits
2026-02-12 04:24:29 +07:00
Tam Nhu Tran 43e73f335f feat(cliproxy): add CLI edit command for composite variants
- Add handleEdit() interactive wizard for modifying existing variants
- Add updateCompositeVariant() to variant-service for partial tier updates
- Route 'edit' subcommand in cliproxy index
- Update help text with edit command documentation
- Export updateCompositeVariant from services index
2026-02-12 04:24:09 +07:00
Tam Nhu Tran 20d60791ff feat(cliproxy): extend composite schema with fallback and thinking fields
- Add fallback? (provider+model) to CompositeTierConfig for per-tier retry
- Add thinking? string to CompositeTierConfig for per-tier thinking budget
- Add hasFallback flag to VariantConfig for runtime detection
- Propagate new fields in listVariantsFromConfig()

Refs #506
2026-02-12 04:11:00 +07:00
Tam Nhu Tran 07bef9f50e feat(cliproxy): wire composite variant into main execution flow
- Detect composite variants in ProfileDetector with tier metadata
- Pass isComposite/compositeTiers/compositeDefaultTier through ccs.ts
- Handle composite in loadConfigSafe() legacy adapter
- Add validateCompositeVariants() for provider string validation
- Display 'composite' label in API profile listing

Refs #506
2026-02-12 04:09:19 +07:00
Tam Nhu Tran 4926c200f2 feat(cliproxy): add composite variant CLI wizard
- Add --composite flag to 'ccs cliproxy variant create'
- Implement selectTierConfig() interactive prompt per tier
- Add default tier selection after all tiers configured
- Display composite label in auth list and variant remove
- Show per-tier details in remove confirmation
- Update help text with --composite usage

Refs #506
2026-02-12 04:09:19 +07:00
Tam Nhu Tran 44b30b8753 feat(cliproxy): add composite variant runtime execution
- Add getCompositeEnvVars() for root URL + per-tier model env vars
- Extend ProxyChainConfig with composite fields
- Route composite variants through root URL in buildClaudeEnvironment()
- Multi-provider auth check for composite (all tiers must pass)
- Multi-provider token refresh for composite
- Per-tier broken model check
- Block --config for composite variants
- Pass composite config through to env resolver

Refs #506
2026-02-12 04:09:19 +07:00
Tam Nhu Tran c58fdc931e feat(cliproxy): implement composite variant CRUD and settings
- Add saveCompositeVariantUnified() for persisting composite configs
- Add createCompositeVariant() with per-tier backend validation
- Add createCompositeSettingsFile() with root URL + per-tier model env vars
- Add getCompositeRelativeSettingsPath() helper
- Handle composite in listVariantsFromConfig() and removeVariantFromUnifiedConfig()
- Block model update for composite variants (edit config.yaml instead)
- Export new functions from services barrel

Refs #506
2026-02-12 04:09:18 +07:00
Tam Nhu Tran 3d207faac5 feat(cliproxy): add composite variant type definitions
- Add CompositeVariantConfig, CompositeTierConfig interfaces
- Add CLIPROXY_SUPPORTED_PROVIDERS const array
- Extend ExecutorConfig with composite fields (isComposite, compositeTiers, compositeDefaultTier)
- Update variants record type to accept composite configs
- Export CLIProxyVariantConfig from types barrel

Refs #506
2026-02-12 04:09:18 +07:00
Kai (Tam Nhu) TranandGitHub 5df2965642 Merge pull request #525 from kaitranntt/kai/feat/518-cursor-protobuf-executor
feat(cursor): add ConnectRPC protobuf encoder/decoder and HTTP/2 executor
2026-02-12 03:48:23 +07:00
Tam Nhu Tran 79ba1de4e2 fix(cursor): tighten rate limit detection string matching
Use specific patterns ('rate limit', 'resource_exhausted', 'too many
requests') instead of broad 'rate' or 'limit' substrings that would
false-positive on unrelated errors like 'character limit exceeded'.
2026-02-12 03:38:31 +07:00
Tam Nhu Tran c5e8241393 fix(cursor): address fourth-round review feedback for protobuf module 2026-02-12 03:27:58 +07:00
Kai (Tam Nhu) TranandGitHub cb981db356 Merge pull request #526 from kaitranntt/kai/feat/519-cursor-auth-module
feat(cursor): add credential detection, SQLite token extraction, and auth status
2026-02-12 03:16:47 +07:00
Tam Nhu Tran 66a93ee46f fix(cursor): address third-round review feedback for protobuf module
HIGH PRIORITY FIXES:
- Extract shared buffer parsing logic into parseProtobufFrames generator
  method (DRY violation fix) - both JSON and SSE transformers now use
  common frame parsing loop, eliminating ~60% code duplication
- Use COMPRESS_FLAG constants instead of hardcoded 0x01/0x02/0x03 in
  parseConnectRPCFrame for better maintainability

MEDIUM PRIORITY FIXES:
- Return empty buffer on gzip decompression failure (prevents silent
  data corruption) - ALREADY FIXED
- Add debug warning for unknown message roles in convertMessages
- Create GitHub issue #535 for FIELD namespace refactoring follow-up
- Add test coverage: transformProtobufToSSE, error paths, unknown roles

LOW PRIORITY FIXES:
- Rename checksum test to clarify timestamp granularity (~16 min)
- Fix debug log function name in SSE transformer - FIXED BY REFACTOR
- Add comment to TOOL_RESULT_RESULT field documenting future use

All tests pass (1593 pass, 0 fail)
All validation checks pass (typecheck + lint + format + tests)
2026-02-12 03:15:24 +07:00
Tam Nhu Tran a8a68c9599 fix(cursor): address third-round review feedback for auth module 2026-02-12 03:09:35 +07:00
Tam Nhu Tran 7d9c538248 fix(glm): fix missed help text reference and glm-4.5-air pricing
- Update delegation help text from "GLM-4.6" to "GLM-5"
- Fix glm-4.5-air pricing to OpenRouter verified rates:
  input $0.20 -> $0.13, output $1.10 -> $0.85, cache $0.03 -> $0.025
2026-02-12 01:52:32 +07:00
Tam Nhu Tran 3e26dee013 feat(glm): update default model to GLM-5 and fix all GLM pricing
- Update default GLM model from glm-4.7 to glm-5 across configs, presets, help text, and fallbacks
- Add glm-5 pricing entry ($1.00/$3.20 per M tokens, OpenRouter verified)
- Fix incorrect glm-4.7 pricing: $0.60/$2.20 -> $0.40/$1.50 (OpenRouter verified)
- Fix incorrect glm-4.6 pricing: $0.60/$2.20 -> $0.35/$1.50 (OpenRouter verified)
- Fix incorrect glm-4.5 pricing: $0.60/$2.20 -> $0.35/$1.55 (OpenRouter verified)
- Keep all previous GLM model entries for backward compatibility

Closes #532
2026-02-12 01:43:59 +07:00
Tam Nhu Tran e177a4b097 fix(cursor): address second-round review feedback for protobuf module
HIGH Priority:
- Add comprehensive unit tests (27 tests covering encoder, decoder, translator, executor)
  * encodeVarint/decodeVarint round-trip (0, 1, 127, 128, 16383, 0xFFFFFFFF)
  * encodeField/decodeField round-trip (VARINT, LEN string, LEN binary)
  * wrapConnectRPCFrame/parseConnectRPCFrame (compressed/uncompressed)
  * buildCursorRequest message translation (system, user, assistant, tool)
  * generateChecksum header format validation
  * buildHeaders output validation
  * transformProtobufToJSON basic conversion
- Create GitHub issue #531 for true streaming implementation
- Update TODO comment to reference issue #531

MEDIUM Priority:
- Export CursorCredentials from cursor-protobuf-schema.ts
- Add JSDoc grouping comments to FIELD constant for clarity
- Make hardcoded values configurable (CURSOR_CLIENT_VERSION, CURSOR_USER_AGENT)
- Add debug logging to 9 silent catch blocks (respects CCS_DEBUG env var)
- Fix stream check: stream !== false → stream === true

Bug Fixes:
- Fix decodeVarint to return unsigned values (>>> 0)
- Fix test assertion for Response.text() async API
2026-02-12 01:26:47 +07:00
Tam Nhu Tran 84a256d0ac fix(cursor): address second-round review feedback for auth module
- Add comprehensive unit tests for cursor-auth.test.ts
  - validateToken: valid/invalid tokens, short tokens, UUID formats, empty strings
  - extractUserInfo: JWT parsing, email handling, non-JWT tokens, malformed base64
  - saveCredentials/loadCredentials: round-trip, invalid JSON/types, missing fields
  - checkAuthStatus: authenticated/not authenticated, expired tokens, JWT exp, invalid dates
  - deleteCredentials: delete existing/non-existent files, multiple deletes
  - All tests use CCS_HOME env var for isolation, real file I/O, no mocks

- Fix dead try-catch around new Date() in checkAuthStatus()
  - Replace try-catch with isNaN check (new Date('garbage') returns Invalid Date, not throw)
  - Properly handle Invalid Date by checking isNaN(getTime())

- Fix email populated with sub claim in extractUserInfo()
  - Change email: decoded.email || decoded.sub to email: decoded.email || undefined
  - Prevent non-email values (UUIDs) from populating email field

- Add type guards for JSON.parse result in extractUserInfo()
  - Cast to Record<string, unknown> and validate types
  - Use typeof checks for email, userId, exp fields
2026-02-12 01:23:29 +07:00
Tam Nhu Tran b412ba2a9e fix(cursor): address remaining review items in auth module
- Enhanced extractUserInfo to return JWT exp claim for expiry detection
- Updated checkAuthStatus to use JWT exp when available, fallback to importedAt heuristic
- Added typeof validation for loadCredentials fields
- Added ENOENT detection for sqlite3 availability in queryStateDb
- Added deleteCredentials function for cleanup
- Updated PR #526 description to remove refreshToken mention
2026-02-12 01:07:25 +07:00
Tam Nhu Tran f3d532afd9 fix(cursor): address remaining LOW review items in protobuf module 2026-02-12 01:06:33 +07:00
Tam Nhu Tran 7d049d8f1e fix(cliproxy): address all review feedback (Low + informational)
- Add sync constraint comment on process.exit handler (executor)
- Add TOCTOU race acceptability comment (account-safety)
- Mask email in handleQuotaExhaustion reason string
- Use realistic exhaustion_threshold (5) in test configs
2026-02-12 00:42:54 +07:00
Tam Nhu Tran fcc605bc1f fix(cliproxy): mask email in ban detection and fix JSDoc default
- Use maskEmail() in handleBanDetection output for consistency
- Fix cooldown_minutes JSDoc: default is 5, not 10
2026-02-12 00:34:03 +07:00
Kai (Tam Nhu) TranandGitHub c6c94a0c1e feat(cliproxy): runtime quota monitoring during active sessions (#529)
* feat(cliproxy): add runtime quota monitoring during active sessions

Adds adaptive background quota polling to detect and respond to quota
exhaustion during active CLIProxy sessions. Prevents rate-limit-driven
account bans by auto-cooling exhausted accounts and switching defaults.

- Adaptive polling: 300s normal, 60s at 20% threshold, stops at 0%
- Stderr warnings at 20%, boxed exhaustion alerts at 0%
- Cooldown + default switch on exhaustion (existing patterns)
- Configurable via quota_management.runtime_monitor in config.yaml
- Timer.unref() prevents blocking process exit
- monitorStopped guard for in-flight poll safety

Closes #524

* fix: address code review feedback (attempt 1/5)

- M1: Round quotaPercent display with Math.round() to avoid ugly floats
- M2: Rename exhaust_threshold -> exhaustion_threshold for consistency
  with existing auto.exhaustion_threshold config field
- M3: Replace async not.toThrow() with direct await assertion pattern

* fix: address code review feedback (attempt 2/5)

- Remove .claude/agent-memory/ from tracking and add to .gitignore
- Unify cooldown_minutes default to 5 (was 10 in runtime_monitor, 5 in auto)
- Add threshold validation in startQuotaMonitor (warn > exhaustion)
- Document intentional post-switch monitoring gap in code comment
2026-02-11 22:50:50 +07:00
Tam Nhu Tran 7e4f08004c fix(cursor): address code review feedback on auth module
- Sanitize SQL key parameter in queryStateDb to prevent injection
- Fix UUID regex: use exact {32} length, remove redundant hyphen from
  stripped character class
- Remove unused types from types.ts (YAGNI): CursorDaemonStatus,
  CursorModel, MessageRole, CursorMessage, CursorToolCall,
  CursorToolResult, ProtobufExtractResult — belong in their respective
  module PRs
2026-02-11 19:31:04 +07:00
Tam Nhu Tran 31f574118d fix(cursor): address code review feedback (attempt 1/5)
- Fix bitwise shift overflow in generateChecksum: use Math.trunc
  division for >>40/>>32 which wrap modulo 32 in JS
- Add FIXED64/FIXED32 bounds checks in protobuf decoder to prevent
  out-of-bounds slice on truncated buffers
- Consolidate COMPRESS_FLAG to single definition in schema (DRY):
  executor now imports from schema, added GZIP_ALT/GZIP_BOTH values
- Fix token split edge case: use indexOf+slice instead of split('::')[1]
  to handle tokens containing multiple :: delimiters
- Fix AbortSignal listener leak: store handler ref, use once:true,
  remove listener on request end/error
2026-02-11 19:27:39 +07:00
Kai (Tam Nhu) TranandGitHub e055dac199 feat(cliproxy): add account safety guards to prevent Google account bans (#516)
* feat(cliproxy): add account safety guards to prevent Google account bans

Implements cross-provider isolation to prevent Google from flagging
concurrent OAuth usage across different client IDs (ref: #509, #512).

Three pillars:
1. Auto-pause enforcement at session launch — conflicting accounts in
   other Google OAuth providers are paused so CLIProxyAPI can't use them,
   restored on session exit with crash recovery via auto-paused.json
2. Ban/disable detection — error responses matching Google ban patterns
   auto-pause the affected account to prevent further damage
3. Cross-provider conflict warnings during OAuth registration

Key design decisions:
- PID-based session tracking for crash recovery (dead PID = restore)
- Timestamp comparison prevents restoring ban-paused accounts on exit
- Schema validation on auto-paused.json prevents corrupted state
- Falls back to warn-only when another session is managing isolation

* fix(cliproxy): address code review feedback (attempt 1/5)

- Re-read auto-paused.json before write in enforceProviderIsolation to
  reduce concurrent write race window
- Use actual email from registry for display instead of raw accountId
- Export maskEmail for testability
- Add 27 unit tests covering ban detection, email masking,
  cross-provider duplicate detection, enforcement lifecycle,
  crash recovery, and timestamp-guarded restore

* fix(cliproxy): address remaining review feedback (attempt 2/5)

- Add handleBanDetection test verifying account pause on ban error
- Add warnCrossProviderDuplicates tests (true/false/non-Google)
- Document PID reuse limitation in isPidAlive JSDoc comment
2026-02-11 19:21:31 +07:00
Tam Nhu Tran cc5a9039e4 fix(cursor): address code review edge cases in protobuf and executor
CRITICAL FIX:
- CursorCredentials interface now matches types.ts (machineId, ghostMode as top-level)
- Fixes runtime error when cursor-auth saves credentials and cursor-executor reads them

HIGH:
- Replace 18+ non-null assertions with guard clauses across executor and decoder
- Prefix unused params in translator (_model, _stream, _credentials)
- HTTP/2 client closes on connection error to prevent leak
- AbortSignal listener leak documented with TODO (inline arrow prevents cleanup)

MEDIUM:
- Export concatArrays from encoder, remove duplicate from protobuf.ts
- Varint decoder now enforces 5-byte max to prevent overflow
- Buffer slice bounds check prevents out-of-range read
- Empty messages array validation with explicit error
- Buffered streaming limitation documented with TODO comment

All edge cases from code review now addressed.
2026-02-11 19:13:58 +07:00
Tam Nhu Tran aeb580281f fix(cursor): harden auth security and add token expiry warning 2026-02-11 19:06:57 +07:00
Kai (Tam Nhu) TranandGitHub 4065399d8a fix(cliproxy): add fork:true for Claude model aliases in config generator (#523)
Config generator now outputs fork:true for Claude model alias entries,
ensuring both upstream (claude-*) and aliased (gemini-claude-*) model
names appear in /v1/models listings. Also preserves fork flag when
parsing user-added aliases during config regeneration.

Bumps config version to v7 to trigger regeneration on next ccs doctor.

Closes #522
2026-02-11 19:04:41 +07:00
Tam Nhu Tran 9daf9430bb feat(cursor): add core protobuf encoder/decoder and executor
- Split protobuf into 3 files: schema, encoder, decoder for <200 LOC constraint
- Implement ConnectRPC wire format encoding (varint, fields, messages, frames)
- Implement protobuf decoder with gzip decompression support
- Port Cursor executor with HTTP/2 support and checksum generation (Jyh cipher)
- Add OpenAI to Cursor message translator (system→user, tool results handling)
- Transform protobuf responses to both SSE and JSON formats
- Use Node.js built-in crypto/zlib (no uuid dependency)
- All files TypeScript strict mode compliant
2026-02-11 17:59:44 +07:00
Tam Nhu Tran 56270d99f3 feat(cursor): add auth module with SQLite auto-detect and types
- Add CursorCredentials, CursorAuthStatus, and related types
- Implement autoDetectTokens() using sqlite3 CLI (no native deps)
- Add validateToken() for token format validation
- Add extractUserInfo() for JWT decoding
- Add saveCredentials/loadCredentials using getCcsDir()
- Add checkAuthStatus() for auth verification
- Platform-specific state.vscdb paths (Linux/macOS/Windows)
- Graceful error handling for missing database/tokens

Refs: #519 (sub-task of #517)
2026-02-11 17:55:15 +07:00