Improve external agent invite flow (#6183)

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies.
> - Agent creation can happen through local runtimes, managed runtimes,
and external agents that onboard through invites.
> - The old OpenClaw-oriented invite UX lived under company
settings/invites and made a gateway-specific path look like a company
access setting.
> - That hid the broader bring-your-own-agent flow and forced operators
to leave the add-agent modal when adding an external agent.
> - This pull request moves external agent invite generation into the
add-agent modal and makes the copy agent-oriented instead of
OpenClaw-only.
> - The benefit is a clearer agent-first onboarding path while company
invites stay focused on human access.

## What Changed

- Added an external-agent invite branch to the add-agent modal,
including a dedicated prompt result view with Back navigation.
- Added a shared agent onboarding prompt builder and focused modal
coverage for prompt replacement/back navigation.
- Removed the agent invite prompt UI from Company Settings and Company
Invites, leaving Company Invites focused on human access links and
invite history.
- Updated the hidden OpenClaw Gateway runtime hint to direct operators
to the add-agent invite flow instead of presenting it as a blocked
runtime card.
- Updated invite/onboarding docs, storybook coverage, and server-side
onboarding copy toward generic agent language while preserving existing
gateway compatibility.

## Verification

- `pnpm -r typecheck`
- `pnpm build`
- `FAKE_BIN="$(mktemp -d)/bin"; mkdir -p "$FAKE_BIN"; printf
'#!/bin/sh\nexit 1\n' > "$FAKE_BIN/tailscale"; chmod +x
"$FAKE_BIN/tailscale"; PATH="$FAKE_BIN:$PATH" pnpm test:run`
- `pnpm test:run` without the fake `tailscale` shim was also attempted;
it failed only in two pre-existing CLI tailnet fallback tests because
this host has a real Tailscale address (`100.125.202.3`) where those
tests expect no Tailscale.
- Focused confirmation for that host-env issue: `FAKE_BIN=...
PATH="$FAKE_BIN:$PATH" pnpm exec vitest run --project paperclipai
cli/src/__tests__/network-bind.test.ts
cli/src/__tests__/onboard.test.ts`
- Manual UI verification: served UI locally in light mode, opened
add-agent modal, generated external agent prompt, verified the generated
prompt replaces the form and Back returns to the form.

### Screenshots

![Add agent
modal](https://raw.githubusercontent.com/aronprins/paperclip/pr-assets/6183-agent-invites/.github/pr-screenshots/6183/add-agent-modal-light.png)

![External agent invite
form](https://raw.githubusercontent.com/aronprins/paperclip/pr-assets/6183-agent-invites/.github/pr-screenshots/6183/external-agent-invite-form-light.png)

![Generated onboarding prompt replacement
view](https://raw.githubusercontent.com/aronprins/paperclip/pr-assets/6183-agent-invites/.github/pr-screenshots/6183/onboarding-prompt-result-light.png)

## Risks

- Existing OpenClaw gateway compatibility remains, but operators now
discover external agent onboarding from the add-agent modal instead of
company settings.
- Agent invites still appear in the invite history table, so that page
may show agent-scoped invite rows even though it no longer creates agent
onboarding prompts.
- Low migration risk: no schema changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5 coding agent in Codex desktop; tool-enabled
repository, shell, browser, and GitHub workflow. Context window size was
not exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
This commit is contained in:
Aron Prins 2026-05-23 16:09:40 +02:00 committed by GitHub
parent e3c875c1c7
commit 897cc322c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 693 additions and 451 deletions

View file

@ -554,10 +554,12 @@ pnpm paperclipai dashboard get
See full command reference in `doc/CLI.md`.
## OpenClaw Invite Onboarding Endpoints
## Agent Invite Onboarding Endpoints
Agent-oriented invite onboarding now exposes machine-readable API docs:
The board UI generates agent onboarding prompts from the add-agent modal (`+` in the agent sidebar), so agent onboarding sits with the rest of agent creation rather than company member invite settings.
- `GET /api/invites/:token` returns invite summary plus onboarding and skills index links.
- `GET /api/invites/:token/onboarding` returns onboarding manifest details (registration endpoint, claim endpoint template, skill install hints).
- `GET /api/invites/:token/onboarding.txt` returns a plain-text onboarding doc intended for both human operators and agents (llm.txt-style handoff), including optional inviter message and suggested network host candidates.
@ -575,7 +577,7 @@ pnpm smoke:openclaw-join
What it validates:
- invite creation for agent-only join
- agent join request using `adapterType=openclaw`
- agent join request using `adapterType=openclaw_gateway`
- board approval + one-time API key claim semantics
- callback delivery on wakeup to a dockerized OpenClaw-style webhook receiver

View file

@ -6,7 +6,7 @@ Date: 2026-04-13
This document maps the current invite creation and acceptance states implemented in:
- `ui/src/pages/CompanyInvites.tsx`
- `ui/src/pages/CompanySettings.tsx`
- `ui/src/components/NewAgentDialog.tsx`
- `ui/src/pages/InviteLanding.tsx`
- `server/src/routes/access.ts`
- `server/src/lib/join-request-dedupe.ts`
@ -23,9 +23,9 @@ This document maps the current invite creation and acceptance states implemented
```mermaid
flowchart TD
Board[Board user on invite screen]
Board[Board user on invite or add-agent screen]
HumanInvite[Create human company invite]
OpenClawInvite[Generate OpenClaw invite prompt]
AgentInvite[Generate agent onboarding prompt]
Active[Invite state: active]
Revoked[Invite state: revoked]
Expired[Invite state: expired]
@ -44,7 +44,7 @@ flowchart TD
OpenClawReplay[Special replay path:<br/>accepted invite can be POSTed again<br/>for openclaw_gateway only]
Board --> HumanInvite --> Active
Board --> OpenClawInvite --> Active
Board --> AgentInvite --> Active
Active --> Revoked: revoke
Active --> Expired: expiresAt passes
@ -102,10 +102,10 @@ stateDiagram-v2
LatestInviteVisible --> Ready: navigate away or refresh
}
CompanySelection --> OpenClawPromptReady: Company settings prompt generator
OpenClawPromptReady --> OpenClawPromptPending: Generate OpenClaw Invite Prompt
OpenClawPromptPending --> OpenClawSnippetVisible: prompt generated
OpenClawPromptPending --> OpenClawPromptReady: generation failed
CompanySelection --> AgentPromptReady: Add-agent modal prompt generator
AgentPromptReady --> AgentPromptPending: Generate agent onboarding prompt
AgentPromptPending --> AgentSnippetVisible: prompt generated
AgentPromptPending --> AgentPromptReady: generation failed
```
## Invite Landing Screen States
@ -247,21 +247,21 @@ sequenceDiagram
sequenceDiagram
autonumber
actor Board as Board user
participant Settings as Company Settings UI
participant AddAgent as Add agent modal
participant API as Access routes
participant Invites as invites table
actor Gateway as OpenClaw gateway agent
actor Gateway as External agent
participant Join as join_requests table
actor Approver as Company admin
participant Agents as agents table
participant Keys as agent_api_keys table
Board->>Settings: Generate OpenClaw invite prompt
Settings->>API: POST /api/companies/:companyId/openclaw-invite-prompt
Board->>AddAgent: Generate agent onboarding prompt
AddAgent->>API: POST /api/companies/:companyId/invites (allowedJoinTypes=agent)
API->>Invites: Insert active agent invite
API-->>Settings: Prompt text + invite token
API-->>AddAgent: Prompt text + invite token
Gateway->>API: POST /api/invites/:token/accept (agent, openclaw_gateway)
Gateway->>API: POST /api/invites/:token/accept (agent, adapter-specific payload)
API->>Invites: Mark invite accepted
API->>Join: Insert pending_approval join request + claimSecretHash
API-->>Gateway: requestId + claimSecret + claimApiKeyPath