smithue-cli 0.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.
- package/README.md +146 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +190 -0
- package/dist/client.d.ts +37 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +184 -0
- package/dist/commands/batch.d.ts +13 -0
- package/dist/commands/batch.d.ts.map +1 -0
- package/dist/commands/batch.js +64 -0
- package/dist/commands/exec.d.ts +6 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +18 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +18 -0
- package/dist/commands/purge.d.ts +3 -0
- package/dist/commands/purge.d.ts.map +1 -0
- package/dist/commands/purge.js +154 -0
- package/dist/commands/search.d.ts +8 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +31 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +20 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +139 -0
- package/dist/output.d.ts +8 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +46 -0
- package/dist/portfile.d.ts +31 -0
- package/dist/portfile.d.ts.map +1 -0
- package/dist/portfile.js +133 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/version-check.d.ts +2 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +9 -0
- package/package.json +40 -0
package/dist/portfile.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readdir, readFile, unlink } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Error class
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export class SmithUEError extends Error {
|
|
7
|
+
exitCode;
|
|
8
|
+
constructor(message, exitCode) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.exitCode = exitCode;
|
|
11
|
+
this.name = 'SmithUEError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export function getPortfileDir() {
|
|
18
|
+
const localAppData = process.env['LOCALAPPDATA'];
|
|
19
|
+
if (!localAppData) {
|
|
20
|
+
throw new SmithUEError('LOCALAPPDATA environment variable is not set. This command requires Windows.', 2);
|
|
21
|
+
}
|
|
22
|
+
return join(localAppData, '.smithue');
|
|
23
|
+
}
|
|
24
|
+
export async function readPortfiles(dir) {
|
|
25
|
+
let entries;
|
|
26
|
+
try {
|
|
27
|
+
entries = await readdir(dir);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const portfiles = [];
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (!entry.endsWith('.port'))
|
|
35
|
+
continue;
|
|
36
|
+
const filePath = join(dir, entry);
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
39
|
+
const data = JSON.parse(raw);
|
|
40
|
+
portfiles.push({ file: filePath, data });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Ignore malformed portfiles
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return portfiles;
|
|
47
|
+
}
|
|
48
|
+
async function checkLiveness(port, filePath) {
|
|
49
|
+
try {
|
|
50
|
+
await fetch(`http://127.0.0.1:${port}/ready`, {
|
|
51
|
+
signal: AbortSignal.timeout(3000),
|
|
52
|
+
});
|
|
53
|
+
// any HTTP response = server is alive (including 503 during startup)
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// network failure = truly stale
|
|
58
|
+
try {
|
|
59
|
+
await unlink(filePath);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// best effort
|
|
63
|
+
}
|
|
64
|
+
throw new SmithUEError(`SmithUE instance on port ${port} is not responding. Stale portfile removed.`, 2);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Main export
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
export async function discoverPort(opts = {}) {
|
|
71
|
+
// 1. SMITHUE_PORT env override — skip discovery entirely
|
|
72
|
+
const envPort = process.env['SMITHUE_PORT'];
|
|
73
|
+
if (envPort) {
|
|
74
|
+
const port = parseInt(envPort, 10);
|
|
75
|
+
if (isNaN(port) || port <= 0) {
|
|
76
|
+
throw new SmithUEError(`SMITHUE_PORT is not a valid port number: "${envPort}"`, 1);
|
|
77
|
+
}
|
|
78
|
+
return { port, pid: 0, project: '', project_name: '' };
|
|
79
|
+
}
|
|
80
|
+
// 2. --port flag shortcut (already resolved by caller, treated same as env override)
|
|
81
|
+
if (opts.port !== undefined) {
|
|
82
|
+
return { port: opts.port, pid: 0, project: '', project_name: '' };
|
|
83
|
+
}
|
|
84
|
+
// 3. Determine effective PID filter (--pid > SMITHUE_PID env)
|
|
85
|
+
let pidFilter = opts.pid;
|
|
86
|
+
if (pidFilter === undefined) {
|
|
87
|
+
const envPid = process.env['SMITHUE_PID'];
|
|
88
|
+
if (envPid) {
|
|
89
|
+
const p = parseInt(envPid, 10);
|
|
90
|
+
if (!isNaN(p) && p > 0) {
|
|
91
|
+
pidFilter = p;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 4. Read all portfiles
|
|
96
|
+
const dir = getPortfileDir();
|
|
97
|
+
const all = await readPortfiles(dir);
|
|
98
|
+
if (all.length === 0) {
|
|
99
|
+
throw new SmithUEError('No SmithUE portfiles found. Is the SmithUE plugin running in Unreal Editor?', 2);
|
|
100
|
+
}
|
|
101
|
+
// 5. Apply filters
|
|
102
|
+
let candidates = all;
|
|
103
|
+
if (pidFilter !== undefined) {
|
|
104
|
+
candidates = candidates.filter((c) => c.data.pid === pidFilter);
|
|
105
|
+
if (candidates.length === 0) {
|
|
106
|
+
throw new SmithUEError(`No SmithUE instance found with PID ${pidFilter}.`, 2);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (opts.project !== undefined) {
|
|
110
|
+
// Exact absolute path comparison (M7)
|
|
111
|
+
candidates = candidates.filter((c) => c.data.project === opts.project);
|
|
112
|
+
if (candidates.length === 0) {
|
|
113
|
+
throw new SmithUEError(`No SmithUE instance found for project "${opts.project}".`, 2);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// 6. Multi-instance error (no disambiguation possible)
|
|
117
|
+
if (candidates.length > 1) {
|
|
118
|
+
const list = candidates
|
|
119
|
+
.map((c) => ` PID ${c.data.pid} ${c.data.project_name} (port ${c.data.port})`)
|
|
120
|
+
.join('\n');
|
|
121
|
+
throw new SmithUEError(`Multiple SmithUE instances are running. Use --pid or --project to select one:\n${list}`, 1);
|
|
122
|
+
}
|
|
123
|
+
// 7. Single candidate — liveness check
|
|
124
|
+
const { file, data } = candidates[0];
|
|
125
|
+
await checkLiveness(data.port, file);
|
|
126
|
+
return {
|
|
127
|
+
port: data.port,
|
|
128
|
+
pid: data.pid,
|
|
129
|
+
project: data.project,
|
|
130
|
+
project_name: data.project_name,
|
|
131
|
+
plugin_version: data.plugin_version,
|
|
132
|
+
};
|
|
133
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface SmithUEToolParam {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
description: string;
|
|
5
|
+
required: boolean;
|
|
6
|
+
default?: string;
|
|
7
|
+
itemsType?: string;
|
|
8
|
+
allowedValues?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface SmithUEToolSchema {
|
|
11
|
+
name: string;
|
|
12
|
+
category: string;
|
|
13
|
+
description: string;
|
|
14
|
+
params: SmithUEToolParam[];
|
|
15
|
+
}
|
|
16
|
+
export interface SmithUEListToolsResponse {
|
|
17
|
+
status: 'success' | 'error';
|
|
18
|
+
data: {
|
|
19
|
+
protocol_version: string;
|
|
20
|
+
tools: SmithUEToolSchema[];
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface SmithUEExecuteResponse {
|
|
24
|
+
status: 'success' | 'error';
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
error?: string;
|
|
27
|
+
error_code?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SmithUEClientConfig {
|
|
30
|
+
host: string;
|
|
31
|
+
port: number;
|
|
32
|
+
timeout: number;
|
|
33
|
+
}
|
|
34
|
+
export interface PurgeOptions {
|
|
35
|
+
force: boolean;
|
|
36
|
+
dryRun: boolean;
|
|
37
|
+
yes: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface PurgeResult {
|
|
40
|
+
status: 'purged' | 'nothing_to_purge' | 'partial' | 'cancelled' | 'dry_run';
|
|
41
|
+
path: string;
|
|
42
|
+
scanned: number;
|
|
43
|
+
deleted: number;
|
|
44
|
+
skipped_live: number;
|
|
45
|
+
failed: number;
|
|
46
|
+
directory_removed: boolean;
|
|
47
|
+
errors: string[];
|
|
48
|
+
warnings: string[];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,IAAI,EAAE;QACJ,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,iBAAiB,EAAE,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,QAAQ,GAAG,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-check.d.ts","sourceRoot":"","sources":["../src/version-check.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAW9F"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function checkVersionCompat(cliVersion, pluginVersion) {
|
|
2
|
+
if (!pluginVersion)
|
|
3
|
+
return;
|
|
4
|
+
const [cliMajor, cliMinor] = cliVersion.split('.');
|
|
5
|
+
const [pluginMajor, pluginMinor] = pluginVersion.split('.');
|
|
6
|
+
if (cliMajor !== pluginMajor || cliMinor !== pluginMinor) {
|
|
7
|
+
process.stderr.write(`Warning: smithue-cli version ${cliVersion} does not match plugin version ${pluginVersion}. Run "smithue-cli upgrade" to update.\n`);
|
|
8
|
+
}
|
|
9
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "smithue-cli",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc -p tsconfig.build.json",
|
|
8
|
+
"test": "vitest run",
|
|
9
|
+
"typecheck": "tsc --noEmit",
|
|
10
|
+
"dev": "tsc -p tsconfig.build.json --watch"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/",
|
|
14
|
+
"package.json",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^20.0.0",
|
|
19
|
+
"typescript": "^5.3.0",
|
|
20
|
+
"vitest": "^1.0.0"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"commander": "^15.0.0"
|
|
24
|
+
},
|
|
25
|
+
"bin": {
|
|
26
|
+
"smithue-cli": "./dist/cli.js"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": "\u003e=18"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"description": "CLI tool for controlling Unreal Engine editor via SmithUE plugin",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/123dx-svg/smithue-cli.git"
|
|
39
|
+
}
|
|
40
|
+
}
|