godot-cli 0.2.0 → 0.4.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/commands/create-project.d.ts +2 -0
- package/dist/commands/create-project.js +49 -0
- package/dist/commands/create-project.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/create-project.d.ts +88 -0
- package/dist/lib/create-project.js +314 -0
- package/dist/lib/create-project.js.map +1 -0
- package/dist/lib/types.d.ts +45 -0
- package/dist/lib.d.ts +2 -1
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as ui from '../utils/ui.js';
|
|
4
|
+
import { verbose } from '../utils/ui.js';
|
|
5
|
+
import { createProject } from '../lib/create-project.js';
|
|
6
|
+
export const createProjectCommand = new Command('create-project')
|
|
7
|
+
.description('Scaffold a minimal valid Godot 4.x project (project.godot + icon.svg). Pass --dotnet to also scaffold a Godot.NET.Sdk (C#) csproj. Refuses to overwrite an existing Godot/Unity/Unreal project.')
|
|
8
|
+
.argument('[path]', 'Target directory to scaffold the project into (defaults to current directory)')
|
|
9
|
+
.option('--path <path>', 'Target directory to scaffold the project into')
|
|
10
|
+
.option('--name <name>', 'Project name (defaults to a name derived from the folder name)')
|
|
11
|
+
.option('--dotnet', 'Also scaffold a Godot.NET.Sdk (C#) csproj')
|
|
12
|
+
.action(async (positionalPath, options) => {
|
|
13
|
+
const resolvedPath = positionalPath ?? options.path ?? process.cwd();
|
|
14
|
+
const projectPath = path.resolve(resolvedPath);
|
|
15
|
+
ui.heading('Creating Godot project');
|
|
16
|
+
verbose(`Target path: ${projectPath}`);
|
|
17
|
+
verbose(`--dotnet: ${options.dotnet === true}`);
|
|
18
|
+
const spinner = ui.startSpinner('Scaffolding project...');
|
|
19
|
+
const result = await createProject({
|
|
20
|
+
projectPath,
|
|
21
|
+
name: options.name,
|
|
22
|
+
dotnet: options.dotnet === true,
|
|
23
|
+
});
|
|
24
|
+
if (result.kind === 'failure') {
|
|
25
|
+
spinner.error('Failed to create project');
|
|
26
|
+
ui.error(result.errorMessage);
|
|
27
|
+
// Surface failure-shape diagnostics BEFORE exiting: leftover files a
|
|
28
|
+
// partial rollback could not remove, plus any rollback warnings.
|
|
29
|
+
if (result.filesWritten.length > 0) {
|
|
30
|
+
ui.label('Files left behind (cleanup failed)', result.filesWritten.join(', '));
|
|
31
|
+
}
|
|
32
|
+
for (const warning of result.warnings) {
|
|
33
|
+
console.log('');
|
|
34
|
+
ui.warn(warning);
|
|
35
|
+
}
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
spinner.success(`Created Godot project "${result.projectName}"`);
|
|
39
|
+
ui.label('Project path', result.projectPath);
|
|
40
|
+
ui.label('Files written', result.filesWritten.join(', '));
|
|
41
|
+
if (result.dotnet) {
|
|
42
|
+
ui.label('C# (.NET)', 'enabled');
|
|
43
|
+
}
|
|
44
|
+
for (const warning of result.warnings) {
|
|
45
|
+
console.log('');
|
|
46
|
+
ui.warn(warning);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=create-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-project.js","sourceRoot":"","sources":["../../src/commands/create-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAQzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC;KAC9D,WAAW,CACV,iMAAiM,CAClM;KACA,QAAQ,CAAC,QAAQ,EAAE,+EAA+E,CAAC;KACnG,MAAM,CAAC,eAAe,EAAE,+CAA+C,CAAC;KACxE,MAAM,CAAC,eAAe,EAAE,gEAAgE,CAAC;KACzF,MAAM,CAAC,UAAU,EAAE,2CAA2C,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,cAAkC,EAAE,OAAgC,EAAE,EAAE;IACrF,MAAM,YAAY,GAAG,cAAc,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACrE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/C,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACrC,OAAO,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,aAAa,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAEhD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;QACjC,WAAW;QACX,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;KAChC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1C,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC9B,qEAAqE;QACrE,iEAAiE;QACjE,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,KAAK,CAAC,oCAAoC,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjF,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,0BAA0B,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;IACjE,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC7C,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { statusCommand } from './commands/status.js';
|
|
|
7
7
|
import { waitForReadyCommand } from './commands/wait-for-ready.js';
|
|
8
8
|
import { setupMcpCommand } from './commands/setup-mcp.js';
|
|
9
9
|
import { configureCommand } from './commands/configure.js';
|
|
10
|
+
import { createProjectCommand } from './commands/create-project.js';
|
|
10
11
|
import { closeCommand } from './commands/close.js';
|
|
11
12
|
import { createUpdateCommand } from './commands/update.js';
|
|
12
13
|
import { installPluginCommand } from './commands/install-plugin.js';
|
|
@@ -25,6 +26,7 @@ program
|
|
|
25
26
|
const subcommands = [
|
|
26
27
|
closeCommand,
|
|
27
28
|
configureCommand,
|
|
29
|
+
createProjectCommand,
|
|
28
30
|
installPluginCommand,
|
|
29
31
|
openCommand,
|
|
30
32
|
removePluginCommand,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { CreateProjectOptions, CreateProjectResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `Godot.NET.Sdk` version pinned into a scaffolded `--dotnet` csproj. Matches
|
|
4
|
+
* the addon's own min-version floor (`Godot-MCP.csproj` pins `4.3.0`) and the
|
|
5
|
+
* `config/features` "4.3" floor written into `project.godot`. A consumer can
|
|
6
|
+
* bump this to their editor version freely; the scaffold targets the floor so
|
|
7
|
+
* the generated project opens in any Godot 4.3+ editor.
|
|
8
|
+
*/
|
|
9
|
+
export declare const GODOT_SDK_VERSION = "4.3.0";
|
|
10
|
+
/**
|
|
11
|
+
* Default `icon.svg` written into a scaffolded project — a self-contained,
|
|
12
|
+
* valid SVG using Godot's signature rounded-rect blue background. Mirrors the
|
|
13
|
+
* shape of the icon Godot writes for a fresh project (the exact glyph differs;
|
|
14
|
+
* what matters is a valid default icon the editor can load at `res://icon.svg`).
|
|
15
|
+
*/
|
|
16
|
+
export declare const DEFAULT_ICON_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"128\" height=\"128\" viewBox=\"0 0 128 128\">\n <rect width=\"124\" height=\"124\" x=\"2\" y=\"2\" fill=\"#363d52\" stroke=\"#212532\" stroke-width=\"4\" rx=\"14\"/>\n <g fill=\"#fff\">\n <circle cx=\"48\" cy=\"58\" r=\"10\"/>\n <circle cx=\"80\" cy=\"58\" r=\"10\"/>\n <rect x=\"40\" y=\"82\" width=\"48\" height=\"8\" rx=\"4\"/>\n </g>\n</svg>\n";
|
|
17
|
+
/** Engine project marker detected when refusing to scaffold over an existing project. */
|
|
18
|
+
export type ProjectMarkerEngine = 'godot' | 'unity' | 'unreal';
|
|
19
|
+
/**
|
|
20
|
+
* Derive the project name from an explicit option, falling back to the target
|
|
21
|
+
* folder's base name. Returns `GodotProject` only when both are empty. Pure.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deriveProjectName(projectPath: string, explicitName?: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* The `[dotnet] project/assembly_name` value AND the csproj filename. Godot
|
|
26
|
+
* itself permits hyphens here (the infra testbed uses `Godot-Test-Project`), so
|
|
27
|
+
* the name is kept verbatim apart from trimming; falls back when empty. Pure.
|
|
28
|
+
*/
|
|
29
|
+
export declare function toAssemblyName(projectName: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* The csproj `<RootNamespace>` — must be a valid C# identifier, so every char
|
|
32
|
+
* that is not a letter/digit/underscore is stripped and a leading digit is
|
|
33
|
+
* prefixed with `_`. Mirrors the testbed's `Godot-Test-Project` ->
|
|
34
|
+
* `GodotTestProject` derivation. Pure.
|
|
35
|
+
*/
|
|
36
|
+
export declare function toRootNamespace(projectName: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Escape a string for embedding inside a double-quoted Godot `ConfigFile`
|
|
39
|
+
* value (the `project.godot` format): backslash -> `\\` and double-quote ->
|
|
40
|
+
* `\"`. Without this, a name containing `"` or `\` produces a `project.godot`
|
|
41
|
+
* Godot cannot parse — or, worse, lets a crafted name inject arbitrary config
|
|
42
|
+
* keys. Pure. Exported for unit tests.
|
|
43
|
+
*/
|
|
44
|
+
export declare function escapeGodotConfigString(value: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Validate a project name before any filesystem write. Rejected when the name
|
|
47
|
+
* would corrupt the generated `project.godot` (line breaks inside a quoted
|
|
48
|
+
* `ConfigFile` string) or would escape / break the `--dotnet` csproj filename
|
|
49
|
+
* (path separators, `..` traversal, or characters illegal in a filename).
|
|
50
|
+
* Returns a human-readable reason when invalid, or `null` when safe. Pure.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateProjectName(projectName: string): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Detect whether `dir` already hosts a project for any supported engine and, if
|
|
55
|
+
* so, which marker file proves it. Checks (in order) a Godot `project.godot`, a
|
|
56
|
+
* Unity `ProjectSettings/ProjectVersion.txt`, and any Unreal `*.uproject` file
|
|
57
|
+
* directly inside `dir`. Returns `null` when no marker is present (including
|
|
58
|
+
* when `dir` does not exist). Side-effect-free beyond read-only `fs` probing.
|
|
59
|
+
*/
|
|
60
|
+
export declare function detectExistingProjectMarker(dir: string): {
|
|
61
|
+
engine: ProjectMarkerEngine;
|
|
62
|
+
markerPath: string;
|
|
63
|
+
} | null;
|
|
64
|
+
/**
|
|
65
|
+
* Render the body of a minimal valid Godot 4.x `project.godot`
|
|
66
|
+
* (`config_version=5`). When `dotnet` is set, adds the `"C#"` feature and a
|
|
67
|
+
* `[dotnet]` section carrying the assembly name. Pure. Exported for unit tests.
|
|
68
|
+
*/
|
|
69
|
+
export declare function renderProjectGodot(projectName: string, dotnet: boolean): string;
|
|
70
|
+
/**
|
|
71
|
+
* Render a `Godot.NET.Sdk` csproj matching the infra `Godot-Test-Project/`
|
|
72
|
+
* reference shape (Sdk + `net8.0` + `Nullable` + `RootNamespace`). The testbed's
|
|
73
|
+
* addon-specific `PackageReference`s are intentionally NOT included — a freshly
|
|
74
|
+
* scaffolded project is not necessarily an addon consumer. Pure. Exported for
|
|
75
|
+
* unit tests.
|
|
76
|
+
*/
|
|
77
|
+
export declare function renderCsproj(projectName: string): string;
|
|
78
|
+
/**
|
|
79
|
+
* Scaffold a minimal valid Godot 4.x project — the library-callable equivalent
|
|
80
|
+
* of the `create-project` CLI command. Library-safe: never calls
|
|
81
|
+
* `process.exit`, never prints, never throws past the public boundary.
|
|
82
|
+
*
|
|
83
|
+
* Writes `project.godot` (`config_version=5`) + `icon.svg`, plus a
|
|
84
|
+
* `Godot.NET.Sdk` csproj when `dotnet` is set. Refuses (structured failure, no
|
|
85
|
+
* writes) when the target already contains a Godot/Unity/Unreal project marker.
|
|
86
|
+
* Pure `fs` operations only — no Godot binary required.
|
|
87
|
+
*/
|
|
88
|
+
export declare function createProject(options: CreateProjectOptions): Promise<CreateProjectResult>;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { resolveProjectPath } from './open.js';
|
|
4
|
+
import { emitProgress } from './progress.js';
|
|
5
|
+
/**
|
|
6
|
+
* `Godot.NET.Sdk` version pinned into a scaffolded `--dotnet` csproj. Matches
|
|
7
|
+
* the addon's own min-version floor (`Godot-MCP.csproj` pins `4.3.0`) and the
|
|
8
|
+
* `config/features` "4.3" floor written into `project.godot`. A consumer can
|
|
9
|
+
* bump this to their editor version freely; the scaffold targets the floor so
|
|
10
|
+
* the generated project opens in any Godot 4.3+ editor.
|
|
11
|
+
*/
|
|
12
|
+
export const GODOT_SDK_VERSION = '4.3.0';
|
|
13
|
+
/**
|
|
14
|
+
* Default `icon.svg` written into a scaffolded project — a self-contained,
|
|
15
|
+
* valid SVG using Godot's signature rounded-rect blue background. Mirrors the
|
|
16
|
+
* shape of the icon Godot writes for a fresh project (the exact glyph differs;
|
|
17
|
+
* what matters is a valid default icon the editor can load at `res://icon.svg`).
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
20
|
+
<rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/>
|
|
21
|
+
<g fill="#fff">
|
|
22
|
+
<circle cx="48" cy="58" r="10"/>
|
|
23
|
+
<circle cx="80" cy="58" r="10"/>
|
|
24
|
+
<rect x="40" y="82" width="48" height="8" rx="4"/>
|
|
25
|
+
</g>
|
|
26
|
+
</svg>
|
|
27
|
+
`;
|
|
28
|
+
/**
|
|
29
|
+
* Derive the project name from an explicit option, falling back to the target
|
|
30
|
+
* folder's base name. Returns `GodotProject` only when both are empty. Pure.
|
|
31
|
+
*/
|
|
32
|
+
export function deriveProjectName(projectPath, explicitName) {
|
|
33
|
+
const trimmed = explicitName?.trim();
|
|
34
|
+
if (trimmed)
|
|
35
|
+
return trimmed;
|
|
36
|
+
const base = path.basename(path.resolve(projectPath));
|
|
37
|
+
return base.length > 0 ? base : 'GodotProject';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The `[dotnet] project/assembly_name` value AND the csproj filename. Godot
|
|
41
|
+
* itself permits hyphens here (the infra testbed uses `Godot-Test-Project`), so
|
|
42
|
+
* the name is kept verbatim apart from trimming; falls back when empty. Pure.
|
|
43
|
+
*/
|
|
44
|
+
export function toAssemblyName(projectName) {
|
|
45
|
+
const cleaned = projectName.trim();
|
|
46
|
+
return cleaned.length > 0 ? cleaned : 'GodotProject';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The csproj `<RootNamespace>` — must be a valid C# identifier, so every char
|
|
50
|
+
* that is not a letter/digit/underscore is stripped and a leading digit is
|
|
51
|
+
* prefixed with `_`. Mirrors the testbed's `Godot-Test-Project` ->
|
|
52
|
+
* `GodotTestProject` derivation. Pure.
|
|
53
|
+
*/
|
|
54
|
+
export function toRootNamespace(projectName) {
|
|
55
|
+
const cleaned = projectName.replace(/[^A-Za-z0-9_]/g, '');
|
|
56
|
+
if (cleaned.length === 0)
|
|
57
|
+
return 'GodotProject';
|
|
58
|
+
return /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Escape a string for embedding inside a double-quoted Godot `ConfigFile`
|
|
62
|
+
* value (the `project.godot` format): backslash -> `\\` and double-quote ->
|
|
63
|
+
* `\"`. Without this, a name containing `"` or `\` produces a `project.godot`
|
|
64
|
+
* Godot cannot parse — or, worse, lets a crafted name inject arbitrary config
|
|
65
|
+
* keys. Pure. Exported for unit tests.
|
|
66
|
+
*/
|
|
67
|
+
export function escapeGodotConfigString(value) {
|
|
68
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate a project name before any filesystem write. Rejected when the name
|
|
72
|
+
* would corrupt the generated `project.godot` (line breaks inside a quoted
|
|
73
|
+
* `ConfigFile` string) or would escape / break the `--dotnet` csproj filename
|
|
74
|
+
* (path separators, `..` traversal, or characters illegal in a filename).
|
|
75
|
+
* Returns a human-readable reason when invalid, or `null` when safe. Pure.
|
|
76
|
+
*/
|
|
77
|
+
export function validateProjectName(projectName) {
|
|
78
|
+
if (/[\r\n]/.test(projectName))
|
|
79
|
+
return 'must not contain line breaks';
|
|
80
|
+
if (/[/\\]/.test(projectName))
|
|
81
|
+
return 'must not contain path separators ("/" or "\\")';
|
|
82
|
+
if (projectName.includes('..'))
|
|
83
|
+
return 'must not contain ".." path segments';
|
|
84
|
+
if (/[<>:"|?*]/.test(projectName))
|
|
85
|
+
return 'must not contain reserved characters (< > : " | ? *)';
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Detect whether `dir` already hosts a project for any supported engine and, if
|
|
90
|
+
* so, which marker file proves it. Checks (in order) a Godot `project.godot`, a
|
|
91
|
+
* Unity `ProjectSettings/ProjectVersion.txt`, and any Unreal `*.uproject` file
|
|
92
|
+
* directly inside `dir`. Returns `null` when no marker is present (including
|
|
93
|
+
* when `dir` does not exist). Side-effect-free beyond read-only `fs` probing.
|
|
94
|
+
*/
|
|
95
|
+
export function detectExistingProjectMarker(dir) {
|
|
96
|
+
const godot = path.join(dir, 'project.godot');
|
|
97
|
+
if (fs.existsSync(godot))
|
|
98
|
+
return { engine: 'godot', markerPath: godot };
|
|
99
|
+
const unity = path.join(dir, 'ProjectSettings', 'ProjectVersion.txt');
|
|
100
|
+
if (fs.existsSync(unity))
|
|
101
|
+
return { engine: 'unity', markerPath: unity };
|
|
102
|
+
if (fs.existsSync(dir)) {
|
|
103
|
+
try {
|
|
104
|
+
const uproject = fs
|
|
105
|
+
.readdirSync(dir)
|
|
106
|
+
.find((entry) => entry.toLowerCase().endsWith('.uproject'));
|
|
107
|
+
if (uproject)
|
|
108
|
+
return { engine: 'unreal', markerPath: path.join(dir, uproject) };
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// A readdir failure here is not a marker; the scaffold's own mkdir/write
|
|
112
|
+
// below will surface any real filesystem error as a structured failure.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Render the body of a minimal valid Godot 4.x `project.godot`
|
|
119
|
+
* (`config_version=5`). When `dotnet` is set, adds the `"C#"` feature and a
|
|
120
|
+
* `[dotnet]` section carrying the assembly name. Pure. Exported for unit tests.
|
|
121
|
+
*/
|
|
122
|
+
export function renderProjectGodot(projectName, dotnet) {
|
|
123
|
+
const features = dotnet ? 'PackedStringArray("4.3", "C#")' : 'PackedStringArray("4.3")';
|
|
124
|
+
const dotnetSection = dotnet
|
|
125
|
+
? `\n[dotnet]\n\nproject/assembly_name="${escapeGodotConfigString(toAssemblyName(projectName))}"\n`
|
|
126
|
+
: '';
|
|
127
|
+
return `; Engine configuration file.
|
|
128
|
+
; It's best edited using the editor UI and not directly,
|
|
129
|
+
; since the parameters that go here are not all obvious.
|
|
130
|
+
;
|
|
131
|
+
; Format:
|
|
132
|
+
; [section] ; section goes between []
|
|
133
|
+
; param=value ; assign values to parameters
|
|
134
|
+
|
|
135
|
+
config_version=5
|
|
136
|
+
|
|
137
|
+
[application]
|
|
138
|
+
|
|
139
|
+
config/name="${escapeGodotConfigString(projectName)}"
|
|
140
|
+
config/features=${features}
|
|
141
|
+
config/icon="res://icon.svg"
|
|
142
|
+
${dotnetSection}`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Render a `Godot.NET.Sdk` csproj matching the infra `Godot-Test-Project/`
|
|
146
|
+
* reference shape (Sdk + `net8.0` + `Nullable` + `RootNamespace`). The testbed's
|
|
147
|
+
* addon-specific `PackageReference`s are intentionally NOT included — a freshly
|
|
148
|
+
* scaffolded project is not necessarily an addon consumer. Pure. Exported for
|
|
149
|
+
* unit tests.
|
|
150
|
+
*/
|
|
151
|
+
export function renderCsproj(projectName) {
|
|
152
|
+
return `<Project Sdk="Godot.NET.Sdk/${GODOT_SDK_VERSION}">
|
|
153
|
+
|
|
154
|
+
<PropertyGroup>
|
|
155
|
+
<TargetFramework>net8.0</TargetFramework>
|
|
156
|
+
<EnableDynamicLoading>true</EnableDynamicLoading>
|
|
157
|
+
<Nullable>enable</Nullable>
|
|
158
|
+
<RootNamespace>${toRootNamespace(projectName)}</RootNamespace>
|
|
159
|
+
</PropertyGroup>
|
|
160
|
+
|
|
161
|
+
</Project>
|
|
162
|
+
`;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Scaffold a minimal valid Godot 4.x project — the library-callable equivalent
|
|
166
|
+
* of the `create-project` CLI command. Library-safe: never calls
|
|
167
|
+
* `process.exit`, never prints, never throws past the public boundary.
|
|
168
|
+
*
|
|
169
|
+
* Writes `project.godot` (`config_version=5`) + `icon.svg`, plus a
|
|
170
|
+
* `Godot.NET.Sdk` csproj when `dotnet` is set. Refuses (structured failure, no
|
|
171
|
+
* writes) when the target already contains a Godot/Unity/Unreal project marker.
|
|
172
|
+
* Pure `fs` operations only — no Godot binary required.
|
|
173
|
+
*/
|
|
174
|
+
export async function createProject(options) {
|
|
175
|
+
const warnings = [];
|
|
176
|
+
const filesWritten = [];
|
|
177
|
+
// Original bytes of any pre-existing file we overwrite, so a failed scaffold
|
|
178
|
+
// can RESTORE the caller's file rather than delete it during rollback.
|
|
179
|
+
const overwrittenOriginals = new Map();
|
|
180
|
+
let resolvedProjectPath;
|
|
181
|
+
let projectDirExistedBefore = true;
|
|
182
|
+
try {
|
|
183
|
+
const { projectPath } = resolveProjectPath(options.projectPath, process.cwd());
|
|
184
|
+
resolvedProjectPath = projectPath;
|
|
185
|
+
const dotnet = options.dotnet === true;
|
|
186
|
+
const projectName = deriveProjectName(projectPath, options.name);
|
|
187
|
+
// Validate the name BEFORE any writes — line breaks would corrupt the
|
|
188
|
+
// quoted `project.godot` strings, and path separators / `..` / reserved
|
|
189
|
+
// chars would let a crafted `--dotnet` csproj filename escape the target.
|
|
190
|
+
const nameError = validateProjectName(projectName);
|
|
191
|
+
if (nameError) {
|
|
192
|
+
const hint = options.name?.trim()
|
|
193
|
+
? ''
|
|
194
|
+
: ' (derived from the target folder name — pass --name to override)';
|
|
195
|
+
throw new Error(`Invalid project name "${projectName}": ${nameError}.${hint}`);
|
|
196
|
+
}
|
|
197
|
+
emitProgress(options.onProgress, {
|
|
198
|
+
phase: 'start',
|
|
199
|
+
message: `Creating Godot project at ${projectPath}`,
|
|
200
|
+
});
|
|
201
|
+
// Refuse to scaffold over an existing project of ANY engine BEFORE writing.
|
|
202
|
+
const existing = detectExistingProjectMarker(projectPath);
|
|
203
|
+
if (existing) {
|
|
204
|
+
throw new Error(`Refusing to scaffold: target already contains a ${existing.engine} project marker (${existing.markerPath}).`);
|
|
205
|
+
}
|
|
206
|
+
// Create the target directory (and any parents) if absent. Record whether
|
|
207
|
+
// it pre-existed so a failed scaffold can remove a directory it created
|
|
208
|
+
// (but never one the caller already had).
|
|
209
|
+
projectDirExistedBefore = fs.existsSync(projectPath);
|
|
210
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
211
|
+
// Write one file, recording it for rollback and warning when an existing
|
|
212
|
+
// non-marker file is clobbered.
|
|
213
|
+
const writeFile = (filePath, contents) => {
|
|
214
|
+
// Only a pre-existing regular FILE is an overwrite worth warning about /
|
|
215
|
+
// snapshotting; a directory at this path isn't a file we can clobber (the
|
|
216
|
+
// write below will throw), so it must not produce a phantom warning.
|
|
217
|
+
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
218
|
+
warnings.push(`Overwrote existing file: ${filePath}`);
|
|
219
|
+
// Snapshot the caller's original bytes (once) so rollback restores them
|
|
220
|
+
// instead of deleting a file they already had. If the read fails, fall
|
|
221
|
+
// back to delete-on-rollback (best-effort).
|
|
222
|
+
if (!overwrittenOriginals.has(filePath)) {
|
|
223
|
+
try {
|
|
224
|
+
overwrittenOriginals.set(filePath, fs.readFileSync(filePath));
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Unreadable: treat as freshly-written (rmSync on rollback).
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
fs.writeFileSync(filePath, contents);
|
|
232
|
+
filesWritten.push(filePath);
|
|
233
|
+
};
|
|
234
|
+
// Write the icon and (optional) csproj first, then `project.godot` LAST so
|
|
235
|
+
// the engine marker only exists once the scaffold fully succeeds — a
|
|
236
|
+
// mid-write failure leaves no marker to brick a corrected retry.
|
|
237
|
+
const iconPath = path.join(projectPath, 'icon.svg');
|
|
238
|
+
writeFile(iconPath, DEFAULT_ICON_SVG);
|
|
239
|
+
if (dotnet) {
|
|
240
|
+
const csprojPath = path.join(projectPath, `${toAssemblyName(projectName)}.csproj`);
|
|
241
|
+
writeFile(csprojPath, renderCsproj(projectName));
|
|
242
|
+
}
|
|
243
|
+
const projectGodotPath = path.join(projectPath, 'project.godot');
|
|
244
|
+
writeFile(projectGodotPath, renderProjectGodot(projectName, dotnet));
|
|
245
|
+
emitProgress(options.onProgress, {
|
|
246
|
+
phase: 'project-scaffolded',
|
|
247
|
+
message: `Scaffolded ${filesWritten.length} file(s)`,
|
|
248
|
+
projectPath,
|
|
249
|
+
});
|
|
250
|
+
emitProgress(options.onProgress, { phase: 'done', message: 'Project created.' });
|
|
251
|
+
return {
|
|
252
|
+
kind: 'success',
|
|
253
|
+
success: true,
|
|
254
|
+
projectPath,
|
|
255
|
+
projectName,
|
|
256
|
+
dotnet,
|
|
257
|
+
filesWritten,
|
|
258
|
+
warnings,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
// Roll back any files written before the failure (best-effort, reverse
|
|
263
|
+
// order) so a failed/refused scaffold leaves the target as it was found.
|
|
264
|
+
// A file we OVERWROTE is restored to its original bytes (never deleted —
|
|
265
|
+
// that would leave the caller with less than they started with); a file we
|
|
266
|
+
// freshly created is removed. Only entries whose cleanup FAILED stay in
|
|
267
|
+
// `leftover` — honouring the CreateProjectFailure.filesWritten contract
|
|
268
|
+
// (non-empty only when a partial scaffold could not be fully cleaned up).
|
|
269
|
+
const leftover = [];
|
|
270
|
+
for (const filePath of [...filesWritten].reverse()) {
|
|
271
|
+
try {
|
|
272
|
+
const original = overwrittenOriginals.get(filePath);
|
|
273
|
+
if (original !== undefined) {
|
|
274
|
+
fs.writeFileSync(filePath, original);
|
|
275
|
+
// The overwrite was reverted, so drop the now-inaccurate warning.
|
|
276
|
+
const idx = warnings.indexOf(`Overwrote existing file: ${filePath}`);
|
|
277
|
+
if (idx !== -1)
|
|
278
|
+
warnings.splice(idx, 1);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
fs.rmSync(filePath, { force: true });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
warnings.push(`Failed to roll back partially-written file: ${filePath}`);
|
|
286
|
+
leftover.push(filePath);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// We iterated in reverse for cleanup; restore write order for the contract.
|
|
290
|
+
leftover.reverse();
|
|
291
|
+
// If we created the target directory and rollback emptied it, remove it too
|
|
292
|
+
// so a failed scaffold leaves the target as it was found. Best-effort: a
|
|
293
|
+
// non-empty dir (pre-existing sibling content) keeps the rmdir from firing.
|
|
294
|
+
if (resolvedProjectPath && !projectDirExistedBefore && leftover.length === 0) {
|
|
295
|
+
try {
|
|
296
|
+
fs.rmdirSync(resolvedProjectPath);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// Directory not empty or already gone — leave it; cleanup is best-effort.
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
303
|
+
return {
|
|
304
|
+
kind: 'failure',
|
|
305
|
+
success: false,
|
|
306
|
+
projectPath: resolvedProjectPath,
|
|
307
|
+
warnings,
|
|
308
|
+
filesWritten: leftover,
|
|
309
|
+
errorMessage: errorObj.message,
|
|
310
|
+
error: errorObj,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=create-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-project.js","sourceRoot":"","sources":["../../src/lib/create-project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;CAQ/B,CAAC;AAKF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,YAAqB;IAC1E,MAAM,OAAO,GAAG,YAAY,EAAE,IAAI,EAAE,CAAC;IACrC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAChD,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,8BAA8B,CAAC;IACtE,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,gDAAgD,CAAC;IACvF,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,qCAAqC,CAAC;IAC7E,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,sDAAsD,CAAC;IACjG,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,GAAW;IAEX,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAExE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;IACtE,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAExE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,EAAE;iBAChB,WAAW,CAAC,GAAG,CAAC;iBAChB,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;YAC9D,IAAI,QAAQ;gBAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,wEAAwE;QAC1E,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAAE,MAAe;IACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,0BAA0B,CAAC;IACxF,MAAM,aAAa,GAAG,MAAM;QAC1B,CAAC,CAAC,wCAAwC,uBAAuB,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,KAAK;QACnG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;eAYM,uBAAuB,CAAC,WAAW,CAAC;kBACjC,QAAQ;;EAExB,aAAa,EAAE,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,+BAA+B,iBAAiB;;;;;;qBAMpC,eAAe,CAAC,WAAW,CAAC;;;;CAIhD,CAAC;AACF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,6EAA6E;IAC7E,uEAAuE;IACvE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvD,IAAI,mBAAuC,CAAC;IAC5C,IAAI,uBAAuB,GAAG,IAAI,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/E,mBAAmB,GAAG,WAAW,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC;QACvC,MAAM,WAAW,GAAG,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAEjE,sEAAsE;QACtE,wEAAwE;QACxE,0EAA0E;QAC1E,MAAM,SAAS,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACnD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE;gBAC/B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,kEAAkE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE;YAC/B,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,6BAA6B,WAAW,EAAE;SACpD,CAAC,CAAC;QAEH,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,mDAAmD,QAAQ,CAAC,MAAM,oBAAoB,QAAQ,CAAC,UAAU,IAAI,CAC9G,CAAC;QACJ,CAAC;QAED,0EAA0E;QAC1E,wEAAwE;QACxE,0CAA0C;QAC1C,uBAAuB,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACrD,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/C,yEAAyE;QACzE,gCAAgC;QAChC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,QAAgB,EAAQ,EAAE;YAC7D,yEAAyE;YACzE,0EAA0E;YAC1E,qEAAqE;YACrE,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC9D,QAAQ,CAAC,IAAI,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;gBACtD,wEAAwE;gBACxE,uEAAuE;gBACvE,4CAA4C;gBAC5C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC;wBACH,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAChE,CAAC;oBAAC,MAAM,CAAC;wBACP,6DAA6D;oBAC/D,CAAC;gBACH,CAAC;YACH,CAAC;YACD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC;QAEF,2EAA2E;QAC3E,qEAAqE;QACrE,iEAAiE;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACpD,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAEtC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YACnF,SAAS,CAAC,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACjE,SAAS,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QAErE,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE;YAC/B,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,cAAc,YAAY,CAAC,MAAM,UAAU;YACpD,WAAW;SACZ,CAAC,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAEjF,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;YACb,WAAW;YACX,WAAW;YACX,MAAM;YACN,YAAY;YACZ,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,uEAAuE;QACvE,yEAAyE;QACzE,yEAAyE;QACzE,2EAA2E;QAC3E,wEAAwE;QACxE,wEAAwE;QACxE,0EAA0E;QAC1E,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBACrC,kEAAkE;oBAClE,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;oBACrE,IAAI,GAAG,KAAK,CAAC,CAAC;wBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC1C,CAAC;qBAAM,CAAC;oBACN,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,IAAI,CAAC,+CAA+C,QAAQ,EAAE,CAAC,CAAC;gBACzE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QACD,4EAA4E;QAC5E,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEnB,4EAA4E;QAC5E,yEAAyE;QACzE,4EAA4E;QAC5E,IAAI,mBAAmB,IAAI,CAAC,uBAAuB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7E,IAAI,CAAC;gBACH,EAAE,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACP,0EAA0E;YAC5E,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,mBAAmB;YAChC,QAAQ;YACR,YAAY,EAAE,QAAQ;YACtB,YAAY,EAAE,QAAQ,CAAC,OAAO;YAC9B,KAAK,EAAE,QAAQ;SAChB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ export type ProgressEvent = {
|
|
|
9
9
|
phase: 'manifest-patched';
|
|
10
10
|
message: string;
|
|
11
11
|
manifestPath: string;
|
|
12
|
+
} | {
|
|
13
|
+
phase: 'project-scaffolded';
|
|
14
|
+
message: string;
|
|
15
|
+
projectPath: string;
|
|
12
16
|
} | {
|
|
13
17
|
phase: 'editor-resolved';
|
|
14
18
|
message: string;
|
|
@@ -118,6 +122,47 @@ export interface OpenEnvInputs {
|
|
|
118
122
|
mode?: OpenProjectOptions['mode'];
|
|
119
123
|
logLevel?: OpenProjectOptions['logLevel'];
|
|
120
124
|
}
|
|
125
|
+
export interface CreateProjectOptions {
|
|
126
|
+
/** Target directory to scaffold the project into. Defaults to `process.cwd()`. */
|
|
127
|
+
projectPath?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Project name written to `config/name` (and the `[dotnet]` assembly name /
|
|
130
|
+
* csproj filename when `dotnet` is set). Defaults to a name derived from the
|
|
131
|
+
* target folder name.
|
|
132
|
+
*/
|
|
133
|
+
name?: string;
|
|
134
|
+
/** When `true`, additionally scaffold a `Godot.NET.Sdk` (C#) csproj. */
|
|
135
|
+
dotnet?: boolean;
|
|
136
|
+
onProgress?: ProgressCallback;
|
|
137
|
+
}
|
|
138
|
+
export interface CreateProjectSuccess {
|
|
139
|
+
kind: 'success';
|
|
140
|
+
success: true;
|
|
141
|
+
projectPath: string;
|
|
142
|
+
/** The resolved project name (explicit arg or folder-name derivation). */
|
|
143
|
+
projectName: string;
|
|
144
|
+
/** Whether the C# (`--dotnet`) csproj was scaffolded. */
|
|
145
|
+
dotnet: boolean;
|
|
146
|
+
/** Absolute paths of every file written, in write order. */
|
|
147
|
+
filesWritten: string[];
|
|
148
|
+
warnings: string[];
|
|
149
|
+
}
|
|
150
|
+
export interface CreateProjectFailure {
|
|
151
|
+
kind: 'failure';
|
|
152
|
+
success: false;
|
|
153
|
+
projectPath?: string;
|
|
154
|
+
warnings: string[];
|
|
155
|
+
/**
|
|
156
|
+
* Absolute paths of any files written before the failure, in write order.
|
|
157
|
+
* Empty when the scaffold was refused before writing or after a successful
|
|
158
|
+
* best-effort rollback; non-empty only when cleanup of a partial scaffold
|
|
159
|
+
* could not be completed — lets the consumer finish the cleanup.
|
|
160
|
+
*/
|
|
161
|
+
filesWritten: string[];
|
|
162
|
+
errorMessage: string;
|
|
163
|
+
error: Error;
|
|
164
|
+
}
|
|
165
|
+
export type CreateProjectResult = CreateProjectSuccess | CreateProjectFailure;
|
|
121
166
|
export type RunToolFailureReason = 'invalid-input' | 'connection-refused' | 'connection-reset' | 'network-error' | 'timeout' | 'http-error' | 'unknown';
|
|
122
167
|
/**
|
|
123
168
|
* Options accepted by both {@link runTool} and {@link runSystemTool}.
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { openProject } from './lib/open.js';
|
|
2
|
+
export { createProject } from './lib/create-project.js';
|
|
2
3
|
export { runTool, runSystemTool } from './lib/run-tool.js';
|
|
3
4
|
export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
|
|
4
5
|
export { installPlugin, removePlugin } from './lib/install-plugin.js';
|
|
5
|
-
export type { ProgressEvent, ProgressCallback, ResultKind, OpenProjectOptions, OpenProjectResult, OpenProjectSuccess, OpenProjectFailure, OpenProjectAuthOption, OpenProjectConnectionMode, RunToolOptions, RunToolResult, RunToolSuccess, RunToolFailure, RunToolFailureReason, RunSystemToolOptions, RunSystemToolResult, RunSystemToolSuccess, RunSystemToolFailure, SetupMcpOptions, SetupMcpResult, SetupMcpSuccess, SetupMcpFailure, InstallPluginOptions, InstallPluginResult, InstallPluginSuccess, InstallPluginFailure, RemovePluginOptions, RemovePluginResult, RemovePluginSuccess, RemovePluginFailure, } from './lib/types.js';
|
|
6
|
+
export type { ProgressEvent, ProgressCallback, ResultKind, OpenProjectOptions, OpenProjectResult, OpenProjectSuccess, OpenProjectFailure, OpenProjectAuthOption, OpenProjectConnectionMode, CreateProjectOptions, CreateProjectResult, CreateProjectSuccess, CreateProjectFailure, RunToolOptions, RunToolResult, RunToolSuccess, RunToolFailure, RunToolFailureReason, RunSystemToolOptions, RunSystemToolResult, RunSystemToolSuccess, RunSystemToolFailure, SetupMcpOptions, SetupMcpResult, SetupMcpSuccess, SetupMcpFailure, InstallPluginOptions, InstallPluginResult, InstallPluginSuccess, InstallPluginFailure, RemovePluginOptions, RemovePluginResult, RemovePluginSuccess, RemovePluginFailure, } from './lib/types.js';
|
package/dist/lib.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
// Consumers: `import { openProject } from 'godot-cli'` (maps to this file
|
|
14
14
|
// via the `exports` field in package.json).
|
|
15
15
|
export { openProject } from './lib/open.js';
|
|
16
|
+
export { createProject } from './lib/create-project.js';
|
|
16
17
|
export { runTool, runSystemTool } from './lib/run-tool.js';
|
|
17
18
|
export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
|
|
18
19
|
export { installPlugin, removePlugin } from './lib/install-plugin.js';
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,eAAe;AACf,+EAA+E;AAC/E,wDAAwD;AACxD,oDAAoD;AACpD,yEAAyE;AACzE,4DAA4D;AAC5D,+EAA+E;AAC/E,gEAAgE;AAChE,6EAA6E;AAC7E,EAAE;AACF,0EAA0E;AAC1E,4CAA4C;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,eAAe;AACf,+EAA+E;AAC/E,wDAAwD;AACxD,oDAAoD;AACpD,yEAAyE;AACzE,4DAA4D;AAC5D,+EAA+E;AAC/E,gEAAgE;AAChE,6EAA6E;AAC7E,EAAE;AACF,0EAA0E;AAC1E,4CAA4C;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "godot-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Cross-platform CLI tool for Godot-MCP (Skills & MCP). Resolves and launches the Godot editor with MCP connection env vars, runs MCP/system tools over HTTP, probes server health, configures AI agents (Claude Code, Cursor, VS Code, …), and enables/disables the godot_mcp addon. Works with Claude Code, Cursor, Copilot, and any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/lib.js",
|