mirror of
https://github.com/hanzoai/extension.git
synced 2026-10-31 21:57:06 +00:00
server.js was mcp's dist/cli.js, which leaves the MCP SDK, commander, glob and zod to node_modules; the .dxt and the npm package ship none, and the CLI also read its version from a ../package.json that sits beside neither. dxt's build now bundles mcp's src/cli.ts with every dependency inlined, as CommonJS because a .dxt has no package.json to declare ESM, and the version is imported so the bundler inlines it. The native optionals stay external: @lancedb/lancedb and @xenova/transformers back the legacy vector tools and jsautogui backs --enable-autogui, none of them on the default surface, and each tool answers an error naming the missing package. getSystemPrompt imported tools/index.js dynamically though cli.ts already imports it. That made esbuild wrap the module graph, zod included, in lazy init, and the SDK read zod before it ran: the bundle died at load with "Class2 is not a constructor". It is a static import. The build writes dist/: server.js, the manifest stamped with package.json's version, the icon, and hanzo-ai.dxt zipped with yazl, since the runners have no zip. The manifest failed the schema Claude Desktop installs by (mcpb validate, and the older dxt validate): `compatibility.runtime` is `runtimes`, and `user_config` has no `env` key. The server reads none of those variables anyway, and nothing implements anonymous mode, allowed paths or a write switch, so those settings go; disabledTools reaches the --disable-tools flag the server has. The tool list names `ui`, which it serves, not `computer`, which it does not. Claude-Session: https://claude.ai/code/session_01Dc8DXc3fEQCRHUa6XWK4Ku
56 lines
2.0 KiB
JavaScript
56 lines
2.0 KiB
JavaScript
// Builds the Claude Desktop extension into dist/: server.js, mcp's CLI with
|
|
// every dependency inlined (the extension ships no node_modules); the
|
|
// manifest, stamped with this package's version; the icon; and hanzo-ai.dxt,
|
|
// the zip of those three that Claude Desktop installs.
|
|
const esbuild = require('esbuild');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const yazl = require('yazl');
|
|
|
|
const pkg = require('../package.json');
|
|
const root = path.join(__dirname, '..');
|
|
const out = (...p) => path.join(root, 'dist', ...p);
|
|
|
|
// Left as runtime import()s, never bundled: native packages that only tools
|
|
// off the default surface load, each of which answers an error naming the
|
|
// package when it is absent. @lancedb/lancedb and @xenova/transformers back
|
|
// the legacy vector tools; jsautogui backs --enable-autogui.
|
|
const optional = ['@lancedb/lancedb', '@xenova/transformers', 'jsautogui'];
|
|
|
|
async function build() {
|
|
fs.rmSync(out(), { recursive: true, force: true });
|
|
|
|
// CommonJS, because a .dxt has no package.json to declare a module type.
|
|
await esbuild.build({
|
|
entryPoints: [path.join(root, '..', 'mcp', 'src', 'cli.ts')],
|
|
outfile: out('server.js'),
|
|
bundle: true,
|
|
platform: 'node',
|
|
format: 'cjs',
|
|
target: 'node18',
|
|
minify: true,
|
|
external: optional,
|
|
logLevel: 'warning',
|
|
});
|
|
|
|
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'manifest.json'), 'utf8'));
|
|
manifest.version = pkg.version;
|
|
fs.writeFileSync(out('manifest.json'), JSON.stringify(manifest, null, 2) + '\n');
|
|
fs.copyFileSync(path.join(root, 'icon.png'), out('icon.png'));
|
|
|
|
const zip = new yazl.ZipFile();
|
|
for (const name of ['manifest.json', 'server.js', 'icon.png']) zip.addFile(out(name), name);
|
|
zip.end();
|
|
await new Promise((resolve, reject) => {
|
|
zip.outputStream
|
|
.pipe(fs.createWriteStream(out(`${manifest.name}.dxt`)))
|
|
.on('close', resolve)
|
|
.on('error', reject);
|
|
});
|
|
}
|
|
|
|
build().catch((err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|