unity-hub-cli 0.17.0 → 0.18.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/README.md +40 -1
- package/dist/index.js +234 -32
- package/package.json +31 -18
package/README.md
CHANGED
|
@@ -58,14 +58,53 @@ The display includes Git branch (if present), Unity version, project path, and l
|
|
|
58
58
|
## CLI Options
|
|
59
59
|
|
|
60
60
|
- `--no-git-root-name`: Display Unity project titles instead of Git repository root folder names.
|
|
61
|
+
- `--shell-init`: Install shell function for automatic `cd` integration (with confirmation prompt).
|
|
62
|
+
- `--shell-init --dry-run`: Preview the shell function without installing.
|
|
63
|
+
|
|
64
|
+
## Shell Integration
|
|
65
|
+
|
|
66
|
+
You can add a shell function to automatically `cd` to the project directory after opening Unity.
|
|
67
|
+
|
|
68
|
+
### Setup
|
|
69
|
+
|
|
70
|
+
1. Install globally:
|
|
71
|
+
```bash
|
|
72
|
+
npm install -g unity-hub-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. Run the shell init command (auto-detects your shell):
|
|
76
|
+
```bash
|
|
77
|
+
unity-hub-cli --shell-init
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This automatically adds the `unity-hub` function to your shell config file (`.zshrc`, `.bashrc`, `config.fish`, or PowerShell profile).
|
|
81
|
+
|
|
82
|
+
3. Reload your shell:
|
|
83
|
+
```bash
|
|
84
|
+
source ~/.zshrc # or restart your terminal
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Usage
|
|
88
|
+
|
|
89
|
+
Now you can use `unity-hub` to:
|
|
90
|
+
1. Browse and select Unity projects
|
|
91
|
+
2. Press `o` to launch Unity
|
|
92
|
+
3. Your terminal automatically `cd`s to the project directory
|
|
93
|
+
|
|
94
|
+
### Notes
|
|
95
|
+
|
|
96
|
+
- Running `--shell-init` multiple times is safe - it updates the existing function using marker comments
|
|
97
|
+
- The function uses absolute paths detected from your environment
|
|
98
|
+
- **Windows**: Shell integration supports PowerShell only. CMD is not supported because it lacks shell functions required for automatic `cd` after launching Unity
|
|
61
99
|
|
|
62
100
|
## Security
|
|
63
101
|
|
|
64
102
|
This project implements supply chain attack prevention measures:
|
|
65
103
|
|
|
66
104
|
- **ignore-scripts**: Disables automatic script execution during `npm install`
|
|
105
|
+
- **@lavamoat/allow-scripts**: Explicitly controls which packages can run install scripts
|
|
67
106
|
- **Dependabot**: Automated weekly security updates
|
|
68
|
-
- **Security audit CI**: Runs `npm audit
|
|
107
|
+
- **Security audit CI**: Runs `npm audit`, `lockfile-lint`, and OSV-Scanner on every PR
|
|
69
108
|
- **Pinned versions**: All dependencies use exact versions (no `^` or `~`)
|
|
70
109
|
|
|
71
110
|
## License
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.tsx
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
4
8
|
import process3 from "process";
|
|
9
|
+
import { createInterface as createInterface2 } from "readline";
|
|
10
|
+
import chalk from "chalk";
|
|
5
11
|
import { render } from "ink";
|
|
6
12
|
|
|
7
13
|
// src/application/usecases.ts
|
|
@@ -1332,7 +1338,7 @@ var WinUnityProcessTerminator = class {
|
|
|
1332
1338
|
],
|
|
1333
1339
|
{ env: getMsysDisabledEnv() }
|
|
1334
1340
|
);
|
|
1335
|
-
} catch
|
|
1341
|
+
} catch {
|
|
1336
1342
|
if (!ensureProcessAlive2(unityProcess.pid)) {
|
|
1337
1343
|
return { terminated: true, stage: "sigterm" };
|
|
1338
1344
|
}
|
|
@@ -1358,7 +1364,7 @@ var WinUnityProcessTerminator = class {
|
|
|
1358
1364
|
],
|
|
1359
1365
|
{ env: getMsysDisabledEnv() }
|
|
1360
1366
|
);
|
|
1361
|
-
} catch
|
|
1367
|
+
} catch {
|
|
1362
1368
|
if (!ensureProcessAlive2(unityProcess.pid)) {
|
|
1363
1369
|
return { terminated: true, stage: "sigkill" };
|
|
1364
1370
|
}
|
|
@@ -1999,7 +2005,9 @@ var App = ({
|
|
|
1999
2005
|
onLaunchEditorOnly,
|
|
2000
2006
|
onTerminate,
|
|
2001
2007
|
onRefresh,
|
|
2002
|
-
useGitRootName = true
|
|
2008
|
+
useGitRootName = true,
|
|
2009
|
+
outputPathOnExit = false,
|
|
2010
|
+
onSetExitPath
|
|
2003
2011
|
}) => {
|
|
2004
2012
|
const { exit } = useApp();
|
|
2005
2013
|
const { stdout } = useStdout2();
|
|
@@ -2196,20 +2204,14 @@ var App = ({
|
|
|
2196
2204
|
return;
|
|
2197
2205
|
}
|
|
2198
2206
|
const { project } = projectView;
|
|
2199
|
-
|
|
2200
|
-
const cdTarget = getCopyTargetPath(projectView);
|
|
2201
|
-
const command = buildCdCommand(cdTarget);
|
|
2202
|
-
clipboard.writeSync(command);
|
|
2203
|
-
} catch (error) {
|
|
2204
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2205
|
-
setHint(`Failed to copy: ${message}`);
|
|
2206
|
-
setTimeout(() => {
|
|
2207
|
-
setHint(defaultHintMessage);
|
|
2208
|
-
}, 3e3);
|
|
2209
|
-
return;
|
|
2210
|
-
}
|
|
2207
|
+
const cdTarget = getCopyTargetPath(projectView);
|
|
2211
2208
|
try {
|
|
2212
2209
|
await onLaunch(project);
|
|
2210
|
+
if (outputPathOnExit) {
|
|
2211
|
+
onSetExitPath?.(cdTarget);
|
|
2212
|
+
exit();
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2213
2215
|
setLaunchedProjects((previous) => {
|
|
2214
2216
|
const next = new Set(previous);
|
|
2215
2217
|
next.add(project.id);
|
|
@@ -2229,6 +2231,11 @@ var App = ({
|
|
|
2229
2231
|
}, 3e3);
|
|
2230
2232
|
} catch (error) {
|
|
2231
2233
|
if (error instanceof LaunchCancelledError) {
|
|
2234
|
+
if (outputPathOnExit) {
|
|
2235
|
+
onSetExitPath?.(cdTarget);
|
|
2236
|
+
exit();
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2232
2239
|
setHint("Launch cancelled");
|
|
2233
2240
|
setTimeout(() => {
|
|
2234
2241
|
setHint(defaultHintMessage);
|
|
@@ -2241,7 +2248,7 @@ var App = ({
|
|
|
2241
2248
|
setHint(defaultHintMessage);
|
|
2242
2249
|
}, 3e3);
|
|
2243
2250
|
}
|
|
2244
|
-
}, [index, onLaunch, sortedProjects]);
|
|
2251
|
+
}, [exit, index, onLaunch, onSetExitPath, outputPathOnExit, sortedProjects]);
|
|
2245
2252
|
const launchSelectedWithEditor = useCallback(async () => {
|
|
2246
2253
|
if (!onLaunchWithEditor) {
|
|
2247
2254
|
setHint("Launch with editor not available");
|
|
@@ -2259,20 +2266,14 @@ var App = ({
|
|
|
2259
2266
|
return;
|
|
2260
2267
|
}
|
|
2261
2268
|
const { project } = projectView;
|
|
2262
|
-
|
|
2263
|
-
const cdTarget = getCopyTargetPath(projectView);
|
|
2264
|
-
const command = buildCdCommand(cdTarget);
|
|
2265
|
-
clipboard.writeSync(command);
|
|
2266
|
-
} catch (error) {
|
|
2267
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2268
|
-
setHint(`Failed to copy: ${message}`);
|
|
2269
|
-
setTimeout(() => {
|
|
2270
|
-
setHint(defaultHintMessage);
|
|
2271
|
-
}, 3e3);
|
|
2272
|
-
return;
|
|
2273
|
-
}
|
|
2269
|
+
const cdTarget = getCopyTargetPath(projectView);
|
|
2274
2270
|
try {
|
|
2275
2271
|
const result = await onLaunchWithEditor(project);
|
|
2272
|
+
if (outputPathOnExit) {
|
|
2273
|
+
onSetExitPath?.(cdTarget);
|
|
2274
|
+
exit();
|
|
2275
|
+
return;
|
|
2276
|
+
}
|
|
2276
2277
|
setLaunchedProjects((previous) => {
|
|
2277
2278
|
const next = new Set(previous);
|
|
2278
2279
|
next.add(project.id);
|
|
@@ -2292,6 +2293,11 @@ var App = ({
|
|
|
2292
2293
|
}, 3e3);
|
|
2293
2294
|
} catch (error) {
|
|
2294
2295
|
if (error instanceof LaunchCancelledError) {
|
|
2296
|
+
if (outputPathOnExit) {
|
|
2297
|
+
onSetExitPath?.(cdTarget);
|
|
2298
|
+
exit();
|
|
2299
|
+
return;
|
|
2300
|
+
}
|
|
2295
2301
|
setHint("Launch cancelled");
|
|
2296
2302
|
setTimeout(() => {
|
|
2297
2303
|
setHint(defaultHintMessage);
|
|
@@ -2304,7 +2310,7 @@ var App = ({
|
|
|
2304
2310
|
setHint(defaultHintMessage);
|
|
2305
2311
|
}, 3e3);
|
|
2306
2312
|
}
|
|
2307
|
-
}, [index, onLaunchWithEditor, sortedProjects]);
|
|
2313
|
+
}, [exit, index, onLaunchWithEditor, onSetExitPath, outputPathOnExit, sortedProjects]);
|
|
2308
2314
|
const launchEditorOnly = useCallback(async () => {
|
|
2309
2315
|
if (!onLaunchEditorOnly) {
|
|
2310
2316
|
setHint("Launch editor only not available");
|
|
@@ -2634,7 +2640,186 @@ var App = ({
|
|
|
2634
2640
|
|
|
2635
2641
|
// src/index.tsx
|
|
2636
2642
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2643
|
+
var SHELL_INIT_MARKER_START = "# >>> unity-hub-cli >>>";
|
|
2644
|
+
var SHELL_INIT_MARKER_END = "# <<< unity-hub-cli <<<";
|
|
2645
|
+
var getShellConfigPath = () => {
|
|
2646
|
+
const shell = process3.env["SHELL"] ?? "";
|
|
2647
|
+
const home = homedir();
|
|
2648
|
+
if (shell.includes("zsh")) {
|
|
2649
|
+
return join9(home, ".zshrc");
|
|
2650
|
+
}
|
|
2651
|
+
if (shell.includes("bash")) {
|
|
2652
|
+
const bashrcPath = join9(home, ".bashrc");
|
|
2653
|
+
const profilePath = join9(home, ".bash_profile");
|
|
2654
|
+
return existsSync3(bashrcPath) ? bashrcPath : profilePath;
|
|
2655
|
+
}
|
|
2656
|
+
if (shell.includes("fish")) {
|
|
2657
|
+
return join9(home, ".config", "fish", "config.fish");
|
|
2658
|
+
}
|
|
2659
|
+
if (process3.platform === "win32") {
|
|
2660
|
+
return join9(home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
2661
|
+
}
|
|
2662
|
+
return void 0;
|
|
2663
|
+
};
|
|
2664
|
+
var getShellInitScriptWithMarkers = () => {
|
|
2665
|
+
const script = getShellInitScript();
|
|
2666
|
+
return `${SHELL_INIT_MARKER_START}
|
|
2667
|
+
${script}
|
|
2668
|
+
${SHELL_INIT_MARKER_END}`;
|
|
2669
|
+
};
|
|
2670
|
+
var askConfirmation = (question) => {
|
|
2671
|
+
const rl = createInterface2({
|
|
2672
|
+
input: process3.stdin,
|
|
2673
|
+
output: process3.stdout
|
|
2674
|
+
});
|
|
2675
|
+
return new Promise((resolve4) => {
|
|
2676
|
+
rl.question(question, (answer) => {
|
|
2677
|
+
rl.close();
|
|
2678
|
+
resolve4(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
2679
|
+
});
|
|
2680
|
+
});
|
|
2681
|
+
};
|
|
2682
|
+
var previewShellInit = () => {
|
|
2683
|
+
const configPath = getShellConfigPath();
|
|
2684
|
+
console.log("=== Shell Integration Preview ===\n");
|
|
2685
|
+
console.log(`Target file: ${configPath ?? "Unknown (unsupported shell)"}
|
|
2686
|
+
`);
|
|
2687
|
+
console.log("Content to be added:\n");
|
|
2688
|
+
console.log(getShellInitScriptWithMarkers());
|
|
2689
|
+
};
|
|
2690
|
+
var installShellInit = () => {
|
|
2691
|
+
const configPath = getShellConfigPath();
|
|
2692
|
+
if (!configPath) {
|
|
2693
|
+
return { success: false, message: "Unsupported shell. Please copy the function from the README into your shell config manually." };
|
|
2694
|
+
}
|
|
2695
|
+
const scriptWithMarkers = getShellInitScriptWithMarkers();
|
|
2696
|
+
const markerPattern = new RegExp(
|
|
2697
|
+
`${SHELL_INIT_MARKER_START}[\\s\\S]*?${SHELL_INIT_MARKER_END}`,
|
|
2698
|
+
"g"
|
|
2699
|
+
);
|
|
2700
|
+
let content = "";
|
|
2701
|
+
if (existsSync3(configPath)) {
|
|
2702
|
+
content = readFileSync(configPath, "utf-8");
|
|
2703
|
+
}
|
|
2704
|
+
const existingMatch = content.match(markerPattern);
|
|
2705
|
+
if (existingMatch && existingMatch[0] === scriptWithMarkers) {
|
|
2706
|
+
return { success: true, message: `Shell integration is already up to date in ${configPath}` };
|
|
2707
|
+
}
|
|
2708
|
+
let newContent;
|
|
2709
|
+
let action;
|
|
2710
|
+
if (existingMatch) {
|
|
2711
|
+
newContent = content.replace(markerPattern, scriptWithMarkers);
|
|
2712
|
+
action = "updated";
|
|
2713
|
+
} else {
|
|
2714
|
+
newContent = content.trimEnd() + "\n\n" + scriptWithMarkers + "\n";
|
|
2715
|
+
action = "installed";
|
|
2716
|
+
}
|
|
2717
|
+
mkdirSync(dirname2(configPath), { recursive: true });
|
|
2718
|
+
writeFileSync(configPath, newContent, "utf-8");
|
|
2719
|
+
return { success: true, message: `Shell integration ${action} in ${configPath}` };
|
|
2720
|
+
};
|
|
2721
|
+
var getNodePath = () => {
|
|
2722
|
+
const isWindows = process3.platform === "win32";
|
|
2723
|
+
const command = isWindows ? "where node" : "which node";
|
|
2724
|
+
try {
|
|
2725
|
+
const result = execSync(command, { encoding: "utf-8" }).trim().split("\n")[0];
|
|
2726
|
+
if (result && existsSync3(result)) {
|
|
2727
|
+
return result;
|
|
2728
|
+
}
|
|
2729
|
+
} catch {
|
|
2730
|
+
}
|
|
2731
|
+
return "node";
|
|
2732
|
+
};
|
|
2733
|
+
var getUnityHubCliPath = () => {
|
|
2734
|
+
const isWindows = process3.platform === "win32";
|
|
2735
|
+
try {
|
|
2736
|
+
const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
|
|
2737
|
+
const binDir = isWindows ? prefix : `${prefix}/bin`;
|
|
2738
|
+
const cliPath = isWindows ? `${binDir}/unity-hub-cli.cmd` : `${binDir}/unity-hub-cli`;
|
|
2739
|
+
if (existsSync3(cliPath)) {
|
|
2740
|
+
return cliPath;
|
|
2741
|
+
}
|
|
2742
|
+
} catch {
|
|
2743
|
+
}
|
|
2744
|
+
return "unity-hub-cli";
|
|
2745
|
+
};
|
|
2746
|
+
var getShellInitScript = () => {
|
|
2747
|
+
const shell = process3.env["SHELL"] ?? "";
|
|
2748
|
+
const isWindows = process3.platform === "win32";
|
|
2749
|
+
const nodePath = getNodePath();
|
|
2750
|
+
const cliPath = getUnityHubCliPath();
|
|
2751
|
+
if (shell.includes("fish")) {
|
|
2752
|
+
return `function unity-hub
|
|
2753
|
+
set -l tmpfile (mktemp)
|
|
2754
|
+
${nodePath} ${cliPath} --output-path-on-exit > $tmpfile
|
|
2755
|
+
set -l dir (cat $tmpfile)
|
|
2756
|
+
rm -f $tmpfile
|
|
2757
|
+
if test -n "$dir"
|
|
2758
|
+
cd $dir
|
|
2759
|
+
end
|
|
2760
|
+
end`;
|
|
2761
|
+
}
|
|
2762
|
+
if (shell.includes("bash") || shell.includes("zsh")) {
|
|
2763
|
+
return `unity-hub() {
|
|
2764
|
+
local tmpfile=$(mktemp)
|
|
2765
|
+
${nodePath} ${cliPath} --output-path-on-exit >| "$tmpfile"
|
|
2766
|
+
local dir=$(cat "$tmpfile")
|
|
2767
|
+
rm -f "$tmpfile"
|
|
2768
|
+
if [ -n "$dir" ]; then
|
|
2769
|
+
cd "$dir"
|
|
2770
|
+
fi
|
|
2771
|
+
}`;
|
|
2772
|
+
}
|
|
2773
|
+
if (isWindows) {
|
|
2774
|
+
return `function unity-hub {
|
|
2775
|
+
$tmpfile = [System.IO.Path]::GetTempFileName()
|
|
2776
|
+
& "${cliPath}" --output-path-on-exit > $tmpfile
|
|
2777
|
+
$dir = Get-Content $tmpfile
|
|
2778
|
+
Remove-Item $tmpfile
|
|
2779
|
+
if ($dir) {
|
|
2780
|
+
Set-Location $dir
|
|
2781
|
+
}
|
|
2782
|
+
}`;
|
|
2783
|
+
}
|
|
2784
|
+
return `unity-hub() {
|
|
2785
|
+
local tmpfile=$(mktemp)
|
|
2786
|
+
${nodePath} ${cliPath} --output-path-on-exit >| "$tmpfile"
|
|
2787
|
+
local dir=$(cat "$tmpfile")
|
|
2788
|
+
rm -f "$tmpfile"
|
|
2789
|
+
if [ -n "$dir" ]; then
|
|
2790
|
+
cd "$dir"
|
|
2791
|
+
fi
|
|
2792
|
+
}`;
|
|
2793
|
+
};
|
|
2637
2794
|
var bootstrap = async () => {
|
|
2795
|
+
const args = process3.argv.slice(2);
|
|
2796
|
+
if (args.includes("--shell-init")) {
|
|
2797
|
+
const isDryRun = args.includes("--dry-run");
|
|
2798
|
+
if (isDryRun) {
|
|
2799
|
+
previewShellInit();
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
const configPath = getShellConfigPath();
|
|
2803
|
+
if (!configPath) {
|
|
2804
|
+
console.log("Unsupported shell. Please copy the function from the README into your shell config manually.");
|
|
2805
|
+
process3.exitCode = 1;
|
|
2806
|
+
return;
|
|
2807
|
+
}
|
|
2808
|
+
console.log(`This will install the unity-hub function to: ${configPath}
|
|
2809
|
+
`);
|
|
2810
|
+
previewShellInit();
|
|
2811
|
+
console.log("");
|
|
2812
|
+
const confirmed = await askConfirmation("Proceed with installation? (y/n): ");
|
|
2813
|
+
if (!confirmed) {
|
|
2814
|
+
console.log("Installation cancelled.");
|
|
2815
|
+
return;
|
|
2816
|
+
}
|
|
2817
|
+
const result = installShellInit();
|
|
2818
|
+
console.log(result.message);
|
|
2819
|
+
process3.exitCode = result.success ? 0 : 1;
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
const outputPathOnExit = args.includes("--output-path-on-exit");
|
|
2638
2823
|
const isWindows = process3.platform === "win32";
|
|
2639
2824
|
const unityHubReader = isWindows ? new WinUnityHubProjectsReader() : new MacUnityHubProjectsReader();
|
|
2640
2825
|
const gitRepositoryInfoReader = new GitRepositoryInfoReader();
|
|
@@ -2694,8 +2879,13 @@ var bootstrap = async () => {
|
|
|
2694
2879
|
process3.exitCode = 1;
|
|
2695
2880
|
return;
|
|
2696
2881
|
}
|
|
2882
|
+
if (outputPathOnExit && process3.stderr.isTTY) {
|
|
2883
|
+
chalk.level = 3;
|
|
2884
|
+
}
|
|
2697
2885
|
const theme = await detectTerminalTheme();
|
|
2886
|
+
let lastOpenedPath;
|
|
2698
2887
|
const projects = await listProjectsUseCase.execute();
|
|
2888
|
+
const renderOptions = outputPathOnExit ? { stdout: process3.stderr, stdin: process3.stdin } : void 0;
|
|
2699
2889
|
const { waitUntilExit } = render(
|
|
2700
2890
|
/* @__PURE__ */ jsx7(ThemeProvider, { theme, children: /* @__PURE__ */ jsx7(
|
|
2701
2891
|
App,
|
|
@@ -2706,12 +2896,24 @@ var bootstrap = async () => {
|
|
|
2706
2896
|
onLaunchEditorOnly: (project) => launchEditorOnlyUseCase.execute(project),
|
|
2707
2897
|
onTerminate: (project) => terminateProjectUseCase.execute(project),
|
|
2708
2898
|
onRefresh: () => listProjectsUseCase.execute(),
|
|
2709
|
-
useGitRootName
|
|
2899
|
+
useGitRootName,
|
|
2900
|
+
outputPathOnExit,
|
|
2901
|
+
onSetExitPath: (path) => {
|
|
2902
|
+
lastOpenedPath = path;
|
|
2903
|
+
}
|
|
2710
2904
|
}
|
|
2711
|
-
) })
|
|
2905
|
+
) }),
|
|
2906
|
+
renderOptions
|
|
2712
2907
|
);
|
|
2713
2908
|
await waitUntilExit();
|
|
2714
|
-
|
|
2909
|
+
if (outputPathOnExit) {
|
|
2910
|
+
process3.stderr.write("\x1B[2J\x1B[3J\x1B[H");
|
|
2911
|
+
if (lastOpenedPath) {
|
|
2912
|
+
process3.stdout.write(lastOpenedPath);
|
|
2913
|
+
}
|
|
2914
|
+
} else {
|
|
2915
|
+
process3.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
2916
|
+
}
|
|
2715
2917
|
} catch (error) {
|
|
2716
2918
|
const message = error instanceof Error ? error.message : String(error);
|
|
2717
2919
|
console.error(message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unity-hub-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A CLI tool that reads Unity Hub's projects and launches Unity Editor with an interactive TUI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
"dev": "tsx src/index.ts",
|
|
9
9
|
"build": "tsup",
|
|
10
10
|
"start": "node dist/index.js",
|
|
11
|
-
"lint": "eslint .
|
|
12
|
-
"lint:fix": "eslint . --
|
|
11
|
+
"lint": "eslint .",
|
|
12
|
+
"lint:fix": "eslint . --fix",
|
|
13
13
|
"format": "prettier --write .",
|
|
14
|
-
"typecheck": "tsc -noEmit"
|
|
14
|
+
"typecheck": "tsc -noEmit",
|
|
15
|
+
"allow-scripts": "allow-scripts"
|
|
15
16
|
},
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
@@ -36,26 +37,38 @@
|
|
|
36
37
|
"dist"
|
|
37
38
|
],
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
40
|
+
"chalk": "5.6.2",
|
|
41
|
+
"clipboardy": "5.0.1",
|
|
42
|
+
"ink": "6.5.1",
|
|
43
|
+
"react": "19.2.1"
|
|
42
44
|
},
|
|
43
45
|
"engines": {
|
|
44
46
|
"node": ">=18"
|
|
45
47
|
},
|
|
48
|
+
"lavamoat": {
|
|
49
|
+
"allowScripts": {
|
|
50
|
+
"eslint-import-resolver-typescript>unrs-resolver": false,
|
|
51
|
+
"tsup>bundle-require>esbuild": false,
|
|
52
|
+
"tsup>esbuild": false,
|
|
53
|
+
"tsx>esbuild": false
|
|
54
|
+
}
|
|
55
|
+
},
|
|
46
56
|
"devDependencies": {
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"eslint": "8.
|
|
52
|
-
"eslint
|
|
53
|
-
"eslint
|
|
57
|
+
"@eslint/js": "^9.39.1",
|
|
58
|
+
"@lavamoat/allow-scripts": "3.4.1",
|
|
59
|
+
"@types/node": "24.10.1",
|
|
60
|
+
"@types/react": "19.2.7",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "8.48.1",
|
|
62
|
+
"@typescript-eslint/parser": "8.48.1",
|
|
63
|
+
"eslint": "9.39.1",
|
|
64
|
+
"eslint-config-prettier": "10.1.8",
|
|
65
|
+
"eslint-import-resolver-typescript": "4.4.4",
|
|
54
66
|
"eslint-plugin-import": "2.32.0",
|
|
55
|
-
"prettier": "3.
|
|
56
|
-
"tsup": "8.5.
|
|
57
|
-
"tsx": "4.
|
|
67
|
+
"prettier": "3.7.3",
|
|
68
|
+
"tsup": "8.5.1",
|
|
69
|
+
"tsx": "4.21.0",
|
|
58
70
|
"typescript": "5.9.3",
|
|
59
|
-
"
|
|
71
|
+
"typescript-eslint": "^8.48.1",
|
|
72
|
+
"vitest": "4.0.15"
|
|
60
73
|
}
|
|
61
74
|
}
|