A radically simple workflow tool for Jujutsu that makes patch-stack development with GitHub beautiful and effortless.
Query, don't track. jflow has zero state filesโit queries jj directly using powerful revsets. Your stack is always ::@ ~ ::main@origin. Simple.
Four commands. That's it.
jf status- See your beautiful stackjf pr- Create bookmark + PRjf sync- Update all bookmarksjf pull- Fetch + rebase
- Jujutsu (jj) installed
- Rust toolchain (for building)
cargo install --path .Or with just the binary name:
cargo build --release
cp target/release/jf ~/.local/bin/ # or wherever in your PATH# In your jj repository
cd my-project
# Initialize jflow (creates .jflow.toml)
jf init
# See your stack
jf status
# Create a PR for a change
jf pr abc1234 my-feature-name
# Update all bookmarks after making changes
jf sync
# Pull latest and rebase
jf pullInitialize jflow in your repository. Creates .jflow.toml with smart defaults.
jf init # Interactive configuration
jf init --defaults # Skip prompts, use defaultsWhat it does:
- Checks if you're in a jj repository
- Detects your main branch (main, master, or trunk)
- Detects your remote name
- Checks if gh CLI is available
- Creates
.jflow.tomlwith detected settings
Interactive mode:
- Prompts for main branch (detected: main)
- Prompts for remote (detected: origin)
- Choose theme (catppuccin, nord, dracula, default)
- Choose icons (unicode or ascii)
- Set bookmark prefix (default: jf/)
Example output:
๐ฏ Initializing jflow...
๐ Configuration (press Enter to use detected/default values)
Main branch name [main]:
Remote name [origin]:
๐จ Available themes:
1. catppuccin (warm pastels) [default]
2. nord (cool arctic)
3. dracula (high contrast)
4. default (terminal colors)
Choose theme (1-4): 1
โจ Icon style:
1. unicode (โโโโ) [default]
2. ascii (*o#->)
Choose icons (1-2): 1
Bookmark prefix [jf/]:
โ Created .jflow.toml
๐ Configuration Summary:
Stack revset: ::@ ~ ::main@origin
Theme: catppuccin
Icons: unicode
Bookmark prefix: jf/
๐ก Next steps:
1. View your stack: jf status
2. Create a PR: jf pr <change-id> <bookmark-name>
3. Edit config: .jflow.toml
Beautiful visualization of your stack with PR status.
โญโ Your Stack โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ โ qwer5678 Add login screen โ
โ ๐ก ready to create PR โ
โ โ โ
โ โ tyui9012 Add backend API โ
โ โ jf/add-backend-api โ
โ โณ awaiting review โ
โ โ โ
โ โ asdf1234 Add REST library โ
โ โ jf/add-rest-library โ
โ โ
approved, ready to merge โ
โ โ โ
โ โ main@origin โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
๐ก Suggestions:
โข jf pr qwer5678 add-login-screen
Icons:
โWorking copy (@)โChange in stackโMain branchโHas bookmark๐กReady for action
Create a bookmark and PR for a specific change.
jf pr abc1234 add-rest-libraryThis:
- Creates bookmark
jf/add-rest-libraryat changeabc1234 - Pushes to GitHub
- Creates PR with stack context (if
ghCLI is available)
Options:
--title- Custom PR title (defaults to commit description)
With stack context enabled (default), the PR description includes:
Add REST library
---
**Part of stack:**
- โ
**This PR** (Add REST library)
- โณ Add backend API (bookmark: `jf/add-backend-api`)
- โณ Add login screen (bookmark: `jf/add-login-screen`)Requirements:
ghCLI installed for automatic PR creation- Without
gh, bookmark is pushed but PR must be created manually
Update all bookmarks to their current commit positions and push.
jf syncAfter rebasing or editing changes, bookmarks need to be updated to point to the new commits (remember: jj change IDs are stable, but commit IDs change). This command does it automatically for all bookmarks in your stack.
What it does:
- Finds all bookmarks in your stack (
::@ ~ ::main@origin) - For each bookmark, finds the current commit for that change ID
- Updates the bookmark to point to the new commit
- Pushes all bookmarks to remote
Options:
--dry-run- Show what would be done without making changes
Example output:
โน Found 3 bookmark(s) to sync
Updated jf/core-library โ abc1234
Updated jf/api-layer โ def5678
Updated jf/ui-component โ ghi9012
โน Pushing bookmarks to remote...
โ Successfully synced all bookmarks!
When to use:
- After
jj editon any change with a bookmark - After
jj rebase - After
jj squashor other history modifications - Before
jf pullif you have local changes
Fetch from remote and rebase your stack.
jf pullEquivalent to:
jj git fetch
jj rebase -d main@originCreate .jflow.toml in your repository root:
[stack]
revset = "::@ ~ ::main@origin"
main_branch = "main"
remote = "origin"
[display]
theme = "catppuccin" # catppuccin, nord, dracula, default
icons = "unicode" # unicode or ascii
[bookmarks]
prefix = "jf/"See .jflow.toml.example for all options.
Catppuccin Mocha (default)
- Warm, pastel colors
- Excellent contrast
Nord
- Cool, arctic palette
- Easy on the eyes
Dracula
- High contrast
- Popular dark theme
Default
- Uses terminal colors
- Maximum compatibility
jflow uses jj's revset language under the hood:
// Your stack
"::@ ~ ::main@origin"
// Changes with bookmarks
"bookmarks() & (::@ ~ ::main@origin)"
// Changes ready for PR
"(::@ ~ ::main@origin) ~ bookmarks()"No metadata files. No state tracking. Just queries.
Via gh CLI (recommended):
[github]
method = "gh-cli"Via API token:
[github]
method = "api-token"
token = "ghp_..."# 0. Initialize jflow (first time only)
jf init
# 1. Start work (outside-in development)
jj new -m "Add REST library"
# ... implement library ...
jj new -m "Add backend API"
# ... implement API using library ...
jj new -m "Add login screen"
# ... implement UI using API ...
# 2. View your stack
jf status
# Output:
# โญโ Your Stack โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
# โ โ xyz789 Add login screen โ
# โ ๐ก ready to create PR โ
# โ โ def456 Add backend API โ
# โ ๐ก ready to create PR โ
# โ โ abc123 Add REST library โ
# โ ๐ก ready to create PR โ
# โ โ main@origin โ
# โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
# 3. Create PRs from bottom up (inside-out review)
jf pr abc123 rest-library
jf pr def456 backend-api
jf pr xyz789 login-screen
# 4. Teammate reviews library PR and requests changes
# Edit the library commit directly
jj edit abc123
# ... make changes ...
# 5. Sync all bookmarks (library bookmark + all descendants)
jf sync
# Output:
# โน Found 3 bookmark(s) to sync
# Updated jf/rest-library โ abc123
# Updated jf/backend-api โ def456
# Updated jf/login-screen โ xyz789
# โน Pushing bookmarks to remote...
# โ Successfully synced all bookmarks!
# 6. All PRs automatically updated! ๐
# The dependent PRs (API, UI) automatically rebased on the library fix
# 7. Library gets merged
# Pull and rebase
jf pull
# Output:
# โน Fetching from origin...
# โน Rebasing stack onto main@origin...
# โ Successfully pulled and rebased!
#
# Stack now shows:
# โญโ Your Stack โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
# โ โ xyz789 Add login screen โ
# โ โ def456 Add backend API โ
# โ โ main@origin โ
# โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
# 8. Sync remaining PRs
jf sync# Morning: Pull latest changes
jf pull
# Create new work
jj new -m "Feature X"
# Check status anytime
jf status
# Create PR when ready
jf pr <change-id> feature-x
# After making any edits
jf sync
# End of day: Push latest changes
jf syncโ All Commands Implemented! โ
Currently implemented:
- โ
jf init- Initialize jflow with smart defaults - โ
jf status- Beautiful stack visualization - โ
jf pr- Create bookmark + PR (with gh CLI integration) - โ
jf sync- Update all bookmarks and push - โ
jf pull- Fetch + rebase stack
Ready to use for daily workflow!
This is an experimental project. Contributions welcome!
# Run with example
cd /path/to/your/jj/repo
jf status
# Build
cargo build
# Test
cargo testMIT
Inspired by:
- Jujutsu by Martin von Zweigbergk
- Drew Deponte's patch stack methodology
- Steve Klabnik's Jujutsu tutorial
Icons and colors from: