shellfirm 0.3.8

`shellfirm` will intercept any risky patterns (default or defined by you) and prompt you a small challenge for double verification, kinda like a captcha for your terminal.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
---
# -- git:bisect --
- test: "git bisect start"
  description: "match bisect start"
  expect_ids: ["git:bisect"]
- test: "git bisect good"
  description: "match bisect good"
  expect_ids: ["git:bisect"]
- test: "git bisect bad"
  description: "match bisect bad"
  expect_ids: ["git:bisect"]
- test: "git bisect reset"
  description: "match bisect reset"
  expect_ids: ["git:bisect"]

# -- git:cherry_pick --
- test: "git cherry-pick abc123"
  description: "match cherry-pick command"
  expect_ids: ["git:cherry_pick"]
- test: "git cherry-pick --no-commit"
  description: "match cherry-pick without commit"
  expect_ids: ["git:cherry_pick"]

# -- git:clean_force --
- test: "git clean -fd"
  description: "match force clean command"
  expect_ids: ["git:clean_force"]
- test: "git clean -fdx"
  description: "match force clean command with x option"
  expect_ids: ["git:clean_force"]

# -- git:delete_all --
- test: "git  rm *"
  description: "match command"
  expect_ids: ["git:delete_all"]
- test: "git rm ."
  description: "match command"
  expect_ids: ["git:delete_all"]
- test: "git rm README.md"
  description: "negative: removing a specific file should not match"
  expect_ids: []
- test: "gitt rm"
  description: "invalid command"
  expect_ids: []

# -- git:delete_ref --
- test: "git update-ref -d refs/heads/feature"
  description: "match delete reference"
  expect_ids: ["git:delete_ref"]
- test: "git update-ref -d HEAD"
  description: "match delete HEAD reference"
  expect_ids: ["git:delete_ref"]

# -- git:filter_branch --
- test: "git filter-branch --env-filter"
  description: "match filter-branch command"
  expect_ids: ["git:filter_branch"]
- test: "git filter-branch --force"
  description: "match filter-branch with force"
  expect_ids: ["git:filter_branch"]

# -- git:force_checkout --
- test: "git checkout -f main"
  description: "match force checkout"
  expect_ids: ["git:force_checkout"]
- test: "git checkout -f"
  description: "match force checkout current branch"
  expect_ids: ["git:force_checkout"]

# -- git:force_delete_branch --
- test: "git branch -D feature"
  description: "match force delete branch"
  expect_ids: ["git:force_delete_branch"]
- test: "git branch -D"
  description: "match force delete current branch"
  expect_ids: ["git:force_delete_branch"]

# -- git:force_push --
- test: "git push -f"
  description: "match force push command"
  expect_ids: ["git:force_push"]
- test: "git push --force"
  description: "match force push with long option"
  expect_ids: ["git:force_push"]
- test: "git push origin --force"
  description: "match force push with remote before flag"
  expect_ids: ["git:force_push"]
- test: "git push origin main --force"
  description: "match force push with remote and branch before flag"
  expect_ids: ["git:force_push"]
- test: "git push origin -f"
  description: "match force push with remote before short flag"
  expect_ids: ["git:force_push"]
- test: "git push --force-with-lease"
  description: "force push with lease is the safe alternative and should not match"
  expect_ids: []

# -- git:gc_prune --
- test: "git gc --prune=now"
  description: "match garbage collection with prune"
  expect_ids: ["git:gc_prune"]
- test: "git   gc   --prune=now"
  description: "match garbage collection with prune and extra spaces"
  expect_ids: ["git:gc_prune"]
- test: "git gc --aggressive"
  description: "match aggressive garbage collection"
  expect_ids: []
- test: "git gc --prune"
  description: "should not match without =now"
  expect_ids: []

# -- git:interactive_rebase --
- test: "git rebase -i HEAD~3"
  description: "match interactive rebase"
  expect_ids: ["git-strict:rebase", "git:interactive_rebase"]
- test: "git rebase -i"
  description: "match interactive rebase without range"
  expect_ids: ["git-strict:rebase", "git:interactive_rebase"]

# -- git:merge_no_ff --
- test: "git merge --no-ff feature"
  description: "match non-fast-forward merge"
  expect_ids: ["git:merge_no_ff"]
- test: "git merge --abort"
  description: "match merge abort"
  expect_ids: ["git:merge_no_ff"]
- test: "git merge --no-ff"
  description: "match non-fast-forward merge without branch"
  expect_ids: ["git:merge_no_ff"]

# -- git:reset --
- test: "git reset"
  description: "match command"
  expect_ids: ["git:reset"]
- test: "git    reset"
  description: "match command"
  expect_ids: ["git:reset"]
- test: "gitt reset"
  description: "invalid command"
  expect_ids: []

# -- git:worktree_management --
- test: "git worktree add ../other"
  description: "match add worktree"
  expect_ids: ["git:worktree_management"]
- test: "git worktree remove ../other"
  description: "match remove worktree"
  expect_ids: ["git:worktree_management"]
- test: "git worktree add -f ../other"
  description: "match force add worktree"
  expect_ids: ["git:worktree_management"]
- test: "git worktree remove -f ../other"
  description: "match force remove worktree"
  expect_ids: ["git:worktree_management"]

# -- git-strict:add_all --
- test: "git add ."
  description: "match add all files"
  expect_ids: ["git-strict:add_all"]
- test: "git add -A"
  description: "match add all files with -A"
  expect_ids: ["git-strict:add_all"]
- test: "git add --all"
  description: "match add all files with --all"
  expect_ids: ["git-strict:add_all"]
- test: "git add README.md"
  description: "negative: adding a specific file should not match"
  expect_ids: []
- test: "git status"
  description: "negative: status command should not match add pattern"
  expect_ids: []

# -- git-strict:commit_all --
- test: "git commit --all"
  description: "match commit all changes"
  expect_ids: ["git-strict:commit_all"]
- test: "git commit -a"
  description: "match commit all with short option"
  expect_ids: ["git-strict:commit_all"]
- test: "git commit -am 'message'"
  description: "match commit all with message"
  expect_ids: ["git-strict:commit_all"]
- test: "git commit -m 'test'"
  description: "negative: commit with only -m (no -a) should not match"
  expect_ids: []
- test: "git commit --amend"
  description: "negative: amend should not match commit-all check"
  expect_ids: []
- test: "git commit --author='someone'"
  description: "negative: author flag should not match commit-all check"
  expect_ids: []

# -- git-strict:create_tag --
- test: "git tag -a v1.0.0"
  description: "match create annotated tag"
  expect_ids: ["git-strict:create_tag"]
- test: "git tag -a"
  description: "match create annotated tag without name"
  expect_ids: ["git-strict:create_tag"]
- test: "git tag v1.0.0"
  description: "negative: lightweight tag without -a should not match"
  expect_ids: []

# -- git-strict:rebase --
- test: "git rebase main"
  description: "match basic rebase"
  expect_ids: ["git-strict:rebase"]
- test: "git rebase"
  description: "match rebase without branch"
  expect_ids: ["git-strict:rebase"]
- test: "git pull --rebase main"
  description: "negative: pull with --rebase flag is not a rebase command"
  expect_ids: []

# -- git-strict:stash_pop_drop --
- test: "git stash pop"
  description: "match stash pop"
  expect_ids: ["git-strict:stash_pop_drop"]
- test: "git stash drop"
  description: "match stash drop"
  expect_ids: ["git-strict:stash_pop_drop"]
- test: "git stash list"
  description: "negative: listing stash entries should not match"
  expect_ids: []

# -- git-strict:submodule_update --
- test: "git submodule update"
  description: "match submodule update"
  expect_ids: ["git-strict:submodule_update"]
- test: "git submodule deinit"
  description: "match submodule deinit"
  expect_ids: ["git-strict:submodule_update"]
- test: "git submodule update --init"
  description: "match submodule update with init"
  expect_ids: ["git-strict:submodule_update"]
- test: "git submodule status"
  description: "negative: checking submodule status should not match"
  expect_ids: []

# -- git:clean_force — flag reordering --
- test: "git clean -df"
  description: "flag reorder -df now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -fxd"
  description: "flag reorder -fxd now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -xfd"
  description: "flag reorder -xfd now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -dfx"
  description: "flag reorder -dfx now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -xdf"
  description: "flag reorder -xdf now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -dxf"
  description: "flag reorder -dxf now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -f -d"
  description: "separate -f -d flags now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -d -f"
  description: "separate -d -f flags now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -f -d -x"
  description: "three separate flags now matched after regex fix"
  expect_ids: ["git:clean_force"]

- test: "git clean -fdX"
  description: "-fdX starts with -fd, matches"
  expect_ids: ["git:clean_force"]

- test: "git   clean   -fd"
  description: "extra spaces, still matches"
  expect_ids: ["git:clean_force"]

- test: "git clean -fdn"
  description: "-fdn starts with -fd, '-n' substring not present (n preceded by d not -)"
  expect_ids: ["git:clean_force"]

# -- git:force_delete_branch — long-form flags --
- test: "git branch --delete --force feature"
  description: "long-form --delete --force now matched after regex fix"
  expect_ids: ["git:force_delete_branch"]

- test: "git branch -d --force feature"
  description: "-d with --force now matched after regex fix"
  expect_ids: ["git:force_delete_branch"]

- test: "git branch -D feature/my-branch"
  description: "branch with slash in name"
  expect_ids: ["git:force_delete_branch"]

# -- git:force_checkout — long-form flag --
- test: "git checkout --force main"
  description: "long-form --force now matched after regex fix"
  expect_ids: ["git:force_checkout"]

- test: "git checkout -f -- ."
  description: "force checkout with -- separator"
  expect_ids: ["git:force_checkout"]

# -- git:checkout_discard_all --
- test: "git checkout -- ."
  description: "match checkout discard all changes"
  expect_ids: ["git:checkout_discard_all"]
- test: "git checkout -- ./"
  description: "match checkout discard all with trailing slash"
  expect_ids: ["git:checkout_discard_all"]
- test: "git checkout -- *"
  description: "match checkout discard with glob"
  expect_ids: ["git:checkout_discard_all"]
- test: "git  checkout  --  ."
  description: "match checkout discard all with extra spaces"
  expect_ids: ["git:checkout_discard_all"]
- test: "git checkout -- file.txt"
  description: "negative: checkout specific file should not match"
  expect_ids: []
- test: "git checkout -- src/main.rs"
  description: "negative: checkout specific file path should not match"
  expect_ids: []
- test: "git checkout -- .gitignore"
  description: "negative: checkout dotfile should not match"
  expect_ids: []
- test: "git checkout -- .env"
  description: "negative: checkout .env file should not match"
  expect_ids: []

# -- git:restore_discard_all --
- test: "git restore ."
  description: "match restore discard all changes"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore ./"
  description: "match restore discard all with trailing slash"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore *"
  description: "match restore discard with glob"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore --staged ."
  description: "match restore staged discard all"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore --staged ./"
  description: "match restore staged with trailing slash"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore --source=HEAD ."
  description: "match restore with source flag"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore --staged --worktree ."
  description: "match restore with multiple flags"
  expect_ids: ["git:restore_discard_all"]
- test: "git  restore  ."
  description: "match restore discard all with extra spaces"
  expect_ids: ["git:restore_discard_all"]
- test: "git restore file.txt"
  description: "negative: restore specific file should not match"
  expect_ids: []
- test: "git restore --staged file.txt"
  description: "negative: restore staged specific file should not match"
  expect_ids: []
- test: "git restore src/main.rs"
  description: "negative: restore specific file path should not match"
  expect_ids: []
- test: "git restore .gitignore"
  description: "negative: restore dotfile should not match"
  expect_ids: []
- test: "git restore .env"
  description: "negative: restore .env file should not match"
  expect_ids: []

# -- git:reset — more variants --
- test: "git reset --hard"
  description: "hard reset, most dangerous variant"
  expect_ids: ["git:reset"]

- test: "git reset --hard HEAD~3"
  description: "hard reset to specific commit"
  expect_ids: ["git:reset"]

- test: "git reset --soft HEAD~1"
  description: "soft reset filtered out by NotContains"
  expect_ids: []

- test: "git reset --hard origin/main"
  description: "hard reset to remote"
  expect_ids: ["git:reset"]

# -- git:push_mirror --
- test: "git push --mirror origin"
  description: "match push --mirror with remote"
  expect_ids: ["git:push_mirror"]
- test: "git push origin --mirror"
  description: "match push with remote before --mirror"
  expect_ids: ["git:push_mirror"]
- test: "git push --mirror"
  description: "match push --mirror without remote"
  expect_ids: ["git:push_mirror"]
- test: "git push origin main"
  description: "negative: regular push should not match mirror"
  expect_ids: []

# -- git:push_delete_branch --
- test: "git push origin --delete feature-branch"
  description: "match push --delete branch"
  expect_ids: ["git:push_delete_branch"]
- test: "git push origin --delete main"
  description: "match push --delete main branch"
  expect_ids: ["git:push_delete_branch"]
- test: "git push origin :feature-branch"
  description: "match push colon syntax to delete remote branch"
  expect_ids: ["git:push_delete_branch"]
- test: "git push origin main"
  description: "negative: regular push should not match delete"
  expect_ids: []

# -- git:reflog_expire --
- test: "git reflog expire --expire=now --all"
  description: "match reflog expire now with --all"
  expect_ids: ["git:reflog_expire"]
- test: "git reflog expire --expire=now"
  description: "match reflog expire now without --all"
  expect_ids: ["git:reflog_expire"]
- test: "git reflog show"
  description: "negative: reflog show should not match"
  expect_ids: []
- test: "git reflog expire --expire=90.days"
  description: "negative: normal expire should not match"
  expect_ids: []