gflows 0.1.15 → 0.1.17

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 CHANGED
@@ -401,10 +401,10 @@ Switch to a workflow branch. With TTY and no branch name, shows a picker; otherw
401
401
 
402
402
  | Option | Description |
403
403
  | ------ | ----------- |
404
+ | **Move** | Move current changes to the target branch. |
405
+ | **Restore** | Save changes for this branch; restore target's saved state (if any). |
406
+ | **Clean** | Discard changes and switch clean at HEAD. |
404
407
  | **Cancel** | Abort switching. |
405
- | **Move changes to target** | Take current changes with you to the target branch (stash → switch → pop). |
406
- | **Restore** | Save changes for the current branch; switch; restore any saved changes for the target branch (if any). |
407
- | **Clean** | Discard changes and switch to the target branch clean at HEAD. |
408
408
 
409
409
  You can skip the prompt by passing exactly one of the flags below. If the target branch has saved changes and you use **Clean**, a warning is shown (unless `-q`).
410
410
 
@@ -425,9 +425,9 @@ bun gflows -W feature/auth-refactor
425
425
  | -------------- | ----- | --------------------------------------------------------------------------- |
426
426
  | `--path <dir>` | `-C` | Run as if in `<dir>`. |
427
427
  | `--branch <name>` | `-B` | Branch to switch to (alternative to positional). |
428
- | `--move` | — | Take current changes to the target branch; no prompt. |
429
- | `--restore` | — | Per-branch save/restore; no prompt. |
430
- | `--clean` | — | Discard changes and switch clean; no prompt. |
428
+ | `--move` | — | Move current changes to the target branch; no prompt. |
429
+ | `--restore` | — | Save for this branch; restore target's saved state (if any); no prompt. |
430
+ | `--clean` | — | Discard changes and switch clean at HEAD; no prompt. |
431
431
  | `--cancel` | — | Abort switching; no prompt. |
432
432
  | `--verbose` | `-v` | Verbose output. |
433
433
  | `--quiet` | `-q` | Minimal output (suppresses Clean warning about saved changes on target). |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gflows",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "A lightweight CLI for consistent Git branching workflows (main + dev, feature/bugfix/chore/release/hotfix).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -160,15 +160,16 @@ function writePackageVersion(dir: string, newVersion: string): void {
160
160
  }
161
161
 
162
162
  /**
163
- * Updates version in jsr.json if the file exists; preserves other keys.
163
+ * Updates version in jsr.json if the file exists. Only the version value is changed;
164
+ * the rest of the file (format, commas, spacing) is left unchanged.
164
165
  */
165
166
  function syncJsrVersion(dir: string, newVersion: string): boolean {
166
167
  const path = join(dir, JSR_JSON);
167
168
  if (!existsSync(path)) return false;
168
169
  const raw = readFileSync(path, "utf-8");
169
- const data = JSON.parse(raw) as Record<string, unknown>;
170
- data.version = newVersion;
171
- writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
170
+ const updated = raw.replace(/"version":\s*"[^"]*"/, `"version": "${newVersion}"`);
171
+ if (updated === raw) return false;
172
+ writeFileSync(path, updated, "utf-8");
172
173
  return true;
173
174
  }
174
175
 
@@ -48,7 +48,10 @@ Start: --force Allow dirty working tree
48
48
  Finish: --no-ff Always create merge commit; -D/--delete, -N/--no-delete;
49
49
  -s/--sign, -T/--no-tag, -M/--tag-message, -m/--message
50
50
  List: -r, --include-remote Include remote-tracking branches
51
- Switch: --move, --restore, --clean, --cancel Explicit mode when uncommitted (no prompt)
51
+ Switch: --move Move current changes to the target branch
52
+ --restore Save for this branch; restore target's saved state (if any)
53
+ --clean Discard changes and switch clean at HEAD
54
+ --cancel Abort switching
52
55
 
53
56
  Exit codes: 0 success, 1 usage/validation, 2 Git or system error.
54
57
 
@@ -87,10 +87,17 @@ export async function run(args: ParsedArgs): Promise<void> {
87
87
  process.exit(EXIT_OK);
88
88
  }
89
89
 
90
+ const currentBranchForPicker = await getCurrentBranch(root, {
91
+ dryRun,
92
+ verbose: args.verbose,
93
+ });
90
94
  const { select } = await import("@inquirer/prompts");
91
95
  const chosen = await select({
92
96
  message: "Switch to branch",
93
- choices: choices.map((b) => ({ name: b, value: b })),
97
+ choices: choices.map((b) => ({
98
+ name: currentBranchForPicker && b === currentBranchForPicker ? `${b} (current)` : b,
99
+ value: b,
100
+ })),
94
101
  });
95
102
 
96
103
  if (typeof chosen !== "string") {
@@ -111,19 +118,13 @@ export async function run(args: ParsedArgs): Promise<void> {
111
118
  whenUncommitted = await selectPrompt({
112
119
  message: "Working tree has uncommitted changes. What do you want to do?",
113
120
  choices: [
114
- { name: "CancelAbort switching", value: "cancel" as const },
115
- {
116
- name: "Move changes to target — Take current changes with you to the target branch",
117
- value: "move" as const,
118
- },
121
+ { name: "MoveMove current changes to the target branch", value: "move" as const },
119
122
  {
120
- name: "Restore — Save for this branch; switch; restore target's saved changes (if any)",
123
+ name: "Restore — Save changes for this branch; restore target's saved state (if any)",
121
124
  value: "restore" as const,
122
125
  },
123
- {
124
- name: "CleanDiscard changes and switch to target clean at HEAD",
125
- value: "clean" as const,
126
- },
126
+ { name: "Clean — Discard changes and switch clean at HEAD", value: "clean" as const },
127
+ { name: "CancelAbort switching", value: "cancel" as const },
127
128
  ],
128
129
  });
129
130
  } else if (!treeClean) {
@@ -187,23 +188,26 @@ export async function run(args: ParsedArgs): Promise<void> {
187
188
  }
188
189
  }
189
190
 
190
- if (whenUncommitted === "restore") {
191
+ const tryRestoreTargetStash = async (): Promise<void> => {
191
192
  const targetStashRef = await findStashRefByBranch(root, targetBranch, gitOpts);
192
- if (targetStashRef) {
193
- try {
194
- await stashPopRef(root, targetStashRef, gitOpts);
195
- } catch (err) {
196
- const msg = err instanceof Error ? err.message : String(err);
197
- console.error(
198
- `gflows switch: conflicts occurred while restoring saved changes for '${targetBranch}'.`,
199
- );
200
- console.error(
201
- "The stash was not dropped. Resolve conflicts, then commit or run `git stash drop` as needed.",
202
- );
203
- if (args.verbose && msg) console.error(msg);
204
- process.exit(EXIT_GIT);
205
- }
193
+ if (!targetStashRef) return;
194
+ try {
195
+ await stashPopRef(root, targetStashRef, gitOpts);
196
+ } catch (err) {
197
+ const msg = err instanceof Error ? err.message : String(err);
198
+ console.error(
199
+ `gflows switch: conflicts occurred while restoring saved changes for '${targetBranch}'.`,
200
+ );
201
+ console.error(
202
+ "The stash was not dropped. Resolve conflicts, then commit or run `git stash drop` as needed.",
203
+ );
204
+ if (args.verbose && msg) console.error(msg);
205
+ process.exit(EXIT_GIT);
206
206
  }
207
+ };
208
+
209
+ if (whenUncommitted === "restore" || whenUncommitted === undefined) {
210
+ await tryRestoreTargetStash();
207
211
  }
208
212
 
209
213
  if (!quiet && !dryRun) {