easegit-cli 1.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/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # EaseGit
2
+
3
+ **Automatic checkpoints before Git can hurt you.**
4
+
5
+ ## What is EaseGit?
6
+
7
+ EaseGit creates automatic safety checkpoints before dangerous Git operations and lets you undo them with one command.
8
+
9
+ - Automatic protection during rebase, merge, push, checkout
10
+ - Restore everything in one command
11
+ - Zero configuration
12
+ - Invisible until needed
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install -g easegit
18
+ cd my-repo
19
+ easegit init
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Setup (one time)
25
+
26
+ ```bash
27
+ easegit init
28
+ ```
29
+
30
+ This installs Git hooks that automatically create checkpoints before dangerous operations.
31
+
32
+ ### Normal work (unchanged)
33
+
34
+ ```bash
35
+ git commit
36
+ git merge
37
+ git rebase
38
+ git push --force
39
+ ```
40
+
41
+ EaseGit runs silently in the background. You won't notice it.
42
+
43
+ ### When something breaks
44
+
45
+ ```bash
46
+ easegit undo
47
+ ```
48
+
49
+ This restores your working directory, staged files, and untracked files to the last safe checkpoint.
50
+
51
+ ### Check status
52
+
53
+ ```bash
54
+ easegit status
55
+ ```
56
+
57
+ Shows when the last checkpoint was created and what operation triggered it.
58
+
59
+ ## How it works
60
+
61
+ EaseGit installs Git hooks that automatically create checkpoints before:
62
+
63
+ - `git rebase`
64
+ - `git merge`
65
+ - `git push`
66
+ - `git checkout`
67
+ - `git pull`
68
+ - `git reset`
69
+
70
+ Each checkpoint captures:
71
+
72
+ - All working files
73
+ - Staged changes
74
+ - Untracked files
75
+
76
+ Checkpoints are stored as Git objects under hidden refs. Your commit history is never modified.
77
+
78
+ ## Recovery
79
+
80
+ If a Git operation damages your working state, run:
81
+
82
+ ```bash
83
+ easegit undo
84
+ ```
85
+
86
+ This restores everything exactly as it was before the operation.
87
+
88
+ ## Commands
89
+
90
+ - `easegit init` - Set up EaseGit in this repository
91
+ - `easegit status` - Show last checkpoint information
92
+ - `easegit undo` - Restore last checkpoint
93
+
94
+ ## What EaseGit is NOT
95
+
96
+ - Not a Git replacement
97
+ - Not a backup tool
98
+ - Not a tutorial
99
+ - No configuration needed
100
+ - No GUI
101
+
102
+ ## Philosophy
103
+
104
+ Git is powerful but dangerous. EaseGit makes it safe by creating automatic undo points before operations that can lose work.
105
+
106
+ You never have to remember to create a checkpoint. EaseGit does it automatically.
107
+
108
+ ## License
109
+
110
+ MIT
package/bin/easegit ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/index.js');
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Execute a Git command and return output
3
+ */
4
+ export declare function gitExec(args: string[], cwd?: string): string;
5
+ /**
6
+ * Check if current directory is a Git repository
7
+ */
8
+ export declare function isGitRepo(): boolean;
9
+ /**
10
+ * Get the Git directory path
11
+ */
12
+ export declare function getGitDir(): string;
13
+ /**
14
+ * Get the root directory of the Git repository
15
+ */
16
+ export declare function getRepoRoot(): string;
17
+ /**
18
+ * Create a tree object from the current working directory and index
19
+ * Returns the tree SHA
20
+ */
21
+ export declare function createTreeFromWorkingDir(): string;
22
+ /**
23
+ * Create a ref under refs/easegit/checkpoints/
24
+ */
25
+ export declare function createCheckpointRef(treeSha: string, operation: string): string;
26
+ /**
27
+ * Get the most recent checkpoint ref
28
+ */
29
+ export declare function getLatestCheckpointRef(): string | null;
30
+ /**
31
+ * Get checkpoint info
32
+ */
33
+ export declare function getCheckpointInfo(refName: string): {
34
+ timestamp: number;
35
+ operation: string;
36
+ commitSha: string;
37
+ } | null;
38
+ /**
39
+ * Restore working directory from a tree SHA
40
+ */
41
+ export declare function restoreFromTree(commitSha: string): void;
42
+ /**
43
+ * Check if there are merge conflicts
44
+ */
45
+ export declare function hasMergeConflicts(): boolean;
46
+ /**
47
+ * Check if HEAD is detached
48
+ */
49
+ export declare function isDetachedHead(): boolean;
50
+ /**
51
+ * Check if working directory is dirty
52
+ */
53
+ export declare function isDirty(): boolean;
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.gitExec = gitExec;
37
+ exports.isGitRepo = isGitRepo;
38
+ exports.getGitDir = getGitDir;
39
+ exports.getRepoRoot = getRepoRoot;
40
+ exports.createTreeFromWorkingDir = createTreeFromWorkingDir;
41
+ exports.createCheckpointRef = createCheckpointRef;
42
+ exports.getLatestCheckpointRef = getLatestCheckpointRef;
43
+ exports.getCheckpointInfo = getCheckpointInfo;
44
+ exports.restoreFromTree = restoreFromTree;
45
+ exports.hasMergeConflicts = hasMergeConflicts;
46
+ exports.isDetachedHead = isDetachedHead;
47
+ exports.isDirty = isDirty;
48
+ const child_process_1 = require("child_process");
49
+ const path = __importStar(require("path"));
50
+ /**
51
+ * Execute a Git command and return output
52
+ */
53
+ function gitExec(args, cwd) {
54
+ try {
55
+ return (0, child_process_1.execSync)(`git ${args.join(' ')}`, {
56
+ cwd: cwd || process.cwd(),
57
+ encoding: 'utf8',
58
+ stdio: ['pipe', 'pipe', 'pipe']
59
+ }).trim();
60
+ }
61
+ catch (error) {
62
+ throw new Error(`Git command failed: ${error.message}`);
63
+ }
64
+ }
65
+ /**
66
+ * Check if current directory is a Git repository
67
+ */
68
+ function isGitRepo() {
69
+ try {
70
+ gitExec(['rev-parse', '--git-dir']);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * Get the Git directory path
79
+ */
80
+ function getGitDir() {
81
+ return gitExec(['rev-parse', '--git-dir']);
82
+ }
83
+ /**
84
+ * Get the root directory of the Git repository
85
+ */
86
+ function getRepoRoot() {
87
+ return gitExec(['rev-parse', '--show-toplevel']);
88
+ }
89
+ /**
90
+ * Create a tree object from the current working directory and index
91
+ * Returns the tree SHA
92
+ */
93
+ function createTreeFromWorkingDir() {
94
+ const fs = require('fs');
95
+ // Add all files including untracked to index temporarily
96
+ const originalIndex = path.join(getGitDir(), 'index');
97
+ const tempIndex = path.join(getGitDir(), 'index.easegit.tmp');
98
+ try {
99
+ // Copy current index
100
+ fs.copyFileSync(originalIndex, tempIndex);
101
+ // Set temporary index
102
+ process.env.GIT_INDEX_FILE = tempIndex;
103
+ // Add all files including untracked
104
+ gitExec(['add', '-A']);
105
+ // Write tree
106
+ const treeSha = gitExec(['write-tree']);
107
+ return treeSha;
108
+ }
109
+ finally {
110
+ // Restore original index
111
+ delete process.env.GIT_INDEX_FILE;
112
+ // Clean up temp index
113
+ try {
114
+ fs.unlinkSync(tempIndex);
115
+ }
116
+ catch { }
117
+ }
118
+ }
119
+ /**
120
+ * Create a ref under refs/easegit/checkpoints/
121
+ */
122
+ function createCheckpointRef(treeSha, operation) {
123
+ const timestamp = Date.now();
124
+ const refName = `refs/easegit/checkpoints/${timestamp}`;
125
+ // Create a commit object for the checkpoint
126
+ const message = `EaseGit checkpoint before ${operation}\nTimestamp: ${timestamp}`;
127
+ // Use current HEAD as parent if it exists
128
+ const commitArgs = ['commit-tree', treeSha, '-m', message];
129
+ try {
130
+ const head = gitExec(['rev-parse', 'HEAD']);
131
+ commitArgs.splice(2, 0, '-p', head);
132
+ }
133
+ catch {
134
+ // No HEAD yet (empty repo)
135
+ }
136
+ const commitSha = gitExec(commitArgs).trim();
137
+ // Update ref
138
+ gitExec(['update-ref', refName, commitSha]);
139
+ return refName;
140
+ }
141
+ /**
142
+ * Get the most recent checkpoint ref
143
+ */
144
+ function getLatestCheckpointRef() {
145
+ try {
146
+ const refs = gitExec(['for-each-ref', 'refs/easegit/checkpoints/', '--sort=-refname', '--format=%(refname)', '--count=1']);
147
+ return refs || null;
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ }
153
+ /**
154
+ * Get checkpoint info
155
+ */
156
+ function getCheckpointInfo(refName) {
157
+ try {
158
+ const commitSha = gitExec(['rev-parse', refName]);
159
+ const message = gitExec(['log', '-1', '--format=%B', commitSha]);
160
+ const timestampMatch = message.match(/Timestamp: (\d+)/);
161
+ const operationMatch = message.match(/checkpoint before (.+)/);
162
+ if (!timestampMatch)
163
+ return null;
164
+ return {
165
+ timestamp: parseInt(timestampMatch[1]),
166
+ operation: operationMatch ? operationMatch[1].split('\n')[0] : 'unknown',
167
+ commitSha
168
+ };
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ }
174
+ /**
175
+ * Restore working directory from a tree SHA
176
+ */
177
+ function restoreFromTree(commitSha) {
178
+ const repoRoot = getRepoRoot();
179
+ // Clear working directory (except .git)
180
+ gitExec(['clean', '-fd']);
181
+ // Checkout the tree without moving HEAD
182
+ gitExec(['checkout', commitSha, '--', '.']);
183
+ }
184
+ /**
185
+ * Check if there are merge conflicts
186
+ */
187
+ function hasMergeConflicts() {
188
+ try {
189
+ const status = gitExec(['status', '--porcelain']);
190
+ return status.includes('UU ') || status.includes('AA ') || status.includes('DD ');
191
+ }
192
+ catch {
193
+ return false;
194
+ }
195
+ }
196
+ /**
197
+ * Check if HEAD is detached
198
+ */
199
+ function isDetachedHead() {
200
+ try {
201
+ gitExec(['symbolic-ref', 'HEAD']);
202
+ return false;
203
+ }
204
+ catch {
205
+ return true;
206
+ }
207
+ }
208
+ /**
209
+ * Check if working directory is dirty
210
+ */
211
+ function isDirty() {
212
+ try {
213
+ const status = gitExec(['status', '--porcelain']);
214
+ return status.length > 0;
215
+ }
216
+ catch {
217
+ return false;
218
+ }
219
+ }
220
+ // CommonJS exports for hook scripts
221
+ if (typeof module !== 'undefined' && module.exports) {
222
+ module.exports = {
223
+ gitExec,
224
+ isGitRepo,
225
+ getGitDir,
226
+ getRepoRoot,
227
+ createTreeFromWorkingDir,
228
+ createCheckpointRef,
229
+ getLatestCheckpointRef,
230
+ getCheckpointInfo,
231
+ restoreFromTree,
232
+ hasMergeConflicts,
233
+ isDetachedHead,
234
+ isDirty
235
+ };
236
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const init_1 = require("./init");
4
+ const status_1 = require("./status");
5
+ const undo_1 = require("./undo");
6
+ const command = process.argv[2];
7
+ async function main() {
8
+ try {
9
+ switch (command) {
10
+ case 'init':
11
+ await (0, init_1.init)();
12
+ break;
13
+ case 'status':
14
+ await (0, status_1.status)();
15
+ break;
16
+ case 'undo':
17
+ await (0, undo_1.undo)();
18
+ break;
19
+ default:
20
+ console.log('EaseGit - Automatic Git safety checkpoints\n');
21
+ console.log('Commands:');
22
+ console.log(' easegit init Set up EaseGit in this repository');
23
+ console.log(' easegit status Show last checkpoint information');
24
+ console.log(' easegit undo Restore last checkpoint');
25
+ process.exit(command ? 1 : 0);
26
+ }
27
+ }
28
+ catch (error) {
29
+ console.error(error instanceof Error ? error.message : 'Unknown error');
30
+ process.exit(1);
31
+ }
32
+ }
33
+ main();
package/dist/init.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function init(): Promise<void>;
package/dist/init.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.init = init;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const plumbing_1 = require("./git/plumbing");
40
+ async function init() {
41
+ if (!(0, plumbing_1.isGitRepo)()) {
42
+ throw new Error('Not a Git repository. Run this command inside a Git repository.');
43
+ }
44
+ const gitDir = (0, plumbing_1.getGitDir)();
45
+ const hooksDir = path.join(gitDir, 'hooks');
46
+ // Ensure hooks directory exists
47
+ if (!fs.existsSync(hooksDir)) {
48
+ fs.mkdirSync(hooksDir, { recursive: true });
49
+ }
50
+ // Hook definitions
51
+ const hooks = [
52
+ 'pre-rebase',
53
+ 'pre-merge-commit',
54
+ 'pre-push',
55
+ 'post-checkout'
56
+ ];
57
+ // Get the hooks template directory (from installed package)
58
+ // This will be in node_modules/easegit/hooks or local hooks/ during development
59
+ const packageHooksDir = path.join(__dirname, '..', 'hooks');
60
+ // Install hooks
61
+ for (const hookName of hooks) {
62
+ const hookPath = path.join(hooksDir, hookName);
63
+ const templatePath = path.join(packageHooksDir, hookName);
64
+ if (fs.existsSync(templatePath)) {
65
+ // Copy the hook template
66
+ const hookContent = fs.readFileSync(templatePath, 'utf8');
67
+ fs.writeFileSync(hookPath, hookContent, { mode: 0o755 });
68
+ }
69
+ }
70
+ console.log('EaseGit initialized successfully');
71
+ console.log('Automatic checkpoints will be created before dangerous operations');
72
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Create a checkpoint of the current working state
3
+ */
4
+ export declare function createCheckpoint(operation: string): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCheckpoint = createCheckpoint;
4
+ const plumbing_1 = require("../git/plumbing");
5
+ /**
6
+ * Create a checkpoint of the current working state
7
+ */
8
+ function createCheckpoint(operation) {
9
+ try {
10
+ // Create tree from current working directory (includes untracked files)
11
+ const treeSha = (0, plumbing_1.createTreeFromWorkingDir)();
12
+ // Store as checkpoint ref
13
+ (0, plumbing_1.createCheckpointRef)(treeSha, operation);
14
+ }
15
+ catch (error) {
16
+ // Silently fail - checkpoints are best-effort
17
+ // We never want to block the user's Git operation
18
+ }
19
+ }
20
+ // CommonJS export for hook scripts
21
+ if (typeof module !== 'undefined' && module.exports) {
22
+ module.exports = { createCheckpoint };
23
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Restore the most recent checkpoint
3
+ */
4
+ export declare function restoreCheckpoint(): void;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.restoreCheckpoint = restoreCheckpoint;
4
+ const plumbing_1 = require("../git/plumbing");
5
+ /**
6
+ * Restore the most recent checkpoint
7
+ */
8
+ function restoreCheckpoint() {
9
+ const refName = (0, plumbing_1.getLatestCheckpointRef)();
10
+ if (!refName) {
11
+ throw new Error('No checkpoint found to restore');
12
+ }
13
+ const info = (0, plumbing_1.getCheckpointInfo)(refName);
14
+ if (!info) {
15
+ throw new Error('Checkpoint data is corrupted');
16
+ }
17
+ // Restore working directory from the checkpoint
18
+ (0, plumbing_1.restoreFromTree)(info.commitSha);
19
+ console.log(`Restored checkpoint from ${new Date(info.timestamp).toLocaleString()}`);
20
+ console.log(`Operation: ${info.operation}`);
21
+ }
@@ -0,0 +1 @@
1
+ export declare function status(): Promise<void>;
package/dist/status.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.status = status;
4
+ const plumbing_1 = require("./git/plumbing");
5
+ async function status() {
6
+ if (!(0, plumbing_1.isGitRepo)()) {
7
+ throw new Error('Not a Git repository');
8
+ }
9
+ const refName = (0, plumbing_1.getLatestCheckpointRef)();
10
+ if (!refName) {
11
+ console.log('No checkpoints available');
12
+ console.log('EaseGit will create checkpoints automatically before dangerous operations');
13
+ return;
14
+ }
15
+ const info = (0, plumbing_1.getCheckpointInfo)(refName);
16
+ if (!info) {
17
+ console.log('Checkpoint data corrupted');
18
+ return;
19
+ }
20
+ const date = new Date(info.timestamp);
21
+ console.log('Last checkpoint:');
22
+ console.log(` Time: ${date.toLocaleString()}`);
23
+ console.log(` Operation: ${info.operation}`);
24
+ console.log(` Undo available: yes`);
25
+ }
package/dist/undo.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function undo(): Promise<void>;
package/dist/undo.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.undo = undo;
4
+ const plumbing_1 = require("./git/plumbing");
5
+ const restore_1 = require("./snapshot/restore");
6
+ async function undo() {
7
+ if (!(0, plumbing_1.isGitRepo)()) {
8
+ throw new Error('Not a Git repository');
9
+ }
10
+ (0, restore_1.restoreCheckpoint)();
11
+ }
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Post-checkout hook - creates checkpoint after checkout
4
+ // Also detects failures and warns user
5
+ const path = require('path');
6
+ const mainPath = path.join(__dirname, '..', '..');
7
+ const { createCheckpoint } = require(path.join(mainPath, 'dist', 'snapshot', 'create'));
8
+ const { hasMergeConflicts, isDetachedHead, isDirty } = require(path.join(mainPath, 'dist', 'git', 'plumbing'));
9
+
10
+ // Create checkpoint for the new state
11
+ createCheckpoint('checkout');
12
+
13
+ // Check for problems after checkout
14
+ try {
15
+ const hasConflicts = hasMergeConflicts();
16
+ const detached = isDetachedHead();
17
+ const dirty = isDirty();
18
+
19
+ if (hasConflicts || (detached && dirty)) {
20
+ console.error('⚠ EaseGit: last Git operation damaged your working state.');
21
+ console.error('Run `easegit undo` to restore the last safe checkpoint.');
22
+ }
23
+ } catch {
24
+ // Silent fail
25
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Pre-merge hook - creates checkpoint before merge
4
+ const path = require('path');
5
+ const mainPath = path.join(__dirname, '..', '..');
6
+ const { createCheckpoint } = require(path.join(mainPath, 'dist', 'snapshot', 'create'));
7
+
8
+ createCheckpoint('merge');
package/hooks/pre-push ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Pre-push hook - creates checkpoint before push
4
+ const path = require('path');
5
+ const mainPath = path.join(__dirname, '..', '..');
6
+ const { createCheckpoint } = require(path.join(mainPath, 'dist', 'snapshot', 'create'));
7
+
8
+ createCheckpoint('push');
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Pre-rebase hook - creates checkpoint before rebase
4
+ const path = require('path');
5
+ const mainPath = path.join(__dirname, '..', '..');
6
+ const { createCheckpoint } = require(path.join(mainPath, 'dist', 'snapshot', 'create'));
7
+
8
+ createCheckpoint('rebase');
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "easegit-cli",
3
+ "version": "1.0.0",
4
+ "description": "Automatic checkpoints before Git can hurt you",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "easegit": "./bin/easegit"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "bin",
12
+ "hooks",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "prepublish": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "git",
21
+ "undo",
22
+ "safety",
23
+ "checkpoint",
24
+ "git-safety",
25
+ "git-undo"
26
+ ],
27
+ "author": "hp-078",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/hp-078/easegit-cli.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/hp-078/easegit-cli/issues"
34
+ },
35
+ "homepage": "https://github.com/hp-078/easegit-cli#readme",
36
+ "license": "MIT",
37
+ "devDependencies": {
38
+ "@types/node": "^20.0.0",
39
+ "typescript": "^5.0.0"
40
+ },
41
+ "dependencies": {},
42
+ "engines": {
43
+ "node": ">=16.0.0"
44
+ }
45
+ }