|
| 1 | +# Atomic Identifiers Feature - Product Requirements Document |
| 2 | + |
| 3 | +## Executive Summary |
| 4 | +Add support for treating certain identifiers as "atomic" - indivisible units that should not have word boundaries detected during case transformations. This solves the problem where compound brand names like "DocSpring" or "GitHub" need to maintain their identity as single words in all case styles. |
| 5 | + |
| 6 | +## Problem Statement |
| 7 | +Currently, when renaming identifiers like "DocSpring" or "GitHub", renamify detects word boundaries and generates variants like: |
| 8 | +- `doc_spring` (snake_case) |
| 9 | +- `doc-spring` (kebab-case) |
| 10 | +- `DOC_SPRING` (SCREAMING_SNAKE_CASE) |
| 11 | + |
| 12 | +However, these brand names should be treated as single, indivisible units: |
| 13 | +- `docspring` (snake_case) |
| 14 | +- `docspring` (kebab-case) |
| 15 | +- `DOCSPRING` (SCREAMING_SNAKE_CASE) |
| 16 | +- `DocSpring` (PascalCase - the only time there is a word break) |
| 17 | + |
| 18 | +This is similar to Rails' `inflect.acronym` feature, but for compound words that aren't acronyms. |
| 19 | + |
| 20 | +## User Stories |
| 21 | + |
| 22 | +### Story 1: CLI User with Atomic Identifiers |
| 23 | +As a developer renaming "HubGit" to "GitHub" in my codebase, |
| 24 | +I want to specify that both names are atomic, |
| 25 | +So that `hubgit_api` becomes `github_api` (not `git_hub_api`). |
| 26 | + |
| 27 | +### Story 2: Project with Persistent Atomic Configuration |
| 28 | +As a team maintaining a project with brand names like "DocSpring", |
| 29 | +I want to configure these as atomic in a config file, |
| 30 | +So that all team members automatically get correct renaming behavior. |
| 31 | + |
| 32 | +### Story 3: VS Code Extension User |
| 33 | +As a VS Code user, |
| 34 | +I want checkboxes to mark search/replace terms as atomic, |
| 35 | +So that I can control word boundary detection visually. |
| 36 | + |
| 37 | +### Story 4: Partial Atomic Matching |
| 38 | +As a developer with "FormAPIController" in my code, |
| 39 | +I want atomic "FormAPI" to match and replace the atomic portion correctly, |
| 40 | +So that it becomes "DocSpringController" (not "DocSpringAPIController"). |
| 41 | + |
| 42 | +## Functional Requirements |
| 43 | + |
| 44 | +### 1. Core Atomic Detection |
| 45 | +- When an identifier is marked as atomic, it should be treated as a single token |
| 46 | +- Atomic identifiers should not have internal word boundaries detected |
| 47 | +- The atomic property applies to the identifier wherever it appears (standalone or as part of larger identifiers) |
| 48 | + |
| 49 | +### 2. CLI Flags |
| 50 | +- `--atomic` - Both search and replace are atomic |
| 51 | +- `--atomic-search` - Only search term is atomic |
| 52 | +- `--atomic-replace` - Only replace term is atomic |
| 53 | +- `--no-atomic` - Override config, treat as normal |
| 54 | +- `--no-atomic-search` - Override config for search term |
| 55 | +- `--no-atomic-replace` - Override config for replace term |
| 56 | +- Error if user specifies both `--atomic` and `--atomic-search`/`--atomic-replace` |
| 57 | + |
| 58 | +### 3. Configuration File |
| 59 | +- Support `atomic = ["DocSpring", "GitHub", "GitHub"]` in `.renamify/config.toml` |
| 60 | +- Config entries are case-insensitive matched (PascalCase in config matches all cases) |
| 61 | +- Config auto-applies when matching identifiers are used |
| 62 | +- CLI flags override config settings |
| 63 | + |
| 64 | +### 4. Variant Generation |
| 65 | +For atomic identifier "DocSpring": |
| 66 | +- Generate only: `DocSpring`, `docspring`, `DOCSPRING` |
| 67 | +- Do NOT generate: `doc_spring`, `DOC_SPRING`, `doc-spring`, `docSpring` |
| 68 | + |
| 69 | +### 5. Compound Identifier Handling |
| 70 | +When "FormAPI" is atomic: |
| 71 | +- `FormAPIController` → `DocSpringController` |
| 72 | +- `form_api_client` → `docspring_client` |
| 73 | +- `FORMAPI_TOKEN` → `DOCSPRING_TOKEN` |
| 74 | +- The atomic portion is preserved as a unit within larger identifiers |
| 75 | + |
| 76 | +### 6. VS Code Extension |
| 77 | +- Add "Atomic" checkbox under Search field with tooltip |
| 78 | +- Add "Atomic" checkbox under Replace field with tooltip |
| 79 | +- Tooltips explain: "Treat as indivisible (no word boundaries)" |
| 80 | +- Pre-check boxes if terms match config entries |
| 81 | + |
| 82 | +### 7. MCP Server |
| 83 | +- Add `atomicSearch: boolean` parameter |
| 84 | +- Add `atomicReplace: boolean` parameter |
| 85 | +- Read and respect `.renamify/config.toml` atomic entries |
| 86 | + |
| 87 | +## Technical Requirements |
| 88 | + |
| 89 | +### 1. Case Model Refactoring |
| 90 | +- Split `case_model.rs` into smaller modules (it's currently 1100 lines) |
| 91 | +- Create `atomic.rs` module for atomic-specific logic |
| 92 | +- Maintain backward compatibility |
| 93 | + |
| 94 | +### 2. Token Generation |
| 95 | +- Modify `parse_to_tokens` to accept atomic hints |
| 96 | +- When atomic, return single token regardless of internal capitals |
| 97 | +- Preserve existing behavior when not atomic |
| 98 | + |
| 99 | +### 3. Variant Map Generation |
| 100 | +- Update `generate_variant_map` to accept atomic flags |
| 101 | +- Generate limited variants for atomic identifiers |
| 102 | +- Handle mixed atomic/non-atomic scenarios |
| 103 | + |
| 104 | +### 4. Testing |
| 105 | +- Unit tests for atomic token parsing |
| 106 | +- Integration tests for compound identifiers |
| 107 | +- End-to-end tests with real examples (DocSpring, GitHub) |
| 108 | +- Performance tests to ensure no regression |
| 109 | + |
| 110 | +## Non-Functional Requirements |
| 111 | + |
| 112 | +### 1. Performance |
| 113 | +- Atomic detection should not significantly impact scan performance |
| 114 | +- Config file parsing should be cached |
| 115 | + |
| 116 | +### 2. Documentation |
| 117 | +- Create "Atomic Identifiers" page in Features section |
| 118 | +- Include examples of when to use atomic mode |
| 119 | +- Document config file format |
| 120 | + |
| 121 | +### 3. Error Handling |
| 122 | +- Clear error messages for conflicting flags |
| 123 | +- Warn if atomic identifier contains delimiters |
| 124 | + |
| 125 | +## Acceptance Criteria |
| 126 | + |
| 127 | +### Test Case 1: Basic Atomic Renaming |
| 128 | +```bash |
| 129 | +renamify rename GitLab GitHub --atomic |
| 130 | +``` |
| 131 | +- `git_lab_api` → `GitHub_api` |
| 132 | +- `GIT_LAB_TOKEN` → `GitHub_TOKEN` |
| 133 | +- `GitLabController` → `GitHubController` |
| 134 | + |
| 135 | +### Test Case 2: Config File Auto-Application |
| 136 | +`.renamify/config.toml`: |
| 137 | +```toml |
| 138 | +atomic = ["DocSpring"] |
| 139 | +``` |
| 140 | +```bash |
| 141 | +renamify rename DocSpring Helper |
| 142 | +``` |
| 143 | +- `docspring_api` → `helper_api` (NOT `doc_spring_api` → `helper_api`) |
| 144 | + |
| 145 | +### Test Case 3: Partial Identifier Matching |
| 146 | +```bash |
| 147 | +renamify rename FormAPI DocSpring --atomic |
| 148 | +``` |
| 149 | +- `FormAPIController` → `DocSpringController` |
| 150 | +- `useFormAPIHook` → `useDocSpringHook` |
| 151 | + |
| 152 | +### Test Case 4: Override Config |
| 153 | +`.renamify/config.toml`: |
| 154 | +```toml |
| 155 | +atomic = ["DocSpring"] |
| 156 | +``` |
| 157 | +```bash |
| 158 | +renamify rename DocSpring doc_spring --no-atomic-search |
| 159 | +``` |
| 160 | +- `DocSpring` → `doc_spring` (word boundary detected due to override) |
| 161 | + |
| 162 | +## Implementation Plan |
| 163 | + |
| 164 | +### Phase 1: Core Support (Week 1) |
| 165 | +1. Refactor case_model.rs into modules |
| 166 | +2. Implement atomic token parsing |
| 167 | +3. Update variant generation |
| 168 | +4. Add comprehensive tests |
| 169 | + |
| 170 | +### Phase 2: CLI Integration (Week 1) |
| 171 | +1. Add CLI flags |
| 172 | +2. Implement config file support |
| 173 | +3. Wire up to plan operation |
| 174 | +4. Add integration tests |
| 175 | + |
| 176 | +### Phase 3: UI Integration (Week 2) |
| 177 | +1. Update VS Code extension |
| 178 | +2. Update MCP server |
| 179 | +3. Add tooltips and help text |
| 180 | +4. End-to-end testing |
| 181 | + |
| 182 | +### Phase 4: Documentation (Week 2) |
| 183 | +1. Create atomic identifiers documentation |
| 184 | +2. Update existing docs with atomic examples |
| 185 | +3. Add to README and help text |
| 186 | + |
| 187 | +## Success Metrics |
| 188 | +- All test cases pass |
| 189 | +- No performance regression (scan time within 5% of baseline) |
| 190 | +- User feedback positive on solving word boundary issues |
| 191 | +- Documentation clear (no support questions about basic usage) |
| 192 | + |
| 193 | +## Risks and Mitigations |
| 194 | + |
| 195 | +### Risk 1: Breaking Changes |
| 196 | +**Mitigation**: Atomic mode is opt-in, existing behavior unchanged by default |
| 197 | + |
| 198 | +### Risk 2: Performance Impact |
| 199 | +**Mitigation**: Early detection during parsing, benchmark before/after |
| 200 | + |
| 201 | +### Risk 3: User Confusion |
| 202 | +**Mitigation**: Clear documentation, intuitive naming ("atomic"), helpful tooltips |
| 203 | + |
| 204 | +## Future Enhancements |
| 205 | +- Support for regex patterns in atomic config |
| 206 | +- Auto-detection of likely atomic identifiers based on casing patterns |
| 207 | +- Project-specific dictionaries of atomic terms |
| 208 | +- Integration with language-specific naming conventions |
0 commit comments