@proagentstore/cli 0.4.11 → 0.4.13

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.
@@ -33,9 +33,14 @@ export class HeadlessSession {
33
33
  this.cmdArgs = args;
34
34
  this.binName = (this.cmdBin.split("/").pop() || this.cmdBin) || "cli";
35
35
  }
36
- /** True while the agent process is running. */
36
+ /** True while the agent process is running. NOTE: do NOT use `proc.killed` — Node sets
37
+ * it true the instant a signal is DELIVERED, not when the process exits. interrupt()
38
+ * SIGINTs to abort a turn while the process keeps running, so `killed` gave a false
39
+ * "dead" → input() then spawned a SECOND process (orphaning the first). exitCode is
40
+ * null while running and set on normal exit; signalCode is set when a signal actually
41
+ * terminated it — together they're the real liveness signal. */
37
42
  get alive() {
38
- return this.proc !== null && this.proc.exitCode === null && !this.proc.killed;
43
+ return this.proc !== null && this.proc.exitCode === null && this.proc.signalCode === null;
39
44
  }
40
45
  /** Idle = ready for the next instruction. */
41
46
  get ready() {
@@ -275,8 +280,12 @@ export function buildClaudeArgs(userArgs, resumeId) {
275
280
  i++;
276
281
  continue;
277
282
  }
278
- if (!args.includes(a))
279
- args.push(a);
283
+ // Push every user token as-is. A previous `!args.includes(a)` dedup silently
284
+ // dropped a REPEATED flag token (e.g. the 2nd `--add-dir` in `--add-dir /a
285
+ // --add-dir /b`), which orphaned its value (`/b` became a stray positional).
286
+ // Our own structural flags are already protected via RESERVED_CLAUDE_FLAGS, so
287
+ // no dedup is needed here.
288
+ args.push(a);
280
289
  }
281
290
  if (!args.includes("--dangerously-skip-permissions"))
282
291
  args.push("--dangerously-skip-permissions");
@@ -54,7 +54,11 @@ export class CodingRuntime {
54
54
  snapshot(sessionId) {
55
55
  const session = this.require(sessionId);
56
56
  const alive = session.alive;
57
- const pane = alive ? clip(session.snapshot()) : "";
57
+ // ALWAYS return the transcript — it holds the produced output AND the
58
+ // `[exited with code N]` / `[error]` lines recorded on exit. Blanking it when the
59
+ // process is dead lost exactly the output + failure reason the brain/console needs
60
+ // to diagnose a crash or read a one-shot CLI's final result.
61
+ const pane = clip(session.snapshot());
58
62
  return {
59
63
  sessionId,
60
64
  pane,
@@ -67,9 +67,9 @@ if (!config.token && !LOOPBACK.has(config.host)) {
67
67
  process.exit(1);
68
68
  }
69
69
  const started = await startRunnerServer(config);
70
- process.stdout.write(`FAGS browser runtime listening at ${started.url}\n`);
70
+ process.stdout.write(`ProAgentStore browser runtime listening at ${started.url}\n`);
71
71
  process.stdout.write(`Data dir: ${config.dataDir}\n`);
72
- process.stdout.write("Control plane: PAGS; runtime plane: FAGS; brain placement: PAGS; runner role: tool-executor\n");
72
+ process.stdout.write("Control plane: PAGS; runtime plane: PAGS; brain placement: PAGS; runner role: tool-executor\n");
73
73
  if (config.token)
74
74
  process.stdout.write("Auth: bearer token required\n");
75
75
  if (config.instanceId)
@@ -74,10 +74,10 @@ export class LocalRunner {
74
74
  }
75
75
  capabilities() {
76
76
  return {
77
- runtime: "fags-browser-runtime",
77
+ runtime: "pags-browser-runtime",
78
78
  brainPlacement: "pags",
79
79
  controlPlane: "pags",
80
- runtimePlane: "fags",
80
+ runtimePlane: "pags",
81
81
  runnerRole: "tool-executor",
82
82
  capabilities: [...CAPABILITIES, ...CodingRuntime.capabilities()],
83
83
  taskTypes: ["echo", "browser.open", "job.apply_agent", ...CodingRuntime.taskTypes()],
@@ -42,10 +42,10 @@ async function route(runner, req, res) {
42
42
  if ((req.method === "GET" || req.method === "POST") && path === "/health") {
43
43
  return json(res, 200, {
44
44
  ok: true,
45
- service: "freeagentstore-browser-runtime",
45
+ service: "proagentstore-browser-runtime",
46
46
  brainPlacement: "pags",
47
47
  controlPlane: "pags",
48
- runtimePlane: "fags",
48
+ runtimePlane: "pags",
49
49
  instanceId: runner.config.instanceId,
50
50
  });
51
51
  }
package/dist/index.js CHANGED
@@ -932,9 +932,9 @@ function openRelaySocket(instanceId, wsBase, mintToken, localUrl, runnerToken, f
932
932
  }
933
933
  function createRunnerCommand() {
934
934
  const command = new Command6("runner").description(
935
- "Manage the local FAGS browser runtime for ProAgentStore agents"
935
+ "Manage the local ProAgentStore browser runtime for ProAgentStore agents"
936
936
  );
937
- 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) => {
937
+ command.command("start").description("Start the local ProAgentStore 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) => {
938
938
  await startRunnerForeground(opts);
939
939
  });
940
940
  command.command("connect <instanceIds...>").description("Start ONE local runtime, connect via WebSocket relay, and register it for every given PAGS instance").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("--runner-version <version>", "Runner version").option("--force", "Take over from another connected machine").action(async (instanceIds, opts) => {
@@ -952,10 +952,14 @@ function createRunnerCommand() {
952
952
  });
953
953
  runner.stdout?.on("data", (data) => process.stdout.write(data));
954
954
  runner.stderr?.on("data", (data) => process.stderr.write(data));
955
+ let shuttingDown = false;
955
956
  runner.on("exit", (code) => {
956
- if (code && code !== 0) writeError(`runner exited with code ${code}`);
957
+ if (shuttingDown) return;
958
+ writeError(`Local browser runtime exited unexpectedly${code ? ` (code ${code})` : ""}. Run \`pags up\` again to reconnect.`);
959
+ process.exit(code ?? 1);
957
960
  });
958
961
  const shutdown = () => {
962
+ shuttingDown = true;
959
963
  if (!runner.killed) runner.kill("SIGTERM");
960
964
  };
961
965
  process.once("SIGINT", () => {
@@ -968,7 +972,7 @@ function createRunnerCommand() {
968
972
  });
969
973
  try {
970
974
  await waitForLocalRunner({ url: localUrl, token: runnerToken, instanceId: primary });
971
- writeLine(`Local FAGS runtime healthy at ${localUrl}`);
975
+ writeLine(`Local browser runtime healthy at ${localUrl}`);
972
976
  await connectViaRelay(instanceIds, localUrl, runnerToken, opts, Boolean(opts.force));
973
977
  await new Promise((resolvePromise) => {
974
978
  runner.on("exit", () => resolvePromise());
@@ -978,12 +982,12 @@ function createRunnerCommand() {
978
982
  throw error;
979
983
  }
980
984
  });
981
- 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) => {
985
+ command.command("status").description("Check local browser 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) => {
982
986
  const health = await requestRunner("GET", "/health", opts);
983
987
  const capabilities = await requestRunner("GET", "/capabilities", opts);
984
988
  writeLine(JSON.stringify({ health, capabilities }, null, 2));
985
989
  });
986
- 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(
990
+ command.command("task").description("Create a local browser 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(
987
991
  async (opts) => {
988
992
  let input = {};
989
993
  if (opts.input) {
@@ -1004,7 +1008,7 @@ function createRunnerCommand() {
1004
1008
  writeLine(JSON.stringify(task, null, 2));
1005
1009
  }
1006
1010
  );
1007
- 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) => {
1011
+ command.command("register <instanceId>").description("Register a local or managed browser runtime endpoint with a PAGS instance").requiredOption("--endpoint-url <url>", "browser 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>", "browser runtime bearer token to store in PAGS").option("--url <url>", "Local browser runtime URL to probe for capabilities").option("--token <token>", "Local browser 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 browser runtime before registering").action(async (instanceId, opts) => {
1008
1012
  let capabilities = opts.capability || [];
1009
1013
  if (opts.probe) {
1010
1014
  const data = await requestRunner("GET", "/capabilities", {
@@ -1018,7 +1022,7 @@ function createRunnerCommand() {
1018
1022
  const result = await requestPags("POST", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts, body);
1019
1023
  writeLine(JSON.stringify(result, null, 2));
1020
1024
  });
1021
- 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) => {
1025
+ 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 browser runtime").action(async (instanceId, opts) => {
1022
1026
  const path = opts.probe ? `/v1/instances/${apiPathSegment(instanceId)}/runtime/status` : `/v1/instances/${apiPathSegment(instanceId)}/runtime`;
1023
1027
  const result = await requestPags("GET", path, opts);
1024
1028
  writeLine(JSON.stringify(result, null, 2));
@@ -1027,7 +1031,7 @@ function createRunnerCommand() {
1027
1031
  const result = await requestPags("DELETE", `/v1/instances/${apiPathSegment(instanceId)}/runtime`, opts);
1028
1032
  writeLine(JSON.stringify(result, null, 2));
1029
1033
  });
1030
- 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(
1034
+ command.command("run <instanceId>").description("Create a task through PAGS on an instance's registered browser 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(
1031
1035
  async (instanceId, opts) => {
1032
1036
  let input = {};
1033
1037
  if (opts.input) {
@@ -1048,7 +1052,7 @@ function createRunnerCommand() {
1048
1052
  writeLine(JSON.stringify(result, null, 2));
1049
1053
  }
1050
1054
  );
1051
- 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) => {
1055
+ command.command("approve-task <instanceId> <taskId>").description("Approve a registered browser 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) => {
1052
1056
  const result = await requestPags(
1053
1057
  "POST",
1054
1058
  `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/approve`,
@@ -1056,7 +1060,7 @@ function createRunnerCommand() {
1056
1060
  );
1057
1061
  writeLine(JSON.stringify(result, null, 2));
1058
1062
  });
1059
- 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) => {
1063
+ command.command("cancel-task <instanceId> <taskId>").description("Cancel a registered browser 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) => {
1060
1064
  const result = await requestPags(
1061
1065
  "POST",
1062
1066
  `/v1/instances/${apiPathSegment(instanceId)}/tasks/${apiPathSegment(taskId)}/cancel`,
@@ -1064,7 +1068,7 @@ function createRunnerCommand() {
1064
1068
  );
1065
1069
  writeLine(JSON.stringify(result, null, 2));
1066
1070
  });
1067
- 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) => {
1071
+ command.command("task-events <instanceId>").description("Read registered browser 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) => {
1068
1072
  const result = await requestPags(
1069
1073
  "GET",
1070
1074
  `/v1/instances/${apiPathSegment(instanceId)}/task-events?limit=${Number(opts.limit) || 50}`,
@@ -1076,11 +1080,11 @@ function createRunnerCommand() {
1076
1080
  const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/approve`, opts);
1077
1081
  writeLine(JSON.stringify(task, null, 2));
1078
1082
  });
1079
- 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) => {
1083
+ command.command("cancel <taskId>").description("Cancel a local browser 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) => {
1080
1084
  const task = await requestRunner("POST", `/tasks/${apiPathSegment(taskId)}/cancel`, opts);
1081
1085
  writeLine(JSON.stringify(task, null, 2));
1082
1086
  });
1083
- 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) => {
1087
+ command.command("events").description("List recent browser 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) => {
1084
1088
  const events = await requestRunner("GET", `/events?limit=${Number(opts.limit) || 50}`, opts);
1085
1089
  writeLine(JSON.stringify(events, null, 2));
1086
1090
  });
@@ -1289,7 +1293,7 @@ var upCommand = new Command7("up").description("Start the browser runner for all
1289
1293
  printStatus(state);
1290
1294
  continue;
1291
1295
  }
1292
- if (trimmed.includes("FAGS browser runtime listening")) {
1296
+ if (trimmed.includes("browser runtime listening")) {
1293
1297
  state.runner = "online";
1294
1298
  state.lastEvent = "Runner started";
1295
1299
  printStatus(state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",