@h-rig/cli 0.0.6-alpha.75 → 0.0.6-alpha.77

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.
@@ -2,6 +2,66 @@
2
2
  // packages/cli/src/commands/_cli-format.ts
3
3
  import { log, note } from "@clack/prompts";
4
4
  import pc from "picocolors";
5
+
6
+ // packages/cli/src/commands/_tui-theme.ts
7
+ var RIG_PALETTE = {
8
+ ink: "#f2f3f6",
9
+ ink2: "#aeb0ba",
10
+ ink3: "#6c6e79",
11
+ ink4: "#44464f",
12
+ accent: "#ccff4d",
13
+ accentDim: "#a9d63f",
14
+ cyan: "#56d8ff",
15
+ red: "#ff5d5d",
16
+ yellow: "#ffd24d"
17
+ };
18
+ function hexToRgb(hex) {
19
+ const value = hex.replace("#", "");
20
+ return [
21
+ Number.parseInt(value.slice(0, 2), 16),
22
+ Number.parseInt(value.slice(2, 4), 16),
23
+ Number.parseInt(value.slice(4, 6), 16)
24
+ ];
25
+ }
26
+ function fg(hex) {
27
+ const [r, g, b] = hexToRgb(hex);
28
+ return (text) => `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
29
+ }
30
+ var ink = fg(RIG_PALETTE.ink);
31
+ var ink2 = fg(RIG_PALETTE.ink2);
32
+ var ink3 = fg(RIG_PALETTE.ink3);
33
+ var ink4 = fg(RIG_PALETTE.ink4);
34
+ var accent = fg(RIG_PALETTE.accent);
35
+ var accentDim = fg(RIG_PALETTE.accentDim);
36
+ var cyan = fg(RIG_PALETTE.cyan);
37
+ var red = fg(RIG_PALETTE.red);
38
+ var yellow = fg(RIG_PALETTE.yellow);
39
+ var DRONE_ART = [
40
+ " .-=-. .-=-. ",
41
+ " ( !!! ) ( !!! ) ",
42
+ " '-=-'._ _.'-=-' ",
43
+ " '._ _.' ",
44
+ " '=$$$$$$$=.' ",
45
+ " =$$$$$$$$$$$= ",
46
+ " $$$@@@@@@@@@@$$$ ",
47
+ " $$$@@ @@$$$ ",
48
+ " $$@ ? @$$$ ",
49
+ " $$$@ '-' @$$$ ",
50
+ " $$$@@ @@$$$ ",
51
+ " $$$@@@@@@@@@@$$$ ",
52
+ " =$$$$$$$$$$$= ",
53
+ " '=$$$$$$$=.' ",
54
+ " _.' '._ ",
55
+ " .-=-.' '.-=-. ",
56
+ " ( !!! ) ( !!! ) ",
57
+ " '-=-' '-=-' "
58
+ ];
59
+ var DRONE_WIDTH = DRONE_ART[0].length;
60
+ var DRONE_HEIGHT = DRONE_ART.length;
61
+
62
+ // packages/cli/src/commands/_cli-format.ts
63
+ var themeDim = (value) => ink3(value);
64
+ var themeFaint = (value) => ink4(value);
5
65
  function stringField(record, key, fallback = "") {
6
66
  const value = record[key];
7
67
  return typeof value === "string" && value.trim() ? value.trim() : fallback;
@@ -30,15 +90,15 @@ function pad(value, width) {
30
90
  }
31
91
  function statusColor(status) {
32
92
  const normalized = status.toLowerCase();
33
- if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
34
- return pc.green;
93
+ if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved", "running"].includes(normalized))
94
+ return accent;
35
95
  if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
36
- return pc.red;
37
- if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
38
- return pc.cyan;
39
- if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
40
- return pc.yellow;
41
- return pc.dim;
96
+ return red;
97
+ if (["reviewing", "validating", "in_progress", "in-progress", "remote", "preparing", "closing-out"].includes(normalized))
98
+ return cyan;
99
+ if (["ready", "open", "queued", "created", "local", "pending"].includes(normalized))
100
+ return yellow;
101
+ return themeDim;
42
102
  }
43
103
  function compactDate(value) {
44
104
  if (!value.trim())
@@ -97,17 +157,17 @@ function formatStatusPill(status) {
97
157
  return statusColor(label)(`\u25CF ${label}`);
98
158
  }
99
159
  function formatSection(title, subtitle) {
100
- return `${pc.bold(pc.cyan("\u25C6"))} ${pc.bold(title)}${subtitle ? pc.dim(` \u2014 ${subtitle}`) : ""}`;
160
+ return `${pc.bold(accent("\u25C6"))} ${pc.bold(title)}${subtitle ? themeDim(` \u2014 ${subtitle}`) : ""}`;
101
161
  }
102
162
  function formatSuccessCard(title, rows = []) {
103
- const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc.dim("\u2502")} ${pc.dim(key.padEnd(12))} ${value}`);
163
+ const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${themeFaint("\u2502")} ${themeDim(key.padEnd(12))} ${value}`);
104
164
  return [formatSection(title), ...body].join(`
105
165
  `);
106
166
  }
107
167
  function formatNextSteps(steps) {
108
168
  if (steps.length === 0)
109
169
  return [];
110
- return [pc.bold("Next"), ...steps.map((step) => `${pc.dim("\u203A")} ${step}`)];
170
+ return [pc.bold("Next"), ...steps.map((step) => `${accent("\u203A")} ${step}`)];
111
171
  }
112
172
  function formatTaskList(tasks, options = {}) {
113
173
  if (options.raw)
@@ -129,8 +189,8 @@ function formatTaskList(tasks, options = {}) {
129
189
  const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
130
190
  const header = `${pc.bold(pad("TASK", idWidth))} ${pc.bold(pad("STATUS", statusWidth))} ${pc.bold("TITLE")}`;
131
191
  const body = rows.map((row) => {
132
- const labels = row.labels.length > 0 ? pc.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
133
- const source = row.source ? pc.dim(` ${row.source}`) : "";
192
+ const labels = row.labels.length > 0 ? themeDim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
193
+ const source = row.source ? themeDim(` ${row.source}`) : "";
134
194
  return [
135
195
  pc.bold(pad(truncate(row.id, idWidth), idWidth)),
136
196
  statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
@@ -178,7 +238,7 @@ function formatRunList(runs, options = {}) {
178
238
  if (runs.length === 0) {
179
239
  return [
180
240
  formatSection("Runs", "none recorded"),
181
- options.source === "server" ? pc.dim("No runs recorded on the selected Rig server.") : pc.dim("No runs recorded in .rig/runs."),
241
+ options.source === "server" ? themeDim("No runs recorded on the selected Rig server.") : themeDim("No runs recorded in .rig/runs."),
182
242
  "",
183
243
  ...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
184
244
  ].join(`
@@ -198,7 +258,7 @@ function formatRunList(runs, options = {}) {
198
258
  const body = rows.map((row) => [
199
259
  pc.bold(pad(truncate(row.runId, idWidth), idWidth)),
200
260
  statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
201
- `${row.title}${row.runtime ? pc.dim(` ${row.runtime}`) : ""}`
261
+ `${row.title}${row.runtime ? themeDim(` ${row.runtime}`) : ""}`
202
262
  ].join(" "));
203
263
  return [formatSection("Runs", options.source === "server" ? "selected server" : "local state"), header, ...body, "", ...formatNextSteps(["Follow live: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"])].join(`
204
264
  `);
@@ -272,7 +332,7 @@ function formatRunStatus(summary, options = {}) {
272
332
  const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
273
333
  lines.push("", pc.bold(`Active runs (${activeRuns.length})`));
274
334
  if (activeRuns.length === 0) {
275
- lines.push(pc.dim("No active runs."));
335
+ lines.push(themeDim("No active runs."));
276
336
  } else {
277
337
  for (const run of activeRuns) {
278
338
  lines.push(formatRunSummaryLine(run));
@@ -280,7 +340,7 @@ function formatRunStatus(summary, options = {}) {
280
340
  }
281
341
  lines.push("", pc.bold(`Recent runs (${recentRuns.length})`));
282
342
  if (recentRuns.length === 0) {
283
- lines.push(pc.dim("No recent terminal runs."));
343
+ lines.push(themeDim("No recent terminal runs."));
284
344
  } else {
285
345
  for (const run of recentRuns.slice(0, 10)) {
286
346
  lines.push(formatRunSummaryLine(run));
@@ -298,14 +358,14 @@ function formatRunSummaryLine(run) {
298
358
  const title = runTitleOf(record);
299
359
  const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
300
360
  const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
301
- return `${pc.dim("\u2502")} ${pc.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc.dim(` ${runtime}`) : ""}`;
361
+ return `${themeFaint("\u2502")} ${pc.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? themeDim(` ${runtime}`) : ""}`;
302
362
  }
303
363
  function formatInboxList(kind, entries) {
304
364
  const title = kind === "approvals" ? "Approval inbox" : "Input inbox";
305
365
  if (entries.length === 0) {
306
366
  return [
307
367
  formatSection(title, "empty"),
308
- pc.dim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
368
+ themeDim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
309
369
  "",
310
370
  ...formatNextSteps(["Check runs: `rig run status`", "Start work: `rig task run --next`"])
311
371
  ].join(`
@@ -319,8 +379,8 @@ function formatInboxList(kind, entries) {
319
379
  const requestId = requestIdOf(record);
320
380
  const status = firstString(record, ["status", "state"], "pending");
321
381
  const prompt = firstString(record, ["prompt", "message", "reason", "title", "summary"], kind === "approvals" ? "Approval requested" : "Input requested");
322
- lines.push(`${pc.dim("\u2502")} ${pc.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
323
- lines.push(`${pc.dim("\u2502")} ${pc.dim("run ")} ${runId || "(unknown-run)"}${taskId ? pc.dim(` task ${taskId}`) : ""}`);
382
+ lines.push(`${themeFaint("\u2502")} ${pc.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
383
+ lines.push(`${themeFaint("\u2502")} ${themeDim("run ")} ${runId || "(unknown-run)"}${taskId ? themeDim(` task ${taskId}`) : ""}`);
324
384
  }
325
385
  lines.push("", ...formatNextSteps(kind === "approvals" ? ["Resolve: `rig inbox approve --run <run-id> --request <request-id> --decision approve|reject`", "Rejoin: `rig run attach <run-id> --follow`"] : ["Respond: `rig inbox respond --run <run-id> --request <request-id> --answer key=value`", "Rejoin: `rig run attach <run-id> --follow`"]));
326
386
  return lines.join(`
@@ -342,9 +402,9 @@ function formatConnectionStatus(selected, connections) {
342
402
  const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
343
403
  return [
344
404
  formatSection("Rig server", "selected for this repo"),
345
- `${pc.dim("\u2502")} ${pc.dim("selected ")} ${pc.bold(selected)}`,
346
- `${pc.dim("\u2502")} ${pc.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
347
- `${pc.dim("\u2502")} ${pc.dim("target ")} ${target ?? "not configured"}`,
405
+ `${themeFaint("\u2502")} ${themeDim("selected ")} ${pc.bold(selected)}`,
406
+ `${themeFaint("\u2502")} ${themeDim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
407
+ `${themeFaint("\u2502")} ${themeDim("target ")} ${target ?? "not configured"}`,
348
408
  "",
349
409
  ...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
350
410
  ].join(`