Skip to content

Repository files navigation

⚡ PacLife

All Eyez on your environment.

A persistent Power Platform CLI (pac) statusline pinned to the top of your terminal. Always know who you're logged in as, which tenant, which environment, and which solution you're working on — before you run that pac solution import against the wrong org.

PacLife statusline pinned to the top of the terminal

How it started

A colleague started living in the Power Platform CLI and kept hitting the same wall before every command: which environment am I actually pointed at right now? The honest way to find out is pac org who — six seconds, one network round-trip, and a small prayer that the answer isn't "Production." He wanted that answer pinned to the top of his terminal: always on, no round-trip, no praying.

"Can't you just... make that?"

Reader, this is "just make that."

The name wrote itself. pac + a statusline keeping All Eyez on your environment left no responsible alternative to naming it after 2Pac's Pac's Life. Yes, really. Roll the tape:

2Pac — Pac's Life

Why

  • pac org who takes 6+ seconds (network round-trip). PacLife reads pac's local auth store and renders in milliseconds — no network calls, ever.
  • The statusline refreshes after every command: run pac auth select or pac env select and the top row updates immediately.
  • Production gets the red treatment: environments of type Production/Default — or any URL you mark as protected — show a red segment stating why: ⚠ Production, ⚠ Default Environment or ⚠ Protected.
  • Service principals are unmistakable: SPN auth renders on a purple segment with the AppId, so a CI/consultant identity is never mistaken for you.
  • Sovereign clouds stand out: GCC / GCC High / DoD / China get a high-visibility magenta segment.

Install

irm https://raw.githubusercontent.com/Gakinchi/paclife/main/install.ps1 | iex

Installs the latest GitHub Release into your user module path and adds an activation block to your PowerShell profile.

Requirements: a VT-capable terminal (Windows Terminal, VS Code terminal, iTerm2, ...). Works on both PowerShell 7+ and Windows PowerShell 5.1 — it's the terminal that matters, not the shell. In a legacy console without VT support, PacLife simply stays quiet.

Commands

You type Which is What it does
paclife Show-PacLife print the compact context line once
alleyez Show-PacLife -Full All Eyez on Me — the full detail banner
keepyaheadup Enable-PacLife pin the statusline to the top (+ profile)
lifegoeson Disable-PacLife turn it off and restore the terminal
changes Update-PacLife update to the latest release
Get-PacContext the context as an object, for your own scripts
Get-PacLifeStatusLine the context as one line, for an AI agent's statusline (see below)

What the statusline shows

Segment Source
Identity user UPN (blue) or service principal AppId (purple, SPN)
Environment friendly name, colored red (Production/Default/protected), green (Sandbox/Developer/Trial), yellow (unknown or no environment selected)
Auth kind only shown for legacy DATAVERSE/ADMIN profiles (explains why some pac commands fail despite being "logged in") — the modern UNIVERSAL default is hidden
Geo / cloud the environment's region (EMEA, dim); the cloud appears only when sovereign (GCC High, magenta) — the default Public cloud is hidden
Solution detected from your working directory (.cdsproj, src/Other/Solution.xml, .pcfproj — searched upward, like git finds .git), with its version: sln ContosoCore 1.2.0.3
Profiles 4 profiles — shown when you have more than one to switch between (pac auth list; details in alleyez)
pac version the locally installed CLI version

The terminal tab title is set to the environment name too, so you can tell your tabs apart.

Matches your oh-my-posh theme

If you use oh-my-posh, PacLife reads your active theme (via POSH_THEME, offline — it never runs oh-my-posh.exe) and restyles itself to match:

  • Colors: segments adopt your theme's palette, rendered in exact 24-bit truecolor.
  • Shape: diamond-style themes (like atomic) get diamond-capped segments; powerline themes get their own separator glyph.
  • Semantics stay sacred: the environment segment keeps its red/green/yellow meaning, but uses your theme's own red/green/yellow shades (with built-in fallback when the theme has no matching hue). Theme matching changes nuances, never meaning.

JSON themes only — YAML/TOML themes silently fall back to the built-in palette. Set "theme": "builtin" to opt out.

Configuration (~/.paclife.json, optional)

{
  "protectedUrls": ["*contoso-prod*", "*.crm4.dynamics.com/"],
  "safeUrls": ["*playground*"],
  "windowTitle": true,
  "theme": "auto",
  "style": "auto"
}
  • protectedUrls — wildcard patterns that force the red treatment regardless of environment type (for that production org someone created as a Sandbox...). safeUrls mutes it.
  • theme"auto" (match oh-my-posh when present), "builtin", or a path to an .omp.json file.
  • style"auto" (follow the theme), "powerline", "diamond", or "plain".
  • NO_COLOR environment variable is honored.

Honesty notes (by design)

  • PacLife shows the last known context — a mirror of what pac last wrote to disk. It never claims live status and never makes a network call (only changes/install.ps1 touch the network, because you asked them to).
  • The "context last refreshed ≈ ..." line in alleyez is derived from the cached token timestamp. An old date does not mean you must re-authenticate — pac renews tokens silently.
  • Logged in ≠ connected to an environment. If you're authenticated without an environment, PacLife says so on a yellow segment instead of pretending.

Using oh-my-posh or starship?

No problem — PacLife wraps your prompt function and calls it through, so both render. Just make sure the PacLife block stays last in your $PROFILE (the installer puts it there).

Inside an AI coding agent (Claude Code, Copilot CLI, Cursor)

The pinned top row works by owning a terminal scroll region and repainting itself on every PowerShell prompt. A full-screen TUI agent — Claude Code CLI, GitHub Copilot CLI, Cursor CLI — takes over the whole screen, resets the scroll region, and stops the prompt loop, so the pinned banner disappears for the length of the session. Two programs can't own the same surface; this is structural, not a bug (it's the same reason vim/less disturb the top row — except here the prompt doesn't come back until you quit the agent).

The fix is to stop fighting for row 1 and ride the agent's own statusline instead. All three agents support a custom statusline: they run a command and render its stdout at the bottom of their UI. Get-PacLifeStatusLine is exactly that command's payload — the same compact, theme-aware line, on one row. It reads pac's auth store directly, so it needs nothing from the agent.

A ready-made launcher lives at agents/paclife-statusline.ps1 (it discards the session JSON the agent pipes in and prints the line).

Claude Code

Claude Code renders multiple lines, so the cleanest setup is to compose PacLife as a second line under whatever your statusline already shows. If you already have a statusLine script, append:

Import-Module PacLife -ErrorAction SilentlyContinue
if (Get-Command Get-PacLifeStatusLine -ErrorAction SilentlyContinue) {
    "`n" + (Get-PacLifeStatusLine)
}

If you have no statusline yet, point ~/.claude/settings.json straight at the launcher:

{
  "statusLine": {
    "type": "command",
    "command": "powershell -NoProfile -File C:/Users/you/.claude/paclife-statusline.ps1"
  }
}

(or run /statusline in Claude Code and describe what you want).

GitHub Copilot CLI

Custom statuslines are behind the experimental flag. Add to ~/.copilot/settings.json:

{
  "experimental": true,
  "statusLine": {
    "type": "command",
    "command": "powershell -NoProfile -File C:/Users/you/.copilot/paclife-statusline.ps1"
  }
}

Then, inside Copilot CLI, run /statusline, toggle custom on, and /restart.

Cursor CLI

Cursor's custom-command statusline is experimental and its config schema isn't officially documented yet, so the reliable path is the in-CLI helper: run /statusline in Cursor and point it at the launcher, e.g. powershell -NoProfile -File C:/Users/you/.cursor/paclife-statusline.ps1.

Heads-up: Each agent spawns a fresh PowerShell per refresh, so the line adds a small Import-Module cost. PacLife's reads are mtime-cached and never hit the network, so it stays well within a statusline budget.

Uninstall

lifegoeson    # turn off + remove from profile
# or remove everything:
irm https://raw.githubusercontent.com/Gakinchi/paclife/main/uninstall.ps1 | iex

FAQ

Why doesn't it show whether my token is still valid? Because it can't know without a network call, and a statusline that makes network calls on every prompt is a statusline you'll uninstall by lunch. See Honesty notes.

The top row got messed up by a full-screen app (vim, less). It heals on your next prompt — the scroll region and statusline are re-asserted every time.

Does it send telemetry? No.

License

MIT — see LICENSE.

About

All Eyez on your environment - a persistent Power Platform CLI (pac) statusline pinned to the top of your terminal. Offline, instant, always visible.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages