unity-hub-cli 0.13.1 → 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 +180 -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";
|
|
@@ -652,6 +747,13 @@ var extractProjectPath = (command) => {
|
|
|
652
747
|
var isUnityMainProcess = (command) => {
|
|
653
748
|
return UNITY_EXECUTABLE_PATTERN.test(command);
|
|
654
749
|
};
|
|
750
|
+
var isUnityAuxiliaryProcess = (command) => {
|
|
751
|
+
const normalized = command.toLowerCase();
|
|
752
|
+
if (normalized.includes("-batchmode")) {
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
return normalized.includes("assetimportworker");
|
|
756
|
+
};
|
|
655
757
|
var isProcessMissingError = (error) => {
|
|
656
758
|
if (typeof error !== "object" || error === null) {
|
|
657
759
|
return false;
|
|
@@ -698,6 +800,9 @@ var MacUnityProcessReader = class {
|
|
|
698
800
|
if (!isUnityMainProcess(command)) {
|
|
699
801
|
return void 0;
|
|
700
802
|
}
|
|
803
|
+
if (isUnityAuxiliaryProcess(command)) {
|
|
804
|
+
return void 0;
|
|
805
|
+
}
|
|
701
806
|
const projectArgument = extractProjectPath(command);
|
|
702
807
|
if (!projectArgument) {
|
|
703
808
|
return void 0;
|
|
@@ -1007,6 +1112,56 @@ import { basename as basename3 } from "path";
|
|
|
1007
1112
|
import { Box as Box3 } from "ink";
|
|
1008
1113
|
import { useMemo } from "react";
|
|
1009
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
|
+
|
|
1010
1165
|
// src/presentation/utils/path.ts
|
|
1011
1166
|
var homeDirectory = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
1012
1167
|
var normalizedHomeDirectory = homeDirectory.replace(/\\/g, "/");
|
|
@@ -1060,13 +1215,14 @@ var ProjectRow = ({
|
|
|
1060
1215
|
showSpacer
|
|
1061
1216
|
}) => {
|
|
1062
1217
|
const { stdout } = useStdout();
|
|
1218
|
+
const colors = useThemeColors();
|
|
1063
1219
|
const computedCenterWidth = typeof stdout?.columns === "number" ? Math.max(0, stdout.columns - 6) : void 0;
|
|
1064
1220
|
const centerWidth = typeof computedCenterWidth === "number" ? Math.max(0, computedCenterWidth - (isSelected ? 1 : 0)) : void 0;
|
|
1065
1221
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", children: [
|
|
1066
1222
|
/* @__PURE__ */ jsxs2(Box2, { width: 1, flexDirection: "column", alignItems: "center", marginLeft: 0, children: [
|
|
1067
|
-
/* @__PURE__ */ jsx2(Text, { color: isSelected ?
|
|
1068
|
-
showBranch ? /* @__PURE__ */ jsx2(Text, { color: isSelected ?
|
|
1069
|
-
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
|
|
1070
1226
|
] }),
|
|
1071
1227
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginLeft: isSelected ? 2 : 1, width: centerWidth, children: [
|
|
1072
1228
|
/* @__PURE__ */ jsxs2(Text, { wrap: "truncate", children: [
|
|
@@ -1078,8 +1234,8 @@ var ProjectRow = ({
|
|
|
1078
1234
|
updatedText ? /* @__PURE__ */ jsx2(Text, { children: ` ${updatedText}` }) : null,
|
|
1079
1235
|
statusLabel && statusColor ? /* @__PURE__ */ jsx2(Text, { color: statusColor, children: ` ${statusLabel}` }) : null
|
|
1080
1236
|
] }),
|
|
1081
|
-
showBranch ? /* @__PURE__ */ jsx2(Text, { color:
|
|
1082
|
-
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,
|
|
1083
1239
|
showSpacer ? /* @__PURE__ */ jsx2(Text, { children: " " }) : null
|
|
1084
1240
|
] }),
|
|
1085
1241
|
/* @__PURE__ */ jsxs2(Box2, { marginLeft: 1, width: 1, flexDirection: "column", alignItems: "center", children: [
|
|
@@ -1093,8 +1249,6 @@ var ProjectRow = ({
|
|
|
1093
1249
|
|
|
1094
1250
|
// src/presentation/components/ProjectList.tsx
|
|
1095
1251
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1096
|
-
var PROJECT_COLOR = "#abd8e7";
|
|
1097
|
-
var LOCK_COLOR = "yellow";
|
|
1098
1252
|
var STATUS_LABELS = {
|
|
1099
1253
|
idle: "",
|
|
1100
1254
|
running: "[running]",
|
|
@@ -1189,6 +1343,7 @@ var ProjectList = ({
|
|
|
1189
1343
|
launchedProjects,
|
|
1190
1344
|
totalProjects
|
|
1191
1345
|
}) => {
|
|
1346
|
+
const colors = useThemeColors();
|
|
1192
1347
|
const scrollbarChars = useMemo(() => {
|
|
1193
1348
|
const totalLines = totalProjects * linesPerProject;
|
|
1194
1349
|
const windowProjects = visibleProjects.length;
|
|
@@ -1242,14 +1397,14 @@ var ProjectList = ({
|
|
|
1242
1397
|
const pathScrollbar = showPath ? scrollbarChars[baseScrollbarIndex + 1 + (showBranch ? 1 : 0)] ?? " " : " ";
|
|
1243
1398
|
const spacerScrollbar = scrollbarChars[baseScrollbarIndex + linesPerProject - 1] ?? " ";
|
|
1244
1399
|
const statusLabel = STATUS_LABELS[displayStatus];
|
|
1245
|
-
const statusColor = displayStatus === "running" ?
|
|
1400
|
+
const statusColor = displayStatus === "running" ? colors.status : void 0;
|
|
1246
1401
|
return /* @__PURE__ */ jsx3(
|
|
1247
1402
|
ProjectRow,
|
|
1248
1403
|
{
|
|
1249
1404
|
isSelected,
|
|
1250
1405
|
selectionBar,
|
|
1251
1406
|
projectName,
|
|
1252
|
-
projectColor:
|
|
1407
|
+
projectColor: colors.projectName,
|
|
1253
1408
|
versionLabel,
|
|
1254
1409
|
updatedText,
|
|
1255
1410
|
statusLabel,
|
|
@@ -1303,10 +1458,11 @@ var SortPanel = ({ sortPreferences, focusedIndex, width }) => {
|
|
|
1303
1458
|
const primaryLine = lineForPrimary(sortPreferences.primary);
|
|
1304
1459
|
const directionLine = lineForDirection(sortPreferences);
|
|
1305
1460
|
const favoritesLine = lineForFavorites(sortPreferences.favoritesFirst);
|
|
1461
|
+
const colors = useThemeColors();
|
|
1306
1462
|
const Item = ({ label, selected }) => {
|
|
1307
1463
|
const prefix = selected ? "> " : " ";
|
|
1308
1464
|
return /* @__PURE__ */ jsxs3(Text2, { children: [
|
|
1309
|
-
selected ? /* @__PURE__ */ jsx4(Text2, { color:
|
|
1465
|
+
selected ? /* @__PURE__ */ jsx4(Text2, { color: colors.focus, children: prefix }) : prefix,
|
|
1310
1466
|
label
|
|
1311
1467
|
] });
|
|
1312
1468
|
};
|
|
@@ -1315,7 +1471,7 @@ var SortPanel = ({ sortPreferences, focusedIndex, width }) => {
|
|
|
1315
1471
|
{
|
|
1316
1472
|
flexDirection: "column",
|
|
1317
1473
|
borderStyle: "round",
|
|
1318
|
-
borderColor:
|
|
1474
|
+
borderColor: colors.border,
|
|
1319
1475
|
paddingX: 1,
|
|
1320
1476
|
width,
|
|
1321
1477
|
children: [
|
|
@@ -1335,10 +1491,11 @@ var lineForPath = (on) => `Show path: ${on ? "ON" : "OFF"}`;
|
|
|
1335
1491
|
var VisibilityPanel = ({ visibility, focusedIndex, width }) => {
|
|
1336
1492
|
const branchLine = lineForBranch(visibility.showBranch);
|
|
1337
1493
|
const pathLine = lineForPath(visibility.showPath);
|
|
1494
|
+
const colors = useThemeColors();
|
|
1338
1495
|
const Item = ({ label, selected }) => {
|
|
1339
1496
|
const prefix = selected ? "> " : " ";
|
|
1340
1497
|
return /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
1341
|
-
selected ? /* @__PURE__ */ jsx5(Text3, { color:
|
|
1498
|
+
selected ? /* @__PURE__ */ jsx5(Text3, { color: colors.focus, children: prefix }) : prefix,
|
|
1342
1499
|
label
|
|
1343
1500
|
] });
|
|
1344
1501
|
};
|
|
@@ -1347,7 +1504,7 @@ var VisibilityPanel = ({ visibility, focusedIndex, width }) => {
|
|
|
1347
1504
|
{
|
|
1348
1505
|
flexDirection: "column",
|
|
1349
1506
|
borderStyle: "round",
|
|
1350
|
-
borderColor:
|
|
1507
|
+
borderColor: colors.border,
|
|
1351
1508
|
paddingX: 1,
|
|
1352
1509
|
width,
|
|
1353
1510
|
children: [
|
|
@@ -1552,6 +1709,7 @@ var App = ({
|
|
|
1552
1709
|
}) => {
|
|
1553
1710
|
const { exit } = useApp();
|
|
1554
1711
|
const { stdout } = useStdout2();
|
|
1712
|
+
const colors = useThemeColors();
|
|
1555
1713
|
const [projectViews, setProjectViews] = useState4(projects);
|
|
1556
1714
|
const [isSortMenuOpen, setIsSortMenuOpen] = useState4(false);
|
|
1557
1715
|
const [isVisibilityMenuOpen, setIsVisibilityMenuOpen] = useState4(false);
|
|
@@ -2030,7 +2188,7 @@ var App = ({
|
|
|
2030
2188
|
{
|
|
2031
2189
|
flexDirection: "column",
|
|
2032
2190
|
borderStyle: "round",
|
|
2033
|
-
borderColor:
|
|
2191
|
+
borderColor: colors.border,
|
|
2034
2192
|
width: typeof stdout?.columns === "number" ? stdout.columns : void 0,
|
|
2035
2193
|
children: sortedProjects.length === 0 ? /* @__PURE__ */ jsx6(Text4, { children: "No Unity Hub projects were found." }) : /* @__PURE__ */ jsx6(
|
|
2036
2194
|
ProjectList,
|
|
@@ -2117,21 +2275,22 @@ var bootstrap = async () => {
|
|
|
2117
2275
|
);
|
|
2118
2276
|
if (!rawModeSupported) {
|
|
2119
2277
|
const message = [
|
|
2120
|
-
"
|
|
2121
|
-
"PowerShell / cmd.exe
|
|
2122
|
-
"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:",
|
|
2123
2281
|
" - winpty cmd.exe /c npx unity-hub-cli",
|
|
2124
2282
|
" - winpty powershell.exe -NoProfile -Command npx unity-hub-cli",
|
|
2125
|
-
"
|
|
2126
|
-
"
|
|
2283
|
+
"(If already built) npm run build && winpty node dist/index.js",
|
|
2284
|
+
"Details: https://github.com/vadimdemedes/ink/#israwmodesupported"
|
|
2127
2285
|
].join("\n");
|
|
2128
2286
|
console.error(message);
|
|
2129
2287
|
process2.exitCode = 1;
|
|
2130
2288
|
return;
|
|
2131
2289
|
}
|
|
2290
|
+
const theme = await detectTerminalTheme();
|
|
2132
2291
|
const projects = await listProjectsUseCase.execute();
|
|
2133
2292
|
const { waitUntilExit } = render(
|
|
2134
|
-
/* @__PURE__ */ jsx7(
|
|
2293
|
+
/* @__PURE__ */ jsx7(ThemeProvider, { theme, children: /* @__PURE__ */ jsx7(
|
|
2135
2294
|
App,
|
|
2136
2295
|
{
|
|
2137
2296
|
projects,
|
|
@@ -2140,7 +2299,7 @@ var bootstrap = async () => {
|
|
|
2140
2299
|
onRefresh: () => listProjectsUseCase.execute(),
|
|
2141
2300
|
useGitRootName
|
|
2142
2301
|
}
|
|
2143
|
-
)
|
|
2302
|
+
) })
|
|
2144
2303
|
);
|
|
2145
2304
|
await waitUntilExit();
|
|
2146
2305
|
process2.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|