llmove is a command-line tool that processes XML specification files and sends them to Claude (Anthropic's LLM) for AI-powered code generation.
llmove scans a directory of .xml specification files, extracts prompts and system instructions, and sends them to Claude to generate code or documentation. The tool:
- Recursively processes XML files with support for includes and plugins
- Tracks which files have been processed to avoid duplicates
- Supports dry-run mode to preview what will be sent to the API
- Can re-apply the last generated output
- Automatically handles file naming conflicts with timestamps
npm install -g llmovellmove configureThis will prompt you for:
- Your Anthropic API key
- The model to use (default:
claude-opus-4-20250514) - The specs folder path (default:
specs)
Configuration is stored in ~/.llmove/config.json.
llmove initCreate a file specs/my-feature.xml:
<prompt>
Generate a Node.js function that validates email addresses using regex.
The function should:
- Return true for valid emails
- Return false for invalid emails
- Handle edge cases like multiple dots, special characters
</prompt># Preview what will be sent (dry run)
llmove --dryRun
# Generate code from your specs
llmove
Spec files use two main tags:
<system>- Sets the system prompt/context for the LLM<prompt>- Contains the user prompt/request
<!-- specs/api/user-service.xml -->
<system>
You are an expert Node.js developer. Generate clean, well-documented code
following REST API best practices.
</system>
<prompt>
Create a user service with the following endpoints:
- GET /users - List all users with pagination
- GET /users/:id - Get user by ID
- POST /users - Create new user
- PUT /users/:id - Update user
- DELETE /users/:id - Delete user
Use Express.js and include input validation.
</prompt>You can include content from other files:
<prompt>
Update this function to handle async operations:
<llmove:include path="./src/validator.js" lines="10:25" />
</prompt>Use the source tag to include entire files:
<prompt>
Refactor this code to use TypeScript:
<llmove:source path="./legacy/user.js" />
</prompt>The specs/root.xml file can define global settings:
<system version="0.2.0">
<!-- Global system context applied to all prompts -->
You are a senior developer working on a Node.js microservices project.
Follow clean code principles and include comprehensive error handling.
</system>With
llmove chatyou can chat with your LLM having the XML root and conventions file as context.
You can override configuration using environment variables:
LLMOVE_API_KEY- Your Anthropic API keyLLMOVE_API_URL- Custom API URL (default: https://api.anthropic.com)LLMOVE_API_MODEL- Model to use
project/
├── specs/ # Your XML specification files
│ ├── root.xml # Global configuration
│ └── features/ # Organize specs in subdirectories
├── .llmove/ # Cache and metadata
│ ├── userPrompts.txt # Tracks processed files
│ └── last-llmove-output.json # Last generation result
- Organize your specs: Use subdirectories to group related specifications
- Use conventions.xml: Place common patterns in
conventions.xmlfiles - Incremental processing: llmove tracks which files have been processed
- Version control: Commit your specs to track changes over time
- Dry run first: Always use
--dryRunto preview before making API calls
llmove is designed to be minimal and extensible:
- Main CLI (
llmove.cjs): Entry point and command handling - Libraries (
lib/): Core functionality split into focused modules - Plugins (
lib/plugins/): Transform and filter XML content
llmove supports two types of plugins:
Filter plugins process the list of files before parsing:
// lib/plugins/myFilter.js
module.exports = async function filterExample(config, files, metadata) {
// Transform or filter the files array
return files.filter(file => !file.path.includes('draft'));
};Parse plugins transform individual file content:
// lib/plugins/myParser.js
module.exports = async function parseExample(config, file, metadata) {
// Transform file content
file.content = file.content.replace(/TODO/g, 'TASK');
// Can return just the file or include new files to process
return {
file: file,
newFiles: [] // Optional: additional files to process
};
};- Create your plugin in
lib/plugins/ - Add it to the appropriate array in
lib/plugins.js:
const filterPlugins = [
require('./plugins/filterAddRootConventions'),
require('./plugins/myFilter') // Add your filter plugin
];
const parsePlugins = [
require('./plugins/source'),
require('./plugins/includeFiles'),
require('./plugins/myParser') // Add your parse plugin
];- Keep it tiny: No unnecessary dependencies
- Small functions: Each function should do one thing well
- Clear separation: Logic should be separated into appropriate modules
- Error handling: Fail gracefully with helpful error messages
- Cross-platform: Use Node.js built-ins for file system operations
- Autocode: Use llmove itself to create plugins =)
Create test XML files in specs/test/ and run:
llmove --dryRun- Fork the repository
- Create a feature branch
- Write clear commit messages
- Ensure your code follows the existing style
- Submit a pull request with a description of your changes
CC0-1.0
Luca Rainone