Metadata-Version: 2.5
Name: wisbot
Version: 0.1.1
Summary: WisBot command-line interface: deploy, preview and review from your terminal or coding agent.
Project-URL: Homepage, https://wisbot.ai
Author: WisBot
Keywords: claude-code,cli,code-review,codex,deploy,preview,wisbot
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: typer>=0.12
Provides-Extra: test
Requires-Dist: pytest>=8; extra == 'test'
Requires-Dist: respx>=0.21; extra == 'test'
Description-Content-Type: text/markdown

# wisbot CLI

Deploy, preview and review your app on WisBot from the terminal, or let Claude Code / Codex do it for you.
Code reaches WisBot through GitHub: the CLI pushes your current branch, then calls WisBot with the repo and branch.

## Install

```bash
uv tool install wisbot
# or: pipx install wisbot
# upgrade later with: uv tool upgrade wisbot
```

## Log in

```bash
wisbot login            # opens the browser; approve the code shown in the terminal
wisbot whoami
```

The token is stored in `~/.wisbot/config.json` (mode 0600). Production deploys need the
`deploy:prod` scope: `wisbot login --scopes read,deploy,sandbox,review,deploy:prod`.
For CI, create a token in WisBot under **Account → CLI & access tokens** and set `WISBOT_TOKEN`.
`WISBOT_API_URL` (or `--api-url`) points the CLI at another WisBot instance.

## Commands

```
wisbot deploy [--env dev|prod] [--yes] [--allow-destroy]   # push, plan, (approve), apply
wisbot deploy approve <id> --yes | status <id> | logs <id> | list | terminate <id> --yes
wisbot preview launch [--replace]                           # push, sync, run preview sandbox
wisbot preview status | logs [--follow] | stop
wisbot sandbox launch | status | services | logs [--service NAME] [--tail N] [--follow] | stop
wisbot sandbox test [--service NAME] [--workdir /app] -- COMMAND [ARGS...]
wisbot sandbox exec [--service NAME] -- COMMAND [ARGS...]
wisbot review [--pr N] [--title ...] [--base ...]           # push, open PR if needed, AI review
wisbot skill install [--project] [--codex-print]
wisbot login | logout | whoami | version
```

Add `--json` to any command for a single machine-readable object on stdout.

Exit codes: `0` ok, `1` unexpected error, `2` usage, `3` auth/scope, `4` not found,
`5` precondition/conflict, `6` remote failure, `7` timeout, `10` deployment awaiting approval.

Without `--yes`, `wisbot deploy` stops with exit code 10 once the plan is ready, so a person
(or an agent that asked one) can review it before `wisbot deploy approve <id> --yes`.

## Use a sandbox and run tests

`sandbox` and `preview` are aliases; existing preview commands continue to work.
Launch the committed branch, find its application services, then inspect logs or run a test command:

```bash
wisbot sandbox launch
wisbot sandbox services
wisbot sandbox logs --service backend --tail 50
wisbot sandbox logs --service backend --follow
wisbot sandbox test --service backend -- python -m pytest -q
wisbot sandbox test --service frontend -- npm test -- --run
wisbot sandbox exec --service backend --workdir /app -- sh -lc 'curl -fsS http://localhost:8000/health'
wisbot sandbox stop
```

Commands select the active sandbox for the current repository and branch. Use `--branch` to
select another branch, or `--container NAME` for `exec`/`test` without a local checkout. Status,
services, logs, and stop accept an optional sandbox name as their positional argument.
`--service` is required when the sandbox has multiple application containers.
Execution refuses a sandbox on another branch. The backend also checks the selected branch before
running the command. With an explicit `--container`, add `--branch` to require a specific branch.

`exec` and `test` run the exact arguments after `--`, using the service's configured user,
environment, and working directory. Shell expressions require an explicit `sh -lc` as above.
They use the code already in the sandbox; launch again after committing changes to sync and restart it.
The service image must include the test tools, `sh`, `sleep`, and `setsid` (`util-linux` on
Debian-based images, or the BusyBox applet on Alpine). A supervisor runs inside the service,
stops the command's process group on timeout, and records the deadline independently of exit status.
It cleans up remaining processes in that group when the command finishes. Commands run only in
application services of current sandboxes; they do not depend on the image's `timeout` utility.

Execution waits for completion with a 300-second limit (`--timeout 1..600`), and retains the last
64 KiB each of stdout and stderr so final test summaries survive truncation. With `--json`, the result
includes `exit_code`, `stdout`, `stderr`, `timed_out`, and `output_truncated`.
A failing test exits the CLI with code 6 while preserving
the command's exit status in the result; a timeout exits with code 7. Logs return a finite snapshot
by default, up to 100 recent lines per service; `--follow` streams until interrupted and cannot
be combined with `--json`. If an older server keeps streaming a snapshot, an idle timeout
returns the lines already received, including in JSON mode. A timeout before any lines arrive
still fails; `--idle` controls this timeout (30 seconds by default).

The WisBot server must enable CLI token authentication (`WISBOT_WSGI_PAT_ENABLED=true`).
Service discovery and logs need the `read` scope; execution needs `sandbox`. Repository grants
and sandbox ownership are checked on every request. Saved sandbox values of at least eight characters
are redacted from output and echoed arguments; credential patterns also redact shorter secrets in context.

## Coding agents

- **Claude Code:** `wisbot skill install` (user-wide) or `wisbot skill install --project` (this repo).
- **Codex:** `wisbot skill install --codex-print >> AGENTS.md`.

Then ask the agent things like "deploy this to WisBot dev", "preview this branch on WisBot", or
"get a WisBot review of my PR".

## Development

```bash
cd cli
uv venv .venv && uv pip install -p .venv -e '.[test]'
.venv/bin/pytest
```

## Releasing

Published to PyPI as [`wisbot`](https://pypi.org/p/wisbot) by `.github/workflows/publish-cli.yml`.

1. Bump `__version__` in `wisbot_cli/__init__.py` and merge to `main`.
2. Optional dry run: run the workflow manually (Actions → *CLI (test & publish to PyPI)* → Run workflow),
   which publishes to TestPyPI; check with `uv tool install --index-url https://test.pypi.org/simple/ --index-strategy unsafe-best-match wisbot`.
3. Tag and push: `git tag cli-v0.1.1 && git push origin cli-v0.1.1`. The workflow tests, builds, checks
   the tag matches `__version__`, and publishes to PyPI. Pushing the tag is the release decision:
   the `pypi` environment only accepts `cli-v*` tags, and has no required reviewers.
