feat: add NPX CLI and OpenClaw build pipeline, optimize npm package size
Adds esbuild steps for npx-cli (57KB, Node.js ESM) and openclaw plugin (12KB). Creates .npmignore to exclude node_modules and Bun binary from npm package, reducing pack size from 146MB to 2MB. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+49
@@ -0,0 +1,49 @@
|
|||||||
|
# Source code (dist/ and plugin/ are the shipped artifacts)
|
||||||
|
src/
|
||||||
|
scripts/
|
||||||
|
tests/
|
||||||
|
docs/
|
||||||
|
datasets/
|
||||||
|
private/
|
||||||
|
installer/
|
||||||
|
antipattern-czar/
|
||||||
|
|
||||||
|
# Heavy binaries installed at runtime via smart-install.js
|
||||||
|
plugin/node_modules/
|
||||||
|
plugin/scripts/claude-mem
|
||||||
|
plugin/bun.lock
|
||||||
|
plugin/data/
|
||||||
|
plugin/data.backup/
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
*.ts
|
||||||
|
!*.d.ts
|
||||||
|
tsconfig*.json
|
||||||
|
.eslintrc*
|
||||||
|
.prettierrc*
|
||||||
|
.editorconfig
|
||||||
|
jest.config*
|
||||||
|
vitest.config*
|
||||||
|
|
||||||
|
# Git and CI
|
||||||
|
.git/
|
||||||
|
.github/
|
||||||
|
.gitignore
|
||||||
|
.claude/
|
||||||
|
.cursor/
|
||||||
|
.mcp.json
|
||||||
|
.plan/
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
Auto Run Docs/
|
||||||
|
~*/
|
||||||
|
http*/
|
||||||
|
https*/
|
||||||
|
.idea/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
||||||
+11
-1
@@ -42,7 +42,17 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"plugin"
|
"plugin/.claude-plugin",
|
||||||
|
"plugin/CLAUDE.md",
|
||||||
|
"plugin/package.json",
|
||||||
|
"plugin/hooks",
|
||||||
|
"plugin/modes",
|
||||||
|
"plugin/scripts/*.js",
|
||||||
|
"plugin/scripts/*.cjs",
|
||||||
|
"plugin/scripts/CLAUDE.md",
|
||||||
|
"plugin/skills",
|
||||||
|
"plugin/ui",
|
||||||
|
"openclaw"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0",
|
"node": ">=18.0.0",
|
||||||
|
|||||||
+63
-1
@@ -182,6 +182,62 @@ async function buildHooks() {
|
|||||||
const contextGenStats = fs.statSync(`${hooksDir}/${CONTEXT_GENERATOR.name}.cjs`);
|
const contextGenStats = fs.statSync(`${hooksDir}/${CONTEXT_GENERATOR.name}.cjs`);
|
||||||
console.log(`✓ context-generator built (${(contextGenStats.size / 1024).toFixed(2)} KB)`);
|
console.log(`✓ context-generator built (${(contextGenStats.size / 1024).toFixed(2)} KB)`);
|
||||||
|
|
||||||
|
// Build NPX CLI (pure Node.js — no Bun dependency)
|
||||||
|
console.log(`\n🔧 Building NPX CLI...`);
|
||||||
|
const npxCliOutDir = 'dist/npx-cli';
|
||||||
|
if (!fs.existsSync(npxCliOutDir)) {
|
||||||
|
fs.mkdirSync(npxCliOutDir, { recursive: true });
|
||||||
|
}
|
||||||
|
await build({
|
||||||
|
entryPoints: ['src/npx-cli/index.ts'],
|
||||||
|
bundle: true,
|
||||||
|
platform: 'node',
|
||||||
|
target: 'node18',
|
||||||
|
format: 'esm',
|
||||||
|
outfile: `${npxCliOutDir}/index.js`,
|
||||||
|
minify: true,
|
||||||
|
logLevel: 'error',
|
||||||
|
external: [
|
||||||
|
'fs', 'fs/promises', 'path', 'os', 'child_process', 'url',
|
||||||
|
'crypto', 'http', 'https', 'net', 'stream', 'util', 'events',
|
||||||
|
'buffer', 'querystring', 'readline', 'tty', 'assert',
|
||||||
|
],
|
||||||
|
define: {
|
||||||
|
'__DEFAULT_PACKAGE_VERSION__': `"${version}"`
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make NPX CLI executable
|
||||||
|
fs.chmodSync(`${npxCliOutDir}/index.js`, 0o755);
|
||||||
|
const npxCliStats = fs.statSync(`${npxCliOutDir}/index.js`);
|
||||||
|
console.log(`✓ npx-cli built (${(npxCliStats.size / 1024).toFixed(2)} KB)`);
|
||||||
|
|
||||||
|
// Build OpenClaw plugin (self-contained, only Node builtins external)
|
||||||
|
if (fs.existsSync('openclaw/src/index.ts')) {
|
||||||
|
console.log(`\n🔧 Building OpenClaw plugin...`);
|
||||||
|
const openclawOutDir = 'openclaw/dist';
|
||||||
|
if (!fs.existsSync(openclawOutDir)) {
|
||||||
|
fs.mkdirSync(openclawOutDir, { recursive: true });
|
||||||
|
}
|
||||||
|
await build({
|
||||||
|
entryPoints: ['openclaw/src/index.ts'],
|
||||||
|
bundle: true,
|
||||||
|
platform: 'node',
|
||||||
|
target: 'node18',
|
||||||
|
format: 'esm',
|
||||||
|
outfile: `${openclawOutDir}/index.js`,
|
||||||
|
minify: true,
|
||||||
|
logLevel: 'error',
|
||||||
|
external: [
|
||||||
|
'fs', 'fs/promises', 'path', 'os', 'child_process', 'url',
|
||||||
|
'crypto', 'http', 'https', 'net', 'stream', 'util', 'events',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const openclawStats = fs.statSync(`${openclawOutDir}/index.js`);
|
||||||
|
console.log(`✓ openclaw plugin built (${(openclawStats.size / 1024).toFixed(2)} KB)`);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify critical distribution files exist (skills are source files, not build outputs)
|
// Verify critical distribution files exist (skills are source files, not build outputs)
|
||||||
console.log('\n📋 Verifying distribution files...');
|
console.log('\n📋 Verifying distribution files...');
|
||||||
const requiredDistributionFiles = [
|
const requiredDistributionFiles = [
|
||||||
@@ -197,11 +253,17 @@ async function buildHooks() {
|
|||||||
}
|
}
|
||||||
console.log('✓ All required distribution files present');
|
console.log('✓ All required distribution files present');
|
||||||
|
|
||||||
console.log('\n✅ Worker service, MCP server, and context generator built successfully!');
|
console.log('\n✅ All build targets compiled successfully!');
|
||||||
console.log(` Output: ${hooksDir}/`);
|
console.log(` Output: ${hooksDir}/`);
|
||||||
console.log(` - Worker: worker-service.cjs`);
|
console.log(` - Worker: worker-service.cjs`);
|
||||||
console.log(` - MCP Server: mcp-server.cjs`);
|
console.log(` - MCP Server: mcp-server.cjs`);
|
||||||
console.log(` - Context Generator: context-generator.cjs`);
|
console.log(` - Context Generator: context-generator.cjs`);
|
||||||
|
console.log(` Output: ${npxCliOutDir}/`);
|
||||||
|
console.log(` - NPX CLI: index.js`);
|
||||||
|
if (fs.existsSync('openclaw/dist/index.js')) {
|
||||||
|
console.log(` Output: openclaw/dist/`);
|
||||||
|
console.log(` - OpenClaw Plugin: index.js`);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('\n❌ Build failed:', error.message);
|
console.error('\n❌ Build failed:', error.message);
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ export function claudeMemDataDirectory(): string {
|
|||||||
/**
|
/**
|
||||||
* Resolve the root of the installed npm package.
|
* Resolve the root of the installed npm package.
|
||||||
*
|
*
|
||||||
* The CLI entry point lives at `<pkg>/dist/cli/index.js`. Walking up
|
* After bundling, the CLI entry point lives at `<pkg>/dist/npx-cli/index.js`.
|
||||||
* from `import.meta.url` (or `__dirname` equivalent) we reach the
|
* Walking up 2 levels from `import.meta.url` reaches the package root
|
||||||
* package root where `plugin/` can be found.
|
* where `plugin/` and `package.json` can be found.
|
||||||
*/
|
*/
|
||||||
export function npmPackageRootDirectory(): string {
|
export function npmPackageRootDirectory(): string {
|
||||||
const currentFilePath = fileURLToPath(import.meta.url);
|
const currentFilePath = fileURLToPath(import.meta.url);
|
||||||
// <pkg>/dist/npx-cli/utils/paths.js -> up 3 levels -> <pkg>
|
// <pkg>/dist/npx-cli/index.js -> up 2 levels -> <pkg>
|
||||||
return join(dirname(currentFilePath), '..', '..', '..');
|
return join(dirname(currentFilePath), '..', '..');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user