Skip to main content
Home

Transform simple TODO comments into structured, Codex-ready task briefs using AI.

This package works with Node.js, Deno, Browsers
This package works with Node.js
This package works with Deno
This package works with Browsers
JSR Score
94%
Published
2 months ago (1.0.3)

TODO Expander

Transform simple TODO comments into structured, Codex-ready task briefs using AI.

Migration notice

  • This project now publishes only under organization scopes:
    • NPM: @openminds-it-lab/todo-expander
    • JSR: jsr:@openminds-it-lab/todo-expander
  • Legacy packages (@saladin/todo-expander on JSR and unscoped todo-expander on NPM) have been deprecated/yanked.
  • If you previously installed the legacy NPM package globally, uninstall it before installing the scoped one:
    • npm uninstall -g todo-expander
    • npm install -g @openminds-it-lab/todo-expander

Docs

  • docs/ARCHITECTURE.md: Pipeline and design overview
  • docs/MODULES.md: Module-by-module reference

Overview

TODO Expander is a Deno-based CLI tool that automatically converts plain TODO comments into detailed, structured specifications that are ready for AI coding assistants. Instead of vague // TODO: fix this later, get comprehensive briefs with Context, Goal, Steps, Constraints, and Acceptance criteria.

Before

// TODO: Extract time formatting utility

After

// TODO: Extract time formatting utility
// Context
// - React + TypeScript; current formatter is inline and reused across views.
// Goal
// - Move the mm:ss formatter into src/utils/datetime.ts as a named export.
// Steps
// 1) Create src/utils/datetime.ts with: export const formatTime = (seconds: number): string => { /* same logic */ }
// 2) Replace local usage with: import { formatTime } from '../utils/datetime'
// 3) Remove the local function.
// 4) Add tests for: 0->"00:00", 5->"00:05", 65->"01:05", 3599->"59:59".
// Constraints
// - Pure function; no Date APIs; keep padStart semantics.
// Acceptance
// - Type-checks and tests pass; UI timer unchanged; no new warnings.

Features

  • 🤖 AI-Powered: Uses OpenAI's GPT models to intelligently expand TODOs
  • 🎯 Context-Aware: Analyzes surrounding code for better understanding
  • 💾 Smart Caching: Avoids redundant API calls with FNV-1a hashing
  • 🔄 Git Integration: Works seamlessly with staged files
  • 📝 Comment Preservation: Maintains original comment style (//, #, /* */)
  • Parallel Processing: Concurrent API requests for better performance
  • 🎨 Auto-Formatting: Optionally formats modified files after processing
  • 🔍 Dry Run: Preview changes before applying them

Installation

Prerequisites

  • OpenAI API key
  • Choose your runtime:
    • Deno: Deno (v2.0 or later) for JSR
    • Node.js: Node.js (v18 or later) for NPM

Package Managers (Recommended)

JSR (Deno)

# Import as library
deno add jsr:@openminds-it-lab/todo-expander

# Use in your code
import { processFile } from "jsr:@openminds-it-lab/todo-expander";

NPM (Node.js)

# Install globally for CLI access
npm install -g @openminds-it-lab/todo-expander
todo-expand --help

# Or install locally in your project
npm install @openminds-it-lab/todo-expander
npx todo-expand --help

GitHub Releases (Cross-platform binaries)

# Download binary for your platform from:
# https://github.com/OpenMindS-IT-Lab/todo-expander/releases

# macOS ARM64 example:
wget https://github.com/OpenMindS-IT-Lab/todo-expander/releases/latest/download/todo-expand-v0.1.0-macos-arm64
chmod +x todo-expand-v0.1.0-macos-arm64
sudo mv todo-expand-v0.1.0-macos-arm64 /usr/local/bin/todo-expand

Development Setup

# Clone the repository
git clone https://github.com/OpenMindS-IT-Lab/todo-expander.git
cd todo-expander

# Run directly with Deno
deno run -A bin/todo-expand.ts --help

# Or use the task runner
deno task todo:file path/to/file.ts

# Build local binary
deno task build:cli

Usage

Setup

Export your OpenAI API key:

export OPENAI_API_KEY="your-api-key-here"

Basic Commands

# Process all staged files
todo-expand --staged

# Process specific files
todo-expand src/components/App.tsx src/utils/helpers.ts

# Dry run (preview changes without writing)
todo-expand --staged --dry-run

# Use different model
OPENAI_MODEL=gpt-4 todo-expand --staged

Advanced Options

# Custom file extensions and exclusions
todo-expand --include=ts,js,py --exclude=test,spec --staged

# Verbose output with custom sections
todo-expand --style=verbose --sections="Context,Goal,Implementation,Testing" file.ts

# Skip caching and formatting
todo-expand --no-cache --no-format --staged

# Adjust context and concurrency
todo-expand --context-lines=20 --concurrency=5 --staged

Configuration

Quick Setup

# Initialize config in your project
todo-expand init

# View merged configuration
todo-expand --print-config

Configuration Files

Todo-expander supports layered configuration with the following precedence (highest to lowest):

  1. CLI flags (e.g., --style=verbose)
  2. Environment variables (e.g., TODO_EXPAND_STYLE=verbose)
  3. Project config (.todoexpandrc.json in current directory)
  4. Global config (~/.config/todo-expand/config.json)
  5. Default values

Project Configuration

Create a .todoexpandrc.json file in your project root with IntelliSense support:

{
  "$schema": "https://raw.githubusercontent.com/OpenMindS-IT-Lab/todo-expander/main/schema/todoexpand.schema.json",
  "style": "verbose",
  "include": ["ts", "tsx", "js", "jsx"],
  "exclude": ["node_modules", "build", "dist", ".git"],
  "concurrency": 2,
  "timeout": 30000,
  "cache": true
}

The $schema property enables:

  • IntelliSense in VS Code and other editors
  • Type validation and error highlighting
  • Documentation on hover
  • Auto-completion of property names and values

Init Command

Bootstrap configuration quickly with templates:

# Auto-detect project type and create config
todo-expand init

# Use specific template
todo-expand init --template=monorepo
todo-expand init --template=non-git

# Skip package.json script updates
todo-expand init --skip-package-json

# Overwrite existing config
todo-expand init --force

Available templates:

  • base: Standard single-repository project (default)
  • monorepo: Multi-language repository with higher concurrency
  • non-git: Non-git project with caching disabled

Environment Variables

Variable Required Default Description
OPENAI_API_KEY Yes - OpenAI API key for LLM calls
OPENAI_MODEL No gpt-4o-mini Model to use
TODO_EXPAND_DRY No - Set to 1 for dry-run mode

CLI Flags

Flag Description Default
--staged Process only git-staged files -
--dry-run, -n Preview changes without writing false
--no-cache Skip response caching false
--no-format Skip code formatting after rewrite false
--include=ext1,ext2 File extensions to include ts,tsx,js,jsx
--exclude=dir1,dir2 Directories to exclude node_modules,build,dist,.git
--style=succinct|verbose Output style preference succinct
--sections=Context,Goal,Steps Custom section names Context,Goal,Steps,Constraints,Acceptance
--context-lines=N Lines of code context to include 12
--concurrency=N Parallel LLM requests 3

TODO Detection

The tool automatically detects and processes these TODO formats:

Supported Formats

// TODO: Single-line JavaScript/TypeScript comment
# TODO: Python/shell comment
/* TODO: Block comment */
/* TODO:
   Multi-line block comment
*/

Skipped TODOs

Already structured TODOs containing these keywords are skipped:

  • AI TASK
  • Context
  • Goal
  • Steps
  • Constraints
  • Acceptance

Integration

Git Hooks

Set up automatic TODO expansion on commit:

# Set global hooks directory
git config --global core.hooksPath ~/.git-hooks
mkdir -p ~/.git-hooks

# Create pre-commit hook
cat > ~/.git-hooks/pre-commit <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
# Skip if repo opted out
if [ -f .no-todo-expand ]; then exit 0; fi
# Expand TODOs in staged files
if command -v todo-expand >/dev/null 2>&1; then
  todo-expand --staged || true
  git add -A
fi
EOF

chmod +x ~/.git-hooks/pre-commit

Pre-commit Formatting

Use a repo-tracked hook to auto-format staged files with deno fmt before committing:

# One-time: point git at the repo hooks directory and make the hook executable
git config core.hooksPath .githooks
chmod +x .githooks/pre-commit

# Or via deno task
deno task githooks:install

The hook formats staged TS/JS/JSON/MD files and re-stages them so the commit includes the changes. Create a .no-format-hook file at the repo root to temporarily opt out.

Warp Workflows

The project includes pre-built Warp workflows in warp/workflows/:

  • expand-todos-staged.yaml: Process staged files
  • expand-todos-file.yaml: Process specific file
  • expand-todos-dry.yaml: Dry-run preview
  • check-raw-todos.yaml: CI validation

CI Integration

Validate that no unstructured TODOs exist in your codebase:

# Check for raw TODOs (exits with code 1 if found)
files=$(git diff --name-only --cached | grep -E '\.(ts|tsx|js|jsx|py|go|rs|md)$' || true)
if [ -n "$files" ]; then
  bad=$(grep -nE 'TODO(:| )' $files | grep -viE 'AI TASK|Context|Goal|Steps|Constraints|Acceptance' || true)
  if [ -n "$bad" ]; then
    echo "Found unstructured TODOs:"
    echo "$bad"
    exit 1
  fi
fi

Development

Available Tasks

# Run on staged files
deno task todo:staged

# Run on specific file
deno task todo:file path/to/file.ts

# Build standalone binary
deno task build:cli

# Format code
deno task fmt

# Lint code
deno task lint

Testing Your Changes

# Test TODO detection
deno run -A bin/todo-expand.ts --staged --dry-run

# Test with specific parameters
deno run -A bin/todo-expand.ts --include=ts --style=verbose test-file.ts

# Test caching behavior
deno run -A bin/todo-expand.ts --staged  # First run
deno run -A bin/todo-expand.ts --staged  # Should use cache

Architecture

The codebase follows a modular pipeline architecture:

  1. Target Discovery (src/targets.ts): Find files to process
  2. TODO Detection (src/todos.ts): Parse TODO comments
  3. Context Extraction (src/process.ts): Get surrounding code
  4. Prompt Generation (src/prompt.ts): Create LLM prompts
  5. API Interaction (src/prompt.ts): Call OpenAI API
  6. Content Rewriting (src/rewrite.ts): Replace TODOs in-place
  7. Formatting (src/format.ts): Format modified files

Permissions

The CLI requires these Deno permissions:

deno run \
  --allow-read \      # Read source files and config
  --allow-write \     # Write modified files and cache
  --allow-env \       # Access API keys and config
  --allow-run=git \   # Execute git for staged files
  --allow-net=api.openai.com \  # Make API calls
  bin/todo-expand.ts

Or use -A for all permissions (recommended for development).

Troubleshooting

Common Issues

Missing API Key

# Error: OPENAI_API_KEY is not set
export OPENAI_API_KEY="your-key-here"

Git Repository Required

# Error when using --staged outside git repo
cd /path/to/git/repository
todo-expand --staged

Large Files Skipped

# Files over 512KB are skipped by default
# Process specific files instead of using --staged
todo-expand large-file.ts

Cache Issues

# Clear cache if responses seem stale
rm .git/.todoexpand-cache.json

Verification

Test your setup:

# Verify API key
curl -sS https://api.openai.com/v1/models \
  -H "Authorization: Bearer ${OPENAI_API_KEY}" | \
  jq 'if .error then "❌ " + .error.message else "✅ API key valid" end'

# Test on a sample file
echo '// TODO: test comment' > test.js
todo-expand --dry-run test.js
rm test.js

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test with deno task fmt and deno task lint
  5. Submit a pull request

License

[License information would go here]


Made with ❤️ and AI assistance

New Ticket: Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@openminds-it-lab/todo-expander

Import symbol

import * as todo_expander from "@openminds-it-lab/todo-expander";
or

Import directly with a jsr specifier

import * as todo_expander from "jsr:@openminds-it-lab/todo-expander";

Add Package

pnpm i jsr:@openminds-it-lab/todo-expander
or (using pnpm 10.8 or older)
pnpm dlx jsr add @openminds-it-lab/todo-expander

Import symbol

import * as todo_expander from "@openminds-it-lab/todo-expander";

Add Package

yarn add jsr:@openminds-it-lab/todo-expander
or (using Yarn 4.8 or older)
yarn dlx jsr add @openminds-it-lab/todo-expander

Import symbol

import * as todo_expander from "@openminds-it-lab/todo-expander";

Add Package

vlt install jsr:@openminds-it-lab/todo-expander

Import symbol

import * as todo_expander from "@openminds-it-lab/todo-expander";

Add Package

npx jsr add @openminds-it-lab/todo-expander

Import symbol

import * as todo_expander from "@openminds-it-lab/todo-expander";