meter-ai 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/README.md +124 -0
- package/dist/auth/credentials.d.ts +9 -0
- package/dist/auth/credentials.d.ts.map +1 -0
- package/dist/auth/credentials.js +32 -0
- package/dist/auth/credentials.js.map +1 -0
- package/dist/auth/detect.d.ts +7 -0
- package/dist/auth/detect.d.ts.map +1 -0
- package/dist/auth/detect.js +20 -0
- package/dist/auth/detect.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +26 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/history.d.ts +2 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +19 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +58 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/report.d.ts +2 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +37 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +20 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +20 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/wrap.d.ts +2 -0
- package/dist/commands/wrap.d.ts.map +1 -0
- package/dist/commands/wrap.js +189 -0
- package/dist/commands/wrap.js.map +1 -0
- package/dist/constants.d.ts +30 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +48 -0
- package/dist/constants.js.map +1 -0
- package/dist/estimation/heuristics.d.ts +8 -0
- package/dist/estimation/heuristics.d.ts.map +1 -0
- package/dist/estimation/heuristics.js +28 -0
- package/dist/estimation/heuristics.js.map +1 -0
- package/dist/estimation/history-matcher.d.ts +4 -0
- package/dist/estimation/history-matcher.d.ts.map +1 -0
- package/dist/estimation/history-matcher.js +27 -0
- package/dist/estimation/history-matcher.js.map +1 -0
- package/dist/estimation/llm-precheck.d.ts +3 -0
- package/dist/estimation/llm-precheck.d.ts.map +1 -0
- package/dist/estimation/llm-precheck.js +21 -0
- package/dist/estimation/llm-precheck.js.map +1 -0
- package/dist/estimation/pipeline.d.ts +16 -0
- package/dist/estimation/pipeline.d.ts.map +1 -0
- package/dist/estimation/pipeline.js +48 -0
- package/dist/estimation/pipeline.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/pty/resize.d.ts +7 -0
- package/dist/pty/resize.d.ts.map +1 -0
- package/dist/pty/resize.js +10 -0
- package/dist/pty/resize.js.map +1 -0
- package/dist/pty/screen.d.ts +6 -0
- package/dist/pty/screen.d.ts.map +1 -0
- package/dist/pty/screen.js +15 -0
- package/dist/pty/screen.js.map +1 -0
- package/dist/pty/wrapper.d.ts +15 -0
- package/dist/pty/wrapper.d.ts.map +1 -0
- package/dist/pty/wrapper.js +49 -0
- package/dist/pty/wrapper.js.map +1 -0
- package/dist/shell/binary-resolver.d.ts +2 -0
- package/dist/shell/binary-resolver.d.ts.map +1 -0
- package/dist/shell/binary-resolver.js +18 -0
- package/dist/shell/binary-resolver.js.map +1 -0
- package/dist/shell/detect.d.ts +5 -0
- package/dist/shell/detect.d.ts.map +1 -0
- package/dist/shell/detect.js +32 -0
- package/dist/shell/detect.js.map +1 -0
- package/dist/shell/path-inject.d.ts +5 -0
- package/dist/shell/path-inject.d.ts.map +1 -0
- package/dist/shell/path-inject.js +30 -0
- package/dist/shell/path-inject.js.map +1 -0
- package/dist/shell/shim-writer.d.ts +3 -0
- package/dist/shell/shim-writer.d.ts.map +1 -0
- package/dist/shell/shim-writer.js +22 -0
- package/dist/shell/shim-writer.js.map +1 -0
- package/dist/storage/config-store.d.ts +10 -0
- package/dist/storage/config-store.d.ts.map +1 -0
- package/dist/storage/config-store.js +42 -0
- package/dist/storage/config-store.js.map +1 -0
- package/dist/storage/db.d.ts +7 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +53 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/tracking/cost.d.ts +6 -0
- package/dist/tracking/cost.d.ts.map +1 -0
- package/dist/tracking/cost.js +6 -0
- package/dist/tracking/cost.js.map +1 -0
- package/dist/tracking/plan-usage.d.ts +6 -0
- package/dist/tracking/plan-usage.d.ts.map +1 -0
- package/dist/tracking/plan-usage.js +53 -0
- package/dist/tracking/plan-usage.js.map +1 -0
- package/dist/tracking/tokens.d.ts +7 -0
- package/dist/tracking/tokens.d.ts.map +1 -0
- package/dist/tracking/tokens.js +14 -0
- package/dist/tracking/tokens.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/keypress.d.ts +3 -0
- package/dist/ui/keypress.d.ts.map +1 -0
- package/dist/ui/keypress.js +20 -0
- package/dist/ui/keypress.js.map +1 -0
- package/dist/ui/notification.d.ts +11 -0
- package/dist/ui/notification.d.ts.map +1 -0
- package/dist/ui/notification.js +18 -0
- package/dist/ui/notification.js.map +1 -0
- package/dist/ui/statusbar.d.ts +15 -0
- package/dist/ui/statusbar.d.ts.map +1 -0
- package/dist/ui/statusbar.js +53 -0
- package/dist/ui/statusbar.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# meter
|
|
2
|
+
|
|
3
|
+
**Intelligent CLI wrapper for Claude Code** — pre-task cost estimation, live status bar, budget protection.
|
|
4
|
+
|
|
5
|
+
meter sits transparently between you and Claude Code via PATH shimming. You keep typing `claude` exactly as before. meter adds:
|
|
6
|
+
|
|
7
|
+
- **Pre-task estimation** — know what a task will cost before it runs
|
|
8
|
+
- **Live status bar** — ambient cost/usage ticker while the agent works
|
|
9
|
+
- **Budget protection** — non-blocking notification when thresholds are hit, with one-keypress model switching
|
|
10
|
+
- **Works for both API users and plan subscribers**
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
$ claude "refactor the auth layer"
|
|
14
|
+
◆ meter claude-opus ~$0.38 heavy ████████████░░░░ 68% 5hr window | $0.12 elapsed
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g meter-ai
|
|
21
|
+
meter init
|
|
22
|
+
# restart your terminal
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
That's it. `meter init` detects your shell, finds the real `claude` binary, sets up a transparent shim, and writes your config. From now on, every `claude` invocation runs through meter automatically.
|
|
26
|
+
|
|
27
|
+
## How It Works
|
|
28
|
+
|
|
29
|
+
meter uses a PTY (pseudo-terminal) wrapper — the same mechanism used by VS Code's integrated terminal, tmux, and asciinema. Claude Code runs inside a PTY slave and believes it owns a real terminal. meter is the PTY master: it passes all I/O through unchanged while injecting a status bar at the bottom of your terminal.
|
|
30
|
+
|
|
31
|
+
### For API users (paying per token)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
◆ meter claude-opus ~$0.38 heavy │ ████████████░░░░ $0.21 / $0.50
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
meter tracks actual dollar cost in real time. When your per-task budget threshold is hit, you get a non-blocking notification:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
⚠ 80% budget hit ($0.40/$0.50) [s]witch to sonnet [d]ismiss [c]ancel
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### For plan users (Claude Max, Pro)
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
◆ meter claude-opus ~$0.38 heavy │ ████████████░░░░ 68% 5hr window reset in 2h 14m
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
meter polls your 5-hour usage window percentage and warns before you hit the rate limit wall mid-task.
|
|
50
|
+
|
|
51
|
+
## Pre-Task Estimation
|
|
52
|
+
|
|
53
|
+
meter estimates task cost/weight using a three-layer pipeline:
|
|
54
|
+
|
|
55
|
+
1. **Heuristics** (~50ms, free) — keyword scoring + repo size analysis
|
|
56
|
+
2. **Historical baseline** (~10ms, free) — trigram similarity against your past tasks
|
|
57
|
+
3. **LLM pre-call** (~1-2s, ~$0.0001) — only fires on ambiguous tasks
|
|
58
|
+
|
|
59
|
+
Simple tasks never hit layer 3. The estimate shows instantly and the agent starts immediately — no confirmation gate, no pause.
|
|
60
|
+
|
|
61
|
+
## Commands
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
meter init # Set up PATH shim and config
|
|
65
|
+
meter status # Show current mode, model, usage, and config
|
|
66
|
+
meter report # Weekly digest of usage and costs
|
|
67
|
+
meter history # Browse past task records
|
|
68
|
+
meter config # View and set budgets, thresholds, model chain
|
|
69
|
+
meter uninstall # Clean removal of all shims and data
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Configuration
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
meter config set budget 1.00 # Set per-task budget to $1.00
|
|
76
|
+
meter config set threshold 90 # Notify at 90% instead of 80%
|
|
77
|
+
meter config # View current config as JSON
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Model Switching
|
|
81
|
+
|
|
82
|
+
When a budget threshold is hit, press `s` to switch to a cheaper model:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
claude-opus-4 → claude-sonnet-4 → claude-haiku-4
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
meter warns you that conversation context will reset, and gives you 5 seconds to cancel before proceeding.
|
|
89
|
+
|
|
90
|
+
## Data Storage
|
|
91
|
+
|
|
92
|
+
All data stays local. No telemetry, no cloud, no accounts.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
~/.meter/
|
|
96
|
+
config.json # Mode, budgets, thresholds, resolved binary path
|
|
97
|
+
history.db # SQLite: task history, costs, estimates
|
|
98
|
+
pricing.json # Model pricing table (updated weekly)
|
|
99
|
+
bin/claude # PATH shim
|
|
100
|
+
cache/ # Usage data, session state
|
|
101
|
+
reports/ # Weekly digest snapshots
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Uninstall
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
meter uninstall # Removes shim and PATH entry
|
|
108
|
+
npm uninstall -g meter-ai
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Roadmap
|
|
112
|
+
|
|
113
|
+
- **v1.1** — Aider support
|
|
114
|
+
- **v1.2** — Gemini CLI support
|
|
115
|
+
- **v1.3** — Codex CLI support
|
|
116
|
+
- **v2.0** — CSV/JSON export, `--dry-run` estimation, team usage sharing
|
|
117
|
+
|
|
118
|
+
## Support
|
|
119
|
+
|
|
120
|
+
If meter saved you from a surprise bill or a rate limit wall, consider [buying me a coffee](https://buymeacoffee.com/catancs).
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ClaudeCredentials {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
refreshToken?: string;
|
|
4
|
+
expiresAt?: number;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export declare function readCredentials(path: string): Promise<ClaudeCredentials | null>;
|
|
8
|
+
export declare function watchCredentials(path: string, onChange: (creds: ClaudeCredentials | null) => void): () => void;
|
|
9
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAgBrF;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,GAClD,MAAM,IAAI,CAYZ"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { watch } from 'fs';
|
|
2
|
+
import { readFile as readFileAsync } from 'fs/promises';
|
|
3
|
+
export async function readCredentials(path) {
|
|
4
|
+
async function tryRead() {
|
|
5
|
+
try {
|
|
6
|
+
const raw = await readFileAsync(path, 'utf-8');
|
|
7
|
+
return JSON.parse(raw);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const first = await tryRead();
|
|
14
|
+
if (first)
|
|
15
|
+
return first;
|
|
16
|
+
// retry once after 200ms (handles partial writes on macOS kqueue)
|
|
17
|
+
await new Promise(r => setTimeout(r, 200));
|
|
18
|
+
return tryRead();
|
|
19
|
+
}
|
|
20
|
+
export function watchCredentials(path, onChange) {
|
|
21
|
+
let debounceTimer = null;
|
|
22
|
+
const watcher = watch(path, () => {
|
|
23
|
+
if (debounceTimer)
|
|
24
|
+
clearTimeout(debounceTimer);
|
|
25
|
+
debounceTimer = setTimeout(async () => {
|
|
26
|
+
const creds = await readCredentials(path);
|
|
27
|
+
onChange(creds);
|
|
28
|
+
}, 100); // 100ms debounce to avoid partial-write reads
|
|
29
|
+
});
|
|
30
|
+
return () => watcher.close();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAC1B,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,aAAa,CAAA;AASvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,KAAK,UAAU,OAAO;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAA;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,CAAA;IAC7B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAA;IAEvB,kEAAkE;IAClE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IAC1C,OAAO,OAAO,EAAE,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,QAAmD;IAEnD,IAAI,aAAa,GAA0B,IAAI,CAAA;IAE/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;QAC/B,IAAI,aAAa;YAAE,YAAY,CAAC,aAAa,CAAC,CAAA;QAC9C,aAAa,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACpC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAA;YACzC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjB,CAAC,EAAE,GAAG,CAAC,CAAA,CAAC,8CAA8C;IACxD,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/auth/detect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,UAAU,aAAa;IACrB,eAAe,EAAE,MAAM,CAAA;CACxB;AAWD,wBAAsB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAO9E"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { access } from 'fs/promises';
|
|
2
|
+
async function fileExists(path) {
|
|
3
|
+
try {
|
|
4
|
+
await access(path);
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function detectMode(opts) {
|
|
12
|
+
const hasApiKey = Boolean(process.env.ANTHROPIC_API_KEY);
|
|
13
|
+
const hasCredentials = await fileExists(opts.credentialsPath);
|
|
14
|
+
if (hasCredentials)
|
|
15
|
+
return 'plan';
|
|
16
|
+
if (hasApiKey)
|
|
17
|
+
return 'api';
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/auth/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAOpC,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAmB;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACxD,MAAM,cAAc,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAE7D,IAAI,cAAc;QAAE,OAAO,MAAM,CAAA;IACjC,IAAI,SAAS;QAAE,OAAO,KAAK,CAAA;IAC3B,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAe7D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readConfig, writeConfig } from '../storage/config-store.js';
|
|
2
|
+
import { CONFIG_PATH } from '../constants.js';
|
|
3
|
+
export async function runConfig(args) {
|
|
4
|
+
const config = await readConfig(CONFIG_PATH);
|
|
5
|
+
if (!config) {
|
|
6
|
+
console.log('Run meter init first.');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (args.length === 0) {
|
|
10
|
+
console.log(JSON.stringify(config, null, 2));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (args[0] === 'set' && args[1] && args[2]) {
|
|
14
|
+
const field = args[1];
|
|
15
|
+
const val = args[2];
|
|
16
|
+
if (field === 'budget')
|
|
17
|
+
config.budget.per_task_usd = parseFloat(val);
|
|
18
|
+
else if (field === 'threshold') {
|
|
19
|
+
config.budget.threshold_pct = parseInt(val, 10);
|
|
20
|
+
config.plan.window_threshold_pct = parseInt(val, 10);
|
|
21
|
+
}
|
|
22
|
+
await writeConfig(CONFIG_PATH, config);
|
|
23
|
+
console.log(`✓ ${field} set to ${val}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IAC5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IAC7D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IAC/E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,KAAK,KAAK,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;aAC/D,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAC/C,MAAM,CAAC,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QACtD,CAAC;QACD,MAAM,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,WAAW,GAAG,EAAE,CAAC,CAAA;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAGA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { openDb, getRecentTasks } from '../storage/db.js';
|
|
2
|
+
import { HISTORY_DB_PATH } from '../constants.js';
|
|
3
|
+
export async function runHistory(args) {
|
|
4
|
+
const limit = parseInt(args[0] ?? '30', 10);
|
|
5
|
+
const db = await openDb(HISTORY_DB_PATH);
|
|
6
|
+
const tasks = getRecentTasks(db, limit);
|
|
7
|
+
db.close();
|
|
8
|
+
if (tasks.length === 0) {
|
|
9
|
+
console.log('No tasks recorded yet.');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
console.log(`\n◆ meter history (last ${limit})\n`);
|
|
13
|
+
for (const t of tasks) {
|
|
14
|
+
const date = new Date(t.created_at).toLocaleString();
|
|
15
|
+
const cost = t.actual_cost != null ? `$${t.actual_cost.toFixed(3)}` : t.window_pct_end != null ? `${t.window_pct_end.toFixed(0)}% window` : '—';
|
|
16
|
+
console.log(` ${date} ${t.complexity.padEnd(8)} ${cost.padStart(10)} ${t.prompt_text.slice(0, 50)}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAc;IAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;IAC3C,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IACxC,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IACvC,EAAE,CAAC,KAAK,EAAE,CAAA;IACV,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,KAAK,CAAC,CAAA;IACpD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,cAAc,EAAE,CAAA;QACpD,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAA;QAC/I,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1G,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UserMode } from '../types.js';
|
|
2
|
+
export interface InitOptions {
|
|
3
|
+
meterDir: string;
|
|
4
|
+
trueBinary?: string;
|
|
5
|
+
mode?: UserMode;
|
|
6
|
+
skipPathInjection?: boolean;
|
|
7
|
+
orgId?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function runInit(opts: InitOptions): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD9D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { mkdir } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { detectShell, getShellConfigPath } from '../shell/detect.js';
|
|
4
|
+
import { resolveTrueBinary } from '../shell/binary-resolver.js';
|
|
5
|
+
import { writeShim } from '../shell/shim-writer.js';
|
|
6
|
+
import { injectPath, isPathAlreadyInjected } from '../shell/path-inject.js';
|
|
7
|
+
import { writeConfig, ensureConfigDefaults } from '../storage/config-store.js';
|
|
8
|
+
import { detectMode } from '../auth/detect.js';
|
|
9
|
+
import { readCredentials } from '../auth/credentials.js';
|
|
10
|
+
import { resolveOrgId } from '../tracking/plan-usage.js';
|
|
11
|
+
import { CLAUDE_CREDENTIALS_PATH } from '../constants.js';
|
|
12
|
+
export async function runInit(opts) {
|
|
13
|
+
const meterDir = opts.meterDir;
|
|
14
|
+
const binDir = join(meterDir, 'bin');
|
|
15
|
+
await mkdir(binDir, { recursive: true });
|
|
16
|
+
await mkdir(join(meterDir, 'cache'), { recursive: true });
|
|
17
|
+
await mkdir(join(meterDir, 'reports'), { recursive: true });
|
|
18
|
+
// Resolve true claude binary
|
|
19
|
+
const trueBinary = opts.trueBinary ?? await resolveTrueBinary('claude', binDir);
|
|
20
|
+
if (!trueBinary) {
|
|
21
|
+
throw new Error('claude not found in PATH. Install Claude Code first.');
|
|
22
|
+
}
|
|
23
|
+
// Detect mode
|
|
24
|
+
const mode = opts.mode ?? await detectMode({ credentialsPath: CLAUDE_CREDENTIALS_PATH });
|
|
25
|
+
if (!mode) {
|
|
26
|
+
throw new Error('No Claude credentials found. Run `claude` first to authenticate.');
|
|
27
|
+
}
|
|
28
|
+
// Resolve org_id for Plan Mode
|
|
29
|
+
let orgId = opts.orgId ?? null;
|
|
30
|
+
if (mode === 'plan' && orgId === null) {
|
|
31
|
+
const creds = await readCredentials(CLAUDE_CREDENTIALS_PATH);
|
|
32
|
+
if (creds)
|
|
33
|
+
orgId = await resolveOrgId(creds);
|
|
34
|
+
}
|
|
35
|
+
// Write shim
|
|
36
|
+
const shimPath = join(binDir, 'claude');
|
|
37
|
+
await writeShim(shimPath, trueBinary);
|
|
38
|
+
// Inject PATH (skip in tests)
|
|
39
|
+
if (!opts.skipPathInjection) {
|
|
40
|
+
const shell = detectShell();
|
|
41
|
+
const configPath = getShellConfigPath(shell);
|
|
42
|
+
const already = await isPathAlreadyInjected(configPath);
|
|
43
|
+
await injectPath(shell, configPath);
|
|
44
|
+
if (!already) {
|
|
45
|
+
console.log(`✓ Added ~/.meter/bin to PATH in ${configPath}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Write config
|
|
49
|
+
const config = ensureConfigDefaults({
|
|
50
|
+
mode,
|
|
51
|
+
resolved_binaries: { claude: trueBinary },
|
|
52
|
+
...(orgId ? { org_id: orgId } : {}),
|
|
53
|
+
});
|
|
54
|
+
await writeConfig(join(meterDir, 'config.json'), config);
|
|
55
|
+
console.log(`✓ meter initialised (${mode} mode)`);
|
|
56
|
+
console.log(` Restart your terminal or run: source ~/.zshrc`);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB/C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { readConfig } from '../storage/config-store.js';
|
|
2
|
+
import { openDb, getRecentTasks } from '../storage/db.js';
|
|
3
|
+
import { CONFIG_PATH, HISTORY_DB_PATH } from '../constants.js';
|
|
4
|
+
export async function runReport() {
|
|
5
|
+
const config = await readConfig(CONFIG_PATH);
|
|
6
|
+
if (!config) {
|
|
7
|
+
console.log('Run meter init first.');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const db = await openDb(HISTORY_DB_PATH);
|
|
11
|
+
const weekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
|
|
12
|
+
const allTasks = getRecentTasks(db, 500).filter(t => t.created_at >= weekAgo);
|
|
13
|
+
db.close();
|
|
14
|
+
if (allTasks.length === 0) {
|
|
15
|
+
console.log('No tasks recorded this week.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const totalCost = allTasks.reduce((s, t) => s + (t.actual_cost ?? 0), 0);
|
|
19
|
+
const heaviest = allTasks.sort((a, b) => (b.actual_cost ?? 0) - (a.actual_cost ?? 0))[0];
|
|
20
|
+
const byComplexity = { low: 0, medium: 0, heavy: 0, critical: 0 };
|
|
21
|
+
for (const t of allTasks)
|
|
22
|
+
byComplexity[t.complexity] = (byComplexity[t.complexity] ?? 0) + 1;
|
|
23
|
+
console.log(`\n◆ meter weekly report\n`);
|
|
24
|
+
console.log(` Mode ${config.mode}`);
|
|
25
|
+
console.log(` Tasks run ${allTasks.length}`);
|
|
26
|
+
if (config.mode === 'api') {
|
|
27
|
+
console.log(` Total spend $${totalCost.toFixed(3)}`);
|
|
28
|
+
console.log(` Avg task cost $${(totalCost / allTasks.length).toFixed(3)}`);
|
|
29
|
+
}
|
|
30
|
+
if (heaviest)
|
|
31
|
+
console.log(` Heaviest task "${heaviest.prompt_text.slice(0, 40)}"`);
|
|
32
|
+
console.log(`\n By complexity:`);
|
|
33
|
+
for (const [k, v] of Object.entries(byComplexity))
|
|
34
|
+
if (v > 0)
|
|
35
|
+
console.log(` ${k.padEnd(10)} ${v} tasks`);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAY/C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readConfig } from '../storage/config-store.js';
|
|
2
|
+
import { CONFIG_PATH } from '../constants.js';
|
|
3
|
+
export async function runStatus() {
|
|
4
|
+
const config = await readConfig(CONFIG_PATH);
|
|
5
|
+
if (!config) {
|
|
6
|
+
console.log('meter not initialised. Run: meter init');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
console.log(`◆ meter status\n`);
|
|
10
|
+
console.log(` Mode: ${config.mode}`);
|
|
11
|
+
console.log(` Model: ${config.models.claude_chain[0]}`);
|
|
12
|
+
console.log(` Claude: ${config.resolved_binaries.claude}`);
|
|
13
|
+
if (config.mode === 'api') {
|
|
14
|
+
console.log(` Budget: $${config.budget.per_task_usd} per task (notify at ${config.budget.threshold_pct}%)`);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log(` Window: notify at ${config.plan.window_threshold_pct}%`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC/B,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;IACxC,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC1D,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5D,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,CAAC,YAAY,yBAAyB,MAAM,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAA;IAChH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAA;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAMA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAalD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { rm } from 'fs/promises';
|
|
2
|
+
import { removePath } from '../shell/path-inject.js';
|
|
3
|
+
import { detectShell, getShellConfigPath } from '../shell/detect.js';
|
|
4
|
+
import { METER_DIR } from '../constants.js';
|
|
5
|
+
import * as readline from 'readline/promises';
|
|
6
|
+
export async function runUninstall() {
|
|
7
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8
|
+
const answer = await rl.question('Remove all meter data (~/.meter/)? [y/N] ');
|
|
9
|
+
rl.close();
|
|
10
|
+
const shell = detectShell();
|
|
11
|
+
const configPath = getShellConfigPath(shell);
|
|
12
|
+
await removePath(configPath);
|
|
13
|
+
console.log(`✓ Removed PATH entry from ${configPath}`);
|
|
14
|
+
if (answer.toLowerCase() === 'y') {
|
|
15
|
+
await rm(METER_DIR, { recursive: true, force: true });
|
|
16
|
+
console.log('✓ Removed ~/.meter/');
|
|
17
|
+
}
|
|
18
|
+
console.log('✓ Uninstall complete. Run: npm uninstall -g meter-ai');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAE7C,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACrF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC,CAAA;IAC7E,EAAE,CAAC,KAAK,EAAE,CAAA;IACV,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;IAC3B,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC5C,MAAM,UAAU,CAAC,UAAU,CAAC,CAAA;IAC5B,OAAO,CAAC,GAAG,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAA;IACtD,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;QACjC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;IACpC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAA;AACrE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/commands/wrap.ts"],"names":[],"mappings":"AAmBA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsL3D"}
|