mirror of
https://github.com/hexastack/hexabot
synced 2025-05-03 20:41:15 +00:00
Merge pull request #279 from Hexastack/feat/cli-create-project
Feat/cli Move CLI to it's own repo
This commit is contained in:
commit
2bf0135ca3
127
README.md
127
README.md
@ -58,84 +58,73 @@
|
||||
- **nlu:** The NLU Engine built with Python, enabling intent recognition and language detection through machine learning models.
|
||||
- **docker:** A set of Docker Compose files for deploying the entire solution, making it easy to run Hexabot in any environment.
|
||||
|
||||
## Prerequisites
|
||||
## Getting Started
|
||||
|
||||
To ensure Hexabot runs smoothly, you'll need the following:
|
||||
### Prerequisites
|
||||
|
||||
- **Docker:** We recommend using Docker to start the app since multiple services are required (MongoDB, Redis, Prometheus, etc.). All the necessary Docker Compose files are located in the docker folder.
|
||||
- **Node.js:** For development purposes, ensure you have Node.js >= v18.17.0 installed. We recommend using nvm (Node Version Manager) to easily manage and update your Node.js versions.
|
||||
- Node.js >= 18.17.0
|
||||
- npm (Node Package Manager)
|
||||
- Docker installed
|
||||
|
||||
## Installation
|
||||
### Installation
|
||||
|
||||
1. **Clone the Repository:**
|
||||
Install Hexabot CLI globally to have easy access to its commands:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/hexastack/hexabot.git
|
||||
```sh
|
||||
npm install -g hexabot-cli
|
||||
```
|
||||
|
||||
2. **Installation:**
|
||||
Install node dependencies:
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
### Usage
|
||||
|
||||
3. **Environment Setup:** To configure the environment variables, use the following command at the root folder for initialization:
|
||||
1. **Create a new project**:
|
||||
|
||||
```bash
|
||||
$ npx hexabot init
|
||||
```
|
||||
```sh
|
||||
hexabot create my-chatbot
|
||||
```
|
||||
|
||||
This will copy the `.env.example` file to `.env` in the `./docker` directory if the file does not already exist.
|
||||
This will create a new folder `my-chatbot` with all necessary files to get started.
|
||||
|
||||
4. **Running the Application:** Once your environment is set up, you can start the app. Use either of the following commands:
|
||||
2. **Navigate to your project folder**:
|
||||
|
||||
```bash
|
||||
$ npx hexabot start
|
||||
```
|
||||
```sh
|
||||
cd my-chatbot
|
||||
```
|
||||
|
||||
or for development mode:
|
||||
3. **Install dependencies**:
|
||||
|
||||
```bash
|
||||
$ npx hexabot dev
|
||||
```
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
You can also enable services such as the NLU engine and Ollama (The services are declared under the `./docker` folder) :
|
||||
4. **Initialize environment**:
|
||||
|
||||
```bash
|
||||
$ npx hexabot dev --enable=ollama,nlu
|
||||
```
|
||||
```sh
|
||||
hexabot init
|
||||
```
|
||||
|
||||
**Note:** The first time you run the app, Docker will take some time to download all the required images.
|
||||
This command copies the `.env.example` file to `.env`, which you can edit to customize your configuration.
|
||||
|
||||
5. **Run in development mode**:
|
||||
|
||||
```sh
|
||||
hexabot dev --services nlu,ollama
|
||||
```
|
||||
|
||||
This starts the required services in development mode.
|
||||
|
||||
## Usage
|
||||
|
||||
UI Admin Panel is accessible via http://localhost:8080, the default credentials are :
|
||||
|
||||
- **Username:** admin@admin.admin
|
||||
- **Password:** adminadmin
|
||||
|
||||
Live Chat Widget is accessible via http://localhost:5173
|
||||
|
||||
## Commands
|
||||
|
||||
- `npx hexabot init` : Copies the .env.example file to .env in the ./docker directory if .env does not exist. This is usually used for initial setup.
|
||||
- `npx hexabot dev` : Starts all configured Docker services in development mode. It first checks the .env file for completeness against .env.example and builds the docker images locally.
|
||||
- `npx hexabot start` : Starts all configured Docker services by loading all images from Docker Hub. This target also checks the .env file for required variables.
|
||||
- `npx hexabot stop` : Stops all running Docker services defined in the compose files.
|
||||
- `npx hexabot destroy` : Stops all services and removes all volumes associated with the Docker compose setup, ensuring a clean state.
|
||||
|
||||
Example on how to start the stack by adding the Nginx service :
|
||||
|
||||
```sh
|
||||
npx hexabot start --enable=nginx
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For detailed information on how to get started, as well as in-depth user and developer guides, please refer to our full documentation available in the docs folder or visit the [Documentation](https://docs.hexabot.ai).
|
||||
|
||||
You can also find specific documentation for different components of the project in the following locations:
|
||||
|
||||
- [CLI Documentation](https://github.com/Hexastack/hexabot-cli/)
|
||||
- [API Documentation](api/README.md)
|
||||
- [UI Documentation](frontend/README.md)
|
||||
- [Live Chat Widget Documentation](widget/README.md)
|
||||
@ -152,6 +141,48 @@ Please refer to our contribution policy first : [How to contribute to Hexabot](.
|
||||
|
||||
Feel free to join us on [Discord](https://discord.gg/rNb9t2MFkG)
|
||||
|
||||
1. **Clone the Repository:**
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/hexastack/hexabot.git
|
||||
```
|
||||
|
||||
2. **Installation:**
|
||||
Install node dependencies:
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
3. **Environment Setup:** To configure the environment variables, use the following command at the root folder for initialization:
|
||||
|
||||
```bash
|
||||
$ hexabot init
|
||||
```
|
||||
|
||||
This will copy the `.env.example` file to `.env` in the `./docker` directory if the file does not already exist.
|
||||
|
||||
4. **Running the Application:** Once your environment is set up, you can start the app. Use either of the following commands:
|
||||
|
||||
|
||||
For development mode:
|
||||
|
||||
```bash
|
||||
$ hexabot dev
|
||||
```
|
||||
|
||||
Otherwise, you can choose to download docker images rather than building them:
|
||||
```bash
|
||||
$ hexabot start
|
||||
```
|
||||
|
||||
You can also enable services such as the NLU engine and Ollama (The services are declared under the `./docker` folder) :
|
||||
|
||||
```bash
|
||||
$ hexabot dev --enable=ollama,nlu
|
||||
```
|
||||
|
||||
**Note:** The first time you run the app, Docker will take some time to download all the required images.
|
||||
|
||||
## License
|
||||
|
||||
This software is licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
|
2
cli/.gitignore
vendored
2
cli/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
@ -1,35 +0,0 @@
|
||||
{
|
||||
"name": "hexabot-cli",
|
||||
"version": "2.0.0",
|
||||
"description": "Hexabot CLI for creating and managing chatbots built with Hexabot.",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"hexabot": "dist/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/cli.js",
|
||||
"dev": "ts-node src/cli.ts",
|
||||
"prepare": "npm run build"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Hexastack",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"degit": "^2.8.4",
|
||||
"dotenv": "^16.4.5",
|
||||
"figlet": "^1.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/commander": "^2.12.2",
|
||||
"@types/degit": "^2.8.6",
|
||||
"@types/figlet": "^1.5.8",
|
||||
"@types/node": "^22.7.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.2"
|
||||
}
|
||||
}
|
235
cli/src/index.ts
235
cli/src/index.ts
@ -1,235 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { execSync } from 'child_process';
|
||||
import { Command } from 'commander';
|
||||
import figlet from 'figlet';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
console.log(figlet.textSync('Hexabot'));
|
||||
|
||||
// Configuration
|
||||
const FOLDER = path.resolve(process.cwd(), './docker');
|
||||
|
||||
/**
|
||||
* Check if the docker folder exists, otherwise prompt the user to cd into the correct folder.
|
||||
*/
|
||||
const checkDockerFolder = (): void => {
|
||||
if (!fs.existsSync(FOLDER)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Error: The 'docker' folder is not found in the current directory.`,
|
||||
),
|
||||
);
|
||||
console.error(
|
||||
chalk.yellow(
|
||||
`Please make sure you're in the Hexabot project directory and try again.`,
|
||||
),
|
||||
);
|
||||
console.log(chalk.cyan(`Example: cd path/to/hexabot`));
|
||||
process.exit(1); // Exit the script if the folder is not found
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize Commander
|
||||
const program = new Command();
|
||||
|
||||
// Helper Functions
|
||||
|
||||
/**
|
||||
* Generate Docker Compose file arguments based on provided services.
|
||||
* @param services List of services
|
||||
* @param type Optional type ('dev' | 'prod')
|
||||
* @returns String of Docker Compose file arguments
|
||||
*/
|
||||
const generateComposeFiles = (
|
||||
services: string[],
|
||||
type?: 'dev' | 'prod',
|
||||
): string => {
|
||||
let files = [`-f ${path.join(FOLDER, 'docker-compose.yml')}`];
|
||||
|
||||
services.forEach((service) => {
|
||||
files.push(`-f ${path.join(FOLDER, `docker-compose.${service}.yml`)}`);
|
||||
if (type) {
|
||||
const serviceTypeFile = path.join(
|
||||
FOLDER,
|
||||
`docker-compose.${service}.${type}.yml`,
|
||||
);
|
||||
if (fs.existsSync(serviceTypeFile)) {
|
||||
files.push(`-f ${serviceTypeFile}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (type) {
|
||||
const mainTypeFile = path.join(FOLDER, `docker-compose.${type}.yml`);
|
||||
if (fs.existsSync(mainTypeFile)) {
|
||||
files.push(`-f ${mainTypeFile}`);
|
||||
}
|
||||
}
|
||||
|
||||
return files.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a Docker Compose command.
|
||||
* @param args Additional arguments for the docker compose command
|
||||
*/
|
||||
const dockerCompose = (args: string): void => {
|
||||
try {
|
||||
execSync(`docker compose ${args}`, { stdio: 'inherit' });
|
||||
} catch (error) {
|
||||
console.error(chalk.red('Error executing Docker Compose command.'));
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a Docker Exec command.
|
||||
* @param container Container for the docker exec command
|
||||
* @param options Additional options for the docker exec command
|
||||
* @param command Command to be executed within the container
|
||||
*/
|
||||
const dockerExec = (
|
||||
container: string,
|
||||
command: string,
|
||||
options?: string,
|
||||
): void => {
|
||||
try {
|
||||
execSync(`docker exec -it ${options} ${container} ${command}`, {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(chalk.red('Error executing Docker Exec command.'));
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the comma-separated service list.
|
||||
* @param serviceString Comma-separated list of services
|
||||
* @returns Array of services
|
||||
*/
|
||||
const parseServices = (serviceString: string): string[] => {
|
||||
return serviceString
|
||||
.split(',')
|
||||
.map((service) => service.trim())
|
||||
.filter((s) => s);
|
||||
};
|
||||
|
||||
// Check if the docker folder exists
|
||||
checkDockerFolder();
|
||||
|
||||
// Commands
|
||||
|
||||
program
|
||||
.name('Hexabot')
|
||||
.description('A CLI to manage your Hexabot chatbot instance')
|
||||
.version('1.0.0');
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.description('Initialize the environment by copying .env.example to .env')
|
||||
.action(() => {
|
||||
const envPath = path.join(FOLDER, '.env');
|
||||
const exampleEnvPath = path.join(FOLDER, '.env.example');
|
||||
|
||||
if (fs.existsSync(envPath)) {
|
||||
console.log(chalk.yellow('.env file already exists.'));
|
||||
} else {
|
||||
fs.copyFileSync(exampleEnvPath, envPath);
|
||||
console.log(chalk.green('Copied .env.example to .env'));
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('start')
|
||||
.description('Start specified services with Docker Compose')
|
||||
.option(
|
||||
'--enable <services>',
|
||||
'Comma-separated list of services to enable',
|
||||
'',
|
||||
)
|
||||
.action((options) => {
|
||||
const services = parseServices(options.enable);
|
||||
const composeArgs = generateComposeFiles(services);
|
||||
dockerCompose(`${composeArgs} up -d`);
|
||||
});
|
||||
|
||||
program
|
||||
.command('dev')
|
||||
.description(
|
||||
'Start specified services in development mode with Docker Compose',
|
||||
)
|
||||
.option(
|
||||
'--enable <services>',
|
||||
'Comma-separated list of services to enable',
|
||||
'',
|
||||
)
|
||||
.action((options) => {
|
||||
const services = parseServices(options.enable);
|
||||
const composeArgs = generateComposeFiles(services, 'dev');
|
||||
dockerCompose(`${composeArgs} up --build -d`);
|
||||
});
|
||||
|
||||
program
|
||||
.command('migrate [args...]')
|
||||
.description('Run database migrations')
|
||||
.action((args) => {
|
||||
const migrateArgs = args.join(' ');
|
||||
dockerExec(
|
||||
'api',
|
||||
`npm run migrate ${migrateArgs}`,
|
||||
'--user $(id -u):$(id -g)',
|
||||
);
|
||||
});
|
||||
|
||||
program
|
||||
.command('start-prod')
|
||||
.description(
|
||||
'Start specified services in production mode with Docker Compose',
|
||||
)
|
||||
.option(
|
||||
'--enable <services>',
|
||||
'Comma-separated list of services to enable',
|
||||
'',
|
||||
)
|
||||
.action((options) => {
|
||||
const services = parseServices(options.enable);
|
||||
const composeArgs = generateComposeFiles(services, 'prod');
|
||||
dockerCompose(`${composeArgs} up -d`);
|
||||
});
|
||||
|
||||
program
|
||||
.command('stop')
|
||||
.description('Stop specified Docker Compose services')
|
||||
.option('--enable <services>', 'Comma-separated list of services to stop', '')
|
||||
.action((options) => {
|
||||
const services = parseServices(options.enable);
|
||||
const composeArgs = generateComposeFiles(services);
|
||||
dockerCompose(`${composeArgs} down`);
|
||||
});
|
||||
|
||||
program
|
||||
.command('destroy')
|
||||
.description('Destroy specified Docker Compose services and remove volumes')
|
||||
.option(
|
||||
'--enable <services>',
|
||||
'Comma-separated list of services to destroy',
|
||||
'',
|
||||
)
|
||||
.action((options) => {
|
||||
const services = parseServices(options.enable);
|
||||
const composeArgs = generateComposeFiles(services);
|
||||
dockerCompose(`${composeArgs} down -v`);
|
||||
});
|
||||
|
||||
// Parse arguments
|
||||
program.parse(process.argv);
|
||||
|
||||
// If no command is provided, display help
|
||||
if (!process.argv.slice(2).length) {
|
||||
program.outputHelp();
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ES2020", // Change to ES2020 or ESNext
|
||||
"moduleResolution": "node", // Ensure module resolution is node
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user