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
JavaScript
;
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