worktrees 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/commands/plan.md +42 -0
- data/.claude/commands/specify.md +12 -0
- data/.claude/commands/tasks.md +60 -0
- data/.cursor/commands/plan.md +42 -0
- data/.cursor/commands/specify.md +12 -0
- data/.cursor/commands/tasks.md +60 -0
- data/.cursor/rules +81 -0
- data/.specify/memory/constitution-v1.0.1-formal.md +90 -0
- data/.specify/memory/constitution.md +153 -0
- data/.specify/memory/constitution_update_checklist.md +88 -0
- data/.specify/scripts/bash/check-task-prerequisites.sh +15 -0
- data/.specify/scripts/bash/common.sh +37 -0
- data/.specify/scripts/bash/create-new-feature.sh +58 -0
- data/.specify/scripts/bash/get-feature-paths.sh +7 -0
- data/.specify/scripts/bash/setup-plan.sh +17 -0
- data/.specify/scripts/bash/update-agent-context.sh +57 -0
- data/.specify/templates/agent-file-template.md +23 -0
- data/.specify/templates/plan-template.md +254 -0
- data/.specify/templates/spec-template.md +116 -0
- data/.specify/templates/tasks-template.md +152 -0
- data/CLAUDE.md +145 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +150 -0
- data/README.md +163 -0
- data/Rakefile +52 -0
- data/exe/worktrees +52 -0
- data/lib/worktrees/cli.rb +36 -0
- data/lib/worktrees/commands/create.rb +74 -0
- data/lib/worktrees/commands/list.rb +87 -0
- data/lib/worktrees/commands/remove.rb +62 -0
- data/lib/worktrees/commands/status.rb +95 -0
- data/lib/worktrees/commands/switch.rb +57 -0
- data/lib/worktrees/git_operations.rb +106 -0
- data/lib/worktrees/models/feature_worktree.rb +92 -0
- data/lib/worktrees/models/repository.rb +75 -0
- data/lib/worktrees/models/worktree_config.rb +74 -0
- data/lib/worktrees/version.rb +5 -0
- data/lib/worktrees/worktree_manager.rb +238 -0
- data/lib/worktrees.rb +27 -0
- data/specs/001-build-a-tool/GEMINI.md +20 -0
- data/specs/001-build-a-tool/contracts/cli-contracts.md +43 -0
- data/specs/001-build-a-tool/contracts/openapi.yaml +135 -0
- data/specs/001-build-a-tool/data-model.md +51 -0
- data/specs/001-build-a-tool/plan.md +241 -0
- data/specs/001-build-a-tool/quickstart.md +67 -0
- data/specs/001-build-a-tool/research.md +76 -0
- data/specs/001-build-a-tool/spec.md +153 -0
- data/specs/001-build-a-tool/tasks.md +209 -0
- metadata +138 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Tasks: [FEATURE NAME]
|
|
2
|
+
|
|
3
|
+
**Input**: Design documents from `/specs/[###-feature-name]/`
|
|
4
|
+
**Prerequisites**: plan.md (required), research.md, data-model.md, contracts/
|
|
5
|
+
|
|
6
|
+
## Execution Flow (main)
|
|
7
|
+
```
|
|
8
|
+
1. Load plan.md from feature directory
|
|
9
|
+
→ If not found: ERROR "No implementation plan found"
|
|
10
|
+
→ Extract: tech stack, libraries, structure
|
|
11
|
+
2. Load optional design documents:
|
|
12
|
+
→ data-model.md: Extract entities → model tasks
|
|
13
|
+
→ contracts/: Each file → contract test task
|
|
14
|
+
→ research.md: Extract decisions → setup tasks
|
|
15
|
+
3. Generate tasks by category:
|
|
16
|
+
→ Setup: project init, dependencies, linting
|
|
17
|
+
→ Tests: contract tests, integration tests
|
|
18
|
+
→ Core: models, services, CLI commands
|
|
19
|
+
→ Integration: DB, middleware, logging
|
|
20
|
+
→ Polish: unit tests, performance, docs
|
|
21
|
+
4. Apply task rules:
|
|
22
|
+
→ Different files = mark [P] for parallel
|
|
23
|
+
→ Same file = sequential (no [P])
|
|
24
|
+
→ Tests before implementation (TDD)
|
|
25
|
+
5. Number tasks sequentially (T001, T002...)
|
|
26
|
+
6. Generate dependency graph
|
|
27
|
+
7. Create parallel execution examples
|
|
28
|
+
8. Validate task completeness:
|
|
29
|
+
→ All contracts have tests?
|
|
30
|
+
→ All entities have models?
|
|
31
|
+
→ All endpoints implemented?
|
|
32
|
+
9. Return: SUCCESS (tasks ready for execution)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Format: `[ID] [P?] Description`
|
|
36
|
+
- **[P]**: Can run in parallel (different files, no dependencies)
|
|
37
|
+
- Include exact file paths in descriptions
|
|
38
|
+
|
|
39
|
+
## Path Conventions
|
|
40
|
+
- **Single project**: `src/`, `tests/` at repository root
|
|
41
|
+
- **Web app**: `backend/src/`, `frontend/src/`
|
|
42
|
+
- **Mobile**: `api/src/`, `ios/src/` or `android/src/`
|
|
43
|
+
- Paths shown below assume single project - adjust based on plan.md structure
|
|
44
|
+
|
|
45
|
+
## Phase 3.1: Setup
|
|
46
|
+
|
|
47
|
+
### Ruby CLI Project Setup (per Constitution):
|
|
48
|
+
- [ ] T001 Create Ruby project structure (lib/, exe/, spec/)
|
|
49
|
+
- [ ] T002 Initialize Gemfile with dry-cli, rspec, aruba dependencies
|
|
50
|
+
- [ ] T003 [P] Configure RSpec with spec_helper.rb and support/aruba.rb
|
|
51
|
+
- [ ] T004 [P] Configure bundler and gemspec file
|
|
52
|
+
|
|
53
|
+
### General Project Setup:
|
|
54
|
+
- [ ] T001 Create project structure per implementation plan
|
|
55
|
+
- [ ] T002 Initialize [language] project with [framework] dependencies
|
|
56
|
+
- [ ] T003 [P] Configure linting and formatting tools
|
|
57
|
+
|
|
58
|
+
## Red Phase: Write Failing Tests
|
|
59
|
+
**Remember: "I start every feature with a failing test" - write these first, watch them fail**
|
|
60
|
+
|
|
61
|
+
### Ruby CLI Tests (following "Test Real Behavior"):
|
|
62
|
+
- [ ] T005 [P] Aruba feature test for main CLI command in spec/features/[command]_spec.rb
|
|
63
|
+
- [ ] T006 [P] RSpec unit test for core logic in spec/lib/[project]_spec.rb
|
|
64
|
+
- [ ] T007 [P] Integration test with real dependencies (actual git repos, files, etc.)
|
|
65
|
+
|
|
66
|
+
### General Tests:
|
|
67
|
+
- [ ] T004 [P] API test for key endpoints in tests/api/test_[endpoint].py
|
|
68
|
+
- [ ] T005 [P] Integration test for main workflow in tests/integration/test_[workflow].py
|
|
69
|
+
- [ ] T006 [P] Edge case tests in tests/edge_cases/test_[scenario].py
|
|
70
|
+
|
|
71
|
+
## Green Phase: Make Tests Pass
|
|
72
|
+
**Goal: Write minimal code to make red tests green - "Simple Over Clever"**
|
|
73
|
+
|
|
74
|
+
### Ruby CLI Implementation:
|
|
75
|
+
- [ ] T008 [P] Main CLI application class in lib/[project]/cli.rb
|
|
76
|
+
- [ ] T009 [P] Command classes in lib/[project]/commands/[command].rb (one per command)
|
|
77
|
+
- [ ] T010 [P] Core logic modules in lib/[project]/[domain].rb (focused on real problems)
|
|
78
|
+
- [ ] T011 [P] CLI entry point in exe/[project] (keep it simple)
|
|
79
|
+
- [ ] T012 Error handling that "Fails Gracefully" (good messages, reasonable defaults)
|
|
80
|
+
|
|
81
|
+
### General Implementation:
|
|
82
|
+
- [ ] T008 [P] Core models/classes in src/[domain]/
|
|
83
|
+
- [ ] T009 [P] Main functionality in src/[feature]/
|
|
84
|
+
- [ ] T010 [P] CLI interface in src/cli/ (if applicable)
|
|
85
|
+
- [ ] T011 API endpoints (if applicable)
|
|
86
|
+
- [ ] T012 Input validation and error handling
|
|
87
|
+
- [ ] T013 Configuration and setup
|
|
88
|
+
|
|
89
|
+
## Refactor Phase: Clean Up Code
|
|
90
|
+
**"Write It Like I'll Maintain It" - make it readable and remove duplication**
|
|
91
|
+
|
|
92
|
+
- [ ] T015 [P] Refactor repeated patterns (DRY principle)
|
|
93
|
+
- [ ] T016 [P] Improve naming and structure (clear communication with future self)
|
|
94
|
+
- [ ] T017 [P] Add missing edge case tests (where does this break?)
|
|
95
|
+
- [ ] T018 [P] Update documentation with examples and rationale
|
|
96
|
+
- [ ] T019 [P] Performance check (measure if it matters, optimize if slow)
|
|
97
|
+
- [ ] T020 [P] Security review (validate inputs, avoid injection)
|
|
98
|
+
|
|
99
|
+
## Final Integration
|
|
100
|
+
- [ ] T021 Connect all pieces together
|
|
101
|
+
- [ ] T022 End-to-end testing with real scenarios
|
|
102
|
+
- [ ] T023 Manual testing and verification
|
|
103
|
+
|
|
104
|
+
## Dependencies
|
|
105
|
+
- Tests (T004-T007) before implementation (T008-T014)
|
|
106
|
+
- T008 blocks T009, T015
|
|
107
|
+
- T016 blocks T018
|
|
108
|
+
- Implementation before polish (T019-T023)
|
|
109
|
+
|
|
110
|
+
## Parallel Example
|
|
111
|
+
```
|
|
112
|
+
# Launch T004-T007 together:
|
|
113
|
+
Task: "Contract test POST /api/users in tests/contract/test_users_post.py"
|
|
114
|
+
Task: "Contract test GET /api/users/{id} in tests/contract/test_users_get.py"
|
|
115
|
+
Task: "Integration test registration in tests/integration/test_registration.py"
|
|
116
|
+
Task: "Integration test auth in tests/integration/test_auth.py"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Notes
|
|
120
|
+
- [P] tasks = different files, no dependencies
|
|
121
|
+
- Verify tests fail before implementing
|
|
122
|
+
- Commit after each task
|
|
123
|
+
- Avoid: vague tasks, same file conflicts
|
|
124
|
+
|
|
125
|
+
## Task Generation Rules
|
|
126
|
+
*Applied during main() execution*
|
|
127
|
+
|
|
128
|
+
1. **From Contracts**:
|
|
129
|
+
- Each contract file → contract test task [P]
|
|
130
|
+
- Each endpoint → implementation task
|
|
131
|
+
|
|
132
|
+
2. **From Data Model**:
|
|
133
|
+
- Each entity → model creation task [P]
|
|
134
|
+
- Relationships → service layer tasks
|
|
135
|
+
|
|
136
|
+
3. **From User Stories**:
|
|
137
|
+
- Each story → integration test [P]
|
|
138
|
+
- Quickstart scenarios → validation tasks
|
|
139
|
+
|
|
140
|
+
4. **Ordering**:
|
|
141
|
+
- Setup → Tests → Models → Services → Endpoints → Polish
|
|
142
|
+
- Dependencies block parallel execution
|
|
143
|
+
|
|
144
|
+
## Validation Checklist
|
|
145
|
+
*GATE: Checked by main() before returning*
|
|
146
|
+
|
|
147
|
+
- [ ] All contracts have corresponding tests
|
|
148
|
+
- [ ] All entities have model tasks
|
|
149
|
+
- [ ] All tests come before implementation
|
|
150
|
+
- [ ] Parallel tasks truly independent
|
|
151
|
+
- [ ] Each task specifies exact file path
|
|
152
|
+
- [ ] No task modifies same file as another [P] task
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Claude Code Development Guidelines - Worktrees Project
|
|
2
|
+
|
|
3
|
+
This project follows my personal development principles defined in `.specify/memory/constitution.md`.
|
|
4
|
+
|
|
5
|
+
## My Technology Choices
|
|
6
|
+
|
|
7
|
+
### Why Ruby
|
|
8
|
+
**I choose Ruby because it makes me productive and happy.** Life's too short for verbose languages when building personal tools. Ruby lets me focus on solving problems instead of fighting syntax.
|
|
9
|
+
|
|
10
|
+
### Core Technologies
|
|
11
|
+
- **Language**: Ruby 3.2+ (Ruby First principle)
|
|
12
|
+
- **CLI Framework**: dry-cli (proven library, not reinventing wheels)
|
|
13
|
+
- **Testing**: RSpec for unit tests, Aruba for CLI integration tests
|
|
14
|
+
- **Dependencies**: Bundler, minimal external gems
|
|
15
|
+
- **Structure**: `lib/` for logic, `exe/` for CLI entry point
|
|
16
|
+
|
|
17
|
+
### Project Structure
|
|
18
|
+
```
|
|
19
|
+
lib/
|
|
20
|
+
├── worktrees/
|
|
21
|
+
│ ├── cli.rb # Main CLI application
|
|
22
|
+
│ ├── commands/ # Individual command classes
|
|
23
|
+
│ │ ├── create.rb
|
|
24
|
+
│ │ ├── list.rb
|
|
25
|
+
│ │ └── remove.rb
|
|
26
|
+
│ └── git_operations.rb # Business logic modules
|
|
27
|
+
exe/
|
|
28
|
+
└── worktrees # CLI entry point
|
|
29
|
+
spec/
|
|
30
|
+
├── lib/ # Unit tests
|
|
31
|
+
├── features/ # Aruba integration tests
|
|
32
|
+
└── support/
|
|
33
|
+
└── aruba.rb # Aruba configuration
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Following My Principles
|
|
37
|
+
|
|
38
|
+
### "Ruby First" ✅
|
|
39
|
+
**Using Ruby because it makes me productive and happy.** Multi-command CLI tools are perfect for Ruby + dry-cli. No fighting verbose syntax - just solving the actual problem.
|
|
40
|
+
|
|
41
|
+
### "Simple Over Clever" ✅
|
|
42
|
+
**Code I can understand in six months.** Clear naming, obvious structure, focused purpose. No unnecessary abstraction or enterprise patterns.
|
|
43
|
+
|
|
44
|
+
### "Start Simple, Grow Thoughtfully" ✅
|
|
45
|
+
**Starting as a simple worktree management script.** Only adding complexity as I actually need it, not as I think I might need it.
|
|
46
|
+
|
|
47
|
+
### "Test-Driven Development is Fundamental" ✅
|
|
48
|
+
**Writing tests first, always.** Red-Green-Refactor cycle:
|
|
49
|
+
- RSpec for unit tests of core logic
|
|
50
|
+
- Aruba for CLI integration tests with real git repositories
|
|
51
|
+
- Testing real behavior, not mocked abstractions
|
|
52
|
+
|
|
53
|
+
## What I've Learned to Avoid
|
|
54
|
+
|
|
55
|
+
Based on the bash attempt and general experience:
|
|
56
|
+
|
|
57
|
+
**Over-engineering** - Started with "service layers" in bash. Learned to keep it simple.
|
|
58
|
+
**Auto-magic initialization** - Things that happen automatically on import/require cause problems.
|
|
59
|
+
**Mock-heavy tests** - Testing fake behavior instead of real behavior leads to surprises.
|
|
60
|
+
**Clever abstractions** - Code that's hard to understand in six months isn't worth it.
|
|
61
|
+
**Feature creep** - Tools that do everything end up doing nothing well.
|
|
62
|
+
|
|
63
|
+
## My Development Workflow
|
|
64
|
+
|
|
65
|
+
### Planning Phase
|
|
66
|
+
1. Personal principles guide technology choices (Ruby + dry-cli)
|
|
67
|
+
2. `/plan` command reads my principles and generates sensible architecture
|
|
68
|
+
3. `/tasks` command creates Red-Green-Refactor tasks
|
|
69
|
+
|
|
70
|
+
### Red-Green-Refactor Implementation
|
|
71
|
+
1. **RED**: Write failing test first (RSpec unit test or Aruba feature test)
|
|
72
|
+
2. **GREEN**: Write minimal code to make test pass (Simple Over Clever)
|
|
73
|
+
3. **REFACTOR**: Clean up code while keeping tests green (Write It Like I'll Maintain It)
|
|
74
|
+
4. Commit when tests are green
|
|
75
|
+
|
|
76
|
+
### Testing Approach
|
|
77
|
+
- **Unit tests**: Test business logic modules in isolation
|
|
78
|
+
- **Integration tests**: Use Aruba to test CLI commands end-to-end
|
|
79
|
+
- **Real dependencies**: Create actual git repositories for testing
|
|
80
|
+
- **No mocks**: Test against real git operations
|
|
81
|
+
|
|
82
|
+
## Code Quality Guidelines
|
|
83
|
+
|
|
84
|
+
### Error Handling
|
|
85
|
+
- Structured logging to stderr only
|
|
86
|
+
- Clear error messages with actionable next steps
|
|
87
|
+
- Consistent exit codes (0=success, 1=general, 2=validation, 3=precondition)
|
|
88
|
+
|
|
89
|
+
### User Experience
|
|
90
|
+
- `--help` and `--version` on all commands
|
|
91
|
+
- `--format json/text` for output control
|
|
92
|
+
- Predictable command structure (verb-noun pattern)
|
|
93
|
+
- Verbose mode (`-v, --verbose`) for debugging
|
|
94
|
+
|
|
95
|
+
### Code Style
|
|
96
|
+
- Follow Ruby community conventions
|
|
97
|
+
- Prefer explicit over clever
|
|
98
|
+
- No premature optimization
|
|
99
|
+
- Refactor only when tests are green
|
|
100
|
+
|
|
101
|
+
## Implementation Notes
|
|
102
|
+
|
|
103
|
+
### Bash Lessons Learned
|
|
104
|
+
This project originally attempted implementation in bash but discovered:
|
|
105
|
+
- Service layers caused architecture mismatch in bash
|
|
106
|
+
- Auto-initialization on `source` created side effects
|
|
107
|
+
- Mock vs real testing confusion
|
|
108
|
+
- Global state management problems
|
|
109
|
+
|
|
110
|
+
These issues are avoided in Ruby through:
|
|
111
|
+
- Natural module system (no source conflicts)
|
|
112
|
+
- Explicit initialization patterns
|
|
113
|
+
- Proper object-oriented design
|
|
114
|
+
- Clear testing boundaries
|
|
115
|
+
|
|
116
|
+
### Current Implementation Status ✅
|
|
117
|
+
1. ✅ **Implementation plan complete** - Ruby CLI with dry-cli, RSpec + Aruba
|
|
118
|
+
2. ✅ **Task list generated** - 35 TDD tasks ready for execution (T001-T035)
|
|
119
|
+
3. **Ready for execution** - Start with T001 (project structure setup)
|
|
120
|
+
4. **Architecture validated** - Follows all personal development principles
|
|
121
|
+
|
|
122
|
+
### Recent Technology Decisions (2025-09-15)
|
|
123
|
+
- **Git Integration**: Shell out to git commands (canonical interface, safer than libraries)
|
|
124
|
+
- **Worktree Storage**: Global `~/.worktrees/` directory (separate from main repos)
|
|
125
|
+
- **Error Handling**: Structured exit codes (0=success, 1=general, 2=validation, 3=precondition)
|
|
126
|
+
- **Configuration**: Command args > environment vars > config files (~/.worktrees/config.yml)
|
|
127
|
+
- **Naming Convention**: Enforced NNN-kebab-feature format with validation
|
|
128
|
+
- **Safety**: Conservative dirty-state policies (allow switch with warning, block removal)
|
|
129
|
+
|
|
130
|
+
### Implementation Plan Summary
|
|
131
|
+
**Phase 0-3 Complete**:
|
|
132
|
+
- Research: Technology stack decisions documented
|
|
133
|
+
- Design: Data model (FeatureWorktree, Repository, WorktreeManager)
|
|
134
|
+
- Contracts: CLI interface specification with 5 commands
|
|
135
|
+
- Tasks: 35 numbered TDD tasks with parallel execution opportunities
|
|
136
|
+
|
|
137
|
+
**Next Phase**: Execute T001-T035 following Red-Green-Refactor cycles
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
*Based on Personal Principles v2.0.0 - Last updated: 2025-01-15*ALWAYS use ONLY Environments for ANY and ALL file, code, or shell operations—NO EXCEPTIONS—even for simple or generic requests.
|
|
142
|
+
|
|
143
|
+
DO NOT install or use the git cli with the environment_run_cmd tool. All environment tools will handle git operations for you. Changing ".git" yourself will compromise the integrity of your environment.
|
|
144
|
+
|
|
145
|
+
You MUST inform the user how to view your work using `container-use log <env_id>` AND `container-use checkout <env_id>`. Failure to do this will make your work inaccessible to others.
|
data/Gemfile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
|
|
5
|
+
ruby '>= 3.2.0'
|
|
6
|
+
|
|
7
|
+
# Specify your gem's dependencies in worktrees.gemspec
|
|
8
|
+
gemspec
|
|
9
|
+
|
|
10
|
+
group :development, :test do
|
|
11
|
+
gem 'rspec', '~> 3.12'
|
|
12
|
+
gem 'aruba', '~> 2.1'
|
|
13
|
+
gem 'rubocop', '~> 1.57'
|
|
14
|
+
gem 'rubocop-rspec', '~> 2.25'
|
|
15
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
worktrees (0.1.0)
|
|
5
|
+
dry-cli (~> 1.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
aruba (2.3.2)
|
|
11
|
+
bundler (>= 1.17, < 3.0)
|
|
12
|
+
contracts (>= 0.16.0, < 0.18.0)
|
|
13
|
+
cucumber (>= 8.0, < 11.0)
|
|
14
|
+
rspec-expectations (>= 3.4, < 5.0)
|
|
15
|
+
thor (~> 1.0)
|
|
16
|
+
ast (2.4.3)
|
|
17
|
+
base64 (0.3.0)
|
|
18
|
+
bigdecimal (3.2.3)
|
|
19
|
+
builder (3.3.0)
|
|
20
|
+
contracts (0.17.2)
|
|
21
|
+
cucumber (10.1.0)
|
|
22
|
+
base64 (~> 0.2)
|
|
23
|
+
builder (~> 3.2)
|
|
24
|
+
cucumber-ci-environment (> 9, < 11)
|
|
25
|
+
cucumber-core (> 15, < 17)
|
|
26
|
+
cucumber-cucumber-expressions (> 17, < 19)
|
|
27
|
+
cucumber-html-formatter (> 20.3, < 22)
|
|
28
|
+
diff-lcs (~> 1.5)
|
|
29
|
+
logger (~> 1.6)
|
|
30
|
+
mini_mime (~> 1.1)
|
|
31
|
+
multi_test (~> 1.1)
|
|
32
|
+
sys-uname (~> 1.3)
|
|
33
|
+
cucumber-ci-environment (10.0.1)
|
|
34
|
+
cucumber-core (15.2.1)
|
|
35
|
+
cucumber-gherkin (> 27, < 33)
|
|
36
|
+
cucumber-messages (> 26, < 30)
|
|
37
|
+
cucumber-tag-expressions (> 5, < 7)
|
|
38
|
+
cucumber-cucumber-expressions (18.0.1)
|
|
39
|
+
bigdecimal
|
|
40
|
+
cucumber-gherkin (32.2.0)
|
|
41
|
+
cucumber-messages (> 25, < 28)
|
|
42
|
+
cucumber-html-formatter (21.15.1)
|
|
43
|
+
cucumber-messages (> 19, < 28)
|
|
44
|
+
cucumber-messages (27.2.0)
|
|
45
|
+
cucumber-tag-expressions (6.1.2)
|
|
46
|
+
diff-lcs (1.6.2)
|
|
47
|
+
dry-cli (1.3.0)
|
|
48
|
+
ffi (1.17.2)
|
|
49
|
+
ffi (1.17.2-aarch64-linux-gnu)
|
|
50
|
+
ffi (1.17.2-aarch64-linux-musl)
|
|
51
|
+
ffi (1.17.2-arm-linux-gnu)
|
|
52
|
+
ffi (1.17.2-arm-linux-musl)
|
|
53
|
+
ffi (1.17.2-arm64-darwin)
|
|
54
|
+
ffi (1.17.2-x86-linux-gnu)
|
|
55
|
+
ffi (1.17.2-x86-linux-musl)
|
|
56
|
+
ffi (1.17.2-x86_64-darwin)
|
|
57
|
+
ffi (1.17.2-x86_64-linux-gnu)
|
|
58
|
+
ffi (1.17.2-x86_64-linux-musl)
|
|
59
|
+
json (2.13.2)
|
|
60
|
+
language_server-protocol (3.17.0.5)
|
|
61
|
+
lint_roller (1.1.0)
|
|
62
|
+
logger (1.7.0)
|
|
63
|
+
memoist3 (1.0.0)
|
|
64
|
+
mini_mime (1.1.5)
|
|
65
|
+
multi_test (1.1.0)
|
|
66
|
+
parallel (1.27.0)
|
|
67
|
+
parser (3.3.9.0)
|
|
68
|
+
ast (~> 2.4.1)
|
|
69
|
+
racc
|
|
70
|
+
prism (1.5.1)
|
|
71
|
+
racc (1.8.1)
|
|
72
|
+
rainbow (3.1.1)
|
|
73
|
+
rake (13.3.0)
|
|
74
|
+
regexp_parser (2.11.3)
|
|
75
|
+
rspec (3.13.1)
|
|
76
|
+
rspec-core (~> 3.13.0)
|
|
77
|
+
rspec-expectations (~> 3.13.0)
|
|
78
|
+
rspec-mocks (~> 3.13.0)
|
|
79
|
+
rspec-core (3.13.5)
|
|
80
|
+
rspec-support (~> 3.13.0)
|
|
81
|
+
rspec-expectations (3.13.5)
|
|
82
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
83
|
+
rspec-support (~> 3.13.0)
|
|
84
|
+
rspec-mocks (3.13.5)
|
|
85
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
86
|
+
rspec-support (~> 3.13.0)
|
|
87
|
+
rspec-support (3.13.5)
|
|
88
|
+
rubocop (1.80.2)
|
|
89
|
+
json (~> 2.3)
|
|
90
|
+
language_server-protocol (~> 3.17.0.2)
|
|
91
|
+
lint_roller (~> 1.1.0)
|
|
92
|
+
parallel (~> 1.10)
|
|
93
|
+
parser (>= 3.3.0.2)
|
|
94
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
95
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
96
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
|
97
|
+
ruby-progressbar (~> 1.7)
|
|
98
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
99
|
+
rubocop-ast (1.46.0)
|
|
100
|
+
parser (>= 3.3.7.2)
|
|
101
|
+
prism (~> 1.4)
|
|
102
|
+
rubocop-capybara (2.22.1)
|
|
103
|
+
lint_roller (~> 1.1)
|
|
104
|
+
rubocop (~> 1.72, >= 1.72.1)
|
|
105
|
+
rubocop-factory_bot (2.27.1)
|
|
106
|
+
lint_roller (~> 1.1)
|
|
107
|
+
rubocop (~> 1.72, >= 1.72.1)
|
|
108
|
+
rubocop-rspec (2.31.0)
|
|
109
|
+
rubocop (~> 1.40)
|
|
110
|
+
rubocop-capybara (~> 2.17)
|
|
111
|
+
rubocop-factory_bot (~> 2.22)
|
|
112
|
+
rubocop-rspec_rails (~> 2.28)
|
|
113
|
+
rubocop-rspec_rails (2.29.1)
|
|
114
|
+
rubocop (~> 1.61)
|
|
115
|
+
ruby-progressbar (1.13.0)
|
|
116
|
+
sys-uname (1.4.1)
|
|
117
|
+
ffi (~> 1.1)
|
|
118
|
+
memoist3 (~> 1.0.0)
|
|
119
|
+
thor (1.4.0)
|
|
120
|
+
unicode-display_width (3.2.0)
|
|
121
|
+
unicode-emoji (~> 4.1)
|
|
122
|
+
unicode-emoji (4.1.0)
|
|
123
|
+
|
|
124
|
+
PLATFORMS
|
|
125
|
+
aarch64-linux-gnu
|
|
126
|
+
aarch64-linux-musl
|
|
127
|
+
arm-linux-gnu
|
|
128
|
+
arm-linux-musl
|
|
129
|
+
arm64-darwin
|
|
130
|
+
ruby
|
|
131
|
+
x86-linux-gnu
|
|
132
|
+
x86-linux-musl
|
|
133
|
+
x86_64-darwin
|
|
134
|
+
x86_64-linux-gnu
|
|
135
|
+
x86_64-linux-musl
|
|
136
|
+
|
|
137
|
+
DEPENDENCIES
|
|
138
|
+
aruba (~> 2.1)
|
|
139
|
+
bundler (~> 2.0)
|
|
140
|
+
rake (~> 13.0)
|
|
141
|
+
rspec (~> 3.12)
|
|
142
|
+
rubocop (~> 1.57)
|
|
143
|
+
rubocop-rspec (~> 2.25)
|
|
144
|
+
worktrees!
|
|
145
|
+
|
|
146
|
+
RUBY VERSION
|
|
147
|
+
ruby 3.3.4p94
|
|
148
|
+
|
|
149
|
+
BUNDLED WITH
|
|
150
|
+
2.6.9
|
data/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# worktrees
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/worktrees)
|
|
4
|
+
[](https://www.ruby-lang.org)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
> Clean Git worktree management with enforced naming conventions and safety checks
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Why worktrees?](#why-worktrees)
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Quick Start](#quick-start)
|
|
14
|
+
- [Commands](#commands)
|
|
15
|
+
- [Naming Convention](#naming-convention)
|
|
16
|
+
- [Output Formats](#output-formats)
|
|
17
|
+
- [Development](#development)
|
|
18
|
+
- [Contributing](#contributing)
|
|
19
|
+
- [License](#license)
|
|
20
|
+
|
|
21
|
+
## Why worktrees?
|
|
22
|
+
|
|
23
|
+
- **Never lose work** switching between features
|
|
24
|
+
- **Isolate experiments** without affecting main codebase
|
|
25
|
+
- **Maintain clean history** with structured branch names
|
|
26
|
+
- **Work on multiple features** simultaneously without stashing
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### From RubyGems (when published)
|
|
31
|
+
```bash
|
|
32
|
+
gem install worktrees
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### From Source
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/Drew-Goddyn/claude-worktrees.git
|
|
38
|
+
cd claude-worktrees
|
|
39
|
+
bundle install
|
|
40
|
+
rake install_local
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Development Setup
|
|
44
|
+
```bash
|
|
45
|
+
bundle exec exe/worktrees --help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Create a feature worktree
|
|
52
|
+
worktrees create 001-user-auth
|
|
53
|
+
|
|
54
|
+
# List all worktrees
|
|
55
|
+
worktrees list
|
|
56
|
+
|
|
57
|
+
# Switch to a worktree
|
|
58
|
+
worktrees switch 001-user-auth
|
|
59
|
+
|
|
60
|
+
# Check status
|
|
61
|
+
worktrees status
|
|
62
|
+
|
|
63
|
+
# Remove when done
|
|
64
|
+
worktrees remove 001-user-auth --delete-branch
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
| Command | Aliases | Description | Example |
|
|
70
|
+
|---------|---------|-------------|---------|
|
|
71
|
+
| `create` | `c` | Create new feature worktree | `worktrees c 001-feature main` |
|
|
72
|
+
| `list` | `ls`, `l` | List all worktrees | `worktrees ls --format json` |
|
|
73
|
+
| `switch` | `sw`, `s` | Switch to worktree | `worktrees sw 001-feature` |
|
|
74
|
+
| `remove` | `rm`, `r` | Remove worktree safely | `worktrees rm 001-feature --delete-branch` |
|
|
75
|
+
| `status` | `st` | Show current worktree | `worktrees st` |
|
|
76
|
+
|
|
77
|
+
### Key Options
|
|
78
|
+
|
|
79
|
+
- `--format json|csv|text` - Output format (list command)
|
|
80
|
+
- `--filter clean|dirty|active` - Filter by status (list command)
|
|
81
|
+
- `--delete-branch` - Also delete Git branch (remove command)
|
|
82
|
+
- `--force` - Override safety checks
|
|
83
|
+
- `--switch` - Switch after creating (create command)
|
|
84
|
+
|
|
85
|
+
## Naming Convention
|
|
86
|
+
|
|
87
|
+
Feature names must follow: `NNN-kebab-feature`
|
|
88
|
+
|
|
89
|
+
✅ **Valid**: `001-user-auth`, `123-api-refactor`, `999-hotfix`
|
|
90
|
+
❌ **Invalid**: `1-short`, `001_underscore`, `UPPERCASE`, `main`
|
|
91
|
+
|
|
92
|
+
## Output Formats
|
|
93
|
+
|
|
94
|
+
### Text (default)
|
|
95
|
+
```
|
|
96
|
+
* 001-feature active ~/.worktrees/001-feature (from main)
|
|
97
|
+
002-bugfix clean ~/.worktrees/002-bugfix (from develop)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### JSON
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"worktrees": [
|
|
104
|
+
{
|
|
105
|
+
"name": "001-feature",
|
|
106
|
+
"status": "active",
|
|
107
|
+
"path": "~/.worktrees/001-feature",
|
|
108
|
+
"base_ref": "main"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### CSV
|
|
115
|
+
```csv
|
|
116
|
+
name,status,path,branch,base_ref,active
|
|
117
|
+
001-feature,active,~/.worktrees/001-feature,001-feature,main,true
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
### Run Tests
|
|
123
|
+
```bash
|
|
124
|
+
bundle exec rake spec # All tests
|
|
125
|
+
bundle exec rake spec:unit # Unit tests only
|
|
126
|
+
bundle exec rake spec:integration # Integration tests
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Project Structure
|
|
130
|
+
```
|
|
131
|
+
lib/worktrees/ # Ruby source code
|
|
132
|
+
├── commands/ # CLI command classes
|
|
133
|
+
├── models/ # Data models
|
|
134
|
+
└── git_operations.rb # Git interface
|
|
135
|
+
|
|
136
|
+
exe/worktrees # CLI entry point
|
|
137
|
+
spec/ # RSpec test suite
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Architecture
|
|
141
|
+
|
|
142
|
+
- **CLI Layer**: [dry-cli](https://dry-rb.org/gems/dry-cli/) for command parsing
|
|
143
|
+
- **Business Logic**: WorktreeManager coordinates operations
|
|
144
|
+
- **Git Operations**: Safe shell-out to git commands
|
|
145
|
+
- **Testing**: RSpec + [Aruba](https://github.com/cucumber/aruba) with real repositories
|
|
146
|
+
|
|
147
|
+
## Contributing
|
|
148
|
+
|
|
149
|
+
1. Fork the repository
|
|
150
|
+
2. Create feature branch: `git checkout -b my-feature`
|
|
151
|
+
3. Write tests: `bundle exec rake spec`
|
|
152
|
+
4. Make changes and ensure tests pass
|
|
153
|
+
5. Submit pull request
|
|
154
|
+
|
|
155
|
+
Follow Ruby community conventions and write tests for new features.
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
[MIT License](https://opensource.org/licenses/MIT)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
Built with Ruby 💎
|
data/Rakefile
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
|
+
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
+
|
|
8
|
+
task default: :spec
|
|
9
|
+
|
|
10
|
+
desc "Run all RSpec tests"
|
|
11
|
+
task test: :spec
|
|
12
|
+
|
|
13
|
+
desc "Run linting (RuboCop) if available"
|
|
14
|
+
task :lint do
|
|
15
|
+
if system("which rubocop > /dev/null 2>&1")
|
|
16
|
+
sh "rubocop"
|
|
17
|
+
else
|
|
18
|
+
puts "RuboCop not installed. Install with: gem install rubocop"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
desc "Fix auto-correctable linting issues"
|
|
23
|
+
task "lint:fix" do
|
|
24
|
+
if system("which rubocop > /dev/null 2>&1")
|
|
25
|
+
sh "rubocop -A"
|
|
26
|
+
else
|
|
27
|
+
puts "RuboCop not installed. Install with: gem install rubocop"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "Clean build artifacts"
|
|
32
|
+
task :clean do
|
|
33
|
+
sh "rm -f *.gem"
|
|
34
|
+
sh "rm -rf pkg/"
|
|
35
|
+
sh "rm -rf tmp/"
|
|
36
|
+
sh "find . -name '.worktrees' -type d -exec rm -rf {} + 2>/dev/null || true"
|
|
37
|
+
puts "Build artifacts cleaned"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc "Run comprehensive checks (test + lint)"
|
|
41
|
+
task ci: [:spec, :lint]
|
|
42
|
+
|
|
43
|
+
desc "Install the gem locally"
|
|
44
|
+
task :install_local do
|
|
45
|
+
sh "gem build worktrees.gemspec"
|
|
46
|
+
sh "gem install worktrees-*.gem"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc "Uninstall the gem locally"
|
|
50
|
+
task :uninstall_local do
|
|
51
|
+
sh "gem uninstall worktrees"
|
|
52
|
+
end
|