ccusage-collector 0.2.0 โ 0.3.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/.turbo/turbo-build.log +5 -4
- package/LICENSE +21 -0
- package/README.md +135 -75
- package/dist/cli.js +172 -46
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +97 -0
- package/dist/config.js.map +1 -0
- package/dist/interactive-config.d.ts +7 -0
- package/dist/interactive-config.d.ts.map +1 -0
- package/dist/interactive-config.js +150 -0
- package/dist/interactive-config.js.map +1 -0
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/device-info.d.ts +1 -0
- package/dist/utils/device-info.d.ts.map +1 -1
- package/dist/utils/device-info.js +26 -2
- package/dist/utils/device-info.js.map +1 -1
- package/package.json +15 -16
- package/src/cli.ts +195 -49
- package/src/config.ts +121 -0
- package/src/interactive-config.ts +168 -0
- package/src/types.ts +0 -1
- package/src/utils/device-info.ts +29 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> ccusage-collector@0.2.0 build /Users/didi/Documents/Code/MyCCusage/packages/ccusage-collector
|
|
4
|
+
> tsc
|
|
5
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Richard Wang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -22,69 +22,115 @@ npm install -g pm2
|
|
|
22
22
|
|
|
23
23
|
## Quick Start
|
|
24
24
|
|
|
25
|
-
### 1.
|
|
25
|
+
### 1. Interactive Configuration
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
ccusage-collector
|
|
28
|
+
ccusage-collector config
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
This will prompt you for:
|
|
32
|
+
- **API Key** (hidden input)
|
|
33
|
+
- **Dashboard URL** (domain only, e.g., https://your-app.com)
|
|
34
|
+
- **Sync Schedule** (user-friendly options like "Every 4 hours")
|
|
35
|
+
|
|
36
|
+
### 2. Start Background Sync
|
|
32
37
|
|
|
33
38
|
```bash
|
|
34
|
-
pm2 start ccusage-collector --
|
|
39
|
+
pm2 start ccusage-collector -- start
|
|
35
40
|
```
|
|
36
41
|
|
|
37
|
-
### 3.
|
|
42
|
+
### 3. Check Status
|
|
38
43
|
|
|
39
44
|
```bash
|
|
40
|
-
ccusage-collector
|
|
45
|
+
ccusage-collector status
|
|
46
|
+
pm2 status
|
|
41
47
|
```
|
|
42
48
|
|
|
43
|
-
##
|
|
49
|
+
## Available Commands
|
|
44
50
|
|
|
45
|
-
|
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
| `-V, --version` | Show version | No | - |
|
|
51
|
+
| Command | Description |
|
|
52
|
+
|---------|-------------|
|
|
53
|
+
| `ccusage-collector config` | Interactive configuration wizard |
|
|
54
|
+
| `ccusage-collector start` | Start scheduled sync (requires configuration) |
|
|
55
|
+
| `ccusage-collector sync` | Run single sync operation |
|
|
56
|
+
| `ccusage-collector sync --dry-run` | Test data collection without syncing |
|
|
57
|
+
| `ccusage-collector status` | Check configuration status |
|
|
58
|
+
| `ccusage-collector test` | Test configuration and connection |
|
|
59
|
+
| `ccusage-collector --help` | Show help |
|
|
55
60
|
|
|
56
|
-
##
|
|
61
|
+
## Configuration
|
|
62
|
+
|
|
63
|
+
Configuration is stored in `~/.ccusage-collector/config.json` with user-only file permissions.
|
|
64
|
+
|
|
65
|
+
### Interactive Configuration
|
|
57
66
|
|
|
58
|
-
### One-time sync
|
|
59
67
|
```bash
|
|
60
|
-
ccusage-collector
|
|
68
|
+
ccusage-collector config
|
|
61
69
|
```
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
pm2 start ccusage-collector -- \
|
|
66
|
-
--api-key=sk-1234567890abcdef \
|
|
67
|
-
--endpoint=https://myccusage.example.com/api/usage-sync \
|
|
68
|
-
--schedule="0 */6 * * *"
|
|
71
|
+
**Sample Configuration Session:**
|
|
69
72
|
```
|
|
73
|
+
๐ง ccusage-collector Configuration Wizard
|
|
74
|
+
=========================================
|
|
75
|
+
|
|
76
|
+
? Enter your API Key: ********** (hidden input)
|
|
77
|
+
? Enter your dashboard URL (domain only): https://myccusage.example.com
|
|
78
|
+
? Select sync frequency: Every 4 hours
|
|
79
|
+
|
|
80
|
+
๐งช Testing configuration...
|
|
81
|
+
โ
Configuration test passed!
|
|
82
|
+
โ
Configuration saved successfully!
|
|
83
|
+
|
|
84
|
+
๐ก Start with PM2:
|
|
85
|
+
pm2 start ccusage-collector -- start
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Available Schedule Options
|
|
89
|
+
|
|
90
|
+
- Every 30 minutes
|
|
91
|
+
- Every 1 hour
|
|
92
|
+
- Every 2 hours
|
|
93
|
+
- Every 4 hours (recommended)
|
|
94
|
+
- Every 8 hours
|
|
95
|
+
- Once daily
|
|
96
|
+
|
|
97
|
+
## Usage Examples
|
|
98
|
+
|
|
99
|
+
### Complete Setup Flow
|
|
70
100
|
|
|
71
|
-
### Test without syncing
|
|
72
101
|
```bash
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
# 1. Configure credentials
|
|
103
|
+
ccusage-collector config
|
|
104
|
+
|
|
105
|
+
# 2. Test the configuration
|
|
106
|
+
ccusage-collector test
|
|
107
|
+
|
|
108
|
+
# 3. Start background sync
|
|
109
|
+
pm2 start ccusage-collector -- start
|
|
110
|
+
|
|
111
|
+
# 4. Check status
|
|
112
|
+
ccusage-collector status
|
|
113
|
+
pm2 status
|
|
77
114
|
```
|
|
78
115
|
|
|
79
|
-
|
|
116
|
+
### Maintenance Commands
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# View sync logs
|
|
120
|
+
pm2 logs ccusage-collector
|
|
121
|
+
|
|
122
|
+
# Restart sync process
|
|
123
|
+
pm2 restart ccusage-collector
|
|
124
|
+
|
|
125
|
+
# Stop sync process
|
|
126
|
+
pm2 stop ccusage-collector
|
|
127
|
+
|
|
128
|
+
# Run one-time sync
|
|
129
|
+
ccusage-collector sync
|
|
80
130
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
| `"*/10 * * * *"` | Every 10 minutes |
|
|
85
|
-
| `"0 0 * * *"` | Daily at midnight |
|
|
86
|
-
| `"0 */1 * * *"` | Every hour |
|
|
87
|
-
| `"0 9,17 * * 1-5"` | 9 AM and 5 PM on weekdays |
|
|
131
|
+
# Test without syncing
|
|
132
|
+
ccusage-collector sync --dry-run
|
|
133
|
+
```
|
|
88
134
|
|
|
89
135
|
## Setup Guide
|
|
90
136
|
|
|
@@ -101,13 +147,17 @@ Set the `API_KEY` environment variable in your dashboard deployment:
|
|
|
101
147
|
API_KEY=your-secret-api-key-here
|
|
102
148
|
```
|
|
103
149
|
|
|
104
|
-
### 3. Install and
|
|
150
|
+
### 3. Install and Configure Collector
|
|
105
151
|
```bash
|
|
152
|
+
# Install globally
|
|
106
153
|
npm install -g ccusage-collector
|
|
107
154
|
npm install -g pm2
|
|
108
155
|
|
|
156
|
+
# Configure
|
|
157
|
+
ccusage-collector config
|
|
158
|
+
|
|
109
159
|
# Start background sync
|
|
110
|
-
pm2 start ccusage-collector --
|
|
160
|
+
pm2 start ccusage-collector -- start
|
|
111
161
|
```
|
|
112
162
|
|
|
113
163
|
## Data Collection
|
|
@@ -117,82 +167,90 @@ The collector:
|
|
|
117
167
|
- Collects historical data (not just recent usage)
|
|
118
168
|
- Syncs complete usage records to your dashboard
|
|
119
169
|
- Supports upsert operations (updates existing records)
|
|
170
|
+
- Generates unique device fingerprints for multi-device tracking
|
|
120
171
|
|
|
121
172
|
### Data Format
|
|
122
173
|
The collector syncs:
|
|
123
174
|
- Daily usage metrics (tokens, costs, models)
|
|
124
175
|
- Token breakdowns (input, output, cache creation/read)
|
|
125
176
|
- Model usage statistics
|
|
126
|
-
-
|
|
177
|
+
- Device information for multi-device analytics
|
|
127
178
|
|
|
128
179
|
## Error Handling
|
|
129
180
|
|
|
130
181
|
- **Network failures**: Automatic retry with exponential backoff
|
|
131
182
|
- **Authentication errors**: Immediate failure (no retry on 401/403)
|
|
132
183
|
- **Individual record failures**: Continues processing other records
|
|
184
|
+
- **Configuration errors**: Clear guidance on resolution
|
|
133
185
|
- **Detailed logging**: Clear error messages and debugging info
|
|
134
186
|
|
|
135
187
|
## Process Management with PM2
|
|
136
188
|
|
|
137
|
-
|
|
189
|
+
### Why PM2?
|
|
190
|
+
- **Automatic restart** if process crashes
|
|
191
|
+
- **Background execution** - no need to keep terminal open
|
|
192
|
+
- **Process monitoring** and logging
|
|
193
|
+
- **Prevents duplicate instances** - safe to run multiple times
|
|
194
|
+
- **Cross-platform** - works on Windows, Linux, and macOS
|
|
138
195
|
|
|
139
|
-
###
|
|
140
|
-
```bash
|
|
141
|
-
pm2 start ccusage-collector -- --api-key=your-key --endpoint=https://your-domain.com/api/usage-sync --schedule="0 */4 * * *"
|
|
142
|
-
```
|
|
196
|
+
### PM2 Commands
|
|
143
197
|
|
|
144
|
-
### Check Status
|
|
145
198
|
```bash
|
|
199
|
+
# Start background sync
|
|
200
|
+
pm2 start ccusage-collector -- start
|
|
201
|
+
|
|
202
|
+
# Check status
|
|
146
203
|
pm2 list # Show all processes
|
|
147
204
|
pm2 show ccusage-collector # Show detailed info
|
|
148
205
|
pm2 logs ccusage-collector # View logs
|
|
149
206
|
pm2 monit # Real-time monitoring
|
|
150
|
-
```
|
|
151
207
|
|
|
152
|
-
|
|
153
|
-
```bash
|
|
208
|
+
# Control process
|
|
154
209
|
pm2 stop ccusage-collector # Stop process
|
|
155
210
|
pm2 restart ccusage-collector # Restart process
|
|
156
211
|
pm2 delete ccusage-collector # Remove process
|
|
157
|
-
```
|
|
158
212
|
|
|
159
|
-
|
|
160
|
-
```bash
|
|
213
|
+
# Auto-start on boot
|
|
161
214
|
pm2 startup # Generate startup script
|
|
162
215
|
pm2 save # Save current process list
|
|
163
216
|
```
|
|
164
217
|
|
|
165
|
-
### Benefits of PM2
|
|
166
|
-
- **Automatic restart** if process crashes
|
|
167
|
-
- **Background execution** - no need to keep terminal open
|
|
168
|
-
- **Process monitoring** and logging
|
|
169
|
-
- **Prevents duplicate instances** - safe to run multiple times
|
|
170
|
-
- **Cross-platform** - works on Windows, Linux, and macOS
|
|
171
|
-
|
|
172
218
|
## Troubleshooting
|
|
173
219
|
|
|
174
220
|
### Common Issues
|
|
175
221
|
|
|
176
|
-
|
|
222
|
+
**โ Configuration not found**
|
|
223
|
+
```bash
|
|
224
|
+
# Run interactive configuration
|
|
225
|
+
ccusage-collector config
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**โ "ccusage command not found"**
|
|
177
229
|
- Ensure Claude Code CLI is installed and in PATH
|
|
178
230
|
- Run `npx ccusage --help` to verify installation
|
|
179
231
|
|
|
180
|
-
|
|
232
|
+
**โ "Authentication failed"**
|
|
233
|
+
- Run `ccusage-collector config` to update credentials
|
|
181
234
|
- Verify API key matches your dashboard configuration
|
|
182
|
-
- Check that API key is correctly set in dashboard environment
|
|
183
235
|
|
|
184
|
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
236
|
+
**โ "Connection refused"**
|
|
237
|
+
- Check endpoint URL in configuration
|
|
238
|
+
- Verify your dashboard is running and accessible
|
|
187
239
|
|
|
188
|
-
|
|
189
|
-
- Use online cron validators to test expressions
|
|
190
|
-
- Ensure cron format is correct (5 fields: minute hour day month weekday)
|
|
240
|
+
### Debug and Test
|
|
191
241
|
|
|
192
|
-
### Debug Mode
|
|
193
242
|
```bash
|
|
194
|
-
#
|
|
195
|
-
|
|
243
|
+
# Check configuration
|
|
244
|
+
ccusage-collector status
|
|
245
|
+
|
|
246
|
+
# Test configuration and connection
|
|
247
|
+
ccusage-collector test
|
|
248
|
+
|
|
249
|
+
# Test data collection only
|
|
250
|
+
ccusage-collector sync --dry-run
|
|
251
|
+
|
|
252
|
+
# View detailed logs
|
|
253
|
+
pm2 logs ccusage-collector
|
|
196
254
|
```
|
|
197
255
|
|
|
198
256
|
## Contributing
|
|
@@ -218,7 +276,8 @@ pnpm build
|
|
|
218
276
|
|
|
219
277
|
# Test CLI locally
|
|
220
278
|
pnpm cli --help
|
|
221
|
-
pnpm cli
|
|
279
|
+
pnpm cli config
|
|
280
|
+
pnpm cli status
|
|
222
281
|
|
|
223
282
|
# Run type checking
|
|
224
283
|
pnpm typecheck
|
|
@@ -239,4 +298,5 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
239
298
|
## Support
|
|
240
299
|
|
|
241
300
|
- ๐ [Report bugs](https://github.com/i-richardwang/MyCCusage/issues)
|
|
242
|
-
- ๐ก [Request features](https://github.com/i-richardwang/MyCCusage/issues)
|
|
301
|
+
- ๐ก [Request features](https://github.com/i-richardwang/MyCCusage/issues)
|
|
302
|
+
- ๐ [Documentation](https://github.com/i-richardwang/MyCCusage/blob/main/README.md)
|
package/dist/cli.js
CHANGED
|
@@ -2,74 +2,200 @@
|
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import * as cron from 'node-cron';
|
|
4
4
|
import { UsageCollector } from './collector.js';
|
|
5
|
+
import { ConfigManager } from './config.js';
|
|
6
|
+
import { InteractiveConfig } from './interactive-config.js';
|
|
7
|
+
const configManager = new ConfigManager();
|
|
5
8
|
program
|
|
6
9
|
.name('ccusage-collector')
|
|
7
10
|
.description('Collect and sync Claude Code usage statistics')
|
|
8
|
-
.version('0.
|
|
11
|
+
.version('0.3.1');
|
|
12
|
+
// Config command - Interactive configuration
|
|
9
13
|
program
|
|
10
|
-
.
|
|
11
|
-
.
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.
|
|
19
|
-
.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
.command('config')
|
|
15
|
+
.description('Configure API credentials and sync settings')
|
|
16
|
+
.action(async () => {
|
|
17
|
+
const interactiveConfig = new InteractiveConfig();
|
|
18
|
+
await interactiveConfig.runConfigurationWizard();
|
|
19
|
+
});
|
|
20
|
+
// Start command - Start scheduled sync
|
|
21
|
+
program
|
|
22
|
+
.command('start')
|
|
23
|
+
.description('Start scheduled sync (requires configuration)')
|
|
24
|
+
.action(async () => {
|
|
25
|
+
const config = configManager.loadConfig();
|
|
26
|
+
if (!config) {
|
|
27
|
+
configManager.showNoConfigMessage();
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const collectorConfig = {
|
|
31
|
+
apiKey: config.apiKey,
|
|
32
|
+
endpoint: config.endpoint,
|
|
33
|
+
maxRetries: config.maxRetries,
|
|
34
|
+
retryDelay: config.retryDelay
|
|
35
|
+
};
|
|
36
|
+
const collector = new UsageCollector(collectorConfig);
|
|
37
|
+
console.log(`๐ Starting scheduled sync: ${config.scheduleLabel}`);
|
|
38
|
+
console.log(`๐ Schedule: ${config.schedule}`);
|
|
39
|
+
// Validate cron expression
|
|
40
|
+
if (!cron.validate(config.schedule)) {
|
|
41
|
+
console.error('โ Invalid cron expression in configuration');
|
|
23
42
|
process.exit(1);
|
|
24
43
|
}
|
|
25
|
-
|
|
26
|
-
|
|
44
|
+
// Run once immediately
|
|
45
|
+
console.log('\nโณ Running initial sync...');
|
|
46
|
+
try {
|
|
47
|
+
await collector.run();
|
|
48
|
+
console.log('โ
Initial sync completed');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('โ Initial sync failed:', error instanceof Error ? error.message : error);
|
|
52
|
+
// Continue with scheduling even if initial sync fails
|
|
53
|
+
}
|
|
54
|
+
// Schedule periodic runs
|
|
55
|
+
cron.schedule(config.schedule, async () => {
|
|
56
|
+
console.log(`\n[${new Date().toISOString()}] โณ Running scheduled sync...`);
|
|
57
|
+
try {
|
|
58
|
+
await collector.run();
|
|
59
|
+
console.log('โ
Scheduled sync completed');
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('โ Scheduled sync failed:', error instanceof Error ? error.message : error);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
console.log('\n๐ Scheduled sync is running. Press Ctrl+C to stop.');
|
|
66
|
+
// Keep the process running
|
|
67
|
+
process.on('SIGINT', () => {
|
|
68
|
+
console.log('\n๐ Stopping scheduled sync...');
|
|
69
|
+
process.exit(0);
|
|
70
|
+
});
|
|
71
|
+
process.on('SIGTERM', () => {
|
|
72
|
+
console.log('\n๐ Received SIGTERM, stopping scheduled sync...');
|
|
73
|
+
process.exit(0);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
// Sync command - Run single sync
|
|
77
|
+
program
|
|
78
|
+
.command('sync')
|
|
79
|
+
.description('Run a single sync operation')
|
|
80
|
+
.option('--dry-run', 'Collect data but don\'t sync to server')
|
|
81
|
+
.action(async (options) => {
|
|
82
|
+
const config = configManager.loadConfig();
|
|
83
|
+
if (!config) {
|
|
84
|
+
configManager.showNoConfigMessage();
|
|
27
85
|
process.exit(1);
|
|
28
86
|
}
|
|
29
|
-
const
|
|
30
|
-
apiKey:
|
|
31
|
-
endpoint:
|
|
32
|
-
maxRetries:
|
|
33
|
-
retryDelay:
|
|
87
|
+
const collectorConfig = {
|
|
88
|
+
apiKey: config.apiKey,
|
|
89
|
+
endpoint: config.endpoint,
|
|
90
|
+
maxRetries: config.maxRetries,
|
|
91
|
+
retryDelay: config.retryDelay
|
|
34
92
|
};
|
|
35
|
-
const collector = new UsageCollector(
|
|
93
|
+
const collector = new UsageCollector(collectorConfig);
|
|
36
94
|
if (options.dryRun) {
|
|
37
|
-
console.log('Dry run mode: collecting data only');
|
|
95
|
+
console.log('๐งช Dry run mode: collecting data only');
|
|
38
96
|
try {
|
|
39
97
|
const data = await collector.collectUsageData();
|
|
40
|
-
console.log('Collected data:'
|
|
98
|
+
console.log('๐ Collected data:');
|
|
99
|
+
console.log(JSON.stringify(data, null, 2));
|
|
41
100
|
}
|
|
42
101
|
catch (error) {
|
|
43
|
-
console.error('Failed to collect data:', error instanceof Error ? error.message : error);
|
|
102
|
+
console.error('โ Failed to collect data:', error instanceof Error ? error.message : error);
|
|
44
103
|
process.exit(1);
|
|
45
104
|
}
|
|
46
105
|
return;
|
|
47
106
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
107
|
+
console.log('โณ Running single sync...');
|
|
108
|
+
try {
|
|
109
|
+
await collector.run();
|
|
110
|
+
console.log('โ
Sync completed successfully');
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('โ Sync failed:', error instanceof Error ? error.message : error);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// Status command - Check configuration and status
|
|
118
|
+
program
|
|
119
|
+
.command('status')
|
|
120
|
+
.description('Check configuration status')
|
|
121
|
+
.action(() => {
|
|
122
|
+
const config = configManager.loadConfig();
|
|
123
|
+
if (!config) {
|
|
124
|
+
console.log('โ No configuration found');
|
|
125
|
+
console.log(`๐ Expected location: ${configManager.getConfigPath()}`);
|
|
126
|
+
console.log('\n๐ Run configuration:');
|
|
127
|
+
console.log(' ccusage-collector config');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log('โ
Configuration found');
|
|
131
|
+
console.log(`๐ Config file: ${configManager.getConfigPath()}`);
|
|
132
|
+
console.log(`๐ Endpoint: ${config.endpoint}`);
|
|
133
|
+
console.log(`โฐ Schedule: ${config.scheduleLabel} (${config.schedule})`);
|
|
134
|
+
console.log(`๐ Max retries: ${config.maxRetries}`);
|
|
135
|
+
console.log(`โฑ๏ธ Retry delay: ${config.retryDelay}ms`);
|
|
136
|
+
console.log('\n๐ก Available commands:');
|
|
137
|
+
console.log(' ccusage-collector sync # Run single sync');
|
|
138
|
+
console.log(' ccusage-collector start # Start scheduled sync');
|
|
139
|
+
});
|
|
140
|
+
// Test command - Test configuration and connection
|
|
141
|
+
program
|
|
142
|
+
.command('test')
|
|
143
|
+
.description('Test configuration and connection')
|
|
144
|
+
.action(async () => {
|
|
145
|
+
const config = configManager.loadConfig();
|
|
146
|
+
if (!config) {
|
|
147
|
+
configManager.showNoConfigMessage();
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
const collectorConfig = {
|
|
151
|
+
apiKey: config.apiKey,
|
|
152
|
+
endpoint: config.endpoint,
|
|
153
|
+
maxRetries: config.maxRetries,
|
|
154
|
+
retryDelay: config.retryDelay
|
|
155
|
+
};
|
|
156
|
+
const collector = new UsageCollector(collectorConfig);
|
|
157
|
+
console.log('๐งช Testing configuration...');
|
|
158
|
+
try {
|
|
159
|
+
console.log('๐ Testing data collection...');
|
|
160
|
+
const data = await collector.collectUsageData();
|
|
161
|
+
if (!data || !data.daily || data.daily.length === 0) {
|
|
162
|
+
console.log('โ ๏ธ No usage data found. Make sure you have Claude Code usage to sync.');
|
|
54
163
|
}
|
|
55
|
-
|
|
56
|
-
|
|
164
|
+
else {
|
|
165
|
+
console.log(`โ
Found ${data.daily.length} days of usage data`);
|
|
166
|
+
}
|
|
167
|
+
console.log('๐ Testing connection to endpoint...');
|
|
168
|
+
console.log('โณ Running test sync...');
|
|
57
169
|
await collector.run();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
170
|
+
console.log('โ
Test completed successfully!');
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error('โ Test failed:', error instanceof Error ? error.message : error);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// Default action (no command specified)
|
|
178
|
+
program.action(() => {
|
|
179
|
+
console.log('ccusage-collector - Claude Code Usage Statistics Collector\n');
|
|
180
|
+
const config = configManager.loadConfig();
|
|
181
|
+
if (!config) {
|
|
182
|
+
console.log('โ No configuration found\n');
|
|
183
|
+
console.log('๐ง Get started:');
|
|
184
|
+
console.log(' ccusage-collector config # Configure credentials and settings');
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log('๐ Other commands:');
|
|
187
|
+
console.log(' ccusage-collector --help # Show all available commands');
|
|
69
188
|
}
|
|
70
189
|
else {
|
|
71
|
-
|
|
72
|
-
|
|
190
|
+
console.log('โ
Configuration found\n');
|
|
191
|
+
console.log('๐ Common commands:');
|
|
192
|
+
console.log(' ccusage-collector sync # Run single sync');
|
|
193
|
+
console.log(' ccusage-collector start # Start scheduled sync');
|
|
194
|
+
console.log(' ccusage-collector status # Check status');
|
|
195
|
+
console.log(' ccusage-collector test # Test configuration');
|
|
196
|
+
console.log('');
|
|
197
|
+
console.log('๐ Other commands:');
|
|
198
|
+
console.log(' ccusage-collector --help # Show all available commands');
|
|
73
199
|
}
|
|
74
200
|
});
|
|
75
201
|
program.parse();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;
|
|
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,26 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
endpoint: string;
|
|
4
|
+
schedule: string;
|
|
5
|
+
scheduleLabel: string;
|
|
6
|
+
maxRetries: number;
|
|
7
|
+
retryDelay: number;
|
|
8
|
+
deviceId?: string;
|
|
9
|
+
deviceName?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const SCHEDULE_OPTIONS: {
|
|
12
|
+
value: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}[];
|
|
15
|
+
export declare class ConfigManager {
|
|
16
|
+
private configDir;
|
|
17
|
+
private configPath;
|
|
18
|
+
constructor();
|
|
19
|
+
hasConfig(): boolean;
|
|
20
|
+
loadConfig(): Config | null;
|
|
21
|
+
saveConfig(config: Config): void;
|
|
22
|
+
getConfigPath(): string;
|
|
23
|
+
updateDeviceInfo(deviceId: string, deviceName: string): void;
|
|
24
|
+
showNoConfigMessage(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,gBAAgB;;;GAO5B,CAAA;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,UAAU,CAAQ;;IAO1B,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,MAAM,GAAG,IAAI;IA4B3B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAoBhC,aAAa,IAAI,MAAM;IAIvB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAoB5D,mBAAmB,IAAI,IAAI;CAW5B"}
|