Browse docsWeb viewer

Web viewer

Enso’s optional web viewer answers operational questions that are awkward to answer from chat: what an agent can see, which workspace and skills it uses, what a scheduled job is configured to do, and why its last run failed.

The viewer is intentionally read-only. It cannot start a job, send a message, edit a file, modify configuration, or repair a workspace. It is a window into Enso, not a control panel.

Install the web extra

The base CLI can report and stop viewer processes, but starting the viewer requires the web extra. From the parent directory of a local Enso source checkout named enso, install the combination you use:

# Viewer only, in addition to the base CLI
uv tool install -e './enso[web]'

# Or install transports and the viewer together
uv tool install -e './enso[slack,telegram,web]'

The extra supplies aiohttp, jinja2, and markdown-it-py. Without it, enso web start exits with an installation hint instead of a Python import traceback.

Start and stop the viewer

enso web start
enso web status
enso web stop

The default start is a background process bound to 127.0.0.1:8787. Its output goes to ~/.enso/web.log, and it holds ~/.enso/web.pid while running. start waits until the viewer answers, prints its URL, and then exits.

Run it in the foreground while diagnosing startup or rendering problems:

enso web start --port 9000 --foreground

Press Ctrl-C to stop a foreground viewer. Command-line --host and --port values take precedence over web.host and web.port in config.json.

The lifecycle commands are safe to use in scripts:

Command state Result
start while the same viewer is live Prints already running and exits 0
stop while no viewer is live Prints not running and exits 0
status while live Prints the PID and URL and exits 0
status while stopped Prints not running and exits 1
status with an obsolete PID file Reports the stale PID and exits 1

The viewer is a separate process from enso serve. Restarting or crashing it does not interrupt Slack, Telegram, or the scheduler. Conversely, installing Enso’s background service does not make the viewer survive a reboot; start the viewer again when you want it.

Configuration and recovery mode

The normal defaults are:

{
  "web": {
    "host": "127.0.0.1",
    "port": 8787
  }
}

web.port must be an integer from 1 through 65535, and web.host must be a non-empty string. Flags override either value for one start:

enso web start --host 127.0.0.1 --port 9000

Unlike enso serve, the viewer still starts when config.json is missing or invalid. It warns, falls back to 127.0.0.1:8787 unless flags provide another address, and keeps the Health page available so you can inspect the configuration error.

This recovery behavior is useful when the main service cannot start:

enso web start
# Open the printed URL, then choose Health.

See Configuration for the complete file and CLI reference for enso doctor and log filtering.

What the viewer shows

The HTML is rendered on the server. One stylesheet and one small progressive-enhancement script support filtering and sorting; pages remain useful without JavaScript, and the viewer loads no assets from the public internet.

Workspaces and files

The Workspaces view lists each workspace, the conversations bound to it, jobs that name it, and its current workspace audit. A malformed link, missing directory, untouched instruction template, skill collision, or orphaned workspace is visible before it surprises a turn.

Each workspace has a file browser limited to:

  • knowledge/ for durable reference material;
  • drafts/ for generated and editable work products;
  • uploads/ for retained chat attachments.

Text and Markdown render in place. Dotfiles are included because they can affect what the agent sees. Files larger than 2 MiB, binary files, and unreadable files show metadata rather than a body.

The renderer treats workspace content as untrusted:

  • raw HTML in Markdown is escaped;
  • image syntax remains text, so opening a page does not fetch an image;
  • only relative, http, https, and mailto links survive sanitization;
  • a path resolving outside the three allowed directories, including through a symlink, returns 404.

Skills

The Skills view resolves the workspace, Enso-home, and provider-user scopes. It shows each skill’s path, scope, description, validity, and any collision. Provider-user skills are visible for diagnosis but remain outside Enso’s management.

For example, the page can distinguish a healthy home skill from a conflicting workspace copy:

Skill Scope Status
enso-jobs Enso home active
research workspace active
research Enso home collides with workspace (error)
commit provider user active, not managed by Enso

The viewer reports; it never resolves a collision for you. See Customizing Enso for the correct locations and naming rules.

Jobs

The Jobs view shows every job’s schedule, explicit provider/model/effort triple, workspace, enabled state, next slot, latest outcome, prompt body, and configured prerun or postrun scripts. Parse and validation problems that prevent a job from running appear beside the job.

Editing JOB.md still happens on disk. Use enso job show, enso job run, and the process described in Jobs to make and test changes.

Runs

The Runs view is filterable by job and status. The list does not load large output bodies; opening a run shows its complete retained record, including status, trigger, agent, exit code, duration, error, and up to the final retained 1 MiB of provider output.

Status Meaning
ok The provider completed successfully
error The provider exited non-zero or the run otherwise failed
timeout The job exceeded its timeout and its process tree was killed
no_work The prerun exited 1, so the provider never ran
prerun_error The prerun failed, timed out, or could not start
running The run is still active, or the process ended before its row could close

This is especially useful for failed scheduled work whose output is too long for a chat alert.

Health

Health contains the same seven sections as enso doctor: configuration, home, workspaces, providers, transports, service, and jobs. It also shows:

  • the enso.db footprint, including the sizes of its -wal and -shm companions;
  • whether the main database can be opened and its schema is supported by this Enso version;
  • the last 200 lines of ~/.enso/enso.log;
  • the address on which this viewer is listening.

Sections dependent on valid configuration are marked skipped until configuration is fixed. A warning alone does not make the overall doctor result fail; a problem does.

Security model

The viewer has no authentication. Keep it on 127.0.0.1 unless an authenticated, private layer controls access.

The default loopback address is reachable only from the local machine. If --host or web.host selects a non-loopback address, enso web start warns that other machines can reach private material.

Everything displayed should be treated as sensitive: workspace files, uploads, job prompts, provider output, configuration facts, skill instructions, and log lines. The viewer does not reveal transport tokens from a configuration form because it has no editor, but the content an agent handled can contain private data.

enso serve --debug is particularly sensitive. Debug mode records the complete assembled prompt and raw provider events in enso.log; the Health page then exposes the newest part of that log to anyone who can reach the viewer. Use debug mode briefly, avoid it around secrets, and stop or rotate sensitive logs according to your own retention policy.

For remote access, keep Enso bound to loopback and place it behind a private tunnel or reverse proxy that authenticates every request. Do not expose the unauthenticated port directly to a public or shared network.

HTTP behavior

The viewer serves GET requests only. Other methods, including HEAD, receive 405. Health monitors that assume HEAD should be configured to perform a small GET instead.

HTML pages use Cache-Control: no-store. Packaged CSS and JavaScript use no-cache with ETags, so clients may retain them but must revalidate. Responses include a restrictive Content Security Policy permitting only the viewer’s own stylesheet and script. The server opens enso.db in read-only mode and writes only its log and PID file; viewing a page cannot mutate Enso state or block the main service’s database work.

Troubleshooting

enso web start says an extra is missing

Reinstall the local checkout with the web extra included. enso web status and stop do not require the extra, but start does.

The viewer starts on an unexpected address

Flags win over configuration. Run enso web stop, inspect the web block with enso config show, then start with explicit loopback values:

enso web stop
enso config show
enso web start --host 127.0.0.1 --port 8787

The viewer reports already running

Use enso web status and open the URL it prints. start intentionally does not replace an existing live viewer.

status reports a stale PID

No matching viewer owns the old lock. A subsequent start handles the stale file. If startup still fails, inspect ~/.enso/web.log and run in the foreground to see the immediate error.

A workspace file is missing or returns 404

Only files resolving under that workspace’s knowledge/, drafts/, and uploads/ directories are served. Files outside those roots and symlinks escaping them are intentionally unavailable.

Data looks stale

Refresh the page first: every request reads current files and database state. Job definitions are reloaded by the main service once per minute, while configuration and bindings require a enso service restart before the service uses changes. The viewer can show the file on disk even before the service reloads it.

The Health page contains private text

Stop external access immediately, then inspect how the viewer was bound and whether debug logging was enabled. The viewer is behaving as designed by showing the Enso log; the corrective action is to restore private access and handle the log according to your security requirements.