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 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
- This folder contains a high-performance, lightweight port of the ExplainThisRepo CLI tool.
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
- ## Features
7
- - **Automated Repository Analysis**: Seamlessly fetches repository data and documentation via the GitHub REST API.
8
- - **AI-Driven Contextualization**: Uses Google Gemini 2.5 Flash Lite to extract technical value and purpose from codebases.
9
- - **Senior Engineer Perspective**: Generates explanations tailored for developers, focusing on architecture, target audience, and execution.
10
- - **Markdown Generation**: Automatically outputs a clean, structured `EXPLAIN.md` file for immediate reading.
11
- - **TypeScript Core**: Built with type safety and modern asynchronous patterns for reliable performance.
5
+ It's helps developers understand unfamiliar repositories does by generating a structured `EXPLAIN.md` from real
6
+
7
+ [![PyPI Version](https://img.shields.io/pypi/v/explainthisrepo?color=blue)](https://pypi.org/project/explainthisrepo/)
8
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/explainthisrepo?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/explainthisrepo)
9
+ [![Python](https://img.shields.io/pypi/pyversions/explainthisrepo?logo=python&logoColor=white)](https://pypi.org/project/explainthisrepo/)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
11
+ [![npm version](https://img.shields.io/npm/v/explainthisrepo)](https://www.npmjs.com/package/explainthisrepo)
12
+ [![Node](https://img.shields.io/node/v/explainthisrepo)](https://www.npmjs.com/package/explainthisrepo)
13
+ [![Docs](https://img.shields.io/badge/docs-explainthisrepo.com-black)](https://explainthisrepo.com)
14
+
15
+ ---
16
+
17
+ ![demo](https://github.com/user-attachments/assets/837e0593-db64-4657-8855-bb1915011eb6)
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
- Follow these steps to set up the project locally on your machine:
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
- 1. **Clone the Repository**
18
- ```bash
19
- git clone https://github.com/calchiwo/ExplainThisRepo.git
20
- cd ExplainThisRepo/node_version
21
- ```
86
+ Alternatively,
22
87
 
23
- 2. **Install Dependencies**
24
- ```bash
25
- npm install
26
- ```
88
+ ```bash
89
+ pipx install explainthisrepo
90
+ explainthisrepo owner/repo
91
+ ```
27
92
 
28
- 3. **Set Up Environment Variables**
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
- 4. **Build the Project**
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
- npm link
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
- Once the project is built, you can use the CLI tool to analyze any public GitHub repository.
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
+ ![Quick Mode Output](assets/quick-command-output.png)
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
+ ![Detailed Mode Output](assets/detailed-command-output.png)
48
157
 
49
- ### Running the CLI
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
+ ![Simple Mode Output](assets/simple-command-output.png)
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
- node dist/cli.js facebook/react
175
+ explainthisrepo owner/repo --stack
54
176
  ```
177
+ ![Stack detector Output](assets/stack-command-output.png)
178
+
179
+ ### Version
55
180
 
56
- ### Expected Workflow
57
- 1. The tool fetches the repository description and README from GitHub.
58
- 2. It processes the information and sends a structured prompt to the Gemini AI.
59
- 3. An `EXPLAIN.md` file is generated in your current working directory containing:
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
- ### Scripts
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
- ## Contributing
188
+ ### Doctor
71
189
 
72
- Contributions are what make the open-source community an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
190
+ Check environment + connectivity (useful for debugging):
191
+ ```bash
192
+ explainthisrepo --doctor
193
+ ```
73
194
 
74
- -️ **Report Bugs**: Open an issue if you find any unexpected behavior.
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
- > Note: Please run npm run format before submitting a Pull Request to ensure code consistency.
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
- ## Author Info
240
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
241
+
242
+ ---
243
+
244
+ ## Author
84
245
 
85
- [**Caleb Wodi**](https://github.com/calchiwo)
246
+ Caleb Wodi
86
247
 
87
- Node version contibuted by [@Spectra010s](https://github.com/spectra010s)
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 (${e?.name || "Error"}: ${e?.message || e})`,
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
- console.warn(`Warning: Could not read repo files: ${e?.message || e}`);
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: ${e?.message || e}`);
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
- console.error(`error: ${e.message}`);
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
- console.error(`error: ${e?.message || e}`);
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: ${e?.message || e}`);
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
- console.warn(`Warning: Could not fetch README: ${e?.message || e}`);
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, "&lt;").replace(/>/g, "&gt;");
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.2",
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
- "prepublishOnly": "npm run build"
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"