Repomix Extension
This tutorial covers how to add the Repomix MCP Server as a Goose extension to enable automated repository packing, codebase analysis, architecture summaries, test generation, and code exploration, all while compressing the codebase to minimize token usage and stay within your LLM's context limits.
Command
npx -y repomix --mcp
Configuration
Note that you'll need Node.js installed on your system to run this command, as it uses npx
.
- Goose CLI
- Goose Desktop
- Run the
configure
command:
goose configure
- Choose to add a
Command-line Extension
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◆ What type of extension would you like to add?
│ ○ Built-in Extension
│ ● Command-line Extension (Run a local command or script)
│ ○ Remote Extension
└
- Give your extension a name
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◆ What would you like to call this extension?
│ repomix
└
- Enter the command
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ repomix
│
◆ What command should be run?
│ npx -y repomix --mcp
└
- Enter the number of seconds Goose should wait for actions to complete before timing out. Default is 300s
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ repomix
│
◇ What command should be run?
│ npx -y repomix --mcp
│
◆ Please set the timeout for this tool (in secs):
│ 300
│
└
- Choose No when asked to add environment variables
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ repomix
│
◇ What command should be run?
│ npx -y repomix --mcp
│
◇ Please set the timeout for this tool (in secs):
│ 300
│
◆ Would you like to add environment variables?
│ No
│
└ Added repomix extension
- Launch the installer
- Press
Yes
to confirm the installation - Click
Save Configuration
- Scroll to the top and click
Exit
from the upper left corner
Example Usage
In this example, I’ll show you how to use Goose with the Repomix Extension to analyze the compressed Axios repository. Goose will focus on the lib/core/Axios.js
file, explain its role in the architecture, spot missing tests, write new unit tests, and suggest improvements to the testing strategy and code maintainability.
By compressing the entire codebase into an AI-friendly format, Repomix helps Goose stay within token limits while providing detailed, file-specific insights.
Goose Prompt
Review the file lib/core/Axios.js from the Axios repository and identify any missing unit tests needed to thoroughly cover its core functions and classes. Explain the role this file plays in the overall Axios architecture, how it integrates with other modules, and how well it is currently tested. Write new unit tests to improve coverage, and recommend improvements to the testing strategy or refactoring opportunities to make the code more maintainable.
Goose Output
I'll help analyze the Axios.js core file and its testing coverage. Let's break this down into steps:
- First, let's fetch and examine the Axios repository using repomix
- Then analyze the specific file and its related tests
- Finally provide recommendations and new unit tests
Let's start by getting the repository:
--- Pack Remote Repository ---
Now let's read the core Axios.js file and its related test files:
--- Read Repomix Output ---
Based on my analysis of the Axios codebase, I'll provide you with a comprehensive overview of the project structure and create an improved README. Let me break this down into sections:
Role in Axios Architecture
The Axios.js
file is one of the most critical core components of the Axios library. It serves several key purposes:
- Request Handling: It contains the main
Axios
class that processes and dispatches HTTP requests - Configuration Management: Handles merging of default configs with request-specific configs
- Interceptor Management: Manages request and response interceptors
- HTTP Method Convenience: Provides convenience methods for different HTTP verbs (get, post, etc.)
The file integrates with other core modules through:
InterceptorManager
for handling request/response interceptorsdispatchRequest
for making the actual HTTP requestsmergeConfig
for configuration processingbuildFullPath
for URL resolutionAxiosHeaders
for header management
Current Test Coverage Analysis
The current test coverage for Axios.js is fairly good but has some gaps. Looking at the test files:
test/unit/core/Axios.js
- Focuses mainly on error handling cases, particularly un-writable error stackstest/specs/api.spec.js
- Tests the public API surfacetest/specs/interceptors.spec.js
- Tests interceptor functionalitytest/specs/instance.spec.js
- Tests instance creation and configuration
Missing Test Coverage
- Error Handling:
// Missing tests for error propagation in request chain
_request(configOrUrl, config) {
// Error handling here needs more coverage
}
- Config Processing:
// Missing edge cases for config validation
request(configOrUrl, config) {
// Config validation edge cases not fully tested
}
- Method Aliases:
// Missing tests for all HTTP method aliases with various parameter combinations
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
// Missing tests for these methods with different data types
});
- Interceptor Chain:
// Missing tests for complex interceptor chains and error scenarios
const chain = [dispatchRequest.bind(this), undefined];
chain.unshift.apply(chain, requestInterceptorChain);
chain.push.apply(chain, responseInterceptorChain);
New Unit Tests Here are new unit tests to improve coverage:
describe('core::Axios', function() {
describe('request method', function() {
it('should handle null/undefined config values', function(done) {
const instance = new Axios({});
instance.request({
url: '/foo',
params: null,
data: undefined
}).then(function(response) {
expect(response.config.params).toBeNull();
expect(response.config.data).toBeUndefined();
done();
}).catch(done);
});
it('should properly merge nested config objects', function(done) {
const instance = new Axios({
headers: {
common: {
'X-Common': 'common'
},
get: {
'X-Method': 'get'
}
}
});
instance.request({
method: 'get',
headers: {
'X-Custom': 'custom'
}
}).then(function(response) {
expect(response.config.headers['X-Common']).toBe('common');
expect(response.config.headers['X-Method']).toBe('get');
expect(response.config.headers['X-Custom']).toBe('custom');
done();
}).catch(done);
});
});
describe('interceptor chain', function() {
it('should handle async interceptors correctly', async function() {
const instance = new Axios({});
const order = [];
instance.interceptors.request.use(async function(config) {
await new Promise(resolve => setTimeout(resolve, 100));
order.push(1);
return config;
});
instance.interceptors.request.use(async function(config) {
await new Promise(resolve => setTimeout(resolve, 50));
order.push(2);
return config;
});
instance.interceptors.response.use(async function(response) {
await new Promise(resolve => setTimeout(resolve, 100));
order.push(3);
return response;
});
await instance.request('/foo');
expect(order).toEqual([2, 1, 3]); // Interceptors should execute in correct order
});
it('should handle interceptor errors properly', function(done) {
const instance = new Axios({});
const error = new Error('Interceptor Error');
instance.interceptors.request.use(function() {
throw error;
});
instance.request('/foo').catch(function(e) {
expect(e).toBe(error);
done();
});
});
});
describe('HTTP method aliases', function() {
it('should handle various data types in post/put/patch', function(done) {
const instance = new Axios({});
const testCases = [
{method: 'post', data: {foo: 'bar'}},
{method: 'put', data: 'string data'},
{method: 'patch', data: new URLSearchParams('foo=bar')},
{method: 'post', data: new FormData()},
{method: 'put', data: new Blob(['test'])},
{method: 'patch', data: null}
];
Promise.all(testCases.map(({method, data}) => {
return instance[method]('/foo', data).then(response => {
expect(response.config.data).toEqual(data);
return response;
});
})).then(() => done()).catch(done);
});
});
});
Recommendations for Testing Strategy
- Modular Testing:
- Break down tests into smaller, focused units
- Test each HTTP method alias separately
- Create dedicated test suites for config processing, interceptors, and error handling
- Mock Integration Points:
- Use dependency injection for better isolation
- Mock external dependencies consistently
- Create reusable mock factories
- Error Handling:
- Add more tests for error cases
- Test error propagation through interceptor chains
- Verify error object properties and inheritance
- Config Processing:
- Test complex config merging scenarios
- Verify default values are applied correctly
- Test config validation edge cases
- Interceptor Testing:
- Test complex chains of interceptors
- Verify async interceptor behavior
- Test interceptor error handling
Refactoring Opportunities
- Error Handling:
// Current
_request(configOrUrl, config) {
try {
return this.request(configOrUrl, config);
} catch (err) {
// Error handling
}
}
// Suggested
async _request(configOrUrl, config) {
try {
return await this.request(configOrUrl, config);
} catch (err) {
if (err instanceof AxiosError) {
throw err;
}
throw AxiosError.from(err);
}
}
- Config Processing:
// Current
request(configOrUrl, config) {
// Config processing
}
// Suggested
request(configOrUrl, config) {
const normalizedConfig = this._normalizeConfig(configOrUrl, config);
this._validateConfig(normalizedConfig);
return this._processRequest(normalizedConfig);
}
- Interceptor Chain:
// Current
// Interceptor chain building mixed with request logic
// Suggested
class InterceptorChain {
constructor(request, config) {
this.request = request;
this.config = config;
this.chain = [];
}
addRequestInterceptors(interceptors) {
// Add request interceptors
}
addResponseInterceptors(interceptors) {
// Add response interceptors
}
execute() {
// Execute chain
}
}
These improvements would make the code more maintainable and easier to test, while also improving error handling and separation of concerns.
The current test coverage is good but could be improved in these specific areas to ensure more robust functionality. The suggested new tests and refactoring opportunities would help catch edge cases and make the code more maintainable.