7.8 KiB
cd-browser -- Development Journey (Reconstructed from Chat Session)
Author: Saky
Method: AI‑assisted development with OpenCode + ChatGPT
Environment: macOS, Python 3.11, zsh terminal
Overview
This document reconstructs the full development process of cd-browser, a terminal directory navigator, built step‑by‑step using:
- a reusable Python development template
- OpenCode as an autonomous coding agent
- ChatGPT as architectural guidance
The workflow followed a structured pattern:
Specification → Plan → Implementation → Validation → Integration → Release
Phase 1 --- Creating the Python AI Development Template
Objective
Create a reusable repository template for AI‑assisted Python projects with:
- clean structure
- automated formatting
- static analysis
- testing
- reproducible workflows
Key decisions
- Python ≥ 3.11
- virtual environment
.venv - tooling:
Tool Purpose
black formatting ruff linting mypy type checking pytest testing pre-commit automated checks make task automation
Repository structure
src/ tests/ specs/ scripts/ Makefile pyproject.toml instructions-agent.md
Important file
instructions-agent.md
Defines how OpenCode should behave:
- read specs before implementing
- keep changes minimal
- reuse modules
- run validation after changes
This file becomes the AI contract for the repository.
Phase 2 --- Creating the Project
Project Name
cd-browser
Goal:
A terminal directory browser that allows fast navigation and returns a directory path to the shell.
Phase 3 --- Application Specification
Specification stored in:
specs/cd_browser_spec.md
Key behavior defined:
- browse directories in terminal
- arrow navigation
- expandable tree
- history support
- return selected path to shell
Phase 4 --- Preparing the Codebase
Created modules:
src/app/
cli.py
filesystem.py
history.py
navigator.py
ui.py
main.py
Purpose of each module:
Module Responsibility
filesystem filesystem inspection history navigation history navigator state machine ui terminal rendering cli orchestration main entrypoint
Phase 5 --- Implementation via OpenCode
OpenCode was instructed to implement modules step‑by‑step.
Step 1 --- Filesystem layer
Prompt summary:
Implement filesystem helpers: - list directories - detect subdirectories - return structured entries
Result
filesystem.py implemented:
- DirectoryEntry
- list_directories()
- has_subdirectories()
Tests added
tests/test_filesystem.py
Validation:
pytest
black
ruff
mypy
All passed.
Step 2 --- History module
Prompt summary:
Implement session history manager.
Result
history.py:
- visit()
- back()
- forward()
- select()
Tests
tests/test_history.py
Validation: success.
Step 3 --- Navigator (core logic)
Prompt summary:
Implement navigator state model using filesystem + history. Do not implement UI yet.
Result
navigator.py manages:
- current_path
- visible entries
- selection index
- expand/collapse
- parent navigation
- history integration
Tests
tests/test_navigator.py
22 tests passed.
Step 4 --- Terminal UI
Prompt summary:
Implement minimal curses UI.
Result
ui.py:
- curses interface
- path display
- selection highlighting
- arrow navigation
- ESC exit
Tests
UI-independent logic tested.
Step 5 --- CLI integration
Prompt summary:
Create CLI orchestration.
Result
cli.py
- initializes navigator
- launches UI
- returns final path
main.py
- entrypoint
- prints selected path
Validation:
27 tests passed
Phase 6 --- Shell Integration
Problem:
A program cannot change the parent shell directory.
Solution:
Create shell wrapper:
cd_() { local target target="$(cd_browser)" if [ -n "$target" ] && [ -d "$target" ]; then cd "$target" fi }
Added to:
~/.zshrc
Now command:
cd_
opens the navigator and changes directory.
Phase 7 --- Critical Bug Encountered
Issue
Using command substitution:
target="$(cd_browser)"
broke the curses UI.
Observed behavior:
- UI not rendering
- logging printed to stdout
Example output:
INFO app.main Starting application
Root cause
- stdout captured by shell
- curses requires real terminal
- logging polluted stdout
Resolution
Prompt given to OpenCode:
Fix integration so UI uses real terminal while stdout remains clean.
Fix implemented
- UI attached to /dev/tty
- logging redirected to stderr
- stdout reserved for final path
Files modified
ui.py
main.py
logging_config.py
tests
Validation:
28 tests passed
Problem resolved.
Phase 8 --- Packaging
Added console entrypoint in pyproject.toml:
[project.scripts] cd_browser = "app.main:main"
Now installable via:
pip install .
Command available:
cd_browser
Phase 9 --- Documentation Refactor
Problem:
README from template conflicted with project README.
Solution:
README.md
README_TEMPLATE.md
README.md → project documentation
README_TEMPLATE.md → original template documentation preserved
Phase 10 --- Repository Release Preparation
Checklist performed:
- formatting
- linting
- type checking
- tests
Commands:
make fix
make quality
make ci
All passed.
Phase 11 --- Final Repository Initialization
Repository prepared for first release.
git add .
git commit -m "Initial release: cd-browser v0.1.0"
Then:
git push -u origin main
git tag v0.1.0
git push origin v0.1.0
Current Features
cd-browser provides:
- interactive terminal directory browsing
- expandable directory tree
- keyboard navigation
- directory history
- shell integration
- installation via pip
- automated testing and quality checks
Future Improvements
Planned navigation redesign:
Key model:
→ expand / enter
← collapse / go up
Enter confirm directory
ESC cancel
Lessons Learned
AI‑assisted development works best with:
- clear specifications
- modular architecture
- strict validation loops
- minimal prompts with clear scope
Critical discovery:
Terminal applications must handle:
stdout
stderr
/dev/tty
correctly when used inside shell substitution.
End of document.