gflows 1.2.0 → 1.2.1

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/AGENTS.md CHANGED
@@ -46,8 +46,9 @@ gflows start release v1.2.0
46
46
  # … changelog / commits …
47
47
  gflows finish release -y -p
48
48
 
49
- # Quick release from dev (bump + merge main + tag, no release/* branch)
50
- gflows release up patch -y -p # or -P; must be on dev
49
+ # Quick release from dev (bump or keep version + merge main + tag, no release/* branch)
50
+ gflows release up patch -y -p # or -P; must be on dev
51
+ gflows release current -y -p # after a manual bump; tags package version as-is
51
52
 
52
53
  # Stuck
53
54
  gflows doctor --json
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.1] - 2026-07-25
11
+
12
+ ### Added
13
+
14
+ - Quick release can keep the package version already on disk: `gflows release current -y -p` (or choose **keep current** in the hub / interactive prompt)
15
+ - MCP `gflows_release` accepts `keepCurrent: true` as an alternative to `bumpType`
16
+
10
17
  ## [1.2.0] - 2026-07-25
11
18
 
12
19
  ### Added
package/README.md CHANGED
@@ -130,7 +130,7 @@ main ← release / hotfix only (production)
130
130
  | **dev** | Integration (created by `init` from main) |
131
131
  | **feature / bugfix / chore / spike** | Day-to-day work → merge to **dev** |
132
132
  | **release / hotfix** | Versioned (`vX.Y.Z`) → **main**, then **main → dev**, + tag |
133
- | **quick release** (`gflows release`) | From **dev** only: bump → **main** → tag → sync **dev** |
133
+ | **quick release** (`gflows release`) | From **dev** only: bump or keep → **main** → tag → sync **dev** |
134
134
 
135
135
 
136
136
  **Lifecycle:** `init` → `start` → commit → (`sync`) → (`pr`) → `finish`
@@ -217,11 +217,13 @@ Hub: `g` → select the action. Typed short form assumes `alias g=gflows`.
217
217
  | `gflows start release v1.4.0` | `g -S -r v1.4.0` |
218
218
  | `gflows finish release -y -p` | `g -F -r -y -p` |
219
219
 
220
- **Quick release from `dev`** — bump, merge **main**, tag, sync **main → dev** (no `release/*` branch)
220
+ **Quick release from `dev`** — merge **main**, tag, sync **main → dev** (no `release/*` branch). Choose a bump, or keep a version you already set manually.
221
221
 
222
222
  | Long | Short |
223
223
  |------|-------|
224
- | `gflows release up patch -y -p` | — |
224
+ | `gflows release up patch -y -p` | — (bump, then ship) |
225
+ | `gflows release up minor -y -p` | — |
226
+ | `gflows release current -y -p` | — (keep `package.json` version; no bump commit) |
225
227
 
226
228
  **Hotfix**
227
229
 
@@ -274,7 +276,7 @@ Bare `gflows` / `g` in a **TTY** opens the Ink hub (see [Way 1](#way-1--hub-reco
274
276
  | `init` `-I` | Ensure main; create dev |
275
277
  | `start` `-S` | Create typed branch |
276
278
  | `finish` `-F` | Merge + close (plan; delete default **on**) |
277
- | `release` | Quick release from `dev` (bump + main + tag)|
279
+ | `release` | Quick release from `dev` (bump/keep + main + tag)|
278
280
  | `sync` | Update branch from its base |
279
281
  | `pr` | Open PR/MR (`gh` / `glab`) |
280
282
  | `switch` `-W` | Switch branch |
package/llms.txt CHANGED
@@ -14,6 +14,7 @@
14
14
  - `gflows viz`: scrollback status panel — lifecycle, branches, recommended next step
15
15
  - `gflows init` / `start` / `finish` / `release` / `sync` / `pr`
16
16
  - `gflows release up patch -y -p` — quick ship from `dev` (bump + merge main + tag)
17
+ - `gflows release current -y -p` — same, but keep the package version already on disk (after a manual bump)
17
18
  - `gflows continue` / `undo` / `abort` — recovery after conflicts
18
19
  - `gflows doctor` / `info` / `config` / `status --json` / `mcp`
19
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gflows",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "author": "Ali AlNaghmoush (https://github.com/alialnaghmoush)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -135,8 +135,8 @@ _gflows() {
135
135
  ;;
136
136
  release)
137
137
  if (( cword == cmd_idx + 1 )); then
138
- COMPREPLY=($(compgen -W "up" -- "$cur"))
139
- elif (( cword == cmd_idx + 2 )); then
138
+ COMPREPLY=($(compgen -W "up current" -- "$cur"))
139
+ elif (( cword == cmd_idx + 2 )) && [[ "${D}words[cmd_idx + 1]}" == "up" ]]; then
140
140
  COMPREPLY=($(compgen -W "${BUMP_TYPES.join(" ")}" -- "$cur"))
141
141
  else
142
142
  COMPREPLY=()
@@ -226,7 +226,7 @@ _gflows() {
226
226
  if [[ "${D}words[CURRENT-1]}" == "up" ]]; then
227
227
  _values "bump-type" ${BUMP_TYPES.map((t) => `"${t}"`).join(" ")}
228
228
  else
229
- _values "direction" "up"
229
+ _values "mode" "up" "current"
230
230
  fi
231
231
  ;;
232
232
  esac
@@ -334,9 +334,11 @@ complete -c gflows -f -n "__fish_seen_subcommand_from bump; and not __fish_seen_
334
334
  complete -c gflows -f -n "__fish_seen_subcommand_from bump; and __fish_seen_subcommand_from up down" \\
335
335
  -a "patch minor major"
336
336
 
337
- # release up [patch|minor|major]
338
- complete -c gflows -f -n "__fish_seen_subcommand_from release; and not __fish_seen_subcommand_from up" \\
339
- -a "up"
337
+ # release up [patch|minor|major] | current
338
+ complete -c gflows -f -n "__fish_seen_subcommand_from release; and not __fish_seen_subcommand_from up current" \\
339
+ -a "up" -d "Bump then release"
340
+ complete -c gflows -f -n "__fish_seen_subcommand_from release; and not __fish_seen_subcommand_from up current" \\
341
+ -a "current" -d "Keep current version (no bump)"
340
342
  complete -c gflows -f -n "__fish_seen_subcommand_from release; and __fish_seen_subcommand_from up" \\
341
343
  -a "patch minor major"
342
344
 
@@ -19,7 +19,7 @@ Commands:
19
19
  init, -I Ensure main, create dev (TTY: wizard; optional package.json script alias)
20
20
  start, -S Create workflow branch (TTY: prompts if args missing)
21
21
  finish, -F Merge and close branch (plan + delete by default)
22
- release Quick release from dev (bump + merge main + tag)
22
+ release Quick release from dev (bump or keep version + merge main + tag)
23
23
  sync Update current branch from its base
24
24
  pr Open PR/MR via gh or glab (correct base)
25
25
  switch, -W Switch branch (picker or name)
@@ -62,7 +62,7 @@ Init: --script-alias <name> Add package.json script (e.g. g → "gflows")
62
62
  Start: --force Allow dirty working tree
63
63
  Finish: --no-ff Always create merge commit; -D/--delete, -N/--no-delete;
64
64
  --squash, --preview, --bump; -s/--sign, -T/--no-tag, -M/--tag-message, -m/--message
65
- Release: up <patch|minor|major> (from dev only); -y -p|-P; --preview; -s/--sign
65
+ Release: up <patch|minor|major> | current (from dev only); -y -p|-P; --preview; -s/--sign
66
66
  Sync: --rebase, --force
67
67
  List: -r, --include-remote Include remote-tracking branches
68
68
  Switch: --move | --restore | --clean | --destroy | --cancel
@@ -96,19 +96,22 @@ const TOOLS = [
96
96
  {
97
97
  name: "gflows_release",
98
98
  description:
99
- "Quick release from dev: bump package version, merge into main, tag, sync main→dev. Requires bumpType.",
99
+ "Quick release from dev: optional bump (or keep current version), merge into main, tag, sync main→dev. Pass bumpType or keepCurrent.",
100
100
  inputSchema: {
101
101
  type: "object",
102
102
  properties: {
103
103
  path: { type: "string" },
104
104
  bumpType: {
105
105
  type: "string",
106
- description: "Semver segment to bump: patch, minor, or major",
106
+ description: "Semver segment to bump: patch, minor, or major (omit when keepCurrent)",
107
+ },
108
+ keepCurrent: {
109
+ type: "boolean",
110
+ description: "Tag the package version already on disk (no bump commit)",
107
111
  },
108
112
  push: { type: "boolean" },
109
113
  preview: { type: "boolean" },
110
114
  },
111
- required: ["bumpType"],
112
115
  },
113
116
  },
114
117
  {
@@ -178,8 +181,13 @@ async function runTool(
178
181
  else argv.push("-P");
179
182
  break;
180
183
  case "gflows_release": {
181
- const bumpType = String(args.bumpType ?? "patch");
182
- argv.push("release", "up", bumpType);
184
+ if (args.keepCurrent === true) {
185
+ argv.push("release", "current");
186
+ } else if (typeof args.bumpType === "string" && args.bumpType.trim() !== "") {
187
+ argv.push("release", "up", args.bumpType.trim());
188
+ } else {
189
+ throw new Error("gflows_release: pass bumpType (patch|minor|major) or keepCurrent: true");
190
+ }
183
191
  if (args.preview) argv.push("--preview");
184
192
  if (args.push) argv.push("-p");
185
193
  else argv.push("-P");
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Quick release from the long-lived `dev` branch: bump, merge into main, tag, sync main→dev.
2
+ * Quick release from the long-lived `dev` branch: bump (or keep), merge into main, tag, sync main→dev.
3
3
  * @module commands/release
4
4
  */
5
5
 
@@ -21,9 +21,18 @@ import {
21
21
  import { hint, success } from "../out.js";
22
22
  import { PACKAGE_JSON } from "../packages.js";
23
23
  import type { BumpType, ParsedArgs } from "../types.js";
24
- import { applyVersionToPackages, computeBump, JSR_JSON } from "../version-bump.js";
24
+ import {
25
+ applyVersionToPackages,
26
+ computeBump,
27
+ JSR_JSON,
28
+ readPackageVersion,
29
+ sortedPackageRoots,
30
+ } from "../version-bump.js";
25
31
  import { type FinishContext, runFinishPlan } from "./finish.js";
26
32
 
33
+ /** Interactive choice: keep package version as-is, or bump a semver segment. */
34
+ type ReleaseVersionChoice = "current" | BumpType;
35
+
27
36
  /**
28
37
  * Runs quick release: only valid when HEAD is the configured `dev` branch.
29
38
  */
@@ -66,24 +75,30 @@ export async function run(args: ParsedArgs): Promise<void> {
66
75
  );
67
76
  }
68
77
 
78
+ let keepCurrent = args.keepCurrent === true;
69
79
  let bumpType: BumpType | undefined = args.bumpType;
80
+
70
81
  if (args.bumpDirection === "down") {
71
82
  console.error(
72
- "gflows release: only 'up' is supported (not 'down'). Example: gflows release up patch",
83
+ "gflows release: only 'up' or 'current' is supported (not 'down'). Example: gflows release up patch",
73
84
  );
74
85
  process.exit(EXIT_USER);
75
86
  }
76
87
  if (args.bumpDirection && args.bumpDirection !== "up") {
77
88
  console.error(
78
- "gflows release: expected 'up <patch|minor|major>'. Example: gflows release up patch",
89
+ "gflows release: expected 'up <patch|minor|major>' or 'current'. Example: gflows release up patch",
79
90
  );
80
91
  process.exit(EXIT_USER);
81
92
  }
93
+ if (keepCurrent && (args.bumpDirection || bumpType)) {
94
+ console.error("gflows release: use either 'current' or 'up <patch|minor|major>', not both.");
95
+ process.exit(EXIT_USER);
96
+ }
82
97
 
83
- if (!bumpType) {
98
+ if (!keepCurrent && !bumpType) {
84
99
  if (!isTTY) {
85
100
  console.error(
86
- "gflows release: when not in a TTY, bump type is required. Example: gflows release up patch -y -P",
101
+ "gflows release: when not in a TTY, specify version mode. Examples: gflows release current -y -P or gflows release up patch -y -P",
87
102
  );
88
103
  process.exit(EXIT_USER);
89
104
  }
@@ -96,14 +111,32 @@ export async function run(args: ParsedArgs): Promise<void> {
96
111
  }
97
112
  })();
98
113
  const currentVer = computedPreview?.oldVersion ?? "?";
99
- bumpType = await selectPrompt<"patch" | "minor" | "major">({
100
- message: `Bump version (current ${currentVer})`,
101
- options: [
102
- { label: "patch (x.y.Z)", value: "patch" },
103
- { label: "minor (x.Y.0)", value: "minor" },
104
- { label: "major (X.0.0)", value: "major" },
105
- ],
106
- });
114
+ // `release up` already chose bumping only ask which segment.
115
+ if (args.bumpDirection === "up") {
116
+ bumpType = await selectPrompt<BumpType>({
117
+ message: `Bump version (current ${currentVer})`,
118
+ options: [
119
+ { label: "patch (x.y.Z)", value: "patch" },
120
+ { label: "minor (x.Y.0)", value: "minor" },
121
+ { label: "major (X.0.0)", value: "major" },
122
+ ],
123
+ });
124
+ } else {
125
+ const choice = await selectPrompt<ReleaseVersionChoice>({
126
+ message: `Version for release (current ${currentVer})`,
127
+ options: [
128
+ { label: `keep current (${currentVer})`, value: "current" },
129
+ { label: "bump patch (x.y.Z)", value: "patch" },
130
+ { label: "bump minor (x.Y.0)", value: "minor" },
131
+ { label: "bump major (X.0.0)", value: "major" },
132
+ ],
133
+ });
134
+ if (choice === "current") {
135
+ keepCurrent = true;
136
+ } else {
137
+ bumpType = choice;
138
+ }
139
+ }
107
140
  }
108
141
 
109
142
  let doPush = false;
@@ -123,18 +156,56 @@ export async function run(args: ParsedArgs): Promise<void> {
123
156
  doPush = false;
124
157
  }
125
158
 
126
- const { oldVersion, newVersion, roots } = computeBump(repoRoot, "up", bumpType);
159
+ let oldVersion: string;
160
+ let newVersion: string;
161
+ let roots: string[];
162
+
163
+ if (keepCurrent) {
164
+ roots = sortedPackageRoots(repoRoot);
165
+ if (roots.length === 0) {
166
+ console.error(
167
+ `gflows release: no package.json found under ${repoRoot}. Run from project root or use -C <dir>.`,
168
+ );
169
+ process.exit(EXIT_USER);
170
+ }
171
+ const primaryRoot = roots[0];
172
+ if (primaryRoot === undefined) {
173
+ console.error(
174
+ `gflows release: no package.json found under ${repoRoot}. Run from project root or use -C <dir>.`,
175
+ );
176
+ process.exit(EXIT_USER);
177
+ }
178
+ oldVersion = readPackageVersion(primaryRoot).raw;
179
+ newVersion = oldVersion;
180
+ } else {
181
+ if (!bumpType) {
182
+ console.error(
183
+ "gflows release: expected 'up <patch|minor|major>' or 'current'. Example: gflows release up patch",
184
+ );
185
+ process.exit(EXIT_USER);
186
+ }
187
+ ({ oldVersion, newVersion, roots } = computeBump(repoRoot, "up", bumpType));
188
+ }
189
+
127
190
  const tagName = normalizeTagVersion(newVersion);
128
191
 
129
192
  if (await tagExists(repoRoot, tagName, opts)) {
130
193
  console.error(`gflows release: tag '${tagName}' already exists.`);
131
- hint("Use a different bump (minor/major), or delete the tag if you intend to recreate it.");
194
+ hint(
195
+ keepCurrent
196
+ ? "Bump the version first, or delete the tag if you intend to recreate it."
197
+ : "Use a different bump (minor/major), or delete the tag if you intend to recreate it.",
198
+ );
132
199
  process.exit(2);
133
200
  }
134
201
 
135
202
  console.error("gflows release plan:");
136
203
  console.error(` from: ${config.dev}`);
137
- console.error(` bump: ${oldVersion} → ${newVersion}`);
204
+ if (keepCurrent) {
205
+ console.error(` version: ${newVersion} (keep current, no bump)`);
206
+ } else {
207
+ console.error(` bump: ${oldVersion} → ${newVersion}`);
208
+ }
138
209
  console.error(` merge: → ${config.main}, then ${config.main} → ${config.dev}`);
139
210
  console.error(` tag: ${tagName}`);
140
211
  console.error(` push: ${doPush ? "yes" : "no"}`);
@@ -159,7 +230,7 @@ export async function run(args: ParsedArgs): Promise<void> {
159
230
  process.exit(EXIT_USER);
160
231
  }
161
232
 
162
- if (!opts.dryRun) {
233
+ if (!keepCurrent && !opts.dryRun) {
163
234
  applyVersionToPackages(repoRoot, roots, newVersion);
164
235
  for (const dir of roots) {
165
236
  await runGit(["add", "--", join(dir, PACKAGE_JSON)], {
@@ -57,7 +57,7 @@ export async function run(_args: ParsedArgs): Promise<void> {
57
57
  "-m/--message",
58
58
  ],
59
59
  release: [
60
- "up patch|minor|major",
60
+ "up patch|minor|major | current",
61
61
  "-y",
62
62
  "-p/--push",
63
63
  "-P/--no-push",
@@ -74,7 +74,7 @@ export async function run(_args: ParsedArgs): Promise<void> {
74
74
  agentNotes: [
75
75
  "Always pass explicit flags in non-TTY (never assume interactive hub).",
76
76
  "Prefer -y to accept finish plan (delete defaults on); pass -P or -p for push.",
77
- "Quick release from dev: gflows release up patch -y -p (or -P).",
77
+ "Quick release from dev: gflows release up patch -y -p (or -P); or gflows release current -y -p after a manual bump.",
78
78
  "On conflict: gflows continue | gflows abort | gflows undo.",
79
79
  "Use gflows schema and AGENTS.md as source of truth.",
80
80
  ],
@@ -87,7 +87,10 @@ function commandMeta(command: string): { summary: string; interactiveOk: boolean
87
87
  init: { summary: "Ensure main; create dev", interactiveOk: true },
88
88
  start: { summary: "Create workflow branch", interactiveOk: true },
89
89
  finish: { summary: "Merge and close workflow branch", interactiveOk: true },
90
- release: { summary: "Quick release from dev (bump, merge main, tag)", interactiveOk: true },
90
+ release: {
91
+ summary: "Quick release from dev (bump or keep version, merge main, tag)",
92
+ interactiveOk: true,
93
+ },
91
94
  switch: { summary: "Switch workflow branch", interactiveOk: true },
92
95
  delete: { summary: "Delete local workflow branches", interactiveOk: true },
93
96
  list: { summary: "List workflow branches", interactiveOk: false },
@@ -127,16 +127,21 @@ async function runHubAction(cwd: string, action: string): Promise<void> {
127
127
  return;
128
128
  }
129
129
  if (action === "release") {
130
- const bumpType = await selectPrompt<"patch" | "minor" | "major">({
131
- message: "Bump version",
130
+ const choice = await selectPrompt<"current" | "patch" | "minor" | "major">({
131
+ message: "Version for release",
132
132
  options: [
133
- { label: "patch (x.y.Z)", value: "patch" },
134
- { label: "minor (x.Y.0)", value: "minor" },
135
- { label: "major (X.0.0)", value: "major" },
133
+ { label: "keep current", value: "current" },
134
+ { label: "bump patch (x.y.Z)", value: "patch" },
135
+ { label: "bump minor (x.Y.0)", value: "minor" },
136
+ { label: "bump major (X.0.0)", value: "major" },
136
137
  ],
137
138
  });
138
139
  const push = await confirmPrompt({ message: "Push after release?", initialValue: false });
139
- await dispatch(cwd, ["release", "up", bumpType, "-y", push ? "-p" : "-P"]);
140
+ const releaseArgv =
141
+ choice === "current"
142
+ ? (["release", "current", "-y", push ? "-p" : "-P"] as string[])
143
+ : (["release", "up", choice, "-y", push ? "-p" : "-P"] as string[]);
144
+ await dispatch(cwd, releaseArgv);
140
145
  return;
141
146
  }
142
147
  if (action === "sync") {
package/src/parse.ts CHANGED
@@ -236,7 +236,9 @@ function resolveName(
236
236
  }
237
237
  if (command === "bump" || command === "release") {
238
238
  const dir = positionals[skip];
239
- if (dir === "up" || dir === "down") return dir;
239
+ if (dir === "up" || dir === "down" || (command === "release" && dir === "current")) {
240
+ return dir;
241
+ }
240
242
  return undefined;
241
243
  }
242
244
  if (command === "switch" || command === "pr" || command === "sync") {
@@ -248,11 +250,15 @@ function resolveName(
248
250
  function resolveBump(positionals: string[]): {
249
251
  direction?: "up" | "down";
250
252
  type?: "patch" | "minor" | "major";
253
+ keepCurrent?: boolean;
251
254
  } {
252
255
  // Skip leading command when present; with -U, positionals start at up/down
253
256
  const skip = positionals[0] === "bump" || positionals[0] === "release" ? 1 : 0;
254
257
  const a = positionals[skip];
255
258
  const b = positionals[skip + 1];
259
+ if (positionals[0] === "release" && a === "current") {
260
+ return { keepCurrent: true };
261
+ }
256
262
  const direction = a === "up" || a === "down" ? a : undefined;
257
263
  const type = b === "patch" || b === "minor" || b === "major" ? b : undefined;
258
264
  return { direction, type };
@@ -297,6 +303,7 @@ function emptyArgs(cwd: string, pathStr: string | undefined): ParsedArgs {
297
303
  squash: false,
298
304
  preview: false,
299
305
  bumpOnFinish: false,
306
+ keepCurrent: false,
300
307
  includeRemote: false,
301
308
  json: false,
302
309
  rebase: false,
@@ -336,10 +343,13 @@ export function parse(
336
343
 
337
344
  const type = resolveType(command, positionals, v);
338
345
  const name = resolveName(command, positionals, v);
339
- const { direction: bumpDirection, type: bumpType } =
346
+ const bumpResolved =
340
347
  command === "bump" || command === "release"
341
348
  ? resolveBump(positionals)
342
- : { direction: undefined, type: undefined };
349
+ : { direction: undefined, type: undefined, keepCurrent: undefined };
350
+ const bumpDirection = bumpResolved.direction;
351
+ const bumpType = bumpResolved.type;
352
+ const keepCurrent = bumpResolved.keepCurrent === true;
343
353
  const configArgs = command === "config" ? resolveConfigArgs(positionals) : {};
344
354
 
345
355
  const branchNames =
@@ -395,6 +405,7 @@ export function parse(
395
405
  branchNames,
396
406
  bumpDirection,
397
407
  bumpType,
408
+ keepCurrent,
398
409
  configAction: configArgs.action,
399
410
  configKey: configArgs.key,
400
411
  configValue: configArgs.value,
package/src/tui/flows.tsx CHANGED
@@ -135,21 +135,22 @@ export function ReleaseFlow({
135
135
  onCancel: () => void;
136
136
  }): React.ReactElement {
137
137
  const [step, setStep] = useState<"type" | "push">("type");
138
- const [bumpType, setBumpType] = useState<"patch" | "minor" | "major">("patch");
138
+ const [choice, setChoice] = useState<"current" | "patch" | "minor" | "major">("current");
139
139
 
140
140
  if (step === "type") {
141
141
  return (
142
142
  <WizardFrame title="Quick release from dev">
143
- <InkSelect<"patch" | "minor" | "major">
144
- message="Bump version"
143
+ <InkSelect<"current" | "patch" | "minor" | "major">
144
+ message="Version for release"
145
145
  options={[
146
- { value: "patch", label: "patch (x.y.Z)" },
147
- { value: "minor", label: "minor (x.Y.0)" },
148
- { value: "major", label: "major (X.0.0)" },
146
+ { value: "current", label: "keep current" },
147
+ { value: "patch", label: "bump patch (x.y.Z)" },
148
+ { value: "minor", label: "bump minor (x.Y.0)" },
149
+ { value: "major", label: "bump major (X.0.0)" },
149
150
  ]}
150
151
  onCancel={onCancel}
151
152
  onSubmit={(t) => {
152
- setBumpType(t);
153
+ setChoice(t);
153
154
  setStep("push");
154
155
  }}
155
156
  />
@@ -157,14 +158,20 @@ export function ReleaseFlow({
157
158
  );
158
159
  }
159
160
 
161
+ const title = choice === "current" ? "Release · keep current" : `Release · up ${choice}`;
162
+
160
163
  return (
161
- <WizardFrame title={`Release · up ${bumpType}`}>
164
+ <WizardFrame title={title}>
162
165
  <InkConfirm
163
166
  message="Push after release?"
164
167
  initialValue={false}
165
168
  onCancel={onCancel}
166
169
  onSubmit={(push) => {
167
- onDone(["release", "up", bumpType, "-y", push ? "-p" : "-P"]);
170
+ onDone(
171
+ choice === "current"
172
+ ? ["release", "current", "-y", push ? "-p" : "-P"]
173
+ : ["release", "up", choice, "-y", push ? "-p" : "-P"],
174
+ );
168
175
  }}
169
176
  />
170
177
  </WizardFrame>
package/src/types.ts CHANGED
@@ -134,6 +134,11 @@ export interface ParsedArgs {
134
134
  bumpDirection?: BumpDirection;
135
135
  /** Bump type (patch | minor | major). */
136
136
  bumpType?: BumpType;
137
+ /**
138
+ * Quick release: tag the package version already on disk (no bump commit).
139
+ * From `gflows release current`.
140
+ */
141
+ keepCurrent?: boolean;
137
142
  /** Config get/set action. */
138
143
  configAction?: ConfigAction;
139
144
  /** Config key (main, dev, remote, or prefixes.<type>). */