chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Prepare offline wheels for windows-mcp under resources/windows-mcp/wheels.
|
||||
*
|
||||
* Runtime installation will happen on end-user machine to avoid non-relocatable
|
||||
* uv tool launcher issues when app is installed in a different path.
|
||||
*
|
||||
* Note: Bundled uv no longer provides `uv pip download`; we use
|
||||
* `uv run ... python -m pip download` with a pinned Python (3.13+) so wheel tags
|
||||
* match package `Requires-Python` and typical `uv tool install` on Windows.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { execFileSync } = require('child_process');
|
||||
const { getProjectRoot, resolveFromProject } = require('../utils/project-paths');
|
||||
|
||||
const projectRoot = getProjectRoot();
|
||||
const resDir = path.join(projectRoot, 'resources', 'windows-mcp');
|
||||
const wheelsDir = path.join(resDir, 'wheels');
|
||||
const manifestPath = path.join(resDir, 'manifest.json');
|
||||
|
||||
const PACKAGE_NAME = 'windows-mcp';
|
||||
/** Interpreter for pip download (windows-mcp currently requires Python >= 3.13). 若修改须同步 windowsMcp.ts 的 WINDOWS_MCP_UV_PYTHON。 */
|
||||
const PIP_DOWNLOAD_PYTHON = '3.13';
|
||||
|
||||
function getUvBinPath() {
|
||||
const uvBinName = process.platform === 'win32' ? 'uv.exe' : 'uv';
|
||||
return resolveFromProject('resources', 'uv', 'bin', uvBinName);
|
||||
}
|
||||
|
||||
function runPipDownload(uvBin, destDir, packageName, env) {
|
||||
execFileSync(
|
||||
uvBin,
|
||||
[
|
||||
'run',
|
||||
'--no-project',
|
||||
'--isolated',
|
||||
'--python',
|
||||
PIP_DOWNLOAD_PYTHON,
|
||||
'-w',
|
||||
'pip',
|
||||
'python',
|
||||
'-m',
|
||||
'pip',
|
||||
'download',
|
||||
'--dest',
|
||||
destDir,
|
||||
'--only-binary',
|
||||
':all:',
|
||||
packageName,
|
||||
],
|
||||
{ stdio: 'inherit', env },
|
||||
);
|
||||
}
|
||||
|
||||
function resolvePinnedVersion(files) {
|
||||
const wheel = files.find((name) => /^windows_mcp-([^-]+)-.*\.whl$/i.test(name));
|
||||
if (!wheel) {
|
||||
return null;
|
||||
}
|
||||
const match = wheel.match(/^windows_mcp-([^-]+)-.*\.whl$/i);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (process.platform !== 'win32') {
|
||||
console.log('[prepare-windows-mcp] Skipped: not Windows platform');
|
||||
return;
|
||||
}
|
||||
|
||||
const uvBin = getUvBinPath();
|
||||
if (!fs.existsSync(uvBin)) {
|
||||
console.error('[prepare-windows-mcp] uv not found at:', uvBin);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('[prepare-windows-mcp] Using uv:', uvBin);
|
||||
|
||||
if (fs.existsSync(resDir)) {
|
||||
console.log('[prepare-windows-mcp] Removing old resources/windows-mcp ...');
|
||||
fs.rmSync(resDir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(wheelsDir, { recursive: true });
|
||||
|
||||
console.log('[prepare-windows-mcp] Downloading wheels for offline installation ...');
|
||||
try {
|
||||
runPipDownload(uvBin, wheelsDir, PACKAGE_NAME, {
|
||||
...process.env,
|
||||
UV_PYTHON_DOWNLOADS: process.env.UV_PYTHON_DOWNLOADS ?? 'automatic',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[prepare-windows-mcp] Failed to download windows-mcp wheels:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = fs
|
||||
.readdirSync(wheelsDir)
|
||||
.filter((name) => {
|
||||
const full = path.join(wheelsDir, name);
|
||||
return fs.statSync(full).isFile() && name.toLowerCase().endsWith('.whl');
|
||||
})
|
||||
.sort();
|
||||
|
||||
if (files.length === 0) {
|
||||
console.error('[prepare-windows-mcp] No files downloaded into wheels directory');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const version = resolvePinnedVersion(files);
|
||||
if (!version) {
|
||||
console.error('[prepare-windows-mcp] Could not resolve pinned windows-mcp version from downloaded wheels');
|
||||
console.error('[prepare-windows-mcp] Downloaded files:', files.join(', '));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const manifest = {
|
||||
packageName: PACKAGE_NAME,
|
||||
version,
|
||||
resolvedSpec: `${PACKAGE_NAME}==${version}`,
|
||||
generatedAt: new Date().toISOString(),
|
||||
files,
|
||||
};
|
||||
|
||||
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
|
||||
|
||||
console.log(`[prepare-windows-mcp] ✓ Downloaded ${files.length} files`);
|
||||
console.log(`[prepare-windows-mcp] ✓ Pinned ${manifest.resolvedSpec}`);
|
||||
console.log(`[prepare-windows-mcp] ✓ Wrote manifest: ${manifestPath}`);
|
||||
console.log('[prepare-windows-mcp] ✓ resources/windows-mcp ready');
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user