gflows 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ali AlNaghmoush (https://github.com/alialnaghmoush)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,549 @@
1
+ # gflows
2
+
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
+
5
+ **Author:** [Ali AlNaghmoush](https://github.com/alialnaghmoush) · **Repository:** [github.com/alialnaghmoush/gflows](https://github.com/alialnaghmoush/gflows)
6
+
7
+ ---
8
+
9
+ ## Table of contents
10
+
11
+ - [Prerequisites](#prerequisites)
12
+ - [Installation](#installation)
13
+ - [Concepts](#concepts)
14
+ - [Quick start](#quick-start)
15
+ - [Command reference](#command-reference)
16
+ - [Branch types in detail](#branch-types-in-detail)
17
+ - [Configuration](#configuration)
18
+ - [Scripting and CI](#scripting-and-ci)
19
+ - [Exit codes](#exit-codes)
20
+ - [Troubleshooting](#troubleshooting)
21
+ - [Shell completion](#shell-completion)
22
+ - [Publishing (maintainers)](#publishing-maintainers)
23
+ - [License](#license)
24
+
25
+ ---
26
+
27
+ ## Prerequisites
28
+
29
+ - **Bun** ≥ 1.0 (recommended). The CLI runs TypeScript directly; no separate build step.
30
+ - **Git** for all repository operations.
31
+
32
+ Check versions:
33
+
34
+ ```bash
35
+ bun --version
36
+ git --version
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Installation
42
+
43
+ **From the repository (development or link):**
44
+
45
+ ```bash
46
+ git clone https://github.com/alialnaghmoush/gflows.git
47
+ cd gflows
48
+ bun install
49
+ bun link # global `gflows` (or: npm link)
50
+ ```
51
+
52
+ **Run without installing** (from repo root):
53
+
54
+ ```bash
55
+ bun run gflows -- <command> ...
56
+ # or
57
+ bun run src/cli.ts -- <command> ...
58
+ ```
59
+
60
+ **After linking**, use `gflows` from any Git repository:
61
+
62
+ ```bash
63
+ cd /path/to/your/repo
64
+ gflows init
65
+ gflows start feature my-feature
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Concepts
71
+
72
+ - **main** — Long-lived production branch. Default name: `main`. Only release and hotfix branches merge here.
73
+ - **dev** — Long-lived integration branch. Default name: `dev`. Feature, bugfix, chore, and spike branches merge here. Created by `gflows init` from `main`.
74
+ - **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).
75
+ - **Merge targets** — Where `gflows finish` merges:
76
+ - **feature / chore / spike** → `dev` only.
77
+ - **bugfix** → `dev` (or `main` if the bugfix was started from main with `-o main`).
78
+ - **release** → `main` first, then `main` is merged into `dev`; a tag is created.
79
+ - **hotfix** → `main` first, then `main` is merged into `dev`; a tag is created.
80
+
81
+ You can override branch names and prefixes via [configuration](#configuration).
82
+
83
+ ---
84
+
85
+ ## Quick start
86
+
87
+ **1. One-time setup** in your repo (ensure `main` exists and create `dev`):
88
+
89
+ ```bash
90
+ gflows init
91
+ gflows init --push # also push dev to origin
92
+ gflows init --dry-run # show what would be done, no writes
93
+ ```
94
+
95
+ **2. Daily development** (feature → dev):
96
+
97
+ ```bash
98
+ gflows start feature add-login
99
+ # ... code, commit ...
100
+ gflows finish feature # merge into dev
101
+ gflows finish feature --push # merge and push dev
102
+ gflows finish feature --push -D # merge, push, and delete local branch
103
+ ```
104
+
105
+ **3. Release** (dev → main, then tag):
106
+
107
+ ```bash
108
+ gflows bump up minor # e.g. 1.2.3 → 1.3.0
109
+ gflows start release v1.3.0
110
+ # ... update CHANGELOG, commit ...
111
+ gflows finish release --push # merge to main, then dev; tag v1.3.0; push
112
+ ```
113
+
114
+ **4. Hotfix** (main → fix → main + dev):
115
+
116
+ ```bash
117
+ gflows start hotfix v1.3.1
118
+ # ... fix, commit ...
119
+ gflows finish hotfix --push # merge to main, then dev; tag v1.3.1; push
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Command reference
125
+
126
+ ### Summary table
127
+
128
+ | Command | Short | Description |
129
+ |-------------|-------|--------------|
130
+ | `init` | `-I` | Ensure main exists; create dev from main. |
131
+ | `start` | `-S` | Create a workflow branch (requires type + name). |
132
+ | `finish` | `-F` | Merge branch into target(s), optional tag (release/hotfix), delete, push. |
133
+ | `switch` | `-W` | Switch to a workflow branch (picker or name). |
134
+ | `delete` | `-L` | Delete local workflow branch(es). Never main/dev. |
135
+ | `list` | `-l` | List workflow branches; optional type filter and remote. |
136
+ | `bump` | — | Bump or rollback package version (patch/minor/major). |
137
+ | `completion` | — | Print shell completion script (bash \| zsh \| fish). |
138
+ | `status` | `-t` | Show current branch, type, base, merge target(s), ahead/behind. |
139
+ | `help` | `-h` | Show usage and quick reference. |
140
+ | `version` | `-V` | Show version. |
141
+
142
+ **Branch types (for start/finish/list):** `feature` (`-f`), `bugfix` (`-b`), `chore` (`-c`), `release` (`-r`), `hotfix` (`-x`), `spike` (`-e`).
143
+
144
+ ---
145
+
146
+ ### init
147
+
148
+ 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.
149
+
150
+ **Examples:**
151
+
152
+ ```bash
153
+ gflows init
154
+ gflows init --push # push dev to remote after creating
155
+ gflows init -C ../other-repo # run in another directory
156
+ gflows init --dry-run # log intended actions only
157
+ ```
158
+
159
+ **Flags:** `--push`, `-C`/`--path <dir>`, `--dry-run`, `-v`/`--verbose`, `-q`/`--quiet`.
160
+
161
+ ---
162
+
163
+ ### start
164
+
165
+ 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`).
166
+
167
+ **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).
168
+
169
+ **Examples:**
170
+
171
+ ```bash
172
+ gflows start feature auth-refactor
173
+ gflows start -f auth-refactor # same (short type)
174
+ gflows start bugfix fix-login --from main # bugfix from main instead of dev
175
+ gflows start release v2.0.0
176
+ gflows start hotfix 1.2.1 # "v" is optional for version
177
+ gflows start feature wip --force # allow uncommitted changes
178
+ gflows start feature api-v2 --push # create branch and push to remote
179
+ gflows start chore deps-update -C ./backend # run in subdirectory
180
+ ```
181
+
182
+ **Flags:** `--force` (allow dirty working tree), `--push`, `-o`/`--from <branch>` (base override, e.g. `-o main` for bugfix), `-R`/`--remote`, `-C`/`--path`, `--dry-run`, `-v`, `-q`.
183
+
184
+ ---
185
+
186
+ ### finish
187
+
188
+ 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.
189
+
190
+ **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.
191
+
192
+ **Examples:**
193
+
194
+ ```bash
195
+ gflows finish feature # merge current branch (feature/xyz) into dev
196
+ gflows finish feature -B feature/auth # finish branch feature/auth
197
+ gflows finish feature --no-ff # always create a merge commit
198
+ gflows finish feature --push -D # merge, push, delete local branch
199
+ gflows finish release --push # merge to main, then dev; tag; push
200
+ gflows finish hotfix -s # sign the tag (GPG)
201
+ gflows finish hotfix -T # no tag (e.g. abandon hotfix as release)
202
+ gflows finish -y # skip "Delete branch after finish?" prompt (use default)
203
+ ```
204
+
205
+ **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.
206
+
207
+ **Flags:** `-B`/`--branch <name>`, `--no-ff`, `-D`/`--delete` (delete branch after finish), `-N`/`--no-delete`, `--push`, `-s`/`--sign`, `-T`/`--no-tag`, `-M`/`--tag-message`, `-m`/`--message`, `-y`/`--yes`, `-C`, `--dry-run`, `-v`, `-q`.
208
+
209
+ ---
210
+
211
+ ### switch
212
+
213
+ 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.
214
+
215
+ **Examples:**
216
+
217
+ ```bash
218
+ gflows switch # picker (if TTY)
219
+ gflows switch feature/auth-refactor
220
+ gflows -W feature/auth-refactor # same with short command
221
+ ```
222
+
223
+ **Flags:** `-C`/`--path`, `-v`, `-q`.
224
+
225
+ ---
226
+
227
+ ### delete
228
+
229
+ 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.
230
+
231
+ **Examples:**
232
+
233
+ ```bash
234
+ gflows delete # picker (if TTY)
235
+ gflows delete feature/old-spike
236
+ gflows delete feature/one feature/two # delete multiple
237
+ ```
238
+
239
+ **Flags:** `-C`/`--path`, `-v`, `-q`.
240
+
241
+ ---
242
+
243
+ ### list
244
+
245
+ 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).
246
+
247
+ **Examples:**
248
+
249
+ ```bash
250
+ gflows list # all local workflow branches
251
+ gflows list feature # only feature/* branches
252
+ gflows list -r # include remote-tracking branches
253
+ gflows list -r feature # remote + local feature branches
254
+ gflows list --include-remote
255
+ ```
256
+
257
+ **Flags:** `-r`/`--include-remote`, `-C`/`--path`, `--dry-run`, `-v`, `-q`.
258
+
259
+ ---
260
+
261
+ ### bump
262
+
263
+ 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`.
264
+
265
+ **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.
266
+
267
+ **Examples:**
268
+
269
+ ```bash
270
+ gflows bump up patch # 1.2.3 → 1.2.4
271
+ gflows bump up minor # 1.2.3 → 1.3.0
272
+ gflows bump up major # 1.2.3 → 2.0.0
273
+ gflows bump down patch # 1.2.4 → 1.2.3 (floor at 0)
274
+ gflows bump down minor # 1.3.0 → 1.2.0
275
+ gflows bump # interactive (direction + type) when TTY
276
+ gflows bump --dry-run # print old → new, no file writes
277
+ ```
278
+
279
+ **Flags:** `--dry-run`, `-C`/`--path`, `-v`, `-q`.
280
+
281
+ ---
282
+
283
+ ### status
284
+
285
+ 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.
286
+
287
+ **Examples:**
288
+
289
+ ```bash
290
+ gflows status
291
+ gflows -t
292
+ ```
293
+
294
+ **Flags:** `-C`/`--path`, `-v`, `-q`.
295
+
296
+ ---
297
+
298
+ ### completion
299
+
300
+ 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.
301
+
302
+ **Examples:** See [Shell completion](#shell-completion).
303
+
304
+ ---
305
+
306
+ ### help & version
307
+
308
+ ```bash
309
+ gflows help
310
+ gflows -h
311
+ gflows version
312
+ gflows -V
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Branch types in detail
318
+
319
+ | Type | Short | Base (default) | With `-o main` | Merge target(s) | Tag |
320
+ |----------|-------|------------------|-----------------|------------------------|-------|
321
+ | feature | `-f` | dev | — | dev | no |
322
+ | bugfix | `-b` | dev | main | dev (or main if from main) | no |
323
+ | chore | `-c` | dev | — | dev | no |
324
+ | release | `-r` | dev | — | main, then dev | yes |
325
+ | hotfix | `-x` | main | — | main, then dev | yes |
326
+ | spike | `-e` | dev | — | dev | no |
327
+
328
+ - **feature** — New functionality; branches from dev, merges to dev.
329
+ - **bugfix** — Bug fixes. Usually from dev → dev. Use `-o main` when fixing a bug on production (branch from main, merge to main then dev).
330
+ - **chore** — Tasks that don’t change behavior (deps, tooling, docs). dev → dev.
331
+ - **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`.
332
+ - **hotfix** — Urgent fix from production (main). Merge to main, then main into dev; tag. Name must be a version.
333
+ - **spike** — Short-lived experiment; dev → dev, no tag. Discard or merge as needed.
334
+
335
+ **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.
336
+
337
+ ---
338
+
339
+ ## Configuration
340
+
341
+ Configuration is **optional**. Override branch names, remote, and branch **prefixes** when needed.
342
+
343
+ **Resolution order** (later overrides earlier):
344
+
345
+ 1. Built-in defaults (`main`, `dev`, `origin`, and default prefixes).
346
+ 2. Repo config file: **`.gflows.json`** in repo root, or **`gflows`** key in **`package.json`**.
347
+ 3. Environment: **`GFLOWS_MAIN`**, **`GFLOWS_DEV`**, **`GFLOWS_REMOTE`**.
348
+ 4. CLI (e.g. `-R`/`--remote` for push).
349
+
350
+ Only include keys you want to override; the rest stay default. Invalid or malformed config is ignored (with an optional warning when using `-v`).
351
+
352
+ ### Example: `.gflows.json` (full)
353
+
354
+ ```json
355
+ {
356
+ "main": "main",
357
+ "dev": "dev",
358
+ "remote": "origin",
359
+ "prefixes": {
360
+ "feature": "feature/",
361
+ "bugfix": "bugfix/",
362
+ "chore": "chore/",
363
+ "release": "release/",
364
+ "hotfix": "hotfix/",
365
+ "spike": "spike/"
366
+ }
367
+ }
368
+ ```
369
+
370
+ ### Example: minimal override (different branch names)
371
+
372
+ ```json
373
+ {
374
+ "main": "master",
375
+ "dev": "develop"
376
+ }
377
+ ```
378
+
379
+ ### Example: custom prefixes only
380
+
381
+ ```json
382
+ {
383
+ "prefixes": {
384
+ "feature": "feat/",
385
+ "bugfix": "fix/"
386
+ }
387
+ }
388
+ ```
389
+
390
+ ### Example: `package.json` key
391
+
392
+ ```json
393
+ {
394
+ "name": "my-app",
395
+ "version": "1.0.0",
396
+ "gflows": {
397
+ "main": "main",
398
+ "dev": "development",
399
+ "remote": "upstream"
400
+ }
401
+ }
402
+ ```
403
+
404
+ ### Environment variables
405
+
406
+ ```bash
407
+ export GFLOWS_MAIN=main
408
+ export GFLOWS_DEV=develop
409
+ export GFLOWS_REMOTE=origin
410
+ gflows init
411
+ ```
412
+
413
+ ---
414
+
415
+ ## Scripting and CI
416
+
417
+ - **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).
418
+ - **Skip confirmations:** Use **`-y`/`--yes`** to accept defaults (e.g. "Delete branch after finish?" → no delete unless you also passed `-D`).
419
+ - **Exit codes:** Use them in scripts: `0` success, `1` usage/validation, `2` Git/system error.
420
+
421
+ **Examples:**
422
+
423
+ ```bash
424
+ # Require explicit branch when not TTY
425
+ gflows finish feature -B feature/add-login --push -y
426
+
427
+ # List branches for parsing (one per line)
428
+ gflows list feature | while read -r b; do echo "Branch: $b"; done
429
+
430
+ # CI: fail fast on error
431
+ set -e
432
+ gflows start feature ci-job --force
433
+ # ... run tests ...
434
+ gflows finish feature -B feature/ci-job -y
435
+ ```
436
+
437
+ **Path:** Use `-C`/`--path` so all git and config resolution use that directory:
438
+
439
+ ```bash
440
+ gflows -C /var/lib/repos/my-app status
441
+ gflows -C ./packages/api list
442
+ ```
443
+
444
+ ---
445
+
446
+ ## Exit codes
447
+
448
+ | Code | Meaning | Typical causes |
449
+ |------|---------|-----------------|
450
+ | **0** | Success | Command completed without error. |
451
+ | **1** | Usage / validation | Missing type or name for `start`; invalid branch name or version format; wrong/missing positionals for non-TTY. |
452
+ | **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. |
453
+
454
+ **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.
455
+
456
+ **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).
457
+
458
+ ---
459
+
460
+ ## Troubleshooting
461
+
462
+ | Situation | What to do |
463
+ |-----------|------------|
464
+ | **"Not a Git repository"** | Run from a directory that contains `.git`, or use `-C <path>` to point to the repo root. |
465
+ | **"Working tree has uncommitted changes"** | Commit or stash changes before `start`, or use `--force` (only when you intend to carry uncommitted work). |
466
+ | **"Merge conflict while merging into …"** | Resolve conflicts in your working tree, then run `git add` and `git merge --continue` (or `git merge --abort` to cancel). Re-run `gflows finish` after resolving if needed. |
467
+ | **"Tag v1.2.3 already exists"** | Use a new version for the release/hotfix, or delete/move the tag if you know what you’re doing. gflows does not overwrite tags. |
468
+ | **"Cannot finish the long-lived branch main/dev"** | You’re on main or dev. Checkout a workflow branch first, or use `-B <branch>` to finish another branch. |
469
+ | **"HEAD is detached"** | Checkout a branch (e.g. `git checkout dev`) before running `start` or `finish`. |
470
+ | **"A rebase or merge is in progress"** | Run `git rebase --abort` or `git merge --abort`, or complete the operation, then retry gflows. |
471
+ | **Picker not showing / "requires branch name"** | Without a TTY, gflows does not show interactive pickers. Pass the branch name explicitly (e.g. `-B feature/xyz` or `gflows switch feature/xyz`). |
472
+ | **Wrong remote or branch names** | Set `GFLOWS_MAIN`, `GFLOWS_DEV`, `GFLOWS_REMOTE` or use `.gflows.json` / `package.json` "gflows" key. Use `-R` for one-off remote override. |
473
+
474
+ Use **`-v`/`--verbose`** to see git commands and extra diagnostics; combine with the error message to pinpoint the cause.
475
+
476
+ ---
477
+
478
+ ## Shell completion
479
+
480
+ Generate and install completion so you can tab-complete commands, types, and (where applicable) branch names.
481
+
482
+ **Bash:**
483
+
484
+ ```bash
485
+ source <(gflows completion bash)
486
+ # Or persist:
487
+ echo 'source <(gflows completion bash)' >> ~/.bashrc
488
+ ```
489
+
490
+ **Zsh:**
491
+
492
+ ```bash
493
+ source <(gflows completion zsh)
494
+ # Or persist:
495
+ echo 'source <(gflows completion zsh)' >> ~/.zshrc
496
+ ```
497
+
498
+ **Fish:**
499
+
500
+ ```bash
501
+ gflows completion fish | source
502
+ # Or persist:
503
+ gflows completion fish > ~/.config/fish/completions/gflows.fish
504
+ ```
505
+
506
+ 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`).
507
+
508
+ ---
509
+
510
+ ## Publishing (maintainers)
511
+
512
+ 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/`).
513
+
514
+ ### Commands
515
+
516
+ ```bash
517
+ bun run publish # publish to npm and JSR (same version)
518
+ bun run publish -- --dry-run # sync version only; print intended commands; no publish
519
+ bun run publish -- --npm-only # publish only to npm
520
+ bun run publish -- --jsr-only # publish only to JSR
521
+ bun run publish -- --force # skip pre-publish checks (clean tree, branch main)
522
+ ```
523
+
524
+ ### Typical release workflow
525
+
526
+ 1. Ensure you’re on **main** with a clean working tree (or use `--force` when intentional).
527
+ 2. Bump version and tag in Git yourself, or use gflows bump + your own commit:
528
+ ```bash
529
+ gflows bump up minor --dry-run # confirm
530
+ gflows bump up minor
531
+ git add package.json jsr.json && git commit -m "chore: bump to 1.4.0"
532
+ ```
533
+ 3. Run the publish script:
534
+ ```bash
535
+ bun run publish -- --dry-run # verify
536
+ bun run publish
537
+ ```
538
+ 4. Optionally push main and tags:
539
+ ```bash
540
+ git push origin main --tags
541
+ ```
542
+
543
+ **Version sync:** The script reads `version` from **package.json** and writes it to **jsr.json** before publishing so the two registries never drift. Use **`gflows bump`** to change the version; the script does not bump for you.
544
+
545
+ ---
546
+
547
+ ## License
548
+
549
+ See [LICENSE](LICENSE) in this repository.
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "gflows",
3
+ "version": "0.1.1",
4
+ "description": "A lightweight CLI for consistent Git branching workflows (main + dev, feature/bugfix/chore/release/hotfix).",
5
+ "type": "module",
6
+ "module": "src/index.ts",
7
+ "bin": {
8
+ "gflows": "src/cli.ts"
9
+ },
10
+ "scripts": {
11
+ "test": "bun test",
12
+ "lint": "tsc --noEmit",
13
+ "gflows": "bun run src/cli.ts",
14
+ "publish": "bun run scripts/publish.ts",
15
+ "publish:npm": "bun run scripts/publish.ts -- --npm-only",
16
+ "publish:jsr": "bun run scripts/publish.ts -- --jsr-only"
17
+ },
18
+ "files": [
19
+ "src",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "engines": {
24
+ "bun": ">=1.0.0"
25
+ },
26
+ "author": "Ali AlNaghmoush (https://github.com/alialnaghmoush)",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/alialnaghmoush/gflows.git"
30
+ },
31
+ "dependencies": {
32
+ "@inquirer/prompts": "^8"
33
+ },
34
+ "devDependencies": {
35
+ "@types/bun": "latest",
36
+ "typescript": "^5"
37
+ }
38
+ }