Skip to main content

TodoScope

Working name: TodoScope is temporary. A final package and command name will be selected before publication.

TodoScope is a fast Python command-line tool for finding maintenance comments in source code. It scans real code comments for configurable markers such as TODO and prints a structured report. Deterministic scanning happens locally; an optional OpenAI step interprets only the extracted comment text — source code never leaves your machine.

todoscope src/

Features

  • Real comment detection for Python, JavaScript, TypeScript, JSX/TSX, and Rust — markers inside strings, template literals, JSX text, and raw strings are ignored (language-aware parsers, not text search).
  • Configurable markers (TODO by default), extensions, and exact-path or directory-prefix exclusions via .todoscope.json.
  • Respects the project-root .gitignore; asks for confirmation before scanning an explicitly requested ignored target.
  • Deterministic finding order (directory depth, path, line).
  • Local-first: the scanner is fully useful without any API key.
  • Optional AI analysis: one short interpretation and one estimated priority per finding plus one overall summary, using only the extracted comment text (ID, marker, text — nothing else).

Installation

Requires Python 3.12+. Recommended:

pipx install todoscope

Alternative:

python3 -m pip install todoscope

Then run:

todoscope src/

Usage

todoscope src/                 # scan a directory recursively
todoscope src/main.py          # scan one file
todoscope .                    # scan the repository root
todoscope src/ --no-ai         # normal report, skip the AI request
todoscope src/ --quiet         # one finding per line, no headings or AI
todoscope src/ --verbose       # extra scan details on stderr

Exit codes: 0 success (including local-only completion after any AI problem), 1 unexpected failure, 2 invalid path/usage or an unconfirmed ignored target in non-interactive mode, 3 configuration error.

Configuration

All configuration lives in a .todoscope.json in the project root:

{
  "markers": ["TODO", "FIXME", "HELP", "LATER"],
  "extensions": [".py", ".js", ".jsx", ".ts", ".tsx", ".rs"],
  "exclude": ["tests/fixtures/", "generated/", "src/legacy/example.py"],
  "model": "your-openai-model-id",
  "max_ai_characters": 20000
}
  • markers replaces the default list (["TODO"]). Matching is case-sensitive and prefix-based (TODO matches TODOLIST); the longest matching marker wins. Markers may contain only letters, numbers, underscores, or hyphens.
  • extensions replaces the default list. An extension without a supported parser is a configuration error.
  • exclude lists exact project-root-relative paths or directory prefixes. No wildcards.
  • model is required for AI analysis. There is no default model.
  • max_ai_characters may lower the hard payload ceiling (see below), never raise it. The hard ceiling is 100,000 characters and is not overridable.

The file contains no secrets and may be committed.

API keys

AI analysis uses the OpenAI API. Keys are read from the process environment first, then from a .env file in the project root:

TODOSCOPE_API_KEY=...
TODOSCOPE_SECONDARY_API_KEY=...
  • Shell environment variables win; .env only fills missing values.
  • A key loaded from .env is only used when .env is ignored by the project-root .gitignore; otherwise AI analysis is refused and the local report is printed.
  • Keys are never printed, logged, sent to the AI, or written into .todoscope.json. Copy .env.example and fill it in.

If the primary request fails and a secondary key is configured, an interactive terminal offers exactly one retry with the secondary key and the same model. The secondary key is never used silently, and never in non-interactive runs.

Privacy boundary

The only repository-derived data sent to the AI is each finding's scan-local ID, its marker, and its extracted comment text. The request also contains fixed TodoScope instructions and the expected response shape.

Never sent: source code, surrounding lines, file names, paths, line numbers, repository structure, Git data, configuration, environment values, or keys.

Comments are untrusted data: instructions written inside a TODO can never change TodoScope's behaviour. Never place credentials or other secrets in source comments — comment text may be sent to the AI.

AI limitations

Priorities and interpretations are estimated from comment text only. The model never sees source code, so its output can be wrong or generic. Empty or vague comments normally receive an "Unclear" priority.

Development

Development uses uv (an installed project manager, not a repository file) and Python 3.12.

uv sync                      # create/update the local environment
uv run todoscope --help      # run the command
uv run pytest                # tests
uv run ruff check .          # lint
uv run ruff format --check . # format check
uv build                     # build wheel + sdist into dist/

Documentation

Planned after 1.0: nested .gitignore support, more languages, structured JSON output, secret-pattern detection inside comments, and an explicit non-interactive ignored-target override flag.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

todoscope-0.1.0.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

todoscope-0.1.0-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file todoscope-0.1.0.tar.gz.

File metadata

  • Download URL: todoscope-0.1.0.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for todoscope-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2fea1cb5c273ca118b45651c38760a24bd70da349dae64024624ecc2c0069be2
MD5 30cfc1e968be5a22fb475f40b528cf5e
BLAKE2b-256 ceb83c965fd85757918dd7380c53073c7fa40c726a197c95b92c496961768fb1

See more details on using hashes here.

File details

Details for the file todoscope-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: todoscope-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for todoscope-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 35d6b5310438b946cb1e41c5f50b9c49837c085d3835a732696ba7d756fe5644
MD5 25b8f008562b86495ea301d330fc5dff
BLAKE2b-256 f93d9355e6d6e02e6ddd09b9cc1f8f97ca0b6d489c7fed4df20e82b8c8e93181

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page