@legioncodeinc/honeycomb 0.1.9 → 0.1.10

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.10"
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.10",
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.10",
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.10" : "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.10" : "0.0.0-dev";
17405
17409
  var PRODUCT_SLUG = "honeycomb";
17406
17410
 
17407
17411
  // dist/src/commands/install.js
@@ -20736,7 +20740,18 @@ async function main(argv = process.argv.slice(2)) {
20736
20740
  const result = await dispatcher.dispatch(inv, deps);
20737
20741
  return result.exitCode;
20738
20742
  }
20739
- if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("cli.js")) {
20743
+ function isCliEntry(importMetaUrl, argv1) {
20744
+ if (typeof argv1 !== "string" || argv1.length === 0)
20745
+ return false;
20746
+ try {
20747
+ if (importMetaUrl === pathToFileURL(argv1).href)
20748
+ return true;
20749
+ return importMetaUrl === pathToFileURL(realpathSync(argv1)).href;
20750
+ } catch {
20751
+ return false;
20752
+ }
20753
+ }
20754
+ if (isCliEntry(import.meta.url, process.argv[1])) {
20740
20755
  main().then(async (code) => {
20741
20756
  await finalizeCliExit();
20742
20757
  process.exitCode = code;
@@ -20748,5 +20763,6 @@ if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith
20748
20763
  });
20749
20764
  }
20750
20765
  export {
20766
+ isCliEntry,
20751
20767
  main
20752
20768
  };
package/daemon/index.js CHANGED
@@ -7369,7 +7369,7 @@ var require_dist = __commonJS({
7369
7369
  // dist/src/shared/constants.js
7370
7370
  var DAEMON_PORT = 3850;
7371
7371
  var DAEMON_HOST = "127.0.0.1";
7372
- var HONEYCOMB_VERSION = true ? "0.1.9" : "0.0.0-dev";
7372
+ var HONEYCOMB_VERSION = true ? "0.1.10" : "0.0.0-dev";
7373
7373
 
7374
7374
  // node_modules/zod/v4/classic/external.js
7375
7375
  var external_exports = {};
@@ -25690,6 +25690,14 @@ var SESSIONS_COLUMNS = Object.freeze([
25690
25690
  { name: "output_tokens", sql: "BIGINT" },
25691
25691
  { name: "cache_read_input_tokens", sql: "BIGINT" },
25692
25692
  { name: "cache_creation_input_tokens", sql: "BIGINT" },
25693
+ // ── PRD-060 ROI fix: the per-turn MODEL id ────────────────────────────────────
25694
+ // The model the turn ran on (e.g. `claude-opus-4-8`), read from the Claude Code
25695
+ // transcript so the ROI dashboard prices the turn at its REAL model's rate instead of
25696
+ // the Sonnet default (`rowToCapturedTurn` reads this; `resolveRate` does the rest).
25697
+ // Additive, healed in via the SAME `ALTER TABLE ADD COLUMN … DEFAULT ''` path as the
25698
+ // 060a columns. TEXT NOT NULL DEFAULT '' — heal-safe on a populated legacy table because
25699
+ // the empty string backfills, and `'' = "model unknown"` (the model-absent encoding).
25700
+ { name: "model", sql: "TEXT NOT NULL DEFAULT ''" },
25693
25701
  // The capture-source discriminant (a-AC-7): every Claude-Code row carries
25694
25702
  // `source_tool = 'claude-code'`, so 060b/060e can render a "Claude Code only"
25695
25703
  // partial state. NOT NULL DEFAULT '' (a discriminant always present; '' = unknown
@@ -28182,7 +28190,7 @@ function coarsePipelineStatus(storage) {
28182
28190
  }
28183
28191
 
28184
28192
  // dist/src/daemon/runtime/assemble.js
28185
- import { mkdirSync as mkdirSync20, mkdtempSync, readFileSync as readFileSync22, rmSync as rmSync10, writeFileSync as writeFileSync17 } from "node:fs";
28193
+ import { mkdirSync as mkdirSync20, mkdtempSync, readFileSync as readFileSync23, rmSync as rmSync10, writeFileSync as writeFileSync17 } from "node:fs";
28186
28194
  import { homedir as homedir25 } from "node:os";
28187
28195
  import { join as join32 } from "node:path";
28188
28196
 
@@ -28610,7 +28618,7 @@ function buildAllowedProperties(input) {
28610
28618
  }
28611
28619
  var systemTelemetryClock = () => (/* @__PURE__ */ new Date()).toISOString();
28612
28620
  var DEFAULT_EMIT_TIMEOUT_MS = 2e3;
28613
- var HONEYCOMB_VERSION2 = true ? "0.1.9" : "0.0.0-dev";
28621
+ var HONEYCOMB_VERSION2 = true ? "0.1.10" : "0.0.0-dev";
28614
28622
  async function emitTelemetry(event, opts, deps = {}) {
28615
28623
  const env = deps.env ?? process.env;
28616
28624
  const key = deps.posthogKey ?? POSTHOG_KEY;
@@ -31210,7 +31218,13 @@ var AssistantMessageEventSchema = external_exports.object({
31210
31218
  kind: external_exports.literal("assistant_message"),
31211
31219
  text: external_exports.string(),
31212
31220
  /** PRD-060a: optional per-turn token + cache counts; absent when unavailable. */
31213
- usage: TurnUsageSchema
31221
+ usage: TurnUsageSchema,
31222
+ /**
31223
+ * PRD-060 ROI fix: the optional per-turn model id. A blank/whitespace value is treated as
31224
+ * ABSENT (transformed to `undefined`) so an empty string is never persisted — the column
31225
+ * stays `''` = "model unknown" rather than carrying a meaningless empty model.
31226
+ */
31227
+ model: external_exports.string().optional().transform((m) => m !== void 0 && m.trim() !== "" ? m.trim() : void 0)
31214
31228
  });
31215
31229
  var CaptureEventSchema = external_exports.discriminatedUnion("kind", [
31216
31230
  UserMessageEventSchema,
@@ -31648,6 +31662,11 @@ var CaptureRouteHandler = class {
31648
31662
  // canonical harness token the shim stamps (`claude-code` for the reference
31649
31663
  // shim), so every Claude-Code-captured row carries `source_tool='claude-code'`.
31650
31664
  ["source_tool", val.str(meta3.agent)],
31665
+ // PRD-060 ROI fix: the per-turn model id (e.g. `claude-opus-4-8`) read from the
31666
+ // transcript, so the dashboard prices the turn at its real model's rate. An absent
31667
+ // model writes `''` ("model unknown" — the column default); a present model writes the
31668
+ // id via the typed `val.str` SQL guard. Carried on the SAME append-only INSERT.
31669
+ ["model", val.str(modelFor(event))],
31651
31670
  ["creation_date", val.str(nowIso10)],
31652
31671
  ["last_update_date", val.str(nowIso10)]
31653
31672
  ];
@@ -31812,6 +31831,9 @@ function usageColumns(event) {
31812
31831
  cols.push(["cache_creation_input_tokens", u.cacheCreation]);
31813
31832
  return cols;
31814
31833
  }
31834
+ function modelFor(event) {
31835
+ return event.kind === "assistant_message" && event.model !== void 0 ? event.model : "";
31836
+ }
31815
31837
  function groupRowsByScope(batch) {
31816
31838
  const byKey = /* @__PURE__ */ new Map();
31817
31839
  for (const item of batch) {
@@ -36399,11 +36421,15 @@ function tokenCountOrNull(value) {
36399
36421
  }
36400
36422
  function rowToCapturedTurn(r) {
36401
36423
  const sourceTool = toStr2(r.source_tool);
36424
+ const model = toStr2(r.model);
36425
+ const isAnthropic = sourceTool === "claude-code" || model.startsWith("claude-");
36402
36426
  return {
36403
36427
  input_tokens: tokenCountOrNull(r.input_tokens),
36404
36428
  output_tokens: tokenCountOrNull(r.output_tokens),
36405
36429
  cache_read_input_tokens: tokenCountOrNull(r.cache_read_input_tokens),
36406
36430
  cache_creation_input_tokens: tokenCountOrNull(r.cache_creation_input_tokens),
36431
+ ...model !== "" ? { model } : {},
36432
+ ...model !== "" && isAnthropic ? { provider: "anthropic" } : {},
36407
36433
  ...sourceTool !== "" ? { sourceTool } : {}
36408
36434
  };
36409
36435
  }
@@ -36413,7 +36439,7 @@ async function readCapturedTurns(storage, scope, projectId) {
36413
36439
  const dateCol = sqlIdent("creation_date");
36414
36440
  const idCol = sqlIdent("id");
36415
36441
  const projClause = projectWhereClause(projectId);
36416
- const sql = `SELECT ${sqlIdent("input_tokens")}, ${sqlIdent("output_tokens")}, ${sqlIdent("cache_read_input_tokens")}, ${sqlIdent("cache_creation_input_tokens")}, ${sqlIdent("source_tool")} FROM "${tbl}"${projClause} ORDER BY ${dateCol} DESC, ${idCol} DESC LIMIT ${ROI_SESSIONS_LIMIT}`;
36442
+ const sql = `SELECT ${sqlIdent("input_tokens")}, ${sqlIdent("output_tokens")}, ${sqlIdent("cache_read_input_tokens")}, ${sqlIdent("cache_creation_input_tokens")}, ${sqlIdent("source_tool")}, ${sqlIdent("model")} FROM "${tbl}"${projClause} ORDER BY ${dateCol} DESC, ${idCol} DESC LIMIT ${ROI_SESSIONS_LIMIT}`;
36417
36443
  const rows = await selectRows2(storage, sql, scope);
36418
36444
  return rows.map(rowToCapturedTurn);
36419
36445
  }
@@ -37502,12 +37528,14 @@ function nestedString(raw2, a, b) {
37502
37528
  function userMessageData(text) {
37503
37529
  return { kind: "user_message", text };
37504
37530
  }
37505
- function assistantMessageData(text, usage) {
37531
+ function assistantMessageData(text, usage, model) {
37506
37532
  const normalized = usage !== void 0 ? compactUsage(usage) : void 0;
37533
+ const trimmedModel = typeof model === "string" ? model.trim() : "";
37507
37534
  return {
37508
37535
  kind: "assistant_message",
37509
37536
  text,
37510
- ...normalized !== void 0 ? { usage: normalized } : {}
37537
+ ...normalized !== void 0 ? { usage: normalized } : {},
37538
+ ...trimmedModel !== "" ? { model: trimmedModel } : {}
37511
37539
  };
37512
37540
  }
37513
37541
  function compactUsage(usage) {
@@ -37577,6 +37605,112 @@ function preToolData(tool, fields) {
37577
37605
  };
37578
37606
  }
37579
37607
 
37608
+ // dist/src/hooks/claude-code/transcript.js
37609
+ import { readFileSync as readFileSync16 } from "node:fs";
37610
+ function parseTurnUsage(jsonlText) {
37611
+ const entries = parseEntries(jsonlText);
37612
+ let lastUserIndex = -1;
37613
+ for (let i = 0; i < entries.length; i++) {
37614
+ if (entryType(entries[i]) === "user")
37615
+ lastUserIndex = i;
37616
+ }
37617
+ const totals = new TurnTotals();
37618
+ let lastModel;
37619
+ let sawAssistant = false;
37620
+ for (let i = lastUserIndex + 1; i < entries.length; i++) {
37621
+ const entry = entries[i];
37622
+ if (entryType(entry) !== "assistant")
37623
+ continue;
37624
+ sawAssistant = true;
37625
+ totals.add(messageOf(entry));
37626
+ const model = modelOf(entry);
37627
+ if (model !== void 0)
37628
+ lastModel = model;
37629
+ }
37630
+ if (!sawAssistant)
37631
+ return {};
37632
+ const usage = totals.toUsage();
37633
+ return {
37634
+ ...lastModel !== void 0 ? { model: lastModel } : {},
37635
+ ...usage !== void 0 ? { usage } : {}
37636
+ };
37637
+ }
37638
+ function readTranscriptTurnUsage(transcriptPath2) {
37639
+ if (transcriptPath2.length === 0)
37640
+ return {};
37641
+ let text;
37642
+ try {
37643
+ text = readFileSync16(transcriptPath2, "utf8");
37644
+ } catch {
37645
+ return {};
37646
+ }
37647
+ return parseTurnUsage(text);
37648
+ }
37649
+ function parseEntries(jsonlText) {
37650
+ const out = [];
37651
+ for (const line of jsonlText.split("\n")) {
37652
+ const trimmed = line.trim();
37653
+ if (trimmed.length === 0)
37654
+ continue;
37655
+ let parsed;
37656
+ try {
37657
+ parsed = JSON.parse(trimmed);
37658
+ } catch {
37659
+ continue;
37660
+ }
37661
+ if (parsed !== null && typeof parsed === "object")
37662
+ out.push(parsed);
37663
+ }
37664
+ return out;
37665
+ }
37666
+ function entryType(entry) {
37667
+ return typeof entry.type === "string" ? entry.type : "";
37668
+ }
37669
+ function messageOf(entry) {
37670
+ const message = entry.message;
37671
+ return message !== null && typeof message === "object" ? message : {};
37672
+ }
37673
+ function modelOf(entry) {
37674
+ const model = messageOf(entry).model;
37675
+ return typeof model === "string" && model.length > 0 ? model : void 0;
37676
+ }
37677
+ var TurnTotals = class {
37678
+ input;
37679
+ output;
37680
+ cacheRead;
37681
+ cacheCreation;
37682
+ /** Fold one assistant `message.usage` block's counts into the running totals (absent counts skipped). */
37683
+ add(message) {
37684
+ const usage = message.usage;
37685
+ const block = usage !== null && typeof usage === "object" ? usage : {};
37686
+ this.input = addCount(this.input, readCount2(block, "input_tokens"));
37687
+ this.output = addCount(this.output, readCount2(block, "output_tokens"));
37688
+ this.cacheRead = addCount(this.cacheRead, readCount2(block, "cache_read_input_tokens"));
37689
+ this.cacheCreation = addCount(this.cacheCreation, readCount2(block, "cache_creation_input_tokens"));
37690
+ }
37691
+ /** Compact the totals into a {@link NormalizedTurnUsage}, or `undefined` when every bucket stayed absent. */
37692
+ toUsage() {
37693
+ const usage = {
37694
+ ...this.input !== void 0 ? { input: this.input } : {},
37695
+ ...this.output !== void 0 ? { output: this.output } : {},
37696
+ ...this.cacheRead !== void 0 ? { cacheRead: this.cacheRead } : {},
37697
+ ...this.cacheCreation !== void 0 ? { cacheCreation: this.cacheCreation } : {}
37698
+ };
37699
+ return Object.keys(usage).length > 0 ? usage : void 0;
37700
+ }
37701
+ };
37702
+ function addCount(running, addend) {
37703
+ if (addend === void 0)
37704
+ return running;
37705
+ return (running ?? 0) + addend;
37706
+ }
37707
+ function readCount2(block, key) {
37708
+ const value = block[key];
37709
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0)
37710
+ return void 0;
37711
+ return value;
37712
+ }
37713
+
37580
37714
  // dist/src/hooks/claude-code/shim.js
37581
37715
  var CLAUDE_CODE_EVENT_MAP = {
37582
37716
  SessionStart: "session-start",
@@ -37591,7 +37725,7 @@ var CLAUDE_CODE_CONTEXT_CHANNEL = "model-only";
37591
37725
  var CLAUDE_CODE_RUNTIME_PATH = "legacy";
37592
37726
  var CLAUDE_CODE_HOST_CLI = { bin: "claude", args: ["-p"] };
37593
37727
  var CLAUDE_CODE_REFERENCES = "references/claude-code/";
37594
- function claudeCodeExtractData(raw2, logical) {
37728
+ function claudeCodeExtractData(raw2, logical, meta3) {
37595
37729
  switch (logical) {
37596
37730
  case "session-start":
37597
37731
  return sessionStartData(pickString(raw2, "source") || "startup");
@@ -37605,8 +37739,11 @@ function claudeCodeExtractData(raw2, logical) {
37605
37739
  });
37606
37740
  case "tool_call":
37607
37741
  return toolCallData(pickString(raw2, "tool_name", "tool"), nested(raw2, "tool_input"), nested(raw2, "tool_response"));
37608
- case "assistant_message":
37609
- return assistantMessageData(pickString(raw2, "text", "message"), extractTurnUsage(raw2));
37742
+ case "assistant_message": {
37743
+ const fromTranscript = readTranscriptTurnUsage(meta3.path ?? "");
37744
+ const usage = fromTranscript.usage ?? extractTurnUsage(raw2);
37745
+ return assistantMessageData(pickString(raw2, "text", "message"), usage, fromTranscript.model);
37746
+ }
37610
37747
  case "session-end":
37611
37748
  return sessionEndData(pickString(raw2, "reason") || "Stop");
37612
37749
  default:
@@ -37621,9 +37758,8 @@ function createClaudeCodeShim() {
37621
37758
  hostCli: CLAUDE_CODE_HOST_CLI,
37622
37759
  references: CLAUDE_CODE_REFERENCES,
37623
37760
  eventMap: CLAUDE_CODE_EVENT_MAP,
37624
- extractData(raw2, logical, _meta) {
37625
- void _meta;
37626
- return claudeCodeExtractData(raw2, logical);
37761
+ extractData(raw2, logical, meta3) {
37762
+ return claudeCodeExtractData(raw2, logical, meta3);
37627
37763
  }
37628
37764
  });
37629
37765
  }
@@ -38659,7 +38795,7 @@ async function tableAbsent(probe, table) {
38659
38795
  }
38660
38796
 
38661
38797
  // dist/src/daemon/runtime/dashboard/asset-install-target.js
38662
- import { existsSync as existsSync13, mkdirSync as mkdirSync14, readFileSync as readFileSync16, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "node:fs";
38798
+ import { existsSync as existsSync13, mkdirSync as mkdirSync14, readFileSync as readFileSync17, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "node:fs";
38663
38799
  import { homedir as homedir17 } from "node:os";
38664
38800
  import { join as join21 } from "node:path";
38665
38801
  var SKILLS_SUBDIR = join21(".claude", "skills");
@@ -38695,7 +38831,7 @@ function createFsAssetInstallTarget(dirs = {}) {
38695
38831
  const { file: file2 } = pathFor(assetType, install, name);
38696
38832
  if (!existsSync13(file2))
38697
38833
  return null;
38698
- return readFileSync16(file2, "utf-8");
38834
+ return readFileSync17(file2, "utf-8");
38699
38835
  } catch {
38700
38836
  return null;
38701
38837
  }
@@ -39098,7 +39234,7 @@ function pickAssetType(value) {
39098
39234
  }
39099
39235
 
39100
39236
  // dist/src/daemon/runtime/dashboard/web-assets.js
39101
- import { existsSync as existsSync14, readFileSync as readFileSync17 } from "node:fs";
39237
+ import { existsSync as existsSync14, readFileSync as readFileSync18 } from "node:fs";
39102
39238
  import { dirname as dirname13, join as join22 } from "node:path";
39103
39239
  import { fileURLToPath as fileURLToPath2 } from "node:url";
39104
39240
  var CSS_FILES = ["tokens/fonts.css", "tokens/colors.css", "tokens/typography.css", "tokens/spacing.css", "tokens/base.css"];
@@ -39148,7 +39284,7 @@ function resolveBundleDir(startUrl = import.meta.url) {
39148
39284
  }
39149
39285
  function readSoft(path4) {
39150
39286
  try {
39151
- return existsSync14(path4) ? readFileSync17(path4, "utf-8") : null;
39287
+ return existsSync14(path4) ? readFileSync18(path4, "utf-8") : null;
39152
39288
  } catch {
39153
39289
  return null;
39154
39290
  }
@@ -39157,7 +39293,7 @@ function readBinarySoft(path4) {
39157
39293
  try {
39158
39294
  if (!existsSync14(path4))
39159
39295
  return null;
39160
- const buf = readFileSync17(path4);
39296
+ const buf = readFileSync18(path4);
39161
39297
  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
39162
39298
  } catch {
39163
39299
  return null;
@@ -48534,7 +48670,7 @@ function buildSourcesApiDeps(options) {
48534
48670
  // dist/src/daemon/runtime/secrets/store.js
48535
48671
  import { execFileSync as execFileSync6 } from "node:child_process";
48536
48672
  import { randomBytes as randomBytes5 } from "node:crypto";
48537
- import { appendFileSync, existsSync as existsSync18, mkdirSync as mkdirSync16, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as rmSync8, statSync as statSync3, writeFileSync as writeFileSync13 } from "node:fs";
48673
+ import { appendFileSync, existsSync as existsSync18, mkdirSync as mkdirSync16, readdirSync as readdirSync4, readFileSync as readFileSync19, rmSync as rmSync8, statSync as statSync3, writeFileSync as writeFileSync13 } from "node:fs";
48538
48674
  import { homedir as homedir21 } from "node:os";
48539
48675
  import { join as join27 } from "node:path";
48540
48676
 
@@ -49271,7 +49407,7 @@ function readOsMachineId() {
49271
49407
  if (process.platform === "linux") {
49272
49408
  for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
49273
49409
  if (existsSync18(p)) {
49274
- const id = readFileSync18(p, "utf8").trim();
49410
+ const id = readFileSync19(p, "utf8").trim();
49275
49411
  if (id.length > 0)
49276
49412
  return id;
49277
49413
  }
@@ -49306,7 +49442,7 @@ function readOrCreateFallbackKey(homeDir) {
49306
49442
  const dir = join27(homeDir, MACHINE_KEY_DIR_NAME);
49307
49443
  const file2 = machineKeyFilePath(homeDir);
49308
49444
  if (existsSync18(file2)) {
49309
- const hex4 = readFileSync18(file2, "utf8").trim();
49445
+ const hex4 = readFileSync19(file2, "utf8").trim();
49310
49446
  if (hex4.length > 0)
49311
49447
  return hex4;
49312
49448
  }
@@ -49437,7 +49573,7 @@ var SecretsStore = class {
49437
49573
  }
49438
49574
  let record2;
49439
49575
  try {
49440
- const parsed = JSON.parse(readFileSync18(file2, "utf8"));
49576
+ const parsed = JSON.parse(readFileSync19(file2, "utf8"));
49441
49577
  if (!isSecretRecord(parsed)) {
49442
49578
  this.audit("resolved_for_exec", scope, "error", safe);
49443
49579
  return { ok: false, reason: "io_error" };
@@ -49527,7 +49663,7 @@ function stripRefWrapper(ref) {
49527
49663
  }
49528
49664
 
49529
49665
  // dist/src/daemon/runtime/vault/store.js
49530
- import { appendFileSync as appendFileSync2, existsSync as existsSync19, mkdirSync as mkdirSync17, readdirSync as readdirSync5, readFileSync as readFileSync19, rmSync as rmSync9, writeFileSync as writeFileSync14 } from "node:fs";
49666
+ import { appendFileSync as appendFileSync2, existsSync as existsSync19, mkdirSync as mkdirSync17, readdirSync as readdirSync5, readFileSync as readFileSync20, rmSync as rmSync9, writeFileSync as writeFileSync14 } from "node:fs";
49531
49667
  import { join as join28 } from "node:path";
49532
49668
  var VAULT_DIR_NAME = ".vault";
49533
49669
  var VAULT_AUDIT_FILE_NAME = "vault-audit.ndjson";
@@ -49729,7 +49865,7 @@ var VaultStore = class {
49729
49865
  }
49730
49866
  let record2;
49731
49867
  try {
49732
- const parsed = JSON.parse(readFileSync19(file2, "utf8"));
49868
+ const parsed = JSON.parse(readFileSync20(file2, "utf8"));
49733
49869
  if (!isSecretRecord(parsed)) {
49734
49870
  this.audit(klass, op, scope, "error", safe);
49735
49871
  return { ok: false, reason: "io_error" };
@@ -52976,7 +53112,7 @@ import { homedir as homedir24 } from "node:os";
52976
53112
  import { join as join31 } from "node:path";
52977
53113
 
52978
53114
  // dist/src/daemon/runtime/skillify/install-target.js
52979
- import { mkdirSync as mkdirSync18, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
53115
+ import { mkdirSync as mkdirSync18, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
52980
53116
  import { homedir as homedir22 } from "node:os";
52981
53117
  import { join as join29 } from "node:path";
52982
53118
  var SKILLS_SUBDIR2 = join29(".claude", "skills");
@@ -52995,7 +53131,7 @@ function createFsInstallTarget(dirs = {}) {
52995
53131
  },
52996
53132
  async read(install, name) {
52997
53133
  try {
52998
- return readFileSync20(fileFor(install, name), "utf-8");
53134
+ return readFileSync21(fileFor(install, name), "utf-8");
52999
53135
  } catch {
53000
53136
  return null;
53001
53137
  }
@@ -53008,7 +53144,7 @@ function sanitizeSegment4(name) {
53008
53144
  }
53009
53145
 
53010
53146
  // dist/src/daemon/runtime/skillify/watermark.js
53011
- import { mkdirSync as mkdirSync19, readFileSync as readFileSync21, writeFileSync as writeFileSync16 } from "node:fs";
53147
+ import { mkdirSync as mkdirSync19, readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "node:fs";
53012
53148
  import { homedir as homedir23 } from "node:os";
53013
53149
  import { dirname as dirname14, join as join30 } from "node:path";
53014
53150
  function defaultWatermarkBaseDir() {
@@ -53018,7 +53154,7 @@ function createWatermarkStore(baseDir = defaultWatermarkBaseDir()) {
53018
53154
  const fileFor = (projectKey) => join30(baseDir, sanitizeSegment5(projectKey), "watermark.json");
53019
53155
  const read = (projectKey) => {
53020
53156
  try {
53021
- const raw2 = readFileSync21(fileFor(projectKey), "utf-8");
53157
+ const raw2 = readFileSync22(fileFor(projectKey), "utf-8");
53022
53158
  const parsed = JSON.parse(raw2);
53023
53159
  return typeof parsed.watermark === "string" && parsed.watermark !== "" ? parsed.watermark : null;
53024
53160
  } catch {
@@ -53075,18 +53211,22 @@ function tokenCountOrNull2(value) {
53075
53211
  }
53076
53212
  function rowToCapturedTurn2(r) {
53077
53213
  const sourceTool = typeof r.source_tool === "string" ? r.source_tool : "";
53214
+ const model = typeof r.model === "string" ? r.model : "";
53215
+ const provider = sourceTool === "claude-code" || model.startsWith("claude-") ? "anthropic" : void 0;
53078
53216
  return {
53079
53217
  input_tokens: tokenCountOrNull2(r.input_tokens),
53080
53218
  output_tokens: tokenCountOrNull2(r.output_tokens),
53081
53219
  cache_read_input_tokens: tokenCountOrNull2(r.cache_read_input_tokens),
53082
53220
  cache_creation_input_tokens: tokenCountOrNull2(r.cache_creation_input_tokens),
53083
- ...sourceTool !== "" ? { sourceTool } : {}
53221
+ ...sourceTool !== "" ? { sourceTool } : {},
53222
+ ...model !== "" ? { model } : {},
53223
+ ...provider !== void 0 ? { provider } : {}
53084
53224
  };
53085
53225
  }
53086
53226
  async function readSessionTurns(storage, scope, path4) {
53087
53227
  const tbl = sqlIdent("sessions");
53088
53228
  const pathCol = sqlIdent("path");
53089
- const sql = `SELECT ${sqlIdent("input_tokens")}, ${sqlIdent("output_tokens")}, ${sqlIdent("cache_read_input_tokens")}, ${sqlIdent("cache_creation_input_tokens")}, ${sqlIdent("source_tool")} FROM "${tbl}" WHERE ${pathCol} = ${sLiteral(path4)} LIMIT ${SESSION_TURNS_LIMIT}`;
53229
+ const sql = `SELECT ${sqlIdent("input_tokens")}, ${sqlIdent("output_tokens")}, ${sqlIdent("cache_read_input_tokens")}, ${sqlIdent("cache_creation_input_tokens")}, ${sqlIdent("source_tool")}, ${sqlIdent("model")} FROM "${tbl}" WHERE ${pathCol} = ${sLiteral(path4)} LIMIT ${SESSION_TURNS_LIMIT}`;
53090
53230
  let result;
53091
53231
  try {
53092
53232
  result = await storage.query(sql, scope);
@@ -53863,7 +54003,7 @@ function acquireSingleInstanceLock(runtimeDir) {
53863
54003
  }
53864
54004
  function readPidFile(path4) {
53865
54005
  try {
53866
- const raw2 = readFileSync22(path4, "utf8").trim();
54006
+ const raw2 = readFileSync23(path4, "utf8").trim();
53867
54007
  if (raw2.length === 0)
53868
54008
  return null;
53869
54009
  const pid = Number.parseInt(raw2, 10);
@@ -2,7 +2,7 @@
2
2
  import { createServer } from "node:http";
3
3
 
4
4
  // dist/src/shared/constants.js
5
- var HONEYCOMB_VERSION = true ? "0.1.9" : "0.0.0-dev";
5
+ var HONEYCOMB_VERSION = true ? "0.1.10" : "0.0.0-dev";
6
6
 
7
7
  // dist/embeddings/src/index.js
8
8
  var EMBED_DIMS = 768;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "honeycomb",
3
3
  "description": "Honeycomb — persistent memory for Claude Code sessions via the local Honeycomb daemon",
4
- "version": "0.1.9",
4
+ "version": "0.1.10",
5
5
  "author": {
6
6
  "name": "Honeycomb"
7
7
  },