@kaitranntt/ccs 5.15.0 → 5.16.0-dev.10

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.
Files changed (159) hide show
  1. package/README.md +3 -5
  2. package/VERSION +1 -1
  3. package/dist/cliproxy/account-manager.d.ts.map +1 -1
  4. package/dist/cliproxy/account-manager.js +35 -0
  5. package/dist/cliproxy/account-manager.js.map +1 -1
  6. package/dist/cliproxy/auth-handler.d.ts.map +1 -1
  7. package/dist/cliproxy/auth-handler.js +23 -20
  8. package/dist/cliproxy/auth-handler.js.map +1 -1
  9. package/dist/cliproxy/binary-manager.d.ts +25 -0
  10. package/dist/cliproxy/binary-manager.d.ts.map +1 -1
  11. package/dist/cliproxy/binary-manager.js +86 -5
  12. package/dist/cliproxy/binary-manager.js.map +1 -1
  13. package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -1
  14. package/dist/cliproxy/cliproxy-executor.js +45 -17
  15. package/dist/cliproxy/cliproxy-executor.js.map +1 -1
  16. package/dist/cliproxy/config-generator.d.ts +21 -0
  17. package/dist/cliproxy/config-generator.d.ts.map +1 -1
  18. package/dist/cliproxy/config-generator.js +127 -18
  19. package/dist/cliproxy/config-generator.js.map +1 -1
  20. package/dist/cliproxy/index.d.ts +8 -2
  21. package/dist/cliproxy/index.d.ts.map +1 -1
  22. package/dist/cliproxy/index.js +25 -2
  23. package/dist/cliproxy/index.js.map +1 -1
  24. package/dist/cliproxy/openai-compat-manager.d.ts +46 -0
  25. package/dist/cliproxy/openai-compat-manager.d.ts.map +1 -0
  26. package/dist/cliproxy/openai-compat-manager.js +191 -0
  27. package/dist/cliproxy/openai-compat-manager.js.map +1 -0
  28. package/dist/cliproxy/service-manager.d.ts +43 -0
  29. package/dist/cliproxy/service-manager.d.ts.map +1 -0
  30. package/dist/cliproxy/service-manager.js +220 -0
  31. package/dist/cliproxy/service-manager.js.map +1 -0
  32. package/dist/cliproxy/stats-fetcher.d.ts +59 -0
  33. package/dist/cliproxy/stats-fetcher.d.ts.map +1 -0
  34. package/dist/cliproxy/stats-fetcher.js +134 -0
  35. package/dist/cliproxy/stats-fetcher.js.map +1 -0
  36. package/dist/commands/cliproxy-command.d.ts.map +1 -1
  37. package/dist/commands/cliproxy-command.js +50 -19
  38. package/dist/commands/cliproxy-command.js.map +1 -1
  39. package/dist/commands/config-command.d.ts +1 -0
  40. package/dist/commands/config-command.d.ts.map +1 -1
  41. package/dist/commands/config-command.js +24 -1
  42. package/dist/commands/config-command.js.map +1 -1
  43. package/dist/commands/install-command.d.ts +2 -2
  44. package/dist/commands/install-command.d.ts.map +1 -1
  45. package/dist/commands/install-command.js +9 -6
  46. package/dist/commands/install-command.js.map +1 -1
  47. package/dist/commands/migrate-command.d.ts.map +1 -1
  48. package/dist/commands/migrate-command.js +20 -20
  49. package/dist/commands/migrate-command.js.map +1 -1
  50. package/dist/commands/shell-completion-command.d.ts.map +1 -1
  51. package/dist/commands/shell-completion-command.js +10 -9
  52. package/dist/commands/shell-completion-command.js.map +1 -1
  53. package/dist/commands/sync-command.d.ts.map +1 -1
  54. package/dist/commands/sync-command.js +5 -4
  55. package/dist/commands/sync-command.js.map +1 -1
  56. package/dist/commands/update-command.d.ts.map +1 -1
  57. package/dist/commands/update-command.js +41 -40
  58. package/dist/commands/update-command.js.map +1 -1
  59. package/dist/commands/version-command.d.ts +1 -1
  60. package/dist/commands/version-command.d.ts.map +1 -1
  61. package/dist/commands/version-command.js +18 -17
  62. package/dist/commands/version-command.js.map +1 -1
  63. package/dist/config/migration-manager.d.ts.map +1 -1
  64. package/dist/config/migration-manager.js +4 -7
  65. package/dist/config/migration-manager.js.map +1 -1
  66. package/dist/config/unified-config-loader.d.ts +1 -0
  67. package/dist/config/unified-config-loader.d.ts.map +1 -1
  68. package/dist/config/unified-config-loader.js +27 -2
  69. package/dist/config/unified-config-loader.js.map +1 -1
  70. package/dist/config/unified-config-types.d.ts +2 -0
  71. package/dist/config/unified-config-types.d.ts.map +1 -1
  72. package/dist/config/unified-config-types.js +5 -5
  73. package/dist/config/unified-config-types.js.map +1 -1
  74. package/dist/delegation/delegation-handler.d.ts.map +1 -1
  75. package/dist/delegation/delegation-handler.js +6 -5
  76. package/dist/delegation/delegation-handler.js.map +1 -1
  77. package/dist/delegation/headless-executor.d.ts.map +1 -1
  78. package/dist/delegation/headless-executor.js +14 -14
  79. package/dist/delegation/headless-executor.js.map +1 -1
  80. package/dist/management/doctor.d.ts +6 -2
  81. package/dist/management/doctor.d.ts.map +1 -1
  82. package/dist/management/doctor.js +130 -28
  83. package/dist/management/doctor.js.map +1 -1
  84. package/dist/management/recovery-manager.d.ts.map +1 -1
  85. package/dist/management/recovery-manager.js +3 -2
  86. package/dist/management/recovery-manager.js.map +1 -1
  87. package/dist/management/shared-manager.d.ts.map +1 -1
  88. package/dist/management/shared-manager.js +19 -18
  89. package/dist/management/shared-manager.js.map +1 -1
  90. package/dist/types/config.d.ts +13 -0
  91. package/dist/types/config.d.ts.map +1 -1
  92. package/dist/types/config.js.map +1 -1
  93. package/dist/ui/assets/accounts-BeL69fgi.js +1 -0
  94. package/dist/ui/assets/analytics-CAiq9C19.js +64 -0
  95. package/dist/ui/assets/{api-LYILKXgM.js → api-CvY-Z9t4.js} +1 -1
  96. package/dist/ui/assets/cliproxy-DbfUkLCy.js +1 -0
  97. package/dist/ui/assets/cliproxy-control-panel-DTiBzA5u.js +1 -0
  98. package/dist/ui/assets/{code-editor-HkboCFlD.js → code-editor-xnukAIwJ.js} +11 -11
  99. package/dist/ui/assets/health-D29me3pE.js +1 -0
  100. package/dist/ui/assets/icons-Alnq4BWm.js +1 -0
  101. package/dist/ui/assets/index-CVMaabkX.js +12 -0
  102. package/dist/ui/assets/index-DMEwxqAV.css +1 -0
  103. package/dist/ui/assets/providers/agy.png +0 -0
  104. package/dist/ui/assets/providers/gemini-color.svg +1 -0
  105. package/dist/ui/assets/providers/openai.svg +1 -0
  106. package/dist/ui/assets/providers/qwen-color.svg +1 -0
  107. package/dist/ui/assets/{radix-ui-CgfZoNEt.js → radix-ui-OFtPgiRV.js} +1 -1
  108. package/dist/ui/assets/{settings-DUCWbKbP.js → settings-C-IIOnQo.js} +1 -1
  109. package/dist/ui/assets/{shared-Da5f_jsc.js → shared-DRWHGJPD.js} +1 -1
  110. package/dist/ui/assets/{tanstack-BgSYOn90.js → tanstack-DMWkeNzM.js} +1 -1
  111. package/dist/ui/index.html +5 -5
  112. package/dist/utils/claude-dir-installer.js +3 -3
  113. package/dist/utils/claude-dir-installer.js.map +1 -1
  114. package/dist/utils/claude-symlink-manager.js +3 -3
  115. package/dist/utils/claude-symlink-manager.js.map +1 -1
  116. package/dist/utils/config-manager.js +10 -10
  117. package/dist/utils/config-manager.js.map +1 -1
  118. package/dist/utils/error-manager.d.ts.map +1 -1
  119. package/dist/utils/error-manager.js +11 -4
  120. package/dist/utils/error-manager.js.map +1 -1
  121. package/dist/utils/platform-commands.d.ts +53 -0
  122. package/dist/utils/platform-commands.d.ts.map +1 -0
  123. package/dist/utils/platform-commands.js +189 -0
  124. package/dist/utils/platform-commands.js.map +1 -0
  125. package/dist/utils/update-checker.d.ts.map +1 -1
  126. package/dist/utils/update-checker.js +5 -5
  127. package/dist/utils/update-checker.js.map +1 -1
  128. package/dist/web-server/data-aggregator.d.ts +11 -1
  129. package/dist/web-server/data-aggregator.d.ts.map +1 -1
  130. package/dist/web-server/data-aggregator.js +87 -1
  131. package/dist/web-server/data-aggregator.js.map +1 -1
  132. package/dist/web-server/routes.d.ts.map +1 -1
  133. package/dist/web-server/routes.js +329 -4
  134. package/dist/web-server/routes.js.map +1 -1
  135. package/dist/web-server/shutdown.d.ts.map +1 -1
  136. package/dist/web-server/shutdown.js +4 -3
  137. package/dist/web-server/shutdown.js.map +1 -1
  138. package/dist/web-server/usage-disk-cache.d.ts +3 -2
  139. package/dist/web-server/usage-disk-cache.d.ts.map +1 -1
  140. package/dist/web-server/usage-disk-cache.js +11 -9
  141. package/dist/web-server/usage-disk-cache.js.map +1 -1
  142. package/dist/web-server/usage-routes.d.ts.map +1 -1
  143. package/dist/web-server/usage-routes.js +118 -17
  144. package/dist/web-server/usage-routes.js.map +1 -1
  145. package/dist/web-server/usage-types.d.ts +13 -0
  146. package/dist/web-server/usage-types.d.ts.map +1 -1
  147. package/dist/web-server/websocket.d.ts.map +1 -1
  148. package/dist/web-server/websocket.js +7 -6
  149. package/dist/web-server/websocket.js.map +1 -1
  150. package/package.json +3 -3
  151. package/scripts/verify-bundle.js +11 -4
  152. package/dist/ui/assets/accounts-CTh48XsV.js +0 -1
  153. package/dist/ui/assets/analytics-CeU8ZE3O.js +0 -64
  154. package/dist/ui/assets/cliproxy-Cy2Bjv-c.js +0 -1
  155. package/dist/ui/assets/health-DyAiAnv0.js +0 -1
  156. package/dist/ui/assets/icons-CRbZgamU.js +0 -1
  157. package/dist/ui/assets/index-BIVAVDH5.js +0 -10
  158. package/dist/ui/assets/index-vojI8oaQ.css +0 -1
  159. package/dist/ui/assets/table-BCRYixSo.js +0 -1
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ /**
3
+ * CLIProxy Service Manager
4
+ *
5
+ * Manages CLIProxyAPI as a background service for the CCS dashboard.
6
+ * Ensures the proxy is running when needed for:
7
+ * - Control Panel integration (management.html)
8
+ * - Stats fetching
9
+ * - OAuth flows
10
+ *
11
+ * Unlike cliproxy-executor.ts which runs proxy per-session,
12
+ * this module manages a persistent background instance.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.getServiceStatus = exports.stopCliproxyService = exports.ensureCliproxyService = void 0;
39
+ const child_process_1 = require("child_process");
40
+ const net = __importStar(require("net"));
41
+ const binary_manager_1 = require("./binary-manager");
42
+ const config_generator_1 = require("./config-generator");
43
+ const stats_fetcher_1 = require("./stats-fetcher");
44
+ /** Background proxy process reference */
45
+ let proxyProcess = null;
46
+ /** Cleanup registered flag */
47
+ let cleanupRegistered = false;
48
+ /**
49
+ * Wait for TCP port to become available
50
+ */
51
+ async function waitForPort(port, timeout = 5000, pollInterval = 100) {
52
+ const start = Date.now();
53
+ while (Date.now() - start < timeout) {
54
+ try {
55
+ await new Promise((resolve, reject) => {
56
+ const socket = net.createConnection({ port, host: '127.0.0.1' }, () => {
57
+ socket.destroy();
58
+ resolve();
59
+ });
60
+ socket.on('error', (err) => {
61
+ socket.destroy();
62
+ reject(err);
63
+ });
64
+ socket.setTimeout(500, () => {
65
+ socket.destroy();
66
+ reject(new Error('Connection timeout'));
67
+ });
68
+ });
69
+ return true; // Connection successful
70
+ }
71
+ catch {
72
+ await new Promise((r) => setTimeout(r, pollInterval));
73
+ }
74
+ }
75
+ return false;
76
+ }
77
+ /**
78
+ * Register cleanup handlers to stop proxy on process exit
79
+ */
80
+ function registerCleanup() {
81
+ if (cleanupRegistered)
82
+ return;
83
+ const cleanup = () => {
84
+ if (proxyProcess && !proxyProcess.killed) {
85
+ proxyProcess.kill('SIGTERM');
86
+ proxyProcess = null;
87
+ }
88
+ };
89
+ process.once('exit', cleanup);
90
+ process.once('SIGTERM', cleanup);
91
+ process.once('SIGINT', cleanup);
92
+ cleanupRegistered = true;
93
+ }
94
+ /**
95
+ * Ensure CLIProxy service is running
96
+ *
97
+ * If proxy is already running, returns immediately.
98
+ * If not, spawns a new background instance.
99
+ *
100
+ * @param port CLIProxy port (default: 8317)
101
+ * @param verbose Show debug output
102
+ * @returns Result indicating success and whether it was already running
103
+ */
104
+ async function ensureCliproxyService(port = config_generator_1.CLIPROXY_DEFAULT_PORT, verbose = false) {
105
+ const log = (msg) => {
106
+ if (verbose) {
107
+ console.error(`[cliproxy-service] ${msg}`);
108
+ }
109
+ };
110
+ // Check if already running (from another process or previous start)
111
+ log(`Checking if CLIProxy is running on port ${port}...`);
112
+ const running = await (0, stats_fetcher_1.isCliproxyRunning)(port);
113
+ // Check if config needs update (even if running)
114
+ let configRegenerated = false;
115
+ if ((0, config_generator_1.configNeedsRegeneration)()) {
116
+ log('Config outdated, regenerating...');
117
+ (0, config_generator_1.regenerateConfig)(port);
118
+ configRegenerated = true;
119
+ }
120
+ if (running) {
121
+ log('CLIProxy already running');
122
+ if (configRegenerated) {
123
+ log('Config was updated - running instance will use new config on next restart');
124
+ }
125
+ return { started: true, alreadyRunning: true, port, configRegenerated };
126
+ }
127
+ // Need to start new instance
128
+ log('CLIProxy not running, starting background instance...');
129
+ // 1. Ensure binary exists
130
+ let binaryPath;
131
+ try {
132
+ binaryPath = await (0, binary_manager_1.ensureCLIProxyBinary)(verbose);
133
+ log(`Binary ready: ${binaryPath}`);
134
+ }
135
+ catch (error) {
136
+ const err = error;
137
+ return {
138
+ started: false,
139
+ alreadyRunning: false,
140
+ port,
141
+ error: `Failed to prepare binary: ${err.message}`,
142
+ };
143
+ }
144
+ // 2. Ensure/regenerate config if needed
145
+ let configPath;
146
+ if ((0, config_generator_1.configNeedsRegeneration)()) {
147
+ log('Config needs regeneration, updating...');
148
+ configPath = (0, config_generator_1.regenerateConfig)(port);
149
+ }
150
+ else {
151
+ // generateConfig only creates if doesn't exist
152
+ configPath = (0, config_generator_1.generateConfig)('gemini', port); // Provider doesn't matter for unified config
153
+ }
154
+ log(`Config ready: ${configPath}`);
155
+ // 3. Spawn background process
156
+ const proxyArgs = ['--config', configPath];
157
+ log(`Spawning: ${binaryPath} ${proxyArgs.join(' ')}`);
158
+ proxyProcess = (0, child_process_1.spawn)(binaryPath, proxyArgs, {
159
+ stdio: ['ignore', verbose ? 'pipe' : 'ignore', verbose ? 'pipe' : 'ignore'],
160
+ detached: true, // Allow process to run independently
161
+ });
162
+ // Forward output in verbose mode
163
+ if (verbose) {
164
+ proxyProcess.stdout?.on('data', (data) => {
165
+ process.stderr.write(`[cliproxy] ${data.toString()}`);
166
+ });
167
+ proxyProcess.stderr?.on('data', (data) => {
168
+ process.stderr.write(`[cliproxy-err] ${data.toString()}`);
169
+ });
170
+ }
171
+ // Don't let this process prevent parent from exiting
172
+ proxyProcess.unref();
173
+ // Handle spawn errors
174
+ proxyProcess.on('error', (error) => {
175
+ log(`Spawn error: ${error.message}`);
176
+ });
177
+ // Register cleanup handlers
178
+ registerCleanup();
179
+ // 4. Wait for proxy to be ready
180
+ log(`Waiting for CLIProxy on port ${port}...`);
181
+ const ready = await waitForPort(port, 5000);
182
+ if (!ready) {
183
+ // Kill failed process
184
+ if (proxyProcess && !proxyProcess.killed) {
185
+ proxyProcess.kill('SIGTERM');
186
+ proxyProcess = null;
187
+ }
188
+ return {
189
+ started: false,
190
+ alreadyRunning: false,
191
+ port,
192
+ error: `CLIProxy failed to start within 5s on port ${port}`,
193
+ };
194
+ }
195
+ log(`CLIProxy service started on port ${port}`);
196
+ return { started: true, alreadyRunning: false, port };
197
+ }
198
+ exports.ensureCliproxyService = ensureCliproxyService;
199
+ /**
200
+ * Stop the managed CLIProxy service
201
+ */
202
+ function stopCliproxyService() {
203
+ if (proxyProcess && !proxyProcess.killed) {
204
+ proxyProcess.kill('SIGTERM');
205
+ proxyProcess = null;
206
+ return true;
207
+ }
208
+ return false;
209
+ }
210
+ exports.stopCliproxyService = stopCliproxyService;
211
+ /**
212
+ * Get service status
213
+ */
214
+ async function getServiceStatus(port = config_generator_1.CLIPROXY_DEFAULT_PORT) {
215
+ const running = await (0, stats_fetcher_1.isCliproxyRunning)(port);
216
+ const managedByUs = proxyProcess !== null && !proxyProcess.killed;
217
+ return { running, managedByUs, port };
218
+ }
219
+ exports.getServiceStatus = getServiceStatus;
220
+ //# sourceMappingURL=service-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-manager.js","sourceRoot":"","sources":["../../src/cliproxy/service-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * CLIProxyAPI Stats Fetcher
3
+ *
4
+ * Fetches usage statistics from CLIProxyAPI's management API.
5
+ * Requires usage-statistics-enabled: true in config.yaml.
6
+ */
7
+ /** Usage statistics from CLIProxyAPI */
8
+ export interface CliproxyStats {
9
+ /** Total number of requests processed */
10
+ totalRequests: number;
11
+ /** Token counts */
12
+ tokens: {
13
+ input: number;
14
+ output: number;
15
+ total: number;
16
+ };
17
+ /** Requests grouped by model */
18
+ requestsByModel: Record<string, number>;
19
+ /** Requests grouped by provider */
20
+ requestsByProvider: Record<string, number>;
21
+ /** Number of quota exceeded (429) events */
22
+ quotaExceededCount: number;
23
+ /** Number of request retries */
24
+ retryCount: number;
25
+ /** Timestamp of stats collection */
26
+ collectedAt: string;
27
+ }
28
+ /**
29
+ * Fetch usage statistics from CLIProxyAPI management API
30
+ * @param port CLIProxyAPI port (default: 8317)
31
+ * @returns Stats object or null if unavailable
32
+ */
33
+ export declare function fetchCliproxyStats(port?: number): Promise<CliproxyStats | null>;
34
+ /** OpenAI-compatible model object from /v1/models endpoint */
35
+ export interface CliproxyModel {
36
+ id: string;
37
+ object: string;
38
+ created: number;
39
+ owned_by: string;
40
+ }
41
+ /** Categorized models response for UI */
42
+ export interface CliproxyModelsResponse {
43
+ models: CliproxyModel[];
44
+ byCategory: Record<string, CliproxyModel[]>;
45
+ totalCount: number;
46
+ }
47
+ /**
48
+ * Fetch available models from CLIProxyAPI /v1/models endpoint
49
+ * @param port CLIProxyAPI port (default: 8317)
50
+ * @returns Categorized models or null if unavailable
51
+ */
52
+ export declare function fetchCliproxyModels(port?: number): Promise<CliproxyModelsResponse | null>;
53
+ /**
54
+ * Check if CLIProxyAPI is running and responsive
55
+ * @param port CLIProxyAPI port (default: 8317)
56
+ * @returns true if proxy is running
57
+ */
58
+ export declare function isCliproxyRunning(port?: number): Promise<boolean>;
59
+ //# sourceMappingURL=stats-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats-fetcher.d.ts","sourceRoot":"","sources":["../../src/cliproxy/stats-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,gCAAgC;IAChC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,mCAAmC;IACnC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB;AA2BD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,GAAE,MAA8B,GACnC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAuD/B;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAQD,yCAAyC;AACzC,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,GAAE,MAA8B,GACnC,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CA6CxC;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,MAA8B,GAAG,OAAO,CAAC,OAAO,CAAC,CAe9F"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * CLIProxyAPI Stats Fetcher
4
+ *
5
+ * Fetches usage statistics from CLIProxyAPI's management API.
6
+ * Requires usage-statistics-enabled: true in config.yaml.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.isCliproxyRunning = exports.fetchCliproxyModels = exports.fetchCliproxyStats = void 0;
10
+ const config_generator_1 = require("./config-generator");
11
+ /**
12
+ * Fetch usage statistics from CLIProxyAPI management API
13
+ * @param port CLIProxyAPI port (default: 8317)
14
+ * @returns Stats object or null if unavailable
15
+ */
16
+ async function fetchCliproxyStats(port = config_generator_1.CLIPROXY_DEFAULT_PORT) {
17
+ try {
18
+ const controller = new AbortController();
19
+ const timeoutId = setTimeout(() => controller.abort(), 3000); // 3s timeout
20
+ const response = await fetch(`http://127.0.0.1:${port}/v0/management/usage`, {
21
+ signal: controller.signal,
22
+ headers: {
23
+ Accept: 'application/json',
24
+ Authorization: `Bearer ${config_generator_1.CCS_CONTROL_PANEL_SECRET}`,
25
+ },
26
+ });
27
+ clearTimeout(timeoutId);
28
+ if (!response.ok) {
29
+ return null;
30
+ }
31
+ const data = (await response.json());
32
+ const usage = data.usage;
33
+ // Extract models and providers from the nested API structure
34
+ const requestsByModel = {};
35
+ const requestsByProvider = {};
36
+ if (usage?.apis) {
37
+ for (const [provider, providerData] of Object.entries(usage.apis)) {
38
+ requestsByProvider[provider] = providerData.total_requests ?? 0;
39
+ if (providerData.models) {
40
+ for (const [model, modelData] of Object.entries(providerData.models)) {
41
+ requestsByModel[model] = modelData.total_requests ?? 0;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ // Normalize the response to our interface
47
+ return {
48
+ totalRequests: usage?.total_requests ?? 0,
49
+ tokens: {
50
+ input: 0, // API doesn't provide input/output breakdown
51
+ output: 0,
52
+ total: usage?.total_tokens ?? 0,
53
+ },
54
+ requestsByModel,
55
+ requestsByProvider,
56
+ quotaExceededCount: usage?.failure_count ?? data.failed_requests ?? 0,
57
+ retryCount: 0, // API doesn't track retries separately
58
+ collectedAt: new Date().toISOString(),
59
+ };
60
+ }
61
+ catch {
62
+ // CLIProxyAPI not running or stats endpoint not available
63
+ return null;
64
+ }
65
+ }
66
+ exports.fetchCliproxyStats = fetchCliproxyStats;
67
+ /**
68
+ * Fetch available models from CLIProxyAPI /v1/models endpoint
69
+ * @param port CLIProxyAPI port (default: 8317)
70
+ * @returns Categorized models or null if unavailable
71
+ */
72
+ async function fetchCliproxyModels(port = config_generator_1.CLIPROXY_DEFAULT_PORT) {
73
+ try {
74
+ const controller = new AbortController();
75
+ const timeoutId = setTimeout(() => controller.abort(), 3000);
76
+ const response = await fetch(`http://127.0.0.1:${port}/v1/models`, {
77
+ signal: controller.signal,
78
+ headers: {
79
+ Accept: 'application/json',
80
+ // Use the internal API key for /v1 endpoints
81
+ Authorization: 'Bearer ccs-internal-managed',
82
+ },
83
+ });
84
+ clearTimeout(timeoutId);
85
+ if (!response.ok) {
86
+ return null;
87
+ }
88
+ const data = (await response.json());
89
+ // Group models by owned_by field
90
+ const byCategory = {};
91
+ for (const model of data.data) {
92
+ const category = model.owned_by || 'other';
93
+ if (!byCategory[category]) {
94
+ byCategory[category] = [];
95
+ }
96
+ byCategory[category].push(model);
97
+ }
98
+ // Sort models within each category alphabetically
99
+ for (const category of Object.keys(byCategory)) {
100
+ byCategory[category].sort((a, b) => a.id.localeCompare(b.id));
101
+ }
102
+ return {
103
+ models: data.data,
104
+ byCategory,
105
+ totalCount: data.data.length,
106
+ };
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ }
112
+ exports.fetchCliproxyModels = fetchCliproxyModels;
113
+ /**
114
+ * Check if CLIProxyAPI is running and responsive
115
+ * @param port CLIProxyAPI port (default: 8317)
116
+ * @returns true if proxy is running
117
+ */
118
+ async function isCliproxyRunning(port = config_generator_1.CLIPROXY_DEFAULT_PORT) {
119
+ try {
120
+ const controller = new AbortController();
121
+ const timeoutId = setTimeout(() => controller.abort(), 1000); // 1s timeout
122
+ // Use root endpoint - CLIProxyAPI returns server info at /
123
+ const response = await fetch(`http://127.0.0.1:${port}/`, {
124
+ signal: controller.signal,
125
+ });
126
+ clearTimeout(timeoutId);
127
+ return response.ok;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
133
+ exports.isCliproxyRunning = isCliproxyRunning;
134
+ //# sourceMappingURL=stats-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats-fetcher.js","sourceRoot":"","sources":["../../src/cliproxy/stats-fetcher.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cliproxy-command.d.ts","sourceRoot":"","sources":["../../src/commands/cliproxy-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAg+BH;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDzE"}
1
+ {"version":3,"file":"cliproxy-command.d.ts","sourceRoot":"","sources":["../../src/commands/cliproxy-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAqgCH;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE"}
@@ -677,8 +677,9 @@ async function showHelp() {
677
677
  // Binary Commands
678
678
  console.log((0, ui_1.subheader)('Binary Commands:'));
679
679
  const binaryCmds = [
680
- ['--install <version>', 'Install a specific binary version'],
681
- ['--latest', 'Install the latest binary version'],
680
+ ['--install <version>', 'Install and pin a specific version'],
681
+ ['--latest', 'Install the latest version (no pin)'],
682
+ ['--update', 'Unpin and update to latest version'],
682
683
  ];
683
684
  const maxBinaryLen = Math.max(...binaryCmds.map(([cmd]) => cmd.length));
684
685
  for (const [cmd, desc] of binaryCmds) {
@@ -743,12 +744,16 @@ async function showStatus(verbose) {
743
744
  const installed = (0, cliproxy_1.isCLIProxyInstalled)();
744
745
  const currentVersion = (0, cliproxy_1.getInstalledCliproxyVersion)();
745
746
  const binaryPath = (0, cliproxy_1.getCLIProxyPath)();
747
+ const pinnedVersion = (0, cliproxy_1.getPinnedVersion)();
746
748
  console.log('');
747
749
  console.log((0, ui_1.color)('CLIProxyAPI Status', 'primary'));
748
750
  console.log('');
749
751
  if (installed) {
750
752
  console.log(` Installed: ${(0, ui_1.color)('Yes', 'success')}`);
751
- console.log(` Version: ${(0, ui_1.color)(`v${currentVersion}`, 'info')}`);
753
+ const versionLabel = pinnedVersion
754
+ ? `${(0, ui_1.color)(`v${currentVersion}`, 'info')} ${(0, ui_1.color)('(pinned)', 'warning')}`
755
+ : (0, ui_1.color)(`v${currentVersion}`, 'info');
756
+ console.log(` Version: ${versionLabel}`);
752
757
  console.log(` Binary: ${(0, ui_1.dim)(binaryPath)}`);
753
758
  }
754
759
  else {
@@ -762,9 +767,16 @@ async function showStatus(verbose) {
762
767
  console.log(` ${(0, ui_1.dim)('Checking for updates...')}`);
763
768
  const latestVersion = await (0, cliproxy_1.fetchLatestCliproxyVersion)();
764
769
  if (latestVersion !== currentVersion) {
765
- console.log(` Latest: ${(0, ui_1.color)(`v${latestVersion}`, 'success')} ${(0, ui_1.dim)('(update available)')}`);
766
- console.log('');
767
- console.log(` ${(0, ui_1.dim)(`Run "ccs cliproxy --latest" to update`)}`);
770
+ if (pinnedVersion) {
771
+ console.log(` Latest: ${(0, ui_1.color)(`v${latestVersion}`, 'success')} ${(0, ui_1.dim)('(pinned to v' + pinnedVersion + ')')}`);
772
+ console.log('');
773
+ console.log(` ${(0, ui_1.dim)('Run "ccs cliproxy --update" to unpin and update')}`);
774
+ }
775
+ else {
776
+ console.log(` Latest: ${(0, ui_1.color)(`v${latestVersion}`, 'success')} ${(0, ui_1.dim)('(update available)')}`);
777
+ console.log('');
778
+ console.log(` ${(0, ui_1.dim)('Run "ccs cliproxy --latest" to update')}`);
779
+ }
768
780
  }
769
781
  else {
770
782
  console.log(` Latest: ${(0, ui_1.color)(`v${latestVersion}`, 'success')} ${(0, ui_1.dim)('(up to date)')}`);
@@ -781,25 +793,31 @@ async function showStatus(verbose) {
781
793
  console.log('');
782
794
  }
783
795
  /**
784
- * Install a specific version
796
+ * Install a specific version (pins the version to prevent auto-update)
785
797
  */
786
798
  async function installVersion(version, verbose) {
787
799
  // Validate version format (basic semver check)
788
800
  if (!/^\d+\.\d+\.\d+$/.test(version)) {
789
- console.error('[X] Invalid version format. Expected format: X.Y.Z (e.g., 6.5.53)');
801
+ console.error((0, ui_1.fail)('Invalid version format. Expected format: X.Y.Z (e.g., 6.5.53)'));
790
802
  process.exit(1);
791
803
  }
792
- console.log(`[i] Installing CLIProxyAPI v${version}...`);
804
+ console.log((0, ui_1.info)(`Installing CLIProxyAPI v${version}...`));
793
805
  console.log('');
794
806
  try {
795
807
  await (0, cliproxy_1.installCliproxyVersion)(version, verbose);
808
+ // Pin the version to prevent auto-update
809
+ (0, cliproxy_1.savePinnedVersion)(version);
810
+ console.log('');
811
+ console.log((0, ui_1.ok)(`CLIProxyAPI v${version} installed (pinned)`));
812
+ console.log('');
813
+ console.log((0, ui_1.dim)('This version will be used until you run:'));
814
+ console.log(` ${(0, ui_1.color)('ccs cliproxy --update', 'command')} ${(0, ui_1.dim)('# Update to latest and unpin')}`);
796
815
  console.log('');
797
- console.log(`[OK] CLIProxyAPI v${version} installed successfully`);
798
816
  }
799
817
  catch (error) {
800
818
  const err = error;
801
819
  console.error('');
802
- console.error(`[X] Failed to install CLIProxyAPI v${version}`);
820
+ console.error((0, ui_1.fail)(`Failed to install CLIProxyAPI v${version}`));
803
821
  console.error(` ${err.message}`);
804
822
  console.error('');
805
823
  console.error('Possible causes:');
@@ -813,29 +831,37 @@ async function installVersion(version, verbose) {
813
831
  }
814
832
  }
815
833
  /**
816
- * Install latest version
834
+ * Install latest version (clears any version pin)
817
835
  */
818
836
  async function installLatest(verbose) {
819
- console.log('[i] Fetching latest CLIProxyAPI version...');
837
+ console.log((0, ui_1.info)('Fetching latest CLIProxyAPI version...'));
820
838
  try {
821
839
  const latestVersion = await (0, cliproxy_1.fetchLatestCliproxyVersion)();
822
840
  const currentVersion = (0, cliproxy_1.getInstalledCliproxyVersion)();
823
- if ((0, cliproxy_1.isCLIProxyInstalled)() && latestVersion === currentVersion) {
824
- console.log(`[OK] Already running latest version: v${latestVersion}`);
841
+ const wasPinned = (0, cliproxy_1.isVersionPinned)();
842
+ if ((0, cliproxy_1.isCLIProxyInstalled)() && latestVersion === currentVersion && !wasPinned) {
843
+ console.log((0, ui_1.ok)(`Already running latest version: v${latestVersion}`));
825
844
  return;
826
845
  }
827
- console.log(`[i] Latest version: v${latestVersion}`);
846
+ console.log((0, ui_1.info)(`Latest version: v${latestVersion}`));
828
847
  if ((0, cliproxy_1.isCLIProxyInstalled)()) {
829
- console.log(`[i] Current version: v${currentVersion}`);
848
+ console.log((0, ui_1.info)(`Current version: v${currentVersion}`));
849
+ }
850
+ if (wasPinned) {
851
+ console.log((0, ui_1.info)(`Removing version pin (was v${(0, cliproxy_1.getPinnedVersion)()})`));
830
852
  }
831
853
  console.log('');
832
854
  await (0, cliproxy_1.installCliproxyVersion)(latestVersion, verbose);
855
+ // Clear any version pin so auto-update works again
856
+ (0, cliproxy_1.clearPinnedVersion)();
857
+ console.log('');
858
+ console.log((0, ui_1.ok)(`CLIProxyAPI updated to v${latestVersion}`));
859
+ console.log((0, ui_1.dim)('Auto-update is now enabled.'));
833
860
  console.log('');
834
- console.log(`[OK] CLIProxyAPI updated to v${latestVersion}`);
835
861
  }
836
862
  catch (error) {
837
863
  const err = error;
838
- console.error(`[X] Failed to install latest version: ${err.message}`);
864
+ console.error((0, ui_1.fail)(`Failed to install latest version: ${err.message}`));
839
865
  process.exit(1);
840
866
  }
841
867
  }
@@ -884,6 +910,11 @@ async function handleCliproxyCommand(args) {
884
910
  await installLatest(verbose);
885
911
  return;
886
912
  }
913
+ // Handle --update (unpin and update to latest)
914
+ if (args.includes('--update')) {
915
+ await installLatest(verbose);
916
+ return;
917
+ }
887
918
  // Default: show status
888
919
  await showStatus(verbose);
889
920
  }