modelstat 0.0.12 → 0.0.14
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/README.md +3 -3
- package/dist/cli.mjs +81 -20
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,9 +22,9 @@ modelstat connect
|
|
|
22
22
|
Or via npm / pnpm / bun:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install -g modelstat && modelstat connect
|
|
26
|
-
pnpm add -g modelstat && modelstat connect
|
|
27
|
-
bun add -g modelstat && modelstat connect
|
|
25
|
+
npm install -g @modelstat/agent && modelstat connect
|
|
26
|
+
pnpm add -g @modelstat/agent && modelstat connect
|
|
27
|
+
bun add -g @modelstat/agent && modelstat connect
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
`modelstat connect` installs a **launchd user agent** on macOS (at `~/Library/LaunchAgents/ai.modelstat.agent.plist`) or a **systemd user unit** on Linux (at `~/.config/systemd/user/modelstat.service`). The daemon starts automatically on login.
|
package/dist/cli.mjs
CHANGED
|
@@ -4484,7 +4484,22 @@ var init_schemas = __esm({
|
|
|
4484
4484
|
});
|
|
4485
4485
|
|
|
4486
4486
|
// ../../packages/core/src/ids.ts
|
|
4487
|
-
|
|
4487
|
+
function ulid(seedTime) {
|
|
4488
|
+
const t = seedTime ?? Date.now();
|
|
4489
|
+
let timeStr = "";
|
|
4490
|
+
let ts = t;
|
|
4491
|
+
for (let i = 9; i >= 0; i--) {
|
|
4492
|
+
timeStr = ULID_ALPHABET[ts % 32] + timeStr;
|
|
4493
|
+
ts = Math.floor(ts / 32);
|
|
4494
|
+
}
|
|
4495
|
+
const bytes = new Uint8Array(16);
|
|
4496
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
4497
|
+
let randStr = "";
|
|
4498
|
+
for (let i = 0; i < 16; i++) {
|
|
4499
|
+
randStr += ULID_ALPHABET[bytes[i] % 32];
|
|
4500
|
+
}
|
|
4501
|
+
return timeStr + randStr;
|
|
4502
|
+
}
|
|
4488
4503
|
function sourceEventId(deviceId, sourceOrFilePath, byteOffsetMaybe) {
|
|
4489
4504
|
let key;
|
|
4490
4505
|
if (typeof sourceOrFilePath === "string") {
|
|
@@ -4513,10 +4528,11 @@ function segmentId(sessionId, startedAtMs, endedAtMs, sourceEventIds) {
|
|
|
4513
4528
|
}
|
|
4514
4529
|
return `seg_${h.toString(36)}`;
|
|
4515
4530
|
}
|
|
4516
|
-
var batchId;
|
|
4531
|
+
var ULID_ALPHABET, batchId;
|
|
4517
4532
|
var init_ids = __esm({
|
|
4518
4533
|
"../../packages/core/src/ids.ts"() {
|
|
4519
4534
|
"use strict";
|
|
4535
|
+
ULID_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
4520
4536
|
batchId = () => ulid();
|
|
4521
4537
|
}
|
|
4522
4538
|
});
|
|
@@ -7748,7 +7764,7 @@ async function reportDiscovery(report) {
|
|
|
7748
7764
|
}
|
|
7749
7765
|
}
|
|
7750
7766
|
async function fetchDeviceViewByClaim(claimCode) {
|
|
7751
|
-
const res = await request(`${state.apiUrl}/v1/
|
|
7767
|
+
const res = await request(`${state.apiUrl}/v1/device/${encodeURIComponent(claimCode)}`, {
|
|
7752
7768
|
method: "GET"
|
|
7753
7769
|
});
|
|
7754
7770
|
if (res.statusCode === 404) return null;
|
|
@@ -7759,7 +7775,7 @@ async function fetchDeviceViewByClaim(claimCode) {
|
|
|
7759
7775
|
}
|
|
7760
7776
|
async function fetchDeviceViewJobsByClaim(claimCode) {
|
|
7761
7777
|
const res = await request(
|
|
7762
|
-
`${state.apiUrl}/v1/
|
|
7778
|
+
`${state.apiUrl}/v1/device/${encodeURIComponent(claimCode)}/jobs`,
|
|
7763
7779
|
{ method: "GET" }
|
|
7764
7780
|
);
|
|
7765
7781
|
if (res.statusCode === 404) return null;
|
|
@@ -7770,7 +7786,7 @@ async function fetchDeviceViewJobsByClaim(claimCode) {
|
|
|
7770
7786
|
}
|
|
7771
7787
|
async function fetchDeviceViewLedgerByClaim(claimCode) {
|
|
7772
7788
|
const res = await request(
|
|
7773
|
-
`${state.apiUrl}/v1/
|
|
7789
|
+
`${state.apiUrl}/v1/device/${encodeURIComponent(claimCode)}/ledger`,
|
|
7774
7790
|
{ method: "GET" }
|
|
7775
7791
|
);
|
|
7776
7792
|
if (res.statusCode === 404) return null;
|
|
@@ -8908,6 +8924,7 @@ function generateUuidV7() {
|
|
|
8908
8924
|
}
|
|
8909
8925
|
async function cmdSelfRegister() {
|
|
8910
8926
|
const deviceUuid = state.deviceUuid ?? generateUuidV7();
|
|
8927
|
+
const fresh = !state.deviceUuid;
|
|
8911
8928
|
const fingerprint = {
|
|
8912
8929
|
hostname: hostname2(),
|
|
8913
8930
|
os_family: osFamily(),
|
|
@@ -8916,6 +8933,14 @@ async function cmdSelfRegister() {
|
|
|
8916
8933
|
agent: "modelstat-agent-dev",
|
|
8917
8934
|
agent_version: AGENT_VERSION3
|
|
8918
8935
|
};
|
|
8936
|
+
if (fresh) {
|
|
8937
|
+
process.stdout.write(` \x1B[2mgenerated UUIDv7 ${deviceUuid.slice(0, 8)}\u2026\x1B[0m
|
|
8938
|
+
`);
|
|
8939
|
+
}
|
|
8940
|
+
process.stdout.write(
|
|
8941
|
+
` \x1B[2m\u2192 POST ${state.apiUrl}/v1/devices/self-register\x1B[0m
|
|
8942
|
+
`
|
|
8943
|
+
);
|
|
8919
8944
|
const res = await selfRegister({
|
|
8920
8945
|
device_uuid: deviceUuid,
|
|
8921
8946
|
fingerprint
|
|
@@ -8925,16 +8950,12 @@ async function cmdSelfRegister() {
|
|
|
8925
8950
|
state.setBearer(res.device_secret);
|
|
8926
8951
|
state.setClaimCode(res.claim_code);
|
|
8927
8952
|
state.setClaimUrl(res.claim_url);
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
console.log(` ${res.claim_url}`);
|
|
8935
|
-
console.log(` code: ${res.claim_code}`);
|
|
8936
|
-
console.log();
|
|
8937
|
-
console.log(` state: ${state.storePath}`);
|
|
8953
|
+
process.stdout.write(` \x1B[32m\u2713\x1B[0m registered device_id=${res.device_id}
|
|
8954
|
+
`);
|
|
8955
|
+
process.stdout.write(` \x1B[32m\u2713\x1B[0m secret ${res.secret_prefix}\u2026 (hashed on server, never re-sent)
|
|
8956
|
+
`);
|
|
8957
|
+
process.stdout.write(` \x1B[32m\u2713\x1B[0m claim code ${res.claim_code}
|
|
8958
|
+
`);
|
|
8938
8959
|
}
|
|
8939
8960
|
async function cmdAwaitClaim() {
|
|
8940
8961
|
const secret = state.bearer;
|
|
@@ -8971,12 +8992,43 @@ function emitEvent(opts, event, fields = {}) {
|
|
|
8971
8992
|
);
|
|
8972
8993
|
}
|
|
8973
8994
|
async function cmdConnect(opts) {
|
|
8995
|
+
const step = (msg) => {
|
|
8996
|
+
if (opts.json) return;
|
|
8997
|
+
process.stdout.write(`\x1B[1;36m\u25B8\x1B[0m ${msg}
|
|
8998
|
+
`);
|
|
8999
|
+
};
|
|
9000
|
+
const ok = (msg) => {
|
|
9001
|
+
if (opts.json) return;
|
|
9002
|
+
process.stdout.write(` \x1B[32m\u2713\x1B[0m ${msg}
|
|
9003
|
+
`);
|
|
9004
|
+
};
|
|
9005
|
+
const warn = (msg) => {
|
|
9006
|
+
if (opts.json) return;
|
|
9007
|
+
process.stdout.write(` \x1B[33m\u26A0\x1B[0m ${msg}
|
|
9008
|
+
`);
|
|
9009
|
+
};
|
|
9010
|
+
const hasLegacyBearer = !!state.bearer && !state.bearer.startsWith("ds_live_");
|
|
9011
|
+
const hasLegacyClaim = !!state.claimUrl && (state.claimUrl.includes("/c/") || /\/d\/[a-z]/.test(state.claimUrl) || !state.claimUrl.includes("/device/"));
|
|
9012
|
+
const hasLegacyCode = !!state.claimCode && !/^[0-9a-hjkmnp-tv-z]{32}$/.test(state.claimCode);
|
|
9013
|
+
if (hasLegacyBearer || hasLegacyClaim || hasLegacyCode) {
|
|
9014
|
+
step("Legacy state detected from an older version \u2014 wiping");
|
|
9015
|
+
state.setBearer(null);
|
|
9016
|
+
state.setDeviceId(null);
|
|
9017
|
+
state.setDeviceUuid(null);
|
|
9018
|
+
state.setClaimCode(null);
|
|
9019
|
+
state.setClaimUrl(null);
|
|
9020
|
+
ok("clean slate");
|
|
9021
|
+
}
|
|
8974
9022
|
if (!state.deviceUuid || !state.bearer || !state.deviceId) {
|
|
9023
|
+
step("Registering this device with modelstat.ai");
|
|
8975
9024
|
await cmdSelfRegister();
|
|
9025
|
+
} else {
|
|
9026
|
+
step("Re-using existing device identity");
|
|
9027
|
+
ok(`device ${state.deviceId}`);
|
|
8976
9028
|
}
|
|
8977
9029
|
const claimCode = state.claimCode ?? "(unknown)";
|
|
8978
|
-
const claimUrl = state.claimUrl ?? `https://modelstat.ai/
|
|
8979
|
-
const agentUrl = `https://modelstat.ai/
|
|
9030
|
+
const claimUrl = state.claimUrl ?? `https://modelstat.ai/device/${claimCode}`;
|
|
9031
|
+
const agentUrl = `https://modelstat.ai/device-agent/${claimCode}`;
|
|
8980
9032
|
emitEvent(opts, "registered", {
|
|
8981
9033
|
device_uuid: state.deviceUuid,
|
|
8982
9034
|
device_id: state.deviceId,
|
|
@@ -8985,36 +9037,45 @@ async function cmdConnect(opts) {
|
|
|
8985
9037
|
agent_url: agentUrl
|
|
8986
9038
|
});
|
|
8987
9039
|
if (platform4() === "darwin") {
|
|
9040
|
+
step("Installing menu-bar tray (macOS)");
|
|
8988
9041
|
try {
|
|
8989
9042
|
const src = bundledTrayAppPath();
|
|
8990
9043
|
if (src) {
|
|
8991
9044
|
const out = installTrayApp(src);
|
|
8992
|
-
if (out)
|
|
9045
|
+
if (out) {
|
|
9046
|
+
emitEvent(opts, "tray_installed", { path: out.installedAt });
|
|
9047
|
+
ok(`tray at ${out.installedAt}`);
|
|
9048
|
+
}
|
|
8993
9049
|
} else {
|
|
8994
9050
|
emitEvent(opts, "tray_not_bundled", {});
|
|
9051
|
+
warn("no bundled tray \u2014 skipping (install Xcode CLI tools and re-run to get the icon)");
|
|
8995
9052
|
}
|
|
8996
9053
|
} catch (e) {
|
|
8997
9054
|
emitEvent(opts, "tray_install_failed", { error: e.message });
|
|
9055
|
+
warn(`tray install skipped: ${e.message}`);
|
|
8998
9056
|
}
|
|
8999
9057
|
}
|
|
9058
|
+
step("Installing background service so the agent survives reboots");
|
|
9000
9059
|
let serviceOk = false;
|
|
9001
9060
|
try {
|
|
9002
9061
|
const svc = installService();
|
|
9003
9062
|
serviceOk = true;
|
|
9004
9063
|
emitEvent(opts, "service_installed", { path: svc.path, logs: svc.logs });
|
|
9064
|
+
ok(`${platform4() === "darwin" ? "launchd" : "systemd --user"}: ${svc.path}`);
|
|
9005
9065
|
} catch (e) {
|
|
9006
9066
|
emitEvent(opts, "service_install_failed", { error: e.message });
|
|
9067
|
+
warn(`couldn't install service: ${e.message}`);
|
|
9068
|
+
warn("will run in the foreground instead \u2014 don't close this terminal");
|
|
9007
9069
|
}
|
|
9008
9070
|
if (!opts.json) {
|
|
9009
9071
|
const tray = trayStatus();
|
|
9010
|
-
const svcOk = serviceOk;
|
|
9011
9072
|
const line = "\u2501".repeat(60);
|
|
9012
9073
|
console.log();
|
|
9013
9074
|
console.log(line);
|
|
9014
9075
|
console.log(` \u2713 Device registered \u2014 streaming your AI usage to modelstat.`);
|
|
9015
9076
|
console.log();
|
|
9016
9077
|
console.log(
|
|
9017
|
-
` service : \x1B[${
|
|
9078
|
+
` service : \x1B[${serviceOk ? "32" : "33"}m${serviceOk ? "installed" : "foreground"}\x1B[0m`
|
|
9018
9079
|
);
|
|
9019
9080
|
if (platform4() === "darwin") {
|
|
9020
9081
|
console.log(
|