modelstat 0.1.3 → 0.2.0

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
@@ -149,7 +149,7 @@ var init_billing = __esm({
149
149
  });
150
150
 
151
151
  // ../../packages/core/src/enums.ts
152
- var AGENTS, PROVIDERS, IDENTITY_OWNER_SCOPES, INSTALL_METHODS, OS_FAMILIES, EVENT_KINDS, TOOL_CALL_STATUSES, COMPANION_PHASES, CLASSIFICATION_CONFIDENCE;
152
+ var AGENTS, PROVIDERS, IDENTITY_OWNER_SCOPES, INSTALL_METHODS, OS_FAMILIES, EVENT_KINDS, TOOL_CALL_STATUSES, DAEMON_PHASES, CLASSIFICATION_CONFIDENCE;
153
153
  var init_enums = __esm({
154
154
  "../../packages/core/src/enums.ts"() {
155
155
  "use strict";
@@ -181,7 +181,7 @@ var init_enums = __esm({
181
181
  "raw_sdk_anthropic",
182
182
  "raw_sdk_openai",
183
183
  "raw_sdk_google",
184
- // Web chat UIs (Chrome-extension companion). Categorically distinct
184
+ // Web chat UIs (Chrome-extension daemon). Categorically distinct
185
185
  // from *_cli / *_desktop agents — same provider, different surface.
186
186
  "chatgpt_web",
187
187
  "claude_web",
@@ -241,7 +241,7 @@ var init_enums = __esm({
241
241
  "timeout",
242
242
  "unknown"
243
243
  ];
244
- COMPANION_PHASES = [
244
+ DAEMON_PHASES = [
245
245
  "starting",
246
246
  "discovering",
247
247
  "idle",
@@ -4540,7 +4540,7 @@ var init_redact_floor = __esm({
4540
4540
  pattern: /(?:sk|pk|rk)_test_[A-Za-z0-9]{24,}/g,
4541
4541
  replacement: "<REDACTED:stripe_test_key>"
4542
4542
  },
4543
- // Discord bot token (was agent-sdk-only — the canonical drift example).
4543
+ // Discord bot token (was daemon-sdk-only — the canonical drift example).
4544
4544
  {
4545
4545
  name: "discord_token",
4546
4546
  pattern: /[MN][A-Za-z\d]{23}\.[\w-]{6}\.[\w-]{27}/g,
@@ -5045,7 +5045,7 @@ var init_schemas = __esm({
5045
5045
  // available, the on-device Privacy Filter adapter.
5046
5046
  // 3. Stripping code blocks and file-path noise.
5047
5047
  // Optional — events without it fall back to metadata-only abstracts
5048
- // (the historical behaviour). The companion-core pipeline runs
5048
+ // (the historical behaviour). The daemon-core pipeline runs
5049
5049
  // redact() over it again as defence-in-depth before building the
5050
5050
  // summarize prompt; it never gets stored long-term server-side, only
5051
5051
  // used to construct the summarize input.
@@ -5076,7 +5076,7 @@ var init_schemas = __esm({
5076
5076
  root_key: external_exports.string().max(60),
5077
5077
  name: external_exports.string().max(120),
5078
5078
  confidence: external_exports.number().min(0).max(1).default(0.7),
5079
- /** Optional free-text reason the companion attached this tag — surfaces
5079
+ /** Optional free-text reason the daemon attached this tag — surfaces
5080
5080
  * in the audit log so the user can see "why was this tagged X?" */
5081
5081
  reason: external_exports.string().max(200).optional()
5082
5082
  });
@@ -5099,7 +5099,7 @@ var init_schemas = __esm({
5099
5099
  /** `source_event_id`s covered by this segment. Used for dedupe + replay. */
5100
5100
  source_event_ids: external_exports.array(external_exports.string()).max(2e3),
5101
5101
  /** Optional embedding of the abstract (BGE-small-en-v1.5, 384 dims).
5102
- * Present when the companion has an Embedder adapter configured. */
5102
+ * Present when the daemon has an Embedder adapter configured. */
5103
5103
  abstract_embedding: external_exports.array(external_exports.number()).length(384).optional()
5104
5104
  });
5105
5105
  ToolAction = external_exports.object({
@@ -5115,7 +5115,7 @@ var init_schemas = __esm({
5115
5115
  qualifiers: external_exports.array(external_exports.string().max(40)).max(8).default([]),
5116
5116
  /** Value-masked argument skeleton (every value → `§`). Carried in full up
5117
5117
  * to a malicious-size guard (mirrors backend `MAX_TOOL_ACTION_PARAM_SHAPE_CHARS`);
5118
- * the companion clamps rather than truncating semantically. (tier 1) */
5118
+ * the daemon clamps rather than truncating semantically. (tier 1) */
5119
5119
  param_shape: external_exports.string().max(16384).nullable().default(null),
5120
5120
  /** Relevant non-sensitive keywords (e.g. ["rollout","restart","prod"]),
5121
5121
  * OpenAI-redacted on-device. (tier 0) */
@@ -5147,7 +5147,7 @@ var init_schemas = __esm({
5147
5147
  session_id: external_exports.string().max(120),
5148
5148
  /** The RawEvent that contained the tool_use (dedupe/replay anchor). */
5149
5149
  source_event_id: external_exports.string(),
5150
- /** Segment containing source_event_id — filled by the companion at
5150
+ /** Segment containing source_event_id — filled by the daemon at
5151
5151
  * batch-build time when known, else null. */
5152
5152
  segment_id: external_exports.string().max(64).nullable().default(null),
5153
5153
  /** The agent that made the call (AGENTS enum). */
@@ -5185,7 +5185,7 @@ var init_schemas = __esm({
5185
5185
  batch_id: external_exports.string(),
5186
5186
  // ULID
5187
5187
  device_id: external_exports.string(),
5188
- companion_version: external_exports.string().max(40),
5188
+ daemon_version: external_exports.string().max(40),
5189
5189
  events: external_exports.array(RawEvent).max(1e4),
5190
5190
  segments: external_exports.array(Segment).max(2e3).default([]),
5191
5191
  /** Per-call tool invocations (additive — old agents omit it, old
@@ -5201,8 +5201,8 @@ var init_schemas = __esm({
5201
5201
  })
5202
5202
  ).optional(),
5203
5203
  /** Optional per-session titles — session_id → short redacted title
5204
- * (≤120 chars) produced by the companion's local titler from the
5205
- * session's segment abstracts. Companions recompute it from the full
5204
+ * (≤120 chars) produced by the daemon's local titler from the
5205
+ * session's segment abstracts. Daemons recompute it from the full
5206
5206
  * session view on every upload, so the latest batch always carries the
5207
5207
  * freshest title. Absent for runtimes without a titler (older agents,
5208
5208
  * no-op browser summariser). */
@@ -5211,20 +5211,20 @@ var init_schemas = __esm({
5211
5211
  * {@link SessionMetadata}: the repos, pull requests, commits, and issues the
5212
5212
  * session touched, detected on-device across git context, tool calls,
5213
5213
  * redacted content, and the local model (so it works for any provider).
5214
- * Additive — old companions omit it, old servers ignore it (the wire has no
5214
+ * Additive — old daemons omit it, old servers ignore it (the wire has no
5215
5215
  * `deny_unknown_fields`). The join layer between AI spend and shipped work. */
5216
5216
  session_metadata: external_exports.record(external_exports.string(), SessionMetadata).optional()
5217
5217
  });
5218
5218
  HeartbeatPayload = external_exports.object({
5219
5219
  device_id: external_exports.string(),
5220
- status: external_exports.enum(COMPANION_PHASES),
5220
+ status: external_exports.enum(DAEMON_PHASES),
5221
5221
  message: external_exports.string().max(240).nullable(),
5222
5222
  progress_done: external_exports.number().int().nonnegative().default(0),
5223
5223
  progress_total: external_exports.number().int().nonnegative().default(0),
5224
5224
  queue_size: external_exports.number().int().nonnegative().default(0),
5225
5225
  stats: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
5226
5226
  last_event_at: external_exports.string().datetime({ offset: true }).nullable(),
5227
- companion_version: external_exports.string().max(40)
5227
+ daemon_version: external_exports.string().max(40)
5228
5228
  });
5229
5229
  DeviceEnrollment = external_exports.object({
5230
5230
  machine_id: external_exports.string(),
@@ -5233,10 +5233,10 @@ var init_schemas = __esm({
5233
5233
  os_family: external_exports.enum(OS_FAMILIES),
5234
5234
  os_version: external_exports.string().max(60),
5235
5235
  arch: external_exports.enum(["x86_64", "arm64", "other"]),
5236
- companion_version: external_exports.string().max(40)
5236
+ daemon_version: external_exports.string().max(40)
5237
5237
  });
5238
5238
  DeviceSelfRegister = external_exports.object({
5239
- /** Agent-generated UUIDv7 — must pass shape + recent-timestamp checks. */
5239
+ /** Daemon-generated UUIDv7 — must pass shape + recent-timestamp checks. */
5240
5240
  device_uuid: external_exports.string(),
5241
5241
  /** Base64-encoded ed25519 public key, exactly 32 raw bytes. Optional
5242
5242
  * but recommended (used for sender-constrained tokens / DPoP later). */
@@ -5249,8 +5249,8 @@ var init_schemas = __esm({
5249
5249
  os_family: external_exports.enum(OS_FAMILIES).optional(),
5250
5250
  os_version: external_exports.string().max(60).optional(),
5251
5251
  arch: external_exports.enum(["x86_64", "arm64", "other"]).optional(),
5252
- companion: external_exports.string().max(80).optional(),
5253
- companion_version: external_exports.string().max(40).optional()
5252
+ daemon: external_exports.string().max(80).optional(),
5253
+ daemon_version: external_exports.string().max(40).optional()
5254
5254
  // Allow extra fields for forward-compat without breaking old agents.
5255
5255
  }).catchall(external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).default({})
5256
5256
  });
@@ -33608,14 +33608,14 @@ ${captureLines}` : capture.stack;
33608
33608
  }
33609
33609
  });
33610
33610
 
33611
- // ../../packages/companion-core/src/config/index.ts
33611
+ // ../../packages/daemon-core/src/config/index.ts
33612
33612
  function expBackoff(attempt) {
33613
33613
  const i = Math.min(Math.max(attempt, 0), BACKOFF_MS.length - 1);
33614
33614
  return BACKOFF_MS[i];
33615
33615
  }
33616
33616
  var INGEST_BATCH_MAX_EVENTS, BACKOFF_MS, BACKSTOP_SCAN_MS;
33617
33617
  var init_config = __esm({
33618
- "../../packages/companion-core/src/config/index.ts"() {
33618
+ "../../packages/daemon-core/src/config/index.ts"() {
33619
33619
  "use strict";
33620
33620
  INGEST_BATCH_MAX_EVENTS = 1e3;
33621
33621
  BACKOFF_MS = [1e3, 2500, 5e3, 1e4, 2e4, 6e4];
@@ -33623,7 +33623,7 @@ var init_config = __esm({
33623
33623
  }
33624
33624
  });
33625
33625
 
33626
- // ../../packages/companion-core/src/logger.ts
33626
+ // ../../packages/daemon-core/src/logger.ts
33627
33627
  function defaultLevel() {
33628
33628
  const env2 = globalThis.process?.env ?? {};
33629
33629
  const raw = (env2.LOG_LEVEL ?? "").toLowerCase();
@@ -33676,7 +33676,7 @@ function describeErrorWithCause(err, depth = 4) {
33676
33676
  }
33677
33677
  var LEVEL_RANK;
33678
33678
  var init_logger = __esm({
33679
- "../../packages/companion-core/src/logger.ts"() {
33679
+ "../../packages/daemon-core/src/logger.ts"() {
33680
33680
  "use strict";
33681
33681
  LEVEL_RANK = {
33682
33682
  debug: 10,
@@ -33687,7 +33687,7 @@ var init_logger = __esm({
33687
33687
  }
33688
33688
  });
33689
33689
 
33690
- // ../../packages/companion-core/src/http/index.ts
33690
+ // ../../packages/daemon-core/src/http/index.ts
33691
33691
  function classifyStatus(status2, attempt) {
33692
33692
  if (status2 >= 200 && status2 < 300) return { type: "commit" };
33693
33693
  if (status2 === 400 || status2 === 422) return { type: "drop", reason: `http_${status2}` };
@@ -33707,7 +33707,7 @@ function sleep(ms) {
33707
33707
  }
33708
33708
  var IngestClient;
33709
33709
  var init_http = __esm({
33710
- "../../packages/companion-core/src/http/index.ts"() {
33710
+ "../../packages/daemon-core/src/http/index.ts"() {
33711
33711
  "use strict";
33712
33712
  init_config();
33713
33713
  init_logger();
@@ -45249,7 +45249,7 @@ var init_config2 = __esm({
45249
45249
  DEFAULT_API_URL = "https://modelstat.ai";
45250
45250
  LEGACY_LOCALHOST_API = "http://localhost:3010";
45251
45251
  store = new Conf({
45252
- projectName: "modelstat-agent-dev",
45252
+ projectName: "modelstat-daemon",
45253
45253
  defaults: {
45254
45254
  // Intentionally empty — the apiUrl getter below computes this
45255
45255
  // from env + stored value + DEFAULT_API_URL. Keeping the stored
@@ -45281,7 +45281,7 @@ var init_config2 = __esm({
45281
45281
  * or paired pre-0.0.8) → production default. The legacy localhost
45282
45282
  * value is ignored so upgrades from 0.0.7 self-heal. */
45283
45283
  get apiUrl() {
45284
- if (process.env.AGENT_API_URL) return process.env.AGENT_API_URL;
45284
+ if (process.env.DAEMON_API_URL) return process.env.DAEMON_API_URL;
45285
45285
  const stored = store.get("apiUrl");
45286
45286
  if (stored && stored !== LEGACY_LOCALHOST_API) return stored;
45287
45287
  return DEFAULT_API_URL;
@@ -45289,6 +45289,16 @@ var init_config2 = __esm({
45289
45289
  setApiUrl(v) {
45290
45290
  store.set("apiUrl", v);
45291
45291
  },
45292
+ /** True when `apiUrl` resolves to the baked-in production default with no
45293
+ * explicit override (no `DAEMON_API_URL`, no operator-set stored URL). Used
45294
+ * to refuse silent prod self-register from CI/non-interactive environments
45295
+ * so ephemeral runners don't pile up unclaimed device rows. */
45296
+ get isProdDefaultApi() {
45297
+ if (process.env.DAEMON_API_URL) return false;
45298
+ const stored = store.get("apiUrl");
45299
+ if (stored && stored !== LEGACY_LOCALHOST_API) return false;
45300
+ return true;
45301
+ },
45292
45302
  // ── Identity: backed by ~/.modelstat/identity.json ─────────────
45293
45303
  /** Seed a fresh identity after a successful self-register. Writes
45294
45304
  * the file atomically; use `state.backupAndReset()` first if
@@ -45427,7 +45437,7 @@ async function rotateDeviceSecret(currentSecret) {
45427
45437
  }
45428
45438
  async function reportDiscovery(report) {
45429
45439
  const bearer = state.bearer;
45430
- if (!bearer) throw new Error("agent not enrolled \u2014 run `register` first");
45440
+ if (!bearer) throw new Error("daemon not enrolled \u2014 run `register` first");
45431
45441
  const res = await (0, import_undici.request)(`${state.apiUrl}/v1/devices/discovery`, {
45432
45442
  method: "POST",
45433
45443
  headers: { "content-type": "application/json", authorization: `Bearer ${bearer}` },
@@ -45472,7 +45482,7 @@ async function fetchDeviceViewLedgerByClaim(claimCode) {
45472
45482
  }
45473
45483
  function ingestClient() {
45474
45484
  if (_ingest) return _ingest;
45475
- const logger = createLogger("agent.ingest");
45485
+ const logger = createLogger("daemon.ingest");
45476
45486
  _ingest = new IngestClient({
45477
45487
  apiUrl: state.apiUrl,
45478
45488
  auth: {
@@ -45632,24 +45642,24 @@ var init_machine_key = __esm({
45632
45642
  }
45633
45643
  });
45634
45644
 
45635
- // ../../packages/companion-core/src/contracts/index.ts
45645
+ // ../../packages/daemon-core/src/contracts/index.ts
45636
45646
  var init_contracts = __esm({
45637
- "../../packages/companion-core/src/contracts/index.ts"() {
45647
+ "../../packages/daemon-core/src/contracts/index.ts"() {
45638
45648
  "use strict";
45639
45649
  init_schemas();
45640
45650
  init_enums();
45641
45651
  }
45642
45652
  });
45643
45653
 
45644
- // ../../packages/companion-core/src/ids.ts
45654
+ // ../../packages/daemon-core/src/ids.ts
45645
45655
  var init_ids2 = __esm({
45646
- "../../packages/companion-core/src/ids.ts"() {
45656
+ "../../packages/daemon-core/src/ids.ts"() {
45647
45657
  "use strict";
45648
45658
  init_ids();
45649
45659
  }
45650
45660
  });
45651
45661
 
45652
- // ../../packages/companion-core/src/queue/index.ts
45662
+ // ../../packages/daemon-core/src/queue/index.ts
45653
45663
  function attachSegmentIdsByMap(calls, segmentByEvent) {
45654
45664
  return calls.map((c) => ({
45655
45665
  ...c,
@@ -45657,14 +45667,14 @@ function attachSegmentIdsByMap(calls, segmentByEvent) {
45657
45667
  }));
45658
45668
  }
45659
45669
  var init_queue = __esm({
45660
- "../../packages/companion-core/src/queue/index.ts"() {
45670
+ "../../packages/daemon-core/src/queue/index.ts"() {
45661
45671
  "use strict";
45662
45672
  init_config();
45663
45673
  init_ids2();
45664
45674
  }
45665
45675
  });
45666
45676
 
45667
- // ../../packages/companion-core/src/pipeline/cognition.ts
45677
+ // ../../packages/daemon-core/src/pipeline/cognition.ts
45668
45678
  function buildCognitionUserPrompt(abstract) {
45669
45679
  return `Summary: "${abstract.replace(/\s+/g, " ").trim().slice(0, 480)}"
45670
45680
 
@@ -45736,7 +45746,7 @@ function extractFirstJsonObject(s) {
45736
45746
  }
45737
45747
  var COGNITION_SYSTEM_PROMPT, MAX_COGNITION_TAGS_PER_FIELD, MAX_COGNITION_TAG_CHARS, COGNITION_MAX_TOKENS, COGNITION_TEMPERATURE;
45738
45748
  var init_cognition = __esm({
45739
- "../../packages/companion-core/src/pipeline/cognition.ts"() {
45749
+ "../../packages/daemon-core/src/pipeline/cognition.ts"() {
45740
45750
  "use strict";
45741
45751
  COGNITION_SYSTEM_PROMPT = 'You read a one-sentence summary of an AI-coding work session and identify the user\'s emotional state and meta-cognitive state. Output JSON only \u2014 first character of reply is `{`. Schema: {"emotions":[],"meta":[]}. emotions: \u2264 3 short lowercase MOOD tags \u2014 how the user FEELS \u2014 such as frustrated, curious, excited, calm, confused, anxious, satisfied, proud, bored, energised, overwhelmed, confident. meta: \u2264 3 short lowercase MENTAL-MODE tags \u2014 HOW the user is THINKING, never what they are doing. Valid examples: focused, scattered, in-flow, deliberate, hurried, stuck, open, exploratory, methodical, distracted. DO NOT emit ACTIVITY verbs (debugging, refactoring, designing, reviewing, deploying, planning, documenting, implementing) under meta \u2014 those describe the WORK, not the MIND. If the only candidate tag would be an activity verb, return [] for meta instead. Each tag \u2264 24 chars, single word or hyphenated, no punctuation. Only emit a tag if the summary gives clear evidence \u2014 return [] for either field when unsure. Do not invent emotions or mental modes the user did not display. No prose, no markdown.';
45742
45752
  MAX_COGNITION_TAGS_PER_FIELD = 3;
@@ -45746,10 +45756,10 @@ var init_cognition = __esm({
45746
45756
  }
45747
45757
  });
45748
45758
 
45749
- // ../../packages/companion-core/src/pipeline/prompts.ts
45759
+ // ../../packages/daemon-core/src/pipeline/prompts.ts
45750
45760
  var OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL, SUMMARISER_SYSTEM_PROMPT, SUMMARISER_MAX_TOKENS, SUMMARISER_TEMPERATURE, QWEN_CHARS_PER_TOKEN, ABSTRACT_OUTPUT_MAX_CHARS;
45751
45761
  var init_prompts = __esm({
45752
- "../../packages/companion-core/src/pipeline/prompts.ts"() {
45762
+ "../../packages/daemon-core/src/pipeline/prompts.ts"() {
45753
45763
  "use strict";
45754
45764
  OLLAMA_CHAT_MODEL = "qwen3:4b";
45755
45765
  OLLAMA_EMBED_MODEL = "bge-small-en-v1.5";
@@ -45761,7 +45771,7 @@ var init_prompts = __esm({
45761
45771
  }
45762
45772
  });
45763
45773
 
45764
- // ../../packages/companion-core/src/pipeline/script-summary.ts
45774
+ // ../../packages/daemon-core/src/pipeline/script-summary.ts
45765
45775
  function buildScriptSummaryUserPrompt(input) {
45766
45776
  const body = input.content.slice(0, SCRIPT_SUMMARY_INPUT_MAX_CHARS);
45767
45777
  return [
@@ -45776,7 +45786,7 @@ function buildScriptSummaryUserPrompt(input) {
45776
45786
  }
45777
45787
  var SCRIPT_SUMMARY_OUTPUT_MAX_CHARS, SCRIPT_SUMMARY_TEMPERATURE, SCRIPT_SUMMARY_MAX_TOKENS, SCRIPT_SUMMARY_INPUT_MAX_CHARS, SCRIPT_SUMMARY_SYSTEM_PROMPT;
45778
45788
  var init_script_summary = __esm({
45779
- "../../packages/companion-core/src/pipeline/script-summary.ts"() {
45789
+ "../../packages/daemon-core/src/pipeline/script-summary.ts"() {
45780
45790
  "use strict";
45781
45791
  SCRIPT_SUMMARY_OUTPUT_MAX_CHARS = 200;
45782
45792
  SCRIPT_SUMMARY_TEMPERATURE = 0.2;
@@ -45793,7 +45803,7 @@ Rules:
45793
45803
  }
45794
45804
  });
45795
45805
 
45796
- // ../../packages/companion-core/src/pipeline/title.ts
45806
+ // ../../packages/daemon-core/src/pipeline/title.ts
45797
45807
  function buildTitleUserPrompt(input) {
45798
45808
  const lines = input.abstracts.map(
45799
45809
  (a, i) => ` [part ${i + 1}] ${a.replace(/\s+/g, " ").trim().slice(0, TITLER_ABSTRACT_SLICE_CHARS)}`
@@ -45864,7 +45874,7 @@ async function buildSessionTitles(segments, entitle) {
45864
45874
  }
45865
45875
  var TITLER_SYSTEM_PROMPT, TITLE_MAX_CHARS, TITLER_MAX_TOKENS, TITLER_TEMPERATURE, TITLER_MAX_ABSTRACTS, TITLER_ABSTRACT_SLICE_CHARS;
45866
45876
  var init_title = __esm({
45867
- "../../packages/companion-core/src/pipeline/title.ts"() {
45877
+ "../../packages/daemon-core/src/pipeline/title.ts"() {
45868
45878
  "use strict";
45869
45879
  init_redact();
45870
45880
  TITLER_SYSTEM_PROMPT = "You write a short TITLE for an AI coding session, given one-sentence summaries of its parts in chronological order. The title names what the session was about at a high level, in 3-8 words. If the session clearly spans more than one theme, name the top themes (at most 3) separated by ' \xB7 '. Use concrete domain keywords (features, components, subsystems). No narration, no filler words like 'session' or 'work on', no quotes, no trailing period, no PII, no code literals, no file paths. Reply with only the title.";
@@ -45876,7 +45886,7 @@ var init_title = __esm({
45876
45886
  }
45877
45887
  });
45878
45888
 
45879
- // ../../packages/companion-core/src/pipeline/session-metadata.ts
45889
+ // ../../packages/daemon-core/src/pipeline/session-metadata.ts
45880
45890
  function buildLinkExtractUserPrompt(abstracts) {
45881
45891
  const lines = abstracts.map((a, i) => ` [part ${i + 1}] ${a.replace(/\s+/g, " ").trim().slice(0, 240)}`).join("\n");
45882
45892
  return `Summaries of the session's parts:
@@ -45975,7 +45985,7 @@ async function buildSessionMetadata(segments, events, opts = {}) {
45975
45985
  }
45976
45986
  var LINK_EXTRACT_SYSTEM_PROMPT, LINK_EXTRACT_MAX_TOKENS, LINK_EXTRACT_TEMPERATURE, LINK_EXTRACT_MAX_ABSTRACTS;
45977
45987
  var init_session_metadata2 = __esm({
45978
- "../../packages/companion-core/src/pipeline/session-metadata.ts"() {
45988
+ "../../packages/daemon-core/src/pipeline/session-metadata.ts"() {
45979
45989
  "use strict";
45980
45990
  init_session_metadata();
45981
45991
  init_title();
@@ -45986,7 +45996,7 @@ var init_session_metadata2 = __esm({
45986
45996
  }
45987
45997
  });
45988
45998
 
45989
- // ../../packages/companion-core/src/pipeline/index.ts
45999
+ // ../../packages/daemon-core/src/pipeline/index.ts
45990
46000
  async function buildSegmentsForSession(events, adapters2, onProgress) {
45991
46001
  if (events.length === 0) return [];
45992
46002
  const bySession = /* @__PURE__ */ new Map();
@@ -46288,7 +46298,7 @@ function inferEnvironment(branch) {
46288
46298
  }
46289
46299
  var SEGMENT_TIME_GAP_MS, SEGMENT_TOPIC_THRESHOLD, SEGMENT_MAX_TURNS, SEGMENT_MAX_DURATION_MS, SEGMENT_MAX_CONTENT_CHARS, ABSTRACT_MAX_CHARS;
46290
46300
  var init_pipeline = __esm({
46291
- "../../packages/companion-core/src/pipeline/index.ts"() {
46301
+ "../../packages/daemon-core/src/pipeline/index.ts"() {
46292
46302
  "use strict";
46293
46303
  init_ids();
46294
46304
  init_redact();
@@ -46309,9 +46319,9 @@ var init_pipeline = __esm({
46309
46319
  }
46310
46320
  });
46311
46321
 
46312
- // ../../packages/companion-core/src/index.ts
46322
+ // ../../packages/daemon-core/src/index.ts
46313
46323
  var init_src3 = __esm({
46314
- "../../packages/companion-core/src/index.ts"() {
46324
+ "../../packages/daemon-core/src/index.ts"() {
46315
46325
  "use strict";
46316
46326
  init_contracts();
46317
46327
  init_ids2();
@@ -46323,12 +46333,12 @@ var init_src3 = __esm({
46323
46333
  }
46324
46334
  });
46325
46335
 
46326
- // ../../packages/companion-core/src/node/file-queue-store.ts
46336
+ // ../../packages/daemon-core/src/node/file-queue-store.ts
46327
46337
  import { promises as fs3 } from "fs";
46328
46338
  import { dirname as dirname4 } from "path";
46329
46339
  var SENT_TTL_MS, FileQueueStore;
46330
46340
  var init_file_queue_store = __esm({
46331
- "../../packages/companion-core/src/node/file-queue-store.ts"() {
46341
+ "../../packages/daemon-core/src/node/file-queue-store.ts"() {
46332
46342
  "use strict";
46333
46343
  SENT_TTL_MS = 24 * 60 * 60 * 1e3;
46334
46344
  FileQueueStore = class {
@@ -46446,7 +46456,7 @@ var init_file_queue_store = __esm({
46446
46456
  }
46447
46457
  });
46448
46458
 
46449
- // ../../packages/companion-core/src/node/llama.ts
46459
+ // ../../packages/daemon-core/src/node/llama.ts
46450
46460
  import { existsSync as existsSync7 } from "fs";
46451
46461
  import { mkdir } from "fs/promises";
46452
46462
  import { homedir as homedir5 } from "os";
@@ -46742,7 +46752,7 @@ function llamaExtractLinks(cfg = defaultLlamaConfig()) {
46742
46752
  }
46743
46753
  var DEFAULT_LLAMA_MODEL_URL, LLAMA_MAX_TOKENS, loaded, loadPromise, inflight, llamaInstance;
46744
46754
  var init_llama = __esm({
46745
- "../../packages/companion-core/src/node/llama.ts"() {
46755
+ "../../packages/daemon-core/src/node/llama.ts"() {
46746
46756
  "use strict";
46747
46757
  init_cognition();
46748
46758
  init_prompts();
@@ -46758,7 +46768,7 @@ var init_llama = __esm({
46758
46768
  }
46759
46769
  });
46760
46770
 
46761
- // ../../packages/companion-core/src/node/ollama.ts
46771
+ // ../../packages/daemon-core/src/node/ollama.ts
46762
46772
  function defaultOllamaConfig() {
46763
46773
  const base = globalThis.process?.env ?? {};
46764
46774
  return {
@@ -46861,14 +46871,14 @@ function ollamaCognize(cfg = defaultOllamaConfig()) {
46861
46871
  };
46862
46872
  }
46863
46873
  var init_ollama = __esm({
46864
- "../../packages/companion-core/src/node/ollama.ts"() {
46874
+ "../../packages/daemon-core/src/node/ollama.ts"() {
46865
46875
  "use strict";
46866
46876
  init_prompts();
46867
46877
  init_cognition();
46868
46878
  }
46869
46879
  });
46870
46880
 
46871
- // ../../packages/companion-core/src/optional-module.ts
46881
+ // ../../packages/daemon-core/src/optional-module.ts
46872
46882
  function isMissingOptionalModuleError(err) {
46873
46883
  const code = err?.code;
46874
46884
  if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
@@ -46877,13 +46887,13 @@ function isMissingOptionalModuleError(err) {
46877
46887
  }
46878
46888
  var OPTIONAL_MODULE_MAX_LOAD_ATTEMPTS;
46879
46889
  var init_optional_module = __esm({
46880
- "../../packages/companion-core/src/optional-module.ts"() {
46890
+ "../../packages/daemon-core/src/optional-module.ts"() {
46881
46891
  "use strict";
46882
46892
  OPTIONAL_MODULE_MAX_LOAD_ATTEMPTS = 3;
46883
46893
  }
46884
46894
  });
46885
46895
 
46886
- // ../../packages/companion-core/src/node/transformersjs-embed.ts
46896
+ // ../../packages/daemon-core/src/node/transformersjs-embed.ts
46887
46897
  async function loadPipeline(model) {
46888
46898
  if (cached) return cached;
46889
46899
  if (loadFailedPermanently) return null;
@@ -46937,7 +46947,7 @@ function createTransformersJsEmbedder(model = DEFAULT_MODEL) {
46937
46947
  }
46938
46948
  var cached, loadPromise2, loadFailedPermanently, loadAttempts, warnedUnavailable, warnedInferenceError, DEFAULT_MODEL, importModule;
46939
46949
  var init_transformersjs_embed = __esm({
46940
- "../../packages/companion-core/src/node/transformersjs-embed.ts"() {
46950
+ "../../packages/daemon-core/src/node/transformersjs-embed.ts"() {
46941
46951
  "use strict";
46942
46952
  init_optional_module();
46943
46953
  cached = null;
@@ -46954,7 +46964,7 @@ var init_transformersjs_embed = __esm({
46954
46964
  }
46955
46965
  });
46956
46966
 
46957
- // ../../packages/companion-core/src/node/index.ts
46967
+ // ../../packages/daemon-core/src/node/index.ts
46958
46968
  var node_exports = {};
46959
46969
  __export(node_exports, {
46960
46970
  DEFAULT_LLAMA_MODEL_URL: () => DEFAULT_LLAMA_MODEL_URL,
@@ -46976,7 +46986,7 @@ __export(node_exports, {
46976
46986
  ollamaTokenize: () => ollamaTokenize
46977
46987
  });
46978
46988
  var init_node2 = __esm({
46979
- "../../packages/companion-core/src/node/index.ts"() {
46989
+ "../../packages/daemon-core/src/node/index.ts"() {
46980
46990
  "use strict";
46981
46991
  init_file_queue_store();
46982
46992
  init_llama();
@@ -46985,7 +46995,7 @@ var init_node2 = __esm({
46985
46995
  }
46986
46996
  });
46987
46997
 
46988
- // ../../packages/companion-core/src/redact/privacy-filter.ts
46998
+ // ../../packages/daemon-core/src/redact/privacy-filter.ts
46989
46999
  async function createPrivacyFilterRedactor(opts = {}) {
46990
47000
  const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
46991
47001
  const device = opts.device ?? (isBrowser ? "webgpu" : "cpu");
@@ -47091,7 +47101,7 @@ async function createPrivacyFilterRedactor(opts = {}) {
47091
47101
  };
47092
47102
  }
47093
47103
  var init_privacy_filter = __esm({
47094
- "../../packages/companion-core/src/redact/privacy-filter.ts"() {
47104
+ "../../packages/daemon-core/src/redact/privacy-filter.ts"() {
47095
47105
  "use strict";
47096
47106
  init_optional_module();
47097
47107
  }
@@ -47217,7 +47227,7 @@ async function getAdapters() {
47217
47227
  await import("node-llama-cpp");
47218
47228
  } catch (err) {
47219
47229
  throw new Error(
47220
- `modelstat agent can't start: the bundled summariser (node-llama-cpp) failed to load. Re-run \`modelstat connect\` (or \`npm i -g modelstat\`) so the native runtime is re-staged beside the bundle. Underlying error: ${err.message}`
47230
+ `modelstat daemon can't start: the bundled summariser (node-llama-cpp) failed to load. Re-run \`modelstat connect\` (or \`npm i -g modelstat\`) so the native runtime is re-staged beside the bundle. Underlying error: ${err.message}`
47221
47231
  );
47222
47232
  }
47223
47233
  console.log("[modelstat] using bundled local summariser (Qwen3.5-4B, runs on this machine)");
@@ -47288,7 +47298,7 @@ function withNonNullTokens(e) {
47288
47298
  }
47289
47299
  async function scanAll(cb = {}) {
47290
47300
  const deviceId = state.deviceId;
47291
- if (!deviceId) throw new Error("agent not enrolled \u2014 run `register` first");
47301
+ if (!deviceId) throw new Error("daemon not enrolled \u2014 run `register` first");
47292
47302
  const jobs = [];
47293
47303
  try {
47294
47304
  const base = join6(homedir6(), ".claude/projects");
@@ -47393,7 +47403,7 @@ async function scanAll(cb = {}) {
47393
47403
  const batch = {
47394
47404
  batch_id: batchId(),
47395
47405
  device_id: deviceId,
47396
- companion_version: AGENT_VERSION,
47406
+ daemon_version: DAEMON_VERSION,
47397
47407
  events,
47398
47408
  segments,
47399
47409
  tool_calls: attachSegmentIdsByMap(toolCallBuffer, callSegmentByEvent),
@@ -47468,7 +47478,7 @@ async function scanAll(cb = {}) {
47468
47478
  morePending
47469
47479
  };
47470
47480
  }
47471
- var AGENT_VERSION, BATCH_MAX_EVENTS, BATCH_MAX_TOOL_CALLS, BATCH_BUFFER_HARD_CAP, ZERO_TOKENS;
47481
+ var DAEMON_VERSION, BATCH_MAX_EVENTS, BATCH_MAX_TOOL_CALLS, BATCH_BUFFER_HARD_CAP, ZERO_TOKENS;
47472
47482
  var init_scan = __esm({
47473
47483
  "src/scan.ts"() {
47474
47484
  "use strict";
@@ -47479,7 +47489,7 @@ var init_scan = __esm({
47479
47489
  init_api();
47480
47490
  init_config2();
47481
47491
  init_pipeline2();
47482
- AGENT_VERSION = true ? "agent-0.1.3" : "agent-dev";
47492
+ DAEMON_VERSION = true ? "daemon-0.2.0" : "daemon-dev";
47483
47493
  BATCH_MAX_EVENTS = INGEST_BATCH_MAX_EVENTS;
47484
47494
  BATCH_MAX_TOOL_CALLS = 2e4;
47485
47495
  BATCH_BUFFER_HARD_CAP = BATCH_MAX_EVENTS * 2;
@@ -47526,7 +47536,7 @@ function readDaemonLock(lockFile = LOCK_FILE) {
47526
47536
  return {
47527
47537
  pid: obj.pid,
47528
47538
  startedAt: obj.startedAt ?? "unknown",
47529
- companionVersion: obj.companionVersion ?? "unknown",
47539
+ daemonVersion: obj.daemonVersion ?? "unknown",
47530
47540
  apiUrl: obj.apiUrl ?? "unknown"
47531
47541
  };
47532
47542
  } catch {
@@ -47568,7 +47578,7 @@ function acquireDaemonLock(opts) {
47568
47578
  const meta = {
47569
47579
  pid: process.pid,
47570
47580
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
47571
- companionVersion: opts.companionVersion,
47581
+ daemonVersion: opts.daemonVersion,
47572
47582
  apiUrl: opts.apiUrl
47573
47583
  };
47574
47584
  writeLockAtomic(meta);
@@ -47886,7 +47896,7 @@ var init_node3 = __esm({
47886
47896
  }
47887
47897
  });
47888
47898
 
47889
- // ../../packages/companion-core/src/policies/index.ts
47899
+ // ../../packages/daemon-core/src/policies/index.ts
47890
47900
  var policies_exports = {};
47891
47901
  __export(policies_exports, {
47892
47902
  createPolicyRefresher: () => createPolicyRefresher
@@ -47930,7 +47940,7 @@ function createPolicyRefresher(opts) {
47930
47940
  }
47931
47941
  var DEFAULT_REFRESH_MS, policiesKind;
47932
47942
  var init_policies2 = __esm({
47933
- "../../packages/companion-core/src/policies/index.ts"() {
47943
+ "../../packages/daemon-core/src/policies/index.ts"() {
47934
47944
  "use strict";
47935
47945
  init_src();
47936
47946
  init_src4();
@@ -49710,7 +49720,7 @@ function snapshotBody() {
49710
49720
  queue_size: status.queueSize,
49711
49721
  stats: status.stats,
49712
49722
  last_event_at: status.lastEventAt,
49713
- companion_version: AGENT_VERSION2,
49723
+ daemon_version: DAEMON_VERSION2,
49714
49724
  machine_id: machineKey()
49715
49725
  };
49716
49726
  }
@@ -49735,7 +49745,7 @@ async function sendHeartbeat() {
49735
49745
  if (!bearer || !deviceId) return;
49736
49746
  const body = { ...snapshotBody(), device_id: deviceId };
49737
49747
  try {
49738
- const res = await (0, import_undici2.request)(`${state.apiUrl}/v1/agent/heartbeat`, {
49748
+ const res = await (0, import_undici2.request)(`${state.apiUrl}/v1/daemon/heartbeat`, {
49739
49749
  method: "POST",
49740
49750
  headers: { "content-type": "application/json", authorization: `Bearer ${bearer}` },
49741
49751
  body: JSON.stringify(body)
@@ -49866,7 +49876,7 @@ async function runDaemon(opts = {}) {
49866
49876
  throw new Error("not enrolled \u2014 run `npx modelstat@latest` first");
49867
49877
  }
49868
49878
  const lock = acquireDaemonLock({
49869
- companionVersion: AGENT_VERSION2,
49879
+ daemonVersion: DAEMON_VERSION2,
49870
49880
  apiUrl: state.apiUrl,
49871
49881
  force: opts.force === true,
49872
49882
  // If a racing daemon out-renamed us for the lock (see lock.ts
@@ -49884,7 +49894,7 @@ async function runDaemon(opts = {}) {
49884
49894
  console.log(
49885
49895
  `modelstat daemon is already running \u2014 PID ${lock.owner.pid}, started ${formatAge(
49886
49896
  lock.ageSec
49887
- )} ago, agent ${lock.owner.companionVersion}.`
49897
+ )} ago, daemon ${lock.owner.daemonVersion}.`
49888
49898
  );
49889
49899
  console.log(" \u2192 to stop it: kill " + lock.owner.pid);
49890
49900
  console.log(" \u2192 to force-replace it: modelstat start --force");
@@ -49976,7 +49986,7 @@ async function runDaemon(opts = {}) {
49976
49986
  await new Promise(() => {
49977
49987
  });
49978
49988
  }
49979
- var import_undici2, AGENT_VERSION2, HEARTBEAT_INTERVAL_MS, SCAN_INTERVAL_MS, DISCOVERY_INTERVAL_MS, status, LOCAL_FLUSH_THROTTLE_MS, localFlushTimer, localFlushPending, LOG_MAX_BYTES, LOG_TAIL_KEEP_BYTES, lastStatusPath, scanRunner;
49989
+ var import_undici2, DAEMON_VERSION2, HEARTBEAT_INTERVAL_MS, SCAN_INTERVAL_MS, DISCOVERY_INTERVAL_MS, status, LOCAL_FLUSH_THROTTLE_MS, localFlushTimer, localFlushPending, LOG_MAX_BYTES, LOG_TAIL_KEEP_BYTES, lastStatusPath, scanRunner;
49980
49990
  var init_daemon = __esm({
49981
49991
  "src/daemon.ts"() {
49982
49992
  "use strict";
@@ -49989,7 +49999,7 @@ var init_daemon = __esm({
49989
49999
  init_machine_key();
49990
50000
  init_scan();
49991
50001
  init_single_flight();
49992
- AGENT_VERSION2 = true ? "agent-0.1.3" : "agent-dev";
50002
+ DAEMON_VERSION2 = true ? "daemon-0.2.0" : "daemon-dev";
49993
50003
  HEARTBEAT_INTERVAL_MS = 1e4;
49994
50004
  SCAN_INTERVAL_MS = 5 * 60 * 1e3;
49995
50005
  DISCOVERY_INTERVAL_MS = 6e4;
@@ -50134,7 +50144,7 @@ import { createRequire } from "module";
50134
50144
  import { homedir as homedir7, platform as platform3, userInfo } from "os";
50135
50145
  import { dirname as dirname6, join as join7 } from "path";
50136
50146
  import { fileURLToPath as fileURLToPath2 } from "url";
50137
- var SERVICE_LABEL = "ai.modelstat.agent";
50147
+ var SERVICE_LABEL = "ai.modelstat.daemon";
50138
50148
  var SYSTEMD_UNIT = "modelstat";
50139
50149
  function home() {
50140
50150
  return homedir7();
@@ -50341,7 +50351,7 @@ function writeSystemdUnit(cliPath) {
50341
50351
  const unitPath = systemdUnitPath();
50342
50352
  mkdirSync3(dirname6(unitPath), { recursive: true });
50343
50353
  const unit = `[Unit]
50344
- Description=modelstat agent
50354
+ Description=modelstat daemon
50345
50355
  Documentation=https://modelstat.ai
50346
50356
  After=network-online.target
50347
50357
  Wants=network-online.target
@@ -50408,7 +50418,7 @@ function installService() {
50408
50418
  return { path: systemdUnitPath(), logs: logDir() };
50409
50419
  }
50410
50420
  throw new Error(
50411
- `Service installation isn't supported on ${p}. Run 'modelstat start' manually to keep the agent running.`
50421
+ `Service installation isn't supported on ${p}. Run 'modelstat start' manually to keep the daemon running.`
50412
50422
  );
50413
50423
  }
50414
50424
  function uninstallService() {
@@ -50445,7 +50455,7 @@ async function bundledTrayAppPath(progress) {
50445
50455
  const candidates = [
50446
50456
  // Pre-built .app — CI with codesigning drops one here.
50447
50457
  join7(here2, "..", "vendor", "ModelstatTray.app"),
50448
- // Local dev layout: apps/agent-dev/src/service.ts → ../../tray-mac/build/ModelstatTray.app
50458
+ // Local dev layout: apps/daemon/src/service.ts → ../../tray-mac/build/ModelstatTray.app
50449
50459
  join7(here2, "..", "..", "tray-mac", "build", "ModelstatTray.app")
50450
50460
  ];
50451
50461
  for (const c of candidates) {
@@ -50519,7 +50529,7 @@ function decideSupervision(input) {
50519
50529
  const fresh = input.statusFreshMs ?? STATUS_FRESH_MS;
50520
50530
  const grace = input.bootGraceMs ?? BOOT_GRACE_MS;
50521
50531
  if (!input.lock || !input.ownerAlive) return "spawn";
50522
- if (input.myCompanionVersion && input.lock.companionVersion !== "unknown" && input.lock.companionVersion !== input.myCompanionVersion) {
50532
+ if (input.myDaemonVersion && input.lock.daemonVersion !== "unknown" && input.lock.daemonVersion !== input.myDaemonVersion) {
50523
50533
  return "replace";
50524
50534
  }
50525
50535
  if (input.statusAgeMs !== null && input.statusAgeMs <= fresh) return "adopt";
@@ -50547,7 +50557,7 @@ function daemonHealth(opts = {}) {
50547
50557
  ownerAlive,
50548
50558
  lockAgeMs,
50549
50559
  statusAgeMs,
50550
- myCompanionVersion: opts.myCompanionVersion
50560
+ myDaemonVersion: opts.myDaemonVersion
50551
50561
  }),
50552
50562
  lock,
50553
50563
  ownerAlive,
@@ -50591,7 +50601,7 @@ function tryOpenBrowser(url) {
50591
50601
  return false;
50592
50602
  }
50593
50603
  }
50594
- var AGENT_VERSION3 = true ? "agent-0.1.3" : "agent-dev";
50604
+ var DAEMON_VERSION3 = true ? "daemon-0.2.0" : "daemon-dev";
50595
50605
  function osFamily() {
50596
50606
  const p = platform5();
50597
50607
  if (p === "darwin") return "macos";
@@ -50609,17 +50619,30 @@ function intendedDeviceUuid() {
50609
50619
  const key = salt ? `${machineKey()}:${salt}` : machineKey();
50610
50620
  return deviceUuidFromMachineKey(key);
50611
50621
  }
50622
+ function isNonInteractive() {
50623
+ return Boolean(process.env.CI) || process.stdin.isTTY !== true;
50624
+ }
50625
+ function prodRegisterOptIn() {
50626
+ const v = process.env.MODELSTAT_ALLOW_PROD_REGISTER?.trim().toLowerCase();
50627
+ return v === "1" || v === "true" || v === "yes";
50628
+ }
50612
50629
  async function cmdSelfRegister() {
50613
50630
  const deviceUuid = state.deviceUuid ?? intendedDeviceUuid();
50614
50631
  const derived = !state.deviceUuid;
50632
+ if (derived && state.isProdDefaultApi && isNonInteractive() && !prodRegisterOptIn()) {
50633
+ process.stderr.write(
50634
+ "modelstat: refusing to self-register a new device against production from a\nnon-interactive/CI environment (no claim is possible here anyway). Either:\n \u2022 point at your own backend: DAEMON_API_URL=https://your-host (CI/e2e)\n \u2022 explicitly opt in: MODELSTAT_ALLOW_PROD_REGISTER=1\n \u2022 or run it interactively: npx modelstat@latest\n"
50635
+ );
50636
+ process.exit(2);
50637
+ }
50615
50638
  const mid = machineKey();
50616
50639
  const fingerprint = {
50617
50640
  hostname: hostname2(),
50618
50641
  os_family: osFamily(),
50619
50642
  os_version: release(),
50620
50643
  arch: osArch(),
50621
- companion: "modelstat-agent-dev",
50622
- companion_version: AGENT_VERSION3,
50644
+ daemon: "modelstat-daemon",
50645
+ daemon_version: DAEMON_VERSION3,
50623
50646
  // Stable, install-method-independent machine key. The server
50624
50647
  // dedupes self-register on this so the same physical machine can
50625
50648
  // never become two device rows, even if the UUID somehow differs
@@ -50845,7 +50868,7 @@ async function cmdConnect(opts) {
50845
50868
  warn(`couldn't prepare summariser model: ${e.message}`);
50846
50869
  warn("the background service will retry the download on its first scan");
50847
50870
  }
50848
- step("Installing/refreshing background service so the agent survives reboots");
50871
+ step("Installing/refreshing background service so the daemon survives reboots");
50849
50872
  let serviceOk = false;
50850
50873
  try {
50851
50874
  const svc = installService();
@@ -50859,7 +50882,7 @@ async function cmdConnect(opts) {
50859
50882
  } catch (e) {
50860
50883
  emitEvent(opts, "service_install_failed", { error: e.message });
50861
50884
  warn(`couldn't install service: ${e.message}`);
50862
- warn("the agent will not run in the background \u2014 re-run after fixing the issue");
50885
+ warn("the daemon will not run in the background \u2014 re-run after fixing the issue");
50863
50886
  }
50864
50887
  step("Detecting installed AI tools and signed-in accounts");
50865
50888
  let discovered = null;
@@ -51081,7 +51104,7 @@ async function cmdStats(args) {
51081
51104
  console.log(` ${dashboard}`);
51082
51105
  if (local) {
51083
51106
  console.log(
51084
- `local agent: ${local.status ?? "?"}${local.message ? ` \xB7 ${local.message}` : ""}`
51107
+ `local daemon: ${local.status ?? "?"}${local.message ? ` \xB7 ${local.message}` : ""}`
51085
51108
  );
51086
51109
  const stats = local.stats ?? {};
51087
51110
  for (const [k, v] of Object.entries(stats)) console.log(` ${k}: ${v}`);
@@ -51096,9 +51119,9 @@ async function cmdStats(args) {
51096
51119
  }
51097
51120
  console.log(`device: ${view.device.id}`);
51098
51121
  console.log(`host: ${view.device.hostname ?? "(unknown)"} (${view.device.os_family ?? "?"})`);
51099
- console.log(`companion: ${view.device.companion_version ?? "(unknown)"}`);
51122
+ console.log(`daemon: ${view.device.daemon_version ?? "(unknown)"}`);
51100
51123
  console.log(
51101
- `status: ${view.device.companion_status ?? "(unknown)"}${view.device.last_seen_at ? ` \xB7 last seen ${view.device.last_seen_at}` : ""}`
51124
+ `status: ${view.device.daemon_status ?? "(unknown)"}${view.device.last_seen_at ? ` \xB7 last seen ${view.device.last_seen_at}` : ""}`
51102
51125
  );
51103
51126
  console.log(
51104
51127
  `claim: ${view.status}${view.status === "unclaimed" ? ` (at ${view.claim_url})` : ""}`
@@ -51226,7 +51249,7 @@ async function main() {
51226
51249
  }
51227
51250
  case "_daemon-health": {
51228
51251
  try {
51229
- console.log(JSON.stringify(daemonHealth({ myCompanionVersion: AGENT_VERSION3 })));
51252
+ console.log(JSON.stringify(daemonHealth({ myDaemonVersion: DAEMON_VERSION3 })));
51230
51253
  } catch (e) {
51231
51254
  console.log(JSON.stringify({ decision: "spawn", error: e.message }));
51232
51255
  }