unity-open-mcp 0.1.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.
Files changed (630) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/dist/batch-spawn.d.ts +33 -0
  4. package/dist/batch-spawn.js +329 -0
  5. package/dist/batch-spawn.js.map +1 -0
  6. package/dist/capabilities/build-capabilities.d.ts +155 -0
  7. package/dist/capabilities/build-capabilities.js +475 -0
  8. package/dist/capabilities/build-capabilities.js.map +1 -0
  9. package/dist/capabilities/list-rules.d.ts +45 -0
  10. package/dist/capabilities/list-rules.js +121 -0
  11. package/dist/capabilities/list-rules.js.map +1 -0
  12. package/dist/capabilities/rule-catalog.d.ts +44 -0
  13. package/dist/capabilities/rule-catalog.js +330 -0
  14. package/dist/capabilities/rule-catalog.js.map +1 -0
  15. package/dist/capabilities/tool-groups.d.ts +53 -0
  16. package/dist/capabilities/tool-groups.js +396 -0
  17. package/dist/capabilities/tool-groups.js.map +1 -0
  18. package/dist/cli/args.d.ts +36 -0
  19. package/dist/cli/args.js +239 -0
  20. package/dist/cli/args.js.map +1 -0
  21. package/dist/cli/cli.d.ts +23 -0
  22. package/dist/cli/cli.js +125 -0
  23. package/dist/cli/cli.js.map +1 -0
  24. package/dist/cli/commands.d.ts +37 -0
  25. package/dist/cli/commands.js +277 -0
  26. package/dist/cli/commands.js.map +1 -0
  27. package/dist/cli/ping-poller.d.ts +81 -0
  28. package/dist/cli/ping-poller.js +161 -0
  29. package/dist/cli/ping-poller.js.map +1 -0
  30. package/dist/compat.d.ts +32 -0
  31. package/dist/compat.js +121 -0
  32. package/dist/compat.js.map +1 -0
  33. package/dist/compiler-errors.d.ts +31 -0
  34. package/dist/compiler-errors.js +91 -0
  35. package/dist/compiler-errors.js.map +1 -0
  36. package/dist/compressible-router.d.ts +18 -0
  37. package/dist/compressible-router.js +191 -0
  38. package/dist/compressible-router.js.map +1 -0
  39. package/dist/compression/asset-model.d.ts +86 -0
  40. package/dist/compression/asset-model.js +15 -0
  41. package/dist/compression/asset-model.js.map +1 -0
  42. package/dist/compression/compact.d.ts +153 -0
  43. package/dist/compression/compact.js +501 -0
  44. package/dist/compression/compact.js.map +1 -0
  45. package/dist/dialog-dismiss.d.ts +197 -0
  46. package/dist/dialog-dismiss.js +533 -0
  47. package/dist/dialog-dismiss.js.map +1 -0
  48. package/dist/event-stream.d.ts +60 -0
  49. package/dist/event-stream.js +228 -0
  50. package/dist/event-stream.js.map +1 -0
  51. package/dist/gate-error.d.ts +18 -0
  52. package/dist/gate-error.js +11 -0
  53. package/dist/gate-error.js.map +1 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.js +146 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/instance-discovery.d.ts +117 -0
  58. package/dist/instance-discovery.js +202 -0
  59. package/dist/instance-discovery.js.map +1 -0
  60. package/dist/live-client.d.ts +68 -0
  61. package/dist/live-client.js +583 -0
  62. package/dist/live-client.js.map +1 -0
  63. package/dist/offline.d.ts +75 -0
  64. package/dist/offline.js +1495 -0
  65. package/dist/offline.js.map +1 -0
  66. package/dist/package-version.d.ts +8 -0
  67. package/dist/package-version.js +41 -0
  68. package/dist/package-version.js.map +1 -0
  69. package/dist/ping-cache.d.ts +15 -0
  70. package/dist/ping-cache.js +10 -0
  71. package/dist/ping-cache.js.map +1 -0
  72. package/dist/project-health.d.ts +52 -0
  73. package/dist/project-health.js +177 -0
  74. package/dist/project-health.js.map +1 -0
  75. package/dist/resource-router.d.ts +26 -0
  76. package/dist/resource-router.js +143 -0
  77. package/dist/resource-router.js.map +1 -0
  78. package/dist/resources/index.d.ts +6 -0
  79. package/dist/resources/index.js +40 -0
  80. package/dist/resources/index.js.map +1 -0
  81. package/dist/results.d.ts +14 -0
  82. package/dist/results.js +22 -0
  83. package/dist/results.js.map +1 -0
  84. package/dist/router.d.ts +5 -0
  85. package/dist/router.js +2 -0
  86. package/dist/router.js.map +1 -0
  87. package/dist/routers.d.ts +44 -0
  88. package/dist/routers.js +73 -0
  89. package/dist/routers.js.map +1 -0
  90. package/dist/schema-defaults.d.ts +10 -0
  91. package/dist/schema-defaults.js +43 -0
  92. package/dist/schema-defaults.js.map +1 -0
  93. package/dist/skill/client-paths.d.ts +33 -0
  94. package/dist/skill/client-paths.js +131 -0
  95. package/dist/skill/client-paths.js.map +1 -0
  96. package/dist/skill/generate-skill.d.ts +38 -0
  97. package/dist/skill/generate-skill.js +389 -0
  98. package/dist/skill/generate-skill.js.map +1 -0
  99. package/dist/tool-router.d.ts +40 -0
  100. package/dist/tool-router.js +778 -0
  101. package/dist/tool-router.js.map +1 -0
  102. package/dist/tool-session-state.d.ts +55 -0
  103. package/dist/tool-session-state.js +116 -0
  104. package/dist/tool-session-state.js.map +1 -0
  105. package/dist/tools/agent-capabilities.d.ts +2 -0
  106. package/dist/tools/agent-capabilities.js +24 -0
  107. package/dist/tools/agent-capabilities.js.map +1 -0
  108. package/dist/tools/animation-create.d.ts +2 -0
  109. package/dist/tools/animation-create.js +31 -0
  110. package/dist/tools/animation-create.js.map +1 -0
  111. package/dist/tools/animation-get-data.d.ts +2 -0
  112. package/dist/tools/animation-get-data.js +23 -0
  113. package/dist/tools/animation-get-data.js.map +1 -0
  114. package/dist/tools/animation-modify.d.ts +2 -0
  115. package/dist/tools/animation-modify.js +45 -0
  116. package/dist/tools/animation-modify.js.map +1 -0
  117. package/dist/tools/animator-create.d.ts +2 -0
  118. package/dist/tools/animator-create.js +31 -0
  119. package/dist/tools/animator-create.js.map +1 -0
  120. package/dist/tools/animator-get-data.d.ts +2 -0
  121. package/dist/tools/animator-get-data.js +23 -0
  122. package/dist/tools/animator-get-data.js.map +1 -0
  123. package/dist/tools/animator-modify.d.ts +2 -0
  124. package/dist/tools/animator-modify.js +51 -0
  125. package/dist/tools/animator-modify.js.map +1 -0
  126. package/dist/tools/apply-fix.d.ts +2 -0
  127. package/dist/tools/apply-fix.js +39 -0
  128. package/dist/tools/apply-fix.js.map +1 -0
  129. package/dist/tools/assets-copy.d.ts +2 -0
  130. package/dist/tools/assets-copy.js +50 -0
  131. package/dist/tools/assets-copy.js.map +1 -0
  132. package/dist/tools/assets-create-folder.d.ts +2 -0
  133. package/dist/tools/assets-create-folder.js +53 -0
  134. package/dist/tools/assets-create-folder.js.map +1 -0
  135. package/dist/tools/assets-delete.d.ts +2 -0
  136. package/dist/tools/assets-delete.js +34 -0
  137. package/dist/tools/assets-delete.js.map +1 -0
  138. package/dist/tools/assets-move.d.ts +2 -0
  139. package/dist/tools/assets-move.js +50 -0
  140. package/dist/tools/assets-move.js.map +1 -0
  141. package/dist/tools/assets-refresh.d.ts +2 -0
  142. package/dist/tools/assets-refresh.js +37 -0
  143. package/dist/tools/assets-refresh.js.map +1 -0
  144. package/dist/tools/baseline-create.d.ts +2 -0
  145. package/dist/tools/baseline-create.js +20 -0
  146. package/dist/tools/baseline-create.js.map +1 -0
  147. package/dist/tools/bridge-status.d.ts +2 -0
  148. package/dist/tools/bridge-status.js +44 -0
  149. package/dist/tools/bridge-status.js.map +1 -0
  150. package/dist/tools/build-get-active-target.d.ts +2 -0
  151. package/dist/tools/build-get-active-target.js +16 -0
  152. package/dist/tools/build-get-active-target.js.map +1 -0
  153. package/dist/tools/build-get-defines.d.ts +2 -0
  154. package/dist/tools/build-get-defines.js +16 -0
  155. package/dist/tools/build-get-defines.js.map +1 -0
  156. package/dist/tools/build-get-scenes.d.ts +2 -0
  157. package/dist/tools/build-get-scenes.js +16 -0
  158. package/dist/tools/build-get-scenes.js.map +1 -0
  159. package/dist/tools/build-get-targets.d.ts +2 -0
  160. package/dist/tools/build-get-targets.js +18 -0
  161. package/dist/tools/build-get-targets.js.map +1 -0
  162. package/dist/tools/build-set-defines.d.ts +2 -0
  163. package/dist/tools/build-set-defines.js +50 -0
  164. package/dist/tools/build-set-defines.js.map +1 -0
  165. package/dist/tools/build-set-scenes.d.ts +2 -0
  166. package/dist/tools/build-set-scenes.js +60 -0
  167. package/dist/tools/build-set-scenes.js.map +1 -0
  168. package/dist/tools/build-set-target.d.ts +2 -0
  169. package/dist/tools/build-set-target.js +49 -0
  170. package/dist/tools/build-set-target.js.map +1 -0
  171. package/dist/tools/build-start.d.ts +2 -0
  172. package/dist/tools/build-start.js +64 -0
  173. package/dist/tools/build-start.js.map +1 -0
  174. package/dist/tools/capture-inline.d.ts +2 -0
  175. package/dist/tools/capture-inline.js +57 -0
  176. package/dist/tools/capture-inline.js.map +1 -0
  177. package/dist/tools/checkpoint-create.d.ts +2 -0
  178. package/dist/tools/checkpoint-create.js +16 -0
  179. package/dist/tools/checkpoint-create.js.map +1 -0
  180. package/dist/tools/compile-check.d.ts +2 -0
  181. package/dist/tools/compile-check.js +26 -0
  182. package/dist/tools/compile-check.js.map +1 -0
  183. package/dist/tools/component-add.d.ts +2 -0
  184. package/dist/tools/component-add.js +47 -0
  185. package/dist/tools/component-add.js.map +1 -0
  186. package/dist/tools/component-destroy.d.ts +2 -0
  187. package/dist/tools/component-destroy.js +46 -0
  188. package/dist/tools/component-destroy.js.map +1 -0
  189. package/dist/tools/component-get.d.ts +2 -0
  190. package/dist/tools/component-get.js +54 -0
  191. package/dist/tools/component-get.js.map +1 -0
  192. package/dist/tools/component-list-all.d.ts +2 -0
  193. package/dist/tools/component-list-all.js +38 -0
  194. package/dist/tools/component-list-all.js.map +1 -0
  195. package/dist/tools/component-modify.d.ts +2 -0
  196. package/dist/tools/component-modify.js +80 -0
  197. package/dist/tools/component-modify.js.map +1 -0
  198. package/dist/tools/console-clear.d.ts +2 -0
  199. package/dist/tools/console-clear.js +19 -0
  200. package/dist/tools/console-clear.js.map +1 -0
  201. package/dist/tools/console-log.d.ts +2 -0
  202. package/dist/tools/console-log.js +47 -0
  203. package/dist/tools/console-log.js.map +1 -0
  204. package/dist/tools/delta.d.ts +2 -0
  205. package/dist/tools/delta.js +17 -0
  206. package/dist/tools/delta.js.map +1 -0
  207. package/dist/tools/editor-add-layer.d.ts +2 -0
  208. package/dist/tools/editor-add-layer.js +51 -0
  209. package/dist/tools/editor-add-layer.js.map +1 -0
  210. package/dist/tools/editor-add-tag.d.ts +2 -0
  211. package/dist/tools/editor-add-tag.js +41 -0
  212. package/dist/tools/editor-add-tag.js.map +1 -0
  213. package/dist/tools/editor-get-layers.d.ts +2 -0
  214. package/dist/tools/editor-get-layers.js +22 -0
  215. package/dist/tools/editor-get-layers.js.map +1 -0
  216. package/dist/tools/editor-get-tags.d.ts +2 -0
  217. package/dist/tools/editor-get-tags.js +19 -0
  218. package/dist/tools/editor-get-tags.js.map +1 -0
  219. package/dist/tools/editor-redo.d.ts +2 -0
  220. package/dist/tools/editor-redo.js +27 -0
  221. package/dist/tools/editor-redo.js.map +1 -0
  222. package/dist/tools/editor-set-state.d.ts +2 -0
  223. package/dist/tools/editor-set-state.js +57 -0
  224. package/dist/tools/editor-set-state.js.map +1 -0
  225. package/dist/tools/editor-status.d.ts +2 -0
  226. package/dist/tools/editor-status.js +17 -0
  227. package/dist/tools/editor-status.js.map +1 -0
  228. package/dist/tools/editor-undo.d.ts +2 -0
  229. package/dist/tools/editor-undo.js +29 -0
  230. package/dist/tools/editor-undo.js.map +1 -0
  231. package/dist/tools/execute-csharp.d.ts +2 -0
  232. package/dist/tools/execute-csharp.js +74 -0
  233. package/dist/tools/execute-csharp.js.map +1 -0
  234. package/dist/tools/execute-menu.d.ts +2 -0
  235. package/dist/tools/execute-menu.js +40 -0
  236. package/dist/tools/execute-menu.js.map +1 -0
  237. package/dist/tools/find-members.d.ts +2 -0
  238. package/dist/tools/find-members.js +56 -0
  239. package/dist/tools/find-members.js.map +1 -0
  240. package/dist/tools/find-references.d.ts +2 -0
  241. package/dist/tools/find-references.js +29 -0
  242. package/dist/tools/find-references.js.map +1 -0
  243. package/dist/tools/gameobject-create.d.ts +2 -0
  244. package/dist/tools/gameobject-create.js +61 -0
  245. package/dist/tools/gameobject-create.js.map +1 -0
  246. package/dist/tools/gameobject-destroy.d.ts +2 -0
  247. package/dist/tools/gameobject-destroy.js +38 -0
  248. package/dist/tools/gameobject-destroy.js.map +1 -0
  249. package/dist/tools/gameobject-duplicate.d.ts +2 -0
  250. package/dist/tools/gameobject-duplicate.js +40 -0
  251. package/dist/tools/gameobject-duplicate.js.map +1 -0
  252. package/dist/tools/gameobject-find.d.ts +2 -0
  253. package/dist/tools/gameobject-find.js +59 -0
  254. package/dist/tools/gameobject-find.js.map +1 -0
  255. package/dist/tools/gameobject-modify.d.ts +2 -0
  256. package/dist/tools/gameobject-modify.js +76 -0
  257. package/dist/tools/gameobject-modify.js.map +1 -0
  258. package/dist/tools/gameobject-set-parent.d.ts +2 -0
  259. package/dist/tools/gameobject-set-parent.js +55 -0
  260. package/dist/tools/gameobject-set-parent.js.map +1 -0
  261. package/dist/tools/gate-budget-estimate.d.ts +2 -0
  262. package/dist/tools/gate-budget-estimate.js +59 -0
  263. package/dist/tools/gate-budget-estimate.js.map +1 -0
  264. package/dist/tools/generate-skill.d.ts +2 -0
  265. package/dist/tools/generate-skill.js +37 -0
  266. package/dist/tools/generate-skill.js.map +1 -0
  267. package/dist/tools/impact-preview.d.ts +2 -0
  268. package/dist/tools/impact-preview.js +50 -0
  269. package/dist/tools/impact-preview.js.map +1 -0
  270. package/dist/tools/index.d.ts +30 -0
  271. package/dist/tools/index.js +576 -0
  272. package/dist/tools/index.js.map +1 -0
  273. package/dist/tools/inputsystem-action-add.d.ts +2 -0
  274. package/dist/tools/inputsystem-action-add.js +61 -0
  275. package/dist/tools/inputsystem-action-add.js.map +1 -0
  276. package/dist/tools/inputsystem-actionmap-add.d.ts +2 -0
  277. package/dist/tools/inputsystem-actionmap-add.js +31 -0
  278. package/dist/tools/inputsystem-actionmap-add.js.map +1 -0
  279. package/dist/tools/inputsystem-asset-create.d.ts +2 -0
  280. package/dist/tools/inputsystem-asset-create.js +35 -0
  281. package/dist/tools/inputsystem-asset-create.js.map +1 -0
  282. package/dist/tools/inputsystem-binding-add.d.ts +2 -0
  283. package/dist/tools/inputsystem-binding-add.js +48 -0
  284. package/dist/tools/inputsystem-binding-add.js.map +1 -0
  285. package/dist/tools/inputsystem-binding-composite-add.d.ts +2 -0
  286. package/dist/tools/inputsystem-binding-composite-add.js +51 -0
  287. package/dist/tools/inputsystem-binding-composite-add.js.map +1 -0
  288. package/dist/tools/inputsystem-controlscheme-add.d.ts +2 -0
  289. package/dist/tools/inputsystem-controlscheme-add.js +43 -0
  290. package/dist/tools/inputsystem-controlscheme-add.js.map +1 -0
  291. package/dist/tools/inputsystem-get.d.ts +2 -0
  292. package/dist/tools/inputsystem-get.js +22 -0
  293. package/dist/tools/inputsystem-get.js.map +1 -0
  294. package/dist/tools/invoke-method.d.ts +2 -0
  295. package/dist/tools/invoke-method.js +104 -0
  296. package/dist/tools/invoke-method.js.map +1 -0
  297. package/dist/tools/list-assets.d.ts +2 -0
  298. package/dist/tools/list-assets.js +30 -0
  299. package/dist/tools/list-assets.js.map +1 -0
  300. package/dist/tools/list-rules.d.ts +2 -0
  301. package/dist/tools/list-rules.js +27 -0
  302. package/dist/tools/list-rules.js.map +1 -0
  303. package/dist/tools/manage-tools.d.ts +2 -0
  304. package/dist/tools/manage-tools.js +47 -0
  305. package/dist/tools/manage-tools.js.map +1 -0
  306. package/dist/tools/material-create.d.ts +2 -0
  307. package/dist/tools/material-create.js +37 -0
  308. package/dist/tools/material-create.js.map +1 -0
  309. package/dist/tools/material-get-keywords.d.ts +2 -0
  310. package/dist/tools/material-get-keywords.js +23 -0
  311. package/dist/tools/material-get-keywords.js.map +1 -0
  312. package/dist/tools/material-get-properties.d.ts +2 -0
  313. package/dist/tools/material-get-properties.js +32 -0
  314. package/dist/tools/material-get-properties.js.map +1 -0
  315. package/dist/tools/material-set-keyword.d.ts +2 -0
  316. package/dist/tools/material-set-keyword.js +42 -0
  317. package/dist/tools/material-set-keyword.js.map +1 -0
  318. package/dist/tools/material-set-property.d.ts +2 -0
  319. package/dist/tools/material-set-property.js +49 -0
  320. package/dist/tools/material-set-property.js.map +1 -0
  321. package/dist/tools/material-set-shader.d.ts +2 -0
  322. package/dist/tools/material-set-shader.js +39 -0
  323. package/dist/tools/material-set-shader.js.map +1 -0
  324. package/dist/tools/mutation-explain.d.ts +2 -0
  325. package/dist/tools/mutation-explain.js +44 -0
  326. package/dist/tools/mutation-explain.js.map +1 -0
  327. package/dist/tools/navigation-agent-add.d.ts +2 -0
  328. package/dist/tools/navigation-agent-add.js +38 -0
  329. package/dist/tools/navigation-agent-add.js.map +1 -0
  330. package/dist/tools/navigation-agent-set-destination.d.ts +2 -0
  331. package/dist/tools/navigation-agent-set-destination.js +33 -0
  332. package/dist/tools/navigation-agent-set-destination.js.map +1 -0
  333. package/dist/tools/navigation-get.d.ts +2 -0
  334. package/dist/tools/navigation-get.js +20 -0
  335. package/dist/tools/navigation-get.js.map +1 -0
  336. package/dist/tools/navigation-link-add.d.ts +2 -0
  337. package/dist/tools/navigation-link-add.js +57 -0
  338. package/dist/tools/navigation-link-add.js.map +1 -0
  339. package/dist/tools/navigation-list.d.ts +2 -0
  340. package/dist/tools/navigation-list.js +16 -0
  341. package/dist/tools/navigation-list.js.map +1 -0
  342. package/dist/tools/navigation-modifier-add.d.ts +2 -0
  343. package/dist/tools/navigation-modifier-add.js +42 -0
  344. package/dist/tools/navigation-modifier-add.js.map +1 -0
  345. package/dist/tools/navigation-modifier-volume-add.d.ts +2 -0
  346. package/dist/tools/navigation-modifier-volume-add.js +41 -0
  347. package/dist/tools/navigation-modifier-volume-add.js.map +1 -0
  348. package/dist/tools/navigation-modify.d.ts +2 -0
  349. package/dist/tools/navigation-modify.js +47 -0
  350. package/dist/tools/navigation-modify.js.map +1 -0
  351. package/dist/tools/navigation-set-bake-settings.d.ts +2 -0
  352. package/dist/tools/navigation-set-bake-settings.js +42 -0
  353. package/dist/tools/navigation-set-bake-settings.js.map +1 -0
  354. package/dist/tools/navigation-surface-add.d.ts +2 -0
  355. package/dist/tools/navigation-surface-add.js +62 -0
  356. package/dist/tools/navigation-surface-add.js.map +1 -0
  357. package/dist/tools/navigation-surface-bake.d.ts +2 -0
  358. package/dist/tools/navigation-surface-bake.js +30 -0
  359. package/dist/tools/navigation-surface-bake.js.map +1 -0
  360. package/dist/tools/object-get-data.d.ts +2 -0
  361. package/dist/tools/object-get-data.js +59 -0
  362. package/dist/tools/object-get-data.js.map +1 -0
  363. package/dist/tools/object-modify.d.ts +2 -0
  364. package/dist/tools/object-modify.js +73 -0
  365. package/dist/tools/object-modify.js.map +1 -0
  366. package/dist/tools/package-add.d.ts +2 -0
  367. package/dist/tools/package-add.js +42 -0
  368. package/dist/tools/package-add.js.map +1 -0
  369. package/dist/tools/package-check.d.ts +2 -0
  370. package/dist/tools/package-check.js +27 -0
  371. package/dist/tools/package-check.js.map +1 -0
  372. package/dist/tools/package-get-dependencies.d.ts +2 -0
  373. package/dist/tools/package-get-dependencies.js +17 -0
  374. package/dist/tools/package-get-dependencies.js.map +1 -0
  375. package/dist/tools/package-get-info.d.ts +2 -0
  376. package/dist/tools/package-get-info.js +33 -0
  377. package/dist/tools/package-get-info.js.map +1 -0
  378. package/dist/tools/package-list.d.ts +2 -0
  379. package/dist/tools/package-list.js +57 -0
  380. package/dist/tools/package-list.js.map +1 -0
  381. package/dist/tools/package-remove.d.ts +2 -0
  382. package/dist/tools/package-remove.js +40 -0
  383. package/dist/tools/package-remove.js.map +1 -0
  384. package/dist/tools/package-search.d.ts +2 -0
  385. package/dist/tools/package-search.js +42 -0
  386. package/dist/tools/package-search.js.map +1 -0
  387. package/dist/tools/particle-system-get.d.ts +2 -0
  388. package/dist/tools/particle-system-get.js +42 -0
  389. package/dist/tools/particle-system-get.js.map +1 -0
  390. package/dist/tools/particle-system-modify.d.ts +2 -0
  391. package/dist/tools/particle-system-modify.js +73 -0
  392. package/dist/tools/particle-system-modify.js.map +1 -0
  393. package/dist/tools/ping.d.ts +2 -0
  394. package/dist/tools/ping.js +10 -0
  395. package/dist/tools/ping.js.map +1 -0
  396. package/dist/tools/prefab-apply.d.ts +2 -0
  397. package/dist/tools/prefab-apply.js +39 -0
  398. package/dist/tools/prefab-apply.js.map +1 -0
  399. package/dist/tools/prefab-close.d.ts +2 -0
  400. package/dist/tools/prefab-close.js +29 -0
  401. package/dist/tools/prefab-close.js.map +1 -0
  402. package/dist/tools/prefab-create.d.ts +2 -0
  403. package/dist/tools/prefab-create.js +52 -0
  404. package/dist/tools/prefab-create.js.map +1 -0
  405. package/dist/tools/prefab-get-overrides.d.ts +2 -0
  406. package/dist/tools/prefab-get-overrides.js +27 -0
  407. package/dist/tools/prefab-get-overrides.js.map +1 -0
  408. package/dist/tools/prefab-instantiate.d.ts +2 -0
  409. package/dist/tools/prefab-instantiate.js +52 -0
  410. package/dist/tools/prefab-instantiate.js.map +1 -0
  411. package/dist/tools/prefab-open.d.ts +2 -0
  412. package/dist/tools/prefab-open.js +30 -0
  413. package/dist/tools/prefab-open.js.map +1 -0
  414. package/dist/tools/prefab-revert.d.ts +2 -0
  415. package/dist/tools/prefab-revert.js +37 -0
  416. package/dist/tools/prefab-revert.js.map +1 -0
  417. package/dist/tools/prefab-save.d.ts +2 -0
  418. package/dist/tools/prefab-save.js +24 -0
  419. package/dist/tools/prefab-save.js.map +1 -0
  420. package/dist/tools/prefab-status.d.ts +2 -0
  421. package/dist/tools/prefab-status.js +29 -0
  422. package/dist/tools/prefab-status.js.map +1 -0
  423. package/dist/tools/prefab-unpack.d.ts +2 -0
  424. package/dist/tools/prefab-unpack.js +43 -0
  425. package/dist/tools/prefab-unpack.js.map +1 -0
  426. package/dist/tools/probuilder-create-shape.d.ts +2 -0
  427. package/dist/tools/probuilder-create-shape.js +40 -0
  428. package/dist/tools/probuilder-create-shape.js.map +1 -0
  429. package/dist/tools/probuilder-delete-faces.d.ts +2 -0
  430. package/dist/tools/probuilder-delete-faces.js +47 -0
  431. package/dist/tools/probuilder-delete-faces.js.map +1 -0
  432. package/dist/tools/probuilder-extrude.d.ts +2 -0
  433. package/dist/tools/probuilder-extrude.js +58 -0
  434. package/dist/tools/probuilder-extrude.js.map +1 -0
  435. package/dist/tools/probuilder-get-mesh-info.d.ts +2 -0
  436. package/dist/tools/probuilder-get-mesh-info.js +21 -0
  437. package/dist/tools/probuilder-get-mesh-info.js.map +1 -0
  438. package/dist/tools/probuilder-set-face-material.d.ts +2 -0
  439. package/dist/tools/probuilder-set-face-material.js +53 -0
  440. package/dist/tools/probuilder-set-face-material.js.map +1 -0
  441. package/dist/tools/profiler-capture.d.ts +2 -0
  442. package/dist/tools/profiler-capture.js +84 -0
  443. package/dist/tools/profiler-capture.js.map +1 -0
  444. package/dist/tools/profiler-clear-data.d.ts +2 -0
  445. package/dist/tools/profiler-clear-data.js +20 -0
  446. package/dist/tools/profiler-clear-data.js.map +1 -0
  447. package/dist/tools/profiler-enable-module.d.ts +2 -0
  448. package/dist/tools/profiler-enable-module.js +32 -0
  449. package/dist/tools/profiler-enable-module.js.map +1 -0
  450. package/dist/tools/profiler-get-config.d.ts +2 -0
  451. package/dist/tools/profiler-get-config.js +21 -0
  452. package/dist/tools/profiler-get-config.js.map +1 -0
  453. package/dist/tools/profiler-get-script-stats.d.ts +2 -0
  454. package/dist/tools/profiler-get-script-stats.js +20 -0
  455. package/dist/tools/profiler-get-script-stats.js.map +1 -0
  456. package/dist/tools/profiler-get-status.d.ts +2 -0
  457. package/dist/tools/profiler-get-status.js +22 -0
  458. package/dist/tools/profiler-get-status.js.map +1 -0
  459. package/dist/tools/profiler-list-modules.d.ts +2 -0
  460. package/dist/tools/profiler-list-modules.js +20 -0
  461. package/dist/tools/profiler-list-modules.js.map +1 -0
  462. package/dist/tools/profiler-load-data.d.ts +2 -0
  463. package/dist/tools/profiler-load-data.js +38 -0
  464. package/dist/tools/profiler-load-data.js.map +1 -0
  465. package/dist/tools/profiler-memory.d.ts +2 -0
  466. package/dist/tools/profiler-memory.js +21 -0
  467. package/dist/tools/profiler-memory.js.map +1 -0
  468. package/dist/tools/profiler-rendering.d.ts +2 -0
  469. package/dist/tools/profiler-rendering.js +14 -0
  470. package/dist/tools/profiler-rendering.js.map +1 -0
  471. package/dist/tools/profiler-save-data.d.ts +2 -0
  472. package/dist/tools/profiler-save-data.js +38 -0
  473. package/dist/tools/profiler-save-data.js.map +1 -0
  474. package/dist/tools/profiler-set-config.d.ts +2 -0
  475. package/dist/tools/profiler-set-config.js +72 -0
  476. package/dist/tools/profiler-set-config.js.map +1 -0
  477. package/dist/tools/profiler-start.d.ts +2 -0
  478. package/dist/tools/profiler-start.js +31 -0
  479. package/dist/tools/profiler-start.js.map +1 -0
  480. package/dist/tools/profiler-stop.d.ts +2 -0
  481. package/dist/tools/profiler-stop.js +20 -0
  482. package/dist/tools/profiler-stop.js.map +1 -0
  483. package/dist/tools/pull-events.d.ts +2 -0
  484. package/dist/tools/pull-events.js +43 -0
  485. package/dist/tools/pull-events.js.map +1 -0
  486. package/dist/tools/read-asset.d.ts +2 -0
  487. package/dist/tools/read-asset.js +62 -0
  488. package/dist/tools/read-asset.js.map +1 -0
  489. package/dist/tools/read-compile-errors.d.ts +2 -0
  490. package/dist/tools/read-compile-errors.js +59 -0
  491. package/dist/tools/read-compile-errors.js.map +1 -0
  492. package/dist/tools/read-console.d.ts +2 -0
  493. package/dist/tools/read-console.js +57 -0
  494. package/dist/tools/read-console.js.map +1 -0
  495. package/dist/tools/regression-check.d.ts +2 -0
  496. package/dist/tools/regression-check.js +36 -0
  497. package/dist/tools/regression-check.js.map +1 -0
  498. package/dist/tools/reserialize.d.ts +2 -0
  499. package/dist/tools/reserialize.js +31 -0
  500. package/dist/tools/reserialize.js.map +1 -0
  501. package/dist/tools/run-tests.d.ts +2 -0
  502. package/dist/tools/run-tests.js +49 -0
  503. package/dist/tools/run-tests.js.map +1 -0
  504. package/dist/tools/scan-all.d.ts +2 -0
  505. package/dist/tools/scan-all.js +25 -0
  506. package/dist/tools/scan-all.js.map +1 -0
  507. package/dist/tools/scan-paths.d.ts +2 -0
  508. package/dist/tools/scan-paths.js +40 -0
  509. package/dist/tools/scan-paths.js.map +1 -0
  510. package/dist/tools/scene-create.d.ts +2 -0
  511. package/dist/tools/scene-create.js +47 -0
  512. package/dist/tools/scene-create.js.map +1 -0
  513. package/dist/tools/scene-focus.d.ts +2 -0
  514. package/dist/tools/scene-focus.js +55 -0
  515. package/dist/tools/scene-focus.js.map +1 -0
  516. package/dist/tools/scene-get-data.d.ts +2 -0
  517. package/dist/tools/scene-get-data.js +52 -0
  518. package/dist/tools/scene-get-data.js.map +1 -0
  519. package/dist/tools/scene-get-dirty-summary.d.ts +2 -0
  520. package/dist/tools/scene-get-dirty-summary.js +17 -0
  521. package/dist/tools/scene-get-dirty-summary.js.map +1 -0
  522. package/dist/tools/scene-list-opened.d.ts +2 -0
  523. package/dist/tools/scene-list-opened.js +16 -0
  524. package/dist/tools/scene-list-opened.js.map +1 -0
  525. package/dist/tools/scene-open.d.ts +2 -0
  526. package/dist/tools/scene-open.js +48 -0
  527. package/dist/tools/scene-open.js.map +1 -0
  528. package/dist/tools/scene-save.d.ts +2 -0
  529. package/dist/tools/scene-save.js +38 -0
  530. package/dist/tools/scene-save.js.map +1 -0
  531. package/dist/tools/scene-set-active.d.ts +2 -0
  532. package/dist/tools/scene-set-active.js +33 -0
  533. package/dist/tools/scene-set-active.js.map +1 -0
  534. package/dist/tools/scene-unload.d.ts +2 -0
  535. package/dist/tools/scene-unload.js +33 -0
  536. package/dist/tools/scene-unload.js.map +1 -0
  537. package/dist/tools/screenshot-camera.d.ts +2 -0
  538. package/dist/tools/screenshot-camera.js +59 -0
  539. package/dist/tools/screenshot-camera.js.map +1 -0
  540. package/dist/tools/screenshot-window.d.ts +2 -0
  541. package/dist/tools/screenshot-window.js +54 -0
  542. package/dist/tools/screenshot-window.js.map +1 -0
  543. package/dist/tools/screenshot.d.ts +2 -0
  544. package/dist/tools/screenshot.js +47 -0
  545. package/dist/tools/screenshot.js.map +1 -0
  546. package/dist/tools/script-delete.d.ts +2 -0
  547. package/dist/tools/script-delete.js +37 -0
  548. package/dist/tools/script-delete.js.map +1 -0
  549. package/dist/tools/script-read.d.ts +2 -0
  550. package/dist/tools/script-read.js +46 -0
  551. package/dist/tools/script-read.js.map +1 -0
  552. package/dist/tools/script-write.d.ts +2 -0
  553. package/dist/tools/script-write.js +56 -0
  554. package/dist/tools/script-write.js.map +1 -0
  555. package/dist/tools/search-assets.d.ts +2 -0
  556. package/dist/tools/search-assets.js +49 -0
  557. package/dist/tools/search-assets.js.map +1 -0
  558. package/dist/tools/selection-get.d.ts +2 -0
  559. package/dist/tools/selection-get.js +28 -0
  560. package/dist/tools/selection-get.js.map +1 -0
  561. package/dist/tools/selection-set.d.ts +2 -0
  562. package/dist/tools/selection-set.js +72 -0
  563. package/dist/tools/selection-set.js.map +1 -0
  564. package/dist/tools/settings-get-lighting.d.ts +2 -0
  565. package/dist/tools/settings-get-lighting.js +21 -0
  566. package/dist/tools/settings-get-lighting.js.map +1 -0
  567. package/dist/tools/settings-get-physics.d.ts +2 -0
  568. package/dist/tools/settings-get-physics.js +17 -0
  569. package/dist/tools/settings-get-physics.js.map +1 -0
  570. package/dist/tools/settings-get-player.d.ts +2 -0
  571. package/dist/tools/settings-get-player.js +16 -0
  572. package/dist/tools/settings-get-player.js.map +1 -0
  573. package/dist/tools/settings-get-quality.d.ts +2 -0
  574. package/dist/tools/settings-get-quality.js +16 -0
  575. package/dist/tools/settings-get-quality.js.map +1 -0
  576. package/dist/tools/settings-set-lighting.d.ts +2 -0
  577. package/dist/tools/settings-set-lighting.js +58 -0
  578. package/dist/tools/settings-set-lighting.js.map +1 -0
  579. package/dist/tools/settings-set-physics.d.ts +2 -0
  580. package/dist/tools/settings-set-physics.js +52 -0
  581. package/dist/tools/settings-set-physics.js.map +1 -0
  582. package/dist/tools/settings-set-player.d.ts +2 -0
  583. package/dist/tools/settings-set-player.js +62 -0
  584. package/dist/tools/settings-set-player.js.map +1 -0
  585. package/dist/tools/settings-set-quality.d.ts +2 -0
  586. package/dist/tools/settings-set-quality.js +51 -0
  587. package/dist/tools/settings-set-quality.js.map +1 -0
  588. package/dist/tools/shader-get-data.d.ts +2 -0
  589. package/dist/tools/shader-get-data.js +31 -0
  590. package/dist/tools/shader-get-data.js.map +1 -0
  591. package/dist/tools/shader-list-all.d.ts +2 -0
  592. package/dist/tools/shader-list-all.js +24 -0
  593. package/dist/tools/shader-list-all.js.map +1 -0
  594. package/dist/tools/spatial-query.d.ts +2 -0
  595. package/dist/tools/spatial-query.js +117 -0
  596. package/dist/tools/spatial-query.js.map +1 -0
  597. package/dist/tools/splines-add-knot.d.ts +2 -0
  598. package/dist/tools/splines-add-knot.js +44 -0
  599. package/dist/tools/splines-add-knot.js.map +1 -0
  600. package/dist/tools/splines-container-create.d.ts +2 -0
  601. package/dist/tools/splines-container-create.js +39 -0
  602. package/dist/tools/splines-container-create.js.map +1 -0
  603. package/dist/tools/splines-evaluate.d.ts +2 -0
  604. package/dist/tools/splines-evaluate.js +31 -0
  605. package/dist/tools/splines-evaluate.js.map +1 -0
  606. package/dist/tools/splines-get-knots.d.ts +2 -0
  607. package/dist/tools/splines-get-knots.js +25 -0
  608. package/dist/tools/splines-get-knots.js.map +1 -0
  609. package/dist/tools/splines-modify.d.ts +2 -0
  610. package/dist/tools/splines-modify.js +35 -0
  611. package/dist/tools/splines-modify.js.map +1 -0
  612. package/dist/tools/splines-set-knot.d.ts +2 -0
  613. package/dist/tools/splines-set-knot.js +41 -0
  614. package/dist/tools/splines-set-knot.js.map +1 -0
  615. package/dist/tools/splines-set-tangent-mode.d.ts +2 -0
  616. package/dist/tools/splines-set-tangent-mode.js +43 -0
  617. package/dist/tools/splines-set-tangent-mode.js.map +1 -0
  618. package/dist/tools/type-schema.d.ts +2 -0
  619. package/dist/tools/type-schema.js +62 -0
  620. package/dist/tools/type-schema.js.map +1 -0
  621. package/dist/tools/validate-edit.d.ts +2 -0
  622. package/dist/tools/validate-edit.js +43 -0
  623. package/dist/tools/validate-edit.js.map +1 -0
  624. package/dist/unity-install-discovery.d.ts +79 -0
  625. package/dist/unity-install-discovery.js +206 -0
  626. package/dist/unity-install-discovery.js.map +1 -0
  627. package/dist/unity-log.d.ts +35 -0
  628. package/dist/unity-log.js +110 -0
  629. package/dist/unity-log.js.map +1 -0
  630. package/package.json +54 -0
@@ -0,0 +1,1495 @@
1
+ // Offline asset reader — parses text-serialized Unity assets (.prefab/.unity/
2
+ // .asset) from disk without a running Editor. Ported from unity-scanner
3
+ // internal/unityasset (yaml.go, scan.go, kind.go, project.go).
4
+ //
5
+ // Single runtime module (so it loads cleanly under node --experimental-strip-
6
+ // types in tests: no cross-file runtime imports). Type-only contract lives in
7
+ // compression/asset-model.ts (stripped at test time).
8
+ //
9
+ // Exports three entry points used by the compressible-tool router:
10
+ // - readAssetOffline → AssetModel (for read_asset)
11
+ // - searchAssetsOffline → SearchModel (for search_assets)
12
+ // - listAssetsOffline → listing result (for list_assets)
13
+ import { readFile, readdir, stat } from "node:fs/promises";
14
+ import { join, basename, extname, relative, sep } from "node:path";
15
+ // ===========================================================================
16
+ // Native Unity class IDs → names (from unity-scanner yaml.go).
17
+ // ===========================================================================
18
+ const nativeClassNames = {
19
+ 1: "GameObject",
20
+ 4: "Transform",
21
+ 20: "Camera",
22
+ 23: "MeshRenderer",
23
+ 33: "MeshFilter",
24
+ 64: "MeshCollider",
25
+ 65: "BoxCollider",
26
+ 81: "AudioListener",
27
+ 82: "AudioSource",
28
+ 95: "Animator",
29
+ 108: "Light",
30
+ 114: "MonoBehaviour",
31
+ 115: "MonoScript",
32
+ 120: "LineRenderer",
33
+ 137: "SkinnedMeshRenderer",
34
+ 156: "Terrain",
35
+ 198: "ParticleSystem",
36
+ 212: "SpriteRenderer",
37
+ 222: "CanvasRenderer",
38
+ 223: "Canvas",
39
+ 224: "RectTransform",
40
+ 225: "CanvasGroup",
41
+ 329: "VideoPlayer",
42
+ 73398921: "VFXRenderer",
43
+ };
44
+ function nativeClassName(classID) {
45
+ return nativeClassNames[classID] ?? "";
46
+ }
47
+ // ===========================================================================
48
+ // Kind / extension utilities (from unity-scanner kind.go).
49
+ // ===========================================================================
50
+ const extToKind = {
51
+ ".anim": "anim",
52
+ ".asset": "asset",
53
+ ".controller": "controller",
54
+ ".cs": "cs",
55
+ ".mat": "mat",
56
+ ".overrideController": "controller",
57
+ ".physicsMaterial2D": "physics2d",
58
+ ".physicMaterial": "physics",
59
+ ".playable": "playable",
60
+ ".prefab": "prefab",
61
+ ".shader": "shader",
62
+ ".spriteatlas": "atlas",
63
+ ".unity": "scene",
64
+ ".uss": "uss",
65
+ ".uxml": "uxml",
66
+ ".meta": "meta",
67
+ };
68
+ const kindAliases = {
69
+ prefabs: "prefab",
70
+ scenes: "scene",
71
+ unity: "scene",
72
+ scripts: "cs",
73
+ script: "cs",
74
+ material: "mat",
75
+ materials: "mat",
76
+ };
77
+ function kindForPath(path) {
78
+ const ext = extname(path);
79
+ if (extToKind[ext])
80
+ return extToKind[ext];
81
+ if (ext === "")
82
+ return "none";
83
+ return ext.slice(1).toLowerCase();
84
+ }
85
+ function normalizeKind(kind) {
86
+ const trimmed = kind.trim().toLowerCase();
87
+ if (kindAliases[trimmed])
88
+ return kindAliases[trimmed];
89
+ return trimmed;
90
+ }
91
+ function parseKindSet(raw) {
92
+ const out = new Set();
93
+ for (const part of raw.split(",")) {
94
+ const kind = normalizeKind(part);
95
+ if (kind !== "")
96
+ out.add(kind);
97
+ }
98
+ return out;
99
+ }
100
+ const skipDirs = new Set([
101
+ ".git", ".vs", "Library", "Logs", "obj", "Obj",
102
+ "Temp", "Build", "Builds", "UserSettings", "node_modules",
103
+ ]);
104
+ function shouldSkipDir(name) {
105
+ return skipDirs.has(name);
106
+ }
107
+ // ===========================================================================
108
+ // YAML parser — split YAML into documents, extract key fields per object.
109
+ // (Ported from unity-scanner yaml.go ParseAssetWithOptions.)
110
+ // ===========================================================================
111
+ function parseAsset(data) {
112
+ const objects = [];
113
+ const byID = new Map();
114
+ const lines = data.split("\n");
115
+ let current = null;
116
+ for (const line of lines) {
117
+ const header = parseHeaderLine(line);
118
+ if (header) {
119
+ if (current)
120
+ finishObject(current, objects, byID);
121
+ current = {
122
+ id: header.id,
123
+ classID: header.classID,
124
+ type: "",
125
+ lines: [],
126
+ order: objects.length,
127
+ name: "",
128
+ componentIDs: [],
129
+ gameObjectID: "",
130
+ fatherTransformID: "",
131
+ sourceObjectID: "",
132
+ sourceGUID: "",
133
+ scriptGUID: "",
134
+ };
135
+ continue;
136
+ }
137
+ if (current === null)
138
+ continue;
139
+ current.lines.push(line);
140
+ scanObjectTypeLine(current, line);
141
+ }
142
+ if (current)
143
+ finishObject(current, objects, byID);
144
+ if (objects.length === 0) {
145
+ throw new Error("no Unity YAML objects found");
146
+ }
147
+ applyPrefabNameOverrides(objects);
148
+ return { path: "", kind: "", guid: "", objects, byID };
149
+ }
150
+ function finishObject(o, objects, byID) {
151
+ if (o.lines.length > 0) {
152
+ o.name = readScalar(o.lines, "m_Name");
153
+ switch (o.type) {
154
+ case "GameObject":
155
+ o.componentIDs = readComponentIDs(o.lines);
156
+ break;
157
+ case "Transform":
158
+ case "RectTransform":
159
+ o.gameObjectID = readFileIDField(o.lines, "m_GameObject");
160
+ o.fatherTransformID = readFileIDField(o.lines, "m_Father");
161
+ break;
162
+ default:
163
+ o.gameObjectID = readFileIDField(o.lines, "m_GameObject");
164
+ break;
165
+ }
166
+ o.sourceObjectID = readFileIDField(o.lines, "m_CorrespondingSourceObject");
167
+ o.sourceGUID = readGUIDField(o.lines, "m_CorrespondingSourceObject");
168
+ if (o.type === "MonoBehaviour") {
169
+ o.scriptGUID = readGUIDField(o.lines, "m_Script");
170
+ }
171
+ }
172
+ objects.push(o);
173
+ byID.set(o.id, o);
174
+ }
175
+ // ===========================================================================
176
+ // Hierarchy — build GameObject tree from Transform parent links.
177
+ // ===========================================================================
178
+ function buildHierarchy(asset) {
179
+ const transformToGO = new Map();
180
+ const goToTransform = new Map();
181
+ const parentTransform = new Map();
182
+ for (const obj of asset.objects) {
183
+ if (obj.type !== "Transform" && obj.type !== "RectTransform")
184
+ continue;
185
+ transformToGO.set(obj.id, obj.gameObjectID);
186
+ goToTransform.set(obj.gameObjectID, obj.id);
187
+ parentTransform.set(obj.id, obj.fatherTransformID);
188
+ }
189
+ const gameObjects = asset.objects.filter((o) => o.type === "GameObject");
190
+ const nodes = new Map();
191
+ for (const go of gameObjects) {
192
+ nodes.set(go.id, { gameObject: go, children: [], path: "", depth: 0 });
193
+ }
194
+ const hasParent = new Set();
195
+ for (const [goID, transformID] of goToTransform) {
196
+ const node = nodes.get(goID);
197
+ if (!node)
198
+ continue;
199
+ const parentGO = transformToGO.get(parentTransform.get(transformID) ?? "");
200
+ const parent = parentGO ? nodes.get(parentGO) : undefined;
201
+ if (!parent || parent === node)
202
+ continue;
203
+ parent.children.push(node);
204
+ hasParent.add(goID);
205
+ }
206
+ const roots = [];
207
+ for (const go of gameObjects) {
208
+ const node = nodes.get(go.id);
209
+ if (!node || hasParent.has(go.id))
210
+ continue;
211
+ roots.push(node);
212
+ }
213
+ sortNodes(roots);
214
+ for (const root of roots)
215
+ assignNodePath(root, "", 0);
216
+ return roots;
217
+ }
218
+ function sortNodes(nodes) {
219
+ nodes.sort((a, b) => a.gameObject.order - b.gameObject.order);
220
+ for (const node of nodes)
221
+ sortNodes(node.children);
222
+ }
223
+ function assignNodePath(node, parent, depth) {
224
+ node.depth = depth;
225
+ let name = node.gameObject.name;
226
+ if (name === "")
227
+ name = `<unnamed:${node.gameObject.id}>`;
228
+ node.path = parent === "" ? name : `${parent}/${name}`;
229
+ for (const child of node.children) {
230
+ assignNodePath(child, node.path, depth + 1);
231
+ }
232
+ }
233
+ // ===========================================================================
234
+ // Components — resolve component objects for a GameObject.
235
+ // ===========================================================================
236
+ function componentsFor(asset, goID, scriptIndex) {
237
+ const goObj = asset.byID.get(goID);
238
+ if (!goObj)
239
+ return [];
240
+ const out = [];
241
+ const seen = new Set();
242
+ for (const compID of goObj.componentIDs) {
243
+ const compObj = asset.byID.get(compID);
244
+ if (!compObj)
245
+ continue;
246
+ seen.add(compObj.id);
247
+ const { name, scriptPath } = componentName(compObj, scriptIndex);
248
+ out.push({ object: compObj, name, scriptPath });
249
+ }
250
+ for (const compObj of asset.objects) {
251
+ if (compObj.gameObjectID !== goID || seen.has(compObj.id) || compObj.type === "GameObject")
252
+ continue;
253
+ seen.add(compObj.id);
254
+ const { name, scriptPath } = componentName(compObj, scriptIndex);
255
+ out.push({ object: compObj, name, scriptPath });
256
+ }
257
+ return out;
258
+ }
259
+ function componentName(obj, scriptIndex) {
260
+ if (obj.type === "MonoBehaviour") {
261
+ const path = scriptIndex.get(obj.scriptGUID);
262
+ if (path) {
263
+ const base = basename(path);
264
+ const ext = extname(path);
265
+ const name = ext ? base.slice(0, -ext.length) : base;
266
+ return { name, scriptPath: path };
267
+ }
268
+ if (obj.scriptGUID !== "") {
269
+ return { name: `MonoBehaviour(${shortGUID(obj.scriptGUID)})`, scriptPath: "" };
270
+ }
271
+ }
272
+ const native = nativeClassName(obj.classID);
273
+ if (native)
274
+ return { name: native, scriptPath: "" };
275
+ if (obj.type !== "")
276
+ return { name: obj.type, scriptPath: "" };
277
+ return { name: `ClassID:${obj.classID}`, scriptPath: "" };
278
+ }
279
+ // ===========================================================================
280
+ // Fields — extract top-level serialized fields.
281
+ // ===========================================================================
282
+ const skipFieldNames = new Set([
283
+ "m_Name", "m_ObjectHideFlags", "m_CorrespondingSourceObject",
284
+ "m_PrefabInstance", "m_PrefabAsset", "serializedVersion",
285
+ "m_GameObject", "m_Script", "m_Enabled",
286
+ "m_EditorHideFlags", "m_EditorClassIdentifier", "m_Modification",
287
+ ]);
288
+ function fieldsWithHidden(asset, obj, limit, guidIndex) {
289
+ const fields = [];
290
+ let hidden = 0;
291
+ for (let i = 0; i < obj.lines.length; i++) {
292
+ const line = obj.lines[i];
293
+ if (!isTopLevelFieldLine(line))
294
+ continue;
295
+ const trim = line.trim();
296
+ const colonIdx = trim.indexOf(":");
297
+ if (colonIdx < 0)
298
+ continue;
299
+ const key = trim.slice(0, colonIdx).trim();
300
+ if (skipFieldNames.has(key))
301
+ continue;
302
+ if (limit > 0 && fields.length >= limit) {
303
+ hidden++;
304
+ continue;
305
+ }
306
+ let value = trim.slice(colonIdx + 1).trim();
307
+ if (value === "") {
308
+ value = summarizeNested(obj.lines, i + 1);
309
+ }
310
+ value = resolveReferences(value, guidIndex, asset);
311
+ fields.push({ name: displayFieldName(key), value });
312
+ }
313
+ return { fields, hidden };
314
+ }
315
+ function displayFieldName(name) {
316
+ if (name.startsWith("<") && name.endsWith(">k__BackingField")) {
317
+ return name.slice(1, -">k__BackingField".length);
318
+ }
319
+ return name;
320
+ }
321
+ function isTopLevelFieldLine(line) {
322
+ return (line.startsWith(" ") &&
323
+ !line.startsWith(" ") &&
324
+ !line.startsWith(" -"));
325
+ }
326
+ function summarizeNested(lines, start) {
327
+ const maxParts = 4;
328
+ const parts = [];
329
+ let parent = "";
330
+ let sequenceIndex = 0;
331
+ for (let i = start; i < lines.length; i++) {
332
+ const line = lines[i];
333
+ if (line.startsWith(" ") && !line.startsWith(" ") && !line.startsWith(" -"))
334
+ break;
335
+ const trim = line.trim();
336
+ if (trim === "")
337
+ continue;
338
+ if (trim.startsWith("- ")) {
339
+ let v = trim.slice(2);
340
+ if (parent !== "") {
341
+ v = `${parent}[${sequenceIndex}]: ${v}`;
342
+ sequenceIndex++;
343
+ }
344
+ parts.push(v);
345
+ }
346
+ else if (trim.endsWith(":")) {
347
+ parent = trim.slice(0, -1);
348
+ sequenceIndex = 0;
349
+ continue;
350
+ }
351
+ else {
352
+ parts.push(trim.split(/\s+/).join(" "));
353
+ }
354
+ if (parts.length >= maxParts)
355
+ break;
356
+ }
357
+ if (parts.length === 0)
358
+ return "<object>";
359
+ return parts.join(" | ");
360
+ }
361
+ // ===========================================================================
362
+ // Reference resolution.
363
+ // ===========================================================================
364
+ function resolveReferences(value, guidIndex, asset) {
365
+ const guids = findGUIDs(value);
366
+ if (guids.length > 0) {
367
+ const refs = [];
368
+ const seen = new Set();
369
+ for (const guid of guids) {
370
+ const path = guidIndex.get(guid);
371
+ if (!path || seen.has(path))
372
+ continue;
373
+ seen.add(path);
374
+ const name = basename(path);
375
+ const ext = extname(name);
376
+ refs.push(ext ? name.slice(0, -ext.length) : name);
377
+ }
378
+ if (refs.length > 0)
379
+ return `${value} -> ${refs.join(", ")}`;
380
+ }
381
+ if (guids.length === 0) {
382
+ const refs = [];
383
+ const seen = new Set();
384
+ for (const fileID of findFileIDs(value)) {
385
+ const label = localReferenceLabel(asset, fileID);
386
+ if (label === "" || seen.has(label))
387
+ continue;
388
+ seen.add(label);
389
+ refs.push(label);
390
+ }
391
+ if (refs.length > 0)
392
+ return `${value} -> ${refs.join(", ")}`;
393
+ }
394
+ return value;
395
+ }
396
+ function localReferenceLabel(asset, fileID, scriptIndex = new Map()) {
397
+ if (fileID === "" || fileID === "0")
398
+ return "";
399
+ const obj = asset.byID.get(fileID);
400
+ if (!obj)
401
+ return "";
402
+ if (obj.type === "GameObject")
403
+ return objectPath(asset, obj.id);
404
+ const { name } = componentName(obj, scriptIndex);
405
+ if (obj.gameObjectID !== "") {
406
+ const path = objectPath(asset, obj.gameObjectID);
407
+ if (path)
408
+ return `${name} on ${path}`;
409
+ }
410
+ if (obj.name !== "")
411
+ return `${name} ${obj.name}`;
412
+ return `${name} ${obj.id}`;
413
+ }
414
+ function objectPath(asset, goID) {
415
+ for (const node of flattenNodes(asset)) {
416
+ if (node.gameObject.id === goID)
417
+ return node.path;
418
+ }
419
+ const obj = asset.byID.get(goID);
420
+ return obj ? obj.name : "";
421
+ }
422
+ function flattenNodes(asset) {
423
+ const out = [];
424
+ const walk = (nodes) => {
425
+ for (const node of nodes) {
426
+ out.push(node);
427
+ walk(node.children);
428
+ }
429
+ };
430
+ walk(buildHierarchy(asset));
431
+ return out;
432
+ }
433
+ // ===========================================================================
434
+ // Prefab override name resolution + override parsing.
435
+ // ===========================================================================
436
+ function applyPrefabNameOverrides(objects) {
437
+ const names = new Map();
438
+ for (const obj of objects) {
439
+ if (obj.type !== "PrefabInstance")
440
+ continue;
441
+ for (const override of parsePrefabOverrides(obj.lines)) {
442
+ if (override.kind !== "property" || override.propertyPath !== "m_Name" || override.value === "")
443
+ continue;
444
+ const id = extractFileID(override.target);
445
+ const guid = extractGUID(override.target);
446
+ if (id === "" || guid === "")
447
+ continue;
448
+ names.set(`${guid.toLowerCase()}\0${id}`, override.value);
449
+ }
450
+ }
451
+ if (names.size === 0)
452
+ return;
453
+ for (const obj of objects) {
454
+ if (obj.name !== "" || obj.sourceObjectID === "" || obj.sourceGUID === "")
455
+ continue;
456
+ const name = names.get(`${obj.sourceGUID.toLowerCase()}\0${obj.sourceObjectID}`);
457
+ if (name)
458
+ obj.name = name;
459
+ }
460
+ }
461
+ function parsePrefabOverrides(lines) {
462
+ const out = [];
463
+ let section = "";
464
+ for (let i = 0; i < lines.length; i++) {
465
+ const trim = lines[i].trim();
466
+ switch (trim) {
467
+ case "m_Modifications:":
468
+ section = "modifications";
469
+ continue;
470
+ case "m_RemovedComponents:":
471
+ section = "removed-components";
472
+ continue;
473
+ case "m_RemovedGameObjects:":
474
+ section = "removed-gameobjects";
475
+ continue;
476
+ case "m_AddedComponents:":
477
+ section = "added-components";
478
+ continue;
479
+ case "m_AddedGameObjects:":
480
+ section = "added-gameobjects";
481
+ continue;
482
+ }
483
+ if (!trim.startsWith("- "))
484
+ continue;
485
+ switch (section) {
486
+ case "modifications": {
487
+ const { override, next } = parsePrefabPropertyOverride(lines, i);
488
+ if (override.target !== "")
489
+ out.push(override);
490
+ i = next;
491
+ break;
492
+ }
493
+ case "removed-components":
494
+ case "removed-gameobjects": {
495
+ const target = trim.slice(2).trim();
496
+ if (target !== "" && target !== "[]") {
497
+ out.push({ kind: section, target, propertyPath: "", value: "", addedObject: "" });
498
+ }
499
+ break;
500
+ }
501
+ case "added-components": {
502
+ const { override, next } = parsePrefabAddedComponentOverride(lines, i, "added-component");
503
+ if (override.target !== "" || override.addedObject !== "")
504
+ out.push(override);
505
+ i = next;
506
+ break;
507
+ }
508
+ case "added-gameobjects": {
509
+ const { override, next } = parsePrefabAddedComponentOverride(lines, i, "added-gameobjects");
510
+ if (override.target !== "" || override.addedObject !== "")
511
+ out.push(override);
512
+ i = next;
513
+ break;
514
+ }
515
+ }
516
+ }
517
+ return out;
518
+ }
519
+ function parsePrefabPropertyOverride(lines, start) {
520
+ const override = { kind: "property", target: "", propertyPath: "", value: "", addedObject: "" };
521
+ for (let i = start; i < lines.length; i++) {
522
+ const trim = lines[i].trim();
523
+ if (i > start && isPrefabOverrideSection(trim))
524
+ return { override, next: i - 1 };
525
+ if (i > start && trim.startsWith("- "))
526
+ return { override, next: i - 1 };
527
+ if (trim.startsWith("- target:")) {
528
+ override.target = trim.slice("- target:".length).trim();
529
+ }
530
+ else if (trim.startsWith("propertyPath:")) {
531
+ override.propertyPath = displayFieldName(cleanScalar(trim.slice("propertyPath:".length).trim()));
532
+ }
533
+ else if (trim.startsWith("value:")) {
534
+ override.value = cleanScalar(trim.slice("value:".length).trim());
535
+ }
536
+ else if (trim.startsWith("objectReference:") && override.value === "") {
537
+ override.value = trim.slice("objectReference:".length).trim();
538
+ }
539
+ }
540
+ return { override, next: lines.length - 1 };
541
+ }
542
+ function parsePrefabAddedComponentOverride(lines, start, kind) {
543
+ const override = { kind, target: "", propertyPath: "", value: "", addedObject: "" };
544
+ for (let i = start; i < lines.length; i++) {
545
+ const trim = lines[i].trim();
546
+ if (i > start && isPrefabOverrideSection(trim))
547
+ return { override, next: i - 1 };
548
+ if (i > start && trim.startsWith("- "))
549
+ return { override, next: i - 1 };
550
+ if (trim.startsWith("- targetCorrespondingSourceObject:")) {
551
+ override.target = trim.slice("- targetCorrespondingSourceObject:".length).trim();
552
+ }
553
+ else if (trim.startsWith("addedObject:")) {
554
+ override.addedObject = trim.slice("addedObject:".length).trim();
555
+ }
556
+ }
557
+ return { override, next: lines.length - 1 };
558
+ }
559
+ function isPrefabOverrideSection(trim) {
560
+ switch (trim) {
561
+ case "m_Modifications:":
562
+ case "m_RemovedComponents:":
563
+ case "m_RemovedGameObjects:":
564
+ case "m_AddedComponents:":
565
+ case "m_AddedGameObjects:":
566
+ return true;
567
+ default:
568
+ return false;
569
+ }
570
+ }
571
+ // ===========================================================================
572
+ // Prefab override collection — resolve raw overrides to readable labels.
573
+ // ===========================================================================
574
+ function buildSourceMap(parsed) {
575
+ const map = new Map();
576
+ for (const obj of parsed.objects) {
577
+ if (obj.sourceObjectID === "" || obj.sourceGUID === "")
578
+ continue;
579
+ map.set(`${obj.sourceGUID.toLowerCase()}\0${obj.sourceObjectID}`, obj);
580
+ }
581
+ return map;
582
+ }
583
+ function collectOverrides(parsed, scriptIndex, guidIndex) {
584
+ const sourceMap = buildSourceMap(parsed);
585
+ const entries = [];
586
+ for (const obj of parsed.objects) {
587
+ if (obj.type !== "PrefabInstance")
588
+ continue;
589
+ for (const ov of parsePrefabOverrides(obj.lines)) {
590
+ entries.push(resolveOverrideEntry(ov, parsed, sourceMap, scriptIndex, guidIndex));
591
+ }
592
+ }
593
+ return entries;
594
+ }
595
+ function resolveOverrideEntry(ov, parsed, sourceMap, scriptIndex, guidIndex) {
596
+ const entry = { kind: ov.kind };
597
+ switch (ov.kind) {
598
+ case "property":
599
+ entry.propertyPath = ov.propertyPath;
600
+ entry.value = normalizeOverrideValue(ov.value, guidIndex, parsed);
601
+ entry.target = resolveOverrideTarget(ov.target, sourceMap, parsed, scriptIndex);
602
+ break;
603
+ case "added-component":
604
+ case "added-gameobjects":
605
+ entry.target = resolveOverrideTarget(ov.target, sourceMap, parsed, scriptIndex);
606
+ entry.addedObject = resolveAddedObject(ov.addedObject, parsed, scriptIndex);
607
+ break;
608
+ default:
609
+ entry.target = resolveOverrideTarget(ov.target, sourceMap, parsed, scriptIndex);
610
+ break;
611
+ }
612
+ return entry;
613
+ }
614
+ function normalizeOverrideValue(value, guidIndex, parsed) {
615
+ const trimmed = value.trim();
616
+ if (trimmed === "{fileID: 0}" || trimmed === "{}")
617
+ return "null";
618
+ return resolveReferences(value, guidIndex, parsed);
619
+ }
620
+ function resolveOverrideTarget(target, sourceMap, parsed, scriptIndex) {
621
+ if (target === "")
622
+ return undefined;
623
+ const fileID = extractFileID(target);
624
+ const guid = extractGUID(target);
625
+ if (fileID === "" && guid === "")
626
+ return undefined;
627
+ if (guid !== "" && fileID !== "") {
628
+ const localObj = sourceMap.get(`${guid.toLowerCase()}\0${fileID}`);
629
+ if (localObj) {
630
+ return labelForParsedObject(localObj, parsed, scriptIndex);
631
+ }
632
+ }
633
+ if (fileID !== "") {
634
+ const label = localReferenceLabel(parsed, fileID, scriptIndex);
635
+ if (label)
636
+ return label;
637
+ }
638
+ return undefined;
639
+ }
640
+ function resolveAddedObject(addedObject, parsed, scriptIndex) {
641
+ if (addedObject === "")
642
+ return undefined;
643
+ const fileID = extractFileID(addedObject);
644
+ if (fileID === "")
645
+ return undefined;
646
+ const label = localReferenceLabel(parsed, fileID, scriptIndex);
647
+ return label || undefined;
648
+ }
649
+ function labelForParsedObject(obj, parsed, scriptIndex) {
650
+ if (obj.type === "GameObject")
651
+ return objectPath(parsed, obj.id);
652
+ const { name } = componentName(obj, scriptIndex);
653
+ if (obj.gameObjectID !== "") {
654
+ const path = objectPath(parsed, obj.gameObjectID);
655
+ if (path)
656
+ return `${name} on ${path}`;
657
+ }
658
+ if (obj.name !== "")
659
+ return `${name} ${obj.name}`;
660
+ return `${name} ${obj.id}`;
661
+ }
662
+ // ===========================================================================
663
+ // Field-level GUID scanning.
664
+ // ===========================================================================
665
+ function fieldGUIDs(obj) {
666
+ const guids = new Set();
667
+ for (const line of obj.lines) {
668
+ if (!line.includes("guid:") || line.includes("m_Script"))
669
+ continue;
670
+ for (const guid of findGUIDs(line))
671
+ guids.add(guid);
672
+ }
673
+ return guids;
674
+ }
675
+ function scriptGUIDs(asset) {
676
+ const guids = new Set();
677
+ for (const obj of asset.objects) {
678
+ if (obj.scriptGUID !== "")
679
+ guids.add(obj.scriptGUID);
680
+ }
681
+ return guids;
682
+ }
683
+ // ===========================================================================
684
+ // Line-scanning helpers.
685
+ // ===========================================================================
686
+ function scanObjectTypeLine(obj, line) {
687
+ if (obj.type !== "" || line.length <= 1 || line[0] === " " || !line.endsWith(":")) {
688
+ return false;
689
+ }
690
+ obj.type = line.slice(0, -1).trim();
691
+ return true;
692
+ }
693
+ function parseHeaderLine(line) {
694
+ const prefix = "--- !u!";
695
+ if (!line.startsWith(prefix))
696
+ return null;
697
+ const rest = line.slice(prefix.length);
698
+ const space = rest.indexOf(" ");
699
+ if (space <= 0 || space + 2 > rest.length || rest[space + 1] !== "&")
700
+ return null;
701
+ const classID = parsePositiveInt(rest.slice(0, space));
702
+ if (classID === null)
703
+ return null;
704
+ let id = rest.slice(space + 2);
705
+ const fields = id.split(/\s+/);
706
+ if (fields.length > 0)
707
+ id = fields[0];
708
+ if (id === "")
709
+ return null;
710
+ return { classID, id };
711
+ }
712
+ function parsePositiveInt(value) {
713
+ if (value.length === 0)
714
+ return null;
715
+ let out = 0;
716
+ for (const ch of value) {
717
+ if (ch < "0" || ch > "9")
718
+ return null;
719
+ out = out * 10 + (ch.charCodeAt(0) - "0".charCodeAt(0));
720
+ }
721
+ return out;
722
+ }
723
+ function readScalar(lines, key) {
724
+ const prefix = ` ${key}:`;
725
+ for (const line of lines) {
726
+ if (line.startsWith(prefix))
727
+ return cleanScalar(line.slice(prefix.length).trim());
728
+ }
729
+ return "";
730
+ }
731
+ function readFileIDField(lines, key) {
732
+ const prefix = ` ${key}:`;
733
+ for (const line of lines) {
734
+ if (line.startsWith(prefix))
735
+ return extractFileID(line);
736
+ }
737
+ return "";
738
+ }
739
+ function readGUIDField(lines, key) {
740
+ const prefix = ` ${key}:`;
741
+ for (const line of lines) {
742
+ if (line.startsWith(prefix))
743
+ return extractGUID(line);
744
+ }
745
+ return "";
746
+ }
747
+ function readComponentIDs(lines) {
748
+ const ids = [];
749
+ for (const line of lines) {
750
+ if (line.includes("- component:")) {
751
+ const id = extractFileID(line);
752
+ if (id !== "" && id !== "0")
753
+ ids.push(id);
754
+ }
755
+ }
756
+ return ids;
757
+ }
758
+ function extractFileID(line) {
759
+ const start = line.indexOf("fileID:");
760
+ if (start < 0)
761
+ return "";
762
+ let i = start + "fileID:".length;
763
+ while (i < line.length && line[i] === " ")
764
+ i++;
765
+ const begin = i;
766
+ if (i < line.length && line[i] === "-")
767
+ i++;
768
+ while (i < line.length && line[i] >= "0" && line[i] <= "9")
769
+ i++;
770
+ if (i === begin || (line[begin] === "-" && i === begin + 1))
771
+ return "";
772
+ return line.slice(begin, i);
773
+ }
774
+ function extractGUID(line) {
775
+ const start = line.indexOf("guid:");
776
+ if (start < 0)
777
+ return "";
778
+ return scanGUID(line.slice(start + "guid:".length));
779
+ }
780
+ function findGUIDs(value) {
781
+ const out = [];
782
+ let offset = 0;
783
+ while (offset < value.length) {
784
+ const start = value.indexOf("guid:", offset);
785
+ if (start < 0)
786
+ break;
787
+ offset = start + "guid:".length;
788
+ const guid = scanGUID(value.slice(offset));
789
+ if (guid !== "") {
790
+ out.push(guid);
791
+ offset += guid.length;
792
+ }
793
+ }
794
+ return out;
795
+ }
796
+ function findFileIDs(value) {
797
+ const out = [];
798
+ let offset = 0;
799
+ while (offset < value.length) {
800
+ const start = value.indexOf("fileID:", offset);
801
+ if (start < 0)
802
+ break;
803
+ offset = start + "fileID:".length;
804
+ while (offset < value.length && value[offset] === " ")
805
+ offset++;
806
+ const begin = offset;
807
+ if (offset < value.length && value[offset] === "-")
808
+ offset++;
809
+ while (offset < value.length && value[offset] >= "0" && value[offset] <= "9")
810
+ offset++;
811
+ if (offset === begin || (value[begin] === "-" && offset === begin + 1))
812
+ continue;
813
+ out.push(value.slice(begin, offset));
814
+ }
815
+ return out;
816
+ }
817
+ function scanGUID(value) {
818
+ let i = 0;
819
+ while (i < value.length && value[i] === " ")
820
+ i++;
821
+ const start = i;
822
+ while (i < value.length && isHex(value.charCodeAt(i)))
823
+ i++;
824
+ if (i === start)
825
+ return "";
826
+ return value.slice(start, i).toLowerCase();
827
+ }
828
+ function isHex(code) {
829
+ return ((code >= 48 && code <= 57) ||
830
+ (code >= 97 && code <= 102) ||
831
+ (code >= 65 && code <= 70));
832
+ }
833
+ function cleanScalar(value) {
834
+ value = value.trim();
835
+ if (value.length >= 2 && value[0] === '"' && value[value.length - 1] === '"') {
836
+ try {
837
+ return JSON.parse(value);
838
+ }
839
+ catch {
840
+ return value.slice(1, -1);
841
+ }
842
+ }
843
+ return value;
844
+ }
845
+ function shortGUID(guid) {
846
+ if (guid.length <= 8)
847
+ return guid;
848
+ return guid.slice(0, 8);
849
+ }
850
+ // ===========================================================================
851
+ // GUID index builder — reads .meta files (from unity-scanner yaml.go).
852
+ // ===========================================================================
853
+ function readMetaGUID(data) {
854
+ let start;
855
+ if (data.startsWith("guid:")) {
856
+ start = "guid:".length;
857
+ }
858
+ else {
859
+ const idx = data.indexOf("\nguid:");
860
+ if (idx < 0)
861
+ return "";
862
+ start = idx + 1 + "guid:".length;
863
+ }
864
+ const end = data.indexOf("\n", start);
865
+ const slice = end < 0 ? data.slice(start) : data.slice(start, end);
866
+ return slice.trim();
867
+ }
868
+ function toAssetPath(projectRoot, absPath) {
869
+ let rel = relative(projectRoot, absPath);
870
+ if (sep === "\\")
871
+ rel = rel.replace(/\\/g, "/");
872
+ return rel;
873
+ }
874
+ async function buildGUIDIndex(projectRoot, wanted) {
875
+ const index = new Map();
876
+ if (wanted && wanted.size === 0)
877
+ return index;
878
+ const assetsDir = join(projectRoot, "Assets");
879
+ await walkMeta(assetsDir, async (metaPath) => {
880
+ try {
881
+ const data = await readFile(metaPath, "utf-8");
882
+ let guid = readMetaGUID(data);
883
+ if (guid === "")
884
+ return;
885
+ guid = guid.toLowerCase();
886
+ if (wanted && !wanted.has(guid))
887
+ return;
888
+ index.set(guid, toAssetPath(projectRoot, metaPath.slice(0, -5)));
889
+ }
890
+ catch { /* skip */ }
891
+ });
892
+ return index;
893
+ }
894
+ async function buildScriptIndex(projectRoot, wanted) {
895
+ const index = new Map();
896
+ if (wanted && wanted.size === 0)
897
+ return index;
898
+ const guidIndex = await buildGUIDIndex(projectRoot, wanted);
899
+ for (const [guid, path] of guidIndex) {
900
+ if (path.endsWith(".cs"))
901
+ index.set(guid, path);
902
+ }
903
+ return index;
904
+ }
905
+ async function buildScriptIndexForQuery(projectRoot, query) {
906
+ const index = new Map();
907
+ const q = query.trim().toLowerCase();
908
+ if (q === "")
909
+ return index;
910
+ const assetsDir = join(projectRoot, "Assets");
911
+ await walkMeta(assetsDir, async (metaPath) => {
912
+ if (!metaPath.endsWith(".cs.meta"))
913
+ return;
914
+ const scriptPath = metaPath.slice(0, -5);
915
+ const base = basename(scriptPath);
916
+ const ext = extname(base);
917
+ const name = ext ? base.slice(0, -ext.length) : base;
918
+ if (!name.toLowerCase().includes(q))
919
+ return;
920
+ try {
921
+ const data = await readFile(metaPath, "utf-8");
922
+ const guid = readMetaGUID(data);
923
+ if (guid === "")
924
+ return;
925
+ index.set(guid.toLowerCase(), toAssetPath(projectRoot, scriptPath));
926
+ }
927
+ catch { /* skip */ }
928
+ });
929
+ return index;
930
+ }
931
+ async function walkMeta(dir, fn) {
932
+ let entries;
933
+ try {
934
+ entries = await readdir(dir);
935
+ }
936
+ catch {
937
+ return;
938
+ }
939
+ await Promise.all(entries.map(async (name) => {
940
+ if (shouldSkipDir(name))
941
+ return;
942
+ const fullPath = join(dir, name);
943
+ try {
944
+ const s = await stat(fullPath);
945
+ if (s.isDirectory())
946
+ await walkMeta(fullPath, fn);
947
+ else if (name.endsWith(".meta"))
948
+ await fn(fullPath);
949
+ }
950
+ catch { /* skip */ }
951
+ }));
952
+ }
953
+ // ===========================================================================
954
+ // readAssetOffline — parse a text-serialized asset → AssetModel.
955
+ // ===========================================================================
956
+ const OFFLINE_EXTENSIONS = new Set([
957
+ ".prefab", ".unity", ".asset", ".mat", ".controller", ".anim", ".playable",
958
+ ]);
959
+ export function isOfflineAsset(assetPath) {
960
+ const dot = assetPath.lastIndexOf(".");
961
+ if (dot < 0)
962
+ return false;
963
+ return OFFLINE_EXTENSIONS.has(assetPath.slice(dot).toLowerCase());
964
+ }
965
+ export async function readAssetOffline(assetPath, opts) {
966
+ const absPath = join(opts.projectRoot, assetPath);
967
+ const data = await readFile(absPath, "utf-8");
968
+ const parsed = parseAsset(data);
969
+ parsed.path = assetPath;
970
+ parsed.kind = kindForPath(assetPath);
971
+ parsed.guid = await safeReadMetaGUID(absPath + ".meta");
972
+ const wantedScripts = scriptGUIDs(parsed);
973
+ const scriptIndex = await buildScriptIndex(opts.projectRoot, wantedScripts);
974
+ const wantedGUIDs = collectFieldGUIDs(parsed);
975
+ const guidIndex = await buildGUIDIndex(opts.projectRoot, wantedGUIDs);
976
+ for (const [g, p] of scriptIndex)
977
+ guidIndex.set(g, p);
978
+ return { model: buildAssetModel(parsed, scriptIndex, guidIndex, opts.fieldLimit), source: "offline" };
979
+ }
980
+ async function safeReadMetaGUID(metaPath) {
981
+ try {
982
+ return readMetaGUID(await readFile(metaPath, "utf-8"));
983
+ }
984
+ catch {
985
+ return "";
986
+ }
987
+ }
988
+ function collectFieldGUIDs(asset) {
989
+ const guids = new Set();
990
+ for (const obj of asset.objects) {
991
+ for (const line of obj.lines) {
992
+ if (!line.includes("guid:") || line.includes("m_Script"))
993
+ continue;
994
+ for (const g of findGUIDs(line))
995
+ guids.add(g);
996
+ }
997
+ }
998
+ return guids;
999
+ }
1000
+ function buildAssetModel(parsed, scriptIndex, guidIndex, fieldLimit) {
1001
+ const hierarchy = buildHierarchy(parsed);
1002
+ const overrides = collectOverrides(parsed, scriptIndex, guidIndex);
1003
+ if (hierarchy.length > 0) {
1004
+ const roots = hierarchy.map((node) => convertNode(node, parsed, scriptIndex, guidIndex, fieldLimit));
1005
+ let componentCount = 0;
1006
+ const countComps = (n) => {
1007
+ componentCount += n.components.length;
1008
+ n.children.forEach(countComps);
1009
+ };
1010
+ roots.forEach(countComps);
1011
+ return {
1012
+ kind: parsed.kind,
1013
+ path: parsed.path,
1014
+ guid: parsed.guid || undefined,
1015
+ objectCount: parsed.objects.length,
1016
+ componentCount,
1017
+ roots,
1018
+ ...(overrides.length > 0 ? { overrides } : {}),
1019
+ };
1020
+ }
1021
+ const flatObjects = [];
1022
+ for (const obj of parsed.objects) {
1023
+ if (obj.type === "PrefabInstance")
1024
+ continue;
1025
+ const { name } = componentName(obj, scriptIndex);
1026
+ const { fields } = fieldsWithHidden(parsed, obj, fieldLimit, guidIndex);
1027
+ flatObjects.push({
1028
+ name: obj.name || name,
1029
+ type: name,
1030
+ fields: fields.length > 0 ? fields.map(toComponentField) : undefined,
1031
+ });
1032
+ }
1033
+ return {
1034
+ kind: parsed.kind,
1035
+ path: parsed.path,
1036
+ guid: parsed.guid || undefined,
1037
+ objectCount: parsed.objects.length,
1038
+ componentCount: 0,
1039
+ roots: [],
1040
+ flatObjects,
1041
+ ...(overrides.length > 0 ? { overrides } : {}),
1042
+ };
1043
+ }
1044
+ function convertNode(node, parsed, scriptIndex, guidIndex, fieldLimit) {
1045
+ const comps = componentsFor(parsed, node.gameObject.id, scriptIndex);
1046
+ const components = comps.map((c) => {
1047
+ const comp = { name: c.name };
1048
+ if (c.scriptPath)
1049
+ comp.scriptPath = c.scriptPath;
1050
+ if (fieldLimit > 0) {
1051
+ const { fields } = fieldsWithHidden(parsed, c.object, fieldLimit, guidIndex);
1052
+ if (fields.length > 0)
1053
+ comp.fields = fields.map(toComponentField);
1054
+ }
1055
+ return comp;
1056
+ });
1057
+ return {
1058
+ name: node.gameObject.name,
1059
+ path: node.path,
1060
+ depth: node.depth,
1061
+ fileID: node.gameObject.id,
1062
+ components,
1063
+ children: node.children.map((child) => convertNode(child, parsed, scriptIndex, guidIndex, fieldLimit)),
1064
+ };
1065
+ }
1066
+ function toComponentField(f) {
1067
+ return { name: f.name, value: f.value };
1068
+ }
1069
+ // ===========================================================================
1070
+ // searchAssetsOffline — scan Assets/ → SearchModel.
1071
+ // ===========================================================================
1072
+ const SEARCHABLE_EXTENSIONS = new Set([
1073
+ ".prefab", ".unity", ".asset", ".mat", ".controller", ".anim", ".playable",
1074
+ ]);
1075
+ export async function searchAssetsOffline(opts) {
1076
+ const nameQuery = (opts.name ?? "").trim().toLowerCase();
1077
+ const componentQuery = (opts.component ?? "").trim().toLowerCase();
1078
+ const guidQuery = (opts.guid ?? "").trim().toLowerCase();
1079
+ const typeFilter = opts.type ? parseKindSet(opts.type) : null;
1080
+ const folder = opts.folder ?? "Assets";
1081
+ const maxResults = opts.maxResults ?? 50;
1082
+ const searchDir = join(opts.projectRoot, folder);
1083
+ const scriptIndex = componentQuery
1084
+ ? await buildScriptIndexForQuery(opts.projectRoot, componentQuery)
1085
+ : new Map();
1086
+ const guidIndex = guidQuery
1087
+ ? await resolveGUIDPaths(opts.projectRoot, guidQuery)
1088
+ : new Map();
1089
+ const matches = [];
1090
+ const files = await collectFiles(searchDir);
1091
+ for (const filePath of files) {
1092
+ if (matches.length >= maxResults)
1093
+ break;
1094
+ const assetPath = toAssetPath(opts.projectRoot, filePath);
1095
+ const ext = extname(filePath).toLowerCase();
1096
+ if (!SEARCHABLE_EXTENSIONS.has(ext))
1097
+ continue;
1098
+ const kind = kindForPath(filePath);
1099
+ if (typeFilter && typeFilter.size > 0 && !typeFilter.has(kind))
1100
+ continue;
1101
+ let parsed;
1102
+ try {
1103
+ parsed = parseAsset(await readFile(filePath, "utf-8"));
1104
+ }
1105
+ catch {
1106
+ continue;
1107
+ }
1108
+ parsed.path = assetPath;
1109
+ parsed.kind = kind;
1110
+ const guid = await safeReadMetaGUID(filePath + ".meta");
1111
+ const match = checkMatch(parsed, scriptIndex, guidIndex, assetPath, kind, guid, { nameQuery, componentQuery, guidQuery });
1112
+ if (match)
1113
+ matches.push(match);
1114
+ }
1115
+ return {
1116
+ query: { name: opts.name, component: opts.component, guid: opts.guid, type: opts.type },
1117
+ matchCount: matches.length,
1118
+ matches,
1119
+ truncated: 0,
1120
+ };
1121
+ }
1122
+ function checkMatch(parsed, scriptIndex, guidIndex, assetPath, kind, guid, criteria) {
1123
+ const reasons = [];
1124
+ const objects = [];
1125
+ const { nameQuery, componentQuery, guidQuery } = criteria;
1126
+ const fileName = basename(assetPath);
1127
+ if (nameQuery && fileName.toLowerCase().includes(nameQuery))
1128
+ reasons.push("file-name");
1129
+ if (guidQuery) {
1130
+ if (guid.toLowerCase() === guidQuery)
1131
+ reasons.push("guid");
1132
+ let hasFieldGUID = false;
1133
+ for (const obj of parsed.objects) {
1134
+ if (fieldGUIDs(obj).has(guidQuery)) {
1135
+ hasFieldGUID = true;
1136
+ break;
1137
+ }
1138
+ }
1139
+ if (hasFieldGUID)
1140
+ reasons.push("guid");
1141
+ }
1142
+ const hierarchy = buildHierarchy(parsed);
1143
+ if (nameQuery) {
1144
+ for (const node of flattenHierarchy(hierarchy)) {
1145
+ if (node.gameObject.name.toLowerCase().includes(nameQuery)) {
1146
+ const comps = componentsFor(parsed, node.gameObject.id, scriptIndex);
1147
+ objects.push({ path: node.path, components: comps.map((c) => c.name) });
1148
+ }
1149
+ }
1150
+ if (objects.length > 0 && !reasons.includes("file-name"))
1151
+ reasons.push("gameobject");
1152
+ }
1153
+ if (componentQuery) {
1154
+ let componentMatch = false;
1155
+ for (const node of flattenHierarchy(hierarchy)) {
1156
+ const comps = componentsFor(parsed, node.gameObject.id, scriptIndex);
1157
+ const matching = comps.filter((c) => c.name.toLowerCase().includes(componentQuery) ||
1158
+ (c.scriptPath && c.scriptPath.toLowerCase().includes(componentQuery)));
1159
+ if (matching.length > 0) {
1160
+ componentMatch = true;
1161
+ if (!objects.some((o) => o.path === node.path)) {
1162
+ objects.push({ path: node.path, components: comps.map((c) => c.name) });
1163
+ }
1164
+ }
1165
+ }
1166
+ if (componentMatch && !reasons.includes("component"))
1167
+ reasons.push("component");
1168
+ }
1169
+ if (!componentQuery && !nameQuery && !guidQuery)
1170
+ reasons.push("file-name");
1171
+ if (reasons.length === 0)
1172
+ return null;
1173
+ return { path: assetPath, guid: guid || undefined, kind, reasons, objects: objects.length > 0 ? objects : undefined };
1174
+ }
1175
+ function flattenHierarchy(nodes) {
1176
+ const out = [];
1177
+ const walk = (ns) => {
1178
+ for (const n of ns) {
1179
+ out.push(n);
1180
+ walk(n.children);
1181
+ }
1182
+ };
1183
+ walk(nodes);
1184
+ return out;
1185
+ }
1186
+ async function collectFiles(dir) {
1187
+ const results = [];
1188
+ let entries;
1189
+ try {
1190
+ entries = await readdir(dir);
1191
+ }
1192
+ catch {
1193
+ return results;
1194
+ }
1195
+ for (const name of entries) {
1196
+ if (shouldSkipDir(name))
1197
+ continue;
1198
+ const fullPath = join(dir, name);
1199
+ try {
1200
+ const s = await stat(fullPath);
1201
+ if (s.isDirectory())
1202
+ results.push(...await collectFiles(fullPath));
1203
+ else if (!name.endsWith(".meta"))
1204
+ results.push(fullPath);
1205
+ }
1206
+ catch { /* skip */ }
1207
+ }
1208
+ return results;
1209
+ }
1210
+ async function resolveGUIDPaths(projectRoot, guidQuery) {
1211
+ const result = new Map();
1212
+ const assetsDir = join(projectRoot, "Assets");
1213
+ await walkMetaForGUIDs(assetsDir, projectRoot, guidQuery, result);
1214
+ return result;
1215
+ }
1216
+ async function walkMetaForGUIDs(dir, projectRoot, guidQuery, result) {
1217
+ let entries;
1218
+ try {
1219
+ entries = await readdir(dir);
1220
+ }
1221
+ catch {
1222
+ return;
1223
+ }
1224
+ for (const name of entries) {
1225
+ if (shouldSkipDir(name))
1226
+ continue;
1227
+ const fullPath = join(dir, name);
1228
+ try {
1229
+ const s = await stat(fullPath);
1230
+ if (s.isDirectory())
1231
+ await walkMetaForGUIDs(fullPath, projectRoot, guidQuery, result);
1232
+ else if (name.endsWith(".meta")) {
1233
+ const guid = readMetaGUID(await readFile(fullPath, "utf-8")).toLowerCase();
1234
+ if (guid === guidQuery) {
1235
+ result.set(guid, toAssetPath(projectRoot, fullPath.slice(0, -5)));
1236
+ }
1237
+ }
1238
+ }
1239
+ catch { /* skip */ }
1240
+ if (result.size > 0)
1241
+ return;
1242
+ }
1243
+ }
1244
+ const LISTABLE_EXTENSIONS = new Set([
1245
+ ".prefab", ".unity", ".asset", ".mat", ".controller", ".anim", ".playable",
1246
+ ".cs", ".shader", ".spriteatlas", ".physicMaterial", ".physicsMaterial2D",
1247
+ ".overrideController", ".uxml", ".uss",
1248
+ ]);
1249
+ export async function listAssetsOffline(opts) {
1250
+ const folder = opts.folder ?? "Assets";
1251
+ const typeFilter = opts.type
1252
+ ? new Set(opts.type.split(",").map((t) => normalizeKind(t)).filter((t) => t !== ""))
1253
+ : null;
1254
+ const searchDir = join(opts.projectRoot, folder);
1255
+ const folders = [];
1256
+ const kindSummary = {};
1257
+ let totalFiles = 0;
1258
+ let truncated = 0;
1259
+ const folderMap = new Map();
1260
+ await walkFiles(searchDir, opts.projectRoot, async (absPath) => {
1261
+ const ext = extname(absPath).toLowerCase();
1262
+ if (!LISTABLE_EXTENSIONS.has(ext))
1263
+ return;
1264
+ const kind = kindForPath(absPath);
1265
+ if (typeFilter && typeFilter.size > 0 && !typeFilter.has(kind))
1266
+ return;
1267
+ const relDir = relativeDir(opts.projectRoot, absPath);
1268
+ const fileName = basename(absPath);
1269
+ let listing = folderMap.get(relDir);
1270
+ if (!listing) {
1271
+ listing = { folder: relDir, kinds: {}, fileCount: 0 };
1272
+ folderMap.set(relDir, listing);
1273
+ folders.push(listing);
1274
+ }
1275
+ listing.fileCount++;
1276
+ totalFiles++;
1277
+ if (!listing.kinds[kind])
1278
+ listing.kinds[kind] = { count: 0, sample: [] };
1279
+ listing.kinds[kind].count++;
1280
+ kindSummary[kind] = (kindSummary[kind] ?? 0) + 1;
1281
+ const samples = listing.kinds[kind].sample;
1282
+ if (samples.length < 5) {
1283
+ const nameWithoutExt = ext ? fileName.slice(0, -(ext.length)) : fileName;
1284
+ if (!samples.includes(nameWithoutExt))
1285
+ samples.push(nameWithoutExt);
1286
+ }
1287
+ else {
1288
+ truncated++;
1289
+ }
1290
+ });
1291
+ folders.sort((a, b) => a.folder.localeCompare(b.folder));
1292
+ return {
1293
+ root: folder, typeFilter: opts.type, folders,
1294
+ totalFiles, totalFolders: folders.length, kindSummary, truncated,
1295
+ };
1296
+ }
1297
+ function relativeDir(projectRoot, absPath) {
1298
+ let rel = absPath.slice(projectRoot.length).replace(/\\/g, "/");
1299
+ if (rel.startsWith("/"))
1300
+ rel = rel.slice(1);
1301
+ const lastSlash = rel.lastIndexOf("/");
1302
+ return lastSlash >= 0 ? rel.slice(0, lastSlash) : rel;
1303
+ }
1304
+ async function walkFiles(dir, projectRoot, fn) {
1305
+ let entries;
1306
+ try {
1307
+ entries = await readdir(dir);
1308
+ }
1309
+ catch {
1310
+ return;
1311
+ }
1312
+ for (const name of entries) {
1313
+ if (shouldSkipDir(name))
1314
+ continue;
1315
+ if (name.endsWith(".meta"))
1316
+ continue;
1317
+ const fullPath = join(dir, name);
1318
+ try {
1319
+ const s = await stat(fullPath);
1320
+ if (s.isDirectory())
1321
+ await walkFiles(fullPath, projectRoot, fn);
1322
+ else
1323
+ await fn(fullPath);
1324
+ }
1325
+ catch { /* skip */ }
1326
+ }
1327
+ }
1328
+ // ===========================================================================
1329
+ // findReferencesOffline — offline reverse reference lookup (T1.4).
1330
+ //
1331
+ // Scans .meta + YAML on disk to find all assets that reference a given target
1332
+ // (by GUID or asset path). No running Editor required. Output is grouped by
1333
+ // asset kind and folder, with detail levels and caps to protect token budget.
1334
+ //
1335
+ // Algorithm: resolve target GUID → scan all text-serialized files → raw-text
1336
+ // fast-filter (content.includes(guid)) → optional YAML parse for verbose
1337
+ // locations → group + cap + collapse.
1338
+ // ===========================================================================
1339
+ const REFERENCEABLE_EXTENSIONS = new Set([
1340
+ ".prefab", ".unity", ".asset", ".mat", ".controller", ".anim", ".playable",
1341
+ ]);
1342
+ export async function findReferencesOffline(opts) {
1343
+ const detail = (opts.detail ?? "normal");
1344
+ const maxResults = opts.maxResults ?? 100;
1345
+ const maxPerFile = opts.maxPerFile ?? 5;
1346
+ const patternThreshold = opts.patternThreshold ?? 0;
1347
+ // Resolve target GUID + path.
1348
+ let targetGuid = "";
1349
+ let targetPath = "";
1350
+ if (opts.guid) {
1351
+ targetGuid = opts.guid.toLowerCase();
1352
+ }
1353
+ else if (opts.assetPath) {
1354
+ targetPath = opts.assetPath;
1355
+ targetGuid = (await safeReadMetaGUID(join(opts.projectRoot, opts.assetPath + ".meta"))).toLowerCase();
1356
+ }
1357
+ if (targetGuid === "") {
1358
+ return {
1359
+ queriedAssetPath: targetPath,
1360
+ queriedAssetGuid: "",
1361
+ referencedBy: [],
1362
+ totalCount: 0,
1363
+ byKind: {},
1364
+ byFolder: {},
1365
+ detail,
1366
+ truncated: 0,
1367
+ };
1368
+ }
1369
+ // If only GUID was given, resolve target path from .meta index.
1370
+ if (targetPath === "") {
1371
+ const guidIndex = await buildGUIDIndex(opts.projectRoot, new Set([targetGuid]));
1372
+ targetPath = guidIndex.get(targetGuid) ?? "";
1373
+ }
1374
+ // Scan all candidate files in Assets/.
1375
+ const candidates = await collectFiles(join(opts.projectRoot, "Assets"));
1376
+ const hits = [];
1377
+ for (const absPath of candidates) {
1378
+ const ext = extname(absPath).toLowerCase();
1379
+ if (!REFERENCEABLE_EXTENSIONS.has(ext))
1380
+ continue;
1381
+ let content;
1382
+ try {
1383
+ content = await readFile(absPath, "utf-8");
1384
+ }
1385
+ catch {
1386
+ continue;
1387
+ }
1388
+ // Fast filter: skip files that don't mention the GUID at all.
1389
+ if (!content.includes(targetGuid))
1390
+ continue;
1391
+ const assetPath = toAssetPath(opts.projectRoot, absPath);
1392
+ // Skip self-reference.
1393
+ if (assetPath === targetPath)
1394
+ continue;
1395
+ const kind = kindForPath(absPath);
1396
+ const folder = relativeDir(opts.projectRoot, absPath);
1397
+ const guid = await safeReadMetaGUID(absPath + ".meta");
1398
+ const entry = {
1399
+ assetPath,
1400
+ guid: guid || undefined,
1401
+ kind,
1402
+ folder,
1403
+ };
1404
+ if (detail === "verbose") {
1405
+ entry.locations = extractReferenceLocations(content, targetGuid, maxPerFile);
1406
+ }
1407
+ hits.push(entry);
1408
+ }
1409
+ // Group by kind and folder.
1410
+ const byKind = {};
1411
+ const byFolder = {};
1412
+ for (const hit of hits) {
1413
+ byKind[hit.kind] = (byKind[hit.kind] ?? 0) + 1;
1414
+ byFolder[hit.folder] = (byFolder[hit.folder] ?? 0) + 1;
1415
+ }
1416
+ // Pattern collapsing: folders with >= threshold files get collapsed.
1417
+ let collapsedGroups;
1418
+ let displayHits = hits;
1419
+ if (patternThreshold > 0) {
1420
+ collapsedGroups = [];
1421
+ const collapsedFolders = new Set();
1422
+ for (const [folder, count] of Object.entries(byFolder)) {
1423
+ if (count < patternThreshold)
1424
+ continue;
1425
+ const kinds = {};
1426
+ for (const hit of hits) {
1427
+ if (hit.folder !== folder)
1428
+ continue;
1429
+ kinds[hit.kind] = (kinds[hit.kind] ?? 0) + 1;
1430
+ }
1431
+ collapsedGroups.push({ folder, count, kinds });
1432
+ collapsedFolders.add(folder);
1433
+ }
1434
+ if (collapsedFolders.size > 0) {
1435
+ displayHits = hits.filter((h) => !collapsedFolders.has(h.folder));
1436
+ }
1437
+ }
1438
+ // Apply max_results cap and detail filtering.
1439
+ const totalCount = hits.length;
1440
+ let referencedBy;
1441
+ let truncated = 0;
1442
+ if (detail === "summary") {
1443
+ referencedBy = [];
1444
+ }
1445
+ else {
1446
+ referencedBy = displayHits.slice(0, maxResults);
1447
+ truncated = Math.max(0, displayHits.length - maxResults);
1448
+ }
1449
+ return {
1450
+ queriedAssetPath: targetPath,
1451
+ queriedAssetGuid: targetGuid,
1452
+ referencedBy,
1453
+ totalCount,
1454
+ byKind,
1455
+ byFolder,
1456
+ collapsedGroups: collapsedGroups && collapsedGroups.length > 0
1457
+ ? collapsedGroups
1458
+ : undefined,
1459
+ detail,
1460
+ truncated,
1461
+ };
1462
+ }
1463
+ function extractReferenceLocations(content, targetGuid, maxPerFile) {
1464
+ const locations = [];
1465
+ const lines = content.split("\n");
1466
+ for (let i = 0; i < lines.length; i++) {
1467
+ if (!lines[i].includes(targetGuid))
1468
+ continue;
1469
+ if (locations.length >= maxPerFile)
1470
+ break;
1471
+ const trim = lines[i].trim();
1472
+ const cleaned = trim.startsWith("- ") ? trim.slice(2) : trim;
1473
+ const colonIdx = cleaned.indexOf(":");
1474
+ const field = colonIdx > 0 ? cleaned.slice(0, colonIdx).trim() : cleaned;
1475
+ if (field === "target") {
1476
+ let label = "prefab modification";
1477
+ for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
1478
+ const pp = lines[j].trim();
1479
+ if (pp.startsWith("propertyPath:")) {
1480
+ label = `prefab → ${displayFieldName(cleanScalar(pp.slice("propertyPath:".length).trim()))}`;
1481
+ break;
1482
+ }
1483
+ if (pp.startsWith("- target:") || pp.startsWith("- ") || pp === "")
1484
+ continue;
1485
+ break;
1486
+ }
1487
+ locations.push(label);
1488
+ }
1489
+ else {
1490
+ locations.push(displayFieldName(field));
1491
+ }
1492
+ }
1493
+ return locations;
1494
+ }
1495
+ //# sourceMappingURL=offline.js.map