{"_id":"@4fu/godot-cli","_rev":"4-0048fc43ae75fa09bf3277c610a831f2","name":"@4fu/godot-cli","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@4fu/godot-cli","version":"1.0.0","author":{"url":"https://github.com/4fuu","name":"4fu","email":"hi@4fwu.com"},"_id":"@4fu/godot-cli@1.0.0","maintainers":[{"name":"4fu","email":"npm@4fwu.com"}],"bin":{"godot-cli":"dist/cli.js"},"dist":{"shasum":"66a47b73a83882aa5e309595c61663bca5ead4d5","tarball":"https://registry.npmjs.org/@4fu/godot-cli/-/godot-cli-1.0.0.tgz","fileCount":33,"integrity":"sha512-sXPbupFZ1dbyQyevGO1yMaq4uzy0l0wkNPiSkbrmtCV6F8SBGAxdg/8Hb5gOz1cF3mc8ENObqk+LImPiyt95EQ==","signatures":[{"sig":"MEUCIQDKckqgMTXSVHLirYPqNQ1TeLx2bRJ+SO4vA0aF2i/+6gIgEln4NKw0qp6UvDCGv9gjYbEKn0Ku7twGVSM2iU2Go4g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":210044},"type":"module","engines":{"node":">=20.9"},"gitHead":"7f6b35e118083dda963ff6373534cdca26891e4c","scripts":{"test":"npm run clean && tsc -p tsconfig.test.json && node --test dist-test/test/unit/*.test.js","build":"npm run clean && tsc -p tsconfig.json","clean":"node -e \"for(const p of ['dist','dist-test'])require('node:fs').rmSync(p,{recursive:true,force:true})\"","prepack":"npm run build"},"_npmUser":{"name":"4fu","email":"npm@4fwu.com"},"_npmVersion":"11.16.0","description":"[English](README.md)","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ajv":"^8.17.1","@sinclair/typebox":"^0.34.38"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/godot-cli_1.0.0_1785851268583_0.15911668886607555","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@4fu/godot-cli","version":"1.0.1","author":{"url":"https://github.com/4fuu","name":"4fu","email":"hi@4fwu.com"},"_id":"@4fu/godot-cli@1.0.1","maintainers":[{"name":"4fu","email":"npm@4fwu.com"}],"bin":{"godot-cli":"dist/cli.js"},"dist":{"shasum":"57770a7e13f62e6207fbf801f38a22e7e9cfe7e3","tarball":"https://registry.npmjs.org/@4fu/godot-cli/-/godot-cli-1.0.1.tgz","fileCount":30,"integrity":"sha512-i5j5tIT0uG4KIjeEENZtJzQIhYKISAUVJfgQT5rYOtZW+c0mGcF5fHwye0p8ctTcWD2BgqxLo7kw2To/Ud4sZg==","signatures":[{"sig":"MEUCIQDC+80V2IDlArqW5em0InJLjBR0FQwjrtDwnap3OrMpiwIgTWCFigtOGGsJ/TApHd+cQW6GM2f9+tHLOZax8v7+Kno=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":202297},"type":"module","engines":{"node":">=20.9"},"gitHead":"683289cd4f80871d93b01aa7a218c637000fba64","scripts":{"test":"npm run clean && tsc -p tsconfig.test.json && node --test dist-test/test/unit/*.test.js","build":"npm run clean && tsc -p tsconfig.json","clean":"node -e \"for(const p of ['dist','dist-test'])require('node:fs').rmSync(p,{recursive:true,force:true})\"","format":"npm run format:typescript && npm run format:gdscript","prepack":"npm run format:check && npm run build","format:check":"npm run format:typescript:check && npm run format:gdscript:check","format:gdscript":"uvx --from gdtoolkit==4.5.0 gdformat --line-length 100 godot","format:typescript":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json","format:gdscript:check":"uvx --from gdtoolkit==4.5.0 gdformat --check --line-length 100 godot","format:typescript:check":"prettier --check \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json"},"_npmUser":{"name":"4fu","email":"npm@4fwu.com"},"_npmVersion":"11.16.0","description":"[English](README.md)","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ajv":"^8.17.1","@sinclair/typebox":"^0.34.38"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"^3.9.6","typescript":"^7.0.2","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/godot-cli_1.0.1_1786014545344_0.2502061400659519","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@4fu/godot-cli","version":"1.0.2","author":{"url":"https://github.com/4fuu","name":"4fu","email":"hi@4fwu.com"},"_id":"@4fu/godot-cli@1.0.2","maintainers":[{"name":"4fu","email":"npm@4fwu.com"}],"bin":{"godot-cli":"dist/cli.js"},"dist":{"shasum":"d01e968af47dc0fc23d77d668b7b77fd0d98e9a1","tarball":"https://registry.npmjs.org/@4fu/godot-cli/-/godot-cli-1.0.2.tgz","fileCount":30,"integrity":"sha512-SQH4PHA7GFeiCy0cpIGrQWnpehvIgGM7OqXme9B3bRp2VDi0bnHm3Gx8bMpNL/G7jU4XjJI/t5sCCZEO8WhhZw==","signatures":[{"sig":"MEQCIHaqThDPOy3yxWj4CipVUtZAsDjOiOWY8R5nOw09yGsRAiA8zE6th7GSMacka9+tPv7+eNqM1XiiEReXmoxZCVKeMA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":221952},"type":"module","engines":{"node":">=20.9"},"gitHead":"80e070e244f8fe4b1e72fde64ab8add3719f61c8","scripts":{"test":"npm run clean && tsc -p tsconfig.test.json && node --test dist-test/test/unit/*.test.js","build":"npm run clean && tsc -p tsconfig.json","clean":"node -e \"for(const p of ['dist','dist-test'])require('node:fs').rmSync(p,{recursive:true,force:true})\"","format":"npm run format:typescript && npm run format:gdscript","prepack":"npm run format:check && npm run build","format:check":"npm run format:typescript:check && npm run format:gdscript:check","format:gdscript":"uvx --from gdtoolkit==4.5.0 gdformat --line-length 100 godot","format:typescript":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json","format:gdscript:check":"uvx --from gdtoolkit==4.5.0 gdformat --check --line-length 100 godot","format:typescript:check":"prettier --check \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json"},"_npmUser":{"name":"4fu","email":"npm@4fwu.com"},"_npmVersion":"11.16.0","description":"[English](README.md)","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ajv":"^8.17.1","@sinclair/typebox":"^0.34.38"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"^3.9.6","typescript":"^7.0.2","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/godot-cli_1.0.2_1786178586551_0.5139033458331872","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@4fu/godot-cli","version":"1.0.3","publishConfig":{"access":"public"},"author":{"name":"4fu","email":"hi@4fwu.com","url":"https://github.com/4fuu"},"type":"module","engines":{"node":">=20.9"},"bin":{"godot-cli":"dist/cli.js"},"scripts":{"clean":"node -e \"for(const p of ['dist','dist-test'])require('node:fs').rmSync(p,{recursive:true,force:true})\"","build":"npm run clean && tsc -p tsconfig.json","test":"npm run clean && tsc -p tsconfig.test.json && node --test dist-test/test/unit/*.test.js","format":"npm run format:typescript && npm run format:gdscript","format:check":"npm run format:typescript:check && npm run format:gdscript:check","format:typescript":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json","format:typescript:check":"prettier --check \"src/**/*.ts\" \"test/**/*.ts\" package.json package-lock.json \"tsconfig*.json\" .prettierrc.json","format:gdscript":"uvx --from gdtoolkit==4.5.0 gdformat --line-length 100 godot","format:gdscript:check":"uvx --from gdtoolkit==4.5.0 gdformat --check --line-length 100 godot","prepack":"npm run format:check && npm run build"},"dependencies":{"@sinclair/typebox":"^0.34.38","ajv":"^8.17.1"},"devDependencies":{"@types/node":"^22.10.0","prettier":"^3.9.6","typescript":"^7.0.2"},"gitHead":"d924ebe8e29dab7b496826b7bb0a8ee5ee9de03c","_id":"@4fu/godot-cli@1.0.3","description":"[English](README.md)","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-ifEUJ6SNX9G352MO5EpxCp0Naqa8S7I8JsqEHvw6p2PX8Ht9S9L4i8nb3t2Z3fH2XHIJOltP7N8bHeiUDiF/iw==","shasum":"c84a497969e80eaa1bef2c9e1803f19c70fc3f54","tarball":"https://registry.npmjs.org/@4fu/godot-cli/-/godot-cli-1.0.3.tgz","fileCount":30,"unpackedSize":233282,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCOIEykagJ+Mh0MeF6z1QTidTifOlv6KcBVnnxF/MPlXwIhAIo+cMAL3r4AGj3/AAiDXIPWuT1uEel3r/CpUmztabYL"}]},"_npmUser":{"name":"4fu","email":"npm@4fwu.com"},"directories":{},"maintainers":[{"name":"4fu","email":"npm@4fwu.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/godot-cli_1.0.3_1786247845644_0.959311801510405"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T13:47:48.417Z","modified":"2026-08-09T03:57:25.944Z","1.0.0":"2026-08-04T13:47:48.727Z","1.0.1":"2026-08-06T11:09:05.500Z","1.0.2":"2026-08-08T08:43:06.700Z","1.0.3":"2026-08-09T03:57:25.790Z"},"author":{"name":"4fu","email":"hi@4fwu.com","url":"https://github.com/4fuu"},"description":"[English](README.md)","maintainers":[{"name":"4fu","email":"npm@4fwu.com"}],"readme":"# godot-cli\n\n[English](README.md)\n\n`godot-cli` 是一个为编码 Agent 补充 Godot 专属自动化能力的结构化命令行工具。它提供带类型、可发现的命令，用于项目操作、无头场景/资源/脚本处理、进程生命周期以及运行时检查和测试；普通文件编辑则交给 Agent 原生工具。\n\n## 功能\n\n- **分层命令发现**：通过 `--help` 获取可读指导，通过 `commands` 浏览目录，通过 `--help-json` 获取精确 schema。\n- **类型化输入校验**：命令参数从 TypeBox schema 生成，并在 adapter 执行前校验。\n- **默认可读、按需结构化**：交互输出默认为简洁文本；自动化可通过 `--json` 获取稳定的成功或错误 envelope。\n- **项目操作**：检查或创建项目并管理 Godot 项目设置。\n- **Godot 无头操作**：创建/读取场景、添加/删除节点、创建/检查资源，以及通过 Godot 校验脚本。\n- **运行时控制**：启动和停止 Godot 场景，检查进程/运行时状态及场景树，读取日志，发送输入，等待帧并执行断言。\n- **写入预览**：受支持的写风险命令可先通过全局 `--dry-run` 返回计划变更。\n- **Agent Skill**：一个路由 skill 按任务渐进加载所需的工作流 reference。\n\n## 要求与兼容性\n\n- Node.js 20.9 或更新版本。\n- Godot 可通过 `godot`/`godot4` 访问，或通过 `--godot`、`GODOT_BIN` 指定。\n- 发布前冒烟流程使用 Godot 4.7.1 验证。\n\nGodot 的行为可能随引擎版本和项目配置变化。“已测试”并不代表承诺兼容所有 Godot 4 版本。\n\n## 安装\n\n全局安装 CLI 包：\n\n```sh\nnpm install --global @4fu/godot-cli\ngodot-cli --help\n```\n\n指定非默认 Godot 二进制：\n\n```sh\ngodot-cli --godot /path/to/godot --project . project inspect\nGODOT_BIN=/path/to/godot godot-cli --project . project inspect\n```\n\n## 快速开始\n\n检查项目和场景：\n\n```sh\ngodot-cli --project . project inspect\ngodot-cli --project . scene read --path res://main.tscn --depth 4 --limit 200\n```\n\n预览、应用并验证场景修改：\n\n```sh\ngodot-cli --project . --dry-run scene add-node \\\n  --path res://main.tscn --parent . --type Node2D --name SpawnPoint\n\ngodot-cli --project . scene add-node \\\n  --path res://main.tscn --parent . --type Node2D --name SpawnPoint\n\ngodot-cli --project . scene read --path res://main.tscn\n```\n\n启动场景、检查运行时并确保停止进程：\n\n```sh\ngodot-cli --project . --timeout 15000 process run --scene res://main.tscn\ngodot-cli --project . runtime state\ngodot-cli --project . runtime tree --depth 3\ngodot-cli --project . process stop\n```\n\n## 实时编辑器模式\n\n使用 `godot-cli editor start` 和 `godot-cli editor stop` 启停项目编辑器会话（自动化环境可传 `--headless true`）。`editor` 下的命令直接操作编辑器的当前场景、选择、文件系统与调试器真实状态，也能读取尚未保存的修改。场景写操作进入 Godot 原生撤销历史；由于 Godot 没有暴露可安全驱动管理器的脚本命令，撤销/重做仍由编辑器 UI 执行。可用 `--expected-scene res://...` 防止场景标签切换后误操作。\n\n## 命令发现\n\n先使用内置的人类可读帮助。根命令、命令族和具体命令均提供帮助：\n\n```sh\ngodot-cli --help\ngodot-cli scene --help\ngodot-cli scene add-node --help\n```\n\n列出全部命令或单个命令族：\n\n```sh\ngodot-cli commands\ngodot-cli commands scene\n```\n\n人类可读目录使用 `scene add-node` 这种可以直接复制的 Shell 名称。脚本需要稳定目录时添加 `--json`；其中的规范路径使用 `domain/command`：\n\n```sh\ngodot-cli commands --json\n```\n\n只有当自动化客户端需要精确的 mode、wire route、风险、输入/输出 schema、CLI bindings 和超时元数据时，才使用 `--help-json`：\n\n```sh\ngodot-cli scene add-node --help-json\ngodot-cli runtime assert --help-json\n```\n\n## 命令族\n\n| 命令族 | 命令 |\n| --- | --- |\n| System | Godot 版本、ClassDB class 搜索与 API 元数据 |\n| Project | 检查/创建、settings、autoload、输入动作、layers、plugins、translations、主场景、导出预设和导出 |\n| Scene | 读取/创建/诊断、节点增删/属性/结构、PackedScene 实例化、脚本挂载和持久化信号连接 |\n| Script | 单个/批量/全项目校验、诊断、符号、C# 脚手架和受控项目脚本执行 |\n| Resource | 创建/检查/修改/复制/重存/UID 和 Shader 管理 |\n| Process | `process/run`, `process/stop`, `process/logs`, `process/state` |\n| Editor | 实时场景/选择/节点/属性及原生撤销历史、场景标签/保存、文件扫描/重新导入和 debugger 状态 |\n| Runtime | state/tree/节点变更/property/method/groups/signals、可见 UI、engine/window/性能、场景切换、暂停/步进、viewport、多设备输入、等待/断言、截图和 cursor 日志 |\n\n准确参数和 schema 以命令发现输出为准。\n\n## 执行模型\n\n命令分发到四种执行模式：\n\n| 模式 | 职责 |\n| --- | --- |\n| Local | Godot 版本查询、项目/进程生命周期、导出和受控脚本执行 |\n| Headless | 使用隔离的 Godot 进程执行场景、资源、脚本和项目检查/修改 |\n| Runtime | 与 `process run` 启动的场景建立经过认证的 loopback 连接 |\n| Editor | 与 `editor start` 启动的实时编辑器建立经过认证的 loopback 连接 |\n\n命令目录负责公共名称与 schema；adapter 将校验后的输入转换为后端操作，使 Shell 语法与内部 wire route 解耦。\n\n## 全局参数\n\n| 参数 | 说明 |\n| --- | --- |\n| `--project <path>` | 选择项目根目录，默认为当前目录 |\n| `--godot <path>` | 选择 Godot 可执行文件 |\n| `--timeout <ms>` | 设置有界操作超时 |\n| `--dry-run` | 预览受支持的写风险操作 |\n| `--allow <capability>` | 授予受保护能力，可重复 |\n| `--session <path>` | 覆盖运行时 session 文件路径 |\n| `--json` | 输出稳定的机器可读 JSON |\n| `--pretty` | 输出缩进 JSON；隐含 `--json` |\n\n全局参数可以放在命令词之前或之后。\n\n## 输出与退出行为\n\n交互命令默认输出人类可读文本。字段名保持不变，便于准确识别值：\n\n```text\nSuccess\nname: Example project\npath: /projects/example\n```\n\n失败时直接显示稳定错误码，不再默认包裹整段 JSON：\n\n```text\nError [INVALID_INPUT]: Unknown option \"--paht\". Did you mean --path?\n```\n\n当输出需要被解析、传输或作为稳定自动化结果保存时，添加 `--json`。JSON 执行成功：\n\n```json\n{\"ok\":true,\"data\":{}}\n```\n\n执行失败：\n\n```json\n{\"ok\":false,\"error\":{\"code\":\"ERROR_CODE\",\"message\":\"Description\",\"details\":{}}}\n```\n\n`details` 是可选字段。`--pretty` 隐含 `--json`，只改变缩进。`rpc --stdin` 与 `--help-json` 是机器接口，因此始终输出 JSON。无效命令输入以状态码 2 退出；后端错误或断言失败以状态码 1 退出。\n\n## 路径、写入与受保护操作\n\n- 普通项目文件与脚本源码的读取、搜索、创建、patch、重命名和删除应使用编码 Agent 的原生文件工具。\n- 写入目标和脚本使用项目内的 `res://` 路径。读取或实例化现有场景/资源的命令也接受 `uid://` 引用，并通过 Godot UID 缓存解析。\n- 普通词法路径穿越会被拒绝；这是项目边界检查，不是操作系统级沙箱。\n- 对写风险命令先使用 `--dry-run`，检查 `planned_changes`（使用 `--json` 时为 `data.planned_changes`），再移除 `--dry-run` 执行。\n- `--dry-run` 用于受支持的写入；它不会使进程或运行时执行命令变成空操作。\n- 受保护操作需要显式匹配的 `--allow` 值，应根据策略错误和命令 schema 操作，而不是猜测。\n- 对重要项目保留源码管理或备份；预览不等于备份。\n\n## 运行时生命周期与边界\n\n`process run` 默认以无头模式启动 Godot，并在所选项目下（或 `--session` 指定位置）保存经过认证的 loopback session。运行时命令必须使用相同的项目/session。即使测试失败，也应在清理阶段调用 `process stop`。\n\n当前公共命令有以下明确边界：\n\n- `scene read` 默认最多读取 4 层、200 个节点，并返回 `truncated`/`node_count`。可用 `--node`、`--depth`、`--limit` 缩小或扩大读取范围；只看层级时使用 `--include-properties false`。\n- 默认无头运行时可报告 viewport 尺寸以及可见 Control 的 bounds/focus，但 Godot 的 dummy renderer 无法捕获像素。在具备显示服务和渲染驱动的环境中，可先用 `process run --headless false` 启动，再调用 `runtime screenshot`；否则会返回 `SCREENSHOT_UNAVAILABLE`。\n- `runtime call` 和 `script run` 分别要求 `--allow call_method` 与 `--allow script_run`。脚本执行只接受项目内 `res://` 且继承 `SceneTree` 的脚本，不提供任意源码 eval。\n- 实时编辑器 selection、Inspector、原生 Undo/Redo、导入队列和未保存的内存场景不由 headless/runtime session 表示。\n- 路径在应用层受到边界限制；处理不可信项目时，CLI 不能替代操作系统进程隔离。\n\n## Agent Skill\n\n仓库提供一个位于 `.agents/skills/using-godot-cli` 的路由 skill。它的 `SKILL.md` 保存共享规则，并仅在需要时路由到五类 reference：命令发现、场景/资源、脚本/文件、运行时测试或编辑器工作流。\n\n使用开放 Agent Skills CLI 列出或安装：\n\n```sh\nnpx skills add 4fuu/godot-cli --list\nnpx skills add 4fuu/godot-cli --skill using-godot-cli -y\n```\n\n从本地 checkout：\n\n```sh\nnpx skills add . --list\nnpx skills add . --skill using-godot-cli -y\n```\n\n## 开发与验证\n\n从源码构建：\n\n```sh\nnpm install\nnpm run build\nnode dist/cli.js commands\n```\n\n### 格式化\n\n先安装 [uv](https://docs.astral.sh/uv/) 以运行固定版本的 GDScript 格式化器，然后执行：\n\n```sh\nnpm run format\nnpm run format:check\n```\n\nPrettier 负责格式化 TypeScript、测试和 JSON；`gdformat` 4.5.0 负责格式化并检查\n`godot/` 下的 GDScript。\n\n### 验证\n\n```sh\nnpm test\nnpm run build\nnpm pack --dry-run\n```\n\n使用显式 Godot 二进制运行测试：\n\n```sh\nGODOT_BIN=/path/to/godot npm test\n```\n\n发布前至少验证：命令目录/schema 测试、项目边界、dry-run 不修改、skill 发现、包内容、场景 dry-run/read，以及 `process run` → `runtime state/tree` → `process stop` 生命周期。\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.zh-CN.md"}