๐ง CLI Study Hub v5.0 โ Slash-Command Study Companion
CLI Study Hub is a terminal-first, community-driven study notebook. Every
command is a /slash-command with a live, Claude-Code-style autocomplete menu
โ start typing and matching commands pop up as you go. Notes live in this
GitHub repo, so anyone with push access gets automatic, hassle-free syncing.
A welcome banner, spinners during sync/network calls, and small emoji
celebrations for milestones (first subject, first post, streaks) make the
terminal experience feel alive โ all of it degrades to plain, instant output
when the CLI isn't attached to a real terminal (e.g. scripted/piped use), so
nothing here ever blocks automation.
๐ Install
The only real requirement is Python 3.9+. Everything else (rich,
prompt_toolkit, requests, PyPDF2, python-docx, lxml) is declared as
a normal dependency in pyproject.toml and gets pulled in
automatically by whichever installer you use below โ there's nothing to
install by hand beyond Python itself and one small installer tool.
study-cli-hub is published on PyPI,
so any of these work on macOS, Linux, or Windows:
Option A โ uv (recommended)
uv manages its own Python builds, so it isn't affected by a broken or
missing system/Homebrew Python โ the most reliable option if you've ever
had installer trouble with Python before.
# 1. Install uv itself (one time):
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
# or on Windows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# 2. Install the app:
uv tool install study-cli-hub
# ...or skip installing it permanently and just run it once:
uvx study-cli-hub
Option B โ pipx
# 1. Install pipx itself (one time):
brew install pipx && pipx ensurepath # macOS (Homebrew)
sudo apt install pipx && pipx ensurepath # Debian/Ubuntu
python3 -m pip install --user pipx && python3 -m pipx ensurepath # any other Linux/Windows
# 2. Install the app:
pipx install study-cli-hub
โ ๏ธ Known issue on macOS: if
pipx installfails withBroken Python installation, platform.mac_ver() returned an empty value, that's a bug in a specific Homebrew Python bottle (seen withpython@3.14), not withstudy-cli-hub. Point pipx at a different interpreter instead:pipx install --python /usr/bin/python3 study-cli-hub(or
--python $(brew --prefix python@3.12)/bin/python3.12if you have that version installed). If you hit this,uv(Option A) avoids the whole class of problem since it never touches your system Python at all.
Option C โ plain pip (zero extra tools, if you'd rather not install uv/pipx)
python3 -m venv ~/.study-cli-hub-venv
~/.study-cli-hub-venv/bin/pip install study-cli-hub
# then use ~/.study-cli-hub-venv/bin/study-hub, or add it to your shell's PATH/alias
Run it
Your notes are stored as files in this repo's subjects/ folder, so clone
the repo first, cd into it, then launch the app from there:
git clone https://github.com/govindmehta15/study-cli-hub.git
cd study-cli-hub
study-hub
โจ๏ธ Slash Commands & Autocomplete
Every command starts with /. As soon as you type /, a live menu of
matching commands (with a one-line description of each) appears and narrows
down as you keep typing โ just like Claude Code's slash menu. Press Tab /
Enter to accept a suggestion.
๐ Main menu
| Command | Action |
|---|---|
/study <name|number> |
Open a subject |
/create-subject |
Add a new subject with a description |
/list |
Refresh the subjects list |
/switch-user |
Switch user folder or global mode |
/explore |
Explore other users' study content (read-only) |
/search <term> |
Full-text search your and others' notes |
/quiz <name|number> |
Quiz yourself: flashcards (with spaced repetition) or AI-generated |
/stats |
Show your subjects/notes/streak dashboard (+ 7-day activity graph) |
/leaderboard |
Rank all known users by streak/activity |
/digest |
See what's new since your last visit |
/pomodoro [minutes] |
Run a focus-session countdown (default 25 min) |
/export [json|csv] |
Back up your subjects/notes/stats to a file |
/feed |
Browse the global knowledge feed |
/chat <username> |
Open an async chat with another user |
/login |
Connect your GitHub account |
/logout |
Disconnect your GitHub account |
/whoami |
Show the connected GitHub account |
/sync |
Pull + push notes with GitHub right now |
/help |
Show this command list |
/exit |
Exit (auto-syncs with GitHub) |
๐ Inside a subject
| Command | Action |
|---|---|
/read <note|number> |
Open a note in the interactive reader |
/edit <note|number> |
Edit a note with reason tracking + backup |
/new-note |
Create a new note file |
/upload |
Upload a file via the interactive file browser |
/repair <path> |
Diagnose a Word document's issues |
/help |
Show this command list |
/back |
Return to the subjects menu |
๐ Inside the interactive reader / document viewers
โ/โork/jโ scroll line by linePgUp/PgDnoru/dโ jump multiple linesSPACE/hโ highlight/unhighlight the current line/โ search within the filen/pโ next/previous search resulttโ toggle paragraphs/tables (DOCX only)qโ quit back to the subject menu
๐ Community: explore, feed, comments, and chat
These features solve a different problem than the git-synced subjects/
notes: no collaborator permissions, and no merge conflicts. Instead of
writing shared files, they read/write GitHub Discussions
on this repo. Any GitHub account can post or comment on a public repo's
Discussions without being added as a collaborator, and there's no file to
merge โ GitHub's API is the single source of truth, so two people posting at
the same time can never conflict.
/exploreโ browse other users'subjects/folders read-only (no GitHub login needed; it just reads the files already synced into this repo)./search <term>โ full-text search across your own notes, every "global" subject, and (read-only) everyone else's notes โ no login needed, it's pure local file search./feedโ a global text feed./postto share something,/comment <number> <text>to reply to someone else's post,/react <number> <emoji>to react with ๐โค๏ธ๐๐๐๐๐ (e.g./react 2 heart, or/react 2.1 laughto react to comment 1 on post 2). Requires/login./chat <username>โ an async 1:1 thread with another GitHub user, one canonical thread per pair regardless of who starts it. It's not real-time โ run/chat <username>or/refreshagain later to pick up replies, same as checking a GitHub Discussion for new comments./react <number> <emoji>works on messages too. Requires/login./digestโ "what's new since your last visit": new feed posts/comments and new chat messages. Compares against a timestamp stored locally on your own machine (~/.config/study-cli-hub/state.json) โ deliberately not synced to the repo, since your read-receipts aren't anyone else's business and syncing them would just create pointless git noise. Requires/login.
These need GitHub Discussions enabled on this repo (Settings โ General โ Features โ Discussions). The CLI looks for categories named "Feed" and "Chat"; if they don't exist yet it falls back to whatever category is available (e.g. "General"), so there's nothing else to configure to get started โ creating those two categories is optional polish for keeping the Discussions tab organized.
๐ Stats, streaks & the leaderboard
/stats shows your subject/note counts and your daily activity streak โ
computed entirely from git log on your own subjects/<username>/ folder,
not from a separate tracking file. That means it can't drift from reality,
gives you retroactive credit for history already in the repo, and needs
zero GitHub API calls for /leaderboard to rank every known user by the
same numbers.
Two honest limitations:
/statsand/leaderboardneed a personal user folder (/switch-userto one) โ Global mode has no identity to attach a streak to.- The streak reflects commit dates in your local clone's history, so it
needs a normal (non-shallow)
git cloneโ exactly what this README's clone instructions already do. It's also not tamper-proof (nothing stops backdating a commit), which is fine for a casual gamification feature, not a strict requirement.
๐ Flashcards, spaced repetition, focus timer & export
/quiz <subject> picks up flashcards from any note with Q: .../A: ...
lines โ no setup needed. In flashcards mode, after you grade your own recall
1 (blackout) to 5 (perfect), a simplified SM-2
scheduler decides when that exact card should come back (a card you nail
gets pushed days out; one you miss comes right back tomorrow). Scheduling
state lives in a small .srs_state.json file per subject, git-synced
alongside your notes โ no database, same plain-file model as everything
else here. If some cards are due and others aren't, /quiz offers to study
just the due ones; if nothing's due yet, it lets you practice the full set
anyway.
/pomodoro [minutes] (default 25) runs a live countdown you can Ctrl+C
out of early, then fires a best-effort desktop notification (macOS/Linux/
Windows) plus a small celebration when it completes. It's a foreground
countdown, not a background timer that ticks in a corner while you keep
typing elsewhere โ the fixed-layout TUI can't safely have something else
write to the screen mid-render, so this is the safe fit for now.
/export [json|csv] (default json) writes your subjects, notes, stats, and
SRS progress to a plain file in your current directory โ a portable backup
that needs nothing but a text editor or spreadsheet to read, on purpose:
this app never wants to be the only place your data can live.
๐ Connect your GitHub account
Run /login once. It starts GitHub's Device Flow:
- The CLI shows a one-time code and a URL (
github.com/login/device). - Open the URL in any browser (phone or laptop) and enter the code.
- Approve access โ the CLI picks up the token automatically and stores it
locally at
~/.config/study-cli-hub/credentials.json(readable only by you).
From then on, /sync and the automatic pull-on-start/push-on-exit use your
GitHub login instead of relying on locally configured SSH keys or cached
credentials โ so any collaborator can clone the repo and start syncing
immediately after /login, with no extra git configuration.
Using the app is auto-approved for anyone โ changing the app's code is not. These are two different things and the CLI treats them differently:
- Using the app (creating subjects, notes, feed posts) only ever touches
files under
subjects/<your-username>/. If you're a collaborator,/syncpushes those changes straight tomain. If you're not a collaborator,/syncautomatically forks this repo under your own GitHub account, pushes your notes there, and opens a pull request back here โ no need to ask anyone for access first. A GitHub Action (.github/workflows/auto-merge-data-prs.yml) checks that the PR only touchessubjects/**and auto-approves + auto-merges it. You'll never see a pending-review screen just for adding your own notes. - Changing the app's code (anything under
study_cli_hub/,pyproject.toml, workflows, this README) always requires a real pull request reviewed by a maintainer โ enforced by branch protection onmainplus.github/CODEOWNERS. The auto-merge Action above only fires for PRs that are 100%subjects/**; anything touching code is left for manual review, full stop.
Hassle-free with many users pushing at once: if two people run /sync
around the same time, the second push gets rejected (git's normal
non-fast-forward check). The CLI handles this automatically โ it pulls with
--rebase and retries the push (up to 3 times) without you doing anything.
Because every user only ever writes inside their own subjects/<username>/
folder, this almost always resolves cleanly on its own. The one case it
can't: two people editing the exact same lines of the exact same file โ that
surfaces a clear "needs a human" message with the exact git commands to
resolve it, instead of silently discarding anyone's work.
Use /whoami to check who's connected and /logout to disconnect.
๐ /login's OAuth App
/login works out of the box โ no setup needed. It uses a GitHub OAuth App
(Device Flow enabled) whose Client ID is baked into
study_cli_hub/github_auth.py (DEFAULT_GITHUB_CLIENT_ID). This is a public
identifier, not a secret โ no client secret is ever used or needed for
Device Flow โ so it's safe to commit and ship in the published package.
Running your own fork against a different OAuth App? Override it without touching the code:
export STUDY_HUB_GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx
(register your own at github.com/settings/developers โ New OAuth App, with "Enable Device Flow" checked).
๐ก๏ธ Maintainer setup: branch protection on main
This repo's main branch requires a pull request for every change, including
the maintainer's own โ enforced via GitHub branch protection with
.github/CODEOWNERS requiring review on code paths. Data-only PRs
(subjects/**) skip human review entirely via the auto-merge Action above;
everything else needs a real review.
One unavoidable GitHub limitation to know about: with a single collaborator
on the repo, there's nobody else who can approve your own code PRs. This
repo has enforce_admins turned on, so โ unlike the usual
solo-maintainer OSS pattern โ there is no admin-bypass button here either:
gh pr merge --admin is flatly rejected with "Waiting on code owner
review," the same as anyone else's PR. That's deliberate (real second-person
review on every code change, no exceptions), but it does mean every
code PR needs an actual approval from a @govindmehta15/@govind-m15
review before it can merge โ plan for that, don't expect to self-merge.
Your own day-to-day push workflow
git push on main always fails with GH006: Protected branch update failed โ that's the protection working as intended, not a bug. Push a
branch and open a PR instead:
git checkout -b my-change
git push -u origin my-change
gh pr create --fill
# then get it reviewed/approved by a code owner before merging:
gh pr merge --squash
If you want a true self-mergeable admin bypass in the future, that requires
turning enforce_admins off in branch protection settings first โ a
deliberate trade-off against the "no exceptions" review guarantee, so change
it consciously rather than reaching for --admin expecting it to work.
๐ฆ Publishing a new release (maintainers)
study-cli-hub is already live on PyPI via a one-time Trusted Publisher link (no API tokens stored anywhere). Shipping a new version is just:
- Bump
versioninpyproject.toml, land it through the normal code-review PR flow (see Contribution Guide). gh release create vX.Y.Z --generate-notes(or via the GitHub UI).- That's it โ
.github/workflows/publish.ymlbuilds and uploads automatically.uv tool install study-cli-hub/pipx upgrade study-cli-hubpick up the new version immediately.
๐งฉ Project Layout
study-cli-hub/
โโโ pyproject.toml # Package metadata + `study-hub` console script
โโโ study_cli_hub/
โ โโโ cli.py # Slash-command REPL (main entry point)
โ โโโ completer.py # Live '/' autocomplete menu
โ โโโ github_auth.py # Device Flow login + token-authenticated git sync
โ โโโ community.py # Feed/comments/chat/reactions via GitHub Discussions (permission-less, conflict-free)
โ โโโ search.py # Full-text search across your and others' notes
โ โโโ stats.py # git-log-derived streak/leaderboard/activity-graph stats (zero API calls)
โ โโโ srs.py # Simplified SM-2 spaced repetition for /quiz flashcards
โ โโโ pomodoro.py # Focus-session countdown + best-effort desktop notification
โ โโโ exporter.py # /export - JSON/CSV backup of subjects/notes/stats/SRS progress
โ โโโ local_state.py # Personal, per-device "last seen" markers for /digest (not git-synced)
โ โโโ animations.py # Typewriter/spinner/celebration primitives (degrade to plain output non-interactively)
โ โโโ contribute.py # Fork + auto-PR fallback for non-collaborators (hassle-free app usage)
โ โโโ tui.py # Fixed-layout TUI shell (pinned input + toolbar) for the main menu
โ โโโ file_viewer.py # Scrollable viewers (text/PDF/DOCX/CSV) with highlighting
โ โโโ file_uploader.py # Interactive file browser + upload
โ โโโ doc_repair.py # Word document diagnostics
โ โโโ error_handler.py # Centralized error logging
โ โโโ paths.py # Subject/user folder path helpers
โโโ subjects/ # All study notes (synced to GitHub)
โ โโโ GlobalSubject/
โ โ โโโ description_GlobalSubject.txt
โ โ โโโ note1.txt
โ โโโ <username>/
โ โโโ <Subject>/
โโโ .github/workflows/publish.yml
๐ฅ Contribution Guide
Adding study notes โ no setup beyond /login:
git clone https://github.com/govindmehta15/study-cli-hub.git && cd study-cli-hubpipx install study-cli-hub(orpipx install -e .for a live-editable install), thenstudy-hub/loginonce, then add subjects/notes as usual./syncor/exitโ auto-commits, and auto-forks + opens a PR for you if you're not a collaborator. Either way, notes-only changes auto-merge with no wait.
Changing the app's code โ needs an actual review, so use the normal GitHub flow:
- Fork the repository.
- Clone your fork and run
pipx install -e .for a live-editable install. - Make your change, commit, push to your fork.
- Open a Pull Request โ a maintainer (per
.github/CODEOWNERS) will review it.
๐ For Non-CLI Users
Browse all study notes directly on GitHub under /subjects โ
each subject has a description file and notes in readable formats, viewable
on desktop or mobile without installing anything.
๐งฐ Requirements
- Python โฅ 3.9 โ the only hard requirement. Every other Python package
(
rich,prompt_toolkit,requests,PyPDF2,python-docx,lxml) is installed automatically byuv/pipx/pipโ you never install these by hand. - Git โ for cloning the repo and for
/syncto work. uvorpipx(recommended, not strictly required) โ see Install above for exact commands per OS. Option C shows how to install with plainpipand no extra tool at all, if you'd rather not.
โค๏ธ About the Project
CLI Study Hub is an open-source educational project for technical learners: structured, subject-wise notes, studied efficiently from the terminal, kept in sync on GitHub, and easy to contribute to.
๐ Built for learners, by learners โ one note at a time.
๐ง Author & Community
Created by: Govind Mehta ๐ India ๐ฎ๐ณ
โญ Star on GitHub and share with your study community!
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file study_cli_hub-5.1.1.tar.gz.
File metadata
- Download URL: study_cli_hub-5.1.1.tar.gz
- Upload date:
- Size: 70.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0ec086d014dd5c0c23780faeefba24306e47c4906e26e16ba4bd62695c666fe
|
|
| MD5 |
3b431780300cf52f4e41da4cbeeab369
|
|
| BLAKE2b-256 |
941563daed9e75f99967093373271d0038384f0f4e742c9cfe23cbd60af4c024
|
Provenance
The following attestation bundles were made for study_cli_hub-5.1.1.tar.gz:
Publisher:
publish.yml on govindmehta15/study-cli-hub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
study_cli_hub-5.1.1.tar.gz -
Subject digest:
a0ec086d014dd5c0c23780faeefba24306e47c4906e26e16ba4bd62695c666fe - Sigstore transparency entry: 2339488705
- Sigstore integration time:
-
Permalink:
govindmehta15/study-cli-hub@e68aabf6f1a47810087cf7919980ea0b1a0f845a -
Branch / Tag:
refs/tags/v5.1.1 - Owner: https://github.com/govindmehta15
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e68aabf6f1a47810087cf7919980ea0b1a0f845a -
Trigger Event:
release
-
Statement type:
File details
Details for the file study_cli_hub-5.1.1-py3-none-any.whl.
File metadata
- Download URL: study_cli_hub-5.1.1-py3-none-any.whl
- Upload date:
- Size: 69.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b92bee072358cc0f973526da90f1388703df892cb8a6e8261672bd4a54a62587
|
|
| MD5 |
904ed1a904c86213a88ca4cad087b0ac
|
|
| BLAKE2b-256 |
a247a992d8da97453abf6f6e6dc7078542b41e9236405ca312633299d23f2433
|
Provenance
The following attestation bundles were made for study_cli_hub-5.1.1-py3-none-any.whl:
Publisher:
publish.yml on govindmehta15/study-cli-hub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
study_cli_hub-5.1.1-py3-none-any.whl -
Subject digest:
b92bee072358cc0f973526da90f1388703df892cb8a6e8261672bd4a54a62587 - Sigstore transparency entry: 2339488717
- Sigstore integration time:
-
Permalink:
govindmehta15/study-cli-hub@e68aabf6f1a47810087cf7919980ea0b1a0f845a -
Branch / Tag:
refs/tags/v5.1.1 - Owner: https://github.com/govindmehta15
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e68aabf6f1a47810087cf7919980ea0b1a0f845a -
Trigger Event:
release
-
Statement type: