@proagentstore/cli 0.1.9 → 0.1.10

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 CHANGED
@@ -1,19 +1,31 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- __require,
4
- runnerCommand,
5
- writeError,
6
- writeLine
7
- } from "./chunk-LNY7MNUC.js";
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
8
 
9
9
  // src/index.ts
10
10
  import { createRequire } from "module";
11
- import { Command as Command7 } from "commander";
11
+ import { Command as Command8 } from "commander";
12
12
 
13
13
  // src/commands/check.ts
14
14
  import { existsSync, readFileSync } from "fs";
15
15
  import { join, resolve } from "path";
16
16
  import { Command } from "commander";
17
+
18
+ // src/output.ts
19
+ function writeLine(message = "") {
20
+ process.stdout.write(`${message}
21
+ `);
22
+ }
23
+ function writeError(message = "") {
24
+ process.stderr.write(`${message}
25
+ `);
26
+ }
27
+
28
+ // src/commands/check.ts
17
29
  var checkCommand = new Command("check").description("Run compliance checks on an agent").option("-d, --dir <path>", "Agent directory", ".").action((opts) => {
18
30
  const dir = resolve(opts.dir);
19
31
  const results = [];
@@ -397,7 +409,7 @@ var loginCommand = new Command3("login").description("Sign in with Google or Git
397
409
  writeLine(`Opening browser for ${provider} sign-in...`);
398
410
  const port = await findFreePort();
399
411
  const callbackUrl = `http://127.0.0.1:${port}/callback`;
400
- const tokenPromise = new Promise((resolve4, reject) => {
412
+ const tokenPromise = new Promise((resolve5, reject) => {
401
413
  const timeout = setTimeout(() => {
402
414
  server.close();
403
415
  reject(new Error("Login timed out (60s)"));
@@ -436,7 +448,7 @@ var loginCommand = new Command3("login").description("Sign in with Google or Git
436
448
  res.end(`<h1>Signed in as ${data.user?.login}</h1><p>You can close this tab and return to the terminal.</p><script>window.close()</script>`);
437
449
  clearTimeout(timeout);
438
450
  server.close();
439
- resolve4(data.token);
451
+ resolve5(data.token);
440
452
  } catch (err) {
441
453
  res.writeHead(500, { "Content-Type": "text/html" });
442
454
  res.end(`<h1>Sign-in failed</h1><p>${err instanceof Error ? err.message : String(err)}</p>`);
@@ -481,12 +493,12 @@ var whoamiCommand = new Command3("whoami").description("Show current signed-in u
481
493
  }
482
494
  });
483
495
  async function findFreePort() {
484
- return new Promise((resolve4) => {
496
+ return new Promise((resolve5) => {
485
497
  const server = createServer();
486
498
  server.listen(0, "127.0.0.1", () => {
487
499
  const addr = server.address();
488
500
  const port = typeof addr === "object" && addr ? addr.port : 0;
489
- server.close(() => resolve4(port));
501
+ server.close(() => resolve5(port));
490
502
  });
491
503
  });
492
504
  }
@@ -503,11 +515,11 @@ async function runMcpProxy(opts, extraArgs = []) {
503
515
  stdio: "inherit",
504
516
  env: process.env
505
517
  });
506
- await new Promise((resolve4, reject) => {
518
+ await new Promise((resolve5, reject) => {
507
519
  child.on("error", reject);
508
520
  child.on("close", (code) => {
509
521
  if (code && code !== 0) reject(new Error(`mcp proxy exited with code ${code}`));
510
- else resolve4();
522
+ else resolve5();
511
523
  });
512
524
  });
513
525
  }
@@ -598,10 +610,390 @@ var publishCommand = new Command5("publish").description("Publish an agent to Pr
598
610
  writeLine();
599
611
  });
600
612
 
601
- // src/commands/up.ts
613
+ // src/commands/runner.ts
614
+ import { spawn as spawn2 } from "child_process";
615
+ import { randomUUID } from "crypto";
616
+ import { existsSync as existsSync5 } from "fs";
617
+ import { resolve as resolve4 } from "path";
618
+ import { fileURLToPath as fileURLToPath2 } from "url";
602
619
  import { Command as Command6 } from "commander";
620
+ var runnerCommand = createRunnerCommand();
621
+ function runnerBaseUrl(url) {
622
+ return (clean(url) || clean(process.env.PAGS_RUNNER_URL) || "http://127.0.0.1:49171").replace(/\/$/, "");
623
+ }
624
+ function pagsApiBase(url) {
625
+ return (clean(url) || clean(process.env.PAGS_API_BASE) || "https://api.proagentstore.online").replace(/\/$/, "");
626
+ }
627
+ function pagsHeaders(token) {
628
+ const resolved = clean(token) || clean(process.env.PAGS_TOKEN);
629
+ return resolved ? { Authorization: `Bearer ${resolved}` } : {};
630
+ }
631
+ function runnerRequestHeaders(opts) {
632
+ const resolved = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN);
633
+ const headers = resolved ? { Authorization: `Bearer ${resolved}` } : {};
634
+ const instanceId = clean(opts.instanceId) || clean(process.env.PAGS_INSTANCE_ID);
635
+ if (instanceId) headers["X-PAGS-Instance-Id"] = instanceId;
636
+ return headers;
637
+ }
638
+ function apiPathSegment(value) {
639
+ return encodeURIComponent(value);
640
+ }
641
+ function buildRunnerArgs(opts) {
642
+ const args = [];
643
+ if (clean(opts.host)) args.push("--host", clean(opts.host));
644
+ if (clean(opts.port)) args.push("--port", clean(opts.port));
645
+ if (clean(opts.dataDir)) args.push("--data-dir", clean(opts.dataDir));
646
+ if (clean(opts.token)) args.push("--token", clean(opts.token));
647
+ if (clean(opts.instanceId)) args.push("--instance-id", clean(opts.instanceId));
648
+ if (opts.headless) args.push("--headless");
649
+ return args;
650
+ }
651
+ function buildCloudflaredArgs(localUrl) {
652
+ return ["tunnel", "--url", localUrl];
653
+ }
654
+ function parseCloudflaredTunnelUrl(text) {
655
+ return text.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/i)?.[0] || null;
656
+ }
657
+ function buildRuntimeRegistrationBody(opts, capabilities = []) {
658
+ return {
659
+ endpointUrl: clean(opts.endpointUrl) || opts.endpointUrl,
660
+ token: clean(opts.runnerToken) || clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN),
661
+ placement: opts.placement === "managed" ? "managed" : "local",
662
+ capabilities,
663
+ runnerVersion: clean(opts.runnerVersion) || ""
664
+ };
665
+ }
666
+ function clean(value) {
667
+ const trimmed = value?.trim();
668
+ return trimmed || void 0;
669
+ }
670
+ function findWorkspaceRoot() {
671
+ let dir = process.cwd();
672
+ for (let i = 0; i < 8; i++) {
673
+ if (existsSync5(resolve4(dir, "pnpm-workspace.yaml"))) return dir;
674
+ const parent = resolve4(dir, "..");
675
+ if (parent === dir) break;
676
+ dir = parent;
677
+ }
678
+ return process.cwd();
679
+ }
680
+ function bundledRunnerPath() {
681
+ return fileURLToPath2(new URL("./browser-runner/index.js", import.meta.url));
682
+ }
683
+ function runnerSpawnSpec(opts) {
684
+ const root = findWorkspaceRoot();
685
+ const localPackage = resolve4(root, "packages", "browser-runner", "src", "index.ts");
686
+ const bundledPackage = bundledRunnerPath();
687
+ const runnerArgs = buildRunnerArgs(opts);
688
+ let cwd = root;
689
+ let command = "pags-browser-runner";
690
+ let args = runnerArgs;
691
+ if (existsSync5(localPackage)) {
692
+ command = "pnpm";
693
+ args = ["--filter", "@proagentstore/browser-runner", "dev", "--", ...runnerArgs];
694
+ } else if (existsSync5(bundledPackage)) {
695
+ cwd = process.cwd();
696
+ command = process.execPath;
697
+ args = [bundledPackage, ...runnerArgs];
698
+ }
699
+ return { command, args, cwd };
700
+ }
701
+ function startRunnerForeground(opts) {
702
+ const spec = runnerSpawnSpec(opts);
703
+ return new Promise((resolvePromise, reject) => {
704
+ const child = spawn2(spec.command, spec.args, {
705
+ cwd: spec.cwd,
706
+ stdio: "inherit",
707
+ shell: process.platform === "win32"
708
+ });
709
+ child.on("error", reject);
710
+ child.on("exit", (code) => {
711
+ if (code && code !== 0) reject(new Error(`runner exited with code ${code}`));
712
+ else resolvePromise();
713
+ });
714
+ });
715
+ }
716
+ async function waitForLocalRunner(opts, timeoutMs = 15e3) {
717
+ const started = Date.now();
718
+ let lastError;
719
+ while (Date.now() - started < timeoutMs) {
720
+ try {
721
+ await requestRunner("GET", "/health", opts);
722
+ return;
723
+ } catch (error) {
724
+ lastError = error;
725
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, 500));
726
+ }
727
+ }
728
+ throw new Error(`runner did not become healthy: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
729
+ }
730
+ async function requestRunner(method, path, opts, body) {
731
+ const headers = {
732
+ ...runnerRequestHeaders(opts)
733
+ };
734
+ if (body !== void 0) headers["Content-Type"] = "application/json";
735
+ const res = await fetch(`${runnerBaseUrl(opts.url)}${path}`, {
736
+ method,
737
+ headers,
738
+ body: body === void 0 ? void 0 : JSON.stringify(body)
739
+ });
740
+ const { text, data } = await readResponse(res);
741
+ if (!res.ok) {
742
+ const message = responseErrorMessage(data, text, res.statusText);
743
+ throw new Error(`${res.status} ${message}`);
744
+ }
745
+ return data;
746
+ }
747
+ async function requestPags(method, path, opts, body) {
748
+ const headers = {
749
+ ...pagsHeaders(opts.pagsToken)
750
+ };
751
+ if (!headers.Authorization) {
752
+ throw new Error("PAGS token required. Set PAGS_TOKEN or pass --pags-token.");
753
+ }
754
+ if (body !== void 0) headers["Content-Type"] = "application/json";
755
+ const res = await fetch(`${pagsApiBase(opts.apiBase)}${path}`, {
756
+ method,
757
+ headers,
758
+ body: body === void 0 ? void 0 : JSON.stringify(body)
759
+ });
760
+ const { text, data } = await readResponse(res);
761
+ if (!res.ok) {
762
+ const message = responseErrorMessage(data, text, res.statusText);
763
+ throw new Error(`${res.status} ${message}`);
764
+ }
765
+ return data;
766
+ }
767
+ async function readResponse(res) {
768
+ const text = await res.text();
769
+ if (!text) return { text, data: {} };
770
+ try {
771
+ return { text, data: JSON.parse(text) };
772
+ } catch {
773
+ return { text, data: {} };
774
+ }
775
+ }
776
+ function responseErrorMessage(data, text, statusText) {
777
+ return typeof data.error === "string" ? data.error : text || statusText;
778
+ }
779
+ function collectCapability(value, previous = []) {
780
+ return [...previous, value];
781
+ }
782
+ function createRunnerCommand() {
783
+ const command = new Command6("runner").description(
784
+ "Manage the local FAGS browser runtime for ProAgentStore agents"
785
+ );
786
+ command.command("start").description("Start the local FAGS browser runtime in the foreground").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind", "49171").option("--data-dir <path>", "Runner data directory").option("--token <token>", "Require this bearer token").option("--instance-id <id>", "Bind runner requests to a PAGS instance id").option("--headless", "Run Playwright headless").action(async (opts) => {
787
+ await startRunnerForeground(opts);
788
+ });
789
+ command.command("connect <instanceId>").description("Start the local FAGS runtime, open a Cloudflare quick tunnel, and register it with PAGS").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind", "49171").option("--data-dir <path>", "Runner data directory").option("--token <token>", "Runner bearer token. Defaults to PAGS_RUNNER_TOKEN or a generated token").option("--headless", "Run Playwright headless").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--cloudflared <path>", "cloudflared executable", "cloudflared").option("--runner-version <version>", "Runner version").option("--skip-probe", "Skip PAGS FAGS-runtime probe after registration").action(async (instanceId, opts) => {
790
+ const runnerToken = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN) || `pags_runner_${randomUUID()}`;
791
+ const host = clean(opts.host) || "127.0.0.1";
792
+ const port = clean(opts.port) || "49171";
793
+ const localUrl = `http://${host}:${port}`;
794
+ const runnerOpts = {
795
+ ...opts,
796
+ host,
797
+ port,
798
+ token: runnerToken,
799
+ instanceId
800
+ };
801
+ const spec = runnerSpawnSpec(runnerOpts);
802
+ const runner = spawn2(spec.command, spec.args, {
803
+ cwd: spec.cwd,
804
+ stdio: ["ignore", "pipe", "pipe"],
805
+ shell: process.platform === "win32"
806
+ });
807
+ runner.stdout?.on("data", (data) => process.stdout.write(data));
808
+ runner.stderr?.on("data", (data) => process.stderr.write(data));
809
+ runner.on("exit", (code) => {
810
+ if (code && code !== 0) writeError(`runner exited with code ${code}`);
811
+ });
812
+ let tunnel = null;
813
+ const shutdown = () => {
814
+ if (tunnel && !tunnel.killed) tunnel.kill("SIGTERM");
815
+ if (!runner.killed) runner.kill("SIGTERM");
816
+ };
817
+ process.once("SIGINT", () => {
818
+ shutdown();
819
+ process.exit(0);
820
+ });
821
+ process.once("SIGTERM", () => {
822
+ shutdown();
823
+ process.exit(0);
824
+ });
825
+ try {
826
+ await waitForLocalRunner({ url: localUrl, token: runnerToken, instanceId });
827
+ writeLine(`Local FAGS runtime healthy at ${localUrl}`);
828
+ const tunnelUrl = await new Promise((resolveTunnel, reject) => {
829
+ let output = "";
830
+ const cloudflared = clean(opts.cloudflared) || "cloudflared";
831
+ tunnel = spawn2(cloudflared, buildCloudflaredArgs(localUrl), {
832
+ stdio: ["ignore", "pipe", "pipe"],
833
+ shell: process.platform === "win32"
834
+ });
835
+ const onData = (data) => {
836
+ const text = data.toString("utf-8");
837
+ output += text;
838
+ process.stderr.write(text);
839
+ const parsed = parseCloudflaredTunnelUrl(output);
840
+ if (parsed) resolveTunnel(parsed);
841
+ };
842
+ tunnel.stdout?.on("data", onData);
843
+ tunnel.stderr?.on("data", onData);
844
+ tunnel.on("error", reject);
845
+ tunnel.on("exit", (code) => {
846
+ if (code && code !== 0) reject(new Error(`cloudflared exited with code ${code}`));
847
+ });
848
+ setTimeout(() => reject(new Error("timed out waiting for cloudflared tunnel URL")), 45e3).unref();
849
+ });
850
+ writeLine(`Tunnel ready: ${tunnelUrl}`);
851
+ await waitForLocalRunner({ url: tunnelUrl, token: runnerToken, instanceId }, 3e4);
852
+ writeLine("Tunnel health check passed");
853
+ const capabilities = await requestRunner("GET", "/capabilities", {
854
+ url: tunnelUrl,
855
+ token: runnerToken,
856
+ instanceId
857
+ });
858
+ const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts, {
859
+ endpointUrl: tunnelUrl,
860
+ token: runnerToken,
861
+ placement: "local",
862
+ capabilities: Array.isArray(capabilities.capabilities) ? capabilities.capabilities.filter((item) => typeof item === "string") : [],
863
+ runnerVersion: clean(opts.runnerVersion) || ""
864
+ });
865
+ writeLine(JSON.stringify(result, null, 2));
866
+ if (!opts.skipProbe) {
867
+ const status = await requestPags(
868
+ "GET",
869
+ `/v1/instances/${apiPathSegment(instanceId)}/runtime/status`,
870
+ opts
871
+ );
872
+ writeLine(JSON.stringify(status, null, 2));
873
+ }
874
+ writeLine("Connected. Keep this process running while the agent uses your FAGS browser runtime.");
875
+ await new Promise((resolvePromise) => {
876
+ runner.on("exit", () => resolvePromise());
877
+ tunnel?.on("exit", () => resolvePromise());
878
+ });
879
+ } catch (error) {
880
+ shutdown();
881
+ throw error;
882
+ }
883
+ });
884
+ command.command("status").description("Check local FAGS runtime health and capabilities").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (opts) => {
885
+ const health = await requestRunner("GET", "/health", opts);
886
+ const capabilities = await requestRunner("GET", "/capabilities", opts);
887
+ writeLine(JSON.stringify({ health, capabilities }, null, 2));
888
+ });
889
+ command.command("task").description("Create a local FAGS runtime task").requiredOption("--type <type>", "Task type, e.g. echo or browser.open").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").option("--input <json>", "Task input JSON").option("--job-url <url>", "Shortcut input for browser.open").option("--approve", "Create task in needs_approval state").option("--approval-prompt <text>", "Approval prompt").action(
890
+ async (opts) => {
891
+ let input = {};
892
+ if (opts.input) {
893
+ try {
894
+ input = JSON.parse(opts.input);
895
+ } catch {
896
+ writeError("--input must be valid JSON");
897
+ process.exit(1);
898
+ }
899
+ }
900
+ if (opts.jobUrl) input.url = opts.jobUrl;
901
+ const task = await requestRunner("POST", "/tasks", opts, {
902
+ type: opts.type,
903
+ input,
904
+ requiresApproval: Boolean(opts.approve),
905
+ approvalPrompt: opts.approvalPrompt
906
+ });
907
+ writeLine(JSON.stringify(task, null, 2));
908
+ }
909
+ );
910
+ command.command("register <instanceId>").description("Register a local or managed FAGS runtime endpoint with a PAGS instance").requiredOption("--endpoint-url <url>", "FAGS runtime endpoint URL to store in PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--runner-token <token>", "FAGS runtime bearer token to store in PAGS").option("--url <url>", "Local FAGS runtime URL to probe for capabilities").option("--token <token>", "Local FAGS runtime bearer token for capability probe").option("--instance-id <id>", "PAGS instance id header for capability probe").option("--placement <placement>", "Runtime placement: local or managed", "local").option("--runner-version <version>", "Runner version").option("--capability <name>", "Runtime capability; repeatable", collectCapability, []).option("--probe", "Read capabilities from the FAGS runtime before registering").action(async (instanceId, opts) => {
911
+ let capabilities = opts.capability || [];
912
+ if (opts.probe) {
913
+ const data = await requestRunner("GET", "/capabilities", {
914
+ url: opts.url || opts.endpointUrl,
915
+ token: opts.token || opts.runnerToken,
916
+ instanceId: opts.instanceId || instanceId
917
+ });
918
+ capabilities = Array.isArray(data.capabilities) ? data.capabilities.filter((item) => typeof item === "string") : capabilities;
919
+ }
920
+ const body = buildRuntimeRegistrationBody(opts, capabilities);
921
+ const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts, body);
922
+ writeLine(JSON.stringify(result, null, 2));
923
+ });
924
+ command.command("runtime <instanceId>").description("Read the PAGS runtime registration for an instance").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--probe", "Ask PAGS to probe /health and /capabilities on the FAGS runtime").action(async (instanceId, opts) => {
925
+ const path = opts.probe ? `/v1/instances/${apiPathSegment(instanceId)}/runtime/status` : `/v1/instances/${apiPathSegment(instanceId)}/runtime`;
926
+ const result = await requestPags("GET", path, opts);
927
+ writeLine(JSON.stringify(result, null, 2));
928
+ });
929
+ command.command("unregister <instanceId>").description("Remove the PAGS runtime registration for an instance").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, opts) => {
930
+ const result = await requestPags("DELETE", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts);
931
+ writeLine(JSON.stringify(result, null, 2));
932
+ });
933
+ command.command("run <instanceId>").description("Create a task through PAGS on an instance's registered FAGS runtime").requiredOption("--type <type>", "Task type, e.g. echo or browser.open").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--input <json>", "Task input JSON").option("--job-url <url>", "Shortcut input for browser.open").option("--approve", "Create task in needs_approval state").option("--approval-prompt <text>", "Approval prompt").action(
934
+ async (instanceId, opts) => {
935
+ let input = {};
936
+ if (opts.input) {
937
+ try {
938
+ input = JSON.parse(opts.input);
939
+ } catch {
940
+ writeError("--input must be valid JSON");
941
+ process.exit(1);
942
+ }
943
+ }
944
+ if (opts.jobUrl) input.url = opts.jobUrl;
945
+ const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/tasks`, opts, {
946
+ type: opts.type,
947
+ input,
948
+ requiresApproval: Boolean(opts.approve),
949
+ approvalPrompt: opts.approvalPrompt
950
+ });
951
+ writeLine(JSON.stringify(result, null, 2));
952
+ }
953
+ );
954
+ command.command("approve-task <instanceId> <taskId>").description("Approve a registered FAGS runtime task through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, taskId, opts) => {
955
+ const result = await requestPags(
956
+ "POST",
957
+ `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/approve`,
958
+ opts
959
+ );
960
+ writeLine(JSON.stringify(result, null, 2));
961
+ });
962
+ command.command("cancel-task <instanceId> <taskId>").description("Cancel a registered FAGS runtime task through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, taskId, opts) => {
963
+ const result = await requestPags(
964
+ "POST",
965
+ `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/cancel`,
966
+ opts
967
+ );
968
+ writeLine(JSON.stringify(result, null, 2));
969
+ });
970
+ command.command("task-events <instanceId>").description("Read registered FAGS runtime task events through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--limit <n>", "Number of events", "50").action(async (instanceId, opts) => {
971
+ const result = await requestPags(
972
+ "GET",
973
+ `/v1/instances/${apiPathSegment(instanceId)}/task-events?limit=${Number(opts.limit) || 50}`,
974
+ opts
975
+ );
976
+ writeLine(JSON.stringify(result, null, 2));
977
+ });
978
+ command.command("approve <taskId>").description("Approve a task waiting on human approval").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (taskId, opts) => {
979
+ const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/approve`, opts);
980
+ writeLine(JSON.stringify(task, null, 2));
981
+ });
982
+ command.command("cancel <taskId>").description("Cancel a local FAGS runtime task").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (taskId, opts) => {
983
+ const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/cancel`, opts);
984
+ writeLine(JSON.stringify(task, null, 2));
985
+ });
986
+ command.command("events").description("List recent FAGS runtime events").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").option("--limit <n>", "Number of events", "50").action(async (opts) => {
987
+ const events = await requestRunner("GET", `/events?limit=${Number(opts.limit) || 50}`, opts);
988
+ writeLine(JSON.stringify(events, null, 2));
989
+ });
990
+ return command;
991
+ }
992
+
993
+ // src/commands/up.ts
994
+ import { Command as Command7 } from "commander";
603
995
  var API_BASE2 = "https://api.proagentstore.online";
604
- var upCommand = new Command6("up").description("Start the browser runner for all your agent instances").option("--headless", "Run browser in headless mode").option("--instance <id>", "Connect to a specific instance only").action(async (opts) => {
996
+ var upCommand = new Command7("up").description("Start the browser runner for all your agent instances").option("--headless", "Run browser in headless mode").option("--instance <id>", "Connect to a specific instance only").action(async (opts) => {
605
997
  const session = requireSession();
606
998
  writeLine(`Signed in as ${session.user.login}`);
607
999
  writeLine("Fetching your instances...");
@@ -628,15 +1020,10 @@ var upCommand = new Command6("up").description("Start the browser runner for all
628
1020
  const target = instances[0];
629
1021
  writeLine(`
630
1022
  Connecting runner to: ${target.name || target.id.slice(0, 8)}...`);
631
- const { runnerCommand: runnerCommand2 } = await import("./runner-CM72EPKQ.js");
632
- const connectCmd = runnerCommand2.commands.find((c) => c.name() === "connect");
633
- if (!connectCmd) {
634
- writeError("Runner connect command not found");
635
- process.exit(1);
636
- }
1023
+ const { spawn: spawn3 } = await import("child_process");
1024
+ const cliPath = process.argv[1];
637
1025
  const args = [
638
- "node",
639
- "pags",
1026
+ cliPath,
640
1027
  "runner",
641
1028
  "connect",
642
1029
  target.id,
@@ -644,19 +1031,19 @@ Connecting runner to: ${target.name || target.id.slice(0, 8)}...`);
644
1031
  session.token
645
1032
  ];
646
1033
  if (opts.headless) args.push("--headless");
647
- process.argv = args;
648
- try {
649
- await connectCmd.parseAsync(args.slice(2), { from: "user" });
650
- } catch (err) {
651
- writeError(err instanceof Error ? err.message : String(err));
652
- process.exit(1);
653
- }
1034
+ const child = spawn3(process.execPath, args, {
1035
+ stdio: "inherit",
1036
+ env: process.env
1037
+ });
1038
+ child.on("exit", (code) => {
1039
+ process.exit(code || 0);
1040
+ });
654
1041
  });
655
1042
 
656
1043
  // src/index.ts
657
1044
  var require2 = createRequire(import.meta.url);
658
1045
  var { version } = require2("../package.json");
659
- var program = new Command7();
1046
+ var program = new Command8();
660
1047
  program.name("pags").description(
661
1048
  "ProAgentStore CLI \u2014 create and publish server-powered AI agents"
662
1049
  ).version(version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,423 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- // src/commands/runner.ts
9
- import { spawn } from "child_process";
10
- import { randomUUID } from "crypto";
11
- import { existsSync } from "fs";
12
- import { resolve } from "path";
13
- import { fileURLToPath } from "url";
14
- import { Command } from "commander";
15
-
16
- // src/output.ts
17
- function writeLine(message = "") {
18
- process.stdout.write(`${message}
19
- `);
20
- }
21
- function writeError(message = "") {
22
- process.stderr.write(`${message}
23
- `);
24
- }
25
-
26
- // src/commands/runner.ts
27
- var runnerCommand = createRunnerCommand();
28
- function runnerBaseUrl(url) {
29
- return (clean(url) || clean(process.env.PAGS_RUNNER_URL) || "http://127.0.0.1:49171").replace(/\/$/, "");
30
- }
31
- function pagsApiBase(url) {
32
- return (clean(url) || clean(process.env.PAGS_API_BASE) || "https://api.proagentstore.online").replace(/\/$/, "");
33
- }
34
- function pagsHeaders(token) {
35
- const resolved = clean(token) || clean(process.env.PAGS_TOKEN);
36
- return resolved ? { Authorization: `Bearer ${resolved}` } : {};
37
- }
38
- function runnerHeaders(token) {
39
- const resolved = clean(token) || clean(process.env.PAGS_RUNNER_TOKEN);
40
- return resolved ? { Authorization: `Bearer ${resolved}` } : {};
41
- }
42
- function runnerRequestHeaders(opts) {
43
- const resolved = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN);
44
- const headers = resolved ? { Authorization: `Bearer ${resolved}` } : {};
45
- const instanceId = clean(opts.instanceId) || clean(process.env.PAGS_INSTANCE_ID);
46
- if (instanceId) headers["X-PAGS-Instance-Id"] = instanceId;
47
- return headers;
48
- }
49
- function apiPathSegment(value) {
50
- return encodeURIComponent(value);
51
- }
52
- function buildRunnerArgs(opts) {
53
- const args = [];
54
- if (clean(opts.host)) args.push("--host", clean(opts.host));
55
- if (clean(opts.port)) args.push("--port", clean(opts.port));
56
- if (clean(opts.dataDir)) args.push("--data-dir", clean(opts.dataDir));
57
- if (clean(opts.token)) args.push("--token", clean(opts.token));
58
- if (clean(opts.instanceId)) args.push("--instance-id", clean(opts.instanceId));
59
- if (opts.headless) args.push("--headless");
60
- return args;
61
- }
62
- function buildCloudflaredArgs(localUrl) {
63
- return ["tunnel", "--url", localUrl];
64
- }
65
- function parseCloudflaredTunnelUrl(text) {
66
- return text.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/i)?.[0] || null;
67
- }
68
- function buildRuntimeRegistrationBody(opts, capabilities = []) {
69
- return {
70
- endpointUrl: clean(opts.endpointUrl) || opts.endpointUrl,
71
- token: clean(opts.runnerToken) || clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN),
72
- placement: opts.placement === "managed" ? "managed" : "local",
73
- capabilities,
74
- runnerVersion: clean(opts.runnerVersion) || ""
75
- };
76
- }
77
- function clean(value) {
78
- const trimmed = value?.trim();
79
- return trimmed || void 0;
80
- }
81
- function findWorkspaceRoot() {
82
- let dir = process.cwd();
83
- for (let i = 0; i < 8; i++) {
84
- if (existsSync(resolve(dir, "pnpm-workspace.yaml"))) return dir;
85
- const parent = resolve(dir, "..");
86
- if (parent === dir) break;
87
- dir = parent;
88
- }
89
- return process.cwd();
90
- }
91
- function bundledRunnerPath() {
92
- return fileURLToPath(new URL("./browser-runner/index.js", import.meta.url));
93
- }
94
- function runnerSpawnSpec(opts) {
95
- const root = findWorkspaceRoot();
96
- const localPackage = resolve(root, "packages", "browser-runner", "src", "index.ts");
97
- const bundledPackage = bundledRunnerPath();
98
- const runnerArgs = buildRunnerArgs(opts);
99
- let cwd = root;
100
- let command = "pags-browser-runner";
101
- let args = runnerArgs;
102
- if (existsSync(localPackage)) {
103
- command = "pnpm";
104
- args = ["--filter", "@proagentstore/browser-runner", "dev", "--", ...runnerArgs];
105
- } else if (existsSync(bundledPackage)) {
106
- cwd = process.cwd();
107
- command = process.execPath;
108
- args = [bundledPackage, ...runnerArgs];
109
- }
110
- return { command, args, cwd };
111
- }
112
- function startRunnerForeground(opts) {
113
- const spec = runnerSpawnSpec(opts);
114
- return new Promise((resolvePromise, reject) => {
115
- const child = spawn(spec.command, spec.args, {
116
- cwd: spec.cwd,
117
- stdio: "inherit",
118
- shell: process.platform === "win32"
119
- });
120
- child.on("error", reject);
121
- child.on("exit", (code) => {
122
- if (code && code !== 0) reject(new Error(`runner exited with code ${code}`));
123
- else resolvePromise();
124
- });
125
- });
126
- }
127
- async function waitForLocalRunner(opts, timeoutMs = 15e3) {
128
- const started = Date.now();
129
- let lastError;
130
- while (Date.now() - started < timeoutMs) {
131
- try {
132
- await requestRunner("GET", "/health", opts);
133
- return;
134
- } catch (error) {
135
- lastError = error;
136
- await new Promise((resolvePromise) => setTimeout(resolvePromise, 500));
137
- }
138
- }
139
- throw new Error(`runner did not become healthy: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
140
- }
141
- async function requestRunner(method, path, opts, body) {
142
- const headers = {
143
- ...runnerRequestHeaders(opts)
144
- };
145
- if (body !== void 0) headers["Content-Type"] = "application/json";
146
- const res = await fetch(`${runnerBaseUrl(opts.url)}${path}`, {
147
- method,
148
- headers,
149
- body: body === void 0 ? void 0 : JSON.stringify(body)
150
- });
151
- const { text, data } = await readResponse(res);
152
- if (!res.ok) {
153
- const message = responseErrorMessage(data, text, res.statusText);
154
- throw new Error(`${res.status} ${message}`);
155
- }
156
- return data;
157
- }
158
- async function requestPags(method, path, opts, body) {
159
- const headers = {
160
- ...pagsHeaders(opts.pagsToken)
161
- };
162
- if (!headers.Authorization) {
163
- throw new Error("PAGS token required. Set PAGS_TOKEN or pass --pags-token.");
164
- }
165
- if (body !== void 0) headers["Content-Type"] = "application/json";
166
- const res = await fetch(`${pagsApiBase(opts.apiBase)}${path}`, {
167
- method,
168
- headers,
169
- body: body === void 0 ? void 0 : JSON.stringify(body)
170
- });
171
- const { text, data } = await readResponse(res);
172
- if (!res.ok) {
173
- const message = responseErrorMessage(data, text, res.statusText);
174
- throw new Error(`${res.status} ${message}`);
175
- }
176
- return data;
177
- }
178
- async function readResponse(res) {
179
- const text = await res.text();
180
- if (!text) return { text, data: {} };
181
- try {
182
- return { text, data: JSON.parse(text) };
183
- } catch {
184
- return { text, data: {} };
185
- }
186
- }
187
- function responseErrorMessage(data, text, statusText) {
188
- return typeof data.error === "string" ? data.error : text || statusText;
189
- }
190
- function collectCapability(value, previous = []) {
191
- return [...previous, value];
192
- }
193
- function createRunnerCommand() {
194
- const command = new Command("runner").description(
195
- "Manage the local FAGS browser runtime for ProAgentStore agents"
196
- );
197
- command.command("start").description("Start the local FAGS browser runtime in the foreground").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind", "49171").option("--data-dir <path>", "Runner data directory").option("--token <token>", "Require this bearer token").option("--instance-id <id>", "Bind runner requests to a PAGS instance id").option("--headless", "Run Playwright headless").action(async (opts) => {
198
- await startRunnerForeground(opts);
199
- });
200
- command.command("connect <instanceId>").description("Start the local FAGS runtime, open a Cloudflare quick tunnel, and register it with PAGS").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind", "49171").option("--data-dir <path>", "Runner data directory").option("--token <token>", "Runner bearer token. Defaults to PAGS_RUNNER_TOKEN or a generated token").option("--headless", "Run Playwright headless").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--cloudflared <path>", "cloudflared executable", "cloudflared").option("--runner-version <version>", "Runner version").option("--skip-probe", "Skip PAGS FAGS-runtime probe after registration").action(async (instanceId, opts) => {
201
- const runnerToken = clean(opts.token) || clean(process.env.PAGS_RUNNER_TOKEN) || `pags_runner_${randomUUID()}`;
202
- const host = clean(opts.host) || "127.0.0.1";
203
- const port = clean(opts.port) || "49171";
204
- const localUrl = `http://${host}:${port}`;
205
- const runnerOpts = {
206
- ...opts,
207
- host,
208
- port,
209
- token: runnerToken,
210
- instanceId
211
- };
212
- const spec = runnerSpawnSpec(runnerOpts);
213
- const runner = spawn(spec.command, spec.args, {
214
- cwd: spec.cwd,
215
- stdio: ["ignore", "pipe", "pipe"],
216
- shell: process.platform === "win32"
217
- });
218
- runner.stdout?.on("data", (data) => process.stdout.write(data));
219
- runner.stderr?.on("data", (data) => process.stderr.write(data));
220
- runner.on("exit", (code) => {
221
- if (code && code !== 0) writeError(`runner exited with code ${code}`);
222
- });
223
- let tunnel = null;
224
- const shutdown = () => {
225
- if (tunnel && !tunnel.killed) tunnel.kill("SIGTERM");
226
- if (!runner.killed) runner.kill("SIGTERM");
227
- };
228
- process.once("SIGINT", () => {
229
- shutdown();
230
- process.exit(0);
231
- });
232
- process.once("SIGTERM", () => {
233
- shutdown();
234
- process.exit(0);
235
- });
236
- try {
237
- await waitForLocalRunner({ url: localUrl, token: runnerToken, instanceId });
238
- writeLine(`Local FAGS runtime healthy at ${localUrl}`);
239
- const tunnelUrl = await new Promise((resolveTunnel, reject) => {
240
- let output = "";
241
- const cloudflared = clean(opts.cloudflared) || "cloudflared";
242
- tunnel = spawn(cloudflared, buildCloudflaredArgs(localUrl), {
243
- stdio: ["ignore", "pipe", "pipe"],
244
- shell: process.platform === "win32"
245
- });
246
- const onData = (data) => {
247
- const text = data.toString("utf-8");
248
- output += text;
249
- process.stderr.write(text);
250
- const parsed = parseCloudflaredTunnelUrl(output);
251
- if (parsed) resolveTunnel(parsed);
252
- };
253
- tunnel.stdout?.on("data", onData);
254
- tunnel.stderr?.on("data", onData);
255
- tunnel.on("error", reject);
256
- tunnel.on("exit", (code) => {
257
- if (code && code !== 0) reject(new Error(`cloudflared exited with code ${code}`));
258
- });
259
- setTimeout(() => reject(new Error("timed out waiting for cloudflared tunnel URL")), 45e3).unref();
260
- });
261
- writeLine(`Tunnel ready: ${tunnelUrl}`);
262
- await waitForLocalRunner({ url: tunnelUrl, token: runnerToken, instanceId }, 3e4);
263
- writeLine("Tunnel health check passed");
264
- const capabilities = await requestRunner("GET", "/capabilities", {
265
- url: tunnelUrl,
266
- token: runnerToken,
267
- instanceId
268
- });
269
- const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts, {
270
- endpointUrl: tunnelUrl,
271
- token: runnerToken,
272
- placement: "local",
273
- capabilities: Array.isArray(capabilities.capabilities) ? capabilities.capabilities.filter((item) => typeof item === "string") : [],
274
- runnerVersion: clean(opts.runnerVersion) || ""
275
- });
276
- writeLine(JSON.stringify(result, null, 2));
277
- if (!opts.skipProbe) {
278
- const status = await requestPags(
279
- "GET",
280
- `/v1/instances/${apiPathSegment(instanceId)}/runtime/status`,
281
- opts
282
- );
283
- writeLine(JSON.stringify(status, null, 2));
284
- }
285
- writeLine("Connected. Keep this process running while the agent uses your FAGS browser runtime.");
286
- await new Promise((resolvePromise) => {
287
- runner.on("exit", () => resolvePromise());
288
- tunnel?.on("exit", () => resolvePromise());
289
- });
290
- } catch (error) {
291
- shutdown();
292
- throw error;
293
- }
294
- });
295
- command.command("status").description("Check local FAGS runtime health and capabilities").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (opts) => {
296
- const health = await requestRunner("GET", "/health", opts);
297
- const capabilities = await requestRunner("GET", "/capabilities", opts);
298
- writeLine(JSON.stringify({ health, capabilities }, null, 2));
299
- });
300
- command.command("task").description("Create a local FAGS runtime task").requiredOption("--type <type>", "Task type, e.g. echo or browser.open").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").option("--input <json>", "Task input JSON").option("--job-url <url>", "Shortcut input for browser.open").option("--approve", "Create task in needs_approval state").option("--approval-prompt <text>", "Approval prompt").action(
301
- async (opts) => {
302
- let input = {};
303
- if (opts.input) {
304
- try {
305
- input = JSON.parse(opts.input);
306
- } catch {
307
- writeError("--input must be valid JSON");
308
- process.exit(1);
309
- }
310
- }
311
- if (opts.jobUrl) input.url = opts.jobUrl;
312
- const task = await requestRunner("POST", "/tasks", opts, {
313
- type: opts.type,
314
- input,
315
- requiresApproval: Boolean(opts.approve),
316
- approvalPrompt: opts.approvalPrompt
317
- });
318
- writeLine(JSON.stringify(task, null, 2));
319
- }
320
- );
321
- command.command("register <instanceId>").description("Register a local or managed FAGS runtime endpoint with a PAGS instance").requiredOption("--endpoint-url <url>", "FAGS runtime endpoint URL to store in PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--runner-token <token>", "FAGS runtime bearer token to store in PAGS").option("--url <url>", "Local FAGS runtime URL to probe for capabilities").option("--token <token>", "Local FAGS runtime bearer token for capability probe").option("--instance-id <id>", "PAGS instance id header for capability probe").option("--placement <placement>", "Runtime placement: local or managed", "local").option("--runner-version <version>", "Runner version").option("--capability <name>", "Runtime capability; repeatable", collectCapability, []).option("--probe", "Read capabilities from the FAGS runtime before registering").action(async (instanceId, opts) => {
322
- let capabilities = opts.capability || [];
323
- if (opts.probe) {
324
- const data = await requestRunner("GET", "/capabilities", {
325
- url: opts.url || opts.endpointUrl,
326
- token: opts.token || opts.runnerToken,
327
- instanceId: opts.instanceId || instanceId
328
- });
329
- capabilities = Array.isArray(data.capabilities) ? data.capabilities.filter((item) => typeof item === "string") : capabilities;
330
- }
331
- const body = buildRuntimeRegistrationBody(opts, capabilities);
332
- const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts, body);
333
- writeLine(JSON.stringify(result, null, 2));
334
- });
335
- command.command("runtime <instanceId>").description("Read the PAGS runtime registration for an instance").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--probe", "Ask PAGS to probe /health and /capabilities on the FAGS runtime").action(async (instanceId, opts) => {
336
- const path = opts.probe ? `/v1/instances/${apiPathSegment(instanceId)}/runtime/status` : `/v1/instances/${apiPathSegment(instanceId)}/runtime`;
337
- const result = await requestPags("GET", path, opts);
338
- writeLine(JSON.stringify(result, null, 2));
339
- });
340
- command.command("unregister <instanceId>").description("Remove the PAGS runtime registration for an instance").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, opts) => {
341
- const result = await requestPags("DELETE", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts);
342
- writeLine(JSON.stringify(result, null, 2));
343
- });
344
- command.command("run <instanceId>").description("Create a task through PAGS on an instance's registered FAGS runtime").requiredOption("--type <type>", "Task type, e.g. echo or browser.open").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--input <json>", "Task input JSON").option("--job-url <url>", "Shortcut input for browser.open").option("--approve", "Create task in needs_approval state").option("--approval-prompt <text>", "Approval prompt").action(
345
- async (instanceId, opts) => {
346
- let input = {};
347
- if (opts.input) {
348
- try {
349
- input = JSON.parse(opts.input);
350
- } catch {
351
- writeError("--input must be valid JSON");
352
- process.exit(1);
353
- }
354
- }
355
- if (opts.jobUrl) input.url = opts.jobUrl;
356
- const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/tasks`, opts, {
357
- type: opts.type,
358
- input,
359
- requiresApproval: Boolean(opts.approve),
360
- approvalPrompt: opts.approvalPrompt
361
- });
362
- writeLine(JSON.stringify(result, null, 2));
363
- }
364
- );
365
- command.command("approve-task <instanceId> <taskId>").description("Approve a registered FAGS runtime task through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, taskId, opts) => {
366
- const result = await requestPags(
367
- "POST",
368
- `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/approve`,
369
- opts
370
- );
371
- writeLine(JSON.stringify(result, null, 2));
372
- });
373
- command.command("cancel-task <instanceId> <taskId>").description("Cancel a registered FAGS runtime task through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").action(async (instanceId, taskId, opts) => {
374
- const result = await requestPags(
375
- "POST",
376
- `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/cancel`,
377
- opts
378
- );
379
- writeLine(JSON.stringify(result, null, 2));
380
- });
381
- command.command("task-events <instanceId>").description("Read registered FAGS runtime task events through PAGS").option("--api-base <url>", "PAGS API base URL").option("--pags-token <token>", "PAGS session token. Defaults to PAGS_TOKEN").option("--limit <n>", "Number of events", "50").action(async (instanceId, opts) => {
382
- const result = await requestPags(
383
- "GET",
384
- `/v1/instances/${apiPathSegment(instanceId)}/task-events?limit=${Number(opts.limit) || 50}`,
385
- opts
386
- );
387
- writeLine(JSON.stringify(result, null, 2));
388
- });
389
- command.command("approve <taskId>").description("Approve a task waiting on human approval").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (taskId, opts) => {
390
- const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/approve`, opts);
391
- writeLine(JSON.stringify(task, null, 2));
392
- });
393
- command.command("cancel <taskId>").description("Cancel a local FAGS runtime task").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").action(async (taskId, opts) => {
394
- const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/cancel`, opts);
395
- writeLine(JSON.stringify(task, null, 2));
396
- });
397
- command.command("events").description("List recent FAGS runtime events").option("--url <url>", "Runner URL").option("--token <token>", "Runner bearer token").option("--instance-id <id>", "PAGS instance id header").option("--limit <n>", "Number of events", "50").action(async (opts) => {
398
- const events = await requestRunner("GET", `/events?limit=${Number(opts.limit) || 50}`, opts);
399
- writeLine(JSON.stringify(events, null, 2));
400
- });
401
- return command;
402
- }
403
-
404
- export {
405
- __require,
406
- writeLine,
407
- writeError,
408
- runnerCommand,
409
- runnerBaseUrl,
410
- pagsApiBase,
411
- pagsHeaders,
412
- runnerHeaders,
413
- runnerRequestHeaders,
414
- apiPathSegment,
415
- buildRunnerArgs,
416
- buildCloudflaredArgs,
417
- parseCloudflaredTunnelUrl,
418
- buildRuntimeRegistrationBody,
419
- bundledRunnerPath,
420
- requestRunner,
421
- requestPags,
422
- createRunnerCommand
423
- };
@@ -1,34 +0,0 @@
1
- import {
2
- apiPathSegment,
3
- buildCloudflaredArgs,
4
- buildRunnerArgs,
5
- buildRuntimeRegistrationBody,
6
- bundledRunnerPath,
7
- createRunnerCommand,
8
- pagsApiBase,
9
- pagsHeaders,
10
- parseCloudflaredTunnelUrl,
11
- requestPags,
12
- requestRunner,
13
- runnerBaseUrl,
14
- runnerCommand,
15
- runnerHeaders,
16
- runnerRequestHeaders
17
- } from "./chunk-LNY7MNUC.js";
18
- export {
19
- apiPathSegment,
20
- buildCloudflaredArgs,
21
- buildRunnerArgs,
22
- buildRuntimeRegistrationBody,
23
- bundledRunnerPath,
24
- createRunnerCommand,
25
- pagsApiBase,
26
- pagsHeaders,
27
- parseCloudflaredTunnelUrl,
28
- requestPags,
29
- requestRunner,
30
- runnerBaseUrl,
31
- runnerCommand,
32
- runnerHeaders,
33
- runnerRequestHeaders
34
- };