* feat(website): serve paseo.sh in Simplified Chinese
Every page of the website now has a Simplified Chinese version under
/zh-CN: the interface, docs, blog posts, comparison pages, legal pages,
all changelog releases and the homepage mockup. English URLs are unchanged.
The URL alone decides the language. There is no browser-language redirect
and no stored preference, because either would have to redirect the
unprefixed English URLs that people share and search engines index.
Internal links carry the page's language instead, and hreflang alternates
point Chinese search results at /zh-CN.
Translated headings pin the English anchor with {#id}, so section links
work in both languages. content-translations.test.ts fails when a page
has no translation or a translation's headings drift from the English.
Changelog releases and plugin listings without a translation render
whole in English under a notice, so a release never waits on one.
Plugin manifests and the registry gain optional translations and
OVERVIEW.zh-CN.md fields; older clients and registries ignore them.
* feat(website): replace the native language select with an EN/ZH menu
The header showed an OS-native select whose popup did not match the site.
The trigger now shows the language abbreviated (EN, ZH) and opens a menu in
the app's dropdown style that names each language in itself, with its name
in the page language underneath. Rows are real links to the same page in
that language; arrows, Escape, outside presses and taps behave as a menu
button, and the menu keeps itself on screen when a narrow header pushes the
trigger toward an edge.
Also drops the stray space after the full-width comma in the Chinese
homepage subtitle.
* docs(website): translate main's new docs and 0.12.0 release notes
Main added Keep run workspaces to the schedules docs, rewrote plugin icons
around inline SVG, and promoted 0.12.0 with new entries. Bring the Chinese
pages and changelog in line so no section falls back to English.
* fix(server): leave plugin listing translations to the registry
The daemon rejected manifests whose translations the registry would refuse,
so a plugin main installs could fail to load here. Paseo never reads
translations; the registry validates them at publish. Docs now say which
checks are automated at publish and which are human review.
* docs(plugins): describe the registry's final overview translation discovery
* style(server): format manifest test
* test(app): measure sidebar rows one at a time
After a reload the developer error toast appears while expectVerticalOrder
measures every row at once. Each concurrent boundingBox runs the toast
locator handler, and only one of them resumes, so the poll timed out on
every attempt since #7424. Measuring sequentially keeps one action in flight.
* test(app): return sidebar row measuring to main
#7480 hides the developer toast instead of running a locator handler, so
measuring the rows concurrently no longer races it. Reverts 41ac23016.
* test(app): wait for the compact shell before opening compact Changes
The shell survives the breakpoint, so right after the resize the wide
Explorer could still be visible: the test skipped the Explorer toggle and
the tab then disappeared, or toggled at the wrong time. Wait for the
compact-shell marker, as the composer helpers do since #7424.
* docs(website): translate main's plugin file panel docs
* test(app): edit the code font size after the font family remount
A committed appearance change remounts the settings screen through
AppearanceStyleBoundary, and the new form starts from the stored size.
Filling the size before that remount lost the edit in CI.
* docs(website): translate main's client/ui import docs
Follows #7474: one /client/ui entry, StreamedText instead of useRevealedText,
SettingsGroup dropped from the settings table, and the new
'UI imports in v0.13' migration section.
* test(app): wait for the previous layout's file panel picker to leave
After a resize the old layout's picker animates out while the new one is
already mounted, so the Use button matched two elements and the strict
locator failed. Wait for the shell's layout and a single picker first.
6.2 KiB
title, description, nav
| title | description | nav |
|---|---|---|
| 自托管 Hub | 使用内嵌数据库在本地运行 Hub,或配合 PostgreSQL 部署。 | 自托管 |
自托管 Hub
最快的方式只需一条命令:
npx @getpaseo/hub
打开 http://localhost:3000。全新的 Hub 会创建内嵌数据库和认证密钥,然后引导你创建管理员账号,以及你需要的 GitHub、Slack 或 Discord 应用。
按照快速开始,通过 Socket Mode 连接 Slack,无需公开服务器即可运行第一个 workflow。
本地数据
如果没有设置 DATABASE_URL,Hub 会把内嵌的 PGlite 数据库及其生成的认证密钥保存在 $XDG_DATA_HOME/paseo-hub 下。如果 XDG_DATA_HOME 没有设置为绝对路径,Hub 会使用 ~/.local/share/paseo-hub。两者在重启后都会保留。
用以下方式显式指定其他位置:
PASEO_HUB_DATA_DIR=/path/to/paseo-hub-data npx @getpaseo/hub
内嵌模式下,每个数据目录只支持一个 Hub 进程,适用于个人或单进程的 Hub。升级或迁移之前,请备份整个数据目录。
公开地址
Hub 默认使用 http://localhost:3000。对于它的控制台、daemon、Slack Socket Mode 以及由 Hub 主动连接出去的 Provider,这已经足够。
GitHub 事件触发器使用 webhook,需要一个公开的 HTTPS 地址。没有 webhook 时,仓库访问仍然可以工作。Slack 可选的 Webhooks 传输方式也需要公开 HTTPS;Socket Mode 则不需要。
当 Hub 有一个稳定的公开地址时,请在启动前设置它:
PASEO_HUB_APP_URL=https://hub.example.com npx @getpaseo/hub
修改公开地址后,需要更新 Provider 应用中的回调和 webhook 设置。Apps 页面会为 Hub 当前使用的地址生成这些 URL。
PostgreSQL
设置 DATABASE_URL,即可使用 PostgreSQL 代替内嵌数据库:
DATABASE_URL=postgres://paseo:password@localhost:5432/paseo_hub \
npx @getpaseo/hub
对于持久的服务器部署、多个 Hub 进程,或已有的数据库备份和运维体系,请使用 PostgreSQL。迁移会在启动时自动运行。迁移失败时,Hub 不会开始监听。
数据库同样保存 Hub 生成的认证密钥。只有当部署必须从平台的密钥存储中提供该密钥时,才设置 PASEO_HUB_AUTH_SECRET。设置此覆盖期间,Hub 会使用它,但不会替换已保存的密钥。更改实际生效的密钥会让所有人退出控制台;已签发的执行凭据在其执行结束前仍然有效。
应用配置
管理员在 Apps 下配置 GitHub、Slack 和 Discord。Hub 会先验证凭据,再保存到数据库中,并启动与通过环境变量配置的部署相同的 Provider 运行时。
对于在 Hub 之外管理密钥的部署,环境变量仍然可用。完整的环境变量配置优先于已保存的应用,并在控制台中显示为 Managed by environment。
# GitHub
GITHUB_APP_SLUG=
GITHUB_APP_ID=
GITHUB_APP_CLIENT_ID=
GITHUB_APP_CLIENT_SECRET=
GITHUB_APP_PRIVATE_KEY= # or GITHUB_APP_PRIVATE_KEY_PATH
GITHUB_WEBHOOK_SECRET=
# Slack Socket Mode
SLACK_TRANSPORT=socket
SLACK_APP_ID=
SLACK_APP_TOKEN=
# Slack Webhooks instead of Socket Mode
SLACK_TRANSPORT=webhook
SLACK_APP_ID=
SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
SLACK_SIGNING_SECRET=
# Discord
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_BOT_TOKEN=
各 Provider 的行为和连接步骤见 GitHub、Slack 和 Discord。
通过环境变量初始化
对于全新的数据库,默认通过浏览器完成设置。无人值守的部署可以改用环境变量创建第一个管理员:
PASEO_BOOTSTRAP_ORGANIZATION=My organization
PASEO_BOOTSTRAP_OWNER_EMAIL=me@example.com
PASEO_BOOTSTRAP_OWNER_PASSWORD=replace-with-a-temporary-password
密码至少需要 12 个字符。登录一次,在控制台中替换密码,然后移除 PASEO_BOOTSTRAP_OWNER_PASSWORD。Hub 会保留该账号和组织。
Docker Compose
仓库中包含一个由 Hub 和 PostgreSQL 组成的 Compose 栈:
git clone https://github.com/getpaseo/hub.git
cd hub
cp .env.example .env
docker compose up -d
打开 http://localhost:3000 并完成浏览器设置。对于公开部署,请在启动栈之前,在 .env 中设置 PASEO_HUB_APP_URL 以及任何反向代理设置。
该栈在端口 3000 上发布 Hub,并把 PostgreSQL 数据保存在一个命名卷中。Hub 镜像是 ghcr.io/getpaseo/hub:latest。
使用 Caddy 提供 HTTPS
Compose 在端口 3000 上提供纯 HTTP。在同一台主机上运行 Caddy 来终止 TLS:
hub.example.com {
reverse_proxy 127.0.0.1:3000
}
把 hub.example.com 指向该主机,并开放 80 和 443 端口。Caddy 会自动获取并续期证书。
然后在 .env 中设置:
PASEO_HUB_APP_URL=https://hub.example.com
PASEO_HUB_TRUSTED_CLIENT_IP_HEADER=x-forwarded-for
如果不想让端口 3000 暴露在公网接口上,请把 compose.yml 中 hub 的端口改为 "127.0.0.1:3000:3000"。
Fly
克隆仓库,并用你自己控制的名称创建应用和数据库:
git clone https://github.com/getpaseo/hub.git
cd hub
fly apps create your-hub
fly postgres create --name your-hub-db
fly postgres attach your-hub-db -a your-hub
部署 Dockerfile,并为 Hub 提供公开地址:
fly deploy -a your-hub \
-e PASEO_HUB_APP_URL=https://your-hub.fly.dev
打开该地址并完成浏览器设置,或者在部署前设置初始化环境变量。
请保持一台机器持续运行。Hub 维持着 Slack Socket Mode 和 Discord gateway 连接,并把事件派发给 daemon,因此机器停止期间会错过事件。
升级
拉取新的镜像或源码并部署。迁移只能向前。请先备份内嵌数据目录或 PostgreSQL 数据库;其中包含账号、应用凭据、配置版本、连接和执行历史。