CLI-Inbox banner

CLI-Inbox

13 devlogs
38h 7m 43s

A terminal-based Gmail client written in Python. Read, write, and manage your emails inside your terminal. (uses IMAP + SMTP)

This project uses AI

[from README.md]
This project was developed with selective use of AI assistance. Most of the implementation was done independently, with AI mainly used for:

resolve_label function (main.py)
When implementing threaded conversation support, there was an issue with message IDs and IMAP label targeting.

Demo mode (demo.py)
The demo mode ended up being significantly harder than expected. AI was asked for a suggestion on how to approach the problem, and it suggested using a ‘monkey patching’ technique. Additional help was needed for thread handling inside demo mode.

Minor bug fixes
Some other minor bugs and not working stuff was debugged with AI assistance, there were some issues with attachments, labels, and email rendering, and some more that I don’t remember.

Documentation
The README was partially generated by AI and then modified to ensure accuracy.

Used ChatGPT and Github Copilot (mainly for inline suggestions)

Demo Repository

Loading README...

artur33

Shipped this project!

Hours: 38.1
Cookies: đŸȘ 533
Multiplier: 13.98 cookies/hr

After about 2/3 weeks of working on it, I’m shipping CLI-Inbox!!
It’s a Gmail client that runs in your terminal. You can read full email threads, write and send emails with a proper terminal text editor, reply, forward, manage drafts, search, create and manage labels, download attachments, attach files when composing, and switch between multiple Gmail accounts.
I thought I didn’t have much time, but then Flavortown got extended so I took it easier lol (so yeah, I thought this to be my last ft project, but now I don’t think so, hihi).
IMAP is genuinely one of the messiest things bruh (I mean, this protocol has so many quirks and edge cases uhh, all the ID issuessss aaaaaa), also the Label handling was painful because they depend on the language of your gmail account, then thread handling also caused a lot of problems (there was a bug with message IDs and label targeting when fetching threads), THEN THE DEMO MODE was genuinely harder than I expected
 making it behave like a real IMAP/SMTP backend without actually connecting to anything required monkey patching, which I had never done before [If you’re trying the project, please just use a real account, the demo is more of a “look what the UI looks like” thing than a perfect simulation].
The last devlog was almost entirely bug fixes and stuff, omg, this was so annoying aaah, I’m sure that there are some other bugs, so please find them and tell meee, uhhh.
Anyway, I discovered the “rich” library, I found it kind of by accident when I was trying to figure out how to make a decent table layout in the terminal, it works fine yeah, and it’s pretty easy to use (I’ve also seen Textual now, which is basically “rich” but for full TUI applicationssss! ).
Also, email as a format is way more complex than it looks from the outside: HTML emails, multipart messages, attachments encoded in base64, quoted-printable encoding, timezone differences, threads linked by message IDs, etc. there’s a lot going on behind an email lol, that was interesting to discover :)
I’m proud of, uhm, just that it works, it actually works, that’s pretty enough for me, hah, there are all the basic features of an email client and it’s usable, so that’s what makes me proud. I also tried to keep the codebase clean which made it easier to keep building without getting too lost (unlike my first ft project, where I got completely lost in the codebase
).
Oh and last thing, maybe someday I will add an Outlook support, I wanted to add it but honestly Gmail was already enough complexity, so yeahhhh, maybe I’m just lazyyy.
Anyway, time to ship it nowwww :D

artur33

Added/Fixed:

  • Fixed demo message ordering and missing fields
  • Ensured CC/BCC default values are always present in demo mode
  • Corrected label iteration logic
  • Improved star/unstar handling (keeps Starred and All Mail in sync) in demo mode
  • Improved trash/delete flow in demo mode and added untrash command
  • Null/invalid correct fetch
  • Version info command
  • Improved help command message
  • Alias system improved (argument expansion)
  • Account credential validation with retry flow
  • Demo mode now shows a clear prompt indicator
  • Escapes rendered headers to prevent markup injection issues
  • In general A LOT of bug fixes, small improvements, and random stufff, I just can’t list them all, these are the most important ig
  • Wrote the README (with AI help)
  • Added ‘requirements.txt’
  • Added banner and icon
  • Created the executable (with Pyinstaller ‘cliinbox.spec’)
  • Tested if everything works

Note: Last devlog for this project yay . This one took some time because it’s mostly fixes, edge cases, and making everything work somehow. Not the most “visible” update, but probably one of the most important for the usability lol. Overall, well, I’m really happy with how this turned out. It became a fully usable CLI email client, I also wanted to do an Outlook support, buuuuuut yeah, I just decided to let it be only for Gmail. It’s not perfect (demo mode is still a bit strange), but it’s definitely something I can actually improve sometime. Also yeah, I learned especially about IMAP weirdness, email stuff, and CLI UI/UX (I discovered Rich, and
 I’ve seen Textual, hmmmmm, there is another month for cooking, who knowsss, maybe the next project will be using this framework, ehe, we’ll see :) )

Next:

  • SHIPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
Attachment
0
artur33

Added/Fixed:

  • Draft system implemented (“compose” UI now supports saving drafts when cancelling writing)
  • New command ‘edit’ to modify/send drafts
  • Compose workflow now lets modifing the To, CC, BCC and Subject fields
  • IMAP and demo helpers for saving and deleting drafts
  • Command alias system implemented (allows custom shortcuts for commands)
  • New commands: ‘alias’ and ‘unalias’
  • Command parser now resolves aliases automatically, btw this is the same behaviour as one of my previus project, so yeah :p
  • Minor fixes and refactorss

Next:

  • BUG FIXINGGG
  • Testttttttttttt
  • Make an executable
  • Shipppppppppppppppppppppppppppppppppppp
0
artur33

Added/Fixed:

  • Label management system implemented
  • Commands to create, delete, rename, set, and unset labels
  • Demo mode added (allows running the client without real credentials) (demo.py) (use the --demo flag to start in demo mode) (the email in demo mode is: [email protected])

Note: The label system was actually done in like
 30 minutes, the rest of the time was spent on the demo mode. At first I thought it would be easy but uhm
 no. I ended up using AI for a suggestion on how to approach it, and it (chatgpt) suggested using a ‘monkey patch’ technique. I spent some time understanding how that works and then implemented it. It was kinda ok in the end, I only needed some help for the threads inside demo mode. And yeah, it works, but it’s still a bit buggy and weird in some cases AAAAAAAAAAAA
 it’s DEFINITELY better using a real accounttt, so please use a real accounttt.

Next:

  • Other things that come to my mind?
  • BUG FIXINGGG
  • Testtttt
  • Make an executable
  • Shipppppppppp
0
artur33

Added/Fixed:

  • Multi account support implemented (keyring stores multiple email accounts (ONLY GMAILLL))
  • Commands to add, list, switch, and remove accounts
  • Accounts are automatically set as active when used (fixed bugs and stuff with this)
  • New settings added: auto_mark_read and default_label
  • Settings loader now merges defaults to support updates without breaking anything
  • Added date header to emails and normalized displayed dates to the local timezone (beacuse the time in the inbox was broken)
  • Minor fixes and adjustments yee

Next:

  • Trial mode with a fake email (for testing (for the shipp))
  • Custom labels management
  • Other stuff, I still need to think

  • BUG FIXINGGG
  • Shipppp
0
artur33

Added/Fixed:

  • User settings system implemented (settings.py): for now: emails_per_page, download_folder, and signature
  • New commands (‘settings’ and ‘setting’) to view and update settings
  • Settings automatically loaded on startup and saved when modified
  • Inbox pagination now respects the emails_per_page setting
  • download_folder setting used as the destination for attachments
  • Added support for CC and BCC fields
  • Signature automatically appended to composed emails
  • Send confirmation now displays attachment details
  • Minor fixes: I found out a lot of them, but I used a bit of AI to fix them, ye :/

Next:

  • Account management
Attachment
Attachment
Attachment
Attachment
0
artur33

Added/Fixed:

  • Threaded conversation support implemented (fetches IMAP thread IDs and groups related messages) allowing viewing an entire conversation instead of single emails
  • Threads supported both in the terminal UI and browser view (‘open’ command)
  • Attachment support added (support of attaching files when composing emails)
  • Displays attachment list in the email view
  • New ‘download’ command to save attachments
  • Message dates fix
  • Resolve label resolution implemented (see Note)
  • Other fixes and stuff AAAAAAAAAAAAAAAAAA

Note: There was a issue with message IDs when I was implementing threads. I tried to reason through the IMAP behavior myself but, uhm
 yeah, in the end I used AI for helpp, it suggested the ‘resolve_label’ function that fixed the label targeting problems. This devlog was the hardesttt, uhhh sob-ios also the videos take too much of my timeee, it’s like 1 hour just to censor my email everywhere in the recordings bruhh, now I need to study, Math test tomorrow :/

Next:

  • Account management
  • Settings
0
artur33

Added/Fixed:

  • Parses HTML email parts while preserving the raw HTML content + generates a plain text fallback using the ‘html2text’ library
  • New ‘open’ command that opens an email (HTML or text) in the system browser (allowing proper viewing of complex HTML emails when the terminal view is baddd)
  • Composer modified for reply editor: now prefills quoted content from the original message
  • New ‘forward’ command to forward emails (automatically includes original message content)
  • Minor internal fixes

Note: Initially I planned to use the w3m CLI browser to render HTML emails directly in the terminal, but nothing was really working properly. In the end I went with two separate approaches: terminal display uses ‘html2text’, and the new ‘open’ command allows viewing the full HTML version in the browser.

Next:

  • Attachment download and send
  • Threaded email view
  • Account management
  • Settings
Attachment
Attachment
Attachment
1

Comments

Cyber Ninja
Cyber Ninja about 2 months ago

cool project

artur33

Added/Fixed:

  • Commands (‘next’/‘prev’/‘page’) to navigate between pages for now it’s still 20 emails per page (will do settings laterrr)
  • Star and unstar emails
  • Mark emails as unread
  • Delete emails (moves to trash)
  • Archive emails DOESN’T WORK FOR SOME REASONN I will fix in the next devlog if I can bruh
  • Automatically detects default labels used (this is because of different languages problems)
  • Shows “To” field when viewing sent emails
  • Starred messages visually highlighted in the inbox + star collumn
  • Prevents occasional decode errors when parsing messages
  • Fixed some other problems and sidebar now displays as the same height as the email part of the layout

Note: this took some time because of the ‘archive’ problem and some “gmail language” problems, hm (that’s why I added the default labels func and dict)


Next:

  • Display HTML emails properly
  • Attachment download and send
  • Account management
  • Settings
0
artur33

Added/Fixed:

  • Email search functionality implemented (search results update the active message list)
  • New ‘search’ command
  • Labels now integrated directly into the main inbox view layout (responsive for wider terminals)
  • Small layout and rendering fixes

Next:

  • Star, delete, archive and mark unread actions
  • Display HTML emails properly
  • Attachment download and send
  • Account management
  • Settings
Attachment
0
artur33

Added/Fixed:

  • Label support implemented (lists available labels over the inbox, switching between labels using the ‘label’ command + fixed all the million IMAP problems -> that’s because I’m baka dev, the fix was easy, just separating the ‘name’ and ‘display’ in get_labels func
)
  • Message flags now fetched from IMAP
  • Unread emails are now bold in the UI inbox
  • Emails automatically marked as “seen” when opened
  • Threaded reply fixes (but still incomplete) (replying to emails preserves parent references)
  • Minor rendering improvements in the inbox and other stuff

Next:

  • Email search functionality
  • Star, delete, archive and mark unread actions
  • How can I display HTML emails
?
0
artur33

Added/Fixed:

  • Email compose functionality implemented (interactive terminal editor to write new emails (used prompt_toolkit library))
  • SMTP integration for sending emails
  • Reply support added (automatically fills recipient and subject)
  • Message IDs now displayed in inbox listing
  • Screen clears before commands for a TUI-like flow

Next:

  • Switch between Inbox, Sent, Spam, ecc.
  • Read indicators and behaviour
  • Email search functionality ye
0
artur33

Added/Fixed:

  • Inbox and email UI rendering using the “rich” library (table layout and formatted email display) (ui.py)
  • Inbox fetch limit increased (I’ll need to make a setting for this)
  • New ‘view’ command to open a specific email by ID
  • Email parsing improvements
  • Date formatting func

Note: I discovered the “rich” library while working on the UI and
 wow, it saves a lot of time for tables. Feels much more polished with very little effort
 incredible, why I haven’t discovered it earlier bruhh :/

Next:

  • Add compose and send email functionality (with SMTP)
  • Switch between Inbox, Sent, Spam, ecc.
Attachment
0
artur33

Note: This project started as a small experiment to see how practical a CLI email client could be lol, I don’t have much time left so I think I will need to grind it, ehe

Added/Fixed:

  • Basic project structure split into modules (main, mail, auth and utils)
  • Simple command loop with command parsing (basically the same as one of my previous projects)
  • Gmail IMAP integration
  • Account setup flow added for first run (Email and password are stored securely using the system keychain (via the ‘keyring’ Python library), and the credentials automatically load on subsequent runs.
  • Login using Google App Passwords
  • Inbox basic fetching implemented (retrieves the latest emails from the inbox (for testing noww))
  • Colored status messages (info, success, error)
  • Other minor additions

Next:

  • Implement a proper UI to display the inbox
  • Add compose and send email functionality (with SMTP)
Attachment
0