website: add privacy policy page and footer link

Add a minimal privacy policy at /privacy that explains:
- Paseo is self-hosted, no data collection
- The relay uses end-to-end encryption and cannot read messages
- No analytics, tracking, or ads
- Third-party agent providers handle their own auth

Add footer link on home page styled as muted/subtle.
This commit is contained in:
Mohamed Boudra
2026-02-12 14:20:32 +07:00
parent fba7c73c8b
commit e542854ae0
3 changed files with 137 additions and 0 deletions
+21
View File
@@ -9,6 +9,7 @@
// 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 PrivacyRouteImport } from './routes/privacy'
import { Route as DocsRouteImport } from './routes/docs'
import { Route as IndexRouteImport } from './routes/index'
import { Route as DocsIndexRouteImport } from './routes/docs/index'
@@ -19,6 +20,11 @@ import { Route as DocsConfigurationRouteImport } from './routes/docs/configurati
import { Route as DocsCliRouteImport } from './routes/docs/cli'
import { Route as DocsBestPracticesRouteImport } from './routes/docs/best-practices'
const PrivacyRoute = PrivacyRouteImport.update({
id: '/privacy',
path: '/privacy',
getParentRoute: () => rootRouteImport,
} as any)
const DocsRoute = DocsRouteImport.update({
id: '/docs',
path: '/docs',
@@ -68,6 +74,7 @@ const DocsBestPracticesRoute = DocsBestPracticesRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/docs': typeof DocsRouteWithChildren
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
'/docs/configuration': typeof DocsConfigurationRoute
@@ -78,6 +85,7 @@ export interface FileRoutesByFullPath {
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
'/docs/configuration': typeof DocsConfigurationRoute
@@ -90,6 +98,7 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/docs': typeof DocsRouteWithChildren
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
'/docs/configuration': typeof DocsConfigurationRoute
@@ -103,6 +112,7 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/docs'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
| '/docs/configuration'
@@ -113,6 +123,7 @@ export interface FileRouteTypes {
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
| '/docs/configuration'
@@ -124,6 +135,7 @@ export interface FileRouteTypes {
| '__root__'
| '/'
| '/docs'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
| '/docs/configuration'
@@ -136,10 +148,18 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
DocsRoute: typeof DocsRouteWithChildren
PrivacyRoute: typeof PrivacyRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/privacy': {
id: '/privacy'
path: '/privacy'
fullPath: '/privacy'
preLoaderRoute: typeof PrivacyRouteImport
parentRoute: typeof rootRouteImport
}
'/docs': {
id: '/docs'
path: '/docs'
@@ -231,6 +251,7 @@ const DocsRouteWithChildren = DocsRoute._addFileChildren(DocsRouteChildren)
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
DocsRoute: DocsRouteWithChildren,
PrivacyRoute: PrivacyRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
+10
View File
@@ -53,6 +53,16 @@ function Home() {
<Story />
<FAQ />
</main>
<footer className="p-6 md:p-20 md:pt-0 max-w-3xl mx-auto">
<div className="border-t border-white/10 pt-6">
<a
href="/privacy"
className="text-xs text-white/40 hover:text-white/60 transition-colors"
>
Privacy
</a>
</div>
</footer>
</div>
</CursorFieldProvider>
)
+106
View File
@@ -0,0 +1,106 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/privacy')({
head: () => ({
meta: [
{ title: 'Privacy Policy - Paseo' },
{
name: 'description',
content:
'Privacy policy for Paseo - a self-hosted agent manager with no tracking or analytics.',
},
],
}),
component: Privacy,
})
function Privacy() {
return (
<div className="min-h-screen bg-background">
<div className="max-w-3xl mx-auto p-6 md:p-12">
<h1 className="text-3xl font-medium mb-8">Privacy Policy</h1>
<div className="space-y-6 text-white/70 leading-relaxed">
<p>
Paseo is a self-hosted tool for managing coding agents. Your code and
data stay on your machine.
</p>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">What we collect</h2>
<p>Nothing. Paseo runs on your machine and doesn't send us any data.</p>
</section>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">The relay server</h2>
<p>
If you use the optional encrypted relay to connect your phone to your
daemon, the relay sees:
</p>
<ul className="list-disc list-inside space-y-1 ml-4">
<li>IP addresses and connection timing</li>
<li>Message sizes</li>
<li>Session IDs</li>
</ul>
<p>
All messages between your phone and daemon are end-to-end encrypted
with AES-256-GCM. The relay cannot read your messages, see your code,
or decrypt your traffic.
</p>
</section>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">Analytics and tracking</h2>
<p>
We don't use analytics, tracking pixels, cookies, or ads. The app
doesn't phone home.
</p>
</section>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">Third-party services</h2>
<p>
Paseo wraps agent providers like Claude Code, Codex, and OpenCode.
Those tools communicate with their own APIs (Anthropic, OpenAI, etc.)
using your credentials. Paseo doesn't manage or intercept those API
calls.
</p>
<p>
If you use voice features with cloud providers (OpenAI speech), your
voice data is sent to those services according to their privacy
policies.
</p>
</section>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">
We don't sell your data
</h2>
<p>
We don't have your data to sell. Paseo is self-hosted and
local-first.
</p>
</section>
<section className="space-y-3">
<h2 className="text-xl font-medium text-white">Questions</h2>
<p>
If you have questions about privacy, open an issue on{' '}
<a
href="https://github.com/getpaseo/paseo"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-white/90"
>
GitHub
</a>
.
</p>
</section>
<p className="text-sm text-white/50 pt-6">Last updated: February 2025</p>
</div>
</div>
</div>
)
}