zusage 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/bin/index.js +122 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Zusage
|
|
2
|
+
|
|
3
|
+
A minimal CLI tool to monitor your Z.ai token usage when using a Claude Code coding plan.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This tool connects to the Z.ai API to fetch and display your current token consumption, showing your usage progress within the 5-hour rolling window and the time until your next quota reset.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Visual progress bar showing token usage percentage
|
|
12
|
+
- Current tokens used, remaining, and total limit
|
|
13
|
+
- Time remaining until next reset
|
|
14
|
+
- Next reset date and time (Paris timezone)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
### Via npx (recommended)
|
|
19
|
+
|
|
20
|
+
No installation needed - just run:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx -y zusage@latest
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Or install globally
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g zusage
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
Set your `ANTHROPIC_AUTH_TOKEN` environment variable (found in your browser's localStorage when logged into Z.ai):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
export ANTHROPIC_AUTH_TOKEN="your_token_here"
|
|
38
|
+
|
|
39
|
+
# Via npx
|
|
40
|
+
npx -y zusage@latest
|
|
41
|
+
|
|
42
|
+
# Or if installed globally
|
|
43
|
+
zusage
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Example Output
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
==================================================
|
|
50
|
+
📊 Z.AI - UTILISATION DES TOKENS
|
|
51
|
+
==================================================
|
|
52
|
+
|
|
53
|
+
Progression: [███████████████████████░░░░] 72%
|
|
54
|
+
|
|
55
|
+
📈 Utilisé: 145 000 tokens
|
|
56
|
+
📉 Restant: 55 000 tokens
|
|
57
|
+
🎯 Limite: 200 000 tokens
|
|
58
|
+
|
|
59
|
+
⏱️ Reset dans: 2h 15min
|
|
60
|
+
📅 Prochain reset: lundi 11 janvier 2026 à 14:30
|
|
61
|
+
|
|
62
|
+
==================================================
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 5-Hour Rolling Window
|
|
66
|
+
|
|
67
|
+
Z.ai uses a 5-hour rolling window for token limits. This means your quota resets based on your usage over the past 5 hours, not at a fixed time. This tool shows when your next window reset will occur based on the API data.
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Programme simple pour afficher l'utilisation des tokens Z.ai
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const BASE_URL = 'https://api.z.ai';
|
|
7
|
+
const AUTH_TOKEN = process.env.ANTHROPIC_AUTH_TOKEN;
|
|
8
|
+
|
|
9
|
+
if (!AUTH_TOKEN) {
|
|
10
|
+
console.error('❌ Erreur: La variable d\'environnement ANTHROPIC_AUTH_TOKEN n\'est pas définie');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Récupère les limites de tokens depuis l'API Z.ai
|
|
16
|
+
*/
|
|
17
|
+
async function getTokenLimit() {
|
|
18
|
+
const response = await fetch(`${BASE_URL}/api/monitor/usage/quota/limit`, {
|
|
19
|
+
method: 'GET',
|
|
20
|
+
headers: {
|
|
21
|
+
'accept': 'application/json, text/plain, */*',
|
|
22
|
+
'origin': 'https://z.ai',
|
|
23
|
+
'authorization': `Bearer ${AUTH_TOKEN}`,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
|
|
33
|
+
if (!data.success) {
|
|
34
|
+
throw new Error(`API Error: ${data.msg}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Trouver et retourner uniquement la partie TOKENS_LIMIT
|
|
38
|
+
const tokensLimit = data.data.limits.find(limit => limit.type === 'TOKENS_LIMIT');
|
|
39
|
+
|
|
40
|
+
if (!tokensLimit) {
|
|
41
|
+
throw new Error('TOKENS_LIMIT non trouvé dans la réponse');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return tokensLimit;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Formate un nombre avec séparateur de milliers
|
|
49
|
+
*/
|
|
50
|
+
function formatNumber(num) {
|
|
51
|
+
return new Intl.NumberFormat('fr-FR').format(num);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Formette un timestamp en date lisible
|
|
56
|
+
*/
|
|
57
|
+
function formatDate(timestamp) {
|
|
58
|
+
return new Date(timestamp).toLocaleString('fr-FR', {
|
|
59
|
+
timeZone: 'Europe/Paris',
|
|
60
|
+
dateStyle: 'full',
|
|
61
|
+
timeStyle: 'short',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Calcule le temps restant jusqu'au reset
|
|
67
|
+
*/
|
|
68
|
+
function getTimeRemaining(nextResetTime) {
|
|
69
|
+
const now = Date.now();
|
|
70
|
+
const remaining = nextResetTime - now;
|
|
71
|
+
|
|
72
|
+
const days = Math.floor(remaining / (1000 * 60 * 60 * 24));
|
|
73
|
+
const hours = Math.floor((remaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
74
|
+
const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60));
|
|
75
|
+
|
|
76
|
+
if (days > 0) {
|
|
77
|
+
return `${days}j ${hours}h ${minutes}min`;
|
|
78
|
+
} else if (hours > 0) {
|
|
79
|
+
return `${hours}h ${minutes}min`;
|
|
80
|
+
} else {
|
|
81
|
+
return `${minutes}min`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Affiche les infos de manière stylisée
|
|
87
|
+
*/
|
|
88
|
+
function displayTokenInfo(info) {
|
|
89
|
+
console.log('\n' + '='.repeat(50));
|
|
90
|
+
console.log(' 📊 Z.AI - UTILISATION DES TOKENS');
|
|
91
|
+
console.log('='.repeat(50));
|
|
92
|
+
|
|
93
|
+
// Barre de progression visuelle
|
|
94
|
+
const barLength = 30;
|
|
95
|
+
const filled = Math.round((info.percentage / 100) * barLength);
|
|
96
|
+
const empty = barLength - filled;
|
|
97
|
+
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
98
|
+
|
|
99
|
+
console.log(`\n Progression: [${bar}] ${info.percentage}%`);
|
|
100
|
+
console.log(`\n 📈 Utilisé: ${formatNumber(info.currentValue)} tokens`);
|
|
101
|
+
console.log(` 📉 Restant: ${formatNumber(info.remaining)} tokens`);
|
|
102
|
+
console.log(` 🎯 Limite: ${formatNumber(info.usage)} tokens`);
|
|
103
|
+
|
|
104
|
+
const timeRemaining = getTimeRemaining(info.nextResetTime);
|
|
105
|
+
console.log(`\n ⏱️ Reset dans: ${timeRemaining}`);
|
|
106
|
+
console.log(` 📅 Prochain reset: ${formatDate(info.nextResetTime)}`);
|
|
107
|
+
|
|
108
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Point d'entrée
|
|
112
|
+
async function main() {
|
|
113
|
+
try {
|
|
114
|
+
const tokenInfo = await getTokenLimit();
|
|
115
|
+
displayTokenInfo(tokenInfo);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('❌ Erreur:', error.message);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zusage",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "CLI tool to monitor Z.ai token usage for Claude Code coding plans",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"zusage": "./bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "node bin/index.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"zai",
|
|
17
|
+
"claude",
|
|
18
|
+
"token",
|
|
19
|
+
"usage",
|
|
20
|
+
"monitor",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"author": "lab34",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/lab34/zusage.git"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/lab34/zusage/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/lab34/zusage#readme",
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0"
|
|
35
|
+
}
|
|
36
|
+
}
|