@dguttman/aider-js v1.4.0
@dguttman/aider-js
Node.js wrapper for the Aider tool using a self-contained Python environment via uv.
This package allows you to easily integrate Aider's AI coding capabilities into your Node.js projects without needing to manage Python environments or dependencies manually.
Features
- Provides a simple
runAider(options)function. - Automatically downloads the
uvbinary during installation. - Creates an isolated Python virtual environment using
uv. - Installs
aider-chatwithin the isolated environment. - Handles communication with the Aider process.
Installation
npm install @dguttman/aider-jsThe postinstall script will automatically download the necessary uv binary for your platform and set up the Python environment with aider-chat.
Usage
API Keys:
- Default Behavior: By default,
runAiderexpects API keys (e.g.,OPENAI_API_KEY,OPENROUTER_API_KEY,ANTHROPIC_API_KEY) to be set as environment variables in the Node.js process. These are automatically passed down to the underlying Aider Python process. - Using
apiBase: If you provide the optionalapiBaseoption (for proxies or custom endpoints like OpenRouter), you have two choices for the API key:- Set
OPENAI_API_KEYEnvironment Variable: IfapiBaseis provided and theapiKeyoption (see below) is not used, theOPENAI_API_KEYenvironment variable must be set. Aider uses this specific environment variable whenapiBaseis involved, even for non-OpenAI models. - Use
apiKeyOption: Alternatively, ifapiBaseis provided, you can also provide the optionalapiKeystring directly in therunAideroptions. If you do this, the value of theapiKeyoption will be used as theOPENAI_API_KEYfor the Python process for that specific call, overriding anyOPENAI_API_KEYenvironment variable that might also be set.
- Set
In summary: Use environment variables for keys by default. Only use the apiKey option if you are also using apiBase and you want to specify the key directly for that call instead of relying on the OPENAI_API_KEY environment variable.
Example Environment Setup:
# Set API key(s) as environment variables
export OPENAI_API_KEY=sk-...
export OPENROUTER_API_KEY=sk-or-...
# Run your Node.js script
node your_script.jsExample runAider Call:
const { runAider } = require('@dguttman/aider-js');
const path = require('path'); // For constructing paths
async function main() {
try {
// --- Options ---
// See descriptions below the example
const result = await runAider({
// --- Required ---
prompt: 'Refactor the main function in app.js based on the architecture doc.',
modelName: 'openai/gpt-4o-mini',
repoPath: path.resolve('../path/to/your/git/repository'),
// --- Files (Relative to repoPath) ---
editableFiles: ['src/app.js', 'src/utils.js'],
readOnlyFiles: ['docs/architecture.md'],
// --- Optional: Custom Endpoint ---
apiBase: 'https://openrouter.ai/api/v1',
apiKey: 'sk-or-xxxxxx', // Only needed if using apiBase AND overriding OPENAI_API_KEY env var.
// --- Optional: Behavior ---
autoCommits: false, // Default: false
showDiffs: false, // Default: false
stream: false, // Default: false (Note: Streaming currently not fully supported by Node wrapper)
chatLanguage: 'english', // Default: 'english'
verbose: false // Default: false
});
// Output from the aider process
console.log('Aider completed successfully.');
// Aider's stdout (contains diffs, chat messages, etc.)
console.log('Stdout:\n', result.stdout);
// Aider's stderr (contains informational logs, warnings, errors from Python)
console.log('Stderr:\n', result.stderr);
} catch (error) {
console.error('Error running Aider:', error);
// error.stderr and error.stdout might contain additional context
if (error.stderr) {
console.error('Stderr from failed run:\n', error.stderr);
}
}
}
main();The runAider function accepts an options object with the following properties:
prompt(string, required): The natural language instruction for Aider.modelName(string, required): The identifier for the LLM model Aider should use (e.g.,'openai/gpt-4o','anthropic/claude-3-5-sonnet-20240620').repoPath(string, required): An absolute or relative path to the root of the Git repository Aider should operate within.editableFiles(array of strings, optional): A list of file paths (relative torepoPathor absolute) that Aider is allowed to modify. Defaults to[].readOnlyFiles(array of strings, optional): A list of file paths (relative torepoPathor absolute) that Aider can read for context but cannot modify. Defaults to[].apiBase(string, optional): The base URL for a custom LLM API endpoint (e.g., for using proxies, local LLMs, or services like OpenRouter). See API Key section above for crucial details.apiKey(string, optional): The API key. This is primarily used whenapiBaseis also provided, allowing you to specify the key directly for the call, overriding theOPENAI_API_KEYenvironment variable. See API Key section above.autoCommits(boolean, optional): Iftrue, Aider will automatically commit changes it makes. Defaults tofalse.showDiffs(boolean, optional): Iftrue, Aider will include diffs of proposed changes in its output. Defaults tofalse.stream(boolean, optional): Iftrue, instructs Aider to attempt streaming responses. Note: While the option is passed to Aider, the current Node.js wrapper implementation buffers the output, so you won't see true streaming behavior yet. Defaults tofalse.chatLanguage(string, optional): Specifies the language for Aider's chat interactions (e.g.,'spanish','french'). Defaults to'english'.verbose(boolean, optional): Iftrue, enables more detailed logging output from the underlying Aider process (sent to stderr). Defaults tofalse.
The function returns a Promise that resolves with an object containing stdout and stderr from the Aider process, or rejects with an error if the process fails.
How it Works
- Postinstall: Installs
uvand Python dependencies (aider-chat) into.venv/. - Execution (
runAider):- Gathers options (
prompt,modelName,repoPath,editableFiles,readOnlyFiles,apiBase,apiKey,autoCommits,showDiffs,stream,chatLanguage,verbose). - Validation:
- Checks
repoPathexists and is a directory. - If
apiBaseis provided, ensures eitherapiKeyoption orOPENAI_API_KEYenv var is present.
- Checks
- Model Prefixing: Prepends
openai/tomodelNameifapiBaseis provided. - Environment Setup: Prepares environment variables for the child process:
- Inherits all
process.env. - If
apiBaseandapiKeyare both provided, setsOPENAI_API_KEYin the child environment to the value of theapiKeyoption.
- Inherits all
- JSON Payload: Bundles options (including
repoPath, excludingapiKeyitself) into a JSON string. - Spawn: Executes
python/aider_entrypoint.pyusing the Python in.venv/, passing the JSON payload as an argument and the prepared environment variables. Crucially, it also sets thecwd(current working directory) of the Python process to the providedrepoPath.
- Gathers options (
- Python Script (
aider_entrypoint.py):- Parses the JSON configuration (it still receives
repoPathin the JSON, though it's primarily used by Node for settingcwd). - Initializes Aider
Coderwith model, files, etc. (does not explicitly passgit_dname). - Aider implicitly detects the Git repository context from the process's current working directory, which was set to
repoPathby Node.js. - Aider reads API keys from the environment variables provided by Node.js (using
OPENAI_API_KEYifapiBasewas involved). - Runs
coder.run(prompt). - Captures stdout/stderr back to Node.js.
- Parses the JSON configuration (it still receives
Development & Testing
- Cleanup:
npm run cleanup(removes downloadeduvand the.venvdirectory) - Running Tests:
npm test - Test Recording:
- Tests use
echoproxiato record and replay HTTP interactions with the LLM API (e.g., OpenRouter). This allows tests to run without live API calls after the initial recording. - To create or update recordings, run the tests with the
RECORD_MODEenvironment variable set totrueand ensure your API key (e.g.,OPENROUTER_API_KEY) is also set in the environment:export RECORD_MODE=true export OPENROUTER_API_KEY=sk-or-... # Replace with your actual key npm test - Important: When
RECORD_MODEistrue, the existing contents of thetest/__recordings__directory will be deleted before new recordings are made for the current test run.
- Tests use
Contributing
Contributions are welcome! Please open an issue or submit a pull request.