Compare commits

...

1 Commits

Author SHA1 Message Date
Ralph Khreish
83c0eec982 feat: experimental, bundle our commands into bins in order to be able to remove --package 2025-06-20 19:45:57 +03:00
4 changed files with 1762 additions and 98 deletions

1671
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
{ {
"name": "task-master-ai", "name": "task-master-ai",
"version": "0.17.1", "version": "0.17.1-test",
"description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.", "description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
"bin": { "bin": {
"task-master": "bin/task-master.js", "task-master": "dist/task-master.cjs",
"task-master-mcp": "mcp-server/server.js", "task-master-mcp": "dist/task-master-mcp.cjs",
"task-master-ai": "mcp-server/server.js" "task-master-ai": "dist/task-master-mcp.cjs"
}, },
"scripts": { "scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest", "test": "node --experimental-vm-modules node_modules/.bin/jest",
@@ -22,7 +22,13 @@
"inspector": "npx @modelcontextprotocol/inspector node mcp-server/server.js", "inspector": "npx @modelcontextprotocol/inspector node mcp-server/server.js",
"mcp-server": "node mcp-server/server.js", "mcp-server": "node mcp-server/server.js",
"format-check": "biome format .", "format-check": "biome format .",
"format": "biome format . --write" "format": "biome format . --write",
"prebuild": "npm test",
"build": "vite build && npm run postbuild",
"postbuild": "node scripts/add-shebang.js",
"build:bundle": "npm run build",
"build:watch": "vite build --watch",
"test:build": "echo 'Testing bundled binaries:' && echo '🔧 CLI (task-master):' && node dist/task-master.cjs --version && echo '🔌 MCP (task-master-ai):' && node dist/task-master-mcp.cjs --help | head -5 && echo '✅ Both bundles work!'"
}, },
"keywords": [ "keywords": [
"claude", "claude",
@@ -91,14 +97,11 @@
"url": "https://github.com/eyaltoledano/claude-task-master/issues" "url": "https://github.com/eyaltoledano/claude-task-master/issues"
}, },
"files": [ "files": [
"scripts/**", "dist/**",
"assets/**",
".cursor/**",
"README-task-master.md",
"index.js",
"bin/**",
"mcp-server/**", "mcp-server/**",
"src/**" "README-task-master.md",
".cursor/**",
"assets/**"
], ],
"overrides": { "overrides": {
"node-fetch": "^2.6.12", "node-fetch": "^2.6.12",
@@ -108,15 +111,19 @@
"@biomejs/biome": "^1.9.4", "@biomejs/biome": "^1.9.4",
"@changesets/changelog-github": "^0.5.1", "@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.28.1", "@changesets/cli": "^2.28.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"execa": "^8.0.1", "execa": "^8.0.1",
"ink": "^5.0.1", "ink": "^5.0.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-environment-node": "^29.7.0", "jest-environment-node": "^29.7.0",
"mock-fs": "^5.5.0", "mock-fs": "^5.5.0",
"pkg": "^5.8.1",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"react": "^18.3.1", "react": "^18.3.1",
"supertest": "^7.1.0", "supertest": "^7.1.0",
"tsx": "^4.16.2" "tsx": "^4.16.2",
"vite": "^6.3.5"
} }
} }

82
scripts/add-shebang.js Normal file
View File

@@ -0,0 +1,82 @@
#!/usr/bin/env node
import {
readFileSync,
writeFileSync,
chmodSync,
copyFileSync,
mkdirSync,
existsSync
} from 'fs';
import { join, dirname } from 'path';
const bundlePaths = [
join(process.cwd(), 'dist/task-master.cjs'), // CLI tool
join(process.cwd(), 'dist/task-master-mcp.cjs') // MCP server
];
try {
// Copy necessary asset files to dist
const assetsToCopy = [
{
src: 'scripts/modules/supported-models.json',
dest: 'dist/supported-models.json'
},
{ src: 'README-task-master.md', dest: 'dist/README-task-master.md' }
];
console.log('📁 Copying assets...');
for (const asset of assetsToCopy) {
const srcPath = join(process.cwd(), asset.src);
const destPath = join(process.cwd(), asset.dest);
if (existsSync(srcPath)) {
// Ensure destination directory exists
const destDir = dirname(destPath);
if (!existsSync(destDir)) {
mkdirSync(destDir, { recursive: true });
}
copyFileSync(srcPath, destPath);
console.log(` ✅ Copied ${asset.src}${asset.dest}`);
} else {
console.log(` ⚠️ Source not found: ${asset.src}`);
}
}
// Process each bundle file
for (const bundlePath of bundlePaths) {
const fileName = bundlePath.split('/').pop();
if (!existsSync(bundlePath)) {
console.log(`⚠️ Bundle not found: ${fileName}`);
continue;
}
// Read the existing bundle
const bundleContent = readFileSync(bundlePath, 'utf8');
// Add shebang if it doesn't already exist
if (!bundleContent.startsWith('#!/usr/bin/env node')) {
const contentWithShebang = '#!/usr/bin/env node\n' + bundleContent;
writeFileSync(bundlePath, contentWithShebang);
console.log(`✅ Added shebang to ${fileName}`);
} else {
console.log(`✅ Shebang already exists in ${fileName}`);
}
// Make it executable
chmodSync(bundlePath, 0o755);
console.log(`✅ Made ${fileName} executable`);
}
console.log('📦 Both bundles ready:');
console.log(' 🔧 CLI tool: dist/task-master.cjs');
console.log(' 🔌 MCP server: dist/task-master-mcp.cjs');
console.log('🧪 Test with:');
console.log(' node dist/task-master.cjs --version');
console.log(' node dist/task-master-mcp.cjs --help');
} catch (error) {
console.error('❌ Post-build failed:', error.message);
process.exit(1);
}

72
vite.config.js Normal file
View File

@@ -0,0 +1,72 @@
import { defineConfig } from 'vite';
import { resolve } from 'path';
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default defineConfig({
build: {
ssr: true, // Use SSR mode for Node.js
rollupOptions: {
// Multiple entry points for different applications
input: {
'task-master': resolve(__dirname, 'bin/task-master.js'), // CLI tool
'task-master-mcp': resolve(__dirname, 'mcp-server/server.js') // MCP server
},
// Bundle everything except Node.js built-ins
external: [
// Node.js built-in modules
'fs',
'fs/promises',
'path',
'os',
'crypto',
'http',
'https',
'net',
'tls',
'child_process',
'util',
'events',
'stream',
'url',
'querystring',
'buffer',
'module',
'worker_threads',
'readline',
'process',
'assert',
'zlib',
'dns',
'perf_hooks',
// Optional dependencies that might not be available
'@anthropic-ai/claude-code'
],
output: {
// Generate separate files for each entry
dir: 'dist',
format: 'cjs', // CommonJS for Node.js compatibility
entryFileNames: '[name].cjs',
chunkFileNames: 'chunks/[name]-[hash].cjs',
assetFileNames: 'assets/[name].[ext]'
},
plugins: [
nodeResolve({
preferBuiltins: true,
exportConditions: ['node']
})
]
},
target: 'node18',
outDir: 'dist',
minify: false, // Keep readable for debugging
sourcemap: false
},
define: {
// Define any environment variables if needed
'process.env.NODE_ENV': '"production"'
},
ssr: {
// Don't externalize any dependencies - bundle them all
noExternal: true
}
});