From 5aee41952e15bb40c307fce3244740751fe95f00 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sun, 4 Oct 2026 17:12:11 +0100 Subject: [PATCH] feat(website): browse plugins by nine community categories (#6068) Organize community plugins by what Paseo does and verify the category layout with a static registry fixture. --- packages/website/e2e/plugins.spec.ts | 35 +- packages/website/e2e/registry-server.mjs | 14 + packages/website/e2e/registry.fixture.json | 631 ++++++++++++++++++ packages/website/playwright.config.ts | 19 +- packages/website/src/plugins/categories.ts | 62 +- packages/website/src/plugins/registry.test.ts | 2 +- 6 files changed, 722 insertions(+), 41 deletions(-) create mode 100644 packages/website/e2e/registry-server.mjs create mode 100644 packages/website/e2e/registry.fixture.json diff --git a/packages/website/e2e/plugins.spec.ts b/packages/website/e2e/plugins.spec.ts index bd8f70f004..e3b2eeb115 100644 --- a/packages/website/e2e/plugins.spec.ts +++ b/packages/website/e2e/plugins.spec.ts @@ -1,4 +1,5 @@ import { expect, test, type Page } from "playwright/test"; +import { CATEGORIES } from "../src/plugins/categories"; async function openPlugins(page: Page) { // Wait for hydration so typing reaches React rather than the server-rendered input. @@ -27,7 +28,7 @@ test("browses from the directory into a category, a plugin, and its author", asy const themes = page.getByRole("region", { name: "Themes" }); await expect(themes.getByRole("link", { name: /Dracula/ })).toBeVisible(); - await browseCategory(page, "Git & code review"); + await browseCategory(page, "Git"); await expect(page).toHaveURL(/category=/); await expect(page.getByRole("heading", { level: 2 })).toHaveCount(1); await expect(page.getByRole("region", { name: "Themes" })).toHaveCount(0); @@ -48,7 +49,7 @@ test("browses from the directory into a category, a plugin, and its author", asy const breadcrumbs = page.getByRole("navigation", { name: "Breadcrumb" }); await expect(breadcrumbs).toContainText("Plugins"); - await expect(breadcrumbs).toContainText("Git & code review"); + await expect(breadcrumbs).toContainText("Git"); await expect(breadcrumbs).toContainText("Fresh Worktrees"); await openAuthor(page, "Omer Cohen"); @@ -86,10 +87,7 @@ async function copyInstallCommand(page: Page) { } async function browseCategory(page: Page, category: string) { - await page - .getByRole("region", { name: category }) - .getByRole("link", { name: /^View all/ }) - .click(); + await page.getByRole("link", { name: category, exact: true }).click(); } async function openPlugin(page: Page, name: RegExp) { await page.getByRole("link", { name }).first().click(); @@ -214,3 +212,28 @@ test("keeps the directory unlinked until the coordinated announcement", async ({ expect(response?.status()).toBe(200); await expect(page.getByRole("heading", { level: 1, name: "Plugins" })).toBeVisible(); }); + +// External deployments own their registry contents; these assertions use the local fixture. +test.describe("registry category layout", () => { + test.skip(Boolean(process.env.WEBSITE_TEST_URL), "Requires the local registry fixture"); + + test("orders populated categories and hides the empty Extras category", async ({ page }) => { + await openPlugins(page); + await expect(page.getByRole("heading", { level: 2 })).toHaveText([ + "Daemon management", + "Themes", + "Providers", + "Orchestration", + "Git", + "Workspaces", + "Sidebar", + "Utils", + ]); + await expect(page.getByRole("region", { name: "Extras", exact: true })).toHaveCount(0); + for (const category of CATEGORIES.filter((entry) => entry.slug !== "extras")) { + await expect(page.getByRole("region", { name: category.label, exact: true })).toContainText( + category.description, + ); + } + }); +}); diff --git a/packages/website/e2e/registry-server.mjs b/packages/website/e2e/registry-server.mjs new file mode 100644 index 0000000000..211fee9f38 --- /dev/null +++ b/packages/website/e2e/registry-server.mjs @@ -0,0 +1,14 @@ +import { createServer } from "node:http"; +import registry from "./registry.fixture.json" with { type: "json" }; + +// Serve the published registry contract so SSR and browser navigation use the same data. +createServer((request, response) => { + response.setHeader("Content-Type", "application/json"); + if (request.url === "/index.json") { + response.end(JSON.stringify(registry)); + return; + } + const plugin = registry.plugins.find((entry) => request.url === `/plugins/${entry.id}.json`); + response.statusCode = plugin ? 200 : 404; + response.end(JSON.stringify(plugin ?? { error: "Plugin not found" })); +}).listen(8188, "127.0.0.1"); diff --git a/packages/website/e2e/registry.fixture.json b/packages/website/e2e/registry.fixture.json new file mode 100644 index 0000000000..6b75599d3d --- /dev/null +++ b/packages/website/e2e/registry.fixture.json @@ -0,0 +1,631 @@ +{ + "schemaVersion": 1, + "registry": { + "name": "Paseo plugins", + "url": "https://plugins.paseo.sh" + }, + "generatedAt": "2026-10-04T15:55:47.882Z", + "categories": [ + { + "slug": "daemon-management", + "label": "Daemon management", + "description": "Manage hosts, daemon jobs, resources, approvals, and MCP servers." + }, + { + "slug": "themes", + "label": "Themes", + "description": "Change the app color scheme." + }, + { + "slug": "providers", + "label": "Providers", + "description": "Connect coding agents, ACP servers, and model routers, with account and quota fallback." + }, + { + "slug": "orchestration", + "label": "Orchestration", + "description": "Coordinate agents, delegate work, and send messages across hosts." + }, + { + "slug": "git", + "label": "Git", + "description": "Work with branches, worktrees, pull requests, stacks, diffs, and reviews." + }, + { + "slug": "workspaces", + "label": "Workspaces", + "description": "Add workspace panels and tabs for boards, browsers, documents, and terminals." + }, + { + "slug": "sidebar", + "label": "Sidebar", + "description": "Add sidebar items and panels for usage, notifications, pricing, and links." + }, + { + "slug": "extras", + "label": "Extras", + "description": "Add presence, pets, puzzles, wellbeing reminders, and demos." + }, + { + "slug": "utils", + "label": "Utils", + "description": "Extend the composer and timeline with commands, prompts, skills, and small helpers." + } + ], + "plugins": [ + { + "id": "alhassanaraouf/base2tone", + "name": "Base2Tone", + "description": "Base2Tone theme for Paseo, ported from the Obsidian theme deathau/Base2Tone-For-Obsidian.md.", + "artifact": { + "kind": "npm", + "package": "@alhassanaraouf/paseo-base2tone-theme", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@alhassanaraouf/paseo-base2tone-theme/-/paseo-base2tone-theme-0.1.2.tgz", + "integrity": "sha512-baP+qh3MlPgwACvt72XjrULjbDHARofzHfxyGGVVl22iw6qVnMzyfBJXi4exgtplvD/yPqf/XlsqD8wTqHB+lg==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/alhassanaraouf/paseo-themes/tree/HEAD/packages/paseo-base2tone-theme" + }, + "categories": ["themes"], + "author": { + "npm": "alhassanaraouf", + "name": "alhassanaraouf", + "github": "alhassanaraouf" + }, + "screenshots": [ + "https://raw.githubusercontent.com/alhassanaraouf/paseo-themes/main/packages/paseo-base2tone-theme/preview.png" + ], + "submittedAt": "2026-09-24T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-24T17:12:05.467Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Base2Tone\n\n## Behavior\n\nBase2Tone theme for Paseo, ported from the Obsidian theme deathau/Base2Tone-For-Obsidian.md." + }, + { + "id": "dorasto/sayr", + "name": "Sayr", + "description": "A paseo plugin for viewing and managing your Sayr tasks", + "artifact": { + "kind": "npm", + "package": "@sayrio/paseo-plugin", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@sayrio/paseo-plugin/-/paseo-plugin-0.2.0.tgz", + "integrity": "sha512-LPmVkEPWl8Km6US4zQAzhqSbGm7lBDwCjgNoysOhCsDiRy0jbtDKYRg1XVgwwUkoEwhF1EdZHCPwIuT8IizyWQ==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/dorasto/sayr/tree/HEAD/packages/paseo-plugin", + "commit": "e70919b89df3cf9e95c18242939193a79c7593b1" + }, + "categories": ["workspaces"], + "author": { + "npm": "trent-001", + "name": "Tom Lundy", + "github": "dorasto" + }, + "screenshots": [ + "https://raw.githubusercontent.com/dorasto/sayr/main/packages/paseo-plugin/assets/sayr-plguin-1.png", + "https://raw.githubusercontent.com/dorasto/sayr/main/packages/paseo-plugin/assets/paseo-plugin-2.png" + ], + "submittedAt": "2026-09-22T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-22T10:39:28.935Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Sayr\n\n## Behavior\n\nA paseo plugin for viewing and managing your Sayr tasks" + }, + { + "id": "gpambrozio/github-board", + "name": "GitHub Board", + "description": "Paseo plugin: a GitHub sidebar board of your issues, draft and open pull requests, and discussions", + "artifact": { + "kind": "npm", + "package": "@gpambrozio/paseo-github-board", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@gpambrozio/paseo-github-board/-/paseo-github-board-0.10.0.tgz", + "integrity": "sha512-G6LxSsbt4Kt36yWEB2rXUxOwNLFsA4DbF20ViroVqaicMPjaw5H4JUWXjzEZAxWJT+0DlH12/TtqN4I0sNoQtg==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/gpambrozio/paseo-plugins/tree/HEAD/github-board", + "commit": "530a66c592e20915169b5e67a35de8793f71ec60" + }, + "categories": ["git"], + "author": { + "npm": "gpambrozio", + "name": "gpambrozio", + "github": "gpambrozio" + }, + "screenshots": [ + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/github-board/docs/screenshot.png", + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/github-board/docs/detail-panel.png" + ], + "submittedAt": "2026-09-19T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-01T17:46:20.500Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# GitHub Board\n\n## Behavior\n\nPaseo plugin: a GitHub sidebar board of your issues, draft and open pull requests, and discussions" + }, + { + "id": "gpambrozio/herald", + "name": "Herald", + "description": "Paseo plugin: speaks one sentence when an agent needs you, and lists everything waiting in a sidebar panel", + "artifact": { + "kind": "npm", + "package": "@gpambrozio/paseo-herald", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@gpambrozio/paseo-herald/-/paseo-herald-0.5.1.tgz", + "integrity": "sha512-rXdlaxgRlYP3nmZrvbG29sQeluz5JC7TPuJDgKzyh9itDH1AvZYGjLgGp9XZGKxdBBhaGxgGAFhDh+VTL8h9dw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/gpambrozio/paseo-plugins/tree/HEAD/herald", + "commit": "b658d0ab58735959e46d12660ae179c002cdadda" + }, + "categories": ["sidebar"], + "author": { + "npm": "gpambrozio", + "name": "gpambrozio", + "github": "gpambrozio" + }, + "screenshots": [ + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/herald/docs/panel.png", + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/herald/docs/timeline-card.png" + ], + "submittedAt": "2026-09-19T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-27T19:03:31.943Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Herald\n\n## Behavior\n\nPaseo plugin: speaks one sentence when an agent needs you, and lists everything waiting in a sidebar panel" + }, + { + "id": "gpambrozio/launchd-jobs", + "name": "launchd Jobs", + "description": "Paseo plugin: schedule shell commands on your Mac through launchd, from a sidebar panel", + "artifact": { + "kind": "npm", + "package": "@gpambrozio/paseo-launchd-jobs", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@gpambrozio/paseo-launchd-jobs/-/paseo-launchd-jobs-0.5.0.tgz", + "integrity": "sha512-H6CQnalMdyQjW9ta9ZT40qEPJsREgNFSEAH8EC4sJXdz2Hz9tIsInSUmm2bDcgfY3D3HFffUrwf1mmeevi/wUA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/gpambrozio/paseo-plugins/tree/HEAD/launchd-jobs", + "commit": "08e75003b287208ef804f3d31b2fda2597f69dce" + }, + "categories": ["daemon-management"], + "author": { + "npm": "gpambrozio", + "name": "gpambrozio", + "github": "gpambrozio" + }, + "screenshots": [ + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/launchd-jobs/docs/screenshot.png" + ], + "submittedAt": "2026-09-19T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-22T17:56:41.061Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# launchd Jobs\n\n## Behavior\n\nPaseo plugin: schedule shell commands on your Mac through launchd, from a sidebar panel" + }, + { + "id": "gpambrozio/model-pricing", + "name": "Model Pricing", + "description": "Paseo plugin: a sidebar table of what every model costs, across Anthropic, OpenAI, Fireworks AI, Ollama Cloud and OpenRouter", + "artifact": { + "kind": "npm", + "package": "@gpambrozio/paseo-model-pricing", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@gpambrozio/paseo-model-pricing/-/paseo-model-pricing-0.3.0.tgz", + "integrity": "sha512-jLfC6iCLOwNACiili8nw3/qmBymoj6YHitMeGCa2RggiMdUhT6n+INRsSjoTs2kNzeYMftMfQ3MZJXeLLF1opA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/gpambrozio/paseo-plugins/tree/HEAD/model-pricing", + "commit": "08e75003b287208ef804f3d31b2fda2597f69dce" + }, + "categories": ["sidebar"], + "author": { + "npm": "gpambrozio", + "name": "gpambrozio", + "github": "gpambrozio" + }, + "screenshots": [ + "https://raw.githubusercontent.com/gpambrozio/paseo-plugins/main/model-pricing/docs/screenshot.png" + ], + "submittedAt": "2026-09-19T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-22T18:03:14.979Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Model Pricing\n\n## Behavior\n\nPaseo plugin: a sidebar table of what every model costs, across Anthropic, OpenAI, Fireworks AI, Ollama Cloud and OpenRouter" + }, + { + "id": "gpambrozio/skills", + "name": "Skills", + "description": "Paseo plugin: lists the skills an agent can use, shows where each comes from, renders its SKILL.md, and invokes it", + "artifact": { + "kind": "npm", + "package": "@gpambrozio/paseo-skills", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@gpambrozio/paseo-skills/-/paseo-skills-0.4.0.tgz", + "integrity": "sha512-zMgP2U/vrRsLkKhoQICkN52+YoDy2WkkYymEDmruduKxf4Dq99Ct8Pk3xqJyAzijq2oprMFYLbj/wT6XepBLeA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/gpambrozio/paseo-plugins/tree/HEAD/skills", + "commit": "d04187ee60ca3702ca5843803567600427102d99" + }, + "categories": ["utils"], + "author": { + "npm": "gpambrozio", + "name": "gpambrozio", + "github": "gpambrozio" + }, + "screenshots": [], + "submittedAt": "2026-09-19T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-01T22:25:58.192Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Skills\n\n## Behavior\n\nPaseo plugin: lists the skills an agent can use, shows where each comes from, renders its SKILL.md, and invokes it" + }, + { + "id": "hungcuong9125/prompt-kit", + "name": "PromptKit", + "description": "PromptKit - rewrite and transform prompts directly from the Paseo composer.", + "artifact": { + "kind": "npm", + "package": "paseo-prompt-kit", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/paseo-prompt-kit/-/paseo-prompt-kit-0.6.0.tgz", + "integrity": "sha512-eiagOY1OokDx2iihfe3Vjh2dgKKP6IsBKbJYbfhM+TXw3aU7duV/rs/TUnBSeeWAk0cEsVg2Jd+EkeaPM8IJdA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/hungcuong9125/paseo-prompt-kit" + }, + "categories": ["utils"], + "author": { + "npm": "hungcuong9125", + "name": "hungcuong9125", + "github": "hungcuong9125" + }, + "screenshots": [ + "https://raw.githubusercontent.com/hungcuong9125/paseo-prompt-kit/main/docs/images/settings-provider-cli.png", + "https://raw.githubusercontent.com/hungcuong9125/paseo-prompt-kit/main/docs/images/settings-direct-api.png" + ], + "submittedAt": "2026-09-22T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-30T02:57:56.473Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# PromptKit\n\n## Behavior\n\nPromptKit - rewrite and transform prompts directly from the Paseo composer." + }, + { + "id": "omercnet/agent-monitor", + "name": "Agent Monitor", + "description": "A Paseo plugin that provides a host-wide agent triage roster.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-agent-monitor", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-agent-monitor/-/paseo-agent-monitor-1.2.0.tgz", + "integrity": "sha512-dY7/3f49sPMVwb+Wr7iUsw4jCoQWRX2UF9Li+uU8yJdN0cj4BvTsz4GDiR3OsKk8zJ1/o01DSRi1e4uDRS3TmA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/agent-monitor", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["orchestration"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/agent-monitor/docs/images/agent-monitor-roster.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/agent-monitor/docs/images/agent-monitor-settings.png" + ], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:36:35.639Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Agent Monitor\n\n## Behavior\n\nA Paseo plugin that provides a host-wide agent triage roster." + }, + { + "id": "omercnet/beads", + "name": "Beads", + "description": "A dependency-aware Beads work queue for each Paseo workspace.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-beads", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-beads/-/paseo-beads-1.2.0.tgz", + "integrity": "sha512-UkI1SNP73RUrW0ap4qOx2Jv1GCxkrw4HIMrWOFCS3FDoPg2jw06DqHC8Jf34psaFglxXKWLAOkfL2wEZJhlUFw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/paseo-beads", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["workspaces"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-beads/docs/images/paseo-beads-wide.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-beads/docs/images/paseo-beads-compact.png" + ], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:37:29.149Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Beads\n\n## Behavior\n\nA dependency-aware Beads work queue for each Paseo workspace." + }, + { + "id": "omercnet/dracula", + "name": "Dracula", + "description": "Dracula Classic and Alucard Classic themes for Paseo.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-dracula", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-dracula/-/paseo-dracula-1.2.0.tgz", + "integrity": "sha512-I3yUiFIvaIe3jdvuQ1tZyngsfgukaUJwEQza2XYkEaB8yIA0pplZehqJLvqqmA403cjNXdVtsdW7umPtmnycqw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/paseo-dracula", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["themes"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-dracula/screenshot.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-dracula/screenshot-alucard.png" + ], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:37:18.185Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Dracula\n\n## Behavior\n\nDracula Classic and Alucard Classic themes for Paseo." + }, + { + "id": "omercnet/fresh-worktrees", + "name": "Fresh Worktrees", + "description": "Fast-forwards clean local base branches before Paseo creates branch-off worktrees", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-fresh-worktrees", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-fresh-worktrees/-/paseo-fresh-worktrees-2.2.0.tgz", + "integrity": "sha512-WRarzdfTbrZ36JfzmvX9HfnIYh6Pp+GV9TkoeVwM7I6f1MAEZ4gzPEmT51lWuUyMGvwTs2HFB7LthCa+VYs7IA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/fresh-worktrees", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["git"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/fresh-worktrees/docs/images/fresh-worktrees-behind.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/fresh-worktrees/docs/images/fresh-worktrees-settings.png" + ], + "submittedAt": "2026-09-18T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:36:06.720Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Fresh Worktrees\n\n## Behavior\n\nFast-forwards clean local base branches before Paseo creates branch-off worktrees" + }, + { + "id": "omercnet/omp", + "name": "OMP", + "description": "Paseo integration for OMP, including its direct provider and workspace tooling.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-omp", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-omp/-/paseo-omp-1.2.0.tgz", + "integrity": "sha512-ueZede5D34hoNrdF4y6DBaomErA+hHcv+bcz0Sd6eArQKqF8L6ecKXdBe2tEZd3Ev8uQwxMHuiDQhMBx3q6gOw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/paseo-omp", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["providers"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-omp/docs/images/plugin-manager.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-omp/docs/images/workspace-settings.png" + ], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:36:36.267Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# OMP\n\n## Behavior\n\nPaseo integration for OMP, including its direct provider and workspace tooling." + }, + { + "id": "omercnet/pr-radar", + "name": "PR Radar", + "description": "A viewer-aware delivery queue for pull requests linked to Paseo workspaces.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-pr-radar", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-pr-radar/-/paseo-pr-radar-1.2.0.tgz", + "integrity": "sha512-sk+zuzTGZ5Vmri2toic3z3uChm4d6kEShSr/UjkqfOTeILrsZVDHUc+XKX/CtZIQazT/vWvbgZ115+KUiAonCw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/pr-radar", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["git"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:37:04.327Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# PR Radar\n\n## Behavior\n\nA viewer-aware delivery queue for pull requests linked to Paseo workspaces." + }, + { + "id": "omercnet/shared-browser", + "name": "Shared Browser", + "description": "One real Chromium session per Paseo workspace, shared live across every connected client.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-shared-browser", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-shared-browser/-/paseo-shared-browser-1.2.0.tgz", + "integrity": "sha512-ddvtkBSzHLFzyTRZFixO1y+QXOKW0of8Uo3PSkETRhW5xhd9ep0jqsJJF9JSfWLt1ouvVa5K8zFXic/EBzQ8lw==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/paseo-shared-browser", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["workspaces"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [ + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-shared-browser/docs/images/shared-browser-wide.png", + "https://raw.githubusercontent.com/omercnet/paseo-plugins/main/paseo-shared-browser/docs/images/shared-browser-compact.png" + ], + "submittedAt": "2026-09-18T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:38:48.289Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Shared Browser\n\n## Behavior\n\nOne real Chromium session per Paseo workspace, shared live across every connected client." + }, + { + "id": "omercnet/tell-agent", + "name": "Tell Agent", + "description": "Send messages to agents in other workspaces on the same Paseo host.", + "artifact": { + "kind": "npm", + "package": "@omercnet/paseo-tell-agent", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@omercnet/paseo-tell-agent/-/paseo-tell-agent-1.2.0.tgz", + "integrity": "sha512-4XqL1RK1x3TQLoRRKTkZfDxytJbUCEnu2em5pbPDpsGQ5Gv6VN1h07mBci9iW8s2FbNINohNcIBdUaAMTXdOHA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/omercnet/paseo-plugins/tree/HEAD/tell-agent", + "commit": "d7b3e654f364b5be72edf6fd1d914a3750b53082" + }, + "categories": ["orchestration"], + "author": { + "npm": "omercnet", + "name": "Omer Cohen", + "github": "omercnet" + }, + "screenshots": [], + "submittedAt": "2026-09-17T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-10-03T09:36:15.719Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Tell Agent\n\n## Behavior\n\nSend messages to agents in other workspaces on the same Paseo host." + }, + { + "id": "tomgrin10/defer", + "name": "Defer", + "description": "Defer messages to Paseo coding agents until a chosen time or usage-window reset.", + "artifact": { + "kind": "npm", + "package": "paseo-defer", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/paseo-defer/-/paseo-defer-2.1.9.tgz", + "integrity": "sha512-xBBf4TUC8zkTh9WMzQRRDt0alRAYPRCmUdBnBI1ZEkatUFC4i9MxFHgaTY939xij99dASM/261IWqctcKsQppQ==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/tomgrin10/paseo-defer" + }, + "categories": ["utils"], + "author": { + "npm": "tomgrin10", + "name": "Tom Gringauz", + "github": "tomgrin10" + }, + "screenshots": [ + "https://raw.githubusercontent.com/tomgrin10/paseo-defer/main/docs/defer-popover.png" + ], + "submittedAt": "2026-09-22T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-27T09:59:16.553Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Defer\n\n## Behavior\n\nDefer messages to Paseo coding agents until a chosen time or usage-window reset." + }, + { + "id": "tomgrin10/graphite", + "name": "Graphite", + "description": "Workspace-native Graphite stack status and PR action radar for Paseo.", + "artifact": { + "kind": "npm", + "package": "paseo-graphite", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/paseo-graphite/-/paseo-graphite-0.2.4.tgz", + "integrity": "sha512-aAFvh+118c5mmSQ3sTsDKO8Is7g1ZU8m2+0fisr8nFrgPMu0m2mokPJnM/LaIqQc3Zaaak1chB6M6k0dWOPeIA==" + }, + "license": "MIT", + "repository": { + "url": "https://github.com/tomgrin10/paseo-graphite" + }, + "categories": ["git"], + "author": { + "npm": "tomgrin10", + "name": "Tom Gringauz", + "github": "tomgrin10" + }, + "screenshots": [], + "submittedAt": "2026-09-22T00:00:00.000Z", + "reviewedAt": "2026-10-03T00:00:00.000Z", + "publishedAt": "2026-09-23T10:36:50.112Z", + "updatedAt": "2026-10-03T00:00:00.000Z", + "installs": 0, + "readme": "# Graphite\n\n## Behavior\n\nWorkspace-native Graphite stack status and PR action radar for Paseo." + } + ] +} diff --git a/packages/website/playwright.config.ts b/packages/website/playwright.config.ts index 28566f30b4..a80b84abd8 100644 --- a/packages/website/playwright.config.ts +++ b/packages/website/playwright.config.ts @@ -12,9 +12,18 @@ export default defineConfig({ ], webServer: process.env.WEBSITE_TEST_URL ? undefined - : { - command: "npm run build && npm run preview -- --host 127.0.0.1 --port 8187 --strictPort", - url: baseURL, - reuseExistingServer: !process.env.CI, - }, + : [ + { + command: "node e2e/registry-server.mjs", + url: "http://127.0.0.1:8188/index.json", + }, + { + command: "npm run build && npm run preview -- --host 127.0.0.1 --port 8187 --strictPort", + url: baseURL, + env: { + CLOUDFLARE_INCLUDE_PROCESS_ENV: "true", + PLUGINS_REGISTRY_URL: "http://127.0.0.1:8188", + }, + }, + ], }); diff --git a/packages/website/src/plugins/categories.ts b/packages/website/src/plugins/categories.ts index 498bea280e..96fc836bf4 100644 --- a/packages/website/src/plugins/categories.ts +++ b/packages/website/src/plugins/categories.ts @@ -1,47 +1,51 @@ export const CATEGORIES = [ - { slug: "themes", label: "Themes", description: "Change how Paseo looks." }, { - slug: "agents-and-providers", - label: "Agents & providers", - description: "Run more coding agents through Paseo.", + slug: "daemon-management", + label: "Daemon management", + description: "Manage hosts, daemon jobs, resources, approvals, and MCP servers.", }, { - slug: "monitoring", - label: "Monitoring & orchestration", - description: "See every agent at once and steer work across workspaces.", + slug: "themes", + label: "Themes", + description: "Change the app color scheme.", }, { - slug: "timeline-and-composer", - label: "Timeline & composer", - description: "Change what a conversation shows and how you write to agents.", + slug: "providers", + label: "Providers", + description: + "Connect coding agents, ACP servers, and model routers, with account and quota fallback.", }, { - slug: "workspace-panels", - label: "Workspace panels", - description: "Tools that open as tabs next to your agents.", + slug: "orchestration", + label: "Orchestration", + description: "Coordinate agents, delegate work, and send messages across hosts.", }, { - slug: "git-and-code-review", - label: "Git & code review", - description: "Branches, worktrees, and pull requests.", + slug: "git", + label: "Git", + description: "Work with branches, worktrees, pull requests, stacks, diffs, and reviews.", }, { - slug: "automation", - label: "Automation & scheduling", - description: "Run things later, on a schedule, or when an agent goes idle.", - }, - { slug: "notifications", label: "Notifications", description: "Know when an agent needs you." }, - { - slug: "usage-and-pricing", - label: "Usage & pricing", - description: "What models cost and how much you have used.", + slug: "workspaces", + label: "Workspaces", + description: "Add workspace panels and tabs for boards, browsers, documents, and terminals.", }, { - slug: "integrations", - label: "Integrations", - description: "Issues, tasks, and tools from other services inside Paseo.", + slug: "sidebar", + label: "Sidebar", + description: "Add sidebar items and panels for usage, notifications, pricing, and links.", + }, + { + slug: "extras", + label: "Extras", + description: "Add presence, pets, puzzles, wellbeing reminders, and demos.", + }, + { + slug: "utils", + label: "Utils", + description: + "Extend the composer and timeline with commands, prompts, skills, and small helpers.", }, - { slug: "utilities", label: "Utilities", description: "Small helpers for everyday work." }, ] as const; export type CategorySlug = (typeof CATEGORIES)[number]["slug"]; diff --git a/packages/website/src/plugins/registry.test.ts b/packages/website/src/plugins/registry.test.ts index 20f5cfda6e..ed5963fb0a 100644 --- a/packages/website/src/plugins/registry.test.ts +++ b/packages/website/src/plugins/registry.test.ts @@ -63,7 +63,7 @@ describe("plugin registry", () => { "acme/example", ]); expect(queryPlugins([plugin, popular], { q: "acme/example", sort: "new" })).toEqual([plugin]); - expect(queryPlugins([plugin], { category: "utilities", sort: "popular" })).toEqual([]); + expect(queryPlugins([plugin], { category: "utils", sort: "popular" })).toEqual([]); }); it("offers a registry command and an exact explicit command", () => { expect(installCommand(plugin)).toBe("paseo plugin install acme/example");