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