# Installation

Enso `0.1.0` is currently an unreleased, pre-production project. There is no public
package or working public source repository yet, so there is no supported public install
command. In particular, Enso does not publish an `install.sh` script.

If you already have an authorized Enso source checkout, the steps below describe the
current source installation. Otherwise, use this documentation to evaluate Enso and wait
for a public distribution before trying to install it.

## Requirements

An Enso machine needs:

- **macOS or Linux.** The background-service integration uses launchd or systemd.
- **Python 3.14.** The package declares `requires-python = ">=3.14"`.
- **[uv](https://docs.astral.sh/uv/).** Enso is currently installed as a uv tool from a
  source checkout.
- **At least one supported agent CLI:** `claude`, `codex`, or `grok`, already installed and
  authenticated for the account you intend to use.
- **At least one chat transport:** a Slack app using Socket Mode or a Telegram bot token.

Enso drives provider CLIs; it does not install them, log into them, or replace their
credentials. Before starting setup, confirm at least one provider works in your terminal:

```bash
command -v claude
command -v codex
command -v grok
```

Only one needs to be present. Run that CLI's own harmless help or status command if you are
unsure whether its authentication is current.

## Install from a source checkout

From the root of an authorized Enso checkout, install the transports and optional viewer
you need:

```bash
cd /path/to/enso
uv tool install -e '.[slack,telegram,web]'
```

The extras are independent:

| Extra | Adds | Include when |
| --- | --- | --- |
| `slack` | Slack Bolt and its HTTP dependency | You will connect a Slack app |
| `telegram` | Python Telegram Bot | You will connect a Telegram bot |
| `web` | aiohttp, Jinja, and Markdown rendering | You want the local read-only viewer |

Install only what you use. For example, a Telegram-only host without the viewer can use:

```bash
uv tool install -e '.[telegram]'
```

The base CLI still includes `enso web status` and `enso web stop` without the `web`
extra. `enso web start` explains which extra is missing instead of failing with an import
traceback.

Confirm the executable is available:

```bash
command -v enso
enso --help
```

If the first command prints nothing, ensure uv's tool executable directory is on `PATH`.
Use uv's own environment guidance for your shell rather than hard-coding a path from
another machine.

## Prepare a transport

Setup connects one transport. You can add the second later in `config.json`.

### Slack preparation

Slack requires both a bot token and an app-level token with Socket Mode enabled. The
authorized source checkout includes `assets/slack/manifest.json`, which declares the exact
scopes and events Enso needs.

Before running setup:

1. Create a Slack app from that manifest.
2. Enable or confirm Socket Mode.
3. Keep the bot token (`xoxb-…`) and app-level token (`xapp-…`) available.
4. Decide which channel or direct message should receive the setup test.
5. Invite the bot to every channel you later bind.

When applying the manifest to an existing app that has broader scopes, revoke the old bot
token before reinstalling the app. Slack does not remove old scopes from a live token. A
reinstall also removes the bot from channels, so invite it again afterward.

### Telegram preparation

Telegram uses one bot token and an allowlist of numeric user ids. Setup waits for you to
send the bot a private message, then records the sender's numeric id.

Enso accepts Telegram private chats only. Users not listed in `allowed_users` are ignored
silently, so make sure the account you use during setup is the account you intend to
allow.

## Run guided setup

Use your real Enso home only when you are ready to create persistent configuration:

```bash
enso setup
```

On a fresh home, the wizard proceeds in order:

1. Detects supported provider CLIs on `PATH` and records their available model choices and
   unattended permission flags.
2. Asks for the default provider, model, and effort.
3. Connects one Slack or Telegram transport. Slack validates the bot token; Telegram waits
   for a private message so it can capture the user's numeric id.
4. Creates the `default` workspace and seeds the home instructions, bundled skills,
   discovery links, and empty Git root.
5. Writes `config.json`, sends a test when a notification destination is configured, and
   offers to install the background service.

The wizard is intended for a fresh home. If setup reports existing or invalid state, stop
and inspect it instead of repeatedly overwriting files. Enso's configuration and
workspace audit commands collect problems without requiring you to guess which file is
wrong.

### What setup creates

The important initial paths are:

```text
~/.enso/
├── config.json
├── AGENTS.md
├── CLAUDE.md -> AGENTS.md
├── skills/
├── workspaces/default/
│   ├── AGENTS.md
│   ├── knowledge/
│   ├── drafts/
│   ├── uploads/
│   └── skills/
├── jobs/
├── secrets/
└── .git/
```

See [Workspaces](/docs/workspaces/) before changing this layout manually. The links and Git
root are part of provider instruction and skill discovery, not incidental scaffolding.

## Install and operate the service

If you did not install the service during setup, do it explicitly:

```bash
enso service install
enso service status
```

The service command supports the full lifecycle:

```bash
enso service start
enso service stop
enso service restart
enso service status
enso service uninstall
```

`service install` writes a user service for the particular `enso` executable on your
current `PATH`, then starts it. The unit is stored at:

- `~/Library/LaunchAgents/com.enso.agent.plist` on macOS;
- `~/.config/systemd/user/enso.service` on Linux.

The generated service environment includes a `PATH` that covers every configured provider.
If you later move or reinstall a provider or Enso itself, `enso doctor` warns when the
service unit and current executable no longer agree.

Restart the service after editing `config.json`; transports, providers, bindings, and
workspace overrides load at process start. `JOB.md` files are different: the scheduler
reloads them every minute, so job edits need no service restart.

## Verify the installation

Run the checks from narrowest to broadest:

```bash
enso config check
enso workspace audit
enso doctor
enso service status
```

- `config check` validates strict JSON and reports every configuration problem it can find.
- `workspace audit` checks the Enso home, fixed directory layout, instruction links, skill
  links, collisions, bindings, and jobs.
- `doctor` combines those checks with provider paths, transport extras, service state, and
  all job definitions.
- `service status` confirms whether the installed user service is actually running.

Then test the transport:

- Send `!help` in a bound Slack conversation.
- Send `/help` in a bound Telegram private chat.

Use `!status` or `/status` to see the effective workspace and agent, where the agent choice
came from, the current session age, active work, and queue depth.

## Read logs without exposing too much

The main rotating log is `~/.enso/enso.log`:

```bash
enso logs -n 100
enso logs -f
enso logs --job morning-brief
enso logs --turn a1b2c3
enso logs --grep timeout
```

On macOS, service stdout and stderr also go to `~/.enso/launchd.log`; this is mainly useful
when the process crashes before normal logging starts.

Avoid `enso serve --debug` on a shared or poorly protected machine. Debug mode records
complete prompts and raw provider events, which can include private chat content, file
paths, tool output, and secrets exposed by a provider.

## Start the optional viewer

With the `web` extra installed:

```bash
enso web start
enso web status
```

The default URL is `http://127.0.0.1:8787`. The viewer runs separately from the service,
writes to `~/.enso/web.log`, and does not survive a reboot. It is read-only and has no
authentication, so keep it on localhost unless a trusted private tunnel or authenticated
reverse proxy controls access.

Stop it independently:

```bash
enso web stop
```

See [Web viewer](/docs/web/) for its pages and threat model.

## Add the second transport or more workspaces

The first-run wizard connects one transport and creates `default`. Further setup is
file-based:

1. Create another workspace with `enso workspace create NAME`.
2. Add the second transport and any bindings to `~/.enso/config.json`.
3. Run `enso config check` and `enso workspace audit`.
4. Restart the service.
5. Send `status` in the newly bound conversation to confirm the route.

Follow [Configuration](/docs/configuration/) for strict copyable examples and
[Workspaces](/docs/workspaces/) before editing workspace internals.

## Upgrade a source installation

Enso is pre-production and provides no migration promise yet. When an authorized source
checkout is updated:

1. Read its changelog and documentation before reinstalling.
2. Update the checkout using the method supplied by its distributor.
3. Repeat the same `uv tool install -e '.[…]'` command from the source root.
4. Run `enso config check` and `enso workspace audit`.
5. Fix every reported incompatibility.
6. Reinstall or restart the service if the Enso executable location changed.

Back up `~/.enso` before testing a version that changes the config schema, database, or
home layout.

## Development and isolated evaluation

Contributors with a source checkout can create the development environment with:

```bash
uv sync --all-extras
uv run ruff check .
uv run ruff format --check .
uv run mypy
uv run pytest
```

Always point manual development runs at a scratch home:

```bash
ENSO_HOME=/tmp/enso-dev uv run enso setup
ENSO_HOME=/tmp/enso-dev uv run enso serve --debug
```

That prevents development setup, config, jobs, sessions, and logs from touching the real
`~/.enso` home.

## Installation troubleshooting

### `enso` is not found

Confirm `uv tool install` succeeded, then add uv's tool executable directory to your shell
`PATH`. Start a new shell and retry `command -v enso`.

### A provider is missing

Run `command -v claude`, `command -v codex`, or `command -v grok` in the same environment.
If it works interactively but not as a service, run `enso doctor` and compare the provider
path in `config.json` with the service's recorded executable paths.

### The service runs but chat is silent

Check, in order:

```bash
enso doctor
enso service status
enso logs -n 100
```

Then confirm the chat location has a binding, the named workspace exists, the Slack bot was
invited to the channel or the Telegram user id is allowed, and the configured transport
extra is installed.

### Configuration changed but behavior did not

Run `enso config check`, then `enso service restart`. Configuration loads only when the
service starts. Job files are the exception and reload on the scheduler's next minute tick.
