From 924732371a757faae8fac64195e8c38a195e1caa Mon Sep 17 00:00:00 2001 From: Kishore Kumar Date: Mon, 22 Jun 2026 09:04:27 +0530 Subject: [PATCH 1/4] docs: fix CLI/API/memory/tooling drift + pivot install flow to CLI-first templates Cross-referenced every guide against the agentsfleet CLI, the OpenAPI spec, the Zig runtime, and the M94 fleet-bundle template catalogue (Pull Request #438), then corrected the drift the review surfaced. Install flow (skills -> CLI-first templates): - quickstart: full rewrite. Drop the markdown-skill host onboarding and the fabricated ~/.config/agentsfleet/samples/ path; lead with the CLI install one-liner, then `agentsfleet install --template github-pr-reviewer` and manual webhook registration (native install prints the URL, it does not auto-register via gh). - index / install / cli/install / templates / running: same skills->template pivot; remove host-agent, `npx skills add`, `/agentsfleet-install-platform-ops`. Correctness fixes (docs vs source): - exit codes: real 1/2/3/4/5 map (auth/network/server/validation/config), was 0/1/2. - error codes: drop fabricated UZ-MEM-001, UZ-TOOL-004, UZ-AGT-001/002 and the retired UZ-WH-003; use the real UZ-AGT-008/011, UZ-MEM-002, UZ-EXEC-003. - authoring: replace invented validator strings (RuntimeKeysOutsideBlock, name_mismatch, ERR_AGENTSFLEET_INVALID_CONFIG, the "install rejected" block) with real wire codes; network.allow is optional; drop the unenforced <=200-char rule. - memory: remove the non-existent `workspace` category and `tags` field; memory_recall is a `query` search, not a key lookup; storage is a separate Postgres schema+role (not a separate database); entries read back as JSON. - tools: 32 built-in tools (was "23"); `shell` + the full file toolset are real and declarable (deny-by-default), correcting the "no free shell" claim. - webhooks: success body is {status:"accepted",event_id}; a paused/killed fleet returns 200 {"ignored":"fleet_paused"}, not 410. - api: soften the unverifiable JSON Web Token (JWT) "~15 min" lifetime; use a real error example (UZ-AGT-009); note the 409 current_state field. Verified: `mintlify validate` and `mintlify broken-links` both pass. Related follow-ups handed off (separate repos, not in this diff): ui/agentsfleet.dev/dist/install.sh still installs the skill and must drop it to match these docs; the website (ui/packages/website) still markets the skills flow. Co-Authored-By: Claude Opus 4.8 (1M context) --- api-reference/introduction.mdx | 12 +-- cli/agentsfleet.mdx | 10 +- cli/install.mdx | 16 ++-- fleets/authoring.mdx | 22 ++--- fleets/credentials.mdx | 11 ++- fleets/install.mdx | 28 +++--- fleets/overview.mdx | 6 +- fleets/running.mdx | 20 ++-- fleets/templates.mdx | 14 +-- fleets/tools.mdx | 25 +++-- fleets/troubleshooting.mdx | 14 +-- fleets/webhooks.mdx | 26 +++--- index.mdx | 6 +- memory.mdx | 44 +++++---- quickstart.mdx | 161 +++++++++++++++------------------ 15 files changed, 207 insertions(+), 208 deletions(-) diff --git a/api-reference/introduction.mdx b/api-reference/introduction.mdx index befe0e6..2fae2f5 100644 --- a/api-reference/introduction.mdx +++ b/api-reference/introduction.mdx @@ -21,7 +21,7 @@ curl https://api.agentsfleet.net/v1/workspaces/0198a7b0-3c2d-7f14-9a08-1b6e4d2f8 Two kinds of bearer token are accepted: - **Tenant API key (`agt_t…`)** — long-lived, for programmatic and service-to-service callers (CI, cron, integrations, scripts). Create one in the dashboard under **Settings → API keys**; the raw value is shown once. This is the right credential for calling the API directly. -- **User JWT** — short-lived (~15 min), for an interactive human. Mint one with `agentsfleet login`, a browser device flow with terminal-side verification. It can't be obtained by a bare API client — the flow needs the dashboard's browser leg — so for unattended access use a tenant API key. +- **User JWT** — short-lived, for an interactive human. Mint one with `agentsfleet login`, a browser device flow with terminal-side verification. It can't be obtained by a bare API client — the flow needs the dashboard's browser leg — so for unattended access use a tenant API key. ## Errors @@ -29,15 +29,15 @@ All errors use RFC 7807 problem detail (`Content-Type: application/problem+json` ```json { - "docs_uri": "https://docs.agentsfleet.net/api-reference/error-codes#UZ-WORKSPACE-001", - "title": "Workspace not found", - "detail": "No workspace with the given ID exists.", - "error_code": "UZ-WORKSPACE-001", + "docs_uri": "https://docs.agentsfleet.net/api-reference/error-codes#UZ-AGT-009", + "title": "Fleet not found", + "detail": "No fleet with the given ID exists in this workspace.", + "error_code": "UZ-AGT-009", "request_id": "0198a7b6-1f2a-7d53-8c94-2b7e5a1f9d40" } ``` -Error codes follow the `UZ--NNN` scheme in the `error_code` field. Every response includes a `request_id` for tracing. See [Error codes](/api-reference/error-codes) for the full registry. +Error codes follow the `UZ--NNN` scheme in the `error_code` field. Every response includes a `request_id` for tracing. On `409 Conflict` responses the body may carry an extra `current_state` field naming the resource's blocking state (e.g. `paused`). See [Error codes](/api-reference/error-codes) for the full registry. ## Conventions diff --git a/cli/agentsfleet.mdx b/cli/agentsfleet.mdx index b44c9e2..246f215 100644 --- a/cli/agentsfleet.mdx +++ b/cli/agentsfleet.mdx @@ -67,7 +67,7 @@ Removes local credentials (`~/.config/agentsfleet/credentials.json`) and aborts agentsfleet logout ``` -Does **NOT** revoke your active session token — JWTs are short-lived (~15 min) and expire on their own. Does **NOT** touch the `AGENTSFLEET_API_KEY` environment variable — if it's set, subsequent commands continue to authenticate with that key (it overrides a stored login) until you unset it. +Does **NOT** revoke your active session token — JWTs are short-lived and expire on their own. Does **NOT** touch the `AGENTSFLEET_API_KEY` environment variable — if it's set, subsequent commands continue to authenticate with that key (it overrides a stored login) until you unset it. ### `agentsfleet auth status` @@ -91,13 +91,13 @@ The probe result is one of `valid` (200 from the billing endpoint), `unauthorize ### `agentsfleet install --from ` -Reads `SKILL.md` and `TRIGGER.md` from ``, validates them, and uploads to the active workspace. The two markdown files are the configuration; the `agentsfleet-install-platform-ops` host-agent skill is what generates them under `.agentsfleet//` in your repo. The `--from` flag is required — there are no bare-name template aliases. +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 ~/.config/agentsfleet/samples/platform-ops +agentsfleet install --from ./my-fleet ``` -The `samples/` directory ships with `agentsfleet` and contains the flagship `platform-ops` sample. The host-agent install skill (`/agentsfleet-install-platform-ops`) drives this command under the hood. See [Quickstart](/quickstart) and [Templates](/fleets/templates). +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 ` @@ -132,7 +132,7 @@ Prints a table of template id, name, and required credentials. Pass `--json` for Re-parse `SKILL.md` and `TRIGGER.md` from a local bundle and `PATCH` them onto an existing fleet — the in-place counterpart to `install`. Use it to roll a configuration change onto an already-registered fleet without re-creating it. ```bash -agentsfleet fleet update 01900000-0000-7000-8000-000000000001 --from ~/.config/agentsfleet/samples/platform-ops +agentsfleet fleet update 01900000-0000-7000-8000-000000000001 --from ./my-fleet ``` | Flag | Default | Purpose | diff --git a/cli/install.mdx b/cli/install.mdx index 5b2aaee..927f103 100644 --- a/cli/install.mdx +++ b/cli/install.mdx @@ -25,21 +25,23 @@ description: "Install the agentsfleet CLI." -## Fleet Skills +## Install a fleet -The `agentsfleet-install-platform-ops` skill is the guided install UX driven from a host agent (Claude Code, Amp, Codex CLI, OpenCode). Add the skills with one command: +With the CLI installed, sign in and install a fleet from the template catalogue: ```bash -npx skills add agentsfleet/skills +agentsfleet login # browser approval + verification code +agentsfleet templates # browse the catalogue +agentsfleet install --template github-pr-reviewer ``` -This symlinks the `/agentsfleet-*` slash commands from the public [`agentsfleet/skills`](https://github.com/agentsfleet/skills) repo into every supported host's skill directory it detects on your machine — invoke `/agentsfleet-install-platform-ops` in your agent and you’re set. Pass `--host=` to target a single host instead of every detected one. +Or install a local bundle you authored with `agentsfleet install --from ` (see [Authoring a fleet](/fleets/authoring)). - **No global install?** `curl -fsSL https://agentsfleet.dev | bash` installs `agentsfleet` and the skill together in one command (requires Node — it runs npm under the hood). Run `curl -fsSL https://agentsfleet.dev` without `| bash` to read it first. + **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. -The skill drives `agentsfleet install --from`, `agentsfleet credential`, `agentsfleet steer`, `agentsfleet logs`, and the doctor preflight under the hood. See [Quickstart](/quickstart) for the end-to-end flow. +See [Quickstart](/quickstart) for the end-to-end flow from a cold machine. ## Verify installation @@ -63,4 +65,4 @@ agentsfleet doctor | `workspace_selected` | The local config has a `current_workspace_id`. Auto-populated by `agentsfleet login` from your signup-provisioned default workspace; can also be set or replaced by `agentsfleet workspace add` / `workspace use`. | | `workspace_binding_valid` | The resolved auth token can read the selected workspace's fleets — i.e. it is bound to the right tenant. Reports a failed check (rather than aborting) when no token is present. | -Pass `--json` for the structured `{ ok, api_url, checks: [...] }` envelope. Run it before any install — host-agent skills depend on this preflight. For the tenant's inference posture and free-trial window, use [`agentsfleet tenant provider show`](/cli/agentsfleet#tenant-provider). +Pass `--json` for the structured `{ ok, api_url, checks: [...] }` envelope. Run it before installing a fleet to confirm connectivity and workspace selection. For the tenant's inference posture and free-trial window, use [`agentsfleet tenant provider show`](/cli/agentsfleet#tenant-provider). diff --git a/fleets/authoring.mdx b/fleets/authoring.mdx index 6a4e187..b37271d 100644 --- a/fleets/authoring.mdx +++ b/fleets/authoring.mdx @@ -36,7 +36,7 @@ model: claude-sonnet-4-6 # optional, hint | Field | Required | Purpose | |---|---|---| | `name` | yes | Identity. Must equal `TRIGGER.md` `name:` (install rejects mismatch). | -| `description` | yes | One-line summary, ≤200 chars. | +| `description` | yes | One-line summary. | | `version` | yes | Semver string. | | `when_to_use`, `tags`, `author`, `model` | no | Pass-through metadata. | @@ -130,14 +130,14 @@ 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 (`ERR_AGENTSFLEET_INVALID_CONFIG: use "triggers:" (array)`). 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 install 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. | | `triggers[].signature.secret_ref` | optional | Vault key whose value verifies webhook signatures (first-class providers). | | `tools` | yes | Non-empty list of tool names from the [Tools catalogue](/fleets/tools). | | `credentials` | optional | Vault key names the fleet reads at event time. | -| `network.allow` | yes | Outbound hostname allowlist enforced by the sandbox. | +| `network.allow` | optional | Outbound hostname allowlist enforced by the sandbox. Omit it (or the whole `network:` block) for an empty allowlist — `http_request` then has no permitted hosts. | | `budget.daily_dollars` | yes | Rolling 24-hour dollar ceiling. | | `budget.monthly_dollars` | optional | Calendar-month dollar ceiling. | @@ -157,7 +157,7 @@ A fleet can declare up to eight triggers and wake on any of them — e.g. one we The `tools:` list is the explicit allowlist of tools the fleet may invoke. A compromised or jailbroken fleet cannot reach outside this list. -23 tools are user-callable today, grouped by category — network (`http_request`, `web_search`, `web_fetch`), memory (`memory_store`/`recall`/`list`/`forget`), cron (`cron_add`/`list`/`remove`/`update`/`run`/`runs`), fleet orchestration (`delegate`, `spawn`, `schedule`), browser, git, file edits, and stateless utilities. **See [Tools catalogue](/fleets/tools) for every tool with its purpose and use cases.** +The runner exposes 32 built-in tools — network (`http_request`, `web_search`, `web_fetch`, `pushover`), memory (`memory_store`/`recall`/`list`/`forget`), cron (`cron_add`/`list`/`remove`/`update`/`run`/`runs`), fleet orchestration (`delegate`, `spawn`, `schedule`), browser, git, `shell` and the file tools, and stateless utilities. The list is deny-by-default — declare only what the fleet needs. **See [Tools catalogue](/fleets/tools) for every tool with its purpose and use cases.** ### Credentials @@ -180,23 +180,21 @@ A breach terminates the in-flight event cleanly and records a `budget_breach` en | Symptom | Cause | Fix | |---|---|---| -| `RuntimeKeysOutsideBlock` at install | `tools:`, `credentials:`, etc. at the top of TRIGGER.md | Indent them under `x-agentsfleet:`. | -| `UnknownRuntimeKey` at install | Typo in a runtime subkey (e.g. `crendentials:` instead of `credentials:`) | Fix the spelling, or remove the key. Validation under `x-agentsfleet:` is strict. | -| `name_mismatch` at install | SKILL.md and TRIGGER.md disagree on `name:` | One identity per bundle. Make both top-level `name:` values equal. | -| `MissingRequiredField` for SKILL.md | `name`, `description`, or `version` missing from SKILL.md frontmatter | All three are required at the top level. | +| `UZ-AGT-008` (invalid fleet config) | A runtime key (`tools:`, `credentials:`, `network:`, …) at the top of TRIGGER.md instead of nested; a typo'd subkey under `x-agentsfleet:`; a singular `trigger:`; or a malformed `name:` | Nest runtime keys under `x-agentsfleet:`, fix the spelling, use the `triggers:` array, and keep `name:` kebab-case (`^[a-z0-9-]+$`, 1–64 chars). Validation under `x-agentsfleet:` is strict — unknown subkeys are rejected. | +| `UZ-AGT-011` (name mismatch) | SKILL.md and TRIGGER.md disagree on top-level `name:` | One identity per bundle. Make both `name:` values equal. | +| Missing `name` / `description` / `version` in SKILL.md | A required frontmatter field is absent | All three are required at the top level of `SKILL.md`. | ## Validation -`agentsfleet install --from ` reads both files and posts them to the server, which runs the same parser the runtime uses. Errors are returned with the field at fault. +`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 ``` ``` -✗ install rejected: name_mismatch - SKILL.md name: platform-ops-fleet - TRIGGER.md name: platform-ops-zombe ← typo +UZ-AGT-011 SKILL.md and TRIGGER.md disagree on `name:` + Suggestion: make the top-level name: identical in both files ``` ## Next diff --git a/fleets/credentials.mdx b/fleets/credentials.mdx index e154b22..74c0cd2 100644 --- a/fleets/credentials.mdx +++ b/fleets/credentials.mdx @@ -41,13 +41,20 @@ JSON The command POSTs to `/v1/workspaces/{workspace_id}/credentials` with the JSON body. Values are encrypted at rest; only the tool bridge can decrypt them when servicing an outbound call. + + The vault stores any JSON object and does **not** validate field names. Shapes like `github` → `{api_token, webhook_secret}` or `slack` → `{bot_token}` are conventions your `SKILL.md` and `http_request` calls rely on — not a server-enforced schema. Keep the field names consistent with what your fleet expects. + + The default behaviour is **skip-if-exists** — passing the same name twice is a no-op. Use `--force` to overwrite an existing credential (rotation). Exit codes: - `0` — stored (or skip-if-exists). -- `1` — no workspace selected, or API error. -- `2` — missing ``, missing `--data`, or invalid JSON. +- `1` — not authenticated (re-run `agentsfleet login`). +- `2` — network error reaching the API. +- `3` — the API rejected the credential (e.g. `UZ-VAULT-001` empty / not an object, `UZ-VAULT-002` too large). +- `4` — missing `` or `--data`. +- `5` — local config error, or `--data` input that isn't readable JSON. ## Listing credentials diff --git a/fleets/install.mdx b/fleets/install.mdx index 676351f..e05082a 100644 --- a/fleets/install.mdx +++ b/fleets/install.mdx @@ -6,7 +6,7 @@ description: "What `agentsfleet install --from ` 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. ```bash -agentsfleet install --from ~/.config/agentsfleet/samples/platform-ops +agentsfleet install --from ./platform-ops ``` ``` @@ -16,25 +16,20 @@ agentsfleet install --from ~/.config/agentsfleet/samples/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`. The host-agent install skill consumes this map and registers each URL on the upstream provider via the user's own `gh` (or equivalent) CLI — no paste-into-GitHub step. See [Quickstart](/quickstart) for the guided flow, or [Webhooks](/fleets/webhooks) if you maintain the upstream hook by hand. +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. 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. -## Two ways to invoke +## Install from the catalogue instead -Most users don't run `agentsfleet install --from` directly. They drive the install from a host agent (Claude Code, Amp, Codex CLI, OpenCode) via the `/agentsfleet-install-platform-ops` slash command. Add the skills with `npx skills add agentsfleet/skills`, which symlinks `/agentsfleet-*` into every supported host's skill directory it detects. Then invoke the slash command in your host agent: +To start from a curated, ready-to-run fleet rather than a local directory, install a [template](/fleets/templates) by id: +```bash +agentsfleet templates # browse the catalogue +agentsfleet install --template github-pr-reviewer ``` -/agentsfleet-install-platform-ops -``` - - - **No global install?** `curl -fsSL https://agentsfleet.dev | bash` installs `agentsfleet` and the skill together in one command (requires Node — it runs npm under the hood). Run `curl -fsSL https://agentsfleet.dev` without `| bash` to read it first. - - -The slash command asks three gating questions (Slack channel, production branch glob, optional cron schedule), registers the webhook via your existing `gh` CLI, and prints a per-trigger registration summary at the end. See [Quickstart](/quickstart) for the full walkthrough. -Power users and scripted setups call `agentsfleet install --from ` directly — the same flow as the slash command, minus the gating questions and the auto-registration. +`--from` and `--template` are mutually exclusive — exactly one source per install. See [Quickstart](/quickstart) for the end-to-end walkthrough from a cold machine. For the self-managed provider posture, see [`agentsfleet tenant provider`](/cli/agentsfleet#tenant-provider). @@ -43,8 +38,11 @@ For the self-managed provider posture, see [`agentsfleet tenant provider`](/cli/ | Code | Meaning | |---|---| | `0` | Installed (or updated). | -| `1` | No workspace selected, or API error. | -| `2` | Missing `--from`, invalid path, or schema rejection. | +| `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`). | ## See also diff --git a/fleets/overview.mdx b/fleets/overview.mdx index 325507f..24b5db3 100644 --- a/fleets/overview.mdx +++ b/fleets/overview.mdx @@ -5,7 +5,7 @@ description: "What a fleet is, the lifecycle it moves through, and how it relate ## Overview -A **fleet** is a preconfigured, always-on process in your workspace. You describe it once — its trigger, the skills it can use, the credentials it needs, the budget it is allowed to consume — and the platform keeps it alive, receiving events and invoking the fleet, until you kill it. +A **fleet** is a preconfigured, always-on process in your workspace. You describe it once — its trigger, the tools it can use, the credentials it needs, the budget it is allowed to consume — and the platform keeps it alive, receiving events and invoking the fleet, until you kill it. Everything in this section of the docs is about working with fleets: how to install one from a template, how to start and stop it, how to attach credentials, how webhooks reach it, and how to author the `SKILL.md` and `TRIGGER.md` files that define its behavior. @@ -43,7 +43,7 @@ agentsfleet steer 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 "morning health check" Every fleet belongs to exactly one **workspace**. The workspace is the boundary for: -- **Credentials** — the vault that fleets read from when they invoke skills. See [Credentials](/fleets/credentials). +- **Credentials** — the vault that fleets read from when they invoke tools. See [Credentials](/fleets/credentials). - **Access control** — teammates invited to a workspace can see, start, and kill its fleets; they cannot see fleets in other workspaces. - **Webhook namespace** — every fleet in a workspace gets one unique URL per declared trigger under `https://api.agentsfleet.net/v1/webhooks/{fleet_id}/{source}` (one entry per `triggers[].source` in `TRIGGER.md`). @@ -55,7 +55,7 @@ Billing is **not** workspace-scoped — every workspace draws on the same tenant - Scaffold a fleet from a bundled template. + Install a fleet from the catalogue or a local bundle. The `install`, `status`, `events`, `steer`, and `kill` commands. diff --git a/fleets/running.mdx b/fleets/running.mdx index 222e6de..dab8b30 100644 --- a/fleets/running.mdx +++ b/fleets/running.mdx @@ -8,7 +8,7 @@ description: "The lifecycle commands — install, status, logs, events, steer, s A small set of verbs cover the live lifecycle: `install --from ` 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`. ```bash -agentsfleet install --from ~/.config/agentsfleet/samples/platform-ops +agentsfleet install --from ./platform-ops 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" @@ -22,7 +22,7 @@ agentsfleet delete 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 # h Reads `SKILL.md` and `TRIGGER.md` from the directory you point at, validates them, and uploads to the active workspace. **Install is the deploy** — there is no separate `up` step. ```bash -agentsfleet install --from ~/.config/agentsfleet/samples/platform-ops +agentsfleet install --from ./platform-ops ``` ``` @@ -32,15 +32,18 @@ agentsfleet install --from ~/.config/agentsfleet/samples/platform-ops github: https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github ``` -One URL is printed per declared `webhook` trigger, keyed by `triggers[].source`. The host-agent install skill registers each URL on the upstream provider via your existing `gh` (or equivalent) CLI — there is no separate paste step. To rotate the workspace-level signing secret, see [Quickstart → Verify the registered webhook](/quickstart#verify-the-registered-webhook). +One URL is printed per declared `webhook` trigger, keyed by `triggers[].source`. Register each on its upstream provider — on GitHub, **Settings → Webhooks** (or `gh api -X POST repos///hooks …`). See [Webhooks](/fleets/webhooks) for the signature config and [Credentials](/fleets/credentials) to rotate the signing secret. Re-running `agentsfleet install --from ` 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. Exit codes: - `0` — installed (or updated). -- `1` — no workspace selected, or API error. -- `2` — missing `--from`, invalid path, or schema rejection. +- `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`). ## `agentsfleet status` @@ -134,7 +137,10 @@ State is checkpointed at every transition — nothing on the activity stream is | Code | Meaning | |------|---------| | `0` | Success. | -| `1` | Workspace not selected, network error, or server rejected the call. | -| `2` | Invalid or missing argument (missing `--from`, missing ``, etc.). | +| `1` | Not authenticated. | +| `2` | Network error reaching the API. | +| `3` | The API rejected the call (e.g. invalid state transition). | +| `4` | Missing or invalid argument (e.g. no ``). | +| `5` | Local config error. | See the [CLI reference](/cli/agentsfleet) for the full command matrix. diff --git a/fleets/templates.mdx b/fleets/templates.mdx index c469390..aee16a8 100644 --- a/fleets/templates.mdx +++ b/fleets/templates.mdx @@ -1,6 +1,6 @@ --- title: "Templates" -description: "The first-party template catalogue and the local sample directory — pre-built fleets you install with one command." +description: "The first-party template catalogue and local bundles — pre-built fleets you install with one command." --- A **template** is a pre-built fleet you install in one command. There are two sources: @@ -56,17 +56,7 @@ Any directory with a valid `SKILL.md` and `TRIGGER.md` installs with `--from`: agentsfleet install --from ``` -The `agentsfleet` package ships sample directories under `~/.config/agentsfleet/samples/`. - -### `platform-ops` - -The flagship v2 sample. Wakes on a GitHub Actions deploy failure, gathers evidence from your hosting provider and the failed workflow, and posts an evidenced diagnosis to Slack. Read-only against your infrastructure; the only write path is the channel post. - -- **Tools:** `http_request`, `memory_recall`, `memory_store`, `cron_add`, `cron_list`, `cron_remove`. -- **Credentials:** `github` (with `webhook_secret` for signature verification), `slack` (bot token). -- **Trigger:** `webhook` from GitHub Actions (`workflow_run.conclusion=failure`). - -For the full install walkthrough — host agent, gating questions, webhook wiring — see [Quickstart](/quickstart). Don't duplicate the steps here. +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. ## Writing your own diff --git a/fleets/tools.mdx b/fleets/tools.mdx index 57bafa5..df4a895 100644 --- a/fleets/tools.mdx +++ b/fleets/tools.mdx @@ -14,7 +14,7 @@ x-agentsfleet: - cron_add ``` -23 tools are user-callable today. They group into nine categories below. For the file format, validation rules, and frontmatter, see [Authoring a fleet](/fleets/authoring). +The runner exposes 32 built-in tools, grouped into the categories below. The `tools:` list in `TRIGGER.md` is an explicit allowlist — declare only what the fleet needs; anything you omit is unreachable. For the file format, validation rules, and frontmatter, see [Authoring a fleet](/fleets/authoring). ## Network @@ -32,12 +32,12 @@ How a fleet talks to the outside world. Each network tool has a different relati ## Memory -Cross-run durable state. See [Memory](/memory) for the four-category model and key conventions. +Cross-run durable state. See [Memory](/memory) for the category model and key conventions. | Tool | What it does | Reach for when | |---|---|---| -| `memory_store` | Upsert a distilled fact (key + category + body + tags). | End of every run where the fleet learned something worth keeping. | -| `memory_recall` | Exact-key lookup; returns the entry or empty. | Start of every run, before reasoning. | +| `memory_store` | Upsert a distilled fact under a stable key (`key` + `content`, optional `category`). | End of every run where the fleet learned something worth keeping. | +| `memory_recall` | Free-text search over recent memory (recency-ranked); returns matching entries. | Start of every run, before reasoning. | | `memory_list` | Filter entries by category, tags, recency. | When the fleet doesn't know the exact key (e.g. "show me all open tickets"). | | `memory_forget` | Delete an entry. | Correcting stale facts; fed by `agentsfleet steer` corrections. | @@ -72,6 +72,7 @@ Three independently-declarable tools that look related but overlap awkwardly. ** |---|---|---| | `browser` | Multi-action verb. The schema advertises `open`, `screenshot`, `click`, `type`, `scroll`, `read` — but only `open` and `read` are functional. **`screenshot` redirects** to the standalone tool (`return ToolResult.fail("Use the screenshot tool instead")`). **`click`/`type`/`scroll` always fail** ("CDP not available"). `read` is a curl-based HTML fetcher capped at 8 KB. | `open` shells out to `open`/`xdg-open` on the runner host — no display on a headless cloud worker, so this no-ops or errors. `read` works but is inferior to `web_fetch`. | | `screenshot` | Independent tool. Captures the runner's screen via platform-native commands. Returns an `[IMAGE:path]` marker. | The hosted v2 runner is headless. There's no display to capture, and the tool reflects that — declare only if you're running a self-hosted runner with a display attached. | +| `browser_open` | Open a URL on the runner host (`open`/`xdg-open`). | Same headless limitation as `browser`'s `open` action — no-ops or errors on the cloud runner; for self-hosted runners with a display only. | **Declaring `browser` does NOT unlock `screenshot` capabilities.** They're independent tools; the sub-action name overlap is incidental. If you want a screen capture, declare `screenshot`. Declaring both `browser` and `screenshot` is fine — they don't conflict. @@ -85,13 +86,20 @@ Repository operations on the runner's workspace directory. |---|---| | `git` | Structured wrapper for `status`, `diff`, `log`, `branch`, `commit`, `add`, `checkout`, `stash`. Constrained to the runner's workspace. | -## File +## Shell and file -The fleet does not get a free shell or filesystem inside the sandbox. The one file tool exposed to fleets enforces hash-anchored edits to prevent silent overwrites. +These operate on the runner's sandbox workspace and are **deny-by-default** — a fleet gets them only if its `TRIGGER.md` `tools:` list names them. Declare the narrowest set you need; `shell` and the write/delete tools are powerful, so add them deliberately. Most operational fleets need none of these — they reach external systems through `http_request`, not the local filesystem. | Tool | What it does | |---|---| -| `file_edit_hashed` | Replace lines in a file using Hashline anchors. Edits are rejected if the on-disk content has drifted from the hash the fleet saw — protects against concurrent-edit races. | +| `shell` | Run a shell command in the sandbox workspace. | +| `file_read` | Read a file from the workspace. | +| `file_write` | Write (create or overwrite) a file. | +| `file_append` | Append to a file. | +| `file_delete` | Delete a file. | +| `file_edit` | Replace lines in a file. | +| `file_edit_hashed` | Replace lines using Hashline anchors — rejected if the on-disk content drifted from the hash the fleet saw, protecting against concurrent-edit races. | +| `file_read_hashed` | Read a file with per-line hashes, so a later `file_edit_hashed` can anchor safely. | ## Stateless utilities @@ -107,6 +115,7 @@ Pure-function helpers — no side effects, no network, no state. | Tool | What it does | |---|---| | `message` | Send a message to a channel. If `channel`/`chat_id` are omitted, posts to the current conversation. Supports attachment markers (`[FILE:...]`, `[DOCUMENT:...]`, `[IMAGE:...]`) on marker-aware channels. | +| `pushover` | Send a push notification to your devices via [Pushover](https://pushover.net) — for paging a human from inside a run. Needs a `pushover` credential. | ## How tools, credentials, and the network allowlist combine @@ -137,7 +146,7 @@ The practical consequences: - **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. -When the fleet tries to invoke a tool not in the fleet's resolved `tools:` set, the underlying fleet runtime returns a "no such tool" error to the fleet in-prompt — visible in the activity-stream entry, not as a wire response. The platform registers `UZ-TOOL-004` (Tool not attached) for this case but the v2 emission path stays inside the activity stream. See [Error codes → Tool](/api-reference/error-codes#tool). +When the fleet tries to invoke a tool not in its resolved `tools:` set, the underlying fleet runtime returns a "no such tool" error to the fleet in-prompt — visible in the activity-stream entry, not as a wire response. There is no dedicated wire code for this case; only `UZ-TOOL-005` (Unknown tool) exists, and it too stays in the activity stream. See [Error codes → Tool](/api-reference/error-codes#tool). ## See also diff --git a/fleets/troubleshooting.mdx b/fleets/troubleshooting.mdx index 7f90c27..7143039 100644 --- a/fleets/troubleshooting.mdx +++ b/fleets/troubleshooting.mdx @@ -18,7 +18,7 @@ A fleet that's misbehaving falls into one of six failure shapes. Find the sympto ## 1. Install rejected -`agentsfleet install --from ` exited with code `2`. The platform parsed your `SKILL.md` + `TRIGGER.md` and rejected them. +`agentsfleet install --from ` exited 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 @@ -54,6 +54,7 @@ Three things to look for in the output: | Zero events in the window | Request never reached the platform (DNS, firewall, wrong URL on the upstream side). | | Events with rejection metadata, not run opens | Signature verification failed. | | Events but `actor: webhook:unknown` | Source label is missing or the `signature` block in `TRIGGER.md` doesn't match the upstream's actual headers. | +| Upstream got `200 {"ignored": "fleet_paused"}` | The fleet is paused, stopped, or killed — so the event is accepted but no run opens. `agentsfleet status` shows the state; `agentsfleet resume ` if it should be running. | ### Wire codes returned to the upstream @@ -63,8 +64,7 @@ If the upstream itself shows a non-2xx response, the body carries one of: |---|---|---| | `UZ-WH-001` | 404 | URL is wrong. The path is `https://api.agentsfleet.net/v1/webhooks/{fleet_id}/{source}` — verify the ID matches `agentsfleet status`. | | `UZ-WH-002` | 400 | Request body is malformed JSON or empty. | -| `UZ-WH-003` | 403 | Fleet is paused or killed. `agentsfleet status` will show the state; re-install with `agentsfleet install --from `. | -| `UZ-WH-010` | 401 | HMAC signature verification failed. The shared secret in your vault doesn't match the one configured at the upstream. Rotate per [Quickstart → Verify the registered webhook](/quickstart#verify-the-registered-webhook). | +| `UZ-WH-010` | 401 | HMAC signature verification failed. The shared secret in your vault doesn't match the one configured at the upstream. Rotate per [Credentials → Rotation](/fleets/credentials#rotation). | | `UZ-WH-011` | 401 | Replay-window violation — request timestamp is older than 5 minutes. Sender clock skew is the usual culprit. | | `UZ-WH-020` | 401 | No webhook credential configured for this fleet's source. The `secret_ref` in `TRIGGER.md` either isn't set or points at a vault key that doesn't exist. Run `agentsfleet credential list` to confirm; add with `agentsfleet credential add --data=@-`. | | `UZ-WH-030` | 413 | Payload exceeds the 1 MiB ingest limit. The upstream is sending too much; filter or trim the event body before forwarding. | @@ -97,12 +97,12 @@ agentsfleet events --since 1h --json | jq 'select(.error)' | Wire code | Cause | Fix | |---|---|---| | `UZ-AGT-003` | A required vault credential is absent | The credential name in `TRIGGER.md` `credentials:` doesn't exist in the workspace vault. `agentsfleet credential list` to confirm; `agentsfleet credential add --data=@-` to add. | -| `UZ-AGT-002` | Fleet timeout | The model didn't return within the per-event ceiling. Often a sign the prompt is too large or the model is overwhelmed. Tighten `SKILL.md` or check `tool_window` in [Context lifecycle](/concepts/context-lifecycle). | +| `UZ-EXEC-003` | Execution timeout | The run exceeded its wall-clock ceiling and was killed. Often a sign the prompt is too large or the model is overwhelmed. Tighten `SKILL.md` or check `tool_window` in [Context lifecycle](/concepts/context-lifecycle). | | `UZ-MEM-003` | Memory backend unavailable | Transient. Re-trigger; if persistent, file an issue. | -| `UZ-MEM-001` | Memory scope denied | The fleet tried to read another fleet's memory. Check the `key` derivation in `SKILL.md` — keys are fleet-scoped. | +| `UZ-MEM-002` | Fleet not found for memory op | The `fleet_id` on the memory call doesn't exist in this workspace. Memory is fleet-scoped; confirm the fleet with `agentsfleet status`. | -**Tool-related failures don't surface as wire codes.** When a `tools:` entry has a typo, the runner logs `UZ-TOOL-005` at warn level and silently skips it. When the fleet tries to invoke a tool that isn't in its resolved set, NullClaw returns a "no such tool" message in the activity stream rather than emitting `UZ-TOOL-004` to a caller. Both `UZ-TOOL-*` codes exist in the registry (see [Error codes → Tool](/api-reference/error-codes#tool)) but in v2 today the diagnostic signal is the activity-stream entry, not a wire response. Audit `agentsfleet logs ` for the actual error text. See [Tools catalogue → Validation](/fleets/tools#validation). +**Tool-related failures don't surface as wire codes.** When a `tools:` entry has a typo, the runner logs `UZ-TOOL-005` (Unknown tool) at warn level and silently skips it. When the fleet tries to invoke a tool that isn't in its resolved set, the runtime returns a "no such tool" message in the activity stream. Either way the diagnostic signal is the activity-stream entry, not a wire response — audit `agentsfleet logs ` for the actual error text. See [Tools catalogue → Validation](/fleets/tools#validation). ### Network allowlist drops @@ -142,7 +142,7 @@ Edit `SKILL.md`, `agentsfleet install --from .`, re-steer. The next event uses t ## 5. Budget breach -Run terminated with `UZ-AGT-001`. The `daily_dollars` or `monthly_dollars` ceiling in `TRIGGER.md` was hit. +The run terminated on a budget breach — the `daily_dollars` or `monthly_dollars` ceiling in `TRIGGER.md` was hit. The activity stream records the terminated run (there's no separate wire code). ```bash agentsfleet status --json | jq '.[] | select(.fleet_id == "") | {state, budget}' diff --git a/fleets/webhooks.mdx b/fleets/webhooks.mdx index 3b8b603..9a601e5 100644 --- a/fleets/webhooks.mdx +++ b/fleets/webhooks.mdx @@ -12,7 +12,7 @@ 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. - **Most users don't wire webhooks by hand.** The `platform-ops` install skill registers each declared webhook automatically via your existing `gh` CLI — no paste-into-GitHub step. Use [Quickstart](/quickstart) for the full guided flow. The reference below is for custom webhooks — your own provider, an internal service, etc. + **`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. ## Declaring a webhook trigger @@ -37,7 +37,7 @@ x-agentsfleet: `source` is a label that appears in the activity stream (`github`, `slack`, `linear`, etc.) and selects the per-trigger inbound URL — `https://api.agentsfleet.net/v1/webhooks/{fleet_id}/{source}`. `events` is an optional whitelist of upstream event names (1–16 entries, ≤64 chars each); omit it to accept every event the source delivers. The `signature` block tells the platform how to verify the request. -The singular `trigger:` shape is rejected at install (`ERR_AGENTSFLEET_INVALID_CONFIG: use "triggers:" (array)`); always declare the array form, even for a single webhook. +The singular `trigger:` shape is rejected at install with `UZ-AGT-008` (invalid fleet config); always declare the array form, even for a single webhook. ## Authentication @@ -103,20 +103,22 @@ curl -X POST https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4 The platform verifies the signature, enqueues the event, and returns `202 Accepted`: ```json -{ "accepted": true, "request_id": "0198a7b7-4e9c-7a18-b3d6-5f2c8a4e1b73" } +{ "status": "accepted", "event_id": "0198a7b7-4e9c-7a18-b3d6-5f2c8a4e1b73" } ``` Delivery is **at-least-once** — your provider may retry on transient failure, so the same event can arrive twice. Include a unique `event_id` in the body so the fleet can dedupe. -## Failure responses - -| Status | Cause | -|--------|-------| -| `401` | Missing, malformed, or mis-signed signature header. | -| `404` | Fleet ID does not exist. | -| `410` | Fleet was killed; re-install with `agentsfleet install --from `. | -| `429` | Rate limit hit; back off per `Retry-After`. | -| `503` | Budget breached, or platform applying backpressure; safe to retry after the period resets. | +## Responses + +| Status | Body | Meaning | +|--------|------|---------| +| `202` | `{ "status": "accepted", "event_id": "…" }` | Signature verified; event enqueued. | +| `200` | `{ "ignored": "fleet_paused" }` (or a filter reason) | Fleet is paused, stopped, or killed — or the event was filtered out. Accepted without opening a run; retry queues add no value, so this is `200`, not `4xx`. | +| `401` | `UZ-WH-010` / `UZ-WH-011` / `UZ-WH-020` | Missing, malformed, mis-signed, or stale signature; or no webhook credential configured. | +| `404` | `UZ-WH-001` | No fleet at this URL — wrong `fleet_id`, or the fleet was deleted. | +| `413` | `UZ-WH-030` | Payload exceeds the 1 MiB ingest limit. | +| `429` | — | Rate limit hit; back off per `Retry-After`. | +| `503` | — | Platform applying backpressure; safe to retry after the period resets. | ## Approval gate webhooks diff --git a/index.mdx b/index.mdx index b399f08..2fcb8ea 100644 --- a/index.mdx +++ b/index.mdx @@ -7,18 +7,18 @@ description: "agentsfleet is a fleet of prebuilt AI teammates for recurring engi agentsfleet is in early access. Join the waitlist to get in — or email [agentsfleet@agentmail.to](mailto:agentsfleet@agentmail.to) to come on as a design partner. -Each one wakes on an event — a pull request, an incident, a deploy — investigates across your code, telemetry, and live control-plane state, opens a scenario-backed fix, and waits for human approval before it ships. Every move lands in a durable, replayable log — evidenced answers, never chat. +Each fleet is two markdown files — a `SKILL.md` that says what to investigate and a `TRIGGER.md` that says when it wakes and which tools it may call. Install one, wire a webhook, and it runs on every event — no servers to manage, every move in a replayable log. ## Get started -Install `agentsfleet` and the host skills in one command: +Install the `agentsfleet` CLI in one command: ```bash curl -fsSL https://agentsfleet.dev | bash ``` - Sign in, install `platform-ops`, and trigger your first real diagnosis — step by step from a cold machine. + Sign in, install a fleet from the template catalogue, and trigger your first real run — step by step from a cold machine. ## Explore diff --git a/memory.mdx b/memory.mdx index 526467b..d47bf60 100644 --- a/memory.mdx +++ b/memory.mdx @@ -1,22 +1,22 @@ --- title: "Memory" -description: "How a fleet remembers across events — four categories, four tools, when to use each." +description: "How a fleet remembers across events — the categories, the four tools, and when to use each." --- Memory is what a fleet *learned* from prior events that lets it behave like a teammate who's been here before, instead of one that showed up this morning. A fleet writes facts via `memory_store` and reads them back via `memory_recall` on the next event. Memory is always on — no setup, no flag. -## The four categories +## Categories | Category | Scope | Lifetime | Use for | |---|---|---|---| | `core` | fleet | durable; evicted last at the entry cap | Learned facts about durable entities — customers, accounts, preferences. | | `daily` | fleet | 72h auto-prune | Time-bounded follow-ups, open tickets, scheduled reminders. | -| `conversation` | event | dies with the run | Within-run scratch — checkpoint findings during a long incident. | -| `workspace` | workspace | durable | Facts shared across every fleet in the workspace. | +| `conversation` | fleet | windowed; ages out fast | Within-run scratch — checkpoint findings during a long incident. | +| *(custom)* | fleet | windowed by recency | Any other label you pick — treated as recency-windowed, never pinned. | -Pick `core` for "would I want a future event to know this?" Pick `daily` for "this should expire on its own." Pick `conversation` only for staging during a long run. Pick `workspace` only when multiple fleets need the same fact. +All memory is scoped to one `fleet_id` — there is no cross-fleet or workspace-wide category. Pick `core` for "would I want a future event to know this?" Pick `daily` for "this should expire on its own." Pick `conversation` only for run-scoped scratch. Any label the platform doesn't recognise is treated as a custom, recency-windowed category. ## The four tools @@ -24,12 +24,12 @@ The fleet calls these from inside a run; the runtime wires them to the memory ba | Tool | Shape | Purpose | |---|---|---| -| `memory_store(key, category, content, tags?)` | upsert | Write a distilled fact. | -| `memory_recall(key)` | one entry or empty | Exact lookup by key. | -| `memory_list(filter)` | matching entries | Filter by category / tags / recency. | -| `memory_forget(key)` | delete | Remove or correct a fact. | +| `memory_store(key, content, category?)` | upsert | Write a distilled fact under a stable key. | +| `memory_recall(query, limit?)` | ranked matches | Search recent memory by free-text query (recency-ranked, not an exact-key lookup). | +| `memory_list(filter)` | matching entries | Filter by category / recency. | +| `memory_forget(key)` | delete | Remove or correct a fact by key. | -There is no vector search. Pre-filter with tags + categories + recency, then let the model reason over the candidate set. +There is no vector search — recall ranks by recency, not embedding similarity. Narrow with categories and recency, then let the model reason over the candidate set. ## Where memory fits in a run @@ -62,20 +62,18 @@ Four habits make selection work for you instead of against you: ## Entry format -Memory is stored in Postgres but exports as markdown for human review. +Memory is stored in Postgres. Read it back with `agentsfleet memory list` / `agentsfleet memory search` — a table, or `--json` for the raw shape: -```markdown ---- -key: customer_bob_chen_acme -category: core -tags: [customer, plan_pro] ---- - -Bob Chen, Acme. Pro since Jan 15. API user (not dashboard), webhooks → Slack. -Prefers technical responses. Prior: Feb 3 signature issue (NTP). +```json +{ + "key": "customer_bob_chen_acme", + "category": "core", + "content": "Bob Chen, Acme. Pro since Jan 15. API user (not dashboard), webhooks → Slack. Prefers technical responses. Prior: Feb 3 signature issue (NTP).", + "updated_at": 1718900000000 +} ``` -Frontmatter is structured metadata; the body is the distilled prose the fleet wrote. +`key` is the stable handle the fleet stores and forgets by; `content` is the distilled prose it wrote. ## Correcting what the fleet learned @@ -89,7 +87,7 @@ The next event uses the corrected memory. ## Isolation -Every memory operation is scoped by `fleet_id`. Fleet A cannot read Fleet B's memory. The memory store is a separate Postgres database, not a shared filesystem — even a fleet with shell or file tools can't reach it through the wrong protocol. +Every memory operation is scoped by `fleet_id`. Fleet A cannot read Fleet B's memory. The memory store is a separate Postgres schema behind a dedicated database role with no grants on the core tables — not a shared filesystem, so even a fleet with shell or file tools can't reach it through the wrong protocol. ## Common questions @@ -112,4 +110,4 @@ The underlying system changed but memory didn't. Steer the fleet to call `memory | Recall returns nothing on a known entity | Inconsistent key convention | Use a stable, deterministic key derivation in `SKILL.md` (e.g. `customer_`). | | Memory grows forever | `core` has no time-based pruning; at the entry cap, coldest `core` entries are evicted when no non-core entries remain | Steer the fleet to call `memory_forget` on stale keys, or move time-bounded entries to `daily`. | | `UZ-MEM-003` on store | Memory backend unavailable | Re-run the trigger; if persistent, file an issue. | -| `UZ-MEM-001` on store | Memory scope denied (cross-fleet access attempt) | Memory is per-fleet. Use `workspace`-category writes if you need to share facts across fleets. | +| `UZ-MEM-002` on store | Fleet not found for memory op | The `fleet_id` doesn't exist in this workspace (a cross-workspace id returns the same 404, so existence isn't leaked). Confirm with `agentsfleet status`. | diff --git a/quickstart.mdx b/quickstart.mdx index b9c3141..917025c 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -1,36 +1,24 @@ --- title: Quickstart -description: "Install agentsfleet, run /agentsfleet-install-platform-ops, see a real diagnosis in Slack." +description: "Install the agentsfleet CLI, install a fleet from the template catalogue, and watch it run." --- -This walks through installing the flagship `platform-ops` fleet on one of your repositories. Total time: about ten minutes from a cold machine. At the end, a deploy failure on the repo lands an evidenced diagnosis in your Slack channel. +This walks through installing a fleet from the first-party catalogue and seeing it run — about five minutes from a cold machine. We'll use `github-pr-reviewer`, which wakes on a pull request and posts a review comment; the same steps work for any template. - - You'll drive the install via a markdown-skill host. Any of these work — the install skill ships identical prompts in each: - - - **Claude Code** — `claude.ai/code` - - **Amp** — `ampcode.com` - - **Codex CLI** — `npm install -g @openai/codex` - - **OpenCode** — `opencode.ai` - - Pick one. The rest of this page assumes you have a working session in front of you. - - - + ```bash - npm install -g @agentsfleet/cli - npx skills add agentsfleet/skills + curl -fsSL https://agentsfleet.dev | bash ``` + This installs the `agentsfleet` CLI (it runs npm under the hood, so Node.js is required). Prefer npm directly? `npm install -g @agentsfleet/cli`. Run `curl -fsSL https://agentsfleet.dev` without `| bash` to read the script first. + Verify: ```bash agentsfleet --version ``` - - `agentsfleet` is the only binary you install on your machine; it ships the skill samples under `~/.config/agentsfleet/samples/` so the install skill can drive `agentsfleet install --from` against a known-good source. `npx skills add agentsfleet/skills` then symlinks the `/agentsfleet-*` host skills from the public [`agentsfleet/skills`](https://github.com/agentsfleet/skills) repo into every supported agent it detects — so `/agentsfleet-install-platform-ops` is ready to invoke in the next step. @@ -38,102 +26,97 @@ This walks through installing the flagship `platform-ops` fleet on one of your r agentsfleet login ``` - Opens a Clerk-backed approval page in your browser. After you click **Approve**, the page shows a 6-digit verification code — type it back into the CLI to complete login. The code binds the browser approver to the terminal you're typing from. Hosted execution (event receipts + runs) is **free until July 31, 2026** — no credit card to start; see [pricing](https://agentsfleet.net/pricing) for the metered rates after the trial. You bring your provider and model — pay them directly. agentsfleet marks up zero on inference. + Opens a Clerk-backed approval page in your browser. After you click **Approve**, the page shows a 6-digit verification code — type it back into the CLI to complete login. The code binds the browser approver to the terminal you're typing from. - Login also fetches your tenant's workspaces and selects the first one as active locally. Signup auto-provisions a default workspace, so your CLI is ready to install fleets immediately — no `workspace add` required. + Login also fetches your tenant's workspaces and selects the first one as active. Signup auto-provisions a default workspace, so your CLI is ready to install a fleet immediately — no `workspace add` required. - Pass `--token-name "your-device-label"` to label this install so it's easy to recognize on the approval page and in `agentsfleet auth status` later. Defaults to your platform family otherwise. + Hosted execution (event receipts + runs) is **free until July 31, 2026** — no credit card to start; see [pricing](https://agentsfleet.net/pricing) for the metered rates after the trial. You bring your provider and model and pay them directly — agentsfleet marks up zero on inference. - **No terminal — CI, or an agent driving the CLI?** Skip the browser entirely: supply a token via the `--token ` flag or piped on stdin — resolved in that order (prefer stdin to keep it out of shell history). For ongoing machine auth, set the `AGENTSFLEET_API_KEY` environment variable instead of logging in — it is sent on every request and overrides a stored login. Add `--no-input` to fail fast instead of waiting for the code — a no-TTY shell with no token exits with an error. Full precedence in [`agentsfleet login`](/cli/agentsfleet#agentsfleet-login). + **No terminal — CI, or an agent driving the CLI?** Skip the browser: supply a token via `--token ` or piped on stdin (prefer stdin to keep it out of shell history). For ongoing machine auth, set the `AGENTSFLEET_API_KEY` environment variable instead of logging in — it's sent on every request and overrides a stored login. Add `--no-input` to fail fast instead of waiting for the code. Full precedence in [`agentsfleet login`](/cli/agentsfleet#agentsfleet-login). ```bash - agentsfleet workspace add platform-ops + agentsfleet workspace add pr-review ``` - Skip this step if the signup-provisioned default workspace is fine. Run it only when you want a second workspace or a custom name. Workspaces are the boundary for credentials, access control, and webhook namespaces — every fleet lives in exactly one. Switch later with `agentsfleet workspace use `. See [Command reference → workspaces](/cli/agentsfleet#workspaces). + Skip this if the signup-provisioned default workspace is fine. Workspaces are the boundary for credentials, access control, and webhook namespaces — every fleet lives in exactly one. Switch later with `agentsfleet workspace use `. See [Command reference → workspaces](/cli/agentsfleet#workspaces). - - The `npx skills add agentsfleet/skills` in Step 2 already added the `/agentsfleet-install-platform-ops` skill to your agent. Invoke it: + + List the first-party templates and the credentials each one needs: + ```bash + agentsfleet templates ``` - /agentsfleet-install-platform-ops - ``` - - The skill drives `agentsfleet install --from ~/.config/agentsfleet/samples/platform-ops` under the hood. Power users can run that directly; everyone else gets the guided flow. - - **Fresh machine?** `curl -fsSL https://agentsfleet.dev | bash` installs `agentsfleet` and the skill in one shot (it runs npm under the hood) — a one-command replacement for Step 2. You still need `agentsfleet login` (Step 3) before the skill works. Run `curl -fsSL https://agentsfleet.dev` without `| bash` to read it first. - + ``` + TEMPLATE NAME CREDENTIALS + github-pr-reviewer GitHub Pull Request reviewer github + security-reviewer Security reviewer github + zoho-sprint-daily-summarizer Zoho Sprints daily summarizer zoho + ``` - The skill asks three gating questions: + `github-pr-reviewer` needs a `github` credential. Add it to the workspace vault before installing (install rejects a bundle whose credentials are missing, `UZ-BUNDLE-003`). Pipe the JSON on stdin so it never lands in shell history: - - **Slack channel** — where diagnoses post (e.g. `#platform-ops`). - - **Production branch glob** — which branches count as production (default `main`). - - **Cron schedule** (optional) — for periodic health checks (e.g. `*/30 * * * *`). Leave blank for webhook-only. + ```bash + agentsfleet credential add github --data=@- <<'JSON' + { "api_token": "ghp_...", "webhook_secret": "<32-byte hex>" } + JSON + ``` - It writes `.agentsfleet/platform-ops/SKILL.md` and `.agentsfleet/platform-ops/TRIGGER.md` into the current repo. Re-running against the same workspace is idempotent; existing files are diffed and updated. + `api_token` lets the fleet post review comments; `webhook_secret` verifies inbound webhook signatures. See [Credentials](/fleets/credentials) for the full vault model. - - The install skill registers the GitHub webhook automatically. It reads the `triggers[]` block in the generated `TRIGGER.md`, then calls `gh api repos///hooks` per webhook trigger — using the user's existing `gh` authentication and the `webhook_secret` field from the workspace `github` credential. There is no paste-into-GitHub step. + + ```bash + agentsfleet install --template github-pr-reviewer + ``` - After install, the skill prints a summary line per registered hook: + agentsfleet fetches the template's pinned source, validates it server-side, prints a requirements preview (credentials, tools, network hosts), then creates the fleet and prints its webhook URL: ``` - ✓ github · https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github - hook_id=489182 events=[workflow_run] active=true - HMAC self-verify: ok + ✓ github-pr-reviewer is live. + Fleet ID: 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 + Webhook URLs (register on the upstream provider): + github: https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github ``` - The fleet filters incoming payloads for `conclusion=failure` on a production-branch workflow — the rule lives in the generated `.agentsfleet/platform-ops/SKILL.md` and is editable. See [Authoring](/fleets/authoring) to widen or narrow it. - - If `gh` is not authenticated for `admin:repo_hook` scope, the skill stops with the exact recovery command (`gh auth refresh -s admin:repo_hook`). If the hook already exists at the same URL, the skill matches on `config.url` and advances — re-running the install is idempotent. - - - **One workspace credential, many repos.** The workspace's `github` credential carries the signing secret for every fleet in the workspace. Tradeoff: rotation is workspace-wide; rotating the workspace `github` credential affects every fleet that uses it. - - - - **Rotating the webhook secret.** The signing secret lives in the workspace vault under the `github` credential — there is no user-visible copy printed at install. To rotate, replace the credential then update every registered hook with `gh`. Two steps: - - **1. Rotate the workspace `github` credential.** Generate a new webhook secret (e.g. `openssl rand -hex 32`), store it in 1Password, then pipe the credential JSON through `op inject` so the secret never appears in shell history or argv. Run `op signin` first — if the 1Password session is stale, `op inject` fails before `agentsfleet` runs and the workspace vault is left untouched (don't proceed to step 2 in that case, or your GitHub webhooks will be set to a secret the server never stored): + Re-running is idempotent. Pass `--name ` to back several fleets with one template (e.g. one reviewer per repo). See [Templates](/fleets/templates). + - ```bash - cat <<'JSON' | op inject | agentsfleet credential add github --data=@- --force - { - "api_token": "{{ op://Personal/agentsfleet-github/api_token }}", - "webhook_secret": "{{ op://Personal/agentsfleet-github/webhook_secret }}" - } - JSON - ``` + + The CLI prints the webhook URL but does **not** register it for you. Add it to your repository on GitHub — **Settings → Webhooks → Add webhook**: - `op inject` substitutes each `{{ op://... }}` reference with the resolved secret and pipes the rendered JSON to `agentsfleet`. `--data=@-` reads from stdin; `--force` overwrites the existing credential. If you don't use 1Password, the literal-JSON form below works the same — just keep it on stdin, never inline: + - **Payload URL** — the `github:` URL the install step printed. + - **Content type** — `application/json`. + - **Secret** — the same `webhook_secret` you stored in the `github` credential. + - **Which events** — "Let me select individual events" → **Pull requests**. - ```bash - cat <<'JSON' | agentsfleet credential add github --data=@- --force - { "api_token": "ghp_...", "webhook_secret": "" } - JSON - ``` + Or do it from the terminal with your existing `gh` auth: - See [Credentials](/fleets/credentials) for the full schema. + ```bash + gh api repos///hooks --method POST \ + -f "name=web" \ + -f "config[url]=https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github" \ + -f "config[content_type]=json" \ + -f "config[secret]=" \ + -f "events[]=pull_request" \ + -F "active=true" + ``` - **2. Update every registered hook.** Re-run `/agentsfleet-install-platform-ops` in each repo — the install skill detects the existing hook, calls `gh api -X PATCH repos///hooks/` with the new secret, and re-runs HMAC self-verify. The old secret stops working the moment step 1 completes, so do this immediately after. - + See [Webhooks](/fleets/webhooks) for signature details and other providers. - - Cause a deploy failure on the production branch — push a known-broken commit, fail a test on purpose, whatever you have handy. Within seconds: + + Open a pull request on the repo. Within seconds: - - GitHub fires `workflow_run.completed` with `conclusion: failure` to the webhook URL. - - The fleet wakes, calls the tools `TRIGGER.md` allow-lists (`http_request` against your hosting provider, `memory_store` for findings), gathers evidence from the failed workflow. - - An evidenced diagnosis posts to your Slack channel. + - GitHub fires `pull_request` to the webhook URL. + - The fleet wakes, reads the PR, and posts a review comment. - Tail it — replace `` with the value the install step printed (e.g. `0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71`): + Tail it — replace `` with the value the install step printed: ```bash agentsfleet logs 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 @@ -146,21 +129,27 @@ This walks through installing the flagship `platform-ops` fleet on one of your r ## What just happened -The platform-ops fleet installed `SKILL.md` (the prose system prompt — what to investigate, how to phrase a diagnosis) and `TRIGGER.md` (which tools the model can call) into your repo. From here, behaviour iterates on prose: edit the `.agentsfleet/platform-ops/SKILL.md` file, push, the next trigger runs the new behaviour. No redeploys, no DAG editor. +A fleet is two markdown files: `SKILL.md` (the prose system prompt — what to do, how to phrase a result) and `TRIGGER.md` (the runtime config — when it wakes, which tools it may call, which credentials it reads). The template shipped both; the platform stores them server-side. To change behaviour, edit a local bundle and roll it onto the live fleet: + +```bash +agentsfleet fleet update 0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71 --from ./my-fleet +``` + +No redeploys, no DAG editor — the next event runs the new prose. ## Next steps - `agentsfleet steer "morning health check"` — same reasoning loop, manual trigger. Useful before you have a webhook firing. + `agentsfleet steer "review the latest PR"` — same reasoning loop, manual trigger. Useful before a webhook is firing. - - The two markdown files in `.agentsfleet/platform-ops/` are the entire behaviour. Edit them like any other source file. + + Write your own `SKILL.md` + `TRIGGER.md` and install it with `agentsfleet install --from .`. - Why deep incidents keep reasoning past the model's context cap. Defaults work for 95% of cases. + Why deep runs keep reasoning past the model's context cap. Defaults work for 95% of cases. - - The `SKILL.md` + `TRIGGER.md` reference for writing your own. + + The full first-party catalogue and how to install from it. From 40900f3f01e3eee2c0a0c7b56ab2a72d70044aae Mon Sep 17 00:00:00 2001 From: Kishore Kumar Date: Mon, 22 Jun 2026 09:20:09 +0530 Subject: [PATCH 2/4] docs: align memory_recall wording with architecture (selected, not ranked search) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The architecture reference (docs/architecture/direction.md, runner_fleet.md §Selection policy) is explicit that fleet memory is selected, not searched: memory_recall returns the raw entries whose key matches a substring filter and the model decides relevance — no scoring, no ranking, no vector search. The recency/category pinning applies to hydration (selection), not to recall. The prior wording ("recency-ranked search") overstated it; this matches the canonical model so memory.mdx and the architecture docs agree. Co-Authored-By: Claude Opus 4.8 (1M context) --- fleets/tools.mdx | 2 +- memory.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fleets/tools.mdx b/fleets/tools.mdx index df4a895..e66ee11 100644 --- a/fleets/tools.mdx +++ b/fleets/tools.mdx @@ -37,7 +37,7 @@ Cross-run durable state. See [Memory](/memory) for the category model and key co | Tool | What it does | Reach for when | |---|---|---| | `memory_store` | Upsert a distilled fact under a stable key (`key` + `content`, optional `category`). | End of every run where the fleet learned something worth keeping. | -| `memory_recall` | Free-text search over recent memory (recency-ranked); returns matching entries. | Start of every run, before reasoning. | +| `memory_recall` | Return memory entries whose key matches the query (substring filter); the model judges relevance — no ranking or vector search. | Start of every run, before reasoning. | | `memory_list` | Filter entries by category, tags, recency. | When the fleet doesn't know the exact key (e.g. "show me all open tickets"). | | `memory_forget` | Delete an entry. | Correcting stale facts; fed by `agentsfleet steer` corrections. | diff --git a/memory.mdx b/memory.mdx index d47bf60..d214c23 100644 --- a/memory.mdx +++ b/memory.mdx @@ -25,11 +25,11 @@ The fleet calls these from inside a run; the runtime wires them to the memory ba | Tool | Shape | Purpose | |---|---|---| | `memory_store(key, content, category?)` | upsert | Write a distilled fact under a stable key. | -| `memory_recall(query, limit?)` | ranked matches | Search recent memory by free-text query (recency-ranked, not an exact-key lookup). | +| `memory_recall(query, limit?)` | matching entries | Return entries whose key matches the query (substring filter) for the model to judge — no ranking, no vector search. | | `memory_list(filter)` | matching entries | Filter by category / recency. | | `memory_forget(key)` | delete | Remove or correct a fact by key. | -There is no vector search — recall ranks by recency, not embedding similarity. Narrow with categories and recency, then let the model reason over the candidate set. +There is no vector search and no scoring — `memory_recall` returns the raw entries whose key matches (a substring filter is the ceiling), and the model decides relevance. Narrow by category and recency with `memory_list`, then let the model reason over the candidate set. ## Where memory fits in a run From 5cf7e48852e2090651d7060021b35a4101e100f2 Mon Sep 17 00:00:00 2001 From: Kishore Kumar Date: Mon, 22 Jun 2026 09:34:23 +0530 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20address=20greptile=20P1s=20?= =?UTF-8?q?=E2=80=94=20drop=20stale=20memory=5Flist=20tags=20filter;=20use?= =?UTF-8?q?=20=20placeholder=20in=20webhook=20gh=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fleets/tools.mdx: memory_list no longer advertises a tags filter (tags was removed from the memory model in this PR; memory.mdx already says category/recency). - quickstart.mdx: the gh api webhook-registration URL used a literal example fleet UUID; replaced with the placeholder so a copy-paste does not silently register the hook to the wrong fleet. Co-Authored-By: Claude Opus 4.8 (1M context) --- fleets/tools.mdx | 2 +- quickstart.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fleets/tools.mdx b/fleets/tools.mdx index e66ee11..ac0f29d 100644 --- a/fleets/tools.mdx +++ b/fleets/tools.mdx @@ -38,7 +38,7 @@ Cross-run durable state. See [Memory](/memory) for the category model and key co |---|---|---| | `memory_store` | Upsert a distilled fact under a stable key (`key` + `content`, optional `category`). | End of every run where the fleet learned something worth keeping. | | `memory_recall` | Return memory entries whose key matches the query (substring filter); the model judges relevance — no ranking or vector search. | Start of every run, before reasoning. | -| `memory_list` | Filter entries by category, tags, recency. | When the fleet doesn't know the exact key (e.g. "show me all open tickets"). | +| `memory_list` | Filter entries by category / recency. | When the fleet doesn't know the exact key (e.g. "show me all open tickets"). | | `memory_forget` | Delete an entry. | Correcting stale facts; fed by `agentsfleet steer` corrections. | ## Cron diff --git a/quickstart.mdx b/quickstart.mdx index 917025c..da18796 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -100,7 +100,7 @@ This walks through installing a fleet from the first-party catalogue and seeing ```bash gh api repos///hooks --method POST \ -f "name=web" \ - -f "config[url]=https://api.agentsfleet.net/v1/webhooks/0198a7b2-9e1f-7c3a-8b25-6d4f0a9e2c71/github" \ + -f "config[url]=https://api.agentsfleet.net/v1/webhooks//github" \ -f "config[content_type]=json" \ -f "config[secret]=" \ -f "events[]=pull_request" \ From ae38802f7a9295539da50c73b5c60eed78e929f0 Mon Sep 17 00:00:00 2001 From: Kishore Kumar Date: Mon, 22 Jun 2026 09:57:27 +0530 Subject: [PATCH 4/4] docs: link UZ-BUNDLE-003 to its error-codes reference (greptile follow-up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UZ-BUNDLE-003 (424 Fleet Bundle credentials missing) is a real registered code — error_registry.zig:127 / error_entries.zig:123 — and is already documented in api-reference/error-codes.mdx (Fleet Bundle section). greptile flagged it as possibly fabricated because error-codes.mdx is unchanged in this PR and so wasn't in its diff view. Link the inline mention to the reference page so the code is verifiable from the quickstart. Co-Authored-By: Claude Opus 4.8 (1M context) --- quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart.mdx b/quickstart.mdx index da18796..38e66e8 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -59,7 +59,7 @@ This walks through installing a fleet from the first-party catalogue and seeing zoho-sprint-daily-summarizer Zoho Sprints daily summarizer zoho ``` - `github-pr-reviewer` needs a `github` credential. Add it to the workspace vault before installing (install rejects a bundle whose credentials are missing, `UZ-BUNDLE-003`). Pipe the JSON on stdin so it never lands in shell history: + `github-pr-reviewer` needs a `github` credential. Add it to the workspace vault before installing (install rejects a bundle whose credentials are missing, [`UZ-BUNDLE-003`](/api-reference/error-codes#fleet-bundle)). Pipe the JSON on stdin so it never lands in shell history: ```bash agentsfleet credential add github --data=@- <<'JSON'