diff --git a/api-reference/error-codes.mdx b/api-reference/error-codes.mdx
index bfb38a3..1dae07e 100644
--- a/api-reference/error-codes.mdx
+++ b/api-reference/error-codes.mdx
@@ -159,15 +159,15 @@ Load-shedding on a saturated API instance — back off and retry.
## Fleet Bundle
-Import + snapshot of a Fleet Bundle (the SKILL.md/TRIGGER.md package behind a Fleet) via `POST /v1/workspaces/{workspace_id}/fleets/bundles/snapshots`.
+Onboarding a Fleet template (the SKILL.md/TRIGGER.md package behind a Fleet) and installing it. Onboard a template via `POST /v1/admin/fleet-templates` (platform tier) or `POST /v1/workspaces/{workspace_id}/fleet-templates` (your workspace's tenant tier); install one via `POST /v1/workspaces/{workspace_id}/fleets`.
| Code | HTTP | Title | Common Causes |
|---|---|---|---|
| `UZ-BUNDLE-001` | 400 | Invalid Fleet Bundle | The supplied bundle is missing `SKILL.md` or contains unsafe, oversized, or malformed files. |
-| `UZ-BUNDLE-002` | 404 | Fleet Bundle not found | No Fleet Bundle snapshot matches the supplied `bundle_id` in this workspace. |
-| `UZ-BUNDLE-003` | 424 | Fleet Bundle credentials missing | Add the workspace credentials named in `missing_credentials` before installing this bundle. |
+| `UZ-BUNDLE-002` | 404 | Fleet Bundle not found | No installable template or stored snapshot matches the request in this workspace. The `platform_template_id`/`tenant_template_id` is unknown, or the template has not been onboarded yet. |
+| `UZ-BUNDLE-003` | 424 | Fleet Bundle credentials missing | Add the workspace credentials named in `missing_credentials` before installing this template. |
| `UZ-BUNDLE-004` | 502 | Fleet Bundle fetch failed | The bundle source could not be fetched from GitHub — the repository may be missing or private, or GitHub may be unreachable. Verify the source reference and retry. |
-| `UZ-BUNDLE-005` | 503 | Fleet Bundle storage unavailable | Snapshot storage is not configured or is unavailable, so the validated bundle could not be stored. Retry later or contact the operator. |
+| `UZ-BUNDLE-005` | 503 | Fleet Bundle storage unavailable | Template object storage is not configured or is unavailable, so the onboarded bundle could not be stored. Retry later or contact the operator. |
| `UZ-BUNDLE-006` | 429 | Too many Fleet Bundle imports in flight | This instance is at its concurrent import ceiling. Honor the `Retry-After` header and retry with backoff. |
## Integration grants
diff --git a/changelog.mdx b/changelog.mdx
index 27693cb..64ca871 100644
--- a/changelog.mdx
+++ b/changelog.mdx
@@ -22,6 +22,36 @@ export const STAGE_SELF_MANAGED_M66 = "$0.0001";
agentsfleet is in **stealth-mode testing** and pre-production. APIs and agent behavior may change between releases without long deprecation windows. Email [agentsfleet@agentmail.to](mailto:agentsfleet@agentmail.to) if you want a hand calibrating an agent or to join as a design partner.
+
+ ## Bring your own Fleet templates
+
+ You can now onboard your own Fleet templates into your workspace, alongside the curated platform catalogue. The install gallery shows both — the platform templates and your workspace's own — and you install any of them by id. Templates are stored once, content-addressed, and shared across the fleets you spin up from them. Installing a fleet is now always "pick a template, install it"; the old "paste a local `SKILL.md`" and "import a GitHub repo at install" paths are gone.
+
+ ## Upgrading
+
+ - **Install is template-only.** `agentsfleet install --from ` (installing a new fleet from a local directory) has been removed. Install by id instead: `agentsfleet install --template `. To run a fleet you authored yourself, onboard its `SKILL.md`/`TRIGGER.md` as a template first — through the dashboard or the onboarding API — then install it by id. To push local edits onto an **already-installed** fleet, use `agentsfleet fleet update --from ` (unchanged). Upgrade the CLI and server together.
+ - **Fleet-create takes a template id, not a bundle.** `POST /v1/workspaces/{workspace_id}/fleets` now accepts exactly one of `{platform_template_id}` or `{tenant_template_id}` (plus an optional `name`). Raw `source_markdown`, the per-workspace `bundle_id`, and the github-import-at-create body are rejected. Onboard a template, then install it by id.
+ - **Bundle import/snapshot endpoints removed.** `POST /v1/workspaces/{workspace_id}/fleets/bundles/snapshots` and the snapshot-detail read no longer exist. Use the onboarding routes below.
+
+ ## What's new
+
+ - **Onboard templates into two tiers.** Onboard a template into the global platform catalogue or into your own workspace; workspace templates are visible only to your workspace.
+ - **One gallery, both tiers.** The dashboard install gallery unions the platform catalogue with your workspace's own templates, and never shows another workspace's templates.
+ - **Templates explain their credentials.** Gallery entries carry a description and per-credential "why this is needed" copy, so the install gate can tell you what each credential is for before you connect it.
+
+ ## API reference
+
+ - **`GET /v1/workspaces/{workspace_id}/fleet-templates`** — the workspace gallery: the platform catalogue plus this workspace's own templates. Each entry carries `id`, `name`, `description`, `visibility` (`"platform"` or `"tenant"`), `source_ref`, `requirements`, `required_credentials_reasons`, and support-file summaries — never an object-store key.
+ - **`POST /v1/admin/fleet-templates`** (scope `platform-template:write`) and **`POST /v1/workspaces/{workspace_id}/fleet-templates`** (scope `template:write` + workspace ownership) — onboard a template from a GitHub source into the platform or workspace tier. The canonical bundle is written to object storage keyed by content hash; the response is metadata only.
+ - **`POST /v1/workspaces/{workspace_id}/fleets`** — install body is now `{platform_template_id}` **or** `{tenant_template_id}`, plus an optional `name` so one template can back several fleets.
+ - **`UZ-BUNDLE-002`** now reads "No installable template or stored snapshot matches the request in this workspace."
+
+ ## CLI
+
+ - **`agentsfleet install --template `** resolves the template in your workspace gallery and installs it by tier. The `--from ` option has been removed from `install`.
+ - **`agentsfleet fleet update --from `** (live-editing an installed fleet's instructions from a local directory) is unchanged.
+
+
## Authorization is now scope-based
diff --git a/cli/agentsfleet.mdx b/cli/agentsfleet.mdx
index e580def..f23180f 100644
--- a/cli/agentsfleet.mdx
+++ b/cli/agentsfleet.mdx
@@ -8,7 +8,7 @@ description: "Complete agentsfleet command reference."
| Group | Commands |
|-------|----------|
| Authentication | `login`, `logout`, `auth status` |
-| Fleets (top-level) | `install --from`, `install --template`, `templates`, `list`, `status`, `stop`, `resume`, `kill`, `delete`, `logs`, `events`, `steer` |
+| Fleets (top-level) | `install --template`, `templates`, `list`, `status`, `stop`, `resume`, `kill`, `delete`, `logs`, `events`, `steer` |
| Fleets (in-place update) | `fleet update --from` |
| Credentials | `credential add`, `credential show`, `credential list`, `credential delete` |
| Workspaces | `workspace add`, `workspace list`, `workspace use`, `workspace show`, `workspace credentials`, `workspace delete` |
@@ -89,32 +89,23 @@ The probe result is one of `valid` (200 from the billing endpoint), `unauthorize
## Fleets
-### `agentsfleet install --from `
-
-Reads `SKILL.md` and `TRIGGER.md` from ``, validates them server-side, and uploads to the active workspace. `SKILL.md` is required; `TRIGGER.md` is optional (a default API wake is generated when it's absent). `install` needs exactly one source — `--from ` or `--template `; there are no bare-name aliases.
-
-```bash
-agentsfleet install --from ./my-fleet
-```
-
-For a curated, ready-to-run fleet, use `agentsfleet install --template ` instead (browse with `agentsfleet templates`). See [Quickstart](/quickstart) and [Templates](/fleets/templates).
-
### `agentsfleet install --template `
-Install a fleet from the first-party template catalogue (browse it with `agentsfleet templates`) instead of a local directory. agentsfleet fetches the template's pinned source, validates it, prints a requirements preview (credentials, tools, network hosts), then creates the fleet.
+Install a fleet from your workspace gallery — the first-party platform catalogue plus your workspace's own onboarded templates. agentsfleet resolves the template by id, fetches its pinned `SKILL.md` + `TRIGGER.md`, prints a requirements preview (credentials, tools, network hosts), then creates the fleet in the active workspace. `install` takes exactly one source, `--template `; there are no bare-name aliases and no local-directory install.
```bash
agentsfleet install --template github-pr-reviewer
agentsfleet install --template github-pr-reviewer --name pr-reviewer-frontend
```
-`--from` and `--template` are mutually exclusive — exactly one source per install. If the template ships no `TRIGGER.md`, a default API wake is generated and the result notes it.
+If the template ships no `TRIGGER.md`, a default API wake is generated and the result notes it.
+
+To run a fleet you wrote yourself, onboard its `SKILL.md` + `TRIGGER.md` as a template first — via the dashboard or the API (`POST /v1/admin/fleet-templates` for the platform tier, `POST /v1/workspaces/{workspace_id}/fleet-templates` for a workspace template) — then install it by id. Frontmatter is validated at onboard time. There is no CLI onboard command. See [Authoring a fleet](/fleets/authoring) and [Templates](/fleets/templates).
| Flag | Default | Purpose |
|------|---------|---------|
-| `--from ` | *(one source required)* | Install from a local directory containing `SKILL.md` + `TRIGGER.md`. |
-| `--template ` | *(one source required)* | Install from a catalogue template by id (see `agentsfleet templates`). |
-| `--name ` | *(SKILL.md `name:`)* | Override the fleet name so one bundle or template can back several fleets in a workspace. Without it, a second install of the same source collides with `UZ-AGT-006`. |
+| `--template ` | *(required)* | Install from a workspace-gallery template by id (browse the platform tier with `agentsfleet templates`). |
+| `--name ` | *(SKILL.md `name:`)* | Override the fleet name so one template can back several fleets in a workspace. Without it, a second install of the same template collides with `UZ-AGT-006`. |
### `agentsfleet templates`
diff --git a/cli/install.mdx b/cli/install.mdx
index 927f103..40c5c16 100644
--- a/cli/install.mdx
+++ b/cli/install.mdx
@@ -35,7 +35,7 @@ agentsfleet templates # browse the catalogue
agentsfleet install --template github-pr-reviewer
```
-Or install a local bundle you authored with `agentsfleet install --from ` (see [Authoring a fleet](/fleets/authoring)).
+Authored your own `SKILL.md` + `TRIGGER.md`? Onboard it as a template (via the dashboard or the API), then install it by id with `agentsfleet install --template `. To push local edits onto an already-installed fleet, use `agentsfleet fleet update --from `. See [Authoring a fleet](/fleets/authoring).
**One-line bootstrap.** `curl -fsSL https://agentsfleet.dev | bash` installs the `agentsfleet` CLI (it runs npm under the hood — Node required). Run `curl -fsSL https://agentsfleet.dev` without `| bash` to read it first.
diff --git a/fleets/authoring.mdx b/fleets/authoring.mdx
index b37271d..d6bbe63 100644
--- a/fleets/authoring.mdx
+++ b/fleets/authoring.mdx
@@ -13,7 +13,7 @@ my-fleet/
└── TRIGGER.md # machine-readable config + deployment metadata
```
-`agentsfleet install ` scaffolds both. This page is the reference for authoring your own.
+Installing a [template](/fleets/templates) with `agentsfleet install --template ` gives you a fleet backed by both files. This page is the reference for authoring your own — which you then onboard as a template (dashboard or API) before installing by id.
## `SKILL.md` — fleet instructions
@@ -35,12 +35,12 @@ model: claude-sonnet-4-6 # optional, hint
| Field | Required | Purpose |
|---|---|---|
-| `name` | yes | Identity. Must equal `TRIGGER.md` `name:` (install rejects mismatch). |
+| `name` | yes | Identity. Must equal `TRIGGER.md` `name:` (onboarding rejects mismatch). |
| `description` | yes | One-line summary. |
| `version` | yes | Semver string. |
| `when_to_use`, `tags`, `author`, `model` | no | Pass-through metadata. |
-Unknown top-level keys are accepted silently — drop in vendor-specific extras (`x-amp:`, etc.) without breaking install.
+Unknown top-level keys are accepted silently — drop in vendor-specific extras (`x-amp:`, etc.) without breaking onboarding.
### Body
@@ -130,7 +130,7 @@ Validation under this block is rigid: an unknown subkey is rejected with a typo
| Subkey | Required | Purpose |
|---|---|---|
-| `triggers[]` | yes | Array of 1–8 trigger entries. The singular `trigger:` shape is rejected at install with `UZ-AGT-008` (invalid fleet config). Entries are unique on the `(type, source)` tuple; at most one `cron` entry. |
+| `triggers[]` | yes | Array of 1–8 trigger entries. The singular `trigger:` shape is rejected at onboard time with `UZ-AGT-008` (invalid fleet config). Entries are unique on the `(type, source)` tuple; at most one `cron` entry. |
| `triggers[].type` | yes | One of `webhook` \| `cron` \| `api`. See the table below. |
| `triggers[].source` | per type | Required for `webhook`. Carries the upstream label (e.g. `github`, `slack`, `linear`) and selects the per-trigger URL `…/v1/webhooks/{fleet_id}/{source}` — see [Webhooks](/fleets/webhooks). |
| `triggers[].events` | optional | Per-webhook event whitelist (1–16 entries, ≤64 chars each). Omit to accept every event the source delivers. |
@@ -186,17 +186,19 @@ A breach terminates the in-flight event cleanly and records a `budget_breach` en
## Validation
-`agentsfleet install --from ` reads both files and posts them to the server, which runs the same parser the runtime uses — there is no separate local lint step. Errors come back as a `UZ-AGT-*` wire code with a suggestion.
-
-```bash
-agentsfleet install --from ./my-fleet
-```
+Authoring produces a template you **onboard** — through the dashboard or the API (`POST /v1/admin/fleet-templates` for the platform tier, `POST /v1/workspaces/{workspace_id}/fleet-templates` for a workspace template). Onboarding posts both files to the server, which runs the same parser the runtime uses — there is no separate local lint step. Errors come back as a `UZ-AGT-*` wire code with a suggestion:
```
UZ-AGT-011 SKILL.md and TRIGGER.md disagree on `name:`
Suggestion: make the top-level name: identical in both files
```
+Once onboarded, install the template by id with `agentsfleet install --template `. To re-parse and validate edits against an already-installed fleet, push them with `agentsfleet fleet update --from ` — the same parser runs and returns the same `UZ-AGT-*` codes.
+
+```bash
+agentsfleet fleet update 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 --from ./my-fleet
+```
+
## Next
diff --git a/fleets/credentials.mdx b/fleets/credentials.mdx
index 6af829c..8a339dd 100644
--- a/fleets/credentials.mdx
+++ b/fleets/credentials.mdx
@@ -124,7 +124,7 @@ x-agentsfleet:
At event delivery time the tool bridge fetches each named secret from the vault and substitutes it into the outbound HTTP call. The fleet never sees the resolved value.
-If a fleet references a credential that is not present in the vault when `agentsfleet install --from ` is called, install fails with a clear error listing the missing names.
+If a fleet references a credential that is not present in the vault when `agentsfleet install --template ` is called, install fails with a clear error listing the missing names.
## Rotation
diff --git a/fleets/install.mdx b/fleets/install.mdx
index e05082a..9b617fa 100644
--- a/fleets/install.mdx
+++ b/fleets/install.mdx
@@ -1,12 +1,13 @@
---
title: "Installing a fleet"
-description: "What `agentsfleet install --from ` does and how to invoke it."
+description: "What `agentsfleet install --template ` does and how to invoke it."
---
-`agentsfleet install --from ` is how you bring a fleet up. It reads `SKILL.md` and `TRIGGER.md` from the directory you point at, validates them, and uploads to your active workspace. **Install is the deploy** — there's no separate `up` step.
+`agentsfleet install --template ` is how you bring a fleet up. It resolves the template from your workspace gallery — the platform catalogue plus your workspace's own onboarded templates — reads the template's already-onboarded `SKILL.md` and `TRIGGER.md`, prints a requirements preview, then creates the fleet in your active workspace. **Install is the deploy** — there's no separate `up` step.
```bash
-agentsfleet install --from ./platform-ops
+agentsfleet templates # browse the platform catalogue
+agentsfleet install --template github-pr-reviewer
```
```
@@ -16,20 +17,36 @@ agentsfleet install --from ./platform-ops
github: https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github
```
-One URL is printed per declared `webhook` trigger in `TRIGGER.md`, keyed by `triggers[].source`. Register each URL on its upstream provider — on GitHub, **Settings → Webhooks** (or `gh api -X POST repos///hooks …`). See [Webhooks](/fleets/webhooks) for the signature config the platform expects.
+One URL is printed per declared `webhook` trigger in the template's `TRIGGER.md`, keyed by `triggers[].source`. Register each URL on its upstream provider — on GitHub, **Settings → Webhooks** (or `gh api -X POST repos///hooks …`). See [Webhooks](/fleets/webhooks) for the signature config the platform expects.
+
+Pass `--name ` to override the fleet name so one template can back several fleets in a workspace. Without it, a second install of the same template collides with `UZ-AGT-006`.
+
+```bash
+agentsfleet install --template github-pr-reviewer --name pr-reviewer-frontend
+```
+
+## Authoring your own fleet
-Re-running against the same workspace is safe — running it twice has the same effect as running it once. Your edits to `SKILL.md` / `TRIGGER.md` replace the previous version on the next event.
+There is no local-directory install. To run a fleet you wrote yourself, **onboard** its `SKILL.md` + `TRIGGER.md` as a template first, then install it by id. Onboarding happens through the dashboard or the API — there is no CLI onboard command:
-## Install from the catalogue instead
+- **Platform tier** (visible to every workspace) — `POST /v1/admin/fleet-templates`.
+- **Workspace tier** (visible only to your workspace) — `POST /v1/workspaces/{workspace_id}/fleet-templates`.
-To start from a curated, ready-to-run fleet rather than a local directory, install a [template](/fleets/templates) by id:
+Onboarding is where the platform parses and validates your frontmatter; a malformed `SKILL.md` / `TRIGGER.md` is rejected there with a `UZ-AGT-*` wire code. Once onboarded, the template shows up in `agentsfleet templates` (platform tier) or your workspace gallery, and you install it the same way as any catalogue template:
```bash
-agentsfleet templates # browse the catalogue
-agentsfleet install --template github-pr-reviewer
+agentsfleet install --template my-onboarded-fleet
```
-`--from` and `--template` are mutually exclusive — exactly one source per install. See [Quickstart](/quickstart) for the end-to-end walkthrough from a cold machine.
+See [Authoring a fleet](/fleets/authoring) for the `SKILL.md` / `TRIGGER.md` reference and the onboarding flow.
+
+## Iterating on a running fleet
+
+To roll local `SKILL.md` / `TRIGGER.md` edits onto an already-installed fleet without re-onboarding, use [`agentsfleet fleet update --from `](/cli/agentsfleet#agentsfleet-fleet-update-fleet-id-from-path) — it re-parses the bundle and `PATCH`es it onto the live fleet. The next event runs the new prose.
+
+```bash
+agentsfleet fleet update 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 --from ./my-fleet
+```
For the self-managed provider posture, see [`agentsfleet tenant provider`](/cli/agentsfleet#tenant-provider).
@@ -40,12 +57,12 @@ For the self-managed provider posture, see [`agentsfleet tenant provider`](/cli/
| `0` | Installed (or updated). |
| `1` | Not authenticated. |
| `2` | Network error reaching the API. |
-| `3` | The API rejected the bundle (schema validation, name clash, etc.). |
-| `4` | Missing or invalid argument (e.g. no `--from`/`--template`). |
-| `5` | Bad local bundle (path missing, no `SKILL.md`). |
+| `3` | The API rejected the install (name clash, etc.). |
+| `4` | Missing or invalid argument (e.g. no `--template`). |
+| `5` | Template not found in the workspace gallery. |
## See also
- [Templates](/fleets/templates) — the catalogue of pre-built fleets you can install.
-- [Authoring a fleet](/fleets/authoring) — the `SKILL.md` and `TRIGGER.md` reference for writing your own.
+- [Authoring a fleet](/fleets/authoring) — the `SKILL.md` and `TRIGGER.md` reference, plus how to onboard your own template.
- [Starting, observing, and stopping](/fleets/running) — what to do after install.
diff --git a/fleets/overview.mdx b/fleets/overview.mdx
index 498be96..5addf64 100644
--- a/fleets/overview.mdx
+++ b/fleets/overview.mdx
@@ -26,7 +26,7 @@ flowchart LR
Killed -->|agentsfleet delete| Deleted([deleted])
```
-1. **`active`.** `agentsfleet install` reads a local `SKILL.md` + `TRIGGER.md` (or a [catalogue template](/fleets/templates)), validates the schema, uploads to your workspace, provisions the webhook URL, and starts the event loop. Install is the deploy — there is no separate `up` step. While active, each signed event (webhook, cron, or steer) opens a **run**: the fleet reads the event, reasons, invokes the tools listed in `TRIGGER.md`, and produces a result. The activity stream is the durable record — replay with `agentsfleet logs ` (or `events --actor 'webhook:*'` for filtered history).
+1. **`active`.** `agentsfleet install --template ` resolves a [template](/fleets/templates) from your workspace gallery, fetches its `SKILL.md` + `TRIGGER.md`, creates the fleet in your workspace, provisions the webhook URL, and starts the event loop. Install is the deploy — there is no separate `up` step. While active, each signed event (webhook, cron, or steer) opens a **run**: the fleet reads the event, reasons, invokes the tools listed in `TRIGGER.md`, and produces a result. The activity stream is the durable record — replay with `agentsfleet logs ` (or `events --actor 'webhook:*'` for filtered history).
2. **`paused`.** The platform pauses a fleet on its own when it trips a guardrail (rate limit or circuit breaker). While paused it refuses new work — a steer or API call returns `UZ-AGT-012`, and a webhook gets `200 {"ignored":"fleet_paused"}` so upstream senders don't retry. It returns to `active` once the condition clears, and `agentsfleet resume` forces it back early. The CLI cannot *set* `paused` — it is server-only.
3. **`stopped`.** `agentsfleet stop ` halts the running session — new events stop dispatching, the in-flight run finishes cleanly. Reversible with `agentsfleet resume`. Use this for "pause while I debug upstream"; reach for `kill` only when you mean *terminal*.
4. **`killed`.** `agentsfleet kill ` marks the fleet terminal. The row, history, and webhook URL persist but no new events are processed. State is checkpointed; nothing on the event stream is lost. Re-installing with the same `SKILL.md` produces a **new** `fleet_id`.
@@ -59,7 +59,7 @@ Billing is **not** workspace-scoped — every workspace draws on the same tenant
The guided five-minute path: install the `github-pr-reviewer` template and watch it react to a real pull request.
- Install a fleet from the catalogue or a local bundle.
+ Install a fleet from a template in your workspace gallery.
The `install`, `status`, `events`, `steer`, and `kill` commands.
diff --git a/fleets/running.mdx b/fleets/running.mdx
index ee716f0..1bef313 100644
--- a/fleets/running.mdx
+++ b/fleets/running.mdx
@@ -5,10 +5,10 @@ description: "The lifecycle commands — install, status, logs, events, steer, s
## Overview
-A small set of verbs cover the live lifecycle: `install` (from a local `--from ` or a catalogue `--template`) brings a fleet up, `status` shows what's running, `logs` (or `events` for filtered history) replays the activity stream, `steer` triggers a manual run, and `stop` / `resume` / `kill` / `delete` walk the irreversibility ladder. Each operates on the current workspace; set it with `agentsfleet workspace use` or check with `agentsfleet workspace show`.
+A small set of verbs cover the live lifecycle: `install --template ` brings a fleet up from the workspace gallery, `status` shows what's running, `logs` (or `events` for filtered history) replays the activity stream, `steer` triggers a manual run, and `stop` / `resume` / `kill` / `delete` walk the irreversibility ladder. Each operates on the current workspace; set it with `agentsfleet workspace use` or check with `agentsfleet workspace show`.
```bash
-agentsfleet install --from ./platform-ops
+agentsfleet install --template github-pr-reviewer
agentsfleet status # every fleet in the workspace
agentsfleet logs 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 # tail one fleet's recent activity
agentsfleet steer 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 "morning health check"
@@ -19,14 +19,13 @@ agentsfleet delete 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 # h
## `agentsfleet install`
-Brings a fleet up from a local bundle (`--from`) or the catalogue (`--template`) — **install is the deploy**, there is no separate `up` step. The full flag set, output shape, and exit codes live in [Installing a fleet](/fleets/install).
+Brings a fleet up from a template in your workspace gallery (`--template `) — **install is the deploy**, there is no separate `up` step. The full flag set, output shape, and exit codes live in [Installing a fleet](/fleets/install).
```bash
-agentsfleet install --from ./platform-ops # local bundle
-agentsfleet install --template github-pr-reviewer # catalogue template
+agentsfleet install --template github-pr-reviewer # workspace-gallery template
```
-Re-running against a workspace that already has the same fleet is idempotent: the new `SKILL.md` / `TRIGGER.md` replace the previous version on the next event. One webhook URL is printed per declared `webhook` trigger — register each on its upstream provider (see [Webhooks](/fleets/webhooks)).
+To run a fleet you authored, onboard it as a template first (dashboard or API), then install it by id — see [Authoring a fleet](/fleets/authoring). One webhook URL is printed per declared `webhook` trigger — register each on its upstream provider (see [Webhooks](/fleets/webhooks)). To roll local edits onto a running fleet, use `agentsfleet fleet update --from `.
## `agentsfleet status`
diff --git a/fleets/templates.mdx b/fleets/templates.mdx
index f0fe6d4..f8e132d 100644
--- a/fleets/templates.mdx
+++ b/fleets/templates.mdx
@@ -1,14 +1,14 @@
---
title: "Templates"
-description: "The first-party template catalogue and local bundles — pre-built fleets you install with one command."
+description: "The platform template catalogue and your workspace's own templates — pre-built fleets you install with one command."
---
-A **template** is a pre-built fleet you install in one command. There are two sources:
+A **template** is a pre-built fleet you install in one command, `agentsfleet install --template `. Two tiers share that one install path:
-- The **first-party catalogue** — curated templates hosted by agentsfleet, browsable with `agentsfleet templates` and installed by id.
-- A **local directory** — any folder with a valid `SKILL.md` and `TRIGGER.md`, installed with `--from`.
+- The **platform catalogue** — curated templates hosted by agentsfleet, browsable with `agentsfleet templates` and installed by id.
+- Your **workspace's own templates** — tenant templates onboarded into your workspace; once they appear in your gallery they install by the same `--template `.
-`--template` and `--from` are mutually exclusive: every `install` takes exactly one source.
+There is no `install --from ` — installing a fleet is always by template id. To run a fleet you authored, onboard it as a template first (via the dashboard or API), then `install --template `. To push local edits to an *already-installed* fleet, use `agentsfleet fleet update --from ` (see [below](#editing-an-installed-fleet-from-a-local-directory)).
New here? The [Quickstart](/quickstart) runs the `github-pr-reviewer` template end to end — browse, add the credential, install, register the webhook, and watch it react to a real pull request.
@@ -16,7 +16,7 @@ A **template** is a pre-built fleet you install in one command. There are two so
## Browse the catalogue
-`agentsfleet templates` lists the curated first-party templates — the same gallery the dashboard shows. It reads `GET /v1/fleets/bundles`; metadata only, no workspace required:
+`agentsfleet templates` lists the curated platform catalogue. It reads `GET /v1/fleets/bundles`; metadata only, no workspace required. (The dashboard install gallery shows the same platform templates **plus** any tenant templates onboarded into your workspace.)
```bash
agentsfleet templates
@@ -39,7 +39,7 @@ Install a catalogue template by its id:
agentsfleet install --template github-pr-reviewer
```
-agentsfleet fetches the template's pinned source, validates it, prints a requirements preview (credentials, tools, network hosts), then creates the fleet. If the template ships no `TRIGGER.md`, a default API wake is generated (capped at a `$1.00/day` budget) and the result notes it.
+agentsfleet resolves the template in your workspace gallery, prints a requirements preview (credentials, tools, network hosts), then creates the fleet from the onboarded template — the SKILL.md/TRIGGER.md was fetched and content-addressed when the template was onboarded, so no fetch happens at install. If the template ships no `TRIGGER.md`, a default API wake is generated (capped at a `$1.00/day` budget) and the result notes it.
Install needs every declared credential in the workspace vault first. The dashboard install gallery blocks on a missing one — there is no skip — and the CLI and API reject the install with [`UZ-BUNDLE-003`](/api-reference/error-codes#fleet-bundle), whose `missing_credentials` list names what's absent. Add the credential, then install.
@@ -54,28 +54,30 @@ agentsfleet install --template github-pr-reviewer --name pr-reviewer-backend
Without `--name`, the fleet takes the template's own `name:`. Installing the same template twice without it collides with `UZ-AGT-006` (fleet name already exists) — see [Error codes](/api-reference/error-codes).
-## Install from a local directory
+## Editing an installed fleet from a local directory
-Any directory with a valid `SKILL.md` and `TRIGGER.md` installs with `--from`:
+There is no `agentsfleet install --from ` — installing a *new* fleet is always by template id (`--template `), resolved from your workspace gallery. To run a fleet you authored locally, onboard it as a template (dashboard or API), then install it from the [catalogue](#install-from-the-catalogue).
+
+You can still push local `SKILL.md`/`TRIGGER.md` edits to an **already-installed** fleet:
```bash
-agentsfleet install --from
+agentsfleet fleet update --from
```
-Point `--from` at any local bundle — one you authored (see [Authoring a fleet](/fleets/authoring)) or a template you cloned from git. The directory needs a `SKILL.md`; `TRIGGER.md` is optional (a default API wake is generated when it's absent). For a curated, ready-to-run fleet, install from the [catalogue](#install-from-the-catalogue) instead.
+This overrides the live fleet's instructions from the directory (a `SKILL.md` is required; `TRIGGER.md` is optional). See [Authoring a fleet](/fleets/authoring) for the file references.
## Writing your own
-A template is just a directory with `SKILL.md` and `TRIGGER.md`. See [Authoring a fleet](/fleets/authoring) for the file references; install with:
+A template is just a directory with `SKILL.md` and `TRIGGER.md`. See [Authoring a fleet](/fleets/authoring) for the file references. To iterate on an installed fleet from your working directory:
```bash
-agentsfleet install --from .
+agentsfleet fleet update --from .
```
## Sharing
-Templates are markdown — commit `my-fleet/` to git, clone it on a new machine, `agentsfleet install --from .`. Credentials never live in the template; they live in the workspace vault. The template is safe to share publicly; credentials are not.
+Templates are markdown — commit `my-fleet/` to git, clone it on a new machine, onboard it as a template (dashboard or API), then install it with `agentsfleet install --template `. Once installed, iterate on it with `agentsfleet fleet update --from .`. Credentials never live in the template; they live in the workspace vault. The template is safe to share publicly; credentials are not.
- A hosted template marketplace (community-contributed templates, one-click install) is on the roadmap. The first-party catalogue above is the curated starting set; git remains the distribution mechanism for your own templates.
+ A hosted template marketplace (community-contributed templates, one-click install) is on the roadmap. The platform catalogue above is the curated starting set; git remains the distribution mechanism for your own templates.
diff --git a/fleets/tools.mdx b/fleets/tools.mdx
index ac0f29d..ad721f2 100644
--- a/fleets/tools.mdx
+++ b/fleets/tools.mdx
@@ -138,11 +138,11 @@ Drop any one and the call fails: missing tool → fleet can't even try; missing
## Validation
-`agentsfleet install --from ` accepts the `tools:` list as-is — there's no catalogue check at install time. Unknown names surface later, when the runner builds tools for a run: each unrecognized name gets logged as `UZ-TOOL-005` (Unknown tool) and silently skipped. The fleet runs with the remaining tools.
+Onboarding a template (and `agentsfleet fleet update --from`) accepts the `tools:` list as-is — there's no catalogue check when the `SKILL.md` is parsed. Unknown names surface later, when the runner builds tools for a run: each unrecognized name gets logged as `UZ-TOOL-005` (Unknown tool) and silently skipped. The fleet runs with the remaining tools.
The practical consequences:
-- **Typos pass install.** Declaring `http_requesst:` (typo) won't fail `agentsfleet install --from`. Catch this by tailing `agentsfleet logs ` after the first event and looking for the skip warning, or by spotting tool calls in the activity stream that don't match what your `SKILL.md` prose expects.
+- **Typos pass parsing.** Declaring `http_requesst:` (typo) won't fail onboarding or `agentsfleet fleet update --from`. Catch this by tailing `agentsfleet logs ` after the first event and looking for the skip warning, or by spotting tool calls in the activity stream that don't match what your `SKILL.md` prose expects.
- **Disabled tools are also silently dropped.** Setting `enabled: false` on a tool entry skips it without a warning.
- **`UZ-TOOL-005` is a log warning, not a wire response.** It won't appear as an HTTP error to a webhook caller; it's a server-side observability signal.
diff --git a/fleets/troubleshooting.mdx b/fleets/troubleshooting.mdx
index 7143039..915ef7b 100644
--- a/fleets/troubleshooting.mdx
+++ b/fleets/troubleshooting.mdx
@@ -9,32 +9,32 @@ A fleet that's misbehaving falls into one of six failure shapes. Find the sympto
| Symptom | Most likely cause | Start here |
|---|---|---|
-| `agentsfleet install --from` exits non-zero | Frontmatter validation failed | [§1 Install rejected](#1-install-rejected) |
+| Onboarding or `agentsfleet fleet update --from` exits non-zero | Frontmatter validation failed | [§1 Frontmatter rejected](#1-frontmatter-rejected) |
| Upstream says it sent the webhook, fleet didn't wake | Signature mismatch or wrong URL | [§2 Webhook delivered but fleet silent](#2-webhook-delivered-but-fleet-silent) |
| Fleet woke, run failed before producing output | Credential, network, or tool error | [§3 Run opens then fails](#3-run-opens-then-fails) |
| Run produces a result but it's wrong | `SKILL.md` prose or memory issue | [§4 Run completes but output is wrong](#4-run-completes-but-output-is-wrong) |
| Run terminates with `budget_breach` | `daily_dollars` / `monthly_dollars` ceiling hit | [§5 Budget breach](#5-budget-breach) |
| `agentsfleet` itself is broken (auth, network) | Local config or platform reachability | [§6 agentsfleet can't reach the platform](#6-agentsfleet-cant-reach-the-platform) |
-## 1. Install rejected
+## 1. Frontmatter rejected
-`agentsfleet install --from ` exited with code `3` (the API rejected the bundle). The platform parsed your `SKILL.md` + `TRIGGER.md` and rejected them.
+Frontmatter is parsed at two points: when you **onboard** a template (dashboard or API), and when you push edits to a running fleet with `agentsfleet fleet update --from `. Either can fail with code `3` (the API rejected the bundle) — the platform parsed your `SKILL.md` + `TRIGGER.md` and rejected them.
```bash
-agentsfleet install --from ./my-fleet --json 2>&1 | tail -5
+agentsfleet fleet update 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 --from ./my-fleet --json 2>&1 | tail -5
```
-The `--json` output carries the wire error code:
+The `--json` output (and the onboarding API response) carries the wire error code:
| Wire code | Cause | Fix |
|---|---|---|
| `UZ-AGT-008` | `TRIGGER.md` config_json fails schema validation | Re-read [Authoring](/fleets/authoring) §`x-agentsfleet:` subkeys. Common: a runtime key (`tools`, `credentials`, `network`) at the top level instead of nested under `x-agentsfleet:`. |
| `UZ-AGT-011` | `SKILL.md` and `TRIGGER.md` disagree on top-level `name:` | Make both files' `name:` value identical. |
-| `UZ-VAULT-001` | Credential `data` body is empty / not a JSON object | The error is from a prior `credential add` call, not from `install` itself. Re-run `agentsfleet credential add --data=@-` with a non-empty JSON object. |
+| `UZ-VAULT-001` | Credential `data` body is empty / not a JSON object | The error is from a prior `credential add` call, not from onboarding itself. Re-run `agentsfleet credential add --data=@-` with a non-empty JSON object. |
For other codes, check [Error codes](/api-reference/error-codes) and grep for the `UZ-` prefix.
-**Local validation tip:** the parser the platform uses is the same one `agentsfleet install --from` runs — there's no separate lint command. To catch schema errors before committing, run `agentsfleet install --from --json` and read the structured error output. Note the call still uploads on success; there is no `--validate-only` flag.
+**Local validation tip:** the parser the platform uses on onboard is the same one `agentsfleet fleet update --from` runs against a live fleet — there's no separate lint command. To catch schema errors on an installed fleet before relying on it, run `agentsfleet fleet update --from --json` and read the structured error output. There is no `--validate-only` flag.
## 2. Webhook delivered but fleet silent
@@ -138,7 +138,7 @@ The model's tool-call trail tells you what it actually did. Compare against what
agentsfleet steer ""
```
-Edit `SKILL.md`, `agentsfleet install --from .`, re-steer. The next event uses the new prose — no redeploy.
+Edit `SKILL.md`, `agentsfleet fleet update --from .`, re-steer. The next event uses the new prose — no redeploy.
## 5. Budget breach
@@ -150,7 +150,7 @@ agentsfleet status --json | jq '.[] | select(.fleet_id == "") | {state, budg
Two layers of cap exist independently:
-1. **Per-fleet** (`TRIGGER.md` `budget.daily_dollars` / `monthly_dollars`) — terminates this fleet's runs until the rolling window resets. Raise the value, re-install.
+1. **Per-fleet** (`TRIGGER.md` `budget.daily_dollars` / `monthly_dollars`) — terminates this fleet's runs until the rolling window resets. Raise the value in `TRIGGER.md`, then push it with `agentsfleet fleet update --from .`.
2. **Tenant wallet** — every workspace's runs debit the same pool. When it hits zero, all runs across all workspaces stop. Top up at `app.agentsfleet.net/billing`. See [Billing → Budgets](/billing/budgets).
If you're hitting the per-fleet cap repeatedly on legitimate traffic, the fleet's per-run cost is higher than you sized for. Audit the activity stream for unusually long runs (high `tokens` or `wall_ms` fields), and consider tightening `SKILL.md` or splitting the work across multiple smaller fleets.
diff --git a/fleets/webhooks.mdx b/fleets/webhooks.mdx
index 9a601e5..2003985 100644
--- a/fleets/webhooks.mdx
+++ b/fleets/webhooks.mdx
@@ -9,7 +9,7 @@ Every webhook trigger declared in `TRIGGER.md` gets a unique, stable URL keyed b
https://api.agentsfleet.net/v1/webhooks/{fleet_id}/{source}
```
-External systems POST to this URL. The platform verifies the signature and delivers the event to the fleet. No tunneling, no ngrok, no custom servers on your side. `agentsfleet install --from` prints the full set of URLs (one per declared webhook trigger) at install time.
+External systems POST to this URL. The platform verifies the signature and delivers the event to the fleet. No tunneling, no ngrok, no custom servers on your side. `agentsfleet install --template` prints the full set of URLs (one per declared webhook trigger) at install time.
**`agentsfleet install` prints the webhook URL(s) to register.** Add each printed URL to its upstream provider — on GitHub, **Settings → Webhooks** (or `gh api -X POST repos///hooks …`). The reference below covers the signature config the platform expects.
diff --git a/quickstart.mdx b/quickstart.mdx
index 096a54e..880bd0f 100644
--- a/quickstart.mdx
+++ b/quickstart.mdx
@@ -146,7 +146,7 @@ No redeploys, no DAG editor — the next event runs the new prose.
`agentsfleet steer "review the latest PR"` — same reasoning loop, manual trigger. Useful before a webhook is firing.
- Write your own `SKILL.md` + `TRIGGER.md` and install it with `agentsfleet install --from .`.
+ Write your own `SKILL.md` + `TRIGGER.md`, onboard it as a template (dashboard or API), then `agentsfleet install --template `. Iterate on a running fleet with `agentsfleet fleet update --from .`.
Why deep runs keep reasoning past the model's context cap. Defaults work for 95% of cases.
diff --git a/workspaces/managing.mdx b/workspaces/managing.mdx
index 4f23970..e9acce7 100644
--- a/workspaces/managing.mdx
+++ b/workspaces/managing.mdx
@@ -42,7 +42,7 @@ The leading `*` marks the active workspace (the one set by `agentsfleet workspac
agentsfleet workspace use
```
-Makes the workspace active for subsequent CLI commands — `agentsfleet install --from`, `agentsfleet list`, `agentsfleet status`, `agentsfleet logs`, `agentsfleet events`, `agentsfleet steer`, and anything else that accepts a `--workspace-id` flag defaults to this value when the flag is omitted.
+Makes the workspace active for subsequent CLI commands — `agentsfleet install --template`, `agentsfleet list`, `agentsfleet status`, `agentsfleet logs`, `agentsfleet events`, `agentsfleet steer`, and anything else that accepts a `--workspace-id` flag defaults to this value when the flag is omitted.
The choice is persisted to `~/.config/agentsfleet/workspaces.json` (`current_workspace_id` field), so it survives across shells and sessions.