Skip to content

send X-Deeplake-Client: hivemind/<version> on deeplake-api calls#74

Open
kaghni wants to merge 2 commits intomainfrom
deeplake-client-header
Open

send X-Deeplake-Client: hivemind/<version> on deeplake-api calls#74
kaghni wants to merge 2 commits intomainfrom
deeplake-client-header

Conversation

@kaghni
Copy link
Copy Markdown
Collaborator

@kaghni kaghni commented Apr 23, 2026

Summary

  • Adds X-Deeplake-Client: hivemind/<version> header on every outbound request to deeplake-api, so the backend can attribute hivemind traffic for analytics (signup source, login source, daily retention rollup).
  • New src/utils/client-header.ts with a single deeplakeClientHeader() helper. Version is injected at bundle time via an esbuild __HIVEMIND_VERSION__ define (same pattern openclaw already uses for its own version). Dev / tsx / vitest runs fall back to "dev" so nothing crashes without a bundle.
  • Applied at every fetch site: DeepLakeAPI (query + listTables), commands/auth.ts (whoami / orgs / workspaces / device-code / device-token), and both wiki-worker.ts entry points (CC + Codex).
  • Rebuilt claude-code/bundle/ and codex/bundle/ — grep confirms the version literal + header template both land in every shipped bundle.

No PostHog SDK added to hivemind. All analytics stay server-side in deeplake-api (PR activeloopai/deeplake-api#193).

Test plan

  • npm run typecheck clean
  • npm test — all 966 tests pass
  • npm run build produces bundles; grep confirms "0.6.45" + `hivemind/${pluginVersion()}` are present in CC + Codex bundles
  • Runtime intercept-fetch smoke: calling requestDeviceCode() emits the header (confirmed X-Deeplake-Client: hivemind/dev in unbundled dev; bundle path gets hivemind/0.6.45)
  • After merge of deeplake-api#193, end-to-end: hivemind login → PostHog shows login_completed with login_source: hivemind, hivemind_version: 0.6.45
  • After a hivemind session writes to its sessions table, the next 00:05 UTC rollup emits hivemind_daily_active with matching sessions_count

The deeplake-api backend reads X-Deeplake-Client to attribute traffic
for analytics (signup_source, login_source, daily retention rollup).
Without the header, hivemind requests look identical to the generic
cli_device_flow and are invisible in PostHog.

- Add src/utils/client-header.ts with deeplakeClientHeader() using
  a build-time __HIVEMIND_VERSION__ define; dev runs fall back to
  "dev" so tsx/vitest don't crash on the undefined symbol.
- Extend esbuild.config.mjs: define __HIVEMIND_VERSION__ for the CC
  and Codex bundles (openclaw already had an analogous define for
  its own version).
- Apply the header at every outbound fetch site: DeepLakeAPI (query
  + listTables), commands/auth.ts (whoami / orgs / workspaces /
  device-code / device-token), and both wiki-worker.ts entry points.
- Rebuild CC + Codex bundles so the shipped plugin carries the
  version literal baked in.

No PostHog SDK in hivemind; backend does all analytics.
@claude
Copy link
Copy Markdown

claude Bot commented Apr 23, 2026

Claude finished @kaghni's task in 59s —— View job


One inline comment: the try/catch in pluginVersion() is dead code — typeof never throws a ReferenceError in JS, so the catch block is unreachable and the comment is misleading.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Coverage Report

Scope: files changed in this PR. Enforced threshold: 90% per metric (per file via vitest.config.ts).

Status Category Percentage Covered / Total
🔴 Lines 75.42% (🎯 90%) 316 / 419
🔴 Statements 73.40% (🎯 90%) 356 / 485
🔴 Functions 68.60% (🎯 90%) 59 / 86
🔴 Branches 67.80% (🎯 90%) 179 / 264
File Coverage — 5 files changed
File Stmts Branches Functions Lines
src/commands/auth.ts 🔴 0.0% 🔴 0.0% 🔴 0.0% 🔴 0.0%
src/deeplake-api.ts 🟢 98.4% 🟢 91.6% 🟢 97.3% 🟢 99.4%
src/hooks/codex/wiki-worker.ts 🟢 98.8% 🟢 97.1% 🟢 100.0% 🟢 98.7%
src/hooks/wiki-worker.ts 🟢 98.8% 🟢 97.1% 🟢 100.0% 🟢 98.7%
src/utils/client-header.ts 🔴 85.7% 🔴 50.0% 🟢 100.0% 🔴 85.7%

Generated for commit a25e248.

Comment on lines +15 to +20
function pluginVersion(): string {
try {
if (typeof __HIVEMIND_VERSION__ === "string" && __HIVEMIND_VERSION__) {
return __HIVEMIND_VERSION__;
}
} catch { /* reference error in unbundled dev → fall through */ }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try/catch around typeof __HIVEMIND_VERSION__ is unnecessary and the comment is incorrect — typeof never throws a ReferenceError in JavaScript; it specifically returns "undefined" for undeclared identifiers. The catch block will never execute. Drop the try/catch wrapper.

Suggested change
function pluginVersion(): string {
try {
if (typeof __HIVEMIND_VERSION__ === "string" && __HIVEMIND_VERSION__) {
return __HIVEMIND_VERSION__;
}
} catch { /* reference error in unbundled dev → fall through */ }
function pluginVersion(): string {
if (typeof __HIVEMIND_VERSION__ === "string" && __HIVEMIND_VERSION__) {
return __HIVEMIND_VERSION__;
}
return "dev";
}

…tch too

OpenClaw is the same product as hivemind analytics-wise (same install
base per user, same retention story), so it sends the same
"hivemind/<version>" value via the shared helper. Only one outbound
deeplake-api call (POST /users/me/tokens) needed the change; openclaw
already has __HIVEMIND_VERSION__ defined by esbuild so no config
changes.

openclaw/dist/ is gitignored; rebuilds at release time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant