# Nipux CLI

```text
 _   _ ___ ____  _   ___  __
| \ | |_ _|  _ \| | | \ \/ /
|  \| || || |_) | | | |>  <
| |\  || ||  __/| |_| /_/\_\
|_| \_|___|_|    \__,_|
```

Nipux CLI is a small, restartable worker for long-running browser, web research,
and command-line jobs. It supports any OpenAI-compatible local or remote model
endpoint. It is maintained for Nipux and built around one practical idea: keep a
worker moving in bounded steps, save exact evidence, learn from each branch, and
recover cleanly when a process or model call fails.

- Website: [Nipux.com](https://nipux.com)
- Source: [github.com/nipuxx/agent-cli](https://github.com/nipuxx/agent-cli)
- License: [MIT](LICENSE)

## What It Does

Nipux runs jobs that are too long or repetitive for a single chat turn. A job can
search the web, operate a persistent browser profile, write artifacts, inspect
local files with bounded shell commands, update source and finding ledgers, and
continue through a daemon loop until the operator pauses or cancels it.

The default runtime is intentionally narrow:

- one OpenAI-compatible model endpoint chosen during setup
- one SQLite state store under `~/.nipux`
- one restartable daemon with a single-instance lock
- per-job artifact files for exact evidence
- per-job browser profiles through `agent-browser`
- compact memory summaries that point back to artifacts
- visible event history for chat, tools, artifacts, progress, errors, and digests
- durable ledgers for lessons, sources, findings, tasks, roadmap, and experiments

Nipux does not include a messaging gateway, plugin marketplace, skills manager,
RL environment, voice stack, image stack, or broad web application. The public
surface is the `nipux` CLI and the focused `nipux_cli/` Python package.

## Install

Requirements:

- Python 3.11+
- an OpenAI-compatible chat completions endpoint, local or remote
- optional browser automation: `npm install -g agent-browser && agent-browser install`

Install and open the full-screen setup wizard with one command:

```bash
curl -fsSL https://raw.githubusercontent.com/nipuxx/agent-cli/main/scripts/install.sh | bash
```

The first-run wizard asks for the provider/model, endpoint, API key location,
and tool access. After the model is verified, Nipux opens the workspace chat
where you can describe worker jobs in plain language. It stores
secrets outside the git repo and writes runtime state under `~/.nipux` unless
`NIPUX_HOME` is set.

Install from a local checkout while developing:

```bash
git clone https://github.com/nipuxx/agent-cli.git
cd agent-cli
uv tool install --editable .
nipux
```

Install directly from git once the repository is public:

```bash
uv tool install git+https://github.com/nipuxx/agent-cli.git
```

## First Run

Run `nipux`. If this is a fresh profile, the full-screen setup wizard opens
immediately and locks chat/job creation until the configured model passes a real
chat request. The wizard writes `config.yaml` and a local `.env` template under
`~/.nipux` unless `NIPUX_HOME` is set. Real API keys stay in the environment or
`~/.nipux/.env`, not in the git repo.

```bash
nipux
```

After setup, `nipux` opens the workspace chat. Type a plain-English goal to spin
up a worker, or use `/new OBJECTIVE`. Use `/settings` to edit model, endpoint,
tool access, runtime, and cost fields from inside the UI.

Manual configuration is still available for scripts or headless environments:

```bash
nipux init --model local-model --base-url http://localhost:8000/v1 --api-key-env OPENAI_API_KEY
nipux doctor --check-model
```

`nipux init` creates `~/.nipux/config.yaml` and `~/.nipux/.env` with private
file permissions. Later `/api-key` edits keep the secret in `~/.nipux/.env`
instead of writing it to config.

Update an installed tool or source checkout from anywhere:

```bash
nipux update
```

When installed as a `uv tool`, `nipux update` force-refreshes the command from
the source repository and verifies the installed command afterward. When run
inside a git checkout, it fast-forwards the checkout. If a daemon is running,
update restarts it automatically unless `--no-restart` is used. Set
`NIPUX_UPDATE_SPEC` only when you need to update from a different package source.

Inspect progress from the terminal:

```bash
nipux status
nipux activity --follow
```

On macOS, install launchd autostart:

```bash
nipux autostart install --poll-seconds 0
nipux autostart status
```

On Linux, install a user service:

```bash
nipux service install
nipux service status
```

Fully remove local runtime state when you want a fresh user install:

```bash
nipux uninstall --yes
```

This stops the daemon, removes launchd/systemd service files, deletes
`~/.nipux`, removes legacy `~/.kneepucks` state if it exists, and removes the
installed `nipux` command with `uv tool uninstall nipux`. Add `--keep-tool` only
when you intentionally want to keep the command installed.

## Secrets

Nipux never needs an API key in `config.yaml`. The config stores only the name
of the environment variable to read:

```yaml
model:
  name: provider/model
  base_url: https://provider.example/v1
  api_key_env: PROVIDER_API_KEY
  # Optional fallback pricing when the provider does not return cost metadata.
  input_cost_per_million: null
  output_cost_per_million: null
```

Put secrets in your shell, your process manager, or `~/.nipux/.env`:

```bash
# ~/.nipux/.env
PROVIDER_API_KEY=
```

The repository includes `.env.example` and `config.example.yaml` as templates.
Do not commit real `.env`, state databases, logs, artifacts, or browser
profiles. The default `.gitignore` excludes those local runtime files.

## Tool Access

The first-run wizard and config slash commands control which generic tool groups
the worker can use:

```yaml
tools:
  browser: true
  web: true
  shell: true
  files: true
```

Use `/browser`, `/web`, `/cli-access`, and `/file-access` in the terminal UI to
change those switches later. Disabled tools are removed from the worker tool
schema and blocked if an old daemon tries to call them.

## Local Model Examples

Nipux talks to OpenAI-compatible `/v1/chat/completions` and `/v1/models`
servers. Use any serving stack that supports the model and tool-calling behavior
you want.

SGLang example:

```bash
python -m sglang.launch_server \
  --model-path "$MODEL_NAME" \
  --port 8000 \
  --context-length 262144 \
  --reasoning-parser auto \
  --tool-call-parser auto
```

vLLM example:

```bash
vllm serve "$MODEL_NAME" \
  --port 8000 \
  --max-model-len 262144 \
  --enable-auto-tool-choice \
  --tool-call-parser auto
```

## Operator Workflow

The no-argument CLI opens the focused job directly. Plain text becomes operator
steering for the next worker step. The terminal UI keeps conversation/output on
the left and status, jobs, saved outputs, updates, and worker activity on the
right. Configuration is handled through slash commands such as `/model`,
`/api-key`, `/base-url`, and `/context`, not a separate settings page.

```text
nipux > what are you working on?
nipux > prioritize measured progress over notes
```

For direct command use:

```bash
uv run nipux status "nightly research" --full
uv run nipux history "nightly research"
uv run nipux events "nightly research" --follow
uv run nipux activity "nightly research" --follow
uv run nipux outcomes "nightly research"
uv run nipux outcomes --all
uv run nipux findings "nightly research"
uv run nipux tasks "nightly research"
uv run nipux roadmap "nightly research"
uv run nipux experiments "nightly research"
uv run nipux sources "nightly research"
uv run nipux memory "nightly research"
uv run nipux metrics "nightly research"
uv run nipux usage "nightly research"
uv run nipux artifacts "nightly research" --paths
```

Use `nipux health` for daemon truth without opening the dashboard. It reports
the lock state, heartbeat, recent failures, log paths, autostart state, focused
job, and latest daemon events.

### Seeing What It Actually Did

Use these views when a job has been running unattended:

- `nipux outcomes JOB` or the **Outcomes** pane: durable work grouped by time,
  including saved outputs, findings, measurements, decisions, lessons, and file
  changes.
- `nipux outcomes --all`: latest durable work and saved outputs for every job,
  useful when several agents have been running in the background.
- `nipux activity JOB --follow` or the **Work** pane: the raw live tool stream
  for debugging what the worker is doing right now.
- `nipux usage JOB`: model calls, context pressure, output tokens, and cost when
  the provider returns cost metadata. If the provider does not return cost,
  configure `/input-cost` and `/output-cost` to estimate it from token counts.
- `nipux digest JOB` and `nipux daily-digest`: durable summary reports that
  include progress counts, active operator context, experiments, artifacts, and
  token/cost usage.

## Tool Surface

The worker exposes a deliberately small tool registry:

- `browser_navigate`
- `browser_snapshot`
- `browser_click`
- `browser_type`
- `browser_scroll`
- `browser_back`
- `browser_press`
- `browser_console`
- `web_search`
- `web_extract`
- `shell_exec`
- `write_file`
- `write_artifact`
- `read_artifact`
- `search_artifacts`
- `update_job_state`
- `defer_job`
- `report_update`
- `record_lesson`
- `acknowledge_operator_context`
- `record_source`
- `record_findings`
- `record_tasks`
- `record_roadmap`
- `record_milestone_validation`
- `record_experiment`
- `send_digest_email`

`shell_exec` is bounded with timeouts and output capture. Browser sessions use
per-job profiles under `~/.nipux/browser-profiles/`. Anti-bot, CAPTCHA, login,
and paywall pages are recorded as visible source-quality warnings; Nipux does
not bypass protections.

Workers can use `defer_job` for scheduled follow-up, monitor intervals, or long
external processes that are actually waiting on time to pass. Deferred jobs stay
runnable but show as waiting until their next check time, so the daemon can keep
other work moving without burning model calls on repeated polling.

## Command Reference

```bash
nipux init [--force] [--openrouter] [--model MODEL] [--base-url URL] [--api-key-env ENV]
nipux update [--path PATH] [--allow-dirty] [--no-restart]
nipux uninstall [--yes] [--dry-run] [--keep-legacy] [--keep-tool]
nipux doctor [--check-model]
nipux shell [--status]
nipux create "objective" [--title TITLE] [--kind KIND] [--cadence CADENCE]
nipux jobs
nipux ls
nipux focus [JOB_TITLE]
nipux rename JOB_TITLE --title NEW_TITLE
nipux delete JOB_TITLE [--keep-files]
nipux chat [JOB_TITLE] [--no-history]
nipux steer [--job JOB_TITLE] MESSAGE
nipux pause [JOB_TITLE] [note...]
nipux resume [JOB_TITLE]
nipux cancel [JOB_TITLE] [note...]
nipux start [--poll-seconds N]
nipux stop
nipux autostart install|status|uninstall [--poll-seconds N]
nipux service install|status|uninstall [--poll-seconds N]
nipux browser-dashboard [--port N] [--foreground] [--stop]
nipux health
nipux status [JOB_TITLE] [--full] [--json]
nipux history [JOB_TITLE] [--full] [--json]
nipux events [JOB_TITLE] [--follow] [--json]
nipux activity [JOB_TITLE] [--follow] [--verbose]
nipux updates [JOB_TITLE]
nipux outcomes [JOB_TITLE] [--all]
nipux dashboard [JOB_TITLE]
nipux findings [JOB_TITLE] [--limit N] [--json]
nipux tasks [JOB_TITLE] [--limit N] [--status STATUS] [--json]
nipux roadmap [JOB_TITLE] [--limit N] [--json]
nipux experiments [JOB_TITLE] [--limit N] [--status STATUS] [--json]
nipux sources [JOB_TITLE] [--limit N] [--json]
nipux memory [JOB_TITLE]
nipux metrics [JOB_TITLE]
nipux usage [JOB_TITLE] [--json]
nipux artifacts [JOB_TITLE] [--paths]
nipux artifact QUERY_OR_TITLE [--job JOB_TITLE]
nipux lessons [JOB_TITLE]
nipux learn [--job JOB_TITLE] [--category CATEGORY] LESSON
nipux logs [JOB_TITLE] [--limit N] [--verbose]
nipux outputs [JOB_TITLE] [--limit N] [--verbose]
nipux watch JOB_TITLE [--verbose]
nipux run-one JOB_TITLE [--fake]
nipux work [JOB_TITLE] [--steps N] [--verbose] [--dashboard]
nipux run [JOB_TITLE] [--poll-seconds N] [--no-follow]
nipux daemon [--once] [--fake] [--verbose] [--poll-seconds N]
nipux digest JOB_TITLE
nipux daily-digest [--day YYYY-MM-DD]
```

## Development

```bash
PYTEST_ADDOPTS='' uv run --extra dev python -m pytest -q
uv run --extra dev ruff check --isolated nipux_cli tests/nipux_cli
```

The active implementation notes live in `plans/nipux-runtime-notes.md`.
