unity-hub-cli 0.13.2 → 0.14.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.
- package/dist/index.js +170 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -263,6 +263,101 @@ var NodeProcessLauncher = class {
|
|
|
263
263
|
}
|
|
264
264
|
};
|
|
265
265
|
|
|
266
|
+
// src/infrastructure/terminalTheme.ts
|
|
267
|
+
import { createInterface } from "readline";
|
|
268
|
+
var parseOsc11Response = (response) => {
|
|
269
|
+
const rgbMatch = response.match(/rgb:([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)/);
|
|
270
|
+
if (!rgbMatch) {
|
|
271
|
+
return void 0;
|
|
272
|
+
}
|
|
273
|
+
const [, rHex, gHex, bHex] = rgbMatch;
|
|
274
|
+
if (!rHex || !gHex || !bHex) {
|
|
275
|
+
return void 0;
|
|
276
|
+
}
|
|
277
|
+
const normalizeColorValue = (hex) => {
|
|
278
|
+
const value = parseInt(hex, 16);
|
|
279
|
+
if (hex.length === 4) {
|
|
280
|
+
return Math.floor(value / 256);
|
|
281
|
+
}
|
|
282
|
+
return value;
|
|
283
|
+
};
|
|
284
|
+
return {
|
|
285
|
+
r: normalizeColorValue(rHex),
|
|
286
|
+
g: normalizeColorValue(gHex),
|
|
287
|
+
b: normalizeColorValue(bHex)
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
var calculateRelativeLuminance = (color) => {
|
|
291
|
+
const toLinear = (value) => {
|
|
292
|
+
const normalized = value / 255;
|
|
293
|
+
if (normalized <= 0.03928) {
|
|
294
|
+
return normalized / 12.92;
|
|
295
|
+
}
|
|
296
|
+
return Math.pow((normalized + 0.055) / 1.055, 2.4);
|
|
297
|
+
};
|
|
298
|
+
const rLinear = toLinear(color.r);
|
|
299
|
+
const gLinear = toLinear(color.g);
|
|
300
|
+
const bLinear = toLinear(color.b);
|
|
301
|
+
return 0.2126 * rLinear + 0.7152 * gLinear + 0.0722 * bLinear;
|
|
302
|
+
};
|
|
303
|
+
var determineThemeFromLuminance = (luminance) => {
|
|
304
|
+
const darkThreshold = 0.5;
|
|
305
|
+
return luminance < darkThreshold ? "dark" : "light";
|
|
306
|
+
};
|
|
307
|
+
var queryTerminalBackgroundColor = async (timeoutMs) => {
|
|
308
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
309
|
+
return void 0;
|
|
310
|
+
}
|
|
311
|
+
return new Promise((resolve4) => {
|
|
312
|
+
let responseBuffer = "";
|
|
313
|
+
let resolved = false;
|
|
314
|
+
if (process.stdin.isTTY) {
|
|
315
|
+
process.stdin.setRawMode(true);
|
|
316
|
+
}
|
|
317
|
+
const rl = createInterface({
|
|
318
|
+
input: process.stdin,
|
|
319
|
+
escapeCodeTimeout: timeoutMs
|
|
320
|
+
});
|
|
321
|
+
let timeoutId;
|
|
322
|
+
const onData = (chunk) => {
|
|
323
|
+
responseBuffer += chunk.toString();
|
|
324
|
+
if (responseBuffer.includes("\x07") || responseBuffer.includes("\x1B\\")) {
|
|
325
|
+
if (!resolved) {
|
|
326
|
+
resolved = true;
|
|
327
|
+
const color = parseOsc11Response(responseBuffer);
|
|
328
|
+
cleanup();
|
|
329
|
+
resolve4(color);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
const cleanup = () => {
|
|
334
|
+
clearTimeout(timeoutId);
|
|
335
|
+
rl.close();
|
|
336
|
+
process.stdin.off("data", onData);
|
|
337
|
+
if (process.stdin.isTTY && process.stdin.isRaw) {
|
|
338
|
+
process.stdin.setRawMode(false);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
timeoutId = setTimeout(() => {
|
|
342
|
+
if (!resolved) {
|
|
343
|
+
resolved = true;
|
|
344
|
+
cleanup();
|
|
345
|
+
resolve4(void 0);
|
|
346
|
+
}
|
|
347
|
+
}, timeoutMs);
|
|
348
|
+
process.stdin.on("data", onData);
|
|
349
|
+
process.stdout.write("\x1B]11;?\x07");
|
|
350
|
+
});
|
|
351
|
+
};
|
|
352
|
+
var detectTerminalTheme = async (timeoutMs = 100) => {
|
|
353
|
+
const backgroundColor = await queryTerminalBackgroundColor(timeoutMs);
|
|
354
|
+
if (!backgroundColor) {
|
|
355
|
+
return "dark";
|
|
356
|
+
}
|
|
357
|
+
const luminance = calculateRelativeLuminance(backgroundColor);
|
|
358
|
+
return determineThemeFromLuminance(luminance);
|
|
359
|
+
};
|
|
360
|
+
|
|
266
361
|
// src/infrastructure/unityhub.ts
|
|
267
362
|
import { readFile as readFile2, writeFile } from "fs/promises";
|
|
268
363
|
import { basename } from "path";
|
|
@@ -1017,6 +1112,56 @@ import { basename as basename3 } from "path";
|
|
|
1017
1112
|
import { Box as Box3 } from "ink";
|
|
1018
1113
|
import { useMemo } from "react";
|
|
1019
1114
|
|
|
1115
|
+
// src/presentation/theme.ts
|
|
1116
|
+
import { createContext, createElement, useContext } from "react";
|
|
1117
|
+
var darkPalette = {
|
|
1118
|
+
projectName: "#abd8e7",
|
|
1119
|
+
// Light cyan
|
|
1120
|
+
branch: "#e3839c",
|
|
1121
|
+
// Pink
|
|
1122
|
+
path: "#719bd8",
|
|
1123
|
+
// Blue
|
|
1124
|
+
border: "green",
|
|
1125
|
+
// Green
|
|
1126
|
+
status: "yellow",
|
|
1127
|
+
// Yellow
|
|
1128
|
+
focus: "green"
|
|
1129
|
+
// Green
|
|
1130
|
+
};
|
|
1131
|
+
var lightPalette = {
|
|
1132
|
+
projectName: "#0044aa",
|
|
1133
|
+
// Deep blue
|
|
1134
|
+
branch: "#991144",
|
|
1135
|
+
// Deep magenta
|
|
1136
|
+
path: "#1a4570",
|
|
1137
|
+
// Deep blue
|
|
1138
|
+
border: "#006400",
|
|
1139
|
+
// Dark green
|
|
1140
|
+
status: "#cc6600",
|
|
1141
|
+
// Dark orange (more visible)
|
|
1142
|
+
focus: "#006400"
|
|
1143
|
+
// Dark green
|
|
1144
|
+
};
|
|
1145
|
+
var getColorPalette = (theme) => {
|
|
1146
|
+
return theme === "dark" ? darkPalette : lightPalette;
|
|
1147
|
+
};
|
|
1148
|
+
var defaultThemeContext = {
|
|
1149
|
+
theme: "dark",
|
|
1150
|
+
colors: darkPalette
|
|
1151
|
+
};
|
|
1152
|
+
var ThemeContext = createContext(defaultThemeContext);
|
|
1153
|
+
var useThemeColors = () => {
|
|
1154
|
+
const context = useContext(ThemeContext);
|
|
1155
|
+
return context.colors;
|
|
1156
|
+
};
|
|
1157
|
+
var ThemeProvider = ({ theme, children }) => {
|
|
1158
|
+
const value = {
|
|
1159
|
+
theme,
|
|
1160
|
+
colors: getColorPalette(theme)
|
|
1161
|
+
};
|
|
1162
|
+
return createElement(ThemeContext.Provider, { value }, children);
|
|
1163
|
+
};
|
|
1164
|
+
|
|
1020
1165
|
// src/presentation/utils/path.ts
|
|
1021
1166
|
var homeDirectory = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
1022
1167
|
var normalizedHomeDirectory = homeDirectory.replace(/\\/g, "/");
|
|
@@ -1070,13 +1215,14 @@ var ProjectRow = ({
|
|
|
1070
1215
|
showSpacer
|
|
1071
1216
|
}) => {
|
|
1072
1217
|
const { stdout } = useStdout();
|
|
1218
|
+
const colors = useThemeColors();
|
|
1073
1219
|
const computedCenterWidth = typeof stdout?.columns === "number" ? Math.max(0, stdout.columns - 6) : void 0;
|
|
1074
1220
|
const centerWidth = typeof computedCenterWidth === "number" ? Math.max(0, computedCenterWidth - (isSelected ? 1 : 0)) : void 0;
|
|
1075
1221
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", children: [
|
|
1076
1222
|
/* @__PURE__ */ jsxs2(Box2, { width: 1, flexDirection: "column", alignItems: "center", marginLeft: 0, children: [
|
|
1077
|
-
/* @__PURE__ */ jsx2(Text, { color: isSelected ?
|
|
1078
|
-
showBranch ? /* @__PURE__ */ jsx2(Text, { color: isSelected ?
|
|
1079
|
-
showPath ? /* @__PURE__ */ jsx2(Text, { color: isSelected ?
|
|
1223
|
+
/* @__PURE__ */ jsx2(Text, { color: isSelected ? colors.focus : void 0, children: selectionBar }),
|
|
1224
|
+
showBranch ? /* @__PURE__ */ jsx2(Text, { color: isSelected ? colors.focus : void 0, children: selectionBar }) : null,
|
|
1225
|
+
showPath ? /* @__PURE__ */ jsx2(Text, { color: isSelected ? colors.focus : void 0, children: selectionBar }) : null
|
|
1080
1226
|
] }),
|
|
1081
1227
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginLeft: isSelected ? 2 : 1, width: centerWidth, children: [
|
|
1082
1228
|
/* @__PURE__ */ jsxs2(Text, { wrap: "truncate", children: [
|
|
@@ -1088,8 +1234,8 @@ var ProjectRow = ({
|
|
|
1088
1234
|
updatedText ? /* @__PURE__ */ jsx2(Text, { children: ` ${updatedText}` }) : null,
|
|
1089
1235
|
statusLabel && statusColor ? /* @__PURE__ */ jsx2(Text, { color: statusColor, children: ` ${statusLabel}` }) : null
|
|
1090
1236
|
] }),
|
|
1091
|
-
showBranch ? /* @__PURE__ */ jsx2(Text, { color:
|
|
1092
|
-
showPath ? /* @__PURE__ */ jsx2(Text, { color:
|
|
1237
|
+
showBranch ? /* @__PURE__ */ jsx2(Text, { color: colors.branch, wrap: "truncate", children: branchLine }) : null,
|
|
1238
|
+
showPath ? /* @__PURE__ */ jsx2(Text, { color: colors.path, wrap: "truncate", children: pathLine }) : null,
|
|
1093
1239
|
showSpacer ? /* @__PURE__ */ jsx2(Text, { children: " " }) : null
|
|
1094
1240
|
] }),
|
|
1095
1241
|
/* @__PURE__ */ jsxs2(Box2, { marginLeft: 1, width: 1, flexDirection: "column", alignItems: "center", children: [
|
|
@@ -1103,8 +1249,6 @@ var ProjectRow = ({
|
|
|
1103
1249
|
|
|
1104
1250
|
// src/presentation/components/ProjectList.tsx
|
|
1105
1251
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1106
|
-
var PROJECT_COLOR = "#abd8e7";
|
|
1107
|
-
var LOCK_COLOR = "yellow";
|
|
1108
1252
|
var STATUS_LABELS = {
|
|
1109
1253
|
idle: "",
|
|
1110
1254
|
running: "[running]",
|
|
@@ -1199,6 +1343,7 @@ var ProjectList = ({
|
|
|
1199
1343
|
launchedProjects,
|
|
1200
1344
|
totalProjects
|
|
1201
1345
|
}) => {
|
|
1346
|
+
const colors = useThemeColors();
|
|
1202
1347
|
const scrollbarChars = useMemo(() => {
|
|
1203
1348
|
const totalLines = totalProjects * linesPerProject;
|
|
1204
1349
|
const windowProjects = visibleProjects.length;
|
|
@@ -1252,14 +1397,14 @@ var ProjectList = ({
|
|
|
1252
1397
|
const pathScrollbar = showPath ? scrollbarChars[baseScrollbarIndex + 1 + (showBranch ? 1 : 0)] ?? " " : " ";
|
|
1253
1398
|
const spacerScrollbar = scrollbarChars[baseScrollbarIndex + linesPerProject - 1] ?? " ";
|
|
1254
1399
|
const statusLabel = STATUS_LABELS[displayStatus];
|
|
1255
|
-
const statusColor = displayStatus === "running" ?
|
|
1400
|
+
const statusColor = displayStatus === "running" ? colors.status : void 0;
|
|
1256
1401
|
return /* @__PURE__ */ jsx3(
|
|
1257
1402
|
ProjectRow,
|
|
1258
1403
|
{
|
|
1259
1404
|
isSelected,
|
|
1260
1405
|
selectionBar,
|
|
1261
1406
|
projectName,
|
|
1262
|
-
projectColor:
|
|
1407
|
+
projectColor: colors.projectName,
|
|
1263
1408
|
versionLabel,
|
|
1264
1409
|
updatedText,
|
|
1265
1410
|
statusLabel,
|
|
@@ -1313,10 +1458,11 @@ var SortPanel = ({ sortPreferences, focusedIndex, width }) => {
|
|
|
1313
1458
|
const primaryLine = lineForPrimary(sortPreferences.primary);
|
|
1314
1459
|
const directionLine = lineForDirection(sortPreferences);
|
|
1315
1460
|
const favoritesLine = lineForFavorites(sortPreferences.favoritesFirst);
|
|
1461
|
+
const colors = useThemeColors();
|
|
1316
1462
|
const Item = ({ label, selected }) => {
|
|
1317
1463
|
const prefix = selected ? "> " : " ";
|
|
1318
1464
|
return /* @__PURE__ */ jsxs3(Text2, { children: [
|
|
1319
|
-
selected ? /* @__PURE__ */ jsx4(Text2, { color:
|
|
1465
|
+
selected ? /* @__PURE__ */ jsx4(Text2, { color: colors.focus, children: prefix }) : prefix,
|
|
1320
1466
|
label
|
|
1321
1467
|
] });
|
|
1322
1468
|
};
|
|
@@ -1325,7 +1471,7 @@ var SortPanel = ({ sortPreferences, focusedIndex, width }) => {
|
|
|
1325
1471
|
{
|
|
1326
1472
|
flexDirection: "column",
|
|
1327
1473
|
borderStyle: "round",
|
|
1328
|
-
borderColor:
|
|
1474
|
+
borderColor: colors.border,
|
|
1329
1475
|
paddingX: 1,
|
|
1330
1476
|
width,
|
|
1331
1477
|
children: [
|
|
@@ -1345,10 +1491,11 @@ var lineForPath = (on) => `Show path: ${on ? "ON" : "OFF"}`;
|
|
|
1345
1491
|
var VisibilityPanel = ({ visibility, focusedIndex, width }) => {
|
|
1346
1492
|
const branchLine = lineForBranch(visibility.showBranch);
|
|
1347
1493
|
const pathLine = lineForPath(visibility.showPath);
|
|
1494
|
+
const colors = useThemeColors();
|
|
1348
1495
|
const Item = ({ label, selected }) => {
|
|
1349
1496
|
const prefix = selected ? "> " : " ";
|
|
1350
1497
|
return /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
1351
|
-
selected ? /* @__PURE__ */ jsx5(Text3, { color:
|
|
1498
|
+
selected ? /* @__PURE__ */ jsx5(Text3, { color: colors.focus, children: prefix }) : prefix,
|
|
1352
1499
|
label
|
|
1353
1500
|
] });
|
|
1354
1501
|
};
|
|
@@ -1357,7 +1504,7 @@ var VisibilityPanel = ({ visibility, focusedIndex, width }) => {
|
|
|
1357
1504
|
{
|
|
1358
1505
|
flexDirection: "column",
|
|
1359
1506
|
borderStyle: "round",
|
|
1360
|
-
borderColor:
|
|
1507
|
+
borderColor: colors.border,
|
|
1361
1508
|
paddingX: 1,
|
|
1362
1509
|
width,
|
|
1363
1510
|
children: [
|
|
@@ -1562,6 +1709,7 @@ var App = ({
|
|
|
1562
1709
|
}) => {
|
|
1563
1710
|
const { exit } = useApp();
|
|
1564
1711
|
const { stdout } = useStdout2();
|
|
1712
|
+
const colors = useThemeColors();
|
|
1565
1713
|
const [projectViews, setProjectViews] = useState4(projects);
|
|
1566
1714
|
const [isSortMenuOpen, setIsSortMenuOpen] = useState4(false);
|
|
1567
1715
|
const [isVisibilityMenuOpen, setIsVisibilityMenuOpen] = useState4(false);
|
|
@@ -2040,7 +2188,7 @@ var App = ({
|
|
|
2040
2188
|
{
|
|
2041
2189
|
flexDirection: "column",
|
|
2042
2190
|
borderStyle: "round",
|
|
2043
|
-
borderColor:
|
|
2191
|
+
borderColor: colors.border,
|
|
2044
2192
|
width: typeof stdout?.columns === "number" ? stdout.columns : void 0,
|
|
2045
2193
|
children: sortedProjects.length === 0 ? /* @__PURE__ */ jsx6(Text4, { children: "No Unity Hub projects were found." }) : /* @__PURE__ */ jsx6(
|
|
2046
2194
|
ProjectList,
|
|
@@ -2127,21 +2275,22 @@ var bootstrap = async () => {
|
|
|
2127
2275
|
);
|
|
2128
2276
|
if (!rawModeSupported) {
|
|
2129
2277
|
const message = [
|
|
2130
|
-
"
|
|
2131
|
-
"PowerShell / cmd.exe
|
|
2132
|
-
"MinTTY
|
|
2278
|
+
"Interactive input (Raw mode) is not available in this terminal.",
|
|
2279
|
+
"Please run in PowerShell / cmd.exe, or use Git Bash in a ConPTY-based terminal (Windows Terminal, VS Code/Cursor integrated terminal).",
|
|
2280
|
+
"For MinTTY Git Bash, use one of the following:",
|
|
2133
2281
|
" - winpty cmd.exe /c npx unity-hub-cli",
|
|
2134
2282
|
" - winpty powershell.exe -NoProfile -Command npx unity-hub-cli",
|
|
2135
|
-
"
|
|
2136
|
-
"
|
|
2283
|
+
"(If already built) npm run build && winpty node dist/index.js",
|
|
2284
|
+
"Details: https://github.com/vadimdemedes/ink/#israwmodesupported"
|
|
2137
2285
|
].join("\n");
|
|
2138
2286
|
console.error(message);
|
|
2139
2287
|
process2.exitCode = 1;
|
|
2140
2288
|
return;
|
|
2141
2289
|
}
|
|
2290
|
+
const theme = await detectTerminalTheme();
|
|
2142
2291
|
const projects = await listProjectsUseCase.execute();
|
|
2143
2292
|
const { waitUntilExit } = render(
|
|
2144
|
-
/* @__PURE__ */ jsx7(
|
|
2293
|
+
/* @__PURE__ */ jsx7(ThemeProvider, { theme, children: /* @__PURE__ */ jsx7(
|
|
2145
2294
|
App,
|
|
2146
2295
|
{
|
|
2147
2296
|
projects,
|
|
@@ -2150,7 +2299,7 @@ var bootstrap = async () => {
|
|
|
2150
2299
|
onRefresh: () => listProjectsUseCase.execute(),
|
|
2151
2300
|
useGitRootName
|
|
2152
2301
|
}
|
|
2153
|
-
)
|
|
2302
|
+
) })
|
|
2154
2303
|
);
|
|
2155
2304
|
await waitUntilExit();
|
|
2156
2305
|
process2.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|