@runloop/rl-cli 1.8.0 → 1.10.0

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.
Files changed (66) hide show
  1. package/README.md +21 -7
  2. package/dist/cli.js +0 -0
  3. package/dist/commands/blueprint/delete.js +21 -0
  4. package/dist/commands/blueprint/list.js +226 -174
  5. package/dist/commands/blueprint/prune.js +13 -28
  6. package/dist/commands/devbox/create.js +41 -0
  7. package/dist/commands/devbox/list.js +142 -110
  8. package/dist/commands/devbox/rsync.js +69 -41
  9. package/dist/commands/devbox/scp.js +180 -39
  10. package/dist/commands/devbox/tunnel.js +4 -19
  11. package/dist/commands/gateway-config/create.js +53 -0
  12. package/dist/commands/gateway-config/delete.js +21 -0
  13. package/dist/commands/gateway-config/get.js +18 -0
  14. package/dist/commands/gateway-config/list.js +493 -0
  15. package/dist/commands/gateway-config/update.js +70 -0
  16. package/dist/commands/snapshot/list.js +11 -2
  17. package/dist/commands/snapshot/prune.js +265 -0
  18. package/dist/components/BenchmarkMenu.js +23 -3
  19. package/dist/components/DetailedInfoView.js +20 -0
  20. package/dist/components/DevboxActionsMenu.js +26 -62
  21. package/dist/components/DevboxCreatePage.js +763 -15
  22. package/dist/components/DevboxDetailPage.js +73 -24
  23. package/dist/components/GatewayConfigCreatePage.js +272 -0
  24. package/dist/components/LogsViewer.js +6 -40
  25. package/dist/components/ResourceDetailPage.js +143 -160
  26. package/dist/components/ResourceListView.js +3 -33
  27. package/dist/components/ResourcePicker.js +234 -0
  28. package/dist/components/SecretCreatePage.js +71 -27
  29. package/dist/components/SettingsMenu.js +12 -2
  30. package/dist/components/StateHistory.js +1 -20
  31. package/dist/components/StatusBadge.js +9 -2
  32. package/dist/components/StreamingLogsViewer.js +8 -42
  33. package/dist/components/form/FormTextInput.js +4 -2
  34. package/dist/components/resourceDetailTypes.js +18 -0
  35. package/dist/hooks/useInputHandler.js +103 -0
  36. package/dist/router/Router.js +79 -2
  37. package/dist/screens/BenchmarkDetailScreen.js +163 -0
  38. package/dist/screens/BenchmarkJobCreateScreen.js +524 -0
  39. package/dist/screens/BenchmarkJobDetailScreen.js +614 -0
  40. package/dist/screens/BenchmarkJobListScreen.js +479 -0
  41. package/dist/screens/BenchmarkListScreen.js +266 -0
  42. package/dist/screens/BenchmarkMenuScreen.js +6 -0
  43. package/dist/screens/BenchmarkRunDetailScreen.js +258 -22
  44. package/dist/screens/BenchmarkRunListScreen.js +21 -1
  45. package/dist/screens/BlueprintDetailScreen.js +5 -1
  46. package/dist/screens/DevboxCreateScreen.js +2 -2
  47. package/dist/screens/GatewayConfigDetailScreen.js +236 -0
  48. package/dist/screens/GatewayConfigListScreen.js +7 -0
  49. package/dist/screens/ScenarioRunDetailScreen.js +6 -0
  50. package/dist/screens/SecretDetailScreen.js +26 -2
  51. package/dist/screens/SettingsMenuScreen.js +3 -0
  52. package/dist/screens/SnapshotDetailScreen.js +6 -0
  53. package/dist/services/agentService.js +42 -0
  54. package/dist/services/benchmarkJobService.js +122 -0
  55. package/dist/services/benchmarkService.js +47 -0
  56. package/dist/services/gatewayConfigService.js +153 -0
  57. package/dist/services/scenarioService.js +34 -0
  58. package/dist/store/benchmarkJobStore.js +66 -0
  59. package/dist/store/benchmarkStore.js +63 -0
  60. package/dist/store/gatewayConfigStore.js +83 -0
  61. package/dist/utils/browser.js +22 -0
  62. package/dist/utils/clipboard.js +41 -0
  63. package/dist/utils/commands.js +105 -9
  64. package/dist/utils/gatewayConfigValidation.js +58 -0
  65. package/dist/utils/time.js +121 -0
  66. package/package.json +43 -43
@@ -0,0 +1,163 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * BenchmarkDetailScreen - Detail page for benchmark definitions
4
+ * Uses the generic ResourceDetailPage component
5
+ */
6
+ import React from "react";
7
+ import { Text } from "ink";
8
+ import figures from "figures";
9
+ import { useNavigation } from "../store/navigationStore.js";
10
+ import { useBenchmarkStore } from "../store/benchmarkStore.js";
11
+ import { ResourceDetailPage, formatTimestamp, } from "../components/ResourceDetailPage.js";
12
+ import { getBenchmark } from "../services/benchmarkService.js";
13
+ import { SpinnerComponent } from "../components/Spinner.js";
14
+ import { ErrorMessage } from "../components/ErrorMessage.js";
15
+ import { Breadcrumb } from "../components/Breadcrumb.js";
16
+ import { colors } from "../utils/theme.js";
17
+ export function BenchmarkDetailScreen({ benchmarkId, }) {
18
+ const { goBack, navigate } = useNavigation();
19
+ const benchmarks = useBenchmarkStore((state) => state.benchmarks);
20
+ const [loading, setLoading] = React.useState(false);
21
+ const [error, setError] = React.useState(null);
22
+ const [fetchedBenchmark, setFetchedBenchmark] = React.useState(null);
23
+ // Find benchmark in store first
24
+ const benchmarkFromStore = benchmarks.find((b) => b.id === benchmarkId);
25
+ // Polling function
26
+ const pollBenchmark = React.useCallback(async () => {
27
+ if (!benchmarkId)
28
+ return null;
29
+ return getBenchmark(benchmarkId);
30
+ }, [benchmarkId]);
31
+ // Fetch benchmark from API if not in store
32
+ React.useEffect(() => {
33
+ if (benchmarkId && !loading && !fetchedBenchmark && !benchmarkFromStore) {
34
+ setLoading(true);
35
+ setError(null);
36
+ getBenchmark(benchmarkId)
37
+ .then((benchmark) => {
38
+ setFetchedBenchmark(benchmark);
39
+ setLoading(false);
40
+ })
41
+ .catch((err) => {
42
+ setError(err);
43
+ setLoading(false);
44
+ });
45
+ }
46
+ }, [benchmarkId, loading, fetchedBenchmark, benchmarkFromStore]);
47
+ // Use fetched benchmark for full details, fall back to store for basic display
48
+ const benchmark = fetchedBenchmark || benchmarkFromStore;
49
+ // Show loading state
50
+ if (!benchmark && benchmarkId && !error) {
51
+ return (_jsxs(_Fragment, { children: [_jsx(Breadcrumb, { items: [
52
+ { label: "Home" },
53
+ { label: "Benchmarks" },
54
+ { label: "Benchmark Definitions" },
55
+ { label: "Loading...", active: true },
56
+ ] }), _jsx(SpinnerComponent, { message: "Loading benchmark details..." })] }));
57
+ }
58
+ // Show error state
59
+ if (error && !benchmark) {
60
+ return (_jsxs(_Fragment, { children: [_jsx(Breadcrumb, { items: [
61
+ { label: "Home" },
62
+ { label: "Benchmarks" },
63
+ { label: "Benchmark Definitions" },
64
+ { label: "Error", active: true },
65
+ ] }), _jsx(ErrorMessage, { message: "Failed to load benchmark details", error: error })] }));
66
+ }
67
+ // Show not found error
68
+ if (!benchmark) {
69
+ return (_jsxs(_Fragment, { children: [_jsx(Breadcrumb, { items: [
70
+ { label: "Home" },
71
+ { label: "Benchmarks" },
72
+ { label: "Benchmark Definitions" },
73
+ { label: "Not Found", active: true },
74
+ ] }), _jsx(ErrorMessage, { message: `Benchmark ${benchmarkId || "unknown"} not found`, error: new Error("Benchmark not found") })] }));
75
+ }
76
+ // Build detail sections
77
+ const detailSections = [];
78
+ // Basic details section
79
+ const basicFields = [];
80
+ if (benchmark.created_at) {
81
+ basicFields.push({
82
+ label: "Created",
83
+ value: formatTimestamp(benchmark.created_at),
84
+ });
85
+ }
86
+ if (benchmark.description) {
87
+ basicFields.push({
88
+ label: "Description",
89
+ value: benchmark.description,
90
+ });
91
+ }
92
+ if (basicFields.length > 0) {
93
+ detailSections.push({
94
+ title: "Details",
95
+ icon: figures.squareSmallFilled,
96
+ color: colors.warning,
97
+ fields: basicFields,
98
+ });
99
+ }
100
+ // Metadata section
101
+ if (benchmark.metadata &&
102
+ Object.keys(benchmark.metadata).length > 0) {
103
+ const metadataFields = Object.entries(benchmark.metadata).map(([key, value]) => ({
104
+ label: key,
105
+ value: value,
106
+ }));
107
+ detailSections.push({
108
+ title: "Metadata",
109
+ icon: figures.identical,
110
+ color: colors.secondary,
111
+ fields: metadataFields,
112
+ });
113
+ }
114
+ // Operations available for benchmarks
115
+ const operations = [
116
+ {
117
+ key: "create-job",
118
+ label: "Create Benchmark Job",
119
+ color: colors.success,
120
+ icon: figures.play,
121
+ shortcut: "c",
122
+ },
123
+ ];
124
+ // Handle operation selection
125
+ const handleOperation = async (operation, resource) => {
126
+ switch (operation) {
127
+ case "create-job":
128
+ navigate("benchmark-job-create", { initialBenchmarkIds: resource.id });
129
+ break;
130
+ }
131
+ };
132
+ // Build detailed info lines for full details view
133
+ const buildDetailLines = (b) => {
134
+ const lines = [];
135
+ // Core Information
136
+ lines.push(_jsx(Text, { color: colors.warning, bold: true, children: "Benchmark Details" }, "core-title"));
137
+ lines.push(_jsxs(Text, { color: colors.idColor, children: [" ", "ID: ", b.id] }, "core-id"));
138
+ lines.push(_jsxs(Text, { dimColor: true, children: [" ", "Name: ", b.name || "(none)"] }, "core-name"));
139
+ if (b.description) {
140
+ lines.push(_jsxs(Text, { dimColor: true, children: [" ", "Description: ", b.description] }, "core-desc"));
141
+ }
142
+ if (b.created_at) {
143
+ lines.push(_jsxs(Text, { dimColor: true, children: [" ", "Created: ", new Date(b.created_at).toLocaleString()] }, "core-created"));
144
+ }
145
+ lines.push(_jsx(Text, { children: " " }, "core-space"));
146
+ // Metadata
147
+ if (b.metadata && Object.keys(b.metadata).length > 0) {
148
+ lines.push(_jsx(Text, { color: colors.warning, bold: true, children: "Metadata" }, "meta-title"));
149
+ Object.entries(b.metadata).forEach(([key, value], idx) => {
150
+ lines.push(_jsxs(Text, { dimColor: true, children: [" ", key, ": ", value] }, `meta-${idx}`));
151
+ });
152
+ lines.push(_jsx(Text, { children: " " }, "meta-space"));
153
+ }
154
+ // Raw JSON
155
+ lines.push(_jsx(Text, { color: colors.warning, bold: true, children: "Raw JSON" }, "json-title"));
156
+ const jsonLines = JSON.stringify(b, null, 2).split("\n");
157
+ jsonLines.forEach((line, idx) => {
158
+ lines.push(_jsxs(Text, { dimColor: true, children: [" ", line] }, `json-${idx}`));
159
+ });
160
+ return lines;
161
+ };
162
+ return (_jsx(ResourceDetailPage, { resource: benchmark, resourceType: "Benchmark Definitions", getDisplayName: (b) => b.name || b.id, getId: (b) => b.id, getStatus: (b) => b.status, detailSections: detailSections, operations: operations, onOperation: handleOperation, onBack: goBack, buildDetailLines: buildDetailLines, breadcrumbPrefix: [{ label: "Home" }, { label: "Benchmarks" }] }));
163
+ }