modelstat 0.0.48 → 0.0.49
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.mjs +306 -194
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -44914,6 +44914,116 @@ var init_api = __esm({
|
|
|
44914
44914
|
}
|
|
44915
44915
|
});
|
|
44916
44916
|
|
|
44917
|
+
// src/machine-key.ts
|
|
44918
|
+
import { spawnSync } from "child_process";
|
|
44919
|
+
import { createHash as createHash3 } from "crypto";
|
|
44920
|
+
import { chmodSync as chmodSync2, existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
44921
|
+
import { homedir as homedir4, platform as platform2 } from "os";
|
|
44922
|
+
import { join as join4 } from "path";
|
|
44923
|
+
function macosPlatformUuid() {
|
|
44924
|
+
try {
|
|
44925
|
+
const r = spawnSync("ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {
|
|
44926
|
+
encoding: "utf8",
|
|
44927
|
+
timeout: 4e3
|
|
44928
|
+
});
|
|
44929
|
+
if (r.status !== 0 || !r.stdout) return null;
|
|
44930
|
+
const m = /"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(r.stdout);
|
|
44931
|
+
return m?.[1]?.trim() || null;
|
|
44932
|
+
} catch {
|
|
44933
|
+
return null;
|
|
44934
|
+
}
|
|
44935
|
+
}
|
|
44936
|
+
function linuxMachineId() {
|
|
44937
|
+
for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
44938
|
+
try {
|
|
44939
|
+
const v = readFileSync3(p, "utf8").trim();
|
|
44940
|
+
if (v) return v;
|
|
44941
|
+
} catch {
|
|
44942
|
+
}
|
|
44943
|
+
}
|
|
44944
|
+
return null;
|
|
44945
|
+
}
|
|
44946
|
+
function windowsMachineGuid() {
|
|
44947
|
+
try {
|
|
44948
|
+
const r = spawnSync(
|
|
44949
|
+
"reg",
|
|
44950
|
+
["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"],
|
|
44951
|
+
{ encoding: "utf8", timeout: 4e3 }
|
|
44952
|
+
);
|
|
44953
|
+
if (r.status !== 0 || !r.stdout) return null;
|
|
44954
|
+
const m = /MachineGuid\s+REG_SZ\s+([0-9a-fA-F-]+)/.exec(r.stdout);
|
|
44955
|
+
return m?.[1]?.trim() || null;
|
|
44956
|
+
} catch {
|
|
44957
|
+
return null;
|
|
44958
|
+
}
|
|
44959
|
+
}
|
|
44960
|
+
function fallbackKey() {
|
|
44961
|
+
try {
|
|
44962
|
+
if (existsSync6(FALLBACK_KEY_FILE)) {
|
|
44963
|
+
const v = readFileSync3(FALLBACK_KEY_FILE, "utf8").trim();
|
|
44964
|
+
if (v) return v;
|
|
44965
|
+
}
|
|
44966
|
+
} catch {
|
|
44967
|
+
}
|
|
44968
|
+
const fresh = createHash3("sha256").update(`${MACHINE_KEY_SALT}:fallback:${Date.now()}:${Math.random()}`).digest("hex");
|
|
44969
|
+
try {
|
|
44970
|
+
mkdirSync2(ROOT2, { recursive: true, mode: 448 });
|
|
44971
|
+
writeFileSync3(FALLBACK_KEY_FILE, fresh, { mode: 384 });
|
|
44972
|
+
chmodSync2(FALLBACK_KEY_FILE, 384);
|
|
44973
|
+
} catch {
|
|
44974
|
+
}
|
|
44975
|
+
return fresh;
|
|
44976
|
+
}
|
|
44977
|
+
function resolveRaw() {
|
|
44978
|
+
const p = platform2();
|
|
44979
|
+
if (p === "darwin") {
|
|
44980
|
+
const v = macosPlatformUuid();
|
|
44981
|
+
if (v) return { raw: v, source: "macos-ioplatform" };
|
|
44982
|
+
} else if (p === "win32") {
|
|
44983
|
+
const v = windowsMachineGuid();
|
|
44984
|
+
if (v) return { raw: v, source: "windows-guid" };
|
|
44985
|
+
} else {
|
|
44986
|
+
const v = linuxMachineId();
|
|
44987
|
+
if (v) return { raw: v, source: "linux-machine-id" };
|
|
44988
|
+
}
|
|
44989
|
+
return { raw: fallbackKey(), source: "fallback-file" };
|
|
44990
|
+
}
|
|
44991
|
+
function machineKey() {
|
|
44992
|
+
if (cachedKey) return cachedKey;
|
|
44993
|
+
const { raw, source } = resolveRaw();
|
|
44994
|
+
cachedSource = source;
|
|
44995
|
+
cachedKey = createHash3("sha256").update(`${MACHINE_KEY_SALT}:${raw}`).digest("hex");
|
|
44996
|
+
return cachedKey;
|
|
44997
|
+
}
|
|
44998
|
+
function machineKeySource() {
|
|
44999
|
+
if (!cachedSource) machineKey();
|
|
45000
|
+
return cachedSource;
|
|
45001
|
+
}
|
|
45002
|
+
function deviceUuidFromMachineKey(key = machineKey()) {
|
|
45003
|
+
const nsHex = DEVICE_UUID_NAMESPACE.replace(/-/g, "");
|
|
45004
|
+
const nsBytes = Buffer.from(nsHex, "hex");
|
|
45005
|
+
const hash = createHash3("sha1").update(nsBytes).update(key).digest();
|
|
45006
|
+
const b = Buffer.from(hash.subarray(0, 16));
|
|
45007
|
+
b[6] = b[6] & 15 | 80;
|
|
45008
|
+
b[8] = b[8] & 63 | 128;
|
|
45009
|
+
const h = b.toString("hex");
|
|
45010
|
+
return [h.slice(0, 8), h.slice(8, 12), h.slice(12, 16), h.slice(16, 20), h.slice(20, 32)].join(
|
|
45011
|
+
"-"
|
|
45012
|
+
);
|
|
45013
|
+
}
|
|
45014
|
+
var MACHINE_KEY_SALT, DEVICE_UUID_NAMESPACE, ROOT2, FALLBACK_KEY_FILE, cachedKey, cachedSource;
|
|
45015
|
+
var init_machine_key = __esm({
|
|
45016
|
+
"src/machine-key.ts"() {
|
|
45017
|
+
"use strict";
|
|
45018
|
+
MACHINE_KEY_SALT = "modelstat.device.machine-key.v1";
|
|
45019
|
+
DEVICE_UUID_NAMESPACE = "6f1d2c9a-8b3e-4a7f-9c2d-0e5a1b6c7d8e";
|
|
45020
|
+
ROOT2 = join4(homedir4(), ".modelstat");
|
|
45021
|
+
FALLBACK_KEY_FILE = join4(ROOT2, "machine-key");
|
|
45022
|
+
cachedKey = null;
|
|
45023
|
+
cachedSource = null;
|
|
45024
|
+
}
|
|
45025
|
+
});
|
|
45026
|
+
|
|
44917
45027
|
// ../../packages/companion-core/src/contracts/index.ts
|
|
44918
45028
|
var init_contracts = __esm({
|
|
44919
45029
|
"../../packages/companion-core/src/contracts/index.ts"() {
|
|
@@ -45696,14 +45806,14 @@ var init_ollama = __esm({
|
|
|
45696
45806
|
|
|
45697
45807
|
// ../../packages/companion-core/src/node/llama.ts
|
|
45698
45808
|
import { mkdir } from "fs/promises";
|
|
45699
|
-
import { existsSync as
|
|
45700
|
-
import { homedir as
|
|
45701
|
-
import { dirname as dirname5, join as
|
|
45809
|
+
import { existsSync as existsSync7 } from "fs";
|
|
45810
|
+
import { homedir as homedir5 } from "os";
|
|
45811
|
+
import { dirname as dirname5, join as join5 } from "path";
|
|
45702
45812
|
function defaultLlamaConfig() {
|
|
45703
45813
|
const env2 = globalThis.process?.env ?? {};
|
|
45704
|
-
const modelsDir = env2.MODELSTAT_MODELS_DIR ??
|
|
45814
|
+
const modelsDir = env2.MODELSTAT_MODELS_DIR ?? join5(homedir5(), ".modelstat", "models");
|
|
45705
45815
|
const modelUrl = env2.MODELSTAT_LLAMA_MODEL_URL ?? DEFAULT_LLAMA_MODEL_URL;
|
|
45706
|
-
const modelPath = env2.MODELSTAT_LLAMA_MODEL_PATH ??
|
|
45816
|
+
const modelPath = env2.MODELSTAT_LLAMA_MODEL_PATH ?? join5(modelsDir, basenameFromUrl(modelUrl));
|
|
45707
45817
|
return {
|
|
45708
45818
|
modelPath,
|
|
45709
45819
|
modelUrl,
|
|
@@ -45724,7 +45834,7 @@ function basenameFromUrl(url) {
|
|
|
45724
45834
|
return parts[parts.length - 1] || "model.gguf";
|
|
45725
45835
|
}
|
|
45726
45836
|
async function ensureLlamaModel(cfg = defaultLlamaConfig()) {
|
|
45727
|
-
if (
|
|
45837
|
+
if (existsSync7(cfg.modelPath)) return cfg.modelPath;
|
|
45728
45838
|
await mkdir(dirname5(cfg.modelPath), { recursive: true });
|
|
45729
45839
|
const res = await fetch(cfg.modelUrl);
|
|
45730
45840
|
if (!res.ok || !res.body) {
|
|
@@ -46237,8 +46347,8 @@ var init_pipeline2 = __esm({
|
|
|
46237
46347
|
|
|
46238
46348
|
// src/scan.ts
|
|
46239
46349
|
import { readdir, stat as stat2 } from "fs/promises";
|
|
46240
|
-
import { homedir as
|
|
46241
|
-
import { join as
|
|
46350
|
+
import { homedir as homedir6 } from "os";
|
|
46351
|
+
import { join as join6 } from "path";
|
|
46242
46352
|
function withNonNullTokens(e) {
|
|
46243
46353
|
return e.tokens ? e : { ...e, tokens: { ...ZERO_TOKENS } };
|
|
46244
46354
|
}
|
|
@@ -46247,16 +46357,16 @@ async function scanAll(cb = {}) {
|
|
|
46247
46357
|
if (!deviceId) throw new Error("agent not enrolled \u2014 run `register` first");
|
|
46248
46358
|
const jobs = [];
|
|
46249
46359
|
try {
|
|
46250
|
-
const base =
|
|
46360
|
+
const base = join6(homedir6(), ".claude/projects");
|
|
46251
46361
|
const projects = await readdir(base).catch(() => []);
|
|
46252
46362
|
for (const p of projects) {
|
|
46253
|
-
const dir =
|
|
46363
|
+
const dir = join6(base, p);
|
|
46254
46364
|
const ds = await stat2(dir).catch(() => null);
|
|
46255
46365
|
if (!ds?.isDirectory()) continue;
|
|
46256
46366
|
const files = await readdir(dir);
|
|
46257
46367
|
for (const f of files) {
|
|
46258
46368
|
if (!f.endsWith(".jsonl")) continue;
|
|
46259
|
-
const full =
|
|
46369
|
+
const full = join6(dir, f);
|
|
46260
46370
|
jobs.push({
|
|
46261
46371
|
path: full,
|
|
46262
46372
|
parse: async (sink2) => {
|
|
@@ -46270,17 +46380,17 @@ async function scanAll(cb = {}) {
|
|
|
46270
46380
|
console.warn("claude scan skipped:", e.message);
|
|
46271
46381
|
}
|
|
46272
46382
|
try {
|
|
46273
|
-
const base =
|
|
46383
|
+
const base = join6(homedir6(), ".codex/sessions");
|
|
46274
46384
|
const years = await readdir(base).catch(() => []);
|
|
46275
46385
|
for (const y of years) {
|
|
46276
|
-
const months = await readdir(
|
|
46386
|
+
const months = await readdir(join6(base, y)).catch(() => []);
|
|
46277
46387
|
for (const m of months) {
|
|
46278
|
-
const days = await readdir(
|
|
46388
|
+
const days = await readdir(join6(base, y, m)).catch(() => []);
|
|
46279
46389
|
for (const d of days) {
|
|
46280
|
-
const files = await readdir(
|
|
46390
|
+
const files = await readdir(join6(base, y, m, d)).catch(() => []);
|
|
46281
46391
|
for (const f of files) {
|
|
46282
46392
|
if (!f.startsWith("rollout-") || !f.endsWith(".jsonl")) continue;
|
|
46283
|
-
const full =
|
|
46393
|
+
const full = join6(base, y, m, d, f);
|
|
46284
46394
|
jobs.push({
|
|
46285
46395
|
path: full,
|
|
46286
46396
|
parse: async (sink2) => {
|
|
@@ -46397,7 +46507,7 @@ var init_scan = __esm({
|
|
|
46397
46507
|
init_api();
|
|
46398
46508
|
init_config2();
|
|
46399
46509
|
init_pipeline2();
|
|
46400
|
-
AGENT_VERSION = true ? "agent-0.0.
|
|
46510
|
+
AGENT_VERSION = true ? "agent-0.0.49" : "agent-dev";
|
|
46401
46511
|
BATCH_MAX_EVENTS = 2e3;
|
|
46402
46512
|
BATCH_MAX_TOOL_CALLS = 2e4;
|
|
46403
46513
|
BATCH_BUFFER_HARD_CAP = BATCH_MAX_EVENTS * 2;
|
|
@@ -46414,17 +46524,17 @@ var init_scan = __esm({
|
|
|
46414
46524
|
// src/lock.ts
|
|
46415
46525
|
import {
|
|
46416
46526
|
closeSync,
|
|
46417
|
-
existsSync as
|
|
46418
|
-
mkdirSync as
|
|
46527
|
+
existsSync as existsSync9,
|
|
46528
|
+
mkdirSync as mkdirSync4,
|
|
46419
46529
|
openSync,
|
|
46420
|
-
readFileSync as
|
|
46530
|
+
readFileSync as readFileSync5,
|
|
46421
46531
|
renameSync as renameSync2,
|
|
46422
46532
|
unlinkSync as unlinkSync2,
|
|
46423
|
-
writeFileSync as
|
|
46533
|
+
writeFileSync as writeFileSync5,
|
|
46424
46534
|
writeSync
|
|
46425
46535
|
} from "fs";
|
|
46426
|
-
import { homedir as
|
|
46427
|
-
import { join as
|
|
46536
|
+
import { homedir as homedir8 } from "os";
|
|
46537
|
+
import { join as join8 } from "path";
|
|
46428
46538
|
function isProcessAlive(pid) {
|
|
46429
46539
|
if (!pid || pid <= 0) return false;
|
|
46430
46540
|
try {
|
|
@@ -46438,7 +46548,7 @@ function isProcessAlive(pid) {
|
|
|
46438
46548
|
}
|
|
46439
46549
|
function readDaemonLock(lockFile = LOCK_FILE) {
|
|
46440
46550
|
try {
|
|
46441
|
-
const raw =
|
|
46551
|
+
const raw = readFileSync5(lockFile, "utf8");
|
|
46442
46552
|
const obj = JSON.parse(raw);
|
|
46443
46553
|
if (typeof obj.pid !== "number") return null;
|
|
46444
46554
|
return {
|
|
@@ -46452,7 +46562,7 @@ function readDaemonLock(lockFile = LOCK_FILE) {
|
|
|
46452
46562
|
}
|
|
46453
46563
|
}
|
|
46454
46564
|
function writeLockAtomic(meta) {
|
|
46455
|
-
|
|
46565
|
+
mkdirSync4(LOCK_DIR, { recursive: true });
|
|
46456
46566
|
const tmp = `${LOCK_FILE}.${meta.pid}.${Date.now()}.tmp`;
|
|
46457
46567
|
const fd = openSync(tmp, "wx");
|
|
46458
46568
|
try {
|
|
@@ -46544,8 +46654,8 @@ var LOCK_DIR, LOCK_FILE, LOCK_RECHECK_MS;
|
|
|
46544
46654
|
var init_lock = __esm({
|
|
46545
46655
|
"src/lock.ts"() {
|
|
46546
46656
|
"use strict";
|
|
46547
|
-
LOCK_DIR =
|
|
46548
|
-
LOCK_FILE =
|
|
46657
|
+
LOCK_DIR = join8(homedir8(), ".modelstat");
|
|
46658
|
+
LOCK_FILE = join8(LOCK_DIR, "daemon.lock");
|
|
46549
46659
|
LOCK_RECHECK_MS = 5e3;
|
|
46550
46660
|
}
|
|
46551
46661
|
});
|
|
@@ -48342,7 +48452,7 @@ __export(daemon_exports, {
|
|
|
48342
48452
|
setQueue: () => setQueue,
|
|
48343
48453
|
setStat: () => setStat
|
|
48344
48454
|
});
|
|
48345
|
-
import { existsSync as
|
|
48455
|
+
import { existsSync as existsSync10, statSync as statSync2 } from "fs";
|
|
48346
48456
|
function setPhase(phase, message) {
|
|
48347
48457
|
status.phase = phase;
|
|
48348
48458
|
status.message = message ?? null;
|
|
@@ -48384,7 +48494,8 @@ function snapshotBody() {
|
|
|
48384
48494
|
queue_size: status.queueSize,
|
|
48385
48495
|
stats: status.stats,
|
|
48386
48496
|
last_event_at: status.lastEventAt,
|
|
48387
|
-
agent_version: AGENT_VERSION2
|
|
48497
|
+
agent_version: AGENT_VERSION2,
|
|
48498
|
+
machine_id: machineKey()
|
|
48388
48499
|
};
|
|
48389
48500
|
}
|
|
48390
48501
|
function scheduleLocalFlush() {
|
|
@@ -48421,12 +48532,12 @@ async function sendHeartbeat() {
|
|
|
48421
48532
|
writeLocalStatus(body).catch(() => void 0);
|
|
48422
48533
|
}
|
|
48423
48534
|
async function rotateRunawayLogs() {
|
|
48424
|
-
const { homedir:
|
|
48425
|
-
const { join:
|
|
48535
|
+
const { homedir: homedir11 } = await import("os");
|
|
48536
|
+
const { join: join13 } = await import("path");
|
|
48426
48537
|
const { open: open2, stat: stat6, truncate, writeFile } = await import("fs/promises");
|
|
48427
|
-
const dir =
|
|
48538
|
+
const dir = join13(homedir11(), ".modelstat", "logs");
|
|
48428
48539
|
for (const name of ["out.log", "err.log"]) {
|
|
48429
|
-
const p =
|
|
48540
|
+
const p = join13(dir, name);
|
|
48430
48541
|
try {
|
|
48431
48542
|
const st = await stat6(p);
|
|
48432
48543
|
if (st.size <= LOG_MAX_BYTES) continue;
|
|
@@ -48448,16 +48559,16 @@ async function rotateRunawayLogs() {
|
|
|
48448
48559
|
}
|
|
48449
48560
|
}
|
|
48450
48561
|
async function writeLocalStatus(snapshot) {
|
|
48451
|
-
const { homedir:
|
|
48452
|
-
const { join:
|
|
48562
|
+
const { homedir: homedir11 } = await import("os");
|
|
48563
|
+
const { join: join13 } = await import("path");
|
|
48453
48564
|
const { writeFile, mkdir: mkdir2, rename } = await import("fs/promises");
|
|
48454
48565
|
if (!lastStatusPath) {
|
|
48455
|
-
const dir =
|
|
48566
|
+
const dir = join13(homedir11(), ".modelstat");
|
|
48456
48567
|
try {
|
|
48457
48568
|
await mkdir2(dir, { recursive: true });
|
|
48458
48569
|
} catch {
|
|
48459
48570
|
}
|
|
48460
|
-
lastStatusPath =
|
|
48571
|
+
lastStatusPath = join13(dir, "last-status.json");
|
|
48461
48572
|
}
|
|
48462
48573
|
const tmp = `${lastStatusPath}.tmp`;
|
|
48463
48574
|
try {
|
|
@@ -48499,10 +48610,7 @@ async function runScanCycle(reason) {
|
|
|
48499
48610
|
if (p.segment === 0) {
|
|
48500
48611
|
setPhase("processing", `Analyzing${sess}`);
|
|
48501
48612
|
} else {
|
|
48502
|
-
setPhase(
|
|
48503
|
-
"processing",
|
|
48504
|
-
`Summarising segment ${p.segment}/${p.segmentTotal}${sess}`
|
|
48505
|
-
);
|
|
48613
|
+
setPhase("processing", `Summarising segment ${p.segment}/${p.segmentTotal}${sess}`);
|
|
48506
48614
|
}
|
|
48507
48615
|
},
|
|
48508
48616
|
onUpload({ segments }) {
|
|
@@ -48557,12 +48665,8 @@ async function runDaemon(opts = {}) {
|
|
|
48557
48665
|
lock.ageSec
|
|
48558
48666
|
)} ago, agent ${lock.owner.agentVersion}.`
|
|
48559
48667
|
);
|
|
48560
|
-
console.log(
|
|
48561
|
-
|
|
48562
|
-
);
|
|
48563
|
-
console.log(
|
|
48564
|
-
" \u2192 to force-replace it: modelstat start --force"
|
|
48565
|
-
);
|
|
48668
|
+
console.log(" \u2192 to stop it: kill " + lock.owner.pid);
|
|
48669
|
+
console.log(" \u2192 to force-replace it: modelstat start --force");
|
|
48566
48670
|
return;
|
|
48567
48671
|
}
|
|
48568
48672
|
setPhase("starting", "Booting");
|
|
@@ -48590,21 +48694,19 @@ async function runDaemon(opts = {}) {
|
|
|
48590
48694
|
await runDiscovery();
|
|
48591
48695
|
await requestScan("startup");
|
|
48592
48696
|
const chokidar = (await Promise.resolve().then(() => (init_esm2(), esm_exports))).default;
|
|
48593
|
-
const { homedir:
|
|
48594
|
-
const { join:
|
|
48595
|
-
const home2 =
|
|
48697
|
+
const { homedir: homedir11, platform: platform6 } = await import("os");
|
|
48698
|
+
const { join: join13 } = await import("path");
|
|
48699
|
+
const home2 = homedir11();
|
|
48596
48700
|
const dirs = [
|
|
48597
|
-
|
|
48598
|
-
|
|
48599
|
-
|
|
48600
|
-
|
|
48601
|
-
...
|
|
48602
|
-
|
|
48603
|
-
|
|
48604
|
-
] : [
|
|
48605
|
-
|
|
48606
|
-
]
|
|
48607
|
-
].filter((p) => existsSync9(p) && statSync2(p).isDirectory());
|
|
48701
|
+
join13(home2, ".claude/projects"),
|
|
48702
|
+
join13(home2, ".codex/sessions"),
|
|
48703
|
+
join13(home2, ".cursor/ai-tracking"),
|
|
48704
|
+
join13(home2, ".gemini"),
|
|
48705
|
+
...platform6() === "darwin" ? [
|
|
48706
|
+
join13(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
48707
|
+
join13(home2, "Library/Application Support/Claude")
|
|
48708
|
+
] : [join13(home2, ".config/Cursor/User/workspaceStorage")]
|
|
48709
|
+
].filter((p) => existsSync10(p) && statSync2(p).isDirectory());
|
|
48608
48710
|
setPhase("watching", `Watching ${dirs.length} directories`);
|
|
48609
48711
|
const watcher = chokidar.watch(dirs, {
|
|
48610
48712
|
persistent: true,
|
|
@@ -48629,10 +48731,7 @@ async function runDaemon(opts = {}) {
|
|
|
48629
48731
|
});
|
|
48630
48732
|
const backstop = setInterval(() => void requestScan("interval"), SCAN_INTERVAL_MS);
|
|
48631
48733
|
backstop.unref();
|
|
48632
|
-
const discoveryTimer = setInterval(
|
|
48633
|
-
() => void runDiscovery(),
|
|
48634
|
-
DISCOVERY_INTERVAL_MS
|
|
48635
|
-
);
|
|
48734
|
+
const discoveryTimer = setInterval(() => void runDiscovery(), DISCOVERY_INTERVAL_MS);
|
|
48636
48735
|
discoveryTimer.unref();
|
|
48637
48736
|
const shutdown = async () => {
|
|
48638
48737
|
setPhase("offline", "Shutting down");
|
|
@@ -48649,15 +48748,16 @@ var import_undici2, AGENT_VERSION2, HEARTBEAT_INTERVAL_MS, SCAN_INTERVAL_MS, DIS
|
|
|
48649
48748
|
var init_daemon = __esm({
|
|
48650
48749
|
"src/daemon.ts"() {
|
|
48651
48750
|
"use strict";
|
|
48652
|
-
import_undici2 = __toESM(require_undici(), 1);
|
|
48653
48751
|
init_logger();
|
|
48654
48752
|
init_src2();
|
|
48753
|
+
import_undici2 = __toESM(require_undici(), 1);
|
|
48655
48754
|
init_api();
|
|
48656
48755
|
init_config2();
|
|
48657
48756
|
init_lock();
|
|
48757
|
+
init_machine_key();
|
|
48658
48758
|
init_scan();
|
|
48659
48759
|
init_single_flight();
|
|
48660
|
-
AGENT_VERSION2 = true ? "agent-0.0.
|
|
48760
|
+
AGENT_VERSION2 = true ? "agent-0.0.49" : "agent-dev";
|
|
48661
48761
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
48662
48762
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
48663
48763
|
DISCOVERY_INTERVAL_MS = 6e4;
|
|
@@ -48685,37 +48785,37 @@ var watch_exports = {};
|
|
|
48685
48785
|
__export(watch_exports, {
|
|
48686
48786
|
watchForever: () => watchForever
|
|
48687
48787
|
});
|
|
48688
|
-
import { existsSync as
|
|
48689
|
-
import { homedir as
|
|
48690
|
-
import { join as
|
|
48788
|
+
import { existsSync as existsSync11 } from "fs";
|
|
48789
|
+
import { homedir as homedir10, platform as platform4 } from "os";
|
|
48790
|
+
import { join as join12 } from "path";
|
|
48691
48791
|
function resolveWatchDirs() {
|
|
48692
|
-
const home2 =
|
|
48693
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
48694
|
-
const xdgData = process.env.XDG_DATA_HOME ??
|
|
48792
|
+
const home2 = homedir10();
|
|
48793
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join12(home2, ".config");
|
|
48794
|
+
const xdgData = process.env.XDG_DATA_HOME ?? join12(home2, ".local/share");
|
|
48695
48795
|
const candidates = [
|
|
48696
48796
|
// universal (default HOME-rooted CLI data dirs)
|
|
48697
|
-
|
|
48698
|
-
|
|
48699
|
-
|
|
48700
|
-
|
|
48701
|
-
|
|
48797
|
+
join12(home2, ".claude/projects"),
|
|
48798
|
+
join12(home2, ".codex/sessions"),
|
|
48799
|
+
join12(home2, ".cursor/ai-tracking"),
|
|
48800
|
+
join12(home2, ".gemini"),
|
|
48801
|
+
join12(home2, ".aider"),
|
|
48702
48802
|
// XDG / Linux
|
|
48703
|
-
|
|
48704
|
-
|
|
48705
|
-
|
|
48706
|
-
|
|
48707
|
-
|
|
48708
|
-
|
|
48803
|
+
join12(xdgConfig, "claude/projects"),
|
|
48804
|
+
join12(xdgConfig, "codex/sessions"),
|
|
48805
|
+
join12(xdgConfig, "Cursor/User/workspaceStorage"),
|
|
48806
|
+
join12(xdgConfig, "Code/User/workspaceStorage"),
|
|
48807
|
+
join12(xdgConfig, "Code - Insiders/User/workspaceStorage"),
|
|
48808
|
+
join12(xdgData, "claude/projects"),
|
|
48709
48809
|
// macOS
|
|
48710
|
-
...
|
|
48711
|
-
|
|
48712
|
-
|
|
48713
|
-
|
|
48714
|
-
|
|
48715
|
-
|
|
48810
|
+
...platform4() === "darwin" ? [
|
|
48811
|
+
join12(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
48812
|
+
join12(home2, "Library/Application Support/Claude"),
|
|
48813
|
+
join12(home2, "Library/Application Support/Code/User/workspaceStorage"),
|
|
48814
|
+
join12(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
|
|
48815
|
+
join12(home2, "Library/Application Support/Zed")
|
|
48716
48816
|
] : []
|
|
48717
48817
|
];
|
|
48718
|
-
return Array.from(new Set(candidates)).filter((p) =>
|
|
48818
|
+
return Array.from(new Set(candidates)).filter((p) => existsSync11(p));
|
|
48719
48819
|
}
|
|
48720
48820
|
async function safeScan(reason) {
|
|
48721
48821
|
if (scanning) {
|
|
@@ -48780,53 +48880,53 @@ init_src2();
|
|
|
48780
48880
|
init_api();
|
|
48781
48881
|
init_config2();
|
|
48782
48882
|
init_identity();
|
|
48883
|
+
init_machine_key();
|
|
48783
48884
|
init_scan();
|
|
48784
48885
|
import { spawn } from "child_process";
|
|
48785
|
-
import {
|
|
48786
|
-
import { arch as cpuArch, hostname as hostname2, platform as platform4, release } from "os";
|
|
48886
|
+
import { arch as cpuArch, hostname as hostname2, platform as platform5, release } from "os";
|
|
48787
48887
|
import { createInterface as createInterface3 } from "readline";
|
|
48788
48888
|
|
|
48789
48889
|
// src/service.ts
|
|
48790
|
-
import { spawnSync } from "child_process";
|
|
48890
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
48791
48891
|
import {
|
|
48792
48892
|
copyFileSync,
|
|
48793
|
-
existsSync as
|
|
48794
|
-
mkdirSync as
|
|
48795
|
-
readFileSync as
|
|
48893
|
+
existsSync as existsSync8,
|
|
48894
|
+
mkdirSync as mkdirSync3,
|
|
48895
|
+
readFileSync as readFileSync4,
|
|
48796
48896
|
realpathSync,
|
|
48797
48897
|
unlinkSync,
|
|
48798
|
-
writeFileSync as
|
|
48898
|
+
writeFileSync as writeFileSync4
|
|
48799
48899
|
} from "fs";
|
|
48800
48900
|
import { createRequire } from "module";
|
|
48801
|
-
import { homedir as
|
|
48802
|
-
import { dirname as dirname6, join as
|
|
48901
|
+
import { homedir as homedir7, platform as platform3, userInfo } from "os";
|
|
48902
|
+
import { dirname as dirname6, join as join7 } from "path";
|
|
48803
48903
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
48804
48904
|
var SERVICE_LABEL = "ai.modelstat.agent";
|
|
48805
48905
|
var SYSTEMD_UNIT = "modelstat";
|
|
48806
48906
|
function home() {
|
|
48807
|
-
return
|
|
48907
|
+
return homedir7();
|
|
48808
48908
|
}
|
|
48809
48909
|
function stateDir() {
|
|
48810
|
-
return
|
|
48910
|
+
return join7(home(), ".modelstat");
|
|
48811
48911
|
}
|
|
48812
48912
|
function binDir() {
|
|
48813
|
-
return
|
|
48913
|
+
return join7(stateDir(), "bin");
|
|
48814
48914
|
}
|
|
48815
48915
|
function logDir() {
|
|
48816
|
-
return
|
|
48916
|
+
return join7(stateDir(), "logs");
|
|
48817
48917
|
}
|
|
48818
48918
|
function installedCliPath() {
|
|
48819
|
-
return
|
|
48919
|
+
return join7(binDir(), "modelstat.mjs");
|
|
48820
48920
|
}
|
|
48821
48921
|
function runningCliPath() {
|
|
48822
48922
|
return fileURLToPath2(import.meta.url).replace(/service\.(mjs|js|ts)$/, "cli.mjs");
|
|
48823
48923
|
}
|
|
48824
48924
|
function installBundle() {
|
|
48825
|
-
|
|
48826
|
-
|
|
48925
|
+
mkdirSync3(binDir(), { recursive: true });
|
|
48926
|
+
mkdirSync3(logDir(), { recursive: true });
|
|
48827
48927
|
const src = runningCliPath();
|
|
48828
48928
|
const dest = installedCliPath();
|
|
48829
|
-
if (!
|
|
48929
|
+
if (!existsSync8(src)) {
|
|
48830
48930
|
throw new Error(
|
|
48831
48931
|
`Can't find the CLI bundle to install from (${src}). Are you running a local dev build?`
|
|
48832
48932
|
);
|
|
@@ -48844,9 +48944,9 @@ function sourceLlamaVersion(sourceCli) {
|
|
|
48844
48944
|
const req = createRequire(sourceCli);
|
|
48845
48945
|
let d = dirname6(realpathSync(req.resolve("node-llama-cpp")));
|
|
48846
48946
|
for (let i = 0; i < 10; i++) {
|
|
48847
|
-
const pj =
|
|
48848
|
-
if (
|
|
48849
|
-
const p = JSON.parse(
|
|
48947
|
+
const pj = join7(d, "package.json");
|
|
48948
|
+
if (existsSync8(pj)) {
|
|
48949
|
+
const p = JSON.parse(readFileSync4(pj, "utf8"));
|
|
48850
48950
|
if (p.name === "node-llama-cpp" && p.version) return p.version;
|
|
48851
48951
|
}
|
|
48852
48952
|
const up = dirname6(d);
|
|
@@ -48862,19 +48962,19 @@ function installNativeRuntime(sourceCli) {
|
|
|
48862
48962
|
const dest = binDir();
|
|
48863
48963
|
try {
|
|
48864
48964
|
const have = JSON.parse(
|
|
48865
|
-
|
|
48866
|
-
|
|
48965
|
+
readFileSync4(
|
|
48966
|
+
join7(dest, "node_modules", "node-llama-cpp", "package.json"),
|
|
48867
48967
|
"utf8"
|
|
48868
48968
|
)
|
|
48869
48969
|
);
|
|
48870
48970
|
if (have.version === version) return [`node-llama-cpp@${version} (cached)`];
|
|
48871
48971
|
} catch {
|
|
48872
48972
|
}
|
|
48873
|
-
|
|
48973
|
+
mkdirSync3(dest, { recursive: true });
|
|
48874
48974
|
const childEnv = { ...process.env };
|
|
48875
48975
|
delete childEnv.npm_config_global;
|
|
48876
48976
|
delete childEnv.npm_config_prefix;
|
|
48877
|
-
const r =
|
|
48977
|
+
const r = spawnSync2(
|
|
48878
48978
|
"npm",
|
|
48879
48979
|
[
|
|
48880
48980
|
"install",
|
|
@@ -48904,21 +49004,21 @@ function nodeBinary() {
|
|
|
48904
49004
|
return process.execPath;
|
|
48905
49005
|
}
|
|
48906
49006
|
function plistPath() {
|
|
48907
|
-
return
|
|
49007
|
+
return join7(home(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
|
|
48908
49008
|
}
|
|
48909
49009
|
function locateTrayExecutable() {
|
|
48910
49010
|
const candidates = [
|
|
48911
|
-
|
|
49011
|
+
join7(home(), "Applications", "ModelstatTray.app", "Contents", "MacOS", "modelstat-tray"),
|
|
48912
49012
|
"/Applications/ModelstatTray.app/Contents/MacOS/modelstat-tray"
|
|
48913
49013
|
];
|
|
48914
49014
|
for (const p of candidates) {
|
|
48915
|
-
if (
|
|
49015
|
+
if (existsSync8(p)) return p;
|
|
48916
49016
|
}
|
|
48917
49017
|
return null;
|
|
48918
49018
|
}
|
|
48919
49019
|
function writePlist(cliPath) {
|
|
48920
49020
|
const p = plistPath();
|
|
48921
|
-
|
|
49021
|
+
mkdirSync3(dirname6(p), { recursive: true });
|
|
48922
49022
|
const tray = locateTrayExecutable();
|
|
48923
49023
|
const programArgs = tray ? ` <string>${tray}</string>` : [
|
|
48924
49024
|
` <string>${nodeBinary()}</string>`,
|
|
@@ -48938,8 +49038,8 @@ ${programArgs}
|
|
|
48938
49038
|
<key>KeepAlive</key>
|
|
48939
49039
|
<dict><key>SuccessfulExit</key><false/></dict>
|
|
48940
49040
|
<key>ThrottleInterval</key><integer>30</integer>
|
|
48941
|
-
<key>StandardOutPath</key><string>${
|
|
48942
|
-
<key>StandardErrorPath</key><string>${
|
|
49041
|
+
<key>StandardOutPath</key><string>${join7(logDir(), "out.log")}</string>
|
|
49042
|
+
<key>StandardErrorPath</key><string>${join7(logDir(), "err.log")}</string>
|
|
48943
49043
|
<key>EnvironmentVariables</key>
|
|
48944
49044
|
<dict>
|
|
48945
49045
|
<key>PATH</key><string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
|
|
@@ -48953,11 +49053,11 @@ ${programArgs}
|
|
|
48953
49053
|
</dict>
|
|
48954
49054
|
</plist>
|
|
48955
49055
|
`;
|
|
48956
|
-
|
|
49056
|
+
writeFileSync4(p, plist, { mode: 420 });
|
|
48957
49057
|
return p;
|
|
48958
49058
|
}
|
|
48959
49059
|
function launchctl(args) {
|
|
48960
|
-
const r =
|
|
49060
|
+
const r = spawnSync2("launchctl", args, { encoding: "utf8" });
|
|
48961
49061
|
return { ok: r.status === 0, out: r.stdout ?? "", err: r.stderr ?? "" };
|
|
48962
49062
|
}
|
|
48963
49063
|
function macInstall() {
|
|
@@ -48984,7 +49084,7 @@ function macUninstall() {
|
|
|
48984
49084
|
const target = `gui/${uid}/${SERVICE_LABEL}`;
|
|
48985
49085
|
launchctl(["bootout", target]);
|
|
48986
49086
|
const plist = plistPath();
|
|
48987
|
-
if (
|
|
49087
|
+
if (existsSync8(plist)) {
|
|
48988
49088
|
try {
|
|
48989
49089
|
unlinkSync(plist);
|
|
48990
49090
|
} catch {
|
|
@@ -48997,12 +49097,12 @@ function macStatus() {
|
|
|
48997
49097
|
return { running: r.ok, hint: r.ok ? "launchd managed" : "not installed" };
|
|
48998
49098
|
}
|
|
48999
49099
|
function systemdUnitPath() {
|
|
49000
|
-
const xdg = process.env.XDG_CONFIG_HOME ??
|
|
49001
|
-
return
|
|
49100
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join7(home(), ".config");
|
|
49101
|
+
return join7(xdg, "systemd", "user", `${SYSTEMD_UNIT}.service`);
|
|
49002
49102
|
}
|
|
49003
49103
|
function writeSystemdUnit(cliPath) {
|
|
49004
49104
|
const unitPath = systemdUnitPath();
|
|
49005
|
-
|
|
49105
|
+
mkdirSync3(dirname6(unitPath), { recursive: true });
|
|
49006
49106
|
const unit = `[Unit]
|
|
49007
49107
|
Description=modelstat agent
|
|
49008
49108
|
Documentation=https://modelstat.ai
|
|
@@ -49021,17 +49121,17 @@ RestartSec=10
|
|
|
49021
49121
|
# Don't restart-storm if the service is persistently unreachable.
|
|
49022
49122
|
StartLimitIntervalSec=300
|
|
49023
49123
|
StartLimitBurst=10
|
|
49024
|
-
StandardOutput=append:${
|
|
49025
|
-
StandardError=append:${
|
|
49124
|
+
StandardOutput=append:${join7(logDir(), "out.log")}
|
|
49125
|
+
StandardError=append:${join7(logDir(), "err.log")}
|
|
49026
49126
|
|
|
49027
49127
|
[Install]
|
|
49028
49128
|
WantedBy=default.target
|
|
49029
49129
|
`;
|
|
49030
|
-
|
|
49130
|
+
writeFileSync4(unitPath, unit, { mode: 420 });
|
|
49031
49131
|
return unitPath;
|
|
49032
49132
|
}
|
|
49033
49133
|
function systemctl(args) {
|
|
49034
|
-
const r =
|
|
49134
|
+
const r = spawnSync2("systemctl", ["--user", ...args], { encoding: "utf8" });
|
|
49035
49135
|
return { ok: r.status === 0, out: r.stdout ?? "", err: r.stderr ?? "" };
|
|
49036
49136
|
}
|
|
49037
49137
|
function linuxInstall() {
|
|
@@ -49047,7 +49147,7 @@ function linuxInstall() {
|
|
|
49047
49147
|
function linuxUninstall() {
|
|
49048
49148
|
systemctl(["disable", "--now", `${SYSTEMD_UNIT}.service`]);
|
|
49049
49149
|
const unit = systemdUnitPath();
|
|
49050
|
-
if (
|
|
49150
|
+
if (existsSync8(unit)) {
|
|
49051
49151
|
try {
|
|
49052
49152
|
unlinkSync(unit);
|
|
49053
49153
|
} catch {
|
|
@@ -49061,7 +49161,7 @@ function linuxStatus() {
|
|
|
49061
49161
|
return { running: active, hint: active ? "systemd managed" : "not running" };
|
|
49062
49162
|
}
|
|
49063
49163
|
function installService() {
|
|
49064
|
-
const p =
|
|
49164
|
+
const p = platform3();
|
|
49065
49165
|
if (p === "darwin") {
|
|
49066
49166
|
macInstall();
|
|
49067
49167
|
return { path: plistPath(), logs: logDir() };
|
|
@@ -49075,13 +49175,13 @@ function installService() {
|
|
|
49075
49175
|
);
|
|
49076
49176
|
}
|
|
49077
49177
|
function uninstallService() {
|
|
49078
|
-
const p =
|
|
49178
|
+
const p = platform3();
|
|
49079
49179
|
if (p === "darwin") return macUninstall();
|
|
49080
49180
|
if (p === "linux") return linuxUninstall();
|
|
49081
49181
|
throw new Error(`Service uninstall isn't supported on ${p}.`);
|
|
49082
49182
|
}
|
|
49083
49183
|
function serviceStatus() {
|
|
49084
|
-
const p =
|
|
49184
|
+
const p = platform3();
|
|
49085
49185
|
if (p === "darwin") return macStatus();
|
|
49086
49186
|
if (p === "linux") return linuxStatus();
|
|
49087
49187
|
return { running: false, hint: `unsupported platform (${p})` };
|
|
@@ -49090,60 +49190,60 @@ function logsDir() {
|
|
|
49090
49190
|
return logDir();
|
|
49091
49191
|
}
|
|
49092
49192
|
function installTrayApp(sourceAppPath) {
|
|
49093
|
-
if (
|
|
49094
|
-
if (!
|
|
49095
|
-
const dest =
|
|
49096
|
-
|
|
49097
|
-
|
|
49098
|
-
const r =
|
|
49193
|
+
if (platform3() !== "darwin") return null;
|
|
49194
|
+
if (!existsSync8(sourceAppPath)) return null;
|
|
49195
|
+
const dest = join7(home(), "Applications", "ModelstatTray.app");
|
|
49196
|
+
mkdirSync3(dirname6(dest), { recursive: true });
|
|
49197
|
+
spawnSync2("rm", ["-rf", dest]);
|
|
49198
|
+
const r = spawnSync2("cp", ["-R", sourceAppPath, dest], { encoding: "utf8" });
|
|
49099
49199
|
if (r.status !== 0) {
|
|
49100
49200
|
throw new Error(`cp ModelstatTray.app failed: ${r.stderr?.trim() || `exit ${r.status}`}`);
|
|
49101
49201
|
}
|
|
49102
49202
|
return { installedAt: dest };
|
|
49103
49203
|
}
|
|
49104
49204
|
function bundledTrayAppPath() {
|
|
49105
|
-
if (
|
|
49205
|
+
if (platform3() !== "darwin") return null;
|
|
49106
49206
|
const here2 = dirname6(fileURLToPath2(import.meta.url));
|
|
49107
49207
|
const candidates = [
|
|
49108
49208
|
// Pre-built .app — CI with codesigning drops one here.
|
|
49109
|
-
|
|
49209
|
+
join7(here2, "..", "vendor", "ModelstatTray.app"),
|
|
49110
49210
|
// Local dev layout: apps/agent-dev/src/service.ts → ../../tray-mac/build/ModelstatTray.app
|
|
49111
|
-
|
|
49211
|
+
join7(here2, "..", "..", "tray-mac", "build", "ModelstatTray.app")
|
|
49112
49212
|
];
|
|
49113
49213
|
for (const c of candidates) {
|
|
49114
|
-
if (
|
|
49214
|
+
if (existsSync8(c)) return c;
|
|
49115
49215
|
}
|
|
49116
49216
|
const sourceDirs = [
|
|
49117
|
-
|
|
49118
|
-
|
|
49217
|
+
join7(here2, "..", "vendor", "tray-mac"),
|
|
49218
|
+
join7(here2, "..", "..", "tray-mac")
|
|
49119
49219
|
];
|
|
49120
49220
|
for (const src of sourceDirs) {
|
|
49121
|
-
const build =
|
|
49122
|
-
if (!
|
|
49221
|
+
const build = join7(src, "build-app.sh");
|
|
49222
|
+
if (!existsSync8(build)) continue;
|
|
49123
49223
|
if (!hasSwift()) return null;
|
|
49124
|
-
const r =
|
|
49224
|
+
const r = spawnSync2("bash", [build], { cwd: src, encoding: "utf8" });
|
|
49125
49225
|
if (r.status === 0) {
|
|
49126
|
-
const app =
|
|
49127
|
-
if (
|
|
49226
|
+
const app = join7(src, "build", "ModelstatTray.app");
|
|
49227
|
+
if (existsSync8(app)) return app;
|
|
49128
49228
|
}
|
|
49129
49229
|
}
|
|
49130
49230
|
return null;
|
|
49131
49231
|
}
|
|
49132
49232
|
function hasSwift() {
|
|
49133
|
-
const r =
|
|
49233
|
+
const r = spawnSync2("swift", ["--version"], { encoding: "utf8" });
|
|
49134
49234
|
return r.status === 0;
|
|
49135
49235
|
}
|
|
49136
49236
|
function trayStatus() {
|
|
49137
|
-
if (
|
|
49237
|
+
if (platform3() !== "darwin") return { installed: false, path: null };
|
|
49138
49238
|
const exe = locateTrayExecutable();
|
|
49139
49239
|
return exe ? { installed: true, path: exe.replace(/\/Contents\/MacOS\/modelstat-tray$/, "") } : { installed: false, path: null };
|
|
49140
49240
|
}
|
|
49141
49241
|
|
|
49142
49242
|
// src/supervise.ts
|
|
49143
49243
|
init_lock();
|
|
49144
|
-
import { readFileSync as
|
|
49145
|
-
import { homedir as
|
|
49146
|
-
import { join as
|
|
49244
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
49245
|
+
import { homedir as homedir9 } from "os";
|
|
49246
|
+
import { join as join9 } from "path";
|
|
49147
49247
|
var STATUS_FRESH_MS = 12e4;
|
|
49148
49248
|
var BOOT_GRACE_MS = 9e4;
|
|
49149
49249
|
function decideSupervision(input) {
|
|
@@ -49160,13 +49260,13 @@ function decideSupervision(input) {
|
|
|
49160
49260
|
function daemonHealth(opts = {}) {
|
|
49161
49261
|
const now = opts.now ?? Date.now();
|
|
49162
49262
|
const pidAlive = opts.pidAlive ?? isProcessAlive;
|
|
49163
|
-
const statusPath = opts.statusPath ??
|
|
49263
|
+
const statusPath = opts.statusPath ?? join9(homedir9(), ".modelstat", "last-status.json");
|
|
49164
49264
|
const lock = opts.lockPath === void 0 ? readDaemonLock() : readDaemonLock(opts.lockPath);
|
|
49165
49265
|
const ownerAlive = lock !== null && pidAlive(lock.pid);
|
|
49166
49266
|
const lockAgeMs = lock ? ageMs(lock.startedAt, now) : null;
|
|
49167
49267
|
let statusAgeMs = null;
|
|
49168
49268
|
try {
|
|
49169
|
-
const raw =
|
|
49269
|
+
const raw = readFileSync6(statusPath, "utf8");
|
|
49170
49270
|
const writtenAt = JSON.parse(raw).written_at;
|
|
49171
49271
|
statusAgeMs = writtenAt ? ageMs(writtenAt, now) : null;
|
|
49172
49272
|
} catch {
|
|
@@ -49208,7 +49308,7 @@ async function confirmPrompt(question, defaultYes) {
|
|
|
49208
49308
|
}
|
|
49209
49309
|
}
|
|
49210
49310
|
function tryOpenBrowser(url) {
|
|
49211
|
-
const p =
|
|
49311
|
+
const p = platform5();
|
|
49212
49312
|
const cmd = p === "darwin" ? "open" : p === "win32" ? "cmd" : "xdg-open";
|
|
49213
49313
|
const args = p === "win32" ? ["/c", "start", "", url] : [url];
|
|
49214
49314
|
try {
|
|
@@ -49222,9 +49322,9 @@ function tryOpenBrowser(url) {
|
|
|
49222
49322
|
return false;
|
|
49223
49323
|
}
|
|
49224
49324
|
}
|
|
49225
|
-
var AGENT_VERSION3 = true ? "agent-0.0.
|
|
49325
|
+
var AGENT_VERSION3 = true ? "agent-0.0.49" : "agent-dev";
|
|
49226
49326
|
function osFamily() {
|
|
49227
|
-
const p =
|
|
49327
|
+
const p = platform5();
|
|
49228
49328
|
if (p === "darwin") return "macos";
|
|
49229
49329
|
if (p === "linux") return "linux";
|
|
49230
49330
|
return "other";
|
|
@@ -49235,35 +49335,33 @@ function osArch() {
|
|
|
49235
49335
|
if (a === "arm64") return "arm64";
|
|
49236
49336
|
return "other";
|
|
49237
49337
|
}
|
|
49238
|
-
function
|
|
49239
|
-
const
|
|
49240
|
-
const
|
|
49241
|
-
|
|
49242
|
-
rand[0] = rand[0] & 15 | 112;
|
|
49243
|
-
rand[2] = rand[2] & 63 | 128;
|
|
49244
|
-
const hex = tsHex + rand.toString("hex");
|
|
49245
|
-
return [
|
|
49246
|
-
hex.slice(0, 8),
|
|
49247
|
-
hex.slice(8, 12),
|
|
49248
|
-
hex.slice(12, 16),
|
|
49249
|
-
hex.slice(16, 20),
|
|
49250
|
-
hex.slice(20, 32)
|
|
49251
|
-
].join("-");
|
|
49338
|
+
function intendedDeviceUuid() {
|
|
49339
|
+
const salt = process.env.MODELSTAT_DEVICE_SALT?.trim();
|
|
49340
|
+
const key = salt ? `${machineKey()}:${salt}` : machineKey();
|
|
49341
|
+
return deviceUuidFromMachineKey(key);
|
|
49252
49342
|
}
|
|
49253
49343
|
async function cmdSelfRegister() {
|
|
49254
|
-
const deviceUuid = state.deviceUuid ??
|
|
49255
|
-
const
|
|
49344
|
+
const deviceUuid = state.deviceUuid ?? intendedDeviceUuid();
|
|
49345
|
+
const derived = !state.deviceUuid;
|
|
49346
|
+
const mid = machineKey();
|
|
49256
49347
|
const fingerprint = {
|
|
49257
49348
|
hostname: hostname2(),
|
|
49258
49349
|
os_family: osFamily(),
|
|
49259
49350
|
os_version: release(),
|
|
49260
49351
|
arch: osArch(),
|
|
49261
49352
|
agent: "modelstat-agent-dev",
|
|
49262
|
-
agent_version: AGENT_VERSION3
|
|
49353
|
+
agent_version: AGENT_VERSION3,
|
|
49354
|
+
// Stable, install-method-independent machine key. The server
|
|
49355
|
+
// dedupes self-register on this so the same physical machine can
|
|
49356
|
+
// never become two device rows, even if the UUID somehow differs
|
|
49357
|
+
// (legacy random UUID → deterministic UUID transition).
|
|
49358
|
+
machine_id: mid
|
|
49263
49359
|
};
|
|
49264
|
-
if (
|
|
49265
|
-
process.stdout.write(
|
|
49266
|
-
`)
|
|
49360
|
+
if (derived) {
|
|
49361
|
+
process.stdout.write(
|
|
49362
|
+
` \x1B[2mdevice id derived from machine key (${machineKeySource()}): ${deviceUuid.slice(0, 8)}\u2026\x1B[0m
|
|
49363
|
+
`
|
|
49364
|
+
);
|
|
49267
49365
|
}
|
|
49268
49366
|
process.stdout.write(` \x1B[2m\u2192 POST ${state.apiUrl}/v1/devices/self-register\x1B[0m
|
|
49269
49367
|
`);
|
|
@@ -49343,7 +49441,7 @@ async function cmdConnect(opts) {
|
|
|
49343
49441
|
await cmdSelfRegister();
|
|
49344
49442
|
};
|
|
49345
49443
|
if (opts.fresh && hasIdentityFile()) {
|
|
49346
|
-
step("`--fresh` passed \u2014
|
|
49444
|
+
step("`--fresh` passed \u2014 re-registering this device");
|
|
49347
49445
|
await wipeAndSelfRegister("forced fresh start");
|
|
49348
49446
|
} else if (!state.deviceUuid || !state.bearer || !state.deviceId) {
|
|
49349
49447
|
step("Registering this device with modelstat.ai");
|
|
@@ -49388,7 +49486,7 @@ async function cmdConnect(opts) {
|
|
|
49388
49486
|
claim_url: claimUrl,
|
|
49389
49487
|
agent_url: agentUrl
|
|
49390
49488
|
});
|
|
49391
|
-
if (
|
|
49489
|
+
if (platform5() === "darwin") {
|
|
49392
49490
|
step("Installing menu-bar tray (macOS)");
|
|
49393
49491
|
try {
|
|
49394
49492
|
const src = bundledTrayAppPath();
|
|
@@ -49432,7 +49530,7 @@ async function cmdConnect(opts) {
|
|
|
49432
49530
|
logs: svc.logs,
|
|
49433
49531
|
summariser_ready: modelReady
|
|
49434
49532
|
});
|
|
49435
|
-
ok(`${
|
|
49533
|
+
ok(`${platform5() === "darwin" ? "launchd" : "systemd --user"}: ${svc.path}`);
|
|
49436
49534
|
} catch (e) {
|
|
49437
49535
|
emitEvent(opts, "service_install_failed", { error: e.message });
|
|
49438
49536
|
warn(`couldn't install service: ${e.message}`);
|
|
@@ -49475,7 +49573,7 @@ async function cmdConnect(opts) {
|
|
|
49475
49573
|
` detected: \x1B[32m${discovered.installations} installs \xB7 ${discovered.identities} accounts\x1B[0m`
|
|
49476
49574
|
);
|
|
49477
49575
|
}
|
|
49478
|
-
if (
|
|
49576
|
+
if (platform5() === "darwin") {
|
|
49479
49577
|
console.log(
|
|
49480
49578
|
` tray : \x1B[${tray.installed ? "32" : "2"}m${tray.installed ? "menu-bar icon ready" : "not installed"}\x1B[0m`
|
|
49481
49579
|
);
|
|
@@ -49606,10 +49704,10 @@ function fmtTokens(v) {
|
|
|
49606
49704
|
}
|
|
49607
49705
|
async function readLocalStatus() {
|
|
49608
49706
|
try {
|
|
49609
|
-
const { homedir:
|
|
49610
|
-
const { join:
|
|
49707
|
+
const { homedir: homedir11 } = await import("os");
|
|
49708
|
+
const { join: join13 } = await import("path");
|
|
49611
49709
|
const { readFile } = await import("fs/promises");
|
|
49612
|
-
const p =
|
|
49710
|
+
const p = join13(homedir11(), ".modelstat", "last-status.json");
|
|
49613
49711
|
const txt = await readFile(p, "utf8");
|
|
49614
49712
|
return JSON.parse(txt);
|
|
49615
49713
|
} catch {
|
|
@@ -49729,11 +49827,17 @@ async function cmdJobs(args) {
|
|
|
49729
49827
|
}
|
|
49730
49828
|
}
|
|
49731
49829
|
function cmdPaths(args) {
|
|
49830
|
+
const intended = intendedDeviceUuid();
|
|
49732
49831
|
const data = {
|
|
49733
49832
|
state: state.storePath,
|
|
49833
|
+
identity: identityPath(),
|
|
49734
49834
|
logs: logsDir(),
|
|
49735
49835
|
api: state.apiUrl,
|
|
49736
|
-
paired: !!state.bearer && !!state.deviceId
|
|
49836
|
+
paired: !!state.bearer && !!state.deviceId,
|
|
49837
|
+
device_id: state.deviceId ?? "(none)",
|
|
49838
|
+
device_uuid: state.deviceUuid ?? "(none)",
|
|
49839
|
+
intended_uuid: intended,
|
|
49840
|
+
machine_key_source: machineKeySource()
|
|
49737
49841
|
};
|
|
49738
49842
|
if (args.includes("--json")) {
|
|
49739
49843
|
process.stdout.write(`${JSON.stringify(data)}
|
|
@@ -49840,10 +49944,18 @@ async function main() {
|
|
|
49840
49944
|
console.log();
|
|
49841
49945
|
console.log("Diagnostics:");
|
|
49842
49946
|
console.log(" npx modelstat@latest status \u2014 show pairing + service state");
|
|
49843
|
-
console.log(
|
|
49844
|
-
|
|
49845
|
-
|
|
49846
|
-
console.log(
|
|
49947
|
+
console.log(
|
|
49948
|
+
" npx modelstat@latest stats \u2014 live device summary: sessions \xB7 tokens \xB7 cost (--json)"
|
|
49949
|
+
);
|
|
49950
|
+
console.log(
|
|
49951
|
+
" npx modelstat@latest jobs \u2014 pipeline queue + recent processing ledger (--json)"
|
|
49952
|
+
);
|
|
49953
|
+
console.log(
|
|
49954
|
+
" npx modelstat@latest paths \u2014 print state file + log dir + api URL (--json)"
|
|
49955
|
+
);
|
|
49956
|
+
console.log(
|
|
49957
|
+
" npx modelstat@latest token \u2014 print the device token for hosted MCP / API access (--json)"
|
|
49958
|
+
);
|
|
49847
49959
|
console.log();
|
|
49848
49960
|
console.log("Dev / one-shots:");
|
|
49849
49961
|
console.log(" npx modelstat@latest scan \u2014 one-shot parse + upload of local JSONL");
|