@runloop/rl-cli 1.7.1 → 1.8.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.
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useNavigation } from "../store/navigationStore.js";
3
+ import { SettingsMenu } from "../components/SettingsMenu.js";
4
+ export function SettingsMenuScreen() {
5
+ const { navigate, goBack } = useNavigation();
6
+ const handleSelect = (key) => {
7
+ switch (key) {
8
+ case "network-policies":
9
+ navigate("network-policy-list");
10
+ break;
11
+ case "secrets":
12
+ navigate("secret-list");
13
+ break;
14
+ default:
15
+ // Fallback for any other screen names
16
+ navigate(key);
17
+ }
18
+ };
19
+ const handleBack = () => {
20
+ goBack();
21
+ };
22
+ return _jsx(SettingsMenu, { onSelect: handleSelect, onBack: handleBack });
23
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Benchmark Service - Handles all benchmark-related API calls
3
+ */
4
+ import { getClient } from "../utils/client.js";
5
+ /**
6
+ * List benchmark runs with pagination
7
+ */
8
+ export async function listBenchmarkRuns(options) {
9
+ const client = getClient();
10
+ const queryParams = {
11
+ limit: options.limit,
12
+ };
13
+ if (options.startingAfter) {
14
+ queryParams.starting_after = options.startingAfter;
15
+ }
16
+ const page = await client.benchmarkRuns.list(queryParams);
17
+ const benchmarkRuns = page.runs || [];
18
+ return {
19
+ benchmarkRuns,
20
+ totalCount: page.total_count || benchmarkRuns.length,
21
+ hasMore: page.has_more || false,
22
+ };
23
+ }
24
+ /**
25
+ * Get benchmark run by ID
26
+ */
27
+ export async function getBenchmarkRun(id) {
28
+ const client = getClient();
29
+ return client.benchmarkRuns.retrieve(id);
30
+ }
31
+ /**
32
+ * List scenario runs with pagination
33
+ */
34
+ export async function listScenarioRuns(options) {
35
+ const client = getClient();
36
+ // If we have a benchmark run ID, use the dedicated endpoint
37
+ if (options.benchmarkRunId) {
38
+ const queryParams = {
39
+ limit: options.limit,
40
+ };
41
+ if (options.startingAfter) {
42
+ queryParams.starting_after = options.startingAfter;
43
+ }
44
+ const page = await client.benchmarkRuns.listScenarioRuns(options.benchmarkRunId, queryParams);
45
+ const scenarioRuns = page.runs || [];
46
+ return {
47
+ scenarioRuns,
48
+ totalCount: page.total_count || scenarioRuns.length,
49
+ hasMore: page.has_more || false,
50
+ };
51
+ }
52
+ // Otherwise, list all scenario runs
53
+ const queryParams = {
54
+ limit: options.limit,
55
+ };
56
+ if (options.startingAfter) {
57
+ queryParams.starting_after = options.startingAfter;
58
+ }
59
+ const page = await client.scenarios.runs.list(queryParams);
60
+ const scenarioRuns = page.runs || [];
61
+ return {
62
+ scenarioRuns,
63
+ totalCount: page.total_count || scenarioRuns.length,
64
+ hasMore: page.has_more || false,
65
+ };
66
+ }
67
+ /**
68
+ * Get scenario run by ID
69
+ */
70
+ export async function getScenarioRun(id) {
71
+ const client = getClient();
72
+ return client.scenarios.runs.retrieve(id);
73
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Benchmark Store - Manages benchmark run and scenario run state
3
+ */
4
+ import { create } from "zustand";
5
+ const MAX_CACHE_SIZE = 10;
6
+ export const useBenchmarkStore = create((set, get) => ({
7
+ // Initial benchmark run state
8
+ benchmarkRuns: [],
9
+ benchmarkRunsLoading: false,
10
+ benchmarkRunsError: null,
11
+ benchmarkRunsTotalCount: 0,
12
+ benchmarkRunsHasMore: false,
13
+ benchmarkRunsCurrentPage: 0,
14
+ // Initial scenario run state
15
+ scenarioRuns: [],
16
+ scenarioRunsLoading: false,
17
+ scenarioRunsError: null,
18
+ scenarioRunsTotalCount: 0,
19
+ scenarioRunsHasMore: false,
20
+ scenarioRunsCurrentPage: 0,
21
+ // Filters
22
+ benchmarkRunIdFilter: undefined,
23
+ // Selection
24
+ selectedBenchmarkRunIndex: 0,
25
+ selectedScenarioRunIndex: 0,
26
+ // Caches
27
+ benchmarkRunPageCache: new Map(),
28
+ scenarioRunPageCache: new Map(),
29
+ // Benchmark Run Actions
30
+ setBenchmarkRuns: (runs) => set({ benchmarkRuns: runs }),
31
+ setBenchmarkRunsLoading: (loading) => set({ benchmarkRunsLoading: loading }),
32
+ setBenchmarkRunsError: (error) => set({ benchmarkRunsError: error }),
33
+ setBenchmarkRunsTotalCount: (count) => set({ benchmarkRunsTotalCount: count }),
34
+ setBenchmarkRunsHasMore: (hasMore) => set({ benchmarkRunsHasMore: hasMore }),
35
+ setBenchmarkRunsCurrentPage: (page) => set({ benchmarkRunsCurrentPage: page }),
36
+ setSelectedBenchmarkRunIndex: (index) => set({ selectedBenchmarkRunIndex: index }),
37
+ // Scenario Run Actions
38
+ setScenarioRuns: (runs) => set({ scenarioRuns: runs }),
39
+ setScenarioRunsLoading: (loading) => set({ scenarioRunsLoading: loading }),
40
+ setScenarioRunsError: (error) => set({ scenarioRunsError: error }),
41
+ setScenarioRunsTotalCount: (count) => set({ scenarioRunsTotalCount: count }),
42
+ setScenarioRunsHasMore: (hasMore) => set({ scenarioRunsHasMore: hasMore }),
43
+ setScenarioRunsCurrentPage: (page) => set({ scenarioRunsCurrentPage: page }),
44
+ setSelectedScenarioRunIndex: (index) => set({ selectedScenarioRunIndex: index }),
45
+ setBenchmarkRunIdFilter: (id) => set({ benchmarkRunIdFilter: id }),
46
+ // Cache management
47
+ cacheBenchmarkRunPage: (page, data) => {
48
+ const state = get();
49
+ const cache = state.benchmarkRunPageCache;
50
+ if (cache.size >= MAX_CACHE_SIZE) {
51
+ const oldestKey = cache.keys().next().value;
52
+ if (oldestKey !== undefined) {
53
+ cache.delete(oldestKey);
54
+ }
55
+ }
56
+ const plainData = data.map((d) => JSON.parse(JSON.stringify(d)));
57
+ cache.set(page, plainData);
58
+ set({});
59
+ },
60
+ getCachedBenchmarkRunPage: (page) => {
61
+ return get().benchmarkRunPageCache.get(page);
62
+ },
63
+ cacheScenarioRunPage: (page, data) => {
64
+ const state = get();
65
+ const cache = state.scenarioRunPageCache;
66
+ if (cache.size >= MAX_CACHE_SIZE) {
67
+ const oldestKey = cache.keys().next().value;
68
+ if (oldestKey !== undefined) {
69
+ cache.delete(oldestKey);
70
+ }
71
+ }
72
+ const plainData = data.map((d) => JSON.parse(JSON.stringify(d)));
73
+ cache.set(page, plainData);
74
+ set({});
75
+ },
76
+ getCachedScenarioRunPage: (page) => {
77
+ return get().scenarioRunPageCache.get(page);
78
+ },
79
+ clearCache: () => {
80
+ const state = get();
81
+ state.benchmarkRunPageCache.clear();
82
+ state.scenarioRunPageCache.clear();
83
+ set({
84
+ benchmarkRunPageCache: new Map(),
85
+ scenarioRunPageCache: new Map(),
86
+ });
87
+ },
88
+ clearAll: () => {
89
+ const state = get();
90
+ state.benchmarkRunPageCache.clear();
91
+ state.scenarioRunPageCache.clear();
92
+ set({
93
+ benchmarkRuns: [],
94
+ benchmarkRunsLoading: false,
95
+ benchmarkRunsError: null,
96
+ benchmarkRunsTotalCount: 0,
97
+ benchmarkRunsHasMore: false,
98
+ benchmarkRunsCurrentPage: 0,
99
+ scenarioRuns: [],
100
+ scenarioRunsLoading: false,
101
+ scenarioRunsError: null,
102
+ scenarioRunsTotalCount: 0,
103
+ scenarioRunsHasMore: false,
104
+ scenarioRunsCurrentPage: 0,
105
+ benchmarkRunIdFilter: undefined,
106
+ selectedBenchmarkRunIndex: 0,
107
+ selectedScenarioRunIndex: 0,
108
+ benchmarkRunPageCache: new Map(),
109
+ scenarioRunPageCache: new Map(),
110
+ });
111
+ },
112
+ getSelectedBenchmarkRun: () => {
113
+ const state = get();
114
+ return state.benchmarkRuns[state.selectedBenchmarkRunIndex];
115
+ },
116
+ getSelectedScenarioRun: () => {
117
+ const state = get();
118
+ return state.scenarioRuns[state.selectedScenarioRunIndex];
119
+ },
120
+ }));
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Beta Feature Store - React context for managing beta feature flags
4
+ *
5
+ * Enable beta features by setting the environment variable:
6
+ * export RL_CLI_BETA=1
7
+ * export RL_CLI_BETA=true
8
+ */
9
+ import React from "react";
10
+ import { isBetaEnabled } from "../utils/config.js";
11
+ const BetaFeatureContext = React.createContext(null);
12
+ export function BetaFeatureProvider({ children }) {
13
+ // Read beta status once on mount (env vars don't change during runtime)
14
+ const betaEnabled = React.useMemo(() => isBetaEnabled(), []);
15
+ const isFeatureEnabled = React.useCallback((feature) => {
16
+ // Currently all beta features are gated by the same flag
17
+ // This can be extended to support per-feature flags in the future
18
+ switch (feature) {
19
+ case "benchmarks":
20
+ return betaEnabled;
21
+ default:
22
+ return false;
23
+ }
24
+ }, [betaEnabled]);
25
+ const value = React.useMemo(() => ({
26
+ isBetaEnabled: betaEnabled,
27
+ isFeatureEnabled,
28
+ }), [betaEnabled, isFeatureEnabled]);
29
+ return (_jsx(BetaFeatureContext.Provider, { value: value, children: children }));
30
+ }
31
+ /**
32
+ * Hook to access beta feature flags
33
+ */
34
+ export function useBetaFeatures() {
35
+ const context = React.useContext(BetaFeatureContext);
36
+ if (!context) {
37
+ throw new Error("useBetaFeatures must be used within BetaFeatureProvider");
38
+ }
39
+ return context;
40
+ }
41
+ /**
42
+ * Hook to check if a specific beta feature is enabled
43
+ */
44
+ export function useBetaFeature(feature) {
45
+ const { isFeatureEnabled } = useBetaFeatures();
46
+ return isFeatureEnabled(feature);
47
+ }
@@ -2,6 +2,7 @@
2
2
  * Root Store - Exports all stores for easy importing
3
3
  */
4
4
  export { useNavigation, useNavigationStore, NavigationProvider, } from "./navigationStore.js";
5
+ export { BetaFeatureProvider, useBetaFeatures, useBetaFeature, } from "./betaFeatureStore.js";
5
6
  export { useDevboxStore } from "./devboxStore.js";
6
7
  export { useBlueprintStore } from "./blueprintStore.js";
7
8
  export { useSnapshotStore } from "./snapshotStore.js";
@@ -72,6 +72,14 @@ export function setDetectedTheme(theme) {
72
72
  export function clearDetectedTheme() {
73
73
  config.delete("detectedTheme");
74
74
  }
75
+ /**
76
+ * Check if beta features are enabled via the RL_CLI_BETA environment variable.
77
+ * Set RL_CLI_BETA=1 or RL_CLI_BETA=true to enable beta features.
78
+ */
79
+ export function isBetaEnabled() {
80
+ const betaValue = process.env.RL_CLI_BETA?.toLowerCase();
81
+ return betaValue === "1" || betaValue === "true";
82
+ }
75
83
  /**
76
84
  * Returns the detailed error message for when the API key is not configured.
77
85
  * This message provides instructions on how to set up the API key.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runloop/rl-cli",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "Beautiful CLI for the Runloop platform",
5
5
  "type": "module",
6
6
  "bin": {