token-guard 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 +109 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +141 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +43 -0
- package/dist/config.js.map +1 -0
- package/dist/display.d.ts +10 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +139 -0
- package/dist/display.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor.d.ts +20 -0
- package/dist/monitor.d.ts.map +1 -0
- package/dist/monitor.js +160 -0
- package/dist/monitor.js.map +1 -0
- package/dist/pricing.d.ts +6 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +60 -0
- package/dist/pricing.js.map +1 -0
- package/dist/tokenizer.d.ts +3 -0
- package/dist/tokenizer.d.ts.map +1 -0
- package/dist/tokenizer.js +54 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
- package/src/cli.ts +166 -0
- package/src/config.ts +44 -0
- package/src/display.ts +160 -0
- package/src/index.ts +7 -0
- package/src/monitor.ts +189 -0
- package/src/pricing.ts +66 -0
- package/src/tokenizer.ts +57 -0
- package/src/types.ts +33 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# token-guard
|
|
2
|
+
|
|
3
|
+
CLI tool to monitor and limit token usage for AI coding assistants like Claude Code, Aider, and others.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
A single "refactor this directory" command can burn 100k+ tokens in minutes. There's no visibility into token usage until you get the bill.
|
|
8
|
+
|
|
9
|
+
## The Solution
|
|
10
|
+
|
|
11
|
+
`token-guard` wraps your AI coding commands with real-time token monitoring, budgets, and cost estimates.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g token-guard
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Basic Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Wrap any command with token monitoring
|
|
25
|
+
token-guard -- claude "refactor the auth module"
|
|
26
|
+
|
|
27
|
+
# Set a token budget (stops execution if exceeded)
|
|
28
|
+
token-guard --budget 50000 -- aider --message "add tests"
|
|
29
|
+
|
|
30
|
+
# Set a cost limit (in USD)
|
|
31
|
+
token-guard --cost-limit 0.50 -- claude "explain this codebase"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Options
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Options:
|
|
38
|
+
-b, --budget <tokens> Maximum tokens allowed (default: unlimited)
|
|
39
|
+
-c, --cost-limit <usd> Maximum cost in USD (default: unlimited)
|
|
40
|
+
-m, --model <name> Model for pricing (default: auto-detect)
|
|
41
|
+
-w, --warn <percent> Warn at percentage of budget (default: 80)
|
|
42
|
+
-q, --quiet Only show warnings and errors
|
|
43
|
+
-o, --output <file> Save usage report to file
|
|
44
|
+
-h, --help Show help
|
|
45
|
+
-v, --version Show version
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Examples
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Monitor Claude Code with 50k token budget
|
|
52
|
+
token-guard -b 50000 -- claude "add error handling to api routes"
|
|
53
|
+
|
|
54
|
+
# Set $1 cost limit with warnings at 50%
|
|
55
|
+
token-guard -c 1.00 -w 50 -- aider --model claude-3-opus
|
|
56
|
+
|
|
57
|
+
# Quiet mode - only show if budget exceeded
|
|
58
|
+
token-guard -b 100000 -q -- claude "refactor src/"
|
|
59
|
+
|
|
60
|
+
# Save report for later analysis
|
|
61
|
+
token-guard -o usage-report.json -- claude "review this PR"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Configuration
|
|
65
|
+
|
|
66
|
+
Create `~/.token-guard.json` for persistent settings:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"defaultBudget": 50000,
|
|
71
|
+
"warnPercent": 80,
|
|
72
|
+
"models": {
|
|
73
|
+
"claude-3-opus": { "input": 15.00, "output": 75.00 },
|
|
74
|
+
"claude-3-sonnet": { "input": 3.00, "output": 15.00 },
|
|
75
|
+
"gpt-4": { "input": 30.00, "output": 60.00 }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## How It Works
|
|
81
|
+
|
|
82
|
+
1. **Intercepts I/O**: Monitors stdin/stdout of wrapped commands
|
|
83
|
+
2. **Counts Tokens**: Uses tiktoken for accurate token counting
|
|
84
|
+
3. **Tracks Costs**: Applies model-specific pricing
|
|
85
|
+
4. **Enforces Limits**: Terminates process if budget exceeded
|
|
86
|
+
5. **Reports Usage**: Shows real-time and final usage stats
|
|
87
|
+
|
|
88
|
+
## Supported Tools
|
|
89
|
+
|
|
90
|
+
- Claude Code (`claude`)
|
|
91
|
+
- Aider (`aider`)
|
|
92
|
+
- Any CLI tool that streams text output
|
|
93
|
+
|
|
94
|
+
## Output Example
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
┌─────────────────────────────────────────────┐
|
|
98
|
+
│ token-guard v0.1.0 │
|
|
99
|
+
│ Budget: 50,000 tokens | Warn: 80% │
|
|
100
|
+
├─────────────────────────────────────────────┤
|
|
101
|
+
│ ████████████░░░░░░░░ 42,150 / 50,000 │
|
|
102
|
+
│ Input: 8,200 | Output: 33,950 │
|
|
103
|
+
│ Est. Cost: $0.43 (claude-3-sonnet) │
|
|
104
|
+
└─────────────────────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const config_js_1 = require("./config.js");
|
|
5
|
+
const monitor_js_1 = require("./monitor.js");
|
|
6
|
+
const VERSION = '0.1.0';
|
|
7
|
+
const HELP = `
|
|
8
|
+
token-guard v${VERSION}
|
|
9
|
+
Monitor and limit token usage for AI coding assistants
|
|
10
|
+
|
|
11
|
+
USAGE:
|
|
12
|
+
token-guard [options] -- <command>
|
|
13
|
+
|
|
14
|
+
OPTIONS:
|
|
15
|
+
-b, --budget <tokens> Maximum tokens allowed (default: unlimited)
|
|
16
|
+
-c, --cost-limit <usd> Maximum cost in USD (default: unlimited)
|
|
17
|
+
-m, --model <name> Model for pricing (default: auto-detect)
|
|
18
|
+
-w, --warn <percent> Warn at percentage of budget (default: 80)
|
|
19
|
+
-q, --quiet Only show warnings and errors
|
|
20
|
+
-o, --output <file> Save usage report to JSON file
|
|
21
|
+
-h, --help Show this help message
|
|
22
|
+
-v, --version Show version
|
|
23
|
+
|
|
24
|
+
EXAMPLES:
|
|
25
|
+
token-guard -- claude "refactor the auth module"
|
|
26
|
+
token-guard -b 50000 -- aider --message "add tests"
|
|
27
|
+
token-guard -c 0.50 -- claude "explain this codebase"
|
|
28
|
+
token-guard -b 100000 -w 50 -o report.json -- claude "review PR"
|
|
29
|
+
|
|
30
|
+
CONFIGURATION:
|
|
31
|
+
Create ~/.token-guard.json for persistent settings:
|
|
32
|
+
{
|
|
33
|
+
"defaultBudget": 50000,
|
|
34
|
+
"warnPercent": 80,
|
|
35
|
+
"models": {
|
|
36
|
+
"custom-model": { "input": 5.00, "output": 15.00 }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
`;
|
|
41
|
+
function parseArgs(args) {
|
|
42
|
+
const config = (0, config_js_1.loadConfig)();
|
|
43
|
+
const options = {
|
|
44
|
+
budget: config.defaultBudget,
|
|
45
|
+
costLimit: config.defaultCostLimit,
|
|
46
|
+
warnPercent: config.warnPercent,
|
|
47
|
+
quiet: false,
|
|
48
|
+
};
|
|
49
|
+
const command = [];
|
|
50
|
+
let i = 0;
|
|
51
|
+
let foundSeparator = false;
|
|
52
|
+
while (i < args.length) {
|
|
53
|
+
const arg = args[i];
|
|
54
|
+
if (foundSeparator) {
|
|
55
|
+
command.push(arg);
|
|
56
|
+
i++;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (arg === '--') {
|
|
60
|
+
foundSeparator = true;
|
|
61
|
+
i++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
switch (arg) {
|
|
65
|
+
case '-h':
|
|
66
|
+
case '--help':
|
|
67
|
+
console.log(HELP);
|
|
68
|
+
process.exit(0);
|
|
69
|
+
break;
|
|
70
|
+
case '-v':
|
|
71
|
+
case '--version':
|
|
72
|
+
console.log(`token-guard v${VERSION}`);
|
|
73
|
+
process.exit(0);
|
|
74
|
+
break;
|
|
75
|
+
case '-b':
|
|
76
|
+
case '--budget':
|
|
77
|
+
options.budget = parseInt(args[++i], 10);
|
|
78
|
+
if (isNaN(options.budget)) {
|
|
79
|
+
console.error('Error: --budget requires a number');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case '-c':
|
|
84
|
+
case '--cost-limit':
|
|
85
|
+
options.costLimit = parseFloat(args[++i]);
|
|
86
|
+
if (isNaN(options.costLimit)) {
|
|
87
|
+
console.error('Error: --cost-limit requires a number');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
case '-m':
|
|
92
|
+
case '--model':
|
|
93
|
+
options.model = args[++i];
|
|
94
|
+
break;
|
|
95
|
+
case '-w':
|
|
96
|
+
case '--warn':
|
|
97
|
+
options.warnPercent = parseInt(args[++i], 10);
|
|
98
|
+
if (isNaN(options.warnPercent)) {
|
|
99
|
+
console.error('Error: --warn requires a number');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case '-q':
|
|
104
|
+
case '--quiet':
|
|
105
|
+
options.quiet = true;
|
|
106
|
+
break;
|
|
107
|
+
case '-o':
|
|
108
|
+
case '--output':
|
|
109
|
+
options.output = args[++i];
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
// If we hit an unknown arg before --, treat rest as command
|
|
113
|
+
command.push(arg);
|
|
114
|
+
foundSeparator = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
i++;
|
|
118
|
+
}
|
|
119
|
+
return { options, command };
|
|
120
|
+
}
|
|
121
|
+
async function main() {
|
|
122
|
+
const args = process.argv.slice(2);
|
|
123
|
+
if (args.length === 0) {
|
|
124
|
+
console.log(HELP);
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
const { options, command } = parseArgs(args);
|
|
128
|
+
if (command.length === 0) {
|
|
129
|
+
console.error('Error: No command specified');
|
|
130
|
+
console.error('Usage: token-guard [options] -- <command>');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
const monitor = new monitor_js_1.TokenMonitor(command.join(' '), options);
|
|
134
|
+
const exitCode = await monitor.run(command);
|
|
135
|
+
process.exit(exitCode);
|
|
136
|
+
}
|
|
137
|
+
main().catch((err) => {
|
|
138
|
+
console.error('Fatal error:', err);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAUzC,wBAAgB,UAAU,IAAI,MAAM,CA0BnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
exports.getConfigPath = getConfigPath;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const pricing_js_1 = require("./pricing.js");
|
|
9
|
+
const CONFIG_FILENAME = '.token-guard.json';
|
|
10
|
+
const DEFAULT_CONFIG = {
|
|
11
|
+
warnPercent: 80,
|
|
12
|
+
models: pricing_js_1.MODEL_PRICING,
|
|
13
|
+
};
|
|
14
|
+
function loadConfig() {
|
|
15
|
+
const configPaths = [
|
|
16
|
+
(0, node_path_1.join)(process.cwd(), CONFIG_FILENAME),
|
|
17
|
+
(0, node_path_1.join)((0, node_os_1.homedir)(), CONFIG_FILENAME),
|
|
18
|
+
];
|
|
19
|
+
for (const configPath of configPaths) {
|
|
20
|
+
if ((0, node_fs_1.existsSync)(configPath)) {
|
|
21
|
+
try {
|
|
22
|
+
const content = (0, node_fs_1.readFileSync)(configPath, 'utf-8');
|
|
23
|
+
const userConfig = JSON.parse(content);
|
|
24
|
+
return {
|
|
25
|
+
...DEFAULT_CONFIG,
|
|
26
|
+
...userConfig,
|
|
27
|
+
models: {
|
|
28
|
+
...DEFAULT_CONFIG.models,
|
|
29
|
+
...userConfig.models,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Ignore invalid config files
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return DEFAULT_CONFIG;
|
|
39
|
+
}
|
|
40
|
+
function getConfigPath() {
|
|
41
|
+
return (0, node_path_1.join)((0, node_os_1.homedir)(), CONFIG_FILENAME);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAaA,gCA0BC;AAED,sCAEC;AA3CD,qCAAmD;AACnD,qCAAkC;AAClC,yCAAiC;AAEjC,6CAA6C;AAE7C,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C,MAAM,cAAc,GAAW;IAC7B,WAAW,EAAE,EAAE;IACf,MAAM,EAAE,0BAAa;CACtB,CAAC;AAEF,SAAgB,UAAU;IACxB,MAAM,WAAW,GAAG;QAClB,IAAA,gBAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC;QACpC,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,eAAe,CAAC;KACjC,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,IAAA,oBAAU,EAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAClD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvC,OAAO;oBACL,GAAG,cAAc;oBACjB,GAAG,UAAU;oBACb,MAAM,EAAE;wBACN,GAAG,cAAc,CAAC,MAAM;wBACxB,GAAG,UAAU,CAAC,MAAM;qBACrB;iBACF,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,8BAA8B;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,eAAe,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UsageStats, TokenGuardOptions } from './types.js';
|
|
2
|
+
export declare function clearLine(): void;
|
|
3
|
+
export declare function moveCursorUp(lines: number): void;
|
|
4
|
+
export declare function progressBar(current: number, max: number, width?: number): string;
|
|
5
|
+
export declare function formatCost(cost: number): string;
|
|
6
|
+
export declare function renderStatus(stats: UsageStats, options: TokenGuardOptions, inline?: boolean): string;
|
|
7
|
+
export declare function renderFinalReport(stats: UsageStats, options: TokenGuardOptions): string;
|
|
8
|
+
export declare function warn(message: string): void;
|
|
9
|
+
export declare function error(message: string): void;
|
|
10
|
+
//# sourceMappingURL=display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkBhE,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAUpF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,GAAE,OAAc,GACrB,MAAM,CAsER;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAiCvF;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C"}
|
package/dist/display.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearLine = clearLine;
|
|
4
|
+
exports.moveCursorUp = moveCursorUp;
|
|
5
|
+
exports.progressBar = progressBar;
|
|
6
|
+
exports.formatCost = formatCost;
|
|
7
|
+
exports.renderStatus = renderStatus;
|
|
8
|
+
exports.renderFinalReport = renderFinalReport;
|
|
9
|
+
exports.warn = warn;
|
|
10
|
+
exports.error = error;
|
|
11
|
+
const tokenizer_js_1 = require("./tokenizer.js");
|
|
12
|
+
const COLORS = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bold: '\x1b[1m',
|
|
15
|
+
dim: '\x1b[2m',
|
|
16
|
+
red: '\x1b[31m',
|
|
17
|
+
green: '\x1b[32m',
|
|
18
|
+
yellow: '\x1b[33m',
|
|
19
|
+
blue: '\x1b[34m',
|
|
20
|
+
magenta: '\x1b[35m',
|
|
21
|
+
cyan: '\x1b[36m',
|
|
22
|
+
white: '\x1b[37m',
|
|
23
|
+
bgRed: '\x1b[41m',
|
|
24
|
+
bgYellow: '\x1b[43m',
|
|
25
|
+
};
|
|
26
|
+
function clearLine() {
|
|
27
|
+
process.stderr.write('\x1b[2K\x1b[G');
|
|
28
|
+
}
|
|
29
|
+
function moveCursorUp(lines) {
|
|
30
|
+
process.stderr.write(`\x1b[${lines}A`);
|
|
31
|
+
}
|
|
32
|
+
function progressBar(current, max, width = 20) {
|
|
33
|
+
const percent = Math.min(current / max, 1);
|
|
34
|
+
const filled = Math.round(width * percent);
|
|
35
|
+
const empty = width - filled;
|
|
36
|
+
let color = COLORS.green;
|
|
37
|
+
if (percent >= 0.9)
|
|
38
|
+
color = COLORS.red;
|
|
39
|
+
else if (percent >= 0.8)
|
|
40
|
+
color = COLORS.yellow;
|
|
41
|
+
return `${color}${'█'.repeat(filled)}${COLORS.dim}${'░'.repeat(empty)}${COLORS.reset}`;
|
|
42
|
+
}
|
|
43
|
+
function formatCost(cost) {
|
|
44
|
+
return `$${cost.toFixed(4)}`;
|
|
45
|
+
}
|
|
46
|
+
function renderStatus(stats, options, inline = true) {
|
|
47
|
+
const { budget, costLimit, warnPercent } = options;
|
|
48
|
+
const { inputTokens, outputTokens, totalTokens, estimatedCost, model } = stats;
|
|
49
|
+
if (options.quiet) {
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
const lines = [];
|
|
53
|
+
if (inline) {
|
|
54
|
+
// Compact inline display
|
|
55
|
+
let status = `${COLORS.cyan}◆${COLORS.reset} `;
|
|
56
|
+
status += `${COLORS.bold}${(0, tokenizer_js_1.formatTokens)(totalTokens)}${COLORS.reset} tokens `;
|
|
57
|
+
status += `${COLORS.dim}(in:${(0, tokenizer_js_1.formatTokens)(inputTokens)} out:${(0, tokenizer_js_1.formatTokens)(outputTokens)})${COLORS.reset} `;
|
|
58
|
+
status += `${COLORS.green}${formatCost(estimatedCost)}${COLORS.reset} `;
|
|
59
|
+
if (budget) {
|
|
60
|
+
const percent = (totalTokens / budget) * 100;
|
|
61
|
+
if (percent >= 100) {
|
|
62
|
+
status += `${COLORS.bgRed}${COLORS.white} BUDGET EXCEEDED ${COLORS.reset}`;
|
|
63
|
+
}
|
|
64
|
+
else if (percent >= warnPercent) {
|
|
65
|
+
status += `${COLORS.yellow}⚠ ${percent.toFixed(0)}% of budget${COLORS.reset}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (costLimit) {
|
|
69
|
+
const percent = (estimatedCost / costLimit) * 100;
|
|
70
|
+
if (percent >= 100) {
|
|
71
|
+
status += `${COLORS.bgRed}${COLORS.white} COST LIMIT EXCEEDED ${COLORS.reset}`;
|
|
72
|
+
}
|
|
73
|
+
else if (percent >= warnPercent) {
|
|
74
|
+
status += `${COLORS.yellow}⚠ ${percent.toFixed(0)}% of cost limit${COLORS.reset}`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return status;
|
|
78
|
+
}
|
|
79
|
+
// Box display
|
|
80
|
+
const width = 47;
|
|
81
|
+
const border = '─'.repeat(width - 2);
|
|
82
|
+
lines.push(`${COLORS.dim}┌${border}┐${COLORS.reset}`);
|
|
83
|
+
lines.push(`${COLORS.dim}│${COLORS.reset} ${COLORS.bold}${COLORS.cyan}token-guard${COLORS.reset} v0.1.0${' '.repeat(width - 24)}${COLORS.dim}│${COLORS.reset}`);
|
|
84
|
+
if (budget) {
|
|
85
|
+
const budgetLine = ` Budget: ${(0, tokenizer_js_1.formatTokens)(budget)} tokens | Warn: ${warnPercent}%`;
|
|
86
|
+
lines.push(`${COLORS.dim}│${COLORS.reset}${budgetLine}${' '.repeat(width - budgetLine.length - 2)}${COLORS.dim}│${COLORS.reset}`);
|
|
87
|
+
}
|
|
88
|
+
lines.push(`${COLORS.dim}├${border}┤${COLORS.reset}`);
|
|
89
|
+
// Progress bar
|
|
90
|
+
if (budget) {
|
|
91
|
+
const bar = progressBar(totalTokens, budget, 20);
|
|
92
|
+
const counts = `${(0, tokenizer_js_1.formatTokens)(totalTokens)} / ${(0, tokenizer_js_1.formatTokens)(budget)}`;
|
|
93
|
+
lines.push(`${COLORS.dim}│${COLORS.reset} ${bar} ${counts}${' '.repeat(width - 30 - counts.length)}${COLORS.dim}│${COLORS.reset}`);
|
|
94
|
+
}
|
|
95
|
+
// Token breakdown
|
|
96
|
+
const breakdown = ` Input: ${(0, tokenizer_js_1.formatTokens)(inputTokens)} | Output: ${(0, tokenizer_js_1.formatTokens)(outputTokens)}`;
|
|
97
|
+
lines.push(`${COLORS.dim}│${COLORS.reset}${breakdown}${' '.repeat(width - breakdown.length - 2)}${COLORS.dim}│${COLORS.reset}`);
|
|
98
|
+
// Cost
|
|
99
|
+
const costLine = ` Est. Cost: ${formatCost(estimatedCost)} (${model})`;
|
|
100
|
+
lines.push(`${COLORS.dim}│${COLORS.reset}${costLine}${' '.repeat(width - costLine.length - 2)}${COLORS.dim}│${COLORS.reset}`);
|
|
101
|
+
lines.push(`${COLORS.dim}└${border}┘${COLORS.reset}`);
|
|
102
|
+
return lines.join('\n');
|
|
103
|
+
}
|
|
104
|
+
function renderFinalReport(stats, options) {
|
|
105
|
+
const lines = [];
|
|
106
|
+
const duration = stats.endTime
|
|
107
|
+
? ((stats.endTime.getTime() - stats.startTime.getTime()) / 1000).toFixed(1)
|
|
108
|
+
: '?';
|
|
109
|
+
lines.push('');
|
|
110
|
+
lines.push(`${COLORS.bold}${COLORS.cyan}═══ token-guard Report ═══${COLORS.reset}`);
|
|
111
|
+
lines.push('');
|
|
112
|
+
lines.push(`${COLORS.bold}Command:${COLORS.reset} ${stats.command}`);
|
|
113
|
+
lines.push(`${COLORS.bold}Model:${COLORS.reset} ${stats.model}`);
|
|
114
|
+
lines.push(`${COLORS.bold}Duration:${COLORS.reset} ${duration}s`);
|
|
115
|
+
lines.push('');
|
|
116
|
+
lines.push(`${COLORS.bold}Tokens:${COLORS.reset}`);
|
|
117
|
+
lines.push(` Input: ${(0, tokenizer_js_1.formatTokens)(stats.inputTokens).padStart(10)}`);
|
|
118
|
+
lines.push(` Output: ${(0, tokenizer_js_1.formatTokens)(stats.outputTokens).padStart(10)}`);
|
|
119
|
+
lines.push(` Total: ${(0, tokenizer_js_1.formatTokens)(stats.totalTokens).padStart(10)}`);
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push(`${COLORS.bold}Estimated Cost:${COLORS.reset} ${COLORS.green}${formatCost(stats.estimatedCost)}${COLORS.reset}`);
|
|
122
|
+
if (stats.budgetExceeded) {
|
|
123
|
+
lines.push('');
|
|
124
|
+
lines.push(`${COLORS.bgRed}${COLORS.white} BUDGET EXCEEDED - Process terminated ${COLORS.reset}`);
|
|
125
|
+
}
|
|
126
|
+
if (stats.costExceeded) {
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push(`${COLORS.bgRed}${COLORS.white} COST LIMIT EXCEEDED - Process terminated ${COLORS.reset}`);
|
|
129
|
+
}
|
|
130
|
+
lines.push('');
|
|
131
|
+
return lines.join('\n');
|
|
132
|
+
}
|
|
133
|
+
function warn(message) {
|
|
134
|
+
console.error(`${COLORS.yellow}⚠ token-guard:${COLORS.reset} ${message}`);
|
|
135
|
+
}
|
|
136
|
+
function error(message) {
|
|
137
|
+
console.error(`${COLORS.red}✖ token-guard:${COLORS.reset} ${message}`);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { TokenMonitor } from './monitor.js';
|
|
2
|
+
export { countTokens, formatTokens } from './tokenizer.js';
|
|
3
|
+
export { calculateCost, getPricing, detectModel, MODEL_PRICING } from './pricing.js';
|
|
4
|
+
export { loadConfig, getConfigPath } from './config.js';
|
|
5
|
+
export type { TokenGuardOptions, UsageStats, ModelPricing, Config } from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// token-guard - Monitor and limit token usage for AI coding assistants
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.getConfigPath = exports.loadConfig = exports.MODEL_PRICING = exports.detectModel = exports.getPricing = exports.calculateCost = exports.formatTokens = exports.countTokens = exports.TokenMonitor = void 0;
|
|
5
|
+
var monitor_js_1 = require("./monitor.js");
|
|
6
|
+
Object.defineProperty(exports, "TokenMonitor", { enumerable: true, get: function () { return monitor_js_1.TokenMonitor; } });
|
|
7
|
+
var tokenizer_js_1 = require("./tokenizer.js");
|
|
8
|
+
Object.defineProperty(exports, "countTokens", { enumerable: true, get: function () { return tokenizer_js_1.countTokens; } });
|
|
9
|
+
Object.defineProperty(exports, "formatTokens", { enumerable: true, get: function () { return tokenizer_js_1.formatTokens; } });
|
|
10
|
+
var pricing_js_1 = require("./pricing.js");
|
|
11
|
+
Object.defineProperty(exports, "calculateCost", { enumerable: true, get: function () { return pricing_js_1.calculateCost; } });
|
|
12
|
+
Object.defineProperty(exports, "getPricing", { enumerable: true, get: function () { return pricing_js_1.getPricing; } });
|
|
13
|
+
Object.defineProperty(exports, "detectModel", { enumerable: true, get: function () { return pricing_js_1.detectModel; } });
|
|
14
|
+
Object.defineProperty(exports, "MODEL_PRICING", { enumerable: true, get: function () { return pricing_js_1.MODEL_PRICING; } });
|
|
15
|
+
var config_js_1 = require("./config.js");
|
|
16
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_js_1.loadConfig; } });
|
|
17
|
+
Object.defineProperty(exports, "getConfigPath", { enumerable: true, get: function () { return config_js_1.getConfigPath; } });
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,uEAAuE;;;AAEvE,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,+CAA2D;AAAlD,2GAAA,WAAW,OAAA;AAAE,4GAAA,YAAY,OAAA;AAClC,2CAAqF;AAA5E,2GAAA,aAAa,OAAA;AAAE,wGAAA,UAAU,OAAA;AAAE,yGAAA,WAAW,OAAA;AAAE,2GAAA,aAAa,OAAA;AAC9D,yCAAwD;AAA/C,uGAAA,UAAU,OAAA;AAAE,0GAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TokenGuardOptions, UsageStats } from './types.js';
|
|
2
|
+
export declare class TokenMonitor {
|
|
3
|
+
private stats;
|
|
4
|
+
private options;
|
|
5
|
+
private process;
|
|
6
|
+
private updateInterval;
|
|
7
|
+
private lastStatusLength;
|
|
8
|
+
constructor(command: string, options: TokenGuardOptions);
|
|
9
|
+
run(args: string[]): Promise<number>;
|
|
10
|
+
private addInputTokens;
|
|
11
|
+
private addOutputTokens;
|
|
12
|
+
private updateTotals;
|
|
13
|
+
private checkLimits;
|
|
14
|
+
private terminate;
|
|
15
|
+
private showStatus;
|
|
16
|
+
private cleanup;
|
|
17
|
+
private saveReport;
|
|
18
|
+
getStats(): UsageStats;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKhE,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAAK;gBAEjB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAiBjD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IA2D1C,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,UAAU;IAiBlB,QAAQ,IAAI,UAAU;CAGvB"}
|