electric-ax 0.2.1 → 0.2.2

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.cjs CHANGED
@@ -11,6 +11,7 @@ const node_path = require_chunk.__toESM(require("node:path"));
11
11
  const node_url = require_chunk.__toESM(require("node:url"));
12
12
  const commander = require_chunk.__toESM(require("commander"));
13
13
  const node_readline_promises = require_chunk.__toESM(require("node:readline/promises"));
14
+ const __electric_ax_agents_server_headers = require_chunk.__toESM(require("@electric-ax/agents/server-headers"));
14
15
 
15
16
  //#region src/prompt-api-key.ts
16
17
  const FRIENDLY_INTRO = `\n${[
@@ -162,17 +163,20 @@ function parseElectricAgentsHeaders(raw) {
162
163
  }
163
164
  function getElectricCliEnv(env = process.env) {
164
165
  const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
166
+ const headers = parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS);
165
167
  return {
166
168
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
167
169
  electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
168
- electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
170
+ electricAgentsHeaders: (0, __electric_ax_agents_server_headers.mergeElectricPrincipalHeader)(headers, env.ELECTRIC_AGENTS_PRINCIPAL)
169
171
  };
170
172
  }
171
173
  function getErrorMessage(error) {
172
- return error instanceof Error ? error.message : String(error);
174
+ if (error instanceof Error) return error.message || error.name || `Unknown error`;
175
+ const message = String(error);
176
+ return message || `Unknown error`;
173
177
  }
174
178
  function fail(message) {
175
- throw new CliError(message);
179
+ throw new CliError(message || `Unknown error`);
176
180
  }
177
181
  function relativeTime(epochMs) {
178
182
  const seconds = Math.floor((Date.now() - epochMs) / 1e3);
@@ -310,17 +314,36 @@ async function parseJsonResponse(res) {
310
314
  return JSON.parse(text);
311
315
  } catch (error) {
312
316
  if (!(error instanceof SyntaxError)) throw error;
313
- return { error: { message: text || res.statusText } };
317
+ return { error: { message: text || fallbackResponseMessage(res) } };
314
318
  }
315
319
  }
320
+ function fallbackResponseMessage(res) {
321
+ const status = res.status ? `HTTP ${res.status}` : `HTTP error`;
322
+ return res.statusText ? `${status}: ${res.statusText}` : status;
323
+ }
324
+ function stringMessage(value) {
325
+ if (typeof value !== `string`) return void 0;
326
+ const trimmed = value.trim();
327
+ if (trimmed.length === 0) return void 0;
328
+ return trimmed;
329
+ }
330
+ function errorMessageFromValue(value) {
331
+ const direct = stringMessage(value);
332
+ if (direct) return direct;
333
+ if (!value || typeof value !== `object` || Array.isArray(value)) return void 0;
334
+ const record = value;
335
+ return errorMessageFromValue(record.message) ?? errorMessageFromValue(record.error) ?? errorMessageFromValue(record.reason) ?? errorMessageFromValue(record.detail);
336
+ }
337
+ function responseErrorMessage(data, res) {
338
+ return errorMessageFromValue(data) ?? fallbackResponseMessage(res);
339
+ }
316
340
  function failFromResponse(data, res) {
317
- const err = data.error;
318
- fail(String(err?.message ?? res.statusText));
341
+ fail(responseErrorMessage(data, res));
319
342
  }
320
343
  async function fetchEntityTypes(env) {
321
344
  const res = await electricAgentsFetch(env, `/_electric/entity-types`);
322
- const data = await res.json();
323
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
345
+ const data = await parseJsonResponse(res);
346
+ if (!res.ok) failFromResponse(data, res);
324
347
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entity types`);
325
348
  return data;
326
349
  }
@@ -345,8 +368,8 @@ async function fetchEntities(env, options = {}) {
345
368
  if (options.parent) searchParams.set(`parent`, options.parent);
346
369
  const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : ``;
347
370
  const res = await electricAgentsFetch(env, `/_electric/entities${suffix}`);
348
- const data = await res.json();
349
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
371
+ const data = await parseJsonResponse(res);
372
+ if (!res.ok) failFromResponse(data, res);
350
373
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entities`);
351
374
  return data;
352
375
  }
@@ -525,6 +548,8 @@ function getHelpText(commandName) {
525
548
  Environment:
526
549
  ELECTRIC_AGENTS_URL Base URL of the server (default: ${DEFAULT_ELECTRIC_AGENTS_URL})
527
550
  ELECTRIC_AGENTS_IDENTITY Sender identity for messages (default: ${getDefaultElectricAgentsIdentity()})
551
+ ELECTRIC_AGENTS_PRINCIPAL Optional principal key sent as the Electric-Principal header
552
+ ELECTRIC_AGENTS_SERVER_HEADERS Optional JSON object of additional server headers
528
553
  ANTHROPIC_API_KEY Required for '${agentsCommand} start-builtin' and '${agentsCommand} quickstart'
529
554
 
530
555
  Examples:
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import { basename, resolve } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { Command } from "commander";
11
11
  import { createInterface } from "node:readline/promises";
12
+ import { mergeElectricPrincipalHeader } from "@electric-ax/agents/server-headers";
12
13
 
13
14
  //#region src/prompt-api-key.ts
14
15
  const FRIENDLY_INTRO = `\n${[
@@ -160,17 +161,20 @@ function parseElectricAgentsHeaders(raw) {
160
161
  }
161
162
  function getElectricCliEnv(env = process.env) {
162
163
  const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
164
+ const headers = parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS);
163
165
  return {
164
166
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
165
167
  electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
166
- electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
168
+ electricAgentsHeaders: mergeElectricPrincipalHeader(headers, env.ELECTRIC_AGENTS_PRINCIPAL)
167
169
  };
168
170
  }
169
171
  function getErrorMessage(error) {
170
- return error instanceof Error ? error.message : String(error);
172
+ if (error instanceof Error) return error.message || error.name || `Unknown error`;
173
+ const message = String(error);
174
+ return message || `Unknown error`;
171
175
  }
172
176
  function fail(message) {
173
- throw new CliError(message);
177
+ throw new CliError(message || `Unknown error`);
174
178
  }
175
179
  function relativeTime(epochMs) {
176
180
  const seconds = Math.floor((Date.now() - epochMs) / 1e3);
@@ -308,17 +312,36 @@ async function parseJsonResponse(res) {
308
312
  return JSON.parse(text);
309
313
  } catch (error) {
310
314
  if (!(error instanceof SyntaxError)) throw error;
311
- return { error: { message: text || res.statusText } };
315
+ return { error: { message: text || fallbackResponseMessage(res) } };
312
316
  }
313
317
  }
318
+ function fallbackResponseMessage(res) {
319
+ const status = res.status ? `HTTP ${res.status}` : `HTTP error`;
320
+ return res.statusText ? `${status}: ${res.statusText}` : status;
321
+ }
322
+ function stringMessage(value) {
323
+ if (typeof value !== `string`) return void 0;
324
+ const trimmed = value.trim();
325
+ if (trimmed.length === 0) return void 0;
326
+ return trimmed;
327
+ }
328
+ function errorMessageFromValue(value) {
329
+ const direct = stringMessage(value);
330
+ if (direct) return direct;
331
+ if (!value || typeof value !== `object` || Array.isArray(value)) return void 0;
332
+ const record = value;
333
+ return errorMessageFromValue(record.message) ?? errorMessageFromValue(record.error) ?? errorMessageFromValue(record.reason) ?? errorMessageFromValue(record.detail);
334
+ }
335
+ function responseErrorMessage(data, res) {
336
+ return errorMessageFromValue(data) ?? fallbackResponseMessage(res);
337
+ }
314
338
  function failFromResponse(data, res) {
315
- const err = data.error;
316
- fail(String(err?.message ?? res.statusText));
339
+ fail(responseErrorMessage(data, res));
317
340
  }
318
341
  async function fetchEntityTypes(env) {
319
342
  const res = await electricAgentsFetch(env, `/_electric/entity-types`);
320
- const data = await res.json();
321
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
343
+ const data = await parseJsonResponse(res);
344
+ if (!res.ok) failFromResponse(data, res);
322
345
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entity types`);
323
346
  return data;
324
347
  }
@@ -343,8 +366,8 @@ async function fetchEntities(env, options = {}) {
343
366
  if (options.parent) searchParams.set(`parent`, options.parent);
344
367
  const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : ``;
345
368
  const res = await electricAgentsFetch(env, `/_electric/entities${suffix}`);
346
- const data = await res.json();
347
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
369
+ const data = await parseJsonResponse(res);
370
+ if (!res.ok) failFromResponse(data, res);
348
371
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entities`);
349
372
  return data;
350
373
  }
@@ -523,6 +546,8 @@ function getHelpText(commandName) {
523
546
  Environment:
524
547
  ELECTRIC_AGENTS_URL Base URL of the server (default: ${DEFAULT_ELECTRIC_AGENTS_URL})
525
548
  ELECTRIC_AGENTS_IDENTITY Sender identity for messages (default: ${getDefaultElectricAgentsIdentity()})
549
+ ELECTRIC_AGENTS_PRINCIPAL Optional principal key sent as the Electric-Principal header
550
+ ELECTRIC_AGENTS_SERVER_HEADERS Optional JSON object of additional server headers
526
551
  ANTHROPIC_API_KEY Required for '${agentsCommand} start-builtin' and '${agentsCommand} quickstart'
527
552
 
528
553
  Examples:
package/dist/start.cjs CHANGED
@@ -3,6 +3,7 @@ const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
3
  const require_env = require('./env-CFKgT8o2.cjs');
4
4
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
5
5
  const node_url = require_chunk.__toESM(require("node:url"));
6
+ const __electric_ax_agents_server_headers = require_chunk.__toESM(require("@electric-ax/agents/server-headers"));
6
7
  const node_child_process = require_chunk.__toESM(require("node:child_process"));
7
8
  const __electric_ax_agents = require_chunk.__toESM(require("@electric-ax/agents"));
8
9
 
@@ -69,7 +70,7 @@ function resolvePullWakeRunnerId(env = process.env, fileEnv = require_env.readDo
69
70
  return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]));
70
71
  }
71
72
  function resolvePullWakeOwnerId(env = process.env, fileEnv = require_env.readDotEnvFile()) {
72
- return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
73
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]) ?? readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
73
74
  }
74
75
  function parseAdditionalServerHeaders(env, fileEnv) {
75
76
  const raw = readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
@@ -89,6 +90,9 @@ function parseAdditionalServerHeaders(env, fileEnv) {
89
90
  const normalized = Object.fromEntries(headers.entries());
90
91
  return Object.keys(normalized).length > 0 ? normalized : void 0;
91
92
  }
93
+ function resolveServerHeaders(env, fileEnv) {
94
+ return (0, __electric_ax_agents_server_headers.mergeElectricPrincipalHeader)(parseAdditionalServerHeaders(env, fileEnv), readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]));
95
+ }
92
96
  function mergeHeaders(...sources) {
93
97
  const headers = new Headers();
94
98
  for (const source of sources) {
@@ -227,7 +231,7 @@ async function startBuiltinAgentsServer(options, params = {}) {
227
231
  const anthropicApiKey = require_env.resolveAnthropicApiKey(options, env, fileEnv);
228
232
  const runnerId = resolvePullWakeRunnerId(env, fileEnv);
229
233
  const ownerUserId = resolvePullWakeOwnerId(env, fileEnv);
230
- const serverHeaders = mergeHeaders(parseAdditionalServerHeaders(env, fileEnv));
234
+ const serverHeaders = mergeHeaders(resolveServerHeaders(env, fileEnv));
231
235
  const agentServerUrl = params.agentServerUrl ?? env.ELECTRIC_AGENTS_URL?.trim() ?? `http://localhost:${resolveElectricAgentsPort(env, fileEnv)}`;
232
236
  process.env.ANTHROPIC_API_KEY = anthropicApiKey;
233
237
  await waitForElectricAgentsServer(agentServerUrl, { headers: serverHeaders });
package/dist/start.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readDotEnvFile$1 as readDotEnvFile, resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-DIhTv987.js";
2
2
  import { appendPathToUrl } from "@electric-ax/agents-runtime";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { mergeElectricPrincipalHeader } from "@electric-ax/agents/server-headers";
4
5
  import { spawn } from "node:child_process";
5
6
  import { BuiltinAgentsServer } from "@electric-ax/agents";
6
7
 
@@ -67,7 +68,7 @@ function resolvePullWakeRunnerId(env = process.env, fileEnv = readDotEnvFile())
67
68
  return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]));
68
69
  }
69
70
  function resolvePullWakeOwnerId(env = process.env, fileEnv = readDotEnvFile()) {
70
- return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
71
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]) ?? readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
71
72
  }
72
73
  function parseAdditionalServerHeaders(env, fileEnv) {
73
74
  const raw = readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
@@ -87,6 +88,9 @@ function parseAdditionalServerHeaders(env, fileEnv) {
87
88
  const normalized = Object.fromEntries(headers.entries());
88
89
  return Object.keys(normalized).length > 0 ? normalized : void 0;
89
90
  }
91
+ function resolveServerHeaders(env, fileEnv) {
92
+ return mergeElectricPrincipalHeader(parseAdditionalServerHeaders(env, fileEnv), readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]));
93
+ }
90
94
  function mergeHeaders(...sources) {
91
95
  const headers = new Headers();
92
96
  for (const source of sources) {
@@ -225,7 +229,7 @@ async function startBuiltinAgentsServer(options, params = {}) {
225
229
  const anthropicApiKey = resolveAnthropicApiKey(options, env, fileEnv);
226
230
  const runnerId = resolvePullWakeRunnerId(env, fileEnv);
227
231
  const ownerUserId = resolvePullWakeOwnerId(env, fileEnv);
228
- const serverHeaders = mergeHeaders(parseAdditionalServerHeaders(env, fileEnv));
232
+ const serverHeaders = mergeHeaders(resolveServerHeaders(env, fileEnv));
229
233
  const agentServerUrl = params.agentServerUrl ?? env.ELECTRIC_AGENTS_URL?.trim() ?? `http://localhost:${resolveElectricAgentsPort(env, fileEnv)}`;
230
234
  process.env.ANTHROPIC_API_KEY = anthropicApiKey;
231
235
  await waitForElectricAgentsServer(agentServerUrl, { headers: serverHeaders });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electric-ax",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "CLI for Electric Agents",
5
5
  "author": "ElectricSQL team and contributors",
6
6
  "license": "Apache-2.0",
@@ -39,14 +39,14 @@
39
39
  "dependencies": {
40
40
  "@durable-streams/client": "https://pkg.pr.new/durable-streams/durable-streams/@durable-streams/client@350",
41
41
  "@durable-streams/state": "https://pkg.pr.new/durable-streams/durable-streams/@durable-streams/state@350",
42
- "@electric-sql/client": "^1.5.17",
42
+ "@electric-sql/client": "^1.5.18",
43
43
  "@tanstack/db": "^0.6.4",
44
44
  "@tanstack/react-db": "^0.1.82",
45
45
  "commander": "^13.1.0",
46
46
  "ink": "^6.8.0",
47
47
  "omelette": "^0.4.17",
48
48
  "react": "^19.2.0",
49
- "@electric-ax/agents": "0.4.1",
49
+ "@electric-ax/agents": "0.4.2",
50
50
  "@electric-ax/agents-runtime": "0.2.1"
51
51
  },
52
52
  "devDependencies": {