ai-cc-router 0.2.6 → 0.2.7
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/dist/cli/cmd-service.js +0 -4
- package/dist/cli/cmd-setup.js +1 -2
- package/dist/cli/cmd-start.js +0 -4
- package/dist/config/telemetry.js +1 -3
- package/dist/proxy/server.js +1 -4
- package/dist/utils/telemetry.js +11 -37
- package/package.json +1 -1
package/dist/cli/cmd-service.js
CHANGED
|
@@ -4,7 +4,6 @@ import { fileURLToPath } from "url";
|
|
|
4
4
|
import { join, dirname } from "path";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { detectPlatform } from "../utils/platform.js";
|
|
7
|
-
import { showTelemetryDisclosureIfNeeded } from "../utils/telemetry.js";
|
|
8
7
|
const execFileAsync = promisify(execFile);
|
|
9
8
|
// Resolve the path to the compiled CLI entry point
|
|
10
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -19,9 +18,6 @@ export function registerService(program) {
|
|
|
19
18
|
.description("Register cc-router to start automatically on system boot")
|
|
20
19
|
.action(async () => {
|
|
21
20
|
console.log(chalk.cyan("\nInstalling cc-router as a system service...\n"));
|
|
22
|
-
// Show telemetry disclosure once before the service takes over — after
|
|
23
|
-
// this point output goes to PM2 logs, not the user's terminal.
|
|
24
|
-
showTelemetryDisclosureIfNeeded();
|
|
25
21
|
// 1. Verify PM2 is installed
|
|
26
22
|
const pm2Version = await getPm2Version();
|
|
27
23
|
if (!pm2Version) {
|
package/dist/cli/cmd-setup.js
CHANGED
|
@@ -13,7 +13,7 @@ import { DEFAULT_RATE_LIMITS } from "../proxy/types.js";
|
|
|
13
13
|
import { existsSync } from "fs";
|
|
14
14
|
import { checkMitmproxyInstalled, isCaCertInstalled, generateCaCert, installCaCert, writeAddonScript, getNetworkExtensionStatus, openNetworkExtensionSettings, } from "../interceptor/mitmproxy-manager.js";
|
|
15
15
|
import { printDesktopSupportExplainer, printNetworkExtensionInstructions } from "./cmd-client.js";
|
|
16
|
-
import { trackEvent
|
|
16
|
+
import { trackEvent } from "../utils/telemetry.js";
|
|
17
17
|
const execFileAsync = promisify(execFile);
|
|
18
18
|
// ─── Public registration ──────────────────────────────────────────────────────
|
|
19
19
|
export function registerSetup(program) {
|
|
@@ -213,7 +213,6 @@ async function runSetupWizard({ addMode }) {
|
|
|
213
213
|
console.log(chalk.bold(`\n${"━".repeat(40)}\n Saving\n${"━".repeat(40)}\n`));
|
|
214
214
|
saveAccounts(merged);
|
|
215
215
|
console.log(chalk.green(` ✓ ${merged.length} account(s) saved to ~/.cc-router/accounts.json`));
|
|
216
|
-
showTelemetryDisclosureIfNeeded();
|
|
217
216
|
void trackEvent("setup_completed", { account_count: merged.length });
|
|
218
217
|
// ─── Post-setup interactive flow ─────────────────────────────────────────
|
|
219
218
|
await runPostSetupFlow(merged.length);
|
package/dist/cli/cmd-start.js
CHANGED
|
@@ -2,7 +2,6 @@ import { execFile } from "child_process";
|
|
|
2
2
|
import { promisify } from "util";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { PROXY_PORT, LITELLM_PORT, ACCOUNTS_PATH } from "../config/paths.js";
|
|
5
|
-
import { showTelemetryDisclosureIfNeeded } from "../utils/telemetry.js";
|
|
6
5
|
const execFileAsync = promisify(execFile);
|
|
7
6
|
export function registerStart(program) {
|
|
8
7
|
program
|
|
@@ -14,9 +13,6 @@ export function registerStart(program) {
|
|
|
14
13
|
.option("--accounts <path>", "Path to accounts.json", ACCOUNTS_PATH)
|
|
15
14
|
.action(async (opts) => {
|
|
16
15
|
if (opts.daemon) {
|
|
17
|
-
// Show telemetry disclosure in the user's terminal before handing off
|
|
18
|
-
// to PM2 — once the daemon starts, its stdout goes to PM2 logs.
|
|
19
|
-
showTelemetryDisclosureIfNeeded();
|
|
20
16
|
await startDaemon();
|
|
21
17
|
return;
|
|
22
18
|
}
|
package/dist/config/telemetry.js
CHANGED
|
@@ -7,7 +7,6 @@ function defaultState() {
|
|
|
7
7
|
enabled: true,
|
|
8
8
|
installId: randomUUID(),
|
|
9
9
|
firstRunAt: new Date().toISOString(),
|
|
10
|
-
disclosureShown: false,
|
|
11
10
|
};
|
|
12
11
|
}
|
|
13
12
|
// Read the telemetry state, creating and persisting a fresh one on first run.
|
|
@@ -25,9 +24,8 @@ export function loadTelemetryState() {
|
|
|
25
24
|
enabled: raw.enabled ?? true,
|
|
26
25
|
installId: raw.installId ?? randomUUID(),
|
|
27
26
|
firstRunAt: raw.firstRunAt ?? new Date().toISOString(),
|
|
28
|
-
disclosureShown: raw.disclosureShown ?? false,
|
|
29
27
|
};
|
|
30
|
-
if (!raw.installId
|
|
28
|
+
if (!raw.installId) {
|
|
31
29
|
writeTelemetryState(state);
|
|
32
30
|
}
|
|
33
31
|
return state;
|
package/dist/proxy/server.js
CHANGED
|
@@ -6,7 +6,7 @@ import { TokenPool } from "./token-pool.js";
|
|
|
6
6
|
import { needsRefresh, refreshAccountToken, saveAccounts, startRefreshLoop } from "./token-refresher.js";
|
|
7
7
|
import { loadAccounts, accountsFileExists, readAccountsFromPath, readConfig } from "../config/manager.js";
|
|
8
8
|
import { checkForUpdate, performUpdate, restartSelf } from "../utils/self-update.js";
|
|
9
|
-
import { trackEvent, startHeartbeat
|
|
9
|
+
import { trackEvent, startHeartbeat } from "../utils/telemetry.js";
|
|
10
10
|
import { loadTelemetryState } from "../config/telemetry.js";
|
|
11
11
|
import { logRoute, logError, logStartup } from "./logger.js";
|
|
12
12
|
import { stats } from "./stats.js";
|
|
@@ -386,10 +386,7 @@ export async function startServer(opts = {}) {
|
|
|
386
386
|
if (autoUpdate)
|
|
387
387
|
console.log(chalk.gray(" Auto-update: enabled (patch/minor)"));
|
|
388
388
|
// Anonymous telemetry — fire-and-forget, never blocks proxy startup.
|
|
389
|
-
// Show the disclosure on the very first start (covers existing users
|
|
390
|
-
// upgrading from versions before telemetry existed) before sending anything.
|
|
391
389
|
try {
|
|
392
|
-
showTelemetryDisclosureIfNeeded();
|
|
393
390
|
const telemetryState = loadTelemetryState();
|
|
394
391
|
// First-run detection: if the install is brand new, emit app_started too
|
|
395
392
|
const firstRunAge = Date.now() - new Date(telemetryState.firstRunAt).getTime();
|
package/dist/utils/telemetry.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import os from "os";
|
|
2
|
-
import
|
|
3
|
-
import { isTelemetryEnabled, loadTelemetryState, writeTelemetryState } from "../config/telemetry.js";
|
|
2
|
+
import { isTelemetryEnabled, loadTelemetryState } from "../config/telemetry.js";
|
|
4
3
|
import { detectPlatform } from "./platform.js";
|
|
5
4
|
import { getCurrentVersion } from "./self-update.js";
|
|
6
5
|
// ─── Aptabase configuration ──────────────────────────────────────────────────
|
|
@@ -19,10 +18,12 @@ function getOsName() {
|
|
|
19
18
|
}
|
|
20
19
|
function getLocale() {
|
|
21
20
|
try {
|
|
22
|
-
|
|
21
|
+
// Aptabase limits locale to 10 characters — truncate extended subtags
|
|
22
|
+
const raw = Intl.DateTimeFormat().resolvedOptions().locale;
|
|
23
|
+
return raw.length <= 10 ? raw : raw.slice(0, 10);
|
|
23
24
|
}
|
|
24
25
|
catch {
|
|
25
|
-
return process.env["LANG"]?.split(".")[0] ?? "unknown";
|
|
26
|
+
return process.env["LANG"]?.split(".")[0]?.slice(0, 10) ?? "unknown";
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
function getSystemProps() {
|
|
@@ -37,11 +38,14 @@ function getSystemProps() {
|
|
|
37
38
|
sdkVersion: `cc-router@${getCurrentVersion()}`,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
// Session ID
|
|
41
|
-
//
|
|
41
|
+
// Session ID groups events from the same install within an hourly window,
|
|
42
|
+
// without leaking timing precision finer than 1h.
|
|
43
|
+
// Aptabase limits sessionId to 36 characters. A UUID with dashes is already 36,
|
|
44
|
+
// so we strip dashes and take the first 24 hex chars + epochHours (~6-7 digits).
|
|
42
45
|
function getSessionId(installId) {
|
|
43
46
|
const epochHours = Math.floor(Date.now() / 3_600_000);
|
|
44
|
-
|
|
47
|
+
const shortId = installId.replace(/-/g, "").slice(0, 24);
|
|
48
|
+
return `${shortId}${epochHours}`;
|
|
45
49
|
}
|
|
46
50
|
// ─── Public API ──────────────────────────────────────────────────────────────
|
|
47
51
|
// Fire-and-forget: never throws, never blocks the caller. If telemetry is
|
|
@@ -85,33 +89,3 @@ export function startHeartbeat(accountCount) {
|
|
|
85
89
|
}, 6 * 60 * 60 * 1000);
|
|
86
90
|
timer.unref();
|
|
87
91
|
}
|
|
88
|
-
// One-time disclosure shown the very first time CC-Router runs after install
|
|
89
|
-
// or upgrade. Idempotent — gated by telemetry.disclosureShown so it's safe to
|
|
90
|
-
// call from multiple entry points (setup wizard, foreground start, daemon
|
|
91
|
-
// start, service install). Returns true if the disclosure was just shown.
|
|
92
|
-
export function showTelemetryDisclosureIfNeeded() {
|
|
93
|
-
try {
|
|
94
|
-
const state = loadTelemetryState();
|
|
95
|
-
if (state.disclosureShown)
|
|
96
|
-
return false;
|
|
97
|
-
console.log();
|
|
98
|
-
console.log(chalk.dim("─".repeat(60)));
|
|
99
|
-
console.log(chalk.bold(" Anonymous usage analytics"));
|
|
100
|
-
console.log();
|
|
101
|
-
console.log(" CC-Router sends anonymous lifecycle events (version, OS,");
|
|
102
|
-
console.log(" startup, heartbeat) to help us understand usage and prioritize");
|
|
103
|
-
console.log(" improvements. No IPs, no tokens, no prompts, no request content.");
|
|
104
|
-
console.log();
|
|
105
|
-
console.log(` Disable: ${chalk.cyan("cc-router telemetry off")}`);
|
|
106
|
-
console.log(` Or set: ${chalk.cyan("DO_NOT_TRACK=1")} | ${chalk.cyan("CC_ROUTER_TELEMETRY=0")}`);
|
|
107
|
-
console.log(` Source: ${chalk.dim("src/utils/telemetry.ts")}`);
|
|
108
|
-
console.log(chalk.dim("─".repeat(60)));
|
|
109
|
-
console.log();
|
|
110
|
-
state.disclosureShown = true;
|
|
111
|
-
writeTelemetryState(state);
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
}
|