Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Terminal-based academic workflow CLI: courses, lectures, problem sets, grades, dashboard, and a LaTeX figure pipeline.
Terminal-based academic workflow CLI — courses, lectures, problem sets, grades, and a status dashboard, with first-class neovim and fish integration. Compile LaTeX with
latexmk, insert Ipe figures with one keymap, and track grades from the command line.
Inspired by the late Gilles Castel.
acad is a single command-line tool for organizing notes-as-code. It manages courses, scaffolds new lectures and problem sets (in LaTeX or Org-mode), tracks grades, renders a live dashboard of recent activity, and integrates with latexmk for compilation and an Ipe pipeline for figures.
It is designed to live next to neovim (with vimtex) and fish — but the core CLI works in any shell with any editor.
pipx install acad-cli
acad init # interactive: pick a content directory
export UNI_ROOT="$HOME/academic" # add to your shell config
acad d # dashboard
If those four commands worked, you're done with setup. Jump to Usage or Editor integration.
If you don't have Python or pipx or LaTeX, keep reading.
acad itself is a small Python program. It calls out to pdflatex / latexmk for compilation, and optionally to ipe for figures and task/timew for the task panel of the dashboard.
| Requirement | Required? | What it's for |
|---|---|---|
| Python 3.9+ | yes | running acad itself |
| pipx | yes | installing acad in an isolated environment |
| TeX Live or MacTeX | yes (for compilation) | pdflatex, latexmk |
| neovim 0.9+ | recommended | the editor experience this tool is designed around |
| vimtex | recommended | LaTeX-aware editing inside neovim |
| Skim (macOS) or zathura (Linux) | recommended | synctex-capable PDF viewer |
| Ipe | optional | figure-insertion keymaps |
| Taskwarrior + Timewarrior | optional | populating the "TASKS" panel on the dashboard |
| fish | optional | the uni wrapper + aliases (any POSIX shell works for acad itself) |
macOS (recommended: Homebrew)
# Install Homebrew if you don't have it: https://brew.sh
brew install python pipx
pipx ensurepath
exec $SHELL # reload your shell so ~/.local/bin is on PATH
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install python3 python3-pip pipx
pipx ensurepath
exec $SHELL
Linux (Arch)
sudo pacman -S python python-pipx
pipx ensurepath
Windows — install Python from python.org (check "Add Python to PATH" during install), then in PowerShell:
python -m pip install --user pipx
python -m pipx ensurepath
To verify: python3 --version should print 3.9 or higher, and pipx --version should print a version number.
macOS — install MacTeX (the full distribution, ~4 GB) or BasicTeX (smaller). With Homebrew:
brew install --cask mactex # full
# or:
brew install --cask basictex # smaller
Linux (Debian/Ubuntu)
sudo apt install texlive-full # full
# or smaller subset:
sudo apt install texlive-latex-recommended texlive-latex-extra latexmk
Linux (Arch)
sudo pacman -S texlive-most texlive-latexextra
Windows — install MiKTeX.
To verify: pdflatex --version and latexmk --version should both work.
If you want the figure pipeline.
brew install --cask ipesudo apt install ipe (Debian/Ubuntu) or sudo pacman -S ipe (Arch)acad's editor integration is designed around neovim. You can use any editor, but you'll get the most out of it with nvim.
Install neovim:
brew install neovimsudo apt install neovim (note: distro versions are sometimes old — for the latest, use the official AppImage or bob)sudo pacman -S neovimInstall vimtex — vimtex is a neovim plugin. Use whatever plugin manager you already have (lazy.nvim, packer, vim-plug). For lazy.nvim, add { "lervag/vimtex" } to your plugin list. For vim-plug, add Plug 'lervag/vimtex' to your init.vim and run :PlugInstall.
If you don't have a neovim setup yet, the easiest starting point is a kickstart distribution like kickstart.nvim or LazyVim — both come with sensible defaults that work well with vimtex.
Once Python and pipx are working:
pipx install acad-cli
This puts the acad command on your PATH (in ~/.local/bin/acad) inside an isolated virtual environment, so it won't conflict with other Python packages.
To verify:
acad --help
You should see a usage line listing the subcommands (new, pset, course, list, dashboard, init, grades, select, info, format).
If you get "command not found", ~/.local/bin is not on your PATH. Run pipx ensurepath and restart your shell.
acad init
acad init prompts you to either use the default location (~/academic) or specify a custom path. It creates the directory and drops in:
preamble.tex — a starter LaTeX preamble (you'll edit this to taste)preamble-darkmode.tex — optional dark-mode tweaks.latexmkrc — the build config (plain pdflatex via latexmk).academic/config.json — semester, author name, course listThen tell your shell where this is:
bash / zsh — add to ~/.bashrc or ~/.zshrc:
export UNI_ROOT="$HOME/academic" # or whatever path you chose
fish — run once:
set -Ux UNI_ROOT "$HOME/academic"
Open a new terminal (or source the config), then run acad d to see your dashboard. It will be empty until you add courses.
acad course add math101 --code "MATH 101" --instructor "Dr. Smith" --schedule "MWF 10am"
acad list
This creates $UNI_ROOT/math101/ and registers it in .academic/config.json.
acad select math101 # set "current course"
acad new -t "Vector Spaces" --tex # scaffold lecture_01.tex
This creates a numbered lecture file (lecture_01.tex) with the right preamble inputs, opens cleanly in vimtex, compiles with latexmk against the shared preamble.
The recommended setup is neovim + vimtex + the acad keymap layer.
(See Installing neovim and vimtex above.)
This repo ships two starter files under integration/nvim/:
vimtex.lua — vimtex compiler config (plain pdflatex via latexmk, synctex-correct, Skim-aware autocompile)keymaps.lua — <leader>a* and <leader>i* keymap stanzas wired to acad and the Ipe pipelineCopy them into your neovim config:
# clone or download this repo if you haven't:
git clone https://github.com/sdvstephens/acad-cli.git
cd acad-cli
# adapt these into your own config — the exact paths depend on your setup:
cp integration/nvim/vimtex.lua ~/.config/nvim/lua/plugins/
cp integration/nvim/keymaps.lua ~/.config/nvim/lua/config/acad-keymaps.lua
Then require("config.acad-keymaps") from your init.lua.
Open any .tex file in your $UNI_ROOT, then try:
| keymap | what it does |
|---|---|
<leader>tc | compile (vimtex) |
<leader>tv | view PDF in Skim/zathura |
<leader>al | new lecture (prompts for course + topic) |
<leader>ah | new problem set |
<leader>ad | dashboard (inside nvim) |
<leader>ar | list courses |
<leader>ai | current course info |
<leader>ic | create new Ipe figure (requires ipe-figures.py — see note in keymaps.lua) |
If you use fish, copy integration/fish/uni.fish into ~/.config/fish/conf.d/. It gives you a uni <subcommand> wrapper plus a grades shorthand alias:
cp integration/fish/uni.fish ~/.config/fish/conf.d/
exec fish
uni help
For bash/zsh users, an equivalent function is on the roadmap. For now, just call acad directly.
# Dashboard
acad d # or `acad dashboard` — courses, tasks, recent files
acad d --json # machine-readable
# Courses
acad list # list all courses
acad course add <name> # add a new course
acad course edit <name> --code C101 # edit metadata
acad course cleanup --name <course> # delete aux files in a course
acad select <name> # set the "current course"
acad info # info about current course
# Lectures and psets
acad new -c <course> -t "<topic>" --tex # create a numbered lecture
acad pset -c <course> -t "<title>" --tex # create a numbered problem set
# Grades
acad grades list # list courses with grade tracking
acad grades add-course -c "Linear Algebra" --credits 3
acad grades add-category -c "Linear Algebra" --category PSets --weight 30
acad grades add-grade -c "Linear Algebra" -a "PS1" -g 95 --max 100 --category PSets
acad grades show -c "Linear Algebra" # full grade card
acad grades show-all # all courses
acad grades export-latex -c "Linear Algebra" # LaTeX table
# Output format default
acad format tex # default to LaTeX for new lectures
acad format org # default to Org-mode
acad: command not found — ~/.local/bin is not on your PATH. Run pipx ensurepath and open a new shell.
pdflatex: command not found — TeX Live / MacTeX is not installed, or its bin directory is not on PATH. On macOS, the MacTeX installer normally adds /Library/TeX/texbin to PATH; reopen your terminal after install.
acad d shows "No courses found" — either UNI_ROOT isn't exported (check with echo $UNI_ROOT) or there are no course directories under it. Run acad init if you haven't, then acad course add <name> to add one.
vimtex compile fails with "preamble.tex not found" — _UNI_ROOT in the LaTeX \input resolves to whatever UNI_ROOT was when acad new scaffolded the lecture. Check the first lines of the generated .tex file — they should reference your actual content directory.
Skim doesn't open the PDF on save — make sure Skim is set as the default .pdf handler, and that vimtex's g:vimtex_view_method = "skim" (already configured in the shipped vimtex.lua).
Permission denied opening acad — pipx installed it, but ~/.local/bin/acad isn't executable somehow. Try pipx reinstall acad-cli.
acad reads and writes only inside $UNI_ROOT (and ~/.local/share/pipx/... for the install itself). It does not phone home, does not collect telemetry, does not require an account. Your .grades.json and .academic/config.json stay on your machine.
compile_master.py (multi-lecture master compile) into acad as acad compileipe-figures.py into acad as acad figintegration/fish/uni.fishMIT — see LICENSE.
Inspired by the late Gilles Castel. Built atop neovim, vimtex, latexmk, and Ipe.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 29 May 2026 | 0 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:b97ca3131e51d09f747681c8693737d6e23e7867a249e3e81fea7c5b8e96f8e8