@jjdenhertog/ai-driven-development
Version:
AI-driven development workflow with learning capabilities for Claude
120 lines • 7.11 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.webCommand = webCommand;
/* eslint-disable unicorn/prefer-module */
const fs_extra_1 = require("fs-extra");
const node_child_process_1 = require("node:child_process");
const node_path_1 = __importDefault(require("node:path"));
const checkGitInitialized_1 = require("../utils/git/checkGitInitialized");
const logger_1 = require("../utils/logger");
const getContainerName_1 = require("../utils/docker/getContainerName");
const isRunningInDocker_1 = require("../utils/docker/isRunningInDocker");
function webCommand(options) {
return __awaiter(this, void 0, void 0, function* () {
const { cwd, dev, proxyPort = 8888 } = options;
try {
// If a custom working directory is provided, change to it
const targetDir = cwd || process.cwd();
// Check if git is initialized in target directory
const gitInitialized = yield (0, checkGitInitialized_1.checkGitInitialized)();
if (!gitInitialized) {
throw new Error('This command must be run in a git repository');
}
// Check if .aidev-storage exists in target directory
if (!(0, fs_extra_1.existsSync)(node_path_1.default.join(targetDir, '.aidev-storage')))
throw new Error('AIdev has not been initialized. Run "aidev init" first.');
(0, logger_1.log)('Starting AIdev web interface...', 'info');
// Navigate to web directory - handle both development and production paths
let webDir;
const devWebDir = node_path_1.default.join(__dirname, '..', '..', '..', 'src', 'web');
const prodWebDir = node_path_1.default.join(__dirname, '..', '..', 'web');
// Check which path exists
if ((0, fs_extra_1.existsSync)(devWebDir)) {
webDir = devWebDir;
}
else if ((0, fs_extra_1.existsSync)(prodWebDir)) {
webDir = prodWebDir;
}
else {
throw new Error('Could not find web directory. The package may be corrupted.');
}
const host = (0, isRunningInDocker_1.isRunningInDocker)() ? 'host.docker.internal' : 'localhost';
const hostProxyPort = process.env.AIDEV_HOST_PROXY_PORT || proxyPort;
const hostProxy = process.env.AIDEV_HOST_PROXY || `http://${host}:${hostProxyPort}`;
let webProcess;
// Development mode - for npm link development
if (dev) {
(0, logger_1.log)('Starting AIdev web interface (development mode)...', 'info');
const port = process.env.AIDEV_WEB_PORT || '3001';
(0, logger_1.log)(`Starting development server on http://${host}:${port}`, 'info');
// Start the Next.js dev server
webProcess = (0, node_child_process_1.spawn)('npm', ['run', 'dev'], {
cwd: webDir,
stdio: 'inherit',
shell: true,
env: Object.assign(Object.assign({}, process.env), { PROJECT_ROOT: targetDir, HOSTNAME: "localhost", PORT: port, AIDEV_WEB_PORT: port, AIDEV_HOST_PROXY: hostProxy, CONTAINER_PREFIX: (0, getContainerName_1.getContainerName)('') })
});
}
else {
// Production mode - use standalone build
// In production, the standalone files are copied directly to dist/web
const standaloneServerPath = node_path_1.default.join(webDir, 'server.js');
// Check if standalone build exists
if (!(0, fs_extra_1.existsSync)(standaloneServerPath))
throw new Error(`Web interface build not found. The package may be corrupted. Try reinstalling @jjdenhertog/ai-driven-development`);
const modules = node_path_1.default.join(webDir, 'node_modules');
if (!(0, fs_extra_1.existsSync)(modules)) {
(0, logger_1.log)('Installing web interface dependencies...', 'info');
try {
(0, node_child_process_1.execSync)(`npm install`, { cwd: webDir });
}
catch (error) {
console.log(error);
throw new Error(`Failed to install web interface dependencies, it might be rights thing. If you have installed the package globally with sudo, you will need to run this command as root as well.`);
}
}
const port = process.env.AIDEV_WEB_PORT || '3001';
// const proxyPort = process.env.AIDEV_PROXY_PORT || '8888';
(0, logger_1.log)(`Starting AIdev web interface on http://${host}:${port}`, 'info');
(0, logger_1.log)(`Server will bind to: 0.0.0.0:${port}`, 'info');
// Run the standalone server
webProcess = (0, node_child_process_1.spawn)('node', ['server.js'], {
cwd: webDir, // Run from web directory where server.js is located
stdio: 'inherit',
shell: true,
env: Object.assign(Object.assign({}, process.env), { PROJECT_ROOT: targetDir, HOSTNAME: "0.0.0.0", PORT: port, AIDEV_WEB_PORT: port, AIDEV_HOST_PROXY: hostProxy, CONTAINER_PREFIX: (0, getContainerName_1.getContainerName)('') })
});
}
webProcess.on('error', (error) => {
throw new Error(`Failed to start web interface: ${error.message}`);
});
webProcess.on('exit', (code) => {
if (code !== 0) {
throw new Error(`Web interface exited with code ${code}`);
}
});
// Handle SIGINT (Ctrl+C)
process.on('SIGINT', () => {
(0, logger_1.log)('Shutting down web interface...', 'info');
webProcess.kill('SIGINT');
process.exit(0);
});
}
catch (error) {
throw new Error(`Failed to start web interface: ${error instanceof Error ? error.message : String(error)}`);
}
});
}
//# sourceMappingURL=webCommand.js.map