---
phase: 04-foundation-flat-list-visual-chrome
plan: "01"
type: execute
wave: 1
depends_on: []
files_modified:
  - possession/tui/screens/main.py
  - possession/tui/widgets/breadcrumb.py
autonomous: false
requirements:
  - VIEW-01
  - TOPBAR-01

must_haves:
  truths:
    - "Running the app shows all inventory items in a flat DataTable without any drill-down"
    - "Pressing 'e' on a selected item opens EditItemScreen immediately (no silent no-op)"
    - "Pressing 'd' on a selected item shows delete confirmation immediately (no silent no-op)"
    - "A persistent 'Possession' label is visible at the top of the screen at all times"
    - "No Breadcrumb widget appears anywhere in the app"
    - "Pressing 'q' exits the app from the main screen"
  artifacts:
    - path: "possession/tui/screens/main.py"
      provides: "Flat-list MainScreen with no drill-down state machine"
      contains: "_load_items"
    - path: "possession/tui/widgets/breadcrumb.py"
      provides: "Dead code preserved but not imported or used"
  key_links:
    - from: "possession/tui/screens/main.py"
      to: "possession/db/models.py"
      via: "list_items(self.app.db_path) in _load_items()"
      pattern: "list_items\\(self\\.app\\.db_path\\)"
    - from: "possession/tui/screens/main.py"
      to: "possession/tui/screens/edit.py"
      via: "push_screen(EditItemScreen(...)) in action_edit_item()"
      pattern: "push_screen.*EditItemScreen"
---

<objective>
Remove the drill-down state machine from MainScreen and replace it with a flat list that always shows all items. Add a persistent top bar replacing the Breadcrumb widget.

Purpose: VIEW-01 is the load-bearing foundation for the entire v1.1 milestone — all subsequent phases (Phase 5 stats bar, Phase 6 filter pickers) require the flat-list architecture. TOPBAR-01 is bundled here because it replaces the visual role of Breadcrumb, which is deleted in this same commit.

Output: A fully functional MainScreen that boots directly into a flat item list, with 'e'/'d'/'a' all working without any _view_mode guards.
</objective>

<execution_context>
@/Users/paritoshpatil/.claude/get-shit-done/workflows/execute-plan.md
@/Users/paritoshpatil/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/04-foundation-flat-list-visual-chrome/04-RESEARCH.md
@possession/tui/screens/main.py
@possession/tui/widgets/breadcrumb.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Remove drill-down state machine — migrate MainScreen to flat list (VIEW-01)</name>
  <files>possession/tui/screens/main.py</files>
  <action>
    Replace the three-mode drill-down state machine in MainScreen with a flat-list-only screen. This is a single coordinated change — ALL nine locations must be updated in the same edit. Do not make a partial migration.

    **Step 1: Update `__init__()` — remove drill-down state variables**
    Remove from `__init__()`:
    - `self._view_mode`
    - `self._current_room_id`
    - `self._current_room_name`
    - `self._current_container_id`
    - `self._current_container_name`

    Keep: `self._items`, `self._last_key`, `self._delete_pending_id`, `self._confirm_mode`
    Add (if not already present): `self._filter_text: str = ""`

    **Step 2: Update `compose()` — remove Breadcrumb, add top bar Static**
    - Remove the `Breadcrumb` yield and its import
    - Remove `_update_breadcrumb()` method entirely (and all its call sites)
    - Add `yield Static("Possession", id="topbar")` as the FIRST widget yielded
    - Import `Static` from `textual.widgets` at the top of the file

    Updated compose order:
    ```python
    yield Static("Possession", id="topbar")
    yield DataTable(cursor_type="row", show_header=True)
    yield Input(placeholder="Filter... (/ to open, Esc to clear)", id="filter-input", classes="hidden")
    yield QuickAddBar(id="quickadd-bar", classes="hidden")
    yield Input(placeholder="Delete item? [y/N]", id="delete-confirm", classes="hidden")
    ```

    **Step 3: Add top bar CSS to MainScreen.DEFAULT_CSS**
    Add to DEFAULT_CSS:
    ```
    #topbar {
        dock: top;
        height: 1;
        background: $primary-darken-2;
        color: $text;
        padding: 0 1;
        text-style: bold;
    }
    ```
    Remove any Breadcrumb-specific CSS rules from DEFAULT_CSS.

    **Step 4: Replace `_load_view()` with `_load_items()`**
    Delete `_load_view()` entirely. Add new `_load_items()`:
    ```python
    def _load_items(self) -> None:
        """Load all items and refresh the DataTable. No drill-down branches."""
        table = self.query_one(DataTable)
        try:
            table.clear(columns=True)
        except TypeError:
            table.clear()
        table.add_columns("Name", "Description", "Location", "Category", "Cost")
        self._items = list_items(self.app.db_path)
        self._apply_filter(self._filter_text)
    ```

    **Step 5: Replace `_apply_filter()` — items-only branch only**
    Remove the three-way branch (rooms / containers / items). The new `_apply_filter()` always filters items:
    ```python
    def _apply_filter(self, query: str) -> None:
        """Filter the DataTable by query string (case-insensitive). Items only."""
        self._filter_text = query
        table = self.query_one(DataTable)
        table.clear()
        q = query.lower().strip()
        for item in self._items:
            if q and not any(
                q in (item.get(f) or "").lower()
                for f in ("name", "description", "room_name",
                          "container_name", "category_name")
            ):
                continue
            table.add_row(
                item["name"],
                item.get("description") or "",
                _fmt_location(item),
                item.get("category_name") or "",
                _fmt_cost(item.get("cost")),
                key=str(item["id"]),
            )
    ```

    **Step 6: Update `on_mount()` — remove `_view_mode = "rooms"`, call `_load_items()` directly**
    Replace `_load_view()` call with `_load_items()`.
    Remove `self._view_mode = "rooms"` line.

    **Step 7: Update `on_screen_resume()`**
    Replace any `_load_view()` call with `_load_items()`.

    **Step 8: Remove `_view_mode` guards from action methods**
    In `action_edit_item()`: remove `if self._view_mode != "items": return`
    In `action_delete_item()`: remove `if self._view_mode != "items": return`
    In `on_data_table_row_selected()`: remove the drill-down logic. In Phase 4, Enter on a row is a no-op (Phase 5 will wire it to detail panel). Replace the entire body with `return`.

    **Step 9: Replace `action_go_back()` body with single-line exit**
    ```python
    def action_go_back(self) -> None:
        self.app.exit()
    ```

    **Step 10: Remove unused imports**
    Remove imports of `list_rooms`, `list_containers` if not used elsewhere.
    Keep `list_items` import.
    Remove `Breadcrumb` import.

    **Verification checklist (apply after writing):**
    - Search `_view_mode` in main.py — zero occurrences expected
    - Search `_current_room` in main.py — zero occurrences expected
    - Search `Breadcrumb` in main.py — zero occurrences expected
    - Search `_load_view` in main.py — zero occurrences expected
    - Search `_update_breadcrumb` in main.py — zero occurrences expected
  </action>
  <verify>
    <automated>cd /Users/paritoshpatil/Personal/claude-projects/possession-terminal-2 && python -c "from possession.tui.screens.main import MainScreen; print('import ok')" && grep -c "_view_mode" possession/tui/screens/main.py | xargs -I{} test {} -eq 0 && echo "no _view_mode guards remain"</automated>
    <manual>Run `python -m possession` and verify: flat item list appears directly on launch (no "Select a room" prompt), pressing 'e' on an item opens EditItemScreen, pressing 'd' shows delete confirmation, 'q' exits.</manual>
  </verify>
  <done>
    - `_view_mode` appears 0 times in main.py
    - `Breadcrumb` appears 0 times in main.py
    - `_load_view` appears 0 times in main.py
    - App imports without error
    - `_load_items()` is the sole data-loading method
    - `Static("Possession", id="topbar")` is first widget in compose()
  </done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <name>Checkpoint: Verify flat list and top bar work end-to-end</name>
  <files>N/A — human verification, no files modified</files>
  <action>Human verifies the flat list and Possession top bar are working correctly in the live app.</action>
  <what-built>
    Flat-list MainScreen with VIEW-01 (drill-down removed) and TOPBAR-01 (persistent Possession header). All item actions (e/d/a) now work unconditionally. q exits the app.
  </what-built>
  <how-to-verify>
    1. Run: `python -m possession`
    2. Expected: App launches directly into a flat DataTable showing all items (no "Rooms" list, no drill-down)
    3. Expected: A bold "Possession" bar is visible at the top of the screen
    4. Navigate to an item row with j/k. Press 'e' — EditItemScreen should open immediately
    5. Press Escape to return. Press 'd' on any item — delete confirmation should appear
    6. Press 'n' to cancel. Press 'a' — QuickAddBar should open
    7. Press Escape to close. Press 'q' — app should exit
    8. Verify: No colored bar with empty text exists anywhere (old Breadcrumb would show as blank)
  </how-to-verify>
  <verify>Human confirms all 8 checks pass by typing "approved"</verify>
  <done>User types "approved" — flat list and top bar confirmed working</done>
  <resume-signal>Type "approved" if all 8 checks pass, or describe any issues</resume-signal>
</task>

</tasks>

<verification>
- `grep -n "_view_mode" possession/tui/screens/main.py` returns empty
- `grep -n "Breadcrumb" possession/tui/screens/main.py` returns empty
- `python -c "from possession.tui.screens.main import MainScreen"` exits 0
- `grep -n "topbar" possession/tui/screens/main.py` shows the Static widget
- `grep -n "_load_items" possession/tui/screens/main.py` shows method definition and all call sites
</verification>

<success_criteria>
- MainScreen shows flat item list on launch — no drill-down state machine
- 'e', 'd', 'a' all work without guards on the flat list
- "Possession" top bar is always visible
- Breadcrumb is gone from compose() and imports
- `python -m possession` starts without import errors
</success_criteria>

<output>
After completion, create `.planning/phases/04-foundation-flat-list-visual-chrome/04-01-SUMMARY.md`
</output>
