Skip to content
DocsActions

Actions

Actions are the commands you run once in a while — your test suite, a database migration, a deploy script. Services run continuously; actions fire once, do their job, and show you the result. Each one is a button in the project toolbar — or in the footer bar under the terminal — and one click runs it.

Actions with confirm: true ask before running; everything else just runs.

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  test: npm test              # shorthand

  deploy:                     # full form
    cmd: ./scripts/deploy.sh
    label: Deploy to Production  # display name in the UI
    confirm: true             # ask before running
    display: header           # main button row (default; omit to get the same)
    env:
      NODE_ENV: production
  • cmdstring

    The shell command to run — whatever you’d type into a terminal yourself. Required unless the action groups child actions with actions below.

  • labelstring

    The friendly name shown on the button. If you skip it, lpm shows the action’s key as-is — db-reset stays db-reset, while label: Reset DB reads better.

  • emojistring

    A single emoji shown in front of the label, so a crowded toolbar stays scannable. It’s prefixed to whatever the label resolves to — emoji: 🚀 with label: Deploy renders as 🚀 Deploy.

  • cwdstring

    Run the command from a different folder than the project root — useful for monorepos or when the action lives in a subfolder. Relative paths resolve from root; absolute paths are used as-is (see Path resolution). Nested actions inherit this from their parent.

  • envmap

    Extra environment variables to set just for this action — handy for one-off flags like NODE_ENV=production. Nested actions inherit these from their parent.

  • confirmbool

    Show a confirmation dialog before running. Turn this on for anything you’d regret clicking by accident — deletes, resets, production deploys.

  • displaystring

    Where the action appears. The default, header, pins it to the project toolbar so it’s always one click away — omit display entirely to get the same result. footer tucks it into the status bar below the terminal — handy for tight, always-visible controls. Or name a zone to put the button in it. menu still works as a legacy value (overflow menu) but is no longer suggested by the editor.

  • typestring

    How the action runs. The default pops open a modal and streams output while the command runs. terminal opens a persistent interactive pane (see the Terminals section below). background runs the command hidden behind a small live card that counts the time, keeps the output a click away with Cancel and Copy output, and shows success or failure when it finishes — perfect for slow, boring commands whose only interesting signal is “did it succeed.” command types the command into the terminal you have focused.

  • actionsmap

    Group related commands under this action. They show up as a dropdown. If the parent also has a cmd, it renders as a split button — clicking the main part runs the parent, clicking the chevron opens the group.

  • primarystring

    Only for actions with nested actions: which child the main half of the split button runs. Name a child’s key (primary: staging) to pin it, or use last-used so the button follows whichever child you ran most recently — remembered per project on that computer. It takes precedence over the parent’s own cmd.

More fields. The table above covers what the examples on this page use. Actions also take these, and the app’s action editor sets most of them for you:

  • colorstring

    An accent for the button and the tab it opens: a name like blue, claude or rose, the same name plus -deep, or any CSS color (quote a leading #).

  • shortcutstring

    A key combo that runs the action while the project is open, like cmd+shift+b.

  • inputsmap

    Values lpm asks for before running — text, password, or a choice of options — filled into the command wherever {{key}} appears.

  • promptstring

    On a terminal that starts Claude Code, Codex, Gemini CLI, or OpenCode: the task sent to the agent once it’s ready.

  • reusebool

    On a terminal: use the pane that’s already open instead of opening a new one each click.

  • labelRefreshstring

    How often commands in a label or emoji run, like 5m. See dynamic labels below.

  • positionnumber

    Order among the buttons of its bar, or inside its zone. Lower comes first.

  • portnumber | list

    Ports that must be free before running: a number, a range like "3002-3010", or a list. portConflict says what to do when one is taken: ask, free, or fail.

  • modestring

    SSH projects only: remote runs on the host; sync copies the project here, runs the command on this computer, and syncs the changes back.

Dynamic labels. A label can keep itself current: the branch with {{git.branch}}, your last release and how long ago it was with {{git.tag}} and {{git.tagAge}}, or whatever a command prints with $(…), refreshed on a timer or the moment the code changes. The lesson below sets one up and has Claude Code add another:

Shorthand. If all your action needs is a command, write it as a single line — the key becomes the label and you skip the nested form entirely. Great for everyday dev commands:

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  test: npm test
  lint: npm run lint
  build: npm run build
  typecheck: npx tsc --noEmit
  format: npx prettier --write .

Destructive actions. For anything you don’t want to click by accident — cache wipes, rollbacks, production deploys — add confirm: true to get a confirmation dialog, and pair it with display: header (the default) so the action lives in the toolbar where you’ll find it:

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  reset-cache:
    cmd: rm -rf .next node_modules/.cache
    label: Reset Cache
    confirm: true
    display: header
  rollback:
    cmd: ./scripts/rollback.sh
    label: Rollback Deploy
    confirm: true
    env:
      NODE_ENV: production

Grouping related actions. Give a parent action both a cmd and nested actions and lpm renders it as a split button: the main part runs the parent’s command, the chevron opens a menu with the children. Use this when there’s a sensible default plus a few alternatives — like “Deploy staging” with production and preview tucked behind it:

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  deploy:
    cmd: ./deploy.sh staging     # split button — main click runs this
    label: Deploy
    emoji: 🚀                    # icon shown next to the label
    display: header
    confirm: true
    actions:                     # chevron opens these
      production:
        cmd: ./deploy.sh production
        label: Production
        emoji: 🔴
        confirm: true
      preview:
        cmd: ./deploy.sh preview
        label: Preview
        emoji: 👁️

Remembering your last choice. Add primary: last-used instead of a parent cmd and the main part of the split button becomes whichever option you clicked last — deploy to staging once, and the button reads “Staging” until you pick something else. Set primary to a child’s name (like primary: staging) to pin one option as the default instead:

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  deploy:
    primary: last-used           # main click repeats the last used option
    actions:                     # chevron opens these
      staging:
        cmd: ./deploy.sh staging
        label: Staging
        emoji: 🟢
      production:
        cmd: ./deploy.sh production
        label: Production
        emoji: 🔴
        confirm: true

Dropdown-only groups. Drop the parent’s cmd and the whole button becomes a dropdown. Good for a set of related commands with no obvious default — like a database toolkit (Migrate, Seed, Reset):

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  db:
    label: Database
    emoji: 🗄️
    display: header
    cwd: ./backend
    actions:
      migrate:
        cmd: python manage.py migrate
        label: Migrate
        emoji: 📦
      seed:
        cmd: python manage.py seed
        label: Seed
        emoji: 🌱
      reset:
        cmd: python manage.py flush
        label: Reset
        emoji: 💣
        confirm: true

Background actions. For slow, boring commands where the only thing you care about is whether they succeeded — builds, migrations, docker pulls, git fetch — add type: background. The command runs hidden while a small live card counts the time and keeps its output a click away, with Cancel and Copy output, then shows success or failure when it’s done. No modal to dismiss, no terminal tab to clean up, and you can fire several in parallel while you keep working:

~/.lpm/projects/myapp.ymlvalid
name: myapp
root: ~/Projects/myapp
services:
  web: npm run dev
actions:
  db-reset:
    cmd: npm run db:reset && npm run db:seed
    label: Reset DB
    type: background       # runs hidden, with a live progress card
    confirm: true          # pair with confirm for destructive ones

A note on inheritance

Nested actions inherit cwd and env from their parent unless they override them. Set cwd: ./backend on the parent once and every child runs from there — no need to repeat yourself.