Skip to content

Instantly share code, notes, and snippets.

@kfrancis
Created December 19, 2024 16:53
Show Gist options
  • Save kfrancis/bbb57d85306246b72130f4a62ae7b946 to your computer and use it in GitHub Desktop.
Save kfrancis/bbb57d85306246b72130f4a62ae7b946 to your computer and use it in GitHub Desktop.
Repomix Browser Extension
{
"manifest_version": 3,
"name": "Repomix Helper",
"version": "1.0",
"description": "Generate repomix output from GitHub repositories with advanced configuration",
"permissions": [
"activeTab",
"scripting",
"storage"
],
"action": {
"default_popup": "popup.html"
},
"host_permissions": [
"https://github.com/*"
],
"options_page": "options.html"
}
<!DOCTYPE html>
<html>
<head>
<style>
body {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.section {
margin-bottom: 20px;
}
.input-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}
textarea {
width: 100%;
height: 60px;
}
.checkbox-group {
margin: 5px 0;
}
</style>
</head>
<body>
<h2>Repomix Helper Settings</h2>
<div class="section">
<h3>Output Settings</h3>
<div class="input-group">
<label>Output Style:</label>
<select id="outputStyle">
<option value="plain">Plain Text</option>
<option value="xml">XML</option>
<option value="markdown">Markdown</option>
</select>
</div>
<div class="checkbox-group">
<input type="checkbox" id="removeComments">
<label for="removeComments">Remove Comments</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="removeEmptyLines">
<label for="removeEmptyLines">Remove Empty Lines</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="showLineNumbers">
<label for="showLineNumbers">Show Line Numbers</label>
</div>
</div>
<div class="section">
<h3>File Patterns</h3>
<div class="input-group">
<label>Default Include Patterns:</label>
<textarea id="includePatterns">src/**/*.ts,**/*.md</textarea>
</div>
<div class="input-group">
<label>Default Ignore Patterns:</label>
<textarea id="ignorePatterns">**/*.log,tmp/</textarea>
</div>
</div>
<div class="section">
<h3>Security Settings</h3>
<div class="checkbox-group">
<input type="checkbox" id="enableSecurityCheck" checked>
<label for="enableSecurityCheck">Enable Security Check</label>
</div>
</div>
<button id="save">Save Settings</button>
<div id="status" style="margin-top: 10px;"></div>
<script src="options.js"></script>
</body>
</html>
document.addEventListener('DOMContentLoaded', function() {
// Load saved settings
chrome.storage.sync.get({
outputStyle: 'plain',
removeComments: false,
removeEmptyLines: false,
showLineNumbers: false,
includePatterns: 'src/**/*.ts,**/*.md',
ignorePatterns: '**/*.log,tmp/',
enableSecurityCheck: true
}, function(items) {
document.getElementById('outputStyle').value = items.outputStyle;
document.getElementById('removeComments').checked = items.removeComments;
document.getElementById('removeEmptyLines').checked = items.removeEmptyLines;
document.getElementById('showLineNumbers').checked = items.showLineNumbers;
document.getElementById('includePatterns').value = items.includePatterns;
document.getElementById('ignorePatterns').value = items.ignorePatterns;
document.getElementById('enableSecurityCheck').checked = items.enableSecurityCheck;
});
// Save settings
document.getElementById('save').addEventListener('click', function() {
const settings = {
outputStyle: document.getElementById('outputStyle').value,
removeComments: document.getElementById('removeComments').checked,
removeEmptyLines: document.getElementById('removeEmptyLines').checked,
showLineNumbers: document.getElementById('showLineNumbers').checked,
includePatterns: document.getElementById('includePatterns').value,
ignorePatterns: document.getElementById('ignorePatterns').value,
enableSecurityCheck: document.getElementById('enableSecurityCheck').checked
};
chrome.storage.sync.set(settings, function() {
const status = document.getElementById('status');
status.textContent = 'Settings saved!';
setTimeout(function() {
status.textContent = '';
}, 2000);
});
});
});
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 400px;
padding: 15px;
}
.input-group {
margin-bottom: 15px;
}
.section {
margin-bottom: 20px;
}
textarea {
width: 100%;
height: 60px;
}
.checkbox-group {
margin: 5px 0;
}
</style>
</head>
<body>
<div class="section">
<h3>Generate Repomix Command</h3>
<div class="input-group">
<label>Include Patterns:</label>
<textarea id="includePatterns"></textarea>
</div>
<div class="input-group">
<label>Ignore Patterns:</label>
<textarea id="ignorePatterns"></textarea>
</div>
<div class="checkbox-group">
<input type="checkbox" id="useStoredSettings" checked>
<label for="useStoredSettings">Use Saved Settings</label>
</div>
<button id="generate">Generate Command</button>
<button id="openSettings" style="margin-left: 10px;">Settings</button>
</div>
<div id="output" style="margin-top: 15px;"></div>
<script src="popup.js"></script>
</body>
</html>
// popup.js
document.addEventListener('DOMContentLoaded', function() {
const generateButton = document.getElementById('generate');
const outputDiv = document.getElementById('output');
const useStoredSettings = document.getElementById('useStoredSettings');
// Load saved patterns into textareas
chrome.storage.sync.get({
includePatterns: 'src/**/*.ts,**/*.md',
ignorePatterns: '**/*.log,tmp/'
}, function(items) {
document.getElementById('includePatterns').value = items.includePatterns;
document.getElementById('ignorePatterns').value = items.ignorePatterns;
});
document.getElementById('openSettings').addEventListener('click', function() {
chrome.runtime.openOptionsPage();
});
function getRepoUrlFromGitHub(url) {
try {
const githubUrl = new URL(url);
if (!githubUrl.hostname.includes('github.com')) {
return null;
}
// Split the pathname and remove empty strings
const pathParts = githubUrl.pathname.split('/').filter(part => part);
// We need at least username/repo
if (pathParts.length < 2) {
return null;
}
// Just take the username and repo name
const [username, repo] = pathParts;
return `https://github.com/${username}/${repo}`;
} catch (e) {
console.error('Error parsing GitHub URL:', e);
return null;
}
}
generateButton.addEventListener('click', async () => {
// Get the current tab
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const repoUrl = getRepoUrlFromGitHub(tab.url);
if (!repoUrl) {
outputDiv.textContent = 'Please navigate to a GitHub repository page';
return;
}
const includePatterns = document.getElementById('includePatterns').value;
const ignorePatterns = document.getElementById('ignorePatterns').value;
let command = `npx repomix --remote ${repoUrl}`;
if (useStoredSettings.checked) {
// Get stored settings
chrome.storage.sync.get({
outputStyle: 'plain',
removeComments: false,
removeEmptyLines: false,
showLineNumbers: false,
enableSecurityCheck: true
}, function(settings) {
if (settings.outputStyle !== 'plain') {
command += ` --style ${settings.outputStyle}`;
}
if (settings.removeComments) {
command += ' --remove-comments';
}
if (settings.removeEmptyLines) {
command += ' --remove-empty-lines';
}
if (settings.showLineNumbers) {
command += ' --output-show-line-numbers';
}
if (!settings.enableSecurityCheck) {
command += ' --no-security-check';
}
if (includePatterns) {
command += ` --include "${includePatterns}"`;
}
if (ignorePatterns) {
command += ` --ignore "${ignorePatterns}"`;
}
displayOutput(command);
});
} else {
if (includePatterns) {
command += ` --include "${includePatterns}"`;
}
if (ignorePatterns) {
command += ` --ignore "${ignorePatterns}"`;
}
displayOutput(command);
}
});
function displayOutput(command) {
outputDiv.innerHTML = `
<div style="margin-bottom: 10px">Command generated:</div>
<textarea readonly style="width: 100%; height: 80px">${command}</textarea>
<button id="copy" style="margin-top: 5px">Copy to Clipboard</button>
`;
document.getElementById('copy').addEventListener('click', () => {
navigator.clipboard.writeText(command);
const copyBtn = document.getElementById('copy');
copyBtn.textContent = 'Copied!';
setTimeout(() => {
copyBtn.textContent = 'Copy to Clipboard';
}, 2000);
});
}
});
@kfrancis
Copy link
Author

Just creating a little Repomix browser extension. I love using it, just trying to make it easier to use personally.

@krigeta
Copy link

krigeta commented Jan 5, 2025

this seems amazing plugin but getting this error, Please Help:

Getting this error:
npx repomix --remote https://github.com/nikahmadz/4046cf69caf4ddc68ea5e293e6afdc0e --include "src//*.ts,/.md" --ignore "**/.log,tmp/"
npm error code ERR_INVALID_URL
npm error Invalid URL
npm error A complete log of this run can be found in: C:\Users\user123_789\AppData\Local\npm-cache_logs\2025-01-05T08_00_23_247Z-debug-0.log

Log:
0 verbose cli C:\Program Files\nodejs\node.exe C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js
1 info using [email protected]
2 info using [email protected]
3 silly config load:file:C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\npmrc
4 silly config load:file:\wsl.localhost\Ubuntu\home\user123_789.npmrc
5 silly config load:file:C:\Users\user123_789.npmrc
6 silly config load:file:C:\Users\user123_789\AppData\Roaming\npm\etc\npmrc
7 verbose title npm exec repomix --remote https://github.com/nikahmadz/4046cf69caf4ddc68ea5e293e6afdc0e
8 verbose argv "exec" "--" "repomix" "--remote" "https://github.com/nikahmadz/4046cf69caf4ddc68ea5e293e6afdc0e"
9 verbose logfile logs-max:10 dir:C:\Users\user123_789\AppData\Local\npm-cache_logs\2025-01-05T08_00_23_247Z-
10 verbose logfile C:\Users\user123_789\AppData\Local\npm-cache_logs\2025-01-05T08_00_23_247Z-debug-0.log
11 silly logfile start cleaning logs, removing 3 files
12 verbose stack TypeError: Invalid URL
12 verbose stack at new URL (node:internal/url:816:29)
12 verbose stack at fromFile (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\npm-package-arg\lib\npa.js:263:15)
12 verbose stack at resolve (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\npm-package-arg\lib\npa.js:71:12)
12 verbose stack at npa (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\npm-package-arg\lib\npa.js:53:10)
12 verbose stack at FetcherBase.get (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\pacote\lib\fetcher.js:474:16)
12 verbose stack at Object.manifest (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\pacote\lib\index.js:20:29)
12 verbose stack at hasPkgBin (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\libnpmexec\lib\index.js:82:10)
12 verbose stack at exec (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\node_modules\libnpmexec\lib\index.js:137:17)
12 verbose stack at Exec.callExec (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\lib\commands\exec.js:79:12)
12 verbose stack at Exec.exec (C:\Users\user123_789\AppData\Roaming\npm\node_modules\npm\lib\commands\exec.js:28:17)
13 error code ERR_INVALID_URL
14 error Invalid URL
15 verbose cwd \wsl.localhost\Ubuntu\home\user123_789
16 verbose os Windows_NT 10.0.26100
17 verbose node v22.11.0
18 verbose npm v10.9.2
19 verbose exit 1
20 verbose code 1
21 error A complete log of this run can be found in: C:\Users\user123_789\AppData\Local\npm-cache_logs\2025-01-05T08_00_23_247Z-debug-0.log

@kfrancis
Copy link
Author

kfrancis commented Jan 6, 2025

Well, @krigeta https://github.com/nikahmadz/4046cf69caf4ddc68ea5e293e6afdc0e is not a repo url. You have to be visiting a repo and then use the extension. I didn't really play around with it too much, since the Repomix author wanted to take it and roll with it, but it worked well enough for the work I was trying to do (and made it simple). None of the config options do anything, just FYI, more just Claude spitting out options and a UI but no way of using them in that implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment