feat: add list command with global filters

This commit is contained in:
Rogee
2025-10-29 16:08:46 +08:00
parent 88563d48e2
commit fa57af8a26
29 changed files with 1892 additions and 25 deletions

View File

@@ -0,0 +1,34 @@
# Specification Quality Checklist: Cobra List Command with Global Filters
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-10-29
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan`

View File

@@ -0,0 +1,59 @@
# CLI Contract: `renamer list`
## Command Synopsis
```bash
renamer list [--path <dir>] [-r] [-d] [-e .ext|.ext2] [--format table|plain]
```
## Description
Enumerates filesystem entries that match the active global filters without applying any rename
operations. Output supports human-friendly table view and automation-friendly plain mode. Results
mirror the candidate set used by `renamer preview` and `renamer rename`.
## Arguments & Flags
| Flag | Type | Default | Required | Applies To | Description |
|------|------|---------|----------|------------|-------------|
| `--path` | string | current directory | No | root command | Directory to operate on; must exist and be readable |
| `-r`, `--recursive` | bool | `false` | No | root command | Enable depth-first traversal through subdirectories |
| `-d`, `--include-dirs` | bool | `false` | No | root command | Include directories in output alongside files |
| `-e`, `--extensions` | string | (none) | No | root command | `|`-delimited list of `.`-prefixed extensions used to filter files |
| `--format` | enum (`table`, `plain`) | `table` | No | list subcommand | Controls output rendering style |
| `--limit` | int | 0 (no limit) | No | list subcommand | Optional cap on number of entries returned; 0 means unlimited |
| `--no-progress` | bool | `false` | No | list subcommand | Suppress progress indicators for scripting |
## Exit Codes
| Code | Meaning | Example Trigger |
|------|---------|-----------------|
| `0` | Success | Listing completed even if zero entries matched |
| `2` | Validation error | Duplicate/empty extension token, unreadable path |
| `3` | Traversal failure | I/O error during directory walk |
## Output Formats
### Table (default)
```
PATH TYPE SIZE
photos/2024/event.jpg file 3.2 MB
photos/2024 directory —
```
### Plain (`--format plain`)
```
photos/2024/event.jpg
photos/2024
```
Both formats MUST include a trailing summary line:
```
Total: 42 entries (files: 38, directories: 4)
```
## Validation Rules
- Extensions MUST begin with `.` and be deduplicated case-insensitively.
- When no entries remain after filtering, the command prints `No entries matched the provided
filters.` and exits with code `0`.
- Symlinks MUST be reported with type `symlink` and NOT followed recursively unless future scope
explicitly enables it.

View File

@@ -0,0 +1,40 @@
# Data Model: Cobra List Command with Global Filters
## Entities
### ListingRequest
- **Description**: Captures the users desired listing scope and presentation options.
- **Fields**:
- `workingDir` (string): Absolute or relative path where traversal begins. Default: current dir.
- `includeDirectories` (bool): Mirrors `-d` flag; when true, directories appear in results.
- `recursive` (bool): Mirrors `-r` flag; enables depth-first traversal of subdirectories.
- `extensions` ([]string): Parsed, normalized list of `.`-prefixed extensions from `-e`.
- `format` (enum): Output format requested (`table`, `plain`).
- `maxDepth` (int, optional): Future-safe guard to prevent runaway recursion; defaults to unlimited.
- **Validations**:
- `extensions` MUST NOT contain empty strings or duplicates after normalization.
- `format` MUST be one of the supported enum values; invalid values trigger validation errors.
- `workingDir` MUST resolve to an accessible directory before traversal begins.
### ListingEntry
- **Description**: Represents a single filesystem node returned by the list command.
- **Fields**:
- `path` (string): Relative path from `workingDir`.
- `type` (enum): `file`, `directory`, or `symlink`.
- `sizeBytes` (int64): File size in bytes; directories report aggregated size only if available.
- `depth` (int): Depth level from the root directory (root = 0).
- `matchedExtension` (string, optional): Extension that satisfied the filter when applicable.
- **Validations**:
- `path` MUST be unique within a single command invocation.
- `type` MUST align with actual filesystem metadata; symlinks MUST be flagged to avoid confusion.
## Relationships
- `ListingRequest` produces a stream of `ListingEntry` items based on traversal rules.
- `ListingEntry` items may reference parent directories implicitly via `path` hierarchy; no explicit
parent pointer is stored to keep payload lightweight.
## State Transitions
1. **Initialization**: CLI parses flags into `ListingRequest` and validates inputs.
2. **Traversal**: Request feeds traversal engine, emitting raw filesystem metadata.
3. **Filtering**: Raw entries filtered against `includeDirectories`, `recursive`, and `extensions`.
4. **Formatting**: Filtered entries passed to output renderer selecting table or plain layout.

View File

@@ -0,0 +1,99 @@
# Implementation Plan: Cobra List Command with Global Filters
**Branch**: `001-list-command-filters` | **Date**: 2025-10-29 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/001-list-command-filters/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
## Summary
Introduce a Cobra `list` subcommand that enumerates filesystem entries using the same global filter
flags (`-r`, `-d`, `-e`) shared with preview/rename flows. The command will reuse traversal and
validation utilities to guarantee consistent candidate sets, provide table/plain output formats, and
surface clear messaging for empty results or invalid filters.
## Technical Context
<!--
ACTION REQUIRED: Replace the content in this section with the technical details
for the project. The structure here is presented in advisory capacity to guide
the iteration process.
-->
**Language/Version**: Go 1.24
**Primary Dependencies**: `spf13/cobra`, `spf13/pflag`
**Storage**: Local filesystem (read-only listing)
**Testing**: Go `testing` package with CLI-focused integration tests
**Target Platform**: Cross-platform CLI (Linux, macOS, Windows)
**Project Type**: Single CLI project
**Performance Goals**: First page of 5k entries within 2 seconds via streaming output
**Constraints**: Deterministic ordering, no filesystem mutations, filters shared across commands
**Scale/Scope**: Operates on directories with tens of thousands of entries per invocation
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Preview flow MUST show deterministic rename mappings and require explicit confirmation (Preview-First Safety).
- Undo strategy MUST describe how the `.renamer` ledger entry is written and reversed (Persistent Undo Ledger).
- Planned rename rules MUST document their inputs, validations, and composing order (Composable Rule Engine).
- Scope handling MUST cover files vs directories (`-d`), recursion (`-r`), and extension filtering via `-e` without escaping the requested path (Scope-Aware Traversal).
- CLI UX plan MUST confirm Cobra usage, flag naming, help text, and automated tests for preview/undo flows (Ergonomic CLI Stewardship).
**Gate Alignment**:
- Listing command will remain a read-only helper; preview/rename confirmation flow stays unchanged.
- Ledger logic untouched; plan maintains append-only guarantees by reusing existing history modules.
- Filters, traversal, and rule composition will be centralized to avoid divergence between commands.
- Root-level flags (`-r`, `-d`, `-e`) will configure shared traversal services so all subcommands honor identical scope rules.
- Cobra command UX will include consistent help text, validation errors, and integration tests for list/preview parity.
## Project Structure
### Documentation (this feature)
```text
specs/001-list-command-filters/
├── plan.md # This file (/speckit.plan command output)
├── research.md # Phase 0 output (/speckit.plan command)
├── data-model.md # Phase 1 output (/speckit.plan command)
├── quickstart.md # Phase 1 output (/speckit.plan command)
├── contracts/ # Phase 1 output (/speckit.plan command)
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```
### Source Code (repository root)
<!--
ACTION REQUIRED: Replace the placeholder tree below with the concrete layout
for this feature. Delete unused options and expand the chosen structure with
real paths (e.g., apps/admin, packages/something). The delivered plan must
not include Option labels.
-->
```text
cmd/
├── root.go # Cobra root command with global flags
├── list.go # New list subcommand entry point
└── preview.go # Existing preview wiring (to be reconciled with shared filters)
internal/
├── traversal/ # Scope walking utilities (files, directories, recursion)
├── filters/ # Extension parsing/validation shared across commands
├── listing/ # New package composing traversal + formatting
└── output/ # Shared renderers for table/plain display
tests/
├── contract/
│ └── list_command_test.go
├── integration/
│ └── list_and_preview_parity_test.go
└── fixtures/ # Sample directory trees for CLI tests
```
**Structure Decision**: Single CLI repository rooted at `cmd/` with supporting packages under
`internal/`. Shared traversal and filter logic will move into dedicated packages to ensure the
global flags are consumed identically by `list`, `preview`, and rename workflows. Tests live under
`tests/` mirroring contract vs integration coverage.
## Complexity Tracking
No constitution gate violations identified; no additional complexity justifications required.

View File

@@ -0,0 +1,60 @@
# Quickstart: Cobra List Command with Global Filters
## Goal
Learn how to preview rename scope safely by using the new `renamer list` subcommand with global
filter flags that apply across all commands.
## Prerequisites
- Go toolchain installed (>= 1.24) for building the CLI locally.
- Sample directory containing mixed file types to exercise filters.
## Steps
1. **Build the CLI**
```bash
go build -o renamer ./...
```
2. **Inspect available commands and global flags**
```bash
./renamer --help
./renamer list --help
```
Confirm `-r`, `-d`, and `-e` are listed as global flags.
3. **List JPEG assets recursively**
```bash
./renamer list -r -e .jpg
```
Verify output shows a table with relative paths, types, and sizes. The summary line should report
total entries found.
4. **Produce automation-friendly output**
```bash
./renamer list --format plain -e .mov|.mp4 > media-files.txt
```
Inspect `media-files.txt` to confirm one path per line.
5. **Validate filter parity with preview**
```bash
./renamer list -r -d -e .txt|.md
./renamer preview -r -d -e .txt|.md
```
Ensure both commands report the same number of directories, since `-d` suppresses files.
6. **Handle empty results gracefully**
```bash
./renamer list -e .doesnotexist
```
Expect a friendly message explaining that no entries matched the filters.
7. **Inspect hidden files when needed**
```bash
./renamer list --hidden -e .env
```
Hidden entries are excluded by default, so `--hidden` opts in explicitly when you need to audit dotfiles.
## Next Steps
- Integrate the list command into scripts that currently run `preview` to guard against unintended
rename scopes.
- Extend automated tests to cover new filters plus list/preview parity checks.

View File

@@ -0,0 +1,33 @@
# Phase 0 Research: Cobra List Command with Global Filters
## Decision: Promote scope flags to Cobra root command persistent flags
- **Rationale**: Persistent flags defined on the root command automatically apply to all
subcommands, ensuring a single source of truth for recursion (`-r`), directory inclusion (`-d`),
and extension filters (`-e`). This prevents divergence between `list`, `preview`, and future
rename commands.
- **Alternatives considered**:
- *Duplicate flag definitions per subcommand*: rejected because it risks inconsistent validation
and requires keeping help text in sync.
- *Environment variables for shared filters*: rejected because CLI users expect flag-driven scope
control and env vars complicate scripting.
## Decision: Stream directory traversal using `filepath.WalkDir` with early emission
- **Rationale**: `WalkDir` supports depth-first traversal with built-in symlink detection and allows
emitting entries as they are encountered, keeping memory usage bounded even for directories with
>10k items.
- **Alternatives considered**:
- *Preloading all entries into slices before formatting*: rejected because it inflates memory and
delays first output, violating the 2-second responsiveness goal.
- *Shelling out to `find` or OS-specific tools*: rejected due to portability concerns and reduced
testability inside Go.
## Decision: Provide dual output renderers (table + plain) via shared formatter interface
- **Rationale**: Implementing a small formatter interface allows easy expansion of output modes and
keeps the list command decoupled from presentation details. A table renderer can rely on
text/tabwriter, while the plain renderer writes newline-delimited paths to satisfy scripting use
cases.
- **Alternatives considered**:
- *Hard-coding formatted strings inside the command*: rejected because it complicates testing and
future format additions (JSON, CSV).
- *Introducing a heavy templating library*: rejected as unnecessary overhead for simple CLI
output.

View File

@@ -0,0 +1,151 @@
# Feature Specification: Cobra List Command with Global Filters
**Feature Branch**: `001-list-command-filters`
**Created**: 2025-10-29
**Status**: Draft
**Input**: User description: "实现文件列表遍历展示cobra 子命令list支持当前系统要求的过滤参数过滤参数为全局生效所以应该指定到root command上。"
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Discover Filtered Files Before Renaming (Priority: P1)
As a command-line user preparing a batch rename, I want to run `renamer list` with the same filters
that the rename command will honor so I can preview the exact files that will be affected.
**Why this priority**: Prevents accidental renames by making scope explicit before any destructive
action.
**Independent Test**: Execute `renamer list -e .jpg|.png` in a sample directory and verify the output
lists only matching files without performing any rename.
**Acceptance Scenarios**:
1. **Given** a directory containing mixed file types, **When** the user runs `renamer list -e .jpg`,
**Then** the output only includes `.jpg` files and reports the total count.
2. **Given** a directory tree with nested folders, **When** the user runs `renamer list -r`,
**Then** results include files from subdirectories with each entry showing the relative path.
---
### User Story 2 - Apply Global Filters Consistently (Priority: P2)
As an operator scripting renamer commands, I want filter flags (`-r`, `-d`, `-e`) to be defined on
the root command so they apply consistently to `list`, `preview`, and future subcommands without
redundant configuration.
**Why this priority**: Ensures a single source of truth for scope filters, reducing user error and
documentation complexity.
**Independent Test**: Run `renamer list` and `renamer preview` with the same global flags in a
script, confirming both commands interpret scope identically.
**Acceptance Scenarios**:
1. **Given** the root command defines global filter flags, **When** the user specifies `--extensions
.mov|.mp4` with `renamer list`, **Then** running `renamer preview` in the same shell session with
identical flags produces the same candidate set.
---
### User Story 3 - Review Listing Output Comfortably (Priority: P3)
As a user reviewing large directories, I want the `list` output to provide human-readable columns
and an optional machine-friendly format so I can spot issues quickly or pipe results into other
tools.
**Why this priority**: Good ergonomics encourage the list command to become part of every workflow,
increasing safety and adoption.
**Independent Test**: Run `renamer list --format table` and `renamer list --format plain` to confirm
both modes display the same entries in different formats without extra configuration.
**Acceptance Scenarios**:
1. **Given** the list command is executed with default settings, **When** multiple files are
returned, **Then** the output presents aligned columns containing path, type (file/directory),
and size.
2. **Given** the user supplies `--format plain`, **When** the command runs, **Then** the output
emits one path per line suitable for piping into other commands.
---
### Edge Cases
- Directory contains no items after filters are applied; command must exit gracefully with zero
results and a clear message.
- Filters include duplicate or malformed extensions (e.g., `-e .jpg||.png`); command must reject the
input and surface a descriptive validation error.
- Listing directories requires read permissions; command must skip unreadable paths, log warnings,
and continue scanning allowed paths.
- File system contains symbolic links or junctions; traversal must avoid infinite loops and clearly
mark symlinked entries.
- Large directories (>10k entries); command must stream results without excessive memory usage and
display progress feedback when execution exceeds a user-friendly threshold.
- Hidden files may be unintentionally included; unless `--hidden` is provided, they must remain
excluded and the help text should explain how to opt in.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The root Cobra command MUST expose global filter flags for recursion (`-r`), directory
inclusion (`-d`), and extension filtering (`-e .ext|.ext2`) that apply to all subcommands.
- **FR-002**: The `list` subcommand MUST enumerate files and directories matching the active filters
within the current (or user-specified) working directory without modifying the filesystem.
- **FR-003**: Listing results MUST be deterministic: entries sorted lexicographically by relative
path with directories identified distinctly from files.
- **FR-004**: The command MUST support at least two output formats: a human-readable table (default)
and a plain-text list (`--format plain`) for automation.
- **FR-005**: When filters exclude all entries, the CLI MUST communicate that zero results were
found and suggest reviewing filter parameters.
- **FR-006**: The `list` subcommand MUST share validation and traversal utilities with preview and
rename flows to guarantee identical scope resolution across commands.
- **FR-007**: The command MUST return a non-zero exit code when input validation fails and zero when
execution completes successfully, enabling scripting.
- **FR-008**: Hidden files and directories MUST be excluded by default and only included when users
explicitly pass a `--hidden` flag.
### Key Entities *(include if feature involves data)*
- **ListingRequest**: Captures active filters (recursion, directory inclusion, extensions, path) and
desired output format for a listing invocation.
- **ListingEntry**: Represents a single file or directory discovered during traversal, including its
relative path, type, size (bytes), and depth.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Users can execute `renamer list` with filters on a directory containing up to 5,000
entries and receive the first page of results within 2 seconds.
- **SC-002**: In usability testing, 90% of participants correctly predict which files will be renamed
after reviewing `renamer list` output.
- **SC-003**: Automated regression tests confirm that `list`, `preview`, and `rename` commands return
identical candidate counts for the same filter combinations in 100% of tested scenarios.
- **SC-004**: Support requests related to "unexpected files being renamed" decrease by 30% in the
first release cycle following launch.
## Assumptions
- Default output format is a table suitable for terminals with ANSI support; plain text is available
for scripting without additional flags beyond `--format`.
- Users run commands from the directory they intend to operate on; specifying alternative roots will
follow existing conventions (e.g., `--path`) if already provided by the tool.
- Existing preview and rename workflows already rely on shared traversal utilities that can be
extended for the list command.
## Dependencies & Risks
- Requires traversal utilities to handle large directories efficiently; performance optimizations may
be needed if current implementation does not stream results.
- Depends on existing validation logic for extension filtering and directory scopes; any divergence
introduces inconsistency between commands.
- Risk of confusing users if help documentation is not updated to emphasize using `list` before
running rename operations.
## Clarifications
### Session 2025-10-29
- Q: Should the list command include hidden files by default or require an explicit opt-in? → A:
Exclude hidden files by default; add a `--hidden` flag to include them.

View File

@@ -0,0 +1,175 @@
# Tasks: Cobra List Command with Global Filters
**Input**: Design documents from `/specs/001-list-command-filters/`
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
**Tests**: Tests are optional; include them only where they support the user storys independent validation.
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Prepare Cobra project for new subcommand and tests
- [X] T001 Normalize root command metadata and remove placeholder toggle flag in `cmd/root.go`
- [X] T002 Scaffold listing service package with stub struct in `internal/listing/service.go`
- [X] T003 Add fixture guidance for sample directory trees in `tests/fixtures/README.md`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core utilities shared across list, preview, and rename flows
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
- [X] T004 Define `ListingRequest`/`ListingEntry` structs with validators in `internal/listing/types.go`
- [X] T005 [P] Implement extension filter parser/normalizer in `internal/filters/extensions.go`
- [X] T006 [P] Implement streaming traversal walker with symlink guard in `internal/traversal/walker.go`
- [X] T007 [P] Declare formatter interface and summary helpers in `internal/output/formatter.go`
- [X] T008 Document global filter contract expectations in `docs/cli-flags.md`
**Checkpoint**: Foundation ready—user story implementation can now begin in parallel
---
## Phase 3: User Story 1 - Discover Filtered Files Before Renaming (Priority: P1) 🎯 MVP
**Goal**: Provide a read-only `renamer list` command that mirrors rename scope
**Independent Test**: Run `renamer list -e .jpg|.png` against fixtures and verify results/summary without filesystem changes
### Tests for User Story 1 (OPTIONAL - included for confidence)
- [X] T009 [P] [US1] Add contract test for filtered listing summary in `tests/contract/list_command_test.go`
- [X] T010 [P] [US1] Add integration test covering recursive listing in `tests/integration/list_recursive_test.go`
### Implementation for User Story 1
- [X] T011 [US1] Implement listing pipeline combining traversal, filters, and summary in `internal/listing/service.go`
- [X] T012 [US1] Implement zero-result messaging helper in `internal/listing/summary.go`
- [X] T013 [US1] Add Cobra `list` command entry point in `cmd/list.go`
- [X] T014 [US1] Register `list` command and write help text in `cmd/root.go`
- [X] T015 [US1] Update quickstart usage section for `renamer list` workflow in `specs/001-list-command-filters/quickstart.md`
**Checkpoint**: User Story 1 delivers a safe, filter-aware listing command
---
## Phase 4: User Story 2 - Apply Global Filters Consistently (Priority: P2)
**Goal**: Ensure scope flags (`-r`, `-d`, `-e`) live on the root command and hydrate shared request builders
**Independent Test**: Execute `renamer list` twice—once via command parsing, once via helper—and confirm identical candidate counts
### Implementation for User Story 2
- [X] T016 [P] [US2] Promote scope flags to persistent flags on the root command in `cmd/root.go`
- [X] T017 [US2] Create shared flag extraction helper returning `ListingRequest` in `internal/listing/options.go`
- [X] T018 [US2] Refactor `cmd/list.go` to consume shared helper and root-level flags
- [X] T019 [P] [US2] Add integration test validating flag parity in `tests/integration/global_flag_parity_test.go`
- [X] T020 [US2] Expand CLI flag documentation for global usage patterns in `docs/cli-flags.md`
**Checkpoint**: User Story 2 guarantees consistent scope interpretation across commands
---
## Phase 5: User Story 3 - Review Listing Output Comfortably (Priority: P3)
**Goal**: Offer table and plain output modes for human review and scripting
**Independent Test**: Run `renamer list --format table` vs `--format plain` and ensure entries match across formats
### Implementation for User Story 3
- [X] T021 [P] [US3] Implement table renderer using `text/tabwriter` in `internal/output/table.go`
- [X] T022 [P] [US3] Implement plain renderer emitting newline-delimited paths in `internal/output/plain.go`
- [X] T023 [US3] Wire format selection into listing service dispatcher in `internal/listing/service.go`
- [X] T024 [US3] Extend contract tests to verify format output parity in `tests/contract/list_command_test.go`
- [X] T025 [US3] Update quickstart to demonstrate `--format` options in `specs/001-list-command-filters/quickstart.md`
**Checkpoint**: User Story 3 delivers ergonomic output formats for all audiences
---
## Phase N: Polish & Cross-Cutting Concerns
**Purpose**: Final validation, documentation, and release notes
- [X] T026 Update agent guidance with list command summary in `AGENTS.md`
- [X] T027 Add release note entry describing new list command in `docs/CHANGELOG.md`
- [X] T028 Create smoke-test script exercising list + preview parity in `scripts/smoke-test-list.sh`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: Complete before foundational utilities to ensure project scaffolding exists.
- **Foundational (Phase 2)**: Depends on Setup; blocks all user stories because shared utilities power every command.
- **User Story 1 (Phase 3)**: Depends on Foundational; delivers MVP list command.
- **User Story 2 (Phase 4)**: Depends on User Story 1 (reuses command structure) and Foundational.
- **User Story 3 (Phase 5)**: Depends on User Story 1 (listing pipeline) and Foundational (formatter interface).
- **Polish (Final Phase)**: Runs after desired user stories finish.
### User Story Dependencies
- **User Story 1 (P1)**: Requires Foundational utilities; no other story prerequisites.
- **User Story 2 (P2)**: Requires User Story 1 to expose list command behaviors before sharing flags.
- **User Story 3 (P3)**: Requires User Story 1 to deliver base listing plus Foundational formatter interface.
### Within Each User Story
- Tests marked [P] should be authored before or alongside implementation; ensure they fail prior to feature work.
- Service implementations depend on validated request structs and traversal utilities.
- CLI command wiring depends on service implementation and helper functions.
- Documentation tasks finalize once command behavior is stable.
### Parallel Opportunities
- Foundational tasks T005T007 operate on different packages and can proceed in parallel after T004 validates data structures.
- User Story 1 tests (T009, T010) can be developed in parallel before implementation tasks T011T014.
- User Story 3 renderers (T021, T022) can be implemented concurrently, converging at T023 for integration.
---
## Parallel Example: User Story 1
```bash
# In one terminal: author contract test
go test ./tests/contract -run TestListCommandFilters
# In another terminal: implement listing service
go test ./internal/listing -run TestService
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Setup + Foundational phases.
2. Implement User Story 1 tasks (T009T015) to deliver a working `renamer list`.
3. Validate with contract/integration tests and quickstart instructions.
### Incremental Delivery
1. Deliver MVP (User Story 1).
2. Add User Story 2 to guarantee global flag consistency.
3. Add User Story 3 to enhance output ergonomics.
4. Finalize polish tasks for documentation and smoke testing.
### Parallel Team Strategy
- Developer A handles Foundational tasks (T004T007) while Developer B updates documentation (T008).
- After Foundational checkpoint, Developer A implements listing service (T011T014), Developer B authors tests (T009T010).
- Once MVP ships, Developer A tackles global flag refactor (T016T018) while Developer B extends integration tests (T019) and docs (T020).
- For User Story 3, split renderer work (T021 vs T022) before merging at T023.