modelstat 0.0.49 → 0.0.50

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
@@ -78,11 +78,11 @@ var init_git = __esm({
78
78
  });
79
79
 
80
80
  // ../../packages/core/src/enums.ts
81
- var TOOLS, PROVIDERS, IDENTITY_OWNER_SCOPES, INSTALL_METHODS, OS_FAMILIES, EVENT_KINDS, TOOL_CALL_STATUSES, COMPANION_PHASES, CLASSIFICATION_CONFIDENCE;
81
+ var AGENTS, PROVIDERS, IDENTITY_OWNER_SCOPES, INSTALL_METHODS, OS_FAMILIES, EVENT_KINDS, TOOL_CALL_STATUSES, COMPANION_PHASES, CLASSIFICATION_CONFIDENCE;
82
82
  var init_enums = __esm({
83
83
  "../../packages/core/src/enums.ts"() {
84
84
  "use strict";
85
- TOOLS = [
85
+ AGENTS = [
86
86
  "claude_code",
87
87
  "claude_desktop",
88
88
  "codex_cli",
@@ -105,12 +105,13 @@ var init_enums = __esm({
105
105
  "crush",
106
106
  "kimi",
107
107
  "openclaw",
108
+ "hermes",
108
109
  "ollama",
109
110
  "raw_sdk_anthropic",
110
111
  "raw_sdk_openai",
111
112
  "raw_sdk_google",
112
113
  // Web chat UIs (Chrome-extension companion). Categorically distinct
113
- // from *_cli / *_desktop tools — same provider, different surface.
114
+ // from *_cli / *_desktop agents — same provider, different surface.
114
115
  "chatgpt_web",
115
116
  "claude_web",
116
117
  "gemini_web",
@@ -4339,11 +4340,11 @@ var init_schemas = __esm({
4339
4340
  ts: external_exports.string().datetime({ offset: true }),
4340
4341
  kind: external_exports.enum(EVENT_KINDS),
4341
4342
  // Attribution
4342
- tool: external_exports.enum(TOOLS),
4343
+ agent: external_exports.enum(AGENTS),
4343
4344
  provider: external_exports.enum(PROVIDERS),
4344
4345
  model: external_exports.string().max(120).nullable(),
4345
4346
  session_id: external_exports.string().max(120),
4346
- // tool-local session id (UUID in most cases)
4347
+ // agent-local session id (UUID in most cases)
4347
4348
  turn_index: external_exports.number().int().nonnegative().nullable(),
4348
4349
  parent_event_id: external_exports.string().nullable(),
4349
4350
  // for subagent turns
@@ -4372,7 +4373,7 @@ var init_schemas = __esm({
4372
4373
  // Reference to originating file for reparsing
4373
4374
  source_file: external_exports.string().max(1024).nullable(),
4374
4375
  source_byte_offset: external_exports.number().int().nonnegative().nullable(),
4375
- // Billing mode. Tools with a flat-fee subscription tier (Claude
4376
+ // Billing mode. Agents with a flat-fee subscription tier (Claude
4376
4377
  // Code, Cursor Pro, GitHub Copilot, etc) emit events tagged
4377
4378
  // `billing: "subscription"` — the server short-circuits cost to $0
4378
4379
  // for those, since token-level pricing doesn't apply once the user
@@ -4397,7 +4398,7 @@ var init_schemas = __esm({
4397
4398
  /** sha256-based deterministic id — see @modelstat/core/ids.ts segmentId(). */
4398
4399
  segment_id: external_exports.string().max(64),
4399
4400
  session_id: external_exports.string().max(120),
4400
- tool: external_exports.enum(TOOLS),
4401
+ agent: external_exports.enum(AGENTS),
4401
4402
  started_at: external_exports.string().datetime({ offset: true }),
4402
4403
  ended_at: external_exports.string().datetime({ offset: true }),
4403
4404
  /** Pre-redacted abstract, ≤ 512 chars. Never contains PII. */
@@ -4421,15 +4422,15 @@ var init_schemas = __esm({
4421
4422
  * deterministic `tc_<djb2-base36>` of `${source_event_id}|${call_index}`
4422
4423
  * when the source line carries no id. */
4423
4424
  external_call_id: external_exports.string().max(120),
4424
- /** Tool-local session id — same id space as RawEvent.session_id. */
4425
+ /** Agent-local session id — same id space as RawEvent.session_id. */
4425
4426
  session_id: external_exports.string().max(120),
4426
4427
  /** The RawEvent that contained the tool_use (dedupe/replay anchor). */
4427
4428
  source_event_id: external_exports.string(),
4428
4429
  /** Segment containing source_event_id — filled by the companion at
4429
4430
  * batch-build time when known, else null. */
4430
4431
  segment_id: external_exports.string().max(64).nullable().default(null),
4431
- /** The agent that made the call (TOOLS enum — "tool" in legacy naming). */
4432
- agent: external_exports.enum(TOOLS),
4432
+ /** The agent that made the call (AGENTS enum). */
4433
+ agent: external_exports.enum(AGENTS),
4433
4434
  /** `builtin` or `mcp:<server>`. */
4434
4435
  server: external_exports.string().max(120),
4435
4436
  /** Bare tool name (`Bash`, `create_pr`) — normalised vendor identifier. */
@@ -4463,7 +4464,7 @@ var init_schemas = __esm({
4463
4464
  batch_id: external_exports.string(),
4464
4465
  // ULID
4465
4466
  device_id: external_exports.string(),
4466
- agent_version: external_exports.string().max(40),
4467
+ companion_version: external_exports.string().max(40),
4467
4468
  events: external_exports.array(RawEvent).max(1e4),
4468
4469
  segments: external_exports.array(Segment).max(2e3).default([]),
4469
4470
  /** Per-call tool invocations (additive — old agents omit it, old
@@ -4496,7 +4497,7 @@ var init_schemas = __esm({
4496
4497
  queue_size: external_exports.number().int().nonnegative().default(0),
4497
4498
  stats: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
4498
4499
  last_event_at: external_exports.string().datetime({ offset: true }).nullable(),
4499
- agent_version: external_exports.string().max(40)
4500
+ companion_version: external_exports.string().max(40)
4500
4501
  });
4501
4502
  DeviceEnrollment = external_exports.object({
4502
4503
  machine_id: external_exports.string(),
@@ -4505,7 +4506,7 @@ var init_schemas = __esm({
4505
4506
  os_family: external_exports.enum(OS_FAMILIES),
4506
4507
  os_version: external_exports.string().max(60),
4507
4508
  arch: external_exports.enum(["x86_64", "arm64", "other"]),
4508
- agent_version: external_exports.string().max(40)
4509
+ companion_version: external_exports.string().max(40)
4509
4510
  });
4510
4511
  DeviceSelfRegister = external_exports.object({
4511
4512
  /** Agent-generated UUIDv7 — must pass shape + recent-timestamp checks. */
@@ -4521,8 +4522,8 @@ var init_schemas = __esm({
4521
4522
  os_family: external_exports.enum(OS_FAMILIES).optional(),
4522
4523
  os_version: external_exports.string().max(60).optional(),
4523
4524
  arch: external_exports.enum(["x86_64", "arm64", "other"]).optional(),
4524
- agent: external_exports.string().max(80).optional(),
4525
- agent_version: external_exports.string().max(40).optional()
4525
+ companion: external_exports.string().max(80).optional(),
4526
+ companion_version: external_exports.string().max(40).optional()
4526
4527
  // Allow extra fields for forward-compat without breaking old agents.
4527
4528
  }).catchall(external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).default({})
4528
4529
  });
@@ -4553,7 +4554,7 @@ var init_schemas = __esm({
4553
4554
  recommended_for: external_exports.string().max(160).optional()
4554
4555
  });
4555
4556
  DetectedInstallation = external_exports.object({
4556
- tool: external_exports.enum(TOOLS),
4557
+ agent: external_exports.enum(AGENTS),
4557
4558
  install_method: external_exports.enum(INSTALL_METHODS),
4558
4559
  binary_path: external_exports.string().nullable(),
4559
4560
  data_dir: external_exports.string().nullable(),
@@ -5143,7 +5144,7 @@ async function parseClaudeCodeJsonl(ctx) {
5143
5144
  source_event_id: eventId,
5144
5145
  ts: a.timestamp,
5145
5146
  kind: "assistant_message",
5146
- tool: "claude_code",
5147
+ agent: "claude_code",
5147
5148
  provider: "anthropic",
5148
5149
  model: a.message?.model ?? null,
5149
5150
  session_id: sessionId,
@@ -5206,7 +5207,7 @@ async function parseClaudeCodeJsonl(ctx) {
5206
5207
  source_event_id: eventId,
5207
5208
  ts: u.timestamp,
5208
5209
  kind: "user_message",
5209
- tool: "claude_code",
5210
+ agent: "claude_code",
5210
5211
  provider: "anthropic",
5211
5212
  model: lastModel,
5212
5213
  session_id: sessionId,
@@ -5531,7 +5532,7 @@ async function parseCodexRollout(ctx) {
5531
5532
  source_event_id: sourceEventId(ctx.deviceId, ctx.sourceFile, offsetAtLineStart),
5532
5533
  ts,
5533
5534
  kind: "assistant_message",
5534
- tool: "codex_cli",
5535
+ agent: "codex_cli",
5535
5536
  provider: "openai",
5536
5537
  model,
5537
5538
  session_id: sessionId,
@@ -5571,7 +5572,7 @@ async function parseCodexRollout(ctx) {
5571
5572
  source_event_id: sourceEventId(ctx.deviceId, ctx.sourceFile, offsetAtLineStart),
5572
5573
  ts,
5573
5574
  kind: "user_message",
5574
- tool: "codex_cli",
5575
+ agent: "codex_cli",
5575
5576
  provider: "openai",
5576
5577
  model,
5577
5578
  session_id: sessionId,
@@ -7805,11 +7806,11 @@ async function discover(options = {}) {
7805
7806
  const v = process.env[env2];
7806
7807
  if (v) candidates.add(v);
7807
7808
  }
7808
- for (const extra of options.extraDataDirs?.[spec.tool] ?? []) candidates.add(expandPath(extra));
7809
+ for (const extra of options.extraDataDirs?.[spec.agent] ?? []) candidates.add(expandPath(extra));
7809
7810
  for (const p of candidates) {
7810
7811
  if (existsSync3(p) && statSync(p).isDirectory()) {
7811
7812
  installations.push({
7812
- tool: spec.tool,
7813
+ agent: spec.agent,
7813
7814
  install_method: "manual",
7814
7815
  binary_path: null,
7815
7816
  data_dir: p,
@@ -7828,7 +7829,7 @@ async function discover(options = {}) {
7828
7829
  if (existsSync3(p)) {
7829
7830
  const version = await safeVersionProbe(p);
7830
7831
  installations.push({
7831
- tool: spec.tool,
7832
+ agent: spec.agent,
7832
7833
  install_method: classifyInstallMethod(p, os2),
7833
7834
  binary_path: p,
7834
7835
  data_dir: null,
@@ -7848,7 +7849,7 @@ async function discover(options = {}) {
7848
7849
  const hit = apps.find((a) => a.bundleId === bid);
7849
7850
  if (hit) {
7850
7851
  installations.push({
7851
- tool: spec.tool,
7852
+ agent: spec.agent,
7852
7853
  install_method: "app_bundle",
7853
7854
  binary_path: hit.path,
7854
7855
  data_dir: null,
@@ -8076,7 +8077,7 @@ async function probeIdentities(os2) {
8076
8077
  function dedupeInstalls(list) {
8077
8078
  const seen = /* @__PURE__ */ new Map();
8078
8079
  for (const i of list) {
8079
- const k = `${i.tool}|${i.binary_path ?? ""}|${i.data_dir ?? ""}`;
8080
+ const k = `${i.agent}|${i.binary_path ?? ""}|${i.data_dir ?? ""}`;
8080
8081
  const prev = seen.get(k);
8081
8082
  if (!prev) {
8082
8083
  seen.set(k, i);
@@ -8103,7 +8104,7 @@ var init_discovery = __esm({
8103
8104
  H = (p) => p.startsWith("~") ? p.replace("~", homedir()) : p;
8104
8105
  SOURCES = [
8105
8106
  {
8106
- tool: "claude_code",
8107
+ agent: "claude_code",
8107
8108
  dataDirs: {
8108
8109
  macos: ["~/.claude"],
8109
8110
  linux: ["$XDG_CONFIG_HOME/claude", "~/.claude", "~/.config/claude"]
@@ -8115,7 +8116,7 @@ var init_discovery = __esm({
8115
8116
  ]
8116
8117
  },
8117
8118
  {
8118
- tool: "codex_cli",
8119
+ agent: "codex_cli",
8119
8120
  dataDirs: {
8120
8121
  macos: ["~/.codex"],
8121
8122
  linux: ["$XDG_CONFIG_HOME/codex", "~/.codex"]
@@ -8125,7 +8126,7 @@ var init_discovery = __esm({
8125
8126
  fileSignatures: [{ filenameGlob: "sessions/**/rollout-*.jsonl" }]
8126
8127
  },
8127
8128
  {
8128
- tool: "claude_desktop",
8129
+ agent: "claude_desktop",
8129
8130
  dataDirs: {
8130
8131
  macos: ["~/Library/Application Support/Claude"],
8131
8132
  linux: ["~/.config/Claude"]
@@ -8133,7 +8134,7 @@ var init_discovery = __esm({
8133
8134
  bundleIds: ["com.anthropic.claudeforbrowser", "com.anthropic.claudeelectron"]
8134
8135
  },
8135
8136
  {
8136
- tool: "cursor",
8137
+ agent: "cursor",
8137
8138
  dataDirs: {
8138
8139
  macos: ["~/Library/Application Support/Cursor"],
8139
8140
  linux: ["~/.config/Cursor"]
@@ -8141,7 +8142,7 @@ var init_discovery = __esm({
8141
8142
  bundleIds: ["co.anysphere.cursor", "com.todesktop.230313mzl4w4u92"]
8142
8143
  },
8143
8144
  {
8144
- tool: "windsurf",
8145
+ agent: "windsurf",
8145
8146
  dataDirs: {
8146
8147
  macos: ["~/Library/Application Support/Windsurf"],
8147
8148
  linux: ["~/.config/Windsurf"]
@@ -8149,7 +8150,7 @@ var init_discovery = __esm({
8149
8150
  bundleIds: ["com.codeium.windsurf"]
8150
8151
  },
8151
8152
  {
8152
- tool: "zed",
8153
+ agent: "zed",
8153
8154
  dataDirs: {
8154
8155
  macos: ["~/Library/Application Support/Zed", "~/.config/zed"],
8155
8156
  linux: ["~/.config/zed"]
@@ -8158,7 +8159,7 @@ var init_discovery = __esm({
8158
8159
  bundleIds: ["dev.zed.Zed"]
8159
8160
  },
8160
8161
  {
8161
- tool: "gemini_cli",
8162
+ agent: "gemini_cli",
8162
8163
  dataDirs: {
8163
8164
  macos: ["~/.gemini"],
8164
8165
  linux: ["~/.gemini"]
@@ -8166,18 +8167,18 @@ var init_discovery = __esm({
8166
8167
  binaries: ["gemini"]
8167
8168
  },
8168
8169
  {
8169
- tool: "aider",
8170
+ agent: "aider",
8170
8171
  dataDirs: { macos: ["~/.aider"], linux: ["~/.aider"] },
8171
8172
  binaries: ["aider"]
8172
8173
  },
8173
8174
  {
8174
- tool: "ollama",
8175
+ agent: "ollama",
8175
8176
  dataDirs: { macos: ["~/.ollama"], linux: ["~/.ollama"] },
8176
8177
  binaries: ["ollama"],
8177
8178
  bundleIds: ["com.electron.ollama"]
8178
8179
  },
8179
8180
  {
8180
- tool: "openclaw",
8181
+ agent: "openclaw",
8181
8182
  dataDirs: { macos: ["~/.openclaw", "~/.claw"], linux: ["~/.openclaw", "~/.claw"] },
8182
8183
  binaries: ["openclaw", "claw", "clawdbot", "moltbot"]
8183
8184
  }
@@ -45209,7 +45210,7 @@ async function buildSessionTitles(segments, entitle) {
45209
45210
  const project = first.tags.find((t) => t.root_key === "projects")?.name;
45210
45211
  const facts = [
45211
45212
  project ? `repo ${project}` : null,
45212
- `${sorted.length} part${sorted.length === 1 ? "" : "s"} on ${first.tool}`
45213
+ `${sorted.length} part${sorted.length === 1 ? "" : "s"} on ${first.agent}`
45213
45214
  ].filter(Boolean).join("; ");
45214
45215
  try {
45215
45216
  title = sanitiseTitle(await entitle({ abstracts: sampleAbstracts(abstracts), facts }));
@@ -45364,14 +45365,14 @@ async function summariseSlice(sessionId, slice, adapters2) {
45364
45365
  const promptFacts = [
45365
45366
  first.git?.remote_slug ? `repo ${first.git.remote_slug}` : null,
45366
45367
  first.git?.branch ? `branch ${first.git.branch}` : null,
45367
- `${slice.length} turns on ${first.tool}`,
45368
+ `${slice.length} turns on ${first.agent}`,
45368
45369
  first.files_touched?.length ? `files touched: ${first.files_touched.slice(0, 5).join(", ")}` : null,
45369
45370
  Object.keys(first.tool_calls ?? {}).length ? `tool calls: ${Object.keys(first.tool_calls).slice(0, 5).join(", ")}` : null
45370
45371
  ].filter(Boolean).join("; ");
45371
45372
  const excerpts = sampleAndRedactExcerpts(slice);
45372
45373
  if (excerpts.length === 0) {
45373
45374
  throw new Error(
45374
- `parser produced 0 content excerpts for session ${sessionId} (${slice.length} turns) \u2014 the summariser would only see metadata and produce "${slice.length} turns on ${first.tool}". Check the parser for ${first.tool} (likely extractExcerpt stripped everything as code or the session is pure tool_use).`
45375
+ `parser produced 0 content excerpts for session ${sessionId} (${slice.length} turns) \u2014 the summariser would only see metadata and produce "${slice.length} turns on ${first.agent}". Check the parser for ${first.agent} (likely extractExcerpt stripped everything as code or the session is pure tool_use).`
45375
45376
  );
45376
45377
  }
45377
45378
  const excerptBlock = excerpts.map((e, i) => ` [turn ${i + 1}] "${e.replace(/\s+/g, " ").trim()}"`).join("\n");
@@ -45414,7 +45415,7 @@ Write the SHORTEST keyword-dense paragraph (1-3 sentences, \u2264${ABSTRACT_OUTP
45414
45415
  }
45415
45416
  }
45416
45417
  const tags = [
45417
- { root_key: "tools", name: first.tool, confidence: 1 },
45418
+ { root_key: "agents", name: first.agent, confidence: 1 },
45418
45419
  { root_key: "providers", name: first.provider, confidence: 1 }
45419
45420
  ];
45420
45421
  if (first.model) tags.push({ root_key: "models", name: first.model, confidence: 1 });
@@ -45465,7 +45466,7 @@ Write the SHORTEST keyword-dense paragraph (1-3 sentences, \u2264${ABSTRACT_OUTP
45465
45466
  return {
45466
45467
  segment_id: id,
45467
45468
  session_id: sessionId,
45468
- tool: first.tool,
45469
+ agent: first.agent,
45469
45470
  started_at: first.ts,
45470
45471
  ended_at: last.ts,
45471
45472
  // Slice to the user-visible cap (ABSTRACT_OUTPUT_MAX_CHARS, default
@@ -45509,7 +45510,7 @@ function sampleAndRedactExcerpts(slice) {
45509
45510
  return out;
45510
45511
  }
45511
45512
  function turnSurface(e) {
45512
- const parts = [e.kind, e.tool];
45513
+ const parts = [e.kind, e.agent];
45513
45514
  if (e.model) parts.push(e.model);
45514
45515
  const toolCalls = Object.keys(e.tool_calls ?? {});
45515
45516
  if (toolCalls.length) parts.push(`tools:${toolCalls.join(",")}`);
@@ -45594,7 +45595,7 @@ var init_file_queue_store = __esm({
45594
45595
  try {
45595
45596
  const raw = await fs3.readFile(this.filePath, "utf8");
45596
45597
  const parsed = JSON.parse(raw);
45597
- if (parsed.version === 1 && parsed.items) {
45598
+ if (parsed.version === 2 && parsed.items) {
45598
45599
  const now = Date.now();
45599
45600
  for (const [k, v] of Object.entries(parsed.items)) {
45600
45601
  if (v.synced && now - v.last_event_ts_ms > SENT_TTL_MS) continue;
@@ -45606,7 +45607,7 @@ var init_file_queue_store = __esm({
45606
45607
  try {
45607
45608
  const bak = await fs3.readFile(`${this.filePath}.bak`, "utf8");
45608
45609
  const parsed = JSON.parse(bak);
45609
- if (parsed.version === 1 && parsed.items) {
45610
+ if (parsed.version === 2 && parsed.items) {
45610
45611
  for (const [k, v] of Object.entries(parsed.items)) {
45611
45612
  this.items.set(k, v);
45612
45613
  }
@@ -45625,7 +45626,7 @@ var init_file_queue_store = __esm({
45625
45626
  const run = async () => {
45626
45627
  await prior?.catch(() => void 0);
45627
45628
  const snap = {
45628
- version: 1,
45629
+ version: 2,
45629
45630
  items: Object.fromEntries(this.items.entries())
45630
45631
  };
45631
45632
  const tmp = `${this.filePath}.tmp`;
@@ -46442,7 +46443,7 @@ async function scanAll(cb = {}) {
46442
46443
  const batch = {
46443
46444
  batch_id: batchId(),
46444
46445
  device_id: deviceId,
46445
- agent_version: AGENT_VERSION,
46446
+ companion_version: AGENT_VERSION,
46446
46447
  events,
46447
46448
  segments,
46448
46449
  tool_calls: attachSegmentIdsByMap(toolCallBuffer, callSegmentByEvent),
@@ -46507,7 +46508,7 @@ var init_scan = __esm({
46507
46508
  init_api();
46508
46509
  init_config2();
46509
46510
  init_pipeline2();
46510
- AGENT_VERSION = true ? "agent-0.0.49" : "agent-dev";
46511
+ AGENT_VERSION = true ? "agent-0.0.50" : "agent-dev";
46511
46512
  BATCH_MAX_EVENTS = 2e3;
46512
46513
  BATCH_MAX_TOOL_CALLS = 2e4;
46513
46514
  BATCH_BUFFER_HARD_CAP = BATCH_MAX_EVENTS * 2;
@@ -46554,7 +46555,7 @@ function readDaemonLock(lockFile = LOCK_FILE) {
46554
46555
  return {
46555
46556
  pid: obj.pid,
46556
46557
  startedAt: obj.startedAt ?? "unknown",
46557
- agentVersion: obj.agentVersion ?? "unknown",
46558
+ companionVersion: obj.companionVersion ?? "unknown",
46558
46559
  apiUrl: obj.apiUrl ?? "unknown"
46559
46560
  };
46560
46561
  } catch {
@@ -46596,7 +46597,7 @@ function acquireDaemonLock(opts) {
46596
46597
  const meta = {
46597
46598
  pid: process.pid,
46598
46599
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
46599
- agentVersion: opts.agentVersion,
46600
+ companionVersion: opts.companionVersion,
46600
46601
  apiUrl: opts.apiUrl
46601
46602
  };
46602
46603
  writeLockAtomic(meta);
@@ -48494,7 +48495,7 @@ function snapshotBody() {
48494
48495
  queue_size: status.queueSize,
48495
48496
  stats: status.stats,
48496
48497
  last_event_at: status.lastEventAt,
48497
- agent_version: AGENT_VERSION2,
48498
+ companion_version: AGENT_VERSION2,
48498
48499
  machine_id: machineKey()
48499
48500
  };
48500
48501
  }
@@ -48645,7 +48646,7 @@ async function runDaemon(opts = {}) {
48645
48646
  throw new Error("not enrolled \u2014 run `npx modelstat@latest` first");
48646
48647
  }
48647
48648
  const lock = acquireDaemonLock({
48648
- agentVersion: AGENT_VERSION2,
48649
+ companionVersion: AGENT_VERSION2,
48649
48650
  apiUrl: state.apiUrl,
48650
48651
  force: opts.force === true,
48651
48652
  // If a racing daemon out-renamed us for the lock (see lock.ts
@@ -48663,7 +48664,7 @@ async function runDaemon(opts = {}) {
48663
48664
  console.log(
48664
48665
  `modelstat daemon is already running \u2014 PID ${lock.owner.pid}, started ${formatAge(
48665
48666
  lock.ageSec
48666
- )} ago, agent ${lock.owner.agentVersion}.`
48667
+ )} ago, agent ${lock.owner.companionVersion}.`
48667
48668
  );
48668
48669
  console.log(" \u2192 to stop it: kill " + lock.owner.pid);
48669
48670
  console.log(" \u2192 to force-replace it: modelstat start --force");
@@ -48757,7 +48758,7 @@ var init_daemon = __esm({
48757
48758
  init_machine_key();
48758
48759
  init_scan();
48759
48760
  init_single_flight();
48760
- AGENT_VERSION2 = true ? "agent-0.0.49" : "agent-dev";
48761
+ AGENT_VERSION2 = true ? "agent-0.0.50" : "agent-dev";
48761
48762
  HEARTBEAT_INTERVAL_MS = 1e4;
48762
48763
  SCAN_INTERVAL_MS = 5 * 60 * 1e3;
48763
48764
  DISCOVERY_INTERVAL_MS = 6e4;
@@ -49250,7 +49251,7 @@ function decideSupervision(input) {
49250
49251
  const fresh = input.statusFreshMs ?? STATUS_FRESH_MS;
49251
49252
  const grace = input.bootGraceMs ?? BOOT_GRACE_MS;
49252
49253
  if (!input.lock || !input.ownerAlive) return "spawn";
49253
- if (input.myAgentVersion && input.lock.agentVersion !== "unknown" && input.lock.agentVersion !== input.myAgentVersion) {
49254
+ if (input.myCompanionVersion && input.lock.companionVersion !== "unknown" && input.lock.companionVersion !== input.myCompanionVersion) {
49254
49255
  return "replace";
49255
49256
  }
49256
49257
  if (input.statusAgeMs !== null && input.statusAgeMs <= fresh) return "adopt";
@@ -49278,7 +49279,7 @@ function daemonHealth(opts = {}) {
49278
49279
  ownerAlive,
49279
49280
  lockAgeMs,
49280
49281
  statusAgeMs,
49281
- myAgentVersion: opts.myAgentVersion
49282
+ myCompanionVersion: opts.myCompanionVersion
49282
49283
  }),
49283
49284
  lock,
49284
49285
  ownerAlive,
@@ -49322,7 +49323,7 @@ function tryOpenBrowser(url) {
49322
49323
  return false;
49323
49324
  }
49324
49325
  }
49325
- var AGENT_VERSION3 = true ? "agent-0.0.49" : "agent-dev";
49326
+ var AGENT_VERSION3 = true ? "agent-0.0.50" : "agent-dev";
49326
49327
  function osFamily() {
49327
49328
  const p = platform5();
49328
49329
  if (p === "darwin") return "macos";
@@ -49349,8 +49350,8 @@ async function cmdSelfRegister() {
49349
49350
  os_family: osFamily(),
49350
49351
  os_version: release(),
49351
49352
  arch: osArch(),
49352
- agent: "modelstat-agent-dev",
49353
- agent_version: AGENT_VERSION3,
49353
+ companion: "modelstat-agent-dev",
49354
+ companion_version: AGENT_VERSION3,
49354
49355
  // Stable, install-method-independent machine key. The server
49355
49356
  // dedupes self-register on this so the same physical machine can
49356
49357
  // never become two device rows, even if the UUID somehow differs
@@ -49766,9 +49767,9 @@ async function cmdStats(args) {
49766
49767
  }
49767
49768
  console.log(`device: ${view.device.id}`);
49768
49769
  console.log(`host: ${view.device.hostname ?? "(unknown)"} (${view.device.os_family ?? "?"})`);
49769
- console.log(`agent: ${view.device.agent_version ?? "(unknown)"}`);
49770
+ console.log(`companion: ${view.device.companion_version ?? "(unknown)"}`);
49770
49771
  console.log(
49771
- `status: ${view.device.agent_status ?? "(unknown)"}${view.device.last_seen_at ? ` \xB7 last seen ${view.device.last_seen_at}` : ""}`
49772
+ `status: ${view.device.companion_status ?? "(unknown)"}${view.device.last_seen_at ? ` \xB7 last seen ${view.device.last_seen_at}` : ""}`
49772
49773
  );
49773
49774
  console.log(
49774
49775
  `claim: ${view.status}${view.status === "unclaimed" ? ` (at ${view.claim_url})` : ""}`
@@ -49896,7 +49897,7 @@ async function main() {
49896
49897
  }
49897
49898
  case "_daemon-health": {
49898
49899
  try {
49899
- console.log(JSON.stringify(daemonHealth({ myAgentVersion: AGENT_VERSION3 })));
49900
+ console.log(JSON.stringify(daemonHealth({ myCompanionVersion: AGENT_VERSION3 })));
49900
49901
  } catch (e) {
49901
49902
  console.log(JSON.stringify({ decision: "spawn", error: e.message }));
49902
49903
  }