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:
@@ -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.
|
// 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 rootRouteImport } from './routes/__root'
|
||||||
|
import { Route as PrivacyRouteImport } from './routes/privacy'
|
||||||
import { Route as DocsRouteImport } from './routes/docs'
|
import { Route as DocsRouteImport } from './routes/docs'
|
||||||
import { Route as IndexRouteImport } from './routes/index'
|
import { Route as IndexRouteImport } from './routes/index'
|
||||||
import { Route as DocsIndexRouteImport } from './routes/docs/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 DocsCliRouteImport } from './routes/docs/cli'
|
||||||
import { Route as DocsBestPracticesRouteImport } from './routes/docs/best-practices'
|
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({
|
const DocsRoute = DocsRouteImport.update({
|
||||||
id: '/docs',
|
id: '/docs',
|
||||||
path: '/docs',
|
path: '/docs',
|
||||||
@@ -68,6 +74,7 @@ const DocsBestPracticesRoute = DocsBestPracticesRouteImport.update({
|
|||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/docs': typeof DocsRouteWithChildren
|
'/docs': typeof DocsRouteWithChildren
|
||||||
|
'/privacy': typeof PrivacyRoute
|
||||||
'/docs/best-practices': typeof DocsBestPracticesRoute
|
'/docs/best-practices': typeof DocsBestPracticesRoute
|
||||||
'/docs/cli': typeof DocsCliRoute
|
'/docs/cli': typeof DocsCliRoute
|
||||||
'/docs/configuration': typeof DocsConfigurationRoute
|
'/docs/configuration': typeof DocsConfigurationRoute
|
||||||
@@ -78,6 +85,7 @@ export interface FileRoutesByFullPath {
|
|||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/privacy': typeof PrivacyRoute
|
||||||
'/docs/best-practices': typeof DocsBestPracticesRoute
|
'/docs/best-practices': typeof DocsBestPracticesRoute
|
||||||
'/docs/cli': typeof DocsCliRoute
|
'/docs/cli': typeof DocsCliRoute
|
||||||
'/docs/configuration': typeof DocsConfigurationRoute
|
'/docs/configuration': typeof DocsConfigurationRoute
|
||||||
@@ -90,6 +98,7 @@ export interface FileRoutesById {
|
|||||||
__root__: typeof rootRouteImport
|
__root__: typeof rootRouteImport
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/docs': typeof DocsRouteWithChildren
|
'/docs': typeof DocsRouteWithChildren
|
||||||
|
'/privacy': typeof PrivacyRoute
|
||||||
'/docs/best-practices': typeof DocsBestPracticesRoute
|
'/docs/best-practices': typeof DocsBestPracticesRoute
|
||||||
'/docs/cli': typeof DocsCliRoute
|
'/docs/cli': typeof DocsCliRoute
|
||||||
'/docs/configuration': typeof DocsConfigurationRoute
|
'/docs/configuration': typeof DocsConfigurationRoute
|
||||||
@@ -103,6 +112,7 @@ export interface FileRouteTypes {
|
|||||||
fullPaths:
|
fullPaths:
|
||||||
| '/'
|
| '/'
|
||||||
| '/docs'
|
| '/docs'
|
||||||
|
| '/privacy'
|
||||||
| '/docs/best-practices'
|
| '/docs/best-practices'
|
||||||
| '/docs/cli'
|
| '/docs/cli'
|
||||||
| '/docs/configuration'
|
| '/docs/configuration'
|
||||||
@@ -113,6 +123,7 @@ export interface FileRouteTypes {
|
|||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to:
|
to:
|
||||||
| '/'
|
| '/'
|
||||||
|
| '/privacy'
|
||||||
| '/docs/best-practices'
|
| '/docs/best-practices'
|
||||||
| '/docs/cli'
|
| '/docs/cli'
|
||||||
| '/docs/configuration'
|
| '/docs/configuration'
|
||||||
@@ -124,6 +135,7 @@ export interface FileRouteTypes {
|
|||||||
| '__root__'
|
| '__root__'
|
||||||
| '/'
|
| '/'
|
||||||
| '/docs'
|
| '/docs'
|
||||||
|
| '/privacy'
|
||||||
| '/docs/best-practices'
|
| '/docs/best-practices'
|
||||||
| '/docs/cli'
|
| '/docs/cli'
|
||||||
| '/docs/configuration'
|
| '/docs/configuration'
|
||||||
@@ -136,10 +148,18 @@ export interface FileRouteTypes {
|
|||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexRoute: typeof IndexRoute
|
IndexRoute: typeof IndexRoute
|
||||||
DocsRoute: typeof DocsRouteWithChildren
|
DocsRoute: typeof DocsRouteWithChildren
|
||||||
|
PrivacyRoute: typeof PrivacyRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
interface FileRoutesByPath {
|
interface FileRoutesByPath {
|
||||||
|
'/privacy': {
|
||||||
|
id: '/privacy'
|
||||||
|
path: '/privacy'
|
||||||
|
fullPath: '/privacy'
|
||||||
|
preLoaderRoute: typeof PrivacyRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
'/docs': {
|
'/docs': {
|
||||||
id: '/docs'
|
id: '/docs'
|
||||||
path: '/docs'
|
path: '/docs'
|
||||||
@@ -231,6 +251,7 @@ const DocsRouteWithChildren = DocsRoute._addFileChildren(DocsRouteChildren)
|
|||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
IndexRoute: IndexRoute,
|
IndexRoute: IndexRoute,
|
||||||
DocsRoute: DocsRouteWithChildren,
|
DocsRoute: DocsRouteWithChildren,
|
||||||
|
PrivacyRoute: PrivacyRoute,
|
||||||
}
|
}
|
||||||
export const routeTree = rootRouteImport
|
export const routeTree = rootRouteImport
|
||||||
._addFileChildren(rootRouteChildren)
|
._addFileChildren(rootRouteChildren)
|
||||||
|
|||||||
@@ -53,6 +53,16 @@ function Home() {
|
|||||||
<Story />
|
<Story />
|
||||||
<FAQ />
|
<FAQ />
|
||||||
</main>
|
</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>
|
</div>
|
||||||
</CursorFieldProvider>
|
</CursorFieldProvider>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user