gitflash 0.7.0 → 0.8.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +124 -114
- data/lib/gitflash/branch.rb +10 -5
- data/lib/gitflash/branch_activity.rb +47 -0
- data/lib/gitflash/cleanup.rb +42 -1
- data/lib/gitflash/cli.rb +32 -0
- data/lib/gitflash/commands/clean.rb +14 -4
- data/lib/gitflash/commands/skill_install.rb +118 -0
- data/lib/gitflash/hook/branch_marker.rb +17 -11
- data/lib/gitflash/hook/command_parser.rb +13 -6
- data/lib/gitflash/hook/heredocs.rb +120 -0
- data/lib/gitflash/hook/shell_text.rb +52 -19
- data/lib/gitflash/mcp/confirmation.rb +61 -0
- data/lib/gitflash/mcp/elicitation.rb +122 -0
- data/lib/gitflash/mcp/plan_change.rb +53 -0
- data/lib/gitflash/mcp/runner.rb +41 -0
- data/lib/gitflash/mcp/server.rb +148 -0
- data/lib/gitflash/mcp/tools.rb +195 -0
- data/lib/gitflash/repo.rb +4 -4
- data/lib/gitflash/reused_snapshot.rb +11 -0
- data/lib/gitflash/skill_cli.rb +46 -0
- data/lib/gitflash/snapshot.rb +3 -0
- data/lib/gitflash/snapshots.rb +3 -2
- data/lib/gitflash/ui.rb +8 -2
- data/lib/gitflash/version.rb +1 -1
- data/schema/v1.json +74 -0
- data/skills/gitflash/SKILL.md +95 -0
- metadata +32 -4
data/schema/v1.json
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"gc",
|
|
28
28
|
"hook install",
|
|
29
29
|
"hook status",
|
|
30
|
+
"skill install",
|
|
30
31
|
"worktree list",
|
|
31
32
|
"worktree add",
|
|
32
33
|
"worktree remove",
|
|
@@ -84,6 +85,10 @@
|
|
|
84
85
|
},
|
|
85
86
|
"command": {
|
|
86
87
|
"type": "string"
|
|
88
|
+
},
|
|
89
|
+
"reused": {
|
|
90
|
+
"const": true,
|
|
91
|
+
"description": "Present when nothing had changed since an earlier snapshot, which is handed back instead of saving the same state again. Its id is older than the change; undo with it restores the state before the change."
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
}
|
|
@@ -317,6 +322,25 @@
|
|
|
317
322
|
}
|
|
318
323
|
}
|
|
319
324
|
},
|
|
325
|
+
{
|
|
326
|
+
"if": {
|
|
327
|
+
"properties": {
|
|
328
|
+
"command": {
|
|
329
|
+
"const": "skill install"
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
"then": {
|
|
334
|
+
"properties": {
|
|
335
|
+
"plan": {
|
|
336
|
+
"$ref": "#/$defs/skill_install"
|
|
337
|
+
},
|
|
338
|
+
"result": {
|
|
339
|
+
"$ref": "#/$defs/skill_install"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
},
|
|
320
344
|
{
|
|
321
345
|
"if": {
|
|
322
346
|
"properties": {
|
|
@@ -656,6 +680,21 @@
|
|
|
656
680
|
null
|
|
657
681
|
],
|
|
658
682
|
"description": "Who created the branch; null when unmarked (treated as human)."
|
|
683
|
+
},
|
|
684
|
+
"unused": {
|
|
685
|
+
"type": [
|
|
686
|
+
"boolean",
|
|
687
|
+
"null"
|
|
688
|
+
],
|
|
689
|
+
"description": "Nothing moved the branch since it was created (its reflog has only the creation): it is new, so clean does not treat it as merged. null when the branch has no reflog."
|
|
690
|
+
},
|
|
691
|
+
"last_activity_at": {
|
|
692
|
+
"type": [
|
|
693
|
+
"string",
|
|
694
|
+
"null"
|
|
695
|
+
],
|
|
696
|
+
"format": "date-time",
|
|
697
|
+
"description": "When the branch last moved (its newest reflog entry); null without a reflog. Stale means neither this nor last_commit_at is recent."
|
|
659
698
|
}
|
|
660
699
|
}
|
|
661
700
|
},
|
|
@@ -1194,6 +1233,41 @@
|
|
|
1194
1233
|
}
|
|
1195
1234
|
}
|
|
1196
1235
|
},
|
|
1236
|
+
"skill_install": {
|
|
1237
|
+
"type": "object",
|
|
1238
|
+
"required": [
|
|
1239
|
+
"scope",
|
|
1240
|
+
"directory",
|
|
1241
|
+
"file",
|
|
1242
|
+
"version"
|
|
1243
|
+
],
|
|
1244
|
+
"properties": {
|
|
1245
|
+
"scope": {
|
|
1246
|
+
"enum": [
|
|
1247
|
+
"user",
|
|
1248
|
+
"project",
|
|
1249
|
+
"path"
|
|
1250
|
+
],
|
|
1251
|
+
"description": "`path` when --path DIR was given."
|
|
1252
|
+
},
|
|
1253
|
+
"directory": {
|
|
1254
|
+
"type": "string",
|
|
1255
|
+
"description": "The skills directory; the skill is its gitflash/ subdirectory."
|
|
1256
|
+
},
|
|
1257
|
+
"file": {
|
|
1258
|
+
"type": "string",
|
|
1259
|
+
"description": "Absolute path of the installed SKILL.md."
|
|
1260
|
+
},
|
|
1261
|
+
"version": {
|
|
1262
|
+
"type": "string",
|
|
1263
|
+
"description": "The gitflash version whose skill is installed."
|
|
1264
|
+
},
|
|
1265
|
+
"previous_sha256": {
|
|
1266
|
+
"type": "string",
|
|
1267
|
+
"description": "SHA-256 of the file this install replaces, when one differs. Replacing it needs --confirm TOKEN."
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1197
1271
|
"worktree": {
|
|
1198
1272
|
"type": "object",
|
|
1199
1273
|
"required": [
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitflash
|
|
3
|
+
description: Safe branch, worktree and cleanup work in git repositories, with an undo for every change. Use when you are about to delete or reset branches, discard local changes, remove worktrees, clean up merged or agent-created branches, move commits between branches, or need to recover work that a git command lost (a deleted branch, uncommitted or untracked files, a dropped stash).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# gitflash
|
|
7
|
+
|
|
8
|
+
gitflash is a command-line tool for git repositories that agents work in. Before every change it makes, it saves a snapshot (branches, HEAD, staged, tracked and untracked files, stash entries), so `gitflash undo` can bring the previous state back. Plain git cannot restore uncommitted or untracked files, the reflog of a deleted branch, or a dropped stash.
|
|
9
|
+
|
|
10
|
+
Check that it is installed with `gitflash version`. It needs a git repository; run it from inside one.
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
If the gitflash MCP tools are available (`list_branches`, `delete_branches`, ...), use them instead of the shell for changes: they answer with the same envelope, and their destructive tools can show the plan to the user and ask them to approve it, which the shell cannot. To see a plan without changing anything, call `plan_change` with the tool name and its arguments; then call the tool with `confirm_token`. Destructive tools may ask the user to approve the plan in the client: `cancelled` means the user declined, so do not retry. Otherwise they return `confirmation_required` with `error.confirm_token` first; call again with `confirm_token` only after the user agreed to the plan.
|
|
15
|
+
|
|
16
|
+
1. Prefer gitflash over plain git for anything that deletes or rewrites: `gitflash delete` over `git branch -D`, `gitflash reset --hard` over `git reset --hard`, `gitflash wt remove` over `git worktree remove`.
|
|
17
|
+
2. Always pass `--json`. Never parse the text output.
|
|
18
|
+
3. Without a terminal gitflash never waits for input. A command that needs a choice fails with exit code 2 and says which argument to pass.
|
|
19
|
+
4. Use the two-step flow for changes: run the command without `--yes` (or with `--dry-run`) to get the plan, check it, then run it again with `--yes`.
|
|
20
|
+
5. Do not pass `--yes` to commands the user did not ask for. Show the plan and ask when the change is larger than the request.
|
|
21
|
+
6. A command that chooses what to change by a rule (`clean`, `wt clean`) can select more than the user expects. Show the user the list from the plan and wait for their OK before `--yes`, unless they named every item themselves.
|
|
22
|
+
7. After a change, keep the `undo.command` from the output. Tell the user how to undo it.
|
|
23
|
+
8. Do not save a snapshot yourself before a plain git command when the gitflash hook is installed (`gitflash hook status`, or the gitflash Claude Code plugin): the hook saves one before every risky git command and tells you its undo command. Use `gitflash snapshot` only when no hook is installed, or to mark a point the user wants to come back to.
|
|
24
|
+
|
|
25
|
+
## The JSON envelope
|
|
26
|
+
|
|
27
|
+
Every `--json` run prints one object (the full JSON Schema: `gitflash schema`):
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"schema": 1,
|
|
32
|
+
"command": "delete",
|
|
33
|
+
"ok": true,
|
|
34
|
+
"status": "done",
|
|
35
|
+
"dry_run": false,
|
|
36
|
+
"plan": { "branches": ["old-feature"], "force": false },
|
|
37
|
+
"result": { "deleted": [{ "branch": "old-feature", "sha": "3551cba" }], "failed": [] },
|
|
38
|
+
"undo": { "snapshot": "20261031T191914339710-b836", "command": "gitflash undo 20261031T191914339710-b836" }
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `status`: `done`, `planned` (`--dry-run`), `noop` (nothing to do), `cancelled`, `failed`, `confirmation_required` or `error`. `ok` is true for the first four.
|
|
43
|
+
- `plan`: what the command will do or did. `result`: what happened, including what you need to revert by hand (the SHA of each deleted branch, the previous branch after `checkout`, the previous commit after `reset`).
|
|
44
|
+
- `undo`: the snapshot saved before the change and the command that restores it. With `"reused": true` the id is an earlier snapshot, because nothing had changed since it was taken; that is not a missing snapshot, and undo with it restores the state before this change.
|
|
45
|
+
- `error.code`: a stable identifier to branch on, for example `unknown_branch`, `protected_branch`, `confirmation_required`, `conflict`, `invalid_config`. The message is for people.
|
|
46
|
+
|
|
47
|
+
Exit codes: `0` success, `1` an error (for example a git command failed), `2` invalid usage or a confirmation is needed.
|
|
48
|
+
|
|
49
|
+
## Confirmation
|
|
50
|
+
|
|
51
|
+
- `status: confirmation_required` with exit code 2 means the command stopped before changing anything. The `plan` shows what it would do. Run it again with `--yes` when the plan is what you want.
|
|
52
|
+
- Some changes cannot be undone by `gitflash undo`: `gc` (deletes snapshots), `wt remove` and `wt clean` of a worktree with ignored files (`.env`, local databases), and `skill install` over a changed skill file. `--yes` is not enough for them. The error has `confirm_token`; run the same command again with `--confirm TOKEN`. The token belongs to that exact plan. Ask the user before you do this.
|
|
53
|
+
|
|
54
|
+
## Commands
|
|
55
|
+
|
|
56
|
+
Every command accepts `--json`, `--yes` (`-y`), `--dry-run` and `--confirm TOKEN`. Run `gitflash help COMMAND` for details.
|
|
57
|
+
|
|
58
|
+
| Task | Command |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| List branches with upstream and merge status | `gitflash branches --json` (filters: `--merged`, `--gone`, `--stale DAYS`) |
|
|
61
|
+
| Switch branch | `gitflash checkout BRANCH --json` |
|
|
62
|
+
| Delete branches | `gitflash delete BRANCH... --yes --json` (unmerged ones need `--force`) |
|
|
63
|
+
| Reset the current branch | `gitflash reset COMMIT --json` (mixed; `--soft`, `--hard`) |
|
|
64
|
+
| Delete merged and upstream-gone branches | `gitflash clean --json` (add `--stale [DAYS]`, `--agent`; `--force` for unmerged ones; a branch nobody has committed to yet is kept until it is stale) |
|
|
65
|
+
| Mark branches as agent or human work | `gitflash mark BRANCH... --owner agent --json` (`--clear` removes the mark) |
|
|
66
|
+
| List worktrees with absolute paths | `gitflash wt list --json` |
|
|
67
|
+
| Create a worktree for parallel work | `gitflash wt add BRANCH --json` (the path is in `result`) |
|
|
68
|
+
| Remove worktrees | `gitflash wt remove WORKTREE... --yes --json`, `gitflash wt clean --yes --json` |
|
|
69
|
+
| Other worktree commands | `gitflash wt prune`, `lock`, `unlock`, `move` |
|
|
70
|
+
| Commits of another branch that are not here | `gitflash pick SOURCE --list --json` |
|
|
71
|
+
| Apply them | `gitflash pick SOURCE SHA... --yes --json` (on `conflict`: resolve, then `pick --continue`, or `--skip`, `--abort`) |
|
|
72
|
+
| Save the current state | `gitflash snapshot --message WHY --json` |
|
|
73
|
+
| List snapshots | `gitflash snapshots --json` |
|
|
74
|
+
| Restore a snapshot | `gitflash undo [SNAPSHOT] --yes --json` (default: the latest one taken in this worktree) |
|
|
75
|
+
| Delete old snapshots | `gitflash gc --older-than DAYS --json` (needs `--confirm TOKEN`) |
|
|
76
|
+
|
|
77
|
+
## Protected branches
|
|
78
|
+
|
|
79
|
+
`delete` and `clean` never touch the current branch, the default branch, `main`, `master`, `develop`, `development`, `trunk`, `release/*`, the `protected` patterns in `.gitflash.yml` and `~/.config/gitflash.yml`, or (for `clean`) a branch checked out in a worktree. Do not try to work around this with plain git; ask the user.
|
|
80
|
+
|
|
81
|
+
## Parallel agent work
|
|
82
|
+
|
|
83
|
+
- Create each agent's worktree with `gitflash wt add BRANCH`. Work in the absolute path from `result.path`. `gitflash wt list --json` shows every worktree's path, branch, dirty state and owner from any of them.
|
|
84
|
+
- `wt add` marks a new branch as agent work. For a branch you made with plain git, run `gitflash mark BRANCH --owner agent`, so `gitflash clean --agent` can find it later.
|
|
85
|
+
- `gitflash undo` without an ID restores the latest snapshot of the current worktree, not one taken by another agent in a parallel worktree. Pass the ID from `undo.command` to be exact.
|
|
86
|
+
|
|
87
|
+
## Recovering lost work
|
|
88
|
+
|
|
89
|
+
When the user says a git command lost something:
|
|
90
|
+
|
|
91
|
+
1. Run `gitflash snapshots --json` and find the snapshot taken before the loss (`created_at`, `reason`).
|
|
92
|
+
2. Run `gitflash undo SNAPSHOT --dry-run --json` and show the user what it restores.
|
|
93
|
+
3. Run `gitflash undo SNAPSHOT --yes --json`. The current state is saved first, so this undo can itself be undone.
|
|
94
|
+
|
|
95
|
+
Snapshots do not save ignored files or untracked files over 50 MB, and they cannot bring back a branch on a remote after `git push --force`.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gitflash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kleanthis Mitsioulis
|
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mcp
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.8'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.8'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: thor
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -57,8 +71,8 @@ dependencies:
|
|
|
57
71
|
- - "~>"
|
|
58
72
|
- !ruby/object:Gem::Version
|
|
59
73
|
version: '2.6'
|
|
60
|
-
description:
|
|
61
|
-
|
|
74
|
+
description: Snapshots and undo for plain git, cleanup of agent branches and worktrees,
|
|
75
|
+
one JSON contract for CLI, MCP, skill and hook
|
|
62
76
|
email:
|
|
63
77
|
- kleanthismits@hotmail.gr
|
|
64
78
|
executables:
|
|
@@ -75,6 +89,7 @@ files:
|
|
|
75
89
|
- lib/gitflash.rb
|
|
76
90
|
- lib/gitflash/atomic_file.rb
|
|
77
91
|
- lib/gitflash/branch.rb
|
|
92
|
+
- lib/gitflash/branch_activity.rb
|
|
78
93
|
- lib/gitflash/cherry_pick.rb
|
|
79
94
|
- lib/gitflash/cherry_pick/log_parser.rb
|
|
80
95
|
- lib/gitflash/cleanup.rb
|
|
@@ -95,6 +110,7 @@ files:
|
|
|
95
110
|
- lib/gitflash/commands/pick_outcome.rb
|
|
96
111
|
- lib/gitflash/commands/removal_report.rb
|
|
97
112
|
- lib/gitflash/commands/reset.rb
|
|
113
|
+
- lib/gitflash/commands/skill_install.rb
|
|
98
114
|
- lib/gitflash/commands/snapshot_create.rb
|
|
99
115
|
- lib/gitflash/commands/snapshot_list.rb
|
|
100
116
|
- lib/gitflash/commands/undo.rb
|
|
@@ -123,6 +139,7 @@ files:
|
|
|
123
139
|
- lib/gitflash/hook/creations.rb
|
|
124
140
|
- lib/gitflash/hook/failure.rb
|
|
125
141
|
- lib/gitflash/hook/git_invocation.rb
|
|
142
|
+
- lib/gitflash/hook/heredocs.rb
|
|
126
143
|
- lib/gitflash/hook/history_rules.rb
|
|
127
144
|
- lib/gitflash/hook/losses.rb
|
|
128
145
|
- lib/gitflash/hook/messages.rb
|
|
@@ -133,12 +150,20 @@ files:
|
|
|
133
150
|
- lib/gitflash/hook/shell_text.rb
|
|
134
151
|
- lib/gitflash/hook/wrappers.rb
|
|
135
152
|
- lib/gitflash/hook_cli.rb
|
|
153
|
+
- lib/gitflash/mcp/confirmation.rb
|
|
154
|
+
- lib/gitflash/mcp/elicitation.rb
|
|
155
|
+
- lib/gitflash/mcp/plan_change.rb
|
|
156
|
+
- lib/gitflash/mcp/runner.rb
|
|
157
|
+
- lib/gitflash/mcp/server.rb
|
|
158
|
+
- lib/gitflash/mcp/tools.rb
|
|
136
159
|
- lib/gitflash/ownership.rb
|
|
137
160
|
- lib/gitflash/prompt.rb
|
|
138
161
|
- lib/gitflash/protection.rb
|
|
139
162
|
- lib/gitflash/repo.rb
|
|
140
163
|
- lib/gitflash/restore.rb
|
|
141
164
|
- lib/gitflash/result.rb
|
|
165
|
+
- lib/gitflash/reused_snapshot.rb
|
|
166
|
+
- lib/gitflash/skill_cli.rb
|
|
142
167
|
- lib/gitflash/snapshot.rb
|
|
143
168
|
- lib/gitflash/snapshot_check.rb
|
|
144
169
|
- lib/gitflash/snapshots.rb
|
|
@@ -154,12 +179,15 @@ files:
|
|
|
154
179
|
- lib/gitflash/worktree_revival.rb
|
|
155
180
|
- lib/gitflash/worktrees.rb
|
|
156
181
|
- schema/v1.json
|
|
182
|
+
- skills/gitflash/SKILL.md
|
|
157
183
|
homepage: https://github.com/Kleanthismits/git_flash
|
|
158
184
|
licenses:
|
|
159
185
|
- MIT
|
|
160
186
|
metadata:
|
|
161
187
|
source_code_uri: https://github.com/Kleanthismits/git_flash
|
|
162
188
|
changelog_uri: https://github.com/Kleanthismits/git_flash/blob/main/CHANGELOG.md
|
|
189
|
+
documentation_uri: https://github.com/Kleanthismits/git_flash#readme
|
|
190
|
+
bug_tracker_uri: https://github.com/Kleanthismits/git_flash/issues
|
|
163
191
|
rubygems_mfa_required: 'true'
|
|
164
192
|
rdoc_options: []
|
|
165
193
|
require_paths:
|
|
@@ -177,5 +205,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
177
205
|
requirements: []
|
|
178
206
|
rubygems_version: 4.0.23
|
|
179
207
|
specification_version: 4
|
|
180
|
-
summary:
|
|
208
|
+
summary: Safety net and cleanup for git repos that AI coding agents work in
|
|
181
209
|
test_files: []
|