uloop-cli 0.48.4 → 0.49.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/cli.bundle.cjs +211 -22
- package/dist/cli.bundle.cjs.map +3 -3
- package/jest.config.cjs +2 -1
- package/md-transformer.cjs +11 -0
- package/package.json +1 -1
- package/scripts/generate-bundled-skills.ts +87 -31
- package/src/__tests__/cli-e2e.test.ts +76 -10
- package/src/__tests__/skills-manager.test.ts +158 -0
- package/src/cli.ts +44 -2
- package/src/default-tools.json +1 -1
- package/src/skills/bundled-skills.ts +19 -16
- package/src/skills/skill-definitions/cli-only/uloop-get-version/SKILL.md +37 -0
- package/src/skills/skills-manager.ts +232 -9
- package/src/version.ts +1 -1
- package/CLAUDE.md +0 -61
- package/src/skills/skill-definitions/uloop-capture-unity-window/SKILL.md +0 -81
- package/src/skills/skill-definitions/uloop-clear-console/SKILL.md +0 -34
- package/src/skills/skill-definitions/uloop-compile/SKILL.md +0 -47
- package/src/skills/skill-definitions/uloop-control-play-mode/SKILL.md +0 -48
- package/src/skills/skill-definitions/uloop-execute-dynamic-code/SKILL.md +0 -79
- package/src/skills/skill-definitions/uloop-execute-menu-item/SKILL.md +0 -43
- package/src/skills/skill-definitions/uloop-find-game-objects/SKILL.md +0 -46
- package/src/skills/skill-definitions/uloop-focus-window/SKILL.md +0 -34
- package/src/skills/skill-definitions/uloop-get-hierarchy/SKILL.md +0 -44
- package/src/skills/skill-definitions/uloop-get-logs/SKILL.md +0 -45
- package/src/skills/skill-definitions/uloop-get-menu-items/SKILL.md +0 -44
- package/src/skills/skill-definitions/uloop-get-provider-details/SKILL.md +0 -45
- package/src/skills/skill-definitions/uloop-get-version/SKILL.md +0 -32
- package/src/skills/skill-definitions/uloop-run-tests/SKILL.md +0 -43
- package/src/skills/skill-definitions/uloop-unity-search/SKILL.md +0 -44
- /package/src/skills/skill-definitions/{uloop-get-project-info → cli-only/uloop-get-project-info}/SKILL.md +0 -0
package/dist/cli.bundle.cjs
CHANGED
|
@@ -5621,7 +5621,7 @@ var import_path3 = require("path");
|
|
|
5621
5621
|
|
|
5622
5622
|
// src/default-tools.json
|
|
5623
5623
|
var default_tools_default = {
|
|
5624
|
-
version: "0.
|
|
5624
|
+
version: "0.49.0",
|
|
5625
5625
|
tools: [
|
|
5626
5626
|
{
|
|
5627
5627
|
name: "compile",
|
|
@@ -6042,7 +6042,7 @@ function getCacheFilePath() {
|
|
|
6042
6042
|
}
|
|
6043
6043
|
|
|
6044
6044
|
// src/version.ts
|
|
6045
|
-
var VERSION = "0.
|
|
6045
|
+
var VERSION = "0.49.0";
|
|
6046
6046
|
|
|
6047
6047
|
// src/spinner.ts
|
|
6048
6048
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -6333,46 +6333,46 @@ var import_fs4 = require("fs");
|
|
|
6333
6333
|
var import_path5 = require("path");
|
|
6334
6334
|
var import_os = require("os");
|
|
6335
6335
|
|
|
6336
|
-
//
|
|
6336
|
+
// ../Editor/Api/McpTools/CaptureUnityWindow/SKILL.md
|
|
6337
6337
|
var SKILL_default = '---\nname: uloop-capture-unity-window\ndescription: Capture Unity EditorWindow and save as PNG image. Use when you need to: (1) Take a screenshot of Game View, Scene View, Console, Inspector, etc., (2) Capture visual state for debugging or verification, (3) Save editor output as an image file.\n---\n\n# uloop capture-unity-window\n\nCapture any Unity EditorWindow by name and save as PNG image.\n\n## Usage\n\n```bash\nuloop capture-unity-window [--window-name <name>] [--resolution-scale <scale>]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--window-name` | string | `Game` | Window name to capture (e.g., "Game", "Scene", "Console", "Inspector", "Project", "Hierarchy", or any EditorWindow title) |\n| `--resolution-scale` | number | `1.0` | Resolution scale (0.1 to 1.0) |\n\n## Window Name\n\nThe window name is the text displayed in the window\'s title bar (tab). The user (human) will tell you which window to capture. Common window names include:\n\n- **Game**: Game View window\n- **Scene**: Scene View window\n- **Console**: Console window\n- **Inspector**: Inspector window\n- **Project**: Project browser window\n- **Hierarchy**: Hierarchy window\n- **Animation**: Animation window\n- **Animator**: Animator window\n- **Profiler**: Profiler window\n- **Audio Mixer**: Audio Mixer window\n\nYou can also specify custom EditorWindow titles (e.g., "EditorWindow Capture Test").\n\n## Examples\n\n```bash\n# Capture Game View at full resolution\nuloop capture-unity-window\n\n# Capture Game View at half resolution\nuloop capture-unity-window --window-name Game --resolution-scale 0.5\n\n# Capture Scene View\nuloop capture-unity-window --window-name Scene\n\n# Capture Console window\nuloop capture-unity-window --window-name Console\n\n# Capture Inspector window\nuloop capture-unity-window --window-name Inspector\n\n# Capture Project browser\nuloop capture-unity-window --window-name Project\n\n# Capture custom EditorWindow by title\nuloop capture-unity-window --window-name "My Custom Window"\n```\n\n## Output\n\nReturns JSON with:\n- `CapturedCount`: Number of windows captured\n- `CapturedWindows`: Array of captured window info, each containing:\n - `ImagePath`: Absolute path to the saved PNG image\n - `FileSizeBytes`: Size of the saved file in bytes\n - `Width`: Captured image width in pixels\n - `Height`: Captured image height in pixels\n\nWhen multiple windows of the same type are open (e.g., multiple Inspector windows), all matching windows are captured with numbered filenames (e.g., `Inspector_1_*.png`, `Inspector_2_*.png`).\n\n## Notes\n\n- Use `uloop focus-window` first if needed\n- Target window must be open in Unity Editor\n- Window name matching is case-insensitive\n';
|
|
6338
6338
|
|
|
6339
|
-
//
|
|
6339
|
+
// ../Editor/Api/McpTools/ClearConsole/SKILL.md
|
|
6340
6340
|
var SKILL_default2 = "---\nname: uloop-clear-console\ndescription: Clear Unity console logs via uloop CLI. Use when you need to: (1) Clear the console before running tests, (2) Start a fresh debugging session, (3) Clean up log output for better readability.\n---\n\n# uloop clear-console\n\nClear Unity console logs.\n\n## Usage\n\n```bash\nuloop clear-console [--add-confirmation-message]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--add-confirmation-message` | boolean | `false` | Add confirmation message after clearing |\n\n## Examples\n\n```bash\n# Clear console\nuloop clear-console\n\n# Clear with confirmation\nuloop clear-console --add-confirmation-message\n```\n\n## Output\n\nReturns JSON confirming the console was cleared.\n";
|
|
6341
6341
|
|
|
6342
|
-
//
|
|
6342
|
+
// ../Editor/Api/McpTools/Compile/SKILL.md
|
|
6343
6343
|
var SKILL_default3 = '---\nname: uloop-compile\ndescription: Compile Unity project via uloop CLI. Use when you need to: (1) Verify C# code compiles successfully after editing scripts, (2) Check for compile errors or warnings, (3) Validate script changes before running tests.\n---\n\n# uloop compile\n\nExecute Unity project compilation.\n\n## Usage\n\n```bash\nuloop compile [--force-recompile]\n```\n\n## Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `--force-recompile` | boolean | Force full recompilation (triggers Domain Reload) |\n\n## Examples\n\n```bash\n# Check compilation\nuloop compile\n\n# Force full recompilation\nuloop compile --force-recompile\n```\n\n## Output\n\nReturns JSON:\n- `Success`: boolean\n- `ErrorCount`: number\n- `WarningCount`: number\n\n## Troubleshooting\n\nIf CLI hangs or shows "Unity is busy" errors after compilation, stale lock files may be preventing connection. Run the following to clean them up:\n\n```bash\nuloop fix\n```\n\nThis removes any leftover lock files (`compiling.lock`, `domainreload.lock`, `serverstarting.lock`) from the Unity project\'s Temp directory.\n';
|
|
6344
6344
|
|
|
6345
|
-
//
|
|
6346
|
-
var SKILL_default4 = "---\nname: uloop-control-play-mode\ndescription: Control Unity Editor play mode via uloop CLI. Use when you need to: (1) Start play mode for testing, (2) Stop play mode after testing, (3) Pause play mode for debugging.\n---\n\n# uloop control-play-mode\n\nControl Unity Editor play mode (play/stop/pause).\n\n## Usage\n\n```bash\nuloop control-play-mode [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--action` | string | `Play` | Action to perform: `Play`, `Stop`, `Pause` |\n\n## Examples\n\n```bash\n# Start play mode\nuloop control-play-mode --action Play\n\n# Stop play mode\nuloop control-play-mode --action Stop\n\n# Pause play mode\nuloop control-play-mode --action Pause\n```\n\n## Output\n\nReturns JSON with the current play mode state:\n- `IsPlaying`: Whether Unity is currently in play mode\n- `IsPaused`: Whether play mode is paused\n- `Message`: Description of the action performed\n\n## Notes\n\n- Play action starts the game in the Unity Editor (also resumes from pause)\n- Stop action exits play mode and returns to edit mode\n- Pause action pauses the game while remaining in play mode\n- Useful for automated testing workflows\n
|
|
6345
|
+
// ../Editor/Api/McpTools/ControlPlayMode/SKILL.md
|
|
6346
|
+
var SKILL_default4 = "---\nname: uloop-control-play-mode\ndescription: Control Unity Editor play mode via uloop CLI. Use when you need to: (1) Start play mode for testing, (2) Stop play mode after testing, (3) Pause play mode for debugging.\n---\n\n# uloop control-play-mode\n\nControl Unity Editor play mode (play/stop/pause).\n\n## Usage\n\n```bash\nuloop control-play-mode [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--action` | string | `Play` | Action to perform: `Play`, `Stop`, `Pause` |\n\n## Examples\n\n```bash\n# Start play mode\nuloop control-play-mode --action Play\n\n# Stop play mode\nuloop control-play-mode --action Stop\n\n# Pause play mode\nuloop control-play-mode --action Pause\n```\n\n## Output\n\nReturns JSON with the current play mode state:\n- `IsPlaying`: Whether Unity is currently in play mode\n- `IsPaused`: Whether play mode is paused\n- `Message`: Description of the action performed\n\n## Notes\n\n- Play action starts the game in the Unity Editor (also resumes from pause)\n- Stop action exits play mode and returns to edit mode\n- Pause action pauses the game while remaining in play mode\n- Useful for automated testing workflows\n";
|
|
6347
6347
|
|
|
6348
|
-
//
|
|
6348
|
+
// ../Editor/Api/McpTools/ExecuteDynamicCode/SKILL.md
|
|
6349
6349
|
var SKILL_default5 = "---\nname: uloop-execute-dynamic-code\ndescription: Execute C# code dynamically in Unity Editor via uloop CLI. Use for editor automation: (1) Prefab/material wiring and AddComponent operations, (2) Reference wiring with SerializedObject, (3) Scene/hierarchy edits and batch operations. NOT for file I/O or script authoring.\n---\n\n# uloop execute-dynamic-code\n\nExecute C# code dynamically in Unity Editor.\n\n## Usage\n\n```bash\nuloop execute-dynamic-code --code '<c# code>'\n```\n\n## Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `--code` | string | C# code to execute (direct statements, no class wrapper) |\n| `--compile-only` | boolean | Compile without execution |\n| `--auto-qualify-unity-types-once` | boolean | Auto-qualify Unity types |\n\n## Code Format\n\nWrite direct statements only (no classes/namespaces/methods). Return is optional.\n\n```csharp\n// Using directives at top are hoisted\nusing UnityEngine;\nvar x = Mathf.PI;\nreturn x;\n```\n\n## String Literals (Shell-specific)\n\n| Shell | Method |\n|-------|--------|\n| bash/zsh/MINGW64/Git Bash | `'Debug.Log(\"Hello!\");'` |\n| PowerShell | `'Debug.Log(\"\"Hello!\"\");'` |\n\n## Allowed Operations\n\n- Prefab/material wiring (PrefabUtility)\n- AddComponent + reference wiring (SerializedObject)\n- Scene/hierarchy edits\n- Inspector modifications\n\n## Forbidden Operations\n\n- System.IO.* (File/Directory/Path)\n- AssetDatabase.CreateFolder / file writes\n- Create/edit .cs/.asmdef files\n\n## Examples\n\n### bash / zsh / MINGW64 / Git Bash\n\n```bash\nuloop execute-dynamic-code --code 'return Selection.activeGameObject?.name;'\nuloop execute-dynamic-code --code 'new GameObject(\"MyObject\");'\nuloop execute-dynamic-code --code 'UnityEngine.Debug.Log(\"Hello from CLI!\");'\n```\n\n### PowerShell\n\n```powershell\nuloop execute-dynamic-code --code 'return Selection.activeGameObject?.name;'\nuloop execute-dynamic-code --code 'new GameObject(\"\"MyObject\"\");'\nuloop execute-dynamic-code --code 'UnityEngine.Debug.Log(\"\"Hello from CLI!\"\");'\n```\n\n## Output\n\nReturns JSON with execution result or compile errors.\n\n## Notes\n\nFor file/directory operations, use terminal commands instead.\n";
|
|
6350
6350
|
|
|
6351
|
-
//
|
|
6351
|
+
// ../Editor/Api/McpTools/ExecuteMenuItem/SKILL.md
|
|
6352
6352
|
var SKILL_default6 = '---\nname: uloop-execute-menu-item\ndescription: Execute Unity MenuItem via uloop CLI. Use when you need to: (1) Trigger menu commands programmatically, (2) Automate editor actions (save, build, refresh), (3) Run custom menu items defined in scripts.\n---\n\n# uloop execute-menu-item\n\nExecute Unity MenuItem.\n\n## Usage\n\n```bash\nuloop execute-menu-item --menu-item-path "<path>"\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--menu-item-path` | string | - | Menu item path (e.g., "GameObject/Create Empty") |\n| `--use-reflection-fallback` | boolean | `true` | Use reflection fallback |\n\n## Examples\n\n```bash\n# Create empty GameObject\nuloop execute-menu-item --menu-item-path "GameObject/Create Empty"\n\n# Save scene\nuloop execute-menu-item --menu-item-path "File/Save"\n\n# Open project settings\nuloop execute-menu-item --menu-item-path "Edit/Project Settings..."\n```\n\n## Output\n\nReturns JSON with execution result.\n\n## Notes\n\n- Use `uloop get-menu-items` to discover available menu paths\n- Some menu items may require specific context or selection\n';
|
|
6353
6353
|
|
|
6354
|
-
//
|
|
6354
|
+
// ../Editor/Api/McpTools/FindGameObjects/SKILL.md
|
|
6355
6355
|
var SKILL_default7 = '---\nname: uloop-find-game-objects\ndescription: Find GameObjects with search criteria via uloop CLI. Use when you need to: (1) Locate GameObjects by name pattern, (2) Find objects by tag or layer, (3) Search for objects with specific component types.\n---\n\n# uloop find-game-objects\n\nFind GameObjects with search criteria.\n\n## Usage\n\n```bash\nuloop find-game-objects [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--name-pattern` | string | - | Name pattern to search |\n| `--search-mode` | string | `Contains` | Search mode: `Exact`, `Path`, `Regex`, `Contains` |\n| `--required-components` | array | - | Required components |\n| `--tag` | string | - | Tag filter |\n| `--layer` | string | - | Layer filter |\n| `--max-results` | integer | `20` | Maximum number of results |\n| `--include-inactive` | boolean | `false` | Include inactive GameObjects |\n\n## Examples\n\n```bash\n# Find by name\nuloop find-game-objects --name-pattern "Player"\n\n# Find with component\nuloop find-game-objects --required-components Rigidbody\n\n# Find by tag\nuloop find-game-objects --tag "Enemy"\n\n# Regex search\nuloop find-game-objects --name-pattern "UI_.*" --search-mode Regex\n```\n\n## Output\n\nReturns JSON array of matching GameObjects with paths and components.\n';
|
|
6356
6356
|
|
|
6357
|
-
//
|
|
6357
|
+
// ../Editor/Api/McpTools/FocusUnityWindow/SKILL.md
|
|
6358
6358
|
var SKILL_default8 = "---\nname: uloop-focus-window\ndescription: Bring Unity Editor window to front via uloop CLI. Use when you need to: (1) Focus Unity Editor before capturing screenshots, (2) Ensure Unity window is visible for visual checks, (3) Bring Unity to foreground for user interaction.\n---\n\n# uloop focus-window\n\nBring Unity Editor window to front.\n\n## Usage\n\n```bash\nuloop focus-window\n```\n\n## Parameters\n\nNone.\n\n## Examples\n\n```bash\n# Focus Unity Editor\nuloop focus-window\n```\n\n## Output\n\nReturns JSON confirming the window was focused.\n\n## Notes\n\n- Useful before `uloop capture-unity-window` to ensure the target window is visible\n- Brings the main Unity Editor window to the foreground\n";
|
|
6359
6359
|
|
|
6360
|
-
//
|
|
6360
|
+
// ../Editor/Api/McpTools/GetHierarchy/SKILL.md
|
|
6361
6361
|
var SKILL_default9 = '---\nname: uloop-get-hierarchy\ndescription: Get Unity Hierarchy structure via uloop CLI. Use when you need to: (1) Inspect scene structure and GameObject tree, (2) Find GameObjects and their parent-child relationships, (3) Check component attachments on objects.\n---\n\n# uloop get-hierarchy\n\nGet Unity Hierarchy structure.\n\n## Usage\n\n```bash\nuloop get-hierarchy [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--root-path` | string | - | Root GameObject path to start from |\n| `--max-depth` | integer | `-1` | Maximum depth (-1 for unlimited) |\n| `--include-components` | boolean | `true` | Include component information |\n| `--include-inactive` | boolean | `true` | Include inactive GameObjects |\n| `--include-paths` | boolean | `false` | Include full path information |\n\n## Examples\n\n```bash\n# Get entire hierarchy\nuloop get-hierarchy\n\n# Get hierarchy from specific root\nuloop get-hierarchy --root-path "Canvas/UI"\n\n# Limit depth\nuloop get-hierarchy --max-depth 2\n\n# Without components\nuloop get-hierarchy --include-components false\n```\n\n## Output\n\nReturns JSON with hierarchical structure of GameObjects and their components.\n';
|
|
6362
6362
|
|
|
6363
|
-
//
|
|
6363
|
+
// ../Editor/Api/McpTools/GetLogs/SKILL.md
|
|
6364
6364
|
var SKILL_default10 = '---\nname: uloop-get-logs\ndescription: Retrieve Unity Console logs via uloop CLI. Use when you need to: (1) Check for errors or warnings after operations, (2) Debug runtime issues in Unity Editor, (3) Investigate unexpected behavior or exceptions.\n---\n\n# uloop get-logs\n\nRetrieve logs from Unity Console.\n\n## Usage\n\n```bash\nuloop get-logs [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--log-type` | string | `All` | Log type filter: `Error`, `Warning`, `Log`, `All` |\n| `--max-count` | integer | `100` | Maximum number of logs to retrieve |\n| `--search-text` | string | - | Text to search within logs |\n| `--include-stack-trace` | boolean | `true` | Include stack trace in output |\n| `--use-regex` | boolean | `false` | Use regex for search |\n| `--search-in-stack-trace` | boolean | `false` | Search within stack trace |\n\n## Examples\n\n```bash\n# Get all logs\nuloop get-logs\n\n# Get only errors\nuloop get-logs --log-type Error\n\n# Search for specific text\nuloop get-logs --search-text "NullReference"\n\n# Regex search\nuloop get-logs --search-text "Missing.*Component" --use-regex\n```\n\n## Output\n\nReturns JSON array of log entries with message, type, and optional stack trace.\n';
|
|
6365
6365
|
|
|
6366
|
-
//
|
|
6366
|
+
// ../Editor/Api/McpTools/GetMenuItems/SKILL.md
|
|
6367
6367
|
var SKILL_default11 = '---\nname: uloop-get-menu-items\ndescription: Retrieve Unity MenuItems via uloop CLI. Use when you need to: (1) Discover available menu commands in Unity Editor, (2) Find menu paths for automation, (3) Prepare for executing menu items programmatically.\n---\n\n# uloop get-menu-items\n\nRetrieve Unity MenuItems.\n\n## Usage\n\n```bash\nuloop get-menu-items [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--filter-text` | string | - | Filter text |\n| `--filter-type` | string | `contains` | Filter type: `contains`, `exact`, `startswith` |\n| `--max-count` | integer | `200` | Maximum number of items |\n| `--include-validation` | boolean | `false` | Include validation functions |\n\n## Examples\n\n```bash\n# List all menu items\nuloop get-menu-items\n\n# Filter by text\nuloop get-menu-items --filter-text "GameObject"\n\n# Exact match\nuloop get-menu-items --filter-text "File/Save" --filter-type exact\n```\n\n## Output\n\nReturns JSON array of menu items with paths and metadata.\n\n## Notes\n\nUse with `uloop execute-menu-item` to run discovered menu commands.\n';
|
|
6368
6368
|
|
|
6369
|
-
//
|
|
6369
|
+
// ../Editor/Api/McpTools/UnitySearchProviderDetails/SKILL.md
|
|
6370
6370
|
var SKILL_default12 = "---\nname: uloop-get-provider-details\ndescription: Get Unity Search provider details via uloop CLI. Use when you need to: (1) Discover available search providers, (2) Understand search capabilities and filters, (3) Configure searches with specific provider options.\n---\n\n# uloop get-provider-details\n\nGet detailed information about Unity Search providers.\n\n## Usage\n\n```bash\nuloop get-provider-details [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--provider-id` | string | - | Specific provider ID to query |\n| `--active-only` | boolean | `false` | Only show active providers |\n| `--include-descriptions` | boolean | `true` | Include descriptions |\n| `--sort-by-priority` | boolean | `true` | Sort by priority |\n\n## Examples\n\n```bash\n# List all providers\nuloop get-provider-details\n\n# Get specific provider\nuloop get-provider-details --provider-id asset\n\n# Active providers only\nuloop get-provider-details --active-only\n```\n\n## Output\n\nReturns JSON:\n- `Providers`: array of provider info (ID, name, description, priority)\n\n## Notes\n\nUse provider IDs with `uloop unity-search --providers` option.\n";
|
|
6371
6371
|
|
|
6372
|
-
//
|
|
6372
|
+
// ../Editor/Api/McpTools/RunTests/SKILL.md
|
|
6373
6373
|
var SKILL_default13 = '---\nname: uloop-run-tests\ndescription: Execute Unity Test Runner via uloop CLI. Use when you need to: (1) Run unit tests (EditMode tests), (2) Run integration tests (PlayMode tests), (3) Verify code changes don\'t break existing functionality.\n---\n\n# uloop run-tests\n\nExecute Unity Test Runner.\n\n## Usage\n\n```bash\nuloop run-tests [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--test-mode` | string | `EditMode` | Test mode: `EditMode`, `PlayMode` |\n| `--filter-type` | string | `all` | Filter type: `all`, `exact`, `regex`, `assembly` |\n| `--filter-value` | string | - | Filter value (test name, pattern, or assembly) |\n| `--save-xml` | boolean | `false` | Save test results as XML |\n\n## Examples\n\n```bash\n# Run all EditMode tests\nuloop run-tests\n\n# Run PlayMode tests\nuloop run-tests --test-mode PlayMode\n\n# Run specific test\nuloop run-tests --filter-type exact --filter-value "MyTest.TestMethod"\n\n# Run tests matching pattern\nuloop run-tests --filter-type regex --filter-value ".*Integration.*"\n```\n\n## Output\n\nReturns JSON with test results including pass/fail counts and details.\n';
|
|
6374
6374
|
|
|
6375
|
-
//
|
|
6375
|
+
// ../Editor/Api/McpTools/UnitySearch/SKILL.md
|
|
6376
6376
|
var SKILL_default14 = '---\nname: uloop-unity-search\ndescription: Search Unity project via uloop CLI. Use when you need to: (1) Find assets by name or type (scenes, prefabs, scripts, materials), (2) Search for project resources using Unity\'s search system, (3) Locate files within the Unity project.\n---\n\n# uloop unity-search\n\nSearch Unity project using Unity Search.\n\n## Usage\n\n```bash\nuloop unity-search [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--search-query` | string | - | Search query |\n| `--providers` | array | - | Search providers (e.g., `asset`, `scene`, `find`) |\n| `--max-results` | integer | `50` | Maximum number of results |\n| `--save-to-file` | boolean | `false` | Save results to file |\n\n## Examples\n\n```bash\n# Search for assets\nuloop unity-search --search-query "Player"\n\n# Search with specific provider\nuloop unity-search --search-query "t:Prefab" --providers asset\n\n# Limit results\nuloop unity-search --search-query "*.cs" --max-results 20\n```\n\n## Output\n\nReturns JSON array of search results with paths and metadata.\n\n## Notes\n\nUse `uloop get-provider-details` to discover available search providers.\n';
|
|
6377
6377
|
|
|
6378
6378
|
// src/skills/bundled-skills.ts
|
|
@@ -6450,6 +6450,7 @@ var BUNDLED_SKILLS = [
|
|
|
6450
6450
|
];
|
|
6451
6451
|
|
|
6452
6452
|
// src/skills/skills-manager.ts
|
|
6453
|
+
var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "Temp", "obj", "Build", "Builds", "Logs"]);
|
|
6453
6454
|
function getGlobalSkillsDir(target) {
|
|
6454
6455
|
return (0, import_path5.join)((0, import_os.homedir)(), target.projectDir, "skills");
|
|
6455
6456
|
}
|
|
@@ -6481,12 +6482,125 @@ function getSkillStatus(skill, target, global) {
|
|
|
6481
6482
|
}
|
|
6482
6483
|
return "installed";
|
|
6483
6484
|
}
|
|
6485
|
+
function parseFrontmatter(content) {
|
|
6486
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6487
|
+
if (!frontmatterMatch) {
|
|
6488
|
+
return {};
|
|
6489
|
+
}
|
|
6490
|
+
const frontmatter = {};
|
|
6491
|
+
const lines = frontmatterMatch[1].split("\n");
|
|
6492
|
+
for (const line of lines) {
|
|
6493
|
+
const colonIndex = line.indexOf(":");
|
|
6494
|
+
if (colonIndex === -1) {
|
|
6495
|
+
continue;
|
|
6496
|
+
}
|
|
6497
|
+
const key = line.slice(0, colonIndex).trim();
|
|
6498
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
6499
|
+
if (value === "true") {
|
|
6500
|
+
frontmatter[key] = true;
|
|
6501
|
+
} else if (value === "false") {
|
|
6502
|
+
frontmatter[key] = false;
|
|
6503
|
+
} else {
|
|
6504
|
+
frontmatter[key] = value;
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6507
|
+
return frontmatter;
|
|
6508
|
+
}
|
|
6509
|
+
function scanEditorFolderForSkills(editorPath, skills) {
|
|
6510
|
+
if (!(0, import_fs4.existsSync)(editorPath)) {
|
|
6511
|
+
return;
|
|
6512
|
+
}
|
|
6513
|
+
const entries = (0, import_fs4.readdirSync)(editorPath, { withFileTypes: true });
|
|
6514
|
+
for (const entry of entries) {
|
|
6515
|
+
if (EXCLUDED_DIRS.has(entry.name)) {
|
|
6516
|
+
continue;
|
|
6517
|
+
}
|
|
6518
|
+
const fullPath = (0, import_path5.join)(editorPath, entry.name);
|
|
6519
|
+
if (entry.isDirectory()) {
|
|
6520
|
+
const skillMdPath = (0, import_path5.join)(fullPath, "SKILL.md");
|
|
6521
|
+
if ((0, import_fs4.existsSync)(skillMdPath)) {
|
|
6522
|
+
const content = (0, import_fs4.readFileSync)(skillMdPath, "utf-8");
|
|
6523
|
+
const frontmatter = parseFrontmatter(content);
|
|
6524
|
+
if (frontmatter.internal === true) {
|
|
6525
|
+
continue;
|
|
6526
|
+
}
|
|
6527
|
+
const name = typeof frontmatter.name === "string" ? frontmatter.name : entry.name;
|
|
6528
|
+
skills.push({
|
|
6529
|
+
name,
|
|
6530
|
+
dirName: name,
|
|
6531
|
+
content,
|
|
6532
|
+
sourcePath: skillMdPath
|
|
6533
|
+
});
|
|
6534
|
+
}
|
|
6535
|
+
scanEditorFolderForSkills(fullPath, skills);
|
|
6536
|
+
}
|
|
6537
|
+
}
|
|
6538
|
+
}
|
|
6539
|
+
function findEditorFolders(basePath, maxDepth = 2) {
|
|
6540
|
+
const editorFolders = [];
|
|
6541
|
+
function scan(currentPath, depth) {
|
|
6542
|
+
if (depth > maxDepth || !(0, import_fs4.existsSync)(currentPath)) {
|
|
6543
|
+
return;
|
|
6544
|
+
}
|
|
6545
|
+
const entries = (0, import_fs4.readdirSync)(currentPath, { withFileTypes: true });
|
|
6546
|
+
for (const entry of entries) {
|
|
6547
|
+
if (!entry.isDirectory() || EXCLUDED_DIRS.has(entry.name)) {
|
|
6548
|
+
continue;
|
|
6549
|
+
}
|
|
6550
|
+
const fullPath = (0, import_path5.join)(currentPath, entry.name);
|
|
6551
|
+
if (entry.name === "Editor") {
|
|
6552
|
+
editorFolders.push(fullPath);
|
|
6553
|
+
} else {
|
|
6554
|
+
scan(fullPath, depth + 1);
|
|
6555
|
+
}
|
|
6556
|
+
}
|
|
6557
|
+
}
|
|
6558
|
+
scan(basePath, 0);
|
|
6559
|
+
return editorFolders;
|
|
6560
|
+
}
|
|
6561
|
+
function collectProjectSkills() {
|
|
6562
|
+
const projectRoot = process.cwd();
|
|
6563
|
+
const skills = [];
|
|
6564
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
6565
|
+
const searchPaths = [
|
|
6566
|
+
(0, import_path5.join)(projectRoot, "Assets"),
|
|
6567
|
+
(0, import_path5.join)(projectRoot, "Packages"),
|
|
6568
|
+
(0, import_path5.join)(projectRoot, "Library", "PackageCache")
|
|
6569
|
+
];
|
|
6570
|
+
for (const searchPath of searchPaths) {
|
|
6571
|
+
if (!(0, import_fs4.existsSync)(searchPath)) {
|
|
6572
|
+
continue;
|
|
6573
|
+
}
|
|
6574
|
+
const editorFolders = findEditorFolders(searchPath, 3);
|
|
6575
|
+
for (const editorFolder of editorFolders) {
|
|
6576
|
+
scanEditorFolderForSkills(editorFolder, skills);
|
|
6577
|
+
}
|
|
6578
|
+
}
|
|
6579
|
+
const uniqueSkills = [];
|
|
6580
|
+
for (const skill of skills) {
|
|
6581
|
+
if (!seenNames.has(skill.name)) {
|
|
6582
|
+
seenNames.add(skill.name);
|
|
6583
|
+
uniqueSkills.push(skill);
|
|
6584
|
+
}
|
|
6585
|
+
}
|
|
6586
|
+
return uniqueSkills;
|
|
6587
|
+
}
|
|
6484
6588
|
function getAllSkillStatuses(target, global) {
|
|
6485
|
-
|
|
6589
|
+
const bundledStatuses = BUNDLED_SKILLS.map((skill) => ({
|
|
6590
|
+
name: skill.name,
|
|
6591
|
+
status: getSkillStatus(skill, target, global),
|
|
6592
|
+
path: isSkillInstalled(skill, target, global) ? getSkillPath(skill.dirName, target, global) : void 0,
|
|
6593
|
+
source: "bundled"
|
|
6594
|
+
}));
|
|
6595
|
+
const projectSkills = collectProjectSkills();
|
|
6596
|
+
const bundledNames = new Set(BUNDLED_SKILLS.map((s) => s.name));
|
|
6597
|
+
const projectStatuses = projectSkills.filter((skill) => !bundledNames.has(skill.name)).map((skill) => ({
|
|
6486
6598
|
name: skill.name,
|
|
6487
6599
|
status: getSkillStatus(skill, target, global),
|
|
6488
|
-
path: isSkillInstalled(skill, target, global) ? getSkillPath(skill.dirName, target, global) : void 0
|
|
6600
|
+
path: isSkillInstalled(skill, target, global) ? getSkillPath(skill.dirName, target, global) : void 0,
|
|
6601
|
+
source: "project"
|
|
6489
6602
|
}));
|
|
6603
|
+
return [...bundledStatuses, ...projectStatuses];
|
|
6490
6604
|
}
|
|
6491
6605
|
function installSkill(skill, target, global) {
|
|
6492
6606
|
const baseDir = global ? getGlobalSkillsDir(target) : getProjectSkillsDir(target);
|
|
@@ -6505,7 +6619,13 @@ function uninstallSkill(skill, target, global) {
|
|
|
6505
6619
|
return true;
|
|
6506
6620
|
}
|
|
6507
6621
|
function installAllSkills(target, global) {
|
|
6508
|
-
const result = {
|
|
6622
|
+
const result = {
|
|
6623
|
+
installed: 0,
|
|
6624
|
+
updated: 0,
|
|
6625
|
+
skipped: 0,
|
|
6626
|
+
bundledCount: 0,
|
|
6627
|
+
projectCount: 0
|
|
6628
|
+
};
|
|
6509
6629
|
for (const skill of BUNDLED_SKILLS) {
|
|
6510
6630
|
const status = getSkillStatus(skill, target, global);
|
|
6511
6631
|
if (status === "not_installed") {
|
|
@@ -6518,6 +6638,27 @@ function installAllSkills(target, global) {
|
|
|
6518
6638
|
result.skipped++;
|
|
6519
6639
|
}
|
|
6520
6640
|
}
|
|
6641
|
+
result.bundledCount = BUNDLED_SKILLS.length;
|
|
6642
|
+
const projectSkills = collectProjectSkills();
|
|
6643
|
+
const bundledNames = new Set(BUNDLED_SKILLS.map((s) => s.name));
|
|
6644
|
+
for (const skill of projectSkills) {
|
|
6645
|
+
if (bundledNames.has(skill.name)) {
|
|
6646
|
+
continue;
|
|
6647
|
+
}
|
|
6648
|
+
const status = getSkillStatus(skill, target, global);
|
|
6649
|
+
if (status === "not_installed") {
|
|
6650
|
+
installSkill(skill, target, global);
|
|
6651
|
+
result.installed++;
|
|
6652
|
+
result.projectCount++;
|
|
6653
|
+
} else if (status === "outdated") {
|
|
6654
|
+
installSkill(skill, target, global);
|
|
6655
|
+
result.updated++;
|
|
6656
|
+
result.projectCount++;
|
|
6657
|
+
} else {
|
|
6658
|
+
result.skipped++;
|
|
6659
|
+
result.projectCount++;
|
|
6660
|
+
}
|
|
6661
|
+
}
|
|
6521
6662
|
return result;
|
|
6522
6663
|
}
|
|
6523
6664
|
function uninstallAllSkills(target, global) {
|
|
@@ -6529,13 +6670,28 @@ function uninstallAllSkills(target, global) {
|
|
|
6529
6670
|
result.notFound++;
|
|
6530
6671
|
}
|
|
6531
6672
|
}
|
|
6673
|
+
const projectSkills = collectProjectSkills();
|
|
6674
|
+
const bundledNames = new Set(BUNDLED_SKILLS.map((s) => s.name));
|
|
6675
|
+
for (const skill of projectSkills) {
|
|
6676
|
+
if (bundledNames.has(skill.name)) {
|
|
6677
|
+
continue;
|
|
6678
|
+
}
|
|
6679
|
+
if (uninstallSkill(skill, target, global)) {
|
|
6680
|
+
result.removed++;
|
|
6681
|
+
} else {
|
|
6682
|
+
result.notFound++;
|
|
6683
|
+
}
|
|
6684
|
+
}
|
|
6532
6685
|
return result;
|
|
6533
6686
|
}
|
|
6534
6687
|
function getInstallDir(target, global) {
|
|
6535
6688
|
return global ? getGlobalSkillsDir(target) : getProjectSkillsDir(target);
|
|
6536
6689
|
}
|
|
6537
6690
|
function getTotalSkillCount() {
|
|
6538
|
-
|
|
6691
|
+
const projectSkills = collectProjectSkills();
|
|
6692
|
+
const bundledNames = new Set(BUNDLED_SKILLS.map((s) => s.name));
|
|
6693
|
+
const uniqueProjectCount = projectSkills.filter((s) => !bundledNames.has(s.name)).length;
|
|
6694
|
+
return BUNDLED_SKILLS.length + uniqueProjectCount;
|
|
6539
6695
|
}
|
|
6540
6696
|
|
|
6541
6697
|
// src/skills/target-config.ts
|
|
@@ -7092,7 +7248,40 @@ function listOptionsForCommand(cmdName) {
|
|
|
7092
7248
|
}
|
|
7093
7249
|
console.log(options.join("\n"));
|
|
7094
7250
|
}
|
|
7095
|
-
|
|
7251
|
+
function commandExists(cmdName) {
|
|
7252
|
+
if (BUILTIN_COMMANDS.includes(cmdName)) {
|
|
7253
|
+
return true;
|
|
7254
|
+
}
|
|
7255
|
+
const tools = loadToolsCache();
|
|
7256
|
+
return tools.tools.some((t) => t.name === cmdName);
|
|
7257
|
+
}
|
|
7258
|
+
async function main() {
|
|
7259
|
+
if (handleCompletionOptions()) {
|
|
7260
|
+
return;
|
|
7261
|
+
}
|
|
7262
|
+
const args = process.argv.slice(2);
|
|
7263
|
+
const cmdName = args.find((arg) => !arg.startsWith("-"));
|
|
7264
|
+
if (cmdName && !commandExists(cmdName)) {
|
|
7265
|
+
console.log(`\x1B[33mUnknown command '${cmdName}'. Syncing tools from Unity...\x1B[0m`);
|
|
7266
|
+
try {
|
|
7267
|
+
await syncTools({});
|
|
7268
|
+
const newCache = loadToolsCache();
|
|
7269
|
+
const tool = newCache.tools.find((t) => t.name === cmdName);
|
|
7270
|
+
if (tool) {
|
|
7271
|
+
registerToolCommand(tool);
|
|
7272
|
+
console.log(`\x1B[32m\u2713 Found '${cmdName}' after sync.\x1B[0m
|
|
7273
|
+
`);
|
|
7274
|
+
} else {
|
|
7275
|
+
console.error(`\x1B[31mError: Command '${cmdName}' not found even after sync.\x1B[0m`);
|
|
7276
|
+
process.exit(1);
|
|
7277
|
+
}
|
|
7278
|
+
} catch (error) {
|
|
7279
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7280
|
+
console.error(`\x1B[31mError: Failed to sync tools: ${message}\x1B[0m`);
|
|
7281
|
+
process.exit(1);
|
|
7282
|
+
}
|
|
7283
|
+
}
|
|
7096
7284
|
program2.parse();
|
|
7097
7285
|
}
|
|
7286
|
+
void main();
|
|
7098
7287
|
//# sourceMappingURL=cli.bundle.cjs.map
|