gflows 0.1.12 → 0.1.14

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
@@ -1,4 +1,4 @@
1
- # gflows
1
+ # gFlows
2
2
 
3
3
  A lightweight CLI for consistent Git branching workflows: long-lived **main** (production) and **dev** (integration), plus short-lived workflow branches with clear merge targets. Built for [Bun](https://bun.sh) and TypeScript; **scriptable** and **safe by default**—no history rewriting, predictable exit codes, and optional interactive pickers only when running in a TTY.
4
4
 
@@ -8,16 +8,31 @@ A lightweight CLI for consistent Git branching workflows: long-lived **main** (p
8
8
 
9
9
  ## Table of contents
10
10
 
11
+ **Get started**
12
+
11
13
  - [Prerequisites](#prerequisites)
12
14
  - [Installation](#installation)
13
- - [Concepts](#concepts)
14
15
  - [Quick start](#quick-start)
15
- - [Command reference](#command-reference)
16
+
17
+ **Understand**
18
+
19
+ - [Concepts](#concepts)
20
+ - [Flowcharts](#flowcharts)
16
21
  - [Branch types in detail](#branch-types-in-detail)
22
+
23
+ **Reference**
24
+
25
+ - [Command reference](#command-reference)
26
+
27
+ **Configure & operate**
28
+
17
29
  - [Configuration](#configuration)
18
30
  - [Scripting and CI](#scripting-and-ci)
19
31
  - [Exit codes](#exit-codes)
20
32
  - [Troubleshooting](#troubleshooting)
33
+
34
+ **More**
35
+
21
36
  - [Shell completion](#shell-completion)
22
37
  - [Publishing (maintainers)](#publishing-maintainers)
23
38
  - [License](#license)
@@ -26,8 +41,8 @@ A lightweight CLI for consistent Git branching workflows: long-lived **main** (p
26
41
 
27
42
  ## Prerequisites
28
43
 
29
- - **Bun** ≥ 1.0 (recommended). The CLI runs TypeScript directly; no separate build step.
30
- - **Git** for all repository operations.
44
+ - **Bun** ≥ 1.0 (recommended). The CLI runs TypeScript directly.
45
+ - **Git** for repository operations.
31
46
 
32
47
  Check versions:
33
48
 
@@ -40,120 +55,204 @@ git --version
40
55
 
41
56
  ## Installation
42
57
 
43
- **As a dev dependency (recommended):**
58
+ **Dev dependency (recommended):** `bun add --dev gflows` or `npm install --save-dev gflows`.
59
+ **JSR:** `npx jsr add --dev @alialnaghmoush/gflows` or `deno add --dev jsr:@alialnaghmoush/gflows`.
44
60
 
45
- **npm**
61
+ Run with `bunx gflows ...` or `npx gflows ...`. [npm](https://www.npmjs.com/package/gflows) · [JSR](https://jsr.io/@alialnaghmoush/gflows)
46
62
 
47
- ```bash
48
- npm install --save-dev gflows
49
- ```
63
+ **Global:** `bun add --global gflows` or `npm install --global gflows`
50
64
 
51
- **Bun**
65
+ ---
52
66
 
53
- ```bash
54
- bun add --dev gflows
55
- ```
67
+ ## Quick start
56
68
 
57
- **JSR (npm / npx)**
69
+ **1. One-time setup** — In your repo, ensure `main` exists and create `dev`:
58
70
 
59
71
  ```bash
60
- npx jsr add --dev @alialnaghmoush/gflows
72
+ bun gflows init
61
73
  ```
62
74
 
63
- **JSR (Bun / bunx)**
75
+ Use `--no-push` to skip push, `--dry-run` to preview. Pass `--main`, `--dev`, `--remote` to persist to `.gflows.json`.
64
76
 
65
77
  ```bash
66
- bunx jsr add --dev @alialnaghmoush/gflows
78
+ bun gflows init --main main --dev develop --remote origin
67
79
  ```
68
80
 
69
- **JSR (Deno)**
81
+ **2. Daily development** (feature → dev):
70
82
 
71
83
  ```bash
72
- deno add --dev jsr:@alialnaghmoush/gflows
84
+ bun gflows start feature add-login
85
+ # ... code, commit ...
86
+ bun gflows finish feature
87
+ bun gflows finish feature --push
88
+ bun gflows finish feature --push -D
73
89
  ```
74
90
 
75
- Available on:
76
-
77
- - [npm: gflows](https://www.npmjs.com/package/gflows)
78
- - [JSR: @alialnaghmoush/gflows](https://jsr.io/@alialnaghmoush/gflows)
79
-
80
- If installed as a local dev dependency, run via your package runner:
81
-
82
- - Bun: `bunx gflows ...` (or `bun gflows ...` when available in your Bun setup)
83
- - npm: `npx gflows ...`
84
-
85
- **Global install (optional):**
86
-
87
- **npm**
91
+ **3. Release** (dev → main, then tag):
88
92
 
89
93
  ```bash
90
- npm install --global gflows
94
+ bun gflows bump up minor
95
+ bun gflows start release v1.3.0
96
+ # ... update CHANGELOG, commit ...
97
+ bun gflows finish release --push
91
98
  ```
92
99
 
93
- **Bun**
100
+ **4. Hotfix** (main → fix → main + dev):
94
101
 
95
102
  ```bash
96
- bun add --global gflows
103
+ bun gflows start hotfix v1.3.1
104
+ # ... fix, commit ...
105
+ bun gflows finish hotfix --push
97
106
  ```
98
107
 
99
108
  ---
100
109
 
101
110
  ## Concepts
102
111
 
103
- - **main** — Long-lived production branch. Default name: `main`. Only release and hotfix branches merge here.
104
- - **dev** — Long-lived integration branch. Default name: `dev`. Feature, bugfix, chore, and spike branches merge here. Created by `gflows init` from `main`.
105
- - **Workflow branches** — Short-lived branches with a type prefix (e.g. `feature/`, `bugfix/`, `release/`). Each type has a **base** branch and **merge target(s)**. gflows never rewrites history (no rebase by default).
106
- - **Merge targets** Where `gflows finish` merges:
107
- - **feature / chore / spike** → `dev` only.
108
- - **bugfix** → `dev` (or `main` if the bugfix was started from main with `-o main`).
109
- - **release** → `main` first, then `main` is merged into `dev`; a tag is created.
110
- - **hotfix** → `main` first, then `main` is merged into `dev`; a tag is created.
112
+ - **main** — Production branch. Only release and hotfix merge here.
113
+ - **dev** — Integration branch. Feature, bugfix, chore, spike merge here. Created by `gflows init` from main.
114
+ - **Workflow branches** — Short-lived branches with a type prefix; each has a base and merge target(s). No history rewriting.
115
+ - **Merge targets:** feature/chore/spike dev; bugfix → dev (or main with `-o main`); release/hotfix → main then dev + tag.
111
116
 
112
- You can override branch names and prefixes via [configuration](#configuration).
117
+ Override names and prefixes via [configuration](#configuration).
113
118
 
114
119
  ---
115
120
 
116
- ## Quick start
121
+ ## Flowcharts
117
122
 
118
- **1. One-time setup** In your repo, ensure `main` exists and create `dev`:
123
+ ### Lifecycle (init start finish)
119
124
 
120
- ```bash
121
- gflows init
125
+ ```mermaid
126
+ flowchart LR
127
+ subgraph setup["One-time setup"]
128
+ A[main exists] --> B["bun gflows init"]
129
+ B --> C[dev created]
130
+ C --> D[optional: push dev]
131
+ end
132
+ subgraph daily["Daily workflow"]
133
+ E["bun gflows start<br/>type name"] --> F[work & commit]
134
+ F --> G["bun gflows finish<br/>type"]
135
+ G --> H{type?}
136
+ H -->|feature/bugfix/chore/spike| I[merged to dev]
137
+ H -->|release/hotfix| J[merged to main → dev + tag]
138
+ end
139
+ setup --> daily
122
140
  ```
123
141
 
124
- Optional: use `--push` to push `dev` to the remote, or `--dry-run` to preview. To use different branch or remote names, pass `--main`, `--dev`, and `--remote`; those values are written to `.gflows.json` for future runs.
142
+ ### init
125
143
 
126
- ```bash
127
- gflows init --push # create dev, then push to origin
128
- gflows init --main main --dev develop --remote origin # custom names, persisted to .gflows.json
144
+ ```mermaid
145
+ flowchart TD
146
+ Start([bun gflows init]) --> Repo{In git repo?}
147
+ Repo -->|no| ErrRepo[Exit: Not a repo]
148
+ Repo -->|yes| MainExists{main branch exists?}
149
+ MainExists -->|no| ErrMain[Exit: Create main first]
150
+ MainExists -->|yes| DevExists{dev branch exists?}
151
+ DevExists -->|yes| DoneNoOp[Done: nothing to do]
152
+ DevExists -->|no| CreateDev[Create dev from main]
153
+ CreateDev --> Push{--no-push?}
154
+ Push -->|no| DoPush[Push dev to remote]
155
+ Push -->|yes| SkipPush[Skip push]
156
+ DoPush --> Done[Done]
157
+ SkipPush --> Done
158
+ DoneNoOp --> Done
129
159
  ```
130
160
 
131
- **2. Daily development** (feature → dev):
161
+ ### start
132
162
 
133
- ```bash
134
- gflows start feature add-login
135
- # ... code, commit ...
136
- gflows finish feature # merge into dev
137
- gflows finish feature --push # merge and push dev
138
- gflows finish feature --push -D # merge, push, and delete local branch
163
+ ```mermaid
164
+ flowchart TD
165
+ Start([bun gflows start type name]) --> Repo{In git repo?}
166
+ Repo -->|no| ErrRepo[Exit: Not a repo]
167
+ Repo -->|yes| Clean{Tree clean or --force?}
168
+ Clean -->|no| ErrDirty[Exit: Uncommitted changes]
169
+ Clean -->|yes| Base[Resolve base branch for type]
170
+ Base --> BaseExists{Base exists locally or remote?}
171
+ BaseExists -->|no| ErrBase[Exit: Base not found]
172
+ BaseExists -->|yes| Create[Create workflow branch from base]
173
+ Create --> PushOpt{--push?}
174
+ PushOpt -->|yes| Push[Push new branch to remote]
175
+ PushOpt -->|no| Done[Done]
176
+ Push --> Done
177
+ ```
178
+
179
+ ### finish (merge targets by branch type)
180
+
181
+ ```mermaid
182
+ flowchart TD
183
+ Start([bun gflows finish type]) --> Resolve[Resolve branch to finish]
184
+ Resolve --> T{type}
185
+ T -->|feature / chore / spike| M1[Merge → dev]
186
+ T -->|bugfix from dev| M1
187
+ T -->|bugfix from main| M2[Merge → main]
188
+ T -->|release| M3[Merge → main]
189
+ M3 --> M3b[Merge main → dev]
190
+ M3b --> Tag1[Create tag]
191
+ T -->|hotfix| M4[Merge → main]
192
+ M4 --> M4b[Merge main → dev]
193
+ M4b --> Tag2[Create tag]
194
+ M2 --> M2b[Merge main → dev]
195
+ M1 --> Opt[Optional: delete branch, push]
196
+ M2b --> Opt
197
+ Tag1 --> Opt
198
+ Tag2 --> Opt
199
+ Opt --> Done([Done])
200
+ ```
201
+
202
+ ### Branch types and merge targets
203
+
204
+ ```mermaid
205
+ flowchart TB
206
+ subgraph longlived["Long-lived branches"]
207
+ main[main]
208
+ dev[dev]
209
+ end
210
+ subgraph workflow["Workflow branches"]
211
+ feature[feature/...]
212
+ bugfix[bugfix/...]
213
+ chore[chore/...]
214
+ release[release/...]
215
+ hotfix[hotfix/...]
216
+ spike[spike/...]
217
+ end
218
+ feature --> dev
219
+ chore --> dev
220
+ spike --> dev
221
+ bugfix --> dev
222
+ bugfix -.->|"-o main"| main
223
+ release --> main
224
+ main --> dev
225
+ release -.-> dev
226
+ hotfix --> main
227
+ main --> dev
228
+ hotfix -.-> dev
229
+ ```
230
+
231
+ ### bump (version)
232
+
233
+ ```mermaid
234
+ flowchart LR
235
+ Start([bun gflows bump direction type]) --> Discover[Discover package.json, jsr.json]
236
+ Discover --> Read[Read version from primary root]
237
+ Read --> Calc[Compute new version]
238
+ Calc --> Write[Write to all roots]
239
+ Write --> Done([Done])
139
240
  ```
140
241
 
141
- **3. Release** (dev → main, then tag):
242
+ ---
142
243
 
143
- ```bash
144
- gflows bump up minor # e.g. 1.2.3 → 1.3.0
145
- gflows start release v1.3.0
146
- # ... update CHANGELOG, commit ...
147
- gflows finish release --push # merge to main, then dev; tag v1.3.0; push
148
- ```
244
+ ## Branch types in detail
149
245
 
150
- **4. Hotfix** (main fix main + dev):
246
+ | Type | Short | Base (default) | With `-o main` | Merge target(s) | Tag |
247
+ | ------- | ----- | -------------- | -------------- | -------------------------- | --- |
248
+ | feature | `-f` | dev | — | dev | no |
249
+ | bugfix | `-b` | dev | main | dev (or main if from main) | no |
250
+ | chore | `-c` | dev | — | dev | no |
251
+ | release | `-r` | dev | — | main, then dev | yes |
252
+ | hotfix | `-x` | main | — | main, then dev | yes |
253
+ | spike | `-e` | dev | — | dev | no |
151
254
 
152
- ```bash
153
- gflows start hotfix v1.3.1
154
- # ... fix, commit ...
155
- gflows finish hotfix --push # merge to main, then dev; tag v1.3.1; push
156
- ```
255
+ Release and hotfix names must be a version (`vX.Y.Z` or `X.Y.Z`). Branch names use default prefixes (e.g. `feature/add-login`); override in [configuration](#configuration). Invalid names (e.g. `..`, `*`, spaces) → exit 1.
157
256
 
158
257
  ---
159
258
 
@@ -161,7 +260,6 @@ gflows finish hotfix --push # merge to main, then dev; tag v1.3.1;
161
260
 
162
261
  ### Summary table
163
262
 
164
-
165
263
  | Command | Short | Description |
166
264
  | ------------ | ----- | ------------------------------------------------------------------------- |
167
265
  | `init` | `-I` | Ensure main exists; create dev from main. |
@@ -177,309 +275,259 @@ gflows finish hotfix --push # merge to main, then dev; tag v1.3.1;
177
275
  | `version` | `-V` | Show version. |
178
276
 
179
277
 
180
- **Branch types (for start/finish/list):** `feature` (`-f`), `bugfix` (`-b`), `chore` (`-c`), `release` (`-r`), `hotfix` (`-x`), `spike` (`-e`).
278
+ **Common flags:**
181
279
 
182
- **Common flags** (used by multiple commands):
183
280
 
184
- | Flag | Short | Description |
185
- |------|-------|-------------|
186
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
187
- | `--dry-run` | `-d` | Log intended actions only; no writes. |
188
- | `--verbose` | `-v` | Verbose output. |
189
- | `--quiet` | `-q` | Minimal output. |
190
- | `--push` | `-p` | Push after init/start/finish. |
191
- | `--no-push` | `-P` | Do not push. |
192
- | `--main <name>` | — | Main branch override. |
193
- | `--dev <name>` | — | Dev branch override. |
194
- | `--remote <name>` | `-R` | Remote for push. |
195
- | `--from <branch>` | `-o` | Base branch override (start). |
196
- | `--branch <name>` | `-B` | Branch name (finish). |
197
- | `--yes` | `-y` | Skip confirmations. |
281
+ | Flag | Short | Description |
282
+ | ----------------- | ----- | ------------------------------------- |
283
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
284
+ | `--dry-run` | `-d` | Log intended actions only; no writes. |
285
+ | `--verbose` | `-v` | Verbose output. |
286
+ | `--quiet` | `-q` | Minimal output. |
287
+ | `--push` | `-p` | Push after init/start/finish. |
288
+ | `--no-push` | `-P` | Do not push. |
289
+ | `--main <name>` | — | Main branch override. |
290
+ | `--dev <name>` | — | Dev branch override. |
291
+ | `--remote <name>` | `-R` | Remote for push. |
292
+ | `--from <branch>` | `-o` | Base branch override (start). |
293
+ | `--branch <name>` | `-B` | Branch name (finish). |
294
+ | `--yes` | `-y` | Skip confirmations. |
295
+
198
296
 
199
297
  ---
200
298
 
201
299
  ### init
202
300
 
203
- Ensures the **main** branch exists (exits with error if not). Creates **dev** from main if it does not exist; does nothing if dev already exists. Does not rewrite or force-push.
204
-
205
- You can set and persist config with `**--main`**, `**--dev`**, and `**-R`/`--remote**`. Any of these flags cause init to write or update `.gflows.json` with the given values (after a successful init; skipped with `--dry-run`).
301
+ Ensures main exists; creates dev from main if missing. Use `--main`, `--dev`, `-R` to persist to `.gflows.json`.
206
302
 
207
303
  **Examples:**
208
304
 
209
305
  ```bash
210
- gflows init
211
- gflows init --push # push dev to remote after creating
212
- gflows init --main main --dev develop --remote origin # create dev branch "develop", persist to .gflows.json
213
- gflows init -C ../other-repo # run in another directory
214
- gflows init --dry-run # log intended actions only
306
+ bun gflows init
307
+ bun gflows init --main main --dev develop --remote origin
308
+ bun gflows init -C ../other-repo --dry-run
215
309
  ```
216
310
 
217
311
  **Flags:**
218
312
 
219
- | Flag | Short | Description |
220
- |------|-------|-------------|
221
- | `--push` | `-p` | Push dev to remote after creating. |
222
- | `--main <name>` | | Main branch name (persisted to `.gflows.json` when provided). |
223
- | `--dev <name>` | — | Dev branch name (persisted to `.gflows.json` when provided). |
224
- | `--remote <name>` | `-R` | Remote name (persisted to `.gflows.json` when provided). |
225
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
226
- | `--dry-run` | `-d` | Log intended actions only; no writes. |
227
- | `--verbose` | `-v` | Verbose output. |
228
- | `--quiet` | `-q` | Minimal output. |
313
+
314
+ | Flag | Short | Description |
315
+ | ----------------- | ----- | ------------------------------------------------------------- |
316
+ | `--push` | `-p` | Push dev to remote after creating (default). |
317
+ | `--main <name>` | — | Main branch name (persisted to `.gflows.json` when provided). |
318
+ | `--dev <name>` | | Dev branch name (persisted to `.gflows.json` when provided). |
319
+ | `--remote <name>` | `-R` | Remote name (persisted to `.gflows.json` when provided). |
320
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
321
+ | `--dry-run` | `-d` | Log intended actions only; no writes. |
322
+ | `--verbose` | `-v` | Verbose output. |
323
+ | `--quiet` | `-q` | Minimal output. |
324
+
229
325
 
230
326
  ---
231
327
 
232
328
  ### start
233
329
 
234
- Creates a new workflow branch from the correct base. **Requires** type and name (e.g. `start feature my-feat`). For **release** and **hotfix**, the name must be a version: `vX.Y.Z` or `X.Y.Z` (e.g. `v1.2.0`).
235
-
236
- **Pre-checks:** Repository is Git; not detached HEAD; no rebase/merge in progress; working tree clean (unless `--force`); base branch exists (local or after fetch).
330
+ Creates a workflow branch from the correct base. Requires type + name; release/hotfix name must be a version. Pre-checks: git repo, clean tree (or `--force`), base exists.
237
331
 
238
332
  **Examples:**
239
333
 
240
334
  ```bash
241
- gflows start feature auth-refactor
242
- gflows start -f auth-refactor # same (short type)
243
- gflows start bugfix fix-login --from main # bugfix from main instead of dev
244
- gflows start release v2.0.0
245
- gflows start hotfix 1.2.1 # "v" is optional for version
246
- gflows start feature wip --force # allow uncommitted changes
247
- gflows start feature api-v2 --push # create branch and push to remote
248
- gflows start chore deps-update -C ./backend # run in subdirectory
335
+ bun gflows start feature auth-refactor
336
+ bun gflows start bugfix fix-login --from main
337
+ bun gflows start release v2.0.0
338
+ bun gflows start hotfix 1.2.1
339
+ bun gflows start feature wip --force --push
249
340
  ```
250
341
 
251
342
  **Flags:**
252
343
 
253
- | Flag | Short | Description |
254
- |------|-------|-------------|
255
- | `--force` | | Allow dirty working tree. |
256
- | `--push` | `-p` | Push new branch to remote after creating. |
257
- | `--from <branch>` | `-o` | Base branch override (e.g. `-o main` for bugfix). |
258
- | `--remote <name>` | `-R` | Remote for push. |
259
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
260
- | `--dry-run` | `-d` | Log intended actions only; no writes. |
261
- | `--verbose` | `-v` | Verbose output. |
262
- | `--quiet` | `-q` | Minimal output. |
344
+
345
+ | Flag | Short | Description |
346
+ | ----------------- | ----- | ------------------------------------------------- |
347
+ | `--force` | | Allow dirty working tree. |
348
+ | `--push` | `-p` | Push new branch to remote after creating. |
349
+ | `--from <branch>` | `-o` | Base branch override (e.g. `-o main` for bugfix). |
350
+ | `--remote <name>` | `-R` | Remote for push. |
351
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
352
+ | `--dry-run` | `-d` | Log intended actions only; no writes. |
353
+ | `--verbose` | `-v` | Verbose output. |
354
+ | `--quiet` | `-q` | Minimal output. |
355
+
263
356
 
264
357
  ---
265
358
 
266
359
  ### finish
267
360
 
268
- Merges the current workflow branch (or the one given with `-B`) into its merge target(s). For **release** and **hotfix**, merges into main first, then merges main into dev and creates a tag. Uses normal merge; use `--no-ff` to always create a merge commit. On **merge conflict**, gflows exits with a clear message and does not complete the merge—you resolve conflicts manually, then run `git merge --continue` or re-run `gflows finish` as needed.
269
-
270
- **Pre-checks:** Not detached HEAD; no rebase/merge in progress; current branch (or `-B` target) is not main or dev; for release/hotfix, tag does not already exist.
361
+ Merges the branch (current or `-B`) into its target(s). Release/hotfix: merge to main, then main dev, create tag. Use `--no-ff` for a merge commit. On conflict, resolve then `git merge --continue` or re-run finish.
271
362
 
272
363
  **Examples:**
273
364
 
274
365
  ```bash
275
- gflows finish feature # merge current branch (feature/xyz) into dev
276
- gflows finish feature -B feature/auth # finish branch feature/auth
277
- gflows finish feature --no-ff # always create a merge commit
278
- gflows finish feature --push -D # merge, push, delete local branch
279
- gflows finish release --push # merge to main, then dev; tag; push
280
- gflows finish hotfix -s # sign the tag (GPG)
281
- gflows finish hotfix -T # no tag (e.g. abandon hotfix as release)
282
- gflows finish -y # skip "Delete branch after finish?" prompt (use default)
366
+ bun gflows finish feature
367
+ bun gflows finish feature -B feature/auth --push -D
368
+ bun gflows finish release --push
369
+ bun gflows finish hotfix -s -T -y
283
370
  ```
284
371
 
285
- **Branch resolution:** If you omit the branch name, gflows uses the current branch. With `-B` and no value in a TTY, it shows a picker of workflow branches. Without a TTY, you must pass the branch name explicitly.
286
-
287
372
  **Flags:**
288
373
 
289
- | Flag | Short | Description |
290
- |------|-------|-------------|
291
- | `--branch <name>` | `-B` | Branch to finish (current branch if omitted; picker in TTY when `-B` with no value). |
292
- | `--no-ff` | | Always create a merge commit. |
293
- | `--delete` | `-D` | Delete branch after finish. |
294
- | `--no-delete` | `-N` | Do not delete branch after finish. |
295
- | `--push` | `-p` | Push after merge (finish prompts "Do you want to push?" when neither `-p` nor `-P`). |
296
- | `--no-push` | `-P` | Do not push. |
297
- | `--sign` | `-s` | Sign the tag (release/hotfix; GPG). |
298
- | `--no-tag` | `-T` | Do not create tag (release/hotfix). |
299
- | `--tag-message <msg>` | `-M` | Tag message. |
300
- | `--message <msg>` | `-m` | Merge message. |
301
- | `--yes` | `-y` | Skip confirmations (e.g. "Delete branch after finish?"). |
302
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
303
- | `--dry-run` | `-d` | Log intended actions only; no writes. |
304
- | `--verbose` | `-v` | Verbose output. |
305
- | `--quiet` | `-q` | Minimal output. |
374
+
375
+ | Flag | Short | Description |
376
+ | --------------------- | ----- | ------------------------------------------------------------------------------------ |
377
+ | `--branch <name>` | `-B` | Branch to finish (current branch if omitted; picker in TTY when `-B` with no value). |
378
+ | `--no-ff` | | Always create a merge commit. |
379
+ | `--delete` | `-D` | Delete branch after finish. |
380
+ | `--no-delete` | `-N` | Do not delete branch after finish. |
381
+ | `--push` | `-p` | Push after merge (finish prompts "Do you want to push?" when neither `-p` nor `-P`). |
382
+ | `--no-push` | `-P` | Do not push. |
383
+ | `--sign` | `-s` | Sign the tag (release/hotfix; GPG). |
384
+ | `--no-tag` | `-T` | Do not create tag (release/hotfix). |
385
+ | `--tag-message <msg>` | `-M` | Tag message. |
386
+ | `--message <msg>` | `-m` | Merge message. |
387
+ | `--yes` | `-y` | Skip confirmations (e.g. "Delete branch after finish?"). |
388
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
389
+ | `--dry-run` | `-d` | Log intended actions only; no writes. |
390
+ | `--verbose` | `-v` | Verbose output. |
391
+ | `--quiet` | `-q` | Minimal output. |
392
+
306
393
 
307
394
  ---
308
395
 
309
396
  ### switch
310
397
 
311
- Switches to a workflow branch. With a **TTY** and no branch name, shows an interactive **picker** of local workflow branches. Otherwise you must pass the branch name as a positional.
398
+ Switch to a workflow branch. With TTY and no name, shows a picker; otherwise pass branch name.
312
399
 
313
400
  **Examples:**
314
401
 
315
402
  ```bash
316
- gflows switch # picker (if TTY)
317
- gflows switch feature/auth-refactor
318
- gflows -W feature/auth-refactor # same with short command
403
+ bun gflows switch
404
+ bun gflows switch feature/auth-refactor
405
+ bun gflows -W feature/auth-refactor
319
406
  ```
320
407
 
321
408
  **Flags:**
322
409
 
323
- | Flag | Short | Description |
324
- |------|-------|-------------|
325
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
326
- | `--verbose` | `-v` | Verbose output. |
327
- | `--quiet` | `-q` | Minimal output. |
410
+
411
+ | Flag | Short | Description |
412
+ | -------------- | ----- | --------------------- |
413
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
414
+ | `--verbose` | `-v` | Verbose output. |
415
+ | `--quiet` | `-q` | Minimal output. |
416
+
328
417
 
329
418
  ---
330
419
 
331
420
  ### delete
332
421
 
333
- Deletes **local** workflow branch(es). Never deletes the configured main or dev. With a **TTY** and no names, shows a picker (or multi-select if supported). Otherwise pass one or more branch names as positionals.
422
+ Delete local workflow branch(es). Never deletes main/dev. TTY: picker; otherwise pass branch name(s).
334
423
 
335
424
  **Examples:**
336
425
 
337
426
  ```bash
338
- gflows delete # picker (if TTY)
339
- gflows delete feature/old-spike
340
- gflows delete feature/one feature/two # delete multiple
427
+ bun gflows delete
428
+ bun gflows delete feature/old-spike
429
+ bun gflows delete feature/one feature/two
341
430
  ```
342
431
 
343
432
  **Flags:**
344
433
 
345
- | Flag | Short | Description |
346
- |------|-------|-------------|
347
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
348
- | `--verbose` | `-v` | Verbose output. |
349
- | `--quiet` | `-q` | Minimal output. |
434
+
435
+ | Flag | Short | Description |
436
+ | -------------- | ----- | --------------------- |
437
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
438
+ | `--verbose` | `-v` | Verbose output. |
439
+ | `--quiet` | `-q` | Minimal output. |
440
+
350
441
 
351
442
  ---
352
443
 
353
444
  ### list
354
445
 
355
- Lists workflow branches (those matching configured prefixes). Output is **one branch per line** to stdout for scripting. Optionally filter by type; optionally include remote-tracking branches (with `-r`/`--include-remote`, which may run `git fetch` first).
446
+ List workflow branches (one per line). Filter by type; use `-r` to include remote (may run `git fetch`).
356
447
 
357
448
  **Examples:**
358
449
 
359
450
  ```bash
360
- gflows list # all local workflow branches
361
- gflows list feature # only feature/* branches
362
- gflows list -r # include remote-tracking branches
363
- gflows list -r feature # remote + local feature branches
364
- gflows list --include-remote
451
+ bun gflows list
452
+ bun gflows list feature
453
+ bun gflows list -r
365
454
  ```
366
455
 
367
456
  **Flags:**
368
457
 
369
- | Flag | Short | Description |
370
- |------|-------|-------------|
371
- | `--include-remote` | `-r` | Include remote-tracking branches (may run `git fetch`). |
372
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
373
- | `--dry-run` | `-d` | Log intended actions only. |
374
- | `--verbose` | `-v` | Verbose output. |
375
- | `--quiet` | `-q` | Minimal output. |
458
+
459
+ | Flag | Short | Description |
460
+ | ------------------ | ----- | ------------------------------------------------------- |
461
+ | `--include-remote` | `-r` | Include remote-tracking branches (may run `git fetch`). |
462
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
463
+ | `--dry-run` | `-d` | Log intended actions only. |
464
+ | `--verbose` | `-v` | Verbose output. |
465
+ | `--quiet` | `-q` | Minimal output. |
466
+
376
467
 
377
468
  ---
378
469
 
379
470
  ### bump
380
471
 
381
- Bumps or rolls back the **root** package version (reads `package.json` from cwd or `-C`). Keeps `package.json` and `jsr.json` in sync; **no git operations** (no commit or tag). Useful before `gflows start release vX.Y.Z`.
382
-
383
- **Positionals:** direction `up` | `down`, type `patch` | `minor` | `major`. When both are omitted and stdin is a TTY, shows interactive selects. When not a TTY, both are required.
472
+ Bump or rollback version in `package.json` and `jsr.json` (monorepo: all discovered roots). No git operations. Direction: `up`|`down`; type: `patch`|`minor`|`major`. TTY: interactive; non-TTY: both required.
384
473
 
385
474
  **Examples:**
386
475
 
387
476
  ```bash
388
- gflows bump up patch # 1.2.3 → 1.2.4
389
- gflows bump up minor # 1.2.3 → 1.3.0
390
- gflows bump up major # 1.2.3 → 2.0.0
391
- gflows bump down patch # 1.2.4 → 1.2.3 (floor at 0)
392
- gflows bump down minor # 1.3.0 → 1.2.0
393
- gflows bump # interactive (direction + type) when TTY
394
- gflows bump --dry-run # print old → new, no file writes
477
+ bun gflows bump up patch
478
+ bun gflows bump down minor
479
+ bun gflows bump --dry-run
395
480
  ```
396
481
 
397
482
  **Flags:**
398
483
 
399
- | Flag | Short | Description |
400
- |------|-------|-------------|
401
- | `--dry-run` | `-d` | Print old → new version only; no file writes. |
402
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
403
- | `--verbose` | `-v` | Verbose output. |
404
- | `--quiet` | `-q` | Minimal output. |
484
+
485
+ | Flag | Short | Description |
486
+ | -------------- | ----- | --------------------------------------------- |
487
+ | `--dry-run` | `-d` | Print old new version only; no file writes. |
488
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
489
+ | `--verbose` | `-v` | Verbose output. |
490
+ | `--quiet` | `-q` | Minimal output. |
491
+
405
492
 
406
493
  ---
407
494
 
408
495
  ### status
409
496
 
410
- Shows current branch, its **classification** (feature, bugfix, chore, release, hotfix, spike, main, dev, or unknown), **base** branch, **merge target(s)**, and **ahead/behind** vs base. No write operations; safe to run anytime.
497
+ Shows current branch, type, base, merge target(s), ahead/behind. Read-only.
411
498
 
412
499
  **Examples:**
413
500
 
414
501
  ```bash
415
- gflows status
416
- gflows -t
502
+ bun gflows status
503
+ bun gflows -t
417
504
  ```
418
505
 
419
506
  **Flags:**
420
507
 
421
- | Flag | Short | Description |
422
- |------|-------|-------------|
423
- | `--path <dir>` | `-C` | Run as if in `<dir>`. |
424
- | `--verbose` | `-v` | Verbose output. |
425
- | `--quiet` | `-q` | Minimal output. |
426
-
427
- ---
428
-
429
- ### completion
430
508
 
431
- Prints the shell completion script. Use with `source` (bash/zsh) or pipe into your shell (fish) to enable tab-completion for commands, types, and branch names.
509
+ | Flag | Short | Description |
510
+ | -------------- | ----- | --------------------- |
511
+ | `--path <dir>` | `-C` | Run as if in `<dir>`. |
512
+ | `--verbose` | `-v` | Verbose output. |
513
+ | `--quiet` | `-q` | Minimal output. |
432
514
 
433
- **Examples:** See [Shell completion](#shell-completion).
434
515
 
435
516
  ---
436
517
 
437
- ### help & version
438
-
439
- ```bash
440
- gflows help
441
- gflows -h
442
- gflows version
443
- gflows -V
444
- ```
445
-
446
- ---
447
-
448
- ## Branch types in detail
449
-
450
-
451
- | Type | Short | Base (default) | With `-o main` | Merge target(s) | Tag |
452
- | ------- | ----- | -------------- | -------------- | -------------------------- | --- |
453
- | feature | `-f` | dev | — | dev | no |
454
- | bugfix | `-b` | dev | main | dev (or main if from main) | no |
455
- | chore | `-c` | dev | — | dev | no |
456
- | release | `-r` | dev | — | main, then dev | yes |
457
- | hotfix | `-x` | main | — | main, then dev | yes |
458
- | spike | `-e` | dev | — | dev | no |
518
+ ### completion
459
519
 
520
+ Prints completion script for bash/zsh/fish. See [Shell completion](#shell-completion).
460
521
 
461
- - **feature** New functionality; branches from dev, merges to dev.
462
- - **bugfix** — Bug fixes. Usually from dev → dev. Use `-o main` when fixing a bug on production (branch from main, merge to main then dev).
463
- - **chore** — Tasks that don’t change behavior (deps, tooling, docs). dev → dev.
464
- - **release** — Prepare a release from dev: merge to main, then merge main into dev, create tag (e.g. `v1.2.0`). Name must be a version: `vX.Y.Z` or `X.Y.Z`.
465
- - **hotfix** — Urgent fix from production (main). Merge to main, then main into dev; tag. Name must be a version.
466
- - **spike** — Short-lived experiment; dev → dev, no tag. Discard or merge as needed.
522
+ ### help & version
467
523
 
468
- **Naming:** Branch names use prefixes by default: `feature/add-login`, `bugfix/fix-login`, `release/v1.0.0`, `hotfix/v1.0.1`, `chore/update-deps`, `spike/try-cache`. Prefixes can be overridden in [configuration](#configuration). Invalid branch names (e.g. containing `..`, `*`, spaces) are rejected with exit code 1.
524
+ `bun gflows help` · `bun gflows -V`
469
525
 
470
526
  ---
471
527
 
472
528
  ## Configuration
473
529
 
474
- Configuration is **optional**. Override branch names, remote, and branch **prefixes** when needed.
475
-
476
- **Resolution order** (later overrides earlier):
477
-
478
- 1. Built-in defaults (`main`, `dev`, `origin`, and default prefixes).
479
- 2. Repo config file: `**.gflows.json`** in repo root, or `**gflows`** key in `**package.json**`.
480
- 3. CLI (e.g. `--main`, `--dev`, `-R`/`--remote`).
481
-
482
- Only include keys you want to override; the rest stay default. Invalid or malformed config is ignored (with an optional warning when using `-v`).
530
+ Optional. Override main, dev, remote, prefixes. Resolution: defaults `.gflows.json` or `package.json` "gflows" key → CLI flags. Invalid config is ignored (`-v` for warning).
483
531
 
484
532
  ### Example: `.gflows.json` (full)
485
533
 
@@ -499,92 +547,40 @@ Only include keys you want to override; the rest stay default. Invalid or malfor
499
547
  }
500
548
  ```
501
549
 
502
- ### Example: minimal override (different branch names)
550
+ ### Example: minimal
503
551
 
504
552
  ```json
505
- {
506
- "main": "master",
507
- "dev": "develop"
508
- }
553
+ { "main": "master", "dev": "develop" }
509
554
  ```
510
555
 
511
- ### Example: custom prefixes only
512
-
513
- ```json
514
- {
515
- "prefixes": {
516
- "feature": "feat/",
517
- "bugfix": "fix/"
518
- }
519
- }
520
- ```
521
-
522
- ### Example: `package.json` key
523
-
524
- ```json
525
- {
526
- "name": "my-app",
527
- "version": "1.0.0",
528
- "gflows": {
529
- "main": "main",
530
- "dev": "development",
531
- "remote": "upstream"
532
- }
533
- }
534
- ```
556
+ Or in `package.json`: `"gflows": { "main": "main", "dev": "development", "remote": "upstream" }`
535
557
 
536
558
  ---
537
559
 
538
560
  ## Scripting and CI
539
561
 
540
- - **Non-interactive:** When stdin is **not** a TTY, gflows does **not** show pickers (e.g. for switch, delete, or finish `-B`). You must pass branch names explicitly or the command exits with a clear message (exit code 1).
541
- - **Skip confirmations:** Use `**-y`/`--yes`** to accept defaults (e.g. "Delete branch after finish?" → no delete unless you also passed `-D`).
542
- - **Exit codes:** Use them in scripts: `0` success, `1` usage/validation, `2` Git/system error.
543
-
544
- **Examples:**
545
-
546
- ```bash
547
- # Require explicit branch when not TTY
548
- gflows finish feature -B feature/add-login --push -y
549
-
550
- # List branches for parsing (one per line)
551
- gflows list feature | while read -r b; do echo "Branch: $b"; done
552
-
553
- # CI: fail fast on error
554
- set -e
555
- gflows start feature ci-job --force
556
- # ... run tests ...
557
- gflows finish feature -B feature/ci-job -y
558
- ```
559
-
560
- **Path:** Use `-C`/`--path` so all git and config resolution use that directory:
562
+ Non-TTY: no pickers; pass branch names explicitly. Use `-y` to skip confirmations. Exit codes: 0 success, 1 validation, 2 Git/state. Use `-C <dir>` to run in another directory.
561
563
 
562
564
  ```bash
563
- gflows -C /var/lib/repos/my-app status
564
- gflows -C ./packages/api list
565
+ bun gflows finish feature -B feature/add-login --push -y
566
+ bun gflows list feature | while read -r b; do echo "$b"; done
567
+ bun gflows -C ./packages/api list
565
568
  ```
566
569
 
567
570
  ---
568
571
 
569
572
  ## Exit codes
570
573
 
571
-
572
574
  | Code | Meaning | Typical causes |
573
575
  | ----- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
574
576
  | **0** | Success | Command completed without error. |
575
- | **1** | Usage / validation | Missing type or name for `start`; invalid branch name or version format; wrong/missing positionals for non-TTY. |
576
- | **2** | Git / system | Not a Git repo; branch not found; dirty working tree (start without `--force`); merge conflict on finish; rebase/merge in progress; detached HEAD; finish on main/dev; tag already exists; push failed after merge. |
577
-
578
-
579
- **Validation (exit 1):** Invalid version (e.g. `start release foo`), invalid branch name (e.g. `feature/bad..name`), or missing required args in non-interactive mode.
580
-
581
- **Git/state (exit 2):** Repository issues, branch missing, merge conflicts (user must resolve manually), or guards (e.g. cannot finish main/dev, cannot delete main/dev).
577
+ | **1** | Usage / validation | Missing type or name for `start`; invalid branch name or version; wrong/missing positionals when not TTY. |
578
+ | **2** | Git / system | Not a repo; branch not found; dirty tree; merge conflict; rebase/merge in progress; detached HEAD; finish on main/dev; tag exists; push failed. |
582
579
 
583
580
  ---
584
581
 
585
582
  ## Troubleshooting
586
583
 
587
-
588
584
  | Situation | What to do |
589
585
  | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
590
586
  | **"Not a Git repository"** | Run from a directory that contains `.git`, or use `-C <path>` to point to the repo root. |
@@ -598,54 +594,45 @@ gflows -C ./packages/api list
598
594
  | **Wrong remote or branch names** | Use `.gflows.json` or `package.json` "gflows" key, or `gflows init --main … --dev … --remote …`. Use `-R` for one-off remote override. |
599
595
 
600
596
 
601
- Use `**-v`/`--verbose`** to see git commands and extra diagnostics; combine with the error message to pinpoint the cause.
597
+ Use `-v` for verbose git commands and diagnostics.
602
598
 
603
599
  ---
604
600
 
605
601
  ## Shell completion
606
602
 
607
- Generate and install completion so you can tab-complete commands, types, and (where applicable) branch names.
608
-
609
603
  **Bash:**
610
604
 
611
605
  ```bash
612
- source <(gflows completion bash)
613
- # Or persist:
614
- echo 'source <(gflows completion bash)' >> ~/.bashrc
606
+ source <(bun gflows completion bash)
607
+ echo 'source <(bun gflows completion bash)' >> ~/.bashrc
615
608
  ```
616
609
 
617
610
  **Zsh:**
618
611
 
619
612
  ```bash
620
- source <(gflows completion zsh)
621
- # Or persist:
622
- echo 'source <(gflows completion zsh)' >> ~/.zshrc
613
+ source <(bun gflows completion zsh)
614
+ echo 'source <(bun gflows completion zsh)' >> ~/.zshrc
623
615
  ```
624
616
 
625
617
  **Fish:**
626
618
 
627
619
  ```bash
628
- gflows completion fish | source
629
- # Or persist:
630
- gflows completion fish > ~/.config/fish/completions/gflows.fish
620
+ bun gflows completion fish | source
621
+ bun gflows completion fish > ~/.config/fish/completions/gflows.fish
631
622
  ```
632
623
 
633
- Completion covers: **commands** (init, start, finish, switch, delete, list, bump, completion, status, help, version), **types** (feature, bugfix, chore, release, hotfix, spike), and **branch names** from local workflow branches when the context expects a branch (e.g. after `switch` or `finish -B`).
634
-
635
624
  ---
636
625
 
637
626
  ## Publishing (maintainers)
638
627
 
639
- Publishing is done with the **internal script** `scripts/publish.ts`. It syncs the version from **package.json** to **jsr.json**, then publishes to **npm** and/or **JSR**. The script is not part of the published package (`files` excludes `scripts/`).
640
-
641
- ### Commands
628
+ Internal script `scripts/publish.ts`: syncs version from package.json to jsr.json, then publishes to npm and/or JSR. Not in published package.
642
629
 
643
630
  ```bash
644
- bun run publish:all # publish to npm and JSR (same version)
645
- bun run publish:all -- --dry-run # sync version only; print intended commands; no publish
646
- bun run publish:npm # publish only to npm
647
- bun run publish:jsr # publish only to JSR
648
- bun run publish:all -- --force # skip pre-publish checks (clean tree, branch main)
631
+ bun run publish:all
632
+ bun run publish:all -- --dry-run
633
+ bun run publish:npm
634
+ bun run publish:jsr
635
+ bun run publish:all -- --force
649
636
  ```
650
637
 
651
638
  ### Typical release workflow