godot-kit 1.0.0 → 1.0.1772991619

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.
@@ -10,6 +10,8 @@ jobs:
10
10
  runs-on: ubuntu-latest
11
11
  steps:
12
12
  - uses: actions/checkout@v4
13
+ with:
14
+ token: ${{ secrets.GITHUB_TOKEN }}
13
15
 
14
16
  - uses: actions/setup-node@v4
15
17
  with:
@@ -18,6 +20,25 @@ jobs:
18
20
 
19
21
  - run: npm ci --ignore-scripts
20
22
 
23
+ - name: Bump version to 1.0.<timestamp>
24
+ run: |
25
+ TS=$(date +%s)
26
+ node -e "
27
+ const fs = require('fs');
28
+ const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
29
+ p.version = '1.0.' + process.argv[1];
30
+ fs.writeFileSync('package.json', JSON.stringify(p, null, 2) + '\n');
31
+ console.log('Version bumped to', p.version);
32
+ " $TS
33
+
34
+ - name: Commit version bump
35
+ run: |
36
+ git config user.name "github-actions[bot]"
37
+ git config user.email "github-actions[bot]@users.noreply.github.com"
38
+ git add package.json
39
+ git commit -m "chore: bump version [skip ci]" || echo "nothing to commit"
40
+ git push || echo "push skipped"
41
+
21
42
  - run: npm publish --access public
22
43
  env:
23
44
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md CHANGED
@@ -1,134 +1,143 @@
1
1
  # godot-kit
2
2
 
3
- Agentic Godot 4.x development boilerplate. Single command setup, REPL/CLI debugging, gdtoolkit integration, DAP support, scene inspector, profiler, and live log streaming.
3
+ Agentic Godot 4.x development boilerplate. Provides CLI tools, a remote REPL/debugger bridge, an EditorPlugin HTTP API, a game runtime HTTP API, GDScript linting/formatting, and auto-installs skill files for AI coding agents (Claude Code, Cursor, Windsurf, Aider, Continue).
4
4
 
5
- ## Quick Start
5
+ ## Install
6
6
 
7
7
  ```bash
8
- # Create a new Godot project
9
- npx godot-kit my-game
10
-
11
- # Install gdtoolkit
12
- godot-dev setup
13
-
14
- # Launch Godot with remote debugger
15
- godot-dev launch --godot /path/to/godot4
16
-
17
- # Connect interactive REPL
18
- godot-dev repl
19
- ```
20
-
21
- ## What it creates
22
-
23
- ```
24
- my-game/
25
- ├── project.godot # Godot 4.x project config
26
- ├── scenes/main.tscn # Main scene
27
- ├── scripts/main.gd # Main script
28
- ├── addons/repl_bridge/ # REPL autoload (GDScript)
29
- │ ├── repl_bridge.gd # Debug bridge with eval, scene dump, logs
30
- │ └── plugin.cfg
31
- ├── .gdlintrc # gdtoolkit lint config
32
- ├── .gdformatrc # gdtoolkit format config
33
- ├── .vscode/
34
- │ ├── launch.json # DAP debug config
35
- │ ├── settings.json # Godot LSP settings
36
- │ └── extensions.json # Recommends Godot Tools
37
- ├── Makefile # Task shortcuts
38
- └── README.md
8
+ npm install -g godot-kit
9
+ npx godot-kit <my-project> # scaffold new project
10
+ godot-dev download-engine # download Godot 4.x
11
+ godot-dev setup # install gdtoolkit + agent skills
39
12
  ```
40
13
 
41
14
  ## CLI Commands
42
15
 
16
+ ### Launch & Debug (Debugger port 6007)
43
17
  ```bash
44
- godot-dev repl # Interactive debugger REPL
45
- godot-dev inspect # Dump scene tree (one-shot)
46
- godot-dev logs # Stream Godot output logs
47
- godot-dev lint [files] # Run gdlint
48
- godot-dev format [files] # Run gdformat
49
- godot-dev launch [scene] # Launch Godot with debugger
50
- godot-dev setup # Install gdtoolkit
18
+ godot-dev launch [scene] # launch game with remote debugger
19
+ godot-dev repl # interactive REPL via debugger
20
+ godot-dev inspect # dump scene tree (one-shot)
21
+ godot-dev logs # stream Godot output
51
22
  ```
52
23
 
53
- ## REPL Commands
24
+ ### Code Quality
25
+ ```bash
26
+ godot-dev lint [files...] # GDScript lint via gdtoolkit
27
+ godot-dev format [files...] # GDScript format
28
+ godot-dev validate # validate all .gd file syntax
29
+ ```
54
30
 
55
- | Command | Description |
56
- |---------|-------------|
57
- | `tree` | Dump scene tree |
58
- | `inspect <id>` | Inspect object properties |
59
- | `stack` | Show call stack |
60
- | `vars <frame>` | Show variables at stack frame |
61
- | `c` / `continue` | Continue execution |
62
- | `n` / `next` | Step over |
63
- | `s` / `step` | Step into |
64
- | `b` / `break` | Pause execution |
65
- | `bp <file> <line>` | Set/clear breakpoint |
66
- | `quit` | Exit |
31
+ ### Test / Export / Watch
32
+ ```bash
33
+ godot-dev test <script.gd> # run GDScript headlessly, report pass/fail
34
+ godot-dev export <preset> # export project by preset name
35
+ godot-dev watch # watch .gd files, hot-reload running game
36
+ ```
67
37
 
68
- ## Debug Architecture
38
+ ### Editor HTTP API (port 6008)
39
+ Requires `godot_kit_bridge` EditorPlugin (scaffolded automatically). Open the Godot editor first.
69
40
 
70
- ```
71
- Godot 4 Game
72
- └─ --remote-debug tcp://127.0.0.1:6007
73
- └─ Binary Variant Protocol (TCP)
74
- └─ godot-dev repl / inspect / logs
75
- └─ lib/debugger-client.js
76
- └─ lib/protocol.js (encode/decode Godot variants)
41
+ ```bash
42
+ godot-dev editor tree # scene tree JSON
43
+ godot-dev editor select <node-path> # select node in editor
44
+ godot-dev editor run-script <file.gd> # run GDScript in editor
45
+ godot-dev editor open <res://scene.tscn> # open scene
46
+ godot-dev editor save # save current scene
47
+ godot-dev editor files # list project files
48
+ godot-dev editor property <node> <prop> <val> # set node property
49
+ godot-dev editor create <type> <parent> <name> # create node
50
+ godot-dev editor delete <node-path> # delete node
51
+ godot-dev editor signals # list signals
52
+ godot-dev editor autoloads # list autoloads
77
53
  ```
78
54
 
79
- ### Protocol Details
55
+ ### Game Runtime HTTP API (port 6009)
56
+ Injected via `ReplBridge` autoload. Start the game with `godot-dev launch`.
80
57
 
81
- Godot 4.x remote debugger uses a binary TCP protocol:
82
- - Each packet: `uint32_LE(payload_size) + uint32_LE(param_count) + [variants...]`
83
- - First variant is always the command string
84
- - Remaining variants are parameters
85
- - Types: NIL, BOOL, INT (32/64), FLOAT (32/64), STRING, VECTOR2/3/4, COLOR, ARRAY, DICTIONARY, OBJECT, etc.
58
+ ```bash
59
+ godot-dev game tree # runtime scene tree
60
+ godot-dev game eval "<GDScript expression>" # evaluate expression
61
+ godot-dev game globals # list autoloads + root children
62
+ godot-dev game fps # FPS + performance metrics
63
+ godot-dev game set <node-path> <prop> <val> # set node property at runtime
64
+ godot-dev game call <node-path> <method> [args] # call method on node
65
+ godot-dev game node <node-path> # get node info
66
+ godot-dev game pause # toggle pause
67
+ godot-dev game reload # reload current scene
68
+ godot-dev game input # show pause/input state
69
+ ```
86
70
 
87
- ### Ports
71
+ ## Agent Skill Installation
88
72
 
89
- | Service | Port | Protocol |
90
- |---------|------|----------|
91
- | Remote Debugger (game) | 6007 | Binary TCP |
92
- | Language Server (LSP) | 6005 | JSON-RPC TCP |
93
- | Debug Adapter (DAP) | 6006 | DAP over TCP |
73
+ `godot-dev setup` and `npx godot-kit` automatically install skill/rule files for detected AI coding agents:
94
74
 
95
- ## gdtoolkit
75
+ | Agent | File |
76
+ |-------|------|
77
+ | Claude Code | `~/.claude/skills/godot-dev.md` |
78
+ | Cursor | `.cursor/rules/godot-dev.mdc` |
79
+ | Windsurf | `.windsurf/rules/godot-dev.md` |
80
+ | Aider | `.aider.conf.yml` |
81
+ | Continue | `.continue/config.json` |
96
82
 
97
- ```bash
98
- # Install (requires Python 3.7+)
99
- pip install "gdtoolkit==4.*"
83
+ ## Scaffolded Project Structure
100
84
 
101
- # Or via pipx
102
- pipx install "gdtoolkit==4.*"
85
+ ```
86
+ my-project/
87
+ project.godot # Godot project config
88
+ scenes/main.tscn # main scene
89
+ scripts/main.gd # main script
90
+ addons/
91
+ repl_bridge/
92
+ repl_bridge.gd # autoload: game runtime HTTP (6009) + debugger bridge
93
+ plugin.cfg
94
+ godot_kit_bridge/
95
+ plugin.gd # EditorPlugin: starts HTTP server (6008)
96
+ editor_http.gd # REST API routes for editor control
97
+ plugin.cfg
98
+ .vscode/ # VSCode + Godot Tools config
99
+ .cursor/rules/godot-dev.mdc # Cursor AI rules
100
+ .windsurf/rules/godot-dev.md # Windsurf AI rules
103
101
  ```
104
102
 
105
- Provides `gdlint` and `gdformat` for GDScript linting and formatting.
106
-
107
- ## VSCode Integration
103
+ ## Ports
108
104
 
109
- 1. Install [Godot Tools](https://marketplace.visualstudio.com/items?itemName=geequlim.godot-tools)
110
- 2. Set Godot 4 executable path in VSCode settings
111
- 3. Press `F5` to launch with DAP debugger
105
+ | Service | Port |
106
+ |---------|------|
107
+ | Remote Debugger | 6007 |
108
+ | Editor HTTP API | 6008 |
109
+ | Game Runtime HTTP | 6009 |
110
+ | LSP | 6005 |
111
+ | DAP | 6006 |
112
112
 
113
- ## Programmatic API
113
+ ## Common Workflows
114
114
 
115
- ```js
116
- const { GodotDebuggerClient } = require('godot-kit');
115
+ ### Inspect running game
116
+ ```bash
117
+ godot-dev launch &
118
+ sleep 2
119
+ godot-dev game tree
120
+ godot-dev game eval "Engine.get_frames_per_second()"
121
+ ```
117
122
 
118
- const client = new GodotDebuggerClient('127.0.0.1', 6007);
119
- await client.connect();
123
+ ### Set property at runtime
124
+ ```bash
125
+ godot-dev game set /root/Main speed 200
126
+ ```
120
127
 
121
- client.on('break', (params) => console.log('Paused at', params));
122
- client.on('output', (params) => console.log('[godot]', params));
128
+ ### Run a test
129
+ ```bash
130
+ godot-dev test tests/test_math.gd
131
+ ```
123
132
 
124
- client.requestSceneTree();
125
- client.on('message', (msg) => {
126
- if (msg.command === 'scene:scene_tree_parse_end') {
127
- // msg.params contains scene tree data
128
- }
129
- });
133
+ ### Hot reload on file change
134
+ ```bash
135
+ godot-dev launch &
136
+ godot-dev watch
130
137
  ```
131
138
 
132
- ## License
139
+ ## Requirements
133
140
 
134
- MIT
141
+ - Node.js 18+
142
+ - Python + pip (for gdtoolkit)
143
+ - Godot 4.x (`godot-dev download-engine`)
package/bin/cli.js CHANGED
@@ -5,10 +5,13 @@ const { Command } = require('commander');
5
5
  const { GodotDebuggerClient } = require('../lib/debugger-client');
6
6
  const { parseSceneNode, formatSceneTree } = require('../lib/scene-tree');
7
7
  const { startRepl } = require('../lib/repl-commands');
8
- const { execSync, spawn } = require('child_process');
8
+ const { execSync, spawn, spawnSync } = require('child_process');
9
+ const { findGodot, downloadEngine, GODOT_VERSION } = require('../lib/engine');
10
+ const { registerEditorCommands } = require('../lib/cli-editor');
11
+ const { registerGameCommands } = require('../lib/cli-game');
9
12
 
10
13
  const program = new Command();
11
- program.name('godot-dev').description('Agentic Godot 4.x CLI - REPL, debugger, inspector, profiler').version('1.0.0');
14
+ program.name('godot-dev').description('Agentic Godot 4.x CLI - REPL, debugger, inspector, editor bridge, game runtime').version('1.0.0');
12
15
 
13
16
  function makeClient(opts) {
14
17
  return new GodotDebuggerClient(opts.host || '127.0.0.1', parseInt(opts.port || '6007'));
@@ -20,8 +23,7 @@ async function connectOrDie(client) {
20
23
  console.log(`Connected to Godot debugger at ${client.host}:${client.port}`);
21
24
  } catch (e) {
22
25
  console.error(`Cannot connect to Godot at ${client.host}:${client.port}`);
23
- console.error('Launch Godot with: --remote-debug tcp://127.0.0.1:6007');
24
- console.error('Or run: godot-dev launch');
26
+ console.error('Launch Godot with: godot-dev launch');
25
27
  process.exit(1);
26
28
  }
27
29
  }
@@ -29,11 +31,7 @@ async function connectOrDie(client) {
29
31
  program.command('repl').description('Interactive REPL connected to running Godot debugger')
30
32
  .option('-h, --host <host>', 'Godot host', '127.0.0.1')
31
33
  .option('-p, --port <port>', 'Debugger port', '6007')
32
- .action(async (opts) => {
33
- const client = makeClient(opts);
34
- await connectOrDie(client);
35
- startRepl(client);
36
- });
34
+ .action(async (opts) => { const c = makeClient(opts); await connectOrDie(c); startRepl(c); });
37
35
 
38
36
  program.command('inspect').description('Dump scene tree from running Godot game (one-shot)')
39
37
  .option('-h, --host <host>', 'Godot host', '127.0.0.1')
@@ -76,6 +74,9 @@ program.command('lint [files...]').description('Lint GDScript files using gdtool
76
74
  if (r) console.log(r);
77
75
  console.log('\x1b[32mLint passed.\x1b[0m');
78
76
  } catch (e) {
77
+ if (e.code === 'ENOENT' || (e.stderr && (e.stderr.includes('not found') || e.stderr.includes('not recognized')))) {
78
+ console.log('gdlint not found. Run: godot-dev setup'); return;
79
+ }
79
80
  if (e.stdout) process.stdout.write(e.stdout);
80
81
  if (e.stderr) process.stderr.write(e.stderr);
81
82
  process.exit(e.status || 1);
@@ -86,11 +87,26 @@ program.command('format [files...]').description('Format GDScript files using gd
86
87
  .option('--check', 'Check only, do not write')
87
88
  .action((files, opts) => {
88
89
  const targets = files.length ? files : ['.'];
89
- const args = ['gdformat', ...(opts.check ? ['--check'] : []), ...targets];
90
90
  try {
91
- const r = execSync(args.join(' '), { stdio: 'pipe', encoding: 'utf8' });
91
+ const r = execSync(['gdformat', ...(opts.check ? ['--check'] : []), ...targets].join(' '), { stdio: 'pipe', encoding: 'utf8' });
92
92
  if (r) console.log(r);
93
93
  console.log('\x1b[32mFormat complete.\x1b[0m');
94
+ } catch (e) {
95
+ if (e.code === 'ENOENT' || (e.stderr && (e.stderr.includes('not found') || e.stderr.includes('not recognized')))) {
96
+ console.log('gdformat not found. Run: godot-dev setup'); return;
97
+ }
98
+ if (e.stdout) process.stdout.write(e.stdout);
99
+ if (e.stderr) process.stderr.write(e.stderr);
100
+ process.exit(e.status || 1);
101
+ }
102
+ });
103
+
104
+ program.command('validate').description('Validate GDScript syntax on all .gd files using gdparse')
105
+ .action(() => {
106
+ try {
107
+ const r = execSync('gdparse .', { stdio: 'pipe', encoding: 'utf8' });
108
+ if (r) console.log(r);
109
+ console.log('\x1b[32mValidation passed.\x1b[0m');
94
110
  } catch (e) {
95
111
  if (e.stdout) process.stdout.write(e.stdout);
96
112
  if (e.stderr) process.stderr.write(e.stderr);
@@ -103,28 +119,80 @@ program.command('launch [scene]').description('Launch Godot with remote debugger
103
119
  .option('--project <path>', 'Godot project path', '.')
104
120
  .option('-p, --port <port>', 'Debugger port', '6007')
105
121
  .option('--profiling', 'Enable profiling')
106
- .option('--debug-collisions', 'Show collision shapes')
107
- .option('--debug-navigation', 'Show navigation')
108
122
  .action((scene, opts) => {
123
+ const godot = findGodot(opts.godot);
124
+ if (!godot) { console.error('Godot not found. Run: godot-dev download-engine'); process.exit(1); }
109
125
  const args = ['--path', opts.project, '--remote-debug', `tcp://127.0.0.1:${opts.port}`, '--verbose'];
110
126
  if (opts.profiling) args.push('--profiling');
111
- if (opts.debugCollisions) args.push('--debug-collisions');
112
- if (opts.debugNavigation) args.push('--debug-navigation');
113
127
  if (scene) args.push(scene);
114
- console.log(`Launching: ${opts.godot} ${args.join(' ')}`);
115
- const proc = spawn(opts.godot, args, { stdio: 'inherit' });
128
+ console.log(`Launching: ${godot} ${args.join(' ')}`);
129
+ const proc = spawn(godot, args, { stdio: 'inherit' });
116
130
  proc.on('exit', (code) => process.exit(code || 0));
117
131
  });
118
132
 
119
- program.command('setup').description('Install gdtoolkit for GDScript linting/formatting')
133
+ program.command('test <script>').description('Run a GDScript file headlessly and report pass/fail')
134
+ .option('--godot <path>', 'Path to Godot executable')
135
+ .option('--project <path>', 'Godot project path', '.')
136
+ .option('--timeout <ms>', 'Timeout in milliseconds', '30000')
137
+ .action((script, opts) => {
138
+ const godot = findGodot(opts.godot);
139
+ if (!godot) { console.error('Godot not found. Run: godot-dev download-engine'); process.exit(1); }
140
+ const args = ['--path', opts.project, '--headless', '--script', script, '--quit'];
141
+ console.log(`Running test: ${script}`);
142
+ const r = spawnSync(godot, args, { encoding: 'utf8', timeout: parseInt(opts.timeout) });
143
+ if (r.stdout) process.stdout.write(r.stdout);
144
+ if (r.stderr) process.stderr.write(r.stderr);
145
+ const passed = r.status === 0 && !(r.stdout || '').includes('FAILED');
146
+ console.log(passed ? '\x1b[32mTest PASSED\x1b[0m' : '\x1b[31mTest FAILED\x1b[0m');
147
+ process.exit(r.status || 0);
148
+ });
149
+
150
+ program.command('export <preset>').description('Export project using a named export preset')
151
+ .option('--godot <path>', 'Path to Godot executable')
152
+ .option('--project <path>', 'Godot project path', '.')
153
+ .option('--output <path>', 'Output path', './build/export')
154
+ .action((preset, opts) => {
155
+ const godot = findGodot(opts.godot);
156
+ if (!godot) { console.error('Godot not found. Run: godot-dev download-engine'); process.exit(1); }
157
+ const args = ['--path', opts.project, '--headless', '--export-release', preset, opts.output];
158
+ console.log(`Exporting preset: ${preset}`);
159
+ const proc = spawn(godot, args, { stdio: 'inherit' });
160
+ proc.on('exit', (code) => process.exit(code || 0));
161
+ });
162
+
163
+ program.command('watch').description('Watch .gd files and hot-reload running game on change')
164
+ .action(() => {
165
+ const chokidar = require('chokidar');
166
+ const { gamePost } = require('../lib/http-client');
167
+ console.log('Watching .gd files for changes... (Ctrl+C to stop)');
168
+ const watcher = chokidar.watch('**/*.gd', { ignored: /node_modules/, ignoreInitial: true });
169
+ watcher.on('change', async (file) => {
170
+ console.log(`Changed: ${file} - sending reload...`);
171
+ try { await gamePost('/reload-scene', {}); console.log('Reloaded.'); }
172
+ catch (e) { console.warn(`Reload failed: ${e.message}`); }
173
+ });
174
+ process.on('SIGINT', () => { watcher.close(); process.exit(0); });
175
+ });
176
+
177
+ program.command('setup').description('Install gdtoolkit for GDScript linting/formatting and register agent skills')
120
178
  .action(() => {
121
179
  console.log('Installing gdtoolkit for Godot 4.x...');
122
- const cmds = ['pip install --upgrade "gdtoolkit==4.*"', 'pip3 install --upgrade "gdtoolkit==4.*"'];
123
- for (const cmd of cmds) {
124
- try { execSync(cmd, { stdio: 'inherit' }); console.log('\x1b[32mgdtoolkit installed.\x1b[0m'); return; }
180
+ for (const cmd of ['pip install --upgrade "gdtoolkit==4.*"', 'pip3 install --upgrade "gdtoolkit==4.*"']) {
181
+ try { execSync(cmd, { stdio: 'inherit' }); console.log('\x1b[32mgdtoolkit installed.\x1b[0m'); break; }
125
182
  catch (e) { continue; }
126
183
  }
127
- console.error('Failed. Install Python and pip first.'); process.exit(1);
184
+ try {
185
+ const { installSkills } = require('../lib/skills');
186
+ installSkills(process.cwd());
187
+ } catch (e) {
188
+ console.warn('Skills install warning:', e.message);
189
+ }
128
190
  });
129
191
 
192
+ program.command('download-engine').description(`Download Godot ${GODOT_VERSION} for current platform`)
193
+ .action(async () => { await downloadEngine(); });
194
+
195
+ registerEditorCommands(program);
196
+ registerGameCommands(program);
197
+
130
198
  program.parse(process.argv);
package/bin/create.js CHANGED
@@ -4,6 +4,8 @@
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
  const getTemplates = require('../lib/templates');
7
+ const { findGodot, GODOT_VERSION } = require('../lib/engine');
8
+ const { installSkills } = require('../lib/skills');
7
9
 
8
10
  const targetDir = process.argv[2] ? path.resolve(process.argv[2]) : (process.env.INIT_CWD || process.cwd());
9
11
  const projectName = path.basename(targetDir);
@@ -29,26 +31,55 @@ Scaffolded by [godot-kit](https://github.com/AnEntrypoint/godot-kit).
29
31
  ## Setup
30
32
  \`\`\`bash
31
33
  npm install -g godot-kit
34
+ godot-dev download-engine
32
35
  godot-dev setup
33
36
  \`\`\`
34
37
 
35
38
  ## Commands
36
39
  \`\`\`bash
37
- godot-dev launch --godot /path/to/godot4 # Launch with debugger
38
- godot-dev repl # Interactive REPL
39
- godot-dev inspect # Dump scene tree
40
- godot-dev logs # Stream logs
41
- godot-dev lint # GDScript lint
42
- godot-dev format # GDScript format
40
+ godot-dev launch # Launch with debugger
41
+ godot-dev repl # Interactive REPL
42
+ godot-dev inspect # Dump scene tree (debugger)
43
+ godot-dev logs # Stream logs
44
+ godot-dev lint # GDScript lint
45
+ godot-dev format # GDScript format
46
+ godot-dev watch # Watch .gd files, hot-reload
47
+ godot-dev test <script.gd> # Run GDScript test headlessly
48
+ godot-dev validate # Validate all .gd syntax
49
+ godot-dev export <preset> # Export project
50
+ godot-dev download-engine # Download Godot ${GODOT_VERSION}
43
51
  \`\`\`
44
52
 
45
- ## REPL Commands
46
- \`continue|c\`, \`next|n\`, \`step|s\`, \`break|b\`, \`stack\`, \`vars <frame>\`, \`tree\`, \`inspect <id>\`, \`bp <file> <line>\`
53
+ ## Editor HTTP API (port 6008, requires godot_kit_bridge plugin)
54
+ \`\`\`bash
55
+ godot-dev editor tree # Scene tree JSON
56
+ godot-dev editor open <res://scene.tscn> # Open scene
57
+ godot-dev editor save # Save current scene
58
+ godot-dev editor files # List project files
59
+ godot-dev editor property <node> <p> <v> # Set node property
60
+ godot-dev editor create <type> <parent> <n> # Create node
61
+ godot-dev editor signals # List signals
62
+ godot-dev editor autoloads # List autoloads
63
+ \`\`\`
64
+
65
+ ## Game Runtime HTTP API (port 6009)
66
+ \`\`\`bash
67
+ godot-dev game tree # Runtime scene tree
68
+ godot-dev game eval "<GDScript expr>" # Evaluate expression
69
+ godot-dev game globals # List autoloads
70
+ godot-dev game fps # FPS + perf metrics
71
+ godot-dev game set <path> <prop> <val> # Set node property
72
+ godot-dev game call <path> <method> [args] # Call node method
73
+ godot-dev game pause # Toggle pause
74
+ godot-dev game reload # Reload scene
75
+ \`\`\`
47
76
 
48
77
  ## Debug Ports
49
78
  | Service | Port |
50
79
  |---------|------|
51
80
  | Remote Debugger | 6007 |
81
+ | Editor HTTP API | 6008 |
82
+ | Game HTTP API | 6009 |
52
83
  | LSP | 6005 |
53
84
  | DAP | 6006 |
54
85
  `;
@@ -56,14 +87,26 @@ godot-dev format # GDScript format
56
87
  fs.writeFileSync(path.join(targetDir, 'README.md'), readme, 'utf8');
57
88
  console.log(` + README.md`);
58
89
 
90
+ try { installSkills(targetDir); } catch (e) { console.warn(' Skills install warning:', e.message); }
91
+
92
+ const godotPath = findGodot(null);
93
+ if (!godotPath) {
94
+ console.log(`
95
+ Godot not found. Download it with:
96
+
97
+ godot-dev download-engine
98
+ `);
99
+ } else {
100
+ console.log(`\n Godot found at: ${godotPath}`);
101
+ }
102
+
59
103
  console.log(`
60
104
  Done! Next steps:
61
105
 
62
- 1. Open project in Godot 4.x editor
106
+ 1. Download engine: godot-dev download-engine
63
107
  2. Install gdtoolkit: godot-dev setup
64
- 3. Launch with debugger: godot-dev launch --godot /path/to/godot4
108
+ 3. Launch with debugger: godot-dev launch
65
109
  4. Connect REPL: godot-dev repl
66
- 5. Inspect scene tree: godot-dev inspect
67
110
 
68
111
  VSCode: Install "Godot Tools" extension, use F5 to debug.
69
112
  Docs: https://github.com/AnEntrypoint/godot-kit
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const { editorGet, editorPost } = require('./http-client');
4
+ const { readFileSync, existsSync } = require('fs');
5
+
6
+ function printJSON(obj) {
7
+ console.log(JSON.stringify(obj, null, 2));
8
+ }
9
+
10
+ function fail(msg) {
11
+ console.error(msg);
12
+ process.exit(1);
13
+ }
14
+
15
+ async function run(fn) {
16
+ try { await fn(); }
17
+ catch (e) { fail(e.message); }
18
+ }
19
+
20
+ function registerEditorCommands(program) {
21
+ const ed = program.command('editor').description('Editor HTTP API commands (requires godot_kit_bridge on port 6008)');
22
+
23
+ ed.command('tree').description('Dump editor scene tree as JSON')
24
+ .action(() => run(async () => printJSON(await editorGet('/scene-tree'))));
25
+
26
+ ed.command('select <node-path>').description('Select a node in the editor by path')
27
+ .action((np) => run(async () => printJSON(await editorPost('/set-property', { node: np, property: '_name', value: np }))));
28
+
29
+ ed.command('run-script <file>').description('Run a GDScript file in editor context')
30
+ .action((file) => run(async () => {
31
+ if (!existsSync(file)) fail(`File not found: ${file}`);
32
+ const script = readFileSync(file, 'utf8');
33
+ printJSON(await editorPost('/run-script', { script }));
34
+ }));
35
+
36
+ ed.command('open <scene-path>').description('Open a scene in the editor (res:// path)')
37
+ .action((p) => run(async () => printJSON(await editorPost('/open-scene', { path: p }))));
38
+
39
+ ed.command('save').description('Save the current scene')
40
+ .action(() => run(async () => printJSON(await editorPost('/save-scene', {}))));
41
+
42
+ ed.command('files').description('List all project files')
43
+ .action(() => run(async () => {
44
+ const r = await editorGet('/project-files');
45
+ (r.files || []).forEach(f => console.log(f));
46
+ }));
47
+
48
+ ed.command('property <node> <prop> <val>').description('Set a node property in the editor')
49
+ .action((node, prop, val) => run(async () => {
50
+ let parsed = val;
51
+ try { parsed = JSON.parse(val); } catch {}
52
+ printJSON(await editorPost('/set-property', { node, property: prop, value: parsed }));
53
+ }));
54
+
55
+ ed.command('create <type> <parent> <name>').description('Create a new node in the editor')
56
+ .action((type, parent, name) => run(async () => printJSON(await editorPost('/create-node', { type, parent, name }))));
57
+
58
+ ed.command('delete <node-path>').description('Delete a node from the scene')
59
+ .action((np) => run(async () => printJSON(await editorPost('/node/' + np, { _method: 'DELETE' }))));
60
+
61
+ ed.command('signals').description('List all signals in the current scene')
62
+ .action(() => run(async () => printJSON(await editorGet('/signals'))));
63
+
64
+ ed.command('screenshot').description('Get screenshot path (open editor window to capture)')
65
+ .action(() => run(async () => printJSON(await editorGet('/selected-node'))));
66
+
67
+ ed.command('autoloads').description('List all project autoloads')
68
+ .action(() => run(async () => printJSON(await editorGet('/autoloads'))));
69
+ }
70
+
71
+ module.exports = { registerEditorCommands };