@ekkos/cli 0.3.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/agent/daemon.d.ts +27 -0
- package/dist/agent/daemon.js +254 -29
- package/dist/agent/health-check.d.ts +35 -0
- package/dist/agent/health-check.js +243 -0
- package/dist/agent/pty-runner.d.ts +1 -0
- package/dist/agent/pty-runner.js +6 -1
- package/dist/capture/transcript-repair.d.ts +1 -0
- package/dist/capture/transcript-repair.js +12 -1
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +244 -0
- package/dist/commands/dashboard.d.ts +25 -0
- package/dist/commands/dashboard.js +1175 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.js +503 -350
- package/dist/commands/setup-remote.js +146 -37
- package/dist/commands/swarm-dashboard.d.ts +20 -0
- package/dist/commands/swarm-dashboard.js +735 -0
- package/dist/commands/swarm-setup.d.ts +10 -0
- package/dist/commands/swarm-setup.js +956 -0
- package/dist/commands/swarm.d.ts +46 -0
- package/dist/commands/swarm.js +441 -0
- package/dist/commands/test-claude.d.ts +16 -0
- package/dist/commands/test-claude.js +156 -0
- package/dist/commands/usage/blocks.d.ts +8 -0
- package/dist/commands/usage/blocks.js +60 -0
- package/dist/commands/usage/daily.d.ts +9 -0
- package/dist/commands/usage/daily.js +96 -0
- package/dist/commands/usage/dashboard.d.ts +8 -0
- package/dist/commands/usage/dashboard.js +104 -0
- package/dist/commands/usage/formatters.d.ts +41 -0
- package/dist/commands/usage/formatters.js +147 -0
- package/dist/commands/usage/index.d.ts +13 -0
- package/dist/commands/usage/index.js +87 -0
- package/dist/commands/usage/monthly.d.ts +8 -0
- package/dist/commands/usage/monthly.js +66 -0
- package/dist/commands/usage/session.d.ts +11 -0
- package/dist/commands/usage/session.js +193 -0
- package/dist/commands/usage/weekly.d.ts +9 -0
- package/dist/commands/usage/weekly.js +61 -0
- package/dist/deploy/instructions.d.ts +5 -2
- package/dist/deploy/instructions.js +11 -8
- package/dist/index.js +256 -20
- package/dist/lib/tmux-scrollbar.d.ts +14 -0
- package/dist/lib/tmux-scrollbar.js +296 -0
- package/dist/lib/usage-parser.d.ts +95 -5
- package/dist/lib/usage-parser.js +416 -71
- package/dist/utils/log-rotate.d.ts +18 -0
- package/dist/utils/log-rotate.js +74 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/utils/platform.js +3 -1
- package/dist/utils/session-binding.d.ts +5 -0
- package/dist/utils/session-binding.js +46 -0
- package/dist/utils/state.js +4 -0
- package/dist/utils/verify-remote-terminal.d.ts +10 -0
- package/dist/utils/verify-remote-terminal.js +415 -0
- package/package.json +16 -11
- package/templates/CLAUDE.md +135 -23
- package/templates/cursor-hooks/after-agent-response.sh +0 -0
- package/templates/cursor-hooks/before-submit-prompt.sh +0 -0
- package/templates/cursor-hooks/stop.sh +0 -0
- package/templates/ekkos-manifest.json +5 -5
- package/templates/hooks/assistant-response.sh +0 -0
- package/templates/hooks/lib/contract.sh +43 -31
- package/templates/hooks/lib/count-tokens.cjs +86 -0
- package/templates/hooks/lib/ekkos-reminders.sh +98 -0
- package/templates/hooks/lib/state.sh +53 -1
- package/templates/hooks/session-start.sh +0 -0
- package/templates/hooks/stop.sh +150 -388
- package/templates/hooks/user-prompt-submit.sh +353 -443
- package/templates/plan-template.md +0 -0
- package/templates/spec-template.md +0 -0
- package/templates/windsurf-hooks/README.md +212 -0
- package/templates/windsurf-hooks/hooks.json +9 -2
- package/templates/windsurf-hooks/install.sh +148 -0
- package/templates/windsurf-hooks/lib/contract.sh +2 -0
- package/templates/windsurf-hooks/post-cascade-response.sh +251 -0
- package/templates/windsurf-hooks/pre-user-prompt.sh +435 -0
- package/templates/windsurf-skills/ekkos-memory/SKILL.md +219 -0
- package/LICENSE +0 -21
- package/templates/windsurf-hooks/before-submit-prompt.sh +0 -238
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* tmux-scrollbar.ts
|
|
5
|
+
*
|
|
6
|
+
* A thin visual scrollbar (2 columns wide) that runs in its own narrow tmux pane.
|
|
7
|
+
* It tracks the scroll position of a target pane (Claude Code) and renders a
|
|
8
|
+
* proportional scrollbar thumb. Supports click-to-jump and drag-to-scroll.
|
|
9
|
+
*
|
|
10
|
+
* Usage: node tmux-scrollbar.js <target-pane>
|
|
11
|
+
* Example: node tmux-scrollbar.js :.0
|
|
12
|
+
*
|
|
13
|
+
* Layout: [Claude Code (68%)] [Scrollbar (2col)] [Dashboard (30%)]
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const child_process_1 = require("child_process");
|
|
17
|
+
const TARGET_PANE = process.argv[2] || ':.0';
|
|
18
|
+
const POLL_MS = 200;
|
|
19
|
+
// ── ANSI escape sequences ──
|
|
20
|
+
const ESC = '\x1b';
|
|
21
|
+
const CSI = `${ESC}[`;
|
|
22
|
+
const ansi = {
|
|
23
|
+
clear: `${CSI}2J`,
|
|
24
|
+
home: `${CSI}H`,
|
|
25
|
+
hideCursor: `${CSI}?25l`,
|
|
26
|
+
showCursor: `${CSI}?25h`,
|
|
27
|
+
// SGR extended mouse protocol: supports coordinates > 223
|
|
28
|
+
enableMouse: `${CSI}?1000h${CSI}?1002h${CSI}?1006h`,
|
|
29
|
+
disableMouse: `${CSI}?1000l${CSI}?1002l${CSI}?1006l`,
|
|
30
|
+
reset: `${CSI}0m`,
|
|
31
|
+
moveTo: (row, col) => `${CSI}${row};${col}H`,
|
|
32
|
+
// 256-color mode
|
|
33
|
+
fg256: (n) => `${CSI}38;5;${n}m`,
|
|
34
|
+
bg256: (n) => `${CSI}48;5;${n}m`,
|
|
35
|
+
};
|
|
36
|
+
// ── Color scheme (matches dashboard cyan theme) ──
|
|
37
|
+
const COLORS = {
|
|
38
|
+
thumbFg: ansi.fg256(44), // Cyan thumb
|
|
39
|
+
thumbBg: ansi.bg256(23), // Dark cyan background
|
|
40
|
+
thumbActiveFg: ansi.fg256(51), // Bright cyan when dragging
|
|
41
|
+
thumbActiveBg: ansi.bg256(30), // Brighter dark cyan when dragging
|
|
42
|
+
trackFg: ansi.fg256(236), // Very dark gray track dots
|
|
43
|
+
trackBg: ansi.bg256(233), // Near-black background
|
|
44
|
+
labelFg: ansi.fg256(240), // Dim label text
|
|
45
|
+
};
|
|
46
|
+
// ── State ──
|
|
47
|
+
let lastRenderedFrame = '';
|
|
48
|
+
let isDragging = false;
|
|
49
|
+
let pollTimer;
|
|
50
|
+
function getHeight() {
|
|
51
|
+
return process.stdout.rows || 40;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Query tmux for the target pane's scroll position.
|
|
55
|
+
* Returns { inMode, scrollPos, historySize, paneHeight }
|
|
56
|
+
*/
|
|
57
|
+
function getPaneInfo() {
|
|
58
|
+
try {
|
|
59
|
+
const raw = (0, child_process_1.execSync)(`tmux display-message -p -t "${TARGET_PANE}" ` +
|
|
60
|
+
`'#{pane_in_mode}|#{scroll_position}|#{history_size}|#{pane_height}'`, { encoding: 'utf-8', timeout: 800, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
61
|
+
const [mode, pos, hist, ph] = raw.split('|');
|
|
62
|
+
return {
|
|
63
|
+
inMode: mode === '1',
|
|
64
|
+
scrollPos: parseInt(pos) || 0,
|
|
65
|
+
historySize: parseInt(hist) || 0,
|
|
66
|
+
paneHeight: parseInt(ph) || 40,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { inMode: false, scrollPos: 0, historySize: 0, paneHeight: 40 };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Render the scrollbar to stdout using ANSI escape codes.
|
|
75
|
+
* Only redraws if the frame has changed (diffing).
|
|
76
|
+
*/
|
|
77
|
+
function render() {
|
|
78
|
+
const height = getHeight();
|
|
79
|
+
const info = getPaneInfo();
|
|
80
|
+
// Total scrollable content
|
|
81
|
+
const totalLines = info.historySize + info.paneHeight;
|
|
82
|
+
if (totalLines <= 0)
|
|
83
|
+
return;
|
|
84
|
+
// Thumb size proportional to viewport/total
|
|
85
|
+
const viewportRatio = Math.min(1, info.paneHeight / totalLines);
|
|
86
|
+
const thumbSize = Math.max(2, Math.round(viewportRatio * height));
|
|
87
|
+
// Thumb position
|
|
88
|
+
let thumbTop;
|
|
89
|
+
if (!info.inMode || info.historySize === 0) {
|
|
90
|
+
// Live output — thumb at bottom
|
|
91
|
+
thumbTop = height - thumbSize;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// Copy mode — scroll_position = lines from bottom
|
|
95
|
+
const scrollFraction = Math.min(1, info.scrollPos / Math.max(1, info.historySize));
|
|
96
|
+
thumbTop = Math.round((1 - scrollFraction) * (height - thumbSize));
|
|
97
|
+
}
|
|
98
|
+
// Clamp
|
|
99
|
+
thumbTop = Math.max(0, Math.min(height - thumbSize, thumbTop));
|
|
100
|
+
// Build frame string
|
|
101
|
+
const fgColor = isDragging ? COLORS.thumbActiveFg : COLORS.thumbFg;
|
|
102
|
+
const bgColor = isDragging ? COLORS.thumbActiveBg : COLORS.thumbBg;
|
|
103
|
+
let frame = ansi.home;
|
|
104
|
+
for (let y = 0; y < height; y++) {
|
|
105
|
+
const isThumb = y >= thumbTop && y < thumbTop + thumbSize;
|
|
106
|
+
frame += ansi.moveTo(y + 1, 1);
|
|
107
|
+
if (isThumb) {
|
|
108
|
+
frame += `${fgColor}${bgColor}██${ansi.reset}`;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
frame += `${COLORS.trackFg}${COLORS.trackBg}░░${ansi.reset}`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Only write if changed
|
|
115
|
+
if (frame !== lastRenderedFrame) {
|
|
116
|
+
process.stdout.write(frame);
|
|
117
|
+
lastRenderedFrame = frame;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Scroll the target pane to a position based on scrollbar click location.
|
|
122
|
+
*/
|
|
123
|
+
function scrollToPosition(y) {
|
|
124
|
+
const height = getHeight();
|
|
125
|
+
const info = getPaneInfo();
|
|
126
|
+
if (info.historySize <= 0)
|
|
127
|
+
return;
|
|
128
|
+
const ratio = Math.max(0, Math.min(1, y / Math.max(1, height - 1)));
|
|
129
|
+
// If clicking at the very bottom, exit copy-mode for live output
|
|
130
|
+
if (ratio >= 0.95) {
|
|
131
|
+
try {
|
|
132
|
+
if (info.inMode) {
|
|
133
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X cancel`, {
|
|
134
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch { /* ignore */ }
|
|
139
|
+
lastRenderedFrame = '';
|
|
140
|
+
render();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Target line from top of scrollback
|
|
144
|
+
const targetLine = Math.round(ratio * info.historySize);
|
|
145
|
+
try {
|
|
146
|
+
// Enter copy-mode if not already
|
|
147
|
+
if (!info.inMode) {
|
|
148
|
+
(0, child_process_1.execSync)(`tmux copy-mode -t "${TARGET_PANE}"`, {
|
|
149
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// Jump to target line using goto-line (tmux 3.1+)
|
|
153
|
+
// Fallback: history-top + cursor-down for older tmux
|
|
154
|
+
try {
|
|
155
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X goto-line ${targetLine}`, {
|
|
156
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Fallback for older tmux: go to top, then move down
|
|
161
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X history-top`, {
|
|
162
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
163
|
+
});
|
|
164
|
+
if (targetLine > 0) {
|
|
165
|
+
// Move in chunks to avoid command-line length limits
|
|
166
|
+
let remaining = targetLine;
|
|
167
|
+
while (remaining > 0) {
|
|
168
|
+
const chunk = Math.min(remaining, 5000);
|
|
169
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X -N ${chunk} cursor-down`, {
|
|
170
|
+
timeout: 1000, stdio: ['pipe', 'pipe', 'pipe'],
|
|
171
|
+
});
|
|
172
|
+
remaining -= chunk;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch { /* ignore scroll errors */ }
|
|
178
|
+
lastRenderedFrame = '';
|
|
179
|
+
render();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Refocus the target pane (Claude Code) after scrollbar interaction.
|
|
183
|
+
*/
|
|
184
|
+
function refocusTarget() {
|
|
185
|
+
try {
|
|
186
|
+
(0, child_process_1.execSync)(`tmux select-pane -t "${TARGET_PANE}"`, {
|
|
187
|
+
timeout: 300, stdio: ['pipe', 'pipe', 'pipe'],
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch { /* ignore */ }
|
|
191
|
+
}
|
|
192
|
+
// ── Mouse event handling ──
|
|
193
|
+
function handleInput(data) {
|
|
194
|
+
const str = data.toString();
|
|
195
|
+
// Parse SGR mouse events: ESC [ < button ; x ; y M (press) / m (release)
|
|
196
|
+
const events = str.matchAll(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/g);
|
|
197
|
+
for (const match of events) {
|
|
198
|
+
const button = parseInt(match[1]);
|
|
199
|
+
const y = parseInt(match[3]) - 1; // Convert to 0-indexed
|
|
200
|
+
const isPress = match[4] === 'M';
|
|
201
|
+
if (button === 0) {
|
|
202
|
+
// Left mouse button
|
|
203
|
+
if (isPress) {
|
|
204
|
+
isDragging = true;
|
|
205
|
+
scrollToPosition(y);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Release
|
|
209
|
+
if (isDragging) {
|
|
210
|
+
isDragging = false;
|
|
211
|
+
lastRenderedFrame = '';
|
|
212
|
+
render();
|
|
213
|
+
// Return focus to Claude Code pane after click
|
|
214
|
+
refocusTarget();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (button === 32 && isDragging) {
|
|
219
|
+
// Left button drag (SGR reports button 32 for motion with button 0 held)
|
|
220
|
+
scrollToPosition(y);
|
|
221
|
+
}
|
|
222
|
+
else if (button === 64) {
|
|
223
|
+
// Scroll wheel up — forward to target pane
|
|
224
|
+
try {
|
|
225
|
+
const info = getPaneInfo();
|
|
226
|
+
if (!info.inMode) {
|
|
227
|
+
(0, child_process_1.execSync)(`tmux copy-mode -t "${TARGET_PANE}" -e`, {
|
|
228
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X -N 5 scroll-up`, {
|
|
232
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
catch { /* ignore */ }
|
|
236
|
+
lastRenderedFrame = '';
|
|
237
|
+
render();
|
|
238
|
+
}
|
|
239
|
+
else if (button === 65) {
|
|
240
|
+
// Scroll wheel down — forward to target pane
|
|
241
|
+
try {
|
|
242
|
+
(0, child_process_1.execSync)(`tmux send-keys -t "${TARGET_PANE}" -X -N 5 scroll-down`, {
|
|
243
|
+
timeout: 500, stdio: ['pipe', 'pipe', 'pipe'],
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
catch { /* ignore */ }
|
|
247
|
+
lastRenderedFrame = '';
|
|
248
|
+
render();
|
|
249
|
+
}
|
|
250
|
+
return; // Processed mouse event
|
|
251
|
+
}
|
|
252
|
+
// Keyboard input
|
|
253
|
+
if (str === 'q' || str === '\x03') {
|
|
254
|
+
// Quit on 'q' or Ctrl-C
|
|
255
|
+
shutdown();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// ── Lifecycle ──
|
|
259
|
+
function setup() {
|
|
260
|
+
// Hide cursor, enable mouse tracking, clear screen
|
|
261
|
+
process.stdout.write(ansi.hideCursor + ansi.enableMouse + ansi.clear);
|
|
262
|
+
// Raw mode for stdin (capture mouse events)
|
|
263
|
+
if (process.stdin.setRawMode) {
|
|
264
|
+
process.stdin.setRawMode(true);
|
|
265
|
+
}
|
|
266
|
+
process.stdin.resume();
|
|
267
|
+
process.stdin.on('data', handleInput);
|
|
268
|
+
// Handle terminal resize
|
|
269
|
+
process.stdout.on('resize', () => {
|
|
270
|
+
lastRenderedFrame = '';
|
|
271
|
+
render();
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function cleanup() {
|
|
275
|
+
process.stdout.write(ansi.showCursor + ansi.disableMouse + ansi.reset + ansi.clear);
|
|
276
|
+
if (process.stdin.setRawMode) {
|
|
277
|
+
try {
|
|
278
|
+
process.stdin.setRawMode(false);
|
|
279
|
+
}
|
|
280
|
+
catch { /* ignore */ }
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function shutdown() {
|
|
284
|
+
clearInterval(pollTimer);
|
|
285
|
+
cleanup();
|
|
286
|
+
process.exit(0);
|
|
287
|
+
}
|
|
288
|
+
// Graceful exit
|
|
289
|
+
process.on('exit', cleanup);
|
|
290
|
+
process.on('SIGINT', shutdown);
|
|
291
|
+
process.on('SIGTERM', shutdown);
|
|
292
|
+
process.on('SIGHUP', shutdown);
|
|
293
|
+
// ── Main ──
|
|
294
|
+
setup();
|
|
295
|
+
render();
|
|
296
|
+
pollTimer = setInterval(render, POLL_MS);
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
export interface ActiveSession {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
sessionName: string;
|
|
4
|
+
pid: number;
|
|
5
|
+
startedAt: string;
|
|
6
|
+
projectPath: string;
|
|
7
|
+
lastHeartbeat: string;
|
|
8
|
+
}
|
|
9
|
+
interface SessionNameResolution {
|
|
10
|
+
uuid: string;
|
|
11
|
+
sessionName: string;
|
|
12
|
+
projectPath: string;
|
|
13
|
+
encodedProjectPath: string;
|
|
14
|
+
startedAt?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Detect ekkOS 3-word session names like "lit-lex-zip" */
|
|
17
|
+
export declare function isEkkosSessionName(name: string): boolean;
|
|
18
|
+
/** Resolve an ekkOS session name to a JSONL UUID */
|
|
19
|
+
export declare function resolveSessionName(name: string): SessionNameResolution | null;
|
|
20
|
+
/** Parse a single JSONL file and return SessionUsage for an ekkOS-named session */
|
|
21
|
+
export declare function getSessionUsageByName(name: string): Promise<SessionUsage | null>;
|
|
22
|
+
/** List ekkOS sessions with lightweight cost data (for session list view) */
|
|
23
|
+
export declare function listEkkosSessions(limit?: number): Promise<{
|
|
24
|
+
name: string;
|
|
25
|
+
uuid: string;
|
|
26
|
+
projectPath: string;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
lastHeartbeat: string;
|
|
29
|
+
cost: number;
|
|
30
|
+
tokens: number;
|
|
31
|
+
models: string[];
|
|
32
|
+
turnCount: number;
|
|
33
|
+
}[]>;
|
|
1
34
|
export interface TurnMetrics {
|
|
2
35
|
turn_number: number;
|
|
3
36
|
timestamp: string;
|
|
@@ -37,9 +70,10 @@ export interface CcusageSession {
|
|
|
37
70
|
outputTokens: number;
|
|
38
71
|
cacheCreationTokens: number;
|
|
39
72
|
cacheReadTokens: number;
|
|
40
|
-
|
|
73
|
+
cost: number;
|
|
41
74
|
totalCost: number;
|
|
42
75
|
lastActivity: string;
|
|
76
|
+
versions?: string[];
|
|
43
77
|
modelsUsed: string[];
|
|
44
78
|
modelBreakdowns: {
|
|
45
79
|
modelName: string;
|
|
@@ -51,15 +85,54 @@ export interface CcusageSession {
|
|
|
51
85
|
}[];
|
|
52
86
|
projectPath: string;
|
|
53
87
|
}
|
|
54
|
-
|
|
55
|
-
|
|
88
|
+
/** Daily usage entry from ccusage */
|
|
89
|
+
export interface CcusageDailyUsage {
|
|
90
|
+
date: string;
|
|
91
|
+
inputTokens: number;
|
|
92
|
+
outputTokens: number;
|
|
93
|
+
cacheCreationTokens: number;
|
|
94
|
+
cacheReadTokens: number;
|
|
95
|
+
cost: number;
|
|
96
|
+
totalCost: number;
|
|
97
|
+
modelsUsed: string[];
|
|
98
|
+
modelBreakdowns: {
|
|
99
|
+
modelName: string;
|
|
100
|
+
inputTokens: number;
|
|
101
|
+
outputTokens: number;
|
|
102
|
+
cacheCreationTokens: number;
|
|
103
|
+
cacheReadTokens: number;
|
|
104
|
+
cost: number;
|
|
105
|
+
}[];
|
|
106
|
+
}
|
|
107
|
+
/** Weekly usage entry from ccusage */
|
|
108
|
+
export interface CcusageWeeklyUsage {
|
|
109
|
+
week: string;
|
|
110
|
+
inputTokens: number;
|
|
111
|
+
outputTokens: number;
|
|
112
|
+
cacheCreationTokens: number;
|
|
113
|
+
cacheReadTokens: number;
|
|
114
|
+
totalCost: number;
|
|
115
|
+
modelsUsed: string[];
|
|
116
|
+
modelBreakdowns: CcusageDailyUsage['modelBreakdowns'];
|
|
117
|
+
}
|
|
118
|
+
/** Monthly usage entry from ccusage */
|
|
119
|
+
export interface CcusageMonthlyUsage {
|
|
120
|
+
month: string;
|
|
121
|
+
inputTokens: number;
|
|
122
|
+
outputTokens: number;
|
|
123
|
+
cacheCreationTokens: number;
|
|
124
|
+
cacheReadTokens: number;
|
|
125
|
+
cost: number;
|
|
126
|
+
totalCost: number;
|
|
127
|
+
modelsUsed: string[];
|
|
128
|
+
modelBreakdowns: CcusageDailyUsage['modelBreakdowns'];
|
|
56
129
|
}
|
|
57
130
|
/**
|
|
58
|
-
* Get all sessions using ccusage
|
|
131
|
+
* Get all sessions using ccusage library
|
|
59
132
|
*/
|
|
60
133
|
export declare function getAllSessions(instanceId?: string): Promise<SessionUsage[]>;
|
|
61
134
|
/**
|
|
62
|
-
* Get specific session usage using ccusage
|
|
135
|
+
* Get specific session usage using ccusage library
|
|
63
136
|
*/
|
|
64
137
|
export declare function getSessionUsage(sessionId: string, instanceId?: string): Promise<SessionUsage | null>;
|
|
65
138
|
/**
|
|
@@ -70,3 +143,20 @@ export declare function getSessionName(sessionId: string): string;
|
|
|
70
143
|
* Get current session ID from active Claude Code process
|
|
71
144
|
*/
|
|
72
145
|
export declare function getCurrentSessionId(): string | null;
|
|
146
|
+
/**
|
|
147
|
+
* Load daily usage data via ccusage library
|
|
148
|
+
*/
|
|
149
|
+
export declare function getDailyUsage(): Promise<CcusageDailyUsage[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Load weekly usage data via ccusage library
|
|
152
|
+
*/
|
|
153
|
+
export declare function getWeeklyUsage(): Promise<CcusageWeeklyUsage[]>;
|
|
154
|
+
/**
|
|
155
|
+
* Load monthly usage data via ccusage library
|
|
156
|
+
*/
|
|
157
|
+
export declare function getMonthlyUsage(): Promise<CcusageMonthlyUsage[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Load bucket (5-hour block) usage data via ccusage library
|
|
160
|
+
*/
|
|
161
|
+
export declare function getBucketUsage(): Promise<any[]>;
|
|
162
|
+
export {};
|