gent-cli 1.3.0 → 1.5.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/README.md +68 -242
- package/package.json +2 -2
- package/src/commands/commit.js +28 -3
- package/src/commands/init.js +39 -92
- package/src/utils/auth-storage.js +4 -3
package/README.md
CHANGED
|
@@ -1,316 +1,142 @@
|
|
|
1
|
-
# Gent CLI
|
|
1
|
+
# Gent CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> A modern, Git-like version control CLI with built-in cloud authentication and global user identity management.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`gent` is a lightweight version control system that feels exactly like Git but handles user identity automatically through the cloud. No more configuring `user.name` and `user.email` for every repository!
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **File Staging** - Add files to staging area before committing
|
|
9
|
-
- **Commit Management** - Record changes with descriptive messages
|
|
10
|
-
- **Branch Operations** - Create, switch, and manage branches
|
|
11
|
-
- **Status Tracking** - View working tree status and changes
|
|
12
|
-
- **Commit History** - Browse commit logs with detailed information
|
|
7
|
+
## 🚀 Features
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- **Cloud Authentication**: Login once, work everywhere. Your identity follows you across projects.
|
|
10
|
+
- **Git-like Experience**: Familiar commands (`init`, `add`, `commit`, `status`, `log`, `branch`, `checkout`).
|
|
11
|
+
- **Zero Configuration**: `gent init` is silent and auto-detects your authenticated user profile.
|
|
12
|
+
- **Global Identity**: Commits are automatically authored with your cloud profile.
|
|
13
|
+
- **Secure**: Tokens stored securely in your home directory.
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
# Navigate to the CLI directory
|
|
18
|
-
cd apps/Cli
|
|
19
|
-
|
|
20
|
-
# Install dependencies
|
|
21
|
-
npm install
|
|
15
|
+
## 📦 Installation
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
npm
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g gent-cli
|
|
25
19
|
```
|
|
26
20
|
|
|
27
|
-
##
|
|
21
|
+
## 🔐 Authentication (The Magic mmss)
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
Gent uses a global authentication system. You only need to login once.
|
|
30
24
|
|
|
31
|
-
Create
|
|
25
|
+
### Create an Account
|
|
32
26
|
|
|
33
27
|
```bash
|
|
34
|
-
gent
|
|
28
|
+
gent register
|
|
35
29
|
```
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
### Login
|
|
38
32
|
|
|
39
33
|
```bash
|
|
40
|
-
gent
|
|
34
|
+
gent login
|
|
35
|
+
# or
|
|
36
|
+
gent login -e user@example.com -p YourPassword
|
|
41
37
|
```
|
|
42
38
|
|
|
43
39
|
### Check Status
|
|
44
40
|
|
|
45
|
-
View the current state of your working tree:
|
|
46
|
-
|
|
47
41
|
```bash
|
|
48
|
-
gent
|
|
42
|
+
gent whoami
|
|
49
43
|
```
|
|
50
44
|
|
|
51
|
-
|
|
45
|
+
### Logout
|
|
52
46
|
|
|
53
47
|
```bash
|
|
54
|
-
gent
|
|
48
|
+
gent logout
|
|
55
49
|
```
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Add files to the staging area:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# Add specific files
|
|
63
|
-
gent add file1.js file2.js
|
|
64
|
-
|
|
65
|
-
# Add all files
|
|
66
|
-
gent add --all
|
|
67
|
-
gent add .
|
|
68
|
-
```
|
|
51
|
+
## 🛠 Usage
|
|
69
52
|
|
|
70
|
-
###
|
|
53
|
+
### 1. Initialize a Repository
|
|
71
54
|
|
|
72
|
-
|
|
55
|
+
Just like Git, `gent init` is silent and sets up a new repository in your current directory. It automatically uses your logged-in identity for configuration.
|
|
73
56
|
|
|
74
57
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# Interactive (will prompt for message)
|
|
79
|
-
gent commit
|
|
58
|
+
gent init
|
|
59
|
+
# Output: Initialized empty Gent repository in /path/to/project
|
|
80
60
|
```
|
|
81
61
|
|
|
82
|
-
|
|
62
|
+
### 2. Check Status
|
|
63
|
+
|
|
64
|
+
See which files are modified or untracked.
|
|
83
65
|
|
|
84
66
|
```bash
|
|
85
|
-
gent
|
|
67
|
+
gent status
|
|
86
68
|
```
|
|
87
69
|
|
|
88
|
-
###
|
|
70
|
+
### 3. Stage Files
|
|
89
71
|
|
|
90
|
-
|
|
72
|
+
Add files to the staging area.
|
|
91
73
|
|
|
92
74
|
```bash
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# Show specific number of commits
|
|
97
|
-
gent log -n 5
|
|
98
|
-
|
|
99
|
-
# Compact oneline format
|
|
100
|
-
gent log --oneline
|
|
75
|
+
gent add filename.js
|
|
76
|
+
# or add all files
|
|
77
|
+
gent add .
|
|
101
78
|
```
|
|
102
79
|
|
|
103
|
-
###
|
|
80
|
+
### 4. Commit Changes
|
|
104
81
|
|
|
105
|
-
|
|
82
|
+
Create a commit. Gent automatically fetches your name and email from your global login session.
|
|
106
83
|
|
|
107
84
|
```bash
|
|
108
|
-
gent
|
|
85
|
+
gent commit -m "Initial commit"
|
|
86
|
+
# Output: [main a1b2c3d] Initial commit
|
|
87
|
+
# Author: Your Name <your.email@example.com>
|
|
109
88
|
```
|
|
110
89
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
gent branch feature-name
|
|
115
|
-
```
|
|
90
|
+
### 5. View History
|
|
116
91
|
|
|
117
|
-
|
|
92
|
+
See your commit history.
|
|
118
93
|
|
|
119
94
|
```bash
|
|
120
|
-
gent
|
|
95
|
+
gent log
|
|
96
|
+
# or compact view
|
|
97
|
+
gent log --oneline
|
|
121
98
|
```
|
|
122
99
|
|
|
123
|
-
|
|
100
|
+
## 🌿 Branching
|
|
124
101
|
|
|
125
|
-
|
|
102
|
+
Manage branches just like you're used to.
|
|
126
103
|
|
|
127
104
|
```bash
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
Create and switch to a new branch:
|
|
105
|
+
# Create and switch to a new branch
|
|
106
|
+
gent checkout -b feature-login
|
|
132
107
|
|
|
133
|
-
|
|
134
|
-
gent
|
|
135
|
-
```
|
|
108
|
+
# List branches
|
|
109
|
+
gent branch
|
|
136
110
|
|
|
137
|
-
|
|
111
|
+
# Switch back to main
|
|
112
|
+
gent checkout main
|
|
138
113
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
├── src/
|
|
142
|
-
│ ├── index.js # Main entry point
|
|
143
|
-
│ ├── commands/ # Command implementations
|
|
144
|
-
│ │ ├── init.js # Initialize repository
|
|
145
|
-
│ │ ├── status.js # Show status
|
|
146
|
-
│ │ ├── add.js # Stage files
|
|
147
|
-
│ │ ├── commit.js # Create commits
|
|
148
|
-
│ │ ├── log.js # View history
|
|
149
|
-
│ │ ├── branch.js # Manage branches
|
|
150
|
-
│ │ └── checkout.js # Switch branches
|
|
151
|
-
│ └── utils/ # Utility modules
|
|
152
|
-
│ ├── constants.js # Application constants
|
|
153
|
-
│ ├── fileSystem.js # File operations
|
|
154
|
-
│ └── helpers.js # Helper functions
|
|
155
|
-
├── package.json # Dependencies and scripts
|
|
156
|
-
└── README.md # Documentation
|
|
114
|
+
# Delete a branch
|
|
115
|
+
gent branch -d feature-login
|
|
157
116
|
```
|
|
158
117
|
|
|
159
|
-
## Repository Structure
|
|
118
|
+
## 📂 Repository Structure
|
|
160
119
|
|
|
161
|
-
|
|
120
|
+
Gent creates a `.gent` directory in your project root:
|
|
162
121
|
|
|
163
122
|
```
|
|
164
123
|
.gent/
|
|
165
|
-
├── config.json
|
|
166
|
-
├──
|
|
167
|
-
├──
|
|
168
|
-
|
|
169
|
-
├── objects/ # File objects (future use)
|
|
170
|
-
└── refs/ # Branch references
|
|
171
|
-
├── heads/ # Branch pointers
|
|
172
|
-
└── tags/ # Tag references
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## Configuration
|
|
176
|
-
|
|
177
|
-
Gent stores configuration in `.gent/config.json`:
|
|
178
|
-
|
|
179
|
-
```json
|
|
180
|
-
{
|
|
181
|
-
"user": {
|
|
182
|
-
"name": "Your Name",
|
|
183
|
-
"email": "your.email@example.com"
|
|
184
|
-
},
|
|
185
|
-
"repository": {
|
|
186
|
-
"name": "project-name",
|
|
187
|
-
"description": "Project description",
|
|
188
|
-
"created": "2025-11-06T00:00:00.000Z"
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## Ignore Patterns
|
|
194
|
-
|
|
195
|
-
Create a `.gentignore` file to exclude files from tracking:
|
|
196
|
-
|
|
197
|
-
```
|
|
198
|
-
# Dependencies
|
|
199
|
-
node_modules/
|
|
200
|
-
|
|
201
|
-
# Build outputs
|
|
202
|
-
dist/
|
|
203
|
-
build/
|
|
204
|
-
|
|
205
|
-
# Environment files
|
|
206
|
-
.env
|
|
207
|
-
.env.local
|
|
208
|
-
|
|
209
|
-
# Logs
|
|
210
|
-
*.log
|
|
211
|
-
|
|
212
|
-
# OS files
|
|
213
|
-
.DS_Store
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Command Reference
|
|
217
|
-
|
|
218
|
-
| Command | Description | Options |
|
|
219
|
-
|---------|-------------|---------|
|
|
220
|
-
| `gent init` | Initialize repository | `-y, --yes` Skip prompts |
|
|
221
|
-
| `gent status` | Show working tree status | `-s, --short` Short format |
|
|
222
|
-
| `gent add <files>` | Stage files | `-A, --all` Stage all files |
|
|
223
|
-
| `gent commit` | Record changes | `-m <msg>` Message, `-a` Stage all |
|
|
224
|
-
| `gent log` | Show commit history | `-n <num>` Limit, `--oneline` Compact |
|
|
225
|
-
| `gent branch [name]` | Manage branches | `-d <name>` Delete, `-a` List all |
|
|
226
|
-
| `gent checkout <branch>` | Switch branches | `-b` Create new |
|
|
227
|
-
| `gent help [command]` | Show help | |
|
|
228
|
-
|
|
229
|
-
## Dependencies
|
|
230
|
-
|
|
231
|
-
- **commander** - CLI framework
|
|
232
|
-
- **chalk** - Terminal styling
|
|
233
|
-
- **inquirer** - Interactive prompts
|
|
234
|
-
- **ora** - Elegant terminal spinners
|
|
235
|
-
- **boxen** - Create boxes in terminal
|
|
236
|
-
- **date-fns** - Date formatting utilities
|
|
237
|
-
|
|
238
|
-
## Development
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
# Run locally
|
|
242
|
-
npm start
|
|
243
|
-
|
|
244
|
-
# Run specific command
|
|
245
|
-
node src/index.js init
|
|
246
|
-
node src/index.js status
|
|
124
|
+
├── config.json # Project configuration
|
|
125
|
+
├── objects/ # Stored file contents
|
|
126
|
+
├── refs/ # Branch pointers
|
|
127
|
+
└── HEAD # Current branch reference
|
|
247
128
|
```
|
|
248
129
|
|
|
249
|
-
|
|
130
|
+
Your authentication tokens are stored globally in `~/.gent/auth.json`.
|
|
250
131
|
|
|
251
|
-
|
|
132
|
+
## 🤝 Contributing
|
|
252
133
|
|
|
253
|
-
|
|
254
|
-
# Initialize repository
|
|
255
|
-
gent init
|
|
134
|
+
We welcome contributions! Please fork the repository and submit a Pull Request.
|
|
256
135
|
|
|
257
|
-
|
|
258
|
-
echo "console.log('Hello');" > app.js
|
|
259
|
-
gent add app.js
|
|
260
|
-
|
|
261
|
-
# Commit changes
|
|
262
|
-
gent commit -m "Initial commit"
|
|
263
|
-
|
|
264
|
-
# Create a feature branch
|
|
265
|
-
gent branch feature-login
|
|
266
|
-
gent checkout feature-login
|
|
267
|
-
|
|
268
|
-
# Make changes and commit
|
|
269
|
-
echo "// Login logic" >> app.js
|
|
270
|
-
gent add app.js
|
|
271
|
-
gent commit -m "Add login feature"
|
|
272
|
-
|
|
273
|
-
# View history
|
|
274
|
-
gent log
|
|
275
|
-
|
|
276
|
-
# Switch back to main
|
|
277
|
-
gent checkout main
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## Error Handling
|
|
281
|
-
|
|
282
|
-
Gent provides clear error messages:
|
|
283
|
-
|
|
284
|
-
- **Not a gent repository** - Run `gent init` first
|
|
285
|
-
- **No changes to commit** - Stage files with `gent add`
|
|
286
|
-
- **Branch not found** - Check available branches with `gent branch`
|
|
287
|
-
|
|
288
|
-
## Best Practices
|
|
289
|
-
|
|
290
|
-
1. **Commit Often** - Make small, focused commits
|
|
291
|
-
2. **Write Clear Messages** - Describe what and why
|
|
292
|
-
3. **Use Branches** - Isolate features and experiments
|
|
293
|
-
4. **Check Status** - Review changes before committing
|
|
294
|
-
5. **Update .gentignore** - Exclude unnecessary files
|
|
295
|
-
|
|
296
|
-
## Future Enhancements
|
|
297
|
-
|
|
298
|
-
- [ ] Diff visualization
|
|
299
|
-
- [ ] Remote repository support
|
|
300
|
-
- [ ] Merge functionality
|
|
301
|
-
- [ ] Tag management
|
|
302
|
-
- [ ] Stash implementation
|
|
303
|
-
- [ ] File restoration
|
|
304
|
-
- [ ] Conflict resolution
|
|
305
|
-
|
|
306
|
-
## License
|
|
136
|
+
## 📄 License
|
|
307
137
|
|
|
308
138
|
ISC
|
|
309
139
|
|
|
310
|
-
## Author
|
|
311
|
-
|
|
312
|
-
Built with ❤️ using Node.js
|
|
313
|
-
|
|
314
140
|
---
|
|
315
141
|
|
|
316
|
-
|
|
142
|
+
Built with ❤️ by [Abdalrahman Kanawati](https://github.com/SaadShaya7)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gent-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A Git-like version control CLI
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "A modern, Git-like version control CLI with built-in cloud authentication and global user identity management.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"gent": "src/index.js"
|
package/src/commands/commit.js
CHANGED
|
@@ -8,6 +8,7 @@ const chalk = require('chalk');
|
|
|
8
8
|
const inquirer = require('inquirer');
|
|
9
9
|
const ora = require('ora');
|
|
10
10
|
const { getGentPath, readJSON, writeJSON } = require('../utils/fileSystem');
|
|
11
|
+
const authStorage = require('../utils/auth-storage');
|
|
11
12
|
const { STAGING_FILE, COMMITS_FILE, CONFIG_FILE } = require('../utils/constants');
|
|
12
13
|
const { generateCommitHash, getFileHash } = require('../utils/helpers');
|
|
13
14
|
|
|
@@ -49,17 +50,41 @@ async function commit(options) {
|
|
|
49
50
|
|
|
50
51
|
const spinner = ora('Creating commit...').start();
|
|
51
52
|
|
|
52
|
-
// Read config and repository
|
|
53
53
|
const config = await readJSON(path.join(gentPath, CONFIG_FILE));
|
|
54
54
|
const repository = await readJSON(path.join(gentPath, COMMITS_FILE));
|
|
55
55
|
|
|
56
|
+
// Resolve author identity
|
|
57
|
+
let authorName = config.user.name;
|
|
58
|
+
let authorEmail = config.user.email;
|
|
59
|
+
|
|
60
|
+
// Fallback to global auth if local config is empty
|
|
61
|
+
if (!authorName || !authorEmail) {
|
|
62
|
+
const globalUser = await authStorage.getUser();
|
|
63
|
+
if (globalUser) {
|
|
64
|
+
if (!authorName) {
|
|
65
|
+
authorName = [globalUser.first_name, globalUser.last_name].filter(Boolean).join(' ');
|
|
66
|
+
}
|
|
67
|
+
if (!authorEmail) {
|
|
68
|
+
authorEmail = globalUser.email;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Fail if still no identity
|
|
74
|
+
if (!authorName || !authorEmail) {
|
|
75
|
+
spinner.stop();
|
|
76
|
+
console.error(chalk.red('Author identity unknown'));
|
|
77
|
+
console.log(chalk.yellow('Please run "gent login" to set your identity globally'));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
56
81
|
// Create commit object
|
|
57
82
|
const commit = {
|
|
58
83
|
hash: generateCommitHash(),
|
|
59
84
|
message: message,
|
|
60
85
|
author: {
|
|
61
|
-
name:
|
|
62
|
-
email:
|
|
86
|
+
name: authorName,
|
|
87
|
+
email: authorEmail
|
|
63
88
|
},
|
|
64
89
|
timestamp: new Date().toISOString(),
|
|
65
90
|
parent: repository.branches[repository.currentBranch] || null,
|
package/src/commands/init.js
CHANGED
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
const fs = require('fs').promises;
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const chalk = require('chalk');
|
|
9
|
-
const inquirer = require('inquirer');
|
|
10
|
-
const ora = require('ora');
|
|
11
|
-
const boxen = require('boxen');
|
|
12
9
|
const { ensureDir, writeJSON, pathExists } = require('../utils/fileSystem');
|
|
10
|
+
const authStorage = require('../utils/auth-storage');
|
|
13
11
|
const { GENT_DIR, CONFIG_FILE, STAGING_FILE, COMMITS_FILE } = require('../utils/constants');
|
|
14
12
|
|
|
15
13
|
/**
|
|
@@ -17,8 +15,6 @@ const { GENT_DIR, CONFIG_FILE, STAGING_FILE, COMMITS_FILE } = require('../utils/
|
|
|
17
15
|
* @param {Object} options - Command options
|
|
18
16
|
*/
|
|
19
17
|
async function init(options) {
|
|
20
|
-
const spinner = ora('Initializing gent repository...').start();
|
|
21
|
-
|
|
22
18
|
try {
|
|
23
19
|
const cwd = process.cwd();
|
|
24
20
|
const gentPath = path.join(cwd, GENT_DIR);
|
|
@@ -26,28 +22,31 @@ async function init(options) {
|
|
|
26
22
|
|
|
27
23
|
// Check if already initialized
|
|
28
24
|
if (await pathExists(gentPath)) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
default: true
|
|
36
|
-
}
|
|
37
|
-
]);
|
|
25
|
+
isReinit = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Get authenticated user profile if available
|
|
29
|
+
let defaultName = '';
|
|
30
|
+
let defaultEmail = '';
|
|
38
31
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
try {
|
|
33
|
+
const user = await authStorage.getUser();
|
|
34
|
+
if (user) {
|
|
35
|
+
if (user.first_name || user.last_name) {
|
|
36
|
+
defaultName = [user.first_name, user.last_name].filter(Boolean).join(' ');
|
|
37
|
+
}
|
|
38
|
+
if (user.email) {
|
|
39
|
+
defaultEmail = user.email;
|
|
40
|
+
}
|
|
42
41
|
}
|
|
43
|
-
|
|
42
|
+
} catch (error) {
|
|
43
|
+
// Ignore auth errors
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// Get user configuration if not using defaults
|
|
47
46
|
let config = {
|
|
48
47
|
user: {
|
|
49
|
-
name:
|
|
50
|
-
email:
|
|
48
|
+
name: defaultName,
|
|
49
|
+
email: defaultEmail
|
|
51
50
|
},
|
|
52
51
|
repository: {
|
|
53
52
|
name: path.basename(cwd),
|
|
@@ -56,48 +55,6 @@ async function init(options) {
|
|
|
56
55
|
}
|
|
57
56
|
};
|
|
58
57
|
|
|
59
|
-
if (!options.yes) {
|
|
60
|
-
spinner.stop(); // Ensure spinner is stopped before prompt
|
|
61
|
-
|
|
62
|
-
const answers = await inquirer.prompt([
|
|
63
|
-
{
|
|
64
|
-
type: 'input',
|
|
65
|
-
name: 'userName',
|
|
66
|
-
message: 'Enter your name:',
|
|
67
|
-
default: 'Anonymous'
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
type: 'input',
|
|
71
|
-
name: 'userEmail',
|
|
72
|
-
message: 'Enter your email:',
|
|
73
|
-
default: 'anonymous@example.com',
|
|
74
|
-
validate: (input) => {
|
|
75
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
76
|
-
return emailRegex.test(input) || 'Please enter a valid email';
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
type: 'input',
|
|
81
|
-
name: 'repoName',
|
|
82
|
-
message: 'Repository name:',
|
|
83
|
-
default: path.basename(cwd)
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
type: 'input',
|
|
87
|
-
name: 'repoDescription',
|
|
88
|
-
message: 'Repository description:',
|
|
89
|
-
default: 'A gent repository'
|
|
90
|
-
}
|
|
91
|
-
]);
|
|
92
|
-
|
|
93
|
-
config.user.name = answers.userName;
|
|
94
|
-
config.user.email = answers.userEmail;
|
|
95
|
-
config.repository.name = answers.repoName;
|
|
96
|
-
config.repository.description = answers.repoDescription;
|
|
97
|
-
|
|
98
|
-
spinner.start(isReinit ? 'Re-initializing repository...' : 'Creating repository structure...');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
58
|
// Create directory structure
|
|
102
59
|
await ensureDir(gentPath);
|
|
103
60
|
await ensureDir(path.join(gentPath, 'objects'));
|
|
@@ -105,28 +62,37 @@ async function init(options) {
|
|
|
105
62
|
await ensureDir(path.join(gentPath, 'refs', 'tags'));
|
|
106
63
|
|
|
107
64
|
// Create/Update configuration
|
|
108
|
-
|
|
65
|
+
// Only write config if it doesn't exist OR if we have valid user info to update
|
|
66
|
+
const configPath = path.join(gentPath, CONFIG_FILE);
|
|
67
|
+
if (!(await pathExists(configPath)) || (defaultName && defaultEmail)) {
|
|
68
|
+
// If re-init, we might want to preserve existing config unless we have better info?
|
|
69
|
+
// Git re-init doesn't overwrite config usually.
|
|
70
|
+
// But for now, let's write ensuring we have a config file.
|
|
71
|
+
if (!isReinit || !(await pathExists(configPath))) {
|
|
72
|
+
await writeJSON(configPath, config);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
109
75
|
|
|
110
|
-
// Create initial files only if they don't exist
|
|
76
|
+
// Create initial files only if they don't exist
|
|
111
77
|
const stagingPath = path.join(gentPath, STAGING_FILE);
|
|
112
|
-
if (!
|
|
78
|
+
if (!(await pathExists(stagingPath))) {
|
|
113
79
|
await writeJSON(stagingPath, { files: [] });
|
|
114
80
|
}
|
|
115
81
|
|
|
116
82
|
const commitsPath = path.join(gentPath, COMMITS_FILE);
|
|
117
|
-
if (!
|
|
83
|
+
if (!(await pathExists(commitsPath))) {
|
|
118
84
|
await writeJSON(commitsPath, { commits: [], branches: { main: null }, currentBranch: 'main' });
|
|
119
85
|
}
|
|
120
86
|
|
|
121
87
|
// Create HEAD file only if it doesn't exist
|
|
122
88
|
const headPath = path.join(gentPath, 'HEAD');
|
|
123
|
-
if (!
|
|
89
|
+
if (!(await pathExists(headPath))) {
|
|
124
90
|
await fs.writeFile(headPath, 'ref: refs/heads/main\n');
|
|
125
91
|
}
|
|
126
92
|
|
|
127
93
|
// Create .gentignore only if it doesn't exist
|
|
128
94
|
const ignorePath = path.join(cwd, '.gentignore');
|
|
129
|
-
if (!
|
|
95
|
+
if (!(await pathExists(ignorePath))) {
|
|
130
96
|
const gentignore = `# Gent ignore patterns
|
|
131
97
|
node_modules/
|
|
132
98
|
.DS_Store
|
|
@@ -138,33 +104,14 @@ node_modules/
|
|
|
138
104
|
}
|
|
139
105
|
|
|
140
106
|
if (isReinit) {
|
|
141
|
-
|
|
107
|
+
console.log(chalk.gray(`Reinitialized existing Gent repository in ${gentPath}`));
|
|
142
108
|
} else {
|
|
143
|
-
|
|
109
|
+
console.log(chalk.gray(`Initialized empty Gent repository in ${gentPath}`));
|
|
144
110
|
}
|
|
145
111
|
|
|
146
|
-
// Display success message
|
|
147
|
-
const message = chalk.white(`
|
|
148
|
-
${chalk.bold('Repository:')} ${config.repository.name}
|
|
149
|
-
${chalk.bold('User:')} ${config.user.name} <${config.user.email}>
|
|
150
|
-
${chalk.bold('Branch:')} main
|
|
151
|
-
|
|
152
|
-
${chalk.cyan('Next steps:')}
|
|
153
|
-
${chalk.gray('•')} gent add <files> - Add files to staging
|
|
154
|
-
${chalk.gray('•')} gent commit - Commit your changes
|
|
155
|
-
${chalk.gray('•')} gent status - View repository status
|
|
156
|
-
`);
|
|
157
|
-
|
|
158
|
-
console.log(boxen(message, {
|
|
159
|
-
padding: 1,
|
|
160
|
-
margin: 1,
|
|
161
|
-
borderStyle: 'round',
|
|
162
|
-
borderColor: 'cyan'
|
|
163
|
-
}));
|
|
164
|
-
|
|
165
112
|
} catch (error) {
|
|
166
|
-
|
|
167
|
-
console.error(chalk.red('
|
|
113
|
+
console.error(chalk.red('Failed to initialize repository'));
|
|
114
|
+
console.error(chalk.red('Error:'), error.message);
|
|
168
115
|
process.exit(1);
|
|
169
116
|
}
|
|
170
117
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs').promises;
|
|
7
7
|
const path = require('path');
|
|
8
|
+
const os = require('os');
|
|
8
9
|
const CryptoJS = require('crypto-js');
|
|
9
10
|
const { GENT_DIR, AUTH_FILE } = require('./constants');
|
|
10
11
|
|
|
@@ -16,7 +17,7 @@ const ENCRYPTION_KEY = 'gent-cli-secret-key-v1';
|
|
|
16
17
|
* @returns {string} Path to auth.json file
|
|
17
18
|
*/
|
|
18
19
|
function getAuthFilePath() {
|
|
19
|
-
return path.join(
|
|
20
|
+
return path.join(os.homedir(), GENT_DIR, AUTH_FILE);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -48,7 +49,7 @@ function decrypt(encryptedData) {
|
|
|
48
49
|
*/
|
|
49
50
|
async function saveTokens(accessToken, refreshToken, user) {
|
|
50
51
|
const authFilePath = getAuthFilePath();
|
|
51
|
-
const gentDir = path.join(
|
|
52
|
+
const gentDir = path.join(os.homedir(), GENT_DIR);
|
|
52
53
|
|
|
53
54
|
const authData = {
|
|
54
55
|
accessToken,
|
|
@@ -149,7 +150,7 @@ async function updateAccessToken(newAccessToken) {
|
|
|
149
150
|
authData.timestamp = new Date().toISOString();
|
|
150
151
|
|
|
151
152
|
const authFilePath = getAuthFilePath();
|
|
152
|
-
const gentDir = path.join(
|
|
153
|
+
const gentDir = path.join(os.homedir(), GENT_DIR);
|
|
153
154
|
const encryptedData = encrypt(authData);
|
|
154
155
|
|
|
155
156
|
// Ensure .gent directory exists
|