Contributions are welcome! This document covers how to contribute, including how to pair with an AI assistant like Claude.
- Clone the repository
- Install Bun
- Run the test suite:
bun test - Try the sample files:
bun qif-to-ledger.ts -a "Assets:Checking" examples/sample.qif bun csv-to-ledger.ts -a "Assets:Checking" examples/sample.csv bun ledger-converter-tui.ts
├── *-to-ledger.ts, ledger-converter*.ts # Entry points (compilable to binaries)
├── cli/
│ ├── arg_parser.ts # CLI argument parsing
│ ├── help.ts # Help text for CLI tools
│ ├── tui.ts # TUI utilities (prompts, colors, spinner)
│ └── types.ts # Shared types
├── utils/
│ ├── qif_parser.ts # QIF file parsing
│ ├── qif_parser.test.ts # QIF parser tests
│ ├── csv_parser.ts # CSV file parsing
│ ├── csv_parser.test.ts # CSV parser tests
│ └── ledger_converter.ts # Ledger format conversion
└── examples/ # Sample files for testing
- Make your changes
- Run the test suite:
bun test - Test with the sample files in
examples/ - Update documentation if adding new features
- Commit with a descriptive message
This project was developed in collaboration with Claude, Anthropic's AI assistant. Claude can help with:
- Understanding the codebase
- Implementing new features
- Debugging issues
- Writing documentation
When working with Claude on this project:
- Share context: Point Claude to relevant files or describe the feature you're working on
- Use the sample files:
examples/sample.qifandexamples/sample.csvare useful for testing - Test incrementally: Have Claude verify changes work before moving on
The following section contains guidance for AI assistants (like Claude) contributing to this project.
The interactive TUI (ledger-converter-tui.ts) requires TTY input and cannot be tested directly from a non-interactive shell. Use tmux to test the TUI:
The TUI defaults to sample files (examples/sample.qif or examples/sample.csv), so you can press Enter to accept defaults.
# Start TUI in a tmux session
tmux new-session -d -s tui-test -x 80 -y 24 'bun ledger-converter-tui.ts'
# Wait for startup
sleep 1
# Capture current screen
tmux capture-pane -t tui-test -p
# Send keystrokes (Enter accepts defaults, including sample file paths)
tmux send-keys -t tui-test Enter # Select QIF format
tmux send-keys -t tui-test Enter # Accept default: examples/sample.qif
tmux send-keys -t tui-test Enter # Accept default: Assets:Checking
# Capture output after interaction
sleep 0.5
tmux capture-pane -t tui-test -p
# Clean up when done
tmux kill-session -t tui-testKey tmux commands:
| Command | Purpose |
|---|---|
tmux send-keys -t <session> Enter |
Press Enter |
tmux send-keys -t <session> 'text' |
Type text |
tmux send-keys -t <session> Up / Down |
Arrow keys |
tmux send-keys -t <session> Escape |
Press Escape (go back) |
tmux capture-pane -t <session> -p |
Capture current screen output |
- Entry points (
*-to-ledger.ts,ledger-converter*.ts): Keep minimal, delegate to utilities - cli/: User interface code (arguments, help, TUI)
- utils/: Core parsing and conversion logic (no UI dependencies)
When updating documentation:
- Update header comments in source files to list all entry points
- Keep help text in
cli/help.tssynchronized with README - Include sample file examples in "Try it" sections
# Run the test suite (always do this first)
bun test
# Test CLI entry points with sample files
bun qif-to-ledger.ts -a "Assets:Checking" examples/sample.qif
bun csv-to-ledger.ts -a "Assets:Checking" examples/sample.csv
bun ledger-converter.ts -a "Assets:Checking" -i qif examples/sample.qif
# Test help output
bun qif-to-ledger.ts --help
# Test TUI (use tmux as described above)
# Compile binaries to verify build works
bun build --compile --outfile=ledger-converter-tui ledger-converter-tui.tsTests are located alongside the source files in utils/:
utils/qif_parser.test.ts- QIF parser tests (date formats, amounts, splits)utils/csv_parser.test.ts- CSV parser tests (quoted fields, date formats, debit/credit)
When adding new parsing functionality, add corresponding tests. Bun's test runner automatically discovers *.test.ts files.