Agent integration
Give your coding agent its own window onto AppHaven. With the apphaven CLI and the
AppHaven skill installed, an agent working in your repository can answer for itself: is the
app deployed, on what URL, did the build succeed, why did it crash, what is it logging right now.
It can also check apphaven.yaml against the platform's validation before anything is pushed.
The CLI inspects your app and submits configuration proposals for human review. It cannot approve or apply settings, deploy, restart, or read secret values. It can withdraw its user's own CLI submissions. Deploys keep following your configured Git push policy.
The fast path: install the plugin (step 1) and ask your agent to "set up AppHaven access". The skill walks it through installing the CLI and starting the login; your only step is approving the request in your browser. Steps 2 and 3 are the manual equivalent.
1. Teach your agent
Claude Code: install the AppHaven plugin from the marketplace.
/plugin marketplace add apphaven-eu/claude-plugins
/plugin install apphaven
The plugin ships the skill: what the CLI can do, how to read build and runtime logs, how to author
apphaven.yaml, and where these docs live. Updates arrive through the marketplace.
Codex and other agents: paste this block into the instructions file your agent reads
(AGENTS.md or equivalent). Keep the markers so you can replace the block when it changes.
<!-- apphaven:begin -->
## AppHaven (this app's hosting platform)
- This repo deploys on AppHaven. Pushing the production branch deploys production. Pushing a
branch that matches the app's preview pattern (default `preview/*`) deploys it as a preview
on its own URL — the branch name is the deploy trigger. `apphaven app <name>` shows the
app's actual `Auto-deploy:` setting; check it before assuming.
- Preview loop: push a matching branch, `apphaven status <app> --wait`, hand the human the
preview URL (they sign in; you cannot fetch the protected page yourself). If no deployment
appears, `apphaven events <app>` says why: "Preview limit reached" means the human must
delete an old preview in the console first (nothing is evicted automatically), then push
again. Previews are not backed up; deleting the branch deletes the preview and its data;
30 days idle stops a preview (data kept, next push resumes it).
- The `apphaven` CLI inspects apps and submits changes for human review. Useful commands
(all support --json; `apphaven <cmd> --help` is authoritative):
- `apphaven status <app>`: deployment phase, branch, URL
- `apphaven build-log <app>`: latest build log (failures are at the tail)
- `apphaven crash-log <app>`: what to read when a deployment is Failed
- `apphaven logs <app> --service <svc>`: container output
- `apphaven variables <app>`: config names (secret values are never shown)
- `apphaven vulns <app>`: security scan findings — package, installed version,
and "update to <version>" when a fix is released; bump the dependency (or the
Dockerfile base image) and push, the next build is re-scanned automatically
- `apphaven validate`: validate apphaven.yaml before pushing
- Debugging order: status, then build-log (build failed), then crash-log
(deploy failed), then logs (running but misbehaving), then variables
(missing config).
- Submit configuration proposals with `apphaven proposals create <app> --file changes.json --open`.
Each item needs a stable id, type, value and reason. Read current settings and pending proposals
first. The CLI generates a request ID; retain it and reuse `--request-id <printed-request-id>`
after a timeout or uncertain result. Never invent random IDs or create duplicate retry batches.
- Give the human the review URL. Only humans approve in the console, with the same permissions
as manual edits: developers can approve deployment policy; administrators can also approve
access mode and public paths. Never approve via browser automation or direct console requests.
- Read outcomes using `apphaven proposals show <app> <proposal-id> --json`. Unselected items stay
pending. Respect declines; do not repeat a declined request under a different ID.
- Repository recommendations use `proposals` in apphaven.yaml with id/type/value/reason. Preserve
IDs when editing. Only the configured production branch (usually main) is imported. Reasons
and formatting do not reset decisions; changed operation/value creates a new version. Removing
an item does not undo accepted settings. Do not duplicate recommendations via CLI and manifest.
- `apphaven proposals withdraw <app> <proposal-id>` cancels pending items only in CLI batches
submitted by the same subject. Use repeated `--item <id>` (the item id from the batch file) for a subset. Other users' batches
and manifest recommendations require an authorized human in the console, even for admin tokens.
- Public-path and access-mode approval saves settings; each branch must deploy before they take
effect. A login redirect before that is expected. Explain how public endpoints authenticate callers.
- The CLI cannot apply settings, deploy, restart, or reveal secrets. Deploys follow Git push policy
or human console action. If login is required, run `apphaven login` and leave browser consent to
the human. Never echo credentials. Proposal guide: https://docs.apphaven.eu/proposals.
- apphaven.yaml is strictly validated; unknown fields are errors. Reference:
https://docs.apphaven.eu/reference/manifest (full docs index for agents:
https://docs.apphaven.eu/llms.txt)
<!-- apphaven:end -->
2. Install the CLI
One line, no dependencies: the CLI is a single static binary.
# Linux, macOS, and WSL
curl -fsSL https://raw.githubusercontent.com/apphaven-eu/cli/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/apphaven-eu/cli/main/install.ps1 | iex
Verify with apphaven version. Your agent can run the installer for you; its normal
command-approval flow is your consent gate.
When a newer CLI is available, any command prints a one-line notice on stderr
(at most once a day; command output on stdout is never touched, so --json
pipelines are safe). Rerun the installer to update. Set
APPHAVEN_NO_UPDATE_NOTIFY=1 to silence the notice, for example in CI.
3. Log in
apphaven login
Your browser opens on auth.apphaven.eu and asks you to approve read access and proposal
submission. The CLI can submit proposed settings and withdraw your own CLI requests; it cannot
approve or apply settings. Existing read-only grants stay read-only until you log in again and
approve the expanded access. Credentials stay in your user profile (~/.config/apphaven/, or
%APPDATA%\apphaven on Windows) and refresh automatically.
It is safe to let an agent run apphaven login: the approval happens in your browser, and
credentials never appear in the command's output, so there is nothing for the agent to see or
echo.
You stay in control afterwards: the CLI access page in your account on auth.apphaven.eu lists
every active CLI login with its last use, and one click revokes it. apphaven logout does the
same from the terminal.
4. What the agent can (and cannot) do
| Can read | Can never do |
|---|---|
| Projects and applications you are a member of | Deploy, stop, or restart anything |
| Deployment status, branches, and URLs | Create, change, or delete applications |
| Build logs, crash reports, container output | Change variables or any configuration |
| Variable names (secret values stay masked) | Read secret values |
| The activity timeline | Act on projects you are not a member of |
| Submit proposals and withdraw its own CLI requests | Approve or apply proposed settings |
| Vulnerability findings and the inventory behind them | Change the access mode or public paths |
apphaven vulns <app> is worth pointing an agent at deliberately: it prints the affected
package, the version you run, and the version that fixes it, which is everything needed to raise a
dependency and push. Building with AI agents covers that
loop.
Reads follow your project membership. Revoking the grant (or losing membership) cuts the agent off at the next refresh.
5. Writing apphaven.yaml with an agent
Two tools keep a generated manifest honest:
-
apphaven validatechecks workload and proposal authoring rules. Invalid recommendations appear as validation/import errors but do not block an otherwise valid workload deployment. -
The JSON Schema gives editors and agents inline checking as the file is written. Add one comment line at the top of
apphaven.yaml:# yaml-language-server: $schema=https://docs.apphaven.eu/schemas/apphaven.schema.json
The schema checks structure; apphaven validate is the authority. It also catches what a schema
cannot, like dependency cycles or a ${...} reference to a service that doesn't exist. The
manifest reference documents every field.
For agents that read documentation directly: https://docs.apphaven.eu/llms.txt is an index of
every page on this site, and llms-full.txt is the whole documentation in one file.
6. Suggesting a public path
Use a public_path.add proposal, with an explanation of how the endpoint authenticates
callers. The CLI submits a batch and opens its review URL; the administrator decides in the app's
Proposals section. For repository-carried recommendations use the proposals manifest section,
which is imported only from the production branch. auth.public_paths remains a compatibility input.
After approval, the exemption takes effect on each branch's next deployment. Until then, a login redirect is expected. Requests to an exempt path carry no AppHaven identity header; your app must validate signatures, API keys, or other credentials itself.
Troubleshooting
Not logged in. Run "apphaven login".Exactly that; the grant may have been revoked or expired after long disuse.- The browser never reaches the terminal (firewall, SSH box, container): run
apphaven login --manual, open the printed URL on any device, and paste the code the approval page shows you back into the terminal. - 403: you are not a member of that project, or the grant was revoked.
- 429: the CLI is rate-limited per user; agents should respect the
Retry-Afterheader (apphaven status --waitandlogs --followdo this automatically). - "ambiguous app name": two apps share a name across your projects; pass
--project.