RepoPilotOpen in app →

gleitz/howdoi

instant coding answers via the command line

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3w ago
  • 11 active contributors
  • MIT licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 61% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/gleitz/howdoi)](https://repopilot.app/r/gleitz/howdoi)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/gleitz/howdoi on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: gleitz/howdoi

Generated by RepoPilot · 2026-05-07 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/gleitz/howdoi shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3w ago
  • 11 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 61% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live gleitz/howdoi repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/gleitz/howdoi.

What it runs against: a local clone of gleitz/howdoi — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in gleitz/howdoi | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 52 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>gleitz/howdoi</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of gleitz/howdoi. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/gleitz/howdoi.git
#   cd howdoi
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of gleitz/howdoi and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "gleitz/howdoi(\\.git)?\\b" \\
  && ok "origin remote is gleitz/howdoi" \\
  || miss "origin remote is not gleitz/howdoi (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "howdoi/howdoi.py" \\
  && ok "howdoi/howdoi.py" \\
  || miss "missing critical file: howdoi/howdoi.py"
test -f "howdoi/__main__.py" \\
  && ok "howdoi/__main__.py" \\
  || miss "missing critical file: howdoi/__main__.py"
test -f "howdoi/__init__.py" \\
  && ok "howdoi/__init__.py" \\
  || miss "missing critical file: howdoi/__init__.py"
test -f "howdoi/errors.py" \\
  && ok "howdoi/errors.py" \\
  || miss "missing critical file: howdoi/errors.py"
test -f "mkdocs.yml" \\
  && ok "mkdocs.yml" \\
  || miss "missing critical file: mkdocs.yml"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 52 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~22d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/gleitz/howdoi"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

howdoi is a command-line tool that answers programming questions instantly by scraping Stack Overflow and returning concise code snippets without opening a browser. It's a Python CLI that takes natural language queries like 'howdoi format date bash' and returns executable code examples directly in your terminal. Hybrid monorepo structure: the core Python package (howdoi/) provides CLI and scraping logic, while extension/code-editor-integration/ contains a TypeScript plugin system (plugin.ts, plugin_interfaces.ts) for IDE integration. The extension/vscode-howdoi/ directory suggests a separate VS Code extension package, with docs/ holding user-facing guides.

👥Who it's for

Developers who frequently switch between coding and searching for solutions—especially those in terminal-heavy workflows (DevOps, backend engineers, Linux/macOS users) who want to avoid context-switching to browsers and documentation sites.

🌱Maturity & risk

Production-ready with active maintenance: the repo has GitHub Actions CI/CD workflows for Python and Node.js (python.yml, node.js.yml), comprehensive documentation in docs/, and multi-platform support (pip, brew). The codebase spans 51k Python lines with TypeScript extensions, indicating a mature, feature-rich project.

Low to moderate risk: single maintainer (gleitz) could bottleneck decisions, but the project has established CI/CD and community issue templates suggesting some process maturity. Dependencies appear minimal in package.json (only dev dependencies listed), reducing supply-chain risk, though web scraping from Stack Overflow is fragile and subject to markup changes.

Active areas of work

No recent activity is visible from the file list alone, but the repo maintains active CI workflows (python.yml, python-non-master.yml, early-warning.yml) and issue templates suggesting ongoing triage. The presence of .pre-commit-config.yaml and strict linting config (.pylintrc, .flake8) indicates active code quality standards.

🚀Get running

git clone https://github.com/gleitz/howdoi.git && cd howdoi && pip install -e . && howdoi format date bash

Daily commands: After installation: howdoi [QUERY] (e.g., howdoi print stack trace python). For extension development: cd extension/code-editor-integration && npm install && npm run build.

🗺️Map of the codebase

  • howdoi/howdoi.py — Core engine that handles question parsing, search, answer extraction, and caching logic—the heart of the CLI tool
  • howdoi/__main__.py — Entry point for the CLI; defines argument parsing and orchestrates the main request flow
  • howdoi/__init__.py — Package initialization and public API exports for both CLI and programmatic use
  • howdoi/errors.py — Custom exception classes used throughout the codebase for error handling and debugging
  • mkdocs.yml — Documentation configuration; defines user-facing feature documentation and contribution guides
  • .flake8 — Code style enforcement rules; establishes linting standards every contributor must follow
  • extension/code-editor-integration/src/plugin.ts — Core plugin interface for editor integrations; implements the bridge between IDE and howdoi backend

🧩Components & responsibilities

  • main.py (argparse, sys, os) — Parse CLI arguments, validate inputs, invoke core query logic, format and output results
    • Failure mode: Invalid arguments → show help; network error → return None; malformed query → exit with error code
  • howdoi.py (requests, BeautifulSoup, gzip, re (regex)) — Execute search queries, extract answers from HTML, manage page cache, apply post-processing filters
    • Failure mode: No results found → raise SearchException; parsing fails → return empty string; cache corrupt → re-fetch from web
  • errors.py (Python exception hierarchy) — Define domain-specific exceptions for search failures, network issues, and parsing errors
    • Failure mode: Enables clean error handling and user-friendly error messages in main.py
  • VSCode extension (extension.ts) (VS Code API, TypeScript, IPC to Node subprocess) — Hook into editor UI, capture selected text, invoke howdoi backend, display results in webview or status bar
    • Failure mode: Backend unavailable → show 'howdoi not installed' warning; parsing error → display raw error in editor UI
  • Page cache (gzip, file I/O, hash-based indexing) — Store gzipped HTML responses indexed by query hash to avoid redundant network requests
    • Failure mode: Cache miss → fetch from web and store; corrupted .gz file → re-fetch; disk full → silently skip cache write

🔀Data flow

  • User CLI input__main__.py argument parser — Raw question string and optional flags (--all, --no-cache, --color, etc.)
  • __main__.pyhowdoi.py query() function — Validated question, filter flags, and cache policy
  • howdoi.pypage_cache/ — Check for cached HTML before making new network request
  • howdoi.pySearch engine (DuckDuckGo/Google) — Outbound HTTP POST/GET with question as search term
  • Search enginehowdoi.py — Raw HTML search results page
  • undefinedundefined — undefined

🛠️How to make changes

Add a New Command-Line Flag

  1. Define the argument in the argument parser setup within main.py (howdoi/__main__.py)
  2. Add the corresponding logic branch in the main execution function in howdoi.py to handle the new flag (howdoi/howdoi.py)
  3. Update the usage documentation to describe the new flag (docs/usage.md)

Add a New Editor Integration (e.g., Sublime, Vim)

  1. Implement the plugin interface defined in plugin_interfaces.ts (extension/code-editor-integration/src/plugin_interfaces.ts)
  2. Create your editor-specific plugin extending the base plugin class (extension/code-editor-integration/src/plugin.ts)
  3. Add build configuration (e.g., package.json for Node-based editors) in the extension directory (extension/code-editor-integration/package.json)
  4. Document the installation and usage steps for your new integration (docs/extension_dev.md)

Improve Search or Answer Extraction Logic

  1. Modify the search engine integration or parsing functions in howdoi.py (howdoi/howdoi.py)
  2. Define or update custom exceptions in errors.py if new error cases emerge (howdoi/errors.py)
  3. Update linting/code style rules if new patterns are introduced (.flake8)
  4. Verify changes pass CI/CD checks as defined in the workflow (.github/workflows/python.yml)

🔧Why these technologies

  • Python + Click/argparse — Fast CLI tool development; minimal dependencies for a terminal-first experience
  • DuckDuckGo/Google search API — Free, no API key required; allows instant answers without OAuth setup
  • BeautifulSoup/lxml for parsing — Reliable HTML parsing for extracting code snippets from StackOverflow and other sites
  • Gzip-compressed page cache — Reduces disk I/O and storage footprint for frequently-accessed answers
  • TypeScript for editor extensions — Type safety and code reuse across VSCode and future editor integrations

⚖️Trade-offs already made

  • Web scraping vs. official APIs

    • Why: No StackOverflow API authentication overhead; instant setup for users
    • Consequence: Fragile to site layout changes; requires maintenance when SE updates HTML structure
  • Local gzip cache vs. cloud cache

    • Why: Works offline; no external service dependency; privacy-friendly
    • Consequence: Cache invalidation is manual; stale answers possible; no cross-device sync
  • Single Python process vs. daemon/service

    • Why: Zero setup; works immediately from shell; simple installation
    • Consequence: No persistent state between calls; cold start time on first query

🚫Non-goals (don't propose these)

  • Real-time collaborative coding assistance
  • User authentication or personalized learning profiles
  • Integration with proprietary IDE closed ecosystems (without open plugin APIs)
  • Machine learning-based answer ranking (all results are browser-scraped, not ML-ranked)
  • Offline-first mode without pre-cached data
  • Support for non-English Q&A sites by default

🪤Traps & gotchas

Stack Overflow HTML markup is not versioned in this repo—scraping will break silently if SO changes their DOM; no caching layer visible in file list, so queries hit the network every time unless memoized externally. TypeScript plugin system requires tsc compilation before running (see package.json 'compile' script). Python package requires 'pip install -e .' for editable development mode to pick up local changes. IDE extension development requires separate npm install in extension/code-editor-integration/—parent node_modules won't work.

🏗️Architecture

💡Concepts to learn

  • Web Scraping & DOM Parsing — howdoi's core capability is scraping Stack Overflow's HTML; understanding BeautifulSoup or similar parsing is essential to maintaining the scraper when SO's markup changes
  • CLI Argument Parsing (argparse) — The README shows complex argument handling (howdoi [-h] [-p POS] [-n NUM] [-a] [-l] [-c] [-x] [-C] [-j] [-v] [-e [ENGINE]] ...); understanding Python's argparse is required to modify command syntax
  • Plugin Architecture (TypeScript interfaces) — The extension/code-editor-integration/ uses plugin_interfaces.ts to define how IDE integration works; understanding this pattern is crucial for extending howdoi into new editors
  • Regex-based Text Transformation — extension/code-editor-integration/src/remove_regexes.ts suggests howdoi sanitizes code snippets with regex; understanding regex is needed to debug or extend output formatting
  • GitHub Actions CI/CD — The repo uses .github/workflows/ for automated testing and deployment; any change requires passing python.yml and python-non-master.yml workflows
  • TypeScript Compilation & Type Safety — The extension uses TypeScript with tsconfig.json; contributers must understand tsc compilation, interfaces, and type checking to modify IDE plugins
  • Pre-commit Hooks — .pre-commit-config.yaml enforces code style before commits; understanding pre-commit ensures local changes pass CI without failed pushes
  • sindresorhus/tldr — Similar CLI tool that serves cheat sheets instead of Stack Overflow; competes for same audience (developers who want fast terminal-based answers)
  • cheat/cheat — Python-based cheat sheet CLI with community-contributed snippets; alternative to howdoi's web-scraping approach with offline-first design
  • Microsoft/vscode — howdoi has an extension/vscode-howdoi/ package targeting VS Code; understanding VS Code's extension API is required to maintain it
  • jqlang/jq — Command-line JSON query tool often featured in howdoi results; commonly paired with howdoi queries for data wrangling answers
  • pytorch/pytorch — Example of a mature Python project with similar CI/CD patterns (GitHub Actions, linting gates, docs/); good reference for Pythonic packaging standards

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add TypeScript unit tests for code-editor-integration plugin modules

The extension/code-editor-integration/src/test/ directory only contains a single test file. The modules create_attributes.ts, find_attributes.ts, and remove_regexes.ts lack corresponding unit tests. This is critical for a plugin that modifies code, as bugs could corrupt user files. Adding comprehensive test coverage for these core transformation functions will improve reliability and make contributions safer.

  • [ ] Create extension/code-editor-integration/src/test/create_attributes.test.ts with tests for attribute creation logic
  • [ ] Create extension/code-editor-integration/src/test/find_attributes.test.ts with tests for regex matching and attribute detection
  • [ ] Create extension/code-editor-integration/src/test/remove_regexes.test.ts with tests for regex removal edge cases
  • [ ] Ensure all tests pass with npm test and verify coverage is >80%
  • [ ] Update extension/code-editor-integration/README.md to document test execution

Add GitHub Actions workflow for Node.js code-editor-integration CI/CD

The repo has multiple Python CI workflows (.github/workflows/python.yml, python-non-master.yml) but the Node.js workflow (.github/workflows/node.js.yml) appears minimal or outdated. The extension/code-editor-integration/ subdirectory with TypeScript, linting, and tests needs a dedicated CI pipeline to catch regressions. This ensures the VSCode extension and plugin remain stable across commits.

  • [ ] Review existing .github/workflows/node.js.yml and determine if it covers extension/ directory
  • [ ] Create or update workflow to run npm install && npm run lint && npm run compile && npm test in extension/code-editor-integration/
  • [ ] Configure workflow to also test extension/vscode-howdoi/ with npm install && npm run compile
  • [ ] Ensure workflow triggers on pushes to main/master and pull requests affecting extension/**
  • [ ] Add status badge to extension/code-editor-integration/README.md

Document extension/vscode-howdoi development setup and testing procedures

The docs/extension_dev.md file exists but the VSCode extension project in extension/vscode-howdoi/ lacks internal documentation. Contributors cannot easily understand how to test the extension locally, run the test suite (extension/vscode-howdoi/src/test/), or debug it in VSCode. This creates friction for contributors wanting to improve the editor integration.

  • [ ] Create extension/vscode-howdoi/DEVELOPMENT.md with prerequisites (Node.js version, VSCode API version)
  • [ ] Document how to run npm install, compile TypeScript, and launch the extension in VSCode debug mode
  • [ ] Document the test structure in extension/vscode-howdoi/src/test/suite/ and how to run tests with npm test
  • [ ] Include debugging tips (setting breakpoints in VSCode, using the Extension Development Host)
  • [ ] Link DEVELOPMENT.md from the main docs/extension_dev.md and extension/vscode-howdoi/README.md

🌿Good first issues

  • Add integration tests for the TypeScript plugin system in extension/code-editor-integration/src/test/ (currently only plugin.test.ts exists; test coverage for find_attributes.ts, create_attributes.ts, remove_regexes.ts is missing)
  • Document the Stack Overflow scraping logic and query format in docs/extension_dev.md or create a new docs/architecture.md explaining how howdoi parses SO responses (useful for future maintainers when SO changes markup)
  • Add Windows-specific examples to docs/windows-contributing.md and test the CLI on Windows in CI (docs/windows-contributing.md exists but may be outdated; a fresh contributor could validate and update for current Python/pip practices)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 033dd3c — Merge pull request #499 from torzsmokus/patch-1 (gleitz)
  • 6237a19 — add missing line break to doc (torzsmokus)
  • af1ce83 — Merge pull request #497 from ilaumjd/fix/remove-bad-test-case (gleitz)
  • 7d24e9e — fix: remove bad test case (ilaumjd)
  • 6f8813d — Merge pull request #491 from dizzygz/master (gleitz)
  • 1dc6cde — update 2 places for int and str operations (dizzygz)
  • 96ac611 — Update download count in README (gleitz)
  • 7bbafb7 — Merge pull request #484 from gleitz/dependabot/pip/requirements/requests-2.31.0 (gleitz)
  • c2de314 — Bump requests from 2.27.1 to 2.31.0 in /requirements (dependabot[bot])
  • 659e370 — Fix typo in pull request template (gleitz)

🔒Security observations

The howdoi codebase has moderate security concerns, primarily related to severely outdated dependencies in the TypeScript/Node.js components (dating to 2019-2020). The Python component's security posture is not fully visible, but the presence of cached HTML files without validation and lack of documented security policies present additional risks. Immediate action is required to update all dependencies, implement automated security scanning in CI/CD pipelines, and establish security governance practices. The codebase lacks evident injection vulnerabilities or hardcoded secrets based on available files, but dependency vulnerabilities pose significant supply chain risk.

  • High · Outdated TypeScript Development Dependencies — extension/code-editor-integration/package.json. The code-editor-integration package.json uses outdated TypeScript versions (^3.5.3) and associated tooling from 2019-2020. These versions contain known security vulnerabilities and lack security patches. TypeScript 3.5.3 was released in June 2019 and is severely outdated. Fix: Update TypeScript to version ^5.0.0 or latest stable. Update @typescript-eslint/* packages to latest versions (currently pinned to 3.9.0/3.4.0 from 2020). Review and update all other devDependencies to current versions.
  • High · Vulnerable Mocha Version — extension/code-editor-integration/package.json. The package.json specifies mocha ^10.1.0, but the package history shows versions 10.x were released much later. However, the lock file likely has an older version. Cross-env ^5.2.0 is also outdated (from 2019) and should be updated to ^7.x. Fix: Update cross-env to ^7.0.0 or latest. Ensure mocha is updated to latest stable version (14.x+). Use 'npm audit' and 'npm audit fix' to identify and resolve known vulnerabilities.
  • Medium · Missing Package-lock.json Review — extension/code-editor-integration/package-lock.json, extension/vscode-howdoi/package-lock.json. The codebase includes package-lock.json files but no evidence of dependency scanning in CI/CD. With severely outdated dependencies visible in package.json, transitive dependencies are likely vulnerable. Fix: Implement automated dependency scanning in GitHub Actions (npm audit, Snyk, or Dependabot). Add 'npm audit' as a mandatory CI check. Regularly update dependencies according to a schedule.
  • Medium · Web Cache Directory with Unverified Content — page_cache/. The 'page_cache' directory contains cached HTML files (.html.gz) with names derived from URLs. These cached pages could contain malicious content if scraped from untrusted sources, and there's no validation of cache integrity. Fix: Implement cache validation and sanitization. Consider using a cryptographic hash to verify cache contents. Document the cache invalidation strategy. Consider not committing cache files to version control; use .gitignore for cache directories.
  • Medium · No Security Policy Documented — Repository root. While GitHub issue templates exist, there is no SECURITY.md file documenting vulnerability disclosure policy or security contact information. Fix: Create a SECURITY.md file following GitHub's security policy template. Include instructions for responsible disclosure and security contact information.
  • Low · Hardcoded Configuration Patterns — .flake8, .mypy.ini, .pylintrc, .pre-commit-config.yaml. Multiple configuration files present (.flake8, .mypy.ini, .pylintrc) but without explicit evidence of credential exposure. However, best practices suggest reviewing these for any hardcoded sensitive values. Fix: Audit all configuration files to ensure no credentials, API keys, or sensitive tokens are hardcoded. Use environment variables or secret management tools for sensitive configuration.
  • Low · Missing CODEOWNERS File — Repository root. No CODEOWNERS file found to manage code review requirements and security oversight for critical files. Fix: Create a .github/CODEOWNERS file to enforce security reviews on critical components (main howdoi module, extension integration points).

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · gleitz/howdoi — RepoPilot