@akiojin/unity-mcp-server 2.26.0 → 2.26.1

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.
@@ -5,21 +5,20 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
5
5
 
6
6
  export class VideoCaptureStopToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
- super(
9
- 'video_capture_stop',
10
- 'Stop current video recording and finalize the file.',
11
- {
12
- type: 'object',
13
- properties: {
14
- recordingId: { type: 'string', description: 'Optional. Stop a specific recording session. Defaults to the latest.' }
8
+ super('video_capture_stop', 'Stop current video recording and finalize the file.', {
9
+ type: 'object',
10
+ properties: {
11
+ recordingId: {
12
+ type: 'string',
13
+ description: 'Optional. Stop a specific recording session. Defaults to the latest.'
15
14
  }
16
15
  }
17
- );
16
+ });
18
17
  this.unityConnection = unityConnection;
19
18
  }
20
19
 
21
20
  /** @override */
22
- async execute(params, context) {
21
+ async execute(params, _context) {
23
22
  const response = await this.unityConnection.sendCommand('capture_video_stop', params || {});
24
23
  if (response.error) {
25
24
  return { error: response.error, code: response.code || 'UNITY_ERROR' };
@@ -16,7 +16,7 @@ export class LspProcessManager {
16
16
  const rid = this.utils.detectRid();
17
17
  const bin = await this.utils.ensureLocal(rid);
18
18
  const proc = spawn(bin, { stdio: ['pipe', 'pipe', 'pipe'] });
19
- proc.on('error', (e) => logger.error(`[csharp-lsp] process error: ${e.message}`));
19
+ proc.on('error', e => logger.error(`[csharp-lsp] process error: ${e.message}`));
20
20
  proc.on('close', (code, sig) => {
21
21
  logger.warn(`[csharp-lsp] exited code=${code} signal=${sig || ''}`);
22
22
  this.proc = null;
@@ -29,7 +29,11 @@ export class LspProcessManager {
29
29
  logger.info(`[csharp-lsp] started (pid=${proc.pid})`);
30
30
  return proc;
31
31
  })();
32
- try { return await this.starting; } finally { this.starting = null; }
32
+ try {
33
+ return await this.starting;
34
+ } finally {
35
+ this.starting = null;
36
+ }
33
37
  }
34
38
 
35
39
  async stop(graceMs = 3000) {
@@ -38,7 +42,7 @@ export class LspProcessManager {
38
42
  this.proc = null;
39
43
  try {
40
44
  // Send LSP shutdown/exit if possible
41
- const shutdown = (obj) => {
45
+ const shutdown = obj => {
42
46
  try {
43
47
  const json = JSON.stringify(obj);
44
48
  const payload = `Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`;
@@ -49,12 +53,25 @@ export class LspProcessManager {
49
53
  shutdown({ jsonrpc: '2.0', method: 'exit' });
50
54
  p.stdin.end();
51
55
  } catch {}
52
- await new Promise((resolve) => {
53
- const to = setTimeout(() => {
54
- try { p.kill('SIGTERM'); } catch {}
55
- setTimeout(() => { try { p.kill('SIGKILL'); } catch {} ; resolve(); }, 1000);
56
- }, Math.max(0, graceMs));
57
- p.on('close', () => { clearTimeout(to); resolve(); });
56
+ await new Promise(resolve => {
57
+ const to = setTimeout(
58
+ () => {
59
+ try {
60
+ p.kill('SIGTERM');
61
+ } catch {}
62
+ setTimeout(() => {
63
+ try {
64
+ p.kill('SIGKILL');
65
+ } catch {}
66
+ resolve();
67
+ }, 1000);
68
+ },
69
+ Math.max(0, graceMs)
70
+ );
71
+ p.on('close', () => {
72
+ clearTimeout(to);
73
+ resolve();
74
+ });
58
75
  });
59
76
  }
60
77
  }
@@ -3,18 +3,24 @@ import { VideoCaptureForToolHandler } from '../../handlers/video/VideoCaptureFor
3
3
 
4
4
  async function main() {
5
5
  const unity = new UnityConnection();
6
- try { await unity.connect(); } catch (e) { console.error('connect failed:', e.message); process.exit(1); }
6
+ try {
7
+ await unity.connect();
8
+ } catch (e) {
9
+ console.error('connect failed:', e.message);
10
+ process.exit(1);
11
+ }
7
12
  try {
8
13
  const ts = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
9
14
  const outputPath = `Assets/Screenshots/recordings/mcp_for_${ts}.mp4`;
10
15
  const handler = new VideoCaptureForToolHandler(unity);
11
16
  const result = await handler.execute({
12
- captureMode: 'game',
13
- width: 1280,
14
- height: 720,
15
- fps: 30,
16
- durationSec: 2,
17
- play: true
17
+ captureMode: 'game',
18
+ width: 1280,
19
+ height: 720,
20
+ fps: 30,
21
+ durationSec: 2,
22
+ play: true,
23
+ outputPath
18
24
  });
19
25
  if (result && result.error) {
20
26
  console.error('capture_video_for error:', result.error);
@@ -1,5 +1,4 @@
1
1
  import { UnityConnection } from '../../core/unityConnection.js';
2
- import { config } from '../../core/config.js';
3
2
 
4
3
  async function main() {
5
4
  const unity = new UnityConnection();
@@ -16,7 +15,9 @@ async function main() {
16
15
  // Domain reload causes disconnect. Reconnect and wait for play.
17
16
  for (let i = 0; i < 60; i++) {
18
17
  if (!unity.isConnected()) {
19
- try { await unity.connect(); } catch {}
18
+ try {
19
+ await unity.connect();
20
+ } catch {}
20
21
  }
21
22
  try {
22
23
  const s = await unity.sendCommand('get_editor_state', {});
@@ -39,19 +40,19 @@ async function main() {
39
40
 
40
41
  // Poll status a few times
41
42
  for (let i = 0; i < 16; i++) {
42
- const st = await unity.sendCommand('capture_video_status', {});
43
- // console.log('[recordPlayMode] status', st);
43
+ await unity.sendCommand('capture_video_status', {});
44
44
  await new Promise(r => setTimeout(r, 250));
45
45
  }
46
46
 
47
47
  // Ensure stopped
48
48
  await unity.sendCommand('capture_video_stop', {});
49
-
50
49
  } catch (e) {
51
50
  console.error('[recordPlayMode] error:', e.message);
52
51
  } finally {
53
52
  try {
54
- if (!unity.isConnected()) { await unity.connect(); }
53
+ if (!unity.isConnected()) {
54
+ await unity.connect();
55
+ }
55
56
  await unity.sendCommand('stop_game', {});
56
57
  } catch {}
57
58
  unity.disconnect();
@@ -1,11 +1,15 @@
1
+ /* eslint-disable no-useless-escape */
1
2
  // Lightweight C# symbol extractor for Node-side fallback (not Roslyn-accurate)
2
3
  export function parseFileSymbols(relPath, text) {
3
4
  const lines = text.split('\n');
4
5
  const result = { path: relPath, symbols: [] };
5
6
  const nsRx = /^\s*namespace\s+([A-Za-z0-9_.]+)/;
6
- const typeRx = /^\s*(?:public|internal|protected|private|abstract|sealed|static|partial|new|readonly|\s)*\s*(class|struct|interface|enum)\s+([A-Za-z0-9_]+)/;
7
- const methodRx = /^\s*(?:public|internal|protected|private|static|virtual|override|async|sealed|extern|unsafe|new|readonly|\s)+[A-Za-z0-9_<>,\[\]\?\(\)\.:\s]+\s+([A-Za-z0-9_]+)\s*\(([^)]*)\)\s*(?:\{|=>|;)/;
8
- const propRx = /^\s*(?:public|internal|protected|private|static|virtual|override|sealed|new|readonly|\s)+[A-Za-z0-9_<>,\[\]\?\.:\s]+\s+([A-Za-z0-9_]+)\s*\{/;
7
+ const typeRx =
8
+ /^\s*(?:public|internal|protected|private|abstract|sealed|static|partial|new|readonly|\s)*\s*(class|struct|interface|enum)\s+([A-Za-z0-9_]+)/;
9
+ const methodRx =
10
+ /^\s*(?:public|internal|protected|private|static|virtual|override|async|sealed|extern|unsafe|new|readonly|\s)+[A-Za-z0-9_<>,\[\]\?\(\)\.:\s]+\s+([A-Za-z0-9_]+)\s*\(([^)]*)\)\s*(?:\{|=>|;)/;
11
+ const propRx =
12
+ /^\s*(?:public|internal|protected|private|static|virtual|override|sealed|new|readonly|\s)+[A-Za-z0-9_<>,\[\]\?\.:\s]+\s+([A-Za-z0-9_]+)\s*\{/;
9
13
 
10
14
  const nsStack = [];
11
15
  const typeStack = [];
@@ -29,7 +33,7 @@ export function parseFileSymbols(relPath, text) {
29
33
  startLine: i + 1,
30
34
  endLine: 0,
31
35
  startColumn: 1,
32
- endColumn: 1,
36
+ endColumn: 1
33
37
  });
34
38
  }
35
39
 
@@ -44,7 +48,7 @@ export function parseFileSymbols(relPath, text) {
44
48
  startLine: i + 1,
45
49
  endLine: i + 1,
46
50
  startColumn: 1,
47
- endColumn: 1,
51
+ endColumn: 1
48
52
  });
49
53
  }
50
54
 
@@ -59,7 +63,7 @@ export function parseFileSymbols(relPath, text) {
59
63
  startLine: i + 1,
60
64
  endLine: i + 1,
61
65
  startColumn: 1,
62
- endColumn: 1,
66
+ endColumn: 1
63
67
  });
64
68
  }
65
69
 
@@ -74,7 +78,10 @@ export function parseFileSymbols(relPath, text) {
74
78
  // set endLine for the last matching symbol
75
79
  for (let j = result.symbols.length - 1; j >= 0; j--) {
76
80
  const s = result.symbols[j];
77
- if (s.kind === closed.kind && s.name === closed.name && s.endLine === 0) { s.endLine = i + 1; break; }
81
+ if (s.kind === closed.kind && s.name === closed.name && s.endLine === 0) {
82
+ s.endLine = i + 1;
83
+ break;
84
+ }
78
85
  }
79
86
  }
80
87
  }
@@ -85,4 +92,3 @@ export function parseFileSymbols(relPath, text) {
85
92
  }
86
93
  return result;
87
94
  }
88
-