sidekick-shared 0.25.0 → 0.26.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/CHANGELOG.md +65 -0
- package/README.md +50 -3
- package/dist/accountChanges.js +22 -3
- package/dist/accountRegistry.d.ts +22 -1
- package/dist/accountRegistry.js +37 -14
- 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 +11 -1
- package/dist/browser.js +29 -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/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 +46 -12
- package/dist/index.js +112 -24
- package/dist/modelContext.js +8 -3
- package/dist/modelInfo.js +45 -27
- package/dist/node.d.ts +19 -0
- package/dist/node.js +47 -1
- package/dist/observedContextWindows.d.ts +7 -0
- package/dist/observedContextWindows.js +17 -2
- package/dist/observedSessionCollector.d.ts +3 -8
- package/dist/observedSessionCollector.js +10 -27
- package/dist/parsers/sessionActivityDetector.d.ts +24 -2
- package/dist/parsers/sessionActivityDetector.js +95 -17
- 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/providers/claudeCode.js +11 -96
- package/dist/providers/codex.d.ts +2 -0
- package/dist/providers/codex.js +94 -259
- package/dist/providers/detect.d.ts +2 -0
- package/dist/providers/detect.js +29 -24
- package/dist/providers/factory.d.ts +6 -0
- package/dist/providers/openCode.d.ts +2 -0
- package/dist/providers/openCode.js +105 -121
- package/dist/providers/rolloutWalker.d.ts +53 -0
- package/dist/providers/rolloutWalker.js +209 -0
- package/dist/providers/types.d.ts +30 -0
- package/dist/quota.d.ts +30 -3
- package/dist/quota.js +35 -3
- package/dist/quotaHistory.d.ts +1 -1
- package/dist/quotaHistory.js +36 -35
- package/dist/quotaPresentation.js +17 -5
- package/dist/quotaResolver.d.ts +83 -0
- package/dist/quotaResolver.js +234 -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/index.d.ts +2 -0
- package/dist/schemas/index.js +10 -1
- package/dist/schemas/quota.d.ts +139 -0
- package/dist/schemas/quota.js +17 -2
- package/dist/schemas/quotaHistory.d.ts +1 -0
- 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/transcript.js +2 -0
- package/dist/sessionFingerprint.d.ts +25 -0
- package/dist/sessionFingerprint.js +46 -0
- package/dist/sessionPreviews.d.ts +7 -1
- package/dist/sessionPreviews.js +15 -3
- 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 +2 -0
- package/dist/types/observedSessionV1.js +75 -18
- 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 +1 -1
package/dist/schemas/quota.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @module schemas/quota
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.quotaStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaWindowSchema = void 0;
|
|
13
|
+
exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.quotaStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaFreshnessSchema = exports.quotaCapturedSourceSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaWindowSchema = void 0;
|
|
14
14
|
const zod_1 = require("zod");
|
|
15
15
|
const providerIds_1 = require("../providerIds");
|
|
16
16
|
// ── QuotaWindow ──
|
|
@@ -27,7 +27,18 @@ exports.quotaFailureKindSchema = zod_1.z.enum([
|
|
|
27
27
|
'unknown',
|
|
28
28
|
]);
|
|
29
29
|
exports.quotaProviderIdSchema = zod_1.z.enum(providerIds_1.QUOTA_PROVIDER_IDS);
|
|
30
|
-
exports.quotaSourceSchema = zod_1.z.enum([
|
|
30
|
+
exports.quotaSourceSchema = zod_1.z.enum([
|
|
31
|
+
'api',
|
|
32
|
+
'session',
|
|
33
|
+
'cache',
|
|
34
|
+
'statusline',
|
|
35
|
+
]);
|
|
36
|
+
exports.quotaCapturedSourceSchema = zod_1.z.enum([
|
|
37
|
+
'api',
|
|
38
|
+
'session',
|
|
39
|
+
'statusline',
|
|
40
|
+
]);
|
|
41
|
+
exports.quotaFreshnessSchema = zod_1.z.enum(['fresh', 'aging', 'stale']);
|
|
31
42
|
exports.codexResetCreditSchema = zod_1.z.object({
|
|
32
43
|
title: zod_1.z.string().optional(),
|
|
33
44
|
status: zod_1.z.string(),
|
|
@@ -54,8 +65,11 @@ exports.quotaStateSchema = zod_1.z.object({
|
|
|
54
65
|
projectedSevenDay: zod_1.z.number().optional(),
|
|
55
66
|
providerId: exports.quotaProviderIdSchema.optional(),
|
|
56
67
|
source: exports.quotaSourceSchema.optional(),
|
|
68
|
+
capturedSource: exports.quotaCapturedSourceSchema.optional(),
|
|
57
69
|
capturedAt: zod_1.z.string().optional(),
|
|
58
70
|
stale: zod_1.z.boolean().optional(),
|
|
71
|
+
ageMs: zod_1.z.number().finite().nonnegative().optional(),
|
|
72
|
+
freshness: exports.quotaFreshnessSchema.optional(),
|
|
59
73
|
fiveHourLabel: zod_1.z.string().optional(),
|
|
60
74
|
sevenDayLabel: zod_1.z.string().optional(),
|
|
61
75
|
limitId: zod_1.z.string().optional(),
|
|
@@ -78,6 +92,7 @@ exports.peakHoursStateSchema = zod_1.z.object({
|
|
|
78
92
|
updatedAt: zod_1.z.string(),
|
|
79
93
|
unavailable: zod_1.z.boolean(),
|
|
80
94
|
notApplicable: zod_1.z.boolean().optional(),
|
|
95
|
+
source: zod_1.z.enum(['promoclock', 'schedule']).optional(),
|
|
81
96
|
});
|
|
82
97
|
// ── QuotaFailureDescriptor ──
|
|
83
98
|
exports.quotaFailureDescriptorSchema = zod_1.z.object({
|
|
@@ -28,7 +28,7 @@ exports.quotaHistorySampleSchema = zod_1.z.object({
|
|
|
28
28
|
sevenDay: zod_1.z.object({ utilization: zod_1.z.number(), resetsAt: zod_1.z.string() }),
|
|
29
29
|
available: zod_1.z.boolean(),
|
|
30
30
|
error: zod_1.z.string().optional(),
|
|
31
|
-
source: zod_1.z.enum(['session', 'cache', 'api']).optional(),
|
|
31
|
+
source: zod_1.z.enum(['session', 'cache', 'api', 'statusline']).optional(),
|
|
32
32
|
stale: zod_1.z.boolean().optional(),
|
|
33
33
|
});
|
|
34
34
|
// ── QuotaHistoryDailyBucket ──
|
|
@@ -52,6 +52,7 @@ export declare const sessionMessageSchema: z.ZodObject<{
|
|
|
52
52
|
}, z.core.$strip>;
|
|
53
53
|
}, z.core.$strip>>;
|
|
54
54
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
55
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
55
56
|
}, z.core.$strip>;
|
|
56
57
|
export declare const permissionModeSchema: z.ZodEnum<{
|
|
57
58
|
default: "default";
|
|
@@ -136,6 +137,7 @@ export declare const userSessionEventSchema: z.ZodObject<{
|
|
|
136
137
|
}, z.core.$strip>;
|
|
137
138
|
}, z.core.$strip>>;
|
|
138
139
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
140
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
139
141
|
}, z.core.$strip>;
|
|
140
142
|
}, z.core.$strip>;
|
|
141
143
|
export declare const assistantSessionEventSchema: z.ZodObject<{
|
|
@@ -215,6 +217,7 @@ export declare const assistantSessionEventSchema: z.ZodObject<{
|
|
|
215
217
|
}, z.core.$strip>;
|
|
216
218
|
}, z.core.$strip>>;
|
|
217
219
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
220
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
218
221
|
}, z.core.$strip>;
|
|
219
222
|
}, z.core.$strip>;
|
|
220
223
|
export declare const summarySessionEventSchema: z.ZodType<SummarySessionEvent>;
|
|
@@ -295,6 +298,7 @@ export declare const systemSessionEventSchema: z.ZodObject<{
|
|
|
295
298
|
}, z.core.$strip>;
|
|
296
299
|
}, z.core.$strip>>;
|
|
297
300
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
301
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
298
302
|
}, z.core.$strip>>;
|
|
299
303
|
}, z.core.$strip>;
|
|
300
304
|
export declare const toolUseSessionEventSchema: z.ZodObject<{
|
|
@@ -378,6 +382,7 @@ export declare const toolUseSessionEventSchema: z.ZodObject<{
|
|
|
378
382
|
}, z.core.$strip>;
|
|
379
383
|
}, z.core.$strip>>;
|
|
380
384
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
385
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
381
386
|
}, z.core.$strip>>;
|
|
382
387
|
}, z.core.$strip>;
|
|
383
388
|
export declare const toolResultSessionEventSchema: z.ZodObject<{
|
|
@@ -462,6 +467,7 @@ export declare const toolResultSessionEventSchema: z.ZodObject<{
|
|
|
462
467
|
}, z.core.$strip>;
|
|
463
468
|
}, z.core.$strip>>;
|
|
464
469
|
content: z.ZodOptional<z.ZodUnknown>;
|
|
470
|
+
stop_reason: z.ZodOptional<z.ZodString>;
|
|
465
471
|
}, z.core.$strip>>;
|
|
466
472
|
}, z.core.$strip>;
|
|
467
473
|
export declare const sessionEventSchema: z.ZodType<SessionEvent>;
|
|
@@ -30,6 +30,7 @@ exports.sessionMessageSchema = zod_1.z.object({
|
|
|
30
30
|
usage: exports.messageUsageSchema.optional(),
|
|
31
31
|
normalizedUsage: usageNormalization_1.normalizedUsageSchema.optional(),
|
|
32
32
|
content: zod_1.z.unknown().optional(),
|
|
33
|
+
stop_reason: zod_1.z.string().optional(),
|
|
33
34
|
});
|
|
34
35
|
// ── PermissionMode ──
|
|
35
36
|
exports.permissionModeSchema = zod_1.z.enum([
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for the public `state.json` contract (`schemaVersion: 1`).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the interfaces in `stateFile.ts` (keep in sync when those change;
|
|
5
|
+
* fields are only ever added). Consumers validating the file from another
|
|
6
|
+
* process import this from `sidekick-shared/schemas`.
|
|
7
|
+
*
|
|
8
|
+
* @module schemas/stateFile
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
export declare const stateFileWriterSchema: z.ZodEnum<{
|
|
12
|
+
statusline: "statusline";
|
|
13
|
+
"cli-dashboard": "cli-dashboard";
|
|
14
|
+
"vscode-dashboard": "vscode-dashboard";
|
|
15
|
+
}>;
|
|
16
|
+
export declare const stateFileQuotaWindowSchema: z.ZodObject<{
|
|
17
|
+
utilization: z.ZodNumber;
|
|
18
|
+
resetsAt: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const stateFileQuotaSchema: z.ZodObject<{
|
|
21
|
+
fiveHour: z.ZodObject<{
|
|
22
|
+
utilization: z.ZodNumber;
|
|
23
|
+
resetsAt: z.ZodString;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
sevenDay: z.ZodObject<{
|
|
26
|
+
utilization: z.ZodNumber;
|
|
27
|
+
resetsAt: z.ZodString;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
source: z.ZodNullable<z.ZodEnum<{
|
|
30
|
+
api: "api";
|
|
31
|
+
cache: "cache";
|
|
32
|
+
session: "session";
|
|
33
|
+
statusline: "statusline";
|
|
34
|
+
}>>;
|
|
35
|
+
capturedSource: z.ZodNullable<z.ZodEnum<{
|
|
36
|
+
api: "api";
|
|
37
|
+
session: "session";
|
|
38
|
+
statusline: "statusline";
|
|
39
|
+
}>>;
|
|
40
|
+
capturedAt: z.ZodNullable<z.ZodString>;
|
|
41
|
+
ageMs: z.ZodNullable<z.ZodNumber>;
|
|
42
|
+
freshness: z.ZodNullable<z.ZodEnum<{
|
|
43
|
+
fresh: "fresh";
|
|
44
|
+
aging: "aging";
|
|
45
|
+
stale: "stale";
|
|
46
|
+
}>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export declare const stateFileAccountSchema: z.ZodObject<{
|
|
49
|
+
providerId: z.ZodEnum<{
|
|
50
|
+
"claude-code": "claude-code";
|
|
51
|
+
codex: "codex";
|
|
52
|
+
}>;
|
|
53
|
+
id: z.ZodNullable<z.ZodString>;
|
|
54
|
+
label: z.ZodNullable<z.ZodString>;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
export declare const stateFileContextSchema: z.ZodObject<{
|
|
57
|
+
usedPercentage: z.ZodNullable<z.ZodNumber>;
|
|
58
|
+
contextWindowSize: z.ZodNullable<z.ZodNumber>;
|
|
59
|
+
totalInputTokens: z.ZodNullable<z.ZodNumber>;
|
|
60
|
+
totalOutputTokens: z.ZodNullable<z.ZodNumber>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const stateFileSessionSchema: z.ZodObject<{
|
|
63
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
64
|
+
cwd: z.ZodNullable<z.ZodString>;
|
|
65
|
+
model: z.ZodNullable<z.ZodString>;
|
|
66
|
+
costUsd: z.ZodNullable<z.ZodNumber>;
|
|
67
|
+
durationMs: z.ZodNullable<z.ZodNumber>;
|
|
68
|
+
linesAdded: z.ZodNullable<z.ZodNumber>;
|
|
69
|
+
linesRemoved: z.ZodNullable<z.ZodNumber>;
|
|
70
|
+
promptCacheHitRatio: z.ZodNullable<z.ZodNumber>;
|
|
71
|
+
}, z.core.$strip>;
|
|
72
|
+
export declare const stateFileBillingBlockSchema: z.ZodObject<{
|
|
73
|
+
start: z.ZodString;
|
|
74
|
+
end: z.ZodString;
|
|
75
|
+
isActive: z.ZodBoolean;
|
|
76
|
+
tokens: z.ZodNumber;
|
|
77
|
+
costUsd: z.ZodNumber;
|
|
78
|
+
costProvenance: z.ZodEnum<{
|
|
79
|
+
none: "none";
|
|
80
|
+
reported: "reported";
|
|
81
|
+
estimated: "estimated";
|
|
82
|
+
unpriced: "unpriced";
|
|
83
|
+
mixed: "mixed";
|
|
84
|
+
}>;
|
|
85
|
+
burnRatePerMinute: z.ZodNumber;
|
|
86
|
+
projectedTokens: z.ZodNumber;
|
|
87
|
+
projectedCostUsd: z.ZodNumber;
|
|
88
|
+
remainingMs: z.ZodNumber;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
export declare const sidekickStateFileSchema: z.ZodObject<{
|
|
91
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
92
|
+
writtenAt: z.ZodString;
|
|
93
|
+
writer: z.ZodEnum<{
|
|
94
|
+
statusline: "statusline";
|
|
95
|
+
"cli-dashboard": "cli-dashboard";
|
|
96
|
+
"vscode-dashboard": "vscode-dashboard";
|
|
97
|
+
}>;
|
|
98
|
+
account: z.ZodNullable<z.ZodObject<{
|
|
99
|
+
providerId: z.ZodEnum<{
|
|
100
|
+
"claude-code": "claude-code";
|
|
101
|
+
codex: "codex";
|
|
102
|
+
}>;
|
|
103
|
+
id: z.ZodNullable<z.ZodString>;
|
|
104
|
+
label: z.ZodNullable<z.ZodString>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
106
|
+
quota: z.ZodObject<{
|
|
107
|
+
claude: z.ZodNullable<z.ZodObject<{
|
|
108
|
+
fiveHour: z.ZodObject<{
|
|
109
|
+
utilization: z.ZodNumber;
|
|
110
|
+
resetsAt: z.ZodString;
|
|
111
|
+
}, z.core.$strip>;
|
|
112
|
+
sevenDay: z.ZodObject<{
|
|
113
|
+
utilization: z.ZodNumber;
|
|
114
|
+
resetsAt: z.ZodString;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
source: z.ZodNullable<z.ZodEnum<{
|
|
117
|
+
api: "api";
|
|
118
|
+
cache: "cache";
|
|
119
|
+
session: "session";
|
|
120
|
+
statusline: "statusline";
|
|
121
|
+
}>>;
|
|
122
|
+
capturedSource: z.ZodNullable<z.ZodEnum<{
|
|
123
|
+
api: "api";
|
|
124
|
+
session: "session";
|
|
125
|
+
statusline: "statusline";
|
|
126
|
+
}>>;
|
|
127
|
+
capturedAt: z.ZodNullable<z.ZodString>;
|
|
128
|
+
ageMs: z.ZodNullable<z.ZodNumber>;
|
|
129
|
+
freshness: z.ZodNullable<z.ZodEnum<{
|
|
130
|
+
fresh: "fresh";
|
|
131
|
+
aging: "aging";
|
|
132
|
+
stale: "stale";
|
|
133
|
+
}>>;
|
|
134
|
+
}, z.core.$strip>>;
|
|
135
|
+
codex: z.ZodNullable<z.ZodObject<{
|
|
136
|
+
fiveHour: z.ZodObject<{
|
|
137
|
+
utilization: z.ZodNumber;
|
|
138
|
+
resetsAt: z.ZodString;
|
|
139
|
+
}, z.core.$strip>;
|
|
140
|
+
sevenDay: z.ZodObject<{
|
|
141
|
+
utilization: z.ZodNumber;
|
|
142
|
+
resetsAt: z.ZodString;
|
|
143
|
+
}, z.core.$strip>;
|
|
144
|
+
source: z.ZodNullable<z.ZodEnum<{
|
|
145
|
+
api: "api";
|
|
146
|
+
cache: "cache";
|
|
147
|
+
session: "session";
|
|
148
|
+
statusline: "statusline";
|
|
149
|
+
}>>;
|
|
150
|
+
capturedSource: z.ZodNullable<z.ZodEnum<{
|
|
151
|
+
api: "api";
|
|
152
|
+
session: "session";
|
|
153
|
+
statusline: "statusline";
|
|
154
|
+
}>>;
|
|
155
|
+
capturedAt: z.ZodNullable<z.ZodString>;
|
|
156
|
+
ageMs: z.ZodNullable<z.ZodNumber>;
|
|
157
|
+
freshness: z.ZodNullable<z.ZodEnum<{
|
|
158
|
+
fresh: "fresh";
|
|
159
|
+
aging: "aging";
|
|
160
|
+
stale: "stale";
|
|
161
|
+
}>>;
|
|
162
|
+
}, z.core.$strip>>;
|
|
163
|
+
}, z.core.$strip>;
|
|
164
|
+
context: z.ZodNullable<z.ZodObject<{
|
|
165
|
+
usedPercentage: z.ZodNullable<z.ZodNumber>;
|
|
166
|
+
contextWindowSize: z.ZodNullable<z.ZodNumber>;
|
|
167
|
+
totalInputTokens: z.ZodNullable<z.ZodNumber>;
|
|
168
|
+
totalOutputTokens: z.ZodNullable<z.ZodNumber>;
|
|
169
|
+
}, z.core.$strip>>;
|
|
170
|
+
session: z.ZodNullable<z.ZodObject<{
|
|
171
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
172
|
+
cwd: z.ZodNullable<z.ZodString>;
|
|
173
|
+
model: z.ZodNullable<z.ZodString>;
|
|
174
|
+
costUsd: z.ZodNullable<z.ZodNumber>;
|
|
175
|
+
durationMs: z.ZodNullable<z.ZodNumber>;
|
|
176
|
+
linesAdded: z.ZodNullable<z.ZodNumber>;
|
|
177
|
+
linesRemoved: z.ZodNullable<z.ZodNumber>;
|
|
178
|
+
promptCacheHitRatio: z.ZodNullable<z.ZodNumber>;
|
|
179
|
+
}, z.core.$strip>>;
|
|
180
|
+
billingBlock: z.ZodNullable<z.ZodObject<{
|
|
181
|
+
start: z.ZodString;
|
|
182
|
+
end: z.ZodString;
|
|
183
|
+
isActive: z.ZodBoolean;
|
|
184
|
+
tokens: z.ZodNumber;
|
|
185
|
+
costUsd: z.ZodNumber;
|
|
186
|
+
costProvenance: z.ZodEnum<{
|
|
187
|
+
none: "none";
|
|
188
|
+
reported: "reported";
|
|
189
|
+
estimated: "estimated";
|
|
190
|
+
unpriced: "unpriced";
|
|
191
|
+
mixed: "mixed";
|
|
192
|
+
}>;
|
|
193
|
+
burnRatePerMinute: z.ZodNumber;
|
|
194
|
+
projectedTokens: z.ZodNumber;
|
|
195
|
+
projectedCostUsd: z.ZodNumber;
|
|
196
|
+
remainingMs: z.ZodNumber;
|
|
197
|
+
}, z.core.$strip>>;
|
|
198
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for the public `state.json` contract (`schemaVersion: 1`).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the interfaces in `stateFile.ts` (keep in sync when those change;
|
|
6
|
+
* fields are only ever added). Consumers validating the file from another
|
|
7
|
+
* process import this from `sidekick-shared/schemas`.
|
|
8
|
+
*
|
|
9
|
+
* @module schemas/stateFile
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.sidekickStateFileSchema = exports.stateFileBillingBlockSchema = exports.stateFileSessionSchema = exports.stateFileContextSchema = exports.stateFileAccountSchema = exports.stateFileQuotaSchema = exports.stateFileQuotaWindowSchema = exports.stateFileWriterSchema = void 0;
|
|
13
|
+
const zod_1 = require("zod");
|
|
14
|
+
exports.stateFileWriterSchema = zod_1.z.enum([
|
|
15
|
+
'statusline',
|
|
16
|
+
'cli-dashboard',
|
|
17
|
+
'vscode-dashboard',
|
|
18
|
+
]);
|
|
19
|
+
exports.stateFileQuotaWindowSchema = zod_1.z.object({
|
|
20
|
+
utilization: zod_1.z.number(),
|
|
21
|
+
resetsAt: zod_1.z.string(),
|
|
22
|
+
});
|
|
23
|
+
exports.stateFileQuotaSchema = zod_1.z.object({
|
|
24
|
+
fiveHour: exports.stateFileQuotaWindowSchema,
|
|
25
|
+
sevenDay: exports.stateFileQuotaWindowSchema,
|
|
26
|
+
source: zod_1.z.enum(['api', 'session', 'cache', 'statusline']).nullable(),
|
|
27
|
+
capturedSource: zod_1.z.enum(['api', 'session', 'statusline']).nullable(),
|
|
28
|
+
capturedAt: zod_1.z.string().nullable(),
|
|
29
|
+
ageMs: zod_1.z.number().nullable(),
|
|
30
|
+
freshness: zod_1.z.enum(['fresh', 'aging', 'stale']).nullable(),
|
|
31
|
+
});
|
|
32
|
+
exports.stateFileAccountSchema = zod_1.z.object({
|
|
33
|
+
providerId: zod_1.z.enum(['claude-code', 'codex']),
|
|
34
|
+
id: zod_1.z.string().nullable(),
|
|
35
|
+
label: zod_1.z.string().nullable(),
|
|
36
|
+
});
|
|
37
|
+
exports.stateFileContextSchema = zod_1.z.object({
|
|
38
|
+
usedPercentage: zod_1.z.number().nullable(),
|
|
39
|
+
contextWindowSize: zod_1.z.number().nullable(),
|
|
40
|
+
totalInputTokens: zod_1.z.number().nullable(),
|
|
41
|
+
totalOutputTokens: zod_1.z.number().nullable(),
|
|
42
|
+
});
|
|
43
|
+
exports.stateFileSessionSchema = zod_1.z.object({
|
|
44
|
+
sessionId: zod_1.z.string().nullable(),
|
|
45
|
+
cwd: zod_1.z.string().nullable(),
|
|
46
|
+
model: zod_1.z.string().nullable(),
|
|
47
|
+
costUsd: zod_1.z.number().nullable(),
|
|
48
|
+
durationMs: zod_1.z.number().nullable(),
|
|
49
|
+
linesAdded: zod_1.z.number().nullable(),
|
|
50
|
+
linesRemoved: zod_1.z.number().nullable(),
|
|
51
|
+
promptCacheHitRatio: zod_1.z.number().nullable(),
|
|
52
|
+
});
|
|
53
|
+
exports.stateFileBillingBlockSchema = zod_1.z.object({
|
|
54
|
+
start: zod_1.z.string(),
|
|
55
|
+
end: zod_1.z.string(),
|
|
56
|
+
isActive: zod_1.z.boolean(),
|
|
57
|
+
tokens: zod_1.z.number(),
|
|
58
|
+
costUsd: zod_1.z.number(),
|
|
59
|
+
costProvenance: zod_1.z.enum(['reported', 'estimated', 'mixed', 'unpriced', 'none']),
|
|
60
|
+
burnRatePerMinute: zod_1.z.number(),
|
|
61
|
+
projectedTokens: zod_1.z.number(),
|
|
62
|
+
projectedCostUsd: zod_1.z.number(),
|
|
63
|
+
remainingMs: zod_1.z.number(),
|
|
64
|
+
});
|
|
65
|
+
exports.sidekickStateFileSchema = zod_1.z.object({
|
|
66
|
+
schemaVersion: zod_1.z.literal(1),
|
|
67
|
+
writtenAt: zod_1.z.string(),
|
|
68
|
+
writer: exports.stateFileWriterSchema,
|
|
69
|
+
account: exports.stateFileAccountSchema.nullable(),
|
|
70
|
+
quota: zod_1.z.object({
|
|
71
|
+
claude: exports.stateFileQuotaSchema.nullable(),
|
|
72
|
+
codex: exports.stateFileQuotaSchema.nullable(),
|
|
73
|
+
}),
|
|
74
|
+
context: exports.stateFileContextSchema.nullable(),
|
|
75
|
+
session: exports.stateFileSessionSchema.nullable(),
|
|
76
|
+
billingBlock: exports.stateFileBillingBlockSchema.nullable(),
|
|
77
|
+
});
|
|
@@ -78,6 +78,8 @@ exports.canonicalSessionTranscriptSchema = zod_1.z.object({
|
|
|
78
78
|
totalTokens: zod_1.z.number().finite().nonnegative(),
|
|
79
79
|
}),
|
|
80
80
|
totalCostUsd: zod_1.z.number().finite().nonnegative().nullable(),
|
|
81
|
+
pricedCostUsd: zod_1.z.number().finite().nonnegative(),
|
|
82
|
+
unpricedEvents: zod_1.z.number().int().nonnegative(),
|
|
81
83
|
}),
|
|
82
84
|
provenance: zod_1.z.object({
|
|
83
85
|
source: zod_1.z.literal('session-events'),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size/mtime fingerprints for session sources.
|
|
3
|
+
*
|
|
4
|
+
* Shared by the observed-session collector, the V1 adapter's watch loop, and
|
|
5
|
+
* the usage cache, so "has this session changed?" is answered the same way
|
|
6
|
+
* everywhere without re-reading content.
|
|
7
|
+
*
|
|
8
|
+
* @module sessionFingerprint
|
|
9
|
+
*/
|
|
10
|
+
import type { SessionProviderBase } from './providers/types';
|
|
11
|
+
export interface ObservedSessionFingerprintParts {
|
|
12
|
+
sizeBytes: number;
|
|
13
|
+
mtimeMs: number;
|
|
14
|
+
}
|
|
15
|
+
/** Structured size/mtime fingerprint; returns null for inaccessible or synthetic paths. */
|
|
16
|
+
export declare function fileFingerprintParts(sourcePath: string): ObservedSessionFingerprintParts | null;
|
|
17
|
+
/** Size/mtime fingerprint suitable for retry bypass; returns null for synthetic DB locators. */
|
|
18
|
+
export declare function fileFingerprint(sourcePath: string): string | null;
|
|
19
|
+
/** Canonical `${sizeBytes}:${mtimeMs}` form of a fingerprint. */
|
|
20
|
+
export declare function fingerprintString(parts: ObservedSessionFingerprintParts): string;
|
|
21
|
+
/**
|
|
22
|
+
* Fingerprint for a session path, falling back to provider metadata (mtime
|
|
23
|
+
* only) for database-backed sessions whose path is synthetic.
|
|
24
|
+
*/
|
|
25
|
+
export declare function sessionFingerprintParts(provider: SessionProviderBase, sessionPath: string): ObservedSessionFingerprintParts | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Size/mtime fingerprints for session sources.
|
|
4
|
+
*
|
|
5
|
+
* Shared by the observed-session collector, the V1 adapter's watch loop, and
|
|
6
|
+
* the usage cache, so "has this session changed?" is answered the same way
|
|
7
|
+
* everywhere without re-reading content.
|
|
8
|
+
*
|
|
9
|
+
* @module sessionFingerprint
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.fileFingerprintParts = fileFingerprintParts;
|
|
13
|
+
exports.fileFingerprint = fileFingerprint;
|
|
14
|
+
exports.fingerprintString = fingerprintString;
|
|
15
|
+
exports.sessionFingerprintParts = sessionFingerprintParts;
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
/** Structured size/mtime fingerprint; returns null for inaccessible or synthetic paths. */
|
|
18
|
+
function fileFingerprintParts(sourcePath) {
|
|
19
|
+
try {
|
|
20
|
+
const stat = (0, node_fs_1.statSync)(sourcePath);
|
|
21
|
+
return { sizeBytes: stat.size, mtimeMs: stat.mtimeMs };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Size/mtime fingerprint suitable for retry bypass; returns null for synthetic DB locators. */
|
|
28
|
+
function fileFingerprint(sourcePath) {
|
|
29
|
+
const parts = fileFingerprintParts(sourcePath);
|
|
30
|
+
return parts ? fingerprintString(parts) : null;
|
|
31
|
+
}
|
|
32
|
+
/** Canonical `${sizeBytes}:${mtimeMs}` form of a fingerprint. */
|
|
33
|
+
function fingerprintString(parts) {
|
|
34
|
+
return `${parts.sizeBytes}:${parts.mtimeMs}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fingerprint for a session path, falling back to provider metadata (mtime
|
|
38
|
+
* only) for database-backed sessions whose path is synthetic.
|
|
39
|
+
*/
|
|
40
|
+
function sessionFingerprintParts(provider, sessionPath) {
|
|
41
|
+
const parts = fileFingerprintParts(sessionPath);
|
|
42
|
+
if (parts)
|
|
43
|
+
return parts;
|
|
44
|
+
const metadata = provider.getSessionMetadata?.(sessionPath);
|
|
45
|
+
return metadata ? { sizeBytes: 0, mtimeMs: metadata.mtime.getTime() } : null;
|
|
46
|
+
}
|
|
@@ -36,7 +36,11 @@ export interface SessionPreview {
|
|
|
36
36
|
workspacePath: string | null;
|
|
37
37
|
}
|
|
38
38
|
export interface ReadSessionPreviewOptions {
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Byte budget for the generic prefix scan (default 16 KiB). `0` skips the
|
|
41
|
+
* scan entirely for callers that ignore `firstTimestamp` and
|
|
42
|
+
* `workspacePath`; both come back `null` and the file is not opened.
|
|
43
|
+
*/
|
|
40
44
|
maxPrefixBytes?: number;
|
|
41
45
|
}
|
|
42
46
|
export interface ListSessionPreviewsOptions extends ReadSessionPreviewOptions {
|
|
@@ -64,6 +68,8 @@ export interface SessionPreviewReadResult {
|
|
|
64
68
|
export interface SessionPreviewListResult {
|
|
65
69
|
previews: SessionPreview[];
|
|
66
70
|
diagnostics: SessionProviderDiagnostic[];
|
|
71
|
+
/** True when more candidates existed than `limit` allowed; the caller may offer a larger limit. */
|
|
72
|
+
hasMore: boolean;
|
|
67
73
|
}
|
|
68
74
|
/**
|
|
69
75
|
* Reads a bounded preview of one session file. Returns `null` when the file is
|
package/dist/sessionPreviews.js
CHANGED
|
@@ -57,6 +57,9 @@ exports.readSessionPreviewAsync = readSessionPreviewAsync;
|
|
|
57
57
|
exports.listSessionPreviews = listSessionPreviews;
|
|
58
58
|
exports.listSessionPreviewsAsync = listSessionPreviewsAsync;
|
|
59
59
|
const fs = __importStar(require("fs"));
|
|
60
|
+
function emptyPrefixScan() {
|
|
61
|
+
return { firstTimestamp: null, workspacePath: null };
|
|
62
|
+
}
|
|
60
63
|
const DEFAULT_PREFIX_BYTES = 16 * 1024;
|
|
61
64
|
const DEFAULT_LIMIT = 50;
|
|
62
65
|
const DEFAULT_CONCURRENCY = 4;
|
|
@@ -108,7 +111,8 @@ function readSessionPreview(provider, sessionPath, options = {}) {
|
|
|
108
111
|
catch {
|
|
109
112
|
// A provider that cannot identify the file still yields a usable preview.
|
|
110
113
|
}
|
|
111
|
-
const
|
|
114
|
+
const prefixBudget = options.maxPrefixBytes ?? DEFAULT_PREFIX_BYTES;
|
|
115
|
+
const prefix = prefixBudget > 0 ? scanPrefix(sessionPath, prefixBudget) : emptyPrefixScan();
|
|
112
116
|
return {
|
|
113
117
|
provider: provider.id,
|
|
114
118
|
sessionId,
|
|
@@ -238,6 +242,7 @@ async function listSessionPreviewsAsync(providers, options = {}) {
|
|
|
238
242
|
}, concurrency(options));
|
|
239
243
|
return {
|
|
240
244
|
previews: previews.filter((preview) => preview !== null),
|
|
245
|
+
hasMore: candidates.length > limit,
|
|
241
246
|
diagnostics: dedupeDiagnostics([
|
|
242
247
|
...operationDiagnostics,
|
|
243
248
|
...providers.flatMap(providerDiagnostics),
|
|
@@ -248,7 +253,13 @@ function resolveSinceMs(since) {
|
|
|
248
253
|
if (since === undefined)
|
|
249
254
|
return null;
|
|
250
255
|
const ms = since instanceof Date ? since.getTime() : Date.parse(since);
|
|
251
|
-
|
|
256
|
+
if (!Number.isFinite(ms)) {
|
|
257
|
+
// An unparseable cutoff used to mean "no cutoff", silently returning
|
|
258
|
+
// every session. Fail loudly instead so a typo cannot masquerade as a
|
|
259
|
+
// full listing.
|
|
260
|
+
throw new RangeError(`Invalid \`since\` value: ${String(since)}`);
|
|
261
|
+
}
|
|
262
|
+
return ms;
|
|
252
263
|
}
|
|
253
264
|
function enumerateSessionFiles(provider, workspacePath) {
|
|
254
265
|
try {
|
|
@@ -359,7 +370,8 @@ async function readSessionPreviewFromInfoAsync(provider, info, firstUserPrompt,
|
|
|
359
370
|
catch {
|
|
360
371
|
return null;
|
|
361
372
|
}
|
|
362
|
-
const
|
|
373
|
+
const prefixBudget = options.maxPrefixBytes ?? DEFAULT_PREFIX_BYTES;
|
|
374
|
+
const prefix = prefixBudget > 0 ? await scanPrefixAsync(info.path, prefixBudget) : emptyPrefixScan();
|
|
363
375
|
return {
|
|
364
376
|
provider: provider.id,
|
|
365
377
|
sessionId: info.sessionId ?? safeSessionId(provider, info.path),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One `readSessionStats()` implementation for every session provider.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code, Codex, and OpenCode used to compute session stats three
|
|
5
|
+
* different ways (a hand-rolled JSONL scan, an aggregator drain, and a direct
|
|
6
|
+
* SQLite read with hardcoded zeros). Every provider now drains its reader once
|
|
7
|
+
* into the shared `EventAggregator`, so per-model totals use the
|
|
8
|
+
* cache-inclusive vocabulary, cost carries provenance, tool failures are
|
|
9
|
+
* split out, and compaction and truncation counts are real for all three.
|
|
10
|
+
*/
|
|
11
|
+
import type { EventAggregatorOptions } from './aggregation/types';
|
|
12
|
+
import type { ProviderId, SessionFileStats, SessionFileStatsAvailability, SessionProviderBase } from './providers/types';
|
|
13
|
+
import type { SessionEvent } from './types/sessionEvent';
|
|
14
|
+
export interface ComputeSessionFileStatsOptions {
|
|
15
|
+
providerId: ProviderId;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
filePath: string;
|
|
18
|
+
/** Label to use; derived from the first user prompt when omitted or null. */
|
|
19
|
+
label?: string | null;
|
|
20
|
+
/** Provider-specific context formula, forwarded to the aggregator. */
|
|
21
|
+
computeContextSize?: EventAggregatorOptions['computeContextSize'];
|
|
22
|
+
/** Defaults to `full`. */
|
|
23
|
+
availability?: SessionFileStatsAvailability;
|
|
24
|
+
unavailableReason?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ReadSessionFileStatsOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Cheap label source consulted before the events (for example a SQLite
|
|
29
|
+
* thread title). Return null to fall back to the first user prompt.
|
|
30
|
+
*/
|
|
31
|
+
resolveLabel?: () => string | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* First user prompt in a session, compacted to one line and truncated the
|
|
35
|
+
* way every provider's `extractSessionLabel()` truncates (60 characters).
|
|
36
|
+
*/
|
|
37
|
+
export declare function firstUserPrompt(events: readonly SessionEvent[], maxLength?: number): string | null;
|
|
38
|
+
/** Compute stats for an already-read event array through the shared aggregator. */
|
|
39
|
+
export declare function computeSessionFileStats(events: readonly SessionEvent[], options: ComputeSessionFileStatsOptions): SessionFileStats;
|
|
40
|
+
/** The aggregator's context-size hook for a provider, or undefined for the default formula. */
|
|
41
|
+
export declare function providerContextSizeFn(provider: SessionProviderBase): EventAggregatorOptions['computeContextSize'];
|
|
42
|
+
/**
|
|
43
|
+
* Read a session once through the provider's reader and compute its stats.
|
|
44
|
+
*
|
|
45
|
+
* The reader is drained with `readAll()` and then `flush()`ed so a final line
|
|
46
|
+
* without a trailing newline is included, and it is never opened a second
|
|
47
|
+
* time for the label. A source that cannot be read yields
|
|
48
|
+
* `availability: 'unavailable'` with a reason instead of silent zeros; a
|
|
49
|
+
* reader that reports truncation yields `partial`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readSessionFileStats(provider: SessionProviderBase, sessionPath: string, options?: ReadSessionFileStatsOptions): SessionFileStats;
|