Compare commits
16 Commits
f03417f2f2
...
v0.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
| d9d412973b | |||
| 9704d3ef5b | |||
| 0118ad9314 | |||
| e766210920 | |||
| 6849631cc1 | |||
| 7c87d6f1f0 | |||
| 60723c33bc | |||
| 6195f7b8a3 | |||
| 801544951f | |||
| 65508d263f | |||
| 2bdfbe25d5 | |||
| 12d2577a31 | |||
| 90008f149a | |||
| e481b1ae45 | |||
| 0b789b77e9 | |||
| 91a23203ed |
260
AGENT.md
Normal file
260
AGENT.md
Normal 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
298
AGENT_WORKFLOW.md
Normal 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
179
AI_TASK_TEMPLATE.md
Normal 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.
|
||||
@@ -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
|
||||
|
||||
202
docs/ai-development-playbook.md
Normal file
202
docs/ai-development-playbook.md
Normal 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
|
||||
- Codex‑style coding agents
|
||||
- LLM programming assistants
|
||||
|
||||
Goal:
|
||||
|
||||
Maintain **architectural control and code quality** while benefiting
|
||||
from AI‑accelerated 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. Anti‑Patterns
|
||||
|
||||
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
219
docs/ai-execution-log.md
Normal 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
221
docs/ai-prompts.md
Normal 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
377
docs/ai-worklog.md
Normal file
@@ -0,0 +1,377 @@
|
||||
# AI Worklog
|
||||
|
||||
This file records important AI‑assisted development actions.
|
||||
|
||||
The log is designed for long‑term traceability of AI‑driven 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 user‑focused.
|
||||
|
||||
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 long‑term 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
191
docs/architecture.md
Normal 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 keyboard‑driven 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
453
docs/development-journey.md
Normal file
@@ -0,0 +1,453 @@
|
||||
# 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.
|
||||
174
docs/index.md
Normal file
174
docs/index.md
Normal 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
|
||||
|
||||
High‑level 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
243
docs/project_overview.md
Normal 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.
|
||||
@@ -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
149
scripts/ai-task
Executable 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
|
||||
227
src/app/ui.py
227
src/app/ui.py
@@ -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]]:
|
||||
|
||||
156
tests/test_ui.py
156
tests/test_ui.py
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user