burnwatch 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 +342 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1151 -0
- package/dist/cli.js.map +1 -0
- package/dist/hooks/on-file-change.d.ts +1 -0
- package/dist/hooks/on-file-change.js +226 -0
- package/dist/hooks/on-file-change.js.map +1 -0
- package/dist/hooks/on-prompt.d.ts +1 -0
- package/dist/hooks/on-prompt.js +211 -0
- package/dist/hooks/on-prompt.js.map +1 -0
- package/dist/hooks/on-session-start.d.ts +1 -0
- package/dist/hooks/on-session-start.js +766 -0
- package/dist/hooks/on-session-start.js.map +1 -0
- package/dist/hooks/on-stop.d.ts +1 -0
- package/dist/hooks/on-stop.js +561 -0
- package/dist/hooks/on-stop.js.map +1 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +573 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/registry.json +330 -0
- package/skills/setup-burnwatch/SKILL.md +95 -0
- package/skills/spend/SKILL.md +25 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence tiers for spend tracking.
|
|
3
|
+
*
|
|
4
|
+
* LIVE — Real billing API data
|
|
5
|
+
* CALC — Fixed monthly cost, user-entered
|
|
6
|
+
* EST — Estimated from usage signals + pricing formula
|
|
7
|
+
* BLIND — Detected in project, no tracking configured
|
|
8
|
+
*/
|
|
9
|
+
type ConfidenceTier = "live" | "calc" | "est" | "blind";
|
|
10
|
+
declare const CONFIDENCE_BADGES: Record<ConfidenceTier, string>;
|
|
11
|
+
/** How a service charges — determines tracking strategy. */
|
|
12
|
+
type BillingModel = "token_usage" | "credit_pool" | "per_unit" | "percentage" | "flat_monthly" | "tiered" | "compute" | "unknown";
|
|
13
|
+
/** How cost scales — helps the agent reason about future spend. */
|
|
14
|
+
type ScalingShape = "linear" | "linear_burndown" | "tiered_jump" | "percentage" | "fixed" | "unknown";
|
|
15
|
+
/** A service definition from the registry. */
|
|
16
|
+
interface ServiceDefinition {
|
|
17
|
+
/** Unique service identifier */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Human-readable name */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Package names in npm/pip that indicate this service */
|
|
22
|
+
packageNames: string[];
|
|
23
|
+
/** Env var patterns that indicate this service */
|
|
24
|
+
envPatterns: string[];
|
|
25
|
+
/** Import patterns to scan for (regex strings) */
|
|
26
|
+
importPatterns: string[];
|
|
27
|
+
/** Keywords that indicate mentions in prompts */
|
|
28
|
+
mentionKeywords: string[];
|
|
29
|
+
/** Billing model */
|
|
30
|
+
billingModel: BillingModel;
|
|
31
|
+
/** How cost scales */
|
|
32
|
+
scalingShape: ScalingShape;
|
|
33
|
+
/** What tier of tracking is available */
|
|
34
|
+
apiTier: ConfidenceTier;
|
|
35
|
+
/** Billing API endpoint, if available */
|
|
36
|
+
apiEndpoint?: string;
|
|
37
|
+
/** Pricing details */
|
|
38
|
+
pricing?: {
|
|
39
|
+
/** Human-readable formula */
|
|
40
|
+
formula?: string;
|
|
41
|
+
/** Rate per unit, if applicable */
|
|
42
|
+
unitRate?: number;
|
|
43
|
+
/** Unit name (token, credit, email, session, etc.) */
|
|
44
|
+
unitName?: string;
|
|
45
|
+
/** Monthly base cost, if flat */
|
|
46
|
+
monthlyBase?: number;
|
|
47
|
+
};
|
|
48
|
+
/** Known gotchas that affect cost */
|
|
49
|
+
gotchas?: string[];
|
|
50
|
+
/** Alternative services (free or cheaper) */
|
|
51
|
+
alternatives?: string[];
|
|
52
|
+
/** Documentation URL */
|
|
53
|
+
docsUrl?: string;
|
|
54
|
+
/** Last time pricing was verified */
|
|
55
|
+
lastVerified?: string;
|
|
56
|
+
/** Notes about recent pricing changes */
|
|
57
|
+
pricingNotes?: string;
|
|
58
|
+
}
|
|
59
|
+
/** A tracked service instance — a service definition + user config. */
|
|
60
|
+
interface TrackedService {
|
|
61
|
+
/** Service definition ID */
|
|
62
|
+
serviceId: string;
|
|
63
|
+
/** How this service was detected */
|
|
64
|
+
detectedVia: DetectionSource[];
|
|
65
|
+
/** User-configured monthly budget */
|
|
66
|
+
budget?: number;
|
|
67
|
+
/** Whether the user has provided an API/billing key */
|
|
68
|
+
hasApiKey: boolean;
|
|
69
|
+
/** Override confidence tier (e.g., user provided billing key upgrades to LIVE) */
|
|
70
|
+
tierOverride?: ConfidenceTier;
|
|
71
|
+
/** User-entered monthly plan cost (for CALC tier) */
|
|
72
|
+
planCost?: number;
|
|
73
|
+
/** When this service was first detected */
|
|
74
|
+
firstDetected: string;
|
|
75
|
+
}
|
|
76
|
+
type DetectionSource = "package_json" | "env_var" | "import_scan" | "prompt_mention" | "git_diff" | "manual";
|
|
77
|
+
/** A spend snapshot for a single service at a point in time. */
|
|
78
|
+
interface SpendSnapshot {
|
|
79
|
+
serviceId: string;
|
|
80
|
+
/** Current period spend (or estimate) */
|
|
81
|
+
spend: number;
|
|
82
|
+
/** Is the spend figure exact or estimated? */
|
|
83
|
+
isEstimate: boolean;
|
|
84
|
+
/** Confidence tier for this reading */
|
|
85
|
+
tier: ConfidenceTier;
|
|
86
|
+
/** Budget allocated */
|
|
87
|
+
budget?: number;
|
|
88
|
+
/** Percentage of budget consumed */
|
|
89
|
+
budgetPercent?: number;
|
|
90
|
+
/** Budget status */
|
|
91
|
+
status: "healthy" | "caution" | "over" | "unknown";
|
|
92
|
+
/** Human-readable status label */
|
|
93
|
+
statusLabel: string;
|
|
94
|
+
/** Raw data from billing API, if available */
|
|
95
|
+
raw?: Record<string, unknown>;
|
|
96
|
+
/** Timestamp of this snapshot */
|
|
97
|
+
timestamp: string;
|
|
98
|
+
}
|
|
99
|
+
/** The full spend brief, injected at session start. */
|
|
100
|
+
interface SpendBrief {
|
|
101
|
+
projectName: string;
|
|
102
|
+
generatedAt: string;
|
|
103
|
+
period: string;
|
|
104
|
+
services: SpendSnapshot[];
|
|
105
|
+
totalSpend: number;
|
|
106
|
+
totalIsEstimate: boolean;
|
|
107
|
+
estimateMargin: number;
|
|
108
|
+
untrackedCount: number;
|
|
109
|
+
alerts: SpendAlert[];
|
|
110
|
+
}
|
|
111
|
+
interface SpendAlert {
|
|
112
|
+
serviceId: string;
|
|
113
|
+
type: "over_budget" | "near_budget" | "new_service" | "stale_data" | "blind_service";
|
|
114
|
+
message: string;
|
|
115
|
+
severity: "warning" | "critical" | "info";
|
|
116
|
+
}
|
|
117
|
+
/** Ledger entry — one row in spend-ledger.md */
|
|
118
|
+
interface LedgerEntry {
|
|
119
|
+
serviceId: string;
|
|
120
|
+
serviceName: string;
|
|
121
|
+
spend: number;
|
|
122
|
+
isEstimate: boolean;
|
|
123
|
+
tier: ConfidenceTier;
|
|
124
|
+
budget?: number;
|
|
125
|
+
statusLabel: string;
|
|
126
|
+
}
|
|
127
|
+
/** Event logged to events.jsonl */
|
|
128
|
+
interface SpendEvent {
|
|
129
|
+
timestamp: string;
|
|
130
|
+
sessionId: string;
|
|
131
|
+
type: "session_start" | "session_end" | "service_detected" | "service_mentioned" | "spend_polled" | "budget_alert" | "ledger_written";
|
|
132
|
+
data: Record<string, unknown>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Load the service registry.
|
|
137
|
+
* Checks project-local override first, then falls back to bundled registry.
|
|
138
|
+
*/
|
|
139
|
+
declare function loadRegistry(projectRoot?: string): Map<string, ServiceDefinition>;
|
|
140
|
+
/** Get a single service definition by ID. */
|
|
141
|
+
declare function getService(id: string, projectRoot?: string): ServiceDefinition | undefined;
|
|
142
|
+
/** Get all service definitions. */
|
|
143
|
+
declare function getAllServices(projectRoot?: string): ServiceDefinition[];
|
|
144
|
+
|
|
145
|
+
interface DetectionResult {
|
|
146
|
+
service: ServiceDefinition;
|
|
147
|
+
sources: DetectionSource[];
|
|
148
|
+
details: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Run all detection surfaces against the current project.
|
|
152
|
+
* Returns services detected via any combination of:
|
|
153
|
+
* - package.json dependencies
|
|
154
|
+
* - environment variable patterns
|
|
155
|
+
* - import statement scanning
|
|
156
|
+
* - (prompt mention scanning is handled separately in hooks)
|
|
157
|
+
*/
|
|
158
|
+
declare function detectServices(projectRoot: string): DetectionResult[];
|
|
159
|
+
/**
|
|
160
|
+
* Detect services mentioned in a prompt string.
|
|
161
|
+
* Used by the UserPromptSubmit hook.
|
|
162
|
+
*/
|
|
163
|
+
declare function detectMentions(prompt: string, projectRoot?: string): DetectionResult[];
|
|
164
|
+
/**
|
|
165
|
+
* Detect new services introduced in a file change.
|
|
166
|
+
* Used by the PostToolUse hook for Write/Edit events.
|
|
167
|
+
*/
|
|
168
|
+
declare function detectInFileChange(filePath: string, content: string, projectRoot?: string): DetectionResult[];
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Format a spend brief as a text block for injection into Claude's context.
|
|
172
|
+
*/
|
|
173
|
+
declare function formatBrief(brief: SpendBrief): string;
|
|
174
|
+
/**
|
|
175
|
+
* Format a single-service spend card for injection on mention.
|
|
176
|
+
*/
|
|
177
|
+
declare function formatSpendCard(snapshot: SpendSnapshot): string;
|
|
178
|
+
/**
|
|
179
|
+
* Build a SpendBrief from snapshots and project config.
|
|
180
|
+
*/
|
|
181
|
+
declare function buildBrief(projectName: string, snapshots: SpendSnapshot[], blindCount: number): SpendBrief;
|
|
182
|
+
/**
|
|
183
|
+
* Build a SpendSnapshot from tracked service data.
|
|
184
|
+
*/
|
|
185
|
+
declare function buildSnapshot(serviceId: string, tier: ConfidenceTier, spend: number, budget?: number): SpendSnapshot;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Write the spend ledger as a human-readable markdown file.
|
|
189
|
+
* Designed to be git-committable and readable in 10 seconds.
|
|
190
|
+
*/
|
|
191
|
+
declare function writeLedger(brief: SpendBrief, projectRoot?: string): void;
|
|
192
|
+
/**
|
|
193
|
+
* Append an event to the append-only event log.
|
|
194
|
+
*/
|
|
195
|
+
declare function logEvent(event: SpendEvent, projectRoot?: string): void;
|
|
196
|
+
/**
|
|
197
|
+
* Read recent events from the event log.
|
|
198
|
+
*/
|
|
199
|
+
declare function readRecentEvents(count: number, projectRoot?: string): SpendEvent[];
|
|
200
|
+
/**
|
|
201
|
+
* Save a spend snapshot to the snapshots directory.
|
|
202
|
+
* Used for delta computation across sessions.
|
|
203
|
+
*/
|
|
204
|
+
declare function saveSnapshot(brief: SpendBrief, projectRoot?: string): void;
|
|
205
|
+
/**
|
|
206
|
+
* Read the most recent snapshot, if any.
|
|
207
|
+
*/
|
|
208
|
+
declare function readLatestSnapshot(projectRoot?: string): SpendBrief | null;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Paths for burnwatch configuration and data.
|
|
212
|
+
*
|
|
213
|
+
* Hybrid model:
|
|
214
|
+
* - Global config (API keys, service credentials): ~/.config/burnwatch/
|
|
215
|
+
* - Project config (budgets, tracked services): .burnwatch/
|
|
216
|
+
* - Project data (ledger, events, cache): .burnwatch/data/
|
|
217
|
+
*/
|
|
218
|
+
/** Global config directory — stores API keys, never in project dirs. */
|
|
219
|
+
declare function globalConfigDir(): string;
|
|
220
|
+
/** Project config directory — stores budgets, tracked services. */
|
|
221
|
+
declare function projectConfigDir(projectRoot?: string): string;
|
|
222
|
+
/** Project data directory — stores ledger, events, cache. */
|
|
223
|
+
declare function projectDataDir(projectRoot?: string): string;
|
|
224
|
+
interface GlobalConfig {
|
|
225
|
+
services: Record<string, {
|
|
226
|
+
apiKey?: string;
|
|
227
|
+
token?: string;
|
|
228
|
+
orgId?: string;
|
|
229
|
+
}>;
|
|
230
|
+
}
|
|
231
|
+
declare function readGlobalConfig(): GlobalConfig;
|
|
232
|
+
declare function writeGlobalConfig(config: GlobalConfig): void;
|
|
233
|
+
interface ProjectConfig {
|
|
234
|
+
projectName: string;
|
|
235
|
+
services: Record<string, TrackedService>;
|
|
236
|
+
createdAt: string;
|
|
237
|
+
updatedAt: string;
|
|
238
|
+
}
|
|
239
|
+
declare function readProjectConfig(projectRoot?: string): ProjectConfig | null;
|
|
240
|
+
declare function writeProjectConfig(config: ProjectConfig, projectRoot?: string): void;
|
|
241
|
+
/** Ensure all project directories exist. */
|
|
242
|
+
declare function ensureProjectDirs(projectRoot?: string): void;
|
|
243
|
+
/** Check if burnwatch is initialized in the given project. */
|
|
244
|
+
declare function isInitialized(projectRoot?: string): boolean;
|
|
245
|
+
|
|
246
|
+
export { type BillingModel, CONFIDENCE_BADGES, type ConfidenceTier, type DetectionSource, type LedgerEntry, type ScalingShape, type ServiceDefinition, type SpendAlert, type SpendBrief, type SpendEvent, type SpendSnapshot, type TrackedService, buildBrief, buildSnapshot, detectInFileChange, detectMentions, detectServices, ensureProjectDirs, formatBrief, formatSpendCard, getAllServices, getService, globalConfigDir, isInitialized, loadRegistry, logEvent, projectConfigDir, projectDataDir, readGlobalConfig, readLatestSnapshot, readProjectConfig, readRecentEvents, saveSnapshot, writeGlobalConfig, writeLedger, writeProjectConfig };
|