uloop-cli 0.44.1 → 0.45.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.
@@ -3453,8 +3453,8 @@ var require_commander = __commonJS({
3453
3453
  });
3454
3454
 
3455
3455
  // src/cli.ts
3456
- var import_fs4 = require("fs");
3457
- var import_path5 = require("path");
3456
+ var import_fs5 = require("fs");
3457
+ var import_path6 = require("path");
3458
3458
  var import_os2 = require("os");
3459
3459
  var import_child_process = require("child_process");
3460
3460
 
@@ -3475,6 +3475,11 @@ var {
3475
3475
  Help
3476
3476
  } = import_index.default;
3477
3477
 
3478
+ // src/execute-tool.ts
3479
+ var readline = __toESM(require("readline"), 1);
3480
+ var import_fs3 = require("fs");
3481
+ var import_path4 = require("path");
3482
+
3478
3483
  // src/direct-unity-client.ts
3479
3484
  var net = __toESM(require("net"), 1);
3480
3485
 
@@ -3685,7 +3690,7 @@ var import_path3 = require("path");
3685
3690
 
3686
3691
  // src/default-tools.json
3687
3692
  var default_tools_default = {
3688
- version: "0.44.1",
3693
+ version: "0.45.0",
3689
3694
  tools: [
3690
3695
  {
3691
3696
  name: "compile",
@@ -4082,9 +4087,96 @@ function getCacheFilePath() {
4082
4087
  }
4083
4088
 
4084
4089
  // src/version.ts
4085
- var VERSION = "0.44.1";
4090
+ var VERSION = "0.45.0";
4091
+
4092
+ // src/spinner.ts
4093
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
4094
+ var FRAME_INTERVAL_MS = 80;
4095
+ function createSpinner(initialMessage) {
4096
+ if (!process.stderr.isTTY) {
4097
+ return {
4098
+ update: () => {
4099
+ },
4100
+ stop: () => {
4101
+ }
4102
+ };
4103
+ }
4104
+ let frameIndex = 0;
4105
+ let currentMessage = initialMessage;
4106
+ const render = () => {
4107
+ const frame = SPINNER_FRAMES[frameIndex];
4108
+ process.stderr.write(`\r\x1B[K${frame} ${currentMessage}`);
4109
+ frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
4110
+ };
4111
+ render();
4112
+ const intervalId = setInterval(render, FRAME_INTERVAL_MS);
4113
+ return {
4114
+ update(message) {
4115
+ currentMessage = message;
4116
+ },
4117
+ stop() {
4118
+ clearInterval(intervalId);
4119
+ process.stderr.write("\r\x1B[K");
4120
+ }
4121
+ };
4122
+ }
4086
4123
 
4087
4124
  // src/execute-tool.ts
4125
+ function suppressStdinEcho() {
4126
+ if (!process.stdin.isTTY) {
4127
+ return () => {
4128
+ };
4129
+ }
4130
+ const rl = readline.createInterface({
4131
+ input: process.stdin,
4132
+ output: process.stdout,
4133
+ terminal: false
4134
+ });
4135
+ process.stdin.setRawMode(true);
4136
+ process.stdin.resume();
4137
+ const onData = (data) => {
4138
+ if (data[0] === 3) {
4139
+ process.exit(130);
4140
+ }
4141
+ };
4142
+ process.stdin.on("data", onData);
4143
+ return () => {
4144
+ process.stdin.off("data", onData);
4145
+ process.stdin.setRawMode(false);
4146
+ process.stdin.pause();
4147
+ rl.close();
4148
+ };
4149
+ }
4150
+ var RETRY_DELAY_MS = 500;
4151
+ var MAX_RETRIES = 3;
4152
+ function sleep(ms) {
4153
+ return new Promise((resolve) => setTimeout(resolve, ms));
4154
+ }
4155
+ function isRetryableError(error) {
4156
+ if (!(error instanceof Error)) {
4157
+ return false;
4158
+ }
4159
+ const message = error.message;
4160
+ return message.includes("ECONNREFUSED") || message === "UNITY_NO_RESPONSE";
4161
+ }
4162
+ function checkUnityBusyState() {
4163
+ const projectRoot = findUnityProjectRoot();
4164
+ if (projectRoot === null) {
4165
+ return;
4166
+ }
4167
+ const compilingLock = (0, import_path4.join)(projectRoot, "Temp", "compiling.lock");
4168
+ if ((0, import_fs3.existsSync)(compilingLock)) {
4169
+ throw new Error("UNITY_COMPILING");
4170
+ }
4171
+ const domainReloadLock = (0, import_path4.join)(projectRoot, "Temp", "domainreload.lock");
4172
+ if ((0, import_fs3.existsSync)(domainReloadLock)) {
4173
+ throw new Error("UNITY_DOMAIN_RELOAD");
4174
+ }
4175
+ const serverStartingLock = (0, import_path4.join)(projectRoot, "Temp", "serverstarting.lock");
4176
+ if ((0, import_fs3.existsSync)(serverStartingLock)) {
4177
+ throw new Error("UNITY_SERVER_STARTING");
4178
+ }
4179
+ }
4088
4180
  async function executeToolCommand(toolName, params, globalOptions) {
4089
4181
  let portNumber;
4090
4182
  if (globalOptions.port) {
@@ -4095,14 +4187,38 @@ async function executeToolCommand(toolName, params, globalOptions) {
4095
4187
  portNumber = parsed;
4096
4188
  }
4097
4189
  const port = await resolveUnityPort(portNumber);
4098
- const client = new DirectUnityClient(port);
4099
- try {
4100
- await client.connect();
4101
- const result = await client.sendRequest(toolName, params);
4102
- console.log(JSON.stringify(result, null, 2));
4103
- } finally {
4104
- client.disconnect();
4190
+ const restoreStdin = suppressStdinEcho();
4191
+ const spinner = createSpinner("Connecting to Unity...");
4192
+ let lastError;
4193
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
4194
+ checkUnityBusyState();
4195
+ const client = new DirectUnityClient(port);
4196
+ try {
4197
+ await client.connect();
4198
+ spinner.update(`Executing ${toolName}...`);
4199
+ const result = await client.sendRequest(toolName, params);
4200
+ if (result === void 0 || result === null) {
4201
+ throw new Error("UNITY_NO_RESPONSE");
4202
+ }
4203
+ spinner.stop();
4204
+ restoreStdin();
4205
+ console.log(JSON.stringify(result, null, 2));
4206
+ return;
4207
+ } catch (error) {
4208
+ lastError = error;
4209
+ client.disconnect();
4210
+ if (!isRetryableError(error) || attempt >= MAX_RETRIES) {
4211
+ break;
4212
+ }
4213
+ spinner.update("Retrying connection...");
4214
+ await sleep(RETRY_DELAY_MS);
4215
+ } finally {
4216
+ client.disconnect();
4217
+ }
4105
4218
  }
4219
+ spinner.stop();
4220
+ restoreStdin();
4221
+ throw lastError;
4106
4222
  }
4107
4223
  async function listAvailableTools(globalOptions) {
4108
4224
  let portNumber;
@@ -4114,19 +4230,40 @@ async function listAvailableTools(globalOptions) {
4114
4230
  portNumber = parsed;
4115
4231
  }
4116
4232
  const port = await resolveUnityPort(portNumber);
4117
- const client = new DirectUnityClient(port);
4118
- try {
4119
- await client.connect();
4120
- const result = await client.sendRequest("get-tool-details", { IncludeDevelopmentOnly: false });
4121
- if (!result.Tools || !Array.isArray(result.Tools)) {
4122
- throw new Error("Unexpected response from Unity: missing Tools array");
4123
- }
4124
- for (const tool of result.Tools) {
4125
- console.log(` - ${tool.name}`);
4233
+ const restoreStdin = suppressStdinEcho();
4234
+ const spinner = createSpinner("Connecting to Unity...");
4235
+ let lastError;
4236
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
4237
+ checkUnityBusyState();
4238
+ const client = new DirectUnityClient(port);
4239
+ try {
4240
+ await client.connect();
4241
+ spinner.update("Fetching tool list...");
4242
+ const result = await client.sendRequest("get-tool-details", { IncludeDevelopmentOnly: false });
4243
+ if (!result.Tools || !Array.isArray(result.Tools)) {
4244
+ throw new Error("Unexpected response from Unity: missing Tools array");
4245
+ }
4246
+ spinner.stop();
4247
+ restoreStdin();
4248
+ for (const tool of result.Tools) {
4249
+ console.log(` - ${tool.name}`);
4250
+ }
4251
+ return;
4252
+ } catch (error) {
4253
+ lastError = error;
4254
+ client.disconnect();
4255
+ if (!isRetryableError(error) || attempt >= MAX_RETRIES) {
4256
+ break;
4257
+ }
4258
+ spinner.update("Retrying connection...");
4259
+ await sleep(RETRY_DELAY_MS);
4260
+ } finally {
4261
+ client.disconnect();
4126
4262
  }
4127
- } finally {
4128
- client.disconnect();
4129
4263
  }
4264
+ spinner.stop();
4265
+ restoreStdin();
4266
+ throw lastError;
4130
4267
  }
4131
4268
  function convertProperties(unityProps) {
4132
4269
  const result = {};
@@ -4150,35 +4287,57 @@ async function syncTools(globalOptions) {
4150
4287
  portNumber = parsed;
4151
4288
  }
4152
4289
  const port = await resolveUnityPort(portNumber);
4153
- const client = new DirectUnityClient(port);
4154
- try {
4155
- await client.connect();
4156
- const result = await client.sendRequest("get-tool-details", { IncludeDevelopmentOnly: false });
4157
- if (!result.Tools || !Array.isArray(result.Tools)) {
4158
- throw new Error("Unexpected response from Unity: missing Tools array");
4159
- }
4160
- const cache = {
4161
- version: VERSION,
4162
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4163
- tools: result.Tools.map((tool) => ({
4164
- name: tool.name,
4165
- description: tool.description,
4166
- inputSchema: {
4167
- type: "object",
4168
- properties: convertProperties(tool.parameterSchema.Properties),
4169
- required: tool.parameterSchema.Required
4170
- }
4171
- }))
4172
- };
4173
- saveToolsCache(cache);
4174
- console.log(`Synced ${cache.tools.length} tools to ${getCacheFilePath()}`);
4175
- console.log("\nTools:");
4176
- for (const tool of cache.tools) {
4177
- console.log(` - ${tool.name}`);
4290
+ const restoreStdin = suppressStdinEcho();
4291
+ const spinner = createSpinner("Connecting to Unity...");
4292
+ let lastError;
4293
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
4294
+ checkUnityBusyState();
4295
+ const client = new DirectUnityClient(port);
4296
+ try {
4297
+ await client.connect();
4298
+ spinner.update("Syncing tools...");
4299
+ const result = await client.sendRequest("get-tool-details", { IncludeDevelopmentOnly: false });
4300
+ spinner.stop();
4301
+ if (!result.Tools || !Array.isArray(result.Tools)) {
4302
+ restoreStdin();
4303
+ throw new Error("Unexpected response from Unity: missing Tools array");
4304
+ }
4305
+ const cache = {
4306
+ version: VERSION,
4307
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4308
+ tools: result.Tools.map((tool) => ({
4309
+ name: tool.name,
4310
+ description: tool.description,
4311
+ inputSchema: {
4312
+ type: "object",
4313
+ properties: convertProperties(tool.parameterSchema.Properties),
4314
+ required: tool.parameterSchema.Required
4315
+ }
4316
+ }))
4317
+ };
4318
+ saveToolsCache(cache);
4319
+ console.log(`Synced ${cache.tools.length} tools to ${getCacheFilePath()}`);
4320
+ console.log("\nTools:");
4321
+ for (const tool of cache.tools) {
4322
+ console.log(` - ${tool.name}`);
4323
+ }
4324
+ restoreStdin();
4325
+ return;
4326
+ } catch (error) {
4327
+ lastError = error;
4328
+ client.disconnect();
4329
+ if (!isRetryableError(error) || attempt >= MAX_RETRIES) {
4330
+ break;
4331
+ }
4332
+ spinner.update("Retrying connection...");
4333
+ await sleep(RETRY_DELAY_MS);
4334
+ } finally {
4335
+ client.disconnect();
4178
4336
  }
4179
- } finally {
4180
- client.disconnect();
4181
4337
  }
4338
+ spinner.stop();
4339
+ restoreStdin();
4340
+ throw lastError;
4182
4341
  }
4183
4342
 
4184
4343
  // src/arg-parser.ts
@@ -4188,12 +4347,12 @@ function pascalToKebabCase(pascal) {
4188
4347
  }
4189
4348
 
4190
4349
  // src/skills/skills-manager.ts
4191
- var import_fs3 = require("fs");
4192
- var import_path4 = require("path");
4350
+ var import_fs4 = require("fs");
4351
+ var import_path5 = require("path");
4193
4352
  var import_os = require("os");
4194
4353
 
4195
4354
  // src/skills/skill-definitions/uloop-compile/SKILL.md
4196
- var SKILL_default = "---\nname: uloop-compile\ndescription: Compile Unity project via uloop CLI. Use when you need to: (1) Verify C# code compiles successfully after editing scripts, (2) Check for compile errors or warnings, (3) Validate script changes before running tests.\n---\n\n# uloop compile\n\nExecute Unity project compilation.\n\n## Usage\n\n```bash\nuloop compile [--force-recompile]\n```\n\n## Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `--force-recompile` | boolean | Force full recompilation (triggers Domain Reload) |\n\n## Examples\n\n```bash\n# Check compilation\nuloop compile\n\n# Force full recompilation\nuloop compile --force-recompile\n```\n\n## Output\n\nReturns JSON:\n- `Success`: boolean\n- `ErrorCount`: number\n- `WarningCount`: number\n";
4355
+ var SKILL_default = '---\nname: uloop-compile\ndescription: Compile Unity project via uloop CLI. Use when you need to: (1) Verify C# code compiles successfully after editing scripts, (2) Check for compile errors or warnings, (3) Validate script changes before running tests.\n---\n\n# uloop compile\n\nExecute Unity project compilation.\n\n## Usage\n\n```bash\nuloop compile [--force-recompile]\n```\n\n## Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `--force-recompile` | boolean | Force full recompilation (triggers Domain Reload) |\n\n## Examples\n\n```bash\n# Check compilation\nuloop compile\n\n# Force full recompilation\nuloop compile --force-recompile\n```\n\n## Output\n\nReturns JSON:\n- `Success`: boolean\n- `ErrorCount`: number\n- `WarningCount`: number\n\n## Troubleshooting\n\nIf CLI hangs or shows "Unity is busy" errors after compilation, stale lock files may be preventing connection. Run the following to clean them up:\n\n```bash\nuloop fix\n```\n\nThis removes any leftover lock files (`compiling.lock`, `domainreload.lock`, `serverstarting.lock`) from the Unity project\'s Temp directory.\n';
4197
4356
 
4198
4357
  // src/skills/skill-definitions/uloop-get-logs/SKILL.md
4199
4358
  var SKILL_default2 = '---\nname: uloop-get-logs\ndescription: Retrieve Unity Console logs via uloop CLI. Use when you need to: (1) Check for errors or warnings after operations, (2) Debug runtime issues in Unity Editor, (3) Investigate unexpected behavior or exceptions.\n---\n\n# uloop get-logs\n\nRetrieve logs from Unity Console.\n\n## Usage\n\n```bash\nuloop get-logs [options]\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `--log-type` | string | `All` | Log type filter: `Error`, `Warning`, `Log`, `All` |\n| `--max-count` | integer | `100` | Maximum number of logs to retrieve |\n| `--search-text` | string | - | Text to search within logs |\n| `--include-stack-trace` | boolean | `true` | Include stack trace in output |\n| `--use-regex` | boolean | `false` | Use regex for search |\n| `--search-in-stack-trace` | boolean | `false` | Search within stack trace |\n\n## Examples\n\n```bash\n# Get all logs\nuloop get-logs\n\n# Get only errors\nuloop get-logs --log-type Error\n\n# Search for specific text\nuloop get-logs --search-text "NullReference"\n\n# Regex search\nuloop get-logs --search-text "Missing.*Component" --use-regex\n```\n\n## Output\n\nReturns JSON array of log entries with message, type, and optional stack trace.\n';
@@ -4270,25 +4429,25 @@ var BUNDLED_SKILLS = [
4270
4429
 
4271
4430
  // src/skills/skills-manager.ts
4272
4431
  function getGlobalSkillsDir() {
4273
- return (0, import_path4.join)((0, import_os.homedir)(), ".claude", "skills");
4432
+ return (0, import_path5.join)((0, import_os.homedir)(), ".claude", "skills");
4274
4433
  }
4275
4434
  function getProjectSkillsDir() {
4276
- return (0, import_path4.join)(process.cwd(), ".claude", "skills");
4435
+ return (0, import_path5.join)(process.cwd(), ".claude", "skills");
4277
4436
  }
4278
4437
  function getSkillPath(skillDirName, global) {
4279
4438
  const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
4280
- return (0, import_path4.join)(baseDir, skillDirName, "SKILL.md");
4439
+ return (0, import_path5.join)(baseDir, skillDirName, "SKILL.md");
4281
4440
  }
4282
4441
  function isSkillInstalled(skill, global) {
4283
4442
  const skillPath = getSkillPath(skill.dirName, global);
4284
- return (0, import_fs3.existsSync)(skillPath);
4443
+ return (0, import_fs4.existsSync)(skillPath);
4285
4444
  }
4286
4445
  function isSkillOutdated(skill, global) {
4287
4446
  const skillPath = getSkillPath(skill.dirName, global);
4288
- if (!(0, import_fs3.existsSync)(skillPath)) {
4447
+ if (!(0, import_fs4.existsSync)(skillPath)) {
4289
4448
  return false;
4290
4449
  }
4291
- const installedContent = (0, import_fs3.readFileSync)(skillPath, "utf-8");
4450
+ const installedContent = (0, import_fs4.readFileSync)(skillPath, "utf-8");
4292
4451
  return installedContent !== skill.content;
4293
4452
  }
4294
4453
  function getSkillStatus(skill, global) {
@@ -4309,18 +4468,18 @@ function getAllSkillStatuses(global) {
4309
4468
  }
4310
4469
  function installSkill(skill, global) {
4311
4470
  const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
4312
- const skillDir = (0, import_path4.join)(baseDir, skill.dirName);
4313
- const skillPath = (0, import_path4.join)(skillDir, "SKILL.md");
4314
- (0, import_fs3.mkdirSync)(skillDir, { recursive: true });
4315
- (0, import_fs3.writeFileSync)(skillPath, skill.content, "utf-8");
4471
+ const skillDir = (0, import_path5.join)(baseDir, skill.dirName);
4472
+ const skillPath = (0, import_path5.join)(skillDir, "SKILL.md");
4473
+ (0, import_fs4.mkdirSync)(skillDir, { recursive: true });
4474
+ (0, import_fs4.writeFileSync)(skillPath, skill.content, "utf-8");
4316
4475
  }
4317
4476
  function uninstallSkill(skill, global) {
4318
4477
  const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
4319
- const skillDir = (0, import_path4.join)(baseDir, skill.dirName);
4320
- if (!(0, import_fs3.existsSync)(skillDir)) {
4478
+ const skillDir = (0, import_path5.join)(baseDir, skill.dirName);
4479
+ if (!(0, import_fs4.existsSync)(skillDir)) {
4321
4480
  return false;
4322
4481
  }
4323
- (0, import_fs3.rmSync)(skillDir, { recursive: true, force: true });
4482
+ (0, import_fs4.rmSync)(skillDir, { recursive: true, force: true });
4324
4483
  return true;
4325
4484
  }
4326
4485
  function installAllSkills(global) {
@@ -4438,7 +4597,7 @@ Uninstalling uloop skills (${location})...`);
4438
4597
  }
4439
4598
 
4440
4599
  // src/cli.ts
4441
- var BUILTIN_COMMANDS = ["list", "sync", "completion", "update", "skills"];
4600
+ var BUILTIN_COMMANDS = ["list", "sync", "completion", "update", "fix", "skills"];
4442
4601
  var program2 = new Command();
4443
4602
  program2.name("uloop").description("Unity MCP CLI - Direct communication with Unity Editor").version(VERSION, "-v, --version", "Output the version number");
4444
4603
  program2.option("--list-commands", "List all command names (for shell completion)");
@@ -4455,6 +4614,9 @@ program2.command("completion").description("Setup shell completion").option("--i
4455
4614
  program2.command("update").description("Update uloop CLI to the latest version").action(() => {
4456
4615
  updateCli();
4457
4616
  });
4617
+ program2.command("fix").description("Clean up stale lock files that may prevent CLI from connecting").action(() => {
4618
+ cleanupLockFiles();
4619
+ });
4458
4620
  registerSkillsCommand(program2);
4459
4621
  var toolsCache = loadToolsCache();
4460
4622
  for (const tool of toolsCache.tools) {
@@ -4538,27 +4700,34 @@ function extractGlobalOptions(options) {
4538
4700
  port: options["port"]
4539
4701
  };
4540
4702
  }
4541
- function isDomainReloadLockFilePresent() {
4542
- const projectRoot = findUnityProjectRoot();
4543
- if (projectRoot === null) {
4544
- return false;
4545
- }
4546
- const lockPath = (0, import_path5.join)(projectRoot, "Temp", "domainreload.lock");
4547
- return (0, import_fs4.existsSync)(lockPath);
4548
- }
4549
4703
  async function runWithErrorHandling(fn) {
4550
4704
  try {
4551
4705
  await fn();
4552
4706
  } catch (error) {
4553
4707
  const message = error instanceof Error ? error.message : String(error);
4708
+ if (message === "UNITY_COMPILING") {
4709
+ console.error("\x1B[33m\u23F3 Unity is compiling scripts.\x1B[0m");
4710
+ console.error("Please wait for compilation to finish and try again.");
4711
+ process.exit(1);
4712
+ }
4713
+ if (message === "UNITY_DOMAIN_RELOAD") {
4714
+ console.error("\x1B[33m\u23F3 Unity is reloading (Domain Reload in progress).\x1B[0m");
4715
+ console.error("Please wait a moment and try again.");
4716
+ process.exit(1);
4717
+ }
4718
+ if (message === "UNITY_SERVER_STARTING") {
4719
+ console.error("\x1B[33m\u23F3 Unity server is starting.\x1B[0m");
4720
+ console.error("Please wait a moment and try again.");
4721
+ process.exit(1);
4722
+ }
4723
+ if (message === "UNITY_NO_RESPONSE") {
4724
+ console.error("\x1B[33m\u23F3 Unity is busy (no response received).\x1B[0m");
4725
+ console.error("Unity may be compiling, reloading, or starting. Please wait and try again.");
4726
+ process.exit(1);
4727
+ }
4554
4728
  if (message.includes("ECONNREFUSED")) {
4555
- if (isDomainReloadLockFilePresent()) {
4556
- console.error("\x1B[33m\u23F3 Unity is reloading (Domain Reload in progress).\x1B[0m");
4557
- console.error("Please wait a moment and try again.");
4558
- } else {
4559
- console.error("\x1B[31mError: Cannot connect to Unity.\x1B[0m");
4560
- console.error("Make sure Unity is running with uLoopMCP installed.");
4561
- }
4729
+ console.error("\x1B[31mError: Cannot connect to Unity.\x1B[0m");
4730
+ console.error("Make sure Unity is running with uLoopMCP installed.");
4562
4731
  process.exit(1);
4563
4732
  }
4564
4733
  console.error(`\x1B[31mError: ${message}\x1B[0m`);
@@ -4567,7 +4736,7 @@ async function runWithErrorHandling(fn) {
4567
4736
  }
4568
4737
  function detectShell() {
4569
4738
  const shell = process.env["SHELL"] || "";
4570
- const shellName = (0, import_path5.basename)(shell).replace(/\.exe$/i, "");
4739
+ const shellName = (0, import_path6.basename)(shell).replace(/\.exe$/i, "");
4571
4740
  if (shellName === "zsh") {
4572
4741
  return "zsh";
4573
4742
  }
@@ -4582,12 +4751,12 @@ function detectShell() {
4582
4751
  function getShellConfigPath(shell) {
4583
4752
  const home = (0, import_os2.homedir)();
4584
4753
  if (shell === "zsh") {
4585
- return (0, import_path5.join)(home, ".zshrc");
4754
+ return (0, import_path6.join)(home, ".zshrc");
4586
4755
  }
4587
4756
  if (shell === "powershell") {
4588
- return (0, import_path5.join)(home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
4757
+ return (0, import_path6.join)(home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
4589
4758
  }
4590
- return (0, import_path5.join)(home, ".bashrc");
4759
+ return (0, import_path6.join)(home, ".bashrc");
4591
4760
  }
4592
4761
  function getCompletionScript(shell) {
4593
4762
  if (shell === "bash") {
@@ -4663,6 +4832,30 @@ function updateCli() {
4663
4832
  process.exit(1);
4664
4833
  });
4665
4834
  }
4835
+ var LOCK_FILES = ["compiling.lock", "domainreload.lock", "serverstarting.lock"];
4836
+ function cleanupLockFiles() {
4837
+ const projectRoot = findUnityProjectRoot();
4838
+ if (projectRoot === null) {
4839
+ console.error("Could not find Unity project root.");
4840
+ process.exit(1);
4841
+ }
4842
+ const tempDir = (0, import_path6.join)(projectRoot, "Temp");
4843
+ let cleaned = 0;
4844
+ for (const lockFile of LOCK_FILES) {
4845
+ const lockPath = (0, import_path6.join)(tempDir, lockFile);
4846
+ if ((0, import_fs5.existsSync)(lockPath)) {
4847
+ (0, import_fs5.unlinkSync)(lockPath);
4848
+ console.log(`Removed: ${lockFile}`);
4849
+ cleaned++;
4850
+ }
4851
+ }
4852
+ if (cleaned === 0) {
4853
+ console.log("No lock files found.");
4854
+ } else {
4855
+ console.log(`
4856
+ \u2705 Cleaned up ${cleaned} lock file(s).`);
4857
+ }
4858
+ }
4666
4859
  function handleCompletion(install, shellOverride) {
4667
4860
  let shell;
4668
4861
  if (shellOverride) {
@@ -4686,13 +4879,13 @@ function handleCompletion(install, shellOverride) {
4686
4879
  return;
4687
4880
  }
4688
4881
  const configPath = getShellConfigPath(shell);
4689
- const configDir = (0, import_path5.dirname)(configPath);
4690
- if (!(0, import_fs4.existsSync)(configDir)) {
4691
- (0, import_fs4.mkdirSync)(configDir, { recursive: true });
4882
+ const configDir = (0, import_path6.dirname)(configPath);
4883
+ if (!(0, import_fs5.existsSync)(configDir)) {
4884
+ (0, import_fs5.mkdirSync)(configDir, { recursive: true });
4692
4885
  }
4693
4886
  let content = "";
4694
- if ((0, import_fs4.existsSync)(configPath)) {
4695
- content = (0, import_fs4.readFileSync)(configPath, "utf-8");
4887
+ if ((0, import_fs5.existsSync)(configPath)) {
4888
+ content = (0, import_fs5.readFileSync)(configPath, "utf-8");
4696
4889
  content = content.replace(
4697
4890
  /\n?# >>> uloop completion >>>[\s\S]*?# <<< uloop completion <<<\n?/g,
4698
4891
  ""
@@ -4706,7 +4899,7 @@ ${startMarker}
4706
4899
  ${script}
4707
4900
  ${endMarker}
4708
4901
  `;
4709
- (0, import_fs4.writeFileSync)(configPath, content + lineToAdd, "utf-8");
4902
+ (0, import_fs5.writeFileSync)(configPath, content + lineToAdd, "utf-8");
4710
4903
  } else {
4711
4904
  const evalLine = `eval "$(uloop completion --shell ${shell})"`;
4712
4905
  const lineToAdd = `
@@ -4714,7 +4907,7 @@ ${startMarker}
4714
4907
  ${evalLine}
4715
4908
  ${endMarker}
4716
4909
  `;
4717
- (0, import_fs4.writeFileSync)(configPath, content + lineToAdd, "utf-8");
4910
+ (0, import_fs5.writeFileSync)(configPath, content + lineToAdd, "utf-8");
4718
4911
  }
4719
4912
  console.log(`Completion installed to ${configPath}`);
4720
4913
  if (shell === "powershell") {