Skip to content

Feature request: CLI subcommands — version, update, doctor, status/stop, serve #1139

Description

@gzliudan

pi-web is launch-options only today. bin/pi-web-options.js defines four options (--port, --hostname, --no-open, --help), and parseLaunchOptions rejects every positional, so there is no subcommand surface at all. Finding out which version is installed means reading package.json or running npm ls -g, updating means re-running npm install -g @agegr/pi-web@latest by hand after stopping the server with Ctrl+C, and that is exactly what the README tells people to do.

That is fine for the happy path, but it blocks the shell workflows people expect from a dev-server CLI: is it running, is it still alive, stop it, am I current, is my environment sane.

Proposed commands

  • pi-web version (-v, --version, --json) — report the installed version plus the resolved install source (global prefix vs npx cache) so the two can be told apart. Since Pi Web shares its data directory with the pi CLI, also report the pi version in use and the agent data directory that was resolved.

  • pi-web update — check for and install a newer release. --check should only report; --stop-first should stop a running server before reinstalling. The registry comparison can reuse lib/app-update.ts (isNewerStableVersion, getPiWebReleaseUrl) and the npm invocation can reuse lib/node-cli.ts (findNodeCliScript), so Windows stays shell-free. A running server must not be replaced underneath itself — next start has .next/ open — so the command should detect that case, print the pid it found, and refuse.

  • pi-web doctor — environment check: Node >= 22.19.0 (that check already exists in bin/node-version.js and can be reused), pi CLI presence and version, readability of PI_CODING_AGENT_DIR / ~/.pi/agent, whether the port is already taken, whether a non-loopback bind has PI_WEB_PASSWORD set (today that warning is printed once during startup and then lost), and whether the data directory is writable.

  • pi-web status and pi-web stop — whether a server is running, on which host and port, since when, and a way to stop it. bin/process-lifecycle.js forwards SIGINT/SIGTERM and force-kills after 5s, but nothing is persisted, so the CLI can answer neither question today. A pid file under ~/.pi-web/ next to projects.json is the missing piece, and it is also what update and doctor need.

  • pi-web serve — the current behaviour under an explicit name, so help text can read pi-web [command] [options]. Bare pi-web keeps working exactly as it does now.

  • pi-web open — open the UI in a browser without starting a second server; today the browser only opens as a side effect of launching one.

  • pi-web completion <shell> — bash, zsh and fish completions for the commands and options above.

Nice-to-have, if the CLI surface grows anyway

  • pi-web projects add|remove|list — ~/.pi-web/projects.json is already the registry of project entries the UI offers.
  • pi-web sessions ls|export|rm — mirror /api/sessions and /api/sessions/[id]/export, reading ~/.pi/agent/sessions/... directly when no server is running.
  • pi-web models, auth, mcp, skills — line up with the pi CLI subcommands of the same name; the HTTP side already exists (/api/models-config/test, /api/mcp/test, /api/plugins/check).
  • pi-web run <project> -- "<prompt>" — one non-interactive task via pi --print.

Notes for implementation

  • Backwards compatibility first: match a known command name before running the existing parseArgs, keep --help at exit 0 and unknown input at exit 1, and point unknown commands at pi-web --help.
  • Docs to keep in sync with a new command surface: getHelpText() plus the four READMEs.

No ordering is implied. version, doctor, the pid file, status/stop and update --check would already cover most of it without touching a single API route.

Activity

  1. agegr commented on Oct 9, 2026

    @agegr
    Owner

    Thanks for the detailed proposal. We're taking the practical subset: version (-v), status, stop, open and update [--check], in #1154. update installs only into a global npm install, and refuses while a server is running (pi-web stop first). Running servers are tracked in ~/.pi-web/run/. doctor, serve, shell completion and the projects/sessions/models subcommands are out of scope for a light wrapper. This issue will close when the PR merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions