Files
cd-browser/docs/development-journey.md

7.8 KiB
Raw Blame History

cd-browser -- Development Journey (Reconstructed from Chat Session)

Author: Saky
Method: AIassisted 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 stepbystep 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 AIassisted 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 stepbystep.

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

AIassisted 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.