AI assistants working in this repository should read the shared guide in AGENTS.md. Client-specific files should point there instead of duplicating general repo guidance.
macOS / Linux:
git clone https://github.com/hi-godot/godot-ai.git
cd godot-ai
script/setup-dev # creates .venv, installs deps, builds plugin symlink, installs git hooks
source .venv/bin/activateWindows (PowerShell):
git clone https://github.com/hi-godot/godot-ai.git
cd godot-ai
.\script\setup-dev.ps1 # creates .venv, installs deps, builds plugin junction, installs git hooks
.venv\Scripts\Activate.ps1Plugin link is built locally, not tracked in git.
test_project/addons/godot_aiis a symlink (Unix) or directory junction (Windows) intoplugin/addons/godot_ai, created fresh bysetup-dev. A clone without runningsetup-devhas no link and Godot won't find the plugin. The Windows flavor usesmklink /J, which works without admin rights and without Windows Developer Mode.
One-time per clone:
setup-devinstalls apost-checkoutgit hook (fromscript/githooks/) into.git/hooks/. The hook auto-builds the plugin link on everygit worktree addandgit checkout <branch>, so every future worktree of this clone gets a working link automatically. You only need to runsetup-devonce per clone.
pytest -v # unit + integration tests
ruff check src/ tests/ # lint
ruff format src/ tests/ # formatGDScript test suites run inside the connected editor via MCP:
test_run # run all suites
test_run suite=scene # run one suite
test_results_get # review last results
When CI starts failing, identify the regression window (last green → first red):
script/ci-find-regression-range hi-godot/godot-ai ci.yml mainIf your local clone has a valid origin GitHub remote, you can omit owner/repo:
script/ci-find-regression-rangeFor changes that touch self-update, plugin reload handoff, or install/extract logic, run the interactive local harness:
script/local-self-update-smokeIt creates a disposable project with a physical addons/godot_ai/ copy, stages a synthetic v(N+1) plugin ZIP, launches Godot, and prints the single manual action: click Update in the Godot AI dock. After you close Godot normally, the script verifies the fixture version advanced, the update temp dir was consumed, and no new macOS Godot*.ips crash report appeared.
Self-update safety depends on the installed runner. Releases that include the fixed runner write one complete v(N+1) snapshot before Godot scans, so future upgrades from that release avoid mixed old/new script parsing. Users on older releases still take their next update through the old two-phase runner, so release shape still matters during that transition.
- Do not delete a
class_namedeclaration that has shipped in any release. If a published class needs to move or retire, leave the original file path andclass_namein place as a compatibility shim. - Before cutting a release that may be installed by an old two-phase runner, avoid adding new files that reference constants, methods, or static/non-static shape changes added to existing load-surface scripts in the same release. This applies to
class_namescripts and preload-only scripts. - Keep historical old-runner upgrade tests manual or explicitly marked. Default CI should gate the forward fixed-runner path, not permanently fail on old shipped runner behavior.
For Python-side changes without restarting Godot:
python -m godot_ai --transport streamable-http --port 8000 --reloadThe Godot AI dock also has a Start/Stop Dev Server button when running from a dev checkout.
- Branch off
main - Keep tests and lint clean
- Add tests for new behavior — both Python and Godot-side when crossing the plugin boundary
git checkout -b feature/my-feature
pytest -v && ruff check src/ tests/
git push -u origin feature/my-feature
gh pr create