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 +96 -7
- package/dist/index.js +97 -8
- package/dist/init.cjs +1 -1
- package/dist/init.js +1 -1
- package/package.json +2 -2
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}
|
|
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
|
|
69
|
-
if (userAgent.startsWith(`npm/`)) return `npx electric-ax
|
|
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
|
-
|
|
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(`
|
|
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}
|
|
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}
|
|
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}
|
|
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
|
|
67
|
-
if (userAgent.startsWith(`npm/`)) return `npx electric-ax
|
|
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
|
-
|
|
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(`
|
|
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}
|
|
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}
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
49
|
+
"@electric-ax/agents": "0.2.2",
|
|
50
50
|
"@electric-ax/agents-runtime": "0.1.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|