unity-bridge — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited unity-bridge (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
⚠️ Building UI / presentation / animation / effects? FIRST read [`PRESENTATION_RULES.md`](./PRESENTATION_RULES.md) (next to this file) — hard rules: editable prefabs (no hardcoded coords), non-destructive prefab edits, native-size sprites, no git on the user's project, real Unity game-feel. Violating them costs rework.
The AI Bridge package runs inside the open Unity Editor and exposes commands over a plain file channel. You operate Unity by writing a request file and reading the reply. No MCP, no ports.
<project>/.aibridge/ (here: D:/AI/unity_test/testgame/.aibridge/).in/<id>.json — { "id": "<unique>", "command": "<name>", ...fields }.out/<id>.json — { "id", "command", "ok", "error", "result" }.out/<id>.json.id per request so replies never collide.Bash idiom:
cd <project>/.aibridge
printf '{ "id":"x1", "command":"scene.dump" }' > in/x1.json
sleep 2 && cat out/x1.jsonIf out/<id>.json never appears: Unity may be recompiling or unfocused. Ask the user to focus Unity, check the Console for [AIBridge], and retry. You cannot trigger a recompile yourself — after editing any C# in the project, ask the user to focus Unity so it compiles.
selection.jsonWhen the user says "this / here / the selected one", they mean what they pointed at in Unity:
.aibridge/selection.json (written by the AI Reference window — scene objectsand/or Project-window assets, or a clicked point, with an optional note).
selection.get for whatever is selected right now.Selected assets (sprites, prefabs, materials…) appear under assets[] (with assetPath) in both selection.json and selection.get — feed assetPath into reference.wire targetAssetPath.
To change the exact thing the user picked, pass path: "@selection" to object.modify / component.set. It targets Selection.activeGameObject directly, so it works anywhere — including inside an open Prefab Mode stage, which a scene-path lookup cannot reach.
⚠️ Prefab Mode is a separate stage the bridge's scene-path lookup does NOT see. When the user has a prefab open in Prefab Mode (they double-clicked it):
selection.get can read their selection (you know what they picked), but a plain scene path like"Dex/BgImage" won't resolve, and editing the prefab asset on disk (`prefab.modify`) will NOT show — Unity doesn't refresh the open stage, and the user's later save can overwrite your disk edit.
path: "@selection" (reaches the live stage object the user sees), or ask theuser to exit Prefab Mode first. After an @selection edit they persist it with Ctrl+S in Prefab Mode.
object.modify / component.set also auto-fall back to the open Prefab stage.Tell-tale: you edit a prefab but the user keeps seeing the OLD value, and selection.get returns the same entityId every call → they're looking at a stale Prefab Mode stage. Switch to @selection.
| Command | Fields | Returns |
|---|---|---|
ping | — | message, unityVersion |
scene.dump | includeInactive?, maxObjects? | scene objects: path, worldPosition, rect (if UI), components |
selection.get | — | currently selected objects (same shape) |
reference.wire | sourcePath, sourceComponent, field, then ONE of: targetPath(+targetComponent?) / targetAssetPath | what was wired |
gameobject.create | name, parentPath?, primitive?, position?{x,y,z}, components?[] | created object |
component.add | path, component | updated component list |
object.modify | path, ops:[{property,value}] | applied, errors, object state |
gameobject.delete | path | deleted path |
screenshot.annotated | width?, height?, annotate?, maxLabels? | imagePath (read it!), objects[{screenRect, worldPosition}] |
screenshot.gameview | max? | real Game View PNG incl. overlay UI (imagePath — read it). Use to see UI. |
console.get | maxEntries?, logTypeFilter?, lastMinutes?, includeStackTrace? | recent Console logs (script/runtime; not compiler errors) |
console.read | max?, typeFilter? | the real Console (errors/warnings), survives reloads — use for compile diagnostics |
console.clear | — | clear the Console + log buffer (wipe stale errors before a fresh check) |
component.set | path, component, componentIndex?, ops:[{field,value}] | set value fields (color/number/bool/string/vector/enum) |
gameobject.duplicate | path, name?, setPosition?, position? | clone a GameObject (with components) |
prefab.create | path, assetPath | save a GameObject as a prefab asset |
prefab.instantiate | assetPath, name?, parentPath?, setPosition?, position? | spawn a prefab instance |
refresh | save?, recompile? | import + recompile changed scripts (you can compile your own edits) |
editor.play | action (enter/exit/toggle/pause/resume/step) | run the game; poll status for isPlaying, then screenshot.gameview |
scene.create / scene.open / scene.save / scene.list / scene.close | path, additive?, force? (open/create); path? (save) | multi-scene management (single/additive; force discards unsaved) |
status | — | isCompiling/isPlaying/… + last compile compileMessages (poll after refresh) |
menu.execute | menuPath | run any Editor menu item by path (e.g. Tools/AI Bridge/Configure Claude Code) |
asset.find | filter, folder?, max? | find assets by Unity search (t:Sprite, t:Prefab, …) |
asset.reimport | path | force-reimport an asset/folder (regenerate importer-derived assets) |
sprite.set | path, assetPath, component? | assign a sprite to a SpriteRenderer/Image (auto-imports as Sprite) |
audio.add | path, clip?, loop?, volume?, playOnAwake?, spatialBlend? | add/configure an AudioSource + assign a clip |
particle.create | name?, parentPath?, position?, preset (burst/explosion/stream/sparkle), color?, size?, lifetime?, count? | create a particle effect (plays in Play mode) |
ui.create | kind (image/text/button/canvas), name?, parentPath?, anchor?, x/y/width/height?, text?, fontSize?, color?, sprite? | turnkey UGUI (auto Canvas + EventSystem) |
prefab.modify | prefabPath, edits:[{path, ops?, addChild?, duplicateAs?}] | non-destructive in-place prefab edit: patch text/sprite/color/active/rect/Type.member; addChild (image/text/empty, index for layering); ops:addComponent |
ui.buildPrefabFromSpec | specPath(.ui.json), outPrefab, spriteRoots[], fontResource | a node-tree spec → a UGUI prefab (then tune with prefab.modify) |
ui.makeScrollable | prefabPath, node, vertical?, horizontal?, width?, height? | wrap a layout container in a ScrollRect (viewport = node's size) so a list scrolls instead of overflowing |
compile | — | force a script recompile even while the Editor is unfocused (poll status) |
Notes:
Root/Child/Leaf within the active scene (the shape scene.dump emits) — or `@selection`to target the current Editor selection (the only way to reach a node inside an open Prefab Mode stage).
object.modify properties: name, active, position, localPosition, rotation (euler),localRotation, scale; UI: anchoredPosition, sizeDelta, anchorMin, anchorMax, pivot. Vector values are comma-separated, e.g. "1,2,0".
prefab.modify (non-destructive, snapshots & restores untouchedtransforms). Don't do it while the user has that prefab open in Prefab Mode — use @selection instead.
reference.wire is for object-reference fields only; for primitive values use the Inspector/scripts.README.md / CHANGELOG.md.scene.dump for data, and/or screenshot.annotated then read the PNG atresult.imagePath to see the scene.
selection.get or read selection.json.gameobject.create / component.add / reference.wire / object.modify / gameobject.delete.screenshot.annotated again and read the PNG to confirm the change looks right; don'tassume — look.
Full field reference: Packages/com.aibridge.unity/README.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.