---
title: Change your first App
description: Initialize one exact Host workspace, add a Plugin Bundle, inspect the derived App, run it, and remove the change.
---

The [Quickstart](/docs/core/quickstart) proves one Plugin in isolation. This
guide completes the next boundary: make that Bundle an explicit difference in
one real App.

You need two artifacts from the product Host owner:

- the Host executable; and
- `host-catalog.json` emitted by that exact Host build.

The generic CLI cannot invent the Host's root Slots, embedded Plugins,
replacement policy, Runtime Driver, or Execution Adapters.

## 1. Initialize the App workspace

Keep the Host and its matching Catalog together:

```sh
lenso app init \
  --host ./host \
  --host-catalog ./host-catalog.json \
  --root ./my-app
```

This creates the only two App-owner-visible roots:

```text
my-app/
├── .lenso/
│   ├── host
│   └── host-catalog.json
└── plugins/
```

`.lenso/host-catalog.json` is read-only authority generated by the Host build.
`plugins/` contains only App-owned differences from its defaults.

## 2. Inspect the Host defaults

```sh
lenso plugins list --root ./my-app
lenso app show --root ./my-app
lenso app check --root ./my-app
```

`plugins list` shows every derived Plugin Instance and its source. `app show`
adds exact Capability bindings and Plan keys. `app check` gives the shortest
pass/fail validation of the derived App.

## 3. Add the Bundle

Use the Bundle produced by the Quickstart:

```sh
lenso plugins add \
  ./example.echo/dist/example.echo-0.1.0.lenso-plugin \
  --root ./my-app
```

Before committing bytes under `plugins/`, the CLI verifies the archive,
resolves the complete candidate against the Host Catalog, and rejects an
unknown Plugin, illegal replacement, missing Capability, ambiguous binding, or
invalid configuration.

Inspect the accepted result instead of inferring it from the new directory:

```sh
lenso app show --root ./my-app
lenso app check --root ./my-app
```

The new Instance must appear with the expected source and Capability binding.
If the Host Catalog does not offer this Plugin to a compatible Slot, stop: App
configuration cannot expand Host policy.

## 4. Run the current Host

```sh
lenso doctor --root ./my-app
lenso run --root ./my-app
```

`doctor` checks the Host Catalog, optional Host executable, derived App, and
external runtimes selected by its execution classes. `run` starts the copied
Host with the App derived directly from the current Plugin Root. There is no
App-owner Plan file to generate or hand-edit.

How you exercise `example.echo` now depends on the Host's product surface. An
Agent Host may expose it as a Tool; another Host may bind the same Plugin role
to a different surface.

## 5. Prove replacement and removal

Disable the Instance without deleting its configuration, inspect the result,
then enable it again:

```sh
lenso plugins disable example.echo default --root ./my-app
lenso app show --root ./my-app
lenso plugins enable example.echo default --root ./my-app
```

Finally remove the entire App-owned Plugin directory:

```sh
lenso plugins remove example.echo --root ./my-app
lenso app check --root ./my-app
```

Whole-Plugin removal uses the recoverable `.lenso/trash/` path. Passing an
Instance key removes only that Instance difference and may reveal a matching
Host default, so inspect the derived App after either operation.

You have completed the loop when add, run, disable, enable, and remove each
produce the expected observable behavior. Continue with
[Inspect and troubleshoot an App](/docs/core/inspect-an-app) when setup or
resolution does not match this path.
