@h-rig/cli 0.0.6-alpha.66 → 0.0.6-alpha.67

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/bin/rig.js CHANGED
@@ -2923,6 +2923,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
2923
2923
  return;
2924
2924
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
2925
2925
  }
2926
+ function isRemoteConnectionSelected(projectRoot) {
2927
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
2928
+ }
2926
2929
 
2927
2930
  // packages/cli/src/commands/_server-client.ts
2928
2931
  init_runner();
@@ -7849,9 +7852,6 @@ function normalizeRemoteRunDetails(payload) {
7849
7852
  };
7850
7853
  }
7851
7854
  var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
7852
- function isRemoteConnectionSelected(projectRoot) {
7853
- return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
7854
- }
7855
7855
  async function listRunsForSelectedConnection(context, options = {}) {
7856
7856
  if (isRemoteConnectionSelected(context.projectRoot)) {
7857
7857
  return { runs: await listRunsViaServer(context, options), source: "server" };
@@ -8201,28 +8201,38 @@ async function executeRun(context, args) {
8201
8201
  };
8202
8202
  }
8203
8203
  case "resume": {
8204
- requireNoExtraArgs(rest, "rig run resume");
8204
+ let pending = rest;
8205
+ const runOpt = takeOption(pending, "--run");
8206
+ pending = runOpt.rest;
8207
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8208
+ requireNoExtraArgs(pending, "rig run resume [<run-id>] [--run <id>]");
8209
+ const targetRunId = runOpt.value ?? positional ?? null;
8205
8210
  if (context.dryRun) {
8206
8211
  if (context.outputMode === "text") {
8207
8212
  console.log("[dry-run] rig run resume");
8208
8213
  }
8209
8214
  return { ok: true, group: "run", command };
8210
8215
  }
8211
- const resumed = await runResume(context.projectRoot, runtimeContext);
8216
+ const resumed = await runResume(context.projectRoot, runtimeContext, targetRunId);
8212
8217
  if (context.outputMode === "text") {
8213
8218
  console.log(`Resumed run: ${resumed.runId}`);
8214
8219
  }
8215
8220
  return { ok: true, group: "run", command, details: resumed };
8216
8221
  }
8217
8222
  case "restart": {
8218
- requireNoExtraArgs(rest, "rig run restart");
8223
+ let pending = rest;
8224
+ const runOpt = takeOption(pending, "--run");
8225
+ pending = runOpt.rest;
8226
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8227
+ requireNoExtraArgs(pending, "rig run restart [<run-id>] [--run <id>]");
8228
+ const targetRunId = runOpt.value ?? positional ?? null;
8219
8229
  if (context.dryRun) {
8220
8230
  if (context.outputMode === "text") {
8221
8231
  console.log("[dry-run] rig run restart");
8222
8232
  }
8223
8233
  return { ok: true, group: "run", command };
8224
8234
  }
8225
- const restarted = await runRestart(context.projectRoot, runtimeContext);
8235
+ const restarted = await runRestart(context.projectRoot, runtimeContext, targetRunId);
8226
8236
  if (context.outputMode === "text") {
8227
8237
  console.log(`Restarted run: ${restarted.runId}`);
8228
8238
  }
@@ -8517,10 +8527,7 @@ async function executeServer(context, args, options) {
8517
8527
  // packages/cli/src/commands/stats.ts
8518
8528
  init_runner();
8519
8529
  import pc5 from "picocolors";
8520
- import {
8521
- listAuthorityRuns as listAuthorityRuns3,
8522
- projectRunFromJournal
8523
- } from "@rig/runtime/control-plane/authority-files";
8530
+ import { computeRigStats } from "@rig/runtime/control-plane/native/run-stats";
8524
8531
 
8525
8532
  // packages/cli/src/commands/_help-catalog.ts
8526
8533
  import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
@@ -9009,90 +9016,6 @@ function parseSinceOption(value, now = new Date) {
9009
9016
  }
9010
9017
  return new Date(parsed);
9011
9018
  }
9012
- function median(values) {
9013
- if (values.length === 0)
9014
- return null;
9015
- const sorted = [...values].sort((left, right) => left - right);
9016
- const middle = Math.floor(sorted.length / 2);
9017
- const upper = sorted[middle];
9018
- if (sorted.length % 2 === 1)
9019
- return upper;
9020
- return (sorted[middle - 1] + upper) / 2;
9021
- }
9022
- function rate(part, total) {
9023
- if (total === 0)
9024
- return null;
9025
- return part / total;
9026
- }
9027
- function parseTimestamp(value) {
9028
- if (!value)
9029
- return null;
9030
- const parsed = Date.parse(value);
9031
- return Number.isFinite(parsed) ? parsed : null;
9032
- }
9033
- function computeRigStats(projectRoot, options = {}) {
9034
- const since = options.since ?? null;
9035
- const sinceMs = since ? since.getTime() : null;
9036
- const runs = listAuthorityRuns3(projectRoot).filter((run) => {
9037
- if (sinceMs === null)
9038
- return true;
9039
- const createdAt = parseTimestamp(run.createdAt) ?? parseTimestamp(run.updatedAt);
9040
- return createdAt !== null && createdAt >= sinceMs;
9041
- });
9042
- const statusCounts = {};
9043
- const completionDurations = [];
9044
- let steeringTotal = 0;
9045
- let stallTotal = 0;
9046
- let approvalsApproved = 0;
9047
- let approvalsRejected = 0;
9048
- let approvalsPending = 0;
9049
- for (const run of runs) {
9050
- const status = run.status ?? "unknown";
9051
- statusCounts[status] = (statusCounts[status] ?? 0) + 1;
9052
- if (status === "completed") {
9053
- const createdAt = parseTimestamp(run.createdAt);
9054
- const completedAt = parseTimestamp(run.completedAt);
9055
- if (createdAt !== null && completedAt !== null && completedAt >= createdAt) {
9056
- completionDurations.push(completedAt - createdAt);
9057
- }
9058
- }
9059
- const projection = projectRunFromJournal(projectRoot, run.runId);
9060
- if (!projection)
9061
- continue;
9062
- steeringTotal += projection.steeringCount;
9063
- stallTotal += projection.stallCount;
9064
- approvalsPending += projection.pendingApprovals.length;
9065
- for (const resolved of projection.resolvedApprovals) {
9066
- if (resolved.decision === "approve")
9067
- approvalsApproved += 1;
9068
- else
9069
- approvalsRejected += 1;
9070
- }
9071
- }
9072
- const totalRuns = runs.length;
9073
- const completedRuns = statusCounts["completed"] ?? 0;
9074
- const failedRuns = statusCounts["failed"] ?? 0;
9075
- const needsAttentionRuns = statusCounts["needs-attention"] ?? 0;
9076
- return {
9077
- since: since ? since.toISOString() : null,
9078
- totalRuns,
9079
- statusCounts,
9080
- completedRuns,
9081
- failedRuns,
9082
- needsAttentionRuns,
9083
- completionRate: rate(completedRuns, totalRuns),
9084
- failureRate: rate(failedRuns, totalRuns),
9085
- needsAttentionRate: rate(needsAttentionRuns, totalRuns),
9086
- medianCompletionMs: median(completionDurations),
9087
- steeringTotal,
9088
- steeringPerRun: totalRuns === 0 ? null : steeringTotal / totalRuns,
9089
- stallTotal,
9090
- approvalsRequested: approvalsApproved + approvalsRejected + approvalsPending,
9091
- approvalsApproved,
9092
- approvalsRejected,
9093
- approvalsPending
9094
- };
9095
- }
9096
9019
  function formatPercent(value) {
9097
9020
  if (value === null)
9098
9021
  return "\u2014";
@@ -9150,7 +9073,7 @@ async function executeStats(context, args) {
9150
9073
  const sinceResult = takeOption(pending, "--since");
9151
9074
  requireNoExtraArgs(sinceResult.rest, "rig stats [show] [--since <7d|30d|ISO date>]");
9152
9075
  const since = parseSinceOption(sinceResult.value);
9153
- const stats = computeRigStats(context.projectRoot, { since });
9076
+ const stats = isRemoteConnectionSelected(context.projectRoot) ? await requestServerJson(context, `/api/stats${since ? `?since=${encodeURIComponent(since.toISOString())}` : ""}`) : computeRigStats(context.projectRoot, { since });
9154
9077
  if (context.outputMode === "text") {
9155
9078
  printFormattedOutput(formatStatsReport(stats));
9156
9079
  }
@@ -125,6 +125,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
125
125
  return;
126
126
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
127
127
  }
128
+ function isRemoteConnectionSelected(projectRoot) {
129
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
130
+ }
128
131
  export {
129
132
  writeRepoServerProjectRoot,
130
133
  writeRepoConnection,
@@ -134,5 +137,6 @@ export {
134
137
  resolveRepoConnectionPath,
135
138
  resolveGlobalConnectionsPath,
136
139
  readRepoConnection,
137
- readGlobalConnections
140
+ readGlobalConnections,
141
+ isRemoteConnectionSelected
138
142
  };
@@ -188,6 +188,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
188
188
  return;
189
189
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
190
190
  }
191
+ function isRemoteConnectionSelected(projectRoot) {
192
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
193
+ }
191
194
 
192
195
  // packages/cli/src/commands/_server-client.ts
193
196
  var scopedGitHubBearerTokens = new Map;
@@ -1167,9 +1170,6 @@ function normalizeRemoteRunDetails(payload) {
1167
1170
  };
1168
1171
  }
1169
1172
  var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
1170
- function isRemoteConnectionSelected(projectRoot) {
1171
- return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
1172
- }
1173
1173
  async function listRunsForSelectedConnection(context, options = {}) {
1174
1174
  if (isRemoteConnectionSelected(context.projectRoot)) {
1175
1175
  return { runs: await listRunsViaServer(context, options), source: "server" };
@@ -1519,28 +1519,38 @@ async function executeRun(context, args) {
1519
1519
  };
1520
1520
  }
1521
1521
  case "resume": {
1522
- requireNoExtraArgs(rest, "rig run resume");
1522
+ let pending = rest;
1523
+ const runOpt = takeOption(pending, "--run");
1524
+ pending = runOpt.rest;
1525
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
1526
+ requireNoExtraArgs(pending, "rig run resume [<run-id>] [--run <id>]");
1527
+ const targetRunId = runOpt.value ?? positional ?? null;
1523
1528
  if (context.dryRun) {
1524
1529
  if (context.outputMode === "text") {
1525
1530
  console.log("[dry-run] rig run resume");
1526
1531
  }
1527
1532
  return { ok: true, group: "run", command };
1528
1533
  }
1529
- const resumed = await runResume(context.projectRoot, runtimeContext);
1534
+ const resumed = await runResume(context.projectRoot, runtimeContext, targetRunId);
1530
1535
  if (context.outputMode === "text") {
1531
1536
  console.log(`Resumed run: ${resumed.runId}`);
1532
1537
  }
1533
1538
  return { ok: true, group: "run", command, details: resumed };
1534
1539
  }
1535
1540
  case "restart": {
1536
- requireNoExtraArgs(rest, "rig run restart");
1541
+ let pending = rest;
1542
+ const runOpt = takeOption(pending, "--run");
1543
+ pending = runOpt.rest;
1544
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
1545
+ requireNoExtraArgs(pending, "rig run restart [<run-id>] [--run <id>]");
1546
+ const targetRunId = runOpt.value ?? positional ?? null;
1537
1547
  if (context.dryRun) {
1538
1548
  if (context.outputMode === "text") {
1539
1549
  console.log("[dry-run] rig run restart");
1540
1550
  }
1541
1551
  return { ok: true, group: "run", command };
1542
1552
  }
1543
- const restarted = await runRestart(context.projectRoot, runtimeContext);
1553
+ const restarted = await runRestart(context.projectRoot, runtimeContext, targetRunId);
1544
1554
  if (context.outputMode === "text") {
1545
1555
  console.log(`Restarted run: ${restarted.runId}`);
1546
1556
  }
@@ -45,10 +45,298 @@ Usage: ${usage}`);
45
45
  }
46
46
 
47
47
  // packages/cli/src/commands/stats.ts
48
- import {
49
- listAuthorityRuns,
50
- projectRunFromJournal
51
- } from "@rig/runtime/control-plane/authority-files";
48
+ import { computeRigStats } from "@rig/runtime/control-plane/native/run-stats";
49
+
50
+ // packages/cli/src/commands/_connection-state.ts
51
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
52
+ import { homedir } from "os";
53
+ import { dirname, resolve } from "path";
54
+ function resolveGlobalConnectionsPath(env = process.env) {
55
+ const explicit = env.RIG_CONNECTIONS_FILE?.trim();
56
+ if (explicit)
57
+ return resolve(explicit);
58
+ const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
59
+ if (stateDir)
60
+ return resolve(stateDir, "connections.json");
61
+ return resolve(homedir(), ".rig", "connections.json");
62
+ }
63
+ function resolveRepoConnectionPath(projectRoot) {
64
+ return resolve(projectRoot, ".rig", "state", "connection.json");
65
+ }
66
+ function readJsonFile(path) {
67
+ if (!existsSync(path))
68
+ return null;
69
+ try {
70
+ return JSON.parse(readFileSync(path, "utf8"));
71
+ } catch (error) {
72
+ throw new CliError(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1, { hint: "Fix or delete that file, then re-select a server with `rig server use <alias|local>`." });
73
+ }
74
+ }
75
+ function writeJsonFile(path, value) {
76
+ mkdirSync(dirname(path), { recursive: true });
77
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
78
+ `, "utf8");
79
+ }
80
+ function normalizeConnection(value) {
81
+ if (!value || typeof value !== "object" || Array.isArray(value))
82
+ return null;
83
+ const record = value;
84
+ if (record.kind === "local")
85
+ return { kind: "local", mode: "auto" };
86
+ if (record.kind === "remote" && typeof record.baseUrl === "string" && record.baseUrl.trim()) {
87
+ const baseUrl = record.baseUrl.trim().replace(/\/+$/, "");
88
+ return { kind: "remote", baseUrl };
89
+ }
90
+ return null;
91
+ }
92
+ function readGlobalConnections(options = {}) {
93
+ const path = resolveGlobalConnectionsPath(options.env ?? process.env);
94
+ const payload = readJsonFile(path);
95
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
96
+ return { connections: {} };
97
+ }
98
+ const rawConnections = payload.connections;
99
+ const connections = {};
100
+ if (rawConnections && typeof rawConnections === "object" && !Array.isArray(rawConnections)) {
101
+ for (const [alias, raw] of Object.entries(rawConnections)) {
102
+ const connection = normalizeConnection(raw);
103
+ if (connection)
104
+ connections[alias] = connection;
105
+ }
106
+ }
107
+ return { connections };
108
+ }
109
+ function readRepoConnection(projectRoot) {
110
+ const payload = readJsonFile(resolveRepoConnectionPath(projectRoot));
111
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
112
+ return null;
113
+ const record = payload;
114
+ const selected = typeof record.selected === "string" ? record.selected.trim() : "";
115
+ if (!selected)
116
+ return null;
117
+ return {
118
+ selected,
119
+ project: typeof record.project === "string" ? record.project : undefined,
120
+ linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
121
+ serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
122
+ };
123
+ }
124
+ function writeRepoConnection(projectRoot, state) {
125
+ writeJsonFile(resolveRepoConnectionPath(projectRoot), state);
126
+ }
127
+ function resolveSelectedConnection(projectRoot, options = {}) {
128
+ const repo = readRepoConnection(projectRoot);
129
+ if (!repo)
130
+ return null;
131
+ if (repo.selected === "local")
132
+ return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
133
+ const global = readGlobalConnections(options);
134
+ const connection = global.connections[repo.selected];
135
+ if (!connection) {
136
+ throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
137
+ }
138
+ return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
139
+ }
140
+ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
141
+ const repo = readRepoConnection(projectRoot);
142
+ if (!repo)
143
+ return;
144
+ writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
145
+ }
146
+ function isRemoteConnectionSelected(projectRoot) {
147
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
148
+ }
149
+
150
+ // packages/cli/src/commands/_server-client.ts
151
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
152
+ import { resolve as resolve2 } from "path";
153
+ import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
154
+ var scopedGitHubBearerTokens = new Map;
155
+ function cleanToken(value) {
156
+ const trimmed = value?.trim();
157
+ return trimmed ? trimmed : null;
158
+ }
159
+ function readPrivateRemoteSessionToken(projectRoot) {
160
+ const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
161
+ if (!existsSync2(path))
162
+ return null;
163
+ try {
164
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
165
+ return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
166
+ } catch {
167
+ return null;
168
+ }
169
+ }
170
+ function readGitHubBearerTokenForRemote(projectRoot) {
171
+ const scopedKey = resolve2(projectRoot);
172
+ if (scopedGitHubBearerTokens.has(scopedKey))
173
+ return scopedGitHubBearerTokens.get(scopedKey) ?? null;
174
+ const privateSession = readPrivateRemoteSessionToken(projectRoot);
175
+ if (privateSession)
176
+ return privateSession;
177
+ return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
178
+ }
179
+ function readStoredGitHubAuthToken(projectRoot) {
180
+ const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
181
+ if (!existsSync2(path))
182
+ return null;
183
+ try {
184
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
185
+ return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
186
+ } catch {
187
+ return null;
188
+ }
189
+ }
190
+ function readLocalConnectionFallbackToken(projectRoot) {
191
+ return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
192
+ }
193
+ async function ensureServerForCli(projectRoot) {
194
+ try {
195
+ const selected = resolveSelectedConnection(projectRoot);
196
+ if (selected?.connection.kind === "remote") {
197
+ const authToken = readGitHubBearerTokenForRemote(projectRoot);
198
+ const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
199
+ return {
200
+ baseUrl: selected.connection.baseUrl,
201
+ authToken,
202
+ connectionKind: "remote",
203
+ serverProjectRoot
204
+ };
205
+ }
206
+ const connection = await ensureLocalRigServerConnection(projectRoot);
207
+ return {
208
+ baseUrl: connection.baseUrl,
209
+ authToken: connection.authToken ?? readLocalConnectionFallbackToken(projectRoot),
210
+ connectionKind: "local",
211
+ serverProjectRoot: resolve2(projectRoot)
212
+ };
213
+ } catch (error) {
214
+ if (error instanceof Error) {
215
+ throw new CliError(error.message, 1);
216
+ }
217
+ throw error;
218
+ }
219
+ }
220
+ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
221
+ const repo = readRepoConnection(projectRoot);
222
+ const slug = repo?.project?.trim();
223
+ if (!slug)
224
+ return null;
225
+ try {
226
+ const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
227
+ headers: mergeHeaders(undefined, authToken)
228
+ });
229
+ if (!response.ok)
230
+ return null;
231
+ const payload = await response.json();
232
+ const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
233
+ const checkouts = Array.isArray(project?.checkouts) ? project.checkouts : [];
234
+ const latestCheckout = [...checkouts].reverse().find((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.path === "string"));
235
+ const path = typeof latestCheckout?.path === "string" && latestCheckout.path.trim() ? latestCheckout.path.trim() : null;
236
+ if (path)
237
+ writeRepoServerProjectRoot(projectRoot, path);
238
+ return path;
239
+ } catch {
240
+ return null;
241
+ }
242
+ }
243
+ function mergeHeaders(headers, authToken) {
244
+ const merged = new Headers(headers);
245
+ if (authToken) {
246
+ merged.set("authorization", `Bearer ${authToken}`);
247
+ }
248
+ return merged;
249
+ }
250
+ function diagnosticMessage(payload) {
251
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
252
+ return null;
253
+ const record = payload;
254
+ const diagnostics = Array.isArray(record.diagnostics) ? record.diagnostics : [];
255
+ const messages = diagnostics.flatMap((entry) => {
256
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
257
+ return [];
258
+ const diagnostic = entry;
259
+ const kind = typeof diagnostic.kind === "string" ? diagnostic.kind : "task-source";
260
+ const message = typeof diagnostic.message === "string" ? diagnostic.message : null;
261
+ return message ? [`${kind}: ${message}`] : [];
262
+ });
263
+ return messages.length > 0 ? messages.join("; ") : null;
264
+ }
265
+ var serverReachabilityCache = new Map;
266
+ async function probeServerReachability(baseUrl, authToken) {
267
+ try {
268
+ const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
269
+ headers: mergeHeaders(undefined, authToken),
270
+ signal: AbortSignal.timeout(1500)
271
+ });
272
+ return response.ok;
273
+ } catch {
274
+ return false;
275
+ }
276
+ }
277
+ function cachedServerReachability(projectRoot, baseUrl, authToken) {
278
+ const key = resolve2(projectRoot);
279
+ const cached = serverReachabilityCache.get(key);
280
+ if (cached)
281
+ return cached;
282
+ const probe = probeServerReachability(baseUrl, authToken);
283
+ serverReachabilityCache.set(key, probe);
284
+ return probe;
285
+ }
286
+ function describeSelectedServer(projectRoot, server) {
287
+ try {
288
+ const selected = resolveSelectedConnection(projectRoot);
289
+ if (selected) {
290
+ return {
291
+ alias: selected.alias,
292
+ target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
293
+ };
294
+ }
295
+ } catch {}
296
+ return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
297
+ }
298
+ async function buildServerFailureContext(projectRoot, server) {
299
+ const { alias, target } = describeSelectedServer(projectRoot, server);
300
+ const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
301
+ const reachability = reachable ? "server is reachable" : "server is unreachable";
302
+ return {
303
+ contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
304
+ hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
305
+ };
306
+ }
307
+ async function requestServerJson(context, pathname, init = {}) {
308
+ const server = await ensureServerForCli(context.projectRoot);
309
+ const headers = mergeHeaders(init.headers, server.authToken);
310
+ if (server.serverProjectRoot)
311
+ headers.set("x-rig-project-root", server.serverProjectRoot);
312
+ let response;
313
+ try {
314
+ response = await fetch(`${server.baseUrl}${pathname}`, {
315
+ ...init,
316
+ headers
317
+ });
318
+ } catch (error) {
319
+ const failure = await buildServerFailureContext(context.projectRoot, server);
320
+ throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
321
+ ${failure.contextLine}`, 1, { hint: failure.hint });
322
+ }
323
+ const text = await response.text();
324
+ const payload = text.trim().length > 0 ? (() => {
325
+ try {
326
+ return JSON.parse(text);
327
+ } catch {
328
+ return null;
329
+ }
330
+ })() : null;
331
+ if (!response.ok) {
332
+ const diagnostics = diagnosticMessage(payload);
333
+ const detail = diagnostics ?? (text || response.statusText);
334
+ const failure = await buildServerFailureContext(context.projectRoot, server);
335
+ throw new CliError(`Rig server request failed (${response.status}): ${detail}
336
+ ${failure.contextLine}`, 1, { hint: failure.hint });
337
+ }
338
+ return payload;
339
+ }
52
340
 
53
341
  // packages/cli/src/commands/_cli-format.ts
54
342
  import { log, note } from "@clack/prompts";
@@ -512,90 +800,6 @@ function parseSinceOption(value, now = new Date) {
512
800
  }
513
801
  return new Date(parsed);
514
802
  }
515
- function median(values) {
516
- if (values.length === 0)
517
- return null;
518
- const sorted = [...values].sort((left, right) => left - right);
519
- const middle = Math.floor(sorted.length / 2);
520
- const upper = sorted[middle];
521
- if (sorted.length % 2 === 1)
522
- return upper;
523
- return (sorted[middle - 1] + upper) / 2;
524
- }
525
- function rate(part, total) {
526
- if (total === 0)
527
- return null;
528
- return part / total;
529
- }
530
- function parseTimestamp(value) {
531
- if (!value)
532
- return null;
533
- const parsed = Date.parse(value);
534
- return Number.isFinite(parsed) ? parsed : null;
535
- }
536
- function computeRigStats(projectRoot, options = {}) {
537
- const since = options.since ?? null;
538
- const sinceMs = since ? since.getTime() : null;
539
- const runs = listAuthorityRuns(projectRoot).filter((run) => {
540
- if (sinceMs === null)
541
- return true;
542
- const createdAt = parseTimestamp(run.createdAt) ?? parseTimestamp(run.updatedAt);
543
- return createdAt !== null && createdAt >= sinceMs;
544
- });
545
- const statusCounts = {};
546
- const completionDurations = [];
547
- let steeringTotal = 0;
548
- let stallTotal = 0;
549
- let approvalsApproved = 0;
550
- let approvalsRejected = 0;
551
- let approvalsPending = 0;
552
- for (const run of runs) {
553
- const status = run.status ?? "unknown";
554
- statusCounts[status] = (statusCounts[status] ?? 0) + 1;
555
- if (status === "completed") {
556
- const createdAt = parseTimestamp(run.createdAt);
557
- const completedAt = parseTimestamp(run.completedAt);
558
- if (createdAt !== null && completedAt !== null && completedAt >= createdAt) {
559
- completionDurations.push(completedAt - createdAt);
560
- }
561
- }
562
- const projection = projectRunFromJournal(projectRoot, run.runId);
563
- if (!projection)
564
- continue;
565
- steeringTotal += projection.steeringCount;
566
- stallTotal += projection.stallCount;
567
- approvalsPending += projection.pendingApprovals.length;
568
- for (const resolved of projection.resolvedApprovals) {
569
- if (resolved.decision === "approve")
570
- approvalsApproved += 1;
571
- else
572
- approvalsRejected += 1;
573
- }
574
- }
575
- const totalRuns = runs.length;
576
- const completedRuns = statusCounts["completed"] ?? 0;
577
- const failedRuns = statusCounts["failed"] ?? 0;
578
- const needsAttentionRuns = statusCounts["needs-attention"] ?? 0;
579
- return {
580
- since: since ? since.toISOString() : null,
581
- totalRuns,
582
- statusCounts,
583
- completedRuns,
584
- failedRuns,
585
- needsAttentionRuns,
586
- completionRate: rate(completedRuns, totalRuns),
587
- failureRate: rate(failedRuns, totalRuns),
588
- needsAttentionRate: rate(needsAttentionRuns, totalRuns),
589
- medianCompletionMs: median(completionDurations),
590
- steeringTotal,
591
- steeringPerRun: totalRuns === 0 ? null : steeringTotal / totalRuns,
592
- stallTotal,
593
- approvalsRequested: approvalsApproved + approvalsRejected + approvalsPending,
594
- approvalsApproved,
595
- approvalsRejected,
596
- approvalsPending
597
- };
598
- }
599
803
  function formatPercent(value) {
600
804
  if (value === null)
601
805
  return "\u2014";
@@ -653,7 +857,7 @@ async function executeStats(context, args) {
653
857
  const sinceResult = takeOption(pending, "--since");
654
858
  requireNoExtraArgs(sinceResult.rest, "rig stats [show] [--since <7d|30d|ISO date>]");
655
859
  const since = parseSinceOption(sinceResult.value);
656
- const stats = computeRigStats(context.projectRoot, { since });
860
+ const stats = isRemoteConnectionSelected(context.projectRoot) ? await requestServerJson(context, `/api/stats${since ? `?since=${encodeURIComponent(since.toISOString())}` : ""}`) : computeRigStats(context.projectRoot, { since });
657
861
  if (context.outputMode === "text") {
658
862
  printFormattedOutput(formatStatsReport(stats));
659
863
  }
@@ -2730,6 +2730,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
2730
2730
  return;
2731
2731
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
2732
2732
  }
2733
+ function isRemoteConnectionSelected(projectRoot) {
2734
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
2735
+ }
2733
2736
 
2734
2737
  // packages/cli/src/commands/_server-client.ts
2735
2738
  init_runner();
@@ -7656,9 +7659,6 @@ function normalizeRemoteRunDetails(payload) {
7656
7659
  };
7657
7660
  }
7658
7661
  var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
7659
- function isRemoteConnectionSelected(projectRoot) {
7660
- return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
7661
- }
7662
7662
  async function listRunsForSelectedConnection(context, options = {}) {
7663
7663
  if (isRemoteConnectionSelected(context.projectRoot)) {
7664
7664
  return { runs: await listRunsViaServer(context, options), source: "server" };
@@ -8008,28 +8008,38 @@ async function executeRun(context, args) {
8008
8008
  };
8009
8009
  }
8010
8010
  case "resume": {
8011
- requireNoExtraArgs(rest, "rig run resume");
8011
+ let pending = rest;
8012
+ const runOpt = takeOption(pending, "--run");
8013
+ pending = runOpt.rest;
8014
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8015
+ requireNoExtraArgs(pending, "rig run resume [<run-id>] [--run <id>]");
8016
+ const targetRunId = runOpt.value ?? positional ?? null;
8012
8017
  if (context.dryRun) {
8013
8018
  if (context.outputMode === "text") {
8014
8019
  console.log("[dry-run] rig run resume");
8015
8020
  }
8016
8021
  return { ok: true, group: "run", command };
8017
8022
  }
8018
- const resumed = await runResume(context.projectRoot, runtimeContext);
8023
+ const resumed = await runResume(context.projectRoot, runtimeContext, targetRunId);
8019
8024
  if (context.outputMode === "text") {
8020
8025
  console.log(`Resumed run: ${resumed.runId}`);
8021
8026
  }
8022
8027
  return { ok: true, group: "run", command, details: resumed };
8023
8028
  }
8024
8029
  case "restart": {
8025
- requireNoExtraArgs(rest, "rig run restart");
8030
+ let pending = rest;
8031
+ const runOpt = takeOption(pending, "--run");
8032
+ pending = runOpt.rest;
8033
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8034
+ requireNoExtraArgs(pending, "rig run restart [<run-id>] [--run <id>]");
8035
+ const targetRunId = runOpt.value ?? positional ?? null;
8026
8036
  if (context.dryRun) {
8027
8037
  if (context.outputMode === "text") {
8028
8038
  console.log("[dry-run] rig run restart");
8029
8039
  }
8030
8040
  return { ok: true, group: "run", command };
8031
8041
  }
8032
- const restarted = await runRestart(context.projectRoot, runtimeContext);
8042
+ const restarted = await runRestart(context.projectRoot, runtimeContext, targetRunId);
8033
8043
  if (context.outputMode === "text") {
8034
8044
  console.log(`Restarted run: ${restarted.runId}`);
8035
8045
  }
@@ -8324,10 +8334,7 @@ async function executeServer(context, args, options) {
8324
8334
  // packages/cli/src/commands/stats.ts
8325
8335
  init_runner();
8326
8336
  import pc5 from "picocolors";
8327
- import {
8328
- listAuthorityRuns as listAuthorityRuns3,
8329
- projectRunFromJournal
8330
- } from "@rig/runtime/control-plane/authority-files";
8337
+ import { computeRigStats } from "@rig/runtime/control-plane/native/run-stats";
8331
8338
 
8332
8339
  // packages/cli/src/commands/_help-catalog.ts
8333
8340
  import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
@@ -8816,90 +8823,6 @@ function parseSinceOption(value, now = new Date) {
8816
8823
  }
8817
8824
  return new Date(parsed);
8818
8825
  }
8819
- function median(values) {
8820
- if (values.length === 0)
8821
- return null;
8822
- const sorted = [...values].sort((left, right) => left - right);
8823
- const middle = Math.floor(sorted.length / 2);
8824
- const upper = sorted[middle];
8825
- if (sorted.length % 2 === 1)
8826
- return upper;
8827
- return (sorted[middle - 1] + upper) / 2;
8828
- }
8829
- function rate(part, total) {
8830
- if (total === 0)
8831
- return null;
8832
- return part / total;
8833
- }
8834
- function parseTimestamp(value) {
8835
- if (!value)
8836
- return null;
8837
- const parsed = Date.parse(value);
8838
- return Number.isFinite(parsed) ? parsed : null;
8839
- }
8840
- function computeRigStats(projectRoot, options = {}) {
8841
- const since = options.since ?? null;
8842
- const sinceMs = since ? since.getTime() : null;
8843
- const runs = listAuthorityRuns3(projectRoot).filter((run) => {
8844
- if (sinceMs === null)
8845
- return true;
8846
- const createdAt = parseTimestamp(run.createdAt) ?? parseTimestamp(run.updatedAt);
8847
- return createdAt !== null && createdAt >= sinceMs;
8848
- });
8849
- const statusCounts = {};
8850
- const completionDurations = [];
8851
- let steeringTotal = 0;
8852
- let stallTotal = 0;
8853
- let approvalsApproved = 0;
8854
- let approvalsRejected = 0;
8855
- let approvalsPending = 0;
8856
- for (const run of runs) {
8857
- const status = run.status ?? "unknown";
8858
- statusCounts[status] = (statusCounts[status] ?? 0) + 1;
8859
- if (status === "completed") {
8860
- const createdAt = parseTimestamp(run.createdAt);
8861
- const completedAt = parseTimestamp(run.completedAt);
8862
- if (createdAt !== null && completedAt !== null && completedAt >= createdAt) {
8863
- completionDurations.push(completedAt - createdAt);
8864
- }
8865
- }
8866
- const projection = projectRunFromJournal(projectRoot, run.runId);
8867
- if (!projection)
8868
- continue;
8869
- steeringTotal += projection.steeringCount;
8870
- stallTotal += projection.stallCount;
8871
- approvalsPending += projection.pendingApprovals.length;
8872
- for (const resolved of projection.resolvedApprovals) {
8873
- if (resolved.decision === "approve")
8874
- approvalsApproved += 1;
8875
- else
8876
- approvalsRejected += 1;
8877
- }
8878
- }
8879
- const totalRuns = runs.length;
8880
- const completedRuns = statusCounts["completed"] ?? 0;
8881
- const failedRuns = statusCounts["failed"] ?? 0;
8882
- const needsAttentionRuns = statusCounts["needs-attention"] ?? 0;
8883
- return {
8884
- since: since ? since.toISOString() : null,
8885
- totalRuns,
8886
- statusCounts,
8887
- completedRuns,
8888
- failedRuns,
8889
- needsAttentionRuns,
8890
- completionRate: rate(completedRuns, totalRuns),
8891
- failureRate: rate(failedRuns, totalRuns),
8892
- needsAttentionRate: rate(needsAttentionRuns, totalRuns),
8893
- medianCompletionMs: median(completionDurations),
8894
- steeringTotal,
8895
- steeringPerRun: totalRuns === 0 ? null : steeringTotal / totalRuns,
8896
- stallTotal,
8897
- approvalsRequested: approvalsApproved + approvalsRejected + approvalsPending,
8898
- approvalsApproved,
8899
- approvalsRejected,
8900
- approvalsPending
8901
- };
8902
- }
8903
8826
  function formatPercent(value) {
8904
8827
  if (value === null)
8905
8828
  return "\u2014";
@@ -8957,7 +8880,7 @@ async function executeStats(context, args) {
8957
8880
  const sinceResult = takeOption(pending, "--since");
8958
8881
  requireNoExtraArgs(sinceResult.rest, "rig stats [show] [--since <7d|30d|ISO date>]");
8959
8882
  const since = parseSinceOption(sinceResult.value);
8960
- const stats = computeRigStats(context.projectRoot, { since });
8883
+ const stats = isRemoteConnectionSelected(context.projectRoot) ? await requestServerJson(context, `/api/stats${since ? `?since=${encodeURIComponent(since.toISOString())}` : ""}`) : computeRigStats(context.projectRoot, { since });
8961
8884
  if (context.outputMode === "text") {
8962
8885
  printFormattedOutput(formatStatsReport(stats));
8963
8886
  }
package/dist/src/index.js CHANGED
@@ -2919,6 +2919,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
2919
2919
  return;
2920
2920
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
2921
2921
  }
2922
+ function isRemoteConnectionSelected(projectRoot) {
2923
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
2924
+ }
2922
2925
 
2923
2926
  // packages/cli/src/commands/_server-client.ts
2924
2927
  init_runner();
@@ -7845,9 +7848,6 @@ function normalizeRemoteRunDetails(payload) {
7845
7848
  };
7846
7849
  }
7847
7850
  var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
7848
- function isRemoteConnectionSelected(projectRoot) {
7849
- return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
7850
- }
7851
7851
  async function listRunsForSelectedConnection(context, options = {}) {
7852
7852
  if (isRemoteConnectionSelected(context.projectRoot)) {
7853
7853
  return { runs: await listRunsViaServer(context, options), source: "server" };
@@ -8197,28 +8197,38 @@ async function executeRun(context, args) {
8197
8197
  };
8198
8198
  }
8199
8199
  case "resume": {
8200
- requireNoExtraArgs(rest, "rig run resume");
8200
+ let pending = rest;
8201
+ const runOpt = takeOption(pending, "--run");
8202
+ pending = runOpt.rest;
8203
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8204
+ requireNoExtraArgs(pending, "rig run resume [<run-id>] [--run <id>]");
8205
+ const targetRunId = runOpt.value ?? positional ?? null;
8201
8206
  if (context.dryRun) {
8202
8207
  if (context.outputMode === "text") {
8203
8208
  console.log("[dry-run] rig run resume");
8204
8209
  }
8205
8210
  return { ok: true, group: "run", command };
8206
8211
  }
8207
- const resumed = await runResume(context.projectRoot, runtimeContext);
8212
+ const resumed = await runResume(context.projectRoot, runtimeContext, targetRunId);
8208
8213
  if (context.outputMode === "text") {
8209
8214
  console.log(`Resumed run: ${resumed.runId}`);
8210
8215
  }
8211
8216
  return { ok: true, group: "run", command, details: resumed };
8212
8217
  }
8213
8218
  case "restart": {
8214
- requireNoExtraArgs(rest, "rig run restart");
8219
+ let pending = rest;
8220
+ const runOpt = takeOption(pending, "--run");
8221
+ pending = runOpt.rest;
8222
+ const positional = pending[0] && !pending[0].startsWith("-") ? pending.shift() : undefined;
8223
+ requireNoExtraArgs(pending, "rig run restart [<run-id>] [--run <id>]");
8224
+ const targetRunId = runOpt.value ?? positional ?? null;
8215
8225
  if (context.dryRun) {
8216
8226
  if (context.outputMode === "text") {
8217
8227
  console.log("[dry-run] rig run restart");
8218
8228
  }
8219
8229
  return { ok: true, group: "run", command };
8220
8230
  }
8221
- const restarted = await runRestart(context.projectRoot, runtimeContext);
8231
+ const restarted = await runRestart(context.projectRoot, runtimeContext, targetRunId);
8222
8232
  if (context.outputMode === "text") {
8223
8233
  console.log(`Restarted run: ${restarted.runId}`);
8224
8234
  }
@@ -8513,10 +8523,7 @@ async function executeServer(context, args, options) {
8513
8523
  // packages/cli/src/commands/stats.ts
8514
8524
  init_runner();
8515
8525
  import pc5 from "picocolors";
8516
- import {
8517
- listAuthorityRuns as listAuthorityRuns3,
8518
- projectRunFromJournal
8519
- } from "@rig/runtime/control-plane/authority-files";
8526
+ import { computeRigStats } from "@rig/runtime/control-plane/native/run-stats";
8520
8527
 
8521
8528
  // packages/cli/src/commands/_help-catalog.ts
8522
8529
  import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
@@ -9005,90 +9012,6 @@ function parseSinceOption(value, now = new Date) {
9005
9012
  }
9006
9013
  return new Date(parsed);
9007
9014
  }
9008
- function median(values) {
9009
- if (values.length === 0)
9010
- return null;
9011
- const sorted = [...values].sort((left, right) => left - right);
9012
- const middle = Math.floor(sorted.length / 2);
9013
- const upper = sorted[middle];
9014
- if (sorted.length % 2 === 1)
9015
- return upper;
9016
- return (sorted[middle - 1] + upper) / 2;
9017
- }
9018
- function rate(part, total) {
9019
- if (total === 0)
9020
- return null;
9021
- return part / total;
9022
- }
9023
- function parseTimestamp(value) {
9024
- if (!value)
9025
- return null;
9026
- const parsed = Date.parse(value);
9027
- return Number.isFinite(parsed) ? parsed : null;
9028
- }
9029
- function computeRigStats(projectRoot, options = {}) {
9030
- const since = options.since ?? null;
9031
- const sinceMs = since ? since.getTime() : null;
9032
- const runs = listAuthorityRuns3(projectRoot).filter((run) => {
9033
- if (sinceMs === null)
9034
- return true;
9035
- const createdAt = parseTimestamp(run.createdAt) ?? parseTimestamp(run.updatedAt);
9036
- return createdAt !== null && createdAt >= sinceMs;
9037
- });
9038
- const statusCounts = {};
9039
- const completionDurations = [];
9040
- let steeringTotal = 0;
9041
- let stallTotal = 0;
9042
- let approvalsApproved = 0;
9043
- let approvalsRejected = 0;
9044
- let approvalsPending = 0;
9045
- for (const run of runs) {
9046
- const status = run.status ?? "unknown";
9047
- statusCounts[status] = (statusCounts[status] ?? 0) + 1;
9048
- if (status === "completed") {
9049
- const createdAt = parseTimestamp(run.createdAt);
9050
- const completedAt = parseTimestamp(run.completedAt);
9051
- if (createdAt !== null && completedAt !== null && completedAt >= createdAt) {
9052
- completionDurations.push(completedAt - createdAt);
9053
- }
9054
- }
9055
- const projection = projectRunFromJournal(projectRoot, run.runId);
9056
- if (!projection)
9057
- continue;
9058
- steeringTotal += projection.steeringCount;
9059
- stallTotal += projection.stallCount;
9060
- approvalsPending += projection.pendingApprovals.length;
9061
- for (const resolved of projection.resolvedApprovals) {
9062
- if (resolved.decision === "approve")
9063
- approvalsApproved += 1;
9064
- else
9065
- approvalsRejected += 1;
9066
- }
9067
- }
9068
- const totalRuns = runs.length;
9069
- const completedRuns = statusCounts["completed"] ?? 0;
9070
- const failedRuns = statusCounts["failed"] ?? 0;
9071
- const needsAttentionRuns = statusCounts["needs-attention"] ?? 0;
9072
- return {
9073
- since: since ? since.toISOString() : null,
9074
- totalRuns,
9075
- statusCounts,
9076
- completedRuns,
9077
- failedRuns,
9078
- needsAttentionRuns,
9079
- completionRate: rate(completedRuns, totalRuns),
9080
- failureRate: rate(failedRuns, totalRuns),
9081
- needsAttentionRate: rate(needsAttentionRuns, totalRuns),
9082
- medianCompletionMs: median(completionDurations),
9083
- steeringTotal,
9084
- steeringPerRun: totalRuns === 0 ? null : steeringTotal / totalRuns,
9085
- stallTotal,
9086
- approvalsRequested: approvalsApproved + approvalsRejected + approvalsPending,
9087
- approvalsApproved,
9088
- approvalsRejected,
9089
- approvalsPending
9090
- };
9091
- }
9092
9015
  function formatPercent(value) {
9093
9016
  if (value === null)
9094
9017
  return "\u2014";
@@ -9146,7 +9069,7 @@ async function executeStats(context, args) {
9146
9069
  const sinceResult = takeOption(pending, "--since");
9147
9070
  requireNoExtraArgs(sinceResult.rest, "rig stats [show] [--since <7d|30d|ISO date>]");
9148
9071
  const since = parseSinceOption(sinceResult.value);
9149
- const stats = computeRigStats(context.projectRoot, { since });
9072
+ const stats = isRemoteConnectionSelected(context.projectRoot) ? await requestServerJson(context, `/api/stats${since ? `?since=${encodeURIComponent(since.toISOString())}` : ""}`) : computeRigStats(context.projectRoot, { since });
9150
9073
  if (context.outputMode === "text") {
9151
9074
  printFormattedOutput(formatStatsReport(stats));
9152
9075
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-rig/cli",
3
- "version": "0.0.6-alpha.66",
3
+ "version": "0.0.6-alpha.67",
4
4
  "type": "module",
5
5
  "description": "Rig package",
6
6
  "license": "UNLICENSED",
@@ -24,13 +24,13 @@
24
24
  "dependencies": {
25
25
  "@clack/prompts": "^1.2.0",
26
26
  "@earendil-works/pi-coding-agent": "0.79.0",
27
- "@rig/client": "npm:@h-rig/client@0.0.6-alpha.66",
28
- "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.66",
29
- "@rig/core": "npm:@h-rig/core@0.0.6-alpha.66",
30
- "@rig/pi-rig": "npm:@h-rig/pi-rig@0.0.6-alpha.66",
31
- "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.66",
32
- "@rig/server": "npm:@h-rig/server@0.0.6-alpha.66",
33
- "@rig/standard-plugin": "npm:@h-rig/standard-plugin@0.0.6-alpha.66",
27
+ "@rig/client": "npm:@h-rig/client@0.0.6-alpha.67",
28
+ "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.67",
29
+ "@rig/core": "npm:@h-rig/core@0.0.6-alpha.67",
30
+ "@rig/pi-rig": "npm:@h-rig/pi-rig@0.0.6-alpha.67",
31
+ "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.67",
32
+ "@rig/server": "npm:@h-rig/server@0.0.6-alpha.67",
33
+ "@rig/standard-plugin": "npm:@h-rig/standard-plugin@0.0.6-alpha.67",
34
34
  "effect": "4.0.0-beta.78",
35
35
  "picocolors": "^1.1.1"
36
36
  }