mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
Classify Claude CLI usage shell failures (#6065)
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -634,6 +634,34 @@ describe('fetchClaudeRateLimits', () => {
|
||||
expect(fetchViaPty).toHaveBeenCalledWith({ authPreparation })
|
||||
})
|
||||
|
||||
it('marks CLI plan usage shell results as usage unavailable', async () => {
|
||||
const authPreparation: ClaudeRuntimeAuthPreparation = {
|
||||
configDir: '/Users/test/.claude',
|
||||
envPatch: {},
|
||||
stripAuthEnv: false,
|
||||
provenance: 'system'
|
||||
}
|
||||
vi.mocked(fetchViaPty).mockResolvedValueOnce({
|
||||
provider: 'claude',
|
||||
session: null,
|
||||
weekly: null,
|
||||
updatedAt: 1,
|
||||
error: 'Claude plan usage is unavailable for this Claude CLI session.',
|
||||
status: 'error'
|
||||
})
|
||||
|
||||
await expect(fetchClaudeRateLimits({ authPreparation })).resolves.toMatchObject({
|
||||
provider: 'claude',
|
||||
status: 'error',
|
||||
error: 'Claude plan usage is unavailable for this Claude CLI session.',
|
||||
usageMetadata: {
|
||||
source: 'cli',
|
||||
attemptedSources: ['cli'],
|
||||
failureKind: 'usage-unavailable'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('surfaces Keychain read failures as structured usage metadata when CLI fallback is disabled', async () => {
|
||||
vi.mocked(readActiveClaudeKeychainCredentials).mockRejectedValueOnce(
|
||||
new Error('security timed out after 3000ms')
|
||||
|
||||
@@ -443,6 +443,21 @@ function metadataForAttempt(input: {
|
||||
}
|
||||
}
|
||||
|
||||
function classifyClaudeCliUsageFailure(
|
||||
limits: ProviderRateLimits
|
||||
): UsageRateLimitFailureKind | undefined {
|
||||
if (!limits.error) {
|
||||
return undefined
|
||||
}
|
||||
if (/rate limited/i.test(limits.error)) {
|
||||
return 'rate-limited'
|
||||
}
|
||||
if (/plan usage is unavailable|usage is unavailable/i.test(limits.error)) {
|
||||
return 'usage-unavailable'
|
||||
}
|
||||
return 'cli-unavailable'
|
||||
}
|
||||
|
||||
async function fetchClaudeUsageViaCli(input: {
|
||||
authPreparation?: ClaudeRuntimeAuthPreparation
|
||||
oauthCredentials: OAuthCredentialReadResult
|
||||
@@ -456,7 +471,8 @@ async function fetchClaudeUsageViaCli(input: {
|
||||
attemptedSources: input.attempts.attemptedSources,
|
||||
oauthCredentials: input.oauthCredentials,
|
||||
authPreparation: input.authPreparation,
|
||||
source: 'cli'
|
||||
source: 'cli',
|
||||
failureKind: classifyClaudeCliUsageFailure(limits)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@@ -212,6 +212,16 @@ describe('provider usage error copy', () => {
|
||||
expect(getProviderUsageStatusLabel(p)).toBe('Sign-in unavailable')
|
||||
expect(getProviderUsageErrorMessage(p)).toBe('Claude sign-in credentials could not be read.')
|
||||
})
|
||||
|
||||
it('uses structured unavailable copy for Claude CLI usage shell failures', () => {
|
||||
const p = provider({
|
||||
error: 'Claude plan usage is unavailable for this Claude CLI session.',
|
||||
usageMetadata: { failureKind: 'usage-unavailable' }
|
||||
})
|
||||
|
||||
expect(getProviderUsageStatusLabel(p)).toBe('Usage unavailable')
|
||||
expect(getProviderUsageErrorMessage(p)).toBe('Claude usage is unavailable right now.')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getWindowSections', () => {
|
||||
|
||||
Reference in New Issue
Block a user