# plane-cli A lightweight **zsh + curl** CLI for [Plane](https://plane.so) (works with self-hosted instances). No build step, no dependencies to install beyond what you already have — it's a single sourced shell file that wraps the Plane REST API with `fzf` pickers. > Personal tool, built for a self-hosted Plane instance. Inspired by > [`cpatrickalves/plane-cli`](https://github.com/cpatrickalves/plane-cli), but deliberately > tiny: just functions in your shell. ## Requirements - `zsh` - `curl` - `python3` (used for JSON shaping — stdlib only) - `fzf` (interactive pickers) ## Install ```sh git clone https://forgejo.ludique.dev/theo/plane-cli.git ~/Developer/plane-cli ``` Add to your `~/.zshrc`: ```sh export PLANE_API_KEY="plane_api_xxxxxxxxxxxxxxxx" # keep this out of version control source ~/Developer/plane-cli/plane.zsh ``` Reload: `source ~/.zshrc`. ### Configuration | Env var | Required | Default | |----------------------|----------|-----------------------------------------------------------| | `PLANE_API_KEY` | **yes** | — (Plane → *Settings → API tokens*) | | `PLANE_BASE` | no | `https://plane.ludique.dev/api/v1/workspaces/oloap` | | `PLANE_PROJECT` | no | a project UUID | | `PLANE_PROJECT_NAME` | no | `colorcatchers` | `PLANE_BASE` is `/api/v1/workspaces/`. The active project can also be switched at runtime with `pluse` (it re-fetches the project's workflow states). ## Commands ``` pl list open issues (shows labels) pl -a list ALL issues (incl. done/cancelled) pl -s backlog|todo|... filter by state pl -p urgent|high|... filter by priority pl /text search titles containing 'text' pl -j raw JSON output (pipe to jq); honours filters pl -h full help pladd create an issue (interactive wizard) pladd "title" [opts] create inline -p priority urgent|high|medium|low (default: none) -s state backlog|todo|progress (default: backlog) -d YYYY-MM-DD due date -l a,b,c attach labels (must already exist) plstate [#] change state — fzf picker if no id pldone [#] mark done — fzf picker if no id plshow fzf-pick and inspect an issue (shows labels) pledit [#] edit title/priority/due/labels plrm [# ...] delete — fzf multi-select if no ids plcomment [#] [text] list comments on an issue, or add one pllabels [add "n" [#hex]] list project labels, or create one plprojects list all projects pluse [name|id] switch active project (fzf if no arg) plsync [--dry-run] mirror open issues from all projects into an "Everything" project ``` ### Examples ```sh pl -s todo # only todo issues pl -p high # only high priority pl /login # titles containing "login" pl -j | jq -r '.[].name' # scriptable JSON pladd "Fix export button" -p high -s todo -l bug,urgent plcomment 7 "fixed in latest deploy" pllabels add "bug" "#FF0000" ``` ## Notes - `pl -j` emits the filtered issue list as JSON for piping to `jq`. - Comments are created via Plane's `comment_html` field (the API stores HTML). - `plsync` is idempotent — it keys mirrored items by `[IDENTIFIER] title` and removes ones that have been closed at the source. ## License MIT