16 Commits

Author SHA1 Message Date
d9d412973b feat: finalize AI logging framework and workflow
- align instructions, workflow rules, and task template with three-level logging
- extend ai-task generation to support execution-log requirements
- update worklog, prompt log, and execution log for the finalized framework
- validate the framework with generator and project quality checks
2026-03-16 03:00:39 +01:00
9704d3ef5b docs: improve AI agent workflow and instruction framework
- strengthen agent workflow rules and commit/log ordering
- improve AI logging instructions and traceability
- add agent framework documents and task generation tooling
- keep repository workflow consistent for future AI-assisted tasks
2026-03-16 02:00:18 +01:00
0118ad9314 docs: record AI agent framework task logs 2026-03-16 01:47:57 +01:00
e766210920 feat: introduce AI agent framework and task tooling
- add AGENT.md describing the agent system
- add AGENT_WORKFLOW.md defining the execution workflow
- add AI_TASK_TEMPLATE.md for structured task prompts
- add scripts/ai-task CLI tool for generating standardized agent tasks
2026-03-16 01:38:36 +01:00
6849631cc1 docs: finalize AI logging format system
- align ai-worklog and ai-prompts with the current logging framework
- require timestamped structured log entries
- finalize logging rules in instructions-agent.md
2026-03-16 01:33:02 +01:00
7c87d6f1f0 docs: require timestamp in AI log entries
- enforce YYYY-MM-DD HH:MM format in AI logs
- update AI BUILD ENTRY and AI PLAN ENTRY examples
- improve chronological accuracy of worklog
2026-03-16 00:32:57 +01:00
60723c33bc feat: improve terminal navigation and UI behavior
- refine tree and history navigation behavior
- improve scrolling continuity in the terminal UI
- keep AI worklog and prompt log updated
- validate changes with project quality checks
2026-03-16 00:28:27 +01:00
6195f7b8a3 docs: introduce standard AI log entry format
- add standardized AI BUILD ENTRY and AI PLAN ENTRY format
- improve consistency of AI development logs
- update instructions-agent.md
2026-03-15 22:22:35 +01:00
801544951f docs: introduce mandatory AI logging system
- add AI worklog and prompt logs
- enforce logging rules in instructions-agent.md
- require AI agents to record plan and build tasks
- establish traceable AI-assisted development workflow
2026-03-15 18:26:22 +01:00
65508d263f feat: implement history mode and AI development logging
- add dedicated history mode UI (toggle with `h`)
- allow navigation inside history with arrows
- allow selecting history entries with Enter
- add tests for history mode behavior
- introduce AI development logs (`ai-worklog.md`, `ai-prompts.md`)
- add AI worklog policy to `instructions-agent.md`
2026-03-15 17:46:11 +01:00
2bdfbe25d5 debug: add temporary history overlay 2026-03-15 12:03:11 +01:00
12d2577a31 feat: improve navigation behaviour 2026-03-14 18:54:20 +01:00
90008f149a docs: add documentation index linking all project docs 2026-03-14 18:03:09 +01:00
e481b1ae45 docs: add documentation index 2026-03-14 18:00:07 +01:00
0b789b77e9 docs: add project overview 2026-03-14 17:55:28 +01:00
91a23203ed docs: add AI development playbook and architecture documentation 2026-03-14 17:52:04 +01:00
16 changed files with 3496 additions and 28 deletions

260
AGENT.md Normal file
View File

@@ -0,0 +1,260 @@
# AGENT.md
AI Agent Development Guide
This file defines the operational rules that AI agents must follow when working in this repository.
The goal is to ensure:
- reproducible AI-assisted development
- traceable decisions
- consistent repository history
- safe automated contributions
This document complements:
- `instructions-agent.md`
- `docs/ai-worklog.md`
- `docs/ai-prompts.md`
---
# Core Principles
Agents must prioritize:
1. Deterministic changes
2. Minimal scope modifications
3. Explicit logging of work
4. Repository stability
Agents must never:
- fabricate repository state
- invent files that do not exist
- modify unrelated parts of the project
- skip validation steps
---
# Development Workflow
Agents operate using two primary task types:
## PLAN
Used to:
- investigate problems
- inspect repository state
- propose architecture changes
PLAN tasks must:
- analyze the current implementation
- identify the root cause
- propose minimal changes
PLAN tasks **must not modify code**.
---
## BUILD
Used to:
- implement changes
- update code
- add tests
- update documentation
BUILD tasks may:
- modify source files
- update tests
- update documentation
BUILD tasks must:
- remain minimal in scope
- preserve existing behavior unless explicitly changed
---
# Validation Requirements
All BUILD tasks must run:
```
make fix
make quality
```
These commands must pass before changes are considered valid.
---
# Logging System
All significant AI actions must be recorded.
Two log files are used:
```
docs/ai-worklog.md
docs/ai-prompts.md
```
---
# Worklog Entries
Executed work must be recorded in:
```
docs/ai-worklog.md
```
Each entry must follow the standard format defined in `instructions-agent.md`.
Mandatory fields:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task
- Objective
- Scope
- Files Modified / Files Inspected
- Key Decisions / Proposed Changes
- Validation
- Result
- Open Issues
---
# Prompt Log
Prompts that trigger significant work must be recorded in:
```
docs/ai-prompts.md
```
Each prompt entry must include:
- Date
- Task ID
- Agent
- Task
- Scope
- Prompt Summary
- Result Summary
Chain-of-thought reasoning must **never be stored**.
---
# Task IDs
All tasks must include a unique identifier.
Format:
```
BUILD-YYYYMMDD-XXX
PLAN-YYYYMMDD-XXX
```
Examples:
```
BUILD-20260315-001
PLAN-20260316-002
```
This allows prompts and worklog entries to be correlated.
---
# Git Rules
Agents must follow these repository rules.
Agents must **not commit or push** unless explicitly requested.
When committing:
Use structured commit messages.
Example:
```
feat: improve terminal navigation behavior
- refine tree navigation
- improve scrolling continuity
- update AI logs
```
Documentation-only updates should use:
```
docs:
```
---
# Code Modification Rules
Agents should prefer:
- small targeted patches
- isolated logic changes
- preserving existing abstractions
Agents should avoid:
- rewriting entire modules
- introducing unnecessary dependencies
- altering unrelated code paths
---
# UI Changes
When modifying UI behavior:
- keep navigation predictable
- preserve keyboard ergonomics
- ensure selections remain visible
- maintain compatibility with history mode
---
# Testing Rules
Whenever logic changes:
- update existing tests
- add focused tests when appropriate
Tests should validate behavior, not implementation details.
---
# Scope Discipline
Agents must strictly respect scope defined in prompts.
If additional changes appear necessary:
Agents must propose them in a PLAN task before implementing.
---
# Repository Safety
Agents must not:
- delete important files
- alter project configuration without justification
- introduce breaking changes without explicit instruction
---
# End of Document
---

298
AGENT_WORKFLOW.md Normal file
View File

@@ -0,0 +1,298 @@
# AGENT_WORKFLOW.md
AI Agent Operational Workflow
This document defines the deterministic workflow that AI agents must follow when performing work in this repository.
The workflow ensures:
- predictable development cycles
- traceable decisions
- minimal risk of unintended changes
- consistent logging of AI actions
This file complements:
- `AGENT.md`
- `instructions-agent.md`
- `docs/ai-worklog.md`
- `docs/ai-prompts.md`
- `docs/ai-execution-log.md`
---
# Standard Workflow
Every AI task must follow this sequence:
PLAN → REVIEW → BUILD → VALIDATE → LOG
---
# Execution Order (Strict)
The following operational order must be respected when executing any BUILD task.
1. Implement changes (BUILD)
2. Run validation
make fix
make quality
3. Update AI logs
- docs/ai-execution-log.md
- docs/ai-prompts.md
- docs/ai-worklog.md
4. Stage all modified files including logs
5. Create commit
6. Push only if explicitly requested
Important rule:
Logs must always be written **before creating a commit**. If log files are modified after a commit, the task is considered incomplete and must be corrected.
---
This sequence must not be skipped.
---
# 1. PLAN
Goal:
Understand the problem and determine the minimal solution.
Actions:
- inspect repository state
- read relevant source files
- analyze existing architecture
- identify root cause of the problem
- propose a minimal change
Rules:
- PLAN must **not modify code**
- PLAN must **not change files**
- PLAN must only produce analysis and a proposal
Output should include:
- diagnosis summary
- proposed changes
- expected file scope
---
# 2. REVIEW
Goal:
Validate the plan before implementing it.
Actions:
- confirm the proposed scope is minimal
- ensure no unrelated components are affected
- verify the change aligns with project architecture
Rules:
- If the scope expands unexpectedly, return to PLAN.
---
# 3. BUILD
Goal:
Implement the approved change.
Actions:
- modify only the files defined in scope
- preserve existing architecture
- avoid unnecessary refactors
- maintain compatibility with existing behavior
BUILD tasks may modify:
- source files
- tests
- documentation
BUILD tasks must remain minimal and targeted.
---
# 4. VALIDATE
Goal:
Ensure the repository remains stable.
Agents must run:
```
make fix
make quality
```
Validation must pass before changes are considered complete.
---
# 5. LOG
Goal:
Record the AI activity for traceability.
Three log files must be updated.
### Work Log
```
docs/ai-worklog.md
```
Record:
- AI BUILD ENTRY
- or AI PLAN ENTRY
Including:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task
- Objective
- Scope
- Files Modified / Files Inspected
- Key Decisions / Proposed Changes
- Validation
- Result
- Open Issues
### Prompt Log
```
docs/ai-prompts.md
```
Record:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task
- prompt summary
- scope
- result summary
Do not store chain-of-thought reasoning.
### Execution Log
```
docs/ai-execution-log.md
```
Record the full visible execution trace including:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task Type
- Full prompt text
- Agent todos
- Execution report
The execution log preserves the complete operational record of the AI session.
---
# Task ID Coordination
Every PLAN or BUILD must generate a unique Task ID.
Format:
```
PLAN-YYYYMMDD-XXX
BUILD-YYYYMMDD-XXX
```
Example:
```
PLAN-20260316-001
BUILD-20260316-002
```
The same Task ID must appear in:
- ai-execution-log.md
- ai-prompts.md
- ai-worklog.md
---
# Commit Workflow
Agents must **not commit or push automatically** unless explicitly instructed.
Before creating a commit the agent must ensure:
- validation has passed
- AI logs have been written
- docs/ai-execution-log.md, docs/ai-worklog.md and docs/ai-prompts.md are staged
Commits that omit required AI log entries violate the repository workflow rules.
When commits are requested:
1. Validate repository state
2. Stage modified files
3. Use structured commit messages
Example:
```
feat: improve terminal navigation
- refine tree navigation
- improve scrolling
- update AI logs
```
Documentation-only updates should use:
```
docs:
```
---
# Failure Handling
If validation fails:
Agents must:
1. stop the BUILD process
2. report the error
3. propose a fix
Agents must **not silently bypass failing checks**.
---
# Scope Control
Agents must strictly respect the defined scope.
If additional changes appear necessary:
- return to PLAN
- propose a new change
Do not expand scope during BUILD.
---
# End of Document

179
AI_TASK_TEMPLATE.md Normal file
View File

@@ -0,0 +1,179 @@
# AI Task Template
Reusable prompt template for launching tasks with AI agents.
This template enforces the repository workflow defined in:
- AGENT.md
- AGENT_WORKFLOW.md
- instructions-agent.md
It ensures every task follows the deterministic sequence:
PLAN → REVIEW → BUILD → VALIDATE → LOG
---
# Basic Task Structure
Use the following structure when requesting work from an AI agent.
```
Task Type:
PLAN | BUILD
Task ID:
PLAN-YYYYMMDD-XXX | BUILD-YYYYMMDD-XXX
Date:
YYYY-MM-DD HH:MM
Objective:
Short description of the goal.
Context:
Relevant background about the current repository state.
Scope:
List of files or directories the agent may modify or inspect.
Requirements:
Detailed description of the behavior that must be implemented or analyzed.
Constraints:
Things the agent must NOT change or must preserve.
Testing:
Describe expected tests or validations.
Validation:
The agent must run:
make fix
make quality
Logging requirements:
- Append an entry to docs/ai-worklog.md
- Append an entry to docs/ai-prompts.md
- Append an entry to docs/ai-execution-log.md
- Include Date, Task ID, Agent, Scope, Result
Execution Logging requirements:
- Append an entry to docs/ai-execution-log.md
- Include:
- full prompt
- agent todos
- final execution report
- Use the standard execution log format defined in docs/ai-execution-log.md
Git requirements:
- Do NOT commit or push unless explicitly requested.
Expected Report:
The agent must summarize:
- files changed
- behavior changes
- validation results
```
---
# Example BUILD Task
```
Task Type:
BUILD
Task ID:
BUILD-YYYYMMDD-XXX
Date:
YYYY-MM-DD HH:MM
Objective:
Improve vertical scrolling behavior in the terminal UI.
Scope:
- src/app/ui.py
- tests/test_ui.py
Requirements:
Ensure the selected entry remains visible when navigating through long directory lists.
Constraints:
Do not modify navigator logic.
Testing:
Add helper tests if necessary.
Validation:
make fix
make quality
Logging requirements:
- Update `docs/ai-worklog.md` and `docs/ai-prompts.md` using the standard log format.
Execution Logging requirements:
- Update docs/ai-execution-log.md with:
- full prompt
- agent todos
- final execution report
Git requirements:
- Do NOT commit or push unless explicitly requested.
```
---
# Example PLAN Task
```
Task Type:
PLAN
Task ID:
PLAN-YYYYMMDD-XXX
Date:
YYYY-MM-DD HH:MM
Objective:
Investigate inconsistent navigation behavior.
Scope:
- src/app/ui.py
- src/app/navigator.py
Requirements:
Analyze the current navigation flow and propose a minimal fix.
Constraints:
Do not modify code.
Validation:
make fix
make quality
Logging requirements:
- Update `docs/ai-worklog.md` and `docs/ai-prompts.md` using the standard log format.
Execution Logging requirements:
- Update docs/ai-execution-log.md with:
- full prompt
- agent todos
- final execution report
Git requirements:
- Do NOT commit or push unless explicitly requested.
Expected Output:
- diagnosis summary
- proposed changes
- expected file scope
```
---
# Notes
This template keeps AI interactions consistent across tasks and helps maintain a clean development history.

View File

@@ -4,6 +4,13 @@
It provides an interactive interface for exploring directories with the keyboard and returns the selected path at the end of the session so shell wrappers can change the current shell directory.
## Documentation
See the documentation index:
docs/index.md
## Features
- Interactive terminal directory browser

View File

@@ -0,0 +1,202 @@
# cd-browser AI Development Playbook
Author: Saky\
Purpose: Reusable methodology for building software with AI coding
agents.
------------------------------------------------------------------------
# 1. Philosophy
This playbook documents a repeatable workflow for building software with
AI agents such as:
- OpenCode
- Codexstyle coding agents
- LLM programming assistants
Goal:
Maintain **architectural control and code quality** while benefiting
from AIaccelerated development.
Core principle:
AI is used as an **implementation engine**, not as an architect.
The human defines:
- architecture
- boundaries
- specifications
- validation rules
------------------------------------------------------------------------
# 2. The AI Development Workflow
The method used in the `cd-browser` project follows this sequence:
Specification → Architecture → Module Scaffolding → Implementation →
Validation → Integration → Release
Each step uses **focused prompts with limited scope**.
------------------------------------------------------------------------
# 3. Repository Preparation
Before using an AI coding agent, the repository must define:
## Tooling
black -- formatting\
ruff -- linting\
mypy -- type checking\
pytest -- testing\
pre-commit -- commit validation
## Folder structure
src/ tests/ specs/ scripts/ docs/
## AI agent rules
Defined in:
instructions-agent.md
The file instructs the agent to:
- read specifications first
- reuse modules
- keep changes minimal
- run validation workflows
------------------------------------------------------------------------
# 4. Prompt Design Principles
Effective prompts follow three rules:
### 1. Limit scope
Always define affected files.
Example:
Scope: - src/app/navigator.py - tests/test_navigator.py
### 2. Define constraints
Example:
Do not implement UI yet.
### 3. Require validation
Example:
Run:
make fix\
make quality
------------------------------------------------------------------------
# 5. Example Prompt --- Module Implementation
Example used in the project:
Implement navigator state model.
Scope: - src/app/navigator.py - tests related to navigator behavior
Requirements: - track current path - manage selection - support
expansion and collapse - integrate history module - add pytest coverage
Validation: - make fix - make quality
Output: - files changed - summary of implementation
------------------------------------------------------------------------
# 6. Example Prompt --- Debugging
Example debugging prompt used:
We discovered a terminal integration issue.
Problem: The shell wrapper captures stdout using command substitution.
The curses UI fails when stdout is captured.
Requirements: - attach UI to /dev/tty - ensure stdout prints only final
path - move logs to stderr
------------------------------------------------------------------------
# 7. Prompt Template
Reusable template:
Scope: (list files)
Requirements: (describe expected behaviour)
Constraints: (limit unwanted features)
Validation: (run project tooling)
Output: (files changed + summary)
------------------------------------------------------------------------
# 8. Validation Loop
Every change follows the validation loop:
1. Agent implements change
2. Run:
make fix make quality
3. Review output
4. Commit if successful
This guarantees stable incremental development.
------------------------------------------------------------------------
# 9. Best Practices
✔ Keep prompts small\
✔ Implement one module at a time\
✔ Always request tests\
✔ Run automated checks\
✔ Separate specification from implementation
------------------------------------------------------------------------
# 10. AntiPatterns
Avoid:
❌ large prompts implementing entire applications\
❌ vague requirements\
❌ skipping validation steps\
❌ allowing the AI to define architecture
------------------------------------------------------------------------
# 11. Benefits
Using this workflow:
- reduces implementation time
- preserves architectural control
- ensures consistent code quality
- enables reproducible development
------------------------------------------------------------------------
# End

219
docs/ai-execution-log.md Normal file
View File

@@ -0,0 +1,219 @@
# AI Execution Log
This file stores the **full execution traces** of AI-assisted tasks.
Unlike:
- `docs/ai-worklog.md` → concise technical task summaries
- `docs/ai-prompts.md` → concise prompt summaries
this file preserves the **complete operational record** of an AI session.
The purpose of this file is to make it possible to reconstruct:
- the exact prompt given to the agent
- the execution plan or todo list generated by the agent
- the final execution report returned by the agent
This file is intended for **full traceability** of AI-assisted development.
Entries must be appended in chronological order.
---
## Standard Entry Structure
Each execution entry should follow this structure:
```md
## BUILD-YYYYMMDD-XXX
Date: YYYY-MM-DD HH:MM
Agent: OpenCode
Task Type: BUILD
---
### Prompt Provided to Agent
<full prompt text>
---
### Agent Todos
# Todos
[ ] item 1
[ ] item 2
---
### Agent Execution Report
<final report returned by the agent>
```
For plan tasks, use:
```md
## PLAN-YYYYMMDD-XXX
Date: YYYY-MM-DD HH:MM
Agent: OpenCode
Task Type: PLAN
```
---
## Logging Rules
When a significant AI task is executed, this file should record:
1. The prompt that was actually given to the agent.
2. The todo or execution plan shown by the agent.
3. The final summary or execution report returned by the agent.
Do not store private chain-of-thought.
Only store user-visible execution artifacts.
---
## Relationship With Other Logs
- `docs/ai-prompts.md` stores a concise summary of the prompt.
- `docs/ai-worklog.md` stores a concise technical summary of what was done.
- `docs/ai-execution-log.md` stores the complete visible execution trace.
Together, the three files provide:
1. Prompt intent
2. Technical result
3. Full execution trace
---
## First Use
The next significant OpenCode task should append the first real execution entry to this file using the structure above.
---
## BUILD-20260316-005
Date: 2026-03-16 02:51
Agent: OpenCode
Task Type: BUILD
---
### Prompt Provided to Agent
Task Type:
BUILD
Task ID:
BUILD-20260316-005
Date:
2026-03-16 02:51
Objective:
Finalize AI logging framework and repository workflow updates
Context:
The repository contains pending changes related to the AI logging framework, execution logging, and AI task workflow. These changes introduce a three-level logging system (`ai-worklog.md`, `ai-prompts.md`, and `ai-execution-log.md`), improved agent workflow rules, and enhancements to the `scripts/ai-task` tooling. The goal of this task is to validate these changes, ensure logs are consistent, and publish the finalized framework.
Scope:
- instructions-agent.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
- docs/ai-execution-log.md
Requirements:
1. Inspect the current working tree and confirm the changes in scope.
2. Verify that the AI logging framework is consistent across:
- instructions-agent.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
3. Ensure that `scripts/ai-task` supports the three logging files:
- docs/ai-worklog.md
- docs/ai-prompts.md
- docs/ai-execution-log.md
4. Append a new AI BUILD ENTRY to `docs/ai-worklog.md`.
5. Append a new BUILD PROMPT ENTRY to `docs/ai-prompts.md`.
6. Append a new execution entry to `docs/ai-execution-log.md` containing:
- the full prompt
- the agent todos
- the final execution report
7. Ensure all three logs remain in chronological order.
8. Stage all modified files within the defined scope.
9. Create a single commit describing the finalized AI workflow and logging framework.
10. Push the commit to the current branch.
Constraints:
- follow AGENT_WORKFLOW.md
- keep scope limited to the files listed above
- preserve existing project behavior unless explicitly changed
- logs must be written before creating the commit
- logs must be included in the same commit
Testing:
- run `make fix`
- run `make quality`
- verify that `scripts/ai-task` still generates a valid BUILD task prompt
- verify that log files remain chronologically ordered
Validation:
make fix
make quality
Logging requirements:
- append entry to docs/ai-worklog.md
- append entry to docs/ai-prompts.md
- include Date, Task ID, Agent, Scope
- use Task ID: BUILD-20260316-005
- maintain chronological Task ID order in ai-worklog.md, ai-prompts.md and ai-execution-log.md
- append entry to docs/ai-execution-log.md
Execution Logging requirements:
- append entry to docs/ai-execution-log.md
- include:
- full prompt
- agent todos
- final execution report
- use the standard execution log format defined in docs/ai-execution-log.md
Git requirements:
- create a single commit
- include all updated logs in the commit
- push the commit to the current branch
Expected Report:
- files committed
- commit hash
- validation results
- confirmation that logs were updated before commit
- confirmation that push succeeded
---
### Agent Todos
# Todos
[x] Inspect scoped files and current logging framework changes
[x] Update worklog, prompt log, and execution log for BUILD-20260316-005
[x] Validate `scripts/ai-task` output and run `make fix` and `make quality`
[x] Stage scoped files, create single commit, and push branch
---
### Agent Execution Report
- Verified that `instructions-agent.md`, `AGENT_WORKFLOW.md`, `AI_TASK_TEMPLATE.md`, and `scripts/ai-task` describe the same three-level logging workflow.
- Updated the task template and logs so the worklog, prompt log, and execution log stay aligned and chronological.
- Confirmed `scripts/ai-task build "test task" src/app/ui.py` still produces a valid BUILD task prompt that references all three logs.
- Ran `make fix` and `make quality` successfully before commit creation.
- Prepared the scoped files for a single commit and push covering the finalized AI workflow and logging framework.

221
docs/ai-prompts.md Normal file
View File

@@ -0,0 +1,221 @@
# AI Prompts Log
This file stores the prompts that triggered significant AI-driven development tasks.
The goal is to preserve traceability between:
- the prompt given to the AI
- the scope of the change
- the resulting work recorded in `ai-worklog.md`
Each entry must include:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task type (plan/build)
- Scope
- Prompt summary
- Result summary
Only record prompts that:
- change architecture
- introduce new behavior
- modify important logic
- affect project structure
- debug complex issues
Do not store chain-of-thought reasoning. Only store the prompt intent and a concise result summary.
---
### BUILD PROMPT ENTRY
Date: 2026-03-15 18:05
Task ID: BUILD-20260315-001
Agent: OpenCode
Task: build
Scope:
- src/app/ui.py
- tests/test_ui.py
Prompt Summary:
Implement a dedicated history mode in `src/app/ui.py` so pressing `h` hides the tree, shows only history entries, supports Up/Down navigation, and uses Enter to select a history entry and return to the normal tree view.
Result Summary:
Added a dedicated history mode with its own selection state, removed the temporary overlay behavior, preserved existing `b`/`f` and normal tree navigation behavior, and added focused UI tests.
---
### BUILD PROMPT ENTRY
Date: 2026-03-15 19:25
Task ID: BUILD-20260315-002
Agent: OpenCode
Task: build
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Prompt Summary:
Introduce a mandatory AI logging system by updating `instructions-agent.md` and adding repository logs for AI work entries and prompt summaries.
Result Summary:
Added enforceable AI logging rules to `instructions-agent.md`, created `docs/ai-worklog.md` and `docs/ai-prompts.md`, and established a traceable workflow for recording significant AI-assisted tasks.
---
### BUILD PROMPT ENTRY
Date: 2026-03-15 20:00
Task ID: BUILD-20260315-003
Agent: OpenCode
Task: build
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Prompt Summary:
Introduce a standard AI log entry format in `instructions-agent.md` and record the change in the repository AI logs.
Result Summary:
Added standardized `AI BUILD ENTRY` and `AI PLAN ENTRY` formats, improving consistency and long-term traceability of AI-assisted development.
---
### BUILD PROMPT ENTRY
Date: 2026-03-15 21:35
Task ID: BUILD-20260315-004
Agent: OpenCode
Task: build
Scope:
- src/app/ui.py
- tests/test_ui.py
Prompt Summary:
Improve keyboard navigation in `src/app/ui.py` so Right expands or enters, Left collapses or goes to the parent, Enter confirms the selected destination, and ESC cancels back to the starting directory.
Result Summary:
Updated the tree-mode key handling in the terminal UI, preserved history mode behavior, and added focused UI tests for the new navigation rules.
---
### BUILD PROMPT ENTRY
Date: 2026-03-15 22:20
Task ID: BUILD-20260315-005
Agent: OpenCode
Task: build
Scope:
- src/app/ui.py
- tests/test_ui.py
Prompt Summary:
Improve vertical scrolling in `src/app/ui.py` so the selected entry always remains visible in tree mode and history mode when the list is taller than the screen.
Result Summary:
Added UI scroll offset handling for tree and history views, kept existing navigation behavior unchanged, and added focused tests for the scroll helper logic.
---
### BUILD PROMPT ENTRY
Date: 2026-03-16 00:27
Task ID: BUILD-20260316-001
Agent: OpenCode
Task: build
Scope:
- src/app/ui.py
- tests/test_ui.py
Prompt Summary:
Refine terminal UI navigation, maintain dedicated history mode, and ensure scrolling continuity so selections remain visible.
Result Summary:
Updated terminal UI behavior, consolidated navigation improvements, and ensured consistent scrolling and selection visibility across tree and history modes.
---
### BUILD PROMPT ENTRY
Date: 2026-03-16 01:26
Task ID: BUILD-20260316-002
Agent: OpenCode
Task: build
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Prompt Summary:
Finalize the AI logging format system by requiring timestamped structured log entries and aligning the repository worklog and prompt log with the current logging framework.
Result Summary:
Updated the logging instructions, normalized the prompt log to the structured entry format, and added matching repository log entries for the finalized AI logging system.
---
### BUILD PROMPT ENTRY
Date: 2026-03-16 01:34
Task ID: BUILD-20260316-003
Agent: OpenCode
Task: build
Scope:
- AGENT.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
Prompt Summary:
Introduce the AI agent operational framework by adding agent guidance, workflow rules, a reusable task template, and a CLI tool that generates standardized AI task prompts.
Result Summary:
Added the repository agent framework documents, introduced the `scripts/ai-task` helper, aligned the framework with validation and logging rules, and recorded the change in the AI logs.
---
### BUILD PROMPT ENTRY
Date: 2026-03-16 01:45
Task ID: BUILD-20260316-004
Agent: OpenCode
Task: build
Scope:
- instructions-agent.md
- AGENT.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
Prompt Summary:
Finalize and publish the repository AI agent workflow and instruction framework by strengthening workflow and logging rules, documenting the agent framework files, and shipping the task generation tooling.
Result Summary:
Updated the workflow and instruction rules, recorded the framework rollout in the AI logs, and prepared the branch so the agent framework documents and `scripts/ai-task` tooling are published together.
---
### BUILD PROMPT ENTRY
Date: 2026-03-16 02:51
Task ID: BUILD-20260316-005
Agent: OpenCode
Task: build
Scope:
- instructions-agent.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
- docs/ai-execution-log.md
Prompt Summary:
Finalize the AI logging framework by aligning instructions, workflow rules, task templates, generator tooling, and all three repository logs, then validate and publish the changes.
Result Summary:
Updated the repository workflow documents and task template for the three-level logging model, verified `scripts/ai-task`, and recorded synchronized worklog, prompt log, and execution log entries.

377
docs/ai-worklog.md Normal file
View File

@@ -0,0 +1,377 @@
# AI Worklog
This file records important AIassisted development actions.
The log is designed for longterm traceability of AIdriven development.
Each entry must include:
- Date (YYYY-MM-DD HH:MM)
- Task ID
- Agent
- Task type (plan/build)
- Objective
- Scope
- Files Modified / Files Inspected
- Key Decisions or Proposed Changes
- Validation
- Result
- Open Issues
Entries must remain chronological.
---
### AI BUILD ENTRY
Date: 2026-03-15 18:10
Task ID: BUILD-20260315-001
Agent: OpenCode
Task: build
Objective: Replace the temporary history debug overlay with a dedicated history mode in the terminal UI.
Scope:
- src/app/ui.py
- tests/test_ui.py
Files Modified:
- src/app/ui.py
- tests/test_ui.py
Key Decisions:
- Keep `b` and `f` unchanged.
- Add separate history-mode selection state inside the UI.
- Hide the tree while history mode is active.
- Use Enter to select a history entry and return to the tree view.
Validation:
- make fix
- make quality
Result:
- History mode now shows only the history list and allows navigation and selection of past directories.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-15 19:30
Task ID: BUILD-20260315-002
Agent: OpenCode
Task: build
Objective: Introduce mandatory AI logging rules and repository logging workflow.
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Files Modified:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Require AI agents to log plan and build tasks.
- Separate logs for work results and prompts.
- Keep entries concise and userfocused.
Validation:
- not run
Result:
- Repository now enforces AI logging via instructions-agent.md.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-15 20:05
Task ID: BUILD-20260315-003
Agent: OpenCode
Task: build
Objective: Introduce the standard AI log entry format and improve logging consistency.
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Files Modified:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Define AI BUILD ENTRY and AI PLAN ENTRY blocks.
- Standardize structure for longterm repository traceability.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- Repository now uses a standardized AI logging format.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-15 21:40
Task ID: BUILD-20260315-004
Agent: OpenCode
Task: build
Objective: Improve keyboard navigation behavior in the terminal UI for tree mode.
Scope:
- src/app/ui.py
- tests/test_ui.py
Files Modified:
- src/app/ui.py
- tests/test_ui.py
Key Decisions:
- Right expands collapsed directories and enters expanded directories.
- Left collapses expanded directories or navigates to the parent directory.
- Enter confirms the selected path.
- ESC cancels and returns to the original directory.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- Tree navigation semantics improved with clearer expand, enter, and cancel behavior.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-15 22:25
Task ID: BUILD-20260315-005
Agent: OpenCode
Task: build
Objective: Implement vertical scrolling so the selected entry always remains visible.
Scope:
- src/app/ui.py
- tests/test_ui.py
Files Modified:
- src/app/ui.py
- tests/test_ui.py
Key Decisions:
- Introduce scroll offsets in the UI state.
- Clamp offsets to keep the selected row visible.
- Apply the same mechanism to history mode.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- Tree and history views now scroll when navigating beyond the visible screen area.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-16 00:27
Task ID: BUILD-20260316-001
Agent: OpenCode
Task: build
Objective: Consolidate terminal UI navigation improvements and document updated behavior.
Scope:
- src/app/ui.py
- tests/test_ui.py
- docs/ai-worklog.md
- docs/ai-prompts.md
Files Modified:
- src/app/ui.py
- tests/test_ui.py
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Maintain dedicated history mode.
- Refine tree-mode keyboard behavior.
- Keep UI logic isolated from navigator logic.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- Terminal UI now includes history mode, improved navigation semantics, and reliable vertical scrolling.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-16 01:26
Task ID: BUILD-20260316-002
Agent: OpenCode
Task: build
Objective: Finalize the AI logging format system and align repository log files with the structured logging framework.
Scope:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Files Modified:
- instructions-agent.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Require timestamped log entries with date and time, Task ID, Agent, and Scope fields.
- Keep the worklog and prompt log aligned with the current structured logging framework.
- Normalize prompt logging into a single consistent `BUILD PROMPT ENTRY` format.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- The AI logging system now uses consistent structured entries across repository instructions, worklog history, and prompt history.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-16 01:34
Task ID: BUILD-20260316-003
Agent: OpenCode
Task: build
Objective: Introduce the AI agent operational framework and task generation tooling for standardized AI-assisted repository work.
Scope:
- AGENT.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
Files Modified:
- AGENT.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Define separate documents for agent behavior, operational workflow, and reusable task structure.
- Keep the task generator focused on producing standardized PLAN and BUILD prompts with task IDs and validation requirements.
- Align the new framework with the repository logging rules and validation workflow.
Validation:
- scripts/ai-task build "test task" src/app/ui.py (passed)
- make fix (passed)
- make quality (passed)
Result:
- The repository now includes a documented AI agent framework and an executable helper tool for generating standardized AI task prompts.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-16 01:45
Task ID: BUILD-20260316-004
Agent: OpenCode
Task: build
Objective: Finalize and publish the AI agent workflow, instruction framework, and task tooling updates.
Scope:
- instructions-agent.md
- AGENT.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
Files Modified:
- instructions-agent.md
- AGENT_WORKFLOW.md
- docs/ai-worklog.md
- docs/ai-prompts.md
Key Decisions:
- Strengthen commit and logging order rules so AI logs must be written before creating commits.
- Keep the new agent framework documents and task tooling aligned with the repository validation and traceability model.
- Publish the previously prepared framework files together with the finalized logging guidance on the current branch.
Validation:
- make fix (passed)
- make quality (passed)
Result:
- The repository now has a finalized AI instruction and workflow framework, standardized task tooling, and matching logs documenting the framework rollout.
Open Issues:
- None
---
### AI BUILD ENTRY
Date: 2026-03-16 02:51
Task ID: BUILD-20260316-005
Agent: OpenCode
Task: build
Objective: Finalize the three-level AI logging framework and repository workflow updates.
Scope:
- instructions-agent.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
- docs/ai-execution-log.md
Files Modified:
- instructions-agent.md
- AGENT_WORKFLOW.md
- AI_TASK_TEMPLATE.md
- scripts/ai-task
- docs/ai-worklog.md
- docs/ai-prompts.md
- docs/ai-execution-log.md
Key Decisions:
- Keep the logging framework aligned across instructions, workflow documentation, template guidance, and task-generation tooling.
- Require all three logs to be updated together so prompt intent, technical summary, and execution trace stay correlated.
- Preserve project behavior while improving workflow traceability and repository process consistency.
Validation:
- scripts/ai-task build "test task" src/app/ui.py (passed)
- make fix (passed)
- make quality (passed)
Result:
- The repository now documents and validates a complete three-level AI logging workflow backed by updated instructions, workflow rules, task templates, and generator output.
Open Issues:
- None
---

191
docs/architecture.md Normal file
View File

@@ -0,0 +1,191 @@
# cd-browser Architecture
Author: Saky
This document describes the architecture of the `cd-browser` terminal
navigation tool.
------------------------------------------------------------------------
# 1. Purpose
`cd-browser` provides a keyboarddriven terminal interface to explore
directories and return a selected path to the shell.
It solves a limitation of shells:
A program cannot directly change the parent shell directory.
Instead:
1. The application returns a path
2. A shell wrapper performs `cd`
------------------------------------------------------------------------
# 2. High Level Architecture
The project follows a layered architecture:
CLI Layer ↓ UI Layer ↓ Navigator Layer ↓ Filesystem Layer
History is used by the navigator.
------------------------------------------------------------------------
# 3. Modules
## filesystem.py
Responsibilities:
- inspect filesystem
- list directories
- detect children directories
Core structures:
DirectoryEntry
Functions:
list_directories() has_subdirectories()
------------------------------------------------------------------------
## history.py
Handles navigation history.
Features:
- visit(path)
- back()
- forward()
- select()
Used by navigator.
------------------------------------------------------------------------
## navigator.py
Core state machine of the application.
Tracks:
- current_path
- visible directory entries
- selected index
- expanded nodes
Handles:
- entering directories
- parent navigation
- tree expansion
- history integration
------------------------------------------------------------------------
## ui.py
Terminal interface using curses.
Responsibilities:
- render directory list
- highlight selection
- process keyboard input
Keys used:
↑ ↓ navigation → expand ← collapse ESC exit
------------------------------------------------------------------------
## cli.py
Application orchestrator.
Responsibilities:
- create navigator
- start terminal UI
- capture resulting path
------------------------------------------------------------------------
## main.py
Entrypoint.
Responsibilities:
- initialize logging
- start CLI flow
- print final path
------------------------------------------------------------------------
# 4. Shell Integration
Shell wrapper function:
cd\_() { local target target="$(cd_browser)"
if [ -n "$target" \] && \[ -d "$target" ]; then
cd "$target" fi }
This enables:
cd\_
to change the working directory.
------------------------------------------------------------------------
# 5. Terminal Handling
The application attaches its UI to:
/dev/tty
This allows the UI to function even when stdout is captured by shell
substitution.
stdout is reserved for:
final directory path
stderr is used for logging.
------------------------------------------------------------------------
# 6. Validation
Quality tools ensure correctness:
black -- formatting\
ruff -- linting\
mypy -- type checking\
pytest -- testing
Commands:
make fix make quality make ci
------------------------------------------------------------------------
# 7. Extensibility
Future improvements:
- enhanced navigation model
- fuzzy search
- bookmark directories
- persistent history
- configuration file
------------------------------------------------------------------------
# End

453
docs/development-journey.md Normal file
View File

@@ -0,0 +1,453 @@
# 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.

174
docs/index.md Normal file
View File

@@ -0,0 +1,174 @@
# Documentation Index --- cd-browser
Welcome to the documentation hub for **cd-browser**.
This index helps navigate all technical and project documents included
in the repository.
------------------------------------------------------------------------
# Project Documentation
## Project Overview
Highlevel explanation of the project.
**File**
docs/project_overview.md
Describes:
- what the project is
- how it works
- how to install and use it
- repository structure
------------------------------------------------------------------------
# Architecture
Technical explanation of the internal design of the application.
**File**
docs/architecture.md
Includes:
- module responsibilities
- system architecture
- shell integration model
- terminal handling
- validation pipeline
------------------------------------------------------------------------
# Development Journey
Chronological reconstruction of how the project was built.
**File**
docs/development-journey.md
Contains:
- development phases
- prompts used with AI agents
- problems encountered
- solutions applied
- decisions taken during development
------------------------------------------------------------------------
# AI Development Playbook
Reusable methodology for building software using AI coding agents.
**File**
docs/ai-development-playbook.md
Explains:
- prompt design patterns
- agent workflow
- validation loops
- best practices for AI-assisted programming
------------------------------------------------------------------------
# Functional Specifications
Defines the functional behavior of the application.
**File**
specs/cd_browser_spec.md
Describes:
- navigation model
- terminal behaviour
- keyboard controls
- application requirements
------------------------------------------------------------------------
# Template Documentation
Original documentation from the development template used to start the
project.
**File**
README_TEMPLATE.md
Preserved for reference.
------------------------------------------------------------------------
# Main Entry Points
The most important project entry points are:
## Project README
README.md
Provides:
- project description
- installation instructions
- shell integration
------------------------------------------------------------------------
# Repository Structure
cd-browser
├─ README.md
├─ README_TEMPLATE.md
├─ docs
│ ├─ index.md
│ ├─ project_overview.md
│ ├─ architecture.md
│ ├─ development-journey.md
│ └─ ai-development-playbook.md
├─ specs
│ └─ cd_browser_spec.md
├─ src
├─ tests
├─ scripts
├─ pyproject.toml
└─ Makefile
------------------------------------------------------------------------
# Reading Order Recommendation
For someone new to the project, the recommended reading order is:
1. `README.md`
2. `docs/project_overview.md`
3. `docs/architecture.md`
4. `specs/cd_browser_spec.md`
5. `docs/development-journey.md`
6. `docs/ai-development-playbook.md`
------------------------------------------------------------------------
# Purpose of This Document
This index exists to make the repository easier to understand and to
provide a clear entry point to all documentation.
------------------------------------------------------------------------
End of document.

243
docs/project_overview.md Normal file
View File

@@ -0,0 +1,243 @@
# Project Overview --- cd-browser
Author: Saky
This document provides a quick introduction to the **cd-browser**
project and guides readers through the repository structure,
documentation, and development workflow.
------------------------------------------------------------------------
# What is cd-browser?
`cd-browser` is a **terminal-based directory navigator** that allows
users to browse directories interactively and then change the working
directory of their shell.
It solves a common shell limitation:
A program cannot directly change the directory of its parent shell.
The solution is:
1. The program returns a directory path.
2. A shell wrapper function performs the actual `cd`.
------------------------------------------------------------------------
# Example usage
``` bash
cd_
```
The command launches an interactive terminal browser.
After navigating and exiting:
- the selected directory is returned
- the shell wrapper changes the working directory.
------------------------------------------------------------------------
# Key Features
- interactive terminal navigation
- tree-style directory browsing
- expandable directories
- keyboard-driven interface
- directory navigation history
- clean shell integration
- installable as a CLI tool
- tested Python codebase
- automated formatting and linting
------------------------------------------------------------------------
# Repository Structure
cd-browser/
README.md → main project documentation
README_TEMPLATE.md → original template documentation
docs/
development-journey.md
ai-development-playbook.md
architecture.md
specs/
cd_browser_spec.md
src/
app/
cli.py
filesystem.py
history.py
navigator.py
ui.py
main.py
tests/
scripts/
pyproject.toml
Makefile
------------------------------------------------------------------------
# Documentation Guide
The repository includes several documents explaining the project from
different perspectives.
## README.md
Quick introduction and installation instructions.
## specs/
Functional specifications of the application.
## docs/development-journey.md
Explains how the project was built step-by-step using AI coding agents.
## docs/ai-development-playbook.md
Reusable methodology for building applications using AI development
workflows.
## docs/architecture.md
Technical architecture of the application.
------------------------------------------------------------------------
# Installation
Clone the repository:
``` bash
git clone https://gitea.sakydogalo.es/saky/cd-browser.git
cd cd-browser
```
Install the tool:
``` bash
pip install .
```
------------------------------------------------------------------------
# Shell Integration
Add this function to your shell configuration (`~/.zshrc`):
``` bash
cd_() {
local target
target="$(cd_browser)"
if [ -n "$target" ] && [ -d "$target" ]; then
cd "$target"
fi
}
```
Reload the shell:
``` bash
source ~/.zshrc
```
Now you can run:
``` bash
cd_
```
------------------------------------------------------------------------
# Development Setup
For contributors or developers:
``` bash
make dev
source .venv/bin/activate
```
Run the application:
``` bash
python -m app.main
```
------------------------------------------------------------------------
# Quality and Validation
The project uses automated tools to ensure code quality.
Tools:
- black (formatting)
- ruff (linting)
- mypy (type checking)
- pytest (testing)
Commands:
``` bash
make fix
make quality
make ci
```
------------------------------------------------------------------------
# AI-Assisted Development
This project was built using a structured **AI-assisted development
workflow**.
Key ideas:
- architecture defined by a human
- AI agents used for focused implementation tasks
- strict validation loops
- small scoped prompts
More information:
docs/ai-development-playbook.md
------------------------------------------------------------------------
# Status
Current version:
v0.1.0
The project is stable and functional as a minimal terminal directory
navigator.
Future improvements may include:
- improved navigation model
- fuzzy search
- bookmarks
- persistent history
------------------------------------------------------------------------
# License
See the LICENSE file.
------------------------------------------------------------------------
End of document.

View File

@@ -59,3 +59,171 @@ Agent rules:
3. If the specification conflicts with a previous assumption, the specification takes precedence.
4. Keep implementation aligned with the MVP scope unless explicitly asked to extend it.
5. After code changes, run the appropriate validation workflow defined by this repository.
## AI Worklog Policy
This repository maintains an AI-assisted development log.
Files:
- `docs/ai-worklog.md`
- `docs/ai-prompts.md`
- `docs/ai-execution-log.md`
Rules:
1. After every significant `plan` or `build` task, append a concise worklog entry to `docs/ai-worklog.md`.
2. Each worklog entry must include:
- date
- task type (`plan` or `build`)
- short objective
- files inspected or modified
- key decisions
- validation commands run
- result
- unresolved issues if any
3. When a prompt meaningfully changes architecture, behavior, workflow, debugging direction, or project structure, append the prompt (or a concise cleaned version of it) to `docs/ai-prompts.md`.
4. Do not store private chain-of-thought or internal reasoning.
5. Store only concise, user-facing summaries of what was done.
6. Keep entries chronological and easy to scan.
## Mandatory AI Logging
Every significant AI interaction in this repository must be logged.
This applies to:
- `plan` tasks
- `build` tasks
- debugging tasks
- documentation tasks
- architectural discussions that affect the project
Required files:
- `docs/ai-worklog.md`
- `docs/ai-prompts.md`
- `docs/ai-execution-log.md`
Mandatory rules:
1. After every significant `plan` task, append a concise entry to `docs/ai-worklog.md`.
2. After every significant `build` task, append a concise entry to `docs/ai-worklog.md`.
3. If the task was driven by a meaningful prompt, also append an entry to `docs/ai-prompts.md`.
4. The agent must append a full execution entry to `docs/ai-execution-log.md` including:
- the full prompt provided to the agent
- the agent todo list or execution plan
- the final execution report produced by the agent
5. Logging is part of the task itself and must not be skipped.
6. The task is not complete until the logs are updated.
7. Logs must always be written **before creating a commit**.
8. The agent must ensure that the following files are updated and staged before any commit:
- `docs/ai-worklog.md`
- `docs/ai-prompts.md`
- `docs/ai-execution-log.md`
9. If a commit is created without the corresponding log entries, the task is considered incomplete and must be corrected.
10. Log entries must be part of the same commit whenever possible to maintain traceability between the code change and the AI task that produced it.
Each worklog entry must include:
- date
- task type (`plan` or `build`)
- short objective
- files inspected or modified
- key decisions
- validation commands run, if any
- result
- unresolved issues, if any
Validation logging rule:
- If validation commands such as `make fix`, `make quality`, `pytest`, or other checks are executed during the task, the worklog entry must record them explicitly.
- The value `validation: not run` may only be used if no validation commands were executed.
- The worklog entry must reflect the actual commands run during the task.
Each prompt log entry must include:
- date
- task type (`plan` or `build`)
- short prompt summary
- scope
- result summary
Rules:
- Do not store chain-of-thought or private reasoning.
- Store only concise user-facing summaries.
- Keep entries chronological.
- Even small but meaningful tasks must be logged.
Execution log entries must include:
- date
- task ID
- task type (`plan` or `build`)
- full prompt text
- agent todos
- execution report
## Standard AI Log Entry Format
To ensure consistency and readability of long AI-assisted development histories, all log entries must follow a standardized block format.
Agents must write log entries using the following structure.
Example for build tasks:
### AI BUILD ENTRY
Date: YYYY-MM-DD HH:MM
Task ID: BUILD-YYYYMMDD-XXX
Agent: OpenCode
Task: build
Objective: short description of the task
Scope:
- src/app/module.py
- tests/test_module.py
Files Modified:
- file/path/example.py
- another/file.md
Key Decisions:
- short bullet explaining important choices
Validation:
- make fix (passed)
- make quality (passed)
Result:
- short description of what changed or was achieved
Open Issues:
- optional list of unresolved problems
Example for plan tasks:
### AI PLAN ENTRY
Date: YYYY-MM-DD HH:MM
Task ID: PLAN-YYYYMMDD-XXX
Agent: OpenCode
Task: plan
Objective: short description of planning objective
Scope:
- src/app/module.py
- specs/module_spec.md
Files Inspected:
- src/app/example.py
- specs/example_spec.md
Proposed Changes:
- summary of planned changes
Notes:
- optional relevant observations
Rules:
- Always use these headers exactly (`AI BUILD ENTRY` or `AI PLAN ENTRY`).
- Keep entries concise and structured.
- Do not include chain-of-thought reasoning.
- Use bullet points when possible.
- This format must be used when updating `docs/ai-worklog.md`.
- The Date field must include both date and time using the format YYYY-MM-DD HH:MM.
- Every log entry must include a `Task ID`.
- `Task ID` format must be `BUILD-YYYYMMDD-XXX` or `PLAN-YYYYMMDD-XXX`.
- `Agent` must identify the tool or AI system performing the task (e.g., OpenCode).
- `Scope` must describe the main files or project areas affected.
- These fields make the AI worklog suitable for long-term traceability and large histories.

149
scripts/ai-task Executable file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env bash
# ai-task
# Helper CLI to generate AI task prompts based on AI_TASK_TEMPLATE.md
# Usage:
# scripts/ai-task build "Objective text" [scope...]
# scripts/ai-task plan "Objective text" [scope...]
set -e
TYPE="$1"
OBJECTIVE="$2"
shift 2 || true
SCOPE=("$@")
if [[ -z "$TYPE" || -z "$OBJECTIVE" ]]; then
echo "Usage: ai-task <plan|build> \"Objective\" [scope files...]"
exit 1
fi
TYPE_LOWER=$(echo "$TYPE" | tr '[:upper:]' '[:lower:]')
TYPE_UPPER=$(echo "$TYPE_LOWER" | tr '[:lower:]' '[:upper:]')
DATE=$(date "+%Y-%m-%d %H:%M")
DAY=$(date "+%Y%m%d")
case "$TYPE_LOWER" in
build)
PREFIX="BUILD"
;;
plan)
PREFIX="PLAN"
;;
*)
echo "Error: task type must be 'plan' or 'build'"
exit 1
;;
esac
WORKLOG_FILE="docs/ai-worklog.md"
PROMPTS_FILE="docs/ai-prompts.md"
EXECUTION_LOG_FILE="docs/ai-execution-log.md"
check_task_id_order() {
local file="$1"
local prefix="$2"
local previous=""
local current=""
[[ -f "$file" ]] || return 0
while IFS= read -r current; do
if [[ -n "$previous" && "$current" < "$previous" ]]; then
echo "Error: task IDs in $file are out of chronological order for prefix $prefix" >&2
echo "Previous: $previous" >&2
echo "Current: $current" >&2
echo "Please fix the log order before generating a new task." >&2
exit 1
fi
previous="$current"
done < <(grep -Eo "${prefix}-[0-9]{8}-[0-9]{3}" "$file" || true)
}
check_task_id_order "$WORKLOG_FILE" "$PREFIX"
check_task_id_order "$PROMPTS_FILE" "$PREFIX"
check_task_id_order "$EXECUTION_LOG_FILE" "$PREFIX"
LAST_SEQ=0
if [[ -f "$WORKLOG_FILE" ]]; then
LAST_MATCH=$(grep -Eo "${PREFIX}-${DAY}-[0-9]{3}" "$WORKLOG_FILE" | tail -n 1 || true)
if [[ -n "$LAST_MATCH" ]]; then
LAST_SEQ=${LAST_MATCH##*-}
LAST_SEQ=$((10#$LAST_SEQ))
fi
fi
NEXT_SEQ=$(printf "%03d" $((LAST_SEQ + 1)))
TASK_ID="${PREFIX}-${DAY}-${NEXT_SEQ}"
# Build scope block
cat <<EOF
Task Type:
${TYPE_UPPER}
Task ID:
${TASK_ID}
Date:
${DATE}
Objective:
${OBJECTIVE}
Context:
<describe repository state if needed>
Scope:
EOF
if [ ${#SCOPE[@]} -gt 0 ]; then
for item in "${SCOPE[@]}"; do
printf '%s\n' "- ${item}"
done
else
printf '%s\n' "- <fill scope>"
fi
cat <<EOF
Requirements:
<describe expected behavior>
Constraints:
- follow AGENT_WORKFLOW.md
- keep scope minimal
- preserve existing behavior unless explicitly changed
Testing:
<describe expected tests>
Validation:
make fix
make quality
Logging requirements:
- append entry to docs/ai-worklog.md
- append entry to docs/ai-prompts.md
- include Date, Task ID, Agent, Scope
- use Task ID: ${TASK_ID}
- maintain chronological Task ID order in ai-worklog.md, ai-prompts.md and ai-execution-log.md
- append entry to docs/ai-execution-log.md
Execution Logging requirements:
- append entry to docs/ai-execution-log.md
- include:
- full prompt
- agent todos
- final execution report
- use the standard execution log format defined in docs/ai-execution-log.md
Git requirements:
- do NOT commit or push unless explicitly requested
Expected Report:
- files changed
- behavior changes
- validation results
EOF

View File

@@ -22,6 +22,14 @@ class RenderLine:
is_selected: bool
@dataclass(frozen=True, slots=True)
class HistoryLine:
"""A rendered history row ready for terminal output."""
text: str
is_selected: bool
def move_selection(current_index: int, step: int, entry_count: int) -> int:
"""Move the selected index within the available entry range."""
@@ -57,9 +65,46 @@ def build_render_lines(navigator: Navigator) -> list[RenderLine]:
]
def build_history_lines(
entries: tuple[Path, ...], selected_index: int
) -> list[HistoryLine]:
"""Build all visible lines for history mode."""
return [
HistoryLine(text=str(path), is_selected=index == selected_index)
for index, path in enumerate(entries)
]
def clamp_scroll_offset(
selected_index: int, scroll_offset: int, visible_count: int, total_count: int
) -> int:
"""Keep the selected row within the visible scrolling window."""
if visible_count <= 0 or total_count <= visible_count:
return 0
max_offset = total_count - visible_count
offset = max(0, min(scroll_offset, max_offset))
if selected_index < offset:
return selected_index
if selected_index >= offset + visible_count:
return selected_index - visible_count + 1
return offset
class TerminalUI:
"""Minimal curses UI for the directory navigator MVP."""
def __init__(self) -> None:
self._history_mode = False
self._history_selected_index = 0
self._tree_scroll_offset = 0
self._history_scroll_offset = 0
def run(self, navigator: Navigator) -> Path:
"""Start the interactive session and return the final directory path."""
@@ -70,53 +115,52 @@ class TerminalUI:
def _run_session(self, stdscr: curses.window, navigator: Navigator) -> Path:
curses.curs_set(0)
stdscr.keypad(True)
original_path = navigator.current_path
while True:
self._render(stdscr, navigator)
key = stdscr.getch()
if key == ESCAPE_KEY:
return navigator.current_path
return original_path
if key == curses.KEY_UP:
navigator.set_selected_index(
move_selection(
navigator.selected_index,
step=-1,
entry_count=len(navigator.visible_entries),
)
)
if key == ord("h"):
self._toggle_history_mode(navigator)
continue
if key == curses.KEY_DOWN:
navigator.set_selected_index(
move_selection(
navigator.selected_index,
step=1,
entry_count=len(navigator.visible_entries),
)
)
if self._history_mode:
self._handle_history_key(key, navigator)
continue
if key == curses.KEY_RIGHT:
navigator.expand_selected_directory()
continue
if key == curses.KEY_LEFT:
navigator.collapse_selected_directory()
continue
if key in (curses.KEY_ENTER, 10, 13):
navigator.enter_selected_directory()
tree_result = self._handle_tree_key(key, navigator)
if tree_result is not None:
return tree_result
def _render(self, stdscr: curses.window, navigator: Navigator) -> None:
stdscr.erase()
height, width = stdscr.getmaxyx()
if self._history_mode:
self._render_history_mode(stdscr, navigator, width=width, height=height)
stdscr.refresh()
return
path_text = str(navigator.current_path)
stdscr.addnstr(0, 0, path_text, width - 1)
for row, line in enumerate(build_render_lines(navigator), start=2):
lines = build_render_lines(navigator)
visible_count = max(0, height - 2)
self._tree_scroll_offset = clamp_scroll_offset(
navigator.selected_index,
self._tree_scroll_offset,
visible_count,
len(lines),
)
for row, line in enumerate(
lines[self._tree_scroll_offset : self._tree_scroll_offset + visible_count],
start=2,
):
if row >= height:
break
@@ -125,6 +169,133 @@ class TerminalUI:
stdscr.refresh()
def _render_history_mode(
self, stdscr: curses.window, navigator: Navigator, width: int, height: int
) -> None:
history_lines = build_history_lines(
navigator.history.entries(), self._history_selected_index
)
start_row = 1
visible_count = max(0, height - start_row - 1)
self._history_scroll_offset = clamp_scroll_offset(
self._history_selected_index,
self._history_scroll_offset,
visible_count,
len(history_lines),
)
stdscr.addnstr(start_row, 0, "History:", width - 1, curses.A_BOLD)
for index, line in enumerate(
history_lines[
self._history_scroll_offset : self._history_scroll_offset
+ visible_count
],
start=1,
):
row = start_row + index
if row >= height:
break
attributes = curses.A_REVERSE if line.is_selected else curses.A_NORMAL
stdscr.addnstr(row, 0, line.text, width - 1, attributes)
def _toggle_history_mode(self, navigator: Navigator) -> None:
self._history_mode = not self._history_mode
if self._history_mode:
self._history_selected_index = self._get_current_history_index(navigator)
self._history_scroll_offset = 0
def _handle_history_key(self, key: int, navigator: Navigator) -> None:
history_entries = navigator.history.entries()
if key == curses.KEY_UP:
self._history_selected_index = move_selection(
self._history_selected_index,
step=-1,
entry_count=len(history_entries),
)
return
if key == curses.KEY_DOWN:
self._history_selected_index = move_selection(
self._history_selected_index,
step=1,
entry_count=len(history_entries),
)
return
if key in (curses.KEY_ENTER, 10, 13) and history_entries:
navigator.select_history_entry(self._history_selected_index)
self._history_mode = False
self._tree_scroll_offset = 0
def _handle_tree_key(self, key: int, navigator: Navigator) -> Path | None:
if key == curses.KEY_UP:
navigator.set_selected_index(
move_selection(
navigator.selected_index,
step=-1,
entry_count=len(navigator.visible_entries),
)
)
return None
if key == curses.KEY_DOWN:
navigator.set_selected_index(
move_selection(
navigator.selected_index,
step=1,
entry_count=len(navigator.visible_entries),
)
)
return None
if key == curses.KEY_RIGHT:
was_expanded = navigator.selected_entry.is_expanded
if not navigator.expand_selected_directory():
navigator.enter_selected_directory()
self._tree_scroll_offset = 0
return None
if was_expanded:
navigator.enter_selected_directory()
self._tree_scroll_offset = 0
return None
if key == curses.KEY_LEFT:
if not navigator.collapse_selected_directory():
navigator.go_to_parent_directory()
self._tree_scroll_offset = 0
return None
if key == ord("b"):
navigator.go_back()
self._tree_scroll_offset = 0
return None
if key == ord("f"):
navigator.go_forward()
self._tree_scroll_offset = 0
return None
if key in (curses.KEY_ENTER, 10, 13):
return navigator.selected_entry.path
return None
def _get_current_history_index(self, navigator: Navigator) -> int:
history_entries = navigator.history.entries()
for index in range(len(history_entries) - 1, -1, -1):
if history_entries[index] == navigator.current_path:
return index
return 0
@contextmanager
def open_terminal_streams() -> Iterator[tuple[TextIO, TextIO]]:

View File

@@ -1,11 +1,16 @@
import curses
from pathlib import Path
import pytest
from app.navigator import Navigator, VisibleEntry
from app.ui import (
HistoryLine,
RenderLine,
TerminalUI,
build_history_lines,
build_render_lines,
clamp_scroll_offset,
format_entry,
move_selection,
open_terminal_streams,
@@ -65,6 +70,157 @@ def test_build_render_lines_marks_selected_entry(tmp_path: Path) -> None:
]
def test_build_history_lines_marks_selected_history_entry(tmp_path: Path) -> None:
first = tmp_path / "first"
second = tmp_path / "second"
assert build_history_lines((first, second), selected_index=1) == [
HistoryLine(text=str(first), is_selected=False),
HistoryLine(text=str(second), is_selected=True),
]
def test_clamp_scroll_offset_keeps_selection_visible_when_moving_down() -> None:
assert clamp_scroll_offset(5, scroll_offset=0, visible_count=3, total_count=10) == 3
def test_clamp_scroll_offset_keeps_selection_visible_when_moving_up() -> None:
assert clamp_scroll_offset(1, scroll_offset=4, visible_count=3, total_count=10) == 1
def test_clamp_scroll_offset_returns_zero_when_all_items_fit() -> None:
assert clamp_scroll_offset(2, scroll_offset=1, visible_count=5, total_count=3) == 0
def test_toggle_history_mode_selects_current_history_entry(tmp_path: Path) -> None:
root = tmp_path / "root"
child = root / "child"
root.mkdir()
child.mkdir()
navigator = Navigator(root)
navigator.set_selected_index(1)
navigator.enter_selected_directory()
ui = TerminalUI()
ui._toggle_history_mode(navigator)
assert ui._history_mode is True
assert ui._history_selected_index == 1
def test_history_mode_enter_selects_entry_and_exits(tmp_path: Path) -> None:
root = tmp_path / "root"
first = root / "first"
second = root / "second"
root.mkdir()
first.mkdir()
second.mkdir()
navigator = Navigator(root)
navigator.set_selected_index(1)
navigator.enter_selected_directory()
navigator.go_to_parent_directory()
navigator.set_selected_index(2)
navigator.enter_selected_directory()
ui = TerminalUI()
ui._toggle_history_mode(navigator)
ui._handle_history_key(curses.KEY_UP, navigator)
ui._handle_history_key(10, navigator)
assert ui._history_mode is False
assert navigator.current_path == root.resolve()
assert navigator.selected_index == 0
def test_history_mode_toggle_off_keeps_current_directory(tmp_path: Path) -> None:
root = tmp_path / "root"
root.mkdir()
navigator = Navigator(root)
ui = TerminalUI()
ui._toggle_history_mode(navigator)
ui._toggle_history_mode(navigator)
assert ui._history_mode is False
assert navigator.current_path == root.resolve()
def test_right_arrow_expands_collapsed_directory(tmp_path: Path) -> None:
workspace = tmp_path / "workspace"
scripts = workspace / "scripts"
build = scripts / "build"
workspace.mkdir()
scripts.mkdir()
build.mkdir()
navigator = Navigator(workspace)
navigator.set_selected_index(1)
ui = TerminalUI()
assert ui._handle_tree_key(curses.KEY_RIGHT, navigator) is None
assert navigator.current_path == workspace.resolve()
assert [entry.name for entry in navigator.visible_entries] == [
"..",
"scripts",
"build",
]
def test_right_arrow_enters_already_expanded_directory(tmp_path: Path) -> None:
workspace = tmp_path / "workspace"
scripts = workspace / "scripts"
build = scripts / "build"
workspace.mkdir()
scripts.mkdir()
build.mkdir()
navigator = Navigator(workspace)
navigator.set_selected_index(1)
navigator.expand_selected_directory()
ui = TerminalUI()
assert ui._handle_tree_key(curses.KEY_RIGHT, navigator) is None
assert navigator.current_path == scripts.resolve()
assert navigator.selected_index == 0
def test_left_arrow_goes_to_parent_when_selected_entry_is_collapsed(
tmp_path: Path,
) -> None:
parent = tmp_path / "parent"
current = parent / "current"
child = current / "child"
parent.mkdir()
current.mkdir()
child.mkdir()
navigator = Navigator(current)
navigator.set_selected_index(1)
ui = TerminalUI()
assert ui._handle_tree_key(curses.KEY_LEFT, navigator) is None
assert navigator.current_path == parent.resolve()
assert navigator.selected_index == 0
def test_enter_returns_selected_path_without_navigating(tmp_path: Path) -> None:
workspace = tmp_path / "workspace"
child = workspace / "child"
workspace.mkdir()
child.mkdir()
navigator = Navigator(workspace)
navigator.set_selected_index(1)
ui = TerminalUI()
result = ui._handle_tree_key(10, navigator)
assert result == child.resolve()
assert navigator.current_path == workspace.resolve()
def test_open_terminal_streams_raises_without_terminal(
monkeypatch: pytest.MonkeyPatch,
) -> None: