Add configurable sequence numbering command

This commit is contained in:
2025-11-03 10:59:15 +08:00
parent 843c51e347
commit e6a5c6499b
34 changed files with 1920 additions and 1 deletions

View File

@@ -0,0 +1,34 @@
# Specification Quality Checklist: Sequence Numbering Command
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-10-31
**Feature**: [Sequence Numbering Command](../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,241 @@
openapi: 3.1.0
info:
title: Renamer Sequence Command Contract
version: 0.1.0
description: >
Conceptual REST contract for the `renamer sequence` CLI behavior, used to
formalize preview/apply expectations for testing and documentation.
servers:
- url: cli://local
paths:
/sequence/preview:
post:
summary: Generate a deterministic sequence numbering preview.
operationId: previewSequence
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SequenceRequest'
responses:
'200':
description: Preview generated successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/SequencePlan'
'400':
description: Invalid configuration (e.g., width <= 0, invalid separator).
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/sequence/apply:
post:
summary: Apply sequence numbering to previously previewed candidates.
operationId: applySequence
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SequenceRequest'
- type: object
properties:
confirm:
type: boolean
const: true
responses:
'200':
description: Sequence numbering applied.
content:
application/json:
schema:
$ref: '#/components/schemas/SequenceApplyResult'
'207':
description: Applied with skipped conflicts.
content:
application/json:
schema:
$ref: '#/components/schemas/SequenceApplyResult'
'400':
description: Invalid configuration or missing confirmation.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'409':
description: Scope filters yielded zero candidates.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
SequenceRequest:
type: object
required:
- start
- placement
- separator
properties:
path:
type: string
description: Root directory for traversal.
recursive:
type: boolean
includeDirs:
type: boolean
description: Directories remain untouched even when included.
hidden:
type: boolean
extensions:
type: array
items:
type: string
pattern: '^\\.[^./]+$'
dryRun:
type: boolean
yes:
type: boolean
start:
type: integer
minimum: 1
width:
type: integer
minimum: 1
placement:
type: string
enum: [prefix, suffix]
separator:
type: string
minLength: 1
pattern: '^[^/\\\\]+$'
SequencePlan:
type: object
required:
- candidates
- config
- summary
properties:
candidates:
type: array
items:
$ref: '#/components/schemas/SequenceCandidate'
skippedConflicts:
type: array
items:
$ref: '#/components/schemas/SequenceConflict'
summary:
$ref: '#/components/schemas/SequenceSummary'
config:
$ref: '#/components/schemas/SequenceConfig'
SequenceCandidate:
type: object
required:
- originalPath
- proposedPath
- index
properties:
originalPath:
type: string
proposedPath:
type: string
index:
type: integer
minimum: 0
SequenceConflict:
type: object
required:
- originalPath
- conflictingPath
- reason
properties:
originalPath:
type: string
conflictingPath:
type: string
reason:
type: string
enum: [existing_target, invalid_separator, width_overflow]
SequenceSummary:
type: object
required:
- totalCandidates
- renamedCount
- skippedCount
properties:
totalCandidates:
type: integer
renamedCount:
type: integer
skippedCount:
type: integer
warnings:
type: array
items:
type: string
SequenceConfig:
type: object
required:
- start
- placement
- separator
properties:
start:
type: integer
width:
type: integer
placement:
type: string
enum: [prefix, suffix]
separator:
type: string
SequenceApplyResult:
type: object
required:
- plan
- ledgerEntry
properties:
plan:
$ref: '#/components/schemas/SequencePlan'
ledgerEntry:
$ref: '#/components/schemas/SequenceLedgerEntry'
SequenceLedgerEntry:
type: object
required:
- rule
- config
- operations
properties:
timestamp:
type: string
format: date-time
rule:
type: string
const: sequence
config:
$ref: '#/components/schemas/SequenceConfig'
operations:
type: array
items:
$ref: '#/components/schemas/SequenceOperation'
SequenceOperation:
type: object
required:
- from
- to
properties:
from:
type: string
to:
type: string
ErrorResponse:
type: object
required:
- message
properties:
message:
type: string

View File

@@ -0,0 +1,68 @@
# Data Model: Sequence Numbering Command
## SequenceRequest
- **Fields**
- `Path` (string): Root path for traversal (defaults to current directory); must exist and be accessible.
- `Recursive` (bool): Includes subdirectories when true.
- `IncludeDirs` (bool): Includes directories in traversal results without numbering.
- `Hidden` (bool): Includes hidden files when true.
- `Extensions` ([]string): Optional `.`-prefixed extension filter; deduplicated and validated.
- `DryRun` (bool): Indicates preview-only execution.
- `Yes` (bool): Confirmation flag for apply mode.
- `Start` (int): First sequence value; must be ≥1.
- `Width` (int): Minimum digits for zero padding; must be ≥1 when provided.
- `Placement` (enum: `prefix` | `suffix`): Determines where the sequence number is inserted; default `suffix`.
- `Separator` (string): Separator between number and filename; defaults to `_`; must comply with filesystem rules (no path separators, non-empty).
- **Relationships**: Consumed by traversal service to produce candidates and by sequence rule to generate `SequencePlan`.
- **Validations**: Numeric fields validated before preview; separator sanitized; conflicting flags (dry-run vs yes) rejected.
## SequencePlan
- **Fields**
- `Candidates` ([]SequenceCandidate): Ordered list of files considered for numbering.
- `SkippedConflicts` ([]SequenceConflict): Files skipped due to target path collisions.
- `Summary` (SequenceSummary): Counts for total candidates, renamed files, and skipped items.
- `Config` (SequenceConfig): Snapshot of sequence settings (start, width, placement, separator).
- **Relationships**: Passed to output package for preview rendering and to history package for ledger persistence.
- **Validations**: Candidate ordering must match traversal ordering; conflicts identified before apply.
### SequenceCandidate
- **Fields**
- `OriginalPath` (string)
- `ProposedPath` (string)
- `Index` (int): Zero-based position used to derive padded number.
- **Constraints**: Proposed path must differ from original to be considered a rename; duplicates flagged as conflicts.
### SequenceConflict
- **Fields**
- `OriginalPath` (string)
- `ConflictingPath` (string)
- `Reason` (string enum: `existing_target`, `invalid_separator`, `width_overflow`)
### SequenceSummary
- **Fields**
- `TotalCandidates` (int)
- `RenamedCount` (int)
- `SkippedCount` (int)
- `Warnings` ([]string)
## SequenceLedgerEntry
- **Fields**
- `Timestamp` (time.Time)
- `Rule` (string): Fixed value `sequence`.
- `Config` (SequenceConfig): Stored to support undo.
- `Operations` ([]SequenceOperation): Each captures `From` and `To` paths actually renamed.
- **Relationships**: Append-only entry written by history package; consumed by undo command.
- **Validations**: Only include successful renames (skipped conflicts omitted). Undo must verify files still exist before attempting reversal.
### SequenceOperation
- **Fields**
- `From` (string)
- `To` (string)
## SequenceConfig
- **Fields**
- `Start` (int)
- `Width` (int)
- `Placement` (string)
- `Separator` (string)
- **Usage**: Embedded in plan summaries, ledger entries, and undo operations to ensure consistent behavior across preview and apply.

View File

@@ -0,0 +1,87 @@
# Implementation Plan: Sequence Numbering Command
**Branch**: `001-sequence-numbering` | **Date**: 2025-11-03 | **Spec**: `specs/001-sequence-numbering/spec.md`
**Input**: Feature specification from `/specs/001-sequence-numbering/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
## Summary
Deliver a new `renamer sequence` command that appends deterministic sequence numbers to file candidates following the preview-first workflow. The command respects existing scope flags, supports configuration for start value, width, placement, and separator, records batches in the `.renamer` ledger for undo, and skips conflicting filesystem entries while warning the user.
## 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`, internal traversal/history/output packages
**Storage**: Local filesystem + `.renamer` ledger files
**Testing**: `go test ./...`, contract + integration suites under `tests/`
**Target Platform**: Cross-platform CLI (Linux/macOS/Windows shells)
**Project Type**: CLI application (single Go project)
**Performance Goals**: Preview + apply 500 files in ≤120s; preview/apply parity ≥95%
**Constraints**: Deterministic ordering, atomic ledger writes, skip conflicts while warning
**Scale/Scope**: Operates on batches up to hundreds of files per invocation
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Preview flow will extend existing preview pipeline to list original → numbered name mappings and highlight skipped conflicts before requiring `--yes`.
- Undo strategy leverages ledger entries capturing sequence parameters (start, width, placement) and per-file mappings, ensuring reversal mirrors numbering order.
- Sequence rule will be implemented as a composable transformation module declaring inputs (scope candidates + sequence config), validations, and outputs, reusable across preview/apply.
- Scope handling continues to consume existing traversal services, honoring `-d`, `-r`, `--extensions`, and leaving directories untouched per clarified requirement while preventing scope escape.
- CLI UX will wire flags via Cobra, update help text, and add tests covering flag validation, preview output, warning messaging, and undo flow consistency.
**Post-Design Review:** Research and design artifacts confirm all principles remain satisfied; no constitution waivers required.
## Project Structure
### Documentation (this feature)
```text
specs/[###-feature]/
├── 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/
├── renamer/ # Cobra CLI entrypoints and command wiring
internal/
├── traversal/ # Scope resolution and ordering services
├── history/ # Ledger and undo utilities
├── output/ # Preview/summary formatting
└── sequence/ # [to be added] sequence rule implementation
tests/
├── contract/ # CLI contract tests
├── integration/ # Multi-command flow tests
└── smoke/ # Smoke scripts under scripts/
```
**Structure Decision**: Extend existing single Go CLI project; new logic lives under `internal/sequence`, with command wiring in `cmd/renamer`.
## Complexity Tracking
> **Fill ONLY if Constitution Check has violations that must be justified**
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |

View File

@@ -0,0 +1,55 @@
# Quickstart: Sequence Numbering Command
## Prerequisites
- Go 1.24 toolchain installed.
- `renamer` repository cloned and bootstrapped (`go mod tidy` already satisfied in repo).
- Test fixtures available under `tests/` for validation runs.
## Build & Install
```bash
go build -o bin/renamer ./cmd/renamer
```
## Preview Sequence Numbering
```bash
bin/renamer sequence \
--path ./fixtures/sample-batch \
--dry-run
```
Outputs a preview table showing `001_`, `002_`, … prefixes based on alphabetical order.
## Customize Formatting
```bash
bin/renamer sequence \
--path ./fixtures/sample-batch \
--start 10 \
--width 4 \
--number-prefix seq \
--separator "" \
--dry-run
```
Produces names such as `seq0010file.ext`. Errors if width/start are invalid.
## Apply Changes
```bash
bin/renamer sequence \
--path ./fixtures/sample-batch \
--yes
```
Writes rename results to the `.renamer` ledger while skipping conflicting targets and warning the user.
## Undo Sequence Batch
```bash
bin/renamer undo --path ./fixtures/sample-batch
```
Restores filenames using the most recent ledger entry.
## Run Automated Tests
```bash
go test ./...
tests/integration/remove_flow_test.go # existing suites ensure regressions are caught
```
## Troubleshooting
- Conflict warnings indicate existing files with the same numbered name; resolve manually or adjust flags.
- Zero candidates cause a 409-style error; adjust scope flags to include desired files.

View File

@@ -0,0 +1,26 @@
# Research Log
## Cobra Flag Validation For Sequence Command
- **Decision**: Validate `--start`, `--width`, `--placement`, and `--separator` flags using Cobra command `PreRunE` with shared helpers, returning errors for invalid inputs before preview executes.
- **Rationale**: Cobra documentation and community guides recommend using `RunE`/`PreRunE` to surface validation errors with non-zero exit codes, ensuring CLI consistency and enabling tests to cover messaging.
- **Alternatives considered**: Inline validation inside business logic (rejected—mixes CLI parsing with domain rules and complicates contract tests); custom flag types (rejected—adds complexity without additional value).
## Sequence Ordering And Determinism
- **Decision**: Reuse the existing traversal service to produce a stable, path-sorted candidate list and derive sequence numbers from index positions in the preview plan.
- **Rationale**: Internal traversal package already guarantees deterministic ordering and filtering; leveraging it avoids duplicating scope logic and satisfies Preview-First and Scope-Aware principles.
- **Alternatives considered**: Implement ad-hoc sorting inside sequence rule (rejected—risk of diverging from other commands); rely on filesystem iteration order (rejected—non-deterministic across platforms).
## Ledger Metadata Capture
- **Decision**: Extend history ledger entries with a new sequence record type storing sequence parameters and per-file mappings, ensuring undo can skip missing files but restore others.
- **Rationale**: Existing ledger pattern (as used by replace/remove commands) stores rule metadata for undo; following same structure keeps undo consistent and auditable.
- **Alternatives considered**: Store only file rename pairs without parameters (rejected—undo would lack context if future migrations require differentiation); create a separate ledger file (rejected—breaks append-only guarantee).
## Conflict Handling Strategy
- **Decision**: During apply, skip conflicting file targets, log a warning via output package, and continue numbering remaining candidates; conflicts remain in preview so users can resolve them beforehand.
- **Rationale**: Aligns with clarified requirements and minimizes partial ledger entries while informing users; consistent with existing warning infrastructure used by other commands.
- **Alternatives considered**: Abort entire batch on conflict (rejected—user explicitly requested skip behavior); auto-adjust numbers (rejected—violates preview/apply parity).
## Directory Inclusion Policy
- **Decision**: Filter traversal results so directories included via `--include-dirs` are reported but not renamed; numbering applies only to file candidates.
- **Rationale**: Keeps command behavior predictable, avoids confusing two numbering schemes, and respects clarified requirement without altering traversal contract tests.
- **Alternatives considered**: Separate numbering sequences for files vs directories (rejected—adds complexity with little user need); rename directories by default (rejected—breaks clarified guidance).

View File

@@ -0,0 +1,109 @@
# Feature Specification: Sequence Numbering Command
**Feature Branch**: `001-sequence-numbering`
**Created**: 2025-10-31
**Status**: Draft
**Input**: User description: "添加 sequence 功能,为重命名文件添加序号,可以定义序列号长度 使用0左填充可以指定序列号开始序号"
## Clarifications
### Session 2025-11-03
- Q: How should the command behave when the generated filename already exists outside the current batch (e.g., `file_001.txt`)? → A: Skip conflicting files, continue, and warn.
- Q: How are sequence numbers applied when new files appear between preview and apply, potentially altering traversal order? → A: Ignore new files and rename only the previewed set.
- Q: What validation and messaging occur when the starting number, width, or separator arguments are invalid (negative numbers, zero width, multi-character separator conflicting with filesystem rules)? → A: Hard error with non-zero exit and no preview output.
- Q: How is numbering handled for directories when `--include-dirs` is used alongside files within the same traversal scope? → A: Do not rename directories; sequence applies to files only.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Add Sequential Indices to Batch (Priority: P1)
As a content manager preparing assets for delivery, I want to append an auto-incrementing number to each filename within my selected scope so that downstream systems receive files in a predictable order.
**Why this priority**: Sequencing multiple files is the primary value of the feature and removes the need for external renaming tools for common workflows such as media preparation or document packaging.
**Independent Test**: Place three files in a working directory, run `renamer sequence --path <dir> --dry-run`, and verify the preview shows `001_`, `002_`, `003_` prefixes in deterministic order. Re-run with `--yes` and confirm the ledger captures the batch.
**Acceptance Scenarios**:
1. **Given** a directory containing `draft.txt`, `notes.txt`, and `plan.txt`, **When** the user runs `renamer sequence --dry-run --path <dir>`, **Then** the preview lists each file renamed with a `001_` prefix in alphabetical order and reports the candidate totals.
2. **Given** the same directory and preview, **When** the user re-executes the command with `--yes`, **Then** the CLI reports three files updated and the `.renamer` ledger stores the sequence configuration.
---
### User Story 2 - Control Number Formatting (Priority: P2)
As an archivist following strict naming standards, I want to define the sequence width and zero padding so the filenames meet fixed-length requirements without additional scripts.
**Why this priority**: Formatting options broaden adoption by matching industry conventions (e.g., four-digit reels) and avoid manual corrections after renaming.
**Independent Test**: Run `renamer sequence --width 4 --path <dir> --dry-run` and confirm every previewed filename contains a four-digit, zero-padded sequence value.
**Acceptance Scenarios**:
1. **Given** files `cutA.mov` and `cutB.mov`, **When** the user runs `renamer sequence --width 4 --dry-run`, **Then** the preview shows `0001_` and `0002_` prefixes despite having only two files.
2. **Given** the same files, **When** the user omits an explicit width, **Then** the preview pads only as needed to accommodate the highest sequence number (e.g., `1_`, `2_`, `10_`).
---
### User Story 3 - Configure Starting Number and Placement (Priority: P3)
As a production coordinator resuming interrupted work, I want to choose the starting sequence value and whether the number appears as a prefix or suffix so I can continue existing numbering schemes without renaming older assets.
**Why this priority**: Starting offsets and placement control reduce rework when numbering must align with partner systems or previously delivered batches.
**Independent Test**: Run `renamer sequence --start 10 --dry-run` and confirm the preview begins at `010_` and inserts the number before the filename stem with the configured separator.
**Acceptance Scenarios**:
1. **Given** files `shotA.exr` and `shotB.exr`, **When** the user runs `renamer sequence --start 10 --dry-run`, **Then** the preview numbers the files starting at `010_` and `011_`.
2. **Given** files `cover.png` and `index.png`, **When** the user runs `renamer sequence --placement prefix --separator "-" --dry-run`, **Then** the preview shows names such as `001-cover.png` and `002-index.png` with the separator preserved.
---
### Edge Cases
- Generated filename conflicts with an existing filesystem entry outside the batch: skip the conflicting candidate, continue with the rest, and warn with conflict details.
- Requested width smaller than digits required is automatically expanded with a warning so numbering completes without truncation.
- New files encountered between preview and apply are ignored; only the previewed candidates are renamed.
- Invalid starting number, width, or separator arguments produce a hard error with non-zero exit status; no preview or apply runs until corrected.
- Directories included via `--include-dirs` are left unchanged; numbering applies exclusively to files.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The CLI MUST expose a `sequence` command that applies an ordered numbering rule to all candidates within the current scope while preserving the preview-first workflow used by other renamer commands.
- **FR-002**: The command MUST use a deterministic ordering strategy (default: path-sorted traversal after scope filters) so preview and apply yield identical sequences.
- **FR-003**: Users MUST be able to configure the sequence starting value via a `--start` flag (default `1`) accepting positive integers only, with validation errors for invalid input.
- **FR-004**: Users MUST be able to configure the minimum digit width via a `--width` flag (default determined by total candidates) and the tool MUST zero-pad numbers to match the requested width.
- **FR-005**: Users MUST be able to choose number placement (`prefix` or `suffix`, default prefix) and optionally set a separator string plus static number prefix/suffix tokens while preserving file extensions and directory structure.
- **FR-006**: Preview output MUST display original and proposed names, total candidates, total changed, and warnings when numbering would exceed the requested width or create conflicts.
- **FR-007**: Apply MUST record the numbering rule (start, width, placement, separator, ordering) in the `.renamer` ledger, alongside per-file operations, so that undo can faithfully restore original names.
- **FR-008**: Undo MUST revert sequence-based renames in reverse order even if additional files have been added since the apply step, skipping only those already removed.
- **FR-009**: The `sequence` command MUST respect existing scope flags (`--path`, `--recursive`, `--include-dirs`, `--hidden`, `--extensions`, `--dry-run`, `--yes`) with identical semantics to other commands.
- **FR-010**: When numbering would collide with an existing filesystem entry, the CLI MUST skip the conflicting candidate, continue numbering the remaining files, and emit a warning that lists the skipped items; apply MUST still abort if scope filters yield zero candidates.
- **FR-011**: Invalid formatting arguments (negative start, zero/negative width, unsupported separator) MUST trigger a human-readable error, exit with non-zero status, and prevent preview/apply execution.
- **FR-012**: Directories included in scope via `--include-dirs` MUST be preserved without numbering; only files receive sequence numbers while directories remain untouched.
### Key Entities *(include if feature involves data)*
- **SequenceRequest**: Captures user-supplied configuration (start value, width, placement, separator, scope flags, execution mode).
- **SequencePlan**: Represents the ordered list of candidate files with assigned sequence numbers, proposed names, conflicts, and summary counts.
- **SequenceLedgerEntry**: Stores metadata required for undo, including request parameters, execution timestamp, and file rename mappings.
### Assumptions
- Ordering follows the preview list sorted by relative path unless future features introduce additional ordering controls.
- If numbering exceeds the requested width, the command extends the width automatically, surfaces a warning, and continues rather than failing the batch.
- Default placement is prefix with an underscore separator (e.g., `001_name.ext`) unless overridden by flags.
- Scope and ledger behavior mirror existing rename commands; no new traversal modes are introduced.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Users can number 500 files (preview + apply) in under 120 seconds on a representative workstation without manual intervention.
- **SC-002**: At least 95% of sampled previews match their subsequent apply results exactly during beta testing (no ordering drift or mismatched numbering).
- **SC-003**: 90% of beta participants report that numbering settings (start value, width, placement) meet their formatting needs without external tools.
- **SC-004**: Support requests related to manual numbering workflows decrease by 40% within one release cycle after launch.

View File

@@ -0,0 +1,115 @@
# Tasks: Sequence Numbering Command
**Input**: Design documents from `/specs/001-sequence-numbering/`
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `contracts/`, `quickstart.md`
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Establish scaffolding required by all user stories.
- [X] T001 Create sequence package documentation stub in `internal/sequence/doc.go`
- [X] T002 Seed sample fixtures for numbering scenarios in `testdata/sequence/basic/`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Shared components that every sequence story depends on.
- [X] T003 Define sequence options struct with default values in `internal/sequence/options.go`
- [X] T004 Implement zero-padding formatter helper in `internal/sequence/format.go`
- [X] T005 Introduce plan and summary data structures in `internal/sequence/plan.go`
**Checkpoint**: Base package compiles with shared types ready for story work.
---
## Phase 3: User Story 1 - Add Sequential Indices to Batch (Priority: P1) 🎯 MVP
**Goal**: Append auto-incremented suffixes (e.g., `_001`) to scoped files with deterministic ordering and ledger persistence.
**Independent Test**: `renamer sequence --dry-run --path <dir>` on three files shows `_001`, `_002`, `_003`; rerun with `--yes` updates ledger.
### Tests for User Story 1
- [X] T006 [P] [US1] Add preview contract test covering default numbering in `tests/contract/sequence_preview_test.go`
- [X] T007 [P] [US1] Add integration flow test verifying preview/apply parity in `tests/integration/sequence_flow_test.go`
### Implementation for User Story 1
- [X] T008 [US1] Implement candidate traversal adapter using listing scope in `internal/sequence/traversal.go`
- [X] T009 [US1] Generate preview plan with conflict detection in `internal/sequence/preview.go`
- [X] T010 [US1] Apply renames and record sequence metadata in `internal/sequence/apply.go`
- [X] T011 [US1] Wire Cobra sequence command execution in `cmd/sequence.go`
- [X] T012 [US1] Register sequence command on the root command in `cmd/root.go`
**Checkpoint**: Sequence preview/apply for default suffix behavior is fully testable and undoable.
---
## Phase 4: User Story 2 - Control Number Formatting (Priority: P2)
**Goal**: Allow explicit width flag with zero padding and warning when auto-expanding.
**Independent Test**: `renamer sequence --width 4 --dry-run` shows `_0001` suffixes; omitting width auto-expands on demand.
### Tests for User Story 2
- [X] T013 [P] [US2] Add contract test for explicit width padding in `tests/contract/sequence_width_test.go`
- [X] T014 [P] [US2] Add integration test validating width flag and warnings in `tests/integration/sequence_width_test.go`
### Implementation for User Story 2
- [X] T015 [US2] Extend options validation to handle width flag rules in `internal/sequence/options.go`
- [X] T016 [US2] Update preview planner to enforce configured width and warnings in `internal/sequence/preview.go`
- [X] T017 [US2] Parse and bind `--width` flag within Cobra command in `cmd/sequence.go`
**Checkpoint**: Users can control sequence width with deterministic zero-padding.
---
## Phase 5: User Story 3 - Configure Starting Number and Placement (Priority: P3)
**Goal**: Support custom start offsets plus prefix/suffix placement with configurable separator.
**Independent Test**: `renamer sequence --start 10 --placement prefix --separator "-" --dry-run` produces `0010-file.ext` entries.
### Tests for User Story 3
- [X] T018 [P] [US3] Add contract test for start and placement variants in `tests/contract/sequence_placement_test.go`
- [X] T019 [P] [US3] Add integration test for start offset with undo coverage in `tests/integration/sequence_start_test.go`
### Implementation for User Story 3
- [X] T020 [US3] Validate start, placement, and separator flags in `internal/sequence/options.go`
- [X] T021 [US3] Update preview generation to honor prefix/suffix placement and separators in `internal/sequence/preview.go`
- [X] T022 [US3] Persist placement and separator metadata during apply in `internal/sequence/apply.go`
- [X] T023 [US3] Wire `--start`, `--placement`, and `--separator` flags in `cmd/sequence.go`
**Checkpoint**: Placement and numbering customization scenarios fully supported with ledger fidelity.
---
## Phase 6: Polish & Cross-Cutting Concerns
- [X] T024 [P] Document sequence command flags in `docs/cli-flags.md`
- [X] T025 [P] Log sequence feature addition in `docs/CHANGELOG.md`
- [X] T026 [P] Update command overview with sequence entry in `README.md`
---
## Dependencies
- Setup (Phase 1) → Foundational (Phase 2) → US1 (Phase 3) → US2 (Phase 4) → US3 (Phase 5) → Polish (Phase 6)
- User Story dependencies: `US1` completion unlocks `US2`; `US2` completion unlocks `US3`.
## Parallel Execution Opportunities
- Contract and integration test authoring tasks (T006, T007, T013, T014, T018, T019) can run concurrently with implementation once shared scaffolding is ready.
- Documentation polish tasks (T024T026) can be executed in parallel after all story implementations stabilize.
## Implementation Strategy
1. Deliver MVP by completing Phase 13 (US1), enabling default sequence numbering with undo.
2. Iterate with formatting controls (Phase 4) to broaden usability while maintaining preview/apply parity.
3. Finish with placement customization (Phase 5) and polish tasks (Phase 6) before release.