@legioncodeinc/nectar 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE.md +662 -662
  2. package/README.md +307 -307
  3. package/dist/brooding/describe.js +13 -13
  4. package/dist/cli.js +26 -26
  5. package/dist/service/templates.js +80 -80
  6. package/dist/telemetry/checkin.js +6 -6
  7. package/dist/telemetry/db.js +21 -21
  8. package/dist/telemetry/metrics.js +8 -8
  9. package/dist/telemetry-usage/posthog-key.js +4 -22
  10. package/package.json +48 -44
  11. package/dist/embeddings/cohere-portkey.d.ts +0 -67
  12. package/dist/embeddings/cohere-portkey.d.ts.map +0 -1
  13. package/dist/embeddings/cohere-portkey.js +0 -171
  14. package/dist/embeddings/cohere-portkey.js.map +0 -1
  15. package/dist/hivedoctor-registry.d.ts +0 -111
  16. package/dist/hivedoctor-registry.d.ts.map +0 -1
  17. package/dist/hivedoctor-registry.js +0 -143
  18. package/dist/hivedoctor-registry.js.map +0 -1
  19. package/dist/source-graph/deeplake-credentials.d.ts +0 -57
  20. package/dist/source-graph/deeplake-credentials.d.ts.map +0 -1
  21. package/dist/source-graph/deeplake-credentials.js +0 -109
  22. package/dist/source-graph/deeplake-credentials.js.map +0 -1
  23. package/dist/source-graph/deeplake-heal.d.ts +0 -53
  24. package/dist/source-graph/deeplake-heal.d.ts.map +0 -1
  25. package/dist/source-graph/deeplake-heal.js +0 -41
  26. package/dist/source-graph/deeplake-heal.js.map +0 -1
  27. package/dist/source-graph/deeplake-store.d.ts +0 -151
  28. package/dist/source-graph/deeplake-store.d.ts.map +0 -1
  29. package/dist/source-graph/deeplake-store.js +0 -389
  30. package/dist/source-graph/deeplake-store.js.map +0 -1
  31. package/dist/source-graph/deeplake-transport.d.ts +0 -74
  32. package/dist/source-graph/deeplake-transport.d.ts.map +0 -1
  33. package/dist/source-graph/deeplake-transport.js +0 -107
  34. package/dist/source-graph/deeplake-transport.js.map +0 -1
  35. package/dist/source-graph/hash.d.ts +0 -3
  36. package/dist/source-graph/hash.d.ts.map +0 -1
  37. package/dist/source-graph/hash.js +0 -12
  38. package/dist/source-graph/hash.js.map +0 -1
  39. package/dist/source-graph/memory-store.d.ts +0 -32
  40. package/dist/source-graph/memory-store.d.ts.map +0 -1
  41. package/dist/source-graph/memory-store.js +0 -81
  42. package/dist/source-graph/memory-store.js.map +0 -1
  43. package/dist/source-graph/model.d.ts +0 -102
  44. package/dist/source-graph/model.d.ts.map +0 -1
  45. package/dist/source-graph/model.js +0 -36
  46. package/dist/source-graph/model.js.map +0 -1
  47. package/dist/source-graph/paths.d.ts +0 -7
  48. package/dist/source-graph/paths.d.ts.map +0 -1
  49. package/dist/source-graph/paths.js +0 -26
  50. package/dist/source-graph/paths.js.map +0 -1
  51. package/dist/source-graph/schema.d.ts +0 -44
  52. package/dist/source-graph/schema.d.ts.map +0 -1
  53. package/dist/source-graph/schema.js +0 -123
  54. package/dist/source-graph/schema.js.map +0 -1
  55. package/dist/source-graph/sql-guards.d.ts +0 -99
  56. package/dist/source-graph/sql-guards.d.ts.map +0 -1
  57. package/dist/source-graph/sql-guards.js +0 -129
  58. package/dist/source-graph/sql-guards.js.map +0 -1
  59. package/dist/source-graph/store.d.ts +0 -101
  60. package/dist/source-graph/store.d.ts.map +0 -1
  61. package/dist/source-graph/store.js +0 -2
  62. package/dist/source-graph/store.js.map +0 -1
  63. package/dist/source-graph/ulid.d.ts +0 -9
  64. package/dist/source-graph/ulid.d.ts.map +0 -1
  65. package/dist/source-graph/ulid.js +0 -61
  66. package/dist/source-graph/ulid.js.map +0 -1
@@ -1,171 +0,0 @@
1
- /**
2
- * The Cohere-via-Portkey embeddings transport (PRD-014b — the operator opt-in).
3
- *
4
- * Modeled on honeycomb's shipped Cohere-rerank-via-Portkey transport
5
- * (`honeycomb/src/daemon/runtime/recall/rerank-portkey.ts`): it reuses the SAME
6
- * `x-portkey-api-key` + `x-portkey-config` auth pair (via
7
- * {@link buildPortkeyHeaders}) and the SAME gateway host; the ONE difference is
8
- * the path — `/v1/embeddings` ({@link PORTKEY_EMBEDDINGS_URL}) instead of
9
- * `/v1/rerank` — and the request/response shape.
10
- *
11
- * ── Model + dimension are config, not hardcoded (decision #30) ───────────────
12
- * The opt-in targets Cohere `embed-v4.0` with `output_dimension: 768` so it
13
- * produces contract-valid 768-dim vectors instead of guard-discarded 1024-dim
14
- * ones. Both the model id and the output dimension are config values
15
- * ({@link CohereEmbeddingsConfig}); recall's 768-dim guard (`guard.ts`) stays as
16
- * the backstop for whatever the gateway actually returns.
17
- *
18
- * ── Fail-soft is the cardinal rule (AC-4 / US-014b.3) ────────────────────────
19
- * EVERY failure path — Portkey not keyed, a network/transport error, a non-2xx
20
- * gateway status, or a malformed body — resolves to `null` for the affected
21
- * texts, NEVER a throw into the caller's hot path. A bounded retry covers 429 +
22
- * transient 5xx (the same statuses the sibling chat transport retries); the
23
- * bound is exhausted to nulls rather than thrown.
24
- *
25
- * ── The secret-never-logged invariant (US-014b.3) ────────────────────────────
26
- * The resolved key is placed ONLY in the `x-portkey-api-key` header (via
27
- * {@link buildPortkeyHeaders}) and is NEVER included in a returned value, a log
28
- * line, or an error. On any failure the response body is not read into a message
29
- * (it could echo a credential).
30
- */
31
- import { buildPortkeyHeaders, PORTKEY_EMBEDDINGS_URL } from "../portkey/headers.js";
32
- import { defaultFetch, defaultSleep } from "./http.js";
33
- /** SIGNED OFF 2026-07-02 (decision #30): the Cohere embed model the opt-in targets. Config-overridable. */
34
- export const DEFAULT_COHERE_EMBED_MODEL = "embed-v4.0";
35
- /**
36
- * SIGNED OFF 2026-07-02 (decision #30): the requested output dimension. 768 keeps
37
- * the opt-in on the fixed 768-dim contract; the guard discards anything else.
38
- * Config-overridable. (Cohere's documented Matryoshka set for embed-v4.0 is
39
- * [256, 512, 1024, 1536]; if the gateway ignores 768 the guard degrades to BM25.
40
- * See the module report.)
41
- */
42
- export const DEFAULT_COHERE_OUTPUT_DIMENSION = 768;
43
- /** HTTP statuses that trigger a bounded retry (429 rate limit + transient 5xx), matching the chat transport. */
44
- export const COHERE_RETRYABLE_STATUSES = new Set([429, 500, 502, 503, 504]);
45
- /** Maximum attempts including the first POST (mirrors `src/portkey/transport.ts`'s `PORTKEY_MAX_ATTEMPTS`). */
46
- export const DEFAULT_COHERE_MAX_ATTEMPTS = 3;
47
- /** Backoff between retryable failures in ms (mirrors `src/portkey/transport.ts`'s backoff). */
48
- export const DEFAULT_COHERE_RETRY_BACKOFF_MS = 250;
49
- /**
50
- * Per-attempt request timeout (ms), mirroring `deeplake-transport.ts`'s
51
- * `DEFAULT_TRANSPORT_TIMEOUT_MS` AbortController pattern: an unresponsive gateway
52
- * aborts rather than hanging the embed path indefinitely (fail-soft, AC-4).
53
- */
54
- export const DEFAULT_COHERE_REQUEST_TIMEOUT_MS = 15_000;
55
- /** All-nulls result of length `n` (the fail-soft shape, built in one place). */
56
- function allNull(n) {
57
- return new Array(n).fill(null);
58
- }
59
- /**
60
- * Parse the embeddings response into one vector (or `null`) per input index,
61
- * defensively. Primary shape is Portkey's OpenAI-compatible
62
- * `{ data: [{ embedding: number[], index }] }`; a Cohere-native
63
- * `{ embeddings: number[][] }` or `{ embeddings: { float: number[][] } }` body is
64
- * tolerated as a fallback. Anything else yields all-nulls. Never throws. The
65
- * per-vector dimension is NOT checked here — the guard owns that (AC-3).
66
- */
67
- export function parseEmbeddingsResponse(raw, count) {
68
- let body;
69
- try {
70
- body = raw.length > 0 ? JSON.parse(raw) : null;
71
- }
72
- catch {
73
- return allNull(count);
74
- }
75
- if (typeof body !== "object" || body === null)
76
- return allNull(count);
77
- const out = allNull(count);
78
- const asFinite = (v) => Array.isArray(v) && v.every((n) => typeof n === "number" && Number.isFinite(n)) ? v : null;
79
- // Primary: OpenAI-compatible `data: [{ embedding, index }]`.
80
- const data = body.data;
81
- if (Array.isArray(data)) {
82
- data.forEach((entry, i) => {
83
- if (typeof entry !== "object" || entry === null)
84
- return;
85
- const e = entry;
86
- const idx = typeof e.index === "number" && Number.isInteger(e.index) ? e.index : i;
87
- if (idx < 0 || idx >= count)
88
- return;
89
- out[idx] = asFinite(e.embedding);
90
- });
91
- return out;
92
- }
93
- // Fallback: Cohere-native `embeddings: number[][]` or `embeddings: { float: number[][] }`.
94
- const embeddings = body.embeddings;
95
- const rows = Array.isArray(embeddings)
96
- ? embeddings
97
- : typeof embeddings === "object" && embeddings !== null && Array.isArray(embeddings.float)
98
- ? (embeddings.float)
99
- : null;
100
- if (rows !== null) {
101
- rows.forEach((row, i) => {
102
- if (i < count)
103
- out[i] = asFinite(row);
104
- });
105
- return out;
106
- }
107
- return allNull(count);
108
- }
109
- /**
110
- * Build the Cohere-via-Portkey embeddings {@link EmbedProvider} (PRD-014b). A
111
- * batch is sent as ONE POST reusing the rerank transport's auth pattern; the body
112
- * carries the config model id + `output_dimension` (AC-2). Every failure resolves
113
- * to nulls for the batch (fail-soft, AC-4); the key is never logged or thrown.
114
- */
115
- export function createCoherePortkeyProvider(config, deps = {}) {
116
- const doFetch = deps.fetch ?? defaultFetch();
117
- const sleep = deps.sleep ?? defaultSleep;
118
- return {
119
- kind: "cohere",
120
- async embed(texts) {
121
- if (texts.length === 0)
122
- return [];
123
- // Not keyed -> fail soft to nulls (no POST). A missing key is a misconfiguration, not a crash (AC-4).
124
- if (config.apiKey === null || config.configId === null)
125
- return allNull(texts.length);
126
- const headers = buildPortkeyHeaders(config.apiKey, config.configId);
127
- // The embeddings body (decision #30): the config model id + `output_dimension`, both overridable (AC-2).
128
- const body = JSON.stringify({
129
- model: config.model,
130
- input: [...texts],
131
- output_dimension: config.outputDimension,
132
- });
133
- for (let attempt = 1; attempt <= config.maxAttempts; attempt++) {
134
- let res;
135
- const controller = new AbortController();
136
- const timer = setTimeout(() => controller.abort(), config.requestTimeoutMs);
137
- try {
138
- res = await doFetch(config.url, { method: "POST", headers, body, signal: controller.signal });
139
- }
140
- catch {
141
- // Network/transport failure, or our own abort on `requestTimeoutMs` (an unresponsive
142
- // gateway) -> retry within the bound, else fail soft to nulls. Never surface the error
143
- // (it could carry a body/key); only the fail-soft nulls escape.
144
- if (attempt < config.maxAttempts) {
145
- await sleep(config.retryBackoffMs * attempt);
146
- continue;
147
- }
148
- return allNull(texts.length);
149
- }
150
- finally {
151
- clearTimeout(timer);
152
- }
153
- if (!res.ok) {
154
- // A non-2xx gateway status: retry the retryable ones within the bound, else fail soft. Never
155
- // read the body into a message (it could echo a credential).
156
- if (attempt < config.maxAttempts && COHERE_RETRYABLE_STATUSES.has(res.status)) {
157
- await sleep(config.retryBackoffMs * attempt);
158
- continue;
159
- }
160
- return allNull(texts.length);
161
- }
162
- // A 2xx: parse defensively. A malformed body fails soft to nulls (the gateway was reachable,
163
- // the body was just unusable) rather than throwing.
164
- const text = await res.text().catch(() => "");
165
- return parseEmbeddingsResponse(text, texts.length);
166
- }
167
- return allNull(texts.length);
168
- },
169
- };
170
- }
171
- //# sourceMappingURL=cohere-portkey.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cohere-portkey.js","sourceRoot":"","sources":["../../src/embeddings/cohere-portkey.ts"],"names":[],"mappings":"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"}
@@ -1,111 +0,0 @@
1
- /**
2
- * hivenectar's registry entry in hivedoctor's daemon registry (PRD-003c).
3
- *
4
- * hivenectar becomes a supervised daemon by appending ONE entry to hivedoctor's
5
- * registry file (`~/.honeycomb/hivedoctor.daemons.json`, the schema PRD-004a
6
- * specifies, mirrored read-side in `hivedoctor/src/registry.ts`). That entry
7
- * carries hivenectar's `healthUrl`, `pidPath`, `probeIntervalMs`, `startupGraceMs`,
8
- * and restart thresholds. At the next hivedoctor boot, hivedoctor reads the
9
- * registry and spawns one supervisor instance for hivenectar alongside honeycomb
10
- * and thehive.
11
- *
12
- * Registration is a FILE EDIT at install time (PRD-003c "Registration mechanics"),
13
- * never a runtime call: this module does not restart hivedoctor, does not open an
14
- * HTTP connection, and does not hot-reload anything. It is idempotent - re-running
15
- * the installer replaces hivenectar's own entry (keyed by `name: "hivenectar"`)
16
- * rather than appending a duplicate, and every other daemon's entry is preserved
17
- * byte-for-byte apart from array position.
18
- *
19
- * A PRESENT-but-malformed registry file fails loudly (this module never silently
20
- * clobbers a broken file it cannot safely parse), mirroring hivedoctor's own
21
- * fail-loud posture for a malformed registry (`hivedoctor/src/registry.ts`).
22
- * PRD-017a deliberately does NOT change this posture to match hivedoctor's own
23
- * fail-soft posture for a malformed registry read - the two are intentionally
24
- * different (this writer refuses to clobber a broken install-time file; a
25
- * malformed registry read is hivedoctor's own runtime concern, not this one).
26
- *
27
- * PRD-017a extends this entry with `telemetryDbPath`: the absolute path to
28
- * hivenectar's runtime telemetry SQLite database (`telemetry/db.ts`,
29
- * `~/.honeycomb/telemetry/hivenectar.sqlite` by default), per hivedoctor's
30
- * `ADR-0002-service-registration-static-registry-plus-runtime-sqlite.md`. It is
31
- * derived from `config.pidFilePath`'s directory (the same resolved runtime dir
32
- * `healthUrl`/`pidPath` already come from), so a test-overridden runtime dir
33
- * (`HIVENECTAR_RUNTIME_DIR` / `resolveConfig({ runtimeDir })`) keeps every
34
- * per-daemon artifact - pid, lock, and now telemetry DB - colocated, with no
35
- * separate `~` round-trip needed here (same rationale as `healthUrl`/`pidPath`).
36
- *
37
- * Built-ins only: node:fs, node:os, node:path.
38
- */
39
- import type { RuntimeConfig } from "./config.js";
40
- /** The daemon name hivenectar registers itself under. */
41
- export declare const HIVENECTAR_DAEMON_NAME: "hivenectar";
42
- /**
43
- * One registry entry, matching the schema hivedoctor's registry loader parses
44
- * (PRD-004a / `hivedoctor/src/registry.ts`).
45
- */
46
- export interface HivedoctorRegistryEntry {
47
- readonly name: string;
48
- readonly healthUrl: string;
49
- readonly pidPath: string;
50
- readonly probeIntervalMs: number;
51
- readonly startupGraceMs: number;
52
- readonly restartGiveUpThreshold: number;
53
- readonly restartCooldownMs: number;
54
- /**
55
- * The absolute path to hivenectar's runtime telemetry SQLite database
56
- * (PRD-017a), so hivedoctor knows where to poll (read-only) for check-in
57
- * status, metrics, and logs. Optional in the type only so a pre-PRD-017
58
- * entry a test constructs by hand still type-checks; `buildHivenectarRegistryEntry`
59
- * always populates it.
60
- */
61
- readonly telemetryDbPath?: string;
62
- }
63
- /** hivedoctor's per-daemon defaults hivenectar's entry resolves to (PRD-003c table). */
64
- export declare const DEFAULT_PROBE_INTERVAL_MS = 30000;
65
- export declare const DEFAULT_STARTUP_GRACE_MS = 60000;
66
- export declare const DEFAULT_RESTART_GIVE_UP_THRESHOLD = 3;
67
- export declare const DEFAULT_RESTART_COOLDOWN_MS = 5000;
68
- /** Thrown when a PRESENT registry file cannot be safely parsed/edited. */
69
- export declare class HivedoctorRegistryError extends Error {
70
- constructor(message: string);
71
- }
72
- /** The default registry file location, alongside the other `~/.honeycomb` artifacts. */
73
- export declare function defaultHivedoctorRegistryPath(home?: string): string;
74
- /**
75
- * Build hivenectar's registry entry from its resolved {@link RuntimeConfig}
76
- * (PRD-003c table): `healthUrl`/`pidPath` come from hivenectar's own runtime
77
- * config (already home-expanded, so no `~` round-trip is needed here); the
78
- * remaining fields are hivedoctor's per-daemon defaults unless overridden.
79
- *
80
- * `telemetryDbPath` (PRD-017a) defaults to `<runtimeDir>/telemetry/hivenectar.sqlite`,
81
- * where `runtimeDir` is `pidFilePath`'s own directory - the same resolved
82
- * runtime dir every other per-daemon artifact already lives under, so a
83
- * test-overridden runtime dir keeps pid/lock/telemetry colocated automatically.
84
- */
85
- export declare function buildHivenectarRegistryEntry(config: Pick<RuntimeConfig, "host" | "port" | "pidFilePath">, overrides?: Partial<Pick<HivedoctorRegistryEntry, "probeIntervalMs" | "startupGraceMs" | "restartGiveUpThreshold" | "restartCooldownMs" | "telemetryDbPath">>): HivedoctorRegistryEntry;
86
- export interface RegisterWithHivedoctorOptions {
87
- /** hivenectar's runtime config (supplies healthUrl + pidPath). */
88
- readonly config: Pick<RuntimeConfig, "host" | "port" | "pidFilePath">;
89
- /** Override the registry file path (default: {@link defaultHivedoctorRegistryPath}). */
90
- readonly registryPath?: string;
91
- /** Override the entry's per-daemon fields (default: hivedoctor's built-in defaults). */
92
- readonly overrides?: Partial<Pick<HivedoctorRegistryEntry, "probeIntervalMs" | "startupGraceMs" | "restartGiveUpThreshold" | "restartCooldownMs" | "telemetryDbPath">>;
93
- }
94
- export interface RegisterWithHivedoctorResult {
95
- /** The path the registry file was written to. */
96
- readonly registryPath: string;
97
- /** The entry that was written for hivenectar. */
98
- readonly entry: HivedoctorRegistryEntry;
99
- /** True when the registry file did not exist and was created fresh. */
100
- readonly created: boolean;
101
- /** True when an existing hivenectar entry was replaced (idempotent re-install). */
102
- readonly replaced: boolean;
103
- }
104
- /**
105
- * Append (or idempotently replace) hivenectar's entry in hivedoctor's registry
106
- * file (PRD-003c US-003c.1). Every OTHER daemon's entry is preserved unchanged.
107
- * Does NOT restart hivedoctor and does NOT touch anything besides this one file -
108
- * the entry takes effect at hivedoctor's next natural boot (PRD-003c Non-Goals).
109
- */
110
- export declare function registerWithHivedoctor(options: RegisterWithHivedoctorOptions): RegisterWithHivedoctorResult;
111
- //# sourceMappingURL=hivedoctor-registry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hivedoctor-registry.d.ts","sourceRoot":"","sources":["../src/hivedoctor-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,EAAG,YAAqB,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAChD,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,iCAAiC,IAAI,CAAC;AACnD,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD,0EAA0E;AAC1E,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAED,wFAAwF;AACxF,wBAAgB,6BAA6B,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC,EAC5D,SAAS,GAAE,OAAO,CAChB,IAAI,CACF,uBAAuB,EACvB,iBAAiB,GAAG,gBAAgB,GAAG,wBAAwB,GAAG,mBAAmB,GAAG,iBAAiB,CAC1G,CACG,GACL,uBAAuB,CAYzB;AA0DD,MAAM,WAAW,6BAA6B;IAC5C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC;IACtE,wFAAwF;IACxF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAC1B,IAAI,CACF,uBAAuB,EACvB,iBAAiB,GAAG,gBAAgB,GAAG,wBAAwB,GAAG,mBAAmB,GAAG,iBAAiB,CAC1G,CACF,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,iDAAiD;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,6BAA6B,GACrC,4BAA4B,CAa9B"}
@@ -1,143 +0,0 @@
1
- /**
2
- * hivenectar's registry entry in hivedoctor's daemon registry (PRD-003c).
3
- *
4
- * hivenectar becomes a supervised daemon by appending ONE entry to hivedoctor's
5
- * registry file (`~/.honeycomb/hivedoctor.daemons.json`, the schema PRD-004a
6
- * specifies, mirrored read-side in `hivedoctor/src/registry.ts`). That entry
7
- * carries hivenectar's `healthUrl`, `pidPath`, `probeIntervalMs`, `startupGraceMs`,
8
- * and restart thresholds. At the next hivedoctor boot, hivedoctor reads the
9
- * registry and spawns one supervisor instance for hivenectar alongside honeycomb
10
- * and thehive.
11
- *
12
- * Registration is a FILE EDIT at install time (PRD-003c "Registration mechanics"),
13
- * never a runtime call: this module does not restart hivedoctor, does not open an
14
- * HTTP connection, and does not hot-reload anything. It is idempotent - re-running
15
- * the installer replaces hivenectar's own entry (keyed by `name: "hivenectar"`)
16
- * rather than appending a duplicate, and every other daemon's entry is preserved
17
- * byte-for-byte apart from array position.
18
- *
19
- * A PRESENT-but-malformed registry file fails loudly (this module never silently
20
- * clobbers a broken file it cannot safely parse), mirroring hivedoctor's own
21
- * fail-loud posture for a malformed registry (`hivedoctor/src/registry.ts`).
22
- * PRD-017a deliberately does NOT change this posture to match hivedoctor's own
23
- * fail-soft posture for a malformed registry read - the two are intentionally
24
- * different (this writer refuses to clobber a broken install-time file; a
25
- * malformed registry read is hivedoctor's own runtime concern, not this one).
26
- *
27
- * PRD-017a extends this entry with `telemetryDbPath`: the absolute path to
28
- * hivenectar's runtime telemetry SQLite database (`telemetry/db.ts`,
29
- * `~/.honeycomb/telemetry/hivenectar.sqlite` by default), per hivedoctor's
30
- * `ADR-0002-service-registration-static-registry-plus-runtime-sqlite.md`. It is
31
- * derived from `config.pidFilePath`'s directory (the same resolved runtime dir
32
- * `healthUrl`/`pidPath` already come from), so a test-overridden runtime dir
33
- * (`HIVENECTAR_RUNTIME_DIR` / `resolveConfig({ runtimeDir })`) keeps every
34
- * per-daemon artifact - pid, lock, and now telemetry DB - colocated, with no
35
- * separate `~` round-trip needed here (same rationale as `healthUrl`/`pidPath`).
36
- *
37
- * Built-ins only: node:fs, node:os, node:path.
38
- */
39
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
40
- import { homedir } from "node:os";
41
- import { dirname, join } from "node:path";
42
- import { TELEMETRY_DB_FILE_NAME, TELEMETRY_DIR_NAME } from "./telemetry/db.js";
43
- /** The daemon name hivenectar registers itself under. */
44
- export const HIVENECTAR_DAEMON_NAME = "hivenectar";
45
- /** hivedoctor's per-daemon defaults hivenectar's entry resolves to (PRD-003c table). */
46
- export const DEFAULT_PROBE_INTERVAL_MS = 30_000;
47
- export const DEFAULT_STARTUP_GRACE_MS = 60_000;
48
- export const DEFAULT_RESTART_GIVE_UP_THRESHOLD = 3;
49
- export const DEFAULT_RESTART_COOLDOWN_MS = 5_000;
50
- /** Thrown when a PRESENT registry file cannot be safely parsed/edited. */
51
- export class HivedoctorRegistryError extends Error {
52
- constructor(message) {
53
- super(message);
54
- this.name = "HivedoctorRegistryError";
55
- }
56
- }
57
- /** The default registry file location, alongside the other `~/.honeycomb` artifacts. */
58
- export function defaultHivedoctorRegistryPath(home = homedir()) {
59
- return join(home, ".honeycomb", "hivedoctor.daemons.json");
60
- }
61
- /**
62
- * Build hivenectar's registry entry from its resolved {@link RuntimeConfig}
63
- * (PRD-003c table): `healthUrl`/`pidPath` come from hivenectar's own runtime
64
- * config (already home-expanded, so no `~` round-trip is needed here); the
65
- * remaining fields are hivedoctor's per-daemon defaults unless overridden.
66
- *
67
- * `telemetryDbPath` (PRD-017a) defaults to `<runtimeDir>/telemetry/hivenectar.sqlite`,
68
- * where `runtimeDir` is `pidFilePath`'s own directory - the same resolved
69
- * runtime dir every other per-daemon artifact already lives under, so a
70
- * test-overridden runtime dir keeps pid/lock/telemetry colocated automatically.
71
- */
72
- export function buildHivenectarRegistryEntry(config, overrides = {}) {
73
- const runtimeDir = dirname(config.pidFilePath);
74
- return {
75
- name: HIVENECTAR_DAEMON_NAME,
76
- healthUrl: `http://${config.host}:${config.port}/health`,
77
- pidPath: config.pidFilePath,
78
- probeIntervalMs: overrides.probeIntervalMs ?? DEFAULT_PROBE_INTERVAL_MS,
79
- startupGraceMs: overrides.startupGraceMs ?? DEFAULT_STARTUP_GRACE_MS,
80
- restartGiveUpThreshold: overrides.restartGiveUpThreshold ?? DEFAULT_RESTART_GIVE_UP_THRESHOLD,
81
- restartCooldownMs: overrides.restartCooldownMs ?? DEFAULT_RESTART_COOLDOWN_MS,
82
- telemetryDbPath: overrides.telemetryDbPath ?? join(runtimeDir, TELEMETRY_DIR_NAME, TELEMETRY_DB_FILE_NAME),
83
- };
84
- }
85
- function isRecord(value) {
86
- return value !== null && typeof value === "object";
87
- }
88
- /**
89
- * Read the registry file's raw `daemons` array. A PRESENT-but-malformed file
90
- * (unparseable JSON, not an object, or a `daemons` field that is not an array)
91
- * throws {@link HivedoctorRegistryError} rather than being silently overwritten -
92
- * a real misconfiguration must not be clobbered by an installer.
93
- */
94
- function readExistingRegistry(registryPath) {
95
- let contents;
96
- try {
97
- contents = readFileSync(registryPath, "utf8");
98
- }
99
- catch (error) {
100
- if (error.code === "ENOENT")
101
- return { fileExisted: false, daemons: [] };
102
- throw new HivedoctorRegistryError(`could not read the hivedoctor registry at ${registryPath}: ${error instanceof Error ? error.message : "unknown"}`);
103
- }
104
- let parsed;
105
- try {
106
- parsed = JSON.parse(contents);
107
- }
108
- catch (error) {
109
- throw new HivedoctorRegistryError(`the hivedoctor registry at ${registryPath} is not valid JSON: ${error instanceof Error ? error.message : "unknown"}`);
110
- }
111
- if (!isRecord(parsed)) {
112
- throw new HivedoctorRegistryError(`the hivedoctor registry at ${registryPath} must be a JSON object with a "daemons" array`);
113
- }
114
- const daemons = parsed.daemons;
115
- if (daemons === undefined)
116
- return { fileExisted: true, daemons: [] };
117
- if (!Array.isArray(daemons)) {
118
- throw new HivedoctorRegistryError(`the hivedoctor registry at ${registryPath} has a non-array "daemons" field`);
119
- }
120
- return { fileExisted: true, daemons };
121
- }
122
- /** True iff a raw (unvalidated) registry entry names hivenectar. */
123
- function isHivenectarEntry(raw) {
124
- return isRecord(raw) && raw.name === HIVENECTAR_DAEMON_NAME;
125
- }
126
- /**
127
- * Append (or idempotently replace) hivenectar's entry in hivedoctor's registry
128
- * file (PRD-003c US-003c.1). Every OTHER daemon's entry is preserved unchanged.
129
- * Does NOT restart hivedoctor and does NOT touch anything besides this one file -
130
- * the entry takes effect at hivedoctor's next natural boot (PRD-003c Non-Goals).
131
- */
132
- export function registerWithHivedoctor(options) {
133
- const registryPath = options.registryPath ?? defaultHivedoctorRegistryPath();
134
- const entry = buildHivenectarRegistryEntry(options.config, options.overrides);
135
- const { fileExisted, daemons: existing } = readExistingRegistry(registryPath);
136
- const replaced = existing.some(isHivenectarEntry);
137
- const kept = existing.filter((raw) => !isHivenectarEntry(raw));
138
- const daemons = [...kept, entry];
139
- mkdirSync(dirname(registryPath), { recursive: true });
140
- writeFileSync(registryPath, `${JSON.stringify({ daemons }, null, 2)}\n`, "utf8");
141
- return { registryPath, entry, created: !fileExisted, replaced };
142
- }
143
- //# sourceMappingURL=hivedoctor-registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hivedoctor-registry.js","sourceRoot":"","sources":["../src/hivedoctor-registry.ts"],"names":[],"mappings":"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"}
@@ -1,57 +0,0 @@
1
- /** The SHARED credentials directory name under the user's home. */
2
- export declare const CREDENTIALS_DIR_NAME = ".deeplake";
3
- /** The credentials file name within the dir. */
4
- export declare const CREDENTIALS_FILE_NAME = "credentials.json";
5
- /** The canonical Deep Lake API base URL used when a file omits `apiUrl`. */
6
- export declare const DEFAULT_DEEPLAKE_API_URL = "https://api.deeplake.ai";
7
- /** The validated Deep Lake connection details the transport is built from. */
8
- export interface DeepLakeCredentials {
9
- /** Deep Lake HTTP query endpoint. Defaults to {@link DEFAULT_DEEPLAKE_API_URL}. */
10
- readonly apiUrl: string;
11
- /** The org-bound bearer token (SECRET; never logged in full). */
12
- readonly token: string;
13
- /** The org id the token is bound to. */
14
- readonly orgId: string;
15
- /** The active workspace id. */
16
- readonly workspaceId: string;
17
- }
18
- /**
19
- * Options for {@link loadDeepLakeCredentials}, injectable so a test points the
20
- * file read at a temp dir without touching the real `~/.deeplake` (mirrors
21
- * honeycomb's `CredentialsFileProviderOptions`). All optional.
22
- */
23
- export interface LoadCredentialsOptions {
24
- /** Override the credentials directory (tests). Defaults to `~/.deeplake`. */
25
- readonly dir?: string;
26
- }
27
- /**
28
- * Structured, fail-closed rejection. Carries exactly which fields were missing
29
- * or invalid so a caller (or an operator reading a log line) knows what to
30
- * fix without the loader ever echoing the file's contents (which may hold the
31
- * token).
32
- */
33
- export declare class DeepLakeCredentialsError extends Error {
34
- readonly missing: readonly string[];
35
- constructor(missing: readonly string[]);
36
- }
37
- /** Resolve the credentials directory, honoring the test override. */
38
- export declare function credentialsDir(options?: LoadCredentialsOptions): string;
39
- /** Resolve the full credentials file path within the (possibly overridden) dir. */
40
- export declare function credentialsPath(options?: LoadCredentialsOptions): string;
41
- /**
42
- * Load and validate `~/.deeplake/credentials.json` (or the overridden dir in
43
- * `options.dir`). Throws {@link DeepLakeCredentialsError} listing every
44
- * problem found: a missing file, invalid JSON, a non-object payload, or a
45
- * missing/empty `token` / `orgId` / `workspaceId`. Never returns a partial
46
- * credential — the caller either gets a fully-populated `DeepLakeCredentials`
47
- * or a clear, typed reason it could not.
48
- */
49
- export declare function loadDeepLakeCredentials(options?: LoadCredentialsOptions): DeepLakeCredentials;
50
- /**
51
- * Redact a token for logs and errors. Never echoes a token in full: keeps the
52
- * last 4 chars for correlation, masks the rest. An empty/short value collapses
53
- * to a fixed mask so length isn't leaked either. Mirrors honeycomb's
54
- * `redactToken` (`src/daemon/runtime/auth/credentials-store.ts:254-257`).
55
- */
56
- export declare function redactToken(value: string): string;
57
- //# sourceMappingURL=deeplake-credentials.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deeplake-credentials.d.ts","sourceRoot":"","sources":["../../src/source-graph/deeplake-credentials.ts"],"names":[],"mappings":"AA4BA,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAChD,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AACxD,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAElE,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;gBACxB,OAAO,EAAE,SAAS,MAAM,EAAE;CAKvC;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAE3E;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,sBAA2B,GAAG,mBAAmB,CAkCjG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD"}
@@ -1,109 +0,0 @@
1
- /**
2
- * Deep Lake credentials loader for hivenectar (PRD-005).
3
- *
4
- * Reads the SHARED `~/.deeplake/credentials.json` file that `hivemind login`
5
- * (and honeycomb) already write, mirroring the shape honeycomb's
6
- * `loadDiskCredentials` / `deeplakeCredentialsFileProvider`
7
- * (`src/daemon/runtime/auth/credentials-store.ts`,
8
- * `src/daemon/storage/config.ts`) read: `{ apiUrl, token, orgId, workspaceId }`.
9
- * Per ADR-0002, hivenectar never imports honeycomb's runtime for this; it
10
- * reads the same on-disk file with its own loader.
11
- *
12
- * Fail-closed by design (mirrors honeycomb's `StorageConfigError` posture): a
13
- * missing file, malformed JSON, or a missing required field throws a
14
- * `DeepLakeCredentialsError` listing exactly what is wrong, rather than
15
- * returning a partially-undefined credential object a caller could
16
- * accidentally use. `apiUrl` is the one field with a documented default (a
17
- * legacy or hand-written file may omit it); `token`, `orgId`, and
18
- * `workspaceId` are load-bearing and always required.
19
- *
20
- * The token is never logged or included in an error message in full;
21
- * `redactToken` keeps only the last 4 characters, exactly like honeycomb's
22
- * `redactToken` (`src/daemon/runtime/auth/credentials-store.ts:254-257`, its
23
- * `defaultCredentialProvider` variant).
24
- */
25
- import { existsSync, readFileSync } from "node:fs";
26
- import { homedir } from "node:os";
27
- import { join } from "node:path";
28
- /** The SHARED credentials directory name under the user's home. */
29
- export const CREDENTIALS_DIR_NAME = ".deeplake";
30
- /** The credentials file name within the dir. */
31
- export const CREDENTIALS_FILE_NAME = "credentials.json";
32
- /** The canonical Deep Lake API base URL used when a file omits `apiUrl`. */
33
- export const DEFAULT_DEEPLAKE_API_URL = "https://api.deeplake.ai";
34
- /**
35
- * Structured, fail-closed rejection. Carries exactly which fields were missing
36
- * or invalid so a caller (or an operator reading a log line) knows what to
37
- * fix without the loader ever echoing the file's contents (which may hold the
38
- * token).
39
- */
40
- export class DeepLakeCredentialsError extends Error {
41
- missing;
42
- constructor(missing) {
43
- super(`Invalid Deep Lake credentials: ${missing.join("; ")}`);
44
- this.name = "DeepLakeCredentialsError";
45
- this.missing = missing;
46
- }
47
- }
48
- /** Resolve the credentials directory, honoring the test override. */
49
- export function credentialsDir(options = {}) {
50
- return options.dir ?? join(homedir(), CREDENTIALS_DIR_NAME);
51
- }
52
- /** Resolve the full credentials file path within the (possibly overridden) dir. */
53
- export function credentialsPath(options = {}) {
54
- return join(credentialsDir(options), CREDENTIALS_FILE_NAME);
55
- }
56
- /**
57
- * Load and validate `~/.deeplake/credentials.json` (or the overridden dir in
58
- * `options.dir`). Throws {@link DeepLakeCredentialsError} listing every
59
- * problem found: a missing file, invalid JSON, a non-object payload, or a
60
- * missing/empty `token` / `orgId` / `workspaceId`. Never returns a partial
61
- * credential — the caller either gets a fully-populated `DeepLakeCredentials`
62
- * or a clear, typed reason it could not.
63
- */
64
- export function loadDeepLakeCredentials(options = {}) {
65
- const path = credentialsPath(options);
66
- if (!existsSync(path)) {
67
- throw new DeepLakeCredentialsError([`credentials file not found at ${path}`]);
68
- }
69
- let parsed;
70
- try {
71
- parsed = JSON.parse(readFileSync(path, "utf8"));
72
- }
73
- catch {
74
- throw new DeepLakeCredentialsError([`credentials file at ${path} is not valid JSON`]);
75
- }
76
- if (typeof parsed !== "object" || parsed === null) {
77
- throw new DeepLakeCredentialsError([`credentials file at ${path} does not contain a JSON object`]);
78
- }
79
- const record = parsed;
80
- const missing = [];
81
- if (typeof record.token !== "string" || record.token.length === 0)
82
- missing.push("token");
83
- if (typeof record.orgId !== "string" || record.orgId.length === 0)
84
- missing.push("orgId");
85
- if (typeof record.workspaceId !== "string" || record.workspaceId.length === 0)
86
- missing.push("workspaceId");
87
- if (missing.length > 0) {
88
- throw new DeepLakeCredentialsError(missing);
89
- }
90
- const apiUrl = typeof record.apiUrl === "string" && record.apiUrl.length > 0 ? record.apiUrl : DEFAULT_DEEPLAKE_API_URL;
91
- return {
92
- apiUrl,
93
- token: record.token,
94
- orgId: record.orgId,
95
- workspaceId: record.workspaceId,
96
- };
97
- }
98
- /**
99
- * Redact a token for logs and errors. Never echoes a token in full: keeps the
100
- * last 4 chars for correlation, masks the rest. An empty/short value collapses
101
- * to a fixed mask so length isn't leaked either. Mirrors honeycomb's
102
- * `redactToken` (`src/daemon/runtime/auth/credentials-store.ts:254-257`).
103
- */
104
- export function redactToken(value) {
105
- if (value.length <= 4)
106
- return "****";
107
- return `****${value.slice(-4)}`;
108
- }
109
- //# sourceMappingURL=deeplake-credentials.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deeplake-credentials.js","sourceRoot":"","sources":["../../src/source-graph/deeplake-credentials.ts"],"names":[],"mappings":"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"}