Advisory guidance for using the experimental Unity CLI (the official `unity` command-line tool) alongside UnitySkills — cold-start a bound project without Unity Hub, probe editor liveness, launch with arguments, run headless tests, run one-shot batch automation, and build headlessly. Only applies when the project has been bound in the UnitySkills panel (Library/UnitySkills/cli_config.json exists with enabled:true). 实验性 Unity CLI(官方 unity 命令行工具)与 UnitySkills 协同的指导文档——免 Unity Hub 冷启动已绑定项目、探测编辑器存活、传参启动、无头测试、批处理运行、无头构建;仅当项目已在 UnitySkills 面板完成绑定(存在 Library/UnitySkills/cli_config.json 且 enabled:true)时适用。
npx skills add https://github.com/Besty0728/Unity-Skills --skill unity-cli
Advisory module — no REST skills. All commands here run in YOUR shell on the user's machine, not through the REST server. That is the point: they work while the Unity Editor is closed.
Before using anything below, check the binding config:
<projectRoot>/Library/UnitySkills/cli_config.json
enabled: false → Unity CLI is OFF for this project. Ignore this module entirely. Do not suggest installing the CLI unprompted; the user opts in via Window > UnitySkills → AI Config → Unity CLI Setup….enabled: true → use cliPath as the executable (it may not be on your PATH). Respect the per-feature switches in features:{
"schemaVersion": 1,
"enabled": true,
"cliPath": "/Users/me/.local/bin/unity",
"cliVersion": "1.0.0-beta.3",
"projectPath": "/path/to/Project",
"editorVersion": "6000.0.32f1",
"boundAt": "2026-07-26T09:00:00Z",
"features": { "coldStart": true, "openArgs": true, "cliTest": true, "cliRun": false, "cliBuild": false }
}
Configs written by older plugin versions may lack the cliRun / cliBuild keys — for these two, a missing key means OFF (the first three keys keep their original semantics). Both also default to off on fresh binds; the user enables them per project in the panel.
The global registry (~/.unity_skills/registry.json) also carries cliBound / cliPath per running instance — use it for liveness checks only, never as authorization: the ONLY thing that authorizes CLI use for a project is that project's own cli_config.json. Do not cold-start any project whose own config you have not read, even if it appears in the registry. Also note projectPath inside the config is a bind-time snapshot — the directory you actually found the config under is authoritative (helper get_cli_config() already rewrites it); never open the stored path if it differs from the real project root.
> Unity CLI is experimental (beta) and its command surface changes between releases — this document was verified against 1.0.0-beta.3; the official docs may lag behind the binary, so <cliPath> --help is always authoritative. If a command errors unexpectedly, run <cliPath> doctor --format json first (environment snapshot: CLI version, paths, auth state, installed editors, recent log lines; --tail <n> for more log) and re-check --help before retrying. Never modify the server or config to work around a CLI quirk.
features.coldStart)The one capability REST can never provide: starting the editor when it is not running.
<cliPath> status --format json # any editor instances running?
<cliPath> open "<projectPath>" --args -unityskills-coldstart
Always pass --args -unityskills-coldstart when cold-starting: the UnitySkills plugin detects this marker at editor startup and force-starts the REST server for this session, even if the user's Auto-start preference is off. Without the marker you depend on the user's saved preference. The marker is consumed once per editor session — it never overrides a mid-session manual stop.
Preflight — is the right editor even installed? open / test / run / build all resolve the editor from the project's ProjectVersion.txt. Before the first CLI launch of a session, confirm the bound editorVersion is actually installed:
<cliPath> editors -i --format json
If it is not installed, stop and tell the user — installing an editor is a large, system-changing operation that only the user decides on. Never run install, and never pass --allow-install (see DO NOT).
After launching, poll the UnitySkills REST server until ready (first import/compile can take minutes):
from unity_skills import wait_for_health
health = wait_for_health(timeout=600) # polls /health on ports 8090-8100
Liveness triage — prefer this over blind retry. When REST is unreachable:
~/.unity_skills/registry.json, find the entry whose path equals the project root, then test its pid (ps -p <pid> / Windows tasklist). Live pid → the editor is running but busy (Domain Reload / import) → keep the normal REST wait-and-retry; do not cold-start.<cliPath> status is supplementary, not authoritative: it only lists editor instances visible to the CLI (requires the Unity Pipeline package in the project). An empty table / non-zero exit does NOT mean the editor is closed — verified in practice: a running editor without the Pipeline package shows nothing.open, then wait_for_health.open a project whose editor is already running (live registry pid, or Library/UnityLockfile held) — Unity refuses a second instance on the same project.features.openArgs)<cliPath> open "<projectPath>" --args -openscene "Assets/Scenes/Main.unity"
Anything after --args is passed to the Unity Editor as standard command-line arguments. Useful to land in a known state (specific scene, custom -executeMethod). Only at launch time — for an already-running editor use REST scene_open instead.
features.cliTest)<cliPath> test "<projectPath>" --mode EditMode --filter <pattern> --output test-results.xml --timeout 1800
--mode <EditMode|PlayMode> — omit to run the editor's default test platform; cover both modes with two separate invocations.--filter <pattern> — only run tests whose names match.--output <path> — NUnit XML report (default test-results.xml).--timeout <seconds> (env UNITY_TEST_TIMEOUT) — kills the Unity process after N seconds; disabled by default, always set one for unattended runs.--, e.g. -- -nographics.0 all passed; 6 tests ran but at least one failed (introduced in the official 0.1.0-beta.7 release notes); any other non-zero = the command itself failed — check stderr, not the XML.Routing rule:
test_* skills.unity test (headless, NUnit XML output). Do not run unity test against a project whose editor is open.features.cliRun)One-shot batch automation on the bound project only, while the editor is closed — the third lifecycle option between REST (editor open, interactive) and cold start (launch and keep serving):
<cliPath> run "<projectPath>" --timeout 1800 -- -executeMethod Your.Static.Method -quit
-- is forwarded to the Unity Editor as standard command-line arguments; -executeMethod <static method> plus -quit is the typical shape (asset re-import, batch fixes, custom pipelines).--timeout <seconds> (env UNITY_RUN_TIMEOUT) — disabled by default; always set one, a hung batch editor otherwise blocks your shell forever.run (Unity refuses a second instance on the same project — same Library/UnityLockfile rule as cold start). Editor closed + persistent session needed → cold start. Editor closed + one-shot task → run.run --command <name> — that drives Unity Pipeline package commands, which is not part of the UnitySkills workflow (see DO NOT).features.cliBuild)<cliPath> build "<projectPath>" --target StandaloneWindows64 --execute-method Builder.PerformBuild --output-path ./Builds/win64
--target and --execute-method are both required — Unity has no built-in command-line build; the bound project must already contain a static build method. If it does not, tell the user instead of writing one into their project unasked.--output-path is forwarded to Unity as -buildOutput; the execute-method itself is responsible for reading it.--no-tail to disable); the full log lands at <project>/Logs/build-<target>-<timestamp>.log unless --log-file overrides it.build refuses to run with uncommitted changes. That protection is deliberate — pass --allow-dirty-build only when the user explicitly says so.--versioning-strategy <semantic|tag|custom|none> (default none) stamps the build version from git tags/history; --build-version applies only with custom.--android-export-type <apk|aab|android-studio-project> plus keystore/signing flags exist, but the CLI's own help warns that secrets passed as CLI arguments can leak into shell history and CI logs — let the user handle signing configuration themselves; never ask them to paste keystore passwords into your shell commands.run: bound project only, editor must be closed, and once the editor is up again all normal operations go back through REST.--format <human|json|tsv|ndjson> (env UNITY_FORMAT); --json is shorthand for --format json. When stdout is piped the default silently becomes TSV — one more reason to always pass --format json explicitly. JSON responses use a standard envelope {success, command, data, errors, warnings}; ndjson streams progress events for long-running commands.--non-interactive (env UNITY_NON_INTERACTIVE) turns prompts into hard errors instead of hanging your shell; combine with --quiet (env UNITY_QUIET) and --no-banner (env UNITY_NO_BANNER) for clean machine output. Exporting the env vars once (UNITY_FORMAT=json, UNITY_NON_INTERACTIVE=1) covers a whole scripted session.0 success, 1 generic error (read stderr), 130 cancelled by user, 6 = test finished with failing tests.--verbose adds full error details with stack traces — useful once, when reporting a CLI problem to the user.cli_config.json is absent or enabled:false — the user has not opted in. Operate only on the bound project (the directory you found the config under); never open / test / run / build any other project.--allow-install (accepted by test / run / build), and do not use unity install / uninstall / hub / license commands unless the user explicitly asks — installing or removing editors is a large, slow, system-changing operation that belongs to the user alone.unity mcp — it starts a blocking stdio MCP server and waits for a client, hanging your shell.unity command / unity pipeline / unity run --command — the Unity Pipeline package route duplicates what UnitySkills REST already provides and is not part of this workflow.unity language, e.g. Chinese table headers) — always pass --format json --non-interactive when you need to read results programmatically./health responds, all normal operations go through REST skills.Exact names, parameters, defaults, and returns are defined by GET /skills/schema or unity_skills.get_skill_schema(), not by this file.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Comprehensive GitHub release orchestration with AI swarm coordination for automated versioning, testing, deployment, and rollback management
Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.
Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun.
You are a dependency management expert specializing in safe, incremental upgrades of project dependencies. Plan and execute dependency updates with minimal risk, proper testing, and clear migration pa
Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently track down bugs across any codebase or technology stack. Use when investigating bugs, performance issues, or unexpected behavior.
Opinionated backend development standards for Node.js + Express + TypeScript microservices. Covers layered architecture, BaseController pattern, dependency injection, Prisma repositories, Zod validation, unifiedConfig, Sentry error tracking, async safety, and testing discipline.
Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns.
Take besty0728/unity-cli from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.