sidekick-shared 0.28.2 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/README.md +176 -30
- package/dist/authStatus.d.ts +54 -0
- package/dist/authStatus.js +91 -0
- package/dist/browser.d.ts +14 -6
- package/dist/browser.js +26 -1
- package/dist/codex.d.ts +23 -0
- package/dist/codex.js +44 -0
- package/dist/codexProfiles.d.ts +1 -0
- package/dist/codexProfiles.js +8 -11
- package/dist/codexQuota.js +17 -4
- package/dist/esm/authStatus.js +87 -0
- package/dist/esm/browser.js +6 -2
- package/dist/esm/codex.js +18 -0
- package/dist/esm/codexProfiles.js +8 -11
- package/dist/esm/codexQuota.js +18 -5
- package/dist/esm/formatting.js +10 -1
- package/dist/esm/index.js +12 -9
- package/dist/esm/modelCatalog.js +2 -1
- package/dist/esm/modelInfo.js +422 -45
- package/dist/esm/multiProviderQuotaService.js +1 -1
- package/dist/esm/node.js +9 -3
- package/dist/esm/parsers/codexParser.js +175 -54
- package/dist/esm/parsers/codexRolloutOrigin.js +107 -0
- package/dist/esm/parsers/openCodeParser.js +83 -21
- package/dist/esm/pricing.js +18 -0
- package/dist/esm/pricingCatalog.js +14 -7
- package/dist/esm/promptHistory.js +66 -4
- package/dist/esm/providerFailure.js +124 -3
- package/dist/esm/providers/codex.js +2 -24
- package/dist/esm/providers/codexDatabase.js +3 -19
- package/dist/esm/providers/codexRollouts.js +24 -1
- package/dist/esm/providers/openCode.js +9 -17
- package/dist/esm/quota.js +356 -24
- package/dist/esm/quotaHistory.js +33 -8
- package/dist/esm/quotaPoller.js +5 -2
- package/dist/esm/quotaResolver.js +31 -6
- package/dist/esm/quotaSnapshots.js +65 -10
- package/dist/esm/quotaThresholds.js +7 -2
- package/dist/esm/report/htmlReportGenerator.js +42 -5
- package/dist/esm/report/transcriptParser.js +13 -11
- package/dist/esm/schemas/index.js +2 -2
- package/dist/esm/schemas/providerFailure.js +3 -1
- package/dist/esm/schemas/quota.js +30 -0
- package/dist/esm/schemas/quotaHistory.js +10 -2
- package/dist/esm/schemas/stateFile.js +9 -0
- package/dist/esm/schemas/transcript.js +4 -0
- package/dist/esm/sessionPromptHistory.js +2 -2
- package/dist/esm/stateFile.js +18 -3
- package/dist/esm/statusline/claudeStatuslinePayload.js +16 -4
- package/dist/esm/statusline/formatter.js +57 -18
- package/dist/esm/statusline/index.js +2 -2
- package/dist/esm/statusline/payload.js +9 -0
- package/dist/esm/testing/credentialGuard.js +87 -5
- package/dist/esm/toolCallOrigins.js +310 -0
- package/dist/esm/transcript.js +42 -3
- package/dist/esm/usage/usageEvents.js +146 -17
- package/dist/esm/usage/usageReports.js +39 -6
- package/dist/esm/watchers/jsonlTail.js +378 -59
- package/dist/esm/zaiQuotaApi.js +4 -2
- package/dist/formatting.d.ts +26 -1
- package/dist/formatting.js +11 -1
- package/dist/index.d.ts +22 -16
- package/dist/index.js +48 -12
- package/dist/modelCatalog.js +2 -1
- package/dist/modelInfo.d.ts +185 -16
- package/dist/modelInfo.js +431 -47
- package/dist/multiProviderQuotaService.js +1 -1
- package/dist/node.d.ts +16 -5
- package/dist/node.js +31 -2
- package/dist/parsers/codexParser.d.ts +55 -0
- package/dist/parsers/codexParser.js +175 -54
- package/dist/parsers/codexRolloutOrigin.d.ts +49 -0
- package/dist/parsers/codexRolloutOrigin.js +111 -0
- package/dist/parsers/openCodeParser.d.ts +38 -0
- package/dist/parsers/openCodeParser.js +86 -21
- package/dist/pricing.d.ts +22 -0
- package/dist/pricing.js +50 -0
- package/dist/pricingCatalog.d.ts +10 -0
- package/dist/pricingCatalog.js +13 -6
- package/dist/promptHistory.d.ts +65 -4
- package/dist/promptHistory.js +68 -5
- package/dist/providerFailure.d.ts +44 -0
- package/dist/providerFailure.js +126 -4
- package/dist/providers/codex.d.ts +3 -22
- package/dist/providers/codex.js +3 -26
- package/dist/providers/codexDatabase.d.ts +3 -2
- package/dist/providers/codexDatabase.js +4 -22
- package/dist/providers/codexRollouts.d.ts +22 -0
- package/dist/providers/codexRollouts.js +24 -0
- package/dist/providers/openCode.js +8 -16
- package/dist/quota.d.ts +131 -1
- package/dist/quota.js +366 -24
- package/dist/quotaHistory.d.ts +10 -0
- package/dist/quotaHistory.js +34 -8
- package/dist/quotaPoller.d.ts +11 -3
- package/dist/quotaPoller.js +5 -2
- package/dist/quotaResolver.js +30 -5
- package/dist/quotaSnapshots.js +64 -9
- package/dist/quotaThresholds.js +7 -2
- package/dist/report/htmlReportGenerator.js +42 -5
- package/dist/report/transcriptParser.d.ts +10 -1
- package/dist/report/transcriptParser.js +13 -11
- package/dist/schemas/index.d.ts +3 -3
- package/dist/schemas/index.js +5 -2
- package/dist/schemas/providerFailure.d.ts +39 -0
- package/dist/schemas/providerFailure.js +2 -0
- package/dist/schemas/quota.d.ts +258 -0
- package/dist/schemas/quota.js +31 -1
- package/dist/schemas/quotaHistory.d.ts +2 -0
- package/dist/schemas/quotaHistory.js +10 -2
- package/dist/schemas/stateFile.d.ts +34 -0
- package/dist/schemas/stateFile.js +10 -1
- package/dist/schemas/transcript.d.ts +2 -0
- package/dist/schemas/transcript.js +4 -0
- package/dist/sessionPromptHistory.d.ts +7 -1
- package/dist/sessionPromptHistory.js +1 -1
- package/dist/stateFile.d.ts +18 -0
- package/dist/stateFile.js +17 -2
- package/dist/statusline/claudeStatuslinePayload.d.ts +4 -3
- package/dist/statusline/claudeStatuslinePayload.js +16 -4
- package/dist/statusline/formatter.d.ts +5 -0
- package/dist/statusline/formatter.js +56 -17
- package/dist/statusline/index.d.ts +4 -4
- package/dist/statusline/index.js +5 -1
- package/dist/statusline/payload.d.ts +10 -0
- package/dist/statusline/payload.js +14 -0
- package/dist/testing/credentialGuard.d.ts +14 -0
- package/dist/testing/credentialGuard.js +87 -5
- package/dist/toolCallOrigins.d.ts +70 -0
- package/dist/toolCallOrigins.js +346 -0
- package/dist/transcript.d.ts +12 -0
- package/dist/transcript.js +42 -3
- package/dist/types/opencode.d.ts +2 -0
- package/dist/usage/usageEvents.d.ts +54 -6
- package/dist/usage/usageEvents.js +146 -17
- package/dist/usage/usageReports.d.ts +35 -4
- package/dist/usage/usageReports.js +39 -6
- package/dist/watchers/jsonlTail.d.ts +101 -4
- package/dist/watchers/jsonlTail.js +380 -60
- package/dist/zaiQuotaApi.js +3 -1
- package/package.json +41 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure parsers for the provider CLIs' read-only sign-in status commands,
|
|
4
|
+
* `claude auth status --json` and `codex login status`. They do no I/O. The
|
|
5
|
+
* caller runs the command with its own environment, home, and timeout, and
|
|
6
|
+
* passes the output here.
|
|
7
|
+
*
|
|
8
|
+
* A status command reports which credential the CLI would use. It does not
|
|
9
|
+
* prove that a request will authenticate: an expired or revoked token can
|
|
10
|
+
* still read as logged in.
|
|
11
|
+
*
|
|
12
|
+
* @module authStatus
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.parseClaudeAuthStatus = parseClaudeAuthStatus;
|
|
16
|
+
exports.parseCodexLoginStatus = parseCodexLoginStatus;
|
|
17
|
+
/** Larger outputs are not a status report; reading stops there. */
|
|
18
|
+
const MAX_STATUS_OUTPUT = 256 * 1024;
|
|
19
|
+
const MAX_DETAIL = 200;
|
|
20
|
+
function stringField(record, key) {
|
|
21
|
+
const value = record[key];
|
|
22
|
+
if (typeof value !== 'string')
|
|
23
|
+
return undefined;
|
|
24
|
+
const trimmed = value.trim();
|
|
25
|
+
return trimmed && trimmed.length <= 512 ? trimmed : undefined;
|
|
26
|
+
}
|
|
27
|
+
function parseJsonObject(output) {
|
|
28
|
+
const trimmed = output.trim();
|
|
29
|
+
const candidates = [trimmed];
|
|
30
|
+
// Tolerate warning lines printed ahead of the JSON document, which must
|
|
31
|
+
// then start a line and run to the end of the output.
|
|
32
|
+
const start = trimmed.search(/\n[ \t]*\{/);
|
|
33
|
+
if (start >= 0)
|
|
34
|
+
candidates.push(trimmed.slice(start).trim());
|
|
35
|
+
for (const candidate of candidates) {
|
|
36
|
+
if (!candidate.startsWith('{') || !candidate.endsWith('}'))
|
|
37
|
+
continue;
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(candidate);
|
|
40
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
/* Try the next candidate. */
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse the stdout of `claude auth status --json`. Claude Code exits 1 while
|
|
51
|
+
* printing valid signed-out JSON, so parse stdout whatever the exit status
|
|
52
|
+
* was. Only a JSON `"loggedIn": true` counts as logged in.
|
|
53
|
+
*/
|
|
54
|
+
function parseClaudeAuthStatus(stdout) {
|
|
55
|
+
const raw = typeof stdout === 'string' && stdout.length <= MAX_STATUS_OUTPUT
|
|
56
|
+
? parseJsonObject(stdout)
|
|
57
|
+
: undefined;
|
|
58
|
+
if (!raw)
|
|
59
|
+
return { loggedIn: false };
|
|
60
|
+
const method = stringField(raw, 'authMethod');
|
|
61
|
+
const email = stringField(raw, 'email');
|
|
62
|
+
const subscriptionType = stringField(raw, 'subscriptionType');
|
|
63
|
+
return {
|
|
64
|
+
loggedIn: raw.loggedIn === true,
|
|
65
|
+
...(method ? { method } : {}),
|
|
66
|
+
...(email ? { email } : {}),
|
|
67
|
+
...(subscriptionType ? { subscriptionType } : {}),
|
|
68
|
+
raw,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse the output of `codex login status`. Codex prints its status line to
|
|
73
|
+
* stderr (`Logged in using ChatGPT`, `Logged in using an API key - sk-…`,
|
|
74
|
+
* `Not logged in`), so pass both streams. The exit status is not consulted:
|
|
75
|
+
* callers that require exit 0 check it themselves.
|
|
76
|
+
*/
|
|
77
|
+
function parseCodexLoginStatus(stdout, stderr) {
|
|
78
|
+
const combined = `${typeof stdout === 'string' ? stdout : ''}\n${typeof stderr === 'string' ? stderr : ''}`.trim();
|
|
79
|
+
const firstLine = combined.split(/\r?\n/, 1)[0]?.trim() ?? '';
|
|
80
|
+
const detail = (/^(Logged in using .*?API key)\s+-\s.*$/i.exec(firstLine)?.[1] ?? firstLine)
|
|
81
|
+
.slice(0, MAX_DETAIL)
|
|
82
|
+
.trim();
|
|
83
|
+
const withDetail = detail ? { detail } : {};
|
|
84
|
+
if (!/^Logged in/i.test(combined))
|
|
85
|
+
return { loggedIn: false, ...withDetail };
|
|
86
|
+
if (/API key/i.test(combined))
|
|
87
|
+
return { loggedIn: true, method: 'api-key', ...withDetail };
|
|
88
|
+
if (/ChatGPT/i.test(combined))
|
|
89
|
+
return { loggedIn: true, method: 'chatgpt', ...withDetail };
|
|
90
|
+
return { loggedIn: true, ...withDetail };
|
|
91
|
+
}
|
package/dist/browser.d.ts
CHANGED
|
@@ -24,12 +24,14 @@ export { parseMcpToolName } from './parsers/mcpToolName';
|
|
|
24
24
|
export type { McpToolNameParts } from './parsers/mcpToolName';
|
|
25
25
|
export { buildSessionContextSnapshot, calculateSessionContextPressure, createSessionContextProjector, } from './context/sessionContext';
|
|
26
26
|
export { ACCOUNT_PROVIDER_IDS, MODEL_PROVIDER_IDS, QUOTA_PROVIDER_IDS, RUNTIME_QUOTA_PROVIDER_IDS, SESSION_PROVIDER_IDS, } from './providerIds';
|
|
27
|
-
export type { AccountProviderId, ModelProviderId, QuotaProviderId, RuntimeQuotaProviderId, SessionProviderId,
|
|
27
|
+
export type { AccountProviderId, ModelProviderId, QuotaProviderId, RuntimeQuotaProviderId, SessionProviderId,
|
|
28
|
+
/** Same type as `ProviderId` from the package root and `sidekick-shared/node`. */
|
|
29
|
+
SessionProviderId as ProviderId, } from './providerIds';
|
|
28
30
|
export type { BuildSessionContextSnapshotOptions, SessionContextCapabilities, SessionContextLayerBreakdown, SessionContextPressure, SessionContextProjector, SessionContextSnapshot, SessionContextSource, SessionContextSourceType, } from './context/sessionContext';
|
|
29
31
|
export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
|
|
30
32
|
export type { AssistantTurnEvent, AssistantTurnEventType, AssistantTurnProcess, AssistantTurnProcessStep, AssistantTurnProjection, AssistantTurnSubagent, AssistantTurnSubagentStatus, AssistantTurnTimelineItem, AssistantTurnToolRef, ExtractTurnSubagentsOptions, ReasoningSummary, SegmentAssistantTurnOptions, } from './turns/assistantTurn';
|
|
31
|
-
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, } from './modelInfo';
|
|
32
|
-
export type { ModelPricing, CostTokenUsage, CostSource, CostProvenanceInput, CostWithProvenance, ModelProvider, ParsedModelId, ModelInfo, ModelDisplayInfo, ModelPricingMatch, ModelPricingProvenance, ModelPricingSource, ResolvedModelPricing, } from './modelInfo';
|
|
33
|
+
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, canonicalModelId, isMovingModelAlias, registerModelPricing, clearRegisteredModelPricing, getPricingCatalogInfo, costSourceFromPricingProvenance, mergeCostComponents, } from './modelInfo';
|
|
34
|
+
export type { ModelPricing, ResolveModelPricingOptions, RegisterModelPricingOptions, PricingCatalogInfo, PricingCatalogSource, CostComponent, FormatCostOptions, CostTokenUsage, CostSource, CostProvenanceInput, CostWithProvenance, ModelProvider, ParsedModelId, ModelInfo, ModelDisplayInfo, ModelPricingMatch, ModelPricingProvenance, ModelPricingSource, ResolvedModelPricing, } from './modelInfo';
|
|
33
35
|
export { exportResolvedModelCatalog, importResolvedModelCatalog, registerModelAlias, resolveModelAlias, RESOLVED_MODEL_CATALOG_SCHEMA_VERSION, } from './modelCatalog';
|
|
34
36
|
export type { ImportResolvedModelCatalogResult, ResolvedModelCatalogEntry, ResolvedModelCatalogSnapshot, } from './modelCatalog';
|
|
35
37
|
export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock, } from './usage/billingBlocks';
|
|
@@ -40,17 +42,23 @@ export { applySessionSummary, isFileImported, markFileImported, removeSessionSum
|
|
|
40
42
|
export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
|
|
41
43
|
export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
|
|
42
44
|
export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';
|
|
43
|
-
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, } from './providerFailure';
|
|
44
|
-
export
|
|
45
|
+
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, CODEX_ERROR_INFO_KINDS, decodeCodexErrorInfo, } from './providerFailure';
|
|
46
|
+
export { parseClaudeAuthStatus, parseCodexLoginStatus } from './authStatus';
|
|
47
|
+
export type { ParsedClaudeAuthStatus, ParsedCodexLoginStatus } from './authStatus';
|
|
48
|
+
export type { CodexErrorInfoKind, CodexErrorInfoSummary, ProviderCredentialKind, ProviderAuthenticationEvidence, ProviderFailureInput, ProviderFailureCode, ProviderRecoveryAction, ProviderRetryAfter, ProviderFailureEvidence, ProviderFailureDiagnosis, } from './providerFailure';
|
|
45
49
|
export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
|
|
46
50
|
export type { SessionEvent, ClaudeSessionEvent, MessageUsage, SessionMessage, SessionEventBase, MessageSessionEvent, UserSessionEvent, AssistantSessionEvent, SummarySessionEvent, SystemSessionEvent, ToolUseSessionEvent, ToolResultSessionEvent, TokenUsage, ToolCall, ToolAnalytics, TimelineEvent, PendingToolCall, TaskStatus as SessionTaskStatus, TrackedTask, TaskState, SubagentStats, PendingUserRequest, ResponseLatency, LatencyStats, PlanStep, PlanState, SessionStats, CompactionEvent, TruncationEvent, ContextAttribution, TurnAttribution, ContextSizePoint, PermissionMode, PermissionModeChange, } from './types/sessionEvent';
|
|
47
51
|
export type { CodexRolloutLine, CodexSessionMeta, CodexResponseItem, CodexMessageItem, CodexContentPart, CodexReasoningItem, CodexFunctionCallItem, CodexFunctionCallOutputItem, CodexLocalShellCallItem, CodexWebSearchCallItem, CodexCustomToolCallItem, CodexCustomToolCallOutputItem, CodexCompacted, CodexTurnContext, CodexEventMsg, CodexEvent, CodexTurnStartedEvent, CodexTurnCompleteEvent, CodexTaskStartedEvent, CodexTaskCompleteEvent, CodexTurnAbortedEvent, CodexTokenCountEvent, CodexTokenUsage, CodexRateLimits, CodexAgentMessageEvent, CodexAgentReasoningEvent, CodexUserMessageEvent, CodexExecCommandBeginEvent, CodexExecCommandEndEvent, CodexMcpToolCallBeginEvent, CodexMcpToolCallEndEvent, CodexErrorEvent, CodexContextCompactedEvent, CodexPatchAppliedEvent, CodexBackgroundEvent, CodexGenericEvent, CodexDbThread, CodexReasoningSummary, } from './types/codex';
|
|
48
52
|
export { isAggregateCodexLimit } from './types/codex';
|
|
49
53
|
export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
|
|
50
|
-
export type { CodexRolloutParserOptions } from './parsers/codexParser';
|
|
54
|
+
export type { CodexPendingStats, CodexRolloutParserOptions } from './parsers/codexParser';
|
|
55
|
+
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
56
|
+
export type { CodexRolloutOrigin } from './parsers/codexRolloutOrigin';
|
|
51
57
|
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
|
52
58
|
export type { HumanPromptProvider } from './humanPrompt';
|
|
53
59
|
export { renderHandoffUrlTemplate } from './handoffUrl';
|
|
54
60
|
export type { HandoffUrlIdentifiers } from './handoffUrl';
|
|
55
61
|
export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
56
62
|
export type { ClassifyToolOptions, ToolCategory } from './toolCategory';
|
|
63
|
+
export { claudePlanLabel, extraQuotaRows, formatExtraUsage, quotaWindowApplies, quotaWindowHasData, quotaWindowLabel, quotaWindowShortLabel, } from './quota';
|
|
64
|
+
export type { QuotaExtraUsage, QuotaLimitRow, QuotaWindow } from './quota';
|
package/dist/browser.js
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.ASCII_CHARS_PER_TOKEN = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
|
|
13
|
-
exports.
|
|
13
|
+
exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.codexSpawnParentFromSource = exports.codexRolloutOrigin = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.DEFAULT_MAX_TRACKED_TOOL_CALLS = exports.CodexRolloutParser = exports.isAggregateCodexLimit = exports.parseCodexLoginStatus = exports.parseClaudeAuthStatus = exports.decodeCodexErrorInfo = exports.CODEX_ERROR_INFO_KINDS = exports.PROVIDER_RECOVERY_ACTIONS = exports.PROVIDER_FAILURE_EVIDENCE_SOURCES = exports.PROVIDER_FAILURE_CODES = exports.PROVIDER_CREDENTIAL_KINDS = exports.PROVIDER_AUTHENTICATION_STATES = exports.PROVIDER_AUTHENTICATION_SOURCES = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.mergeCostComponents = exports.costSourceFromPricingProvenance = exports.getPricingCatalogInfo = exports.clearRegisteredModelPricing = exports.registerModelPricing = exports.isMovingModelAlias = exports.canonicalModelId = exports.formatCost = exports.sortModelIds = void 0;
|
|
14
|
+
exports.quotaWindowShortLabel = exports.quotaWindowLabel = exports.quotaWindowHasData = exports.quotaWindowApplies = exports.formatExtraUsage = exports.extraQuotaRows = exports.claudePlanLabel = exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = void 0;
|
|
14
15
|
var modelContext_1 = require("./modelContext");
|
|
15
16
|
Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
|
|
16
17
|
Object.defineProperty(exports, "resolveModelContextWindow", { enumerable: true, get: function () { return modelContext_1.resolveModelContextWindow; } });
|
|
@@ -75,6 +76,13 @@ Object.defineProperty(exports, "getModelDisplayInfo", { enumerable: true, get: f
|
|
|
75
76
|
Object.defineProperty(exports, "compareModelIds", { enumerable: true, get: function () { return modelInfo_1.compareModelIds; } });
|
|
76
77
|
Object.defineProperty(exports, "sortModelIds", { enumerable: true, get: function () { return modelInfo_1.sortModelIds; } });
|
|
77
78
|
Object.defineProperty(exports, "formatCost", { enumerable: true, get: function () { return modelInfo_1.formatCost; } });
|
|
79
|
+
Object.defineProperty(exports, "canonicalModelId", { enumerable: true, get: function () { return modelInfo_1.canonicalModelId; } });
|
|
80
|
+
Object.defineProperty(exports, "isMovingModelAlias", { enumerable: true, get: function () { return modelInfo_1.isMovingModelAlias; } });
|
|
81
|
+
Object.defineProperty(exports, "registerModelPricing", { enumerable: true, get: function () { return modelInfo_1.registerModelPricing; } });
|
|
82
|
+
Object.defineProperty(exports, "clearRegisteredModelPricing", { enumerable: true, get: function () { return modelInfo_1.clearRegisteredModelPricing; } });
|
|
83
|
+
Object.defineProperty(exports, "getPricingCatalogInfo", { enumerable: true, get: function () { return modelInfo_1.getPricingCatalogInfo; } });
|
|
84
|
+
Object.defineProperty(exports, "costSourceFromPricingProvenance", { enumerable: true, get: function () { return modelInfo_1.costSourceFromPricingProvenance; } });
|
|
85
|
+
Object.defineProperty(exports, "mergeCostComponents", { enumerable: true, get: function () { return modelInfo_1.mergeCostComponents; } });
|
|
78
86
|
var modelCatalog_1 = require("./modelCatalog");
|
|
79
87
|
Object.defineProperty(exports, "exportResolvedModelCatalog", { enumerable: true, get: function () { return modelCatalog_1.exportResolvedModelCatalog; } });
|
|
80
88
|
Object.defineProperty(exports, "importResolvedModelCatalog", { enumerable: true, get: function () { return modelCatalog_1.importResolvedModelCatalog; } });
|
|
@@ -108,6 +116,11 @@ Object.defineProperty(exports, "PROVIDER_CREDENTIAL_KINDS", { enumerable: true,
|
|
|
108
116
|
Object.defineProperty(exports, "PROVIDER_FAILURE_CODES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_FAILURE_CODES; } });
|
|
109
117
|
Object.defineProperty(exports, "PROVIDER_FAILURE_EVIDENCE_SOURCES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_FAILURE_EVIDENCE_SOURCES; } });
|
|
110
118
|
Object.defineProperty(exports, "PROVIDER_RECOVERY_ACTIONS", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_RECOVERY_ACTIONS; } });
|
|
119
|
+
Object.defineProperty(exports, "CODEX_ERROR_INFO_KINDS", { enumerable: true, get: function () { return providerFailure_1.CODEX_ERROR_INFO_KINDS; } });
|
|
120
|
+
Object.defineProperty(exports, "decodeCodexErrorInfo", { enumerable: true, get: function () { return providerFailure_1.decodeCodexErrorInfo; } });
|
|
121
|
+
var authStatus_1 = require("./authStatus");
|
|
122
|
+
Object.defineProperty(exports, "parseClaudeAuthStatus", { enumerable: true, get: function () { return authStatus_1.parseClaudeAuthStatus; } });
|
|
123
|
+
Object.defineProperty(exports, "parseCodexLoginStatus", { enumerable: true, get: function () { return authStatus_1.parseCodexLoginStatus; } });
|
|
111
124
|
var codex_1 = require("./types/codex");
|
|
112
125
|
Object.defineProperty(exports, "isAggregateCodexLimit", { enumerable: true, get: function () { return codex_1.isAggregateCodexLimit; } });
|
|
113
126
|
// Codex rollout parsing (pure: no filesystem access)
|
|
@@ -118,6 +131,9 @@ Object.defineProperty(exports, "extractPatchFilePaths", { enumerable: true, get:
|
|
|
118
131
|
Object.defineProperty(exports, "normalizeCodexToolName", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolName; } });
|
|
119
132
|
Object.defineProperty(exports, "normalizeCodexToolInput", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolInput; } });
|
|
120
133
|
Object.defineProperty(exports, "resolveCodexCallUsage", { enumerable: true, get: function () { return codexParser_1.resolveCodexCallUsage; } });
|
|
134
|
+
var codexRolloutOrigin_1 = require("./parsers/codexRolloutOrigin");
|
|
135
|
+
Object.defineProperty(exports, "codexRolloutOrigin", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexRolloutOrigin; } });
|
|
136
|
+
Object.defineProperty(exports, "codexSpawnParentFromSource", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexSpawnParentFromSource; } });
|
|
121
137
|
var humanPrompt_1 = require("./humanPrompt");
|
|
122
138
|
Object.defineProperty(exports, "HUMAN_CLAUDE_ENTRYPOINTS", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CLAUDE_ENTRYPOINTS; } });
|
|
123
139
|
Object.defineProperty(exports, "HUMAN_CODEX_SOURCES", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CODEX_SOURCES; } });
|
|
@@ -129,3 +145,12 @@ Object.defineProperty(exports, "renderHandoffUrlTemplate", { enumerable: true, g
|
|
|
129
145
|
var toolCategory_1 = require("./toolCategory");
|
|
130
146
|
Object.defineProperty(exports, "classifyTool", { enumerable: true, get: function () { return toolCategory_1.classifyTool; } });
|
|
131
147
|
Object.defineProperty(exports, "TOOL_CATEGORIES", { enumerable: true, get: function () { return toolCategory_1.TOOL_CATEGORIES; } });
|
|
148
|
+
// Quota window helpers (pure; safe for webviews)
|
|
149
|
+
var quota_1 = require("./quota");
|
|
150
|
+
Object.defineProperty(exports, "claudePlanLabel", { enumerable: true, get: function () { return quota_1.claudePlanLabel; } });
|
|
151
|
+
Object.defineProperty(exports, "extraQuotaRows", { enumerable: true, get: function () { return quota_1.extraQuotaRows; } });
|
|
152
|
+
Object.defineProperty(exports, "formatExtraUsage", { enumerable: true, get: function () { return quota_1.formatExtraUsage; } });
|
|
153
|
+
Object.defineProperty(exports, "quotaWindowApplies", { enumerable: true, get: function () { return quota_1.quotaWindowApplies; } });
|
|
154
|
+
Object.defineProperty(exports, "quotaWindowHasData", { enumerable: true, get: function () { return quota_1.quotaWindowHasData; } });
|
|
155
|
+
Object.defineProperty(exports, "quotaWindowLabel", { enumerable: true, get: function () { return quota_1.quotaWindowLabel; } });
|
|
156
|
+
Object.defineProperty(exports, "quotaWindowShortLabel", { enumerable: true, get: function () { return quota_1.quotaWindowShortLabel; } });
|
package/dist/codex.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sidekick-shared/codex` — a small Node-only entry for Codex homes, the
|
|
3
|
+
* child-process environment, `auth.json` helpers, credential-store mode,
|
|
4
|
+
* rollout lookup, and the atomic JSON writers those helpers rely on.
|
|
5
|
+
*
|
|
6
|
+
* Loads a handful of modules and no Zod, so a host that only launches or
|
|
7
|
+
* locates Codex does not pay for the full `sidekick-shared/node` surface.
|
|
8
|
+
* Everything here is also exported from the package root and from
|
|
9
|
+
* `sidekick-shared/node`.
|
|
10
|
+
*
|
|
11
|
+
* @module codex
|
|
12
|
+
*/
|
|
13
|
+
export { getSystemCodexHome, resolveSidekickCodexHome, getCodexExecutionEnv, getCodexMonitoringHomes, getCodexSessionsDirs, getCodexCredentialStoreMode, forceFileCredentialStore, CODEX_SESSIONS_SUBDIR, CODEX_ARCHIVED_SESSIONS_SUBDIR, } from './codexPaths';
|
|
14
|
+
export type { CodexCredentialStoreMode, CodexSessionsDirsOptions } from './codexPaths';
|
|
15
|
+
export { parseAuthJson as parseCodexAuthJson, readAuthIdentityFromRaw as readCodexAuthIdentity, readLastRefresh as readCodexLastRefresh, readAccessTokenExpiry as readCodexAccessTokenExpiry, identitiesMatch as codexIdentitiesMatch, codexRefreshFingerprint, compareCodexAuthFreshness, } from './codexAuth';
|
|
16
|
+
export type { CodexAuthIdentity, CodexAuthJsonFile } from './codexAuth';
|
|
17
|
+
export { findCodexRolloutFile } from './providers/codexRollouts';
|
|
18
|
+
export type { FindCodexRolloutFileOptions } from './providers/codexRollouts';
|
|
19
|
+
export { atomicWriteJson, atomicWriteJsonSync } from './writers/atomic';
|
|
20
|
+
export { parseClaudeAuthStatus, parseCodexLoginStatus } from './authStatus';
|
|
21
|
+
export type { ParsedClaudeAuthStatus, ParsedCodexLoginStatus } from './authStatus';
|
|
22
|
+
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
23
|
+
export type { CodexRolloutOrigin } from './parsers/codexRolloutOrigin';
|
package/dist/codex.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `sidekick-shared/codex` — a small Node-only entry for Codex homes, the
|
|
4
|
+
* child-process environment, `auth.json` helpers, credential-store mode,
|
|
5
|
+
* rollout lookup, and the atomic JSON writers those helpers rely on.
|
|
6
|
+
*
|
|
7
|
+
* Loads a handful of modules and no Zod, so a host that only launches or
|
|
8
|
+
* locates Codex does not pay for the full `sidekick-shared/node` surface.
|
|
9
|
+
* Everything here is also exported from the package root and from
|
|
10
|
+
* `sidekick-shared/node`.
|
|
11
|
+
*
|
|
12
|
+
* @module codex
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.codexSpawnParentFromSource = exports.codexRolloutOrigin = exports.parseCodexLoginStatus = exports.parseClaudeAuthStatus = exports.atomicWriteJsonSync = exports.atomicWriteJson = exports.findCodexRolloutFile = exports.compareCodexAuthFreshness = exports.codexRefreshFingerprint = exports.codexIdentitiesMatch = exports.readCodexAccessTokenExpiry = exports.readCodexLastRefresh = exports.readCodexAuthIdentity = exports.parseCodexAuthJson = exports.CODEX_ARCHIVED_SESSIONS_SUBDIR = exports.CODEX_SESSIONS_SUBDIR = exports.forceFileCredentialStore = exports.getCodexCredentialStoreMode = exports.getCodexSessionsDirs = exports.getCodexMonitoringHomes = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.getSystemCodexHome = void 0;
|
|
16
|
+
var codexPaths_1 = require("./codexPaths");
|
|
17
|
+
Object.defineProperty(exports, "getSystemCodexHome", { enumerable: true, get: function () { return codexPaths_1.getSystemCodexHome; } });
|
|
18
|
+
Object.defineProperty(exports, "resolveSidekickCodexHome", { enumerable: true, get: function () { return codexPaths_1.resolveSidekickCodexHome; } });
|
|
19
|
+
Object.defineProperty(exports, "getCodexExecutionEnv", { enumerable: true, get: function () { return codexPaths_1.getCodexExecutionEnv; } });
|
|
20
|
+
Object.defineProperty(exports, "getCodexMonitoringHomes", { enumerable: true, get: function () { return codexPaths_1.getCodexMonitoringHomes; } });
|
|
21
|
+
Object.defineProperty(exports, "getCodexSessionsDirs", { enumerable: true, get: function () { return codexPaths_1.getCodexSessionsDirs; } });
|
|
22
|
+
Object.defineProperty(exports, "getCodexCredentialStoreMode", { enumerable: true, get: function () { return codexPaths_1.getCodexCredentialStoreMode; } });
|
|
23
|
+
Object.defineProperty(exports, "forceFileCredentialStore", { enumerable: true, get: function () { return codexPaths_1.forceFileCredentialStore; } });
|
|
24
|
+
Object.defineProperty(exports, "CODEX_SESSIONS_SUBDIR", { enumerable: true, get: function () { return codexPaths_1.CODEX_SESSIONS_SUBDIR; } });
|
|
25
|
+
Object.defineProperty(exports, "CODEX_ARCHIVED_SESSIONS_SUBDIR", { enumerable: true, get: function () { return codexPaths_1.CODEX_ARCHIVED_SESSIONS_SUBDIR; } });
|
|
26
|
+
var codexAuth_1 = require("./codexAuth");
|
|
27
|
+
Object.defineProperty(exports, "parseCodexAuthJson", { enumerable: true, get: function () { return codexAuth_1.parseAuthJson; } });
|
|
28
|
+
Object.defineProperty(exports, "readCodexAuthIdentity", { enumerable: true, get: function () { return codexAuth_1.readAuthIdentityFromRaw; } });
|
|
29
|
+
Object.defineProperty(exports, "readCodexLastRefresh", { enumerable: true, get: function () { return codexAuth_1.readLastRefresh; } });
|
|
30
|
+
Object.defineProperty(exports, "readCodexAccessTokenExpiry", { enumerable: true, get: function () { return codexAuth_1.readAccessTokenExpiry; } });
|
|
31
|
+
Object.defineProperty(exports, "codexIdentitiesMatch", { enumerable: true, get: function () { return codexAuth_1.identitiesMatch; } });
|
|
32
|
+
Object.defineProperty(exports, "codexRefreshFingerprint", { enumerable: true, get: function () { return codexAuth_1.codexRefreshFingerprint; } });
|
|
33
|
+
Object.defineProperty(exports, "compareCodexAuthFreshness", { enumerable: true, get: function () { return codexAuth_1.compareCodexAuthFreshness; } });
|
|
34
|
+
var codexRollouts_1 = require("./providers/codexRollouts");
|
|
35
|
+
Object.defineProperty(exports, "findCodexRolloutFile", { enumerable: true, get: function () { return codexRollouts_1.findCodexRolloutFile; } });
|
|
36
|
+
var atomic_1 = require("./writers/atomic");
|
|
37
|
+
Object.defineProperty(exports, "atomicWriteJson", { enumerable: true, get: function () { return atomic_1.atomicWriteJson; } });
|
|
38
|
+
Object.defineProperty(exports, "atomicWriteJsonSync", { enumerable: true, get: function () { return atomic_1.atomicWriteJsonSync; } });
|
|
39
|
+
var authStatus_1 = require("./authStatus");
|
|
40
|
+
Object.defineProperty(exports, "parseClaudeAuthStatus", { enumerable: true, get: function () { return authStatus_1.parseClaudeAuthStatus; } });
|
|
41
|
+
Object.defineProperty(exports, "parseCodexLoginStatus", { enumerable: true, get: function () { return authStatus_1.parseCodexLoginStatus; } });
|
|
42
|
+
var codexRolloutOrigin_1 = require("./parsers/codexRolloutOrigin");
|
|
43
|
+
Object.defineProperty(exports, "codexRolloutOrigin", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexRolloutOrigin; } });
|
|
44
|
+
Object.defineProperty(exports, "codexSpawnParentFromSource", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexSpawnParentFromSource; } });
|
package/dist/codexProfiles.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ interface CodexLoginStatus {
|
|
|
23
23
|
loggedIn: boolean;
|
|
24
24
|
authMode?: 'chatgpt' | 'api-key';
|
|
25
25
|
}
|
|
26
|
+
/** `codex login status` counts only on exit 0; the text is read by {@link parseCodexLoginStatus}. */
|
|
26
27
|
export declare function parseCodexLoginStatusOutput(status: number | null, stdout: string): CodexLoginStatus;
|
|
27
28
|
/**
|
|
28
29
|
* Blocks the caller's event loop for up to {@link PROBE_TIMEOUT_MS}. Async code
|
package/dist/codexProfiles.js
CHANGED
|
@@ -79,6 +79,7 @@ const accountRegistry_1 = require("./accountRegistry");
|
|
|
79
79
|
// re-serializing would drop fields added by newer codex versions, and the
|
|
80
80
|
// rotated refresh token inside is only valid in its freshest form.
|
|
81
81
|
const atomic_1 = require("./writers/atomic");
|
|
82
|
+
const authStatus_1 = require("./authStatus");
|
|
82
83
|
const codexAuth_1 = require("./codexAuth");
|
|
83
84
|
const codexPaths_1 = require("./codexPaths");
|
|
84
85
|
const accountHealth_1 = require("./accountHealth");
|
|
@@ -285,18 +286,14 @@ function readMetadataFromLegacyCredentials(codexHome) {
|
|
|
285
286
|
return {};
|
|
286
287
|
}
|
|
287
288
|
const PROBE_TIMEOUT_MS = 4000;
|
|
289
|
+
/** `codex login status` counts only on exit 0; the text is read by {@link parseCodexLoginStatus}. */
|
|
288
290
|
function parseCodexLoginStatusOutput(status, stdout) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return { loggedIn: true, authMode: 'chatgpt' };
|
|
296
|
-
}
|
|
297
|
-
return { loggedIn: true };
|
|
298
|
-
}
|
|
299
|
-
return { loggedIn: false };
|
|
291
|
+
if (status !== 0)
|
|
292
|
+
return { loggedIn: false };
|
|
293
|
+
const parsed = (0, authStatus_1.parseCodexLoginStatus)(stdout);
|
|
294
|
+
if (!parsed.loggedIn)
|
|
295
|
+
return { loggedIn: false };
|
|
296
|
+
return parsed.method ? { loggedIn: true, authMode: parsed.method } : { loggedIn: true };
|
|
300
297
|
}
|
|
301
298
|
/**
|
|
302
299
|
* Blocks the caller's event loop for up to {@link PROBE_TIMEOUT_MS}. Async code
|
package/dist/codexQuota.js
CHANGED
|
@@ -93,6 +93,11 @@ function isPreferredQuotaHit(candidate, current) {
|
|
|
93
93
|
function normalizePercent(value) {
|
|
94
94
|
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
95
95
|
}
|
|
96
|
+
function reportedWindowMs(value) {
|
|
97
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
|
98
|
+
? value * 60_000
|
|
99
|
+
: undefined;
|
|
100
|
+
}
|
|
96
101
|
function windowMinutesToMs(value, fallbackMs) {
|
|
97
102
|
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
|
98
103
|
? value * 60_000
|
|
@@ -235,26 +240,34 @@ function quotaFromCodexRateLimits(rateLimits, source = 'session', capturedAt = n
|
|
|
235
240
|
const secondary = rateLimits?.secondary;
|
|
236
241
|
if (!primary && !secondary)
|
|
237
242
|
return null;
|
|
243
|
+
const primaryMs = reportedWindowMs(primary?.window_minutes);
|
|
244
|
+
const secondaryMs = reportedWindowMs(secondary?.window_minutes);
|
|
238
245
|
return (0, quota_1.withQuotaProjections)({
|
|
246
|
+
// A plan can report one window only (e.g. a weekly primary with no
|
|
247
|
+
// secondary); the missing one is marked `absent` rather than shown as 0%.
|
|
239
248
|
fiveHour: primary
|
|
240
249
|
? {
|
|
241
250
|
utilization: normalizePercent(primary.used_percent),
|
|
242
251
|
resetsAt: timestampToIso(primary.resets_at),
|
|
252
|
+
...(primaryMs !== undefined ? { windowMs: primaryMs } : {}),
|
|
243
253
|
}
|
|
244
|
-
: { utilization: 0, resetsAt: '' },
|
|
254
|
+
: { utilization: 0, resetsAt: '', absent: true },
|
|
245
255
|
sevenDay: secondary
|
|
246
256
|
? {
|
|
247
257
|
utilization: normalizePercent(secondary.used_percent),
|
|
248
258
|
resetsAt: timestampToIso(secondary.resets_at),
|
|
259
|
+
...(secondaryMs !== undefined ? { windowMs: secondaryMs } : {}),
|
|
249
260
|
}
|
|
250
|
-
: { utilization: 0, resetsAt: '' },
|
|
261
|
+
: { utilization: 0, resetsAt: '', absent: true },
|
|
251
262
|
available: true,
|
|
252
263
|
providerId: 'codex',
|
|
253
264
|
source,
|
|
254
265
|
capturedAt,
|
|
255
266
|
stale: source === 'cache',
|
|
256
|
-
|
|
257
|
-
|
|
267
|
+
// Name each window by its reported length (`5-Hour`, `Weekly`), falling
|
|
268
|
+
// back to the positional names when the length is not reported.
|
|
269
|
+
fiveHourLabel: (0, quota_1.quotaWindowLabel)(primaryMs, 'Primary'),
|
|
270
|
+
sevenDayLabel: (0, quota_1.quotaWindowLabel)(secondaryMs, 'Secondary'),
|
|
258
271
|
limitId: rateLimits?.limit_id,
|
|
259
272
|
limitName: rateLimits?.limit_name ?? undefined,
|
|
260
273
|
credits: rateLimits?.credits,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parsers for the provider CLIs' read-only sign-in status commands,
|
|
3
|
+
* `claude auth status --json` and `codex login status`. They do no I/O. The
|
|
4
|
+
* caller runs the command with its own environment, home, and timeout, and
|
|
5
|
+
* passes the output here.
|
|
6
|
+
*
|
|
7
|
+
* A status command reports which credential the CLI would use. It does not
|
|
8
|
+
* prove that a request will authenticate: an expired or revoked token can
|
|
9
|
+
* still read as logged in.
|
|
10
|
+
*
|
|
11
|
+
* @module authStatus
|
|
12
|
+
*/
|
|
13
|
+
/** Larger outputs are not a status report; reading stops there. */
|
|
14
|
+
const MAX_STATUS_OUTPUT = 256 * 1024;
|
|
15
|
+
const MAX_DETAIL = 200;
|
|
16
|
+
function stringField(record, key) {
|
|
17
|
+
const value = record[key];
|
|
18
|
+
if (typeof value !== 'string')
|
|
19
|
+
return undefined;
|
|
20
|
+
const trimmed = value.trim();
|
|
21
|
+
return trimmed && trimmed.length <= 512 ? trimmed : undefined;
|
|
22
|
+
}
|
|
23
|
+
function parseJsonObject(output) {
|
|
24
|
+
const trimmed = output.trim();
|
|
25
|
+
const candidates = [trimmed];
|
|
26
|
+
// Tolerate warning lines printed ahead of the JSON document, which must
|
|
27
|
+
// then start a line and run to the end of the output.
|
|
28
|
+
const start = trimmed.search(/\n[ \t]*\{/);
|
|
29
|
+
if (start >= 0)
|
|
30
|
+
candidates.push(trimmed.slice(start).trim());
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
if (!candidate.startsWith('{') || !candidate.endsWith('}'))
|
|
33
|
+
continue;
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(candidate);
|
|
36
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* Try the next candidate. */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse the stdout of `claude auth status --json`. Claude Code exits 1 while
|
|
47
|
+
* printing valid signed-out JSON, so parse stdout whatever the exit status
|
|
48
|
+
* was. Only a JSON `"loggedIn": true` counts as logged in.
|
|
49
|
+
*/
|
|
50
|
+
export function parseClaudeAuthStatus(stdout) {
|
|
51
|
+
const raw = typeof stdout === 'string' && stdout.length <= MAX_STATUS_OUTPUT
|
|
52
|
+
? parseJsonObject(stdout)
|
|
53
|
+
: undefined;
|
|
54
|
+
if (!raw)
|
|
55
|
+
return { loggedIn: false };
|
|
56
|
+
const method = stringField(raw, 'authMethod');
|
|
57
|
+
const email = stringField(raw, 'email');
|
|
58
|
+
const subscriptionType = stringField(raw, 'subscriptionType');
|
|
59
|
+
return {
|
|
60
|
+
loggedIn: raw.loggedIn === true,
|
|
61
|
+
...(method ? { method } : {}),
|
|
62
|
+
...(email ? { email } : {}),
|
|
63
|
+
...(subscriptionType ? { subscriptionType } : {}),
|
|
64
|
+
raw,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse the output of `codex login status`. Codex prints its status line to
|
|
69
|
+
* stderr (`Logged in using ChatGPT`, `Logged in using an API key - sk-…`,
|
|
70
|
+
* `Not logged in`), so pass both streams. The exit status is not consulted:
|
|
71
|
+
* callers that require exit 0 check it themselves.
|
|
72
|
+
*/
|
|
73
|
+
export function parseCodexLoginStatus(stdout, stderr) {
|
|
74
|
+
const combined = `${typeof stdout === 'string' ? stdout : ''}\n${typeof stderr === 'string' ? stderr : ''}`.trim();
|
|
75
|
+
const firstLine = combined.split(/\r?\n/, 1)[0]?.trim() ?? '';
|
|
76
|
+
const detail = (/^(Logged in using .*?API key)\s+-\s.*$/i.exec(firstLine)?.[1] ?? firstLine)
|
|
77
|
+
.slice(0, MAX_DETAIL)
|
|
78
|
+
.trim();
|
|
79
|
+
const withDetail = detail ? { detail } : {};
|
|
80
|
+
if (!/^Logged in/i.test(combined))
|
|
81
|
+
return { loggedIn: false, ...withDetail };
|
|
82
|
+
if (/API key/i.test(combined))
|
|
83
|
+
return { loggedIn: true, method: 'api-key', ...withDetail };
|
|
84
|
+
if (/ChatGPT/i.test(combined))
|
|
85
|
+
return { loggedIn: true, method: 'chatgpt', ...withDetail };
|
|
86
|
+
return { loggedIn: true, ...withDetail };
|
|
87
|
+
}
|
package/dist/esm/browser.js
CHANGED
|
@@ -18,17 +18,21 @@ export { parseMcpToolName } from './parsers/mcpToolName';
|
|
|
18
18
|
export { buildSessionContextSnapshot, calculateSessionContextPressure, createSessionContextProjector, } from './context/sessionContext';
|
|
19
19
|
export { ACCOUNT_PROVIDER_IDS, MODEL_PROVIDER_IDS, QUOTA_PROVIDER_IDS, RUNTIME_QUOTA_PROVIDER_IDS, SESSION_PROVIDER_IDS, } from './providerIds';
|
|
20
20
|
export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
|
|
21
|
-
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, } from './modelInfo';
|
|
21
|
+
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, canonicalModelId, isMovingModelAlias, registerModelPricing, clearRegisteredModelPricing, getPricingCatalogInfo, costSourceFromPricingProvenance, mergeCostComponents, } from './modelInfo';
|
|
22
22
|
export { exportResolvedModelCatalog, importResolvedModelCatalog, registerModelAlias, resolveModelAlias, RESOLVED_MODEL_CATALOG_SCHEMA_VERSION, } from './modelCatalog';
|
|
23
23
|
export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock, } from './usage/billingBlocks';
|
|
24
24
|
export { bucketUsage, summarizeUsageRows, usageBucketKey, weekKey } from './usage/usageReports';
|
|
25
25
|
export { applySessionSummary, isFileImported, markFileImported, removeSessionSummary, sessionSummaryFromStats, } from './historicalStore';
|
|
26
26
|
export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
|
|
27
|
-
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, } from './providerFailure';
|
|
27
|
+
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, CODEX_ERROR_INFO_KINDS, decodeCodexErrorInfo, } from './providerFailure';
|
|
28
|
+
export { parseClaudeAuthStatus, parseCodexLoginStatus } from './authStatus';
|
|
28
29
|
export { isAggregateCodexLimit } from './types/codex';
|
|
29
30
|
// Codex rollout parsing (pure: no filesystem access)
|
|
30
31
|
export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
|
|
32
|
+
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
31
33
|
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
|
32
34
|
export { renderHandoffUrlTemplate } from './handoffUrl';
|
|
33
35
|
// Tool categories across providers
|
|
34
36
|
export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
37
|
+
// Quota window helpers (pure; safe for webviews)
|
|
38
|
+
export { claudePlanLabel, extraQuotaRows, formatExtraUsage, quotaWindowApplies, quotaWindowHasData, quotaWindowLabel, quotaWindowShortLabel, } from './quota';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sidekick-shared/codex` — a small Node-only entry for Codex homes, the
|
|
3
|
+
* child-process environment, `auth.json` helpers, credential-store mode,
|
|
4
|
+
* rollout lookup, and the atomic JSON writers those helpers rely on.
|
|
5
|
+
*
|
|
6
|
+
* Loads a handful of modules and no Zod, so a host that only launches or
|
|
7
|
+
* locates Codex does not pay for the full `sidekick-shared/node` surface.
|
|
8
|
+
* Everything here is also exported from the package root and from
|
|
9
|
+
* `sidekick-shared/node`.
|
|
10
|
+
*
|
|
11
|
+
* @module codex
|
|
12
|
+
*/
|
|
13
|
+
export { getSystemCodexHome, resolveSidekickCodexHome, getCodexExecutionEnv, getCodexMonitoringHomes, getCodexSessionsDirs, getCodexCredentialStoreMode, forceFileCredentialStore, CODEX_SESSIONS_SUBDIR, CODEX_ARCHIVED_SESSIONS_SUBDIR, } from './codexPaths';
|
|
14
|
+
export { parseAuthJson as parseCodexAuthJson, readAuthIdentityFromRaw as readCodexAuthIdentity, readLastRefresh as readCodexLastRefresh, readAccessTokenExpiry as readCodexAccessTokenExpiry, identitiesMatch as codexIdentitiesMatch, codexRefreshFingerprint, compareCodexAuthFreshness, } from './codexAuth';
|
|
15
|
+
export { findCodexRolloutFile } from './providers/codexRollouts';
|
|
16
|
+
export { atomicWriteJson, atomicWriteJsonSync } from './writers/atomic';
|
|
17
|
+
export { parseClaudeAuthStatus, parseCodexLoginStatus } from './authStatus';
|
|
18
|
+
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
@@ -7,6 +7,7 @@ import { getAccountsDir, getActiveSavedAccount, listSavedAccountProfiles, remove
|
|
|
7
7
|
// re-serializing would drop fields added by newer codex versions, and the
|
|
8
8
|
// rotated refresh token inside is only valid in its freshest form.
|
|
9
9
|
import { atomicWriteFileSync as atomicWriteFile, atomicWriteJsonSync as atomicWriteJson, withFileLockSync, } from './writers/atomic';
|
|
10
|
+
import { parseCodexLoginStatus } from './authStatus';
|
|
10
11
|
import { identitiesMatch, codexRefreshFingerprint, compareCodexAuthFreshness, readAuthIdentityFromRaw, readLastRefresh, STALE_AUTH_THRESHOLD_MS, } from './codexAuth';
|
|
11
12
|
import { ensureCodexProfileDirs, forceFileCredentialStore, getCodexCredentialStoreMode, getCodexProfileDir, getCodexProfileHome, getCodexProfileStatePath, getCodexBackupPath, getCodexLoginDir, getCodexLoginsDir, getCodexLoginHome, getCodexLoginStatePath, getCodexProfilesDir, getSystemCodexHome, readFileOrNull, resolveSidekickCodexHome, } from './codexPaths';
|
|
12
13
|
import { getAccountHealth, readHealthSidecar, writeCodexHealthSidecar, } from './accountHealth';
|
|
@@ -206,18 +207,14 @@ function readMetadataFromLegacyCredentials(codexHome) {
|
|
|
206
207
|
return {};
|
|
207
208
|
}
|
|
208
209
|
const PROBE_TIMEOUT_MS = 4000;
|
|
210
|
+
/** `codex login status` counts only on exit 0; the text is read by {@link parseCodexLoginStatus}. */
|
|
209
211
|
export function parseCodexLoginStatusOutput(status, stdout) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return { loggedIn: true, authMode: 'chatgpt' };
|
|
217
|
-
}
|
|
218
|
-
return { loggedIn: true };
|
|
219
|
-
}
|
|
220
|
-
return { loggedIn: false };
|
|
212
|
+
if (status !== 0)
|
|
213
|
+
return { loggedIn: false };
|
|
214
|
+
const parsed = parseCodexLoginStatus(stdout);
|
|
215
|
+
if (!parsed.loggedIn)
|
|
216
|
+
return { loggedIn: false };
|
|
217
|
+
return parsed.method ? { loggedIn: true, authMode: parsed.method } : { loggedIn: true };
|
|
221
218
|
}
|
|
222
219
|
/**
|
|
223
220
|
* Blocks the caller's event loop for up to {@link PROBE_TIMEOUT_MS}. Async code
|
package/dist/esm/codexQuota.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { getActiveCodexAccount, getCodexMonitoringHomes, resolveSidekickCodexHome, } from './codexProfiles';
|
|
4
4
|
import { readQuotaSnapshot, writeQuotaSnapshot } from './quotaSnapshots';
|
|
5
|
-
import { FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, withQuotaProjections } from './quota';
|
|
5
|
+
import { FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, quotaWindowLabel, withQuotaProjections, } from './quota';
|
|
6
6
|
import { CodexProvider } from './providers/codex';
|
|
7
7
|
import { walkRolloutFiles } from './providers/rolloutWalker';
|
|
8
8
|
import { isAggregateCodexLimit } from './types/codex';
|
|
@@ -51,6 +51,11 @@ function isPreferredQuotaHit(candidate, current) {
|
|
|
51
51
|
function normalizePercent(value) {
|
|
52
52
|
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
53
53
|
}
|
|
54
|
+
function reportedWindowMs(value) {
|
|
55
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
|
56
|
+
? value * 60_000
|
|
57
|
+
: undefined;
|
|
58
|
+
}
|
|
54
59
|
function windowMinutesToMs(value, fallbackMs) {
|
|
55
60
|
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
|
56
61
|
? value * 60_000
|
|
@@ -193,26 +198,34 @@ export function quotaFromCodexRateLimits(rateLimits, source = 'session', capture
|
|
|
193
198
|
const secondary = rateLimits?.secondary;
|
|
194
199
|
if (!primary && !secondary)
|
|
195
200
|
return null;
|
|
201
|
+
const primaryMs = reportedWindowMs(primary?.window_minutes);
|
|
202
|
+
const secondaryMs = reportedWindowMs(secondary?.window_minutes);
|
|
196
203
|
return withQuotaProjections({
|
|
204
|
+
// A plan can report one window only (e.g. a weekly primary with no
|
|
205
|
+
// secondary); the missing one is marked `absent` rather than shown as 0%.
|
|
197
206
|
fiveHour: primary
|
|
198
207
|
? {
|
|
199
208
|
utilization: normalizePercent(primary.used_percent),
|
|
200
209
|
resetsAt: timestampToIso(primary.resets_at),
|
|
210
|
+
...(primaryMs !== undefined ? { windowMs: primaryMs } : {}),
|
|
201
211
|
}
|
|
202
|
-
: { utilization: 0, resetsAt: '' },
|
|
212
|
+
: { utilization: 0, resetsAt: '', absent: true },
|
|
203
213
|
sevenDay: secondary
|
|
204
214
|
? {
|
|
205
215
|
utilization: normalizePercent(secondary.used_percent),
|
|
206
216
|
resetsAt: timestampToIso(secondary.resets_at),
|
|
217
|
+
...(secondaryMs !== undefined ? { windowMs: secondaryMs } : {}),
|
|
207
218
|
}
|
|
208
|
-
: { utilization: 0, resetsAt: '' },
|
|
219
|
+
: { utilization: 0, resetsAt: '', absent: true },
|
|
209
220
|
available: true,
|
|
210
221
|
providerId: 'codex',
|
|
211
222
|
source,
|
|
212
223
|
capturedAt,
|
|
213
224
|
stale: source === 'cache',
|
|
214
|
-
|
|
215
|
-
|
|
225
|
+
// Name each window by its reported length (`5-Hour`, `Weekly`), falling
|
|
226
|
+
// back to the positional names when the length is not reported.
|
|
227
|
+
fiveHourLabel: quotaWindowLabel(primaryMs, 'Primary'),
|
|
228
|
+
sevenDayLabel: quotaWindowLabel(secondaryMs, 'Secondary'),
|
|
216
229
|
limitId: rateLimits?.limit_id,
|
|
217
230
|
limitName: rateLimits?.limit_name ?? undefined,
|
|
218
231
|
credits: rateLimits?.credits,
|