mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
docs(hub): document zero-friction onboarding (#3657)
Lead with the browser-to-CLI onboarding journey, document the generated starter bundle, and align guided setup with available Hub connections and daemon-reported runtime defaults.
This commit is contained in:
+8
-1
@@ -263,6 +263,7 @@ Use `PASEO_HOME` to run multiple isolated daemon instances.
|
||||
|
||||
```bash
|
||||
paseo hub login [url] # Approve and store organization-scoped CLI access
|
||||
paseo hub init # Guided setup: scaffold and deploy a starter bundle here
|
||||
paseo hub connect [url] # Enroll this daemon using CLI access
|
||||
paseo hub projects # List projects in the authenticated organization
|
||||
paseo hub status # Show the current Hub relationship
|
||||
@@ -276,7 +277,13 @@ Run deploy from the project root. It reads `.paseo/hub.yml`, every direct `.pase
|
||||
|
||||
Pass `-p, --project <slug>` to select the target project. `--dry-run` performs the same discovery and server validation without recording or activating a revision. Both outputs include the resolved Hub, project, and discovered workflow count.
|
||||
|
||||
`login` opens the Hub approval page and stores a durable organization-scoped CLI credential under `PASEO_HOME`. The stored login is separate from the daemon relationship created by `connect`. Interactive logout checks the same-origin daemon relationship and asks whether to disconnect before deleting the login. Declining removes only the login. JSON and noninteractive logout never prompt or disconnect implicitly; `--disconnect-daemon` is the explicit automation path, and `--force` applies to that daemon disconnection. If a requested disconnection fails, the login is preserved.
|
||||
`login` opens the Hub approval page and stores a durable organization-scoped CLI credential under `PASEO_HOME`. In an interactive terminal it then asks whether to connect this daemon and whether to initialize and deploy a starter workflow, both defaulting to yes. Declining the connection prints `paseo hub connect <origin>; then paseo hub init`, because the connection alone does not produce a bundle; declining only the starter prints `paseo hub init`. `--json` and non-TTY login remain login-only and never prompt. The stored login is separate from the daemon relationship created by `connect`.
|
||||
|
||||
`init` runs the same guided setup on its own and requires a TTY. It connects the daemon, uses the organization's only project or asks which one, and lists the Hub app connections that can back a starter workflow. One usable connection is selected automatically; with several, you choose a **Trigger connection**. If none is ready, setup sends you to **Hub → Apps** and stops before selecting an agent or writing files.
|
||||
|
||||
Setup then asks which agent provider, model, and mode the starter should run, choosing from what the connected daemon reports. A provider is offered only when the daemon has it enabled with a selectable model. Suggested model and mode entries are the daemon's defaults; no provider is suggested merely because it appears first. The mode question is skipped for providers that expose no modes and asked explicitly when the daemon has modes but no default. Finally, setup asks for the identity that gates the chosen connection: a GitHub username, a Slack member ID, or a Discord user ID. It writes `.paseo/hub.yml` and `.paseo/workflows/<provider>-help.yml`, validates them against Hub, and deploys. An existing `.paseo/` directory is replaced only after you confirm. See the [generated starter bundle](/docs/hub/configuration#generated-starter-bundle).
|
||||
|
||||
Interactive logout checks the same-origin daemon relationship and asks whether to disconnect before deleting the login. Declining removes only the login. JSON and noninteractive logout never prompt or disconnect implicitly; `--disconnect-daemon` is the explicit automation path, and `--force` applies to that daemon disconnection. If a requested disconnection fails, the login is preserved.
|
||||
|
||||
Every command resolves and normalizes its destination before Hub or daemon work. Origin precedence is an explicit command origin or `--hub`, then `PASEO_HUB_URL`, then the active stored login origin, then the hosted default `https://hub.paseo.sh`. The hosted default never overrides an active login. Credential precedence is `--api-key <secret>`, then `PASEO_HUB_API_KEY`, then a stored login for the exact resolved origin. A stored credential is never sent to a different origin. API keys passed through flags or the environment are not stored.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Work down this list.
|
||||
|
||||
1. **Is the event in the project's Activity?** If not, check **Connections → Known unrouted events** and use its reason to distinguish routing, source, filter, and configuration failures.
|
||||
2. **Is the event anywhere at all?** If not, the event never reached Hub. Check the provider's own delivery log: GitHub's App → Advanced → Recent Deliveries, or Slack's Event Subscriptions page. Then check that the app is subscribed to that event type.
|
||||
3. **Is your user in `from_users`?** This is the most common cause. GitHub uses your login; Slack and Discord use the user ID, not the display name.
|
||||
3. **Is your user in `from_users`?** This is the most common cause. GitHub uses your login; Slack and Discord use the user ID, not the display name. See [find your Slack IDs](/docs/hub/triggers/slack#find-your-slack-ids) and [find your Discord IDs](/docs/hub/triggers/discord#find-your-discord-ids).
|
||||
4. **Did the invocation match?** On GitHub, `contains` must appear in the comment body. On Slack and Discord the bot must be mentioned, and `pattern` or its legacy `contains` alias must prefix the text after the mention.
|
||||
5. **Is the configuration you think is active actually active?** The Configuration tab shows the active revision and the last sync attempt. A failed push leaves the old revision serving.
|
||||
6. **Is the daemon connected?** An offline daemon fails dispatch with `daemon_not_connected`.
|
||||
|
||||
@@ -23,6 +23,60 @@ A project configuration is one versioned bundle:
|
||||
|
||||
[single-repo-team-bot](https://github.com/getpaseo/hub/tree/main/examples/single-repo-team-bot) is a complete bundle in this shape: Discord, Slack, and GitHub workflows running a classifier and a worker on shared partials. Copy `.paseo/` into your repository and replace the placeholders its README lists.
|
||||
|
||||
## Generated starter bundle
|
||||
|
||||
`paseo hub init`, and the guided setup that interactive `paseo hub login` offers, write two files for the directory you run them in:
|
||||
|
||||
```yaml
|
||||
# .paseo/hub.yml
|
||||
environments:
|
||||
my-macbook:
|
||||
kind: daemon
|
||||
daemon: my-macbook
|
||||
cwd: /Users/you/code/your-repo
|
||||
agents:
|
||||
starter:
|
||||
provider: codex
|
||||
model: gpt-5
|
||||
mode: full-access
|
||||
```
|
||||
|
||||
The environment is named after the connected daemon and points at the directory setup ran in. `provider`, `model`, and `mode` are the runtime you chose from what that daemon reported, so the starter agent is a complete selection before its first run. `mode` is omitted for a provider that exposes none.
|
||||
|
||||
```yaml
|
||||
# .paseo/workflows/slack-help.yml
|
||||
name: slack-help
|
||||
on: slack.mention
|
||||
max_runtime: 2h
|
||||
filters:
|
||||
workspace: T01234567
|
||||
from_users:
|
||||
- U01234567
|
||||
steps:
|
||||
- id: work
|
||||
environment: my-macbook
|
||||
max_runtime: 90m
|
||||
idle_timeout: 10m
|
||||
agent: starter
|
||||
prompt:
|
||||
- text: |
|
||||
Answer with hub.reply, then complete this request and call hub.finish_execution when done.
|
||||
|
||||
<user-prompt>
|
||||
${{ paseo.prompt }}
|
||||
</user-prompt>
|
||||
allow_outputs:
|
||||
- type: slack.reply
|
||||
max: 1
|
||||
required: true
|
||||
```
|
||||
|
||||
`filters` carries the identity each provider matches on: the Slack team and member ID above, the Discord guild and user ID for a Discord starter, and `owner/name` plus your login for GitHub.
|
||||
|
||||
A Discord starter is `discord-help.yml` and carries `discord.reply`, the counterpart of the `slack.reply` above. A GitHub starter is `github-help.yml` and declares no reply output; GitHub has no reply capability, so a step that must comment needs a [`github` block](/docs/hub/github) instead.
|
||||
|
||||
The generated workflow allows one user in one workspace. Read [Hub security](/docs/hub/security) before widening it.
|
||||
|
||||
## Sources
|
||||
|
||||
A configuration comes from one source:
|
||||
|
||||
@@ -18,7 +18,11 @@ Log in from the machine first:
|
||||
paseo hub login https://hub.example.com
|
||||
```
|
||||
|
||||
The CLI prints a URL and a verification code and opens your browser. The approved login is stored under `PASEO_HOME`. Then enroll the daemon:
|
||||
The CLI prints a URL and a verification code and opens your browser. The approved login is stored under `PASEO_HOME`.
|
||||
|
||||
In an interactive terminal, login then offers to finish setup: whether to connect this daemon, and whether to initialize and deploy a starter workflow. Both default to yes. Declining the connection prints `paseo hub connect <origin>; then paseo hub init`, since connecting alone leaves the project without a workflow. Declining only the starter prints `paseo hub init`. `--json` or non-TTY login only logs in. [Quickstart](/docs/hub/quickstart) walks through the questions.
|
||||
|
||||
Enroll the daemon on its own when you declined, or when the machine is already logged in:
|
||||
|
||||
```sh
|
||||
paseo hub connect
|
||||
|
||||
@@ -28,18 +28,16 @@ Your daemons keep running agents where they always did. Hub decides when to ask
|
||||
|
||||
## What lives in your repository
|
||||
|
||||
`paseo hub init` creates a project resource file for environments and agents, plus a safe starter workflow:
|
||||
Guided setup creates a project resource file for environments and agents, plus one safe starter workflow:
|
||||
|
||||
```text
|
||||
.paseo/
|
||||
├── hub.yml
|
||||
└── workflows/
|
||||
├── slack-help.yml
|
||||
└── partials/
|
||||
└── answer.md
|
||||
└── slack-help.yml
|
||||
```
|
||||
|
||||
Deploy the bundle, mention the bot, and an agent starts on your machine. [Quickstart](/docs/hub/quickstart) runs the guided setup; [Workflows](/docs/hub/workflows) covers routing and provider-specific replies.
|
||||
Guided setup deploys the bundle, and mentioning the bot starts an agent on your machine. [Quickstart](/docs/hub/quickstart) runs it end to end; the [generated starter bundle](/docs/hub/configuration#generated-starter-bundle) shows what it wrote, and [Workflows](/docs/hub/workflows) covers routing, prompt partials, and provider-specific replies.
|
||||
|
||||
## Reading order
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ category: Hub
|
||||
|
||||
# Hub quickstart
|
||||
|
||||
Run Hub locally, connect it to Slack without a public server, and answer a mention with an agent on your machine.
|
||||
Run Hub on your machine, connect it to Slack without a public server, and answer a mention with an agent in your repository. Hub's browser setup hands off to your terminal, and guided setup writes and deploys the workflow for you.
|
||||
|
||||
You need [Paseo installed and running](/docs), Node.js, and a Slack workspace where you can create an app.
|
||||
|
||||
@@ -18,13 +18,13 @@ You need [Paseo installed and running](/docs), Node.js, and a Slack workspace wh
|
||||
npx @getpaseo/hub
|
||||
```
|
||||
|
||||
Open <http://localhost:3000>. Hub uses an embedded database by default, so this first run needs no database, environment variables, or Docker.
|
||||
Open the address it prints, normally <http://localhost:3000>, and create the operator account Hub asks for.
|
||||
|
||||
Create the operator account when Hub welcomes you.
|
||||
The first run needs no database, Docker, environment variables, or API keys. Hub creates an embedded database, your organization, and a **Default** project. You never create a project by hand.
|
||||
|
||||
## 2. Connect Slack
|
||||
|
||||
The next screen explains how to create the Slack app and gives you a manifest to paste into Slack. Keep **Socket Mode** selected. It connects out from Hub and does not need a public address or HTTPS.
|
||||
**Set up your apps** explains how to create the Slack app and gives you a manifest to paste into Slack. Keep **Socket Mode** selected. It connects out from Hub and needs no public address or HTTPS.
|
||||
|
||||
Paste the App-level token and Bot token back into Hub, then choose **Connect Slack**. Invite the bot to the channel where you will use it:
|
||||
|
||||
@@ -32,35 +32,63 @@ Paste the App-level token and Bot token back into Hub, then choose **Connect Sla
|
||||
/invite @Paseo
|
||||
```
|
||||
|
||||
You can skip GitHub and Discord for now. Their setup remains available under **Apps**.
|
||||
GitHub and Discord can wait. Their setup stays available under **Apps**.
|
||||
|
||||
## 3. Initialize the project
|
||||
## 3. Connect the machine your code is on
|
||||
|
||||
From the repository where the agent should work:
|
||||
**Connect a daemon** shows one command with this Hub's address already in it:
|
||||
|
||||
```sh
|
||||
paseo hub init
|
||||
paseo hub login http://localhost:3000
|
||||
```
|
||||
|
||||
Choose **Custom endpoint…** and enter `http://localhost:3000`, then choose Slack. The guided setup:
|
||||
Run it on the machine where your code lives, in the repository the agent should work in. Guided setup records that directory as the workflow's working directory.
|
||||
|
||||
- signs you in through the browser;
|
||||
- connects the local Paseo daemon;
|
||||
- uses the default project created during first-run setup;
|
||||
- selects the connected Slack workspace and asks for your Slack username;
|
||||
- writes `.paseo/hub.yml` and `.paseo/workflows/slack-help.yml`;
|
||||
- validates the generated bundle and offers to deploy it.
|
||||
Approve the login in the browser tab that opens. Leave the Hub tab open: it watches for the daemon and shows **Daemon connected** by itself. **Continue** and **Do this later** both land in the Default project.
|
||||
|
||||
Accept the default **Deploy now?** choice. The generated workflow accepts mentions only from the username you entered.
|
||||
## 4. Answer the setup questions
|
||||
|
||||
## 4. Mention the bot
|
||||
Your terminal confirms the login, then picks up where the browser left off. Most questions arrive with a default or a suggested answer; only your Slack member ID has to be typed.
|
||||
|
||||
Mention the bot in the channel:
|
||||
| Question | What it wants |
|
||||
| ----------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| Connect this daemon to this Hub? | Yes. This enrolls the machine you are on. |
|
||||
| Initialize and deploy a starter workflow? | Yes. |
|
||||
| Starter agent provider, model, and mode | What your daemon reports it can run. Suggested model and mode entries are its defaults. |
|
||||
| Your Slack member ID | `U01234567`, the only account allowed to trigger the bot. |
|
||||
|
||||
Setup lists the app connections ready for this workflow. Because you connected one Slack workspace in step 2, it selects that connection automatically instead of asking you to choose Slack. If several usable connections exist, setup asks for the **Trigger connection**. If none is ready, it sends you to **Hub → Apps** and stops before asking about the agent or writing files.
|
||||
|
||||
The agent provider list contains only runtimes the daemon can use; it does not suggest one arbitrarily. Suggested model and mode entries are defaults reported by the daemon. A provider that has modes but no default mode is still offered; setup asks you to pick the mode instead of guessing one.
|
||||
|
||||
[Find your Slack IDs](/docs/hub/triggers/slack#find-your-slack-ids) has the two clicks that copy your member ID. The Slack workspace comes from the app you connected in step 2, so setup does not ask for it.
|
||||
|
||||
Setup then validates the bundle, writes it, and deploys:
|
||||
|
||||
```text
|
||||
@Paseo explain what this project does
|
||||
.paseo/
|
||||
├── hub.yml
|
||||
└── workflows/
|
||||
└── slack-help.yml
|
||||
```
|
||||
|
||||
Hub starts the agent on your daemon and posts its reply in the Slack thread. Open the project's **Activity** tab if nothing runs.
|
||||
If `.paseo/` already exists, setup asks before replacing it. Declining the daemon connection prints `paseo hub connect <hub>; then paseo hub init` — both commands, because connecting alone does not create the workflow. Declining only the starter workflow prints `paseo hub init`.
|
||||
|
||||
Hub keeps its local state in your user data directory (normally `~/.local/share/paseo-hub`). [Self-hosting](/docs/hub/self-hosting) covers PostgreSQL, public URLs, environment-managed apps, Docker, and cloud deployment. [Configuration](/docs/hub/configuration) explains the generated files and manual deployment.
|
||||
## 5. Mention the bot
|
||||
|
||||
In the channel you invited the bot to:
|
||||
|
||||
```text
|
||||
@Paseo have a look
|
||||
```
|
||||
|
||||
Hub starts the agent on your daemon and posts its reply in the Slack thread. The terminal prints the project's Activity URL, where the run appears. If nothing runs, [Activity](/docs/hub/activity) tells a filtered mention from one that never matched a workflow.
|
||||
|
||||
## Next
|
||||
|
||||
- [How Hub works](/docs/hub/concepts) — how an event becomes a workflow run on your daemon.
|
||||
- [Generated starter bundle](/docs/hub/configuration#generated-starter-bundle) — the two files setup wrote, field by field.
|
||||
- [Workflows](/docs/hub/workflows) — routing, prompts, and provider replies.
|
||||
- [Hub security](/docs/hub/security) — read this before widening `from_users` or giving an agent GitHub authority.
|
||||
|
||||
Hub keeps its local state in your user data directory, normally `~/.local/share/paseo-hub`. [Self-hosting](/docs/hub/self-hosting) covers deployment and advanced configuration when you outgrow the local run.
|
||||
|
||||
@@ -34,8 +34,14 @@ steps:
|
||||
- { type: discord.reply, max: 1, required: true }
|
||||
```
|
||||
|
||||
Turn on Discord Developer Mode to copy IDs. `from_users` matches the author; `guild` and `channels` constrain where the mention arrived. `pattern` is a required prefix after the mention; `contains` is its legacy alias and has the same prefix behavior. All filters must pass.
|
||||
Discord filters use IDs, not server names, display names, or Hub connection slugs. `from_users` matches the author; `guild` and `channels` constrain where the mention arrived. `pattern` is a required prefix after the mention; `contains` is its legacy alias and has the same prefix behavior. All filters must pass.
|
||||
|
||||
The reply posts in the triggering thread or channel. `discord.reply` grants `hub.reply`, but does not rewrite the prompt. A Discord trigger grants no GitHub credential; add a [`github` block](/docs/hub/github) to the step that needs one.
|
||||
|
||||
Leading declared inputs follow the mention. Hub exposes the remaining text as `${{ paseo.prompt }}`. See [Workflows](/docs/hub/workflows).
|
||||
|
||||
## Find your Discord IDs
|
||||
|
||||
Turn on **Settings → Advanced → Developer Mode**, then right-click to **Copy Server ID** for `guild`, **Copy Channel ID** for `channels`, and **Copy User ID** for `from_users`. All three are numeric snowflakes; quote them so YAML keeps them as strings.
|
||||
|
||||
[Guided setup](/docs/hub/quickstart) fills `guild` from the Discord app you connected and asks you for your user ID.
|
||||
|
||||
@@ -34,7 +34,7 @@ steps:
|
||||
- { type: slack.reply, max: 1, required: true }
|
||||
```
|
||||
|
||||
Slack filters use IDs, not display names. `from_users` matches the author, `workspace` the team, and `channels` the channel. `pattern` is a required prefix after the mention; `contains` is its legacy alias and has the same prefix behavior. All filters must pass.
|
||||
Slack filters use IDs, not display names or Hub connection slugs. `from_users` matches the author, `workspace` the team, and `channels` the channel. `pattern` is a required prefix after the mention; `contains` is its legacy alias and has the same prefix behavior. All filters must pass.
|
||||
|
||||
The reply posts in the triggering thread. A root message gets a thread; a threaded message stays there. `slack.reply` grants `hub.reply`, but does not add reply instructions to the prompt.
|
||||
|
||||
@@ -45,3 +45,13 @@ Leading declared inputs follow the mention:
|
||||
```
|
||||
|
||||
Hub consumes consecutive declared headers and exposes the remainder as `${{ paseo.prompt }}`. See [Workflows](/docs/hub/workflows).
|
||||
|
||||
## Find your Slack IDs
|
||||
|
||||
| Filter | Where to copy it |
|
||||
| ------------ | ------------------------------------------------------------------------------------------- |
|
||||
| `workspace` | Open Slack in a browser. The team ID is the `T…` segment of the URL. |
|
||||
| `from_users` | Your avatar → **Profile** → **⋮** → **Copy member ID**. Member IDs start with `U`. |
|
||||
| `channels` | Channel name → **About**. The channel ID is at the bottom of the panel and starts with `C`. |
|
||||
|
||||
[Guided setup](/docs/hub/quickstart) fills `workspace` from the Slack app you connected and asks you for your member ID, so a generated starter already carries both.
|
||||
|
||||
Reference in New Issue
Block a user