siwatsystem-mcp-dxt/build.ts
Siwat Sirichai a433ac337d
Some checks failed
Build and Package DXT / build (push) Failing after 47s
feat: initialize project with package.json and tsconfig.json
- Added package.json for project dependencies and scripts
- Included TypeScript configuration in tsconfig.json
2025-07-06 01:31:52 +07:00

136 lines
No EOL
4 KiB
JavaScript

#!/usr/bin/env node
import { execSync } from 'child_process';
import { writeFileSync, mkdirSync, existsSync, readFileSync, copyFileSync, readdirSync, statSync, createWriteStream, rmSync } from 'fs';
import { join } from 'path';
import archiver from 'archiver';
const DIST_DIR = 'dist';
const STAGING_DIR = join(DIST_DIR, 'siwat_system_mcp');
const OUTPUT_FILE = join(STAGING_DIR, 'index.js');
const DXT_FILE = join(DIST_DIR, 'siwat_system_mcp.dxt');
// Function to create .dxt file using archiver (cross-platform)
async function createDxtFile(): Promise<void> {
return new Promise((resolve, reject) => {
console.log('📦 Creating .dxt file...');
const output = createWriteStream(DXT_FILE);
const archive = archiver('zip', {
zlib: { level: 9 } // Maximum compression
});
output.on('close', () => {
console.log(`📦 Created ${DXT_FILE} (${archive.pointer()} bytes)`);
resolve();
});
archive.on('error', (err) => {
reject(err);
});
archive.pipe(output);
// Add all files from staging directory to the archive
archive.directory(STAGING_DIR, false);
archive.finalize();
});
}
// Function to copy assets to staging directory
function copyAssets() {
const assetsDir = 'assets';
if (!existsSync(assetsDir)) {
console.log('📂 No assets directory found, skipping asset copy');
return;
}
console.log('📁 Copying assets to staging directory...');
// Copy all files from assets to staging root (for .dxt extension structure)
try {
const files = readdirSync(assetsDir);
files.forEach(file => {
const srcPath = join(assetsDir, file);
const destPath = join(STAGING_DIR, file);
if (statSync(srcPath).isFile()) {
copyFileSync(srcPath, destPath);
console.log(`📄 Copied ${file} to ${STAGING_DIR}/`);
}
});
} catch (error: any) {
console.warn('⚠️ Warning: Could not copy some assets:', error.message);
}
}
async function build() {
try {
console.log('🚀 Starting build process...');
// Clean dist directory if it exists
if (existsSync(DIST_DIR)) {
console.log('🧹 Cleaning dist directory...');
rmSync(DIST_DIR, { recursive: true, force: true });
}
// Ensure dist and staging directories exist
mkdirSync(DIST_DIR, { recursive: true });
console.log('📁 Created dist directory');
mkdirSync(STAGING_DIR, { recursive: true });
console.log('📁 Created staging directory');
// Check if mcp-remote is available
try {
execSync('npm list mcp-remote', { stdio: 'ignore' });
} catch {
console.log('📦 Installing mcp-remote...');
execSync('npm install mcp-remote', { stdio: 'inherit' });
}
// Install ncc if not available
try {
execSync('npx ncc --version', { stdio: 'ignore' });
} catch {
console.log('📦 Installing @vercel/ncc...');
execSync('npm install @vercel/ncc', { stdio: 'inherit' });
}
// Find mcp-remote entry point
const mcpRemoteEntry = 'node_modules/mcp-remote/dist/proxy.js';
if (!existsSync(mcpRemoteEntry)) {
console.log('📦 Installing mcp-remote...');
execSync('npm install mcp-remote', { stdio: 'inherit' });
}
// Bundle with ncc
console.log('🔨 Bundling with @vercel/ncc...');
const nccCommand = `npx ncc build ${mcpRemoteEntry} -o ${STAGING_DIR} --minify --no-source-map-register`;
execSync(nccCommand, { stdio: 'inherit' });
// Copy assets to staging directory (manifest.json, icon.png, etc.)
copyAssets();
// Create .dxt file by zipping the staging directory
await createDxtFile();
console.log('✅ Build completed successfully!');
console.log(`📦 Standalone server created at: ${OUTPUT_FILE}`);
console.log(`🎯 Extension packaged as: ${DXT_FILE}`);
console.log('🎯 Run with: node dist/siwat_system_mcp/index.js');
} catch (error) {
console.error('❌ Build failed:', error);
process.exit(1);
}
}
// Main execution
if (require.main === module) {
build();
}
export { build };