feat: add replace subcommand with multi-pattern support

This commit is contained in:
Rogee
2025-10-29 17:46:54 +08:00
parent fa57af8a26
commit ceea09f7be
42 changed files with 1848 additions and 14 deletions

View File

@@ -0,0 +1,29 @@
# Release Readiness Checklist: Replace Command with Multi-Pattern Support
**Purpose**: Verify readiness for release / polish phase
**Created**: 2025-10-29
**Feature**: [spec.md](../spec.md)
## Documentation
- [x] Quickstart reflects latest syntax and automation workflow
- [x] CLI reference (`docs/cli-flags.md`) includes replace command usage and warnings
- [x] AGENTS.md updated with replace command summary
- [x] CHANGELOG entry drafted for replace command
## Quality Gates
- [x] `go test ./...` passing locally
- [x] Smoke test script for replace + undo exists and runs
- [x] Ledger metadata includes pattern counts and is asserted in tests
- [x] Empty replacement path warns users in preview
## Operational Readiness
- [x] `--dry-run` and `--yes` are mutually exclusive and error when combined
- [x] Undo command reverses replace operations via ledger entry
- [x] Scope flags behave identically across list/replace commands
## Notes
- Resolve outstanding checklist items prior to tagging release.

View File

@@ -0,0 +1,34 @@
# Specification Quality Checklist: Replace Command with Multi-Pattern Support
**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,70 @@
# CLI Contract: `renamer replace`
## Command Synopsis
```bash
renamer replace <pattern1> [pattern2 ...] <replacement> [flags]
```
### Global Flags (inherited from root command)
- `--path <dir>` (defaults to current working directory)
- `-r`, `--recursive`
- `-d`, `--include-dirs`
- `--hidden`
- `-e`, `--extensions <.ext|.ext2>`
- `--yes` — apply without interactive confirmation (used by all mutating commands)
- `--dry-run` — force preview-only run even if `--yes` is supplied
## Description
Batch-replace literal substrings across filenames and directories using shared traversal and preview
infrastructure. All arguments except the final token are treated as patterns; the last argument is
the replacement value.
## Arguments & Flags
| Argument | Required | Description |
|----------|----------|-------------|
| `<pattern...>` | Yes (≥2) | Literal substrings to be replaced. Quotes required when containing spaces. |
| `<replacement>` | Yes | Final positional argument; literal replacement applied to each pattern. |
| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--path` | string | `.` | Working directory for traversal (global flag). |
| `-r`, `--recursive` | bool | `false` | Traverse subdirectories depth-first (global flag). |
| `-d`, `--include-dirs` | bool | `false` | Include directory names in replacement scope (global flag). |
| `--hidden` | bool | `false` | Include hidden files/directories (global flag). |
| `-e`, `--extensions` | string | (none) | Restrict replacements to files matching `|`-delimited extensions (global flag). |
| `--yes` | bool | `false` | Skip confirmation prompt and apply immediately after successful preview (global flag). |
| `--dry-run` | bool | `false` | Force preview-only run even if `--yes` is provided (global flag). |
## Exit Codes
| Code | Meaning | Example Trigger |
|------|---------|-----------------|
| `0` | Success | Preview or apply completed without conflicts. |
| `2` | Validation error | Fewer than two arguments supplied or unreadable directory. |
| `3` | Conflict detected | Target filename already exists; user must resolve before retry. |
## Preview Output
- Lists each impacted file with columns: `PATH`, `MATCHED PATTERN`, `NEW PATH`.
- Summary line: `Total: <files> (patterns: pattern1=#, pattern2=#, conflicts=#)`.
## Apply Behavior
- Re-validates preview results before writing changes.
- Writes ledger entry capturing old/new names, patterns, replacement string, timestamp.
- On conflict, aborts without partial renames.
## Validation Rules
- Minimum two unique patterns required (at least one pattern plus replacement).
- Patterns and replacement treated as UTF-8 literals; no regex expansion.
- Duplicate patterns deduplicated with warning in preview summary.
- Replacement applied to every occurrence within file/dir name.
- Empty replacement allowed but requires confirmation message: "Replacement string is empty; affected substrings will be removed."
## Examples
```bash
renamer replace draft Draft DRAFT final
renamer replace "Project X" "Project-X" ProjectX --extensions .txt|.md
renamer replace tmp temp temp-backup stable --hidden --recursive --yes
```

View File

@@ -0,0 +1,45 @@
# Data Model: Replace Command with Multi-Pattern Support
## Entities
### ReplaceRequest
- **Description**: Captures all inputs driving a replace operation.
- **Fields**:
- `workingDir` (string, required): Absolute path where traversal begins.
- `patterns` ([]string, min length 2): Ordered list of literal substrings to replace.
- `replacement` (string, required): Literal value substituting each pattern.
- `includeDirectories` (bool): Whether directories participate in replacement.
- `recursive` (bool): Traverse subdirectories depth-first.
- `includeHidden` (bool): Include hidden files during traversal.
- `extensions` ([]string): Optional extension filters inherited from scope flags.
- `dryRun` (bool): Preview mode flag; true during preview, false when applying changes.
- **Validations**:
- `patterns` MUST be deduplicated case-sensitively before execution.
- `replacement` MAY be empty, but command must warn the user during preview.
- `workingDir` MUST exist and be readable before traversal.
### ReplaceSummary
- **Description**: Aggregates preview/apply outcomes for reporting and ledger entries.
- **Fields**:
- `totalFiles` (int): Count of files/directories affected.
- `patternMatches` (map[string]int): Total substitutions per pattern.
- `conflicts` ([]ConflictDetail): Detected filename collisions with rationale.
- `ledgerEntryID` (string, optional): Identifier once committed to `.renamer` ledger.
### ConflictDetail
- **Description**: Describes a file that could not be renamed due to collision or validation failure.
- **Fields**:
- `originalPath` (string)
- `proposedPath` (string)
- `reason` (string): Human-readable description (e.g., "target already exists").
## Relationships
- `ReplaceRequest` produces a stream of candidate rename operations via traversal utilities.
- `ReplaceSummary` aggregates results from executing the request and is persisted inside ledger entries.
- `ConflictDetail` records subset of `ReplaceSummary` when collisions block application.
## State Transitions
1. **Parsing**: CLI args parsed into `ReplaceRequest`; validations run immediately.
2. **Preview**: Traversal + replacement simulation produce `ReplaceSummary` with proposed paths.
3. **Confirm**: Upon user confirmation (or `--yes`), operations apply atomically; ledger entry written.
4. **Undo**: Ledger reverse operation reads `ReplaceSummary` data to restore originals.

View File

@@ -0,0 +1,90 @@
# Implementation Plan: Replace Command with Multi-Pattern Support
**Branch**: `002-add-replace-command` | **Date**: 2025-10-29 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/002-add-replace-command/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 `renamer replace` subcommand that accepts multiple literal patterns and replaces them
with a single target string while honoring existing preview → confirm → ledger → undo guarantees.
The feature will extend shared scope flags, reuse traversal/filtering pipelines, and add
automation-friendly validation and help documentation.
## Technical Context
**Language/Version**: Go 1.24
**Primary Dependencies**: `spf13/cobra`, `spf13/pflag`
**Storage**: Local filesystem (no persistent database)
**Testing**: Go `testing` package with CLI integration/contract tests
**Target Platform**: Cross-platform CLI (Linux, macOS, Windows)
**Project Type**: Single CLI project
**Performance Goals**: Complete preview + apply for 100 files within 2 minutes
**Constraints**: Deterministic previews, reversible ledger entries, conflict detection before apply
**Scale/Scope**: Handles hundreds of files per invocation; patterns limited to user-provided literals
## 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**:
- Replace command will reuse preview + confirmation pipeline; no direct rename without preview.
- Ledger entries will include replacement mappings to maintain undo guarantees.
- Replacement logic will be implemented as composable rule(s) integrating with existing rename engine.
- Command will rely on shared scope flags (`--path`, `-r`, `-d`, `--hidden`, `-e`) to avoid divergence.
- Cobra command structure and automated tests will cover help/validation/undo parity.
## Project Structure
### Documentation (this feature)
```text
specs/002-add-replace-command/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
```
### Source Code (repository root)
```text
cmd/
├── root.go
└── list.go (existing CLI commands; replace command will be added here or alongside)
internal/
├── listing/
├── output/
├── traversal/
└── (new replace-specific packages under internal/replace/)
scripts/
└── smoke-test-list.sh
tests/
├── contract/
├── integration/
└── fixtures/
docs/
└── cli-flags.md
```
**Structure Decision**: Single CLI repository with commands under `cmd/` and reusable logic under
`internal/`. Replace-specific logic will live in `internal/replace/` (request parsing, rule engine,
summary). CLI command wiring will reside in `cmd/replace.go`. Tests will follow existing
contract/integration directories.
## Complexity Tracking
No constitution gate violations identified; additional complexity justification not required.

View File

@@ -0,0 +1,63 @@
# Quickstart: Replace Command with Multi-Pattern Support
## Goal
Demonstrate how to consolidate multiple filename patterns into a single replacement while using the
preview → apply → undo workflow safely.
## Prerequisites
- Go toolchain (>= 1.24) installed for building the CLI locally.
- Sample directory with files containing inconsistent substrings (e.g., `draft`, `Draft`, `DRAFT`).
## Steps
1. **Build the CLI**
```bash
go build -o renamer ./...
```
2. **Inspect replace help**
```bash
./renamer replace --help
```
Review syntax, especially the "final argument is replacement" guidance and quoting rules.
3. **Run a preview with multiple patterns**
```bash
./renamer replace draft Draft DRAFT final --dry-run
```
Confirm the table shows each occurrence mapped to `final` and the summary lists per-pattern counts.
4. **Apply replacements after review**
```bash
./renamer replace draft Draft DRAFT final --yes
```
Observe the confirmation summary, then verify file names have been updated.
5. **Undo if necessary**
```bash
./renamer undo
```
Ensure the ledger entry created by step 4 is reversed and filenames restored.
6. **Handle patterns with spaces**
```bash
./renamer replace "Project X" "Project-X" ProjectX --dry-run
```
Verify that quoting preserves whitespace and the preview reflects the intended substitution.
7. **Combine with scope filters**
```bash
./renamer replace tmp temp stable --path ./examples --extensions .log|.txt --recursive
```
Confirm only matching files under `./examples` are listed.
8. **Integrate into automation**
```bash
./renamer replace draft Draft final --dry-run && \
./renamer replace draft Draft final --yes
```
The first command previews changes; the second applies them with exit code `0` when successful.
## Next Steps
- Add contract/integration tests covering edge cases (empty replacement, conflicts).
- Update documentation (`docs/cli-flags.md`, README) with replace command examples.

View File

@@ -0,0 +1,32 @@
# Phase 0 Research: Replace Command with Multi-Pattern Support
## Decision: Literal substring replacement with ordered evaluation
- **Rationale**: Aligns with current rename semantics and keeps user expectations simple for first
iteration; avoids complexity of regex/glob interactions. Ordered application ensures predictable
handling of overlapping patterns.
- **Alternatives considered**:
- *Regex support*: powerful but significantly increases validation surface and user errors.
- *Simultaneous substitution without order*: risk of ambiguous conflicts when one pattern is subset
of another.
## Decision: Dedicated replace service under `internal/replace`
- **Rationale**: Keeps responsibilities separated from existing listing module, enabling reusable
preview + apply logic while encapsulating pattern parsing, summary, and reporting.
- **Alternatives considered**:
- *Extending existing listing package*: would blur responsibilities between read-only listing and
mutation workflows.
- *Embedding in command file*: hinders testability and violates composable rule principle.
## Decision: Pattern delimiter syntax `with`
- **Rationale**: Matches user description and provides a clear boundary between patterns and
replacement string. Works well with Cobra argument parsing and allows quoting for whitespace.
- **Alternatives considered**:
- *Using flags for replacement string*: more verbose and inconsistent with provided example.
- *Special separators like `--`*: less descriptive and increases documentation burden.
## Decision: Conflict detection before apply
- **Rationale**: Maintains Preview-First Safety by ensuring duplicates or invalid filesystem names are
reported before commit. Reuses existing validation helpers from rename pipeline.
- **Alternatives considered**:
- *Best-effort renames with partial success*: violates atomic undo expectations.
- *Skipping conflicting files silently*: unsafe and would erode trust.

View File

@@ -0,0 +1,115 @@
# Feature Specification: Replace Command with Multi-Pattern Support
**Feature Branch**: `002-add-replace-command`
**Created**: 2025-10-29
**Status**: Draft
**Input**: User description: "添加 替换replace命令用于替换指定的字符串支持同时对多个字符串进行替换为一个 示例: renamer replace pattern1 pattern2 with space pattern3 <replacement>"
## Clarifications
### Session 2025-10-29
- Q: What syntax separates patterns from the replacement value? → A: The final positional argument is the replacement; no delimiter keyword is used.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Normalize Naming with One Command (Priority: P1)
As a CLI user cleaning messy filenames, I want to run `renamer replace` with multiple source
patterns so I can normalize all variants to a single replacement in one pass.
**Why this priority**: Unlocks the main value proposition—batch consolidation of inconsistent
substrings without writing custom scripts.
**Independent Test**: Execute `renamer list` to confirm scope, then `renamer replace foo bar Baz`
and verify preview shows every `foo` and `bar` occurrence replaced with `Baz` before confirming.
**Acceptance Scenarios**:
1. **Given** files containing `draft`, `Draft`, and `DRAFT`, **When** the user runs `renamer replace draft Draft DRAFT final`, **Then** the preview lists every filename replaced with `final`, and execution applies the same mapping.
2. **Given** filenames where patterns appear multiple times, **When** the user runs `renamer replace beta gamma release`, **Then** each occurrence within a single filename is substituted, and the summary highlights total replacements per file.
---
### User Story 2 - Script-Friendly Replacement Workflows (Priority: P2)
As an operator embedding renamer in automation, I want deterministic exit codes and reusable
profiles for replace operations so scripts can preview, apply, and undo safely.
**Why this priority**: Ensures pipelines can rely on the command without interactive ambiguity.
**Independent Test**: In a CI script, run `renamer replace ... --dry-run` (preview), assert exit code
0, then run with `--yes` and check ledger entry plus `renamer undo` restores originals.
**Acceptance Scenarios**:
1. **Given** a non-interactive environment, **When** the user passes `--yes` to apply replacements after a successful preview, **Then** the command exits 0 on success and writes a ledger entry capturing all mappings.
2. **Given** an invalid argument (e.g., only one token supplied), **When** the command executes, **Then** it exits with a non-zero code and explains that the final positional argument becomes the replacement value.
---
### User Story 3 - Validate Complex Pattern Input (Priority: P3)
As a power user handling patterns with spaces or special characters, I want clear syntax guidance
and validation feedback so I can craft replacements confidently.
**Why this priority**: Prevents user frustration when patterns require quoting or escaping.
**Independent Test**: Run `renamer replace "Project X" "Project-X" ProjectX` and confirm preview
resolves both variants, while invalid quoting produces actionable guidance.
**Acceptance Scenarios**:
1. **Given** a pattern containing whitespace, **When** it is provided in quotes, **Then** the preview reflects the intended substring and documentation shows identical syntax describing the final argument as replacement.
2. **Given** duplicate patterns in the same command, **When** the command runs, **Then** duplicates are deduplicated with a warning so replacements remain idempotent.
---
### Edge Cases
- Replacement produces duplicate target filenames; command must surface conflicts before confirmation.
- Patterns overlap within the same filename (e.g., `aaa` replaced via `aa`); order of application must be deterministic and documented.
- Case-sensitivity opt-in: default literal matching is case-sensitive, but a future `--ignore-case` option is deferred; command must warn that matches are case-sensitive.
- Replacement string empty (aka deletion); preview must show empty substitution clearly and require explicit confirmation.
- No files match any pattern; command exits 0 with "No entries matched" messaging and no ledger entry.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The CLI MUST expose `renamer replace <pattern...> <replacement>` and treat all but the final token as literal patterns (quotes support whitespace).
- **FR-002**: Replace operations MUST integrate with the existing preview → confirm workflow; previews list old and new names with highlighted substrings.
- **FR-003**: Executions MUST append detailed entries to `.renamer` including original names, replacements performed, patterns supplied, and timestamps so undo remains possible.
- **FR-004**: Users MUST be able to undo the most recent replace batch via existing undo mechanics without orphaned files.
- **FR-005**: Command MUST respect global scope flags (`--recursive`, `--include-dirs`, `--hidden`, `--extensions`, `--path`) identical to `list` / `preview` behavior.
- **FR-006**: Command MUST accept two or more patterns and collapse them into a single replacement string applied to every filename in scope.
- **FR-007**: Command MUST preserve idempotence by deduplicating patterns and reporting the number of substitutions per pattern in summary output.
- **FR-008**: Invalid invocations (fewer than two arguments, empty pattern list after deduplication, missing replacement) MUST fail with exit code ≠0 and actionable usage guidance.
- **FR-009**: CLI help MUST document quoting rules for patterns containing spaces or shell special characters.
### Key Entities *(include if feature involves data)*
- **ReplaceRequest**: Captures working directory, scope flags, ordered pattern list, replacement string, and preview/apply options.
- **ReplaceSummary**: Aggregates per-pattern match counts, per-file changes, and conflict warnings for preview and ledger output.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Users complete a multi-pattern replacement across 100 files with preview + apply in under 2 minutes end-to-end.
- **SC-002**: 95% of usability test participants interpret the final positional replacement argument correctly after reading `renamer replace --help`.
- **SC-003**: Automated regression tests confirm replace + undo leave the filesystem unchanged in 100% of scripted scenarios.
- **SC-004**: Support tickets related to manual string normalization drop by 40% within the first release cycle after launch.
## Assumptions
- Patterns are treated as literal substrings; regex support is out of scope for this increment.
- Case-sensitive matching aligns with current rename semantics; advanced matching can be added later.
- Replacement applies to filenames (and directories when `-d`/`--include-dirs` is set), not file contents.
- Existing infrastructure for preview, ledger, and undo can be extended without architectural changes.
## Dependencies & Risks
- Requires updates to shared traversal/filter utilities so replace respects global scope flags.
- Help/quickstart documentation must be updated alongside the command to prevent misuse.
- Potential filename conflicts must be detected pre-apply to avoid data loss; conflict handling relies on existing validation pipeline.

View File

@@ -0,0 +1,169 @@
# Tasks: Replace Command with Multi-Pattern Support
**Input**: Design documents from `/specs/002-add-replace-command/`
**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 project for replace command implementation
- [X] T001 Audit root command for shared flags; document expected additions in `cmd/root.go`
- [X] T002 Create replace package scaffold in `internal/replace/README.md` with intended module layout
- [X] T003 Add sample fixtures directory for replacement tests at `tests/fixtures/replace-samples/README.md`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core utilities required by every user story
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
- [X] T004 Implement `ReplaceRequest` struct and validators in `internal/replace/request.go`
- [X] T005 [P] Implement pattern parser handling quoting/deduplication in `internal/replace/parser.go`
- [X] T006 [P] Extend traversal utilities to emit replace candidates in `internal/replace/traversal.go`
- [X] T007 [P] Implement replacement engine with overlap handling in `internal/replace/engine.go`
- [X] T008 Define summary metrics and conflict structs in `internal/replace/summary.go`
- [X] T009 Document replace syntax and flags draft in `docs/cli-flags.md`
**Checkpoint**: Foundation ready—user story implementation can begin
---
## Phase 3: User Story 1 - Normalize Naming with One Command (Priority: P1) 🎯 MVP
**Goal**: Deliver multi-pattern replacement with preview + apply guarantees
**Independent Test**: `renamer replace foo bar Baz --dry-run` followed by `--yes`; verify preview shows replacements, apply updates files, and `renamer undo` restores originals.
### Tests for User Story 1 (OPTIONAL - included for confidence)
- [X] T010 [P] [US1] Contract test for preview summary counts in `tests/contract/replace_command_test.go`
- [X] T011 [P] [US1] Integration test covering multi-pattern apply + undo in `tests/integration/replace_flow_test.go`
### Implementation for User Story 1
- [X] T012 [US1] Implement CLI command wiring in `cmd/replace.go` using shared scope flags
- [X] T013 [US1] Implement preview rendering and summary output in `internal/replace/preview.go`
- [X] T014 [US1] Hook replace engine into ledger/undo pipeline in `internal/replace/apply.go`
- [X] T015 [US1] Add documentation examples to `docs/cli-flags.md` and quickstart
**Checkpoint**: User Story 1 delivers functional `renamer replace` with preview/apply/undo
---
## Phase 4: User Story 2 - Script-Friendly Replacement Workflows (Priority: P2)
**Goal**: Ensure automation-friendly behaviors (exit codes, non-interactive usage)
**Independent Test**: Scripted run invoking `renamer replace ... --dry-run` then `--yes`; expect consistent exit codes and ledger entry
### Implementation for User Story 2
- [X] T016 [US2] Implement non-interactive flag validation (`--yes` + positional args) in `cmd/replace.go`
- [X] T017 [US2] Add ledger metadata (pattern counts) for automation in `internal/replace/summary.go`
- [X] T018 [US2] Expand integration test to assert exit codes for invalid input in `tests/integration/replace_flow_test.go`
- [X] T019 [US2] Update quickstart section with automation guidance in `specs/002-add-replace-command/quickstart.md`
**Checkpoint**: Scripts can rely on deterministic exit codes and ledger data
---
## Phase 5: User Story 3 - Validate Complex Pattern Input (Priority: P3)
**Goal**: Provide resilient handling for whitespace/special-character patterns and user guidance
**Independent Test**: `renamer replace "Project X" "Project-X" ProjectX --dry-run` plus invalid quoting to verify errors
### Implementation for User Story 3
- [X] T020 [P] [US3] Implement quoting guidance and warnings in `cmd/replace.go`
- [X] T021 [P] [US3] Add parser coverage for whitespace patterns in `tests/unit/replace_parser_test.go`
- [X] T022 [US3] Surface duplicate pattern warnings in preview summary in `internal/replace/preview.go`
- [X] T023 [US3] Document advanced pattern examples in `docs/cli-flags.md`
**Checkpoint**: Power users receive clear guidance and validation feedback
---
## Phase N: Polish & Cross-Cutting Concerns
**Purpose**: Final validation, documentation, and release readiness
- [X] T024 Update agent guidance with replace command details in `AGENTS.md`
- [X] T025 Add changelog entry describing new replace command in `docs/CHANGELOG.md`
- [X] T026 Create smoke test script covering replace + undo in `scripts/smoke-test-replace.sh`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No prerequisites
- **Foundational (Phase 2)**: Depends on setup completion; blocks all user stories
- **User Story 1 (Phase 3)**: Depends on foundational phase; MVP delivery
- **User Story 2 (Phase 4)**: Depends on User Story 1 (automation builds on base command)
- **User Story 3 (Phase 5)**: Depends on User Story 1 (parser/extensions) and shares foundation
- **Polish (Phase N)**: Runs after user stories complete
### User Story Dependencies
- **US1**: Requires foundational tasks
- **US2**: Requires US1 implementation + ledger integration
- **US3**: Requires US1 parser and preview infrastructure
### Within Each User Story
- Tests (if included) should be authored before implementation tasks
- Parser/engine updates precede CLI wiring
- Documentation updates finalize after behavior stabilizes
### Parallel Opportunities
- Foundational parser/engine/summary tasks (T005T008) can progress in parallel after T004
- US1 tests (T010T011) can run alongside command wiring (T012T014)
- US3 parser coverage (T021) can proceed independently while warnings (T022) integrate with preview
---
## Parallel Example: User Story 1
```bash
# Terminal 1: Write contract test and run in watch mode
go test ./tests/contract -run TestReplaceCommandPreview
# Terminal 2: Implement preview renderer
$EDITOR internal/replace/preview.go
```
---
## Implementation Strategy
### MVP First (User Story 1)
1. Complete Setup and Foundational phases
2. Implement US1 tasks (T010T015)
3. Ensure preview/apply/undo works end-to-end
### Incremental Delivery
1. Ship US1 (core replace command)
2. Layer US2 (automation-friendly exit codes and ledger metadata)
3. Add US3 (advanced pattern validation)
4. Execute polish tasks for documentation and smoke tests
### Parallel Team Strategy
- Engineer A: Parser/engine/summary foundational work
- Engineer B: CLI command wiring + tests (US1)
- Engineer C: Automation behaviors and documentation (US2/Polish)
- After US1, shift Engineers to handle US3 enhancements and polish concurrently