@ganakailabs/cloudeval-cli 0.18.4

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,131 @@
1
+ import {
2
+ CLI_VERSION
3
+ } from "./chunk-RQ2GBK43.js";
4
+ import {
5
+ shouldUseColor,
6
+ terminalTheme
7
+ } from "./chunk-UOCT7M4J.js";
8
+
9
+ // src/ui/components/Banner.tsx
10
+ import { Box, Text } from "ink";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ var wordArt = [
13
+ " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 ",
14
+ "\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 ",
15
+ "\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ",
16
+ "\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 ",
17
+ "\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
18
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
19
+ ];
20
+ var artWidth = (art) => Math.max(...art.map((line) => line.length));
21
+ var fillGradient = [
22
+ "#ffd60a",
23
+ "#facc15",
24
+ "#fbbf24",
25
+ "#f59e0b",
26
+ "#d97706",
27
+ "#b45309"
28
+ ];
29
+ var outlineGradient = [
30
+ "#ca8a04",
31
+ "#a16207",
32
+ "#92400e",
33
+ "#9a3412",
34
+ "#7c2d12",
35
+ "#7c2d12"
36
+ ];
37
+ var outlineGlyphs = /* @__PURE__ */ new Set(["\u2554", "\u2557", "\u255A", "\u255D", "\u2550", "\u2551", "\u2566", "\u2569", "\u2560", "\u2563"]);
38
+ var bannerSegmentTone = (character) => {
39
+ if (character === " ") {
40
+ return "space";
41
+ }
42
+ return outlineGlyphs.has(character) ? "outline" : "fill";
43
+ };
44
+ var splitBannerLineSegments = (line) => {
45
+ const segments = [];
46
+ for (const character of line) {
47
+ const tone = bannerSegmentTone(character);
48
+ const previous = segments.at(-1);
49
+ if (previous?.tone === tone) {
50
+ previous.text += character;
51
+ } else {
52
+ segments.push({ text: character, tone });
53
+ }
54
+ }
55
+ return segments;
56
+ };
57
+ var gradientIndex = (lineIndex, totalLines, paletteLength) => {
58
+ const boundedTotal = Math.max(1, totalLines);
59
+ const boundedLine = Math.min(Math.max(0, lineIndex), boundedTotal - 1);
60
+ const ratio = boundedTotal === 1 ? 0 : boundedLine / (boundedTotal - 1);
61
+ return Math.min(paletteLength - 1, Math.round(ratio * (paletteLength - 1)));
62
+ };
63
+ var bannerSegmentColor = (tone, lineIndex = 0, totalLines = wordArt.length) => {
64
+ if (!shouldUseColor()) {
65
+ return void 0;
66
+ }
67
+ if (tone === "outline") {
68
+ return outlineGradient[gradientIndex(lineIndex, totalLines, outlineGradient.length)];
69
+ }
70
+ if (tone === "fill") {
71
+ return fillGradient[gradientIndex(lineIndex, totalLines, fillGradient.length)];
72
+ }
73
+ return void 0;
74
+ };
75
+ var BannerArtLine = ({ line, lineIndex, totalLines }) => /* @__PURE__ */ jsx(Text, { wrap: "truncate", children: splitBannerLineSegments(line).map((segment, index) => /* @__PURE__ */ jsx(
76
+ Text,
77
+ {
78
+ color: bannerSegmentColor(segment.tone, lineIndex, totalLines),
79
+ children: segment.text
80
+ },
81
+ `${index}-${segment.text}`
82
+ )) });
83
+ var Banner = ({
84
+ disable = false,
85
+ details = [],
86
+ terminalColumns
87
+ }) => {
88
+ if (disable) return null;
89
+ const columns = terminalColumns ?? process.stdout.columns ?? 100;
90
+ const art = wordArt;
91
+ const width = artWidth(art);
92
+ const showArt = columns >= width;
93
+ const showDetailsBesideArt = showArt && details.length > 0 && columns >= width + 42;
94
+ const version = process.env.CLOUDEVAL_CLI_VERSION ?? CLI_VERSION;
95
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "flex-start", marginBottom: 1, children: [
96
+ showArt ? /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ /* @__PURE__ */ jsx(Text, { color: terminalTheme.success, children: "Welcome to" }),
98
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
99
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: art.map((line, lineIndex) => /* @__PURE__ */ jsx(
100
+ BannerArtLine,
101
+ {
102
+ line,
103
+ lineIndex,
104
+ totalLines: art.length
105
+ },
106
+ line
107
+ )) }),
108
+ showDetailsBesideArt ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [
109
+ /* @__PURE__ */ jsxs(Text, { color: terminalTheme.success, children: [
110
+ "CLI v",
111
+ version
112
+ ] }),
113
+ details.map((detail) => /* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "truncate", children: detail }, detail))
114
+ ] }) : null
115
+ ] })
116
+ ] }) : null,
117
+ !showDetailsBesideArt ? /* @__PURE__ */ jsxs(Fragment, { children: [
118
+ /* @__PURE__ */ jsxs(Text, { color: terminalTheme.success, children: [
119
+ "CLI v",
120
+ version
121
+ ] }),
122
+ details.map((detail) => /* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "truncate", children: detail }, detail))
123
+ ] }) : null
124
+ ] });
125
+ };
126
+
127
+ export {
128
+ splitBannerLineSegments,
129
+ bannerSegmentColor,
130
+ Banner
131
+ };
@@ -0,0 +1,6 @@
1
+ // src/version.ts
2
+ var CLI_VERSION = "0.18.4";
3
+
4
+ export {
5
+ CLI_VERSION
6
+ };
@@ -0,0 +1,174 @@
1
+ // src/frontendLinks.ts
2
+ var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
3
+ var resolveFrontendBaseUrl = ({
4
+ frontendUrl,
5
+ apiBaseUrl,
6
+ env = process.env
7
+ } = {}) => {
8
+ const explicit = frontendUrl?.trim() || env.CLOUDEVAL_FRONTEND_URL || env.CLOUDEVAL_WEB_URL;
9
+ if (explicit) {
10
+ return trimTrailingSlash(explicit);
11
+ }
12
+ try {
13
+ const api = apiBaseUrl ? new URL(apiBaseUrl) : void 0;
14
+ if (api && ["localhost", "127.0.0.1", "::1"].includes(api.hostname)) {
15
+ return "http://localhost:3000";
16
+ }
17
+ } catch {
18
+ }
19
+ return "https://cloudeval.ai";
20
+ };
21
+ var appUrl = (baseUrl, path) => new URL(
22
+ `/app${path.startsWith("/") ? path : `/${path}`}`,
23
+ `${trimTrailingSlash(baseUrl)}/`
24
+ );
25
+ var setParam = (url, key, value) => {
26
+ if (value !== void 0 && value !== "" && value !== false) {
27
+ url.searchParams.set(key, String(value));
28
+ }
29
+ };
30
+ var setArrayParam = (url, key, value) => {
31
+ if (!value) {
32
+ return;
33
+ }
34
+ url.searchParams.set(key, Array.isArray(value) ? value.join(",") : value);
35
+ };
36
+ var buildFrontendUrl = (options) => {
37
+ let url;
38
+ switch (options.target) {
39
+ case "overview":
40
+ url = appUrl(options.baseUrl, "/overview");
41
+ break;
42
+ case "chat":
43
+ url = appUrl(options.baseUrl, "/chat");
44
+ setParam(url, "threadId", options.threadId);
45
+ break;
46
+ case "projects":
47
+ url = appUrl(options.baseUrl, "/projects");
48
+ if (options.quick) {
49
+ setParam(url, "dialog", "quick");
50
+ setParam(url, "template_url", options.templateUrl);
51
+ setParam(url, "name", options.name);
52
+ setParam(url, "description", options.description);
53
+ setParam(url, "provider", options.provider);
54
+ setParam(url, "auto_submit", options.autoSubmit ? "true" : void 0);
55
+ }
56
+ break;
57
+ case "project":
58
+ if (!options.projectId) {
59
+ throw new Error("projectId is required for project frontend links.");
60
+ }
61
+ url = appUrl(
62
+ options.baseUrl,
63
+ `/projects/${encodeURIComponent(options.projectId)}`
64
+ );
65
+ setParam(url, "view", options.view);
66
+ setParam(url, "layout", options.layout);
67
+ setArrayParam(url, "node", options.node);
68
+ setParam(url, "resource", options.resource);
69
+ setParam(url, "tab", options.tab);
70
+ setParam(url, "file", options.file);
71
+ setArrayParam(url, "files", options.files);
72
+ setParam(url, "cursor", options.cursor);
73
+ setParam(url, "selection", options.selection);
74
+ setParam(
75
+ url,
76
+ "workspaceFocus",
77
+ options.workspaceFocus ? "true" : void 0
78
+ );
79
+ setParam(url, "mode", options.presentation ? "presentation" : void 0);
80
+ break;
81
+ case "connections":
82
+ url = appUrl(options.baseUrl, "/connections");
83
+ setParam(url, "dialog", options.dialog);
84
+ break;
85
+ case "connection":
86
+ if (!options.connectionId) {
87
+ throw new Error(
88
+ "connectionId is required for connection frontend links."
89
+ );
90
+ }
91
+ url = appUrl(
92
+ options.baseUrl,
93
+ `/connections/${encodeURIComponent(options.connectionId)}`
94
+ );
95
+ break;
96
+ case "reports":
97
+ url = options.projectId ? appUrl(
98
+ options.baseUrl,
99
+ `/reports/${encodeURIComponent(options.projectId)}`
100
+ ) : appUrl(options.baseUrl, "/reports");
101
+ setParam(url, "tab", options.tab);
102
+ setParam(url, "reportType", options.reportType);
103
+ setParam(url, "timeRange", options.timeRange);
104
+ setParam(url, "persona", options.persona);
105
+ setParam(url, "cadence", options.cadence);
106
+ setParam(url, "issuesQuery", options.issuesQuery);
107
+ setParam(
108
+ url,
109
+ "issuesFullscreen",
110
+ options.issuesFullscreen ? "1" : void 0
111
+ );
112
+ setParam(url, "issuesView", options.issuesView);
113
+ setParam(url, "downloadPdf", options.downloadPdf ? "1" : void 0);
114
+ setParam(url, "pdfVerbosity", options.pdfVerbosity);
115
+ setParam(url, "downloadReport", options.downloadReport);
116
+ setParam(url, "reportVerbosity", options.reportVerbosity);
117
+ break;
118
+ case "billing":
119
+ url = appUrl(options.baseUrl, "/subscription");
120
+ setParam(url, "tab", options.tab);
121
+ break;
122
+ default:
123
+ throw new Error(
124
+ `Unsupported frontend target '${String(options.target)}'.`
125
+ );
126
+ }
127
+ return url.toString();
128
+ };
129
+ var openExternalUrl = async (url) => {
130
+ const { spawn } = await import("child_process");
131
+ const platform = process.platform;
132
+ const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
133
+ const args = platform === "win32" ? ["/c", "start", "", url] : [url];
134
+ const child = spawn(command, args, {
135
+ detached: true,
136
+ stdio: "ignore"
137
+ });
138
+ child.unref();
139
+ };
140
+
141
+ // src/ui/userDisplayName.ts
142
+ var toTitleCase = (value) => {
143
+ const normalized = value.trim();
144
+ if (!normalized) {
145
+ return "";
146
+ }
147
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1).toLowerCase();
148
+ };
149
+ var firstToken = (value) => {
150
+ const token = value?.trim().split(/\s+/)[0]?.replace(/^[^\p{L}]+|[^\p{L}]+$/gu, "");
151
+ return token ? toTitleCase(token) : void 0;
152
+ };
153
+ var firstNameFromEmail = (email) => {
154
+ const localPart = email?.split("@")[0];
155
+ if (!localPart) {
156
+ return void 0;
157
+ }
158
+ const token = localPart.split(/[._-]+/).find((part) => /[a-z]/i.test(part))?.replace(/\d+/g, "");
159
+ return token ? toTitleCase(token) : void 0;
160
+ };
161
+ var getFirstNameForDisplay = (user, fallback = "You") => {
162
+ const fromName = firstToken(user?.full_name ?? user?.fullName ?? user?.name);
163
+ if (fromName) {
164
+ return fromName;
165
+ }
166
+ return firstNameFromEmail(user?.email) ?? fallback;
167
+ };
168
+
169
+ export {
170
+ resolveFrontendBaseUrl,
171
+ buildFrontendUrl,
172
+ openExternalUrl,
173
+ getFirstNameForDisplay
174
+ };
@@ -0,0 +1,43 @@
1
+ // src/ui/theme.ts
2
+ var hasColor = () => !process.env.NO_COLOR && process.env.TERM !== "dumb";
3
+ var terminalBackground = () => {
4
+ const colorFgBg = process.env.COLORFGBG;
5
+ if (!colorFgBg) {
6
+ return "unknown";
7
+ }
8
+ const bg = Number(colorFgBg.split(";").pop());
9
+ if (!Number.isFinite(bg)) {
10
+ return "unknown";
11
+ }
12
+ return bg >= 7 && bg <= 15 ? "light" : "dark";
13
+ };
14
+ var isLightTerminal = () => terminalBackground() === "light";
15
+ var color = (dark, light) => {
16
+ if (!hasColor()) {
17
+ return void 0;
18
+ }
19
+ return isLightTerminal() ? light : dark;
20
+ };
21
+ var terminalTheme = {
22
+ brand: color("cyan", "blue"),
23
+ accent: color("yellow", "blue"),
24
+ success: color("green", "green"),
25
+ muted: color("gray", "gray"),
26
+ /** Inline ghost / autosuggest — distinct from user text and from gray-muted UI chrome */
27
+ inputGhost: color("magenta", "blue"),
28
+ warning: color("yellow", "magenta"),
29
+ danger: color("red", "red"),
30
+ cursor: color("cyan", "blue")
31
+ };
32
+ var shouldUseColor = hasColor;
33
+ var raisedButtonStyle = {
34
+ border: "round",
35
+ activeMarker: "\u25CF",
36
+ inactiveMarker: "\u25CB"
37
+ };
38
+
39
+ export {
40
+ terminalTheme,
41
+ shouldUseColor,
42
+ raisedButtonStyle
43
+ };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ declare const setVerbose: (enabled: boolean) => void;
3
+ declare const isVerbose: () => boolean;
4
+ declare const verboseLog: (message: string, data?: any) => void;
5
+ declare const verboseLogRequest: (method: string, url: string, options?: RequestInit) => void;
6
+ declare const verboseLogResponse: (url: string, response: Response, error?: any) => void;
7
+
8
+ export { isVerbose, setVerbose, verboseLog, verboseLogRequest, verboseLogResponse };