explainthisrepo 0.6.0 → 0.6.2

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/README.md CHANGED
@@ -26,9 +26,9 @@ It helps developers quickly understand unfamiliar codebases by deriving architec
26
26
  - Builds a file tree summary to understand project architecture
27
27
  - Detects programming languages with the GitHub API
28
28
  - Analyzes local project directories using the same pipeline as GitHub repositories
29
- - Generates a structured plain English explanation grounded in actual project files
30
- - Outputs the explanation to an `EXPLAIN.md` file in your current directory or print it directly in the terminal
31
- - Multi mode command-line interface
29
+ - Generates a structured plain-English explanation grounded in actual project files
30
+ - Outputs the explanation to an `EXPLAIN.md` file in your current directory or prints it directly in the terminal
31
+ - Multi-mode command-line interface
32
32
 
33
33
  ---
34
34
 
@@ -54,9 +54,21 @@ It helps developers quickly understand unfamiliar codebases by deriving architec
54
54
 
55
55
  ## Configuration
56
56
 
57
- ExplainThisRepo uses Gemini models for code analysis.
57
+ ExplainThisRepo requires a Google Gemini API key for code analysis.
58
58
 
59
- Set your Google Gemini API key as an environment variable.
59
+ ### Quick setup (recommended)
60
+
61
+ Use the built-in `init` command to securely store your API key:
62
+
63
+ ```bash
64
+ explainthisrepo init
65
+ # or npx explainthisrepo init
66
+ ```
67
+ > For details about how initialization works, see [INIT.md](INIT.md).
68
+
69
+ ### Environment variable (manual setup)
70
+
71
+ If you prefer not to use the `init` command, you can also configure the API key using an environment variable
60
72
 
61
73
  Linux / macOS
62
74
 
package/dist/cli.js CHANGED
@@ -64,9 +64,6 @@ function getPkgVersion() {
64
64
  return "unknown";
65
65
  }
66
66
  }
67
- function printVersion() {
68
- console.log(getPkgVersion());
69
- }
70
67
  function hasEnv(key) {
71
68
  const v = process.env[key];
72
69
  return Boolean(v && v.trim());
@@ -130,44 +127,7 @@ async function generateWithExit(prompt) {
130
127
  process.exit(1);
131
128
  }
132
129
  }
133
- async function main() {
134
- const program = new Command();
135
- program
136
- .name("explainthisrepo")
137
- .description("CLI that generates plain English explanations of any codebase")
138
- .version(getPkgVersion(), "-v, --version", "Show version")
139
- .argument("[repository]", "GitHub repository (owner/repo or URL) or local directories")
140
- .option("--doctor", "Run diagnostics")
141
- .option("--quick", "Quick summary mode")
142
- .option("--simple", "Simple summary mode")
143
- .option("--detailed", "Detailed explanation mode")
144
- .option("--stack", "Stack detection mode")
145
- .addHelpText("after", `
146
- Examples:
147
- $ explainthisrepo owner/repo
148
- $ explainthisrepo https://github.com/owner/repo
149
- $ explainthisrepo github.com/owner/repo
150
- $ explainthisrepo git@github.com:owner/repo.git
151
- $ explainthisrepo owner/repo --detailed
152
- $ explainthisrepo owner/repo --quick
153
- $ explainthisrepo owner/repo --simple
154
- $ explainthisrepo owner/repo --stack
155
- $ explainthisrepo .
156
- $ explainthisrepo ./path/to/directory
157
- $ explainthisrepo . --stack
158
- $ explainthisrepo --doctor`);
159
- program
160
- .command("init")
161
- .description("Initialize configuration with Gemini API key")
162
- .action(async () => {
163
- await runInit();
164
- });
165
- program.parse(process.argv);
166
- if (process.argv[2] === "init") {
167
- return;
168
- }
169
- const options = program.opts();
170
- const repository = program.args[0];
130
+ async function runAnalysis(repository, options) {
171
131
  if (options.doctor) {
172
132
  const code = await runDoctor();
173
133
  process.exit(code);
@@ -182,9 +142,6 @@ Examples:
182
142
  console.error("error: only one mode flag can be used at a time");
183
143
  process.exit(1);
184
144
  }
185
- if (!repository) {
186
- program.error("repository argument required (or use `init` to set up API key)");
187
- }
188
145
  const local = fs.existsSync(repository);
189
146
  let owner = "";
190
147
  let repo = "";
@@ -329,4 +286,46 @@ Examples:
329
286
  console.log(`Words: ${wordCount}`);
330
287
  console.log("Open EXPLAIN.md to read it.");
331
288
  }
332
- main();
289
+ const program = new Command();
290
+ program
291
+ .name("explainthisrepo")
292
+ .description("CLI that generates plain English explanations of any codebase")
293
+ .version(getPkgVersion(), "-v, --version", "Show version")
294
+ .argument("[repository]", "GitHub repository (owner/repo or URL) or local directories")
295
+ .option("--doctor", "Run diagnostics")
296
+ .option("--quick", "Quick summary mode")
297
+ .option("--simple", "Simple summary mode")
298
+ .option("--detailed", "Detailed explanation mode")
299
+ .option("--stack", "Stack detection mode")
300
+ .addHelpText("after", `
301
+ Examples:
302
+ $ explainthisrepo owner/repo
303
+ $ explainthisrepo https://github.com/owner/repo
304
+ $ explainthisrepo github.com/owner/repo
305
+ $ explainthisrepo git@github.com:owner/repo.git
306
+ $ explainthisrepo owner/repo --detailed
307
+ $ explainthisrepo owner/repo --quick
308
+ $ explainthisrepo owner/repo --simple
309
+ $ explainthisrepo owner/repo --stack
310
+ $ explainthisrepo .
311
+ $ explainthisrepo ./path/to/directory
312
+ $ explainthisrepo . --stack
313
+ $ explainthisrepo --doctor`)
314
+ .action(async (repository, options) => {
315
+ if (options.doctor) {
316
+ const code = await runDoctor();
317
+ process.exit(code);
318
+ }
319
+ if (!repository) {
320
+ program.error("repository argument required (or use `init` to set up API key)");
321
+ return;
322
+ }
323
+ await runAnalysis(repository, options);
324
+ });
325
+ program
326
+ .command("init")
327
+ .description("Initialize configuration with Gemini API key")
328
+ .action(async () => {
329
+ await runInit();
330
+ });
331
+ program.parseAsync(process.argv);
package/dist/init.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import readline from "node:readline";
2
2
  import process from "node:process";
3
- import { stdin as input, stderr as output } from "node:process";
4
3
  import chalk from "chalk";
5
4
  import { writeConfig } from "./config.js";
6
5
  const CONFIG_TEMPLATE = `[llm]
@@ -8,33 +7,38 @@ provider = "gemini"
8
7
  api_key = "{api_key}"
9
8
  `;
10
9
  export async function runInit() {
11
- output.write(chalk.yellow("WARNING: input is hidden. Paste your GEMINI_API_KEY and press Enter.\n"));
10
+ const err = process.stderr;
11
+ err.write(chalk.yellow("WARNING: input is hidden. Paste your GEMINI_API_KEY and press Enter.\n\n"));
12
12
  try {
13
13
  const apiKey = (await promptHidden("Gemini API key: ")).trim();
14
14
  if (!apiKey) {
15
- output.write(chalk.red("error: API key cannot be empty\n"));
15
+ err.write(chalk.red("error: API key cannot be empty\n"));
16
16
  process.exit(1);
17
17
  }
18
18
  writeConfig(CONFIG_TEMPLATE.replace("{api_key}", apiKey));
19
- output.write(chalk.green("Configuration written.\n"));
19
+ err.write("\r");
20
+ err.write("\x1b[2K");
21
+ err.write(chalk.green("Configuration written.\n"));
20
22
  process.exit(0);
21
23
  }
22
24
  catch {
23
- output.write(chalk.red("\nInterrupted.\n"));
25
+ err.write(chalk.red("\nInterrupted.\n"));
24
26
  process.exit(130);
25
27
  }
26
28
  }
27
- function promptHidden(prompt) {
29
+ function promptHidden(label) {
30
+ const err = process.stderr;
28
31
  return new Promise((resolve) => {
32
+ err.write(label);
29
33
  const rl = readline.createInterface({
30
- input,
31
- output,
34
+ input: process.stdin,
35
+ output: undefined,
32
36
  terminal: true,
33
37
  });
34
38
  rl._writeToOutput = () => { };
35
- rl.question(prompt, (answer) => {
39
+ rl.question("", (answer) => {
36
40
  rl.close();
37
- output.write("\n");
41
+ err.write("\n");
38
42
  resolve(answer);
39
43
  });
40
44
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "explainthisrepo",
3
- "version": "0.6.0",
4
- "description": "CLI that generates plain English explanations of any codebase",
3
+ "version": "0.6.2",
4
+ "description": "CLI that generates plain-English explanations of any codebase",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "author": "Caleb Wodi <calebwodi33@gmail.com>",