@proagentstore/cli 0.4.116 → 0.4.118

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/bootstrap.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  newestPayload,
9
9
  olderThan,
10
10
  payloadAt
11
- } from "./chunk-RGNU4W6B.js";
11
+ } from "./chunk-LQ57ADUG.js";
12
12
 
13
13
  // src/bootstrap.ts
14
14
  import { existsSync } from "fs";
@@ -24,7 +24,9 @@ export class CodingRuntime {
24
24
  */
25
25
  liveWork() {
26
26
  return [...this.sessions.entries()].flatMap(([sessionId, s]) => {
27
- const engine = s.clientType ?? "";
27
+ // The engine lives on the session's CONFIG (#1053): reading a top-level `clientType` — which a
28
+ // HeadlessSession does not have — labelled every live Claude turn "coding turn is lost on a restart".
29
+ const engine = s.config?.clientType ?? "";
28
30
  const consequence = engine === "claude" ? "Claude conversation resumes after a restart" : `${engine || "coding"} turn is lost on a restart`;
29
31
  try {
30
32
  // `alive: false` is an observed inactive session. Any other answer (including a
@@ -2,7 +2,7 @@
2
2
  import { execFile } from "child_process";
3
3
  import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync } from "fs";
4
4
  import { homedir } from "os";
5
- import { join } from "path";
5
+ import { join, win32 } from "path";
6
6
  import { promisify } from "util";
7
7
  var run = promisify(execFile);
8
8
  var CLI_PACKAGE = "@proagentstore/cli";
@@ -47,9 +47,32 @@ function cachedPayloads(root = payloadRoot()) {
47
47
  function newestPayload(payloads) {
48
48
  return payloads.reduce((best, p) => !best || olderThan(best.version, p.version) ? p : best, null);
49
49
  }
50
+ var CMD_META = /([()\][%!^"`<>&|;, *?])/g;
51
+ function quoteCmdArg(arg) {
52
+ const quoted = `"${arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
53
+ return quoted.replace(CMD_META, "^$1").replace(CMD_META, "^$1");
54
+ }
55
+ var envVar = (env, name) => env[Object.keys(env).find((k) => k.toUpperCase() === name) ?? name];
56
+ function npmInvocation(args, deps = {}) {
57
+ if ((deps.platform ?? process.platform) !== "win32") return { file: "npm", args };
58
+ const env = deps.env ?? process.env;
59
+ const exists = deps.exists ?? existsSync;
60
+ const execPath = deps.execPath ?? process.execPath;
61
+ const cli = (dir) => win32.join(dir, "node_modules", "npm", "bin", "npm-cli.js");
62
+ const onPath = (envVar(env, "PATH") ?? "").split(";").filter((dir) => dir && exists(win32.join(dir, "npm.cmd")));
63
+ for (const dir of [...onPath, win32.dirname(execPath)]) {
64
+ if (exists(cli(dir))) return { file: execPath, args: [cli(dir), ...args] };
65
+ }
66
+ const line = ["npm", ...args.map(quoteCmdArg)].join(" ");
67
+ return { file: envVar(env, "COMSPEC") || "cmd.exe", args: ["/d", "/s", "/c", `"${line}"`], windowsVerbatimArguments: true };
68
+ }
69
+ function runNpm(args, options) {
70
+ const npm = npmInvocation(args);
71
+ return run(npm.file, npm.args, { ...options, ...npm.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {} });
72
+ }
50
73
  async function latestPublishedVersion(timeoutMs = 3e4, signal) {
51
74
  try {
52
- const { stdout } = await run("npm", ["view", CLI_PACKAGE, "version"], { timeout: timeoutMs, signal });
75
+ const { stdout } = await runNpm(["view", CLI_PACKAGE, "version"], { timeout: timeoutMs, signal });
53
76
  return stdout.trim() || null;
54
77
  } catch {
55
78
  return null;
@@ -57,7 +80,7 @@ async function latestPublishedVersion(timeoutMs = 3e4, signal) {
57
80
  }
58
81
  async function npmInstallInto(dir, version) {
59
82
  try {
60
- await run("npm", ["install", "--prefix", dir, "--omit=dev", "--no-audit", "--no-fund", "--no-save", `${CLI_PACKAGE}@${version}`], { timeout: 5 * 6e4 });
83
+ await runNpm(["install", "--prefix", dir, "--omit=dev", "--no-audit", "--no-fund", "--no-save", `${CLI_PACKAGE}@${version}`], { timeout: 5 * 6e4 });
61
84
  } catch (e) {
62
85
  const stderr = String(e.stderr ?? "").trim();
63
86
  throw new Error((stderr || (e instanceof Error ? e.message : String(e))).slice(-400));
@@ -96,6 +119,7 @@ export {
96
119
  payloadAt,
97
120
  cachedPayloads,
98
121
  newestPayload,
122
+ runNpm,
99
123
  latestPublishedVersion,
100
124
  installPayload
101
125
  };
package/dist/index.js CHANGED
@@ -5,8 +5,9 @@ import {
5
5
  installPayload,
6
6
  isVersion,
7
7
  latestPublishedVersion,
8
- olderThan
9
- } from "./chunk-RGNU4W6B.js";
8
+ olderThan,
9
+ runNpm
10
+ } from "./chunk-LQ57ADUG.js";
10
11
 
11
12
  // src/index.ts
12
13
  import { createRequire as createRequire3 } from "module";
@@ -1256,9 +1257,7 @@ function sampleResources(read = os, now = Date.now(), extra = {}) {
1256
1257
  }
1257
1258
 
1258
1259
  // src/commands/runner/self-update.ts
1259
- import { execFile, spawn as spawn3 } from "child_process";
1260
- import { promisify } from "util";
1261
- var run = promisify(execFile);
1260
+ import { spawn as spawn3 } from "child_process";
1262
1261
  var RUNNER_UPDATE_PATH = "/pags/runner/update";
1263
1262
  var RUNNER_RESTART_PATH = "/pags/runner/restart";
1264
1263
  var RUNNER_RESTART_EXIT_CODE = 75;
@@ -1306,7 +1305,7 @@ function restartUpArgs(opts) {
1306
1305
  }
1307
1306
  function planRunnerUpdate(f) {
1308
1307
  if (f.fromSource) return { action: "refused", current: f.current, reason: "This runner runs from a source checkout \u2014 update it with `git pull` there, not npm." };
1309
- if (!f.latest) return { action: "refused", current: f.current, reason: `npm could not be asked for the latest ${CLI_PACKAGE} from this machine.` };
1308
+ if (!f.latest) return { action: "refused", current: f.current, reason: `npm could not be asked for the latest ${CLI_PACKAGE} from this machine.`, retryable: true };
1310
1309
  if (!olderThan(f.current, f.latest)) return { action: "up-to-date", current: f.current };
1311
1310
  if (!f.restarter) {
1312
1311
  return {
@@ -1346,7 +1345,7 @@ async function installVersion(version2) {
1346
1345
  return;
1347
1346
  }
1348
1347
  try {
1349
- await run("npm", ["i", "-g", `${CLI_PACKAGE}@${version2}`], { timeout: 5 * 6e4 });
1348
+ await runNpm(["i", "-g", `${CLI_PACKAGE}@${version2}`], { timeout: 5 * 6e4 });
1350
1349
  } catch (e) {
1351
1350
  const stderr = String(e.stderr ?? "").trim();
1352
1351
  throw new Error((stderr || (e instanceof Error ? e.message : String(e))).slice(-400));
@@ -1984,7 +1983,8 @@ var AutomaticUpdateController = class {
1984
1983
  return;
1985
1984
  }
1986
1985
  if (plan.action === "refused") {
1987
- this.deps.status("unsupported", { reason: plan.reason });
1986
+ if (plan.retryable) this.failures++;
1987
+ this.deps.status(plan.retryable ? "failure" : "unsupported", { reason: plan.reason });
1988
1988
  this.schedule();
1989
1989
  return;
1990
1990
  }
@@ -2073,16 +2073,35 @@ function isWorkShape(work) {
2073
2073
  const w2 = work;
2074
2074
  return count(w2.codingTurns) && count(w2.localRuns) && Array.isArray(w2.detail) && w2.detail.every((item) => typeof item === "string");
2075
2075
  }
2076
+ function sessionStateOf(session) {
2077
+ if (!session || typeof session !== "object") return "unknown";
2078
+ const s = session;
2079
+ if (s.alive === false) return "stopped";
2080
+ const state = typeof s.runState === "string" && s.runState ? s.runState : null;
2081
+ if (s.alive !== true || !state) return "unknown";
2082
+ return state === "idle" ? "idle_retained" : "active_turn";
2083
+ }
2084
+ function sessionStateCounts(sessions) {
2085
+ const counts = { activeTurns: 0, idleRetained: 0, stopped: 0, unknown: 0 };
2086
+ for (const session of sessions) {
2087
+ const state = sessionStateOf(session);
2088
+ if (state === "active_turn") counts.activeTurns++;
2089
+ else if (state === "idle_retained") counts.idleRetained++;
2090
+ else if (state === "stopped") counts.stopped++;
2091
+ else counts.unknown++;
2092
+ }
2093
+ return counts;
2094
+ }
2076
2095
  function observedRunnerWork(observation) {
2077
2096
  const sessions = observation.sessions;
2078
2097
  const work = observation.work;
2079
2098
  if (!Array.isArray(sessions) || !isWorkShape(work)) return ["runner-work-observation-unavailable"];
2080
2099
  const { codingTurns, localRuns, detail } = work;
2081
2100
  const activeCoding = sessions.flatMap((session) => {
2082
- if (session?.alive === false) return [];
2101
+ const kind = sessionStateOf(session);
2102
+ if (kind === "stopped" || kind === "idle_retained") return [];
2083
2103
  const id = typeof session?.sessionId === "string" && session.sessionId ? session.sessionId : "unidentified-session";
2084
2104
  const state = typeof session?.runState === "string" && session.runState ? session.runState : "unknown";
2085
- if (session?.alive === true && state === "idle") return [];
2086
2105
  return [`coding session ${id} (${state})`];
2087
2106
  });
2088
2107
  const unmatchedCodingTurns = Math.max(0, codingTurns - activeCoding.length);
@@ -2100,7 +2119,14 @@ function readWorkLook(sessions, health, sampledAt) {
2100
2119
  return {
2101
2120
  busy,
2102
2121
  observations: [
2103
- { source: "sessions", success: sessionsOk, sampledAt, ...sessions.status === "fulfilled" && !sessionsOk ? { malformed: true } : {} },
2122
+ {
2123
+ source: "sessions",
2124
+ success: sessionsOk,
2125
+ sampledAt,
2126
+ ...sessions.status === "fulfilled" && !sessionsOk ? { malformed: true } : {},
2127
+ // What the readable list held, by lifecycle state — counts only (#1020).
2128
+ ...sessions.status === "fulfilled" && sessionsOk ? { sessionStates: sessionStateCounts(sessions.value.sessions) } : {}
2129
+ },
2104
2130
  { source: "health", success: healthOk, sampledAt, ...health.status === "fulfilled" && !healthOk ? { malformed: true } : {} }
2105
2131
  ]
2106
2132
  };
@@ -2193,7 +2219,7 @@ function createInstallBridge(deps) {
2193
2219
  release(drained);
2194
2220
  throw new BoundExpired(`${what} did not answer within ${(deps.bound?.ms ?? 3e4) / 1e3}s; nothing restarted, and it will be retried.`);
2195
2221
  };
2196
- const run2 = async (plan, automatic = false, lease) => {
2222
+ const run = async (plan, automatic = false, lease) => {
2197
2223
  if (inFlight || lease && !deps.leaseActive(lease)) return false;
2198
2224
  inFlight = true;
2199
2225
  if (automatic) {
@@ -2240,7 +2266,7 @@ function createInstallBridge(deps) {
2240
2266
  deps.detachAll();
2241
2267
  return true;
2242
2268
  };
2243
- return { run: run2, inFlight: () => inFlight, installedPendingRestart: () => installedPendingRestart };
2269
+ return { run, inFlight: () => inFlight, installedPendingRestart: () => installedPendingRestart };
2244
2270
  }
2245
2271
 
2246
2272
  // src/commands/runner/relay.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.116",
3
+ "version": "0.4.118",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",