electric-ax 0.1.17 → 0.2.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.
@@ -1,4 +1,4 @@
1
- import { ElectricCliEnv } from "./index-B2MsxFCW.cjs";
1
+ import { ElectricCliEnv } from "./index-BQ4JyfkG.cjs";
2
2
 
3
3
  //#region src/completions.d.ts
4
4
  declare function fetchEntityTypeNames(env: ElectricCliEnv): Promise<Array<string>>;
@@ -1,4 +1,4 @@
1
- import { ElectricCliEnv } from "./index-BDO8dHhT.js";
1
+ import { ElectricCliEnv } from "./index-D6TZ88Yg.js";
2
2
 
3
3
  //#region src/completions.d.ts
4
4
  declare function fetchEntityTypeNames(env: ElectricCliEnv): Promise<Array<string>>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
+ const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
4
+
5
+ //#region src/entity-api.ts
6
+ function withLeadingSlash(path) {
7
+ return path.startsWith(`/`) ? path : `/${path}`;
8
+ }
9
+ function entityApiPath(entityUrl, suffix = ``) {
10
+ return `/_electric/entities${withLeadingSlash(entityUrl)}${suffix}`;
11
+ }
12
+ function entityApiUrl(baseUrl, entityUrl, suffix = ``) {
13
+ return (0, __electric_ax_agents_runtime.appendPathToUrl)(baseUrl, entityApiPath(entityUrl, suffix));
14
+ }
15
+ function assertedIdentityHeaders(identity) {
16
+ const trimmed = identity?.trim();
17
+ return trimmed ? { "x-electric-asserted-email": trimmed } : {};
18
+ }
19
+
20
+ //#endregion
21
+ Object.defineProperty(exports, 'assertedIdentityHeaders', {
22
+ enumerable: true,
23
+ get: function () {
24
+ return assertedIdentityHeaders;
25
+ }
26
+ });
27
+ Object.defineProperty(exports, 'entityApiPath', {
28
+ enumerable: true,
29
+ get: function () {
30
+ return entityApiPath;
31
+ }
32
+ });
33
+ Object.defineProperty(exports, 'entityApiUrl', {
34
+ enumerable: true,
35
+ get: function () {
36
+ return entityApiUrl;
37
+ }
38
+ });
@@ -0,0 +1,19 @@
1
+ import { appendPathToUrl } from "@electric-ax/agents-runtime";
2
+
3
+ //#region src/entity-api.ts
4
+ function withLeadingSlash(path) {
5
+ return path.startsWith(`/`) ? path : `/${path}`;
6
+ }
7
+ function entityApiPath(entityUrl, suffix = ``) {
8
+ return `/_electric/entities${withLeadingSlash(entityUrl)}${suffix}`;
9
+ }
10
+ function entityApiUrl(baseUrl, entityUrl, suffix = ``) {
11
+ return appendPathToUrl(baseUrl, entityApiPath(entityUrl, suffix));
12
+ }
13
+ function assertedIdentityHeaders(identity) {
14
+ const trimmed = identity?.trim();
15
+ return trimmed ? { "x-electric-asserted-email": trimmed } : {};
16
+ }
17
+
18
+ //#endregion
19
+ export { assertedIdentityHeaders, entityApiPath, entityApiUrl };
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
+ const require_entity_api = require('./entity-api-ClpnLxWJ.cjs');
3
4
  const __durable_streams_state = require_chunk.__toESM(require("@durable-streams/state"));
4
5
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
5
6
 
@@ -8,21 +9,28 @@ function getMainStreamPath(entityUrl, entity) {
8
9
  return entity.streams?.main ?? `${entityUrl}/main`;
9
10
  }
10
11
  async function createEntityStreamDB(opts) {
11
- const { baseUrl, entityUrl, initialOffset } = opts;
12
+ const { baseUrl, entityUrl, initialOffset, assertedAuthEmail, assertedAuthName, headers: serverHeaders } = opts;
12
13
  console.log(`[createEntityStreamDB] Creating entity stream DB for ${baseUrl}${entityUrl}`);
14
+ const requestHeaders = {
15
+ "content-type": `application/json`,
16
+ ...require_entity_api.assertedIdentityHeaders(assertedAuthEmail),
17
+ ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
18
+ ...serverHeaders
19
+ };
13
20
  let res;
14
21
  try {
15
- res = await fetch(`${baseUrl}${entityUrl}`, { headers: { "content-type": `application/json` } });
22
+ res = await fetch(require_entity_api.entityApiUrl(baseUrl, entityUrl), { headers: requestHeaders });
16
23
  } catch (err) {
17
24
  throw new Error(`Could not connect to the Electric Agents server at ${baseUrl} — is it running?\n ${err instanceof Error ? err.message : String(err)}`);
18
25
  }
19
26
  if (!res.ok) throw new Error(`Failed to fetch entity at ${entityUrl}: ${res.statusText}`);
20
27
  const entity = await res.json();
21
28
  const streamPath = getMainStreamPath(entityUrl, entity);
22
- const streamUrl = `${baseUrl}${streamPath}`;
29
+ const streamUrl = (0, __electric_ax_agents_runtime.appendPathToUrl)(baseUrl, streamPath);
23
30
  const db = (0, __durable_streams_state.createStreamDB)({
24
31
  streamOptions: {
25
32
  url: streamUrl,
33
+ headers: requestHeaders,
26
34
  contentType: `application/json`,
27
35
  ...initialOffset ? { offset: initialOffset } : {}
28
36
  },
@@ -6,8 +6,11 @@ declare function createEntityStreamDB(opts: {
6
6
  baseUrl: string;
7
7
  entityUrl: string;
8
8
  initialOffset?: string;
9
+ assertedAuthEmail?: string;
10
+ assertedAuthName?: string;
11
+ headers?: Record<string, string>;
9
12
  }): Promise<{
10
13
  db: EntityStreamDB;
11
14
  close: () => void;
12
15
  }>; //#endregion
13
- export { EntityStreamDB$1 as EntityStreamDB, createEntityStreamDB as createEntityStreamDB$1 };
16
+ export { EntityStreamDB$1 as EntityStreamDB, createEntityStreamDB };
@@ -1,26 +1,34 @@
1
+ import { assertedIdentityHeaders, entityApiUrl } from "./entity-api-Dh28Mz7H.js";
1
2
  import { createStreamDB } from "@durable-streams/state";
2
- import { entityStateSchema } from "@electric-ax/agents-runtime";
3
+ import { appendPathToUrl, entityStateSchema } from "@electric-ax/agents-runtime";
3
4
 
4
5
  //#region src/entity-stream-db.ts
5
6
  function getMainStreamPath(entityUrl, entity) {
6
7
  return entity.streams?.main ?? `${entityUrl}/main`;
7
8
  }
8
9
  async function createEntityStreamDB(opts) {
9
- const { baseUrl, entityUrl, initialOffset } = opts;
10
+ const { baseUrl, entityUrl, initialOffset, assertedAuthEmail, assertedAuthName, headers: serverHeaders } = opts;
10
11
  console.log(`[createEntityStreamDB] Creating entity stream DB for ${baseUrl}${entityUrl}`);
12
+ const requestHeaders = {
13
+ "content-type": `application/json`,
14
+ ...assertedIdentityHeaders(assertedAuthEmail),
15
+ ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
16
+ ...serverHeaders
17
+ };
11
18
  let res;
12
19
  try {
13
- res = await fetch(`${baseUrl}${entityUrl}`, { headers: { "content-type": `application/json` } });
20
+ res = await fetch(entityApiUrl(baseUrl, entityUrl), { headers: requestHeaders });
14
21
  } catch (err) {
15
22
  throw new Error(`Could not connect to the Electric Agents server at ${baseUrl} — is it running?\n ${err instanceof Error ? err.message : String(err)}`);
16
23
  }
17
24
  if (!res.ok) throw new Error(`Failed to fetch entity at ${entityUrl}: ${res.statusText}`);
18
25
  const entity = await res.json();
19
26
  const streamPath = getMainStreamPath(entityUrl, entity);
20
- const streamUrl = `${baseUrl}${streamPath}`;
27
+ const streamUrl = appendPathToUrl(baseUrl, streamPath);
21
28
  const db = createStreamDB({
22
29
  streamOptions: {
23
30
  url: streamUrl,
31
+ headers: requestHeaders,
24
32
  contentType: `application/json`,
25
33
  ...initialOffset ? { offset: initialOffset } : {}
26
34
  },
@@ -6,8 +6,11 @@ declare function createEntityStreamDB(opts: {
6
6
  baseUrl: string;
7
7
  entityUrl: string;
8
8
  initialOffset?: string;
9
+ assertedAuthEmail?: string;
10
+ assertedAuthName?: string;
11
+ headers?: Record<string, string>;
9
12
  }): Promise<{
10
13
  db: EntityStreamDB;
11
14
  close: () => void;
12
15
  }>; //#endregion
13
- export { EntityStreamDB$1 as EntityStreamDB, createEntityStreamDB };
16
+ export { EntityStreamDB$1 as EntityStreamDB, createEntityStreamDB as createEntityStreamDB$1 };
@@ -1,3 +1,4 @@
1
- const require_entity_stream_db = require('./entity-stream-db-Djo-7a11.cjs');
1
+ require('./entity-api-ClpnLxWJ.cjs');
2
+ const require_entity_stream_db = require('./entity-stream-db-BLbPedyR.cjs');
2
3
 
3
4
  exports.createEntityStreamDB = require_entity_stream_db.createEntityStreamDB
@@ -1,2 +1,2 @@
1
- import { EntityStreamDB, createEntityStreamDB } from "./entity-stream-db-C2C3t_hD.cjs";
1
+ import { EntityStreamDB, createEntityStreamDB } from "./entity-stream-db-CmDwc49J.cjs";
2
2
  export { EntityStreamDB, createEntityStreamDB };
@@ -1,2 +1,2 @@
1
- import { EntityStreamDB, createEntityStreamDB$1 as createEntityStreamDB } from "./entity-stream-db-BRwzIuHl.js";
1
+ import { EntityStreamDB, createEntityStreamDB$1 as createEntityStreamDB } from "./entity-stream-db-DgzxI6C_.js";
2
2
  export { EntityStreamDB, createEntityStreamDB };
@@ -1,3 +1,4 @@
1
- import { createEntityStreamDB } from "./entity-stream-db-CGP2xVeJ.js";
1
+ import "./entity-api-Dh28Mz7H.js";
2
+ import { createEntityStreamDB } from "./entity-stream-db-Czz3S8YF.js";
2
3
 
3
4
  export { createEntityStreamDB };
@@ -19,22 +19,22 @@ interface StoppedDevEnvironment {
19
19
  removedVolumes: boolean;
20
20
  }
21
21
  interface StartedBuiltinAgentsEnvironment {
22
- port: number;
22
+ runnerId: string;
23
23
  url: string;
24
- registeredBaseUrl: string;
25
24
  agentServerUrl: string;
26
25
  }
27
26
  interface WaitForServerOptions {
28
27
  fetchImpl?: typeof globalThis.fetch;
28
+ headers?: Record<string, string>;
29
29
  timeoutMs?: number;
30
30
  intervalMs?: number;
31
31
  }
32
- declare function resolveBuiltinAgentsPort(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): number;
33
- declare function resolveBuiltinAgentsHost(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
34
32
  declare function resolveElectricAgentsPort(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): number;
35
33
  declare function getStartedEnvironmentMessage(started: StartedDevEnvironment): string;
36
34
  declare function getStoppedEnvironmentMessage(stopped: StoppedDevEnvironment): string;
37
35
  declare function getStartedBuiltinAgentsMessage(started: StartedBuiltinAgentsEnvironment): string;
36
+ declare function resolvePullWakeRunnerId(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
37
+ declare function resolvePullWakeOwnerId(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
38
38
  declare function resolveComposeProjectName(_cwd?: string, env?: NodeJS.ProcessEnv): string;
39
39
  declare function waitForElectricAgentsServer(baseUrl: string, options?: WaitForServerOptions): Promise<void>;
40
40
  declare function startElectricAgentsDevEnvironment(_options?: StartCommandOptions, env?: NodeJS.ProcessEnv, cwd?: string): Promise<StartedDevEnvironment>;
@@ -52,6 +52,9 @@ declare const DEFAULT_ELECTRIC_AGENTS_URL = "http://localhost:4437";
52
52
  interface ElectricCliEnv {
53
53
  electricAgentsUrl: string;
54
54
  electricAgentsIdentity: string;
55
+ electricAssertedAuthEmail?: string;
56
+ electricAssertedAuthName?: string;
57
+ electricAgentsHeaders?: Record<string, string>;
55
58
  }
56
59
  interface SpawnCommandOptions {
57
60
  args?: string;
@@ -124,4 +127,4 @@ declare function createElectricProgram({
124
127
  declare function run(argv?: Array<string>): Promise<void>;
125
128
 
126
129
  //#endregion
127
- export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveBuiltinAgentsHost, resolveBuiltinAgentsPort, resolveCommandPrefix, resolveComposeProjectName, resolveElectricAgentsPort, run, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
130
+ export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveCommandPrefix, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, run, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
@@ -19,22 +19,22 @@ interface StoppedDevEnvironment {
19
19
  removedVolumes: boolean;
20
20
  }
21
21
  interface StartedBuiltinAgentsEnvironment {
22
- port: number;
22
+ runnerId: string;
23
23
  url: string;
24
- registeredBaseUrl: string;
25
24
  agentServerUrl: string;
26
25
  }
27
26
  interface WaitForServerOptions {
28
27
  fetchImpl?: typeof globalThis.fetch;
28
+ headers?: Record<string, string>;
29
29
  timeoutMs?: number;
30
30
  intervalMs?: number;
31
31
  }
32
- declare function resolveBuiltinAgentsPort(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): number;
33
- declare function resolveBuiltinAgentsHost(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
34
32
  declare function resolveElectricAgentsPort(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): number;
35
33
  declare function getStartedEnvironmentMessage(started: StartedDevEnvironment): string;
36
34
  declare function getStoppedEnvironmentMessage(stopped: StoppedDevEnvironment): string;
37
35
  declare function getStartedBuiltinAgentsMessage(started: StartedBuiltinAgentsEnvironment): string;
36
+ declare function resolvePullWakeRunnerId(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
37
+ declare function resolvePullWakeOwnerId(env?: NodeJS.ProcessEnv, fileEnv?: Record<string, string>): string;
38
38
  declare function resolveComposeProjectName(_cwd?: string, env?: NodeJS.ProcessEnv): string;
39
39
  declare function waitForElectricAgentsServer(baseUrl: string, options?: WaitForServerOptions): Promise<void>;
40
40
  declare function startElectricAgentsDevEnvironment(_options?: StartCommandOptions, env?: NodeJS.ProcessEnv, cwd?: string): Promise<StartedDevEnvironment>;
@@ -52,6 +52,9 @@ declare const DEFAULT_ELECTRIC_AGENTS_URL = "http://localhost:4437";
52
52
  interface ElectricCliEnv {
53
53
  electricAgentsUrl: string;
54
54
  electricAgentsIdentity: string;
55
+ electricAssertedAuthEmail?: string;
56
+ electricAssertedAuthName?: string;
57
+ electricAgentsHeaders?: Record<string, string>;
55
58
  }
56
59
  interface SpawnCommandOptions {
57
60
  args?: string;
@@ -124,4 +127,4 @@ declare function createElectricProgram({
124
127
  declare function run(argv?: Array<string>): Promise<void>;
125
128
 
126
129
  //#endregion
127
- export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveBuiltinAgentsHost, resolveBuiltinAgentsPort, resolveCommandPrefix, resolveComposeProjectName, resolveElectricAgentsPort, run, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
130
+ export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveCommandPrefix, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, run, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
package/dist/index.cjs CHANGED
@@ -2,7 +2,9 @@
2
2
  "use strict";
3
3
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
4
4
  const require_completions = require('./completions-Bj4D5DRa.cjs');
5
- const require_env = require('./env-BXUgom_C.cjs');
5
+ const require_entity_api = require('./entity-api-ClpnLxWJ.cjs');
6
+ const require_env = require('./env-CFKgT8o2.cjs');
7
+ const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
6
8
  const node_fs = require_chunk.__toESM(require("node:fs"));
7
9
  const node_os = require_chunk.__toESM(require("node:os"));
8
10
  const node_path = require_chunk.__toESM(require("node:path"));
@@ -67,11 +69,16 @@ async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
67
69
  await validate(explicitKey);
68
70
  return explicitKey;
69
71
  }
72
+ let resolvedKey;
70
73
  try {
71
- const key = require_env.resolveAnthropicApiKey(options);
72
- assertAnthropicApiKeyPrefix(key);
73
- await validate(key);
74
- return key;
74
+ resolvedKey = require_env.resolveAnthropicApiKey(options);
75
+ } catch (error) {
76
+ if (!io.isTTY) throw error;
77
+ }
78
+ if (resolvedKey !== void 0) try {
79
+ assertAnthropicApiKeyPrefix(resolvedKey);
80
+ await validate(resolvedKey);
81
+ return resolvedKey;
75
82
  } catch (error) {
76
83
  if (!io.isTTY) throw error;
77
84
  initialError = error;
@@ -135,10 +142,32 @@ var CliError = class extends Error {};
135
142
  function getDefaultElectricAgentsIdentity() {
136
143
  return `${(0, node_os.userInfo)().username}@${(0, node_os.hostname)()}`;
137
144
  }
145
+ function parseElectricAgentsHeaders(raw) {
146
+ const trimmed = raw?.trim();
147
+ if (!trimmed) return void 0;
148
+ let parsed;
149
+ try {
150
+ parsed = JSON.parse(trimmed);
151
+ } catch {
152
+ fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: expected JSON`);
153
+ }
154
+ if (!parsed || typeof parsed !== `object` || Array.isArray(parsed)) fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: expected a JSON object`);
155
+ const headers = new Headers();
156
+ for (const [name, value] of Object.entries(parsed)) {
157
+ if (typeof value !== `string`) fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: header "${name}" must be a string`);
158
+ headers.set(name, value);
159
+ }
160
+ const normalized = Object.fromEntries(headers.entries());
161
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
162
+ }
138
163
  function getElectricCliEnv(env = process.env) {
164
+ const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
139
165
  return {
140
166
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
141
- electricAgentsIdentity: env.ELECTRIC_AGENTS_IDENTITY || getDefaultElectricAgentsIdentity()
167
+ electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
168
+ electricAssertedAuthEmail: env.ELECTRIC_ASSERTED_AUTH_EMAIL?.trim() || explicitIdentity || void 0,
169
+ electricAssertedAuthName: env.ELECTRIC_ASSERTED_AUTH_NAME?.trim(),
170
+ electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
142
171
  };
143
172
  }
144
173
  function getErrorMessage(error) {
@@ -265,10 +294,13 @@ function resolveCommandPrefix(argv, env = process.env) {
265
294
  }
266
295
  async function electricAgentsFetch(env, path, opts = {}) {
267
296
  try {
268
- return await fetch(`${env.electricAgentsUrl}${path}`, {
297
+ return await fetch((0, __electric_ax_agents_runtime.appendPathToUrl)(env.electricAgentsUrl, path), {
269
298
  ...opts,
270
299
  headers: {
271
300
  "content-type": `application/json`,
301
+ ...require_entity_api.assertedIdentityHeaders(env.electricAssertedAuthEmail),
302
+ ...env.electricAssertedAuthName ? { "x-electric-asserted-name": env.electricAssertedAuthName } : {},
303
+ ...env.electricAgentsHeaders,
272
304
  ...opts.headers
273
305
  }
274
306
  });
@@ -343,7 +375,7 @@ async function spawnEntity(env, urlPath, options) {
343
375
  } catch (error) {
344
376
  fail(`--args must be valid JSON: ${getErrorMessage(error)}`);
345
377
  }
346
- const res = await electricAgentsFetch(env, urlPath, {
378
+ const res = await electricAgentsFetch(env, require_entity_api.entityApiPath(urlPath), {
347
379
  method: `PUT`,
348
380
  body: JSON.stringify({ args: spawnArgs })
349
381
  });
@@ -360,7 +392,7 @@ async function sendMessage(env, url, message, options) {
360
392
  payload
361
393
  };
362
394
  if (options.type) body.type = options.type;
363
- const res = await electricAgentsFetch(env, `${url}/send`, {
395
+ const res = await electricAgentsFetch(env, require_entity_api.entityApiPath(url, `/send`), {
364
396
  method: `POST`,
365
397
  body: JSON.stringify(body)
366
398
  });
@@ -377,11 +409,14 @@ async function observeEntity(env, url, options) {
377
409
  entityUrl: url,
378
410
  baseUrl: env.electricAgentsUrl,
379
411
  identity: env.electricAgentsIdentity,
412
+ assertedAuthEmail: env.electricAssertedAuthEmail,
413
+ assertedAuthName: env.electricAssertedAuthName,
414
+ headers: env.electricAgentsHeaders,
380
415
  initialOffset: options.from
381
416
  });
382
417
  }
383
418
  async function inspectEntity(env, url) {
384
- const res = await electricAgentsFetch(env, url);
419
+ const res = await electricAgentsFetch(env, require_entity_api.entityApiPath(url));
385
420
  const data = await parseJsonResponse(res);
386
421
  if (!res.ok) failFromResponse(data, res);
387
422
  console.log(JSON.stringify(data, null, 2));
@@ -406,7 +441,7 @@ async function listEntities(env, options) {
406
441
  }
407
442
  }
408
443
  async function killEntity(env, url) {
409
- const res = await electricAgentsFetch(env, url, { method: `DELETE` });
444
+ const res = await electricAgentsFetch(env, require_entity_api.entityApiPath(url), { method: `DELETE` });
410
445
  if (!res.ok) {
411
446
  const data = await parseJsonResponse(res);
412
447
  failFromResponse(data, res);
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-B2MsxFCW.cjs";
2
+ import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-BQ4JyfkG.cjs";
3
3
  export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-BDO8dHhT.js";
2
+ import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-D6TZ88Yg.js";
3
3
  export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run };
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { installCompletions, setupCompletions } from "./completions-B-Lf28Wy.js";
3
- import { resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-LZtIfFz1.js";
3
+ import { assertedIdentityHeaders, entityApiPath } from "./entity-api-Dh28Mz7H.js";
4
+ import { resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-DIhTv987.js";
5
+ import { appendPathToUrl } from "@electric-ax/agents-runtime";
4
6
  import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
5
7
  import { hostname, userInfo } from "node:os";
6
8
  import { basename, resolve } from "node:path";
@@ -65,11 +67,16 @@ async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
65
67
  await validate(explicitKey);
66
68
  return explicitKey;
67
69
  }
70
+ let resolvedKey;
68
71
  try {
69
- const key = resolveAnthropicApiKey(options);
70
- assertAnthropicApiKeyPrefix(key);
71
- await validate(key);
72
- return key;
72
+ resolvedKey = resolveAnthropicApiKey(options);
73
+ } catch (error) {
74
+ if (!io.isTTY) throw error;
75
+ }
76
+ if (resolvedKey !== void 0) try {
77
+ assertAnthropicApiKeyPrefix(resolvedKey);
78
+ await validate(resolvedKey);
79
+ return resolvedKey;
73
80
  } catch (error) {
74
81
  if (!io.isTTY) throw error;
75
82
  initialError = error;
@@ -133,10 +140,32 @@ var CliError = class extends Error {};
133
140
  function getDefaultElectricAgentsIdentity() {
134
141
  return `${userInfo().username}@${hostname()}`;
135
142
  }
143
+ function parseElectricAgentsHeaders(raw) {
144
+ const trimmed = raw?.trim();
145
+ if (!trimmed) return void 0;
146
+ let parsed;
147
+ try {
148
+ parsed = JSON.parse(trimmed);
149
+ } catch {
150
+ fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: expected JSON`);
151
+ }
152
+ if (!parsed || typeof parsed !== `object` || Array.isArray(parsed)) fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: expected a JSON object`);
153
+ const headers = new Headers();
154
+ for (const [name, value] of Object.entries(parsed)) {
155
+ if (typeof value !== `string`) fail(`Invalid ELECTRIC_AGENTS_SERVER_HEADERS: header "${name}" must be a string`);
156
+ headers.set(name, value);
157
+ }
158
+ const normalized = Object.fromEntries(headers.entries());
159
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
160
+ }
136
161
  function getElectricCliEnv(env = process.env) {
162
+ const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
137
163
  return {
138
164
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
139
- electricAgentsIdentity: env.ELECTRIC_AGENTS_IDENTITY || getDefaultElectricAgentsIdentity()
165
+ electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
166
+ electricAssertedAuthEmail: env.ELECTRIC_ASSERTED_AUTH_EMAIL?.trim() || explicitIdentity || void 0,
167
+ electricAssertedAuthName: env.ELECTRIC_ASSERTED_AUTH_NAME?.trim(),
168
+ electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
140
169
  };
141
170
  }
142
171
  function getErrorMessage(error) {
@@ -263,10 +292,13 @@ function resolveCommandPrefix(argv, env = process.env) {
263
292
  }
264
293
  async function electricAgentsFetch(env, path$1, opts = {}) {
265
294
  try {
266
- return await fetch(`${env.electricAgentsUrl}${path$1}`, {
295
+ return await fetch(appendPathToUrl(env.electricAgentsUrl, path$1), {
267
296
  ...opts,
268
297
  headers: {
269
298
  "content-type": `application/json`,
299
+ ...assertedIdentityHeaders(env.electricAssertedAuthEmail),
300
+ ...env.electricAssertedAuthName ? { "x-electric-asserted-name": env.electricAssertedAuthName } : {},
301
+ ...env.electricAgentsHeaders,
270
302
  ...opts.headers
271
303
  }
272
304
  });
@@ -341,7 +373,7 @@ async function spawnEntity(env, urlPath, options) {
341
373
  } catch (error) {
342
374
  fail(`--args must be valid JSON: ${getErrorMessage(error)}`);
343
375
  }
344
- const res = await electricAgentsFetch(env, urlPath, {
376
+ const res = await electricAgentsFetch(env, entityApiPath(urlPath), {
345
377
  method: `PUT`,
346
378
  body: JSON.stringify({ args: spawnArgs })
347
379
  });
@@ -358,7 +390,7 @@ async function sendMessage(env, url, message, options) {
358
390
  payload
359
391
  };
360
392
  if (options.type) body.type = options.type;
361
- const res = await electricAgentsFetch(env, `${url}/send`, {
393
+ const res = await electricAgentsFetch(env, entityApiPath(url, `/send`), {
362
394
  method: `POST`,
363
395
  body: JSON.stringify(body)
364
396
  });
@@ -375,11 +407,14 @@ async function observeEntity(env, url, options) {
375
407
  entityUrl: url,
376
408
  baseUrl: env.electricAgentsUrl,
377
409
  identity: env.electricAgentsIdentity,
410
+ assertedAuthEmail: env.electricAssertedAuthEmail,
411
+ assertedAuthName: env.electricAssertedAuthName,
412
+ headers: env.electricAgentsHeaders,
378
413
  initialOffset: options.from
379
414
  });
380
415
  }
381
416
  async function inspectEntity(env, url) {
382
- const res = await electricAgentsFetch(env, url);
417
+ const res = await electricAgentsFetch(env, entityApiPath(url));
383
418
  const data = await parseJsonResponse(res);
384
419
  if (!res.ok) failFromResponse(data, res);
385
420
  console.log(JSON.stringify(data, null, 2));
@@ -404,7 +439,7 @@ async function listEntities(env, options) {
404
439
  }
405
440
  }
406
441
  async function killEntity(env, url) {
407
- const res = await electricAgentsFetch(env, url, { method: `DELETE` });
442
+ const res = await electricAgentsFetch(env, entityApiPath(url), { method: `DELETE` });
408
443
  if (!res.ok) {
409
444
  const data = await parseJsonResponse(res);
410
445
  failFromResponse(data, res);