@remnic/connector-bee 9.69.27 → 9.69.29

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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { WearableConversation, WearableNativeMemory, WearableConnectorFactoryOptions, WearableSourceConnector, WearableConnectorRegistration } from '@remnic/core';
2
+ import { ConnectorApiError } from '@remnic/core/http-retry';
2
3
 
3
4
  /**
4
5
  * Minimal Bee developer API client (raw fetch, no SDK).
@@ -22,6 +23,7 @@ import { WearableConversation, WearableNativeMemory, WearableConnectorFactoryOpt
22
23
  * in the envelope; timestamps are epoch milliseconds. Tokens are never
23
24
  * logged and never appear in thrown error messages.
24
25
  */
26
+
25
27
  declare const BEE_DEFAULT_BASE_URL = "http://127.0.0.1:8787";
26
28
  declare const BEE_DIRECT_BASE_URL = "https://app-api-developer.ce.bee.amazon.dev";
27
29
  interface BeeConversationListItem {
@@ -76,9 +78,8 @@ interface BeeClientOptions {
76
78
  timeoutMs?: number;
77
79
  sleep?: (ms: number) => Promise<void>;
78
80
  }
79
- declare class BeeApiError extends Error {
80
- readonly status?: number | undefined;
81
- constructor(message: string, status?: number | undefined);
81
+ declare class BeeApiError extends ConnectorApiError {
82
+ constructor(message: string, status?: number);
82
83
  }
83
84
  declare class BeeClient {
84
85
  private readonly token;
package/dist/index.js CHANGED
@@ -7,19 +7,21 @@ import {
7
7
  } from "@remnic/core";
8
8
 
9
9
  // src/client.ts
10
+ import {
11
+ ConnectorApiError,
12
+ describeNetworkError,
13
+ retryingFetch,
14
+ stripTrailingSlashes
15
+ } from "@remnic/core/http-retry";
10
16
  var BEE_DEFAULT_BASE_URL = "http://127.0.0.1:8787";
11
17
  var BEE_DIRECT_BASE_URL = "https://app-api-developer.ce.bee.amazon.dev";
12
18
  var DEFAULT_TIMEOUT_MS = 3e4;
13
- var MAX_RETRIES = 3;
14
- var MAX_RETRY_DELAY_MS = 3e4;
15
19
  var LIST_PAGE_SIZE = 50;
16
- var BeeApiError = class extends Error {
20
+ var BeeApiError = class extends ConnectorApiError {
17
21
  constructor(message, status) {
18
- super(message);
19
- this.status = status;
22
+ super(message, status);
20
23
  this.name = "BeeApiError";
21
24
  }
22
- status;
23
25
  };
24
26
  var BeeClient = class {
25
27
  token;
@@ -113,56 +115,34 @@ var BeeClient = class {
113
115
  }
114
116
  }
115
117
  async requestJson(pathAndQuery, signal) {
116
- let lastError;
117
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
118
- signal?.throwIfAborted();
119
- const timeoutSignal = AbortSignal.timeout(this.timeoutMs);
120
- const combined = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
121
- let response;
122
- try {
123
- response = await this.fetchImpl(`${this.baseUrl}${pathAndQuery}`, {
124
- method: "GET",
125
- headers: {
126
- Accept: "application/json",
127
- ...this.token !== void 0 ? { Authorization: `Bearer ${this.token}` } : {}
128
- },
129
- signal: combined
130
- });
131
- } catch (err) {
132
- if (signal?.aborted) throw err;
133
- lastError = err;
134
- if (attempt < MAX_RETRIES) {
135
- await this.sleep(backoffMs(attempt));
136
- continue;
137
- }
138
- throw new BeeApiError(
139
- `Bee API request failed after ${MAX_RETRIES + 1} attempts: ${describeNetworkError(err)}` + (this.usingLocalProxy ? " \u2014 is `bee proxy` running?" : "")
140
- );
141
- }
142
- if (response.status === 429 || response.status >= 500) {
143
- lastError = new BeeApiError(
144
- `Bee API responded ${response.status}`,
145
- response.status
146
- );
147
- if (attempt < MAX_RETRIES) {
148
- await this.sleep(retryDelayMs(response, attempt));
149
- continue;
118
+ const response = await retryingFetch(`${this.baseUrl}${pathAndQuery}`, {
119
+ init: {
120
+ method: "GET",
121
+ headers: {
122
+ Accept: "application/json",
123
+ ...this.token !== void 0 ? { Authorization: `Bearer ${this.token}` } : {}
150
124
  }
151
- throw lastError;
152
- }
153
- if (!response.ok) {
154
- throw new BeeApiError(
155
- `Bee API responded ${response.status} for ${pathAndQuery.split("?")[0]}`,
156
- response.status
157
- );
158
- }
159
- try {
160
- return await response.json();
161
- } catch {
162
- throw new BeeApiError("Bee API returned a non-JSON body");
163
- }
125
+ },
126
+ fetchImpl: this.fetchImpl,
127
+ sleep: this.sleep,
128
+ signal,
129
+ timeoutMs: this.timeoutMs,
130
+ networkError: (err, attempts) => new BeeApiError(
131
+ `Bee API request failed after ${attempts} attempts: ${describeNetworkError(err)}` + (this.usingLocalProxy ? " \u2014 is `bee proxy` running?" : "")
132
+ ),
133
+ retryableError: (retryable) => new BeeApiError(`Bee API responded ${retryable.status}`, retryable.status)
134
+ });
135
+ if (!response.ok) {
136
+ throw new BeeApiError(
137
+ `Bee API responded ${response.status} for ${pathAndQuery.split("?")[0]}`,
138
+ response.status
139
+ );
140
+ }
141
+ try {
142
+ return await response.json();
143
+ } catch {
144
+ throw new BeeApiError("Bee API returned a non-JSON body");
164
145
  }
165
- throw lastError instanceof Error ? lastError : new BeeApiError("Bee API request failed");
166
146
  }
167
147
  };
168
148
  function isConversationListItem(entry) {
@@ -182,29 +162,6 @@ function isLocalProxyUrl(url) {
182
162
  return false;
183
163
  }
184
164
  }
185
- function describeNetworkError(err) {
186
- if (!(err instanceof Error)) return "unexpected non-Error failure";
187
- const code = err.code;
188
- return typeof code === "string" && code.length > 0 ? `${err.name} (${code})` : err.name;
189
- }
190
- function stripTrailingSlashes(value) {
191
- let end = value.length;
192
- while (end > 0 && value.charCodeAt(end - 1) === 47) end--;
193
- return value.slice(0, end);
194
- }
195
- function backoffMs(attempt) {
196
- return Math.min(MAX_RETRY_DELAY_MS, 1e3 * 2 ** attempt);
197
- }
198
- function retryDelayMs(response, attempt) {
199
- const headerValue = response.headers.get("retry-after");
200
- if (headerValue !== null) {
201
- const parsed = Number(headerValue);
202
- if (Number.isFinite(parsed) && parsed > 0) {
203
- return Math.min(MAX_RETRY_DELAY_MS, Math.ceil(parsed * 1e3));
204
- }
205
- }
206
- return backoffMs(attempt);
207
- }
208
165
 
209
166
  // src/normalize.ts
210
167
  var BEE_SOURCE_ID = "bee";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/normalize.ts"],"sourcesContent":["/**\n * @remnic/connector-bee — Bee wearable connector.\n *\n * À-la-carte optional companion of @remnic/core (computed-specifier\n * discovery; importing this module self-registers idempotently).\n *\n * Access modes:\n * - default: the local `bee proxy` (http://127.0.0.1:8787, no token)\n * - direct: set `wearables.sources.bee.baseUrl` to the direct host\n * and provide a token via `REMNIC_BEE_API_TOKEN` /\n * `BEE_API_TOKEN` (or `apiKey` in config)\n *\n * Bee's list API has no date filter, so the connector paginates\n * newest-first and filters conversations to the requested local day,\n * stopping once a whole page predates it.\n */\n\nimport {\n dateInTimezone,\n selfRegisterWearableConnector,\n type WearableConnectorFactoryOptions,\n type WearableConnectorRegistration,\n type WearableFetchOptions,\n type WearableFetchPage,\n type WearableNativeMemoryPage,\n type WearableSourceConnector,\n} from \"@remnic/core\";\n\nimport { BeeClient, isLocalProxyUrl, BEE_DEFAULT_BASE_URL, type BeeConversationListItem } from \"./client.js\";\nimport { BEE_SOURCE_ID, conversationToWearable, factToNativeMemory } from \"./normalize.js\";\n\nexport {\n BeeApiError,\n BeeClient,\n BEE_DEFAULT_BASE_URL,\n BEE_DIRECT_BASE_URL,\n isLocalProxyUrl,\n} from \"./client.js\";\nexport type {\n BeeClientOptions,\n BeeConversationDetail,\n BeeConversationListItem,\n BeeConversationsPage,\n BeeFact,\n BeeFactsPage,\n BeeUtterance,\n} from \"./client.js\";\nexport { BEE_SOURCE_ID, conversationToWearable, factToNativeMemory } from \"./normalize.js\";\n\nexport function resolveBeeToken(\n configuredToken: string | undefined,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n if (typeof configuredToken === \"string\" && configuredToken.trim().length > 0) {\n return configuredToken.trim();\n }\n for (const name of [\"REMNIC_BEE_API_TOKEN\", \"BEE_API_TOKEN\"]) {\n const value = env[name];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return undefined;\n}\n\n/** Conversations still being recorded are skipped until they settle. */\nfunction isSyncableState(item: BeeConversationListItem): boolean {\n return typeof item.state !== \"string\" || item.state.toUpperCase() !== \"CAPTURING\";\n}\n\nexport function createBeeConnector(\n options: WearableConnectorFactoryOptions,\n): WearableSourceConnector {\n let client: BeeClient | null = null;\n const getClient = (): BeeClient => {\n if (!client) {\n const baseUrl = options.settings.baseUrl ?? BEE_DEFAULT_BASE_URL;\n // The local proxy is unauthenticated by design — never attach a\n // Bearer header there, even when a direct-mode token sits in the\n // environment (it would 401 proxy requests for users who keep\n // BEE_API_TOKEN exported for occasional direct use).\n const token = isLocalProxyUrl(baseUrl)\n ? undefined\n : resolveBeeToken(options.settings.apiKey);\n client = new BeeClient({ token, baseUrl });\n }\n return client;\n };\n\n return {\n id: BEE_SOURCE_ID,\n displayName: \"Bee\",\n async verifyAuth(signal?: AbortSignal) {\n return getClient().verifyAuth(signal);\n },\n async fetchConversations(opts: WearableFetchOptions): Promise<WearableFetchPage> {\n const page = await getClient().listConversations({\n cursor: opts.cursor,\n signal: opts.signal,\n });\n\n const matching: BeeConversationListItem[] = [];\n let sawOnlyOlder = page.conversations.length > 0;\n for (const item of page.conversations) {\n const localDate = dateInTimezone(new Date(item.start_time), opts.timezone);\n if (localDate === opts.date && isSyncableState(item)) {\n matching.push(item);\n }\n if (localDate >= opts.date) {\n sawOnlyOlder = false;\n }\n }\n\n const conversations = [];\n for (const item of matching) {\n const detail = await getClient().getConversation(item.id, opts.signal);\n if (detail === null) continue;\n conversations.push(conversationToWearable(detail));\n }\n\n // Stop paginating once an entire (newest-first) page predates the\n // requested day; anything deeper is older still.\n const nextCursor = sawOnlyOlder ? null : page.nextCursor;\n return { conversations, nextCursor };\n },\n async fetchNativeMemories(opts: {\n cursor?: string | null;\n signal?: AbortSignal;\n }): Promise<WearableNativeMemoryPage> {\n const page = await getClient().listFacts({\n cursor: opts.cursor,\n signal: opts.signal,\n });\n return {\n memories: page.facts.map(factToNativeMemory),\n nextCursor: page.nextCursor,\n };\n },\n };\n}\n\nexport const wearableConnectorRegistration: WearableConnectorRegistration = {\n id: BEE_SOURCE_ID,\n displayName: \"Bee\",\n factory: createBeeConnector,\n};\n\n/**\n * Idempotently register the connector with the core registry. Importing\n * this module registers it as a side effect; calling this again is safe\n * (returns false when already registered).\n */\nexport const ensureBeeConnectorRegistered =\n selfRegisterWearableConnector(wearableConnectorRegistration);\n","/**\n * Minimal Bee developer API client (raw fetch, no SDK).\n *\n * Contract verified against the official `@beeai/cli` source and\n * docs.bee.computer (2026-06). Two access modes:\n *\n * - **Proxy mode (default):** the official `bee proxy` command serves\n * the full developer API unauthenticated on `http://127.0.0.1:8787`.\n * No token required.\n * - **Direct mode:** `https://app-api-developer.ce.bee.amazon.dev`\n * with `Authorization: Bearer <token>` (token from `bee login`,\n * stored at `~/.bee/token-prod`). The direct host uses Bee's private\n * CA — point `NODE_EXTRA_CA_CERTS` at it when going direct.\n *\n * The legacy pre-acquisition API (`api.bee.computer`, `x-api-key`,\n * page/totalPages) no longer resolves and is intentionally not\n * supported.\n *\n * List endpoints use `limit` + `cursor` pagination with a `next_cursor`\n * in the envelope; timestamps are epoch milliseconds. Tokens are never\n * logged and never appear in thrown error messages.\n */\n\nexport const BEE_DEFAULT_BASE_URL = \"http://127.0.0.1:8787\";\nexport const BEE_DIRECT_BASE_URL = \"https://app-api-developer.ce.bee.amazon.dev\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_RETRIES = 3;\nconst MAX_RETRY_DELAY_MS = 30_000;\nconst LIST_PAGE_SIZE = 50;\n\nexport interface BeeConversationListItem {\n id: number;\n start_time: number;\n end_time?: number | null;\n device_type?: string;\n short_summary?: string | null;\n summary?: string | null;\n state?: string;\n}\n\nexport interface BeeUtterance {\n id?: number;\n start?: number | null;\n end?: number | null;\n spoken_at?: number;\n text?: string;\n speaker?: string;\n}\n\nexport interface BeeConversationDetail extends BeeConversationListItem {\n transcriptions?: Array<{\n id?: number;\n utterances?: BeeUtterance[];\n }>;\n primary_location?: {\n address?: string | null;\n latitude?: number;\n longitude?: number;\n } | null;\n}\n\nexport interface BeeFact {\n id: number;\n text: string;\n tags?: string[];\n created_at?: number;\n confirmed?: boolean;\n}\n\nexport interface BeeConversationsPage {\n conversations: BeeConversationListItem[];\n nextCursor: string | null;\n}\n\nexport interface BeeFactsPage {\n facts: BeeFact[];\n nextCursor: string | null;\n}\n\nexport interface BeeClientOptions {\n /** Bearer token for direct mode. Omit entirely for proxy mode. */\n token?: string;\n /** Defaults to the local `bee proxy` address. */\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport class BeeApiError extends Error {\n constructor(\n message: string,\n readonly status?: number,\n ) {\n super(message);\n this.name = \"BeeApiError\";\n }\n}\n\nexport class BeeClient {\n private readonly token: string | undefined;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n private readonly sleep: (ms: number) => Promise<void>;\n\n constructor(options: BeeClientOptions = {}) {\n this.token =\n typeof options.token === \"string\" && options.token.trim().length > 0\n ? options.token.trim()\n : undefined;\n this.baseUrl = stripTrailingSlashes(options.baseUrl ?? BEE_DEFAULT_BASE_URL);\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.sleep =\n options.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));\n }\n\n get usingLocalProxy(): boolean {\n return isLocalProxyUrl(this.baseUrl);\n }\n\n async listConversations(params: {\n cursor?: string | null;\n limit?: number;\n signal?: AbortSignal;\n } = {}): Promise<BeeConversationsPage> {\n const search = new URLSearchParams({\n limit: String(params.limit ?? LIST_PAGE_SIZE),\n });\n if (typeof params.cursor === \"string\" && params.cursor.length > 0) {\n search.set(\"cursor\", params.cursor);\n }\n const payload = await this.requestJson(\n `/v1/conversations?${search.toString()}`,\n params.signal,\n );\n const conversations = (payload as { conversations?: unknown }).conversations;\n if (!Array.isArray(conversations)) {\n throw new BeeApiError(\n \"Bee API returned an unexpected /v1/conversations shape (missing conversations array)\",\n );\n }\n return {\n conversations: conversations.filter(isConversationListItem),\n nextCursor: readNextCursor(payload),\n };\n }\n\n async getConversation(\n id: number,\n signal?: AbortSignal,\n ): Promise<BeeConversationDetail | null> {\n let payload: unknown;\n try {\n payload = await this.requestJson(`/v1/conversations/${id}`, signal);\n } catch (err) {\n // A conversation can be deleted between the list and the detail\n // fetch — a 404 skips that conversation instead of aborting the\n // whole day sync. Other failures (auth, 5xx after retries) still\n // throw so transient outages retry the sync rather than silently\n // dropping data.\n if (err instanceof BeeApiError && err.status === 404) return null;\n throw err;\n }\n // Current API returns the detail at the top level; the legacy shape\n // wrapped it as {conversation: {...}}. Accept both.\n const detail =\n payload !== null &&\n typeof payload === \"object\" &&\n \"conversation\" in (payload as Record<string, unknown>)\n ? (payload as { conversation: unknown }).conversation\n : payload;\n return isConversationListItem(detail) ? (detail as BeeConversationDetail) : null;\n }\n\n async listFacts(params: {\n cursor?: string | null;\n signal?: AbortSignal;\n } = {}): Promise<BeeFactsPage> {\n const search = new URLSearchParams({\n limit: String(LIST_PAGE_SIZE),\n confirmed: \"true\",\n });\n if (typeof params.cursor === \"string\" && params.cursor.length > 0) {\n search.set(\"cursor\", params.cursor);\n }\n const payload = await this.requestJson(`/v1/facts?${search.toString()}`, params.signal);\n const facts = (payload as { facts?: unknown }).facts;\n if (!Array.isArray(facts)) {\n throw new BeeApiError(\n \"Bee API returned an unexpected /v1/facts shape (missing facts array)\",\n );\n }\n return {\n facts: facts.filter(\n (entry): entry is BeeFact =>\n entry !== null &&\n typeof entry === \"object\" &&\n typeof (entry as { id?: unknown }).id === \"number\" &&\n typeof (entry as { text?: unknown }).text === \"string\",\n ),\n nextCursor: readNextCursor(payload),\n };\n }\n\n async verifyAuth(signal?: AbortSignal): Promise<{ ok: boolean; detail?: string }> {\n try {\n await this.requestJson(\"/v1/me\", signal);\n return {\n ok: true,\n detail: this.usingLocalProxy ? \"via local bee proxy\" : \"direct API access\",\n };\n } catch (err) {\n if (err instanceof BeeApiError && (err.status === 401 || err.status === 403)) {\n return {\n ok: false,\n detail: this.usingLocalProxy\n ? \"the bee proxy rejected the request — re-run `bee login` then restart `bee proxy`\"\n : \"Bee rejected the token (401/403) — re-run `bee login` and update BEE_API_TOKEN\",\n };\n }\n // BeeApiError messages are our own constructed strings (status\n // codes + endpoint role; network failures already carry the\n // `bee proxy` hint from requestJson) — keep them actionable.\n // Only foreign errors are reduced to name + code.\n return {\n ok: false,\n detail: err instanceof BeeApiError ? err.message : describeNetworkError(err),\n };\n }\n }\n\n private async requestJson(pathAndQuery: string, signal?: AbortSignal): Promise<unknown> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n signal?.throwIfAborted();\n const timeoutSignal = AbortSignal.timeout(this.timeoutMs);\n const combined = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n let response: Response;\n try {\n response = await this.fetchImpl(`${this.baseUrl}${pathAndQuery}`, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n ...(this.token !== undefined\n ? { Authorization: `Bearer ${this.token}` }\n : {}),\n },\n signal: combined,\n });\n } catch (err) {\n if (signal?.aborted) throw err;\n lastError = err;\n if (attempt < MAX_RETRIES) {\n await this.sleep(backoffMs(attempt));\n continue;\n }\n throw new BeeApiError(\n `Bee API request failed after ${MAX_RETRIES + 1} attempts: ${describeNetworkError(err)}` +\n (this.usingLocalProxy ? \" — is `bee proxy` running?\" : \"\"),\n );\n }\n\n if (response.status === 429 || response.status >= 500) {\n lastError = new BeeApiError(\n `Bee API responded ${response.status}`,\n response.status,\n );\n if (attempt < MAX_RETRIES) {\n await this.sleep(retryDelayMs(response, attempt));\n continue;\n }\n throw lastError;\n }\n if (!response.ok) {\n throw new BeeApiError(\n `Bee API responded ${response.status} for ${pathAndQuery.split(\"?\")[0]}`,\n response.status,\n );\n }\n try {\n return await response.json();\n } catch {\n throw new BeeApiError(\"Bee API returned a non-JSON body\");\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new BeeApiError(\"Bee API request failed\");\n }\n}\n\nfunction isConversationListItem(entry: unknown): entry is BeeConversationListItem {\n return (\n entry !== null &&\n typeof entry === \"object\" &&\n typeof (entry as { id?: unknown }).id === \"number\" &&\n typeof (entry as { start_time?: unknown }).start_time === \"number\"\n );\n}\n\nfunction readNextCursor(payload: unknown): string | null {\n const cursor = (payload as { next_cursor?: unknown }).next_cursor;\n if (typeof cursor === \"string\" && cursor.length > 0) return cursor;\n if (typeof cursor === \"number\") return String(cursor);\n return null;\n}\n\n/**\n * True when the URL points at the local `bee proxy`. Hostname is\n * compared exactly after parsing — a prefix match would also treat\n * hosts like 127.0.0.1.evil.example as local.\n */\nexport function isLocalProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return (\n parsed.hostname === \"127.0.0.1\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"[::1]\" ||\n parsed.hostname === \"::1\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Network/timeout failures wrap Node error text that can carry loader\n * paths or stack fragments; sync errors reach MCP clients verbatim, so\n * only the error name + code survive.\n */\nfunction describeNetworkError(err: unknown): string {\n if (!(err instanceof Error)) return \"unexpected non-Error failure\";\n const code = (err as NodeJS.ErrnoException).code;\n return typeof code === \"string\" && code.length > 0 ? `${err.name} (${code})` : err.name;\n}\n\n/** Loop instead of `/\\/+$/` — CodeQL js/polynomial-redos on user-set URLs. */\nfunction stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 0x2f) end--;\n return value.slice(0, end);\n}\n\nfunction backoffMs(attempt: number): number {\n return Math.min(MAX_RETRY_DELAY_MS, 1_000 * 2 ** attempt);\n}\n\nfunction retryDelayMs(response: Response, attempt: number): number {\n const headerValue = response.headers.get(\"retry-after\");\n if (headerValue !== null) {\n const parsed = Number(headerValue);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.min(MAX_RETRY_DELAY_MS, Math.ceil(parsed * 1_000));\n }\n }\n return backoffMs(attempt);\n}\n","/**\n * Normalize Bee conversations into Remnic's provider-agnostic\n * `WearableConversation` shape.\n *\n * Bee timestamps are epoch milliseconds; utterance `speaker` values are\n * opaque diarization labels (\"0\", \"1\", ...) with no wearer marker — the\n * Remnic speaker registry is how labels become names\n * (`remnic wearables speakers set bee 0 \"You\" --self`).\n */\n\nimport type {\n WearableConversation,\n WearableNativeMemory,\n WearableTranscriptSegment,\n} from \"@remnic/core\";\n\nimport type { BeeConversationDetail, BeeFact } from \"./client.js\";\n\nexport const BEE_SOURCE_ID = \"bee\";\n\nfunction msToIso(ms: number | null | undefined): string | undefined {\n if (typeof ms !== \"number\" || !Number.isFinite(ms) || ms <= 0) return undefined;\n return new Date(ms).toISOString();\n}\n\nexport function conversationToWearable(\n detail: BeeConversationDetail,\n): WearableConversation {\n const segments: WearableTranscriptSegment[] = [];\n for (const transcription of detail.transcriptions ?? []) {\n for (const utterance of transcription.utterances ?? []) {\n const text = typeof utterance.text === \"string\" ? utterance.text.trim() : \"\";\n if (text.length === 0) continue;\n const speaker =\n typeof utterance.speaker === \"string\" && utterance.speaker.trim().length > 0\n ? utterance.speaker.trim()\n : \"unknown\";\n // Prefer Bee's explicit utterance `start`/`end` when a real\n // (positive) timestamp is present; otherwise fall back to\n // `spoken_at` for the start (issue #1811). A `start` of 0 is not a\n // valid epoch, so it is treated as absent and yields the\n // `spoken_at` fallback. Carrying `end` keeps per-utterance timing\n // on the segment and lets the cleanup pass reason about real gaps\n // instead of treating every utterance as a point in time.\n const startMs =\n typeof utterance.start === \"number\" && utterance.start > 0\n ? utterance.start\n : utterance.spoken_at;\n const startIso = msToIso(startMs);\n const endIso = msToIso(utterance.end ?? undefined);\n segments.push({\n text,\n speakerKey: speaker,\n ...(startIso !== undefined ? { startIso } : {}),\n ...(endIso !== undefined ? { endIso } : {}),\n });\n }\n }\n // Bee nests utterances per transcription block; order within a block\n // is chronological but blocks can interleave — sort stably by time\n // when timestamps exist.\n segments.sort((a, b) => {\n const aMs = a.startIso ? Date.parse(a.startIso) : Number.NaN;\n const bMs = b.startIso ? Date.parse(b.startIso) : Number.NaN;\n if (Number.isNaN(aMs) || Number.isNaN(bMs)) return 0;\n if (aMs < bMs) return -1;\n if (aMs > bMs) return 1;\n return 0;\n });\n\n const title =\n typeof detail.short_summary === \"string\" && detail.short_summary.trim().length > 0\n ? detail.short_summary.trim().split(\"\\n\")[0]\n : undefined;\n\n return {\n id: String(detail.id),\n source: BEE_SOURCE_ID,\n ...(title !== undefined ? { title } : {}),\n ...(typeof detail.summary === \"string\" && detail.summary.trim().length > 0\n ? { summary: detail.summary.trim() }\n : {}),\n startIso: msToIso(detail.start_time) ?? \"\",\n ...(msToIso(detail.end_time ?? undefined) !== undefined\n ? { endIso: msToIso(detail.end_time ?? undefined) }\n : {}),\n ...(typeof detail.primary_location?.address === \"string\" &&\n detail.primary_location.address.length > 0\n ? { location: detail.primary_location.address }\n : {}),\n segments,\n };\n}\n\nexport function factToNativeMemory(fact: BeeFact): WearableNativeMemory {\n return {\n id: String(fact.id),\n content: fact.text,\n ...(msToIso(fact.created_at) !== undefined\n ? { createdIso: msToIso(fact.created_at) }\n : {}),\n ...(Array.isArray(fact.tags) && fact.tags.length > 0 ? { tags: fact.tags } : {}),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/normalize.ts"],"sourcesContent":["/**\n * @remnic/connector-bee — Bee wearable connector.\n *\n * À-la-carte optional companion of @remnic/core (computed-specifier\n * discovery; importing this module self-registers idempotently).\n *\n * Access modes:\n * - default: the local `bee proxy` (http://127.0.0.1:8787, no token)\n * - direct: set `wearables.sources.bee.baseUrl` to the direct host\n * and provide a token via `REMNIC_BEE_API_TOKEN` /\n * `BEE_API_TOKEN` (or `apiKey` in config)\n *\n * Bee's list API has no date filter, so the connector paginates\n * newest-first and filters conversations to the requested local day,\n * stopping once a whole page predates it.\n */\n\nimport {\n dateInTimezone,\n selfRegisterWearableConnector,\n type WearableConnectorFactoryOptions,\n type WearableConnectorRegistration,\n type WearableFetchOptions,\n type WearableFetchPage,\n type WearableNativeMemoryPage,\n type WearableSourceConnector,\n} from \"@remnic/core\";\n\nimport { BeeClient, isLocalProxyUrl, BEE_DEFAULT_BASE_URL, type BeeConversationListItem } from \"./client.js\";\nimport { BEE_SOURCE_ID, conversationToWearable, factToNativeMemory } from \"./normalize.js\";\n\nexport {\n BeeApiError,\n BeeClient,\n BEE_DEFAULT_BASE_URL,\n BEE_DIRECT_BASE_URL,\n isLocalProxyUrl,\n} from \"./client.js\";\nexport type {\n BeeClientOptions,\n BeeConversationDetail,\n BeeConversationListItem,\n BeeConversationsPage,\n BeeFact,\n BeeFactsPage,\n BeeUtterance,\n} from \"./client.js\";\nexport { BEE_SOURCE_ID, conversationToWearable, factToNativeMemory } from \"./normalize.js\";\n\nexport function resolveBeeToken(\n configuredToken: string | undefined,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n if (typeof configuredToken === \"string\" && configuredToken.trim().length > 0) {\n return configuredToken.trim();\n }\n for (const name of [\"REMNIC_BEE_API_TOKEN\", \"BEE_API_TOKEN\"]) {\n const value = env[name];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return undefined;\n}\n\n/** Conversations still being recorded are skipped until they settle. */\nfunction isSyncableState(item: BeeConversationListItem): boolean {\n return typeof item.state !== \"string\" || item.state.toUpperCase() !== \"CAPTURING\";\n}\n\nexport function createBeeConnector(\n options: WearableConnectorFactoryOptions,\n): WearableSourceConnector {\n let client: BeeClient | null = null;\n const getClient = (): BeeClient => {\n if (!client) {\n const baseUrl = options.settings.baseUrl ?? BEE_DEFAULT_BASE_URL;\n // The local proxy is unauthenticated by design — never attach a\n // Bearer header there, even when a direct-mode token sits in the\n // environment (it would 401 proxy requests for users who keep\n // BEE_API_TOKEN exported for occasional direct use).\n const token = isLocalProxyUrl(baseUrl)\n ? undefined\n : resolveBeeToken(options.settings.apiKey);\n client = new BeeClient({ token, baseUrl });\n }\n return client;\n };\n\n return {\n id: BEE_SOURCE_ID,\n displayName: \"Bee\",\n async verifyAuth(signal?: AbortSignal) {\n return getClient().verifyAuth(signal);\n },\n async fetchConversations(opts: WearableFetchOptions): Promise<WearableFetchPage> {\n const page = await getClient().listConversations({\n cursor: opts.cursor,\n signal: opts.signal,\n });\n\n const matching: BeeConversationListItem[] = [];\n let sawOnlyOlder = page.conversations.length > 0;\n for (const item of page.conversations) {\n const localDate = dateInTimezone(new Date(item.start_time), opts.timezone);\n if (localDate === opts.date && isSyncableState(item)) {\n matching.push(item);\n }\n if (localDate >= opts.date) {\n sawOnlyOlder = false;\n }\n }\n\n const conversations = [];\n for (const item of matching) {\n const detail = await getClient().getConversation(item.id, opts.signal);\n if (detail === null) continue;\n conversations.push(conversationToWearable(detail));\n }\n\n // Stop paginating once an entire (newest-first) page predates the\n // requested day; anything deeper is older still.\n const nextCursor = sawOnlyOlder ? null : page.nextCursor;\n return { conversations, nextCursor };\n },\n async fetchNativeMemories(opts: {\n cursor?: string | null;\n signal?: AbortSignal;\n }): Promise<WearableNativeMemoryPage> {\n const page = await getClient().listFacts({\n cursor: opts.cursor,\n signal: opts.signal,\n });\n return {\n memories: page.facts.map(factToNativeMemory),\n nextCursor: page.nextCursor,\n };\n },\n };\n}\n\nexport const wearableConnectorRegistration: WearableConnectorRegistration = {\n id: BEE_SOURCE_ID,\n displayName: \"Bee\",\n factory: createBeeConnector,\n};\n\n/**\n * Idempotently register the connector with the core registry. Importing\n * this module registers it as a side effect; calling this again is safe\n * (returns false when already registered).\n */\nexport const ensureBeeConnectorRegistered =\n selfRegisterWearableConnector(wearableConnectorRegistration);\n","/**\n * Minimal Bee developer API client (raw fetch, no SDK).\n *\n * Contract verified against the official `@beeai/cli` source and\n * docs.bee.computer (2026-06). Two access modes:\n *\n * - **Proxy mode (default):** the official `bee proxy` command serves\n * the full developer API unauthenticated on `http://127.0.0.1:8787`.\n * No token required.\n * - **Direct mode:** `https://app-api-developer.ce.bee.amazon.dev`\n * with `Authorization: Bearer <token>` (token from `bee login`,\n * stored at `~/.bee/token-prod`). The direct host uses Bee's private\n * CA — point `NODE_EXTRA_CA_CERTS` at it when going direct.\n *\n * The legacy pre-acquisition API (`api.bee.computer`, `x-api-key`,\n * page/totalPages) no longer resolves and is intentionally not\n * supported.\n *\n * List endpoints use `limit` + `cursor` pagination with a `next_cursor`\n * in the envelope; timestamps are epoch milliseconds. Tokens are never\n * logged and never appear in thrown error messages.\n */\n\nimport {\n ConnectorApiError,\n describeNetworkError,\n retryingFetch,\n stripTrailingSlashes,\n} from \"@remnic/core/http-retry\";\n\nexport const BEE_DEFAULT_BASE_URL = \"http://127.0.0.1:8787\";\nexport const BEE_DIRECT_BASE_URL = \"https://app-api-developer.ce.bee.amazon.dev\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst LIST_PAGE_SIZE = 50;\n\nexport interface BeeConversationListItem {\n id: number;\n start_time: number;\n end_time?: number | null;\n device_type?: string;\n short_summary?: string | null;\n summary?: string | null;\n state?: string;\n}\n\nexport interface BeeUtterance {\n id?: number;\n start?: number | null;\n end?: number | null;\n spoken_at?: number;\n text?: string;\n speaker?: string;\n}\n\nexport interface BeeConversationDetail extends BeeConversationListItem {\n transcriptions?: Array<{\n id?: number;\n utterances?: BeeUtterance[];\n }>;\n primary_location?: {\n address?: string | null;\n latitude?: number;\n longitude?: number;\n } | null;\n}\n\nexport interface BeeFact {\n id: number;\n text: string;\n tags?: string[];\n created_at?: number;\n confirmed?: boolean;\n}\n\nexport interface BeeConversationsPage {\n conversations: BeeConversationListItem[];\n nextCursor: string | null;\n}\n\nexport interface BeeFactsPage {\n facts: BeeFact[];\n nextCursor: string | null;\n}\n\nexport interface BeeClientOptions {\n /** Bearer token for direct mode. Omit entirely for proxy mode. */\n token?: string;\n /** Defaults to the local `bee proxy` address. */\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport class BeeApiError extends ConnectorApiError {\n constructor(\n message: string,\n status?: number,\n ) {\n super(message, status);\n this.name = \"BeeApiError\";\n }\n}\n\nexport class BeeClient {\n private readonly token: string | undefined;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n private readonly sleep: (ms: number) => Promise<void>;\n\n constructor(options: BeeClientOptions = {}) {\n this.token =\n typeof options.token === \"string\" && options.token.trim().length > 0\n ? options.token.trim()\n : undefined;\n this.baseUrl = stripTrailingSlashes(options.baseUrl ?? BEE_DEFAULT_BASE_URL);\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.sleep =\n options.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));\n }\n\n get usingLocalProxy(): boolean {\n return isLocalProxyUrl(this.baseUrl);\n }\n\n async listConversations(params: {\n cursor?: string | null;\n limit?: number;\n signal?: AbortSignal;\n } = {}): Promise<BeeConversationsPage> {\n const search = new URLSearchParams({\n limit: String(params.limit ?? LIST_PAGE_SIZE),\n });\n if (typeof params.cursor === \"string\" && params.cursor.length > 0) {\n search.set(\"cursor\", params.cursor);\n }\n const payload = await this.requestJson(\n `/v1/conversations?${search.toString()}`,\n params.signal,\n );\n const conversations = (payload as { conversations?: unknown }).conversations;\n if (!Array.isArray(conversations)) {\n throw new BeeApiError(\n \"Bee API returned an unexpected /v1/conversations shape (missing conversations array)\",\n );\n }\n return {\n conversations: conversations.filter(isConversationListItem),\n nextCursor: readNextCursor(payload),\n };\n }\n\n async getConversation(\n id: number,\n signal?: AbortSignal,\n ): Promise<BeeConversationDetail | null> {\n let payload: unknown;\n try {\n payload = await this.requestJson(`/v1/conversations/${id}`, signal);\n } catch (err) {\n // A conversation can be deleted between the list and the detail\n // fetch — a 404 skips that conversation instead of aborting the\n // whole day sync. Other failures (auth, 5xx after retries) still\n // throw so transient outages retry the sync rather than silently\n // dropping data.\n if (err instanceof BeeApiError && err.status === 404) return null;\n throw err;\n }\n // Current API returns the detail at the top level; the legacy shape\n // wrapped it as {conversation: {...}}. Accept both.\n const detail =\n payload !== null &&\n typeof payload === \"object\" &&\n \"conversation\" in (payload as Record<string, unknown>)\n ? (payload as { conversation: unknown }).conversation\n : payload;\n return isConversationListItem(detail) ? (detail as BeeConversationDetail) : null;\n }\n\n async listFacts(params: {\n cursor?: string | null;\n signal?: AbortSignal;\n } = {}): Promise<BeeFactsPage> {\n const search = new URLSearchParams({\n limit: String(LIST_PAGE_SIZE),\n confirmed: \"true\",\n });\n if (typeof params.cursor === \"string\" && params.cursor.length > 0) {\n search.set(\"cursor\", params.cursor);\n }\n const payload = await this.requestJson(`/v1/facts?${search.toString()}`, params.signal);\n const facts = (payload as { facts?: unknown }).facts;\n if (!Array.isArray(facts)) {\n throw new BeeApiError(\n \"Bee API returned an unexpected /v1/facts shape (missing facts array)\",\n );\n }\n return {\n facts: facts.filter(\n (entry): entry is BeeFact =>\n entry !== null &&\n typeof entry === \"object\" &&\n typeof (entry as { id?: unknown }).id === \"number\" &&\n typeof (entry as { text?: unknown }).text === \"string\",\n ),\n nextCursor: readNextCursor(payload),\n };\n }\n\n async verifyAuth(signal?: AbortSignal): Promise<{ ok: boolean; detail?: string }> {\n try {\n await this.requestJson(\"/v1/me\", signal);\n return {\n ok: true,\n detail: this.usingLocalProxy ? \"via local bee proxy\" : \"direct API access\",\n };\n } catch (err) {\n if (err instanceof BeeApiError && (err.status === 401 || err.status === 403)) {\n return {\n ok: false,\n detail: this.usingLocalProxy\n ? \"the bee proxy rejected the request — re-run `bee login` then restart `bee proxy`\"\n : \"Bee rejected the token (401/403) — re-run `bee login` and update BEE_API_TOKEN\",\n };\n }\n // BeeApiError messages are our own constructed strings (status\n // codes + endpoint role; network failures already carry the\n // `bee proxy` hint from requestJson) — keep them actionable.\n // Only foreign errors are reduced to name + code.\n return {\n ok: false,\n detail: err instanceof BeeApiError ? err.message : describeNetworkError(err),\n };\n }\n }\n\n private async requestJson(pathAndQuery: string, signal?: AbortSignal): Promise<unknown> {\n const response = await retryingFetch(`${this.baseUrl}${pathAndQuery}`, {\n init: {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n ...(this.token !== undefined\n ? { Authorization: `Bearer ${this.token}` }\n : {}),\n },\n },\n fetchImpl: this.fetchImpl,\n sleep: this.sleep,\n signal,\n timeoutMs: this.timeoutMs,\n networkError: (err, attempts) =>\n new BeeApiError(\n `Bee API request failed after ${attempts} attempts: ${describeNetworkError(err)}` +\n (this.usingLocalProxy ? \" — is `bee proxy` running?\" : \"\"),\n ),\n retryableError: (retryable) =>\n new BeeApiError(`Bee API responded ${retryable.status}`, retryable.status),\n });\n if (!response.ok) {\n throw new BeeApiError(\n `Bee API responded ${response.status} for ${pathAndQuery.split(\"?\")[0]}`,\n response.status,\n );\n }\n try {\n return await response.json();\n } catch {\n throw new BeeApiError(\"Bee API returned a non-JSON body\");\n }\n }\n}\n\nfunction isConversationListItem(entry: unknown): entry is BeeConversationListItem {\n return (\n entry !== null &&\n typeof entry === \"object\" &&\n typeof (entry as { id?: unknown }).id === \"number\" &&\n typeof (entry as { start_time?: unknown }).start_time === \"number\"\n );\n}\n\nfunction readNextCursor(payload: unknown): string | null {\n const cursor = (payload as { next_cursor?: unknown }).next_cursor;\n if (typeof cursor === \"string\" && cursor.length > 0) return cursor;\n if (typeof cursor === \"number\") return String(cursor);\n return null;\n}\n\n/**\n * True when the URL points at the local `bee proxy`. Hostname is\n * compared exactly after parsing — a prefix match would also treat\n * hosts like 127.0.0.1.evil.example as local.\n */\nexport function isLocalProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return (\n parsed.hostname === \"127.0.0.1\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"[::1]\" ||\n parsed.hostname === \"::1\"\n );\n } catch {\n return false;\n }\n}\n\n\n","/**\n * Normalize Bee conversations into Remnic's provider-agnostic\n * `WearableConversation` shape.\n *\n * Bee timestamps are epoch milliseconds; utterance `speaker` values are\n * opaque diarization labels (\"0\", \"1\", ...) with no wearer marker — the\n * Remnic speaker registry is how labels become names\n * (`remnic wearables speakers set bee 0 \"You\" --self`).\n */\n\nimport type {\n WearableConversation,\n WearableNativeMemory,\n WearableTranscriptSegment,\n} from \"@remnic/core\";\n\nimport type { BeeConversationDetail, BeeFact } from \"./client.js\";\n\nexport const BEE_SOURCE_ID = \"bee\";\n\nfunction msToIso(ms: number | null | undefined): string | undefined {\n if (typeof ms !== \"number\" || !Number.isFinite(ms) || ms <= 0) return undefined;\n return new Date(ms).toISOString();\n}\n\nexport function conversationToWearable(\n detail: BeeConversationDetail,\n): WearableConversation {\n const segments: WearableTranscriptSegment[] = [];\n for (const transcription of detail.transcriptions ?? []) {\n for (const utterance of transcription.utterances ?? []) {\n const text = typeof utterance.text === \"string\" ? utterance.text.trim() : \"\";\n if (text.length === 0) continue;\n const speaker =\n typeof utterance.speaker === \"string\" && utterance.speaker.trim().length > 0\n ? utterance.speaker.trim()\n : \"unknown\";\n // Prefer Bee's explicit utterance `start`/`end` when a real\n // (positive) timestamp is present; otherwise fall back to\n // `spoken_at` for the start (issue #1811). A `start` of 0 is not a\n // valid epoch, so it is treated as absent and yields the\n // `spoken_at` fallback. Carrying `end` keeps per-utterance timing\n // on the segment and lets the cleanup pass reason about real gaps\n // instead of treating every utterance as a point in time.\n const startMs =\n typeof utterance.start === \"number\" && utterance.start > 0\n ? utterance.start\n : utterance.spoken_at;\n const startIso = msToIso(startMs);\n const endIso = msToIso(utterance.end ?? undefined);\n segments.push({\n text,\n speakerKey: speaker,\n ...(startIso !== undefined ? { startIso } : {}),\n ...(endIso !== undefined ? { endIso } : {}),\n });\n }\n }\n // Bee nests utterances per transcription block; order within a block\n // is chronological but blocks can interleave — sort stably by time\n // when timestamps exist.\n segments.sort((a, b) => {\n const aMs = a.startIso ? Date.parse(a.startIso) : Number.NaN;\n const bMs = b.startIso ? Date.parse(b.startIso) : Number.NaN;\n if (Number.isNaN(aMs) || Number.isNaN(bMs)) return 0;\n if (aMs < bMs) return -1;\n if (aMs > bMs) return 1;\n return 0;\n });\n\n const title =\n typeof detail.short_summary === \"string\" && detail.short_summary.trim().length > 0\n ? detail.short_summary.trim().split(\"\\n\")[0]\n : undefined;\n\n return {\n id: String(detail.id),\n source: BEE_SOURCE_ID,\n ...(title !== undefined ? { title } : {}),\n ...(typeof detail.summary === \"string\" && detail.summary.trim().length > 0\n ? { summary: detail.summary.trim() }\n : {}),\n startIso: msToIso(detail.start_time) ?? \"\",\n ...(msToIso(detail.end_time ?? undefined) !== undefined\n ? { endIso: msToIso(detail.end_time ?? undefined) }\n : {}),\n ...(typeof detail.primary_location?.address === \"string\" &&\n detail.primary_location.address.length > 0\n ? { location: detail.primary_location.address }\n : {}),\n segments,\n };\n}\n\nexport function factToNativeMemory(fact: BeeFact): WearableNativeMemory {\n return {\n id: String(fact.id),\n content: fact.text,\n ...(msToIso(fact.created_at) !== undefined\n ? { createdIso: msToIso(fact.created_at) }\n : {}),\n ...(Array.isArray(fact.tags) && fact.tags.length > 0 ? { tags: fact.tags } : {}),\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/connector-bee",
3
- "version": "9.69.27",
3
+ "version": "9.69.29",
4
4
  "description": "Bee wearable connector for Remnic — pull, clean, and remember bracelet transcripts via the Bee developer API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,13 +19,13 @@
19
19
  "provenance": true
20
20
  },
21
21
  "peerDependencies": {
22
- "@remnic/core": "^9.69.27"
22
+ "@remnic/core": "^9.69.29"
23
23
  },
24
24
  "devDependencies": {
25
25
  "tsup": "^8.0.0",
26
26
  "typescript": "^5.7.0",
27
27
  "tsx": "^4.0.0",
28
- "@remnic/core": "9.69.27"
28
+ "@remnic/core": "9.69.29"
29
29
  },
30
30
  "license": "MIT",
31
31
  "repository": {