explainthisrepo 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +220 -57
- package/dist/cli.js +15 -7
- package/dist/prompt.js +15 -12
- package/package.json +3 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Caleb Wodi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,87 +1,250 @@
|
|
|
1
1
|
# ExplainThisRepo
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
While the original Python implementation is the primary version of this tool, this Node.js port was created to provide a "zero-compilation" experience for users where Python C-extensions (like Pillow) can be difficult to build.
|
|
3
|
+
ExplainThisRepo is a CLI that generates plain-English explanations of public GitHub repositories by analyzing repository structure, README content, and selected high signal files.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
It's helps developers understand unfamiliar repositories does by generating a structured `EXPLAIN.md` from real
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/explainthisrepo/)
|
|
8
|
+
[](https://pepy.tech/projects/explainthisrepo)
|
|
9
|
+
[](https://pypi.org/project/explainthisrepo/)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://www.npmjs.com/package/explainthisrepo)
|
|
12
|
+
[](https://www.npmjs.com/package/explainthisrepo)
|
|
13
|
+
[](https://explainthisrepo.com)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Key Features
|
|
21
|
+
|
|
22
|
+
- Understand unfamiliar repositories instantly through structural and architechural summaries by turning structure and code signals into a readable architectural summary
|
|
23
|
+
- Fetches public GitHub repositories automatically
|
|
24
|
+
- Analyzes real repository data including file tree, configs, entrypoints, and high signal source files
|
|
25
|
+
- Extracts repo signals from key files (package.json, pyproject.toml, config files, entrypoints)
|
|
26
|
+
- Builds a file tree summary to understand project architecture
|
|
27
|
+
- Detects programming languages via the GitHub API
|
|
28
|
+
- Accepts repositories via owner/repo, GitHub URLs (with or without https), issue links, query strings, and SSH clone links
|
|
29
|
+
- Generates a structured plain English explanation grounded in actual project files
|
|
30
|
+
- Outputs an EXPLAIN.md file in your current directory (default mode)
|
|
31
|
+
- Multi mode command-line interface
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Modes
|
|
36
|
+
|
|
37
|
+
- (no flag) → Full repository explanation written to EXPLAIN.md
|
|
38
|
+
|
|
39
|
+
- `--quick` → One-sentence summary
|
|
40
|
+
|
|
41
|
+
- `--simple` → Short, easy explanation
|
|
42
|
+
|
|
43
|
+
- `--detailed` → Deeper explanation including structure and architecture
|
|
44
|
+
|
|
45
|
+
- `--stack` → Tech stack breakdown from repo signals
|
|
46
|
+
|
|
47
|
+
- `--version` → Show CLI version
|
|
48
|
+
|
|
49
|
+
- `--help` → Show usage guide
|
|
50
|
+
|
|
51
|
+
- `--doctor` → Check environmental health and API connectivity
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
ExplainThisRepo uses Gemini models for code analysis.
|
|
58
|
+
|
|
59
|
+
Set your API key as an environment variable.
|
|
60
|
+
|
|
61
|
+
macOS / Linux
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
export GEMINI_API_KEY="your_api_key_here"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Windows (PowerShell)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
setx GEMINI_API_KEY "your_api_key_here"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Restart your terminal after setting the key.
|
|
12
74
|
|
|
13
75
|
## Installation
|
|
14
76
|
|
|
15
|
-
|
|
77
|
+
### Option 1: install via pip (recommended):
|
|
78
|
+
|
|
79
|
+
Requirements: Python 3.9+
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install explainthisrepo
|
|
83
|
+
explainthisrepo owner/repo
|
|
84
|
+
```
|
|
16
85
|
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
git clone https://github.com/calchiwo/ExplainThisRepo.git
|
|
20
|
-
cd ExplainThisRepo/node_version
|
|
21
|
-
```
|
|
86
|
+
Alternatively,
|
|
22
87
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
88
|
+
```bash
|
|
89
|
+
pipx install explainthisrepo
|
|
90
|
+
explainthisrepo owner/repo
|
|
91
|
+
```
|
|
27
92
|
|
|
28
|
-
|
|
29
|
-
Create a `.env` file in the root directory or export the variable directly in your terminal:
|
|
30
|
-
```bash
|
|
31
|
-
export GEMINI_API_KEY=your_actual_api_key_here
|
|
32
|
-
```
|
|
93
|
+
### Option 2: Install with npm
|
|
33
94
|
|
|
34
|
-
|
|
35
|
-
Compile the TypeScript source code into executable JavaScript:
|
|
36
|
-
```bash
|
|
37
|
-
npm run build
|
|
38
|
-
```
|
|
39
|
-
5 **Link the command globally:**
|
|
95
|
+
Install globally and use forever:
|
|
40
96
|
```bash
|
|
41
|
-
|
|
42
|
-
|
|
97
|
+
npm install -g explainthisrepo
|
|
98
|
+
explainthisrepo owner/repo
|
|
99
|
+
# or: npx explainthisrepo owner/repo
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
43
103
|
|
|
104
|
+
## Flexible Repository Input
|
|
105
|
+
|
|
106
|
+
You don’t need to reformat links anymore.
|
|
107
|
+
|
|
108
|
+
ExplainThisRepo accepts GitHub repositories the way you actually copy them.
|
|
109
|
+
```bash
|
|
110
|
+
explainthisrepo https://github.com/owner/repo
|
|
111
|
+
explainthisrepo github.com/owner/repo
|
|
112
|
+
explainthisrepo https://github.com/owner/repo/issues/123
|
|
113
|
+
explainthisrepo https://github.com/owner/repo?tab=readme
|
|
114
|
+
explainthisrepo git@github.com:owner/repo.git
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
All inputs are normalized internally to owner/repo.
|
|
118
|
+
|
|
119
|
+
---
|
|
44
120
|
|
|
45
121
|
## Usage
|
|
46
122
|
|
|
47
|
-
|
|
123
|
+
### Basic
|
|
124
|
+
Generate a full explanation and saves it to `EXPLAIN.md`:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
explainthisrepo owner/repo
|
|
128
|
+
```
|
|
129
|
+
Example:
|
|
130
|
+
```bash
|
|
131
|
+
explainthisrepo facebook/react
|
|
132
|
+
```
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### Quick mode
|
|
136
|
+
|
|
137
|
+
Get a one-sentence definition (prints only, no file created):
|
|
138
|
+
```bash
|
|
139
|
+
explainthisrepo owner/repo --quick
|
|
140
|
+
```
|
|
141
|
+
Example:
|
|
142
|
+
```bash
|
|
143
|
+
explainthisrepo facebook/react --quick
|
|
144
|
+
```
|
|
145
|
+

|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### Detailed mode
|
|
150
|
+
|
|
151
|
+
Generate a more detailed explanation (includes architecture / folder structure):
|
|
152
|
+
```bash
|
|
153
|
+
explainthisrepo owner/repo --detailed
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+

|
|
48
157
|
|
|
49
|
-
|
|
50
|
-
Execute the tool by passing the `owner/repo` string as an argument:
|
|
158
|
+
---
|
|
51
159
|
|
|
160
|
+
### Simple mode
|
|
161
|
+
|
|
162
|
+
Prints only the simple output (no EXPLAIN.md)
|
|
163
|
+
```bash
|
|
164
|
+
explainthisrepo owner/repo --simple
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+

|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### Stack detector
|
|
172
|
+
|
|
173
|
+
Get a tech stack breakdown detected from repo signals. No AI explanation. Prints only.
|
|
52
174
|
```bash
|
|
53
|
-
|
|
175
|
+
explainthisrepo owner/repo --stack
|
|
54
176
|
```
|
|
177
|
+

|
|
178
|
+
|
|
179
|
+
### Version
|
|
55
180
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- Project Overview
|
|
61
|
-
- Functional Breakdown
|
|
62
|
-
- Target User Identification
|
|
63
|
-
- Setup/Execution Instructions
|
|
181
|
+
Print the installed version:
|
|
182
|
+
```bash
|
|
183
|
+
explainthisrepo --version
|
|
184
|
+
```
|
|
64
185
|
|
|
65
|
-
|
|
66
|
-
- `npm run build`: Compiles TypeScript to the `dist` folder.
|
|
67
|
-
- `npm run format`: Formats the codebase using Prettier.
|
|
68
|
-
- `npm start`: Runs the tool (requires the repository argument).
|
|
186
|
+
---
|
|
69
187
|
|
|
70
|
-
|
|
188
|
+
### Doctor
|
|
71
189
|
|
|
72
|
-
|
|
190
|
+
Check environment + connectivity (useful for debugging):
|
|
191
|
+
```bash
|
|
192
|
+
explainthisrepo --doctor
|
|
193
|
+
```
|
|
73
194
|
|
|
74
|
-
|
|
75
|
-
- **Feature Requests**: Proposals for new features are always welcome.
|
|
76
|
-
- **Pull Requests**: Ensure your code follows the existing style and all linting passes.
|
|
195
|
+
## Termux (Android) install notes
|
|
77
196
|
|
|
78
|
-
|
|
197
|
+
Termux has some environment limitations that can make `pip install explainthisrepo` fail to create the `explainthisrepo` command in `$PREFIX/bin`.
|
|
198
|
+
|
|
199
|
+
### Recommended install (Termux)
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pip install --user -U explainthisrepo
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Make sure your user bin directory is on your PATH:
|
|
206
|
+
```bash
|
|
207
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
208
|
+
```
|
|
209
|
+
> Tip: Add the PATH export to your ~/.bashrc or ~/.zshrc so it persists.
|
|
210
|
+
|
|
211
|
+
Alternative (No PATH changes)
|
|
212
|
+
|
|
213
|
+
If you do not want to modify PATH, you can run ExplainThisRepo as a module:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
python -m explain_this_repo owner/repo
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Gemini support on Termux (Optional)
|
|
220
|
+
|
|
221
|
+
Installing Gemini support may require building Rust-based dependencies on Android, which can take time on first install:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
pip install --user -U "explainthisrepo[gemini]"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Contributions
|
|
228
|
+
|
|
229
|
+
Contributions are welcome!
|
|
230
|
+
|
|
231
|
+
If you find a bug, have an idea, or want to improve the tool:
|
|
232
|
+
- See [CONTRIBUTING](CONTRIBUTING.md) for setup and guidelines
|
|
233
|
+
- Open an issue for bugs/feature requests
|
|
234
|
+
- Or submit a pull request for fixes/improvements
|
|
235
|
+
|
|
236
|
+
---
|
|
79
237
|
|
|
80
238
|
## License
|
|
81
|
-
This project is licensed under the MIT License as specified in the package configuration.
|
|
82
239
|
|
|
83
|
-
|
|
240
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Author
|
|
84
245
|
|
|
85
|
-
|
|
246
|
+
Caleb Wodi
|
|
86
247
|
|
|
87
|
-
|
|
248
|
+
- Email: caleb@explainthisrepo.com
|
|
249
|
+
- Twitter: [@calchiwo](https://x.com/calchiwo)
|
|
250
|
+
- LinkedIn: [@calchiwo](https://linkedin.com/in/calchiwo)
|
package/dist/cli.js
CHANGED
|
@@ -81,9 +81,11 @@ async function checkUrl(url, timeoutMs = 6000) {
|
|
|
81
81
|
}
|
|
82
82
|
catch (e) {
|
|
83
83
|
clearTimeout(t);
|
|
84
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
85
|
+
const name = e instanceof Error ? e.name : "Error";
|
|
84
86
|
return {
|
|
85
87
|
ok: false,
|
|
86
|
-
msg: `failed (${
|
|
88
|
+
msg: `failed (${name}: ${message})`,
|
|
87
89
|
};
|
|
88
90
|
}
|
|
89
91
|
}
|
|
@@ -108,7 +110,8 @@ async function safeReadRepoFiles(owner, repo) {
|
|
|
108
110
|
return await readRepoSignalFiles(owner, repo);
|
|
109
111
|
}
|
|
110
112
|
catch (e) {
|
|
111
|
-
|
|
113
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
114
|
+
console.warn(`Warning: Could not read repo files: ${message}`);
|
|
112
115
|
return null;
|
|
113
116
|
}
|
|
114
117
|
}
|
|
@@ -117,8 +120,9 @@ async function generateWithExit(prompt) {
|
|
|
117
120
|
return await generateExplanation(prompt);
|
|
118
121
|
}
|
|
119
122
|
catch (e) {
|
|
123
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
120
124
|
console.error("Failed to generate explanation.");
|
|
121
|
-
console.error(`error: ${
|
|
125
|
+
console.error(`error: ${message}`);
|
|
122
126
|
console.error("\nfix:");
|
|
123
127
|
console.error("- Ensure GEMINI_API_KEY is set");
|
|
124
128
|
console.error("- Or run: explainthisrepo --doctor");
|
|
@@ -173,7 +177,8 @@ Examples:
|
|
|
173
177
|
({ owner, repo } = resolveRepoTarget(repository));
|
|
174
178
|
}
|
|
175
179
|
catch (e) {
|
|
176
|
-
|
|
180
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
181
|
+
console.error(`error: ${message}`);
|
|
177
182
|
process.exit(1);
|
|
178
183
|
}
|
|
179
184
|
console.log(`Fetching ${owner}/${repo}...`);
|
|
@@ -190,7 +195,8 @@ Examples:
|
|
|
190
195
|
return;
|
|
191
196
|
}
|
|
192
197
|
catch (e) {
|
|
193
|
-
|
|
198
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
199
|
+
console.error(`error: ${message}`);
|
|
194
200
|
process.exit(1);
|
|
195
201
|
}
|
|
196
202
|
}
|
|
@@ -199,8 +205,9 @@ Examples:
|
|
|
199
205
|
repoData = await fetchRepo(owner, repo);
|
|
200
206
|
}
|
|
201
207
|
catch (e) {
|
|
208
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
202
209
|
console.error("Failed to fetch repository data.");
|
|
203
|
-
console.error(`error: ${
|
|
210
|
+
console.error(`error: ${message}`);
|
|
204
211
|
console.error("\nfix:");
|
|
205
212
|
console.error("- Ensure the repository exists and is public");
|
|
206
213
|
console.error("- Or set GITHUB_TOKEN to avoid rate limits");
|
|
@@ -211,7 +218,8 @@ Examples:
|
|
|
211
218
|
readme = await fetchReadme(owner, repo);
|
|
212
219
|
}
|
|
213
220
|
catch (e) {
|
|
214
|
-
|
|
221
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
222
|
+
console.warn(`Warning: Could not fetch README: ${message}`);
|
|
215
223
|
readme = null;
|
|
216
224
|
}
|
|
217
225
|
if (options.quick) {
|
package/dist/prompt.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
|
+
function escapeForPromptBlock(input) {
|
|
2
|
+
return input.replace(/</g, "<").replace(/>/g, ">");
|
|
3
|
+
}
|
|
1
4
|
export function buildPrompt(repoName, description, readme, detailed = false, treeText = null, filesText = null) {
|
|
2
5
|
let prompt = `You are a senior software engineer.
|
|
3
6
|
|
|
4
7
|
Your task is to explain a GitHub repository clearly and concisely for a human reader.
|
|
5
8
|
|
|
6
9
|
<repository_metadata>
|
|
7
|
-
Name: ${repoName}
|
|
8
|
-
Description: ${description || "No description provided"}
|
|
10
|
+
Name: ${escapeForPromptBlock(repoName)}
|
|
11
|
+
Description: ${escapeForPromptBlock(description || "No description provided")}
|
|
9
12
|
</repository_metadata>
|
|
10
13
|
|
|
11
14
|
<readme>
|
|
12
|
-
${readme || "No README provided"}
|
|
15
|
+
${escapeForPromptBlock(readme || "No README provided")}
|
|
13
16
|
</readme>
|
|
14
17
|
|
|
15
18
|
<repo_structure>
|
|
16
|
-
${treeText || "No file tree provided"}
|
|
19
|
+
${escapeForPromptBlock(treeText || "No file tree provided")}
|
|
17
20
|
</repo_structure>
|
|
18
21
|
|
|
19
22
|
<code_files>
|
|
20
|
-
${filesText || "No code files provided"}
|
|
23
|
+
${escapeForPromptBlock(filesText || "No code files provided")}
|
|
21
24
|
</code_files>
|
|
22
25
|
|
|
23
26
|
Instructions:
|
|
@@ -59,12 +62,12 @@ export function buildQuickPrompt(repoName, description, readme) {
|
|
|
59
62
|
Write a ONE-SENTENCE plain-English definition of what this GitHub repository is.
|
|
60
63
|
|
|
61
64
|
<repository_metadata>
|
|
62
|
-
Name: ${repoName}
|
|
63
|
-
Description: ${description || "No description provided"}
|
|
65
|
+
Name: ${escapeForPromptBlock(repoName)}
|
|
66
|
+
Description: ${escapeForPromptBlock(description || "No description provided")}
|
|
64
67
|
</repository_metadata>
|
|
65
68
|
|
|
66
69
|
<readme>
|
|
67
|
-
${readmeSnippet}
|
|
70
|
+
${escapeForPromptBlock(readmeSnippet)}
|
|
68
71
|
</readme>
|
|
69
72
|
|
|
70
73
|
Rules:
|
|
@@ -88,16 +91,16 @@ export function buildSimplePrompt(repoName, description, readme, treeText = null
|
|
|
88
91
|
Summarize this GitHub repository in a concise bullet-point format.
|
|
89
92
|
|
|
90
93
|
<repository_metadata>
|
|
91
|
-
Name: ${repoName}
|
|
92
|
-
Description: ${description || "No description provided"}
|
|
94
|
+
Name: ${escapeForPromptBlock(repoName)}
|
|
95
|
+
Description: ${escapeForPromptBlock(description || "No description provided")}
|
|
93
96
|
</repository_metadata>
|
|
94
97
|
|
|
95
98
|
<readme>
|
|
96
|
-
${readmeContent}
|
|
99
|
+
${escapeForPromptBlock(readmeContent)}
|
|
97
100
|
</readme>
|
|
98
101
|
|
|
99
102
|
<repo_structure>
|
|
100
|
-
${treeContent}
|
|
103
|
+
${escapeForPromptBlock(treeContent)}
|
|
101
104
|
</repo_structure>
|
|
102
105
|
|
|
103
106
|
Output style rules:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "explainthisrepo",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "A CLI developer tool to explain any GitHub repository in plain English",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsc",
|
|
39
39
|
"start": "node dist/cli.js",
|
|
40
|
-
"
|
|
40
|
+
"sync-meta": "cp ../README.md README.md && cp ../LICENSE LICENSE",
|
|
41
|
+
"prepublishOnly": "npm run sync-meta && npm run build"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
43
44
|
"node": ">=20"
|