electric-ax 0.1.12 → 0.1.14

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 {};
@@ -60,13 +148,13 @@ function resolveCommandName(argv) {
60
148
  return invoked.replace(/\.(c|m)?js$/, ``);
61
149
  }
62
150
  function commandExample(commandName) {
63
- return `${commandName} agent`;
151
+ return `${commandName} agents`;
64
152
  }
65
153
  function resolveCommandPrefix(argv, env = process.env) {
66
154
  if (env.npm_command === `exec`) {
67
155
  const userAgent = env.npm_config_user_agent ?? ``;
68
- if (userAgent.startsWith(`pnpm/`)) return `pnpx electric-ax agent`;
69
- if (userAgent.startsWith(`npm/`)) return `npx electric-ax agent`;
156
+ if (userAgent.startsWith(`pnpm/`)) return `pnpx electric-ax agents`;
157
+ if (userAgent.startsWith(`npm/`)) return `npx electric-ax agents`;
70
158
  }
71
159
  return commandExample(resolveCommandName(argv));
72
160
  }
@@ -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);
@@ -313,7 +402,7 @@ Examples:
313
402
  function createElectricProgram({ env = getElectricCliEnv(), commandName = `electric`, commandPrefix = commandExample(commandName), handlers = createElectricCliHandlers(env, commandPrefix) } = {}) {
314
403
  const program = new commander.Command();
315
404
  program.name(commandName).description(`Manage Electric tooling`).showHelpAfterError().showSuggestionAfterError().addHelpText(`after`, getHelpText(commandName));
316
- const agentsCommand = program.command(`agent`).alias(`agents`).description(`Manage Electric Agents`);
405
+ const agentsCommand = program.command(`agents`).description(`Manage Electric Agents`);
317
406
  const typesCommand = agentsCommand.command(`types`).description(`List entity types`).action(async () => {
318
407
  await handlers.listTypes();
319
408
  });
@@ -378,7 +467,7 @@ Setup (add to your shell init file):
378
467
  Fish: ${commandName} --completion-fish | source # add to config.fish
379
468
 
380
469
  Auto-install (detects your shell and updates init file):
381
- ${commandName} agent completion install
470
+ ${commandName} agents completion install
382
471
  `).action((action) => {
383
472
  if (action === `install`) {
384
473
  try {
@@ -393,7 +482,7 @@ Auto-install (detects your shell and updates init file):
393
482
  console.log(`Add to your shell init file:`);
394
483
  console.log(` Bash/Zsh: eval "$(${commandName} --completion)"`);
395
484
  console.log(` Fish: ${commandName} --completion-fish | source\n`);
396
- console.log(`Or auto-install: ${commandName} agent completion install`);
485
+ console.log(`Or auto-install: ${commandName} agents completion install`);
397
486
  });
398
487
  completionCommand.alias(`completions`);
399
488
  return program;
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 {};
@@ -58,13 +146,13 @@ function resolveCommandName(argv) {
58
146
  return invoked.replace(/\.(c|m)?js$/, ``);
59
147
  }
60
148
  function commandExample(commandName) {
61
- return `${commandName} agent`;
149
+ return `${commandName} agents`;
62
150
  }
63
151
  function resolveCommandPrefix(argv, env = process.env) {
64
152
  if (env.npm_command === `exec`) {
65
153
  const userAgent = env.npm_config_user_agent ?? ``;
66
- if (userAgent.startsWith(`pnpm/`)) return `pnpx electric-ax agent`;
67
- if (userAgent.startsWith(`npm/`)) return `npx electric-ax agent`;
154
+ if (userAgent.startsWith(`pnpm/`)) return `pnpx electric-ax agents`;
155
+ if (userAgent.startsWith(`npm/`)) return `npx electric-ax agents`;
68
156
  }
69
157
  return commandExample(resolveCommandName(argv));
70
158
  }
@@ -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);
@@ -311,7 +400,7 @@ Examples:
311
400
  function createElectricProgram({ env = getElectricCliEnv(), commandName = `electric`, commandPrefix = commandExample(commandName), handlers = createElectricCliHandlers(env, commandPrefix) } = {}) {
312
401
  const program = new Command();
313
402
  program.name(commandName).description(`Manage Electric tooling`).showHelpAfterError().showSuggestionAfterError().addHelpText(`after`, getHelpText(commandName));
314
- const agentsCommand = program.command(`agent`).alias(`agents`).description(`Manage Electric Agents`);
403
+ const agentsCommand = program.command(`agents`).description(`Manage Electric Agents`);
315
404
  const typesCommand = agentsCommand.command(`types`).description(`List entity types`).action(async () => {
316
405
  await handlers.listTypes();
317
406
  });
@@ -376,7 +465,7 @@ Setup (add to your shell init file):
376
465
  Fish: ${commandName} --completion-fish | source # add to config.fish
377
466
 
378
467
  Auto-install (detects your shell and updates init file):
379
- ${commandName} agent completion install
468
+ ${commandName} agents completion install
380
469
  `).action((action) => {
381
470
  if (action === `install`) {
382
471
  try {
@@ -391,7 +480,7 @@ Auto-install (detects your shell and updates init file):
391
480
  console.log(`Add to your shell init file:`);
392
481
  console.log(` Bash/Zsh: eval "$(${commandName} --completion)"`);
393
482
  console.log(` Fish: ${commandName} --completion-fish | source\n`);
394
- console.log(`Or auto-install: ${commandName} agent completion install`);
483
+ console.log(`Or auto-install: ${commandName} agents completion install`);
395
484
  });
396
485
  completionCommand.alias(`completions`);
397
486
  return program;
package/dist/init.cjs CHANGED
@@ -35,7 +35,7 @@ async function initProject(projectName) {
35
35
  console.log(`Get one at https://console.anthropic.com/settings/keys`);
36
36
  console.log(``);
37
37
  console.log(`Start infrastructure and run:`);
38
- console.log(` npx electric-ax agent quickstart # in one terminal`);
38
+ console.log(` npx electric-ax agents quickstart # in one terminal`);
39
39
  console.log(` pnpm dev # in another terminal`);
40
40
  console.log(``);
41
41
  }
package/dist/init.js CHANGED
@@ -33,7 +33,7 @@ async function initProject(projectName) {
33
33
  console.log(`Get one at https://console.anthropic.com/settings/keys`);
34
34
  console.log(``);
35
35
  console.log(`Start infrastructure and run:`);
36
- console.log(` npx electric-ax agent quickstart # in one terminal`);
36
+ console.log(` npx electric-ax agents quickstart # in one terminal`);
37
37
  console.log(` pnpm dev # in another terminal`);
38
38
  console.log(``);
39
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electric-ax",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "CLI for Electric Agents",
5
5
  "author": "ElectricSQL team and contributors",
6
6
  "license": "Apache-2.0",
@@ -46,7 +46,7 @@
46
46
  "ink": "^6.8.0",
47
47
  "omelette": "^0.4.17",
48
48
  "react": "^19.2.0",
49
- "@electric-ax/agents": "0.2.1",
49
+ "@electric-ax/agents": "0.2.2",
50
50
  "@electric-ax/agents-runtime": "0.1.1"
51
51
  },
52
52
  "devDependencies": {