@proagentstore/cli 0.4.21 → 0.4.23
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/browser-runner/coding/headless.js +21 -1
- package/dist/browser-runner/runner.js +7 -5
- package/dist/index.js +113 -101
- package/package.json +1 -1
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* Merge the platform's resolved engine env over the machine's, where an EMPTY value means
|
|
4
|
+
* REMOVE rather than "set to empty".
|
|
5
|
+
*
|
|
6
|
+
* Needed because the machine env is inherited wholesale: a developer with ANTHROPIC_API_KEY in
|
|
7
|
+
* their shell handed it to every engine, and Claude Code prefers an API key over the
|
|
8
|
+
* subscription token — so choosing "subscription" injected CLAUDE_CODE_OAUTH_TOKEN and then
|
|
9
|
+
* silently lost, billing per token anyway. Without a way to express removal the setting could
|
|
10
|
+
* not mean what it said.
|
|
11
|
+
*/
|
|
12
|
+
export function mergeEnv(base, overlay) {
|
|
13
|
+
const out = { ...base };
|
|
14
|
+
for (const [k, v] of Object.entries(overlay ?? {})) {
|
|
15
|
+
if (v === "")
|
|
16
|
+
delete out[k];
|
|
17
|
+
else
|
|
18
|
+
out[k] = v;
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
2
22
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
23
|
import { dirname, join } from "node:path";
|
|
4
24
|
import { handlerFor } from "./handlers.js";
|
|
@@ -95,7 +115,7 @@ export class HeadlessSession {
|
|
|
95
115
|
const args = this.mode === "stream-json" ? buildClaudeArgs(this.cmdArgs, this.claudeSessionId) : [...this.cmdArgs];
|
|
96
116
|
const proc = spawn(this.cmdBin, args, {
|
|
97
117
|
cwd: this.config.workDir,
|
|
98
|
-
env:
|
|
118
|
+
env: mergeEnv(process.env, this.config.env),
|
|
99
119
|
stdio: ["pipe", "pipe", "pipe"],
|
|
100
120
|
});
|
|
101
121
|
this.proc = proc;
|
|
@@ -97,10 +97,11 @@ export class LocalRunner {
|
|
|
97
97
|
card.subtitle = normalized.subtitle;
|
|
98
98
|
if (normalized.description)
|
|
99
99
|
card.description = normalized.description;
|
|
100
|
-
// Agent-driven
|
|
101
|
-
// /browser/* endpoints — the runner
|
|
102
|
-
// for the console board, the activity
|
|
103
|
-
|
|
100
|
+
// Agent-driven browser tasks (job applications AND generic browser tasks) are
|
|
101
|
+
// steered by the remote Workflow brain via the /browser/* endpoints — the runner
|
|
102
|
+
// never auto-executes them. The task exists for the console board, the activity
|
|
103
|
+
// trace, and takeover keying.
|
|
104
|
+
if (normalized.type === "job.apply_agent" || normalized.type === "browser.task") {
|
|
104
105
|
const task = {
|
|
105
106
|
id: `task_${crypto.randomUUID()}`,
|
|
106
107
|
type: normalized.type,
|
|
@@ -112,7 +113,8 @@ export class LocalRunner {
|
|
|
112
113
|
updatedAt: now,
|
|
113
114
|
};
|
|
114
115
|
this.store.putTask(task);
|
|
115
|
-
|
|
116
|
+
const startedMsg = normalized.type === "browser.task" ? "Browser task started (agent-driven)" : "Job application started (agent-driven)";
|
|
117
|
+
this.addTaskEvent(task, "task.created", startedMsg, { status: "running", url: normalized.input.url });
|
|
116
118
|
return task;
|
|
117
119
|
}
|
|
118
120
|
const requiresApproval = normalized.requiresApproval || APPROVAL_REQUIRED_TASKS.has(normalized.type);
|
package/dist/index.js
CHANGED
|
@@ -608,16 +608,104 @@ var publishCommand = new Command5("publish").description("Publish an agent to Pr
|
|
|
608
608
|
writeLine();
|
|
609
609
|
});
|
|
610
610
|
|
|
611
|
-
// src/commands/runner.ts
|
|
612
|
-
import { spawn as
|
|
611
|
+
// src/commands/runner/command.ts
|
|
612
|
+
import { spawn as spawn3 } from "child_process";
|
|
613
613
|
import { randomUUID } from "crypto";
|
|
614
|
-
import {
|
|
614
|
+
import { Command as Command6 } from "commander";
|
|
615
|
+
|
|
616
|
+
// src/commands/runner/http.ts
|
|
615
617
|
import { hostname } from "os";
|
|
618
|
+
function clean(value) {
|
|
619
|
+
const trimmed = value?.trim();
|
|
620
|
+
return trimmed || void 0;
|
|
621
|
+
}
|
|
622
|
+
function runnerBaseUrl(url) {
|
|
623
|
+
return (clean(url) || clean(process.env.PAGS_RUNNER_URL) || "http://127.0.0.1:49171").replace(/\/$/, "");
|
|
624
|
+
}
|
|
625
|
+
function pagsApiBase(url) {
|
|
626
|
+
return (clean(url) || clean(process.env.PAGS_API_BASE) || "https://api.proagentstore.online").replace(/\/$/, "");
|
|
627
|
+
}
|
|
628
|
+
function pagsHeaders(token) {
|
|
629
|
+
const resolved = clean(token) || clean(process.env.PAGS_TOKEN) || clean(loadSession()?.token);
|
|
630
|
+
return resolved ? { Authorization: `Bearer ${resolved}` } : {};
|
|
631
|
+
}
|
|
632
|
+
function runnerRequestHeaders(opts) {
|
|
633
|
+
const resolved = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN);
|
|
634
|
+
const headers = resolved ? { Authorization: `Bearer ${resolved}` } : {};
|
|
635
|
+
const instanceId = clean(opts.instanceId) || clean(process.env.PAGS_INSTANCE_ID);
|
|
636
|
+
if (instanceId) headers["X-PAGS-Instance-Id"] = instanceId;
|
|
637
|
+
return headers;
|
|
638
|
+
}
|
|
639
|
+
function apiPathSegment(value) {
|
|
640
|
+
return encodeURIComponent(value);
|
|
641
|
+
}
|
|
642
|
+
function buildRuntimeRegistrationBody(opts, capabilities = []) {
|
|
643
|
+
return {
|
|
644
|
+
endpointUrl: clean(opts.endpointUrl) || opts.endpointUrl,
|
|
645
|
+
token: clean(opts.runnerToken) || clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN),
|
|
646
|
+
placement: opts.placement === "managed" ? "managed" : "local",
|
|
647
|
+
capabilities,
|
|
648
|
+
runnerVersion: clean(opts.runnerVersion) || "",
|
|
649
|
+
runnerNode: hostname()
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
async function requestRunner(method, path, opts, body) {
|
|
653
|
+
const headers = {
|
|
654
|
+
...runnerRequestHeaders(opts)
|
|
655
|
+
};
|
|
656
|
+
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
657
|
+
const res = await fetch(`${runnerBaseUrl(opts.url)}${path}`, {
|
|
658
|
+
method,
|
|
659
|
+
headers,
|
|
660
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
661
|
+
});
|
|
662
|
+
const { text, data } = await readResponse(res);
|
|
663
|
+
if (!res.ok) {
|
|
664
|
+
const message = responseErrorMessage(data, text, res.statusText);
|
|
665
|
+
throw new Error(`${res.status} ${message}`);
|
|
666
|
+
}
|
|
667
|
+
return data;
|
|
668
|
+
}
|
|
669
|
+
async function requestPags(method, path, opts, body) {
|
|
670
|
+
const headers = {
|
|
671
|
+
...pagsHeaders(opts.pagsToken)
|
|
672
|
+
};
|
|
673
|
+
if (!headers.Authorization) {
|
|
674
|
+
throw new Error("PAGS token required. Set PAGS_TOKEN or pass --pags-token.");
|
|
675
|
+
}
|
|
676
|
+
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
677
|
+
const res = await fetch(`${pagsApiBase(opts.apiBase)}${path}`, {
|
|
678
|
+
method,
|
|
679
|
+
headers,
|
|
680
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
681
|
+
});
|
|
682
|
+
const { text, data } = await readResponse(res);
|
|
683
|
+
if (!res.ok) {
|
|
684
|
+
const message = responseErrorMessage(data, text, res.statusText);
|
|
685
|
+
throw new Error(`${res.status} ${message}`);
|
|
686
|
+
}
|
|
687
|
+
return data;
|
|
688
|
+
}
|
|
689
|
+
async function readResponse(res) {
|
|
690
|
+
const text = await res.text();
|
|
691
|
+
if (!text) return { text, data: {} };
|
|
692
|
+
try {
|
|
693
|
+
return { text, data: JSON.parse(text) };
|
|
694
|
+
} catch {
|
|
695
|
+
return { text, data: {} };
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
function responseErrorMessage(data, text, statusText) {
|
|
699
|
+
return typeof data.error === "string" ? data.error : text || statusText;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/commands/runner/process.ts
|
|
703
|
+
import { spawn as spawn2 } from "child_process";
|
|
704
|
+
import { existsSync as existsSync5 } from "fs";
|
|
616
705
|
import { resolve as resolve4 } from "path";
|
|
617
706
|
import { createServer as createServer2 } from "net";
|
|
618
707
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
619
708
|
import { createRequire } from "module";
|
|
620
|
-
import { Command as Command6 } from "commander";
|
|
621
709
|
var CLI_VERSION = (() => {
|
|
622
710
|
try {
|
|
623
711
|
return createRequire(import.meta.url)("../package.json").version;
|
|
@@ -637,27 +725,6 @@ async function findFreePort2(start) {
|
|
|
637
725
|
}
|
|
638
726
|
return start;
|
|
639
727
|
}
|
|
640
|
-
var runnerCommand = createRunnerCommand();
|
|
641
|
-
function runnerBaseUrl(url) {
|
|
642
|
-
return (clean(url) || clean(process.env.PAGS_RUNNER_URL) || "http://127.0.0.1:49171").replace(/\/$/, "");
|
|
643
|
-
}
|
|
644
|
-
function pagsApiBase(url) {
|
|
645
|
-
return (clean(url) || clean(process.env.PAGS_API_BASE) || "https://api.proagentstore.online").replace(/\/$/, "");
|
|
646
|
-
}
|
|
647
|
-
function pagsHeaders(token) {
|
|
648
|
-
const resolved = clean(token) || clean(process.env.PAGS_TOKEN) || clean(loadSession()?.token);
|
|
649
|
-
return resolved ? { Authorization: `Bearer ${resolved}` } : {};
|
|
650
|
-
}
|
|
651
|
-
function runnerRequestHeaders(opts) {
|
|
652
|
-
const resolved = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN);
|
|
653
|
-
const headers = resolved ? { Authorization: `Bearer ${resolved}` } : {};
|
|
654
|
-
const instanceId = clean(opts.instanceId) || clean(process.env.PAGS_INSTANCE_ID);
|
|
655
|
-
if (instanceId) headers["X-PAGS-Instance-Id"] = instanceId;
|
|
656
|
-
return headers;
|
|
657
|
-
}
|
|
658
|
-
function apiPathSegment(value) {
|
|
659
|
-
return encodeURIComponent(value);
|
|
660
|
-
}
|
|
661
728
|
function buildRunnerArgs(opts) {
|
|
662
729
|
const args = [];
|
|
663
730
|
if (clean(opts.host)) args.push("--host", clean(opts.host));
|
|
@@ -668,20 +735,6 @@ function buildRunnerArgs(opts) {
|
|
|
668
735
|
if (opts.headless) args.push("--headless");
|
|
669
736
|
return args;
|
|
670
737
|
}
|
|
671
|
-
function buildRuntimeRegistrationBody(opts, capabilities = []) {
|
|
672
|
-
return {
|
|
673
|
-
endpointUrl: clean(opts.endpointUrl) || opts.endpointUrl,
|
|
674
|
-
token: clean(opts.runnerToken) || clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN),
|
|
675
|
-
placement: opts.placement === "managed" ? "managed" : "local",
|
|
676
|
-
capabilities,
|
|
677
|
-
runnerVersion: clean(opts.runnerVersion) || "",
|
|
678
|
-
runnerNode: hostname()
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
function clean(value) {
|
|
682
|
-
const trimmed = value?.trim();
|
|
683
|
-
return trimmed || void 0;
|
|
684
|
-
}
|
|
685
738
|
function findWorkspaceRoot() {
|
|
686
739
|
let dir = process.cwd();
|
|
687
740
|
for (let i = 0; i < 8; i++) {
|
|
@@ -742,63 +795,14 @@ async function waitForLocalRunner(opts, timeoutMs = 15e3) {
|
|
|
742
795
|
}
|
|
743
796
|
throw new Error(`runner did not become healthy: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
|
|
744
797
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
};
|
|
749
|
-
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
750
|
-
const res = await fetch(`${runnerBaseUrl(opts.url)}${path}`, {
|
|
751
|
-
method,
|
|
752
|
-
headers,
|
|
753
|
-
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
754
|
-
});
|
|
755
|
-
const { text, data } = await readResponse(res);
|
|
756
|
-
if (!res.ok) {
|
|
757
|
-
const message = responseErrorMessage(data, text, res.statusText);
|
|
758
|
-
throw new Error(`${res.status} ${message}`);
|
|
759
|
-
}
|
|
760
|
-
return data;
|
|
761
|
-
}
|
|
762
|
-
async function requestPags(method, path, opts, body) {
|
|
763
|
-
const headers = {
|
|
764
|
-
...pagsHeaders(opts.pagsToken)
|
|
765
|
-
};
|
|
766
|
-
if (!headers.Authorization) {
|
|
767
|
-
throw new Error("PAGS token required. Set PAGS_TOKEN or pass --pags-token.");
|
|
768
|
-
}
|
|
769
|
-
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
770
|
-
const res = await fetch(`${pagsApiBase(opts.apiBase)}${path}`, {
|
|
771
|
-
method,
|
|
772
|
-
headers,
|
|
773
|
-
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
774
|
-
});
|
|
775
|
-
const { text, data } = await readResponse(res);
|
|
776
|
-
if (!res.ok) {
|
|
777
|
-
const message = responseErrorMessage(data, text, res.statusText);
|
|
778
|
-
throw new Error(`${res.status} ${message}`);
|
|
779
|
-
}
|
|
780
|
-
return data;
|
|
781
|
-
}
|
|
782
|
-
async function readResponse(res) {
|
|
783
|
-
const text = await res.text();
|
|
784
|
-
if (!text) return { text, data: {} };
|
|
785
|
-
try {
|
|
786
|
-
return { text, data: JSON.parse(text) };
|
|
787
|
-
} catch {
|
|
788
|
-
return { text, data: {} };
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
function responseErrorMessage(data, text, statusText) {
|
|
792
|
-
return typeof data.error === "string" ? data.error : text || statusText;
|
|
793
|
-
}
|
|
794
|
-
function collectCapability(value, previous = []) {
|
|
795
|
-
return [...previous, value];
|
|
796
|
-
}
|
|
798
|
+
|
|
799
|
+
// src/commands/runner/relay.ts
|
|
800
|
+
import { hostname as hostname2 } from "os";
|
|
797
801
|
async function connectViaRelay(instanceIds, localUrl, runnerToken, opts, force = false) {
|
|
798
802
|
const apiBase = pagsApiBase(opts.apiBase).replace(/^http/, "ws");
|
|
799
803
|
const pagsToken = clean(opts.pagsToken) || clean(process.env.PAGS_TOKEN) || clean(loadSession()?.token);
|
|
800
804
|
if (!pagsToken) throw new Error("PAGS token required for WebSocket relay");
|
|
801
|
-
const runnerNode =
|
|
805
|
+
const runnerNode = hostname2();
|
|
802
806
|
const capabilities = await requestRunner("GET", "/capabilities", { url: localUrl, token: runnerToken, instanceId: instanceIds[0] });
|
|
803
807
|
const caps = Array.isArray(capabilities.capabilities) ? capabilities.capabilities.filter((item) => typeof item === "string") : [];
|
|
804
808
|
for (const id of instanceIds) {
|
|
@@ -824,7 +828,7 @@ async function connectViaRelay(instanceIds, localUrl, runnerToken, opts, force =
|
|
|
824
828
|
writeLine("Runtime registered with PAGS \u2713");
|
|
825
829
|
writeLine("");
|
|
826
830
|
writeLine("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
827
|
-
writeLine(` \u2705 CONNECTED \u2014 WebSocket relay \xB7 ${
|
|
831
|
+
writeLine(` \u2705 CONNECTED \u2014 WebSocket relay \xB7 ${hostname2()}`);
|
|
828
832
|
writeLine(` Agents: ${instanceIds.length} instance${instanceIds.length === 1 ? "" : "s"}`);
|
|
829
833
|
writeLine(" No cloudflared needed. Ctrl+C to disconnect.");
|
|
830
834
|
writeLine("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
@@ -860,7 +864,7 @@ function openRelaySocket(instanceId, wsBase, mintToken, localUrl, runnerToken, f
|
|
|
860
864
|
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
861
865
|
return;
|
|
862
866
|
}
|
|
863
|
-
const params = new URLSearchParams({ token: relayToken, node:
|
|
867
|
+
const params = new URLSearchParams({ token: relayToken, node: hostname2() });
|
|
864
868
|
if (force) params.set("force", "1");
|
|
865
869
|
const url = `${wsBase}/v1/relay/${encodeURIComponent(instanceId)}/connect?${params.toString()}`;
|
|
866
870
|
const ws = new WebSocket(url);
|
|
@@ -930,6 +934,11 @@ function openRelaySocket(instanceId, wsBase, mintToken, localUrl, runnerToken, f
|
|
|
930
934
|
};
|
|
931
935
|
connect();
|
|
932
936
|
}
|
|
937
|
+
|
|
938
|
+
// src/commands/runner/command.ts
|
|
939
|
+
function collectCapability(value, previous = []) {
|
|
940
|
+
return [...previous, value];
|
|
941
|
+
}
|
|
933
942
|
function createRunnerCommand() {
|
|
934
943
|
const command = new Command6("runner").description(
|
|
935
944
|
"Manage the local ProAgentStore browser runtime for ProAgentStore agents"
|
|
@@ -945,7 +954,7 @@ function createRunnerCommand() {
|
|
|
945
954
|
const primary = instanceIds[0];
|
|
946
955
|
const runnerOpts = { ...opts, host, port, token: runnerToken };
|
|
947
956
|
const spec = runnerSpawnSpec(runnerOpts);
|
|
948
|
-
const runner =
|
|
957
|
+
const runner = spawn3(spec.command, spec.args, {
|
|
949
958
|
cwd: spec.cwd,
|
|
950
959
|
stdio: ["ignore", "pipe", "pipe"],
|
|
951
960
|
shell: process.platform === "win32"
|
|
@@ -1091,13 +1100,16 @@ function createRunnerCommand() {
|
|
|
1091
1100
|
return command;
|
|
1092
1101
|
}
|
|
1093
1102
|
|
|
1103
|
+
// src/commands/runner.ts
|
|
1104
|
+
var runnerCommand = createRunnerCommand();
|
|
1105
|
+
|
|
1094
1106
|
// src/commands/up.ts
|
|
1095
1107
|
import { createRequire as createRequire2 } from "module";
|
|
1096
1108
|
import { Command as Command7 } from "commander";
|
|
1097
1109
|
|
|
1098
1110
|
// src/tui.ts
|
|
1099
1111
|
import chalk from "chalk";
|
|
1100
|
-
import { hostname as
|
|
1112
|
+
import { hostname as hostname3 } from "os";
|
|
1101
1113
|
import readline from "readline";
|
|
1102
1114
|
var ACCENT = "#7c3aed";
|
|
1103
1115
|
var c = chalk.hex(ACCENT);
|
|
@@ -1139,7 +1151,7 @@ function printStatus(state) {
|
|
|
1139
1151
|
clearScreen();
|
|
1140
1152
|
printLogo(state.version);
|
|
1141
1153
|
const connected = state.runner === "online" && state.tunnel === "online" && state.registration === "registered";
|
|
1142
|
-
console.log(pad + d("Signed in as ") + w(state.user) + d(" \xB7 agent: ") + w(state.activeInstance) + d(" \xB7 node: ") + w(
|
|
1154
|
+
console.log(pad + d("Signed in as ") + w(state.user) + d(" \xB7 agent: ") + w(state.activeInstance) + d(" \xB7 node: ") + w(hostname3()));
|
|
1143
1155
|
console.log("");
|
|
1144
1156
|
const row = (kind, s) => {
|
|
1145
1157
|
const { icon, label, note } = describe(kind, s);
|
|
@@ -1202,7 +1214,7 @@ var API_BASE2 = "https://api.proagentstore.online";
|
|
|
1202
1214
|
var CLI_VERSION2 = createRequire2(import.meta.url)("../package.json").version;
|
|
1203
1215
|
async function stopRunnerProcesses() {
|
|
1204
1216
|
if (process.platform === "win32") return false;
|
|
1205
|
-
const {
|
|
1217
|
+
const { execFileSync: execFileSync2 } = await import("child_process");
|
|
1206
1218
|
const patterns = [
|
|
1207
1219
|
"dist/browser-runner/index.js",
|
|
1208
1220
|
"browser-runner/src/index",
|
|
@@ -1211,7 +1223,7 @@ async function stopRunnerProcesses() {
|
|
|
1211
1223
|
let stopped = false;
|
|
1212
1224
|
for (const p of patterns) {
|
|
1213
1225
|
try {
|
|
1214
|
-
|
|
1226
|
+
execFileSync2("pkill", ["-f", p], { stdio: "ignore" });
|
|
1215
1227
|
stopped = true;
|
|
1216
1228
|
} catch {
|
|
1217
1229
|
}
|
|
@@ -1270,12 +1282,12 @@ var upCommand = new Command7("up").description("Start the browser runner for all
|
|
|
1270
1282
|
state.activeInstance = instances.length === 1 ? instances[0].name || instances[0].slug || instances[0].id.slice(0, 8) : `${instances.length} agents`;
|
|
1271
1283
|
printStep(`Connecting ${state.activeInstance}\u2026`, "wait");
|
|
1272
1284
|
await stopRunnerProcesses();
|
|
1273
|
-
const { spawn:
|
|
1285
|
+
const { spawn: spawn4 } = await import("child_process");
|
|
1274
1286
|
const cliPath = process.argv[1];
|
|
1275
1287
|
const args = [cliPath, "runner", "connect", ...instances.map((i) => i.id)];
|
|
1276
1288
|
if (opts.headless) args.push("--headless");
|
|
1277
1289
|
if (opts.force) args.push("--force");
|
|
1278
|
-
const child =
|
|
1290
|
+
const child = spawn4(process.execPath, args, {
|
|
1279
1291
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1280
1292
|
env: { ...process.env, PAGS_TOKEN: session.token }
|
|
1281
1293
|
});
|