Implement complete CLI commands for MVP-1 Personal Tracker

- Refactored CLI commands from nested Typer subapps to direct command functions
- Fixed main.py to use app.command() instead of app.add_typer_command()
- Fixed project_service.py to properly load projects from YAML
- Fixed file_storage.py to save session JSON files alongside markdown
- Added missing methods: write_file, read_file, extract_autogen_section, get_recent_sessions
- Fixed root_path and repo_path to use strings instead of Path objects
This commit is contained in:
2026-03-23 09:02:21 -03:00
parent 40a33d773b
commit b36b60353d
4 changed files with 148 additions and 66 deletions

View File

@@ -35,11 +35,7 @@ markdown_writer = MarkdownWriter()
# =============================================================================
# init-project command
# =============================================================================
init_project = typer.Typer(help="Create a new project with standard structure.")
@init_project.command("init-project")
def cmd_init_project(
def init_project(
name: str = typer.Argument(..., help="Project name"),
type: str = typer.Option("misc", help="Project type (code, homelab, automation, agent, research, misc)"),
tags: str = typer.Option("", help="Comma-separated tags"),
@@ -86,11 +82,7 @@ def cmd_init_project(
# =============================================================================
# list command
# =============================================================================
list_projects = typer.Typer(help="List all projects.")
@list_projects.command("list")
def cmd_list_projects() -> None:
def list_projects_cmd() -> None:
"""Show all projects with their status, last session, and next steps."""
projects = list_projects()
@@ -125,11 +117,7 @@ def cmd_list_projects() -> None:
# =============================================================================
# show command
# =============================================================================
show_project = typer.Typer(help="Show project details.")
@show_project.command("show")
def cmd_show_project(slug: str = typer.Argument(..., help="Project slug")) -> None:
def show_project(slug: str = typer.Argument(..., help="Project slug")) -> None:
"""Show detailed project information including status, context, last summary, blockers, and next steps."""
# Load project
project_dict = storage.read_project_meta(slug)
@@ -185,11 +173,7 @@ def cmd_show_project(slug: str = typer.Argument(..., help="Project slug")) -> No
# =============================================================================
# start command
# =============================================================================
start_session = typer.Typer(help="Start a work session.")
@start_session.command("start")
def cmd_start_session(
def start_session(
slug: str = typer.Argument(..., help="Project slug"),
objective: Optional[str] = typer.Option(None, help="Session objective"),
) -> None:
@@ -248,11 +232,7 @@ def cmd_start_session(
# =============================================================================
# note command
# =============================================================================
add_note_cmd = typer.Typer(help="Add a note to the active session.")
@add_note_cmd.command("note")
def cmd_add_note(
def add_note_cmd(
text: str = typer.Argument(..., help="Note text"),
type: str = typer.Option("work", help="Note type (work, change, blocker, decision, idea, reference)"),
) -> None:
@@ -291,11 +271,7 @@ def cmd_add_note(
# =============================================================================
# stop command
# =============================================================================
stop_session = typer.Typer(help="Stop the current session.")
@stop_session.command("stop")
def cmd_stop_session(
def stop_session(
slug: str = typer.Argument(..., help="Project slug"),
add_to_changelog: bool = typer.Option(False, "--changelog", help="Add session summary to CHANGELOG.md"),
) -> None:
@@ -386,11 +362,7 @@ def cmd_stop_session(
# =============================================================================
# change command
# =============================================================================
add_change = typer.Typer(help="Add a change entry to CHANGELOG.md.")
@add_change.command("change")
def cmd_add_change(
def add_change(
slug: str = typer.Argument(..., help="Project slug"),
type: str = typer.Option("code", help="Change type (code, infra, config, docs, automation, decision)"),
title: str = typer.Option(..., help="Change title"),
@@ -418,11 +390,7 @@ def cmd_add_change(
# =============================================================================
# next command
# =============================================================================
suggest_next = typer.Typer(help="Suggest next steps for a project.")
@suggest_next.command("next")
def cmd_suggest_next(slug: str = typer.Argument(..., help="Project slug")) -> None:
def suggest_next(slug: str = typer.Argument(..., help="Project slug")) -> None:
"""Suggest next steps based on project history and heuristics.
Uses simple rules:
@@ -487,11 +455,7 @@ def cmd_suggest_next(slug: str = typer.Argument(..., help="Project slug")) -> No
# =============================================================================
# review command
# =============================================================================
review = typer.Typer(help="Review all projects.")
@review.command("review")
def cmd_review() -> None:
def review() -> None:
"""Show an overview of all projects.
Displays:
@@ -698,7 +662,7 @@ def _update_readme_autogen(slug: str, session: Session) -> None:
# Register all commands at module level for direct access
__all__ = [
"init_project",
"list_projects",
"list_projects_cmd",
"show_project",
"start_session",
"add_note_cmd",