UNPKG

spaider

Version:

Deterministic-first AI code assistant that crawls your codebase to implement changes using open source LLMs

192 lines (187 loc) 6.97 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.cli = main; const index_1 = require("./index"); const path = __importStar(require("path")); const utils_1 = require("./lib/utils"); function parseArgs() { const args = process.argv.slice(2); const options = { prompt: "", files: [], projectRoot: process.cwd(), help: false, version: false, writeOnly: false, }; for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case "-h": case "--help": options.help = true; break; case "-v": case "--version": options.version = true; break; case "-p": case "--prompt": if (i + 1 < args.length) { options.prompt = args[++i]; } break; case "-f": case "--files": // Collect all following arguments until next flag or end while (i + 1 < args.length && !args[i + 1].startsWith("-")) { options.files.push(args[++i]); } break; case "-r": case "--root": if (i + 1 < args.length) { options.projectRoot = path.resolve(args[++i]); } break; case "-w": case "--write-only": options.writeOnly = true; break; default: // If no flags are provided, treat the first argument as prompt if (!options.prompt && !arg.startsWith("-")) { options.prompt = arg; } break; } } return options; } function showHelp() { console.log(` Spaider - Deterministic-First AI Code Assistant Usage: spaider [options] <prompt> spaider -p "your prompt" -f file1.ts file2.ts Options: -p, --prompt <text> The request/prompt for the AI assistant -f, --files <files...> Initial files to include in the analysis -r, --root <path> Project root directory (default: current directory) -w, --write-only Write changes to a file instead of applying them directly -h, --help Show this help message -v, --version Show version information Examples: spaider -p "Add a comment to explain this function" -f src/auth.ts spaider -p "Add role-based authorization" -f src/auth.ts src/middleware/ spaider -p "Analyze error handling patterns" -r ./my-project spaider -w -p "Add error handling" -f src/auth.ts Environment Variables: export OPENAI_API_KEY=... Required. Your OpenAI API key export OPENAI_MODEL=... Optional. Model to use (default: gpt-4.1) export OPENAI_BASE_URL=... Optional. Custom OpenAI API base URL Note: - If no files are specified, the assistant will discover relevant files automatically - The assistant works best with TypeScript/JavaScript projects - Make sure you have 'rg' (ripgrep) installed for file discovery - Use --write-only to generate a CHANGES.md file for manual review instead of applying changes directly `); } async function showVersion() { try { const packageJsonPath = path.join(__dirname, "../package.json"); const packageJson = JSON.parse(await (0, utils_1.readFile)(packageJsonPath)); console.log(`Spaider v${packageJson.version}`); console.log(`Description: ${packageJson.description}`); } catch (error) { console.log("Spaider v1.0.0"); } } async function main() { const options = parseArgs(); if (options.help) { showHelp(); process.exit(0); } if (options.version) { await showVersion(); process.exit(0); } if (!options.prompt) { console.error("Error: Please provide a prompt."); console.error("Use 'spaider --help' for usage information."); process.exit(1); } try { const result = await (0, index_1.processRequest)(options.prompt, options.files, options.projectRoot, options.writeOnly); if (options.writeOnly) { if (result.result.createdFiles.includes("CHANGES.md")) { console.log(`\n✅ Changes written to CHANGES.md`); console.log(`📝 Review the file and apply changes manually`); } else { console.log(`\nℹ️ No changes to write (no modifications needed)`); } } else { if (result.result.modifiedFiles.length > 0) { console.log(`\nModified files:`); result.result.modifiedFiles.forEach((file) => console.log(` - ${file}`)); } if (result.result.createdFiles.length > 0) { console.log(`\nCreated files:`); result.result.createdFiles.forEach((file) => console.log(` - ${file}`)); } if (result.result.deletedFiles.length > 0) { console.log(`\nDeleted files:`); result.result.deletedFiles.forEach((file) => console.log(` - ${file}`)); } } } catch (error) { console.error("\nError:", error instanceof Error ? error.message : String(error)); process.exit(1); } } if (require.main === module) { main().catch((error) => { console.error("Unexpected error:", error); process.exit(1); }); } //# sourceMappingURL=cli.js.map