electric-ax 0.1.13 → 0.1.15

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
@@ -8,7 +8,95 @@ const node_os = require_chunk.__toESM(require("node:os"));
8
8
  const node_path = require_chunk.__toESM(require("node:path"));
9
9
  const node_url = require_chunk.__toESM(require("node:url"));
10
10
  const commander = require_chunk.__toESM(require("commander"));
11
+ const node_readline_promises = require_chunk.__toESM(require("node:readline/promises"));
11
12
 
13
+ //#region src/prompt-api-key.ts
14
+ const FRIENDLY_INTRO = [
15
+ ``,
16
+ `The Electric Agents quickstart requires setting an API key to connect to an LLM provider.`,
17
+ ``,
18
+ `Currently (in this initial developer preview release) the key must be an ANTHROPIC_API_KEY.`,
19
+ `Support for other LLM providers is coming very soon.`,
20
+ ``,
21
+ `Note that your API key never leaves your local computer. It's used by the agent entities`,
22
+ `installed by default in the Electric Agents runtime and by the example agents included`,
23
+ `in the quickstart template.`,
24
+ ``,
25
+ `Would you like to:`,
26
+ ``,
27
+ ` 1. manually setup a .env file with ANTHROPIC_API_KEY=...`,
28
+ ` 2. paste your api key into a prompt and we'll set it up for you`,
29
+ ``
30
+ ].join(`\n`);
31
+ const MANUAL_SETUP_INSTRUCTIONS = [
32
+ ``,
33
+ `No problem. To finish setup:`,
34
+ ``,
35
+ ` 1. Get a key from https://console.anthropic.com/settings/keys`,
36
+ ` 2. Add a line to your .env file:`,
37
+ ` ANTHROPIC_API_KEY=sk-ant-...`,
38
+ ` 3. Re-run the command.`,
39
+ ``
40
+ ].join(`\n`);
41
+ function defaultPromptIO() {
42
+ return {
43
+ input: process.stdin,
44
+ output: process.stdout,
45
+ isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
46
+ cwd: process.cwd(),
47
+ exit: process.exit.bind(process)
48
+ };
49
+ }
50
+ async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
51
+ try {
52
+ return require_env.resolveAnthropicApiKey(options);
53
+ } catch (error) {
54
+ if (!io.isTTY) throw error;
55
+ }
56
+ io.output.write(FRIENDLY_INTRO);
57
+ const rl = (0, node_readline_promises.createInterface)({
58
+ input: io.input,
59
+ output: io.output
60
+ });
61
+ try {
62
+ const choice = (await rl.question(`Enter 1/2: `)).trim();
63
+ if (choice === `1`) {
64
+ io.output.write(MANUAL_SETUP_INSTRUCTIONS);
65
+ io.exit(0);
66
+ throw new Error(`unreachable`);
67
+ }
68
+ if (choice === `2`) {
69
+ const key = (await rl.question(`Paste your ANTHROPIC_API_KEY: `)).trim();
70
+ if (!key) throw new Error(`No API key provided. Re-run the command and try again.`);
71
+ const envPath = writeApiKeyToDotEnv(key, io.cwd);
72
+ process.env.ANTHROPIC_API_KEY = key;
73
+ io.output.write(`\nSaved ANTHROPIC_API_KEY to ${envPath}\n\n`);
74
+ return key;
75
+ }
76
+ throw new Error(`Unrecognized choice ${JSON.stringify(choice)}. Please re-run the command and enter 1 or 2.`);
77
+ } finally {
78
+ rl.close();
79
+ }
80
+ }
81
+ function writeApiKeyToDotEnv(key, cwd) {
82
+ const envPath = (0, node_path.resolve)(cwd, `.env`);
83
+ const newLine = `ANTHROPIC_API_KEY=${key}`;
84
+ if (!(0, node_fs.existsSync)(envPath)) {
85
+ (0, node_fs.writeFileSync)(envPath, `${newLine}\n`, `utf8`);
86
+ return envPath;
87
+ }
88
+ const existing = (0, node_fs.readFileSync)(envPath, `utf8`);
89
+ const replaced = existing.replace(/^ANTHROPIC_API_KEY=.*$/m, newLine);
90
+ if (replaced !== existing) {
91
+ (0, node_fs.writeFileSync)(envPath, replaced, `utf8`);
92
+ return envPath;
93
+ }
94
+ const separator = existing.length === 0 || existing.endsWith(`\n`) ? `` : `\n`;
95
+ (0, node_fs.writeFileSync)(envPath, `${existing}${separator}${newLine}\n`, `utf8`);
96
+ return envPath;
97
+ }
98
+
99
+ //#endregion
12
100
  //#region src/index.ts
13
101
  const DEFAULT_ELECTRIC_AGENTS_URL = `http://localhost:4437`;
14
102
  var CliError = class extends Error {};
@@ -257,6 +345,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
257
345
  return started;
258
346
  },
259
347
  startBuiltin: async (options) => {
348
+ options.anthropicApiKey = await ensureAnthropicApiKey(options);
260
349
  const { startBuiltinAgentsServer } = await loadStartModule();
261
350
  return startBuiltinAgentsServer(options, { agentServerUrl: env.electricAgentsUrl });
262
351
  },
@@ -267,7 +356,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
267
356
  return stopped;
268
357
  },
269
358
  quickstart: async (options) => {
270
- require_env.resolveAnthropicApiKey(options);
359
+ options.anthropicApiKey = await ensureAnthropicApiKey(options);
271
360
  const { startBuiltinAgentsServer, startElectricAgentsDevEnvironment } = await loadStartModule();
272
361
  const started = await startElectricAgentsDevEnvironment();
273
362
  printStartedEnvironment(started);
package/dist/index.js CHANGED
@@ -1,12 +1,100 @@
1
1
  #!/usr/bin/env node
2
2
  import { installCompletions, setupCompletions } from "./completions-B-Lf28Wy.js";
3
3
  import { resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-LZtIfFz1.js";
4
- import { realpathSync } from "node:fs";
4
+ import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
5
5
  import { hostname, userInfo } from "node:os";
6
6
  import { basename, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { Command } from "commander";
9
+ import { createInterface } from "node:readline/promises";
9
10
 
11
+ //#region src/prompt-api-key.ts
12
+ const FRIENDLY_INTRO = [
13
+ ``,
14
+ `The Electric Agents quickstart requires setting an API key to connect to an LLM provider.`,
15
+ ``,
16
+ `Currently (in this initial developer preview release) the key must be an ANTHROPIC_API_KEY.`,
17
+ `Support for other LLM providers is coming very soon.`,
18
+ ``,
19
+ `Note that your API key never leaves your local computer. It's used by the agent entities`,
20
+ `installed by default in the Electric Agents runtime and by the example agents included`,
21
+ `in the quickstart template.`,
22
+ ``,
23
+ `Would you like to:`,
24
+ ``,
25
+ ` 1. manually setup a .env file with ANTHROPIC_API_KEY=...`,
26
+ ` 2. paste your api key into a prompt and we'll set it up for you`,
27
+ ``
28
+ ].join(`\n`);
29
+ const MANUAL_SETUP_INSTRUCTIONS = [
30
+ ``,
31
+ `No problem. To finish setup:`,
32
+ ``,
33
+ ` 1. Get a key from https://console.anthropic.com/settings/keys`,
34
+ ` 2. Add a line to your .env file:`,
35
+ ` ANTHROPIC_API_KEY=sk-ant-...`,
36
+ ` 3. Re-run the command.`,
37
+ ``
38
+ ].join(`\n`);
39
+ function defaultPromptIO() {
40
+ return {
41
+ input: process.stdin,
42
+ output: process.stdout,
43
+ isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
44
+ cwd: process.cwd(),
45
+ exit: process.exit.bind(process)
46
+ };
47
+ }
48
+ async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
49
+ try {
50
+ return resolveAnthropicApiKey(options);
51
+ } catch (error) {
52
+ if (!io.isTTY) throw error;
53
+ }
54
+ io.output.write(FRIENDLY_INTRO);
55
+ const rl = createInterface({
56
+ input: io.input,
57
+ output: io.output
58
+ });
59
+ try {
60
+ const choice = (await rl.question(`Enter 1/2: `)).trim();
61
+ if (choice === `1`) {
62
+ io.output.write(MANUAL_SETUP_INSTRUCTIONS);
63
+ io.exit(0);
64
+ throw new Error(`unreachable`);
65
+ }
66
+ if (choice === `2`) {
67
+ const key = (await rl.question(`Paste your ANTHROPIC_API_KEY: `)).trim();
68
+ if (!key) throw new Error(`No API key provided. Re-run the command and try again.`);
69
+ const envPath = writeApiKeyToDotEnv(key, io.cwd);
70
+ process.env.ANTHROPIC_API_KEY = key;
71
+ io.output.write(`\nSaved ANTHROPIC_API_KEY to ${envPath}\n\n`);
72
+ return key;
73
+ }
74
+ throw new Error(`Unrecognized choice ${JSON.stringify(choice)}. Please re-run the command and enter 1 or 2.`);
75
+ } finally {
76
+ rl.close();
77
+ }
78
+ }
79
+ function writeApiKeyToDotEnv(key, cwd) {
80
+ const envPath = resolve(cwd, `.env`);
81
+ const newLine = `ANTHROPIC_API_KEY=${key}`;
82
+ if (!existsSync(envPath)) {
83
+ writeFileSync(envPath, `${newLine}\n`, `utf8`);
84
+ return envPath;
85
+ }
86
+ const existing = readFileSync(envPath, `utf8`);
87
+ const replaced = existing.replace(/^ANTHROPIC_API_KEY=.*$/m, newLine);
88
+ if (replaced !== existing) {
89
+ writeFileSync(envPath, replaced, `utf8`);
90
+ return envPath;
91
+ }
92
+ const separator = existing.length === 0 || existing.endsWith(`\n`) ? `` : `\n`;
93
+ writeFileSync(envPath, `${existing}${separator}${newLine}\n`, `utf8`);
94
+ return envPath;
95
+ }
96
+
97
+ //#endregion
10
98
  //#region src/index.ts
11
99
  const DEFAULT_ELECTRIC_AGENTS_URL = `http://localhost:4437`;
12
100
  var CliError = class extends Error {};
@@ -255,6 +343,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
255
343
  return started;
256
344
  },
257
345
  startBuiltin: async (options) => {
346
+ options.anthropicApiKey = await ensureAnthropicApiKey(options);
258
347
  const { startBuiltinAgentsServer } = await loadStartModule();
259
348
  return startBuiltinAgentsServer(options, { agentServerUrl: env.electricAgentsUrl });
260
349
  },
@@ -265,7 +354,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
265
354
  return stopped;
266
355
  },
267
356
  quickstart: async (options) => {
268
- resolveAnthropicApiKey(options);
357
+ options.anthropicApiKey = await ensureAnthropicApiKey(options);
269
358
  const { startBuiltinAgentsServer, startElectricAgentsDevEnvironment } = await loadStartModule();
270
359
  const started = await startElectricAgentsDevEnvironment();
271
360
  printStartedEnvironment(started);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electric-ax",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "CLI for Electric Agents",
5
5
  "author": "ElectricSQL team and contributors",
6
6
  "license": "Apache-2.0",
@@ -39,15 +39,15 @@
39
39
  "dependencies": {
40
40
  "@durable-streams/client": "npm:@electric-ax/durable-streams-client-beta@^0.3.0",
41
41
  "@durable-streams/state": "npm:@electric-ax/durable-streams-state-beta@^0.3.0",
42
- "@electric-sql/client": "^1.5.14",
42
+ "@electric-sql/client": "^1.5.16",
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.2.2",
50
- "@electric-ax/agents-runtime": "0.1.1"
49
+ "@electric-ax/agents": "0.2.3",
50
+ "@electric-ax/agents-runtime": "0.1.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@vitest/coverage-v8": "^4.1.0",