unity-agentic-tools 0.6.1 → 0.7.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 (47) hide show
  1. package/README.md +18 -2
  2. package/dist/bridge-install.d.ts +6 -1
  3. package/dist/bridge-install.d.ts.map +1 -1
  4. package/dist/bridge-install.js +75 -4
  5. package/dist/bridge-install.js.map +1 -1
  6. package/dist/cli.js +432 -161
  7. package/dist/cli.js.map +1 -1
  8. package/dist/editor-client.d.ts +8 -1
  9. package/dist/editor-client.d.ts.map +1 -1
  10. package/dist/editor-client.js +256 -54
  11. package/dist/editor-client.js.map +1 -1
  12. package/dist/index.d.ts +0 -7
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +39 -972
  15. package/dist/index.js.map +1 -1
  16. package/dist/types.d.ts +16 -239
  17. package/dist/types.d.ts.map +1 -1
  18. package/dist/types.js +1 -0
  19. package/dist/types.js.map +1 -1
  20. package/package.json +8 -13
  21. package/dist/cli-output.d.ts +0 -7
  22. package/dist/cli-output.d.ts.map +0 -1
  23. package/dist/cli-output.js +0 -24
  24. package/dist/cli-output.js.map +0 -1
  25. package/dist/doc-indexer-cli.js +0 -3218
  26. package/dist/guid-cache.d.ts +0 -45
  27. package/dist/guid-cache.d.ts.map +0 -1
  28. package/dist/guid-cache.js +0 -111
  29. package/dist/guid-cache.js.map +0 -1
  30. package/dist/project-search.d.ts +0 -16
  31. package/dist/project-search.d.ts.map +0 -1
  32. package/dist/project-search.js +0 -538
  33. package/dist/project-search.js.map +0 -1
  34. package/dist/scanner.d.ts +0 -150
  35. package/dist/scanner.d.ts.map +0 -1
  36. package/dist/scanner.js +0 -223
  37. package/dist/scanner.js.map +0 -1
  38. package/dist/setup.d.ts +0 -25
  39. package/dist/setup.d.ts.map +0 -1
  40. package/dist/setup.js +0 -185
  41. package/dist/setup.js.map +0 -1
  42. package/native/index.d.ts +0 -335
  43. package/native/index.js +0 -330
  44. package/native/unity-file-tools.darwin-arm64.node +0 -0
  45. package/native/unity-file-tools.darwin-x64.node +0 -0
  46. package/native/unity-file-tools.linux-x64-gnu.node +0 -0
  47. package/native/unity-file-tools.win32-x64-msvc.node +0 -0
package/dist/index.js CHANGED
@@ -1,35 +1,11 @@
1
1
  // @bun @bun-cjs
2
- (function(exports, require, module, __filename, __dirname) {var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __defProp = Object.defineProperty;
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
5
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  function __accessProp(key) {
9
7
  return this[key];
10
8
  }
11
- var __toESMCache_node;
12
- var __toESMCache_esm;
13
- var __toESM = (mod, isNodeMode, target) => {
14
- var canCache = mod != null && typeof mod === "object";
15
- if (canCache) {
16
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
- var cached = cache.get(mod);
18
- if (cached)
19
- return cached;
20
- }
21
- target = mod != null ? __create(__getProtoOf(mod)) : {};
22
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
- for (let key of __getOwnPropNames(mod))
24
- if (!__hasOwnProp.call(to, key))
25
- __defProp(to, key, {
26
- get: __accessProp.bind(mod, key),
27
- enumerable: true
28
- });
29
- if (canCache)
30
- cache.set(mod, to);
31
- return to;
32
- };
33
9
  var __toCommonJS = (from) => {
34
10
  var entry = (__moduleCache ??= new WeakMap).get(from), desc;
35
11
  if (entry)
@@ -47,7 +23,6 @@ var __toCommonJS = (from) => {
47
23
  return entry;
48
24
  };
49
25
  var __moduleCache;
50
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
51
26
  var __returnValue = (v) => v;
52
27
  function __exportSetter(name, newValue) {
53
28
  this[name] = __returnValue.bind(null, newValue);
@@ -62,419 +37,32 @@ var __export = (target, all) => {
62
37
  });
63
38
  };
64
39
 
65
- // package.json
66
- var require_package = __commonJS((exports2, module2) => {
67
- module2.exports = {
68
- name: "unity-agentic-tools",
69
- packageManager: "bun@latest",
70
- version: "0.6.1",
71
- description: "Compact Unity Editor command runner for AI agents",
72
- exports: {
73
- ".": {
74
- import: "./dist/index.js",
75
- types: "./dist/index.d.ts"
76
- },
77
- "./cli": "./dist/cli.js",
78
- "./scanner": "./dist/scanner.js"
79
- },
80
- files: [
81
- "dist",
82
- "native",
83
- "README.md",
84
- "LICENSE"
85
- ],
86
- scripts: {
87
- build: "bun run clean && bun run build:types && bun run build:lib && bun run build:cli && cp ../doc-indexer/dist/cli.js dist/doc-indexer-cli.js",
88
- "build:types": "tsc --project tsconfig.json",
89
- "build:lib": "bun build src/index.ts --outdir=dist --target=bun --format=cjs --external unity-file-tools",
90
- "build:cli": "bun build src/cli.ts --outdir=dist --target=bun --format=cjs --external unity-file-tools",
91
- "build:rust": "cd ../rust-core && bun run build",
92
- "build:all": "bun run build:rust || echo 'Rust build skipped' && bun run build",
93
- dev: "bun build src/index.ts --watch",
94
- clean: "rm -rf dist",
95
- rebuild: "bun run clean && bun run build",
96
- test: "bun test",
97
- "test:watch": "bun test --watch",
98
- "test:coverage": "bun test --coverage",
99
- "test:unity-headless": "bun test/run-headless-validation.ts"
100
- },
101
- dependencies: {
102
- commander: "^14.0.2"
103
- },
104
- devDependencies: {
105
- "@types/node": "^25.0.0",
106
- "@vitest/ui": "^4.0.16",
107
- typescript: "^5.3.0",
108
- "unity-file-tools": "workspace:*",
109
- vitest: "^4.0.16"
110
- },
111
- type: "commonjs",
112
- bin: {
113
- "unity-agentic-tools": "./dist/cli.js"
114
- },
115
- engines: {
116
- bun: ">=1.0.0"
117
- },
118
- repository: {
119
- type: "git",
120
- url: "https://github.com/taconotsandwich/unity-agentic-tools"
121
- },
122
- keywords: [
123
- "unity",
124
- "yaml",
125
- "parser",
126
- "scene",
127
- "prefab",
128
- "gameobject",
129
- "ai",
130
- "cli"
131
- ],
132
- license: "Apache-2.0"
133
- };
134
- });
135
-
136
40
  // src/index.ts
137
41
  var exports_src = {};
138
42
  __export(exports_src, {
139
- walk_project_files: () => walk_project_files,
140
- setup: () => setup,
141
- search_project: () => search_project,
142
- isNativeModuleAvailable: () => isNativeModuleAvailable,
143
- grep_project: () => grep_project,
144
- getNativeModuleError: () => getNativeModuleError,
145
- getNativeExtractDllTypes: () => getNativeExtractDllTypes,
146
- getNativeExtractCsharpTypes: () => getNativeExtractCsharpTypes,
147
- getNativeBuildTypeRegistry: () => getNativeBuildTypeRegistry,
148
43
  generateGuid: () => generateGuid,
149
44
  find_unity_project_root: () => find_unity_project_root,
150
45
  cleanup: () => cleanup,
151
- atomicWrite: () => atomicWrite,
152
- UnityScanner: () => UnityScanner
46
+ atomicWrite: () => atomicWrite
153
47
  });
154
48
  module.exports = __toCommonJS(exports_src);
155
49
 
156
- // src/scanner.ts
157
- var import_module = require("module");
50
+ // src/cleanup.ts
158
51
  var import_fs = require("fs");
159
52
  var import_path = require("path");
160
- var __dirname = "/home/runner/work/unity-agentic-tools/unity-agentic-tools/unity-agentic-tools/src";
161
- var RustScanner = null;
162
- var nativeModuleError = null;
163
- var nativeWalkProjectFiles = null;
164
- var nativeGrepProject = null;
165
- var nativeBuildGuidCache = null;
166
- var nativeExtractCsharpTypes = null;
167
- var nativeBuildTypeRegistry = null;
168
- var nativeExtractDllTypes = null;
169
- var nativeBuildPackageGuidCache = null;
170
- var nativeBuildLocalPackageGuidCache = null;
171
- var nativeExtractSerializedFields = null;
172
- var nativeExtractDllFields = null;
173
- try {
174
- const scriptDir = process.argv[1] ? import_path.dirname(import_path.resolve(process.argv[1])) : __dirname;
175
- let rustModule;
176
- const nativeLoaderPath = import_path.join(scriptDir, "..", "native", "index.js");
177
- if (import_fs.existsSync(nativeLoaderPath)) {
178
- const nativeRequire = import_module.createRequire(nativeLoaderPath);
179
- rustModule = nativeRequire(nativeLoaderPath);
180
- } else {
181
- const wsRequire = import_module.createRequire(import_path.join(scriptDir, "_"));
182
- rustModule = wsRequire("unity-file-tools");
183
- }
184
- RustScanner = rustModule.Scanner;
185
- nativeWalkProjectFiles = rustModule.walkProjectFiles || null;
186
- nativeGrepProject = rustModule.grepProject || null;
187
- nativeBuildGuidCache = rustModule.buildGuidCache || null;
188
- nativeExtractCsharpTypes = rustModule.extractCsharpTypes || null;
189
- nativeBuildTypeRegistry = rustModule.buildTypeRegistry || null;
190
- nativeExtractDllTypes = rustModule.extractDllTypes || null;
191
- nativeBuildPackageGuidCache = rustModule.buildPackageGuidCache || null;
192
- nativeBuildLocalPackageGuidCache = rustModule.buildLocalPackageGuidCache || null;
193
- nativeExtractSerializedFields = rustModule.extractSerializedFields || null;
194
- nativeExtractDllFields = rustModule.extractDllFields || null;
195
- } catch (err) {
196
- nativeModuleError = `Failed to load native Rust module.
197
- ` + `Run: bun install (in the project root)
198
- ` + `Original error: ${err.message}`;
199
- }
200
- function isNativeModuleAvailable() {
201
- return RustScanner !== null;
202
- }
203
- function getNativeModuleError() {
204
- return nativeModuleError;
205
- }
206
-
207
- class UnityScanner {
208
- scanner;
209
- constructor() {
210
- if (!RustScanner) {
211
- throw new Error(nativeModuleError || "Native module not available");
212
- }
213
- this.scanner = new RustScanner;
214
- }
215
- setProjectRoot(path) {
216
- this.scanner.setProjectRoot(path);
217
- }
218
- scan_scene_minimal(file) {
219
- return this.scanner.scanSceneMinimal(file);
220
- }
221
- scan_scene_with_components(file, options) {
222
- return this.scanner.scanSceneWithComponents(file, options);
223
- }
224
- scan_scene_metadata(file) {
225
- return this.scanner.scanSceneMetadata(file);
226
- }
227
- find_by_name(file, pattern, fuzzy = true) {
228
- return this.scanner.findByName(file, pattern, fuzzy);
229
- }
230
- inspect(options) {
231
- return this.scanner.inspect({
232
- file: options.file,
233
- identifier: options.identifier,
234
- includeProperties: options.include_properties,
235
- verbose: options.verbose
236
- });
237
- }
238
- inspect_all(file, include_properties = false, verbose = false) {
239
- return this.scanner.inspectAll(file, include_properties, verbose);
240
- }
241
- inspect_all_paginated(options) {
242
- return this.scanner.inspectAllPaginated({
243
- file: options.file,
244
- includeProperties: options.include_properties,
245
- verbose: options.verbose,
246
- pageSize: options.page_size,
247
- cursor: options.cursor,
248
- maxDepth: options.max_depth,
249
- filterComponent: options.filter_component
250
- });
251
- }
252
- read_asset(file, decode_mesh) {
253
- return this.scanner.readAsset(file, decode_mesh);
254
- }
255
- }
256
- function getNativeWalkProjectFiles() {
257
- return nativeWalkProjectFiles;
258
- }
259
- function getNativeGrepProject() {
260
- return nativeGrepProject;
261
- }
262
- function getNativeBuildGuidCache() {
263
- return nativeBuildGuidCache;
264
- }
265
- function getNativeExtractCsharpTypes() {
266
- return nativeExtractCsharpTypes;
267
- }
268
- function getNativeBuildTypeRegistry() {
269
- return nativeBuildTypeRegistry;
270
- }
271
- function getNativeExtractDllTypes() {
272
- return nativeExtractDllTypes;
273
- }
274
- function getNativeBuildPackageGuidCache() {
275
- return nativeBuildPackageGuidCache;
276
- }
277
- function getNativeBuildLocalPackageGuidCache() {
278
- return nativeBuildLocalPackageGuidCache;
279
- }
280
- // src/setup.ts
281
- var import_fs3 = require("fs");
282
- var import_path3 = require("path");
283
-
284
- // src/gitignore.ts
285
- var import_fs2 = require("fs");
286
- var import_path2 = require("path");
287
- var AGENTIC_DIR = ".unity-agentic";
288
- var GITIGNORE_ENTRY = `${AGENTIC_DIR}/`;
289
- var ACCEPTED_AGENTIC_PATTERNS = new Set([
290
- AGENTIC_DIR,
291
- GITIGNORE_ENTRY,
292
- `/${AGENTIC_DIR}`,
293
- `/${GITIGNORE_ENTRY}`
294
- ]);
295
- function ensure_gitignore_ignores_agentic_dir(project_path) {
296
- const gitignore_path = import_path2.join(project_path, ".gitignore");
297
- if (!import_fs2.existsSync(gitignore_path)) {
298
- import_fs2.writeFileSync(gitignore_path, `${GITIGNORE_ENTRY}
299
- `);
300
- return;
301
- }
302
- const content = import_fs2.readFileSync(gitignore_path, "utf-8");
303
- if (gitignore_ignores_agentic_dir(content)) {
304
- return;
305
- }
306
- const separator = content.length === 0 || content.endsWith(`
307
- `) ? "" : `
308
- `;
309
- import_fs2.writeFileSync(gitignore_path, `${content}${separator}${GITIGNORE_ENTRY}
310
- `);
311
- }
312
- function gitignore_ignores_agentic_dir(content) {
313
- for (const raw_line of content.split(/\r?\n/)) {
314
- const line = raw_line.trim();
315
- if (line.length === 0 || line.startsWith("#")) {
316
- continue;
317
- }
318
- if (ACCEPTED_AGENTIC_PATTERNS.has(line)) {
319
- return true;
320
- }
321
- }
322
- return false;
323
- }
324
-
325
- // src/setup.ts
326
- var VERSION = require_package().version;
327
53
  var CONFIG_DIR = ".unity-agentic";
328
- var CONFIG_FILE = "config.json";
329
54
  var GUID_CACHE_FILE = "guid-cache.json";
330
55
  var PACKAGE_CACHE_FILE = "package-cache.json";
331
56
  var LOCAL_PACKAGE_CACHE_FILE = "local-package-cache.json";
332
57
  var TYPE_REGISTRY_FILE = "type-registry.json";
333
58
  var DOC_INDEX_FILE = "doc-index.json";
334
- function setup(options = {}) {
335
- const projectPath = import_path3.resolve(options.project || process.cwd());
336
- const assetsPath = import_path3.join(projectPath, "Assets");
337
- if (!import_fs3.existsSync(assetsPath)) {
338
- return {
339
- success: false,
340
- project_path: projectPath,
341
- config_path: "",
342
- guid_cache_created: false,
343
- package_cache_created: false,
344
- type_registry_created: false,
345
- doc_index_created: false,
346
- error: `Not a Unity project: Assets folder not found at ${assetsPath}`
347
- };
348
- }
349
- const configPath = import_path3.join(projectPath, CONFIG_DIR);
350
- if (!import_fs3.existsSync(configPath)) {
351
- import_fs3.mkdirSync(configPath, { recursive: true });
352
- }
353
- ensure_gitignore_ignores_agentic_dir(projectPath);
354
- const config = {
355
- version: VERSION,
356
- project_path: projectPath,
357
- created_at: new Date().toISOString(),
358
- rust_enabled: isRustAvailable()
359
- };
360
- import_fs3.writeFileSync(import_path3.join(configPath, CONFIG_FILE), JSON.stringify(config, null, 2));
361
- const guidCache = buildGuidCache(projectPath);
362
- const guidCachePath = import_path3.join(configPath, GUID_CACHE_FILE);
363
- import_fs3.writeFileSync(guidCachePath, JSON.stringify(guidCache, null, 2));
364
- let packageCacheCreated = false;
365
- let packageGuidCount;
366
- const nativePkgBuild = getNativeBuildPackageGuidCache();
367
- if (nativePkgBuild) {
368
- try {
369
- const packageCache = nativePkgBuild(projectPath);
370
- const packageCachePath = import_path3.join(configPath, PACKAGE_CACHE_FILE);
371
- import_fs3.writeFileSync(packageCachePath, JSON.stringify(packageCache, null, 2));
372
- packageCacheCreated = true;
373
- packageGuidCount = Object.keys(packageCache).length;
374
- } catch {}
375
- }
376
- const nativeLocalPkgBuild = getNativeBuildLocalPackageGuidCache();
377
- if (nativeLocalPkgBuild) {
378
- try {
379
- const localPackageCache = nativeLocalPkgBuild(projectPath);
380
- const localPkgCount = Object.keys(localPackageCache).length;
381
- if (localPkgCount > 0) {
382
- const localPkgCachePath = import_path3.join(configPath, LOCAL_PACKAGE_CACHE_FILE);
383
- import_fs3.writeFileSync(localPkgCachePath, JSON.stringify(localPackageCache, null, 2));
384
- }
385
- } catch {}
386
- }
387
- let typeRegistryCreated = false;
388
- let typeCount;
389
- const nativeRegistryBuild = getNativeBuildTypeRegistry();
390
- if (nativeRegistryBuild) {
391
- try {
392
- const types = nativeRegistryBuild(projectPath, true, true);
393
- const registryPath = import_path3.join(configPath, TYPE_REGISTRY_FILE);
394
- import_fs3.writeFileSync(registryPath, JSON.stringify(types, null, 2));
395
- typeRegistryCreated = true;
396
- typeCount = types.length;
397
- } catch {}
398
- }
399
- let docIndexCreated = false;
400
- if (options.indexDocs) {
401
- const docIndex = { chunks: {}, last_updated: Date.now() };
402
- import_fs3.writeFileSync(import_path3.join(configPath, DOC_INDEX_FILE), JSON.stringify(docIndex, null, 2));
403
- docIndexCreated = true;
404
- }
405
- return {
406
- success: true,
407
- project_path: projectPath,
408
- config_path: configPath,
409
- guid_cache_created: true,
410
- package_cache_created: packageCacheCreated,
411
- type_registry_created: typeRegistryCreated,
412
- doc_index_created: docIndexCreated,
413
- guid_count: Object.keys(guidCache).length,
414
- package_guid_count: packageGuidCount,
415
- type_count: typeCount
416
- };
417
- }
418
- function buildGuidCache(projectRoot) {
419
- const nativeBuild = getNativeBuildGuidCache();
420
- if (nativeBuild) {
421
- try {
422
- return nativeBuild(projectRoot);
423
- } catch {}
424
- }
425
- return buildGuidCacheJs(projectRoot);
426
- }
427
- function buildGuidCacheJs(projectRoot) {
428
- const cache = {};
429
- const assetsDir = import_path3.join(projectRoot, "Assets");
430
- if (!import_fs3.existsSync(assetsDir)) {
431
- return cache;
432
- }
433
- scanMetaFiles(assetsDir, projectRoot, cache);
434
- return cache;
435
- }
436
- function scanMetaFiles(dir, projectRoot, cache) {
437
- try {
438
- const entries = import_fs3.readdirSync(dir);
439
- for (const entry of entries) {
440
- const fullPath = import_path3.join(dir, entry);
441
- const stat = import_fs3.statSync(fullPath);
442
- if (stat.isDirectory()) {
443
- scanMetaFiles(fullPath, projectRoot, cache);
444
- } else if (entry.endsWith(".meta")) {
445
- try {
446
- const content = import_fs3.readFileSync(fullPath, "utf-8");
447
- const guidMatch = content.match(/^guid:\s*([a-f0-9]{32})/m);
448
- if (guidMatch) {
449
- const guid = guidMatch[1];
450
- const assetPath = fullPath.slice(0, -5);
451
- const relativePath = import_path3.relative(projectRoot, assetPath);
452
- cache[guid] = relativePath;
453
- }
454
- } catch {}
455
- }
456
- }
457
- } catch {}
458
- }
459
- function isRustAvailable() {
460
- return isNativeModuleAvailable();
461
- }
462
- // src/cleanup.ts
463
- var import_fs4 = require("fs");
464
- var import_path4 = require("path");
465
- var CONFIG_DIR2 = ".unity-agentic";
466
- var GUID_CACHE_FILE2 = "guid-cache.json";
467
- var PACKAGE_CACHE_FILE2 = "package-cache.json";
468
- var LOCAL_PACKAGE_CACHE_FILE2 = "local-package-cache.json";
469
- var TYPE_REGISTRY_FILE2 = "type-registry.json";
470
- var DOC_INDEX_FILE2 = "doc-index.json";
471
59
  var EDITOR_LOCK_FILE = "editor.json";
472
60
  var LAST_EDITOR_CONFIG_FILE = "editor.last.json";
473
61
  function cleanup(options = {}) {
474
- const projectPath = import_path4.resolve(options.project || process.cwd());
475
- const configPath = import_path4.join(projectPath, CONFIG_DIR2);
62
+ const projectPath = import_path.resolve(options.project || process.cwd());
63
+ const configPath = import_path.join(projectPath, CONFIG_DIR);
476
64
  const modes = resolve_cleanup_modes(options);
477
- if (!import_fs4.existsSync(configPath)) {
65
+ if (!import_fs.existsSync(configPath)) {
478
66
  return {
479
67
  success: true,
480
68
  project_path: projectPath,
@@ -489,7 +77,7 @@ function cleanup(options = {}) {
489
77
  try {
490
78
  removeDirectoryRecursive(configPath);
491
79
  directoryRemoved = true;
492
- filesRemoved.push(CONFIG_DIR2);
80
+ filesRemoved.push(CONFIG_DIR);
493
81
  } catch (err) {
494
82
  return {
495
83
  success: false,
@@ -513,11 +101,11 @@ function cleanup(options = {}) {
513
101
  }
514
102
  if (modes.includes("cache")) {
515
103
  remove_files(configPath, [
516
- GUID_CACHE_FILE2,
517
- PACKAGE_CACHE_FILE2,
518
- LOCAL_PACKAGE_CACHE_FILE2,
519
- TYPE_REGISTRY_FILE2,
520
- DOC_INDEX_FILE2
104
+ GUID_CACHE_FILE,
105
+ PACKAGE_CACHE_FILE,
106
+ LOCAL_PACKAGE_CACHE_FILE,
107
+ TYPE_REGISTRY_FILE,
108
+ DOC_INDEX_FILE
521
109
  ], filesRemoved);
522
110
  }
523
111
  return {
@@ -542,15 +130,15 @@ function resolve_cleanup_modes(options) {
542
130
  return modes;
543
131
  }
544
132
  function remove_stale_lock_files(configPath, filesRemoved) {
545
- const editorLockPath = import_path4.join(configPath, EDITOR_LOCK_FILE);
546
- if (import_fs4.existsSync(editorLockPath) && is_stale_editor_lock(editorLockPath)) {
133
+ const editorLockPath = import_path.join(configPath, EDITOR_LOCK_FILE);
134
+ if (import_fs.existsSync(editorLockPath) && is_stale_editor_lock(editorLockPath)) {
547
135
  remove_file(configPath, EDITOR_LOCK_FILE, filesRemoved);
548
136
  }
549
137
  remove_file(configPath, LAST_EDITOR_CONFIG_FILE, filesRemoved);
550
138
  }
551
139
  function is_stale_editor_lock(filePath) {
552
140
  try {
553
- const parsed = JSON.parse(import_fs4.readFileSync(filePath, "utf-8"));
141
+ const parsed = JSON.parse(import_fs.readFileSync(filePath, "utf-8"));
554
142
  if (!is_record(parsed)) {
555
143
  return true;
556
144
  }
@@ -580,48 +168,44 @@ function remove_files(configPath, files, filesRemoved) {
580
168
  }
581
169
  }
582
170
  function remove_file(configPath, file, filesRemoved) {
583
- const filePath = import_path4.join(configPath, file);
584
- if (!import_fs4.existsSync(filePath)) {
171
+ const filePath = import_path.join(configPath, file);
172
+ if (!import_fs.existsSync(filePath)) {
585
173
  return;
586
174
  }
587
175
  try {
588
- import_fs4.unlinkSync(filePath);
176
+ import_fs.unlinkSync(filePath);
589
177
  filesRemoved.push(file);
590
178
  } catch {}
591
179
  }
592
180
  function removeDirectoryRecursive(dir) {
593
- if (!import_fs4.existsSync(dir)) {
181
+ if (!import_fs.existsSync(dir)) {
594
182
  return;
595
183
  }
596
- const entries = import_fs4.readdirSync(dir, { withFileTypes: true });
184
+ const entries = import_fs.readdirSync(dir, { withFileTypes: true });
597
185
  for (const entry of entries) {
598
- const fullPath = import_path4.join(dir, entry.name);
186
+ const fullPath = import_path.join(dir, entry.name);
599
187
  if (entry.isDirectory()) {
600
188
  removeDirectoryRecursive(fullPath);
601
189
  } else {
602
- import_fs4.unlinkSync(fullPath);
190
+ import_fs.unlinkSync(fullPath);
603
191
  }
604
192
  }
605
- import_fs4.rmdirSync(dir);
193
+ import_fs.rmdirSync(dir);
606
194
  }
607
- // src/project-search.ts
608
- var import_fs6 = require("fs");
609
- var path = __toESM(require("path"));
610
-
611
195
  // src/utils.ts
612
- var import_fs5 = require("fs");
613
- var import_path5 = require("path");
196
+ var import_fs2 = require("fs");
197
+ var import_path2 = require("path");
614
198
  function find_unity_project_root(startDir) {
615
- let dir = import_path5.resolve(startDir || process.cwd());
616
- const root = import_path5.resolve("/");
199
+ let dir = import_path2.resolve(startDir || process.cwd());
200
+ const root = import_path2.resolve("/");
617
201
  while (dir !== root) {
618
- if (import_fs5.existsSync(import_path5.join(dir, ".unity-agentic")))
202
+ if (import_fs2.existsSync(import_path2.join(dir, ".unity-agentic")))
619
203
  return dir;
620
- if (import_fs5.existsSync(import_path5.join(dir, "Assets")) && import_fs5.existsSync(import_path5.join(dir, "ProjectSettings")))
204
+ if (import_fs2.existsSync(import_path2.join(dir, "Assets")) && import_fs2.existsSync(import_path2.join(dir, "ProjectSettings")))
621
205
  return dir;
622
- if (import_fs5.existsSync(import_path5.join(dir, "Assets")))
206
+ if (import_fs2.existsSync(import_path2.join(dir, "Assets")))
623
207
  return dir;
624
- const parent = import_path5.dirname(dir);
208
+ const parent = import_path2.dirname(dir);
625
209
  if (parent === dir)
626
210
  break;
627
211
  dir = parent;
@@ -629,9 +213,9 @@ function find_unity_project_root(startDir) {
629
213
  return null;
630
214
  }
631
215
  function atomicWrite(filePath, content) {
632
- if (import_fs5.existsSync(filePath)) {
216
+ if (import_fs2.existsSync(filePath)) {
633
217
  try {
634
- import_fs5.accessSync(filePath, import_fs5.constants.W_OK);
218
+ import_fs2.accessSync(filePath, import_fs2.constants.W_OK);
635
219
  } catch {
636
220
  return {
637
221
  success: false,
@@ -645,9 +229,9 @@ function atomicWrite(filePath, content) {
645
229
  const bakPath = `${filePath}.${suffix}.bak`;
646
230
  let bakCreated = false;
647
231
  try {
648
- import_fs5.writeFileSync(tmpPath, content, "utf-8");
232
+ import_fs2.writeFileSync(tmpPath, content, "utf-8");
649
233
  try {
650
- import_fs5.renameSync(filePath, bakPath);
234
+ import_fs2.renameSync(filePath, bakPath);
651
235
  bakCreated = true;
652
236
  } catch (err) {
653
237
  if (is_enoent(err)) {
@@ -656,10 +240,10 @@ function atomicWrite(filePath, content) {
656
240
  throw err;
657
241
  }
658
242
  }
659
- import_fs5.renameSync(tmpPath, filePath);
243
+ import_fs2.renameSync(tmpPath, filePath);
660
244
  if (bakCreated) {
661
245
  try {
662
- import_fs5.unlinkSync(bakPath);
246
+ import_fs2.unlinkSync(bakPath);
663
247
  } catch {}
664
248
  }
665
249
  return {
@@ -670,13 +254,13 @@ function atomicWrite(filePath, content) {
670
254
  } catch (error) {
671
255
  if (bakCreated) {
672
256
  try {
673
- import_fs5.renameSync(bakPath, filePath);
257
+ import_fs2.renameSync(bakPath, filePath);
674
258
  } catch (restoreError) {
675
259
  console.error("Failed to restore backup:", restoreError);
676
260
  }
677
261
  }
678
262
  try {
679
- import_fs5.unlinkSync(tmpPath);
263
+ import_fs2.unlinkSync(tmpPath);
680
264
  } catch {}
681
265
  return {
682
266
  success: false,
@@ -688,17 +272,6 @@ function atomicWrite(filePath, content) {
688
272
  function is_enoent(err) {
689
273
  return err instanceof Error && "code" in err && err.code === "ENOENT";
690
274
  }
691
- function is_match_all(pattern) {
692
- return pattern === "*" || pattern === "." || pattern === "**" || pattern === ".*";
693
- }
694
- function glob_match(pattern, text) {
695
- if (!pattern.includes("*") && !pattern.includes("?")) {
696
- return pattern.toLowerCase() === text.toLowerCase();
697
- }
698
- const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
699
- const regex_str = escaped.replace(/\*/g, ".*").replace(/\?/g, ".");
700
- return new RegExp(`^${regex_str}$`, "i").test(text);
701
- }
702
275
  function generateGuid() {
703
276
  const hex = "0123456789abcdef";
704
277
  let guid = "";
@@ -707,510 +280,4 @@ function generateGuid() {
707
280
  }
708
281
  return guid;
709
282
  }
710
-
711
- // src/project-search.ts
712
- var BINARY_EXTENSIONS = new Set([
713
- ".png",
714
- ".jpg",
715
- ".jpeg",
716
- ".gif",
717
- ".bmp",
718
- ".tga",
719
- ".psd",
720
- ".tif",
721
- ".tiff",
722
- ".fbx",
723
- ".obj",
724
- ".dae",
725
- ".blend",
726
- ".3ds",
727
- ".max",
728
- ".dll",
729
- ".so",
730
- ".dylib",
731
- ".exe",
732
- ".a",
733
- ".lib",
734
- ".mp3",
735
- ".wav",
736
- ".ogg",
737
- ".aif",
738
- ".aiff",
739
- ".mp4",
740
- ".mov",
741
- ".avi",
742
- ".wmv",
743
- ".zip",
744
- ".gz",
745
- ".tar",
746
- ".rar",
747
- ".7z",
748
- ".ttf",
749
- ".otf",
750
- ".woff",
751
- ".woff2",
752
- ".bank",
753
- ".bytes",
754
- ".db"
755
- ]);
756
- var SKIP_DIRS = new Set(["Library", "Temp", "obj", "Logs", ".git", ".unity-agentic", "node_modules"]);
757
- function walk_project_files(project_path, extensions, exclude_dirs) {
758
- const nativeWalk = getNativeWalkProjectFiles();
759
- if (nativeWalk) {
760
- try {
761
- return nativeWalk(project_path, extensions, exclude_dirs ?? null);
762
- } catch {}
763
- }
764
- return walk_project_files_js(project_path, extensions, exclude_dirs);
765
- }
766
- function walk_project_files_js(project_path, extensions, exclude_dirs) {
767
- const result = [];
768
- const skipSet = new Set([...SKIP_DIRS, ...exclude_dirs || []]);
769
- const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
770
- function walk(dir) {
771
- let entries;
772
- try {
773
- entries = import_fs6.readdirSync(dir);
774
- } catch {
775
- return;
776
- }
777
- for (const entry of entries) {
778
- const full = path.join(dir, entry);
779
- let stat;
780
- try {
781
- stat = import_fs6.statSync(full);
782
- } catch {
783
- continue;
784
- }
785
- if (stat.isDirectory()) {
786
- if (!skipSet.has(entry)) {
787
- walk(full);
788
- }
789
- } else if (stat.isFile()) {
790
- const ext = path.extname(entry).toLowerCase();
791
- if (extSet.has(ext)) {
792
- result.push(full);
793
- }
794
- }
795
- }
796
- }
797
- const assetsDir = path.join(project_path, "Assets");
798
- if (import_fs6.existsSync(assetsDir)) {
799
- walk(assetsDir);
800
- } else {
801
- walk(project_path);
802
- }
803
- if (extSet.has(".asset")) {
804
- const settingsDir = path.join(project_path, "ProjectSettings");
805
- if (import_fs6.existsSync(settingsDir)) {
806
- walk(settingsDir);
807
- }
808
- }
809
- return result;
810
- }
811
- function search_project(options) {
812
- const {
813
- project_path,
814
- name,
815
- exact = false,
816
- component,
817
- tag,
818
- layer,
819
- file_type = "all",
820
- max_matches
821
- } = options;
822
- if (max_matches !== undefined && max_matches < 1) {
823
- return {
824
- success: false,
825
- project_path,
826
- total_files_scanned: 0,
827
- total_matches: 0,
828
- cursor: 0,
829
- truncated: false,
830
- matches: [],
831
- error: "--max-matches must be a positive integer (>= 1)"
832
- };
833
- }
834
- if (name !== undefined && name.trim() === "") {
835
- return {
836
- success: false,
837
- project_path,
838
- total_files_scanned: 0,
839
- total_matches: 0,
840
- cursor: 0,
841
- truncated: false,
842
- matches: [],
843
- error: "Name pattern must not be empty"
844
- };
845
- }
846
- if (!import_fs6.existsSync(project_path)) {
847
- return {
848
- success: false,
849
- project_path,
850
- total_files_scanned: 0,
851
- total_matches: 0,
852
- cursor: 0,
853
- truncated: false,
854
- matches: [],
855
- error: `Project path not found: ${project_path}`
856
- };
857
- }
858
- const ASSET_TYPE_EXTENSIONS = {
859
- mat: [".mat"],
860
- anim: [".anim"],
861
- controller: [".controller"],
862
- asset: [".asset"]
863
- };
864
- const isAssetType = file_type in ASSET_TYPE_EXTENSIONS;
865
- if (isAssetType) {
866
- const extensions2 = ASSET_TYPE_EXTENSIONS[file_type];
867
- const files2 = walk_project_files(project_path, extensions2);
868
- const matches2 = [];
869
- for (const file of files2) {
870
- const relPath = path.relative(project_path, file);
871
- const fileName = path.basename(file, path.extname(file));
872
- if (name) {
873
- const nameLower = name.toLowerCase();
874
- const hasWildcard = name.includes("*") || name.includes("?");
875
- if (hasWildcard) {
876
- if (!glob_match(name, fileName))
877
- continue;
878
- } else if (exact) {
879
- if (fileName !== name)
880
- continue;
881
- } else {
882
- if (!fileName.toLowerCase().includes(nameLower))
883
- continue;
884
- }
885
- }
886
- let display_name = fileName;
887
- try {
888
- const content = import_fs6.readFileSync(file, "utf-8");
889
- const nameMatch = /^\s*m_Name:\s*(.+)$/m.exec(content.slice(0, 2000));
890
- if (nameMatch)
891
- display_name = nameMatch[1].trim();
892
- } catch {}
893
- matches2.push({
894
- file: relPath,
895
- game_object: display_name,
896
- file_id: "0"
897
- });
898
- if (max_matches !== undefined && matches2.length >= max_matches)
899
- break;
900
- }
901
- return {
902
- success: true,
903
- project_path,
904
- total_files_scanned: files2.length,
905
- total_matches: matches2.length,
906
- cursor: 0,
907
- truncated: max_matches !== undefined && matches2.length >= max_matches,
908
- matches: matches2
909
- };
910
- }
911
- if (!isNativeModuleAvailable()) {
912
- return {
913
- success: false,
914
- project_path,
915
- total_files_scanned: 0,
916
- total_matches: 0,
917
- cursor: 0,
918
- truncated: false,
919
- matches: [],
920
- error: "Native scanner module not available. Run bun install in the project root."
921
- };
922
- }
923
- const extensions = [];
924
- if (file_type === "scene" || file_type === "all")
925
- extensions.push(".unity");
926
- if (file_type === "prefab" || file_type === "all")
927
- extensions.push(".prefab");
928
- const files = walk_project_files(project_path, extensions);
929
- const scanner = new UnityScanner;
930
- const matches = [];
931
- let files_with_errors = 0;
932
- for (const file of files) {
933
- try {
934
- let gameObjects;
935
- const needComponents = !!component;
936
- const needMetadata = !!(tag || layer !== undefined);
937
- if (name && !needMetadata && !needComponents) {
938
- gameObjects = scanner.find_by_name(file, name, !exact);
939
- } else if (needComponents) {
940
- gameObjects = scanner.scan_scene_with_components(file);
941
- if (name && !is_match_all(name)) {
942
- const nameLower = name.toLowerCase();
943
- const hasWildcard = name.includes("*") || name.includes("?");
944
- gameObjects = gameObjects.filter((go) => {
945
- if (!go.name)
946
- return false;
947
- if (hasWildcard) {
948
- return glob_match(name, go.name);
949
- }
950
- if (exact) {
951
- return go.name === name;
952
- }
953
- return go.name.toLowerCase().includes(nameLower);
954
- });
955
- }
956
- } else if (needMetadata) {
957
- gameObjects = scanner.scan_scene_metadata(file);
958
- if (name && !is_match_all(name)) {
959
- const nameLower = name.toLowerCase();
960
- const hasWildcard = name.includes("*") || name.includes("?");
961
- gameObjects = gameObjects.filter((go) => {
962
- if (!go.name)
963
- return false;
964
- if (hasWildcard) {
965
- return glob_match(name, go.name);
966
- }
967
- if (exact) {
968
- return go.name === name;
969
- }
970
- return go.name.toLowerCase().includes(nameLower);
971
- });
972
- }
973
- } else {
974
- gameObjects = scanner.scan_scene_minimal(file);
975
- }
976
- for (const go of gameObjects) {
977
- const isFindResult = "resultType" in go;
978
- const isPrefab = isFindResult && go.resultType === "PrefabInstance";
979
- if (isPrefab && (component || tag || layer !== undefined)) {
980
- continue;
981
- }
982
- if (component) {
983
- if ("components" in go && go.components) {
984
- const hasComponent = go.components.some((c) => glob_match(component, c.type));
985
- if (!hasComponent)
986
- continue;
987
- } else {
988
- continue;
989
- }
990
- }
991
- if (tag) {
992
- if (!("tag" in go) || go.tag !== tag)
993
- continue;
994
- }
995
- if (layer !== undefined) {
996
- if (!("layer" in go) || go.layer !== layer)
997
- continue;
998
- }
999
- const relPath = path.relative(project_path, file);
1000
- const fileId = isFindResult ? go.fileId : go.file_id;
1001
- const match = {
1002
- file: relPath,
1003
- game_object: go.name,
1004
- file_id: fileId,
1005
- tag: "tag" in go ? go.tag : undefined,
1006
- layer: "layer" in go ? go.layer : undefined
1007
- };
1008
- if ("components" in go && go.components) {
1009
- match.components = go.components.map((c) => c.type);
1010
- }
1011
- matches.push(match);
1012
- if (max_matches !== undefined && matches.length >= max_matches)
1013
- break;
1014
- }
1015
- if (max_matches !== undefined && matches.length >= max_matches)
1016
- break;
1017
- } catch {
1018
- files_with_errors++;
1019
- continue;
1020
- }
1021
- }
1022
- return {
1023
- success: true,
1024
- project_path,
1025
- total_files_scanned: files.length,
1026
- total_matches: matches.length,
1027
- files_with_errors: files_with_errors > 0 ? files_with_errors : undefined,
1028
- cursor: 0,
1029
- truncated: max_matches !== undefined && matches.length >= max_matches,
1030
- matches
1031
- };
1032
- }
1033
- function grep_project(options) {
1034
- const nativeGrep = getNativeGrepProject();
1035
- if (nativeGrep) {
1036
- try {
1037
- const nativeResult = nativeGrep({
1038
- projectPath: options.project_path,
1039
- pattern: options.pattern,
1040
- fileType: options.file_type,
1041
- maxResults: options.max_results,
1042
- contextLines: options.context_lines
1043
- });
1044
- return {
1045
- success: nativeResult.success,
1046
- project_path: nativeResult.projectPath,
1047
- pattern: nativeResult.pattern,
1048
- total_files_scanned: nativeResult.totalFilesScanned,
1049
- total_matches: nativeResult.totalMatches,
1050
- truncated: nativeResult.truncated,
1051
- error: nativeResult.error,
1052
- matches: nativeResult.matches.map((m) => ({
1053
- file: m.file,
1054
- line_number: m.lineNumber,
1055
- line: m.line,
1056
- context_before: m.contextBefore,
1057
- context_after: m.contextAfter
1058
- }))
1059
- };
1060
- } catch {}
1061
- }
1062
- return grep_project_js(options);
1063
- }
1064
- function grep_project_js(options) {
1065
- const {
1066
- project_path,
1067
- pattern,
1068
- file_type = "all",
1069
- max_results = 100,
1070
- context_lines = 0
1071
- } = options;
1072
- if (!import_fs6.existsSync(project_path)) {
1073
- return {
1074
- success: false,
1075
- project_path,
1076
- pattern,
1077
- total_files_scanned: 0,
1078
- total_matches: 0,
1079
- truncated: false,
1080
- matches: [],
1081
- error: `Project path not found: ${project_path}`
1082
- };
1083
- }
1084
- let regex;
1085
- try {
1086
- regex = new RegExp(pattern, "i");
1087
- } catch (err) {
1088
- return {
1089
- success: false,
1090
- project_path,
1091
- pattern,
1092
- total_files_scanned: 0,
1093
- total_matches: 0,
1094
- truncated: false,
1095
- matches: [],
1096
- error: `Invalid regex pattern: ${err instanceof Error ? err.message : String(err)}`
1097
- };
1098
- }
1099
- const EXTENSION_MAP = {
1100
- cs: [".cs"],
1101
- yaml: [
1102
- ".yaml",
1103
- ".yml",
1104
- ".unity",
1105
- ".prefab",
1106
- ".asset",
1107
- ".mat",
1108
- ".anim",
1109
- ".controller",
1110
- ".overrideController",
1111
- ".mask",
1112
- ".mixer",
1113
- ".lighting",
1114
- ".preset",
1115
- ".signal",
1116
- ".playable",
1117
- ".renderTexture",
1118
- ".flare",
1119
- ".guiskin",
1120
- ".terrainlayer",
1121
- ".cubemap"
1122
- ],
1123
- unity: [".unity"],
1124
- prefab: [".prefab"],
1125
- asset: [".asset"],
1126
- mat: [".mat"],
1127
- anim: [".anim"],
1128
- controller: [".controller"],
1129
- all: [
1130
- ".cs",
1131
- ".unity",
1132
- ".prefab",
1133
- ".asset",
1134
- ".mat",
1135
- ".anim",
1136
- ".controller",
1137
- ".yaml",
1138
- ".yml",
1139
- ".txt",
1140
- ".json",
1141
- ".xml",
1142
- ".shader",
1143
- ".cginc",
1144
- ".hlsl",
1145
- ".compute",
1146
- ".asmdef",
1147
- ".asmref"
1148
- ]
1149
- };
1150
- const extensions = EXTENSION_MAP[file_type] || EXTENSION_MAP.all;
1151
- const files = walk_project_files(project_path, extensions);
1152
- const matches = [];
1153
- let totalFilesScanned = 0;
1154
- let truncated = false;
1155
- for (const file of files) {
1156
- const ext = path.extname(file).toLowerCase();
1157
- if (BINARY_EXTENSIONS.has(ext))
1158
- continue;
1159
- totalFilesScanned++;
1160
- let content;
1161
- try {
1162
- content = import_fs6.readFileSync(file, "utf-8");
1163
- } catch {
1164
- continue;
1165
- }
1166
- const lines = content.split(`
1167
- `);
1168
- const relPath = path.relative(project_path, file);
1169
- for (let i = 0;i < lines.length; i++) {
1170
- if (regex.test(lines[i])) {
1171
- let line = lines[i];
1172
- if (line.length > 200) {
1173
- line = line.substring(0, 200) + "...";
1174
- }
1175
- const match = {
1176
- file: relPath,
1177
- line_number: i + 1,
1178
- line
1179
- };
1180
- if (context_lines > 0) {
1181
- match.context_before = [];
1182
- match.context_after = [];
1183
- for (let j = Math.max(0, i - context_lines);j < i; j++) {
1184
- let ctxLine = lines[j];
1185
- if (ctxLine.length > 200)
1186
- ctxLine = ctxLine.substring(0, 200) + "...";
1187
- match.context_before.push(ctxLine);
1188
- }
1189
- for (let j = i + 1;j <= Math.min(lines.length - 1, i + context_lines); j++) {
1190
- let ctxLine = lines[j];
1191
- if (ctxLine.length > 200)
1192
- ctxLine = ctxLine.substring(0, 200) + "...";
1193
- match.context_after.push(ctxLine);
1194
- }
1195
- }
1196
- matches.push(match);
1197
- if (matches.length >= max_results) {
1198
- truncated = true;
1199
- break;
1200
- }
1201
- }
1202
- }
1203
- if (truncated)
1204
- break;
1205
- }
1206
- return {
1207
- success: true,
1208
- project_path,
1209
- pattern,
1210
- total_files_scanned: totalFilesScanned,
1211
- total_matches: matches.length,
1212
- truncated,
1213
- matches
1214
- };
1215
- }
1216
283
  })