unity-cleaner
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBefore calling any skill in this module: if you are about to call a skill with parameters guessed from its name or description, STOP — read this file (or fetch its schema via) first. If you already have the parameter definitions from recommend/schema, you may proceed straight to dryRun.GET /skills/recommend?includeSchema=true
在调用本模块中的任何Skill之前:如果您打算根据Skill的名称或描述猜测参数来调用它,请停止——先阅读本文档(或通过获取其Schema)。如果您已经从推荐/Schema中获得了参数定义,则可以直接进行dryRun。GET /skills/recommend?includeSchema=true
Triggers
触发场景
- Reducing project bloat
- Hunting duplicate or orphaned assets
- Auditing before a release
- 给项目瘦身、排查重复或孤立资源、发布前审计
- 减少项目冗余
- 查找重复或孤立资源
- 发布前审计
- 给项目瘦身、排查重复或孤立资源、发布前审计
Unity Cleaner Skills
Unity 清理Skills
Safety:uses a two-step confirmToken handshake. Call withoutcleaner_delete_assetsto preview; call again with the returned token (5-minute TTL) to actually delete. There is noconfirmTokenparameter.dryRun
安全说明:采用两步confirmToken验证机制。不带cleaner_delete_assets调用可预览删除内容;使用返回的token(5分钟有效期)再次调用即可执行实际删除。本Skill没有confirmToken参数。dryRun
Guardrails
防护规则
Operating Mode (v1.9 three-tier):
- Approval (default): all analyze/query skills (,
cleaner_find_unused_assets,cleaner_find_duplicates,cleaner_find_missing_references,cleaner_get_asset_usage,cleaner_find_empty_folders,cleaner_find_large_assets) are SemiAuto — run directly.cleaner_get_dependency_tree - Auto / Bypass: SemiAuto and FullAuto run directly.
- Auto-forbidden in this module: ,
cleaner_delete_assets(both carrycleaner_delete_empty_folders). In Approval/Auto these returnSkillOperation.Delete— they are reachable only under Bypass mode or via a user-managed Allowlist entry; the grant flow does not unlock them.MODE_FORBIDDEN - is an
cleaner_fix_missing_scriptsoperation (it replaces missing component references with null in place, no asset deletion), so it does not trigger the NeverInSemi gate. In Auto / Bypass it runs directly; in Approval it still requires the standard grant handshake before execution.Execute | Modify - additionally uses a two-step
cleaner_delete_assetshandshake even when the mode gate allows it — preview first (no token), then confirm with the returned token (5-minute TTL).confirmToken
DO NOT (common hallucinations):
- /
cleaner_deletedo not exist → cleaner skills only find/report; usecleaner_removeto actually removeasset_delete - does not exist → use
cleaner_fixspecifically for missing script referencescleaner_fix_missing_scripts - /
cleaner_scando not exist → use specific skills:cleaner_find_unused,cleaner_find_unused_assets,cleaner_find_duplicates,cleaner_find_missing_references,cleaner_find_empty_folderscleaner_find_large_assets
Routing:
- To delete found assets → use module's
asset/asset_deleteasset_delete_batch - For project validation → use module
validation
运行模式(v1.9 三级模式):
- 审批模式(默认):所有分析/查询类Skills(、
cleaner_find_unused_assets、cleaner_find_duplicates、cleaner_find_missing_references、cleaner_get_asset_usage、cleaner_find_empty_folders、cleaner_find_large_assets)均为半自动模式——可直接运行。cleaner_get_dependency_tree - 自动模式 / 绕过模式:半自动和全自动模式的Skill可直接运行。
- 本模块中禁止自动执行的Skill:、
cleaner_delete_assets(两者均属于cleaner_delete_empty_folders操作)。在审批/自动模式下,调用这些Skill会返回SkillOperation.Delete——仅在绕过模式下或通过用户管理的白名单条目才能调用;授权流程不会解锁这些Skill。MODE_FORBIDDEN - 属于
cleaner_fix_missing_scripts操作(它会原地将缺失的组件引用替换为null,不会删除资源),因此不会触发半自动模式的禁止规则。在自动/绕过模式下可直接运行;在审批模式下,执行前仍需完成标准的授权验证流程。Execute | Modify - 即使模式规则允许调用,它仍需采用两步
cleaner_delete_assets验证机制——先预览(不带token),再使用返回的token(5分钟有效期)确认执行。confirmToken
请勿(常见错误用法):
- /
cleaner_delete不存在→清理类Skill仅负责查找/报告;请使用cleaner_remove执行实际删除操作asset_delete - 不存在→若要修复缺失的脚本引用,请使用
cleaner_fixcleaner_fix_missing_scripts - /
cleaner_scan不存在→请使用具体的Skill:cleaner_find_unused、cleaner_find_unused_assets、cleaner_find_duplicates、cleaner_find_missing_references、cleaner_find_empty_folderscleaner_find_large_assets
路由指引:
- 若要删除找到的资源→使用模块的
asset/asset_deleteasset_delete_batch - 若要进行项目验证→使用模块
validation
Skills Overview
Skills概述
| Skill | Description |
|---|---|
| Find assets not referenced by others |
| Find duplicate files by content hash |
| Find missing scripts/asset references |
| Delete assets via two-step confirmToken (preview → confirm) |
| Find what references a specific asset |
| Find empty folders in the project |
| Find largest assets by file size |
| Delete all empty folders |
| Remove missing script components from GameObjects |
| Get dependency tree for an asset |
| Skill | 描述 |
|---|---|
| 查找未被其他资源引用的资源 |
| 通过内容哈希查找重复文件 |
| 查找缺失的脚本/资源引用 |
| 通过两步confirmToken验证删除资源(预览→确认) |
| 查找引用特定资源的对象 |
| 查找项目中的空文件夹 |
| 按文件大小查找最大的资源 |
| 删除所有空文件夹 |
| 从GameObjects中移除缺失的脚本组件 |
| 获取资源的依赖树 |
Skills
Skills详情
cleaner_find_unused_assets
cleaner_find_unused_assets
Find potentially unused assets of a specific type.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | "Material" | Asset type filter |
| string | No | "Assets" | Search path |
| int | No | 100 | Max results |
Returns:
{success, assetType, potentiallyUnusedCount, assets: [{path, name, type, sizeBytes}]}python
undefined查找特定类型的潜在无用资源。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 否 | "Material" | 资源类型过滤器 |
| string | 否 | "Assets" | 搜索路径 |
| int | 否 | 100 | 最大结果数 |
返回值:
{success, assetType, potentiallyUnusedCount, assets: [{path, name, type, sizeBytes}]}python
undefinedFind unused materials
Find unused materials
result = call_skill("cleaner_find_unused_assets", assetType="Material")
result = call_skill("cleaner_find_unused_assets", assetType="Material")
Find unused textures in a specific folder
Find unused textures in a specific folder
result = call_skill("cleaner_find_unused_assets",
assetType="Texture2D", searchPath="Assets/Textures")
undefinedresult = call_skill("cleaner_find_unused_assets",
assetType="Texture2D", searchPath="Assets/Textures")
undefinedcleaner_find_duplicates
cleaner_find_duplicates
Find duplicate files by MD5 hash.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | "Texture2D" | Asset type |
| string | No | "Assets" | Search path |
| int | No | 50 | Max groups |
Returns:
{success, duplicateGroupCount, totalWastedBytes, totalWastedMB, groups: [{count, sizeBytes, wastedBytes, files}]}python
undefined通过MD5哈希查找重复文件。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 否 | "Texture2D" | 资源类型 |
| string | 否 | "Assets" | 搜索路径 |
| int | 否 | 50 | 最大分组数 |
返回值:
{success, duplicateGroupCount, totalWastedBytes, totalWastedMB, groups: [{count, sizeBytes, wastedBytes, files}]}python
undefinedFind duplicate textures
Find duplicate textures
result = call_skill("cleaner_find_duplicates", assetType="Texture2D")
print(f"Wasted space: {result['totalWastedMB']:.2f} MB")
undefinedresult = call_skill("cleaner_find_duplicates", assetType="Texture2D")
print(f"Wasted space: {result['totalWastedMB']:.2f} MB")
undefinedcleaner_find_missing_references
cleaner_find_missing_references
Find components with missing scripts or null references.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| bool | No | true | Include inactive objects |
Returns:
{success, issueCount, missingScripts, missingReferences, issues: [{type, gameObject, path, ...}]}python
undefined查找包含缺失脚本或空引用的组件。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| bool | 否 | true | 是否包含非激活对象 |
返回值:
{success, issueCount, missingScripts, missingReferences, issues: [{type, gameObject, path, ...}]}python
undefinedScan for all missing references
Scan for all missing references
result = call_skill("cleaner_find_missing_references")
print(f"Missing scripts: {result['missingScripts']}")
print(f"Missing references: {result['missingReferences']}")
undefinedresult = call_skill("cleaner_find_missing_references")
print(f"Missing scripts: {result['missingScripts']}")
print(f"Missing references: {result['missingReferences']}")
undefinedcleaner_delete_assets
cleaner_delete_assets
Delete specified assets with two-step confirmation.
⚠️ Safety First: Deletion requires TWO calls - first preview, then confirm.
Step 1 - Preview (no confirmToken):
| Parameter | Type | Required | Description |
|---|---|---|---|
| string[] | Yes | Asset paths to delete |
Returns:
{action: "preview", confirmToken, assetsToDelete, message}Step 2 - Confirm (with confirmToken):
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Token from preview step |
Returns:
{action: "deleted", deletedCount, results}python
undefined通过两步确认机制删除指定资源。
⚠️ 安全提示:删除操作需要两次调用——先预览,再确认。
步骤1 - 预览(不带confirmToken):
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| string[] | 是 | 要删除的资源路径 |
返回值:
{action: "preview", confirmToken, assetsToDelete, message}步骤2 - 确认(带confirmToken):
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| string | 是 | 预览步骤返回的token |
返回值:
{action: "deleted", deletedCount, results}python
undefinedStep 1: Preview what will be deleted
Step 1: Preview what will be deleted
preview = call_skill("cleaner_delete_assets",
paths=["Assets/Unused/mat1.mat", "Assets/Unused/mat2.mat"])
print(preview['message']) # Shows: "⚠️ PREVIEW ONLY - 2 assets will be deleted..."
print(preview['assetsToDelete']) # Full list with sizes
preview = call_skill("cleaner_delete_assets",
paths=["Assets/Unused/mat1.mat", "Assets/Unused/mat2.mat"])
print(preview['message']) # Shows: "⚠️ PREVIEW ONLY - 2 assets will be deleted..."
print(preview['assetsToDelete']) # Full list with sizes
Step 2: Confirm deletion using token (expires in 5 minutes)
Step 2: Confirm deletion using token (expires in 5 minutes)
if input("Proceed? (y/n): ") == 'y':
result = call_skill("cleaner_delete_assets",
confirmToken=preview['confirmToken'])
print(result['message']) # "Successfully deleted 2 assets"
undefinedif input("Proceed? (y/n): ") == 'y':
result = call_skill("cleaner_delete_assets",
confirmToken=preview['confirmToken'])
print(result['message']) # "Successfully deleted 2 assets"
undefinedcleaner_get_asset_usage
cleaner_get_asset_usage
Find what objects reference a specific asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Asset path |
| int | No | Max results (default 50) |
Returns:
{success, asset, usedByCount, usedBy: [{path, name, type}]}python
undefined查找引用特定资源的对象。
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| string | 是 | 资源路径 |
| int | 否 | 最大结果数(默认50) |
返回值:
{success, asset, usedByCount, usedBy: [{path, name, type}]}python
undefinedCheck what uses a texture
Check what uses a texture
result = call_skill("cleaner_get_asset_usage",
assetPath="Assets/Textures/player.png")
undefinedresult = call_skill("cleaner_get_asset_usage",
assetPath="Assets/Textures/player.png")
undefinedcleaner_find_empty_folders
cleaner_find_empty_folderscleaner_find_empty_folders
cleaner_find_empty_foldersFind empty folders in the project.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | "Assets" | Search path |
Returns:
{ success, count, folders }python
undefined查找项目中的空文件夹。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 否 | "Assets" | 搜索路径 |
返回值:
{ success, count, folders }python
undefinedFind empty folders
Find empty folders
result = call_skill("cleaner_find_empty_folders")
print(f"Found {result['count']} empty folders")
undefinedresult = call_skill("cleaner_find_empty_folders")
print(f"Found {result['count']} empty folders")
undefinedcleaner_find_large_assets
cleaner_find_large_assetscleaner_find_large_assets
cleaner_find_large_assetsFind largest assets by file size.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | "Assets" | Search path |
| int | No | 20 | Max results |
| long | No | 0 | Minimum file size in bytes |
Returns:
{ success, count, assets: [{ path, sizeBytes, sizeMB }] }python
undefined按文件大小查找最大的资源。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 否 | "Assets" | 搜索路径 |
| int | 否 | 20 | 最大结果数 |
| long | 否 | 0 | 文件最小大小(字节) |
返回值:
{ success, count, assets: [{ path, sizeBytes, sizeMB }] }python
undefinedFind top 10 largest assets over 1 MB
Find top 10 largest assets over 1 MB
result = call_skill("cleaner_find_large_assets", limit=10, minSizeBytes=1048576)
for a in result['assets']:
print(f"{a['sizeMB']:.2f} MB - {a['path']}")
undefinedresult = call_skill("cleaner_find_large_assets", limit=10, minSizeBytes=1048576)
for a in result['assets']:
print(f"{a['sizeMB']:.2f} MB - {a['path']}")
undefinedcleaner_delete_empty_folders
cleaner_delete_empty_folderscleaner_delete_empty_folders
cleaner_delete_empty_foldersDelete all empty folders.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | "Assets" | Search path |
Returns:
{ success, deleted, total }python
undefined删除所有空文件夹。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 否 | "Assets" | 搜索路径 |
返回值:
{ success, deleted, total }python
undefinedDelete all empty folders
Delete all empty folders
result = call_skill("cleaner_delete_empty_folders")
print(f"Deleted {result['deleted']} of {result['total']} empty folders")
undefinedresult = call_skill("cleaner_delete_empty_folders")
print(f"Deleted {result['deleted']} of {result['total']} empty folders")
undefinedcleaner_fix_missing_scripts
cleaner_fix_missing_scriptscleaner_fix_missing_scripts
cleaner_fix_missing_scriptsRemove missing script components from GameObjects.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| bool | No | true | Include inactive objects |
Returns:
{ success, removedComponents }python
undefined从GameObjects中移除缺失的脚本组件。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| bool | 否 | true | 是否包含非激活对象 |
返回值:
{ success, removedComponents }python
undefinedRemove all missing script components
Remove all missing script components
result = call_skill("cleaner_fix_missing_scripts")
print(f"Removed {result['removedComponents']} missing script components")
undefinedresult = call_skill("cleaner_fix_missing_scripts")
print(f"Removed {result['removedComponents']} missing script components")
undefinedcleaner_get_dependency_tree
cleaner_get_dependency_treecleaner_get_dependency_tree
cleaner_get_dependency_treeGet dependency tree for an asset.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| string | Yes | - | Asset path |
| bool | No | true | Recursively resolve dependencies |
Returns:
{ success, assetPath, dependencyCount, dependencies: [{ path, type }] }python
undefined获取资源的依赖树。
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| string | 是 | - | 资源路径 |
| bool | 否 | true | 是否递归解析依赖 |
返回值:
{ success, assetPath, dependencyCount, dependencies: [{ path, type }] }python
undefinedGet full dependency tree for a prefab
Get full dependency tree for a prefab
result = call_skill("cleaner_get_dependency_tree",
assetPath="Assets/Prefabs/Player.prefab")
print(f"Dependencies: {result['dependencyCount']}")
---result = call_skill("cleaner_get_dependency_tree",
assetPath="Assets/Prefabs/Player.prefab")
print(f"Dependencies: {result['dependencyCount']}")
---Example Workflow: Clean Project
示例工作流:清理项目
python
import unity_skillspython
import unity_skills1. Find all missing references and fix them
1. 查找所有缺失引用并修复
missing = unity_skills.call_skill("cleaner_find_missing_references")
for issue in missing['issues']:
if issue['type'] == 'MissingScript':
print(f"⚠️ Missing script on: {issue['path']}")
missing = unity_skills.call_skill("cleaner_find_missing_references")
for issue in missing['issues']:
if issue['type'] == 'MissingScript':
print(f"⚠️ Missing script on: {issue['path']}")
2. Find duplicate textures
2. 查找重复纹理
dupes = unity_skills.call_skill("cleaner_find_duplicates", assetType="Texture2D")
if dupes['totalWastedMB'] > 10:
print(f"🗑️ {dupes['totalWastedMB']:.1f} MB wasted on duplicates")
dupes = unity_skills.call_skill("cleaner_find_duplicates", assetType="Texture2D")
if dupes['totalWastedMB'] > 10:
print(f"🗑️ {dupes['totalWastedMB']:.1f} MB wasted on duplicates")
3. Find unused materials
3. 查找无用材质
unused = unity_skills.call_skill("cleaner_find_unused_assets", assetType="Material")
print(f"📦 {unused['potentiallyUnusedCount']} potentially unused materials")
unused = unity_skills.call_skill("cleaner_find_unused_assets", assetType="Material")
print(f"📦 {unused['potentiallyUnusedCount']} potentially unused materials")
4. Preview cleanup
4. 预览清理操作
paths_to_delete = [a['path'] for a in unused['assets'][:5]]
preview = unity_skills.call_skill("cleaner_delete_assets",
paths=paths_to_delete)
print(f"Would free: {preview['totalMB']:.2f} MB")
paths_to_delete = [a['path'] for a in unused['assets'][:5]]
preview = unity_skills.call_skill("cleaner_delete_assets",
paths=paths_to_delete)
print(f"Would free: {preview['totalMB']:.2f} MB")
To actually delete, call again with preview['confirmToken'] within 5 minutes.
若要执行实际删除,请在5分钟内使用preview['confirmToken']再次调用。
---
---Exact Signatures
精确签名
Exact names, parameters, defaults, and returns are defined by or , not by this file.
GET /skills/schemaunity_skills.get_skill_schema()Skill的精确名称、参数、默认值和返回值由或定义,而非本文档。
GET /skills/schemaunity_skills.get_skill_schema()