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
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
export declare const quotaHistoryRuntimeProviderSchema: z.ZodEnum<{
|
|
13
13
|
codex: "codex";
|
|
14
|
-
claude: "claude";
|
|
15
14
|
zai: "zai";
|
|
15
|
+
claude: "claude";
|
|
16
16
|
}>;
|
|
17
17
|
export declare const quotaHistorySampleSchema: z.ZodObject<{
|
|
18
18
|
timestamp: z.ZodString;
|
|
19
19
|
runtimeProvider: z.ZodEnum<{
|
|
20
20
|
codex: "codex";
|
|
21
|
-
claude: "claude";
|
|
22
21
|
zai: "zai";
|
|
22
|
+
claude: "claude";
|
|
23
23
|
}>;
|
|
24
24
|
providerId: z.ZodString;
|
|
25
25
|
workspaceId: z.ZodString;
|
|
@@ -37,6 +37,7 @@ export declare const quotaHistorySampleSchema: z.ZodObject<{
|
|
|
37
37
|
api: "api";
|
|
38
38
|
cache: "cache";
|
|
39
39
|
session: "session";
|
|
40
|
+
statusline: "statusline";
|
|
40
41
|
}>>;
|
|
41
42
|
stale: z.ZodOptional<z.ZodBoolean>;
|
|
42
43
|
}, z.core.$strip>;
|
|
@@ -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
|
+
});
|
|
@@ -6,9 +6,9 @@ export declare const tokenEstimateSchema: z.ZodObject<{
|
|
|
6
6
|
"sidekick-fallback-v1": "sidekick-fallback-v1";
|
|
7
7
|
}>;
|
|
8
8
|
confidence: z.ZodEnum<{
|
|
9
|
+
exact: "exact";
|
|
9
10
|
low: "low";
|
|
10
11
|
medium: "medium";
|
|
11
|
-
exact: "exact";
|
|
12
12
|
}>;
|
|
13
13
|
provenance: z.ZodString;
|
|
14
14
|
}, z.core.$strip>;
|
|
@@ -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
|
+
}
|
package/dist/sessionMonitor.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { AggregatedMetrics, EventAggregatorOptions } from './aggregation/types';
|
|
2
2
|
import type { SessionProviderBase } from './providers/types';
|
|
3
3
|
import type { SessionEvent } from './types/sessionEvent';
|
|
4
|
+
import type { ObservedSessionChangeBatch } from './observedSessionCollector';
|
|
4
5
|
export interface SessionMonitorOptions extends EventAggregatorOptions {
|
|
5
6
|
replayOnAttach?: boolean;
|
|
6
7
|
}
|
|
8
|
+
export interface SessionMonitorSubscribeOptions {
|
|
9
|
+
debounceMs?: number;
|
|
10
|
+
pollIntervalMs?: number;
|
|
11
|
+
onChange?: (batch: ObservedSessionChangeBatch) => void;
|
|
12
|
+
}
|
|
7
13
|
/**
|
|
8
14
|
* UI-independent session monitor for library consumers. It owns one provider
|
|
9
15
|
* reader and the canonical aggregator; hosts decide how often to call `poll()`.
|
|
@@ -14,6 +20,7 @@ export declare class SessionMonitor {
|
|
|
14
20
|
private reader;
|
|
15
21
|
private sessionPath;
|
|
16
22
|
private readonly listeners;
|
|
23
|
+
private readonly subscriptions;
|
|
17
24
|
private readonly replayOnAttach;
|
|
18
25
|
constructor(provider: SessionProviderBase, options?: SessionMonitorOptions);
|
|
19
26
|
attach(sessionPath: string, replay?: boolean): AggregatedMetrics;
|
|
@@ -21,6 +28,14 @@ export declare class SessionMonitor {
|
|
|
21
28
|
poll(): SessionEvent[];
|
|
22
29
|
process(event: SessionEvent): void;
|
|
23
30
|
onEvent(listener: (event: SessionEvent) => void): () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Watches the attached session with debouncing and catch-up polling. Matching
|
|
33
|
+
* fingerprint changes automatically call poll(); parsed events still flow
|
|
34
|
+
* through onEvent.
|
|
35
|
+
*/
|
|
36
|
+
subscribe(options?: SessionMonitorSubscribeOptions): {
|
|
37
|
+
dispose(): void;
|
|
38
|
+
};
|
|
24
39
|
getMetrics(): AggregatedMetrics;
|
|
25
40
|
getSessionPath(): string | null;
|
|
26
41
|
reset(): void;
|
package/dist/sessionMonitor.js
CHANGED
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.SessionMonitor = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
4
38
|
const EventAggregator_1 = require("./aggregation/EventAggregator");
|
|
39
|
+
const observedSessionCollector_1 = require("./observedSessionCollector");
|
|
5
40
|
/**
|
|
6
41
|
* UI-independent session monitor for library consumers. It owns one provider
|
|
7
42
|
* reader and the canonical aggregator; hosts decide how often to call `poll()`.
|
|
@@ -12,6 +47,7 @@ class SessionMonitor {
|
|
|
12
47
|
reader = null;
|
|
13
48
|
sessionPath = null;
|
|
14
49
|
listeners = new Set();
|
|
50
|
+
subscriptions = new Set();
|
|
15
51
|
replayOnAttach;
|
|
16
52
|
constructor(provider, options = {}) {
|
|
17
53
|
this.provider = provider;
|
|
@@ -48,6 +84,110 @@ class SessionMonitor {
|
|
|
48
84
|
this.listeners.add(listener);
|
|
49
85
|
return () => this.listeners.delete(listener);
|
|
50
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Watches the attached session with debouncing and catch-up polling. Matching
|
|
89
|
+
* fingerprint changes automatically call poll(); parsed events still flow
|
|
90
|
+
* through onEvent.
|
|
91
|
+
*/
|
|
92
|
+
subscribe(options = {}) {
|
|
93
|
+
const source = {
|
|
94
|
+
providerId: this.provider.id,
|
|
95
|
+
discover: async () => {
|
|
96
|
+
if (!this.sessionPath)
|
|
97
|
+
return [];
|
|
98
|
+
let parts = (0, observedSessionCollector_1.fileFingerprintParts)(this.sessionPath);
|
|
99
|
+
if (!parts) {
|
|
100
|
+
try {
|
|
101
|
+
const metadata = this.provider.getSessionMetadataAsync
|
|
102
|
+
? await this.provider.getSessionMetadataAsync(this.sessionPath)
|
|
103
|
+
: this.provider.getSessionMetadata?.(this.sessionPath);
|
|
104
|
+
parts = metadata ? { sizeBytes: 0, mtimeMs: metadata.mtime.getTime() } : null;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
parts = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!parts)
|
|
111
|
+
return [];
|
|
112
|
+
return [
|
|
113
|
+
{
|
|
114
|
+
sessionId: this.provider.getSessionId(this.sessionPath),
|
|
115
|
+
sourceKey: this.sessionPath,
|
|
116
|
+
fingerprintHint: `${parts.sizeBytes}:${parts.mtimeMs}`,
|
|
117
|
+
fingerprintParts: parts,
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
},
|
|
121
|
+
read: () => null,
|
|
122
|
+
subscribe: (listener, sourceOptions) => {
|
|
123
|
+
const watchers = new Set();
|
|
124
|
+
let pollTimer = null;
|
|
125
|
+
let roots;
|
|
126
|
+
try {
|
|
127
|
+
roots = this.provider.getWatchRoots?.() ?? [this.provider.getProjectsBaseDir()];
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
roots = [];
|
|
131
|
+
}
|
|
132
|
+
for (const root of new Set(roots)) {
|
|
133
|
+
try {
|
|
134
|
+
const watcher = fs.watch(root, { persistent: false, recursive: true }, listener);
|
|
135
|
+
watchers.add(watcher);
|
|
136
|
+
watcher.on('error', () => {
|
|
137
|
+
watchers.delete(watcher);
|
|
138
|
+
try {
|
|
139
|
+
watcher.close();
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Collector catch-up polling remains active.
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Collector catch-up polling remains active.
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const pollIntervalMs = sourceOptions?.pollIntervalMs ?? 0;
|
|
151
|
+
if (pollIntervalMs > 0) {
|
|
152
|
+
pollTimer = setInterval(listener, pollIntervalMs);
|
|
153
|
+
pollTimer.unref?.();
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
dispose: () => {
|
|
157
|
+
for (const watcher of watchers)
|
|
158
|
+
watcher.close();
|
|
159
|
+
watchers.clear();
|
|
160
|
+
if (pollTimer)
|
|
161
|
+
clearInterval(pollTimer);
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const collector = new observedSessionCollector_1.ObservedSessionCollector({ sources: [source] });
|
|
167
|
+
const changeSubscription = collector.subscribe((batch) => {
|
|
168
|
+
if (batch.changes.some((change) => change.reference.sourceKey === this.sessionPath)) {
|
|
169
|
+
this.poll();
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
options.onChange?.(batch);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Change callbacks are observational.
|
|
176
|
+
}
|
|
177
|
+
}, {
|
|
178
|
+
debounceMs: options.debounceMs,
|
|
179
|
+
pollIntervalMs: options.pollIntervalMs,
|
|
180
|
+
});
|
|
181
|
+
const disposable = {
|
|
182
|
+
dispose: () => {
|
|
183
|
+
changeSubscription.dispose();
|
|
184
|
+
collector.dispose();
|
|
185
|
+
this.subscriptions.delete(disposable);
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
this.subscriptions.add(disposable);
|
|
189
|
+
return disposable;
|
|
190
|
+
}
|
|
51
191
|
getMetrics() {
|
|
52
192
|
return this.aggregator.getMetrics();
|
|
53
193
|
}
|
|
@@ -59,6 +199,8 @@ class SessionMonitor {
|
|
|
59
199
|
this.aggregator.reset();
|
|
60
200
|
}
|
|
61
201
|
dispose() {
|
|
202
|
+
for (const subscription of [...this.subscriptions])
|
|
203
|
+
subscription.dispose();
|
|
62
204
|
this.listeners.clear();
|
|
63
205
|
this.reader = null;
|
|
64
206
|
this.provider.dispose();
|