@boxcrew/cli 0.1.4 → 0.1.5
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.js +56 -45
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/login.ts
|
|
7
|
-
import { createInterface } from "readline";
|
|
8
|
-
import
|
|
7
|
+
import { createInterface as createInterface2 } from "readline";
|
|
8
|
+
import open2 from "open";
|
|
9
9
|
|
|
10
10
|
// src/config.ts
|
|
11
11
|
import Conf from "conf";
|
|
@@ -17,44 +17,19 @@ var config = new Conf({
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
// src/auth.ts
|
|
20
|
+
import { createInterface } from "readline";
|
|
21
|
+
import open from "open";
|
|
22
|
+
var DEFAULT_FRONTEND_URL = "https://boxcrew.ai";
|
|
20
23
|
function getAuthToken() {
|
|
21
24
|
if (process.env.BOXCREW_API_KEY) return process.env.BOXCREW_API_KEY;
|
|
22
25
|
return config.get("apiKey") ?? null;
|
|
23
26
|
}
|
|
24
|
-
function requireAuth() {
|
|
27
|
+
async function requireAuth() {
|
|
25
28
|
const token = getAuthToken();
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
"Not authenticated. Run `bx login` or set the BOXCREW_API_KEY environment variable."
|
|
29
|
-
);
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
return token;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// src/commands/login.ts
|
|
36
|
-
var DEFAULT_FRONTEND_URL = "https://boxcrew.ai";
|
|
37
|
-
function registerLoginCommand(program2) {
|
|
38
|
-
program2.command("login").description("Authenticate with BoxCrew").option("--api-url <url>", "BoxCrew API URL").option(
|
|
39
|
-
"--frontend-url <url>",
|
|
40
|
-
"BoxCrew frontend URL",
|
|
41
|
-
process.env.BOXCREW_FRONTEND_URL || DEFAULT_FRONTEND_URL
|
|
42
|
-
).action(
|
|
43
|
-
async (options) => {
|
|
44
|
-
if (options.apiUrl) {
|
|
45
|
-
config.set("apiUrl", options.apiUrl);
|
|
46
|
-
}
|
|
47
|
-
await ensureLoggedIn(options.frontendUrl);
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
async function ensureLoggedIn(frontendUrl = DEFAULT_FRONTEND_URL) {
|
|
52
|
-
if (getAuthToken()) {
|
|
53
|
-
console.log("Already authenticated.");
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
29
|
+
if (token) return token;
|
|
30
|
+
const frontendUrl = process.env.BOXCREW_FRONTEND_URL || DEFAULT_FRONTEND_URL;
|
|
56
31
|
const authUrl = `${frontendUrl}/cli-auth`;
|
|
57
|
-
console.log("Opening browser to
|
|
32
|
+
console.log("Not authenticated. Opening browser to log in...");
|
|
58
33
|
console.log(`If the browser doesn't open, visit: ${authUrl}
|
|
59
34
|
`);
|
|
60
35
|
open(authUrl).catch(() => {
|
|
@@ -75,6 +50,49 @@ async function ensureLoggedIn(frontendUrl = DEFAULT_FRONTEND_URL) {
|
|
|
75
50
|
}
|
|
76
51
|
config.set("apiKey", apiKey);
|
|
77
52
|
console.log("Authenticated successfully!\n");
|
|
53
|
+
return apiKey;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/commands/login.ts
|
|
57
|
+
var DEFAULT_FRONTEND_URL2 = "https://boxcrew.ai";
|
|
58
|
+
function registerLoginCommand(program2) {
|
|
59
|
+
program2.command("login").description("Authenticate with BoxCrew (or re-authenticate)").option("--api-url <url>", "BoxCrew API URL").option(
|
|
60
|
+
"--frontend-url <url>",
|
|
61
|
+
"BoxCrew frontend URL",
|
|
62
|
+
process.env.BOXCREW_FRONTEND_URL || DEFAULT_FRONTEND_URL2
|
|
63
|
+
).action(
|
|
64
|
+
async (options) => {
|
|
65
|
+
if (options.apiUrl) {
|
|
66
|
+
config.set("apiUrl", options.apiUrl);
|
|
67
|
+
}
|
|
68
|
+
if (getAuthToken()) {
|
|
69
|
+
console.log("Already authenticated. To re-authenticate, continue below.\n");
|
|
70
|
+
}
|
|
71
|
+
const authUrl = `${options.frontendUrl}/cli-auth`;
|
|
72
|
+
console.log("Opening browser to authenticate...");
|
|
73
|
+
console.log(`If the browser doesn't open, visit: ${authUrl}
|
|
74
|
+
`);
|
|
75
|
+
open2(authUrl).catch(() => {
|
|
76
|
+
});
|
|
77
|
+
const rl = createInterface2({
|
|
78
|
+
input: process.stdin,
|
|
79
|
+
output: process.stdout
|
|
80
|
+
});
|
|
81
|
+
const apiKey = await new Promise((resolve) => {
|
|
82
|
+
rl.question("Paste your API key: ", (answer) => {
|
|
83
|
+
rl.close();
|
|
84
|
+
resolve(answer.trim());
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
if (!apiKey.startsWith("bxk_")) {
|
|
88
|
+
console.error('Invalid API key. Keys should start with "bxk_".');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
config.set("apiKey", apiKey);
|
|
92
|
+
console.log("\nAuthenticated successfully!");
|
|
93
|
+
console.log(`API URL: ${config.get("apiUrl")}`);
|
|
94
|
+
}
|
|
95
|
+
);
|
|
78
96
|
}
|
|
79
97
|
|
|
80
98
|
// src/commands/logout.ts
|
|
@@ -90,7 +108,7 @@ function getBaseUrl() {
|
|
|
90
108
|
return process.env.BOXCREW_API_URL || config.get("apiUrl");
|
|
91
109
|
}
|
|
92
110
|
async function apiFetch(path, options = {}) {
|
|
93
|
-
const token = requireAuth();
|
|
111
|
+
const token = await requireAuth();
|
|
94
112
|
const baseUrl = getBaseUrl();
|
|
95
113
|
const url = `${baseUrl}${path}`;
|
|
96
114
|
const headers = {
|
|
@@ -340,7 +358,7 @@ function registerApiCommand(program2) {
|
|
|
340
358
|
|
|
341
359
|
// src/commands/connect.ts
|
|
342
360
|
import { spawn } from "child_process";
|
|
343
|
-
import { createInterface as
|
|
361
|
+
import { createInterface as createInterface3 } from "readline";
|
|
344
362
|
import WebSocket from "ws";
|
|
345
363
|
var RECONNECT_BASE_MS = 1e3;
|
|
346
364
|
var RECONNECT_MAX_MS = 3e4;
|
|
@@ -407,14 +425,7 @@ function parseStreamJsonLine(line) {
|
|
|
407
425
|
return null;
|
|
408
426
|
}
|
|
409
427
|
function registerConnectCommand(program2) {
|
|
410
|
-
program2.command("connect <agent-name>").description("Connect a local Claude Code instance to a BoxCrew agent.").option("--claude-path <path>", "Path to claude CLI binary", "claude").
|
|
411
|
-
"--frontend-url <url>",
|
|
412
|
-
"BoxCrew frontend URL",
|
|
413
|
-
process.env.BOXCREW_FRONTEND_URL || "https://boxcrew.ai"
|
|
414
|
-
).action(async (agentName, options) => {
|
|
415
|
-
if (!getAuthToken()) {
|
|
416
|
-
await ensureLoggedIn(options.frontendUrl);
|
|
417
|
-
}
|
|
428
|
+
program2.command("connect <agent-name>").description("Connect a local Claude Code instance to a BoxCrew agent.").option("--claude-path <path>", "Path to claude CLI binary", "claude").action(async (agentName, options) => {
|
|
418
429
|
const config2 = await apiFetchJson(
|
|
419
430
|
`/agents/${encodeURIComponent(agentName)}/connection-config`
|
|
420
431
|
);
|
|
@@ -439,7 +450,7 @@ function registerConnectCommand(program2) {
|
|
|
439
450
|
env: childEnv
|
|
440
451
|
});
|
|
441
452
|
activeProcess = child;
|
|
442
|
-
const rl =
|
|
453
|
+
const rl = createInterface3({ input: child.stdout });
|
|
443
454
|
rl.on("line", (line) => {
|
|
444
455
|
const event = parseStreamJsonLine(line);
|
|
445
456
|
if (event && sendToServer) {
|