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.
@@ -1,4 +1,5 @@
1
-
2
- > ccusage-collector@0.1.0 build /Users/didi/Documents/Code/MyCCusage/packages/ccusage-collector
3
- > tsc
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. Basic sync (run once)
25
+ ### 1. Interactive Configuration
26
26
 
27
27
  ```bash
28
- ccusage-collector --api-key=your-api-key --endpoint=https://example.com/api/usage-sync
28
+ ccusage-collector config
29
29
  ```
30
30
 
31
- ### 2. Scheduled sync (recommended - runs in background)
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 -- --api-key=your-api-key --endpoint=https://example.com/api/usage-sync --schedule="0 */4 * * *"
39
+ pm2 start ccusage-collector -- start
35
40
  ```
36
41
 
37
- ### 3. Test data collection (dry run)
42
+ ### 3. Check Status
38
43
 
39
44
  ```bash
40
- ccusage-collector --api-key=test --endpoint=https://example.com/api/usage-sync --dry-run
45
+ ccusage-collector status
46
+ pm2 status
41
47
  ```
42
48
 
43
- ## CLI Options
49
+ ## Available Commands
44
50
 
45
- | Option | Description | Required | Default |
46
- |--------|-------------|----------|---------|
47
- | `-k, --api-key <key>` | API key for authentication | Yes | - |
48
- | `-e, --endpoint <url>` | API endpoint URL | Yes | - |
49
- | `-s, --schedule <cron>` | Cron schedule for periodic sync | No | - |
50
- | `-r, --max-retries <number>` | Maximum retry attempts | No | 3 |
51
- | `-d, --retry-delay <ms>` | Delay between retries (ms) | No | 1000 |
52
- | `--dry-run` | Collect data but don't sync | No | false |
53
- | `-h, --help` | Show help | No | - |
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
- ## Usage Examples
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 --api-key=sk-1234567890abcdef --endpoint=https://myccusage.example.com/api/usage-sync
68
+ ccusage-collector config
61
69
  ```
62
70
 
63
- ### Scheduled sync (every 6 hours) - Background execution
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
- ccusage-collector \
74
- --api-key=test \
75
- --endpoint=https://myccusage.example.com/api/usage-sync \
76
- --dry-run
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
- ## Cron Schedule Examples
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
- | Schedule | Description |
82
- |----------|-------------|
83
- | `"0 */4 * * *"` | Every 4 hours |
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 Run Collector
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 -- --api-key=your-secret-api-key-here --endpoint=https://your-domain.com/api/usage-sync --schedule="0 */4 * * *"
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
- - Raw usage data for detailed analysis
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
- For reliable background execution, use PM2 to manage the collector process:
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
- ### Start Background Sync
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
- ### Control Process
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
- ### Auto-start on Boot
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
- **"ccusage command not found"**
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
- **"Authentication failed"**
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
- **"Connection refused"**
185
- - Verify endpoint URL is correct and accessible
186
- - Check that your dashboard is running and deployed
236
+ **โŒ "Connection refused"**
237
+ - Check endpoint URL in configuration
238
+ - Verify your dashboard is running and accessible
187
239
 
188
- **"Invalid cron expression"**
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
- # Enable verbose logging
195
- DEBUG=ccusage-collector ccusage-collector --api-key=... --endpoint=...
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 --dry-run --api-key=test --endpoint=http://localhost:3000
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.2.0');
11
+ .version('0.3.1');
12
+ // Config command - Interactive configuration
9
13
  program
10
- .option('-k, --api-key <key>', 'API key for authentication')
11
- .option('-e, --endpoint <url>', 'API endpoint URL')
12
- .option('-s, --schedule <cron>', `Cron schedule for periodic sync
13
- Examples:
14
- "0 */4 * * *" - Every 4 hours
15
- "*/10 * * * *" - Every 10 minutes`)
16
- .option('-r, --max-retries <number>', 'Maximum number of retry attempts', '3')
17
- .option('-d, --retry-delay <ms>', 'Delay between retry attempts in milliseconds', '1000')
18
- .option('--dry-run', 'Collect data but don\'t sync to server')
19
- .action(async (options) => {
20
- // Validate required options
21
- if (!options.apiKey) {
22
- console.error('Error: API key is required (--api-key)');
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
- if (!options.endpoint) {
26
- console.error('Error: API endpoint is required (--endpoint)');
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 config = {
30
- apiKey: options.apiKey,
31
- endpoint: options.endpoint,
32
- maxRetries: parseInt(options.maxRetries),
33
- retryDelay: parseInt(options.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(config);
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:', JSON.stringify(data, null, 2));
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
- if (options.schedule) {
49
- console.log(`Starting scheduled sync with cron: ${options.schedule}`);
50
- // Validate cron expression
51
- if (!cron.validate(options.schedule)) {
52
- console.error('Error: Invalid cron expression');
53
- process.exit(1);
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
- // Run once immediately
56
- console.log('Running initial sync...');
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
- // Schedule periodic runs
59
- cron.schedule(options.schedule, async () => {
60
- console.log(`\n[${new Date().toISOString()}] Running scheduled sync...`);
61
- await collector.run();
62
- });
63
- console.log('Scheduled sync is running. Press Ctrl+C to stop.');
64
- // Keep the process running
65
- process.on('SIGINT', () => {
66
- console.log('\nStopping scheduled sync...');
67
- process.exit(0);
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
- // Run once
72
- await collector.run();
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":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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"}