sidekick-shared 0.24.5 → 0.26.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 +92 -0
- package/README.md +205 -52
- package/dist/accountChangeSignal.d.ts +3 -0
- package/dist/accountChangeSignal.js +19 -0
- package/dist/accountChanges.d.ts +21 -0
- package/dist/accountChanges.js +170 -0
- package/dist/accountRegistry.d.ts +25 -2
- package/dist/accountRegistry.js +41 -13
- package/dist/accountStatus.d.ts +9 -1
- package/dist/accountStatus.js +3 -3
- package/dist/accounts.d.ts +3 -1
- package/dist/accounts.js +84 -64
- package/dist/aggregation/EventAggregator.d.ts +15 -2
- package/dist/aggregation/EventAggregator.js +54 -9
- package/dist/aggregation/costProvenance.d.ts +14 -0
- package/dist/aggregation/costProvenance.js +35 -0
- package/dist/aggregation/snapshot.d.ts +13 -2
- package/dist/aggregation/snapshot.js +57 -6
- package/dist/aggregation/types.d.ts +30 -1
- package/dist/analytics/compactionLedger.js +15 -5
- package/dist/analytics/qualityScore.js +2 -1
- package/dist/browser.d.ts +19 -4
- package/dist/browser.js +43 -1
- package/dist/codexProfiles.d.ts +3 -1
- package/dist/codexProfiles.js +4 -2
- package/dist/codexQuota.d.ts +2 -0
- package/dist/codexQuota.js +11 -66
- package/dist/codexQuotaWatcher.d.ts +6 -0
- package/dist/codexQuotaWatcher.js +101 -47
- package/dist/failingTools.d.ts +37 -0
- package/dist/failingTools.js +70 -0
- package/dist/formatters/sessionDump.js +13 -7
- package/dist/formatting.d.ts +13 -0
- package/dist/formatting.js +35 -0
- package/dist/historicalStore.d.ts +47 -0
- package/dist/historicalStore.js +312 -0
- package/dist/index.d.ts +67 -23
- package/dist/index.js +138 -26
- package/dist/modelAliases.d.ts +13 -0
- package/dist/modelAliases.js +58 -0
- package/dist/modelCatalog.d.ts +32 -0
- package/dist/modelCatalog.js +145 -0
- package/dist/modelContext.d.ts +36 -3
- package/dist/modelContext.js +109 -34
- package/dist/modelInfo.d.ts +30 -1
- package/dist/modelInfo.js +116 -26
- package/dist/multiProviderQuotaService.d.ts +8 -0
- package/dist/multiProviderQuotaService.js +64 -3
- package/dist/node.d.ts +23 -4
- package/dist/node.js +50 -1
- package/dist/observedContextWindows.d.ts +7 -0
- package/dist/observedContextWindows.js +17 -2
- package/dist/observedSessionCollector.d.ts +72 -6
- package/dist/observedSessionCollector.js +440 -47
- package/dist/parsers/codexHistory.d.ts +4 -2
- package/dist/parsers/codexHistory.js +9 -2
- package/dist/parsers/sessionActivityDetector.d.ts +28 -0
- package/dist/parsers/sessionActivityDetector.js +110 -15
- package/dist/parsers/sessionPathResolver.d.ts +11 -0
- package/dist/parsers/sessionPathResolver.js +13 -10
- package/dist/peakHours.d.ts +34 -3
- package/dist/peakHours.js +92 -7
- package/dist/pricingCatalog.d.ts +7 -0
- package/dist/pricingCatalog.js +8 -5
- package/dist/providerIds.d.ts +11 -0
- package/dist/providerIds.js +9 -0
- package/dist/providerQuota.d.ts +3 -1
- package/dist/providerQuota.js +3 -0
- package/dist/providers/claudeCode.d.ts +10 -1
- package/dist/providers/claudeCode.js +211 -131
- package/dist/providers/codex.d.ts +20 -1
- package/dist/providers/codex.js +308 -244
- package/dist/providers/codexDatabase.d.ts +9 -0
- package/dist/providers/codexDatabase.js +107 -2
- package/dist/providers/detect.d.ts +2 -0
- package/dist/providers/detect.js +29 -24
- package/dist/providers/diagnostics.d.ts +13 -0
- package/dist/providers/diagnostics.js +88 -0
- package/dist/providers/factory.d.ts +20 -0
- package/dist/providers/factory.js +57 -0
- package/dist/providers/openCode.d.ts +22 -1
- package/dist/providers/openCode.js +460 -126
- package/dist/providers/openCodeDatabase.d.ts +10 -0
- package/dist/providers/openCodeDatabase.js +69 -0
- package/dist/providers/rolloutWalker.d.ts +53 -0
- package/dist/providers/rolloutWalker.js +209 -0
- package/dist/providers/types.d.ts +82 -2
- package/dist/providers/types.js +4 -0
- package/dist/quota.d.ts +34 -4
- package/dist/quota.js +37 -9
- package/dist/quotaHistory.d.ts +3 -2
- package/dist/quotaHistory.js +36 -35
- package/dist/quotaPoller.d.ts +13 -1
- package/dist/quotaPoller.js +65 -3
- package/dist/quotaResolver.d.ts +81 -0
- package/dist/quotaResolver.js +213 -0
- package/dist/quotaSnapshots.d.ts +15 -2
- package/dist/quotaSnapshots.js +25 -3
- package/dist/quotaThresholds.d.ts +60 -0
- package/dist/quotaThresholds.js +90 -0
- package/dist/report/htmlReportGenerator.js +10 -4
- package/dist/report/sessionReportInputs.d.ts +23 -0
- package/dist/report/sessionReportInputs.js +34 -0
- package/dist/schemas/accountManager.d.ts +2 -2
- package/dist/schemas/accountManager.js +2 -4
- package/dist/schemas/accountStatus.d.ts +3 -0
- package/dist/schemas/accountStatus.js +1 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.js +16 -2
- package/dist/schemas/observedSessionV1.d.ts +27 -26
- package/dist/schemas/observedSessionV1.js +6 -4
- package/dist/schemas/quota.d.ts +141 -2
- package/dist/schemas/quota.js +20 -8
- package/dist/schemas/quotaHistory.d.ts +3 -2
- package/dist/schemas/quotaHistory.js +1 -1
- package/dist/schemas/sessionEvent.d.ts +6 -0
- package/dist/schemas/sessionEvent.js +1 -0
- package/dist/schemas/stateFile.d.ts +198 -0
- package/dist/schemas/stateFile.js +77 -0
- package/dist/schemas/tokenEstimation.d.ts +1 -1
- package/dist/schemas/transcript.js +2 -0
- package/dist/sessionFingerprint.d.ts +25 -0
- package/dist/sessionFingerprint.js +46 -0
- package/dist/sessionMonitor.d.ts +15 -0
- package/dist/sessionMonitor.js +142 -0
- package/dist/sessionPreviews.d.ts +33 -2
- package/dist/sessionPreviews.js +333 -6
- package/dist/sessionStats.d.ts +51 -0
- package/dist/sessionStats.js +166 -0
- package/dist/stateFile.d.ts +113 -0
- package/dist/stateFile.js +160 -0
- package/dist/statusline/claudeStatuslinePayload.d.ts +89 -0
- package/dist/statusline/claudeStatuslinePayload.js +152 -0
- package/dist/statusline/formatter.d.ts +13 -0
- package/dist/statusline/formatter.js +48 -6
- package/dist/statusline/index.d.ts +10 -2
- package/dist/statusline/index.js +19 -1
- package/dist/tokenSummary.d.ts +62 -0
- package/dist/tokenSummary.js +72 -0
- package/dist/transcript.d.ts +5 -0
- package/dist/transcript.js +2 -0
- package/dist/types/observedSessionV1.d.ts +8 -2
- package/dist/types/observedSessionV1.js +88 -25
- package/dist/types/sessionEvent.d.ts +2 -0
- package/dist/usage/billingBlocks.d.ts +85 -0
- package/dist/usage/billingBlocks.js +153 -0
- package/dist/usage/importSessionHistory.d.ts +53 -0
- package/dist/usage/importSessionHistory.js +88 -0
- package/dist/usage/usageEvents.d.ts +92 -0
- package/dist/usage/usageEvents.js +322 -0
- package/dist/usage/usageReports.d.ts +76 -0
- package/dist/usage/usageReports.js +208 -0
- package/dist/watchers/factory.d.ts +6 -0
- package/dist/watchers/factory.js +30 -25
- package/dist/zaiQuotaApi.d.ts +2 -0
- package/dist/zaiQuotaApi.js +2 -0
- package/package.json +22 -1
|
@@ -44,15 +44,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
44
44
|
};
|
|
45
45
|
})();
|
|
46
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.SESSION_ACTIVITY_STALENESS_MS = exports.SESSION_ACTIVITY_GRACE_PERIOD_MS = void 0;
|
|
47
48
|
exports.detectSessionActivity = detectSessionActivity;
|
|
49
|
+
exports.classifySessionActivity = classifySessionActivity;
|
|
50
|
+
exports.refreshSessionActivityState = refreshSessionActivityState;
|
|
48
51
|
const fs = __importStar(require("fs"));
|
|
49
52
|
// ── Constants ──
|
|
50
53
|
/** How many bytes to read from the end of the file for analysis */
|
|
51
54
|
const TAIL_BYTES = 32 * 1024;
|
|
52
55
|
/** Grace period to prevent spinner flicker (ms) */
|
|
53
|
-
|
|
56
|
+
exports.SESSION_ACTIVITY_GRACE_PERIOD_MS = 5_000;
|
|
57
|
+
const GRACE_PERIOD_MS = exports.SESSION_ACTIVITY_GRACE_PERIOD_MS;
|
|
54
58
|
/** If mtime is older than this, session is stale regardless of content */
|
|
55
|
-
|
|
59
|
+
exports.SESSION_ACTIVITY_STALENESS_MS = 5 * 60 * 1000;
|
|
60
|
+
const STALENESS_THRESHOLD_MS = exports.SESSION_ACTIVITY_STALENESS_MS;
|
|
61
|
+
/** How many trailing events the in-memory classifier inspects (about a 32 KiB tail). */
|
|
62
|
+
const TAIL_EVENTS = 200;
|
|
56
63
|
// ── Event Classification Patterns ──
|
|
57
64
|
/** Patterns indicating the AI is actively working */
|
|
58
65
|
const AI_ACTIVITY_PATTERNS = [
|
|
@@ -105,7 +112,9 @@ function detectSessionActivity(sessionPath) {
|
|
|
105
112
|
if (lines.length === 0) {
|
|
106
113
|
return { state: 'ended', lastActivityTime: new Date(stat.mtimeMs), reason: 'no-events' };
|
|
107
114
|
}
|
|
108
|
-
|
|
115
|
+
return classifyFromSignals(signalsFromLines(lines), stat.mtimeMs, mtimeAge);
|
|
116
|
+
}
|
|
117
|
+
function signalsFromLines(lines) {
|
|
109
118
|
let lastAiActivityIndex = -1;
|
|
110
119
|
let lastEndingIndex = -1;
|
|
111
120
|
let hasTerminal = false;
|
|
@@ -135,31 +144,117 @@ function detectSessionActivity(sessionPath) {
|
|
|
135
144
|
}
|
|
136
145
|
}
|
|
137
146
|
}
|
|
147
|
+
return { lastAiActivityIndex, lastEndingIndex, hasTerminal };
|
|
148
|
+
}
|
|
149
|
+
function hasToolResultBlock(event) {
|
|
150
|
+
const content = event.message?.content;
|
|
151
|
+
return (Array.isArray(content) &&
|
|
152
|
+
content.some((block) => typeof block === 'object' &&
|
|
153
|
+
block !== null &&
|
|
154
|
+
block.type === 'tool_result'));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The same signals the tail scanner derives from raw JSONL lines, read from
|
|
158
|
+
* canonical events instead: assistant, tool-use, and tool-result events (and
|
|
159
|
+
* user events carrying tool results) are AI activity; an assistant turn that
|
|
160
|
+
* stopped with `end_turn` or a user prompt is an ending event.
|
|
161
|
+
*/
|
|
162
|
+
function signalsFromEvents(events) {
|
|
163
|
+
let lastAiActivityIndex = -1;
|
|
164
|
+
let lastEndingIndex = -1;
|
|
165
|
+
for (let i = 0; i < events.length; i++) {
|
|
166
|
+
const event = events[i];
|
|
167
|
+
const carriesToolResult = event.type === 'user' && hasToolResultBlock(event);
|
|
168
|
+
if (event.type === 'assistant' ||
|
|
169
|
+
event.type === 'tool_use' ||
|
|
170
|
+
event.type === 'tool_result' ||
|
|
171
|
+
carriesToolResult) {
|
|
172
|
+
lastAiActivityIndex = i;
|
|
173
|
+
}
|
|
174
|
+
if ((event.type === 'assistant' && event.message?.stop_reason === 'end_turn') ||
|
|
175
|
+
(event.type === 'user' && !carriesToolResult)) {
|
|
176
|
+
lastEndingIndex = i;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { lastAiActivityIndex, lastEndingIndex, hasTerminal: false };
|
|
180
|
+
}
|
|
181
|
+
function classifyFromSignals(signals, mtimeMs, mtimeAge) {
|
|
182
|
+
const lastActivityTime = new Date(mtimeMs);
|
|
183
|
+
const { lastAiActivityIndex, lastEndingIndex, hasTerminal } = signals;
|
|
138
184
|
// Terminal patterns mean the session is definitely done
|
|
139
185
|
if (hasTerminal) {
|
|
140
|
-
return { state: 'ended', lastActivityTime
|
|
186
|
+
return { state: 'ended', lastActivityTime, reason: 'terminal-event' };
|
|
141
187
|
}
|
|
142
|
-
// AI activity after the last ending event
|
|
188
|
+
// AI activity after the last ending event -> ongoing
|
|
143
189
|
if (lastAiActivityIndex > lastEndingIndex) {
|
|
144
|
-
return {
|
|
145
|
-
state: 'ongoing',
|
|
146
|
-
lastActivityTime: new Date(stat.mtimeMs),
|
|
147
|
-
reason: 'ai-activity-after-ending',
|
|
148
|
-
};
|
|
190
|
+
return { state: 'ongoing', lastActivityTime, reason: 'ai-activity-after-ending' };
|
|
149
191
|
}
|
|
150
192
|
// Ending event with no subsequent AI activity
|
|
151
193
|
if (lastEndingIndex >= 0) {
|
|
152
194
|
// Apply grace period to prevent flicker
|
|
153
195
|
if (mtimeAge < GRACE_PERIOD_MS) {
|
|
154
|
-
return { state: 'ongoing', lastActivityTime
|
|
196
|
+
return { state: 'ongoing', lastActivityTime, reason: 'grace-period' };
|
|
155
197
|
}
|
|
156
|
-
return { state: 'ended', lastActivityTime
|
|
198
|
+
return { state: 'ended', lastActivityTime, reason: 'ending-event' };
|
|
157
199
|
}
|
|
158
|
-
// No clear signal
|
|
200
|
+
// No clear signal: if recently modified, assume ongoing
|
|
159
201
|
if (mtimeAge < GRACE_PERIOD_MS) {
|
|
160
|
-
return { state: 'ongoing', lastActivityTime
|
|
202
|
+
return { state: 'ongoing', lastActivityTime, reason: 'recent-mtime' };
|
|
203
|
+
}
|
|
204
|
+
return { state: 'ended', lastActivityTime, reason: 'no-activity-signal' };
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Classify a session from events already in memory, with the same states,
|
|
208
|
+
* reasons, grace period, and staleness rule as {@link detectSessionActivity},
|
|
209
|
+
* but without opening the file again. Works for every provider (the raw
|
|
210
|
+
* tail patterns only ever matched Claude Code JSONL) and for database-backed
|
|
211
|
+
* sessions that have no file to tail.
|
|
212
|
+
*/
|
|
213
|
+
function classifySessionActivity(options) {
|
|
214
|
+
const now = options.now ?? Date.now();
|
|
215
|
+
const events = options.events;
|
|
216
|
+
const lastEventMs = events.length > 0 ? Date.parse(events[events.length - 1].timestamp) : NaN;
|
|
217
|
+
const mtimeMs = typeof options.mtimeMs === 'number' && Number.isFinite(options.mtimeMs)
|
|
218
|
+
? options.mtimeMs
|
|
219
|
+
: Number.isFinite(lastEventMs)
|
|
220
|
+
? lastEventMs
|
|
221
|
+
: null;
|
|
222
|
+
if (mtimeMs === null) {
|
|
223
|
+
return { state: 'ended', lastActivityTime: null, reason: 'no-events' };
|
|
224
|
+
}
|
|
225
|
+
const mtimeAge = now - mtimeMs;
|
|
226
|
+
if (mtimeAge > STALENESS_THRESHOLD_MS) {
|
|
227
|
+
return { state: 'stale', lastActivityTime: new Date(mtimeMs), reason: 'mtime-stale' };
|
|
228
|
+
}
|
|
229
|
+
if (events.length === 0) {
|
|
230
|
+
return { state: 'ended', lastActivityTime: new Date(mtimeMs), reason: 'no-events' };
|
|
231
|
+
}
|
|
232
|
+
const tail = events.length > TAIL_EVENTS ? events.slice(-TAIL_EVENTS) : events;
|
|
233
|
+
return classifyFromSignals(signalsFromEvents(tail), mtimeMs, mtimeAge);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Refresh a cached classification from its unchanged fingerprint without
|
|
237
|
+
* re-reading the transcript. An active file remains active until it crosses
|
|
238
|
+
* the same five-minute staleness boundary used by detectSessionActivity,
|
|
239
|
+
* unless it was active only by grace period (`previousReason`).
|
|
240
|
+
*/
|
|
241
|
+
function refreshSessionActivityState(previous, mtimeMs, nowMs = Date.now(), previousReason) {
|
|
242
|
+
if (!Number.isFinite(mtimeMs))
|
|
243
|
+
return previous;
|
|
244
|
+
if (nowMs - mtimeMs > STALENESS_THRESHOLD_MS)
|
|
245
|
+
return 'idle';
|
|
246
|
+
if (previous === 'ended')
|
|
247
|
+
return 'ended';
|
|
248
|
+
if (previous === 'idle')
|
|
249
|
+
return 'idle';
|
|
250
|
+
// A session that was only active thanks to the grace period ends once the
|
|
251
|
+
// grace period lapses, exactly as a fresh classification would say.
|
|
252
|
+
if (previous === 'active' &&
|
|
253
|
+
(previousReason === 'grace-period' || previousReason === 'recent-mtime') &&
|
|
254
|
+
nowMs - mtimeMs >= GRACE_PERIOD_MS) {
|
|
255
|
+
return 'ended';
|
|
161
256
|
}
|
|
162
|
-
return
|
|
257
|
+
return previous === 'unknown' ? 'unknown' : 'active';
|
|
163
258
|
}
|
|
164
259
|
// ── Helpers ──
|
|
165
260
|
function readTail(filePath, fileSize) {
|
|
@@ -205,6 +205,17 @@ export declare function getAllProjectFolders(workspacePath?: string): ProjectFol
|
|
|
205
205
|
* ```
|
|
206
206
|
*/
|
|
207
207
|
export declare function findSessionsInDirectory(sessionDir: string): string[];
|
|
208
|
+
export interface SessionFileStat {
|
|
209
|
+
path: string;
|
|
210
|
+
mtime: Date;
|
|
211
|
+
sizeBytes: number;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The non-empty `.jsonl` files in a session directory with the stat each one
|
|
215
|
+
* already cost, newest first, so callers that need the mtime do not stat the
|
|
216
|
+
* same files a second time.
|
|
217
|
+
*/
|
|
218
|
+
export declare function findSessionFilesWithStats(sessionDir: string): SessionFileStat[];
|
|
208
219
|
/**
|
|
209
220
|
* Detects if a workspace is a git worktree and resolves the main repo path.
|
|
210
221
|
*
|
|
@@ -54,6 +54,7 @@ exports.findAllSessions = findAllSessions;
|
|
|
54
54
|
exports.decodeEncodedPath = decodeEncodedPath;
|
|
55
55
|
exports.getAllProjectFolders = getAllProjectFolders;
|
|
56
56
|
exports.findSessionsInDirectory = findSessionsInDirectory;
|
|
57
|
+
exports.findSessionFilesWithStats = findSessionFilesWithStats;
|
|
57
58
|
exports.resolveWorktreeMainRepo = resolveWorktreeMainRepo;
|
|
58
59
|
exports.discoverWorktreeSiblings = discoverWorktreeSiblings;
|
|
59
60
|
exports.findAllSessionsWithWorktrees = findAllSessionsWithWorktrees;
|
|
@@ -590,31 +591,33 @@ function getAllProjectFolders(workspacePath) {
|
|
|
590
591
|
* ```
|
|
591
592
|
*/
|
|
592
593
|
function findSessionsInDirectory(sessionDir) {
|
|
594
|
+
return findSessionFilesWithStats(sessionDir).map((file) => file.path);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* The non-empty `.jsonl` files in a session directory with the stat each one
|
|
598
|
+
* already cost, newest first, so callers that need the mtime do not stat the
|
|
599
|
+
* same files a second time.
|
|
600
|
+
*/
|
|
601
|
+
function findSessionFilesWithStats(sessionDir) {
|
|
593
602
|
try {
|
|
594
603
|
if (!fs.existsSync(sessionDir)) {
|
|
595
604
|
return [];
|
|
596
605
|
}
|
|
597
|
-
|
|
606
|
+
return fs
|
|
598
607
|
.readdirSync(sessionDir)
|
|
599
608
|
.filter((file) => file.endsWith('.jsonl'))
|
|
600
609
|
.map((file) => {
|
|
601
610
|
const fullPath = path.join(sessionDir, file);
|
|
602
611
|
try {
|
|
603
612
|
const stats = fs.statSync(fullPath);
|
|
604
|
-
return {
|
|
605
|
-
path: fullPath,
|
|
606
|
-
mtime: stats.mtime.getTime(),
|
|
607
|
-
size: stats.size,
|
|
608
|
-
};
|
|
613
|
+
return { path: fullPath, mtime: stats.mtime, sizeBytes: stats.size };
|
|
609
614
|
}
|
|
610
615
|
catch {
|
|
611
616
|
return null;
|
|
612
617
|
}
|
|
613
618
|
})
|
|
614
|
-
.filter((f) => f !== null && f.
|
|
615
|
-
.sort((a, b) => b.mtime - a.mtime)
|
|
616
|
-
.map((f) => f.path);
|
|
617
|
-
return files;
|
|
619
|
+
.filter((f) => f !== null && f.sizeBytes > 0)
|
|
620
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
618
621
|
}
|
|
619
622
|
catch {
|
|
620
623
|
return [];
|
package/dist/peakHours.d.ts
CHANGED
|
@@ -22,9 +22,34 @@ export interface PeakHoursState {
|
|
|
22
22
|
updatedAt: string;
|
|
23
23
|
unavailable: boolean;
|
|
24
24
|
notApplicable?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* `promoclock` when the state came from promoclock.co, `schedule` when it
|
|
27
|
+
* was computed locally from the published weekday window. Absent on the
|
|
28
|
+
* not-applicable and unavailable placeholder states.
|
|
29
|
+
*/
|
|
30
|
+
source?: 'promoclock' | 'schedule';
|
|
25
31
|
}
|
|
26
|
-
/**
|
|
27
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Default budget for the promoclock.co request, in milliseconds. The schedule
|
|
34
|
+
* fallback answers the question anyway, so a slow third-party host should not
|
|
35
|
+
* hold up a `sidekick status` or `sidekick quota` run for long.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DEFAULT_PEAK_HOURS_TIMEOUT_MS = 4000;
|
|
38
|
+
/** A promoclock.co answer is reused for this long before the host is asked again. */
|
|
39
|
+
export declare const PEAK_HOURS_CACHE_MS: number;
|
|
40
|
+
/** Published peak window: weekdays 13:00–19:00 UTC. */
|
|
41
|
+
export declare const PEAK_WINDOW_START_UTC_HOUR = 13;
|
|
42
|
+
export declare const PEAK_WINDOW_END_UTC_HOUR = 19;
|
|
43
|
+
export declare const PEAK_HOURS_DESCRIPTION = "Weekdays 13:00\u201319:00 UTC";
|
|
44
|
+
/** Forget the cached promoclock.co answer. Test-only. */
|
|
45
|
+
export declare function _resetPeakHoursCache(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Peak-hours state computed from the published schedule alone, with no
|
|
48
|
+
* network access. Used directly by cache-only commands (`sidekick today`) and
|
|
49
|
+
* as the fallback when promoclock.co cannot be reached, so every surface
|
|
50
|
+
* agrees on whether it is currently peak.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getScheduledPeakHoursState(now?: Date): PeakHoursState;
|
|
28
53
|
/** Options for {@link fetchPeakHoursStatus}. */
|
|
29
54
|
export interface FetchPeakHoursOptions {
|
|
30
55
|
/**
|
|
@@ -32,6 +57,8 @@ export interface FetchPeakHoursOptions {
|
|
|
32
57
|
* Defaults to {@link DEFAULT_PEAK_HOURS_TIMEOUT_MS}.
|
|
33
58
|
*/
|
|
34
59
|
timeoutMs?: number;
|
|
60
|
+
/** Bypass the in-process cache and ask promoclock.co again. */
|
|
61
|
+
force?: boolean;
|
|
35
62
|
}
|
|
36
63
|
export declare function isClaudeCodeSessionProvider(providerId: ProviderId): boolean;
|
|
37
64
|
export declare function createPeakHoursNotApplicableState(providerId: ProviderId): PeakHoursState;
|
|
@@ -40,7 +67,11 @@ export declare function scopePeakHoursToSessionProvider(providerId: ProviderId,
|
|
|
40
67
|
* Fetch current Claude peak-hours state from promoclock.co.
|
|
41
68
|
*
|
|
42
69
|
* Single-shot — caller wraps in polling loop, EventEmitter, or interval.
|
|
43
|
-
*
|
|
70
|
+
* A successful answer is cached in-process for {@link PEAK_HOURS_CACHE_MS}.
|
|
71
|
+
* On any network, timeout, or parse error the state is computed from the
|
|
72
|
+
* published schedule instead (`source: 'schedule'`), so callers always get a
|
|
73
|
+
* usable answer and every surface agrees on it; {@link unavailableState} is
|
|
74
|
+
* only returned when the schedule itself cannot be evaluated.
|
|
44
75
|
*
|
|
45
76
|
* promoclock.co is a third-party host, so the request is always bounded by
|
|
46
77
|
* an abort timeout. Without one a hung host would stall the caller — and
|
package/dist/peakHours.js
CHANGED
|
@@ -11,14 +11,74 @@
|
|
|
11
11
|
* Polling / eventing is the caller's responsibility.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = void 0;
|
|
14
|
+
exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_WINDOW_END_UTC_HOUR = exports.PEAK_WINDOW_START_UTC_HOUR = exports.PEAK_HOURS_CACHE_MS = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = void 0;
|
|
15
|
+
exports._resetPeakHoursCache = _resetPeakHoursCache;
|
|
16
|
+
exports.getScheduledPeakHoursState = getScheduledPeakHoursState;
|
|
15
17
|
exports.isClaudeCodeSessionProvider = isClaudeCodeSessionProvider;
|
|
16
18
|
exports.createPeakHoursNotApplicableState = createPeakHoursNotApplicableState;
|
|
17
19
|
exports.scopePeakHoursToSessionProvider = scopePeakHoursToSessionProvider;
|
|
18
20
|
exports.fetchPeakHoursStatus = fetchPeakHoursStatus;
|
|
19
21
|
const PROMOCLOCK_ENDPOINT = 'https://promoclock.co/api/status';
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Default budget for the promoclock.co request, in milliseconds. The schedule
|
|
24
|
+
* fallback answers the question anyway, so a slow third-party host should not
|
|
25
|
+
* hold up a `sidekick status` or `sidekick quota` run for long.
|
|
26
|
+
*/
|
|
27
|
+
exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = 4_000;
|
|
28
|
+
/** A promoclock.co answer is reused for this long before the host is asked again. */
|
|
29
|
+
exports.PEAK_HOURS_CACHE_MS = 10 * 60_000;
|
|
30
|
+
/** Published peak window: weekdays 13:00–19:00 UTC. */
|
|
31
|
+
exports.PEAK_WINDOW_START_UTC_HOUR = 13;
|
|
32
|
+
exports.PEAK_WINDOW_END_UTC_HOUR = 19;
|
|
33
|
+
exports.PEAK_HOURS_DESCRIPTION = 'Weekdays 13:00–19:00 UTC';
|
|
34
|
+
let cachedNetworkState = null;
|
|
35
|
+
/** Forget the cached promoclock.co answer. Test-only. */
|
|
36
|
+
function _resetPeakHoursCache() {
|
|
37
|
+
cachedNetworkState = null;
|
|
38
|
+
}
|
|
39
|
+
function isWeekdayUtc(date) {
|
|
40
|
+
const day = date.getUTCDay();
|
|
41
|
+
return day >= 1 && day <= 5;
|
|
42
|
+
}
|
|
43
|
+
function utcDateAtHour(date, hour, dayOffset = 0) {
|
|
44
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + dayOffset, hour));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Peak-hours state computed from the published schedule alone, with no
|
|
48
|
+
* network access. Used directly by cache-only commands (`sidekick today`) and
|
|
49
|
+
* as the fallback when promoclock.co cannot be reached, so every surface
|
|
50
|
+
* agrees on whether it is currently peak.
|
|
51
|
+
*/
|
|
52
|
+
function getScheduledPeakHoursState(now = new Date()) {
|
|
53
|
+
const hour = now.getUTCHours() + now.getUTCMinutes() / 60;
|
|
54
|
+
const isPeak = isWeekdayUtc(now) && hour >= exports.PEAK_WINDOW_START_UTC_HOUR && hour < exports.PEAK_WINDOW_END_UTC_HOUR;
|
|
55
|
+
let nextChange;
|
|
56
|
+
if (isPeak) {
|
|
57
|
+
nextChange = utcDateAtHour(now, exports.PEAK_WINDOW_END_UTC_HOUR);
|
|
58
|
+
}
|
|
59
|
+
else if (isWeekdayUtc(now) && hour < exports.PEAK_WINDOW_START_UTC_HOUR) {
|
|
60
|
+
nextChange = utcDateAtHour(now, exports.PEAK_WINDOW_START_UTC_HOUR);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
let offset = 1;
|
|
64
|
+
while (!isWeekdayUtc(utcDateAtHour(now, 0, offset)))
|
|
65
|
+
offset += 1;
|
|
66
|
+
nextChange = utcDateAtHour(now, exports.PEAK_WINDOW_START_UTC_HOUR, offset);
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
status: isPeak ? 'peak' : 'off_peak',
|
|
70
|
+
isPeak,
|
|
71
|
+
sessionLimitSpeed: isPeak ? 'faster' : 'normal',
|
|
72
|
+
label: isPeak ? 'Peak Hours' : 'Off-Peak',
|
|
73
|
+
peakHoursDescription: exports.PEAK_HOURS_DESCRIPTION,
|
|
74
|
+
nextChange: nextChange.toISOString(),
|
|
75
|
+
minutesUntilChange: Math.max(0, Math.round((nextChange.getTime() - now.getTime()) / 60_000)),
|
|
76
|
+
note: 'Computed from the published weekday schedule.',
|
|
77
|
+
updatedAt: now.toISOString(),
|
|
78
|
+
unavailable: false,
|
|
79
|
+
source: 'schedule',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
22
82
|
function unavailableState() {
|
|
23
83
|
return {
|
|
24
84
|
status: 'unknown',
|
|
@@ -76,13 +136,23 @@ function normalizeSpeed(raw) {
|
|
|
76
136
|
* Fetch current Claude peak-hours state from promoclock.co.
|
|
77
137
|
*
|
|
78
138
|
* Single-shot — caller wraps in polling loop, EventEmitter, or interval.
|
|
79
|
-
*
|
|
139
|
+
* A successful answer is cached in-process for {@link PEAK_HOURS_CACHE_MS}.
|
|
140
|
+
* On any network, timeout, or parse error the state is computed from the
|
|
141
|
+
* published schedule instead (`source: 'schedule'`), so callers always get a
|
|
142
|
+
* usable answer and every surface agrees on it; {@link unavailableState} is
|
|
143
|
+
* only returned when the schedule itself cannot be evaluated.
|
|
80
144
|
*
|
|
81
145
|
* promoclock.co is a third-party host, so the request is always bounded by
|
|
82
146
|
* an abort timeout. Without one a hung host would stall the caller — and
|
|
83
147
|
* this is polled, so the stall would repeat.
|
|
84
148
|
*/
|
|
85
149
|
async function fetchPeakHoursStatus(options = {}) {
|
|
150
|
+
const now = Date.now();
|
|
151
|
+
if (!options.force &&
|
|
152
|
+
cachedNetworkState &&
|
|
153
|
+
now - cachedNetworkState.fetchedAt < exports.PEAK_HOURS_CACHE_MS) {
|
|
154
|
+
return cachedNetworkState.state;
|
|
155
|
+
}
|
|
86
156
|
const timeoutMs = options.timeoutMs ?? exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS;
|
|
87
157
|
const controller = new AbortController();
|
|
88
158
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -90,12 +160,12 @@ async function fetchPeakHoursStatus(options = {}) {
|
|
|
90
160
|
try {
|
|
91
161
|
const res = await fetch(PROMOCLOCK_ENDPOINT, { signal: controller.signal });
|
|
92
162
|
if (!res.ok)
|
|
93
|
-
return
|
|
163
|
+
return scheduleFallback();
|
|
94
164
|
const data = await res.json();
|
|
95
165
|
const status = normalizeStatus(data.status);
|
|
96
166
|
const sessionLimitSpeed = normalizeSpeed(data.sessionLimitSpeed);
|
|
97
167
|
const isPeak = typeof data.isPeak === 'boolean' ? data.isPeak : status === 'peak';
|
|
98
|
-
|
|
168
|
+
const state = {
|
|
99
169
|
status,
|
|
100
170
|
isPeak,
|
|
101
171
|
sessionLimitSpeed,
|
|
@@ -106,13 +176,28 @@ async function fetchPeakHoursStatus(options = {}) {
|
|
|
106
176
|
note: data.note ?? '',
|
|
107
177
|
updatedAt: data.timestamp ?? new Date().toISOString(),
|
|
108
178
|
unavailable: false,
|
|
179
|
+
source: 'promoclock',
|
|
109
180
|
};
|
|
181
|
+
cachedNetworkState = { state, fetchedAt: now };
|
|
182
|
+
return state;
|
|
110
183
|
}
|
|
111
184
|
catch {
|
|
112
185
|
// Covers AbortError from the timeout above alongside network/parse failures.
|
|
113
|
-
return
|
|
186
|
+
return scheduleFallback();
|
|
114
187
|
}
|
|
115
188
|
finally {
|
|
116
189
|
clearTimeout(timeout);
|
|
117
190
|
}
|
|
118
191
|
}
|
|
192
|
+
function scheduleFallback() {
|
|
193
|
+
try {
|
|
194
|
+
const state = getScheduledPeakHoursState();
|
|
195
|
+
return {
|
|
196
|
+
...state,
|
|
197
|
+
note: 'promoclock.co unreachable; computed from the published weekday schedule.',
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return unavailableState();
|
|
202
|
+
}
|
|
203
|
+
}
|
package/dist/pricingCatalog.d.ts
CHANGED
|
@@ -34,6 +34,13 @@ export interface HydrateOptions {
|
|
|
34
34
|
url?: string;
|
|
35
35
|
/** Optional logger (useful for diagnostics without pulling a logger dep). */
|
|
36
36
|
logger?: (msg: string) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Never touch the network: apply the on-disk cache regardless of its age, or
|
|
39
|
+
* stay on the static tables when there is none. Callers that must produce
|
|
40
|
+
* the same figures on every run (scripted reports, tests, air-gapped hosts)
|
|
41
|
+
* set this; `SIDEKICK_OFFLINE=1` does the same for the CLI.
|
|
42
|
+
*/
|
|
43
|
+
offline?: boolean;
|
|
37
44
|
}
|
|
38
45
|
export interface HydrateResult {
|
|
39
46
|
/** Where the loaded pricing came from. */
|
package/dist/pricingCatalog.js
CHANGED
|
@@ -60,6 +60,7 @@ const path = __importStar(require("node:path"));
|
|
|
60
60
|
const modelContext_1 = require("./modelContext");
|
|
61
61
|
const modelInfo_1 = require("./modelInfo");
|
|
62
62
|
const paths_1 = require("./paths");
|
|
63
|
+
const atomic_1 = require("./writers/atomic");
|
|
63
64
|
// ── Constants ──
|
|
64
65
|
exports.LITELLM_CATALOG_URL = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';
|
|
65
66
|
const CACHE_FILE_NAME = 'pricing-catalog.json';
|
|
@@ -77,16 +78,16 @@ const DEFAULT_TIMEOUT_MS = 3_000;
|
|
|
77
78
|
* Always resolves — never throws. Offline-safe.
|
|
78
79
|
*/
|
|
79
80
|
async function hydratePricingCatalog(options = {}) {
|
|
80
|
-
const { cacheDir = (0, paths_1.getConfigDir)(), fetchImpl = globalThis.fetch, ttlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, url = exports.LITELLM_CATALOG_URL, logger, } = options;
|
|
81
|
+
const { cacheDir = (0, paths_1.getConfigDir)(), fetchImpl = globalThis.fetch, ttlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, url = exports.LITELLM_CATALOG_URL, logger, offline = false, } = options;
|
|
81
82
|
const cachePath = path.join(cacheDir, CACHE_FILE_NAME);
|
|
82
83
|
const now = Date.now();
|
|
83
|
-
// 1. Fresh cache?
|
|
84
|
+
// 1. Fresh cache? (Offline callers take any cache, however old.)
|
|
84
85
|
const cached = await readCache(cachePath);
|
|
85
|
-
if (cached && now - Date.parse(cached.fetchedAt) < ttlMs) {
|
|
86
|
+
if (cached && (offline || now - Date.parse(cached.fetchedAt) < ttlMs)) {
|
|
86
87
|
return applyCacheFile(cached, 'cache');
|
|
87
88
|
}
|
|
88
89
|
// 2. Try network.
|
|
89
|
-
if (fetchImpl) {
|
|
90
|
+
if (fetchImpl && !offline) {
|
|
90
91
|
const fetched = await fetchCatalog(url, fetchImpl, timeoutMs, logger);
|
|
91
92
|
if (fetched) {
|
|
92
93
|
const payload = {
|
|
@@ -256,7 +257,9 @@ async function readCache(cachePath) {
|
|
|
256
257
|
async function writeCache(cachePath, payload, logger) {
|
|
257
258
|
try {
|
|
258
259
|
await node_fs_1.promises.mkdir(path.dirname(cachePath), { recursive: true });
|
|
259
|
-
|
|
260
|
+
// The CLI and the extension host can both refresh the catalog at once;
|
|
261
|
+
// the atomic writer keeps a reader from ever seeing a half-written file.
|
|
262
|
+
await (0, atomic_1.atomicWriteJson)(cachePath, payload);
|
|
260
263
|
}
|
|
261
264
|
catch (err) {
|
|
262
265
|
logger?.(`pricingCatalog: failed to write cache: ${String(err)}`);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Browser-safe provider ID catalogs. Types are derived from these values. */
|
|
2
|
+
export declare const SESSION_PROVIDER_IDS: readonly ["claude-code", "opencode", "codex"];
|
|
3
|
+
export type SessionProviderId = (typeof SESSION_PROVIDER_IDS)[number];
|
|
4
|
+
export declare const ACCOUNT_PROVIDER_IDS: readonly ["claude-code", "codex"];
|
|
5
|
+
export type AccountProviderId = (typeof ACCOUNT_PROVIDER_IDS)[number];
|
|
6
|
+
export declare const QUOTA_PROVIDER_IDS: readonly ["claude-code", "codex", "zai"];
|
|
7
|
+
export type QuotaProviderId = (typeof QUOTA_PROVIDER_IDS)[number];
|
|
8
|
+
export declare const RUNTIME_QUOTA_PROVIDER_IDS: readonly ["claude", "codex", "zai"];
|
|
9
|
+
export type RuntimeQuotaProviderId = (typeof RUNTIME_QUOTA_PROVIDER_IDS)[number];
|
|
10
|
+
export declare const MODEL_PROVIDER_IDS: readonly ["anthropic", "openai", "google", "unknown"];
|
|
11
|
+
export type ModelProviderId = (typeof MODEL_PROVIDER_IDS)[number];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MODEL_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.SESSION_PROVIDER_IDS = void 0;
|
|
4
|
+
/** Browser-safe provider ID catalogs. Types are derived from these values. */
|
|
5
|
+
exports.SESSION_PROVIDER_IDS = ['claude-code', 'opencode', 'codex'];
|
|
6
|
+
exports.ACCOUNT_PROVIDER_IDS = ['claude-code', 'codex'];
|
|
7
|
+
exports.QUOTA_PROVIDER_IDS = ['claude-code', 'codex', 'zai'];
|
|
8
|
+
exports.RUNTIME_QUOTA_PROVIDER_IDS = ['claude', 'codex', 'zai'];
|
|
9
|
+
exports.MODEL_PROVIDER_IDS = ['anthropic', 'openai', 'google', 'unknown'];
|
package/dist/providerQuota.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { PeakHoursState } from './peakHours';
|
|
2
2
|
import type { QuotaState } from './quota';
|
|
3
3
|
import type { QuotaFailureDescriptor } from './quotaPresentation';
|
|
4
|
-
|
|
4
|
+
import type { RuntimeQuotaProviderId } from './providerIds';
|
|
5
|
+
export { RUNTIME_QUOTA_PROVIDER_IDS } from './providerIds';
|
|
6
|
+
export type RuntimeQuotaProvider = RuntimeQuotaProviderId;
|
|
5
7
|
export interface ProviderQuotaState<TProvider extends RuntimeQuotaProvider = RuntimeQuotaProvider> extends QuotaState {
|
|
6
8
|
runtimeProvider: TProvider;
|
|
7
9
|
accountLabel?: string;
|
package/dist/providerQuota.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RUNTIME_QUOTA_PROVIDER_IDS = void 0;
|
|
4
|
+
var providerIds_1 = require("./providerIds");
|
|
5
|
+
Object.defineProperty(exports, "RUNTIME_QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.RUNTIME_QUOTA_PROVIDER_IDS; } });
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ReadSessionContextSnapshotOptions, SessionContextSnapshot } from '../context/sessionContext';
|
|
11
11
|
import type { SubagentStats, TokenUsage } from '../types/sessionEvent';
|
|
12
|
-
import type { SessionProviderBase, SessionReader, SessionFileInfo, SessionFileStats, SearchHit, ProjectFolderInfo, ProviderId } from './types';
|
|
12
|
+
import type { SessionProviderBase, SessionReader, SessionFileInfo, SessionFileStats, SearchHit, ProjectFolderInfo, ProviderId, ProviderOperationStatus, ProviderRuntimeStatus, SessionProviderOptions } from './types';
|
|
13
13
|
/**
|
|
14
14
|
* Session provider for Claude Code CLI.
|
|
15
15
|
*
|
|
@@ -20,27 +20,35 @@ import type { SessionProviderBase, SessionReader, SessionFileInfo, SessionFileSt
|
|
|
20
20
|
export declare class ClaudeCodeProvider implements SessionProviderBase {
|
|
21
21
|
readonly id: ProviderId;
|
|
22
22
|
readonly displayName = "Claude Code";
|
|
23
|
+
private readonly diagnostics;
|
|
23
24
|
/** Runtime-reported context window limit (overrides static map when set). */
|
|
24
25
|
private dynamicContextWindowLimit;
|
|
26
|
+
constructor(options?: SessionProviderOptions);
|
|
25
27
|
getSessionDirectory(workspacePath: string): string;
|
|
26
28
|
discoverSessionDirectory(workspacePath: string): string | null;
|
|
27
29
|
findActiveSession(workspacePath: string): string | null;
|
|
28
30
|
findAllSessions(workspacePath: string): string[];
|
|
31
|
+
findSessionById(workspacePath: string, sessionId: string): string | null;
|
|
29
32
|
/** Backward-compatible alias for findAllSessions. */
|
|
30
33
|
findSessionFiles(workspacePath: string): string[];
|
|
31
34
|
findSessionsInDirectory(dir: string): string[];
|
|
32
35
|
getAllProjectFolders(workspacePath?: string): ProjectFolderInfo[];
|
|
33
36
|
listAllSessionFiles(): SessionFileInfo[];
|
|
37
|
+
listSessionFilesAsync(workspacePath?: string): Promise<SessionFileInfo[]>;
|
|
34
38
|
isSessionFile(filename: string): boolean;
|
|
35
39
|
getSessionId(sessionPath: string): string;
|
|
36
40
|
encodeWorkspacePath(workspacePath: string): string;
|
|
37
41
|
extractSessionLabel(sessionPath: string): string | null;
|
|
42
|
+
extractSessionLabelsAsync(sessionPaths: readonly string[]): Promise<Map<string, string | null>>;
|
|
38
43
|
createReader(sessionPath: string): SessionReader;
|
|
39
44
|
scanSubagents(sessionDir: string, sessionId: string): SubagentStats[];
|
|
40
45
|
searchInSession(sessionPath: string, query: string, maxResults: number): SearchHit[];
|
|
41
46
|
getProjectsBaseDir(): string;
|
|
47
|
+
getWatchRoots(): string[];
|
|
42
48
|
readSessionStats(sessionPath: string): SessionFileStats;
|
|
43
49
|
readSessionContextSnapshot(sessionPath: string, options?: ReadSessionContextSnapshotOptions): SessionContextSnapshot;
|
|
50
|
+
getRuntimeStatus(): ProviderRuntimeStatus;
|
|
51
|
+
getLastOperationStatus(): ProviderOperationStatus;
|
|
44
52
|
getContextWindowLimit(modelId?: string): number;
|
|
45
53
|
/** Set a runtime-reported context window limit (overrides static map). */
|
|
46
54
|
setDynamicContextWindowLimit(limit: number): void;
|
|
@@ -52,4 +60,5 @@ export declare class ClaudeCodeProvider implements SessionProviderBase {
|
|
|
52
60
|
*/
|
|
53
61
|
getCurrentUsageSnapshot(sessionPath: string): TokenUsage | null;
|
|
54
62
|
dispose(): void;
|
|
63
|
+
private recordHomeStatus;
|
|
55
64
|
}
|