Skip to main content
Glama
build-npm.jsโ€ข4.16 kB
#!/usr/bin/env node import fs from 'fs-extra'; import path from 'path'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); class NPMPackageBuilder { constructor() { this.rootDir = path.dirname(__dirname); this.srcDir = path.join(this.rootDir, 'src'); this.outputDir = path.join(this.rootDir, 'npm-package'); } async build() { console.log('๐Ÿ—๏ธ Building NPM package...'); try { await this.cleanOutput(); await this.createDirectories(); await this.copySourceFiles(); await this.copyBinaryFile(); await this.copyPackageJson(); await this.makeExecutable(); console.log('โœ… NPM package built successfully!'); console.log(`๐Ÿ“ฆ Package location: ${this.outputDir}`); console.log('๐Ÿ’ก To install globally: npm install -g ./npm-package'); console.log('๐Ÿ’ก To publish: cd npm-package && npm publish'); } catch (error) { console.error('โŒ Build failed:', error.message); process.exit(1); } } async cleanOutput() { console.log('๐Ÿงน Cleaning output directory...'); await fs.remove(this.outputDir); } async createDirectories() { console.log('๐Ÿ“ Creating directories...'); await fs.ensureDir(path.join(this.outputDir, 'bin')); await fs.ensureDir(path.join(this.outputDir, 'server')); await fs.ensureDir(path.join(this.outputDir, 'renderer')); await fs.ensureDir(path.join(this.outputDir, 'assets')); } async copySourceFiles() { console.log('๐Ÿ“‹ Copying source files...'); const filesToCopy = [ { src: 'main.mjs', dest: 'main.mjs' }, { src: 'preload.mjs', dest: 'preload.mjs' }, { src: 'README.md', dest: 'README.md' } ]; const dirsToCopy = [ { src: 'renderer', dest: 'renderer' }, { src: 'server', dest: 'server' }, { src: 'assets', dest: 'assets' } ]; // Copy individual files for (const file of filesToCopy) { const srcPath = path.join(this.rootDir, file.src); const destPath = path.join(this.outputDir, file.dest); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, destPath); console.log(` โœ“ ${file.src}`); } else { console.warn(` โš ๏ธ ${file.src} not found, skipping`); } } // Copy directories for (const dir of dirsToCopy) { const srcPath = path.join(this.rootDir, dir.src); const destPath = path.join(this.outputDir, dir.dest); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, destPath); console.log(` โœ“ ${dir.src}/`); } else { console.warn(` โš ๏ธ ${dir.src}/ not found, skipping`); } } } async copyBinaryFile() { console.log('๐Ÿ”ง Copying binary file...'); const srcBin = path.join(this.srcDir, 'bin', 'feedback-loop-mcp.js'); const destBin = path.join(this.outputDir, 'bin', 'feedback-loop-mcp'); if (await fs.pathExists(srcBin)) { await fs.copy(srcBin, destBin); console.log(' โœ“ bin/feedback-loop-mcp'); } else { throw new Error('Binary source file not found: ' + srcBin); } } async copyPackageJson() { console.log('๐Ÿ“„ Copying package.json...'); const srcPackage = path.join(this.srcDir, 'package.json'); const destPackage = path.join(this.outputDir, 'package.json'); if (await fs.pathExists(srcPackage)) { await fs.copy(srcPackage, destPackage); console.log(' โœ“ package.json'); } else { throw new Error('Package.json source file not found: ' + srcPackage); } } async makeExecutable() { console.log('๐Ÿ” Making binary executable...'); const binPath = path.join(this.outputDir, 'bin', 'feedback-loop-mcp'); await fs.chmod(binPath, '755'); console.log(' โœ“ Binary is now executable'); } } // Run the builder if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { const builder = new NPMPackageBuilder(); builder.build(); } export default NPMPackageBuilder;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tuandinh-org/feedback-loop-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server