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
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `state.json`: a small, versioned file for external consumers (tmux
|
|
3
|
+
* status bars, menu-bar apps, scripts) that want Sidekick's current account,
|
|
4
|
+
* quota windows with freshness, context usage, session cost, and the active
|
|
5
|
+
* billing block without running a Sidekick command.
|
|
6
|
+
*
|
|
7
|
+
* Written by the status line on every prompt and by both dashboards on their
|
|
8
|
+
* refresh ticks, but only when the content changed, so the hot path costs one
|
|
9
|
+
* small read in the common case. The schema is public: `schemaVersion` is 1,
|
|
10
|
+
* fields are only ever added, and the matching zod schema lives in
|
|
11
|
+
* `sidekick-shared/schemas` (`sidekickStateFileSchema`). This module does not
|
|
12
|
+
* import zod, so the status-line fast path stays small.
|
|
13
|
+
*
|
|
14
|
+
* @module stateFile
|
|
15
|
+
*/
|
|
16
|
+
import type { QuotaState } from './quota';
|
|
17
|
+
import type { BillingBlock } from './usage/billingBlocks';
|
|
18
|
+
export declare const STATE_FILE_SCHEMA_VERSION = 1;
|
|
19
|
+
export declare const STATE_FILE_NAME = "state.json";
|
|
20
|
+
export type StateFileWriter = 'statusline' | 'cli-dashboard' | 'vscode-dashboard';
|
|
21
|
+
export interface StateFileQuotaWindow {
|
|
22
|
+
/** Utilization percentage (0–100). */
|
|
23
|
+
utilization: number;
|
|
24
|
+
/** ISO timestamp when the window resets; empty when unknown. */
|
|
25
|
+
resetsAt: string;
|
|
26
|
+
}
|
|
27
|
+
export interface StateFileQuota {
|
|
28
|
+
fiveHour: StateFileQuotaWindow;
|
|
29
|
+
sevenDay: StateFileQuotaWindow;
|
|
30
|
+
/** How the sample was obtained (`cache` when read back from the snapshot store). */
|
|
31
|
+
source: 'api' | 'session' | 'cache' | 'statusline' | null;
|
|
32
|
+
/** Original origin of a cached sample. */
|
|
33
|
+
capturedSource: 'api' | 'session' | 'statusline' | null;
|
|
34
|
+
capturedAt: string | null;
|
|
35
|
+
ageMs: number | null;
|
|
36
|
+
freshness: 'fresh' | 'aging' | 'stale' | null;
|
|
37
|
+
}
|
|
38
|
+
export interface StateFileAccount {
|
|
39
|
+
providerId: 'claude-code' | 'codex';
|
|
40
|
+
/** Sidekick registry id used to key quota snapshots and history. */
|
|
41
|
+
id: string | null;
|
|
42
|
+
label: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface StateFileContext {
|
|
45
|
+
usedPercentage: number | null;
|
|
46
|
+
contextWindowSize: number | null;
|
|
47
|
+
totalInputTokens: number | null;
|
|
48
|
+
totalOutputTokens: number | null;
|
|
49
|
+
}
|
|
50
|
+
export interface StateFileSession {
|
|
51
|
+
sessionId: string | null;
|
|
52
|
+
cwd: string | null;
|
|
53
|
+
model: string | null;
|
|
54
|
+
costUsd: number | null;
|
|
55
|
+
durationMs: number | null;
|
|
56
|
+
linesAdded: number | null;
|
|
57
|
+
linesRemoved: number | null;
|
|
58
|
+
/** Prompt-cache hit ratio (0–1) when the provider reports it. */
|
|
59
|
+
promptCacheHitRatio: number | null;
|
|
60
|
+
}
|
|
61
|
+
export interface StateFileBillingBlock {
|
|
62
|
+
start: string;
|
|
63
|
+
end: string;
|
|
64
|
+
isActive: boolean;
|
|
65
|
+
/** Cache-inclusive tokens so far. */
|
|
66
|
+
tokens: number;
|
|
67
|
+
costUsd: number;
|
|
68
|
+
costProvenance: 'reported' | 'estimated' | 'mixed' | 'unpriced' | 'none';
|
|
69
|
+
burnRatePerMinute: number;
|
|
70
|
+
projectedTokens: number;
|
|
71
|
+
projectedCostUsd: number;
|
|
72
|
+
remainingMs: number;
|
|
73
|
+
}
|
|
74
|
+
export interface SidekickStateFile {
|
|
75
|
+
schemaVersion: typeof STATE_FILE_SCHEMA_VERSION;
|
|
76
|
+
/** ISO timestamp of the write. Excluded from the unchanged comparison. */
|
|
77
|
+
writtenAt: string;
|
|
78
|
+
writer: StateFileWriter;
|
|
79
|
+
account: StateFileAccount | null;
|
|
80
|
+
quota: {
|
|
81
|
+
claude: StateFileQuota | null;
|
|
82
|
+
codex: StateFileQuota | null;
|
|
83
|
+
};
|
|
84
|
+
context: StateFileContext | null;
|
|
85
|
+
session: StateFileSession | null;
|
|
86
|
+
/** Active five-hour block (local estimate); null when unknown or not computed by the writer. */
|
|
87
|
+
billingBlock: StateFileBillingBlock | null;
|
|
88
|
+
}
|
|
89
|
+
/** Everything but the fields the writer stamps itself. */
|
|
90
|
+
export type SidekickStateInput = Omit<SidekickStateFile, 'schemaVersion' | 'writtenAt'>;
|
|
91
|
+
export interface WriteStateFileOptions {
|
|
92
|
+
/** Defaults to `<configDir>/state.json`. */
|
|
93
|
+
filePath?: string;
|
|
94
|
+
/** Clock for `writtenAt` (default `new Date()`). */
|
|
95
|
+
now?: Date;
|
|
96
|
+
}
|
|
97
|
+
export declare function getStateFilePath(): string;
|
|
98
|
+
/** Read the current state file; null when absent or unreadable. */
|
|
99
|
+
export declare function readStateFile(filePath?: string): SidekickStateFile | null;
|
|
100
|
+
/**
|
|
101
|
+
* Write the state file atomically, but only when something other than
|
|
102
|
+
* `writtenAt` changed since the last write. Returns true when a write
|
|
103
|
+
* happened. Never throws: the state file is a convenience for other tools.
|
|
104
|
+
*/
|
|
105
|
+
export declare function writeStateFile(state: SidekickStateInput, options?: WriteStateFileOptions): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Project a quota sample onto the state-file shape. A live sample (for
|
|
108
|
+
* example from the status-line payload) carries `capturedAt` but no age, so
|
|
109
|
+
* the age and freshness are derived from `now` when the sample omits them.
|
|
110
|
+
*/
|
|
111
|
+
export declare function quotaToStateFile(quota: QuotaState | null | undefined, now?: number): StateFileQuota | null;
|
|
112
|
+
/** Project a billing block onto the state-file shape (totals only). */
|
|
113
|
+
export declare function billingBlockToStateFile(block: BillingBlock | null | undefined): StateFileBillingBlock | null;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `state.json`: a small, versioned file for external consumers (tmux
|
|
4
|
+
* status bars, menu-bar apps, scripts) that want Sidekick's current account,
|
|
5
|
+
* quota windows with freshness, context usage, session cost, and the active
|
|
6
|
+
* billing block without running a Sidekick command.
|
|
7
|
+
*
|
|
8
|
+
* Written by the status line on every prompt and by both dashboards on their
|
|
9
|
+
* refresh ticks, but only when the content changed, so the hot path costs one
|
|
10
|
+
* small read in the common case. The schema is public: `schemaVersion` is 1,
|
|
11
|
+
* fields are only ever added, and the matching zod schema lives in
|
|
12
|
+
* `sidekick-shared/schemas` (`sidekickStateFileSchema`). This module does not
|
|
13
|
+
* import zod, so the status-line fast path stays small.
|
|
14
|
+
*
|
|
15
|
+
* @module stateFile
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.STATE_FILE_NAME = exports.STATE_FILE_SCHEMA_VERSION = void 0;
|
|
52
|
+
exports.getStateFilePath = getStateFilePath;
|
|
53
|
+
exports.readStateFile = readStateFile;
|
|
54
|
+
exports.writeStateFile = writeStateFile;
|
|
55
|
+
exports.quotaToStateFile = quotaToStateFile;
|
|
56
|
+
exports.billingBlockToStateFile = billingBlockToStateFile;
|
|
57
|
+
const fs = __importStar(require("fs"));
|
|
58
|
+
const paths_1 = require("./paths");
|
|
59
|
+
const quota_1 = require("./quota");
|
|
60
|
+
const atomic_1 = require("./writers/atomic");
|
|
61
|
+
exports.STATE_FILE_SCHEMA_VERSION = 1;
|
|
62
|
+
exports.STATE_FILE_NAME = 'state.json';
|
|
63
|
+
function getStateFilePath() {
|
|
64
|
+
return (0, paths_1.getGlobalDataPath)(exports.STATE_FILE_NAME);
|
|
65
|
+
}
|
|
66
|
+
/** Read the current state file; null when absent or unreadable. */
|
|
67
|
+
function readStateFile(filePath = getStateFilePath()) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
70
|
+
return parsed && parsed.schemaVersion === exports.STATE_FILE_SCHEMA_VERSION ? parsed : null;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Key-order-independent serialisation, dropping undefined values. */
|
|
77
|
+
function stableStringify(value) {
|
|
78
|
+
if (Array.isArray(value))
|
|
79
|
+
return `[${value.map(stableStringify).join(',')}]`;
|
|
80
|
+
if (value && typeof value === 'object') {
|
|
81
|
+
const record = value;
|
|
82
|
+
const entries = Object.keys(record)
|
|
83
|
+
.sort()
|
|
84
|
+
.filter((key) => record[key] !== undefined)
|
|
85
|
+
.map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`);
|
|
86
|
+
return `{${entries.join(',')}}`;
|
|
87
|
+
}
|
|
88
|
+
return JSON.stringify(value) ?? 'null';
|
|
89
|
+
}
|
|
90
|
+
/** The content that decides whether a rewrite is needed: everything the writer does not stamp. */
|
|
91
|
+
function comparable(state) {
|
|
92
|
+
return stableStringify({ ...state, schemaVersion: undefined, writtenAt: undefined });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write the state file atomically, but only when something other than
|
|
96
|
+
* `writtenAt` changed since the last write. Returns true when a write
|
|
97
|
+
* happened. Never throws: the state file is a convenience for other tools.
|
|
98
|
+
*/
|
|
99
|
+
function writeStateFile(state, options = {}) {
|
|
100
|
+
const filePath = options.filePath ?? getStateFilePath();
|
|
101
|
+
try {
|
|
102
|
+
const existing = readStateFile(filePath);
|
|
103
|
+
if (existing && comparable(existing) === comparable(state))
|
|
104
|
+
return false;
|
|
105
|
+
const next = {
|
|
106
|
+
schemaVersion: exports.STATE_FILE_SCHEMA_VERSION,
|
|
107
|
+
writtenAt: (options.now ?? new Date()).toISOString(),
|
|
108
|
+
...state,
|
|
109
|
+
};
|
|
110
|
+
(0, atomic_1.atomicWriteJsonSync)(filePath, next);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Project a quota sample onto the state-file shape. A live sample (for
|
|
119
|
+
* example from the status-line payload) carries `capturedAt` but no age, so
|
|
120
|
+
* the age and freshness are derived from `now` when the sample omits them.
|
|
121
|
+
*/
|
|
122
|
+
function quotaToStateFile(quota, now = Date.now()) {
|
|
123
|
+
if (!quota || !quota.available)
|
|
124
|
+
return null;
|
|
125
|
+
let ageMs = typeof quota.ageMs === 'number' ? quota.ageMs : null;
|
|
126
|
+
let freshness = quota.freshness ?? null;
|
|
127
|
+
if (ageMs === null && quota.capturedAt) {
|
|
128
|
+
const capturedMs = Date.parse(quota.capturedAt);
|
|
129
|
+
if (Number.isFinite(capturedMs)) {
|
|
130
|
+
ageMs = Math.max(0, now - capturedMs);
|
|
131
|
+
freshness ??= (0, quota_1.classifyQuotaFreshness)(ageMs);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
fiveHour: { utilization: quota.fiveHour.utilization, resetsAt: quota.fiveHour.resetsAt },
|
|
136
|
+
sevenDay: { utilization: quota.sevenDay.utilization, resetsAt: quota.sevenDay.resetsAt },
|
|
137
|
+
source: quota.source ?? null,
|
|
138
|
+
capturedSource: quota.capturedSource ?? null,
|
|
139
|
+
capturedAt: quota.capturedAt ?? null,
|
|
140
|
+
ageMs,
|
|
141
|
+
freshness,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/** Project a billing block onto the state-file shape (totals only). */
|
|
145
|
+
function billingBlockToStateFile(block) {
|
|
146
|
+
if (!block)
|
|
147
|
+
return null;
|
|
148
|
+
return {
|
|
149
|
+
start: block.start,
|
|
150
|
+
end: block.end,
|
|
151
|
+
isActive: block.isActive,
|
|
152
|
+
tokens: block.tokens.total,
|
|
153
|
+
costUsd: block.costUsd,
|
|
154
|
+
costProvenance: block.costProvenance,
|
|
155
|
+
burnRatePerMinute: block.burnRatePerMinute,
|
|
156
|
+
projectedTokens: block.projectedTokens,
|
|
157
|
+
projectedCostUsd: block.projectedCostUsd,
|
|
158
|
+
remainingMs: block.remainingMs,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser for the JSON Claude Code pipes to its status-line command.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code runs the configured `statusLine.command` after every response
|
|
5
|
+
* (debounced at 300 ms) with a JSON document on stdin describing the session:
|
|
6
|
+
* model, workspace, context-window usage, estimated session cost, and — for
|
|
7
|
+
* Claude.ai Pro and Max subscribers — the *official* five-hour and seven-day
|
|
8
|
+
* rate-limit windows. That last block is the same data `/usage` shows and
|
|
9
|
+
* needs no network call, so Sidekick treats it as its most authoritative
|
|
10
|
+
* quota source whenever the status line is installed.
|
|
11
|
+
*
|
|
12
|
+
* Only the fields Sidekick reads are typed here; the raw document is kept on
|
|
13
|
+
* `raw` for callers that need more. Browser-safe: no Node imports.
|
|
14
|
+
*
|
|
15
|
+
* @module statusline/claudeStatuslinePayload
|
|
16
|
+
*/
|
|
17
|
+
import type { QuotaState } from '../quota';
|
|
18
|
+
/** One official rate-limit window. */
|
|
19
|
+
export interface ClaudeStatuslineRateLimitWindow {
|
|
20
|
+
/** Percentage of the window consumed, 0–100 (spend limits may exceed 100). */
|
|
21
|
+
usedPercentage: number;
|
|
22
|
+
/** Unix epoch seconds when the window resets. */
|
|
23
|
+
resetsAt: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ClaudeStatuslinePayload {
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
transcriptPath?: string;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
model?: {
|
|
30
|
+
id?: string;
|
|
31
|
+
displayName?: string;
|
|
32
|
+
};
|
|
33
|
+
workspace?: {
|
|
34
|
+
currentDir?: string;
|
|
35
|
+
projectDir?: string;
|
|
36
|
+
gitWorktree?: string;
|
|
37
|
+
};
|
|
38
|
+
contextWindow?: {
|
|
39
|
+
usedPercentage?: number | null;
|
|
40
|
+
remainingPercentage?: number | null;
|
|
41
|
+
contextWindowSize?: number;
|
|
42
|
+
totalInputTokens?: number;
|
|
43
|
+
totalOutputTokens?: number;
|
|
44
|
+
};
|
|
45
|
+
cost?: {
|
|
46
|
+
totalCostUsd?: number;
|
|
47
|
+
totalDurationMs?: number;
|
|
48
|
+
totalApiDurationMs?: number;
|
|
49
|
+
totalLinesAdded?: number;
|
|
50
|
+
totalLinesRemoved?: number;
|
|
51
|
+
};
|
|
52
|
+
rateLimits?: {
|
|
53
|
+
fiveHour?: ClaudeStatuslineRateLimitWindow;
|
|
54
|
+
sevenDay?: ClaudeStatuslineRateLimitWindow;
|
|
55
|
+
spendLimit?: ClaudeStatuslineRateLimitWindow;
|
|
56
|
+
};
|
|
57
|
+
promptCache?: {
|
|
58
|
+
warm?: boolean;
|
|
59
|
+
cachingObserved?: boolean;
|
|
60
|
+
hitRatio?: number | null;
|
|
61
|
+
requests?: number;
|
|
62
|
+
misses?: number;
|
|
63
|
+
expectedRebuilds?: number;
|
|
64
|
+
};
|
|
65
|
+
/** The parsed document as received. */
|
|
66
|
+
raw: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Parse a status-line document. Returns `null` for empty input, non-JSON, or
|
|
70
|
+
* JSON that is not an object; never throws.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseClaudeStatuslinePayload(text: string): ClaudeStatuslinePayload | null;
|
|
73
|
+
export interface QuotaFromStatuslineOptions {
|
|
74
|
+
/** Capture time; defaults to now. */
|
|
75
|
+
now?: Date;
|
|
76
|
+
/**
|
|
77
|
+
* A previously known quota (typically the persisted snapshot). Windows the
|
|
78
|
+
* payload omits are carried over from it, since Claude Code drops a window
|
|
79
|
+
* from the document once its reset time has passed.
|
|
80
|
+
*/
|
|
81
|
+
fallback?: QuotaState | null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build a `QuotaState` from the official rate-limit block. Returns `null`
|
|
85
|
+
* when the payload carries no rate limits at all (API-key users, or before
|
|
86
|
+
* the first response of a session), so callers fall back to their other
|
|
87
|
+
* sources.
|
|
88
|
+
*/
|
|
89
|
+
export declare function quotaFromStatuslinePayload(payload: ClaudeStatuslinePayload, options?: QuotaFromStatuslineOptions): QuotaState | null;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Parser for the JSON Claude Code pipes to its status-line command.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code runs the configured `statusLine.command` after every response
|
|
6
|
+
* (debounced at 300 ms) with a JSON document on stdin describing the session:
|
|
7
|
+
* model, workspace, context-window usage, estimated session cost, and — for
|
|
8
|
+
* Claude.ai Pro and Max subscribers — the *official* five-hour and seven-day
|
|
9
|
+
* rate-limit windows. That last block is the same data `/usage` shows and
|
|
10
|
+
* needs no network call, so Sidekick treats it as its most authoritative
|
|
11
|
+
* quota source whenever the status line is installed.
|
|
12
|
+
*
|
|
13
|
+
* Only the fields Sidekick reads are typed here; the raw document is kept on
|
|
14
|
+
* `raw` for callers that need more. Browser-safe: no Node imports.
|
|
15
|
+
*
|
|
16
|
+
* @module statusline/claudeStatuslinePayload
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.parseClaudeStatuslinePayload = parseClaudeStatuslinePayload;
|
|
20
|
+
exports.quotaFromStatuslinePayload = quotaFromStatuslinePayload;
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function num(value) {
|
|
25
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
function nullableNum(value) {
|
|
28
|
+
if (value === null)
|
|
29
|
+
return null;
|
|
30
|
+
return num(value);
|
|
31
|
+
}
|
|
32
|
+
function str(value) {
|
|
33
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
34
|
+
}
|
|
35
|
+
function bool(value) {
|
|
36
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
37
|
+
}
|
|
38
|
+
function window(value) {
|
|
39
|
+
if (!isRecord(value))
|
|
40
|
+
return undefined;
|
|
41
|
+
const usedPercentage = num(value.used_percentage);
|
|
42
|
+
const resetsAt = num(value.resets_at);
|
|
43
|
+
if (usedPercentage === undefined || resetsAt === undefined)
|
|
44
|
+
return undefined;
|
|
45
|
+
return { usedPercentage, resetsAt };
|
|
46
|
+
}
|
|
47
|
+
function defined(value) {
|
|
48
|
+
return Object.values(value).some((entry) => entry !== undefined) ? value : undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parse a status-line document. Returns `null` for empty input, non-JSON, or
|
|
52
|
+
* JSON that is not an object; never throws.
|
|
53
|
+
*/
|
|
54
|
+
function parseClaudeStatuslinePayload(text) {
|
|
55
|
+
if (typeof text !== 'string' || !text.trim())
|
|
56
|
+
return null;
|
|
57
|
+
let raw;
|
|
58
|
+
try {
|
|
59
|
+
raw = JSON.parse(text);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (!isRecord(raw))
|
|
65
|
+
return null;
|
|
66
|
+
const model = isRecord(raw.model) ? raw.model : undefined;
|
|
67
|
+
const workspace = isRecord(raw.workspace) ? raw.workspace : undefined;
|
|
68
|
+
const contextWindow = isRecord(raw.context_window) ? raw.context_window : undefined;
|
|
69
|
+
const cost = isRecord(raw.cost) ? raw.cost : undefined;
|
|
70
|
+
const rateLimits = isRecord(raw.rate_limits) ? raw.rate_limits : undefined;
|
|
71
|
+
const promptCache = isRecord(raw.prompt_cache) ? raw.prompt_cache : undefined;
|
|
72
|
+
return {
|
|
73
|
+
sessionId: str(raw.session_id),
|
|
74
|
+
transcriptPath: str(raw.transcript_path),
|
|
75
|
+
cwd: str(raw.cwd),
|
|
76
|
+
model: model ? defined({ id: str(model.id), displayName: str(model.display_name) }) : undefined,
|
|
77
|
+
workspace: workspace
|
|
78
|
+
? defined({
|
|
79
|
+
currentDir: str(workspace.current_dir),
|
|
80
|
+
projectDir: str(workspace.project_dir),
|
|
81
|
+
gitWorktree: str(workspace.git_worktree),
|
|
82
|
+
})
|
|
83
|
+
: undefined,
|
|
84
|
+
contextWindow: contextWindow
|
|
85
|
+
? defined({
|
|
86
|
+
usedPercentage: nullableNum(contextWindow.used_percentage),
|
|
87
|
+
remainingPercentage: nullableNum(contextWindow.remaining_percentage),
|
|
88
|
+
contextWindowSize: num(contextWindow.context_window_size),
|
|
89
|
+
totalInputTokens: num(contextWindow.total_input_tokens),
|
|
90
|
+
totalOutputTokens: num(contextWindow.total_output_tokens),
|
|
91
|
+
})
|
|
92
|
+
: undefined,
|
|
93
|
+
cost: cost
|
|
94
|
+
? defined({
|
|
95
|
+
totalCostUsd: num(cost.total_cost_usd),
|
|
96
|
+
totalDurationMs: num(cost.total_duration_ms),
|
|
97
|
+
totalApiDurationMs: num(cost.total_api_duration_ms),
|
|
98
|
+
totalLinesAdded: num(cost.total_lines_added),
|
|
99
|
+
totalLinesRemoved: num(cost.total_lines_removed),
|
|
100
|
+
})
|
|
101
|
+
: undefined,
|
|
102
|
+
rateLimits: rateLimits
|
|
103
|
+
? defined({
|
|
104
|
+
fiveHour: window(rateLimits.five_hour),
|
|
105
|
+
sevenDay: window(rateLimits.seven_day),
|
|
106
|
+
spendLimit: window(rateLimits.spend_limit),
|
|
107
|
+
})
|
|
108
|
+
: undefined,
|
|
109
|
+
promptCache: promptCache
|
|
110
|
+
? defined({
|
|
111
|
+
warm: bool(promptCache.warm),
|
|
112
|
+
cachingObserved: bool(promptCache.caching_observed),
|
|
113
|
+
hitRatio: nullableNum(promptCache.hit_ratio),
|
|
114
|
+
requests: num(promptCache.requests),
|
|
115
|
+
misses: num(promptCache.misses),
|
|
116
|
+
expectedRebuilds: num(promptCache.expected_rebuilds),
|
|
117
|
+
})
|
|
118
|
+
: undefined,
|
|
119
|
+
raw,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function toWindow(live, fallback) {
|
|
123
|
+
if (live) {
|
|
124
|
+
return {
|
|
125
|
+
utilization: Math.max(0, live.usedPercentage),
|
|
126
|
+
resetsAt: new Date(live.resetsAt * 1000).toISOString(),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return fallback ?? { utilization: 0, resetsAt: '' };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Build a `QuotaState` from the official rate-limit block. Returns `null`
|
|
133
|
+
* when the payload carries no rate limits at all (API-key users, or before
|
|
134
|
+
* the first response of a session), so callers fall back to their other
|
|
135
|
+
* sources.
|
|
136
|
+
*/
|
|
137
|
+
function quotaFromStatuslinePayload(payload, options = {}) {
|
|
138
|
+
const limits = payload.rateLimits;
|
|
139
|
+
if (!limits?.fiveHour && !limits?.sevenDay)
|
|
140
|
+
return null;
|
|
141
|
+
const now = options.now ?? new Date();
|
|
142
|
+
const fallback = options.fallback ?? undefined;
|
|
143
|
+
return {
|
|
144
|
+
fiveHour: toWindow(limits.fiveHour, fallback?.fiveHour),
|
|
145
|
+
sevenDay: toWindow(limits.sevenDay, fallback?.sevenDay),
|
|
146
|
+
available: true,
|
|
147
|
+
providerId: 'claude-code',
|
|
148
|
+
source: 'statusline',
|
|
149
|
+
capturedAt: now.toISOString(),
|
|
150
|
+
stale: false,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { ActiveAccountStatus } from '../accountStatus';
|
|
2
2
|
import type { QuotaState } from '../quota';
|
|
3
|
+
import type { ClaudeStatuslinePayload } from './claudeStatuslinePayload';
|
|
3
4
|
export interface StatuslineInput {
|
|
4
5
|
accounts: ActiveAccountStatus;
|
|
5
6
|
claudeQuota?: QuotaState | null;
|
|
6
7
|
codexQuota?: QuotaState | null;
|
|
8
|
+
/**
|
|
9
|
+
* The document Claude Code piped to the status-line command, when running
|
|
10
|
+
* as one. Adds context usage, session cost, and prompt-cache hit rate.
|
|
11
|
+
*/
|
|
12
|
+
live?: ClaudeStatuslinePayload | null;
|
|
7
13
|
now?: Date;
|
|
8
14
|
}
|
|
9
15
|
export interface StatuslineSelection {
|
|
@@ -13,4 +19,11 @@ export interface StatuslineSelection {
|
|
|
13
19
|
quota: QuotaState | null;
|
|
14
20
|
}
|
|
15
21
|
export declare function selectStatuslineAccount(input: StatuslineInput): StatuslineSelection | null;
|
|
22
|
+
/**
|
|
23
|
+
* One-line status. Segments, in order, each omitted when unknown:
|
|
24
|
+
* `acct:<label> · 5h 42% resets 14:00 · ~1h20m left · 7d 61% · (2h ago) · ctx 37% · $0.42 · cache 92%`
|
|
25
|
+
*
|
|
26
|
+
* The age segment appears only for cached quota older than five minutes, so
|
|
27
|
+
* a snapshot from yesterday can no longer read like a live figure.
|
|
28
|
+
*/
|
|
16
29
|
export declare function formatStatusline(input: StatuslineInput): string;
|
|
@@ -23,20 +23,62 @@ function selectStatuslineAccount(input) {
|
|
|
23
23
|
}
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* One-line status. Segments, in order, each omitted when unknown:
|
|
28
|
+
* `acct:<label> · 5h 42% resets 14:00 · ~1h20m left · 7d 61% · (2h ago) · ctx 37% · $0.42 · cache 92%`
|
|
29
|
+
*
|
|
30
|
+
* The age segment appears only for cached quota older than five minutes, so
|
|
31
|
+
* a snapshot from yesterday can no longer read like a live figure.
|
|
32
|
+
*/
|
|
26
33
|
function formatStatusline(input) {
|
|
27
34
|
const selected = selectStatuslineAccount(input);
|
|
35
|
+
const now = input.now ?? new Date();
|
|
36
|
+
const liveSegments = formatLiveSegments(input.live);
|
|
28
37
|
if (!selected)
|
|
29
|
-
return 'acct:none
|
|
38
|
+
return joinSegments(['acct:none', 'quota unavailable', ...liveSegments]);
|
|
30
39
|
const account = compactLabel(selected.accountLabel);
|
|
31
40
|
const quota = selected.quota;
|
|
32
|
-
if (!quota?.available)
|
|
33
|
-
return `acct:${account}
|
|
34
|
-
|
|
41
|
+
if (!quota?.available) {
|
|
42
|
+
return joinSegments([`acct:${account}`, 'quota unavailable', ...liveSegments]);
|
|
43
|
+
}
|
|
35
44
|
const utilization = clampPercent(quota.fiveHour.utilization);
|
|
36
45
|
const reset = formatReset(quota.fiveHour.resetsAt, now);
|
|
37
46
|
const eta = estimateWindowEta(quota, now);
|
|
38
|
-
const
|
|
39
|
-
|
|
47
|
+
const segments = [`acct:${account}`, `5h ${Math.round(utilization)}% resets ${reset}`];
|
|
48
|
+
if (eta != null)
|
|
49
|
+
segments.push(`~${formatMinutes(eta)} left`);
|
|
50
|
+
if (quota.sevenDay.resetsAt && quota.sevenDay.utilization > 0) {
|
|
51
|
+
segments.push(`7d ${Math.round(clampPercent(quota.sevenDay.utilization))}%`);
|
|
52
|
+
}
|
|
53
|
+
if (quota.freshness && quota.freshness !== 'fresh') {
|
|
54
|
+
segments.push(`(${(0, quota_1.formatQuotaAge)(quota.ageMs)})`);
|
|
55
|
+
}
|
|
56
|
+
return joinSegments([...segments, ...liveSegments]);
|
|
57
|
+
}
|
|
58
|
+
function formatLiveSegments(live) {
|
|
59
|
+
if (!live)
|
|
60
|
+
return [];
|
|
61
|
+
const segments = [];
|
|
62
|
+
const context = live.contextWindow?.usedPercentage;
|
|
63
|
+
if (typeof context === 'number')
|
|
64
|
+
segments.push(`ctx ${Math.round(clampPercent(context))}%`);
|
|
65
|
+
const cost = live.cost?.totalCostUsd;
|
|
66
|
+
if (typeof cost === 'number' && cost > 0)
|
|
67
|
+
segments.push(`$${formatCost(cost)}`);
|
|
68
|
+
const hitRatio = live.promptCache?.hitRatio;
|
|
69
|
+
if (typeof hitRatio === 'number')
|
|
70
|
+
segments.push(`cache ${Math.round(clampPercent(hitRatio * 100))}%`);
|
|
71
|
+
return segments;
|
|
72
|
+
}
|
|
73
|
+
function joinSegments(segments) {
|
|
74
|
+
return segments.join(' · ');
|
|
75
|
+
}
|
|
76
|
+
function formatCost(value) {
|
|
77
|
+
if (value >= 100)
|
|
78
|
+
return value.toFixed(0);
|
|
79
|
+
if (value >= 10)
|
|
80
|
+
return value.toFixed(1);
|
|
81
|
+
return value.toFixed(2);
|
|
40
82
|
}
|
|
41
83
|
function estimateWindowEta(quota, now) {
|
|
42
84
|
const resetAt = Date.parse(quota.fiveHour.resetsAt);
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
export { getActiveAccountStatus } from '../accountStatus';
|
|
2
|
-
export type { ActiveAccountStatus, ActiveProviderAccountStatus } from '../accountStatus';
|
|
3
|
-
export { readQuotaSnapshot } from '../quotaSnapshots';
|
|
2
|
+
export type { ActiveAccountStatus, ActiveAccountStatusOptions, ActiveProviderAccountStatus, } from '../accountStatus';
|
|
3
|
+
export { readQuotaSnapshot, writeQuotaSnapshot } from '../quotaSnapshots';
|
|
4
4
|
export type { QuotaSnapshotProviderId } from '../quotaSnapshots';
|
|
5
|
+
export { appendQuotaHistorySample, getWorkspaceIdFromPath } from '../quotaHistory';
|
|
6
|
+
export type { QuotaHistorySample } from '../quotaHistory';
|
|
7
|
+
export { classifyQuotaFreshness, formatQuotaAge } from '../quota';
|
|
8
|
+
export type { QuotaFreshness, QuotaState } from '../quota';
|
|
5
9
|
export { BurnRateCalculator, estimateTimeToQuota } from './BurnRateCalculator';
|
|
6
10
|
export { formatStatusline, selectStatuslineAccount } from './formatter';
|
|
7
11
|
export type { StatuslineInput, StatuslineSelection } from './formatter';
|
|
12
|
+
export { parseClaudeStatuslinePayload, quotaFromStatuslinePayload, } from './claudeStatuslinePayload';
|
|
13
|
+
export type { ClaudeStatuslinePayload, ClaudeStatuslineRateLimitWindow, QuotaFromStatuslineOptions, } from './claudeStatuslinePayload';
|
|
14
|
+
export { STATE_FILE_NAME, STATE_FILE_SCHEMA_VERSION, billingBlockToStateFile, getStateFilePath, quotaToStateFile, readStateFile, writeStateFile, } from '../stateFile';
|
|
15
|
+
export type { SidekickStateFile, SidekickStateInput, StateFileAccount, StateFileBillingBlock, StateFileContext, StateFileQuota, StateFileQuotaWindow, StateFileSession, StateFileWriter, WriteStateFileOptions, } from '../stateFile';
|
package/dist/statusline/index.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.readQuotaSnapshot = exports.getActiveAccountStatus = void 0;
|
|
3
|
+
exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.formatQuotaAge = exports.classifyQuotaFreshness = exports.getWorkspaceIdFromPath = exports.appendQuotaHistorySample = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.getActiveAccountStatus = void 0;
|
|
4
4
|
var accountStatus_1 = require("../accountStatus");
|
|
5
5
|
Object.defineProperty(exports, "getActiveAccountStatus", { enumerable: true, get: function () { return accountStatus_1.getActiveAccountStatus; } });
|
|
6
6
|
var quotaSnapshots_1 = require("../quotaSnapshots");
|
|
7
7
|
Object.defineProperty(exports, "readQuotaSnapshot", { enumerable: true, get: function () { return quotaSnapshots_1.readQuotaSnapshot; } });
|
|
8
|
+
Object.defineProperty(exports, "writeQuotaSnapshot", { enumerable: true, get: function () { return quotaSnapshots_1.writeQuotaSnapshot; } });
|
|
9
|
+
var quotaHistory_1 = require("../quotaHistory");
|
|
10
|
+
Object.defineProperty(exports, "appendQuotaHistorySample", { enumerable: true, get: function () { return quotaHistory_1.appendQuotaHistorySample; } });
|
|
11
|
+
Object.defineProperty(exports, "getWorkspaceIdFromPath", { enumerable: true, get: function () { return quotaHistory_1.getWorkspaceIdFromPath; } });
|
|
12
|
+
var quota_1 = require("../quota");
|
|
13
|
+
Object.defineProperty(exports, "classifyQuotaFreshness", { enumerable: true, get: function () { return quota_1.classifyQuotaFreshness; } });
|
|
14
|
+
Object.defineProperty(exports, "formatQuotaAge", { enumerable: true, get: function () { return quota_1.formatQuotaAge; } });
|
|
8
15
|
var BurnRateCalculator_1 = require("./BurnRateCalculator");
|
|
9
16
|
Object.defineProperty(exports, "BurnRateCalculator", { enumerable: true, get: function () { return BurnRateCalculator_1.BurnRateCalculator; } });
|
|
10
17
|
Object.defineProperty(exports, "estimateTimeToQuota", { enumerable: true, get: function () { return BurnRateCalculator_1.estimateTimeToQuota; } });
|
|
11
18
|
var formatter_1 = require("./formatter");
|
|
12
19
|
Object.defineProperty(exports, "formatStatusline", { enumerable: true, get: function () { return formatter_1.formatStatusline; } });
|
|
13
20
|
Object.defineProperty(exports, "selectStatuslineAccount", { enumerable: true, get: function () { return formatter_1.selectStatuslineAccount; } });
|
|
21
|
+
var claudeStatuslinePayload_1 = require("./claudeStatuslinePayload");
|
|
22
|
+
Object.defineProperty(exports, "parseClaudeStatuslinePayload", { enumerable: true, get: function () { return claudeStatuslinePayload_1.parseClaudeStatuslinePayload; } });
|
|
23
|
+
Object.defineProperty(exports, "quotaFromStatuslinePayload", { enumerable: true, get: function () { return claudeStatuslinePayload_1.quotaFromStatuslinePayload; } });
|
|
24
|
+
var stateFile_1 = require("../stateFile");
|
|
25
|
+
Object.defineProperty(exports, "STATE_FILE_NAME", { enumerable: true, get: function () { return stateFile_1.STATE_FILE_NAME; } });
|
|
26
|
+
Object.defineProperty(exports, "STATE_FILE_SCHEMA_VERSION", { enumerable: true, get: function () { return stateFile_1.STATE_FILE_SCHEMA_VERSION; } });
|
|
27
|
+
Object.defineProperty(exports, "billingBlockToStateFile", { enumerable: true, get: function () { return stateFile_1.billingBlockToStateFile; } });
|
|
28
|
+
Object.defineProperty(exports, "getStateFilePath", { enumerable: true, get: function () { return stateFile_1.getStateFilePath; } });
|
|
29
|
+
Object.defineProperty(exports, "quotaToStateFile", { enumerable: true, get: function () { return stateFile_1.quotaToStateFile; } });
|
|
30
|
+
Object.defineProperty(exports, "readStateFile", { enumerable: true, get: function () { return stateFile_1.readStateFile; } });
|
|
31
|
+
Object.defineProperty(exports, "writeStateFile", { enumerable: true, get: function () { return stateFile_1.writeStateFile; } });
|