feat: implement AI-assisted rename prompting feature
- Added data model for AI-assisted renaming including structures for prompts, responses, and policies. - Created implementation plan detailing the integration of Google Genkit into the CLI for renaming tasks. - Developed quickstart guide for setting up and using the new AI rename functionality. - Documented research decisions regarding Genkit orchestration and prompt composition. - Established tasks for phased implementation, including setup, foundational work, and user stories. - Implemented contract tests to ensure AI rename policies and ledger metadata are correctly applied. - Developed integration tests for validating AI rename flows, including preview, apply, and undo functionalities. - Added tooling to pin Genkit dependency for consistent builds.
This commit is contained in:
176
specs/008-ai-rename-prompt/contracts/ai-rename.openapi.yaml
Normal file
176
specs/008-ai-rename-prompt/contracts/ai-rename.openapi.yaml
Normal file
@@ -0,0 +1,176 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: Renamer AI Inline Contract
|
||||
version: 0.1.0
|
||||
description: |
|
||||
JSON payload contract exchanged between the Go `renamer ai` command and the embedded Google Genkit workflow.
|
||||
servers:
|
||||
- url: command://renamer-ai/genkit
|
||||
description: CLI-invoked Genkit runner (JSON via stdin/stdout)
|
||||
paths:
|
||||
/rename-plan:
|
||||
post:
|
||||
summary: Generate a rename plan for scoped files (invoked inline, not over HTTP)
|
||||
operationId: createRenamePlan
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenamePrompt'
|
||||
responses:
|
||||
'200':
|
||||
description: Valid rename plan
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenameResponse'
|
||||
'400':
|
||||
description: Invalid prompt payload
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'422':
|
||||
description: Model returned inconsistent plan
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'503':
|
||||
description: Upstream model unavailable
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
components:
|
||||
schemas:
|
||||
RenamePrompt:
|
||||
type: object
|
||||
required: [workingDir, samples, totalCount, sequenceRule, policies]
|
||||
properties:
|
||||
workingDir:
|
||||
type: string
|
||||
samples:
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
$ref: '#/components/schemas/PromptSample'
|
||||
totalCount:
|
||||
type: integer
|
||||
minimum: 1
|
||||
sequenceRule:
|
||||
$ref: '#/components/schemas/SequenceRule'
|
||||
policies:
|
||||
$ref: '#/components/schemas/NamingPolicy'
|
||||
bannedTerms:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
PromptSample:
|
||||
type: object
|
||||
required: [originalName, extension, sizeBytes, pathDepth]
|
||||
properties:
|
||||
originalName:
|
||||
type: string
|
||||
extension:
|
||||
type: string
|
||||
sizeBytes:
|
||||
type: integer
|
||||
minimum: 0
|
||||
pathDepth:
|
||||
type: integer
|
||||
minimum: 0
|
||||
SequenceRule:
|
||||
type: object
|
||||
required: [style, width, start, separator]
|
||||
properties:
|
||||
style:
|
||||
type: string
|
||||
enum: [prefix, suffix]
|
||||
width:
|
||||
type: integer
|
||||
minimum: 1
|
||||
start:
|
||||
type: integer
|
||||
minimum: 1
|
||||
separator:
|
||||
type: string
|
||||
NamingPolicy:
|
||||
type: object
|
||||
required: [casing]
|
||||
properties:
|
||||
prefix:
|
||||
type: string
|
||||
casing:
|
||||
type: string
|
||||
enum: [kebab, snake, camel, pascal, title]
|
||||
allowSpaces:
|
||||
type: boolean
|
||||
default: false
|
||||
keepOriginalOrder:
|
||||
type: boolean
|
||||
default: false
|
||||
forbiddenTokens:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
RenameResponse:
|
||||
type: object
|
||||
required: [items]
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
$ref: '#/components/schemas/RenameItem'
|
||||
warnings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
promptHash:
|
||||
type: string
|
||||
model:
|
||||
type: string
|
||||
RenameItem:
|
||||
type: object
|
||||
required: [original, proposed, sequence]
|
||||
properties:
|
||||
original:
|
||||
type: string
|
||||
proposed:
|
||||
type: string
|
||||
sequence:
|
||||
type: integer
|
||||
minimum: 1
|
||||
notes:
|
||||
type: string
|
||||
ValidationError:
|
||||
type: object
|
||||
required: [message, conflicts]
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
conflicts:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
original:
|
||||
type: string
|
||||
issue:
|
||||
type: string
|
||||
detail:
|
||||
type: string
|
||||
ErrorResponse:
|
||||
type: object
|
||||
required: [message]
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
retryable:
|
||||
type: boolean
|
||||
99
specs/008-ai-rename-prompt/data-model.md
Normal file
99
specs/008-ai-rename-prompt/data-model.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Data Model: AI-Assisted Rename Prompting
|
||||
|
||||
## AiRenamePrompt
|
||||
- **Fields**
|
||||
- `WorkingDir` (string; absolute path)
|
||||
- `SampleFiles` ([]PromptSample)
|
||||
- `TotalCount` (int)
|
||||
- `SequenceRule` (SequenceRuleConfig)
|
||||
- `NamingPolicies` (NamingPolicyConfig)
|
||||
- `BannedTerms` ([]string)
|
||||
- `Metadata` (map[string]string; includes CLI version, timestamp)
|
||||
- **Relationships**: Built from traversal summary; sent to Genkit workflow.
|
||||
- **Validations**: Require ≥1 sample, forbid empty banned terms, limit payload to ≤2 MB serialized.
|
||||
|
||||
### PromptSample
|
||||
- **Fields**
|
||||
- `OriginalName` (string)
|
||||
- `SizeBytes` (int64)
|
||||
- `Extension` (string)
|
||||
- `PathDepth` (int)
|
||||
|
||||
### SequenceRuleConfig
|
||||
- **Fields**
|
||||
- `Style` (enum: `prefix`, `suffix`)
|
||||
- `Width` (int)
|
||||
- `Start` (int)
|
||||
- `Separator` (string)
|
||||
|
||||
### NamingPolicyConfig
|
||||
- **Fields**
|
||||
- `Prefix` (string)
|
||||
- `Casing` (enum: `kebab`, `snake`, `camel`, `pascal`, `title`)
|
||||
- `AllowSpaces` (bool)
|
||||
- `KeepOriginalOrder` (bool)
|
||||
- `ForbiddenTokens` ([]string)
|
||||
|
||||
## AiRenameResponse
|
||||
- **Fields**
|
||||
- `Items` ([]AiRenameItem)
|
||||
- `Warnings` ([]string)
|
||||
- `PromptHash` (string)
|
||||
- `Model` (string)
|
||||
- **Relationships**: Parsed from Genkit output; feeds validation pipeline.
|
||||
- **Validations**: Items length must equal scoped candidate count; `Original` names must match traversal list; `Proposed` must be unique.
|
||||
|
||||
### AiRenameItem
|
||||
- **Fields**
|
||||
- `Original` (string; relative path)
|
||||
- `Proposed` (string; sanitized stem + extension)
|
||||
- `Sequence` (int)
|
||||
- `Notes` (string; optional reasoning)
|
||||
|
||||
## AiRenamePlan
|
||||
- **Fields**
|
||||
- `Candidates` ([]PlanEntry)
|
||||
- `Conflicts` ([]PlanConflict)
|
||||
- `Policies` (NamingPolicyConfig)
|
||||
- `SequenceAppliedWidth` (int)
|
||||
- `Warnings` ([]string)
|
||||
- **Relationships**: Created post-validation for preview/apply; persisted to ledger metadata.
|
||||
- **Validations**: Enforce contiguous sequences, ensure sanitized stems non-empty, confirm banned tokens absent.
|
||||
|
||||
### PlanEntry
|
||||
- **Fields**
|
||||
- `OriginalPath` (string)
|
||||
- `ProposedPath` (string)
|
||||
- `Sequence` (int)
|
||||
- `Status` (enum: `pending`, `edited`, `skipped`, `unchanged`)
|
||||
- `SanitizedSegments` ([]string)
|
||||
|
||||
### PlanConflict
|
||||
- **Fields**
|
||||
- `OriginalPath` (string)
|
||||
- `Issue` (enum: `duplicate`, `collision`, `policy_violation`, `missing_sequence`)
|
||||
- `Details` (string)
|
||||
|
||||
## AiRenameLedgerMetadata
|
||||
- **Fields**
|
||||
- `PromptHash` (string)
|
||||
- `ResponseHash` (string)
|
||||
- `Model` (string)
|
||||
- `Policies` (NamingPolicyConfig)
|
||||
- `BatchSize` (int)
|
||||
- `AppliedAt` (time.Time)
|
||||
- **Relationships**: Stored under `Entry.Metadata["ai"]` when applying rename batch; consumed by undo for auditing.
|
||||
|
||||
## GenkitWorkflowConfig
|
||||
- **Fields**
|
||||
- `Endpoint` (string; local or remote URL)
|
||||
- `Timeout` (Duration)
|
||||
- `RetryPolicy` (RetryPolicy)
|
||||
- `ApiKeyRef` (string; environment variable name mapping to `$HOME/.config/.renamer/{name}` token file)
|
||||
|
||||
### RetryPolicy
|
||||
- **Fields**
|
||||
- `MaxAttempts` (int)
|
||||
- `BackoffInitial` (Duration)
|
||||
- `BackoffMultiplier` (float64)
|
||||
- `FallbackModel` (string; optional)
|
||||
80
specs/008-ai-rename-prompt/plan.md
Normal file
80
specs/008-ai-rename-prompt/plan.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Implementation Plan: AI-Assisted Rename Prompting
|
||||
|
||||
**Branch**: `008-ai-rename-prompt` | **Date**: 2025-11-03 | **Spec**: `specs/008-ai-rename-prompt/spec.md`
|
||||
**Input**: Feature specification from `/specs/008-ai-rename-prompt/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 ai` command that embeds a Google Genkit (Go SDK) workflow inside the CLI execution path. The command collects scope metadata, calls the Genkit pipeline in-process (defaulting to an OpenAI-compatible model), validates the response for sequential, uniform, sanitized filenames, allows operator edits, and records final mappings in the undo ledger while managing `*_MODEL_AUTH_TOKEN` secrets under `$HOME/.config/.renamer/`.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Go 1.24 (CLI + Google Genkit Go SDK)
|
||||
**Primary Dependencies**: `spf13/cobra`, internal traversal/history/output packages, `github.com/google/genkit/go` (with OpenAI-compatible connectors), OpenAI-compatible HTTP client for fallbacks
|
||||
**Storage**: Local filesystem plus `.renamer` append-only ledger; auth tokens cached under `$HOME/.config/.renamer/`
|
||||
**Testing**: `go test ./...` for CLI logic, `npm test` (Vitest) for Genkit prompt workflows, contract/integration suites under `tests/`
|
||||
**Target Platform**: Cross-platform CLI (macOS, Linux, Windows shells) executing in-process Genkit workflows
|
||||
**Project Type**: Single CLI project with integrated Go Genkit module
|
||||
**Performance Goals**: Generate validated rename plan for up to 1,000 files in ≤ 30 seconds round-trip
|
||||
**Constraints**: Genkit workflow must initialize quickly per invocation; AI requests limited to 2 MB payload; ensure user-provided banned terms removed
|
||||
**Scale/Scope**: Typical batches 1–1,000 files; shared Genkit pipeline available for future AI features
|
||||
|
||||
## Constitution Check
|
||||
|
||||
- Preview flow continues to render deterministic before/after tables and block apply until confirmed, satisfying Preview-First Safety.
|
||||
- Undo path records final mappings plus AI prompt/response metadata in `.renamer`, preserving Persistent Undo Ledger guarantees.
|
||||
- AI rename integration becomes a composable rule module (`internal/ai`) that declares inputs (prompt spec), validations, and postconditions while orchestrating the Go Genkit workflow inline, aligning with Composable Rule Engine.
|
||||
- Scope handling reuses existing traversal services (`internal/traversal`) so filters (`--path`, `-r`, `-d`, `--extensions`) remain enforced per Scope-Aware Traversal.
|
||||
- Cobra wiring (`cmd/ai.go`) follows existing CLI standards with help text, flag validation, tests, meeting Ergonomic CLI Stewardship.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/008-ai-rename-prompt/
|
||||
├── plan.md
|
||||
├── research.md
|
||||
├── data-model.md
|
||||
├── quickstart.md
|
||||
├── contracts/
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
cmd/
|
||||
├── ai.go # Genkit-powered command wiring
|
||||
├── root.go
|
||||
|
||||
internal/
|
||||
├── ai/
|
||||
│ ├── prompt/ # Prompt assembly, policy enforcement
|
||||
│ ├── genkit/ # Go Genkit workflow definitions and model connectors
|
||||
│ └── plan/ # Response validation & editing utilities
|
||||
├── history/
|
||||
├── output/
|
||||
├── traversal/
|
||||
└── sequence/
|
||||
|
||||
tests/
|
||||
├── contract/
|
||||
├── integration/
|
||||
└── unit/
|
||||
```
|
||||
|
||||
tests/
|
||||
├── contract/
|
||||
├── integration/
|
||||
└── unit/
|
||||
|
||||
**Structure Decision**: Extend existing CLI layout by adding an `internal/ai` package that houses Go Genkit workflows invoked directly from `cmd/ai.go`; existing test directories cover the new command with contract/integration suites.
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
||||
|-----------|------------|--------------------------------------|
|
||||
| Direct Go Genkit integration | First-class Go SDK keeps execution inline and satisfies CLI-only requirement | Manual REST integration would lose Genkit workflows (retriers, evaluators) and require bespoke prompt templating |
|
||||
40
specs/008-ai-rename-prompt/quickstart.md
Normal file
40
specs/008-ai-rename-prompt/quickstart.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Quickstart: AI-Assisted Rename Prompting
|
||||
|
||||
## Prerequisites
|
||||
- Go 1.24 environment (CLI build/test)
|
||||
- `*_MODEL_AUTH_TOKEN` stored under `$HOME/.config/.renamer/` (default OpenAI-compatible key)
|
||||
|
||||
## Install Dependencies
|
||||
```bash
|
||||
# Sync Go modules (includes google/genkit)
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
## Preview AI Rename Plan
|
||||
```bash
|
||||
go run ./cmd/renamer ai \
|
||||
--path ./fixtures/batch \
|
||||
--sequence-width 3 \
|
||||
--sequence-style prefix \
|
||||
--naming-casing kebab \
|
||||
--banned "promo,ad" \
|
||||
--dry-run
|
||||
```
|
||||
> CLI invokes the in-process Genkit workflow and renders a preview table with sequential, sanitized names.
|
||||
|
||||
## Apply Approved Plan
|
||||
```bash
|
||||
go run ./cmd/renamer ai --path ./fixtures/batch --yes
|
||||
```
|
||||
> Validates the cached plan, applies filesystem renames, and writes ledger entry with AI metadata.
|
||||
|
||||
## Testing
|
||||
```bash
|
||||
# Go unit + integration tests (includes Genkit workflow tests)
|
||||
go test ./...
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
- **Genkit errors**: Run with `--debug-genkit` to emit inline prompt/response traces (written to `~/.renamer/genkit.log`).
|
||||
- **Validation failures**: Run with `--export-plan out.json` to inspect AI output and manually edit.
|
||||
- **Rate limits**: Configure `--genkit-model` flag or `GENKIT_MODEL` env variable to select a lighter model.
|
||||
21
specs/008-ai-rename-prompt/research.md
Normal file
21
specs/008-ai-rename-prompt/research.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Research Log
|
||||
|
||||
## Genkit Orchestration Strategy
|
||||
- **Decision**: Integrate the official Google Genkit Go SDK directly in `internal/ai/genkit`, executing workflows synchronously inside the `renamer ai` command without external services.
|
||||
- **Rationale**: Satisfies the CLI-only constraint, keeps deployment as a single Go binary, and leverages Genkit guardrails, evaluators, and prompt templating.
|
||||
- **Alternatives considered**: Spawning a Node.js runner (rejected—adds extra runtime and violates updated requirement); Plain REST client to foundation models (rejected—would require rebuilding Genkit safety features manually).
|
||||
|
||||
## Prompt Composition Template
|
||||
- **Decision**: Define typed Go structs mirroring the prompt schema (scope summary, sample filenames, naming policies, banned tokens) and marshal them to JSON for Genkit inputs.
|
||||
- **Rationale**: Strong typing prevents malformed prompts and aligns with Genkit Go helpers for variable interpolation and logging.
|
||||
- **Alternatives considered**: Free-form natural language prompts (rejected—harder to validate); YAML serialization (rejected—JSON is the Genkit default and reduces dependency footprint).
|
||||
|
||||
## Response Schema & Validation
|
||||
- **Decision**: Genkit workflow returns Go structs (`RenameItem`, `Warnings`) serialized as JSON; the CLI validates coverage, uniqueness, banned-term removal, and sequential numbering before building the plan.
|
||||
- **Rationale**: Mirrors existing rename planner data types, enabling reuse of preview/output logic and providing transparent audit metadata.
|
||||
- **Alternatives considered**: Returning only ordered filenames (rejected—insufficient context for debugging); CSV output (rejected—lossy and awkward for nested metadata).
|
||||
|
||||
## Offline & Failure Handling
|
||||
- **Decision**: Use Genkit middleware for retry/backoff and error classification; if the workflow fails or produces invalid data, the CLI aborts gracefully, surfaces the issue, and can export the prompt/response for manual inspection.
|
||||
- **Rationale**: Maintains Preview-First safety by never applying partial results and keeps error handling contained within the CLI execution.
|
||||
- **Alternatives considered**: Persistent background daemon (rejected—contradicts inline execution); Automatic fallback to legacy sequential numbering (rejected—changes user intent, can be added later as an explicit option).
|
||||
@@ -5,6 +5,12 @@
|
||||
**Status**: Draft
|
||||
**Input**: User description: "实现使用AI重命名的功能,把当前的文件列表给AI使用AI进行重新命令,AI返回重命令规则后解析AI的规则进行本地重命名操作。你需要帮我考虑如何建立合适的prompt给AI实现重命名。要求:1、带序列号;2、文件名规则统一;3、文件名中去除广告推广等垃圾信息;4、如果还有其它合适规则你来适量添加。"
|
||||
|
||||
## Clarifications
|
||||
|
||||
### Session 2025-11-03
|
||||
|
||||
- Q: Which AI model should the CLI use by default? → A: Default to an OpenAI-compatible model with override flag/env.
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 - Generate AI Rename Plan (Priority: P1)
|
||||
@@ -66,7 +72,7 @@ As a cautious operator, I want to review the AI plan, make manual adjustments if
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: The CLI MUST collect the active scope (paths, filters, counts) and compose an AI prompt that includes representative filenames plus the required renaming rules (sequence numbering, uniform formatting, spam removal, additional heuristics).
|
||||
- **FR-002**: The prompt MUST instruct the AI to respond in a documented, parseable structure (e.g., JSON with original and proposed names) and to preserve file extensions.
|
||||
- **FR-002**: The prompt MUST instruct the AI to respond in a documented, parseable structure (e.g., JSON with original and proposed names) and to preserve file extensions; the CLI MUST default to an OpenAI-compatible model (override via flag/env).
|
||||
- **FR-003**: The system MUST validate the AI response, ensuring every scoped file has a proposed rename, sequence numbers are continuous, names are unique, and disallowed content is removed before previewing changes.
|
||||
- **FR-004**: Users MUST be able to supply optional naming policy inputs (project tag, casing preference, separator choice, forbidden words) that the prompt reflects and the validator enforces.
|
||||
- **FR-005**: The preview MUST display AI-proposed names with sequence numbers, highlight sanitized segments, and surface any entries needing manual edits before the apply step is allowed.
|
||||
@@ -85,7 +91,7 @@ As a cautious operator, I want to review the AI plan, make manual adjustments if
|
||||
|
||||
### Assumptions
|
||||
|
||||
- Users provide access to an AI endpoint capable of following structured prompts and returning JSON within size limits.
|
||||
- Users provide access to an AI endpoint capable of following structured prompts and returning JSON within size limits; default secret tokens (`*_MODEL_AUTH_TOKEN`) are stored under `$HOME/.config/.renamer/`.
|
||||
- File extensions must remain unchanged; only stems are rewritten.
|
||||
- Default numbering uses three-digit, zero-padded prefixes unless the user specifies a different width or format.
|
||||
- The CLI environment already authenticates outbound AI requests; this feature focuses on prompt content and result handling.
|
||||
|
||||
125
specs/008-ai-rename-prompt/tasks.md
Normal file
125
specs/008-ai-rename-prompt/tasks.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Tasks: AI-Assisted Rename Prompting
|
||||
|
||||
**Input**: Design documents from `/specs/008-ai-rename-prompt/`
|
||||
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/
|
||||
|
||||
## Phase 1: Setup (Shared Infrastructure)
|
||||
|
||||
**Purpose**: Establish tooling and scaffolding for the embedded Go Genkit workflow.
|
||||
|
||||
- [x] T001 Pin Google Genkit Go SDK dependency and run tidy in `go.mod`
|
||||
- [x] T002 Scaffold `cmd/ai.go` command file with Cobra boilerplate
|
||||
- [x] T003 Create `internal/ai` package directories (`prompt`, `genkit`, `plan`) in the repository
|
||||
- [x] T004 Document model token location in `docs/cli-flags.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational (Blocking Prerequisites)
|
||||
|
||||
**Purpose**: Core plumbing that all user stories rely on.
|
||||
|
||||
- [x] T005 Implement env loader for `$HOME/.config/.renamer` in `internal/ai/config/token_store.go` with package `github.com/joho/godotenv`
|
||||
- [x] T006 Define shared prompt/response structs per spec in `internal/ai/prompt/types.go`
|
||||
- [x] T007 Implement Go Genkit workflow skeleton with default OpenAI-compatible model in `internal/ai/genkit/workflow.go`
|
||||
- [x] T008 Build response validator ensuring coverage/uniqueness in `internal/ai/plan/validator.go`
|
||||
- [x] T009 Add CLI flag parsing for AI options (model override, debug export) in `cmd/ai.go`
|
||||
- [x] T010 Wire ledger metadata schema for AI batches in `internal/history/history.go`
|
||||
|
||||
**Checkpoint**: Genkit workflow callable from CLI with validation scaffolding ready.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 1 - Generate AI Rename Plan (Priority: P1) 🎯 MVP
|
||||
|
||||
**Goal**: Produce a previewable AI-generated rename plan with sequential, sanitized filenames.
|
||||
|
||||
**Independent Test**: `go run . ai --path <fixtures>` prints numbered preview (`001_...`) without spam terms and logs prompt hash.
|
||||
|
||||
### Tests for User Story 1
|
||||
|
||||
- [x] T011 [P] [US1] Add contract test covering Genkit prompt/response schema in `tests/contract/ai_prompt_contract_test.go`
|
||||
- [x] T012 [P] [US1] Add integration test for preview output on sample batch in `tests/integration/ai_preview_flow_test.go`
|
||||
|
||||
### Implementation for User Story 1
|
||||
|
||||
- [x] T013 [US1] Assemble prompt builder using traversal samples in `internal/ai/prompt/builder.go`
|
||||
- [x] T014 [US1] Execute Genkit workflow and capture telemetry in `internal/ai/genkit/client.go`
|
||||
- [x] T015 [US1] Map Genkit response to preview plan entries in `internal/ai/plan/mapper.go`
|
||||
- [x] T016 [US1] Render preview table with sequence + sanitization notes in `internal/output/table.go`
|
||||
- [x] T017 [US1] Log prompt hash and response warnings to debug output in `internal/output/plain.go`
|
||||
|
||||
**Checkpoint**: `renamer ai --dry-run` fully functional for default policies.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 2 - Enforce Naming Standards (Priority: P2)
|
||||
|
||||
**Goal**: Allow operators to specify naming policies that the AI prompt and validator enforce.
|
||||
|
||||
**Independent Test**: `renamer ai --naming-casing kebab --prefix proj --dry-run` produces kebab-case names with `proj` prefix and fails invalid responses.
|
||||
|
||||
### Tests for User Story 2
|
||||
|
||||
- [x] T018 [P] [US2] Contract test ensuring casing/prefix rules reach Genkit input in `tests/contract/ai_policy_contract_test.go`
|
||||
- [x] T019 [P] [US2] Integration test covering policy violations in `tests/integration/ai_policy_validation_test.go`
|
||||
|
||||
### Implementation for User Story 2
|
||||
|
||||
- [x] T020 [US2] Extend CLI flags/environment parsing for naming policies in `cmd/ai.go`
|
||||
- [x] T021 [US2] Inject policy directives into prompt payload in `internal/ai/prompt/builder.go`
|
||||
- [x] T022 [US2] Enhance validator to enforce casing/prefix/banned tokens in `internal/ai/plan/validator.go`
|
||||
- [x] T023 [US2] Surface policy failures with actionable messages in `internal/output/plain.go`
|
||||
|
||||
**Checkpoint**: Policy-driven prompts and enforcement operational.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 3 - Review, Edit, and Apply Safely (Priority: P3)
|
||||
|
||||
**Goal**: Support manual edits, conflict resolution, and safe apply/undo flows.
|
||||
|
||||
**Independent Test**: Modify exported plan, revalidate, then `renamer ai --yes` applies changes and ledger records AI metadata; undo restores originals.
|
||||
|
||||
### Tests for User Story 3
|
||||
|
||||
- [x] T024 [P] [US3] Integration test covering manual edits + apply/undo in `tests/integration/ai_apply_undo_test.go`
|
||||
- [x] T025 [P] [US3] Contract test ensuring ledger metadata captures prompt/response hashes in `tests/contract/ai_ledger_contract_test.go`
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [x] T026 [US3] Implement plan editing/export/import helpers in `internal/ai/plan/editor.go`
|
||||
- [x] T027 [US3] Revalidation workflow for edited plans in `internal/ai/plan/validator.go`
|
||||
- [x] T028 [US3] Conflict detection (duplicate targets, missing sequences) surfaced in preview in `internal/ai/plan/conflicts.go`
|
||||
- [x] T029 [US3] Apply pipeline recording AI metadata to ledger in `internal/ai/plan/apply.go`
|
||||
- [x] T030 [US3] Update undo path to respect AI metadata in `cmd/undo.go`
|
||||
|
||||
**Checkpoint**: Full review/edit/apply loop complete with undo safety.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Polish & Cross-Cutting Concerns
|
||||
|
||||
- [x] T031 [P] Add CLI help and usage examples for `renamer ai` in `cmd/root.go`
|
||||
- [x] T032 [P] Update end-user documentation in `docs/cli-flags.md`
|
||||
- [x] T033 [P] Add smoke script exercising AI flow in `scripts/smoke-test-ai.sh`
|
||||
- [x] T034 [P] Record prompt/response telemetry opt-in in `docs/CHANGELOG.md`
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
1. Setup → Foundational → US1 → US2 → US3 → Polish
|
||||
2. User story dependencies: US2 depends on US1; US3 depends on US1 and US2.
|
||||
|
||||
## Parallel Execution Examples
|
||||
|
||||
- During US1, prompt builder (T013) and Genkit client (T014) can proceed in parallel after foundational tasks.
|
||||
- US2 policy contract test (T018) can run alongside validator enhancements (T022) once prompt builder updates (T021) start.
|
||||
- In US3, ledger integration (T029) can progress concurrently with conflict detection (T028).
|
||||
- Polish tasks (T031–T034) may run in parallel after US3 completes.
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
1. Deliver MVP by completing Phases 1–3 (US1) to provide AI-generated preview with validation.
|
||||
2. Layer policy enforcement (US2) to align output with organizational naming standards.
|
||||
3. Finish with editing/apply safety (US3) and polish tasks before release.
|
||||
Reference in New Issue
Block a user