Remove internal-only bundled skills and mock helpers (#376)

* Remove internal-only bundled skills and mock rate-limit behavior

This takes the next planned Phase C-lite slice by deleting bundled skills
that only ever registered for internal users and replacing the internal
mock rate-limit helper with a stable no-op external stub. The external
build keeps the same behavior while removing a concentrated block of
USER_TYPE-gated dead code.

Constraint: Limit this PR to isolated internal-only helpers and avoid bridge, oauth, or rebrand behavior
Rejected: Broad USER_TYPE cleanup across mixed runtime surfaces | too risky for the next medium-sized PR
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: The next cleanup pass should continue with similarly isolated USER_TYPE helpers before touching main.tsx or protocol-heavy code
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (upstream baseline remains noisy)

* Align internal-only helper removal with remaining user guidance

This follow-up fixes the mock billing stub to be a true no-op and removes
stale user-facing references to /verify and /skillify from the same PR.
It also leaves a clearer paper trail for review: the deleted verify skill
was explicitly ant-gated before removal, and the remaining mock helper
callers still resolve to safe no-op returns in the external build.

Constraint: Keep the PR focused on consistency fixes and reviewer-requested evidence, not new cleanup scope
Rejected: Leave stale guidance for a later PR | would make this branch internally inconsistent after skill removal
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When deleting gated features, always sweep user guidance and coordinator prompts in the same pass
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (upstream baseline remains noisy; changed-file scan still shows only pre-existing tipRegistry errors outside edited lines)

* Clarify generic workflow wording after skill removal

This removes the last generic verification-skill wording that could still
be read as pointing at a deleted bundled command. The guidance now talks
about project workflows rather than a specific bundled verify skill.

Constraint: Keep the follow-up limited to reviewer-facing wording cleanup on the same PR
Rejected: Leave generic wording as-is | still too easy to misread after the explicit /verify references were removed
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When removing bundled commands, scrub both explicit and generic references in the same branch
Tested: bun run build
Tested: bun run smoke
Not-tested: Additional checks unchanged by wording-only follow-up

---------

Co-authored-by: anandh8x <test@example.com>
This commit is contained in:
Anandan
2026-04-05 10:14:21 +05:30
committed by GitHub
parent 5ff34283c4
commit daa3aa27a0
9 changed files with 35 additions and 1334 deletions

View File

@@ -1,14 +1,12 @@
// Mock rate limits for testing [internal-only]
// This allows testing various rate limit scenarios without hitting actual limits
//
// ⚠️ WARNING: This is for internal testing/demo purposes only!
// The mock headers may not exactly match the API specification or real-world behavior.
// Always validate against actual API responses before relying on this for production features.
// The external build keeps this module as a stable no-op surface so imports
// remain valid without exposing internal-only rate-limit simulation behavior.
import type { SubscriptionType } from '../services/oauth/types.js'
import { setMockBillingAccessOverride } from '../utils/billing.js'
import type { OverageDisabledReason } from './claudeAiLimits.js'
type SubscriptionType = string
type MockHeaders = {
'anthropic-ratelimit-unified-status'?:
| 'allowed'
@@ -29,7 +27,6 @@ type MockHeaders = {
'anthropic-ratelimit-unified-fallback'?: 'available'
'anthropic-ratelimit-unified-fallback-percentage'?: string
'retry-after'?: string
// Early warning utilization headers
'anthropic-ratelimit-unified-5h-utilization'?: string
'anthropic-ratelimit-unified-5h-reset'?: string
'anthropic-ratelimit-unified-5h-surpassed-threshold'?: string
@@ -79,679 +76,53 @@ export type MockScenario =
| 'extra-usage-required'
| 'clear'
let mockHeaders: MockHeaders = {}
let mockEnabled = false
let mockHeaderless429Message: string | null = null
let mockSubscriptionType: SubscriptionType | null = null
let mockFastModeRateLimitDurationMs: number | null = null
let mockFastModeRateLimitExpiresAt: number | null = null
// Default subscription type for mock testing
const DEFAULT_MOCK_SUBSCRIPTION: SubscriptionType = 'max'
// Track individual exceeded limits with their reset times
type ExceededLimit = {
type: 'five_hour' | 'seven_day' | 'seven_day_opus' | 'seven_day_sonnet'
resetsAt: number // Unix timestamp
}
let exceededLimits: ExceededLimit[] = []
// New approach: Toggle individual headers
export function setMockHeader(
key: MockHeaderKey,
value: string | undefined,
): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
_key: MockHeaderKey,
_value: string | undefined,
): void {}
mockEnabled = true
// Special case for retry-after which doesn't have the prefix
const fullKey = (
key === 'retry-after' ? 'retry-after' : `anthropic-ratelimit-unified-${key}`
) as keyof MockHeaders
if (value === undefined || value === 'clear') {
delete mockHeaders[fullKey]
if (key === 'claim') {
exceededLimits = []
}
// Update retry-after if status changed
if (key === 'status' || key === 'overage-status') {
updateRetryAfter()
}
return
} else {
// Handle special cases for reset times
if (key === 'reset' || key === 'overage-reset') {
// If user provides a number, treat it as hours from now
const hours = Number(value)
if (!isNaN(hours)) {
value = String(Math.floor(Date.now() / 1000) + hours * 3600)
}
}
// Handle claims - add to exceeded limits
if (key === 'claim') {
const validClaims = [
'five_hour',
'seven_day',
'seven_day_opus',
'seven_day_sonnet',
]
if (validClaims.includes(value)) {
// Determine reset time based on claim type
let resetsAt: number
if (value === 'five_hour') {
resetsAt = Math.floor(Date.now() / 1000) + 5 * 3600
} else if (
value === 'seven_day' ||
value === 'seven_day_opus' ||
value === 'seven_day_sonnet'
) {
resetsAt = Math.floor(Date.now() / 1000) + 7 * 24 * 3600
} else {
resetsAt = Math.floor(Date.now() / 1000) + 3600
}
// Add to exceeded limits (remove if already exists)
exceededLimits = exceededLimits.filter(l => l.type !== value)
exceededLimits.push({ type: value as ExceededLimit['type'], resetsAt })
// Set the representative claim (furthest reset time)
updateRepresentativeClaim()
return
}
}
// Widen to a string-valued record so dynamic key assignment is allowed.
// MockHeaders values are string-literal unions; assigning a raw user-input
// string requires widening, but this is mock/test code so it's acceptable.
const headers: Partial<Record<keyof MockHeaders, string>> = mockHeaders
headers[fullKey] = value
// Update retry-after if status changed
if (key === 'status' || key === 'overage-status') {
updateRetryAfter()
}
}
// If all headers are cleared, disable mocking
if (Object.keys(mockHeaders).length === 0) {
mockEnabled = false
}
}
// Helper to update retry-after based on current state
function updateRetryAfter(): void {
const status = mockHeaders['anthropic-ratelimit-unified-status']
const overageStatus =
mockHeaders['anthropic-ratelimit-unified-overage-status']
const reset = mockHeaders['anthropic-ratelimit-unified-reset']
if (
status === 'rejected' &&
(!overageStatus || overageStatus === 'rejected') &&
reset
) {
// Calculate seconds until reset
const resetTimestamp = Number(reset)
const secondsUntilReset = Math.max(
0,
resetTimestamp - Math.floor(Date.now() / 1000),
)
mockHeaders['retry-after'] = String(secondsUntilReset)
} else {
delete mockHeaders['retry-after']
}
}
// Update the representative claim based on exceeded limits
function updateRepresentativeClaim(): void {
if (exceededLimits.length === 0) {
delete mockHeaders['anthropic-ratelimit-unified-representative-claim']
delete mockHeaders['anthropic-ratelimit-unified-reset']
delete mockHeaders['retry-after']
return
}
// Find the limit with the furthest reset time
const furthest = exceededLimits.reduce((prev, curr) =>
curr.resetsAt > prev.resetsAt ? curr : prev,
)
// Set the representative claim (appears for both warning and rejected)
mockHeaders['anthropic-ratelimit-unified-representative-claim'] =
furthest.type
mockHeaders['anthropic-ratelimit-unified-reset'] = String(furthest.resetsAt)
// Add retry-after if rejected and no overage available
if (mockHeaders['anthropic-ratelimit-unified-status'] === 'rejected') {
const overageStatus =
mockHeaders['anthropic-ratelimit-unified-overage-status']
if (!overageStatus || overageStatus === 'rejected') {
// Calculate seconds until reset
const secondsUntilReset = Math.max(
0,
furthest.resetsAt - Math.floor(Date.now() / 1000),
)
mockHeaders['retry-after'] = String(secondsUntilReset)
} else {
// Overage is available, no retry-after
delete mockHeaders['retry-after']
}
} else {
delete mockHeaders['retry-after']
}
}
// Add function to add exceeded limit with custom reset time
export function addExceededLimit(
type: 'five_hour' | 'seven_day' | 'seven_day_opus' | 'seven_day_sonnet',
hoursFromNow: number,
): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
_type: 'five_hour' | 'seven_day' | 'seven_day_opus' | 'seven_day_sonnet',
_hoursFromNow: number,
): void {}
mockEnabled = true
const resetsAt = Math.floor(Date.now() / 1000) + hoursFromNow * 3600
// Remove existing limit of same type
exceededLimits = exceededLimits.filter(l => l.type !== type)
exceededLimits.push({ type, resetsAt })
// Update status to rejected if we have exceeded limits
if (exceededLimits.length > 0) {
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
}
updateRepresentativeClaim()
}
// Set mock early warning utilization for time-relative thresholds
// claimAbbrev: '5h' or '7d'
// utilization: 0-1 (e.g., 0.92 for 92% used)
// hoursFromNow: hours until reset (default: 4 for 5h, 120 for 7d)
export function setMockEarlyWarning(
claimAbbrev: '5h' | '7d' | 'overage',
utilization: number,
hoursFromNow?: number,
): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
_claimAbbrev: '5h' | '7d' | 'overage',
_utilization: number,
_hoursFromNow?: number,
): void {}
mockEnabled = true
export function clearMockEarlyWarning(): void {}
// Clear ALL early warning headers first (5h is checked before 7d, so we need
// to clear 5h headers when testing 7d to avoid 5h taking priority)
clearMockEarlyWarning()
// Default hours based on claim type (early in window to trigger warning)
const defaultHours = claimAbbrev === '5h' ? 4 : 5 * 24
const hours = hoursFromNow ?? defaultHours
const resetsAt = Math.floor(Date.now() / 1000) + hours * 3600
mockHeaders[`anthropic-ratelimit-unified-${claimAbbrev}-utilization`] =
String(utilization)
mockHeaders[`anthropic-ratelimit-unified-${claimAbbrev}-reset`] =
String(resetsAt)
// Set the surpassed-threshold header to trigger early warning
mockHeaders[
`anthropic-ratelimit-unified-${claimAbbrev}-surpassed-threshold`
] = String(utilization)
// Set status to allowed so early warning logic can upgrade it
if (!mockHeaders['anthropic-ratelimit-unified-status']) {
mockHeaders['anthropic-ratelimit-unified-status'] = 'allowed'
}
}
// Clear mock early warning headers
export function clearMockEarlyWarning(): void {
delete mockHeaders['anthropic-ratelimit-unified-5h-utilization']
delete mockHeaders['anthropic-ratelimit-unified-5h-reset']
delete mockHeaders['anthropic-ratelimit-unified-5h-surpassed-threshold']
delete mockHeaders['anthropic-ratelimit-unified-7d-utilization']
delete mockHeaders['anthropic-ratelimit-unified-7d-reset']
delete mockHeaders['anthropic-ratelimit-unified-7d-surpassed-threshold']
}
export function setMockRateLimitScenario(scenario: MockScenario): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
if (scenario === 'clear') {
mockHeaders = {}
mockHeaderless429Message = null
mockEnabled = false
return
}
mockEnabled = true
// Set reset times for demos
const fiveHoursFromNow = Math.floor(Date.now() / 1000) + 5 * 3600
const sevenDaysFromNow = Math.floor(Date.now() / 1000) + 7 * 24 * 3600
// Clear existing headers
mockHeaders = {}
mockHeaderless429Message = null
// Only clear exceeded limits for scenarios that explicitly set them
// Overage scenarios should preserve existing exceeded limits
const preserveExceededLimits = [
'overage-active',
'overage-warning',
'overage-exhausted',
].includes(scenario)
if (!preserveExceededLimits) {
exceededLimits = []
}
switch (scenario) {
case 'normal':
mockHeaders = {
'anthropic-ratelimit-unified-status': 'allowed',
'anthropic-ratelimit-unified-reset': String(fiveHoursFromNow),
}
break
case 'session-limit-reached':
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
break
case 'approaching-weekly-limit':
mockHeaders = {
'anthropic-ratelimit-unified-status': 'allowed_warning',
'anthropic-ratelimit-unified-reset': String(sevenDaysFromNow),
'anthropic-ratelimit-unified-representative-claim': 'seven_day',
}
break
case 'weekly-limit-reached':
exceededLimits = [{ type: 'seven_day', resetsAt: sevenDaysFromNow }]
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
break
case 'overage-active': {
// If no limits have been exceeded yet, default to 5-hour
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'allowed'
// Set overage reset time (monthly)
const endOfMonthActive = new Date()
endOfMonthActive.setMonth(endOfMonthActive.getMonth() + 1, 1)
endOfMonthActive.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthActive.getTime() / 1000),
)
break
}
case 'overage-warning': {
// If no limits have been exceeded yet, default to 5-hour
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] =
'allowed_warning'
// Overage typically resets monthly, but for demo let's say end of month
const endOfMonth = new Date()
endOfMonth.setMonth(endOfMonth.getMonth() + 1, 1)
endOfMonth.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonth.getTime() / 1000),
)
break
}
case 'overage-exhausted': {
// If no limits have been exceeded yet, default to 5-hour
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
// Both subscription and overage are exhausted
// Subscription resets based on the exceeded limit, overage resets monthly
const endOfMonthExhausted = new Date()
endOfMonthExhausted.setMonth(endOfMonthExhausted.getMonth() + 1, 1)
endOfMonthExhausted.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthExhausted.getTime() / 1000),
)
break
}
case 'out-of-credits': {
// Out of credits - subscription limit hit, overage rejected due to insufficient credits
// (wallet is empty)
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-disabled-reason'] =
'out_of_credits'
const endOfMonth = new Date()
endOfMonth.setMonth(endOfMonth.getMonth() + 1, 1)
endOfMonth.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonth.getTime() / 1000),
)
break
}
case 'org-zero-credit-limit': {
// Org service has zero credit limit - admin set org-level spend cap to $0
// Non-admin Team/Enterprise users should not see "Request extra usage" option
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-disabled-reason'] =
'org_service_zero_credit_limit'
const endOfMonthZero = new Date()
endOfMonthZero.setMonth(endOfMonthZero.getMonth() + 1, 1)
endOfMonthZero.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthZero.getTime() / 1000),
)
break
}
case 'org-spend-cap-hit': {
// Org spend cap hit for the month - org overages temporarily disabled
// Non-admin Team/Enterprise users should not see "Request extra usage" option
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-disabled-reason'] =
'org_level_disabled_until'
const endOfMonthHit = new Date()
endOfMonthHit.setMonth(endOfMonthHit.getMonth() + 1, 1)
endOfMonthHit.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthHit.getTime() / 1000),
)
break
}
case 'member-zero-credit-limit': {
// Member has zero credit limit - admin set this user's individual limit to $0
// Non-admin Team/Enterprise users SHOULD see "Request extra usage" (admin can allocate more)
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-disabled-reason'] =
'member_zero_credit_limit'
const endOfMonthMember = new Date()
endOfMonthMember.setMonth(endOfMonthMember.getMonth() + 1, 1)
endOfMonthMember.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthMember.getTime() / 1000),
)
break
}
case 'seat-tier-zero-credit-limit': {
// Seat tier has zero credit limit - admin set this seat tier's limit to $0
// Non-admin Team/Enterprise users SHOULD see "Request extra usage" (admin can allocate more)
if (exceededLimits.length === 0) {
exceededLimits = [{ type: 'five_hour', resetsAt: fiveHoursFromNow }]
}
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-status'] = 'rejected'
mockHeaders['anthropic-ratelimit-unified-overage-disabled-reason'] =
'seat_tier_zero_credit_limit'
const endOfMonthSeatTier = new Date()
endOfMonthSeatTier.setMonth(endOfMonthSeatTier.getMonth() + 1, 1)
endOfMonthSeatTier.setHours(0, 0, 0, 0)
mockHeaders['anthropic-ratelimit-unified-overage-reset'] = String(
Math.floor(endOfMonthSeatTier.getTime() / 1000),
)
break
}
case 'opus-limit': {
exceededLimits = [{ type: 'seven_day_opus', resetsAt: sevenDaysFromNow }]
updateRepresentativeClaim()
// Always send 429 rejected status - the error handler will decide whether
// to show an error or return NO_RESPONSE_REQUESTED based on fallback eligibility
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
break
}
case 'opus-warning': {
mockHeaders = {
'anthropic-ratelimit-unified-status': 'allowed_warning',
'anthropic-ratelimit-unified-reset': String(sevenDaysFromNow),
'anthropic-ratelimit-unified-representative-claim': 'seven_day_opus',
}
break
}
case 'sonnet-limit': {
exceededLimits = [
{ type: 'seven_day_sonnet', resetsAt: sevenDaysFromNow },
]
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
break
}
case 'sonnet-warning': {
mockHeaders = {
'anthropic-ratelimit-unified-status': 'allowed_warning',
'anthropic-ratelimit-unified-reset': String(sevenDaysFromNow),
'anthropic-ratelimit-unified-representative-claim': 'seven_day_sonnet',
}
break
}
case 'fast-mode-limit': {
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
// Duration in ms (> 20s threshold to trigger cooldown)
mockFastModeRateLimitDurationMs = 10 * 60 * 1000
break
}
case 'fast-mode-short-limit': {
updateRepresentativeClaim()
mockHeaders['anthropic-ratelimit-unified-status'] = 'rejected'
// Duration in ms (< 20s threshold, won't trigger cooldown)
mockFastModeRateLimitDurationMs = 10 * 1000
break
}
case 'extra-usage-required': {
// Headerless 429 — exercises the entitlement-rejection path in errors.ts
mockHeaderless429Message =
'Extra usage is required for long context requests.'
break
}
default:
break
}
}
export function setMockRateLimitScenario(_scenario: MockScenario): void {}
export function getMockHeaderless429Message(): string | null {
if (process.env.USER_TYPE !== 'ant') {
return null
}
// Env var path for -p / SDK testing where slash commands aren't available
if (process.env.CLAUDE_MOCK_HEADERLESS_429) {
return process.env.CLAUDE_MOCK_HEADERLESS_429
}
if (!mockEnabled) {
return null
}
return mockHeaderless429Message
return null
}
export function getMockHeaders(): MockHeaders | null {
if (
!mockEnabled ||
process.env.USER_TYPE !== 'ant' ||
Object.keys(mockHeaders).length === 0
) {
return null
}
return mockHeaders
return null
}
export function getMockStatus(): string {
if (
!mockEnabled ||
(Object.keys(mockHeaders).length === 0 && !mockSubscriptionType)
) {
return 'No mock headers active (using real limits)'
}
const lines: string[] = []
lines.push('Active mock headers:')
// Show subscription type - either explicitly set or default
const effectiveSubscription =
mockSubscriptionType || DEFAULT_MOCK_SUBSCRIPTION
if (mockSubscriptionType) {
lines.push(` Subscription Type: ${mockSubscriptionType} (explicitly set)`)
} else {
lines.push(` Subscription Type: ${effectiveSubscription} (default)`)
}
Object.entries(mockHeaders).forEach(([key, value]) => {
if (value !== undefined) {
// Format the header name nicely
const formattedKey = key
.replace('anthropic-ratelimit-unified-', '')
.replace(/-/g, ' ')
.replace(/\b\w/g, c => c.toUpperCase())
// Format timestamps as human-readable
if (key.includes('reset') && value) {
const timestamp = Number(value)
const date = new Date(timestamp * 1000)
lines.push(` ${formattedKey}: ${value} (${date.toLocaleString()})`)
} else {
lines.push(` ${formattedKey}: ${value}`)
}
}
})
// Show exceeded limits if any
if (exceededLimits.length > 0) {
lines.push('\nExceeded limits (contributing to representative claim):')
exceededLimits.forEach(limit => {
const date = new Date(limit.resetsAt * 1000)
lines.push(` ${limit.type}: resets at ${date.toLocaleString()}`)
})
}
return lines.join('\n')
return 'No mock headers active (using real limits)'
}
export function clearMockHeaders(): void {
mockHeaders = {}
exceededLimits = []
mockSubscriptionType = null
mockFastModeRateLimitDurationMs = null
mockFastModeRateLimitExpiresAt = null
mockHeaderless429Message = null
setMockBillingAccessOverride(null)
mockEnabled = false
}
export function applyMockHeaders(
headers: globalThis.Headers,
): globalThis.Headers {
const mock = getMockHeaders()
if (!mock) {
return headers
}
// Create a new Headers object with original headers
// eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins
const newHeaders = new globalThis.Headers(headers)
// Apply mock headers (overwriting originals)
Object.entries(mock).forEach(([key, value]) => {
if (value !== undefined) {
newHeaders.set(key, value)
}
})
return newHeaders
return headers
}
// Check if we should process rate limits even without subscription
// This is for Ant employees testing with mocks
export function shouldProcessMockLimits(): boolean {
if (process.env.USER_TYPE !== 'ant') {
return false
}
return mockEnabled || Boolean(process.env.CLAUDE_MOCK_HEADERLESS_429)
return false
}
export function getCurrentMockScenario(): MockScenario | null {
if (!mockEnabled) {
return null
}
// Reverse lookup the scenario from current headers
if (!mockHeaders) return null
const status = mockHeaders['anthropic-ratelimit-unified-status']
const overage = mockHeaders['anthropic-ratelimit-unified-overage-status']
const claim = mockHeaders['anthropic-ratelimit-unified-representative-claim']
if (claim === 'seven_day_opus') {
return status === 'rejected' ? 'opus-limit' : 'opus-warning'
}
if (claim === 'seven_day_sonnet') {
return status === 'rejected' ? 'sonnet-limit' : 'sonnet-warning'
}
if (overage === 'rejected') return 'overage-exhausted'
if (overage === 'allowed_warning') return 'overage-warning'
if (overage === 'allowed') return 'overage-active'
if (status === 'rejected') {
if (claim === 'five_hour') return 'session-limit-reached'
if (claim === 'seven_day') return 'weekly-limit-reached'
}
if (status === 'allowed_warning') {
if (claim === 'seven_day') return 'approaching-weekly-limit'
}
if (status === 'allowed') return 'normal'
return null
}
@@ -802,81 +173,28 @@ export function getScenarioDescription(scenario: MockScenario): string {
}
}
// Mock subscription type management
export function setMockSubscriptionType(
subscriptionType: SubscriptionType | null,
): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
mockEnabled = true
mockSubscriptionType = subscriptionType
}
_subscriptionType: SubscriptionType | null,
): void {}
export function getMockSubscriptionType(): SubscriptionType | null {
if (!mockEnabled || process.env.USER_TYPE !== 'ant') {
return null
}
// Return the explicitly set subscription type, or default to 'max'
return mockSubscriptionType || DEFAULT_MOCK_SUBSCRIPTION
return null
}
// Export a function that checks if we should use mock subscription
export function shouldUseMockSubscription(): boolean {
return (
mockEnabled &&
mockSubscriptionType !== null &&
process.env.USER_TYPE === 'ant'
)
return false
}
// Mock billing access (admin vs non-admin)
export function setMockBillingAccess(hasAccess: boolean | null): void {
if (process.env.USER_TYPE !== 'ant') {
return
}
mockEnabled = true
setMockBillingAccessOverride(hasAccess)
export function setMockBillingAccess(_hasAccess: boolean | null): void {
// External build: internal mock billing access overrides are disabled.
}
// Mock fast mode rate limit handling
export function isMockFastModeRateLimitScenario(): boolean {
return mockFastModeRateLimitDurationMs !== null
return false
}
export function checkMockFastModeRateLimit(
isFastModeActive?: boolean,
_isFastModeActive?: boolean,
): MockHeaders | null {
if (mockFastModeRateLimitDurationMs === null) {
return null
}
// Only throw when fast mode is active
if (!isFastModeActive) {
return null
}
// Check if the rate limit has expired
if (
mockFastModeRateLimitExpiresAt !== null &&
Date.now() >= mockFastModeRateLimitExpiresAt
) {
clearMockHeaders()
return null
}
// Set expiry on first error (not when scenario is configured)
if (mockFastModeRateLimitExpiresAt === null) {
mockFastModeRateLimitExpiresAt =
Date.now() + mockFastModeRateLimitDurationMs
}
// Compute dynamic retry-after based on remaining time
const remainingMs = mockFastModeRateLimitExpiresAt - Date.now()
const headersToSend = { ...mockHeaders }
headersToSend['retry-after'] = String(
Math.max(1, Math.ceil(remainingMs / 1000)),
)
return headersToSend
return null
}

View File

@@ -645,7 +645,7 @@ const internalOnlyTips: Tip[] =
{
id: 'skillify',
content: async () =>
'[internal] Use /skillify at the end of a workflow to turn it into a reusable skill',
'[internal] Turn repeatable workflows into reusable project skills when they keep recurring',
cooldownSessions: 15,
isRelevant: async () => true,
},