@kaitranntt/ccs 7.74.0 → 7.75.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.
Files changed (242) hide show
  1. package/dist/api/services/profile-writer.d.ts +1 -1
  2. package/dist/api/services/profile-writer.d.ts.map +1 -1
  3. package/dist/api/services/profile-writer.js +11 -5
  4. package/dist/api/services/profile-writer.js.map +1 -1
  5. package/dist/bin/ccsxp-runtime.d.ts +8 -0
  6. package/dist/bin/ccsxp-runtime.d.ts.map +1 -1
  7. package/dist/bin/ccsxp-runtime.js +60 -3
  8. package/dist/bin/ccsxp-runtime.js.map +1 -1
  9. package/dist/ccs.js +4 -2
  10. package/dist/ccs.js.map +1 -1
  11. package/dist/cliproxy/account-safety.d.ts.map +1 -1
  12. package/dist/cliproxy/account-safety.js +6 -1
  13. package/dist/cliproxy/account-safety.js.map +1 -1
  14. package/dist/cliproxy/ai-providers/service.d.ts.map +1 -1
  15. package/dist/cliproxy/ai-providers/service.js +10 -3
  16. package/dist/cliproxy/ai-providers/service.js.map +1 -1
  17. package/dist/cliproxy/binary/lifecycle.d.ts.map +1 -1
  18. package/dist/cliproxy/binary/lifecycle.js +2 -1
  19. package/dist/cliproxy/binary/lifecycle.js.map +1 -1
  20. package/dist/cliproxy/codex-plan-compatibility.d.ts.map +1 -1
  21. package/dist/cliproxy/codex-plan-compatibility.js +1 -0
  22. package/dist/cliproxy/codex-plan-compatibility.js.map +1 -1
  23. package/dist/cliproxy/config/generator.d.ts +2 -1
  24. package/dist/cliproxy/config/generator.d.ts.map +1 -1
  25. package/dist/cliproxy/config/generator.js +25 -1
  26. package/dist/cliproxy/config/generator.js.map +1 -1
  27. package/dist/cliproxy/executor/index.d.ts +5 -0
  28. package/dist/cliproxy/executor/index.d.ts.map +1 -1
  29. package/dist/cliproxy/executor/index.js +22 -6
  30. package/dist/cliproxy/executor/index.js.map +1 -1
  31. package/dist/cliproxy/executor/retry-handler.js +2 -2
  32. package/dist/cliproxy/executor/retry-handler.js.map +1 -1
  33. package/dist/cliproxy/management-api-client.d.ts.map +1 -1
  34. package/dist/cliproxy/management-api-client.js +3 -2
  35. package/dist/cliproxy/management-api-client.js.map +1 -1
  36. package/dist/cliproxy/model-catalog.d.ts.map +1 -1
  37. package/dist/cliproxy/model-catalog.js +12 -0
  38. package/dist/cliproxy/model-catalog.js.map +1 -1
  39. package/dist/cliproxy/quota-fetcher-claude-normalizer.d.ts.map +1 -1
  40. package/dist/cliproxy/quota-fetcher-claude-normalizer.js +16 -12
  41. package/dist/cliproxy/quota-fetcher-claude-normalizer.js.map +1 -1
  42. package/dist/cliproxy/quota-fetcher-codex.d.ts +18 -3
  43. package/dist/cliproxy/quota-fetcher-codex.d.ts.map +1 -1
  44. package/dist/cliproxy/quota-fetcher-codex.js +74 -24
  45. package/dist/cliproxy/quota-fetcher-codex.js.map +1 -1
  46. package/dist/cliproxy/quota-fetcher-ghcp.d.ts.map +1 -1
  47. package/dist/cliproxy/quota-fetcher-ghcp.js +19 -8
  48. package/dist/cliproxy/quota-fetcher-ghcp.js.map +1 -1
  49. package/dist/cliproxy/quota-manager.d.ts +5 -2
  50. package/dist/cliproxy/quota-manager.d.ts.map +1 -1
  51. package/dist/cliproxy/quota-manager.js +177 -63
  52. package/dist/cliproxy/quota-manager.js.map +1 -1
  53. package/dist/cliproxy/quota-types.d.ts +16 -2
  54. package/dist/cliproxy/quota-types.d.ts.map +1 -1
  55. package/dist/cliproxy/routing-strategy-http.d.ts +1 -0
  56. package/dist/cliproxy/routing-strategy-http.d.ts.map +1 -1
  57. package/dist/cliproxy/routing-strategy-http.js +7 -2
  58. package/dist/cliproxy/routing-strategy-http.js.map +1 -1
  59. package/dist/cliproxy/routing-strategy.d.ts +23 -0
  60. package/dist/cliproxy/routing-strategy.d.ts.map +1 -1
  61. package/dist/cliproxy/routing-strategy.js +148 -2
  62. package/dist/cliproxy/routing-strategy.js.map +1 -1
  63. package/dist/cliproxy/service-manager.d.ts +17 -1
  64. package/dist/cliproxy/service-manager.d.ts.map +1 -1
  65. package/dist/cliproxy/service-manager.js +10 -5
  66. package/dist/cliproxy/service-manager.js.map +1 -1
  67. package/dist/cliproxy/sync/profile-mapper.d.ts.map +1 -1
  68. package/dist/cliproxy/sync/profile-mapper.js +21 -0
  69. package/dist/cliproxy/sync/profile-mapper.js.map +1 -1
  70. package/dist/cliproxy/types.d.ts +11 -0
  71. package/dist/cliproxy/types.d.ts.map +1 -1
  72. package/dist/cliproxy/types.js.map +1 -1
  73. package/dist/commands/api-command/create-command.d.ts.map +1 -1
  74. package/dist/commands/api-command/create-command.js +4 -1
  75. package/dist/commands/api-command/create-command.js.map +1 -1
  76. package/dist/commands/api-command/help.d.ts.map +1 -1
  77. package/dist/commands/api-command/help.js +4 -0
  78. package/dist/commands/api-command/help.js.map +1 -1
  79. package/dist/commands/api-command/shared.d.ts +2 -1
  80. package/dist/commands/api-command/shared.d.ts.map +1 -1
  81. package/dist/commands/api-command/shared.js +9 -0
  82. package/dist/commands/api-command/shared.js.map +1 -1
  83. package/dist/commands/cliproxy/help-subcommand.d.ts.map +1 -1
  84. package/dist/commands/cliproxy/help-subcommand.js +3 -1
  85. package/dist/commands/cliproxy/help-subcommand.js.map +1 -1
  86. package/dist/commands/cliproxy/index.d.ts.map +1 -1
  87. package/dist/commands/cliproxy/index.js +12 -0
  88. package/dist/commands/cliproxy/index.js.map +1 -1
  89. package/dist/commands/cliproxy/quota-subcommand.d.ts.map +1 -1
  90. package/dist/commands/cliproxy/quota-subcommand.js +79 -23
  91. package/dist/commands/cliproxy/quota-subcommand.js.map +1 -1
  92. package/dist/commands/cliproxy/routing-subcommand.d.ts +3 -0
  93. package/dist/commands/cliproxy/routing-subcommand.d.ts.map +1 -1
  94. package/dist/commands/cliproxy/routing-subcommand.js +127 -2
  95. package/dist/commands/cliproxy/routing-subcommand.js.map +1 -1
  96. package/dist/commands/command-catalog.d.ts.map +1 -1
  97. package/dist/commands/command-catalog.js +4 -1
  98. package/dist/commands/command-catalog.js.map +1 -1
  99. package/dist/commands/completion-backend.d.ts.map +1 -1
  100. package/dist/commands/completion-backend.js +16 -1
  101. package/dist/commands/completion-backend.js.map +1 -1
  102. package/dist/commands/config-dashboard-host.d.ts.map +1 -1
  103. package/dist/commands/config-dashboard-host.js +14 -2
  104. package/dist/commands/config-dashboard-host.js.map +1 -1
  105. package/dist/config/unified-config-loader.d.ts.map +1 -1
  106. package/dist/config/unified-config-loader.js +26 -0
  107. package/dist/config/unified-config-loader.js.map +1 -1
  108. package/dist/config/unified-config-types.d.ts +4 -0
  109. package/dist/config/unified-config-types.d.ts.map +1 -1
  110. package/dist/config/unified-config-types.js +2 -0
  111. package/dist/config/unified-config-types.js.map +1 -1
  112. package/dist/delegation/headless-executor.d.ts.map +1 -1
  113. package/dist/delegation/headless-executor.js +17 -2
  114. package/dist/delegation/headless-executor.js.map +1 -1
  115. package/dist/proxy/transformers/request-transformer.d.ts.map +1 -1
  116. package/dist/proxy/transformers/request-transformer.js +0 -8
  117. package/dist/proxy/transformers/request-transformer.js.map +1 -1
  118. package/dist/targets/target-metadata.js +1 -1
  119. package/dist/targets/target-metadata.js.map +1 -1
  120. package/dist/ui/assets/{accounts-D0Z5AVKW.js → accounts-CP_Nosd7.js} +1 -1
  121. package/dist/ui/assets/{alert-dialog-CzJucE0e.js → alert-dialog-CjnZBDj3.js} +1 -1
  122. package/dist/ui/assets/{api-DXAf4i-v.js → api-B7mmrAjt.js} +1 -1
  123. package/dist/ui/assets/{auth-section-BrnnHBi-.js → auth-section-BFQ8Mu15.js} +1 -1
  124. package/dist/ui/assets/{backups-section-DCBcfZ-C.js → backups-section-CPwm9q19.js} +1 -1
  125. package/dist/ui/assets/{channels-BSapONLx.js → channels-B2colnY7.js} +1 -1
  126. package/dist/ui/assets/{checkbox-Bd7X5Xud.js → checkbox-BAMXPp68.js} +1 -1
  127. package/dist/ui/assets/{claude-extension-BYJxm4B5.js → claude-extension-BDVoXHr-.js} +1 -1
  128. package/dist/ui/assets/{cliproxy-G5JuFm2j.js → cliproxy-CuLlmDu7.js} +1 -1
  129. package/dist/ui/assets/{cliproxy-ai-providers-D7r2Us_Y.js → cliproxy-ai-providers-8dH1cHVk.js} +1 -1
  130. package/dist/ui/assets/{cliproxy-control-panel-Cmo3ArVL.js → cliproxy-control-panel-CC8HzA8e.js} +1 -1
  131. package/dist/ui/assets/codex-C6Q9rOwp.js +27 -0
  132. package/dist/ui/assets/{confirm-dialog--zJgz4y0.js → confirm-dialog-D0VQlM7B.js} +1 -1
  133. package/dist/ui/assets/{copilot-2ARJ9YVb.js → copilot-CgG2oaRV.js} +1 -1
  134. package/dist/ui/assets/{cursor-CQNCrVt0.js → cursor-CE1giQU2.js} +1 -1
  135. package/dist/ui/assets/{droid-Dl5wRjDv.js → droid-FG2w7nRu.js} +1 -1
  136. package/dist/ui/assets/{globalenv-section-T1imQsSA.js → globalenv-section-BJbBud4W.js} +1 -1
  137. package/dist/ui/assets/health-Dh7o4wt7.js +1 -0
  138. package/dist/ui/assets/index-0mNJhDEG.js +72 -0
  139. package/dist/ui/assets/{index-CqJFugM4.js → index-B6bIHdvz.js} +1 -1
  140. package/dist/ui/assets/{index-DH916Tyi.js → index-BNTqP5R7.js} +1 -1
  141. package/dist/ui/assets/index-BNW5qVXZ.js +1 -0
  142. package/dist/ui/assets/{index-fV5BBuAO.js → index-Bj8UFR7b.js} +1 -1
  143. package/dist/ui/assets/index-DM5Khyln.css +1 -0
  144. package/dist/ui/assets/{index-DFgCoUVv.js → index-DTAdzUUA.js} +1 -1
  145. package/dist/ui/assets/index-X21iqV9e.js +1 -0
  146. package/dist/ui/assets/{logs-CZsWbq7X.js → logs-CxwEaeVS.js} +1 -1
  147. package/dist/ui/assets/masked-input-DygH0M2a.js +1 -0
  148. package/dist/ui/assets/proxy-g4_N-fbB.js +9 -0
  149. package/dist/ui/assets/proxy-status-widget-BWjGFUas.js +1 -0
  150. package/dist/ui/assets/{raw-json-settings-editor-panel-DNmb_vR-.js → raw-json-settings-editor-panel-DYpsr-1d.js} +1 -1
  151. package/dist/ui/assets/{searchable-select--iFe00dY.js → searchable-select-BKx31cCH.js} +1 -1
  152. package/dist/ui/assets/{separator-CaGbNw8E.js → separator-mG07scBE.js} +1 -1
  153. package/dist/ui/assets/{shared-Cgk48Wu3.js → shared-hbFOfnWU.js} +1 -1
  154. package/dist/ui/assets/{table-CKuoPAz4.js → table-DoECcNZ-.js} +1 -1
  155. package/dist/ui/assets/updates-BSeFQRwL.js +1 -0
  156. package/dist/ui/index.html +2 -2
  157. package/dist/utils/openai-compat-launch-settings.d.ts +7 -0
  158. package/dist/utils/openai-compat-launch-settings.d.ts.map +1 -0
  159. package/dist/utils/openai-compat-launch-settings.js +61 -0
  160. package/dist/utils/openai-compat-launch-settings.js.map +1 -0
  161. package/dist/utils/shell-executor.d.ts +1 -1
  162. package/dist/utils/shell-executor.d.ts.map +1 -1
  163. package/dist/utils/shell-executor.js +11 -1
  164. package/dist/utils/shell-executor.js.map +1 -1
  165. package/dist/web-server/jsonl-parser.d.ts.map +1 -1
  166. package/dist/web-server/jsonl-parser.js +22 -4
  167. package/dist/web-server/jsonl-parser.js.map +1 -1
  168. package/dist/web-server/model-pricing.d.ts +8 -6
  169. package/dist/web-server/model-pricing.d.ts.map +1 -1
  170. package/dist/web-server/model-pricing.js +80 -29
  171. package/dist/web-server/model-pricing.js.map +1 -1
  172. package/dist/web-server/models-dev/pricing-resolver.d.ts +18 -0
  173. package/dist/web-server/models-dev/pricing-resolver.d.ts.map +1 -0
  174. package/dist/web-server/models-dev/pricing-resolver.js +153 -0
  175. package/dist/web-server/models-dev/pricing-resolver.js.map +1 -0
  176. package/dist/web-server/models-dev/registry-cache.d.ts +19 -0
  177. package/dist/web-server/models-dev/registry-cache.d.ts.map +1 -0
  178. package/dist/web-server/models-dev/registry-cache.js +155 -0
  179. package/dist/web-server/models-dev/registry-cache.js.map +1 -0
  180. package/dist/web-server/models-dev/types.d.ts +39 -0
  181. package/dist/web-server/models-dev/types.d.ts.map +1 -0
  182. package/dist/web-server/models-dev/types.js +3 -0
  183. package/dist/web-server/models-dev/types.js.map +1 -0
  184. package/dist/web-server/routes/cliproxy-routing-routes.d.ts.map +1 -1
  185. package/dist/web-server/routes/cliproxy-routing-routes.js +35 -0
  186. package/dist/web-server/routes/cliproxy-routing-routes.js.map +1 -1
  187. package/dist/web-server/routes/profile-routes.d.ts.map +1 -1
  188. package/dist/web-server/routes/profile-routes.js +13 -3
  189. package/dist/web-server/routes/profile-routes.js.map +1 -1
  190. package/dist/web-server/routes/route-helpers.d.ts +1 -0
  191. package/dist/web-server/routes/route-helpers.d.ts.map +1 -1
  192. package/dist/web-server/routes/route-helpers.js +11 -0
  193. package/dist/web-server/routes/route-helpers.js.map +1 -1
  194. package/dist/web-server/usage/aggregator.d.ts +1 -0
  195. package/dist/web-server/usage/aggregator.d.ts.map +1 -1
  196. package/dist/web-server/usage/aggregator.js +121 -20
  197. package/dist/web-server/usage/aggregator.js.map +1 -1
  198. package/dist/web-server/usage/cliproxy-usage-syncer.d.ts +0 -15
  199. package/dist/web-server/usage/cliproxy-usage-syncer.d.ts.map +1 -1
  200. package/dist/web-server/usage/cliproxy-usage-syncer.js +159 -55
  201. package/dist/web-server/usage/cliproxy-usage-syncer.js.map +1 -1
  202. package/dist/web-server/usage/cliproxy-usage-transformer.d.ts +23 -7
  203. package/dist/web-server/usage/cliproxy-usage-transformer.d.ts.map +1 -1
  204. package/dist/web-server/usage/cliproxy-usage-transformer.js +191 -28
  205. package/dist/web-server/usage/cliproxy-usage-transformer.js.map +1 -1
  206. package/dist/web-server/usage/codex-native-usage-collector.d.ts +11 -0
  207. package/dist/web-server/usage/codex-native-usage-collector.d.ts.map +1 -0
  208. package/dist/web-server/usage/codex-native-usage-collector.js +177 -0
  209. package/dist/web-server/usage/codex-native-usage-collector.js.map +1 -0
  210. package/dist/web-server/usage/data-aggregator.d.ts.map +1 -1
  211. package/dist/web-server/usage/data-aggregator.js +45 -46
  212. package/dist/web-server/usage/data-aggregator.js.map +1 -1
  213. package/dist/web-server/usage/droid-native-usage-collector.d.ts +14 -0
  214. package/dist/web-server/usage/droid-native-usage-collector.d.ts.map +1 -0
  215. package/dist/web-server/usage/droid-native-usage-collector.js +201 -0
  216. package/dist/web-server/usage/droid-native-usage-collector.js.map +1 -0
  217. package/dist/web-server/usage/handlers.d.ts +1 -0
  218. package/dist/web-server/usage/handlers.d.ts.map +1 -1
  219. package/dist/web-server/usage/handlers.js +155 -45
  220. package/dist/web-server/usage/handlers.js.map +1 -1
  221. package/dist/web-server/usage/model-identity.d.ts +16 -0
  222. package/dist/web-server/usage/model-identity.d.ts.map +1 -0
  223. package/dist/web-server/usage/model-identity.js +70 -0
  224. package/dist/web-server/usage/model-identity.js.map +1 -0
  225. package/dist/web-server/usage/sqlite-cli.d.ts +3 -0
  226. package/dist/web-server/usage/sqlite-cli.d.ts.map +1 -0
  227. package/dist/web-server/usage/sqlite-cli.js +62 -0
  228. package/dist/web-server/usage/sqlite-cli.js.map +1 -0
  229. package/dist/web-server/usage/types.d.ts +6 -0
  230. package/dist/web-server/usage/types.d.ts.map +1 -1
  231. package/lib/mcp/ccs-browser-server.cjs +309 -121
  232. package/package.json +1 -1
  233. package/scripts/dev-release.sh +4 -2
  234. package/dist/ui/assets/codex-4VNBJ4Nb.js +0 -27
  235. package/dist/ui/assets/health-CNous3WN.js +0 -1
  236. package/dist/ui/assets/index-2X8-14xr.js +0 -72
  237. package/dist/ui/assets/index-BcLnqcxD.js +0 -1
  238. package/dist/ui/assets/index-Be3dhMW3.js +0 -9
  239. package/dist/ui/assets/index-DuTB1_9r.css +0 -1
  240. package/dist/ui/assets/masked-input-_EkW1Pzo.js +0 -1
  241. package/dist/ui/assets/proxy-status-widget-D82T2X4F.js +0 -1
  242. package/dist/ui/assets/updates-Dr8Yq-Pm.js +0 -1
@@ -39,14 +39,15 @@ const stats_fetcher_1 = require("../../cliproxy/stats-fetcher");
39
39
  const cliproxy_usage_transformer_1 = require("./cliproxy-usage-transformer");
40
40
  const config_manager_1 = require("../../utils/config-manager");
41
41
  const ui_1 = require("../../utils/ui");
42
- const SNAPSHOT_VERSION = 1;
42
+ const SNAPSHOT_VERSION = 3;
43
+ const SNAPSHOT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
44
+ const HISTORY_RETENTION_DAYS = Math.max(30, parseInt(process.env.CCS_CLIPROXY_HISTORY_RETENTION_DAYS ?? '365', 10) || 365);
45
+ const HISTORY_RETENTION_MS = HISTORY_RETENTION_DAYS * 24 * 60 * 60 * 1000;
46
+ const MAX_WRITE_ATTEMPTS = 3;
43
47
  /** Sync interval in ms, configurable via CCS_CLIPROXY_SYNC_INTERVAL env var (default: 5 min) */
44
48
  const SYNC_INTERVAL_MS = Math.max(30000, parseInt(process.env.CCS_CLIPROXY_SYNC_INTERVAL ?? '300000', 10) || 300000);
45
- // Module-level interval ID
46
49
  let syncIntervalId = null;
47
- // ---------------------------------------------------------------------------
48
- // Cache directory helpers
49
- // ---------------------------------------------------------------------------
50
+ let snapshotTimestampOrdinal = 0;
50
51
  function getCliproxyCacheDir() {
51
52
  return path.join((0, config_manager_1.getCcsDir)(), 'cache', 'cliproxy-usage');
52
53
  }
@@ -59,41 +60,172 @@ function ensureCliproxyCacheDir() {
59
60
  fs.mkdirSync(dir, { recursive: true });
60
61
  }
61
62
  }
62
- // ---------------------------------------------------------------------------
63
- // Load cached data
64
- // ---------------------------------------------------------------------------
65
- /**
66
- * Read the latest CLIProxy usage snapshot from disk.
67
- * Returns empty arrays on failure (file not found, parse error, version mismatch).
68
- */
69
- async function loadCachedCliproxyData() {
70
- const empty = { daily: [], hourly: [], monthly: [] };
63
+ function getSnapshotTimestamp() {
64
+ snapshotTimestampOrdinal = (snapshotTimestampOrdinal + 1) % 1000;
65
+ return Date.now() + snapshotTimestampOrdinal / 1000;
66
+ }
67
+ function buildHourlyTimestamp(hour) {
68
+ return `${hour.replace(' ', 'T')}:00.000Z`;
69
+ }
70
+ function buildDailyTimestamp(date) {
71
+ return `${date}T00:00:00.000Z`;
72
+ }
73
+ function distributeRequestCounts(total, buckets) {
74
+ if (buckets <= 0)
75
+ return [];
76
+ const normalizedTotal = Math.max(buckets, total);
77
+ const base = Math.floor(normalizedTotal / buckets);
78
+ const remainder = normalizedTotal % buckets;
79
+ return Array.from({ length: buckets }, (_value, index) => base + (index < remainder ? 1 : 0));
80
+ }
81
+ function buildLegacyHistoryDetails(snapshot) {
82
+ const details = [];
83
+ const coveredDailyKeys = new Set();
84
+ for (const hour of snapshot.hourly ?? []) {
85
+ const requestCounts = distributeRequestCounts(hour.requestCount ?? hour.modelBreakdowns.length, hour.modelBreakdowns.length);
86
+ hour.modelBreakdowns.forEach((breakdown, index) => {
87
+ details.push({
88
+ model: breakdown.modelName,
89
+ timestamp: buildHourlyTimestamp(hour.hour),
90
+ source: hour.source,
91
+ authIndex: 'legacy-hourly',
92
+ inputTokens: breakdown.inputTokens,
93
+ outputTokens: breakdown.outputTokens,
94
+ cacheReadTokens: breakdown.cacheReadTokens,
95
+ requestCount: requestCounts[index] ?? 1,
96
+ cost: breakdown.cost,
97
+ failed: false,
98
+ });
99
+ coveredDailyKeys.add(`${hour.hour.slice(0, 10)}|${breakdown.modelName}`);
100
+ });
101
+ }
102
+ for (const day of snapshot.daily ?? []) {
103
+ for (const breakdown of day.modelBreakdowns) {
104
+ const key = `${day.date}|${breakdown.modelName}`;
105
+ if (coveredDailyKeys.has(key)) {
106
+ continue;
107
+ }
108
+ details.push({
109
+ model: breakdown.modelName,
110
+ timestamp: buildDailyTimestamp(day.date),
111
+ source: day.source,
112
+ authIndex: 'legacy-daily',
113
+ inputTokens: breakdown.inputTokens,
114
+ outputTokens: breakdown.outputTokens,
115
+ cacheReadTokens: breakdown.cacheReadTokens,
116
+ requestCount: 1,
117
+ cost: breakdown.cost,
118
+ failed: false,
119
+ });
120
+ }
121
+ }
122
+ return details;
123
+ }
124
+ function migrateLegacySnapshot(snapshot, emitWarnings) {
125
+ const details = buildLegacyHistoryDetails(snapshot);
126
+ if (details.length === 0) {
127
+ if (emitWarnings) {
128
+ console.log((0, ui_1.info)('CLIProxy legacy snapshot had no migratable history, will refresh on next sync'));
129
+ }
130
+ return null;
131
+ }
132
+ if (emitWarnings) {
133
+ console.log((0, ui_1.info)('Loaded legacy CLIProxy snapshot into historical format'));
134
+ }
135
+ const { daily, hourly, monthly } = (0, cliproxy_usage_transformer_1.buildCliproxyUsageHistoryAggregates)(details);
136
+ return {
137
+ version: SNAPSHOT_VERSION,
138
+ timestamp: Number.isFinite(snapshot.timestamp) ? Number(snapshot.timestamp) : Date.now(),
139
+ details,
140
+ daily,
141
+ hourly,
142
+ monthly,
143
+ };
144
+ }
145
+ function readSnapshot(emitWarnings = true) {
71
146
  try {
72
147
  const snapshotPath = getLatestSnapshotPath();
73
148
  if (!fs.existsSync(snapshotPath)) {
74
- return empty;
149
+ return null;
75
150
  }
76
151
  const raw = fs.readFileSync(snapshotPath, 'utf-8');
77
152
  const snapshot = JSON.parse(raw);
78
- if (snapshot.version !== SNAPSHOT_VERSION) {
153
+ if (snapshot.version === SNAPSHOT_VERSION) {
154
+ if (!Number.isFinite(snapshot.timestamp)) {
155
+ if (emitWarnings) {
156
+ console.log((0, ui_1.info)('CLIProxy snapshot timestamp invalid, will refresh on next sync'));
157
+ }
158
+ return null;
159
+ }
160
+ if (!Array.isArray(snapshot.details)) {
161
+ if (emitWarnings) {
162
+ console.log((0, ui_1.info)('CLIProxy snapshot details missing, will refresh on next sync'));
163
+ }
164
+ return null;
165
+ }
166
+ return snapshot;
167
+ }
168
+ if (snapshot.version === 1 || snapshot.version === 2) {
169
+ return migrateLegacySnapshot(snapshot, emitWarnings);
170
+ }
171
+ if (emitWarnings) {
79
172
  console.log((0, ui_1.info)('CLIProxy snapshot version mismatch, will refresh on next sync'));
80
- return empty;
81
173
  }
82
- return { daily: snapshot.daily, hourly: snapshot.hourly, monthly: snapshot.monthly };
174
+ return null;
83
175
  }
84
176
  catch (err) {
85
- console.log((0, ui_1.warn)('Failed to read CLIProxy snapshot:') + ` ${err.message}`);
177
+ if (emitWarnings) {
178
+ console.log((0, ui_1.warn)('Failed to read CLIProxy snapshot:') + ` ${err.message}`);
179
+ }
180
+ return null;
181
+ }
182
+ }
183
+ function buildSnapshot(baseDetails, incomingDetails) {
184
+ const mergedDetails = (0, cliproxy_usage_transformer_1.pruneCliproxyUsageHistoryDetails)((0, cliproxy_usage_transformer_1.mergeCliproxyUsageHistoryDetails)(baseDetails, incomingDetails), Date.now() - HISTORY_RETENTION_MS);
185
+ const { daily, hourly, monthly } = (0, cliproxy_usage_transformer_1.buildCliproxyUsageHistoryAggregates)(mergedDetails);
186
+ return {
187
+ version: SNAPSHOT_VERSION,
188
+ timestamp: getSnapshotTimestamp(),
189
+ details: mergedDetails,
190
+ daily,
191
+ hourly,
192
+ monthly,
193
+ };
194
+ }
195
+ async function writeSnapshotWithMerge(incomingDetails) {
196
+ ensureCliproxyCacheDir();
197
+ const snapshotPath = getLatestSnapshotPath();
198
+ for (let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt++) {
199
+ const baseSnapshot = readSnapshot(false);
200
+ const baseTimestamp = baseSnapshot?.timestamp ?? -Infinity;
201
+ const snapshot = buildSnapshot(baseSnapshot?.details ?? [], incomingDetails);
202
+ const tempFile = `${snapshotPath}.${process.pid}.${snapshot.timestamp}.tmp`;
203
+ fs.writeFileSync(tempFile, JSON.stringify(snapshot), 'utf-8');
204
+ const latestSnapshot = readSnapshot(false);
205
+ const latestTimestamp = latestSnapshot?.timestamp ?? -Infinity;
206
+ if (latestTimestamp > baseTimestamp) {
207
+ fs.rmSync(tempFile, { force: true });
208
+ continue;
209
+ }
210
+ fs.renameSync(tempFile, snapshotPath);
211
+ console.log((0, ui_1.ok)('CLIProxy usage snapshot updated'));
212
+ return;
213
+ }
214
+ throw new Error('Failed to write CLIProxy snapshot after repeated overlap retries');
215
+ }
216
+ async function loadCachedCliproxyData() {
217
+ const empty = { daily: [], hourly: [], monthly: [] };
218
+ const snapshot = readSnapshot();
219
+ if (!snapshot) {
86
220
  return empty;
87
221
  }
222
+ const age = Date.now() - snapshot.timestamp;
223
+ if (age > SNAPSHOT_MAX_AGE_MS) {
224
+ console.log((0, ui_1.info)('Using stale CLIProxy snapshot while proxy sync is unavailable'));
225
+ }
226
+ return { daily: snapshot.daily, hourly: snapshot.hourly, monthly: snapshot.monthly };
88
227
  }
89
228
  exports.loadCachedCliproxyData = loadCachedCliproxyData;
90
- // ---------------------------------------------------------------------------
91
- // Sync
92
- // ---------------------------------------------------------------------------
93
- /**
94
- * Fetch latest CLIProxy usage data and persist a snapshot to disk.
95
- * Non-fatal: logs warning and returns early if CLIProxy is unavailable.
96
- */
97
229
  async function syncCliproxyUsage(fetchRaw = stats_fetcher_1.fetchCliproxyUsageRaw) {
98
230
  const raw = await fetchRaw();
99
231
  if (raw === null) {
@@ -101,53 +233,25 @@ async function syncCliproxyUsage(fetchRaw = stats_fetcher_1.fetchCliproxyUsageRa
101
233
  return;
102
234
  }
103
235
  try {
104
- ensureCliproxyCacheDir();
105
- const daily = (0, cliproxy_usage_transformer_1.transformCliproxyToDailyUsage)(raw);
106
- const hourly = (0, cliproxy_usage_transformer_1.transformCliproxyToHourlyUsage)(raw);
107
- const monthly = (0, cliproxy_usage_transformer_1.transformCliproxyToMonthlyUsage)(raw);
108
- const snapshot = {
109
- version: SNAPSHOT_VERSION,
110
- timestamp: Date.now(),
111
- daily,
112
- hourly,
113
- monthly,
114
- };
115
- // Atomic write: temp file + rename
116
- const snapshotPath = getLatestSnapshotPath();
117
- const tempFile = snapshotPath + '.tmp';
118
- fs.writeFileSync(tempFile, JSON.stringify(snapshot), 'utf-8');
119
- fs.renameSync(tempFile, snapshotPath);
120
- console.log((0, ui_1.ok)('CLIProxy usage snapshot updated'));
236
+ await writeSnapshotWithMerge((0, cliproxy_usage_transformer_1.extractCliproxyUsageHistoryDetails)(raw));
121
237
  }
122
238
  catch (err) {
123
- // Non-fatal - stale snapshot will continue to be served
124
239
  console.log((0, ui_1.warn)('Failed to write CLIProxy snapshot:') + ` ${err.message}`);
125
240
  }
126
241
  }
127
242
  exports.syncCliproxyUsage = syncCliproxyUsage;
128
- // ---------------------------------------------------------------------------
129
- // Interval management
130
- // ---------------------------------------------------------------------------
131
- /**
132
- * Start periodic CLIProxy usage sync (every 5 minutes).
133
- * Performs an immediate sync on startup.
134
- */
135
243
  function startCliproxySync(syncNow = () => syncCliproxyUsage()) {
136
244
  if (syncIntervalId !== null) {
137
245
  return;
138
246
  }
139
247
  const intervalMin = Math.round(SYNC_INTERVAL_MS / 60000);
140
248
  console.log((0, ui_1.info)(`Starting CLIProxy usage sync (interval: ${intervalMin} min)`));
141
- // Fire-and-forget initial sync
142
249
  void syncNow();
143
250
  syncIntervalId = setInterval(() => {
144
251
  void syncNow();
145
252
  }, SYNC_INTERVAL_MS);
146
253
  }
147
254
  exports.startCliproxySync = startCliproxySync;
148
- /**
149
- * Stop periodic CLIProxy usage sync.
150
- */
151
255
  function stopCliproxySync() {
152
256
  if (syncIntervalId !== null) {
153
257
  clearInterval(syncIntervalId);
@@ -1 +1 @@
1
- {"version":3,"file":"cliproxy-usage-syncer.js","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-usage-syncer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cliproxy-usage-syncer.js","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-usage-syncer.ts"],"names":[],"mappings":"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"}
@@ -4,23 +4,39 @@
4
4
  * Transforms CLIProxy's usage API response into DailyUsage/HourlyUsage/MonthlyUsage
5
5
  * types compatible with the CCS analytics dashboard.
6
6
  */
7
- import type { CliproxyUsageApiResponse, CliproxyRequestDetail } from '../../cliproxy/stats-fetcher';
7
+ import type { CliproxyUsageApiResponse } from '../../cliproxy/stats-fetcher';
8
8
  import type { DailyUsage, HourlyUsage, MonthlyUsage } from './types';
9
- /** Flat entry pairing a model name with its request detail */
10
- interface FlatDetail {
9
+ /** Persisted request detail used to rebuild historical CLIProxy analytics buckets */
10
+ export interface CliproxyUsageHistoryDetail {
11
11
  model: string;
12
- detail: CliproxyRequestDetail;
12
+ provider?: string;
13
+ timestamp: string;
14
+ source: string;
15
+ authIndex: string;
16
+ inputTokens: number;
17
+ outputTokens: number;
18
+ cacheReadTokens: number;
19
+ requestCount: number;
20
+ cost: number;
21
+ failed: boolean;
13
22
  }
14
23
  /**
15
24
  * Flatten the nested response.usage.apis[provider].models[model].details[]
16
- * structure into a flat array. Failed requests are skipped.
25
+ * structure into normalized history details. Failed requests are retained only
26
+ * when they still report tracked token usage that analytics can account for.
17
27
  */
18
- export declare function flattenCliproxyDetails(response: CliproxyUsageApiResponse): FlatDetail[];
28
+ export declare function extractCliproxyUsageHistoryDetails(response: CliproxyUsageApiResponse): CliproxyUsageHistoryDetail[];
29
+ export declare function mergeCliproxyUsageHistoryDetails(existing: CliproxyUsageHistoryDetail[], incoming: CliproxyUsageHistoryDetail[]): CliproxyUsageHistoryDetail[];
30
+ export declare function pruneCliproxyUsageHistoryDetails(details: CliproxyUsageHistoryDetail[], oldestTimestamp: number): CliproxyUsageHistoryDetail[];
19
31
  /** Transform CLIProxy usage response into DailyUsage array (sorted descending by date) */
20
32
  export declare function transformCliproxyToDailyUsage(response: CliproxyUsageApiResponse): DailyUsage[];
21
33
  /** Transform CLIProxy usage response into HourlyUsage array (sorted descending by hour) */
22
34
  export declare function transformCliproxyToHourlyUsage(response: CliproxyUsageApiResponse): HourlyUsage[];
23
35
  /** Transform CLIProxy usage response into MonthlyUsage array (sorted descending by month) */
24
36
  export declare function transformCliproxyToMonthlyUsage(response: CliproxyUsageApiResponse): MonthlyUsage[];
25
- export {};
37
+ export declare function buildCliproxyUsageHistoryAggregates(details: CliproxyUsageHistoryDetail[]): {
38
+ daily: DailyUsage[];
39
+ hourly: HourlyUsage[];
40
+ monthly: MonthlyUsage[];
41
+ };
26
42
  //# sourceMappingURL=cliproxy-usage-transformer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cliproxy-usage-transformer.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-usage-transformer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEpG,OAAO,KAAK,EAAkB,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMrF,8DAA8D;AAC9D,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,UAAU,EAAE,CAkBvF;AAiDD,0FAA0F;AAC1F,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,wBAAwB,GAAG,UAAU,EAAE,CAsB9F;AAED,2FAA2F;AAC3F,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,wBAAwB,GAAG,WAAW,EAAE,CA0BhG;AAED,6FAA6F;AAC7F,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,wBAAwB,GACjC,YAAY,EAAE,CAkBhB"}
1
+ {"version":3,"file":"cliproxy-usage-transformer.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-usage-transformer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAyB,MAAM,8BAA8B,CAAC;AAEpG,OAAO,KAAK,EAAkB,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAOrF,qFAAqF;AACrF,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AAuED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,wBAAwB,GACjC,0BAA0B,EAAE,CAkB9B;AAiBD,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,0BAA0B,EAAE,EACtC,QAAQ,EAAE,0BAA0B,EAAE,GACrC,0BAA0B,EAAE,CAyC9B;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,0BAA0B,EAAE,EACrC,eAAe,EAAE,MAAM,GACtB,0BAA0B,EAAE,CAK9B;AAoED,0FAA0F;AAC1F,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,wBAAwB,GAAG,UAAU,EAAE,CAsB9F;AAED,2FAA2F;AAC3F,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,wBAAwB,GAAG,WAAW,EAAE,CA2BhG;AAED,6FAA6F;AAC7F,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,wBAAwB,GACjC,YAAY,EAAE,CAkBhB;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,0BAA0B,EAAE,GAAG;IAC1F,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAgEA"}