fluxprotocol-cli
Advanced tools
+2
-1
| { | ||
| "name": "fluxprotocol-cli", | ||
| "version": "0.0.5", | ||
| "version": "0.0.6", | ||
| "description": "FLUX CLI - create, dev, build connectors", | ||
@@ -10,2 +10,3 @@ "type": "module", | ||
| "main": "./dist/index.js", | ||
| "files": ["dist", "README.md"], | ||
| "scripts": { | ||
@@ -12,0 +13,0 @@ "build": "tsup src/index.ts --format esm", |
| import { Command } from 'commander'; | ||
| import { spawn } from 'child_process'; | ||
| import { resolve, dirname, basename } from 'path'; | ||
| import chalk from 'chalk'; | ||
| import ora from 'ora'; | ||
| export const buildCommand = new Command('build') | ||
| .description('Build connector for production') | ||
| .argument('<file>', 'Connector file to build') | ||
| .option('-o, --output <dir>', 'Output directory', 'dist') | ||
| .option('--minify', 'Minify output', false) | ||
| .action(async (file: string, options: { output: string; minify: boolean }) => { | ||
| const spinner = ora('Building connector...').start(); | ||
| const filePath = resolve(file); | ||
| const outputDir = resolve(options.output); | ||
| const entryName = basename(file, '.ts'); | ||
| const args = [ | ||
| 'tsup', | ||
| filePath, | ||
| '--format', 'esm', | ||
| '--out-dir', outputDir, | ||
| '--dts', | ||
| ]; | ||
| if (options.minify) { | ||
| args.push('--minify'); | ||
| } | ||
| const child = spawn('npx', args, { | ||
| stdio: 'pipe', | ||
| shell: true, | ||
| cwd: dirname(filePath), | ||
| }); | ||
| let output = ''; | ||
| child.stdout?.on('data', (data) => { | ||
| output += data.toString(); | ||
| }); | ||
| child.stderr?.on('data', (data) => { | ||
| output += data.toString(); | ||
| }); | ||
| child.on('close', (code) => { | ||
| if (code === 0) { | ||
| spinner.succeed(chalk.green('Build complete!')); | ||
| console.log(chalk.dim(`Output: ${outputDir}/${entryName}.js`)); | ||
| } else { | ||
| spinner.fail(chalk.red('Build failed')); | ||
| console.log(output); | ||
| process.exit(1); | ||
| } | ||
| }); | ||
| child.on('error', (error) => { | ||
| spinner.fail(chalk.red(`Build error: ${error.message}`)); | ||
| process.exit(1); | ||
| }); | ||
| }); |
| import { Command } from 'commander'; | ||
| import { mkdir, writeFile } from 'fs/promises'; | ||
| import { join } from 'path'; | ||
| import chalk from 'chalk'; | ||
| import ora from 'ora'; | ||
| const TEMPLATE = `import { connector, method, FluxServer, StdioTransport } from 'fluxprotocol-sdk'; | ||
| @connector('{{name}}', { description: '{{name}} connector' }) | ||
| class {{className}}Connector { | ||
| @method({ description: 'Example method' }) | ||
| async getData(id: string): Promise<{ id: string; data: string }> { | ||
| return { id, data: 'Hello from {{name}}!' }; | ||
| } | ||
| } | ||
| const server = new FluxServer({{className}}Connector); | ||
| const transport = new StdioTransport(server); | ||
| server.setTransport(transport); | ||
| server.start(); | ||
| `; | ||
| const PACKAGE_TEMPLATE = `{ | ||
| "name": "{{name}}-connector", | ||
| "version": "0.0.1", | ||
| "type": "module", | ||
| "scripts": { | ||
| "start": "tsx index.ts", | ||
| "dev": "tsx watch index.ts" | ||
| }, | ||
| "dependencies": { | ||
| "fluxprotocol-sdk": "latest" | ||
| }, | ||
| "devDependencies": { | ||
| "tsx": "^4.19.2", | ||
| "@types/node": "^22.10.2" | ||
| } | ||
| } | ||
| `; | ||
| function toPascalCase(str: string): string { | ||
| return str | ||
| .split(/[-_\s]+/) | ||
| .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) | ||
| .join(''); | ||
| } | ||
| export const createCommand = new Command('create') | ||
| .description('Create a new FLUX connector') | ||
| .argument('<name>', 'Connector name') | ||
| .option('-d, --dir <directory>', 'Output directory', '.') | ||
| .action(async (name: string, options: { dir: string }) => { | ||
| const spinner = ora(`Creating ${name} connector...`).start(); | ||
| try { | ||
| const dir = join(options.dir, name); | ||
| await mkdir(dir, { recursive: true }); | ||
| const className = toPascalCase(name); | ||
| const indexContent = TEMPLATE | ||
| .replace(/\{\{name\}\}/g, name) | ||
| .replace(/\{\{className\}\}/g, className); | ||
| const packageContent = PACKAGE_TEMPLATE.replace(/\{\{name\}\}/g, name); | ||
| await writeFile(join(dir, 'index.ts'), indexContent); | ||
| await writeFile(join(dir, 'package.json'), packageContent); | ||
| spinner.succeed(chalk.green(`Created ${name} connector!`)); | ||
| console.log(); | ||
| console.log(chalk.dim('Next steps:')); | ||
| console.log(chalk.cyan(` cd ${name}`)); | ||
| console.log(chalk.cyan(' pnpm install')); | ||
| console.log(chalk.cyan(' pnpm dev')); | ||
| } catch (error) { | ||
| spinner.fail(chalk.red('Failed to create connector')); | ||
| console.error(error); | ||
| process.exit(1); | ||
| } | ||
| }); |
| import { Command } from 'commander'; | ||
| import { spawn, type ChildProcess } from 'child_process'; | ||
| import { watch } from 'fs'; | ||
| import { resolve } from 'path'; | ||
| import chalk from 'chalk'; | ||
| export const devCommand = new Command('dev') | ||
| .description('Run connector in development mode with hot reload') | ||
| .argument('<file>', 'Connector file to run') | ||
| .option('-p, --port <port>', 'HTTP port', '3000') | ||
| .action(async (file: string, options: { port: string }) => { | ||
| const filePath = resolve(file); | ||
| let childProcess: ChildProcess | null = null; | ||
| const startProcess = () => { | ||
| if (childProcess) { | ||
| childProcess.kill(); | ||
| } | ||
| console.log(chalk.cyan(`\nš Starting ${file}...`)); | ||
| childProcess = spawn('npx', ['tsx', filePath], { | ||
| stdio: 'inherit', | ||
| shell: true, | ||
| env: { ...process.env, FLUX_PORT: options.port }, | ||
| }); | ||
| childProcess.on('error', (error) => { | ||
| console.error(chalk.red(`Error: ${error.message}`)); | ||
| }); | ||
| }; | ||
| startProcess(); | ||
| const watcher = watch(filePath, (eventType) => { | ||
| if (eventType === 'change') { | ||
| console.log(chalk.yellow('\nš¦ File changed, restarting...')); | ||
| startProcess(); | ||
| } | ||
| }); | ||
| process.on('SIGINT', () => { | ||
| console.log(chalk.dim('\n\nShutting down...')); | ||
| watcher.close(); | ||
| if (childProcess) { | ||
| childProcess.kill(); | ||
| } | ||
| process.exit(0); | ||
| }); | ||
| }); |
-18
| #!/usr/bin/env node | ||
| import { Command } from 'commander'; | ||
| import { createCommand } from './commands/create.js'; | ||
| import { devCommand } from './commands/dev.js'; | ||
| import { buildCommand } from './commands/build.js'; | ||
| const program = new Command(); | ||
| program | ||
| .name('flux') | ||
| .description('FLUX SDK CLI - Universal AI Connectivity') | ||
| .version('0.0.1'); | ||
| program.addCommand(createCommand); | ||
| program.addCommand(devCommand); | ||
| program.addCommand(buildCommand); | ||
| program.parse(); |
| { | ||
| "extends": "../../tsconfig.json", | ||
| "compilerOptions": { | ||
| "outDir": "./dist", | ||
| "rootDir": "./src" | ||
| }, | ||
| "include": [ | ||
| "src/**/*" | ||
| ] | ||
| } |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
3
-50%2
-50%6941
-46.67%3
-62.5%161
-53.6%