From a1ac402154842b9e16d686e5bd63c091f98ca1fe Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 7 May 2026 22:52:26 +0700 Subject: [PATCH] docs(website): add provider pages and refresh docs --- .../website/src/components/agent-route.tsx | 13 + .../website/src/components/landing-page.tsx | 18 +- .../website/src/components/site-footer.tsx | 6 + packages/website/src/data/agent-pages.ts | 379 ++++++++++ packages/website/src/routeTree.gen.ts | 714 ++++++++++++++++++ packages/website/src/routes/agents.tsx | 65 ++ packages/website/src/routes/agoragentic.tsx | 4 + packages/website/src/routes/amp.tsx | 4 + packages/website/src/routes/auggie.tsx | 4 + packages/website/src/routes/autohand.tsx | 4 + packages/website/src/routes/claude-code.tsx | 22 +- packages/website/src/routes/cline.tsx | 4 + packages/website/src/routes/codebuddy.tsx | 4 + packages/website/src/routes/codex.tsx | 22 +- packages/website/src/routes/copilot.tsx | 4 + packages/website/src/routes/cortex-code.tsx | 4 + packages/website/src/routes/corust.tsx | 4 + packages/website/src/routes/crow.tsx | 4 + packages/website/src/routes/cursor.tsx | 4 + packages/website/src/routes/deepagents.tsx | 4 + packages/website/src/routes/dimcode.tsx | 4 + packages/website/src/routes/dirac.tsx | 4 + packages/website/src/routes/factory-droid.tsx | 4 + packages/website/src/routes/fast-agent.tsx | 4 + packages/website/src/routes/gemini.tsx | 4 + packages/website/src/routes/glm.tsx | 4 + packages/website/src/routes/goose.tsx | 4 + packages/website/src/routes/hermes.tsx | 4 + packages/website/src/routes/junie.tsx | 4 + packages/website/src/routes/kilo.tsx | 4 + packages/website/src/routes/kimi.tsx | 4 + packages/website/src/routes/minion-code.tsx | 4 + packages/website/src/routes/mistral-vibe.tsx | 4 + packages/website/src/routes/nova.tsx | 4 + packages/website/src/routes/opencode.tsx | 22 +- packages/website/src/routes/pi.tsx | 4 + packages/website/src/routes/poolside.tsx | 4 + packages/website/src/routes/qoder.tsx | 4 + packages/website/src/routes/qwen-code.tsx | 4 + packages/website/src/routes/sigit.tsx | 4 + packages/website/src/routes/stakpak.tsx | 4 + packages/website/src/routes/vtcode.tsx | 4 + packages/website/vite.config.ts | 30 +- public-docs/best-practices.md | 2 +- public-docs/cli.md | 16 +- public-docs/configuration.md | 44 +- public-docs/custom-providers.md | 192 +++++ public-docs/index.md | 48 +- public-docs/providers.md | 205 +---- public-docs/security.md | 42 +- public-docs/supported-providers.md | 58 ++ public-docs/updates.md | 42 -- public-docs/voice.md | 14 +- public-docs/why.md | 43 ++ public-docs/worktrees.md | 28 +- 55 files changed, 1754 insertions(+), 403 deletions(-) create mode 100644 packages/website/src/components/agent-route.tsx create mode 100644 packages/website/src/data/agent-pages.ts create mode 100644 packages/website/src/routes/agents.tsx create mode 100644 packages/website/src/routes/agoragentic.tsx create mode 100644 packages/website/src/routes/amp.tsx create mode 100644 packages/website/src/routes/auggie.tsx create mode 100644 packages/website/src/routes/autohand.tsx create mode 100644 packages/website/src/routes/cline.tsx create mode 100644 packages/website/src/routes/codebuddy.tsx create mode 100644 packages/website/src/routes/copilot.tsx create mode 100644 packages/website/src/routes/cortex-code.tsx create mode 100644 packages/website/src/routes/corust.tsx create mode 100644 packages/website/src/routes/crow.tsx create mode 100644 packages/website/src/routes/cursor.tsx create mode 100644 packages/website/src/routes/deepagents.tsx create mode 100644 packages/website/src/routes/dimcode.tsx create mode 100644 packages/website/src/routes/dirac.tsx create mode 100644 packages/website/src/routes/factory-droid.tsx create mode 100644 packages/website/src/routes/fast-agent.tsx create mode 100644 packages/website/src/routes/gemini.tsx create mode 100644 packages/website/src/routes/glm.tsx create mode 100644 packages/website/src/routes/goose.tsx create mode 100644 packages/website/src/routes/hermes.tsx create mode 100644 packages/website/src/routes/junie.tsx create mode 100644 packages/website/src/routes/kilo.tsx create mode 100644 packages/website/src/routes/kimi.tsx create mode 100644 packages/website/src/routes/minion-code.tsx create mode 100644 packages/website/src/routes/mistral-vibe.tsx create mode 100644 packages/website/src/routes/nova.tsx create mode 100644 packages/website/src/routes/pi.tsx create mode 100644 packages/website/src/routes/poolside.tsx create mode 100644 packages/website/src/routes/qoder.tsx create mode 100644 packages/website/src/routes/qwen-code.tsx create mode 100644 packages/website/src/routes/sigit.tsx create mode 100644 packages/website/src/routes/stakpak.tsx create mode 100644 packages/website/src/routes/vtcode.tsx create mode 100644 public-docs/custom-providers.md create mode 100644 public-docs/supported-providers.md delete mode 100644 public-docs/updates.md create mode 100644 public-docs/why.md diff --git a/packages/website/src/components/agent-route.tsx b/packages/website/src/components/agent-route.tsx new file mode 100644 index 000000000..3e330def7 --- /dev/null +++ b/packages/website/src/components/agent-route.tsx @@ -0,0 +1,13 @@ +import { LandingPage } from "~/components/landing-page"; +import { getAgentPage } from "~/data/agent-pages"; +import { pageMeta } from "~/meta"; + +export function agentRouteOptions(slug: string) { + const page = getAgentPage(slug); + return { + head: () => ({ meta: pageMeta(page.metaTitle, page.metaDescription) }), + component: function AgentLandingPage() { + return ; + }, + }; +} diff --git a/packages/website/src/components/landing-page.tsx b/packages/website/src/components/landing-page.tsx index 94f2ecb0d..a242399fc 100644 --- a/packages/website/src/components/landing-page.tsx +++ b/packages/website/src/components/landing-page.tsx @@ -33,6 +33,7 @@ const SVG_OVERFLOW_VISIBLE_STYLE = { overflow: "visible" as const }; const PHONE_PERSPECTIVE_STYLE = { minHeight: 480, perspective: 1200 }; import { CursorFieldProvider } from "~/components/butterfly"; import { CommandDialog } from "~/components/command-dialog"; +import { AGENT_PAGES } from "~/data/agent-pages"; import { appStoreUrl, playStoreUrl, @@ -142,6 +143,9 @@ const OPENCODE_BADGE_ICON = ; const COPILOT_BADGE_ICON = ; const PI_BADGE_ICON = ; +const FEATURED_AGENT_COUNT = 5; +const ADDITIONAL_AGENT_COUNT = AGENT_PAGES.length - FEATURED_AGENT_COUNT; + function AgentBadge({ name, icon }: { name: string; icon: React.ReactNode }) { const [hovered, setHovered] = React.useState(false); const handleMouseEnter = React.useCallback(() => setHovered(true), []); @@ -222,7 +226,7 @@ function MultiProviderSection() { ))} -
+
{providers.slice(3).map((p) => (
{p.name}
))} + + +{ADDITIONAL_AGENT_COUNT} more +
); @@ -910,6 +920,12 @@ function GetStarted() {
+ + +{ADDITIONAL_AGENT_COUNT} more + ); diff --git a/packages/website/src/components/site-footer.tsx b/packages/website/src/components/site-footer.tsx index 12e69194f..88e8fc2a9 100644 --- a/packages/website/src/components/site-footer.tsx +++ b/packages/website/src/components/site-footer.tsx @@ -72,6 +72,12 @@ export function SiteFooter({ width = "default" }: SiteFooterProps) { > OpenCode + + All providers +
diff --git a/packages/website/src/data/agent-pages.ts b/packages/website/src/data/agent-pages.ts new file mode 100644 index 000000000..005bf1ee6 --- /dev/null +++ b/packages/website/src/data/agent-pages.ts @@ -0,0 +1,379 @@ +// Source of truth for per-agent marketing landing pages. +// To add a new agent, append an entry here and create a 4-line route file at +// `src/routes/.tsx`. The sitemap (vite.config) reads `AGENT_PAGE_SLUGS`. + +export interface AgentPage { + slug: string; + name: string; + title: string; + subtitle: string; + metaTitle: string; + metaDescription: string; +} + +export const AGENT_PAGES = [ + { + slug: "claude-code", + name: "Claude Code", + title: "Ship with Claude Code from your phone", + subtitle: + "Launch agents, check on progress, and merge from anywhere. Your Claude Code setup, your machine, your pocket.", + metaTitle: "Claude Code Mobile App – Ship from your phone | Paseo", + metaDescription: + "Run Claude Code from your phone. Launch agents, check on progress, review diffs, and merge — all from your pocket. Self-hosted, your code stays on your machine.", + }, + { + slug: "codex", + name: "Codex", + title: "Run Codex from anywhere", + subtitle: + "Kick off Codex agents on your machine from your phone. Check in on the train, review on the couch, merge from the park.", + metaTitle: "Codex Mobile App – Run Codex from anywhere | Paseo", + metaDescription: + "Run OpenAI Codex from your phone. Kick off agents, monitor progress, and ship code without being at your desk. Self-hosted, your code never leaves your machine.", + }, + { + slug: "opencode", + name: "OpenCode", + title: "Run OpenCode from your phone", + subtitle: + "Launch agents, check on builds, and ship code from anywhere. Same setup, same machine, just not at your desk.", + metaTitle: "OpenCode Mobile App – Code from anywhere | Paseo", + metaDescription: + "Run OpenCode from your phone. Launch agents, watch them work, and ship code from wherever you are. Self-hosted, open source, your code stays local.", + }, + { + slug: "copilot", + name: "GitHub Copilot", + title: "GitHub Copilot, mobile", + subtitle: + "Drive Copilot from your phone. Kick off changes, watch them land, ship without sitting down at your desk.", + metaTitle: "GitHub Copilot Mobile App – Drive Copilot from anywhere | Paseo", + metaDescription: + "Control GitHub Copilot from your phone. Launch sessions, monitor progress, merge from anywhere. Your machine, your account, your pocket.", + }, + { + slug: "pi", + name: "Pi", + title: "Run Pi from your phone", + subtitle: "Tiny agent, full control. Launch Pi from anywhere and check in when it matters.", + metaTitle: "Pi Mobile App – Run pi from anywhere | Paseo", + metaDescription: + "Run the pi coding agent from your phone. Launch sessions on your machine, check progress, merge from your pocket. Self-hosted and open source.", + }, + { + slug: "cursor", + name: "Cursor", + title: "Cursor, in your pocket", + subtitle: "Send tasks to Cursor on your machine, watch them run, review the diff on the train.", + metaTitle: "Cursor Mobile App – Drive Cursor from anywhere | Paseo", + metaDescription: + "Run Cursor from your phone. Launch tasks, monitor output, review diffs, and merge — all from your pocket. Self-hosted, your code stays local.", + }, + { + slug: "gemini", + name: "Gemini CLI", + title: "Run Gemini from anywhere", + subtitle: "Kick off Google's Gemini CLI from your phone. Real coding work, no laptop required.", + metaTitle: "Gemini CLI Mobile App – Run Gemini from anywhere | Paseo", + metaDescription: + "Drive Google's Gemini CLI from your phone. Launch agents, monitor progress, and ship from anywhere. Self-hosted, your code never leaves your machine.", + }, + { + slug: "hermes", + name: "Hermes Agent", + title: "Hermes Agent, on your phone", + subtitle: + "Drive Nous Research's Hermes Agent from anywhere. Your machine does the work, your pocket runs the show.", + metaTitle: "Hermes Agent Mobile App – Drive Hermes from anywhere | Paseo", + metaDescription: + "Run Nous Research's Hermes Agent from your phone. Launch sessions, monitor progress, ship code from your pocket.", + }, + { + slug: "qwen-code", + name: "Qwen Code", + title: "Qwen Code from anywhere", + subtitle: "Send Alibaba's Qwen agent to work on your machine while you're not at your desk.", + metaTitle: "Qwen Code Mobile App – Run Qwen from anywhere | Paseo", + metaDescription: + "Drive Alibaba's Qwen Code from your phone. Launch agents on your machine, monitor progress, and merge from anywhere.", + }, + { + slug: "kimi", + name: "Kimi Code CLI", + title: "Kimi Code from your phone", + subtitle: + "Moonshot AI's Kimi Code CLI on your machine, controlled from anywhere. Same setup, no laptop.", + metaTitle: "Kimi Code Mobile App – Run Kimi Code from anywhere | Paseo", + metaDescription: + "Run Moonshot AI's Kimi Code CLI from your phone. Launch sessions, monitor progress, ship from your pocket. Self-hosted and private.", + }, + { + slug: "amp", + name: "Amp", + title: "Amp, mobile", + subtitle: + "Drive the frontier coding agent from your phone. Kick off work, monitor progress, merge from anywhere.", + metaTitle: "Amp Mobile App – Run Amp from anywhere | Paseo", + metaDescription: + "Run Amp, the frontier coding agent, from your phone. Launch tasks on your machine, watch them ship from your pocket.", + }, + { + slug: "auggie", + name: "Auggie CLI", + title: "Auggie, in your pocket", + subtitle: + "Run Augment Code's agent from your phone. Industry-leading context, anywhere you are.", + metaTitle: "Auggie Mobile App – Drive Augment Code from anywhere | Paseo", + metaDescription: + "Run Augment Code's Auggie CLI from your phone. Launch sessions on your machine, monitor progress, ship code from your pocket.", + }, + { + slug: "cline", + name: "Cline", + title: "Cline from anywhere", + subtitle: + "Autonomous coding agent on your machine, controlled from your phone. Watch it work, jump in when needed.", + metaTitle: "Cline Mobile App – Run Cline from anywhere | Paseo", + metaDescription: + "Drive Cline, the autonomous coding agent, from your phone. Launch tasks, monitor output, review diffs from anywhere.", + }, + { + slug: "codebuddy", + name: "Codebuddy Code", + title: "Codebuddy from your phone", + subtitle: + "Run Tencent Cloud's intelligent coding tool from anywhere. Your dev box, your pocket.", + metaTitle: "Codebuddy Code Mobile App – Run Codebuddy from anywhere | Paseo", + metaDescription: + "Drive Tencent Cloud's Codebuddy Code from your phone. Launch sessions on your machine, monitor progress, ship from anywhere.", + }, + { + slug: "cortex-code", + name: "Cortex Code", + title: "Cortex Code, mobile", + subtitle: + "Snowflake's coding agent on your machine, driven from your phone. No laptop required.", + metaTitle: "Cortex Code Mobile App – Run Cortex Code from anywhere | Paseo", + metaDescription: + "Run Snowflake's Cortex Code from your phone. Launch agents, monitor progress, and ship from anywhere.", + }, + { + slug: "corust", + name: "Corust Agent", + title: "Corust, in your pocket", + subtitle: "Build Rust with a seasoned partner on your machine, driven from your phone.", + metaTitle: "Corust Mobile App – Drive Corust agent from anywhere | Paseo", + metaDescription: + "Run the Corust Rust-focused coding agent from your phone. Launch tasks on your machine, ship from your pocket.", + }, + { + slug: "crow", + name: "crow-cli", + title: "crow-cli from your phone", + subtitle: + "Minimal native coding agent on your machine, controlled from anywhere. Lean, ACP-native, mobile.", + metaTitle: "crow-cli Mobile App – Run crow-cli from anywhere | Paseo", + metaDescription: + "Drive crow-cli, the minimal ACP-native coding agent, from your phone. Launch tasks on your machine, monitor from anywhere.", + }, + { + slug: "deepagents", + name: "DeepAgents", + title: "DeepAgents from your phone", + subtitle: + "LangChain-powered coding agent on your machine, driven from anywhere. Batteries included.", + metaTitle: "DeepAgents Mobile App – Run DeepAgents from anywhere | Paseo", + metaDescription: + "Run the LangChain DeepAgents coding agent from your phone. Launch sessions, monitor progress, and ship code from anywhere.", + }, + { + slug: "dimcode", + name: "DimCode", + title: "DimCode from anywhere", + subtitle: "Leading models, one command — driven from your phone. Your machine does the work.", + metaTitle: "DimCode Mobile App – Run DimCode from anywhere | Paseo", + metaDescription: + "Drive DimCode, the multi-model coding agent, from your phone. Launch tasks on your machine, ship from your pocket.", + }, + { + slug: "dirac", + name: "Dirac", + title: "Dirac, mobile", + subtitle: + "Hash-anchored parallel edits on your machine, driven from your pocket. Faster, cheaper, fully open source.", + metaTitle: "Dirac Mobile App – Run Dirac from anywhere | Paseo", + metaDescription: + "Run the Dirac coding agent from your phone. Hash-anchored parallel edits, AST manipulation, ship from anywhere.", + }, + { + slug: "factory-droid", + name: "Factory Droid", + title: "Factory Droid from anywhere", + subtitle: + "Drive Factory's coding agent from your phone. Kick it off, check in, ship from your pocket.", + metaTitle: "Factory Droid Mobile App – Run Droid from anywhere | Paseo", + metaDescription: + "Run Factory AI's Droid coding agent from your phone. Launch sessions on your machine, monitor progress, ship from anywhere.", + }, + { + slug: "fast-agent", + name: "fast-agent", + title: "fast-agent, mobile", + subtitle: + "Multi-provider agent on your machine, controlled from anywhere. Send work, get results.", + metaTitle: "fast-agent Mobile App – Run fast-agent from anywhere | Paseo", + metaDescription: + "Drive fast-agent, the multi-provider coding agent, from your phone. Launch tasks on your machine, monitor from your pocket.", + }, + { + slug: "glm", + name: "GLM Agent", + title: "GLM Agent from your phone", + subtitle: + "Zhipu AI's GLM coding agent on your machine, driven from anywhere. Streaming, mid-session model switching, mobile.", + metaTitle: "GLM Agent Mobile App – Run GLM from anywhere | Paseo", + metaDescription: + "Run Zhipu AI's GLM coding agent from your phone. Launch sessions, monitor progress, and ship code from anywhere.", + }, + { + slug: "goose", + name: "goose", + title: "Run goose from your phone", + subtitle: + "Block's open-source agent on your laptop, driven from anywhere. Local, extensible, mobile.", + metaTitle: "goose Mobile App – Run goose from anywhere | Paseo", + metaDescription: + "Drive Block's goose, the local open-source AI agent, from your phone. Launch tasks on your machine, ship from your pocket.", + }, + { + slug: "junie", + name: "Junie", + title: "Junie, on your phone", + subtitle: + "JetBrains' coding agent on your dev box, controlled from your pocket. Real work, no IDE required.", + metaTitle: "Junie Mobile App – Run Junie from anywhere | Paseo", + metaDescription: + "Drive JetBrains' Junie coding agent from your phone. Launch sessions on your machine, monitor progress, ship from anywhere.", + }, + { + slug: "kilo", + name: "Kilo Code", + title: "Kilo Code from anywhere", + subtitle: "Kilo Code on your machine, driven from your phone. Send tasks, watch them ship.", + metaTitle: "Kilo Code Mobile App – Run Kilo Code from anywhere | Paseo", + metaDescription: + "Run Kilo Code, the open-source coding agent, from your phone. Launch tasks on your machine via Kilo CLI, monitor progress, merge from anywhere.", + }, + { + slug: "minion-code", + name: "Minion Code", + title: "Minion Code, mobile", + subtitle: + "Minion-framework agent on your machine, controlled from your phone. Rich tooling, full freedom.", + metaTitle: "Minion Code Mobile App – Run Minion Code from anywhere | Paseo", + metaDescription: + "Drive Minion Code, the Minion-framework coding agent, from your phone. Launch sessions on your machine, ship from your pocket.", + }, + { + slug: "mistral-vibe", + name: "Mistral Vibe", + title: "Mistral Vibe from your phone", + subtitle: + "Mistral's open-source coding assistant, driven from anywhere. Your machine, your pocket.", + metaTitle: "Mistral Vibe Mobile App – Run Mistral Vibe from anywhere | Paseo", + metaDescription: + "Run Mistral's open-source Vibe coding assistant from your phone. Launch sessions on your machine, monitor progress, ship from anywhere.", + }, + { + slug: "nova", + name: "Nova", + title: "Nova, in your pocket", + subtitle: + "Compass AI's software engineer on your machine, controlled from your phone. Send work, ship code.", + metaTitle: "Nova Mobile App – Run Nova from anywhere | Paseo", + metaDescription: + "Drive Compass AI's Nova coding agent from your phone. Launch sessions on your machine, monitor progress, merge from your pocket.", + }, + { + slug: "poolside", + name: "Poolside", + title: "Poolside, mobile", + subtitle: + "Drive Poolside's coding agent from anywhere. Kick off the work, watch it land, merge on the move.", + metaTitle: "Poolside Mobile App – Run Poolside from anywhere | Paseo", + metaDescription: + "Run Poolside's coding agent from your phone. Launch tasks on your machine, monitor progress, ship from anywhere.", + }, + { + slug: "qoder", + name: "Qoder CLI", + title: "Qoder from your phone", + subtitle: + "Agentic coding assistant on your machine, controlled from anywhere. No laptop required.", + metaTitle: "Qoder Mobile App – Run Qoder from anywhere | Paseo", + metaDescription: + "Drive Qoder, the agentic coding assistant, from your phone. Launch sessions on your machine, ship from your pocket.", + }, + { + slug: "sigit", + name: "siGit Code", + title: "siGit Code, mobile", + subtitle: + "Local-first coding agent on your machine, driven from your phone. Optionally on-device LLM inference.", + metaTitle: "siGit Code Mobile App – Run siGit from anywhere | Paseo", + metaDescription: + "Run siGit Code, the local-first coding agent, from your phone. Launch sessions on your machine, ship from anywhere.", + }, + { + slug: "stakpak", + name: "Stakpak", + title: "Stakpak DevOps from anywhere", + subtitle: + "Open-source DevOps agent on your machine, controlled from your phone. Rust speed, enterprise security.", + metaTitle: "Stakpak Mobile App – Run Stakpak from anywhere | Paseo", + metaDescription: + "Drive Stakpak, the Rust-based DevOps agent, from your phone. Launch tasks on your machine, monitor from your pocket.", + }, + { + slug: "vtcode", + name: "VT Code", + title: "VT Code, mobile", + subtitle: + "Multi-provider coding agent on your machine. Send tasks from anywhere, ship from your pocket.", + metaTitle: "VT Code Mobile App – Run VT Code from anywhere | Paseo", + metaDescription: + "Run VT Code, the open-source multi-provider coding agent, from your phone. Launch sessions, monitor progress, ship from anywhere.", + }, + { + slug: "agoragentic", + name: "Agoragentic", + title: "Agoragentic from your phone", + subtitle: "174+ AI capabilities on your machine, driven from anywhere. Browse, invoke, ship.", + metaTitle: "Agoragentic Mobile App – Run Agoragentic from anywhere | Paseo", + metaDescription: + "Drive Agoragentic, the AI agent marketplace, from your phone. Launch sessions on your machine, ship from your pocket.", + }, + { + slug: "autohand", + name: "Autohand Code", + title: "Autohand Code, mobile", + subtitle: + "Autohand's coding agent on your machine, controlled from your phone. Real work, no laptop.", + metaTitle: "Autohand Code Mobile App – Run Autohand from anywhere | Paseo", + metaDescription: + "Run Autohand AI's coding agent from your phone. Launch sessions on your machine, monitor progress, ship from anywhere.", + }, +] as const satisfies readonly AgentPage[]; + +export const AGENT_PAGE_SLUGS: readonly string[] = AGENT_PAGES.map((p) => p.slug); + +const AGENT_PAGE_MAP_INTERNAL: Record = Object.fromEntries( + AGENT_PAGES.map((p) => [p.slug, p]), +); + +export function getAgentPage(slug: string): AgentPage { + const page = AGENT_PAGE_MAP_INTERNAL[slug]; + if (!page) throw new Error(`Unknown agent page slug: ${slug}`); + return page; +} diff --git a/packages/website/src/routeTree.gen.ts b/packages/website/src/routeTree.gen.ts index b225986f8..94c697378 100644 --- a/packages/website/src/routeTree.gen.ts +++ b/packages/website/src/routeTree.gen.ts @@ -9,31 +9,160 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from "./routes/__root"; +import { Route as VtcodeRouteImport } from "./routes/vtcode"; +import { Route as StakpakRouteImport } from "./routes/stakpak"; +import { Route as SigitRouteImport } from "./routes/sigit"; +import { Route as QwenCodeRouteImport } from "./routes/qwen-code"; +import { Route as QoderRouteImport } from "./routes/qoder"; import { Route as PrivacyRouteImport } from "./routes/privacy"; +import { Route as PoolsideRouteImport } from "./routes/poolside"; +import { Route as PiRouteImport } from "./routes/pi"; import { Route as OpencodeRouteImport } from "./routes/opencode"; +import { Route as NovaRouteImport } from "./routes/nova"; +import { Route as MistralVibeRouteImport } from "./routes/mistral-vibe"; +import { Route as MinionCodeRouteImport } from "./routes/minion-code"; +import { Route as KimiRouteImport } from "./routes/kimi"; +import { Route as KiloRouteImport } from "./routes/kilo"; +import { Route as JunieRouteImport } from "./routes/junie"; +import { Route as HermesRouteImport } from "./routes/hermes"; +import { Route as GooseRouteImport } from "./routes/goose"; +import { Route as GlmRouteImport } from "./routes/glm"; +import { Route as GeminiRouteImport } from "./routes/gemini"; +import { Route as FastAgentRouteImport } from "./routes/fast-agent"; +import { Route as FactoryDroidRouteImport } from "./routes/factory-droid"; import { Route as DownloadRouteImport } from "./routes/download"; import { Route as DocsRouteImport } from "./routes/docs"; +import { Route as DiracRouteImport } from "./routes/dirac"; +import { Route as DimcodeRouteImport } from "./routes/dimcode"; +import { Route as DeepagentsRouteImport } from "./routes/deepagents"; +import { Route as CursorRouteImport } from "./routes/cursor"; +import { Route as CrowRouteImport } from "./routes/crow"; +import { Route as CorustRouteImport } from "./routes/corust"; +import { Route as CortexCodeRouteImport } from "./routes/cortex-code"; +import { Route as CopilotRouteImport } from "./routes/copilot"; import { Route as CodexRouteImport } from "./routes/codex"; +import { Route as CodebuddyRouteImport } from "./routes/codebuddy"; import { Route as CloudRouteImport } from "./routes/cloud"; +import { Route as ClineRouteImport } from "./routes/cline"; import { Route as ClaudeCodeRouteImport } from "./routes/claude-code"; import { Route as ChangelogRouteImport } from "./routes/changelog"; import { Route as BlogRouteImport } from "./routes/blog"; +import { Route as AutohandRouteImport } from "./routes/autohand"; +import { Route as AuggieRouteImport } from "./routes/auggie"; +import { Route as AmpRouteImport } from "./routes/amp"; +import { Route as AgoragenticRouteImport } from "./routes/agoragentic"; +import { Route as AgentsRouteImport } from "./routes/agents"; import { Route as IndexRouteImport } from "./routes/index"; import { Route as DocsIndexRouteImport } from "./routes/docs/index"; import { Route as BlogIndexRouteImport } from "./routes/blog/index"; import { Route as DocsSplatRouteImport } from "./routes/docs/$"; import { Route as BlogSplatRouteImport } from "./routes/blog/$"; +const VtcodeRoute = VtcodeRouteImport.update({ + id: "/vtcode", + path: "/vtcode", + getParentRoute: () => rootRouteImport, +} as any); +const StakpakRoute = StakpakRouteImport.update({ + id: "/stakpak", + path: "/stakpak", + getParentRoute: () => rootRouteImport, +} as any); +const SigitRoute = SigitRouteImport.update({ + id: "/sigit", + path: "/sigit", + getParentRoute: () => rootRouteImport, +} as any); +const QwenCodeRoute = QwenCodeRouteImport.update({ + id: "/qwen-code", + path: "/qwen-code", + getParentRoute: () => rootRouteImport, +} as any); +const QoderRoute = QoderRouteImport.update({ + id: "/qoder", + path: "/qoder", + getParentRoute: () => rootRouteImport, +} as any); const PrivacyRoute = PrivacyRouteImport.update({ id: "/privacy", path: "/privacy", getParentRoute: () => rootRouteImport, } as any); +const PoolsideRoute = PoolsideRouteImport.update({ + id: "/poolside", + path: "/poolside", + getParentRoute: () => rootRouteImport, +} as any); +const PiRoute = PiRouteImport.update({ + id: "/pi", + path: "/pi", + getParentRoute: () => rootRouteImport, +} as any); const OpencodeRoute = OpencodeRouteImport.update({ id: "/opencode", path: "/opencode", getParentRoute: () => rootRouteImport, } as any); +const NovaRoute = NovaRouteImport.update({ + id: "/nova", + path: "/nova", + getParentRoute: () => rootRouteImport, +} as any); +const MistralVibeRoute = MistralVibeRouteImport.update({ + id: "/mistral-vibe", + path: "/mistral-vibe", + getParentRoute: () => rootRouteImport, +} as any); +const MinionCodeRoute = MinionCodeRouteImport.update({ + id: "/minion-code", + path: "/minion-code", + getParentRoute: () => rootRouteImport, +} as any); +const KimiRoute = KimiRouteImport.update({ + id: "/kimi", + path: "/kimi", + getParentRoute: () => rootRouteImport, +} as any); +const KiloRoute = KiloRouteImport.update({ + id: "/kilo", + path: "/kilo", + getParentRoute: () => rootRouteImport, +} as any); +const JunieRoute = JunieRouteImport.update({ + id: "/junie", + path: "/junie", + getParentRoute: () => rootRouteImport, +} as any); +const HermesRoute = HermesRouteImport.update({ + id: "/hermes", + path: "/hermes", + getParentRoute: () => rootRouteImport, +} as any); +const GooseRoute = GooseRouteImport.update({ + id: "/goose", + path: "/goose", + getParentRoute: () => rootRouteImport, +} as any); +const GlmRoute = GlmRouteImport.update({ + id: "/glm", + path: "/glm", + getParentRoute: () => rootRouteImport, +} as any); +const GeminiRoute = GeminiRouteImport.update({ + id: "/gemini", + path: "/gemini", + getParentRoute: () => rootRouteImport, +} as any); +const FastAgentRoute = FastAgentRouteImport.update({ + id: "/fast-agent", + path: "/fast-agent", + getParentRoute: () => rootRouteImport, +} as any); +const FactoryDroidRoute = FactoryDroidRouteImport.update({ + id: "/factory-droid", + path: "/factory-droid", + getParentRoute: () => rootRouteImport, +} as any); const DownloadRoute = DownloadRouteImport.update({ id: "/download", path: "/download", @@ -44,16 +173,66 @@ const DocsRoute = DocsRouteImport.update({ path: "/docs", getParentRoute: () => rootRouteImport, } as any); +const DiracRoute = DiracRouteImport.update({ + id: "/dirac", + path: "/dirac", + getParentRoute: () => rootRouteImport, +} as any); +const DimcodeRoute = DimcodeRouteImport.update({ + id: "/dimcode", + path: "/dimcode", + getParentRoute: () => rootRouteImport, +} as any); +const DeepagentsRoute = DeepagentsRouteImport.update({ + id: "/deepagents", + path: "/deepagents", + getParentRoute: () => rootRouteImport, +} as any); +const CursorRoute = CursorRouteImport.update({ + id: "/cursor", + path: "/cursor", + getParentRoute: () => rootRouteImport, +} as any); +const CrowRoute = CrowRouteImport.update({ + id: "/crow", + path: "/crow", + getParentRoute: () => rootRouteImport, +} as any); +const CorustRoute = CorustRouteImport.update({ + id: "/corust", + path: "/corust", + getParentRoute: () => rootRouteImport, +} as any); +const CortexCodeRoute = CortexCodeRouteImport.update({ + id: "/cortex-code", + path: "/cortex-code", + getParentRoute: () => rootRouteImport, +} as any); +const CopilotRoute = CopilotRouteImport.update({ + id: "/copilot", + path: "/copilot", + getParentRoute: () => rootRouteImport, +} as any); const CodexRoute = CodexRouteImport.update({ id: "/codex", path: "/codex", getParentRoute: () => rootRouteImport, } as any); +const CodebuddyRoute = CodebuddyRouteImport.update({ + id: "/codebuddy", + path: "/codebuddy", + getParentRoute: () => rootRouteImport, +} as any); const CloudRoute = CloudRouteImport.update({ id: "/cloud", path: "/cloud", getParentRoute: () => rootRouteImport, } as any); +const ClineRoute = ClineRouteImport.update({ + id: "/cline", + path: "/cline", + getParentRoute: () => rootRouteImport, +} as any); const ClaudeCodeRoute = ClaudeCodeRouteImport.update({ id: "/claude-code", path: "/claude-code", @@ -69,6 +248,31 @@ const BlogRoute = BlogRouteImport.update({ path: "/blog", getParentRoute: () => rootRouteImport, } as any); +const AutohandRoute = AutohandRouteImport.update({ + id: "/autohand", + path: "/autohand", + getParentRoute: () => rootRouteImport, +} as any); +const AuggieRoute = AuggieRouteImport.update({ + id: "/auggie", + path: "/auggie", + getParentRoute: () => rootRouteImport, +} as any); +const AmpRoute = AmpRouteImport.update({ + id: "/amp", + path: "/amp", + getParentRoute: () => rootRouteImport, +} as any); +const AgoragenticRoute = AgoragenticRouteImport.update({ + id: "/agoragentic", + path: "/agoragentic", + getParentRoute: () => rootRouteImport, +} as any); +const AgentsRoute = AgentsRouteImport.update({ + id: "/agents", + path: "/agents", + getParentRoute: () => rootRouteImport, +} as any); const IndexRoute = IndexRouteImport.update({ id: "/", path: "/", @@ -97,15 +301,49 @@ const BlogSplatRoute = BlogSplatRouteImport.update({ export interface FileRoutesByFullPath { "/": typeof IndexRoute; + "/agents": typeof AgentsRoute; + "/agoragentic": typeof AgoragenticRoute; + "/amp": typeof AmpRoute; + "/auggie": typeof AuggieRoute; + "/autohand": typeof AutohandRoute; "/blog": typeof BlogRouteWithChildren; "/changelog": typeof ChangelogRoute; "/claude-code": typeof ClaudeCodeRoute; + "/cline": typeof ClineRoute; "/cloud": typeof CloudRoute; + "/codebuddy": typeof CodebuddyRoute; "/codex": typeof CodexRoute; + "/copilot": typeof CopilotRoute; + "/cortex-code": typeof CortexCodeRoute; + "/corust": typeof CorustRoute; + "/crow": typeof CrowRoute; + "/cursor": typeof CursorRoute; + "/deepagents": typeof DeepagentsRoute; + "/dimcode": typeof DimcodeRoute; + "/dirac": typeof DiracRoute; "/docs": typeof DocsRouteWithChildren; "/download": typeof DownloadRoute; + "/factory-droid": typeof FactoryDroidRoute; + "/fast-agent": typeof FastAgentRoute; + "/gemini": typeof GeminiRoute; + "/glm": typeof GlmRoute; + "/goose": typeof GooseRoute; + "/hermes": typeof HermesRoute; + "/junie": typeof JunieRoute; + "/kilo": typeof KiloRoute; + "/kimi": typeof KimiRoute; + "/minion-code": typeof MinionCodeRoute; + "/mistral-vibe": typeof MistralVibeRoute; + "/nova": typeof NovaRoute; "/opencode": typeof OpencodeRoute; + "/pi": typeof PiRoute; + "/poolside": typeof PoolsideRoute; "/privacy": typeof PrivacyRoute; + "/qoder": typeof QoderRoute; + "/qwen-code": typeof QwenCodeRoute; + "/sigit": typeof SigitRoute; + "/stakpak": typeof StakpakRoute; + "/vtcode": typeof VtcodeRoute; "/blog/$": typeof BlogSplatRoute; "/docs/$": typeof DocsSplatRoute; "/blog/": typeof BlogIndexRoute; @@ -113,13 +351,47 @@ export interface FileRoutesByFullPath { } export interface FileRoutesByTo { "/": typeof IndexRoute; + "/agents": typeof AgentsRoute; + "/agoragentic": typeof AgoragenticRoute; + "/amp": typeof AmpRoute; + "/auggie": typeof AuggieRoute; + "/autohand": typeof AutohandRoute; "/changelog": typeof ChangelogRoute; "/claude-code": typeof ClaudeCodeRoute; + "/cline": typeof ClineRoute; "/cloud": typeof CloudRoute; + "/codebuddy": typeof CodebuddyRoute; "/codex": typeof CodexRoute; + "/copilot": typeof CopilotRoute; + "/cortex-code": typeof CortexCodeRoute; + "/corust": typeof CorustRoute; + "/crow": typeof CrowRoute; + "/cursor": typeof CursorRoute; + "/deepagents": typeof DeepagentsRoute; + "/dimcode": typeof DimcodeRoute; + "/dirac": typeof DiracRoute; "/download": typeof DownloadRoute; + "/factory-droid": typeof FactoryDroidRoute; + "/fast-agent": typeof FastAgentRoute; + "/gemini": typeof GeminiRoute; + "/glm": typeof GlmRoute; + "/goose": typeof GooseRoute; + "/hermes": typeof HermesRoute; + "/junie": typeof JunieRoute; + "/kilo": typeof KiloRoute; + "/kimi": typeof KimiRoute; + "/minion-code": typeof MinionCodeRoute; + "/mistral-vibe": typeof MistralVibeRoute; + "/nova": typeof NovaRoute; "/opencode": typeof OpencodeRoute; + "/pi": typeof PiRoute; + "/poolside": typeof PoolsideRoute; "/privacy": typeof PrivacyRoute; + "/qoder": typeof QoderRoute; + "/qwen-code": typeof QwenCodeRoute; + "/sigit": typeof SigitRoute; + "/stakpak": typeof StakpakRoute; + "/vtcode": typeof VtcodeRoute; "/blog/$": typeof BlogSplatRoute; "/docs/$": typeof DocsSplatRoute; "/blog": typeof BlogIndexRoute; @@ -128,15 +400,49 @@ export interface FileRoutesByTo { export interface FileRoutesById { __root__: typeof rootRouteImport; "/": typeof IndexRoute; + "/agents": typeof AgentsRoute; + "/agoragentic": typeof AgoragenticRoute; + "/amp": typeof AmpRoute; + "/auggie": typeof AuggieRoute; + "/autohand": typeof AutohandRoute; "/blog": typeof BlogRouteWithChildren; "/changelog": typeof ChangelogRoute; "/claude-code": typeof ClaudeCodeRoute; + "/cline": typeof ClineRoute; "/cloud": typeof CloudRoute; + "/codebuddy": typeof CodebuddyRoute; "/codex": typeof CodexRoute; + "/copilot": typeof CopilotRoute; + "/cortex-code": typeof CortexCodeRoute; + "/corust": typeof CorustRoute; + "/crow": typeof CrowRoute; + "/cursor": typeof CursorRoute; + "/deepagents": typeof DeepagentsRoute; + "/dimcode": typeof DimcodeRoute; + "/dirac": typeof DiracRoute; "/docs": typeof DocsRouteWithChildren; "/download": typeof DownloadRoute; + "/factory-droid": typeof FactoryDroidRoute; + "/fast-agent": typeof FastAgentRoute; + "/gemini": typeof GeminiRoute; + "/glm": typeof GlmRoute; + "/goose": typeof GooseRoute; + "/hermes": typeof HermesRoute; + "/junie": typeof JunieRoute; + "/kilo": typeof KiloRoute; + "/kimi": typeof KimiRoute; + "/minion-code": typeof MinionCodeRoute; + "/mistral-vibe": typeof MistralVibeRoute; + "/nova": typeof NovaRoute; "/opencode": typeof OpencodeRoute; + "/pi": typeof PiRoute; + "/poolside": typeof PoolsideRoute; "/privacy": typeof PrivacyRoute; + "/qoder": typeof QoderRoute; + "/qwen-code": typeof QwenCodeRoute; + "/sigit": typeof SigitRoute; + "/stakpak": typeof StakpakRoute; + "/vtcode": typeof VtcodeRoute; "/blog/$": typeof BlogSplatRoute; "/docs/$": typeof DocsSplatRoute; "/blog/": typeof BlogIndexRoute; @@ -146,15 +452,49 @@ export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath; fullPaths: | "/" + | "/agents" + | "/agoragentic" + | "/amp" + | "/auggie" + | "/autohand" | "/blog" | "/changelog" | "/claude-code" + | "/cline" | "/cloud" + | "/codebuddy" | "/codex" + | "/copilot" + | "/cortex-code" + | "/corust" + | "/crow" + | "/cursor" + | "/deepagents" + | "/dimcode" + | "/dirac" | "/docs" | "/download" + | "/factory-droid" + | "/fast-agent" + | "/gemini" + | "/glm" + | "/goose" + | "/hermes" + | "/junie" + | "/kilo" + | "/kimi" + | "/minion-code" + | "/mistral-vibe" + | "/nova" | "/opencode" + | "/pi" + | "/poolside" | "/privacy" + | "/qoder" + | "/qwen-code" + | "/sigit" + | "/stakpak" + | "/vtcode" | "/blog/$" | "/docs/$" | "/blog/" @@ -162,13 +502,47 @@ export interface FileRouteTypes { fileRoutesByTo: FileRoutesByTo; to: | "/" + | "/agents" + | "/agoragentic" + | "/amp" + | "/auggie" + | "/autohand" | "/changelog" | "/claude-code" + | "/cline" | "/cloud" + | "/codebuddy" | "/codex" + | "/copilot" + | "/cortex-code" + | "/corust" + | "/crow" + | "/cursor" + | "/deepagents" + | "/dimcode" + | "/dirac" | "/download" + | "/factory-droid" + | "/fast-agent" + | "/gemini" + | "/glm" + | "/goose" + | "/hermes" + | "/junie" + | "/kilo" + | "/kimi" + | "/minion-code" + | "/mistral-vibe" + | "/nova" | "/opencode" + | "/pi" + | "/poolside" | "/privacy" + | "/qoder" + | "/qwen-code" + | "/sigit" + | "/stakpak" + | "/vtcode" | "/blog/$" | "/docs/$" | "/blog" @@ -176,15 +550,49 @@ export interface FileRouteTypes { id: | "__root__" | "/" + | "/agents" + | "/agoragentic" + | "/amp" + | "/auggie" + | "/autohand" | "/blog" | "/changelog" | "/claude-code" + | "/cline" | "/cloud" + | "/codebuddy" | "/codex" + | "/copilot" + | "/cortex-code" + | "/corust" + | "/crow" + | "/cursor" + | "/deepagents" + | "/dimcode" + | "/dirac" | "/docs" | "/download" + | "/factory-droid" + | "/fast-agent" + | "/gemini" + | "/glm" + | "/goose" + | "/hermes" + | "/junie" + | "/kilo" + | "/kimi" + | "/minion-code" + | "/mistral-vibe" + | "/nova" | "/opencode" + | "/pi" + | "/poolside" | "/privacy" + | "/qoder" + | "/qwen-code" + | "/sigit" + | "/stakpak" + | "/vtcode" | "/blog/$" | "/docs/$" | "/blog/" @@ -193,19 +601,88 @@ export interface FileRouteTypes { } export interface RootRouteChildren { IndexRoute: typeof IndexRoute; + AgentsRoute: typeof AgentsRoute; + AgoragenticRoute: typeof AgoragenticRoute; + AmpRoute: typeof AmpRoute; + AuggieRoute: typeof AuggieRoute; + AutohandRoute: typeof AutohandRoute; BlogRoute: typeof BlogRouteWithChildren; ChangelogRoute: typeof ChangelogRoute; ClaudeCodeRoute: typeof ClaudeCodeRoute; + ClineRoute: typeof ClineRoute; CloudRoute: typeof CloudRoute; + CodebuddyRoute: typeof CodebuddyRoute; CodexRoute: typeof CodexRoute; + CopilotRoute: typeof CopilotRoute; + CortexCodeRoute: typeof CortexCodeRoute; + CorustRoute: typeof CorustRoute; + CrowRoute: typeof CrowRoute; + CursorRoute: typeof CursorRoute; + DeepagentsRoute: typeof DeepagentsRoute; + DimcodeRoute: typeof DimcodeRoute; + DiracRoute: typeof DiracRoute; DocsRoute: typeof DocsRouteWithChildren; DownloadRoute: typeof DownloadRoute; + FactoryDroidRoute: typeof FactoryDroidRoute; + FastAgentRoute: typeof FastAgentRoute; + GeminiRoute: typeof GeminiRoute; + GlmRoute: typeof GlmRoute; + GooseRoute: typeof GooseRoute; + HermesRoute: typeof HermesRoute; + JunieRoute: typeof JunieRoute; + KiloRoute: typeof KiloRoute; + KimiRoute: typeof KimiRoute; + MinionCodeRoute: typeof MinionCodeRoute; + MistralVibeRoute: typeof MistralVibeRoute; + NovaRoute: typeof NovaRoute; OpencodeRoute: typeof OpencodeRoute; + PiRoute: typeof PiRoute; + PoolsideRoute: typeof PoolsideRoute; PrivacyRoute: typeof PrivacyRoute; + QoderRoute: typeof QoderRoute; + QwenCodeRoute: typeof QwenCodeRoute; + SigitRoute: typeof SigitRoute; + StakpakRoute: typeof StakpakRoute; + VtcodeRoute: typeof VtcodeRoute; } declare module "@tanstack/react-router" { interface FileRoutesByPath { + "/vtcode": { + id: "/vtcode"; + path: "/vtcode"; + fullPath: "/vtcode"; + preLoaderRoute: typeof VtcodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/stakpak": { + id: "/stakpak"; + path: "/stakpak"; + fullPath: "/stakpak"; + preLoaderRoute: typeof StakpakRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/sigit": { + id: "/sigit"; + path: "/sigit"; + fullPath: "/sigit"; + preLoaderRoute: typeof SigitRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/qwen-code": { + id: "/qwen-code"; + path: "/qwen-code"; + fullPath: "/qwen-code"; + preLoaderRoute: typeof QwenCodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/qoder": { + id: "/qoder"; + path: "/qoder"; + fullPath: "/qoder"; + preLoaderRoute: typeof QoderRouteImport; + parentRoute: typeof rootRouteImport; + }; "/privacy": { id: "/privacy"; path: "/privacy"; @@ -213,6 +690,20 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof PrivacyRouteImport; parentRoute: typeof rootRouteImport; }; + "/poolside": { + id: "/poolside"; + path: "/poolside"; + fullPath: "/poolside"; + preLoaderRoute: typeof PoolsideRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/pi": { + id: "/pi"; + path: "/pi"; + fullPath: "/pi"; + preLoaderRoute: typeof PiRouteImport; + parentRoute: typeof rootRouteImport; + }; "/opencode": { id: "/opencode"; path: "/opencode"; @@ -220,6 +711,90 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof OpencodeRouteImport; parentRoute: typeof rootRouteImport; }; + "/nova": { + id: "/nova"; + path: "/nova"; + fullPath: "/nova"; + preLoaderRoute: typeof NovaRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/mistral-vibe": { + id: "/mistral-vibe"; + path: "/mistral-vibe"; + fullPath: "/mistral-vibe"; + preLoaderRoute: typeof MistralVibeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/minion-code": { + id: "/minion-code"; + path: "/minion-code"; + fullPath: "/minion-code"; + preLoaderRoute: typeof MinionCodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/kimi": { + id: "/kimi"; + path: "/kimi"; + fullPath: "/kimi"; + preLoaderRoute: typeof KimiRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/kilo": { + id: "/kilo"; + path: "/kilo"; + fullPath: "/kilo"; + preLoaderRoute: typeof KiloRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/junie": { + id: "/junie"; + path: "/junie"; + fullPath: "/junie"; + preLoaderRoute: typeof JunieRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/hermes": { + id: "/hermes"; + path: "/hermes"; + fullPath: "/hermes"; + preLoaderRoute: typeof HermesRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/goose": { + id: "/goose"; + path: "/goose"; + fullPath: "/goose"; + preLoaderRoute: typeof GooseRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/glm": { + id: "/glm"; + path: "/glm"; + fullPath: "/glm"; + preLoaderRoute: typeof GlmRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/gemini": { + id: "/gemini"; + path: "/gemini"; + fullPath: "/gemini"; + preLoaderRoute: typeof GeminiRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/fast-agent": { + id: "/fast-agent"; + path: "/fast-agent"; + fullPath: "/fast-agent"; + preLoaderRoute: typeof FastAgentRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/factory-droid": { + id: "/factory-droid"; + path: "/factory-droid"; + fullPath: "/factory-droid"; + preLoaderRoute: typeof FactoryDroidRouteImport; + parentRoute: typeof rootRouteImport; + }; "/download": { id: "/download"; path: "/download"; @@ -234,6 +809,62 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof DocsRouteImport; parentRoute: typeof rootRouteImport; }; + "/dirac": { + id: "/dirac"; + path: "/dirac"; + fullPath: "/dirac"; + preLoaderRoute: typeof DiracRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/dimcode": { + id: "/dimcode"; + path: "/dimcode"; + fullPath: "/dimcode"; + preLoaderRoute: typeof DimcodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/deepagents": { + id: "/deepagents"; + path: "/deepagents"; + fullPath: "/deepagents"; + preLoaderRoute: typeof DeepagentsRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/cursor": { + id: "/cursor"; + path: "/cursor"; + fullPath: "/cursor"; + preLoaderRoute: typeof CursorRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/crow": { + id: "/crow"; + path: "/crow"; + fullPath: "/crow"; + preLoaderRoute: typeof CrowRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/corust": { + id: "/corust"; + path: "/corust"; + fullPath: "/corust"; + preLoaderRoute: typeof CorustRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/cortex-code": { + id: "/cortex-code"; + path: "/cortex-code"; + fullPath: "/cortex-code"; + preLoaderRoute: typeof CortexCodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/copilot": { + id: "/copilot"; + path: "/copilot"; + fullPath: "/copilot"; + preLoaderRoute: typeof CopilotRouteImport; + parentRoute: typeof rootRouteImport; + }; "/codex": { id: "/codex"; path: "/codex"; @@ -241,6 +872,13 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof CodexRouteImport; parentRoute: typeof rootRouteImport; }; + "/codebuddy": { + id: "/codebuddy"; + path: "/codebuddy"; + fullPath: "/codebuddy"; + preLoaderRoute: typeof CodebuddyRouteImport; + parentRoute: typeof rootRouteImport; + }; "/cloud": { id: "/cloud"; path: "/cloud"; @@ -248,6 +886,13 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof CloudRouteImport; parentRoute: typeof rootRouteImport; }; + "/cline": { + id: "/cline"; + path: "/cline"; + fullPath: "/cline"; + preLoaderRoute: typeof ClineRouteImport; + parentRoute: typeof rootRouteImport; + }; "/claude-code": { id: "/claude-code"; path: "/claude-code"; @@ -269,6 +914,41 @@ declare module "@tanstack/react-router" { preLoaderRoute: typeof BlogRouteImport; parentRoute: typeof rootRouteImport; }; + "/autohand": { + id: "/autohand"; + path: "/autohand"; + fullPath: "/autohand"; + preLoaderRoute: typeof AutohandRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/auggie": { + id: "/auggie"; + path: "/auggie"; + fullPath: "/auggie"; + preLoaderRoute: typeof AuggieRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/amp": { + id: "/amp"; + path: "/amp"; + fullPath: "/amp"; + preLoaderRoute: typeof AmpRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/agoragentic": { + id: "/agoragentic"; + path: "/agoragentic"; + fullPath: "/agoragentic"; + preLoaderRoute: typeof AgoragenticRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/agents": { + id: "/agents"; + path: "/agents"; + fullPath: "/agents"; + preLoaderRoute: typeof AgentsRouteImport; + parentRoute: typeof rootRouteImport; + }; "/": { id: "/"; path: "/"; @@ -333,15 +1013,49 @@ const DocsRouteWithChildren = DocsRoute._addFileChildren(DocsRouteChildren); const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, + AgentsRoute: AgentsRoute, + AgoragenticRoute: AgoragenticRoute, + AmpRoute: AmpRoute, + AuggieRoute: AuggieRoute, + AutohandRoute: AutohandRoute, BlogRoute: BlogRouteWithChildren, ChangelogRoute: ChangelogRoute, ClaudeCodeRoute: ClaudeCodeRoute, + ClineRoute: ClineRoute, CloudRoute: CloudRoute, + CodebuddyRoute: CodebuddyRoute, CodexRoute: CodexRoute, + CopilotRoute: CopilotRoute, + CortexCodeRoute: CortexCodeRoute, + CorustRoute: CorustRoute, + CrowRoute: CrowRoute, + CursorRoute: CursorRoute, + DeepagentsRoute: DeepagentsRoute, + DimcodeRoute: DimcodeRoute, + DiracRoute: DiracRoute, DocsRoute: DocsRouteWithChildren, DownloadRoute: DownloadRoute, + FactoryDroidRoute: FactoryDroidRoute, + FastAgentRoute: FastAgentRoute, + GeminiRoute: GeminiRoute, + GlmRoute: GlmRoute, + GooseRoute: GooseRoute, + HermesRoute: HermesRoute, + JunieRoute: JunieRoute, + KiloRoute: KiloRoute, + KimiRoute: KimiRoute, + MinionCodeRoute: MinionCodeRoute, + MistralVibeRoute: MistralVibeRoute, + NovaRoute: NovaRoute, OpencodeRoute: OpencodeRoute, + PiRoute: PiRoute, + PoolsideRoute: PoolsideRoute, PrivacyRoute: PrivacyRoute, + QoderRoute: QoderRoute, + QwenCodeRoute: QwenCodeRoute, + SigitRoute: SigitRoute, + StakpakRoute: StakpakRoute, + VtcodeRoute: VtcodeRoute, }; export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/packages/website/src/routes/agents.tsx b/packages/website/src/routes/agents.tsx new file mode 100644 index 000000000..976595904 --- /dev/null +++ b/packages/website/src/routes/agents.tsx @@ -0,0 +1,65 @@ +import { createFileRoute, Link } from "@tanstack/react-router"; +import { CursorFieldProvider } from "~/components/butterfly"; +import { SiteFooter } from "~/components/site-footer"; +import { SiteHeader } from "~/components/site-header"; +import { AGENT_PAGES } from "~/data/agent-pages"; +import { pageMeta } from "~/meta"; +import "~/styles.css"; + +export const Route = createFileRoute("/agents")({ + head: () => ({ + meta: pageMeta( + "Supported agents – Every coding agent Paseo runs | Paseo", + "Run Claude Code, Codex, OpenCode, Cursor CLI, Gemini CLI, Hermes Agent, Qwen Code, Kimi Code, and 28 more coding agents from your phone. Self-hosted, your code stays on your machine.", + ), + }), + component: AgentsPage, +}); + +function AgentsPage() { + return ( + +
+
+ +
+

+ Every agent Paseo supports +

+

+ Paseo runs the native CLI for {AGENT_PAGES.length} coding agents — your skills, your + config, your MCP servers, all intact. Drive any of them from your phone. +

+
+
+ +
+
+ {AGENT_PAGES.map((agent) => ( + +

{agent.name}

+

{agent.subtitle}

+ + ))} +
+ +

+ Want to add another?{" "} + + Configure any ACP-compatible agent + {" "} + in ~/.paseo/config.json. +

+
+ + +
+
+ ); +} diff --git a/packages/website/src/routes/agoragentic.tsx b/packages/website/src/routes/agoragentic.tsx new file mode 100644 index 000000000..accc87acc --- /dev/null +++ b/packages/website/src/routes/agoragentic.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/agoragentic")(agentRouteOptions("agoragentic")); diff --git a/packages/website/src/routes/amp.tsx b/packages/website/src/routes/amp.tsx new file mode 100644 index 000000000..a44fe254d --- /dev/null +++ b/packages/website/src/routes/amp.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/amp")(agentRouteOptions("amp")); diff --git a/packages/website/src/routes/auggie.tsx b/packages/website/src/routes/auggie.tsx new file mode 100644 index 000000000..1237d8f8e --- /dev/null +++ b/packages/website/src/routes/auggie.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/auggie")(agentRouteOptions("auggie")); diff --git a/packages/website/src/routes/autohand.tsx b/packages/website/src/routes/autohand.tsx new file mode 100644 index 000000000..e39d8f033 --- /dev/null +++ b/packages/website/src/routes/autohand.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/autohand")(agentRouteOptions("autohand")); diff --git a/packages/website/src/routes/claude-code.tsx b/packages/website/src/routes/claude-code.tsx index 62f3ac7db..3c4682023 100644 --- a/packages/website/src/routes/claude-code.tsx +++ b/packages/website/src/routes/claude-code.tsx @@ -1,22 +1,4 @@ import { createFileRoute } from "@tanstack/react-router"; -import { LandingPage } from "~/components/landing-page"; -import { pageMeta } from "~/meta"; +import { agentRouteOptions } from "~/components/agent-route"; -export const Route = createFileRoute("/claude-code")({ - head: () => ({ - meta: pageMeta( - "Claude Code Mobile App – Ship from your phone | Paseo", - "Run Claude Code from your phone. Launch agents, check on progress, review diffs, and merge — all from your pocket. Self-hosted, your code stays on your machine.", - ), - }), - component: ClaudeCodePage, -}); - -function ClaudeCodePage() { - return ( - - ); -} +export const Route = createFileRoute("/claude-code")(agentRouteOptions("claude-code")); diff --git a/packages/website/src/routes/cline.tsx b/packages/website/src/routes/cline.tsx new file mode 100644 index 000000000..9eb79fafe --- /dev/null +++ b/packages/website/src/routes/cline.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/cline")(agentRouteOptions("cline")); diff --git a/packages/website/src/routes/codebuddy.tsx b/packages/website/src/routes/codebuddy.tsx new file mode 100644 index 000000000..98a1b92d3 --- /dev/null +++ b/packages/website/src/routes/codebuddy.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/codebuddy")(agentRouteOptions("codebuddy")); diff --git a/packages/website/src/routes/codex.tsx b/packages/website/src/routes/codex.tsx index f00ab49cf..17e768133 100644 --- a/packages/website/src/routes/codex.tsx +++ b/packages/website/src/routes/codex.tsx @@ -1,22 +1,4 @@ import { createFileRoute } from "@tanstack/react-router"; -import { LandingPage } from "~/components/landing-page"; -import { pageMeta } from "~/meta"; +import { agentRouteOptions } from "~/components/agent-route"; -export const Route = createFileRoute("/codex")({ - head: () => ({ - meta: pageMeta( - "Codex Mobile App – Run Codex from anywhere | Paseo", - "Run OpenAI Codex from your phone. Kick off agents, monitor progress, and ship code without being at your desk. Self-hosted, your code never leaves your machine.", - ), - }), - component: CodexPage, -}); - -function CodexPage() { - return ( - - ); -} +export const Route = createFileRoute("/codex")(agentRouteOptions("codex")); diff --git a/packages/website/src/routes/copilot.tsx b/packages/website/src/routes/copilot.tsx new file mode 100644 index 000000000..c0854dc50 --- /dev/null +++ b/packages/website/src/routes/copilot.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/copilot")(agentRouteOptions("copilot")); diff --git a/packages/website/src/routes/cortex-code.tsx b/packages/website/src/routes/cortex-code.tsx new file mode 100644 index 000000000..65724c893 --- /dev/null +++ b/packages/website/src/routes/cortex-code.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/cortex-code")(agentRouteOptions("cortex-code")); diff --git a/packages/website/src/routes/corust.tsx b/packages/website/src/routes/corust.tsx new file mode 100644 index 000000000..67967344c --- /dev/null +++ b/packages/website/src/routes/corust.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/corust")(agentRouteOptions("corust")); diff --git a/packages/website/src/routes/crow.tsx b/packages/website/src/routes/crow.tsx new file mode 100644 index 000000000..ad02566b4 --- /dev/null +++ b/packages/website/src/routes/crow.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/crow")(agentRouteOptions("crow")); diff --git a/packages/website/src/routes/cursor.tsx b/packages/website/src/routes/cursor.tsx new file mode 100644 index 000000000..6a1b17866 --- /dev/null +++ b/packages/website/src/routes/cursor.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/cursor")(agentRouteOptions("cursor")); diff --git a/packages/website/src/routes/deepagents.tsx b/packages/website/src/routes/deepagents.tsx new file mode 100644 index 000000000..c5e357037 --- /dev/null +++ b/packages/website/src/routes/deepagents.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/deepagents")(agentRouteOptions("deepagents")); diff --git a/packages/website/src/routes/dimcode.tsx b/packages/website/src/routes/dimcode.tsx new file mode 100644 index 000000000..8c4d7b6c6 --- /dev/null +++ b/packages/website/src/routes/dimcode.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/dimcode")(agentRouteOptions("dimcode")); diff --git a/packages/website/src/routes/dirac.tsx b/packages/website/src/routes/dirac.tsx new file mode 100644 index 000000000..9ec697706 --- /dev/null +++ b/packages/website/src/routes/dirac.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/dirac")(agentRouteOptions("dirac")); diff --git a/packages/website/src/routes/factory-droid.tsx b/packages/website/src/routes/factory-droid.tsx new file mode 100644 index 000000000..2f38c31a0 --- /dev/null +++ b/packages/website/src/routes/factory-droid.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/factory-droid")(agentRouteOptions("factory-droid")); diff --git a/packages/website/src/routes/fast-agent.tsx b/packages/website/src/routes/fast-agent.tsx new file mode 100644 index 000000000..468394d78 --- /dev/null +++ b/packages/website/src/routes/fast-agent.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/fast-agent")(agentRouteOptions("fast-agent")); diff --git a/packages/website/src/routes/gemini.tsx b/packages/website/src/routes/gemini.tsx new file mode 100644 index 000000000..4b007ca30 --- /dev/null +++ b/packages/website/src/routes/gemini.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/gemini")(agentRouteOptions("gemini")); diff --git a/packages/website/src/routes/glm.tsx b/packages/website/src/routes/glm.tsx new file mode 100644 index 000000000..6a08c6721 --- /dev/null +++ b/packages/website/src/routes/glm.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/glm")(agentRouteOptions("glm")); diff --git a/packages/website/src/routes/goose.tsx b/packages/website/src/routes/goose.tsx new file mode 100644 index 000000000..ba6d4b3b4 --- /dev/null +++ b/packages/website/src/routes/goose.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/goose")(agentRouteOptions("goose")); diff --git a/packages/website/src/routes/hermes.tsx b/packages/website/src/routes/hermes.tsx new file mode 100644 index 000000000..f9a5669bb --- /dev/null +++ b/packages/website/src/routes/hermes.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/hermes")(agentRouteOptions("hermes")); diff --git a/packages/website/src/routes/junie.tsx b/packages/website/src/routes/junie.tsx new file mode 100644 index 000000000..529295018 --- /dev/null +++ b/packages/website/src/routes/junie.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/junie")(agentRouteOptions("junie")); diff --git a/packages/website/src/routes/kilo.tsx b/packages/website/src/routes/kilo.tsx new file mode 100644 index 000000000..3a797e31c --- /dev/null +++ b/packages/website/src/routes/kilo.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/kilo")(agentRouteOptions("kilo")); diff --git a/packages/website/src/routes/kimi.tsx b/packages/website/src/routes/kimi.tsx new file mode 100644 index 000000000..cc749de4b --- /dev/null +++ b/packages/website/src/routes/kimi.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/kimi")(agentRouteOptions("kimi")); diff --git a/packages/website/src/routes/minion-code.tsx b/packages/website/src/routes/minion-code.tsx new file mode 100644 index 000000000..6ff25c72b --- /dev/null +++ b/packages/website/src/routes/minion-code.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/minion-code")(agentRouteOptions("minion-code")); diff --git a/packages/website/src/routes/mistral-vibe.tsx b/packages/website/src/routes/mistral-vibe.tsx new file mode 100644 index 000000000..25c794c3b --- /dev/null +++ b/packages/website/src/routes/mistral-vibe.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/mistral-vibe")(agentRouteOptions("mistral-vibe")); diff --git a/packages/website/src/routes/nova.tsx b/packages/website/src/routes/nova.tsx new file mode 100644 index 000000000..7aa908be1 --- /dev/null +++ b/packages/website/src/routes/nova.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/nova")(agentRouteOptions("nova")); diff --git a/packages/website/src/routes/opencode.tsx b/packages/website/src/routes/opencode.tsx index b9ab6f8f8..dcb326a0f 100644 --- a/packages/website/src/routes/opencode.tsx +++ b/packages/website/src/routes/opencode.tsx @@ -1,22 +1,4 @@ import { createFileRoute } from "@tanstack/react-router"; -import { LandingPage } from "~/components/landing-page"; -import { pageMeta } from "~/meta"; +import { agentRouteOptions } from "~/components/agent-route"; -export const Route = createFileRoute("/opencode")({ - head: () => ({ - meta: pageMeta( - "OpenCode Mobile App – Code from anywhere | Paseo", - "Run OpenCode from your phone. Launch agents, watch them work, and ship code from wherever you are. Self-hosted, open source, your code stays local.", - ), - }), - component: OpenCodePage, -}); - -function OpenCodePage() { - return ( - - ); -} +export const Route = createFileRoute("/opencode")(agentRouteOptions("opencode")); diff --git a/packages/website/src/routes/pi.tsx b/packages/website/src/routes/pi.tsx new file mode 100644 index 000000000..12e2351b5 --- /dev/null +++ b/packages/website/src/routes/pi.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/pi")(agentRouteOptions("pi")); diff --git a/packages/website/src/routes/poolside.tsx b/packages/website/src/routes/poolside.tsx new file mode 100644 index 000000000..e0549a8f8 --- /dev/null +++ b/packages/website/src/routes/poolside.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/poolside")(agentRouteOptions("poolside")); diff --git a/packages/website/src/routes/qoder.tsx b/packages/website/src/routes/qoder.tsx new file mode 100644 index 000000000..18544615a --- /dev/null +++ b/packages/website/src/routes/qoder.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/qoder")(agentRouteOptions("qoder")); diff --git a/packages/website/src/routes/qwen-code.tsx b/packages/website/src/routes/qwen-code.tsx new file mode 100644 index 000000000..85cf2100f --- /dev/null +++ b/packages/website/src/routes/qwen-code.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/qwen-code")(agentRouteOptions("qwen-code")); diff --git a/packages/website/src/routes/sigit.tsx b/packages/website/src/routes/sigit.tsx new file mode 100644 index 000000000..0ec4698f1 --- /dev/null +++ b/packages/website/src/routes/sigit.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/sigit")(agentRouteOptions("sigit")); diff --git a/packages/website/src/routes/stakpak.tsx b/packages/website/src/routes/stakpak.tsx new file mode 100644 index 000000000..618421272 --- /dev/null +++ b/packages/website/src/routes/stakpak.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/stakpak")(agentRouteOptions("stakpak")); diff --git a/packages/website/src/routes/vtcode.tsx b/packages/website/src/routes/vtcode.tsx new file mode 100644 index 000000000..ead4d12d6 --- /dev/null +++ b/packages/website/src/routes/vtcode.tsx @@ -0,0 +1,4 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { agentRouteOptions } from "~/components/agent-route"; + +export const Route = createFileRoute("/vtcode")(agentRouteOptions("vtcode")); diff --git a/packages/website/vite.config.ts b/packages/website/vite.config.ts index 2793956b2..056054eb1 100644 --- a/packages/website/vite.config.ts +++ b/packages/website/vite.config.ts @@ -31,15 +31,36 @@ function discoverDocsRoutes(): string[] { return [...routes].sort(); } +function discoverAgentRoutes(): string[] { + const routesDir = path.join(__dirname, "src/routes"); + const reserved = new Set([ + "__root", + "agents", + "blog", + "changelog", + "cloud", + "docs", + "download", + "index", + "privacy", + ]); + return fs + .readdirSync(routesDir, { withFileTypes: true }) + .filter((entry) => entry.isFile() && entry.name.endsWith(".tsx")) + .map((entry) => entry.name.replace(/\.tsx$/, "")) + .filter((name) => !reserved.has(name)) + .sort() + .map((slug) => `/${slug}`); +} + const sitemapPages = [ "/", + "/agents", "/changelog", - "/claude-code", "/cloud", - "/codex", "/download", - "/opencode", "/privacy", + ...discoverAgentRoutes(), ...discoverDocsRoutes(), ].map((routePath) => ({ path: routePath, @@ -54,6 +75,9 @@ export default defineConfig((): UserConfig => { fs: { allow: [repoRoot], }, + watch: { + ignored: ["**/.tanstack/**"], + }, }, plugins: [ cloudflare({ viteEnvironment: { name: "ssr" } }), diff --git a/public-docs/best-practices.md b/public-docs/best-practices.md index a097422ac..177455263 100644 --- a/public-docs/best-practices.md +++ b/public-docs/best-practices.md @@ -2,7 +2,7 @@ title: Best practices description: Tips for getting the most out of Paseo and mobile-first agent workflows. nav: Best practices -order: 10 +order: 12 --- # Best practices diff --git a/public-docs/cli.md b/public-docs/cli.md index 9dd9a384f..2f60e6362 100644 --- a/public-docs/cli.md +++ b/public-docs/cli.md @@ -2,7 +2,7 @@ title: CLI description: "Paseo CLI reference: manage agents, daemons, permissions, and worktrees from your terminal." nav: CLI -order: 5 +order: 6 --- # CLI @@ -58,7 +58,7 @@ Use `paseo attach` to stream an agent's output in real-time: paseo attach abc123 # Attach to agent (Ctrl+C to detach) ``` -Agent IDs can be shortened — `abc` works if it's unambiguous. +Agent IDs can be shortened, `abc` works if it's unambiguous. ## Sending messages @@ -122,7 +122,7 @@ Use `PASEO_HOME` to run multiple isolated daemon instances. ## Connecting to a remote daemon -`--host` accepts either a local target (`host:port`, a unix socket, or a Windows pipe) or a pairing offer URL — the same `https://app.paseo.sh/#offer=...` link the mobile app uses for QR pairing. With an offer URL the CLI connects through the Paseo relay with end-to-end encryption, so you can drive a daemon on another machine without exposing it to the network. +`--host` accepts either a local target (`host:port`, a unix socket, or a Windows pipe) or a pairing offer URL, the same `https://app.paseo.sh/#offer=...` link the mobile app uses for QR pairing. With an offer URL the CLI connects through the Paseo relay with end-to-end encryption, so you can drive a daemon on another machine without exposing it to the network. Get an offer URL from the daemon you want to control: @@ -165,7 +165,7 @@ while true; do done ``` -This pattern enables hierarchical task decomposition — a lead agent can break down work, delegate to specialists, and synthesize results. +This pattern enables hierarchical task decomposition, a lead agent can break down work, delegate to specialists, and synthesize results. ## Output formats @@ -179,7 +179,7 @@ paseo ls -q # IDs only (quiet) ## Global options -- `--host ` — connect to a different daemon (`host:port`, unix socket, or `https://app.paseo.sh/#offer=...` for relay). See [Connecting to a remote daemon](#connecting-to-a-remote-daemon). -- `--json` — JSON output -- `-q, --quiet` — minimal output -- `--no-color` — disable colors +- `--host `, connect to a different daemon (`host:port`, unix socket, or `https://app.paseo.sh/#offer=...` for relay). See [Connecting to a remote daemon](#connecting-to-a-remote-daemon). +- `--json`, JSON output +- `-q, --quiet`, minimal output +- `--no-color`, disable colors diff --git a/public-docs/configuration.md b/public-docs/configuration.md index 162bb7fd6..0d2b4766a 100644 --- a/public-docs/configuration.md +++ b/public-docs/configuration.md @@ -2,7 +2,7 @@ title: Configuration description: Configure Paseo via config.json, environment variables, and CLI overrides. nav: Configuration -order: 8 +order: 10 --- # Configuration @@ -50,9 +50,9 @@ Minimal example that configures listening address, hostnames, and MCP: ## Agent providers -Agent providers — both the first-class ones Paseo ships with and custom entries you add under `agents.providers` — are documented on their own page. +Agent providers, both the first-class ones Paseo ships with and custom entries you add under `agents.providers`, are documented on their own page. -See [Providers](/docs/providers) for first-class providers, how to point Claude at Anthropic-compatible endpoints (Z.AI, Alibaba/Qwen), multiple profiles, custom binaries, ACP agents, and the `additionalModels` merge behavior. The full field reference lives on GitHub at [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md). +See [Providers](/docs/providers) for the mental model and [Supported providers](/docs/supported-providers) for the full list of agents Paseo can launch. For pointing Claude at Anthropic-compatible endpoints (Z.AI, Alibaba/Qwen), multiple profiles, custom binaries, ACP agents, and the `additionalModels` merge behavior, see [Custom providers](/docs/custom-providers). The full field reference lives on GitHub at [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md). ## Voice @@ -101,7 +101,7 @@ paseo daemon set-password This prompts for a password, writes the bcrypt hash to `config.json`, and tells you to restart the daemon. -Alternatively, set the `PASEO_PASSWORD` environment variable (plaintext — hashed automatically at startup): +Alternatively, set the `PASEO_PASSWORD` environment variable (plaintext, hashed automatically at startup): ```bash PASEO_PASSWORD=my-secret paseo daemon start @@ -144,24 +144,24 @@ In the mobile app, enter the password in the direct connection setup screen. ## Common env vars -- `PASEO_HOME` — set Paseo home directory -- `PASEO_PASSWORD` — on the daemon, the password to require (plaintext, hashed at startup); on the CLI, the password used to connect when the host URI doesn't include one -- `PASEO_LISTEN` — override `daemon.listen` -- `PASEO_HOSTNAMES` — override/extend `daemon.hostnames` -- `PASEO_ALLOWED_HOSTS` — deprecated alias for `PASEO_HOSTNAMES` -- `PASEO_LOG_CONSOLE_LEVEL` — override `log.console.level` -- `PASEO_LOG_FILE_LEVEL` — override `log.file.level` -- `PASEO_LOG_FILE_PATH` — override `log.file.path` -- `PASEO_LOG_FILE_ROTATE_SIZE` — override `log.file.rotate.maxSize` -- `PASEO_LOG_FILE_ROTATE_COUNT` — override `log.file.rotate.maxFiles` -- `PASEO_LOG`, `PASEO_LOG_FORMAT` — legacy log overrides (still supported) -- `OPENAI_API_KEY` — override OpenAI provider key -- `PASEO_VOICE_LLM_PROVIDER` — override voice LLM provider (`claude`, `codex`, `opencode`) -- `PASEO_DICTATION_STT_PROVIDER`, `PASEO_VOICE_STT_PROVIDER`, `PASEO_VOICE_TTS_PROVIDER` — override voice provider selection (`local` or `openai`) -- `PASEO_LOCAL_MODELS_DIR` — control local model directory -- `PASEO_DICTATION_LOCAL_STT_MODEL` — override local dictation STT model -- `PASEO_VOICE_LOCAL_STT_MODEL`, `PASEO_VOICE_LOCAL_TTS_MODEL` — override local voice STT/TTS models -- `PASEO_VOICE_LOCAL_TTS_SPEAKER_ID`, `PASEO_VOICE_LOCAL_TTS_SPEED` — optional local voice TTS tuning +- `PASEO_HOME`, set Paseo home directory +- `PASEO_PASSWORD`, on the daemon, the password to require (plaintext, hashed at startup); on the CLI, the password used to connect when the host URI doesn't include one +- `PASEO_LISTEN`, override `daemon.listen` +- `PASEO_HOSTNAMES`, override/extend `daemon.hostnames` +- `PASEO_ALLOWED_HOSTS`, deprecated alias for `PASEO_HOSTNAMES` +- `PASEO_LOG_CONSOLE_LEVEL`, override `log.console.level` +- `PASEO_LOG_FILE_LEVEL`, override `log.file.level` +- `PASEO_LOG_FILE_PATH`, override `log.file.path` +- `PASEO_LOG_FILE_ROTATE_SIZE`, override `log.file.rotate.maxSize` +- `PASEO_LOG_FILE_ROTATE_COUNT`, override `log.file.rotate.maxFiles` +- `PASEO_LOG`, `PASEO_LOG_FORMAT`, legacy log overrides (still supported) +- `OPENAI_API_KEY`, override OpenAI provider key +- `PASEO_VOICE_LLM_PROVIDER`, override voice LLM provider (`claude`, `codex`, `opencode`) +- `PASEO_DICTATION_STT_PROVIDER`, `PASEO_VOICE_STT_PROVIDER`, `PASEO_VOICE_TTS_PROVIDER`, override voice provider selection (`local` or `openai`) +- `PASEO_LOCAL_MODELS_DIR`, control local model directory +- `PASEO_DICTATION_LOCAL_STT_MODEL`, override local dictation STT model +- `PASEO_VOICE_LOCAL_STT_MODEL`, `PASEO_VOICE_LOCAL_TTS_MODEL`, override local voice STT/TTS models +- `PASEO_VOICE_LOCAL_TTS_SPEAKER_ID`, `PASEO_VOICE_LOCAL_TTS_SPEED`, optional local voice TTS tuning ## Schema diff --git a/public-docs/custom-providers.md b/public-docs/custom-providers.md new file mode 100644 index 000000000..14b5e6399 --- /dev/null +++ b/public-docs/custom-providers.md @@ -0,0 +1,192 @@ +--- +title: Custom providers +description: Configure custom providers, alternative endpoints, profiles, custom binaries, and ACP agents in ~/.paseo/config.json. +nav: Custom providers +order: 5 +--- + +# Custom providers + +Everything beyond the [supported providers](/docs/supported-providers) lives under `agents.providers` in `~/.paseo/config.json`. You can: + +- **Extend** a first-class provider to point at a different API (Z.AI, Alibaba/Qwen, a proxy, a self-hosted endpoint). +- **Add profiles**, multiple entries against the same underlying provider with different credentials or curated model lists. +- **Override the binary**, run a nightly build, a wrapper script, or a Docker image instead of the installed CLI. +- **Add ACP agents**, Gemini CLI, Hermes, or any agent speaking the Agent Client Protocol over stdio. +- **Disable** a provider you don't use. + +Provider IDs must be lowercase alphanumeric with hyphens (`/^[a-z][a-z0-9-]*$/`). Every custom entry needs `extends` (a first-class provider ID or `"acp"`) and a `label`. + +The examples below are a quick tour. The full, up-to-date reference is on GitHub: [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md). + +## Extending a first-class provider + +```json +{ + "agents": { + "providers": { + "my-claude": { + "extends": "claude", + "label": "My Claude", + "env": { + "ANTHROPIC_API_KEY": "sk-ant-...", + "ANTHROPIC_BASE_URL": "https://my-proxy.example.com/v1" + } + } + } + } +} +``` + +## Z.AI (GLM) coding plan + +Z.AI exposes GLM models through an Anthropic-compatible endpoint. Point `ANTHROPIC_BASE_URL` at their API and use `ANTHROPIC_AUTH_TOKEN` for the key. Third-party endpoints don't support Anthropic's server-side tools, so disable `WebSearch`. + +```json +{ + "agents": { + "providers": { + "zai": { + "extends": "claude", + "label": "ZAI", + "env": { + "ANTHROPIC_AUTH_TOKEN": "", + "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic", + "API_TIMEOUT_MS": "3000000" + }, + "disallowedTools": ["WebSearch"], + "models": [ + { "id": "glm-5-turbo", "label": "GLM 5 Turbo", "isDefault": true }, + { "id": "glm-5.1", "label": "GLM 5.1" } + ] + } + } + } +} +``` + +## Alibaba Cloud (Qwen) coding plan + +Alibaba's coding plan routes Claude Code to Qwen models via an Anthropic-compatible API. Subscription keys look like `sk-sp-...` and must be created in the Singapore region. + +```json +{ + "agents": { + "providers": { + "qwen": { + "extends": "claude", + "label": "Qwen (Alibaba)", + "env": { + "ANTHROPIC_AUTH_TOKEN": "sk-sp-", + "ANTHROPIC_BASE_URL": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic" + }, + "disallowedTools": ["WebSearch"], + "models": [ + { "id": "qwen3.5-plus", "label": "Qwen 3.5 Plus", "isDefault": true }, + { "id": "qwen3-coder-next", "label": "Qwen 3 Coder Next" } + ] + } + } + } +} +``` + +## Multiple profiles + +Create as many entries as you want against the same first-class provider. Each one shows up as a separate option in the app with its own credentials and models. + +```json +{ + "agents": { + "providers": { + "claude-work": { + "extends": "claude", + "label": "Claude (Work)", + "env": { "ANTHROPIC_API_KEY": "sk-ant-work-..." } + }, + "claude-personal": { + "extends": "claude", + "label": "Claude (Personal)", + "env": { "ANTHROPIC_API_KEY": "sk-ant-personal-..." } + } + } + } +} +``` + +## Custom binary + +`command` is an array, first element is the binary, the rest are arguments. It fully replaces the default launch command for that provider. + +```json +{ + "agents": { + "providers": { + "claude": { + "command": ["/opt/claude-nightly/claude"] + } + } + } +} +``` + +## ACP providers + +Any agent that speaks [ACP](https://agentclientprotocol.com) over stdio can be added with `extends: "acp"` and a `command`. Paseo spawns the process, sends an `initialize` JSON-RPC request, and the agent reports its capabilities, modes, and models at runtime. + +```json +{ + "agents": { + "providers": { + "gemini": { + "extends": "acp", + "label": "Google Gemini", + "command": ["gemini", "--acp"] + }, + "hermes": { + "extends": "acp", + "label": "Hermes", + "command": ["hermes", "acp"] + } + } + } +} +``` + +## Adding or relabeling models + +`models` replaces the model list entirely. `additionalModels` merges with runtime-discovered models (ACP) or with `models`, use it to add an extra entry or relabel a discovered one without redeclaring the full list. An entry with the same `id` as a discovered model updates it in place. + +```json +{ + "agents": { + "providers": { + "gemini": { + "extends": "acp", + "label": "Google Gemini", + "command": ["gemini", "--acp"], + "additionalModels": [ + { "id": "experimental-model", "label": "Experimental", "isDefault": true }, + { "id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro (preferred)" } + ] + } + } + } +} +``` + +## Disabling a provider + +```json +{ + "agents": { + "providers": { + "copilot": { "enabled": false } + } + } +} +``` + +## Full reference + +For the complete field reference (`extends`, `label`, `command`, `env`, `models`, `additionalModels`, `disallowedTools`, `enabled`, `order`), model and thinking-option schemas, and deeper examples for each plan, see [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md) on GitHub. diff --git a/public-docs/index.md b/public-docs/index.md index e8173bc67..91aaeb1c1 100644 --- a/public-docs/index.md +++ b/public-docs/index.md @@ -1,58 +1,42 @@ --- title: Getting started -description: Learn how to set up and use Paseo to manage your coding agents from anywhere. +description: Install Paseo and start running coding agents from anywhere. nav: Getting started order: 1 --- # Getting started -Paseo has three main pieces: the daemon is the local server that manages your agents, the app is the client you use from mobile, web, or desktop, and the CLI is the terminal interface that can also launch the daemon. +Paseo runs your coding agents on your machine and gives you a mobile, desktop, web, and CLI client to drive them from anywhere. Two ways to install. -## Prerequisites +## Desktop app (recommended) -Paseo manages existing agent CLIs. Install at least one agent and make sure it already works with your credentials before you set up Paseo. +Download from [paseo.sh/download](https://paseo.sh/download) or the [GitHub releases page](https://github.com/getpaseo/paseo/releases). Open it and you're done. -- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) -- [Codex](https://github.com/openai/codex) -- [OpenCode](https://github.com/anomalyco/opencode) +The desktop app bundles its own daemon and starts it automatically, no separate install required. On first launch you'll see a brief startup screen, then connect from your phone by scanning the QR code in Settings. -## Desktop App +## Server / CLI -Download the desktop app from [paseo.sh/download](https://paseo.sh/download) or the [GitHub releases page](https://github.com/getpaseo/paseo/releases). Open it and you're done. - -The desktop app bundles and manages its own daemon automatically, so you do not need a separate CLI install on that machine unless you want it. - -On first launch, you may briefly see a startup screen while the local server starts and the app connects to it. After that, connect from your phone by scanning the QR code in Settings if you want mobile access. - -## CLI / Server - -Use this path for headless setups, servers, or remote machines where you want the daemon running without the desktop app. +For headless machines, dev boxes, or any setup where you want the daemon running without the desktop UI: ```bash npm install -g @getpaseo/cli -``` - -```bash paseo ``` Paseo prints a QR code in the terminal. Scan it from the mobile app, or enter the daemon address manually from another client. -Configuration and local state live under `PASEO_HOME`. +Configuration and local state live under `PASEO_HOME` (defaults to `~/.paseo`). -## Voice Setup +## Where next -Paseo includes first-class voice support with a local-first architecture and configurable speech providers. +- [Providers](/docs/providers), what a provider is and how Paseo wraps existing CLIs. +- [CLI reference](/docs/cli), every command. +- [GitHub repo](https://github.com/getpaseo/paseo) +- [Report an issue](https://github.com/getpaseo/paseo/issues) -For architecture, local model behavior, and provider configuration, see the Voice docs page. +## Prerequisites -[Voice docs](/docs/voice) +Paseo manages other agents, it doesn't ship one. Before it's useful, install at least one provider CLI yourself and make sure it works with your credentials. See [Supported providers](/docs/supported-providers) for the full list. -## Next - -- [Updates](/docs/updates) -- [Voice](/docs/voice) -- [Providers](/docs/providers) -- [Configuration](/docs/configuration) -- [Security](/docs/security) +You'll also want the [GitHub CLI](https://cli.github.com/) (`gh`) installed and authenticated, Paseo uses it for PR-aware worktrees and a few orchestration features. diff --git a/public-docs/providers.md b/public-docs/providers.md index fc3c81756..ae97166ca 100644 --- a/public-docs/providers.md +++ b/public-docs/providers.md @@ -1,206 +1,27 @@ --- title: Providers -description: First-class agent providers in Paseo, and how to configure custom providers, ACP agents, and profiles. +description: How Paseo thinks about coding agents, wrapping existing CLIs, native vs ACP support, and where to go next. nav: Providers -order: 7 +order: 3 --- # Providers -A provider is an agent CLI that Paseo knows how to launch, stream, and control. Paseo ships with first-class providers for the major coding agents, and lets you add your own through `config.json` — either by pointing an existing provider at a different API, adding extra profiles, or plugging in any [ACP](https://agentclientprotocol.com)-compatible agent. +Paseo doesn't ship its own coding agent. It launches and supervises **existing CLIs you've already installed and authenticated**, Claude Code, Codex, OpenCode, Cursor, Gemini, and the rest. Your subscriptions, your config, your skills, your MCP servers all stay intact. Paseo just gives you a UI, a CLI, a relay, and orchestration on top. -## First-class providers +## Mental model -These work out of the box once the underlying CLI is installed and authenticated. Paseo discovers them automatically, wires up modes, and exposes them in the app and CLI. +A provider is the contract between Paseo and one external agent CLI: how to launch it, how to stream its output, how to send input back, what modes it supports. The actual binary lives on your machine and runs as a normal subprocess. -- `claude` — Anthropic's Claude Code. Multi-tool assistant with MCP support, streaming, and deep reasoning. -- `codex` — OpenAI's Codex workspace agent with sandbox controls and optional network access. -- `opencode` — Open-source coding assistant with multi-provider model support. -- `copilot` — GitHub Copilot via ACP, with dynamic modes and session support. -- `pi` — Minimal terminal-based coding agent with multi-provider LLM support. +## Two tiers -## Custom providers +- **Native support**, Paseo ships a bundled adapter for the major agents (Claude Code, Codex, OpenCode, pi). Auto-discovered when the underlying CLI is installed, with mode metadata and voice support where applicable. +- **ACP catalog**, any agent speaking the [Agent Client Protocol](https://agentclientprotocol.com) is supported through a generic adapter. Paseo ships a curated catalog of one-click installs (Cursor, Gemini, GitHub Copilot, Hermes, Kimi, Qwen Code, and 25+ more), and you can add any other ACP agent yourself. -Everything beyond the defaults lives under `agents.providers` in `~/.paseo/config.json`. You can: +Either way, **you install the underlying CLI**. Paseo runs it. -- **Extend** a first-class provider to point at a different API (Z.AI, Alibaba/Qwen, a proxy, a self-hosted endpoint). -- **Add profiles** — multiple entries against the same underlying provider with different credentials or curated model lists. -- **Override the binary** — run a nightly build, a wrapper script, or a Docker image instead of the installed CLI. -- **Add ACP agents** — Gemini CLI, Hermes, or any agent speaking the Agent Client Protocol over stdio. -- **Disable** a provider you don't use. +## Where to go next -Provider IDs must be lowercase alphanumeric with hyphens (`/^[a-z][a-z0-9-]*$/`). Every custom entry needs `extends` (a first-class provider ID or `"acp"`) and a `label`. - -The examples below are a quick tour. The full, up-to-date reference is on GitHub: [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md). - -## Extending a first-class provider - -```json -{ - "agents": { - "providers": { - "my-claude": { - "extends": "claude", - "label": "My Claude", - "env": { - "ANTHROPIC_API_KEY": "sk-ant-...", - "ANTHROPIC_BASE_URL": "https://my-proxy.example.com/v1" - } - } - } - } -} -``` - -## Z.AI (GLM) coding plan - -Z.AI exposes GLM models through an Anthropic-compatible endpoint. Point `ANTHROPIC_BASE_URL` at their API and use `ANTHROPIC_AUTH_TOKEN` for the key. Third-party endpoints don't support Anthropic's server-side tools, so disable `WebSearch`. - -```json -{ - "agents": { - "providers": { - "zai": { - "extends": "claude", - "label": "ZAI", - "env": { - "ANTHROPIC_AUTH_TOKEN": "", - "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic", - "API_TIMEOUT_MS": "3000000" - }, - "disallowedTools": ["WebSearch"], - "models": [ - { "id": "glm-5-turbo", "label": "GLM 5 Turbo", "isDefault": true }, - { "id": "glm-5.1", "label": "GLM 5.1" } - ] - } - } - } -} -``` - -## Alibaba Cloud (Qwen) coding plan - -Alibaba's coding plan routes Claude Code to Qwen models via an Anthropic-compatible API. Subscription keys look like `sk-sp-...` and must be created in the Singapore region. - -```json -{ - "agents": { - "providers": { - "qwen": { - "extends": "claude", - "label": "Qwen (Alibaba)", - "env": { - "ANTHROPIC_AUTH_TOKEN": "sk-sp-", - "ANTHROPIC_BASE_URL": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic" - }, - "disallowedTools": ["WebSearch"], - "models": [ - { "id": "qwen3.5-plus", "label": "Qwen 3.5 Plus", "isDefault": true }, - { "id": "qwen3-coder-next", "label": "Qwen 3 Coder Next" } - ] - } - } - } -} -``` - -## Multiple profiles - -Create as many entries as you want against the same first-class provider. Each one shows up as a separate option in the app with its own credentials and models. - -```json -{ - "agents": { - "providers": { - "claude-work": { - "extends": "claude", - "label": "Claude (Work)", - "env": { "ANTHROPIC_API_KEY": "sk-ant-work-..." } - }, - "claude-personal": { - "extends": "claude", - "label": "Claude (Personal)", - "env": { "ANTHROPIC_API_KEY": "sk-ant-personal-..." } - } - } - } -} -``` - -## Custom binary - -`command` is an array — first element is the binary, the rest are arguments. It fully replaces the default launch command for that provider. - -```json -{ - "agents": { - "providers": { - "claude": { - "command": ["/opt/claude-nightly/claude"] - } - } - } -} -``` - -## ACP providers - -Any agent that speaks [ACP](https://agentclientprotocol.com) over stdio can be added with `extends: "acp"` and a `command`. Paseo spawns the process, sends an `initialize` JSON-RPC request, and the agent reports its capabilities, modes, and models at runtime. - -```json -{ - "agents": { - "providers": { - "gemini": { - "extends": "acp", - "label": "Google Gemini", - "command": ["gemini", "--acp"] - }, - "hermes": { - "extends": "acp", - "label": "Hermes", - "command": ["hermes", "acp"] - } - } - } -} -``` - -## Adding or relabeling models - -`models` replaces the model list entirely. `additionalModels` merges with runtime-discovered models (ACP) or with `models` — use it to add an extra entry or relabel a discovered one without redeclaring the full list. An entry with the same `id` as a discovered model updates it in place. - -```json -{ - "agents": { - "providers": { - "gemini": { - "extends": "acp", - "label": "Google Gemini", - "command": ["gemini", "--acp"], - "additionalModels": [ - { "id": "experimental-model", "label": "Experimental", "isDefault": true }, - { "id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro (preferred)" } - ] - } - } - } -} -``` - -## Disabling a provider - -```json -{ - "agents": { - "providers": { - "copilot": { "enabled": false } - } - } -} -``` - -## Full reference - -For the complete field reference (`extends`, `label`, `command`, `env`, `models`, `additionalModels`, `disallowedTools`, `enabled`, `order`), model and thinking-option schemas, and deeper examples for each plan, see [docs/custom-providers.md](https://github.com/getpaseo/paseo/blob/main/docs/custom-providers.md) on GitHub. +- [Supported providers](/docs/supported-providers), the full list with install links. +- [Custom providers](/docs/custom-providers), add your own provider, point an existing one at a different endpoint, run multiple profiles, or override the binary in `~/.paseo/config.json`. +- [paseo.sh/agents](/agents), per-agent landing page for each supported provider. diff --git a/public-docs/security.md b/public-docs/security.md index 7f8a7dc0e..178406586 100644 --- a/public-docs/security.md +++ b/public-docs/security.md @@ -2,7 +2,7 @@ title: Security description: "Security model for Paseo: architecture overview, connection methods, relay encryption, and best practices." nav: Security -order: 9 +order: 11 --- # Security @@ -17,12 +17,12 @@ The Paseo daemon can run anywhere you want to execute agents: your laptop, a Mac Clients connect to the daemon over WebSocket. There are two ways to establish this connection: -- **Relay connection (recommended)** — The daemon connects outbound to our relay server, and clients meet it there. No open ports required. -- **Direct connection** — The daemon listens on a network address and clients connect directly. +- **Relay connection (recommended)**, The daemon connects outbound to our relay server, and clients meet it there. No open ports required. +- **Direct connection**, The daemon listens on a network address and clients connect directly. ## Relay connections (recommended) -The relay is the simplest way to connect from your phone. It requires no VPN setup, no port forwarding, and no firewall configuration. The daemon can stay bound to localhost or a socket file — it connects _outbound_ to the relay, and your phone meets it there. +The relay is the simplest way to connect from your phone. It requires no VPN setup, no port forwarding, and no firewall configuration. The daemon can stay bound to localhost or a socket file, it connects _outbound_ to the relay, and your phone meets it there. > **The relay is designed to be untrusted.** All traffic between your phone and daemon is end-to-end encrypted. The relay server cannot read your messages, see your code, or modify traffic without detection. Even if the relay is compromised, your data remains protected. @@ -39,14 +39,14 @@ The relay sees only: IP addresses, timing, message sizes, and session IDs. It ca The daemon requires a valid cryptographic handshake before processing any commands. A compromised relay cannot: -- **Send commands** — Without your phone's private key, it cannot complete the handshake -- **Read your traffic** — All messages are encrypted with AES-256-GCM after the handshake -- **Forge messages** — GCM provides authenticated encryption; tampered messages are rejected -- **Replay old messages** — Each session derives fresh encryption keys +- **Send commands**, Without your phone's private key, it cannot complete the handshake +- **Read your traffic**, All messages are encrypted with AES-256-GCM after the handshake +- **Forge messages**, GCM provides authenticated encryption; tampered messages are rejected +- **Replay old messages**, Each session derives fresh encryption keys ### Trust model -The QR code or pairing link is the trust anchor. It contains the daemon's public key, which is required to establish the encrypted connection. Treat it like a password — don't share it publicly. +The QR code or pairing link is the trust anchor. It contains the daemon's public key, which is required to establish the encrypted connection. Treat it like a password, don't share it publicly. If you believe a pairing offer has been compromised, restart the daemon to generate a new session ID and rotate the relay pairing. @@ -56,7 +56,7 @@ By default, the daemon listens on `127.0.0.1:6767` (localhost only). This is saf ### Socket file (CLI only) -For maximum isolation, you can configure the daemon to listen on a Unix socket file instead of a TCP port. This prevents any network access entirely — only processes on the same machine can connect. The CLI supports this mode, but the mobile app and web interface require a network connection. +For maximum isolation, you can configure the daemon to listen on a Unix socket file instead of a TCP port. This prevents any network access entirely, only processes on the same machine can connect. The CLI supports this mode, but the mobile app and web interface require a network connection. ### VPN access @@ -87,11 +87,11 @@ Configure via `daemon.hostnames` in `config.json`: ## Password authentication -By default, anyone who can reach the daemon's listening address can connect. On localhost this is fine — only local processes have access. But if you bind to a network interface (e.g. your LAN IP or `0.0.0.0`), or if you don't fully trust your local network, you can require a password. +By default, anyone who can reach the daemon's listening address can connect. On localhost this is fine, only local processes have access. But if you bind to a network interface (e.g. your LAN IP or `0.0.0.0`), or if you don't fully trust your local network, you can require a password. When a password is configured, all HTTP requests must include an `Authorization: Bearer ` header and all WebSocket connections must authenticate via subprotocol. Unauthenticated requests receive a `401 Unauthorized` response. Only the `/api/health` liveness endpoint is exempt, so that process supervisors and load balancers can probe without credentials. -The password is stored as a bcrypt hash in `config.json` — the daemon never stores it in plaintext. See [Configuration](/docs/configuration#password-authentication) for setup instructions. +The password is stored as a bcrypt hash in `config.json`, the daemon never stores it in plaintext. See [Configuration](/docs/configuration#password-authentication) for setup instructions. ### What password auth does and does not do @@ -104,22 +104,22 @@ The password is stored as a bcrypt hash in `config.json` — the daemon never st - You don't fully trust your local network (shared office, public Wi-Fi with a VPN, etc.). - You're exposing the daemon via a reverse proxy and want an additional authentication layer. -We still recommend the relay for mobile access — it combines authentication with end-to-end encryption out of the box. Password auth is primarily useful for direct LAN or VPN connections where you want access control without the relay. +We still recommend the relay for mobile access, it combines authentication with end-to-end encryption out of the box. Password auth is primarily useful for direct LAN or VPN connections where you want access control without the relay. ## Agent authentication Paseo wraps agent CLIs (Claude Code, Codex, OpenCode) but does not manage their authentication. Each agent provider handles its own credentials: -- **Claude Code** — authenticates via Anthropic's OAuth flow, stored in `~/.claude/` -- **Codex** — uses your OpenAI API key or OAuth session -- **OpenCode** — configured via provider-specific API keys +- **Claude Code**, authenticates via Anthropic's OAuth flow, stored in `~/.claude/` +- **Codex**, uses your OpenAI API key or OAuth session +- **OpenCode**, configured via provider-specific API keys Paseo never stores or transmits provider API keys. Agents run in your user context with your existing credentials. ## Recommendations -- **Use the relay** for mobile access — it's the simplest option and all traffic is end-to-end encrypted -- **Treat the QR code like a password** — anyone with the pairing offer can connect to your daemon -- **Set a password** if you bind to a network address — it prevents unauthorized clients from controlling your agents -- **Never bind to 0.0.0.0 without a password** — without one, any device on your network can connect -- **Keep your daemon updated** — security improvements are released regularly +- **Use the relay** for mobile access, it's the simplest option and all traffic is end-to-end encrypted +- **Treat the QR code like a password**, anyone with the pairing offer can connect to your daemon +- **Set a password** if you bind to a network address, it prevents unauthorized clients from controlling your agents +- **Never bind to 0.0.0.0 without a password**, without one, any device on your network can connect +- **Keep your daemon updated**, security improvements are released regularly diff --git a/public-docs/supported-providers.md b/public-docs/supported-providers.md new file mode 100644 index 000000000..31e1b84dc --- /dev/null +++ b/public-docs/supported-providers.md @@ -0,0 +1,58 @@ +--- +title: Supported providers +description: Every coding agent Paseo can launch, natively supported providers and the ACP catalog. +nav: Supported providers +order: 4 +--- + +# Supported providers + +For the concept and how Paseo manages providers, see [Providers](/docs/providers). To add or configure your own, see [Custom providers](/docs/custom-providers). + +## Native support + +Work out of the box once the underlying CLI is installed and authenticated. + +- [Claude Code](https://docs.anthropic.com/en/docs/claude-code). Anthropic's coding agent with MCP support, streaming, and deep reasoning. +- [Codex CLI](https://github.com/openai/codex). OpenAI's workspace agent with sandbox controls and optional network access. +- [OpenCode](https://opencode.ai/). Open-source coding assistant with multi-provider model support. +- [pi](https://github.com/svkozak/pi-acp). Minimal terminal-based coding agent with multi-provider LLM support. + +## ACP catalog + +Pick any of these from the in-app provider catalog. Each entry is a one-click install of the underlying CLI. + +- [Agoragentic](https://agoragentic.com), agent marketplace with 174+ AI capabilities. +- [Amp](https://github.com/tao12345666333/amp-acp), frontier coding agent. +- [Auggie CLI](https://www.augmentcode.com/), Augment Code's agent backed by their context engine. +- [Autohand Code](https://www.autohand.ai/cli/), Autohand AI's coding agent. +- [Cline](https://cline.bot/cli), autonomous coding agent. +- [Codebuddy Code](https://www.codebuddy.cn/cli/), Tencent Cloud's coding tool. +- [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code-cli), Snowflake's coding agent. +- [Corust Agent](https://github.com/Corust-ai/corust-agent-release/releases), Rust-focused coding partner. +- [crow-cli](https://crow-ai.dev/), minimal ACP-native coding agent. +- [Cursor](https://cursor.com/docs/cli/overview), Cursor's coding agent. +- [DeepAgents](https://docs.langchain.com/oss/javascript/deepagents/overview), LangChain-powered coding agent. +- [DimCode](https://dimcode.dev/docs/acp.html), multi-model coding agent. +- [Dirac](https://dirac.run), open-source agent with hash-anchored parallel edits. +- [Factory Droid](https://factory.ai/product/cli), Factory AI's coding agent. +- [fast-agent](https://fast-agent.ai/acp/), multi-provider coding agent. +- [Gemini CLI](https://geminicli.com), Google's official Gemini CLI. +- [GitHub Copilot](https://github.com/features/copilot/cli/), GitHub's AI pair programmer via ACP. +- [GLM Agent](https://github.com/stefandevo/glm-acp-agent), Zhipu AI's GLM coding agent. +- [goose](https://block.github.io/goose/), Block's local open-source AI agent. +- [Hermes Agent](https://hermes-agent.nousresearch.com/docs/user-guide/features/acp), Nous Research's self-improving agent. +- [Junie](https://junie.jetbrains.com/docs/junie-cli-acp.html), JetBrains' coding agent. +- [Kilo Code](https://kilo.ai/docs/code-with-ai/platforms/cli), open-source coding agent. +- [Kimi Code CLI](https://github.com/MoonshotAI/kimi-cli), Moonshot AI's coding assistant. +- [Minion Code](https://github.com/femto/minion-code), Minion-framework coding agent. +- [Mistral Vibe](https://github.com/mistralai/mistral-vibe), Mistral's open-source CLI assistant. +- [Nova](https://www.compassap.ai/portfolio/nova.html), Compass AI's software engineer. +- [Poolside](https://docs.poolside.ai/cli/pool), Poolside's coding agent. +- [Qoder](https://qoder.com), agentic coding assistant. +- [Qwen Code](https://qwenlm.github.io/qwen-code-docs/en/users/overview), Alibaba's Qwen coding assistant. +- [siGit Code](https://github.com/getsigit/sigit), local-first coding agent with optional on-device LLM. +- [Stakpak](https://stakpak.dev/), Rust-based DevOps agent. +- [VT Code](https://github.com/vinhnx/VTCode/blob/main/docs/guides/zed-acp.md), open-source multi-provider coding agent. + +The in-app catalog is the canonical, version-pinned source. Anything not listed here can still be added manually, see [Custom providers](/docs/custom-providers). diff --git a/public-docs/updates.md b/public-docs/updates.md deleted file mode 100644 index 294170532..000000000 --- a/public-docs/updates.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Updates -description: How to update Paseo daemon and apps across web, desktop, and mobile. -nav: Updates -order: 2 ---- - -# Updates - -Keep your daemon and apps current to get the latest fixes and features. - -## Version compatibility - -For now, daemon and app versions should be kept in lockstep. If your daemon is version X, make sure your clients are also version X. - -## Update the daemon - -Install the latest CLI/daemon package globally: - -```bash -npm install -g @getpaseo/cli@latest -``` - -Then restart the daemon: - -```bash -paseo daemon restart -``` - -## Web app - -[app.paseo.sh](https://app.paseo.sh) is always up to date. No manual update needed. - -## Desktop app - -Download the latest desktop build from the GitHub releases page and install it over your current version. - -[Paseo releases](https://github.com/getpaseo/paseo/releases) - -## Mobile apps - -Mobile apps are available on the App Store and Play Store. Update through your respective store. Store versions may lag behind the latest release due to review processes. diff --git a/public-docs/voice.md b/public-docs/voice.md index dfb34afc1..5d5dafe7a 100644 --- a/public-docs/voice.md +++ b/public-docs/voice.md @@ -2,7 +2,7 @@ title: Voice description: Paseo voice architecture, local-first model execution, and provider configuration. nav: Voice -order: 3 +order: 9 --- # Voice @@ -69,12 +69,12 @@ You can switch dictation, voice STT, and voice TTS to OpenAI by setting provider ## Environment Variables -- `OPENAI_API_KEY` — OpenAI speech credentials -- `PASEO_VOICE_LLM_PROVIDER` — voice agent provider override -- `PASEO_LOCAL_MODELS_DIR` — local model storage directory -- `PASEO_DICTATION_LOCAL_STT_MODEL` — local dictation STT model ID -- `PASEO_VOICE_LOCAL_STT_MODEL`, `PASEO_VOICE_LOCAL_TTS_MODEL` — local voice STT/TTS model IDs -- `PASEO_VOICE_LOCAL_TTS_SPEAKER_ID`, `PASEO_VOICE_LOCAL_TTS_SPEED` — optional local voice TTS tuning +- `OPENAI_API_KEY`, OpenAI speech credentials +- `PASEO_VOICE_LLM_PROVIDER`, voice agent provider override +- `PASEO_LOCAL_MODELS_DIR`, local model storage directory +- `PASEO_DICTATION_LOCAL_STT_MODEL`, local dictation STT model ID +- `PASEO_VOICE_LOCAL_STT_MODEL`, `PASEO_VOICE_LOCAL_TTS_MODEL`, local voice STT/TTS model IDs +- `PASEO_VOICE_LOCAL_TTS_SPEAKER_ID`, `PASEO_VOICE_LOCAL_TTS_SPEED`, optional local voice TTS tuning ## Operational Notes diff --git a/public-docs/why.md b/public-docs/why.md new file mode 100644 index 000000000..d1d9fceab --- /dev/null +++ b/public-docs/why.md @@ -0,0 +1,43 @@ +--- +title: Why Paseo? +description: What Paseo is, what it isn't, and how it fits into your workflow. +nav: Why Paseo? +order: 2 +--- + +# Why Paseo? + +Paseo is a self-hostable platform for running and orchestrating coding agents. It runs the agent CLIs you already use, on the hardware you already have, and gives you a UI, CLI, and API to drive them from anywhere. + +## Architecture + +- Daemon-client architecture. The daemon manages agents; clients (mobile, desktop, web, CLI) connect locally or over a relay. Remote access isn't an add-on. +- macOS, Windows, and Linux are all primary targets. None of them are a port or an afterthought. +- Mobile, desktop, and web are separate native clients. The mobile app is built in React Native, not a webview. + +## Providers + +- Bring your own. Use your Claude subscription, your OpenAI account, your own API keys, a self-hosted endpoint. Paseo doesn't proxy model calls. +- Local voice stack. Speech-to-text and text-to-speech run on-device by default. OpenAI providers are configurable if you want cloud quality. +- Open source. No telemetry on your code. + +## Where agents run + +- Your laptop, a homelab, a company server. Same daemon, same client surface. +- Any directory, git or not. Launch agents, merge locally, review the diff in the app. +- GitHub PRs, checks, and reviews surface in the app when you want them. Not required. + +## Parallel work + +- Splits and panes. Agents, terminals, and browsers side by side in one workspace. +- Per-worktree services. Each worktree gets allocated ports for dev servers and databases, reachable through proxy URLs like `web.fix-auth.my-app.localhost` so they don't collide. +- Multiple agents on the same repo via worktrees. + +## Automation + +- The CLI exposes the same surface as the app. Anything in the UI is scriptable. +- MCP server. Agents can drive Paseo themselves: create worktrees, spawn other agents, open terminals, send prompts. + +## What it isn't + +Not a hosted agent, not an IDE, not a model provider. Paseo runs the CLIs you already use and stays out of the way. diff --git a/public-docs/worktrees.md b/public-docs/worktrees.md index 2056cc201..753767419 100644 --- a/public-docs/worktrees.md +++ b/public-docs/worktrees.md @@ -2,12 +2,12 @@ title: Git worktrees description: Run agents in isolated git worktrees with setup hooks, scripts, and long-running services. nav: Git worktrees -order: 4 +order: 7 --- # Git worktrees -Each agent runs in its own git worktree — a separate directory on a separate branch — so parallel agents never step on each other. You configure setup, scripts, and long-running services through a `paseo.json` file at your repo root. +Each agent runs in its own git worktree, a separate directory on a separate branch, so parallel agents never step on each other. You configure setup, scripts, and long-running services through a `paseo.json` file at your repo root. ## Layout and workflow @@ -20,10 +20,10 @@ Worktrees live under `$PASEO_HOME/worktrees/`, grouped by a hash of the source c └── bold-owl/ ``` -1. Create a worktree — Paseo runs your setup hooks -2. Launch an agent — a branch is created or assigned +1. Create a worktree, Paseo runs your setup hooks +2. Launch an agent, a branch is created or assigned 3. Review the diff against the base branch -4. Merge or archive — archive runs teardown and removes the directory +4. Merge or archive, archive runs teardown and removes the directory ## paseo.json @@ -93,7 +93,7 @@ Commands run with the worktree as `cwd`. Use `$PASEO_SOURCE_CHECKOUT_PATH` to re } ``` -Omit `port` to let Paseo auto-assign one. Bind your process to `$PASEO_PORT` rather than hard-coding — each worktree gets a distinct port so multiple copies of the same service coexist. +Omit `port` to let Paseo auto-assign one. Bind your process to `$PASEO_PORT` rather than hard-coding, each worktree gets a distinct port so multiple copies of the same service coexist. ### Reverse proxy @@ -142,17 +142,17 @@ Open terminals automatically when a worktree is created. Useful for tailing logs Setup, teardown, scripts, and services all see: -- `$PASEO_SOURCE_CHECKOUT_PATH` — the original repo root -- `$PASEO_WORKTREE_PATH` — the worktree directory -- `$PASEO_BRANCH_NAME` — the worktree's branch -- `$PASEO_WORKTREE_PORT` — legacy per-worktree port (prefer `$PASEO_PORT` inside services) +- `$PASEO_SOURCE_CHECKOUT_PATH`, the original repo root +- `$PASEO_WORKTREE_PATH`, the worktree directory +- `$PASEO_BRANCH_NAME`, the worktree's branch +- `$PASEO_WORKTREE_PORT`, legacy per-worktree port (prefer `$PASEO_PORT` inside services) Services additionally get: -- `$PASEO_PORT` — this service's assigned port -- `$PASEO_URL` — this service's proxy URL -- `$PASEO_SERVICE__PORT` / `_URL` — peer service ports and URLs -- `$HOST` — `127.0.0.1` for local-only daemons, `0.0.0.0` when the daemon binds all interfaces +- `$PASEO_PORT`, this service's assigned port +- `$PASEO_URL`, this service's proxy URL +- `$PASEO_SERVICE__PORT` / `_URL`, peer service ports and URLs +- `$HOST`, `127.0.0.1` for local-only daemons, `0.0.0.0` when the daemon binds all interfaces ## CLI