@boxcrew/cli 0.1.15 → 0.1.17
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 +176 -118
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { createRequire } from "module";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
|
|
6
7
|
// src/commands/login.ts
|
|
@@ -103,6 +104,10 @@ function registerLogoutCommand(program2) {
|
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
// src/commands/agents.ts
|
|
108
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
109
|
+
import { homedir as homedir2 } from "os";
|
|
110
|
+
|
|
106
111
|
// src/client.ts
|
|
107
112
|
function getBaseUrl() {
|
|
108
113
|
return process.env.BOXCREW_API_URL || config.get("apiUrl");
|
|
@@ -141,6 +146,64 @@ async function apiFetchJson(path, options = {}) {
|
|
|
141
146
|
return response.json();
|
|
142
147
|
}
|
|
143
148
|
|
|
149
|
+
// src/lib/state.ts
|
|
150
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync } from "fs";
|
|
151
|
+
import { join } from "path";
|
|
152
|
+
import { homedir } from "os";
|
|
153
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
154
|
+
var RUNTIME_NAMES = {
|
|
155
|
+
"claude-code": "Claude Code",
|
|
156
|
+
"opencode": "OpenCode",
|
|
157
|
+
"openclaw": "OpenClaw"
|
|
158
|
+
};
|
|
159
|
+
function getStateDir() {
|
|
160
|
+
const dir = join(homedir(), ".boxcrew");
|
|
161
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
162
|
+
return dir;
|
|
163
|
+
}
|
|
164
|
+
function getPidFile(key) {
|
|
165
|
+
return join(getStateDir(), `${key}.pid`);
|
|
166
|
+
}
|
|
167
|
+
function getMetaFile(key) {
|
|
168
|
+
return join(getStateDir(), `${key}.meta.json`);
|
|
169
|
+
}
|
|
170
|
+
function getLogFile(key) {
|
|
171
|
+
return join(getStateDir(), `${key}.log`);
|
|
172
|
+
}
|
|
173
|
+
function readMeta(key) {
|
|
174
|
+
const metaFile = getMetaFile(key);
|
|
175
|
+
if (!existsSync(metaFile)) return null;
|
|
176
|
+
try {
|
|
177
|
+
return JSON.parse(readFileSync(metaFile, "utf-8"));
|
|
178
|
+
} catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function readPid(key) {
|
|
183
|
+
const pidFile = getPidFile(key);
|
|
184
|
+
if (!existsSync(pidFile)) return null;
|
|
185
|
+
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
186
|
+
if (isNaN(pid)) return null;
|
|
187
|
+
try {
|
|
188
|
+
process.kill(pid, 0);
|
|
189
|
+
return pid;
|
|
190
|
+
} catch {
|
|
191
|
+
unlinkSync(pidFile);
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function resolveAgentKey(nameOrId) {
|
|
196
|
+
if (UUID_RE.test(nameOrId)) return nameOrId;
|
|
197
|
+
const stateDir = getStateDir();
|
|
198
|
+
const metaFiles = readdirSync(stateDir).filter((f) => f.endsWith(".meta.json"));
|
|
199
|
+
for (const file of metaFiles) {
|
|
200
|
+
const key = file.replace(".meta.json", "");
|
|
201
|
+
const meta = readMeta(key);
|
|
202
|
+
if (meta && meta.agentName === nameOrId) return key;
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
144
207
|
// src/commands/agents.ts
|
|
145
208
|
var TRANSIENT_CODES = [
|
|
146
209
|
"ETIMEDOUT",
|
|
@@ -164,10 +227,55 @@ function registerAgentsCommands(program2) {
|
|
|
164
227
|
console.log("No agents found.");
|
|
165
228
|
return;
|
|
166
229
|
}
|
|
167
|
-
|
|
230
|
+
const home = homedir2();
|
|
231
|
+
const shortenPath = (p) => p.startsWith(home) ? "~" + p.slice(home.length) : p;
|
|
232
|
+
const localMeta = /* @__PURE__ */ new Map();
|
|
233
|
+
try {
|
|
234
|
+
const stateDir = getStateDir();
|
|
235
|
+
const metaFiles = readdirSync2(stateDir).filter((f) => f.endsWith(".meta.json"));
|
|
236
|
+
for (const file of metaFiles) {
|
|
237
|
+
const key = file.replace(".meta.json", "");
|
|
238
|
+
const meta = readMeta(key);
|
|
239
|
+
if (meta) {
|
|
240
|
+
localMeta.set(meta.agentId, { pid: readPid(key), cwd: meta.cwd });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
const rows = [];
|
|
168
246
|
for (const agent of data) {
|
|
169
|
-
const
|
|
170
|
-
|
|
247
|
+
const shortId = agent.id.slice(0, 8);
|
|
248
|
+
const typeDisplay = agent.agent_type === "remote" ? "BYOA" : "hosted";
|
|
249
|
+
const runtimeDisplay = RUNTIME_NAMES[agent.runtime] || agent.runtime;
|
|
250
|
+
let status;
|
|
251
|
+
let directory = "-";
|
|
252
|
+
if (agent.agent_type !== "remote") {
|
|
253
|
+
status = "-";
|
|
254
|
+
} else {
|
|
255
|
+
const local = localMeta.get(agent.id);
|
|
256
|
+
if (local?.pid) {
|
|
257
|
+
status = "online (here)";
|
|
258
|
+
directory = shortenPath(local.cwd);
|
|
259
|
+
} else if (agent.is_online) {
|
|
260
|
+
status = "online";
|
|
261
|
+
} else {
|
|
262
|
+
status = "offline";
|
|
263
|
+
if (local?.cwd) directory = shortenPath(local.cwd);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
rows.push({ name: agent.name, id: shortId, type: typeDisplay, runtime: runtimeDisplay, status, directory });
|
|
267
|
+
}
|
|
268
|
+
const headers = { name: "Name", id: "ID", type: "Type", runtime: "Runtime", status: "Status", directory: "Directory" };
|
|
269
|
+
const cols = Object.keys(headers);
|
|
270
|
+
const widths = {};
|
|
271
|
+
for (const col of cols) {
|
|
272
|
+
widths[col] = Math.max(headers[col].length, ...rows.map((r) => r[col].length));
|
|
273
|
+
}
|
|
274
|
+
const pad = (s, w) => s + " ".repeat(w - s.length);
|
|
275
|
+
console.log("");
|
|
276
|
+
console.log(` ${cols.map((c) => pad(headers[c], widths[c])).join(" ")}`);
|
|
277
|
+
for (const row of rows) {
|
|
278
|
+
console.log(` ${cols.map((c) => pad(row[c], widths[c])).join(" ")}`);
|
|
171
279
|
}
|
|
172
280
|
console.log("");
|
|
173
281
|
});
|
|
@@ -359,53 +467,12 @@ function registerApiCommand(program2) {
|
|
|
359
467
|
// src/commands/connect.ts
|
|
360
468
|
import { spawn } from "child_process";
|
|
361
469
|
import { createInterface as createInterface3 } from "readline";
|
|
362
|
-
import { openSync,
|
|
363
|
-
import { join } from "path";
|
|
364
|
-
import { homedir, platform, release, hostname } from "os";
|
|
470
|
+
import { openSync, existsSync as existsSync2, writeFileSync, unlinkSync as unlinkSync2, readdirSync as readdirSync3, renameSync } from "fs";
|
|
471
|
+
import { join as join2 } from "path";
|
|
472
|
+
import { homedir as homedir3, platform, release, hostname } from "os";
|
|
365
473
|
import WebSocket from "ws";
|
|
366
474
|
var RECONNECT_BASE_MS = 1e3;
|
|
367
475
|
var RECONNECT_MAX_MS = 3e4;
|
|
368
|
-
var RUNTIME_NAMES = {
|
|
369
|
-
"claude-code": "Claude Code",
|
|
370
|
-
"opencode": "OpenCode",
|
|
371
|
-
"openclaw": "OpenClaw"
|
|
372
|
-
};
|
|
373
|
-
function getStateDir() {
|
|
374
|
-
const dir = join(homedir(), ".boxcrew");
|
|
375
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
376
|
-
return dir;
|
|
377
|
-
}
|
|
378
|
-
function getPidFile(agentName) {
|
|
379
|
-
return join(getStateDir(), `${agentName}.pid`);
|
|
380
|
-
}
|
|
381
|
-
function getMetaFile(agentName) {
|
|
382
|
-
return join(getStateDir(), `${agentName}.meta.json`);
|
|
383
|
-
}
|
|
384
|
-
function readMeta(agentName) {
|
|
385
|
-
const metaFile = getMetaFile(agentName);
|
|
386
|
-
if (!existsSync(metaFile)) return null;
|
|
387
|
-
try {
|
|
388
|
-
return JSON.parse(readFileSync(metaFile, "utf-8"));
|
|
389
|
-
} catch {
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
function getLogFile(agentName) {
|
|
394
|
-
return join(getStateDir(), `${agentName}.log`);
|
|
395
|
-
}
|
|
396
|
-
function readPid(agentName) {
|
|
397
|
-
const pidFile = getPidFile(agentName);
|
|
398
|
-
if (!existsSync(pidFile)) return null;
|
|
399
|
-
const pid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
400
|
-
if (isNaN(pid)) return null;
|
|
401
|
-
try {
|
|
402
|
-
process.kill(pid, 0);
|
|
403
|
-
return pid;
|
|
404
|
-
} catch {
|
|
405
|
-
unlinkSync(pidFile);
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
476
|
function parseStreamJsonLine(line) {
|
|
410
477
|
let obj;
|
|
411
478
|
try {
|
|
@@ -512,16 +579,16 @@ function parseOpenClawOutput(stdout) {
|
|
|
512
579
|
return [{ kind: "text", text: stdout.trim() || "No response" }];
|
|
513
580
|
}
|
|
514
581
|
}
|
|
515
|
-
function runDaemon(
|
|
582
|
+
function runDaemon(agentId) {
|
|
516
583
|
const wsUrl = process.env._BX_WS_URL;
|
|
517
584
|
const claudePath = process.env._BX_CLAUDE_PATH || "claude";
|
|
518
|
-
const agentDisplayName = process.env._BX_AGENT_NAME ||
|
|
585
|
+
const agentDisplayName = process.env._BX_AGENT_NAME || agentId;
|
|
519
586
|
const runtime = process.env._BX_RUNTIME || "claude-code";
|
|
520
587
|
if (!wsUrl) {
|
|
521
588
|
console.error("Missing _BX_WS_URL");
|
|
522
589
|
process.exit(1);
|
|
523
590
|
}
|
|
524
|
-
writeFileSync(getPidFile(
|
|
591
|
+
writeFileSync(getPidFile(agentId), String(process.pid));
|
|
525
592
|
let activeProcess = null;
|
|
526
593
|
let sendToServer = null;
|
|
527
594
|
let reconnectAttempt = 0;
|
|
@@ -634,7 +701,7 @@ function runDaemon(agentName) {
|
|
|
634
701
|
};
|
|
635
702
|
const cleanup = () => {
|
|
636
703
|
try {
|
|
637
|
-
|
|
704
|
+
unlinkSync2(getPidFile(agentId));
|
|
638
705
|
} catch {
|
|
639
706
|
}
|
|
640
707
|
};
|
|
@@ -678,6 +745,14 @@ function runDaemon(agentName) {
|
|
|
678
745
|
if (msg.type === "chat") {
|
|
679
746
|
handleChat(msg);
|
|
680
747
|
}
|
|
748
|
+
if (msg.type === "rename") {
|
|
749
|
+
const meta = readMeta(agentId);
|
|
750
|
+
if (meta) {
|
|
751
|
+
meta.agentName = msg.newName;
|
|
752
|
+
writeFileSync(getMetaFile(agentId), JSON.stringify(meta, null, 2));
|
|
753
|
+
}
|
|
754
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Agent renamed to "${msg.newName}"`);
|
|
755
|
+
}
|
|
681
756
|
});
|
|
682
757
|
ws.on("close", (code, reason) => {
|
|
683
758
|
sendToServer = null;
|
|
@@ -718,19 +793,27 @@ function runDaemon(agentName) {
|
|
|
718
793
|
connect();
|
|
719
794
|
}
|
|
720
795
|
function registerConnectCommand(program2) {
|
|
721
|
-
program2.command("_daemon <agent-
|
|
722
|
-
runDaemon(
|
|
796
|
+
program2.command("_daemon <agent-id>", { hidden: true }).action((agentId) => {
|
|
797
|
+
runDaemon(agentId);
|
|
723
798
|
});
|
|
724
799
|
program2.command("connect <agent-name>").description("Connect a local agent to BoxCrew.").option("--claude-path <path>", "Path to claude CLI binary", "claude").action(async (agentName, options) => {
|
|
725
|
-
const
|
|
800
|
+
const config2 = await apiFetchJson(
|
|
801
|
+
`/agents/${encodeURIComponent(agentName)}/connection-config`
|
|
802
|
+
);
|
|
803
|
+
const agentId = config2.agent_id;
|
|
804
|
+
if (!existsSync2(getMetaFile(agentId)) && existsSync2(getMetaFile(agentName))) {
|
|
805
|
+
for (const ext of [".meta.json", ".pid", ".log"]) {
|
|
806
|
+
const oldPath = join2(getStateDir(), `${agentName}${ext}`);
|
|
807
|
+
const newPath = join2(getStateDir(), `${agentId}${ext}`);
|
|
808
|
+
if (existsSync2(oldPath)) renameSync(oldPath, newPath);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
const existingPid = readPid(agentId);
|
|
726
812
|
if (existingPid) {
|
|
727
813
|
console.log(`Agent "${agentName}" is already connected (PID ${existingPid}).`);
|
|
728
814
|
return;
|
|
729
815
|
}
|
|
730
|
-
const
|
|
731
|
-
`/agents/${encodeURIComponent(agentName)}/connection-config`
|
|
732
|
-
);
|
|
733
|
-
const logFile = getLogFile(agentName);
|
|
816
|
+
const logFile = getLogFile(agentId);
|
|
734
817
|
const logFd = openSync(logFile, "a");
|
|
735
818
|
const daemonEnv = {
|
|
736
819
|
...process.env,
|
|
@@ -741,7 +824,7 @@ function registerConnectCommand(program2) {
|
|
|
741
824
|
};
|
|
742
825
|
delete daemonEnv.CLAUDECODE;
|
|
743
826
|
delete daemonEnv.CLAUDE_CODE_ENTRYPOINT;
|
|
744
|
-
const child = spawn(process.argv[0], [process.argv[1], "_daemon",
|
|
827
|
+
const child = spawn(process.argv[0], [process.argv[1], "_daemon", agentId], {
|
|
745
828
|
detached: true,
|
|
746
829
|
stdio: ["ignore", logFd, logFd],
|
|
747
830
|
env: daemonEnv
|
|
@@ -751,14 +834,15 @@ function registerConnectCommand(program2) {
|
|
|
751
834
|
pid: child.pid,
|
|
752
835
|
cwd: process.cwd(),
|
|
753
836
|
runtime: config2.runtime,
|
|
837
|
+
agentId,
|
|
754
838
|
agentName: config2.agent_name,
|
|
755
839
|
connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
756
840
|
claudePath: options.claudePath
|
|
757
841
|
};
|
|
758
|
-
writeFileSync(getMetaFile(
|
|
842
|
+
writeFileSync(getMetaFile(agentId), JSON.stringify(meta, null, 2));
|
|
759
843
|
const runtimeDisplay = RUNTIME_NAMES[config2.runtime] || config2.runtime;
|
|
760
844
|
const cwd = process.cwd();
|
|
761
|
-
const home =
|
|
845
|
+
const home = homedir3();
|
|
762
846
|
const shortLog = logFile.startsWith(home) ? "~" + logFile.slice(home.length) : logFile;
|
|
763
847
|
console.log("");
|
|
764
848
|
console.log(` Agent "${config2.agent_name}" is online.`);
|
|
@@ -771,7 +855,12 @@ function registerConnectCommand(program2) {
|
|
|
771
855
|
console.log("");
|
|
772
856
|
});
|
|
773
857
|
program2.command("disconnect <agent-name>").description("Disconnect a local agent.").action((agentName) => {
|
|
774
|
-
const
|
|
858
|
+
const key = resolveAgentKey(agentName);
|
|
859
|
+
if (!key) {
|
|
860
|
+
console.log(`Agent "${agentName}" is not connected.`);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const pid = readPid(key);
|
|
775
864
|
if (!pid) {
|
|
776
865
|
console.log(`Agent "${agentName}" is not connected.`);
|
|
777
866
|
return;
|
|
@@ -779,7 +868,7 @@ function registerConnectCommand(program2) {
|
|
|
779
868
|
try {
|
|
780
869
|
process.kill(pid, "SIGTERM");
|
|
781
870
|
try {
|
|
782
|
-
|
|
871
|
+
unlinkSync2(getPidFile(key));
|
|
783
872
|
} catch {
|
|
784
873
|
}
|
|
785
874
|
console.log(`Agent "${agentName}" disconnected.`);
|
|
@@ -787,57 +876,17 @@ function registerConnectCommand(program2) {
|
|
|
787
876
|
console.error(`Failed to stop process ${pid}.`);
|
|
788
877
|
}
|
|
789
878
|
});
|
|
790
|
-
program2.command("status").description("Show status of all locally connected agents.").action(() => {
|
|
791
|
-
const stateDir = getStateDir();
|
|
792
|
-
const metaFiles = readdirSync(stateDir).filter((f) => f.endsWith(".meta.json"));
|
|
793
|
-
if (metaFiles.length === 0) {
|
|
794
|
-
console.log("No agents found. Use `bx connect <agent-name>` to connect one.");
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
const home = homedir();
|
|
798
|
-
const shortenPath = (p) => p.startsWith(home) ? "~" + p.slice(home.length) : p;
|
|
799
|
-
const rows = [];
|
|
800
|
-
for (const file of metaFiles) {
|
|
801
|
-
const agentName = file.replace(".meta.json", "");
|
|
802
|
-
const meta = readMeta(agentName);
|
|
803
|
-
if (!meta) continue;
|
|
804
|
-
const pid = readPid(agentName);
|
|
805
|
-
const isOnline = pid !== null;
|
|
806
|
-
rows.push({
|
|
807
|
-
agent: meta.agentName || agentName,
|
|
808
|
-
status: isOnline ? "online" : "offline",
|
|
809
|
-
runtime: RUNTIME_NAMES[meta.runtime] || meta.runtime,
|
|
810
|
-
directory: shortenPath(meta.cwd),
|
|
811
|
-
pid: isOnline ? String(pid) : "-"
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
const headers = { agent: "Agent", status: "Status", runtime: "Runtime", directory: "Directory", pid: "PID" };
|
|
815
|
-
const cols = Object.keys(headers);
|
|
816
|
-
const widths = {};
|
|
817
|
-
for (const col of cols) {
|
|
818
|
-
widths[col] = Math.max(headers[col].length, ...rows.map((r) => r[col].length));
|
|
819
|
-
}
|
|
820
|
-
const pad = (s, w) => s + " ".repeat(w - s.length);
|
|
821
|
-
const headerLine = cols.map((c) => pad(headers[c], widths[c])).join(" ");
|
|
822
|
-
console.log("");
|
|
823
|
-
console.log(` ${headerLine}`);
|
|
824
|
-
for (const row of rows) {
|
|
825
|
-
const line = cols.map((c) => pad(row[c], widths[c])).join(" ");
|
|
826
|
-
console.log(` ${line}`);
|
|
827
|
-
}
|
|
828
|
-
console.log("");
|
|
829
|
-
});
|
|
830
879
|
program2.command("reconnect [agent-name]").description("Reconnect a previously connected agent.").option("--all", "Reconnect all agents").option("--claude-path <path>", "Path to claude CLI binary").action(async (agentName, options) => {
|
|
831
880
|
if (options.all) {
|
|
832
881
|
const stateDir = getStateDir();
|
|
833
|
-
const metaFiles =
|
|
882
|
+
const metaFiles = readdirSync3(stateDir).filter((f) => f.endsWith(".meta.json"));
|
|
834
883
|
if (metaFiles.length === 0) {
|
|
835
884
|
console.log("No agents found. Use `bx connect <agent-name>` to connect one.");
|
|
836
885
|
return;
|
|
837
886
|
}
|
|
838
887
|
for (const file of metaFiles) {
|
|
839
|
-
const
|
|
840
|
-
await reconnectAgent(
|
|
888
|
+
const key2 = file.replace(".meta.json", "");
|
|
889
|
+
await reconnectAgent(key2, options.claudePath);
|
|
841
890
|
}
|
|
842
891
|
return;
|
|
843
892
|
}
|
|
@@ -845,30 +894,36 @@ function registerConnectCommand(program2) {
|
|
|
845
894
|
console.error("Please specify an agent name or use --all.");
|
|
846
895
|
process.exit(1);
|
|
847
896
|
}
|
|
848
|
-
|
|
897
|
+
const key = resolveAgentKey(agentName);
|
|
898
|
+
if (!key) {
|
|
899
|
+
console.error(`No previous connection found for "${agentName}". Use \`bx connect ${agentName}\` instead.`);
|
|
900
|
+
process.exit(1);
|
|
901
|
+
}
|
|
902
|
+
await reconnectAgent(key, options.claudePath);
|
|
849
903
|
});
|
|
850
|
-
async function reconnectAgent(
|
|
851
|
-
const meta = readMeta(
|
|
904
|
+
async function reconnectAgent(key, claudePathOverride) {
|
|
905
|
+
const meta = readMeta(key);
|
|
852
906
|
if (!meta) {
|
|
853
|
-
console.error(`No previous connection found for "${
|
|
907
|
+
console.error(`No previous connection found for "${key}". Use \`bx connect <agent-name>\` instead.`);
|
|
854
908
|
return;
|
|
855
909
|
}
|
|
856
|
-
const existingPid = readPid(
|
|
910
|
+
const existingPid = readPid(key);
|
|
857
911
|
if (existingPid) {
|
|
858
912
|
try {
|
|
859
913
|
process.kill(existingPid, "SIGTERM");
|
|
860
914
|
} catch {
|
|
861
915
|
}
|
|
862
916
|
try {
|
|
863
|
-
|
|
917
|
+
unlinkSync2(getPidFile(key));
|
|
864
918
|
} catch {
|
|
865
919
|
}
|
|
866
920
|
}
|
|
921
|
+
const agentId = meta.agentId || key;
|
|
867
922
|
const config2 = await apiFetchJson(
|
|
868
|
-
`/agents/${encodeURIComponent(
|
|
923
|
+
`/agents/${encodeURIComponent(agentId)}/connection-config`
|
|
869
924
|
);
|
|
870
925
|
const claudePath = claudePathOverride || meta.claudePath || "claude";
|
|
871
|
-
const logFile = getLogFile(
|
|
926
|
+
const logFile = getLogFile(key);
|
|
872
927
|
const logFd = openSync(logFile, "a");
|
|
873
928
|
const daemonEnv = {
|
|
874
929
|
...process.env,
|
|
@@ -879,7 +934,7 @@ function registerConnectCommand(program2) {
|
|
|
879
934
|
};
|
|
880
935
|
delete daemonEnv.CLAUDECODE;
|
|
881
936
|
delete daemonEnv.CLAUDE_CODE_ENTRYPOINT;
|
|
882
|
-
const child = spawn(process.argv[0], [process.argv[1], "_daemon",
|
|
937
|
+
const child = spawn(process.argv[0], [process.argv[1], "_daemon", key], {
|
|
883
938
|
detached: true,
|
|
884
939
|
stdio: ["ignore", logFd, logFd],
|
|
885
940
|
cwd: meta.cwd,
|
|
@@ -890,13 +945,14 @@ function registerConnectCommand(program2) {
|
|
|
890
945
|
pid: child.pid,
|
|
891
946
|
cwd: meta.cwd,
|
|
892
947
|
runtime: config2.runtime,
|
|
948
|
+
agentId: config2.agent_id,
|
|
893
949
|
agentName: config2.agent_name,
|
|
894
950
|
connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
895
951
|
claudePath
|
|
896
952
|
};
|
|
897
|
-
writeFileSync(getMetaFile(
|
|
953
|
+
writeFileSync(getMetaFile(key), JSON.stringify(newMeta, null, 2));
|
|
898
954
|
const runtimeDisplay = RUNTIME_NAMES[config2.runtime] || config2.runtime;
|
|
899
|
-
const home =
|
|
955
|
+
const home = homedir3();
|
|
900
956
|
const shortCwd = meta.cwd.startsWith(home) ? "~" + meta.cwd.slice(home.length) : meta.cwd;
|
|
901
957
|
const shortLog = logFile.startsWith(home) ? "~" + logFile.slice(home.length) : logFile;
|
|
902
958
|
console.log("");
|
|
@@ -910,7 +966,9 @@ function registerConnectCommand(program2) {
|
|
|
910
966
|
}
|
|
911
967
|
|
|
912
968
|
// src/index.ts
|
|
913
|
-
var
|
|
969
|
+
var require2 = createRequire(import.meta.url);
|
|
970
|
+
var { version } = require2("../package.json");
|
|
971
|
+
var program = new Command().name("bx").description("BoxCrew CLI \u2014 manage your agents from the terminal").version(version);
|
|
914
972
|
registerLoginCommand(program);
|
|
915
973
|
registerLogoutCommand(program);
|
|
916
974
|
registerAgentsCommands(program);
|