@legioncodeinc/honeycomb 0.1.9 → 0.1.11

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.
@@ -5,13 +5,13 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Honeycomb — persistent memory daemon and thin harness clients for AI coding assistants",
8
- "version": "0.1.9"
8
+ "version": "0.1.11"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "honeycomb",
13
13
  "description": "Honeycomb Claude Code plugin — captures session activity and provides cross-session memory through the local daemon",
14
- "version": "0.1.9",
14
+ "version": "0.1.11",
15
15
  "source": "./harnesses/claude-code"
16
16
  }
17
17
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "honeycomb",
3
3
  "description": "Honeycomb — a long-lived daemon plus thin clients for six coding harnesses, the unified honeycomb CLI, the MCP server, and the embed daemon",
4
- "version": "0.1.9",
4
+ "version": "0.1.11",
5
5
  "author": {
6
6
  "name": "Honeycomb"
7
7
  },
package/README.md CHANGED
@@ -30,7 +30,12 @@
30
30
  </picture>
31
31
  </a>
32
32
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
33
- <a href="https://activeloop.ai"><img src="assets/logos/activeloop-full-mark-logo.svg" alt="Activeloop" height="26"></a>
33
+ <a href="https://activeloop.ai">
34
+ <picture>
35
+ <source media="(prefers-color-scheme: dark)" srcset="assets/logos/activeloop-full-mark-logo-on-dark.svg">
36
+ <img src="assets/logos/activeloop-full-mark-logo.svg" alt="Activeloop" height="26">
37
+ </picture>
38
+ </a>
34
39
  </p>
35
40
 
36
41
  <p align="center"><sub>A <a href="https://github.com/legioncodeinc"><strong>Legion Code</strong></a> &times; <a href="https://activeloop.ai"><strong>Activeloop</strong></a> collaboration · built on <a href="https://github.com/activeloopai/hivemind">Hivemind</a> &amp; <a href="https://deeplake.ai">Deep Lake</a></sub></p>
@@ -88,7 +93,7 @@ curl -fsSL https://get.theapiary.sh | sh
88
93
  irm https://get.theapiary.sh/install.ps1 | iex
89
94
  ```
90
95
 
91
- That single line installs a current Node/npm if missing, installs **`@legioncodeinc/honeycomb`** globally, brings up the daemon on `127.0.0.1:3850`, and opens the dashboard. Then:
96
+ That single line installs a current Node/npm if missing, installs **`@legioncodeinc/honeycomb`** globally, brings up the daemon on `127.0.0.1:3850`, opens the dashboard, and sets up **[HiveDoctor](#-hivedoctor-the-self-healing-watchdog)**, a tiny watchdog that keeps it all healthy (opt out with `--no-hivedoctor`). Then:
92
97
 
93
98
  1. The dashboard loads in a **pre-auth setup state**. No token ever touches your shell.
94
99
  2. Click **"First time setup."** Honeycomb runs the Deep Lake device-flow login *for* you, shows the code right on the page, and opens the verification tab.
@@ -210,6 +215,17 @@ Four ways to reach the same daemon and the same shared memory:
210
215
 
211
216
  ---
212
217
 
218
+ ## 🩺 HiveDoctor: the self-healing watchdog
219
+
220
+ A daemon you cannot see is a daemon you cannot trust. **[HiveDoctor](https://www.npmjs.com/package/@legioncodeinc/hivedoctor)** is a separate, deliberately tiny package (zero runtime dependencies, Node built-ins only) that keeps your Honeycomb daemon healthy and reports home when it cannot. It is supervised by your OS (launchd / systemd / Windows Scheduled Task), so it survives crashes and reboots independently of the daemon it watches.
221
+
222
+ - **Watches and heals.** Probes the daemon's `/health` and runs an escalating repair ladder with exponential backoff: restart, then reinstall, then remove a conflicting Hivemind, then escalate. It goes quiet the moment the daemon is healthy, and it never touches your credentials.
223
+ - **Tells us when it cannot.** An unhealable install surfaces a local status page and, unless you opt out, sends a scrubbed diagnosis home, so problems get fixed proactively instead of becoming a support thread.
224
+ - **Keeps Honeycomb current.** Safely auto-updates the daemon behind a blessed-release gate, verifying health and rolling back on failure.
225
+ - **Honest by default.** Telemetry is opt-out (`DO_NOT_TRACK=1`, `HONEYCOMB_TELEMETRY=0`, or the dashboard) and never includes credentials, tokens, or your code. The one-command installer sets it up automatically; skip it with `--no-hivedoctor`. Full details in the [HiveDoctor README](hivedoctor/README.md).
226
+
227
+ ---
228
+
213
229
  ## 📍 Status & roadmap
214
230
 
215
231
  Honeycomb is **pre-release (v0.1.x)**. We document what's real and flag what's opt-in.
package/bundle/cli.js CHANGED
@@ -5,6 +5,10 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
+ // dist/src/cli/index.js
9
+ import { realpathSync } from "node:fs";
10
+ import { pathToFileURL } from "node:url";
11
+
8
12
  // dist/src/commands/contracts.js
9
13
  var VERB_GROUPS = Object.freeze([
10
14
  { key: "memory", label: "Memory & recall" },
@@ -17258,7 +17262,7 @@ function buildAllowedProperties(input) {
17258
17262
  }
17259
17263
  var systemTelemetryClock = () => (/* @__PURE__ */ new Date()).toISOString();
17260
17264
  var DEFAULT_EMIT_TIMEOUT_MS = 2e3;
17261
- var HONEYCOMB_VERSION = true ? "0.1.9" : "0.0.0-dev";
17265
+ var HONEYCOMB_VERSION = true ? "0.1.11" : "0.0.0-dev";
17262
17266
  async function emitTelemetry(event, opts, deps = {}) {
17263
17267
  const env = deps.env ?? process.env;
17264
17268
  const key = deps.posthogKey ?? POSTHOG_KEY;
@@ -17401,7 +17405,7 @@ function renderGlassBoxText(view) {
17401
17405
  // dist/src/shared/constants.js
17402
17406
  var DAEMON_PORT = 3850;
17403
17407
  var DAEMON_HOST = "127.0.0.1";
17404
- var HONEYCOMB_VERSION2 = true ? "0.1.9" : "0.0.0-dev";
17408
+ var HONEYCOMB_VERSION2 = true ? "0.1.11" : "0.0.0-dev";
17405
17409
  var PRODUCT_SLUG = "honeycomb";
17406
17410
 
17407
17411
  // dist/src/commands/install.js
@@ -20439,8 +20443,18 @@ function schtasksController(runner) {
20439
20443
  }
20440
20444
 
20441
20445
  // dist/src/cli/runtime.js
20446
+ function daemonHost() {
20447
+ const raw = process.env.HONEYCOMB_HOST?.trim();
20448
+ if (raw === "127.0.0.1" || raw === "localhost")
20449
+ return raw;
20450
+ return DAEMON_HOST;
20451
+ }
20452
+ function daemonPort() {
20453
+ const raw = Number.parseInt(process.env.HONEYCOMB_PORT ?? "", 10);
20454
+ return Number.isInteger(raw) && raw > 0 && raw <= 65535 ? raw : DAEMON_PORT;
20455
+ }
20442
20456
  function daemonBaseUrl2() {
20443
- return `http://${DAEMON_HOST}:${DAEMON_PORT}`;
20457
+ return `http://${daemonHost()}:${daemonPort()}`;
20444
20458
  }
20445
20459
  function tenancyHeaders(creds) {
20446
20460
  if (creds === null)
@@ -20606,9 +20620,9 @@ function buildDaemonLifecycle(client, options = {}) {
20606
20620
  }
20607
20621
  }
20608
20622
  if (running) {
20609
- return serviceManager !== void 0 ? { running, pid, port: DAEMON_PORT, serviceManager } : { running, pid, port: DAEMON_PORT };
20623
+ return serviceManager !== void 0 ? { running, pid, port: daemonPort(), serviceManager } : { running, pid, port: daemonPort() };
20610
20624
  }
20611
- return serviceManager !== void 0 ? { running: false, port: DAEMON_PORT, serviceManager } : { running: false, port: DAEMON_PORT };
20625
+ return serviceManager !== void 0 ? { running: false, port: daemonPort(), serviceManager } : { running: false, port: daemonPort() };
20612
20626
  },
20613
20627
  async restart() {
20614
20628
  const svc = serviceController();
@@ -20736,7 +20750,18 @@ async function main(argv = process.argv.slice(2)) {
20736
20750
  const result = await dispatcher.dispatch(inv, deps);
20737
20751
  return result.exitCode;
20738
20752
  }
20739
- if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("cli.js")) {
20753
+ function isCliEntry(importMetaUrl, argv1) {
20754
+ if (typeof argv1 !== "string" || argv1.length === 0)
20755
+ return false;
20756
+ try {
20757
+ if (importMetaUrl === pathToFileURL(argv1).href)
20758
+ return true;
20759
+ return importMetaUrl === pathToFileURL(realpathSync(argv1)).href;
20760
+ } catch {
20761
+ return false;
20762
+ }
20763
+ }
20764
+ if (isCliEntry(import.meta.url, process.argv[1])) {
20740
20765
  main().then(async (code) => {
20741
20766
  await finalizeCliExit();
20742
20767
  process.exitCode = code;
@@ -20748,5 +20773,6 @@ if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith
20748
20773
  });
20749
20774
  }
20750
20775
  export {
20776
+ isCliEntry,
20751
20777
  main
20752
20778
  };