454 lines
7.8 KiB
Markdown
454 lines
7.8 KiB
Markdown
# 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
|
||
|
||
1. UI attached to /dev/tty
|
||
2. logging redirected to stderr
|
||
3. 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:
|
||
|
||
1. clear specifications
|
||
2. modular architecture
|
||
3. strict validation loops
|
||
4. minimal prompts with clear scope
|
||
|
||
Critical discovery:
|
||
|
||
Terminal applications must handle:
|
||
|
||
stdout\
|
||
stderr\
|
||
/dev/tty
|
||
|
||
correctly when used inside shell substitution.
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
End of document.
|