safe-push 0.1.0 → 0.2.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,102 @@
1
+ # safe-push
2
+
3
+ A Bun CLI tool for safe Git push operations. Detects changes to forbidden areas (default: `.github/`) and blocks pushes based on configurable conditions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun install
9
+ bun run build
10
+ ```
11
+
12
+ Global installation:
13
+
14
+ ```bash
15
+ bun link
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Check Push Permission
21
+
22
+ ```bash
23
+ safe-push check # Display result in human-readable format
24
+ safe-push check --json # Output result as JSON
25
+ ```
26
+
27
+ ### Execute Push
28
+
29
+ ```bash
30
+ safe-push push # Check and push if allowed
31
+ safe-push push --force # Bypass safety checks
32
+ safe-push push --dry-run # Show result without actually pushing
33
+ ```
34
+
35
+ ### Configuration Management
36
+
37
+ ```bash
38
+ safe-push config init # Initialize configuration file
39
+ safe-push config init -f # Overwrite existing configuration
40
+ safe-push config show # Show current configuration
41
+ safe-push config path # Show configuration file path
42
+ ```
43
+
44
+ ## Push Permission Rules
45
+
46
+ ```
47
+ Push Allowed = (No forbidden changes) AND (New branch OR Last commit is yours)
48
+ ```
49
+
50
+ | Forbidden Changes | New Branch | Last Commit Yours | Result |
51
+ |-------------------|------------|-------------------|---------|
52
+ | No | Yes | - | Allowed |
53
+ | No | No | Yes | Allowed |
54
+ | No | No | No | Blocked |
55
+ | Yes | - | - | Blocked |
56
+
57
+ ## Configuration
58
+
59
+ **Path**: `~/.config/safe-push/config.jsonc`
60
+
61
+ ```jsonc
62
+ {
63
+ // Forbidden paths (glob patterns)
64
+ "forbiddenPaths": [".github/"],
65
+ // Behavior on forbidden changes: "error" | "prompt"
66
+ "onForbidden": "error"
67
+ }
68
+ ```
69
+
70
+ ### Options
71
+
72
+ | Key | Type | Default | Description |
73
+ |-----|------|---------|-------------|
74
+ | `forbiddenPaths` | `string[]` | `[".github/"]` | Paths to block changes (glob patterns) |
75
+ | `onForbidden` | `"error" \| "prompt"` | `"error"` | Behavior when forbidden changes detected |
76
+
77
+ - `error`: Display error and exit
78
+ - `prompt`: Ask user for confirmation
79
+
80
+ ## Author Detection
81
+
82
+ Local email is determined by the following priority:
83
+
84
+ 1. Environment variable `SAFE_PUSH_EMAIL`
85
+ 2. `git config user.email`
86
+
87
+ ## Development
88
+
89
+ ```bash
90
+ # Run in development
91
+ bun run dev -- check
92
+
93
+ # Type check
94
+ bun run typecheck
95
+
96
+ # Build
97
+ bun run build
98
+ ```
99
+
100
+ ## License
101
+
102
+ MIT
package/dist/index.js CHANGED
@@ -7046,7 +7046,8 @@ function createCheckCommand() {
7046
7046
 
7047
7047
  // src/commands/push.ts
7048
7048
  function createPushCommand() {
7049
- return new Command("push").description("Check and push if allowed").option("-f, --force", "Bypass safety checks").option("--dry-run", "Show what would be pushed without actually pushing").action(async (options) => {
7049
+ return new Command("push").description("Check and push if allowed").option("-f, --force", "Bypass safety checks").option("--dry-run", "Show what would be pushed without actually pushing").allowUnknownOption().action(async (options, command) => {
7050
+ const gitArgs = command.args;
7050
7051
  try {
7051
7052
  if (!await isGitRepository()) {
7052
7053
  printError("Not a git repository");
@@ -7063,7 +7064,7 @@ function createPushCommand() {
7063
7064
  printSuccess("Dry run: would push (checks bypassed)");
7064
7065
  process.exit(0);
7065
7066
  }
7066
- const result2 = await execPush();
7067
+ const result2 = await execPush(gitArgs);
7067
7068
  if (result2.success) {
7068
7069
  printSuccess("Push successful");
7069
7070
  process.exit(0);
@@ -7082,7 +7083,7 @@ function createPushCommand() {
7082
7083
  printSuccess("Dry run: would push (user confirmed)");
7083
7084
  process.exit(0);
7084
7085
  }
7085
- const result2 = await execPush();
7086
+ const result2 = await execPush(gitArgs);
7086
7087
  if (result2.success) {
7087
7088
  printSuccess("Push successful");
7088
7089
  process.exit(0);
@@ -7101,7 +7102,7 @@ function createPushCommand() {
7101
7102
  printSuccess("Dry run: would push");
7102
7103
  process.exit(0);
7103
7104
  }
7104
- const result = await execPush();
7105
+ const result = await execPush(gitArgs);
7105
7106
  if (result.success) {
7106
7107
  printSuccess("Push successful");
7107
7108
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safe-push",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Git push safety checker - blocks pushes to forbidden areas",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,9 @@ export function createPushCommand(): Command {
18
18
  .description("Check and push if allowed")
19
19
  .option("-f, --force", "Bypass safety checks")
20
20
  .option("--dry-run", "Show what would be pushed without actually pushing")
21
- .action(async (options: { force?: boolean; dryRun?: boolean }) => {
21
+ .allowUnknownOption()
22
+ .action(async (options: { force?: boolean; dryRun?: boolean }, command: Command) => {
23
+ const gitArgs = command.args;
22
24
  try {
23
25
  // Gitリポジトリ内か確認
24
26
  if (!(await isGitRepository())) {
@@ -43,7 +45,7 @@ export function createPushCommand(): Command {
43
45
  process.exit(0);
44
46
  }
45
47
 
46
- const result = await execPush();
48
+ const result = await execPush(gitArgs);
47
49
  if (result.success) {
48
50
  printSuccess("Push successful");
49
51
  process.exit(0);
@@ -73,7 +75,7 @@ export function createPushCommand(): Command {
73
75
  process.exit(0);
74
76
  }
75
77
 
76
- const result = await execPush();
78
+ const result = await execPush(gitArgs);
77
79
  if (result.success) {
78
80
  printSuccess("Push successful");
79
81
  process.exit(0);
@@ -96,7 +98,7 @@ export function createPushCommand(): Command {
96
98
  process.exit(0);
97
99
  }
98
100
 
99
- const result = await execPush();
101
+ const result = await execPush(gitArgs);
100
102
  if (result.success) {
101
103
  printSuccess("Push successful");
102
104
  process.exit(0);