Skip to content

Instantly share code, notes, and snippets.

@eonist
Created December 28, 2025 15:53
Show Gist options
  • Select an option

  • Save eonist/84a9053e9cd7f95ce719a315faabc2e1 to your computer and use it in GitHub Desktop.

Select an option

Save eonist/84a9053e9cd7f95ce719a315faabc2e1 to your computer and use it in GitHub Desktop.
terminal interactive segmentation

Here's how the terminal-only flow would work, following patterns similar to git add -p and git rebase -i:[1][2]

Initial Invocation

$ git add .
$ omni --segment

Interactive Terminal Flow

Step 1: Initial Analysis Screen

Analyzing changes... Done!
Found 10 modified files. Suggested 3 commits.

┌─────────────────────────────────────────────────────────┐
│ Commit Segmentation (3 commits from 10 files)          │
└─────────────────────────────────────────────────────────┘

  1. [✓] refactor: authentication system (4 files)
  2. [ ] feat: API v2 endpoints (3 files)  
  3. [ ] test: auth coverage and docs (3 files)

Commands: [n]ext [p]rev [e]dit [s]plit [m]erge [v]iew [a]ccept [q]uit
Current: 1/3
>

Step 2: Navigation with Single-Key Commands

> e     # Edit commit 1

┌─────────────────────────────────────────────────────────┐
│ Edit Commit 1/3                                         │
└─────────────────────────────────────────────────────────┘

Title: refactor: authentication system

Message (press 'i' to edit, Esc to return):
Move JWT logic to dedicated auth service

- Extract token generation and validation to AuthService
- Add refresh token rotation mechanism  
- Implement proper error handling for expired tokens
- Update security headers and CORS configuration

Files (4):
  • src/services/AuthService.ts
  • src/middleware/authenticate.ts
  • src/utils/jwt.ts
  • src/config/security.ts

[i] Edit  [f] Move files  [Enter] Save  [Esc] Cancel

Step 3: Multi-Select for Merging

> m     # Enter merge mode

┌─────────────────────────────────────────────────────────┐
│ Merge Mode (Space to select, Enter to merge)           │
└─────────────────────────────────────────────────────────┘

  [✓] 1. refactor: authentication system (4 files)
  [✓] 2. feat: API v2 endpoints (3 files)  
  [ ] 3. test: auth coverage and docs (3 files)

Selected: 2 commits (7 files total)
Press Enter to merge, Esc to cancel
>

Step 4: Split Flow[2]

> s     # Split commit 2

┌─────────────────────────────────────────────────────────┐
│ Split: feat: API v2 endpoints (3 files)                │
└─────────────────────────────────────────────────────────┘

Select files for FIRST commit (Space to toggle, Enter when done):

  [✓] src/api/routes/users.ts
  [✓] src/api/routes/profile.ts  
  [ ] src/middleware/apiVersion.ts

Remaining files will go to second commit.
>

Step 5: Quick View Mode

> v     # View all commits summary

┌─────────────────────────────────────────────────────────┐
│ Commit Summary                                          │
└─────────────────────────────────────────────────────────┘

Commit 1: refactor: authentication system
  4 files | 156 additions, 89 deletions

Commit 2: feat: API v2 endpoints  
  3 files | 234 additions, 12 deletions

Commit 3: test: auth coverage and docs
  3 files | 445 additions, 0 deletions

Total: 835 additions, 101 deletions across 10 files

[Enter] Return  [a] Accept all  [q] Quit

Step 6: Final Acceptance

> a     # Accept and create commits

Creating commits...
✓ Created: refactor: authentication system (8a3f2d1)
✓ Created: feat: API v2 endpoints (9bc4e8a)  
✓ Created: test: auth coverage and docs (7f1a5c2)

Done! 3 commits created.

Alternative: Stream-Based Flow (No TUI)[3]

For scriptability and simpler terminals, a more traditional prompt-based approach:

$ omni --segment

Commit 1/3: refactor: authentication system (4 files)
Edit title? [y/N]: n
Edit message? [y/N]: y
<opens $EDITOR>
Include in final commits? [Y/n]: y

Commit 2/3: feat: API v2 endpoints (3 files)  
Edit title? [y/N]: n
Edit message? [y/N]: n
Include in final commits? [Y/n]: y

Commit 3/3: test: auth coverage and docs (3 files)
Edit title? [y/N]: n  
Edit message? [y/N]: n
Include in final commits? [Y/n]: y

Summary:
  3 commits will be created
  10 files across all commits
  
Proceed? [Y/n]: y
✓ Done!

Key Terminal UX Patterns Used[4][5]

Single-character commands - Like git add -p with y/n/s/q responses, keeping interactions fast[2]

Editor integration - Opening $EDITOR for longer text like commit messages, following Unix conventions[3]

Visual selection states - Using [✓] and [ ] for checkbox states, > for current position

Escape hatches - Always providing q to quit, Esc to cancel, consistent with vim/less patterns[6]

Status indicators - Progress like "1/3", file counts, and what's currently selected

Command bar - Persistent reminder of available commands at bottom, similar to nano or htop[7]

The TUI approach uses libraries like ncurses or modern alternatives (bubbletea for Go, blessed for Node) to handle cursor positioning and screen updates without full redraws. The simpler prompt-based flow works in any terminal and remains scriptable.[8][5][6][3]

1 2 3 4 5 6 7 8 9 10

@eonist
Copy link
Author

eonist commented Dec 28, 2025

Here's what a pure terminal/CLI flow would look like for omni --segment, inspired by tools like git add --interactive and git add --patch:[1][2]

Terminal-Based Flow

Initial Command

➜ git add .
➜ omni --segment

Analyzing changes...
Found 12 files changed, 482 insertions(+), 103 deletions(-)

Proposing 4 logical commit segments...

Main Interactive Menu

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OMNI SEGMENT - Interactive Commit Builder
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 Segment #1 [x] refactor(auth): decouple user service
             └─ 2 files: auth.ts, user-service.ts

 Segment #2 [ ] feat(ui): update login form validation
             └─ 2 files: login.tsx, types/schema.ts

 Segment #3 [ ] chore: clean up legacy api utils  
             └─ 2 files: api-client.ts, utils.ts

 Segment #4 [ ] style: adjust padding on modal container
             └─ 2 files: global.css, Modal.tsx

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Commands:
  [1-4]  View/edit segment    [m]  Merge segments
  [t]    Toggle selection     [s]  Split segment
  [a]    Accept all & commit  [d]  Discard changes
  [q]    Quit without commit  [?]  Help

What now> _

Editing a Segment (Press 1)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 SEGMENT #1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Title:
  refactor(auth): decouple user service

Description:
  Separates the user fetching logic from the main 
  authentication loop.
  
  Moves fetchUserById to user-service.ts to prevent 
  circular dependencies detected during build.

Files (2):
  • auth.ts                    [+82, -34]
  • user-service.ts            [+45, -12]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  [e] Edit message    [f] View file diffs    [s] Split
  [x] Mark done       [d] Discard            [<] Back

Action> _

Editing Message (Press e)

# Edit commit message (Ctrl+D or :wq to save)
# Lines starting with # will be ignored
#
# Files included in this commit:
#   auth.ts
#   user-service.ts

refactor(auth): decouple user service

Separates the user fetching logic from the main 
authentication loop.

Moves fetchUserById to user-service.ts to prevent 
circular dependencies detected during build.

~
~
[EDITOR MODE - Press i to insert, ESC then :wq to save]

Merging Segments (Press m from main menu)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 MERGE SEGMENTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Select segments to merge (space to toggle, enter when done):

  [x] Segment #2: feat(ui): update login form validation
  [x] Segment #3: chore: clean up legacy api utils  
  [ ] Segment #4: style: adjust padding on modal

Selected: 2 segments

Press [Enter] to merge, [Esc] to cancel

Splitting a Segment (Press s while viewing segment)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 SPLIT SEGMENT #1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Current files in segment:
  [x] auth.ts                    [+82, -34]
  [x] user-service.ts            [+45, -12]

Select files for NEW segment (space to toggle):

  New Segment A:
    ✓ auth.ts

  New Segment B:
    ✓ user-service.ts

Press [Enter] to confirm split, [Esc] to cancel

Final Confirmation

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 REVIEW & COMMIT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Ready to create 4 commits:

  1. refactor(auth): decouple user service
     └─ 2 files

  2. feat(ui): update login form validation  
     └─ 2 files

  3. chore: clean up legacy api utils
     └─ 2 files

  4. style: adjust padding on modal container
     └─ 2 files

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Confirm? [Y/n] _

Execution

Creating commits...

✓ [a3f8b2c] refactor(auth): decouple user service
✓ [d9e1f3a] feat(ui): update login form validation
✓ [c7b5a89] chore: clean up legacy api utils
✓ [e4d2c96] style: adjust padding on modal container

4 commits created successfully!

Key Terminal UX Patterns Used

Single-letter commands - Like git add -p (y/n/s/q), quick actions without Enter[2]

Numbered menus - Like git add -i, select items by number[1][2]

Toggle selection - Spacebar to select multiple items (common in terminal file managers)

Visual indicators - Box drawing characters (━│└) and symbols ([x], , - ) for clarity[3]

Editor integration - Drop into $EDITOR for multiline text editing[1]

Hierarchical navigation - Back/forward navigation through menus with < or Esc

Confirmation prompts - Standard [Y/n] for destructive actions

This approach feels native to terminal users because it follows established patterns from tools like git add -i, apt, npm init, and other interactive CLI tools.[2][1]

1
2
3
4
5
6
7
8
9
10

@eonist
Copy link
Author

eonist commented Dec 28, 2025

Here's how the entire flow would work in a pure terminal interface .

Two Approaches

1. Interactive TUI (Terminal User Interface)

Uses frameworks like blessed (Node.js), charm (Rust), or rich/textual (Python) to create a split-pane interface directly in the terminal:

  • Left pane: List of commits with arrow key navigation
  • Right pane: Live-updating commit message editor
  • Keyboard shortcuts:
    • ↑/↓ or j/k to navigate
    • Space to multi-select
    • m to merge selected commits
    • s to split a commit
    • a to accept all
    • q to quit

The split happens with modal overlays for merge/split operations, all rendered with Unicode box-drawing characters .

2. Simple Prompt-Based Flow

For minimal dependencies, use sequential prompts (like inquirer or promptui):

  • Shows one commit at a time with a menu of actions
  • User navigates through commits sequentially
  • Each commit presents options: accept, edit, merge, split, skip
  • Final confirmation before creating all commits

Key Differences from GUI

  • No mouse: Everything is keyboard-driven
  • State persistence: The TUI maintains state across keypresses
  • Editor integration: Could open $EDITOR (vim/nano) for long descriptions instead of inline editing
  • Faster: No window launching overhead—instant response
  • SSH-friendly: Works perfectly over remote connections

The TUI approach mimics tools like lazygit, tig, or htop where you get a rich visual interface without leaving the terminal .

# TERMINAL-BASED FLOW FOR OMNI SEGMENT

## Initial Command
~/projects/acme-dashboard (feature/api-refactor)
$ git add .
$ omni --segment

⠋ Analyzing changes... 10 files → 3 logical commits


## Interactive TUI View (using terminal UI framework)

┌─ omni segment ──────────────────────────────────────────────────────────────┐
│ ◉ acme-dashboard · feature/api-refactor                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│  COMMITS (3)                    │  COMMIT MESSAGE                            │
│                                 │                                            │
│  ▸ [1] refactor: extract API... │  Title:                                   │
│    4 files                      │  ┌────────────────────────────────────┐   │
│                                 │  │ refactor: extract API client into  │   │
│    [2] refactor: migrate to ... │  │ standalone module                  │   │
│    3 files                      │  └────────────────────────────────────┘   │
│                                 │                                            │
│    [3] chore: update imports... │  Description:                             │
│    3 files                      │  ┌────────────────────────────────────┐   │
│                                 │  │ Move all API-related logic from    │   │
│                                 │  │ scattered components into a        │   │
│                                 │  │ centralized api/ directory.        │   │
│                                 │  │                                    │   │
│                                 │  │ - Create src/lib/api/client.ts     │   │
│                                 │  │ - Add src/lib/api/endpoints.ts     │   │
│                                 │  │ - Implement interceptors           │   │
│                                 │  │ - Add retry logic           

@eonist
Copy link
Author

eonist commented Dec 28, 2025

A fully-terminal version would feel like a mix of git add -p (interactive review/splitting) and a fuzzy multi-select picker like fzf (select many with Tab/Shift-Tab), plus an editor step for commit messages.[1][2][3]

Option A: Full-screen TUI (still terminal)

This is a “curses”/TUI screen inside the terminal (no separate macOS window), where the left list, preview, and editor are just panes.[4][3]

Flow (example transcript):

acme-web % git add .
acme-web % omni segment
# omni scans staged diff and suggests 3 segments

┌ omni --segment ───────────────────────────────────────────────────────────────┐
│ Segments (TAB multi-select)             Preview / Message                     │
│                                                                              │
│ [x] SEG-01 refactor(auth): extract S...   Title: refactor(auth): extract ...  │
│ [ ] SEG-02 feat(auth): enforce rotat...   Body:                               │
│ [ ] SEG-03 chore: run formatter, fix...   - Why: ...                          │
│                                                                              │
│ Files (for active):                                                           │
│  - src/server/routes/auth.ts                                                   │
│  - src/server/services/session-manager.ts                                      │
│  ...                                                                           │
│                                                                              │
│ Keys: j/k move · TAB select · m merge · s split · e edit · enter accept · esc cancel │
└──────────────────────────────────────────────────────────────────────────────┘

Key interactions:

  • Multi-select segments: use TAB / SHIFT+TAB style bindings (common in fzf --multi).[2][3]
  • Merge: select 2+ segments, press m → tool asks for the merged commit title/body (or opens editor).[5]
  • Split: select exactly 1 segment, press s → tool asks how to split (by file, by hunk, or by “suggested split”).[1]
  • Edit message: press e to edit title/body in an inline editor or by launching $EDITOR (like Git does for commit messages).[6]
  • Accept/cancel: Enter to apply (creates commits), Esc (or q) to abort (like quitting interactive flows).[7]

Option B: Pure prompt-by-prompt (no full-screen UI)

This version never “draws a screen”; it’s just sequential prompts, similar in spirit to patch mode asking y/n/s decisions.[7][1]

Flow (example):

acme-web % git add .
acme-web % omni segment

Proposed segments:
  1) refactor(auth): extract SessionManager + move token logic   (6 files)
  2) feat(auth): enforce rotation + add integration tests        (3 files)
  3) chore: run formatter, fix lint, update imports             (1 file)

Select segments (e.g. 1 3, or 'all'): 1 2 3
Action? [enter=continue, m=merge, s=split, v=view files, d=diff, q=cancel]: v 2
Files in segment 2:
  - src/server/services/session-manager.ts
  - src/server/middleware/auth.ts
  - test/integration/auth-refresh.test.ts

Action? ...: s 2
Split segment 2 by: [1=file groups, 2=hunks, 3=suggested] 3
Created segments:
  2a) feat(auth): enforce rotation
  2b) test(auth): add refresh-token reuse coverage

Edit messages now? [Y/n]: Y
Editing "2a" (opens $EDITOR)...

Ready to commit 4 commits. Proceed? [Y/n]: Y
✔ git commit -m "refactor(auth): extract SessionManager..." ...
✔ git commit -m "feat(auth): enforce rotation" ...
✔ git commit -m "test(auth): add refresh-token..." ...
✔ git commit -m "chore: run formatter..." ...

How “split” works in terminal

Splitting can mirror what git add -p does: “split this hunk” vs “stage this hunk”, except your tool is splitting staged changes into commit buckets instead of staging hunks. In a prompt-only version, the split step is typically: choose a segment → choose split mode → confirm the resulting two new segment titles.[7][1]

How “merge” works in terminal

Merging is just “combine selected buckets”, then edit one combined commit message. In a TUI, “merge” would be a single keystroke (m) on a multi-selection, which is exactly the kind of interaction multi-select TUIs support.[3][5]

Which version are you aiming for in practice: a full-screen terminal TUI (fzf/bubbletea-like), or a simple prompt-by-prompt flow that works even over very minimal SSH terminals?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment