@akiojin/unity-mcp-server 2.41.0 → 2.41.2
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.
- package/README.md +7 -0
- package/package.json +3 -8
- package/prebuilt/better-sqlite3/linux-x64-node22/better_sqlite3.node +0 -0
- package/prebuilt/better-sqlite3/manifest.json +9 -1
- package/scripts/ensure-better-sqlite3.mjs +119 -0
- package/src/core/sqliteFallback.js +9 -1
- package/src/handlers/script/CodeIndexStatusToolHandler.js +11 -0
package/README.md
CHANGED
|
@@ -357,6 +357,13 @@ npm install -g @akiojin/unity-mcp-server
|
|
|
357
357
|
|
|
358
358
|
Full source code and documentation: <https://github.com/akiojin/unity-mcp-server>
|
|
359
359
|
|
|
360
|
+
## Release Automation
|
|
361
|
+
|
|
362
|
+
- Releases are generated by release-please on `main`; run `scripts/create-release-branch.sh` to open the `chore(release): x.y.z` PR (auto-merge after checks).
|
|
363
|
+
- Required checks: Markdown, ESLint & Formatting / Commit Message Lint / Test & Coverage / Package.
|
|
364
|
+
- Tags trigger `publish.yml` to push npm, OpenUPM (via tag), and csharp-lsp artifacts; Unity package version is kept in sync via release-please extra-files.
|
|
365
|
+
- If OpenUPM lags, create a new release so the tag and Unity package version match.
|
|
366
|
+
|
|
360
367
|
## License
|
|
361
368
|
|
|
362
369
|
MIT License - see LICENSE file for details.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/unity-mcp-server",
|
|
3
|
-
"version": "2.41.
|
|
3
|
+
"version": "2.41.2",
|
|
4
4
|
"description": "MCP server and Unity Editor bridge — enables AI assistants to control Unity for AI-assisted workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/core/server.js",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"files": [
|
|
71
71
|
"src/",
|
|
72
72
|
"bin/",
|
|
73
|
+
"scripts/ensure-better-sqlite3.mjs",
|
|
73
74
|
"prebuilt/",
|
|
74
75
|
"README.md",
|
|
75
76
|
"LICENSE"
|
|
@@ -81,11 +82,6 @@
|
|
|
81
82
|
"devDependencies": {
|
|
82
83
|
"@commitlint/cli": "^18.6.1",
|
|
83
84
|
"@commitlint/config-conventional": "^18.6.3",
|
|
84
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
85
|
-
"@semantic-release/commit-analyzer": "^11.1.0",
|
|
86
|
-
"@semantic-release/exec": "^6.0.3",
|
|
87
|
-
"@semantic-release/git": "^10.0.1",
|
|
88
|
-
"@semantic-release/release-notes-generator": "^12.1.0",
|
|
89
85
|
"c8": "^10.1.3",
|
|
90
86
|
"eslint": "^8.57.1",
|
|
91
87
|
"eslint-config-standard": "^17.1.0",
|
|
@@ -95,7 +91,6 @@
|
|
|
95
91
|
"husky": "^9.1.7",
|
|
96
92
|
"markdownlint-cli": "^0.43.0",
|
|
97
93
|
"nodemon": "^3.1.7",
|
|
98
|
-
"prettier": "^3.4.2"
|
|
99
|
-
"semantic-release": "^22.0.12"
|
|
94
|
+
"prettier": "^3.4.2"
|
|
100
95
|
}
|
|
101
96
|
}
|
|
Binary file
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Ensure better-sqlite3 native binding exists. Prefers bundled prebuilt binaries, otherwise
|
|
3
|
+
// optionally attempts a native rebuild (opt-in to avoid first-time npx timeouts).
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { spawnSync } from 'child_process';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
|
|
9
|
+
const SCRIPT_PATH = fileURLToPath(import.meta.url);
|
|
10
|
+
const PKG_ROOT = path.resolve(path.dirname(SCRIPT_PATH), '..');
|
|
11
|
+
|
|
12
|
+
const DEFAULT_BINDING_PATH = process.env.UNITY_MCP_BINDING_PATH
|
|
13
|
+
? path.resolve(process.env.UNITY_MCP_BINDING_PATH)
|
|
14
|
+
: path.join(
|
|
15
|
+
PKG_ROOT,
|
|
16
|
+
'node_modules',
|
|
17
|
+
'better-sqlite3',
|
|
18
|
+
'build',
|
|
19
|
+
'Release',
|
|
20
|
+
'better_sqlite3.node'
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const DEFAULT_PREBUILT_ROOT = process.env.UNITY_MCP_PREBUILT_DIR
|
|
24
|
+
? path.resolve(process.env.UNITY_MCP_PREBUILT_DIR)
|
|
25
|
+
: path.join(PKG_ROOT, 'prebuilt', 'better-sqlite3');
|
|
26
|
+
|
|
27
|
+
export function resolvePlatformKey(
|
|
28
|
+
nodeVersion = process.versions.node,
|
|
29
|
+
platform = process.platform,
|
|
30
|
+
arch = process.arch
|
|
31
|
+
) {
|
|
32
|
+
const major = String(nodeVersion).split('.')[0];
|
|
33
|
+
return `${platform}-${arch}-node${major}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function copyPrebuiltBinding(prebuiltDir, bindingTarget, log) {
|
|
37
|
+
const platformKey = resolvePlatformKey();
|
|
38
|
+
const source = path.join(prebuiltDir, platformKey, 'better_sqlite3.node');
|
|
39
|
+
if (!fs.existsSync(source)) return false;
|
|
40
|
+
fs.mkdirSync(path.dirname(bindingTarget), { recursive: true });
|
|
41
|
+
fs.copyFileSync(source, bindingTarget);
|
|
42
|
+
if (log) log(`[postinstall] Installed better-sqlite3 prebuilt for ${platformKey}`);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function rebuildNative(bindingTarget, pkgRoot, log) {
|
|
47
|
+
log(
|
|
48
|
+
'[postinstall] No prebuilt available. Attempting native rebuild (npm rebuild better-sqlite3 --build-from-source)'
|
|
49
|
+
);
|
|
50
|
+
const result = spawnSync('npm', ['rebuild', 'better-sqlite3', '--build-from-source'], {
|
|
51
|
+
stdio: 'inherit',
|
|
52
|
+
shell: false,
|
|
53
|
+
cwd: pkgRoot
|
|
54
|
+
});
|
|
55
|
+
if (result.status !== 0) {
|
|
56
|
+
throw new Error(`better-sqlite3 rebuild failed with code ${result.status ?? 'null'}`);
|
|
57
|
+
}
|
|
58
|
+
if (!fs.existsSync(bindingTarget)) {
|
|
59
|
+
throw new Error('better-sqlite3 rebuild completed but binding was still not found');
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function ensureBetterSqlite3(options = {}) {
|
|
65
|
+
const {
|
|
66
|
+
bindingPath = DEFAULT_BINDING_PATH,
|
|
67
|
+
prebuiltRoot = DEFAULT_PREBUILT_ROOT,
|
|
68
|
+
pkgRoot = PKG_ROOT,
|
|
69
|
+
skipNative = process.env.UNITY_MCP_SKIP_NATIVE_BUILD !== '0',
|
|
70
|
+
forceNative = process.env.UNITY_MCP_FORCE_NATIVE === '1',
|
|
71
|
+
skipLegacyFlag = Boolean(process.env.SKIP_SQLITE_REBUILD),
|
|
72
|
+
log = console.log,
|
|
73
|
+
warn = console.warn
|
|
74
|
+
} = options;
|
|
75
|
+
|
|
76
|
+
if (skipLegacyFlag && !forceNative) {
|
|
77
|
+
warn('[postinstall] SKIP_SQLITE_REBUILD set, skipping better-sqlite3 check');
|
|
78
|
+
return { status: 'skipped' };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!forceNative && copyPrebuiltBinding(prebuiltRoot, bindingPath, log)) {
|
|
82
|
+
return { status: 'copied' };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (skipNative && !forceNative) {
|
|
86
|
+
warn(
|
|
87
|
+
'[postinstall] UNITY_MCP_SKIP_NATIVE_BUILD=1 -> skipping native rebuild; sql.js fallback will be used'
|
|
88
|
+
);
|
|
89
|
+
return { status: 'skipped' };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (forceNative) {
|
|
93
|
+
log('[postinstall] UNITY_MCP_FORCE_NATIVE=1 -> forcing better-sqlite3 rebuild');
|
|
94
|
+
} else if (fs.existsSync(bindingPath)) {
|
|
95
|
+
// Binding already exists and native rebuild not forced.
|
|
96
|
+
return { status: 'existing' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
rebuildNative(bindingPath, pkgRoot, log);
|
|
100
|
+
return { status: 'rebuilt' };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isCliExecution() {
|
|
104
|
+
const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : '';
|
|
105
|
+
return invokedPath === SCRIPT_PATH;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function main() {
|
|
109
|
+
try {
|
|
110
|
+
await ensureBetterSqlite3();
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.warn(`[postinstall] Warning: ${err.message}`);
|
|
113
|
+
// Do not hard fail install; runtime may still use sql.js fallback in codeIndex
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (isCliExecution()) {
|
|
118
|
+
main();
|
|
119
|
+
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { createRequire } from 'module';
|
|
3
5
|
import initSqlJs from 'sql.js';
|
|
4
6
|
|
|
5
7
|
// Create a lightweight better-sqlite3 compatible surface using sql.js (WASM)
|
|
6
8
|
export async function createSqliteFallback(dbPath) {
|
|
7
|
-
const
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const pkgRoot = path.resolve(moduleDir, '..', '..');
|
|
12
|
+
const wasmPath = require.resolve('sql.js/dist/sql-wasm.wasm', {
|
|
13
|
+
// Resolve from package-local node_modules first, then workspace root
|
|
14
|
+
paths: [path.join(pkgRoot, 'node_modules'), path.join(pkgRoot, '..', 'node_modules')]
|
|
15
|
+
});
|
|
8
16
|
const SQL = await initSqlJs({ locateFile: () => wasmPath });
|
|
9
17
|
|
|
10
18
|
const loadDb = () => {
|
|
@@ -32,6 +32,17 @@ export class CodeIndexStatusToolHandler extends BaseToolHandler {
|
|
|
32
32
|
|
|
33
33
|
// Check whether the persistent index already exists or is being built in the background.
|
|
34
34
|
const ready = await this.codeIndex.isReady();
|
|
35
|
+
if (this.codeIndex.disabled) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: 'code_index_unavailable',
|
|
39
|
+
message:
|
|
40
|
+
this.codeIndex.disableReason ||
|
|
41
|
+
'Code index is disabled because the SQLite driver could not be loaded. The server will continue without the symbol index.',
|
|
42
|
+
remediation:
|
|
43
|
+
'Install native build tools (python3, make, g++) in this environment and run "npm rebuild better-sqlite3 --build-from-source", then restart the server.'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
35
46
|
const buildInProgress = latestBuildJob?.status === 'running';
|
|
36
47
|
if (!ready && !buildInProgress) {
|
|
37
48
|
return {
|