@legioncodeinc/honeycomb 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/LICENSE +661 -661
  4. package/README.md +314 -283
  5. package/assets/logos/honeycomb-memory-cluster.svg +17 -17
  6. package/assets/readme.md +117 -117
  7. package/assets/styles.css +11 -11
  8. package/assets/tokens/base.css +76 -76
  9. package/assets/tokens/colors.css +111 -111
  10. package/assets/tokens/fonts.css +32 -32
  11. package/assets/tokens/spacing.css +48 -48
  12. package/assets/tokens/typography.css +38 -38
  13. package/bundle/cli.js +522 -190
  14. package/daemon/index.js +43493 -43073
  15. package/daemon/restart-helper.js +0 -0
  16. package/embeddings/embed-daemon.js +1 -1
  17. package/harnesses/claude-code/.claude-plugin/plugin.json +2 -2
  18. package/harnesses/claude-code/bundle/capture.js +0 -0
  19. package/harnesses/claude-code/bundle/index.js +0 -0
  20. package/harnesses/claude-code/bundle/pre-tool-use.js +0 -0
  21. package/harnesses/claude-code/bundle/session-end.js +0 -0
  22. package/harnesses/claude-code/bundle/session-start.js +0 -0
  23. package/harnesses/claude-code/hooks/hooks.json +86 -86
  24. package/harnesses/codex/bundle/capture.js +0 -0
  25. package/harnesses/codex/bundle/index.js +0 -0
  26. package/harnesses/codex/bundle/pre-tool-use.js +0 -0
  27. package/harnesses/codex/bundle/session-start.js +0 -0
  28. package/harnesses/codex/package.json +2 -2
  29. package/harnesses/cursor/bundle/capture.js +0 -0
  30. package/harnesses/cursor/bundle/index.js +0 -0
  31. package/harnesses/cursor/bundle/pre-tool-use.js +0 -0
  32. package/harnesses/cursor/bundle/session-end.js +0 -0
  33. package/harnesses/cursor/bundle/session-start.js +0 -0
  34. package/harnesses/hermes/bundle/index.js +0 -0
  35. package/harnesses/openclaw/dist/index.js +1 -1
  36. package/harnesses/openclaw/openclaw.plugin.json +1 -1
  37. package/harnesses/openclaw/package.json +2 -2
  38. package/harnesses/pi/bundle/index.js +0 -0
  39. package/mcp/bundle/server.js +1 -1
  40. package/package.json +144 -144
  41. package/scripts/ensure-embed-deps.mjs +67 -67
  42. package/scripts/ensure-tree-sitter.mjs +89 -89
package/bundle/cli.js CHANGED
@@ -16952,134 +16952,6 @@ function renderResolvedScope(deps, out) {
16952
16952
  }
16953
16953
  }
16954
16954
 
16955
- // dist/src/commands/local-handlers.js
16956
- function harnessArg(argv) {
16957
- return argv.find((a) => !a.startsWith("--"));
16958
- }
16959
- async function runConnectorVerb(verb, argv, deps) {
16960
- const out = deps.out ?? ((line) => console.log(line));
16961
- if (deps.connector === void 0) {
16962
- out(`${verb}: the connector engine is not wired in this build (deferred assembly).`);
16963
- return { exitCode: 1 };
16964
- }
16965
- const harness = harnessArg(argv);
16966
- const result = await deps.connector.run({ verb, ...harness !== void 0 ? { harness } : {} });
16967
- if (result.harnesses.length > 0) {
16968
- out(`${verb}: ${verb === "uninstall" ? "reversed" : "wired"} ${result.harnesses.join(", ")}.`);
16969
- } else {
16970
- out(`${verb}: no harnesses ${verb === "uninstall" ? "reversed" : "wired"}.`);
16971
- }
16972
- return { exitCode: result.exitCode };
16973
- }
16974
- async function runDashboardCommand(deps) {
16975
- const out = deps.out ?? ((line) => console.log(line));
16976
- if (deps.dashboard === void 0) {
16977
- out("dashboard: the dashboard launcher is not wired in this build (deferred assembly).");
16978
- return { exitCode: 1 };
16979
- }
16980
- const { reachable: reachable2 } = await deps.dashboard.launch();
16981
- out(reachable2 ? "dashboard: launched (daemon reachable)." : "dashboard: daemon is not reachable \u2014 start it with `honeycomb setup`.");
16982
- return { exitCode: 0 };
16983
- }
16984
- async function runHookCommand(argv, deps) {
16985
- const out = deps.out ?? ((line) => console.log(line));
16986
- const sub = argv.find((a) => !a.startsWith("--")) ?? "status";
16987
- if (sub === "wire") {
16988
- return runConnectorVerb("setup", argv.slice(1), deps);
16989
- }
16990
- out("hook: run `honeycomb hook wire` to (re)wire harness hooks, or `honeycomb status` for D1\u2013D5.");
16991
- return { exitCode: 0 };
16992
- }
16993
- async function runUpdateCommand(argv, deps) {
16994
- const out = deps.out ?? ((line) => console.log(line));
16995
- const dryRun = argv.includes("--dry-run");
16996
- if (dryRun) {
16997
- out("update --dry-run: would update the CLI, daemon, and harness bundles to the latest release.");
16998
- return { exitCode: 0 };
16999
- }
17000
- out("update: self-update is performed by the bundled bin (deferred assembly); re-run with --dry-run to preview.");
17001
- return { exitCode: 0 };
17002
- }
17003
-
17004
- // dist/src/commands/daemon.js
17005
- function parseDaemonArgs(argv) {
17006
- return argv.find((a) => !a.startsWith("--")) ?? "status";
17007
- }
17008
- async function start(deps, out) {
17009
- if (deps.lifecycle === void 0) {
17010
- out("daemon start: no daemon lifecycle is available in this context.");
17011
- return { exitCode: 1 };
17012
- }
17013
- const { started, alreadyRunning } = await deps.lifecycle.start();
17014
- if (alreadyRunning) {
17015
- out("daemon: already running on 127.0.0.1:3850.");
17016
- return { exitCode: 0 };
17017
- }
17018
- if (started) {
17019
- out("daemon: started on 127.0.0.1:3850.");
17020
- return { exitCode: 0 };
17021
- }
17022
- const status3 = await deps.lifecycle.status();
17023
- if (status3.running) {
17024
- out(`daemon: starting \u2014 the process is up (pid ${status3.pid ?? "?"}) but has not answered /health within the start budget; it is likely still warming up. Re-check with \`honeycomb daemon status\`.`);
17025
- return { exitCode: 0 };
17026
- }
17027
- out("daemon: failed to start (did not become reachable on 127.0.0.1:3850).");
17028
- return { exitCode: 1 };
17029
- }
17030
- async function stop(deps, out) {
17031
- if (deps.lifecycle === void 0) {
17032
- out("daemon stop: no daemon lifecycle is available in this context.");
17033
- return { exitCode: 1 };
17034
- }
17035
- const { stopped } = await deps.lifecycle.stop();
17036
- out(stopped ? "daemon: stopped." : "daemon: not running.");
17037
- return { exitCode: 0 };
17038
- }
17039
- async function status(deps, out) {
17040
- if (deps.lifecycle === void 0) {
17041
- const alive = await deps.daemon.ping();
17042
- out(`daemon: ${alive ? "up (127.0.0.1:3850)" : "down"}`);
17043
- return { exitCode: 0 };
17044
- }
17045
- const state = await deps.lifecycle.status();
17046
- const reachable2 = await deps.daemon.ping();
17047
- if (state.running && reachable2) {
17048
- out(`daemon: running on 127.0.0.1:${state.port}${state.pid !== void 0 ? ` (pid ${state.pid})` : ""}.`);
17049
- } else if (state.running && !reachable2) {
17050
- out(`daemon: process holds the lock${state.pid !== void 0 ? ` (pid ${state.pid})` : ""} but is not answering /health yet.`);
17051
- } else {
17052
- out("daemon: not running.");
17053
- }
17054
- return { exitCode: 0 };
17055
- }
17056
- async function runDaemonCommand(argv, deps) {
17057
- const out = deps.out ?? ((line) => console.log(line));
17058
- const sub = parseDaemonArgs(argv);
17059
- if (sub === "start")
17060
- return start(deps, out);
17061
- if (sub === "stop")
17062
- return stop(deps, out);
17063
- if (sub === "status")
17064
- return status(deps, out);
17065
- out("usage: honeycomb daemon <start | stop | status>");
17066
- return { exitCode: 1 };
17067
- }
17068
- async function ensureDaemonRunning(deps) {
17069
- if (await deps.daemon.ping())
17070
- return true;
17071
- if (deps.lifecycle === void 0)
17072
- return false;
17073
- const { started, alreadyRunning } = await deps.lifecycle.start();
17074
- if (alreadyRunning || started) {
17075
- return deps.daemon.ping();
17076
- }
17077
- return false;
17078
- }
17079
-
17080
- // dist/src/commands/install.js
17081
- import { execFileSync as execFileSync3 } from "node:child_process";
17082
-
17083
16955
  // dist/src/daemon/runtime/onboarding/onboarding-store.js
17084
16956
  import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync8, renameSync as renameSync3, writeFileSync as writeFileSync6 } from "node:fs";
17085
16957
  import { homedir as homedir8 } from "node:os";
@@ -17088,7 +16960,13 @@ import { randomUUID as randomUUID3 } from "node:crypto";
17088
16960
  var ONBOARDING_FILE_NAME = "onboarding.json";
17089
16961
  var ONBOARDING_SCHEMA_VERSION = 1;
17090
16962
  var DEFAULT_REF = true ? "mario" : "mario";
17091
- var TelemetryEventNameSchema = external_exports.enum(["honeycomb_installed", "honeycomb_first_link", "honeycomb_hivemind_upgrade"]);
16963
+ var TelemetryEventNameSchema = external_exports.enum([
16964
+ "honeycomb_installed",
16965
+ "honeycomb_first_link",
16966
+ "honeycomb_hivemind_upgrade",
16967
+ "honeycomb_updated",
16968
+ "honeycomb_uninstalled"
16969
+ ]);
17092
16970
  var TelemetrySentRecordSchema = external_exports.object({
17093
16971
  event: TelemetryEventNameSchema,
17094
16972
  at: external_exports.string(),
@@ -17103,16 +16981,18 @@ var OnboardingStateSchema = external_exports.object({
17103
16981
  phase: external_exports.enum(["fresh", "installed", "linking", "linked", "migrating", "migrated"]),
17104
16982
  firstTimeSetupComplete: external_exports.boolean(),
17105
16983
  ref: external_exports.string(),
16984
+ // Optional: absent on a fresh install and on pre-existing files (fail-soft compatibility).
16985
+ lastVersion: external_exports.string().optional(),
17106
16986
  priorTool: external_exports.object({
17107
16987
  hivemind: external_exports.enum(["absent", "present", "migrated"])
17108
16988
  }),
17109
16989
  telemetry: external_exports.object({
17110
16990
  optInTier2: external_exports.boolean(),
17111
- // `reported` is a PARTIAL ledger only events that have fired are present.
17112
- // zod v4's `z.record(enum, …)` is EXHAUSTIVE (it demands every enum key), which
17113
- // would reject the common empty/partial ledger; `z.partialRecord` is the precise
17114
- // match for the `Partial<Record<TelemetryEventName, string>>` contract field.
17115
- reported: external_exports.partialRecord(TelemetryEventNameSchema, external_exports.string()),
16991
+ // `reported` is a PARTIAL ledger keyed by LEDGER KEY (usually the event name, but a
16992
+ // version-qualified key like `honeycomb_updated@1.2.3` is valid too), so the schema is a
16993
+ // plain string→string record rather than an enum-keyed one. Only keys that have fired
16994
+ // are present; an empty ledger is the common fresh-install shape.
16995
+ reported: external_exports.record(external_exports.string(), external_exports.string()),
17116
16996
  sent: external_exports.array(TelemetrySentRecordSchema)
17117
16997
  }),
17118
16998
  migration: external_exports.object({
@@ -17176,17 +17056,17 @@ function saveOnboarding(state, dir) {
17176
17056
  renameSync3(tmp, path);
17177
17057
  return state;
17178
17058
  }
17179
- function markReported(state, event, isoTimestamp) {
17059
+ function markReported(state, ledgerKey, isoTimestamp) {
17180
17060
  return {
17181
17061
  ...state,
17182
17062
  telemetry: {
17183
17063
  ...state.telemetry,
17184
- reported: { ...state.telemetry.reported, [event]: isoTimestamp }
17064
+ reported: { ...state.telemetry.reported, [ledgerKey]: isoTimestamp }
17185
17065
  }
17186
17066
  };
17187
17067
  }
17188
- function isReported(state, event) {
17189
- return state.telemetry.reported[event] !== void 0;
17068
+ function isReported(state, ledgerKey) {
17069
+ return state.telemetry.reported[ledgerKey] !== void 0;
17190
17070
  }
17191
17071
  function appendSent(state, record2) {
17192
17072
  return {
@@ -17200,7 +17080,7 @@ function appendSent(state, record2) {
17200
17080
 
17201
17081
  // dist/src/daemon/runtime/telemetry/emit.js
17202
17082
  import { arch, platform, release } from "node:os";
17203
- var POSTHOG_KEY = true ? "phc_wjWdFZfMRtUATshcoBRkZ3FiSMmAKEuVuP6ftraTCiPz" : "";
17083
+ var POSTHOG_KEY = true ? "" : "";
17204
17084
  var POSTHOG_HOST = "https://us.i.posthog.com".length > 0 ? "https://us.i.posthog.com" : "https://us.i.posthog.com";
17205
17085
  var POSTHOG_CAPTURE_PATH = "/i/v0/e/";
17206
17086
  function captureUrl(host = POSTHOG_HOST) {
@@ -17217,7 +17097,9 @@ function isOptedOut(env = process.env) {
17217
17097
  var TIER1_EVENTS = /* @__PURE__ */ new Set([
17218
17098
  "honeycomb_installed",
17219
17099
  "honeycomb_first_link",
17220
- "honeycomb_hivemind_upgrade"
17100
+ "honeycomb_hivemind_upgrade",
17101
+ "honeycomb_updated",
17102
+ "honeycomb_uninstalled"
17221
17103
  ]);
17222
17104
  function tierForEvent(event) {
17223
17105
  return TIER1_EVENTS.has(event) ? "tier1" : "tier2";
@@ -17262,7 +17144,7 @@ function buildAllowedProperties(input) {
17262
17144
  }
17263
17145
  var systemTelemetryClock = () => (/* @__PURE__ */ new Date()).toISOString();
17264
17146
  var DEFAULT_EMIT_TIMEOUT_MS = 2e3;
17265
- var HONEYCOMB_VERSION = true ? "0.1.13" : "0.0.0-dev";
17147
+ var HONEYCOMB_VERSION = true ? "0.1.14" : "0.0.0-dev";
17266
17148
  async function emitTelemetry(event, opts, deps = {}) {
17267
17149
  const env = deps.env ?? process.env;
17268
17150
  const key = deps.posthogKey ?? POSTHOG_KEY;
@@ -17287,7 +17169,8 @@ async function emitTelemetry(event, opts, deps = {}) {
17287
17169
  if (effectiveTier === "tier2" && state.telemetry.optInTier2 !== true) {
17288
17170
  return { sent: false, skipped: "not_consented", properties };
17289
17171
  }
17290
- if (isReported(state, event))
17172
+ const ledgerKey = opts.dedupeKey ?? event;
17173
+ if (isReported(state, ledgerKey))
17291
17174
  return { sent: false, skipped: "already_reported", properties };
17292
17175
  const distinctId = state.installId;
17293
17176
  const ok2 = await postCapture(event, properties, distinctId, key, deps);
@@ -17296,7 +17179,7 @@ async function emitTelemetry(event, opts, deps = {}) {
17296
17179
  const clock = deps.clock ?? systemTelemetryClock;
17297
17180
  const at = clock();
17298
17181
  const sentRecord = { event, at, properties };
17299
- const next = appendSent(markReported(state, event, at), sentRecord);
17182
+ const next = appendSent(markReported(state, ledgerKey, at), sentRecord);
17300
17183
  try {
17301
17184
  save(next, deps.dir);
17302
17185
  } catch {
@@ -17402,20 +17285,405 @@ function renderGlassBoxText(view) {
17402
17285
  return lines.join("\n");
17403
17286
  }
17404
17287
 
17288
+ // dist/src/daemon/runtime/telemetry/version-check.js
17289
+ async function recordVersionAndEmitUpdated(ref, deps = {}) {
17290
+ try {
17291
+ const load = deps.loadOnboarding ?? loadOnboarding;
17292
+ const save = deps.saveOnboarding ?? saveOnboarding;
17293
+ const version2 = deps.version ?? HONEYCOMB_VERSION;
17294
+ const state = load(deps.dir);
17295
+ if (state.lastVersion === version2)
17296
+ return { changed: false };
17297
+ if (state.lastVersion === void 0) {
17298
+ save({ ...state, lastVersion: version2 }, deps.dir);
17299
+ return { changed: false };
17300
+ }
17301
+ const emit = await emitTelemetry("honeycomb_updated", { ref, tier: "tier1", dedupeKey: `honeycomb_updated@${version2}` }, deps);
17302
+ try {
17303
+ const fresh = load(deps.dir);
17304
+ save({ ...fresh, lastVersion: version2 }, deps.dir);
17305
+ } catch {
17306
+ }
17307
+ return { changed: true, emit };
17308
+ } catch {
17309
+ return { changed: false };
17310
+ }
17311
+ }
17312
+
17313
+ // dist/src/commands/local-handlers.js
17314
+ function harnessArg(argv) {
17315
+ return argv.find((a) => !a.startsWith("--"));
17316
+ }
17317
+ async function runConnectorVerb(verb, argv, deps) {
17318
+ const out = deps.out ?? ((line) => console.log(line));
17319
+ if (deps.connector === void 0) {
17320
+ out(`${verb}: the connector engine is not wired in this build (deferred assembly).`);
17321
+ return { exitCode: 1 };
17322
+ }
17323
+ const harness = harnessArg(argv);
17324
+ if (verb === "uninstall" && harness === void 0) {
17325
+ let ref = DEFAULT_REF;
17326
+ try {
17327
+ ref = loadOnboarding(deps.dir).ref;
17328
+ } catch {
17329
+ }
17330
+ void emitTelemetry("honeycomb_uninstalled", { ref, tier: "tier1" }, { ...deps.telemetry ?? {}, ...deps.dir !== void 0 ? { dir: deps.dir } : {} });
17331
+ }
17332
+ const result = await deps.connector.run({ verb, ...harness !== void 0 ? { harness } : {} });
17333
+ if (result.harnesses.length > 0) {
17334
+ out(`${verb}: ${verb === "uninstall" ? "reversed" : "wired"} ${result.harnesses.join(", ")}.`);
17335
+ } else {
17336
+ out(`${verb}: no harnesses ${verb === "uninstall" ? "reversed" : "wired"}.`);
17337
+ }
17338
+ return { exitCode: result.exitCode };
17339
+ }
17340
+ async function runDashboardCommand(deps) {
17341
+ const out = deps.out ?? ((line) => console.log(line));
17342
+ if (deps.dashboard === void 0) {
17343
+ out("dashboard: the dashboard launcher is not wired in this build (deferred assembly).");
17344
+ return { exitCode: 1 };
17345
+ }
17346
+ const { reachable: reachable2 } = await deps.dashboard.launch();
17347
+ out(reachable2 ? "dashboard: launched (daemon reachable)." : "dashboard: daemon is not reachable \u2014 start it with `honeycomb setup`.");
17348
+ return { exitCode: 0 };
17349
+ }
17350
+ async function runHookCommand(argv, deps) {
17351
+ const out = deps.out ?? ((line) => console.log(line));
17352
+ const sub = argv.find((a) => !a.startsWith("--")) ?? "status";
17353
+ if (sub === "wire") {
17354
+ return runConnectorVerb("setup", argv.slice(1), deps);
17355
+ }
17356
+ out("hook: run `honeycomb hook wire` to (re)wire harness hooks, or `honeycomb status` for D1\u2013D5.");
17357
+ return { exitCode: 0 };
17358
+ }
17359
+ async function runUpdateCommand(argv, deps) {
17360
+ const out = deps.out ?? ((line) => console.log(line));
17361
+ const dryRun = argv.includes("--dry-run");
17362
+ if (dryRun) {
17363
+ out("update --dry-run: would update the CLI, daemon, and harness bundles to the latest release.");
17364
+ return { exitCode: 0 };
17365
+ }
17366
+ out("update: self-update is performed by the bundled bin (deferred assembly); re-run with --dry-run to preview.");
17367
+ return { exitCode: 0 };
17368
+ }
17369
+
17370
+ // dist/src/commands/daemon.js
17371
+ function parseDaemonArgs(argv) {
17372
+ return argv.find((a) => !a.startsWith("--")) ?? "status";
17373
+ }
17374
+ async function start(deps, out) {
17375
+ if (deps.lifecycle === void 0) {
17376
+ out("daemon start: no daemon lifecycle is available in this context.");
17377
+ return { exitCode: 1 };
17378
+ }
17379
+ const { started, alreadyRunning } = await deps.lifecycle.start();
17380
+ if (alreadyRunning) {
17381
+ out("daemon: already running on 127.0.0.1:3850.");
17382
+ return { exitCode: 0 };
17383
+ }
17384
+ if (started) {
17385
+ out("daemon: started on 127.0.0.1:3850.");
17386
+ return { exitCode: 0 };
17387
+ }
17388
+ const status3 = await deps.lifecycle.status();
17389
+ if (status3.running) {
17390
+ out(`daemon: starting \u2014 the process is up (pid ${status3.pid ?? "?"}) but has not answered /health within the start budget; it is likely still warming up. Re-check with \`honeycomb daemon status\`.`);
17391
+ return { exitCode: 0 };
17392
+ }
17393
+ out("daemon: failed to start (did not become reachable on 127.0.0.1:3850).");
17394
+ return { exitCode: 1 };
17395
+ }
17396
+ async function stop(deps, out) {
17397
+ if (deps.lifecycle === void 0) {
17398
+ out("daemon stop: no daemon lifecycle is available in this context.");
17399
+ return { exitCode: 1 };
17400
+ }
17401
+ const { stopped } = await deps.lifecycle.stop();
17402
+ out(stopped ? "daemon: stopped." : "daemon: not running.");
17403
+ return { exitCode: 0 };
17404
+ }
17405
+ async function status(deps, out) {
17406
+ if (deps.lifecycle === void 0) {
17407
+ const alive = await deps.daemon.ping();
17408
+ out(`daemon: ${alive ? "up (127.0.0.1:3850)" : "down"}`);
17409
+ return { exitCode: 0 };
17410
+ }
17411
+ const state = await deps.lifecycle.status();
17412
+ const reachable2 = await deps.daemon.ping();
17413
+ if (state.running && reachable2) {
17414
+ out(`daemon: running on 127.0.0.1:${state.port}${state.pid !== void 0 ? ` (pid ${state.pid})` : ""}.`);
17415
+ } else if (state.running && !reachable2) {
17416
+ out(`daemon: process holds the lock${state.pid !== void 0 ? ` (pid ${state.pid})` : ""} but is not answering /health yet.`);
17417
+ } else {
17418
+ out("daemon: not running.");
17419
+ }
17420
+ return { exitCode: 0 };
17421
+ }
17422
+ async function runDaemonCommand(argv, deps) {
17423
+ const out = deps.out ?? ((line) => console.log(line));
17424
+ const sub = parseDaemonArgs(argv);
17425
+ if (sub === "start")
17426
+ return start(deps, out);
17427
+ if (sub === "stop")
17428
+ return stop(deps, out);
17429
+ if (sub === "status")
17430
+ return status(deps, out);
17431
+ out("usage: honeycomb daemon <start | stop | status>");
17432
+ return { exitCode: 1 };
17433
+ }
17434
+ async function ensureDaemonRunning(deps) {
17435
+ if (await deps.daemon.ping())
17436
+ return true;
17437
+ if (deps.lifecycle === void 0)
17438
+ return false;
17439
+ const { started, alreadyRunning } = await deps.lifecycle.start();
17440
+ if (alreadyRunning || started) {
17441
+ return deps.daemon.ping();
17442
+ }
17443
+ return false;
17444
+ }
17445
+
17446
+ // dist/src/commands/install.js
17447
+ import { execFileSync as execFileSync3 } from "node:child_process";
17448
+
17405
17449
  // dist/src/shared/constants.js
17406
17450
  var DAEMON_PORT = 3850;
17407
17451
  var DAEMON_HOST = "127.0.0.1";
17408
- var HONEYCOMB_VERSION2 = true ? "0.1.13" : "0.0.0-dev";
17452
+ var HIVE_PORT = 3853;
17453
+ var HIVE_HOST = "127.0.0.1";
17454
+ var HONEYCOMB_VERSION2 = true ? "0.1.14" : "0.0.0-dev";
17409
17455
  var PRODUCT_SLUG = "honeycomb";
17410
17456
 
17457
+ // dist/src/daemon/runtime/config.js
17458
+ var DEPLOYMENT_MODES = Object.freeze(["local", "team", "hybrid"]);
17459
+ var LOOPBACK_HOST = DAEMON_HOST;
17460
+ var Port = external_exports.preprocess((raw) => {
17461
+ const n2 = typeof raw === "number" ? raw : Number(raw);
17462
+ if (!Number.isFinite(n2))
17463
+ return DAEMON_PORT;
17464
+ return Math.min(Math.max(1, Math.trunc(n2)), 65535);
17465
+ }, external_exports.number().int());
17466
+ var HOST_PATTERN = /^[A-Za-z0-9._:-]+$/;
17467
+ var Host = external_exports.string().trim().min(1, "host must not be empty").regex(HOST_PATTERN, "host must be a bare hostname or IP, not a URL");
17468
+ var RuntimeConfigSchema = external_exports.object({
17469
+ /** Effective listen host (post-`HONEYCOMB_BIND` widening). */
17470
+ host: Host.default(LOOPBACK_HOST),
17471
+ /** Listen port, clamped into the valid TCP range. */
17472
+ port: Port.default(DAEMON_PORT),
17473
+ /** Deployment mode driving permission enforcement (FR-3). */
17474
+ mode: external_exports.enum(DEPLOYMENT_MODES).default("local"),
17475
+ /** True when the bind was widened off loopback via `HONEYCOMB_BIND` (a-AC-7). */
17476
+ widened: external_exports.boolean().default(false)
17477
+ });
17478
+ var RuntimeConfigError = class extends Error {
17479
+ issues;
17480
+ constructor(issues) {
17481
+ super(`Invalid daemon runtime config: ${issues.join("; ")}`);
17482
+ this.name = "RuntimeConfigError";
17483
+ this.issues = issues;
17484
+ }
17485
+ };
17486
+ function envRuntimeConfigProvider(env = process.env) {
17487
+ return {
17488
+ read() {
17489
+ return {
17490
+ port: env.HONEYCOMB_PORT,
17491
+ host: env.HONEYCOMB_HOST,
17492
+ bind: env.HONEYCOMB_BIND,
17493
+ mode: env.HONEYCOMB_MODE
17494
+ };
17495
+ }
17496
+ };
17497
+ }
17498
+ function resolveRuntimeConfig(provider = envRuntimeConfigProvider()) {
17499
+ const raw = provider.read();
17500
+ const bindSet = typeof raw.bind === "string" && raw.bind.trim().length > 0;
17501
+ const effectiveHost = bindSet ? raw.bind : raw.host;
17502
+ const parsed = RuntimeConfigSchema.safeParse({
17503
+ host: effectiveHost,
17504
+ port: raw.port,
17505
+ mode: raw.mode,
17506
+ widened: bindSet && !isLoopback(String(raw.bind).trim())
17507
+ });
17508
+ if (!parsed.success) {
17509
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`);
17510
+ throw new RuntimeConfigError(issues);
17511
+ }
17512
+ return parsed.data;
17513
+ }
17514
+ function isLoopback(host) {
17515
+ return host === "127.0.0.1" || host === "::1" || host === "localhost";
17516
+ }
17517
+
17518
+ // dist/src/daemon/runtime/telemetry/fleet-registry.js
17519
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync4, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
17520
+ import { homedir as homedir10 } from "node:os";
17521
+ import { dirname as dirname5, join as join10 } from "node:path";
17522
+
17523
+ // dist/src/daemon/runtime/telemetry/fleet-store.js
17524
+ import { existsSync as existsSync6, mkdirSync as mkdirSync7 } from "node:fs";
17525
+ import { createRequire } from "node:module";
17526
+ import { homedir as homedir9 } from "node:os";
17527
+ import { join as join9 } from "node:path";
17528
+ var FLEET_SERVICE_NAME = "honeycomb";
17529
+ var NULL_FLEET_TELEMETRY_STORE = Object.freeze({
17530
+ persistent: false,
17531
+ upsertStatus() {
17532
+ },
17533
+ upsertMetrics() {
17534
+ },
17535
+ appendLog() {
17536
+ },
17537
+ readStatus() {
17538
+ return null;
17539
+ },
17540
+ readMetrics() {
17541
+ return null;
17542
+ },
17543
+ readRecentLogs() {
17544
+ return [];
17545
+ },
17546
+ close() {
17547
+ }
17548
+ });
17549
+
17550
+ // dist/src/daemon/runtime/telemetry/fleet-registry.js
17551
+ function doctorRegistryPath(homeDir = homedir10()) {
17552
+ return join10(homeDir, ".honeycomb", "doctor.daemons.json");
17553
+ }
17554
+ var HONEYCOMB_REGISTRY_NAME = FLEET_SERVICE_NAME;
17555
+ function honeycombRegistryHealthUrl(bind) {
17556
+ return `http://${bind?.host ?? DAEMON_HOST}:${bind?.port ?? DAEMON_PORT}/health`;
17557
+ }
17558
+ var HONEYCOMB_REGISTRY_HEALTH_URL = `http://${DAEMON_HOST}:${DAEMON_PORT}/health`;
17559
+ var HONEYCOMB_REGISTRY_PID_PATH = "~/.honeycomb/daemon.pid";
17560
+ var HONEYCOMB_REGISTRY_PROBE_INTERVAL_MS = 3e4;
17561
+ var HONEYCOMB_REGISTRY_STARTUP_GRACE_MS = 6e4;
17562
+ var HONEYCOMB_REGISTRY_RESTART_GIVE_UP_THRESHOLD = 3;
17563
+ var HONEYCOMB_REGISTRY_RESTART_COOLDOWN_MS = 5e3;
17564
+ var HONEYCOMB_REGISTRY_TELEMETRY_DB_PATH = "~/.honeycomb/telemetry/honeycomb.sqlite";
17565
+ function createNodeRegistryFs() {
17566
+ return {
17567
+ readFile(path) {
17568
+ return readFileSync9(path, "utf8");
17569
+ },
17570
+ mkdirp(path) {
17571
+ mkdirSync8(path, { recursive: true });
17572
+ },
17573
+ writeFile(path, content) {
17574
+ writeFileSync7(path, content, "utf8");
17575
+ },
17576
+ rename(from, to) {
17577
+ renameSync4(from, to);
17578
+ },
17579
+ removeFile(path) {
17580
+ rmSync2(path, { force: true });
17581
+ }
17582
+ };
17583
+ }
17584
+ function asObject(value) {
17585
+ if (typeof value === "object" && value !== null && !Array.isArray(value))
17586
+ return value;
17587
+ return null;
17588
+ }
17589
+ function parseRegistryDocument(raw) {
17590
+ let parsed;
17591
+ try {
17592
+ parsed = JSON.parse(raw);
17593
+ } catch {
17594
+ return { root: {}, daemons: [] };
17595
+ }
17596
+ const root = asObject(parsed);
17597
+ if (root === null)
17598
+ return { root: {}, daemons: [] };
17599
+ const rawDaemons = root.daemons;
17600
+ const daemons = Array.isArray(rawDaemons) ? rawDaemons.map((entry) => asObject(entry)).filter((entry) => entry !== null) : [];
17601
+ return { root, daemons };
17602
+ }
17603
+ function buildHoneycombRegistryEntry(bind) {
17604
+ return {
17605
+ name: HONEYCOMB_REGISTRY_NAME,
17606
+ healthUrl: honeycombRegistryHealthUrl(bind),
17607
+ pidPath: HONEYCOMB_REGISTRY_PID_PATH,
17608
+ probeIntervalMs: HONEYCOMB_REGISTRY_PROBE_INTERVAL_MS,
17609
+ startupGraceMs: HONEYCOMB_REGISTRY_STARTUP_GRACE_MS,
17610
+ restartGiveUpThreshold: HONEYCOMB_REGISTRY_RESTART_GIVE_UP_THRESHOLD,
17611
+ restartCooldownMs: HONEYCOMB_REGISTRY_RESTART_COOLDOWN_MS,
17612
+ telemetryDbPath: HONEYCOMB_REGISTRY_TELEMETRY_DB_PATH
17613
+ };
17614
+ }
17615
+ function readRegistryDocument(path, fs) {
17616
+ try {
17617
+ return parseRegistryDocument(fs.readFile(path));
17618
+ } catch (error51) {
17619
+ const code = error51.code;
17620
+ if (code === "ENOENT")
17621
+ return { root: {}, daemons: [] };
17622
+ throw error51;
17623
+ }
17624
+ }
17625
+ function nextTempPath(registryPath) {
17626
+ return `${registryPath}.tmp-${process.pid}-${Date.now()}`;
17627
+ }
17628
+ var REGISTRY_UPSERT_MAX_ATTEMPTS = 5;
17629
+ function entryMatches(entry, wanted) {
17630
+ for (const [key, value] of Object.entries(wanted)) {
17631
+ if (entry[key] !== value)
17632
+ return false;
17633
+ }
17634
+ return true;
17635
+ }
17636
+ function writeMergedRegistry(registryPath, fs, honeycombEntry) {
17637
+ const parsed = readRegistryDocument(registryPath, fs);
17638
+ const nextDaemons = [...parsed.daemons];
17639
+ const index = nextDaemons.findIndex((entry) => entry.name === HONEYCOMB_REGISTRY_NAME);
17640
+ if (index >= 0) {
17641
+ nextDaemons[index] = { ...nextDaemons[index], ...honeycombEntry };
17642
+ } else {
17643
+ nextDaemons.push(honeycombEntry);
17644
+ }
17645
+ const nextRoot = { ...parsed.root, daemons: nextDaemons };
17646
+ const serialized = `${JSON.stringify(nextRoot, null, 2)}
17647
+ `;
17648
+ const tempPath = nextTempPath(registryPath);
17649
+ fs.mkdirp(dirname5(registryPath));
17650
+ fs.writeFile(tempPath, serialized);
17651
+ try {
17652
+ fs.rename(tempPath, registryPath);
17653
+ } catch (error51) {
17654
+ fs.removeFile(tempPath);
17655
+ throw error51;
17656
+ }
17657
+ return { updatedExistingEntry: index >= 0 };
17658
+ }
17659
+ function registerHoneycombWithDoctor(options = {}) {
17660
+ const registryPath = options.registryPath ?? doctorRegistryPath(options.homeDir ?? homedir10());
17661
+ const fs = options.fs ?? createNodeRegistryFs();
17662
+ const honeycombEntry = buildHoneycombRegistryEntry(options.bind);
17663
+ let updatedExistingEntry = false;
17664
+ for (let attempt = 0; attempt < REGISTRY_UPSERT_MAX_ATTEMPTS; attempt++) {
17665
+ const round = writeMergedRegistry(registryPath, fs, honeycombEntry);
17666
+ if (attempt === 0)
17667
+ updatedExistingEntry = round.updatedExistingEntry;
17668
+ const after = readRegistryDocument(registryPath, fs);
17669
+ const mine = after.daemons.find((entry) => entry.name === HONEYCOMB_REGISTRY_NAME);
17670
+ if (mine !== void 0 && entryMatches(mine, honeycombEntry))
17671
+ break;
17672
+ }
17673
+ return {
17674
+ registryPath,
17675
+ updatedExistingEntry
17676
+ };
17677
+ }
17678
+
17411
17679
  // dist/src/commands/install.js
17412
17680
  var DASHBOARD_LOCAL_HOST = "honeycomb.local";
17413
- var DASHBOARD_PATH = "/dashboard";
17681
+ var DASHBOARD_PATH = "/";
17414
17682
  function localDashboardUrl() {
17415
- return `http://${DASHBOARD_LOCAL_HOST}:${DAEMON_PORT}${DASHBOARD_PATH}`;
17683
+ return `http://${DASHBOARD_LOCAL_HOST}:${HIVE_PORT}${DASHBOARD_PATH}`;
17416
17684
  }
17417
17685
  function loopbackDashboardUrl() {
17418
- return `http://${DAEMON_HOST}:${DAEMON_PORT}${DASHBOARD_PATH}`;
17686
+ return `http://${HIVE_HOST}:${HIVE_PORT}${DASHBOARD_PATH}`;
17419
17687
  }
17420
17688
  function openLocalDashboardUrl(url2) {
17421
17689
  let safeUrl;
@@ -17477,6 +17745,28 @@ function writeInstalledMarker(ref, dir, out) {
17477
17745
  return false;
17478
17746
  }
17479
17747
  }
17748
+ function resolveRegistryBind() {
17749
+ try {
17750
+ const config2 = resolveRuntimeConfig();
17751
+ const host = config2.host === "0.0.0.0" || config2.host === "::" ? DAEMON_HOST : config2.host;
17752
+ return { host, port: config2.port };
17753
+ } catch {
17754
+ return void 0;
17755
+ }
17756
+ }
17757
+ function writeDoctorRegistryEntry(dir, out) {
17758
+ try {
17759
+ const bind = resolveRegistryBind();
17760
+ registerHoneycombWithDoctor({
17761
+ ...dir !== void 0 ? { homeDir: dir } : {},
17762
+ ...bind !== void 0 ? { bind } : {}
17763
+ });
17764
+ return true;
17765
+ } catch {
17766
+ out("note: could not register with doctor (continuing \u2014 the install still succeeded).");
17767
+ return false;
17768
+ }
17769
+ }
17480
17770
  function openDashboardWithFallback(opener, out) {
17481
17771
  const friendly = localDashboardUrl();
17482
17772
  const loopback = loopbackDashboardUrl();
@@ -17521,9 +17811,17 @@ async function runInstallCommand(argv, deps) {
17521
17811
  const wrote = writeInstalledMarker(ref, deps.dir, out);
17522
17812
  if (wrote)
17523
17813
  out(`\u2713 onboarding marked installed (ref: ${ref}).`);
17814
+ writeDoctorRegistryEntry(deps.dir, out);
17524
17815
  openDashboardWithFallback(opener, out);
17525
17816
  out("\u2713 Honeycomb is ready.");
17526
- void emitTelemetry("honeycomb_installed", { ref, tier: "tier1" }, { ...deps.telemetry ?? {}, ...deps.dir !== void 0 ? { dir: deps.dir } : {} });
17817
+ const telemetryDeps = {
17818
+ ...deps.telemetry ?? {},
17819
+ ...deps.dir !== void 0 ? { dir: deps.dir } : {}
17820
+ };
17821
+ void (async () => {
17822
+ await emitTelemetry("honeycomb_installed", { ref, tier: "tier1" }, telemetryDeps);
17823
+ await recordVersionAndEmitUpdated(ref, telemetryDeps);
17824
+ })();
17527
17825
  return { exitCode: 0 };
17528
17826
  }
17529
17827
 
@@ -17718,9 +18016,9 @@ function createDispatcher() {
17718
18016
 
17719
18017
  // dist/src/cli/runtime.js
17720
18018
  import { spawn } from "node:child_process";
17721
- import { mkdirSync as mkdirSync8, mkdtempSync, rmSync as rmSync2 } from "node:fs";
17722
- import { homedir as homedir13 } from "node:os";
17723
- import { dirname as dirname8, join as join13, resolve as resolve8 } from "node:path";
18019
+ import { mkdirSync as mkdirSync10, mkdtempSync, rmSync as rmSync3 } from "node:fs";
18020
+ import { homedir as homedir15 } from "node:os";
18021
+ import { dirname as dirname9, join as join15, resolve as resolve8 } from "node:path";
17724
18022
  import { fileURLToPath as fileURLToPath3 } from "node:url";
17725
18023
 
17726
18024
  // dist/src/daemon/runtime/auth/deeplake-issuer.js
@@ -18305,7 +18603,7 @@ var SCRYPT_PARAMS = Object.freeze({ N: 16384, r: 8, p: 1, keyLen: 32 });
18305
18603
  var API_KEYS_TARGET = { table: "api_keys", columns: [...API_KEYS_COLUMNS] };
18306
18604
 
18307
18605
  // dist/src/cli/auth.js
18308
- import { existsSync as existsSync6, unlinkSync } from "node:fs";
18606
+ import { existsSync as existsSync7, unlinkSync } from "node:fs";
18309
18607
  function parseAuthArgs(argv) {
18310
18608
  let command = "";
18311
18609
  let token;
@@ -18379,7 +18677,7 @@ function logout(deps) {
18379
18677
  const targets = [credentialsPath(dirArg(deps.dir)), legacyCredentialsPath(deps.legacyDir)];
18380
18678
  let removed = false;
18381
18679
  for (const path of targets) {
18382
- if (!existsSync6(path))
18680
+ if (!existsSync7(path))
18383
18681
  continue;
18384
18682
  try {
18385
18683
  unlinkSync(path);
@@ -18956,8 +19254,8 @@ function buildRealTokenIssuer(env = process.env) {
18956
19254
  }
18957
19255
 
18958
19256
  // dist/src/cli/connector-runner.js
18959
- import { homedir as homedir9 } from "node:os";
18960
- import { dirname as dirname6, join as join9, resolve as resolve5 } from "node:path";
19257
+ import { homedir as homedir11 } from "node:os";
19258
+ import { dirname as dirname7, join as join11, resolve as resolve5 } from "node:path";
18961
19259
  import { fileURLToPath } from "node:url";
18962
19260
 
18963
19261
  // dist/src/connectors/contracts.js
@@ -19681,7 +19979,7 @@ function flatHooks(config2) {
19681
19979
 
19682
19980
  // dist/src/connectors/node-fs.js
19683
19981
  import { mkdir, readFile, rm, stat, symlink as fsSymlink, readlink as fsReadlink, writeFile } from "node:fs/promises";
19684
- import { dirname as dirname5 } from "node:path";
19982
+ import { dirname as dirname6 } from "node:path";
19685
19983
  function isEnoent(err) {
19686
19984
  return err?.code === "ENOENT";
19687
19985
  }
@@ -19701,7 +19999,7 @@ function createNodeConnectorFs() {
19701
19999
  }
19702
20000
  },
19703
20001
  async writeFile(path, contents) {
19704
- await mkdir(dirname5(path), { recursive: true });
20002
+ await mkdir(dirname6(path), { recursive: true });
19705
20003
  await writeFile(path, contents, "utf8");
19706
20004
  },
19707
20005
  async removeFile(path) {
@@ -19727,7 +20025,7 @@ function createNodeConnectorFs() {
19727
20025
  await mkdir(path, { recursive: true });
19728
20026
  },
19729
20027
  async symlink(target, linkPath) {
19730
- await mkdir(dirname5(linkPath), { recursive: true });
20028
+ await mkdir(dirname6(linkPath), { recursive: true });
19731
20029
  try {
19732
20030
  await fsSymlink(target, linkPath);
19733
20031
  } catch (err) {
@@ -19813,13 +20111,13 @@ function packageRoot() {
19813
20111
  if (process.env.HONEYCOMB_PACKAGE_ROOT !== void 0 && process.env.HONEYCOMB_PACKAGE_ROOT.length > 0) {
19814
20112
  return process.env.HONEYCOMB_PACKAGE_ROOT;
19815
20113
  }
19816
- const here = dirname6(fileURLToPath(import.meta.url));
20114
+ const here = dirname7(fileURLToPath(import.meta.url));
19817
20115
  return resolve5(here, "..");
19818
20116
  }
19819
20117
  function bundleSourceFor(slug) {
19820
- return join9(packageRoot(), "harnesses", slug, "bundle");
20118
+ return join11(packageRoot(), "harnesses", slug, "bundle");
19821
20119
  }
19822
- function createConnectorRegistry(home = homedir9()) {
20120
+ function createConnectorRegistry(home = homedir11()) {
19823
20121
  const claudePluginRunner = createClaudePluginRunner();
19824
20122
  const builders = {
19825
20123
  "claude-code": (fs) => new ClaudeCodeConnector(fs, {
@@ -19857,9 +20155,9 @@ function buildConnectorRunner() {
19857
20155
 
19858
20156
  // dist/src/cli/health-probes.js
19859
20157
  import { spawnSync as spawnSync2 } from "node:child_process";
19860
- import { existsSync as existsSync8 } from "node:fs";
19861
- import { homedir as homedir11 } from "node:os";
19862
- import { dirname as dirname7, join as join11, resolve as resolve6 } from "node:path";
20158
+ import { existsSync as existsSync9 } from "node:fs";
20159
+ import { homedir as homedir13 } from "node:os";
20160
+ import { dirname as dirname8, join as join13, resolve as resolve6 } from "node:path";
19863
20161
  import { fileURLToPath as fileURLToPath2 } from "node:url";
19864
20162
 
19865
20163
  // dist/src/notifications/contracts.js
@@ -19932,9 +20230,9 @@ function createHealthCheck(deps) {
19932
20230
  }
19933
20231
 
19934
20232
  // dist/src/notifications/state.js
19935
- import { closeSync, existsSync as existsSync7, mkdirSync as mkdirSync7, openSync, readFileSync as readFileSync9, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "node:fs";
19936
- import { homedir as homedir10 } from "node:os";
19937
- import { join as join10 } from "node:path";
20233
+ import { closeSync, existsSync as existsSync8, mkdirSync as mkdirSync9, openSync, readFileSync as readFileSync10, renameSync as renameSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync8 } from "node:fs";
20234
+ import { homedir as homedir12 } from "node:os";
20235
+ import { join as join12 } from "node:path";
19938
20236
 
19939
20237
  // dist/src/notifications/auto-wiring.js
19940
20238
  function createAutoWiring(deps) {
@@ -19963,15 +20261,15 @@ function probeCursorAgent() {
19963
20261
  }
19964
20262
  }
19965
20263
  function probeCursorLogin() {
19966
- const agentDir = join11(homedir11(), ".cursor");
19967
- return existsSync8(agentDir) ? { ok: false, detail: "cursor present; login state unknown (run `cursor-agent login`)" } : { ok: false, detail: "cursor-agent not configured" };
20264
+ const agentDir = join13(homedir13(), ".cursor");
20265
+ return existsSync9(agentDir) ? { ok: false, detail: "cursor present; login state unknown (run `cursor-agent login`)" } : { ok: false, detail: "cursor-agent not configured" };
19968
20266
  }
19969
20267
  function probeHooksWired(runner) {
19970
20268
  if (runner.isPluginEnabled(CLAUDE_PLUGIN_NAME)) {
19971
20269
  return { ok: true, detail: "Claude Code plugin installed + enabled" };
19972
20270
  }
19973
- const hooksPath = join11(homedir11(), ".cursor", "hooks.json");
19974
- return existsSync8(hooksPath) ? { ok: true, detail: "Cursor hooks.json present" } : { ok: false, detail: "capture not wired (run `honeycomb setup`)" };
20271
+ const hooksPath = join13(homedir13(), ".cursor", "hooks.json");
20272
+ return existsSync9(hooksPath) ? { ok: true, detail: "Cursor hooks.json present" } : { ok: false, detail: "capture not wired (run `honeycomb setup`)" };
19975
20273
  }
19976
20274
  function buildHealthProbes(daemon, pluginRunner = createClaudePluginRunner()) {
19977
20275
  return {
@@ -19996,9 +20294,9 @@ function buildHealthProbes(daemon, pluginRunner = createClaudePluginRunner()) {
19996
20294
  function buildStatusHealthSource(daemon, pluginRunner = createClaudePluginRunner()) {
19997
20295
  const fs = createNodeConnectorFs();
19998
20296
  const claudeConnector = new ClaudeCodeConnector(fs, {
19999
- home: homedir11(),
20000
- bundleSource: join11(homedir11(), ".claude", "honeycomb", "bundle"),
20001
- packageRoot: resolve6(dirname7(fileURLToPath2(import.meta.url)), ".."),
20297
+ home: homedir13(),
20298
+ bundleSource: join13(homedir13(), ".claude", "honeycomb", "bundle"),
20299
+ packageRoot: resolve6(dirname8(fileURLToPath2(import.meta.url)), ".."),
20002
20300
  pluginRunner
20003
20301
  });
20004
20302
  const check2 = createHealthCheck({
@@ -20176,11 +20474,15 @@ async function launchDashboard(options = {}) {
20176
20474
  }
20177
20475
 
20178
20476
  // dist/src/cli/daemon-service.js
20179
- import { createRequire } from "node:module";
20180
- import { homedir as homedir12 } from "node:os";
20181
- import { join as join12, normalize, resolve as resolve7, sep as sep3 } from "node:path";
20182
- var SERVICE_LABEL = "ai.honeycomb.daemon";
20183
- var SERVICE_TASK_NAME = "HoneycombDaemon";
20477
+ import { createRequire as createRequire2 } from "node:module";
20478
+ import { homedir as homedir14 } from "node:os";
20479
+ import { join as join14, normalize, resolve as resolve7, sep as sep3 } from "node:path";
20480
+ var SERVICE_LABEL = "com.legioncode.honeycomb";
20481
+ var SERVICE_SYSTEMD_UNIT = "honeycomb.service";
20482
+ var SERVICE_TASK_NAME = "honeycomb";
20483
+ var LEGACY_SERVICE_LABEL = "ai.honeycomb.daemon";
20484
+ var LEGACY_SERVICE_SYSTEMD_UNIT = "ai.honeycomb.daemon.service";
20485
+ var LEGACY_SERVICE_TASK_NAME = "HoneycombDaemon";
20184
20486
  var SERVICE_MODE_ENV = "HONEYCOMB_DAEMON_SERVICE";
20185
20487
  function detectServiceManager(env = process.env, platform2 = process.platform) {
20186
20488
  if ((env[SERVICE_MODE_ENV] ?? "").trim().toLowerCase() === "spawn")
@@ -20198,7 +20500,7 @@ function detectServiceManager(env = process.env, platform2 = process.platform) {
20198
20500
  return null;
20199
20501
  }
20200
20502
  function defaultServiceRunner() {
20201
- const require2 = createRequire(import.meta.url);
20503
+ const require2 = createRequire2(import.meta.url);
20202
20504
  const cp = require2("node:child_process");
20203
20505
  const fs = require2("node:fs");
20204
20506
  return {
@@ -20212,7 +20514,7 @@ function defaultServiceRunner() {
20212
20514
  return typeof out === "string" ? out.trim() : "";
20213
20515
  },
20214
20516
  writeFile(path, contents) {
20215
- fs.mkdirSync(join12(path, ".."), { recursive: true });
20517
+ fs.mkdirSync(join14(path, ".."), { recursive: true });
20216
20518
  fs.writeFileSync(path, contents, { encoding: "utf8" });
20217
20519
  },
20218
20520
  removeFile(path) {
@@ -20243,7 +20545,13 @@ function launchdPlistPath(home) {
20243
20545
  return containedUnitPath(home, ["Library", "LaunchAgents", `${SERVICE_LABEL}.plist`]);
20244
20546
  }
20245
20547
  function systemdUnitPath(home) {
20246
- return containedUnitPath(home, [".config", "systemd", "user", `${SERVICE_LABEL}.service`]);
20548
+ return containedUnitPath(home, [".config", "systemd", "user", SERVICE_SYSTEMD_UNIT]);
20549
+ }
20550
+ function legacyLaunchdPlistPath(home) {
20551
+ return containedUnitPath(home, ["Library", "LaunchAgents", `${LEGACY_SERVICE_LABEL}.plist`]);
20552
+ }
20553
+ function legacySystemdUnitPath(home) {
20554
+ return containedUnitPath(home, [".config", "systemd", "user", LEGACY_SERVICE_SYSTEMD_UNIT]);
20247
20555
  }
20248
20556
  function xmlEscape(value) {
20249
20557
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -20321,7 +20629,7 @@ function buildSchtasksCreateArgs(spec) {
20321
20629
  ];
20322
20630
  }
20323
20631
  function specHome(spec) {
20324
- return spec.home ?? homedir12();
20632
+ return spec.home ?? homedir14();
20325
20633
  }
20326
20634
  function createDaemonServiceController(manager, runner = defaultServiceRunner()) {
20327
20635
  if (manager === "launchd")
@@ -20337,6 +20645,14 @@ function launchdController(runner) {
20337
20645
  return {
20338
20646
  manager: "launchd",
20339
20647
  register(spec) {
20648
+ try {
20649
+ runner.run("launchctl", ["bootout", `${domain2()}/${LEGACY_SERVICE_LABEL}`]);
20650
+ } catch {
20651
+ }
20652
+ try {
20653
+ runner.removeFile(legacyLaunchdPlistPath(specHome(spec)));
20654
+ } catch {
20655
+ }
20340
20656
  const path = launchdPlistPath(specHome(spec));
20341
20657
  runner.writeFile(path, renderLaunchdPlist(spec));
20342
20658
  runner.run("launchctl", ["bootstrap", domain2(), path]);
@@ -20365,10 +20681,18 @@ function launchdController(runner) {
20365
20681
  };
20366
20682
  }
20367
20683
  function systemdController(runner) {
20368
- const unit = `${SERVICE_LABEL}.service`;
20684
+ const unit = SERVICE_SYSTEMD_UNIT;
20369
20685
  return {
20370
20686
  manager: "systemd-user",
20371
20687
  register(spec) {
20688
+ try {
20689
+ runner.run("systemctl", ["--user", "disable", "--now", LEGACY_SERVICE_SYSTEMD_UNIT]);
20690
+ } catch {
20691
+ }
20692
+ try {
20693
+ runner.removeFile(legacySystemdUnitPath(specHome(spec)));
20694
+ } catch {
20695
+ }
20372
20696
  const path = systemdUnitPath(specHome(spec));
20373
20697
  runner.writeFile(path, renderSystemdUnit(spec));
20374
20698
  runner.run("systemctl", ["--user", "daemon-reload"]);
@@ -20404,6 +20728,14 @@ function schtasksController(runner) {
20404
20728
  return {
20405
20729
  manager: "schtasks",
20406
20730
  register(spec) {
20731
+ try {
20732
+ runner.run("schtasks", ["/End", "/TN", LEGACY_SERVICE_TASK_NAME]);
20733
+ } catch {
20734
+ }
20735
+ try {
20736
+ runner.run("schtasks", ["/Delete", "/TN", LEGACY_SERVICE_TASK_NAME, "/F"]);
20737
+ } catch {
20738
+ }
20407
20739
  runner.run("schtasks", buildSchtasksCreateArgs(spec));
20408
20740
  runner.run("schtasks", ["/Run", "/TN", SERVICE_TASK_NAME]);
20409
20741
  return { ok: true, manager: "schtasks" };
@@ -20468,7 +20800,7 @@ function tenancyHeaders(creds) {
20468
20800
  }
20469
20801
  var DAEMON_NODE_FLAGS = ["--experimental-sqlite"];
20470
20802
  function resolveDaemonEntry() {
20471
- const here = dirname8(fileURLToPath3(import.meta.url));
20803
+ const here = dirname9(fileURLToPath3(import.meta.url));
20472
20804
  const bundledSibling = resolve8(here, "..", "daemon", "index.js");
20473
20805
  const devSibling = resolve8(here, "..", "..", "..", "daemon", "index.js");
20474
20806
  return process.env.HONEYCOMB_DAEMON_ENTRY ?? bundledSibling ?? devSibling;
@@ -20476,7 +20808,7 @@ function resolveDaemonEntry() {
20476
20808
  var DEFAULT_START_TIMEOUT_MS = 45e3;
20477
20809
  var START_POLL_INTERVAL_MS = 150;
20478
20810
  function runtimeDir() {
20479
- return join13(homedir13(), ".honeycomb");
20811
+ return join15(homedir15(), ".honeycomb");
20480
20812
  }
20481
20813
  function resolveDaemonWorkspace() {
20482
20814
  const fromEnv = process.env.HONEYCOMB_WORKSPACE;
@@ -20489,9 +20821,9 @@ function resolveDaemonWorkspace() {
20489
20821
  }
20490
20822
  function canWriteDir(dir) {
20491
20823
  try {
20492
- mkdirSync8(dir, { recursive: true });
20493
- const probe = mkdtempSync(join13(dir, ".hc-spawn-probe-"));
20494
- rmSync2(probe, { recursive: true, force: true });
20824
+ mkdirSync10(dir, { recursive: true });
20825
+ const probe = mkdtempSync(join15(dir, ".hc-spawn-probe-"));
20826
+ rmSync3(probe, { recursive: true, force: true });
20495
20827
  return true;
20496
20828
  } catch {
20497
20829
  return false;
@@ -20500,7 +20832,7 @@ function canWriteDir(dir) {
20500
20832
  async function readDaemonPid() {
20501
20833
  const { readFile: readFile2 } = await import("node:fs/promises");
20502
20834
  try {
20503
- const raw = (await readFile2(join13(runtimeDir(), "daemon.pid"), "utf8")).trim();
20835
+ const raw = (await readFile2(join15(runtimeDir(), "daemon.pid"), "utf8")).trim();
20504
20836
  const pid = Number.parseInt(raw, 10);
20505
20837
  return Number.isInteger(pid) && pid > 0 ? pid : null;
20506
20838
  } catch {