sidekick-shared 0.23.0 → 0.23.1
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/README.md +24 -20
- package/dist/accountManager.js +10 -0
- package/dist/aggregation/EventAggregator.d.ts +4 -1
- package/dist/aggregation/EventAggregator.js +22 -9
- package/dist/aggregation/snapshot.d.ts +1 -1
- package/dist/aggregation/snapshot.js +2 -1
- package/dist/aggregation/types.d.ts +2 -0
- package/dist/autoSwitch.d.ts +1 -1
- package/dist/autoSwitch.js +14 -3
- package/dist/codexQuota.d.ts +2 -0
- package/dist/codexQuota.js +27 -0
- package/dist/codexQuotaWatcher.d.ts +7 -0
- package/dist/codexQuotaWatcher.js +37 -19
- package/dist/context/sessionContext.js +35 -9
- package/dist/credentialIO.js +19 -5
- package/dist/errorHistory.d.ts +1 -0
- package/dist/errorHistory.js +3 -2
- package/dist/extractors/toolCall.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +9 -7
- package/dist/modelInfo.js +6 -0
- package/dist/multiProviderQuotaService.js +13 -2
- package/dist/parsers/codexParser.js +4 -1
- package/dist/parsers/sessionActivityDetector.js +2 -0
- package/dist/parsers/sessionPathResolver.js +19 -16
- package/dist/parsers/subagentScanner.d.ts +1 -1
- package/dist/parsers/subagentScanner.js +4 -5
- package/dist/parsers/subagentTraceParser.js +4 -7
- package/dist/providerStatus.js +13 -2
- package/dist/providers/claudeCode.js +18 -4
- package/dist/providers/codex.js +42 -13
- package/dist/providers/detect.js +32 -3
- package/dist/providers/openCodeDatabase.js +12 -3
- package/dist/quota.js +8 -0
- package/dist/quotaPoller.js +17 -6
- package/dist/quotaSnapshots.js +80 -26
- package/dist/readers/decisions.js +3 -1
- package/dist/readers/handoff.js +1 -1
- package/dist/readers/notes.js +9 -4
- package/dist/readers/plans.js +2 -4
- package/dist/readers/tasks.js +3 -1
- package/dist/report/htmlHelpers.js +6 -1
- package/dist/report/openBrowser.js +3 -3
- package/dist/statusline/formatter.js +8 -1
- package/dist/terminalSync.js +16 -7
- package/dist/types/historicalData.d.ts +14 -0
- package/dist/types/historicalData.js +22 -0
- package/dist/types/observedSessionV1.js +6 -5
- package/dist/types/sessionEvent.d.ts +1 -0
- package/dist/watchers/factory.js +14 -3
- package/dist/watchers/jsonlTail.js +34 -14
- package/dist/watchers/jsonlWatcher.js +5 -3
- package/dist/watchers/providerReaderWatcher.js +4 -2
- package/dist/watchers/sqliteWatcher.d.ts +2 -0
- package/dist/watchers/sqliteWatcher.js +27 -14
- package/dist/writers/atomic.js +100 -13
- package/dist/zaiQuotaWatcher.js +6 -0
- package/package.json +1 -1
package/dist/errorHistory.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ErrorRollup, ErrorRollupEntry } from './aggregation/types';
|
|
2
2
|
export declare const ERROR_HISTORY_SCHEMA_VERSION: 1;
|
|
3
|
+
export declare const MAX_ERROR_HISTORY_SESSIONS = 500;
|
|
3
4
|
export interface ErrorHistorySessionRecord {
|
|
4
5
|
sessionId: string;
|
|
5
6
|
providerId: string;
|
package/dist/errorHistory.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ERROR_HISTORY_SCHEMA_VERSION = void 0;
|
|
36
|
+
exports.MAX_ERROR_HISTORY_SESSIONS = exports.ERROR_HISTORY_SCHEMA_VERSION = void 0;
|
|
37
37
|
exports.appendErrorHistory = appendErrorHistory;
|
|
38
38
|
exports.readErrorHistory = readErrorHistory;
|
|
39
39
|
exports.getTopFailingTools = getTopFailingTools;
|
|
@@ -41,6 +41,7 @@ const fs = __importStar(require("fs"));
|
|
|
41
41
|
const paths_1 = require("./paths");
|
|
42
42
|
const atomic_1 = require("./writers/atomic");
|
|
43
43
|
exports.ERROR_HISTORY_SCHEMA_VERSION = 1;
|
|
44
|
+
exports.MAX_ERROR_HISTORY_SESSIONS = 500;
|
|
44
45
|
function emptyStore() {
|
|
45
46
|
return {
|
|
46
47
|
schemaVersion: exports.ERROR_HISTORY_SCHEMA_VERSION,
|
|
@@ -59,7 +60,7 @@ async function appendErrorHistory(identity, rollup, filePath = (0, paths_1.getGl
|
|
|
59
60
|
await (0, atomic_1.updateJsonStoreAtomic)(filePath, emptyStore, (store) => ({
|
|
60
61
|
...store,
|
|
61
62
|
schemaVersion: exports.ERROR_HISTORY_SCHEMA_VERSION,
|
|
62
|
-
sessions: [...store.sessions, record],
|
|
63
|
+
sessions: [...(Array.isArray(store.sessions) ? store.sessions : []), record].slice(-exports.MAX_ERROR_HISTORY_SESSIONS),
|
|
63
64
|
lastSaved: record.endedAt,
|
|
64
65
|
}));
|
|
65
66
|
return record;
|
|
@@ -85,7 +85,7 @@ class ToolCallTracker {
|
|
|
85
85
|
}
|
|
86
86
|
const topLevel = extractToolCall(event);
|
|
87
87
|
if (topLevel) {
|
|
88
|
-
const id = event.message
|
|
88
|
+
const id = event.message?.id;
|
|
89
89
|
if (id) {
|
|
90
90
|
topLevel.toolUseId = id;
|
|
91
91
|
this.pending.set(id, topLevel);
|
|
@@ -94,7 +94,7 @@ class ToolCallTracker {
|
|
|
94
94
|
completed.push(topLevel);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
const content = event.message
|
|
97
|
+
const content = event.message?.content;
|
|
98
98
|
if (!Array.isArray(content))
|
|
99
99
|
return completed;
|
|
100
100
|
for (const block of content) {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ export type { DecisionEntry, DecisionLogStore, DecisionSource } from './types/de
|
|
|
11
11
|
export { DECISION_LOG_SCHEMA_VERSION } from './types/decisionLog';
|
|
12
12
|
export type { KnowledgeNote, KnowledgeNoteStore, KnowledgeNoteType, KnowledgeNoteSource, KnowledgeNoteStatus, KnowledgeNoteImportance, } from './types/knowledgeNote';
|
|
13
13
|
export { KNOWLEDGE_NOTE_SCHEMA_VERSION, IMPORTANCE_DECAY_FACTORS, STALENESS_THRESHOLDS, } from './types/knowledgeNote';
|
|
14
|
-
export type { HistoricalDataStore, DailyData, MonthlyData, AllTimeStats, TokenTotals, ModelUsageRecord, ToolUsageRecord, SessionSummary, SessionHistoryRecord, } from './types/historicalData';
|
|
15
|
-
export { HISTORICAL_DATA_SCHEMA_VERSION, HISTORICAL_SESSION_RETENTION_LIMIT, createEmptyTokenTotals, } from './types/historicalData';
|
|
14
|
+
export type { HistoricalDataStore, DailyData, HourlyData, MonthlyData, AllTimeStats, TokenTotals, ModelUsageRecord, ToolUsageRecord, SessionSummary, SessionHistoryRecord, } from './types/historicalData';
|
|
15
|
+
export { HISTORICAL_DATA_SCHEMA_VERSION, HISTORICAL_SESSION_RETENTION_LIMIT, createEmptyTokenTotals, createEmptyDataStore, } from './types/historicalData';
|
|
16
16
|
export type { PersistedPlan, PersistedPlanStep, PlanHistoryStore, PlanStepStatus, PlanStatus, PlanSource, PlanStepComplexity, } from './types/plan';
|
|
17
17
|
export { PLAN_SCHEMA_VERSION, MAX_PLANS_PER_PROJECT } from './types/plan';
|
|
18
18
|
export { getConfigDir, getProjectDataPath, getGlobalDataPath, encodeWorkspacePath, getProjectSlug, getProjectSlugRaw, resolveProjectIdentity, } from './paths';
|
|
@@ -93,7 +93,7 @@ export type { SerializedAggregatorState } from './aggregation/EventAggregator';
|
|
|
93
93
|
export { saveSnapshot, loadSnapshot, deleteSnapshot, isSnapshotValid, getSnapshotPath, } from './aggregation/snapshot';
|
|
94
94
|
export type { SessionSnapshot } from './aggregation/snapshot';
|
|
95
95
|
export type { EventAggregatorOptions, AggregatedTokens, ModelUsageStats, BurnRateInfo, SubagentLifecycle, AggregatedMetrics, FrequencyMetric, PatternMetric, HeatmapBucketMetric, ErrorRollup, ErrorRollupEntry, ErrorBucketMetric, } from './aggregation/types';
|
|
96
|
-
export { ERROR_HISTORY_SCHEMA_VERSION, appendErrorHistory, getTopFailingTools, readErrorHistory, } from './errorHistory';
|
|
96
|
+
export { ERROR_HISTORY_SCHEMA_VERSION, MAX_ERROR_HISTORY_SESSIONS, appendErrorHistory, getTopFailingTools, readErrorHistory, } from './errorHistory';
|
|
97
97
|
export type { ErrorHistorySessionRecord, ErrorHistoryStore, TopFailingTool } from './errorHistory';
|
|
98
98
|
export { FrequencyTracker } from './aggregation/FrequencyTracker';
|
|
99
99
|
export type { FrequencyEntry, SerializedFrequencyState } from './aggregation/FrequencyTracker';
|
package/dist/index.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Public API for sidekick-shared.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.
|
|
11
|
-
exports.
|
|
12
|
-
exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.createPeakHoursNotApplicableState = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = void 0;
|
|
6
|
+
exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = exports.addDecision = exports.completeTask = exports.addTask = exports.updateJsonStoreAtomic = exports.atomicWriteJsonSync = exports.atomicWriteJson = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.migrateLegacyProjectStores = exports.resolveProjectIdentity = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.getConfigDir = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyDataStore = exports.createEmptyTokenTotals = exports.HISTORICAL_SESSION_RETENTION_LIMIT = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = exports.isAggregateCodexLimit = void 0;
|
|
7
|
+
exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = void 0;
|
|
8
|
+
exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = exports.calculateCodeImpact = exports.scoreSessionQuality = exports.calculateQualityTrend = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.readErrorHistory = exports.getTopFailingTools = exports.appendErrorHistory = exports.MAX_ERROR_HISTORY_SESSIONS = exports.ERROR_HISTORY_SCHEMA_VERSION = exports.getSnapshotPath = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.SessionMonitor = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.formatTokenCount = exports.formatDurationMs = exports.createJsonlTail = exports.toFollowEvents = void 0;
|
|
9
|
+
exports.removeCodexAccount = exports.switchToCodexAccount = exports.finalizeCodexAccount = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.getActiveAccountStatus = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLogin = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = void 0;
|
|
10
|
+
exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.MultiProviderQuotaService = exports.resolveZaiQuota = exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.fetchCodexResetCreditsFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.isShellHookInstalled = exports.uninstallShellHook = exports.installShellHook = exports.setTerminalActiveProfile = void 0;
|
|
11
|
+
exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = exports.extractErrorMessage = exports.categorizeError = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractTokenUsage = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = void 0;
|
|
12
|
+
exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.createPeakHoursNotApplicableState = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = void 0;
|
|
13
13
|
var codex_1 = require("./types/codex");
|
|
14
14
|
Object.defineProperty(exports, "isAggregateCodexLimit", { enumerable: true, get: function () { return codex_1.isAggregateCodexLimit; } });
|
|
15
15
|
var taskPersistence_1 = require("./types/taskPersistence");
|
|
@@ -25,6 +25,7 @@ var historicalData_1 = require("./types/historicalData");
|
|
|
25
25
|
Object.defineProperty(exports, "HISTORICAL_DATA_SCHEMA_VERSION", { enumerable: true, get: function () { return historicalData_1.HISTORICAL_DATA_SCHEMA_VERSION; } });
|
|
26
26
|
Object.defineProperty(exports, "HISTORICAL_SESSION_RETENTION_LIMIT", { enumerable: true, get: function () { return historicalData_1.HISTORICAL_SESSION_RETENTION_LIMIT; } });
|
|
27
27
|
Object.defineProperty(exports, "createEmptyTokenTotals", { enumerable: true, get: function () { return historicalData_1.createEmptyTokenTotals; } });
|
|
28
|
+
Object.defineProperty(exports, "createEmptyDataStore", { enumerable: true, get: function () { return historicalData_1.createEmptyDataStore; } });
|
|
28
29
|
var plan_1 = require("./types/plan");
|
|
29
30
|
Object.defineProperty(exports, "PLAN_SCHEMA_VERSION", { enumerable: true, get: function () { return plan_1.PLAN_SCHEMA_VERSION; } });
|
|
30
31
|
Object.defineProperty(exports, "MAX_PLANS_PER_PROJECT", { enumerable: true, get: function () { return plan_1.MAX_PLANS_PER_PROJECT; } });
|
|
@@ -213,6 +214,7 @@ Object.defineProperty(exports, "isSnapshotValid", { enumerable: true, get: funct
|
|
|
213
214
|
Object.defineProperty(exports, "getSnapshotPath", { enumerable: true, get: function () { return snapshot_1.getSnapshotPath; } });
|
|
214
215
|
var errorHistory_1 = require("./errorHistory");
|
|
215
216
|
Object.defineProperty(exports, "ERROR_HISTORY_SCHEMA_VERSION", { enumerable: true, get: function () { return errorHistory_1.ERROR_HISTORY_SCHEMA_VERSION; } });
|
|
217
|
+
Object.defineProperty(exports, "MAX_ERROR_HISTORY_SESSIONS", { enumerable: true, get: function () { return errorHistory_1.MAX_ERROR_HISTORY_SESSIONS; } });
|
|
216
218
|
Object.defineProperty(exports, "appendErrorHistory", { enumerable: true, get: function () { return errorHistory_1.appendErrorHistory; } });
|
|
217
219
|
Object.defineProperty(exports, "getTopFailingTools", { enumerable: true, get: function () { return errorHistory_1.getTopFailingTools; } });
|
|
218
220
|
Object.defineProperty(exports, "readErrorHistory", { enumerable: true, get: function () { return errorHistory_1.readErrorHistory; } });
|
package/dist/modelInfo.js
CHANGED
|
@@ -142,6 +142,12 @@ const PRICING_TABLE = {
|
|
|
142
142
|
cacheWriteCostPerMillion: 6.25,
|
|
143
143
|
cacheReadCostPerMillion: 0.5,
|
|
144
144
|
},
|
|
145
|
+
'claude-opus-4-5': {
|
|
146
|
+
inputCostPerMillion: 5.0,
|
|
147
|
+
outputCostPerMillion: 25.0,
|
|
148
|
+
cacheWriteCostPerMillion: 6.25,
|
|
149
|
+
cacheReadCostPerMillion: 0.5,
|
|
150
|
+
},
|
|
145
151
|
'claude-opus-4.5': {
|
|
146
152
|
inputCostPerMillion: 5.0,
|
|
147
153
|
outputCostPerMillion: 25.0,
|
|
@@ -174,7 +174,7 @@ class MultiProviderQuotaService {
|
|
|
174
174
|
providerId: 'claude-code',
|
|
175
175
|
});
|
|
176
176
|
this.lastEmittedClaudeState = nextState;
|
|
177
|
-
if (nextState.available) {
|
|
177
|
+
if (nextState.available && nextState.stale !== true) {
|
|
178
178
|
this.lastSuccessfulClaudeState = nextState;
|
|
179
179
|
}
|
|
180
180
|
this.quotaByProvider = {
|
|
@@ -323,7 +323,18 @@ class MultiProviderQuotaService {
|
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
this.cachedFallbackActive = hasVisibleCachedSuccess;
|
|
326
|
-
if (
|
|
326
|
+
if (hasVisibleCachedSuccess) {
|
|
327
|
+
this.emitClaudeState({
|
|
328
|
+
...this.lastSuccessfulClaudeState,
|
|
329
|
+
error: state.error,
|
|
330
|
+
failureKind: state.failureKind,
|
|
331
|
+
httpStatus: state.httpStatus,
|
|
332
|
+
retryAfterMs: state.retryAfterMs,
|
|
333
|
+
source: 'cache',
|
|
334
|
+
stale: true,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
327
338
|
this.emitClaudeState(state);
|
|
328
339
|
}
|
|
329
340
|
}
|
|
@@ -782,7 +782,10 @@ class CodexRolloutParser {
|
|
|
782
782
|
return [];
|
|
783
783
|
const mappedUsage = usage
|
|
784
784
|
? {
|
|
785
|
-
|
|
785
|
+
// Codex reports cached_input_tokens as a subset of input_tokens,
|
|
786
|
+
// while MessageUsage categories are disjoint. Normalize once here
|
|
787
|
+
// so aggregation and pricing do not count cached input twice.
|
|
788
|
+
input_tokens: Math.max(0, (usage.input_tokens || 0) - (usage.cached_input_tokens || 0)),
|
|
786
789
|
output_tokens: usage.output_tokens || 0,
|
|
787
790
|
cache_read_input_tokens: usage.cached_input_tokens || 0,
|
|
788
791
|
cache_creation_input_tokens: 0,
|
|
@@ -126,6 +126,8 @@ function detectSessionActivity(sessionPath) {
|
|
|
126
126
|
}
|
|
127
127
|
if (!hasTerminal) {
|
|
128
128
|
for (const pattern of ENDING_PATTERNS) {
|
|
129
|
+
if (pattern === '"type":"user"' && line.includes('"type":"tool_result"'))
|
|
130
|
+
continue;
|
|
129
131
|
if (line.includes(pattern)) {
|
|
130
132
|
lastEndingIndex = i;
|
|
131
133
|
break;
|
|
@@ -81,10 +81,9 @@ const os = __importStar(require("os"));
|
|
|
81
81
|
function encodeWorkspacePath(workspacePath) {
|
|
82
82
|
// Normalize path separators to forward slash
|
|
83
83
|
const normalized = workspacePath.replace(/\\/g, '/');
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
return normalized.replace(/[:/_]/g, '-');
|
|
84
|
+
// Claude Code replaces every non-alphanumeric path character, including
|
|
85
|
+
// dots and spaces, with a hyphen.
|
|
86
|
+
return normalized.replace(/[^a-zA-Z0-9]/g, '-');
|
|
88
87
|
}
|
|
89
88
|
/**
|
|
90
89
|
* Gets the session directory path for a workspace.
|
|
@@ -249,12 +248,7 @@ function discoverSessionDirectory(workspacePath) {
|
|
|
249
248
|
});
|
|
250
249
|
// Try to match by workspace path components
|
|
251
250
|
// Normalize workspace path for comparison
|
|
252
|
-
const normalizedWorkspace = workspacePath
|
|
253
|
-
.replace(/\\/g, '/')
|
|
254
|
-
.replace(/:/g, '-')
|
|
255
|
-
.replace(/_/g, '-')
|
|
256
|
-
.replace(/\//g, '-')
|
|
257
|
-
.toLowerCase();
|
|
251
|
+
const normalizedWorkspace = encodeWorkspacePath(workspacePath).toLowerCase();
|
|
258
252
|
for (const dir of existingDirs) {
|
|
259
253
|
// Check if the directory name matches (case-insensitive)
|
|
260
254
|
if (dir.toLowerCase() === normalizedWorkspace) {
|
|
@@ -262,7 +256,10 @@ function discoverSessionDirectory(workspacePath) {
|
|
|
262
256
|
}
|
|
263
257
|
}
|
|
264
258
|
// Fallback: match by final path component (project name)
|
|
265
|
-
const workspaceBasename = path
|
|
259
|
+
const workspaceBasename = path
|
|
260
|
+
.basename(workspacePath)
|
|
261
|
+
.replace(/[^a-zA-Z0-9]/g, '-')
|
|
262
|
+
.toLowerCase();
|
|
266
263
|
for (const dir of existingDirs) {
|
|
267
264
|
const dirLower = dir.toLowerCase();
|
|
268
265
|
// Check if dir ends with the project name
|
|
@@ -406,12 +403,18 @@ function findAllSessions(workspacePath) {
|
|
|
406
403
|
.filter((file) => file.endsWith('.jsonl'))
|
|
407
404
|
.map((file) => {
|
|
408
405
|
const fullPath = path.join(sessionDir, file);
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
406
|
+
try {
|
|
407
|
+
const stats = fs.statSync(fullPath);
|
|
408
|
+
return {
|
|
409
|
+
path: fullPath,
|
|
410
|
+
mtime: stats.mtime.getTime(),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
414
416
|
})
|
|
417
|
+
.filter((file) => file !== null)
|
|
415
418
|
.sort((a, b) => b.mtime - a.mtime)
|
|
416
419
|
.map((file) => file.path);
|
|
417
420
|
return files;
|
|
@@ -26,7 +26,7 @@ import type { SubagentStats, TaskState } from '../types/sessionEvent';
|
|
|
26
26
|
* }
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
|
-
export declare function scanSubagentDir(sessionDir: string, sessionId: string, logger?: (msg: string) => void): SubagentStats[];
|
|
29
|
+
export declare function scanSubagentDir(sessionDir: string, sessionId: string, logger?: (msg: string) => void, skipFiles?: ReadonlySet<string>): SubagentStats[];
|
|
30
30
|
/**
|
|
31
31
|
* Handles TaskUpdate tool input and updates task state.
|
|
32
32
|
*/
|
|
@@ -93,7 +93,7 @@ const reportedMissing = new Set();
|
|
|
93
93
|
* }
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
|
-
function scanSubagentDir(sessionDir, sessionId, logger) {
|
|
96
|
+
function scanSubagentDir(sessionDir, sessionId, logger, skipFiles = new Set()) {
|
|
97
97
|
const log = logger || (() => { });
|
|
98
98
|
const subagentsDir = path.join(sessionDir, sessionId, 'subagents');
|
|
99
99
|
const results = [];
|
|
@@ -110,6 +110,8 @@ function scanSubagentDir(sessionDir, sessionId, logger) {
|
|
|
110
110
|
const files = fs.readdirSync(subagentsDir);
|
|
111
111
|
log(`[SubagentScanner] Found ${files.length} files: ${files.join(', ')}`);
|
|
112
112
|
for (const file of files) {
|
|
113
|
+
if (skipFiles.has(file))
|
|
114
|
+
continue;
|
|
113
115
|
const match = file.match(AGENT_FILE_PATTERN);
|
|
114
116
|
if (!match) {
|
|
115
117
|
continue;
|
|
@@ -169,10 +171,7 @@ function parseAgentFile(filePath, agentId, log) {
|
|
|
169
171
|
// Extract token usage from assistant messages
|
|
170
172
|
if (event.type === 'assistant' && event.message?.usage) {
|
|
171
173
|
const usage = event.message.usage;
|
|
172
|
-
inputTokens +=
|
|
173
|
-
(usage.input_tokens || 0) +
|
|
174
|
-
(usage.cache_creation_input_tokens || 0) +
|
|
175
|
-
(usage.cache_read_input_tokens || 0);
|
|
174
|
+
inputTokens += usage.input_tokens || 0;
|
|
176
175
|
outputTokens += usage.output_tokens || 0;
|
|
177
176
|
}
|
|
178
177
|
// Extract agent type and description from Task tool invocation
|
|
@@ -141,7 +141,7 @@ function parseAgentTrace(filePath, agentId) {
|
|
|
141
141
|
}
|
|
142
142
|
// Format tool summary
|
|
143
143
|
let toolSummary;
|
|
144
|
-
if (sessionEvent.
|
|
144
|
+
if (sessionEvent.tool) {
|
|
145
145
|
toolSummary = (0, toolSummary_1.formatToolSummary)(sessionEvent.tool.name, sessionEvent.tool.input);
|
|
146
146
|
}
|
|
147
147
|
events.push({
|
|
@@ -155,10 +155,7 @@ function parseAgentTrace(filePath, agentId) {
|
|
|
155
155
|
// Extract token usage
|
|
156
156
|
if (raw.type === 'assistant' && raw.message?.usage) {
|
|
157
157
|
const usage = raw.message.usage;
|
|
158
|
-
inputTokens +=
|
|
159
|
-
(usage.input_tokens || 0) +
|
|
160
|
-
(usage.cache_creation_input_tokens || 0) +
|
|
161
|
-
(usage.cache_read_input_tokens || 0);
|
|
158
|
+
inputTokens += usage.input_tokens || 0;
|
|
162
159
|
outputTokens += usage.output_tokens || 0;
|
|
163
160
|
}
|
|
164
161
|
// Extract tool calls
|
|
@@ -251,7 +248,7 @@ function linkTraces(traces) {
|
|
|
251
248
|
for (const match of matches) {
|
|
252
249
|
const childId = match[1];
|
|
253
250
|
const child = traceById.get(childId);
|
|
254
|
-
if (child && child !== trace) {
|
|
251
|
+
if (child && child !== trace && !child.parentToolUseId) {
|
|
255
252
|
child.parentToolUseId = trace.agentId;
|
|
256
253
|
trace.children.push(child);
|
|
257
254
|
}
|
|
@@ -274,7 +271,7 @@ function linkTraces(traces) {
|
|
|
274
271
|
continue; // Already linked
|
|
275
272
|
for (const traceEvent of potential.events) {
|
|
276
273
|
const evt = traceEvent.event;
|
|
277
|
-
if (evt.type === '
|
|
274
|
+
if (evt.type === 'assistant' && evt.tool?.name === 'Task') {
|
|
278
275
|
const taskTime = new Date(evt.timestamp).getTime();
|
|
279
276
|
// Within 2 seconds before child start
|
|
280
277
|
if (taskTime <= childStart && childStart - taskTime < 2000) {
|
package/dist/providerStatus.js
CHANGED
|
@@ -24,7 +24,7 @@ function fallbackState() {
|
|
|
24
24
|
*/
|
|
25
25
|
async function fetchStatusPage(baseUrl) {
|
|
26
26
|
try {
|
|
27
|
-
const statusRes = await
|
|
27
|
+
const statusRes = await fetchWithTimeout(`${baseUrl}/api/v2/status.json`);
|
|
28
28
|
if (!statusRes.ok)
|
|
29
29
|
return fallbackState();
|
|
30
30
|
const statusData = await statusRes.json();
|
|
@@ -36,7 +36,7 @@ async function fetchStatusPage(baseUrl) {
|
|
|
36
36
|
return { indicator, description, affectedComponents: [], activeIncident: null, updatedAt };
|
|
37
37
|
}
|
|
38
38
|
// Degraded — fetch summary for components + incidents
|
|
39
|
-
const summaryRes = await
|
|
39
|
+
const summaryRes = await fetchWithTimeout(`${baseUrl}/api/v2/summary.json`);
|
|
40
40
|
if (!summaryRes.ok) {
|
|
41
41
|
return { indicator, description, affectedComponents: [], activeIncident: null, updatedAt };
|
|
42
42
|
}
|
|
@@ -61,6 +61,17 @@ async function fetchStatusPage(baseUrl) {
|
|
|
61
61
|
return fallbackState();
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
async function fetchWithTimeout(url) {
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timeout = setTimeout(() => controller.abort(), 10_000);
|
|
67
|
+
timeout.unref();
|
|
68
|
+
try {
|
|
69
|
+
return await fetch(url, { signal: controller.signal });
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
clearTimeout(timeout);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
64
75
|
/**
|
|
65
76
|
* Fetch current Claude API status from status.claude.com.
|
|
66
77
|
*
|
|
@@ -46,6 +46,7 @@ exports.ClaudeCodeProvider = void 0;
|
|
|
46
46
|
const fs = __importStar(require("fs"));
|
|
47
47
|
const os = __importStar(require("os"));
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
|
+
const string_decoder_1 = require("string_decoder");
|
|
49
50
|
const sessionContext_1 = require("../context/sessionContext");
|
|
50
51
|
const jsonl_1 = require("../parsers/jsonl");
|
|
51
52
|
const sessionPathResolver_1 = require("../parsers/sessionPathResolver");
|
|
@@ -97,6 +98,7 @@ class ClaudeCodeReader {
|
|
|
97
98
|
filePosition = 0;
|
|
98
99
|
events = [];
|
|
99
100
|
_wasTruncated = false;
|
|
101
|
+
decoder = new string_decoder_1.StringDecoder('utf8');
|
|
100
102
|
constructor(sessionPath) {
|
|
101
103
|
this.sessionPath = sessionPath;
|
|
102
104
|
this.parser = new jsonl_1.JsonlParser({
|
|
@@ -120,6 +122,7 @@ class ClaudeCodeReader {
|
|
|
120
122
|
this._wasTruncated = true;
|
|
121
123
|
this.filePosition = 0;
|
|
122
124
|
this.parser.reset();
|
|
125
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
123
126
|
}
|
|
124
127
|
// No new content
|
|
125
128
|
if (currentSize <= this.filePosition) {
|
|
@@ -129,11 +132,16 @@ class ClaudeCodeReader {
|
|
|
129
132
|
const fd = fs.openSync(this.sessionPath, 'r');
|
|
130
133
|
const bufferSize = currentSize - this.filePosition;
|
|
131
134
|
const buffer = Buffer.alloc(bufferSize);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
let bytesRead = 0;
|
|
136
|
+
try {
|
|
137
|
+
bytesRead = fs.readSync(fd, buffer, 0, bufferSize, this.filePosition);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
fs.closeSync(fd);
|
|
141
|
+
}
|
|
142
|
+
const chunk = this.decoder.write(buffer.subarray(0, bytesRead));
|
|
135
143
|
this.parser.processChunk(chunk);
|
|
136
|
-
this.filePosition
|
|
144
|
+
this.filePosition += bytesRead;
|
|
137
145
|
}
|
|
138
146
|
catch (error) {
|
|
139
147
|
console.error(`ClaudeCodeReader: error reading ${this.sessionPath}: ${error}`);
|
|
@@ -147,13 +155,18 @@ class ClaudeCodeReader {
|
|
|
147
155
|
reset() {
|
|
148
156
|
this.filePosition = 0;
|
|
149
157
|
this.parser.reset();
|
|
158
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
150
159
|
this._wasTruncated = false;
|
|
151
160
|
}
|
|
152
161
|
exists() {
|
|
153
162
|
return fs.existsSync(this.sessionPath);
|
|
154
163
|
}
|
|
155
164
|
flush() {
|
|
165
|
+
const finalChunk = this.decoder.end();
|
|
166
|
+
if (finalChunk)
|
|
167
|
+
this.parser.processChunk(finalChunk);
|
|
156
168
|
this.parser.flush();
|
|
169
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
157
170
|
}
|
|
158
171
|
getPosition() {
|
|
159
172
|
return this.filePosition;
|
|
@@ -161,6 +174,7 @@ class ClaudeCodeReader {
|
|
|
161
174
|
seekTo(position) {
|
|
162
175
|
this.filePosition = position;
|
|
163
176
|
this.parser.reset();
|
|
177
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
164
178
|
}
|
|
165
179
|
wasTruncated() {
|
|
166
180
|
return this._wasTruncated;
|
package/dist/providers/codex.js
CHANGED
|
@@ -46,6 +46,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
46
46
|
exports.CodexProvider = void 0;
|
|
47
47
|
const fs = __importStar(require("fs"));
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
|
+
const string_decoder_1 = require("string_decoder");
|
|
49
50
|
const EventAggregator_1 = require("../aggregation/EventAggregator");
|
|
50
51
|
const sessionContext_1 = require("../context/sessionContext");
|
|
51
52
|
const codexParser_1 = require("../parsers/codexParser");
|
|
@@ -131,6 +132,23 @@ function findRolloutFiles(dir) {
|
|
|
131
132
|
}
|
|
132
133
|
return results;
|
|
133
134
|
}
|
|
135
|
+
function hasRolloutFile(dir) {
|
|
136
|
+
try {
|
|
137
|
+
if (!fs.existsSync(dir))
|
|
138
|
+
return false;
|
|
139
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
140
|
+
const fullPath = path.join(dir, entry.name);
|
|
141
|
+
if (entry.isDirectory() && hasRolloutFile(fullPath))
|
|
142
|
+
return true;
|
|
143
|
+
if (entry.isFile() && isRolloutFile(entry.name))
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
134
152
|
function findRolloutFilesInConfiguredHomes() {
|
|
135
153
|
const results = [];
|
|
136
154
|
const seen = new Set();
|
|
@@ -148,7 +166,7 @@ function findRolloutFilesInConfiguredHomes() {
|
|
|
148
166
|
function getSessionsDir() {
|
|
149
167
|
const dirs = getSessionsDirs();
|
|
150
168
|
for (const dir of dirs) {
|
|
151
|
-
if (
|
|
169
|
+
if (hasRolloutFile(dir)) {
|
|
152
170
|
return dir;
|
|
153
171
|
}
|
|
154
172
|
}
|
|
@@ -430,6 +448,7 @@ class CodexReader {
|
|
|
430
448
|
filePosition = 0;
|
|
431
449
|
lineBuffer = '';
|
|
432
450
|
_wasTruncated = false;
|
|
451
|
+
decoder = new string_decoder_1.StringDecoder('utf8');
|
|
433
452
|
constructor(rolloutPath, onContextWindowLimit, onRateLimits, onTokenUsage) {
|
|
434
453
|
this.rolloutPath = rolloutPath;
|
|
435
454
|
this.onContextWindowLimit = onContextWindowLimit;
|
|
@@ -455,6 +474,7 @@ class CodexReader {
|
|
|
455
474
|
this.filePosition = 0;
|
|
456
475
|
this.lineBuffer = '';
|
|
457
476
|
this.parser.reset();
|
|
477
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
458
478
|
}
|
|
459
479
|
// No new content
|
|
460
480
|
if (currentSize <= this.filePosition)
|
|
@@ -463,10 +483,15 @@ class CodexReader {
|
|
|
463
483
|
const fd = fs.openSync(this.rolloutPath, 'r');
|
|
464
484
|
const bufferSize = currentSize - this.filePosition;
|
|
465
485
|
const buffer = Buffer.alloc(bufferSize);
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
486
|
+
let bytesRead = 0;
|
|
487
|
+
try {
|
|
488
|
+
bytesRead = fs.readSync(fd, buffer, 0, bufferSize, this.filePosition);
|
|
489
|
+
}
|
|
490
|
+
finally {
|
|
491
|
+
fs.closeSync(fd);
|
|
492
|
+
}
|
|
493
|
+
const chunk = this.decoder.write(buffer.subarray(0, bytesRead));
|
|
494
|
+
this.filePosition += bytesRead;
|
|
470
495
|
// Process lines
|
|
471
496
|
const text = this.lineBuffer + chunk;
|
|
472
497
|
const lines = text.split('\n');
|
|
@@ -497,11 +522,12 @@ class CodexReader {
|
|
|
497
522
|
// Propagate last token usage snapshot to the provider
|
|
498
523
|
const lastUsage = this.parser.getLastTokenUsage();
|
|
499
524
|
if (lastUsage && this.onTokenUsage) {
|
|
525
|
+
const cacheReadTokens = lastUsage.cached_input_tokens || 0;
|
|
500
526
|
this.onTokenUsage({
|
|
501
|
-
inputTokens: lastUsage.input_tokens || 0,
|
|
527
|
+
inputTokens: Math.max(0, (lastUsage.input_tokens || 0) - cacheReadTokens),
|
|
502
528
|
outputTokens: lastUsage.output_tokens || 0,
|
|
503
529
|
cacheWriteTokens: 0,
|
|
504
|
-
cacheReadTokens
|
|
530
|
+
cacheReadTokens,
|
|
505
531
|
reasoningTokens: lastUsage.reasoning_output_tokens || 0,
|
|
506
532
|
model: this.parser.getCurrentModel() || 'unknown',
|
|
507
533
|
timestamp: new Date(),
|
|
@@ -521,12 +547,14 @@ class CodexReader {
|
|
|
521
547
|
this.filePosition = 0;
|
|
522
548
|
this.lineBuffer = '';
|
|
523
549
|
this.parser.reset();
|
|
550
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
524
551
|
this._wasTruncated = false;
|
|
525
552
|
}
|
|
526
553
|
exists() {
|
|
527
554
|
return fs.existsSync(this.rolloutPath);
|
|
528
555
|
}
|
|
529
556
|
flush() {
|
|
557
|
+
this.lineBuffer += this.decoder.end();
|
|
530
558
|
// Process any remaining data in the line buffer
|
|
531
559
|
if (this.lineBuffer.trim()) {
|
|
532
560
|
try {
|
|
@@ -537,6 +565,7 @@ class CodexReader {
|
|
|
537
565
|
// Not a complete line yet
|
|
538
566
|
}
|
|
539
567
|
}
|
|
568
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
540
569
|
}
|
|
541
570
|
getPosition() {
|
|
542
571
|
return this.filePosition;
|
|
@@ -544,6 +573,7 @@ class CodexReader {
|
|
|
544
573
|
seekTo(position) {
|
|
545
574
|
this.filePosition = position;
|
|
546
575
|
this.lineBuffer = '';
|
|
576
|
+
this.decoder = new string_decoder_1.StringDecoder('utf8');
|
|
547
577
|
}
|
|
548
578
|
wasTruncated() {
|
|
549
579
|
return this._wasTruncated;
|
|
@@ -675,9 +705,10 @@ class CodexProvider {
|
|
|
675
705
|
const db = this.ensureDb();
|
|
676
706
|
if (db) {
|
|
677
707
|
const cwdStats = db.getAllDistinctCwds();
|
|
708
|
+
const sessionsDir = getSessionsDir();
|
|
678
709
|
for (const stat of cwdStats) {
|
|
679
710
|
seenCwds.set(stat.cwd, {
|
|
680
|
-
dir:
|
|
711
|
+
dir: sessionsDir,
|
|
681
712
|
name: stat.cwd,
|
|
682
713
|
encodedName: stat.cwd,
|
|
683
714
|
sessionCount: stat.count,
|
|
@@ -971,11 +1002,9 @@ class CodexProvider {
|
|
|
971
1002
|
return this.lastTokenUsageData;
|
|
972
1003
|
}
|
|
973
1004
|
computeContextSize(usage) {
|
|
974
|
-
//
|
|
975
|
-
//
|
|
976
|
-
|
|
977
|
-
// cacheWrite + cacheRead because Anthropic reports them separately.
|
|
978
|
-
return usage.inputTokens;
|
|
1005
|
+
// Codex usage is normalized to the disjoint TokenUsage shape at the reader
|
|
1006
|
+
// boundary, so reconstruct the full prompt/context from uncached + cached.
|
|
1007
|
+
return usage.inputTokens + usage.cacheReadTokens;
|
|
979
1008
|
}
|
|
980
1009
|
// --- Rate limits (for vscode wrapper to build QuotaState) ---
|
|
981
1010
|
/** Get the last rate limits data received from token_count events. */
|