@semboja/opencode-claude 0.1.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/LICENSE +21 -0
- package/README.md +552 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +182 -0
- package/dist/index.js.map +1 -0
- package/dist/processor.d.ts +38 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +244 -0
- package/dist/processor.js.map +1 -0
- package/dist/prometheus.d.ts +65 -0
- package/dist/prometheus.d.ts.map +1 -0
- package/dist/prometheus.js +304 -0
- package/dist/prometheus.js.map +1 -0
- package/dist/storage.d.ts +31 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +197 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StorageBackend, SessionUsage, ApiRequestMetrics, UsageStats } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* File-based storage backend for Claude usage tracking
|
|
4
|
+
*/
|
|
5
|
+
export declare class FileStorage implements StorageBackend {
|
|
6
|
+
private basePath;
|
|
7
|
+
private sessionsDir;
|
|
8
|
+
private requestsDir;
|
|
9
|
+
constructor(storagePath?: string);
|
|
10
|
+
private ensureDirectories;
|
|
11
|
+
private sessionFilePath;
|
|
12
|
+
private requestFilePath;
|
|
13
|
+
saveSession(session: SessionUsage): Promise<void>;
|
|
14
|
+
saveApiRequest(sessionId: string, request: ApiRequestMetrics): Promise<void>;
|
|
15
|
+
getSession(sessionId: string): Promise<SessionUsage | null>;
|
|
16
|
+
getAllSessions(limit?: number): Promise<SessionUsage[]>;
|
|
17
|
+
getUsageStats(startDate?: string, endDate?: string): Promise<UsageStats>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* In-memory storage backend (useful for testing or ephemeral tracking)
|
|
21
|
+
*/
|
|
22
|
+
export declare class MemoryStorage implements StorageBackend {
|
|
23
|
+
private sessions;
|
|
24
|
+
private requests;
|
|
25
|
+
saveSession(session: SessionUsage): Promise<void>;
|
|
26
|
+
saveApiRequest(sessionId: string, request: ApiRequestMetrics): Promise<void>;
|
|
27
|
+
getSession(sessionId: string): Promise<SessionUsage | null>;
|
|
28
|
+
getAllSessions(limit?: number): Promise<SessionUsage[]>;
|
|
29
|
+
getUsageStats(): Promise<UsageStats>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,UAAU,EAGX,MAAM,YAAY,CAAC;AAsBpB;;GAEG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,CAAC,EAAE,MAAM;IAOhC,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;IAIjB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAa3D,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAyBpD,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CA+E/E;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAA0C;IAEpD,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAI3D,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIpD,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;CAY3C"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
/**
|
|
5
|
+
* Creates an empty token usage object
|
|
6
|
+
*/
|
|
7
|
+
function emptyTokenUsage() {
|
|
8
|
+
return { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, total: 0 };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Adds two token usage objects together
|
|
12
|
+
*/
|
|
13
|
+
function addTokenUsage(a, b) {
|
|
14
|
+
return {
|
|
15
|
+
input: a.input + b.input,
|
|
16
|
+
output: a.output + b.output,
|
|
17
|
+
cacheRead: a.cacheRead + b.cacheRead,
|
|
18
|
+
cacheCreation: a.cacheCreation + b.cacheCreation,
|
|
19
|
+
total: a.total + b.total,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* File-based storage backend for Claude usage tracking
|
|
24
|
+
*/
|
|
25
|
+
export class FileStorage {
|
|
26
|
+
basePath;
|
|
27
|
+
sessionsDir;
|
|
28
|
+
requestsDir;
|
|
29
|
+
constructor(storagePath) {
|
|
30
|
+
this.basePath = storagePath ?? path.join(os.homedir(), '.opencode', 'claude-usage');
|
|
31
|
+
this.sessionsDir = path.join(this.basePath, 'sessions');
|
|
32
|
+
this.requestsDir = path.join(this.basePath, 'requests');
|
|
33
|
+
this.ensureDirectories();
|
|
34
|
+
}
|
|
35
|
+
ensureDirectories() {
|
|
36
|
+
fs.mkdirSync(this.sessionsDir, { recursive: true });
|
|
37
|
+
fs.mkdirSync(this.requestsDir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
sessionFilePath(sessionId) {
|
|
40
|
+
return path.join(this.sessionsDir, `${sessionId}.json`);
|
|
41
|
+
}
|
|
42
|
+
requestFilePath(sessionId) {
|
|
43
|
+
return path.join(this.requestsDir, `${sessionId}.jsonl`);
|
|
44
|
+
}
|
|
45
|
+
async saveSession(session) {
|
|
46
|
+
const serializable = {
|
|
47
|
+
...session,
|
|
48
|
+
toolCalls: Object.fromEntries(session.toolCalls),
|
|
49
|
+
models: Object.fromEntries(session.models),
|
|
50
|
+
};
|
|
51
|
+
fs.writeFileSync(this.sessionFilePath(session.sessionId), JSON.stringify(serializable, null, 2));
|
|
52
|
+
}
|
|
53
|
+
async saveApiRequest(sessionId, request) {
|
|
54
|
+
const line = JSON.stringify(request) + '\n';
|
|
55
|
+
fs.appendFileSync(this.requestFilePath(sessionId), line);
|
|
56
|
+
}
|
|
57
|
+
async getSession(sessionId) {
|
|
58
|
+
const filePath = this.sessionFilePath(sessionId);
|
|
59
|
+
if (!fs.existsSync(filePath)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
63
|
+
return {
|
|
64
|
+
...data,
|
|
65
|
+
toolCalls: new Map(Object.entries(data.toolCalls || {})),
|
|
66
|
+
models: new Map(Object.entries(data.models || {})),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async getAllSessions(limit = 100) {
|
|
70
|
+
if (!fs.existsSync(this.sessionsDir)) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const files = fs.readdirSync(this.sessionsDir)
|
|
74
|
+
.filter(f => f.endsWith('.json'))
|
|
75
|
+
.sort((a, b) => {
|
|
76
|
+
const statA = fs.statSync(path.join(this.sessionsDir, a));
|
|
77
|
+
const statB = fs.statSync(path.join(this.sessionsDir, b));
|
|
78
|
+
return statB.mtime.getTime() - statA.mtime.getTime();
|
|
79
|
+
})
|
|
80
|
+
.slice(0, limit);
|
|
81
|
+
const sessions = [];
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const sessionId = file.replace('.json', '');
|
|
84
|
+
const session = await this.getSession(sessionId);
|
|
85
|
+
if (session) {
|
|
86
|
+
sessions.push(session);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return sessions;
|
|
90
|
+
}
|
|
91
|
+
async getUsageStats(startDate, endDate) {
|
|
92
|
+
const sessions = await this.getAllSessions(1000);
|
|
93
|
+
const stats = {
|
|
94
|
+
totalSessions: 0,
|
|
95
|
+
totalApiRequests: 0,
|
|
96
|
+
totalTokens: emptyTokenUsage(),
|
|
97
|
+
totalCostUsd: 0,
|
|
98
|
+
byModel: new Map(),
|
|
99
|
+
byDay: new Map(),
|
|
100
|
+
topTools: [],
|
|
101
|
+
};
|
|
102
|
+
const toolMap = new Map();
|
|
103
|
+
for (const session of sessions) {
|
|
104
|
+
// Filter by date if provided
|
|
105
|
+
if (startDate && session.startTime < startDate)
|
|
106
|
+
continue;
|
|
107
|
+
if (endDate && session.endTime && session.endTime > endDate)
|
|
108
|
+
continue;
|
|
109
|
+
stats.totalSessions++;
|
|
110
|
+
stats.totalApiRequests += session.apiRequests;
|
|
111
|
+
stats.totalTokens = addTokenUsage(stats.totalTokens, session.tokens);
|
|
112
|
+
stats.totalCostUsd += session.totalCostUsd;
|
|
113
|
+
// Aggregate by model
|
|
114
|
+
for (const [model, modelData] of session.models) {
|
|
115
|
+
const existing = stats.byModel.get(model) ?? {
|
|
116
|
+
requests: 0,
|
|
117
|
+
tokens: emptyTokenUsage(),
|
|
118
|
+
costUsd: 0,
|
|
119
|
+
};
|
|
120
|
+
existing.requests += modelData.requests;
|
|
121
|
+
existing.tokens = addTokenUsage(existing.tokens, modelData.tokens);
|
|
122
|
+
existing.costUsd += modelData.costUsd;
|
|
123
|
+
stats.byModel.set(model, existing);
|
|
124
|
+
}
|
|
125
|
+
// Aggregate by day
|
|
126
|
+
const day = session.startTime.split('T')[0];
|
|
127
|
+
const dayData = stats.byDay.get(day) ?? {
|
|
128
|
+
requests: 0,
|
|
129
|
+
tokens: emptyTokenUsage(),
|
|
130
|
+
costUsd: 0,
|
|
131
|
+
};
|
|
132
|
+
dayData.requests += session.apiRequests;
|
|
133
|
+
dayData.tokens = addTokenUsage(dayData.tokens, session.tokens);
|
|
134
|
+
dayData.costUsd += session.totalCostUsd;
|
|
135
|
+
stats.byDay.set(day, dayData);
|
|
136
|
+
// Aggregate tools
|
|
137
|
+
for (const [toolName, toolData] of session.toolCalls) {
|
|
138
|
+
const existing = toolMap.get(toolName) ?? {
|
|
139
|
+
name: toolName,
|
|
140
|
+
invocations: 0,
|
|
141
|
+
successCount: 0,
|
|
142
|
+
failureCount: 0,
|
|
143
|
+
totalDurationMs: 0,
|
|
144
|
+
avgDurationMs: 0,
|
|
145
|
+
};
|
|
146
|
+
existing.invocations += toolData.invocations;
|
|
147
|
+
existing.successCount += toolData.successCount;
|
|
148
|
+
existing.failureCount += toolData.failureCount;
|
|
149
|
+
existing.totalDurationMs += toolData.totalDurationMs;
|
|
150
|
+
toolMap.set(toolName, existing);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Calculate averages and sort tools
|
|
154
|
+
stats.topTools = Array.from(toolMap.values())
|
|
155
|
+
.map(t => ({
|
|
156
|
+
...t,
|
|
157
|
+
avgDurationMs: t.invocations > 0 ? t.totalDurationMs / t.invocations : 0,
|
|
158
|
+
}))
|
|
159
|
+
.sort((a, b) => b.invocations - a.invocations)
|
|
160
|
+
.slice(0, 10);
|
|
161
|
+
return stats;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* In-memory storage backend (useful for testing or ephemeral tracking)
|
|
166
|
+
*/
|
|
167
|
+
export class MemoryStorage {
|
|
168
|
+
sessions = new Map();
|
|
169
|
+
requests = new Map();
|
|
170
|
+
async saveSession(session) {
|
|
171
|
+
this.sessions.set(session.sessionId, session);
|
|
172
|
+
}
|
|
173
|
+
async saveApiRequest(sessionId, request) {
|
|
174
|
+
const existing = this.requests.get(sessionId) ?? [];
|
|
175
|
+
existing.push(request);
|
|
176
|
+
this.requests.set(sessionId, existing);
|
|
177
|
+
}
|
|
178
|
+
async getSession(sessionId) {
|
|
179
|
+
return this.sessions.get(sessionId) ?? null;
|
|
180
|
+
}
|
|
181
|
+
async getAllSessions(limit = 100) {
|
|
182
|
+
return Array.from(this.sessions.values()).slice(0, limit);
|
|
183
|
+
}
|
|
184
|
+
async getUsageStats() {
|
|
185
|
+
// Simplified implementation - same logic as FileStorage
|
|
186
|
+
return {
|
|
187
|
+
totalSessions: this.sessions.size,
|
|
188
|
+
totalApiRequests: 0,
|
|
189
|
+
totalTokens: emptyTokenUsage(),
|
|
190
|
+
totalCostUsd: 0,
|
|
191
|
+
byModel: new Map(),
|
|
192
|
+
byDay: new Map(),
|
|
193
|
+
topTools: [],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token usage breakdown by type
|
|
3
|
+
*/
|
|
4
|
+
export interface TokenUsage {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
cacheRead: number;
|
|
8
|
+
cacheCreation: number;
|
|
9
|
+
total: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* API request metrics
|
|
13
|
+
*/
|
|
14
|
+
export interface ApiRequestMetrics {
|
|
15
|
+
timestamp: string;
|
|
16
|
+
model: string;
|
|
17
|
+
durationMs: number;
|
|
18
|
+
tokens: TokenUsage;
|
|
19
|
+
costUsd: number;
|
|
20
|
+
success: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Tool usage metrics
|
|
25
|
+
*/
|
|
26
|
+
export interface ToolMetrics {
|
|
27
|
+
name: string;
|
|
28
|
+
invocations: number;
|
|
29
|
+
successCount: number;
|
|
30
|
+
failureCount: number;
|
|
31
|
+
totalDurationMs: number;
|
|
32
|
+
avgDurationMs: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Session-level usage summary
|
|
36
|
+
*/
|
|
37
|
+
export interface SessionUsage {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
startTime: string;
|
|
40
|
+
endTime?: string;
|
|
41
|
+
tokens: TokenUsage;
|
|
42
|
+
totalCostUsd: number;
|
|
43
|
+
apiRequests: number;
|
|
44
|
+
toolCalls: Map<string, ToolMetrics>;
|
|
45
|
+
models: Map<string, {
|
|
46
|
+
requests: number;
|
|
47
|
+
tokens: TokenUsage;
|
|
48
|
+
costUsd: number;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Aggregated usage statistics
|
|
53
|
+
*/
|
|
54
|
+
export interface UsageStats {
|
|
55
|
+
totalSessions: number;
|
|
56
|
+
totalApiRequests: number;
|
|
57
|
+
totalTokens: TokenUsage;
|
|
58
|
+
totalCostUsd: number;
|
|
59
|
+
byModel: Map<string, {
|
|
60
|
+
requests: number;
|
|
61
|
+
tokens: TokenUsage;
|
|
62
|
+
costUsd: number;
|
|
63
|
+
}>;
|
|
64
|
+
byDay: Map<string, {
|
|
65
|
+
requests: number;
|
|
66
|
+
tokens: TokenUsage;
|
|
67
|
+
costUsd: number;
|
|
68
|
+
}>;
|
|
69
|
+
topTools: ToolMetrics[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Storage backend interface
|
|
73
|
+
*/
|
|
74
|
+
export interface StorageBackend {
|
|
75
|
+
saveSession(session: SessionUsage): Promise<void>;
|
|
76
|
+
saveApiRequest(sessionId: string, request: ApiRequestMetrics): Promise<void>;
|
|
77
|
+
getSession(sessionId: string): Promise<SessionUsage | null>;
|
|
78
|
+
getAllSessions(limit?: number): Promise<SessionUsage[]>;
|
|
79
|
+
getUsageStats(startDate?: string, endDate?: string): Promise<UsageStats>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Plugin configuration options
|
|
83
|
+
*/
|
|
84
|
+
export interface ClaudeTrackerConfig {
|
|
85
|
+
/** Storage backend type: 'file' | 'sqlite' | 'custom' */
|
|
86
|
+
storage: 'file' | 'sqlite' | 'custom';
|
|
87
|
+
/** Path for file/sqlite storage (default: ~/.opencode/claude-usage) */
|
|
88
|
+
storagePath?: string;
|
|
89
|
+
/** Custom storage backend implementation */
|
|
90
|
+
customStorage?: StorageBackend;
|
|
91
|
+
/** Enable detailed logging */
|
|
92
|
+
verbose?: boolean;
|
|
93
|
+
/** Flush interval in ms (default: 30000) */
|
|
94
|
+
flushIntervalMs?: number;
|
|
95
|
+
/** Include model names in tracking */
|
|
96
|
+
trackModels?: boolean;
|
|
97
|
+
/** Include tool usage in tracking */
|
|
98
|
+
trackTools?: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Span attribute names used by Claude/OpenCode
|
|
102
|
+
*/
|
|
103
|
+
export declare const SpanAttributes: {
|
|
104
|
+
readonly MODEL: "model";
|
|
105
|
+
readonly COST_USD: "cost_usd";
|
|
106
|
+
readonly DURATION_MS: "duration_ms";
|
|
107
|
+
readonly INPUT_TOKENS: "input_tokens";
|
|
108
|
+
readonly OUTPUT_TOKENS: "output_tokens";
|
|
109
|
+
readonly CACHE_READ_TOKENS: "cache_read_tokens";
|
|
110
|
+
readonly CACHE_CREATION_TOKENS: "cache_creation_tokens";
|
|
111
|
+
readonly TOOL_NAME: "tool_name";
|
|
112
|
+
readonly SUCCESS: "success";
|
|
113
|
+
readonly ERROR: "error";
|
|
114
|
+
readonly SESSION_ID: "session.id";
|
|
115
|
+
readonly EVENT_NAME: "event.name";
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Event names emitted by Claude Code
|
|
119
|
+
*/
|
|
120
|
+
export declare const EventNames: {
|
|
121
|
+
readonly API_REQUEST: "claude_code.api_request";
|
|
122
|
+
readonly API_ERROR: "claude_code.api_error";
|
|
123
|
+
readonly TOOL_RESULT: "claude_code.tool_result";
|
|
124
|
+
readonly TOOL_DECISION: "claude_code.tool_decision";
|
|
125
|
+
readonly USER_PROMPT: "claude_code.user_prompt";
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Span attribute names used by Claude/OpenCode
|
|
3
|
+
*/
|
|
4
|
+
export const SpanAttributes = {
|
|
5
|
+
MODEL: 'model',
|
|
6
|
+
COST_USD: 'cost_usd',
|
|
7
|
+
DURATION_MS: 'duration_ms',
|
|
8
|
+
INPUT_TOKENS: 'input_tokens',
|
|
9
|
+
OUTPUT_TOKENS: 'output_tokens',
|
|
10
|
+
CACHE_READ_TOKENS: 'cache_read_tokens',
|
|
11
|
+
CACHE_CREATION_TOKENS: 'cache_creation_tokens',
|
|
12
|
+
TOOL_NAME: 'tool_name',
|
|
13
|
+
SUCCESS: 'success',
|
|
14
|
+
ERROR: 'error',
|
|
15
|
+
SESSION_ID: 'session.id',
|
|
16
|
+
EVENT_NAME: 'event.name',
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Event names emitted by Claude Code
|
|
20
|
+
*/
|
|
21
|
+
export const EventNames = {
|
|
22
|
+
API_REQUEST: 'claude_code.api_request',
|
|
23
|
+
API_ERROR: 'claude_code.api_error',
|
|
24
|
+
TOOL_RESULT: 'claude_code.tool_result',
|
|
25
|
+
TOOL_DECISION: 'claude_code.tool_decision',
|
|
26
|
+
USER_PROMPT: 'claude_code.user_prompt',
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA8FA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,qBAAqB,EAAE,uBAAuB;IAC9C,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;CAChB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,WAAW,EAAE,yBAAyB;IACtC,SAAS,EAAE,uBAAuB;IAClC,WAAW,EAAE,yBAAyB;IACtC,aAAa,EAAE,2BAA2B;IAC1C,WAAW,EAAE,yBAAyB;CAC9B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@semboja/opencode-claude",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Claude usage tracking plugin for OpenCode - monitor tokens, costs, sessions, and API performance",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"claude-tracker": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"dev": "tsc --watch",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"opencode",
|
|
30
|
+
"plugin",
|
|
31
|
+
"claude",
|
|
32
|
+
"anthropic",
|
|
33
|
+
"llm",
|
|
34
|
+
"monitoring",
|
|
35
|
+
"usage",
|
|
36
|
+
"tokens",
|
|
37
|
+
"cost",
|
|
38
|
+
"observability",
|
|
39
|
+
"opentelemetry"
|
|
40
|
+
],
|
|
41
|
+
"author": "",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@opencode-ai/plugin": "^1.1.14",
|
|
45
|
+
"@opentelemetry/api": "^1.9.0",
|
|
46
|
+
"@opentelemetry/sdk-node": "^0.203.0",
|
|
47
|
+
"@opentelemetry/sdk-trace-base": "^2.0.1"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"typescript": "^5.9.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.0.0"
|
|
55
|
+
},
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": ""
|
|
59
|
+
}
|
|
60
|
+
}
|