e-pick 2.0.0 → 3.0.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.
package/CLAUDE.md ADDED
@@ -0,0 +1,339 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ E-Pick is a web-based tool for cherry-picking git commits from Excel/CSV files. It consists of a CLI that starts an Express server serving a single-page application. The tool validates commit hashes from uploaded files, generates cherry-pick commands in chronological order, and shows affected files.
8
+
9
+ ## Development Setup
10
+
11
+ ```bash
12
+ # Clone the repository
13
+ git clone <repository-url>
14
+ cd e-pick
15
+
16
+ # Install dependencies
17
+ npm install
18
+
19
+ # Start development server
20
+ epick
21
+ ```
22
+
23
+ The tool will start on http://localhost:7991 and automatically open your browser.
24
+
25
+ ## Development Commands
26
+
27
+ ```bash
28
+ # Start the tool
29
+ epick
30
+
31
+ # Start with specific repository
32
+ epick /path/to/repo
33
+ epick my-project # Using saved alias
34
+
35
+ # Start on custom port
36
+ epick --port 8080
37
+
38
+ # Don't auto-open browser
39
+ epick --no-open
40
+
41
+ # Repository management
42
+ epick repo add my-project # Save current directory
43
+ epick repo add my-project /path/to/repo # Save specific path
44
+ epick repo list # List all saved repositories
45
+ epick repo remove my-project # Remove repository
46
+
47
+ # Linting
48
+ npm run lint
49
+ npm run lint:fix
50
+ ```
51
+
52
+ ## Architecture
53
+
54
+ ### CLI Entry Point (src/cli.js)
55
+ - **CLI name**: `epick` (npm package name: `e-pick`)
56
+ - **Command structure**: Uses Commander.js with subcommands
57
+ - Main command: `epick [repository]` - starts server with optional repository path/alias
58
+ - Subcommands: `repo list|add|remove`
59
+ - Validates repository path and ensures it's a git repository using `git rev-parse --git-dir`
60
+ - Manages repository aliases via RepoManager (stored in `~/.e-pick/repos.json`)
61
+ - Starts Express server and passes repository path to AppConfig singleton
62
+ - **Automatically opens browser** using `open` package (unless `--no-open` flag is used)
63
+ - Handles graceful shutdown on SIGINT/SIGTERM
64
+ - Auto-saves repositories when using paths for the first time
65
+
66
+ ### Express Server (src/server.js)
67
+ - Serves static files from `public/` directory (SPA: index.html + CSS + JS)
68
+ - Provides REST API endpoints for commit validation and command generation
69
+ - Port fallback strategy: tries requested port (default 7991), falls back to random port 8000-9000
70
+ - Security: Helmet middleware (CSP disabled for CDN libraries) and CORS enabled
71
+ - Error handling middleware for consistent error responses
72
+ - Validation middleware using Joi schemas
73
+
74
+ ### Configuration Layer
75
+ - **AppConfig** (src/config/app.config.js): Singleton pattern for centralized configuration
76
+ - Manages server config (port, host)
77
+ - Stores current repository path
78
+ - Provides git, CORS, and logging settings
79
+ - **RepoManager** (src/config/repo-manager.js): Repository alias management
80
+ - Saves/loads/removes repository aliases
81
+ - Stores in `~/.e-pick/repos.json` in user home directory
82
+ - Thread-safe file operations with proper error handling
83
+
84
+ ### Services Layer
85
+ - **GitService** (src/services/git.service.js): Abstracts all git operations using execSync
86
+ - Validates commits exist in repository using `git cat-file -t`
87
+ - Gets commit info (hash, date, author, message) using `git show`
88
+ - Sorts commits chronologically by date (critical for cherry-picking)
89
+ - Generates cherry-pick commands with proper formatting
90
+ - Lists changed files across commits using `git diff-tree`
91
+ - All operations use `cwd: repoPath` for correct repository context
92
+
93
+ - **ValidationService** (src/services/validation.service.js): Orchestrates multi-commit validation
94
+ - Delegates to commit.validator.js for individual commit validation
95
+ - Generates summary statistics (total, valid, invalid, canBeIgnored)
96
+ - Groups validation results by status
97
+ - Handles batch validation with proper error aggregation
98
+
99
+ ### Controllers
100
+ - **commit.controller.js** (src/controllers/commit.controller.js): Handles all API routes
101
+ - `POST /api/validate` - Validates array of commit hashes
102
+ - `POST /api/generate-command` - Generates cherry-pick command with sorted commits
103
+ - `GET /api/repo-info` - Returns current repository information
104
+ - `GET /api/check-commit/:commitHash` - Checks if individual commit exists
105
+ - Uses asyncHandler utility to catch async errors
106
+ - Returns consistent JSON responses
107
+
108
+ ### Commands (Command Pattern)
109
+ - **CherryPickCommand** (src/commands/cherry-pick.command.js): Encapsulates cherry-pick operation
110
+ - Sorts commits by date before generating command
111
+ - Returns commit details, changed files, and warnings for large batches (>50 commits)
112
+ - Built for future undo functionality
113
+ - Validates all commits before building command
114
+
115
+ ### Middleware
116
+ - **validation.middleware.js**: Joi schema validation for request bodies
117
+ - Validates 40-character commit hashes format
118
+ - Supports ignoredCommits array and options object
119
+ - Returns 400 errors for invalid requests
120
+
121
+ - **error.middleware.js**: Centralized error handling
122
+ - Custom error classes: ValidationError, GitError, NotFoundError
123
+ - Maps error types to appropriate HTTP status codes
124
+ - 404 handler for unknown routes
125
+ - Consistent error response format
126
+
127
+ ### Validators
128
+ - **commit.validator.js** (src/validators/commit.validator.js): Individual commit validation logic
129
+ - Validates commit hash format (40 hex characters)
130
+ - Checks if commit exists in repository
131
+ - Returns validation result with error details
132
+ - Used by ValidationService
133
+
134
+ ### Frontend (public/)
135
+ - **Single-page application** with 5-step wizard interface
136
+ 1. Upload Excel/CSV file
137
+ 2. Select columns containing commit hashes and descriptions
138
+ 3. Validate commits against repository
139
+ 4. Review results and generate command
140
+ 5. View changed files
141
+
142
+ - **File parsing**:
143
+ - SheetJS (xlsx) for Excel file parsing (.xlsx, .xls)
144
+ - PapaParse for CSV file parsing
145
+ - Parser Factory pattern for extensibility
146
+
147
+ - **State management**:
148
+ - Observer pattern for UI updates
149
+ - State pattern for wizard step management
150
+ - Filter strategies for commit filtering
151
+
152
+ - **Vanilla JavaScript** (no framework)
153
+ - Modular architecture with separate concerns
154
+ - API Facade for backend communication
155
+ - UI Manager for DOM updates
156
+
157
+ ## Key Technical Details
158
+
159
+ ### Commit Hash Validation
160
+ - All commit hashes must be full 40-character SHA-1 hashes
161
+ - Validation uses `git cat-file -t <hash>` to verify commit exists
162
+ - Short hashes are NOT supported in API layer
163
+ - Frontend validates format before sending to backend
164
+
165
+ ### Chronological Sorting
166
+ - **Critical**: Commits are always sorted by commit date before cherry-picking
167
+ - This prevents issues with dependencies between commits
168
+ - Sorting uses `git show -s --format="%ci %H"` to get timestamps
169
+ - Commits sorted in ascending order (oldest first)
170
+
171
+ ### Repository Path Flow
172
+ 1. CLI validates path is a git repository using `git rev-parse --git-dir`
173
+ 2. Path stored in AppConfig singleton
174
+ 3. All services instantiate with repoPath from AppConfig
175
+ 4. Git commands execute with `cwd: repoPath` to ensure correct context
176
+ 5. Repository aliases stored separately in `~/.e-pick/repos.json`
177
+
178
+ ### Error Handling
179
+ - All git operations wrapped in try-catch blocks
180
+ - Git errors parsed for user-friendly messages
181
+ - Controllers use asyncHandler utility to catch async errors
182
+ - Custom error types map to appropriate HTTP status codes
183
+ - Frontend displays errors with clear messages and suggestions
184
+
185
+ ## Project Structure
186
+
187
+ ```
188
+ e-pick/
189
+ ├── src/
190
+ │ ├── cli.js # CLI entry point with Commander.js
191
+ │ ├── server.js # Express server setup
192
+ │ ├── config/
193
+ │ │ ├── app.config.js # Singleton configuration
194
+ │ │ └── repo-manager.js # Repository alias management
195
+ │ ├── controllers/
196
+ │ │ └── commit.controller.js # API route handlers
197
+ │ ├── services/
198
+ │ │ ├── git.service.js # Git operations (Repository Pattern)
199
+ │ │ └── validation.service.js # Validation orchestration
200
+ │ ├── middleware/
201
+ │ │ ├── error.middleware.js # Error handling
202
+ │ │ └── validation.middleware.js # Request validation (Joi)
203
+ │ ├── commands/
204
+ │ │ └── cherry-pick.command.js # Command pattern
205
+ │ ├── validators/
206
+ │ │ └── commit.validator.js # Commit validation logic
207
+ │ └── utils/
208
+ │ └── error-handler.js # Error utilities
209
+ ├── public/
210
+ │ ├── index.html # Main UI (5-step wizard)
211
+ │ ├── css/
212
+ │ │ └── styles.css # Catppuccin Latte theme
213
+ │ └── js/
214
+ │ ├── app.js # Main orchestrator
215
+ │ ├── ui-manager.js # UI updates
216
+ │ ├── commit-validator.js # Validation handling
217
+ │ ├── file-parser.js # File parsing
218
+ │ ├── api-facade.js # API communication
219
+ │ ├── cherry-pick-builder.js # Command builder
220
+ │ ├── filter-strategy.js # Filtering strategies
221
+ │ ├── observable.js # Observer pattern
222
+ │ ├── stepper-states.js # State pattern for wizard
223
+ │ └── parsers/ # File parser implementations
224
+ │ ├── base-parser.js
225
+ │ ├── csv-parser.js
226
+ │ ├── excel-parser.js
227
+ │ └── parser-factory.js
228
+ ├── package.json
229
+ ├── CLAUDE.md # This file (developer documentation)
230
+ └── README.md # User documentation
231
+ ```
232
+
233
+ ## Design Patterns
234
+
235
+ ### Singleton Pattern
236
+ - **AppConfig**: Ensures single source of truth for configuration across all services
237
+ - Lazy initialization on first access
238
+ - Provides centralized repository path management
239
+
240
+ ### Repository Pattern
241
+ - **GitService**: Abstracts all git operations, making it easy to mock or swap implementations
242
+ - Encapsulates git command execution
243
+ - Provides clean interface for business logic
244
+
245
+ ### Command Pattern
246
+ - **CherryPickCommand**: Encapsulates cherry-pick operation as an object
247
+ - Enables future undo/redo functionality
248
+ - Separates command construction from execution
249
+
250
+ ### Factory Pattern
251
+ - **ParserFactory**: Creates appropriate parser based on file type
252
+ - Extensible for new file formats
253
+ - Encapsulates parser instantiation logic
254
+
255
+ ### Observer Pattern
256
+ - **Observable**: Frontend event system for UI updates
257
+ - Decouples data changes from UI updates
258
+ - Enables reactive UI behavior
259
+
260
+ ### Service Layer Pattern
261
+ - Services handle business logic
262
+ - Controllers are thin and delegate to services
263
+ - Clear separation of concerns
264
+
265
+ ## Configuration
266
+
267
+ - **Default Port**: 7991
268
+ - **Fallback Range**: 8000-9000 (if default port is occupied)
269
+ - **Repository Aliases**: Stored in `~/.e-pick/repos.json`
270
+ - **Git Timeout**: 30 seconds for git operations
271
+ - **Max Commits Per Batch**: 100 commits (warning shown above 50)
272
+ - **Node.js**: >= 18.0.0 required
273
+
274
+ ## Code Style
275
+
276
+ - **ES6 modules**: `type: "module"` in package.json
277
+ - **ESLint**: Airbnb base configuration
278
+ - **File naming**: kebab-case for files, camelCase for variables
279
+ - **Imports**: Prefer explicit imports over default exports
280
+ - **Comments**: JSDoc for public methods and complex logic
281
+ - **Error handling**: Always handle errors explicitly, no silent failures
282
+
283
+ ## Testing Strategy
284
+
285
+ When writing tests:
286
+ - Mock `execSync` for GitService tests to avoid real git operations
287
+ - Test validation logic with various commit hash formats (short, long, invalid)
288
+ - Test chronological sorting with out-of-order commits
289
+ - Test error scenarios: invalid repo path, missing commits, network failures
290
+ - Test edge cases: empty files, malformed data, large batches
291
+
292
+ ## Common Tasks
293
+
294
+ ### Adding a New API Endpoint
295
+ 1. Add route handler in `src/controllers/commit.controller.js`
296
+ 2. Add validation schema in `src/middleware/validation.middleware.js`
297
+ 3. Implement business logic in appropriate service
298
+ 4. Update API Facade in `public/js/api-facade.js`
299
+
300
+ ### Adding Support for New File Format
301
+ 1. Create parser class in `public/js/parsers/` extending BaseParser
302
+ 2. Register in ParserFactory
303
+ 3. Update file input accept attribute in HTML
304
+ 4. Test with sample files
305
+
306
+ ### Modifying Git Operations
307
+ 1. Update GitService methods in `src/services/git.service.js`
308
+ 2. Ensure proper error handling
309
+ 3. Test with mock execSync
310
+ 4. Update related controller logic if needed
311
+
312
+ ## Environment Variables
313
+
314
+ - `LOG_LEVEL` - Logging level (default: 'info')
315
+ - `PORT` - Server port (can also use --port flag)
316
+ - No other environment variables required for basic operation
317
+
318
+ ## Dependencies
319
+
320
+ ### Backend
321
+ - **express**: Web server framework
322
+ - **commander**: CLI argument parsing
323
+ - **chalk**: Terminal styling
324
+ - **joi**: Schema validation
325
+ - **helmet**: Security headers
326
+ - **cors**: CORS middleware
327
+ - **open**: Auto-open browser
328
+
329
+ ### Frontend
330
+ - **SheetJS (xlsx)**: Excel file parsing
331
+ - **PapaParse**: CSV file parsing
332
+ - No build step required (vanilla JS)
333
+
334
+ ## Known Limitations
335
+
336
+ - Short commit hashes not supported (must be full 40-character)
337
+ - Large files (>10MB) may cause browser performance issues
338
+ - Only supports standard git repositories (no submodules)
339
+ - Requires git to be installed and in PATH
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # E-Pick
2
+
3
+ > Web-based tool for cherry-picking git commits from Excel/CSV files
4
+
5
+ E-Pick simplifies the process of cherry-picking multiple git commits by allowing you to manage commit lists in spreadsheet files. Upload an Excel or CSV file containing commit hashes, validate them against your repository, and generate ready-to-use cherry-pick commands.
6
+
7
+ ## Features
8
+
9
+ - Upload Excel (.xlsx, .xls) or CSV files containing commit information
10
+ - Validates all commits against your repository before cherry-picking
11
+ - Interactive 5-step wizard interface
12
+ - Automatically sorts commits by date to prevent dependency issues
13
+ - Clear error messages for invalid commits
14
+ - Save and reuse repository paths with aliases
15
+ - Preview all files affected by selected commits
16
+ - Generates ready-to-execute cherry-pick commands
17
+
18
+ ## Requirements
19
+
20
+ - Node.js >= 18.0.0
21
+ - Git repository
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ # Install globally (future - when published to npm)
27
+ npm install -g epick
28
+
29
+ # Or use npx
30
+ npx epick
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### Start the Tool
36
+
37
+ ```bash
38
+ # In your git repository
39
+ epick
40
+
41
+ # With specific repository
42
+ epick /path/to/repo
43
+
44
+ # With saved repository alias
45
+ epick my-project
46
+
47
+ # Don't auto-open browser
48
+ epick --no-open
49
+ ```
50
+
51
+ The tool will automatically open your browser.
52
+
53
+ ### Save Repositories
54
+
55
+ ```bash
56
+ # Save current directory
57
+ epick repo add my-project
58
+
59
+ # Save specific path
60
+ epick repo add work-repo /path/to/repo
61
+
62
+ # List saved repositories
63
+ epick repo list
64
+
65
+ # Remove repository
66
+ epick repo remove my-project
67
+ ```
68
+
69
+ ### Workflow
70
+
71
+ 1. **Upload File**: Drag and drop your Excel/CSV file
72
+ 2. **Select Columns**: Choose which columns contain commit hashes and descriptions
73
+ 3. **Validate**: The tool validates all commits against your repository
74
+ 4. **Review Results**: View valid/invalid commits with clear indicators
75
+ 5. **Generate Command**: Get a ready-to-execute cherry-pick command
76
+ 6. **Execute**: Copy and run the command in your terminal
77
+
78
+ ### File Format
79
+
80
+ Your Excel or CSV file should contain commit hashes:
81
+
82
+ | Commit Hash | Description |
83
+ |-------------|-------------|
84
+ | abc123... | Fix login bug |
85
+ | def456... | Add new feature |
86
+ | ghi789... | Update dependencies |
87
+
88
+ **Note**: Use full commit hashes (40 characters). Short hashes are not supported.
89
+
90
+ ## Troubleshooting
91
+
92
+ ### "Not a git repository" error
93
+
94
+ Run the tool in a git repository directory:
95
+ ```bash
96
+ epick /path/to/your/repo
97
+ ```
98
+
99
+ ### Invalid commit hashes
100
+
101
+ Make sure your file contains full commit hashes (not shortened versions).
102
+
103
+ ## Development
104
+
105
+ For technical documentation and development setup, see [CLAUDE.md](./CLAUDE.md).
106
+
107
+ ## License
108
+
109
+ MIT
package/package.json CHANGED
@@ -1,18 +1,47 @@
1
1
  {
2
2
  "name": "e-pick",
3
- "version": "2.0.0",
4
- "description": "",
5
- "scripts": {},
3
+ "version": "3.0.0",
4
+ "type": "module",
5
+ "description": "Web-based tool for cherry-picking git commits from Excel/CSV files",
6
+ "main": "src/server.js",
6
7
  "bin": {
7
- "epick": "./cli.js"
8
+ "epick": "./src/cli.js"
9
+ },
10
+ "files": [
11
+ "src/",
12
+ "public/",
13
+ "CLAUDE.md"
14
+ ],
15
+ "scripts": {
16
+ "start": "node src/cli.js",
17
+ "lint": "eslint src/ public/js/",
18
+ "lint:fix": "eslint src/ public/js/ --fix"
19
+ },
20
+ "keywords": [
21
+ "git",
22
+ "cherry-pick",
23
+ "excel",
24
+ "csv",
25
+ "cli",
26
+ "git-tools",
27
+ "commit-management"
28
+ ],
29
+ "engines": {
30
+ "node": ">=18.0.0"
8
31
  },
9
- "keywords": [],
10
- "author": "",
11
- "type": "module",
12
32
  "license": "MIT",
13
33
  "dependencies": {
14
- "express": "^4.21.0",
15
- "joi": "^17.13.3",
16
- "meow": "^13.2.0"
34
+ "chalk": "^5.3.0",
35
+ "commander": "^11.1.0",
36
+ "cors": "^2.8.5",
37
+ "express": "^4.18.2",
38
+ "helmet": "^7.1.0",
39
+ "joi": "^17.11.0",
40
+ "open": "^10.2.0"
41
+ },
42
+ "devDependencies": {
43
+ "eslint": "^8.55.0",
44
+ "eslint-config-airbnb-base": "^15.0.0",
45
+ "eslint-plugin-import": "^2.29.0"
17
46
  }
18
47
  }